...

Source file src/pkg/crypto/x509/sec1.go

     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	//   RFC 5915
    21	//   SEC1 - http://www.secg.org/sec1-v2.pdf
    22	// Per RFC 5915 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	// ParseECPrivateKey parses an EC public key in SEC 1, ASN.1 DER form.
    32	//
    33	// This kind of key is commonly encoded in PEM blocks of type "EC PUBLIC KEY".
    34	func ParseECPrivateKey(der []byte) (*ecdsa.PrivateKey, error) {
    35		return parseECPrivateKey(nil, der)
    36	}
    37	
    38	// MarshalECPrivateKey converts an EC private key to SEC 1, ASN.1 DER form.
    39	//
    40	// This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY".
    41	// For a more flexible key format which is not EC specific, use
    42	// MarshalPKCS8PrivateKey.
    43	func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) {
    44		oid, ok := oidFromNamedCurve(key.Curve)
    45		if !ok {
    46			return nil, errors.New("x509: unknown elliptic curve")
    47		}
    48	
    49		return marshalECPrivateKeyWithOID(key, oid)
    50	}
    51	
    52	// marshalECPrivateKey marshals an EC private key into ASN.1, DER format and
    53	// sets the curve ID to the given OID, or omits it if OID is nil.
    54	func marshalECPrivateKeyWithOID(key *ecdsa.PrivateKey, oid asn1.ObjectIdentifier) ([]byte, error) {
    55		privateKeyBytes := key.D.Bytes()
    56		paddedPrivateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8)
    57		copy(paddedPrivateKey[len(paddedPrivateKey)-len(privateKeyBytes):], privateKeyBytes)
    58	
    59		return asn1.Marshal(ecPrivateKey{
    60			Version:       1,
    61			PrivateKey:    paddedPrivateKey,
    62			NamedCurveOID: oid,
    63			PublicKey:     asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)},
    64		})
    65	}
    66	
    67	// parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure.
    68	// The OID for the named curve may be provided from another source (such as
    69	// the PKCS8 container) - if it is provided then use this instead of the OID
    70	// that may exist in the EC private key structure.
    71	func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *ecdsa.PrivateKey, err error) {
    72		var privKey ecPrivateKey
    73		if _, err := asn1.Unmarshal(der, &privKey); err != nil {
    74			if _, err := asn1.Unmarshal(der, &pkcs8{}); err == nil {
    75				return nil, errors.New("x509: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)")
    76			}
    77			if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil {
    78				return nil, errors.New("x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)")
    79			}
    80			return nil, errors.New("x509: failed to parse EC private key: " + err.Error())
    81		}
    82		if privKey.Version != ecPrivKeyVersion {
    83			return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version)
    84		}
    85	
    86		var curve elliptic.Curve
    87		if namedCurveOID != nil {
    88			curve = namedCurveFromOID(*namedCurveOID)
    89		} else {
    90			curve = namedCurveFromOID(privKey.NamedCurveOID)
    91		}
    92		if curve == nil {
    93			return nil, errors.New("x509: unknown elliptic curve")
    94		}
    95	
    96		k := new(big.Int).SetBytes(privKey.PrivateKey)
    97		curveOrder := curve.Params().N
    98		if k.Cmp(curveOrder) >= 0 {
    99			return nil, errors.New("x509: invalid elliptic curve private key value")
   100		}
   101		priv := new(ecdsa.PrivateKey)
   102		priv.Curve = curve
   103		priv.D = k
   104	
   105		privateKey := make([]byte, (curveOrder.BitLen()+7)/8)
   106	
   107		// Some private keys have leading zero padding. This is invalid
   108		// according to [SEC1], but this code will ignore it.
   109		for len(privKey.PrivateKey) > len(privateKey) {
   110			if privKey.PrivateKey[0] != 0 {
   111				return nil, errors.New("x509: invalid private key length")
   112			}
   113			privKey.PrivateKey = privKey.PrivateKey[1:]
   114		}
   115	
   116		// Some private keys remove all leading zeros, this is also invalid
   117		// according to [SEC1] but since OpenSSL used to do this, we ignore
   118		// this too.
   119		copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey)
   120		priv.X, priv.Y = curve.ScalarBaseMult(privateKey)
   121	
   122		return priv, nil
   123	}
   124	

View as plain text