aboutsummaryrefslogtreecommitdiff
path: root/pkcs11.c
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2015-06-24 17:03:21 -0400
committerRob Austein <sra@hactrn.net>2015-06-24 17:03:21 -0400
commit94bf5c0d622698ac90cd2b1735587a840f3602ee (patch)
treea0f1838675e127a51bb6480c1ebdde1ecc85adc5 /pkcs11.c
parent452c5a8d5ecfcd5acfc098997389042e8903b6d7 (diff)
Extracting the private key from a public key object doesn't work very well.
Diffstat (limited to 'pkcs11.c')
-rw-r--r--pkcs11.c74
1 files 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;
}