Skip to content

Commit f5ffd86

Browse files
committed
WIP
1 parent 8ebc6a9 commit f5ffd86

File tree

3 files changed

+73
-10
lines changed

3 files changed

+73
-10
lines changed

lib/base/tlsstream.hpp

+28-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
#include <boost/asio/ssl/context.hpp>
2121
#include <boost/asio/ssl/stream.hpp>
2222

23+
#ifdef _WIN32
24+
# include <boost/wintls.hpp>
25+
#endif /* _WIN32 */
26+
2327
namespace icinga
2428
{
2529

@@ -63,7 +67,30 @@ struct UnbufferedAsioTlsStreamParams
6367
const String& Hostname;
6468
};
6569

66-
typedef SeenStream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> AsioTcpTlsStream;
70+
#ifdef _WIN32
71+
template<class T>
72+
class TlsStream : public boost::wintls::stream<T>
73+
{
74+
public:
75+
using boost::wintls::stream<T>::stream;
76+
77+
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
78+
typedef boost::wintls::handshake_type handshake_type;
79+
80+
static constexpr auto client = boost::wintls::handshake_type::client;
81+
static constexpr auto server = boost::wintls::handshake_type::server;
82+
83+
lowest_layer_type& lowest_layer()
84+
{
85+
return next_layer().lowest_layer();
86+
}
87+
};
88+
#else /* _WIN32 */
89+
template<class T>
90+
using TlsStream = boost::asio::ssl::stream<T>;
91+
#endif /* _WIN32 */
92+
93+
typedef SeenStream<TlsStream<boost::asio::ip::tcp::socket>> AsioTcpTlsStream;
6794

6895
class UnbufferedAsioTlsStream : public AsioTcpTlsStream
6996
{

lib/base/tlsutility.cpp

+34-7
Original file line numberDiff line numberDiff line change
@@ -245,14 +245,21 @@ void SetCipherListToSSLContext(const Shared<TlsContext>::Ptr& context, const Str
245245
* @return The value of the corresponding TLS*_VERSION macro.
246246
*/
247247
TlsProtocolMin ResolveTlsProtocolVersion(const std::string& version) {
248+
#ifdef _WIN32
249+
if (version == "TLSv1.2") {
250+
return TlsProtocolMin((int)TlsProtocolMin::tlsv12 | (int)TlsProtocolMin::tlsv13);
251+
} else if (version == "TLSv1.3") {
252+
return TlsProtocolMin::tlsv13;
253+
#else /* _WIN32 */
248254
if (version == "TLSv1.2") {
249255
return TLS1_2_VERSION;
250256
} else if (version == "TLSv1.3") {
251-
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
257+
# if OPENSSL_VERSION_NUMBER >= 0x10101000L
252258
return TLS1_3_VERSION;
253-
#else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
259+
# else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
254260
throw std::runtime_error("'" + version + "' is only supported with OpenSSL 1.1.1 or newer");
255-
#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
261+
# endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
262+
#endif /* _WIN32 */
256263
} else {
257264
throw std::runtime_error("Unknown TLS protocol version '" + version + "'");
258265
}
@@ -265,10 +272,26 @@ Shared<TlsContext>::Ptr SetupSslContext(const String& certPath, const String& ke
265272

266273
Shared<TlsContext>::Ptr context;
267274

275+
#ifdef _WIN32
276+
auto method (TlsProtocolMin::system_default);
277+
#else /* _WIN32 */
278+
auto method (TlsContext::tls);
279+
#endif /* _WIN32 */
280+
268281
InitializeOpenSSL();
269282

283+
#ifdef _WIN32
284+
if (!protocolmin.IsEmpty()) {
285+
try {
286+
method = ResolveTlsProtocolVersion(protocolmin);
287+
} catch (const std::exception&) {
288+
BOOST_THROW_EXCEPTION(ScriptError("Cannot set minimum TLS protocol version to SSL context with tls_protocolmin: '" + protocolmin + "'.", std::move(di)));
289+
}
290+
}
291+
#endif /* _WIN32 */
292+
270293
try {
271-
context = Shared<TlsContext>::Make(TlsContext::tls);
294+
context = Shared<TlsContext>::Make(method);
272295

273296
InitSslContext(context, certPath, keyPath, caPath);
274297
} catch (const std::exception&) {
@@ -294,17 +317,20 @@ Shared<TlsContext>::Ptr SetupSslContext(const String& certPath, const String& ke
294317
}
295318
}
296319

320+
#ifndef _WIN32
297321
if (!protocolmin.IsEmpty()){
298322
try {
299323
SetTlsProtocolminToSSLContext(context, protocolmin);
300324
} catch (const std::exception&) {
301325
BOOST_THROW_EXCEPTION(ScriptError("Cannot set minimum TLS protocol version to SSL context with tls_protocolmin: '" + protocolmin + "'.", std::move(di)));
302326
}
303327
}
328+
#endif /* _WIN32 */
304329

305330
return context;
306331
}
307332

333+
#ifndef _WIN32
308334
/**
309335
* Set the minimum TLS protocol version to the specified SSL context.
310336
*
@@ -313,7 +339,7 @@ Shared<TlsContext>::Ptr SetupSslContext(const String& certPath, const String& ke
313339
*/
314340
void SetTlsProtocolminToSSLContext(const Shared<TlsContext>::Ptr& context, const String& tlsProtocolmin)
315341
{
316-
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
342+
# if OPENSSL_VERSION_NUMBER >= 0x10100000L
317343
int ret = SSL_CTX_set_min_proto_version(context->native_handle(), ResolveTlsProtocolVersion(tlsProtocolmin));
318344

319345
if (ret != 1) {
@@ -326,12 +352,13 @@ void SetTlsProtocolminToSSLContext(const Shared<TlsContext>::Ptr& context, const
326352
<< boost::errinfo_api_function("SSL_CTX_set_min_proto_version")
327353
<< errinfo_openssl_error(ERR_peek_error()));
328354
}
329-
#else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
355+
# else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
330356
// This should never happen. On this OpenSSL version, ResolveTlsProtocolVersion() should either return TLS 1.2
331357
// or throw an exception, as that's the only TLS version supported by both Icinga and ancient OpenSSL.
332358
VERIFY(ResolveTlsProtocolVersion(tlsProtocolmin) == TLS1_2_VERSION);
333-
#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
359+
# endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
334360
}
361+
#endif /* _WIN32 */
335362

336363
/**
337364
* Loads a CRL and appends its certificates to the specified Boost SSL context.

lib/base/tlsutility.hpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
#include <boost/asio/ssl/context.hpp>
2323
#include <boost/exception/info.hpp>
2424

25+
#ifdef _WIN32
26+
# include <boost/wintls/context.hpp>
27+
#endif /* _WIN32 */
28+
2529
namespace icinga
2630
{
2731

@@ -38,18 +42,23 @@ const auto LEAF_VALID_FOR = 60 * 60 * 24 * 397;
3842
const auto RENEW_THRESHOLD = 60 * 60 * 24 * 30;
3943
const auto RENEW_INTERVAL = 60 * 60 * 24;
4044

45+
#ifdef _WIN32
46+
typedef boost::wintls::context TlsContext;
47+
typedef boost::wintls::method TlsProtocolMin;
48+
#else /* _WIN32 */
4149
typedef boost::asio::ssl::context TlsContext;
42-
4350
typedef int TlsProtocolMin;
4451

52+
void SetTlsProtocolminToSSLContext(const Shared<TlsContext>::Ptr& context, const String& tlsProtocolmin);
53+
#endif /* _WIN32 */
54+
4555
void InitializeOpenSSL();
4656

4757
String GetOpenSSLVersion();
4858

4959
void AddCRLToSSLContext(const Shared<TlsContext>::Ptr& context, const String& crlPath);
5060
void AddCRLToSSLContext(X509_STORE *x509_store, const String& crlPath);
5161
void SetCipherListToSSLContext(const Shared<TlsContext>::Ptr& context, const String& cipherList);
52-
void SetTlsProtocolminToSSLContext(const Shared<TlsContext>::Ptr& context, const String& tlsProtocolmin);
5362
TlsProtocolMin ResolveTlsProtocolVersion(const std::string& version);
5463

5564
Shared<TlsContext>::Ptr SetupSslContext(const String& certPath = String(), const String& keyPath = String(), const String& caPath = String(),

0 commit comments

Comments
 (0)