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/pkix: Name.String() hex-encodes string-type ExtraNames #33093

Open
rittneje opened this issue Jul 13, 2019 · 15 comments
Open

crypto/x509/pkix: Name.String() hex-encodes string-type ExtraNames #33093

rittneje opened this issue Jul 13, 2019 · 15 comments
Assignees
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@rittneje
Copy link

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.

@dmitshur
Copy link
Contributor

/cc @FiloSottile

@dmitshur dmitshur added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jul 15, 2019
@dmitshur dmitshur added this to the Go1.14 milestone Jul 15, 2019
@FiloSottile
Copy link
Contributor

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?

@FiloSottile FiloSottile modified the milestones: Go1.14, Unplanned Oct 1, 2019
@rittneje
Copy link
Author

rittneje commented Oct 2, 2019

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.

@rittneje
Copy link
Author

@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

@rittneje
Copy link
Author

ping @FiloSottile

@rittneje
Copy link
Author

@FiloSottile Is this something you will consider fixing, given what I mentioned?

@rittneje
Copy link
Author

@FiloSottile is there someone else I should CC?

@bjanders
Copy link

bjanders commented Apr 21, 2022

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 #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

@rittneje
Copy link
Author

cc @rolandshoemaker

@rittneje
Copy link
Author

ping @FiloSottile

@bjanders
Copy link

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.

@FiloSottile
Copy link
Contributor

Thanks @bjanders for doing the spec analysis in #33093 (comment), I think you're right and I was interpreting it wrong. We can probably get this into Go 1.21.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/549075 mentions this issue: crypto/x509/pkix: ensure Name.String correctly prints ASN1 printable strings

@odeke-em
Copy link
Member

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.

@odeke-em odeke-em self-assigned this Dec 12, 2023
@odeke-em
Copy link
Member

Kind ping @rolandshoemaker @FiloSottile and others, I did mail a fix for this issue in CL https://go-review.googlesource.com/c/go/+/549075

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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