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

crypto/x509: unable to parse CertificateRequest SAN otherName field #26093

Closed
medzin opened this issue Jun 27, 2018 · 5 comments
Closed

crypto/x509: unable to parse CertificateRequest SAN otherName field #26093

medzin opened this issue Jun 27, 2018 · 5 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@medzin
Copy link
Contributor

medzin commented Jun 27, 2018

ParseCertificateRequest function is unable to parse CSR with otherName field in SAN. It actually destroys the data that is in this field. Consider the following code:

package main

import (
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"log"
)

// content of the CSR otherName field
// openssl asn1parse -in csr -strparse 381
//     0:d=0  hl=2 l=  63 cons: SEQUENCE
//     2:d=1  hl=2 l=  13 prim: cont [ 2 ]
//    17:d=1  hl=2 l=  14 prim: cont [ 2 ]
//    33:d=1  hl=2 l=  12 prim: cont [ 2 ]
//    47:d=1  hl=2 l=  16 cons: cont [ 0 ]
//    49:d=2  hl=2 l=   6 prim: OBJECT            :1.3.6.1.4.1.1
//    57:d=2  hl=2 l=   6 cons: cont [ 0 ]
//    59:d=3  hl=2 l=   4 prim: UTF8STRING        :test

var csrPEM = []byte(`-----BEGIN CERTIFICATE REQUEST-----
MIIC0DCCAbgCAQAwMDELMAkGA1UEBhMCUEwxDjAMBgNVBAgMBVN0YXRlMREwDwYD
VQQHDAhMb2NhbGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMb7
NQIEJwh6nnlgWHXUTG14bhngAx9j0g/KOe2c9YIoztsDIK4YIToO0YJE20hftw+7
/DNnVvVBPMEh1u8sxv4EeMgHMex9P6N0yRjt51IDSOEv8LbEqOTikYsakgeYCxgx
3HkJZ71UY9qcH/TV/c5yJY9+jTjo+dwbMlHHw17wgeZjr3XKnMGnvqffI+1OGd4W
9q9ii3rV8sxrCPB62dQejOUukv3XZv0HFAqIW4pupd8BHOw6QwSl2N5XLo7v+oXy
JqimbECl9CntrTZYctwl2TJC3dzF1x56F3uGZpmleVuhCxuiHw0JadUIgl++svqy
5l3fsD+VNMnw8EFFGp8CAwEAAaBbMFkGCSqGSIb3DQEJDjFMMEowSAYDVR0RBEEw
P4INYmVzdGZsYXJlLmNvbYIOdXNlZnVscmVhZC5jb22CDGNoYW5kYW5rLmNvbaAQ
BgYrBgEEAQGgBgwEdGVzdDANBgkqhkiG9w0BAQsFAAOCAQEAbnuY6uLK48LgLv2d
PEUkUsjFUHMq0POetV3xUFOCdgK8KVORKPp247If+H/I+mEmiZ6SOswe3rVkWt/0
aNW86123kdM0oyrgtYKTJe246DQDof1mrhmPxtgUglc6nIi/nHczJdujIRmoUu3u
GQD2YmKNrZbzgMglJeDXThjYEktOxML6kJzmhF4ASp4ZH5HkEJOsP0z6HTMeTGhs
d6QUfgwXqZPxb1ksR+27YIxSts8ddBFooMU3155d0O81TC+YEThXikyZX9QdxyM/
mJY+ytNvc8wStYbPVubpcww/YZl7re+k9FnTyXwjZttx8MrxvSibUjrljxIzlqGp
lV30FA==
-----END CERTIFICATE REQUEST-----`)

func main() {
	block, _ := pem.Decode(csrPEM)
	csr, err := x509.ParseCertificateRequest(block.Bytes)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s", csr.Extensions[0].Id)    // prints "2.5.29.17", why?
	fmt.Printf("%s", csr.Extensions[0].Value) // prints "test", but sometimes it adds random bytes
}

https://play.golang.org/p/ZWer4GnOM2d

I would expect here to get an Id equal to 0, indicating that this is otherName extension, and at least the whole otherName content (with OID and so on) in Value to be parsed in my code.

@bcmills
Copy link
Contributor

bcmills commented Jun 28, 2018

CC: @FiloSottile @agl

@bcmills bcmills added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jun 28, 2018
@bcmills bcmills added this to the Go1.12 milestone Jun 28, 2018
@agl
Copy link
Contributor

agl commented Jun 28, 2018

Extensions contains all extensions, of which SAN is only one. Id contains that OID because that's the identifier for a SAN extension: http://oid-info.com/get/2.5.29.17. The Value will be the DER-encoded bytes of a SubjectAltName structure.

@medzin
Copy link
Contributor Author

medzin commented Jun 28, 2018

Ok, but where is the OID part of otherName (more precisely the 3.6.1.4.1.1 id)? In the Value I only see "test".

@ncabatoff
Copy link

@medzin this is how you extract it: https://play.golang.org/p/mzxzkKcMz-z

@FiloSottile
Copy link
Contributor

This is working correctly, in Extensions you'll find the whole 2.5.29.17 subjectAltName, and if you want to extract parts that are not parsed by the library you can use encoding/asn1.

@golang golang locked and limited conversation to collaborators Feb 5, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

6 participants