Skip to content

encoding/asn1, crypto/x509: failed to parse Intermediate CA certificate #38737

Open
@sebastien-rosset

Description

A intermediate CA certificate contains X.509 certificate policy extension with OID 1.2.36.67006527840.666.66.1.1. The fourth oid (67006527840) in that extension is greater than math.MaxInt32, which causes a certificate unmarshaling error. Specifically the error occurs in the asn1.Unmarshal function while trying to unmarshal the certificate policy extension.

The CA cert has been issued by an Internet provider in New Zealand. I am not affiliated with the certifucate authority, and I don't know how that OID was assigned. I cannot force the CA to issue a new CA cert with sub-OIDs that have a value lower than math.MaxInt32; to the best of my understanding there is nothing in the ASN.1 spec that states sub-oids must be lower than 2^31 - 1. I've been able to successfully load the CA certificate using openssl, macOS key chain, and browsers.

I understand it may be challenging to change type ObjectIdentifier []int, but it's also not a good long term option to close this issue.

I saw related issues #30757, #19933, #36881. It looks like in practice there are certificates that have OID values higher than 2^31 - 1. So the reality is golang is unable to process some legitimate certificates.

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

go version go1.14.2 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/serosset/.cache/go-build"
GOENV="/home/serosset/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/serosset/goroot"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
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-build216516397=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Parse CA certificate:
https://play.golang.org/p/StRBpHZhgDM

Issue narrowed to parsing issue of ASN.1 object identifier:

  1. Encode the ASN.1 Object Identifier 1.2.36.67006527840.666.66.1.1 in DER format using the golang asn1.Marshal function.
  2. Manually verify the DER encoded data is correct. I used 2 different Linux tools to compare the ASN.1 DER encoding with what is produced by asn1.Marshal.
  3. Take the ASN.1 DER encoded byte array and call asn1.Unmarshal.

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

What did you expect to see?

Unmarshal in step (3) should succeed and the same original object identifier should have been retrieved.

Until a long term fix is determined, maybe the golang asn1 (and x509) package documentation should explicitly mention the implementation is not fully compliant with ITU-T Rec X.690, i.e. object identifiers cannot have values higher than 2^31-1. Also, the error message when parsing a certificate is very low-level and does not provide context: asn1: structure error: base 128 integer too large.

What did you see instead?

Step (3) is failing. asn1.Unmarshal fails with error asn1: structure error: base 128 integer too large

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions