...

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

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

     1  package main
     2  
     3  import (
     4  	"crypto"
     5  	"crypto/ecdsa"
     6  	"crypto/elliptic"
     7  	"crypto/rand"
     8  	"crypto/rsa"
     9  	"crypto/x509"
    10  	"encoding/pem"
    11  	"math/big"
    12  	"os"
    13  	"path"
    14  	"strings"
    15  	"testing"
    16  
    17  	"github.com/letsencrypt/boulder/pkcs11helpers"
    18  	"github.com/letsencrypt/boulder/test"
    19  	"github.com/miekg/pkcs11"
    20  )
    21  
    22  func setupCtx() pkcs11helpers.MockCtx {
    23  	return pkcs11helpers.MockCtx{
    24  		GenerateKeyPairFunc: func(pkcs11.SessionHandle, []*pkcs11.Mechanism, []*pkcs11.Attribute, []*pkcs11.Attribute) (pkcs11.ObjectHandle, pkcs11.ObjectHandle, error) {
    25  			return 0, 0, nil
    26  		},
    27  		SignInitFunc: func(pkcs11.SessionHandle, []*pkcs11.Mechanism, pkcs11.ObjectHandle) error {
    28  			return nil
    29  		},
    30  		GenerateRandomFunc: func(pkcs11.SessionHandle, int) ([]byte, error) {
    31  			return []byte{1, 2, 3}, nil
    32  		},
    33  		FindObjectsInitFunc: func(pkcs11.SessionHandle, []*pkcs11.Attribute) error {
    34  			return nil
    35  		},
    36  		FindObjectsFunc: func(pkcs11.SessionHandle, int) ([]pkcs11.ObjectHandle, bool, error) {
    37  			return nil, false, nil
    38  		},
    39  		FindObjectsFinalFunc: func(pkcs11.SessionHandle) error {
    40  			return nil
    41  		},
    42  	}
    43  }
    44  
    45  func TestGenerateKeyRSA(t *testing.T) {
    46  	tmp := t.TempDir()
    47  
    48  	ctx := setupCtx()
    49  	rsaPriv, err := rsa.GenerateKey(rand.Reader, 1024)
    50  	test.AssertNotError(t, err, "Failed to generate a test RSA key")
    51  	ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
    52  		return []*pkcs11.Attribute{
    53  			pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, big.NewInt(int64(rsaPriv.E)).Bytes()),
    54  			pkcs11.NewAttribute(pkcs11.CKA_MODULUS, rsaPriv.N.Bytes()),
    55  		}, nil
    56  	}
    57  	ctx.SignFunc = func(_ pkcs11.SessionHandle, msg []byte) ([]byte, error) {
    58  		// Chop of the hash identifier and feed back into rsa.SignPKCS1v15
    59  		return rsa.SignPKCS1v15(rand.Reader, rsaPriv, crypto.SHA256, msg[19:])
    60  	}
    61  	s := &pkcs11helpers.Session{Module: &ctx, Session: 0}
    62  	keyPath := path.Join(tmp, "test-rsa-key.pem")
    63  	keyInfo, err := generateKey(s, "", keyPath, keyGenConfig{
    64  		Type:         "rsa",
    65  		RSAModLength: 1024,
    66  	})
    67  	test.AssertNotError(t, err, "Failed to generate RSA key")
    68  	diskKeyBytes, err := os.ReadFile(keyPath)
    69  	test.AssertNotError(t, err, "Failed to load key from disk")
    70  	block, _ := pem.Decode(diskKeyBytes)
    71  	diskKey, err := x509.ParsePKIXPublicKey(block.Bytes)
    72  	test.AssertNotError(t, err, "Failed to parse disk key")
    73  	test.AssertDeepEquals(t, diskKey, keyInfo.key)
    74  }
    75  
    76  func setECGenerateFuncs(ctx *pkcs11helpers.MockCtx) {
    77  	ecPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    78  	if err != nil {
    79  		panic(err)
    80  	}
    81  	ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
    82  		return []*pkcs11.Attribute{
    83  			pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, []byte{6, 8, 42, 134, 72, 206, 61, 3, 1, 7}),
    84  			pkcs11.NewAttribute(pkcs11.CKA_EC_POINT, elliptic.Marshal(elliptic.P256(), ecPriv.X, ecPriv.Y)),
    85  		}, nil
    86  	}
    87  	ctx.SignFunc = func(_ pkcs11.SessionHandle, msg []byte) ([]byte, error) {
    88  		return ecPKCS11Sign(ecPriv, msg)
    89  	}
    90  }
    91  
    92  func TestGenerateKeyEC(t *testing.T) {
    93  	tmp := t.TempDir()
    94  
    95  	ctx := setupCtx()
    96  	setECGenerateFuncs(&ctx)
    97  	keyPath := path.Join(tmp, "test-ecdsa-key.pem")
    98  	s := &pkcs11helpers.Session{Module: &ctx, Session: 0}
    99  	keyInfo, err := generateKey(s, "", keyPath, keyGenConfig{
   100  		Type:       "ecdsa",
   101  		ECDSACurve: "P-256",
   102  	})
   103  	test.AssertNotError(t, err, "Failed to generate ECDSA key")
   104  	diskKeyBytes, err := os.ReadFile(keyPath)
   105  	test.AssertNotError(t, err, "Failed to load key from disk")
   106  	block, _ := pem.Decode(diskKeyBytes)
   107  	diskKey, err := x509.ParsePKIXPublicKey(block.Bytes)
   108  	test.AssertNotError(t, err, "Failed to parse disk key")
   109  	test.AssertDeepEquals(t, diskKey, keyInfo.key)
   110  }
   111  
   112  func setFindObjectsFuncs(label string, ctx *pkcs11helpers.MockCtx) {
   113  	var objectsFound []pkcs11.ObjectHandle
   114  	ctx.FindObjectsInitFunc = func(_ pkcs11.SessionHandle, template []*pkcs11.Attribute) error {
   115  		for _, attr := range template {
   116  			if attr.Type == pkcs11.CKA_LABEL && string(attr.Value) == label {
   117  				objectsFound = []pkcs11.ObjectHandle{1}
   118  			}
   119  		}
   120  		return nil
   121  	}
   122  	ctx.FindObjectsFunc = func(pkcs11.SessionHandle, int) ([]pkcs11.ObjectHandle, bool, error) {
   123  		return objectsFound, false, nil
   124  	}
   125  	ctx.FindObjectsFinalFunc = func(pkcs11.SessionHandle) error {
   126  		objectsFound = nil
   127  		return nil
   128  	}
   129  }
   130  
   131  func TestGenerateKeySlotHasSomethingWithLabel(t *testing.T) {
   132  	tmp := t.TempDir()
   133  
   134  	ctx := setupCtx()
   135  	label := "someLabel"
   136  	setFindObjectsFuncs(label, &ctx)
   137  	keyPath := path.Join(tmp, "should-not-exist.pem")
   138  	s := &pkcs11helpers.Session{Module: &ctx, Session: 0}
   139  	_, err := generateKey(s, label, keyPath, keyGenConfig{
   140  		Type:       "ecdsa",
   141  		ECDSACurve: "P-256",
   142  	})
   143  	test.AssertError(t, err, "expected failure for a slot with an object already in it")
   144  	test.Assert(t, strings.HasPrefix(err.Error(), "expected no preexisting objects with label"), "wrong error")
   145  }
   146  
   147  func TestGenerateKeySlotHasSomethingWithDifferentLabel(t *testing.T) {
   148  	tmp := t.TempDir()
   149  
   150  	ctx := setupCtx()
   151  	setECGenerateFuncs(&ctx)
   152  	setFindObjectsFuncs("someLabel", &ctx)
   153  	keyPath := path.Join(tmp, "should-not-exist.pem")
   154  	s := &pkcs11helpers.Session{Module: &ctx, Session: 0}
   155  	_, err := generateKey(s, "someOtherLabel", keyPath, keyGenConfig{
   156  		Type:       "ecdsa",
   157  		ECDSACurve: "P-256",
   158  	})
   159  	test.AssertNotError(t, err, "expected success even though there was an object with a different label")
   160  }
   161  

View as plain text