diff options
author | Adam Langley <agl@golang.org> | 2009-10-21 17:53:50 -0700 |
---|---|---|
committer | Adam Langley <agl@golang.org> | 2009-10-21 17:53:50 -0700 |
commit | 1d17e52f23e52266b918ee78728b89bf810487e9 (patch) | |
tree | 6554a5a4770adb29aaa65888d331d293a482f543 /src/pkg/crypto/x509 | |
parent | 6c9d3b56326a5a6fe8b24439e85293506440e244 (diff) | |
download | golang-1d17e52f23e52266b918ee78728b89bf810487e9.tar.gz |
Add initial x509 code.
R=rsc
APPROVED=rsc
DELTA=659 (659 added, 0 deleted, 0 changed)
OCL=35932
CL=35975
Diffstat (limited to 'src/pkg/crypto/x509')
-rw-r--r-- | src/pkg/crypto/x509/Makefile | 11 | ||||
-rw-r--r-- | src/pkg/crypto/x509/x509.go | 63 | ||||
-rw-r--r-- | src/pkg/crypto/x509/x509_test.go | 52 |
3 files changed, 126 insertions, 0 deletions
diff --git a/src/pkg/crypto/x509/Makefile b/src/pkg/crypto/x509/Makefile new file mode 100644 index 000000000..98bf44acc --- /dev/null +++ b/src/pkg/crypto/x509/Makefile @@ -0,0 +1,11 @@ +# Copyright 2009 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +include $(GOROOT)/src/Make.$(GOARCH) + +TARG=crypto/x509 +GOFILES=\ + x509.go\ + +include $(GOROOT)/src/Make.pkg diff --git a/src/pkg/crypto/x509/x509.go b/src/pkg/crypto/x509/x509.go new file mode 100644 index 000000000..1997ec9a5 --- /dev/null +++ b/src/pkg/crypto/x509/x509.go @@ -0,0 +1,63 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// NOTE: PACKAGE UNDER CONSTRUCTION. +// +// This package parses X.509-encoded keys and certificates. +package x509 + +import ( + "asn1"; + "crypto/rsa"; + "os"; + big "gmp"; +) + +// pkcs1PrivateKey is a structure which mirrors the PKCS#1 ASN.1 for an RSA private key. +type pkcs1PrivateKey struct { + Version int; + N asn1.RawValue; + E int; + D asn1.RawValue; + P asn1.RawValue; + Q asn1.RawValue; +} + +// rawValueIsInteger returns true iff the given ASN.1 RawValue is an INTEGER type. +func rawValueIsInteger(raw *asn1.RawValue) bool { + return raw.Class == 0 && raw.Tag == 2 && raw.IsCompound == false; +} + +// ParsePKCS1PrivateKey returns an RSA private key from its ASN.1 PKCS#1 DER encoded form. +func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err os.Error) { + var priv pkcs1PrivateKey; + err = asn1.Unmarshal(&priv, der); + if err != nil { + return; + } + + if !rawValueIsInteger(&priv.N) || + !rawValueIsInteger(&priv.D) || + !rawValueIsInteger(&priv.P) || + !rawValueIsInteger(&priv.Q) { + err = asn1.StructuralError{"tags don't match"}; + return; + } + + key = &rsa.PrivateKey{ + PublicKey: rsa.PublicKey{ + E: priv.E, + N: new(big.Int).SetBytes(priv.N.Bytes), + }, + D: new(big.Int).SetBytes(priv.D.Bytes), + P: new(big.Int).SetBytes(priv.P.Bytes), + Q: new(big.Int).SetBytes(priv.Q.Bytes), + }; + + err = key.Validate(); + if err != nil { + return nil, err; + } + return; +} diff --git a/src/pkg/crypto/x509/x509_test.go b/src/pkg/crypto/x509/x509_test.go new file mode 100644 index 000000000..e5ca0f0f0 --- /dev/null +++ b/src/pkg/crypto/x509/x509_test.go @@ -0,0 +1,52 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +import ( + "crypto/rsa"; + "encoding/pem"; + "reflect"; + "strings"; + "testing"; + big "gmp"; +) + +func TestParsePKCS1PrivateKey(t *testing.T) { + block, _ := pem.Decode(strings.Bytes(pemPrivateKey)); + priv, err := ParsePKCS1PrivateKey(block.Bytes); + if err != nil { + t.Errorf("Failed to parse private key: %s", err); + } + if !reflect.DeepEqual(priv, rsaPrivateKey) { + t.Errorf("got:%+v want:%+v", priv, rsaPrivateKey); + } +} + +var pemPrivateKey = `-----BEGIN RSA PRIVATE KEY----- +MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0 +fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu +/ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu +RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/ +EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A +IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS +tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V +-----END RSA PRIVATE KEY----- +` + +func bigFromString(s string) *big.Int { + ret := new(big.Int); + ret.SetString(s, 10); + return ret; +} + +var rsaPrivateKey = &rsa.PrivateKey{ + PublicKey: rsa.PublicKey{ + N: bigFromString("9353930466774385905609975137998169297361893554149986716853295022578535724979677252958524466350471210367835187480748268864277464700638583474144061408845077"), + E: 65537, + }, + D: bigFromString("7266398431328116344057699379749222532279343923819063639497049039389899328538543087657733766554155839834519529439851673014800261285757759040931985506583861"), + P: bigFromString("98920366548084643601728869055592650835572950932266967461790948584315647051443"), + Q: bigFromString("94560208308847015747498523884063394671606671904944666360068158221458669711639"), +} |