diff options
author | Erwin Pe <erwin.pe@mongodb.com> | 2021-10-21 17:56:38 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-10-21 18:08:57 +0000 |
commit | a022feadf02806f9be151bc89a12682731d4ac1b (patch) | |
tree | 0b8271f194b46a4a94087700a40a4859b455192b | |
parent | e9a9c9f342381cbe332bb1c46ecfbd15924c7150 (diff) | |
download | mongo-a022feadf02806f9be151bc89a12682731d4ac1b.tar.gz |
SERVER-60326 Windows server fails to start when X509 certificate has empty subject name
(cherry picked from commit 7a68603aed1dd0b75caf0faae3a9986886af0f18)
-rw-r--r-- | jstests/libs/server_no_subject.pem | 56 | ||||
-rw-r--r-- | jstests/libs/server_no_subject_no_SAN.pem | 55 | ||||
-rw-r--r-- | jstests/ssl/ssl_hostname_validation.js | 9 | ||||
-rw-r--r-- | jstests/ssl/x509/certs.yml | 24 | ||||
-rwxr-xr-x | jstests/ssl/x509/mkcert.py | 10 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_manager_windows.cpp | 4 |
6 files changed, 156 insertions, 2 deletions
diff --git a/jstests/libs/server_no_subject.pem b/jstests/libs/server_no_subject.pem new file mode 100644 index 00000000000..d27c5e438e0 --- /dev/null +++ b/jstests/libs/server_no_subject.pem @@ -0,0 +1,56 @@ +# Autogenerated file, do not edit. +# Generate using jstests/ssl/x509/mkcert.py --config jstests/ssl/x509/certs.yml server_no_subject.pem +# +# Server certificate with empty Subject, but critical SAN. +-----BEGIN CERTIFICATE----- +MIIEDTCCAvWgAwIBAgIEFU1Q8DANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJV +UzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAO +BgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEXMBUGA1UEAwwOS2VybmVs +IFRlc3QgQ0EwHhcNMjEwOTI5MTYzNDIyWhcNNDExMDAxMTYzNDIyWjAAMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz2DvR4rmqxj8jThXpcL9VjlFz3TT +JTUX+Oyewwe3N39XCfo+DNu6Z/TNibYgn1SI9j/F8UxrAxtw7tYeE4mMUiDwDuTk +YHMkoHcmOLr5ZIhRudEIIPwQXDZTIViYpx+qwDEHQr22kaDeNT88OphL3oh84zpn +KplfDXj3vOzamJCsdDQvS28s4IPyAXHMh4IvAovPUsX23aJfg9VHT/zfZVVl0KT0 +vZdsR4BeZeAXOQoLB3yy42OiyaVIf7vjcutHxGJEWcrUIAVkLdHFGu8xYvO3CQe4 +6Y/fmffVR6nXl+7cX98dcZfrIKgU1sgb0p0XD3Qjj4Ogq4WaPf3i3CiKewIDAQAB +o4IBGTCCARUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwHQYDVR0lBBYwFAYIKwYB +BQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBQ1H/2P5mRrXKN4E9j1LhrcptsFBzCB +iwYDVR0jBIGDMIGAoXikdjB0MQswCQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlv +cmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAOBgNVBAoMB01vbmdvREIxDzAN +BgNVBAsMBktlcm5lbDEXMBUGA1UEAwwOS2VybmVsIFRlc3QgQ0GCBBmRIxIwLwYD +VR0RAQH/BCUwI4IJbG9jYWxob3N0hwR/AAABhxAAAAAAAAAAAAAAAAAAAAABMA0G +CSqGSIb3DQEBCwUAA4IBAQCbqcvURsil4JuXrzKvoAjYhuPzWpWmHFa8kbjAQ3Sa +ZUCHmH9YTMan4djm4iT+LAAD/+Oyc60hZ2hGvUppVZlM8t1u/itcR5WZiD3VmHU8 +EEktqg7TpKPh0VoHQ0IJS5Oht0KBjmlAJIRhaMsYrLsGFpMsiEAm5XufBuVCab79 +vlRz8/K9y3NVDRJY5A6IEIjUL+ATGXXbYIjEhnWM2TCPwwikfKmY05wxHfE8J31U +Wg+40lXTPpu8XfF4ErOocMf/s7xZbGEa1uhHa2NKEmFRXBHuED52M8MydiALTgnb +uA57R+S4OBTeDQSVwSpH8VsdxvmGJSv3VJzKTVpNhHX3 +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPYO9HiuarGPyN +OFelwv1WOUXPdNMlNRf47J7DB7c3f1cJ+j4M27pn9M2JtiCfVIj2P8XxTGsDG3Du +1h4TiYxSIPAO5ORgcySgdyY4uvlkiFG50Qgg/BBcNlMhWJinH6rAMQdCvbaRoN41 +Pzw6mEveiHzjOmcqmV8NePe87NqYkKx0NC9Lbyzgg/IBccyHgi8Ci89Sxfbdol+D +1UdP/N9lVWXQpPS9l2xHgF5l4Bc5CgsHfLLjY6LJpUh/u+Ny60fEYkRZytQgBWQt +0cUa7zFi87cJB7jpj9+Z99VHqdeX7txf3x1xl+sgqBTWyBvSnRcPdCOPg6CrhZo9 +/eLcKIp7AgMBAAECggEAeTSOpaHpb9cKxP9JOvjcWKjgxH/jaLu/Zx3lLNg1nZov +pQU9fwZtzJSoDPUF3BnscwCTEJU5dndzaiR7L7AU82uM4yek0zp5DdCV5lJhsQB7 +w78IoT6x0TNvIu5FSmiXw/zj4X5AVp1PQo/TA+w/a7EaTTS1V5CMnbM2GJXWrZPS +k/mlO23A8Pr8R3fbWm/O2xJgJIZ2hGtCkqTBLwwPXVTXcsPlZVRd/vxqtSTaFzxs +Nmh8kXiU7KpeXs3yQjTWuUkq52AXEg6zUdHy+lD2PglcnIoP3t30VWlwR/efTGpC +rnAReokjqGsWneZWlbUGcE+wEmFDS/prRsLXjV3bAQKBgQD+NRY+OxKL4tk9EfCX +FVqZdKDcdtpDak3n3r49Ymtj+lO8BaTGBqHu7NCidXKijjo35/MBuey1opvQI4tE +PzFBTswADCDGSEZhVeu/p/NegCWgYBNZiUR1DzwpC/1zzS/h7xvafKvGaz3vu/xj +mWLmOKSrAkKj/eOaF/J/JubknwKBgQDQ108tO90wE7jyg13m1YdVv72kAKlvXiUn +4tlP8cHTrsZIbqQOyWStxd8l5nxTHbjq81e75VAsbB7/P+CFbhCwY9YvcpcHu7Dc +IThUEhM9E/9QXWohgjULq0GEH5qXF+Ny5Z+L0JnQ+Ar66aBhoiit6o1iFPG2A2i+ +DjX14qrQpQKBgG2MzTgmVvjH2xzRZWCGyFOHimdYJPmWj1pUiKGFj4g3cex+diMM +6q4/ii3o9W0OZBKBuBzPVi50lDdfif3wSba+UXXXxCwPK5143K7snxnjmdOCc/RL +DqBv31pFG4XTMEZquBMxVQmeX8O3vK3jhVZ3pKc5wyRPHs3ichPP3QM7AoGBAMz9 +2wkSjt2nLk5VpjFz/SCtUe+OesIHTj9li1vOeSxYjOcCO2UMSBfOd2hTYkuPjDiL +Xd3gjB7ejlqMD83JKPaLOO1f9GGx2TtqHElhaKL2YxE2cHutvHXUxz1ybCLNXwQj +4sSxoJofL1/1POk46+cyqU7SMiQwGnsbpdnSgUrFAoGBANbRSBoBnvdc5vzwC6gZ +V4WCWS6AXXBW2UXDsZLfMBpFDYR7AeBqiumg7wZoQnTmucSGWxPZlKyJVC2aQkp/ +5Oc+tAOQWU+gBGAtg6zxDXr3cbx/MkkXt2hO5M5VJlHNL0lx8AH+V23lMRgA1S4T +TVFUwKHMSl35i6EL4JSgbPp/ +-----END PRIVATE KEY----- diff --git a/jstests/libs/server_no_subject_no_SAN.pem b/jstests/libs/server_no_subject_no_SAN.pem new file mode 100644 index 00000000000..9e453553666 --- /dev/null +++ b/jstests/libs/server_no_subject_no_SAN.pem @@ -0,0 +1,55 @@ +# Autogenerated file, do not edit. +# Generate using jstests/ssl/x509/mkcert.py --config jstests/ssl/x509/certs.yml server_no_subject_no_SAN.pem +# +# Server certificate with empty Subject, and no SANs. +-----BEGIN CERTIFICATE----- +MIID2jCCAsKgAwIBAgIEfSwWgzANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJV +UzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAO +BgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEXMBUGA1UEAwwOS2VybmVs +IFRlc3QgQ0EwHhcNMjExMDA0MTQwMDUwWhcNNDExMDA2MTQwMDUwWjAAMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs0wFITYhG1bYRxW46+nVp9JdEvLc +chEA0wy7WriuYZDuugpFd/8ox2Hz+nGRkqqZhUYDsTuJ15gjCHYjTclhB1D9V1BY +G7zTeU2nks4pCoRb6vyPcC4RAvGZLP9xWYb2r1+FCjl45Lz36VJYbAT2vmdRlXEX +r8yzpC9u6l2yuTmcal/+eV6tTU9ur0h1BXJUtQG4yz9bGnt5LG0rjO3TlNBj1P6S +FZsCU5MRAyuUlqIoQhOsR+ZP3hy97booNSAr/AQFjrpTPTKne07bPcj3N/SepiqO +mY98bbWu1qS2rSW7d3/eLhCYm8W0tn65/BeFMJ1P8XuuHsMtaq2qeigOSQIDAQAB +o4HnMIHkMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF +BwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQUiZYndlIAlQl5WN3XHADXRDsuxJUwgYsG +A1UdIwSBgzCBgKF4pHYwdDELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3Jr +MRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MRAwDgYDVQQKDAdNb25nb0RCMQ8wDQYD +VQQLDAZLZXJuZWwxFzAVBgNVBAMMDktlcm5lbCBUZXN0IENBggQZkSMSMA0GCSqG +SIb3DQEBCwUAA4IBAQCHVyAZELMyrjKhtl6Y38x68pNgFjVUOY3unnrtLttNMRhG +6xpFTbPKkwS8itJ4jwiY8f+yNdGqGyTfWqG5vwATK1jXxfpShUok+IVj0v8vzGve +E9yA+TcGYZfX9aprhT4QEwrn9jhDtAaNDyZ+gSld0W775at9Z6jbmlDoxh9E/O4r +b7fSnEwz/vCmmLkXcNCycOAQYcAcSV9PZsKshTq1foSQBKJd8sWo7XKEDVhw8LJi +RDEtXAmT4BkMHKgFUi2vYjM7mCUoc+O00EbLGyTH/R+GavtiqLAHMYhXVw9E7LGb +juNqiCdfDOKTYWOiWEtYYpn95bJZToSRquK9PpvG +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCzTAUhNiEbVthH +Fbjr6dWn0l0S8txyEQDTDLtauK5hkO66CkV3/yjHYfP6cZGSqpmFRgOxO4nXmCMI +diNNyWEHUP1XUFgbvNN5TaeSzikKhFvq/I9wLhEC8Zks/3FZhvavX4UKOXjkvPfp +UlhsBPa+Z1GVcRevzLOkL27qXbK5OZxqX/55Xq1NT26vSHUFclS1AbjLP1sae3ks +bSuM7dOU0GPU/pIVmwJTkxEDK5SWoihCE6xH5k/eHL3tuig1ICv8BAWOulM9Mqd7 +Tts9yPc39J6mKo6Zj3xtta7WpLatJbt3f94uEJibxbS2frn8F4UwnU/xe64ewy1q +rap6KA5JAgMBAAECggEASM+YTbJjo2yTC9sAa51cDHjbHzTM3O2Wvh4vf1n8RtbK +e3ZsW5yc/MsEfzHbggoRqhOSsEiTY5/+qhL/pzkeVBBJsUmJXkpCPsKQSIe8Fu9F +PJovzciHVAC0yZc6erbaOsG5jztjotAyhOfRzJv/b7cZZGy2x8eDNCunCTnfuGPE +0KuIEbdY1bIz7ToUyOggaswRgCgUWHm8ww/rQuPKoEo2kQ8YHz+Dxb7InQaWkmNi +RszSwaHfBVARHQRczK1c8GVkWTxz7DsmmlgD19/XNfGXm9UNr6+xPLrCx9mqV05W +epjJn7s2LgGAZm1tSUog+Ah/3X86kg9F3FAwK+dZYQKBgQDc52ShyC7f96WqULv0 +o3hh8Dwetxa8jKAEJVeHHAHepFHrnk6dE4U6f3JJV1HNuEEeeFZEMgBAS4ZK1Wst +r3BTWQd9AIuN28tajKhNqYsIoHg5RuDyirTUEY/x3ssY6QiMX5giu/ZW9GawGz4A +04l7CiSZXoVgY0bEhPUK91SCXQKBgQDPyGOk5koJk/cMuppBrTUXqIGwWquChN9P +5AHS+FPsb3nYHz1OdibCBp9X4ZIjbrjfXdLIxXVll/HTcpjzUTQ+7WpCgPpMQGF7 +jP4adcCzkld2nXBq0iUeeiig6c1SRE85W4O7IganX2K6HhyAOe6wWIPBu22nz76+ +PbceLFFU3QKBgQDMc50/3vcDc0FxEKflFCcm/iGmi+4PNFglfio0ckeIuKzZVfuM +hbSZH7u3BYpAzHf4q4esNlrlJwFz4XMBJY7glVXI6+g9s1/SvrxGpNR5d4vN9zvb +P2V9oYOIaJuwwn2W7iLwgubMNAeWlqAcQ6zKo+ibyk/Hlhq5aBUjwSYGQQKBgQCE +4JrQnrEkVOq9yivR6mm0mn9tf16FVmHVHnQILeTFpDigfMHhBnAczs1iDxA89pbl +yYN9/8Dm2ne9CGFF4V1vDLdSllb7IoT01SK/WySD8gdbBK4asg8o4WhQF5TFkoez +n5Grv8PPj5F8grspSWMahVClOS6UDafm02Liuea9RQKBgDSF+qv+lSbUEmQynAVK +0urucyqYKzBgYT+3sxZ1YVltoTrKaPnjqdLV57hGUUq5gV85K1nwtUrU5duNdEkq +E1Vql5oHa7Oh27/D1R6biSgC4t9kIbnOX8KtpdOFQ9gwBqFOlvHAvAjoqfKjF5vY +2pV1OGsQaBRkBoCc/tIooxd/ +-----END PRIVATE KEY----- diff --git a/jstests/ssl/ssl_hostname_validation.js b/jstests/ssl/ssl_hostname_validation.js index f62da13d669..d52d430dd26 100644 --- a/jstests/ssl/ssl_hostname_validation.js +++ b/jstests/ssl/ssl_hostname_validation.js @@ -6,8 +6,11 @@ var CN_CERT = "jstests/libs/localhostnameCN.pem"; var SAN_CERT = "jstests/libs/localhostnameSAN.pem"; var CLIENT_CERT = "jstests/libs/client.pem"; var BAD_SAN_CERT = "jstests/libs/badSAN.pem"; +var NOSUBJ_CERT = "jstests/libs/server_no_subject.pem"; +var NOSUBJ_NOSAN_CERT = "jstests/libs/server_no_subject_no_SAN.pem"; function testCombination(certPath, allowInvalidHost, allowInvalidCert, shouldSucceed) { + jsTestLog("Testing certificate: " + JSON.stringify(arguments)); var mongod = MongoRunner.runMongod({sslMode: "requireSSL", sslPEMKeyFile: certPath, sslCAFile: CA_CERT}); @@ -75,6 +78,12 @@ testCombination(SERVER_CERT, true, true, true); // BAD_SAN_CERT has SAN=BadSAN. testCombination(BAD_SAN_CERT, false, false, false); +// NOSUBJ_CERT has SAN=localhost but empty Subject +testCombination(NOSUBJ_CERT, false, false, true); + +// NOSUBJ_NOSAN_CERT has neither Subject nor SANs +testCombination(NOSUBJ_NOSAN_CERT, false, false, false); + // Skip db hash check because replset cannot initiate. TestData.skipCheckDBHashes = true; diff --git a/jstests/ssl/x509/certs.yml b/jstests/ssl/x509/certs.yml index 2cee7f9e43f..0abe016bb0e 100644 --- a/jstests/ssl/x509/certs.yml +++ b/jstests/ssl/x509/certs.yml @@ -284,6 +284,30 @@ certs: subjectAltName: DNS: ['localhost', '127.0.0.1'] +- name: 'server_no_subject.pem' + description: Server certificate with empty Subject, but critical SAN. + explicit_subject: true + extensions: + basicConstraints: {CA: false} + subjectKeyIdentifier: hash + keyUsage: [digitalSignature, keyEncipherment] + extendedKeyUsage: [serverAuth, clientAuth] + authorityKeyIdentifier: issuer + subjectAltName: + critical: true + DNS: 'localhost' + IP: ['127.0.0.1', '::1'] + +- name: 'server_no_subject_no_SAN.pem' + description: Server certificate with empty Subject, and no SANs. + explicit_subject: true + extensions: + basicConstraints: {CA: false} + subjectKeyIdentifier: hash + keyUsage: [digitalSignature, keyEncipherment] + extendedKeyUsage: [serverAuth, clientAuth] + authorityKeyIdentifier: issuer + - name: 'server_SAN.pem' description: General purpose server certificate with good SANs. Subject: {CN: 'Kernel Client Peer Role'} diff --git a/jstests/ssl/x509/mkcert.py b/jstests/ssl/x509/mkcert.py index 150be632ac5..269120a9af2 100755 --- a/jstests/ssl/x509/mkcert.py +++ b/jstests/ssl/x509/mkcert.py @@ -109,7 +109,10 @@ def load_authority_file(issuer): def set_subject(x509, cert): """Translate a subject dict to X509Name elements.""" - if cert.get('Subject', None) is None: + if not cert.get('Subject'): + if cert.get('explicit_subject', False): + # do nothing if an empty subject is explicitly provided + return raise ValueError(cert['name'] + ' requires a Subject') if not cert.get('explicit_subject', False): @@ -675,7 +678,10 @@ def process_cert(cert): if isinstance(append_certs, str): append_certs = [append_certs] - if cert.get('Subject'): + subject = cert.get('Subject'); + explicit_empty_subject = cert.get('explicit_subject', False) and not subject; + + if subject or explicit_empty_subject: create_cert(cert) elif append_certs: # Pure composing certificate. Start with a basic preamble. diff --git a/src/mongo/util/net/ssl_manager_windows.cpp b/src/mongo/util/net/ssl_manager_windows.cpp index ce21ddb0de5..36cff38ae66 100644 --- a/src/mongo/util/net/ssl_manager_windows.cpp +++ b/src/mongo/util/net/ssl_manager_windows.cpp @@ -1541,6 +1541,10 @@ StatusWith<SSLX509Name> getCertificateSubjectName(PCCERT_CONTEXT cert) { PCERT_NAME_INFO nameInfo = reinterpret_cast<PCERT_NAME_INFO>(swBlob.getValue().data()); + if (!nameInfo->cRDN) { + return SSLX509Name(); + } + std::vector<std::vector<SSLX509Name::Entry>> entries; // Iterate in reverse order |