style: fix format and lint
This commit is contained in:
parent
ac9df588d1
commit
545ce26e39
|
|
@ -101,7 +101,8 @@ class SSSS {
|
|||
mac: base64.encode(hmac.bytes));
|
||||
}
|
||||
|
||||
static Future<String> decryptAes(_Encrypted data, Uint8List key, String name) async {
|
||||
static Future<String> decryptAes(
|
||||
_Encrypted data, Uint8List key, String name) async {
|
||||
final keys = deriveKeys(key, name);
|
||||
final cipher = base64.decode(data.ciphertext);
|
||||
final hmac = base64
|
||||
|
|
@ -110,7 +111,8 @@ class SSSS {
|
|||
if (hmac != data.mac.replaceAll(RegExp(r'=+$'), '')) {
|
||||
throw Exception('Bad MAC');
|
||||
}
|
||||
final decipher = await uc.aesCtr.encrypt(cipher, keys.aesKey, base64.decode(data.iv));
|
||||
final decipher =
|
||||
await uc.aesCtr.encrypt(cipher, keys.aesKey, base64.decode(data.iv));
|
||||
return String.fromCharCodes(decipher);
|
||||
}
|
||||
|
||||
|
|
@ -147,11 +149,13 @@ class SSSS {
|
|||
.trim();
|
||||
}
|
||||
|
||||
static Future<Uint8List> keyFromPassphrase(String passphrase, PassphraseInfo info) async {
|
||||
static Future<Uint8List> keyFromPassphrase(
|
||||
String passphrase, PassphraseInfo info) async {
|
||||
if (info.algorithm != AlgorithmTypes.pbkdf2) {
|
||||
throw Exception('Unknown algorithm');
|
||||
}
|
||||
return await uc.pbkdf2(utf8.encode(passphrase), utf8.encode(info.salt), uc.sha512, info.iterations, info.bits ?? 256);
|
||||
return await uc.pbkdf2(utf8.encode(passphrase), utf8.encode(info.salt),
|
||||
uc.sha512, info.iterations, info.bits ?? 256);
|
||||
}
|
||||
|
||||
void setValidator(String type, FutureOr<bool> Function(String) validator) {
|
||||
|
|
@ -194,7 +198,8 @@ class SSSS {
|
|||
content.passphrase.algorithm = AlgorithmTypes.pbkdf2;
|
||||
content.passphrase.salt = base64
|
||||
.encode(uc.secureRandomBytes(pbkdf2SaltLength)); // generate salt
|
||||
content.passphrase.iterations = pbkdf2DefaultIterations;;
|
||||
content.passphrase.iterations = pbkdf2DefaultIterations;
|
||||
;
|
||||
content.passphrase.bits = ssssKeyLength * 8;
|
||||
privateKey = await runInBackground(
|
||||
_keyFromPassphrase,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ Future<EncryptedFile> encryptFile(Uint8List input) async {
|
|||
}
|
||||
|
||||
Future<Uint8List> decryptFile(EncryptedFile input) async {
|
||||
if (base64.encode(await sha256(input.data)) != base64.normalize(input.sha256)) {
|
||||
if (base64.encode(await sha256(input.data)) !=
|
||||
base64.normalize(input.sha256)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,70 +7,100 @@ final libcrypto = Platform.isIOS
|
|||
? 'libcrypto.so'
|
||||
: Platform.isWindows
|
||||
? 'libcrypto.dll'
|
||||
: Platform.isMacOS ? 'libcrypto.1.1.dylib' : 'libcrypto.so.1.1');
|
||||
: Platform.isMacOS
|
||||
? 'libcrypto.1.1.dylib'
|
||||
: 'libcrypto.so.1.1');
|
||||
|
||||
final PKCS5_PBKDF2_HMAC = libcrypto.lookupFunction<
|
||||
IntPtr Function(Pointer<Uint8> pass, IntPtr passlen, Pointer<Uint8> salt, IntPtr saltlen, IntPtr iter, Pointer<NativeType> digest, IntPtr keylen, Pointer<Uint8> out),
|
||||
int Function(Pointer<Uint8> pass, int passlen, Pointer<Uint8> salt, int saltlen, int iter, Pointer<NativeType> digest, int keylen, Pointer<Uint8> out)
|
||||
>('PKCS5_PBKDF2_HMAC');
|
||||
IntPtr Function(
|
||||
Pointer<Uint8> pass,
|
||||
IntPtr passlen,
|
||||
Pointer<Uint8> salt,
|
||||
IntPtr saltlen,
|
||||
IntPtr iter,
|
||||
Pointer<NativeType> digest,
|
||||
IntPtr keylen,
|
||||
Pointer<Uint8> out),
|
||||
int Function(
|
||||
Pointer<Uint8> pass,
|
||||
int passlen,
|
||||
Pointer<Uint8> salt,
|
||||
int saltlen,
|
||||
int iter,
|
||||
Pointer<NativeType> digest,
|
||||
int keylen,
|
||||
Pointer<Uint8> out)>('PKCS5_PBKDF2_HMAC');
|
||||
|
||||
final EVP_sha1 = libcrypto.lookupFunction<
|
||||
Pointer<NativeType> Function(),
|
||||
Pointer<NativeType> Function()
|
||||
>('EVP_sha1');
|
||||
final EVP_sha1 = libcrypto.lookupFunction<Pointer<NativeType> Function(),
|
||||
Pointer<NativeType> Function()>('EVP_sha1');
|
||||
|
||||
final EVP_sha256 = libcrypto.lookupFunction<
|
||||
Pointer<NativeType> Function(),
|
||||
Pointer<NativeType> Function()
|
||||
>('EVP_sha256');
|
||||
final EVP_sha256 = libcrypto.lookupFunction<Pointer<NativeType> Function(),
|
||||
Pointer<NativeType> Function()>('EVP_sha256');
|
||||
|
||||
final EVP_sha512 = libcrypto.lookupFunction<
|
||||
Pointer<NativeType> Function(),
|
||||
Pointer<NativeType> Function()
|
||||
>('EVP_sha512');
|
||||
final EVP_sha512 = libcrypto.lookupFunction<Pointer<NativeType> Function(),
|
||||
Pointer<NativeType> Function()>('EVP_sha512');
|
||||
|
||||
final EVP_aes_128_ctr = libcrypto.lookupFunction<
|
||||
Pointer<NativeType> Function(),
|
||||
Pointer<NativeType> Function()
|
||||
>('EVP_aes_128_ctr');
|
||||
final EVP_aes_128_ctr = libcrypto.lookupFunction<Pointer<NativeType> Function(),
|
||||
Pointer<NativeType> Function()>('EVP_aes_128_ctr');
|
||||
|
||||
final EVP_aes_256_ctr = libcrypto.lookupFunction<
|
||||
Pointer<NativeType> Function(),
|
||||
Pointer<NativeType> Function()
|
||||
>('EVP_aes_256_ctr');
|
||||
final EVP_aes_256_ctr = libcrypto.lookupFunction<Pointer<NativeType> Function(),
|
||||
Pointer<NativeType> Function()>('EVP_aes_256_ctr');
|
||||
|
||||
final EVP_CIPHER_CTX_new = libcrypto.lookupFunction<
|
||||
Pointer<NativeType> Function(),
|
||||
Pointer<NativeType> Function()
|
||||
>('EVP_CIPHER_CTX_new');
|
||||
Pointer<NativeType> Function(),
|
||||
Pointer<NativeType> Function()>('EVP_CIPHER_CTX_new');
|
||||
|
||||
final EVP_EncryptInit_ex = libcrypto.lookupFunction<
|
||||
Pointer<NativeType> Function(Pointer<NativeType> ctx, Pointer<NativeType> alg, Pointer<NativeType> some, Pointer<Uint8> key, Pointer<Uint8> iv),
|
||||
Pointer<NativeType> Function(Pointer<NativeType> ctx, Pointer<NativeType> alg, Pointer<NativeType> some, Pointer<Uint8> key, Pointer<Uint8> iv)
|
||||
>('EVP_EncryptInit_ex');
|
||||
Pointer<NativeType> Function(
|
||||
Pointer<NativeType> ctx,
|
||||
Pointer<NativeType> alg,
|
||||
Pointer<NativeType> some,
|
||||
Pointer<Uint8> key,
|
||||
Pointer<Uint8> iv),
|
||||
Pointer<NativeType> Function(
|
||||
Pointer<NativeType> ctx,
|
||||
Pointer<NativeType> alg,
|
||||
Pointer<NativeType> some,
|
||||
Pointer<Uint8> key,
|
||||
Pointer<Uint8> iv)>('EVP_EncryptInit_ex');
|
||||
|
||||
final EVP_EncryptUpdate = libcrypto.lookupFunction<
|
||||
Pointer<NativeType> Function(Pointer<NativeType> ctx, Pointer<Uint8> output, Pointer<IntPtr> outputLen, Pointer<Uint8> input, IntPtr inputLen),
|
||||
Pointer<NativeType> Function(Pointer<NativeType> ctx, Pointer<Uint8> output, Pointer<IntPtr> outputLen, Pointer<Uint8> input, int inputLen)
|
||||
>('EVP_EncryptUpdate');
|
||||
Pointer<NativeType> Function(Pointer<NativeType> ctx, Pointer<Uint8> output,
|
||||
Pointer<IntPtr> outputLen, Pointer<Uint8> input, IntPtr inputLen),
|
||||
Pointer<NativeType> Function(
|
||||
Pointer<NativeType> ctx,
|
||||
Pointer<Uint8> output,
|
||||
Pointer<IntPtr> outputLen,
|
||||
Pointer<Uint8> input,
|
||||
int inputLen)>('EVP_EncryptUpdate');
|
||||
|
||||
final EVP_EncryptFinal_ex = libcrypto.lookupFunction<
|
||||
Pointer<NativeType> Function(Pointer<NativeType> ctx, Pointer<Uint8> data, Pointer<IntPtr> len),
|
||||
Pointer<NativeType> Function(Pointer<NativeType> ctx, Pointer<Uint8> data, Pointer<IntPtr> len)
|
||||
>('EVP_EncryptFinal_ex');
|
||||
Pointer<NativeType> Function(
|
||||
Pointer<NativeType> ctx, Pointer<Uint8> data, Pointer<IntPtr> len),
|
||||
Pointer<NativeType> Function(Pointer<NativeType> ctx, Pointer<Uint8> data,
|
||||
Pointer<IntPtr> len)>('EVP_EncryptFinal_ex');
|
||||
|
||||
final EVP_CIPHER_CTX_free = libcrypto.lookupFunction<
|
||||
Pointer<NativeType> Function(Pointer<NativeType> ctx),
|
||||
Pointer<NativeType> Function(Pointer<NativeType> ctx)
|
||||
>('EVP_CIPHER_CTX_free');
|
||||
Pointer<NativeType> Function(Pointer<NativeType> ctx),
|
||||
Pointer<NativeType> Function(
|
||||
Pointer<NativeType> ctx)>('EVP_CIPHER_CTX_free');
|
||||
|
||||
final EVP_Digest = libcrypto.lookupFunction<
|
||||
IntPtr Function(Pointer<Uint8> data, IntPtr len, Pointer<Uint8> hash, Pointer<IntPtr> hsize, Pointer<NativeType> alg, Pointer<NativeType> engine),
|
||||
int Function(Pointer<Uint8> data, int len, Pointer<Uint8> hash, Pointer<IntPtr> hsize, Pointer<NativeType> alg, Pointer<NativeType> engine)
|
||||
>('EVP_Digest');
|
||||
IntPtr Function(
|
||||
Pointer<Uint8> data,
|
||||
IntPtr len,
|
||||
Pointer<Uint8> hash,
|
||||
Pointer<IntPtr> hsize,
|
||||
Pointer<NativeType> alg,
|
||||
Pointer<NativeType> engine),
|
||||
int Function(
|
||||
Pointer<Uint8> data,
|
||||
int len,
|
||||
Pointer<Uint8> hash,
|
||||
Pointer<IntPtr> hsize,
|
||||
Pointer<NativeType> alg,
|
||||
Pointer<NativeType> engine)>('EVP_Digest');
|
||||
|
||||
final EVP_MD_size = libcrypto.lookupFunction<
|
||||
IntPtr Function(Pointer<NativeType> ctx),
|
||||
int Function(Pointer<NativeType> ctx)
|
||||
>('EVP_MD_size');
|
||||
|
||||
IntPtr Function(Pointer<NativeType> ctx),
|
||||
int Function(Pointer<NativeType> ctx)>('EVP_MD_size');
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ abstract class Hash {
|
|||
Hash._(this.name);
|
||||
String name;
|
||||
|
||||
Future<Uint8List> call(Uint8List input) async => Uint8List.view(await digest(name, input));
|
||||
Future<Uint8List> call(Uint8List input) async =>
|
||||
Uint8List.view(await digest(name, input));
|
||||
}
|
||||
|
||||
final Hash sha1 = _Sha1();
|
||||
|
|
@ -33,10 +34,10 @@ abstract class Cipher {
|
|||
Cipher._(this.name);
|
||||
String name;
|
||||
Object params(Uint8List iv);
|
||||
Future<Uint8List> encrypt(Uint8List input, Uint8List key, Uint8List iv) async {
|
||||
Future<Uint8List> encrypt(
|
||||
Uint8List input, Uint8List key, Uint8List iv) async {
|
||||
final subtleKey = await importKey('raw', key, name, false, ['encrypt']);
|
||||
return (await subtle.encrypt(params(iv), subtleKey, input))
|
||||
.asUint8List();
|
||||
return (await subtle.encrypt(params(iv), subtleKey, input)).asUint8List();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -46,11 +47,18 @@ class _AesCtr extends Cipher {
|
|||
_AesCtr() : super._('AES-CTR');
|
||||
|
||||
@override
|
||||
Object params(Uint8List iv) => AesCtrParams(name: name, counter: iv, length: 64);
|
||||
Object params(Uint8List iv) =>
|
||||
AesCtrParams(name: name, counter: iv, length: 64);
|
||||
}
|
||||
|
||||
Future<Uint8List> pbkdf2(Uint8List passphrase, Uint8List salt, Hash hash, int iterations, int bits) async {
|
||||
final raw = await importKey('raw', passphrase, 'PBKDF2', false, ['deriveBits']);
|
||||
final res = await deriveBits(Pbkdf2Params(name: 'PBKDF2', hash: hash.name, salt: salt, iterations: iterations), raw, bits);
|
||||
Future<Uint8List> pbkdf2(Uint8List passphrase, Uint8List salt, Hash hash,
|
||||
int iterations, int bits) async {
|
||||
final raw =
|
||||
await importKey('raw', passphrase, 'PBKDF2', false, ['deriveBits']);
|
||||
final res = await deriveBits(
|
||||
Pbkdf2Params(
|
||||
name: 'PBKDF2', hash: hash.name, salt: salt, iterations: iterations),
|
||||
raw,
|
||||
bits);
|
||||
return Uint8List.view(res);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:ffi';
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
|
@ -8,7 +9,7 @@ abstract class Hash {
|
|||
Hash._(this.ptr);
|
||||
Pointer<NativeType> ptr;
|
||||
|
||||
Uint8List call(Uint8List data) {
|
||||
FutureOr<Uint8List> call(Uint8List data) {
|
||||
final outSize = EVP_MD_size(ptr);
|
||||
final mem = malloc.call<Uint8>(outSize + data.length);
|
||||
final dataMem = mem.elementAt(outSize);
|
||||
|
|
@ -41,9 +42,10 @@ class _Sha512 extends Hash {
|
|||
abstract class Cipher {
|
||||
Cipher._();
|
||||
Pointer<NativeType> getAlg(int keysize);
|
||||
Uint8List encrypt(Uint8List input, Uint8List key, Uint8List iv) {
|
||||
FutureOr<Uint8List> encrypt(Uint8List input, Uint8List key, Uint8List iv) {
|
||||
final alg = getAlg(key.length * 8);
|
||||
final mem = malloc.call<Uint8>(sizeOf<IntPtr>() + key.length + iv.length + input.length);
|
||||
final mem = malloc
|
||||
.call<Uint8>(sizeOf<IntPtr>() + key.length + iv.length + input.length);
|
||||
final lenMem = mem.cast<IntPtr>();
|
||||
final keyMem = mem.elementAt(sizeOf<IntPtr>());
|
||||
final ivMem = keyMem.elementAt(key.length);
|
||||
|
|
@ -72,14 +74,18 @@ class _AesCtr extends Cipher {
|
|||
@override
|
||||
Pointer<NativeType> getAlg(int keysize) {
|
||||
switch (keysize) {
|
||||
case 128: return EVP_aes_128_ctr();
|
||||
case 256: return EVP_aes_256_ctr();
|
||||
default: throw ArgumentError('invalid key size');
|
||||
case 128:
|
||||
return EVP_aes_128_ctr();
|
||||
case 256:
|
||||
return EVP_aes_256_ctr();
|
||||
default:
|
||||
throw ArgumentError('invalid key size');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Uint8List pbkdf2(Uint8List passphrase, Uint8List salt, Hash hash, int iterations, int bits) {
|
||||
FutureOr<Uint8List> pbkdf2(
|
||||
Uint8List passphrase, Uint8List salt, Hash hash, int iterations, int bits) {
|
||||
final outLen = bits ~/ 8;
|
||||
final mem = malloc.call<Uint8>(passphrase.length + salt.length + outLen);
|
||||
final saltMem = mem.elementAt(passphrase.length);
|
||||
|
|
@ -87,7 +93,8 @@ Uint8List pbkdf2(Uint8List passphrase, Uint8List salt, Hash hash, int iterations
|
|||
try {
|
||||
mem.asTypedList(passphrase.length).setAll(0, passphrase);
|
||||
saltMem.asTypedList(salt.length).setAll(0, salt);
|
||||
PKCS5_PBKDF2_HMAC(mem, passphrase.length, saltMem, salt.length, iterations, hash.ptr, outLen, outMem);
|
||||
PKCS5_PBKDF2_HMAC(mem, passphrase.length, saltMem, salt.length, iterations,
|
||||
hash.ptr, outLen, outMem);
|
||||
return Uint8List.fromList(outMem.asTypedList(outLen));
|
||||
} finally {
|
||||
malloc.free(mem);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ class CryptoKey {}
|
|||
@JS()
|
||||
@anonymous
|
||||
class Pbkdf2Params {
|
||||
external factory Pbkdf2Params({String name, String hash, Uint8List salt, int iterations});
|
||||
external factory Pbkdf2Params(
|
||||
{String name, String hash, Uint8List salt, int iterations});
|
||||
String name;
|
||||
String hash;
|
||||
Uint8List salt;
|
||||
|
|
@ -63,16 +64,20 @@ Future<dynamic> exportKey(String algorithm, CryptoKey key) {
|
|||
}
|
||||
|
||||
@JS('crypto.subtle.deriveKey')
|
||||
external dynamic _deriveKey(dynamic algorithm, CryptoKey baseKey, dynamic derivedKeyAlgorithm, bool extractable, List<String> keyUsages);
|
||||
external dynamic _deriveKey(dynamic algorithm, CryptoKey baseKey,
|
||||
dynamic derivedKeyAlgorithm, bool extractable, List<String> keyUsages);
|
||||
|
||||
Future<ByteBuffer> deriveKey(dynamic algorithm, CryptoKey baseKey, dynamic derivedKeyAlgorithm, bool extractable, List<String> keyUsages) {
|
||||
return promiseToFuture(_deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages));
|
||||
Future<ByteBuffer> deriveKey(dynamic algorithm, CryptoKey baseKey,
|
||||
dynamic derivedKeyAlgorithm, bool extractable, List<String> keyUsages) {
|
||||
return promiseToFuture(_deriveKey(
|
||||
algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages));
|
||||
}
|
||||
|
||||
@JS('crypto.subtle.deriveBits')
|
||||
external dynamic _deriveBits(dynamic algorithm, CryptoKey baseKey, int length);
|
||||
|
||||
Future<ByteBuffer> deriveBits(dynamic algorithm, CryptoKey baseKey, int length) {
|
||||
Future<ByteBuffer> deriveBits(
|
||||
dynamic algorithm, CryptoKey baseKey, int length) {
|
||||
return promiseToFuture(_deriveBits(algorithm, baseKey, length));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,4 +16,5 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export 'fake_database_native.dart' if (dart.library.js) 'fake_database_web.dart';
|
||||
export 'fake_database_native.dart'
|
||||
if (dart.library.js) 'fake_database_web.dart';
|
||||
|
|
|
|||
Loading…
Reference in New Issue