OLD | NEW |
(Empty) | |
| 1 // Copyright 2012 The Go Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style |
| 3 // license that can be found in the LICENSE file. |
| 4 |
| 5 package x509 |
| 6 |
| 7 import ( |
| 8 "crypto/ecdsa" |
| 9 "crypto/elliptic" |
| 10 "encoding/asn1" |
| 11 "errors" |
| 12 "fmt" |
| 13 "math/big" |
| 14 ) |
| 15 |
| 16 const ecPrivKeyVersion = 1 |
| 17 |
| 18 // ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure. |
| 19 // References: |
| 20 // RFC5915 |
| 21 // SEC1 - http://www.secg.org/download/aid-780/sec1-v2.pdf |
| 22 // Per RFC5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in |
| 23 // most cases it is not. |
| 24 type ecPrivateKey struct { |
| 25 Version int |
| 26 PrivateKey []byte |
| 27 NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"` |
| 28 PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"` |
| 29 } |
| 30 |
| 31 // ParseSEC1PrivateKey parses a SEC1 DER encoded ECPrivateKey structure. |
| 32 func ParseSEC1PrivateKey(der []byte) (key *ecdsa.PrivateKey, err error) { |
| 33 var oid asn1.ObjectIdentifier |
| 34 if der, err = asn1.Unmarshal(der, &oid); err != nil { |
| 35 return nil, errors.New("crypto/x509: failed to parse SEC1 privat
e key: " + err.Error()) |
| 36 } |
| 37 return parseECPrivateKey(nil, der) |
| 38 } |
| 39 |
| 40 // ParseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure. |
| 41 func ParseECPrivateKey(der []byte) (key *ecdsa.PrivateKey, err error) { |
| 42 return parseECPrivateKey(nil, der) |
| 43 } |
| 44 |
| 45 // parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure. |
| 46 // The OID for the named curve may be provided from another source (such as |
| 47 // the PKCS8 container) - if it is provided then use this instead of the OID |
| 48 // that may exist in the EC private key structure. |
| 49 func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *e
cdsa.PrivateKey, err error) { |
| 50 var privKey ecPrivateKey |
| 51 if _, err := asn1.Unmarshal(der, &privKey); err != nil { |
| 52 return nil, errors.New("crypto/x509: failed to parse EC private
key: " + err.Error()) |
| 53 } |
| 54 if privKey.Version != ecPrivKeyVersion { |
| 55 return nil, fmt.Errorf("crypto/x509: unknown EC private key vers
ion %d", privKey.Version) |
| 56 } |
| 57 |
| 58 var curve elliptic.Curve |
| 59 if namedCurveOID != nil { |
| 60 curve = namedCurveFromOID(*namedCurveOID) |
| 61 } else { |
| 62 curve = namedCurveFromOID(privKey.NamedCurveOID) |
| 63 } |
| 64 if curve == nil { |
| 65 return nil, errors.New("crypto/x509: unknown elliptic curve") |
| 66 } |
| 67 |
| 68 k := new(big.Int).SetBytes(privKey.PrivateKey) |
| 69 if k.Cmp(curve.Params().N) >= 0 { |
| 70 return nil, errors.New("crypto/x509: invalid elliptic curve priv
ate key value") |
| 71 } |
| 72 priv := new(ecdsa.PrivateKey) |
| 73 priv.Curve = curve |
| 74 priv.D = k |
| 75 priv.X, priv.Y = curve.ScalarBaseMult(privKey.PrivateKey) |
| 76 |
| 77 return priv, nil |
| 78 } |
OLD | NEW |