Bug 158750: Add KeyType constants rsaPssKey and rsaOaepKey, defined in RFC
authorwtc%google.com
Wed, 23 Jun 2010 02:13:56 +0000
changeset 9685 774fafeece47e2b4a0bff966c8fb679ee9f13823
parent 9684 225bd47aec4a39eb2bbc63f2c7f8234fa2ae963a
child 9686 7fc17a93466dcaeeb971cc76bdea4fcbf1a67aab
push idunknown
push userunknown
push dateunknown
bugs158750
Bug 158750: Add KeyType constants rsaPssKey and rsaOaepKey, defined in RFC 4055. The patch is contributed by Hanno Boeck <hanno@hboeck.de>. r=wtc. Modified Files: keythi.h seckey.c secvfy.c
security/nss/lib/cryptohi/keythi.h
security/nss/lib/cryptohi/seckey.c
security/nss/lib/cryptohi/secvfy.c
--- a/security/nss/lib/cryptohi/keythi.h
+++ b/security/nss/lib/cryptohi/keythi.h
@@ -37,24 +37,40 @@
 #ifndef _KEYTHI_H_
 #define _KEYTHI_H_ 1
 
 #include "plarena.h"
 #include "pkcs11t.h"
 #include "secmodt.h"
 #include "prclist.h"
 
+/*
+** RFC 4055 specifies three different RSA key types.
+**
+** rsaKey maps to keys with SEC_OID_PKCS1_RSA_ENCRYPTION and can be used for
+** both encryption and signatures with old (PKCS #1 v1.5) and new (PKCS #1
+** v2.1) padding schemes.
+**
+** rsaPssKey maps to keys with SEC_OID_PKCS1_RSA_PSS_SIGNATURE and may only
+** be used for signatures with PSS padding (PKCS #1 v2.1).
+**
+** rsaOaepKey maps to keys with SEC_OID_PKCS1_RSA_OAEP_ENCRYPTION and may only
+** be used for encryption with OAEP padding (PKCS #1 v2.1).
+*/ 
+
 typedef enum { 
     nullKey = 0, 
     rsaKey = 1, 
     dsaKey = 2, 
     fortezzaKey = 3,
     dhKey = 4, 
     keaKey = 5,
-    ecKey = 6
+    ecKey = 6,
+    rsaPssKey = 7,
+    rsaOaepKey = 8
 } KeyType;
 
 /*
 ** Template Definitions
 **/
 
 SEC_BEGIN_PROTOS
 extern const SEC_ASN1Template SECKEY_RSAPublicKeyTemplate[];
--- a/security/nss/lib/cryptohi/seckey.c
+++ b/security/nss/lib/cryptohi/seckey.c
@@ -970,16 +970,22 @@ KeyType
 seckey_GetKeyType (SECOidTag tag) {
     KeyType keyType;
 
     switch (tag) {
       case SEC_OID_X500_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_RSA_ENCRYPTION:
 	keyType = rsaKey;
 	break;
+      case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
+	keyType = rsaPssKey;
+	break;
+      case SEC_OID_PKCS1_RSA_OAEP_ENCRYPTION:
+	keyType = rsaOaepKey;
+	break;
       case SEC_OID_ANSIX9_DSA_SIGNATURE:
 	keyType = dsaKey;
 	break;
       case SEC_OID_MISSI_KEA_DSS_OLD:
       case SEC_OID_MISSI_KEA_DSS:
       case SEC_OID_MISSI_DSS_OLD:
       case SEC_OID_MISSI_DSS:  
 	keyType = fortezzaKey;
--- a/security/nss/lib/cryptohi/secvfy.c
+++ b/security/nss/lib/cryptohi/secvfy.c
@@ -232,16 +232,17 @@ sec_DecodeSigAlg(const SECKEYPublicKey *
         *hashalg = SEC_OID_MD5;
 	break;
       case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
       case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
       case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
         *hashalg = SEC_OID_SHA1;
 	break;
       case SEC_OID_PKCS1_RSA_ENCRYPTION:
+      case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
         *hashalg = SEC_OID_UNKNOWN; /* get it from the RSA signature */
 	break;
 
       case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
       case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
 	*hashalg = SEC_OID_SHA256;
 	break;
       case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
@@ -322,16 +323,19 @@ sec_DecodeSigAlg(const SECKEYPublicKey *
       case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
       case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
       case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
       case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
 	*encalg = SEC_OID_PKCS1_RSA_ENCRYPTION;
 	break;
+      case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
+	*encalg = SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
+	break;
 
       /* what about normal DSA? */
       case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
       case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
 	*encalg = SEC_OID_ANSIX9_DSA_SIGNATURE;
 	break;
       case SEC_OID_MISSI_DSS:
       case SEC_OID_MISSI_KEA_DSS:
@@ -373,35 +377,37 @@ vfy_CreateContext(const SECKEYPublicKey 
 	SECOidTag encAlg, SECOidTag hashAlg, SECOidTag *hash, void *wincx)
 {
     VFYContext *cx;
     SECStatus rv;
     unsigned int sigLen;
     KeyType type;
 
     /* make sure the encryption algorithm matches the key type */
+    /* RSA-PSS algorithm can be used with both rsaKey and rsaPssKey */
     type = seckey_GetKeyType(encAlg);
-    if (key->keyType != type) {
+    if ((key->keyType != type) &&
+	((key->keyType != rsaKey) || (type != rsaPssKey))) {
 	PORT_SetError(SEC_ERROR_PKCS7_KEYALG_MISMATCH);
 	return NULL;
     }
 
     cx = (VFYContext*) PORT_ZAlloc(sizeof(VFYContext));
     if (cx == NULL) {
 	goto loser;
     }
 
     cx->wincx = wincx;
     cx->hasSignature = (sig != NULL);
     cx->encAlg = encAlg;
     cx->hashAlg = hashAlg;
     cx->key = SECKEY_CopyPublicKey(key);
     rv = SECSuccess;
     if (sig) {
-	switch (key->keyType) {
+	switch (type) {
 	case rsaKey:
 	    rv = DecryptSigBlock(&cx->hashAlg, cx->u.buffer, &cx->rsadigestlen,
 			HASH_LENGTH_MAX, cx->key, sig, (char*)wincx);
 	    if (cx->hashAlg != hashAlg && hashAlg != SEC_OID_UNKNOWN) {
 		PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
 		rv = SECFailure;	
 	    }
 	    break;