github.com/letsencrypt/boulder@v0.20251208.0/cmd/ceremony/ecdsa_test.go (about) 1 package main 2 3 import ( 4 "crypto/ecdsa" 5 "crypto/elliptic" 6 "crypto/rand" 7 "errors" 8 "testing" 9 10 "github.com/letsencrypt/boulder/pkcs11helpers" 11 "github.com/letsencrypt/boulder/test" 12 "github.com/miekg/pkcs11" 13 ) 14 15 func TestECPub(t *testing.T) { 16 s, ctx := pkcs11helpers.NewSessionWithMock() 17 18 // test we fail when pkcs11helpers.GetECDSAPublicKey fails 19 ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) { 20 return nil, errors.New("bad!") 21 } 22 _, err := ecPub(s, 0, elliptic.P256()) 23 test.AssertError(t, err, "ecPub didn't fail with non-matching curve") 24 test.AssertEquals(t, err.Error(), "Failed to retrieve key attributes: bad!") 25 26 // test we fail to construct key with non-matching curve 27 ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) { 28 return []*pkcs11.Attribute{ 29 pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, []byte{6, 5, 43, 129, 4, 0, 33}), 30 pkcs11.NewAttribute(pkcs11.CKA_EC_POINT, []byte{4, 217, 225, 246, 210, 153, 134, 246, 104, 95, 79, 122, 206, 135, 241, 37, 114, 199, 87, 56, 167, 83, 56, 136, 174, 6, 145, 97, 239, 221, 49, 67, 148, 13, 126, 65, 90, 208, 195, 193, 171, 105, 40, 98, 132, 124, 30, 189, 215, 197, 178, 226, 166, 238, 240, 57, 215}), 31 }, nil 32 } 33 _, err = ecPub(s, 0, elliptic.P256()) 34 test.AssertError(t, err, "ecPub didn't fail with non-matching curve") 35 } 36 37 func TestECGenerate(t *testing.T) { 38 ctx := pkcs11helpers.MockCtx{} 39 s := &pkcs11helpers.Session{Module: &ctx, Session: 0} 40 ctx.GenerateRandomFunc = func(pkcs11.SessionHandle, int) ([]byte, error) { 41 return []byte{1, 2, 3}, nil 42 } 43 priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 44 test.AssertNotError(t, err, "Failed to generate a ECDSA test key") 45 46 // Test ecGenerate fails with unknown curve 47 _, _, err = ecGenerate(s, "", "bad-curve") 48 test.AssertError(t, err, "ecGenerate accepted unknown curve") 49 50 // Test ecGenerate fails when GenerateKeyPair fails 51 ctx.GenerateKeyPairFunc = func(pkcs11.SessionHandle, []*pkcs11.Mechanism, []*pkcs11.Attribute, []*pkcs11.Attribute) (pkcs11.ObjectHandle, pkcs11.ObjectHandle, error) { 52 return 0, 0, errors.New("bad") 53 } 54 _, _, err = ecGenerate(s, "", "P-256") 55 test.AssertError(t, err, "ecGenerate didn't fail on GenerateKeyPair error") 56 57 // Test ecGenerate fails when ecPub fails 58 ctx.GenerateKeyPairFunc = func(pkcs11.SessionHandle, []*pkcs11.Mechanism, []*pkcs11.Attribute, []*pkcs11.Attribute) (pkcs11.ObjectHandle, pkcs11.ObjectHandle, error) { 59 return 0, 0, nil 60 } 61 ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) { 62 return nil, errors.New("bad") 63 } 64 _, _, err = ecGenerate(s, "", "P-256") 65 test.AssertError(t, err, "ecGenerate didn't fail on ecPub error") 66 67 // Test ecGenerate fails when ecVerify fails 68 ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) { 69 return []*pkcs11.Attribute{ 70 pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, []byte{6, 8, 42, 134, 72, 206, 61, 3, 1, 7}), 71 pkcs11.NewAttribute(pkcs11.CKA_EC_POINT, elliptic.Marshal(elliptic.P256(), priv.X, priv.Y)), 72 }, nil 73 } 74 ctx.GenerateRandomFunc = func(pkcs11.SessionHandle, int) ([]byte, error) { 75 return nil, errors.New("yup") 76 } 77 _, _, err = ecGenerate(s, "", "P-256") 78 test.AssertError(t, err, "ecGenerate didn't fail on ecVerify error") 79 80 // Test ecGenerate doesn't fail when everything works 81 ctx.SignInitFunc = func(pkcs11.SessionHandle, []*pkcs11.Mechanism, pkcs11.ObjectHandle) error { 82 return nil 83 } 84 ctx.GenerateRandomFunc = func(pkcs11.SessionHandle, int) ([]byte, error) { 85 return []byte{1, 2, 3}, nil 86 } 87 ctx.SignFunc = func(_ pkcs11.SessionHandle, msg []byte) ([]byte, error) { 88 return ecPKCS11Sign(priv, msg) 89 } 90 _, _, err = ecGenerate(s, "", "P-256") 91 test.AssertNotError(t, err, "ecGenerate didn't succeed when everything worked as expected") 92 } 93 94 func ecPKCS11Sign(priv *ecdsa.PrivateKey, msg []byte) ([]byte, error) { 95 r, s, err := ecdsa.Sign(rand.Reader, priv, msg[:]) 96 if err != nil { 97 return nil, err 98 } 99 rBytes := r.Bytes() 100 sBytes := s.Bytes() 101 // http://docs.oasis-open.org/pkcs11/pkcs11-curr/v2.40/os/pkcs11-curr-v2.40-os.html 102 // Section 2.3.1: EC Signatures 103 // "If r and s have different octet length, the shorter of both must be padded with 104 // leading zero octets such that both have the same octet length." 105 switch { 106 case len(rBytes) < len(sBytes): 107 padding := make([]byte, len(sBytes)-len(rBytes)) 108 rBytes = append(padding, rBytes...) 109 case len(rBytes) > len(sBytes): 110 padding := make([]byte, len(rBytes)-len(sBytes)) 111 sBytes = append(padding, sBytes...) 112 } 113 return append(rBytes, sBytes...), nil 114 }