Skip to content

Commit cbd72d4

Browse files
authored
Fix finalizers (#25)
* Migrate RSA algorithms to _EvpPKey * Migrate EC algorithms to _EvpPKey
1 parent 819e9f5 commit cbd72d4

8 files changed

+197
-120
lines changed

lib/src/impl_ffi/impl_ffi.ec_common.dart

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,15 @@ String _ecCurveToJwkCrv(EllipticCurve curve) {
6464

6565
/// Perform some post-import validation for EC keys.
6666
void _validateEllipticCurveKey(
67-
ffi.Pointer<EVP_PKEY> key,
67+
_EvpPKey key,
6868
EllipticCurve curve,
6969
) {
7070
final scope = _Scope();
7171
try {
72-
_checkData(ssl.EVP_PKEY_id(key) == EVP_PKEY_EC,
72+
_checkData(ssl.EVP_PKEY_id.invoke(key) == EVP_PKEY_EC,
7373
message: 'key is not an EC key');
7474

75-
final ec = ssl.EVP_PKEY_get1_EC_KEY(key);
75+
final ec = ssl.EVP_PKEY_get1_EC_KEY.invoke(key);
7676
_checkData(ec.address != 0, fallback: 'key is not an EC key');
7777
scope.defer(() => ssl.EC_KEY_free(ec));
7878

@@ -93,35 +93,35 @@ void _validateEllipticCurveKey(
9393
}
9494
}
9595

96-
ffi.Pointer<EVP_PKEY> _importPkcs8EcPrivateKey(
96+
_EvpPKey _importPkcs8EcPrivateKey(
9797
List<int> keyData,
9898
EllipticCurve curve,
9999
) {
100-
final key = _withDataAsCBS(keyData, ssl.EVP_parse_private_key);
101-
_checkData(key.address != 0, fallback: 'unable to parse key');
102-
_attachFinalizerEVP_PKEY(key);
100+
final k = _withDataAsCBS(keyData, ssl.EVP_parse_private_key);
101+
_checkData(k.address != 0, fallback: 'unable to parse key');
102+
final key = _EvpPKey.wrap(k);
103103

104104
_validateEllipticCurveKey(key, curve);
105105
return key;
106106
}
107107

108-
ffi.Pointer<EVP_PKEY> _importSpkiEcPublicKey(
108+
_EvpPKey _importSpkiEcPublicKey(
109109
List<int> keyData,
110110
EllipticCurve curve,
111111
) {
112112
// TODO: When calling EVP_parse_public_key it might wise to check that CBS_len(cbs) == 0 is true afterwards
113113
// otherwise it might be that all of the contents of the key was not consumed and we should throw
114114
// a FormatException. Notice that this the case for private/public keys, and RSA keys.
115-
final key = _withDataAsCBS(keyData, ssl.EVP_parse_public_key);
116-
_checkData(key.address != 0, fallback: 'unable to parse key');
117-
_attachFinalizerEVP_PKEY(key);
115+
final k = _withDataAsCBS(keyData, ssl.EVP_parse_public_key);
116+
_checkData(k.address != 0, fallback: 'unable to parse key');
117+
final key = _EvpPKey.wrap(k);
118118

119119
_validateEllipticCurveKey(key, curve);
120120

121121
return key;
122122
}
123123

124-
ffi.Pointer<EVP_PKEY> _importJwkEcPrivateOrPublicKey(
124+
_EvpPKey _importJwkEcPrivateOrPublicKey(
125125
JsonWebKey jwk,
126126
EllipticCurve curve, {
127127
required bool isPrivateKey,
@@ -212,16 +212,16 @@ ffi.Pointer<EVP_PKEY> _importJwkEcPrivateOrPublicKey(
212212
_checkDataIsOne(ssl.EC_KEY_check_key(ec), fallback: 'invalid EC key');
213213

214214
// Wrap with an EVP_KEY
215-
final key = _createEVP_PKEYwithFinalizer();
216-
_checkOpIsOne(ssl.EVP_PKEY_set1_EC_KEY(key, ec));
215+
final key = _EvpPKey();
216+
_checkOpIsOne(ssl.EVP_PKEY_set1_EC_KEY.invoke(key, ec));
217217

218218
return key;
219219
} finally {
220220
scope.release();
221221
}
222222
}
223223

224-
ffi.Pointer<EVP_PKEY> _importRawEcPublicKey(
224+
_EvpPKey _importRawEcPublicKey(
225225
List<int> keyData,
226226
EllipticCurve curve,
227227
) {
@@ -248,8 +248,8 @@ ffi.Pointer<EVP_PKEY> _importRawEcPublicKey(
248248
_checkDataIsOne(ssl.EC_KEY_set_public_key(ec, pub),
249249
fallback: 'invalid keyData');
250250

251-
final key = _createEVP_PKEYwithFinalizer();
252-
_checkOpIsOne(ssl.EVP_PKEY_set1_EC_KEY(key, ec));
251+
final key = _EvpPKey();
252+
_checkOpIsOne(ssl.EVP_PKEY_set1_EC_KEY.invoke(key, ec));
253253
_validateEllipticCurveKey(key, curve);
254254

255255
return key;
@@ -261,10 +261,10 @@ ffi.Pointer<EVP_PKEY> _importRawEcPublicKey(
261261
}
262262
}
263263

264-
Uint8List _exportRawEcPublicKey(ffi.Pointer<EVP_PKEY> key) {
264+
Uint8List _exportRawEcPublicKey(_EvpPKey key) {
265265
final scope = _Scope();
266266
try {
267-
final ec = ssl.EVP_PKEY_get1_EC_KEY(key);
267+
final ec = ssl.EVP_PKEY_get1_EC_KEY.invoke(key);
268268
_checkOp(ec.address != 0, fallback: 'internal key type invariant error');
269269
scope.defer(() => ssl.EC_KEY_free(ec));
270270

@@ -285,13 +285,13 @@ Uint8List _exportRawEcPublicKey(ffi.Pointer<EVP_PKEY> key) {
285285
}
286286

287287
Map<String, dynamic> _exportJwkEcPrivateOrPublicKey(
288-
ffi.Pointer<EVP_PKEY> key, {
288+
_EvpPKey key, {
289289
required bool isPrivateKey,
290290
String? jwkUse,
291291
}) {
292292
final scope = _Scope();
293293
try {
294-
final ec = ssl.EVP_PKEY_get1_EC_KEY(key);
294+
final ec = ssl.EVP_PKEY_get1_EC_KEY.invoke(key);
295295
_checkOp(ec.address != 0, fallback: 'internal key type invariant error');
296296
scope.defer(() => ssl.EC_KEY_free(ec));
297297

@@ -340,7 +340,7 @@ Map<String, dynamic> _exportJwkEcPrivateOrPublicKey(
340340
}
341341
}
342342

343-
KeyPair<ffi.Pointer<EVP_PKEY>, ffi.Pointer<EVP_PKEY>> _generateEcKeyPair(
343+
KeyPair<_EvpPKey, _EvpPKey> _generateEcKeyPair(
344344
EllipticCurve curve,
345345
) {
346346
final scope = _Scope();
@@ -351,8 +351,8 @@ KeyPair<ffi.Pointer<EVP_PKEY>, ffi.Pointer<EVP_PKEY>> _generateEcKeyPair(
351351

352352
_checkOpIsOne(ssl.EC_KEY_generate_key(ecPriv));
353353

354-
final privKey = _createEVP_PKEYwithFinalizer();
355-
_checkOpIsOne(ssl.EVP_PKEY_set1_EC_KEY(privKey, ecPriv));
354+
final privKey = _EvpPKey();
355+
_checkOpIsOne(ssl.EVP_PKEY_set1_EC_KEY.invoke(privKey, ecPriv));
356356

357357
final ecPub = ssl.EC_KEY_new_by_curve_name(_ecCurveToNID(curve));
358358
_checkOp(ecPub.address != 0);
@@ -362,8 +362,8 @@ KeyPair<ffi.Pointer<EVP_PKEY>, ffi.Pointer<EVP_PKEY>> _generateEcKeyPair(
362362
ssl.EC_KEY_get0_public_key(ecPriv),
363363
));
364364

365-
final pubKey = _createEVP_PKEYwithFinalizer();
366-
_checkOpIsOne(ssl.EVP_PKEY_set1_EC_KEY(pubKey, ecPub));
365+
final pubKey = _EvpPKey();
366+
_checkOpIsOne(ssl.EVP_PKEY_set1_EC_KEY.invoke(pubKey, ecPub));
367367

368368
return _KeyPair(
369369
privateKey: privKey,

lib/src/impl_ffi/impl_ffi.ecdh.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ Future<EcdhPublicKey> ecdhPublicKey_importJsonWebKey(
6767
));
6868

6969
class _EcdhPrivateKey implements EcdhPrivateKey {
70-
final ffi.Pointer<EVP_PKEY> _key;
70+
final _EvpPKey _key;
7171

7272
_EcdhPrivateKey(this._key);
7373

@@ -88,11 +88,11 @@ class _EcdhPrivateKey implements EcdhPrivateKey {
8888

8989
final scope = _Scope();
9090
try {
91-
final pubEcKey = ssl.EVP_PKEY_get1_EC_KEY(publicKey._key);
91+
final pubEcKey = ssl.EVP_PKEY_get1_EC_KEY.invoke(publicKey._key);
9292
_checkOp(pubEcKey.address != 0, fallback: 'not an ec key');
9393
scope.defer(() => ssl.EC_KEY_free(pubEcKey));
9494

95-
final privEcKey = ssl.EVP_PKEY_get1_EC_KEY(_key);
95+
final privEcKey = ssl.EVP_PKEY_get1_EC_KEY.invoke(_key);
9696
_checkOp(privEcKey.address != 0, fallback: 'not an ec key');
9797
scope.defer(() => ssl.EC_KEY_free(privEcKey));
9898

@@ -164,13 +164,13 @@ class _EcdhPrivateKey implements EcdhPrivateKey {
164164
@override
165165
Future<Uint8List> exportPkcs8Key() async {
166166
return _withOutCBB((cbb) {
167-
_checkOp(ssl.EVP_marshal_private_key(cbb, _key) == 1);
167+
_checkOp(ssl.EVP_marshal_private_key.invoke(cbb, _key) == 1);
168168
});
169169
}
170170
}
171171

172172
class _EcdhPublicKey implements EcdhPublicKey {
173-
final ffi.Pointer<EVP_PKEY> _key;
173+
final _EvpPKey _key;
174174

175175
_EcdhPublicKey(this._key);
176176

@@ -188,7 +188,7 @@ class _EcdhPublicKey implements EcdhPublicKey {
188188
@override
189189
Future<Uint8List> exportSpkiKey() async {
190190
return _withOutCBB((cbb) {
191-
_checkOp(ssl.EVP_marshal_public_key(cbb, _key) == 1);
191+
_checkOp(ssl.EVP_marshal_public_key.invoke(cbb, _key) == 1);
192192
});
193193
}
194194
}

lib/src/impl_ffi/impl_ffi.ecdsa.dart

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ Future<EcdsaPublicKey> ecdsaPublicKey_importJsonWebKey(
8989
///
9090
/// See also: https://chromium.googlesource.com/chromium/src/+/43d62c50b705f88c67b14539e91fd8fd017f70c4/components/webcrypto/algorithms/ecdsa.cc#69
9191
Uint8List _convertEcdsaDerSignatureToWebCryptoSignature(
92-
ffi.Pointer<EVP_PKEY> key,
92+
_EvpPKey key,
9393
Uint8List signature,
9494
) {
9595
final scope = _Scope();
@@ -100,7 +100,7 @@ Uint8List _convertEcdsaDerSignatureToWebCryptoSignature(
100100
scope.defer(() => ssl.ECDSA_SIG_free(ecdsa));
101101

102102
// Read EC key and get the number of bytes required to encode R and S.
103-
final ec = ssl.EVP_PKEY_get1_EC_KEY(key);
103+
final ec = ssl.EVP_PKEY_get1_EC_KEY.invoke(key);
104104
_checkOp(ec.address != 0, message: 'internal key type invariant violation');
105105
scope.defer(() => ssl.EC_KEY_free(ec));
106106

@@ -139,13 +139,13 @@ Uint8List _convertEcdsaDerSignatureToWebCryptoSignature(
139139
///
140140
/// See also: https://chromium.googlesource.com/chromium/src/+/43d62c50b705f88c67b14539e91fd8fd017f70c4/components/webcrypto/algorithms/ecdsa.cc#111
141141
Uint8List? _convertEcdsaWebCryptoSignatureToDerSignature(
142-
ffi.Pointer<EVP_PKEY> key,
142+
_EvpPKey key,
143143
List<int> signature,
144144
) {
145145
final scope = _Scope();
146146
try {
147147
// Read EC key and get the number of bytes required to encode R and S.
148-
final ec = ssl.EVP_PKEY_get1_EC_KEY(key);
148+
final ec = ssl.EVP_PKEY_get1_EC_KEY.invoke(key);
149149
_checkOp(ec.address != 0, message: 'internal key type invariant violation');
150150
scope.defer(() => ssl.EC_KEY_free(ec));
151151

@@ -193,7 +193,7 @@ Uint8List? _convertEcdsaWebCryptoSignatureToDerSignature(
193193
}
194194

195195
class _EcdsaPrivateKey implements EcdsaPrivateKey {
196-
final ffi.Pointer<EVP_PKEY> _key;
196+
final _EvpPKey _key;
197197

198198
_EcdsaPrivateKey(this._key);
199199

@@ -211,9 +211,13 @@ class _EcdsaPrivateKey implements EcdsaPrivateKey {
211211
final _hash = _Hash.fromHash(hash).MD;
212212

213213
final sig = await _withEVP_MD_CTX((ctx) async {
214-
_checkOpIsOne(
215-
ssl.EVP_DigestSignInit(ctx, ffi.nullptr, _hash, ffi.nullptr, _key),
216-
);
214+
_checkOpIsOne(ssl.EVP_DigestSignInit.invoke(
215+
ctx,
216+
ffi.nullptr,
217+
_hash,
218+
ffi.nullptr,
219+
_key,
220+
));
217221

218222
await _streamToUpdate(data, ctx, ssl.EVP_DigestSignUpdate);
219223
return _withAllocation(_sslAlloc<ffi.IntPtr>(),
@@ -235,13 +239,13 @@ class _EcdsaPrivateKey implements EcdsaPrivateKey {
235239
@override
236240
Future<Uint8List> exportPkcs8Key() async {
237241
return _withOutCBB((cbb) {
238-
_checkOp(ssl.EVP_marshal_private_key(cbb, _key) == 1);
242+
_checkOp(ssl.EVP_marshal_private_key.invoke(cbb, _key) == 1);
239243
});
240244
}
241245
}
242246

243247
class _EcdsaPublicKey implements EcdsaPublicKey {
244-
final ffi.Pointer<EVP_PKEY> _key;
248+
final _EvpPKey _key;
245249

246250
_EcdsaPublicKey(this._key);
247251

@@ -273,9 +277,13 @@ class _EcdsaPublicKey implements EcdsaPublicKey {
273277

274278
return await _withEVP_MD_CTX((ctx) async {
275279
return await _withPEVP_PKEY_CTX((pctx) async {
276-
_checkOpIsOne(
277-
ssl.EVP_DigestVerifyInit(ctx, pctx, _hash, ffi.nullptr, _key),
278-
);
280+
_checkOpIsOne(ssl.EVP_DigestVerifyInit.invoke(
281+
ctx,
282+
pctx,
283+
_hash,
284+
ffi.nullptr,
285+
_key,
286+
));
279287
await _streamToUpdate(data, ctx, ssl.EVP_DigestVerifyUpdate);
280288
return _withDataAsPointer(sig, (ffi.Pointer<ffi.Uint8> p) {
281289
final result = ssl.EVP_DigestVerifyFinal(ctx, p, sig.length);
@@ -302,7 +310,7 @@ class _EcdsaPublicKey implements EcdsaPublicKey {
302310
@override
303311
Future<Uint8List> exportSpkiKey() async {
304312
return _withOutCBB((cbb) {
305-
_checkOp(ssl.EVP_marshal_public_key(cbb, _key) == 1);
313+
_checkOp(ssl.EVP_marshal_public_key.invoke(cbb, _key) == 1);
306314
});
307315
}
308316
}

0 commit comments

Comments
 (0)