[Cryptech-Commits] [sw/pkcs11] 01/02: Add (back) ability to construct public keys from stored attributes.

git at cryptech.is git at cryptech.is
Sat May 14 20:36:16 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 7ce10ab8b2351157445a281695dddae0a91f7580
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Sat May 14 14:04:09 2016 -0400

    Add (back) ability to construct public keys from stored attributes.
---
 pkcs11.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 128 insertions(+), 15 deletions(-)

diff --git a/pkcs11.c b/pkcs11.c
index 5d30d34..6ed7bc3 100644
--- a/pkcs11.c
+++ b/pkcs11.c
@@ -1394,6 +1394,95 @@ static int p11_object_pkey_type(const CK_OBJECT_HANDLE object_handle,
  * Fetch the libhal pkey handle for a key object.
  */
 
+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[] =
+    " WITH a (type, value) "
+    "   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";
+
+  uint8_t keybuf[hal_rsa_key_t_size];
+  hal_rsa_key_t *key = NULL;
+  sqlite3_stmt *q = NULL;
+
+  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_rsa_key_load_public(&key, keybuf, sizeof(keybuf),
+                                         sqlite3_column_blob( q, 0),
+                                         sqlite3_column_bytes(q, 0),
+                                         sqlite3_column_blob( q, 1),
+                                         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))) &&
+          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,
+                                      der, sizeof(der), flags)));
+  }
+
+  sqlite3_finalize(q);
+  return ok;
+}
+
+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[] =
+    " WITH a (type, value) "
+    "   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";
+
+  uint8_t keybuf[hal_ecdsa_key_t_size];
+  hal_ecdsa_key_t *key = NULL;
+  hal_curve_name_t curve;
+  sqlite3_stmt *q = NULL;
+
+  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                      &&
+       ec_curve_oid_to_name(sqlite3_column_blob( q, 0),
+                            sqlite3_column_bytes(q, 0),
+                            &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))) &&
+          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,
+                                      der, sizeof(der), flags)));
+  }
+
+  sqlite3_finalize(q);
+  return ok;
+}
+
 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)
@@ -1404,17 +1493,17 @@ static int p11_object_get_pkey_handle(const p11_session_t * const session,
 
   const char *flavor = is_token_handle(object_handle) ? "token" : "session";
 
+  hal_key_flags_t flags = is_token_handle(object_handle) ? 0 : HAL_KEY_FLAG_PROXIMATE;
   hal_key_type_t pkey_type;
   sqlite3_stmt *q = NULL;
-  int ok;
+  hal_error_t err;
+  int ok = 0;
 
   assert(pkey_handle != NULL);
 
-  ok = (sql_check_ok(sql_prepare(&q, select_format, flavor, CKA_ID))    &&
-        sql_check_ok(sqlite3_bind_int64(q, 1, object_handle))           &&
-        sql_check_row(sqlite3_step(q)));
-
-  if (!ok)
+  if (!sql_check_ok(sql_prepare(&q, select_format, flavor, CKA_ID))     ||
+      !sql_check_ok(sqlite3_bind_int64(q, 1, object_handle))            ||
+      !sql_check_row(sqlite3_step(q)))
     goto fail;
 
   switch (sqlite3_column_type(q, 1)) {
@@ -1424,22 +1513,46 @@ static int p11_object_get_pkey_handle(const p11_session_t * const session,
     break;
 
   case SQLITE_NULL:
-    ok = p11_object_pkey_type(object_handle, &pkey_type);
-    if (!ok)
+    if (!p11_object_pkey_type(object_handle, &pkey_type))
       goto fail;
     break;
 
   default:
-    ok = 0;
     goto fail;
   }
 
-  ok = hal_check(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),
-                                   0));
+  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);
+
+  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))
+        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))
+        goto fail;
+      break;
+
+    default:
+      (void) hal_check(err);
+      goto fail;
+    }
+  }
+
+  else if (!hal_check(err))
+    goto fail;
+
+  ok = 1;
 
  fail:
   sqlite3_finalize(q);



More information about the Commits mailing list