diff options
-rw-r--r-- | SConstruct | 1 | ||||
-rw-r--r-- | jstests/libs/trusted-ca.pem | 22 | ||||
-rw-r--r-- | jstests/libs/trusted-client.pem | 49 | ||||
-rw-r--r-- | jstests/libs/trusted-server.pem | 49 | ||||
-rw-r--r-- | jstests/ssl/ssl_with_system_ca.js | 39 | ||||
-rw-r--r-- | src/mongo/shell/shell_options.cpp | 10 | ||||
-rw-r--r-- | src/mongo/shell/shell_options.h | 2 | ||||
-rw-r--r-- | src/mongo/shell/shell_options_init.cpp | 4 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_manager.cpp | 163 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_manager.h | 10 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_options.cpp | 13 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_options.h | 6 |
12 files changed, 58 insertions, 310 deletions
diff --git a/SConstruct b/SConstruct index 571ece51030..821b16a1470 100644 --- a/SConstruct +++ b/SConstruct @@ -1384,7 +1384,6 @@ elif env.TargetOSIs('windows'): 'Psapi.lib', 'advapi32.lib', 'bcrypt.lib', - 'crypt32.lib', 'kernel32.lib', 'shell32.lib', 'version.lib', diff --git a/jstests/libs/trusted-ca.pem b/jstests/libs/trusted-ca.pem deleted file mode 100644 index 2a0e139e184..00000000000 --- a/jstests/libs/trusted-ca.pem +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE-----
-MIIDpjCCAo6gAwIBAgIDAghHMA0GCSqGSIb3DQEBBQUAMHwxHzAdBgNVBAMTFlRy
-dXN0ZWQgS2VybmVsIFRlc3QgQ0ExDzANBgNVBAsTBktlcm5lbDEQMA4GA1UEChMH
-TW9uZ29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlv
-cmsxCzAJBgNVBAYTAlVTMB4XDTE2MDMzMTE0NTY1NVoXDTM2MDMzMTE0NTY1NVow
-fDEfMB0GA1UEAxMWVHJ1c3RlZCBLZXJuZWwgVGVzdCBDQTEPMA0GA1UECxMGS2Vy
-bmVsMRAwDgYDVQQKEwdNb25nb0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREw
-DwYDVQQIEwhOZXcgWW9yazELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUA
-A4IBDwAwggEKAoIBAQCePFHZTydC96SlSHSyu73vw//ddaE33kPllBB9DP2L7yRF
-6D/blFmno9fSM+Dfg64VfGV+0pCXPIZbpH29nzJu0DkvHzKiWK7P1zUj8rAHaX++
-d6k0yeTLFM9v+7YE9rHoANVn22aOyDvTgAyMmA0CLn+SmUy6WObwMIf9cZn97Znd
-lww7IeFNyK8sWtfsVN4yRBnjr7kKN2Qo0QmWeFa7jxVQptMJQrY8k1PcyVUOgOjQ
-ocJLbWLlm9k0/OMEQSwQHJ+d9weUbKjlZ9ExOrm4QuuA2tJhb38baTdAYw3Jui4f
-yD6iBAGD0Jkpc+3YaWv6CBmK8NEFkYJD/gn+lJ75AgMBAAGjMTAvMAwGA1UdEwQF
-MAMBAf8wHwYDVR0RBBgwFoIJbG9jYWxob3N0ggkxMjcuMC4wLjEwDQYJKoZIhvcN
-AQEFBQADggEBADYikjB6iwAUs6sglwkE4rOkeMkJdRCNwK/5LpFJTWrDjBvBQCdA
-Y5hlAVq8PfIYeh+wEuSvsEHXmx7W29X2+p4VuJ95/xBA6NLapwtzuiijRj2RBAOG
-1EGuyFQUPTL27DR3+tfayNykDclsVDNN8+l7nt56j8HojP74P5OMHtn+6HX5+mtF
-FfZMTy0mWguCsMOkZvjAskm6s4U5gEC8pYEoC0ZRbfUdyYsxZe/nrXIFguVlVPCB
-XnfB/0iG9t+VH5cUVj1LP9skXTW4kXfhQmljUuo+EVBNR6n2nfTnpoC65WeAgHV4
-V+s9mJsUv2x72KtKYypqEVT0gaJ1WIN9N1s=
------END CERTIFICATE-----
diff --git a/jstests/libs/trusted-client.pem b/jstests/libs/trusted-client.pem deleted file mode 100644 index dec32375c1b..00000000000 --- a/jstests/libs/trusted-client.pem +++ /dev/null @@ -1,49 +0,0 @@ ------BEGIN CERTIFICATE-----
-MIIDnTCCAoWgAwIBAgIDA1clMA0GCSqGSIb3DQEBBQUAMHwxHzAdBgNVBAMTFlRy
-dXN0ZWQgS2VybmVsIFRlc3QgQ0ExDzANBgNVBAsTBktlcm5lbDEQMA4GA1UEChMH
-TW9uZ29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlv
-cmsxCzAJBgNVBAYTAlVTMB4XDTE2MDMzMTE2MDY0OVoXDTM2MDMzMTE2MDY0OVow
-gYAxIzAhBgNVBAMTGlRydXN0ZWQgS2VybmVsIFRlc3QgQ2xpZW50MQ8wDQYDVQQL
-EwZLZXJuZWwxEDAOBgNVBAoTB01vbmdvREIxFjAUBgNVBAcTDU5ldyBZb3JrIENp
-dHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcN
-AQEBBQADggEPADCCAQoCggEBAKI9cGBnH5wcthvFT1FdfQTw1EvOgtfBHVEMRFZH
-bupMnAqP69id0bf7SdBWzx4A1f1ws1RkeL5ot2u5T9NwsFzGvRBQ5onFtDnC3eKB
-OwapCk2B82mlx4xZBjewg+NbxoRJBUWGqB0LykaVUHxM6BGgwExNAyXQ9syPSyNZ
-NIr+zDrLdTfjKklmDkv9jSCB/T3t80kQPY+04u98buUe7wGM0WQFbVNoYrSkZ6Ja
-O+G8bpXP4hXIXsxOHucjBeJc1KR+lxEMw3wInZ2KjjMv7HsFIIOQg5pkMDXibSU6
-cNUZTA2MrzZ+t7TeAQyOTzfGlaatfvJYxU7v4u0W5jxeV60CAwEAAaMjMCEwHwYD
-VR0RBBgwFoIJbG9jYWxob3N0ggkxMjcuMC4wLjEwDQYJKoZIhvcNAQEFBQADggEB
-AHI6Rfq/UqAoPxiz5bqby2FnGOrskotgXhn1JkZLGCfllx5WgMuLnu1bvjoym567
-HySqAXQOqEWm6XRU7SVOA+69e4OLWX+HSKjFRuG5Ip67UpihZMgyLKuGRBwfnbXj
-14o+xbWjXCgVZEI7vzT7q/7/W1mXj680fHs93Zog561Id4Tf3DYkOoMawSfeF4iu
-8hcYjlJYjFb3ZvM1wokicmEwtY0+YbBGVo8xh5jYdfCLzYLxc3CpP5eXJtMvGE/x
-RnyiY3f7hkUZMibnREPS6kpQVEh36DT21C0OB8s7TcMU7yMKgVdqL1udmEkiKXTj
-H7v/s+7d54O0tr5+IysCAoA=
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAoj1wYGcfnBy2G8VPUV19BPDUS86C18EdUQxEVkdu6kycCo/r
-2J3Rt/tJ0FbPHgDV/XCzVGR4vmi3a7lP03CwXMa9EFDmicW0OcLd4oE7BqkKTYHz
-aaXHjFkGN7CD41vGhEkFRYaoHQvKRpVQfEzoEaDATE0DJdD2zI9LI1k0iv7MOst1
-N+MqSWYOS/2NIIH9Pe3zSRA9j7Ti73xu5R7vAYzRZAVtU2hitKRnolo74bxulc/i
-FchezE4e5yMF4lzUpH6XEQzDfAidnYqOMy/sewUgg5CDmmQwNeJtJTpw1RlMDYyv
-Nn63tN4BDI5PN8aVpq1+8ljFTu/i7RbmPF5XrQIDAQABAoIBAGg9iYKnP4wSdn+J
-WtkwdC9EfWLnoPH3RlrYwt+crgskhe3TYvmfDSxk7JxL6m+god1hGBfVJi9RIOi5
-/Cwib25s0vU0xasnuBCUv/PUjJRO8Cu0nyz2Myxd1rzZUSQ3x2kfcZ+mUUW4WZLY
-RQpYb5ND8coUgT0+8hOkzeY8XqIe5c4VrX16mA+uoIMsr4QHxe0pl59oY57V3Der
-+gsaGuWZ5hDvfuoCOx03Cuc1pTx0T8ZHdliu/xe+np3ETFdQ/1cyJMAJW3w15qKt
-L6AfkeRaMAgqxs2zU1rgPdJddRS7MaSJnpDtMjeyJpeNCMDJ/h3ihgSM1SM1QCtY
-tcnWdIECgYEA1/SVGV9McAvtVtQA1D7kPEo0ifCG8frUfGy2yK9aasFHhLS3JXXY
-4R0Fy/pOwdKNtnN3ZKd0Y0wcmlwPepg2HKlUFJdjqEKZctMzOscy3n08F4AV2rLc
-48q2XLLIQNN/JuqcaeRgQByvP6YL0YuqqsAPiRhTeYgJxp4c+JgbmDUCgYEAwFL7
-jzYwmud3HEgrfpXxDoWpemlKqCqe0cUix0OtR8XfCukZ5lbnC7Mu/FtqBitVdQYd
-2r1nRK66fTJejblNd1E4TG0sIwucI5B24I7XeG78r2kECnFT+vBE8BA6c/y8nTjz
-grWVMeR3n7WFxaTL/VW/kapW2YddWPq1Jh4q4JkCgYB2QBk8kXBbkkxd1Sy3C9ES
-KlfmiGx8KCseDrFv5oUOG9O7mPEIdCVT7v5zmRZzD4ZFt6hS11bl4JFw/KQFLz/C
-Jf5CYDtTsVQxCfDtaJI0PkMfYyWUYYiOuztsOwFobeccOi931HPX510W7yddkKrd
-YNmg6k8bJyCjP4UBotjJWQKBgElP2KDQ0VpbHWZkhF/unEMi5GXLOTA9fukLsqQu
-wiD35nvsO3k4az5kgWalGhdb8Wl4eWzmgjUGPgR3bN+tYUA4b7OCci6xwEU2Tnpv
-OOeptxzOdUHdzVt8t2qjZQTNtMBh80FCIqswIgF5WpLqrO/W/f1y50Roe0bt2pu7
-KDERAoGAbhEL6OCfX6Pf5hCggb4ymm9zmAndRKHAAJ2WQ2p6v+r1vm838n6y8r7Q
-Fqc3B7NIDDYzX4oyQZepOnHNF/UPEyVyGvJ8LBDruyiuAdGakVEvSHZ+ml4LnS06
-msP5hsHh9s4ptVcaF3/mNllBys+FwEWvLewgfVPJrDBNINFvYZ8=
------END RSA PRIVATE KEY-----
diff --git a/jstests/libs/trusted-server.pem b/jstests/libs/trusted-server.pem deleted file mode 100644 index caaee422a44..00000000000 --- a/jstests/libs/trusted-server.pem +++ /dev/null @@ -1,49 +0,0 @@ ------BEGIN CERTIFICATE-----
-MIIDnTCCAoWgAwIBAgIDCWhIMA0GCSqGSIb3DQEBBQUAMHwxHzAdBgNVBAMTFlRy
-dXN0ZWQgS2VybmVsIFRlc3QgQ0ExDzANBgNVBAsTBktlcm5lbDEQMA4GA1UEChMH
-TW9uZ29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlv
-cmsxCzAJBgNVBAYTAlVTMB4XDTE2MDMzMTE2MDUyM1oXDTM2MDMzMTE2MDUyM1ow
-gYAxIzAhBgNVBAMTGlRydXN0ZWQgS2VybmVsIFRlc3QgU2VydmVyMQ8wDQYDVQQL
-EwZLZXJuZWwxEDAOBgNVBAoTB01vbmdvREIxFjAUBgNVBAcTDU5ldyBZb3JrIENp
-dHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcN
-AQEBBQADggEPADCCAQoCggEBAJwOsMO+MhWmHcSOdjFrZYjPMOt8uIqJ1pR/JI/E
-hTdUq7fXPHZNhUTzwX1JZB+QkXhnJiAf2ZQOnl7R49vudoPdOZo6bJQP8/Hy5F79
-B8Nw9xrcPuzGBRK3IpY7j9gnAOC5jvN2zh+nHoqNhPmarpKgbDeLosABiDFSHiCE
-degHziJ0Tj0AJ6GRbeHeTvv5K4lLwMzyYnpkG0cMpLvLIUwJa22Vp8PujMcmjX9W
-ASmSXJmcszYKjaRc7HB6ronIEZWy//PSXlvuk8xYaM40HkGy2gN6wV+2Z45QdDds
-NxUuu56TzJ7z7as/vYXXsIc/TSmvM02S01JWUjWeVGc1sb8CAwEAAaMjMCEwHwYD
-VR0RBBgwFoIJbG9jYWxob3N0ggkxMjcuMC4wLjEwDQYJKoZIhvcNAQEFBQADggEB
-AAKLZiQxz3NYvc04GDMRIUDfR50RMw4SuXXgGYTpPUP/akOes11+u5iKhgyKQ+ca
-TttX8mwwvNjQFN8hjBodsrWK9avMUenJBk+Y2ztzLSpKAmC7NUUM6sFB1D3yocsG
-aH5EuyH/dcAdb9z5vYurriRfd1ldmyGAqvA6lKGp1zxTAi0WWbYIZia0LyVoH98p
-x0s+amrSMvkVqIK+qV+CVqW2dNLe+kREjGxzGidCSfHZrHncuTX8/10xHUbAQW0z
-EWF6epmm+jniwgh2Zs/xe7+eY1Nzfq0ly06MVKCs1/lZ0vhAHGZ7V6yBX5zig02x
-VAHb45KqzmYGwKErO7ZFY2I=
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEpQIBAAKCAQEAnA6ww74yFaYdxI52MWtliM8w63y4ionWlH8kj8SFN1Srt9c8
-dk2FRPPBfUlkH5CReGcmIB/ZlA6eXtHj2+52g905mjpslA/z8fLkXv0Hw3D3Gtw+
-7MYFErciljuP2CcA4LmO83bOH6ceio2E+ZqukqBsN4uiwAGIMVIeIIR16AfOInRO
-PQAnoZFt4d5O+/kriUvAzPJiemQbRwyku8shTAlrbZWnw+6MxyaNf1YBKZJcmZyz
-NgqNpFzscHquicgRlbL/89JeW+6TzFhozjQeQbLaA3rBX7ZnjlB0N2w3FS67npPM
-nvPtqz+9hdewhz9NKa8zTZLTUlZSNZ5UZzWxvwIDAQABAoIBAQCQFHQY1NHy8OKM
-5aaz697bV8dns0fCCI7HnTdJUPxZYGAGJL8azmmbhp1+qbK5/cSA8GLfx+ge7PxE
-uO3x0RE0n5weC5DRhoUIPeOg22Y+iF5sOyoReqWWaOSS5bzhqOkDke4sU+TsjmQB
-MbWyqaBBmcEv60jAkumF97X++azOIm1EqTXfSu1K7gqtiL9H9T8vIYOOuTAduOsD
-el/v5QQbWb3e/NLhcmzHL6rPcR/9jCn1rJ9HAhAqm6eKZS2cAgTGLLtCUhumVliO
-bEIm2fcQ5h+BDZc5EF/SURKvUaFx/xTIQ5s1oEKN8iN+kIYzgbZ/Ds/GOo7nWVmy
-1KZswK05AoGBANBvT/vSpI7vokmph+GifjToHeinceg3pssf8mHw8xv3H0mZxBkt
-CJq6rFwKwMH8K9tQfBqp4hfVgfdAWZyKqqo1Mtecohzb9D0GLYZ6Of18pAZK/aEt
-L8ADuGYbLAFAS10z4djBSqlud82d194zSgfLP3FYRsj5Ni8w9bPuMOKVAoGBAL+r
-gd1/B+kkbO/NAprjXAFT91Wjf+YMQgM8vOMXlq7LlGeGQSb0zVZpdDtZ3ohqdu1i
-38y0G/CvBLddm8VkC3/fhfO8xW8PjdRBbF87j1k4HerAxcLOO91z+MHFMbUryOJc
-U0aAzJB3B4E491xaXTL8jZLYxmgJtc4jBcLKzmIDAoGBAKXf39w9Hx5tUE6k7vE+
-uodqLdsn3nt6Rm+iRedxtFcODEUrbKbIcu+IHYDGQe5eu5w2af1iMv7auCpHeMke
-hYEdAxAZo92poa4qy3IYtSuo1HP5m+x3pGd/znDbsOJyA0fx8QrpkHxT4F2u/srj
-MEgRlLSkFvj7cwaNRQvjQ94dAoGAA2+4wVbgtm5fwaDkVhCTeradrZxj06UOne49
-2Lh4jCO8QmrmyiMDd3QmkFXZJor6HOFz78Ce657Hr93uyAg2KJHCXg9ZXtdhjJer
-sL1poYjfCHFyWj7GVf8ZS6gUbxIc5OoQ2CfBAyoPKWLzFGXOW/apNyPJ0t2xs8Nu
-/AIU1y8CgYEAyUhyJe8XaDOjoR9D1freHY6Vt9NkofDpYfWL4+y/kGD45yCDBXj0
-LYAD89/Qog1MbPN8FGrgMu2b3dI0i+iZlWduvQRn71QepT6wiB84ivxjECSpZGoH
-2F0SM1MVAK/f4Dm9H9Kaukq2BpsN8Uhvzg2EUFg1mLJ+OBArgT524Ys=
------END RSA PRIVATE KEY-----
diff --git a/jstests/ssl/ssl_with_system_ca.js b/jstests/ssl/ssl_with_system_ca.js deleted file mode 100644 index 00eb423ee62..00000000000 --- a/jstests/ssl/ssl_with_system_ca.js +++ /dev/null @@ -1,39 +0,0 @@ -((function() { - 'use strict'; - const HOST_TYPE = getBuildInfo().buildEnvironment.target_os; - - if (HOST_TYPE == "windows") { - runProgram( - "certutil.exe", "-addstore", "-user", "-f", "CA", "jstests\\libs\\trusted-ca.pem"); - } - - var testWithCerts = function(serverPem) { - jsTest.log(`Testing with SSL certs $ { - serverPem - }`); - // allowSSL instead of requireSSL so that the non-SSL connection succeeds. - var conn = MongoRunner.runMongod( - {sslMode: 'requireSSL', sslPEMKeyFile: "jstests/libs/" + serverPem}); - - // Should not be able to authenticate with x509. - // Authenticate call will return 1 on success, 0 on error. - var argv = - ['./mongo', '--ssl', '--port', conn.port, '--eval', ('db.runCommand({buildInfo: 1})')]; - if (HOST_TYPE == "linux") { - // On Linux we override the default path to the system CA store to point to our - // "trusted" CA. On Windows, this CA will have been added to the user's trusted CA list - argv.unshift("env", "SSL_CERT_FILE=jstests/libs/trusted-ca.pem"); - } - var exitStatus = runMongoProgram.apply(null, argv); - assert.eq(exitStatus, 0, "successfully connected with SSL"); - - MongoRunner.stopMongod(conn.port); - }; - - assert.throws(function() { - testWithCerts("server.pem", "client.pem"); - }); - assert.doesNotThrow(function() { - testWithCerts("trusted-server.pem", "trusted-client.pem"); - }); -})()); diff --git a/src/mongo/shell/shell_options.cpp b/src/mongo/shell/shell_options.cpp index bef83eb90bb..5ba9bca4227 100644 --- a/src/mongo/shell/shell_options.cpp +++ b/src/mongo/shell/shell_options.cpp @@ -381,4 +381,14 @@ Status storeMongoShellOptions(const moe::Environment& params, return Status::OK(); } + +Status validateMongoShellOptions(const moe::Environment& params) { +#ifdef MONGO_CONFIG_SSL + Status ret = validateSSLMongoShellOptions(params); + if (!ret.isOK()) { + return ret; + } +#endif + return Status::OK(); +} } diff --git a/src/mongo/shell/shell_options.h b/src/mongo/shell/shell_options.h index 3451143543e..4699f3d09f4 100644 --- a/src/mongo/shell/shell_options.h +++ b/src/mongo/shell/shell_options.h @@ -90,4 +90,6 @@ bool handlePreValidationMongoShellOptions(const moe::Environment& params, const std::vector<std::string>& args); Status storeMongoShellOptions(const moe::Environment& params, const std::vector<std::string>& args); + +Status validateMongoShellOptions(const moe::Environment& params); } diff --git a/src/mongo/shell/shell_options_init.cpp b/src/mongo/shell/shell_options_init.cpp index e1374ec4691..ff6c0792ca5 100644 --- a/src/mongo/shell/shell_options_init.cpp +++ b/src/mongo/shell/shell_options_init.cpp @@ -47,6 +47,10 @@ MONGO_STARTUP_OPTIONS_VALIDATE(MongoShellOptions)(InitializerContext* context) { if (!ret.isOK()) { return ret; } + ret = validateMongoShellOptions(moe::startupOptionsParsed); + if (!ret.isOK()) { + return ret; + } return Status::OK(); } diff --git a/src/mongo/util/net/ssl_manager.cpp b/src/mongo/util/net/ssl_manager.cpp index 5bb0f0c27a3..2832a59f4d1 100644 --- a/src/mongo/util/net/ssl_manager.cpp +++ b/src/mongo/util/net/ssl_manager.cpp @@ -59,12 +59,6 @@ #ifdef MONGO_CONFIG_SSL #include <openssl/evp.h> #include <openssl/x509v3.h> - -#ifdef _WIN32 -#include <openssl/x509_vfy.h> -#include <openssl/pkcs7.h> -#include <wincrypt.h> -#endif #endif using std::endl; @@ -275,12 +269,7 @@ private: /* * Set up an SSL context for certificate validation by loading a CA */ - Status _setupCA(SSL_CTX* context, const std::string& caFile); - - /* - * Set up an SSL context for certificate validation by loading the system's CA store - */ - Status _setupSystemCA(SSL_CTX* context); + bool _setupCA(SSL_CTX* context, const std::string& caFile); /* * Import a certificate revocation list into an SSL context @@ -642,10 +631,12 @@ Status SSLManager::initSSLContext(SSL_CTX* context, } } - const auto status = - params.sslCAFile.empty() ? _setupSystemCA(context) : _setupCA(context, params.sslCAFile); - if (!status.isOK()) - return status; + if (!params.sslCAFile.empty()) { + // Set up certificate validation with a certificate authority + if (!_setupCA(context, params.sslCAFile)) { + return Status(ErrorCodes::InvalidSSLConfiguration, "Can not set up CA file."); + } + } if (!params.sslCRLFile.empty()) { if (!_setupCRL(context, params.sslCRLFile)) { @@ -788,148 +779,27 @@ bool SSLManager::_setupPEM(SSL_CTX* context, return true; } -Status SSLManager::_setupCA(SSL_CTX* context, const std::string& caFile) { +bool SSLManager::_setupCA(SSL_CTX* context, const std::string& caFile) { // Set the list of CAs sent to clients STACK_OF(X509_NAME)* certNames = SSL_load_client_CA_file(caFile.c_str()); if (certNames == NULL) { - return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "cannot read certificate authority file: " << caFile << " " - << getSSLErrorMessage(ERR_get_error())); + error() << "cannot read certificate authority file: " << caFile << " " + << getSSLErrorMessage(ERR_get_error()) << endl; + return false; } SSL_CTX_set_client_CA_list(context, certNames); // Load trusted CA if (SSL_CTX_load_verify_locations(context, caFile.c_str(), NULL) != 1) { - return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() << "cannot read certificate authority file: " << caFile << " " - << getSSLErrorMessage(ERR_get_error())); + error() << "cannot read certificate authority file: " << caFile << " " + << getSSLErrorMessage(ERR_get_error()) << endl; + return false; } - // Set SSL to require peer (client) certificate verification // if a certificate is presented SSL_CTX_set_verify(context, SSL_VERIFY_PEER, &SSLManager::verify_cb); _sslConfiguration.hasCA = true; - return Status::OK(); -} - -#ifdef _WIN32 -// This imports the certificates in a given Windows certificate store into an X509_STORE for -// openssl to use during certificate validation. -Status importCertStoreToX509_STORE(LPWSTR storeName, DWORD storeLocation, X509_STORE* verifyStore) { - HCERTSTORE systemStore = - CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, NULL, storeLocation, storeName); - if (systemStore == NULL) { - return {ErrorCodes::InvalidSSLConfiguration, - str::stream() << "error opening system CA store: " << errnoWithDescription()}; - } - auto systemStoreGuard = MakeGuard([systemStore]() { CertCloseStore(systemStore, 0); }); - - CERT_BLOB p7Data = {0, NULL}; - // We call this the first time to get the size of the PKCS7 object that will be generated - if (CertSaveStore(systemStore, - (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // Save it as X509 certs/CRLs - // encoded as PKCS7 objects - CERT_STORE_SAVE_AS_PKCS7, // Save as a PKCS7 encoded object - CERT_STORE_SAVE_TO_MEMORY, // Save cert store to memory - &p7Data, - 0) == 0) { - return {ErrorCodes::InvalidSSLConfiguration, - str::stream() << "error getting size of PKCS7 object from system CA store" - << errnoWithDescription()}; - } - - std::unique_ptr<BYTE[]> pbDataPtr(new BYTE[p7Data.cbData]); - p7Data.pbData = pbDataPtr.get(); - - // Then we call it again to actually create the PKCS7 object. - if (CertSaveStore(systemStore, - (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), // Save it as X509 certs/CRLs - // encoded as PKCS7 objects - CERT_STORE_SAVE_AS_PKCS7, // Save as a PKCS7 encoded object - CERT_STORE_SAVE_TO_MEMORY, // Save cert store to memory - &p7Data, - 0) == 0) { - return {ErrorCodes::InvalidSSLConfiguration, - str::stream() << "error getting system CA store: " << errnoWithDescription()}; - } - - auto bioDeleter = [](BIO* b) { BIO_free_all(b); }; - std::unique_ptr<BIO, decltype(bioDeleter)> p7Bio(BIO_new_mem_buf(p7Data.pbData, p7Data.cbData), - bioDeleter); - if (!p7Bio) { - return {ErrorCodes::InvalidSSLConfiguration, - "error creating BIO for loading system CA cert store"}; - } - BIO_set_close(p7Bio.get(), BIO_NOCLOSE); - - auto pkcs7Deleter = [](PKCS7* p) { PKCS7_free(p); }; - std::unique_ptr<PKCS7, decltype(pkcs7Deleter)> p7(d2i_PKCS7_bio(p7Bio.get(), NULL), - pkcs7Deleter); - if (!p7) { - return {ErrorCodes::InvalidSSLConfiguration, - "error parsing PKCS7 object from system CA cert store"}; - } - - if ((OBJ_obj2nid(p7->type) != NID_pkcs7_signed) || (p7->d.sign->cert == NULL)) { - return {ErrorCodes::InvalidSSLConfiguration, - "invalid pkcs7 object while loading system certificates"}; - } - - STACK_OF(X509)* systemCACerts = p7->d.sign->cert; - for (auto i = 0; i < sk_X509_num(systemCACerts); i++) { - if (X509_STORE_add_cert(verifyStore, sk_X509_value(systemCACerts, i)) != 1) { - const auto errCode = ERR_peek_last_error(); - if (ERR_GET_LIB(errCode) != ERR_LIB_X509 || - ERR_GET_REASON(errCode) != X509_R_CERT_ALREADY_IN_HASH_TABLE) { - return {ErrorCodes::InvalidSSLConfiguration, - str::stream() << "Error adding certificate to X509 store: " - << ERR_reason_error_string(errCode)}; - } - } - } - - STACK_OF(X509_CRL)* systemCRLs = p7->d.sign->crl; - for (auto i = 0; i < sk_X509_CRL_num(systemCRLs); i++) { - if (X509_STORE_add_crl(verifyStore, sk_X509_CRL_value(systemCRLs, i)) != 1) { - const auto errCode = ERR_peek_last_error(); - if (ERR_GET_LIB(errCode) != ERR_LIB_X509 || - ERR_GET_REASON(errCode) != X509_R_CERT_ALREADY_IN_HASH_TABLE) { - return {ErrorCodes::InvalidSSLConfiguration, - str::stream() << "Error adding CRL to X509 store: " - << ERR_reason_error_string(errCode)}; - } - } - } - - return Status::OK(); -} -#endif - -Status SSLManager::_setupSystemCA(SSL_CTX* context) { -#ifndef _WIN32 - // On non-Windows platforms, the OpenSSL libraries should have been configured with default - // locations for CA certificates. - if (SSL_CTX_set_default_verify_paths(context) != 1) { - return { - ErrorCodes::InvalidSSLConfiguration, - str::stream() << "error loading system CA certificates " - << "(default certificate file: " << X509_get_default_cert_file() << ", " - << "default certificate path: " << X509_get_default_cert_dir() << ")"}; - } - return Status::OK(); -#else - - X509_STORE* verifyStore = SSL_CTX_get_cert_store(context); - if (!verifyStore) { - return {ErrorCodes::InvalidSSLConfiguration, - "no X509 store found for SSL context while loading system certificates"}; - } - - auto status = importCertStoreToX509_STORE(L"root", CERT_SYSTEM_STORE_CURRENT_USER, verifyStore); - if (!status.isOK()) - return status; - return importCertStoreToX509_STORE(L"CA", CERT_SYSTEM_STORE_CURRENT_USER, verifyStore); -#endif + return true; } bool SSLManager::_setupCRL(SSL_CTX* context, const std::string& crlFile) { @@ -1063,7 +933,8 @@ bool SSLManager::_hostNameMatch(const char* nameToMatch, const char* certHostNam StatusWith<boost::optional<std::string>> SSLManager::parseAndValidatePeerCertificate( SSL* conn, const std::string& remoteHost) { - if (!_sslConfiguration.hasCA && isSSLServer) + // only set if a CA cert has been provided + if (!_sslConfiguration.hasCA) return {boost::none}; X509* peerCert = SSL_get_peer_certificate(conn); diff --git a/src/mongo/util/net/ssl_manager.h b/src/mongo/util/net/ssl_manager.h index 2b965b46cc6..6b4e35510af 100644 --- a/src/mongo/util/net/ssl_manager.h +++ b/src/mongo/util/net/ssl_manager.h @@ -70,20 +70,22 @@ public: }; struct SSLConfiguration { - SSLConfiguration() : serverSubjectName(""), clientSubjectName("") {} + SSLConfiguration() : serverSubjectName(""), clientSubjectName(""), hasCA(false) {} SSLConfiguration(const std::string& serverSubjectName, const std::string& clientSubjectName, - const Date_t& serverCertificateExpirationDate) + const Date_t& serverCertificateExpirationDate, + bool hasCA) : serverSubjectName(serverSubjectName), clientSubjectName(clientSubjectName), - serverCertificateExpirationDate(serverCertificateExpirationDate) {} + serverCertificateExpirationDate(serverCertificateExpirationDate), + hasCA(hasCA) {} bool isClusterMember(StringData subjectName) const; BSONObj getServerStatusBSON() const; std::string serverSubjectName; std::string clientSubjectName; Date_t serverCertificateExpirationDate; - bool hasCA = false; + bool hasCA; }; class SSLManagerInterface { diff --git a/src/mongo/util/net/ssl_options.cpp b/src/mongo/util/net/ssl_options.cpp index 2d29e4704f2..650c0a7495e 100644 --- a/src/mongo/util/net/ssl_options.cpp +++ b/src/mongo/util/net/ssl_options.cpp @@ -312,6 +312,9 @@ Status storeSSLServerOptions(const moe::Environment& params) { if (sslGlobalParams.sslPEMKeyFile.size() == 0) { return Status(ErrorCodes::BadValue, "need sslPEMKeyFile when SSL is enabled"); } + if (sslGlobalParams.sslWeakCertificateValidation && sslGlobalParams.sslCAFile.empty()) { + return Status(ErrorCodes::BadValue, "need sslCAFile with sslWeakCertificateValidation"); + } if (!sslGlobalParams.sslCRLFile.empty() && sslGlobalParams.sslCAFile.empty()) { return Status(ErrorCodes::BadValue, "need sslCAFile with sslCRLFile"); } @@ -382,4 +385,14 @@ Status storeSSLClientOptions(const moe::Environment& params) { return Status::OK(); } +Status validateSSLMongoShellOptions(const moe::Environment& params) { + // Users must specify either a CAFile or allowInvalidCertificates if ssl=true. + if (params.count("ssl") && params["ssl"].as<bool>() == true && !params.count("ssl.CAFile") && + !params.count("ssl.allowInvalidCertificates")) { + return Status(ErrorCodes::BadValue, + "need to either provide sslCAFile or specify sslAllowInvalidCertificates"); + } + return Status::OK(); +} + } // namespace mongo diff --git a/src/mongo/util/net/ssl_options.h b/src/mongo/util/net/ssl_options.h index e897656ed25..c5e39908bef 100644 --- a/src/mongo/util/net/ssl_options.h +++ b/src/mongo/util/net/ssl_options.h @@ -103,4 +103,10 @@ Status canonicalizeSSLServerOptions(moe::Environment* params); Status validateSSLServerOptions(const moe::Environment& params); Status storeSSLClientOptions(const moe::Environment& params); + +/** + * Used by the Mongo shell to validate that the SSL options passed are acceptable and + * do not conflict with one another. + */ +Status validateSSLMongoShellOptions(const moe::Environment& params); } |