-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Unknown
-
None
-
Affects Version/s: 1.20.1
-
Component/s: None
-
None
Summary
Private keys can be in PKCS#1 or PKCS#8 format. Secure Channel on Windows is unable to load PKCS#8 encoded private keys.
How to Reproduce
Start a server and require client certificates. Use test .pem files from the https://github.com/mongodb-labs/drivers-evergreen-tools repo:
./bin/mongod \ --setParameter enableTestCommands=1 \ --tlsCertificateKeyFile=C:/cygwin/home/Administrator/code/drivers-evergreen-tools/.evergreen/x509gen/server.pem \ --tlsCAFile=C:/cygwin/home/Administrator/code/drivers-evergreen-tools/.evergreen/x509gen/ca.pem \ --tlsMode=requireTLS \ --port=27018 \ --dbpath ./data
Use the repro environment here:
Use the run.sh script to test connecting with a PKCS#1 key (succeeds) and a PKCS#8 private key (fails):
export CA_FILE="C:/cygwin/home/Administrator/code/drivers-evergreen-tools/.evergreen/x509gen/ca.pem" export CLIENT_FILE="C:/cygwin/home/Administrator/code/drivers-evergreen-tools/.evergreen/x509gen/client-pkcs8-unencrypted.pem" export MONGODB_URI="mongodb://localhost:27018/?tls=true&tlsCAFile=$CA_FILE&tlsCertificateKeyFile=$CLIENT_FILE" ./cmake-build/Debug/crepro.out
Gets the following output on Windows:
2022/01/25 23:59:03.0700: [ 9916]: ERROR: stream-secure-channel: Failed to parse private key. ASN1 bad tag value met. (0x8009310B) 2022/01/25 23:59:03.0930: [ 9916]: ERROR: stream-secure-channel: Failed to parse private key. ASN1 bad tag value met. (0x8009310B) 2022/01/25 23:59:03.0954: [ 9916]: ERROR: mongoc: mongoc_collection_count_documents error: No suitable servers found (`serverSelectionTryOnce` set): [Failed to receive length header from server. calling hello on 'localhost:27018']
Additional Background
See SERVER-35541 for an example of this implementation in the MongoDB Server.
See https://stackoverflow.com/a/48960291/774658 for additional background on PKCS#1 and PKCS#8 format.
https://github.com/jeroen/mongolite/issues/266 may be a related case.
Workaround
As a workaround, users can convert PKCS#8 to PKCS#1 for an RSA key. In OpenSSL 3.0+:
openssl pkey -in private_key_pkcs8.pem -traditional
In OpenSSL versions less than 3:
openssl rsa -in private_key_pkcs8.pem -out private_key_pkcs1.pem