15#ifndef OPENVPN_OPENSSL_SSL_SSLCTX_H
16#define OPENVPN_OPENSSL_SSL_SSLCTX_H
26#include <openssl/crypto.h>
27#include <openssl/ssl.h>
28#include <openssl/x509v3.h>
29#include <openssl/rsa.h>
30#include <openssl/dsa.h>
31#include <openssl/ec.h>
32#include <openssl/bn.h>
33#include <openssl/rand.h>
34#include <openssl/evp.h>
35#include <openssl/opensslv.h>
36#if OPENSSL_VERSION_NUMBER >= 0x30000000L
37#include <openssl/provider.h>
66#if ENABLE_EXTERNAL_PKI
67#if OPENSSL_VERSION_NUMBER >= 0x30000000L
94#if OPENSSL_VERSION_NUMBER < 0x30000000L
135#if OPENSSL_VERSION_NUMBER >= 0x30000000L
140 using TlsLibCtxType = std::remove_pointer<SSLLib::Ctx>::type;
142 using SSLProviderUPtr = std::unique_ptr<OSSL_PROVIDER,
decltype(&::OSSL_PROVIDER_unload)>;
162 LibContext(
unsigned short config)
168 if (
config & LIB_CTX_LEGACY_PROVIDER)
170 SSLProviderUPtr legacy_provider{OSSL_PROVIDER_load(ctx_.get(),
"legacy"), &::OSSL_PROVIDER_unload};
172 if (!legacy_provider)
175 SSLProviderUPtr default_provider{OSSL_PROVIDER_load(ctx_.get(),
"default"), &::OSSL_PROVIDER_unload};
177 if (!default_provider)
180 providers_.emplace_back(std::move(legacy_provider));
181 providers_.emplace_back(std::move(default_provider));
193 std::vector<SSLProviderUPtr> providers_;
281 void load_ca(
const std::string &ca_txt,
bool strict)
override
299 if (!extra_certs_txt.empty())
308 void load_dh(
const std::string &dh_txt)
override
330 std::vector<std::string>
ret;
417 if (!
override.empty())
423 if (!
override.empty())
486 && opt.
exists(
"client-cert-not-required"))
491 const std::string name = opt.
get_optional(
"sni", 1, 256);
498 std::string ca_txt = opt.
cat(
"ca");
500 ca_txt += opt.
cat(
"relay-extra-ca");
506 const std::string crl_txt = opt.
cat(
"crl-verify");
507 if (!crl_txt.empty())
517 const std::string ec_txt = opt.
cat(
"extra-certs");
537 std::string relay_prefix;
539 relay_prefix =
"relay-";
567 if (opt.
exists(
"tls-cipher"))
570 if (opt.
exists(
"tls-ciphersuites"))
573 if (opt.
exists(
"tls-groups"))
581#ifdef OPENVPN_JSON_INTERNAL
583 SSLConfigAPI::Ptr json_override(
const Json::Value &root,
const bool load_cert_key)
const override
585 static const char title[] =
"json_override";
598 const std::string &ca_txt = json::get_string_ref(root,
"ca", title);
599 ret->load_ca(ca_txt,
true);
605 if (!crl_txt.empty())
606 ret->load_crl(crl_txt);
612 bool loaded_cert =
false;
633 const std::string &key_txt = json::get_string_ref(root,
"key", title);
634 if (!key_txt.empty())
635 ret->load_private_key(key_txt);
683#if OPENSSL_VERSION_NUMBER >= 0x30000000L
685 return lib_ctx->ctx();
694#if OPENSSL_VERSION_NUMBER >= 0x30000000L
695 std::lock_guard guard{lib_ctx_mutex};
702 if (it != lib_ctx_map.end())
704 auto cached_ctx = it->second.lock();
708 lib_ctx = std::move(cached_ctx);
724#ifdef SSL_OP_NO_TLSv1_3
726#elif defined(SSL_OP_NO_TLSv1_2)
728#elif defined(SSL_OP_NO_TLSv1_1)
735#if OPENSSL_VERSION_NUMBER >= 0x30000000L
747 static inline std::map<unsigned short, std::weak_ptr<LibContext>> lib_ctx_map;
748 mutable std::shared_ptr<LibContext> lib_ctx;
749 static inline std::mutex lib_ctx_mutex;
768 std::vector<unsigned int>
ku;
795 SSL_do_handshake(
ssl);
800 const int status = BIO_write(
ssl_bio, data, numeric_cast<int>(size));
803 if (status == -1 && BIO_should_retry(
ssl_bio))
817 const int status = BIO_read(
ssl_bio, data, numeric_cast<int>(capacity));
820 if ((status == 0 || status == -1) && BIO_should_retry(
ssl_bio))
830 throw ssl_ciphertext_in_overflow();
851 in->
write(data, size);
873 return SSL_get_session(
ssl) && SSL_export_keying_material(
ssl, dest, size, label.c_str(), label.size(),
nullptr, 0, 0) == 1;
886 return !SSL_session_reused(
ssl);
911#if OPENSSL_VERSION_NUMBER < 0x30000010L && !defined(OPENSSL_NO_EC) && defined(ENABLE_EXTERNAL_PKI)
916 ssl_data_index = SSL_get_ex_new_index(0, (
char *)
"OpenSSLContext::SSL",
nullptr,
nullptr,
nullptr);
917 context_data_index = SSL_get_ex_new_index(0, (
char *)
"OpenSSLContext",
nullptr,
nullptr,
nullptr);
927 ssl = SSL_new(
ctx.ctx.get());
932 SSL_set_mode(
ssl, SSL_MODE_RELEASE_BUFFERS);
937 X509_VERIFY_PARAM *param = SSL_get0_param(
ssl);
938 X509_VERIFY_PARAM_set_hostflags(param, 0);
939 X509_VERIFY_PARAM_set1_host(param, hostname->c_str(), 0);
943 ssl_bio = BIO_new(BIO_f_ssl());
950 if (
ctx.config->mode.is_server())
952 SSL_set_accept_state(
ssl);
954 if (!
ctx.config->x509_track_config.empty())
957 else if (
ctx.config->mode.is_client())
959 if (cache_key &&
ctx.sess_cache)
962 ctx.sess_cache->extract(*cache_key, [
this](SSL_SESSION *sess)
964 if (!SSL_set_session(
ssl, sess))
970 SSL_set_connect_state(
ssl);
973 if (!
ctx.config->sni_name.empty())
975 if (SSL_set_tlsext_host_name(
ssl,
ctx.config->sni_name.c_str()) != 1)
976 throw OpenSSLException(
"OpenSSLContext::SSL: SSL_set_tlsext_host_name failed (sni_name)");
980 if (SSL_set_tlsext_host_name(
ssl, hostname->c_str()) != 1)
981 throw OpenSSLException(
"OpenSSLContext::SSL: SSL_set_tlsext_host_name failed (hostname)");
985 OPENVPN_THROW(ssl_context_error,
"OpenSSLContext::SSL: unknown client/server mode");
993 throw ssl_context_error(
"OpenSSLContext::SSL: ssl_data_index is uninitialized");
1007 throw ssl_context_error(
"OpenSSLContext::SSL: context_data_index is uninitialized");
1013 ::X509 *cert = SSL_get_peer_certificate(
ssl);
1042 std::array<char, 1024> gname{};
1043 size_t gname_sz = gname.size();
1045 const char *group = gname.data();
1048 group =
"Error getting group name";
1056 std::ostringstream
os;
1058 ::X509 *cert = SSL_get_peer_certificate(
ssl);
1063 if (cert !=
nullptr)
1065 EVP_PKEY *pkey = X509_get_pubkey(cert);
1066 if (pkey !=
nullptr)
1068#ifndef OPENSSL_NO_EC
1069 if ((EVP_PKEY_id(pkey) == EVP_PKEY_EC))
1074#if OPENSSL_VERSION_NUMBER < 0x30000000L
1075 int pkeyId = EVP_PKEY_id(pkey);
1076 const char *pkeySN = OBJ_nid2sn(pkeyId);
1078 pkeySN =
"(error getting public key type)";
1081 if (pkeyId == EVP_PKEY_RSA)
1083 else if (pkeyId == EVP_PKEY_DSA)
1086 const char *pkeySN = EVP_PKEY_get0_type_name(pkey);
1089 pkeySN =
"(error getting public key type)";
1093 os <<
", " << EVP_PKEY_bits(pkey) <<
" bit " << pkeySN;
1095 EVP_PKEY_free(pkey);
1100 const SSL_CIPHER *ciph = SSL_get_current_cipher(
ssl);
1103 char *desc = SSL_CIPHER_description(ciph,
nullptr, 0);
1106 os <<
", cipher: Error getting TLS cipher description from SSL_CIPHER_description";
1110 std::string cipher_str(desc);
1113 os <<
", cipher: " << cipher_str;
1118 if (SSL_session_reused(
ssl))
1121#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1122 const char *key_agreement = SSL_get0_group_name(
ssl);
1125 key_agreement =
"(error fetching key-agreeement)";
1127 os <<
", key-agreement: " << key_agreement;
1158 SSL_set_shutdown(
ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
1170 throw OpenSSLException(
"OpenSSLContext::SSL: BIO_new failed on bmq_stream");
1197 std::stringstream cipher_list_ss(cipherlist);
1198 std::string ciphersuite;
1200 std::stringstream result;
1203 while (std::getline(cipher_list_ss, ciphersuite,
':'))
1207 if (!result.str().empty())
1214 OVPN_LOG_INFO(
"OpenSSLContext: Deprecated cipher suite name '"
1222 result << ciphersuite;
1226 return result.str();
1233 if (!SSL_CTX_set_session_id_context(
ctx.get(), (
unsigned char *)sess_id_context.c_str(), numeric_cast<unsigned int>(sess_id_context.length())))
1234 throw OpenSSLException(
"OpenSSLContext: SSL_CTX_set_session_id_context failed");
1236#if OPENSSL_VERSION_NUMBER < 0x30000000L
1238 throw OpenSSLException(
"OpenSSLContext: SSL_CTX_set_tlsext_ticket_key_cb failed");
1242 throw OpenSSLException(
"OpenSSLContext: SSL_CTX_set_tlsext_ticket_evp_cb failed");
1254 throw OpenSSLException(
"OpenSSLContext: SSL_CTX_new_ex failed for server method");
1259#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1260 if (!SSL_CTX_set0_tmp_dh_pkey(
ctx.get(),
config->
dh.obj_release()))
1268 SSL_CTX_set_purpose(
ctx.get(), X509_PURPOSE_SSL_SERVER);
1280 throw OpenSSLException(
"OpenSSLContext: SSL_CTX_new_ex failed for client method");
1283 OPENVPN_THROW(ssl_context_error,
"OpenSSLContext: unknown config->mode");
1288 int vf = SSL_VERIFY_PEER;
1290 vf |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1291 SSL_CTX_set_verify(
ctx.get(),
1296 SSL_CTX_set_verify_depth(
ctx.get(), 16);
1300 long sslopt = SSL_OP_SINGLE_DH_USE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
1302#ifdef SSL_OP_NO_RENEGOTIATION
1303 sslopt |= SSL_OP_NO_RENEGOTIATION;
1308 SSL_CTX_set_session_cache_mode(
ctx.get(), SSL_SESS_CACHE_OFF);
1314 sslopt |= SSL_OP_NO_TICKET;
1321 if (SSL_CTX_add_client_CA(
ctx.get(), e.obj()) != 1)
1330 SSL_CTX_set_session_cache_mode(
ctx.get(), SSL_SESS_CACHE_CLIENT);
1335 SSL_CTX_set_session_cache_mode(
ctx.get(), SSL_SESS_CACHE_OFF);
1336 sslopt |= SSL_OP_NO_TICKET;
1339#if OPENSSL_VERSION_NUMBER >= 0x10100000L
1346 sslopt |= SSL_OP_NO_TLSv1;
1347#ifdef SSL_OP_NO_TLSv1_1
1349 sslopt |= SSL_OP_NO_TLSv1_1;
1351#ifdef SSL_OP_NO_TLSv1_2
1353 sslopt |= SSL_OP_NO_TLSv1_2;
1355#ifdef SSL_OP_NO_TLSv1_3
1357 sslopt |= SSL_OP_NO_TLSv1_3;
1360#if OPENSSL_VERSION_NUMBER >= 0x10100000L
1367 sslopt |= SSL_OP_NO_TLSv1;
1368#ifdef SSL_OP_NO_TLSv1_1
1370 sslopt |= SSL_OP_NO_TLSv1_1;
1372#ifdef SSL_OP_NO_TLSv1_2
1374 sslopt |= SSL_OP_NO_TLSv1_2;
1376#ifdef SSL_OP_NO_TLSv1_3
1378 sslopt |= SSL_OP_NO_TLSv1_3;
1381 SSL_CTX_set_options(
ctx.get(), sslopt);
1387#ifdef TLS1_3_VERSION
1391 OPENVPN_THROW(ssl_context_error,
"OpenSSLContext: SSL_CTX_set_ciphersuites_list failed");
1394 std::string tls_cipher_list =
1398 ":!EXP:!LOW:!MEDIUM"
1416 tls_cipher_list +=
":!SHA1";
1423 if (!SSL_CTX_set_cipher_list(
ctx.get(), tls_cipher_list.c_str()))
1424 OPENVPN_THROW(ssl_context_error,
"OpenSSLContext: SSL_CTX_set_cipher_list failed");
1425#if OPENSSL_VERSION_NUMBER >= 0x10002000L && OPENSSL_VERSION_NUMBER < 0x10100000L
1426 SSL_CTX_set_ecdh_auto(
ctx.get(), 1);
1429#if OPENSSL_VERSION_NUMBER >= 0x10100000L
1434 "OpenSSLContext: undefined tls-cert-profile");
1436#ifdef OPENVPN_ALLOW_INSECURE_CERTPROFILE
1437 case TLSCertProfile::INSECURE:
1438 SSL_CTX_set_security_level(
ctx.get(), 0);
1442 SSL_CTX_set_security_level(
ctx.get(), 1);
1445 SSL_CTX_set_security_level(
ctx.get(), 2);
1448 SSL_CTX_set_security_level(
ctx.get(), 3);
1452 "OpenSSLContext: unexpected tls-cert-profile value");
1460 "OpenSSLContext: tls-cert-profile not supported by this OpenSSL build. Use 'legacy' instead");
1468 OPENVPN_THROW(ssl_context_error,
"OpenSSLContext: cert not defined");
1475#ifdef ENABLE_EXTERNAL_PKI
1476#if OPENSSL_VERSION_NUMBER >= 0x30000010L
1480 auto certType = EVP_PKEY_id(X509_get0_pubkey(
config->
cert.
obj()));
1481 if (certType == EVP_PKEY_RSA)
1485#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(OPENSSL_NO_EC)
1486 else if (certType == EVP_PKEY_EC)
1493 throw OpenSSLException(
"OpenSSLContext: pkey is neither RSA nor EC. Unsupported with external pki");
1497 throw OpenSSLException(
"OpenSSLContext: External PKI is not enabled in this build. ");
1503 OPENVPN_THROW(ssl_context_error,
"OpenSSLContext: private key not defined");
1508 if (!SSL_CTX_check_private_key(
ctx.get()))
1509 throw OpenSSLException(
"OpenSSLContext: private key does not match the certificate");
1518 if (SSL_CTX_add_extra_chain_cert(
ctx.get(), e.obj_dup()) != 1)
1519 throw OpenSSLException(
"OpenSSLContext: SSL_CTX_add_extra_chain_cert failed");
1528 OPENVPN_THROW(ssl_context_error,
"OpenSSLContext: CA not defined");
1539 return SSL::Ptr(
new SSL(*
this,
nullptr,
nullptr));
1545 return SSL::Ptr(
new SSL(*
this, hostname, cache_key));
1551#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1553 throw OpenSSLException(
"OpenSSLContext: library context is not initialised");
1562 SSL_CTX_set_cert_store(
ctx.get(), store.
release());
1578 static void load_cert_info_into_authcert(
AuthCert &authcert,
const std::string &
cert_txt)
1585 X509_digest(cert.obj(), EVP_sha1(), authcert.
issuer_fp, &md_len);
1609 return X509_check_purpose(cert, X509_PURPOSE_SSL_SERVER, 0);
1611 return X509_check_purpose(cert, X509_PURPOSE_SSL_CLIENT, 0);
1618 auto num_groups = std::count(tls_groups.begin(), tls_groups.end(),
':') + 1;
1620 std::unique_ptr<int[]> glist(
new int[num_groups]);
1622 std::stringstream groups_ss(tls_groups);
1626 while (std::getline(groups_ss, group,
':'))
1631 if (group ==
"secp256r1")
1633 group =
"prime256v1";
1636 int nid = OBJ_sn2nid(group.c_str());
1639 glist[glistlen] = nid;
1645 << group <<
"' in tls-groups");
1649 if (!SSL_CTX_set1_groups(
ctx.get(), glist.get(), glistlen))
1650 OPENVPN_THROW(ssl_context_error,
"OpenSSLContext: SSL_CTX_set1_groups failed");
1663 ASN1_BIT_STRING *ku = (ASN1_BIT_STRING *)X509_get_ext_d2i(cert, NID_key_usage,
nullptr,
nullptr);
1668 unsigned int nku = 0;
1670 for (
int i = 0; i < 8; i++)
1672 if (ASN1_BIT_STRING_get_bit(ku, i))
1673 nku |= 1 << (7 - i);
1678 if ((nku & 0xff) == 0)
1683 for (std::vector<unsigned int>::const_iterator i =
config->
ku.begin(); i !=
config->
ku.end(); ++i)
1693 ASN1_BIT_STRING_free(ku);
1708 EXTENDED_KEY_USAGE *eku = (EXTENDED_KEY_USAGE *)X509_get_ext_d2i(cert, NID_ext_key_usage,
nullptr,
nullptr);
1713 for (
int i = 0; !found && i < sk_ASN1_OBJECT_num(eku); i++)
1715 ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(eku, i);
1718 if (!found && OBJ_obj2txt(oid_str,
sizeof(oid_str), oid, 0) != -1)
1725 if (!found && OBJ_obj2txt(oid_str,
sizeof(oid_str), oid, 1) != -1)
1733 sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
1756 if (c.depth_match(depth))
1763 if (!serial.empty())
1776 unsigned char buf[EVP_MAX_MD_SIZE];
1777 unsigned int len = EVP_MAX_MD_SIZE;
1778 X509_digest(cert, EVP_sha1(), buf, &len);
1814 const ASN1_INTEGER *ai = X509_get_serialNumber(cert);
1817 if (ai->type == V_ASN1_NEG_INTEGER)
1819 if (!is_safe_conversion<int>(authcert.
serial.
size()))
1821 BIGNUM *bn = ASN1_INTEGER_to_BN(ai, NULL);
1832 const std::string &signature,
1833 const std::string &subject)
1845 if (!subject.empty())
1848 ret +=
"NO_SUBJECT";
1849 ret +=
", signature: " + signature;
1853 ret += X509_verify_cert_error_string(err);
1862 switch (openssl_err)
1864 case X509_V_ERR_CERT_HAS_EXPIRED:
1874 int nid = X509_get_signature_nid(cert);
1878 case NID_ecdsa_with_SHA1:
1879 case NID_dsaWithSHA:
1880 case NID_dsaWithSHA1:
1881 case NID_sha1WithRSAEncryption:
1883 case NID_md5WithRSA:
1884 case NID_md5WithRSAEncryption:
1894 ::SSL *
ssl = (::SSL *)X509_STORE_CTX_get_ex_data(
ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1903 const int depth = X509_STORE_CTX_get_error_depth(
ctx);
1906 X509 *current_cert = X509_STORE_CTX_get_current_cert(
ctx);
1913 int err = X509_STORE_CTX_get_error(
ctx);
1915 || err != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
1931 return preverify_ok;
1943 OVPN_LOG_INFO(
"VERIFY FAIL -- bad peer-fingerprint in leaf certificate");
1950 OVPN_LOG_INFO(
"VERIFY FAIL -- bad ns-cert-type in leaf certificate");
1951 preverify_ok =
false;
1957 OVPN_LOG_INFO(
"VERIFY FAIL -- bad X509 key usage in leaf certificate");
1958 preverify_ok =
false;
1964 OVPN_LOG_INFO(
"VERIFY FAIL -- bad X509 extended key usage in leaf certificate");
1965 preverify_ok =
false;
1978 if (!verify_x509.
verify(name))
1981 preverify_ok =
false;
1994 preverify_ok =
false;
1998 return preverify_ok;
2004 ::SSL *
ssl = (::SSL *)X509_STORE_CTX_get_ex_data(
ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2013 const int err = X509_STORE_CTX_get_error(
ctx);
2016 const int depth = X509_STORE_CTX_get_error_depth(
ctx);
2019 X509 *current_cert = X509_STORE_CTX_get_current_cert(
ctx);
2025 int err = X509_STORE_CTX_get_error(
ctx);
2027 || err != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
2037 if (!preverify_ok && self_ssl->
authcert)
2040 X509_verify_cert_error_string(err));
2052 if (!X509_digest(current_cert, EVP_sha1(), self_ssl->
authcert->
issuer_fp, &digest_len))
2053 preverify_ok =
false;
2056 else if (depth == 0)
2062 OVPN_LOG_INFO(
"VERIFY FAIL -- bad peer-fingerprint in leaf certificate");
2066 "bad peer-fingerprint in leaf certificate");
2067 X509_STORE_CTX_set_error(
ctx, X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE);
2068 preverify_ok =
false;
2074 OVPN_LOG_INFO(
"VERIFY FAIL -- bad ns-cert-type in leaf certificate");
2078 "bad ns-cert-type in leaf certificate");
2079 X509_STORE_CTX_set_error(
ctx, X509_V_ERR_INVALID_PURPOSE);
2080 preverify_ok =
false;
2086 OVPN_LOG_INFO(
"VERIFY FAIL -- bad X509 key usage in leaf certificate");
2090 "bad X509 key usage in leaf certificate");
2091 X509_STORE_CTX_set_error(
ctx, X509_V_ERR_INVALID_PURPOSE);
2092 preverify_ok =
false;
2098 OVPN_LOG_INFO(
"VERIFY FAIL -- bad X509 extended key usage in leaf certificate");
2102 "bad X509 extended key usage in leaf certificate");
2103 X509_STORE_CTX_set_error(
ctx, X509_V_ERR_INVALID_PURPOSE);
2104 preverify_ok =
false;
2117 OVPN_LOG_INFO(
"VERIFY FAIL -- early rejection of leaf cert Common Name");
2118 X509_STORE_CTX_set_error(
ctx, X509_V_ERR_CERT_REJECTED);
2119 preverify_ok =
false;
2122 catch (
const std::exception &e)
2124 OVPN_LOG_INFO(
"VERIFY FAIL -- early rejection of leaf cert Common Name due to handler exception: " << e.what());
2125 X509_STORE_CTX_set_error(
ctx, X509_V_ERR_CERT_REJECTED);
2126 preverify_ok =
false;
2155 if (where & SSL_CB_LOOP)
2158 << ((where & SSL_ST_CONNECT)
2160 : (where & SSL_ST_ACCEPT
2163 <<
"): " << SSL_state_string_long(s));
2165 if (where & SSL_CB_ALERT)
2168 << (where & SSL_CB_READ ?
"read" :
"write") <<
"): "
2169 << SSL_alert_type_string_long(
ret) <<
": "
2170 << SSL_alert_desc_string_long(
ret));
2175 unsigned char key_name[16],
2176 unsigned char iv[EVP_MAX_IV_LENGTH],
2177 ::EVP_CIPHER_CTX *
ctx,
2203 if (!RAND_bytes(iv, EVP_MAX_IV_LENGTH))
2246 unsigned char iv[EVP_MAX_IV_LENGTH],
2247 ::EVP_CIPHER_CTX *
ctx,
2252 if (!EVP_CipherInit_ex(
ctx, EVP_aes_256_cbc(),
nullptr, key.
cipher_value_, iv, enc))
2254#if OPENSSL_VERSION_NUMBER >= 0x30000000L
2255 OSSL_PARAM params[]{
2258 OSSL_PARAM_construct_utf8_string(
"digest", (
char *)
"sha256", 0),
2259 OSSL_PARAM_construct_end()};
2284 std::string sni_name;
2298 if (!sni_name.empty())
2316 catch (
const std::exception &e)
2319 return sni_error(e.what(), SSL_AD_INTERNAL_ERROR, self, self_ssl, al);
2322 return sni_error(
"SNI name not found", SSL_AD_UNRECOGNIZED_NAME, self, self_ssl, al);
2327 throw Exception(
"sni_handler returned wrong kind of SSLFactoryAPI");
2330 if (fapi.
get() != self)
2332 SSL_set_SSL_CTX(s, self_ssl->
sni_ctx->
ctx.get());
2337 return SSL_CLIENT_HELLO_SUCCESS;
2339 catch (
const std::exception &e)
2341 OPENVPN_LOG(
"SNI exception in OpenSSLContext, SNI=" << sni_name <<
" : " << e.what());
2342 *al = SSL_AD_INTERNAL_ERROR;
2343 return SSL_CLIENT_HELLO_ERROR;
2348 const int ssl_ad_error,
2356 return SSL_CLIENT_HELLO_SUCCESS;
2358 return SSL_CLIENT_HELLO_ERROR;
2370 const unsigned char *p;
2372 if (!SSL_client_hello_get0_ext(s, TLSEXT_TYPE_server_name, &p, &remaining))
2373 return std::string();
2383 if (len != buf.
size())
2388 if (buf.
pop_front() != TLSEXT_NAMETYPE_host_name)
2389 throw Exception(
"expecting TLSEXT_NAMETYPE_host_name");
2394 if (len > buf.
size())
2398 return std::string((
const char *)buf.
c_data(), len);
2411 &&
ssl.authcert->is_fail();
2419 std::shared_ptr<ExternalPKIImpl>
epki =
nullptr;
2428 return OpenSSL_version(OPENSSL_VERSION);
const std::uint8_t * number() const
static constexpr size_t size()
SNI::Metadata::UPtr sni_metadata
std::uint8_t issuer_fp[20]
std::unique_ptr< X509Track::Set > x509_track
void add_fail(const size_t depth, const Fail::Type new_code, std::string reason)
std::string render_pem() const
void parse_pem(const std::string &content, const std::string &title)
static void from_string(const std::string &content, const std::string &title, OpenSSLPKI::X509List *cert_list, OpenSSLPKI::CRLList *crl_list=nullptr)
virtual bool reject(const std::string &cn)=0
const T * c_data() const
Returns a const pointer to the start of the buffer.
size_t size() const
Returns the size of the buffer in T objects.
T pop_front()
Removes and returns the first element from the buffer.
static void init_static()
void write_buf(const BufferPtr &bp)
void set_frame(const Frame::Ptr &frame)
void write(const unsigned char *data, size_t size)
std::string validate_cert_list(const std::string &certs_txt) const override
std::vector< unsigned int > ku
ExternalPKIBase * external_pki
std::string extract_ca() const override
void load(const OptionList &opt, const unsigned int lflags) override
void enable_legacy_algorithms(const bool v) override
OpenSSLPKI::X509List extra_certs
virtual void set_tls_cipher_list(const std::string &override)
void initialise_lib_context() const
For OpenSSL 3.x, set up a library context if one is not already set up.
void set_tls_remote(const std::string &tls_remote_arg) override
VerifyX509Name verify_x509_name
void set_tls_version_min_override(const std::string &override) override
std::string extract_crl() const override
void load_private_key(const std::string &key_txt) override
TLSSessionTicketBase * session_ticket_handler
void set_tls_version_min(const TLSVersion::Type tvm) override
const Mode & get_mode() const override
virtual void set_tls_groups(const std::string &groups)
void set_rng(const StrongRandomAPI::Ptr &rng_arg) override
X509Track::ConfigSet x509_track_config
TLSCertProfile::Type tls_cert_profile
void set_remote_cert_tls(const KUParse::TLSWebType wt) override
void set_tls_cert_profile_override(const std::string &override) override
std::string tls_ciphersuite_list
void set_x509_track(X509Track::ConfigSet x509_track_config_arg) override
NSCert::Type ns_cert_type
void load_cert(const std::string &cert_txt, const std::string &extra_certs_txt) override
bool client_session_tickets
static constexpr unsigned short LIB_CTX_NO_PROVIDERS
void set_frame(const Frame::Ptr &frame_arg) override
unsigned short lib_ctx_provider_config
SNI::HandlerBase * sni_handler
size_t private_key_length() const override
std::string extract_private_key() const override
std::string tls_cipher_list
void load_ca(const std::string &ca_txt, bool strict) override
PKType::Type private_key_type() const override
void set_tls_version_max(const TLSVersion::Type tvm) override
TLSVersion::Type tls_version_max
void set_flags(const unsigned int flags_arg) override
void set_session_ticket_handler(TLSSessionTicketBase *session_ticket_handler_arg) override
std::string external_pki_alias
TLSVersion::Type tls_version_min
void set_sni_handler(SNI::HandlerBase *sni_handler_arg) override
static TLSVersion::Type maxver()
std::string extract_dh() const override
void set_cn_reject_handler(CommonNameReject *cn_reject_handler_arg) override
void load_cert(const std::string &cert_txt) override
friend class OpenSSLContext
std::string extract_cert() const override
std::string validate_private_key(const std::string &key_txt) const override
std::string validate_cert(const std::string &cert_txt) const override
SSLFactoryAPI::Ptr new_factory() override
Return a pointer-like object that refers to a ssl factory.
void set_local_cert_enabled(const bool v) override
void set_client_session_tickets(const bool v) override
void set_sni_name(const std::string &sni_name_arg) override
std::string validate_dh(const std::string &dh_txt) const override
CommonNameReject * cn_reject_handler
void set_tls_cert_profile(const TLSCertProfile::Type type) override
void set_mode(const Mode &mode_arg) override
void load_dh(const std::string &dh_txt) override
PeerFingerprints peer_fingerprints
std::vector< std::string > extract_extra_certs() const override
void set_debug_level(const int debug_level) override
virtual void set_tls_ciphersuite_list(const std::string &override)
void load_crl(const std::string &crl_txt) override
void set_external_pki_callback(ExternalPKIBase *external_pki_arg, const std::string &alias) override
void set_ns_cert_type(const NSCert::Type ns_cert_type_arg) override
void set_private_key_password(const std::string &pwd) override
static constexpr unsigned short LIB_CTX_LEGACY_PROVIDER
std::string validate_crl(const std::string &crl_txt) const override
static void init_static()
const AuthCert::Ptr & auth_cert() const override
ssize_t write_cleartext_unbuffered(const void *data, const size_t size) override
static int context_data_index
static int ssl_data_index
bool export_keying_material(const std::string &label, unsigned char *dest, size_t size) override
void start_handshake() override
OpenSSLContext::Ptr sni_ctx
BufferPtr read_ciphertext() override
bool read_cleartext_ready() const override
static int ssl_pending_override(const ::SSL *)
void write_ciphertext(const BufferPtr &buf) override
static std::string ssl_handshake_details(::SSL *ssl)
bool did_full_handshake() override
Returns the cached/reused status of the session.
std::string ssl_handshake_details() const override
void set_parent(const OpenSSLContext *ctx)
bool read_ciphertext_ready() const override
OpenSSLSessionCache::Key::UPtr sess_cache_key
ssize_t read_cleartext(void *data, const size_t capacity) override
void rebuild_authcert() const
void write_ciphertext_unbuffered(const unsigned char *data, const size_t size) override
void mark_no_cache() override
static BIO * mem_bio(const Frame::Ptr &frame)
SSL(const OpenSSLContext &ctx, const std::string *hostname, const std::string *cache_key)
bool called_did_full_handshake
static void print_ec_key_details(EVP_PKEY *pkey, std::ostream &os)
static void info_callback(const ::SSL *s, int where, int ret)
static bool tls_ticket_init_cipher_hmac(const TLSSessionTicketBase::Key &key, unsigned char iv[EVP_MAX_IV_LENGTH], ::EVP_CIPHER_CTX *ctx, ssl_mac_ctx *mctx, const int enc)
static constexpr bool support_key_material_export()
static void load_serial_number_into_authcert(AuthCert &authcert, ::X509 *cert)
static int verify_callback_client(int preverify_ok, X509_STORE_CTX *ctx)
bool ns_cert_type_defined() const
std::shared_ptr< ExternalPKIImpl > epki
void setup_server_ticket_callback() const
static std::string client_hello_get_sni(::SSL *s)
static int check_cert_warnings(const X509 *cert)
static std::string cert_status_line(int preverify_ok, int depth, int err, const std::string &signature, const std::string &subject)
bool x509_cert_ku_defined() const
SSLAPI::Ptr ssl() override
static int client_hello_callback(::SSL *s, int *al, void *)
static void x509_track_extract_nid(const X509Track::Type xt_type, const int nid, ::X509 *cert, const int depth, X509Track::Set &xts)
const Mode & mode() const override
void set_openssl_tls_groups(const std::string &tls_groups)
~OpenSSLContext()=default
static int sni_error(std::string err, const int ssl_ad_error, OpenSSLContext *self, SSL *self_ssl, int *al)
OpenSSLSessionCache::Ptr sess_cache
static size_t sni_get_len(ConstBuffer &buf)
static std::string translate_cipher_list(const std::string &cipherlist)
static int tls_ticket_key_callback(::SSL *ssl, unsigned char key_name[16], unsigned char iv[EVP_MAX_IV_LENGTH], ::EVP_CIPHER_CTX *ctx, ssl_mac_ctx *hctx, int enc)
static void x509_track_extract_from_cert(::X509 *cert, const int depth, const X509Track::ConfigSet &cs, X509Track::Set &xts)
static AuthCert::Fail::Type cert_fail_code(const int openssl_err)
bool verify_x509_cert_eku(::X509 *cert) const
void update_trust(const CertCRLList &cc)
bool verify_x509_cert_ku(::X509 *cert) const
SSLAPI::Ptr ssl(const std::string *hostname, const std::string *cache_key) override
bool x509_cert_eku_defined() const
OpenSSLContext(Config *config_arg)
bool verify_ns_cert_type(::X509 *cert) const
std::unique_ptr<::SSL_CTX, decltype(&::SSL_CTX_free)> SSL_CTX_unique_ptr
SSLLib::Ctx libctx() override
static int verify_callback_server(int preverify_ok, X509_STORE_CTX *ctx)
bool deferred_cert_verify_failsafe(const SSL &ssl) const
static bool randomize_name_key(TLSSessionTicketBase::Name &name, TLSSessionTicketBase::Key &key)
std::string render_pem() const
std::string render_pem() const
void parse_pem(const std::string &dh_txt)
std::string render_pem() const
size_t key_length() const
void set_private_key_password(const std::string &pwd)
void parse_pem(const std::string &pkey_txt, const std::string &title, SSLLib::Ctx libctx)
PKType::Type key_type() const
std::string render_pem() const
std::string render_pem() const
void parse_pem(const std::string &cert_txt, const std::string &title)
std::string render_pem() const
std::unique_ptr< Key > UPtr
std::string get_optional(const std::string &name, size_t index, const size_t max_len) const
std::string cat(const std::string &name) const
const Option & get(const std::string &name) const
bool exists(const std::string &name) const
void reset() noexcept
Points this RCPtr<T> to nullptr safely.
RCPtr< U > dynamic_pointer_cast() const noexcept
Returns a "RCPtr<U>" that points to our T object.
T * get() const noexcept
Returns the raw pointer to the object T, or nullptr.
virtual SSLFactoryAPI::Ptr sni_hello(const std::string &sni_name, SNI::Metadata::UPtr &sni_metadata, SSLConfigAPI::Ptr default_factory) const =0
@ LF_ALLOW_CLIENT_CERT_NOT_REQUIRED
RCPtr< SSLFactoryAPI > Ptr
unsigned char hmac_value_[HMAC_KEY_SIZE]
unsigned char cipher_value_[CIPHER_KEY_SIZE]
static constexpr size_t CIPHER_KEY_SIZE
static constexpr size_t HMAC_KEY_SIZE
static constexpr size_t SIZE
virtual std::string session_id_context() const =0
virtual Status create_session_ticket_key(Name &name, Key &key) const =0
virtual Status lookup_session_ticket_key(const Name &name, Key &key) const =0
void init(const OptionList &opt, const std::string &relay_prefix)
bool verify(const std::string &value) const
static std::shared_ptr< XKeyExternalPKIImpl > create(SSL_CTX *ssl_ctx, ::X509 *cert, ExternalPKIBase *external_pki, std::string alias)
int log_level() const
return the current logging level for all logging
static logging::Logger< DEFAULT_LOG_LEVEL, MAX_LEVEL > log_
static void set_log_level(int level)
set the log level for all loggigng
static SSL_CTX * SSL_CTX_new_ex(void *libctx, const char *propq, const SSL_METHOD *meth)
#define EVP_PKEY_get_bits
static void OSSL_LIB_CTX_free(void *libctx)
static int EVP_PKEY_get_group_name(EVP_PKEY *pkey, char *gname, size_t gname_sz, size_t *gname_len)
#define OPENVPN_THROW(exc, stuff)
#define OPENVPN_LOG(args)
#define OVPN_LOG_TRACE(args)
#define OVPN_LOG_INFO(args)
void remote_cert_ku(const OptionList &opt, const std::string &relay_prefix, std::vector< unsigned int > &ku)
void remote_cert_tls(const TLSWebType wt, std::vector< unsigned int > &ku, std::string &eku)
void remote_cert_eku(const OptionList &opt, const std::string &relay_prefix, std::string &eku)
Type ns_cert_type(const std::string &ct)
static std::size_t x509_fingerprint_size()
static std::string x509_get_serial_hex(::X509 *cert)
static std::string x509_get_field(::X509 *cert, const int nid)
static std::string X509_get_pem_encoding(::X509 *cert)
static std::string x509_get_serial(::X509 *cert)
static std::vector< uint8_t > x509_get_fingerprint(const ::X509 *cert)
static std::string x509_get_subject(::X509 *cert, bool new_format=false)
static std::string x509_get_signature_algorithm(const ::X509 *cert)
@ VERIFY_PEER_FINGERPRINT
void apply_override(Type &type, const std::string &override)
Type default_if_undef(const Type type)
Type parse_tls_cert_profile(const std::string &profile_name)
std::string sanitize_x509_name(const std::string &str)
bool test(const std::string &tls_remote, const std::string &subject, const std::string &common_name)
std::string sanitize_common_name(const std::string &str)
void log(const std::string &tls_remote, const std::string &subject, const std::string &common_name)
int toTLSVersion(const Type version)
void apply_override(Type &tvm, const std::string &override)
Type parse_tls_version_min(const std::string &ver, const bool or_highest, const Type max_version)
bool is_valid_utf8_uchar_buf(const unsigned char *source, size_t size, const size_t max_len_flags=0)
BIO_METHOD * BIO_s_memq(void)
MemQ * memq_from_bio(BIO *b)
std::string get_string_optional(const Json::Value &root, const NAME &name, const std::string &default_value, const TITLE &title)
constexpr int LOG_LEVEL_INFO
void trim(std::string &str)
void openssl_clear_error_stack()
std::string to_string(const T &t)
Convert a value to a string.
const tls_cipher_name_pair * tls_get_cipher_name_pair(const std::string &ciphername)
std::string render_hex_sep(const unsigned char *data, size_t size, const char sep, const bool caps=false)
const std::string get_ssl_library_version()
bool match(const PeerFingerprint &fp) const
const char * openssl_name
const std::string cert_txt
static const char config[]