-
Notifications
You must be signed in to change notification settings - Fork 513
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
feat: support p12 certificate format #415
base: master
Are you sure you want to change the base?
Conversation
I have some questions....
|
If we want to support a new type of cert (p12), what would you call the old type?
Is password applicable to any other types of certs, or is this p12 specific?Passwords may also be applicable to PEM format certificates, as described in rfc7468 on the Textual Encoding of PKCS #8 Encrypted Private Key Info (https://datatracker.ietf.org/doc/html/rfc7468#section-11). Could the cert type be auto detected without an explicit command line option?
|
Gotcha. So if this PR merged, we'd have code written to support PEM and P12 but nothing else.
Seems like the password option should also apply to PEM then?
I get it, but I worry about option shock. If we added logic to auto-detect the cert type, is there any reason to think we couldn't extend such auto-detection to DER and ENG in the future? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some feedback. Note that even if the feedback were addressed, it's still up to @dragonsinth to decide whether to accept the change or not.
grpcurl.go
Outdated
certificate, err := tls.LoadX509KeyPair(clientCertFile, clientKeyFile) | ||
var certificate tls.Certificate | ||
var err error | ||
if strings.EqualFold(clientCertType, "p12") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For one, we never check that the alternative is "pem". So we accept a garbage cert type, as long as the cert file is actually pem-encoded, which is non-intuitive.
Also (1) why EqualFold
? We can just make it case-sensitive. (2) Why string comparisons everywhere? Maybe introduce a new type CertType int
to represent this, instead of it being stringly typed.
grpcurl.go
Outdated
@@ -527,12 +529,18 @@ func ClientTransportCredentials(insecureSkipVerify bool, cacertFile, clientCertF | |||
// given properties. If cacertFile is blank, only standard trusted certs are used to | |||
// verify the server certs. If clientCertFile is blank, the client will not use a client | |||
// certificate. If clientCertFile is not blank then clientKeyFile must not be blank. | |||
func ClientTLSConfig(insecureSkipVerify bool, cacertFile, clientCertFile, clientKeyFile string) (*tls.Config, error) { | |||
func ClientTLSConfig(insecureSkipVerify bool, cacertFile, clientCertFile, clientKeyFile, clientCertType, clientPass string) (*tls.Config, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a backwards-compatible change. This is exported API, and any other callers of this would be broken by the signature change. This kind of capability would have to be exposed via a new function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your suggestions. I am currently trying to implement auto-detection to DER and ENG formats, and I will work on addressing the issues you pointed out during this process.
cmd/grpcurl/grpcurl.go
Outdated
if (*key == "") != (*cert == "") && !strings.EqualFold(*certType, "p12") { | ||
fail(nil, "The -cert and -key arguments must be used together and both be present.") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is insufficient. With "p12", it still doesn't make sense to provide a -key
argument but not -cert
, since the actual kay+cert is loaded from the -cert
argument. Also, if they do specify both as different files, it should probably be an error with "p12", since the key argument is erroneous (and the current implementation would ignore it).
Also, nowhere is validating the the -cert-type
flag be "p12" or "pem" as indicated in the help for the flag. So this allows users to set a garbage type, in which case the meaning is unclear. It also misleadingly lets them enter "der" or "eng", but then expects the file to actually be "pem".
grpcurl.go
Outdated
for _, block := range pemBlocks { | ||
pemBytes = append(pemBytes, pem.EncodeToMemory(block)...) | ||
} | ||
certificate, err := tls.X509KeyPair(pemBytes, pemBytes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pemBytes
, pemBytes
seems strange... shouldn't there be separate entries for the key and cert?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The file format PKCS12 will contain both the CERTIFICATE and PRIVATE KEY data, while the tls.X509KeyPair function internally identifies the CERTIFICATE and PRIVATE KEY from the PEM data.
@@ -2,3 +2,4 @@ dist/ | |||
.idea/ | |||
VERSION | |||
.tmp/ | |||
*.swp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"swp" files are temporary files generated by the vim.
@wangtiga I pushed a commit demonstrating PEM decoding in a test; could you do something similar for p12? Generate a bogus key and cert with a password and write a simple test calling |
Okay, I'm currently trying auto-detection to DER and ENG formats. Once it's done, I will add unit tests for the relevant formats. |
1730e03
to
3dad42b
Compare
|
".jceks": CertKeyFormatJCEKS, | ||
".jks": CertKeyFormatJCEKS, // Only partially supported | ||
".der": CertKeyFormatDER, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file looks to have a lot of content copied from square/certigo/lib/certs.go -- why is so much code needing to be copied instead of finding a way to use the lib directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main purpose is to add the functionality of auto-detecting file formats. In the square/certigo/lib package, the formatForFile function is private, so a new function lib.GuessFormatForFile has been added. Additionally, there are some minor adjustments, such as introducing the CertificateKeyFormat type to identify file formats and reducing direct string comparisons operations.
|
||
func (f CertificateKeyFormat) IsNone() bool { | ||
return f == CertKeyFormatNONE | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems misleading.. these are called CertificateKeyFormat
, but as far as I can tell the only supported key format is PEM, whereas the cert formats are what vary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both JCEKS and PKCS12 formats include both key and certificate files.
The key file can also be in DER format, but its usage frequency is low, so it is currently not supported.
I am not using the JCEKS format at the moment and haven't tested it, so the code for it is included but not made available for public use.
This commit adds support p12 certificate format.
add three param -cacert-format -cert-format -pass
This should close #331