diff options
Diffstat (limited to 'src/lib/libcrypto/x509v3/v3_purp.c')
-rw-r--r-- | src/lib/libcrypto/x509v3/v3_purp.c | 104 |
1 files changed, 97 insertions, 7 deletions
diff --git a/src/lib/libcrypto/x509v3/v3_purp.c b/src/lib/libcrypto/x509v3/v3_purp.c index 8aecd00e63..b739e4fd83 100644 --- a/src/lib/libcrypto/x509v3/v3_purp.c +++ b/src/lib/libcrypto/x509v3/v3_purp.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* v3_purp.c */ | 1 | /* v3_purp.c */ |
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL |
3 | * project 1999. | 3 | * project 2001. |
4 | */ | 4 | */ |
5 | /* ==================================================================== | 5 | /* ==================================================================== |
6 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | 6 | * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | 9 | * modification, are permitted provided that the following conditions |
@@ -61,7 +61,6 @@ | |||
61 | #include <openssl/x509v3.h> | 61 | #include <openssl/x509v3.h> |
62 | #include <openssl/x509_vfy.h> | 62 | #include <openssl/x509_vfy.h> |
63 | 63 | ||
64 | |||
65 | static void x509v3_cache_extensions(X509 *x); | 64 | static void x509v3_cache_extensions(X509 *x); |
66 | 65 | ||
67 | static int ca_check(const X509 *x); | 66 | static int ca_check(const X509 *x); |
@@ -74,6 +73,7 @@ static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int c | |||
74 | static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca); | 73 | static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca); |
75 | static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca); | 74 | static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca); |
76 | static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca); | 75 | static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca); |
76 | static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca); | ||
77 | 77 | ||
78 | static int xp_cmp(const X509_PURPOSE * const *a, | 78 | static int xp_cmp(const X509_PURPOSE * const *a, |
79 | const X509_PURPOSE * const *b); | 79 | const X509_PURPOSE * const *b); |
@@ -87,6 +87,7 @@ static X509_PURPOSE xstandard[] = { | |||
87 | {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL}, | 87 | {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL}, |
88 | {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL}, | 88 | {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL}, |
89 | {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", NULL}, | 89 | {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", NULL}, |
90 | {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, "OCSP helper", "ocsphelper", NULL}, | ||
90 | }; | 91 | }; |
91 | 92 | ||
92 | #define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE)) | 93 | #define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE)) |
@@ -120,6 +121,16 @@ int X509_check_purpose(X509 *x, int id, int ca) | |||
120 | return pt->check_purpose(pt, x, ca); | 121 | return pt->check_purpose(pt, x, ca); |
121 | } | 122 | } |
122 | 123 | ||
124 | int X509_PURPOSE_set(int *p, int purpose) | ||
125 | { | ||
126 | if(X509_PURPOSE_get_by_id(purpose) == -1) { | ||
127 | X509V3err(X509V3_F_X509_PURPOSE_SET, X509V3_R_INVALID_PURPOSE); | ||
128 | return 0; | ||
129 | } | ||
130 | *p = purpose; | ||
131 | return 1; | ||
132 | } | ||
133 | |||
123 | int X509_PURPOSE_get_count(void) | 134 | int X509_PURPOSE_get_count(void) |
124 | { | 135 | { |
125 | if(!xptable) return X509_PURPOSE_COUNT; | 136 | if(!xptable) return X509_PURPOSE_COUNT; |
@@ -144,7 +155,6 @@ int X509_PURPOSE_get_by_sname(char *sname) | |||
144 | return -1; | 155 | return -1; |
145 | } | 156 | } |
146 | 157 | ||
147 | |||
148 | int X509_PURPOSE_get_by_id(int purpose) | 158 | int X509_PURPOSE_get_by_id(int purpose) |
149 | { | 159 | { |
150 | X509_PURPOSE tmp; | 160 | X509_PURPOSE tmp; |
@@ -256,16 +266,55 @@ int X509_PURPOSE_get_trust(X509_PURPOSE *xp) | |||
256 | return xp->trust; | 266 | return xp->trust; |
257 | } | 267 | } |
258 | 268 | ||
269 | static int nid_cmp(int *a, int *b) | ||
270 | { | ||
271 | return *a - *b; | ||
272 | } | ||
273 | |||
274 | int X509_supported_extension(X509_EXTENSION *ex) | ||
275 | { | ||
276 | /* This table is a list of the NIDs of supported extensions: | ||
277 | * that is those which are used by the verify process. If | ||
278 | * an extension is critical and doesn't appear in this list | ||
279 | * then the verify process will normally reject the certificate. | ||
280 | * The list must be kept in numerical order because it will be | ||
281 | * searched using bsearch. | ||
282 | */ | ||
283 | |||
284 | static int supported_nids[] = { | ||
285 | NID_netscape_cert_type, /* 71 */ | ||
286 | NID_key_usage, /* 83 */ | ||
287 | NID_subject_alt_name, /* 85 */ | ||
288 | NID_basic_constraints, /* 87 */ | ||
289 | NID_ext_key_usage /* 126 */ | ||
290 | }; | ||
291 | |||
292 | int ex_nid; | ||
293 | |||
294 | ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); | ||
295 | |||
296 | if (ex_nid == NID_undef) | ||
297 | return 0; | ||
298 | |||
299 | if (OBJ_bsearch((char *)&ex_nid, (char *)supported_nids, | ||
300 | sizeof(supported_nids)/sizeof(int), sizeof(int), | ||
301 | (int (*)(const void *, const void *))nid_cmp)) | ||
302 | return 1; | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | |||
259 | static void x509v3_cache_extensions(X509 *x) | 307 | static void x509v3_cache_extensions(X509 *x) |
260 | { | 308 | { |
261 | BASIC_CONSTRAINTS *bs; | 309 | BASIC_CONSTRAINTS *bs; |
262 | ASN1_BIT_STRING *usage; | 310 | ASN1_BIT_STRING *usage; |
263 | ASN1_BIT_STRING *ns; | 311 | ASN1_BIT_STRING *ns; |
264 | STACK_OF(ASN1_OBJECT) *extusage; | 312 | EXTENDED_KEY_USAGE *extusage; |
313 | X509_EXTENSION *ex; | ||
265 | 314 | ||
266 | int i; | 315 | int i; |
267 | if(x->ex_flags & EXFLAG_SET) return; | 316 | if(x->ex_flags & EXFLAG_SET) return; |
268 | #ifndef NO_SHA | 317 | #ifndef OPENSSL_NO_SHA |
269 | X509_digest(x, EVP_sha1(), x->sha1_hash, NULL); | 318 | X509_digest(x, EVP_sha1(), x->sha1_hash, NULL); |
270 | #endif | 319 | #endif |
271 | /* Does subject name match issuer ? */ | 320 | /* Does subject name match issuer ? */ |
@@ -320,6 +369,15 @@ static void x509v3_cache_extensions(X509 *x) | |||
320 | case NID_ms_sgc: | 369 | case NID_ms_sgc: |
321 | case NID_ns_sgc: | 370 | case NID_ns_sgc: |
322 | x->ex_xkusage |= XKU_SGC; | 371 | x->ex_xkusage |= XKU_SGC; |
372 | break; | ||
373 | |||
374 | case NID_OCSP_sign: | ||
375 | x->ex_xkusage |= XKU_OCSP_SIGN; | ||
376 | break; | ||
377 | |||
378 | case NID_time_stamp: | ||
379 | x->ex_xkusage |= XKU_TIMESTAMP; | ||
380 | break; | ||
323 | } | 381 | } |
324 | } | 382 | } |
325 | sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); | 383 | sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); |
@@ -333,6 +391,17 @@ static void x509v3_cache_extensions(X509 *x) | |||
333 | } | 391 | } |
334 | x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL); | 392 | x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL); |
335 | x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL); | 393 | x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL); |
394 | for (i = 0; i < X509_get_ext_count(x); i++) | ||
395 | { | ||
396 | ex = X509_get_ext(x, i); | ||
397 | if (!X509_EXTENSION_get_critical(ex)) | ||
398 | continue; | ||
399 | if (!X509_supported_extension(ex)) | ||
400 | { | ||
401 | x->ex_flags |= EXFLAG_CRITICAL; | ||
402 | break; | ||
403 | } | ||
404 | } | ||
336 | x->ex_flags |= EXFLAG_SET; | 405 | x->ex_flags |= EXFLAG_SET; |
337 | } | 406 | } |
338 | 407 | ||
@@ -472,6 +541,27 @@ static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca) | |||
472 | return 1; | 541 | return 1; |
473 | } | 542 | } |
474 | 543 | ||
544 | /* OCSP helper: this is *not* a full OCSP check. It just checks that | ||
545 | * each CA is valid. Additional checks must be made on the chain. | ||
546 | */ | ||
547 | |||
548 | static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) | ||
549 | { | ||
550 | /* Must be a valid CA */ | ||
551 | if(ca) { | ||
552 | int ca_ret; | ||
553 | ca_ret = ca_check(x); | ||
554 | if(ca_ret != 2) return ca_ret; | ||
555 | if(x->ex_flags & EXFLAG_NSCERT) { | ||
556 | if(x->ex_nscert & NS_ANY_CA) return ca_ret; | ||
557 | return 0; | ||
558 | } | ||
559 | return 0; | ||
560 | } | ||
561 | /* leaf certificate is checked in OCSP_verify() */ | ||
562 | return 1; | ||
563 | } | ||
564 | |||
475 | static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca) | 565 | static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca) |
476 | { | 566 | { |
477 | return 1; | 567 | return 1; |
@@ -513,7 +603,7 @@ int X509_check_issued(X509 *issuer, X509 *subject) | |||
513 | * There may be more than one but we only take any | 603 | * There may be more than one but we only take any |
514 | * notice of the first. | 604 | * notice of the first. |
515 | */ | 605 | */ |
516 | STACK_OF(GENERAL_NAME) *gens; | 606 | GENERAL_NAMES *gens; |
517 | GENERAL_NAME *gen; | 607 | GENERAL_NAME *gen; |
518 | X509_NAME *nm = NULL; | 608 | X509_NAME *nm = NULL; |
519 | int i; | 609 | int i; |