github.com/mmcquillan/packer@v1.1.1-0.20171009221028-c85cf0483a5d/builder/azure/common/lin/step_create_cert.go (about)

     1  package lin
     2  
     3  import (
     4  	"crypto/rand"
     5  	"crypto/rsa"
     6  	"crypto/sha1"
     7  	"crypto/x509"
     8  	"crypto/x509/pkix"
     9  	"encoding/pem"
    10  	"fmt"
    11  	"log"
    12  	"math/big"
    13  	"time"
    14  
    15  	"github.com/hashicorp/packer/builder/azure/common/constants"
    16  
    17  	"github.com/hashicorp/packer/packer"
    18  	"github.com/mitchellh/multistep"
    19  )
    20  
    21  type StepCreateCert struct {
    22  	TmpServiceName string
    23  }
    24  
    25  func (s *StepCreateCert) Run(state multistep.StateBag) multistep.StepAction {
    26  	ui := state.Get("ui").(packer.Ui)
    27  
    28  	ui.Say("Creating temporary certificate...")
    29  
    30  	err := s.createCert(state)
    31  	if err != nil {
    32  		err = fmt.Errorf("Error creating temporary certificate: %s", err)
    33  		state.Put("error", err)
    34  		ui.Error(err.Error())
    35  		return multistep.ActionHalt
    36  	}
    37  
    38  	return multistep.ActionContinue
    39  }
    40  
    41  func (s *StepCreateCert) Cleanup(state multistep.StateBag) {}
    42  
    43  func (s *StepCreateCert) createCert(state multistep.StateBag) error {
    44  
    45  	log.Println("createCert: Generating RSA key pair...")
    46  
    47  	priv, err := rsa.GenerateKey(rand.Reader, 2048)
    48  	if err != nil {
    49  		err = fmt.Errorf("Failed to Generate Private Key: %s", err)
    50  		return err
    51  	}
    52  
    53  	// ASN.1 DER encoded form
    54  	privkey := string(pem.EncodeToMemory(&pem.Block{
    55  		Type:  "RSA PRIVATE KEY",
    56  		Bytes: x509.MarshalPKCS1PrivateKey(priv),
    57  	}))
    58  
    59  	// Set the private key in the state bag for later
    60  	state.Put(constants.PrivateKey, privkey)
    61  	log.Printf("createCert: Private key:\n%s", privkey)
    62  
    63  	log.Println("createCert: Creating certificate...")
    64  
    65  	host := fmt.Sprintf("%s.cloudapp.net", s.TmpServiceName)
    66  	notBefore := time.Now()
    67  	notAfter := notBefore.Add(365 * 24 * time.Hour)
    68  
    69  	serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
    70  	if err != nil {
    71  		err = fmt.Errorf("Failed to Generate Serial Number: %v", err)
    72  		return err
    73  	}
    74  
    75  	template := x509.Certificate{
    76  		SerialNumber: serialNumber,
    77  		Issuer: pkix.Name{
    78  			CommonName: host,
    79  		},
    80  		Subject: pkix.Name{
    81  			CommonName: host,
    82  		},
    83  		NotBefore: notBefore,
    84  		NotAfter:  notAfter,
    85  
    86  		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
    87  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
    88  		BasicConstraintsValid: true,
    89  	}
    90  
    91  	derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
    92  	if err != nil {
    93  		err = fmt.Errorf("Failed to Create Certificate: %s", err)
    94  		return err
    95  	}
    96  
    97  	cert := string(pem.EncodeToMemory(&pem.Block{
    98  		Type:  "RSA PRIVATE KEY",
    99  		Bytes: derBytes,
   100  	}))
   101  	state.Put(constants.Certificate, cert)
   102  	log.Printf("createCert: Certificate:\n%s", cert)
   103  
   104  	h := sha1.New()
   105  	h.Write(derBytes)
   106  	thumbprint := fmt.Sprintf("%X", h.Sum(nil))
   107  	state.Put(constants.Thumbprint, thumbprint)
   108  	log.Printf("createCert: Thumbprint:\n%s", thumbprint)
   109  
   110  	return nil
   111  }