style: fix format and lint

This commit is contained in:
Lukas Lihotzki 2021-04-12 14:43:57 +02:00
parent ac9df588d1
commit 545ce26e39
7 changed files with 131 additions and 74 deletions

View File

@ -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,

View File

@ -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;
}

View File

@ -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');

View File

@ -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);
}

View File

@ -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);

View File

@ -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));
}

View File

@ -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';