diff options
author | Sara Golemon <sara.golemon@mongodb.com> | 2018-06-04 19:19:14 -0400 |
---|---|---|
committer | Sara Golemon <sara.golemon@mongodb.com> | 2018-06-05 21:56:33 -0400 |
commit | f58092e36cf32ed90fdae5a5b619f8ed456a009d (patch) | |
tree | 9fa586279411a16864ba5060346436eaab22ef20 | |
parent | b577e9001eacee2fe9ca781e7eb87b2b04b220c6 (diff) | |
download | mongo-f58092e36cf32ed90fdae5a5b619f8ed456a009d.tar.gz |
SERVER-35196 Map additional X509 OIDs
(cherry picked from commit 23cd748c2df0800d908bb6c0e8b29d6f6ef7d0da)
-rw-r--r-- | jstests/libs/client-all-the-oids.csr.in | 74 | ||||
-rw-r--r-- | jstests/libs/client-all-the-oids.pem | 66 | ||||
-rw-r--r-- | jstests/ssl/libs/ssl_x509_role_auth_title.js | 12 | ||||
-rw-r--r-- | jstests/ssl/ssl_x509_roles.js | 20 | ||||
-rw-r--r-- | jstests/ssl/x509_all_the_oids.js | 47 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_manager.cpp | 57 |
6 files changed, 242 insertions, 34 deletions
diff --git a/jstests/libs/client-all-the-oids.csr.in b/jstests/libs/client-all-the-oids.csr.in new file mode 100644 index 00000000000..9d588c9fc13 --- /dev/null +++ b/jstests/libs/client-all-the-oids.csr.in @@ -0,0 +1,74 @@ +# Create certificate using: +# openssl req -new -config client-all-the-oids.csr.in -keyout client-all-the-oids.key -out client-all-the-oids.csr +# openssl rsa -in client-all-the-oids.key -out client-all-the-oids.rsa +# openssl x509 -in client-all-the-oids.csr -out client-all-the-oids.pem -req -CA ca.pem -days 3650 -CAcreateserial +# cat client-all-the-oids.rsa >> client-all-the-oids.pem +# rm ca.srl client-all-the-oids.key client-all-the-oids.rsa client-all-the-oids.csr + +[ req ] +default_bits=2048 +prompt=no +encrypt_key=no +default_md=sha1 +distinguished_name=dn + +[ dn ] +# Collect all known OIDs using: +# grep -E '^X509 ' "$OPENSSL/crypto/objects/objects.txt" | tr -d '\t' | \ +# sed -e 's/^X509 *\([0-9]\+\) *\(: *\)\+\([[:alnum:]]\+\).*/\3=Datum-\1/g' \ +# -e 's/C=Datum-6/C=US/g' -e 's/ST=Datum-8/ST=NY/g' +CN=Datum-3 +SN=Datum-4 +serialNumber=Datum-5 +C=US +L=Datum-7 +ST=NY +street=Datum-9 +O=Datum-10 +OU=Datum-11 +title=Datum-12 +description=Datum-13 +searchGuide=Datum-14 +businessCategory=Datum-15 +postalAddress=Datum-16 +postalCode=Datum-17 +postOfficeBox=Datum-18 +physicalDeliveryOfficeName=Datum-19 +telephoneNumber=Datum-20 +telexNumber=Datum-21 +teletexTerminalIdentifier=Datum-22 +facsimileTelephoneNumber=Datum-23 +x121Address=Datum-24 +internationaliSDNNumber=Datum-25 +registeredAddress=Datum-26 +destinationIndicator=Datum-27 +preferredDeliveryMethod=Datum-28 +presentationAddress=Datum-29 +supportedApplicationContext=Datum-30 +member=Datum-31 +owner=Datum-32 +roleOccupant=Datum-33 +seeAlso=Datum-34 +userPassword=Datum-35 +userCertificate=Datum-36 +cACertificate=Datum-37 +authorityRevocationList=Datum-38 +certificateRevocationList=Datum-39 +crossCertificatePair=Datum-40 +name=Datum-41 +GN=Datum-42 +initials=Datum-43 +generationQualifier=Datum-44 +x500UniqueIdentifier=Datum-45 +dnQualifier=Datum-46 +enhancedSearchGuide=Datum-47 +protocolInformation=Datum-48 +distinguishedName=Datum-49 +uniqueMember=Datum-50 +houseIdentifier=Datum-51 +supportedAlgorithms=Datum-52 +deltaRevocationList=Datum-53 +dmdName=Datum-54 +pseudonym=Datum-65 +role=Datum-72 + diff --git a/jstests/libs/client-all-the-oids.pem b/jstests/libs/client-all-the-oids.pem new file mode 100644 index 00000000000..d92bcd809cc --- /dev/null +++ b/jstests/libs/client-all-the-oids.pem @@ -0,0 +1,66 @@ +-----BEGIN CERTIFICATE----- +MIIG4zCCBcsCCQD7OSGYeyWKHzANBgkqhkiG9w0BAQsFADB0MRcwFQYDVQQDEw5L +ZXJuZWwgVGVzdCBDQTEPMA0GA1UECxMGS2VybmVsMRAwDgYDVQQKEwdNb25nb0RC +MRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9yazELMAkG +A1UEBhMCVVMwHhcNMTgwNjA1MTczMzQ3WhcNMjgwNjAyMTczMzQ3WjCCA/ExEDAO +BgNVBAMMB0RhdHVtLTMxEDAOBgNVBAQMB0RhdHVtLTQxEDAOBgNVBAUTB0RhdHVt +LTUxCzAJBgNVBAYTAlVTMRAwDgYDVQQHDAdEYXR1bS03MQswCQYDVQQIDAJOWTEQ +MA4GA1UECQwHRGF0dW0tOTERMA8GA1UECgwIRGF0dW0tMTAxETAPBgNVBAsMCERh +dHVtLTExMREwDwYDVQQMDAhEYXR1bS0xMjERMA8GA1UEDQwIRGF0dW0tMTMxETAP +BgNVBA4MCERhdHVtLTE0MREwDwYDVQQPDAhEYXR1bS0xNTERMA8GA1UEEAwIRGF0 +dW0tMTYxETAPBgNVBBEMCERhdHVtLTE3MREwDwYDVQQSDAhEYXR1bS0xODERMA8G +A1UEEwwIRGF0dW0tMTkxETAPBgNVBBQMCERhdHVtLTIwMREwDwYDVQQVDAhEYXR1 +bS0yMTERMA8GA1UEFgwIRGF0dW0tMjIxETAPBgNVBBcMCERhdHVtLTIzMREwDwYD +VQQYDAhEYXR1bS0yNDERMA8GA1UEGQwIRGF0dW0tMjUxETAPBgNVBBoMCERhdHVt +LTI2MREwDwYDVQQbDAhEYXR1bS0yNzERMA8GA1UEHAwIRGF0dW0tMjgxETAPBgNV +BB0MCERhdHVtLTI5MREwDwYDVQQeDAhEYXR1bS0zMDERMA8GA1UEHwwIRGF0dW0t +MzExETAPBgNVBCAMCERhdHVtLTMyMREwDwYDVQQhDAhEYXR1bS0zMzERMA8GA1UE +IgwIRGF0dW0tMzQxETAPBgNVBCMMCERhdHVtLTM1MREwDwYDVQQkDAhEYXR1bS0z +NjERMA8GA1UEJQwIRGF0dW0tMzcxETAPBgNVBCYMCERhdHVtLTM4MREwDwYDVQQn +DAhEYXR1bS0zOTERMA8GA1UEKAwIRGF0dW0tNDAxETAPBgNVBCkMCERhdHVtLTQx +MREwDwYDVQQqDAhEYXR1bS00MjERMA8GA1UEKwwIRGF0dW0tNDMxETAPBgNVBCwM +CERhdHVtLTQ0MREwDwYDVQQtDAhEYXR1bS00NTERMA8GA1UELhMIRGF0dW0tNDYx +ETAPBgNVBC8MCERhdHVtLTQ3MREwDwYDVQQwDAhEYXR1bS00ODERMA8GA1UEMQwI +RGF0dW0tNDkxETAPBgNVBDIMCERhdHVtLTUwMREwDwYDVQQzDAhEYXR1bS01MTER +MA8GA1UENAwIRGF0dW0tNTIxETAPBgNVBDUMCERhdHVtLTUzMREwDwYDVQQ2DAhE +YXR1bS01NDERMA8GA1UEQQwIRGF0dW0tNjUxETAPBgNVBEgMCERhdHVtLTcyMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyh8fyOWfeamvgR+hQ3pAd00c +8rPwg3hYcF+7ObZPJI2E7qNV6I+gK6ho5f6D6wx7h3TuJkZLIOnf38HR7YFXKBNp +xPtBiSWmeleryZad5mdGKy5UsBkVz5XjcY/F2MjqAwSuO+tL+KVOHomVWcEp8CTu +lOeVlnP8SG8lrNiCtjm8xhKIs5qC33uhj8aI57D42lpL79y2zcR52SevI7ifw2NU +BHmUr1+mUexZkPbDUeGUS0kbeavleMCpE0cizJHJiFW83XkH7d0KnW01IzkS1DqM +CXQ6MzDOmKtvLvpief/+M4pZdl1iTyYP5cygm/NvtY0VgLvyj4wptuMB5zanuwID +AQABMA0GCSqGSIb3DQEBCwUAA4IBAQADiQXznY0pwwkEncBChXie3BHms11pp6NX +wyDQDud9j8EDa7y48sfNO5nXQw1ND0T4U4LUEFxKPG4lqMtQbsKrEEN3i+Wog/mY +NC+SeVu6S/xxnULzhlLu1Df6+o6MzJcwSEkQgmaFNk8WjkFSU/cBQo41kfXtRId8 +oFlqM6gBjvkELaT77qG6pf9/VqjoGdGMJFp8L+YVCGeSbro65Vpv/RU5lWresewE +sZcflRWvOUFQ4m8n0Q961XR62KbhzHqjyo+H/G6XJGu9y3av/9miWMlBMmbFmrUq +5UvNSGxqh8/xrvRerKrWhRiOXrL7EyAnj6DxpD18RtHhrXcBo85b +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAyh8fyOWfeamvgR+hQ3pAd00c8rPwg3hYcF+7ObZPJI2E7qNV +6I+gK6ho5f6D6wx7h3TuJkZLIOnf38HR7YFXKBNpxPtBiSWmeleryZad5mdGKy5U +sBkVz5XjcY/F2MjqAwSuO+tL+KVOHomVWcEp8CTulOeVlnP8SG8lrNiCtjm8xhKI +s5qC33uhj8aI57D42lpL79y2zcR52SevI7ifw2NUBHmUr1+mUexZkPbDUeGUS0kb +eavleMCpE0cizJHJiFW83XkH7d0KnW01IzkS1DqMCXQ6MzDOmKtvLvpief/+M4pZ +dl1iTyYP5cygm/NvtY0VgLvyj4wptuMB5zanuwIDAQABAoIBAQC+0LliIR34bvDI +l0LYgF7CAmP04VmL1J6xoD8SEgIPgSdhX4QoJQfSj5BQqYKC8erhC8wVCEG/FeyL +wuBcN8I/jGxLUeUiBBBx6bi9fNse/JqrA3diNJx5uIjb2h6vNaZvKQkQemfjmrPw +cnU0If9kvokavLNlMaSYAY5w6ookWxeoB5itbYlXzw2EZF9ldJDZsBWuK3wqfLnj +kR2izXia+lbvdcsUp1chdGDV7COLCoUbpEt4AVdmDhKymQ6xEdYDUG7u9inR4alN +OqDqxL0Nk4JnYVg+9C1a9UWtHw5aKvd75kVBPaVRUehtWnHi0E5hZFj/wjeohuOF +q0HOc2nhAoGBAP5IrRvBGVeOqm3YResmWkaNiARdNbq5Mvb3BfRyAQNL8HKgSELx +LsjM6gZiPIQFS91njiT8t+TZnZh/WJ0aGhIiSWmZyVuKK8sJ80NZpjmBS14gJMz5 +KQPstTXS2WYP57N0BN3eI+tHEoC2/QYuqMLMbSVFQTD1ThwNCONNE/TRAoGBAMt8 +U9/6TZpMV7+c3V7gTx6D0Kf2WRrIIUwAHPMPxxz+Bpg2wRNFXrlDI842y8joeF6g +/h3GFSSs5qTQeYZt0V7XDsUCup9cHDfQdyjESHNjQlRXnM91Citns1cx3SwXb5fw +xdSr+l0Ws7hdHJdha4X7F24HUtryVau7Qo9WZKbLAoGAV0fc21zxdONMTn3gqfE1 +JWhpGo5f5eKxwqFRkvEateX393BavVeJpnTnkx9fBDXJL4re+IUiHdQwSurTIMGX +10ebiTq3KcuIcp3MuP5plu1xUDKaTxzq3iT+oiXoZybocelNzlX0YEq56CJnQRr8 +5DhE8nkOAl8A25IBzftj8TECgYBk7LhJGcONqRnIjsv5N7XmQ6ik9fmB4Asrv86b ++5JdXdz1eArRPRHbP2Kt792pOywgeycuq0VnWF5ZFpF/zE4RBQdtTYo0aiIQyNOh +I6FvoaaPYJkFCF7P4nI/6BpzuPf/W0szzUyzCQSAh6YbqxUCceRQDU/aCmHVeF5t +64KmewKBgQDcfNx9wWs1b+n5XUD26rNP/gyiRWXpZy2y1of2BvWmBNAMTg4w04Mb +ZRcsS26yyX33e0H6oosFB5/knDXwLn+ABsMU3ItjWSWRTC318cnyhGNwmTAtG8WN +W7ZXTiY87qfNHX9coEfjeKgguLiKLkWBH+shwRdS5q+EaADVC48pcg== +-----END RSA PRIVATE KEY----- diff --git a/jstests/ssl/libs/ssl_x509_role_auth_title.js b/jstests/ssl/libs/ssl_x509_role_auth_title.js deleted file mode 100644 index aeec6d97e34..00000000000 --- a/jstests/ssl/libs/ssl_x509_role_auth_title.js +++ /dev/null @@ -1,12 +0,0 @@ -// Helper script used to validate login as x509 auth with a certificate with roles works. -(function() { - "use strict"; - - // Auth as user in certificate with an email address - const ret = db.getSiblingDB("$external").auth({ - mechanism: "MONGODB-X509", - user: - "2.5.4.12=A Test Certificate,emailAddress=example@mongodb.com,CN=client,OU=KernelUser,O=MongoDB,L=New York City,ST=New York,C=US" - }); - assert.eq(ret, 1, "Auth failed"); -}()); diff --git a/jstests/ssl/ssl_x509_roles.js b/jstests/ssl/ssl_x509_roles.js index b55679ad620..ac355414787 100644 --- a/jstests/ssl/ssl_x509_roles.js +++ b/jstests/ssl/ssl_x509_roles.js @@ -76,26 +76,6 @@ load('jstests/ssl/libs/ssl_helpers.js'); // runMongoProgram returns 0 on success assert.eq(0, email, "Connection attempt failed"); - - // We test the "title" OID is represented as an OID on Apple and Windows - // rather then try to make Apple and Windows support every possible OID. - requireSSLProvider(['apple', 'windows'], function() { - - const title = runMongoProgram("mongo", - "--host", - "localhost", - "--port", - port, - "--ssl", - "--sslCAFile", - CA_CERT, - "--sslPEMKeyFile", - CLIENT_TITLE_CERT, - "jstests/ssl/libs/ssl_x509_role_auth_title.js"); - - // runMongoProgram returns 0 on success - assert.eq(0, title, "Connection attempt failed"); - }); } const x509_options = {sslMode: "requireSSL", sslPEMKeyFile: SERVER_CERT, sslCAFile: CA_CERT}; diff --git a/jstests/ssl/x509_all_the_oids.js b/jstests/ssl/x509_all_the_oids.js new file mode 100644 index 00000000000..b33bf81c4d7 --- /dev/null +++ b/jstests/ssl/x509_all_the_oids.js @@ -0,0 +1,47 @@ +// Test X509 auth with all known RDN OIDs. + +(function() { + 'use strict'; + + const SERVER_CERT = 'jstests/libs/server.pem'; + const CA_CERT = 'jstests/libs/ca.pem'; + + function runTest(conn) { + const script = + 'assert(db.getSiblingDB(\'$external\').auth({mechanism: \'MONGODB-X509\'}));'; + clearRawMongoProgramOutput(); + const exitCode = runMongoProgram('mongo', + '--ssl', + '--sslAllowInvalidHostnames', + '--sslPEMKeyFile', + 'jstests/libs/client-all-the-oids.pem', + '--sslCAFile', + CA_CERT, + '--port', + conn.port, + '--eval', + script); + + // We expect failure, since we can't create a user with this massive username in WT. + // But at least make sure the error message is sensible. + assert.neq(exitCode, 0); + const output = rawMongoProgramOutput(); + + const NAME = + 'role=Datum-72,pseudonym=Datum-65,dmdName=Datum-54,deltaRevocationList=Datum-53,supportedAlgorithms=Datum-52,houseIdentifier=Datum-51,uniqueMember=Datum-50,distinguishedName=Datum-49,protocolInformation=Datum-48,enhancedSearchGuide=Datum-47,dnQualifier=Datum-46,x500UniqueIdentifier=Datum-45,generationQualifier=Datum-44,initials=Datum-43,GN=Datum-42,name=Datum-41,crossCertificatePair=Datum-40,certificateRevocationList=Datum-39,authorityRevocationList=Datum-38,cACertificate=Datum-37,userCertificate=Datum-36,userPassword=Datum-35,seeAlso=Datum-34,roleOccupant=Datum-33,owner=Datum-32,member=Datum-31,supportedApplicationContext=Datum-30,presentationAddress=Datum-29,preferredDeliveryMethod=Datum-28,destinationIndicator=Datum-27,registeredAddress=Datum-26,internationaliSDNNumber=Datum-25,x121Address=Datum-24,facsimileTelephoneNumber=Datum-23,teletexTerminalIdentifier=Datum-22,telexNumber=Datum-21,telephoneNumber=Datum-20,physicalDeliveryOfficeName=Datum-19,postOfficeBox=Datum-18,postalCode=Datum-17,postalAddress=Datum-16,businessCategory=Datum-15,searchGuide=Datum-14,description=Datum-13,title=Datum-12,OU=Datum-11,O=Datum-10,street=Datum-9,ST=NY,L=Datum-7,C=US,serialNumber=Datum-5,SN=Datum-4,CN=Datum-3'; + + assert(output.includes('Error: Could not find user ' + NAME + '@$external'), + "Shell is missing unknown user message"); + } + + // Standalone. + const mongod = MongoRunner.runMongod({ + auth: '', + sslMode: 'requireSSL', + sslPEMKeyFile: SERVER_CERT, + sslCAFile: CA_CERT, + sslAllowInvalidCertificates: '', + }); + runTest(mongod); + MongoRunner.stopMongod(mongod); +})(); diff --git a/src/mongo/util/net/ssl_manager.cpp b/src/mongo/util/net/ssl_manager.cpp index f98ac09edb3..27cb381b982 100644 --- a/src/mongo/util/net/ssl_manager.cpp +++ b/src/mongo/util/net/ssl_manager.cpp @@ -128,18 +128,71 @@ std::string x509OidToShortName(const std::string& name) { } #else // On Apple/Windows we have to provide our own mapping. +// Generate the 2.5.4.* portions of this list from OpenSSL sources with: +// grep -E '^X509 ' "$OPENSSL/crypto/objects/objects.txt" | tr -d '\t' | +// sed -e 's/^X509 *\([0-9]\+\) *\(: *\)\+\([[:alnum:]]\+\).*/{"2.5.4.\1", "\3"},/g' std::string x509OidToShortName(const std::string& name) { - static const std::map<std::string, std::string> kX509OidToShortNameMappings = { + static const StringMap<std::string> kX509OidToShortNameMappings = { {"0.9.2342.19200300.100.1.1", "UID"}, {"0.9.2342.19200300.100.1.25", "DC"}, {"1.2.840.113549.1.9.1", "emailAddress"}, + {"2.5.29.17", "subjectAltName"}, + + // X509 OIDs Generated from objects.txt {"2.5.4.3", "CN"}, + {"2.5.4.4", "SN"}, + {"2.5.4.5", "serialNumber"}, {"2.5.4.6", "C"}, {"2.5.4.7", "L"}, {"2.5.4.8", "ST"}, - {"2.5.4.9", "STREET"}, + {"2.5.4.9", "street"}, {"2.5.4.10", "O"}, {"2.5.4.11", "OU"}, + {"2.5.4.12", "title"}, + {"2.5.4.13", "description"}, + {"2.5.4.14", "searchGuide"}, + {"2.5.4.15", "businessCategory"}, + {"2.5.4.16", "postalAddress"}, + {"2.5.4.17", "postalCode"}, + {"2.5.4.18", "postOfficeBox"}, + {"2.5.4.19", "physicalDeliveryOfficeName"}, + {"2.5.4.20", "telephoneNumber"}, + {"2.5.4.21", "telexNumber"}, + {"2.5.4.22", "teletexTerminalIdentifier"}, + {"2.5.4.23", "facsimileTelephoneNumber"}, + {"2.5.4.24", "x121Address"}, + {"2.5.4.25", "internationaliSDNNumber"}, + {"2.5.4.26", "registeredAddress"}, + {"2.5.4.27", "destinationIndicator"}, + {"2.5.4.28", "preferredDeliveryMethod"}, + {"2.5.4.29", "presentationAddress"}, + {"2.5.4.30", "supportedApplicationContext"}, + {"2.5.4.31", "member"}, + {"2.5.4.32", "owner"}, + {"2.5.4.33", "roleOccupant"}, + {"2.5.4.34", "seeAlso"}, + {"2.5.4.35", "userPassword"}, + {"2.5.4.36", "userCertificate"}, + {"2.5.4.37", "cACertificate"}, + {"2.5.4.38", "authorityRevocationList"}, + {"2.5.4.39", "certificateRevocationList"}, + {"2.5.4.40", "crossCertificatePair"}, + {"2.5.4.41", "name"}, + {"2.5.4.42", "GN"}, + {"2.5.4.43", "initials"}, + {"2.5.4.44", "generationQualifier"}, + {"2.5.4.45", "x500UniqueIdentifier"}, + {"2.5.4.46", "dnQualifier"}, + {"2.5.4.47", "enhancedSearchGuide"}, + {"2.5.4.48", "protocolInformation"}, + {"2.5.4.49", "distinguishedName"}, + {"2.5.4.50", "uniqueMember"}, + {"2.5.4.51", "houseIdentifier"}, + {"2.5.4.52", "supportedAlgorithms"}, + {"2.5.4.53", "deltaRevocationList"}, + {"2.5.4.54", "dmdName"}, + {"2.5.4.65", "pseudonym"}, + {"2.5.4.72", "role"}, }; auto it = kX509OidToShortNameMappings.find(name); |