Kea 3.1.1
openssl_tls.cc
Go to the documentation of this file.
1// Copyright (C) 2021-2025 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
8
9#include <config.h>
10
11#ifdef WITH_OPENSSL
12
14#include <asiolink/crypto_tls.h>
15
16#include <sys/stat.h>
17
18#include <openssl/opensslv.h>
19
20using namespace boost::asio;
21using namespace boost::asio::ssl;
22using namespace boost::system;
23using namespace isc::cryptolink;
24
25namespace isc {
26namespace asiolink {
27
28// Enforce TLS 1.2 when the generic TLS method is not available (i.e.
29// the boost version is older than 1.64.0).
30TlsContext::TlsContext(TlsRole role)
31 : TlsContextBase(role), cert_required_(true),
32 context_(context::method::tls)
33{
34 // Not leave the verify mode to OpenSSL default.
35 setCertRequired(true);
36}
37
38boost::asio::ssl::context&
39TlsContext::getContext() {
40 return (context_);
41}
42
43::SSL_CTX*
44TlsContext::getNativeContext() {
45 return (context_.native_handle());
46}
47
48void
49TlsContext::setCertRequired(bool cert_required) {
50 if (!cert_required && (getRole() == TlsRole::CLIENT)) {
52 "'cert-required' parameter must be true for a TLS client");
53 }
54 cert_required_ = cert_required;
55 error_code ec;
56 int mode = verify_peer | verify_fail_if_no_peer_cert;
57 if (!cert_required_) {
58 mode = verify_none;
59 }
60 context_.set_verify_mode(mode, ec);
61 if (ec) {
62 isc_throw(LibraryError, getErrMsg(ec));
63 }
64}
65
66bool
67TlsContext::getCertRequired() const {
68 return (cert_required_);
69}
70
71void
72TlsContext::loadCaFile(const std::string& ca_file) {
73 error_code ec;
74 context_.load_verify_file(ca_file, ec);
75 if (ec) {
76 isc_throw(LibraryError, getErrMsg(ec));
77 }
78}
79
80void
81TlsContext::loadCaPath(const std::string& ca_path) {
82 error_code ec;
83 context_.add_verify_path(ca_path, ec);
84 if (ec) {
85 isc_throw(LibraryError, getErrMsg(ec));
86 }
87}
88
89void
90TlsContext::loadCertFile(const std::string& cert_file) {
91 error_code ec;
92 context_.use_certificate_chain_file(cert_file, ec);
93 if (ec) {
94 isc_throw(LibraryError, getErrMsg(ec));
95 }
96}
97
98void
99TlsContext::loadKeyFile(const std::string& key_file) {
100 error_code ec;
101 context_.use_private_key_file(key_file, context::file_format::pem, ec);
102 if (ec) {
103 isc_throw(LibraryError, getErrMsg(ec));
104 }
105}
106
107std::string
108TlsContext::getErrMsg(error_code ec) {
109 std::string msg = ec.message();
110#ifdef ERR_SYSTEM_ERROR
111 // The SSL category message() method uses ERR_reason_error_string()
112 // which since OpenSSL 3.0 returns NULL on system errors in order
113 // to avoid a memory leak with the strerror_r() buffer.
114 // This code recovers the user-friendly message from the error code
115 // value i.e. the OpenSSL error. Layout of OpenSSL errors is detailed
116 // in the OpenSSL err.h header.
117 unsigned long err = static_cast<unsigned long>(ec.value());
118 if ((msg == "asio.ssl error") && (ERR_SYSTEM_ERROR(err))) {
119 char buf[1024];
120#ifndef __USE_GNU
121 if (strerror_r(err & ERR_SYSTEM_MASK, &buf[0], sizeof(buf)) == 0) {
122 msg = buf;
123 }
124#else
125 msg = strerror_r(err & ERR_SYSTEM_MASK, &buf[0], sizeof(buf));
126#endif
127 }
128#endif
129 return (msg);
130}
131
132} // namespace asiolink
133} // namespace isc
134
135#endif // WITH_OPENSSL
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
TLS API.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Defines the logger used by the top-level component of kea-lfc.