1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved 4e1051a39Sopenharmony_ci * 5e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 6e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 7e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 8e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 9e1051a39Sopenharmony_ci */ 10e1051a39Sopenharmony_ci 11e1051a39Sopenharmony_ci#include <stdio.h> 12e1051a39Sopenharmony_ci#include <sys/types.h> 13e1051a39Sopenharmony_ci 14e1051a39Sopenharmony_ci#include "internal/nelem.h" 15e1051a39Sopenharmony_ci#include "internal/o_dir.h" 16e1051a39Sopenharmony_ci#include <openssl/bio.h> 17e1051a39Sopenharmony_ci#include <openssl/pem.h> 18e1051a39Sopenharmony_ci#include <openssl/store.h> 19e1051a39Sopenharmony_ci#include <openssl/x509v3.h> 20e1051a39Sopenharmony_ci#include <openssl/dh.h> 21e1051a39Sopenharmony_ci#include <openssl/bn.h> 22e1051a39Sopenharmony_ci#include <openssl/crypto.h> 23e1051a39Sopenharmony_ci#include "internal/refcount.h" 24e1051a39Sopenharmony_ci#include "ssl_local.h" 25e1051a39Sopenharmony_ci#include "ssl_cert_table.h" 26e1051a39Sopenharmony_ci#include "internal/thread_once.h" 27e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_POSIX_IO 28e1051a39Sopenharmony_ci# include <sys/stat.h> 29e1051a39Sopenharmony_ci# ifdef _WIN32 30e1051a39Sopenharmony_ci# define stat _stat 31e1051a39Sopenharmony_ci# endif 32e1051a39Sopenharmony_ci# ifndef S_ISDIR 33e1051a39Sopenharmony_ci# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) 34e1051a39Sopenharmony_ci# endif 35e1051a39Sopenharmony_ci#endif 36e1051a39Sopenharmony_ci 37e1051a39Sopenharmony_ci 38e1051a39Sopenharmony_cistatic int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, 39e1051a39Sopenharmony_ci int op, int bits, int nid, void *other, 40e1051a39Sopenharmony_ci void *ex); 41e1051a39Sopenharmony_ci 42e1051a39Sopenharmony_cistatic CRYPTO_ONCE ssl_x509_store_ctx_once = CRYPTO_ONCE_STATIC_INIT; 43e1051a39Sopenharmony_cistatic volatile int ssl_x509_store_ctx_idx = -1; 44e1051a39Sopenharmony_ci 45e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ssl_x509_store_ctx_init) 46e1051a39Sopenharmony_ci{ 47e1051a39Sopenharmony_ci ssl_x509_store_ctx_idx = X509_STORE_CTX_get_ex_new_index(0, 48e1051a39Sopenharmony_ci "SSL for verify callback", 49e1051a39Sopenharmony_ci NULL, NULL, NULL); 50e1051a39Sopenharmony_ci return ssl_x509_store_ctx_idx >= 0; 51e1051a39Sopenharmony_ci} 52e1051a39Sopenharmony_ci 53e1051a39Sopenharmony_ciint SSL_get_ex_data_X509_STORE_CTX_idx(void) 54e1051a39Sopenharmony_ci{ 55e1051a39Sopenharmony_ci 56e1051a39Sopenharmony_ci if (!RUN_ONCE(&ssl_x509_store_ctx_once, ssl_x509_store_ctx_init)) 57e1051a39Sopenharmony_ci return -1; 58e1051a39Sopenharmony_ci return ssl_x509_store_ctx_idx; 59e1051a39Sopenharmony_ci} 60e1051a39Sopenharmony_ci 61e1051a39Sopenharmony_ciCERT *ssl_cert_new(void) 62e1051a39Sopenharmony_ci{ 63e1051a39Sopenharmony_ci CERT *ret = OPENSSL_zalloc(sizeof(*ret)); 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_ci if (ret == NULL) { 66e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 67e1051a39Sopenharmony_ci return NULL; 68e1051a39Sopenharmony_ci } 69e1051a39Sopenharmony_ci 70e1051a39Sopenharmony_ci ret->key = &(ret->pkeys[SSL_PKEY_RSA]); 71e1051a39Sopenharmony_ci ret->references = 1; 72e1051a39Sopenharmony_ci ret->sec_cb = ssl_security_default_callback; 73e1051a39Sopenharmony_ci ret->sec_level = OPENSSL_TLS_SECURITY_LEVEL; 74e1051a39Sopenharmony_ci ret->sec_ex = NULL; 75e1051a39Sopenharmony_ci ret->lock = CRYPTO_THREAD_lock_new(); 76e1051a39Sopenharmony_ci if (ret->lock == NULL) { 77e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 78e1051a39Sopenharmony_ci OPENSSL_free(ret); 79e1051a39Sopenharmony_ci return NULL; 80e1051a39Sopenharmony_ci } 81e1051a39Sopenharmony_ci 82e1051a39Sopenharmony_ci return ret; 83e1051a39Sopenharmony_ci} 84e1051a39Sopenharmony_ci 85e1051a39Sopenharmony_ciCERT *ssl_cert_dup(CERT *cert) 86e1051a39Sopenharmony_ci{ 87e1051a39Sopenharmony_ci CERT *ret = OPENSSL_zalloc(sizeof(*ret)); 88e1051a39Sopenharmony_ci int i; 89e1051a39Sopenharmony_ci 90e1051a39Sopenharmony_ci if (ret == NULL) { 91e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 92e1051a39Sopenharmony_ci return NULL; 93e1051a39Sopenharmony_ci } 94e1051a39Sopenharmony_ci 95e1051a39Sopenharmony_ci ret->references = 1; 96e1051a39Sopenharmony_ci ret->key = &ret->pkeys[cert->key - cert->pkeys]; 97e1051a39Sopenharmony_ci ret->lock = CRYPTO_THREAD_lock_new(); 98e1051a39Sopenharmony_ci if (ret->lock == NULL) { 99e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 100e1051a39Sopenharmony_ci OPENSSL_free(ret); 101e1051a39Sopenharmony_ci return NULL; 102e1051a39Sopenharmony_ci } 103e1051a39Sopenharmony_ci 104e1051a39Sopenharmony_ci if (cert->dh_tmp != NULL) { 105e1051a39Sopenharmony_ci ret->dh_tmp = cert->dh_tmp; 106e1051a39Sopenharmony_ci EVP_PKEY_up_ref(ret->dh_tmp); 107e1051a39Sopenharmony_ci } 108e1051a39Sopenharmony_ci 109e1051a39Sopenharmony_ci ret->dh_tmp_cb = cert->dh_tmp_cb; 110e1051a39Sopenharmony_ci ret->dh_tmp_auto = cert->dh_tmp_auto; 111e1051a39Sopenharmony_ci 112e1051a39Sopenharmony_ci for (i = 0; i < SSL_PKEY_NUM; i++) { 113e1051a39Sopenharmony_ci CERT_PKEY *cpk = cert->pkeys + i; 114e1051a39Sopenharmony_ci CERT_PKEY *rpk = ret->pkeys + i; 115e1051a39Sopenharmony_ci if (cpk->x509 != NULL) { 116e1051a39Sopenharmony_ci rpk->x509 = cpk->x509; 117e1051a39Sopenharmony_ci X509_up_ref(rpk->x509); 118e1051a39Sopenharmony_ci } 119e1051a39Sopenharmony_ci 120e1051a39Sopenharmony_ci if (cpk->privatekey != NULL) { 121e1051a39Sopenharmony_ci rpk->privatekey = cpk->privatekey; 122e1051a39Sopenharmony_ci EVP_PKEY_up_ref(cpk->privatekey); 123e1051a39Sopenharmony_ci } 124e1051a39Sopenharmony_ci 125e1051a39Sopenharmony_ci if (cpk->chain) { 126e1051a39Sopenharmony_ci rpk->chain = X509_chain_up_ref(cpk->chain); 127e1051a39Sopenharmony_ci if (!rpk->chain) { 128e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 129e1051a39Sopenharmony_ci goto err; 130e1051a39Sopenharmony_ci } 131e1051a39Sopenharmony_ci } 132e1051a39Sopenharmony_ci if (cert->pkeys[i].serverinfo != NULL) { 133e1051a39Sopenharmony_ci /* Just copy everything. */ 134e1051a39Sopenharmony_ci ret->pkeys[i].serverinfo = 135e1051a39Sopenharmony_ci OPENSSL_malloc(cert->pkeys[i].serverinfo_length); 136e1051a39Sopenharmony_ci if (ret->pkeys[i].serverinfo == NULL) { 137e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 138e1051a39Sopenharmony_ci goto err; 139e1051a39Sopenharmony_ci } 140e1051a39Sopenharmony_ci ret->pkeys[i].serverinfo_length = cert->pkeys[i].serverinfo_length; 141e1051a39Sopenharmony_ci memcpy(ret->pkeys[i].serverinfo, 142e1051a39Sopenharmony_ci cert->pkeys[i].serverinfo, cert->pkeys[i].serverinfo_length); 143e1051a39Sopenharmony_ci } 144e1051a39Sopenharmony_ci } 145e1051a39Sopenharmony_ci 146e1051a39Sopenharmony_ci /* Configured sigalgs copied across */ 147e1051a39Sopenharmony_ci if (cert->conf_sigalgs) { 148e1051a39Sopenharmony_ci ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen 149e1051a39Sopenharmony_ci * sizeof(*cert->conf_sigalgs)); 150e1051a39Sopenharmony_ci if (ret->conf_sigalgs == NULL) 151e1051a39Sopenharmony_ci goto err; 152e1051a39Sopenharmony_ci memcpy(ret->conf_sigalgs, cert->conf_sigalgs, 153e1051a39Sopenharmony_ci cert->conf_sigalgslen * sizeof(*cert->conf_sigalgs)); 154e1051a39Sopenharmony_ci ret->conf_sigalgslen = cert->conf_sigalgslen; 155e1051a39Sopenharmony_ci } else 156e1051a39Sopenharmony_ci ret->conf_sigalgs = NULL; 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_ci if (cert->client_sigalgs) { 159e1051a39Sopenharmony_ci ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen 160e1051a39Sopenharmony_ci * sizeof(*cert->client_sigalgs)); 161e1051a39Sopenharmony_ci if (ret->client_sigalgs == NULL) 162e1051a39Sopenharmony_ci goto err; 163e1051a39Sopenharmony_ci memcpy(ret->client_sigalgs, cert->client_sigalgs, 164e1051a39Sopenharmony_ci cert->client_sigalgslen * sizeof(*cert->client_sigalgs)); 165e1051a39Sopenharmony_ci ret->client_sigalgslen = cert->client_sigalgslen; 166e1051a39Sopenharmony_ci } else 167e1051a39Sopenharmony_ci ret->client_sigalgs = NULL; 168e1051a39Sopenharmony_ci /* Copy any custom client certificate types */ 169e1051a39Sopenharmony_ci if (cert->ctype) { 170e1051a39Sopenharmony_ci ret->ctype = OPENSSL_memdup(cert->ctype, cert->ctype_len); 171e1051a39Sopenharmony_ci if (ret->ctype == NULL) 172e1051a39Sopenharmony_ci goto err; 173e1051a39Sopenharmony_ci ret->ctype_len = cert->ctype_len; 174e1051a39Sopenharmony_ci } 175e1051a39Sopenharmony_ci 176e1051a39Sopenharmony_ci ret->cert_flags = cert->cert_flags; 177e1051a39Sopenharmony_ci 178e1051a39Sopenharmony_ci ret->cert_cb = cert->cert_cb; 179e1051a39Sopenharmony_ci ret->cert_cb_arg = cert->cert_cb_arg; 180e1051a39Sopenharmony_ci 181e1051a39Sopenharmony_ci if (cert->verify_store) { 182e1051a39Sopenharmony_ci X509_STORE_up_ref(cert->verify_store); 183e1051a39Sopenharmony_ci ret->verify_store = cert->verify_store; 184e1051a39Sopenharmony_ci } 185e1051a39Sopenharmony_ci 186e1051a39Sopenharmony_ci if (cert->chain_store) { 187e1051a39Sopenharmony_ci X509_STORE_up_ref(cert->chain_store); 188e1051a39Sopenharmony_ci ret->chain_store = cert->chain_store; 189e1051a39Sopenharmony_ci } 190e1051a39Sopenharmony_ci 191e1051a39Sopenharmony_ci ret->sec_cb = cert->sec_cb; 192e1051a39Sopenharmony_ci ret->sec_level = cert->sec_level; 193e1051a39Sopenharmony_ci ret->sec_ex = cert->sec_ex; 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_ci if (!custom_exts_copy(&ret->custext, &cert->custext)) 196e1051a39Sopenharmony_ci goto err; 197e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_PSK 198e1051a39Sopenharmony_ci if (cert->psk_identity_hint) { 199e1051a39Sopenharmony_ci ret->psk_identity_hint = OPENSSL_strdup(cert->psk_identity_hint); 200e1051a39Sopenharmony_ci if (ret->psk_identity_hint == NULL) 201e1051a39Sopenharmony_ci goto err; 202e1051a39Sopenharmony_ci } 203e1051a39Sopenharmony_ci#endif 204e1051a39Sopenharmony_ci return ret; 205e1051a39Sopenharmony_ci 206e1051a39Sopenharmony_ci err: 207e1051a39Sopenharmony_ci ssl_cert_free(ret); 208e1051a39Sopenharmony_ci 209e1051a39Sopenharmony_ci return NULL; 210e1051a39Sopenharmony_ci} 211e1051a39Sopenharmony_ci 212e1051a39Sopenharmony_ci/* Free up and clear all certificates and chains */ 213e1051a39Sopenharmony_ci 214e1051a39Sopenharmony_civoid ssl_cert_clear_certs(CERT *c) 215e1051a39Sopenharmony_ci{ 216e1051a39Sopenharmony_ci int i; 217e1051a39Sopenharmony_ci if (c == NULL) 218e1051a39Sopenharmony_ci return; 219e1051a39Sopenharmony_ci for (i = 0; i < SSL_PKEY_NUM; i++) { 220e1051a39Sopenharmony_ci CERT_PKEY *cpk = c->pkeys + i; 221e1051a39Sopenharmony_ci X509_free(cpk->x509); 222e1051a39Sopenharmony_ci cpk->x509 = NULL; 223e1051a39Sopenharmony_ci EVP_PKEY_free(cpk->privatekey); 224e1051a39Sopenharmony_ci cpk->privatekey = NULL; 225e1051a39Sopenharmony_ci sk_X509_pop_free(cpk->chain, X509_free); 226e1051a39Sopenharmony_ci cpk->chain = NULL; 227e1051a39Sopenharmony_ci OPENSSL_free(cpk->serverinfo); 228e1051a39Sopenharmony_ci cpk->serverinfo = NULL; 229e1051a39Sopenharmony_ci cpk->serverinfo_length = 0; 230e1051a39Sopenharmony_ci } 231e1051a39Sopenharmony_ci} 232e1051a39Sopenharmony_ci 233e1051a39Sopenharmony_civoid ssl_cert_free(CERT *c) 234e1051a39Sopenharmony_ci{ 235e1051a39Sopenharmony_ci int i; 236e1051a39Sopenharmony_ci 237e1051a39Sopenharmony_ci if (c == NULL) 238e1051a39Sopenharmony_ci return; 239e1051a39Sopenharmony_ci CRYPTO_DOWN_REF(&c->references, &i, c->lock); 240e1051a39Sopenharmony_ci REF_PRINT_COUNT("CERT", c); 241e1051a39Sopenharmony_ci if (i > 0) 242e1051a39Sopenharmony_ci return; 243e1051a39Sopenharmony_ci REF_ASSERT_ISNT(i < 0); 244e1051a39Sopenharmony_ci 245e1051a39Sopenharmony_ci EVP_PKEY_free(c->dh_tmp); 246e1051a39Sopenharmony_ci 247e1051a39Sopenharmony_ci ssl_cert_clear_certs(c); 248e1051a39Sopenharmony_ci OPENSSL_free(c->conf_sigalgs); 249e1051a39Sopenharmony_ci OPENSSL_free(c->client_sigalgs); 250e1051a39Sopenharmony_ci OPENSSL_free(c->ctype); 251e1051a39Sopenharmony_ci X509_STORE_free(c->verify_store); 252e1051a39Sopenharmony_ci X509_STORE_free(c->chain_store); 253e1051a39Sopenharmony_ci custom_exts_free(&c->custext); 254e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_PSK 255e1051a39Sopenharmony_ci OPENSSL_free(c->psk_identity_hint); 256e1051a39Sopenharmony_ci#endif 257e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(c->lock); 258e1051a39Sopenharmony_ci OPENSSL_free(c); 259e1051a39Sopenharmony_ci} 260e1051a39Sopenharmony_ci 261e1051a39Sopenharmony_ciint ssl_cert_set0_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain) 262e1051a39Sopenharmony_ci{ 263e1051a39Sopenharmony_ci int i, r; 264e1051a39Sopenharmony_ci CERT_PKEY *cpk = s != NULL ? s->cert->key : ctx->cert->key; 265e1051a39Sopenharmony_ci 266e1051a39Sopenharmony_ci if (!cpk) 267e1051a39Sopenharmony_ci return 0; 268e1051a39Sopenharmony_ci for (i = 0; i < sk_X509_num(chain); i++) { 269e1051a39Sopenharmony_ci X509 *x = sk_X509_value(chain, i); 270e1051a39Sopenharmony_ci 271e1051a39Sopenharmony_ci r = ssl_security_cert(s, ctx, x, 0, 0); 272e1051a39Sopenharmony_ci if (r != 1) { 273e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, r); 274e1051a39Sopenharmony_ci return 0; 275e1051a39Sopenharmony_ci } 276e1051a39Sopenharmony_ci } 277e1051a39Sopenharmony_ci sk_X509_pop_free(cpk->chain, X509_free); 278e1051a39Sopenharmony_ci cpk->chain = chain; 279e1051a39Sopenharmony_ci return 1; 280e1051a39Sopenharmony_ci} 281e1051a39Sopenharmony_ci 282e1051a39Sopenharmony_ciint ssl_cert_set1_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain) 283e1051a39Sopenharmony_ci{ 284e1051a39Sopenharmony_ci STACK_OF(X509) *dchain; 285e1051a39Sopenharmony_ci if (!chain) 286e1051a39Sopenharmony_ci return ssl_cert_set0_chain(s, ctx, NULL); 287e1051a39Sopenharmony_ci dchain = X509_chain_up_ref(chain); 288e1051a39Sopenharmony_ci if (!dchain) 289e1051a39Sopenharmony_ci return 0; 290e1051a39Sopenharmony_ci if (!ssl_cert_set0_chain(s, ctx, dchain)) { 291e1051a39Sopenharmony_ci sk_X509_pop_free(dchain, X509_free); 292e1051a39Sopenharmony_ci return 0; 293e1051a39Sopenharmony_ci } 294e1051a39Sopenharmony_ci return 1; 295e1051a39Sopenharmony_ci} 296e1051a39Sopenharmony_ci 297e1051a39Sopenharmony_ciint ssl_cert_add0_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x) 298e1051a39Sopenharmony_ci{ 299e1051a39Sopenharmony_ci int r; 300e1051a39Sopenharmony_ci CERT_PKEY *cpk = s ? s->cert->key : ctx->cert->key; 301e1051a39Sopenharmony_ci if (!cpk) 302e1051a39Sopenharmony_ci return 0; 303e1051a39Sopenharmony_ci r = ssl_security_cert(s, ctx, x, 0, 0); 304e1051a39Sopenharmony_ci if (r != 1) { 305e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, r); 306e1051a39Sopenharmony_ci return 0; 307e1051a39Sopenharmony_ci } 308e1051a39Sopenharmony_ci if (!cpk->chain) 309e1051a39Sopenharmony_ci cpk->chain = sk_X509_new_null(); 310e1051a39Sopenharmony_ci if (!cpk->chain || !sk_X509_push(cpk->chain, x)) 311e1051a39Sopenharmony_ci return 0; 312e1051a39Sopenharmony_ci return 1; 313e1051a39Sopenharmony_ci} 314e1051a39Sopenharmony_ci 315e1051a39Sopenharmony_ciint ssl_cert_add1_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x) 316e1051a39Sopenharmony_ci{ 317e1051a39Sopenharmony_ci if (!ssl_cert_add0_chain_cert(s, ctx, x)) 318e1051a39Sopenharmony_ci return 0; 319e1051a39Sopenharmony_ci X509_up_ref(x); 320e1051a39Sopenharmony_ci return 1; 321e1051a39Sopenharmony_ci} 322e1051a39Sopenharmony_ci 323e1051a39Sopenharmony_ciint ssl_cert_select_current(CERT *c, X509 *x) 324e1051a39Sopenharmony_ci{ 325e1051a39Sopenharmony_ci int i; 326e1051a39Sopenharmony_ci if (x == NULL) 327e1051a39Sopenharmony_ci return 0; 328e1051a39Sopenharmony_ci for (i = 0; i < SSL_PKEY_NUM; i++) { 329e1051a39Sopenharmony_ci CERT_PKEY *cpk = c->pkeys + i; 330e1051a39Sopenharmony_ci if (cpk->x509 == x && cpk->privatekey) { 331e1051a39Sopenharmony_ci c->key = cpk; 332e1051a39Sopenharmony_ci return 1; 333e1051a39Sopenharmony_ci } 334e1051a39Sopenharmony_ci } 335e1051a39Sopenharmony_ci 336e1051a39Sopenharmony_ci for (i = 0; i < SSL_PKEY_NUM; i++) { 337e1051a39Sopenharmony_ci CERT_PKEY *cpk = c->pkeys + i; 338e1051a39Sopenharmony_ci if (cpk->privatekey && cpk->x509 && !X509_cmp(cpk->x509, x)) { 339e1051a39Sopenharmony_ci c->key = cpk; 340e1051a39Sopenharmony_ci return 1; 341e1051a39Sopenharmony_ci } 342e1051a39Sopenharmony_ci } 343e1051a39Sopenharmony_ci return 0; 344e1051a39Sopenharmony_ci} 345e1051a39Sopenharmony_ci 346e1051a39Sopenharmony_ciint ssl_cert_set_current(CERT *c, long op) 347e1051a39Sopenharmony_ci{ 348e1051a39Sopenharmony_ci int i, idx; 349e1051a39Sopenharmony_ci if (!c) 350e1051a39Sopenharmony_ci return 0; 351e1051a39Sopenharmony_ci if (op == SSL_CERT_SET_FIRST) 352e1051a39Sopenharmony_ci idx = 0; 353e1051a39Sopenharmony_ci else if (op == SSL_CERT_SET_NEXT) { 354e1051a39Sopenharmony_ci idx = (int)(c->key - c->pkeys + 1); 355e1051a39Sopenharmony_ci if (idx >= SSL_PKEY_NUM) 356e1051a39Sopenharmony_ci return 0; 357e1051a39Sopenharmony_ci } else 358e1051a39Sopenharmony_ci return 0; 359e1051a39Sopenharmony_ci for (i = idx; i < SSL_PKEY_NUM; i++) { 360e1051a39Sopenharmony_ci CERT_PKEY *cpk = c->pkeys + i; 361e1051a39Sopenharmony_ci if (cpk->x509 && cpk->privatekey) { 362e1051a39Sopenharmony_ci c->key = cpk; 363e1051a39Sopenharmony_ci return 1; 364e1051a39Sopenharmony_ci } 365e1051a39Sopenharmony_ci } 366e1051a39Sopenharmony_ci return 0; 367e1051a39Sopenharmony_ci} 368e1051a39Sopenharmony_ci 369e1051a39Sopenharmony_civoid ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg) 370e1051a39Sopenharmony_ci{ 371e1051a39Sopenharmony_ci c->cert_cb = cb; 372e1051a39Sopenharmony_ci c->cert_cb_arg = arg; 373e1051a39Sopenharmony_ci} 374e1051a39Sopenharmony_ci 375e1051a39Sopenharmony_ci/* 376e1051a39Sopenharmony_ci * Verify a certificate chain 377e1051a39Sopenharmony_ci * Return codes: 378e1051a39Sopenharmony_ci * 1: Verify success 379e1051a39Sopenharmony_ci * 0: Verify failure or error 380e1051a39Sopenharmony_ci * -1: Retry required 381e1051a39Sopenharmony_ci */ 382e1051a39Sopenharmony_ciint ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) 383e1051a39Sopenharmony_ci{ 384e1051a39Sopenharmony_ci X509 *x; 385e1051a39Sopenharmony_ci int i = 0; 386e1051a39Sopenharmony_ci X509_STORE *verify_store; 387e1051a39Sopenharmony_ci X509_STORE_CTX *ctx = NULL; 388e1051a39Sopenharmony_ci X509_VERIFY_PARAM *param; 389e1051a39Sopenharmony_ci 390e1051a39Sopenharmony_ci if ((sk == NULL) || (sk_X509_num(sk) == 0)) 391e1051a39Sopenharmony_ci return 0; 392e1051a39Sopenharmony_ci 393e1051a39Sopenharmony_ci if (s->cert->verify_store) 394e1051a39Sopenharmony_ci verify_store = s->cert->verify_store; 395e1051a39Sopenharmony_ci else 396e1051a39Sopenharmony_ci verify_store = s->ctx->cert_store; 397e1051a39Sopenharmony_ci 398e1051a39Sopenharmony_ci ctx = X509_STORE_CTX_new_ex(s->ctx->libctx, s->ctx->propq); 399e1051a39Sopenharmony_ci if (ctx == NULL) { 400e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 401e1051a39Sopenharmony_ci return 0; 402e1051a39Sopenharmony_ci } 403e1051a39Sopenharmony_ci 404e1051a39Sopenharmony_ci x = sk_X509_value(sk, 0); 405e1051a39Sopenharmony_ci if (!X509_STORE_CTX_init(ctx, verify_store, x, sk)) { 406e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); 407e1051a39Sopenharmony_ci goto end; 408e1051a39Sopenharmony_ci } 409e1051a39Sopenharmony_ci param = X509_STORE_CTX_get0_param(ctx); 410e1051a39Sopenharmony_ci /* 411e1051a39Sopenharmony_ci * XXX: Separate @AUTHSECLEVEL and @TLSSECLEVEL would be useful at some 412e1051a39Sopenharmony_ci * point, for now a single @SECLEVEL sets the same policy for TLS crypto 413e1051a39Sopenharmony_ci * and PKI authentication. 414e1051a39Sopenharmony_ci */ 415e1051a39Sopenharmony_ci X509_VERIFY_PARAM_set_auth_level(param, SSL_get_security_level(s)); 416e1051a39Sopenharmony_ci 417e1051a39Sopenharmony_ci /* Set suite B flags if needed */ 418e1051a39Sopenharmony_ci X509_STORE_CTX_set_flags(ctx, tls1_suiteb(s)); 419e1051a39Sopenharmony_ci if (!X509_STORE_CTX_set_ex_data 420e1051a39Sopenharmony_ci (ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s)) { 421e1051a39Sopenharmony_ci goto end; 422e1051a39Sopenharmony_ci } 423e1051a39Sopenharmony_ci 424e1051a39Sopenharmony_ci /* Verify via DANE if enabled */ 425e1051a39Sopenharmony_ci if (DANETLS_ENABLED(&s->dane)) 426e1051a39Sopenharmony_ci X509_STORE_CTX_set0_dane(ctx, &s->dane); 427e1051a39Sopenharmony_ci 428e1051a39Sopenharmony_ci /* 429e1051a39Sopenharmony_ci * We need to inherit the verify parameters. These can be determined by 430e1051a39Sopenharmony_ci * the context: if its a server it will verify SSL client certificates or 431e1051a39Sopenharmony_ci * vice versa. 432e1051a39Sopenharmony_ci */ 433e1051a39Sopenharmony_ci 434e1051a39Sopenharmony_ci X509_STORE_CTX_set_default(ctx, s->server ? "ssl_client" : "ssl_server"); 435e1051a39Sopenharmony_ci /* 436e1051a39Sopenharmony_ci * Anything non-default in "s->param" should overwrite anything in the ctx. 437e1051a39Sopenharmony_ci */ 438e1051a39Sopenharmony_ci X509_VERIFY_PARAM_set1(param, s->param); 439e1051a39Sopenharmony_ci 440e1051a39Sopenharmony_ci if (s->verify_callback) 441e1051a39Sopenharmony_ci X509_STORE_CTX_set_verify_cb(ctx, s->verify_callback); 442e1051a39Sopenharmony_ci 443e1051a39Sopenharmony_ci if (s->ctx->app_verify_callback != NULL) { 444e1051a39Sopenharmony_ci i = s->ctx->app_verify_callback(ctx, s->ctx->app_verify_arg); 445e1051a39Sopenharmony_ci } else { 446e1051a39Sopenharmony_ci i = X509_verify_cert(ctx); 447e1051a39Sopenharmony_ci /* We treat an error in the same way as a failure to verify */ 448e1051a39Sopenharmony_ci if (i < 0) 449e1051a39Sopenharmony_ci i = 0; 450e1051a39Sopenharmony_ci } 451e1051a39Sopenharmony_ci 452e1051a39Sopenharmony_ci s->verify_result = X509_STORE_CTX_get_error(ctx); 453e1051a39Sopenharmony_ci sk_X509_pop_free(s->verified_chain, X509_free); 454e1051a39Sopenharmony_ci s->verified_chain = NULL; 455e1051a39Sopenharmony_ci if (X509_STORE_CTX_get0_chain(ctx) != NULL) { 456e1051a39Sopenharmony_ci s->verified_chain = X509_STORE_CTX_get1_chain(ctx); 457e1051a39Sopenharmony_ci if (s->verified_chain == NULL) { 458e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 459e1051a39Sopenharmony_ci i = 0; 460e1051a39Sopenharmony_ci } 461e1051a39Sopenharmony_ci } 462e1051a39Sopenharmony_ci 463e1051a39Sopenharmony_ci /* Move peername from the store context params to the SSL handle's */ 464e1051a39Sopenharmony_ci X509_VERIFY_PARAM_move_peername(s->param, param); 465e1051a39Sopenharmony_ci 466e1051a39Sopenharmony_ci end: 467e1051a39Sopenharmony_ci X509_STORE_CTX_free(ctx); 468e1051a39Sopenharmony_ci return i; 469e1051a39Sopenharmony_ci} 470e1051a39Sopenharmony_ci 471e1051a39Sopenharmony_cistatic void set0_CA_list(STACK_OF(X509_NAME) **ca_list, 472e1051a39Sopenharmony_ci STACK_OF(X509_NAME) *name_list) 473e1051a39Sopenharmony_ci{ 474e1051a39Sopenharmony_ci sk_X509_NAME_pop_free(*ca_list, X509_NAME_free); 475e1051a39Sopenharmony_ci *ca_list = name_list; 476e1051a39Sopenharmony_ci} 477e1051a39Sopenharmony_ci 478e1051a39Sopenharmony_ciSTACK_OF(X509_NAME) *SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk) 479e1051a39Sopenharmony_ci{ 480e1051a39Sopenharmony_ci int i; 481e1051a39Sopenharmony_ci const int num = sk_X509_NAME_num(sk); 482e1051a39Sopenharmony_ci STACK_OF(X509_NAME) *ret; 483e1051a39Sopenharmony_ci X509_NAME *name; 484e1051a39Sopenharmony_ci 485e1051a39Sopenharmony_ci ret = sk_X509_NAME_new_reserve(NULL, num); 486e1051a39Sopenharmony_ci if (ret == NULL) { 487e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 488e1051a39Sopenharmony_ci return NULL; 489e1051a39Sopenharmony_ci } 490e1051a39Sopenharmony_ci for (i = 0; i < num; i++) { 491e1051a39Sopenharmony_ci name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); 492e1051a39Sopenharmony_ci if (name == NULL) { 493e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 494e1051a39Sopenharmony_ci sk_X509_NAME_pop_free(ret, X509_NAME_free); 495e1051a39Sopenharmony_ci return NULL; 496e1051a39Sopenharmony_ci } 497e1051a39Sopenharmony_ci sk_X509_NAME_push(ret, name); /* Cannot fail after reserve call */ 498e1051a39Sopenharmony_ci } 499e1051a39Sopenharmony_ci return ret; 500e1051a39Sopenharmony_ci} 501e1051a39Sopenharmony_ci 502e1051a39Sopenharmony_civoid SSL_set0_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) 503e1051a39Sopenharmony_ci{ 504e1051a39Sopenharmony_ci set0_CA_list(&s->ca_names, name_list); 505e1051a39Sopenharmony_ci} 506e1051a39Sopenharmony_ci 507e1051a39Sopenharmony_civoid SSL_CTX_set0_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) 508e1051a39Sopenharmony_ci{ 509e1051a39Sopenharmony_ci set0_CA_list(&ctx->ca_names, name_list); 510e1051a39Sopenharmony_ci} 511e1051a39Sopenharmony_ci 512e1051a39Sopenharmony_ciconst STACK_OF(X509_NAME) *SSL_CTX_get0_CA_list(const SSL_CTX *ctx) 513e1051a39Sopenharmony_ci{ 514e1051a39Sopenharmony_ci return ctx->ca_names; 515e1051a39Sopenharmony_ci} 516e1051a39Sopenharmony_ci 517e1051a39Sopenharmony_ciconst STACK_OF(X509_NAME) *SSL_get0_CA_list(const SSL *s) 518e1051a39Sopenharmony_ci{ 519e1051a39Sopenharmony_ci return s->ca_names != NULL ? s->ca_names : s->ctx->ca_names; 520e1051a39Sopenharmony_ci} 521e1051a39Sopenharmony_ci 522e1051a39Sopenharmony_civoid SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) 523e1051a39Sopenharmony_ci{ 524e1051a39Sopenharmony_ci set0_CA_list(&ctx->client_ca_names, name_list); 525e1051a39Sopenharmony_ci} 526e1051a39Sopenharmony_ci 527e1051a39Sopenharmony_ciSTACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) 528e1051a39Sopenharmony_ci{ 529e1051a39Sopenharmony_ci return ctx->client_ca_names; 530e1051a39Sopenharmony_ci} 531e1051a39Sopenharmony_ci 532e1051a39Sopenharmony_civoid SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) 533e1051a39Sopenharmony_ci{ 534e1051a39Sopenharmony_ci set0_CA_list(&s->client_ca_names, name_list); 535e1051a39Sopenharmony_ci} 536e1051a39Sopenharmony_ci 537e1051a39Sopenharmony_ciconst STACK_OF(X509_NAME) *SSL_get0_peer_CA_list(const SSL *s) 538e1051a39Sopenharmony_ci{ 539e1051a39Sopenharmony_ci return s->s3.tmp.peer_ca_names; 540e1051a39Sopenharmony_ci} 541e1051a39Sopenharmony_ci 542e1051a39Sopenharmony_ciSTACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) 543e1051a39Sopenharmony_ci{ 544e1051a39Sopenharmony_ci if (!s->server) 545e1051a39Sopenharmony_ci return s->s3.tmp.peer_ca_names; 546e1051a39Sopenharmony_ci return s->client_ca_names != NULL ? s->client_ca_names 547e1051a39Sopenharmony_ci : s->ctx->client_ca_names; 548e1051a39Sopenharmony_ci} 549e1051a39Sopenharmony_ci 550e1051a39Sopenharmony_cistatic int add_ca_name(STACK_OF(X509_NAME) **sk, const X509 *x) 551e1051a39Sopenharmony_ci{ 552e1051a39Sopenharmony_ci X509_NAME *name; 553e1051a39Sopenharmony_ci 554e1051a39Sopenharmony_ci if (x == NULL) 555e1051a39Sopenharmony_ci return 0; 556e1051a39Sopenharmony_ci if (*sk == NULL && ((*sk = sk_X509_NAME_new_null()) == NULL)) 557e1051a39Sopenharmony_ci return 0; 558e1051a39Sopenharmony_ci 559e1051a39Sopenharmony_ci if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL) 560e1051a39Sopenharmony_ci return 0; 561e1051a39Sopenharmony_ci 562e1051a39Sopenharmony_ci if (!sk_X509_NAME_push(*sk, name)) { 563e1051a39Sopenharmony_ci X509_NAME_free(name); 564e1051a39Sopenharmony_ci return 0; 565e1051a39Sopenharmony_ci } 566e1051a39Sopenharmony_ci return 1; 567e1051a39Sopenharmony_ci} 568e1051a39Sopenharmony_ci 569e1051a39Sopenharmony_ciint SSL_add1_to_CA_list(SSL *ssl, const X509 *x) 570e1051a39Sopenharmony_ci{ 571e1051a39Sopenharmony_ci return add_ca_name(&ssl->ca_names, x); 572e1051a39Sopenharmony_ci} 573e1051a39Sopenharmony_ci 574e1051a39Sopenharmony_ciint SSL_CTX_add1_to_CA_list(SSL_CTX *ctx, const X509 *x) 575e1051a39Sopenharmony_ci{ 576e1051a39Sopenharmony_ci return add_ca_name(&ctx->ca_names, x); 577e1051a39Sopenharmony_ci} 578e1051a39Sopenharmony_ci 579e1051a39Sopenharmony_ci/* 580e1051a39Sopenharmony_ci * The following two are older names are to be replaced with 581e1051a39Sopenharmony_ci * SSL(_CTX)_add1_to_CA_list 582e1051a39Sopenharmony_ci */ 583e1051a39Sopenharmony_ciint SSL_add_client_CA(SSL *ssl, X509 *x) 584e1051a39Sopenharmony_ci{ 585e1051a39Sopenharmony_ci return add_ca_name(&ssl->client_ca_names, x); 586e1051a39Sopenharmony_ci} 587e1051a39Sopenharmony_ci 588e1051a39Sopenharmony_ciint SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) 589e1051a39Sopenharmony_ci{ 590e1051a39Sopenharmony_ci return add_ca_name(&ctx->client_ca_names, x); 591e1051a39Sopenharmony_ci} 592e1051a39Sopenharmony_ci 593e1051a39Sopenharmony_cistatic int xname_cmp(const X509_NAME *a, const X509_NAME *b) 594e1051a39Sopenharmony_ci{ 595e1051a39Sopenharmony_ci unsigned char *abuf = NULL, *bbuf = NULL; 596e1051a39Sopenharmony_ci int alen, blen, ret; 597e1051a39Sopenharmony_ci 598e1051a39Sopenharmony_ci /* X509_NAME_cmp() itself casts away constness in this way, so 599e1051a39Sopenharmony_ci * assume it's safe: 600e1051a39Sopenharmony_ci */ 601e1051a39Sopenharmony_ci alen = i2d_X509_NAME((X509_NAME *)a, &abuf); 602e1051a39Sopenharmony_ci blen = i2d_X509_NAME((X509_NAME *)b, &bbuf); 603e1051a39Sopenharmony_ci 604e1051a39Sopenharmony_ci if (alen < 0 || blen < 0) 605e1051a39Sopenharmony_ci ret = -2; 606e1051a39Sopenharmony_ci else if (alen != blen) 607e1051a39Sopenharmony_ci ret = alen - blen; 608e1051a39Sopenharmony_ci else /* alen == blen */ 609e1051a39Sopenharmony_ci ret = memcmp(abuf, bbuf, alen); 610e1051a39Sopenharmony_ci 611e1051a39Sopenharmony_ci OPENSSL_free(abuf); 612e1051a39Sopenharmony_ci OPENSSL_free(bbuf); 613e1051a39Sopenharmony_ci 614e1051a39Sopenharmony_ci return ret; 615e1051a39Sopenharmony_ci} 616e1051a39Sopenharmony_ci 617e1051a39Sopenharmony_cistatic int xname_sk_cmp(const X509_NAME *const *a, const X509_NAME *const *b) 618e1051a39Sopenharmony_ci{ 619e1051a39Sopenharmony_ci return xname_cmp(*a, *b); 620e1051a39Sopenharmony_ci} 621e1051a39Sopenharmony_ci 622e1051a39Sopenharmony_cistatic unsigned long xname_hash(const X509_NAME *a) 623e1051a39Sopenharmony_ci{ 624e1051a39Sopenharmony_ci /* This returns 0 also if SHA1 is not available */ 625e1051a39Sopenharmony_ci return X509_NAME_hash_ex((X509_NAME *)a, NULL, NULL, NULL); 626e1051a39Sopenharmony_ci} 627e1051a39Sopenharmony_ci 628e1051a39Sopenharmony_ciSTACK_OF(X509_NAME) *SSL_load_client_CA_file_ex(const char *file, 629e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx, 630e1051a39Sopenharmony_ci const char *propq) 631e1051a39Sopenharmony_ci{ 632e1051a39Sopenharmony_ci BIO *in = BIO_new(BIO_s_file()); 633e1051a39Sopenharmony_ci X509 *x = NULL; 634e1051a39Sopenharmony_ci X509_NAME *xn = NULL; 635e1051a39Sopenharmony_ci STACK_OF(X509_NAME) *ret = NULL; 636e1051a39Sopenharmony_ci LHASH_OF(X509_NAME) *name_hash = lh_X509_NAME_new(xname_hash, xname_cmp); 637e1051a39Sopenharmony_ci OSSL_LIB_CTX *prev_libctx = NULL; 638e1051a39Sopenharmony_ci 639e1051a39Sopenharmony_ci if ((name_hash == NULL) || (in == NULL)) { 640e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 641e1051a39Sopenharmony_ci goto err; 642e1051a39Sopenharmony_ci } 643e1051a39Sopenharmony_ci 644e1051a39Sopenharmony_ci x = X509_new_ex(libctx, propq); 645e1051a39Sopenharmony_ci if (x == NULL) { 646e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 647e1051a39Sopenharmony_ci goto err; 648e1051a39Sopenharmony_ci } 649e1051a39Sopenharmony_ci if (BIO_read_filename(in, file) <= 0) 650e1051a39Sopenharmony_ci goto err; 651e1051a39Sopenharmony_ci 652e1051a39Sopenharmony_ci /* Internally lh_X509_NAME_retrieve() needs the libctx to retrieve SHA1 */ 653e1051a39Sopenharmony_ci prev_libctx = OSSL_LIB_CTX_set0_default(libctx); 654e1051a39Sopenharmony_ci for (;;) { 655e1051a39Sopenharmony_ci if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) 656e1051a39Sopenharmony_ci break; 657e1051a39Sopenharmony_ci if (ret == NULL) { 658e1051a39Sopenharmony_ci ret = sk_X509_NAME_new_null(); 659e1051a39Sopenharmony_ci if (ret == NULL) { 660e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 661e1051a39Sopenharmony_ci goto err; 662e1051a39Sopenharmony_ci } 663e1051a39Sopenharmony_ci } 664e1051a39Sopenharmony_ci if ((xn = X509_get_subject_name(x)) == NULL) 665e1051a39Sopenharmony_ci goto err; 666e1051a39Sopenharmony_ci /* check for duplicates */ 667e1051a39Sopenharmony_ci xn = X509_NAME_dup(xn); 668e1051a39Sopenharmony_ci if (xn == NULL) 669e1051a39Sopenharmony_ci goto err; 670e1051a39Sopenharmony_ci if (lh_X509_NAME_retrieve(name_hash, xn) != NULL) { 671e1051a39Sopenharmony_ci /* Duplicate. */ 672e1051a39Sopenharmony_ci X509_NAME_free(xn); 673e1051a39Sopenharmony_ci xn = NULL; 674e1051a39Sopenharmony_ci } else { 675e1051a39Sopenharmony_ci lh_X509_NAME_insert(name_hash, xn); 676e1051a39Sopenharmony_ci if (!sk_X509_NAME_push(ret, xn)) 677e1051a39Sopenharmony_ci goto err; 678e1051a39Sopenharmony_ci } 679e1051a39Sopenharmony_ci } 680e1051a39Sopenharmony_ci goto done; 681e1051a39Sopenharmony_ci 682e1051a39Sopenharmony_ci err: 683e1051a39Sopenharmony_ci X509_NAME_free(xn); 684e1051a39Sopenharmony_ci sk_X509_NAME_pop_free(ret, X509_NAME_free); 685e1051a39Sopenharmony_ci ret = NULL; 686e1051a39Sopenharmony_ci done: 687e1051a39Sopenharmony_ci /* restore the old libctx */ 688e1051a39Sopenharmony_ci OSSL_LIB_CTX_set0_default(prev_libctx); 689e1051a39Sopenharmony_ci BIO_free(in); 690e1051a39Sopenharmony_ci X509_free(x); 691e1051a39Sopenharmony_ci lh_X509_NAME_free(name_hash); 692e1051a39Sopenharmony_ci if (ret != NULL) 693e1051a39Sopenharmony_ci ERR_clear_error(); 694e1051a39Sopenharmony_ci return ret; 695e1051a39Sopenharmony_ci} 696e1051a39Sopenharmony_ci 697e1051a39Sopenharmony_ciSTACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) 698e1051a39Sopenharmony_ci{ 699e1051a39Sopenharmony_ci return SSL_load_client_CA_file_ex(file, NULL, NULL); 700e1051a39Sopenharmony_ci} 701e1051a39Sopenharmony_ci 702e1051a39Sopenharmony_ciint SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, 703e1051a39Sopenharmony_ci const char *file) 704e1051a39Sopenharmony_ci{ 705e1051a39Sopenharmony_ci BIO *in; 706e1051a39Sopenharmony_ci X509 *x = NULL; 707e1051a39Sopenharmony_ci X509_NAME *xn = NULL; 708e1051a39Sopenharmony_ci int ret = 1; 709e1051a39Sopenharmony_ci int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b); 710e1051a39Sopenharmony_ci 711e1051a39Sopenharmony_ci oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_sk_cmp); 712e1051a39Sopenharmony_ci 713e1051a39Sopenharmony_ci in = BIO_new(BIO_s_file()); 714e1051a39Sopenharmony_ci 715e1051a39Sopenharmony_ci if (in == NULL) { 716e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 717e1051a39Sopenharmony_ci goto err; 718e1051a39Sopenharmony_ci } 719e1051a39Sopenharmony_ci 720e1051a39Sopenharmony_ci if (BIO_read_filename(in, file) <= 0) 721e1051a39Sopenharmony_ci goto err; 722e1051a39Sopenharmony_ci 723e1051a39Sopenharmony_ci for (;;) { 724e1051a39Sopenharmony_ci if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) 725e1051a39Sopenharmony_ci break; 726e1051a39Sopenharmony_ci if ((xn = X509_get_subject_name(x)) == NULL) 727e1051a39Sopenharmony_ci goto err; 728e1051a39Sopenharmony_ci xn = X509_NAME_dup(xn); 729e1051a39Sopenharmony_ci if (xn == NULL) 730e1051a39Sopenharmony_ci goto err; 731e1051a39Sopenharmony_ci if (sk_X509_NAME_find(stack, xn) >= 0) { 732e1051a39Sopenharmony_ci /* Duplicate. */ 733e1051a39Sopenharmony_ci X509_NAME_free(xn); 734e1051a39Sopenharmony_ci } else if (!sk_X509_NAME_push(stack, xn)) { 735e1051a39Sopenharmony_ci X509_NAME_free(xn); 736e1051a39Sopenharmony_ci goto err; 737e1051a39Sopenharmony_ci } 738e1051a39Sopenharmony_ci } 739e1051a39Sopenharmony_ci 740e1051a39Sopenharmony_ci ERR_clear_error(); 741e1051a39Sopenharmony_ci goto done; 742e1051a39Sopenharmony_ci 743e1051a39Sopenharmony_ci err: 744e1051a39Sopenharmony_ci ret = 0; 745e1051a39Sopenharmony_ci done: 746e1051a39Sopenharmony_ci BIO_free(in); 747e1051a39Sopenharmony_ci X509_free(x); 748e1051a39Sopenharmony_ci (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); 749e1051a39Sopenharmony_ci return ret; 750e1051a39Sopenharmony_ci} 751e1051a39Sopenharmony_ci 752e1051a39Sopenharmony_ciint SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, 753e1051a39Sopenharmony_ci const char *dir) 754e1051a39Sopenharmony_ci{ 755e1051a39Sopenharmony_ci OPENSSL_DIR_CTX *d = NULL; 756e1051a39Sopenharmony_ci const char *filename; 757e1051a39Sopenharmony_ci int ret = 0; 758e1051a39Sopenharmony_ci 759e1051a39Sopenharmony_ci /* Note that a side effect is that the CAs will be sorted by name */ 760e1051a39Sopenharmony_ci 761e1051a39Sopenharmony_ci while ((filename = OPENSSL_DIR_read(&d, dir))) { 762e1051a39Sopenharmony_ci char buf[1024]; 763e1051a39Sopenharmony_ci int r; 764e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_POSIX_IO 765e1051a39Sopenharmony_ci struct stat st; 766e1051a39Sopenharmony_ci 767e1051a39Sopenharmony_ci#else 768e1051a39Sopenharmony_ci /* Cannot use stat so just skip current and parent directories */ 769e1051a39Sopenharmony_ci if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) 770e1051a39Sopenharmony_ci continue; 771e1051a39Sopenharmony_ci#endif 772e1051a39Sopenharmony_ci if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) { 773e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, SSL_R_PATH_TOO_LONG); 774e1051a39Sopenharmony_ci goto err; 775e1051a39Sopenharmony_ci } 776e1051a39Sopenharmony_ci#ifdef OPENSSL_SYS_VMS 777e1051a39Sopenharmony_ci r = BIO_snprintf(buf, sizeof(buf), "%s%s", dir, filename); 778e1051a39Sopenharmony_ci#else 779e1051a39Sopenharmony_ci r = BIO_snprintf(buf, sizeof(buf), "%s/%s", dir, filename); 780e1051a39Sopenharmony_ci#endif 781e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_POSIX_IO 782e1051a39Sopenharmony_ci /* Skip subdirectories */ 783e1051a39Sopenharmony_ci if (!stat(buf, &st) && S_ISDIR(st.st_mode)) 784e1051a39Sopenharmony_ci continue; 785e1051a39Sopenharmony_ci#endif 786e1051a39Sopenharmony_ci if (r <= 0 || r >= (int)sizeof(buf)) 787e1051a39Sopenharmony_ci goto err; 788e1051a39Sopenharmony_ci if (!SSL_add_file_cert_subjects_to_stack(stack, buf)) 789e1051a39Sopenharmony_ci goto err; 790e1051a39Sopenharmony_ci } 791e1051a39Sopenharmony_ci 792e1051a39Sopenharmony_ci if (errno) { 793e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), 794e1051a39Sopenharmony_ci "calling OPENSSL_dir_read(%s)", dir); 795e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB); 796e1051a39Sopenharmony_ci goto err; 797e1051a39Sopenharmony_ci } 798e1051a39Sopenharmony_ci 799e1051a39Sopenharmony_ci ret = 1; 800e1051a39Sopenharmony_ci 801e1051a39Sopenharmony_ci err: 802e1051a39Sopenharmony_ci if (d) 803e1051a39Sopenharmony_ci OPENSSL_DIR_end(&d); 804e1051a39Sopenharmony_ci 805e1051a39Sopenharmony_ci return ret; 806e1051a39Sopenharmony_ci} 807e1051a39Sopenharmony_ci 808e1051a39Sopenharmony_cistatic int add_uris_recursive(STACK_OF(X509_NAME) *stack, 809e1051a39Sopenharmony_ci const char *uri, int depth) 810e1051a39Sopenharmony_ci{ 811e1051a39Sopenharmony_ci int ok = 1; 812e1051a39Sopenharmony_ci OSSL_STORE_CTX *ctx = NULL; 813e1051a39Sopenharmony_ci X509 *x = NULL; 814e1051a39Sopenharmony_ci X509_NAME *xn = NULL; 815e1051a39Sopenharmony_ci 816e1051a39Sopenharmony_ci if ((ctx = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL)) == NULL) 817e1051a39Sopenharmony_ci goto err; 818e1051a39Sopenharmony_ci 819e1051a39Sopenharmony_ci while (!OSSL_STORE_eof(ctx) && !OSSL_STORE_error(ctx)) { 820e1051a39Sopenharmony_ci OSSL_STORE_INFO *info = OSSL_STORE_load(ctx); 821e1051a39Sopenharmony_ci int infotype = info == 0 ? 0 : OSSL_STORE_INFO_get_type(info); 822e1051a39Sopenharmony_ci 823e1051a39Sopenharmony_ci if (info == NULL) 824e1051a39Sopenharmony_ci continue; 825e1051a39Sopenharmony_ci 826e1051a39Sopenharmony_ci if (infotype == OSSL_STORE_INFO_NAME) { 827e1051a39Sopenharmony_ci /* 828e1051a39Sopenharmony_ci * This is an entry in the "directory" represented by the current 829e1051a39Sopenharmony_ci * uri. if |depth| allows, dive into it. 830e1051a39Sopenharmony_ci */ 831e1051a39Sopenharmony_ci if (depth > 0) 832e1051a39Sopenharmony_ci ok = add_uris_recursive(stack, OSSL_STORE_INFO_get0_NAME(info), 833e1051a39Sopenharmony_ci depth - 1); 834e1051a39Sopenharmony_ci } else if (infotype == OSSL_STORE_INFO_CERT) { 835e1051a39Sopenharmony_ci if ((x = OSSL_STORE_INFO_get0_CERT(info)) == NULL 836e1051a39Sopenharmony_ci || (xn = X509_get_subject_name(x)) == NULL 837e1051a39Sopenharmony_ci || (xn = X509_NAME_dup(xn)) == NULL) 838e1051a39Sopenharmony_ci goto err; 839e1051a39Sopenharmony_ci if (sk_X509_NAME_find(stack, xn) >= 0) { 840e1051a39Sopenharmony_ci /* Duplicate. */ 841e1051a39Sopenharmony_ci X509_NAME_free(xn); 842e1051a39Sopenharmony_ci } else if (!sk_X509_NAME_push(stack, xn)) { 843e1051a39Sopenharmony_ci X509_NAME_free(xn); 844e1051a39Sopenharmony_ci goto err; 845e1051a39Sopenharmony_ci } 846e1051a39Sopenharmony_ci } 847e1051a39Sopenharmony_ci 848e1051a39Sopenharmony_ci OSSL_STORE_INFO_free(info); 849e1051a39Sopenharmony_ci } 850e1051a39Sopenharmony_ci 851e1051a39Sopenharmony_ci ERR_clear_error(); 852e1051a39Sopenharmony_ci goto done; 853e1051a39Sopenharmony_ci 854e1051a39Sopenharmony_ci err: 855e1051a39Sopenharmony_ci ok = 0; 856e1051a39Sopenharmony_ci done: 857e1051a39Sopenharmony_ci OSSL_STORE_close(ctx); 858e1051a39Sopenharmony_ci 859e1051a39Sopenharmony_ci return ok; 860e1051a39Sopenharmony_ci} 861e1051a39Sopenharmony_ci 862e1051a39Sopenharmony_ciint SSL_add_store_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, 863e1051a39Sopenharmony_ci const char *store) 864e1051a39Sopenharmony_ci{ 865e1051a39Sopenharmony_ci int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b) 866e1051a39Sopenharmony_ci = sk_X509_NAME_set_cmp_func(stack, xname_sk_cmp); 867e1051a39Sopenharmony_ci int ret = add_uris_recursive(stack, store, 1); 868e1051a39Sopenharmony_ci 869e1051a39Sopenharmony_ci (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); 870e1051a39Sopenharmony_ci return ret; 871e1051a39Sopenharmony_ci} 872e1051a39Sopenharmony_ci 873e1051a39Sopenharmony_ci/* Build a certificate chain for current certificate */ 874e1051a39Sopenharmony_ciint ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) 875e1051a39Sopenharmony_ci{ 876e1051a39Sopenharmony_ci CERT *c = s ? s->cert : ctx->cert; 877e1051a39Sopenharmony_ci CERT_PKEY *cpk = c->key; 878e1051a39Sopenharmony_ci X509_STORE *chain_store = NULL; 879e1051a39Sopenharmony_ci X509_STORE_CTX *xs_ctx = NULL; 880e1051a39Sopenharmony_ci STACK_OF(X509) *chain = NULL, *untrusted = NULL; 881e1051a39Sopenharmony_ci X509 *x; 882e1051a39Sopenharmony_ci SSL_CTX *real_ctx = (s == NULL) ? ctx : s->ctx; 883e1051a39Sopenharmony_ci int i, rv = 0; 884e1051a39Sopenharmony_ci 885e1051a39Sopenharmony_ci if (!cpk->x509) { 886e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_SET); 887e1051a39Sopenharmony_ci goto err; 888e1051a39Sopenharmony_ci } 889e1051a39Sopenharmony_ci /* Rearranging and check the chain: add everything to a store */ 890e1051a39Sopenharmony_ci if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) { 891e1051a39Sopenharmony_ci chain_store = X509_STORE_new(); 892e1051a39Sopenharmony_ci if (chain_store == NULL) 893e1051a39Sopenharmony_ci goto err; 894e1051a39Sopenharmony_ci for (i = 0; i < sk_X509_num(cpk->chain); i++) { 895e1051a39Sopenharmony_ci x = sk_X509_value(cpk->chain, i); 896e1051a39Sopenharmony_ci if (!X509_STORE_add_cert(chain_store, x)) 897e1051a39Sopenharmony_ci goto err; 898e1051a39Sopenharmony_ci } 899e1051a39Sopenharmony_ci /* Add EE cert too: it might be self signed */ 900e1051a39Sopenharmony_ci if (!X509_STORE_add_cert(chain_store, cpk->x509)) 901e1051a39Sopenharmony_ci goto err; 902e1051a39Sopenharmony_ci } else { 903e1051a39Sopenharmony_ci if (c->chain_store) 904e1051a39Sopenharmony_ci chain_store = c->chain_store; 905e1051a39Sopenharmony_ci else if (s) 906e1051a39Sopenharmony_ci chain_store = s->ctx->cert_store; 907e1051a39Sopenharmony_ci else 908e1051a39Sopenharmony_ci chain_store = ctx->cert_store; 909e1051a39Sopenharmony_ci 910e1051a39Sopenharmony_ci if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED) 911e1051a39Sopenharmony_ci untrusted = cpk->chain; 912e1051a39Sopenharmony_ci } 913e1051a39Sopenharmony_ci 914e1051a39Sopenharmony_ci xs_ctx = X509_STORE_CTX_new_ex(real_ctx->libctx, real_ctx->propq); 915e1051a39Sopenharmony_ci if (xs_ctx == NULL) { 916e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 917e1051a39Sopenharmony_ci goto err; 918e1051a39Sopenharmony_ci } 919e1051a39Sopenharmony_ci if (!X509_STORE_CTX_init(xs_ctx, chain_store, cpk->x509, untrusted)) { 920e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); 921e1051a39Sopenharmony_ci goto err; 922e1051a39Sopenharmony_ci } 923e1051a39Sopenharmony_ci /* Set suite B flags if needed */ 924e1051a39Sopenharmony_ci X509_STORE_CTX_set_flags(xs_ctx, 925e1051a39Sopenharmony_ci c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS); 926e1051a39Sopenharmony_ci 927e1051a39Sopenharmony_ci i = X509_verify_cert(xs_ctx); 928e1051a39Sopenharmony_ci if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR) { 929e1051a39Sopenharmony_ci if (flags & SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR) 930e1051a39Sopenharmony_ci ERR_clear_error(); 931e1051a39Sopenharmony_ci i = 1; 932e1051a39Sopenharmony_ci rv = 2; 933e1051a39Sopenharmony_ci } 934e1051a39Sopenharmony_ci if (i > 0) 935e1051a39Sopenharmony_ci chain = X509_STORE_CTX_get1_chain(xs_ctx); 936e1051a39Sopenharmony_ci if (i <= 0) { 937e1051a39Sopenharmony_ci i = X509_STORE_CTX_get_error(xs_ctx); 938e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_SSL, SSL_R_CERTIFICATE_VERIFY_FAILED, 939e1051a39Sopenharmony_ci "Verify error:%s", X509_verify_cert_error_string(i)); 940e1051a39Sopenharmony_ci 941e1051a39Sopenharmony_ci goto err; 942e1051a39Sopenharmony_ci } 943e1051a39Sopenharmony_ci /* Remove EE certificate from chain */ 944e1051a39Sopenharmony_ci x = sk_X509_shift(chain); 945e1051a39Sopenharmony_ci X509_free(x); 946e1051a39Sopenharmony_ci if (flags & SSL_BUILD_CHAIN_FLAG_NO_ROOT) { 947e1051a39Sopenharmony_ci if (sk_X509_num(chain) > 0) { 948e1051a39Sopenharmony_ci /* See if last cert is self signed */ 949e1051a39Sopenharmony_ci x = sk_X509_value(chain, sk_X509_num(chain) - 1); 950e1051a39Sopenharmony_ci if (X509_get_extension_flags(x) & EXFLAG_SS) { 951e1051a39Sopenharmony_ci x = sk_X509_pop(chain); 952e1051a39Sopenharmony_ci X509_free(x); 953e1051a39Sopenharmony_ci } 954e1051a39Sopenharmony_ci } 955e1051a39Sopenharmony_ci } 956e1051a39Sopenharmony_ci /* 957e1051a39Sopenharmony_ci * Check security level of all CA certificates: EE will have been checked 958e1051a39Sopenharmony_ci * already. 959e1051a39Sopenharmony_ci */ 960e1051a39Sopenharmony_ci for (i = 0; i < sk_X509_num(chain); i++) { 961e1051a39Sopenharmony_ci x = sk_X509_value(chain, i); 962e1051a39Sopenharmony_ci rv = ssl_security_cert(s, ctx, x, 0, 0); 963e1051a39Sopenharmony_ci if (rv != 1) { 964e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, rv); 965e1051a39Sopenharmony_ci sk_X509_pop_free(chain, X509_free); 966e1051a39Sopenharmony_ci rv = 0; 967e1051a39Sopenharmony_ci goto err; 968e1051a39Sopenharmony_ci } 969e1051a39Sopenharmony_ci } 970e1051a39Sopenharmony_ci sk_X509_pop_free(cpk->chain, X509_free); 971e1051a39Sopenharmony_ci cpk->chain = chain; 972e1051a39Sopenharmony_ci if (rv == 0) 973e1051a39Sopenharmony_ci rv = 1; 974e1051a39Sopenharmony_ci err: 975e1051a39Sopenharmony_ci if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) 976e1051a39Sopenharmony_ci X509_STORE_free(chain_store); 977e1051a39Sopenharmony_ci X509_STORE_CTX_free(xs_ctx); 978e1051a39Sopenharmony_ci 979e1051a39Sopenharmony_ci return rv; 980e1051a39Sopenharmony_ci} 981e1051a39Sopenharmony_ci 982e1051a39Sopenharmony_ciint ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref) 983e1051a39Sopenharmony_ci{ 984e1051a39Sopenharmony_ci X509_STORE **pstore; 985e1051a39Sopenharmony_ci if (chain) 986e1051a39Sopenharmony_ci pstore = &c->chain_store; 987e1051a39Sopenharmony_ci else 988e1051a39Sopenharmony_ci pstore = &c->verify_store; 989e1051a39Sopenharmony_ci X509_STORE_free(*pstore); 990e1051a39Sopenharmony_ci *pstore = store; 991e1051a39Sopenharmony_ci if (ref && store) 992e1051a39Sopenharmony_ci X509_STORE_up_ref(store); 993e1051a39Sopenharmony_ci return 1; 994e1051a39Sopenharmony_ci} 995e1051a39Sopenharmony_ci 996e1051a39Sopenharmony_ciint ssl_cert_get_cert_store(CERT *c, X509_STORE **pstore, int chain) 997e1051a39Sopenharmony_ci{ 998e1051a39Sopenharmony_ci *pstore = (chain ? c->chain_store : c->verify_store); 999e1051a39Sopenharmony_ci return 1; 1000e1051a39Sopenharmony_ci} 1001e1051a39Sopenharmony_ci 1002e1051a39Sopenharmony_ciint ssl_get_security_level_bits(const SSL *s, const SSL_CTX *ctx, int *levelp) 1003e1051a39Sopenharmony_ci{ 1004e1051a39Sopenharmony_ci int level; 1005e1051a39Sopenharmony_ci /* 1006e1051a39Sopenharmony_ci * note that there's a corresponding minbits_table 1007e1051a39Sopenharmony_ci * in crypto/x509/x509_vfy.c that's used for checking the security level 1008e1051a39Sopenharmony_ci * of RSA and DSA keys 1009e1051a39Sopenharmony_ci */ 1010e1051a39Sopenharmony_ci static const int minbits_table[5 + 1] = { 0, 80, 112, 128, 192, 256 }; 1011e1051a39Sopenharmony_ci 1012e1051a39Sopenharmony_ci if (ctx != NULL) 1013e1051a39Sopenharmony_ci level = SSL_CTX_get_security_level(ctx); 1014e1051a39Sopenharmony_ci else 1015e1051a39Sopenharmony_ci level = SSL_get_security_level(s); 1016e1051a39Sopenharmony_ci 1017e1051a39Sopenharmony_ci if (level > 5) 1018e1051a39Sopenharmony_ci level = 5; 1019e1051a39Sopenharmony_ci else if (level < 0) 1020e1051a39Sopenharmony_ci level = 0; 1021e1051a39Sopenharmony_ci 1022e1051a39Sopenharmony_ci if (levelp != NULL) 1023e1051a39Sopenharmony_ci *levelp = level; 1024e1051a39Sopenharmony_ci 1025e1051a39Sopenharmony_ci return minbits_table[level]; 1026e1051a39Sopenharmony_ci} 1027e1051a39Sopenharmony_ci 1028e1051a39Sopenharmony_cistatic int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, 1029e1051a39Sopenharmony_ci int op, int bits, int nid, void *other, 1030e1051a39Sopenharmony_ci void *ex) 1031e1051a39Sopenharmony_ci{ 1032e1051a39Sopenharmony_ci int level, minbits, pfs_mask; 1033e1051a39Sopenharmony_ci 1034e1051a39Sopenharmony_ci minbits = ssl_get_security_level_bits(s, ctx, &level); 1035e1051a39Sopenharmony_ci 1036e1051a39Sopenharmony_ci if (level == 0) { 1037e1051a39Sopenharmony_ci /* 1038e1051a39Sopenharmony_ci * No EDH keys weaker than 1024-bits even at level 0, otherwise, 1039e1051a39Sopenharmony_ci * anything goes. 1040e1051a39Sopenharmony_ci */ 1041e1051a39Sopenharmony_ci if (op == SSL_SECOP_TMP_DH && bits < 80) 1042e1051a39Sopenharmony_ci return 0; 1043e1051a39Sopenharmony_ci return 1; 1044e1051a39Sopenharmony_ci } 1045e1051a39Sopenharmony_ci switch (op) { 1046e1051a39Sopenharmony_ci case SSL_SECOP_CIPHER_SUPPORTED: 1047e1051a39Sopenharmony_ci case SSL_SECOP_CIPHER_SHARED: 1048e1051a39Sopenharmony_ci case SSL_SECOP_CIPHER_CHECK: 1049e1051a39Sopenharmony_ci { 1050e1051a39Sopenharmony_ci const SSL_CIPHER *c = other; 1051e1051a39Sopenharmony_ci /* No ciphers below security level */ 1052e1051a39Sopenharmony_ci if (bits < minbits) 1053e1051a39Sopenharmony_ci return 0; 1054e1051a39Sopenharmony_ci /* No unauthenticated ciphersuites */ 1055e1051a39Sopenharmony_ci if (c->algorithm_auth & SSL_aNULL) 1056e1051a39Sopenharmony_ci return 0; 1057e1051a39Sopenharmony_ci /* No MD5 mac ciphersuites */ 1058e1051a39Sopenharmony_ci if (c->algorithm_mac & SSL_MD5) 1059e1051a39Sopenharmony_ci return 0; 1060e1051a39Sopenharmony_ci /* SHA1 HMAC is 160 bits of security */ 1061e1051a39Sopenharmony_ci if (minbits > 160 && c->algorithm_mac & SSL_SHA1) 1062e1051a39Sopenharmony_ci return 0; 1063e1051a39Sopenharmony_ci /* Level 2: no RC4 */ 1064e1051a39Sopenharmony_ci if (level >= 2 && c->algorithm_enc == SSL_RC4) 1065e1051a39Sopenharmony_ci return 0; 1066e1051a39Sopenharmony_ci /* Level 3: forward secure ciphersuites only */ 1067e1051a39Sopenharmony_ci pfs_mask = SSL_kDHE | SSL_kECDHE | SSL_kDHEPSK | SSL_kECDHEPSK; 1068e1051a39Sopenharmony_ci if (level >= 3 && c->min_tls != TLS1_3_VERSION && 1069e1051a39Sopenharmony_ci !(c->algorithm_mkey & pfs_mask)) 1070e1051a39Sopenharmony_ci return 0; 1071e1051a39Sopenharmony_ci break; 1072e1051a39Sopenharmony_ci } 1073e1051a39Sopenharmony_ci case SSL_SECOP_VERSION: 1074e1051a39Sopenharmony_ci if (!SSL_IS_DTLS(s)) { 1075e1051a39Sopenharmony_ci /* SSLv3 not allowed at level 2 */ 1076e1051a39Sopenharmony_ci if (nid <= SSL3_VERSION && level >= 2) 1077e1051a39Sopenharmony_ci return 0; 1078e1051a39Sopenharmony_ci /* TLS v1.1 and above only for level 3 */ 1079e1051a39Sopenharmony_ci if (nid <= TLS1_VERSION && level >= 3) 1080e1051a39Sopenharmony_ci return 0; 1081e1051a39Sopenharmony_ci /* TLS v1.2 only for level 4 and above */ 1082e1051a39Sopenharmony_ci if (nid <= TLS1_1_VERSION && level >= 4) 1083e1051a39Sopenharmony_ci return 0; 1084e1051a39Sopenharmony_ci } else { 1085e1051a39Sopenharmony_ci /* DTLS v1.2 only for level 4 and above */ 1086e1051a39Sopenharmony_ci if (DTLS_VERSION_LT(nid, DTLS1_2_VERSION) && level >= 4) 1087e1051a39Sopenharmony_ci return 0; 1088e1051a39Sopenharmony_ci } 1089e1051a39Sopenharmony_ci break; 1090e1051a39Sopenharmony_ci 1091e1051a39Sopenharmony_ci case SSL_SECOP_COMPRESSION: 1092e1051a39Sopenharmony_ci if (level >= 2) 1093e1051a39Sopenharmony_ci return 0; 1094e1051a39Sopenharmony_ci break; 1095e1051a39Sopenharmony_ci case SSL_SECOP_TICKET: 1096e1051a39Sopenharmony_ci if (level >= 3) 1097e1051a39Sopenharmony_ci return 0; 1098e1051a39Sopenharmony_ci break; 1099e1051a39Sopenharmony_ci default: 1100e1051a39Sopenharmony_ci if (bits < minbits) 1101e1051a39Sopenharmony_ci return 0; 1102e1051a39Sopenharmony_ci } 1103e1051a39Sopenharmony_ci return 1; 1104e1051a39Sopenharmony_ci} 1105e1051a39Sopenharmony_ci 1106e1051a39Sopenharmony_ciint ssl_security(const SSL *s, int op, int bits, int nid, void *other) 1107e1051a39Sopenharmony_ci{ 1108e1051a39Sopenharmony_ci return s->cert->sec_cb(s, NULL, op, bits, nid, other, s->cert->sec_ex); 1109e1051a39Sopenharmony_ci} 1110e1051a39Sopenharmony_ci 1111e1051a39Sopenharmony_ciint ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid, void *other) 1112e1051a39Sopenharmony_ci{ 1113e1051a39Sopenharmony_ci return ctx->cert->sec_cb(NULL, ctx, op, bits, nid, other, 1114e1051a39Sopenharmony_ci ctx->cert->sec_ex); 1115e1051a39Sopenharmony_ci} 1116e1051a39Sopenharmony_ci 1117e1051a39Sopenharmony_ciint ssl_cert_lookup_by_nid(int nid, size_t *pidx) 1118e1051a39Sopenharmony_ci{ 1119e1051a39Sopenharmony_ci size_t i; 1120e1051a39Sopenharmony_ci 1121e1051a39Sopenharmony_ci for (i = 0; i < OSSL_NELEM(ssl_cert_info); i++) { 1122e1051a39Sopenharmony_ci if (ssl_cert_info[i].nid == nid) { 1123e1051a39Sopenharmony_ci *pidx = i; 1124e1051a39Sopenharmony_ci return 1; 1125e1051a39Sopenharmony_ci } 1126e1051a39Sopenharmony_ci } 1127e1051a39Sopenharmony_ci 1128e1051a39Sopenharmony_ci return 0; 1129e1051a39Sopenharmony_ci} 1130e1051a39Sopenharmony_ci 1131e1051a39Sopenharmony_ciconst SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx) 1132e1051a39Sopenharmony_ci{ 1133e1051a39Sopenharmony_ci size_t i; 1134e1051a39Sopenharmony_ci 1135e1051a39Sopenharmony_ci for (i = 0; i < OSSL_NELEM(ssl_cert_info); i++) { 1136e1051a39Sopenharmony_ci const SSL_CERT_LOOKUP *tmp_lu = &ssl_cert_info[i]; 1137e1051a39Sopenharmony_ci 1138e1051a39Sopenharmony_ci if (EVP_PKEY_is_a(pk, OBJ_nid2sn(tmp_lu->nid)) 1139e1051a39Sopenharmony_ci || EVP_PKEY_is_a(pk, OBJ_nid2ln(tmp_lu->nid))) { 1140e1051a39Sopenharmony_ci if (pidx != NULL) 1141e1051a39Sopenharmony_ci *pidx = i; 1142e1051a39Sopenharmony_ci return tmp_lu; 1143e1051a39Sopenharmony_ci } 1144e1051a39Sopenharmony_ci } 1145e1051a39Sopenharmony_ci 1146e1051a39Sopenharmony_ci return NULL; 1147e1051a39Sopenharmony_ci} 1148e1051a39Sopenharmony_ci 1149e1051a39Sopenharmony_ciconst SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx) 1150e1051a39Sopenharmony_ci{ 1151e1051a39Sopenharmony_ci if (idx >= OSSL_NELEM(ssl_cert_info)) 1152e1051a39Sopenharmony_ci return NULL; 1153e1051a39Sopenharmony_ci return &ssl_cert_info[idx]; 1154e1051a39Sopenharmony_ci} 1155