libaacs | branch: refs/tags/0.3.0 | npzacs <[email protected]> | Sun Sep 25 
03:00:41 2011 +0300| [44c891792dae052275fcaadff1046520d9314762] | committer: 
Ano Nymous

Added simple caching for VUKs

> http://git.videolan.org/gitweb.cgi/libaacs.git/?a=commit;h=44c891792dae052275fcaadff1046520d9314762
---

 src/file/keydbcfg.c |  122 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/file/keydbcfg.h |    6 +++
 src/file/xdg.c      |   25 +++++++++++
 src/file/xdg.h      |    1 +
 src/libaacs/aacs.c  |   12 +++++
 5 files changed, 166 insertions(+)

diff --git a/src/file/keydbcfg.c b/src/file/keydbcfg.c
index d7b663e..3bf06e5 100644
--- a/src/file/keydbcfg.c
+++ b/src/file/keydbcfg.c
@@ -22,10 +22,12 @@
 #ifndef _WIN32
 # include "xdg.h"
 # define get_config_home xdg_get_config_home
+# define get_cache_home xdg_get_cache_home
 # define get_config_system xdg_get_config_system
 #else
 # include "win32.h"
 # define get_config_home win32_get_config_home
+# define get_cache_home(...) NULL
 # define get_config_system win32_get_config_system
 #endif
 
@@ -37,6 +39,10 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
 
 #define CFG_DIR        "aacs"
 
@@ -277,6 +283,122 @@ int keydbcfg_load_cert_file(config_file *cf)
     return result;
 }
 
+static int _mkpath(const char *path)
+{
+    struct stat s;
+    int result = 1;
+    char *dir = str_printf("%s", path);
+    char *end = dir;
+
+    while (*end == '/')
+        end++;
+
+    while ((end = strchr(end, '/'))) {
+        *end = 0;
+
+        if (stat(dir, &s) != 0 || !S_ISDIR(s.st_mode)) {
+            DEBUG(DBG_FILE, "Creating directory %s\n", dir);
+
+            if (mkdir(dir, S_IRWXU|S_IRWXG|S_IRWXO) == -1) {
+                DEBUG(DBG_FILE, "Error creating directory %s\n", dir);
+                result = 0;
+                break;
+            }
+        }
+
+        *end++ = '/';
+    }
+
+    X_FREE(dir);
+
+    return result;
+}
+
+char *_keycache_file(const char *type, const uint8_t *disc_id)
+{
+    const char *cache_dir = get_cache_home();
+    char disc_id_str[41];
+
+    if (!cache_dir) {
+        return NULL;
+    }
+
+    hex_array_to_hexstring(disc_id_str, disc_id, 20);
+
+    return str_printf("%s/%s/%s/%s", cache_dir, CFG_DIR, type, disc_id_str);
+}
+
+int keycache_save(const char *type, const uint8_t *disc_id, const uint8_t 
*key, unsigned int len)
+{
+    int result = 0;
+    char *file = _keycache_file(type, disc_id);
+
+    if (file) {
+        if (_mkpath(file)) {
+            FILE *fp = fopen(file, "w");
+
+            if (fp) {
+                char *key_str = calloc(1, len*2 + 1);
+                hex_array_to_hexstring(key_str, key, len);
+
+                if (fwrite(key_str, 1, len*2, fp) == len*2) {
+                    DEBUG(DBG_FILE, "Wrote %s to %s\n", type, file);
+                    result = 1;
+
+                } else {
+                    DEBUG(DBG_FILE, "Error writing to %s\n", file);
+                }
+
+                free(key_str);
+
+                fclose(fp);
+            }
+        }
+
+        X_FREE(file);
+    }
+
+    return result;
+}
+
+int keycache_find(const char *type, const uint8_t *disc_id, uint8_t *key, 
unsigned int len)
+{
+    int result = 0;
+    char *file = _keycache_file(type, disc_id);
+
+    if (file) {
+        FILE *fp = fopen(file, "r");
+
+        if (fp) {
+            char *key_str = malloc(len*2);
+
+            DEBUG(DBG_FILE, "Reading %s\n", file);
+
+            if (fread(key_str, 1, len*2, fp) == len*2) {
+
+                result = hexstring_to_hex_array(key, len, key_str);
+                if (!result) {
+                    DEBUG(DBG_FILE, "Error converting %s\n", file);
+                }
+
+            } else {
+              DEBUG(DBG_FILE, "Error reading from %s\n", file);
+            }
+
+            free(key_str);
+
+            fclose(fp);
+
+        } else {
+            DEBUG(DBG_FILE, "%s not found\n", file);
+        }
+
+        X_FREE(file);
+    }
+
+    return result;
+}
+
 char *keydbcfg_find_config_file(void)
 {
     static const char cfg_file_name[] = CFG_FILE_NAME;
diff --git a/src/file/keydbcfg.h b/src/file/keydbcfg.h
index 44e47f1..b71a2fa 100644
--- a/src/file/keydbcfg.h
+++ b/src/file/keydbcfg.h
@@ -22,6 +22,8 @@
 
 #include <util/attributes.h>
 
+#include <stdint.h>
+
 /* struct holding a digit and key pair for <ENTRY NUMBER> - <ENTRY> entries */
 typedef struct digit_key_pair_t digit_key_pair;
 struct digit_key_pair_t
@@ -120,5 +122,9 @@ AACS_PRIVATE char *keydbcfg_find_config_file(void);
 AACS_PRIVATE int   keydbcfg_load_cert_file(config_file *cf);
 AACS_PRIVATE int   keydbcfg_load_pk_file(config_file *cf);
 
+AACS_PRIVATE int   keycache_save(const char *type, const uint8_t *disc_id,
+                                 const uint8_t *key, unsigned int len);
+AACS_PRIVATE int   keycache_find(const char *type, const uint8_t *disc_id,
+                                 uint8_t *key, unsigned int len);
 
 #endif
diff --git a/src/file/xdg.c b/src/file/xdg.c
index f99156b..bbb1dd2 100644
--- a/src/file/xdg.c
+++ b/src/file/xdg.c
@@ -32,6 +32,7 @@
  */
 
 #define USER_CFG_DIR   ".config"
+#define USER_CACHE_DIR ".cache"
 #define SYSTEM_CFG_DIR "/etc/xdg"
 
 
@@ -59,6 +60,30 @@ const char *xdg_get_config_home(void)
     return dir;
 }
 
+const char *xdg_get_cache_home(void)
+{
+    static char *dir       = NULL;
+    static int   init_done = 0;
+
+    if (!init_done) {
+        init_done = 1;
+
+        const char *xdg_cache = getenv("XDG_CACHE_HOME");
+        if (xdg_cache && *xdg_cache) {
+            return dir = str_printf("%s", xdg_cache);
+        }
+
+        const char *user_home = getenv("HOME");
+        if (user_home && *user_home) {
+            return dir = str_printf("%s/%s", user_home, USER_CACHE_DIR);
+        }
+
+        DEBUG(DBG_FILE, "Can't find user home directory ($HOME) !\n");
+    }
+
+    return dir;
+}
+
 const char *xdg_get_config_system(const char *dir)
 {
     static char *dirs = NULL; // "dir1\0dir2\0...\0dirN\0\0"
diff --git a/src/file/xdg.h b/src/file/xdg.h
index d36dd8a..d19db5c 100644
--- a/src/file/xdg.h
+++ b/src/file/xdg.h
@@ -24,5 +24,6 @@
 
 AACS_PRIVATE const char *xdg_get_config_home(void);
 AACS_PRIVATE const char *xdg_get_config_system(const char *dir);
+AACS_PRIVATE const char *xdg_get_cache_home(void);
 
 #endif
diff --git a/src/libaacs/aacs.c b/src/libaacs/aacs.c
index 9f9c206..a3f8af6 100644
--- a/src/libaacs/aacs.c
+++ b/src/libaacs/aacs.c
@@ -161,6 +161,12 @@ static int _calc_vuk(AACS *aacs, const char *path)
     if (memcmp(aacs->vuk, empty_key, 16))
       return 1;
 
+    /* get cached vuk */
+    if (keycache_find("vuk", aacs->disc_id, aacs->vuk, 16)) {
+        DEBUG(DBG_AACS, "Using cached VUK\n");
+        return 1;
+    }
+
     /* make sure we have media key */
     if (!_calc_mk(aacs, path)) {
         return 0;
@@ -185,6 +191,9 @@ static int _calc_vuk(AACS *aacs, const char *path)
         DEBUG(DBG_AACS, "Volume unique key: %s\n",
               print_hex(str, aacs->vuk, 16));
 
+        /* cache vuk */
+        keycache_save("vuk", aacs->disc_id, aacs->vuk, 16);
+
         return 1;
     }
 
@@ -227,6 +236,9 @@ static int _calc_vuk(AACS *aacs, const char *path)
                 DEBUG(DBG_AACS, "Volume unique key: %s\n", print_hex(str, 
aacs->vuk,
                                                                     16));
 
+                /* cache vuk */
+                keycache_save("vuk", aacs->disc_id, aacs->vuk, 16);
+
                 return 1;
             }
 

_______________________________________________
libaacs-devel mailing list
[email protected]
http://mailman.videolan.org/listinfo/libaacs-devel

Reply via email to