github.com/yoctocloud/packer@v0.6.2-0.20160520224004-e11a0a18423f/builder/azure/pkcs12/pkcs8.go (about) 1 package pkcs12 2 3 import ( 4 "crypto/ecdsa" 5 "crypto/rsa" 6 "crypto/x509" 7 "crypto/x509/pkix" 8 "encoding/asn1" 9 "errors" 10 ) 11 12 // pkcs8 reflects an ASN.1, PKCS#8 PrivateKey. See 13 // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn 14 // and RFC5208. 15 type pkcs8 struct { 16 Version int 17 Algo pkix.AlgorithmIdentifier 18 PrivateKey []byte 19 // optional attributes omitted. 20 } 21 22 var ( 23 oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} 24 oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1} 25 26 nullAsn = asn1.RawValue{Tag: 5} 27 ) 28 29 // marshalPKCS8PrivateKey converts a private key to PKCS#8 encoded form. 30 // See http://www.rsa.com/rsalabs/node.asp?id=2130 and RFC5208. 31 func marshalPKCS8PrivateKey(key interface{}) (der []byte, err error) { 32 pkcs := pkcs8{ 33 Version: 0, 34 } 35 36 switch key := key.(type) { 37 case *rsa.PrivateKey: 38 pkcs.Algo = pkix.AlgorithmIdentifier{ 39 Algorithm: oidPublicKeyRSA, 40 Parameters: nullAsn, 41 } 42 pkcs.PrivateKey = x509.MarshalPKCS1PrivateKey(key) 43 case *ecdsa.PrivateKey: 44 bytes, err := x509.MarshalECPrivateKey(key) 45 if err != nil { 46 return nil, errors.New("x509: failed to marshal to PKCS#8: " + err.Error()) 47 } 48 49 pkcs.Algo = pkix.AlgorithmIdentifier{ 50 Algorithm: oidPublicKeyECDSA, 51 Parameters: nullAsn, 52 } 53 pkcs.PrivateKey = bytes 54 default: 55 return nil, errors.New("x509: PKCS#8 only RSA and ECDSA private keys supported") 56 } 57 58 bytes, err := asn1.Marshal(pkcs) 59 if err != nil { 60 return nil, errors.New("x509: failed to marshal to PKCS#8: " + err.Error()) 61 } 62 63 return bytes, nil 64 }