summaryrefslogtreecommitdiff
path: root/src/pkg/crypto/x509
diff options
context:
space:
mode:
authorAdam Langley <agl@golang.org>2009-10-21 17:53:50 -0700
committerAdam Langley <agl@golang.org>2009-10-21 17:53:50 -0700
commit1d17e52f23e52266b918ee78728b89bf810487e9 (patch)
tree6554a5a4770adb29aaa65888d331d293a482f543 /src/pkg/crypto/x509
parent6c9d3b56326a5a6fe8b24439e85293506440e244 (diff)
downloadgolang-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/Makefile11
-rw-r--r--src/pkg/crypto/x509/x509.go63
-rw-r--r--src/pkg/crypto/x509/x509_test.go52
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"),
+}