Bug 1049435 - importing an RSA private key fails if p < q, upgrade to NSS 3.17.2, r=wtc, a=sledru
authorKai Engert <kaie@kuix.de>
Wed, 29 Oct 2014 17:33:48 +0100
changeset 218148 8c16b644aaa7
parent 218147 766b4b4fa7c7
child 218149 efd4bca5ac0d
push id554
push userkaie@kuix.de
push date2014-10-29 16:34 +0000
treeherdermozilla-release@8c16b644aaa7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswtc, sledru
bugs1049435
milestone33.0.2
Bug 1049435 - importing an RSA private key fails if p < q, upgrade to NSS 3.17.2, r=wtc, a=sledru
configure.in
security/nss/TAG-INFO
security/nss/cmd/certutil/certutil.c
security/nss/coreconf/coreconf.dep
security/nss/lib/freebl/ec.c
security/nss/lib/freebl/rsa.c
security/nss/lib/nss/nss.h
security/nss/lib/softoken/pkcs11.c
security/nss/lib/softoken/softkver.h
security/nss/lib/util/nssutil.h
security/nss/tests/chains/chains.sh
--- a/configure.in
+++ b/configure.in
@@ -3535,17 +3535,17 @@ dnl = If NSS was not detected in the sys
 dnl = use the one in the source tree (mozilla/security/nss)
 dnl ========================================================
 
 MOZ_ARG_WITH_BOOL(system-nss,
 [  --with-system-nss       Use system installed NSS],
     _USE_SYSTEM_NSS=1 )
 
 if test -n "$_USE_SYSTEM_NSS"; then
-    AM_PATH_NSS(3.17.1, [MOZ_NATIVE_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
+    AM_PATH_NSS(3.17.2, [MOZ_NATIVE_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
 fi
 
 if test -n "$MOZ_NATIVE_NSS"; then
    NSS_LIBS="$NSS_LIBS -lcrmf"
 else
    NSS_CFLAGS='-I$(LIBXUL_DIST)/include/nss'
 
    if test -z "$GNU_CC" -a "$OS_ARCH" = "WINNT"; then
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-NSS_3_17_1_RTM
+NSS_3_17_2_RTM
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -2362,17 +2362,17 @@ secuCommandFlag options_init[] =
 	{ /* opt_KeyOpFlagsOn        */  0,   PR_TRUE, 0, PR_FALSE, 
                                                    "keyOpFlagsOn"},
 	{ /* opt_KeyOpFlagsOff       */  0,   PR_TRUE, 0, PR_FALSE, 
                                                    "keyOpFlagsOff"},
 	{ /* opt_KeyAttrFlags        */  0,   PR_TRUE, 0, PR_FALSE, 
                                                    "keyAttrFlags"},
 	{ /* opt_EmptyPassword       */  0,   PR_FALSE, 0, PR_FALSE, 
                                                    "empty-password"},
-        { /* opt_CertVersion         */  0,   PR_FALSE, 0, PR_FALSE,
+        { /* opt_CertVersion         */  0,   PR_TRUE, 0, PR_FALSE,
                                                    "certVersion"},
 	{ /* opt_AddSubjectAltExt    */  0,   PR_TRUE,  0, PR_FALSE, "extSAN"},
 	{ /* opt_DumpExtensionValue  */  0,   PR_TRUE, 0, PR_FALSE, 
                                                    "dump-ext-val"},
 	{ /* opt_GenericExtensions   */  0,   PR_TRUE, 0, PR_FALSE, 
                                                    "extGeneric"},
 };
 #define NUM_OPTIONS ((sizeof options_init)  / (sizeof options_init[0]))
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,9 +5,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/security/nss/lib/freebl/ec.c
+++ b/security/nss/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/security/nss/lib/freebl/rsa.c
+++ b/security/nss/lib/freebl/rsa.c
@@ -92,18 +92,18 @@ static struct RSABlindingParamsListStr b
 /* Number of times to reuse (f, g).  Suggested by Paul Kocher */
 #define RSA_BLINDING_PARAMS_MAX_REUSE 50
 
 /* Global, allows optional use of blinding.  On by default. */
 /* Cannot be changed at the moment, due to thread-safety issues. */
 static PRBool nssRSAUseBlinding = PR_TRUE;
 
 static SECStatus
-rsa_build_from_primes(mp_int *p, mp_int *q, 
-		mp_int *e, PRBool needPublicExponent, 
+rsa_build_from_primes(const mp_int *p, const mp_int *q,
+		mp_int *e, PRBool needPublicExponent,
 		mp_int *d, PRBool needPrivateExponent,
 		RSAPrivateKey *key, unsigned int keySizeInBits)
 {
     mp_int n, phi;
     mp_int psub1, qsub1, tmp;
     mp_err   err = MP_OKAY;
     SECStatus rv = SECSuccess;
     MP_DIGITS(&n)     = 0;
@@ -111,16 +111,22 @@ rsa_build_from_primes(mp_int *p, mp_int 
     MP_DIGITS(&psub1) = 0;
     MP_DIGITS(&qsub1) = 0;
     MP_DIGITS(&tmp)   = 0;
     CHECK_MPI_OK( mp_init(&n)     );
     CHECK_MPI_OK( mp_init(&phi)   );
     CHECK_MPI_OK( mp_init(&psub1) );
     CHECK_MPI_OK( mp_init(&qsub1) );
     CHECK_MPI_OK( mp_init(&tmp)   );
+    /* p and q must be distinct. */
+    if (mp_cmp(p, q) == 0) {
+	PORT_SetError(SEC_ERROR_NEED_RANDOM);
+	rv = SECFailure;
+	goto cleanup;
+    }
     /* 1.  Compute n = p*q */
     CHECK_MPI_OK( mp_mul(p, q, &n) );
     /*     verify that the modulus has the desired number of bits */
     if ((unsigned)mpl_significant_bits(&n) != keySizeInBits) {
 	PORT_SetError(SEC_ERROR_NEED_RANDOM);
 	rv = SECFailure;
 	goto cleanup;
     }
@@ -275,17 +281,21 @@ RSA_NewKey(int keySizeInBits, SECItem *p
     /* 3.  Set the public exponent */
     SECITEM_TO_MPINT(*publicExponent, &e);
     kiter = 0;
     do {
 	prerr = 0;
 	PORT_SetError(0);
 	CHECK_SEC_OK( generate_prime(&p, primeLen) );
 	CHECK_SEC_OK( generate_prime(&q, primeLen) );
-	/* Assure q < p */
+	/* Assure p > q */
+	/* NOTE: PKCS #1 does not require p > q, and NSS doesn't use any
+	 * implementation optimization that requires p > q. We can remove
+	 * this code in the future.
+	 */
 	if (mp_cmp(&p, &q) < 0)
 	    mp_exch(&p, &q);
 	/* Attempt to use these primes to generate a key */
 	rv = rsa_build_from_primes(&p, &q, 
 			&e, PR_FALSE,  /* needPublicExponent=false */
 			&d, PR_TRUE,   /* needPrivateExponent=true */
 			key, keySizeInBits);
 	if (rv == SECSuccess)
@@ -757,17 +767,21 @@ RSA_PopulatePrivateKey(RSAPrivateKey *ke
 			&n,hasModulus,keySizeInBits));
 	} else {
 	    /* not enough given parameters to get both primes */
 	    err = MP_BADARG;
 	    goto cleanup;
 	}
      }
 
-     /* force p to the the larger prime */
+     /* Assure p > q */
+     /* NOTE: PKCS #1 does not require p > q, and NSS doesn't use any
+      * implementation optimization that requires p > q. We can remove
+      * this code in the future.
+      */
      if (mp_cmp(&p, &q) < 0)
 	mp_exch(&p, &q);
 
      /* we now have our 2 primes and at least one exponent, we can fill
       * in the key */
      rv = rsa_build_from_primes(&p, &q, 
 			&e, needPublicExponent,
 			&d, needPrivateExponent,
@@ -1088,17 +1102,17 @@ init_blinding_params(RSABlindingParams *
 }
 
 static SECStatus
 get_blinding_params(RSAPrivateKey *key, mp_int *n, unsigned int modLen,
                     mp_int *f, mp_int *g)
 {
     RSABlindingParams *rsabp           = NULL;
     blindingParams    *bpUnlinked      = NULL;
-    blindingParams    *bp, *prevbp     = NULL;
+    blindingParams    *bp;
     PRCList           *el;
     SECStatus          rv              = SECSuccess;
     mp_err             err             = MP_OKAY;
     int                cmp             = -1;
     PRBool             holdingLock     = PR_FALSE;
 
     do {
 	if (blindingParamsList.lock == NULL) {
@@ -1178,17 +1192,16 @@ get_blinding_params(RSAPrivateKey *key, 
 		PR_NotifyCondVar( blindingParamsList.cVar );
 		blindingParamsList.waitCount--;
 	    }
 	    PZ_Unlock(blindingParamsList.lock); 
 	    return SECSuccess;
 	}
 	/* We did not find a usable set of blinding params.  Can we make one? */
 	/* Find a free bp struct. */
-	prevbp = NULL;
 	if ((bp = rsabp->free) != NULL) {
 	    /* unlink this bp */
 	    rsabp->free  = bp->next;
 	    bp->next     = NULL;
 	    bpUnlinked   = bp;  /* In case we fail */
 
 	    PZ_Unlock(blindingParamsList.lock); 
 	    holdingLock = PR_FALSE;
@@ -1395,18 +1408,18 @@ RSA_PrivateKeyCheck(const RSAPrivateKey 
     SECITEM_TO_MPINT(key->modulus,         &n);
     SECITEM_TO_MPINT(key->prime1,          &p);
     SECITEM_TO_MPINT(key->prime2,          &q);
     SECITEM_TO_MPINT(key->publicExponent,  &e);
     SECITEM_TO_MPINT(key->privateExponent, &d);
     SECITEM_TO_MPINT(key->exponent1,       &d_p);
     SECITEM_TO_MPINT(key->exponent2,       &d_q);
     SECITEM_TO_MPINT(key->coefficient,     &qInv);
-    /* p > q */
-    if (mp_cmp(&p, &q) <= 0) {
+    /* p and q must be distinct. */
+    if (mp_cmp(&p, &q) == 0) {
 	rv = SECFailure;
 	goto cleanup;
     }
 #define VERIFY_MPI_EQUAL(m1, m2) \
     if (mp_cmp(m1, m2) != 0) {   \
 	rv = SECFailure;         \
 	goto cleanup;            \
     }
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -28,20 +28,20 @@
 
 /*
  * NSS's major version, minor version, patch level, build number, and whether
  * this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define NSS_VERSION  "3.17.1" _NSS_ECC_STRING _NSS_CUSTOMIZED
+#define NSS_VERSION  "3.17.2" _NSS_ECC_STRING _NSS_CUSTOMIZED
 #define NSS_VMAJOR   3
 #define NSS_VMINOR   17
-#define NSS_VPATCH   1
+#define NSS_VPATCH   2
 #define NSS_VBUILD   0
 #define NSS_BETA     PR_FALSE
 
 #ifndef RC_INVOKED
 
 #include "seccomon.h"
 
 typedef struct NSSInitParametersStr NSSInitParameters;
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/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;
 	}
 
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -20,16 +20,16 @@
 
 /*
  * Softoken's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define SOFTOKEN_VERSION  "3.17.1" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VERSION  "3.17.2" SOFTOKEN_ECC_STRING
 #define SOFTOKEN_VMAJOR   3
 #define SOFTOKEN_VMINOR   17
-#define SOFTOKEN_VPATCH   1
+#define SOFTOKEN_VPATCH   2
 #define SOFTOKEN_VBUILD   0
 #define SOFTOKEN_BETA     PR_FALSE
 
 #endif /* _SOFTKVER_H_ */
--- a/security/nss/lib/util/nssutil.h
+++ b/security/nss/lib/util/nssutil.h
@@ -14,20 +14,20 @@
 
 /*
  * NSS utilities's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
  */
-#define NSSUTIL_VERSION  "3.17.1"
+#define NSSUTIL_VERSION  "3.17.2"
 #define NSSUTIL_VMAJOR   3
 #define NSSUTIL_VMINOR   17
-#define NSSUTIL_VPATCH   1
+#define NSSUTIL_VPATCH   2
 #define NSSUTIL_VBUILD   0
 #define NSSUTIL_BETA     PR_FALSE
 
 SEC_BEGIN_PROTOS
 
 /*
  * Returns a const string of the UTIL library version.
  */
old mode 100644
new mode 100755