Kea 2.7.0
openssl_tls.h
Go to the documentation of this file.
1// Copyright (C) 2021-2024 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
7// Do not include this header directly: use crypto_tls.h instead.
8
9#ifndef OPENSSL_TLS_H
10#define OPENSSL_TLS_H
11
13
14#ifdef WITH_OPENSSL
15
18#include <asiolink/io_service.h>
19#include <asiolink/common_tls.h>
20
21#include <boost/asio/ssl.hpp>
22
23namespace isc {
24namespace asiolink {
25
27inline boost::asio::ssl::stream_base::handshake_type roleToImpl(TlsRole role) {
28 if (role == TlsRole::SERVER) {
29 return (boost::asio::ssl::stream_base::server);
30 } else {
31 return (boost::asio::ssl::stream_base::client);
32 }
33}
34
36class TlsContext : public TlsContextBase {
37public:
38
40 virtual ~TlsContext() { }
41
45 explicit TlsContext(TlsRole role);
46
48 boost::asio::ssl::context& getContext();
49
54 ::SSL_CTX* getNativeContext();
55
60 virtual bool getCertRequired() const;
61
69 static std::string getErrMsg(boost::system::error_code ec);
70
71protected:
76 virtual void setCertRequired(bool cert_required);
77
81 virtual void loadCaFile(const std::string& ca_file);
82
86 virtual void loadCaPath(const std::string& ca_path);
87
91 virtual void loadCertFile(const std::string& cert_file);
92
96 virtual void loadKeyFile(const std::string& key_file);
97
99 bool cert_required_;
100
102 boost::asio::ssl::context context_;
103
105 friend class TlsContextBase;
106};
107
109typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> TlsStreamImpl;
110
118template <typename Callback, typename TlsStreamImpl>
120TlsStreamBase(const IOServicePtr& io_service, TlsContextPtr context)
121 : StreamService(io_service, context),
122 TlsStreamImpl(io_service->getInternalIOService(),
123 context->getContext()), role_(context->getRole()) {
124}
125
129template <typename Callback>
130class TlsStream : public TlsStreamBase<Callback, TlsStreamImpl> {
131public:
132
134 typedef TlsStreamBase<Callback, TlsStreamImpl> Base;
135
141 TlsStream(const IOServicePtr& service, TlsContextPtr context)
142 : Base(service, context) {
143 }
144
146 virtual ~TlsStream() {
147 }
148
152 virtual void handshake(Callback& callback) {
153 Base::async_handshake(roleToImpl(Base::getRole()), callback);
154 }
155
159 virtual void shutdown(Callback& callback) {
160 Base::async_shutdown(callback);
161 }
162
173 virtual std::string getSubject() {
174 ::X509* cert = ::SSL_get_peer_certificate(this->native_handle());
175 if (!cert) {
176 return ("");
177 }
178 ::X509_NAME *name = ::X509_get_subject_name(cert);
179 int loc = ::X509_NAME_get_index_by_NID(name, NID_commonName, -1);
180 ::X509_NAME_ENTRY* ne = ::X509_NAME_get_entry(name, loc);
181 if (!ne) {
182 ::X509_free(cert);
183 return ("");
184 }
185 unsigned char* buf = 0;
186 int len = ::ASN1_STRING_to_UTF8(&buf, ::X509_NAME_ENTRY_get_data(ne));
187 if (len < 0) {
188 ::X509_free(cert);
189 return ("");
190 }
191 std::string ret(reinterpret_cast<char*>(buf), static_cast<size_t>(len));
192 ::OPENSSL_free(buf);
193 ::X509_free(cert);
194 return (ret);
195 }
196
207 virtual std::string getIssuer() {
208 ::X509* cert = ::SSL_get_peer_certificate(this->native_handle());
209 if (!cert) {
210 return ("");
211 }
212 ::X509_NAME *name = ::X509_get_issuer_name(cert);
213 int loc = ::X509_NAME_get_index_by_NID(name, NID_commonName, -1);
214 ::X509_NAME_ENTRY* ne = ::X509_NAME_get_entry(name, loc);
215 if (!ne) {
216 ::X509_free(cert);
217 return ("");
218 }
219 unsigned char* buf = 0;
220 int len = ::ASN1_STRING_to_UTF8(&buf, ::X509_NAME_ENTRY_get_data(ne));
221 if (len < 0) {
222 ::X509_free(cert);
223 return ("");
224 }
225 std::string ret(reinterpret_cast<char*>(buf), static_cast<size_t>(len));
226 ::OPENSSL_free(buf);
227 ::X509_free(cert);
228 return (ret);
229 }
230};
231
232// Stream truncated error code.
233#ifdef HAVE_STREAM_TRUNCATED_ERROR
234const int STREAM_TRUNCATED = boost::asio::ssl::error::stream_truncated;
235#else
236const int STREAM_TRUNCATED = ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ);
237#endif
238
239} // namespace asiolink
240} // namespace isc
241
242#endif // WITH_OPENSSL
243
244#endif // OPENSSL_TLS_H
Common TLS API.
Defines the logger used by the top-level component of kea-lfc.