google/webcrypto.dart

package:webcrypto failed to attached finalizer

Closed this issue · 12 comments

Flutter version: (Channel beta, 2.3.0-24.1.pre, on Manjaro Linux 5.10.42-1-MANJARO)

  Assertion failed: "package:webcrypto failed to attached finalizer"
  package:webcrypto/src/impl_ffi/impl_ffi.utils.dart 39:5         _attachFinalizerEVP_PKEY
  package:webcrypto/src/impl_ffi/impl_ffi.utils.dart 49:3         _createEVP_PKEYwithFinalizer
  package:webcrypto/src/impl_ffi/impl_ffi.rsa_common.dart 287:21  _generateRsaKeyPair
  package:webcrypto/src/impl_ffi/impl_ffi.rsaoaep.dart 68:16      rsaOaepPrivateKey_generateKey
  package:webcrypto/src/webcrypto/webcrypto.rsaoaep.dart 50:12    RsaOaepPrivateKey.generateKey
  package:betro_dart_lib/rsa.dart 12:31                           generateRsaPair

Note: This is running fine on flutter stable. With beta, there seems to be some change in ffi API which is causing this issue

Any news on this? Now that Flutter 2.5.0 reaches stable it makes the use of this package impossible.

Same problem

I am using the ECDH from this package. I do not find any other package which supports this on Android, iOS and web. I need this for web push. Why is this package here just broken now when it is from Google?? Now web push is basically unusable with Flutter...

I had a look at whether simply raising the ffigen version would help, but no dice. 2.x and 3.0 simply do not change this bug, 4.0 produces a lot more error messages and prevents apps using webcrypto from starting.

Is someone aware of what changed here (probably in dart) that caused this error? If I got that right,

final ret = dl.webcrypto_dart_dl_attach_finalizer(
is returning -1, which might be because
handle = Dart_NewFinalizableHandle_DL(object, (void*)peer,
is setting the handle to null. But no idea why.

This seems to be the breaking change: dart-lang/sdk#45072.

I've downgraded my project to the flutter ver 2.2.3 via fvm and this issue seems to be gone. If you can find a way of using dart 2.13 with the latest flutter, it should also work too.

@sardok The other way around (I just deleted my comment after mixing this up) - exactly! The bug strikes us only when we upgrade from 2.2.3 to 2.5.0

@sardok @maltemedocs
Is there no other solution but downgrading flutter? This does not feel right!

@mherfurt
As far as I can see, what needs to be done is to solve #10. Instead of attaching finalizers to pointers directly, follow the code example in dart-lang/sdk#45072 and wrap the pointers in a NativeResource, where Dart_NewFInalizableHandle is called in the constructor (or is the constructor adding the finalizer automatically? The comment is unclear to me). I have no overview on how big the additional code changes stemming from such a change would be - this is really a job for a qualified developer familiar with this code base.

@maltemedocs @mherfurt
When using web crypto with actual Dart (Dart version 2.14.4) I ran into the same issue (error: "package:webcrypto failed to attached finalizer").

This message is thrown in impl_ffi.utils.dart and in this routine web crypto tries to let the Dart GC delete the no longer used key as fast as possible. I temporary solved this problem by commenting out the line "throw AssertionError('package:webcrypto failed to attached finalizer');":

/// Attach a finalizer for [key], this means that [ssl.EVP_PKEY_free] will
/// automatically be called with [key] is garbage collected by Dart.
///
/// This takes ownership of [key], and the caller **may not** call
/// [ssl.EVP_PKEY_free].
///
/// Callers should be ware that the Dart GC may collect [key] as soon as it
/// deems the object to not be in use anymore. This can happy at any point when
/// the VM (optimizer) determines that no code-path passing [key] to an FFI
/// function can be called again. For this reason, users should take extra care
/// to make sure that all accesses to [key] takes an extra reference.
void _attachFinalizerEVP_PKEY(ffi.Pointer<EVP_PKEY> key) {
  final ret = dl.webcrypto_dart_dl_attach_finalizer(
    key,
    key.cast(),
    ssl.addresses.EVP_PKEY_free.cast(),
    // We don't really have an estimate of how much space the EVP_PKEY structure
    // takes up, but if we make it some non-trivial size then hopefully the GC
    // will prioritize freeing them.
    4096,
  );
  if (ret != 1) {
    //throw AssertionError('package:webcrypto failed to attached finalizer');
    print('error in impl_ffi.utils.dart: package:webcrypto failed to attached finalizer');
  }
}

I already know that this is a security feature (leave a less cryptographic footprint in the memory) but the GC will delete the key when it is not longer in use.

You can follow a possible solution here: #10

Kind regards Michael

Please feel free to test out the fix in #25

Hi, I was also running into this issue and #25 seems to work really well for me as a git (cbd72d4) dependency. Unfortunately, I can't publish my package to pub.dev with a git dependency. Could you please publish a release to pub.dev with the new changes?

Thanks for this lib

@karmanyaahm thanks for the report, I'll make sure get a release out shortly.