|
59 | 59 | #include "mongo/util/net/private/ssl_expiration.h" |
60 | 60 | #include "mongo/util/net/socket_exception.h" |
61 | 61 | #include "mongo/util/net/ssl_options.h" |
| 62 | +#include "mongo/util/net/ssl_parameters_gen.h" |
62 | 63 | #include "mongo/util/net/ssl_types.h" |
63 | 64 | #include "mongo/util/scopeguard.h" |
64 | 65 | #include "mongo/util/str.h" |
@@ -240,10 +241,21 @@ IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN |
240 | 241 | const STACK_OF(X509_EXTENSION) * X509_get0_extensions(const X509* peerCert) { |
241 | 242 | return peerCert->cert_info->extensions; |
242 | 243 | } |
| 244 | + |
| 245 | +inline ASN1_TIME* X509_get0_notAfter(const X509* cert) { |
| 246 | + return X509_get_notAfter(cert); |
| 247 | +} |
| 248 | + |
243 | 249 | inline int X509_NAME_ENTRY_set(const X509_NAME_ENTRY* ne) { |
244 | 250 | return ne->set; |
245 | 251 | } |
246 | 252 |
|
| 253 | +#if OPENSSL_VESION_NUMBER < 0x10002000L |
| 254 | +inline bool ASN1_TIME_diff(int*, int*, const ASN1_TIME*, const ASN1_TIME*) { |
| 255 | + return false; |
| 256 | +} |
| 257 | +#endif |
| 258 | + |
247 | 259 | int DH_set0_pqg(DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g) { |
248 | 260 | dh->p = p; |
249 | 261 | dh->g = g; |
@@ -1531,22 +1543,39 @@ StatusWith<SSLPeerInfo> SSLManagerOpenSSL::parseAndValidatePeerCertificate( |
1531 | 1543 | auto peerSubject = getCertificateSubjectX509Name(peerCert); |
1532 | 1544 | LOG(2) << "Accepted TLS connection from peer: " << peerSubject; |
1533 | 1545 |
|
1534 | | - // If this is a server and client and server certificate are the same, log a warning. |
1535 | | - if (remoteHost.empty() && _sslConfiguration.serverSubjectName() == peerSubject) { |
1536 | | - warning() << "Client connecting with server's own TLS certificate"; |
1537 | | - } |
1538 | | - |
1539 | 1546 | StatusWith<stdx::unordered_set<RoleName>> swPeerCertificateRoles = _parsePeerRoles(peerCert); |
1540 | 1547 | if (!swPeerCertificateRoles.isOK()) { |
1541 | 1548 | return swPeerCertificateRoles.getStatus(); |
1542 | 1549 | } |
1543 | 1550 |
|
1544 | | - // If this is an SSL client context (on a MongoDB server or client) |
1545 | | - // perform hostname validation of the remote server |
| 1551 | + // Server side. |
1546 | 1552 | if (remoteHost.empty()) { |
| 1553 | + const auto exprThreshold = tlsX509ExpirationWarningThresholdDays; |
| 1554 | + if (exprThreshold > 0) { |
| 1555 | + const auto expiration = X509_get0_notAfter(peerCert); |
| 1556 | + time_t threshold = (Date_t::now() + Days(exprThreshold)).toTimeT(); |
| 1557 | + |
| 1558 | + if (X509_cmp_time(expiration, &threshold) < 0) { |
| 1559 | + int days = 0, secs = 0; |
| 1560 | + if (!ASN1_TIME_diff(&days, &secs, nullptr /* now */, expiration)) { |
| 1561 | + tlsEmitWarningExpiringClientCertificate(peerSubject); |
| 1562 | + } else { |
| 1563 | + tlsEmitWarningExpiringClientCertificate(peerSubject, Days(days)); |
| 1564 | + } |
| 1565 | + } |
| 1566 | + } |
| 1567 | + |
| 1568 | + // If client and server certificate are the same, log a warning. |
| 1569 | + if (_sslConfiguration.serverSubjectName() == peerSubject) { |
| 1570 | + warning() << "Client connecting with server's own TLS certificate"; |
| 1571 | + } |
| 1572 | + |
1547 | 1573 | return SSLPeerInfo(peerSubject, sniName, std::move(swPeerCertificateRoles.getValue())); |
1548 | 1574 | } |
1549 | 1575 |
|
| 1576 | + // If this is an SSL client context (on a MongoDB server or client) |
| 1577 | + // perform hostname validation of the remote server. |
| 1578 | + |
1550 | 1579 | // This is to standardize the IPAddress format for comparison. |
1551 | 1580 | auto swCIDRRemoteHost = CIDR::parse(remoteHost); |
1552 | 1581 |
|
|
0 commit comments