@@ -290,16 +290,18 @@ class SSLContext
290
290
{
291
291
return ctxPtr_;
292
292
}
293
+ bool mtlsEnabled = false ;
293
294
294
295
private:
295
296
SSL_CTX *ctxPtr_;
296
297
};
297
298
class SSLConn
298
299
{
299
300
public:
300
- explicit SSLConn (SSL_CTX *ctx)
301
+ explicit SSLConn (SSL_CTX *ctx, bool mtlsEnabled_ )
301
302
{
302
303
SSL_ = SSL_new (ctx);
304
+ mtlsEnabled = mtlsEnabled_;
303
305
}
304
306
~SSLConn ()
305
307
{
@@ -312,6 +314,7 @@ class SSLConn
312
314
{
313
315
return SSL_;
314
316
}
317
+ bool mtlsEnabled = false ;
315
318
316
319
private:
317
320
SSL *SSL_;
@@ -329,7 +332,8 @@ std::shared_ptr<SSLContext> newSSLServerContext(
329
332
const std::string &certPath,
330
333
const std::string &keyPath,
331
334
bool useOldTLS,
332
- const std::vector<std::pair<std::string, std::string>> &sslConfCmds)
335
+ const std::vector<std::pair<std::string, std::string>> &sslConfCmds,
336
+ const std::string &caPath)
333
337
{
334
338
auto ctx = newSSLContext (useOldTLS, false , sslConfCmds);
335
339
auto r = SSL_CTX_use_certificate_chain_file (ctx->get (), certPath.c_str ());
@@ -356,14 +360,38 @@ std::shared_ptr<SSLContext> newSSLServerContext(
356
360
LOG_FATAL << " Checking private key matches certificate: " << errbuf;
357
361
throw std::runtime_error (" SSL_CTX_check_private_key error" );
358
362
}
363
+
364
+ if (!caPath.empty ())
365
+ {
366
+ auto checkCA =
367
+ SSL_CTX_load_verify_locations (ctx->get (), caPath.c_str (), NULL );
368
+ LOG_DEBUG << " CA CHECK LOC: " << checkCA;
369
+ if (checkCA)
370
+ {
371
+ STACK_OF (X509_NAME) *cert_names =
372
+ SSL_load_client_CA_file (caPath.c_str ());
373
+ if (cert_names != NULL )
374
+ {
375
+ SSL_CTX_set_client_CA_list (ctx->get (), cert_names);
376
+ }
377
+ ctx->mtlsEnabled = true ;
378
+ }
379
+ else
380
+ {
381
+ LOG_FATAL << " caPath location error " ;
382
+ throw std::runtime_error (" SSL_CTX_load_verify_locations error" );
383
+ }
384
+ }
385
+
359
386
return ctx;
360
387
}
361
388
std::shared_ptr<SSLContext> newSSLClientContext (
362
389
bool useOldTLS,
363
390
bool validateCert,
364
391
const std::string &certPath,
365
392
const std::string &keyPath,
366
- const std::vector<std::pair<std::string, std::string>> &sslConfCmds)
393
+ const std::vector<std::pair<std::string, std::string>> &sslConfCmds,
394
+ const std::string &caPath)
367
395
{
368
396
auto ctx = newSSLContext (useOldTLS, validateCert, sslConfCmds);
369
397
if (certPath.empty () || keyPath.empty ())
@@ -393,6 +421,29 @@ std::shared_ptr<SSLContext> newSSLClientContext(
393
421
LOG_FATAL << " Checking private key matches certificate: " << errbuf;
394
422
throw std::runtime_error (" SSL_CTX_check_private_key error." );
395
423
}
424
+
425
+ if (!caPath.empty ())
426
+ {
427
+ auto checkCA =
428
+ SSL_CTX_load_verify_locations (ctx->get (), caPath.c_str (), NULL );
429
+ LOG_DEBUG << " CA CHECK LOC: " << checkCA;
430
+ if (checkCA)
431
+ {
432
+ STACK_OF (X509_NAME) *cert_names =
433
+ SSL_load_client_CA_file (caPath.c_str ());
434
+ if (cert_names != NULL )
435
+ {
436
+ SSL_CTX_set_client_CA_list (ctx->get (), cert_names);
437
+ }
438
+ ctx->mtlsEnabled = true ;
439
+ }
440
+ else
441
+ {
442
+ LOG_FATAL << " caPath location error " ;
443
+ throw std::runtime_error (" SSL_CTX_load_verify_locations error" );
444
+ }
445
+ }
446
+
396
447
return ctx;
397
448
}
398
449
} // namespace trantor
@@ -403,7 +454,8 @@ std::shared_ptr<SSLContext> newSSLServerContext(
403
454
const std::string &,
404
455
const std::string &,
405
456
bool ,
406
- const std::vector<std::pair<std::string, std::string>> &)
457
+ const std::vector<std::pair<std::string, std::string>> &,
458
+ const std::string &)
407
459
{
408
460
LOG_FATAL << " OpenSSL is not found in your system!" ;
409
461
throw std::runtime_error (" OpenSSL is not found in your system!" );
@@ -457,11 +509,15 @@ void TcpConnectionImpl::startClientEncryptionInLoop(
457
509
sslEncryptionPtr_->sslCtxPtr_ =
458
510
newSSLContext (useOldTLS, validateCert_, sslConfCmds);
459
511
sslEncryptionPtr_->sslPtr_ =
460
- std::make_unique<SSLConn>(sslEncryptionPtr_->sslCtxPtr_ ->get ());
461
- if (validateCert)
512
+ std::make_unique<SSLConn>(sslEncryptionPtr_->sslCtxPtr_ ->get (),
513
+ sslEncryptionPtr_->sslCtxPtr_ ->mtlsEnabled );
514
+ if (validateCert || sslEncryptionPtr_->sslPtr_ ->mtlsEnabled )
462
515
{
516
+ LOG_DEBUG << " MTLS: " << sslEncryptionPtr_->sslPtr_ ->mtlsEnabled ;
463
517
SSL_set_verify (sslEncryptionPtr_->sslPtr_ ->get (),
464
- SSL_VERIFY_NONE,
518
+ sslEncryptionPtr_->sslPtr_ ->mtlsEnabled
519
+ ? SSL_VERIFY_PEER
520
+ : SSL_VERIFY_NONE,
465
521
nullptr );
466
522
validateCert_ = validateCert;
467
523
}
@@ -497,13 +553,21 @@ void TcpConnectionImpl::startServerEncryptionInLoop(
497
553
sslEncryptionPtr_->sslCtxPtr_ = ctx;
498
554
sslEncryptionPtr_->isServer_ = true ;
499
555
sslEncryptionPtr_->sslPtr_ =
500
- std::make_unique<SSLConn>(sslEncryptionPtr_->sslCtxPtr_ ->get ());
556
+ std::make_unique<SSLConn>(sslEncryptionPtr_->sslCtxPtr_ ->get (),
557
+ sslEncryptionPtr_->sslCtxPtr_ ->mtlsEnabled );
501
558
isEncrypted_ = true ;
502
559
sslEncryptionPtr_->isUpgrade_ = true ;
503
- if (sslEncryptionPtr_->isServer_ == false )
560
+ if (sslEncryptionPtr_->isServer_ == false ||
561
+ sslEncryptionPtr_->sslPtr_ ->mtlsEnabled )
562
+ {
563
+ LOG_DEBUG << " MTLS: " << sslEncryptionPtr_->sslPtr_ ->mtlsEnabled ;
504
564
SSL_set_verify (sslEncryptionPtr_->sslPtr_ ->get (),
505
- SSL_VERIFY_NONE,
565
+ sslEncryptionPtr_->sslPtr_ ->mtlsEnabled
566
+ ? SSL_VERIFY_PEER
567
+ : SSL_VERIFY_NONE,
506
568
nullptr );
569
+ }
570
+
507
571
auto r = SSL_set_fd (sslEncryptionPtr_->sslPtr_ ->get (), socketPtr_->fd ());
508
572
(void )r;
509
573
assert (r);
@@ -1895,13 +1959,20 @@ TcpConnectionImpl::TcpConnectionImpl(EventLoop *loop,
1895
1959
socketPtr_->setKeepAlive (true );
1896
1960
name_ = localAddr.toIpPort () + " --" + peerAddr.toIpPort ();
1897
1961
sslEncryptionPtr_ = std::make_unique<SSLEncryption>();
1898
- sslEncryptionPtr_->sslPtr_ = std::make_unique<SSLConn>(ctxPtr->get ());
1962
+ sslEncryptionPtr_->sslPtr_ =
1963
+ std::make_unique<SSLConn>(ctxPtr->get (), ctxPtr->mtlsEnabled );
1899
1964
sslEncryptionPtr_->isServer_ = isServer;
1900
1965
validateCert_ = validateCert;
1901
- if (isServer == false )
1966
+ if (isServer == false || sslEncryptionPtr_->sslPtr_ ->mtlsEnabled )
1967
+ {
1968
+ LOG_DEBUG << " MTLS: " << sslEncryptionPtr_->sslPtr_ ->mtlsEnabled ;
1902
1969
SSL_set_verify (sslEncryptionPtr_->sslPtr_ ->get (),
1903
- SSL_VERIFY_NONE,
1970
+ sslEncryptionPtr_->sslPtr_ ->mtlsEnabled
1971
+ ? SSL_VERIFY_PEER
1972
+ : SSL_VERIFY_NONE,
1904
1973
nullptr );
1974
+ }
1975
+
1905
1976
if (!isServer && !hostname.empty ())
1906
1977
{
1907
1978
SSL_set_tlsext_host_name (sslEncryptionPtr_->sslPtr_ ->get (),
@@ -1925,12 +1996,25 @@ bool TcpConnectionImpl::validatePeerCertificate()
1925
1996
SSL *ssl = sslEncryptionPtr_->sslPtr_ ->get ();
1926
1997
1927
1998
auto result = SSL_get_verify_result (ssl);
1928
- if (result != X509_V_OK)
1999
+
2000
+ #ifdef ALLOW_SELF_SIGNED_CERTS
2001
+ if (result != X509_V_OK &&
2002
+ result != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT &&
2003
+ result != X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN &&
2004
+ result != X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
2005
+ {
2006
+ LOG_DEBUG << " cert error code: " << result;
2007
+ LOG_ERROR << " Server certificate is not valid" ;
2008
+ return false ;
2009
+ }
2010
+ #else
2011
+ if (result != X509_V_OK && result)
1929
2012
{
1930
2013
LOG_DEBUG << " cert error code: " << result;
1931
2014
LOG_ERROR << " Server certificate is not valid" ;
1932
2015
return false ;
1933
2016
}
2017
+ #endif
1934
2018
1935
2019
X509 *cert = SSL_get_peer_certificate (ssl);
1936
2020
if (cert == nullptr )
@@ -1944,7 +2028,10 @@ bool TcpConnectionImpl::validatePeerCertificate()
1944
2028
internal::verifyAltName (cert, sslEncryptionPtr_->hostname_ );
1945
2029
X509_free (cert);
1946
2030
1947
- if (domainIsValid)
2031
+ LOG_DEBUG << " domainIsValid: " << domainIsValid;
2032
+
2033
+ // if mtlsEnabled, ignore domain validation
2034
+ if (sslEncryptionPtr_->sslPtr_ ->mtlsEnabled || domainIsValid)
1948
2035
{
1949
2036
return true ;
1950
2037
}
@@ -1965,7 +2052,8 @@ void TcpConnectionImpl::doHandshaking()
1965
2052
{
1966
2053
// Clients don't commonly have certificates. Let's not validate
1967
2054
// that
1968
- if (validateCert_ && sslEncryptionPtr_->isServer_ == false )
2055
+ if (validateCert_ && (!sslEncryptionPtr_->isServer_ ||
2056
+ sslEncryptionPtr_->sslPtr_ ->mtlsEnabled ))
1969
2057
{
1970
2058
if (validatePeerCertificate () == false )
1971
2059
{
0 commit comments