package x509
import (
)
const ecPrivKeyVersion = 1
type ecPrivateKey struct {
Version int
PrivateKey []byte
NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"`
PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"`
}
func ( []byte) (*ecdsa.PrivateKey, error) {
return parseECPrivateKey(nil, )
}
func ( *ecdsa.PrivateKey) ([]byte, error) {
, := oidFromNamedCurve(.Curve)
if ! {
return nil, errors.New("x509: unknown elliptic curve")
}
return marshalECPrivateKeyWithOID(, )
}
func ( *ecdsa.PrivateKey, asn1.ObjectIdentifier) ([]byte, error) {
:= make([]byte, (.Curve.Params().N.BitLen()+7)/8)
return asn1.Marshal(ecPrivateKey{
Version: 1,
PrivateKey: .D.FillBytes(),
NamedCurveOID: ,
PublicKey: asn1.BitString{Bytes: elliptic.Marshal(.Curve, .X, .Y)},
})
}
func ( *asn1.ObjectIdentifier, []byte) ( *ecdsa.PrivateKey, error) {
var ecPrivateKey
if , := asn1.Unmarshal(, &); != nil {
if , := asn1.Unmarshal(, &pkcs8{}); == nil {
return nil, errors.New("x509: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)")
}
if , := asn1.Unmarshal(, &pkcs1PrivateKey{}); == nil {
return nil, errors.New("x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)")
}
return nil, errors.New("x509: failed to parse EC private key: " + .Error())
}
if .Version != ecPrivKeyVersion {
return nil, fmt.Errorf("x509: unknown EC private key version %d", .Version)
}
var elliptic.Curve
if != nil {
= namedCurveFromOID(*)
} else {
= namedCurveFromOID(.NamedCurveOID)
}
if == nil {
return nil, errors.New("x509: unknown elliptic curve")
}
:= new(big.Int).SetBytes(.PrivateKey)
:= .Params().N
if .Cmp() >= 0 {
return nil, errors.New("x509: invalid elliptic curve private key value")
}
:= new(ecdsa.PrivateKey)
.Curve =
.D =
:= make([]byte, (.BitLen()+7)/8)
for len(.PrivateKey) > len() {
if .PrivateKey[0] != 0 {
return nil, errors.New("x509: invalid private key length")
}
.PrivateKey = .PrivateKey[1:]
}
copy([len()-len(.PrivateKey):], .PrivateKey)
.X, .Y = .ScalarBaseMult()
return , nil
}