From 94bf5c0d622698ac90cd2b1735587a840f3602ee Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Wed, 24 Jun 2015 17:03:21 -0400 Subject: 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; } -- cgit v1.2.3