From a95585a25ab25668b931a78b7543f707a3354db8 Mon Sep 17 00:00:00 2001 From: djm <> Date: Fri, 29 Apr 2005 05:37:34 +0000 Subject: import of openssl-0.9.7g; tested on platforms from alpha to zaurus, ok deraadt@ --- src/lib/libcrypto/x509v3/ext_dat.h | 11 +- src/lib/libcrypto/x509v3/v3_bitst.c | 7 +- src/lib/libcrypto/x509v3/v3_ia5.c | 5 +- src/lib/libcrypto/x509v3/v3_int.c | 19 ++- src/lib/libcrypto/x509v3/v3_pci.c | 313 ++++++++++++++++++++++++++++++++++++ src/lib/libcrypto/x509v3/v3_pcia.c | 55 +++++++ src/lib/libcrypto/x509v3/v3_purp.c | 75 +++++---- src/lib/libcrypto/x509v3/v3err.c | 14 +- src/lib/libcrypto/x509v3/x509v3.h | 31 ++++ 9 files changed, 488 insertions(+), 42 deletions(-) create mode 100644 src/lib/libcrypto/x509v3/v3_pci.c create mode 100644 src/lib/libcrypto/x509v3/v3_pcia.c (limited to 'src/lib/libcrypto/x509v3') diff --git a/src/lib/libcrypto/x509v3/ext_dat.h b/src/lib/libcrypto/x509v3/ext_dat.h index 5442480595..d8328ac468 100644 --- a/src/lib/libcrypto/x509v3/ext_dat.h +++ b/src/lib/libcrypto/x509v3/ext_dat.h @@ -3,7 +3,7 @@ * project 1999. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2004 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 @@ -60,10 +60,11 @@ extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo; extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id; -extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate, v3_cpols, v3_crld; +extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; +extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld; extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff; extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc; -extern X509V3_EXT_METHOD v3_crl_hold; +extern X509V3_EXT_METHOD v3_crl_hold, v3_pci; /* This table will be searched using OBJ_bsearch so it *must* kept in * order of the ext_nid values. @@ -89,6 +90,7 @@ static X509V3_EXT_METHOD *standard_exts[] = { &v3_akey_id, &v3_crld, &v3_ext_ku, +&v3_delta_crl, &v3_crl_reason, #ifndef OPENSSL_NO_OCSP &v3_crl_invdate, @@ -105,8 +107,9 @@ static X509V3_EXT_METHOD *standard_exts[] = { #endif &v3_sinfo, #ifndef OPENSSL_NO_OCSP -&v3_crl_hold +&v3_crl_hold, #endif +&v3_pci, }; /* Number of standard extensions */ diff --git a/src/lib/libcrypto/x509v3/v3_bitst.c b/src/lib/libcrypto/x509v3/v3_bitst.c index 16cf125562..274965306d 100644 --- a/src/lib/libcrypto/x509v3/v3_bitst.c +++ b/src/lib/libcrypto/x509v3/v3_bitst.c @@ -124,7 +124,12 @@ static ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, for(bnam = method->usr_data; bnam->lname; bnam++) { if(!strcmp(bnam->sname, val->name) || !strcmp(bnam->lname, val->name) ) { - ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1); + if(!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) { + X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, + ERR_R_MALLOC_FAILURE); + M_ASN1_BIT_STRING_free(bs); + return NULL; + } break; } } diff --git a/src/lib/libcrypto/x509v3/v3_ia5.c b/src/lib/libcrypto/x509v3/v3_ia5.c index f9414456de..9683afa47c 100644 --- a/src/lib/libcrypto/x509v3/v3_ia5.c +++ b/src/lib/libcrypto/x509v3/v3_ia5.c @@ -82,7 +82,10 @@ static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, { char *tmp; if(!ia5 || !ia5->length) return NULL; - if (!(tmp = OPENSSL_malloc(ia5->length + 1))) return NULL; + if(!(tmp = OPENSSL_malloc(ia5->length + 1))) { + X509V3err(X509V3_F_I2S_ASN1_IA5STRING,ERR_R_MALLOC_FAILURE); + return NULL; + } memcpy(tmp, ia5->data, ia5->length); tmp[ia5->length] = 0; return tmp; diff --git a/src/lib/libcrypto/x509v3/v3_int.c b/src/lib/libcrypto/x509v3/v3_int.c index f34cbfb731..7a43b4717b 100644 --- a/src/lib/libcrypto/x509v3/v3_int.c +++ b/src/lib/libcrypto/x509v3/v3_int.c @@ -3,7 +3,7 @@ * project 1999. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2004 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 @@ -61,9 +61,16 @@ #include X509V3_EXT_METHOD v3_crl_num = { -NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER), -0,0,0,0, -(X509V3_EXT_I2S)i2s_ASN1_INTEGER, -0, -0,0,0,0, NULL}; + NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER), + 0,0,0,0, + (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + 0, + 0,0,0,0, NULL}; + +X509V3_EXT_METHOD v3_delta_crl = { + NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER), + 0,0,0,0, + (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + 0, + 0,0,0,0, NULL}; diff --git a/src/lib/libcrypto/x509v3/v3_pci.c b/src/lib/libcrypto/x509v3/v3_pci.c new file mode 100644 index 0000000000..b32d968619 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_pci.c @@ -0,0 +1,313 @@ +/* v3_pci.c -*- mode:C; c-file-style: "eay" -*- */ +/* Contributed to the OpenSSL Project 2004 + * by Richard Levitte (richard@levitte.org) + */ +/* Copyright (c) 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include "cryptlib.h" +#include +#include + +static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext, + BIO *out, int indent); +static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); + +X509V3_EXT_METHOD v3_pci = + { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION), + 0,0,0,0, + 0,0, + NULL, NULL, + (X509V3_EXT_I2R)i2r_pci, + (X509V3_EXT_R2I)r2i_pci, + NULL, + }; + +static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci, + BIO *out, int indent) + { + BIO_printf(out, "%*sPath Length Constraint: ", indent, ""); + if (pci->pcPathLengthConstraint) + i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint); + else + BIO_printf(out, "infinite"); + BIO_puts(out, "\n"); + BIO_printf(out, "%*sPolicy Language: ", indent, ""); + i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage); + BIO_puts(out, "\n"); + if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data) + BIO_printf(out, "%*sPolicy Text: %s\n", indent, "", + pci->proxyPolicy->policy->data); + return 1; + } + +static int process_pci_value(CONF_VALUE *val, + ASN1_OBJECT **language, ASN1_INTEGER **pathlen, + ASN1_OCTET_STRING **policy) + { + int free_policy = 0; + + if (strcmp(val->name, "language") == 0) + { + if (*language) + { + X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED); + X509V3_conf_err(val); + return 0; + } + if (!(*language = OBJ_txt2obj(val->value, 0))) + { + X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return 0; + } + } + else if (strcmp(val->name, "pathlen") == 0) + { + if (*pathlen) + { + X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED); + X509V3_conf_err(val); + return 0; + } + if (!X509V3_get_value_int(val, pathlen)) + { + X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_PATH_LENGTH); + X509V3_conf_err(val); + return 0; + } + } + else if (strcmp(val->name, "policy") == 0) + { + unsigned char *tmp_data = NULL; + long val_len; + if (!*policy) + { + *policy = ASN1_OCTET_STRING_new(); + if (!*policy) + { + X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + return 0; + } + free_policy = 1; + } + if (strncmp(val->value, "hex:", 4) == 0) + { + unsigned char *tmp_data2 = + string_to_hex(val->value + 4, &val_len); + + if (!tmp_data2) goto err; + + tmp_data = OPENSSL_realloc((*policy)->data, + (*policy)->length + val_len + 1); + if (tmp_data) + { + (*policy)->data = tmp_data; + memcpy(&(*policy)->data[(*policy)->length], + tmp_data2, val_len); + (*policy)->length += val_len; + (*policy)->data[(*policy)->length] = '\0'; + } + } + else if (strncmp(val->value, "file:", 5) == 0) + { + unsigned char buf[2048]; + int n; + BIO *b = BIO_new_file(val->value + 5, "r"); + if (!b) + { + X509V3err(X509V3_F_R2I_PCI,ERR_R_BIO_LIB); + X509V3_conf_err(val); + goto err; + } + while((n = BIO_read(b, buf, sizeof(buf))) > 0 + || (n == 0 && BIO_should_retry(b))) + { + if (!n) continue; + + tmp_data = OPENSSL_realloc((*policy)->data, + (*policy)->length + n + 1); + + if (!tmp_data) + break; + + (*policy)->data = tmp_data; + memcpy(&(*policy)->data[(*policy)->length], + buf, n); + (*policy)->length += n; + (*policy)->data[(*policy)->length] = '\0'; + } + + if (n < 0) + { + X509V3err(X509V3_F_R2I_PCI,ERR_R_BIO_LIB); + X509V3_conf_err(val); + goto err; + } + } + else if (strncmp(val->value, "text:", 5) == 0) + { + val_len = strlen(val->value + 5); + tmp_data = OPENSSL_realloc((*policy)->data, + (*policy)->length + val_len + 1); + if (tmp_data) + { + (*policy)->data = tmp_data; + memcpy(&(*policy)->data[(*policy)->length], + val->value + 5, val_len); + (*policy)->length += val_len; + (*policy)->data[(*policy)->length] = '\0'; + } + } + else + { + X509V3err(X509V3_F_R2I_PCI,X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); + X509V3_conf_err(val); + goto err; + } + if (!tmp_data) + { + X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + } + return 1; +err: + if (free_policy) + { + ASN1_OCTET_STRING_free(*policy); + *policy = NULL; + } + return 0; + } + +static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *value) + { + PROXY_CERT_INFO_EXTENSION *pci = NULL; + STACK_OF(CONF_VALUE) *vals; + ASN1_OBJECT *language = NULL; + ASN1_INTEGER *pathlen = NULL; + ASN1_OCTET_STRING *policy = NULL; + int i, j; + + vals = X509V3_parse_list(value); + for (i = 0; i < sk_CONF_VALUE_num(vals); i++) + { + CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i); + if (!cnf->name || (*cnf->name != '@' && !cnf->value)) + { + X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_PROXY_POLICY_SETTING); + X509V3_conf_err(cnf); + goto err; + } + if (*cnf->name == '@') + { + STACK_OF(CONF_VALUE) *sect; + int success_p = 1; + + sect = X509V3_get_section(ctx, cnf->name + 1); + if (!sect) + { + X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_SECTION); + X509V3_conf_err(cnf); + goto err; + } + for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) + { + success_p = + process_pci_value(sk_CONF_VALUE_value(sect, j), + &language, &pathlen, &policy); + } + X509V3_section_free(ctx, sect); + if (!success_p) + goto err; + } + else + { + if (!process_pci_value(cnf, + &language, &pathlen, &policy)) + { + X509V3_conf_err(cnf); + goto err; + } + } + } + + /* Language is mandatory */ + if (!language) + { + X509V3err(X509V3_F_R2I_PCI,X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED); + goto err; + } + i = OBJ_obj2nid(language); + if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy) + { + X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY); + goto err; + } + + pci = PROXY_CERT_INFO_EXTENSION_new(); + if (!pci) + { + X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE); + goto err; + } + pci->proxyPolicy = PROXY_POLICY_new(); + if (!pci->proxyPolicy) + { + X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE); + goto err; + } + + pci->proxyPolicy->policyLanguage = language; language = NULL; + pci->proxyPolicy->policy = policy; policy = NULL; + pci->pcPathLengthConstraint = pathlen; pathlen = NULL; + goto end; +err: + if (language) { ASN1_OBJECT_free(language); language = NULL; } + if (pathlen) { ASN1_INTEGER_free(pathlen); pathlen = NULL; } + if (policy) { ASN1_OCTET_STRING_free(policy); policy = NULL; } + if (pci && pci->proxyPolicy) + { + PROXY_POLICY_free(pci->proxyPolicy); + pci->proxyPolicy = NULL; + } + if (pci) { PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; } +end: + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + return pci; + } diff --git a/src/lib/libcrypto/x509v3/v3_pcia.c b/src/lib/libcrypto/x509v3/v3_pcia.c new file mode 100644 index 0000000000..bb362e0e5a --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_pcia.c @@ -0,0 +1,55 @@ +/* v3_pcia.c -*- mode:C; c-file-style: "eay" -*- */ +/* Contributed to the OpenSSL Project 2004 + * by Richard Levitte (richard@levitte.org) + */ +/* Copyright (c) 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +ASN1_SEQUENCE(PROXY_POLICY) = + { + ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT), + ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(PROXY_POLICY) + +IMPLEMENT_ASN1_FUNCTIONS(PROXY_POLICY) + +ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION) = + { + ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER), + ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY) +} ASN1_SEQUENCE_END(PROXY_CERT_INFO_EXTENSION) + +IMPLEMENT_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) diff --git a/src/lib/libcrypto/x509v3/v3_purp.c b/src/lib/libcrypto/x509v3/v3_purp.c index b3d1ae5d1c..bbdf6da493 100644 --- a/src/lib/libcrypto/x509v3/v3_purp.c +++ b/src/lib/libcrypto/x509v3/v3_purp.c @@ -63,7 +63,6 @@ static void x509v3_cache_extensions(X509 *x); -static int ca_check(const X509 *x); static int check_ssl_ca(const X509 *x); static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca); static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca); @@ -286,7 +285,8 @@ int X509_supported_extension(X509_EXTENSION *ex) NID_key_usage, /* 83 */ NID_subject_alt_name, /* 85 */ NID_basic_constraints, /* 87 */ - NID_ext_key_usage /* 126 */ + NID_ext_key_usage, /* 126 */ + NID_proxyCertInfo /* 661 */ }; int ex_nid; @@ -307,6 +307,7 @@ int X509_supported_extension(X509_EXTENSION *ex) static void x509v3_cache_extensions(X509 *x) { BASIC_CONSTRAINTS *bs; + PROXY_CERT_INFO_EXTENSION *pci; ASN1_BIT_STRING *usage; ASN1_BIT_STRING *ns; EXTENDED_KEY_USAGE *extusage; @@ -335,6 +336,16 @@ static void x509v3_cache_extensions(X509 *x) BASIC_CONSTRAINTS_free(bs); x->ex_flags |= EXFLAG_BCONS; } + /* Handle proxy certificates */ + if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) { + if (x->ex_flags & EXFLAG_CA + || X509_get_ext_by_NID(x, NID_subject_alt_name, 0) >= 0 + || X509_get_ext_by_NID(x, NID_issuer_alt_name, 0) >= 0) { + x->ex_flags |= EXFLAG_INVALID; + } + PROXY_CERT_INFO_EXTENSION_free(pci); + x->ex_flags |= EXFLAG_PROXY; + } /* Handle key usage */ if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) { if(usage->length > 0) { @@ -426,7 +437,7 @@ static void x509v3_cache_extensions(X509 *x) #define ns_reject(x, usage) \ (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) -static int ca_check(const X509 *x) +static int check_ca(const X509 *x) { /* keyUsage if present should allow cert signing */ if(ku_reject(x, KU_KEY_CERT_SIGN)) return 0; @@ -435,25 +446,37 @@ static int ca_check(const X509 *x) /* If basicConstraints says not a CA then say so */ else return 0; } else { + /* we support V1 roots for... uh, I don't really know why. */ if((x->ex_flags & V1_ROOT) == V1_ROOT) return 3; /* If key usage present it must have certSign so tolerate it */ else if (x->ex_flags & EXFLAG_KUSAGE) return 4; - else return 2; + /* Older certificates could have Netscape-specific CA types */ + else if (x->ex_flags & EXFLAG_NSCERT + && x->ex_nscert & NS_ANY_CA) return 5; + /* can this still be regarded a CA certificate? I doubt it */ + return 0; } } +int X509_check_ca(X509 *x) +{ + if(!(x->ex_flags & EXFLAG_SET)) { + CRYPTO_w_lock(CRYPTO_LOCK_X509); + x509v3_cache_extensions(x); + CRYPTO_w_unlock(CRYPTO_LOCK_X509); + } + + return check_ca(x); +} + /* Check SSL CA: common checks for SSL client and server */ static int check_ssl_ca(const X509 *x) { int ca_ret; - ca_ret = ca_check(x); + ca_ret = check_ca(x); if(!ca_ret) return 0; /* check nsCertType if present */ - if(x->ex_flags & EXFLAG_NSCERT) { - if(x->ex_nscert & NS_SSL_CA) return ca_ret; - return 0; - } - if(ca_ret != 2) return ca_ret; + if(ca_ret != 5 || x->ex_nscert & NS_SSL_CA) return ca_ret; else return 0; } @@ -498,14 +521,10 @@ static int purpose_smime(const X509 *x, int ca) if(xku_reject(x,XKU_SMIME)) return 0; if(ca) { int ca_ret; - ca_ret = ca_check(x); + ca_ret = check_ca(x); if(!ca_ret) return 0; /* check nsCertType if present */ - if(x->ex_flags & EXFLAG_NSCERT) { - if(x->ex_nscert & NS_SMIME_CA) return ca_ret; - return 0; - } - if(ca_ret != 2) return ca_ret; + if(ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) return ca_ret; else return 0; } if(x->ex_flags & EXFLAG_NSCERT) { @@ -539,7 +558,7 @@ static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca) { if(ca) { int ca_ret; - if((ca_ret = ca_check(x)) != 2) return ca_ret; + if((ca_ret = check_ca(x)) != 2) return ca_ret; else return 0; } if(ku_reject(x, KU_CRL_SIGN)) return 0; @@ -552,17 +571,9 @@ static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca) static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) { - /* Must be a valid CA */ - if(ca) { - int ca_ret; - ca_ret = ca_check(x); - if(ca_ret != 2) return ca_ret; - if(x->ex_flags & EXFLAG_NSCERT) { - if(x->ex_nscert & NS_ANY_CA) return ca_ret; - return 0; - } - return 0; - } + /* Must be a valid CA. Should we really support the "I don't know" + value (2)? */ + if(ca) return check_ca(x); /* leaf certificate is checked in OCSP_verify() */ return 1; } @@ -624,7 +635,13 @@ int X509_check_issued(X509 *issuer, X509 *subject) return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; } } - if(ku_reject(issuer, KU_KEY_CERT_SIGN)) return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; + if(subject->ex_flags & EXFLAG_PROXY) + { + if(ku_reject(issuer, KU_DIGITAL_SIGNATURE)) + return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; + } + else if(ku_reject(issuer, KU_KEY_CERT_SIGN)) + return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; return X509_V_OK; } diff --git a/src/lib/libcrypto/x509v3/v3err.c b/src/lib/libcrypto/x509v3/v3err.c index 6458e95bb9..2df0c3ef01 100644 --- a/src/lib/libcrypto/x509v3/v3err.c +++ b/src/lib/libcrypto/x509v3/v3err.c @@ -1,6 +1,6 @@ /* crypto/x509v3/v3err.c */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2005 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 @@ -72,12 +72,14 @@ static ERR_STRING_DATA X509V3_str_functs[]= {ERR_PACK(0,X509V3_F_DO_EXT_I2D,0), "DO_EXT_I2D"}, {ERR_PACK(0,X509V3_F_HEX_TO_STRING,0), "hex_to_string"}, {ERR_PACK(0,X509V3_F_I2S_ASN1_ENUMERATED,0), "i2s_ASN1_ENUMERATED"}, +{ERR_PACK(0,X509V3_F_I2S_ASN1_IA5STRING,0), "I2S_ASN1_IA5STRING"}, {ERR_PACK(0,X509V3_F_I2S_ASN1_INTEGER,0), "i2s_ASN1_INTEGER"}, {ERR_PACK(0,X509V3_F_I2V_AUTHORITY_INFO_ACCESS,0), "I2V_AUTHORITY_INFO_ACCESS"}, {ERR_PACK(0,X509V3_F_NOTICE_SECTION,0), "NOTICE_SECTION"}, {ERR_PACK(0,X509V3_F_NREF_NOS,0), "NREF_NOS"}, {ERR_PACK(0,X509V3_F_POLICY_SECTION,0), "POLICY_SECTION"}, {ERR_PACK(0,X509V3_F_R2I_CERTPOL,0), "R2I_CERTPOL"}, +{ERR_PACK(0,X509V3_F_R2I_PCI,0), "R2I_PCI"}, {ERR_PACK(0,X509V3_F_S2I_ASN1_IA5STRING,0), "S2I_ASN1_IA5STRING"}, {ERR_PACK(0,X509V3_F_S2I_ASN1_INTEGER,0), "s2i_ASN1_INTEGER"}, {ERR_PACK(0,X509V3_F_S2I_ASN1_OCTET_STRING,0), "s2i_ASN1_OCTET_STRING"}, @@ -128,6 +130,7 @@ static ERR_STRING_DATA X509V3_str_reasons[]= {X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED,"extension setting not supported"}, {X509V3_R_EXTENSION_VALUE_ERROR ,"extension value error"}, {X509V3_R_ILLEGAL_HEX_DIGIT ,"illegal hex digit"}, +{X509V3_R_INCORRECT_POLICY_SYNTAX_TAG ,"incorrect policy syntax tag"}, {X509V3_R_INVALID_BOOLEAN_STRING ,"invalid boolean string"}, {X509V3_R_INVALID_EXTENSION_STRING ,"invalid extension string"}, {X509V3_R_INVALID_NAME ,"invalid name"}, @@ -139,6 +142,8 @@ static ERR_STRING_DATA X509V3_str_reasons[]= {X509V3_R_INVALID_OBJECT_IDENTIFIER ,"invalid object identifier"}, {X509V3_R_INVALID_OPTION ,"invalid option"}, {X509V3_R_INVALID_POLICY_IDENTIFIER ,"invalid policy identifier"}, +{X509V3_R_INVALID_PROXY_POLICY_IDENTIFIER,"invalid proxy policy identifier"}, +{X509V3_R_INVALID_PROXY_POLICY_SETTING ,"invalid proxy policy setting"}, {X509V3_R_INVALID_PURPOSE ,"invalid purpose"}, {X509V3_R_INVALID_SECTION ,"invalid section"}, {X509V3_R_INVALID_SYNTAX ,"invalid syntax"}, @@ -149,9 +154,16 @@ static ERR_STRING_DATA X509V3_str_reasons[]= {X509V3_R_NO_ISSUER_CERTIFICATE ,"no issuer certificate"}, {X509V3_R_NO_ISSUER_DETAILS ,"no issuer details"}, {X509V3_R_NO_POLICY_IDENTIFIER ,"no policy identifier"}, +{X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED,"no proxy cert policy language defined"}, {X509V3_R_NO_PUBLIC_KEY ,"no public key"}, {X509V3_R_NO_SUBJECT_DETAILS ,"no subject details"}, {X509V3_R_ODD_NUMBER_OF_DIGITS ,"odd number of digits"}, +{X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED,"policy language alreadty defined"}, +{X509V3_R_POLICY_PATH_LENGTH ,"policy path length"}, +{X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED,"policy path length alreadty defined"}, +{X509V3_R_POLICY_SYNTAX_NOT ,"policy syntax not"}, +{X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED,"policy syntax not currently supported"}, +{X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY,"policy when proxy language requires no policy"}, {X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS ,"unable to get issuer details"}, {X509V3_R_UNABLE_TO_GET_ISSUER_KEYID ,"unable to get issuer keyid"}, {X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT ,"unknown bit string argument"}, diff --git a/src/lib/libcrypto/x509v3/x509v3.h b/src/lib/libcrypto/x509v3/x509v3.h index fb07a19016..e6d91251c2 100644 --- a/src/lib/libcrypto/x509v3/x509v3.h +++ b/src/lib/libcrypto/x509v3/x509v3.h @@ -287,6 +287,23 @@ typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; DECLARE_STACK_OF(POLICYINFO) DECLARE_ASN1_SET_OF(POLICYINFO) +/* Proxy certificate structures, see RFC 3820 */ +typedef struct PROXY_POLICY_st + { + ASN1_OBJECT *policyLanguage; + ASN1_OCTET_STRING *policy; + } PROXY_POLICY; + +typedef struct PROXY_CERT_INFO_EXTENSION_st + { + ASN1_INTEGER *pcPathLengthConstraint; + PROXY_POLICY *proxyPolicy; + } PROXY_CERT_INFO_EXTENSION; + +DECLARE_ASN1_FUNCTIONS(PROXY_POLICY) +DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) + + #define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \ ",name:", val->name, ",value:", val->value); @@ -325,6 +342,7 @@ DECLARE_ASN1_SET_OF(POLICYINFO) #define EXFLAG_INVALID 0x80 #define EXFLAG_SET 0x100 #define EXFLAG_CRITICAL 0x200 +#define EXFLAG_PROXY 0x400 #define KU_DIGITAL_SIGNATURE 0x0080 #define KU_NON_REPUDIATION 0x0040 @@ -527,6 +545,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_ca(X509 *x); 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); @@ -564,12 +583,14 @@ void ERR_load_X509V3_strings(void); #define X509V3_F_DO_EXT_I2D 135 #define X509V3_F_HEX_TO_STRING 111 #define X509V3_F_I2S_ASN1_ENUMERATED 121 +#define X509V3_F_I2S_ASN1_IA5STRING 142 #define X509V3_F_I2S_ASN1_INTEGER 120 #define X509V3_F_I2V_AUTHORITY_INFO_ACCESS 138 #define X509V3_F_NOTICE_SECTION 132 #define X509V3_F_NREF_NOS 133 #define X509V3_F_POLICY_SECTION 131 #define X509V3_F_R2I_CERTPOL 130 +#define X509V3_F_R2I_PCI 142 #define X509V3_F_S2I_ASN1_IA5STRING 100 #define X509V3_F_S2I_ASN1_INTEGER 108 #define X509V3_F_S2I_ASN1_OCTET_STRING 112 @@ -617,6 +638,7 @@ void ERR_load_X509V3_strings(void); #define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103 #define X509V3_R_EXTENSION_VALUE_ERROR 116 #define X509V3_R_ILLEGAL_HEX_DIGIT 113 +#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 153 #define X509V3_R_INVALID_BOOLEAN_STRING 104 #define X509V3_R_INVALID_EXTENSION_STRING 105 #define X509V3_R_INVALID_NAME 106 @@ -628,6 +650,8 @@ void ERR_load_X509V3_strings(void); #define X509V3_R_INVALID_OBJECT_IDENTIFIER 110 #define X509V3_R_INVALID_OPTION 138 #define X509V3_R_INVALID_POLICY_IDENTIFIER 134 +#define X509V3_R_INVALID_PROXY_POLICY_IDENTIFIER 147 +#define X509V3_R_INVALID_PROXY_POLICY_SETTING 151 #define X509V3_R_INVALID_PURPOSE 146 #define X509V3_R_INVALID_SECTION 135 #define X509V3_R_INVALID_SYNTAX 143 @@ -638,9 +662,16 @@ void ERR_load_X509V3_strings(void); #define X509V3_R_NO_ISSUER_CERTIFICATE 121 #define X509V3_R_NO_ISSUER_DETAILS 127 #define X509V3_R_NO_POLICY_IDENTIFIER 139 +#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 148 #define X509V3_R_NO_PUBLIC_KEY 114 #define X509V3_R_NO_SUBJECT_DETAILS 125 #define X509V3_R_ODD_NUMBER_OF_DIGITS 112 +#define X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED 149 +#define X509V3_R_POLICY_PATH_LENGTH 152 +#define X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED 150 +#define X509V3_R_POLICY_SYNTAX_NOT 154 +#define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED 155 +#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 156 #define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 122 #define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 123 #define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111 -- cgit v1.2.3-55-g6feb