rsa-key-from-bytes.patch
author David Keeler <dkeeler@mozilla.com>
Thu, 01 Sep 2011 11:03:07 -0700
changeset 48 3e596f38a49a3f0fec18e6ed3eeaf1667007ab44
parent 39 1a7af98e3ac09323c1be65c1444e304bd2e7c523
permissions -rw-r--r--
fixed key disconnect test case

# HG changeset patch
# Parent a5943ddff81acf193d231e538d632fdb71f254bd
# User David Keeler <dkeeler@mozilla.com>

diff --git a/security/nss/lib/cryptohi/keyhi.h b/security/nss/lib/cryptohi/keyhi.h
--- a/security/nss/lib/cryptohi/keyhi.h
+++ b/security/nss/lib/cryptohi/keyhi.h
@@ -247,20 +247,23 @@ SECKEY_CopyEncryptedPrivateKeyInfo(PLAre
 KeyType SECKEY_GetPrivateKeyType(SECKEYPrivateKey *privKey);
 KeyType SECKEY_GetPublicKeyType(SECKEYPublicKey *pubKey);
 
 /*
  * Creates a PublicKey from its DER encoding.
  * Currently only supports RSA and DSA keys.
  */
 SECKEYPublicKey*
 SECKEY_ImportDERPublicKey(SECItem *derKey, CK_KEY_TYPE type);
 
+SECKEYPublicKey *
+SECKEY_ImportRSAPublicKey(SECItem *modulus, SECItem *exponent);
+
 SECKEYPrivateKeyList*
 SECKEY_NewPrivateKeyList(void);
 
 void
 SECKEY_DestroyPrivateKeyList(SECKEYPrivateKeyList *keys);
 
 void
 SECKEY_RemovePrivateKeyListNode(SECKEYPrivateKeyListNode *node);
 
 SECStatus
diff --git a/security/nss/lib/cryptohi/seckey.c b/security/nss/lib/cryptohi/seckey.c
--- a/security/nss/lib/cryptohi/seckey.c
+++ b/security/nss/lib/cryptohi/seckey.c
@@ -1971,20 +1971,79 @@ SECKEY_ImportDERPublicKey(SECItem *derKe
 finish:
     if (rv != SECSuccess) {
         if (arena != NULL) {
             PORT_FreeArena(arena, PR_TRUE);
         }
         pubk = NULL;
     }
     return pubk;
 }
 
+SECKEYPublicKey *
+SECKEY_ImportRSAPublicKey(SECItem *modulus, SECItem *exponent) {
+    SECKEYPublicKey *pubk = NULL;
+    SECStatus rv = SECFailure;
+    PRArenaPool *arena = NULL;
+
+    if (!modulus || !exponent) {
+        return NULL;
+    } 
+
+    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+    if (arena == NULL) {
+        PORT_SetError(SEC_ERROR_NO_MEMORY);
+        goto finish;
+    }
+
+    pubk = PORT_ArenaZNew(arena, SECKEYPublicKey);
+    if (pubk == NULL) {
+        PORT_SetError(SEC_ERROR_NO_MEMORY);
+        goto finish;
+    }
+    pubk->arena = arena;
+
+    rv = SECITEM_CopyItem(pubk->arena, &pubk->u.rsa.modulus, modulus);
+    if (SECSuccess != rv) {
+        PORT_SetError(SEC_ERROR_NO_MEMORY);
+        goto finish;
+    }
+
+    rv = SECITEM_CopyItem(pubk->arena, &pubk->u.rsa.publicExponent, exponent);
+    if (SECSuccess != rv) {
+        PORT_SetError(SEC_ERROR_NO_MEMORY);
+        goto finish;
+    }
+
+    pubk->pkcs11Slot = NULL;
+    pubk->pkcs11ID = CK_INVALID_HANDLE;
+    pubk->keyType = rsaKey;
+    rv = SECSuccess;
+
+finish:
+    if (rv != SECSuccess) {
+        if (pubk != NULL) {
+            if (pubk->u.rsa.modulus.data != NULL) {
+                SECITEM_FreeItem(&pubk->u.rsa.modulus, PR_FALSE);
+            }
+            if (pubk->u.rsa.publicExponent.data != NULL) {
+                SECITEM_FreeItem(&pubk->u.rsa.publicExponent, PR_FALSE);
+            }
+            PORT_Free(pubk);
+        }
+        if (arena != NULL) {
+            PORT_FreeArena(arena, PR_TRUE);
+        }
+        pubk = NULL;
+    }
+    return pubk;
+}
+
 SECKEYPrivateKeyList*
 SECKEY_NewPrivateKeyList(void)
 {
     PRArenaPool *arena = NULL;
     SECKEYPrivateKeyList *ret = NULL;
 
     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     if ( arena == NULL ) {
         goto loser;
     }
diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def
--- a/security/nss/lib/nss/nss.def
+++ b/security/nss/lib/nss/nss.def
@@ -1013,10 +1013,16 @@ SECMOD_RestartModules;
 ;+    local:
 ;+       *;
 ;+};
 ;+NSS_3.12.10 {  # NSS 3.12.10 release
 ;+    global:
 CERT_AllocCERTRevocationFlags;
 CERT_DestroyCERTRevocationFlags;
 ;+    local:
 ;+       *;
 ;+};
+;+NSS_3.13.1 {  # NSS 3.13.1 release
+;+    global:
+SECKEY_ImportRSAPublicKey;
+;+    local:
+;+       *;
+;+};
diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -5272,40 +5272,23 @@ ssl3_HandleServerKeyExchange(sslSocket *
 	    errCode =
 	    	ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
 	    goto alert_loser;
 	}
 
 	/*
 	 * we really need to build a new key here because we can no longer
 	 * ignore calling SECKEY_DestroyPublicKey. Using the key may allocate
 	 * pkcs11 slots and ID's.
 	 */
-    	arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-	if (arena == NULL) {
-	    goto no_memory;
-	}
-
-    	peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
-    	if (peerKey == NULL) {
-            PORT_FreeArena(arena, PR_FALSE);
-	    goto no_memory;
-	}
-
-	peerKey->arena              = arena;
-	peerKey->keyType            = rsaKey;
-	peerKey->pkcs11Slot         = NULL;
-	peerKey->pkcs11ID           = CK_INVALID_HANDLE;
-	if (SECITEM_CopyItem(arena, &peerKey->u.rsa.modulus,        &modulus) ||
-	    SECITEM_CopyItem(arena, &peerKey->u.rsa.publicExponent, &exponent))
-	{
-            PORT_FreeArena(arena, PR_FALSE);
-	    goto no_memory;
+        peerKey = SECKEY_ImportRSAPublicKey(&modulus, &exponent);
+        if (peerKey == NULL) {
+            goto no_memory;
         }
     	ss->sec.peerKey = peerKey;
     	ss->ssl3.hs.ws = wait_cert_request;
     	return SECSuccess;
     }
 
     case kt_dh: {
 	SECItem          dh_p      = {siBuffer, NULL, 0};
 	SECItem          dh_g      = {siBuffer, NULL, 0};
 	SECItem          dh_Ys     = {siBuffer, NULL, 0};