Blame SOURCES/nss-3.36-ipsec_cert_vfy.patch

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