authpass / kdbx.dart

KeepassX format implementation in pure dart.
GNU General Public License v3.0
38 stars 11 forks source link

Unit test failed on Mac M1 #10

Open drriguz opened 4 months ago

drriguz commented 4 months ago

When run flutter test on a Mac M1 device the unit test will fail:

To run this test again: /Users/riguz/mobile/flutter/bin/cache/dart-sdk/bin/dart test /Users/riguz/Documents/apps/kdbx.dart/test/deleted_objects_test.dart -p vm --plain-name 'delete permanently delete entry'
00:01 +6 -25: loading /Users/riguz/Documents/apps/kdbx.dart/test/deleted_objects_test.dart
2024-02-27 16:47:02.918727 FINEST argon2_ffi_base - resolving libargon2_ffi.dylib
2024-02-27 16:47:02.919057 FINE test_utils - Resolving libargon2_ffi.dylib to: /Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib (file:///Users/riguz/Documents/apps/kdbx.dart/main.dart)
2024-02-27 16:47:02.919168 FINEST argon2_ffi_base - DynamicLibrary.open(/Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib)
Shell: 2024-02-27 16:47:02.919406 SEVERE argon2_ffi_base - Error while loading dynamic library from /Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib
(libargon2_ffi.dylib)
Shell: ### ArgumentError: Invalid argument(s): Failed to load dynamic library '/Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib':
dlopen(/Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib, 0x0001): tried: '/Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib' (mach-o file, but is an incompatible
architecture (have 'x86_64', need 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib' (no such file),
'/Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64'))
Shell: #0      _open (dart:ffi-patch/ffi_dynamic_library_patch.dart:11:43)
Shell: #1      new DynamicLibrary.open (dart:ffi-patch/ffi_dynamic_library_patch.dart:22:12)
Shell: #2      Argon2FfiFlutter._loadLib (package:argon2_ffi_base/src/argon2_ffi_impl.dart:163:29)
Shell: #3      new Argon2FfiFlutter (package:argon2_ffi_base/src/argon2_ffi_impl.dart:92:23)
Shell: #4      TestUtil._kdbxFormat (file:///Users/riguz/Documents/apps/kdbx.dart/test/internal/test_utils.dart:29:23)
Shell: #5      TestUtil.kdbxFormat (file:///Users/riguz/Documents/apps/kdbx.dart/test/internal/test_utils.dart:25:27)
Shell: #6      TestUtil.kdbxFormat (file:///Users/riguz/Documents/apps/kdbx.dart/test/internal/test_utils.dart)
Shell: #7      TestUtil.createEmptyFile (file:///Users/riguz/Documents/apps/kdbx.dart/test/internal/test_utils.dart:68:18)
Shell: #8      main.<anonymous closure>.<anonymous closure> (file:///Users/riguz/Documents/apps/kdbx.dart/test/deleted_objects_test.dart:59:29)
Shell: #9      Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:215:19)
Shell: <asynchronous suspension>
Shell: #10     Declarer.test.<anonymous closure> (package:test_api/src/backend/declarer.dart:213:7)
Shell: <asynchronous suspension>
Shell: #11     Invoker._waitForOutstandingCallbacks.<anonymous closure> (package:test_api/src/backend/invoker.dart:258:9)
Shell: <asynchronous suspension>
Shell:

It seems that libargon2_ffi.dylib is compiled on Mac X86_64, and I re-compiled on M1 it works. It could be solved as following(generated by GPT):

final is64Bit = ffi.sizeOf<ffi.IntPtr>() == 8;  
if (is64Bit) {  
      // Use the x86_64 library for MacOS  
      dylib = ffi.DynamicLibrary.open('x86_64.so');  
} else {  
      // Use the arm library for MacOS  
      dylib = ffi.DynamicLibrary.open('arm.so');  
}

Since it requires to modify both kdbx.dart and argon2_ffi_base, I'm not able to file a PR directly.

drriguz commented 4 months ago

However authpass does work on the same computer, why?

image

drriguz commented 4 months ago

BTW, I found that PointyCastleArgon2 is already used in kdbx.dart:

  KdbxFormat([Argon2? argon2])
      : assert(kdbxKeyCommonAssertConsistency()),
        argon2 = argon2 == null || !argon2.isImplemented
            ? const PointyCastleArgon2()
            : argon2;

I think we can use it in unit test, which runs on dart vm and does not require any native library.

Also, have your benchmarked the performance between PointyCastleArgon2 and dragon2_ffi?

hpoul commented 4 months ago

I'm happy with the performance of argon2_ffi, and I don't think dragon2_ffi existed when I implemented it.. never tried it..

I guess we could use an environment variable or something to enforce pointy castle during unit tests 🤷🏽 I would still allow both though, so the ci uses the ffi implementation

drriguz commented 4 months ago

Got it, thanks! I'll try to use pointy castle in my fork of kdbx.dart to reduce complexity. I'm developing an encrypted note app, and I'm considering using kdbx and sqlcipher together to store passwords and notes. Anyway, thanks for your great work !

hpoul commented 4 months ago

fwiw, if you are developing a flutter app the native libraries should be loaded automatically.. just like with authpass.. for dart itself has no way to ship assets with packages yet, but that should change soon https://github.com/dart-lang/sdk/issues/50565