Please answer these questions before submitting your issue. Thanks!
go version)?go version go1.9.2 linux/amd64
Yes.
go env)?GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/parazyd/go"
GORACE=""
GOROOT="/usr/lib/go"
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="x86_64-gentoo-linux-musl-gcc"
GOGCCFLAGS="-fPIC -m64 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build264632172=/tmp/go-build -gno-record-gcc-switches"
CXX="x86_64-gentoo-linux-musl-g++"
CGO_ENABLED="0"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
https://play.golang.org/p/MPAwSqN2e7
Running with the former key from the official(?) example found at https://golang.org/pkg/crypto/x509/#ParsePKIXPublicKey works fine. However, when trying the same with a 1024-bit RSA public key, the program panics, being unable to parse it.
pub is of type RSA:
panic: failed to parse DER encoded public key: asn1: structure error: tags don't match (16 vs {class:0 tag:2 length:129 isCompound:false}) {optional:false explicit:false application:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false} AlgorithmIdentifier @3
goroutine 1 [running]:
main.main()
/tmp/sandbox830663545/main.go:43 +0x3a0
The difference between both keys are not (only) the length of the prime of the rsa keys but the format. Only the first one is a PKIX key (asn1 sequence of AlgorithmIdentifier+BitString and the real key is in the BitString), the second key is a RSA public key (without the AlgorithmIdentifier).
You can see it that one is "-----BEGIN PUBLIC KEY-----", the other is "-----BEGIN RSA PUBLIC KEY-----".
@bpressure Removing "RSA" from the identifiers does not make a difference.
Of cause not, the RSA is an indicator that both keys are serialized in a different way.
The first one was serialized with
type pkixPublicKey struct {
Algo pkix.AlgorithmIdentifier
BitString asn1.BitString
}
the second one with
type PublicKey struct {
N *big.Int // modulus
E int // public exponent
}
This is working as intended, ParsePKIXPublicKey properly parses 1024-bit RSA keys that have an AlgorithmIdentifier and bitstring as @bpressure has explained.
This StackOverflow post also explains it in more detail.
Is there another way to parse such a key then?
@parazyd This issue tracker is not the place for questions, however I will say that you can use the encoding/asn1 package to parse keys that are encoded like that.
const pubPEM = `-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBALj23cgwEWD5R6P0SEqcOiKQkiIHaXuFKVZ3KEOb947ZRHqVPvB7It8V
0pZhit2nippBn7e7nUq/FjWVXsERyr98CYMoEWSwLv7rN7N4O0Evio8IPlK7maAG
rE0DPa61vTDm8qkJN1hYMQ0KQZYI2islND53N14NvOh8/lefIFsBAgMBAAE=
-----END RSA PUBLIC KEY-----`
block, _ := pem.Decode([]byte(pubPEM))
var pk rsa.PublicKey
asn1.Unmarshal(block.Bytes, &pk)
In Go 1.10, there will be a ParsePKCS1PublicKey that can do this. (They're rare, which is why the function hasn't existed prior to this. Normally they live inside a certificate.)
Most helpful comment
In Go 1.10, there will be a ParsePKCS1PublicKey that can do this. (They're rare, which is why the function hasn't existed prior to this. Normally they live inside a certificate.)