fix: update code to pass tests

This commit is contained in:
Hugo Pointcheval 2022-05-27 16:41:43 +02:00
parent cefa73ec3d
commit 1b00d20ec5
Signed by: hugo
GPG Key ID: A9E8E9615379254F
4 changed files with 92 additions and 39 deletions

View File

@ -3,7 +3,7 @@
// ----- // -----
// File: aes.dart // File: aes.dart
// Created Date: 16/12/2021 16:28:00 // Created Date: 16/12/2021 16:28:00
// Last Modified: 26/05/2022 21:07:01 // Last Modified: 27/05/2022 12:13:28
// ----- // -----
// Copyright (c) 2022 // Copyright (c) 2022
@ -46,7 +46,6 @@ class AES implements Cipher {
); );
} }
if (!mode.supportedPaddings.contains(padding)) { if (!mode.supportedPaddings.contains(padding)) {
throw NativeCryptoException( throw NativeCryptoException(
message: 'Invalid padding! ' message: 'Invalid padding! '
@ -56,13 +55,25 @@ class AES implements Cipher {
} }
} }
Future<Uint8List> _decrypt(CipherText cipherText, Future<Uint8List> _decrypt(
{int chunkCount = 0,}) async { CipherText cipherText, {
final Uint8List? decrypted = await platform.decrypt( int chunkCount = 0,
}) async {
Uint8List? decrypted;
try {
decrypted = await platform.decrypt(
cipherText.bytes, cipherText.bytes,
_key.bytes, _key.bytes,
algorithm.name, algorithm.name,
); );
} catch (e, s) {
throw NativeCryptoException(
message: '$e',
code: NativeCryptoExceptionCode.platform_throws.code,
stackTrace: s,
);
}
if (decrypted.isNull) { if (decrypted.isNull) {
throw NativeCryptoException( throw NativeCryptoException(
@ -80,11 +91,21 @@ class AES implements Cipher {
} }
Future<CipherText> _encrypt(Uint8List data, {int chunkCount = 0}) async { Future<CipherText> _encrypt(Uint8List data, {int chunkCount = 0}) async {
final Uint8List? encrypted = await platform.encrypt( Uint8List? encrypted;
try {
encrypted = await platform.encrypt(
data, data,
_key.bytes, _key.bytes,
algorithm.name, algorithm.name,
); );
} catch (e, s) {
throw NativeCryptoException(
message: '$e on chunk #$chunkCount',
code: NativeCryptoExceptionCode.platform_throws.code,
stackTrace: s,
);
}
if (encrypted.isNull) { if (encrypted.isNull) {
throw NativeCryptoException( throw NativeCryptoException(
@ -97,6 +118,7 @@ class AES implements Cipher {
code: NativeCryptoExceptionCode.platform_returned_empty_data.code, code: NativeCryptoExceptionCode.platform_returned_empty_data.code,
); );
} else { } else {
try {
return CipherText.fromBytes( return CipherText.fromBytes(
encrypted, encrypted,
ivLength: 12, ivLength: 12,
@ -104,6 +126,13 @@ class AES implements Cipher {
tagLength: 16, tagLength: 16,
cipherAlgorithm: CipherAlgorithm.aes, cipherAlgorithm: CipherAlgorithm.aes,
); );
} on NativeCryptoException catch (e, s) {
throw NativeCryptoException(
message: '${e.message} on chunk #$chunkCount',
code: e.code,
stackTrace: s,
);
}
} }
} }
@ -125,6 +154,9 @@ class AES implements Cipher {
@override @override
Future<CipherTextWrapper> encrypt(Uint8List data) async { Future<CipherTextWrapper> encrypt(Uint8List data) async {
if (data.isEmpty) {
return CipherTextWrapper.empty();
}
CipherTextWrapper cipherTextWrapper; CipherTextWrapper cipherTextWrapper;
Uint8List dataToEncrypt; Uint8List dataToEncrypt;
final int chunkNb = (data.length / Cipher.bytesCountPerChunk).ceil(); final int chunkNb = (data.length / Cipher.bytesCountPerChunk).ceil();

View File

@ -3,7 +3,7 @@
// ----- // -----
// File: cipher_text.dart // File: cipher_text.dart
// Created Date: 16/12/2021 16:59:53 // Created Date: 16/12/2021 16:59:53
// Last Modified: 26/05/2022 22:20:40 // Last Modified: 27/05/2022 12:09:47
// ----- // -----
// Copyright (c) 2021 // Copyright (c) 2021
@ -47,10 +47,12 @@ class CipherText extends ByteArray {
factory CipherText.fromBytes( factory CipherText.fromBytes(
Uint8List bytes, { Uint8List bytes, {
required int ivLength, required int ivLength,
required int messageLength,
required int tagLength, required int tagLength,
int? messageLength,
CipherAlgorithm? cipherAlgorithm, CipherAlgorithm? cipherAlgorithm,
}) { }) {
messageLength ??= bytes.length - ivLength - tagLength;
if (ivLength.isNegative || if (ivLength.isNegative ||
messageLength.isNegative || messageLength.isNegative ||
tagLength.isNegative) { tagLength.isNegative) {

View File

@ -3,7 +3,7 @@
// ----- // -----
// File: cipher_text_wrapper.dart // File: cipher_text_wrapper.dart
// Created Date: 26/05/2022 14:27:32 // Created Date: 26/05/2022 14:27:32
// Last Modified: 26/05/2022 22:11:42 // Last Modified: 27/05/2022 13:43:29
// ----- // -----
// Copyright (c) 2022 // Copyright (c) 2022
@ -51,7 +51,6 @@ class CipherTextWrapper {
factory CipherTextWrapper.fromBytes( factory CipherTextWrapper.fromBytes(
Uint8List bytes, { Uint8List bytes, {
required int ivLength, required int ivLength,
required int messageLength,
required int tagLength, required int tagLength,
CipherAlgorithm? cipherAlgorithm, CipherAlgorithm? cipherAlgorithm,
int? chunkSize, int? chunkSize,
@ -59,29 +58,38 @@ class CipherTextWrapper {
chunkSize ??= Cipher.bytesCountPerChunk; chunkSize ??= Cipher.bytesCountPerChunk;
Cipher.bytesCountPerChunk = chunkSize; Cipher.bytesCountPerChunk = chunkSize;
if (bytes.length <= chunkSize) { final int messageLength = bytes.length - ivLength - tagLength;
if (messageLength <= chunkSize) {
return CipherTextWrapper.single( return CipherTextWrapper.single(
CipherText.fromBytes( CipherText.fromBytes(
bytes, bytes,
ivLength: ivLength, ivLength: ivLength,
messageLength: messageLength,
tagLength: tagLength, tagLength: tagLength,
cipherAlgorithm: cipherAlgorithm, cipherAlgorithm: cipherAlgorithm,
), ),
); );
} else { } else {
final cipherTexts = <CipherText>[]; final cipherTexts = <CipherText>[];
for (var i = 0; i < bytes.length; i += chunkSize) { for (var i = 0; i < bytes.length; i += chunkSize + ivLength + tagLength) {
final chunk = bytes.sublist(i, i + chunkSize); final chunk = bytes.trySublist(i, i + chunkSize + ivLength + tagLength);
try {
cipherTexts.add( cipherTexts.add(
CipherText.fromBytes( CipherText.fromBytes(
chunk, chunk,
ivLength: ivLength, ivLength: ivLength,
messageLength: messageLength,
tagLength: tagLength, tagLength: tagLength,
cipherAlgorithm: cipherAlgorithm, cipherAlgorithm: cipherAlgorithm,
), ),
); );
} on NativeCryptoException catch (e, s) {
throw NativeCryptoException(
message: '${e.message} on chunk #$i',
code: e.code,
stackTrace: s,
);
}
} }
return CipherTextWrapper.list(cipherTexts); return CipherTextWrapper.list(cipherTexts);
} }

View File

@ -3,7 +3,7 @@
// ----- // -----
// File: extensions.dart // File: extensions.dart
// Created Date: 26/05/2022 12:12:48 // Created Date: 26/05/2022 12:12:48
// Last Modified: 26/05/2022 22:15:33 // Last Modified: 27/05/2022 12:26:55
// ----- // -----
// Copyright (c) 2022 // Copyright (c) 2022
@ -87,4 +87,15 @@ extension Uint8ListX on Uint8List {
/// Returns a concatenation of this with the other [Uint8List]. /// Returns a concatenation of this with the other [Uint8List].
Uint8List plus(final Uint8List other) => [...this, ...other].toTypedList(); Uint8List plus(final Uint8List other) => [...this, ...other].toTypedList();
/// Returns a sublist of this from the [start] index to the [end] index.
/// If [end] is greater than the length of the list, it is set to the length
Uint8List trySublist(int start, [int? end]) {
if (isEmpty) return this;
int ending = end ?? length;
if (ending > length) ending = length;
return sublist(start, ending);
}
} }