Bug 1057161 - NSS hangs with 100% CPU on invalid EC key. r=rrelyea NSS_3_16_2_BRANCH
authorRichard Barnes <rbarnes@mozilla.com>
Sat, 25 Oct 2014 00:42:52 +0200
branchNSS_3_16_2_BRANCH
changeset 11299 dc27c76586282fd4413380ae721a21e57c625f46
parent 11289 e63a75e8dbd3f83bdae1c8d921e0a3a5d27978ff
child 11300 53506619e81aa29a5366453ba17ce93e8427ef8a
push id510
push userkaie@kuix.de
push dateFri, 24 Oct 2014 22:50:22 +0000
reviewersrrelyea
bugs1057161
Bug 1057161 - NSS hangs with 100% CPU on invalid EC key. r=rrelyea
lib/freebl/ec.c
lib/softoken/pkcs11.c
tests/chains/chains.sh
--- a/lib/freebl/ec.c
+++ b/lib/freebl/ec.c
@@ -865,16 +865,21 @@ cleanup:
     PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
 #endif /* NSS_DISABLE_ECC */
 
     return rv;
 }
 
 /*
 ** Checks the signature on the given digest using the key provided.
+**
+** The key argument must represent a valid EC public key (a point on
+** the relevant curve).  If it is not a valid point, then the behavior
+** of this function is undefined.  In cases where a public key might
+** not be valid, use EC_ValidatePublicKey to check.
 */
 SECStatus 
 ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature, 
                  const SECItem *digest)
 {
     SECStatus rv = SECFailure;
 #ifndef NSS_DISABLE_ECC
     mp_int r_, s_;           /* tuple (r', s') is received signature) */
--- a/lib/softoken/pkcs11.c
+++ b/lib/softoken/pkcs11.c
@@ -964,16 +964,27 @@ sftk_handlePublicKeyObject(SFTKSession *
     if (crv != CKR_OK)  return crv; 
 
     object->objectInfo = sftk_GetPubKey(object,key_type, &crv);
     if (object->objectInfo == NULL) {
 	return crv;
     }
     object->infoFree = (SFTKFree) nsslowkey_DestroyPublicKey;
 
+    /* Check that an imported EC key is valid */
+    if (key_type == CKK_EC) {
+      NSSLOWKEYPublicKey *pubKey = (NSSLOWKEYPublicKey*) object->objectInfo;
+      SECStatus rv = EC_ValidatePublicKey(&pubKey->u.ec.ecParams,
+                                          &pubKey->u.ec.publicValue);
+
+      if (rv != SECSuccess) {
+        return CKR_TEMPLATE_INCONSISTENT;
+      }
+    }
+
     if (sftk_isTrue(object,CKA_TOKEN)) {
 	SFTKSlot *slot = session->slot;
 	SFTKDBHandle *certHandle = sftk_getCertDB(slot);
 
 	if (certHandle == NULL) {
 	    return CKR_TOKEN_WRITE_PROTECTED;
 	}
 
old mode 100644
new mode 100755