1 package signerverifier
2
3 import (
4 "context"
5 "encoding/json"
6 "os"
7 "path/filepath"
8 "testing"
9
10 "github.com/secure-systems-lab/go-securesystemslib/cjson"
11 "github.com/secure-systems-lab/go-securesystemslib/dsse"
12 "github.com/stretchr/testify/assert"
13 )
14
15 func TestNewECDSASignerVerifierFromSSLibKey(t *testing.T) {
16 key, err := LoadECDSAKeyFromFile(filepath.Join("test-data", "ecdsa-test-key.pub"))
17 if err != nil {
18 t.Fatal(err)
19 }
20
21 sv, err := NewECDSASignerVerifierFromSSLibKey(key)
22 if err != nil {
23 t.Fatal(err)
24 }
25
26 expectedPublicString := "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEu+HEqqpXLa48lXH9rkRygsfsCKq1\nXM36oXymJ9wxpM68nCqkrZCVnZ9lkEeCwD8qWYTNxD5yfWXwJjFh+K7qLQ==\n-----END PUBLIC KEY-----"
27 _, expectedPublicKey, err := decodeAndParsePEM([]byte(expectedPublicString))
28 assert.Nil(t, err)
29
30 assert.Equal(t, "98adf38602c48c5479e9a991ee3f8cbf541ee4f985e00f7a5fc4148d9a45b704", sv.keyID)
31 assert.Equal(t, expectedPublicKey, sv.public)
32 assert.Nil(t, sv.private)
33 }
34
35 func TestLoadECDSAKeyFromFile(t *testing.T) {
36 t.Run("ecdsa public key", func(t *testing.T) {
37 key, err := LoadECDSAKeyFromFile(filepath.Join("test-data", "ecdsa-test-key.pub"))
38 assert.Nil(t, err)
39
40 assert.Equal(t, "98adf38602c48c5479e9a991ee3f8cbf541ee4f985e00f7a5fc4148d9a45b704", key.KeyID)
41 assert.Equal(t, "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEu+HEqqpXLa48lXH9rkRygsfsCKq1\nXM36oXymJ9wxpM68nCqkrZCVnZ9lkEeCwD8qWYTNxD5yfWXwJjFh+K7qLQ==\n-----END PUBLIC KEY-----", key.KeyVal.Public)
42 assert.Equal(t, "ecdsa-sha2-nistp256", key.Scheme)
43 assert.Equal(t, ECDSAKeyType, key.KeyType)
44 })
45
46 t.Run("ecdsa private key", func(t *testing.T) {
47 key, err := LoadECDSAKeyFromFile(filepath.Join("test-data", "ecdsa-test-key"))
48 assert.Nil(t, err)
49
50 assert.Equal(t, "98adf38602c48c5479e9a991ee3f8cbf541ee4f985e00f7a5fc4148d9a45b704", key.KeyID)
51 assert.Equal(t, "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEu+HEqqpXLa48lXH9rkRygsfsCKq1\nXM36oXymJ9wxpM68nCqkrZCVnZ9lkEeCwD8qWYTNxD5yfWXwJjFh+K7qLQ==\n-----END PUBLIC KEY-----", key.KeyVal.Public)
52 assert.Equal(t, "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIAo6DxXlgqYy+TkvocIOyWlqA3KVtp6dlSY7lS3kkeEMoAoGCCqGSM49\nAwEHoUQDQgAEu+HEqqpXLa48lXH9rkRygsfsCKq1XM36oXymJ9wxpM68nCqkrZCV\nnZ9lkEeCwD8qWYTNxD5yfWXwJjFh+K7qLQ==\n-----END EC PRIVATE KEY-----", key.KeyVal.Private)
53 assert.Equal(t, "ecdsa-sha2-nistp256", key.Scheme)
54 assert.Equal(t, ECDSAKeyType, key.KeyType)
55 })
56
57 t.Run("invalid path", func(t *testing.T) {
58 _, err := LoadECDSAKeyFromFile(filepath.Join("test-data", "invalid"))
59 assert.ErrorContains(t, err, "unable to load ECDSA key from file")
60 })
61 }
62
63 func TestECDSASignerVerifierSign(t *testing.T) {
64 t.Run("using valid key", func(t *testing.T) {
65 key, err := LoadECDSAKeyFromFile(filepath.Join("test-data", "ecdsa-test-key"))
66 if err != nil {
67 t.Fatal(err)
68 }
69
70 sv, err := NewECDSASignerVerifierFromSSLibKey(key)
71 if err != nil {
72 t.Fatal(err)
73 }
74
75 message := []byte("test message")
76
77 signature, err := sv.Sign(context.Background(), message)
78 assert.Nil(t, err)
79
80 err = sv.Verify(context.Background(), message, signature)
81 assert.Nil(t, err)
82 })
83
84 t.Run("using invalid key", func(t *testing.T) {
85 key, err := LoadECDSAKeyFromFile(filepath.Join("test-data", "ecdsa-test-key.pub"))
86 if err != nil {
87 t.Fatal(err)
88 }
89
90 sv, err := NewECDSASignerVerifierFromSSLibKey(key)
91 if err != nil {
92 t.Fatal(err)
93 }
94
95 message := []byte("test message")
96
97 _, err = sv.Sign(context.Background(), message)
98 assert.ErrorIs(t, err, ErrNotPrivateKey)
99 })
100 }
101
102 func TestECDSASignerVerifierWithDSSEEnvelope(t *testing.T) {
103 key, err := LoadECDSAKeyFromFile(filepath.Join("test-data", "ecdsa-test-key"))
104 if err != nil {
105 t.Fatal(err)
106 }
107
108 sv, err := NewECDSASignerVerifierFromSSLibKey(key)
109 if err != nil {
110 t.Fatal(err)
111 }
112
113 payloadType := "application/vnd.dsse+json"
114 payload := []byte("test message")
115
116 es, err := dsse.NewEnvelopeSigner(sv)
117 if err != nil {
118 t.Error(err)
119 }
120
121 env, err := es.SignPayload(context.Background(), payloadType, payload)
122 if err != nil {
123 t.Error(err)
124 }
125
126 assert.Equal(t, "98adf38602c48c5479e9a991ee3f8cbf541ee4f985e00f7a5fc4148d9a45b704", env.Signatures[0].KeyID)
127 envPayload, err := env.DecodeB64Payload()
128 assert.Equal(t, payload, envPayload)
129 assert.Nil(t, err)
130
131 key, err = LoadECDSAKeyFromFile(filepath.Join("test-data", "ecdsa-test-key.pub"))
132 if err != nil {
133 t.Fatal(err)
134 }
135
136 sv, err = NewECDSASignerVerifierFromSSLibKey(key)
137 if err != nil {
138 t.Fatal(err)
139 }
140
141 ev, err := dsse.NewEnvelopeVerifier(sv)
142 if err != nil {
143 t.Error(err)
144 }
145
146 acceptedKeys, err := ev.Verify(context.Background(), env)
147 assert.Nil(t, err)
148 assert.Equal(t, "98adf38602c48c5479e9a991ee3f8cbf541ee4f985e00f7a5fc4148d9a45b704", acceptedKeys[0].KeyID)
149 }
150
151 func TestECDSASignerVerifierWithMetablockFile(t *testing.T) {
152 key, err := LoadECDSAKeyFromFile(filepath.Join("test-data", "ecdsa-test-key.pub"))
153 if err != nil {
154 t.Fatal(err)
155 }
156
157 sv, err := NewECDSASignerVerifierFromSSLibKey(key)
158 if err != nil {
159 t.Fatal(err)
160 }
161
162 metadataBytes, err := os.ReadFile(filepath.Join("test-data", "test-ecdsa.98adf386.link"))
163 if err != nil {
164 t.Fatal(err)
165 }
166
167 mb := struct {
168 Signatures []struct {
169 KeyID string `json:"keyid"`
170 Sig string `json:"sig"`
171 } `json:"signatures"`
172 Signed any `json:"signed"`
173 }{}
174
175 if err := json.Unmarshal(metadataBytes, &mb); err != nil {
176 t.Fatal(err)
177 }
178
179 assert.Equal(t, "304502201fbb03c0937504182a48c66f9218bdcb2e99a07ada273e92e5e543867f98c8d7022100dbfa7bbf74fd76d76c1d08676419cba85bbd81dfb000f3ac6a786693ddc508f5", mb.Signatures[0].Sig)
180 assert.Equal(t, sv.keyID, mb.Signatures[0].KeyID)
181
182 encodedBytes, err := cjson.EncodeCanonical(mb.Signed)
183 if err != nil {
184 t.Fatal(err)
185 }
186
187 decodedSig := hexDecode(t, mb.Signatures[0].Sig)
188
189 err = sv.Verify(context.Background(), encodedBytes, decodedSig)
190 assert.Nil(t, err)
191 }
192
View as plain text