diff options
Diffstat (limited to 'src/lib/libcrypto/x509v3/v3_purp.c')
-rw-r--r-- | src/lib/libcrypto/x509v3/v3_purp.c | 75 |
1 files changed, 29 insertions, 46 deletions
diff --git a/src/lib/libcrypto/x509v3/v3_purp.c b/src/lib/libcrypto/x509v3/v3_purp.c index bbdf6da493..b3d1ae5d1c 100644 --- a/src/lib/libcrypto/x509v3/v3_purp.c +++ b/src/lib/libcrypto/x509v3/v3_purp.c | |||
@@ -63,6 +63,7 @@ | |||
63 | 63 | ||
64 | static void x509v3_cache_extensions(X509 *x); | 64 | static void x509v3_cache_extensions(X509 *x); |
65 | 65 | ||
66 | static int ca_check(const X509 *x); | ||
66 | static int check_ssl_ca(const X509 *x); | 67 | static int check_ssl_ca(const X509 *x); |
67 | static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca); | 68 | static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca); |
68 | static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca); | 69 | static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca); |
@@ -285,8 +286,7 @@ int X509_supported_extension(X509_EXTENSION *ex) | |||
285 | NID_key_usage, /* 83 */ | 286 | NID_key_usage, /* 83 */ |
286 | NID_subject_alt_name, /* 85 */ | 287 | NID_subject_alt_name, /* 85 */ |
287 | NID_basic_constraints, /* 87 */ | 288 | NID_basic_constraints, /* 87 */ |
288 | NID_ext_key_usage, /* 126 */ | 289 | NID_ext_key_usage /* 126 */ |
289 | NID_proxyCertInfo /* 661 */ | ||
290 | }; | 290 | }; |
291 | 291 | ||
292 | int ex_nid; | 292 | int ex_nid; |
@@ -307,7 +307,6 @@ int X509_supported_extension(X509_EXTENSION *ex) | |||
307 | static void x509v3_cache_extensions(X509 *x) | 307 | static void x509v3_cache_extensions(X509 *x) |
308 | { | 308 | { |
309 | BASIC_CONSTRAINTS *bs; | 309 | BASIC_CONSTRAINTS *bs; |
310 | PROXY_CERT_INFO_EXTENSION *pci; | ||
311 | ASN1_BIT_STRING *usage; | 310 | ASN1_BIT_STRING *usage; |
312 | ASN1_BIT_STRING *ns; | 311 | ASN1_BIT_STRING *ns; |
313 | EXTENDED_KEY_USAGE *extusage; | 312 | EXTENDED_KEY_USAGE *extusage; |
@@ -336,16 +335,6 @@ static void x509v3_cache_extensions(X509 *x) | |||
336 | BASIC_CONSTRAINTS_free(bs); | 335 | BASIC_CONSTRAINTS_free(bs); |
337 | x->ex_flags |= EXFLAG_BCONS; | 336 | x->ex_flags |= EXFLAG_BCONS; |
338 | } | 337 | } |
339 | /* Handle proxy certificates */ | ||
340 | if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) { | ||
341 | if (x->ex_flags & EXFLAG_CA | ||
342 | || X509_get_ext_by_NID(x, NID_subject_alt_name, 0) >= 0 | ||
343 | || X509_get_ext_by_NID(x, NID_issuer_alt_name, 0) >= 0) { | ||
344 | x->ex_flags |= EXFLAG_INVALID; | ||
345 | } | ||
346 | PROXY_CERT_INFO_EXTENSION_free(pci); | ||
347 | x->ex_flags |= EXFLAG_PROXY; | ||
348 | } | ||
349 | /* Handle key usage */ | 338 | /* Handle key usage */ |
350 | if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) { | 339 | if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) { |
351 | if(usage->length > 0) { | 340 | if(usage->length > 0) { |
@@ -437,7 +426,7 @@ static void x509v3_cache_extensions(X509 *x) | |||
437 | #define ns_reject(x, usage) \ | 426 | #define ns_reject(x, usage) \ |
438 | (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) | 427 | (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) |
439 | 428 | ||
440 | static int check_ca(const X509 *x) | 429 | static int ca_check(const X509 *x) |
441 | { | 430 | { |
442 | /* keyUsage if present should allow cert signing */ | 431 | /* keyUsage if present should allow cert signing */ |
443 | if(ku_reject(x, KU_KEY_CERT_SIGN)) return 0; | 432 | if(ku_reject(x, KU_KEY_CERT_SIGN)) return 0; |
@@ -446,37 +435,25 @@ static int check_ca(const X509 *x) | |||
446 | /* If basicConstraints says not a CA then say so */ | 435 | /* If basicConstraints says not a CA then say so */ |
447 | else return 0; | 436 | else return 0; |
448 | } else { | 437 | } else { |
449 | /* we support V1 roots for... uh, I don't really know why. */ | ||
450 | if((x->ex_flags & V1_ROOT) == V1_ROOT) return 3; | 438 | if((x->ex_flags & V1_ROOT) == V1_ROOT) return 3; |
451 | /* If key usage present it must have certSign so tolerate it */ | 439 | /* If key usage present it must have certSign so tolerate it */ |
452 | else if (x->ex_flags & EXFLAG_KUSAGE) return 4; | 440 | else if (x->ex_flags & EXFLAG_KUSAGE) return 4; |
453 | /* Older certificates could have Netscape-specific CA types */ | 441 | else return 2; |
454 | else if (x->ex_flags & EXFLAG_NSCERT | ||
455 | && x->ex_nscert & NS_ANY_CA) return 5; | ||
456 | /* can this still be regarded a CA certificate? I doubt it */ | ||
457 | return 0; | ||
458 | } | 442 | } |
459 | } | 443 | } |
460 | 444 | ||
461 | int X509_check_ca(X509 *x) | ||
462 | { | ||
463 | if(!(x->ex_flags & EXFLAG_SET)) { | ||
464 | CRYPTO_w_lock(CRYPTO_LOCK_X509); | ||
465 | x509v3_cache_extensions(x); | ||
466 | CRYPTO_w_unlock(CRYPTO_LOCK_X509); | ||
467 | } | ||
468 | |||
469 | return check_ca(x); | ||
470 | } | ||
471 | |||
472 | /* Check SSL CA: common checks for SSL client and server */ | 445 | /* Check SSL CA: common checks for SSL client and server */ |
473 | static int check_ssl_ca(const X509 *x) | 446 | static int check_ssl_ca(const X509 *x) |
474 | { | 447 | { |
475 | int ca_ret; | 448 | int ca_ret; |
476 | ca_ret = check_ca(x); | 449 | ca_ret = ca_check(x); |
477 | if(!ca_ret) return 0; | 450 | if(!ca_ret) return 0; |
478 | /* check nsCertType if present */ | 451 | /* check nsCertType if present */ |
479 | if(ca_ret != 5 || x->ex_nscert & NS_SSL_CA) return ca_ret; | 452 | if(x->ex_flags & EXFLAG_NSCERT) { |
453 | if(x->ex_nscert & NS_SSL_CA) return ca_ret; | ||
454 | return 0; | ||
455 | } | ||
456 | if(ca_ret != 2) return ca_ret; | ||
480 | else return 0; | 457 | else return 0; |
481 | } | 458 | } |
482 | 459 | ||
@@ -521,10 +498,14 @@ static int purpose_smime(const X509 *x, int ca) | |||
521 | if(xku_reject(x,XKU_SMIME)) return 0; | 498 | if(xku_reject(x,XKU_SMIME)) return 0; |
522 | if(ca) { | 499 | if(ca) { |
523 | int ca_ret; | 500 | int ca_ret; |
524 | ca_ret = check_ca(x); | 501 | ca_ret = ca_check(x); |
525 | if(!ca_ret) return 0; | 502 | if(!ca_ret) return 0; |
526 | /* check nsCertType if present */ | 503 | /* check nsCertType if present */ |
527 | if(ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) return ca_ret; | 504 | if(x->ex_flags & EXFLAG_NSCERT) { |
505 | if(x->ex_nscert & NS_SMIME_CA) return ca_ret; | ||
506 | return 0; | ||
507 | } | ||
508 | if(ca_ret != 2) return ca_ret; | ||
528 | else return 0; | 509 | else return 0; |
529 | } | 510 | } |
530 | if(x->ex_flags & EXFLAG_NSCERT) { | 511 | if(x->ex_flags & EXFLAG_NSCERT) { |
@@ -558,7 +539,7 @@ static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca) | |||
558 | { | 539 | { |
559 | if(ca) { | 540 | if(ca) { |
560 | int ca_ret; | 541 | int ca_ret; |
561 | if((ca_ret = check_ca(x)) != 2) return ca_ret; | 542 | if((ca_ret = ca_check(x)) != 2) return ca_ret; |
562 | else return 0; | 543 | else return 0; |
563 | } | 544 | } |
564 | if(ku_reject(x, KU_CRL_SIGN)) return 0; | 545 | if(ku_reject(x, KU_CRL_SIGN)) return 0; |
@@ -571,9 +552,17 @@ static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca) | |||
571 | 552 | ||
572 | static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) | 553 | static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) |
573 | { | 554 | { |
574 | /* Must be a valid CA. Should we really support the "I don't know" | 555 | /* Must be a valid CA */ |
575 | value (2)? */ | 556 | if(ca) { |
576 | if(ca) return check_ca(x); | 557 | int ca_ret; |
558 | ca_ret = ca_check(x); | ||
559 | if(ca_ret != 2) return ca_ret; | ||
560 | if(x->ex_flags & EXFLAG_NSCERT) { | ||
561 | if(x->ex_nscert & NS_ANY_CA) return ca_ret; | ||
562 | return 0; | ||
563 | } | ||
564 | return 0; | ||
565 | } | ||
577 | /* leaf certificate is checked in OCSP_verify() */ | 566 | /* leaf certificate is checked in OCSP_verify() */ |
578 | return 1; | 567 | return 1; |
579 | } | 568 | } |
@@ -635,13 +624,7 @@ int X509_check_issued(X509 *issuer, X509 *subject) | |||
635 | return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; | 624 | return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; |
636 | } | 625 | } |
637 | } | 626 | } |
638 | if(subject->ex_flags & EXFLAG_PROXY) | 627 | if(ku_reject(issuer, KU_KEY_CERT_SIGN)) return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; |
639 | { | ||
640 | if(ku_reject(issuer, KU_DIGITAL_SIGNATURE)) | ||
641 | return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; | ||
642 | } | ||
643 | else if(ku_reject(issuer, KU_KEY_CERT_SIGN)) | ||
644 | return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; | ||
645 | return X509_V_OK; | 628 | return X509_V_OK; |
646 | } | 629 | } |
647 | 630 | ||