diff --git a/.nss.metadata b/.nss.metadata index 43619b7..542343e 100644 --- a/.nss.metadata +++ b/.nss.metadata @@ -1,5 +1,5 @@ -83025bf9062b026aae49ef8775c6432507159bca SOURCES/PayPalEE.cert -a031c46782e6e6c662c2c87c76da9aa62ccabd8e SOURCES/PayPalICA.cert +e8207a278cbed4d97f443289e76b13ddce5850f6 SOURCES/PayPalEE.cert +7e2f3a4f8fe8fa8a5730aeca029696637e986f3f SOURCES/PayPalICA.cert 706c3f929a1e7eca473be12fcd92620709fdada6 SOURCES/TestOldCA.p12 d272a7b58364862613d44261c5744f7a336bf177 SOURCES/blank-cert8.db b5570125fbf6bfb410705706af48217a0817c03a SOURCES/blank-cert9.db diff --git a/SOURCES/nss-3.36-ipsec_cert_vfy.patch b/SOURCES/nss-3.36-ipsec_cert_vfy.patch new file mode 100644 index 0000000..50d71ad --- /dev/null +++ b/SOURCES/nss-3.36-ipsec_cert_vfy.patch @@ -0,0 +1,820 @@ +# HG changeset patch +# User Robert Relyea +# Date 1541713180 28800 +# Thu Nov 08 13:39:40 2018 -0800 +# Node ID 0c8334a3b23372556ebedbdfe513417eb9ee55a0 +# Parent 070bebf39672054410437b0cf931e00a8920a1ff +try: -b do -p all -u all -t all + +diff --git a/cmd/certutil/certutil.c b/cmd/certutil/certutil.c +--- a/cmd/certutil/certutil.c ++++ b/cmd/certutil/certutil.c +@@ -736,16 +736,19 @@ ValidateCert(CERTCertDBHandle *handle, c + usage = certificateUsageVerifyCA; + break; + case 'C': + usage = certificateUsageSSLClient; + break; + case 'V': + usage = certificateUsageSSLServer; + break; ++ case 'I': ++ usage = certificateUsageIPsec; ++ break; + case 'S': + usage = certificateUsageEmailSigner; + break; + case 'R': + usage = certificateUsageEmailRecipient; + break; + case 'J': + usage = certificateUsageObjectSigner; +@@ -1701,16 +1704,17 @@ luV(enum usage_level ul, const char *com + " -n cert-name"); + FPS "%-20s validity time (\"YYMMDDHHMMSS[+HHMM|-HHMM|Z]\")\n", + " -b time"); + FPS "%-20s Check certificate signature \n", + " -e "); + FPS "%-20s Specify certificate usage:\n", " -u certusage"); + FPS "%-25s C \t SSL Client\n", ""); + FPS "%-25s V \t SSL Server\n", ""); ++ FPS "%-25s I \t IPsec\n", ""); + FPS "%-25s L \t SSL CA\n", ""); + FPS "%-25s A \t Any CA\n", ""); + FPS "%-25s Y \t Verify CA\n", ""); + FPS "%-25s S \t Email signer\n", ""); + FPS "%-25s R \t Email Recipient\n", ""); + FPS "%-25s O \t OCSP status responder\n", ""); + FPS "%-25s J \t Object signer\n", ""); + FPS "%-20s Cert database directory (default is ~/.netscape)\n", +diff --git a/cmd/dbck/dbrecover.c b/cmd/dbck/dbrecover.c +--- a/cmd/dbck/dbrecover.c ++++ b/cmd/dbck/dbrecover.c +@@ -283,17 +283,18 @@ addCertToDB(certDBEntryCert *certEntry, + userCert = (SEC_GET_TRUST_FLAGS(trust, trustSSL) & CERTDB_USER) || + (SEC_GET_TRUST_FLAGS(trust, trustEmail) & CERTDB_USER) || + (SEC_GET_TRUST_FLAGS(trust, trustObjectSigning) & CERTDB_USER); + if (userCert) + goto createcert; + + /* If user chooses so, ignore expired certificates. */ + allowOverride = (PRBool)((oldCert->keyUsage == certUsageSSLServer) || +- (oldCert->keyUsage == certUsageSSLServerWithStepUp)); ++ (oldCert->keyUsage == certUsageSSLServerWithStepUp) || ++ (oldCert->keyUsage == certUsageIPsec)); + validity = CERT_CheckCertValidTimes(oldCert, PR_Now(), allowOverride); + /* If cert expired and user wants to delete it, ignore it. */ + if ((validity != secCertTimeValid) && + userSaysDeleteCert(&oldCert, 1, dbInvalidCert, info, 0)) { + info->dbErrors[dbInvalidCert]++; + if (info->verbose) { + PR_fprintf(info->out, "Deleting expired certificate:\n"); + dumpCertificate(oldCert, -1, info->out); +diff --git a/cmd/ocspclnt/ocspclnt.c b/cmd/ocspclnt/ocspclnt.c +--- a/cmd/ocspclnt/ocspclnt.c ++++ b/cmd/ocspclnt/ocspclnt.c +@@ -129,16 +129,18 @@ long_usage(char *progname) + PR_fprintf(pr_stderr, + " %-13s Type of certificate usage for verification:\n", + "-u usage"); + PR_fprintf(pr_stderr, + "%-17s c SSL Client\n", ""); + PR_fprintf(pr_stderr, + "%-17s s SSL Server\n", ""); + PR_fprintf(pr_stderr, ++ "%-17s I IPsec\n", ""); ++ PR_fprintf(pr_stderr, + "%-17s e Email Recipient\n", ""); + PR_fprintf(pr_stderr, + "%-17s E Email Signer\n", ""); + PR_fprintf(pr_stderr, + "%-17s S Object Signer\n", ""); + PR_fprintf(pr_stderr, + "%-17s C CA\n", ""); + PR_fprintf(pr_stderr, +@@ -903,16 +905,19 @@ cert_usage_from_char(const char *cert_us + + switch (*cert_usage_str) { + case 'c': + *cert_usage = certUsageSSLClient; + break; + case 's': + *cert_usage = certUsageSSLServer; + break; ++ case 'I': ++ *cert_usage = certUsageIPsec; ++ break; + case 'e': + *cert_usage = certUsageEmailRecipient; + break; + case 'E': + *cert_usage = certUsageEmailSigner; + break; + case 'S': + *cert_usage = certUsageObjectSigner; +diff --git a/cmd/p7verify/p7verify.c b/cmd/p7verify/p7verify.c +--- a/cmd/p7verify/p7verify.c ++++ b/cmd/p7verify/p7verify.c +@@ -112,16 +112,17 @@ Usage(char *progName) + fprintf(stderr, "%-25s 4 - certUsageEmailSigner\n", " "); + fprintf(stderr, "%-25s 5 - certUsageEmailRecipient\n", " "); + fprintf(stderr, "%-25s 6 - certUsageObjectSigner\n", " "); + fprintf(stderr, "%-25s 7 - certUsageUserCertImport\n", " "); + fprintf(stderr, "%-25s 8 - certUsageVerifyCA\n", " "); + fprintf(stderr, "%-25s 9 - certUsageProtectedObjectSigner\n", " "); + fprintf(stderr, "%-25s 10 - certUsageStatusResponder\n", " "); + fprintf(stderr, "%-25s 11 - certUsageAnyCA\n", " "); ++ fprintf(stderr, "%-25s 12 - certUsageIPsec\n", " "); + + exit(-1); + } + + static int + HashDecodeAndVerify(FILE *out, FILE *content, PRFileDesc *signature, + SECCertUsage usage, char *progName) + { +diff --git a/cmd/smimetools/cmsutil.c b/cmd/smimetools/cmsutil.c +--- a/cmd/smimetools/cmsutil.c ++++ b/cmd/smimetools/cmsutil.c +@@ -110,16 +110,17 @@ Usage(void) + fprintf(stderr, "%-25s 4 - certUsageEmailSigner\n", " "); + fprintf(stderr, "%-25s 5 - certUsageEmailRecipient\n", " "); + fprintf(stderr, "%-25s 6 - certUsageObjectSigner\n", " "); + fprintf(stderr, "%-25s 7 - certUsageUserCertImport\n", " "); + fprintf(stderr, "%-25s 8 - certUsageVerifyCA\n", " "); + fprintf(stderr, "%-25s 9 - certUsageProtectedObjectSigner\n", " "); + fprintf(stderr, "%-25s 10 - certUsageStatusResponder\n", " "); + fprintf(stderr, "%-25s 11 - certUsageAnyCA\n", " "); ++ fprintf(stderr, "%-25s 12 - certUsageIPsec\n", " "); + + exit(-1); + } + + struct optionsStr { + char *pwfile; + char *password; + SECCertUsage certUsage; +diff --git a/cmd/vfychain/vfychain.c b/cmd/vfychain/vfychain.c +--- a/cmd/vfychain/vfychain.c ++++ b/cmd/vfychain/vfychain.c +@@ -59,17 +59,18 @@ Usage(const char *progName) + "\t-o oid\t\t Set policy OID for cert validation(Format OID.1.2.3)\n" + "\t-p \t\t Use PKIX Library to validate certificate by calling:\n" + "\t\t\t * CERT_VerifyCertificate if specified once,\n" + "\t\t\t * CERT_PKIXVerifyCert if specified twice and more.\n" + "\t-r\t\t Following certfile is raw binary DER (default)\n" + "\t-t\t\t Following cert is explicitly trusted (overrides db trust).\n" + "\t-u usage \t 0=SSL client, 1=SSL server, 2=SSL StepUp, 3=SSL CA,\n" + "\t\t\t 4=Email signer, 5=Email recipient, 6=Object signer,\n" +- "\t\t\t 9=ProtectedObjectSigner, 10=OCSP responder, 11=Any CA\n" ++ "\t\t\t 9=ProtectedObjectSigner, 10=OCSP responder, 11=Any CA,\n" ++ "\t\t\t 12=IPsec\n" + "\t-T\t\t Trust both explicit trust anchors (-t) and the database.\n" + "\t\t\t (Default is to only trust certificates marked -t, if there are any,\n" + "\t\t\t or to trust the database if there are certificates marked -t.)\n" + "\t-v\t\t Verbose mode. Prints root cert subject(double the\n" + "\t\t\t argument for whole root cert info)\n" + "\t-w password\t Database password.\n" + "\t-W pwfile\t Password file.\n\n" + "\tRevocation options for PKIX API(invoked with -pp options) is a\n" +diff --git a/lib/certdb/certdb.c b/lib/certdb/certdb.c +--- a/lib/certdb/certdb.c ++++ b/lib/certdb/certdb.c +@@ -441,16 +441,84 @@ cert_GetCertType(CERTCertificate *cert) + nsCertType = cert_ComputeCertType(cert); + + /* Assert that it is safe to cast &cert->nsCertType to "PRInt32 *" */ + PORT_Assert(sizeof(cert->nsCertType) == sizeof(PRInt32)); + PR_ATOMIC_SET((PRInt32 *)&cert->nsCertType, nsCertType); + return SECSuccess; + } + ++PRBool ++cert_EKUAllowsIPsecIKE(CERTCertificate *cert, PRBool *isCritical) ++{ ++ SECStatus rv; ++ SECItem encodedExtKeyUsage; ++ CERTOidSequence *extKeyUsage = NULL; ++ PRBool result = PR_FALSE; ++ ++ rv = CERT_GetExtenCriticality(cert->extensions, ++ SEC_OID_X509_EXT_KEY_USAGE, ++ isCritical); ++ if (rv != SECSuccess) { ++ *isCritical = PR_FALSE; ++ } ++ ++ encodedExtKeyUsage.data = NULL; ++ rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, ++ &encodedExtKeyUsage); ++ if (rv != SECSuccess) { ++ /* EKU not present, allowed. */ ++ result = PR_TRUE; ++ goto done; ++ } ++ ++ extKeyUsage = CERT_DecodeOidSequence(&encodedExtKeyUsage); ++ if (!extKeyUsage) { ++ /* failure */ ++ goto done; ++ } ++ ++ if (findOIDinOIDSeqByTagNum(extKeyUsage, ++ SEC_OID_X509_ANY_EXT_KEY_USAGE) == ++ SECSuccess) { ++ result = PR_TRUE; ++ goto done; ++ } ++ ++ if (findOIDinOIDSeqByTagNum(extKeyUsage, ++ SEC_OID_EXT_KEY_USAGE_IPSEC_IKE) == ++ SECSuccess) { ++ result = PR_TRUE; ++ goto done; ++ } ++ ++ if (findOIDinOIDSeqByTagNum(extKeyUsage, ++ SEC_OID_IPSEC_IKE_END) == ++ SECSuccess) { ++ result = PR_TRUE; ++ goto done; ++ } ++ ++ if (findOIDinOIDSeqByTagNum(extKeyUsage, ++ SEC_OID_IPSEC_IKE_INTERMEDIATE) == ++ SECSuccess) { ++ result = PR_TRUE; ++ goto done; ++ } ++ ++done: ++ if (encodedExtKeyUsage.data != NULL) { ++ PORT_Free(encodedExtKeyUsage.data); ++ } ++ if (extKeyUsage != NULL) { ++ CERT_DestroyOidSequence(extKeyUsage); ++ } ++ return result; ++} ++ + PRUint32 + cert_ComputeCertType(CERTCertificate *cert) + { + SECStatus rv; + SECItem tmpitem; + SECItem encodedExtKeyUsage; + CERTOidSequence *extKeyUsage = NULL; + PRBool basicConstraintPresent = PR_FALSE; +@@ -1078,16 +1146,20 @@ CERT_KeyUsageAndTypeForCertUsage(SECCert + case certUsageSSLClient: + requiredKeyUsage = KU_KEY_CERT_SIGN; + requiredCertType = NS_CERT_TYPE_SSL_CA; + break; + case certUsageSSLServer: + requiredKeyUsage = KU_KEY_CERT_SIGN; + requiredCertType = NS_CERT_TYPE_SSL_CA; + break; ++ case certUsageIPsec: ++ requiredKeyUsage = KU_KEY_CERT_SIGN; ++ requiredCertType = NS_CERT_TYPE_SSL_CA; ++ break; + case certUsageSSLCA: + requiredKeyUsage = KU_KEY_CERT_SIGN; + requiredCertType = NS_CERT_TYPE_SSL_CA; + break; + case certUsageEmailSigner: + requiredKeyUsage = KU_KEY_CERT_SIGN; + requiredCertType = NS_CERT_TYPE_EMAIL_CA; + break; +@@ -1120,16 +1192,21 @@ CERT_KeyUsageAndTypeForCertUsage(SECCert + */ + requiredKeyUsage = KU_DIGITAL_SIGNATURE; + requiredCertType = NS_CERT_TYPE_SSL_CLIENT; + break; + case certUsageSSLServer: + requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT; + requiredCertType = NS_CERT_TYPE_SSL_SERVER; + break; ++ case certUsageIPsec: ++ /* RFC 4945 Section 5.1.3.2 */ ++ requiredKeyUsage = KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION; ++ requiredCertType = 0; ++ break; + case certUsageSSLServerWithStepUp: + requiredKeyUsage = + KU_KEY_AGREEMENT_OR_ENCIPHERMENT | KU_NS_GOVT_APPROVED; + requiredCertType = NS_CERT_TYPE_SSL_SERVER; + break; + case certUsageSSLCA: + requiredKeyUsage = KU_KEY_CERT_SIGN; + requiredCertType = NS_CERT_TYPE_SSL_CA; +diff --git a/lib/certdb/certi.h b/lib/certdb/certi.h +--- a/lib/certdb/certi.h ++++ b/lib/certdb/certi.h +@@ -289,16 +289,19 @@ SECStatus cert_DestroyLocks(void); + extern SECStatus cert_GetCertType(CERTCertificate* cert); + + /* + * compute and return the value of nsCertType for cert, but do not + * update the CERTCertificate. + */ + extern PRUint32 cert_ComputeCertType(CERTCertificate* cert); + ++extern PRBool cert_EKUAllowsIPsecIKE(CERTCertificate* cert, ++ PRBool* isCritical); ++ + void cert_AddToVerifyLog(CERTVerifyLog* log, CERTCertificate* cert, + long errorCode, unsigned int depth, void* arg); + + /* Insert a DER CRL into the CRL cache, and take ownership of it. + * + * cert_CacheCRLByGeneralName takes ownership of the memory in crl argument + * completely. crl must be freeable by SECITEM_FreeItem. It will be freed + * immediately if it is rejected from the CRL cache, or later during cache +diff --git a/lib/certdb/certt.h b/lib/certdb/certt.h +--- a/lib/certdb/certt.h ++++ b/lib/certdb/certt.h +@@ -442,17 +442,18 @@ typedef enum SECCertUsageEnum { + certUsageSSLCA = 3, + certUsageEmailSigner = 4, + certUsageEmailRecipient = 5, + certUsageObjectSigner = 6, + certUsageUserCertImport = 7, + certUsageVerifyCA = 8, + certUsageProtectedObjectSigner = 9, + certUsageStatusResponder = 10, +- certUsageAnyCA = 11 ++ certUsageAnyCA = 11, ++ certUsageIPsec = 12 + } SECCertUsage; + + typedef PRInt64 SECCertificateUsage; + + #define certificateUsageCheckAllUsages (0x0000) + #define certificateUsageSSLClient (0x0001) + #define certificateUsageSSLServer (0x0002) + #define certificateUsageSSLServerWithStepUp (0x0004) +@@ -460,18 +461,19 @@ typedef PRInt64 SECCertificateUsage; + #define certificateUsageEmailSigner (0x0010) + #define certificateUsageEmailRecipient (0x0020) + #define certificateUsageObjectSigner (0x0040) + #define certificateUsageUserCertImport (0x0080) + #define certificateUsageVerifyCA (0x0100) + #define certificateUsageProtectedObjectSigner (0x0200) + #define certificateUsageStatusResponder (0x0400) + #define certificateUsageAnyCA (0x0800) ++#define certificateUsageIPsec (0x1000) + +-#define certificateUsageHighest certificateUsageAnyCA ++#define certificateUsageHighest certificateUsageIPsec + + /* + * Does the cert belong to the user, a peer, or a CA. + */ + typedef enum CERTCertOwnerEnum { + certOwnerUser = 0, + certOwnerPeer = 1, + certOwnerCA = 2 +diff --git a/lib/certhigh/certvfy.c b/lib/certhigh/certvfy.c +--- a/lib/certhigh/certvfy.c ++++ b/lib/certhigh/certvfy.c +@@ -284,16 +284,20 @@ CERT_TrustFlagsForCACertUsage(SECCertUsa + requiredFlags = CERTDB_TRUSTED_CLIENT_CA; + trustType = trustSSL; + break; + case certUsageSSLServer: + case certUsageSSLCA: + requiredFlags = CERTDB_TRUSTED_CA; + trustType = trustSSL; + break; ++ case certUsageIPsec: ++ requiredFlags = CERTDB_TRUSTED_CA; ++ trustType = trustSSL; ++ break; + case certUsageSSLServerWithStepUp: + requiredFlags = CERTDB_TRUSTED_CA | CERTDB_GOVT_APPROVED_CA; + trustType = trustSSL; + break; + case certUsageEmailSigner: + case certUsageEmailRecipient: + requiredFlags = CERTDB_TRUSTED_CA; + trustType = trustEmail; +@@ -574,16 +578,17 @@ cert_VerifyCertChainOld(CERTCertDBHandle + EXIT_IF_NOT_LOGGING(log); + requiredCAKeyUsage = 0; + caCertType = 0; + } + + switch (certUsage) { + case certUsageSSLClient: + case certUsageSSLServer: ++ case certUsageIPsec: + case certUsageSSLCA: + case certUsageSSLServerWithStepUp: + case certUsageEmailSigner: + case certUsageEmailRecipient: + case certUsageObjectSigner: + case certUsageVerifyCA: + case certUsageAnyCA: + case certUsageStatusResponder: +@@ -640,17 +645,18 @@ cert_VerifyCertChainOld(CERTCertDBHandle + * certifcates (except leaf (EE) certs, root CAs, and self-issued + * intermediate CAs) to be verified against the name constraints + * extension of the issuer certificate. + */ + if (subjectCertIsSelfIssued == PR_FALSE) { + CERTGeneralName *subjectNameList; + int subjectNameListLen; + int i; +- PRBool getSubjectCN = (!count && certUsage == certUsageSSLServer); ++ PRBool getSubjectCN = (!count && ++ (certUsage == certUsageSSLServer || certUsage == certUsageIPsec)); + subjectNameList = + CERT_GetConstrainedCertificateNames(subjectCert, arena, + getSubjectCN); + if (!subjectNameList) + goto loser; + subjectNameListLen = CERT_GetNamesLength(subjectNameList); + if (!subjectNameListLen) + goto loser; +@@ -981,16 +987,17 @@ CERT_VerifyCACertForUsage(CERTCertDBHand + EXIT_IF_NOT_LOGGING(log); + requiredCAKeyUsage = 0; + caCertType = 0; + } + + switch (certUsage) { + case certUsageSSLClient: + case certUsageSSLServer: ++ case certUsageIPsec: + case certUsageSSLCA: + case certUsageSSLServerWithStepUp: + case certUsageEmailSigner: + case certUsageEmailRecipient: + case certUsageObjectSigner: + case certUsageVerifyCA: + case certUsageStatusResponder: + if (CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, +@@ -1166,16 +1173,17 @@ cert_CheckLeafTrust(CERTCertificate *cer + *failedFlags = 0; + *trusted = PR_FALSE; + + /* check trust flags to see if this cert is directly trusted */ + if (CERT_GetCertTrust(cert, &trust) == SECSuccess) { + switch (certUsage) { + case certUsageSSLClient: + case certUsageSSLServer: ++ case certUsageIPsec: + flags = trust.sslFlags; + + /* is the cert directly trusted or not trusted ? */ + if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is + * authoritative */ + if (flags & CERTDB_TRUSTED) { /* trust this cert */ + *trusted = PR_TRUE; + return SECSuccess; +@@ -1342,45 +1350,48 @@ CERT_VerifyCertificate(CERTCertDBHandle + /* we don't have a place to return status for all usages, + so we can skip checks for usages that aren't required */ + checkAllUsages = PR_FALSE; + } + valid = SECSuccess; /* start off assuming cert is valid */ + + /* make sure that the cert is valid at time t */ + allowOverride = (PRBool)((requiredUsages & certificateUsageSSLServer) || +- (requiredUsages & certificateUsageSSLServerWithStepUp)); ++ (requiredUsages & certificateUsageSSLServerWithStepUp) || ++ (requiredUsages & certificateUsageIPsec)); + validity = CERT_CheckCertValidTimes(cert, t, allowOverride); + if (validity != secCertTimeValid) { + valid = SECFailure; + LOG_ERROR_OR_EXIT(log, cert, 0, validity); + } + + /* check key usage and netscape cert type */ + cert_GetCertType(cert); + certType = cert->nsCertType; + + for (i = 1; i <= certificateUsageHighest && + (SECSuccess == valid || returnedUsages || log);) { ++ PRBool typeAndEKUAllowed = PR_TRUE; + PRBool requiredUsage = (i & requiredUsages) ? PR_TRUE : PR_FALSE; + if (PR_FALSE == requiredUsage && PR_FALSE == checkAllUsages) { + NEXT_USAGE(); + } + if (returnedUsages) { + *returnedUsages |= i; /* start off assuming this usage is valid */ + } + switch (certUsage) { + case certUsageSSLClient: + case certUsageSSLServer: + case certUsageSSLServerWithStepUp: + case certUsageSSLCA: + case certUsageEmailSigner: + case certUsageEmailRecipient: + case certUsageObjectSigner: + case certUsageStatusResponder: ++ case certUsageIPsec: + rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE, + &requiredKeyUsage, + &requiredCertType); + if (rv != SECSuccess) { + PORT_Assert(0); + /* EXIT_IF_NOT_LOGGING(log); XXX ??? */ + requiredKeyUsage = 0; + requiredCertType = 0; +@@ -1403,17 +1414,29 @@ CERT_VerifyCertificate(CERTCertDBHandle + } + if (CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess) { + if (PR_TRUE == requiredUsage) { + PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); + } + LOG_ERROR(log, cert, 0, requiredKeyUsage); + INVALID_USAGE(); + } +- if (!(certType & requiredCertType)) { ++ if (certUsage != certUsageIPsec) { ++ if (!(certType & requiredCertType)) { ++ typeAndEKUAllowed = PR_FALSE; ++ } ++ } else { ++ PRBool isCritical; ++ PRBool allowed = cert_EKUAllowsIPsecIKE(cert, &isCritical); ++ /* If the extension isn't critical, we allow any EKU value. */ ++ if (isCritical && !allowed) { ++ typeAndEKUAllowed = PR_FALSE; ++ } ++ } ++ if (!typeAndEKUAllowed) { + if (PR_TRUE == requiredUsage) { + PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE); + } + LOG_ERROR(log, cert, 0, requiredCertType); + INVALID_USAGE(); + } + + rv = cert_CheckLeafTrust(cert, certUsage, &flags, &trusted); +@@ -1503,29 +1526,31 @@ cert_VerifyCertWithFlags(CERTCertDBHandl + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); + LOG_ERROR_OR_EXIT(log, cert, 0, 0); + } + #endif + + /* make sure that the cert is valid at time t */ + allowOverride = (PRBool)((certUsage == certUsageSSLServer) || +- (certUsage == certUsageSSLServerWithStepUp)); ++ (certUsage == certUsageSSLServerWithStepUp) || ++ (certUsage == certUsageIPsec)); + validity = CERT_CheckCertValidTimes(cert, t, allowOverride); + if (validity != secCertTimeValid) { + LOG_ERROR_OR_EXIT(log, cert, 0, validity); + } + + /* check key usage and netscape cert type */ + cert_GetCertType(cert); + certType = cert->nsCertType; + switch (certUsage) { + case certUsageSSLClient: + case certUsageSSLServer: + case certUsageSSLServerWithStepUp: ++ case certUsageIPsec: + case certUsageSSLCA: + case certUsageEmailSigner: + case certUsageEmailRecipient: + case certUsageObjectSigner: + case certUsageStatusResponder: + rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE, + &requiredKeyUsage, + &requiredCertType); +@@ -1628,16 +1653,17 @@ CERT_VerifyCertNow(CERTCertDBHandle *han + } + + /* [ FROM pcertdb.c ] */ + /* + * Supported usage values and types: + * certUsageSSLClient + * certUsageSSLServer + * certUsageSSLServerWithStepUp ++ * certUsageIPsec + * certUsageEmailSigner + * certUsageEmailRecipient + * certUsageObjectSigner + */ + + CERTCertificate * + CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName, + CERTCertOwner owner, SECCertUsage usage, +diff --git a/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c b/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c +--- a/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c ++++ b/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c +@@ -2909,17 +2909,18 @@ PKIX_PL_Cert_CheckValidity( + PKIX_DATEGETPRTIMEFAILED); + } else { + timeToCheck = PR_Now(); + } + + requiredUsages = ((PKIX_PL_NssContext*)plContext)->certificateUsage; + allowOverride = + (PRBool)((requiredUsages & certificateUsageSSLServer) || +- (requiredUsages & certificateUsageSSLServerWithStepUp)); ++ (requiredUsages & certificateUsageSSLServerWithStepUp) || ++ (requiredUsages & certificateUsageIPsec)); + val = CERT_CheckCertValidTimes(cert->nssCert, timeToCheck, allowOverride); + if (val != secCertTimeValid){ + PKIX_ERROR(PKIX_CERTCHECKCERTVALIDTIMESFAILED); + } + + cleanup: + PKIX_RETURN(CERT); + } +@@ -2996,18 +2997,27 @@ PKIX_PL_Cert_VerifyCertAndKeyType( + /* use this key usage and cert type for certUsageAnyCA and + * certUsageVerifyCA. */ + requiredKeyUsage = KU_KEY_CERT_SIGN; + requiredCertType = NS_CERT_TYPE_CA; + } + if (CERT_CheckKeyUsage(cert->nssCert, requiredKeyUsage) != SECSuccess) { + PKIX_ERROR(PKIX_CERTCHECKKEYUSAGEFAILED); + } +- if (!(certType & requiredCertType)) { +- PKIX_ERROR(PKIX_CERTCHECKCERTTYPEFAILED); ++ if (certUsage != certUsageIPsec) { ++ if (!(certType & requiredCertType)) { ++ PKIX_ERROR(PKIX_CERTCHECKCERTTYPEFAILED); ++ } ++ } else { ++ PRBool isCritical; ++ PRBool allowed = cert_EKUAllowsIPsecIKE(cert->nssCert, &isCritical); ++ /* If the extension isn't critical, we allow any EKU value. */ ++ if (isCritical && !allowed) { ++ PKIX_ERROR(PKIX_CERTCHECKCERTTYPEFAILED); ++ } + } + cleanup: + PKIX_DECREF(basicConstraints); + PKIX_RETURN(CERT); + } + + /* + * FUNCTION: PKIX_PL_Cert_VerifyKeyUsage (see comments in pkix_pl_pki.h) +diff --git a/tests/chains/chains.sh b/tests/chains/chains.sh +--- a/tests/chains/chains.sh ++++ b/tests/chains/chains.sh +@@ -347,16 +347,22 @@ create_cert_req() + OPTIONS= + + if [ "${TYPE}" != "EE" ]; then + CA_FLAG="-2" + EXT_DATA="y + -1 + y + " ++ else ++ CA_FLAG="-2" ++ EXT_DATA="n ++-1 ++y ++" + fi + + process_crldp + + echo "${EXT_DATA}" > ${CU_DATA} + + TESTNAME="Creating ${TYPE} certifiate request ${REQ}" + echo "${SCRIPTNAME}: ${TESTNAME}" +@@ -1253,16 +1259,22 @@ process_scenario() + + while read AIA_FILE + do + rm ${AIA_FILE} 2> /dev/null + done < ${AIA_FILES} + rm ${AIA_FILES} + } + ++# process ipsec.cfg separately ++chains_ipsec() ++{ ++ process_scenario "ipsec.cfg" ++} ++ + # process ocspd.cfg separately + chains_ocspd() + { + process_scenario "ocspd.cfg" + } + + # process ocsp.cfg separately + chains_method() +@@ -1274,29 +1286,31 @@ chains_method() + # local shell function to process all testing scenarios + ######################################################################## + chains_main() + { + while read LINE + do + [ `echo ${LINE} | cut -b 1` != "#" ] || continue + ++ [ ${LINE} != 'ipsec.cfg' ] || continue + [ ${LINE} != 'ocspd.cfg' ] || continue + [ ${LINE} != 'method.cfg' ] || continue + + process_scenario ${LINE} + done < "${CHAINS_SCENARIOS}" + } + + ################################ main ################################## + + chains_init + VERIFY_CLASSIC_ENGINE_TOO= + chains_ocspd + VERIFY_CLASSIC_ENGINE_TOO=1 ++chains_ipsec + chains_run_httpserv get + chains_method + chains_stop_httpserv + chains_run_httpserv post + chains_method + chains_stop_httpserv + VERIFY_CLASSIC_ENGINE_TOO= + chains_run_httpserv random +diff --git a/tests/chains/scenarios/ipsec.cfg b/tests/chains/scenarios/ipsec.cfg +new file mode 100644 +--- /dev/null ++++ b/tests/chains/scenarios/ipsec.cfg +@@ -0,0 +1,61 @@ ++# This Source Code Form is subject to the terms of the Mozilla Public ++# License, v. 2.0. If a copy of the MPL was not distributed with this ++# file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++scenario IPsec ++ ++entity Root ++ type Root ++ ++entity CA1 ++ type Intermediate ++ issuer Root ++ ++entity NoKU ++ type EE ++ issuer CA1 ++ ++entity DigSig ++ type EE ++ issuer CA1 ++ ku digitalSignature ++ ++entity NonRep ++ type EE ++ issuer CA1 ++ ku nonRepudiation ++ ++entity DigSigNonRepAndExtra ++ type EE ++ issuer CA1 ++ ku digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement ++ ++entity NoMatch ++ type EE ++ issuer CA1 ++ ku keyEncipherment,dataEncipherment,keyAgreement ++ ++db All ++ ++import Root::C,, ++import CA1:Root: ++ ++verify NoKU:CA1 ++ usage 12 ++ result pass ++ ++verify DigSig:CA1 ++ usage 12 ++ result pass ++ ++verify NonRep:CA1 ++ usage 12 ++ result pass ++ ++verify DigSigNonRepAndExtra:CA1 ++ usage 12 ++ result pass ++ ++verify NoMatch:CA1 ++ usage 12 ++ result fail +diff --git a/tests/chains/scenarios/scenarios b/tests/chains/scenarios/scenarios +--- a/tests/chains/scenarios/scenarios ++++ b/tests/chains/scenarios/scenarios +@@ -17,8 +17,9 @@ bridgewithhalfaia.cfg + bridgewithpolicyextensionandmapping.cfg + realcerts.cfg + dsa.cfg + revoc.cfg + ocsp.cfg + crldp.cfg + trustanchors.cfg + nameconstraints.cfg ++ipsec.cfg diff --git a/SOURCES/nss-tests-paypal-certs-v2.patch b/SOURCES/nss-tests-paypal-certs-v2.patch new file mode 100644 index 0000000..8f37f8c --- /dev/null +++ b/SOURCES/nss-tests-paypal-certs-v2.patch @@ -0,0 +1,29 @@ +# HG changeset patch +# User Daiki Ueno +# Date 1541595734 -3600 +# Wed Nov 07 14:02:14 2018 +0100 +# Node ID 19fd907784e38a5febb54588353368af91b12551 +# Parent 3b79af0fa294b4b1c009c1c0b659bb72b4d2c1c8 +Bug 1505317, update PayPal test certs + +diff --git a/tests/chains/scenarios/realcerts.cfg b/tests/chains/scenarios/realcerts.cfg +--- a/tests/chains/scenarios/realcerts.cfg ++++ b/tests/chains/scenarios/realcerts.cfg +@@ -21,7 +21,7 @@ verify TestUser51:x + result pass + + verify PayPalEE:x +- policy OID.2.16.840.1.114412.1.1 ++ policy OID.2.16.840.1.114412.2.1 + result pass + + verify BrAirWaysBadSig:x +diff --git a/tests/libpkix/vfychain_test.lst b/tests/libpkix/vfychain_test.lst +--- a/tests/libpkix/vfychain_test.lst ++++ b/tests/libpkix/vfychain_test.lst +@@ -1,4 +1,4 @@ + # Status | Leaf Cert | Policies | Others(undef) + 0 TestUser50 undef + 0 TestUser51 undef +-0 PayPalEE OID.2.16.840.1.114412.1.1 ++0 PayPalEE OID.2.16.840.1.114412.2.1 diff --git a/SPECS/nss.spec b/SPECS/nss.spec index d117328..2ad67f6 100644 --- a/SPECS/nss.spec +++ b/SPECS/nss.spec @@ -1,6 +1,6 @@ %global nspr_version 4.19.0 %global nss_util_version 3.36.0 -%global nss_util_build -1 +%global nss_util_build -1.1 # adjust to the version that gets submitted for FIPS validation %global nss_softokn_fips_version 3.36.0 %global nss_softokn_version 3.36.0 @@ -27,7 +27,7 @@ Summary: Network Security Services Name: nss Version: 3.36.0 -Release: 7%{?dist} +Release: 7.1%{?dist} License: MPLv2.0 URL: http://www.mozilla.org/projects/security/pki/nss/ Group: System Environment/Libraries @@ -93,6 +93,9 @@ Source33: TestOldCA.p12 Patch2: add-relro-linker-option.patch Patch3: renegotiate-transitional.patch Patch16: nss-539183.patch +# Remove this patch on when we rebase to NSS 3.40, bug 1639404 +Patch17: nss-3.36-ipsec_cert_vfy.patch +Patch18: nss-tests-paypal-certs-v2.patch # TODO: Remove this patch when the ocsp test are fixed Patch40: nss-3.14.0.0-disble-ocsp-test.patch # Fedora / RHEL-only patch, the templates directory was originally introduced to support mod_revocator @@ -221,6 +224,10 @@ low level services. %patch2 -p0 -b .relro %patch3 -p0 -b .transitional %patch16 -p0 -b .539183 +pushd nss +%patch17 -p1 -b .ipsec_vfy +%patch18 -p1 -b .update_paypal +popd %patch40 -p0 -b .noocsptest %patch47 -p0 -b .templates %patch49 -p0 -b .skipthem @@ -849,6 +856,9 @@ fi %changelog +* Mon Nov 12 2018 Bob Relyea - 3.36.0-7.1 +- Update the cert verify code to allow a new ipsec usage and follow RFC 4945 + * Wed Aug 29 2018 Daiki Ueno - 3.36.0-7 - Backport upstream fix for CVE-2018-12384 - Remove nss-lockcert-api-change.patch, which turned out to be a