Kea 2.0.3
openssl_tls.h
Go to the documentation of this file.
1// Copyright (C) 2021 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
62protected:
67 virtual void setCertRequired(bool cert_required);
68
72 virtual void loadCaFile(const std::string& ca_file);
73
77 virtual void loadCaPath(const std::string& ca_path);
78
82 virtual void loadCertFile(const std::string& cert_file);
83
87 virtual void loadKeyFile(const std::string& key_file);
88
90 bool cert_required_;
91
93 boost::asio::ssl::context context_;
94
96 friend class TlsContextBase;
97};
98
100typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> TlsStreamImpl;
101
109template <typename Callback, typename TlsStreamImpl>
111TlsStreamBase(IOService& service, TlsContextPtr context)
112 : TlsStreamImpl(service.get_io_service(), context->getContext()),
113 role_(context->getRole()) {
114}
115
119template <typename Callback>
120class TlsStream : public TlsStreamBase<Callback, TlsStreamImpl> {
121public:
122
124 typedef TlsStreamBase<Callback, TlsStreamImpl> Base;
125
131 TlsStream(IOService& service, TlsContextPtr context)
132 : Base(service, context) {
133 }
134
136 virtual ~TlsStream() { }
137
141 virtual void handshake(Callback& callback) {
142 Base::async_handshake(roleToImpl(Base::getRole()), callback);
143 }
144
148 virtual void shutdown(Callback& callback) {
149 Base::async_shutdown(callback);
150 }
151
162 virtual std::string getSubject() {
163 ::X509* cert = ::SSL_get_peer_certificate(this->native_handle());
164 if (!cert) {
165 return ("");
166 }
167 ::X509_NAME *name = ::X509_get_subject_name(cert);
168 int loc = ::X509_NAME_get_index_by_NID(name, NID_commonName, -1);
169 ::X509_NAME_ENTRY* ne = ::X509_NAME_get_entry(name, loc);
170 if (!ne) {
171 ::X509_free(cert);
172 return ("");
173 }
174 unsigned char* buf = 0;
175 int len = ::ASN1_STRING_to_UTF8(&buf, ::X509_NAME_ENTRY_get_data(ne));
176 if (len < 0) {
177 ::X509_free(cert);
178 return ("");
179 }
180 std::string ret(reinterpret_cast<char*>(buf), static_cast<size_t>(len));
181 ::OPENSSL_free(buf);
182 ::X509_free(cert);
183 return (ret);
184 }
185
196 virtual std::string getIssuer() {
197 ::X509* cert = ::SSL_get_peer_certificate(this->native_handle());
198 if (!cert) {
199 return ("");
200 }
201 ::X509_NAME *name = ::X509_get_issuer_name(cert);
202 int loc = ::X509_NAME_get_index_by_NID(name, NID_commonName, -1);
203 ::X509_NAME_ENTRY* ne = ::X509_NAME_get_entry(name, loc);
204 if (!ne) {
205 ::X509_free(cert);
206 return ("");
207 }
208 unsigned char* buf = 0;
209 int len = ::ASN1_STRING_to_UTF8(&buf, ::X509_NAME_ENTRY_get_data(ne));
210 if (len < 0) {
211 ::X509_free(cert);
212 return ("");
213 }
214 std::string ret(reinterpret_cast<char*>(buf), static_cast<size_t>(len));
215 ::OPENSSL_free(buf);
216 ::X509_free(cert);
217 return (ret);
218 }
219};
220
221// Stream truncated error code.
222#ifdef HAVE_STREAM_TRUNCATED_ERROR
223const int STREAM_TRUNCATED = boost::asio::ssl::error::stream_truncated;
224#else
225const int STREAM_TRUNCATED = ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ);
226#endif
227
228} // namespace asiolink
229} // namespace isc
230
231#endif // WITH_OPENSSL
232
233#endif // OPENSSL_TLS_H
Common TLS API.
Defines the logger used by the top-level component of kea-lfc.