diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2001-10-21 02:09:15 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2001-10-21 02:09:15 +0000 |
commit | f1558bb4243d83781793ed758367bd71d0983a35 (patch) | |
tree | e1971f6bf6360b9cd2e1fad6ad8f77ed4b916063 /crypto | |
parent | 6ca487992bc63d45f9780c6b83eecf025830e34b (diff) |
Reject certificates with unhandled critical extensions.
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/x509/x509_txt.c | 3 | ||||
-rw-r--r-- | crypto/x509/x509_vfy.c | 11 | ||||
-rw-r--r-- | crypto/x509/x509_vfy.h | 2 | ||||
-rw-r--r-- | crypto/x509v3/v3_purp.c | 54 | ||||
-rw-r--r-- | crypto/x509v3/x509v3.h | 2 |
5 files changed, 68 insertions, 4 deletions
diff --git a/crypto/x509/x509_txt.c b/crypto/x509/x509_txt.c index bcf38a6c91..4f83db8ba2 100644 --- a/crypto/x509/x509_txt.c +++ b/crypto/x509/x509_txt.c @@ -144,6 +144,9 @@ const char *X509_verify_cert_error_string(long n) case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: return("unable to get CRL issuer certificate"); + case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: + return("unhandled critical extension"); + default: sprintf(buf,"error number %ld",n); return(buf); diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 892b7849fd..3c69bb9e0e 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -384,6 +384,15 @@ static int check_chain_purpose(X509_STORE_CTX *ctx) for (i = 0; i < ctx->last_untrusted; i++) { x = sk_X509_value(ctx->chain, i); + if (!(ctx->flags & X509_V_FLAG_IGNORE_CRITICAL) + && (x->ex_flags & EXFLAG_CRITICAL)) + { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; + ctx->error_depth = i; + ctx->current_cert = x; + ok=cb(0,ctx); + if (!ok) goto end; + } if (!X509_check_purpose(x, ctx->purpose, i)) { if (i) @@ -721,8 +730,6 @@ static int internal_verify(X509_STORE_CTX *ctx) if (!ok) goto end; } - /* CRL CHECK */ - /* The last error (if any) is still in the error value */ ctx->current_cert=xs; ok=(*cb)(1,ctx); diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h index 689062fa30..f0be21f452 100644 --- a/crypto/x509/x509_vfy.h +++ b/crypto/x509/x509_vfy.h @@ -303,6 +303,7 @@ struct x509_store_ctx_st /* X509_STORE_CTX */ #define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 #define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 /* The application is not happy */ #define X509_V_ERR_APPLICATION_VERIFICATION 50 @@ -313,6 +314,7 @@ struct x509_store_ctx_st /* X509_STORE_CTX */ #define X509_V_FLAG_USE_CHECK_TIME 0x2 /* Use check time instead of current time */ #define X509_V_FLAG_CRL_CHECK 0x4 /* Lookup CRLs */ #define X509_V_FLAG_CRL_CHECK_ALL 0x8 /* Lookup CRLs for whole chain */ +#define X509_V_FLAG_IGNORE_CRITICAL 0x10 /* Ignore unhandled critical extensions */ int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name); diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c index ad55016236..b739e4fd83 100644 --- a/crypto/x509v3/v3_purp.c +++ b/crypto/x509v3/v3_purp.c @@ -1,9 +1,9 @@ /* v3_purp.c */ /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL - * project 1999. + * project 2001. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -266,12 +266,51 @@ int X509_PURPOSE_get_trust(X509_PURPOSE *xp) return xp->trust; } +static int nid_cmp(int *a, int *b) + { + return *a - *b; + } + +int X509_supported_extension(X509_EXTENSION *ex) + { + /* This table is a list of the NIDs of supported extensions: + * that is those which are used by the verify process. If + * an extension is critical and doesn't appear in this list + * then the verify process will normally reject the certificate. + * The list must be kept in numerical order because it will be + * searched using bsearch. + */ + + static int supported_nids[] = { + NID_netscape_cert_type, /* 71 */ + NID_key_usage, /* 83 */ + NID_subject_alt_name, /* 85 */ + NID_basic_constraints, /* 87 */ + NID_ext_key_usage /* 126 */ + }; + + int ex_nid; + + ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); + + if (ex_nid == NID_undef) + return 0; + + if (OBJ_bsearch((char *)&ex_nid, (char *)supported_nids, + sizeof(supported_nids)/sizeof(int), sizeof(int), + (int (*)(const void *, const void *))nid_cmp)) + return 1; + return 0; + } + + static void x509v3_cache_extensions(X509 *x) { BASIC_CONSTRAINTS *bs; ASN1_BIT_STRING *usage; ASN1_BIT_STRING *ns; EXTENDED_KEY_USAGE *extusage; + X509_EXTENSION *ex; int i; if(x->ex_flags & EXFLAG_SET) return; @@ -352,6 +391,17 @@ static void x509v3_cache_extensions(X509 *x) } x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL); x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL); + for (i = 0; i < X509_get_ext_count(x); i++) + { + ex = X509_get_ext(x, i); + if (!X509_EXTENSION_get_critical(ex)) + continue; + if (!X509_supported_extension(ex)) + { + x->ex_flags |= EXFLAG_CRITICAL; + break; + } + } x->ex_flags |= EXFLAG_SET; } diff --git a/crypto/x509v3/x509v3.h b/crypto/x509v3/x509v3.h index 096dc56b68..d1c9828f78 100644 --- a/crypto/x509v3/x509v3.h +++ b/crypto/x509v3/x509v3.h @@ -324,6 +324,7 @@ DECLARE_ASN1_SET_OF(POLICYINFO) #define EXFLAG_V1 0x40 #define EXFLAG_INVALID 0x80 #define EXFLAG_SET 0x100 +#define EXFLAG_CRITICAL 0x200 #define KU_DIGITAL_SIGNATURE 0x0080 #define KU_NON_REPUDIATION 0x0040 @@ -528,6 +529,7 @@ int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); int X509V3_extensions_print(BIO *out, char *title, STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent); int X509_check_purpose(X509 *x, int id, int ca); +int X509_supported_extension(X509_EXTENSION *ex); int X509_PURPOSE_set(int *p, int purpose); int X509_check_issued(X509 *issuer, X509 *subject); int X509_PURPOSE_get_count(void); |