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