[Cryptech-Commits] [sw/pkcs11] 01/01: Hack PKCS #11 to work with revised libhal pkey API.

git at cryptech.is git at cryptech.is
Sat Sep 3 06:32:16 UTC 2016


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

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

commit 8a36a9c42b6c327056ca334d556c221c28375d15
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Sat Sep 3 02:27:09 2016 -0400

    Hack PKCS #11 to work with revised libhal pkey API.
---
 Makefile      |  14 ++--
 pkcs11.c      | 249 +++++++++++++++++++++++-----------------------------------
 schema.sql    |   4 +-
 unit_tests.py |  23 +++---
 4 files changed, 123 insertions(+), 167 deletions(-)

diff --git a/Makefile b/Makefile
index 0eb86e3..acb20f3 100644
--- a/Makefile
+++ b/Makefile
@@ -197,7 +197,7 @@ TAGS: *.[ch]
 # Basic testing, via the Python unittest library and our py11 interface code
 
 test: all
-	sudo python unit_tests.py
+	python unit_tests.py
 
 # Further testing using hsmbully, if we can find a copy of it.
 
@@ -217,21 +217,21 @@ ifneq "${HSMBULLY}" ""
 
   bully: all
 	set -x; \
-	sudo rm -f ${HSMBULLY_DATABASE} ${HSMBULLY_DATABASE}-journal ${HSMBULLY_KS_CLIENT} ${HSMBULLY_KS_SERVER}; \
+	rm -f ${HSMBULLY_DATABASE} ${HSMBULLY_DATABASE}-journal ${HSMBULLY_KS_CLIENT} ${HSMBULLY_KS_SERVER}; \
 	if test -x '${HSMBULLY_SERVER_BIN}'; \
 	then \
-		sudo CRYPTECH_KEYSTORE=${HSMBULLY_KS_SERVER} ${HSMBULLY_SERVER_BIN} & \
+		CRYPTECH_KEYSTORE=${HSMBULLY_KS_SERVER} ${HSMBULLY_SERVER_BIN} & \
 		pid=$$!; \
 		sleep 5; \
 		(echo YouReallyNeedToChangeThisPINRightNowWeAreNotKidding; echo fnord; echo fnord) | \
 		CRYPTECH_KEYSTORE=${HSMBULLY_KS_CLIENT} ./p11util --set-so-pin --set-user-pin --pin-from-stdin; \
 		PKCS11_DATABASE=${HSMBULLY_DATABASE} CRYPTECH_KEYSTORE=${HSMBULLY_KS_CLIENT} ${HSMBULLY} ${HSMBULLY_OPTIONS}; \
-		sudo kill $$pid; \
+		kill $$pid; \
 	else \
 		(echo YouReallyNeedToChangeThisPINRightNowWeAreNotKidding; echo fnord; echo fnord) | \
-		sudo CRYPTECH_KEYSTORE=${HSMBULLY_KS_CLIENT} ./p11util --set-so-pin --set-user-pin --pin-from-stdin; \
-		sudo PKCS11_DATABASE=${HSMBULLY_DATABASE} CRYPTECH_KEYSTORE=${HSMBULLY_KS_CLIENT} ${HSMBULLY} ${HSMBULLY_OPTIONS}; \
+		CRYPTECH_KEYSTORE=${HSMBULLY_KS_CLIENT} ./p11util --set-so-pin --set-user-pin --pin-from-stdin; \
+		PKCS11_DATABASE=${HSMBULLY_DATABASE} CRYPTECH_KEYSTORE=${HSMBULLY_KS_CLIENT} ${HSMBULLY} ${HSMBULLY_OPTIONS}; \
 	fi; \
-	sudo rm -f ${HSMBULLY_DATABASE} ${HSMBULLY_DATABASE}-journal ${HSMBULLY_KS_CLIENT} ${HSMBULLY_KS_SERVER}
+	rm -f ${HSMBULLY_DATABASE} ${HSMBULLY_DATABASE}-journal ${HSMBULLY_KS_CLIENT} ${HSMBULLY_KS_SERVER}
 
 endif
diff --git a/pkcs11.c b/pkcs11.c
index cf354e6..a482de0 100644
--- a/pkcs11.c
+++ b/pkcs11.c
@@ -1474,66 +1474,31 @@ static CK_OBJECT_HANDLE p11_object_create(const p11_session_t *session,
 }
 
 /*
- * Bind PKCS #11 objects to keystore objects.
- *
- * This requires storing the pkey type (supplied) and the SKI
- * (calcualted from supplied public key DER) of the key.  We return
- * the calculated SKI so that the caller can use it as the pkey name.
- *
- * We don't work with pkey handles here because that would create a
- * chicken-and-egg problem, given that the values calculated and
- * stored by this function are what we use to look up a pkey given
- * a PKCS #11 key object.
+ * Bind PKCS #11 objects to keystore objects, via the key's pkey type
+ * and UUID.
  */
 
 static int p11_object_bind_pkey(const p11_session_t * const session,
-                                const hal_key_type_t pkey_type_1,
-                                const hal_key_type_t pkey_type_2,
-                                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)
+                                const CK_OBJECT_HANDLE object_handle,
+                                const hal_uuid_t * const pkey_uuid,
+                                const hal_key_type_t pkey_type)
 {
-  assert(session != NULL && der != NULL && ski != NULL);
+  assert(session != NULL && pkey_uuid != NULL);
 
   static const char update_format[] =
-    " UPDATE %s_object SET hal_pkey_type = ?1, hal_pkey_ski = ?2"
+    " UPDATE %s_object SET hal_pkey_type = ?1, hal_pkey_uuid = ?2"
     " WHERE %s_object_id = (SELECT %s_object_id FROM object WHERE object_handle = ?3)";
 
-  const char *flavor_1 = is_token_handle(object_handle_1) ? "token" : "session";
-  const char *flavor_2 = is_token_handle(object_handle_2) ? "token" : "session";
-
-  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 *q1 = NULL, *q2 = NULL;
-
-  ok = (sql_check_ok(sql_prepare(&q1, update_format, flavor_1, flavor_1, flavor_1))     &&
-        sql_check_ok(sqlite3_bind_int64(q1, 1, pkey_type_1))                            &&
-        sql_check_ok(sqlite3_bind_blob( q1, 2, ski, ski_len, NULL))                     &&
-        sql_check_ok(sqlite3_bind_int64(q1, 3, object_handle_1))                        &&
-        sql_check_done(sqlite3_step(q1)));
+  const char *flavor = is_token_handle(object_handle) ? "token" : "session";
+  sqlite3_stmt *q = NULL;
 
-  if (ok && object_handle_2 != CK_INVALID_HANDLE)
-    ok = (sql_check_ok(sql_prepare(&q2, update_format, flavor_2, flavor_2, flavor_2))   &&
-          sql_check_ok(sqlite3_bind_int64(q2, 1, pkey_type_2))                          &&
-          sql_check_ok(sqlite3_bind_blob( q2, 2, ski, ski_len, NULL))                   &&
-          sql_check_ok(sqlite3_bind_int64(q2, 3, object_handle_2))                      &&
-          sql_check_done(sqlite3_step(q2)));
+  int ok = (sql_check_ok(sql_prepare(&q, update_format, flavor, flavor, flavor))        &&
+            sql_check_ok(sqlite3_bind_int64(q, 1, pkey_type))                           &&
+            sql_check_ok(sqlite3_bind_blob( q, 2, pkey_uuid, sizeof(*pkey_uuid), NULL)) &&
+            sql_check_ok(sqlite3_bind_int64(q, 3, object_handle))                       &&
+            sql_check_done(sqlite3_step(q)));
 
-  sqlite3_finalize(q1);
-  sqlite3_finalize(q2);
+  sqlite3_finalize(q);
   return ok;
 }
 
@@ -1556,11 +1521,9 @@ static inline int p11_object_create_rsa_public_key(const p11_session_t * const s
   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
-    = (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(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                                                 &&
@@ -1572,18 +1535,21 @@ static inline int p11_object_create_rsa_public_key(const p11_session_t * const s
                                          sqlite3_column_bytes(q, 1))));
 
   if (ok) {
-    uint8_t der[hal_rsa_public_key_to_der_len(key)], ski[ski_len];
+    uint8_t der[hal_rsa_public_key_to_der_len(key)];
+    hal_uuid_t uuid;
     ok = (hal_check(hal_rsa_public_key_to_der(key, der, NULL, sizeof(der)))                     &&
-          p11_object_bind_pkey(session, HAL_KEY_TYPE_RSA_PUBLIC, HAL_KEY_TYPE_NONE,
-                               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, HAL_KEY_TYPE_RSA_PUBLIC, HAL_CURVE_NONE,
-                                      ski, sizeof(ski), der, sizeof(der), flags)));
+                                      &uuid, der, sizeof(der), flags))                          &&
+          p11_object_bind_pkey(session, object_handle, &uuid, HAL_KEY_TYPE_RSA_PUBLIC));
   }
 
-  (void) hal_rpc_pkey_close(pkey);
+  if (!ok && pkey.handle != HAL_HANDLE_NONE)
+    (void) hal_rpc_pkey_delete(pkey);
+  else
+    (void) hal_rpc_pkey_close(pkey);
+
   sqlite3_finalize(q);
   return ok;
 }
@@ -1604,11 +1570,9 @@ static inline int p11_object_create_ec_public_key(const p11_session_t * const se
   hal_ecdsa_key_t *key = NULL;
   hal_curve_name_t curve;
   sqlite3_stmt *q = NULL;
-  size_t ski_len = 0;
 
   int ok
-    = (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(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                                                 &&
@@ -1620,18 +1584,21 @@ static inline int p11_object_create_ec_public_key(const p11_session_t * const se
                                             curve)));
 
   if (ok) {
-    uint8_t der[hal_ecdsa_public_key_to_der_len(key)], ski[ski_len];
+    uint8_t der[hal_ecdsa_public_key_to_der_len(key)];
+    hal_uuid_t uuid;
     ok = (hal_check(hal_ecdsa_public_key_to_der(key, der, NULL, sizeof(der)))                   &&
-          p11_object_bind_pkey(session, HAL_KEY_TYPE_EC_PUBLIC, HAL_KEY_TYPE_NONE,
-                               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, HAL_KEY_TYPE_EC_PUBLIC, curve,
-                                      ski, sizeof(ski), der, sizeof(der), flags)));
+                                      &uuid, der, sizeof(der), flags))                          &&
+          p11_object_bind_pkey(session, object_handle, &uuid, HAL_KEY_TYPE_EC_PUBLIC));
   }
 
-  (void) hal_rpc_pkey_close(pkey);
+  if (!ok && pkey.handle != HAL_HANDLE_NONE)
+    (void) hal_rpc_pkey_delete(pkey);
+  else
+    (void) hal_rpc_pkey_close(pkey);
+
   sqlite3_finalize(q);
   return ok;
 }
@@ -1653,7 +1620,6 @@ static inline int p11_object_create_rsa_private_key(const p11_session_t * const
   uint8_t keybuf[hal_rsa_key_t_size];
   hal_rsa_key_t *key = NULL;
   sqlite3_stmt *q = NULL;
-  size_t ski_len = 0;
 
   const uint8_t *cka_private_exponent = NULL;   size_t cka_private_exponent_len = 0;
   const uint8_t *cka_prime_1 = NULL;            size_t cka_prime_1_len = 0;
@@ -1686,8 +1652,7 @@ static inline int p11_object_create_rsa_private_key(const p11_session_t * const
   }
 
   int ok
-    = (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(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                                                 &&
@@ -1703,23 +1668,24 @@ static inline int p11_object_create_rsa_private_key(const p11_session_t * const
                                           cka_exponent_2,               cka_exponent_2_len)));
 
   if (ok) {
-    const size_t private_len = hal_rsa_private_key_to_der_len(key);
-    const size_t public_len = hal_rsa_public_key_to_der_len(key);
-    uint8_t der[public_len > private_len ? public_len : private_len], ski[ski_len];
-    ok = (hal_check(hal_rsa_public_key_to_der(key, der, NULL, sizeof(der)))                     &&
-          p11_object_bind_pkey(session, HAL_KEY_TYPE_RSA_PRIVATE, HAL_KEY_TYPE_NONE,
-                               object_handle, CK_INVALID_HANDLE,
-                               der, public_len, ski, sizeof(ski))                               &&
-          hal_check(hal_rsa_private_key_to_der(key, der, NULL, sizeof(der)))                    &&
+    uint8_t der[hal_rsa_private_key_to_der_len(key)];
+    hal_uuid_t uuid;
+    ok = (hal_check(hal_rsa_private_key_to_der(key, der, NULL, sizeof(der)))                    &&
           hal_check(hal_rpc_pkey_load(p11_session_hal_client(session),
                                       p11_session_hal_session(session),
                                       &pkey, HAL_KEY_TYPE_RSA_PRIVATE, HAL_CURVE_NONE,
-                                      ski, sizeof(ski), der, private_len, flags)));
+                                      &uuid, der, sizeof(der), flags))                          &&
+          p11_object_bind_pkey(session, object_handle, &uuid, HAL_KEY_TYPE_RSA_PRIVATE));
     memset(der, 0, sizeof(der));
   }
 
   memset(keybuf, 0, sizeof(keybuf));
-  (void) hal_rpc_pkey_close(pkey);
+
+  if (!ok && pkey.handle != HAL_HANDLE_NONE)
+    (void) hal_rpc_pkey_delete(pkey);
+  else
+    (void) hal_rpc_pkey_close(pkey);
+
   sqlite3_finalize(q);
   return ok;
 }
@@ -1742,7 +1708,6 @@ static inline int p11_object_create_ec_private_key(const p11_session_t * const s
   hal_ecdsa_key_t *key = NULL;
   hal_curve_name_t curve;
   sqlite3_stmt *q = NULL;
-  size_t ski_len = 0;
   const uint8_t *ecpoint = NULL;
   size_t ecpoint_len = 0;
 
@@ -1753,8 +1718,7 @@ static inline int p11_object_create_ec_private_key(const p11_session_t * const s
       cka_value = template[i].pValue, cka_value_len = template[i].ulValueLen;
 
   int ok
-    = (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(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                                                 &&
@@ -1768,23 +1732,24 @@ static inline int p11_object_create_ec_private_key(const p11_session_t * const s
                                             cka_value,                          cka_value_len)));
 
   if (ok) {
-    const size_t private_len = hal_ecdsa_private_key_to_der_len(key);
-    const size_t public_len = hal_ecdsa_public_key_to_der_len(key);
-    uint8_t der[public_len > private_len ? public_len : private_len], ski[ski_len];
-    ok = (hal_check(hal_ecdsa_public_key_to_der(key, der, NULL, sizeof(der)))                   &&
-          p11_object_bind_pkey(session, HAL_KEY_TYPE_EC_PRIVATE, HAL_KEY_TYPE_NONE,
-                               object_handle, CK_INVALID_HANDLE,
-                               der, public_len, ski, sizeof(ski))                               &&
-          hal_check(hal_ecdsa_private_key_to_der(key, der, NULL, sizeof(der)))                  &&
+    uint8_t der[hal_ecdsa_private_key_to_der_len(key)];
+    hal_uuid_t uuid;
+    ok = (hal_check(hal_ecdsa_private_key_to_der(key, der, NULL, sizeof(der)))                  &&
           hal_check(hal_rpc_pkey_load(p11_session_hal_client(session),
                                       p11_session_hal_session(session),
                                       &pkey, HAL_KEY_TYPE_EC_PRIVATE, curve,
-                                      ski, sizeof(ski), der, private_len, flags)));
+                                      &uuid, der, sizeof(der), flags))                          &&
+          p11_object_bind_pkey(session, object_handle, &uuid, HAL_KEY_TYPE_EC_PRIVATE));
     memset(der, 0, sizeof(der));
   }
 
   memset(keybuf, 0, sizeof(keybuf));
-  (void) hal_rpc_pkey_close(pkey);
+
+  if (!ok && pkey.handle != HAL_HANDLE_NONE)
+    (void) hal_rpc_pkey_delete(pkey);
+  else
+    (void) hal_rpc_pkey_close(pkey);
+
   sqlite3_finalize(q);
   return ok;
 }
@@ -1798,9 +1763,9 @@ static int p11_object_get_pkey_handle(const p11_session_t * const session,
                                       hal_pkey_handle_t *pkey_handle)
 {
   static const char select_format[] =
-    " SELECT hal_pkey_type, hal_pkey_ski FROM %s_object NATURAL JOIN object WHERE object_handle = ?1";
+    " SELECT hal_pkey_type, hal_pkey_uuid FROM %s_object NATURAL JOIN object WHERE object_handle = ?1";
 
-  hal_key_flags_t flags = is_token_handle(object_handle) ? 0 : HAL_KEY_FLAG_PROXIMATE;
+  hal_key_flags_t flags = is_token_handle(object_handle) ? HAL_KEY_FLAG_TOKEN : 0;
   const char *flavor = is_token_handle(object_handle) ? "token" : "session";
   sqlite3_stmt *q = NULL;
   int ok = 0;
@@ -1811,15 +1776,15 @@ static int p11_object_get_pkey_handle(const p11_session_t * const session,
       !sql_check_ok(sqlite3_bind_int64(q, 1, object_handle))    ||
       !sql_check_row(sqlite3_step(q))                           ||
       sqlite3_column_type(q, 0) != SQLITE_INTEGER               ||
-      sqlite3_column_type(q, 1) != SQLITE_BLOB)
+      sqlite3_column_type(q, 1) != SQLITE_BLOB                  ||
+      sqlite3_column_bytes(q, 1) != sizeof(hal_uuid_t))
     goto fail;
 
   const hal_key_type_t pkey_type = sqlite3_column_int64(q, 0);
-  const uint8_t * const ski      = sqlite3_column_blob( q, 1);
-  const size_t ski_len           = sqlite3_column_bytes(q, 1);
+  const hal_uuid_t *   pkey_uuid = sqlite3_column_blob( q, 1);
 
   ok = hal_check(hal_rpc_pkey_find(p11_session_hal_client(session), p11_session_hal_session(session),
-                                   pkey_handle, pkey_type, ski, ski_len, flags));
+                                   pkey_handle, pkey_type, pkey_uuid, flags));
 
  fail:
   sqlite3_finalize(q);
@@ -2303,15 +2268,16 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session,
                                        const CK_OBJECT_HANDLE private_handle,
                                        const hal_key_flags_t private_flags)
 {
+  const int same_keystore = is_token_handle(public_handle) == is_token_handle(private_handle);
   const uint8_t *public_exponent = const_0x010001;
   size_t public_exponent_len = sizeof(const_0x010001);
   hal_pkey_handle_t pkey1 = {HAL_HANDLE_NONE}, pkey2 = {HAL_HANDLE_NONE};
   CK_ULONG keysize = 0;
-  size_t ski_len = 0;
+  hal_uuid_t uuid;
   CK_RV rv;
   int i;
 
-  assert(session != NULL && pPublicKeyTemplate != NULL && pPrivateKeyTemplate != NULL && is_token_handle(private_handle));
+  assert(session != NULL && pPublicKeyTemplate != NULL && pPrivateKeyTemplate != NULL);
 
   for (i = 0; i < ulPublicKeyAttributeCount; i++) {
     const CK_ATTRIBUTE_TYPE type = pPublicKeyTemplate[i].type;
@@ -2336,47 +2302,43 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session,
   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),
-                                           &pkey1, (const uint8_t *) "", 0, keysize,
+                                           &pkey1, &uuid, keysize,
                                            public_exponent, public_exponent_len,
-                                           private_flags)))
+                                           private_flags))                                      ||
+      !p11_object_bind_pkey(session, private_handle, &uuid, HAL_KEY_TYPE_RSA_PRIVATE))
     lose(CKR_FUNCTION_FAILED);
 
   {
-    uint8_t der[hal_rpc_pkey_get_public_key_len(pkey1)], keybuf[hal_rsa_key_t_size], ski[ski_len];
+    uint8_t der[hal_rpc_pkey_get_public_key_len(pkey1)], keybuf[hal_rsa_key_t_size];
     size_t der_len, modulus_len;
     hal_rsa_key_t *key = NULL;
 
-    const hal_key_type_t pkey2_type = is_token_handle(public_handle) ? HAL_KEY_TYPE_RSA_PRIVATE : HAL_KEY_TYPE_RSA_PUBLIC;
-
     if (!hal_check(hal_rpc_pkey_get_public_key(pkey1, der, &der_len, sizeof(der)))              ||
-        !p11_object_bind_pkey(session, HAL_KEY_TYPE_RSA_PRIVATE, pkey2_type,
-                              private_handle, public_handle,
-                              der, sizeof(der), ski, sizeof(ski))                               ||
-        !hal_check(hal_rpc_pkey_rename(pkey1, 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);
 
     uint8_t modulus[modulus_len];
 
-    if (!hal_check(hal_rsa_key_get_modulus(key, modulus, NULL, sizeof(modulus)))        ||
-        !p11_attribute_set(public_handle,  CKA_MODULUS, modulus, modulus_len)           ||
+    if (!hal_check(hal_rsa_key_get_modulus(key, modulus, NULL, sizeof(modulus)))                ||
+        !p11_attribute_set(public_handle,  CKA_MODULUS, modulus, modulus_len)                   ||
         !p11_attribute_set(private_handle, CKA_MODULUS, modulus, modulus_len))
       lose(CKR_FUNCTION_FAILED);
 
-    if (!is_token_handle(public_handle) &&
+    if (!same_keystore                                                                          &&
         !hal_check(hal_rpc_pkey_load(p11_session_hal_client(session),
                                      p11_session_hal_session(session),
                                      &pkey2, HAL_KEY_TYPE_RSA_PUBLIC, HAL_CURVE_NONE,
-                                     ski, sizeof(ski), der, der_len, public_flags)))
+                                     &uuid, der, der_len, public_flags)))
       lose(CKR_FUNCTION_FAILED);
   }
 
+  if (!p11_object_bind_pkey(session, public_handle,  &uuid,
+                            same_keystore ? HAL_KEY_TYPE_RSA_PRIVATE : HAL_KEY_TYPE_RSA_PUBLIC))
+    lose(CKR_FUNCTION_FAILED);
+
   rv = CKR_OK;
 
  fail:
@@ -2399,15 +2361,16 @@ static CK_RV generate_keypair_ec(p11_session_t *session,
                                  const CK_OBJECT_HANDLE private_handle,
                                  const hal_key_flags_t private_flags)
 {
+  const int same_keystore = is_token_handle(public_handle) == is_token_handle(private_handle);
   hal_pkey_handle_t pkey1 = {HAL_HANDLE_NONE}, pkey2 = {HAL_HANDLE_NONE};
   const CK_BYTE *params = NULL;
   hal_curve_name_t curve;
   size_t params_len;
-  size_t ski_len = 0;
+  hal_uuid_t uuid;
   CK_RV rv;
   int i;
 
-  assert(session != NULL && pPublicKeyTemplate != NULL && pPrivateKeyTemplate != NULL && is_token_handle(private_handle));
+  assert(session != NULL && pPublicKeyTemplate != NULL && pPrivateKeyTemplate != NULL);
 
   for (i = 0; i < ulPublicKeyAttributeCount; i++) {
     const CK_ATTRIBUTE_TYPE type = pPublicKeyTemplate[i].type;
@@ -2426,46 +2389,41 @@ static CK_RV generate_keypair_ec(p11_session_t *session,
   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),
-                                          &pkey1, (const uint8_t *) "", 0,
-                                          curve, private_flags))                ||
-      !p11_attribute_set(public_handle,  CKA_EC_PARAMS, params, params_len)     ||
+                                          &pkey1, &uuid, curve, private_flags))                 ||
+      !p11_object_bind_pkey(session, private_handle, &uuid, HAL_KEY_TYPE_EC_PRIVATE)            ||
+      !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(pkey1)], keybuf[hal_ecdsa_key_t_size], ski[ski_len];
+    uint8_t der[hal_rpc_pkey_get_public_key_len(pkey1)], keybuf[hal_ecdsa_key_t_size];
     hal_ecdsa_key_t *key = NULL;
     size_t der_len;
 
-    const hal_key_type_t pkey2_type = is_token_handle(public_handle) ? HAL_KEY_TYPE_EC_PRIVATE : HAL_KEY_TYPE_EC_PUBLIC;
-
     if (!hal_check(hal_rpc_pkey_get_public_key(pkey1, der, &der_len, sizeof(der)))              ||
-        !p11_object_bind_pkey(session, HAL_KEY_TYPE_EC_PRIVATE, pkey2_type,
-                              private_handle, public_handle,
-                              der, sizeof(der), ski, sizeof(ski))                               ||
-        !hal_check(hal_rpc_pkey_rename(pkey1, ski, sizeof(ski)))                                ||
         !hal_check(hal_ecdsa_public_key_from_der(&key, keybuf, sizeof(keybuf), der, der_len)))
       lose(CKR_FUNCTION_FAILED);
 
     uint8_t point[hal_ecdsa_key_to_ecpoint_len(key)];
 
-    if (!hal_check(hal_ecdsa_key_to_ecpoint(key, point, NULL, sizeof(point)))   ||
+    if (!hal_check(hal_ecdsa_key_to_ecpoint(key, point, NULL, sizeof(point)))                   ||
         !p11_attribute_set(public_handle,  CKA_EC_POINT, point, sizeof(point)))
       lose(CKR_FUNCTION_FAILED);
 
-    if (!is_token_handle(public_handle) &&
+    if (!same_keystore                                                                          &&
         !hal_check(hal_rpc_pkey_load(p11_session_hal_client(session),
                                      p11_session_hal_session(session),
                                      &pkey2, HAL_KEY_TYPE_EC_PUBLIC, curve,
-                                     ski, sizeof(ski), der, der_len, public_flags)))
+                                     &uuid, der, der_len, public_flags)))
       lose(CKR_FUNCTION_FAILED);
   }
 
+  if (!p11_object_bind_pkey(session, public_handle, &uuid,
+                            same_keystore ? HAL_KEY_TYPE_EC_PRIVATE : HAL_KEY_TYPE_EC_PUBLIC))
+    lose(CKR_FUNCTION_FAILED);
+
   rv = CKR_OK;
 
  fail:
@@ -2477,10 +2435,6 @@ static CK_RV generate_keypair_ec(p11_session_t *session,
 /*
  * Key pair generation.  This needs a mechanism-specific function to
  * do the inner bits, but there's a lot of boilerplate.
- *
- * We have no real way to protect session objects, so we don't allow
- * them to hold private keys.  PKCS #11 wants us to report this kind
- * of restriction as a template inconsistency.
  */
 
 static CK_RV generate_keypair(p11_session_t *session,
@@ -2533,11 +2487,11 @@ static CK_RV generate_keypair(p11_session_t *session,
     if (pPrivateKeyTemplate[i].type == CKA_TOKEN)
       private_handle_flavor = p11_handle_flavor_from_cka_token(pPrivateKeyTemplate[i].pValue);
 
-  if (public_handle_flavor == handle_flavor_session_object)
-    public_flags |= HAL_KEY_FLAG_PROXIMATE;
+  if (public_handle_flavor == handle_flavor_token_object)
+    public_flags |= HAL_KEY_FLAG_TOKEN;
 
-  if (private_handle_flavor == handle_flavor_session_object)
-    return CKR_TEMPLATE_INCONSISTENT;
+  if (private_handle_flavor == handle_flavor_token_object)
+    private_flags |= HAL_KEY_FLAG_TOKEN;
 
   if (!sql_exec("BEGIN"))
     lose(CKR_FUNCTION_FAILED);
@@ -3088,7 +3042,7 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID,
   psnprintf(pInfo->serialNumber, sizeof(pInfo->serialNumber),
             "007");
 
-  pInfo->flags = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED;
+  pInfo->flags = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED;
 
 #warning Have not yet sorted out token flags
 #if 0
@@ -3447,9 +3401,6 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession,
       lose(CKR_SESSION_READ_ONLY);
   }
 
-  if (flavor == handle_flavor_session_object && *cka_class == CKO_PRIVATE_KEY)
-    lose(CKR_TEMPLATE_INCONSISTENT);
-
   if (!sql_exec("BEGIN"))
     lose(CKR_FUNCTION_FAILED);
 
@@ -3469,7 +3420,7 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession,
       lose(CKR_FUNCTION_FAILED);
   }
 
-  hal_key_flags_t flags = flavor == handle_flavor_session_object ? HAL_KEY_FLAG_PROXIMATE : 0;
+  hal_key_flags_t flags = flavor == handle_flavor_token_object ? HAL_KEY_FLAG_TOKEN : 0;
 
   for (int i = 0; i < ulCount; i++)
     p11_attribute_apply_keyusage(&flags, pTemplate[i].type, pTemplate[i].pValue);
diff --git a/schema.sql b/schema.sql
index 9de8ce2..1db361c 100644
--- a/schema.sql
+++ b/schema.sql
@@ -78,7 +78,7 @@ CREATE TEMPORARY TABLE IF NOT EXISTS object (
 CREATE TEMPORARY TABLE IF NOT EXISTS session_object (
         session_object_id       INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
         hal_pkey_type           INTEGER,
-        hal_pkey_ski            BLOB,
+        hal_pkey_uuid           BLOB,
         object_id               INTEGER NOT NULL UNIQUE
                                 REFERENCES object
                                 ON DELETE CASCADE ON UPDATE CASCADE
@@ -96,7 +96,7 @@ CREATE TEMPORARY TABLE IF NOT EXISTS session_attribute (
 CREATE TABLE IF NOT EXISTS token_object (
         token_object_id         INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
         hal_pkey_type           INTEGER,
-        hal_pkey_ski            BLOB
+        hal_pkey_uuid           BLOB
 );
 
 CREATE TABLE IF NOT EXISTS token_attribute (
diff --git a/unit_tests.py b/unit_tests.py
index c9d3886..02863c8 100644
--- a/unit_tests.py
+++ b/unit_tests.py
@@ -259,27 +259,32 @@ class TestKeys(TestCase):
     def test_keygen_token_vs_session(self):
         "Test C_GenerateKeypair() CKA_TOKEN restrictions"
 
-        with self.assertRaises(CKR_TEMPLATE_INCONSISTENT):
-            p11.C_GenerateKeyPair(self.session, CKM_EC_KEY_PAIR_GEN, CKA_TOKEN = False,
-                                  CKA_ID = "EC-P256", CKA_EC_PARAMS = self.oid_p256,
-                                  CKA_SIGN = True, CKA_VERIFY = True)
+        self.assertIsKeypair(
+          p11.C_GenerateKeyPair(self.session, CKM_EC_KEY_PAIR_GEN, CKA_TOKEN = False,
+                                CKA_ID = "EC-P256", CKA_EC_PARAMS = self.oid_p256,
+                                CKA_SIGN = True, CKA_VERIFY = True))
 
         self.assertIsKeypair(
           p11.C_GenerateKeyPair(self.session, CKM_EC_KEY_PAIR_GEN, CKA_TOKEN = True,
                                 CKA_ID = "EC-P256", CKA_EC_PARAMS = self.oid_p256,
                                 CKA_SIGN = True, CKA_VERIFY = True))
 
+        # Might need to do this until we expand the number of key slots
+        if False:
+          for handle in p11.FindObjects(self.session):
+            p11.C_DestroyObject(self.session, handle)
+
         self.assertIsKeypair(
             p11.C_GenerateKeyPair(self.session, CKM_EC_KEY_PAIR_GEN,
                                   public_CKA_TOKEN = False, private_CKA_TOKEN = True,
                                   CKA_ID = "EC-P256", CKA_EC_PARAMS = self.oid_p256,
                                   CKA_SIGN = True, CKA_VERIFY = True))
 
-        with self.assertRaises(CKR_TEMPLATE_INCONSISTENT):
-            p11.C_GenerateKeyPair(self.session, CKM_EC_KEY_PAIR_GEN,
-                                  public_CKA_TOKEN = True, private_CKA_TOKEN = False,
-                                  CKA_ID = "EC-P256", CKA_EC_PARAMS = self.oid_p256,
-                                  CKA_SIGN = True, CKA_VERIFY = True)
+        self.assertIsKeypair(
+          p11.C_GenerateKeyPair(self.session, CKM_EC_KEY_PAIR_GEN,
+                                public_CKA_TOKEN = True, private_CKA_TOKEN = False,
+                                CKA_ID = "EC-P256", CKA_EC_PARAMS = self.oid_p256,
+                                CKA_SIGN = True, CKA_VERIFY = True))
 
     def test_gen_sign_verify_ecdsa_p256_sha256(self):
         "Generate/sign/verify with ECDSA-P256-SHA-256"



More information about the Commits mailing list