github.phpd.cn/hashicorp/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  }