When verifying a certificate signature, check whether the curves present,
as well the sizes of the RSA and DSA public keys are accepted. This
uses the previously introduced API NSS_OptionGet().
---
 lib/certhigh/certvfy.c | 83 +++++++++++++++++++++++++++++++++++---------------
 lib/cryptohi/keyhi.h   |  8 +++++
 lib/cryptohi/seckey.c  | 19 ++++++++++++
 3 files changed, 85 insertions(+), 25 deletions(-)

diff --git a/lib/certhigh/certvfy.c b/lib/certhigh/certvfy.c
index 7618822..2deb281 100644
--- a/lib/certhigh/certvfy.c
+++ b/lib/certhigh/certvfy.c
@@ -23,6 +23,7 @@
 #include "pkim.h"
 #include "pki3hack.h"
 #include "base.h"
+#include "keyhi.h"
 
 /*
  * Check the validity times of a certificate
@@ -34,30 +35,13 @@ CERT_CertTimesValid(CERTCertificate *c)
     return (valid == secCertTimeValid) ? SECSuccess : SECFailure;
 }
 
-static SECOidTag
-params2ecTag(const SECKEYECParams * params)
-{
-    SECItem oid = { siBuffer, NULL, 0};
-    SECOidData *oidData = NULL;
-
-    /* 
-     * params->data needs to contain the ASN encoding of an object ID (OID)
-     * representing a named curve. Here, we strip away everything
-     * before the actual OID and use the OID to look up a named curve.
-     */
-    if (params->data[0] != SEC_ASN1_OBJECT_ID) return 0;
-    oid.len = params->len - 2;
-    oid.data = params->data + 2;
-    if ((oidData = SECOID_FindOID(&oid)) == NULL) return 0;
-
-    return oidData->offset;
-}
-
-SECStatus CheckECDSACurves(const SECAlgorithmID *sigAlgorithm, const 
SECKEYPublicKey *key)
+SECStatus checkKeyParams(const SECAlgorithmID *sigAlgorithm, const 
SECKEYPublicKey *key)
 {
-SECOidTag sigAlg;
-SECOidTag curve;
-PRUint32 policyFlags = 0;
+    SECStatus        rv;
+    SECOidTag sigAlg;
+    SECOidTag curve;
+    PRUint32 policyFlags = 0;
+    PRInt32 minLen, len;
 
     sigAlg = SECOID_GetAlgorithmTag(sigAlgorithm);
 
@@ -72,7 +56,7 @@ PRUint32 policyFlags = 0;
                return SECFailure;
            }
 
-            curve = params2ecTag(&key->u.ec.DEREncodedParams);
+            curve = SECKEY_GetECCOid(&key->u.ec.DEREncodedParams);
            if (curve != 0) {
                if (NSS_GetAlgorithmPolicy(curve, &policyFlags) == SECFailure ||
                    !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) {
@@ -85,6 +69,55 @@ PRUint32 policyFlags = 0;
                PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
                return SECFailure;
            }
+            return SECSuccess;
+       case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
+       case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
+       case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
+       case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
+       case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
+       case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
+       case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
+       case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
+           if (key->keyType != rsaKey && key->keyType != rsaPssKey) {
+               PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+               return SECFailure;
+           }
+
+            len = 8 * key->u.rsa.modulus.len;
+
+            rv = NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &minLen);
+            if (rv != SECSuccess) {
+                return SECFailure;
+           }
+
+            if (len < minLen) {
+                return SECFailure;
+           }
+
+            return SECSuccess;
+       case SEC_OID_ANSIX9_DSA_SIGNATURE:
+       case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
+       case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
+       case SEC_OID_SDN702_DSA_SIGNATURE:
+       case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST:
+       case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST:
+           if (key->keyType != dsaKey) {
+               PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+               return SECFailure;
+           }
+
+            len = 8 * key->u.dsa.params.prime.len;
+
+            rv = NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &minLen);
+            if (rv != SECSuccess) {
+                return SECFailure;
+           }
+
+            if (len < minLen) {
+                return SECFailure;
+           }
+
+            return SECSuccess;
        default:
            return SECSuccess;
     }
@@ -116,7 +149,7 @@ CERT_VerifySignedDataWithPublicKey(const CERTSignedData *sd,
     if (rv == SECSuccess) {
         /* Are we honoring signatures for this algorithm?  */
        PRUint32 policyFlags = 0;
-       rv = CheckECDSACurves(&sd->signatureAlgorithm, pubKey);
+       rv = checkKeyParams(&sd->signatureAlgorithm, pubKey);
        if (rv != SECSuccess) {
            PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
            return SECFailure;
diff --git a/lib/cryptohi/keyhi.h b/lib/cryptohi/keyhi.h
index 88a77f1..0c228dc 100644
--- a/lib/cryptohi/keyhi.h
+++ b/lib/cryptohi/keyhi.h
@@ -255,6 +255,14 @@ extern int SECKEY_ECParamsToKeySize(const SECItem *params);
  */
 extern int SECKEY_ECParamsToBasePointOrderLen(const SECItem *params);
 
+/*
+ * Returns the boject identifier of the curve, of the provided
+ * elliptic curve parameters structures.
+ *
+ * Return 0 on failure (unknown EC domain parameters).
+ */
+SECOidTag SECKEY_GetECCOid(const SECKEYECParams * params);
+
 SEC_END_PROTOS
 
 #endif /* _KEYHI_H_ */
diff --git a/lib/cryptohi/seckey.c b/lib/cryptohi/seckey.c
index 16d2a49..f50f9b6 100644
--- a/lib/cryptohi/seckey.c
+++ b/lib/cryptohi/seckey.c
@@ -1889,3 +1889,22 @@ SECKEY_CacheStaticFlags(SECKEYPrivateKey* key)
     }
     return rv;
 }
+
+SECOidTag
+SECKEY_GetECCOid(const SECKEYECParams * params)
+{
+    SECItem oid = { siBuffer, NULL, 0};
+    SECOidData *oidData = NULL;
+
+    /* 
+     * params->data needs to contain the ASN encoding of an object ID (OID)
+     * representing a named curve. Here, we strip away everything
+     * before the actual OID and use the OID to look up a named curve.
+     */
+    if (params->data[0] != SEC_ASN1_OBJECT_ID) return 0;
+    oid.len = params->len - 2;
+    oid.data = params->data + 2;
+    if ((oidData = SECOID_FindOID(&oid)) == NULL) return 0;
+
+    return oidData->offset;
+}
-- 
1.9.0


-- 
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to