@@ -18,161 +18,20 @@ const ECDSA = require('../../src/algorithms/ECDSA')
18
18
const { TextEncoder} = require ( '@sinonjs/text-encoding' )
19
19
const crypto = require ( 'isomorphic-webcrypto' )
20
20
const base64url = require ( 'base64url' )
21
+ const { getPublicKey, getPrivateKey } = require ( '../keys/ES256' )
22
+ const { should } = require ( 'chai' )
23
+
24
+ /**
25
+ * Reused test constants
26
+ */
27
+ const alg = { name : 'ECDSA' , hash : { name : 'SHA-256' } , namedCurve : "P-256" }
28
+
29
+ const data = 'signed with Chrome generated webcrypto key'
21
30
22
- const jwkEcdsaKey = {
23
- "crv" : "P-256" ,
24
- "d" : "XX7AP7HV-6zBeUsAIFwBgpqsQf76ebFN1gquG-9wk8Q" ,
25
- "ext" : true ,
26
- "key_ops" : [
27
- "sign"
28
- ] ,
29
- "kty" : "EC" ,
30
- "x" : "KNeDy7FqchFNXivYDpnNSk0tTvox5cWwJgGoUom24BA" ,
31
- "y" : "qlC7dwMwytkZTY8E6s4Fam1JA8D19OhyFKrUM_aRgPo"
32
- }
33
- const chromeEcdsaSignature = new Uint8Array ( [
34
- 238 ,
35
- 23 ,
36
- 148 ,
37
- 239 ,
38
- 242 ,
39
- 150 ,
40
- 132 ,
41
- 224 ,
42
- 198 ,
43
- 144 ,
44
- 143 ,
45
- 31 ,
46
- 211 ,
47
- 82 ,
48
- 220 ,
49
- 86 ,
50
- 193 ,
51
- 138 ,
52
- 128 ,
53
- 199 ,
54
- 103 ,
55
- 190 ,
56
- 187 ,
57
- 230 ,
58
- 40 ,
59
- 4 ,
60
- 113 ,
61
- 108 ,
62
- 163 ,
63
- 147 ,
64
- 112 ,
65
- 70 ,
66
- 9 ,
67
- 92 ,
68
- 99 ,
69
- 83 ,
70
- 4 ,
71
- 222 ,
72
- 75 ,
73
- 162 ,
74
- 21 ,
75
- 156 ,
76
- 135 ,
77
- 201 ,
78
- 31 ,
79
- 42 ,
80
- 209 ,
81
- 14 ,
82
- 208 ,
83
- 206 ,
84
- 227 ,
85
- 13 ,
86
- 160 ,
87
- 228 ,
88
- 84 ,
89
- 73 ,
90
- 74 ,
91
- 164 ,
92
- 83 ,
93
- 7 ,
94
- 23 ,
95
- 184 ,
96
- 73 ,
97
- 160
98
- ] )
99
-
100
- const publicKey = new Uint8Array ( [
101
- 4 ,
102
- 40 ,
103
- 215 ,
104
- 131 ,
105
- 203 ,
106
- 177 ,
107
- 106 ,
108
- 114 ,
109
- 17 ,
110
- 77 ,
111
- 94 ,
112
- 43 ,
113
- 216 ,
114
- 14 ,
115
- 153 ,
116
- 205 ,
117
- 74 ,
118
- 77 ,
119
- 45 ,
120
- 78 ,
121
- 250 ,
122
- 49 ,
123
- 229 ,
124
- 197 ,
125
- 176 ,
126
- 38 ,
127
- 1 ,
128
- 168 ,
129
- 82 ,
130
- 137 ,
131
- 182 ,
132
- 224 ,
133
- 16 ,
134
- 170 ,
135
- 80 ,
136
- 187 ,
137
- 119 ,
138
- 3 ,
139
- 48 ,
140
- 202 ,
141
- 217 ,
142
- 25 ,
143
- 77 ,
144
- 143 ,
145
- 4 ,
146
- 234 ,
147
- 206 ,
148
- 5 ,
149
- 106 ,
150
- 109 ,
151
- 73 ,
152
- 3 ,
153
- 192 ,
154
- 245 ,
155
- 244 ,
156
- 232 ,
157
- 114 ,
158
- 20 ,
159
- 170 ,
160
- 212 ,
161
- 51 ,
162
- 246 ,
163
- 145 ,
164
- 128 ,
165
- 250
166
- ] )
167
- const signature = 'YvmWUlEcE3C739KYsNRkykl9roZjr7vn0BHkMt0JZqemnWS3pYUoS7AvFs6D3POPosDEk20GbewTs3Mr/K5pWA=='
168
- const alg = { name : 'ECDSA' , hash : { name : 'SHA-256' } , namedCurve : "P-256" }
169
-
170
-
171
- const data = 'signed with Chrome generated webcrypto key'
172
31
/**
173
32
* Tests
174
33
*/
175
- describe . only ( 'ECDSA' , ( ) => {
34
+ describe ( 'ECDSA' , ( ) => {
176
35
177
36
/**
178
37
* constructor
@@ -189,65 +48,91 @@ describe.only('ECDSA', () => {
189
48
* sign
190
49
*/
191
50
describe ( 'sign' , ( ) => {
192
- let importedEcdsaKey , importedPublicKey
193
-
194
- before ( ( ) => {
51
+ let importedEcdsaPrivateKey , importedEcdsaPublicKey
195
52
196
- return crypto . subtle
197
- . importKey ( 'jwk' , jwkEcdsaKey , alg , true , [ 'sign' , 'verify' ] )
198
- . then ( cryptoKey => importedEcdsaKey = cryptoKey )
199
- } )
200
-
201
- before ( ( ) => {
202
- return crypto . subtle
203
- . importKey ( 'raw' , publicKey , alg , true , [ 'verify' ] )
204
- . then ( cryptoKey => importedPublicKey = cryptoKey )
53
+ before ( async ( ) => {
54
+ importedEcdsaPrivateKey = await getPrivateKey ( )
55
+ importedEcdsaPublicKey = await getPublicKey ( )
205
56
} )
206
57
207
58
it ( 'should return a promise' , ( ) => {
208
59
let ecdsa = new ECDSA ( alg )
209
- return ecdsa . sign ( importedEcdsaKey , data ) . should . be . instanceof ( Promise )
60
+ return ecdsa . sign ( importedEcdsaPrivateKey , data ) . should . be . instanceof ( Promise )
210
61
} )
211
62
212
63
it ( 'should reject an insufficient key length' )
213
64
214
- it ( 'should resolve a base64url encoded value' , ( ) => {
215
- let ecdsa = new ECDSA ( alg )
216
- return ecdsa . sign ( importedEcdsaKey , data )
217
- . then ( signature => {
218
- // ECDSA is non-deterministic. Therefore we test that the generated signature gets verified with crypto library
219
- return crypto . subtle . verify ( { name : 'ECDSA' , hash : { name : 'SHA-256' } , namedCurve : "P-256" } , importedPublicKey , new TextEncoder ( ) . encode ( signature ) , new TextEncoder ( ) . encode ( data ) )
220
- // base64url.toBuffer(signature)
221
- // .should.eql(Buffer.from(chromeEcdsaSignature.buffer))
222
- } )
65
+ it ( 'should resolve a base64url encoded value and verification should pass' , async ( ) => {
66
+ const ecdsa = new ECDSA ( alg )
67
+ const signature = await ecdsa . sign ( importedEcdsaPrivateKey , data )
68
+
69
+ // this will fail if signature is anything but base64 string
70
+ expect ( base64url ( base64url . toBuffer ( signature ) ) ) . to . equal ( signature )
71
+
72
+ // ECDSA is non-deterministic. Therefore we test that the generated signature gets verified with crypto library
73
+ const verified = await crypto . subtle . verify (
74
+ {
75
+ name : 'ECDSA' ,
76
+ hash : { name : 'SHA-256' } ,
77
+ namedCurve : "P-256"
78
+ } ,
79
+ importedEcdsaPublicKey ,
80
+ base64url . toBuffer ( signature ) ,
81
+ new TextEncoder ( ) . encode ( data )
82
+ )
83
+
84
+ verified . should . eql ( true )
223
85
} )
224
86
} )
225
87
226
88
/**
227
89
* verify
228
90
*/
229
91
describe ( 'verify' , ( ) => {
230
- let importedEcdsaKey
92
+ let importedEcdsaPublicKey , signature
231
93
232
- before ( ( ) => {
94
+ before ( async ( ) => {
95
+ /**
96
+ * This signature was produced in Chromium
97
+ * deails can be found in comments of ../keys/ES256.js
98
+ */
99
+ signature = 'AUNkOnr//z999flIoTMebaf5EQC56WVQizK3GXW/u4EOQBvs9CtvfgWi0pQ3bi0k8p357ajtNvN/dJ1Vr8gbYg=='
233
100
234
- return crypto . subtle
235
- . importKey ( 'raw' , publicKey , alg , true , [ 'verify' ] )
236
- . then ( cryptoKey => importedEcdsaKey = cryptoKey )
101
+ importedEcdsaPublicKey = await getPublicKey ( )
237
102
} )
238
103
239
104
it ( 'should return a promise' , ( ) => {
240
105
let ecdsa = new ECDSA ( alg )
241
- ecdsa . verify ( importedEcdsaKey , signature , data ) . should . be . instanceof ( Promise )
106
+ ecdsa . verify ( importedEcdsaPublicKey , signature , data ) . should . be . instanceof ( Promise )
242
107
} )
243
108
244
- it ( 'should resolve a boolean' , ( ) => {
245
- let ecdsa = new ECDSA ( alg )
246
- return ecdsa . verify ( importedEcdsaKey , signature , data )
247
- . then ( verified => {
248
- expect ( verified ) . to . equal ( true )
249
- } )
109
+ it ( 'should resolve to true' , async ( ) => {
110
+ const ecdsa = new ECDSA ( alg )
111
+ const verified = await ecdsa . verify ( importedEcdsaPublicKey , signature , data )
112
+ expect ( verified ) . to . equal ( true )
113
+ } )
114
+ } )
115
+
116
+ /**
117
+ * importKey
118
+ */
119
+ describe ( 'importKey' , ( ) => {
120
+ let exampleJwkPublicKey
121
+
122
+ before ( ( ) => {
123
+ exampleJwkPublicKey = {
124
+ crv : 'P-256' ,
125
+ kty : 'EC' ,
126
+ x : '-c0_z0ly3xRDR0XQuvIirfgal59hq7BzF9ObdUXrgmI' ,
127
+ y : '_7QdnDYKrkrkYaCqZko0ebDQ1L1RpHLtzg8YwdT79n8' ,
128
+ alg : 'ES256'
129
+ }
130
+ } )
250
131
132
+ it ( 'should successfully import public jwk key' , async ( ) => {
133
+ const ecdsa = new ECDSA ( alg )
134
+ const key = await ecdsa . importKey ( exampleJwkPublicKey )
135
+ key . cryptoKey . constructor . name . should . equal ( 'CryptoKey' )
251
136
} )
252
137
} )
253
138
} )
0 commit comments