feat(interface)!: add pigeon + add hmac + remove useless decryption method
This commit is contained in:
parent
ff981b2361
commit
0a040d2971
@ -1 +1,6 @@
|
|||||||
include: package:wyatt_analysis/analysis_options.flutter.yaml
|
include: package:wyatt_analysis/analysis_options.flutter.yaml
|
||||||
|
|
||||||
|
analyzer:
|
||||||
|
exclude:
|
||||||
|
- "**/*.pigeon.dart"
|
||||||
|
- "lib/src/pigeon/test_api.dart"
|
@ -1,14 +1,15 @@
|
|||||||
// Author: Hugo Pointcheval
|
// Copyright 2019-2023 Hugo Pointcheval
|
||||||
// Email: git@pcl.ovh
|
//
|
||||||
// -----
|
// Use of this source code is governed by an MIT-style
|
||||||
// File: native_crypto_platform_interface.dart
|
// license that can be found in the LICENSE file or at
|
||||||
// Created Date: 24/05/2022 19:39:11
|
// https://opensource.org/licenses/MIT.
|
||||||
// Last Modified: 24/05/2022 19:39:58
|
|
||||||
// -----
|
|
||||||
// Copyright (c) 2022
|
|
||||||
|
|
||||||
|
/// The interface that implementations of native_crypto must implement.
|
||||||
library native_crypto_platform_interface;
|
library native_crypto_platform_interface;
|
||||||
|
|
||||||
export 'src/method_channel/method_channel_native_crypto.dart';
|
export 'src/core/enums/exception_code.dart';
|
||||||
export 'src/platform_interface/native_crypto_platform.dart';
|
export 'src/core/enums/methods.dart';
|
||||||
export 'src/utils/exception.dart';
|
export 'src/core/exceptions/exception.dart';
|
||||||
|
export 'src/implementations/basic_message_channel_native_crypto.dart';
|
||||||
|
export 'src/implementations/method_channel_native_crypto.dart';
|
||||||
|
export 'src/interface/native_crypto_platform.dart';
|
||||||
|
@ -0,0 +1,84 @@
|
|||||||
|
// Copyright 2019-2023 Hugo Pointcheval
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
|
enum NativeCryptoExceptionCode {
|
||||||
|
/// The method is not implemented on the platform side.
|
||||||
|
platformMethodNotImplemented,
|
||||||
|
|
||||||
|
/// Platform returned invalid data.
|
||||||
|
/// Can be null, empty, or not the expected type.
|
||||||
|
platformReturnedInvalidData, // TODO(hpcl): remove this
|
||||||
|
|
||||||
|
/// The platforms returned null.
|
||||||
|
nullError,
|
||||||
|
|
||||||
|
/// The algorithm is not supported.
|
||||||
|
algorithmNotSupported,
|
||||||
|
|
||||||
|
/// The key is not valid. Like a bad length or format.
|
||||||
|
invalidKey,
|
||||||
|
|
||||||
|
/// The data is not valid.
|
||||||
|
invalidData,
|
||||||
|
|
||||||
|
/// The parameters are not valid. Like an invalid IV.
|
||||||
|
invalidParameters,
|
||||||
|
|
||||||
|
/// Authentication failed. Like a bad MAC or tag.
|
||||||
|
authenticationError,
|
||||||
|
|
||||||
|
/// An I/O error occurred.
|
||||||
|
ioError,
|
||||||
|
|
||||||
|
/// Key derivation failed.
|
||||||
|
keyDerivationError,
|
||||||
|
|
||||||
|
/// Channel error. Like a bad channel or a bad message.
|
||||||
|
channelError,
|
||||||
|
|
||||||
|
/// An unknown error occurred.
|
||||||
|
unknownError;
|
||||||
|
|
||||||
|
/// Returns code of the [NativeCryptoExceptionCode].
|
||||||
|
/// ```dart
|
||||||
|
/// print(NativeCryptoExceptionCode.platformMethodNotImplemented.code)
|
||||||
|
/// // => platform_method_not_implemented
|
||||||
|
/// ```
|
||||||
|
String get code {
|
||||||
|
switch (name.length) {
|
||||||
|
case 0:
|
||||||
|
return name;
|
||||||
|
case 1:
|
||||||
|
return name.toLowerCase();
|
||||||
|
default:
|
||||||
|
return name
|
||||||
|
.splitMapJoin(
|
||||||
|
RegExp('[A-Z]'),
|
||||||
|
onMatch: (m) => ' ${m[0]}',
|
||||||
|
onNonMatch: (n) => n,
|
||||||
|
)
|
||||||
|
.trim()
|
||||||
|
.splitMapJoin(
|
||||||
|
RegExp(r'\s+|-+|_+|\.+'),
|
||||||
|
onMatch: (m) => '_',
|
||||||
|
onNonMatch: (n) => n.toLowerCase(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the [NativeCryptoExceptionCode] from the given [code].
|
||||||
|
static NativeCryptoExceptionCode from(String code) {
|
||||||
|
for (final value in values) {
|
||||||
|
if (value.code == code) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return unknownError;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => code;
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2019-2023 Hugo Pointcheval
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
|
enum NativeCryptoMethod {
|
||||||
|
hash,
|
||||||
|
hmac,
|
||||||
|
generateSecureRandom,
|
||||||
|
pbkdf2,
|
||||||
|
encrypt,
|
||||||
|
decrypt,
|
||||||
|
encryptFile,
|
||||||
|
decryptFile,
|
||||||
|
encryptWithIV
|
||||||
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
// Copyright 2019-2023 Hugo Pointcheval
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:native_crypto_platform_interface/src/core/enums/exception_code.dart';
|
||||||
|
|
||||||
|
/// An exception thrown by the native crypto plugin.
|
||||||
|
class NativeCryptoException extends Equatable implements Exception {
|
||||||
|
/// Creates a new [NativeCryptoException].
|
||||||
|
const NativeCryptoException({
|
||||||
|
required this.code,
|
||||||
|
this.message,
|
||||||
|
this.stackTrace,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Creates a new [NativeCryptoException] from a [PlatformException].
|
||||||
|
factory NativeCryptoException.fromPlatformException(
|
||||||
|
PlatformException platformException,
|
||||||
|
StackTrace stackTrace,
|
||||||
|
) {
|
||||||
|
final Map<String, String>? details = platformException.details != null
|
||||||
|
? Map<String, String>.from(
|
||||||
|
platformException.details as Map<String, String>,
|
||||||
|
)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
String code = platformException.code.split('(').first;
|
||||||
|
String message = platformException.message ?? '';
|
||||||
|
|
||||||
|
if (details != null) {
|
||||||
|
code = details['code'] ?? code;
|
||||||
|
message = details['message'] ?? message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NativeCryptoException(
|
||||||
|
code: NativeCryptoExceptionCode.from(code),
|
||||||
|
message: message,
|
||||||
|
stackTrace: stackTrace,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The standardised error code.
|
||||||
|
final NativeCryptoExceptionCode code;
|
||||||
|
|
||||||
|
/// The long form message of the exception.
|
||||||
|
final String? message;
|
||||||
|
|
||||||
|
/// The stack trace which provides information to the user about the call
|
||||||
|
/// sequence that triggered an exception
|
||||||
|
final StackTrace? stackTrace;
|
||||||
|
|
||||||
|
static Never convertPlatformException(
|
||||||
|
Object exception,
|
||||||
|
StackTrace stackTrace,
|
||||||
|
) {
|
||||||
|
// If the exception is not a PlatformException, throw it as is.
|
||||||
|
if (exception is! Exception || exception is! PlatformException) {
|
||||||
|
Error.throwWithStackTrace(exception, stackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, throw a NativeCryptoException.
|
||||||
|
Error.throwWithStackTrace(
|
||||||
|
NativeCryptoException.fromPlatformException(exception, stackTrace),
|
||||||
|
stackTrace,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeCryptoException copyWith({
|
||||||
|
NativeCryptoExceptionCode? code,
|
||||||
|
String? message,
|
||||||
|
StackTrace? stackTrace,
|
||||||
|
}) =>
|
||||||
|
NativeCryptoException(
|
||||||
|
code: code ?? this.code,
|
||||||
|
message: message ?? this.message,
|
||||||
|
stackTrace: stackTrace ?? this.stackTrace,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final output = StringBuffer('[NativeCrypto/$code]');
|
||||||
|
|
||||||
|
if (message != null) {
|
||||||
|
output.write(' $message');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stackTrace != null) {
|
||||||
|
output.write('\n\n$stackTrace');
|
||||||
|
}
|
||||||
|
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [code, message, stackTrace];
|
||||||
|
}
|
@ -0,0 +1,204 @@
|
|||||||
|
// Copyright 2019-2023 Hugo Pointcheval
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:native_crypto_platform_interface/native_crypto_platform_interface.dart';
|
||||||
|
import 'package:native_crypto_platform_interface/src/pigeon/messages.pigeon.dart';
|
||||||
|
|
||||||
|
/// An implementation of [NativeCryptoPlatform] that uses Pigeon generated code.
|
||||||
|
class BasicMessageChannelNativeCrypto extends NativeCryptoPlatform {
|
||||||
|
/// The Pigeon API used to interact with the native platform.
|
||||||
|
@visibleForTesting
|
||||||
|
NativeCryptoAPI api = NativeCryptoAPI();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Uint8List?> hash(Uint8List data, {required String algorithm}) async {
|
||||||
|
try {
|
||||||
|
return api
|
||||||
|
.hash(
|
||||||
|
HashRequest(
|
||||||
|
data: data,
|
||||||
|
algorithm: algorithm,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.then((value) => value.hash);
|
||||||
|
} catch (e, s) {
|
||||||
|
NativeCryptoException.convertPlatformException(e, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Uint8List?> hmac(
|
||||||
|
Uint8List data, {
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
return api
|
||||||
|
.hmac(
|
||||||
|
HmacRequest(
|
||||||
|
data: data,
|
||||||
|
key: key,
|
||||||
|
algorithm: algorithm,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.then((value) => value.hmac);
|
||||||
|
} catch (e, s) {
|
||||||
|
NativeCryptoException.convertPlatformException(e, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Uint8List?> generateSecureRandom(int length) async {
|
||||||
|
try {
|
||||||
|
return api
|
||||||
|
.generateSecureRandom(
|
||||||
|
GenerateSecureRandomRequest(
|
||||||
|
length: length,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.then((value) => value.random);
|
||||||
|
} catch (e, s) {
|
||||||
|
NativeCryptoException.convertPlatformException(e, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Uint8List?> pbkdf2({
|
||||||
|
required Uint8List password,
|
||||||
|
required Uint8List salt,
|
||||||
|
required int length,
|
||||||
|
required int iterations,
|
||||||
|
required String hashAlgorithm,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
return api
|
||||||
|
.pbkdf2(
|
||||||
|
Pbkdf2Request(
|
||||||
|
password: password,
|
||||||
|
salt: salt,
|
||||||
|
length: length,
|
||||||
|
iterations: iterations,
|
||||||
|
hashAlgorithm: hashAlgorithm,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.then((value) => value.key);
|
||||||
|
} catch (e, s) {
|
||||||
|
NativeCryptoException.convertPlatformException(e, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Uint8List?> encrypt(
|
||||||
|
Uint8List plainText, {
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
return api
|
||||||
|
.encrypt(
|
||||||
|
EncryptRequest(
|
||||||
|
plainText: plainText,
|
||||||
|
key: key,
|
||||||
|
algorithm: algorithm,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.then((value) => value.cipherText);
|
||||||
|
} catch (e, s) {
|
||||||
|
NativeCryptoException.convertPlatformException(e, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Uint8List?> decrypt(
|
||||||
|
Uint8List cipherText, {
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
return api
|
||||||
|
.decrypt(
|
||||||
|
DecryptRequest(
|
||||||
|
cipherText: cipherText,
|
||||||
|
key: key,
|
||||||
|
algorithm: algorithm,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.then((value) => value.plainText);
|
||||||
|
} catch (e, s) {
|
||||||
|
NativeCryptoException.convertPlatformException(e, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool?> encryptFile({
|
||||||
|
required String plainTextPath,
|
||||||
|
required String cipherTextPath,
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
return api
|
||||||
|
.encryptFile(
|
||||||
|
EncryptFileRequest(
|
||||||
|
plainTextPath: plainTextPath,
|
||||||
|
cipherTextPath: cipherTextPath,
|
||||||
|
key: key,
|
||||||
|
algorithm: algorithm,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.then((value) => value.success);
|
||||||
|
} catch (e, s) {
|
||||||
|
NativeCryptoException.convertPlatformException(e, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool?> decryptFile({
|
||||||
|
required String cipherTextPath,
|
||||||
|
required String plainTextPath,
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
return api
|
||||||
|
.decryptFile(
|
||||||
|
DecryptFileRequest(
|
||||||
|
cipherTextPath: cipherTextPath,
|
||||||
|
plainTextPath: plainTextPath,
|
||||||
|
key: key,
|
||||||
|
algorithm: algorithm,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.then((value) => value.success);
|
||||||
|
} catch (e, s) {
|
||||||
|
NativeCryptoException.convertPlatformException(e, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Uint8List?> encryptWithIV({
|
||||||
|
required Uint8List plainText,
|
||||||
|
required Uint8List iv,
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
return api
|
||||||
|
.encryptWithIV(
|
||||||
|
EncryptWithIVRequest(
|
||||||
|
plainText: plainText,
|
||||||
|
iv: iv,
|
||||||
|
key: key,
|
||||||
|
algorithm: algorithm,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.then((value) => value.cipherText);
|
||||||
|
} catch (e, s) {
|
||||||
|
NativeCryptoException.convertPlatformException(e, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,161 @@
|
|||||||
|
// Copyright 2019-2023 Hugo Pointcheval
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:native_crypto_platform_interface/native_crypto_platform_interface.dart';
|
||||||
|
|
||||||
|
/// An implementation of [NativeCryptoPlatform] that uses method channels.
|
||||||
|
class MethodChannelNativeCrypto extends NativeCryptoPlatform {
|
||||||
|
/// The method channel used to interact with the native platform.
|
||||||
|
@visibleForTesting
|
||||||
|
MethodChannel channel = const MethodChannel('plugins.hugop.cl/native_crypto');
|
||||||
|
|
||||||
|
Future<T?> _invokeMethod<T>(
|
||||||
|
NativeCryptoMethod method, [
|
||||||
|
Map<String, dynamic>? arguments,
|
||||||
|
]) async {
|
||||||
|
try {
|
||||||
|
return await channel.invokeMethod<T>(method.name, arguments);
|
||||||
|
} on PlatformException catch (e, s) {
|
||||||
|
NativeCryptoException.convertPlatformException(e, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Uint8List?> hash(Uint8List data, {required String algorithm}) =>
|
||||||
|
_invokeMethod<Uint8List>(
|
||||||
|
NativeCryptoMethod.hash,
|
||||||
|
{
|
||||||
|
'data': data,
|
||||||
|
'algorithm': algorithm,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Uint8List?> hmac(
|
||||||
|
Uint8List data, {
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) =>
|
||||||
|
_invokeMethod<Uint8List>(
|
||||||
|
NativeCryptoMethod.hmac,
|
||||||
|
{
|
||||||
|
'data': data,
|
||||||
|
'key': key,
|
||||||
|
'algorithm': algorithm,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Uint8List?> generateSecureRandom(int length) =>
|
||||||
|
_invokeMethod<Uint8List>(
|
||||||
|
NativeCryptoMethod.generateSecureRandom,
|
||||||
|
{
|
||||||
|
'length': length,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Uint8List?> pbkdf2({
|
||||||
|
required Uint8List password,
|
||||||
|
required Uint8List salt,
|
||||||
|
required int length,
|
||||||
|
required int iterations,
|
||||||
|
required String hashAlgorithm,
|
||||||
|
}) =>
|
||||||
|
_invokeMethod<Uint8List>(
|
||||||
|
NativeCryptoMethod.pbkdf2,
|
||||||
|
{
|
||||||
|
'password': password,
|
||||||
|
'salt': salt,
|
||||||
|
'length': length,
|
||||||
|
'iterations': iterations,
|
||||||
|
'hashAlgorithm': hashAlgorithm,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Uint8List?> encrypt(
|
||||||
|
Uint8List plainText, {
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) =>
|
||||||
|
_invokeMethod<Uint8List>(
|
||||||
|
NativeCryptoMethod.encrypt,
|
||||||
|
{
|
||||||
|
'plainText': plainText,
|
||||||
|
'key': key,
|
||||||
|
'algorithm': algorithm,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Uint8List?> decrypt(
|
||||||
|
Uint8List cipherText, {
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) =>
|
||||||
|
_invokeMethod<Uint8List>(
|
||||||
|
NativeCryptoMethod.decrypt,
|
||||||
|
{
|
||||||
|
'cipherText': cipherText,
|
||||||
|
'key': key,
|
||||||
|
'algorithm': algorithm,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool?> encryptFile({
|
||||||
|
required String plainTextPath,
|
||||||
|
required String cipherTextPath,
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) =>
|
||||||
|
_invokeMethod<bool>(
|
||||||
|
NativeCryptoMethod.encryptFile,
|
||||||
|
{
|
||||||
|
'plainTextPath': plainTextPath,
|
||||||
|
'cipherTextPath': cipherTextPath,
|
||||||
|
'key': key,
|
||||||
|
'algorithm': algorithm,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool?> decryptFile({
|
||||||
|
required String cipherTextPath,
|
||||||
|
required String plainTextPath,
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) =>
|
||||||
|
_invokeMethod<bool>(
|
||||||
|
NativeCryptoMethod.decryptFile,
|
||||||
|
{
|
||||||
|
'cipherTextPath': cipherTextPath,
|
||||||
|
'plainTextPath': plainTextPath,
|
||||||
|
'key': key,
|
||||||
|
'algorithm': algorithm,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Uint8List?> encryptWithIV({
|
||||||
|
required Uint8List plainText,
|
||||||
|
required Uint8List iv,
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) =>
|
||||||
|
_invokeMethod<Uint8List>(
|
||||||
|
NativeCryptoMethod.encryptWithIV,
|
||||||
|
{
|
||||||
|
'plainText': plainText,
|
||||||
|
'iv': iv,
|
||||||
|
'key': key,
|
||||||
|
'algorithm': algorithm,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
// Copyright 2019-2023 Hugo Pointcheval
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:native_crypto_platform_interface/native_crypto_platform_interface.dart';
|
||||||
|
import 'package:native_crypto_platform_interface/src/implementations/method_channel_native_crypto.dart';
|
||||||
|
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
||||||
|
|
||||||
|
/// The interface that implementations of native_crypto must implement.
|
||||||
|
///
|
||||||
|
/// Platform implementations should extend this class rather than implement
|
||||||
|
/// it as `NativeCrypto` does not consider newly added methods to be
|
||||||
|
/// breaking changes. Extending this class (using `extends`) ensures
|
||||||
|
/// that the subclass will get the default implementation, while platform
|
||||||
|
/// implementations that `implements` this interface will be
|
||||||
|
/// broken by newly added [NativeCryptoPlatform] methods.
|
||||||
|
abstract class NativeCryptoPlatform extends PlatformInterface {
|
||||||
|
/// Constructs a NativeCryptoPlatform.
|
||||||
|
NativeCryptoPlatform() : super(token: _token);
|
||||||
|
|
||||||
|
static final Object _token = Object();
|
||||||
|
|
||||||
|
static NativeCryptoPlatform _instance = MethodChannelNativeCrypto();
|
||||||
|
|
||||||
|
/// The default instance of [NativeCryptoPlatform] to use.
|
||||||
|
///
|
||||||
|
/// Defaults to [MethodChannelNativeCrypto].
|
||||||
|
static NativeCryptoPlatform get instance => _instance;
|
||||||
|
|
||||||
|
/// Platform-specific plugins should set this with their own platform-specific
|
||||||
|
/// class that extends [NativeCryptoPlatform] when they register themselves.
|
||||||
|
static set instance(NativeCryptoPlatform instance) {
|
||||||
|
PlatformInterface.verify(instance, _token);
|
||||||
|
_instance = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the hash of the given data.
|
||||||
|
Future<Uint8List?> hash(Uint8List data, {required String algorithm}) {
|
||||||
|
throw UnimplementedError('hash is not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the hmac of the given data using the given key.
|
||||||
|
Future<Uint8List?> hmac(
|
||||||
|
Uint8List data, {
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) {
|
||||||
|
throw UnimplementedError('hmac is not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generates a secure random of the given length in bytes.
|
||||||
|
Future<Uint8List?> generateSecureRandom(int length) {
|
||||||
|
throw UnimplementedError('generateSecureRandom is not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Derives a key from the given password and salt using pbkdf2.
|
||||||
|
Future<Uint8List?> pbkdf2({
|
||||||
|
required Uint8List password,
|
||||||
|
required Uint8List salt,
|
||||||
|
required int length,
|
||||||
|
required int iterations,
|
||||||
|
required String hashAlgorithm,
|
||||||
|
}) {
|
||||||
|
throw UnimplementedError('pbkdf2 is not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Encrypts the given data using the given key and algorithm.
|
||||||
|
Future<Uint8List?> encrypt(
|
||||||
|
Uint8List plainText, {
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) {
|
||||||
|
throw UnimplementedError('encrypt is not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Decrypts the given data using the given key and algorithm.
|
||||||
|
Future<Uint8List?> decrypt(
|
||||||
|
Uint8List cipherText, {
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) {
|
||||||
|
throw UnimplementedError('decrypt is not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Encrypts the given file using the given key and algorithm.
|
||||||
|
Future<bool?> encryptFile({
|
||||||
|
required String plainTextPath,
|
||||||
|
required String cipherTextPath,
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) {
|
||||||
|
throw UnimplementedError('encryptFile is not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Decrypts the given file using the given key and algorithm.
|
||||||
|
Future<bool?> decryptFile({
|
||||||
|
required String cipherTextPath,
|
||||||
|
required String plainTextPath,
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) {
|
||||||
|
throw UnimplementedError('decryptFile is not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Encrypts the given data using the given key, algorithm and iv.
|
||||||
|
///
|
||||||
|
/// Users should use [encrypt] instead if they don't need to specify the iv.
|
||||||
|
Future<Uint8List?> encryptWithIV({
|
||||||
|
required Uint8List plainText,
|
||||||
|
required Uint8List iv,
|
||||||
|
required Uint8List key,
|
||||||
|
required String algorithm,
|
||||||
|
}) {
|
||||||
|
throw UnimplementedError('encryptWithIV is not implemented');
|
||||||
|
}
|
||||||
|
}
|
@ -1,154 +0,0 @@
|
|||||||
// Author: Hugo Pointcheval
|
|
||||||
// Email: git@pcl.ovh
|
|
||||||
// -----
|
|
||||||
// File: native_crypto_method_channel.dart
|
|
||||||
// Created Date: 25/12/2021 16:58:04
|
|
||||||
// Last Modified: 25/05/2022 10:40:29
|
|
||||||
// -----
|
|
||||||
// Copyright (c) 2021
|
|
||||||
|
|
||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:native_crypto_platform_interface/native_crypto_platform_interface.dart';
|
|
||||||
|
|
||||||
/// An implementation of [NativeCryptoPlatform] that uses method channels.
|
|
||||||
class MethodChannelNativeCrypto extends NativeCryptoPlatform {
|
|
||||||
/// The method channel used to interact with the native platform.
|
|
||||||
@visibleForTesting
|
|
||||||
MethodChannel channel = const MethodChannel('plugins.hugop.cl/native_crypto');
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Uint8List?> digest(Uint8List data, String algorithm) async {
|
|
||||||
try {
|
|
||||||
return await channel.invokeMethod<Uint8List>(
|
|
||||||
'digest',
|
|
||||||
<String, dynamic>{
|
|
||||||
'data': data,
|
|
||||||
'algorithm': algorithm,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} catch (e, s) {
|
|
||||||
NativeCryptoException.convertPlatformException(e, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Uint8List?> generateSecretKey(int bitsCount) async {
|
|
||||||
try {
|
|
||||||
return await channel.invokeMethod<Uint8List>(
|
|
||||||
'generateSecretKey',
|
|
||||||
<String, dynamic>{
|
|
||||||
'bitsCount': bitsCount,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} catch (e, s) {
|
|
||||||
NativeCryptoException.convertPlatformException(e, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Uint8List?> pbkdf2(
|
|
||||||
String password,
|
|
||||||
String salt,
|
|
||||||
int keyBytesCount,
|
|
||||||
int iterations,
|
|
||||||
String algorithm,
|
|
||||||
) async {
|
|
||||||
try {
|
|
||||||
return await channel.invokeMethod<Uint8List>(
|
|
||||||
'pbkdf2',
|
|
||||||
<String, dynamic>{
|
|
||||||
'password': password,
|
|
||||||
'salt': salt,
|
|
||||||
'keyBytesCount': keyBytesCount,
|
|
||||||
'iterations': iterations,
|
|
||||||
'algorithm': algorithm,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} catch (e, s) {
|
|
||||||
NativeCryptoException.convertPlatformException(e, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Uint8List>?> encryptAsList(
|
|
||||||
Uint8List data,
|
|
||||||
Uint8List key,
|
|
||||||
String algorithm,
|
|
||||||
) async {
|
|
||||||
try {
|
|
||||||
return await channel.invokeListMethod(
|
|
||||||
'encryptAsList',
|
|
||||||
<String, dynamic>{
|
|
||||||
'data': data,
|
|
||||||
'key': key,
|
|
||||||
'algorithm': algorithm,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} catch (e, s) {
|
|
||||||
NativeCryptoException.convertPlatformException(e, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Uint8List?> decryptAsList(
|
|
||||||
List<Uint8List> data,
|
|
||||||
Uint8List key,
|
|
||||||
String algorithm,
|
|
||||||
) async {
|
|
||||||
try {
|
|
||||||
return await channel.invokeMethod<Uint8List>(
|
|
||||||
'decryptAsList',
|
|
||||||
<String, dynamic>{
|
|
||||||
'data': data,
|
|
||||||
'key': key,
|
|
||||||
'algorithm': algorithm,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} catch (e, s) {
|
|
||||||
NativeCryptoException.convertPlatformException(e, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Uint8List?> encrypt(
|
|
||||||
Uint8List data,
|
|
||||||
Uint8List key,
|
|
||||||
String algorithm,
|
|
||||||
) async {
|
|
||||||
try {
|
|
||||||
return await channel.invokeMethod<Uint8List>(
|
|
||||||
'encrypt',
|
|
||||||
<String, dynamic>{
|
|
||||||
'data': data,
|
|
||||||
'key': key,
|
|
||||||
'algorithm': algorithm,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} catch (e, s) {
|
|
||||||
NativeCryptoException.convertPlatformException(e, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Uint8List?> decrypt(
|
|
||||||
Uint8List data,
|
|
||||||
Uint8List key,
|
|
||||||
String algorithm,
|
|
||||||
) async {
|
|
||||||
try {
|
|
||||||
return await channel.invokeMethod<Uint8List>(
|
|
||||||
'decrypt',
|
|
||||||
<String, dynamic>{
|
|
||||||
'data': data,
|
|
||||||
'key': key,
|
|
||||||
'algorithm': algorithm,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} catch (e, s) {
|
|
||||||
NativeCryptoException.convertPlatformException(e, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,829 @@
|
|||||||
|
// Copyright 2019-2023 Hugo Pointcheval
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://opensource.org/licenses/MIT.
|
||||||
|
// --
|
||||||
|
// Autogenerated from Pigeon (v9.0.0), do not edit directly.
|
||||||
|
// See also: https://pub.dev/packages/pigeon
|
||||||
|
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
class HashRequest {
|
||||||
|
HashRequest({
|
||||||
|
this.data,
|
||||||
|
this.algorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
Uint8List? data;
|
||||||
|
|
||||||
|
String? algorithm;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
data,
|
||||||
|
algorithm,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static HashRequest decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return HashRequest(
|
||||||
|
data: result[0] as Uint8List?,
|
||||||
|
algorithm: result[1] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HashResponse {
|
||||||
|
HashResponse({
|
||||||
|
this.hash,
|
||||||
|
});
|
||||||
|
|
||||||
|
Uint8List? hash;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
hash,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static HashResponse decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return HashResponse(
|
||||||
|
hash: result[0] as Uint8List?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HmacRequest {
|
||||||
|
HmacRequest({
|
||||||
|
this.data,
|
||||||
|
this.key,
|
||||||
|
this.algorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
Uint8List? data;
|
||||||
|
|
||||||
|
Uint8List? key;
|
||||||
|
|
||||||
|
String? algorithm;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
data,
|
||||||
|
key,
|
||||||
|
algorithm,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static HmacRequest decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return HmacRequest(
|
||||||
|
data: result[0] as Uint8List?,
|
||||||
|
key: result[1] as Uint8List?,
|
||||||
|
algorithm: result[2] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HmacResponse {
|
||||||
|
HmacResponse({
|
||||||
|
this.hmac,
|
||||||
|
});
|
||||||
|
|
||||||
|
Uint8List? hmac;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
hmac,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static HmacResponse decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return HmacResponse(
|
||||||
|
hmac: result[0] as Uint8List?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GenerateSecureRandomRequest {
|
||||||
|
GenerateSecureRandomRequest({
|
||||||
|
this.length,
|
||||||
|
});
|
||||||
|
|
||||||
|
int? length;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
length,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static GenerateSecureRandomRequest decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return GenerateSecureRandomRequest(
|
||||||
|
length: result[0] as int?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GenerateSecureRandomResponse {
|
||||||
|
GenerateSecureRandomResponse({
|
||||||
|
this.random,
|
||||||
|
});
|
||||||
|
|
||||||
|
Uint8List? random;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
random,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static GenerateSecureRandomResponse decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return GenerateSecureRandomResponse(
|
||||||
|
random: result[0] as Uint8List?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Pbkdf2Request {
|
||||||
|
Pbkdf2Request({
|
||||||
|
this.password,
|
||||||
|
this.salt,
|
||||||
|
this.length,
|
||||||
|
this.iterations,
|
||||||
|
this.hashAlgorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
Uint8List? password;
|
||||||
|
|
||||||
|
Uint8List? salt;
|
||||||
|
|
||||||
|
int? length;
|
||||||
|
|
||||||
|
int? iterations;
|
||||||
|
|
||||||
|
String? hashAlgorithm;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
password,
|
||||||
|
salt,
|
||||||
|
length,
|
||||||
|
iterations,
|
||||||
|
hashAlgorithm,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static Pbkdf2Request decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return Pbkdf2Request(
|
||||||
|
password: result[0] as Uint8List?,
|
||||||
|
salt: result[1] as Uint8List?,
|
||||||
|
length: result[2] as int?,
|
||||||
|
iterations: result[3] as int?,
|
||||||
|
hashAlgorithm: result[4] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Pbkdf2Response {
|
||||||
|
Pbkdf2Response({
|
||||||
|
this.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
Uint8List? key;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
key,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static Pbkdf2Response decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return Pbkdf2Response(
|
||||||
|
key: result[0] as Uint8List?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EncryptRequest {
|
||||||
|
EncryptRequest({
|
||||||
|
this.plainText,
|
||||||
|
this.key,
|
||||||
|
this.algorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
Uint8List? plainText;
|
||||||
|
|
||||||
|
Uint8List? key;
|
||||||
|
|
||||||
|
String? algorithm;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
plainText,
|
||||||
|
key,
|
||||||
|
algorithm,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static EncryptRequest decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return EncryptRequest(
|
||||||
|
plainText: result[0] as Uint8List?,
|
||||||
|
key: result[1] as Uint8List?,
|
||||||
|
algorithm: result[2] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EncryptResponse {
|
||||||
|
EncryptResponse({
|
||||||
|
this.cipherText,
|
||||||
|
});
|
||||||
|
|
||||||
|
Uint8List? cipherText;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
cipherText,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static EncryptResponse decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return EncryptResponse(
|
||||||
|
cipherText: result[0] as Uint8List?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DecryptRequest {
|
||||||
|
DecryptRequest({
|
||||||
|
this.cipherText,
|
||||||
|
this.key,
|
||||||
|
this.algorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
Uint8List? cipherText;
|
||||||
|
|
||||||
|
Uint8List? key;
|
||||||
|
|
||||||
|
String? algorithm;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
cipherText,
|
||||||
|
key,
|
||||||
|
algorithm,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static DecryptRequest decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return DecryptRequest(
|
||||||
|
cipherText: result[0] as Uint8List?,
|
||||||
|
key: result[1] as Uint8List?,
|
||||||
|
algorithm: result[2] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DecryptResponse {
|
||||||
|
DecryptResponse({
|
||||||
|
this.plainText,
|
||||||
|
});
|
||||||
|
|
||||||
|
Uint8List? plainText;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
plainText,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static DecryptResponse decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return DecryptResponse(
|
||||||
|
plainText: result[0] as Uint8List?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EncryptFileRequest {
|
||||||
|
EncryptFileRequest({
|
||||||
|
this.plainTextPath,
|
||||||
|
this.cipherTextPath,
|
||||||
|
this.key,
|
||||||
|
this.algorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
String? plainTextPath;
|
||||||
|
|
||||||
|
String? cipherTextPath;
|
||||||
|
|
||||||
|
Uint8List? key;
|
||||||
|
|
||||||
|
String? algorithm;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
plainTextPath,
|
||||||
|
cipherTextPath,
|
||||||
|
key,
|
||||||
|
algorithm,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static EncryptFileRequest decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return EncryptFileRequest(
|
||||||
|
plainTextPath: result[0] as String?,
|
||||||
|
cipherTextPath: result[1] as String?,
|
||||||
|
key: result[2] as Uint8List?,
|
||||||
|
algorithm: result[3] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EncryptFileResponse {
|
||||||
|
EncryptFileResponse({
|
||||||
|
this.success,
|
||||||
|
});
|
||||||
|
|
||||||
|
bool? success;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
success,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static EncryptFileResponse decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return EncryptFileResponse(
|
||||||
|
success: result[0] as bool?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DecryptFileRequest {
|
||||||
|
DecryptFileRequest({
|
||||||
|
this.cipherTextPath,
|
||||||
|
this.plainTextPath,
|
||||||
|
this.key,
|
||||||
|
this.algorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
String? cipherTextPath;
|
||||||
|
|
||||||
|
String? plainTextPath;
|
||||||
|
|
||||||
|
Uint8List? key;
|
||||||
|
|
||||||
|
String? algorithm;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
cipherTextPath,
|
||||||
|
plainTextPath,
|
||||||
|
key,
|
||||||
|
algorithm,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static DecryptFileRequest decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return DecryptFileRequest(
|
||||||
|
cipherTextPath: result[0] as String?,
|
||||||
|
plainTextPath: result[1] as String?,
|
||||||
|
key: result[2] as Uint8List?,
|
||||||
|
algorithm: result[3] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DecryptFileResponse {
|
||||||
|
DecryptFileResponse({
|
||||||
|
this.success,
|
||||||
|
});
|
||||||
|
|
||||||
|
bool? success;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
success,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static DecryptFileResponse decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return DecryptFileResponse(
|
||||||
|
success: result[0] as bool?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EncryptWithIVRequest {
|
||||||
|
EncryptWithIVRequest({
|
||||||
|
this.plainText,
|
||||||
|
this.iv,
|
||||||
|
this.key,
|
||||||
|
this.algorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
Uint8List? plainText;
|
||||||
|
|
||||||
|
Uint8List? iv;
|
||||||
|
|
||||||
|
Uint8List? key;
|
||||||
|
|
||||||
|
String? algorithm;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
plainText,
|
||||||
|
iv,
|
||||||
|
key,
|
||||||
|
algorithm,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static EncryptWithIVRequest decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return EncryptWithIVRequest(
|
||||||
|
plainText: result[0] as Uint8List?,
|
||||||
|
iv: result[1] as Uint8List?,
|
||||||
|
key: result[2] as Uint8List?,
|
||||||
|
algorithm: result[3] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NativeCryptoAPICodec extends StandardMessageCodec {
|
||||||
|
const _NativeCryptoAPICodec();
|
||||||
|
@override
|
||||||
|
void writeValue(WriteBuffer buffer, Object? value) {
|
||||||
|
if (value is DecryptFileRequest) {
|
||||||
|
buffer.putUint8(128);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is DecryptFileResponse) {
|
||||||
|
buffer.putUint8(129);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is DecryptRequest) {
|
||||||
|
buffer.putUint8(130);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is DecryptResponse) {
|
||||||
|
buffer.putUint8(131);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is EncryptFileRequest) {
|
||||||
|
buffer.putUint8(132);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is EncryptFileResponse) {
|
||||||
|
buffer.putUint8(133);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is EncryptRequest) {
|
||||||
|
buffer.putUint8(134);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is EncryptResponse) {
|
||||||
|
buffer.putUint8(135);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is EncryptWithIVRequest) {
|
||||||
|
buffer.putUint8(136);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is GenerateSecureRandomRequest) {
|
||||||
|
buffer.putUint8(137);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is GenerateSecureRandomResponse) {
|
||||||
|
buffer.putUint8(138);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is HashRequest) {
|
||||||
|
buffer.putUint8(139);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is HashResponse) {
|
||||||
|
buffer.putUint8(140);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is HmacRequest) {
|
||||||
|
buffer.putUint8(141);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is HmacResponse) {
|
||||||
|
buffer.putUint8(142);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is Pbkdf2Request) {
|
||||||
|
buffer.putUint8(143);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is Pbkdf2Response) {
|
||||||
|
buffer.putUint8(144);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else {
|
||||||
|
super.writeValue(buffer, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Object? readValueOfType(int type, ReadBuffer buffer) {
|
||||||
|
switch (type) {
|
||||||
|
case 128:
|
||||||
|
return DecryptFileRequest.decode(readValue(buffer)!);
|
||||||
|
case 129:
|
||||||
|
return DecryptFileResponse.decode(readValue(buffer)!);
|
||||||
|
case 130:
|
||||||
|
return DecryptRequest.decode(readValue(buffer)!);
|
||||||
|
case 131:
|
||||||
|
return DecryptResponse.decode(readValue(buffer)!);
|
||||||
|
case 132:
|
||||||
|
return EncryptFileRequest.decode(readValue(buffer)!);
|
||||||
|
case 133:
|
||||||
|
return EncryptFileResponse.decode(readValue(buffer)!);
|
||||||
|
case 134:
|
||||||
|
return EncryptRequest.decode(readValue(buffer)!);
|
||||||
|
case 135:
|
||||||
|
return EncryptResponse.decode(readValue(buffer)!);
|
||||||
|
case 136:
|
||||||
|
return EncryptWithIVRequest.decode(readValue(buffer)!);
|
||||||
|
case 137:
|
||||||
|
return GenerateSecureRandomRequest.decode(readValue(buffer)!);
|
||||||
|
case 138:
|
||||||
|
return GenerateSecureRandomResponse.decode(readValue(buffer)!);
|
||||||
|
case 139:
|
||||||
|
return HashRequest.decode(readValue(buffer)!);
|
||||||
|
case 140:
|
||||||
|
return HashResponse.decode(readValue(buffer)!);
|
||||||
|
case 141:
|
||||||
|
return HmacRequest.decode(readValue(buffer)!);
|
||||||
|
case 142:
|
||||||
|
return HmacResponse.decode(readValue(buffer)!);
|
||||||
|
case 143:
|
||||||
|
return Pbkdf2Request.decode(readValue(buffer)!);
|
||||||
|
case 144:
|
||||||
|
return Pbkdf2Response.decode(readValue(buffer)!);
|
||||||
|
default:
|
||||||
|
return super.readValueOfType(type, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NativeCryptoAPI {
|
||||||
|
/// Constructor for [NativeCryptoAPI]. The [binaryMessenger] named argument is
|
||||||
|
/// available for dependency injection. If it is left null, the default
|
||||||
|
/// BinaryMessenger will be used which routes to the host platform.
|
||||||
|
NativeCryptoAPI({BinaryMessenger? binaryMessenger})
|
||||||
|
: _binaryMessenger = binaryMessenger;
|
||||||
|
final BinaryMessenger? _binaryMessenger;
|
||||||
|
|
||||||
|
static const MessageCodec<Object?> codec = _NativeCryptoAPICodec();
|
||||||
|
|
||||||
|
Future<HashResponse> hash(HashRequest arg_request) async {
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.hash', codec,
|
||||||
|
binaryMessenger: _binaryMessenger);
|
||||||
|
final List<Object?>? replyList =
|
||||||
|
await channel.send(<Object?>[arg_request]) as List<Object?>?;
|
||||||
|
if (replyList == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'channel-error',
|
||||||
|
message: 'Unable to establish connection on channel.',
|
||||||
|
);
|
||||||
|
} else if (replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: replyList[0]! as String,
|
||||||
|
message: replyList[1] as String?,
|
||||||
|
details: replyList[2],
|
||||||
|
);
|
||||||
|
} else if (replyList[0] == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'null-error',
|
||||||
|
message: 'Host platform returned null value for non-null return value.',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (replyList[0] as HashResponse?)!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<HmacResponse> hmac(HmacRequest arg_request) async {
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.hmac', codec,
|
||||||
|
binaryMessenger: _binaryMessenger);
|
||||||
|
final List<Object?>? replyList =
|
||||||
|
await channel.send(<Object?>[arg_request]) as List<Object?>?;
|
||||||
|
if (replyList == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'channel-error',
|
||||||
|
message: 'Unable to establish connection on channel.',
|
||||||
|
);
|
||||||
|
} else if (replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: replyList[0]! as String,
|
||||||
|
message: replyList[1] as String?,
|
||||||
|
details: replyList[2],
|
||||||
|
);
|
||||||
|
} else if (replyList[0] == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'null-error',
|
||||||
|
message: 'Host platform returned null value for non-null return value.',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (replyList[0] as HmacResponse?)!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<GenerateSecureRandomResponse> generateSecureRandom(GenerateSecureRandomRequest arg_request) async {
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.generateSecureRandom', codec,
|
||||||
|
binaryMessenger: _binaryMessenger);
|
||||||
|
final List<Object?>? replyList =
|
||||||
|
await channel.send(<Object?>[arg_request]) as List<Object?>?;
|
||||||
|
if (replyList == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'channel-error',
|
||||||
|
message: 'Unable to establish connection on channel.',
|
||||||
|
);
|
||||||
|
} else if (replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: replyList[0]! as String,
|
||||||
|
message: replyList[1] as String?,
|
||||||
|
details: replyList[2],
|
||||||
|
);
|
||||||
|
} else if (replyList[0] == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'null-error',
|
||||||
|
message: 'Host platform returned null value for non-null return value.',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (replyList[0] as GenerateSecureRandomResponse?)!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Pbkdf2Response> pbkdf2(Pbkdf2Request arg_request) async {
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.pbkdf2', codec,
|
||||||
|
binaryMessenger: _binaryMessenger);
|
||||||
|
final List<Object?>? replyList =
|
||||||
|
await channel.send(<Object?>[arg_request]) as List<Object?>?;
|
||||||
|
if (replyList == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'channel-error',
|
||||||
|
message: 'Unable to establish connection on channel.',
|
||||||
|
);
|
||||||
|
} else if (replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: replyList[0]! as String,
|
||||||
|
message: replyList[1] as String?,
|
||||||
|
details: replyList[2],
|
||||||
|
);
|
||||||
|
} else if (replyList[0] == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'null-error',
|
||||||
|
message: 'Host platform returned null value for non-null return value.',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (replyList[0] as Pbkdf2Response?)!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<EncryptResponse> encrypt(EncryptRequest arg_request) async {
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.encrypt', codec,
|
||||||
|
binaryMessenger: _binaryMessenger);
|
||||||
|
final List<Object?>? replyList =
|
||||||
|
await channel.send(<Object?>[arg_request]) as List<Object?>?;
|
||||||
|
if (replyList == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'channel-error',
|
||||||
|
message: 'Unable to establish connection on channel.',
|
||||||
|
);
|
||||||
|
} else if (replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: replyList[0]! as String,
|
||||||
|
message: replyList[1] as String?,
|
||||||
|
details: replyList[2],
|
||||||
|
);
|
||||||
|
} else if (replyList[0] == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'null-error',
|
||||||
|
message: 'Host platform returned null value for non-null return value.',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (replyList[0] as EncryptResponse?)!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<DecryptResponse> decrypt(DecryptRequest arg_request) async {
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.decrypt', codec,
|
||||||
|
binaryMessenger: _binaryMessenger);
|
||||||
|
final List<Object?>? replyList =
|
||||||
|
await channel.send(<Object?>[arg_request]) as List<Object?>?;
|
||||||
|
if (replyList == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'channel-error',
|
||||||
|
message: 'Unable to establish connection on channel.',
|
||||||
|
);
|
||||||
|
} else if (replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: replyList[0]! as String,
|
||||||
|
message: replyList[1] as String?,
|
||||||
|
details: replyList[2],
|
||||||
|
);
|
||||||
|
} else if (replyList[0] == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'null-error',
|
||||||
|
message: 'Host platform returned null value for non-null return value.',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (replyList[0] as DecryptResponse?)!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<EncryptFileResponse> encryptFile(EncryptFileRequest arg_request) async {
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.encryptFile', codec,
|
||||||
|
binaryMessenger: _binaryMessenger);
|
||||||
|
final List<Object?>? replyList =
|
||||||
|
await channel.send(<Object?>[arg_request]) as List<Object?>?;
|
||||||
|
if (replyList == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'channel-error',
|
||||||
|
message: 'Unable to establish connection on channel.',
|
||||||
|
);
|
||||||
|
} else if (replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: replyList[0]! as String,
|
||||||
|
message: replyList[1] as String?,
|
||||||
|
details: replyList[2],
|
||||||
|
);
|
||||||
|
} else if (replyList[0] == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'null-error',
|
||||||
|
message: 'Host platform returned null value for non-null return value.',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (replyList[0] as EncryptFileResponse?)!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<DecryptFileResponse> decryptFile(DecryptFileRequest arg_request) async {
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.decryptFile', codec,
|
||||||
|
binaryMessenger: _binaryMessenger);
|
||||||
|
final List<Object?>? replyList =
|
||||||
|
await channel.send(<Object?>[arg_request]) as List<Object?>?;
|
||||||
|
if (replyList == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'channel-error',
|
||||||
|
message: 'Unable to establish connection on channel.',
|
||||||
|
);
|
||||||
|
} else if (replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: replyList[0]! as String,
|
||||||
|
message: replyList[1] as String?,
|
||||||
|
details: replyList[2],
|
||||||
|
);
|
||||||
|
} else if (replyList[0] == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'null-error',
|
||||||
|
message: 'Host platform returned null value for non-null return value.',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (replyList[0] as DecryptFileResponse?)!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<EncryptResponse> encryptWithIV(EncryptWithIVRequest arg_request) async {
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.encryptWithIV', codec,
|
||||||
|
binaryMessenger: _binaryMessenger);
|
||||||
|
final List<Object?>? replyList =
|
||||||
|
await channel.send(<Object?>[arg_request]) as List<Object?>?;
|
||||||
|
if (replyList == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'channel-error',
|
||||||
|
message: 'Unable to establish connection on channel.',
|
||||||
|
);
|
||||||
|
} else if (replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: replyList[0]! as String,
|
||||||
|
message: replyList[1] as String?,
|
||||||
|
details: replyList[2],
|
||||||
|
);
|
||||||
|
} else if (replyList[0] == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'null-error',
|
||||||
|
message: 'Host platform returned null value for non-null return value.',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (replyList[0] as EncryptResponse?)!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,316 @@
|
|||||||
|
// Copyright 2019-2023 Hugo Pointcheval
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://opensource.org/licenses/MIT.
|
||||||
|
// --
|
||||||
|
// Autogenerated from Pigeon (v9.0.0), do not edit directly.
|
||||||
|
// See also: https://pub.dev/packages/pigeon
|
||||||
|
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import
|
||||||
|
// ignore_for_file: avoid_relative_lib_imports
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
|
||||||
|
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import 'messages.pigeon.dart';
|
||||||
|
|
||||||
|
class _TestNativeCryptoAPICodec extends StandardMessageCodec {
|
||||||
|
const _TestNativeCryptoAPICodec();
|
||||||
|
@override
|
||||||
|
void writeValue(WriteBuffer buffer, Object? value) {
|
||||||
|
if (value is DecryptFileRequest) {
|
||||||
|
buffer.putUint8(128);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is DecryptFileResponse) {
|
||||||
|
buffer.putUint8(129);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is DecryptRequest) {
|
||||||
|
buffer.putUint8(130);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is DecryptResponse) {
|
||||||
|
buffer.putUint8(131);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is EncryptFileRequest) {
|
||||||
|
buffer.putUint8(132);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is EncryptFileResponse) {
|
||||||
|
buffer.putUint8(133);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is EncryptRequest) {
|
||||||
|
buffer.putUint8(134);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is EncryptResponse) {
|
||||||
|
buffer.putUint8(135);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is EncryptWithIVRequest) {
|
||||||
|
buffer.putUint8(136);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is GenerateSecureRandomRequest) {
|
||||||
|
buffer.putUint8(137);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is GenerateSecureRandomResponse) {
|
||||||
|
buffer.putUint8(138);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is HashRequest) {
|
||||||
|
buffer.putUint8(139);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is HashResponse) {
|
||||||
|
buffer.putUint8(140);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is HmacRequest) {
|
||||||
|
buffer.putUint8(141);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is HmacResponse) {
|
||||||
|
buffer.putUint8(142);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is Pbkdf2Request) {
|
||||||
|
buffer.putUint8(143);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is Pbkdf2Response) {
|
||||||
|
buffer.putUint8(144);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else {
|
||||||
|
super.writeValue(buffer, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Object? readValueOfType(int type, ReadBuffer buffer) {
|
||||||
|
switch (type) {
|
||||||
|
case 128:
|
||||||
|
return DecryptFileRequest.decode(readValue(buffer)!);
|
||||||
|
case 129:
|
||||||
|
return DecryptFileResponse.decode(readValue(buffer)!);
|
||||||
|
case 130:
|
||||||
|
return DecryptRequest.decode(readValue(buffer)!);
|
||||||
|
case 131:
|
||||||
|
return DecryptResponse.decode(readValue(buffer)!);
|
||||||
|
case 132:
|
||||||
|
return EncryptFileRequest.decode(readValue(buffer)!);
|
||||||
|
case 133:
|
||||||
|
return EncryptFileResponse.decode(readValue(buffer)!);
|
||||||
|
case 134:
|
||||||
|
return EncryptRequest.decode(readValue(buffer)!);
|
||||||
|
case 135:
|
||||||
|
return EncryptResponse.decode(readValue(buffer)!);
|
||||||
|
case 136:
|
||||||
|
return EncryptWithIVRequest.decode(readValue(buffer)!);
|
||||||
|
case 137:
|
||||||
|
return GenerateSecureRandomRequest.decode(readValue(buffer)!);
|
||||||
|
case 138:
|
||||||
|
return GenerateSecureRandomResponse.decode(readValue(buffer)!);
|
||||||
|
case 139:
|
||||||
|
return HashRequest.decode(readValue(buffer)!);
|
||||||
|
case 140:
|
||||||
|
return HashResponse.decode(readValue(buffer)!);
|
||||||
|
case 141:
|
||||||
|
return HmacRequest.decode(readValue(buffer)!);
|
||||||
|
case 142:
|
||||||
|
return HmacResponse.decode(readValue(buffer)!);
|
||||||
|
case 143:
|
||||||
|
return Pbkdf2Request.decode(readValue(buffer)!);
|
||||||
|
case 144:
|
||||||
|
return Pbkdf2Response.decode(readValue(buffer)!);
|
||||||
|
default:
|
||||||
|
return super.readValueOfType(type, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class TestNativeCryptoAPI {
|
||||||
|
static const MessageCodec<Object?> codec = _TestNativeCryptoAPICodec();
|
||||||
|
|
||||||
|
HashResponse hash(HashRequest request);
|
||||||
|
|
||||||
|
HmacResponse hmac(HmacRequest request);
|
||||||
|
|
||||||
|
GenerateSecureRandomResponse generateSecureRandom(GenerateSecureRandomRequest request);
|
||||||
|
|
||||||
|
Pbkdf2Response pbkdf2(Pbkdf2Request request);
|
||||||
|
|
||||||
|
EncryptResponse encrypt(EncryptRequest request);
|
||||||
|
|
||||||
|
DecryptResponse decrypt(DecryptRequest request);
|
||||||
|
|
||||||
|
EncryptFileResponse encryptFile(EncryptFileRequest request);
|
||||||
|
|
||||||
|
DecryptFileResponse decryptFile(DecryptFileRequest request);
|
||||||
|
|
||||||
|
EncryptResponse encryptWithIV(EncryptWithIVRequest request);
|
||||||
|
|
||||||
|
static void setup(TestNativeCryptoAPI? api, {BinaryMessenger? binaryMessenger}) {
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.hash', codec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
channel.setMockMessageHandler(null);
|
||||||
|
} else {
|
||||||
|
channel.setMockMessageHandler((Object? message) async {
|
||||||
|
assert(message != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.hash was null.');
|
||||||
|
final List<Object?> args = (message as List<Object?>?)!;
|
||||||
|
final HashRequest? arg_request = (args[0] as HashRequest?);
|
||||||
|
assert(arg_request != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.hash was null, expected non-null HashRequest.');
|
||||||
|
final HashResponse output = api.hash(arg_request!);
|
||||||
|
return <Object?>[output];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.hmac', codec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
channel.setMockMessageHandler(null);
|
||||||
|
} else {
|
||||||
|
channel.setMockMessageHandler((Object? message) async {
|
||||||
|
assert(message != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.hmac was null.');
|
||||||
|
final List<Object?> args = (message as List<Object?>?)!;
|
||||||
|
final HmacRequest? arg_request = (args[0] as HmacRequest?);
|
||||||
|
assert(arg_request != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.hmac was null, expected non-null HmacRequest.');
|
||||||
|
final HmacResponse output = api.hmac(arg_request!);
|
||||||
|
return <Object?>[output];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.generateSecureRandom', codec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
channel.setMockMessageHandler(null);
|
||||||
|
} else {
|
||||||
|
channel.setMockMessageHandler((Object? message) async {
|
||||||
|
assert(message != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.generateSecureRandom was null.');
|
||||||
|
final List<Object?> args = (message as List<Object?>?)!;
|
||||||
|
final GenerateSecureRandomRequest? arg_request = (args[0] as GenerateSecureRandomRequest?);
|
||||||
|
assert(arg_request != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.generateSecureRandom was null, expected non-null GenerateSecureRandomRequest.');
|
||||||
|
final GenerateSecureRandomResponse output = api.generateSecureRandom(arg_request!);
|
||||||
|
return <Object?>[output];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.pbkdf2', codec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
channel.setMockMessageHandler(null);
|
||||||
|
} else {
|
||||||
|
channel.setMockMessageHandler((Object? message) async {
|
||||||
|
assert(message != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.pbkdf2 was null.');
|
||||||
|
final List<Object?> args = (message as List<Object?>?)!;
|
||||||
|
final Pbkdf2Request? arg_request = (args[0] as Pbkdf2Request?);
|
||||||
|
assert(arg_request != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.pbkdf2 was null, expected non-null Pbkdf2Request.');
|
||||||
|
final Pbkdf2Response output = api.pbkdf2(arg_request!);
|
||||||
|
return <Object?>[output];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.encrypt', codec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
channel.setMockMessageHandler(null);
|
||||||
|
} else {
|
||||||
|
channel.setMockMessageHandler((Object? message) async {
|
||||||
|
assert(message != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.encrypt was null.');
|
||||||
|
final List<Object?> args = (message as List<Object?>?)!;
|
||||||
|
final EncryptRequest? arg_request = (args[0] as EncryptRequest?);
|
||||||
|
assert(arg_request != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.encrypt was null, expected non-null EncryptRequest.');
|
||||||
|
final EncryptResponse output = api.encrypt(arg_request!);
|
||||||
|
return <Object?>[output];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.decrypt', codec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
channel.setMockMessageHandler(null);
|
||||||
|
} else {
|
||||||
|
channel.setMockMessageHandler((Object? message) async {
|
||||||
|
assert(message != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.decrypt was null.');
|
||||||
|
final List<Object?> args = (message as List<Object?>?)!;
|
||||||
|
final DecryptRequest? arg_request = (args[0] as DecryptRequest?);
|
||||||
|
assert(arg_request != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.decrypt was null, expected non-null DecryptRequest.');
|
||||||
|
final DecryptResponse output = api.decrypt(arg_request!);
|
||||||
|
return <Object?>[output];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.encryptFile', codec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
channel.setMockMessageHandler(null);
|
||||||
|
} else {
|
||||||
|
channel.setMockMessageHandler((Object? message) async {
|
||||||
|
assert(message != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.encryptFile was null.');
|
||||||
|
final List<Object?> args = (message as List<Object?>?)!;
|
||||||
|
final EncryptFileRequest? arg_request = (args[0] as EncryptFileRequest?);
|
||||||
|
assert(arg_request != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.encryptFile was null, expected non-null EncryptFileRequest.');
|
||||||
|
final EncryptFileResponse output = api.encryptFile(arg_request!);
|
||||||
|
return <Object?>[output];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.decryptFile', codec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
channel.setMockMessageHandler(null);
|
||||||
|
} else {
|
||||||
|
channel.setMockMessageHandler((Object? message) async {
|
||||||
|
assert(message != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.decryptFile was null.');
|
||||||
|
final List<Object?> args = (message as List<Object?>?)!;
|
||||||
|
final DecryptFileRequest? arg_request = (args[0] as DecryptFileRequest?);
|
||||||
|
assert(arg_request != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.decryptFile was null, expected non-null DecryptFileRequest.');
|
||||||
|
final DecryptFileResponse output = api.decryptFile(arg_request!);
|
||||||
|
return <Object?>[output];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.NativeCryptoAPI.encryptWithIV', codec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
channel.setMockMessageHandler(null);
|
||||||
|
} else {
|
||||||
|
channel.setMockMessageHandler((Object? message) async {
|
||||||
|
assert(message != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.encryptWithIV was null.');
|
||||||
|
final List<Object?> args = (message as List<Object?>?)!;
|
||||||
|
final EncryptWithIVRequest? arg_request = (args[0] as EncryptWithIVRequest?);
|
||||||
|
assert(arg_request != null,
|
||||||
|
'Argument for dev.flutter.pigeon.NativeCryptoAPI.encryptWithIV was null, expected non-null EncryptWithIVRequest.');
|
||||||
|
final EncryptResponse output = api.encryptWithIV(arg_request!);
|
||||||
|
return <Object?>[output];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,92 +0,0 @@
|
|||||||
// Author: Hugo Pointcheval
|
|
||||||
// Email: git@pcl.ovh
|
|
||||||
// -----
|
|
||||||
// File: native_crypto_platform_interface.dart
|
|
||||||
// Created Date: 25/12/2021 16:43:49
|
|
||||||
// Last Modified: 25/05/2022 22:11:02
|
|
||||||
// -----
|
|
||||||
// Copyright (c) 2021
|
|
||||||
|
|
||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import 'package:native_crypto_platform_interface/src/method_channel/method_channel_native_crypto.dart';
|
|
||||||
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
|
||||||
|
|
||||||
/// The interface that implementations of path_provider must implement.
|
|
||||||
///
|
|
||||||
/// Platform implementations should extend this class rather than implement
|
|
||||||
/// it as `NativeCrypto` does not consider newly added methods to be
|
|
||||||
/// breaking changes. Extending this class (using `extends`) ensures
|
|
||||||
/// that the subclass will get the default implementation, while platform
|
|
||||||
/// implementations that `implements` this interface will be
|
|
||||||
/// broken by newly added [NativeCryptoPlatform] methods.
|
|
||||||
abstract class NativeCryptoPlatform extends PlatformInterface {
|
|
||||||
/// Constructs a NativeCryptoPlatform.
|
|
||||||
NativeCryptoPlatform() : super(token: _token);
|
|
||||||
|
|
||||||
static final Object _token = Object();
|
|
||||||
|
|
||||||
static NativeCryptoPlatform _instance = MethodChannelNativeCrypto();
|
|
||||||
|
|
||||||
/// The default instance of [NativeCryptoPlatform] to use.
|
|
||||||
///
|
|
||||||
/// Defaults to [MethodChannelNativeCrypto].
|
|
||||||
static NativeCryptoPlatform get instance => _instance;
|
|
||||||
|
|
||||||
/// Platform-specific plugins should set this with their own platform-specific
|
|
||||||
/// class that extends [NativeCryptoPlatform] when they register themselves.
|
|
||||||
static set instance(NativeCryptoPlatform instance) {
|
|
||||||
PlatformInterface.verify(instance, _token);
|
|
||||||
_instance = instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Uint8List?> digest(Uint8List data, String algorithm) {
|
|
||||||
throw UnimplementedError('digest is not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Uint8List?> generateSecretKey(int bitsCount) {
|
|
||||||
throw UnimplementedError('generateSecretKey is not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Uint8List?> pbkdf2(
|
|
||||||
String password,
|
|
||||||
String salt,
|
|
||||||
int keyBytesCount,
|
|
||||||
int iterations,
|
|
||||||
String algorithm,
|
|
||||||
) {
|
|
||||||
throw UnimplementedError('pbkdf2 is not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<Uint8List>?> encryptAsList(
|
|
||||||
Uint8List data,
|
|
||||||
Uint8List key,
|
|
||||||
String algorithm,
|
|
||||||
) {
|
|
||||||
throw UnimplementedError('encryptAsList is not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Uint8List?> decryptAsList(
|
|
||||||
List<Uint8List> data,
|
|
||||||
Uint8List key,
|
|
||||||
String algorithm,
|
|
||||||
) {
|
|
||||||
throw UnimplementedError('decryptAsList is not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Uint8List?> encrypt(
|
|
||||||
Uint8List data,
|
|
||||||
Uint8List key,
|
|
||||||
String algorithm,
|
|
||||||
) {
|
|
||||||
throw UnimplementedError('encrypt is not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Uint8List?> decrypt(
|
|
||||||
Uint8List data,
|
|
||||||
Uint8List key,
|
|
||||||
String algorithm,
|
|
||||||
) {
|
|
||||||
throw UnimplementedError('decrypt is not implemented');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,126 +0,0 @@
|
|||||||
// Author: Hugo Pointcheval
|
|
||||||
// Email: git@pcl.ovh
|
|
||||||
// -----
|
|
||||||
// File: exception.dart
|
|
||||||
// Created Date: 24/05/2022 18:54:48
|
|
||||||
// Last Modified: 26/05/2022 20:36:04
|
|
||||||
// -----
|
|
||||||
// Copyright (c) 2022
|
|
||||||
|
|
||||||
// ignore_for_file: constant_identifier_names
|
|
||||||
|
|
||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
|
|
||||||
enum NativeCryptoExceptionCode {
|
|
||||||
unknown,
|
|
||||||
not_implemented,
|
|
||||||
invalid_argument,
|
|
||||||
invalid_key,
|
|
||||||
invalid_key_length,
|
|
||||||
invalid_algorithm,
|
|
||||||
invalid_padding,
|
|
||||||
invalid_mode,
|
|
||||||
invalid_cipher,
|
|
||||||
invalid_data,
|
|
||||||
platform_not_supported,
|
|
||||||
platform_throws,
|
|
||||||
platform_returned_invalid_data,
|
|
||||||
platform_returned_empty_data,
|
|
||||||
platform_returned_null;
|
|
||||||
|
|
||||||
String get code => toString().split('.').last.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
class NativeCryptoException implements Exception {
|
|
||||||
NativeCryptoException({
|
|
||||||
this.message,
|
|
||||||
String? code,
|
|
||||||
this.stackTrace,
|
|
||||||
}) : code = code ?? NativeCryptoExceptionCode.unknown.code;
|
|
||||||
|
|
||||||
/// The long form message of the exception.
|
|
||||||
final String? message;
|
|
||||||
|
|
||||||
/// The optional code to accommodate the message.
|
|
||||||
final String code;
|
|
||||||
|
|
||||||
/// The stack trace which provides information to the user about the call
|
|
||||||
/// sequence that triggered an exception
|
|
||||||
final StackTrace? stackTrace;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
String output = '[NativeCryptoException/$code] $message';
|
|
||||||
|
|
||||||
if (stackTrace != null) {
|
|
||||||
output += '\n\n${stackTrace.toString()}';
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Catches a [PlatformException] and returns an [Exception].
|
|
||||||
///
|
|
||||||
/// If the [Exception] is a [PlatformException],
|
|
||||||
/// a [NativeCryptoException] is returned.
|
|
||||||
static Never convertPlatformException(
|
|
||||||
Object exception,
|
|
||||||
StackTrace stackTrace,
|
|
||||||
) {
|
|
||||||
log(exception.toString());
|
|
||||||
if (exception is! Exception || exception is! PlatformException) {
|
|
||||||
Error.throwWithStackTrace(exception, stackTrace);
|
|
||||||
}
|
|
||||||
|
|
||||||
Error.throwWithStackTrace(
|
|
||||||
NativeCryptoException.fromPlatformException(exception, stackTrace),
|
|
||||||
stackTrace,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Converts a [PlatformException] into a [NativeCryptoException].
|
|
||||||
///
|
|
||||||
/// A [PlatformException] can only be converted to a [NativeCryptoException]
|
|
||||||
/// if the `details` of the exception exist.
|
|
||||||
factory NativeCryptoException.fromPlatformException(
|
|
||||||
PlatformException platformException,
|
|
||||||
StackTrace stackTrace,
|
|
||||||
) {
|
|
||||||
final Map<String, String>? details = platformException.details != null
|
|
||||||
? Map<String, String>.from(
|
|
||||||
platformException.details as Map<String, String>,
|
|
||||||
)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
String code = NativeCryptoExceptionCode.unknown.code;
|
|
||||||
String message = platformException.message ?? '';
|
|
||||||
|
|
||||||
if (details != null) {
|
|
||||||
code = details['code'] ?? code;
|
|
||||||
message = details['message'] ?? message;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NativeCryptoException(
|
|
||||||
message: message,
|
|
||||||
code: code,
|
|
||||||
stackTrace: stackTrace,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
if (identical(this, other)) return true;
|
|
||||||
|
|
||||||
return other is NativeCryptoException &&
|
|
||||||
other.message == message &&
|
|
||||||
other.code == code &&
|
|
||||||
other.stackTrace == stackTrace;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
|
||||||
int get hashCode => message.hashCode ^ code.hashCode ^ stackTrace.hashCode;
|
|
||||||
}
|
|
@ -0,0 +1,6 @@
|
|||||||
|
Copyright 2019-2023 Hugo Pointcheval
|
||||||
|
|
||||||
|
Use of this source code is governed by an MIT-style
|
||||||
|
license that can be found in the LICENSE file or at
|
||||||
|
https://opensource.org/licenses/MIT.
|
||||||
|
--
|
222
packages/native_crypto_platform_interface/pigeons/messages.dart
Normal file
222
packages/native_crypto_platform_interface/pigeons/messages.dart
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||||
|
// Copyright 2019-2023 Hugo Pointcheval
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
|
import 'package:pigeon/pigeon.dart';
|
||||||
|
|
||||||
|
@ConfigurePigeon(
|
||||||
|
PigeonOptions(
|
||||||
|
copyrightHeader: 'pigeons/copyright_header.txt',
|
||||||
|
dartOut: 'lib/src/pigeon/messages.pigeon.dart',
|
||||||
|
// We export in the lib folder to expose the class to other packages.
|
||||||
|
dartTestOut: 'lib/src/pigeon/test_api.dart',
|
||||||
|
javaOut:
|
||||||
|
'../native_crypto_android/android/src/main/java/fr/pointcheval/native_crypto_android/GeneratedAndroidNativeCrypto.java',
|
||||||
|
javaOptions: JavaOptions(
|
||||||
|
package: 'fr.pointcheval.native_crypto_android',
|
||||||
|
className: 'GeneratedAndroidNativeCrypto',
|
||||||
|
),
|
||||||
|
objcHeaderOut: '../native_crypto_ios/ios/Classes/Public/messages.g.h',
|
||||||
|
objcSourceOut: '../native_crypto_ios/ios/Classes/messages.g.m',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
class HashRequest {
|
||||||
|
const HashRequest({
|
||||||
|
this.data,
|
||||||
|
this.algorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Uint8List? data;
|
||||||
|
final String? algorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
class HashResponse {
|
||||||
|
const HashResponse({
|
||||||
|
this.hash,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Uint8List? hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
class HmacRequest {
|
||||||
|
const HmacRequest({
|
||||||
|
this.data,
|
||||||
|
this.key,
|
||||||
|
this.algorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Uint8List? data;
|
||||||
|
final Uint8List? key;
|
||||||
|
final String? algorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
class HmacResponse {
|
||||||
|
const HmacResponse({
|
||||||
|
this.hmac,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Uint8List? hmac;
|
||||||
|
}
|
||||||
|
|
||||||
|
class GenerateSecureRandomRequest {
|
||||||
|
const GenerateSecureRandomRequest({
|
||||||
|
this.length,
|
||||||
|
});
|
||||||
|
|
||||||
|
final int? length;
|
||||||
|
}
|
||||||
|
|
||||||
|
class GenerateSecureRandomResponse {
|
||||||
|
const GenerateSecureRandomResponse({
|
||||||
|
this.random,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Uint8List? random;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Pbkdf2Request {
|
||||||
|
const Pbkdf2Request({
|
||||||
|
this.password,
|
||||||
|
this.salt,
|
||||||
|
this.length,
|
||||||
|
this.iterations,
|
||||||
|
this.hashAlgorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Uint8List? password;
|
||||||
|
final Uint8List? salt;
|
||||||
|
final int? length;
|
||||||
|
final int? iterations;
|
||||||
|
final String? hashAlgorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Pbkdf2Response {
|
||||||
|
const Pbkdf2Response({
|
||||||
|
this.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Uint8List? key;
|
||||||
|
}
|
||||||
|
|
||||||
|
class EncryptRequest {
|
||||||
|
const EncryptRequest({
|
||||||
|
this.plainText,
|
||||||
|
this.key,
|
||||||
|
this.algorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Uint8List? plainText;
|
||||||
|
final Uint8List? key;
|
||||||
|
final String? algorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
class EncryptResponse {
|
||||||
|
const EncryptResponse({
|
||||||
|
this.cipherText,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Uint8List? cipherText;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DecryptRequest {
|
||||||
|
const DecryptRequest({
|
||||||
|
this.cipherText,
|
||||||
|
this.key,
|
||||||
|
this.algorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Uint8List? cipherText;
|
||||||
|
final Uint8List? key;
|
||||||
|
final String? algorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DecryptResponse {
|
||||||
|
const DecryptResponse({
|
||||||
|
this.plainText,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Uint8List? plainText;
|
||||||
|
}
|
||||||
|
|
||||||
|
class EncryptFileRequest {
|
||||||
|
const EncryptFileRequest({
|
||||||
|
this.plainTextPath,
|
||||||
|
this.cipherTextPath,
|
||||||
|
this.key,
|
||||||
|
this.algorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String? plainTextPath;
|
||||||
|
final String? cipherTextPath;
|
||||||
|
final Uint8List? key;
|
||||||
|
final String? algorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
class EncryptFileResponse {
|
||||||
|
const EncryptFileResponse({
|
||||||
|
this.success,
|
||||||
|
});
|
||||||
|
|
||||||
|
final bool? success;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DecryptFileRequest {
|
||||||
|
const DecryptFileRequest({
|
||||||
|
this.cipherTextPath,
|
||||||
|
this.plainTextPath,
|
||||||
|
this.key,
|
||||||
|
this.algorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String? cipherTextPath;
|
||||||
|
final String? plainTextPath;
|
||||||
|
final Uint8List? key;
|
||||||
|
final String? algorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DecryptFileResponse {
|
||||||
|
const DecryptFileResponse({
|
||||||
|
this.success,
|
||||||
|
});
|
||||||
|
|
||||||
|
final bool? success;
|
||||||
|
}
|
||||||
|
|
||||||
|
class EncryptWithIVRequest {
|
||||||
|
const EncryptWithIVRequest({
|
||||||
|
this.plainText,
|
||||||
|
this.iv,
|
||||||
|
this.key,
|
||||||
|
this.algorithm,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Uint8List? plainText;
|
||||||
|
final Uint8List? iv;
|
||||||
|
final Uint8List? key;
|
||||||
|
final String? algorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@HostApi(dartHostTestHandler: 'TestNativeCryptoAPI')
|
||||||
|
abstract class NativeCryptoAPI {
|
||||||
|
HashResponse hash(HashRequest request);
|
||||||
|
HmacResponse hmac(HmacRequest request);
|
||||||
|
|
||||||
|
GenerateSecureRandomResponse generateSecureRandom(
|
||||||
|
GenerateSecureRandomRequest request,
|
||||||
|
);
|
||||||
|
|
||||||
|
Pbkdf2Response pbkdf2(Pbkdf2Request request);
|
||||||
|
|
||||||
|
EncryptResponse encrypt(EncryptRequest request);
|
||||||
|
|
||||||
|
DecryptResponse decrypt(DecryptRequest request);
|
||||||
|
|
||||||
|
EncryptFileResponse encryptFile(EncryptFileRequest request);
|
||||||
|
|
||||||
|
DecryptFileResponse decryptFile(DecryptFileRequest request);
|
||||||
|
|
||||||
|
EncryptResponse encryptWithIV(EncryptWithIVRequest request);
|
||||||
|
}
|
@ -7,19 +7,19 @@ environment:
|
|||||||
flutter: ">=2.5.0"
|
flutter: ">=2.5.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
equatable: ^2.0.5
|
||||||
sdk: flutter
|
flutter: { sdk: flutter }
|
||||||
|
|
||||||
plugin_platform_interface: ^2.1.3
|
plugin_platform_interface: ^2.1.3
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test: { sdk: flutter }
|
||||||
sdk: flutter
|
|
||||||
|
|
||||||
mockito: ^5.3.2
|
mockito: ^5.3.2
|
||||||
|
pigeon: ^9.0.0
|
||||||
|
|
||||||
wyatt_analysis:
|
wyatt_analysis:
|
||||||
hosted:
|
hosted:
|
||||||
url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
url: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
||||||
name: wyatt_analysis
|
name: wyatt_analysis
|
||||||
version: 2.3.0
|
version: 2.4.0
|
||||||
|
@ -1,175 +0,0 @@
|
|||||||
// Author: Hugo Pointcheval
|
|
||||||
// Email: git@pcl.ovh
|
|
||||||
// -----
|
|
||||||
// File: method_channel_native_crypto_test.dart
|
|
||||||
// Created Date: 25/05/2022 22:47:41
|
|
||||||
// Last Modified: 25/05/2022 23:22:44
|
|
||||||
// -----
|
|
||||||
// Copyright (c) 2022
|
|
||||||
|
|
||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:native_crypto_platform_interface/src/method_channel/method_channel_native_crypto.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
TestWidgetsFlutterBinding
|
|
||||||
.ensureInitialized(); // Required for setMockMethodCallHandler
|
|
||||||
|
|
||||||
group('$MethodChannelNativeCrypto', () {
|
|
||||||
const MethodChannel channel =
|
|
||||||
MethodChannel('plugins.hugop.cl/native_crypto');
|
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
|
||||||
final MethodChannelNativeCrypto nativeCrypto = MethodChannelNativeCrypto();
|
|
||||||
|
|
||||||
TestDefaultBinaryMessengerBinding.instance?.defaultBinaryMessenger
|
|
||||||
.setMockMethodCallHandler(channel, (MethodCall call) async {
|
|
||||||
log.add(call);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Run after each test.
|
|
||||||
tearDown(log.clear);
|
|
||||||
|
|
||||||
test('digest', () async {
|
|
||||||
await nativeCrypto.digest(Uint8List(0), 'sha256');
|
|
||||||
expect(
|
|
||||||
log,
|
|
||||||
<Matcher>[
|
|
||||||
isMethodCall(
|
|
||||||
'digest',
|
|
||||||
arguments: <String, dynamic>{
|
|
||||||
'data': Uint8List(0),
|
|
||||||
'algorithm': 'sha256',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('generateSecretKey', () async {
|
|
||||||
await nativeCrypto.generateSecretKey(256);
|
|
||||||
expect(
|
|
||||||
log,
|
|
||||||
<Matcher>[
|
|
||||||
isMethodCall(
|
|
||||||
'generateSecretKey',
|
|
||||||
arguments: <String, dynamic>{
|
|
||||||
'bitsCount': 256,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('pbkdf2', () async {
|
|
||||||
await nativeCrypto.pbkdf2(
|
|
||||||
'password',
|
|
||||||
'salt',
|
|
||||||
32,
|
|
||||||
10000,
|
|
||||||
'sha256',
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
log,
|
|
||||||
<Matcher>[
|
|
||||||
isMethodCall(
|
|
||||||
'pbkdf2',
|
|
||||||
arguments: <String, dynamic>{
|
|
||||||
'password': 'password',
|
|
||||||
'salt': 'salt',
|
|
||||||
'keyBytesCount': 32,
|
|
||||||
'iterations': 10000,
|
|
||||||
'algorithm': 'sha256',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('encryptAsList', () async {
|
|
||||||
await nativeCrypto.encryptAsList(
|
|
||||||
Uint8List(0),
|
|
||||||
Uint8List(0),
|
|
||||||
'aes',
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
log,
|
|
||||||
<Matcher>[
|
|
||||||
isMethodCall(
|
|
||||||
'encryptAsList',
|
|
||||||
arguments: <String, dynamic>{
|
|
||||||
'data': Uint8List(0),
|
|
||||||
'key': Uint8List(0),
|
|
||||||
'algorithm': 'aes',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('decryptAsList', () async {
|
|
||||||
await nativeCrypto.decryptAsList(
|
|
||||||
[Uint8List(0)],
|
|
||||||
Uint8List(0),
|
|
||||||
'aes',
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
log,
|
|
||||||
<Matcher>[
|
|
||||||
isMethodCall(
|
|
||||||
'decryptAsList',
|
|
||||||
arguments: <String, dynamic>{
|
|
||||||
'data': [Uint8List(0)],
|
|
||||||
'key': Uint8List(0),
|
|
||||||
'algorithm': 'aes',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('encrypt', () async {
|
|
||||||
await nativeCrypto.encrypt(
|
|
||||||
Uint8List(0),
|
|
||||||
Uint8List(0),
|
|
||||||
'aes',
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
log,
|
|
||||||
<Matcher>[
|
|
||||||
isMethodCall(
|
|
||||||
'encrypt',
|
|
||||||
arguments: <String, dynamic>{
|
|
||||||
'data': Uint8List(0),
|
|
||||||
'key': Uint8List(0),
|
|
||||||
'algorithm': 'aes',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('decrypt', () async {
|
|
||||||
await nativeCrypto.decrypt(
|
|
||||||
Uint8List(0),
|
|
||||||
Uint8List(0),
|
|
||||||
'aes',
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
log,
|
|
||||||
<Matcher>[
|
|
||||||
isMethodCall(
|
|
||||||
'decrypt',
|
|
||||||
arguments: <String, dynamic>{
|
|
||||||
'data': Uint8List(0),
|
|
||||||
'key': Uint8List(0),
|
|
||||||
'algorithm': 'aes',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
@ -0,0 +1,72 @@
|
|||||||
|
// Copyright 2019-2023 Hugo Pointcheval
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:native_crypto_platform_interface/src/core/enums/exception_code.dart';
|
||||||
|
import 'package:native_crypto_platform_interface/src/core/exceptions/exception.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
group('$NativeCryptoException', () {
|
||||||
|
test('should return a formatted message with only code', () async {
|
||||||
|
const e = NativeCryptoException(
|
||||||
|
code: NativeCryptoExceptionCode.unknownError,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(e.toString(), '[NativeCrypto/unknown_error]');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return a formatted message', () async {
|
||||||
|
const e = NativeCryptoException(
|
||||||
|
code: NativeCryptoExceptionCode.unknownError,
|
||||||
|
message: 'foo',
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(e.toString(), '[NativeCrypto/unknown_error] foo');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return a formatted message with a stack trace', () async {
|
||||||
|
const e = NativeCryptoException(
|
||||||
|
code: NativeCryptoExceptionCode.unknownError,
|
||||||
|
message: 'foo',
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(e.toString(), '[NativeCrypto/unknown_error] foo');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return a formatted message with a stack trace', () async {
|
||||||
|
final e = NativeCryptoException(
|
||||||
|
code: NativeCryptoExceptionCode.unknownError,
|
||||||
|
message: 'foo',
|
||||||
|
stackTrace: StackTrace.current,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Anything with a stack trace adds 2 blanks lines following the message.
|
||||||
|
expect(e.toString(), startsWith('[NativeCrypto/unknown_error] foo\n\n'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should override the == operator', () async {
|
||||||
|
const e1 = NativeCryptoException(
|
||||||
|
code: NativeCryptoExceptionCode.unknownError,
|
||||||
|
message: 'foo',
|
||||||
|
);
|
||||||
|
|
||||||
|
const e2 = NativeCryptoException(
|
||||||
|
code: NativeCryptoExceptionCode.unknownError,
|
||||||
|
message: 'foo',
|
||||||
|
);
|
||||||
|
|
||||||
|
const e3 = NativeCryptoException(
|
||||||
|
code: NativeCryptoExceptionCode.unknownError,
|
||||||
|
message: 'foo',
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(e1 == e2, true);
|
||||||
|
expect(e1 != e3, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -1,43 +1,42 @@
|
|||||||
// Author: Hugo Pointcheval
|
// Copyright 2019-2023 Hugo Pointcheval
|
||||||
// Email: git@pcl.ovh
|
//
|
||||||
// -----
|
// Use of this source code is governed by an MIT-style
|
||||||
// File: native_crypto_platform_test.dart
|
// license that can be found in the LICENSE file or at
|
||||||
// Created Date: 25/05/2022 21:43:25
|
// https://opensource.org/licenses/MIT.
|
||||||
// Last Modified: 25/05/2022 23:26:18
|
|
||||||
// -----
|
|
||||||
// Copyright (c) 2022
|
|
||||||
|
|
||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:mockito/mockito.dart';
|
import 'package:mockito/mockito.dart';
|
||||||
import 'package:native_crypto_platform_interface/src/platform_interface/native_crypto_platform.dart';
|
import 'package:native_crypto_platform_interface/src/implementations/basic_message_channel_native_crypto.dart';
|
||||||
|
import 'package:native_crypto_platform_interface/src/implementations/method_channel_native_crypto.dart';
|
||||||
|
import 'package:native_crypto_platform_interface/src/interface/native_crypto_platform.dart';
|
||||||
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
||||||
|
|
||||||
|
class ImplementsNativeCryptoPlatform
|
||||||
|
// ignore: prefer_mixin
|
||||||
|
with Mock
|
||||||
|
implements NativeCryptoPlatform {}
|
||||||
|
|
||||||
|
class ExtendsNativeCryptoPlatform extends NativeCryptoPlatform {}
|
||||||
|
|
||||||
|
class NativeCryptoMockPlatform extends Mock
|
||||||
|
with
|
||||||
|
// ignore: prefer_mixin, plugin_platform_interface needs to migrate to use `mixin`
|
||||||
|
MockPlatformInterfaceMixin
|
||||||
|
implements
|
||||||
|
NativeCryptoPlatform {}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
late ExtendsNativeCryptoPlatform nativeCryptoPlatform;
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
group('$NativeCryptoPlatform', () {
|
group('$NativeCryptoPlatform', () {
|
||||||
setUpAll(() {
|
// should allow read of default app from native
|
||||||
nativeCryptoPlatform = ExtendsNativeCryptoPlatform();
|
test('$MethodChannelNativeCrypto is the default instance', () {
|
||||||
});
|
expect(NativeCryptoPlatform.instance, isA<MethodChannelNativeCrypto>());
|
||||||
test('Constructor', () {
|
|
||||||
expect(nativeCryptoPlatform, isA<NativeCryptoPlatform>());
|
|
||||||
expect(nativeCryptoPlatform, isA<PlatformInterface>());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('get.instance', () {
|
test('Can be extended', () {
|
||||||
expect(
|
|
||||||
NativeCryptoPlatform.instance,
|
|
||||||
isA<NativeCryptoPlatform>(),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
test('set.instance', () {
|
|
||||||
NativeCryptoPlatform.instance = ExtendsNativeCryptoPlatform();
|
NativeCryptoPlatform.instance = ExtendsNativeCryptoPlatform();
|
||||||
expect(
|
|
||||||
NativeCryptoPlatform.instance,
|
|
||||||
isA<NativeCryptoPlatform>(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Cannot be implemented with `implements`', () {
|
test('Cannot be implemented with `implements`', () {
|
||||||
@ -45,122 +44,19 @@ void main() {
|
|||||||
() {
|
() {
|
||||||
NativeCryptoPlatform.instance = ImplementsNativeCryptoPlatform();
|
NativeCryptoPlatform.instance = ImplementsNativeCryptoPlatform();
|
||||||
},
|
},
|
||||||
throwsA(isInstanceOf<AssertionError>()),
|
throwsA(anything),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Can be mocked with `implements`', () {
|
test('Can be mocked with `implements`', () {
|
||||||
final MockNativeCryptoPlatform mock = MockNativeCryptoPlatform();
|
final NativeCryptoMockPlatform mock = NativeCryptoMockPlatform();
|
||||||
NativeCryptoPlatform.instance = mock;
|
NativeCryptoPlatform.instance = mock;
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Can be extended', () {
|
test('Can set with $BasicMessageChannelNativeCrypto', () {
|
||||||
NativeCryptoPlatform.instance = ExtendsNativeCryptoPlatform();
|
final BasicMessageChannelNativeCrypto pigeon =
|
||||||
});
|
BasicMessageChannelNativeCrypto();
|
||||||
|
NativeCryptoPlatform.instance = pigeon;
|
||||||
test('throws if .digest() not implemented', () async {
|
|
||||||
await expectLater(
|
|
||||||
() => nativeCryptoPlatform.digest(Uint8List(0), 'sha256'),
|
|
||||||
throwsA(
|
|
||||||
isA<UnimplementedError>().having(
|
|
||||||
(e) => e.message,
|
|
||||||
'message',
|
|
||||||
'digest is not implemented',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('throws if .generateSecretKey() not implemented', () async {
|
|
||||||
await expectLater(
|
|
||||||
() => nativeCryptoPlatform.generateSecretKey(256),
|
|
||||||
throwsA(
|
|
||||||
isA<UnimplementedError>().having(
|
|
||||||
(e) => e.message,
|
|
||||||
'message',
|
|
||||||
'generateSecretKey is not implemented',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('throws if .pbkdf2() not implemented', () async {
|
|
||||||
await expectLater(
|
|
||||||
() => nativeCryptoPlatform.pbkdf2('password', 'salt', 0, 0, 'sha256'),
|
|
||||||
throwsA(
|
|
||||||
isA<UnimplementedError>().having(
|
|
||||||
(e) => e.message,
|
|
||||||
'message',
|
|
||||||
'pbkdf2 is not implemented',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('throws if .encryptAsList() not implemented', () async {
|
|
||||||
await expectLater(
|
|
||||||
() => nativeCryptoPlatform.encryptAsList(
|
|
||||||
Uint8List(0),
|
|
||||||
Uint8List(0),
|
|
||||||
'aes',
|
|
||||||
),
|
|
||||||
throwsA(
|
|
||||||
isA<UnimplementedError>().having(
|
|
||||||
(e) => e.message,
|
|
||||||
'message',
|
|
||||||
'encryptAsList is not implemented',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('throws if .decryptAsList() not implemented', () async {
|
|
||||||
await expectLater(
|
|
||||||
() => nativeCryptoPlatform
|
|
||||||
.decryptAsList([Uint8List(0)], Uint8List(0), 'aes'),
|
|
||||||
throwsA(
|
|
||||||
isA<UnimplementedError>().having(
|
|
||||||
(e) => e.message,
|
|
||||||
'message',
|
|
||||||
'decryptAsList is not implemented',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('throws if .encrypt() not implemented', () async {
|
|
||||||
await expectLater(
|
|
||||||
() => nativeCryptoPlatform.encrypt(Uint8List(0), Uint8List(0), 'aes'),
|
|
||||||
throwsA(
|
|
||||||
isA<UnimplementedError>().having(
|
|
||||||
(e) => e.message,
|
|
||||||
'message',
|
|
||||||
'encrypt is not implemented',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('throws if .decrypt() not implemented', () async {
|
|
||||||
await expectLater(
|
|
||||||
() => nativeCryptoPlatform.decrypt(Uint8List(0), Uint8List(0), 'aes'),
|
|
||||||
throwsA(
|
|
||||||
isA<UnimplementedError>().having(
|
|
||||||
(e) => e.message,
|
|
||||||
'message',
|
|
||||||
'decrypt is not implemented',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExtendsNativeCryptoPlatform extends NativeCryptoPlatform {}
|
|
||||||
|
|
||||||
class ImplementsNativeCryptoPlatform extends Mock
|
|
||||||
implements NativeCryptoPlatform {}
|
|
||||||
|
|
||||||
class MockNativeCryptoPlatform extends Mock
|
|
||||||
with MockPlatformInterfaceMixin
|
|
||||||
implements NativeCryptoPlatform {}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user