libaacs | branch: master | npzacs <npz...@gmail.com> | Tue Oct  8 09:57:07 2013 
+0300| [08d869c8122ae4c6a73c8e7d8aed60bdacba339b] | committer: npzacs

Added aacs_get_device_binding_id() and aacs_get_device_nonce()

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

 ChangeLog                |    1 +
 src/examples/aacs_info.c |    2 ++
 src/file/keydbcfg.c      |   55 ++++++++++++++++++++++++++++++++++++++++++++++
 src/file/keydbcfg.h      |    3 +++
 src/libaacs/aacs.c       |   29 ++++++++++++++++++++++++
 src/libaacs/aacs.h       |    4 ++++
 6 files changed, 94 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index fa0a2d2..8e7c0f9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+ - Added aacs_get_device_binding_id() and aacs_get_device_nonce()
  - Fixed reading PMSN
  - Dropped support for compile-time PATCHED_DRIVE flag.
  - Bus encryption support
diff --git a/src/examples/aacs_info.c b/src/examples/aacs_info.c
index 8f8d6d4..8970fd8 100644
--- a/src/examples/aacs_info.c
+++ b/src/examples/aacs_info.c
@@ -112,6 +112,7 @@ int main (int argc, char **argv)
     const uint8_t *id  = aacs_get_disc_id(aacs);
     const uint8_t *pmsn = aacs_get_pmsn(aacs);
     const int      bec  = aacs_get_bus_encryption(aacs);
+    const uint8_t *binding_id = aacs_get_device_binding_id(aacs);
     printf("Disc ID: %s\n", id  ? _hex2str(id,  20) : "???");
     printf("VID    : %s\n", vid ? _hex2str(vid, 16) : "???");
     printf("MKBv   : %d\n", aacs_get_mkb_version(aacs));
@@ -119,6 +120,7 @@ int main (int argc, char **argv)
     printf("Bus encryption:\n");
     printf("  Device support:   %s\n", (bec & AACS_BUS_ENCRYPTION_CAPABLE) ? 
"yes" : "no");
     printf("  Enabled in media: %s\n", (bec & AACS_BUS_ENCRYPTION_ENABLED) ? 
"yes" : "no");
+    printf("Device binding ID:  %s\n", binding_id ? _hex2str(binding_id, 16) : 
"???");
 
     aacs_close(aacs);
 
diff --git a/src/file/keydbcfg.c b/src/file/keydbcfg.c
index 8d93d1f..ddac497 100644
--- a/src/file/keydbcfg.c
+++ b/src/file/keydbcfg.c
@@ -550,6 +550,61 @@ void *cache_get_or_update(const char *type, const void 
*data, uint32_t *len, uin
     return cache_data;
 }
 
+int config_save(const char *name, const void *data, uint32_t len)
+{
+    char *path = NULL;
+    FILE *fp = _open_cfg_file_user(name, &path, "w");
+    int result = 0;
+
+    if (fp) {
+        if (fwrite(&len, 1, 4, fp) == 4 &&
+            fwrite(data, 1, len, fp) == len) {
+          DEBUG(DBG_FILE, "Wrote %d bytes to %s\n", len + 4, path);
+          result = 1;
+
+        } else {
+            DEBUG(DBG_FILE | DBG_CRIT, "Error writing to %s\n", path);
+        }
+
+        fclose(fp);
+    }
+
+    X_FREE(path);
+
+    return result;
+}
+
+int config_get(const char *name, uint32_t *len, void *buf)
+{
+    char *path = NULL;
+    FILE *fp = _open_cfg_file_user(name, &path, "r");
+    int result = 0;
+    uint32_t size = *len;
+
+    *len = 0;
+
+    if (fp) {
+        DEBUG(DBG_FILE, "Reading %s\n", path);
+
+        if (fread(len, 1, 4, fp) == 4 && (size <= *len) &&
+            (!buf || fread(buf, 1, *len, fp) == *len)) {
+
+            DEBUG(DBG_FILE, "Read %d bytes from %s\n", 4 + (buf ? *len : 0), 
path);
+            result = 1;
+
+        } else {
+            DEBUG(DBG_FILE | DBG_CRIT, "Error reading from %s\n", path);
+        }
+
+        fclose(fp);
+    }
+
+    X_FREE(path);
+
+    return result;
+}
+
+
 static char *_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 08677ec..7afc0e8 100644
--- a/src/file/keydbcfg.h
+++ b/src/file/keydbcfg.h
@@ -131,4 +131,7 @@ AACS_PRIVATE int cache_remove(const char *name);
 
 AACS_PRIVATE void *cache_get_or_update(const char *type, const void *data, 
uint32_t *len, uint32_t version);
 
+AACS_PRIVATE int config_get(const char *name, uint32_t *len, void *buf); /* 
use buf=NULL to get size */
+AACS_PRIVATE int config_save(const char *name, const void *data, uint32_t len);
+
 #endif
diff --git a/src/libaacs/aacs.c b/src/libaacs/aacs.c
index 0ae51b4..e8f5812 100644
--- a/src/libaacs/aacs.c
+++ b/src/libaacs/aacs.c
@@ -70,6 +70,10 @@ struct aacs {
     int       bee;        /* bus encryption enabled flag in content 
certificate */
     int       bec;        /* bus encryption capable flag in drive certificate 
*/
     uint8_t   read_data_key[16];
+
+    /* AACS Online (BD-J) */
+    uint8_t   device_nonce[16];
+    uint8_t   device_binding_id[16];
 };
 
 static const uint8_t empty_key[] = "\x00\x00\x00\x00\x00\x00\x00\x00"
@@ -1056,6 +1060,31 @@ const uint8_t *aacs_get_pmsn(AACS *aacs)
     return aacs->pmsn;
 }
 
+const uint8_t *aacs_get_device_binding_id(AACS *aacs)
+{
+  /* Device binding ID is used to encrypt online content.
+   * It needs to be cached so that downloaded content can be played later.
+   */
+    static const char config_file_name[] = "device_binding_id";
+    uint32_t len = sizeof(aacs->device_binding_id);
+
+    DEBUG(DBG_AACS, "reading device binding id\n");
+    if (!config_get(config_file_name, &len, aacs->device_binding_id) || len != 
sizeof(aacs->device_binding_id)) {
+        DEBUG(DBG_AACS, "creating device binding id\n");
+        crypto_create_nonce(aacs->device_binding_id, 
sizeof(aacs->device_binding_id));
+        config_save(config_file_name, aacs->device_binding_id, 
sizeof(aacs->device_binding_id));
+    }
+
+   return aacs->device_binding_id;
+}
+
+const uint8_t *aacs_get_device_nonce(AACS *aacs)
+{
+    DEBUG(DBG_AACS, "creating device nonce\n");
+    crypto_create_nonce(aacs->device_nonce, sizeof(aacs->device_nonce));
+    return aacs->device_nonce;
+}
+
 static AACS_RL_ENTRY *_get_rl(const char *type, int *num_records, int *mkbv)
 {
     uint32_t len, version;
diff --git a/src/libaacs/aacs.h b/src/libaacs/aacs.h
index 1f36b1a..8d51f31 100644
--- a/src/libaacs/aacs.h
+++ b/src/libaacs/aacs.h
@@ -52,6 +52,10 @@ AACS_PUBLIC const uint8_t *aacs_get_disc_id(AACS *aacs);
 AACS_PUBLIC const uint8_t *aacs_get_vid(AACS *aacs);  /* may fail even if disc 
can be decrypted */
 AACS_PUBLIC const uint8_t *aacs_get_pmsn(AACS *aacs); /* may fail even if disc 
can be decrypted */
 
+/* AACS Online */
+AACS_PUBLIC const uint8_t *aacs_get_device_binding_id(AACS *aacs);
+AACS_PUBLIC const uint8_t *aacs_get_device_nonce(AACS *aacs);
+
 /* revocation lists */
 typedef struct {
     uint16_t  range;

_______________________________________________
libaacs-devel mailing list
libaacs-devel@videolan.org
https://mailman.videolan.org/listinfo/libaacs-devel

Reply via email to