Skip to content

Commit 4edf9f4

Browse files
authored
GODRIVER-2650 Fix incorrect X509 certificate being used as username for authentication. (#1148)
1 parent 59c6453 commit 4edf9f4

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

mongo/options/clientoptions.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,8 @@ func (c *ClientOptions) SetTimeout(d time.Duration) *ClientOptions {
752752
// "tlsPrivateKeyFile". The "tlsCertificateKeyFile" option specifies a path to the client certificate and private key,
753753
// which must be concatenated into one file. The "tlsCertificateFile" and "tlsPrivateKey" combination specifies separate
754754
// paths to the client certificate and private key, respectively. Note that if "tlsCertificateKeyFile" is used, the
755-
// other two options must not be specified.
755+
// other two options must not be specified. Only the subject name of the first certificate is honored as the username
756+
// for X509 auth in a file with multiple certs.
756757
//
757758
// 3. "tlsCertificateKeyFilePassword" (or "sslClientCertificateKeyPassword"): Specify the password to decrypt the client
758759
// private key file (e.g. "tlsCertificateKeyFilePassword=password").
@@ -1049,8 +1050,8 @@ func addClientCertFromConcatenatedFile(cfg *tls.Config, certKeyFile, keyPassword
10491050
return addClientCertFromBytes(cfg, data, keyPassword)
10501051
}
10511052

1052-
// addClientCertFromBytes adds a client certificate to the configuration given a path to the
1053-
// containing file and returns the certificate's subject name.
1053+
// addClientCertFromBytes adds client certificates to the configuration given a path to the
1054+
// containing file and returns the subject name in the first certificate.
10541055
func addClientCertFromBytes(cfg *tls.Config, data []byte, keyPasswd string) (string, error) {
10551056
var currentBlock *pem.Block
10561057
var certDecodedBlock []byte
@@ -1067,7 +1068,11 @@ func addClientCertFromBytes(cfg *tls.Config, data []byte, keyPasswd string) (str
10671068
if currentBlock.Type == "CERTIFICATE" {
10681069
certBlock := data[start : len(data)-len(remaining)]
10691070
certBlocks = append(certBlocks, certBlock)
1070-
certDecodedBlock = currentBlock.Bytes
1071+
// Assign the certDecodedBlock when it is never set,
1072+
// so only the first certificate is honored in a file with multiple certs.
1073+
if certDecodedBlock == nil {
1074+
certDecodedBlock = currentBlock.Bytes
1075+
}
10711076
start += len(certBlock)
10721077
} else if strings.HasSuffix(currentBlock.Type, "PRIVATE KEY") {
10731078
isEncrypted := x509.IsEncryptedPEMBlock(currentBlock) || strings.Contains(currentBlock.Type, "ENCRYPTED PRIVATE KEY")

mongo/options/clientoptions_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,15 @@ func TestClientOptions(t *testing.T) {
573573
"mongodb://localhost/?tlsCertificateKeyFile=testdata/one-pk-multiple-certs.pem",
574574
baseClient().SetTLSConfig(&tls.Config{Certificates: make([]tls.Certificate, 1)}),
575575
},
576+
{
577+
"GODRIVER-2650 X509 certificate",
578+
"mongodb://localhost/?ssl=true&authMechanism=mongodb-x509&sslClientCertificateKeyFile=testdata/one-pk-multiple-certs.pem",
579+
baseClient().SetAuth(Credential{
580+
AuthMechanism: "mongodb-x509", AuthSource: "$external",
581+
// Subject name in the first certificate is used as the username for X509 auth.
582+
Username: `C=US,ST=New York,L=New York City,O=MongoDB,OU=Drivers,CN=localhost`,
583+
}).SetTLSConfig(&tls.Config{Certificates: make([]tls.Certificate, 1)}),
584+
},
576585
}
577586

578587
for _, tc := range testCases {

0 commit comments

Comments
 (0)