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

Support for signing CSRs with challengePassword #381

Merged
merged 2 commits into from
Dec 6, 2023

Conversation

maraino
Copy link
Contributor

@maraino maraino commented Dec 6, 2023

Description

This commit adds the ChallengePassword field to the x509util.CertificateRequest struct. If this one is added, the method GetCertificateRequest will re-sign the CSR with the new attribute.

This commit adds the ChallengePassword field to the
`x509util.CertificateRequest` struct. If this one is added, the method
GetCertificateRequest will re-sign the CSR with the new attribute.
@maraino maraino force-pushed the mariano/challenge-password branch from 39463fc to b568818 Compare December 6, 2023 04:45
@@ -116,10 +144,123 @@ func (c *CertificateRequest) GetCertificateRequest() (*x509.CertificateRequest,
if err != nil {
return nil, errors.Wrap(err, "error creating certificate request")
}

// Prepend challenge password and sign again
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Prepend challenge password and sign again
// If a challenge password is provided, encode and prepend it as
// a challenge password attribute. [x509.CertificateRequest.Attributes] is marked deprecated,
// so this requires some low level ASN1 operations.

Copy link
Member

Choose a reason for hiding this comment

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

A bit more commentary seemed useful to me.

Commit marking Attributes as deprecated: golang/go@ccd9d9d

Proposal for accessing PKCS10 attributes: golang/go#60718

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 7a84055

I've changed the suggestion as it is not exactly like that. Go still supports setting attributes but is skipping those that do not match a format similar to the extensions.

I also saw the proposal tool.

Comment on lines 163 to 164
// Marshal challengePassword to ans1.RawValue
// Build challengePassword attribute (RFC 2985 section-5.4)
Copy link
Member

Choose a reason for hiding this comment

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

One of these maybe can be deleted, or combine in a single comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 7a84055, I left the old comment from my previous implementation where I was just using encoding/asn1.


b, err := builder.Bytes()
if err != nil {
return nil, errors.Wrap(err, "error marshaling challenge password")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return nil, errors.Wrap(err, "error marshaling challenge password")
return nil, fmt.Errorf("error marshaling challenge password: %w", err)

Unless you want to keep the stack trace for this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The majority of this package is using pkg/errors, so I'm doing it in the new code too. It is sometimes helpful. I'm not using it on new packages that I create.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I also don't consider using always fmt.Errorf in all the crypto packages as the best option. If we decide to tackle the errors, we should consider using more typed errors.

var signature []byte
signature, err = c.Signer.Sign(rand.Reader, signed, hashFunc)
if err != nil {
return nil, errors.Wrap(err, "error creating certificate request")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return nil, errors.Wrap(err, "error creating certificate request")
return nil, fmt.Errorf("error creating certificate request: %", err)

Unless you want to keep the stack trace

},
})
if err != nil {
return nil, errors.Wrap(err, "error creating certificate request")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return nil, errors.Wrap(err, "error creating certificate request")
return nil, fmt.Errorf("error creating certificate request: %w", err)

Unless you want to keep the stack trace

SignatureAlgorithm: SignatureAlgorithm(x509.SHA256WithRSA),
Signer: rsaKey,
}, expectedUTF8String, assert.NoError},
{"fail challengePAssword", &CertificateRequest{
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
{"fail challengePAssword", &CertificateRequest{
{"fail challengePassword", &CertificateRequest{

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 7a84055

}
}
if !found {
return nil, errors.Errorf("error creating certificate request: unsupported signature algorithm %s", sigAlgoOID)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return nil, errors.Errorf("error creating certificate request: unsupported signature algorithm %s", sigAlgoOID)
return nil, fmt.Errorf("error creating certificate request: unsupported signature algorithm %s", sigAlgoOID)

// Marshal tbsCertificateRequest
tbsCSRContents, err := asn1.Marshal(tbsCSR)
if err != nil {
return nil, errors.Wrap(err, "error creating certificate request")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return nil, errors.Wrap(err, "error creating certificate request")
return nil, fmt.Errorf("error creating certificate request: %w", err)

Unless you want to keep the stack trace


rest, err := asn1.Unmarshal(asn1Data, &csr)
if err != nil {
return nil, err
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return nil, err
return nil, fmt.Errorf("error unmarshaling certificate request: %w", err)

@@ -25,6 +52,7 @@ type CertificateRequest struct {
SANs []SubjectAlternativeName `json:"sans"`
Extensions []Extension `json:"extensions"`
SignatureAlgorithm SignatureAlgorithm `json:"signatureAlgorithm"`
ChallengePassword string `json:"-"`
Copy link
Member

@hslatman hslatman Dec 6, 2023

Choose a reason for hiding this comment

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

Instead of supporting this specific property like this, it might be an option to support it as a slice of Attributes? Then the ChallengePassword could be one specific Attribute. Processing it would be similar to []Extension, but with some custom logic for the additional (supported) attribute OIDs and values, and would allow other attributes to be set more easily too.

Probably good for a future iteration, though.

Copy link
Member

Choose a reason for hiding this comment

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

A nice to have: support the challenge password in NewCertificateRequestFromX509 too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was focusing on adding minimal support to create CSRs with it. I'm not focusing on parsing them, this can go in a future PR. Parsing requires a little bit more effort, but it's not hard.

@maraino maraino requested a review from hslatman December 6, 2023 19:11
@maraino maraino merged commit 41cf778 into master Dec 6, 2023
12 checks passed
@maraino maraino deleted the mariano/challenge-password branch December 6, 2023 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants