Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TOOLS-2013: Support PKCS #8 encrypted client private keys #64

Merged
merged 3 commits into from Jan 14, 2021

Conversation

edobranov
Copy link
Collaborator

Jira: https://jira.mongodb.org/browse/TOOLS-2013

This adds the ability to decrypt PKCS 8 encrypted PEM keys.

The assumption is that these types of keys are the only format possible in PEM blocks labeled -----BEGIN ENCRYPTED PRIVATE KEY-----. I wasn't able to find any place that explicitly states this, though the PKCS 8 documentation mentions an EncryptedPrivateKeyInfo type, which looks to correspond to that label. So I believe it's unique to PKCS 8.

There's one caveat that I'll make a comment about below.

decrypted, err := pkcs8.ParsePKCS8PrivateKey(currentBlock.Bytes, []byte(keyPasswd))
if err != nil {
return "", err
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my understanding, there's a couple ways to encrypt a PEM key in PKCS 8 format. The only one that the pkcs8 Go package can currently handle is called the PKCS 5 v2.0 scheme. The first time I tried this, I accidentally used the wrong scheme and got this error:

error configuring the connector: error configuring client, can't load client certificate: pkcs8: only PKCS #5 v2.0 supported

Even though the error is probably specific enough, I'm wondering if we should make a note of this in the docs under the --sslPEMKeyFile entry and provide guidance on getting the right scheme (e.g. using openssl with the -v2 des3 option to get PKCS 5 v2.0).

I'm okay either way, but curious to hear others' thoughts.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! I agree we should add this limitation to the doc so that it won't cause confusion to the client.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that this is a limitation significant enough to warrant a mention in the docs. Generally, the docs describe what we do support, and I think a limitation has to be pretty notable/important for us to want to describe what we don't do.

@edobranov edobranov requested a review from tfogo January 4, 2021 15:12
Copy link
Collaborator

@huan-Mongo huan-Mongo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job! LGTM!

decrypted, err := pkcs8.ParsePKCS8PrivateKey(currentBlock.Bytes, []byte(keyPasswd))
if err != nil {
return "", err
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! I agree we should add this limitation to the doc so that it won't cause confusion to the client.

Copy link
Member

@tfogo tfogo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

addClientCertFromBytes() is currently replicated in mtc because we are waiting on the go driver to implement GODRIVER-1588. But the eventual goal is to move back to using the version of addClientCertFromBytes() that exists in the go driver. So we probably want to open a go driver ticket to add PKCS#8 support there too.

@@ -48,3 +48,7 @@
go-tests = true
unused-packages = true


[[constraint]]
name = "github.com/youmark/pkcs8"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: we need to update the THIRD-PARTY-NOTICES file in mirror and sqlproxy once we revendor mtc.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@edobranov could you file a ticket for this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, filed TOOLS-2787.

db/db.go Outdated
buf, err := x509.DecryptPEMBlock(currentBlock, []byte(keyPasswd))
if err != nil {
return "", err
isEncrypted := x509.IsEncryptedPEMBlock(currentBlock) || strings.Contains(currentBlock.Type, "ENCRYPTED")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I think it's better to check for equality against the full "ENCRYPTED PRIVATE KEY" string here. It's better to be precise.

@edobranov
Copy link
Collaborator Author

So we probably want to open a go driver ticket to add PKCS#8 support there too.

There's a Go driver ticket linked to the tools one from a while back (GODRIVER-354).

@tfogo
Copy link
Member

tfogo commented Jan 12, 2021

It might be worth talking to the go driver team to see if they think the solution here would work for them and if they're open to you contributing this.

@rychipman rychipman removed their request for review January 14, 2021 02:56
@rychipman
Copy link
Collaborator

I'm removing myself as a reviewer on this PR, since there are already two other LGTMs, and I don't think my review needs to be a blocker here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants