From deb19c2fa306a75cdc666d08abdfa86e9e963678 Mon Sep 17 00:00:00 2001 From: David Hill Date: Tue, 19 Nov 2013 15:57:24 -0500 Subject: [PATCH] Bring MarshalECPrivateKey local so < go1.2 works. Closes #45. --- ofc.go | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ rpcserver.go | 2 +- 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 ofc.go diff --git a/ofc.go b/ofc.go new file mode 100644 index 00000000..6efd5fa8 --- /dev/null +++ b/ofc.go @@ -0,0 +1,60 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the Golang LICENSE file. + +package main + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "encoding/asn1" + "errors" +) + +// ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure. +// References: +// RFC5915 +// SEC1 - http://www.secg.org/download/aid-780/sec1-v2.pdf +// Per RFC5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in +// most cases it is not. +type ecPrivateKey struct { + Version int + PrivateKey []byte + NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"` + PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"` +} + +var ( + oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33} + oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7} + oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34} + oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35} +) + +func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) { + switch curve { + case elliptic.P224(): + return oidNamedCurveP224, true + case elliptic.P256(): + return oidNamedCurveP256, true + case elliptic.P384(): + return oidNamedCurveP384, true + case elliptic.P521(): + return oidNamedCurveP521, true + } + + return nil, false +} + +func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) { + oid, ok := oidFromNamedCurve(key.Curve) + if !ok { + return nil, errors.New("x509: unknown elliptic curve") + } + return asn1.Marshal(ecPrivateKey{ + Version: 1, + PrivateKey: key.D.Bytes(), + NamedCurveOID: oid, + PublicKey: asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)}, + }) +} diff --git a/rpcserver.go b/rpcserver.go index db0672b0..599ed93b 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -390,7 +390,7 @@ func genKey(key, cert string) error { os.Remove(cert) return err } - keybytes, err := x509.MarshalECPrivateKey(priv) + keybytes, err := MarshalECPrivateKey(priv) if err != nil { os.Remove(key) os.Remove(cert)