...

Source file src/github.com/letsencrypt/boulder/cmd/ceremony/key.go

Documentation: github.com/letsencrypt/boulder/cmd/ceremony

     1  package main
     2  
     3  import (
     4  	"crypto"
     5  	"crypto/x509"
     6  	"encoding/pem"
     7  	"fmt"
     8  	"log"
     9  
    10  	"github.com/letsencrypt/boulder/pkcs11helpers"
    11  	"github.com/miekg/pkcs11"
    12  )
    13  
    14  type hsmRandReader struct {
    15  	*pkcs11helpers.Session
    16  }
    17  
    18  func newRandReader(session *pkcs11helpers.Session) *hsmRandReader {
    19  	return &hsmRandReader{session}
    20  }
    21  
    22  func (hrr hsmRandReader) Read(p []byte) (n int, err error) {
    23  	r, err := hrr.Module.GenerateRandom(hrr.Session.Session, len(p))
    24  	if err != nil {
    25  		return 0, err
    26  	}
    27  	copy(p[:], r)
    28  	return len(r), nil
    29  }
    30  
    31  type generateArgs struct {
    32  	mechanism    []*pkcs11.Mechanism
    33  	privateAttrs []*pkcs11.Attribute
    34  	publicAttrs  []*pkcs11.Attribute
    35  }
    36  
    37  // keyInfo is a struct used to pass around information about the public key
    38  // associated with the generated private key. der contains the DER encoding
    39  // of the SubjectPublicKeyInfo structure for the public key. id contains the
    40  // HSM key pair object ID.
    41  type keyInfo struct {
    42  	key crypto.PublicKey
    43  	der []byte
    44  	id  []byte
    45  }
    46  
    47  func generateKey(session *pkcs11helpers.Session, label string, outputPath string, config keyGenConfig) (*keyInfo, error) {
    48  	_, err := session.FindObject([]*pkcs11.Attribute{
    49  		{Type: pkcs11.CKA_LABEL, Value: []byte(label)},
    50  	})
    51  	if err != pkcs11helpers.ErrNoObject {
    52  		return nil, fmt.Errorf("expected no preexisting objects with label %q in slot for key storage. got error: %s", label, err)
    53  	}
    54  
    55  	var pubKey crypto.PublicKey
    56  	var keyID []byte
    57  	switch config.Type {
    58  	case "rsa":
    59  		pubKey, keyID, err = rsaGenerate(session, label, config.RSAModLength)
    60  		if err != nil {
    61  			return nil, fmt.Errorf("failed to generate RSA key pair: %s", err)
    62  		}
    63  	case "ecdsa":
    64  		pubKey, keyID, err = ecGenerate(session, label, config.ECDSACurve)
    65  		if err != nil {
    66  			return nil, fmt.Errorf("failed to generate ECDSA key pair: %s", err)
    67  		}
    68  	}
    69  
    70  	der, err := x509.MarshalPKIXPublicKey(pubKey)
    71  	if err != nil {
    72  		return nil, fmt.Errorf("Failed to marshal public key: %s", err)
    73  	}
    74  
    75  	pemBytes := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: der})
    76  	log.Printf("Public key PEM:\n%s\n", pemBytes)
    77  	err = writeFile(outputPath, pemBytes)
    78  	if err != nil {
    79  		return nil, fmt.Errorf("Failed to write public key to %q: %s", outputPath, err)
    80  	}
    81  	log.Printf("Public key written to %q\n", outputPath)
    82  
    83  	return &keyInfo{key: pubKey, der: der, id: keyID}, nil
    84  }
    85  

View as plain text