[Cryptech-Commits] [sw/pkcs11] 11/20: Extracting the private key from a public key object doesn't work very well.

git at cryptech.is git at cryptech.is
Tue Jul 7 18:26:41 UTC 2015


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

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

commit 94bf5c0d622698ac90cd2b1735587a840f3602ee
Author: Rob Austein <sra at hactrn.net>
Date:   Wed Jun 24 17:03:21 2015 -0400

    Extracting the private key from a public key object doesn't work very well.
---
 pkcs11.c | 74 +++++++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 45 insertions(+), 29 deletions(-)

diff --git a/pkcs11.c b/pkcs11.c
index f77516a..255069a 100644
--- a/pkcs11.c
+++ b/pkcs11.c
@@ -108,7 +108,7 @@
 #endif
 
 #ifndef DEBUG_HAL
-#define DEBUG_HAL       0
+#define DEBUG_HAL       1
 #endif
 
 #ifndef DEBUG_PKCS11
@@ -354,11 +354,11 @@ static pid_t initialized_pid;
 
 #if DEBUG_HAL
 
-static int _hal_check(const hal_error_t err, const char * const expr, const const * const file, const unsigned line)
+static int _hal_check(const hal_error_t err, const char * const expr, const char * const file, const unsigned line)
 {
   if (err == HAL_OK)
     return 1;
-  fprintf(stderr, "%s:%u: %s returned %s\n", file, line, hal_errorstring(err), expr);
+  fprintf(stderr, "%s:%u: %s returned %s\n", file, line, expr, hal_error_string(err));
   return 0;
 }
 
@@ -1444,6 +1444,46 @@ static int p11_object_get_rsa_private_key(const CK_OBJECT_HANDLE object_handle,
   return ok;
 }
 
+#warning Revisit return semantics of p11_object_get_rsa_private_key() and p11_object_get_rsa_public_key()
+
+/*
+ * Fetch an RSA public key.
+ *
+ * Public keys aren't stored separately the way that private keys are,
+ * so we're looking for the public components so we can load them into
+ * a key objet.
+ */
+
+static int p11_object_get_rsa_public_key(const CK_OBJECT_HANDLE object_handle,
+                                         hal_rsa_key_t *key,
+                                         uint8_t *keybuf, const size_t keybuf_len)
+{
+  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";
+
+  const char *flavor = is_token_handle(object_handle) ? "token" : "session";
+  sqlite3_stmt *q = NULL;
+
+  assert(key != NULL && keybuf != NULL);
+
+  const 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, keybuf_len,
+                                                    sqlite3_column_blob( q, 0),
+                                                    sqlite3_column_bytes(q, 0),
+                                                    sqlite3_column_blob( q, 1),
+                                                    sqlite3_column_bytes(q, 1))));
+
+  sqlite3_finalize(q);
+  return ok;
+}
+
 

 
 /*
@@ -3335,11 +3375,6 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession,
     lose(CKR_BUFFER_TOO_SMALL);
 
   if (session->sign_digest_descriptor != NULL) {
-    /*
-     * Caller wanted a hash-and-sign operation.  We need to hash the
-     * caller's data and construct a DigestInfo SEQUENCE.
-     */
-
     uint8_t digest_info[session->sign_digest_descriptor->digest_length + 4 +
                         session->sign_digest_descriptor->digest_algorithm_id_length];
 
@@ -3354,13 +3389,6 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession,
   }
 
   else {
-    /*
-     * Caller wanted a pure-signature operation.  We assume that the
-     * input is a valid DigestInfo SEQUENCE: since we've never seen
-     * the original plaintext, we can't check the hash, thus there's
-     * little point in checking the ASN.1 structure.
-     */
-
     if ((rv = sign_rsa_pkcs(key, pData, ulDataLen, pSignature, signature_len)) != CKR_OK)
       goto fail;
   }
@@ -3457,16 +3485,11 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession,
    * rewriting when we add support for other algorithms.
    */
 
-  if (!p11_object_get_rsa_private_key(session->verify_key_handle,
-                                      &key, keybuf, sizeof(keybuf)))
+  if (!p11_object_get_rsa_public_key(session->verify_key_handle,
+                                     &key, keybuf, sizeof(keybuf)))
     lose(CKR_FUNCTION_FAILED);
 
   if (session->verify_digest_descriptor != NULL) {
-    /*
-     * Caller wanted a hash-and-verify operation.  We need to hash the
-     * caller's data and construct a DigestInfo SEQUENCE.
-     */
-
     uint8_t digest_info[session->verify_digest_descriptor->digest_length + 4 +
                         session->verify_digest_descriptor->digest_algorithm_id_length];
 
@@ -3481,13 +3504,6 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession,
   }
 
   else {
-    /*
-     * Caller wanted a pure-verification operation.  We assume that
-     * the input is a valid DigestInfo SEQUENCE: since we've never
-     * seen the original plaintext, we can't check the hash, thus
-     * there's little point in checking the ASN.1 structure.
-     */
-
     if ((rv = verify_rsa_pkcs(key, pData, ulDataLen, pSignature, ulSignatureLen)) != CKR_OK)
       goto fail;
   }



More information about the Commits mailing list