Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Side by Side Diff: nss/lib/certhigh/certvfy.c

Issue 1843333003: Update NSPR to 4.12 and NSS to 3.23 on iOS (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698