X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_cert.c;h=52a4a7eaadd2028784172ba76e91ec5c994d5371;hp=a87933d1f65d91e76a916c77291257a3d0a67c90;hb=8f39d8af7de12d5ac8699e54cf2fd8ae2325bcf2;hpb=c04cd72827a8a1eccaf75062403c301dd16892be diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index a87933d1f6..52a4a7eaad 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the OpenSSL license (the "License"). You may not use @@ -9,21 +9,19 @@ */ #include +#include -#include "e_os.h" -#ifndef NO_SYS_TYPES_H -# include -#endif - +#include "internal/nelem.h" #include "internal/o_dir.h" -#include #include #include #include #include #include #include +#include "internal/refcount.h" #include "ssl_locl.h" +#include "ssl_cert_table.h" #include "internal/thread_once.h" static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, @@ -229,7 +227,6 @@ void ssl_cert_free(CERT *c) if (c == NULL) return; - CRYPTO_DOWN_REF(&c->references, &i, c->lock); REF_PRINT_COUNT("CERT", c); if (i > 0) @@ -461,23 +458,25 @@ static void set0_CA_list(STACK_OF(X509_NAME) **ca_list, STACK_OF(X509_NAME) *SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk) { int i; + const int num = sk_X509_NAME_num(sk); STACK_OF(X509_NAME) *ret; X509_NAME *name; - ret = sk_X509_NAME_new_null(); + ret = sk_X509_NAME_new_reserve(NULL, num); if (ret == NULL) { SSLerr(SSL_F_SSL_DUP_CA_LIST, ERR_R_MALLOC_FAILURE); return NULL; } - for (i = 0; i < sk_X509_NAME_num(sk); i++) { + for (i = 0; i < num; i++) { name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); - if (name == NULL || !sk_X509_NAME_push(ret, name)) { + if (name == NULL) { + SSLerr(SSL_F_SSL_DUP_CA_LIST, ERR_R_MALLOC_FAILURE); sk_X509_NAME_pop_free(ret, X509_NAME_free); - X509_NAME_free(name); return NULL; } + sk_X509_NAME_push(ret, name); /* Cannot fail after reserve call */ } - return (ret); + return ret; } void SSL_set0_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) @@ -546,16 +545,20 @@ static int add_ca_name(STACK_OF(X509_NAME) **sk, const X509 *x) return 1; } -int SSL_add1_CA_list(SSL *ssl, const X509 *x) +int SSL_add1_to_CA_list(SSL *ssl, const X509 *x) { return add_ca_name(&ssl->ca_names, x); } -int SSL_CTX_add1_CA_list(SSL_CTX *ctx, const X509 *x) +int SSL_CTX_add1_to_CA_list(SSL_CTX *ctx, const X509 *x) { return add_ca_name(&ctx->ca_names, x); } +/* + * The following two are older names are to be replaced with + * SSL(_CTX)_add1_to_CA_list + */ int SSL_add_client_CA(SSL *ssl, X509 *x) { return add_ca_name(&ssl->ca_names, x); @@ -566,14 +569,33 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) return add_ca_name(&ctx->ca_names, x); } -static int xname_sk_cmp(const X509_NAME *const *a, const X509_NAME *const *b) +static int xname_cmp(const X509_NAME *a, const X509_NAME *b) { - return (X509_NAME_cmp(*a, *b)); + unsigned char *abuf = NULL, *bbuf = NULL; + int alen, blen, ret; + + /* X509_NAME_cmp() itself casts away constness in this way, so + * assume it's safe: + */ + alen = i2d_X509_NAME((X509_NAME *)a, &abuf); + blen = i2d_X509_NAME((X509_NAME *)b, &bbuf); + + if (alen < 0 || blen < 0) + ret = -2; + else if (alen != blen) + ret = alen - blen; + else /* alen == blen */ + ret = memcmp(abuf, bbuf, alen); + + OPENSSL_free(abuf); + OPENSSL_free(bbuf); + + return ret; } -static int xname_cmp(const X509_NAME *a, const X509_NAME *b) +static int xname_sk_cmp(const X509_NAME *const *a, const X509_NAME *const *b) { - return X509_NAME_cmp(a, b); + return xname_cmp(*a, *b); } static unsigned long xname_hash(const X509_NAME *a) @@ -643,7 +665,7 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) lh_X509_NAME_free(name_hash); if (ret != NULL) ERR_clear_error(); - return (ret); + return ret; } /** @@ -729,15 +751,15 @@ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, char buf[1024]; int r; - if (strlen(dir) + strlen(filename) + 2 > sizeof buf) { + if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) { SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, SSL_R_PATH_TOO_LONG); goto err; } #ifdef OPENSSL_SYS_VMS - r = BIO_snprintf(buf, sizeof buf, "%s%s", dir, filename); + r = BIO_snprintf(buf, sizeof(buf), "%s%s", dir, filename); #else - r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename); + r = BIO_snprintf(buf, sizeof(buf), "%s/%s", dir, filename); #endif if (r <= 0 || r >= (int)sizeof(buf)) goto err; @@ -929,7 +951,8 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, if (level >= 2 && c->algorithm_enc == SSL_RC4) return 0; /* Level 3: forward secure ciphersuites only */ - if (level >= 3 && !(c->algorithm_mkey & (SSL_kEDH | SSL_kEECDH))) + if (level >= 3 && (c->min_tls != TLS1_3_VERSION || + !(c->algorithm_mkey & (SSL_kEDH | SSL_kEECDH)))) return 0; break; } @@ -977,40 +1000,40 @@ int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid, void *other) ctx->cert->sec_ex); } -/* - * Certificate table information. NB: table entries must match SSL_PKEY indices - */ -static const SSL_CERT_LOOKUP ssl_cert_info [] = { - {EVP_PKEY_RSA, SSL_aRSA}, /* SSL_PKEY_RSA */ - {EVP_PKEY_DSA, SSL_aDSS}, /* SSL_PKEY_DSA_SIGN */ - {EVP_PKEY_EC, SSL_aECDSA}, /* SSL_PKEY_ECC */ - {NID_id_GostR3410_2001, SSL_aGOST01}, /* SSL_PKEY_GOST01 */ - {NID_id_GostR3410_2012_256, SSL_aGOST12}, /* SSL_PKEY_GOST12_256 */ - {NID_id_GostR3410_2012_512, SSL_aGOST12}, /* SSL_PKEY_GOST12_512 */ - {EVP_PKEY_ED25519, SSL_aECDSA} /* SSL_PKEY_ED25519 */ -}; +int ssl_cert_lookup_by_nid(int nid, size_t *pidx) +{ + size_t i; + + for (i = 0; i < OSSL_NELEM(ssl_cert_info); i++) { + if (ssl_cert_info[i].nid == nid) { + *pidx = i; + return 1; + } + } + + return 0; +} const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx) { int nid = EVP_PKEY_id(pk); - size_t i; + size_t tmpidx; if (nid == NID_undef) return NULL; - for (i = 0; i < OSSL_NELEM(ssl_cert_info); i++) { - if (ssl_cert_info[i].nid == nid) { - if (pidx != NULL) - *pidx = i; - return &ssl_cert_info[i]; - } - } - return NULL; + if (!ssl_cert_lookup_by_nid(nid, &tmpidx)) + return NULL; + + if (pidx != NULL) + *pidx = tmpidx; + + return &ssl_cert_info[tmpidx]; } const SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx) { if (idx >= OSSL_NELEM(ssl_cert_info)) - return 0; + return NULL; return &ssl_cert_info[idx]; }