feat: Bring over the cryptography API from moxplatform
This commit is contained in:
parent
fd91ccc46f
commit
b52ca03eff
@ -4,7 +4,7 @@
|
||||
<application>
|
||||
<provider
|
||||
android:name="org.moxxy.moxxy_native.content.MoxxyFileProvider"
|
||||
android:authorities="org.moxxy.moxxyv2.fileprovider"
|
||||
android:authorities="org.moxxy.moxxyv2.fileprovider2"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
|
@ -2,6 +2,9 @@ package org.moxxy.moxxy_native
|
||||
|
||||
const val TAG = "moxxy_native"
|
||||
|
||||
// The size of buffers to use for various operations
|
||||
const val BUFFER_SIZE = 4096
|
||||
|
||||
// The data key for text entered in the notification's reply field
|
||||
const val REPLY_TEXT_KEY = "key_reply_text"
|
||||
|
||||
|
@ -13,6 +13,8 @@ import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
|
||||
import io.flutter.plugin.common.EventChannel
|
||||
import org.moxxy.moxxy_native.cryptography.CryptographyImplementation
|
||||
import org.moxxy.moxxy_native.cryptography.MoxxyCryptographyApi
|
||||
import org.moxxy.moxxy_native.notifications.MessagingNotification
|
||||
import org.moxxy.moxxy_native.notifications.MoxxyNotificationsApi
|
||||
import org.moxxy.moxxy_native.notifications.NotificationChannel
|
||||
@ -57,11 +59,13 @@ class MoxxyNativePlugin : FlutterPlugin, ActivityAware, MoxxyPickerApi, MoxxyNot
|
||||
private var activity: Activity? = null
|
||||
private lateinit var activityClass: Class<Any>
|
||||
private lateinit var pickerListener: PickerResultListener
|
||||
private val cryptographyImplementation = CryptographyImplementation()
|
||||
|
||||
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
context = flutterPluginBinding.applicationContext
|
||||
MoxxyPickerApi.setUp(flutterPluginBinding.binaryMessenger, this)
|
||||
MoxxyNotificationsApi.setUp(flutterPluginBinding.binaryMessenger, this)
|
||||
MoxxyCryptographyApi.setUp(flutterPluginBinding.binaryMessenger, cryptographyImplementation)
|
||||
pickerListener = PickerResultListener(context!!)
|
||||
Log.d(TAG, "Attached to engine")
|
||||
}
|
||||
|
@ -0,0 +1,192 @@
|
||||
// Autogenerated from Pigeon (v11.0.1), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
|
||||
package org.moxxy.moxxy_native.cryptography
|
||||
|
||||
import android.util.Log
|
||||
import io.flutter.plugin.common.BasicMessageChannel
|
||||
import io.flutter.plugin.common.BinaryMessenger
|
||||
import io.flutter.plugin.common.MessageCodec
|
||||
import io.flutter.plugin.common.StandardMessageCodec
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
private fun wrapResult(result: Any?): List<Any?> {
|
||||
return listOf(result)
|
||||
}
|
||||
|
||||
private fun wrapError(exception: Throwable): List<Any?> {
|
||||
if (exception is FlutterError) {
|
||||
return listOf(
|
||||
exception.code,
|
||||
exception.message,
|
||||
exception.details,
|
||||
)
|
||||
} else {
|
||||
return listOf(
|
||||
exception.javaClass.simpleName,
|
||||
exception.toString(),
|
||||
"Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error class for passing custom error details to Flutter via a thrown PlatformException.
|
||||
* @property code The error code.
|
||||
* @property message The error message.
|
||||
* @property details The error details. Must be a datatype supported by the api codec.
|
||||
*/
|
||||
class FlutterError(
|
||||
val code: String,
|
||||
override val message: String? = null,
|
||||
val details: Any? = null,
|
||||
) : Throwable()
|
||||
|
||||
enum class CipherAlgorithm(val raw: Int) {
|
||||
AES128GCMNOPADDING(0),
|
||||
AES256GCMNOPADDING(1),
|
||||
AES256CBCPKCS7(2),
|
||||
;
|
||||
|
||||
companion object {
|
||||
fun ofRaw(raw: Int): CipherAlgorithm? {
|
||||
return values().firstOrNull { it.raw == raw }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Generated class from Pigeon that represents data sent in messages. */
|
||||
data class CryptographyResult(
|
||||
val plaintextHash: ByteArray,
|
||||
val ciphertextHash: ByteArray,
|
||||
|
||||
) {
|
||||
companion object {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun fromList(list: List<Any?>): CryptographyResult {
|
||||
val plaintextHash = list[0] as ByteArray
|
||||
val ciphertextHash = list[1] as ByteArray
|
||||
return CryptographyResult(plaintextHash, ciphertextHash)
|
||||
}
|
||||
}
|
||||
fun toList(): List<Any?> {
|
||||
return listOf<Any?>(
|
||||
plaintextHash,
|
||||
ciphertextHash,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private object MoxxyCryptographyApiCodec : StandardMessageCodec() {
|
||||
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
||||
return when (type) {
|
||||
128.toByte() -> {
|
||||
return (readValue(buffer) as? List<Any?>)?.let {
|
||||
CryptographyResult.fromList(it)
|
||||
}
|
||||
}
|
||||
else -> super.readValueOfType(type, buffer)
|
||||
}
|
||||
}
|
||||
override fun writeValue(stream: ByteArrayOutputStream, value: Any?) {
|
||||
when (value) {
|
||||
is CryptographyResult -> {
|
||||
stream.write(128)
|
||||
writeValue(stream, value.toList())
|
||||
}
|
||||
else -> super.writeValue(stream, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||
interface MoxxyCryptographyApi {
|
||||
fun encryptFile(sourcePath: String, destPath: String, key: ByteArray, iv: ByteArray, algorithm: CipherAlgorithm, hashSpec: String, callback: (Result<CryptographyResult?>) -> Unit)
|
||||
fun decryptFile(sourcePath: String, destPath: String, key: ByteArray, iv: ByteArray, algorithm: CipherAlgorithm, hashSpec: String, callback: (Result<CryptographyResult?>) -> Unit)
|
||||
fun hashFile(sourcePath: String, hashSpec: String, callback: (Result<ByteArray?>) -> Unit)
|
||||
|
||||
companion object {
|
||||
/** The codec used by MoxxyCryptographyApi. */
|
||||
val codec: MessageCodec<Any?> by lazy {
|
||||
MoxxyCryptographyApiCodec
|
||||
}
|
||||
|
||||
/** Sets up an instance of `MoxxyCryptographyApi` to handle messages through the `binaryMessenger`. */
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun setUp(binaryMessenger: BinaryMessenger, api: MoxxyCryptographyApi?) {
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.moxxy_native.MoxxyCryptographyApi.encryptFile", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val sourcePathArg = args[0] as String
|
||||
val destPathArg = args[1] as String
|
||||
val keyArg = args[2] as ByteArray
|
||||
val ivArg = args[3] as ByteArray
|
||||
val algorithmArg = CipherAlgorithm.ofRaw(args[4] as Int)!!
|
||||
val hashSpecArg = args[5] as String
|
||||
api.encryptFile(sourcePathArg, destPathArg, keyArg, ivArg, algorithmArg, hashSpecArg) { result: Result<CryptographyResult?> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(wrapError(error))
|
||||
} else {
|
||||
val data = result.getOrNull()
|
||||
reply.reply(wrapResult(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.moxxy_native.MoxxyCryptographyApi.decryptFile", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val sourcePathArg = args[0] as String
|
||||
val destPathArg = args[1] as String
|
||||
val keyArg = args[2] as ByteArray
|
||||
val ivArg = args[3] as ByteArray
|
||||
val algorithmArg = CipherAlgorithm.ofRaw(args[4] as Int)!!
|
||||
val hashSpecArg = args[5] as String
|
||||
api.decryptFile(sourcePathArg, destPathArg, keyArg, ivArg, algorithmArg, hashSpecArg) { result: Result<CryptographyResult?> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(wrapError(error))
|
||||
} else {
|
||||
val data = result.getOrNull()
|
||||
reply.reply(wrapResult(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.moxxy_native.MoxxyCryptographyApi.hashFile", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val sourcePathArg = args[0] as String
|
||||
val hashSpecArg = args[1] as String
|
||||
api.hashFile(sourcePathArg, hashSpecArg) { result: Result<ByteArray?> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(wrapError(error))
|
||||
} else {
|
||||
val data = result.getOrNull()
|
||||
reply.reply(wrapResult(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,169 @@
|
||||
package org.moxxy.moxxy_native.cryptography
|
||||
|
||||
import android.util.Log
|
||||
import org.moxxy.moxxy_native.BUFFER_SIZE
|
||||
import org.moxxy.moxxy_native.TAG
|
||||
import java.io.FileInputStream
|
||||
import java.security.MessageDigest
|
||||
import javax.crypto.Cipher
|
||||
import javax.crypto.CipherOutputStream
|
||||
import javax.crypto.spec.IvParameterSpec
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
/*
|
||||
* Convert the algorithm spec @algorithm to the format that Java/Android understands
|
||||
* */
|
||||
private fun getCipherSpecFromInteger(algorithm: CipherAlgorithm): String {
|
||||
return when (algorithm) {
|
||||
CipherAlgorithm.AES128GCMNOPADDING -> "AES_128/GCM/NoPadding"
|
||||
CipherAlgorithm.AES256GCMNOPADDING -> "AES_256/GCM/NoPadding"
|
||||
CipherAlgorithm.AES256CBCPKCS7 -> "AES_256/CBC/PKCS7PADDING"
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of Moxxy's cryptography API
|
||||
* */
|
||||
class CryptographyImplementation : MoxxyCryptographyApi {
|
||||
override fun encryptFile(
|
||||
sourcePath: String,
|
||||
destPath: String,
|
||||
key: ByteArray,
|
||||
iv: ByteArray,
|
||||
algorithm: CipherAlgorithm,
|
||||
hashSpec: String,
|
||||
callback: (Result<CryptographyResult?>) -> Unit,
|
||||
) {
|
||||
thread(start = true) {
|
||||
val cipherSpec = getCipherSpecFromInteger(algorithm)
|
||||
val buffer = ByteArray(BUFFER_SIZE)
|
||||
val secretKey = SecretKeySpec(key, cipherSpec)
|
||||
val inputStream = FileInputStream(sourcePath)
|
||||
try {
|
||||
val digest = MessageDigest.getInstance(hashSpec)
|
||||
val cipher = Cipher.getInstance(cipherSpec).apply {
|
||||
init(Cipher.ENCRYPT_MODE, secretKey, IvParameterSpec(iv))
|
||||
}
|
||||
val fileOutputStream = HashedFileOutputStream(destPath, hashSpec)
|
||||
val cipherOutputStream = CipherOutputStream(fileOutputStream, cipher)
|
||||
var length: Int
|
||||
while (true) {
|
||||
length = inputStream.read(buffer)
|
||||
if (length <= 0) break
|
||||
|
||||
digest.update(buffer, 0, length)
|
||||
cipherOutputStream.write(buffer, 0, length)
|
||||
}
|
||||
|
||||
// Clean up
|
||||
cipherOutputStream.apply {
|
||||
flush()
|
||||
close()
|
||||
}
|
||||
|
||||
// Success
|
||||
callback(
|
||||
Result.success(
|
||||
CryptographyResult(
|
||||
plaintextHash = digest.digest(),
|
||||
ciphertextHash = fileOutputStream.digest(),
|
||||
),
|
||||
),
|
||||
)
|
||||
} catch (ex: Exception) {
|
||||
Log.e(TAG, "Failed to encrypt file $sourcePath: ${ex.message}")
|
||||
callback(Result.success(null))
|
||||
} finally {
|
||||
// Clean up
|
||||
inputStream.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun decryptFile(
|
||||
sourcePath: String,
|
||||
destPath: String,
|
||||
key: ByteArray,
|
||||
iv: ByteArray,
|
||||
algorithm: CipherAlgorithm,
|
||||
hashSpec: String,
|
||||
callback: (Result<CryptographyResult?>) -> Unit,
|
||||
) {
|
||||
thread(start = true) {
|
||||
val cipherSpec = getCipherSpecFromInteger(algorithm)
|
||||
val buffer = ByteArray(BUFFER_SIZE)
|
||||
val secretKey = SecretKeySpec(key, cipherSpec)
|
||||
val inputStream = FileInputStream(sourcePath)
|
||||
try {
|
||||
val digest = MessageDigest.getInstance(hashSpec)
|
||||
val cipher = Cipher.getInstance(cipherSpec).apply {
|
||||
init(Cipher.DECRYPT_MODE, secretKey, IvParameterSpec(iv))
|
||||
}
|
||||
val fileOutputStream = HashedFileOutputStream(destPath, hashSpec)
|
||||
val cipherOutputStream = CipherOutputStream(fileOutputStream, cipher)
|
||||
var length: Int
|
||||
while (true) {
|
||||
length = inputStream.read(buffer)
|
||||
if (length <= 0) break
|
||||
|
||||
digest.update(buffer, 0, length)
|
||||
cipherOutputStream.write(buffer, 0, length)
|
||||
}
|
||||
|
||||
// Clean up
|
||||
cipherOutputStream.apply {
|
||||
flush()
|
||||
close()
|
||||
}
|
||||
|
||||
// Success
|
||||
callback(
|
||||
Result.success(
|
||||
CryptographyResult(
|
||||
plaintextHash = digest.digest(),
|
||||
ciphertextHash = fileOutputStream.digest(),
|
||||
),
|
||||
),
|
||||
)
|
||||
} catch (ex: Exception) {
|
||||
Log.e(TAG, "Failed to decrypt file $sourcePath: ${ex.message}")
|
||||
callback(Result.success(null))
|
||||
} finally {
|
||||
// Clean up
|
||||
inputStream.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun hashFile(
|
||||
sourcePath: String,
|
||||
hashSpec: String,
|
||||
callback: (Result<ByteArray?>) -> Unit,
|
||||
) {
|
||||
thread(start = true) {
|
||||
val buffer = ByteArray(BUFFER_SIZE)
|
||||
val inputStream = FileInputStream(sourcePath)
|
||||
try {
|
||||
val digest = MessageDigest.getInstance(hashSpec)
|
||||
var length: Int
|
||||
while (true) {
|
||||
length = inputStream.read(buffer)
|
||||
if (length <= 0) break
|
||||
|
||||
// Only update the digest if we read more than 0 bytes
|
||||
digest.update(buffer, 0, length)
|
||||
}
|
||||
|
||||
// Return success
|
||||
callback(Result.success(digest.digest()))
|
||||
} catch (ex: Exception) {
|
||||
Log.e(TAG, "Failed to has file $sourcePath with $hashSpec: ${ex.message}")
|
||||
callback(Result.success(null))
|
||||
} finally {
|
||||
// Clean up
|
||||
inputStream.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package org.moxxy.moxxy_native.cryptography
|
||||
|
||||
import java.io.FileOutputStream
|
||||
import java.security.MessageDigest
|
||||
|
||||
/*
|
||||
* A FileOutputStream that continuously hashes whatever it writes to the file.
|
||||
*/
|
||||
class HashedFileOutputStream(name: String, hashAlgorithm: String) : FileOutputStream(name) {
|
||||
private val digest: MessageDigest
|
||||
|
||||
init {
|
||||
this.digest = MessageDigest.getInstance(hashAlgorithm)
|
||||
}
|
||||
|
||||
override fun write(buffer: ByteArray, offset: Int, length: Int) {
|
||||
super.write(buffer, offset, length)
|
||||
|
||||
digest.update(buffer, offset, length)
|
||||
}
|
||||
|
||||
fun digest(): ByteArray {
|
||||
return digest.digest()
|
||||
}
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:moxxy_native/moxxy_native.dart';
|
||||
|
||||
@ -5,9 +7,16 @@ void main() {
|
||||
runApp(const MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
class MyApp extends StatefulWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
@override
|
||||
MyAppState createState() => MyAppState();
|
||||
}
|
||||
|
||||
class MyAppState extends State<MyApp> {
|
||||
String? imagePath;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
@ -44,6 +53,48 @@ class MyApp extends StatelessWidget {
|
||||
},
|
||||
child: const Text('Generic multi-picker'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
final result = await MoxxyPickerApi().pickFiles(FilePickerType.image, false);
|
||||
if (result.isEmpty) return;
|
||||
|
||||
final encDest = result.first! + '.enc';
|
||||
final decDest = result.first! + '.dec';
|
||||
final encResult = await MoxxyCryptographyApi().encryptFile(
|
||||
result.first!,
|
||||
encDest,
|
||||
Uint8List.fromList(List.filled(32, 1)),
|
||||
Uint8List.fromList(List.filled(16, 2)),
|
||||
CipherAlgorithm.aes256CbcPkcs7,
|
||||
'SHA-256',
|
||||
);
|
||||
if (encResult == null) {
|
||||
print('Failed to encrypt file');
|
||||
return;
|
||||
}
|
||||
|
||||
final decResult = await MoxxyCryptographyApi().decryptFile(
|
||||
encDest,
|
||||
decDest,
|
||||
Uint8List.fromList(List.filled(32, 1)),
|
||||
Uint8List.fromList(List.filled(16, 2)),
|
||||
CipherAlgorithm.aes256CbcPkcs7,
|
||||
'SHA-256',
|
||||
);
|
||||
if (decResult == null) {
|
||||
print('Failed to decrypt file');
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
imagePath = decDest;
|
||||
});
|
||||
},
|
||||
child: Text('Test cryptography'),
|
||||
),
|
||||
|
||||
if (imagePath != null)
|
||||
Image.file(File(imagePath!)),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
0
example/pigeon/cryptography.dart
Normal file
0
example/pigeon/cryptography.dart
Normal file
@ -130,54 +130,6 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.2"
|
||||
permission_handler:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: permission_handler
|
||||
sha256: bc56bfe9d3f44c3c612d8d393bd9b174eb796d706759f9b495ac254e4294baa5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.4.5"
|
||||
permission_handler_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_android
|
||||
sha256: "59c6322171c29df93a22d150ad95f3aa19ed86542eaec409ab2691b8f35f9a47"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.3.6"
|
||||
permission_handler_apple:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_apple
|
||||
sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.1.4"
|
||||
permission_handler_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_platform_interface
|
||||
sha256: f2343e9fa9c22ae4fd92d4732755bfe452214e7189afcc097380950cf567b4b2
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.11.5"
|
||||
permission_handler_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_windows
|
||||
sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.3"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.6"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@ -241,4 +193,4 @@ packages:
|
||||
version: "2.1.4"
|
||||
sdks:
|
||||
dart: ">=2.19.6 <3.0.0"
|
||||
flutter: ">=2.8.0"
|
||||
flutter: ">=2.5.0"
|
||||
|
@ -1,2 +1,3 @@
|
||||
export 'pigeon/cryptography.g.dart';
|
||||
export 'pigeon/notifications.g.dart';
|
||||
export 'pigeon/picker.g.dart';
|
||||
|
141
lib/pigeon/cryptography.g.dart
Normal file
141
lib/pigeon/cryptography.g.dart
Normal file
@ -0,0 +1,141 @@
|
||||
// Autogenerated from Pigeon (v11.0.1), 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';
|
||||
|
||||
enum CipherAlgorithm {
|
||||
aes128GcmNoPadding,
|
||||
aes256GcmNoPadding,
|
||||
aes256CbcPkcs7,
|
||||
}
|
||||
|
||||
class CryptographyResult {
|
||||
CryptographyResult({
|
||||
required this.plaintextHash,
|
||||
required this.ciphertextHash,
|
||||
});
|
||||
|
||||
Uint8List plaintextHash;
|
||||
|
||||
Uint8List ciphertextHash;
|
||||
|
||||
Object encode() {
|
||||
return <Object?>[
|
||||
plaintextHash,
|
||||
ciphertextHash,
|
||||
];
|
||||
}
|
||||
|
||||
static CryptographyResult decode(Object result) {
|
||||
result as List<Object?>;
|
||||
return CryptographyResult(
|
||||
plaintextHash: result[0]! as Uint8List,
|
||||
ciphertextHash: result[1]! as Uint8List,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _MoxxyCryptographyApiCodec extends StandardMessageCodec {
|
||||
const _MoxxyCryptographyApiCodec();
|
||||
@override
|
||||
void writeValue(WriteBuffer buffer, Object? value) {
|
||||
if (value is CryptographyResult) {
|
||||
buffer.putUint8(128);
|
||||
writeValue(buffer, value.encode());
|
||||
} else {
|
||||
super.writeValue(buffer, value);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Object? readValueOfType(int type, ReadBuffer buffer) {
|
||||
switch (type) {
|
||||
case 128:
|
||||
return CryptographyResult.decode(readValue(buffer)!);
|
||||
default:
|
||||
return super.readValueOfType(type, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MoxxyCryptographyApi {
|
||||
/// Constructor for [MoxxyCryptographyApi]. 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.
|
||||
MoxxyCryptographyApi({BinaryMessenger? binaryMessenger})
|
||||
: _binaryMessenger = binaryMessenger;
|
||||
final BinaryMessenger? _binaryMessenger;
|
||||
|
||||
static const MessageCodec<Object?> codec = _MoxxyCryptographyApiCodec();
|
||||
|
||||
Future<CryptographyResult?> encryptFile(String arg_sourcePath, String arg_destPath, Uint8List arg_key, Uint8List arg_iv, CipherAlgorithm arg_algorithm, String arg_hashSpec) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.moxxy_native.MoxxyCryptographyApi.encryptFile', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_sourcePath, arg_destPath, arg_key, arg_iv, arg_algorithm.index, arg_hashSpec]) 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 {
|
||||
return (replyList[0] as CryptographyResult?);
|
||||
}
|
||||
}
|
||||
|
||||
Future<CryptographyResult?> decryptFile(String arg_sourcePath, String arg_destPath, Uint8List arg_key, Uint8List arg_iv, CipherAlgorithm arg_algorithm, String arg_hashSpec) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.moxxy_native.MoxxyCryptographyApi.decryptFile', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_sourcePath, arg_destPath, arg_key, arg_iv, arg_algorithm.index, arg_hashSpec]) 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 {
|
||||
return (replyList[0] as CryptographyResult?);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Uint8List?> hashFile(String arg_sourcePath, String arg_hashSpec) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.moxxy_native.MoxxyCryptographyApi.hashFile', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_sourcePath, arg_hashSpec]) 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 {
|
||||
return (replyList[0] as Uint8List?);
|
||||
}
|
||||
}
|
||||
}
|
34
pigeon/cryptography.dart
Normal file
34
pigeon/cryptography.dart
Normal file
@ -0,0 +1,34 @@
|
||||
import 'package:pigeon/pigeon.dart';
|
||||
|
||||
@ConfigurePigeon(
|
||||
PigeonOptions(
|
||||
dartOut: 'lib/pigeon/cryptography.g.dart',
|
||||
kotlinOut: 'android/src/main/kotlin/org/moxxy/moxxy_native/cryptography/CryptographyApi.kt',
|
||||
kotlinOptions: KotlinOptions(
|
||||
package: 'org.moxxy.moxxy_native.cryptography',
|
||||
),
|
||||
),
|
||||
)
|
||||
enum CipherAlgorithm {
|
||||
aes128GcmNoPadding,
|
||||
aes256GcmNoPadding,
|
||||
aes256CbcPkcs7;
|
||||
}
|
||||
|
||||
class CryptographyResult {
|
||||
const CryptographyResult(this.plaintextHash, this.ciphertextHash);
|
||||
final Uint8List plaintextHash;
|
||||
final Uint8List ciphertextHash;
|
||||
}
|
||||
|
||||
@HostApi()
|
||||
abstract class MoxxyCryptographyApi {
|
||||
@async
|
||||
CryptographyResult? encryptFile(String sourcePath, String destPath, Uint8List key, Uint8List iv, CipherAlgorithm algorithm, String hashSpec);
|
||||
|
||||
@async
|
||||
CryptographyResult? decryptFile(String sourcePath, String destPath, Uint8List key, Uint8List iv, CipherAlgorithm algorithm, String hashSpec);
|
||||
|
||||
@async
|
||||
Uint8List? hashFile(String sourcePath, String hashSpec);
|
||||
}
|
Loading…
Reference in New Issue
Block a user