What version of Go are you using (go version
)?
$ go version go version go1.12.6 linux/amd64
Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GOARCH="amd64" GOBIN="" GOCACHE="/home/jrittner/.cache/go-build" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOOS="linux" GOPATH="/home/jrittner/go-workspace" GOPROXY="" GORACE="" GOROOT="/home/jrittner/go" GOTMPDIR="" GOTOOLDIR="/home/jrittner/go/pkg/tool/linux_amd64" GCCGO="gccgo" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build691331496=/tmp/go-build -gno-record-gcc-switches"
What did you do?
I created a pkix.Name containing a custom ExtraName, and converted it to a string.
https://play.golang.org/p/1hyqwP_RTBs
What did you expect to see?
1.2.3.4=sample,CN=foobar
What did you see instead?
1.2.3.4=#130673616d706c65,CN=foobar
This is because Go always hex-encodes the asn.1 encoding of the value, even though RFC 2253 states that the value is supposed to just be used as its own string encoding. https://tools.ietf.org/html/rfc2253#section-2.4
Otherwise, if the AttributeValue is of a type which has a string representation, the value is converted first to a UTF-8 string according to its syntax specification (see for example section 6 of [4]).
Note that OpenSSL gives the expected output when viewing a certificate or CSR with a custom name.
Comment From: dmitshur
/cc @FiloSottile
Comment From: FiloSottile
I read the previous spec paragraph as saying that this is the correct form when the type is unknown and expressed as a dotted decimal.
If the AttributeValue is of a type which does not have a string
representation defined for it, then it is simply encoded as an
octothorpe character ('#' ASCII 35) followed by the hexadecimal
representation of each of the bytes of the BER encoding of the X.500
AttributeValue. This form SHOULD be used if the AttributeType is of
the dotted-decimal form.
There is even an example for it in Section 5.
1.3.6.1.4.1.1466.0=#04024869,O=Test,C=GB
Can you provide an example certificate?
Comment From: rittneje
Here is a sample CSR:
-----BEGIN CERTIFICATE REQUEST-----
MIIBYTCBywIBADAiMQ8wDQYDVQQDEwZmb29iYXIxDzANBgMqAwQTBnNhbXBsZTCB
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtDs1ygEixq27qFrGGh4pXIbg5Q6U
kzNRLRVo4STAkYl6looxjPf7u77/6TwYAVnu6zT6VULf+lyk4g7l2AwnxfQ+a6V/
KBqvnMhNI8NbPfouqnqvJekTNUGhnAwfCgthZXuYywlJASsBKcudHwkk+MNJWBUQ
kCU1JyXsFyHdr1sCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4GBAHF/6Hin8itNP/Uv
JW3tvUCkxaFXmL2UjA6Ed+UM4AXnPqSpGXx3hgccOcRJD63uQnl/yUbcpo7xIdFk
i/m6v0HX/8aRHBFM6o8zO8ellcidP0a4K5TzBhbJv6Dpy4HJOPkHZ9Mzi6Dprwj2
0gX/y4r5wM5d0/oOXPHS5N1DgEiK
-----END CERTIFICATE REQUEST-----
OpenSSL shows the custom distinguished name as a string:
$ openssl req -in sample.csr -subject -noout
subject=/CN=foobar/1.2.3.4=sample
The OpenSSL output is preferable over the current Go output because it is human readable.
Comment From: rittneje
@FiloSottile Wanted to follow up on this.
The example you copied is specifically for an "octet string", hence the 04
prefix. However, the custom DN in my example is actually a "printable string", hence the 13
prefix. It should thus be used as its own string representation
Comment From: rittneje
ping @FiloSottile
Comment From: rittneje
@FiloSottile Is this something you will consider fixing, given what I mentioned?
Comment From: rittneje
@FiloSottile is there someone else I should CC?
Comment From: bjanders
I agree with @rittneje . Here is a simple example. Create a certificate with openssl:
openssl req -new -x509 -subj '/UID=foobar/' -nodes -outform DER -out cert.crt
The ASN.1 structure of the Subject DN in cert.crt:
SEQUENCE (1 elem) SET (1 elem) SEQUENCE (2 elem) OBJECT IDENTIFIER 0.9.2342.19200300.100.1.1 userID UTF8String foobar
The type is UTF8String (not for example an octect string). Requoting @rittneje from RFC 2253:
Otherwise, if the AttributeValue is of a type which has a string representation, the value is converted first to a UTF-8 string according to its syntax specification (see for example section 6 of [4]).
UTF8String has a string representation and does not even need conversion, so it should be printed as:
0.9.2342.19200300.100.1.1=foobar
Not like go1.18.1 does:
0.9.2342.19200300.100.1.1=#1306666f6f626172
In https://github.com/golang/go/issues/39924 @FiloSottile says:
Unfortunately, we are bound to the RFC 2253 format by the docs and that format requires any non-standard attribute to be printed as a dotted OID and hex-encoded value.
But this is not what RFC 2253 says. RFC 2253 does not mention "non-standard attributes"; it says "does not have a string representation" which is a different thing:
If the AttributeValue is of a type which does not have a string representation defined for it, then it is simply encoded as an octothorpe character ('#' ASCII 35) followed by the hexadecimal representation
Comment From: rittneje
cc @rolandshoemaker
Comment From: rittneje
ping @FiloSottile
Comment From: bjanders
ping @FiloSottile
I don't think @FiloSottile is working on this project anymore. I guess the fastest way to fix this is to fix it ourselves and request a pull.
Comment From: FiloSottile
Thanks @bjanders for doing the spec analysis in https://github.com/golang/go/issues/33093#issuecomment-1105208529, I think you're right and I was interpreting it wrong. We can probably get this into Go 1.21.
Comment From: gopherbot
Change https://go.dev/cl/549075 mentions this issue: crypto/x509/pkix: ensure Name.String correctly prints ASN1 printable strings
Comment From: odeke-em
Thank you for the discourse @rittneje @FiloSottile @bjanders, I am working on triaging plus fixing issues and I just stumbled upon this issue and it nerd snipped me and I've gone through parts of the specification and to accomplish a probable working fix for this, I examined expectations for ASN1 printable strings per the quoted RFCs and I've mailed out CL https://go-review.googlesource.com/c/go/+/549075 which can be a start for the fix but otherwise moved to the Go1.23 milestone.
Comment From: odeke-em
Kind ping @rolandshoemaker @FiloSottile and others, I did mail a fix for this issue in CL https://go-review.googlesource.com/c/go/+/549075