[pkg-opensc-commit] [opensc] 245/295: PKCS#11 does not define a CKA_VALUE for public keys and is missused

Eric Dorland eric at moszumanska.debian.org
Sat Jun 24 21:11:36 UTC 2017


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

eric pushed a commit to branch master
in repository opensc.

commit d48f4385815314262e5c2de2fa693291ea8a2bb0
Author: Doug Engert <deengert at gmail.com>
Date:   Sat Mar 11 11:49:49 2017 -0600

    PKCS#11 does not define a CKA_VALUE for public keys and is missused
    
    OpenSC opennssl.c in sc_pkcs11_verify_data assumes that it can
    retieve the CKA_VALUE for a public key object, and expect it to
    be usable as RSA.
    
    But internally sc_pkcs15_pubkey can have a "raw" or "spki"
    version of the public key as defined by PKCS#15.  Card drivers
    or pkcs15-<card> routines may store either the "raw" or "spki"
    versions. A get attribute request for CKA_VALUE for a public key
    will return either the raw, spki or will derived rsa verison of the
    pubkey.
    
    This commit will test if the CKA_VALUE is a spki and use d2i_PUBKEY
    which takes a spki version and returns an EVP_KEY. If it not an spki
    the current method, d21_PublicKey(EVP_PKEY_RSA,...) is used which
    only works for RSA.
    
    The problem was found while testing pkcs11-tool -t -l  where
    the  verify tests would fail with a CKR_GENERAL_ERROR because
    the card driver stored the public key as a spki.
    
    On branch verify-pubkey-as-spki-2
     Changes to be committed:
    	modified:   src/pkcs11/openssl.c
    
    Date:      Fri Apr 07 07:50:00 2017 -0600
---
 src/pkcs11/openssl.c | 38 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c
index d16d329..77ce28d 100644
--- a/src/pkcs11/openssl.c
+++ b/src/pkcs11/openssl.c
@@ -405,7 +405,9 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len,
 {
 	int res;
 	CK_RV rv = CKR_GENERAL_ERROR;
-	EVP_PKEY *pkey;
+	EVP_PKEY *pkey = NULL;
+	const unsigned char *pubkey_tmp;
+	int is_spki = 0;
 
 	if (mech == CKM_GOSTR3410)
 	{
@@ -419,7 +421,38 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len,
 #endif
 	}
 
-	pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &pubkey, pubkey_len);
+	/*
+	 * PKCS#11 does not define CKA_VALUE for public keys, and different cards
+	 * return either the raw or spki versions as defined in PKCS#15
+	 * And we need to support more then just RSA.
+	 * We can use d2i_PUBKEY which works for SPKI and any key type. 
+	 */
+	pubkey_tmp = pubkey; /* pass in so pubkey pointer is not modified */
+	/* SPKI ASN.1 starts with SEQUENCE, SEQUENCE, OBJECT IDENTIFIER */
+	if (*pubkey_tmp++ == 0x30) {
+		if (*pubkey_tmp & 0x80)
+			pubkey_tmp += *pubkey_tmp & 0x7F;
+
+		pubkey_tmp++;
+		if (*pubkey_tmp++ == 0x30) {
+			if (*pubkey_tmp & 0x80)
+				pubkey_tmp += *pubkey_tmp & 0x7F;
+
+			pubkey_tmp += 1;
+			if (*pubkey_tmp == 0x06)
+				is_spki = 1;
+		}
+	}
+
+	pubkey_tmp = pubkey; /* pass in so pubkey pointer is not modified */
+
+	if (is_spki) {
+		pkey = d2i_PUBKEY(NULL, &pubkey_tmp, pubkey_len);
+	}else {
+		/* Assume it is RSA */
+		/* TODO support others  but GOST is done above, and EC always uses SPKI */
+		pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &pubkey_tmp, pubkey_len);
+	}
 	if (pkey == NULL)
 		return CKR_GENERAL_ERROR;
 
@@ -449,6 +482,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len,
 		 case CKM_RSA_X_509:
 		 	pad = RSA_NO_PADDING;
 		 	break;
+		/* TODO support more then RSA */
 		 default:
 			EVP_PKEY_free(pkey);
 		 	return CKR_ARGUMENTS_BAD;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-opensc/opensc.git



More information about the pkg-opensc-commit mailing list