summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509v3/v3_purp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/x509v3/v3_purp.c')
-rw-r--r--src/lib/libcrypto/x509v3/v3_purp.c75
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
64static void x509v3_cache_extensions(X509 *x); 64static void x509v3_cache_extensions(X509 *x);
65 65
66static int ca_check(const X509 *x);
66static int check_ssl_ca(const X509 *x); 67static int check_ssl_ca(const X509 *x);
67static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca); 68static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca);
68static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca); 69static 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)
307static void x509v3_cache_extensions(X509 *x) 307static 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
440static int check_ca(const X509 *x) 429static 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
461int 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 */
473static int check_ssl_ca(const X509 *x) 446static 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
572static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) 553static 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