/*
- * 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
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <stdio.h>
+#include <sys/types.h>
-#include "e_os.h"
-#ifndef NO_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
+#include "internal/nelem.h"
#include "internal/o_dir.h"
-#include <openssl/lhash.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <openssl/dh.h>
#include <openssl/bn.h>
#include <openssl/crypto.h>
-#include "ssl_locl.h"
+#include "internal/refcount.h"
+#include "ssl_local.h"
+#include "ssl_cert_table.h"
#include "internal/thread_once.h"
static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx,
ret->client_sigalgslen = cert->client_sigalgslen;
} else
ret->client_sigalgs = NULL;
- /* Shared sigalgs also NULL */
- ret->shared_sigalgs = NULL;
/* Copy any custom client certificate types */
if (cert->ctype) {
ret->ctype = OPENSSL_memdup(cert->ctype, cert->ctype_len);
if (c == NULL)
return;
-
CRYPTO_DOWN_REF(&c->references, &i, c->lock);
REF_PRINT_COUNT("CERT", c);
if (i > 0)
ssl_cert_clear_certs(c);
OPENSSL_free(c->conf_sigalgs);
OPENSSL_free(c->client_sigalgs);
- OPENSSL_free(c->shared_sigalgs);
OPENSSL_free(c->ctype);
X509_STORE_free(c->verify_store);
X509_STORE_free(c->chain_store);
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)
void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list)
{
- SSL_CTX_set0_CA_list(ctx, name_list);
+ set0_CA_list(&ctx->client_ca_names, name_list);
}
STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
{
- return ctx->ca_names;
+ return ctx->client_ca_names;
}
void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list)
{
- SSL_set0_CA_list(s, name_list);
+ set0_CA_list(&s->client_ca_names, name_list);
}
const STACK_OF(X509_NAME) *SSL_get0_peer_CA_list(const SSL *s)
{
- return s->s3 != NULL ? s->s3->tmp.peer_ca_names : NULL;
+ return s->s3.tmp.peer_ca_names;
}
STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s)
{
if (!s->server)
- return s->s3 != NULL ? s->s3->tmp.peer_ca_names : NULL;
- return s->ca_names != NULL ? s->ca_names : s->ctx->ca_names;
+ return s->s3.tmp.peer_ca_names;
+ return s->client_ca_names != NULL ? s->client_ca_names
+ : s->ctx->client_ca_names;
}
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);
+ return add_ca_name(&ssl->client_ca_names, x);
}
int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
{
- return add_ca_name(&ctx->ca_names, x);
+ return add_ca_name(&ctx->client_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)
lh_X509_NAME_free(name_hash);
if (ret != NULL)
ERR_clear_error();
- return (ret);
+ return ret;
}
/**
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;
}
if (errno) {
- SYSerr(SYS_F_OPENDIR, get_last_sys_error());
- ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
+ ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+ "calling OPENSSL_dir_read(%s)",
+ dir);
SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB);
goto err;
}
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;
}
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];
}