| OLD | NEW | 
|---|
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public | 
| 2  * License, v. 2.0. If a copy of the MPL was not distributed with this | 2  * License, v. 2.0. If a copy of the MPL was not distributed with this | 
| 3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 
| 4 #include "nspr.h" | 4 #include "nspr.h" | 
| 5 #include "secerr.h" | 5 #include "secerr.h" | 
| 6 #include "secport.h" | 6 #include "secport.h" | 
| 7 #include "seccomon.h" | 7 #include "seccomon.h" | 
| 8 #include "secoid.h" | 8 #include "secoid.h" | 
| 9 #include "genname.h" | 9 #include "genname.h" | 
| 10 #include "keyhi.h" | 10 #include "keyhi.h" | 
| 11 #include "cert.h" | 11 #include "cert.h" | 
| 12 #include "certdb.h" | 12 #include "certdb.h" | 
| 13 #include "certi.h" | 13 #include "certi.h" | 
| 14 #include "cryptohi.h" | 14 #include "cryptohi.h" | 
| 15 #ifndef NSS_DISABLE_LIBPKIX | 15 #ifndef NSS_DISABLE_LIBPKIX | 
| 16 #include "pkix.h" | 16 #include "pkix.h" | 
| 17 /*#include "pkix_sample_modules.h" */ | 17 /*#include "pkix_sample_modules.h" */ | 
| 18 #include "pkix_pl_cert.h" | 18 #include "pkix_pl_cert.h" | 
| 19 #endif  /* NSS_DISABLE_LIBPKIX */ | 19 #endif  /* NSS_DISABLE_LIBPKIX */ | 
| 20 | 20 | 
| 21 |  | 
| 22 #include "nsspki.h" | 21 #include "nsspki.h" | 
| 23 #include "pkitm.h" | 22 #include "pkitm.h" | 
| 24 #include "pkim.h" | 23 #include "pkim.h" | 
| 25 #include "pki3hack.h" | 24 #include "pki3hack.h" | 
| 26 #include "base.h" | 25 #include "base.h" | 
| 27 #include "keyhi.h" | 26 #include "keyhi.h" | 
| 28 | 27 | 
| 29 #ifdef NSS_DISABLE_LIBPKIX | 28 #ifdef NSS_DISABLE_LIBPKIX | 
| 30 SECStatus | 29 SECStatus | 
| 31 cert_VerifyCertChainPkix( | 30 cert_VerifyCertChainPkix( | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 70 /* | 69 /* | 
| 71  * Check the validity times of a certificate | 70  * Check the validity times of a certificate | 
| 72  */ | 71  */ | 
| 73 SECStatus | 72 SECStatus | 
| 74 CERT_CertTimesValid(CERTCertificate *c) | 73 CERT_CertTimesValid(CERTCertificate *c) | 
| 75 { | 74 { | 
| 76     SECCertTimeValidity valid = CERT_CheckCertValidTimes(c, PR_Now(), PR_TRUE); | 75     SECCertTimeValidity valid = CERT_CheckCertValidTimes(c, PR_Now(), PR_TRUE); | 
| 77     return (valid == secCertTimeValid) ? SECSuccess : SECFailure; | 76     return (valid == secCertTimeValid) ? SECSuccess : SECFailure; | 
| 78 } | 77 } | 
| 79 | 78 | 
| 80 SECStatus checkKeyParams(const SECAlgorithmID *sigAlgorithm, const SECKEYPublicK
      ey *key) | 79 SECStatus | 
|  | 80 checkKeyParams(const SECAlgorithmID *sigAlgorithm, const SECKEYPublicKey *key) | 
| 81 { | 81 { | 
| 82     SECStatus        rv; | 82     SECStatus rv; | 
| 83     SECOidTag sigAlg; | 83     SECOidTag sigAlg; | 
| 84     SECOidTag curve; | 84     SECOidTag curve; | 
| 85     PRUint32 policyFlags = 0; | 85     PRUint32 policyFlags = 0; | 
| 86     PRInt32 minLen, len; | 86     PRInt32 minLen, len; | 
| 87 | 87 | 
| 88     sigAlg = SECOID_GetAlgorithmTag(sigAlgorithm); | 88     sigAlg = SECOID_GetAlgorithmTag(sigAlgorithm); | 
| 89 | 89 | 
| 90     switch(sigAlg) { | 90     switch (sigAlg) { | 
| 91         case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: | 91         case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: | 
| 92 »       case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: | 92         case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: | 
| 93 »       case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: | 93         case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: | 
| 94 »       case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: | 94         case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: | 
| 95 »       case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: | 95         case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: | 
| 96 »           if (key->keyType != ecKey) { | 96             if (key->keyType != ecKey) { | 
| 97 »       »       PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | 97                 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | 
| 98 »       »       return SECFailure; | 98                 return SECFailure; | 
| 99 »           } | 99             } | 
| 100 | 100 | 
| 101             curve = SECKEY_GetECCOid(&key->u.ec.DEREncodedParams); | 101             curve = SECKEY_GetECCOid(&key->u.ec.DEREncodedParams); | 
| 102 »           if (curve != 0) { | 102             if (curve != 0) { | 
| 103 »               if (NSS_GetAlgorithmPolicy(curve, &policyFlags) == SECFailure || | 103                 if (NSS_GetAlgorithmPolicy(curve, &policyFlags) == SECFailure || | 
| 104 »                   !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) { | 104                     !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) { | 
| 105 »                   PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); | 105                     PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); | 
| 106 »       »           return SECFailure; | 106                     return SECFailure; | 
| 107 »       »       } else { | 107                 } else { | 
| 108 »       »           return SECSuccess; | 108                     return SECSuccess; | 
| 109                 } | 109                 } | 
| 110             } else { | 110             } else { | 
| 111 »       »       PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); | 111                 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); | 
| 112 »       »       return SECFailure; | 112                 return SECFailure; | 
| 113 »           } | 113             } | 
| 114             return SECSuccess; | 114             return SECSuccess; | 
| 115 »       case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: | 115         case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: | 
| 116 »       case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: | 116         case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: | 
| 117 »       case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: | 117         case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: | 
| 118 »       case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: | 118         case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: | 
| 119 »       case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: | 119         case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: | 
| 120 »       case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: | 120         case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: | 
| 121 »       case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE: | 121         case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE: | 
| 122 »       case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE: | 122         case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE: | 
| 123 »           if (key->keyType != rsaKey && key->keyType != rsaPssKey) { | 123             if (key->keyType != rsaKey && key->keyType != rsaPssKey) { | 
| 124 »       »       PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | 124                 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | 
| 125 »       »       return SECFailure; | 125                 return SECFailure; | 
| 126 »           } | 126             } | 
| 127 | 127 | 
| 128             len = 8 * key->u.rsa.modulus.len; | 128             len = 8 * key->u.rsa.modulus.len; | 
| 129 | 129 | 
| 130             rv = NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &minLen); | 130             rv = NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &minLen); | 
| 131             if (rv != SECSuccess) { | 131             if (rv != SECSuccess) { | 
| 132                 return SECFailure; | 132                 return SECFailure; | 
| 133 »           } | 133             } | 
| 134 | 134 | 
| 135             if (len < minLen) { | 135             if (len < minLen) { | 
| 136                 return SECFailure; | 136                 return SECFailure; | 
| 137 »           } | 137             } | 
| 138 | 138 | 
| 139             return SECSuccess; | 139             return SECSuccess; | 
| 140 »       case SEC_OID_ANSIX9_DSA_SIGNATURE: | 140         case SEC_OID_ANSIX9_DSA_SIGNATURE: | 
| 141 »       case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: | 141         case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: | 
| 142 »       case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: | 142         case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: | 
| 143 »       case SEC_OID_SDN702_DSA_SIGNATURE: | 143         case SEC_OID_SDN702_DSA_SIGNATURE: | 
| 144 »       case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST: | 144         case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST: | 
| 145 »       case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST: | 145         case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST: | 
| 146 »           if (key->keyType != dsaKey) { | 146             if (key->keyType != dsaKey) { | 
| 147 »       »       PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | 147                 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | 
| 148 »       »       return SECFailure; | 148                 return SECFailure; | 
| 149 »           } | 149             } | 
| 150 | 150 | 
| 151             len = 8 * key->u.dsa.params.prime.len; | 151             len = 8 * key->u.dsa.params.prime.len; | 
| 152 | 152 | 
| 153             rv = NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &minLen); | 153             rv = NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &minLen); | 
| 154             if (rv != SECSuccess) { | 154             if (rv != SECSuccess) { | 
| 155                 return SECFailure; | 155                 return SECFailure; | 
| 156 »           } | 156             } | 
| 157 | 157 | 
| 158             if (len < minLen) { | 158             if (len < minLen) { | 
| 159                 return SECFailure; | 159                 return SECFailure; | 
| 160 »           } | 160             } | 
| 161 | 161 | 
| 162             return SECSuccess; | 162             return SECSuccess; | 
| 163 »       default: | 163         default: | 
| 164 »           return SECSuccess; | 164             return SECSuccess; | 
| 165     } | 165     } | 
| 166 } | 166 } | 
| 167 | 167 | 
| 168 /* | 168 /* | 
| 169  * verify the signature of a signed data object with the given DER publickey | 169  * verify the signature of a signed data object with the given DER publickey | 
| 170  */ | 170  */ | 
| 171 SECStatus | 171 SECStatus | 
| 172 CERT_VerifySignedDataWithPublicKey(const CERTSignedData *sd, | 172 CERT_VerifySignedDataWithPublicKey(const CERTSignedData *sd, | 
| 173                                    SECKEYPublicKey *pubKey, | 173                                    SECKEYPublicKey *pubKey, | 
| 174 »       »                          void *wincx) | 174                                    void *wincx) | 
| 175 { | 175 { | 
| 176     SECStatus        rv; | 176     SECStatus rv; | 
| 177     SECItem          sig; | 177     SECItem sig; | 
| 178     SECOidTag        hashAlg = SEC_OID_UNKNOWN; | 178     SECOidTag hashAlg = SEC_OID_UNKNOWN; | 
| 179 | 179 | 
| 180     if ( !pubKey || !sd ) { | 180     if (!pubKey || !sd) { | 
| 181 »       PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | 181         PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | 
| 182 »       return SECFailure; | 182         return SECFailure; | 
| 183     } | 183     } | 
| 184     /* check the signature */ | 184     /* check the signature */ | 
| 185     sig = sd->signature; | 185     sig = sd->signature; | 
| 186     /* convert sig->len from bit counts to byte count. */ | 186     /* convert sig->len from bit counts to byte count. */ | 
| 187     DER_ConvertBitString(&sig); | 187     DER_ConvertBitString(&sig); | 
| 188 | 188 | 
| 189     rv = VFY_VerifyDataWithAlgorithmID(sd->data.data, sd->data.len, pubKey, | 189     rv = VFY_VerifyDataWithAlgorithmID(sd->data.data, sd->data.len, pubKey, | 
| 190 »       »       »       &sig, &sd->signatureAlgorithm, &hashAlg, wincx); | 190                                        &sig, &sd->signatureAlgorithm, &hashAlg, 
      wincx); | 
| 191     if (rv == SECSuccess) { | 191     if (rv == SECSuccess) { | 
| 192         /* Are we honoring signatures for this algorithm?  */ | 192         /* Are we honoring signatures for this algorithm?  */ | 
| 193 »       PRUint32 policyFlags = 0; | 193         PRUint32 policyFlags = 0; | 
| 194 »       rv = checkKeyParams(&sd->signatureAlgorithm, pubKey); | 194         rv = checkKeyParams(&sd->signatureAlgorithm, pubKey); | 
| 195 »       if (rv != SECSuccess) { | 195         if (rv != SECSuccess) { | 
| 196 »           PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); | 196             PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); | 
| 197 »           return SECFailure; | 197             return SECFailure; | 
| 198 »       } | 198         } | 
| 199 | 199 | 
| 200 »       rv = NSS_GetAlgorithmPolicy(hashAlg, &policyFlags); | 200         rv = NSS_GetAlgorithmPolicy(hashAlg, &policyFlags); | 
| 201 »       if (rv == SECSuccess && | 201         if (rv == SECSuccess && | 
| 202 »           !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) { | 202             !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) { | 
| 203 »           PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); | 203             PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); | 
| 204 »           return SECFailure; | 204             return SECFailure; | 
| 205 »       } | 205         } | 
| 206     } | 206     } | 
| 207     return rv; | 207     return rv; | 
| 208 } | 208 } | 
| 209 | 209 | 
| 210 /* | 210 /* | 
| 211  * verify the signature of a signed data object with the given DER publickey | 211  * verify the signature of a signed data object with the given DER publickey | 
| 212  */ | 212  */ | 
| 213 SECStatus | 213 SECStatus | 
| 214 CERT_VerifySignedDataWithPublicKeyInfo(CERTSignedData *sd, | 214 CERT_VerifySignedDataWithPublicKeyInfo(CERTSignedData *sd, | 
| 215                                        CERTSubjectPublicKeyInfo *pubKeyInfo, | 215                                        CERTSubjectPublicKeyInfo *pubKeyInfo, | 
| 216 »       »                              void *wincx) | 216                                        void *wincx) | 
| 217 { | 217 { | 
| 218     SECKEYPublicKey *pubKey; | 218     SECKEYPublicKey *pubKey; | 
| 219     SECStatus        rv»»       = SECFailure; | 219     SECStatus rv = SECFailure; | 
| 220 | 220 | 
| 221     /* get cert's public key */ | 221     /* get cert's public key */ | 
| 222     pubKey = SECKEY_ExtractPublicKey(pubKeyInfo); | 222     pubKey = SECKEY_ExtractPublicKey(pubKeyInfo); | 
| 223     if (pubKey) { | 223     if (pubKey) { | 
| 224 »       rv =  CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx); | 224         rv = CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx); | 
| 225 »       SECKEY_DestroyPublicKey(pubKey); | 225         SECKEY_DestroyPublicKey(pubKey); | 
| 226     } | 226     } | 
| 227     return rv; | 227     return rv; | 
| 228 } | 228 } | 
| 229 | 229 | 
| 230 /* | 230 /* | 
| 231  * verify the signature of a signed data object with the given certificate | 231  * verify the signature of a signed data object with the given certificate | 
| 232  */ | 232  */ | 
| 233 SECStatus | 233 SECStatus | 
| 234 CERT_VerifySignedData(CERTSignedData *sd, CERTCertificate *cert, | 234 CERT_VerifySignedData(CERTSignedData *sd, CERTCertificate *cert, | 
| 235 »       »             PRTime t, void *wincx) | 235                       PRTime t, void *wincx) | 
| 236 { | 236 { | 
| 237     SECKEYPublicKey *pubKey = 0; | 237     SECKEYPublicKey *pubKey = 0; | 
| 238     SECStatus        rv     = SECFailure; | 238     SECStatus rv = SECFailure; | 
| 239     SECCertTimeValidity validity; | 239     SECCertTimeValidity validity; | 
| 240 | 240 | 
| 241     /* check the certificate's validity */ | 241     /* check the certificate's validity */ | 
| 242     validity = CERT_CheckCertValidTimes(cert, t, PR_FALSE); | 242     validity = CERT_CheckCertValidTimes(cert, t, PR_FALSE); | 
| 243     if ( validity != secCertTimeValid ) { | 243     if (validity != secCertTimeValid) { | 
| 244 »       return rv; | 244         return rv; | 
| 245     } | 245     } | 
| 246 | 246 | 
| 247     /* get cert's public key */ | 247     /* get cert's public key */ | 
| 248     pubKey = CERT_ExtractPublicKey(cert); | 248     pubKey = CERT_ExtractPublicKey(cert); | 
| 249     if (pubKey) { | 249     if (pubKey) { | 
| 250 »       rv =  CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx); | 250         rv = CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx); | 
| 251 »       SECKEY_DestroyPublicKey(pubKey); | 251         SECKEY_DestroyPublicKey(pubKey); | 
| 252     } | 252     } | 
| 253     return rv; | 253     return rv; | 
| 254 } | 254 } | 
| 255 | 255 | 
| 256 |  | 
| 257 SECStatus | 256 SECStatus | 
| 258 SEC_CheckCRL(CERTCertDBHandle *handle,CERTCertificate *cert, | 257 SEC_CheckCRL(CERTCertDBHandle *handle, CERTCertificate *cert, | 
| 259 »            CERTCertificate *caCert, PRTime t, void * wincx) | 258              CERTCertificate *caCert, PRTime t, void *wincx) | 
| 260 { | 259 { | 
| 261     return CERT_CheckCRL(cert, caCert, NULL, t, wincx); | 260     return CERT_CheckCRL(cert, caCert, NULL, t, wincx); | 
| 262 } | 261 } | 
| 263 | 262 | 
| 264 /* | 263 /* | 
| 265  * Find the issuer of a cert.  Use the authorityKeyID if it exists. | 264  * Find the issuer of a cert.  Use the authorityKeyID if it exists. | 
| 266  */ | 265  */ | 
| 267 CERTCertificate * | 266 CERTCertificate * | 
| 268 CERT_FindCertIssuer(CERTCertificate *cert, PRTime validTime, SECCertUsage usage) | 267 CERT_FindCertIssuer(CERTCertificate *cert, PRTime validTime, SECCertUsage usage) | 
| 269 { | 268 { | 
| 270     NSSCertificate *me; | 269     NSSCertificate *me; | 
| 271     NSSTime *nssTime; | 270     NSSTime *nssTime; | 
| 272     NSSTrustDomain *td; | 271     NSSTrustDomain *td; | 
| 273     NSSCryptoContext *cc; | 272     NSSCryptoContext *cc; | 
| 274     NSSCertificate *chain[3]; | 273     NSSCertificate *chain[3]; | 
| 275     NSSUsage nssUsage; | 274     NSSUsage nssUsage; | 
| 276     PRStatus status; | 275     PRStatus status; | 
| 277 | 276 | 
| 278     me = STAN_GetNSSCertificate(cert); | 277     me = STAN_GetNSSCertificate(cert); | 
| 279     if (!me) { | 278     if (!me) { | 
| 280         PORT_SetError(SEC_ERROR_NO_MEMORY); | 279         PORT_SetError(SEC_ERROR_NO_MEMORY); | 
| 281 »       return NULL; | 280         return NULL; | 
| 282     } | 281     } | 
| 283     nssTime = NSSTime_SetPRTime(NULL, validTime); | 282     nssTime = NSSTime_SetPRTime(NULL, validTime); | 
| 284     nssUsage.anyUsage = PR_FALSE; | 283     nssUsage.anyUsage = PR_FALSE; | 
| 285     nssUsage.nss3usage = usage; | 284     nssUsage.nss3usage = usage; | 
| 286     nssUsage.nss3lookingForCA = PR_TRUE; | 285     nssUsage.nss3lookingForCA = PR_TRUE; | 
| 287     memset(chain, 0, 3*sizeof(NSSCertificate *)); | 286     memset(chain, 0, 3 * sizeof(NSSCertificate *)); | 
| 288     td   = STAN_GetDefaultTrustDomain(); | 287     td = STAN_GetDefaultTrustDomain(); | 
| 289     cc = STAN_GetDefaultCryptoContext(); | 288     cc = STAN_GetDefaultCryptoContext(); | 
| 290     (void)NSSCertificate_BuildChain(me, nssTime, &nssUsage, NULL, | 289     (void)NSSCertificate_BuildChain(me, nssTime, &nssUsage, NULL, | 
| 291                                     chain, 2, NULL, &status, td, cc); | 290                                     chain, 2, NULL, &status, td, cc); | 
| 292     nss_ZFreeIf(nssTime); | 291     nss_ZFreeIf(nssTime); | 
| 293     if (status == PR_SUCCESS) { | 292     if (status == PR_SUCCESS) { | 
| 294 »       PORT_Assert(me == chain[0]); | 293         PORT_Assert(me == chain[0]); | 
| 295 »       /* if it's a root, the chain will only have one cert */ | 294         /* if it's a root, the chain will only have one cert */ | 
| 296 »       if (!chain[1]) { | 295         if (!chain[1]) { | 
| 297 »           /* already has a reference from the call to BuildChain */ | 296             /* already has a reference from the call to BuildChain */ | 
| 298 »           return cert; | 297             return cert; | 
| 299 »       } | 298         } | 
| 300 »       NSSCertificate_Destroy(chain[0]); /* the first cert in the chain */ | 299         NSSCertificate_Destroy(chain[0]);         /* the first cert in the chain
       */ | 
| 301 »       return STAN_GetCERTCertificate(chain[1]); /* return the 2nd */ | 300         return STAN_GetCERTCertificate(chain[1]); /* return the 2nd */ | 
| 302     } | 301     } | 
| 303     if (chain[0]) { | 302     if (chain[0]) { | 
| 304 »       PORT_Assert(me == chain[0]); | 303         PORT_Assert(me == chain[0]); | 
| 305 »       NSSCertificate_Destroy(chain[0]); /* the first cert in the chain */ | 304         NSSCertificate_Destroy(chain[0]); /* the first cert in the chain */ | 
| 306     } | 305     } | 
| 307     PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER); | 306     PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); | 
| 308     return NULL; | 307     return NULL; | 
| 309 } | 308 } | 
| 310 | 309 | 
| 311 /* | 310 /* | 
| 312  * return required trust flags for various cert usages for CAs | 311  * return required trust flags for various cert usages for CAs | 
| 313  */ | 312  */ | 
| 314 SECStatus | 313 SECStatus | 
| 315 CERT_TrustFlagsForCACertUsage(SECCertUsage usage, | 314 CERT_TrustFlagsForCACertUsage(SECCertUsage usage, | 
| 316 »       »       »             unsigned int *retFlags, | 315                               unsigned int *retFlags, | 
| 317 »       »       »             SECTrustType *retTrustType) | 316                               SECTrustType *retTrustType) | 
| 318 { | 317 { | 
| 319     unsigned int requiredFlags; | 318     unsigned int requiredFlags; | 
| 320     SECTrustType trustType; | 319     SECTrustType trustType; | 
| 321 | 320 | 
| 322     switch ( usage ) { | 321     switch (usage) { | 
| 323       case certUsageSSLClient: | 322         case certUsageSSLClient: | 
| 324 »       requiredFlags = CERTDB_TRUSTED_CLIENT_CA; | 323             requiredFlags = CERTDB_TRUSTED_CLIENT_CA; | 
| 325 »       trustType = trustSSL; | 324             trustType = trustSSL; | 
| 326         break; | 325             break; | 
| 327       case certUsageSSLServer: | 326         case certUsageSSLServer: | 
| 328       case certUsageSSLCA: | 327         case certUsageSSLCA: | 
| 329 »       requiredFlags = CERTDB_TRUSTED_CA; | 328             requiredFlags = CERTDB_TRUSTED_CA; | 
| 330 »       trustType = trustSSL; | 329             trustType = trustSSL; | 
| 331         break; | 330             break; | 
| 332       case certUsageSSLServerWithStepUp: | 331         case certUsageSSLServerWithStepUp: | 
| 333 »       requiredFlags = CERTDB_TRUSTED_CA | CERTDB_GOVT_APPROVED_CA; | 332             requiredFlags = CERTDB_TRUSTED_CA | CERTDB_GOVT_APPROVED_CA; | 
| 334 »       trustType = trustSSL; | 333             trustType = trustSSL; | 
| 335         break; | 334             break; | 
| 336       case certUsageEmailSigner: | 335         case certUsageEmailSigner: | 
| 337       case certUsageEmailRecipient: | 336         case certUsageEmailRecipient: | 
| 338 »       requiredFlags = CERTDB_TRUSTED_CA; | 337             requiredFlags = CERTDB_TRUSTED_CA; | 
| 339 »       trustType = trustEmail; | 338             trustType = trustEmail; | 
| 340 »       break; | 339             break; | 
| 341       case certUsageObjectSigner: | 340         case certUsageObjectSigner: | 
| 342 »       requiredFlags = CERTDB_TRUSTED_CA; | 341             requiredFlags = CERTDB_TRUSTED_CA; | 
| 343 »       trustType = trustObjectSigning; | 342             trustType = trustObjectSigning; | 
| 344 »       break; | 343             break; | 
| 345       case certUsageVerifyCA: | 344         case certUsageVerifyCA: | 
| 346       case certUsageAnyCA: | 345         case certUsageAnyCA: | 
| 347       case certUsageStatusResponder: | 346         case certUsageStatusResponder: | 
| 348 »       requiredFlags = CERTDB_TRUSTED_CA; | 347             requiredFlags = CERTDB_TRUSTED_CA; | 
| 349 »       trustType = trustTypeNone; | 348             trustType = trustTypeNone; | 
| 350 »       break; | 349             break; | 
| 351       default: | 350         default: | 
| 352 »       PORT_Assert(0); | 351             PORT_Assert(0); | 
| 353 »       goto loser; | 352             goto loser; | 
| 354     } | 353     } | 
| 355     if ( retFlags != NULL ) { | 354     if (retFlags != NULL) { | 
| 356 »       *retFlags = requiredFlags; | 355         *retFlags = requiredFlags; | 
| 357     } | 356     } | 
| 358     if ( retTrustType != NULL ) { | 357     if (retTrustType != NULL) { | 
| 359 »       *retTrustType = trustType; | 358         *retTrustType = trustType; | 
| 360     } | 359     } | 
| 361 | 360 | 
| 362     return(SECSuccess); | 361     return (SECSuccess); | 
| 363 loser: | 362 loser: | 
| 364     return(SECFailure); | 363     return (SECFailure); | 
| 365 } | 364 } | 
| 366 | 365 | 
| 367 void | 366 void | 
| 368 cert_AddToVerifyLog(CERTVerifyLog *log, CERTCertificate *cert, long error, | 367 cert_AddToVerifyLog(CERTVerifyLog *log, CERTCertificate *cert, long error, | 
| 369 »              unsigned int depth, void *arg) | 368                     unsigned int depth, void *arg) | 
| 370 { | 369 { | 
| 371     CERTVerifyLogNode *node, *tnode; | 370     CERTVerifyLogNode *node, *tnode; | 
| 372 | 371 | 
| 373     PORT_Assert(log != NULL); | 372     PORT_Assert(log != NULL); | 
| 374 | 373 | 
| 375     node = (CERTVerifyLogNode *)PORT_ArenaAlloc(log->arena, | 374     node = (CERTVerifyLogNode *)PORT_ArenaAlloc(log->arena, | 
| 376 »       »       »       »       »       »       sizeof(CERTVerifyLogNode)); | 375                                                 sizeof(CERTVerifyLogNode)); | 
| 377     if ( node != NULL ) { | 376     if (node != NULL) { | 
| 378 »       node->cert = CERT_DupCertificate(cert); | 377         node->cert = CERT_DupCertificate(cert); | 
| 379 »       node->error = error; | 378         node->error = error; | 
| 380 »       node->depth = depth; | 379         node->depth = depth; | 
| 381 »       node->arg = arg; | 380         node->arg = arg; | 
| 382 » |  | 
| 383 »       if ( log->tail == NULL ) { |  | 
| 384 »           /* empty list */ |  | 
| 385 »           log->head = log->tail = node; |  | 
| 386 »           node->prev = NULL; |  | 
| 387 »           node->next = NULL; |  | 
| 388 »       } else if ( depth >= log->tail->depth ) { |  | 
| 389 »           /* add to tail */ |  | 
| 390 »           node->prev = log->tail; |  | 
| 391 »           log->tail->next = node; |  | 
| 392 »           log->tail = node; |  | 
| 393 »           node->next = NULL; |  | 
| 394 »       } else if ( depth < log->head->depth ) { |  | 
| 395 »           /* add at head */ |  | 
| 396 »           node->prev = NULL; |  | 
| 397 »           node->next = log->head; |  | 
| 398 »           log->head->prev = node; |  | 
| 399 »           log->head = node; |  | 
| 400 »       } else { |  | 
| 401 »           /* add in middle */ |  | 
| 402 »           tnode = log->tail; |  | 
| 403 »           while ( tnode != NULL ) { |  | 
| 404 »       »       if ( depth >= tnode->depth ) { |  | 
| 405 »       »           /* insert after tnode */ |  | 
| 406 »       »           node->prev = tnode; |  | 
| 407 »       »           node->next = tnode->next; |  | 
| 408 »       »           tnode->next->prev = node; |  | 
| 409 »       »           tnode->next = node; |  | 
| 410 »       »           break; |  | 
| 411 »       »       } |  | 
| 412 | 381 | 
| 413 »       »       tnode = tnode->prev; | 382         if (log->tail == NULL) { | 
| 414 »           } | 383             /* empty list */ | 
| 415 »       } | 384             log->head = log->tail = node; | 
|  | 385             node->prev = NULL; | 
|  | 386             node->next = NULL; | 
|  | 387         } else if (depth >= log->tail->depth) { | 
|  | 388             /* add to tail */ | 
|  | 389             node->prev = log->tail; | 
|  | 390             log->tail->next = node; | 
|  | 391             log->tail = node; | 
|  | 392             node->next = NULL; | 
|  | 393         } else if (depth < log->head->depth) { | 
|  | 394             /* add at head */ | 
|  | 395             node->prev = NULL; | 
|  | 396             node->next = log->head; | 
|  | 397             log->head->prev = node; | 
|  | 398             log->head = node; | 
|  | 399         } else { | 
|  | 400             /* add in middle */ | 
|  | 401             tnode = log->tail; | 
|  | 402             while (tnode != NULL) { | 
|  | 403                 if (depth >= tnode->depth) { | 
|  | 404                     /* insert after tnode */ | 
|  | 405                     node->prev = tnode; | 
|  | 406                     node->next = tnode->next; | 
|  | 407                     tnode->next->prev = node; | 
|  | 408                     tnode->next = node; | 
|  | 409                     break; | 
|  | 410                 } | 
| 416 | 411 | 
| 417 »       log->count++; | 412                 tnode = tnode->prev; | 
|  | 413             } | 
|  | 414         } | 
|  | 415 | 
|  | 416         log->count++; | 
| 418     } | 417     } | 
| 419     return; | 418     return; | 
| 420 } | 419 } | 
| 421 | 420 | 
| 422 #define EXIT_IF_NOT_LOGGING(log) \ | 421 #define EXIT_IF_NOT_LOGGING(log) \ | 
| 423     if ( log == NULL ) { \ | 422     if (log == NULL) {           \ | 
| 424 »       goto loser; \ | 423         goto loser;              \ | 
| 425     } | 424     } | 
| 426 | 425 | 
| 427 #define LOG_ERROR_OR_EXIT(log,cert,depth,arg) \ | 426 #define LOG_ERROR_OR_EXIT(log, cert, depth, arg)               \ | 
| 428     if ( log != NULL ) { \ | 427     if (log != NULL) {                                         \ | 
| 429 »       cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \ | 428         cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \ | 
| 430 »       »       »           (void *)(PRWord)arg); \ | 429                             (void *)(PRWord)arg);              \ | 
| 431     } else { \ | 430     } else {                                                   \ | 
| 432 »       goto loser; \ | 431         goto loser;                                            \ | 
| 433     } | 432     } | 
| 434 | 433 | 
| 435 #define LOG_ERROR(log,cert,depth,arg) \ | 434 #define LOG_ERROR(log, cert, depth, arg)                       \ | 
| 436     if ( log != NULL ) { \ | 435     if (log != NULL) {                                         \ | 
| 437 »       cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \ | 436         cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \ | 
| 438 »       »       »           (void *)(PRWord)arg); \ | 437                             (void *)(PRWord)arg);              \ | 
| 439     } | 438     } | 
| 440 | 439 | 
| 441 static SECStatus | 440 static SECStatus | 
| 442 cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert, | 441 cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert, | 
| 443 »       »            PRBool checkSig, PRBool* sigerror, | 442                         PRBool checkSig, PRBool *sigerror, | 
| 444                      SECCertUsage certUsage, PRTime t, void *wincx, | 443                         SECCertUsage certUsage, PRTime t, void *wincx, | 
| 445                      CERTVerifyLog *log, PRBool* revoked) | 444                         CERTVerifyLog *log, PRBool *revoked) | 
| 446 { | 445 { | 
| 447     SECTrustType trustType; | 446     SECTrustType trustType; | 
| 448     CERTBasicConstraints basicConstraint; | 447     CERTBasicConstraints basicConstraint; | 
| 449     CERTCertificate *issuerCert = NULL; | 448     CERTCertificate *issuerCert = NULL; | 
| 450     CERTCertificate *subjectCert = NULL; | 449     CERTCertificate *subjectCert = NULL; | 
| 451     CERTCertificate *badCert = NULL; | 450     CERTCertificate *badCert = NULL; | 
| 452     PRBool isca; | 451     PRBool isca; | 
| 453     SECStatus rv; | 452     SECStatus rv; | 
| 454     SECStatus rvFinal = SECSuccess; | 453     SECStatus rvFinal = SECSuccess; | 
| 455     int count; | 454     int count; | 
| 456     int currentPathLen = 0; | 455     int currentPathLen = 0; | 
| 457     int pathLengthLimit = CERT_UNLIMITED_PATH_CONSTRAINT; | 456     int pathLengthLimit = CERT_UNLIMITED_PATH_CONSTRAINT; | 
| 458     unsigned int caCertType; | 457     unsigned int caCertType; | 
| 459     unsigned int requiredCAKeyUsage; | 458     unsigned int requiredCAKeyUsage; | 
| 460     unsigned int requiredFlags; | 459     unsigned int requiredFlags; | 
| 461     PLArenaPool *arena = NULL; | 460     PLArenaPool *arena = NULL; | 
| 462     CERTGeneralName *namesList = NULL; | 461     CERTGeneralName *namesList = NULL; | 
| 463     CERTCertificate **certsList      = NULL; | 462     CERTCertificate **certsList = NULL; | 
| 464     int certsListLen = 16; | 463     int certsListLen = 16; | 
| 465     int namesCount = 0; | 464     int namesCount = 0; | 
| 466     PRBool subjectCertIsSelfIssued; | 465     PRBool subjectCertIsSelfIssued; | 
| 467     CERTCertTrust issuerTrust; | 466     CERTCertTrust issuerTrust; | 
| 468 | 467 | 
| 469     if (revoked) { | 468     if (revoked) { | 
| 470         *revoked = PR_FALSE; | 469         *revoked = PR_FALSE; | 
| 471     } | 470     } | 
| 472 | 471 | 
| 473     if (CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_TRUE, | 472     if (CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_TRUE, | 
| 474 »       »       »       »       »        &requiredCAKeyUsage, | 473                                          &requiredCAKeyUsage, | 
| 475 »       »       »       »       »        &caCertType) | 474                                          &caCertType) != | 
| 476 »       != SECSuccess ) { | 475         SECSuccess) { | 
| 477 »       PORT_Assert(0); | 476         PORT_Assert(0); | 
| 478 »       EXIT_IF_NOT_LOGGING(log); | 477         EXIT_IF_NOT_LOGGING(log); | 
| 479 »       requiredCAKeyUsage = 0; | 478         requiredCAKeyUsage = 0; | 
| 480 »       caCertType = 0; | 479         caCertType = 0; | 
| 481     } | 480     } | 
| 482 | 481 | 
| 483     switch ( certUsage ) { | 482     switch (certUsage) { | 
| 484       case certUsageSSLClient: | 483         case certUsageSSLClient: | 
| 485       case certUsageSSLServer: | 484         case certUsageSSLServer: | 
| 486       case certUsageSSLCA: | 485         case certUsageSSLCA: | 
| 487       case certUsageSSLServerWithStepUp: | 486         case certUsageSSLServerWithStepUp: | 
| 488       case certUsageEmailSigner: | 487         case certUsageEmailSigner: | 
| 489       case certUsageEmailRecipient: | 488         case certUsageEmailRecipient: | 
| 490       case certUsageObjectSigner: | 489         case certUsageObjectSigner: | 
| 491       case certUsageVerifyCA: | 490         case certUsageVerifyCA: | 
| 492       case certUsageAnyCA: | 491         case certUsageAnyCA: | 
| 493       case certUsageStatusResponder: | 492         case certUsageStatusResponder: | 
| 494 »       if ( CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, | 493             if (CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, | 
| 495 »       »       »       »       »          &trustType) != SECSuccess ) { | 494                                               &trustType) != SECSuccess) { | 
| 496 »           PORT_Assert(0); | 495                 PORT_Assert(0); | 
| 497 »           EXIT_IF_NOT_LOGGING(log); | 496                 EXIT_IF_NOT_LOGGING(log); | 
| 498 »           /* XXX continuing with requiredFlags = 0 seems wrong.  It'll | 497                 /* XXX continuing with requiredFlags = 0 seems wrong.  It'll | 
| 499 »            * cause the following test to be true incorrectly: | 498                  * cause the following test to be true incorrectly: | 
| 500 »            *   flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType); | 499                  *   flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType); | 
| 501 »            *   if (( flags & requiredFlags ) == requiredFlags) { | 500                  *   if (( flags & requiredFlags ) == requiredFlags) { | 
| 502 »            *       rv = rvFinal; | 501                  *       rv = rvFinal; | 
| 503 »            *       goto done; | 502                  *       goto done; | 
| 504 »            *   } | 503                  *   } | 
| 505 »            * There are three other instances of this problem. | 504                  * There are three other instances of this problem. | 
| 506 »            */ | 505                  */ | 
| 507 »           requiredFlags = 0; | 506                 requiredFlags = 0; | 
| 508 »           trustType = trustSSL; | 507                 trustType = trustSSL; | 
| 509 »       } | 508             } | 
| 510 »       break; | 509             break; | 
| 511       default: | 510         default: | 
| 512 »       PORT_Assert(0); | 511             PORT_Assert(0); | 
| 513 »       EXIT_IF_NOT_LOGGING(log); | 512             EXIT_IF_NOT_LOGGING(log); | 
| 514 »       requiredFlags = 0; | 513             requiredFlags = 0; | 
| 515 »       trustType = trustSSL;/* This used to be 0, but we need something | 514             trustType = trustSSL; /* This used to be 0, but we need something | 
| 516 »       »       »             * that matches the enumeration type. | 515                                    * that matches the enumeration type. | 
| 517 »       »       »             */ | 516                                    */ | 
| 518 »       caCertType = 0; | 517             caCertType = 0; | 
| 519     } | 518     } | 
| 520 | 519 | 
| 521     subjectCert = CERT_DupCertificate(cert); | 520     subjectCert = CERT_DupCertificate(cert); | 
| 522     if ( subjectCert == NULL ) { | 521     if (subjectCert == NULL) { | 
| 523 »       goto loser; | 522         goto loser; | 
| 524     } | 523     } | 
| 525 | 524 | 
| 526     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 525     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 
| 527     if (arena == NULL) { | 526     if (arena == NULL) { | 
| 528 »       goto loser; | 527         goto loser; | 
| 529     } | 528     } | 
| 530 | 529 | 
| 531     certsList = PORT_ZNewArray(CERTCertificate *, certsListLen); | 530     certsList = PORT_ZNewArray(CERTCertificate *, certsListLen); | 
| 532     if (certsList == NULL) | 531     if (certsList == NULL) | 
| 533 »       goto loser; | 532         goto loser; | 
| 534 | 533 | 
| 535     /* RFC 3280 says that the name constraints will apply to the names | 534     /* RFC 3280 says that the name constraints will apply to the names | 
| 536     ** in the leaf (EE) cert, whether it is self issued or not, so | 535     ** in the leaf (EE) cert, whether it is self issued or not, so | 
| 537     ** we pretend that it is not. | 536     ** we pretend that it is not. | 
| 538     */ | 537     */ | 
| 539     subjectCertIsSelfIssued = PR_FALSE; | 538     subjectCertIsSelfIssued = PR_FALSE; | 
| 540     for ( count = 0; count < CERT_MAX_CERT_CHAIN; count++ ) { | 539     for (count = 0; count < CERT_MAX_CERT_CHAIN; count++) { | 
| 541 »       PRBool validCAOverride = PR_FALSE; | 540         PRBool validCAOverride = PR_FALSE; | 
| 542 | 541 | 
| 543 »       /* Construct a list of names for the current and all previous | 542         /* Construct a list of names for the current and all previous | 
| 544 »        * certifcates (except leaf (EE) certs, root CAs, and self-issued | 543          * certifcates (except leaf (EE) certs, root CAs, and self-issued | 
| 545 »        * intermediate CAs) to be verified against the name constraints | 544          * intermediate CAs) to be verified against the name constraints | 
| 546 »        * extension of the issuer certificate. | 545          * extension of the issuer certificate. | 
| 547 »        */ | 546          */ | 
| 548 »       if (subjectCertIsSelfIssued == PR_FALSE) { | 547         if (subjectCertIsSelfIssued == PR_FALSE) { | 
| 549 »           CERTGeneralName *subjectNameList; | 548             CERTGeneralName *subjectNameList; | 
| 550 »           int subjectNameListLen; | 549             int subjectNameListLen; | 
| 551 »           int i; | 550             int i; | 
| 552 »           PRBool getSubjectCN = (!count && certUsage == certUsageSSLServer); | 551             PRBool getSubjectCN = (!count && certUsage == certUsageSSLServer); | 
| 553 »           subjectNameList = | 552             subjectNameList = | 
| 554 »           »   CERT_GetConstrainedCertificateNames(subjectCert, arena, | 553                 CERT_GetConstrainedCertificateNames(subjectCert, arena, | 
| 555 »       »                                           getSubjectCN); | 554                                                     getSubjectCN); | 
| 556 »           if (!subjectNameList) | 555             if (!subjectNameList) | 
| 557 »       »       goto loser; | 556                 goto loser; | 
| 558 »           subjectNameListLen = CERT_GetNamesLength(subjectNameList); | 557             subjectNameListLen = CERT_GetNamesLength(subjectNameList); | 
| 559 »           if (!subjectNameListLen) | 558             if (!subjectNameListLen) | 
| 560 »       »       goto loser; | 559                 goto loser; | 
| 561 »           if (certsListLen <= namesCount + subjectNameListLen) { | 560             if (certsListLen <= namesCount + subjectNameListLen) { | 
| 562 »       »       CERTCertificate **tmpCertsList; | 561                 CERTCertificate **tmpCertsList; | 
| 563 »       »       certsListLen = (namesCount + subjectNameListLen) * 2; | 562                 certsListLen = (namesCount + subjectNameListLen) * 2; | 
| 564 »       »       tmpCertsList = | 563                 tmpCertsList = | 
| 565 »       »           (CERTCertificate **)PORT_Realloc(certsList, | 564                     (CERTCertificate **)PORT_Realloc(certsList, | 
| 566 »                                   certsListLen * sizeof(CERTCertificate *)); | 565                                                      certsListLen * | 
| 567 »       »       if (tmpCertsList == NULL) { | 566                                                          sizeof(CERTCertificate 
      *)); | 
| 568 »       »           goto loser; | 567                 if (tmpCertsList == NULL) { | 
| 569 »       »       } | 568                     goto loser; | 
| 570 »       »       certsList = tmpCertsList; | 569                 } | 
| 571 »           } | 570                 certsList = tmpCertsList; | 
| 572 »           for (i = 0; i < subjectNameListLen; i++) { | 571             } | 
| 573 »       »       certsList[namesCount + i] = subjectCert; | 572             for (i = 0; i < subjectNameListLen; i++) { | 
| 574 »           } | 573                 certsList[namesCount + i] = subjectCert; | 
| 575 »           namesCount += subjectNameListLen; | 574             } | 
| 576 »           namesList = cert_CombineNamesLists(namesList, subjectNameList); | 575             namesCount += subjectNameListLen; | 
| 577 »       } | 576             namesList = cert_CombineNamesLists(namesList, subjectNameList); | 
|  | 577         } | 
| 578 | 578 | 
| 579         /* check if the cert has an unsupported critical extension */ | 579         /* check if the cert has an unsupported critical extension */ | 
| 580 »       if ( subjectCert->options.bits.hasUnsupportedCriticalExt ) { | 580         if (subjectCert->options.bits.hasUnsupportedCriticalExt) { | 
| 581 »           PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION); | 581             PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION); | 
| 582 »           LOG_ERROR_OR_EXIT(log,subjectCert,count,0); | 582             LOG_ERROR_OR_EXIT(log, subjectCert, count, 0); | 
| 583 »       } | 583         } | 
| 584 | 584 | 
| 585 »       /* find the certificate of the issuer */ | 585         /* find the certificate of the issuer */ | 
| 586 »       issuerCert = CERT_FindCertIssuer(subjectCert, t, certUsage); | 586         issuerCert = CERT_FindCertIssuer(subjectCert, t, certUsage); | 
| 587 »       if ( ! issuerCert ) { | 587         if (!issuerCert) { | 
| 588 »           PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); | 588             PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); | 
| 589 »           LOG_ERROR(log,subjectCert,count,0); | 589             LOG_ERROR(log, subjectCert, count, 0); | 
| 590 »           goto loser; | 590             goto loser; | 
| 591 »       } | 591         } | 
| 592 | 592 | 
| 593 »       /* verify the signature on the cert */ | 593         /* verify the signature on the cert */ | 
| 594 »       if ( checkSig ) { | 594         if (checkSig) { | 
| 595 »           rv = CERT_VerifySignedData(&subjectCert->signatureWrap, | 595             rv = CERT_VerifySignedData(&subjectCert->signatureWrap, | 
| 596 »       »       »       »              issuerCert, t, wincx); | 596                                        issuerCert, t, wincx); | 
| 597 | 597 | 
| 598 »           if ( rv != SECSuccess ) { | 598             if (rv != SECSuccess) { | 
| 599                 if (sigerror) { | 599                 if (sigerror) { | 
| 600                     *sigerror = PR_TRUE; | 600                     *sigerror = PR_TRUE; | 
| 601                 } | 601                 } | 
| 602 »       »       if ( PORT_GetError() == SEC_ERROR_EXPIRED_CERTIFICATE ) { | 602                 if (PORT_GetError() == SEC_ERROR_EXPIRED_CERTIFICATE) { | 
| 603 »       »           PORT_SetError(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE); | 603                     PORT_SetError(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE); | 
| 604 »       »           LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0); | 604                     LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, 0); | 
| 605 »       »       } else { | 605                 } else { | 
| 606 »       »           if (PORT_GetError() != | 606                     if (PORT_GetError() != | 
| 607 »       »       »       SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED) { | 607                         SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED) { | 
| 608 »       »       »       PORT_SetError(SEC_ERROR_BAD_SIGNATURE); | 608                         PORT_SetError(SEC_ERROR_BAD_SIGNATURE); | 
| 609 »       »           } | 609                     } | 
| 610 »       »           LOG_ERROR_OR_EXIT(log,subjectCert,count,0); | 610                     LOG_ERROR_OR_EXIT(log, subjectCert, count, 0); | 
| 611 »       »       } | 611                 } | 
| 612 »           } | 612             } | 
| 613 »       } | 613         } | 
| 614 | 614 | 
| 615 »       /* If the basicConstraint extension is included in an immediate CA | 615         /* If the basicConstraint extension is included in an immediate CA | 
| 616 »        * certificate, make sure that the isCA flag is on.  If the | 616          * certificate, make sure that the isCA flag is on.  If the | 
| 617 »        * pathLenConstraint component exists, it must be greater than the | 617          * pathLenConstraint component exists, it must be greater than the | 
| 618 »        * number of CA certificates we have seen so far.  If the extension | 618          * number of CA certificates we have seen so far.  If the extension | 
| 619 »        * is omitted, we will assume that this is a CA certificate with | 619          * is omitted, we will assume that this is a CA certificate with | 
| 620 »        * an unlimited pathLenConstraint (since it already passes the | 620          * an unlimited pathLenConstraint (since it already passes the | 
| 621 »        * netscape-cert-type extension checking). | 621          * netscape-cert-type extension checking). | 
| 622 »        */ | 622          */ | 
| 623 | 623 | 
| 624 »       rv = CERT_FindBasicConstraintExten(issuerCert, &basicConstraint); | 624         rv = CERT_FindBasicConstraintExten(issuerCert, &basicConstraint); | 
| 625 »       if ( rv != SECSuccess ) { | 625         if (rv != SECSuccess) { | 
| 626 »           if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { | 626             if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { | 
| 627 »       »       LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0); | 627                 LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, 0); | 
| 628 »           } | 628             } | 
| 629 »           pathLengthLimit = CERT_UNLIMITED_PATH_CONSTRAINT; | 629             pathLengthLimit = CERT_UNLIMITED_PATH_CONSTRAINT; | 
| 630 »           /* no basic constraints found, we aren't (yet) a CA. */ | 630             /* no basic constraints found, we aren't (yet) a CA. */ | 
| 631 »           isca = PR_FALSE; | 631             isca = PR_FALSE; | 
| 632 »       } else  { | 632         } else { | 
| 633 »           if ( basicConstraint.isCA == PR_FALSE ) { | 633             if (basicConstraint.isCA == PR_FALSE) { | 
| 634 »       »       PORT_SetError (SEC_ERROR_CA_CERT_INVALID); | 634                 PORT_SetError(SEC_ERROR_CA_CERT_INVALID); | 
| 635 »       »       LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0); | 635                 LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, 0); | 
| 636 »           } | 636             } | 
| 637 »           pathLengthLimit = basicConstraint.pathLenConstraint; | 637             pathLengthLimit = basicConstraint.pathLenConstraint; | 
| 638 »           isca = PR_TRUE; | 638             isca = PR_TRUE; | 
| 639 »       } | 639         } | 
| 640 »       /* make sure that the path len constraint is properly set.*/ | 640         /* make sure that the path len constraint is properly set.*/ | 
| 641 »       if (pathLengthLimit >= 0 && currentPathLen > pathLengthLimit) { | 641         if (pathLengthLimit >= 0 && currentPathLen > pathLengthLimit) { | 
| 642 »           PORT_SetError (SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID); | 642             PORT_SetError(SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID); | 
| 643 »           LOG_ERROR_OR_EXIT(log, issuerCert, count+1, pathLengthLimit); | 643             LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, pathLengthLimit); | 
| 644 »       } | 644         } | 
| 645 | 645 | 
| 646         /* make sure that the entire chain is within the name space of the | 646         /* make sure that the entire chain is within the name space of the | 
| 647          * current issuer certificate. | 647          * current issuer certificate. | 
| 648          */ | 648          */ | 
| 649         rv = CERT_CompareNameSpace(issuerCert, namesList, certsList, | 649         rv = CERT_CompareNameSpace(issuerCert, namesList, certsList, | 
| 650                                    arena, &badCert); | 650                                    arena, &badCert); | 
| 651         if (rv != SECSuccess || badCert != NULL) { | 651         if (rv != SECSuccess || badCert != NULL) { | 
| 652             PORT_SetError(SEC_ERROR_CERT_NOT_IN_NAME_SPACE); | 652             PORT_SetError(SEC_ERROR_CERT_NOT_IN_NAME_SPACE); | 
| 653             LOG_ERROR_OR_EXIT(log, badCert, count + 1, 0); | 653             LOG_ERROR_OR_EXIT(log, badCert, count + 1, 0); | 
| 654             goto loser; | 654             goto loser; | 
| 655         } | 655         } | 
| 656 | 656 | 
| 657 »       /* XXX - the error logging may need to go down into CRL stuff at some | 657         /* XXX - the error logging may need to go down into CRL stuff at some | 
| 658 »        * point | 658          * point | 
| 659 »        */ | 659          */ | 
| 660 »       /* check revoked list (issuer) */ | 660         /* check revoked list (issuer) */ | 
| 661         rv = SEC_CheckCRL(handle, subjectCert, issuerCert, t, wincx); | 661         rv = SEC_CheckCRL(handle, subjectCert, issuerCert, t, wincx); | 
| 662         if (rv == SECFailure) { | 662         if (rv == SECFailure) { | 
| 663             if (revoked) { | 663             if (revoked) { | 
| 664                 *revoked = PR_TRUE; | 664                 *revoked = PR_TRUE; | 
| 665             } | 665             } | 
| 666             LOG_ERROR_OR_EXIT(log,subjectCert,count,0); | 666             LOG_ERROR_OR_EXIT(log, subjectCert, count, 0); | 
| 667         } else if (rv == SECWouldBlock) { | 667         } else if (rv == SECWouldBlock) { | 
| 668             /* We found something fishy, so we intend to issue an | 668             /* We found something fishy, so we intend to issue an | 
| 669              * error to the user, but the user may wish to continue | 669              * error to the user, but the user may wish to continue | 
| 670              * processing, in which case we better make sure nothing | 670              * processing, in which case we better make sure nothing | 
| 671              * worse has happened... so keep cranking the loop */ | 671              * worse has happened... so keep cranking the loop */ | 
| 672             rvFinal = SECFailure; | 672             rvFinal = SECFailure; | 
| 673             if (revoked) { | 673             if (revoked) { | 
| 674                 *revoked = PR_TRUE; | 674                 *revoked = PR_TRUE; | 
| 675             } | 675             } | 
| 676             LOG_ERROR(log,subjectCert,count,0); | 676             LOG_ERROR(log, subjectCert, count, 0); | 
| 677         } | 677         } | 
| 678 | 678 | 
| 679 »       if ( CERT_GetCertTrust(issuerCert, &issuerTrust) == SECSuccess) { | 679         if (CERT_GetCertTrust(issuerCert, &issuerTrust) == SECSuccess) { | 
| 680 »           /* we have some trust info, but this does NOT imply that this | 680             /* we have some trust info, but this does NOT imply that this | 
| 681 »            * cert is actually trusted for any purpose.  The cert may be | 681              * cert is actually trusted for any purpose.  The cert may be | 
| 682 »            * explicitly UNtrusted.  We won't know until we examine the | 682              * explicitly UNtrusted.  We won't know until we examine the | 
| 683 »            * trust bits. | 683              * trust bits. | 
| 684 »            */ | 684              */ | 
| 685 »           unsigned int flags; | 685             unsigned int flags; | 
| 686 | 686 | 
| 687 »           if (certUsage != certUsageAnyCA && | 687             if (certUsage != certUsageAnyCA && | 
| 688 »               certUsage != certUsageStatusResponder) { | 688                 certUsage != certUsageStatusResponder) { | 
| 689 | 689 | 
| 690 »               /* | 690                 /* | 
| 691 »                * XXX This choice of trustType seems arbitrary. | 691                  * XXX This choice of trustType seems arbitrary. | 
| 692 »                */ | 692                  */ | 
| 693 »               if ( certUsage == certUsageVerifyCA ) { | 693                 if (certUsage == certUsageVerifyCA) { | 
| 694 »                   if ( subjectCert->nsCertType & NS_CERT_TYPE_EMAIL_CA ) { | 694                     if (subjectCert->nsCertType & NS_CERT_TYPE_EMAIL_CA) { | 
| 695 »                       trustType = trustEmail; | 695                         trustType = trustEmail; | 
| 696 »                   } else if ( subjectCert->nsCertType & NS_CERT_TYPE_SSL_CA ) 
      { | 696                     } else if (subjectCert->nsCertType & NS_CERT_TYPE_SSL_CA) { | 
| 697 »                       trustType = trustSSL; | 697                         trustType = trustSSL; | 
| 698 »                   } else { | 698                     } else { | 
| 699 »                       trustType = trustObjectSigning; | 699                         trustType = trustObjectSigning; | 
| 700 »                   } | 700                     } | 
| 701 »               } | 701                 } | 
| 702 | 702 | 
| 703 »               flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType); | 703                 flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType); | 
| 704 »               if (( flags & requiredFlags ) == requiredFlags) { | 704                 if ((flags & requiredFlags) == requiredFlags) { | 
| 705 »                   /* we found a trusted one, so return */ | 705                     /* we found a trusted one, so return */ | 
| 706 »                   rv = rvFinal; | 706                     rv = rvFinal; | 
| 707 »                   goto done; | 707                     goto done; | 
| 708 »               } | 708                 } | 
| 709 »               if (flags & CERTDB_VALID_CA) { | 709                 if (flags & CERTDB_VALID_CA) { | 
| 710 »                   validCAOverride = PR_TRUE; | 710                     validCAOverride = PR_TRUE; | 
| 711 »               } | 711                 } | 
| 712 »       »       /* is it explicitly distrusted? */ | 712                 /* is it explicitly distrusted? */ | 
| 713 »       »       if ((flags & CERTDB_TERMINAL_RECORD) && | 713                 if ((flags & CERTDB_TERMINAL_RECORD) && | 
| 714 »       »       »       ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) { | 714                     ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0)) { | 
| 715 »       »           /* untrusted -- the cert is explicitly untrusted, not | 715                     /* untrusted -- the cert is explicitly untrusted, not | 
| 716 »       »            * just that it doesn't chain to a trusted cert */ | 716                      * just that it doesn't chain to a trusted cert */ | 
| 717 »       »           PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); | 717                     PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); | 
| 718 »       »           LOG_ERROR_OR_EXIT(log,issuerCert,count+1,flags); | 718                     LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, flags); | 
| 719 »       »       } | 719                 } | 
| 720 »           } else { | 720             } else { | 
| 721                 /* Check if we have any valid trust when cheching for | 721                 /* Check if we have any valid trust when cheching for | 
| 722                  * certUsageAnyCA or certUsageStatusResponder. */ | 722                  * certUsageAnyCA or certUsageStatusResponder. */ | 
| 723                 for (trustType = trustSSL; trustType < trustTypeNone; | 723                 for (trustType = trustSSL; trustType < trustTypeNone; | 
| 724                      trustType++) { | 724                      trustType++) { | 
| 725                     flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType); | 725                     flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType); | 
| 726                     if ((flags & requiredFlags) == requiredFlags) { | 726                     if ((flags & requiredFlags) == requiredFlags) { | 
| 727 »                       rv = rvFinal; | 727                         rv = rvFinal; | 
| 728 »                       goto done; | 728                         goto done; | 
| 729                     } | 729                     } | 
| 730                     if (flags & CERTDB_VALID_CA) | 730                     if (flags & CERTDB_VALID_CA) | 
| 731                         validCAOverride = PR_TRUE; | 731                         validCAOverride = PR_TRUE; | 
| 732                 } | 732                 } | 
| 733 »       »       /* We have 2 separate loops because we want any single trust | 733                 /* We have 2 separate loops because we want any single trust | 
| 734 »       »        * bit to allow this usage to return trusted. Only if none of | 734                  * bit to allow this usage to return trusted. Only if none of | 
| 735 »       »        * the trust bits are on do we check to see if the cert is | 735                  * the trust bits are on do we check to see if the cert is | 
| 736 »       »        * untrusted */ | 736                  * untrusted */ | 
| 737                 for (trustType = trustSSL; trustType < trustTypeNone; | 737                 for (trustType = trustSSL; trustType < trustTypeNone; | 
| 738                      trustType++) { | 738                      trustType++) { | 
| 739                     flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType); | 739                     flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType); | 
| 740 »       »           /* is it explicitly distrusted? */ | 740                     /* is it explicitly distrusted? */ | 
| 741 »       »           if ((flags & CERTDB_TERMINAL_RECORD) && | 741                     if ((flags & CERTDB_TERMINAL_RECORD) && | 
| 742 »       »       »       ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) { | 742                         ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0)) { | 
| 743 »       »       »       /* untrusted -- the cert is explicitly untrusted, not | 743                         /* untrusted -- the cert is explicitly untrusted, not | 
| 744 »       »       »        * just that it doesn't chain to a trusted cert */ | 744                          * just that it doesn't chain to a trusted cert */ | 
| 745 »       »       »       PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); | 745                         PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); | 
| 746 »       »       »       LOG_ERROR_OR_EXIT(log,issuerCert,count+1,flags); | 746                         LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, flags); | 
| 747 »       »           } | 747                     } | 
| 748                 } | 748                 } | 
| 749             } | 749             } | 
| 750         } | 750         } | 
| 751 | 751 | 
| 752 »       if (!validCAOverride) { | 752         if (!validCAOverride) { | 
| 753 »           /* | 753             /* | 
| 754 »            * Make sure that if this is an intermediate CA in the chain that | 754              * Make sure that if this is an intermediate CA in the chain that | 
| 755 »            * it was given permission by its signer to be a CA. | 755              * it was given permission by its signer to be a CA. | 
| 756 »            */ | 756              */ | 
| 757 »           /* | 757             /* | 
| 758 »            * if basicConstraints says it is a ca, then we check the | 758              * if basicConstraints says it is a ca, then we check the | 
| 759 »            * nsCertType.  If the nsCertType has any CA bits set, then | 759              * nsCertType.  If the nsCertType has any CA bits set, then | 
| 760 »            * it must have the right one. | 760              * it must have the right one. | 
| 761 »            */ | 761              */ | 
| 762 »           if (!isca || (issuerCert->nsCertType & NS_CERT_TYPE_CA)) { | 762             if (!isca || (issuerCert->nsCertType & NS_CERT_TYPE_CA)) { | 
| 763 »       »       isca = (issuerCert->nsCertType & caCertType) ? PR_TRUE : PR_FALS
      E; | 763                 isca = (issuerCert->nsCertType & caCertType) ? PR_TRUE : PR_FALS
      E; | 
| 764 »           } | 764             } | 
| 765 » |  | 
| 766 »           if (  !isca  ) { |  | 
| 767 »       »       PORT_SetError(SEC_ERROR_CA_CERT_INVALID); |  | 
| 768 »       »       LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0); |  | 
| 769 »           } |  | 
| 770 | 765 | 
| 771 »           /* make sure key usage allows cert signing */ | 766             if (!isca) { | 
| 772 »           if (CERT_CheckKeyUsage(issuerCert, requiredCAKeyUsage) != SECSuccess
      ) { | 767                 PORT_SetError(SEC_ERROR_CA_CERT_INVALID); | 
| 773 »       »       PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); | 768                 LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, 0); | 
| 774 »       »       LOG_ERROR_OR_EXIT(log,issuerCert,count+1,requiredCAKeyUsage); | 769             } | 
| 775 »           } |  | 
| 776 »       } |  | 
| 777 | 770 | 
| 778 »       /* make sure that the issuer is not self signed.  If it is, then | 771             /* make sure key usage allows cert signing */ | 
| 779 »        * stop here to prevent looping. | 772             if (CERT_CheckKeyUsage(issuerCert, requiredCAKeyUsage) != SECSuccess
      ) { | 
| 780 »        */ | 773                 PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); | 
| 781 »       if (issuerCert->isRoot) { | 774                 LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, requiredCAKeyUsage
      ); | 
| 782 »           PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); | 775             } | 
| 783 »           LOG_ERROR(log, issuerCert, count+1, 0); | 776         } | 
| 784 »           goto loser; |  | 
| 785 »       } |  | 
| 786 »       /* The issuer cert will be the subject cert in the next loop. |  | 
| 787 »        * A cert is self-issued if its subject and issuer are equal and |  | 
| 788 »        * both are of non-zero length. |  | 
| 789 »        */ |  | 
| 790 »       subjectCertIsSelfIssued = (PRBool) |  | 
| 791 »           SECITEM_ItemsAreEqual(&issuerCert->derIssuer, |  | 
| 792 »       »       »       »         &issuerCert->derSubject) && |  | 
| 793 »           issuerCert->derSubject.len > 0; |  | 
| 794 »       if (subjectCertIsSelfIssued == PR_FALSE) { |  | 
| 795 »           /* RFC 3280 says only non-self-issued intermediate CA certs |  | 
| 796 »            * count in path length. |  | 
| 797 »            */ |  | 
| 798 »           ++currentPathLen; |  | 
| 799 »       } |  | 
| 800 | 777 | 
| 801 »       CERT_DestroyCertificate(subjectCert); | 778         /* make sure that the issuer is not self signed.  If it is, then | 
| 802 »       subjectCert = issuerCert; | 779          * stop here to prevent looping. | 
| 803 »       issuerCert = NULL; | 780          */ | 
|  | 781         if (issuerCert->isRoot) { | 
|  | 782             PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); | 
|  | 783             LOG_ERROR(log, issuerCert, count + 1, 0); | 
|  | 784             goto loser; | 
|  | 785         } | 
|  | 786         /* The issuer cert will be the subject cert in the next loop. | 
|  | 787          * A cert is self-issued if its subject and issuer are equal and | 
|  | 788          * both are of non-zero length. | 
|  | 789          */ | 
|  | 790         subjectCertIsSelfIssued = (PRBool) | 
|  | 791                                       SECITEM_ItemsAreEqual(&issuerCert->derIssu
      er, | 
|  | 792                                                             &issuerCert->derSubj
      ect) && | 
|  | 793                                   issuerCert->derSubject.len > | 
|  | 794                                       0; | 
|  | 795         if (subjectCertIsSelfIssued == PR_FALSE) { | 
|  | 796             /* RFC 3280 says only non-self-issued intermediate CA certs | 
|  | 797              * count in path length. | 
|  | 798              */ | 
|  | 799             ++currentPathLen; | 
|  | 800         } | 
|  | 801 | 
|  | 802         CERT_DestroyCertificate(subjectCert); | 
|  | 803         subjectCert = issuerCert; | 
|  | 804         issuerCert = NULL; | 
| 804     } | 805     } | 
| 805 | 806 | 
| 806     PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); | 807     PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); | 
| 807     LOG_ERROR(log,subjectCert,count,0); | 808     LOG_ERROR(log, subjectCert, count, 0); | 
| 808 loser: | 809 loser: | 
| 809     rv = SECFailure; | 810     rv = SECFailure; | 
| 810 done: | 811 done: | 
| 811     if (certsList != NULL) { | 812     if (certsList != NULL) { | 
| 812 »       PORT_Free(certsList); | 813         PORT_Free(certsList); | 
| 813     } | 814     } | 
| 814     if ( issuerCert ) { | 815     if (issuerCert) { | 
| 815 »       CERT_DestroyCertificate(issuerCert); | 816         CERT_DestroyCertificate(issuerCert); | 
| 816     } |  | 
| 817 |  | 
| 818     if ( subjectCert ) { |  | 
| 819 »       CERT_DestroyCertificate(subjectCert); |  | 
| 820     } | 817     } | 
| 821 | 818 | 
| 822     if ( arena != NULL ) { | 819     if (subjectCert) { | 
| 823 »       PORT_FreeArena(arena, PR_FALSE); | 820         CERT_DestroyCertificate(subjectCert); | 
|  | 821     } | 
|  | 822 | 
|  | 823     if (arena != NULL) { | 
|  | 824         PORT_FreeArena(arena, PR_FALSE); | 
| 824     } | 825     } | 
| 825     return rv; | 826     return rv; | 
| 826 } | 827 } | 
| 827 | 828 | 
| 828 SECStatus | 829 SECStatus | 
| 829 cert_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, | 830 cert_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, | 
| 830                      PRBool checkSig, PRBool* sigerror, | 831                      PRBool checkSig, PRBool *sigerror, | 
| 831                      SECCertUsage certUsage, PRTime t, void *wincx, | 832                      SECCertUsage certUsage, PRTime t, void *wincx, | 
| 832                      CERTVerifyLog *log, PRBool* revoked) | 833                      CERTVerifyLog *log, PRBool *revoked) | 
| 833 { | 834 { | 
| 834     if (CERT_GetUsePKIXForValidation()) { | 835     if (CERT_GetUsePKIXForValidation()) { | 
| 835         return cert_VerifyCertChainPkix(cert, checkSig, certUsage, t, | 836         return cert_VerifyCertChainPkix(cert, checkSig, certUsage, t, | 
| 836                                         wincx, log, sigerror, revoked); | 837                                         wincx, log, sigerror, revoked); | 
| 837     } | 838     } | 
| 838     return cert_VerifyCertChainOld(handle, cert, checkSig, sigerror, | 839     return cert_VerifyCertChainOld(handle, cert, checkSig, sigerror, | 
| 839                                    certUsage, t, wincx, log, revoked); | 840                                    certUsage, t, wincx, log, revoked); | 
| 840 } | 841 } | 
| 841 | 842 | 
| 842 SECStatus | 843 SECStatus | 
| 843 CERT_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, | 844 CERT_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, | 
| 844 »       »            PRBool checkSig, SECCertUsage certUsage, PRTime t, | 845                      PRBool checkSig, SECCertUsage certUsage, PRTime t, | 
| 845 »       »            void *wincx, CERTVerifyLog *log) | 846                      void *wincx, CERTVerifyLog *log) | 
| 846 { | 847 { | 
| 847     return cert_VerifyCertChain(handle, cert, checkSig, NULL, certUsage, t, | 848     return cert_VerifyCertChain(handle, cert, checkSig, NULL, certUsage, t, | 
| 848 »       »       »        wincx, log, NULL); | 849                                 wincx, log, NULL); | 
| 849 } | 850 } | 
| 850 | 851 | 
| 851 /* | 852 /* | 
| 852  * verify that a CA can sign a certificate with the requested usage. | 853  * verify that a CA can sign a certificate with the requested usage. | 
| 853  */ | 854  */ | 
| 854 SECStatus | 855 SECStatus | 
| 855 CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert, | 856 CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert, | 
| 856 »       »       PRBool checkSig, SECCertUsage certUsage, PRTime t, | 857                           PRBool checkSig, SECCertUsage certUsage, PRTime t, | 
| 857 »       »       void *wincx, CERTVerifyLog *log) | 858                           void *wincx, CERTVerifyLog *log) | 
| 858 { | 859 { | 
| 859     SECTrustType trustType; | 860     SECTrustType trustType; | 
| 860     CERTBasicConstraints basicConstraint; | 861     CERTBasicConstraints basicConstraint; | 
| 861     PRBool isca; | 862     PRBool isca; | 
| 862     PRBool validCAOverride = PR_FALSE; | 863     PRBool validCAOverride = PR_FALSE; | 
| 863     SECStatus rv; | 864     SECStatus rv; | 
| 864     SECStatus rvFinal = SECSuccess; | 865     SECStatus rvFinal = SECSuccess; | 
| 865     unsigned int flags; | 866     unsigned int flags; | 
| 866     unsigned int caCertType; | 867     unsigned int caCertType; | 
| 867     unsigned int requiredCAKeyUsage; | 868     unsigned int requiredCAKeyUsage; | 
| 868     unsigned int requiredFlags; | 869     unsigned int requiredFlags; | 
| 869     CERTCertificate *issuerCert; | 870     CERTCertificate *issuerCert; | 
| 870     CERTCertTrust certTrust; | 871     CERTCertTrust certTrust; | 
| 871 | 872 | 
| 872 |  | 
| 873     if (CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_TRUE, | 873     if (CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_TRUE, | 
| 874 »       »       »       »       »        &requiredCAKeyUsage, | 874                                          &requiredCAKeyUsage, | 
| 875 »       »       »       »       »        &caCertType) != SECSuccess ) { | 875                                          &caCertType) != SECSuccess) { | 
| 876 »       PORT_Assert(0); | 876         PORT_Assert(0); | 
| 877 »       EXIT_IF_NOT_LOGGING(log); | 877         EXIT_IF_NOT_LOGGING(log); | 
| 878 »       requiredCAKeyUsage = 0; | 878         requiredCAKeyUsage = 0; | 
| 879 »       caCertType = 0; | 879         caCertType = 0; | 
| 880     } | 880     } | 
| 881 | 881 | 
| 882     switch ( certUsage ) { | 882     switch (certUsage) { | 
| 883       case certUsageSSLClient: | 883         case certUsageSSLClient: | 
| 884       case certUsageSSLServer: | 884         case certUsageSSLServer: | 
| 885       case certUsageSSLCA: | 885         case certUsageSSLCA: | 
| 886       case certUsageSSLServerWithStepUp: | 886         case certUsageSSLServerWithStepUp: | 
| 887       case certUsageEmailSigner: | 887         case certUsageEmailSigner: | 
| 888       case certUsageEmailRecipient: | 888         case certUsageEmailRecipient: | 
| 889       case certUsageObjectSigner: | 889         case certUsageObjectSigner: | 
| 890       case certUsageVerifyCA: | 890         case certUsageVerifyCA: | 
| 891       case certUsageStatusResponder: | 891         case certUsageStatusResponder: | 
| 892 »       if ( CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, | 892             if (CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, | 
| 893 »       »       »       »       »          &trustType) != SECSuccess ) { | 893                                               &trustType) != SECSuccess) { | 
| 894 »           PORT_Assert(0); | 894                 PORT_Assert(0); | 
| 895 »           EXIT_IF_NOT_LOGGING(log); | 895                 EXIT_IF_NOT_LOGGING(log); | 
| 896 »           requiredFlags = 0; | 896                 requiredFlags = 0; | 
| 897 »           trustType = trustSSL; | 897                 trustType = trustSSL; | 
| 898 »       } | 898             } | 
| 899 »       break; | 899             break; | 
| 900       default: | 900         default: | 
| 901 »       PORT_Assert(0); | 901             PORT_Assert(0); | 
| 902 »       EXIT_IF_NOT_LOGGING(log); | 902             EXIT_IF_NOT_LOGGING(log); | 
| 903 »       requiredFlags = 0; | 903             requiredFlags = 0; | 
| 904 »       trustType = trustSSL;/* This used to be 0, but we need something | 904             trustType = trustSSL; /* This used to be 0, but we need something | 
| 905 »       »       »             * that matches the enumeration type. | 905                                    * that matches the enumeration type. | 
| 906 »       »       »             */ | 906                                    */ | 
| 907 »       caCertType = 0; | 907             caCertType = 0; | 
| 908     } | 908     } | 
| 909 | 909 | 
| 910     /* If the basicConstraint extension is included in an intermmediate CA | 910     /* If the basicConstraint extension is included in an intermmediate CA | 
| 911      * certificate, make sure that the isCA flag is on.  If the | 911      * certificate, make sure that the isCA flag is on.  If the | 
| 912      * pathLenConstraint component exists, it must be greater than the | 912      * pathLenConstraint component exists, it must be greater than the | 
| 913      * number of CA certificates we have seen so far.  If the extension | 913      * number of CA certificates we have seen so far.  If the extension | 
| 914      * is omitted, we will assume that this is a CA certificate with | 914      * is omitted, we will assume that this is a CA certificate with | 
| 915      * an unlimited pathLenConstraint (since it already passes the | 915      * an unlimited pathLenConstraint (since it already passes the | 
| 916      * netscape-cert-type extension checking). | 916      * netscape-cert-type extension checking). | 
| 917      */ | 917      */ | 
| 918 | 918 | 
| 919     rv = CERT_FindBasicConstraintExten(cert, &basicConstraint); | 919     rv = CERT_FindBasicConstraintExten(cert, &basicConstraint); | 
| 920     if ( rv != SECSuccess ) { | 920     if (rv != SECSuccess) { | 
| 921 »       if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { | 921         if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { | 
| 922 »           LOG_ERROR_OR_EXIT(log,cert,0,0); | 922             LOG_ERROR_OR_EXIT(log, cert, 0, 0); | 
| 923 »       } | 923         } | 
| 924 »       /* no basic constraints found, we aren't (yet) a CA. */ | 924         /* no basic constraints found, we aren't (yet) a CA. */ | 
| 925 »       isca = PR_FALSE; | 925         isca = PR_FALSE; | 
| 926     } else  { | 926     } else { | 
| 927 »       if ( basicConstraint.isCA == PR_FALSE ) { | 927         if (basicConstraint.isCA == PR_FALSE) { | 
| 928 »           PORT_SetError (SEC_ERROR_CA_CERT_INVALID); | 928             PORT_SetError(SEC_ERROR_CA_CERT_INVALID); | 
| 929 »           LOG_ERROR_OR_EXIT(log,cert,0,0); | 929             LOG_ERROR_OR_EXIT(log, cert, 0, 0); | 
| 930 »       } | 930         } | 
| 931 | 931 | 
| 932 »       /* can't check path length if we don't know the previous path */ | 932         /* can't check path length if we don't know the previous path */ | 
| 933 »       isca = PR_TRUE; | 933         isca = PR_TRUE; | 
| 934     } | 934     } | 
| 935 » | 935 | 
| 936     if ( CERT_GetCertTrust(cert, &certTrust) == SECSuccess ) { | 936     if (CERT_GetCertTrust(cert, &certTrust) == SECSuccess) { | 
| 937 »       /* we have some trust info, but this does NOT imply that this | 937         /* we have some trust info, but this does NOT imply that this | 
| 938 »        * cert is actually trusted for any purpose.  The cert may be | 938          * cert is actually trusted for any purpose.  The cert may be | 
| 939 »        * explicitly UNtrusted.  We won't know until we examine the | 939          * explicitly UNtrusted.  We won't know until we examine the | 
| 940 »        * trust bits. | 940          * trust bits. | 
| 941 »        */ | 941          */ | 
| 942         if (certUsage == certUsageStatusResponder) { | 942         if (certUsage == certUsageStatusResponder) { | 
| 943 »           /* Check the special case of certUsageStatusResponder */ | 943             /* Check the special case of certUsageStatusResponder */ | 
| 944             issuerCert = CERT_FindCertIssuer(cert, t, certUsage); | 944             issuerCert = CERT_FindCertIssuer(cert, t, certUsage); | 
| 945             if (issuerCert) { | 945             if (issuerCert) { | 
| 946                 if (SEC_CheckCRL(handle, cert, issuerCert, t, wincx) | 946                 if (SEC_CheckCRL(handle, cert, issuerCert, t, wincx) != | 
| 947 »       »           != SECSuccess) { | 947                     SECSuccess) { | 
| 948                     PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); | 948                     PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); | 
| 949                     CERT_DestroyCertificate(issuerCert); | 949                     CERT_DestroyCertificate(issuerCert); | 
| 950                     goto loser; | 950                     goto loser; | 
| 951                 } | 951                 } | 
| 952                 CERT_DestroyCertificate(issuerCert); | 952                 CERT_DestroyCertificate(issuerCert); | 
| 953             } | 953             } | 
| 954 »           /* XXX We have NOT determined that this cert is trusted. | 954             /* XXX We have NOT determined that this cert is trusted. | 
| 955 »            * For years, NSS has treated this as trusted, | 955              * For years, NSS has treated this as trusted, | 
| 956 »            * but it seems incorrect. | 956              * but it seems incorrect. | 
| 957 »            */ | 957              */ | 
| 958 »           rv = rvFinal; | 958             rv = rvFinal; | 
| 959 »           goto done; | 959             goto done; | 
| 960         } | 960         } | 
| 961 | 961 | 
| 962 »       /* | 962         /* | 
| 963 »        * check the trust params of the issuer | 963          * check the trust params of the issuer | 
| 964 »        */ | 964          */ | 
| 965 »       flags = SEC_GET_TRUST_FLAGS(&certTrust, trustType); | 965         flags = SEC_GET_TRUST_FLAGS(&certTrust, trustType); | 
| 966 »       if ( ( flags & requiredFlags ) == requiredFlags) { | 966         if ((flags & requiredFlags) == requiredFlags) { | 
| 967 »           /* we found a trusted one, so return */ | 967             /* we found a trusted one, so return */ | 
| 968 »           rv = rvFinal; | 968             rv = rvFinal; | 
| 969 »           goto done; | 969             goto done; | 
| 970 »       } | 970         } | 
| 971 »       if (flags & CERTDB_VALID_CA) { | 971         if (flags & CERTDB_VALID_CA) { | 
| 972 »           validCAOverride = PR_TRUE; | 972             validCAOverride = PR_TRUE; | 
| 973 »       } | 973         } | 
| 974 »       /* is it explicitly distrusted? */ | 974         /* is it explicitly distrusted? */ | 
| 975 »       if ((flags & CERTDB_TERMINAL_RECORD) && | 975         if ((flags & CERTDB_TERMINAL_RECORD) && | 
| 976 »       »       ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) { | 976             ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0)) { | 
| 977 »           /* untrusted -- the cert is explicitly untrusted, not | 977             /* untrusted -- the cert is explicitly untrusted, not | 
| 978 »            * just that it doesn't chain to a trusted cert */ | 978              * just that it doesn't chain to a trusted cert */ | 
| 979 »           PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); | 979             PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); | 
| 980 »           LOG_ERROR_OR_EXIT(log,cert,0,flags); | 980             LOG_ERROR_OR_EXIT(log, cert, 0, flags); | 
| 981 »       } | 981         } | 
| 982     } | 982     } | 
| 983     if (!validCAOverride) { | 983     if (!validCAOverride) { | 
| 984 »       /* | 984         /* | 
| 985 »        * Make sure that if this is an intermediate CA in the chain that | 985          * Make sure that if this is an intermediate CA in the chain that | 
| 986 »        * it was given permission by its signer to be a CA. | 986          * it was given permission by its signer to be a CA. | 
| 987 »        */ | 987          */ | 
| 988 »       /* | 988         /* | 
| 989 »        * if basicConstraints says it is a ca, then we check the | 989          * if basicConstraints says it is a ca, then we check the | 
| 990 »        * nsCertType.  If the nsCertType has any CA bits set, then | 990          * nsCertType.  If the nsCertType has any CA bits set, then | 
| 991 »        * it must have the right one. | 991          * it must have the right one. | 
| 992 »        */ | 992          */ | 
| 993 »       if (!isca || (cert->nsCertType & NS_CERT_TYPE_CA)) { | 993         if (!isca || (cert->nsCertType & NS_CERT_TYPE_CA)) { | 
| 994 »           isca = (cert->nsCertType & caCertType) ? PR_TRUE : PR_FALSE; | 994             isca = (cert->nsCertType & caCertType) ? PR_TRUE : PR_FALSE; | 
| 995 »       } | 995         } | 
| 996 » | 996 | 
| 997 »       if (!isca) { | 997         if (!isca) { | 
| 998 »           PORT_SetError(SEC_ERROR_CA_CERT_INVALID); | 998             PORT_SetError(SEC_ERROR_CA_CERT_INVALID); | 
| 999 »           LOG_ERROR_OR_EXIT(log,cert,0,0); | 999             LOG_ERROR_OR_EXIT(log, cert, 0, 0); | 
| 1000 »       } | 1000         } | 
| 1001 » | 1001 | 
| 1002 »       /* make sure key usage allows cert signing */ | 1002         /* make sure key usage allows cert signing */ | 
| 1003 »       if (CERT_CheckKeyUsage(cert, requiredCAKeyUsage) != SECSuccess) { | 1003         if (CERT_CheckKeyUsage(cert, requiredCAKeyUsage) != SECSuccess) { | 
| 1004 »           PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); | 1004             PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); | 
| 1005 »           LOG_ERROR_OR_EXIT(log,cert,0,requiredCAKeyUsage); | 1005             LOG_ERROR_OR_EXIT(log, cert, 0, requiredCAKeyUsage); | 
| 1006 »       } | 1006         } | 
| 1007     } | 1007     } | 
| 1008     /* make sure that the issuer is not self signed.  If it is, then | 1008     /* make sure that the issuer is not self signed.  If it is, then | 
| 1009      * stop here to prevent looping. | 1009      * stop here to prevent looping. | 
| 1010      */ | 1010      */ | 
| 1011     if (cert->isRoot) { | 1011     if (cert->isRoot) { | 
| 1012 »           PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); | 1012         PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); | 
| 1013 »           LOG_ERROR(log, cert, 0, 0); | 1013         LOG_ERROR(log, cert, 0, 0); | 
| 1014 »           goto loser; | 1014         goto loser; | 
| 1015     } | 1015     } | 
| 1016 | 1016 | 
| 1017     return CERT_VerifyCertChain(handle, cert, checkSig, certUsage, t, | 1017     return CERT_VerifyCertChain(handle, cert, checkSig, certUsage, t, | 
| 1018 »       »            »  »       »       »       »       wincx, log); | 1018                                 wincx, log); | 
| 1019 loser: | 1019 loser: | 
| 1020     rv = SECFailure; | 1020     rv = SECFailure; | 
| 1021 done: | 1021 done: | 
| 1022     return rv; | 1022     return rv; | 
| 1023 } | 1023 } | 
| 1024 | 1024 | 
| 1025 #define NEXT_USAGE() { \ | 1025 #define NEXT_USAGE() \ | 
| 1026     i*=2; \ | 1026     {                \ | 
| 1027     certUsage++; \ | 1027         i *= 2;      \ | 
| 1028     continue; \ | 1028         certUsage++; \ | 
| 1029 } | 1029         continue;    \ | 
|  | 1030     } | 
| 1030 | 1031 | 
| 1031 #define VALID_USAGE() { \ | 1032 #define VALID_USAGE() \ | 
| 1032     NEXT_USAGE(); \ | 1033     {                 \ | 
| 1033 } | 1034         NEXT_USAGE(); \ | 
|  | 1035     } | 
| 1034 | 1036 | 
| 1035 #define INVALID_USAGE() { \ | 1037 #define INVALID_USAGE()                 \ | 
| 1036     if (returnedUsages) { \ | 1038     {                                   \ | 
| 1037         *returnedUsages &= (~i); \ | 1039         if (returnedUsages) {           \ | 
| 1038     } \ | 1040             *returnedUsages &= (~i);    \ | 
| 1039     if (PR_TRUE == requiredUsage) { \ | 1041         }                               \ | 
| 1040         valid = SECFailure; \ | 1042         if (PR_TRUE == requiredUsage) { \ | 
| 1041     } \ | 1043             valid = SECFailure;         \ | 
| 1042     NEXT_USAGE(); \ | 1044         }                               \ | 
| 1043 } | 1045         NEXT_USAGE();                   \ | 
|  | 1046     } | 
| 1044 | 1047 | 
| 1045 /* | 1048 /* | 
| 1046  * check the leaf cert against trust and usage. | 1049  * check the leaf cert against trust and usage. | 
| 1047  *   returns success if the cert is not distrusted. If the cert is | 1050  *   returns success if the cert is not distrusted. If the cert is | 
| 1048  *       trusted, then the trusted bool will be true. | 1051  *       trusted, then the trusted bool will be true. | 
| 1049  *   returns failure if the cert is distrusted. If failure, flags | 1052  *   returns failure if the cert is distrusted. If failure, flags | 
| 1050  *       will return the flag bits that indicated distrust. | 1053  *       will return the flag bits that indicated distrust. | 
| 1051  */ | 1054  */ | 
| 1052 SECStatus | 1055 SECStatus | 
| 1053 cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage, | 1056 cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage, | 
| 1054 »                   unsigned int *failedFlags, PRBool *trusted) | 1057                     unsigned int *failedFlags, PRBool *trusted) | 
| 1055 { | 1058 { | 
| 1056     unsigned int flags; | 1059     unsigned int flags; | 
| 1057     CERTCertTrust trust; | 1060     CERTCertTrust trust; | 
| 1058 | 1061 | 
| 1059     *failedFlags = 0; | 1062     *failedFlags = 0; | 
| 1060     *trusted = PR_FALSE; | 1063     *trusted = PR_FALSE; | 
| 1061 »       »       » | 1064 | 
| 1062     /* check trust flags to see if this cert is directly trusted */ | 1065     /* check trust flags to see if this cert is directly trusted */ | 
| 1063     if ( CERT_GetCertTrust(cert, &trust) == SECSuccess ) { | 1066     if (CERT_GetCertTrust(cert, &trust) == SECSuccess) { | 
| 1064 »       switch ( certUsage ) { | 1067         switch (certUsage) { | 
| 1065 »         case certUsageSSLClient: | 1068             case certUsageSSLClient: | 
| 1066 »         case certUsageSSLServer: | 1069             case certUsageSSLServer: | 
| 1067 »           flags = trust.sslFlags; | 1070                 flags = trust.sslFlags; | 
| 1068 » |  | 
| 1069 »           /* is the cert directly trusted or not trusted ? */ |  | 
| 1070 »           if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is |  | 
| 1071 »       »       »       »       »       »           * authoritative */ |  | 
| 1072 »       »       if ( flags & CERTDB_TRUSTED ) {»/* trust this cert */ |  | 
| 1073 »       »           *trusted = PR_TRUE; |  | 
| 1074 »       »           return SECSuccess; |  | 
| 1075 »       »       } else { /* don't trust this cert */ |  | 
| 1076 »       »           *failedFlags = flags; |  | 
| 1077 »       »           return SECFailure; |  | 
| 1078 »       »       } |  | 
| 1079 »           } |  | 
| 1080 »           break; |  | 
| 1081 »         case certUsageSSLServerWithStepUp: |  | 
| 1082 »           /* XXX - step up certs can't be directly trusted, only distrust */ |  | 
| 1083 »           flags = trust.sslFlags; |  | 
| 1084 »           if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is |  | 
| 1085 »       »       »       »       »       »           * authoritative */ |  | 
| 1086 »       »       if (( flags & CERTDB_TRUSTED ) == 0) {» |  | 
| 1087 »       »           /* don't trust this cert */ |  | 
| 1088 »       »           *failedFlags = flags; |  | 
| 1089 »       »           return SECFailure; |  | 
| 1090 »       »       } |  | 
| 1091 »           } |  | 
| 1092 »           break; |  | 
| 1093 »         case certUsageSSLCA: |  | 
| 1094 »           flags = trust.sslFlags; |  | 
| 1095 »           if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is |  | 
| 1096 »       »       »       »       »       »           * authoritative */ |  | 
| 1097 »       »       if (( flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA) ) == 0) {» |  | 
| 1098 »       »           /* don't trust this cert */ |  | 
| 1099 »       »           *failedFlags = flags; |  | 
| 1100 »       »           return SECFailure; |  | 
| 1101 »       »       } |  | 
| 1102 »           } |  | 
| 1103 »           break; |  | 
| 1104 »         case certUsageEmailSigner: |  | 
| 1105 »         case certUsageEmailRecipient: |  | 
| 1106 »           flags = trust.emailFlags; |  | 
| 1107 »           if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is |  | 
| 1108 »       »       »       »       »       »           * authoritative */ |  | 
| 1109 »       »       if ( flags & CERTDB_TRUSTED ) {»/* trust this cert */ |  | 
| 1110 »       »           *trusted = PR_TRUE; |  | 
| 1111 »       »           return SECSuccess; |  | 
| 1112 »       »       } |  | 
| 1113 »       »       else { /* don't trust this cert */ |  | 
| 1114 »       »           *failedFlags = flags; |  | 
| 1115 »       »           return SECFailure; |  | 
| 1116 »       »       } |  | 
| 1117 »           } |  | 
| 1118 » |  | 
| 1119 »           break; |  | 
| 1120 »         case certUsageObjectSigner: |  | 
| 1121 »           flags = trust.objectSigningFlags; |  | 
| 1122 | 1071 | 
| 1123 »           if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is | 1072                 /* is the cert directly trusted or not trusted ? */ | 
| 1124 »       »       »       »       »       »           * authoritative */ | 1073                 if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is | 
| 1125 »       »       if ( flags & CERTDB_TRUSTED ) {»/* trust this cert */ | 1074                             * authoritative */ | 
| 1126 »       »           *trusted = PR_TRUE; | 1075                     if (flags & CERTDB_TRUSTED) {     /* trust this cert */ | 
| 1127 »       »           return SECSuccess; | 1076                         *trusted = PR_TRUE; | 
| 1128 »       »       } else { /* don't trust this cert */ | 1077                         return SECSuccess; | 
| 1129 »       »           *failedFlags = flags; | 1078                     } else { /* don't trust this cert */ | 
| 1130 »       »           return SECFailure; | 1079                         *failedFlags = flags; | 
| 1131 »       »       } | 1080                         return SECFailure; | 
| 1132 »           } | 1081                     } | 
| 1133 »           break; | 1082                 } | 
| 1134 »         case certUsageVerifyCA: | 1083                 break; | 
| 1135 »         case certUsageStatusResponder: | 1084             case certUsageSSLServerWithStepUp: | 
| 1136 »           flags = trust.sslFlags; | 1085                 /* XXX - step up certs can't be directly trusted, only distrust 
      */ | 
| 1137 »           /* is the cert directly trusted or not trusted ? */ | 1086                 flags = trust.sslFlags; | 
| 1138 »           if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) == | 1087                 if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is | 
| 1139 »       »       ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) { | 1088                                                        * authoritative */ | 
| 1140 »       »       *trusted = PR_TRUE; | 1089                     if ((flags & CERTDB_TRUSTED) == 0) { | 
| 1141 »       »       return SECSuccess; | 1090                         /* don't trust this cert */ | 
| 1142 »           } | 1091                         *failedFlags = flags; | 
| 1143 »           flags = trust.emailFlags; | 1092                         return SECFailure; | 
| 1144 »           /* is the cert directly trusted or not trusted ? */ | 1093                     } | 
| 1145 »           if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) == | 1094                 } | 
| 1146 »       »       ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) { | 1095                 break; | 
| 1147 »       »       *trusted = PR_TRUE; | 1096             case certUsageSSLCA: | 
| 1148 »       »       return SECSuccess; | 1097                 flags = trust.sslFlags; | 
| 1149 »           } | 1098                 if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is | 
| 1150 »           flags = trust.objectSigningFlags; | 1099                                                        * authoritative */ | 
| 1151 »           /* is the cert directly trusted or not trusted ? */ | 1100                     if ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0) { | 
| 1152 »           if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) == | 1101                         /* don't trust this cert */ | 
| 1153 »       »       ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) { | 1102                         *failedFlags = flags; | 
| 1154 »       »       *trusted = PR_TRUE; | 1103                         return SECFailure; | 
| 1155 »       »       return SECSuccess; | 1104                     } | 
| 1156 »           } | 1105                 } | 
| 1157 »           /* fall through to test distrust */ | 1106                 break; | 
| 1158 »         case certUsageAnyCA: | 1107             case certUsageEmailSigner: | 
| 1159 »         case certUsageUserCertImport: | 1108             case certUsageEmailRecipient: | 
| 1160 »           /* do we distrust these certs explicitly */ | 1109                 flags = trust.emailFlags; | 
| 1161 »           flags = trust.sslFlags; | 1110                 if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is | 
| 1162 »           if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is | 1111                                                        * authoritative */ | 
| 1163 »       »       »       »       »       »           * authoritative */ | 1112                     if (flags & CERTDB_TRUSTED) {     /* trust this cert */ | 
| 1164 »       »       if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) { | 1113                         *trusted = PR_TRUE; | 
| 1165 »       »           *failedFlags = flags; | 1114                         return SECSuccess; | 
| 1166 »       »           return SECFailure; | 1115                     } else { /* don't trust this cert */ | 
| 1167 »       »       } | 1116                         *failedFlags = flags; | 
| 1168 »           } | 1117                         return SECFailure; | 
| 1169 »           flags = trust.emailFlags; | 1118                     } | 
| 1170 »           if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is | 1119                 } | 
| 1171 »       »       »       »       »       »           * authoritative */ | 1120 | 
| 1172 »       »       if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) { | 1121                 break; | 
| 1173 »       »           *failedFlags = flags; | 1122             case certUsageObjectSigner: | 
| 1174 »       »           return SECFailure; | 1123                 flags = trust.objectSigningFlags; | 
| 1175 »       »       } | 1124 | 
| 1176 »           } | 1125                 if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is | 
| 1177 »           /* fall through */ | 1126                                                        * authoritative */ | 
| 1178 »         case certUsageProtectedObjectSigner: | 1127                     if (flags & CERTDB_TRUSTED) {     /* trust this cert */ | 
| 1179 »           flags = trust.objectSigningFlags; | 1128                         *trusted = PR_TRUE; | 
| 1180 »           if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is | 1129                         return SECSuccess; | 
| 1181 »       »       »       »       »       »           * authoritative */ | 1130                     } else { /* don't trust this cert */ | 
| 1182 »       »       if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) { | 1131                         *failedFlags = flags; | 
| 1183 »       »           *failedFlags = flags; | 1132                         return SECFailure; | 
| 1184 »       »           return SECFailure; | 1133                     } | 
| 1185 »       »       } | 1134                 } | 
| 1186 »           } | 1135                 break; | 
| 1187 »           break; | 1136             case certUsageVerifyCA: | 
| 1188 »       } | 1137             case certUsageStatusResponder: | 
|  | 1138                 flags = trust.sslFlags; | 
|  | 1139                 /* is the cert directly trusted or not trusted ? */ | 
|  | 1140                 if ((flags & (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) == | 
|  | 1141                     (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) { | 
|  | 1142                     *trusted = PR_TRUE; | 
|  | 1143                     return SECSuccess; | 
|  | 1144                 } | 
|  | 1145                 flags = trust.emailFlags; | 
|  | 1146                 /* is the cert directly trusted or not trusted ? */ | 
|  | 1147                 if ((flags & (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) == | 
|  | 1148                     (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) { | 
|  | 1149                     *trusted = PR_TRUE; | 
|  | 1150                     return SECSuccess; | 
|  | 1151                 } | 
|  | 1152                 flags = trust.objectSigningFlags; | 
|  | 1153                 /* is the cert directly trusted or not trusted ? */ | 
|  | 1154                 if ((flags & (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) == | 
|  | 1155                     (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) { | 
|  | 1156                     *trusted = PR_TRUE; | 
|  | 1157                     return SECSuccess; | 
|  | 1158                 } | 
|  | 1159                 /* fall through to test distrust */ | 
|  | 1160             case certUsageAnyCA: | 
|  | 1161             case certUsageUserCertImport: | 
|  | 1162                 /* do we distrust these certs explicitly */ | 
|  | 1163                 flags = trust.sslFlags; | 
|  | 1164                 if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is | 
|  | 1165                             * authoritative */ | 
|  | 1166                     if ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0) { | 
|  | 1167                         *failedFlags = flags; | 
|  | 1168                         return SECFailure; | 
|  | 1169                     } | 
|  | 1170                 } | 
|  | 1171                 flags = trust.emailFlags; | 
|  | 1172                 if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is | 
|  | 1173                             * authoritative */ | 
|  | 1174                     if ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0) { | 
|  | 1175                         *failedFlags = flags; | 
|  | 1176                         return SECFailure; | 
|  | 1177                     } | 
|  | 1178                 } | 
|  | 1179                 /* fall through */ | 
|  | 1180             case certUsageProtectedObjectSigner: | 
|  | 1181                 flags = trust.objectSigningFlags; | 
|  | 1182                 if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is | 
|  | 1183                                                        * authoritative */ | 
|  | 1184                     if ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0) { | 
|  | 1185                         *failedFlags = flags; | 
|  | 1186                         return SECFailure; | 
|  | 1187                     } | 
|  | 1188                 } | 
|  | 1189                 break; | 
|  | 1190         } | 
| 1189     } | 1191     } | 
| 1190     return SECSuccess; | 1192     return SECSuccess; | 
| 1191 } | 1193 } | 
| 1192 | 1194 | 
| 1193 /* | 1195 /* | 
| 1194  * verify a certificate by checking if it's valid and that we | 1196  * verify a certificate by checking if it's valid and that we | 
| 1195  * trust the issuer. | 1197  * trust the issuer. | 
| 1196  * | 1198  * | 
| 1197  * certificateUsage contains a bitfield of all cert usages that are | 1199  * certificateUsage contains a bitfield of all cert usages that are | 
| 1198  * required for verification to succeed | 1200  * required for verification to succeed | 
| 1199  * | 1201  * | 
| 1200  * a bitfield of cert usages is returned in *returnedUsages | 1202  * a bitfield of cert usages is returned in *returnedUsages | 
| 1201  * if requiredUsages is non-zero, the returned bitmap is only | 1203  * if requiredUsages is non-zero, the returned bitmap is only | 
| 1202  * for those required usages, otherwise it is for all usages | 1204  * for those required usages, otherwise it is for all usages | 
| 1203  * | 1205  * | 
| 1204  */ | 1206  */ | 
| 1205 SECStatus | 1207 SECStatus | 
| 1206 CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, | 1208 CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, | 
| 1207 »       »       PRBool checkSig, SECCertificateUsage requiredUsages, PRTime t, | 1209                        PRBool checkSig, SECCertificateUsage requiredUsages, PRTi
      me t, | 
| 1208 »       »       void *wincx, CERTVerifyLog *log, SECCertificateUsage* returnedUs
      ages) | 1210                        void *wincx, CERTVerifyLog *log, SECCertificateUsage *ret
      urnedUsages) | 
| 1209 { | 1211 { | 
| 1210     SECStatus rv; | 1212     SECStatus rv; | 
| 1211     SECStatus valid; | 1213     SECStatus valid; | 
| 1212     unsigned int requiredKeyUsage; | 1214     unsigned int requiredKeyUsage; | 
| 1213     unsigned int requiredCertType; | 1215     unsigned int requiredCertType; | 
| 1214     unsigned int flags; | 1216     unsigned int flags; | 
| 1215     unsigned int certType; | 1217     unsigned int certType; | 
| 1216     PRBool       allowOverride; | 1218     PRBool allowOverride; | 
| 1217     SECCertTimeValidity validity; | 1219     SECCertTimeValidity validity; | 
| 1218     CERTStatusConfig *statusConfig; | 1220     CERTStatusConfig *statusConfig; | 
| 1219     PRInt32 i; | 1221     PRInt32 i; | 
| 1220     SECCertUsage certUsage = 0; | 1222     SECCertUsage certUsage = 0; | 
| 1221     PRBool checkedOCSP = PR_FALSE; | 1223     PRBool checkedOCSP = PR_FALSE; | 
| 1222     PRBool checkAllUsages = PR_FALSE; | 1224     PRBool checkAllUsages = PR_FALSE; | 
| 1223     PRBool revoked = PR_FALSE; | 1225     PRBool revoked = PR_FALSE; | 
| 1224     PRBool sigerror = PR_FALSE; | 1226     PRBool sigerror = PR_FALSE; | 
| 1225     PRBool trusted = PR_FALSE; | 1227     PRBool trusted = PR_FALSE; | 
| 1226 | 1228 | 
| 1227     if (!requiredUsages) { | 1229     if (!requiredUsages) { | 
| 1228         /* there are no required usages, so the user probably wants to | 1230         /* there are no required usages, so the user probably wants to | 
| 1229            get status for all usages */ | 1231            get status for all usages */ | 
| 1230         checkAllUsages = PR_TRUE; | 1232         checkAllUsages = PR_TRUE; | 
| 1231     } | 1233     } | 
| 1232 | 1234 | 
| 1233     if (returnedUsages) { | 1235     if (returnedUsages) { | 
| 1234         *returnedUsages = 0; | 1236         *returnedUsages = 0; | 
| 1235     } else { | 1237     } else { | 
| 1236         /* we don't have a place to return status for all usages, | 1238         /* we don't have a place to return status for all usages, | 
| 1237            so we can skip checks for usages that aren't required */ | 1239            so we can skip checks for usages that aren't required */ | 
| 1238         checkAllUsages = PR_FALSE; | 1240         checkAllUsages = PR_FALSE; | 
| 1239     } | 1241     } | 
| 1240     valid = SECSuccess ; /* start off assuming cert is valid */ | 1242     valid = SECSuccess; /* start off assuming cert is valid */ | 
| 1241 | 1243 | 
| 1242     /* make sure that the cert is valid at time t */ | 1244     /* make sure that the cert is valid at time t */ | 
| 1243     allowOverride = (PRBool)((requiredUsages & certificateUsageSSLServer) || | 1245     allowOverride = (PRBool)((requiredUsages & certificateUsageSSLServer) || | 
| 1244                              (requiredUsages & certificateUsageSSLServerWithStep
      Up)); | 1246                              (requiredUsages & certificateUsageSSLServerWithStep
      Up)); | 
| 1245     validity = CERT_CheckCertValidTimes(cert, t, allowOverride); | 1247     validity = CERT_CheckCertValidTimes(cert, t, allowOverride); | 
| 1246     if ( validity != secCertTimeValid ) { | 1248     if (validity != secCertTimeValid) { | 
| 1247         valid = SECFailure; | 1249         valid = SECFailure; | 
| 1248         LOG_ERROR_OR_EXIT(log,cert,0,validity); | 1250         LOG_ERROR_OR_EXIT(log, cert, 0, validity); | 
| 1249     } | 1251     } | 
| 1250 | 1252 | 
| 1251     /* check key usage and netscape cert type */ | 1253     /* check key usage and netscape cert type */ | 
| 1252     cert_GetCertType(cert); | 1254     cert_GetCertType(cert); | 
| 1253     certType = cert->nsCertType; | 1255     certType = cert->nsCertType; | 
| 1254 | 1256 | 
| 1255     for (i=1; i<=certificateUsageHighest && | 1257     for (i = 1; i <= certificateUsageHighest && | 
| 1256               (SECSuccess == valid || returnedUsages || log) ; ) { | 1258                 (SECSuccess == valid || returnedUsages || log);) { | 
| 1257         PRBool requiredUsage = (i & requiredUsages) ? PR_TRUE : PR_FALSE; | 1259         PRBool requiredUsage = (i & requiredUsages) ? PR_TRUE : PR_FALSE; | 
| 1258         if (PR_FALSE == requiredUsage && PR_FALSE == checkAllUsages) { | 1260         if (PR_FALSE == requiredUsage && PR_FALSE == checkAllUsages) { | 
| 1259             NEXT_USAGE(); | 1261             NEXT_USAGE(); | 
| 1260         } | 1262         } | 
| 1261         if (returnedUsages) { | 1263         if (returnedUsages) { | 
| 1262             *returnedUsages |= i; /* start off assuming this usage is valid */ | 1264             *returnedUsages |= i; /* start off assuming this usage is valid */ | 
| 1263         } | 1265         } | 
| 1264         switch ( certUsage ) { | 1266         switch (certUsage) { | 
| 1265           case certUsageSSLClient: | 1267             case certUsageSSLClient: | 
| 1266           case certUsageSSLServer: | 1268             case certUsageSSLServer: | 
| 1267           case certUsageSSLServerWithStepUp: | 1269             case certUsageSSLServerWithStepUp: | 
| 1268           case certUsageSSLCA: | 1270             case certUsageSSLCA: | 
| 1269           case certUsageEmailSigner: | 1271             case certUsageEmailSigner: | 
| 1270           case certUsageEmailRecipient: | 1272             case certUsageEmailRecipient: | 
| 1271           case certUsageObjectSigner: | 1273             case certUsageObjectSigner: | 
| 1272           case certUsageStatusResponder: | 1274             case certUsageStatusResponder: | 
| 1273             rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE, | 1275                 rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE, | 
| 1274                                                   &requiredKeyUsage, | 1276                                                       &requiredKeyUsage, | 
| 1275                                                   &requiredCertType); | 1277                                                       &requiredCertType); | 
| 1276             if ( rv != SECSuccess ) { | 1278                 if (rv != SECSuccess) { | 
|  | 1279                     PORT_Assert(0); | 
|  | 1280                     /* EXIT_IF_NOT_LOGGING(log); XXX ??? */ | 
|  | 1281                     requiredKeyUsage = 0; | 
|  | 1282                     requiredCertType = 0; | 
|  | 1283                     INVALID_USAGE(); | 
|  | 1284                 } | 
|  | 1285                 break; | 
|  | 1286 | 
|  | 1287             case certUsageAnyCA: | 
|  | 1288             case certUsageProtectedObjectSigner: | 
|  | 1289             case certUsageUserCertImport: | 
|  | 1290             case certUsageVerifyCA: | 
|  | 1291                 /* these usages cannot be verified */ | 
|  | 1292                 NEXT_USAGE(); | 
|  | 1293 | 
|  | 1294             default: | 
| 1277                 PORT_Assert(0); | 1295                 PORT_Assert(0); | 
| 1278                 /* EXIT_IF_NOT_LOGGING(log); XXX ??? */ |  | 
| 1279                 requiredKeyUsage = 0; | 1296                 requiredKeyUsage = 0; | 
| 1280                 requiredCertType = 0; | 1297                 requiredCertType = 0; | 
| 1281                 INVALID_USAGE(); | 1298                 INVALID_USAGE(); | 
| 1282             } |  | 
| 1283             break; |  | 
| 1284 |  | 
| 1285           case certUsageAnyCA: |  | 
| 1286           case certUsageProtectedObjectSigner: |  | 
| 1287           case certUsageUserCertImport: |  | 
| 1288           case certUsageVerifyCA: |  | 
| 1289               /* these usages cannot be verified */ |  | 
| 1290               NEXT_USAGE(); |  | 
| 1291 |  | 
| 1292           default: |  | 
| 1293             PORT_Assert(0); |  | 
| 1294             requiredKeyUsage = 0; |  | 
| 1295             requiredCertType = 0; |  | 
| 1296             INVALID_USAGE(); |  | 
| 1297         } | 1299         } | 
| 1298         if ( CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess ) { | 1300         if (CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess) { | 
| 1299             if (PR_TRUE == requiredUsage) { | 1301             if (PR_TRUE == requiredUsage) { | 
| 1300                 PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); | 1302                 PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); | 
| 1301             } | 1303             } | 
| 1302             LOG_ERROR(log,cert,0,requiredKeyUsage); | 1304             LOG_ERROR(log, cert, 0, requiredKeyUsage); | 
| 1303             INVALID_USAGE(); | 1305             INVALID_USAGE(); | 
| 1304         } | 1306         } | 
| 1305         if ( !( certType & requiredCertType ) ) { | 1307         if (!(certType & requiredCertType)) { | 
| 1306             if (PR_TRUE == requiredUsage) { | 1308             if (PR_TRUE == requiredUsage) { | 
| 1307                 PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE); | 1309                 PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE); | 
| 1308             } | 1310             } | 
| 1309             LOG_ERROR(log,cert,0,requiredCertType); | 1311             LOG_ERROR(log, cert, 0, requiredCertType); | 
| 1310             INVALID_USAGE(); | 1312             INVALID_USAGE(); | 
| 1311         } | 1313         } | 
| 1312 | 1314 | 
| 1313 »       rv = cert_CheckLeafTrust(cert, certUsage, &flags, &trusted); | 1315         rv = cert_CheckLeafTrust(cert, certUsage, &flags, &trusted); | 
| 1314 »       if (rv == SECFailure) { | 1316         if (rv == SECFailure) { | 
| 1315 »           if (PR_TRUE == requiredUsage) { | 1317             if (PR_TRUE == requiredUsage) { | 
| 1316 »       »       PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); | 1318                 PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); | 
| 1317 »           } | 1319             } | 
| 1318 »           LOG_ERROR(log, cert, 0, flags); | 1320             LOG_ERROR(log, cert, 0, flags); | 
| 1319 »           INVALID_USAGE(); | 1321             INVALID_USAGE(); | 
| 1320 »       } else if (trusted) { | 1322         } else if (trusted) { | 
| 1321 »           VALID_USAGE(); | 1323             VALID_USAGE(); | 
| 1322 »       } | 1324         } | 
| 1323 | 1325 | 
| 1324 »       if (PR_TRUE == revoked || PR_TRUE == sigerror) { | 1326         if (PR_TRUE == revoked || PR_TRUE == sigerror) { | 
| 1325 »           INVALID_USAGE(); | 1327             INVALID_USAGE(); | 
| 1326 »       } | 1328         } | 
| 1327 | 1329 | 
| 1328         rv = cert_VerifyCertChain(handle, cert, | 1330         rv = cert_VerifyCertChain(handle, cert, | 
| 1329             checkSig, &sigerror, | 1331                                   checkSig, &sigerror, | 
| 1330             certUsage, t, wincx, log, | 1332                                   certUsage, t, wincx, log, | 
| 1331             &revoked); | 1333                                   &revoked); | 
| 1332 | 1334 | 
| 1333         if (rv != SECSuccess) { | 1335         if (rv != SECSuccess) { | 
| 1334             /* EXIT_IF_NOT_LOGGING(log); XXX ???? */ | 1336             /* EXIT_IF_NOT_LOGGING(log); XXX ???? */ | 
| 1335             INVALID_USAGE(); | 1337             INVALID_USAGE(); | 
| 1336         } | 1338         } | 
| 1337 | 1339 | 
| 1338         /* | 1340         /* | 
| 1339          * Check OCSP revocation status, but only if the cert we are checking | 1341          * Check OCSP revocation status, but only if the cert we are checking | 
| 1340          * is not a status responder itself. We only do this in the case | 1342          * is not a status responder itself. We only do this in the case | 
| 1341          * where we checked the cert chain (above); explicit trust "wins" | 1343          * where we checked the cert chain (above); explicit trust "wins" | 
| 1342          * (avoids status checking, just as it avoids CRL checking) by | 1344          * (avoids status checking, just as it avoids CRL checking) by | 
| 1343          * bypassing this code. | 1345          * bypassing this code. | 
| 1344          */ | 1346          */ | 
| 1345 | 1347 | 
| 1346         if (PR_FALSE == checkedOCSP) { | 1348         if (PR_FALSE == checkedOCSP) { | 
| 1347             checkedOCSP = PR_TRUE; /* only check OCSP once */ | 1349             checkedOCSP = PR_TRUE; /* only check OCSP once */ | 
| 1348             statusConfig = CERT_GetStatusConfig(handle); | 1350             statusConfig = CERT_GetStatusConfig(handle); | 
| 1349             if (requiredUsages != certificateUsageStatusResponder && | 1351             if (requiredUsages != certificateUsageStatusResponder && | 
| 1350                 statusConfig != NULL) { | 1352                 statusConfig != NULL) { | 
| 1351                 if (statusConfig->statusChecker != NULL) { | 1353                 if (statusConfig->statusChecker != NULL) { | 
| 1352                     rv = (* statusConfig->statusChecker)(handle, cert, | 1354                     rv = (*statusConfig->statusChecker)(handle, cert, | 
| 1353                                                                  t, wincx); | 1355                                                         t, wincx); | 
| 1354                     if (rv != SECSuccess) { | 1356                     if (rv != SECSuccess) { | 
| 1355                         LOG_ERROR(log,cert,0,0); | 1357                         LOG_ERROR(log, cert, 0, 0); | 
| 1356                         revoked = PR_TRUE; | 1358                         revoked = PR_TRUE; | 
| 1357                         INVALID_USAGE(); | 1359                         INVALID_USAGE(); | 
| 1358                     } | 1360                     } | 
| 1359                 } | 1361                 } | 
| 1360             } | 1362             } | 
| 1361         } | 1363         } | 
| 1362 | 1364 | 
| 1363         NEXT_USAGE(); | 1365         NEXT_USAGE(); | 
| 1364     } | 1366     } | 
| 1365 | 1367 | 
| 1366 loser: | 1368 loser: | 
| 1367     return(valid); | 1369     return (valid); | 
| 1368 } | 1370 } | 
| 1369 | 1371 | 
| 1370 SECStatus | 1372 SECStatus | 
| 1371 CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert, | 1373 CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert, | 
| 1372 »       »       PRBool checkSig, SECCertUsage certUsage, PRTime t, | 1374                 PRBool checkSig, SECCertUsage certUsage, PRTime t, | 
| 1373 »       »       void *wincx, CERTVerifyLog *log) | 1375                 void *wincx, CERTVerifyLog *log) | 
| 1374 { | 1376 { | 
| 1375     return cert_VerifyCertWithFlags(handle, cert, checkSig, certUsage, t, | 1377     return cert_VerifyCertWithFlags(handle, cert, checkSig, certUsage, t, | 
| 1376                                     CERT_VERIFYCERT_USE_DEFAULTS, wincx, log); | 1378                                     CERT_VERIFYCERT_USE_DEFAULTS, wincx, log); | 
| 1377 } | 1379 } | 
| 1378 | 1380 | 
| 1379 SECStatus | 1381 SECStatus | 
| 1380 cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert, | 1382 cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert, | 
| 1381                          PRBool checkSig, SECCertUsage certUsage, PRTime t, | 1383                          PRBool checkSig, SECCertUsage certUsage, PRTime t, | 
| 1382                          PRUint32 flags, void *wincx, CERTVerifyLog *log) | 1384                          PRUint32 flags, void *wincx, CERTVerifyLog *log) | 
| 1383 { | 1385 { | 
| 1384     SECStatus rv; | 1386     SECStatus rv; | 
| 1385     unsigned int requiredKeyUsage; | 1387     unsigned int requiredKeyUsage; | 
| 1386     unsigned int requiredCertType; | 1388     unsigned int requiredCertType; | 
| 1387     unsigned int failedFlags; | 1389     unsigned int failedFlags; | 
| 1388     unsigned int certType; | 1390     unsigned int certType; | 
| 1389     PRBool       trusted; | 1391     PRBool trusted; | 
| 1390     PRBool       allowOverride; | 1392     PRBool allowOverride; | 
| 1391     SECCertTimeValidity validity; | 1393     SECCertTimeValidity validity; | 
| 1392     CERTStatusConfig *statusConfig; | 1394     CERTStatusConfig *statusConfig; | 
| 1393 | 1395 | 
| 1394 #ifdef notdef | 1396 #ifdef notdef | 
| 1395     /* check if this cert is in the Evil list */ | 1397     /* check if this cert is in the Evil list */ | 
| 1396     rv = CERT_CheckForEvilCert(cert); | 1398     rv = CERT_CheckForEvilCert(cert); | 
| 1397     if ( rv != SECSuccess ) { | 1399     if (rv != SECSuccess) { | 
| 1398 »       PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); | 1400         PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); | 
| 1399 »       LOG_ERROR_OR_EXIT(log,cert,0,0); | 1401         LOG_ERROR_OR_EXIT(log, cert, 0, 0); | 
| 1400     } | 1402     } | 
| 1401 #endif | 1403 #endif | 
| 1402 | 1404 | 
| 1403     /* make sure that the cert is valid at time t */ | 1405     /* make sure that the cert is valid at time t */ | 
| 1404     allowOverride = (PRBool)((certUsage == certUsageSSLServer) || | 1406     allowOverride = (PRBool)((certUsage == certUsageSSLServer) || | 
| 1405                              (certUsage == certUsageSSLServerWithStepUp)); | 1407                              (certUsage == certUsageSSLServerWithStepUp)); | 
| 1406     validity = CERT_CheckCertValidTimes(cert, t, allowOverride); | 1408     validity = CERT_CheckCertValidTimes(cert, t, allowOverride); | 
| 1407     if ( validity != secCertTimeValid ) { | 1409     if (validity != secCertTimeValid) { | 
| 1408 »       LOG_ERROR_OR_EXIT(log,cert,0,validity); | 1410         LOG_ERROR_OR_EXIT(log, cert, 0, validity); | 
| 1409     } | 1411     } | 
| 1410 | 1412 | 
| 1411     /* check key usage and netscape cert type */ | 1413     /* check key usage and netscape cert type */ | 
| 1412     cert_GetCertType(cert); | 1414     cert_GetCertType(cert); | 
| 1413     certType = cert->nsCertType; | 1415     certType = cert->nsCertType; | 
| 1414     switch ( certUsage ) { | 1416     switch (certUsage) { | 
| 1415       case certUsageSSLClient: | 1417         case certUsageSSLClient: | 
| 1416       case certUsageSSLServer: | 1418         case certUsageSSLServer: | 
| 1417       case certUsageSSLServerWithStepUp: | 1419         case certUsageSSLServerWithStepUp: | 
| 1418       case certUsageSSLCA: | 1420         case certUsageSSLCA: | 
| 1419       case certUsageEmailSigner: | 1421         case certUsageEmailSigner: | 
| 1420       case certUsageEmailRecipient: | 1422         case certUsageEmailRecipient: | 
| 1421       case certUsageObjectSigner: | 1423         case certUsageObjectSigner: | 
| 1422       case certUsageStatusResponder: | 1424         case certUsageStatusResponder: | 
| 1423 »       rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE, | 1425             rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE, | 
| 1424 »       »       »       »       »             &requiredKeyUsage, | 1426                                                   &requiredKeyUsage, | 
| 1425 »       »       »       »       »             &requiredCertType); | 1427                                                   &requiredCertType); | 
| 1426 »       if ( rv != SECSuccess ) { | 1428             if (rv != SECSuccess) { | 
| 1427 »           PORT_Assert(0); | 1429                 PORT_Assert(0); | 
| 1428 »           EXIT_IF_NOT_LOGGING(log); | 1430                 EXIT_IF_NOT_LOGGING(log); | 
| 1429 »           requiredKeyUsage = 0; | 1431                 requiredKeyUsage = 0; | 
| 1430 »           requiredCertType = 0; | 1432                 requiredCertType = 0; | 
| 1431 »       } | 1433             } | 
| 1432 »       break; | 1434             break; | 
| 1433       case certUsageVerifyCA: | 1435         case certUsageVerifyCA: | 
| 1434       case certUsageAnyCA: | 1436         case certUsageAnyCA: | 
| 1435 »       requiredKeyUsage = KU_KEY_CERT_SIGN; | 1437             requiredKeyUsage = KU_KEY_CERT_SIGN; | 
| 1436 »       requiredCertType = NS_CERT_TYPE_CA; | 1438             requiredCertType = NS_CERT_TYPE_CA; | 
| 1437 »       if ( ! ( certType & NS_CERT_TYPE_CA ) ) { | 1439             if (!(certType & NS_CERT_TYPE_CA)) { | 
| 1438 »           certType |= NS_CERT_TYPE_CA; | 1440                 certType |= NS_CERT_TYPE_CA; | 
| 1439 »       } | 1441             } | 
| 1440 »       break; | 1442             break; | 
| 1441       default: | 1443         default: | 
| 1442 »       PORT_Assert(0); | 1444             PORT_Assert(0); | 
| 1443 »       EXIT_IF_NOT_LOGGING(log); | 1445             EXIT_IF_NOT_LOGGING(log); | 
| 1444 »       requiredKeyUsage = 0; | 1446             requiredKeyUsage = 0; | 
| 1445 »       requiredCertType = 0; | 1447             requiredCertType = 0; | 
| 1446     } | 1448     } | 
| 1447     if ( CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess ) { | 1449     if (CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess) { | 
| 1448 »       PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); | 1450         PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); | 
| 1449 »       LOG_ERROR_OR_EXIT(log,cert,0,requiredKeyUsage); | 1451         LOG_ERROR_OR_EXIT(log, cert, 0, requiredKeyUsage); | 
| 1450     } | 1452     } | 
| 1451     if ( !( certType & requiredCertType ) ) { | 1453     if (!(certType & requiredCertType)) { | 
| 1452 »       PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE); | 1454         PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE); | 
| 1453 »       LOG_ERROR_OR_EXIT(log,cert,0,requiredCertType); | 1455         LOG_ERROR_OR_EXIT(log, cert, 0, requiredCertType); | 
| 1454     } | 1456     } | 
| 1455 | 1457 | 
| 1456     rv = cert_CheckLeafTrust(cert, certUsage, &failedFlags, &trusted); | 1458     rv = cert_CheckLeafTrust(cert, certUsage, &failedFlags, &trusted); | 
| 1457     if (rv  == SECFailure) { | 1459     if (rv == SECFailure) { | 
| 1458 »       PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); | 1460         PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); | 
| 1459 »       LOG_ERROR_OR_EXIT(log, cert, 0, failedFlags); | 1461         LOG_ERROR_OR_EXIT(log, cert, 0, failedFlags); | 
| 1460     } else if (trusted) { | 1462     } else if (trusted) { | 
| 1461 »       goto done; | 1463         goto done; | 
| 1462     } | 1464     } | 
| 1463 | 1465 | 
| 1464 |  | 
| 1465     rv = CERT_VerifyCertChain(handle, cert, checkSig, certUsage, | 1466     rv = CERT_VerifyCertChain(handle, cert, checkSig, certUsage, | 
| 1466 »       »       »             t, wincx, log); | 1467                               t, wincx, log); | 
| 1467     if (rv != SECSuccess) { | 1468     if (rv != SECSuccess) { | 
| 1468 »       EXIT_IF_NOT_LOGGING(log); | 1469         EXIT_IF_NOT_LOGGING(log); | 
| 1469     } | 1470     } | 
| 1470 | 1471 | 
| 1471     /* | 1472     /* | 
| 1472      * Check revocation status, but only if the cert we are checking is not a | 1473      * Check revocation status, but only if the cert we are checking is not a | 
| 1473      * status responder itself and the caller did not ask us to skip the check. | 1474      * status responder itself and the caller did not ask us to skip the check. | 
| 1474      * We only do this in the case where we checked the cert chain (above); | 1475      * We only do this in the case where we checked the cert chain (above); | 
| 1475      * explicit trust "wins" (avoids status checking, just as it avoids CRL | 1476      * explicit trust "wins" (avoids status checking, just as it avoids CRL | 
| 1476      * checking, which is all done inside VerifyCertChain) by bypassing this | 1477      * checking, which is all done inside VerifyCertChain) by bypassing this | 
| 1477      * code. | 1478      * code. | 
| 1478      */ | 1479      */ | 
| 1479     if (!(flags & CERT_VERIFYCERT_SKIP_OCSP) && | 1480     if (!(flags & CERT_VERIFYCERT_SKIP_OCSP) && | 
| 1480 »       certUsage != certUsageStatusResponder) { | 1481         certUsage != certUsageStatusResponder) { | 
| 1481 »       statusConfig = CERT_GetStatusConfig(handle); | 1482         statusConfig = CERT_GetStatusConfig(handle); | 
| 1482 »       if (statusConfig && statusConfig->statusChecker) { | 1483         if (statusConfig && statusConfig->statusChecker) { | 
| 1483 »           rv = (* statusConfig->statusChecker)(handle, cert, | 1484             rv = (*statusConfig->statusChecker)(handle, cert, | 
| 1484 »       »       »       »       »       »       »        t, wincx); | 1485                                                 t, wincx); | 
| 1485 »           if (rv != SECSuccess) { | 1486             if (rv != SECSuccess) { | 
| 1486 »       »       LOG_ERROR_OR_EXIT(log,cert,0,0); | 1487                 LOG_ERROR_OR_EXIT(log, cert, 0, 0); | 
| 1487 »           } | 1488             } | 
| 1488 »       } | 1489         } | 
| 1489     } | 1490     } | 
| 1490 | 1491 | 
| 1491 done: | 1492 done: | 
| 1492     if (log && log->head) { | 1493     if (log && log->head) { | 
| 1493       return SECFailure; | 1494         return SECFailure; | 
| 1494     } | 1495     } | 
| 1495     return(SECSuccess); | 1496     return (SECSuccess); | 
| 1496 | 1497 | 
| 1497 loser: | 1498 loser: | 
| 1498     rv = SECFailure; | 1499     rv = SECFailure; | 
| 1499 | 1500 | 
| 1500     return(rv); | 1501     return (rv); | 
| 1501 } | 1502 } | 
| 1502 | 1503 | 
| 1503 /* | 1504 /* | 
| 1504  * verify a certificate by checking if its valid and that we | 1505  * verify a certificate by checking if its valid and that we | 
| 1505  * trust the issuer.  Verify time against now. | 1506  * trust the issuer.  Verify time against now. | 
| 1506  */ | 1507  */ | 
| 1507 SECStatus | 1508 SECStatus | 
| 1508 CERT_VerifyCertificateNow(CERTCertDBHandle *handle, CERTCertificate *cert, | 1509 CERT_VerifyCertificateNow(CERTCertDBHandle *handle, CERTCertificate *cert, | 
| 1509 »       »          PRBool checkSig, SECCertificateUsage requiredUsages, | 1510                           PRBool checkSig, SECCertificateUsage requiredUsages, | 
| 1510                    void *wincx, SECCertificateUsage* returnedUsages) | 1511                           void *wincx, SECCertificateUsage *returnedUsages) | 
| 1511 { | 1512 { | 
| 1512     return(CERT_VerifyCertificate(handle, cert, checkSig, | 1513     return (CERT_VerifyCertificate(handle, cert, checkSig, | 
| 1513 »       »          requiredUsages, PR_Now(), wincx, NULL, returnedUsages)); | 1514                                    requiredUsages, PR_Now(), wincx, NULL, return
      edUsages)); | 
| 1514 } | 1515 } | 
| 1515 | 1516 | 
| 1516 /* obsolete, do not use for new code */ | 1517 /* obsolete, do not use for new code */ | 
| 1517 SECStatus | 1518 SECStatus | 
| 1518 CERT_VerifyCertNow(CERTCertDBHandle *handle, CERTCertificate *cert, | 1519 CERT_VerifyCertNow(CERTCertDBHandle *handle, CERTCertificate *cert, | 
| 1519 »       »          PRBool checkSig, SECCertUsage certUsage, void *wincx) | 1520                    PRBool checkSig, SECCertUsage certUsage, void *wincx) | 
| 1520 { | 1521 { | 
| 1521     return(CERT_VerifyCert(handle, cert, checkSig, | 1522     return (CERT_VerifyCert(handle, cert, checkSig, | 
| 1522 »       »          certUsage, PR_Now(), wincx, NULL)); | 1523                             certUsage, PR_Now(), wincx, NULL)); | 
| 1523 } | 1524 } | 
| 1524 | 1525 | 
| 1525 |  | 
| 1526 /* [ FROM pcertdb.c ] */ | 1526 /* [ FROM pcertdb.c ] */ | 
| 1527 /* | 1527 /* | 
| 1528  * Supported usage values and types: | 1528  * Supported usage values and types: | 
| 1529  *»     certUsageSSLClient | 1529  *  certUsageSSLClient | 
| 1530  *»     certUsageSSLServer | 1530  *  certUsageSSLServer | 
| 1531  *»     certUsageSSLServerWithStepUp | 1531  *  certUsageSSLServerWithStepUp | 
| 1532  *»     certUsageEmailSigner | 1532  *  certUsageEmailSigner | 
| 1533  *»     certUsageEmailRecipient | 1533  *  certUsageEmailRecipient | 
| 1534  *»     certUsageObjectSigner | 1534  *  certUsageObjectSigner | 
| 1535  */ | 1535  */ | 
| 1536 | 1536 | 
| 1537 CERTCertificate * | 1537 CERTCertificate * | 
| 1538 CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName, | 1538 CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName, | 
| 1539 »       »             CERTCertOwner owner, SECCertUsage usage, | 1539                       CERTCertOwner owner, SECCertUsage usage, | 
| 1540 »       »             PRBool preferTrusted, PRTime validTime, PRBool validOnly) | 1540                       PRBool preferTrusted, PRTime validTime, PRBool validOnly) | 
| 1541 { | 1541 { | 
| 1542     CERTCertList *certList = NULL; | 1542     CERTCertList *certList = NULL; | 
| 1543     CERTCertificate *cert = NULL; | 1543     CERTCertificate *cert = NULL; | 
| 1544     CERTCertTrust certTrust; | 1544     CERTCertTrust certTrust; | 
| 1545     unsigned int requiredTrustFlags; | 1545     unsigned int requiredTrustFlags; | 
| 1546     SECTrustType requiredTrustType; | 1546     SECTrustType requiredTrustType; | 
| 1547     unsigned int flags; | 1547     unsigned int flags; | 
| 1548 | 1548 | 
| 1549     PRBool lookingForCA = PR_FALSE; | 1549     PRBool lookingForCA = PR_FALSE; | 
| 1550     SECStatus rv; | 1550     SECStatus rv; | 
| 1551     CERTCertListNode *node; | 1551     CERTCertListNode *node; | 
| 1552     CERTCertificate *saveUntrustedCA = NULL; | 1552     CERTCertificate *saveUntrustedCA = NULL; | 
| 1553 | 1553 | 
| 1554     /* if preferTrusted is set, must be a CA cert */ | 1554     /* if preferTrusted is set, must be a CA cert */ | 
| 1555     PORT_Assert( ! ( preferTrusted && ( owner != certOwnerCA ) ) ); | 1555     PORT_Assert(!(preferTrusted && (owner != certOwnerCA))); | 
| 1556 | 1556 | 
| 1557     if ( owner == certOwnerCA ) { | 1557     if (owner == certOwnerCA) { | 
| 1558 »       lookingForCA = PR_TRUE; | 1558         lookingForCA = PR_TRUE; | 
| 1559 »       if ( preferTrusted ) { | 1559         if (preferTrusted) { | 
| 1560 »           rv = CERT_TrustFlagsForCACertUsage(usage, &requiredTrustFlags, | 1560             rv = CERT_TrustFlagsForCACertUsage(usage, &requiredTrustFlags, | 
| 1561 »       »       »       »       »              &requiredTrustType); | 1561                                                &requiredTrustType); | 
| 1562 »           if ( rv != SECSuccess ) { | 1562             if (rv != SECSuccess) { | 
| 1563 »       »       goto loser; | 1563                 goto loser; | 
| 1564 »           } | 1564             } | 
| 1565 »           requiredTrustFlags |= CERTDB_VALID_CA; | 1565             requiredTrustFlags |= CERTDB_VALID_CA; | 
| 1566 »       } | 1566         } | 
| 1567     } | 1567     } | 
| 1568 | 1568 | 
| 1569     certList = CERT_CreateSubjectCertList(NULL, handle, derName, validTime, | 1569     certList = CERT_CreateSubjectCertList(NULL, handle, derName, validTime, | 
| 1570 »       »       »       »       »         validOnly); | 1570                                           validOnly); | 
| 1571     if ( certList != NULL ) { | 1571     if (certList != NULL) { | 
| 1572 »       rv = CERT_FilterCertListByUsage(certList, usage, lookingForCA); | 1572         rv = CERT_FilterCertListByUsage(certList, usage, lookingForCA); | 
| 1573 »       if ( rv != SECSuccess ) { | 1573         if (rv != SECSuccess) { | 
| 1574 »           goto loser; | 1574             goto loser; | 
| 1575 »       } | 1575         } | 
| 1576 » |  | 
| 1577 »       node = CERT_LIST_HEAD(certList); |  | 
| 1578 » |  | 
| 1579 »       while ( !CERT_LIST_END(node, certList) ) { |  | 
| 1580 »           cert = node->cert; |  | 
| 1581 | 1576 | 
| 1582 »           /* looking for a trusted CA cert */ | 1577         node = CERT_LIST_HEAD(certList); | 
| 1583 »           if ( ( owner == certOwnerCA ) && preferTrusted && |  | 
| 1584 »       »       ( requiredTrustType != trustTypeNone ) ) { |  | 
| 1585 | 1578 | 
| 1586 »       »       if ( CERT_GetCertTrust(cert, &certTrust) != SECSuccess ) { | 1579         while (!CERT_LIST_END(node, certList)) { | 
| 1587 »       »           flags = 0; | 1580             cert = node->cert; | 
| 1588 »       »       } else { |  | 
| 1589 »       »           flags = SEC_GET_TRUST_FLAGS(&certTrust, requiredTrustType); |  | 
| 1590 »       »       } |  | 
| 1591 | 1581 | 
| 1592 »       »       if ( ( flags & requiredTrustFlags ) != requiredTrustFlags ) { | 1582             /* looking for a trusted CA cert */ | 
| 1593 »       »           /* cert is not trusted */ | 1583             if ((owner == certOwnerCA) && preferTrusted && | 
| 1594 »       »           /* if this is the first cert to get this far, then save | 1584                 (requiredTrustType != trustTypeNone)) { | 
| 1595 »       »            * it, so we can use it if we can't find a trusted one |  | 
| 1596 »       »            */ |  | 
| 1597 »       »           if ( saveUntrustedCA == NULL ) { |  | 
| 1598 »       »       »       saveUntrustedCA = cert; |  | 
| 1599 »       »           } |  | 
| 1600 »       »           goto endloop; |  | 
| 1601 »       »       } |  | 
| 1602 »           } |  | 
| 1603 »           /* if we got this far, then this cert meets all criteria */ |  | 
| 1604 »           break; |  | 
| 1605 » |  | 
| 1606 endloop: |  | 
| 1607 »           node = CERT_LIST_NEXT(node); |  | 
| 1608 »           cert = NULL; |  | 
| 1609 »       } |  | 
| 1610 | 1585 | 
| 1611 »       /* use the saved one if we have it */ | 1586                 if (CERT_GetCertTrust(cert, &certTrust) != SECSuccess) { | 
| 1612 »       if ( cert == NULL ) { | 1587                     flags = 0; | 
| 1613 »           cert = saveUntrustedCA; | 1588                 } else { | 
| 1614 »       } | 1589                     flags = SEC_GET_TRUST_FLAGS(&certTrust, requiredTrustType); | 
|  | 1590                 } | 
| 1615 | 1591 | 
| 1616 »       /* if we found one then bump the ref count before freeing the list */ | 1592                 if ((flags & requiredTrustFlags) != requiredTrustFlags) { | 
| 1617 »       if ( cert != NULL ) { | 1593                     /* cert is not trusted */ | 
| 1618 »           /* bump the ref count */ | 1594                     /* if this is the first cert to get this far, then save | 
| 1619 »           cert = CERT_DupCertificate(cert); | 1595                      * it, so we can use it if we can't find a trusted one | 
| 1620 »       } | 1596                      */ | 
| 1621 » | 1597                     if (saveUntrustedCA == NULL) { | 
| 1622 »       CERT_DestroyCertList(certList); | 1598                         saveUntrustedCA = cert; | 
|  | 1599                     } | 
|  | 1600                     goto endloop; | 
|  | 1601                 } | 
|  | 1602             } | 
|  | 1603             /* if we got this far, then this cert meets all criteria */ | 
|  | 1604             break; | 
|  | 1605 | 
|  | 1606         endloop: | 
|  | 1607             node = CERT_LIST_NEXT(node); | 
|  | 1608             cert = NULL; | 
|  | 1609         } | 
|  | 1610 | 
|  | 1611         /* use the saved one if we have it */ | 
|  | 1612         if (cert == NULL) { | 
|  | 1613             cert = saveUntrustedCA; | 
|  | 1614         } | 
|  | 1615 | 
|  | 1616         /* if we found one then bump the ref count before freeing the list */ | 
|  | 1617         if (cert != NULL) { | 
|  | 1618             /* bump the ref count */ | 
|  | 1619             cert = CERT_DupCertificate(cert); | 
|  | 1620         } | 
|  | 1621 | 
|  | 1622         CERT_DestroyCertList(certList); | 
| 1623     } | 1623     } | 
| 1624 | 1624 | 
| 1625     return(cert); | 1625     return (cert); | 
| 1626 | 1626 | 
| 1627 loser: | 1627 loser: | 
| 1628     if ( certList != NULL ) { | 1628     if (certList != NULL) { | 
| 1629 »       CERT_DestroyCertList(certList); | 1629         CERT_DestroyCertList(certList); | 
| 1630     } | 1630     } | 
| 1631 | 1631 | 
| 1632     return(NULL); | 1632     return (NULL); | 
| 1633 } | 1633 } | 
| 1634 | 1634 | 
| 1635 |  | 
| 1636 /* [ From certdb.c ] */ | 1635 /* [ From certdb.c ] */ | 
| 1637 /* | 1636 /* | 
| 1638  * Filter a list of certificates, removing those certs that do not have | 1637  * Filter a list of certificates, removing those certs that do not have | 
| 1639  * one of the named CA certs somewhere in their cert chain. | 1638  * one of the named CA certs somewhere in their cert chain. | 
| 1640  * | 1639  * | 
| 1641  *»     "certList" - the list of certificates to filter | 1640  *  "certList" - the list of certificates to filter | 
| 1642  *»     "nCANames" - number of CA names | 1641  *  "nCANames" - number of CA names | 
| 1643  *»     "caNames" - array of CA names in string(rfc 1485) form | 1642  *  "caNames" - array of CA names in string(rfc 1485) form | 
| 1644  *»     "usage" - what use the certs are for, this is used when | 1643  *  "usage" - what use the certs are for, this is used when | 
| 1645  *»     »       selecting CA certs | 1644  *      selecting CA certs | 
| 1646  */ | 1645  */ | 
| 1647 SECStatus | 1646 SECStatus | 
| 1648 CERT_FilterCertListByCANames(CERTCertList *certList, int nCANames, | 1647 CERT_FilterCertListByCANames(CERTCertList *certList, int nCANames, | 
| 1649 »       »       »            char **caNames, SECCertUsage usage) | 1648                              char **caNames, SECCertUsage usage) | 
| 1650 { | 1649 { | 
| 1651     CERTCertificate *issuerCert = NULL; | 1650     CERTCertificate *issuerCert = NULL; | 
| 1652     CERTCertificate *subjectCert; | 1651     CERTCertificate *subjectCert; | 
| 1653     CERTCertListNode *node, *freenode; | 1652     CERTCertListNode *node, *freenode; | 
| 1654     CERTCertificate *cert; | 1653     CERTCertificate *cert; | 
| 1655     int n; | 1654     int n; | 
| 1656     char **names; | 1655     char **names; | 
| 1657     PRBool found; | 1656     PRBool found; | 
| 1658     PRTime time; | 1657     PRTime time; | 
| 1659 | 1658 | 
| 1660     if ( nCANames <= 0 ) { | 1659     if (nCANames <= 0) { | 
| 1661 »       return(SECSuccess); | 1660         return (SECSuccess); | 
| 1662     } | 1661     } | 
| 1663 | 1662 | 
| 1664     time = PR_Now(); | 1663     time = PR_Now(); | 
| 1665 | 1664 | 
| 1666     node = CERT_LIST_HEAD(certList); | 1665     node = CERT_LIST_HEAD(certList); | 
| 1667 |  | 
| 1668     while ( ! CERT_LIST_END(node, certList) ) { |  | 
| 1669         cert = node->cert; |  | 
| 1670 |  | 
| 1671         subjectCert = CERT_DupCertificate(cert); |  | 
| 1672 | 1666 | 
| 1673 »       /* traverse the CA certs for this cert */ | 1667     while (!CERT_LIST_END(node, certList)) { | 
| 1674 »       found = PR_FALSE; | 1668         cert = node->cert; | 
| 1675 »       while ( subjectCert != NULL ) { |  | 
| 1676 »           n = nCANames; |  | 
| 1677 »           names = caNames; |  | 
| 1678 » |  | 
| 1679             if (subjectCert->issuerName != NULL) { |  | 
| 1680 »               while ( n > 0 ) { |  | 
| 1681 »       »           if ( PORT_Strcmp(*names, subjectCert->issuerName) == 0 ) { |  | 
| 1682 »       »               found = PR_TRUE; |  | 
| 1683 »       »               break; |  | 
| 1684 »       »           } |  | 
| 1685 | 1669 | 
| 1686 »       »           n--; | 1670         subjectCert = CERT_DupCertificate(cert); | 
| 1687 »       »           names++; | 1671 | 
|  | 1672         /* traverse the CA certs for this cert */ | 
|  | 1673         found = PR_FALSE; | 
|  | 1674         while (subjectCert != NULL) { | 
|  | 1675             n = nCANames; | 
|  | 1676             names = caNames; | 
|  | 1677 | 
|  | 1678             if (subjectCert->issuerName != NULL) { | 
|  | 1679                 while (n > 0) { | 
|  | 1680                     if (PORT_Strcmp(*names, subjectCert->issuerName) == 0) { | 
|  | 1681                         found = PR_TRUE; | 
|  | 1682                         break; | 
|  | 1683                     } | 
|  | 1684 | 
|  | 1685                     n--; | 
|  | 1686                     names++; | 
| 1688                 } | 1687                 } | 
| 1689 »           } | 1688             } | 
| 1690 | 1689 | 
| 1691 »           if ( found ) { | 1690             if (found) { | 
| 1692 »       »       break; | 1691                 break; | 
| 1693 »           } | 1692             } | 
| 1694 » |  | 
| 1695 »           issuerCert = CERT_FindCertIssuer(subjectCert, time, usage); |  | 
| 1696 »           if ( issuerCert == subjectCert ) { |  | 
| 1697 »       »       CERT_DestroyCertificate(issuerCert); |  | 
| 1698 »       »       issuerCert = NULL; |  | 
| 1699 »       »       break; |  | 
| 1700 »           } |  | 
| 1701 »           CERT_DestroyCertificate(subjectCert); |  | 
| 1702 »           subjectCert = issuerCert; |  | 
| 1703 | 1693 | 
| 1704 »       } | 1694             issuerCert = CERT_FindCertIssuer(subjectCert, time, usage); | 
| 1705 »       CERT_DestroyCertificate(subjectCert); | 1695             if (issuerCert == subjectCert) { | 
| 1706 »       if ( !found ) { | 1696                 CERT_DestroyCertificate(issuerCert); | 
| 1707 »           /* CA was not found, so remove this cert from the list */ | 1697                 issuerCert = NULL; | 
| 1708 »           freenode = node; | 1698                 break; | 
| 1709 »           node = CERT_LIST_NEXT(node); | 1699             } | 
| 1710 »           CERT_RemoveCertListNode(freenode); | 1700             CERT_DestroyCertificate(subjectCert); | 
| 1711 »       } else { | 1701             subjectCert = issuerCert; | 
| 1712 »           /* CA was found, so leave it in the list */ | 1702         } | 
| 1713 »           node = CERT_LIST_NEXT(node); | 1703         CERT_DestroyCertificate(subjectCert); | 
| 1714 »       } | 1704         if (!found) { | 
|  | 1705             /* CA was not found, so remove this cert from the list */ | 
|  | 1706             freenode = node; | 
|  | 1707             node = CERT_LIST_NEXT(node); | 
|  | 1708             CERT_RemoveCertListNode(freenode); | 
|  | 1709         } else { | 
|  | 1710             /* CA was found, so leave it in the list */ | 
|  | 1711             node = CERT_LIST_NEXT(node); | 
|  | 1712         } | 
| 1715     } | 1713     } | 
| 1716 | 1714 | 
| 1717     return(SECSuccess); | 1715     return (SECSuccess); | 
| 1718 } | 1716 } | 
| 1719 | 1717 | 
| 1720 /* | 1718 /* | 
| 1721  * Given a certificate, return a string containing the nickname, and possibly | 1719  * Given a certificate, return a string containing the nickname, and possibly | 
| 1722  * one of the validity strings, based on the current validity state of the | 1720  * one of the validity strings, based on the current validity state of the | 
| 1723  * certificate. | 1721  * certificate. | 
| 1724  * | 1722  * | 
| 1725  * "arena" - arena to allocate returned string from.  If NULL, then heap | 1723  * "arena" - arena to allocate returned string from.  If NULL, then heap | 
| 1726  *»     is used. | 1724  *  is used. | 
| 1727  * "cert" - the cert to get nickname from | 1725  * "cert" - the cert to get nickname from | 
| 1728  * "expiredString" - the string to append to the nickname if the cert is | 1726  * "expiredString" - the string to append to the nickname if the cert is | 
| 1729  *»     »       expired. | 1727  *      expired. | 
| 1730  * "notYetGoodString" - the string to append to the nickname if the cert is | 1728  * "notYetGoodString" - the string to append to the nickname if the cert is | 
| 1731  *»     »       not yet good. | 1729  *      not yet good. | 
| 1732  */ | 1730  */ | 
| 1733 char * | 1731 char * | 
| 1734 CERT_GetCertNicknameWithValidity(PLArenaPool *arena, CERTCertificate *cert, | 1732 CERT_GetCertNicknameWithValidity(PLArenaPool *arena, CERTCertificate *cert, | 
| 1735 »       »       »       »        char *expiredString, char *notYetGoodString) | 1733                                  char *expiredString, char *notYetGoodString) | 
| 1736 { | 1734 { | 
| 1737     SECCertTimeValidity validity; | 1735     SECCertTimeValidity validity; | 
| 1738     char *nickname = NULL, *tmpstr = NULL; | 1736     char *nickname = NULL, *tmpstr = NULL; | 
| 1739 | 1737 | 
| 1740     validity = CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE); | 1738     validity = CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE); | 
| 1741 | 1739 | 
| 1742     /* if the cert is good, then just use the nickname directly */ | 1740     /* if the cert is good, then just use the nickname directly */ | 
| 1743     if ( validity == secCertTimeValid ) { | 1741     if (validity == secCertTimeValid) { | 
| 1744 »       if ( arena == NULL ) { | 1742         if (arena == NULL) { | 
| 1745 »           nickname = PORT_Strdup(cert->nickname); | 1743             nickname = PORT_Strdup(cert->nickname); | 
| 1746 »       } else { | 1744         } else { | 
| 1747 »           nickname = PORT_ArenaStrdup(arena, cert->nickname); | 1745             nickname = PORT_ArenaStrdup(arena, cert->nickname); | 
| 1748 »       } | 1746         } | 
| 1749 » | 1747 | 
| 1750 »       if ( nickname == NULL ) { | 1748         if (nickname == NULL) { | 
| 1751 »           goto loser; | 1749             goto loser; | 
| 1752 »       } | 1750         } | 
| 1753     } else { | 1751     } else { | 
| 1754 » | 1752 | 
| 1755 »       /* if the cert is not valid, then tack one of the strings on the | 1753         /* if the cert is not valid, then tack one of the strings on the | 
| 1756 »        * end | 1754          * end | 
| 1757 »        */ | 1755          */ | 
| 1758 »       if ( validity == secCertTimeExpired ) { | 1756         if (validity == secCertTimeExpired) { | 
| 1759 »           tmpstr = PR_smprintf("%s%s", cert->nickname, | 1757             tmpstr = PR_smprintf("%s%s", cert->nickname, | 
| 1760 »       »       »       »        expiredString); | 1758                                  expiredString); | 
| 1761 »       } else if ( validity == secCertTimeNotValidYet ) { | 1759         } else if (validity == secCertTimeNotValidYet) { | 
| 1762 »           /* not yet valid */ | 1760             /* not yet valid */ | 
| 1763 »           tmpstr = PR_smprintf("%s%s", cert->nickname, | 1761             tmpstr = PR_smprintf("%s%s", cert->nickname, | 
| 1764 »       »       »       »        notYetGoodString); | 1762                                  notYetGoodString); | 
| 1765         } else { | 1763         } else { | 
| 1766             /* undetermined */ | 1764             /* undetermined */ | 
| 1767 »           tmpstr = PR_smprintf("%s", | 1765             tmpstr = PR_smprintf("%s", | 
| 1768                         "(NULL) (Validity Unknown)"); | 1766                                  "(NULL) (Validity Unknown)"); | 
| 1769         } | 1767         } | 
| 1770 | 1768 | 
| 1771 »       if ( tmpstr == NULL ) { | 1769         if (tmpstr == NULL) { | 
| 1772 »           goto loser; | 1770             goto loser; | 
| 1773 »       } | 1771         } | 
| 1774 | 1772 | 
| 1775 »       if ( arena ) { | 1773         if (arena) { | 
| 1776 »           /* copy the string into the arena and free the malloc'd one */ | 1774             /* copy the string into the arena and free the malloc'd one */ | 
| 1777 »           nickname = PORT_ArenaStrdup(arena, tmpstr); | 1775             nickname = PORT_ArenaStrdup(arena, tmpstr); | 
| 1778 »           PORT_Free(tmpstr); | 1776             PORT_Free(tmpstr); | 
| 1779 »       } else { | 1777         } else { | 
| 1780 »           nickname = tmpstr; | 1778             nickname = tmpstr; | 
| 1781 »       } | 1779         } | 
| 1782 »       if ( nickname == NULL ) { | 1780         if (nickname == NULL) { | 
| 1783 »           goto loser; | 1781             goto loser; | 
| 1784 »       } | 1782         } | 
| 1785     } | 1783     } | 
| 1786     return(nickname); | 1784     return (nickname); | 
| 1787 | 1785 | 
| 1788 loser: | 1786 loser: | 
| 1789     return(NULL); | 1787     return (NULL); | 
| 1790 } | 1788 } | 
| 1791 | 1789 | 
| 1792 /* | 1790 /* | 
| 1793  * Collect the nicknames from all certs in a CertList.  If the cert is not | 1791  * Collect the nicknames from all certs in a CertList.  If the cert is not | 
| 1794  * valid, append a string to that nickname. | 1792  * valid, append a string to that nickname. | 
| 1795  * | 1793  * | 
| 1796  * "certList" - the list of certificates | 1794  * "certList" - the list of certificates | 
| 1797  * "expiredString" - the string to append to the nickname of any expired cert | 1795  * "expiredString" - the string to append to the nickname of any expired cert | 
| 1798  * "notYetGoodString" - the string to append to the nickname of any cert | 1796  * "notYetGoodString" - the string to append to the nickname of any cert | 
| 1799  *»     »       that is not yet valid | 1797  *      that is not yet valid | 
| 1800  */ | 1798  */ | 
| 1801 CERTCertNicknames * | 1799 CERTCertNicknames * | 
| 1802 CERT_NicknameStringsFromCertList(CERTCertList *certList, char *expiredString, | 1800 CERT_NicknameStringsFromCertList(CERTCertList *certList, char *expiredString, | 
| 1803 »       »       »       »        char *notYetGoodString) | 1801                                  char *notYetGoodString) | 
| 1804 { | 1802 { | 
| 1805     CERTCertNicknames *names; | 1803     CERTCertNicknames *names; | 
| 1806     PLArenaPool *arena; | 1804     PLArenaPool *arena; | 
| 1807     CERTCertListNode *node; | 1805     CERTCertListNode *node; | 
| 1808     char **nn; | 1806     char **nn; | 
| 1809 | 1807 | 
| 1810     /* allocate an arena */ | 1808     /* allocate an arena */ | 
| 1811     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 1809     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 
| 1812     if ( arena == NULL ) { | 1810     if (arena == NULL) { | 
| 1813 »       return(NULL); | 1811         return (NULL); | 
| 1814     } | 1812     } | 
| 1815 | 1813 | 
| 1816     /* allocate the structure */ | 1814     /* allocate the structure */ | 
| 1817     names = PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames)); | 1815     names = PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames)); | 
| 1818     if ( names == NULL ) { | 1816     if (names == NULL) { | 
| 1819 »       goto loser; | 1817         goto loser; | 
| 1820     } | 1818     } | 
| 1821 | 1819 | 
| 1822     /* init the structure */ | 1820     /* init the structure */ | 
| 1823     names->arena = arena; | 1821     names->arena = arena; | 
| 1824     names->head = NULL; | 1822     names->head = NULL; | 
| 1825     names->numnicknames = 0; | 1823     names->numnicknames = 0; | 
| 1826     names->nicknames = NULL; | 1824     names->nicknames = NULL; | 
| 1827     names->totallen = 0; | 1825     names->totallen = 0; | 
| 1828 | 1826 | 
| 1829     /* count the certs in the list */ | 1827     /* count the certs in the list */ | 
| 1830     node = CERT_LIST_HEAD(certList); | 1828     node = CERT_LIST_HEAD(certList); | 
| 1831     while ( ! CERT_LIST_END(node, certList) ) { | 1829     while (!CERT_LIST_END(node, certList)) { | 
| 1832 »       names->numnicknames++; | 1830         names->numnicknames++; | 
| 1833 »       node = CERT_LIST_NEXT(node); | 1831         node = CERT_LIST_NEXT(node); | 
| 1834     } | 1832     } | 
| 1835 | 1833 | 
| 1836     /* allocate nicknames array */ | 1834     /* allocate nicknames array */ | 
| 1837     names->nicknames = PORT_ArenaAlloc(arena, | 1835     names->nicknames = PORT_ArenaAlloc(arena, | 
| 1838 »       »       »       »              sizeof(char *) * names->numnicknames); | 1836                                        sizeof(char *) * names->numnicknames); | 
| 1839     if ( names->nicknames == NULL ) { | 1837     if (names->nicknames == NULL) { | 
| 1840 »       goto loser; | 1838         goto loser; | 
| 1841     } | 1839     } | 
| 1842 | 1840 | 
| 1843     /* just in case printf can't deal with null strings */ | 1841     /* just in case printf can't deal with null strings */ | 
| 1844     if (expiredString == NULL ) { | 1842     if (expiredString == NULL) { | 
| 1845 »       expiredString = ""; | 1843         expiredString = ""; | 
| 1846     } | 1844     } | 
| 1847 | 1845 | 
| 1848     if ( notYetGoodString == NULL ) { | 1846     if (notYetGoodString == NULL) { | 
| 1849 »       notYetGoodString = ""; | 1847         notYetGoodString = ""; | 
| 1850     } | 1848     } | 
| 1851 | 1849 | 
| 1852     /* traverse the list of certs and collect the nicknames */ | 1850     /* traverse the list of certs and collect the nicknames */ | 
| 1853     nn = names->nicknames; | 1851     nn = names->nicknames; | 
| 1854     node = CERT_LIST_HEAD(certList); | 1852     node = CERT_LIST_HEAD(certList); | 
| 1855     while ( ! CERT_LIST_END(node, certList) ) { | 1853     while (!CERT_LIST_END(node, certList)) { | 
| 1856 »       *nn = CERT_GetCertNicknameWithValidity(arena, node->cert, | 1854         *nn = CERT_GetCertNicknameWithValidity(arena, node->cert, | 
| 1857 »       »       »       »       »              expiredString, | 1855                                                expiredString, | 
| 1858 »       »       »       »       »              notYetGoodString); | 1856                                                notYetGoodString); | 
| 1859 »       if ( *nn == NULL ) { | 1857         if (*nn == NULL) { | 
| 1860 »           goto loser; | 1858             goto loser; | 
| 1861 »       } | 1859         } | 
| 1862 | 1860 | 
| 1863 »       names->totallen += PORT_Strlen(*nn); | 1861         names->totallen += PORT_Strlen(*nn); | 
| 1864 » | 1862 | 
| 1865 »       nn++; | 1863         nn++; | 
| 1866 »       node = CERT_LIST_NEXT(node); | 1864         node = CERT_LIST_NEXT(node); | 
| 1867     } | 1865     } | 
| 1868 | 1866 | 
| 1869     return(names); | 1867     return (names); | 
| 1870 | 1868 | 
| 1871 loser: | 1869 loser: | 
| 1872     PORT_FreeArena(arena, PR_FALSE); | 1870     PORT_FreeArena(arena, PR_FALSE); | 
| 1873     return(NULL); | 1871     return (NULL); | 
| 1874 } | 1872 } | 
| 1875 | 1873 | 
| 1876 /* | 1874 /* | 
| 1877  * Extract the nickname from a nickmake string that may have either | 1875  * Extract the nickname from a nickmake string that may have either | 
| 1878  * expiredString or notYetGoodString appended. | 1876  * expiredString or notYetGoodString appended. | 
| 1879  * | 1877  * | 
| 1880  * Args: | 1878  * Args: | 
| 1881  *»     "namestring" - the string containing the nickname, and possibly | 1879  *  "namestring" - the string containing the nickname, and possibly | 
| 1882  *»     »       one of the validity label strings | 1880  *      one of the validity label strings | 
| 1883  *»     "expiredString" - the expired validity label string | 1881  *  "expiredString" - the expired validity label string | 
| 1884  *»     "notYetGoodString" - the not yet good validity label string | 1882  *  "notYetGoodString" - the not yet good validity label string | 
| 1885  * | 1883  * | 
| 1886  * Returns the raw nickname | 1884  * Returns the raw nickname | 
| 1887  */ | 1885  */ | 
| 1888 char * | 1886 char * | 
| 1889 CERT_ExtractNicknameString(char *namestring, char *expiredString, | 1887 CERT_ExtractNicknameString(char *namestring, char *expiredString, | 
| 1890 »       »       »          char *notYetGoodString) | 1888                            char *notYetGoodString) | 
| 1891 { | 1889 { | 
| 1892     int explen, nyglen, namelen; | 1890     int explen, nyglen, namelen; | 
| 1893     int retlen; | 1891     int retlen; | 
| 1894     char *retstr; | 1892     char *retstr; | 
| 1895 | 1893 | 
| 1896     namelen = PORT_Strlen(namestring); | 1894     namelen = PORT_Strlen(namestring); | 
| 1897     explen = PORT_Strlen(expiredString); | 1895     explen = PORT_Strlen(expiredString); | 
| 1898     nyglen = PORT_Strlen(notYetGoodString); | 1896     nyglen = PORT_Strlen(notYetGoodString); | 
| 1899 | 1897 | 
| 1900     if ( namelen > explen ) { | 1898     if (namelen > explen) { | 
| 1901 »       if ( PORT_Strcmp(expiredString, &namestring[namelen-explen]) == 0 ) { | 1899         if (PORT_Strcmp(expiredString, &namestring[namelen - explen]) == 0) { | 
| 1902 »           retlen = namelen - explen; | 1900             retlen = namelen - explen; | 
| 1903 »           retstr = (char *)PORT_Alloc(retlen+1); | 1901             retstr = (char *)PORT_Alloc(retlen + 1); | 
| 1904 »           if ( retstr == NULL ) { | 1902             if (retstr == NULL) { | 
| 1905 »       »       goto loser; | 1903                 goto loser; | 
| 1906 »           } | 1904             } | 
| 1907 » | 1905 | 
| 1908 »           PORT_Memcpy(retstr, namestring, retlen); | 1906             PORT_Memcpy(retstr, namestring, retlen); | 
| 1909 »           retstr[retlen] = '\0'; | 1907             retstr[retlen] = '\0'; | 
| 1910 »           goto done; | 1908             goto done; | 
| 1911 »       } | 1909         } | 
| 1912     } | 1910     } | 
| 1913 | 1911 | 
| 1914     if ( namelen > nyglen ) { | 1912     if (namelen > nyglen) { | 
| 1915 »       if ( PORT_Strcmp(notYetGoodString, &namestring[namelen-nyglen]) == 0) { | 1913         if (PORT_Strcmp(notYetGoodString, &namestring[namelen - nyglen]) == 0) { | 
| 1916 »           retlen = namelen - nyglen; | 1914             retlen = namelen - nyglen; | 
| 1917 »           retstr = (char *)PORT_Alloc(retlen+1); | 1915             retstr = (char *)PORT_Alloc(retlen + 1); | 
| 1918 »           if ( retstr == NULL ) { | 1916             if (retstr == NULL) { | 
| 1919 »       »       goto loser; | 1917                 goto loser; | 
| 1920 »           } | 1918             } | 
| 1921 » | 1919 | 
| 1922 »           PORT_Memcpy(retstr, namestring, retlen); | 1920             PORT_Memcpy(retstr, namestring, retlen); | 
| 1923 »           retstr[retlen] = '\0'; | 1921             retstr[retlen] = '\0'; | 
| 1924 »           goto done; | 1922             goto done; | 
| 1925 »       } | 1923         } | 
| 1926     } | 1924     } | 
| 1927 | 1925 | 
| 1928     /* if name string is shorter than either invalid string, then it must | 1926     /* if name string is shorter than either invalid string, then it must | 
| 1929      * be a raw nickname | 1927      * be a raw nickname | 
| 1930      */ | 1928      */ | 
| 1931     retstr = PORT_Strdup(namestring); | 1929     retstr = PORT_Strdup(namestring); | 
| 1932 | 1930 | 
| 1933 done: | 1931 done: | 
| 1934     return(retstr); | 1932     return (retstr); | 
| 1935 | 1933 | 
| 1936 loser: | 1934 loser: | 
| 1937     return(NULL); | 1935     return (NULL); | 
| 1938 } | 1936 } | 
| 1939 | 1937 | 
| 1940 CERTCertList * | 1938 CERTCertList * | 
| 1941 CERT_GetCertChainFromCert(CERTCertificate *cert, PRTime time, SECCertUsage usage
      ) | 1939 CERT_GetCertChainFromCert(CERTCertificate *cert, PRTime time, SECCertUsage usage
      ) | 
| 1942 { | 1940 { | 
| 1943     CERTCertList *chain = NULL; | 1941     CERTCertList *chain = NULL; | 
| 1944     int count = 0; | 1942     int count = 0; | 
| 1945 | 1943 | 
| 1946     if (NULL == cert) { | 1944     if (NULL == cert) { | 
| 1947         return NULL; | 1945         return NULL; | 
| 1948     } | 1946     } | 
| 1949 | 1947 | 
| 1950     cert = CERT_DupCertificate(cert); | 1948     cert = CERT_DupCertificate(cert); | 
| 1951     if (NULL == cert) { | 1949     if (NULL == cert) { | 
| 1952         PORT_SetError(SEC_ERROR_NO_MEMORY); | 1950         PORT_SetError(SEC_ERROR_NO_MEMORY); | 
| 1953         return NULL; | 1951         return NULL; | 
| 1954     } | 1952     } | 
| 1955 | 1953 | 
| 1956     chain = CERT_NewCertList(); | 1954     chain = CERT_NewCertList(); | 
| 1957     if (NULL == chain) { | 1955     if (NULL == chain) { | 
| 1958         PORT_SetError(SEC_ERROR_NO_MEMORY); | 1956         PORT_SetError(SEC_ERROR_NO_MEMORY); | 
| 1959         return NULL; | 1957         return NULL; | 
| 1960     } | 1958     } | 
| 1961 | 1959 | 
| 1962     while (cert != NULL && ++count <= CERT_MAX_CERT_CHAIN) { | 1960     while (cert != NULL && ++count <= CERT_MAX_CERT_CHAIN) { | 
| 1963 »       if (SECSuccess != CERT_AddCertToListTail(chain, cert)) { | 1961         if (SECSuccess != CERT_AddCertToListTail(chain, cert)) { | 
| 1964             /* return partial chain */ | 1962             /* return partial chain */ | 
| 1965             PORT_SetError(SEC_ERROR_NO_MEMORY); | 1963             PORT_SetError(SEC_ERROR_NO_MEMORY); | 
| 1966             return chain; | 1964             return chain; | 
| 1967         } | 1965         } | 
| 1968 | 1966 | 
| 1969 »       if (cert->isRoot) { | 1967         if (cert->isRoot) { | 
| 1970             /* return complete chain */ | 1968             /* return complete chain */ | 
| 1971 »           return chain; | 1969             return chain; | 
| 1972 »       } | 1970         } | 
| 1973 | 1971 | 
| 1974 »       cert = CERT_FindCertIssuer(cert, time, usage); | 1972         cert = CERT_FindCertIssuer(cert, time, usage); | 
| 1975     } | 1973     } | 
| 1976 | 1974 | 
| 1977     /* return partial chain */ | 1975     /* return partial chain */ | 
| 1978     PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); | 1976     PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); | 
| 1979     return chain; | 1977     return chain; | 
| 1980 } | 1978 } | 
| OLD | NEW | 
|---|