github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/tls/resource_private_key.go (about)

     1  package tls
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"crypto/elliptic"
     6  	"crypto/rand"
     7  	"crypto/rsa"
     8  	"crypto/x509"
     9  	"encoding/pem"
    10  	"fmt"
    11  
    12  	"github.com/hashicorp/terraform/helper/schema"
    13  )
    14  
    15  type keyAlgo func(d *schema.ResourceData) (interface{}, error)
    16  type keyParser func([]byte) (interface{}, error)
    17  
    18  var keyAlgos map[string]keyAlgo = map[string]keyAlgo{
    19  	"RSA": func(d *schema.ResourceData) (interface{}, error) {
    20  		rsaBits := d.Get("rsa_bits").(int)
    21  		return rsa.GenerateKey(rand.Reader, rsaBits)
    22  	},
    23  	"ECDSA": func(d *schema.ResourceData) (interface{}, error) {
    24  		curve := d.Get("ecdsa_curve").(string)
    25  		switch curve {
    26  		case "P224":
    27  			return ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
    28  		case "P256":
    29  			return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    30  		case "P384":
    31  			return ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
    32  		case "P521":
    33  			return ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
    34  		default:
    35  			return nil, fmt.Errorf("invalid ecdsa_curve; must be P224, P256, P384 or P521")
    36  		}
    37  	},
    38  }
    39  
    40  var keyParsers map[string]keyParser = map[string]keyParser{
    41  	"RSA": func(der []byte) (interface{}, error) {
    42  		return x509.ParsePKCS1PrivateKey(der)
    43  	},
    44  	"ECDSA": func(der []byte) (interface{}, error) {
    45  		return x509.ParseECPrivateKey(der)
    46  	},
    47  }
    48  
    49  func resourcePrivateKey() *schema.Resource {
    50  	return &schema.Resource{
    51  		Create: CreatePrivateKey,
    52  		Delete: DeletePrivateKey,
    53  		Read:   ReadPrivateKey,
    54  
    55  		Schema: map[string]*schema.Schema{
    56  			"algorithm": &schema.Schema{
    57  				Type:        schema.TypeString,
    58  				Required:    true,
    59  				Description: "Name of the algorithm to use to generate the private key",
    60  				ForceNew:    true,
    61  			},
    62  
    63  			"rsa_bits": &schema.Schema{
    64  				Type:        schema.TypeInt,
    65  				Optional:    true,
    66  				Description: "Number of bits to use when generating an RSA key",
    67  				ForceNew:    true,
    68  				Default:     2048,
    69  			},
    70  
    71  			"ecdsa_curve": &schema.Schema{
    72  				Type:        schema.TypeString,
    73  				Optional:    true,
    74  				Description: "ECDSA curve to use when generating a key",
    75  				ForceNew:    true,
    76  				Default:     "P224",
    77  			},
    78  
    79  			"private_key_pem": &schema.Schema{
    80  				Type:     schema.TypeString,
    81  				Computed: true,
    82  			},
    83  		},
    84  	}
    85  }
    86  
    87  func CreatePrivateKey(d *schema.ResourceData, meta interface{}) error {
    88  	keyAlgoName := d.Get("algorithm").(string)
    89  	var keyFunc keyAlgo
    90  	var ok bool
    91  	if keyFunc, ok = keyAlgos[keyAlgoName]; !ok {
    92  		return fmt.Errorf("invalid key_algorithm %#v", keyAlgoName)
    93  	}
    94  
    95  	key, err := keyFunc(d)
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	var keyPemBlock *pem.Block
   101  	switch k := key.(type) {
   102  	case *rsa.PrivateKey:
   103  		keyPemBlock = &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
   104  	case *ecdsa.PrivateKey:
   105  		b, err := x509.MarshalECPrivateKey(k)
   106  		if err != nil {
   107  			return fmt.Errorf("error encoding key to PEM: %s", err)
   108  		}
   109  		keyPemBlock = &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
   110  	default:
   111  		return fmt.Errorf("unsupported private key type")
   112  	}
   113  	keyPem := string(pem.EncodeToMemory(keyPemBlock))
   114  
   115  	pubKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey(key))
   116  	if err != nil {
   117  		return fmt.Errorf("failed to marshal public key: %s", err)
   118  	}
   119  
   120  	d.SetId(hashForState(string((pubKeyBytes))))
   121  	d.Set("private_key_pem", keyPem)
   122  
   123  	return nil
   124  }
   125  
   126  func DeletePrivateKey(d *schema.ResourceData, meta interface{}) error {
   127  	d.SetId("")
   128  	return nil
   129  }
   130  
   131  func ReadPrivateKey(d *schema.ResourceData, meta interface{}) error {
   132  	return nil
   133  }
   134  
   135  func publicKey(priv interface{}) interface{} {
   136  	switch k := priv.(type) {
   137  	case *rsa.PrivateKey:
   138  		return &k.PublicKey
   139  	case *ecdsa.PrivateKey:
   140  		return &k.PublicKey
   141  	default:
   142  		return nil
   143  	}
   144  }