Kea  1.9.9-git
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 
16 #include <asiolink/asio_wrapper.h>
18 #include <asiolink/io_service.h>
19 #include <asiolink/common_tls.h>
20 
21 #include <boost/asio/ssl.hpp>
22 
23 namespace isc {
24 namespace asiolink {
25 
27 inline 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 
36 class TlsContext : public TlsContextBase {
37 public:
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 
62 protected:
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 
100 typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> TlsStreamImpl;
101 
109 template <typename Callback, typename TlsStreamImpl>
111 TlsStreamBase(IOService& service, TlsContextPtr context)
112  : TlsStreamImpl(service.get_io_service(), context->getContext()),
113  role_(context->getRole()) {
114 }
115 
119 template <typename Callback>
120 class TlsStream : public TlsStreamBase<Callback, TlsStreamImpl> {
121 public:
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
223 const int STREAM_TRUNCATED = boost::asio::ssl::error::stream_truncated;
224 #else
225 const 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-dhcp-ddns.