@@ -94,7 +94,7 @@ Uint8List _convertEcdsaDerSignatureToWebCryptoSignature(
94
94
) {
95
95
return _Scope .sync ((scope) {
96
96
// TODO: Check if cbs is empty after parsing, consider using ECDSA_SIG_from_bytes instead (like chrome does)
97
- final ecdsa = _withDataAsCBS (signature, ssl.ECDSA_SIG_parse );
97
+ final ecdsa = ssl.ECDSA_SIG_parse (scope. createCBS (signature) );
98
98
_checkOp (ecdsa.address != 0 ,
99
99
message: 'internal error formatting signature' );
100
100
scope.defer (() => ssl.ECDSA_SIG_free (ecdsa));
@@ -108,25 +108,22 @@ Uint8List _convertEcdsaDerSignatureToWebCryptoSignature(
108
108
ec,
109
109
)));
110
110
111
- return _withAllocation (_sslAlloc< ffi.Pointer <BIGNUM >> (2 ),
112
- (ffi.Pointer <ffi.Pointer <BIGNUM >> RS ) {
113
- // Access R and S from the ecdsa signature
114
- final R = RS .elementAt (0 );
115
- final S = RS .elementAt (1 );
116
- ssl.ECDSA_SIG_get0 (ecdsa, R , S );
117
-
118
- // Dump R and S to return value.
119
- return _withOutPointer (N * 2 , (ffi.Pointer <ffi.Uint8 > p) {
120
- _checkOpIsOne (
121
- ssl.BN_bn2bin_padded (p.elementAt (0 ), N , R .value),
122
- fallback: 'internal error formatting R in signature' ,
123
- );
124
- _checkOpIsOne (
125
- ssl.BN_bn2bin_padded (p.elementAt (N ), N , S .value),
126
- fallback: 'internal error formatting S in signature' ,
127
- );
128
- });
129
- });
111
+ // Access R and S from the ecdsa signature
112
+ final R = scope< ffi.Pointer <BIGNUM >> ();
113
+ final S = scope< ffi.Pointer <BIGNUM >> ();
114
+ ssl.ECDSA_SIG_get0 (ecdsa, R , S );
115
+
116
+ // Dump R and S to return value.
117
+ final out = scope< ffi.Uint8 > (N * 2 );
118
+ _checkOpIsOne (
119
+ ssl.BN_bn2bin_padded (out.elementAt (0 ), N , R .value),
120
+ fallback: 'internal error formatting R in signature' ,
121
+ );
122
+ _checkOpIsOne (
123
+ ssl.BN_bn2bin_padded (out.elementAt (N ), N , S .value),
124
+ fallback: 'internal error formatting S in signature' ,
125
+ );
126
+ return out.copy (N * 2 );
130
127
});
131
128
}
132
129
@@ -157,33 +154,29 @@ Uint8List? _convertEcdsaWebCryptoSignatureToDerSignature(
157
154
return null ;
158
155
}
159
156
160
- final ecdsa = ssl.ECDSA_SIG_new ();
161
- _checkOp (ecdsa.address != 0 ,
162
- message: 'internal error formatting signature' );
163
- scope.defer (() => ssl.ECDSA_SIG_free (ecdsa));
164
-
165
- return _withAllocation (_sslAlloc< ffi.Pointer <BIGNUM >> (2 ),
166
- (ffi.Pointer <ffi.Pointer <BIGNUM >> RS ) {
167
- // Access R and S from the ecdsa signature
168
- final R = RS .elementAt (0 );
169
- final S = RS .elementAt (1 );
170
- ssl.ECDSA_SIG_get0 (ecdsa, R , S );
171
-
172
- _withDataAsPointer (signature, (ffi.Pointer <ffi.Uint8 > p) {
173
- _checkOp (
174
- ssl.BN_bin2bn (p.elementAt (0 ), N , R .value).address != 0 ,
175
- fallback: 'allocation failure' ,
176
- );
177
- _checkOp (
178
- ssl.BN_bin2bn (p.elementAt (N ), N , S .value).address != 0 ,
179
- fallback: 'allocation failure' ,
180
- );
181
- });
182
- return _withOutCBB ((cbb) => _checkOpIsOne (
183
- ssl.ECDSA_SIG_marshal (cbb, ecdsa),
184
- fallback: 'internal error reformatting signature' ,
185
- ));
186
- });
157
+ final ecdsa = scope.create (ssl.ECDSA_SIG_new , ssl.ECDSA_SIG_free );
158
+
159
+ // Access R and S from the ecdsa signature
160
+ final R = scope< ffi.Pointer <BIGNUM >> ();
161
+ final S = scope< ffi.Pointer <BIGNUM >> ();
162
+ ssl.ECDSA_SIG_get0 (ecdsa, R , S );
163
+
164
+ final psig = scope.dataAsPointer< ffi.Uint8 > (signature);
165
+ _checkOp (
166
+ ssl.BN_bin2bn (psig.elementAt (0 ), N , R .value).address != 0 ,
167
+ fallback: 'allocation failure' ,
168
+ );
169
+ _checkOp (
170
+ ssl.BN_bin2bn (psig.elementAt (N ), N , S .value).address != 0 ,
171
+ fallback: 'allocation failure' ,
172
+ );
173
+
174
+ final cbb = scope.createCBB ();
175
+ _checkOpIsOne (
176
+ ssl.ECDSA_SIG_marshal (cbb, ecdsa),
177
+ fallback: 'internal error reformatting signature' ,
178
+ );
179
+ return cbb.copy ();
187
180
});
188
181
}
189
182
@@ -199,26 +192,7 @@ class _EcdsaPrivateKey implements EcdsaPrivateKey {
199
192
@override
200
193
Future <Uint8List > signStream (Stream <List <int >> data, Hash hash) async {
201
194
final md = _Hash .fromHash (hash)._md;
202
-
203
- final sig = await _withEVP_MD_CTX ((ctx) async {
204
- _checkOpIsOne (ssl.EVP_DigestSignInit .invoke (
205
- ctx,
206
- ffi.nullptr,
207
- md,
208
- ffi.nullptr,
209
- _key,
210
- ));
211
-
212
- await _streamToUpdate (data, ctx, ssl.EVP_DigestSignUpdate );
213
- return _withAllocation (_sslAlloc< ffi.Size > (),
214
- (ffi.Pointer <ffi.Size > len) {
215
- len.value = 0 ;
216
- _checkOpIsOne (ssl.EVP_DigestSignFinal (ctx, ffi.nullptr, len));
217
- return _withOutPointer (len.value, (ffi.Pointer <ffi.Uint8 > p) {
218
- _checkOpIsOne (ssl.EVP_DigestSignFinal (ctx, p, len));
219
- }).sublist (0 , len.value);
220
- });
221
- });
195
+ final sig = await _signStream (_key, md, data);
222
196
return _convertEcdsaDerSignatureToWebCryptoSignature (_key, sig);
223
197
}
224
198
@@ -227,11 +201,7 @@ class _EcdsaPrivateKey implements EcdsaPrivateKey {
227
201
_exportJwkEcPrivateOrPublicKey (_key, isPrivateKey: true , jwkUse: 'sig' );
228
202
229
203
@override
230
- Future <Uint8List > exportPkcs8Key () async {
231
- return _withOutCBB ((cbb) {
232
- _checkOp (ssl.EVP_marshal_private_key .invoke (cbb, _key) == 1 );
233
- });
234
- }
204
+ Future <Uint8List > exportPkcs8Key () async => _exportPkcs8Key (_key);
235
205
}
236
206
237
207
class _EcdsaPublicKey implements EcdsaPublicKey {
@@ -258,29 +228,7 @@ class _EcdsaPublicKey implements EcdsaPublicKey {
258
228
return false ;
259
229
}
260
230
261
- return await _withEVP_MD_CTX ((ctx) async {
262
- return await _withPEVP_PKEY_CTX ((pctx) async {
263
- _checkOpIsOne (ssl.EVP_DigestVerifyInit .invoke (
264
- ctx,
265
- pctx,
266
- md,
267
- ffi.nullptr,
268
- _key,
269
- ));
270
- await _streamToUpdate (data, ctx, ssl.EVP_DigestVerifyUpdate );
271
- return _withDataAsPointer (sig, (ffi.Pointer <ffi.Uint8 > p) {
272
- final result = ssl.EVP_DigestVerifyFinal (ctx, p, sig.length);
273
- if (result != 1 ) {
274
- // TODO: We should always clear errors, when returning from any
275
- // function that uses BoringSSL.
276
- // Note: In this case we could probably assert that error is just
277
- // signature related.
278
- ssl.ERR_clear_error ();
279
- }
280
- return result == 1 ;
281
- });
282
- });
283
- });
231
+ return await _verifyStream (_key, md, sig, data);
284
232
}
285
233
286
234
@override
@@ -291,9 +239,5 @@ class _EcdsaPublicKey implements EcdsaPublicKey {
291
239
Future <Uint8List > exportRawKey () async => _exportRawEcPublicKey (_key);
292
240
293
241
@override
294
- Future <Uint8List > exportSpkiKey () async {
295
- return _withOutCBB ((cbb) {
296
- _checkOp (ssl.EVP_marshal_public_key .invoke (cbb, _key) == 1 );
297
- });
298
- }
242
+ Future <Uint8List > exportSpkiKey () async => _exportSpkiKey (_key);
299
243
}
0 commit comments