diff options
Diffstat (limited to 'nss/lib/certhigh/certvfy.c')
-rw-r--r-- | nss/lib/certhigh/certvfy.c | 2457 |
1 files changed, 1301 insertions, 1156 deletions
diff --git a/nss/lib/certhigh/certvfy.c b/nss/lib/certhigh/certvfy.c index d5dcbe8..ccd38e6 100644 --- a/nss/lib/certhigh/certvfy.c +++ b/nss/lib/certhigh/certvfy.c @@ -12,10 +12,13 @@ #include "certdb.h" #include "certi.h" #include "cryptohi.h" + +#ifndef NSS_DISABLE_LIBPKIX #include "pkix.h" -/*#include "pkix_sample_modules.h" */ #include "pkix_pl_cert.h" - +#else +#include "nss.h" +#endif /* NSS_DISABLE_LIBPKIX */ #include "nsspki.h" #include "pkitm.h" @@ -34,9 +37,10 @@ CERT_CertTimesValid(CERTCertificate *c) return (valid == secCertTimeValid) ? SECSuccess : SECFailure; } -SECStatus checkKeyParams(const SECAlgorithmID *sigAlgorithm, const SECKEYPublicKey *key) +SECStatus +checkKeyParams(const SECAlgorithmID *sigAlgorithm, const SECKEYPublicKey *key) { - SECStatus rv; + SECStatus rv; SECOidTag sigAlg; SECOidTag curve; PRUint32 policyFlags = 0; @@ -44,81 +48,81 @@ SECStatus checkKeyParams(const SECAlgorithmID *sigAlgorithm, const SECKEYPublicK sigAlg = SECOID_GetAlgorithmTag(sigAlgorithm); - switch(sigAlg) { + switch (sigAlg) { case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: - case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: - case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: - case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: - case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: - if (key->keyType != ecKey) { - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - return SECFailure; - } + case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: + if (key->keyType != ecKey) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return SECFailure; + } curve = SECKEY_GetECCOid(&key->u.ec.DEREncodedParams); - if (curve != 0) { - if (NSS_GetAlgorithmPolicy(curve, &policyFlags) == SECFailure || - !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) { - PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); - return SECFailure; - } else { - return SECSuccess; + if (curve != 0) { + if (NSS_GetAlgorithmPolicy(curve, &policyFlags) == SECFailure || + !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) { + PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); + return SECFailure; + } else { + return SECSuccess; } } else { - PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); - return SECFailure; - } + 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; - } + 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; - } + 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; + default: + return SECSuccess; } } @@ -128,38 +132,38 @@ SECStatus checkKeyParams(const SECAlgorithmID *sigAlgorithm, const SECKEYPublicK SECStatus CERT_VerifySignedDataWithPublicKey(const CERTSignedData *sd, SECKEYPublicKey *pubKey, - void *wincx) + void *wincx) { - SECStatus rv; - SECItem sig; - SECOidTag hashAlg = SEC_OID_UNKNOWN; + SECStatus rv; + SECItem sig; + SECOidTag hashAlg = SEC_OID_UNKNOWN; - if ( !pubKey || !sd ) { - PORT_SetError(PR_INVALID_ARGUMENT_ERROR); - return SECFailure; + if (!pubKey || !sd) { + PORT_SetError(PR_INVALID_ARGUMENT_ERROR); + return SECFailure; } /* check the signature */ sig = sd->signature; /* convert sig->len from bit counts to byte count. */ DER_ConvertBitString(&sig); - rv = VFY_VerifyDataWithAlgorithmID(sd->data.data, sd->data.len, pubKey, - &sig, &sd->signatureAlgorithm, &hashAlg, wincx); + rv = VFY_VerifyDataWithAlgorithmID(sd->data.data, sd->data.len, pubKey, + &sig, &sd->signatureAlgorithm, &hashAlg, wincx); if (rv == SECSuccess) { /* Are we honoring signatures for this algorithm? */ - PRUint32 policyFlags = 0; - rv = checkKeyParams(&sd->signatureAlgorithm, pubKey); - if (rv != SECSuccess) { - PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); - return SECFailure; - } - - rv = NSS_GetAlgorithmPolicy(hashAlg, &policyFlags); - if (rv == SECSuccess && - !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) { - PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); - return SECFailure; - } + PRUint32 policyFlags = 0; + rv = checkKeyParams(&sd->signatureAlgorithm, pubKey); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); + return SECFailure; + } + + rv = NSS_GetAlgorithmPolicy(hashAlg, &policyFlags); + if (rv == SECSuccess && + !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) { + PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); + return SECFailure; + } } return rv; } @@ -168,18 +172,18 @@ CERT_VerifySignedDataWithPublicKey(const CERTSignedData *sd, * verify the signature of a signed data object with the given DER publickey */ SECStatus -CERT_VerifySignedDataWithPublicKeyInfo(CERTSignedData *sd, +CERT_VerifySignedDataWithPublicKeyInfo(CERTSignedData *sd, CERTSubjectPublicKeyInfo *pubKeyInfo, - void *wincx) + void *wincx) { SECKEYPublicKey *pubKey; - SECStatus rv = SECFailure; + SECStatus rv = SECFailure; /* get cert's public key */ pubKey = SECKEY_ExtractPublicKey(pubKeyInfo); if (pubKey) { - rv = CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx); - SECKEY_DestroyPublicKey(pubKey); + rv = CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx); + SECKEY_DestroyPublicKey(pubKey); } return rv; } @@ -189,31 +193,30 @@ CERT_VerifySignedDataWithPublicKeyInfo(CERTSignedData *sd, */ SECStatus CERT_VerifySignedData(CERTSignedData *sd, CERTCertificate *cert, - PRTime t, void *wincx) + PRTime t, void *wincx) { SECKEYPublicKey *pubKey = 0; - SECStatus rv = SECFailure; + SECStatus rv = SECFailure; SECCertTimeValidity validity; /* check the certificate's validity */ validity = CERT_CheckCertValidTimes(cert, t, PR_FALSE); - if ( validity != secCertTimeValid ) { - return rv; + if (validity != secCertTimeValid) { + return rv; } /* get cert's public key */ pubKey = CERT_ExtractPublicKey(cert); if (pubKey) { - rv = CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx); - SECKEY_DestroyPublicKey(pubKey); + rv = CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx); + SECKEY_DestroyPublicKey(pubKey); } return rv; } - SECStatus -SEC_CheckCRL(CERTCertDBHandle *handle,CERTCertificate *cert, - CERTCertificate *caCert, PRTime t, void * wincx) +SEC_CheckCRL(CERTCertDBHandle *handle, CERTCertificate *cert, + CERTCertificate *caCert, PRTime t, void *wincx) { return CERT_CheckCRL(cert, caCert, NULL, t, wincx); } @@ -235,33 +238,33 @@ CERT_FindCertIssuer(CERTCertificate *cert, PRTime validTime, SECCertUsage usage) me = STAN_GetNSSCertificate(cert); if (!me) { PORT_SetError(SEC_ERROR_NO_MEMORY); - return NULL; + return NULL; } nssTime = NSSTime_SetPRTime(NULL, validTime); nssUsage.anyUsage = PR_FALSE; nssUsage.nss3usage = usage; nssUsage.nss3lookingForCA = PR_TRUE; - memset(chain, 0, 3*sizeof(NSSCertificate *)); - td = STAN_GetDefaultTrustDomain(); + memset(chain, 0, 3 * sizeof(NSSCertificate *)); + td = STAN_GetDefaultTrustDomain(); cc = STAN_GetDefaultCryptoContext(); - (void)NSSCertificate_BuildChain(me, nssTime, &nssUsage, NULL, + (void)NSSCertificate_BuildChain(me, nssTime, &nssUsage, NULL, chain, 2, NULL, &status, td, cc); nss_ZFreeIf(nssTime); if (status == PR_SUCCESS) { - PORT_Assert(me == chain[0]); - /* if it's a root, the chain will only have one cert */ - if (!chain[1]) { - /* already has a reference from the call to BuildChain */ - return cert; - } - NSSCertificate_Destroy(chain[0]); /* the first cert in the chain */ - return STAN_GetCERTCertificate(chain[1]); /* return the 2nd */ - } + PORT_Assert(me == chain[0]); + /* if it's a root, the chain will only have one cert */ + if (!chain[1]) { + /* already has a reference from the call to BuildChain */ + return cert; + } + NSSCertificate_Destroy(chain[0]); /* the first cert in the chain */ + return STAN_GetCERTCertificate(chain[1]); /* return the 2nd */ + } if (chain[0]) { - PORT_Assert(me == chain[0]); - NSSCertificate_Destroy(chain[0]); /* the first cert in the chain */ + PORT_Assert(me == chain[0]); + NSSCertificate_Destroy(chain[0]); /* the first cert in the chain */ } - PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER); + PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); return NULL; } @@ -270,136 +273,272 @@ CERT_FindCertIssuer(CERTCertificate *cert, PRTime validTime, SECCertUsage usage) */ SECStatus CERT_TrustFlagsForCACertUsage(SECCertUsage usage, - unsigned int *retFlags, - SECTrustType *retTrustType) + unsigned int *retFlags, + SECTrustType *retTrustType) { unsigned int requiredFlags; SECTrustType trustType; - switch ( usage ) { - case certUsageSSLClient: - requiredFlags = CERTDB_TRUSTED_CLIENT_CA; - trustType = trustSSL; - break; - case certUsageSSLServer: - case certUsageSSLCA: - 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; - break; - case certUsageObjectSigner: - requiredFlags = CERTDB_TRUSTED_CA; - trustType = trustObjectSigning; - break; - case certUsageVerifyCA: - case certUsageAnyCA: - case certUsageStatusResponder: - requiredFlags = CERTDB_TRUSTED_CA; - trustType = trustTypeNone; - break; - default: - PORT_Assert(0); - goto loser; - } - if ( retFlags != NULL ) { - *retFlags = requiredFlags; - } - if ( retTrustType != NULL ) { - *retTrustType = trustType; - } - - return(SECSuccess); + switch (usage) { + case certUsageSSLClient: + requiredFlags = CERTDB_TRUSTED_CLIENT_CA; + trustType = trustSSL; + break; + case certUsageSSLServer: + case certUsageSSLCA: + 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; + break; + case certUsageObjectSigner: + requiredFlags = CERTDB_TRUSTED_CA; + trustType = trustObjectSigning; + break; + case certUsageVerifyCA: + case certUsageAnyCA: + case certUsageStatusResponder: + requiredFlags = CERTDB_TRUSTED_CA; + trustType = trustTypeNone; + break; + default: + PORT_Assert(0); + goto loser; + } + if (retFlags != NULL) { + *retFlags = requiredFlags; + } + if (retTrustType != NULL) { + *retTrustType = trustType; + } + + return (SECSuccess); loser: - return(SECFailure); + return (SECFailure); } void cert_AddToVerifyLog(CERTVerifyLog *log, CERTCertificate *cert, long error, - unsigned int depth, void *arg) + unsigned int depth, void *arg) { CERTVerifyLogNode *node, *tnode; PORT_Assert(log != NULL); - + node = (CERTVerifyLogNode *)PORT_ArenaAlloc(log->arena, - sizeof(CERTVerifyLogNode)); - if ( node != NULL ) { - node->cert = CERT_DupCertificate(cert); - node->error = error; - node->depth = depth; - node->arg = arg; - - if ( log->tail == NULL ) { - /* empty list */ - log->head = log->tail = node; - node->prev = NULL; - node->next = NULL; - } else if ( depth >= log->tail->depth ) { - /* add to tail */ - node->prev = log->tail; - log->tail->next = node; - log->tail = node; - node->next = NULL; - } else if ( depth < log->head->depth ) { - /* add at head */ - node->prev = NULL; - node->next = log->head; - log->head->prev = node; - log->head = node; - } else { - /* add in middle */ - tnode = log->tail; - while ( tnode != NULL ) { - if ( depth >= tnode->depth ) { - /* insert after tnode */ - node->prev = tnode; - node->next = tnode->next; - tnode->next->prev = node; - tnode->next = node; - break; - } - - tnode = tnode->prev; - } - } - - log->count++; + sizeof(CERTVerifyLogNode)); + if (node != NULL) { + node->cert = CERT_DupCertificate(cert); + node->error = error; + node->depth = depth; + node->arg = arg; + + if (log->tail == NULL) { + /* empty list */ + log->head = log->tail = node; + node->prev = NULL; + node->next = NULL; + } else if (depth >= log->tail->depth) { + /* add to tail */ + node->prev = log->tail; + log->tail->next = node; + log->tail = node; + node->next = NULL; + } else if (depth < log->head->depth) { + /* add at head */ + node->prev = NULL; + node->next = log->head; + log->head->prev = node; + log->head = node; + } else { + /* add in middle */ + tnode = log->tail; + while (tnode != NULL) { + if (depth >= tnode->depth) { + /* insert after tnode */ + node->prev = tnode; + node->next = tnode->next; + tnode->next->prev = node; + tnode->next = node; + break; + } + + tnode = tnode->prev; + } + } + + log->count++; } return; } #define EXIT_IF_NOT_LOGGING(log) \ - if ( log == NULL ) { \ - goto loser; \ + if (log == NULL) { \ + goto loser; \ + } + +#define LOG_ERROR_OR_EXIT(log, cert, depth, arg) \ + if (log != NULL) { \ + cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \ + (void *)(PRWord)arg); \ + } else { \ + goto loser; \ + } + +#define LOG_ERROR(log, cert, depth, arg) \ + if (log != NULL) { \ + cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \ + (void *)(PRWord)arg); \ + } + +/* /C=CN/O=WoSign CA Limited/CN=CA \xE6\xB2\x83\xE9\x80\x9A\xE6\xA0\xB9\xE8\xAF\x81\xE4\xB9\xA6 + * Using a consistent naming convention, this would actually be called + * 'CA沃通根证书DN', but since GCC 6.2.1 apparently can't handle UTF-8 + * identifiers, this will have to do. + */ +static const unsigned char CAWoSignRootDN[72] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, + 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D, + 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x12, 0x43, 0x41, 0x20, 0xE6, 0xB2, 0x83, 0xE9, 0x80, 0x9A, 0xE6, 0xA0, + 0xB9, 0xE8, 0xAF, 0x81, 0xE4, 0xB9, 0xA6, +}; + +/* /C=CN/O=WoSign CA Limited/CN=CA WoSign ECC Root */ +static const unsigned char CAWoSignECCRootDN[72] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, + 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D, + 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x12, 0x43, 0x41, 0x20, 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, + 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, +}; + +/* /C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign */ +static const unsigned char CertificationAuthorityofWoSignDN[87] = { + 0x30, 0x55, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, + 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D, + 0x69, 0x74, 0x65, 0x64, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x21, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x6F, 0x66, 0x20, 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, +}; + +/* /C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign G2 */ +static const unsigned char CertificationAuthorityofWoSignG2DN[90] = { + 0x30, 0x58, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, + 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D, + 0x69, 0x74, 0x65, 0x64, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x24, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x6F, 0x66, 0x20, 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, 0x32, +}; + +/* /C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority */ +static const unsigned char StartComCertificationAuthorityDN[127] = { + 0x30, 0x7D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x49, 0x4C, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, 0x4C, 0x74, 0x64, 0x2E, + 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x22, 0x53, 0x65, + 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6C, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, + 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, +}; + +/* /C=IL/O=StartCom Ltd./CN=StartCom Certification Authority G2 */ +static const unsigned char StartComCertificationAuthorityG2DN[85] = { + 0x30, 0x53, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x49, 0x4C, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, 0x4C, 0x74, 0x64, 0x2E, + 0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x23, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79, 0x20, 0x47, 0x32, +}; + +struct DataAndLength { + const unsigned char *data; + PRUint32 len; +}; + +static const struct DataAndLength StartComAndWoSignDNs[] = { + { CAWoSignRootDN, + sizeof(CAWoSignRootDN) }, + { CAWoSignECCRootDN, + sizeof(CAWoSignECCRootDN) }, + { CertificationAuthorityofWoSignDN, + sizeof(CertificationAuthorityofWoSignDN) }, + { CertificationAuthorityofWoSignG2DN, + sizeof(CertificationAuthorityofWoSignG2DN) }, + { StartComCertificationAuthorityDN, + sizeof(StartComCertificationAuthorityDN) }, + { StartComCertificationAuthorityG2DN, + sizeof(StartComCertificationAuthorityG2DN) }, +}; + +static PRBool +CertIsStartComOrWoSign(const CERTCertificate *cert) +{ + int i; + const struct DataAndLength *dn = StartComAndWoSignDNs; + + for (i = 0; i < sizeof(StartComAndWoSignDNs) / sizeof(struct DataAndLength); ++i, dn++) { + if (cert->derSubject.len == dn->len && + memcmp(cert->derSubject.data, dn->data, dn->len) == 0) { + return PR_TRUE; + } } + return PR_FALSE; +} -#define LOG_ERROR_OR_EXIT(log,cert,depth,arg) \ - if ( log != NULL ) { \ - cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \ - (void *)(PRWord)arg); \ - } else { \ - goto loser; \ +SECStatus +isIssuerCertAllowedAtCertIssuanceTime(CERTCertificate *issuerCert, + CERTCertificate *referenceCert) +{ + if (!issuerCert || !referenceCert) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; } -#define LOG_ERROR(log,cert,depth,arg) \ - if ( log != NULL ) { \ - cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \ - (void *)(PRWord)arg); \ + if (CertIsStartComOrWoSign(issuerCert)) { + /* PRTime is microseconds since the epoch, whereas JS time is milliseconds. + * (new Date("2016-10-21T00:00:00Z")).getTime() * 1000 + */ + static const PRTime OCTOBER_21_2016 = 1477008000000000; + + PRTime notBefore, notAfter; + SECStatus rv; + + rv = CERT_GetCertTimes(referenceCert, ¬Before, ¬After); + if (rv != SECSuccess) + return rv; + + if (notBefore > OCTOBER_21_2016) { + return SECFailure; + } } + return SECSuccess; +} + static SECStatus cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, PRBool* sigerror, - SECCertUsage certUsage, PRTime t, void *wincx, - CERTVerifyLog *log, PRBool* revoked) + PRBool checkSig, PRBool *sigerror, + SECCertUsage certUsage, PRTime t, void *wincx, + CERTVerifyLog *log, PRBool *revoked) { SECTrustType trustType; CERTBasicConstraints basicConstraint; @@ -417,7 +556,7 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert, unsigned int requiredFlags; PLArenaPool *arena = NULL; CERTGeneralName *namesList = NULL; - CERTCertificate **certsList = NULL; + CERTCertificate **certsList = NULL; int certsListLen = 16; int namesCount = 0; PRBool subjectCertIsSelfIssued; @@ -428,177 +567,178 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert, } if (CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_TRUE, - &requiredCAKeyUsage, - &caCertType) - != SECSuccess ) { - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - requiredCAKeyUsage = 0; - caCertType = 0; - } - - switch ( certUsage ) { - case certUsageSSLClient: - case certUsageSSLServer: - case certUsageSSLCA: - case certUsageSSLServerWithStepUp: - case certUsageEmailSigner: - case certUsageEmailRecipient: - case certUsageObjectSigner: - case certUsageVerifyCA: - case certUsageAnyCA: - case certUsageStatusResponder: - if ( CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, - &trustType) != SECSuccess ) { - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - /* XXX continuing with requiredFlags = 0 seems wrong. It'll - * cause the following test to be true incorrectly: - * flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType); - * if (( flags & requiredFlags ) == requiredFlags) { - * rv = rvFinal; - * goto done; - * } - * There are three other instances of this problem. - */ - requiredFlags = 0; - trustType = trustSSL; - } - break; - default: - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - requiredFlags = 0; - trustType = trustSSL;/* This used to be 0, but we need something - * that matches the enumeration type. - */ - caCertType = 0; - } - + &requiredCAKeyUsage, + &caCertType) != + SECSuccess) { + PORT_Assert(0); + EXIT_IF_NOT_LOGGING(log); + requiredCAKeyUsage = 0; + caCertType = 0; + } + + switch (certUsage) { + case certUsageSSLClient: + case certUsageSSLServer: + case certUsageSSLCA: + case certUsageSSLServerWithStepUp: + case certUsageEmailSigner: + case certUsageEmailRecipient: + case certUsageObjectSigner: + case certUsageVerifyCA: + case certUsageAnyCA: + case certUsageStatusResponder: + if (CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, + &trustType) != SECSuccess) { + PORT_Assert(0); + EXIT_IF_NOT_LOGGING(log); + /* XXX continuing with requiredFlags = 0 seems wrong. It'll + * cause the following test to be true incorrectly: + * flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType); + * if (( flags & requiredFlags ) == requiredFlags) { + * rv = rvFinal; + * goto done; + * } + * There are three other instances of this problem. + */ + requiredFlags = 0; + trustType = trustSSL; + } + break; + default: + PORT_Assert(0); + EXIT_IF_NOT_LOGGING(log); + requiredFlags = 0; + trustType = trustSSL; /* This used to be 0, but we need something + * that matches the enumeration type. + */ + caCertType = 0; + } + subjectCert = CERT_DupCertificate(cert); - if ( subjectCert == NULL ) { - goto loser; + if (subjectCert == NULL) { + goto loser; } arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { - goto loser; + goto loser; } certsList = PORT_ZNewArray(CERTCertificate *, certsListLen); if (certsList == NULL) - goto loser; + goto loser; /* RFC 3280 says that the name constraints will apply to the names ** in the leaf (EE) cert, whether it is self issued or not, so ** we pretend that it is not. */ subjectCertIsSelfIssued = PR_FALSE; - for ( count = 0; count < CERT_MAX_CERT_CHAIN; count++ ) { - PRBool validCAOverride = PR_FALSE; - - /* Construct a list of names for the current and all previous - * 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); - subjectNameList = - CERT_GetConstrainedCertificateNames(subjectCert, arena, - getSubjectCN); - if (!subjectNameList) - goto loser; - subjectNameListLen = CERT_GetNamesLength(subjectNameList); - if (!subjectNameListLen) - goto loser; - if (certsListLen <= namesCount + subjectNameListLen) { - CERTCertificate **tmpCertsList; - certsListLen = (namesCount + subjectNameListLen) * 2; - tmpCertsList = - (CERTCertificate **)PORT_Realloc(certsList, - certsListLen * sizeof(CERTCertificate *)); - if (tmpCertsList == NULL) { - goto loser; - } - certsList = tmpCertsList; - } - for (i = 0; i < subjectNameListLen; i++) { - certsList[namesCount + i] = subjectCert; - } - namesCount += subjectNameListLen; - namesList = cert_CombineNamesLists(namesList, subjectNameList); - } + for (count = 0; count < CERT_MAX_CERT_CHAIN; count++) { + PRBool validCAOverride = PR_FALSE; + + /* Construct a list of names for the current and all previous + * 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); + subjectNameList = + CERT_GetConstrainedCertificateNames(subjectCert, arena, + getSubjectCN); + if (!subjectNameList) + goto loser; + subjectNameListLen = CERT_GetNamesLength(subjectNameList); + if (!subjectNameListLen) + goto loser; + if (certsListLen <= namesCount + subjectNameListLen) { + CERTCertificate **tmpCertsList; + certsListLen = (namesCount + subjectNameListLen) * 2; + tmpCertsList = + (CERTCertificate **)PORT_Realloc(certsList, + certsListLen * + sizeof(CERTCertificate *)); + if (tmpCertsList == NULL) { + goto loser; + } + certsList = tmpCertsList; + } + for (i = 0; i < subjectNameListLen; i++) { + certsList[namesCount + i] = subjectCert; + } + namesCount += subjectNameListLen; + namesList = cert_CombineNamesLists(namesList, subjectNameList); + } /* check if the cert has an unsupported critical extension */ - if ( subjectCert->options.bits.hasUnsupportedCriticalExt ) { - PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION); - LOG_ERROR_OR_EXIT(log,subjectCert,count,0); - } - - /* find the certificate of the issuer */ - issuerCert = CERT_FindCertIssuer(subjectCert, t, certUsage); - if ( ! issuerCert ) { - PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); - LOG_ERROR(log,subjectCert,count,0); - goto loser; - } - - /* verify the signature on the cert */ - if ( checkSig ) { - rv = CERT_VerifySignedData(&subjectCert->signatureWrap, - issuerCert, t, wincx); - - if ( rv != SECSuccess ) { + if (subjectCert->options.bits.hasUnsupportedCriticalExt) { + PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION); + LOG_ERROR_OR_EXIT(log, subjectCert, count, 0); + } + + /* find the certificate of the issuer */ + issuerCert = CERT_FindCertIssuer(subjectCert, t, certUsage); + if (!issuerCert) { + PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); + LOG_ERROR(log, subjectCert, count, 0); + goto loser; + } + + /* verify the signature on the cert */ + if (checkSig) { + rv = CERT_VerifySignedData(&subjectCert->signatureWrap, + issuerCert, t, wincx); + + if (rv != SECSuccess) { if (sigerror) { *sigerror = PR_TRUE; } - if ( PORT_GetError() == SEC_ERROR_EXPIRED_CERTIFICATE ) { - PORT_SetError(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE); - LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0); - } else { - if (PORT_GetError() != - SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED) { - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - } - LOG_ERROR_OR_EXIT(log,subjectCert,count,0); - } - } - } - - /* If the basicConstraint extension is included in an immediate CA - * certificate, make sure that the isCA flag is on. If the - * pathLenConstraint component exists, it must be greater than the - * number of CA certificates we have seen so far. If the extension - * is omitted, we will assume that this is a CA certificate with - * an unlimited pathLenConstraint (since it already passes the - * netscape-cert-type extension checking). - */ - - rv = CERT_FindBasicConstraintExten(issuerCert, &basicConstraint); - if ( rv != SECSuccess ) { - if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { - LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0); - } - pathLengthLimit = CERT_UNLIMITED_PATH_CONSTRAINT; - /* no basic constraints found, we aren't (yet) a CA. */ - isca = PR_FALSE; - } else { - if ( basicConstraint.isCA == PR_FALSE ) { - PORT_SetError (SEC_ERROR_CA_CERT_INVALID); - LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0); - } - pathLengthLimit = basicConstraint.pathLenConstraint; - isca = PR_TRUE; - } - /* make sure that the path len constraint is properly set.*/ - if (pathLengthLimit >= 0 && currentPathLen > pathLengthLimit) { - PORT_SetError (SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID); - LOG_ERROR_OR_EXIT(log, issuerCert, count+1, pathLengthLimit); - } + if (PORT_GetError() == SEC_ERROR_EXPIRED_CERTIFICATE) { + PORT_SetError(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE); + LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, 0); + } else { + if (PORT_GetError() != + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + } + LOG_ERROR_OR_EXIT(log, subjectCert, count, 0); + } + } + } + + /* If the basicConstraint extension is included in an immediate CA + * certificate, make sure that the isCA flag is on. If the + * pathLenConstraint component exists, it must be greater than the + * number of CA certificates we have seen so far. If the extension + * is omitted, we will assume that this is a CA certificate with + * an unlimited pathLenConstraint (since it already passes the + * netscape-cert-type extension checking). + */ + + rv = CERT_FindBasicConstraintExten(issuerCert, &basicConstraint); + if (rv != SECSuccess) { + if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { + LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, 0); + } + pathLengthLimit = CERT_UNLIMITED_PATH_CONSTRAINT; + /* no basic constraints found, we aren't (yet) a CA. */ + isca = PR_FALSE; + } else { + if (basicConstraint.isCA == PR_FALSE) { + PORT_SetError(SEC_ERROR_CA_CERT_INVALID); + LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, 0); + } + pathLengthLimit = basicConstraint.pathLenConstraint; + isca = PR_TRUE; + } + /* make sure that the path len constraint is properly set.*/ + if (pathLengthLimit >= 0 && currentPathLen > pathLengthLimit) { + PORT_SetError(SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID); + LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, pathLengthLimit); + } /* make sure that the entire chain is within the name space of the * current issuer certificate. @@ -611,16 +751,23 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert, goto loser; } - /* XXX - the error logging may need to go down into CRL stuff at some - * point - */ - /* check revoked list (issuer) */ + rv = isIssuerCertAllowedAtCertIssuanceTime(issuerCert, cert); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); + LOG_ERROR(log, issuerCert, count + 1, 0); + goto loser; + } + + /* XXX - the error logging may need to go down into CRL stuff at some + * point + */ + /* check revoked list (issuer) */ rv = SEC_CheckCRL(handle, subjectCert, issuerCert, t, wincx); if (rv == SECFailure) { if (revoked) { *revoked = PR_TRUE; } - LOG_ERROR_OR_EXIT(log,subjectCert,count,0); + LOG_ERROR_OR_EXIT(log, subjectCert, count, 0); } else if (rv == SECWouldBlock) { /* We found something fishy, so we intend to issue an * error to the user, but the user may wish to continue @@ -630,163 +777,164 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert, if (revoked) { *revoked = PR_TRUE; } - LOG_ERROR(log,subjectCert,count,0); + LOG_ERROR(log, subjectCert, count, 0); } - if ( CERT_GetCertTrust(issuerCert, &issuerTrust) == SECSuccess) { - /* we have some trust info, but this does NOT imply that this - * cert is actually trusted for any purpose. The cert may be - * explicitly UNtrusted. We won't know until we examine the - * trust bits. - */ - unsigned int flags; - - if (certUsage != certUsageAnyCA && - certUsage != certUsageStatusResponder) { - - /* - * XXX This choice of trustType seems arbitrary. - */ - if ( certUsage == certUsageVerifyCA ) { - if ( subjectCert->nsCertType & NS_CERT_TYPE_EMAIL_CA ) { - trustType = trustEmail; - } else if ( subjectCert->nsCertType & NS_CERT_TYPE_SSL_CA ) { - trustType = trustSSL; - } else { - trustType = trustObjectSigning; - } - } - - flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType); - if (( flags & requiredFlags ) == requiredFlags) { - /* we found a trusted one, so return */ - rv = rvFinal; - goto done; - } - if (flags & CERTDB_VALID_CA) { - validCAOverride = PR_TRUE; - } - /* is it explicitly distrusted? */ - if ((flags & CERTDB_TERMINAL_RECORD) && - ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) { - /* untrusted -- the cert is explicitly untrusted, not - * just that it doesn't chain to a trusted cert */ - PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); - LOG_ERROR_OR_EXIT(log,issuerCert,count+1,flags); - } - } else { + if (CERT_GetCertTrust(issuerCert, &issuerTrust) == SECSuccess) { + /* we have some trust info, but this does NOT imply that this + * cert is actually trusted for any purpose. The cert may be + * explicitly UNtrusted. We won't know until we examine the + * trust bits. + */ + unsigned int flags; + + if (certUsage != certUsageAnyCA && + certUsage != certUsageStatusResponder) { + + /* + * XXX This choice of trustType seems arbitrary. + */ + if (certUsage == certUsageVerifyCA) { + if (subjectCert->nsCertType & NS_CERT_TYPE_EMAIL_CA) { + trustType = trustEmail; + } else if (subjectCert->nsCertType & NS_CERT_TYPE_SSL_CA) { + trustType = trustSSL; + } else { + trustType = trustObjectSigning; + } + } + + flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType); + if ((flags & requiredFlags) == requiredFlags) { + /* we found a trusted one, so return */ + rv = rvFinal; + goto done; + } + if (flags & CERTDB_VALID_CA) { + validCAOverride = PR_TRUE; + } + /* is it explicitly distrusted? */ + if ((flags & CERTDB_TERMINAL_RECORD) && + ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0)) { + /* untrusted -- the cert is explicitly untrusted, not + * just that it doesn't chain to a trusted cert */ + PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); + LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, flags); + } + } else { /* Check if we have any valid trust when cheching for * certUsageAnyCA or certUsageStatusResponder. */ for (trustType = trustSSL; trustType < trustTypeNone; trustType++) { flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType); if ((flags & requiredFlags) == requiredFlags) { - rv = rvFinal; - goto done; + rv = rvFinal; + goto done; } if (flags & CERTDB_VALID_CA) validCAOverride = PR_TRUE; } - /* We have 2 separate loops because we want any single trust - * bit to allow this usage to return trusted. Only if none of - * the trust bits are on do we check to see if the cert is - * untrusted */ + /* We have 2 separate loops because we want any single trust + * bit to allow this usage to return trusted. Only if none of + * the trust bits are on do we check to see if the cert is + * untrusted */ for (trustType = trustSSL; trustType < trustTypeNone; trustType++) { flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType); - /* is it explicitly distrusted? */ - if ((flags & CERTDB_TERMINAL_RECORD) && - ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) { - /* untrusted -- the cert is explicitly untrusted, not - * just that it doesn't chain to a trusted cert */ - PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); - LOG_ERROR_OR_EXIT(log,issuerCert,count+1,flags); - } + /* is it explicitly distrusted? */ + if ((flags & CERTDB_TERMINAL_RECORD) && + ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0)) { + /* untrusted -- the cert is explicitly untrusted, not + * just that it doesn't chain to a trusted cert */ + PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); + LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, flags); + } } } } - if (!validCAOverride) { - /* - * Make sure that if this is an intermediate CA in the chain that - * it was given permission by its signer to be a CA. - */ - /* - * if basicConstraints says it is a ca, then we check the - * nsCertType. If the nsCertType has any CA bits set, then - * it must have the right one. - */ - if (!isca || (issuerCert->nsCertType & NS_CERT_TYPE_CA)) { - isca = (issuerCert->nsCertType & caCertType) ? PR_TRUE : PR_FALSE; - } - - if ( !isca ) { - PORT_SetError(SEC_ERROR_CA_CERT_INVALID); - LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0); - } - - /* make sure key usage allows cert signing */ - if (CERT_CheckKeyUsage(issuerCert, requiredCAKeyUsage) != SECSuccess) { - PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); - LOG_ERROR_OR_EXIT(log,issuerCert,count+1,requiredCAKeyUsage); - } - } - - /* make sure that the issuer is not self signed. If it is, then - * stop here to prevent looping. - */ - if (issuerCert->isRoot) { - PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); - LOG_ERROR(log, issuerCert, count+1, 0); - goto loser; - } - /* The issuer cert will be the subject cert in the next loop. - * A cert is self-issued if its subject and issuer are equal and - * both are of non-zero length. - */ - subjectCertIsSelfIssued = (PRBool) - SECITEM_ItemsAreEqual(&issuerCert->derIssuer, - &issuerCert->derSubject) && - issuerCert->derSubject.len > 0; - if (subjectCertIsSelfIssued == PR_FALSE) { - /* RFC 3280 says only non-self-issued intermediate CA certs - * count in path length. - */ - ++currentPathLen; - } - - CERT_DestroyCertificate(subjectCert); - subjectCert = issuerCert; - issuerCert = NULL; + if (!validCAOverride) { + /* + * Make sure that if this is an intermediate CA in the chain that + * it was given permission by its signer to be a CA. + */ + /* + * if basicConstraints says it is a ca, then we check the + * nsCertType. If the nsCertType has any CA bits set, then + * it must have the right one. + */ + if (!isca || (issuerCert->nsCertType & NS_CERT_TYPE_CA)) { + isca = (issuerCert->nsCertType & caCertType) ? PR_TRUE : PR_FALSE; + } + + if (!isca) { + PORT_SetError(SEC_ERROR_CA_CERT_INVALID); + LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, 0); + } + + /* make sure key usage allows cert signing */ + if (CERT_CheckKeyUsage(issuerCert, requiredCAKeyUsage) != SECSuccess) { + PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); + LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, requiredCAKeyUsage); + } + } + + /* make sure that the issuer is not self signed. If it is, then + * stop here to prevent looping. + */ + if (issuerCert->isRoot) { + PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); + LOG_ERROR(log, issuerCert, count + 1, 0); + goto loser; + } + /* The issuer cert will be the subject cert in the next loop. + * A cert is self-issued if its subject and issuer are equal and + * both are of non-zero length. + */ + subjectCertIsSelfIssued = (PRBool) + SECITEM_ItemsAreEqual(&issuerCert->derIssuer, + &issuerCert->derSubject) && + issuerCert->derSubject.len > + 0; + if (subjectCertIsSelfIssued == PR_FALSE) { + /* RFC 3280 says only non-self-issued intermediate CA certs + * count in path length. + */ + ++currentPathLen; + } + + CERT_DestroyCertificate(subjectCert); + subjectCert = issuerCert; + issuerCert = NULL; } PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); - LOG_ERROR(log,subjectCert,count,0); + LOG_ERROR(log, subjectCert, count, 0); loser: rv = SECFailure; done: if (certsList != NULL) { - PORT_Free(certsList); + PORT_Free(certsList); } - if ( issuerCert ) { - CERT_DestroyCertificate(issuerCert); + if (issuerCert) { + CERT_DestroyCertificate(issuerCert); } - - if ( subjectCert ) { - CERT_DestroyCertificate(subjectCert); + + if (subjectCert) { + CERT_DestroyCertificate(subjectCert); } - if ( arena != NULL ) { - PORT_FreeArena(arena, PR_FALSE); + if (arena != NULL) { + PORT_FreeArena(arena, PR_FALSE); } return rv; } SECStatus cert_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, PRBool* sigerror, + PRBool checkSig, PRBool *sigerror, SECCertUsage certUsage, PRTime t, void *wincx, - CERTVerifyLog *log, PRBool* revoked) + CERTVerifyLog *log, PRBool *revoked) { if (CERT_GetUsePKIXForValidation()) { return cert_VerifyCertChainPkix(cert, checkSig, certUsage, t, @@ -798,11 +946,11 @@ cert_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, SECStatus CERT_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertUsage certUsage, PRTime t, - void *wincx, CERTVerifyLog *log) + PRBool checkSig, SECCertUsage certUsage, PRTime t, + void *wincx, CERTVerifyLog *log) { return cert_VerifyCertChain(handle, cert, checkSig, NULL, certUsage, t, - wincx, log, NULL); + wincx, log, NULL); } /* @@ -810,8 +958,8 @@ CERT_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, */ SECStatus CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertUsage certUsage, PRTime t, - void *wincx, CERTVerifyLog *log) + PRBool checkSig, SECCertUsage certUsage, PRTime t, + void *wincx, CERTVerifyLog *log) { SECTrustType trustType; CERTBasicConstraints basicConstraint; @@ -826,44 +974,43 @@ CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert, CERTCertificate *issuerCert; CERTCertTrust certTrust; - if (CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_TRUE, - &requiredCAKeyUsage, - &caCertType) != SECSuccess ) { - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - requiredCAKeyUsage = 0; - caCertType = 0; - } - - switch ( certUsage ) { - case certUsageSSLClient: - case certUsageSSLServer: - case certUsageSSLCA: - case certUsageSSLServerWithStepUp: - case certUsageEmailSigner: - case certUsageEmailRecipient: - case certUsageObjectSigner: - case certUsageVerifyCA: - case certUsageStatusResponder: - if ( CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, - &trustType) != SECSuccess ) { - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - requiredFlags = 0; - trustType = trustSSL; - } - break; - default: - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - requiredFlags = 0; - trustType = trustSSL;/* This used to be 0, but we need something - * that matches the enumeration type. - */ - caCertType = 0; - } - + &requiredCAKeyUsage, + &caCertType) != SECSuccess) { + PORT_Assert(0); + EXIT_IF_NOT_LOGGING(log); + requiredCAKeyUsage = 0; + caCertType = 0; + } + + switch (certUsage) { + case certUsageSSLClient: + case certUsageSSLServer: + case certUsageSSLCA: + case certUsageSSLServerWithStepUp: + case certUsageEmailSigner: + case certUsageEmailRecipient: + case certUsageObjectSigner: + case certUsageVerifyCA: + case certUsageStatusResponder: + if (CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, + &trustType) != SECSuccess) { + PORT_Assert(0); + EXIT_IF_NOT_LOGGING(log); + requiredFlags = 0; + trustType = trustSSL; + } + break; + default: + PORT_Assert(0); + EXIT_IF_NOT_LOGGING(log); + requiredFlags = 0; + trustType = trustSSL; /* This used to be 0, but we need something + * that matches the enumeration type. + */ + caCertType = 0; + } + /* If the basicConstraint extension is included in an intermmediate CA * certificate, make sure that the isCA flag is on. If the * pathLenConstraint component exists, it must be greater than the @@ -874,133 +1021,136 @@ CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert, */ rv = CERT_FindBasicConstraintExten(cert, &basicConstraint); - if ( rv != SECSuccess ) { - if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { - LOG_ERROR_OR_EXIT(log,cert,0,0); - } - /* no basic constraints found, we aren't (yet) a CA. */ - isca = PR_FALSE; - } else { - if ( basicConstraint.isCA == PR_FALSE ) { - PORT_SetError (SEC_ERROR_CA_CERT_INVALID); - LOG_ERROR_OR_EXIT(log,cert,0,0); - } - - /* can't check path length if we don't know the previous path */ - isca = PR_TRUE; - } - - if ( CERT_GetCertTrust(cert, &certTrust) == SECSuccess ) { - /* we have some trust info, but this does NOT imply that this - * cert is actually trusted for any purpose. The cert may be - * explicitly UNtrusted. We won't know until we examine the - * trust bits. - */ + if (rv != SECSuccess) { + if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { + LOG_ERROR_OR_EXIT(log, cert, 0, 0); + } + /* no basic constraints found, we aren't (yet) a CA. */ + isca = PR_FALSE; + } else { + if (basicConstraint.isCA == PR_FALSE) { + PORT_SetError(SEC_ERROR_CA_CERT_INVALID); + LOG_ERROR_OR_EXIT(log, cert, 0, 0); + } + + /* can't check path length if we don't know the previous path */ + isca = PR_TRUE; + } + + if (CERT_GetCertTrust(cert, &certTrust) == SECSuccess) { + /* we have some trust info, but this does NOT imply that this + * cert is actually trusted for any purpose. The cert may be + * explicitly UNtrusted. We won't know until we examine the + * trust bits. + */ if (certUsage == certUsageStatusResponder) { - /* Check the special case of certUsageStatusResponder */ + /* Check the special case of certUsageStatusResponder */ issuerCert = CERT_FindCertIssuer(cert, t, certUsage); if (issuerCert) { - if (SEC_CheckCRL(handle, cert, issuerCert, t, wincx) - != SECSuccess) { + if (SEC_CheckCRL(handle, cert, issuerCert, t, wincx) != + SECSuccess) { PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); CERT_DestroyCertificate(issuerCert); goto loser; } CERT_DestroyCertificate(issuerCert); } - /* XXX We have NOT determined that this cert is trusted. - * For years, NSS has treated this as trusted, - * but it seems incorrect. - */ - rv = rvFinal; - goto done; + /* XXX We have NOT determined that this cert is trusted. + * For years, NSS has treated this as trusted, + * but it seems incorrect. + */ + rv = rvFinal; + goto done; } - /* - * check the trust params of the issuer - */ - flags = SEC_GET_TRUST_FLAGS(&certTrust, trustType); - if ( ( flags & requiredFlags ) == requiredFlags) { - /* we found a trusted one, so return */ - rv = rvFinal; - goto done; - } - if (flags & CERTDB_VALID_CA) { - validCAOverride = PR_TRUE; - } - /* is it explicitly distrusted? */ - if ((flags & CERTDB_TERMINAL_RECORD) && - ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) { - /* untrusted -- the cert is explicitly untrusted, not - * just that it doesn't chain to a trusted cert */ - PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); - LOG_ERROR_OR_EXIT(log,cert,0,flags); - } + /* + * check the trust params of the issuer + */ + flags = SEC_GET_TRUST_FLAGS(&certTrust, trustType); + if ((flags & requiredFlags) == requiredFlags) { + /* we found a trusted one, so return */ + rv = rvFinal; + goto done; + } + if (flags & CERTDB_VALID_CA) { + validCAOverride = PR_TRUE; + } + /* is it explicitly distrusted? */ + if ((flags & CERTDB_TERMINAL_RECORD) && + ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0)) { + /* untrusted -- the cert is explicitly untrusted, not + * just that it doesn't chain to a trusted cert */ + PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); + LOG_ERROR_OR_EXIT(log, cert, 0, flags); + } } if (!validCAOverride) { - /* - * Make sure that if this is an intermediate CA in the chain that - * it was given permission by its signer to be a CA. - */ - /* - * if basicConstraints says it is a ca, then we check the - * nsCertType. If the nsCertType has any CA bits set, then - * it must have the right one. - */ - if (!isca || (cert->nsCertType & NS_CERT_TYPE_CA)) { - isca = (cert->nsCertType & caCertType) ? PR_TRUE : PR_FALSE; - } - - if (!isca) { - PORT_SetError(SEC_ERROR_CA_CERT_INVALID); - LOG_ERROR_OR_EXIT(log,cert,0,0); - } - - /* make sure key usage allows cert signing */ - if (CERT_CheckKeyUsage(cert, requiredCAKeyUsage) != SECSuccess) { - PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); - LOG_ERROR_OR_EXIT(log,cert,0,requiredCAKeyUsage); - } + /* + * Make sure that if this is an intermediate CA in the chain that + * it was given permission by its signer to be a CA. + */ + /* + * if basicConstraints says it is a ca, then we check the + * nsCertType. If the nsCertType has any CA bits set, then + * it must have the right one. + */ + if (!isca || (cert->nsCertType & NS_CERT_TYPE_CA)) { + isca = (cert->nsCertType & caCertType) ? PR_TRUE : PR_FALSE; + } + + if (!isca) { + PORT_SetError(SEC_ERROR_CA_CERT_INVALID); + LOG_ERROR_OR_EXIT(log, cert, 0, 0); + } + + /* make sure key usage allows cert signing */ + if (CERT_CheckKeyUsage(cert, requiredCAKeyUsage) != SECSuccess) { + PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); + LOG_ERROR_OR_EXIT(log, cert, 0, requiredCAKeyUsage); + } } /* make sure that the issuer is not self signed. If it is, then * stop here to prevent looping. */ if (cert->isRoot) { - PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); - LOG_ERROR(log, cert, 0, 0); - goto loser; + PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); + LOG_ERROR(log, cert, 0, 0); + goto loser; } - return CERT_VerifyCertChain(handle, cert, checkSig, certUsage, t, - wincx, log); + return CERT_VerifyCertChain(handle, cert, checkSig, certUsage, t, + wincx, log); loser: rv = SECFailure; done: return rv; } -#define NEXT_USAGE() { \ - i*=2; \ - certUsage++; \ - continue; \ -} +#define NEXT_USAGE() \ + { \ + i *= 2; \ + certUsage++; \ + continue; \ + } -#define VALID_USAGE() { \ - NEXT_USAGE(); \ -} +#define VALID_USAGE() \ + { \ + NEXT_USAGE(); \ + } -#define INVALID_USAGE() { \ - if (returnedUsages) { \ - *returnedUsages &= (~i); \ - } \ - if (PR_TRUE == requiredUsage) { \ - valid = SECFailure; \ - } \ - NEXT_USAGE(); \ -} +#define INVALID_USAGE() \ + { \ + if (returnedUsages) { \ + *returnedUsages &= (~i); \ + } \ + if (PR_TRUE == requiredUsage) { \ + valid = SECFailure; \ + } \ + NEXT_USAGE(); \ + } /* - * check the leaf cert against trust and usage. + * check the leaf cert against trust and usage. * returns success if the cert is not distrusted. If the cert is * trusted, then the trusted bool will be true. * returns failure if the cert is distrusted. If failure, flags @@ -1008,141 +1158,140 @@ done: */ SECStatus cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage, - unsigned int *failedFlags, PRBool *trusted) + unsigned int *failedFlags, PRBool *trusted) { unsigned int flags; CERTCertTrust trust; *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: - 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; - } else { /* don't trust this cert */ - *failedFlags = flags; - return SECFailure; - } - } - break; - case certUsageSSLServerWithStepUp: - /* XXX - step up certs can't be directly trusted, only distrust */ - flags = trust.sslFlags; - if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is - * authoritative */ - if (( flags & CERTDB_TRUSTED ) == 0) { - /* don't trust this cert */ - *failedFlags = flags; - return SECFailure; - } - } - break; - case certUsageSSLCA: - flags = trust.sslFlags; - if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is - * authoritative */ - if (( flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA) ) == 0) { - /* don't trust this cert */ - *failedFlags = flags; - return SECFailure; - } - } - break; - case certUsageEmailSigner: - case certUsageEmailRecipient: - flags = trust.emailFlags; - if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is - * authoritative */ - if ( flags & CERTDB_TRUSTED ) { /* trust this cert */ - *trusted = PR_TRUE; - return SECSuccess; - } - else { /* don't trust this cert */ - *failedFlags = flags; - return SECFailure; - } - } - - break; - case certUsageObjectSigner: - flags = trust.objectSigningFlags; - - if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is - * authoritative */ - if ( flags & CERTDB_TRUSTED ) { /* trust this cert */ - *trusted = PR_TRUE; - return SECSuccess; - } else { /* don't trust this cert */ - *failedFlags = flags; - return SECFailure; - } - } - break; - case certUsageVerifyCA: - case certUsageStatusResponder: - flags = trust.sslFlags; - /* is the cert directly trusted or not trusted ? */ - if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) == - ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) { - *trusted = PR_TRUE; - return SECSuccess; - } - flags = trust.emailFlags; - /* is the cert directly trusted or not trusted ? */ - if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) == - ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) { - *trusted = PR_TRUE; - return SECSuccess; - } - flags = trust.objectSigningFlags; - /* is the cert directly trusted or not trusted ? */ - if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) == - ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) { - *trusted = PR_TRUE; - return SECSuccess; - } - /* fall through to test distrust */ - case certUsageAnyCA: - case certUsageUserCertImport: - /* do we distrust these certs explicitly */ - flags = trust.sslFlags; - if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is - * authoritative */ - if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) { - *failedFlags = flags; - return SECFailure; - } - } - flags = trust.emailFlags; - if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is - * authoritative */ - if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) { - *failedFlags = flags; - return SECFailure; - } - } - /* fall through */ - case certUsageProtectedObjectSigner: - flags = trust.objectSigningFlags; - if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is - * authoritative */ - if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) { - *failedFlags = flags; - return SECFailure; - } - } - break; - } + if (CERT_GetCertTrust(cert, &trust) == SECSuccess) { + switch (certUsage) { + case certUsageSSLClient: + case certUsageSSLServer: + 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; + } else { /* don't trust this cert */ + *failedFlags = flags; + return SECFailure; + } + } + break; + case certUsageSSLServerWithStepUp: + /* XXX - step up certs can't be directly trusted, only distrust */ + flags = trust.sslFlags; + if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is + * authoritative */ + if ((flags & CERTDB_TRUSTED) == 0) { + /* don't trust this cert */ + *failedFlags = flags; + return SECFailure; + } + } + break; + case certUsageSSLCA: + flags = trust.sslFlags; + if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is + * authoritative */ + if ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0) { + /* don't trust this cert */ + *failedFlags = flags; + return SECFailure; + } + } + break; + case certUsageEmailSigner: + case certUsageEmailRecipient: + flags = trust.emailFlags; + if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is + * authoritative */ + if (flags & CERTDB_TRUSTED) { /* trust this cert */ + *trusted = PR_TRUE; + return SECSuccess; + } else { /* don't trust this cert */ + *failedFlags = flags; + return SECFailure; + } + } + + break; + case certUsageObjectSigner: + flags = trust.objectSigningFlags; + + if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is + * authoritative */ + if (flags & CERTDB_TRUSTED) { /* trust this cert */ + *trusted = PR_TRUE; + return SECSuccess; + } else { /* don't trust this cert */ + *failedFlags = flags; + return SECFailure; + } + } + break; + case certUsageVerifyCA: + case certUsageStatusResponder: + flags = trust.sslFlags; + /* is the cert directly trusted or not trusted ? */ + if ((flags & (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) == + (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) { + *trusted = PR_TRUE; + return SECSuccess; + } + flags = trust.emailFlags; + /* is the cert directly trusted or not trusted ? */ + if ((flags & (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) == + (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) { + *trusted = PR_TRUE; + return SECSuccess; + } + flags = trust.objectSigningFlags; + /* is the cert directly trusted or not trusted ? */ + if ((flags & (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) == + (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) { + *trusted = PR_TRUE; + return SECSuccess; + } + /* fall through to test distrust */ + case certUsageAnyCA: + case certUsageUserCertImport: + /* do we distrust these certs explicitly */ + flags = trust.sslFlags; + if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is + * authoritative */ + if ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0) { + *failedFlags = flags; + return SECFailure; + } + } + flags = trust.emailFlags; + if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is + * authoritative */ + if ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0) { + *failedFlags = flags; + return SECFailure; + } + } + /* fall through */ + case certUsageProtectedObjectSigner: + flags = trust.objectSigningFlags; + if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is + * authoritative */ + if ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0) { + *failedFlags = flags; + return SECFailure; + } + } + break; + } } return SECSuccess; } @@ -1161,8 +1310,8 @@ cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage, */ SECStatus CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertificateUsage requiredUsages, PRTime t, - void *wincx, CERTVerifyLog *log, SECCertificateUsage* returnedUsages) + PRBool checkSig, SECCertificateUsage requiredUsages, PRTime t, + void *wincx, CERTVerifyLog *log, SECCertificateUsage *returnedUsages) { SECStatus rv; SECStatus valid; @@ -1170,7 +1319,7 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, unsigned int requiredCertType; unsigned int flags; unsigned int certType; - PRBool allowOverride; + PRBool allowOverride; SECCertTimeValidity validity; CERTStatusConfig *statusConfig; PRInt32 i; @@ -1194,23 +1343,23 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, so we can skip checks for usages that aren't required */ checkAllUsages = PR_FALSE; } - valid = SECSuccess ; /* start off assuming cert is valid */ - + valid = SECSuccess; /* start off assuming cert is valid */ + /* make sure that the cert is valid at time t */ allowOverride = (PRBool)((requiredUsages & certificateUsageSSLServer) || (requiredUsages & certificateUsageSSLServerWithStepUp)); validity = CERT_CheckCertValidTimes(cert, t, allowOverride); - if ( validity != secCertTimeValid ) { + if (validity != secCertTimeValid) { valid = SECFailure; - LOG_ERROR_OR_EXIT(log,cert,0,validity); + 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) ; ) { + for (i = 1; i <= certificateUsageHighest && + (SECSuccess == valid || returnedUsages || log);) { PRBool requiredUsage = (i & requiredUsages) ? PR_TRUE : PR_FALSE; if (PR_FALSE == requiredUsage && PR_FALSE == checkAllUsages) { NEXT_USAGE(); @@ -1218,74 +1367,74 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, 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: - rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE, - &requiredKeyUsage, - &requiredCertType); - if ( rv != SECSuccess ) { + switch (certUsage) { + case certUsageSSLClient: + case certUsageSSLServer: + case certUsageSSLServerWithStepUp: + case certUsageSSLCA: + case certUsageEmailSigner: + case certUsageEmailRecipient: + case certUsageObjectSigner: + case certUsageStatusResponder: + rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE, + &requiredKeyUsage, + &requiredCertType); + if (rv != SECSuccess) { + PORT_Assert(0); + /* EXIT_IF_NOT_LOGGING(log); XXX ??? */ + requiredKeyUsage = 0; + requiredCertType = 0; + INVALID_USAGE(); + } + break; + + case certUsageAnyCA: + case certUsageProtectedObjectSigner: + case certUsageUserCertImport: + case certUsageVerifyCA: + /* these usages cannot be verified */ + NEXT_USAGE(); + + default: PORT_Assert(0); - /* EXIT_IF_NOT_LOGGING(log); XXX ??? */ requiredKeyUsage = 0; requiredCertType = 0; INVALID_USAGE(); - } - break; - - case certUsageAnyCA: - case certUsageProtectedObjectSigner: - case certUsageUserCertImport: - case certUsageVerifyCA: - /* these usages cannot be verified */ - NEXT_USAGE(); - - default: - PORT_Assert(0); - requiredKeyUsage = 0; - requiredCertType = 0; - INVALID_USAGE(); } - if ( CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess ) { + if (CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess) { if (PR_TRUE == requiredUsage) { PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); } - LOG_ERROR(log,cert,0,requiredKeyUsage); + LOG_ERROR(log, cert, 0, requiredKeyUsage); INVALID_USAGE(); } - if ( !( certType & requiredCertType ) ) { + if (!(certType & requiredCertType)) { if (PR_TRUE == requiredUsage) { PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE); } - LOG_ERROR(log,cert,0,requiredCertType); + LOG_ERROR(log, cert, 0, requiredCertType); INVALID_USAGE(); } - rv = cert_CheckLeafTrust(cert, certUsage, &flags, &trusted); - if (rv == SECFailure) { - if (PR_TRUE == requiredUsage) { - PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); - } - LOG_ERROR(log, cert, 0, flags); - INVALID_USAGE(); - } else if (trusted) { - VALID_USAGE(); - } - - if (PR_TRUE == revoked || PR_TRUE == sigerror) { - INVALID_USAGE(); - } + rv = cert_CheckLeafTrust(cert, certUsage, &flags, &trusted); + if (rv == SECFailure) { + if (PR_TRUE == requiredUsage) { + PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); + } + LOG_ERROR(log, cert, 0, flags); + INVALID_USAGE(); + } else if (trusted) { + VALID_USAGE(); + } + + if (PR_TRUE == revoked || PR_TRUE == sigerror) { + INVALID_USAGE(); + } rv = cert_VerifyCertChain(handle, cert, - checkSig, &sigerror, - certUsage, t, wincx, log, - &revoked); + checkSig, &sigerror, + certUsage, t, wincx, log, + &revoked); if (rv != SECSuccess) { /* EXIT_IF_NOT_LOGGING(log); XXX ???? */ @@ -1306,10 +1455,10 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, if (requiredUsages != certificateUsageStatusResponder && statusConfig != NULL) { if (statusConfig->statusChecker != NULL) { - rv = (* statusConfig->statusChecker)(handle, cert, - t, wincx); + rv = (*statusConfig->statusChecker)(handle, cert, + t, wincx); if (rv != SECSuccess) { - LOG_ERROR(log,cert,0,0); + LOG_ERROR(log, cert, 0, 0); revoked = PR_TRUE; INVALID_USAGE(); } @@ -1319,15 +1468,15 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, NEXT_USAGE(); } - + loser: - return(valid); + return (valid); } SECStatus CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertUsage certUsage, PRTime t, - void *wincx, CERTVerifyLog *log) + PRBool checkSig, SECCertUsage certUsage, PRTime t, + void *wincx, CERTVerifyLog *log) { return cert_VerifyCertWithFlags(handle, cert, checkSig, certUsage, t, CERT_VERIFYCERT_USE_DEFAULTS, wincx, log); @@ -1343,86 +1492,85 @@ cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert, unsigned int requiredCertType; unsigned int failedFlags; unsigned int certType; - PRBool trusted; - PRBool allowOverride; + PRBool trusted; + PRBool allowOverride; SECCertTimeValidity validity; CERTStatusConfig *statusConfig; - -#ifdef notdef + +#ifdef notdef /* check if this cert is in the Evil list */ rv = CERT_CheckForEvilCert(cert); - if ( rv != SECSuccess ) { - PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); - LOG_ERROR_OR_EXIT(log,cert,0,0); + 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)); validity = CERT_CheckCertValidTimes(cert, t, allowOverride); - if ( validity != secCertTimeValid ) { - LOG_ERROR_OR_EXIT(log,cert,0,validity); + 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 certUsageSSLCA: - case certUsageEmailSigner: - case certUsageEmailRecipient: - case certUsageObjectSigner: - case certUsageStatusResponder: - rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE, - &requiredKeyUsage, - &requiredCertType); - if ( rv != SECSuccess ) { - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - requiredKeyUsage = 0; - requiredCertType = 0; - } - break; - case certUsageVerifyCA: - case certUsageAnyCA: - requiredKeyUsage = KU_KEY_CERT_SIGN; - requiredCertType = NS_CERT_TYPE_CA; - if ( ! ( certType & NS_CERT_TYPE_CA ) ) { - certType |= NS_CERT_TYPE_CA; - } - break; - default: - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - requiredKeyUsage = 0; - requiredCertType = 0; - } - if ( CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess ) { - PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); - LOG_ERROR_OR_EXIT(log,cert,0,requiredKeyUsage); - } - if ( !( certType & requiredCertType ) ) { - PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE); - LOG_ERROR_OR_EXIT(log,cert,0,requiredCertType); + switch (certUsage) { + case certUsageSSLClient: + case certUsageSSLServer: + case certUsageSSLServerWithStepUp: + case certUsageSSLCA: + case certUsageEmailSigner: + case certUsageEmailRecipient: + case certUsageObjectSigner: + case certUsageStatusResponder: + rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE, + &requiredKeyUsage, + &requiredCertType); + if (rv != SECSuccess) { + PORT_Assert(0); + EXIT_IF_NOT_LOGGING(log); + requiredKeyUsage = 0; + requiredCertType = 0; + } + break; + case certUsageVerifyCA: + case certUsageAnyCA: + requiredKeyUsage = KU_KEY_CERT_SIGN; + requiredCertType = NS_CERT_TYPE_CA; + if (!(certType & NS_CERT_TYPE_CA)) { + certType |= NS_CERT_TYPE_CA; + } + break; + default: + PORT_Assert(0); + EXIT_IF_NOT_LOGGING(log); + requiredKeyUsage = 0; + requiredCertType = 0; + } + if (CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess) { + PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); + LOG_ERROR_OR_EXIT(log, cert, 0, requiredKeyUsage); + } + if (!(certType & requiredCertType)) { + PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE); + LOG_ERROR_OR_EXIT(log, cert, 0, requiredCertType); } rv = cert_CheckLeafTrust(cert, certUsage, &failedFlags, &trusted); - if (rv == SECFailure) { - PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); - LOG_ERROR_OR_EXIT(log, cert, 0, failedFlags); + if (rv == SECFailure) { + PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); + LOG_ERROR_OR_EXIT(log, cert, 0, failedFlags); } else if (trusted) { - goto done; + goto done; } - rv = CERT_VerifyCertChain(handle, cert, checkSig, certUsage, - t, wincx, log); + t, wincx, log); if (rv != SECSuccess) { - EXIT_IF_NOT_LOGGING(log); + EXIT_IF_NOT_LOGGING(log); } /* @@ -1434,27 +1582,27 @@ cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert, * code. */ if (!(flags & CERT_VERIFYCERT_SKIP_OCSP) && - certUsage != certUsageStatusResponder) { - statusConfig = CERT_GetStatusConfig(handle); - if (statusConfig && statusConfig->statusChecker) { - rv = (* statusConfig->statusChecker)(handle, cert, - t, wincx); - if (rv != SECSuccess) { - LOG_ERROR_OR_EXIT(log,cert,0,0); - } - } + certUsage != certUsageStatusResponder) { + statusConfig = CERT_GetStatusConfig(handle); + if (statusConfig && statusConfig->statusChecker) { + rv = (*statusConfig->statusChecker)(handle, cert, + t, wincx); + if (rv != SECSuccess) { + LOG_ERROR_OR_EXIT(log, cert, 0, 0); + } + } } done: if (log && log->head) { - return SECFailure; + return SECFailure; } - return(SECSuccess); + return (SECSuccess); loser: rv = SECFailure; - - return(rv); + + return (rv); } /* @@ -1463,38 +1611,37 @@ loser: */ SECStatus CERT_VerifyCertificateNow(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertificateUsage requiredUsages, - void *wincx, SECCertificateUsage* returnedUsages) + PRBool checkSig, SECCertificateUsage requiredUsages, + void *wincx, SECCertificateUsage *returnedUsages) { - return(CERT_VerifyCertificate(handle, cert, checkSig, - requiredUsages, PR_Now(), wincx, NULL, returnedUsages)); + return (CERT_VerifyCertificate(handle, cert, checkSig, + requiredUsages, PR_Now(), wincx, NULL, returnedUsages)); } /* obsolete, do not use for new code */ SECStatus CERT_VerifyCertNow(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertUsage certUsage, void *wincx) + PRBool checkSig, SECCertUsage certUsage, void *wincx) { - return(CERT_VerifyCert(handle, cert, checkSig, - certUsage, PR_Now(), wincx, NULL)); + return (CERT_VerifyCert(handle, cert, checkSig, + certUsage, PR_Now(), wincx, NULL)); } - /* [ FROM pcertdb.c ] */ /* * Supported usage values and types: - * certUsageSSLClient - * certUsageSSLServer - * certUsageSSLServerWithStepUp - * certUsageEmailSigner - * certUsageEmailRecipient - * certUsageObjectSigner + * certUsageSSLClient + * certUsageSSLServer + * certUsageSSLServerWithStepUp + * certUsageEmailSigner + * certUsageEmailRecipient + * certUsageObjectSigner */ CERTCertificate * CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName, - CERTCertOwner owner, SECCertUsage usage, - PRBool preferTrusted, PRTime validTime, PRBool validOnly) + CERTCertOwner owner, SECCertUsage usage, + PRBool preferTrusted, PRTime validTime, PRBool validOnly) { CERTCertList *certList = NULL; CERTCertificate *cert = NULL; @@ -1502,108 +1649,107 @@ CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName, unsigned int requiredTrustFlags; SECTrustType requiredTrustType; unsigned int flags; - + PRBool lookingForCA = PR_FALSE; SECStatus rv; CERTCertListNode *node; CERTCertificate *saveUntrustedCA = NULL; - + /* if preferTrusted is set, must be a CA cert */ - PORT_Assert( ! ( preferTrusted && ( owner != certOwnerCA ) ) ); - - if ( owner == certOwnerCA ) { - lookingForCA = PR_TRUE; - if ( preferTrusted ) { - rv = CERT_TrustFlagsForCACertUsage(usage, &requiredTrustFlags, - &requiredTrustType); - if ( rv != SECSuccess ) { - goto loser; - } - requiredTrustFlags |= CERTDB_VALID_CA; - } + PORT_Assert(!(preferTrusted && (owner != certOwnerCA))); + + if (owner == certOwnerCA) { + lookingForCA = PR_TRUE; + if (preferTrusted) { + rv = CERT_TrustFlagsForCACertUsage(usage, &requiredTrustFlags, + &requiredTrustType); + if (rv != SECSuccess) { + goto loser; + } + requiredTrustFlags |= CERTDB_VALID_CA; + } } certList = CERT_CreateSubjectCertList(NULL, handle, derName, validTime, - validOnly); - if ( certList != NULL ) { - rv = CERT_FilterCertListByUsage(certList, usage, lookingForCA); - if ( rv != SECSuccess ) { - goto loser; - } - - node = CERT_LIST_HEAD(certList); - - while ( !CERT_LIST_END(node, certList) ) { - cert = node->cert; - - /* looking for a trusted CA cert */ - if ( ( owner == certOwnerCA ) && preferTrusted && - ( requiredTrustType != trustTypeNone ) ) { - - if ( CERT_GetCertTrust(cert, &certTrust) != SECSuccess ) { - flags = 0; - } else { - flags = SEC_GET_TRUST_FLAGS(&certTrust, requiredTrustType); - } - - if ( ( flags & requiredTrustFlags ) != requiredTrustFlags ) { - /* cert is not trusted */ - /* if this is the first cert to get this far, then save - * it, so we can use it if we can't find a trusted one - */ - if ( saveUntrustedCA == NULL ) { - saveUntrustedCA = cert; - } - goto endloop; - } - } - /* if we got this far, then this cert meets all criteria */ - break; - -endloop: - node = CERT_LIST_NEXT(node); - cert = NULL; - } - - /* use the saved one if we have it */ - if ( cert == NULL ) { - cert = saveUntrustedCA; - } - - /* if we found one then bump the ref count before freeing the list */ - if ( cert != NULL ) { - /* bump the ref count */ - cert = CERT_DupCertificate(cert); - } - - CERT_DestroyCertList(certList); - } - - return(cert); + validOnly); + if (certList != NULL) { + rv = CERT_FilterCertListByUsage(certList, usage, lookingForCA); + if (rv != SECSuccess) { + goto loser; + } + + node = CERT_LIST_HEAD(certList); + + while (!CERT_LIST_END(node, certList)) { + cert = node->cert; + + /* looking for a trusted CA cert */ + if ((owner == certOwnerCA) && preferTrusted && + (requiredTrustType != trustTypeNone)) { + + if (CERT_GetCertTrust(cert, &certTrust) != SECSuccess) { + flags = 0; + } else { + flags = SEC_GET_TRUST_FLAGS(&certTrust, requiredTrustType); + } + + if ((flags & requiredTrustFlags) != requiredTrustFlags) { + /* cert is not trusted */ + /* if this is the first cert to get this far, then save + * it, so we can use it if we can't find a trusted one + */ + if (saveUntrustedCA == NULL) { + saveUntrustedCA = cert; + } + goto endloop; + } + } + /* if we got this far, then this cert meets all criteria */ + break; + + endloop: + node = CERT_LIST_NEXT(node); + cert = NULL; + } + + /* use the saved one if we have it */ + if (cert == NULL) { + cert = saveUntrustedCA; + } + + /* if we found one then bump the ref count before freeing the list */ + if (cert != NULL) { + /* bump the ref count */ + cert = CERT_DupCertificate(cert); + } + + CERT_DestroyCertList(certList); + } + + return (cert); loser: - if ( certList != NULL ) { - CERT_DestroyCertList(certList); + if (certList != NULL) { + CERT_DestroyCertList(certList); } - return(NULL); + return (NULL); } - /* [ From certdb.c ] */ /* * Filter a list of certificates, removing those certs that do not have * one of the named CA certs somewhere in their cert chain. * - * "certList" - the list of certificates to filter - * "nCANames" - number of CA names - * "caNames" - array of CA names in string(rfc 1485) form - * "usage" - what use the certs are for, this is used when - * selecting CA certs + * "certList" - the list of certificates to filter + * "nCANames" - number of CA names + * "caNames" - array of CA names in string(rfc 1485) form + * "usage" - what use the certs are for, this is used when + * selecting CA certs */ SECStatus CERT_FilterCertListByCANames(CERTCertList *certList, int nCANames, - char **caNames, SECCertUsage usage) + char **caNames, SECCertUsage usage) { CERTCertificate *issuerCert = NULL; CERTCertificate *subjectCert; @@ -1613,65 +1759,64 @@ CERT_FilterCertListByCANames(CERTCertList *certList, int nCANames, char **names; PRBool found; PRTime time; - - if ( nCANames <= 0 ) { - return(SECSuccess); + + if (nCANames <= 0) { + return (SECSuccess); } time = PR_Now(); - + node = CERT_LIST_HEAD(certList); - - while ( ! CERT_LIST_END(node, certList) ) { - cert = node->cert; - - subjectCert = CERT_DupCertificate(cert); - - /* traverse the CA certs for this cert */ - found = PR_FALSE; - while ( subjectCert != NULL ) { - n = nCANames; - names = caNames; - - if (subjectCert->issuerName != NULL) { - while ( n > 0 ) { - if ( PORT_Strcmp(*names, subjectCert->issuerName) == 0 ) { - found = PR_TRUE; - break; - } - - n--; - names++; + + while (!CERT_LIST_END(node, certList)) { + cert = node->cert; + + subjectCert = CERT_DupCertificate(cert); + + /* traverse the CA certs for this cert */ + found = PR_FALSE; + while (subjectCert != NULL) { + n = nCANames; + names = caNames; + + if (subjectCert->issuerName != NULL) { + while (n > 0) { + if (PORT_Strcmp(*names, subjectCert->issuerName) == 0) { + found = PR_TRUE; + break; + } + + n--; + names++; } - } - - if ( found ) { - break; - } - - issuerCert = CERT_FindCertIssuer(subjectCert, time, usage); - if ( issuerCert == subjectCert ) { - CERT_DestroyCertificate(issuerCert); - issuerCert = NULL; - break; - } - CERT_DestroyCertificate(subjectCert); - subjectCert = issuerCert; - - } - CERT_DestroyCertificate(subjectCert); - if ( !found ) { - /* CA was not found, so remove this cert from the list */ - freenode = node; - node = CERT_LIST_NEXT(node); - CERT_RemoveCertListNode(freenode); - } else { - /* CA was found, so leave it in the list */ - node = CERT_LIST_NEXT(node); - } - } - - return(SECSuccess); + } + + if (found) { + break; + } + + issuerCert = CERT_FindCertIssuer(subjectCert, time, usage); + if (issuerCert == subjectCert) { + CERT_DestroyCertificate(issuerCert); + issuerCert = NULL; + break; + } + CERT_DestroyCertificate(subjectCert); + subjectCert = issuerCert; + } + CERT_DestroyCertificate(subjectCert); + if (!found) { + /* CA was not found, so remove this cert from the list */ + freenode = node; + node = CERT_LIST_NEXT(node); + CERT_RemoveCertListNode(freenode); + } else { + /* CA was found, so leave it in the list */ + node = CERT_LIST_NEXT(node); + } + } + + return (SECSuccess); } /* @@ -1680,70 +1825,70 @@ CERT_FilterCertListByCANames(CERTCertList *certList, int nCANames, * certificate. * * "arena" - arena to allocate returned string from. If NULL, then heap - * is used. + * is used. * "cert" - the cert to get nickname from * "expiredString" - the string to append to the nickname if the cert is - * expired. + * expired. * "notYetGoodString" - the string to append to the nickname if the cert is - * not yet good. + * not yet good. */ char * CERT_GetCertNicknameWithValidity(PLArenaPool *arena, CERTCertificate *cert, - char *expiredString, char *notYetGoodString) + char *expiredString, char *notYetGoodString) { SECCertTimeValidity validity; char *nickname = NULL, *tmpstr = NULL; - + validity = CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE); /* if the cert is good, then just use the nickname directly */ - if ( validity == secCertTimeValid ) { - if ( arena == NULL ) { - nickname = PORT_Strdup(cert->nickname); - } else { - nickname = PORT_ArenaStrdup(arena, cert->nickname); - } - - if ( nickname == NULL ) { - goto loser; - } + if (validity == secCertTimeValid) { + if (arena == NULL) { + nickname = PORT_Strdup(cert->nickname); + } else { + nickname = PORT_ArenaStrdup(arena, cert->nickname); + } + + if (nickname == NULL) { + goto loser; + } } else { - - /* if the cert is not valid, then tack one of the strings on the - * end - */ - if ( validity == secCertTimeExpired ) { - tmpstr = PR_smprintf("%s%s", cert->nickname, - expiredString); - } else if ( validity == secCertTimeNotValidYet ) { - /* not yet valid */ - tmpstr = PR_smprintf("%s%s", cert->nickname, - notYetGoodString); + + /* if the cert is not valid, then tack one of the strings on the + * end + */ + if (validity == secCertTimeExpired) { + tmpstr = PR_smprintf("%s%s", cert->nickname, + expiredString); + } else if (validity == secCertTimeNotValidYet) { + /* not yet valid */ + tmpstr = PR_smprintf("%s%s", cert->nickname, + notYetGoodString); } else { /* undetermined */ - tmpstr = PR_smprintf("%s", - "(NULL) (Validity Unknown)"); + tmpstr = PR_smprintf("%s", + "(NULL) (Validity Unknown)"); } - if ( tmpstr == NULL ) { - goto loser; - } - - if ( arena ) { - /* copy the string into the arena and free the malloc'd one */ - nickname = PORT_ArenaStrdup(arena, tmpstr); - PORT_Free(tmpstr); - } else { - nickname = tmpstr; - } - if ( nickname == NULL ) { - goto loser; - } - } - return(nickname); + if (tmpstr == NULL) { + goto loser; + } + + if (arena) { + /* copy the string into the arena and free the malloc'd one */ + nickname = PORT_ArenaStrdup(arena, tmpstr); + PORT_Free(tmpstr); + } else { + nickname = tmpstr; + } + if (nickname == NULL) { + goto loser; + } + } + return (nickname); loser: - return(NULL); + return (NULL); } /* @@ -1753,27 +1898,27 @@ loser: * "certList" - the list of certificates * "expiredString" - the string to append to the nickname of any expired cert * "notYetGoodString" - the string to append to the nickname of any cert - * that is not yet valid + * that is not yet valid */ CERTCertNicknames * CERT_NicknameStringsFromCertList(CERTCertList *certList, char *expiredString, - char *notYetGoodString) + char *notYetGoodString) { CERTCertNicknames *names; PLArenaPool *arena; CERTCertListNode *node; char **nn; - + /* allocate an arena */ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - return(NULL); + if (arena == NULL) { + return (NULL); } - + /* allocate the structure */ names = PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames)); - if ( names == NULL ) { - goto loser; + if (names == NULL) { + goto loser; } /* init the structure */ @@ -1785,49 +1930,49 @@ CERT_NicknameStringsFromCertList(CERTCertList *certList, char *expiredString, /* count the certs in the list */ node = CERT_LIST_HEAD(certList); - while ( ! CERT_LIST_END(node, certList) ) { - names->numnicknames++; - node = CERT_LIST_NEXT(node); + while (!CERT_LIST_END(node, certList)) { + names->numnicknames++; + node = CERT_LIST_NEXT(node); } - + /* allocate nicknames array */ names->nicknames = PORT_ArenaAlloc(arena, - sizeof(char *) * names->numnicknames); - if ( names->nicknames == NULL ) { - goto loser; + sizeof(char *) * names->numnicknames); + if (names->nicknames == NULL) { + goto loser; } /* just in case printf can't deal with null strings */ - if (expiredString == NULL ) { - expiredString = ""; + if (expiredString == NULL) { + expiredString = ""; } - if ( notYetGoodString == NULL ) { - notYetGoodString = ""; + if (notYetGoodString == NULL) { + notYetGoodString = ""; } - + /* traverse the list of certs and collect the nicknames */ nn = names->nicknames; node = CERT_LIST_HEAD(certList); - while ( ! CERT_LIST_END(node, certList) ) { - *nn = CERT_GetCertNicknameWithValidity(arena, node->cert, - expiredString, - notYetGoodString); - if ( *nn == NULL ) { - goto loser; - } + while (!CERT_LIST_END(node, certList)) { + *nn = CERT_GetCertNicknameWithValidity(arena, node->cert, + expiredString, + notYetGoodString); + if (*nn == NULL) { + goto loser; + } - names->totallen += PORT_Strlen(*nn); - - nn++; - node = CERT_LIST_NEXT(node); + names->totallen += PORT_Strlen(*nn); + + nn++; + node = CERT_LIST_NEXT(node); } - return(names); + return (names); loser: PORT_FreeArena(arena, PR_FALSE); - return(NULL); + return (NULL); } /* @@ -1835,63 +1980,63 @@ loser: * expiredString or notYetGoodString appended. * * Args: - * "namestring" - the string containing the nickname, and possibly - * one of the validity label strings - * "expiredString" - the expired validity label string - * "notYetGoodString" - the not yet good validity label string + * "namestring" - the string containing the nickname, and possibly + * one of the validity label strings + * "expiredString" - the expired validity label string + * "notYetGoodString" - the not yet good validity label string * * Returns the raw nickname */ char * CERT_ExtractNicknameString(char *namestring, char *expiredString, - char *notYetGoodString) + char *notYetGoodString) { int explen, nyglen, namelen; int retlen; char *retstr; - + namelen = PORT_Strlen(namestring); explen = PORT_Strlen(expiredString); nyglen = PORT_Strlen(notYetGoodString); - - if ( namelen > explen ) { - if ( PORT_Strcmp(expiredString, &namestring[namelen-explen]) == 0 ) { - retlen = namelen - explen; - retstr = (char *)PORT_Alloc(retlen+1); - if ( retstr == NULL ) { - goto loser; - } - - PORT_Memcpy(retstr, namestring, retlen); - retstr[retlen] = '\0'; - goto done; - } - } - - if ( namelen > nyglen ) { - if ( PORT_Strcmp(notYetGoodString, &namestring[namelen-nyglen]) == 0) { - retlen = namelen - nyglen; - retstr = (char *)PORT_Alloc(retlen+1); - if ( retstr == NULL ) { - goto loser; - } - - PORT_Memcpy(retstr, namestring, retlen); - retstr[retlen] = '\0'; - goto done; - } + + if (namelen > explen) { + if (PORT_Strcmp(expiredString, &namestring[namelen - explen]) == 0) { + retlen = namelen - explen; + retstr = (char *)PORT_Alloc(retlen + 1); + if (retstr == NULL) { + goto loser; + } + + PORT_Memcpy(retstr, namestring, retlen); + retstr[retlen] = '\0'; + goto done; + } + } + + if (namelen > nyglen) { + if (PORT_Strcmp(notYetGoodString, &namestring[namelen - nyglen]) == 0) { + retlen = namelen - nyglen; + retstr = (char *)PORT_Alloc(retlen + 1); + if (retstr == NULL) { + goto loser; + } + + PORT_Memcpy(retstr, namestring, retlen); + retstr[retlen] = '\0'; + goto done; + } } /* if name string is shorter than either invalid string, then it must * be a raw nickname */ retstr = PORT_Strdup(namestring); - + done: - return(retstr); + return (retstr); loser: - return(NULL); + return (NULL); } CERTCertList * @@ -1903,7 +2048,7 @@ CERT_GetCertChainFromCert(CERTCertificate *cert, PRTime time, SECCertUsage usage if (NULL == cert) { return NULL; } - + cert = CERT_DupCertificate(cert); if (NULL == cert) { PORT_SetError(SEC_ERROR_NO_MEMORY); @@ -1917,18 +2062,18 @@ CERT_GetCertChainFromCert(CERTCertificate *cert, PRTime time, SECCertUsage usage } while (cert != NULL && ++count <= CERT_MAX_CERT_CHAIN) { - if (SECSuccess != CERT_AddCertToListTail(chain, cert)) { + if (SECSuccess != CERT_AddCertToListTail(chain, cert)) { /* return partial chain */ PORT_SetError(SEC_ERROR_NO_MEMORY); return chain; } - if (cert->isRoot) { + if (cert->isRoot) { /* return complete chain */ - return chain; - } + return chain; + } - cert = CERT_FindCertIssuer(cert, time, usage); + cert = CERT_FindCertIssuer(cert, time, usage); } /* return partial chain */ |