github.com/zmap/zcrypto@v0.0.0-20240512203510-0fef58d9a9db/x509/pkcs8.go (about) 1 // Copyright 2011 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 "errors" 9 "fmt" 10 11 "github.com/zmap/zcrypto/encoding/asn1" 12 "github.com/zmap/zcrypto/x509/pkix" 13 ) 14 15 // pkcs8 reflects an ASN.1, PKCS#8 PrivateKey. See 16 // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn 17 // and RFC 5208. 18 type pkcs8 struct { 19 Version int 20 Algo pkix.AlgorithmIdentifier 21 PrivateKey []byte 22 // optional attributes omitted. 23 } 24 25 // ParsePKCS8PrivateKey parses an unencrypted, PKCS#8 private key. 26 // See RFC 5208. 27 func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) { 28 var privKey pkcs8 29 if _, err := asn1.Unmarshal(der, &privKey); err != nil { 30 return nil, err 31 } 32 switch { 33 case privKey.Algo.Algorithm.Equal(oidPublicKeyRSA): 34 key, err = ParsePKCS1PrivateKey(privKey.PrivateKey) 35 if err != nil { 36 return nil, errors.New("x509: failed to parse RSA private key embedded in PKCS#8: " + err.Error()) 37 } 38 return key, nil 39 40 case privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA): 41 bytes := privKey.Algo.Parameters.FullBytes 42 namedCurveOID := new(asn1.ObjectIdentifier) 43 if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil { 44 namedCurveOID = nil 45 } 46 key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey) 47 if err != nil { 48 return nil, errors.New("x509: failed to parse EC private key embedded in PKCS#8: " + err.Error()) 49 } 50 return key, nil 51 52 default: 53 return nil, fmt.Errorf("x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm) 54 } 55 }