Kea 2.2.0
openssl_tls.h
Go to the documentation of this file.
1// Copyright (C) 2021-2022 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(IOService& service, TlsContextPtr context)
121 : TlsStreamImpl(service.get_io_service(), context->getContext()),
122 role_(context->getRole()) {
123}
124
128template <typename Callback>
129class TlsStream : public TlsStreamBase<Callback, TlsStreamImpl> {
130public:
131
133 typedef TlsStreamBase<Callback, TlsStreamImpl> Base;
134
140 TlsStream(IOService& service, TlsContextPtr context)
141 : Base(service, context) {
142 }
143
145 virtual ~TlsStream() { }
146
150 virtual void handshake(Callback& callback) {
151 Base::async_handshake(roleToImpl(Base::getRole()), callback);
152 }
153
157 virtual void shutdown(Callback& callback) {
158 Base::async_shutdown(callback);
159 }
160
171 virtual std::string getSubject() {
172 ::X509* cert = ::SSL_get_peer_certificate(this->native_handle());
173 if (!cert) {
174 return ("");
175 }
176 ::X509_NAME *name = ::X509_get_subject_name(cert);
177 int loc = ::X509_NAME_get_index_by_NID(name, NID_commonName, -1);
178 ::X509_NAME_ENTRY* ne = ::X509_NAME_get_entry(name, loc);
179 if (!ne) {
180 ::X509_free(cert);
181 return ("");
182 }
183 unsigned char* buf = 0;
184 int len = ::ASN1_STRING_to_UTF8(&buf, ::X509_NAME_ENTRY_get_data(ne));
185 if (len < 0) {
186 ::X509_free(cert);
187 return ("");
188 }
189 std::string ret(reinterpret_cast<char*>(buf), static_cast<size_t>(len));
190 ::OPENSSL_free(buf);
191 ::X509_free(cert);
192 return (ret);
193 }
194
205 virtual std::string getIssuer() {
206 ::X509* cert = ::SSL_get_peer_certificate(this->native_handle());
207 if (!cert) {
208 return ("");
209 }
210 ::X509_NAME *name = ::X509_get_issuer_name(cert);
211 int loc = ::X509_NAME_get_index_by_NID(name, NID_commonName, -1);
212 ::X509_NAME_ENTRY* ne = ::X509_NAME_get_entry(name, loc);
213 if (!ne) {
214 ::X509_free(cert);
215 return ("");
216 }
217 unsigned char* buf = 0;
218 int len = ::ASN1_STRING_to_UTF8(&buf, ::X509_NAME_ENTRY_get_data(ne));
219 if (len < 0) {
220 ::X509_free(cert);
221 return ("");
222 }
223 std::string ret(reinterpret_cast<char*>(buf), static_cast<size_t>(len));
224 ::OPENSSL_free(buf);
225 ::X509_free(cert);
226 return (ret);
227 }
228};
229
230// Stream truncated error code.
231#ifdef HAVE_STREAM_TRUNCATED_ERROR
232const int STREAM_TRUNCATED = boost::asio::ssl::error::stream_truncated;
233#else
234const int STREAM_TRUNCATED = ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ);
235#endif
236
237} // namespace asiolink
238} // namespace isc
239
240#endif // WITH_OPENSSL
241
242#endif // OPENSSL_TLS_H
Common TLS API.
Defines the logger used by the top-level component of kea-lfc.