From 67dcab6e1490381e94b1e87c6442afeeafb76186 Mon Sep 17 00:00:00 2001 From: "Derrick J. Wippler" Date: Mon, 24 Jan 2022 14:23:02 -0600 Subject: [PATCH] GODRIVER-2263 Load all certs in a PEM (#834) --- mongo/options/clientoptions.go | 18 +++-- mongo/options/clientoptions_test.go | 5 ++ .../testdata/one-pk-multiple-certs.pem | 78 +++++++++++++++++++ 3 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 mongo/options/testdata/one-pk-multiple-certs.pem diff --git a/mongo/options/clientoptions.go b/mongo/options/clientoptions.go index b15d780429..da5f630d19 100644 --- a/mongo/options/clientoptions.go +++ b/mongo/options/clientoptions.go @@ -1001,7 +1001,8 @@ func addClientCertFromConcatenatedFile(cfg *tls.Config, certKeyFile, keyPassword // containing file and returns the certificate's subject name. func addClientCertFromBytes(cfg *tls.Config, data []byte, keyPasswd string) (string, error) { var currentBlock *pem.Block - var certBlock, certDecodedBlock, keyBlock []byte + var certDecodedBlock []byte + var certBlocks, keyBlocks [][]byte remaining := data start := 0 @@ -1012,7 +1013,8 @@ func addClientCertFromBytes(cfg *tls.Config, data []byte, keyPasswd string) (str } if currentBlock.Type == "CERTIFICATE" { - certBlock = data[start : len(data)-len(remaining)] + certBlock := data[start : len(data)-len(remaining)] + certBlocks = append(certBlocks, certBlock) certDecodedBlock = currentBlock.Bytes start += len(certBlock) } else if strings.HasSuffix(currentBlock.Type, "PRIVATE KEY") { @@ -1044,22 +1046,24 @@ func addClientCertFromBytes(cfg *tls.Config, data []byte, keyPasswd string) (str } var encoded bytes.Buffer pem.Encode(&encoded, &pem.Block{Type: currentBlock.Type, Bytes: keyBytes}) - keyBlock = encoded.Bytes() + keyBlock := encoded.Bytes() + keyBlocks = append(keyBlocks, keyBlock) start = len(data) - len(remaining) } else { - keyBlock = data[start : len(data)-len(remaining)] + keyBlock := data[start : len(data)-len(remaining)] + keyBlocks = append(keyBlocks, keyBlock) start += len(keyBlock) } } } - if len(certBlock) == 0 { + if len(certBlocks) == 0 { return "", fmt.Errorf("failed to find CERTIFICATE") } - if len(keyBlock) == 0 { + if len(keyBlocks) == 0 { return "", fmt.Errorf("failed to find PRIVATE KEY") } - cert, err := tls.X509KeyPair(certBlock, keyBlock) + cert, err := tls.X509KeyPair(bytes.Join(certBlocks, []byte("\n")), bytes.Join(keyBlocks, []byte("\n"))) if err != nil { return "", err } diff --git a/mongo/options/clientoptions_test.go b/mongo/options/clientoptions_test.go index 609df3dde9..d105ef1fe6 100644 --- a/mongo/options/clientoptions_test.go +++ b/mongo/options/clientoptions_test.go @@ -538,6 +538,11 @@ func TestClientOptions(t *testing.T) { baseClient().SetSRVMaxHosts(2). SetHosts([]string{"localhost.test.build.10gen.cc:27017", "localhost.test.build.10gen.cc:27018"}), }, + { + "GODRIVER-2263 regression test", + "mongodb://localhost/?tlsCertificateKeyFile=testdata/one-pk-multiple-certs.pem", + baseClient().SetTLSConfig(&tls.Config{Certificates: make([]tls.Certificate, 1)}), + }, } for _, tc := range testCases { diff --git a/mongo/options/testdata/one-pk-multiple-certs.pem b/mongo/options/testdata/one-pk-multiple-certs.pem new file mode 100644 index 0000000000..7845a6603d --- /dev/null +++ b/mongo/options/testdata/one-pk-multiple-certs.pem @@ -0,0 +1,78 @@ +This .pem file includes the following: +- Private Key +- Certificate 1 for Private Key +- Certificate 2 for Issuer of Certificate 1. + +This .pem file was created from test certificates from: +https://x509gen.corp.mongodb.com/#/cert/5ce5b21a42a0ef0008b11399 + +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAgqdjbfumni3Z8A7q2TpVvk1XAHAT/LGsNOEZ/Ksuypv+q3BK +BewgsF54n0oc2UshHDw8hIO6UsmsjRplySTvEfLkEaDiCA9xQ/TYVqSbx5PtFIVg +icPniCl01w3cjsO/GqydeyE9O7X7u58tlEyXNgW+5s9wROPSV/TM5gFNmMOHVDJz +QEiQVyVzd/96gYQHS44C/tibXb8Au+Z3dX0B5xPncbTITiZFpxqE7LXY29ZsyhOe +hbA9YS+YmsVnYJI52kWUMeo4HDXYNa7vifdJmbRhmpAAyvDatZdwvdWlEp0odf8k +JV9LNGvc9GZ31UhZmUAUYt4zR1awFr0xUOalMwIDAQABAoIBADrEW77OoGUprouB +yjSnPoX4d5ek0fipWhH25h92R/euLuCiA0miqhlqhMrxJQS//Eac+YOJVLeEKu7U +3s+Yo0fpfphHSyPg/ktYyC5AoCkm6k5+p6uPyIbATuOkQn6coUq4NaV6j/ZZpr7/ +nBrGUIVmFDXxPEhgSO5zF+6ky2hYdF/XSRHSS3ieGxy6PD9dHpWebVnZJ1EtElEc +8h+K0pJzXol++WWNR0S9OZHbYOWfew/2r4K2jfNAYsVjXOLGb2k1k/jC2qN8fq7R +6BGB0D2932X0WfUXBTxj3uBeTcz25ZnQeXuWmcmGRePBuW1nZaZnKcowbdu5gp19 +peaVzWECgYEA0fo9KEb1ffUzZTvX42PX0sZyxCmqLqOOQ9DWt9HNIscykIszF4XH +nrrTASD5p3IAweZI/g7VGxjx5C9irqH4NLIswILCcaSyLKzIy9rj4D/4cEdFT4YQ +8zTWXJAEgyphOSBPrefiwBDtbaQyUU+5lOXLEh+ceXjd/56WS0fOBukCgYEAn0pU +Qg3XuWBi0RbaGWdFJ/A/DTmNP6tn9ULij7bjhpEgOT6E3H7gSUmC4QXKhAu+fdKH +bmCs5GYGl9UOiERLvKl4HqU2lCniCKNP2ygRibH8BiKBNtLAp6SGRi6SJsJqfvge +WddtG6WNNBXLpiNzeQJW6Cm0iKJF6skNzkpNMbsCgYEAwuwP9eHZZvJGocVp5hb7 +dRjv1RXwe5ctK9skWEQUsCJG2FPAPCfeZYV892FLIJv+BAHo5J+USLFha7hpXT/S +j+iPDq7UHncLR9mmFUe/np8D3AbtWqNT/NGh5Q90gObIliVekkve/Pk5zzxL0Zu2 +5XhkiRB7S3BedTscvgmMQnECgYAF8pGI0dl/K3ElG3RTRH7Ziefgx4hVm0HLb47k +DNEcAikw2fu9++LF+b+wRTYVjhazvfuejG+IK6MNYkAjqGEnjzBT/Jk4GQQ+jFJ7 +/VgCSyn81Kb8dAwLdmIpFq4QUmwFh6AifJ+vS5QlILc04df66bJzArOh8mUn6g/g +5vdQ5wKBgBxewVKdmZY/GLn8ieFOHimG8y2xKa59j6nMTGaklKEoSyW60GiHk+Jl +q5LhUwHOQx3HzD5dy0ne2+0gN88iySfIe5rGXS7S9Pvnu06WIIbAnGWfedl026KJ +Tfg4SpzwaZtnXN/UJ62aaNgW2uYrdy4wF4M8zhXsgpj9w6xF369x +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDhTCCAm2gAwIBAgIDAxBVMA0GCSqGSIb3DQEBCwUAMHoxHDAaBgNVBAMTE2Ns +aWVudC1pbnRlcm1lZGlhdGUxEDAOBgNVBAsTB0RyaXZlcnMxEDAOBgNVBAoTB01v +bmdvREIxFjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3Jr +MQswCQYDVQQGEwJVUzAeFw0xOTA2MDMxNTQyMjVaFw0zOTA2MDMxNTQyMjVaMHAx +EjAQBgNVBAMTCWxvY2FsaG9zdDEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMH +TW9uZ29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlv +cmsxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +gqdjbfumni3Z8A7q2TpVvk1XAHAT/LGsNOEZ/Ksuypv+q3BKBewgsF54n0oc2Ush +HDw8hIO6UsmsjRplySTvEfLkEaDiCA9xQ/TYVqSbx5PtFIVgicPniCl01w3cjsO/ +GqydeyE9O7X7u58tlEyXNgW+5s9wROPSV/TM5gFNmMOHVDJzQEiQVyVzd/96gYQH +S44C/tibXb8Au+Z3dX0B5xPncbTITiZFpxqE7LXY29ZsyhOehbA9YS+YmsVnYJI5 +2kWUMeo4HDXYNa7vifdJmbRhmpAAyvDatZdwvdWlEp0odf8kJV9LNGvc9GZ31UhZ +mUAUYt4zR1awFr0xUOalMwIDAQABox4wHDAaBgNVHREEEzARgglsb2NhbGhvc3SH +BH8AAAEwDQYJKoZIhvcNAQELBQADggEBABNAqbfQon7VDIZIVoxL7fNsyv4y/mGI +gR9hTfSJHVyFpgTHjIobKYDpRx01uVTjEGMVjOAcpOYQIfTa7MFdbELrH5q6UUyl +J5i65MJlzIWgrchVzzgcP5UeBRnuUrFRDmt8VOGIA7CI6mWW/dDTHg7NVK5PbVi4 +ad56ogiptbnj1GKkImV2TCpwYhNxkf68OcwgfbknkWDxPjGFQjvYLspQBYdK+j9s +0tOGMqbt+8DH7whioH+yv4KhlN9g4R3oOybG82E0fJ8NbdsjEmQby28/f/U8fsjV +EDnxjuxJs/C9AH42Jpu56Zp16hhEz72mVZqeJZe+11wcUiyFW7jgEGc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDjTCCAnWgAwIBAgIDB0QCMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy +aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u +Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx +CzAJBgNVBAYTAlVTMB4XDTE5MDYwMzE1NDAyM1oXDTM5MDYwMzE1NDAyM1owejEc +MBoGA1UEAxMTY2xpZW50LWludGVybWVkaWF0ZTEQMA4GA1UECxMHRHJpdmVyczEQ +MA4GA1UEChMHTW9uZ29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UE +CBMITmV3IFlvcmsxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAsIKl4kILAnpSbDPQaUNmd8P8X+h45+RXCXmlbNSnKvsDCZU2Q/QV +BxMaOp7jNwOVBdECCQKYp1EL5B8O7rz7i/yJ80MGnh7mQW1Hnan79eIzq8ah5QSz +zJNLdzpix6CBR2GyL4BSl3mujNESEYtotcnihP7+YV6Sis9bttzhYhjmHm7346k2 +IpCBhCTS3AEzVL7ExmEc6D7qVA7pMtRFUFoIUzpGNp53v1wUVjwPiiHmzNsuq/kE +fqurB7WHIogux2xBVdfrU7Pfr+1MdD5rDuUB6VblWQBeeha1L6TvSSP3GHC2fG8j +CnhVNye7kWStd3r6Zfpqp9VDTUu0uXM9qwIDAQABox0wGzAMBgNVHRMEBTADAQH/ +MAsGA1UdDwQEAwICBDANBgkqhkiG9w0BAQsFAAOCAQEAX66R/Jvk2jUoVnvuPztR +iinyq9JXCXVQuG+dJ4ATy6JB8xmuaDMYmOSwzVyYZWQGIlqkwNZR5wga5OnksicI +Nm6dvhc5JbQ7ERDNgWzNtBaNkzJsaEjc9/FWcLlJeuQN+ZFdFVP+6k4aAWiYwf4A +KDvyUILEI59TWaScYnQmQcb/v81gLIq1IjaINAkuZcCHAgu2ZWLOSofgnEATiLYH +cXyy9WeRpd8nB3pgy1OjCN1E7+K6yHYYJYPQol25znAB5TLPbWwA8ek8fdmC3IpG +HOQXMsoPKCdlgNzG1RXalFSIO1AU2nYO5zeVB1l+WbzEp+o/zq0bi/HcvBhNAtRm +Lg== +-----END CERTIFICATE----- \ No newline at end of file