Fix/Update #1
							
								
								
									
										323
									
								
								packages/native_crypto/test/src/aes_cipher_test.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										323
									
								
								packages/native_crypto/test/src/aes_cipher_test.dart
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,323 @@ | |||||||
|  | // Author: Hugo Pointcheval | ||||||
|  | // Email: git@pcl.ovh | ||||||
|  | // ----- | ||||||
|  | // File: aes_cipher_test.dart | ||||||
|  | // Created Date: 26/05/2022 23:20:53 | ||||||
|  | // Last Modified: 27/05/2022 16:39:44 | ||||||
|  | // ----- | ||||||
|  | // Copyright (c) 2022 | ||||||
|  | 
 | ||||||
|  | import 'dart:typed_data'; | ||||||
|  | 
 | ||||||
|  | import 'package:flutter/services.dart'; | ||||||
|  | import 'package:flutter_test/flutter_test.dart'; | ||||||
|  | import 'package:native_crypto/native_crypto.dart'; | ||||||
|  | import 'package:native_crypto_platform_interface/native_crypto_platform_interface.dart'; | ||||||
|  | 
 | ||||||
|  | import '../mocks/mock_native_crypto_platform.dart'; | ||||||
|  | 
 | ||||||
|  | void main() { | ||||||
|  |   final MockNativeCryptoPlatform mock = MockNativeCryptoPlatform(); | ||||||
|  |   NativeCryptoPlatform.instance = mock; | ||||||
|  | 
 | ||||||
|  |   setUp(() { | ||||||
|  |     Cipher.bytesCountPerChunk = Cipher.defaultBytesCountPerChunk; | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   group('Constructor', () { | ||||||
|  |     test('throws on invalid key length', () { | ||||||
|  |       expect( | ||||||
|  |         () => AES(SecretKey(Uint8List(0))), | ||||||
|  |         throwsA( | ||||||
|  |           isA<NativeCryptoException>() | ||||||
|  |               .having( | ||||||
|  |                 (e) => e.code, | ||||||
|  |                 'code', | ||||||
|  |                 'invalid_key_length', | ||||||
|  |               ) | ||||||
|  |               .having( | ||||||
|  |                 (e) => e.message, | ||||||
|  |                 'message', | ||||||
|  |                 contains('Invalid key'), | ||||||
|  |               ), | ||||||
|  |         ), | ||||||
|  |       ); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test('creates a valid instance', () { | ||||||
|  |       expect( | ||||||
|  |         AES( | ||||||
|  |           SecretKey(Uint8List(16)), | ||||||
|  |         ), | ||||||
|  |         isA<AES>(), | ||||||
|  |       ); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   group('encrypt', () { | ||||||
|  |     test('returns a valid cipher text wrapper', () async { | ||||||
|  |       mock | ||||||
|  |         ..setEncryptExpectations( | ||||||
|  |           data: Uint8List(16), | ||||||
|  |           key: Uint8List(16), | ||||||
|  |           algorithm: 'aes', | ||||||
|  |         ) | ||||||
|  |         ..setResponse(() => Uint8List(16 + 28)); | ||||||
|  | 
 | ||||||
|  |       final aes = AES(SecretKey(Uint8List(16))); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         await aes.encrypt(Uint8List(16)), | ||||||
|  |         isA<CipherTextWrapper>().having((e) => e.isSingle, 'is single', isTrue), | ||||||
|  |       ); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test('returns a valid cipher text with multiple chunks', () async { | ||||||
|  |       mock | ||||||
|  |         ..setEncryptExpectations( | ||||||
|  |           data: Uint8List(16), | ||||||
|  |           key: Uint8List(16), | ||||||
|  |           algorithm: 'aes', | ||||||
|  |         ) | ||||||
|  |         ..setResponse(() => Uint8List(16 + 28)); // Returns 1 encrypted chunk | ||||||
|  |       Cipher.bytesCountPerChunk = 16; | ||||||
|  |       final aes = AES(SecretKey(Uint8List(16))); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         await aes.encrypt(Uint8List(16 * 3)), | ||||||
|  |         isA<CipherTextWrapper>().having((e) => e.isList, 'is list', isTrue), | ||||||
|  |       ); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test('handles returning empty list', () async { | ||||||
|  |       mock | ||||||
|  |         ..setEncryptExpectations( | ||||||
|  |           data: Uint8List(16), | ||||||
|  |           key: Uint8List(16), | ||||||
|  |           algorithm: 'aes', | ||||||
|  |         ) | ||||||
|  |         ..setResponse(() => Uint8List(0)); | ||||||
|  | 
 | ||||||
|  |       final aes = AES(SecretKey(Uint8List(16))); | ||||||
|  | 
 | ||||||
|  |       await expectLater( | ||||||
|  |         () => aes.encrypt(Uint8List(16)), | ||||||
|  |         throwsA( | ||||||
|  |           isA<NativeCryptoException>().having( | ||||||
|  |             (e) => e.code, | ||||||
|  |             'code', | ||||||
|  |             'platform_returned_empty_data', | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |       ); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test('handles returning null', () async { | ||||||
|  |       mock | ||||||
|  |         ..setEncryptExpectations( | ||||||
|  |           data: Uint8List(16), | ||||||
|  |           key: Uint8List(16), | ||||||
|  |           algorithm: 'aes', | ||||||
|  |         ) | ||||||
|  |         ..setResponse(() => null); | ||||||
|  | 
 | ||||||
|  |       final aes = AES(SecretKey(Uint8List(16))); | ||||||
|  | 
 | ||||||
|  |       await expectLater( | ||||||
|  |         () => aes.encrypt(Uint8List(16)), | ||||||
|  |         throwsA( | ||||||
|  |           isA<NativeCryptoException>().having( | ||||||
|  |             (e) => e.code, | ||||||
|  |             'code', | ||||||
|  |             'platform_returned_null', | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |       ); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test('handles throwing PlatformException', () async { | ||||||
|  |       mock | ||||||
|  |         ..setEncryptExpectations( | ||||||
|  |           data: Uint8List(16), | ||||||
|  |           key: Uint8List(16), | ||||||
|  |           algorithm: 'aes', | ||||||
|  |         ) | ||||||
|  |         ..setResponse( | ||||||
|  |           () => throw PlatformException( | ||||||
|  |             code: 'native_crypto', | ||||||
|  |             message: 'dummy error', | ||||||
|  |           ), | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
|  |       final aes = AES(SecretKey(Uint8List(16))); | ||||||
|  | 
 | ||||||
|  |       await expectLater( | ||||||
|  |         () => aes.encrypt(Uint8List(16)), | ||||||
|  |         throwsA( | ||||||
|  |           isA<NativeCryptoException>() | ||||||
|  |               .having( | ||||||
|  |                 (e) => e.message, | ||||||
|  |                 'message', | ||||||
|  |                 contains( | ||||||
|  |                   'PlatformException(native_crypto, dummy error, null, null)', | ||||||
|  |                 ), | ||||||
|  |               ) | ||||||
|  |               .having( | ||||||
|  |                 (e) => e.code, | ||||||
|  |                 'code', | ||||||
|  |                 'platform_throws', | ||||||
|  |               ), | ||||||
|  |         ), | ||||||
|  |       ); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   group('decrypt', () { | ||||||
|  |     test('returns a valid Uint8List', () async { | ||||||
|  |       mock | ||||||
|  |         ..setDecryptExpectations( | ||||||
|  |           data: Uint8List(16 + 28), | ||||||
|  |           key: Uint8List(16), | ||||||
|  |           algorithm: 'aes', | ||||||
|  |         ) | ||||||
|  |         ..setResponse(() => Uint8List(16)); | ||||||
|  | 
 | ||||||
|  |       final aes = AES(SecretKey(Uint8List(16))); | ||||||
|  |       final bytes = Uint8List(16 + 28); | ||||||
|  |       final wrapper = CipherTextWrapper.fromBytes( | ||||||
|  |         bytes, | ||||||
|  |         ivLength: 12, | ||||||
|  |         tagLength: 16, | ||||||
|  |       ); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         await aes.decrypt(wrapper), | ||||||
|  |         isA<Uint8List>().having((e) => e.length, 'length', 16), | ||||||
|  |       ); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test('returns a valid Uint8List on decrypting multiple chunks', () async { | ||||||
|  |       const int chunkSize = 8; | ||||||
|  |       mock | ||||||
|  |         ..setDecryptExpectations( | ||||||
|  |           data: Uint8List(chunkSize + 28), | ||||||
|  |           key: Uint8List(16), | ||||||
|  |           algorithm: 'aes', | ||||||
|  |         ) | ||||||
|  |         ..setResponse(() => Uint8List(chunkSize)); | ||||||
|  |       Cipher.bytesCountPerChunk = chunkSize; | ||||||
|  |       final aes = AES(SecretKey(Uint8List(16))); | ||||||
|  |       final bytes = Uint8List((chunkSize + 28) * 3); | ||||||
|  |       final wrapper = CipherTextWrapper.fromBytes( | ||||||
|  |         bytes, | ||||||
|  |         ivLength: 12, | ||||||
|  |         tagLength: 16, | ||||||
|  |       ); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         await aes.decrypt(wrapper), | ||||||
|  |         isA<Uint8List>().having((e) => e.length, 'length', chunkSize * 3), | ||||||
|  |       ); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test('handles returning empty list', () async { | ||||||
|  |       mock | ||||||
|  |         ..setDecryptExpectations( | ||||||
|  |           data: Uint8List(16 + 28), | ||||||
|  |           key: Uint8List(16), | ||||||
|  |           algorithm: 'aes', | ||||||
|  |         ) | ||||||
|  |         ..setResponse(() => Uint8List(0)); | ||||||
|  | 
 | ||||||
|  |       final aes = AES(SecretKey(Uint8List(16))); | ||||||
|  |       final bytes = Uint8List(16 + 28); | ||||||
|  |       final wrapper = CipherTextWrapper.fromBytes( | ||||||
|  |         bytes, | ||||||
|  |         ivLength: 12, | ||||||
|  |         tagLength: 16, | ||||||
|  |       ); | ||||||
|  | 
 | ||||||
|  |       await expectLater( | ||||||
|  |         () => aes.decrypt(wrapper), | ||||||
|  |         throwsA( | ||||||
|  |           isA<NativeCryptoException>().having( | ||||||
|  |             (e) => e.code, | ||||||
|  |             'code', | ||||||
|  |             'platform_returned_empty_data', | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |       ); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test('handles returning null', () async { | ||||||
|  |       mock | ||||||
|  |         ..setDecryptExpectations( | ||||||
|  |           data: Uint8List(16 + 28), | ||||||
|  |           key: Uint8List(16), | ||||||
|  |           algorithm: 'aes', | ||||||
|  |         ) | ||||||
|  |         ..setResponse(() => null); | ||||||
|  | 
 | ||||||
|  |       final aes = AES(SecretKey(Uint8List(16))); | ||||||
|  |       final bytes = Uint8List(16 + 28); | ||||||
|  |       final wrapper = CipherTextWrapper.fromBytes( | ||||||
|  |         bytes, | ||||||
|  |         ivLength: 12, | ||||||
|  |         tagLength: 16, | ||||||
|  |       ); | ||||||
|  | 
 | ||||||
|  |       await expectLater( | ||||||
|  |         () => aes.decrypt(wrapper), | ||||||
|  |         throwsA( | ||||||
|  |           isA<NativeCryptoException>().having( | ||||||
|  |             (e) => e.code, | ||||||
|  |             'code', | ||||||
|  |             'platform_returned_null', | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |       ); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test('handles throwing PlatformException', () async { | ||||||
|  |       mock | ||||||
|  |         ..setDecryptExpectations( | ||||||
|  |           data: Uint8List(16 + 28), | ||||||
|  |           key: Uint8List(16), | ||||||
|  |           algorithm: 'aes', | ||||||
|  |         ) | ||||||
|  |         ..setResponse( | ||||||
|  |           () => throw PlatformException( | ||||||
|  |             code: 'native_crypto', | ||||||
|  |             message: 'dummy error', | ||||||
|  |           ), | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
|  |       final aes = AES(SecretKey(Uint8List(16))); | ||||||
|  |       final bytes = Uint8List(16 + 28); | ||||||
|  |       final wrapper = CipherTextWrapper.fromBytes( | ||||||
|  |         bytes, | ||||||
|  |         ivLength: 12, | ||||||
|  |         tagLength: 16, | ||||||
|  |       ); | ||||||
|  | 
 | ||||||
|  |       await expectLater( | ||||||
|  |         () => aes.decrypt(wrapper), | ||||||
|  |         throwsA( | ||||||
|  |           isA<NativeCryptoException>() | ||||||
|  |               .having( | ||||||
|  |                 (e) => e.message, | ||||||
|  |                 'message', | ||||||
|  |                 contains( | ||||||
|  |                   'PlatformException(native_crypto, dummy error, null, null)', | ||||||
|  |                 ), | ||||||
|  |               ) | ||||||
|  |               .having( | ||||||
|  |                 (e) => e.code, | ||||||
|  |                 'code', | ||||||
|  |                 'platform_throws', | ||||||
|  |               ), | ||||||
|  |         ), | ||||||
|  |       ); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | } | ||||||
| @ -3,7 +3,7 @@ | |||||||
| // ----- | // ----- | ||||||
| // File: cipher_text_wrapper_test.dart | // File: cipher_text_wrapper_test.dart | ||||||
| // Created Date: 26/05/2022 21:35:41 | // Created Date: 26/05/2022 21:35:41 | ||||||
| // Last Modified: 26/05/2022 22:27:31 | // Last Modified: 27/05/2022 13:46:54 | ||||||
| // ----- | // ----- | ||||||
| // Copyright (c) 2022 | // Copyright (c) 2022 | ||||||
| 
 | 
 | ||||||
| @ -293,7 +293,6 @@ void main() { | |||||||
|       final wrapper = CipherTextWrapper.fromBytes( |       final wrapper = CipherTextWrapper.fromBytes( | ||||||
|         Uint8List.fromList([1, 2, 3]), |         Uint8List.fromList([1, 2, 3]), | ||||||
|         ivLength: 1, |         ivLength: 1, | ||||||
|         messageLength: 1, |  | ||||||
|         tagLength: 1, |         tagLength: 1, | ||||||
|       ); |       ); | ||||||
|       expect(wrapper.isSingle, isTrue); |       expect(wrapper.isSingle, isTrue); | ||||||
| @ -301,11 +300,10 @@ void main() { | |||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     test('creates list from bytes when too big', () { |     test('creates list from bytes when too big', () { | ||||||
|       Cipher.bytesCountPerChunk = 3; |       Cipher.bytesCountPerChunk = 1; | ||||||
|       final wrapper = CipherTextWrapper.fromBytes( |       final wrapper = CipherTextWrapper.fromBytes( | ||||||
|         Uint8List.fromList([1, 2, 3, 4, 5, 6]), |         Uint8List.fromList([1, 2, 3, 4, 5, 6]), | ||||||
|         ivLength: 1, |         ivLength: 1, | ||||||
|         messageLength: 1, |  | ||||||
|         tagLength: 1, |         tagLength: 1, | ||||||
|       ); |       ); | ||||||
|       expect(wrapper.isList, isTrue); |       expect(wrapper.isList, isTrue); | ||||||
| @ -317,11 +315,35 @@ void main() { | |||||||
|       CipherTextWrapper.fromBytes( |       CipherTextWrapper.fromBytes( | ||||||
|         Uint8List.fromList([1, 2, 3]), |         Uint8List.fromList([1, 2, 3]), | ||||||
|         ivLength: 1, |         ivLength: 1, | ||||||
|         messageLength: 1, |  | ||||||
|         tagLength: 1, |         tagLength: 1, | ||||||
|         chunkSize: 3, |         chunkSize: 3, | ||||||
|       ); |       ); | ||||||
|       expect(Cipher.bytesCountPerChunk, 3); |       expect(Cipher.bytesCountPerChunk, 3); | ||||||
|     }); |     }); | ||||||
|  | 
 | ||||||
|  |     test('throws if trying to build list with bad parameters', () { | ||||||
|  |       Cipher.bytesCountPerChunk = 1; // length of a message | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         () => CipherTextWrapper.fromBytes( | ||||||
|  |           Uint8List.fromList([1, 2, 3, 4, 5, 6]), | ||||||
|  |           ivLength: 2, | ||||||
|  |           tagLength: 1, | ||||||
|  |         ), | ||||||
|  |         throwsA( | ||||||
|  |           isA<NativeCryptoException>() | ||||||
|  |               .having( | ||||||
|  |                 (e) => e.code, | ||||||
|  |                 'code', | ||||||
|  |                 'invalid_argument', | ||||||
|  |               ) | ||||||
|  |               .having( | ||||||
|  |                 (e) => e.message, | ||||||
|  |                 'message', | ||||||
|  |                 contains('on chunk #'), | ||||||
|  |               ), | ||||||
|  |         ), | ||||||
|  |       ); | ||||||
|  |     }); | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user