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 type does preserve order of multi valued fields. #45882

Closed
databus23 opened this issue Apr 30, 2021 · 4 comments
Closed
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@databus23
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.16.3 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="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16.3"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3048100567=/tmp/go-build -gno-record-gcc-switches"

What did you do?

When I create a certificate with multiple elements for OrganizationalUnit and parse it, the order is not preserved in recent versions of go (1.15 and 1.16). It seems to me in newer versions of go the length of the individual values changes the ordering as if the values are now sorted by length. This was not the case for go < 1.15

Example Code:

package main

import (
	cryptorand "crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"crypto/x509/pkix"
	"log"
	"math/big"
)

func main() {

	privateKey, err := rsa.GenerateKey(cryptorand.Reader, 2048)
	if err != nil {
		if err != nil {
			log.Fatal(err)
		}
	}

	tmpl := x509.Certificate{
		SerialNumber: new(big.Int).SetInt64(0),
		Subject: pkix.Name{
			CommonName:         "whatever",
			OrganizationalUnit: []string{"AA", "BBB", "C"},
		},
	}
	log.Println("OU IN: ", tmpl.Subject.OrganizationalUnit)

	certDERBytes, err := x509.CreateCertificate(cryptorand.Reader, &tmpl, &tmpl, privateKey.Public(), privateKey)
	if err != nil {
		log.Fatalf("Failed to create certificate for CA: %s", err)

	}
	certificate, err := x509.ParseCertificate(certDERBytes)
	if err != nil {
		log.Fatalf("Failed to parse cert for CA: %s", err)
	}
	log.Println("OU OUT:", certificate.Subject.OrganizationalUnit)
}

What did you expect to see?

I expect the order of multiple values in the certificate subject to stay consistent across go versions.

What did you see instead?

$> docker run -v $PWD:/tmp golang:1.12-alpine go run /tmp/main.go
2021/04/30 11:21:37 OU IN:  [AA BBB C]
2021/04/30 11:21:37 OU OUT: [AA BBB C]
$> docker run -v $PWD:/tmp golang:1.13-alpine go run /tmp/main.go
2021/04/30 11:21:37 OU IN:  [AA BBB C]
2021/04/30 11:21:37 OU OUT: [AA BBB C]
$> docker run -v $PWD:/tmp golang:1.14-alpine go run /tmp/main.go
2021/04/30 11:21:37 OU IN:  [AA BBB C]
2021/04/30 11:21:37 OU OUT: [AA BBB C]
$> docker run -v $PWD:/tmp golang:1.15-alpine go run /tmp/main.go
2021/04/30 11:23:17 OU IN:  [AA BBB C]
2021/04/30 11:23:17 OU OUT: [C AA BBB]
$> docker run -v $PWD:/tmp golang:1.16-alpine go run /tmp/main.g
2021/04/30 11:23:34 OU IN:  [AA BBB C]
2021/04/30 11:23:34 OU OUT: [C AA BBB]
@cherrymui cherrymui added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Apr 30, 2021
@cherrymui cherrymui added this to the Backlog milestone Apr 30, 2021
@cherrymui
Copy link
Member

cc @FiloSottile @agl @katiehockman @rolandshoemaker

(It is not clear to me from documentation that the order is preserved. But I'm not familiar with this.)

@katiehockman
Copy link
Contributor

I believe this is intended behavior. See the documentation for pkix.Name:

Note that Name is only an approximation of the X.509 structure. If an accurate representation is needed, asn1.Unmarshal the raw subject or issuer as an RDNSequence.

@oncilla
Copy link

oncilla commented May 3, 2021

I think this might be a side effect of f0cea84

The order is most likely not preserved when creating the certificate. Unmarshalling to the RDNSequence will not help in that case

@rolandshoemaker
Copy link
Member

This is working as intended. The RelativeDistinguishedName ASN.1 object is a SET, and SETs have a required ordering when encoded as DER.

Is there a problem you are running into that requires a specific ordering of subject components?

databus23 added a commit to sapcc/kubernikus that referenced this issue Jul 28, 2021
The order of multiplie values in x509 subjects becaume unreliable
golang/go#45882
@golang golang locked and limited conversation to collaborators Apr 22, 2023
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