diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2019-11-22 17:03:28 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-11-22 17:03:28 +0000 |
commit | 8ff79f256f1e57b32edccae37dc260b342323d26 (patch) | |
tree | f083c0b59d011d1fb05b3ed2cdf46d22b0d813ba | |
parent | e19d92cb777cb87779b614c30b1ed568a6eea088 (diff) | |
download | mongo-8ff79f256f1e57b32edccae37dc260b342323d26.tar.gz |
SERVER-39574 Support intermediate certificates in PEMKeyFile on Windows
(cherry picked from commit aae362fc4d79c9f53c70228d1ba8b966feefaffb)
-rw-r--r-- | jstests/libs/intermediate-ca.pem | 53 | ||||
-rw-r--r-- | jstests/libs/server-intermediate-ca.pem | 114 | ||||
-rw-r--r-- | jstests/ssl/ssl_intermediate_ca.js | 34 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_manager_windows.cpp | 174 |
4 files changed, 262 insertions, 113 deletions
diff --git a/jstests/libs/intermediate-ca.pem b/jstests/libs/intermediate-ca.pem new file mode 100644 index 00000000000..62ee30e9106 --- /dev/null +++ b/jstests/libs/intermediate-ca.pem @@ -0,0 +1,53 @@ +# Autogenerated file, do not edit. +# Generate using jstests/ssl/x509/mkcert.py --config jstests/ssl/x509/certs.yml intermediate-ca.pem +# +# CA issues by the primary root CA, which then issues its own server cert. +-----BEGIN CERTIFICATE----- +MIIDcjCCAloCBFNvXv0wDQYJKoZIhvcNAQELBQAwdDELMAkGA1UEBhMCVVMxETAP +BgNVBAgMCE5ldyBZb3JrMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MRAwDgYDVQQK +DAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxFzAVBgNVBAMMDktlcm5lbCBUZXN0 +IENBMB4XDTE5MTAxNjE3NTc0OVoXDTM5MTAxODE3NTc0OVowdTELMAkGA1UEBhMC +VVMxETAPBgNVBAgMCE5ldyBZb3JrMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MRAw +DgYDVQQKDAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxGDAWBgNVBAMMD0ludGVy +bWVkaWF0ZSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOcrt0K/ +K8ueq9lQ9wVtA+rka82FPaHXpZkH7ii/ZJlNcDXLaJPdRb7XgAabAS3gru+Hpm/g +kAofoL7cDmGZRAbiW0I6X5Nlmjh4/0E6RxSs0urhU34m8sM3OPmAgbq7oLlFINZ6 +GbVR2RzMWhK5HPld8WApDkIVpBFbRGV7dt/LVKY34Nab9hu15WRSH3wzSHJvt8e1 +alYxaRUoE27Fk3zdHPw9Z91/XvfIThTsNXEQVOeaieyQLwoKx8tpMa/ck/mFmSkD +nH4h37ev0ZABB04iTBfLGCpUCKd5LerYIqEu4UPp9r9czbco7twp+k8875pJ3bpV +wMH0/jF68GTC8HsCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsF +AAOCAQEAaL61HT6JD19Ok2LY6b5KkZ4oRhiV73l2/82X88GcV63Bl0rN6AF+W0ut +GuHzSqcHV4qZkt9ezNoDYq41BsV4I8Cxvyaz8is956uyrzQAsVCzidZSGeq2GIfV +9y+IRISBRdzXQHrB0ni93b16MJO1KoJxZbXcb8W9ll2URp+YEnHIrhWpDcMcHN3O +mjoy1+WpHDXpNK2D3Xk5tT5pwxJZWRPB9wvPfTux5Vp07+Rkef9YjXL2ZZxt4vKu +WU0HJWfK905HpbHjwFNRlbT39WWaF8VeJ2nT6OrXTpE8tDdPoeZt5u76eaWEmsf5 +gX2ClrsSmegOKT52V+2NAlKDjQkaDg== +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDnK7dCvyvLnqvZ +UPcFbQPq5GvNhT2h16WZB+4ov2SZTXA1y2iT3UW+14AGmwEt4K7vh6Zv4JAKH6C+ +3A5hmUQG4ltCOl+TZZo4eP9BOkcUrNLq4VN+JvLDNzj5gIG6u6C5RSDWehm1Udkc +zFoSuRz5XfFgKQ5CFaQRW0Rle3bfy1SmN+DWm/YbteVkUh98M0hyb7fHtWpWMWkV +KBNuxZN83Rz8PWfdf173yE4U7DVxEFTnmonskC8KCsfLaTGv3JP5hZkpA5x+Id+3 +r9GQAQdOIkwXyxgqVAineS3q2CKhLuFD6fa/XM23KO7cKfpPPO+aSd26VcDB9P4x +evBkwvB7AgMBAAECggEAaEOwYXuGDk3fpqG8+IaF6NDjyouZE8EG4LHR+jDw97AU +tz6qSV7Y0U2zYcdRzdZ0MHcXW4iGjvpa7xqjpeOR6iT4EjPv3bRKzcPNJSda3flh +HC1LEjAQ+HmUyfvrB0UPJeEHAZWKuNxUt4d37M/vQI3di4iY9Ld8C5QFklwQbrkU +PLRJkpZTPkrE5S+pG80NA8eTz1OjeYFOsiD9INVmD59hgsN92DmzdKqH1QIDOvvF +SW/C+tX9+ou40lf4RZNvjBsfN87Bwdg342YuzOD3vtXjbAkfnofJiHOlayKeLrvw +ZyA1mW3+PfscPJ6SXea/y0sbBFYm5eihb5p+g0LwUQKBgQD8CimfkYex0uBOhFwF +7jlTSKc3dWfs/4dXEk9q8yUloo6v03YmnxkS1cF7KSWIWYCEKe++XP/lKxgRaVrL +Hm+Y5MrrQnVEgnmy7hphyEWuSsoDcTP60ATLXIycsgxsxi46410dVoiUyHRy/Vdj +zswQA4+j6crdszeT5+b2K63j2QKBgQDqzZt7UIeIYLhkh+mS8C2V2rKejn+7Uk9W +9qD+czQ3G8/H1/l5AODZKOCZpLvxi7oclJJt3WE4NQmZbg/MYLzzvZ+RlLaRRtKo +YM5/+Z6AmkKAAp9LFX9Hi3hnNgG3JJLblDSkmZnB2Ur4JyqoeiTEKzcOxHNn6U3U +FXV5QDKGcwKBgQCPHro6GWrDqKqlC3YyC+/TgjsqO+oy43uYDxa39bBPabq6z0qV +bdzQHD/NTzU38xMOeb3hDHBnUwxMvtXG59aZLLqp00hCChFPcPPcONyQt3l1cPAC +aeN/E2PpixWRIwyXdgqnIT9XtWii74eTbpfkNBF6E8WWFTHnNFWrzmvlKQKBgQCO +ynDmgieaES+xu1GZUUR3oGMFt6UIFts3CI8JjqfPZ7NpVfdZ1eXnSkukRCEjmJSa +8uNFut53nxFyZBNpd98Q311d3DFWkdpkGVMbUoNItAcC8BVNRQp9SNz070wFw1Eo +Ba4p91shHvLPjIoNoRIg1iMKcP+5zpDNDCu/jAHt7wKBgBmHFAbNwjBByIMBR3fh +VAGf/3Wow5YGXUkaYPxiiSd8pmotJWFE/47NLxvIHf6zNccuDoQA4VU9GpoLZk6p +1K+ClyU1ksSVtDKbHtzW74xnqnZZ19L404tn7FqyHW+n7YG8sqBC6IROnPnpELh0 +fxSuEbyRVRjNO6ZO3p48E0AS +-----END PRIVATE KEY----- diff --git a/jstests/libs/server-intermediate-ca.pem b/jstests/libs/server-intermediate-ca.pem index 8720a52af58..8f97a1e57a7 100644 --- a/jstests/libs/server-intermediate-ca.pem +++ b/jstests/libs/server-intermediate-ca.pem @@ -3,73 +3,73 @@ # # Server certificate signed by intermediate CA, including root CA in bundle. -----BEGIN CERTIFICATE----- -MIIDaTCCAlECBAGwTLYwDQYJKoZIhvcNAQELBQAwdTELMAkGA1UEBhMCVVMxETAP +MIIDaTCCAlECBCLMKCQwDQYJKoZIhvcNAQELBQAwdTELMAkGA1UEBhMCVVMxETAP BgNVBAgMCE5ldyBZb3JrMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MRAwDgYDVQQK DAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxGDAWBgNVBAMMD0ludGVybWVkaWF0 -ZSBDQTAeFw0xOTA5MjUyMzI3NDFaFw0zOTA5MjcyMzI3NDFaMH0xCzAJBgNVBAYT +ZSBDQTAeFw0xOTEwMTYxNzU3NDlaFw0zOTEwMTgxNzU3NDlaMH0xCzAJBgNVBAYT AlVTMREwDwYDVQQIDAhOZXcgWW9yazEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTEQ MA4GA1UECgwHTW9uZ29EQjEPMA0GA1UECwwGS2VybmVsMSAwHgYDVQQDDBdTZXJ2 ZXIgVmlhIEludGVybWVkaWF0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBANDVywmF9rAMJ1npJlALHpqAiufCBvE0zoBgUPJOPE0zTxhWQ4vWhnfQjupw -PAUGgTeUiJSsmSDPLurTi8qO05hs5BNZxEBXMt5yK2XMOBEDrZkEnJN4fXdtrhZw -ky2CMWEyAoKIqpS4JIqO2zmvyzbPWuDat+qlbKGq8trowukN/8vG3IjlATpDQns/ -8nrgogcx+3fZ6L75LgMCh4Imb+fZtkgehdFlOuQk/9KD7dqDzzMZ6IKeqktXNeY/ -zzrdot2GUtsOV6or8UDK0GfjUOXZWKDGyiYeD5GLVfUp0NuJEsjxq1DUZTdtO7Gv -cMCHrnygdAXjTQ3Wi+IKWNEWqC0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAiiNz -BkbVyBN9hjEvlKQoXMAIv8onlzrNO+CCtMMGW7O4TOc/FEN1lFVvjsWxXW6K4vQ7 -IeCzxG8tR43h5kpIhtExLLHCwxiX3+zhtmTSBBpgRGynVLSxo/fOXr5ngdqHIv2f -qK9atn4eL/hH6DyruoKf8lR7LodX92rYC907HrDcZSFi9el7WPw/Ut8U6GCn+E8/ -2sT21wuYn11UN5gKRLDv/yACe/7hYmxrI2zvfXNuYi/Xg4y0EGS4+jZhQ6db++2C -eulQ42LNkcQ1SVYeyKzouGB5ma6eGxHufLXSWAGJuLAYQW0VwKjBVD+lsXs1x+tw -1n9SA1x7Enyeas7w7g== +ggEBAKCj95jJi63dCJDKyTWQAJwgLtvqwPmIvBMbYMcmrolP3tYolwkkh6c0RJdP +UTy4gJaLZ9b9B8GuiGFatG+ZzEqCUh6AlG1lGJwdyqyP2eotpzkZJhwLGFc81DUt +7WKhZjHikgXcAd3VMCXsjv7/axvBnc459SpsCW5heOiJ3Ap8OJIrTuD4GAWW5cfW +GYa1v07hqXZ7SEloRE5Hm5bItnZA9+A5QNCj2a2PqK3TlrtCnDP125iYHc4W/+NO +1V9LPKpDffdJ7slhrX69k9oV8HTQBgu7lRHKQlprW64pg6EMsw/5hpGjpZkyG9J9 +L1FYrXqsagA1E5j87JQH+SJDOEUCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAPRu7 +YtgaGPx4O2IfvYoK+BsiD/55WylDp/0zxf/xipvuoPRcMgX1ORoNuQTPfeIMxlZS +UAIRHQSjOZQkH0WL2dglqaoBhTXO6c0PUuWOUsDDwnZE8lj26Jkka6PC8d8t7gjt +w/k2IRnhcklKOu6pNlcYi+/WGcWphmkjMRWeka0vqXab/bxF1sdeHD9bMY59QOwI +FT0JCG8Wn0LSi6V/Ip35JV3CryBP1Jual2aCXIXEKm3m+P4NboRQTZ7zqIcJoA8S +i2GkuHCPOhhQP2isiRRBILujcJxnRYrR7qNIqvMrmPx3va8fMrHKtWAx+bfo/EIJ +hlU1Eyls7Xv83x3vaA== -----END CERTIFICATE----- -----BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDQ1csJhfawDCdZ -6SZQCx6agIrnwgbxNM6AYFDyTjxNM08YVkOL1oZ30I7qcDwFBoE3lIiUrJkgzy7q -04vKjtOYbOQTWcRAVzLecitlzDgRA62ZBJyTeH13ba4WcJMtgjFhMgKCiKqUuCSK -jts5r8s2z1rg2rfqpWyhqvLa6MLpDf/LxtyI5QE6Q0J7P/J64KIHMft32ei++S4D -AoeCJm/n2bZIHoXRZTrkJP/Sg+3ag88zGeiCnqpLVzXmP8863aLdhlLbDleqK/FA -ytBn41Dl2VigxsomHg+Ri1X1KdDbiRLI8atQ1GU3bTuxr3DAh658oHQF400N1ovi -CljRFqgtAgMBAAECggEAD8rbG9FBonaI00fKWes9WTm3R2do1vzDUPn3pRs9fCkR -Jin/2adTa+QdqqTqJQck5msZGQUkX1LLnX5558t9PN2fMcdsC+GMOz4vAfe7la3N -hvDOVmiaNFna/F9vAdYCnfMGNZDYNX7nZIMBGQ+uMmrj2HUxy1DPMjqXOu63LqB5 -Tgl61pQ5srqP7rVBEaek5GCKWd6lucMrGSTBqWfmBSH+6cME9KOFHBUWVVjicbmg -0L1WuYz4fh4SDdld7375gEC+zGnfvN0XQvLcv5yff6pwZtneMaPcfw/kjFUiZGoa -j2Q9nsk6ip/05/ycEkynhMYkrhkt7oOGK7LqC6oSEQKBgQD6nZkiAyY6OKvHUyAs -/mBdQwnhgAfyrneTnFEeh9L33gMfALyhm8apckcb0js9RO7Srj+Xdrg0wVb1A6M1 -OmVboyk6bD7OkJsv7MOn8BPK//6+QVORagiKYRhClltSuZYJaa1cC24EPdJ64Zcy -Tb02xeluG3LThUUfbZ2U7Yb6TwKBgQDVUmZL+ohsJfFt3hfuc/4slz8aDNf5WWV1 -Zn5v5CMmXvbSLXSNp3EFlbRxM8W0YBBpspxb2RZ+4k0bSOrrxzCHu5c0RDZscfSL -mv6zzrnfwwq92DRbDwnW2+wskO2NIsAODA/GvyhTI6AmQ+3iWl9YcMrIiaVeEa/3 -wW/7ISCiwwKBgDtoBjegxXwBmP6LvtHLjq4syPfSMJAfOSsdX8E78w9caiL8OrqY -QXRDKYX3xKEWaQI52csekjW3KtSzgwmICSS6vXgi1pSChLbMieiSKS7ylcElnRiY -KOQcdfK6z3UBlwYuLbDm6LJKsUz9kqiS8uo76cR27zYinisAAd2enGNTAoGBAJsA -mJw0mtQabecrLbByUAoOjCddlcD1GCfKJa0f0/qZnjbyGHKlbBZmxQpMWCfMdaCX -y81hXFsuDGD7BtfzkGvP/vpXZkQ+OTcHlHMKjzzr9+4iH0jbEIcyndV0KWgYC/0o -/n2ngKGIjWHAkiWbDRSyQGaeva4wo/AeekO7un8JAoGBAMadYGAhQQhcvG5AYQYl -6kN/xE7qjL6fewxd7EteBvPqzeL6grwAKAjOOjFA8OvAzwOxx8r024ICo49SYTmy -OUO6bGWRzLvzRSWZKnN7ey7ZM4Z2avrG8gys9FUQOajPmIlFItulVEyG9GbKvMum -njdOAl9FqeGcVp2CuM+bI+w9 +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCgo/eYyYut3QiQ +ysk1kACcIC7b6sD5iLwTG2DHJq6JT97WKJcJJIenNESXT1E8uICWi2fW/QfBrohh +WrRvmcxKglIegJRtZRicHcqsj9nqLac5GSYcCxhXPNQ1Le1ioWYx4pIF3AHd1TAl +7I7+/2sbwZ3OOfUqbAluYXjoidwKfDiSK07g+BgFluXH1hmGtb9O4al2e0hJaERO +R5uWyLZ2QPfgOUDQo9mtj6it05a7Qpwz9duYmB3OFv/jTtVfSzyqQ333Se7JYa1+ +vZPaFfB00AYLu5URykJaa1uuKYOhDLMP+YaRo6WZMhvSfS9RWK16rGoANROY/OyU +B/kiQzhFAgMBAAECggEAYNydpj4ZADwgNxZfnvF2vK1XM/noZE6DgU3n3A3B/j/v +0NhmwfeJ6FNG7KnCBUgHGT9z3Jlz/OBdkb5cwFJPcboFBClp1lC4NyJrnAOdVWwz +weUdKpmyEqA2IN7RncBOW9QPUoMniPhMcQGj87RVhEYJ/ljKMMs2IJ2bhzPhP1xV +MK/NJ6cT680MwZTzWWIPYT30Pv6IDm5INjb+AG4PuzDXTx28GsCw2z9RnlH8aSdu +9qSNEoh4oXef4ny2niKa+fwRgTrkUYyljML34301dx6MclsMz0k9SprGrB2dPAxg +IV3pRO3rqS6oEZKjyyXHPV45Q/AAm3tsP5aZCJm9fQKBgQDO6Qj5UpJT1PZcpTLW +UY1l9N9GWDlRCCpprQYKwOWK6H9Pb5ptBYzGrIjC9YmX9hYjL7wOiznSsCO4zv8d +1AR56A3APzD2iQQTyRkY9lr0CbtOSeYyg6MHQOVY8T8E/gw5M6SakLeB9ZwOLjxl +fwu7gKAYmZi+h11R7f5EP3HZdwKBgQDGwK0RAC+fxtGFOY9CGqwG5rom3VPvpKd9 +gjlekXbGguA2Z21y6IdMjpTcrbnCX3DRNedpq1LH0r4xW2zrjV4P7g3j7qeSQwqW +exHLvcfEkUAjPpaE64sC3qYgwJSwNdVWG+ikBmvT4oobFsOZzL6563Md54Tlo+bN +MQ4dPhCrIwKBgFR4OGyotAo7X9RUsNtj8cjU3i32qHeXUNFRjKzpMQyze/3u/ulR +IbaeCzskSGbcVQ9KVojNd+62b+7ruqTvwGAQR0Tbx15uc1ase22AbYNBUdFVRAAN +U4oLiVX1LxgXqt/TYHilafVJUstLPubkpeKHUVSZqAzocEWZVnuANzdjAoGAFvUW +iIou9hOvC+Z0J7yQ9lMcWXTjRyELv7GVEtlWkON5Jo+X0tgNGMi3ZS4j8NG5ZFEH +o+sIKtCq62SWFjdEEC79J8DfVkOsK2mXyqLnOktUzz1hgYT7j59MLShRhHETbVjX +7GpZdiYKscpVWaSOu0b5CxE9BpGCDV2HNdV/c2UCgYEArnS54agkV1qQ6AbMHdkD +qAiDqOosDDzxgnEz422r5S9CGZ4n8uu9PGhb8NtlLxxxfKnArFGOiHmV0aPULUNp +tX+vq4JC+1gyStUdwYkrhN48eG1KUFiAqcfEFxBgvdtpKxeOd+O5SKD/ceqJO7+3 +Z826BiCbw4nJAFNHmbNr6iw= -----END PRIVATE KEY----- -# Certificate from ca.pem +# Certificate from intermediate-ca.pem -----BEGIN CERTIFICATE----- -MIIDdDCCAlwCBBmRIxIwDQYJKoZIhvcNAQELBQAwdDELMAkGA1UEBhMCVVMxETAP +MIIDcjCCAloCBFNvXv0wDQYJKoZIhvcNAQELBQAwdDELMAkGA1UEBhMCVVMxETAP BgNVBAgMCE5ldyBZb3JrMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MRAwDgYDVQQK DAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxFzAVBgNVBAMMDktlcm5lbCBUZXN0 -IENBMB4XDTE5MDkyNTIzMjczOVoXDTM5MDkyNzIzMjczOVowdDELMAkGA1UEBhMC +IENBMB4XDTE5MTAxNjE3NTc0OVoXDTM5MTAxODE3NTc0OVowdTELMAkGA1UEBhMC VVMxETAPBgNVBAgMCE5ldyBZb3JrMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MRAw -DgYDVQQKDAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxFzAVBgNVBAMMDktlcm5l -bCBUZXN0IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAupVkx8+n -AqzsANKwNPeCYlf2q0WgF4kSUMNJdpmMelrr7hh7EOnAU0hTAQx9BKTEbExeCzH6 -OArFNGjewjWVXwaOpCjK8FMvK6/lGVEpmoHNF9XuiQVmaQ4bJD6rC73YjpgNIPeL -5PyoFLEZv+X2cRBPpTcSRcf87tk8HL7v0eyk1JBhkeKK68SYdWwZlHaa1jqwmliW -WvVMkHVH3lx0VOgQwWtOgs0K1zpcZ0sH5MGpYRQOiidIRZj3PkKeTPQe2D6VQQtv -2yDs9dWfCxJJP9QiWclL2rF/xqlFSNEIfNZpZhk6I1DHQpA2uyJfzRH62pFasJuB -CVh5Tr0EDoVreQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB -CwUAA4IBAQARdNCYYWxi2fyhJwzGHwIT261d/pTlOSYLlm84c72aEneFUnfp8/H5 -JjuFbnhiX+5+h3M7eDQhra9s+H3vKr7o38EIVf5OKXvpNLwv1UUmomBvKqccioYh -bxrfwCzfBRuUmW05kcAVn8iKovqyxL7npEZbckwtT+BqZ4kOL4Uzre+S1HMx0zOu -xulSYA/sBoJ2BB93ZIAqB+f/+InS9yggzyhhaQqS7QEl1L4nZE4Oy0jKcxdCzysm -TqiyH+OI5SVRTfXh4XvHmdWBBaQyaTmQzXYUxUi7jg1jEAiebCGrEJv9plwq4KfC -cze9NLBjaXR3GzonT8kICyVT/0UvhuJg +DgYDVQQKDAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxGDAWBgNVBAMMD0ludGVy +bWVkaWF0ZSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOcrt0K/ +K8ueq9lQ9wVtA+rka82FPaHXpZkH7ii/ZJlNcDXLaJPdRb7XgAabAS3gru+Hpm/g +kAofoL7cDmGZRAbiW0I6X5Nlmjh4/0E6RxSs0urhU34m8sM3OPmAgbq7oLlFINZ6 +GbVR2RzMWhK5HPld8WApDkIVpBFbRGV7dt/LVKY34Nab9hu15WRSH3wzSHJvt8e1 +alYxaRUoE27Fk3zdHPw9Z91/XvfIThTsNXEQVOeaieyQLwoKx8tpMa/ck/mFmSkD +nH4h37ev0ZABB04iTBfLGCpUCKd5LerYIqEu4UPp9r9czbco7twp+k8875pJ3bpV +wMH0/jF68GTC8HsCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsF +AAOCAQEAaL61HT6JD19Ok2LY6b5KkZ4oRhiV73l2/82X88GcV63Bl0rN6AF+W0ut +GuHzSqcHV4qZkt9ezNoDYq41BsV4I8Cxvyaz8is956uyrzQAsVCzidZSGeq2GIfV +9y+IRISBRdzXQHrB0ni93b16MJO1KoJxZbXcb8W9ll2URp+YEnHIrhWpDcMcHN3O +mjoy1+WpHDXpNK2D3Xk5tT5pwxJZWRPB9wvPfTux5Vp07+Rkef9YjXL2ZZxt4vKu +WU0HJWfK905HpbHjwFNRlbT39WWaF8VeJ2nT6OrXTpE8tDdPoeZt5u76eaWEmsf5 +gX2ClrsSmegOKT52V+2NAlKDjQkaDg== -----END CERTIFICATE----- diff --git a/jstests/ssl/ssl_intermediate_ca.js b/jstests/ssl/ssl_intermediate_ca.js index 887127d6a73..048bdf782ec 100644 --- a/jstests/ssl/ssl_intermediate_ca.js +++ b/jstests/ssl/ssl_intermediate_ca.js @@ -6,12 +6,6 @@ load('jstests/ssl/libs/ssl_helpers.js'); -if (determineSSLProvider() === 'windows') { - // FIXME: SERVER-39574 - print("Skipping test with windows SChannel pending SERVER-39574"); - return; -} - // server-intermediate-ca was signed by ca.pem, not trusted-ca.pem const VALID_CA = 'jstests/libs/ca.pem'; const INVALID_CA = 'jstests/libs/trusted-ca.pem'; @@ -34,4 +28,32 @@ runTest(VALID_CA, VALID_CA); // Alternate CA mode, only the inbound CA is valid. runTest(VALID_CA, INVALID_CA); + +// Validate we can make a connection from the shell with the intermediate certs +{ + const mongod = MongoRunner.runMongod({ + sslMode: 'requireSSL', + sslAllowConnectionsWithoutCertificates: '', + sslPEMKeyFile: 'jstests/libs/server.pem', + sslCAFile: VALID_CA, + }); + assert(mongod); + assert.eq(mongod.getDB('admin').system.users.find({}).toArray(), []); + + const smoke = runMongoProgram("mongo", + "--host", + "localhost", + "--port", + mongod.port, + "--ssl", + "--sslCAFile", + VALID_CA, + "--sslPEMKeyFile", + "jstests/libs/server-intermediate-ca.pem", + "--eval", + "1;"); + assert.eq(smoke, 0, "Could not connect with intermediate certificate"); + + MongoRunner.stopMongod(mongod); +} })(); diff --git a/src/mongo/util/net/ssl_manager_windows.cpp b/src/mongo/util/net/ssl_manager_windows.cpp index 36e552c6e17..65a72ce2573 100644 --- a/src/mongo/util/net/ssl_manager_windows.cpp +++ b/src/mongo/util/net/ssl_manager_windows.cpp @@ -685,6 +685,73 @@ StatusWith<std::vector<BYTE>> decodeObject(const char* structType, return std::move(binaryBlobBuf); } +StatusWith<std::vector<UniqueCertificate>> readCAPEMBuffer(StringData buffer) { + std::vector<UniqueCertificate> certs; + + // Search the buffer for the various strings that make up a PEM file + size_t pos = 0; + bool found_one = false; + + while (pos < buffer.size()) { + auto swBlob = findPEMBlob(buffer, "CERTIFICATE"_sd, pos, pos != 0); + + // We expect to find at least one certificate + if (!swBlob.isOK()) { + if (found_one) { + return Status::OK(); + } + + return swBlob.getStatus(); + } + + found_one = true; + + auto blobBuf = swBlob.getValue(); + + if (blobBuf.empty()) { + return {std::move(certs)}; + } + + pos = (blobBuf.rawData() + blobBuf.size()) - buffer.rawData(); + + auto swCert = decodePEMBlob(blobBuf); + if (!swCert.isOK()) { + return swCert.getStatus(); + } + + auto certBuf = swCert.getValue(); + + PCCERT_CONTEXT cert = + CertCreateCertificateContext(X509_ASN_ENCODING, certBuf.data(), certBuf.size()); + if (cert == NULL) { + DWORD gle = GetLastError(); + return Status(ErrorCodes::InvalidSSLConfiguration, + str::stream() << "CertCreateCertificateContext failed to decode cert: " + << errnoWithDescription(gle)); + } + + certs.emplace_back(cert); + } + + return {std::move(certs)}; +} + +Status addCertificatesToStore(HCERTSTORE certStore, std::vector<UniqueCertificate>& certificates) { + for (auto& cert : certificates) { + BOOL ret = + CertAddCertificateContextToStore(certStore, cert.get(), CERT_STORE_ADD_NEW, NULL); + + if (!ret) { + DWORD gle = GetLastError(); + return Status(ErrorCodes::InvalidSSLConfiguration, + str::stream() << "CertAddCertificateContextToStore Failed " + << errnoWithDescription(gle)); + } + } + + return Status::OK(); +} + // Read a Certificate PEM file with a private key from disk StatusWith<UniqueCertificateWithPrivateKey> readCertPEMFile(StringData fileName, StringData password) { @@ -715,10 +782,18 @@ StatusWith<UniqueCertificateWithPrivateKey> readCertPEMFile(StringData fileName, // file. auto secondPublicKeyBlobPosition = buf.find("CERTIFICATE", (publicKeyBlob.rawData() + publicKeyBlob.size()) - buf.data()); + std::vector<UniqueCertificate> extraCertificates; if (secondPublicKeyBlobPosition != std::string::npos) { - return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "Certificate PEM files should only have one certificate, " - "intermediate CA certificates belong in the CA file."); + // Read in extra certificates + StringData extraCertificatesBuffer = + StringData(buf).substr(secondPublicKeyBlobPosition - ("-----BEGIN "_sd).size()); + + auto swExtraCertificates = readCAPEMBuffer(extraCertificatesBuffer); + if (!swExtraCertificates.isOK()) { + return swExtraCertificates.getStatus(); + } + + extraCertificates = std::move(swExtraCertificates.getValue()); } auto swCert = decodePEMBlob(publicKeyBlob); @@ -738,6 +813,32 @@ StatusWith<UniqueCertificateWithPrivateKey> readCertPEMFile(StringData fileName, << errnoWithDescription(gle)); } + UniqueCertificate tempCertHolder(cert); + + HCERTSTORE store = CertOpenStore( + CERT_STORE_PROV_MEMORY, 0, NULL, CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, NULL); + if (store == NULL) { + DWORD gle = GetLastError(); + return Status(ErrorCodes::InvalidSSLConfiguration, + str::stream() << "CertOpenStore failed to create memory store: " + << errnoWithDescription(gle)); + } + + UniqueCertStore storeHolder(store); + + // Add the newly created certificate to the memory store, this makes a copy + BOOL ret = CertAddCertificateContextToStore(store, cert, CERT_STORE_ADD_NEW, NULL); + + if (!ret) { + DWORD gle = GetLastError(); + return Status(ErrorCodes::InvalidSSLConfiguration, + str::stream() << "CertAddCertificateContextToStore Memory Failed " + << errnoWithDescription(gle)); + } + + // Get the certificate from the store so we attach the private key to the cert in the store + cert = CertEnumCertificatesInStore(store, NULL); + UniqueCertificate certHolder(cert); std::vector<uint8_t> privateKey; @@ -807,7 +908,6 @@ StatusWith<UniqueCertificateWithPrivateKey> readCertPEMFile(StringData fileName, HCRYPTPROV hProv; std::wstring wstr; - BOOL ret; // Create the right Crypto context depending on whether we running in a server or outside. // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa375195(v=vs.85).aspx @@ -902,7 +1002,10 @@ StatusWith<UniqueCertificateWithPrivateKey> readCertPEMFile(StringData fileName, << errnoWithDescription(gle)); } - return UniqueCertificateWithPrivateKey(std::move(certHolder), std::move(cryptProvider)); + // Add the extra certificates into the same certificate store as the certificate + addCertificatesToStore(certHolder->hCertStore, extraCertificates); + + return UniqueCertificateWithPrivateKey{std::move(certHolder), std::move(cryptProvider)}; } Status readCAPEMFile(HCERTSTORE certStore, StringData fileName) { @@ -914,53 +1017,15 @@ Status readCAPEMFile(HCERTSTORE certStore, StringData fileName) { std::string buf = std::move(swBuf.getValue()); - // Search the buffer for the various strings that make up a PEM file - size_t pos = 0; - - while (pos < buf.size()) { - auto swBlob = findPEMBlob(buf, "CERTIFICATE"_sd, pos, pos != 0); - - // We expect to find at least one certificate - if (!swBlob.isOK()) { - return swBlob.getStatus(); - } - - auto blobBuf = swBlob.getValue(); - - if (blobBuf.empty()) { - return Status::OK(); - } - - pos = (blobBuf.rawData() + blobBuf.size()) - buf.data(); - - auto swCert = decodePEMBlob(blobBuf); - if (!swCert.isOK()) { - return swCert.getStatus(); - } - - auto certBuf = swCert.getValue(); - - PCCERT_CONTEXT cert = - CertCreateCertificateContext(X509_ASN_ENCODING, certBuf.data(), certBuf.size()); - if (cert == NULL) { - DWORD gle = GetLastError(); - return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "CertCreateCertificateContext failed to decode cert: " - << errnoWithDescription(gle)); - } - UniqueCertificate certHolder(cert); - - BOOL ret = CertAddCertificateContextToStore(certStore, cert, CERT_STORE_ADD_NEW, NULL); - if (!ret) { - DWORD gle = GetLastError(); - return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "CertAddCertificateContextToStore Failed " - << errnoWithDescription(gle)); - } + auto swCerts = readCAPEMBuffer(buf); + if (!swCerts.isOK()) { + return swCerts.getStatus(); } - return Status::OK(); + auto certs = std::move(swCerts.getValue()); + + return addCertificatesToStore(certStore, certs); } Status readCRLPEMFile(HCERTSTORE certStore, StringData fileName) { @@ -974,15 +1039,22 @@ Status readCRLPEMFile(HCERTSTORE certStore, StringData fileName) { // Search the buffer for the various strings that make up a PEM file size_t pos = 0; + bool found_one = false; while (pos < buf.size()) { auto swBlob = findPEMBlob(buf, "X509 CRL"_sd, pos, pos != 0); // We expect to find at least one CRL if (!swBlob.isOK()) { + if (found_one) { + return Status::OK(); + } + return swBlob.getStatus(); } + found_one = true; + auto blobBuf = swBlob.getValue(); if (blobBuf.empty()) { @@ -1294,6 +1366,8 @@ Status SSLManagerWindows::initSSLContext(SCHANNEL_CRED* cred, | SCH_CRED_REVOCATION_CHECK_CHAIN // Check certificate revocation | SCH_CRED_NO_SERVERNAME_CHECK // Do not validate server name against cert | SCH_CRED_NO_DEFAULT_CREDS // No Default Certificate + | SCH_CRED_MEMORY_STORE_CERT // Read intermediate certificates from memory store + // associated with client certificate. | SCH_CRED_MANUAL_CRED_VALIDATION; // Validate Certificate Manually } @@ -1622,7 +1696,7 @@ Status validatePeerCertificate(const std::string& remoteHost, BOOL ret = CertGetCertificateChain(certChainEngine, cert, NULL, - NULL, + cert->hCertStore, &certChainPara, CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, NULL, |