[Cryptech-Commits] [sw/pkcs11] 02/03: Use key hashes instead of CKA_ID to name objects in libhal keystore.

git at cryptech.is git at cryptech.is
Mon May 16 04:13:10 UTC 2016


This is an automated email from the git hooks/post-receive script.

sra at hactrn.net pushed a commit to branch rpc
in repository sw/pkcs11.

commit 4be4d40a2af0aecd4b3fe41e33500cfc35442da2
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Sun May 15 23:01:45 2016 -0400

    Use key hashes instead of CKA_ID to name objects in libhal keystore.
---
 pkcs11.c   | 231 +++++++++++++++++++++++++++++++++++++++----------------------
 schema.sql |   1 +
 2 files changed, 150 insertions(+), 82 deletions(-)

diff --git a/pkcs11.c b/pkcs11.c
index b5878e5..e08b9ca 100644
--- a/pkcs11.c
+++ b/pkcs11.c
@@ -188,6 +188,16 @@ typedef enum {
 
 #define is_token_handle(_handle_)       (((_handle_) & FLAG_HANDLE_TOKEN) != 0)
 
+/*
+ * Digest algorithm to use when computing a key hashes.  This doesn't
+ * need to be particularly secure, we're just using it to generate
+ * reasonably unique identifier strings from public keys.  We use
+ * SHA-1 for this because that's what most X.509 implementations use
+ * for this purpose.
+ */
+
+#define P11_KEY_HASH_ALGORITHM  hal_digest_algorithm_sha1
+
 

 
 /*
@@ -1345,7 +1355,7 @@ static CK_OBJECT_HANDLE p11_object_create(const p11_session_t *session,
 }
 
 /*
- * Construct libhal type code for a key object.
+ * Construct and store libhal type code for a key object.
  */
 
 static int p11_object_pkey_type(const CK_OBJECT_HANDLE object_handle,
@@ -1380,11 +1390,61 @@ static int p11_object_pkey_type(const CK_OBJECT_HANDLE object_handle,
 
   sqlite3_stmt *q = NULL;
 
-  return (sql_check_ok(sql_prepare(&q, update_pkey_type))               &&
-          sql_check_ok(sqlite3_bind_int64(q, 1, object_handle))         &&
-          sql_check_ok(sqlite3_bind_int64(q, 2, *pkey_type))            &&
-          sql_check_done(sqlite3_step(q))                               &&
-          sql_check_ok(sqlite3_finalize(q)));
+  int ok = (sql_check_ok(sql_prepare(&q, update_pkey_type))             &&
+            sql_check_ok(sqlite3_bind_int64(q, 1, object_handle))       &&
+            sql_check_ok(sqlite3_bind_int64(q, 2, *pkey_type))          &&
+            sql_check_done(sqlite3_step(q)));
+
+  sqlite3_finalize(q);
+  return ok;
+}
+
+/*
+ * Construct and store SKI (key hash) for a key object.
+ */
+
+static int p11_object_pkey_ski(const p11_session_t * const session,
+                               const CK_OBJECT_HANDLE object_handle_1,
+                               const CK_OBJECT_HANDLE object_handle_2,
+                               const uint8_t * const der, const size_t der_len,
+                               uint8_t *ski, const size_t ski_len)
+{
+  assert(session != NULL && der != NULL && ski != NULL);
+
+  static const char update_pkey_ski[] =
+    " UPDATE object SET hal_pkey_ski = ?2 WHERE object_handle = ?1";
+
+  hal_hash_handle_t hash = {HAL_HANDLE_NONE};
+
+  int ok = hal_check(hal_rpc_hash_initialize(p11_session_hal_client(session),
+                                             p11_session_hal_session(session),
+                                             &hash, P11_KEY_HASH_ALGORITHM, NULL, 0));
+  if (ok)
+    ok = hal_check(hal_rpc_hash_update(hash, der, der_len));
+
+  if (hash.handle != HAL_HANDLE_NONE)
+    ok = hal_check(hal_rpc_hash_finalize(hash, ski, ski_len)) && ok;
+
+  if (!ok)
+    return 0;
+
+  sqlite3_stmt *q = NULL;
+
+  ok = (sql_check_ok(sql_prepare(&q, update_pkey_ski))          &&
+        sql_check_ok(sqlite3_bind_int64(q, 1,
+                                        object_handle_1))       &&
+        sql_check_ok(sqlite3_bind_blob( q, 2,
+                                        ski, ski_len, NULL))    &&
+        sql_check_done(sqlite3_step(q)));
+
+  if (ok && object_handle_2 != CK_INVALID_HANDLE)
+    ok = (sql_check_ok(sqlite3_reset(q))                        &&
+          sql_check_ok(sqlite3_bind_int64(q, 1,
+                                          object_handle_2))     &&
+          sql_check_done(sqlite3_step(q)));
+
+  sqlite3_finalize(q);
+  return ok;
 }
 
 /*
@@ -1396,8 +1456,6 @@ static int p11_object_pkey_type(const CK_OBJECT_HANDLE object_handle,
 static inline int p11_object_get_rsa_public_key(const p11_session_t * const session,
                                                 const CK_OBJECT_HANDLE object_handle,
                                                 hal_pkey_handle_t *pkey_handle,
-                                                const char *flavor,
-                                                const uint8_t * const name, const size_t name_len,
                                                 const hal_key_flags_t flags)
 {
   static const char select_format[] =
@@ -1405,17 +1463,22 @@ static inline int p11_object_get_rsa_public_key(const p11_session_t * const sess
     "   AS (SELECT type, value FROM %s_attribute NATURAL JOIN object WHERE object_handle = ?1)"
     " SELECT a1.value, a2.value FROM a AS a1, a AS a2 WHERE a1.type = %u AND a2.type = %u";
 
+  const char *flavor = is_token_handle(object_handle) ? "token" : "session";
+
   uint8_t keybuf[hal_rsa_key_t_size];
   hal_rsa_key_t *key = NULL;
   sqlite3_stmt *q = NULL;
+  size_t ski_len = 0;
 
   int ok
-    = (sql_check_ok(sql_prepare(&q, select_format, flavor,
-                                CKA_MODULUS, CKA_PUBLIC_EXPONENT))     &&
-       sql_check_ok(sqlite3_bind_int64(q, 1, object_handle))           &&
-       sql_check_row(sqlite3_step(q))                                  &&
-       sqlite3_column_type(q, 0) == SQLITE_BLOB                        &&
-       sqlite3_column_type(q, 1) == SQLITE_BLOB                        &&
+    = (hal_check(hal_rpc_hash_get_digest_length(P11_KEY_HASH_ALGORITHM,
+                                                &ski_len))              &&
+       sql_check_ok(sql_prepare(&q, select_format, flavor,
+                                CKA_MODULUS, CKA_PUBLIC_EXPONENT))      &&
+       sql_check_ok(sqlite3_bind_int64(q, 1, object_handle))            &&
+       sql_check_row(sqlite3_step(q))                                   &&
+       sqlite3_column_type(q, 0) == SQLITE_BLOB                         &&
+       sqlite3_column_type(q, 1) == SQLITE_BLOB                         &&
        hal_check(hal_rsa_key_load_public(&key, keybuf, sizeof(keybuf),
                                          sqlite3_column_blob( q, 0),
                                          sqlite3_column_bytes(q, 0),
@@ -1423,12 +1486,14 @@ static inline int p11_object_get_rsa_public_key(const p11_session_t * const sess
                                          sqlite3_column_bytes(q, 1))));
 
   if (ok) {
-    uint8_t der[hal_rsa_public_key_to_der_len(key)];
-    ok = (hal_check(hal_rsa_public_key_to_der(key, der, NULL, sizeof(der))) &&
+    uint8_t der[hal_rsa_public_key_to_der_len(key)], ski[ski_len];
+    ok = (hal_check(hal_rsa_public_key_to_der(key, der, NULL, sizeof(der)))     &&
+          p11_object_pkey_ski(session, object_handle, CK_INVALID_HANDLE,
+                              der, sizeof(der), ski, sizeof(ski))               &&
           hal_check(hal_rpc_pkey_load(p11_session_hal_client(session),
                                       p11_session_hal_session(session),
                                       pkey_handle, HAL_KEY_TYPE_RSA_PUBLIC,
-                                      HAL_CURVE_NONE, name, name_len,
+                                      HAL_CURVE_NONE, ski, sizeof(ski),
                                       der, sizeof(der), flags)));
   }
 
@@ -1439,8 +1504,6 @@ static inline int p11_object_get_rsa_public_key(const p11_session_t * const sess
 static inline int p11_object_get_ec_public_key(const p11_session_t * const session,
                                                const CK_OBJECT_HANDLE object_handle,
                                                hal_pkey_handle_t *pkey_handle,
-                                               const char *flavor,
-                                               const uint8_t * const name, const size_t name_len,
                                                const hal_key_flags_t flags)
 {
   static const char select_format[] =
@@ -1448,33 +1511,40 @@ static inline int p11_object_get_ec_public_key(const p11_session_t * const sessi
     "   AS (SELECT type, value FROM %s_attribute NATURAL JOIN object WHERE object_handle = ?1)"
     " SELECT a1.value, a2.value FROM a AS a1, a AS a2 WHERE a1.type = %u AND a2.type = %u";
 
+  const char *flavor = is_token_handle(object_handle) ? "token" : "session";
+
   uint8_t keybuf[hal_ecdsa_key_t_size];
   hal_ecdsa_key_t *key = NULL;
   hal_curve_name_t curve;
   sqlite3_stmt *q = NULL;
+  size_t ski_len = 0;
 
   int ok
-    = (sql_check_ok(sql_prepare(&q, select_format, flavor,
-                                CKA_EC_PARAMS, CKA_EC_POINT))        &&
-       sql_check_ok(sqlite3_bind_int64(q, 1, object_handle))         &&
-       sql_check_row(sqlite3_step(q))                                &&
-       sqlite3_column_type(q, 0) == SQLITE_BLOB                      &&
-       sqlite3_column_type(q, 1) == SQLITE_BLOB                      &&
+    = (hal_check(hal_rpc_hash_get_digest_length(P11_KEY_HASH_ALGORITHM,
+                                                &ski_len))              &&
+       sql_check_ok(sql_prepare(&q, select_format, flavor,
+                                CKA_EC_PARAMS, CKA_EC_POINT))           &&
+       sql_check_ok(sqlite3_bind_int64(q, 1, object_handle))            &&
+       sql_check_row(sqlite3_step(q))                                   &&
+       sqlite3_column_type(q, 0) == SQLITE_BLOB                         &&
+       sqlite3_column_type(q, 1) == SQLITE_BLOB                         &&
        ec_curve_oid_to_name(sqlite3_column_blob( q, 0),
                             sqlite3_column_bytes(q, 0),
-                            &curve)                                  &&
+                            &curve)                                     &&
        hal_check(hal_ecdsa_key_from_ecpoint(&key, keybuf, sizeof(keybuf),
                                             sqlite3_column_blob( q, 1),
                                             sqlite3_column_bytes(q, 1),
                                             curve)));
 
   if (ok) {
-    uint8_t der[hal_ecdsa_public_key_to_der_len(key)];
-    ok = (hal_check(hal_ecdsa_public_key_to_der(key, der, NULL, sizeof(der))) &&
+    uint8_t der[hal_ecdsa_public_key_to_der_len(key)], ski[ski_len];
+    ok = (hal_check(hal_ecdsa_public_key_to_der(key, der, NULL, sizeof(der)))   &&
+          p11_object_pkey_ski(session, object_handle, CK_INVALID_HANDLE,
+                              der, sizeof(der), ski, sizeof(ski))               &&
           hal_check(hal_rpc_pkey_load(p11_session_hal_client(session),
                                       p11_session_hal_session(session),
                                       pkey_handle, HAL_KEY_TYPE_EC_PUBLIC,
-                                      curve, name, name_len,
+                                      curve, ski, sizeof(ski),
                                       der, sizeof(der), flags)));
   }
 
@@ -1486,11 +1556,8 @@ static int p11_object_get_pkey_handle(const p11_session_t * const session,
                                       const CK_OBJECT_HANDLE object_handle,
                                       hal_pkey_handle_t *pkey_handle)
 {
-  static const char select_format[] =
-    " SELECT value, hal_pkey_type FROM %s_attribute NATURAL JOIN object"
-    " WHERE object_handle = ?1 AND type = %u";
-
-  const char *flavor = is_token_handle(object_handle) ? "token" : "session";
+  static const char select_query[] =
+    " SELECT hal_pkey_type, hal_pkey_ski FROM object WHERE object_handle = ?1";
 
   hal_key_flags_t flags = is_token_handle(object_handle) ? 0 : HAL_KEY_FLAG_PROXIMATE;
   hal_key_type_t pkey_type;
@@ -1500,15 +1567,15 @@ static int p11_object_get_pkey_handle(const p11_session_t * const session,
 
   assert(pkey_handle != NULL);
 
-  if (!sql_check_ok(sql_prepare(&q, select_format, flavor, CKA_ID))     ||
-      !sql_check_ok(sqlite3_bind_int64(q, 1, object_handle))            ||
+  if (!sql_check_ok(sql_prepare(&q, select_query))              ||
+      !sql_check_ok(sqlite3_bind_int64(q, 1, object_handle))    ||
       !sql_check_row(sqlite3_step(q)))
     goto fail;
 
-  switch (sqlite3_column_type(q, 1)) {
+  switch (sqlite3_column_type(q, 0)) {
 
   case SQLITE_INTEGER:
-    pkey_type = (hal_key_type_t) sqlite3_column_int64(q, 1);
+    pkey_type = (hal_key_type_t) sqlite3_column_int64(q, 0);
     break;
 
   case SQLITE_NULL:
@@ -1520,25 +1587,31 @@ static int p11_object_get_pkey_handle(const p11_session_t * const session,
     goto fail;
   }
 
-  err = hal_rpc_pkey_find(p11_session_hal_client(session),
-                          p11_session_hal_session(session),
-                          pkey_handle, pkey_type,
-                          sqlite3_column_blob(q, 0),
-                          sqlite3_column_bytes(q, 0),
-                          flags);
+  switch (sqlite3_column_type(q, 1)) {
+
+  case SQLITE_BLOB:
+    err = hal_rpc_pkey_find(p11_session_hal_client(session), p11_session_hal_session(session), pkey_handle,
+                            pkey_type, sqlite3_column_blob(q, 1), sqlite3_column_bytes(q, 1), flags);
+    break;
+
+  case SQLITE_NULL:
+    err = HAL_ERROR_KEY_NOT_FOUND;
+    break;
+
+  default:
+    goto fail;
+  }
 
   if (err == HAL_ERROR_KEY_NOT_FOUND) {
     switch (pkey_type) {
 
     case HAL_KEY_TYPE_RSA_PUBLIC:
-      if (!p11_object_get_rsa_public_key(session, object_handle, pkey_handle, flavor,
-                                         sqlite3_column_blob(q, 0), sqlite3_column_bytes(q, 0), flags))
+      if (!p11_object_get_rsa_public_key(session, object_handle, pkey_handle, flags))
         goto fail;
       break;
 
     case HAL_KEY_TYPE_EC_PUBLIC:
-      if (!p11_object_get_ec_public_key(session, object_handle, pkey_handle, flavor,
-                                        sqlite3_column_blob(q, 0), sqlite3_column_bytes(q, 0), flags))
+      if (!p11_object_get_ec_public_key(session, object_handle, pkey_handle, flags))
         goto fail;
       break;
 
@@ -1897,9 +1970,6 @@ static CK_RV p11_template_check_2(const p11_session_t *session,
  * possible through the object descriptor.
  *
  * Key usage handling here is based on RFC 5280 4.2.1.3.
- *
- * PKCS #11 suggests but does not require CKA_ID values for public and
- * private key to match.
  */
 
 static CK_RV p11_check_keypair_attributes(const p11_session_t *session,
@@ -2007,13 +2077,13 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session,
                                        const CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
                                        const CK_ULONG ulPrivateKeyAttributeCount,
                                        const CK_OBJECT_HANDLE private_handle,
-                                       const hal_key_flags_t private_flags,
-                                       const uint8_t * const id, const size_t id_len)
+                                       const hal_key_flags_t private_flags)
 {
   const uint8_t *public_exponent = const_0x010001;
   size_t public_exponent_len = sizeof(const_0x010001);
   hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
   CK_ULONG keysize = 0;
+  size_t ski_len = 0;
   CK_RV rv;
   int i;
 
@@ -2039,22 +2109,28 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session,
     }
   }
 
-  if (keysize == 0 || id == NULL)
+  if (keysize == 0)
     return CKR_TEMPLATE_INCOMPLETE;
 
+  if (!hal_check(hal_rpc_hash_get_digest_length(P11_KEY_HASH_ALGORITHM, &ski_len)))
+    lose(CKR_FUNCTION_FAILED);
+
   if (!hal_check(hal_rpc_pkey_generate_rsa(p11_session_hal_client(session),
                                            p11_session_hal_session(session),
-                                           &pkey, id, id_len, keysize,
+                                           &pkey, (const uint8_t *) "", 0, keysize,
                                            public_exponent, public_exponent_len,
                                            private_flags)))
     lose(CKR_FUNCTION_FAILED);
 
   {
-    uint8_t der[hal_rpc_pkey_get_public_key_len(pkey)], keybuf[hal_rsa_key_t_size];
+    uint8_t der[hal_rpc_pkey_get_public_key_len(pkey)], keybuf[hal_rsa_key_t_size], ski[ski_len];
     size_t der_len, modulus_len;
     hal_rsa_key_t *key = NULL;
 
     if (!hal_check(hal_rpc_pkey_get_public_key(pkey, der, &der_len, sizeof(der)))               ||
+        !p11_object_pkey_ski(session, private_handle, public_handle,
+                             der, sizeof(der), ski, sizeof(ski))                                ||
+        !hal_check(hal_rpc_pkey_rename(pkey, ski, sizeof(ski)))                                 ||
         !hal_check(hal_rsa_public_key_from_der(&key, keybuf, sizeof(keybuf), der, der_len))     ||
         !hal_check(hal_rsa_key_get_modulus(key, NULL, &modulus_len, 0)))
       lose(CKR_FUNCTION_FAILED);
@@ -2086,13 +2162,13 @@ static CK_RV generate_keypair_ec(p11_session_t *session,
                                  const CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
                                  const CK_ULONG ulPrivateKeyAttributeCount,
                                  const CK_OBJECT_HANDLE private_handle,
-                                 const hal_key_flags_t private_flags,
-                                 const uint8_t * const id, const size_t id_len)
+                                 const hal_key_flags_t private_flags)
 {
   hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
   const CK_BYTE *params = NULL;
   hal_curve_name_t curve;
   size_t params_len;
+  size_t ski_len = 0;
   CK_RV rv;
   int i;
 
@@ -2112,23 +2188,29 @@ static CK_RV generate_keypair_ec(p11_session_t *session,
     }
   }
 
-  if (!ec_curve_oid_to_name(params, params_len, &curve) || id == NULL)
+  if (!ec_curve_oid_to_name(params, params_len, &curve))
     return CKR_TEMPLATE_INCOMPLETE;
 
+  if (!hal_check(hal_rpc_hash_get_digest_length(P11_KEY_HASH_ALGORITHM, &ski_len)))
+    lose(CKR_FUNCTION_FAILED);
+
   if (!hal_check(hal_rpc_pkey_generate_ec(p11_session_hal_client(session),
                                           p11_session_hal_session(session),
-                                          &pkey, id, id_len, curve,
+                                          &pkey, (const uint8_t *) "", 0, curve,
                                           private_flags))                       ||
       !p11_attribute_set(public_handle,  CKA_EC_PARAMS, params, params_len)     ||
       !p11_attribute_set(private_handle, CKA_EC_PARAMS, params, params_len))
     lose(CKR_FUNCTION_FAILED);
 
   {
-    uint8_t der[hal_rpc_pkey_get_public_key_len(pkey)], keybuf[hal_ecdsa_key_t_size];
+    uint8_t der[hal_rpc_pkey_get_public_key_len(pkey)], keybuf[hal_ecdsa_key_t_size], ski[ski_len];
     hal_ecdsa_key_t *key = NULL;
     size_t der_len;
 
     if (!hal_check(hal_rpc_pkey_get_public_key(pkey, der, &der_len, sizeof(der)))               ||
+        !p11_object_pkey_ski(session, private_handle, public_handle,
+                             der, sizeof(der), ski, sizeof(ski))                                ||
+        !hal_check(hal_rpc_pkey_rename(pkey, ski, sizeof(ski)))                                 ||
         !hal_check(hal_ecdsa_public_key_from_der(&key, keybuf, sizeof(keybuf), der, der_len)))
       lose(CKR_FUNCTION_FAILED);
 
@@ -2167,8 +2249,7 @@ static CK_RV generate_keypair(p11_session_t *session,
                                                          const CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
                                                          const CK_ULONG ulPrivateKeyAttributeCount,
                                                          const CK_OBJECT_HANDLE private_handle,
-                                                         const hal_key_flags_t private_flags,
-                                                         const uint8_t * const id, const size_t id_len),
+                                                         const hal_key_flags_t private_flags),
                               const p11_descriptor_t * const public_descriptor,
                               const p11_descriptor_t * const private_descriptor)
 {
@@ -2218,25 +2299,11 @@ static CK_RV generate_keypair(p11_session_t *session,
                                           private_descriptor, pMechanism)) == CK_INVALID_HANDLE)
     lose(CKR_FUNCTION_FAILED);
 
-  {
-    CK_ULONG id_len = 0;
-
-    if (!p11_attribute_get(private_handle, CKA_ID, NULL, &id_len, 0) &&
-        !p11_attribute_get(public_handle,  CKA_ID, NULL, &id_len, 0))
-      lose(CKR_TEMPLATE_INCOMPLETE);
-
-    uint8_t id[id_len];
-
-    if (!p11_attribute_get(private_handle, CKA_ID, id, NULL, (size_t) id_len) &&
-        !p11_attribute_get(public_handle,  CKA_ID, id, NULL, (size_t) id_len))
-      lose(CKR_TEMPLATE_INCOMPLETE);
-
-    if ((rv = mechanism_handler(session,
-                                pPublicKeyTemplate,  ulPublicKeyAttributeCount,  public_handle,  public_flags,
-                                pPrivateKeyTemplate, ulPrivateKeyAttributeCount, private_handle, private_flags,
-                                id, id_len)) != CKR_OK)
-      goto fail;
-  }
+  rv = mechanism_handler(session,
+                         pPublicKeyTemplate,  ulPublicKeyAttributeCount,  public_handle,  public_flags,
+                         pPrivateKeyTemplate, ulPrivateKeyAttributeCount, private_handle, private_flags);
+  if (rv != CKR_OK)
+    goto fail;
 
   if (!sql_exec("COMMIT"))
     lose(CKR_FUNCTION_FAILED);
diff --git a/schema.sql b/schema.sql
index 8a81505..bc984ab 100644
--- a/schema.sql
+++ b/schema.sql
@@ -64,6 +64,7 @@ CREATE TEMPORARY TABLE IF NOT EXISTS object (
         object_handle           INTEGER NOT NULL UNIQUE
                                 CHECK (object_handle > 0 AND object_handle <= 0xFFFFFFFF),
         hal_pkey_type           INTEGER,
+        hal_pkey_ski            BLOB,
         session_id              INTEGER REFERENCES session
                                 ON DELETE CASCADE ON UPDATE CASCADE
                                 DEFERRABLE INITIALLY DEFERRED,



More information about the Commits mailing list