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

proposal: crypto/x509: Add support for PKCS#10 attributes #60718

Open
dachaac opened this issue Jun 10, 2023 · 1 comment
Open

proposal: crypto/x509: Add support for PKCS#10 attributes #60718

dachaac opened this issue Jun 10, 2023 · 1 comment
Labels
Proposal Proposal-Crypto Proposal related to crypto packages or other security issues
Milestone

Comments

@dachaac
Copy link

dachaac commented Jun 10, 2023

Certificate signing requests also feature other attributes than Extensions.

There are protocols like RFC 7030: Enrollment over Secure Transport (EST) and RFC RFC 8894: Simple Certificate Enrolment Protocol that supports usage of 'challengePassword' attribute.

There are also other attributes that some party might be needing to use. Example attributes can be found from PKCS #9: Selected Object Classes and Attribute Types Version 2.0 (including specification for challengePassword attribute).

Currently it is a bit hard to access this information from application code. This requires copying parts of the src/crypto/x509/x509.go into your own application and then modifying them in order to access the details. One needs to access RawTBSCertificateRequest and from there RawAttributes and then do ASN.1 parsing.

There exists x509.parseRawAttributes() function to parse PKCS#10 attributes into CertificateRequest.Attributes but that cannot handle (as commented) the "simple" attributes. CertificateRequest.Attributes also has been marked as deprecated in favor of CertificateRequest.Extensions.

There is also old issue #15995 describing some workarounds for accessing the information.

Instead of having those local hacks the proposal here is to export the needed information.

In order not to break previous software that might be using those fields new field and struct is proposed to be added.

Proposed API change is:

diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go
index 9d80b1d8ba..1e5220539e 100644
--- a/src/crypto/x509/x509.go
+++ b/src/crypto/x509/x509.go
@@ -1794,6 +1794,9 @@ type CertificateRequest struct {
        // generating the requestedExtensions attribute.
        Attributes []pkix.AttributeTypeAndValueSET
 
+       // Pkcs10Attributes contains the CSR attributes that are not pkix.Extension's
+       Pkcs10Attributes []Pkcs10Attribute
+
        // Extensions contains all requested extensions, in raw form. When parsing
        // CSRs, this can be used to extract extensions that are not parsed by this
        // package.
@@ -1815,6 +1818,12 @@ type CertificateRequest struct {
        URIs           []*url.URL
 }
 
+// Pkcs10Attribute reflects the Attribute structure from RFC 2986, Section 4.1.
+type Pkcs10Attribute struct {
+       Id     asn1.ObjectIdentifier
+       Values []asn1.RawValue `asn1:"set"`
+}
+
 // These structures reflect the ASN.1 structure of X.509 certificate
 // signature requests (see RFC 2986):
 

Structure pkcs10Attribute from x509.parseCSRExtensions() is now promoted to be exported as x509.Pkcs10Attribute

Then access for in example for challengePassword would be:

var oidChallengePassword = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 7}

func GetChallengePassword(request *x509.CertificateRequest) (string, error) {
	var challengePassword string

	for _, pkcs10attribute := range request.Pkcs10Attributes {
		switch {
		case pkcs10attribute.Id.Equal(oidChallengePassword):
			_, err := asn1.Unmarshal(pkcs10attribute.Values[0].FullBytes, &challengePassword)
			if err != nil {
				return "", err
			}
			return challengePassword, nil
		}
	}

	return "", nil
}

There is pkix.AttributeTypeAndValue and that has been proposed for this use but that is missing value type and asn1 parser guidance.

Note: it might be a good idea to have OID registry available as API for easier access for different attributes. In example x509.OidChallengePassword could be defined in the library.

Alternative implementation could be to add CertificateRequest.ChallengePassowrd to give access for the needed challengePassowrd value.

In here there was only example for using it (as that was the present need) but there should also be support for creating the certificate signing request with the challengePassword.

@gopherbot gopherbot added this to the Proposal milestone Jun 10, 2023
@seankhliao seankhliao added the Proposal-Crypto Proposal related to crypto packages or other security issues label Jun 10, 2023
@ianlancetaylor
Copy link
Contributor

CC @golang/security

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Proposal Proposal-Crypto Proposal related to crypto packages or other security issues
Projects
Status: Incoming
Development

No branches or pull requests

4 participants