diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 050c69a..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,25 +0,0 @@ -## 0.0.6 - -**WIP...** - -## 0.0.5 - -* New API -* Add digest support -* Clean platform specific code base -## 0.0.4 - -* Improve AES - -## 0.0.3 - -* Add PBKDF2 support -* Add exceptions -* Improve documentation -## 0.0.2 - -* Add different key size support -* Improve performances -## 0.0.1 - -* First AES cross-platform encryption & decryption implementation. diff --git a/README.md b/README.md deleted file mode 100644 index 998e20b..0000000 --- a/README.md +++ /dev/null @@ -1,167 +0,0 @@ -# NativeCrypto for Flutter - -![NativeCrypto Logo](/assets/native_crypto.png) ---- - -Fast and powerful cryptographic functions thanks to **javax.crypto** and **CommonCrypto**. - -## πŸ“ Table of Contents - -- [About](#about) -- [Getting Started](#getting_started) -- [Example](#example) -- [Usage](#usage) -- [Built Using](#built_using) -- [TODOS](#todos) -- [Authors](#authors) - -## 🧐 About - -The goal of this plugin is to provide simple access to fast and powerful cryptographic functions by calling native libraries. So on **Android** the plugin uses *javax.crypto* and on **iOS** it uses *CommonCrypto*. - -I started this project because using **Pointy Castle** I faced big performance issues on smartphone. It's quite simple, an encryption of 1MB of data in AES256 on an Android device takes **20s** with Pointy Castle against **27ms** using NativeCrypto. - -![Pointy Castle Benchmark](/assets/benchmark_pointycastle.png) - -> We also notice on this benchmark that the AES encryption time does not even increase linearly with size. - -As for NativeCrypto, here is a benchmark realized on an iPhone 11. - -| Size (kB) | NativeCrypto **encryption** time (ms) | -|-----------|---------------------------------------| -| 2 mB | 13 ms -| 4 mB | 17 ms -| 8 mB | 56 ms -| 16 mB | 73 ms -| 32 mB | 120 ms -| 64 mB | 243 ms -| 128 mB | 509 ms -| 256 mB | 1057 ms - -> ~1s for 256 mB ! - -In short, **NativeCrypto** is incomparable to **Pointy Castle** in terms of performance. - -## 🏁 Getting Started - -### Prerequisites - -You'll need: - -- Flutter - -### Installing - -Add these lines in your **pubspec.yaml**: - -```yaml -native_crypto: - git: - url: https://github.com/hugo-pcl/native-crypto-flutter.git - ref: v0.0.x -``` - -> Replace "x" with the current version! - -Then in your code: - -```dart -import 'package:native_crypto/native_crypto.dart'; -``` - -## πŸ” Example - -Look in **example/lib/** for an example app. - -## 🎈 Usage - -To derive a key with **PBKDF2**. - -```dart -PBKDF2 _pbkdf2 = PBKDF2(keyLength: 32, iteration: 1000, hash: HashAlgorithm.SHA512); -await _pbkdf2.derive(password: "password123", salt: 'salty'); -SecretKey key = _pbkdf2.key; -``` - -To generate a key, and create an **AES Cipher** instance. - -```dart -AESCipher aes = await AESCipher.generate( - AESKeySize.bits256, - CipherParameters( - BlockCipherMode.CBC, - PlainTextPadding.PKCS5, - ), -); -``` - -You can also generate key, then create **AES Cipher**. - -```dart -SecretKey _key = await SecretKey.generate(256, CipherAlgorithm.AES); -AESCipher aes = AESCipher( - _key, - CipherParameters( - BlockCipherMode.CBC, - PlainTextPadding.PKCS5, - ), -); -``` - -Then you can encrypt/decrypt data with this cipher. - -```dart -CipherText cipherText = await aes.encrypt(data); -Uint8List plainText = await aes.decrypt(cipherText); -``` - -You can easely get encrypted bytes and IV from a CipherText - -```dart -Uint8List bytes = cipherText.bytes; -Uint8List iv = cipherText.iv; -``` - -To create a cipher text with custom data. - -```dart -CipherText cipherText = AESCipherText(bytes, iv); -``` - -To create a hashed message - -```dart -MessageDigest md = MessageDigest.getInstance("sha256"); -Uint8List hash = await md.digest(message); -``` - -## ⛏️ Built Using - -- [Dart](https://dart.dev) -- [Flutter](https://flutter.dev) - Framework -- [Kotlin](https://kotlinlang.org) - Android Specific code -- [Swift](https://www.apple.com/fr/swift/) - iOS Specific code - -## πŸš€ TODOS - -Here you can check major changes, roadmap and todos. - -I plan to deal with asymmetric cryptography with the implementation of a Key Encapsulation Mechanism. - -- [x] Add PBKDF2 support. -- [x] Implement working cross platform AES encryption/decryption. -- [x] Add Different key sizes support. -- [x] Add exceptions. -- [x] Clean platform specific code. -- [x] Add digest. -- [x] Rework exposed API. -- [x] Add KeyPair generation. -- [ ] Add KEM. -- [ ] Porting NativeCrypto to other platforms... - -You can contribute to this project. - -## ✍️ Authors - -- [Hugo Pointcheval](https://github.com/hugo-pcl) - Idea & Initial work -- [Chisom Maxwell](https://github.com/maxcotech) - For the chunks idea [#2](https://github.com/hugo-pcl/native-crypto-flutter/issues/2) diff --git a/android/.gitignore b/android/.gitignore deleted file mode 100644 index c6cbe56..0000000 --- a/android/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea/workspace.xml -/.idea/libraries -.DS_Store -/build -/captures diff --git a/android/build.gradle b/android/build.gradle deleted file mode 100644 index 599777e..0000000 --- a/android/build.gradle +++ /dev/null @@ -1,44 +0,0 @@ -group 'fr.pointcheval.native_crypto' -version '1.0-SNAPSHOT' - -buildscript { - ext.kotlin_version = '1.3.50' - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -rootProject.allprojects { - repositories { - google() - jcenter() - } -} - -apply plugin: 'com.android.library' -apply plugin: 'kotlin-android' - -android { - compileSdkVersion 29 - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - defaultConfig { - minSdkVersion 16 - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - lintOptions { - disable 'InvalidPackage' - } -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} diff --git a/android/settings.gradle b/android/settings.gradle deleted file mode 100644 index 430c95a..0000000 --- a/android/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'native_crypto' diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml deleted file mode 100644 index fcd47dc..0000000 --- a/android/src/main/AndroidManifest.xml +++ /dev/null @@ -1,3 +0,0 @@ - - diff --git a/android/src/main/kotlin/fr/pointcheval/native_crypto/Cipher.kt b/android/src/main/kotlin/fr/pointcheval/native_crypto/Cipher.kt deleted file mode 100644 index 5302993..0000000 --- a/android/src/main/kotlin/fr/pointcheval/native_crypto/Cipher.kt +++ /dev/null @@ -1,93 +0,0 @@ -package fr.pointcheval.native_crypto - -import java.lang.Exception -import javax.crypto.Cipher -import javax.crypto.SecretKey -import javax.crypto.spec.IvParameterSpec -import javax.crypto.spec.SecretKeySpec - -enum class CipherAlgorithm(val spec: String) { - AES("AES"), -} - -enum class BlockCipherMode(val instance: String) { - CBC("CBC"), - GCM("GCM"), -} - -enum class Padding(val instance: String) { - PKCS5("PKCS5Padding"), - None("NoPadding") -} - -class CipherParameters(private val mode: BlockCipherMode, private val padding: Padding) { - override fun toString(): String { - return mode.instance + "/" + padding.instance - } -} - -class Cipher { - - fun getCipherAlgorithm(dartAlgorithm: String) : CipherAlgorithm { - return when (dartAlgorithm) { - "aes" -> CipherAlgorithm.AES - else -> CipherAlgorithm.AES - } - } - - fun getInstance(mode : String, padding : String) : CipherParameters { - val m = when (mode) { - "cbc" -> BlockCipherMode.CBC - "gcm" -> BlockCipherMode.GCM - else -> throw Exception() - } - val p = when (padding) { - "pkcs5" -> Padding.PKCS5 - else -> Padding.None - } - return CipherParameters(m,p) - } - - fun encrypt(data: ByteArray, key: ByteArray, algorithm: String, mode: String, padding: String) : List { - val algo = getCipherAlgorithm(algorithm) - val params = getInstance(mode, padding) - - val keySpecification = algo.spec + "/" + params.toString() - - val mac = Hash().digest(key + data) - val sk: SecretKey = SecretKeySpec(key, algo.spec) - - val cipher = Cipher.getInstance(keySpecification) - cipher.init(Cipher.ENCRYPT_MODE, sk) - - val encryptedBytes = cipher.doFinal(mac + data) - val iv = cipher.iv - - return listOf(encryptedBytes, iv); - } - - fun decrypt(payload: Collection, key: ByteArray, algorithm: String, mode: String, padding: String) : ByteArray? { - val algo = getCipherAlgorithm(algorithm) - val params = getInstance(mode, padding) - - val keySpecification = algo.spec + "/" + params.toString() - - val sk: SecretKey = SecretKeySpec(key, algo.spec) - val cipher = Cipher.getInstance(keySpecification); - val iv = payload.last(); - val ivSpec = IvParameterSpec(iv) - cipher.init(Cipher.DECRYPT_MODE, sk, ivSpec); - - val decryptedBytes = cipher.doFinal(payload.first()); - - val mac = decryptedBytes.copyOfRange(0, 32) - val decryptedContent : ByteArray = decryptedBytes.copyOfRange(32, decryptedBytes.size) - val verificationMac = Hash().digest(key + decryptedContent) - - return if (mac.contentEquals(verificationMac)) { - decryptedContent - } else { - null; - } - } -} \ No newline at end of file diff --git a/android/src/main/kotlin/fr/pointcheval/native_crypto/HashAlgorithm.kt b/android/src/main/kotlin/fr/pointcheval/native_crypto/HashAlgorithm.kt deleted file mode 100644 index 434f752..0000000 --- a/android/src/main/kotlin/fr/pointcheval/native_crypto/HashAlgorithm.kt +++ /dev/null @@ -1,42 +0,0 @@ -package fr.pointcheval.native_crypto - -import java.security.MessageDigest - -enum class HashAlgorithm(val length : Int) { - SHA1(160), - SHA224(224), - SHA256(256), - SHA384(384), - SHA512(512); -} - - -class Hash() { - fun digest(data: ByteArray?, algorithm: HashAlgorithm): ByteArray { - val func : String = when (algorithm) { - HashAlgorithm.SHA1 -> "SHA-1" - HashAlgorithm.SHA224 -> "SHA-224" - HashAlgorithm.SHA256 -> "SHA-256" - HashAlgorithm.SHA384 -> "SHA-384" - HashAlgorithm.SHA512 -> "SHA-512" - } - val md = MessageDigest.getInstance(func) - return md.digest(data) - } - - fun digest(data: ByteArray?, algorithm: String): ByteArray { - val func : HashAlgorithm = when (algorithm) { - "sha1" -> HashAlgorithm.SHA1 - "sha224" -> HashAlgorithm.SHA224 - "sha256" -> HashAlgorithm.SHA256 - "sha384" -> HashAlgorithm.SHA384 - "sha512" -> HashAlgorithm.SHA512 - else -> HashAlgorithm.SHA256 - } - return digest(data, func) - } - - fun digest(data: ByteArray?): ByteArray { - return digest(data, HashAlgorithm.SHA256) - } -} diff --git a/android/src/main/kotlin/fr/pointcheval/native_crypto/KeyDerivation.kt b/android/src/main/kotlin/fr/pointcheval/native_crypto/KeyDerivation.kt deleted file mode 100644 index 8931164..0000000 --- a/android/src/main/kotlin/fr/pointcheval/native_crypto/KeyDerivation.kt +++ /dev/null @@ -1,35 +0,0 @@ -package fr.pointcheval.native_crypto - -import android.os.Build -import java.lang.IllegalArgumentException -import javax.crypto.SecretKeyFactory -import javax.crypto.spec.PBEKeySpec - -class KeyDerivation { - fun pbkdf2(password: String, salt: String, keyLength: Int, iteration: Int, algorithm: String): ByteArray { - val chars: CharArray = password.toCharArray() - val availableHashAlgorithm: Map = mapOf( - "sha1" to "PBKDF2withHmacSHA1", - "sha224" to "PBKDF2withHmacSHA224", - "sha256" to "PBKDF2WithHmacSHA256", - "sha384" to "PBKDF2withHmacSHA384", - "sha512" to "PBKDF2withHmacSHA512" - ) - - if (Build.VERSION.SDK_INT >= 26) { - // SHA-1 and SHA-2 implemented - val spec = PBEKeySpec(chars, salt.toByteArray(), iteration, keyLength * 8) - val skf: SecretKeyFactory = SecretKeyFactory.getInstance(availableHashAlgorithm[algorithm]); - return skf.generateSecret(spec).encoded - } else if (Build.VERSION.SDK_INT >= 10) { - // Only SHA-1 is implemented - if (!algorithm.equals("sha1")) { - throw PlatformVersionException("Only SHA1 is implemented on this SDK version!") - } - val spec = PBEKeySpec(chars, salt.toByteArray(), iteration, keyLength * 8) - val skf: SecretKeyFactory = SecretKeyFactory.getInstance("PBKDF2withHmacSHA1"); - return skf.generateSecret(spec).encoded - } - throw PlatformVersionException("Invalid SDK version!") - } -} \ No newline at end of file diff --git a/android/src/main/kotlin/fr/pointcheval/native_crypto/KeyGeneration.kt b/android/src/main/kotlin/fr/pointcheval/native_crypto/KeyGeneration.kt deleted file mode 100644 index b937732..0000000 --- a/android/src/main/kotlin/fr/pointcheval/native_crypto/KeyGeneration.kt +++ /dev/null @@ -1,32 +0,0 @@ -package fr.pointcheval.native_crypto - -import java.security.KeyPairGenerator -import java.security.SecureRandom -import javax.crypto.KeyGenerator - -class KeyGeneration { - fun keygen(size : Int) : ByteArray { - val secureRandom = SecureRandom() - val keyGenerator = if (size in listOf(128,192,256)) { - KeyGenerator.getInstance("AES") - } else { - KeyGenerator.getInstance("BLOWFISH") - } - - keyGenerator.init(size, secureRandom) - val sk = keyGenerator.generateKey() - - return sk!!.encoded - } - - fun rsaKeypairGen(size : Int) : List { - val secureRandom = SecureRandom() - val keyGenerator = KeyPairGenerator.getInstance("RSA") - - keyGenerator.initialize(size, secureRandom) - val keypair = keyGenerator.genKeyPair() - val res : List = listOf(keypair.public.encoded, keypair.private.encoded) - - return res - } -} \ No newline at end of file diff --git a/android/src/main/kotlin/fr/pointcheval/native_crypto/NativeCryptoPlugin.kt b/android/src/main/kotlin/fr/pointcheval/native_crypto/NativeCryptoPlugin.kt deleted file mode 100644 index 78218bd..0000000 --- a/android/src/main/kotlin/fr/pointcheval/native_crypto/NativeCryptoPlugin.kt +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2020 - * Author: Hugo Pointcheval - */ -package fr.pointcheval.native_crypto - -import androidx.annotation.NonNull -import io.flutter.embedding.engine.plugins.FlutterPlugin -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel -import io.flutter.plugin.common.MethodChannel.MethodCallHandler -import io.flutter.plugin.common.MethodChannel.Result -import io.flutter.plugin.common.PluginRegistry.Registrar - - -/** NativeCryptoPlugin */ -class NativeCryptoPlugin : FlutterPlugin, MethodCallHandler { - override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { - val channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "native.crypto") - channel.setMethodCallHandler(NativeCryptoPlugin()); - } - - companion object { - @JvmStatic - fun registerWith(registrar: Registrar) { - val channel = MethodChannel(registrar.messenger(), "native.crypto") - channel.setMethodCallHandler(NativeCryptoPlugin()) - } - } - - override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { - - when (call.method) { - "digest" -> { - val message = call.argument("message") - val algorithm = call.argument("algorithm") - - try { - val d = Hash().digest(message, algorithm!!) - if (d.isNotEmpty()) { - result.success(d) - } else { - result.error("DIGESTERROR", "DIGEST IS NULL.", null) - } - } catch (e : Exception) { - result.error("DIGESTEXCEPTION", e.message, null) - } - } - "pbkdf2" -> { - val password = call.argument("password") - val salt = call.argument("salt") - val keyLength = call.argument("keyLength") - val iteration = call.argument("iteration") - val algorithm = call.argument("algorithm") - - try { - val key = KeyDerivation().pbkdf2(password!!, salt!!, keyLength!!, iteration!!, algorithm!!) - if (key.isNotEmpty()) { - result.success(key) - } else { - result.error("PBKDF2ERROR", "PBKDF2 KEY IS NULL.", null) - } - } catch (e : Exception) { - result.error("PBKDF2EXCEPTION", e.message, null) - } - } - "keygen" -> { - val size = call.argument("size") // 128, 192, 256 - try { - val key = KeyGeneration().keygen(size!!) - - if (key.isNotEmpty()) { - result.success(key) - } else { - result.error("KEYGENERROR", "GENERATED KEY IS NULL.", null) - } - } catch (e : Exception) { - result.error("KEYGENEXCEPTION", e.message, null) - } - } - "rsaKeypairGen" -> { - val size = call.argument("size") - try { - val keypair = KeyGeneration().rsaKeypairGen(size!!) - - if (keypair.isNotEmpty()) { - result.success(keypair) - } else { - result.error("KEYPAIRGENERROR", "GENERATED KEYPAIR IS EMPTY.", null) - } - } catch (e : Exception) { - result.error("KEYPAIRGENEXCEPTION", e.message, null) - } - } - "encrypt" -> { - val data = call.argument("data") - val key = call.argument("key") - val algorithm = call.argument("algorithm") - val mode = call.argument("mode") - val padding = call.argument("padding") - - try { - val payload = Cipher().encrypt(data!!, key!!, algorithm!!, mode!!, padding!!) - - if (payload.isNotEmpty()) { - result.success(payload) - } else { - result.error("ENCRYPTIONERROR", "ENCRYPTED PAYLOAD IS EMPTY.", null) - } - } catch (e: Exception) { - result.error("ENCRYPTIONEXCEPTION", e.message, null) - } - - } - "decrypt" -> { - val payload = call.argument>("payload") // Collection - - val key = call.argument("key") - val algorithm = call.argument("algorithm") - val mode = call.argument("mode") - val padding = call.argument("padding") - - var decryptedPayload : ByteArray? = null - - try { - decryptedPayload = Cipher().decrypt(payload!!, key!!, algorithm!!, mode!!, padding!!) - if (decryptedPayload != null && decryptedPayload.isNotEmpty()) { - result.success(decryptedPayload) - } else { - result.error("DECRYPTIONERROR", "DECRYPTED PAYLOAD IS NULL. MAYBE VERIFICATION MAC IS UNVALID.", null) - } - } catch (e : Exception) { - result.error("DECRYPTIONEXCEPTION", e.message, null) - } - } - else -> result.notImplemented() - } - } - - override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { - } -} diff --git a/android/src/main/kotlin/fr/pointcheval/native_crypto/PlatformVersionException.kt b/android/src/main/kotlin/fr/pointcheval/native_crypto/PlatformVersionException.kt deleted file mode 100644 index 4549060..0000000 --- a/android/src/main/kotlin/fr/pointcheval/native_crypto/PlatformVersionException.kt +++ /dev/null @@ -1,5 +0,0 @@ -package fr.pointcheval.native_crypto - -import java.lang.Exception - -class PlatformVersionException(message : String) : Exception(message) \ No newline at end of file diff --git a/assets/benchmark_pointycastle.png b/assets/benchmark_pointycastle.png deleted file mode 100644 index 0f35735..0000000 Binary files a/assets/benchmark_pointycastle.png and /dev/null differ diff --git a/assets/native_crypto.png b/assets/native_crypto.png deleted file mode 100644 index e3fdadf..0000000 Binary files a/assets/native_crypto.png and /dev/null differ diff --git a/example/android/.gitignore b/example/android/.gitignore deleted file mode 100644 index bc2100d..0000000 --- a/example/android/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -gradle-wrapper.jar -/.gradle -/captures/ -/gradlew -/gradlew.bat -/local.properties -GeneratedPluginRegistrant.java diff --git a/example/android/app/src/main/kotlin/fr/pointcheval/native_crypto_example/MainActivity.kt b/example/android/app/src/main/kotlin/fr/pointcheval/native_crypto_example/MainActivity.kt deleted file mode 100644 index 09d279f..0000000 --- a/example/android/app/src/main/kotlin/fr/pointcheval/native_crypto_example/MainActivity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package fr.pointcheval.native_crypto_example - -import androidx.annotation.NonNull; -import io.flutter.embedding.android.FlutterActivity -import io.flutter.embedding.engine.FlutterEngine -import io.flutter.plugins.GeneratedPluginRegistrant - -class MainActivity: FlutterActivity() { - override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { - GeneratedPluginRegistrant.registerWith(flutterEngine); - } -} diff --git a/example/android/app/src/main/res/values/styles.xml b/example/android/app/src/main/res/values/styles.xml deleted file mode 100644 index 00fa441..0000000 --- a/example/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/example/android/gradle.properties b/example/android/gradle.properties deleted file mode 100644 index 38c8d45..0000000 --- a/example/android/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.enableR8=true -android.useAndroidX=true -android.enableJetifier=true diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index dab3e5b..0000000 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Dec 18 22:37:36 CET 2020 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip diff --git a/example/android/settings.gradle b/example/android/settings.gradle deleted file mode 100644 index 5a2f14f..0000000 --- a/example/android/settings.gradle +++ /dev/null @@ -1,15 +0,0 @@ -include ':app' - -def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() - -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } -} - -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory -} diff --git a/example/ios/Flutter/.last_build_id b/example/ios/Flutter/.last_build_id deleted file mode 100644 index 8f1ef8b..0000000 --- a/example/ios/Flutter/.last_build_id +++ /dev/null @@ -1 +0,0 @@ -a1d04c54a9dc0dec55298921eadf7972 \ No newline at end of file diff --git a/example/ios/Podfile b/example/ios/Podfile deleted file mode 100644 index b30a428..0000000 --- a/example/ios/Podfile +++ /dev/null @@ -1,90 +0,0 @@ -# Uncomment this line to define a global platform for your project -# platform :ios, '9.0' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def parse_KV_file(file, separator='=') - file_abs_path = File.expand_path(file) - if !File.exists? file_abs_path - return []; - end - generated_key_values = {} - skip_line_start_symbols = ["#", "/"] - File.foreach(file_abs_path) do |line| - next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } - plugin = line.split(pattern=separator) - if plugin.length == 2 - podname = plugin[0].strip() - path = plugin[1].strip() - podpath = File.expand_path("#{path}", file_abs_path) - generated_key_values[podname] = podpath - else - puts "Invalid plugin specification: #{line}" - end - end - generated_key_values -end - -target 'Runner' do - use_frameworks! - use_modular_headers! - - # Flutter Pod - - copied_flutter_dir = File.join(__dir__, 'Flutter') - copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') - copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') - unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) - # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. - # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. - # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. - - generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') - unless File.exist?(generated_xcode_build_settings_path) - raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" - end - generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) - cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; - - unless File.exist?(copied_framework_path) - FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) - end - unless File.exist?(copied_podspec_path) - FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) - end - end - - # Keep pod path relative so it can be checked into Podfile.lock. - pod 'Flutter', :path => 'Flutter' - - # Plugin Pods - - # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock - # referring to absolute paths on developers' machines. - system('rm -rf .symlinks') - system('mkdir -p .symlinks/plugins') - plugin_pods = parse_KV_file('../.flutter-plugins') - plugin_pods.each do |name, path| - symlink = File.join('.symlinks', 'plugins', name) - File.symlink(path, symlink) - pod name, :path => File.join(symlink, 'ios') - end -end - -# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. -install! 'cocoapods', :disable_input_output_paths => true - -post_install do |installer| - installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['ENABLE_BITCODE'] = 'NO' - end - end -end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock deleted file mode 100644 index 2d6d76f..0000000 --- a/example/ios/Podfile.lock +++ /dev/null @@ -1,22 +0,0 @@ -PODS: - - Flutter (1.0.0) - - native_crypto (0.0.1): - - Flutter - -DEPENDENCIES: - - Flutter (from `Flutter`) - - native_crypto (from `.symlinks/plugins/native_crypto/ios`) - -EXTERNAL SOURCES: - Flutter: - :path: Flutter - native_crypto: - :path: ".symlinks/plugins/native_crypto/ios" - -SPEC CHECKSUMS: - Flutter: 0e3d915762c693b495b44d77113d4970485de6ec - native_crypto: 33b8108e3fcc10052862b69863efc2304c59cb2f - -PODFILE CHECKSUM: 1b66dae606f75376c5f2135a8290850eeb09ae83 - -COCOAPODS: 1.10.1 diff --git a/example/ios/Runner/Runner-Bridging-Header.h b/example/ios/Runner/Runner-Bridging-Header.h deleted file mode 100644 index 7335fdf..0000000 --- a/example/ios/Runner/Runner-Bridging-Header.h +++ /dev/null @@ -1 +0,0 @@ -#import "GeneratedPluginRegistrant.h" \ No newline at end of file diff --git a/example/lib/main.dart b/example/lib/main.dart deleted file mode 100644 index 0cca731..0000000 --- a/example/lib/main.dart +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2020 -// Author: Hugo Pointcheval -import 'package:flutter/material.dart'; -import 'package:native_crypto_example/pages/kemPage.dart'; - -import 'pages/benchmarkPage.dart'; -import 'pages/cipherPage.dart'; -import 'pages/hashKeyDerivationPage.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatefulWidget { - @override - _MyAppState createState() => _MyAppState(); -} - -class _MyAppState extends State { - int _currentIndex = 0; - final List _children = [ - HashKeyDerivationPage(), - CipherPage(), - KemPage(), - BenchmarkPage(), - ]; - - void onTabTapped(int index) { - setState(() { - _currentIndex = index; - }); - } - - @override - Widget build(BuildContext context) { - return MaterialApp( - home: Scaffold( - appBar: AppBar( - centerTitle: true, - title: const Text('Native Crypto'), - ), - body: _children[_currentIndex], - bottomNavigationBar: BottomNavigationBar( - selectedItemColor: Colors.blue, - unselectedItemColor: Colors.black, - showUnselectedLabels: true, - onTap: onTabTapped, // new - currentIndex: _currentIndex, // new - items: [ - BottomNavigationBarItem( - icon: Icon(Icons.vpn_key), - label: 'Key', - ), - BottomNavigationBarItem( - icon: Icon(Icons.lock), - label: 'Encryption', - ), - BottomNavigationBarItem( - icon: Icon(Icons.connect_without_contact), - label: 'KEM', - ), - BottomNavigationBarItem( - icon: Icon(Icons.timer), - label: 'Benchmark', - ), - ], - ), - ), - ); - } -} diff --git a/example/lib/pages/benchmarkPage.dart b/example/lib/pages/benchmarkPage.dart deleted file mode 100644 index 52024c7..0000000 --- a/example/lib/pages/benchmarkPage.dart +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2021 -// Author: Hugo Pointcheval -import 'dart:developer'; -import 'dart:typed_data'; - -import 'package:flutter/material.dart'; -import 'package:native_crypto/native_crypto.dart'; - -import '../session.dart'; -import '../widgets/button.dart'; -import '../widgets/output.dart'; - -class BenchmarkPage extends StatefulWidget { - const BenchmarkPage({key}) : super(key: key); - - @override - _BenchmarkPageState createState() => _BenchmarkPageState(); -} - -class _BenchmarkPageState extends State { - final Output keyContent = Output( - textEditingController: TextEditingController(), - ); - final Output benchmarkStatus = Output( - textEditingController: TextEditingController(), - large: true, - ); - - Future _benchmark() async { - if (Session.secretKey == null || Session.secretKey.isEmpty) { - benchmarkStatus - .print('No SecretKey!\nGo in Key tab and generate or derive one.'); - return; - } else if (!Session.aesCipher.isInitialized) { - benchmarkStatus.print( - 'Cipher not initialized!\nGo in Key tab and generate or derive one.'); - return; - } - - benchmarkStatus.print("Benchmark 2/4/8/16/32/64/128/256MB\n"); - List testedSizes = [2, 4, 8, 16, 32, 64, 128, 256]; - String csv = - "size;encryption time;encode time;decryption time;crypto time\n"; - - var beforeBench = DateTime.now(); - for (int size in testedSizes) { - var bigFile = Uint8List(size * 1000000); - csv += "${size * 1000000};"; - var cryptoTime = 0; - - // Encryption - var before = DateTime.now(); - var encryptedBigFile = await Session.aesCipher.encrypt(bigFile); - var after = DateTime.now(); - - var benchmark = - after.millisecondsSinceEpoch - before.millisecondsSinceEpoch; - benchmarkStatus.append('[$size MB] Encryption took $benchmark ms\n'); - - csv += "$benchmark;"; - cryptoTime += benchmark; - - // Encoding - before = DateTime.now(); - encryptedBigFile.encode(); - after = DateTime.now(); - - benchmark = after.millisecondsSinceEpoch - before.millisecondsSinceEpoch; - benchmarkStatus.append('[$size MB] Encoding took $benchmark ms\n'); - - csv += "$benchmark;"; - - // Decryption - before = DateTime.now(); - await Session.aesCipher.decrypt(encryptedBigFile); - after = DateTime.now(); - - benchmark = after.millisecondsSinceEpoch - before.millisecondsSinceEpoch; - benchmarkStatus.append('[$size MB] Decryption took $benchmark ms\n'); - - csv += "$benchmark;"; - cryptoTime += benchmark; - csv += "$cryptoTime\n"; - } - var afterBench = DateTime.now(); - var benchmark = - afterBench.millisecondsSinceEpoch - beforeBench.millisecondsSinceEpoch; - var sum = testedSizes.reduce((a, b) => a + b); - benchmarkStatus.append( - 'Benchmark finished.\nGenerated, encrypted and decrypted $sum MB in $benchmark ms'); - log(csv, name: "Benchmark"); - } - - void _clear() { - benchmarkStatus.clear(); - } - - @override - void initState() { - super.initState(); - if (Session.secretKey != null) { - keyContent.print(Session.secretKey.encoded.toString()); - Session.aesCipher = AESCipher( - Session.secretKey, - CipherParameters( - BlockCipherMode.CBC, - PlainTextPadding.PKCS5, - ), - ); - } - } - - @override - Widget build(BuildContext context) { - return SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - Align( - child: Text("Secret Key"), - alignment: Alignment.centerLeft, - ), - keyContent, - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Button( - onPressed: _benchmark, - label: "Launch benchmark", - ), - Button( - onPressed: _clear, - label: "Clear", - ), - ], - ), - benchmarkStatus, - ], - ), - ), - ); - } -} diff --git a/example/lib/pages/cipherPage.dart b/example/lib/pages/cipherPage.dart deleted file mode 100644 index 2813831..0000000 --- a/example/lib/pages/cipherPage.dart +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright (c) 2021 -// Author: Hugo Pointcheval -import 'dart:typed_data'; - -import 'package:flutter/material.dart'; -import 'package:native_crypto/native_crypto.dart'; - -import '../session.dart'; -import '../utils.dart'; -import '../widgets/button.dart'; -import '../widgets/output.dart'; - -class CipherPage extends StatefulWidget { - const CipherPage({key}) : super(key: key); - - @override - _CipherPageState createState() => _CipherPageState(); -} - -class _CipherPageState extends State { - final Output keyContent = Output( - textEditingController: TextEditingController(), - ); - final Output encryptionStatus = Output( - textEditingController: TextEditingController(), - ); - final Output decryptionStatus = Output( - textEditingController: TextEditingController(), - ); - final Output cipherExport = Output( - textEditingController: TextEditingController(), - large: true, - editable: true, - ); - - final TextEditingController _plainTextController = TextEditingController(); - CipherText cipherText; - - void _encrypt() async { - final plainText = _plainTextController.text.trim(); - - if (Session.secretKey == null || Session.secretKey.isEmpty) { - encryptionStatus - .print('No SecretKey!\nGo in Key tab and generate or derive one.'); - } else if (!Session.aesCipher.isInitialized) { - encryptionStatus.print( - 'Cipher not initialized!\nGo in Key tab and generate or derive one.'); - } else if (plainText.isEmpty) { - encryptionStatus.print('Entry is empty'); - } else { - var stringToBytes = TypeHelper.stringToBytes(plainText); - cipherText = await Session.aesCipher.encrypt(stringToBytes); - encryptionStatus.print('String successfully encrypted.\n'); - encryptionStatus.append("IV: " + - cipherText.iv.toString() + - "\nCipherText: " + - cipherText.bytes.toString()); - } - } - - void _alter() async { - if (cipherText == null || cipherText.bytes.isEmpty) { - decryptionStatus.print('Encrypt before altering CipherText!'); - } else { - // Add 1 to the first byte - List _altered = cipherText.bytes; - _altered[0][0] += 1; - // Recreate cipher text with altered data - cipherText = AESCipherText.from(_altered, cipherText.iv); - encryptionStatus.print('String successfully encrypted.\n'); - encryptionStatus.append("IV: " + - cipherText.iv.toString() + - "\nCipherText: " + - cipherText.bytes.toString()); - decryptionStatus.print('CipherText altered!\nDecryption will fail.'); - } - } - - void _decrypt() async { - if (Session.secretKey == null || Session.secretKey.isEmpty) { - decryptionStatus - .print('No SecretKey!\nGo in Key tab and generate or derive one.'); - } else if (!Session.aesCipher.isInitialized) { - decryptionStatus.print( - 'Cipher not initialized!\nGo in Key tab and generate or derive one.'); - } else if (cipherText == null || cipherText.bytes.isEmpty) { - decryptionStatus.print('Encrypt before decrypting!'); - } else { - try { - Uint8List plainText = await Session.aesCipher.decrypt(cipherText); - var bytesToString = TypeHelper.bytesToString(plainText); - decryptionStatus - .print('String successfully decrypted:\n\n$bytesToString'); - } on DecryptionException catch (e) { - decryptionStatus.print(e.message); - } - } - } - - void _export() async { - if (cipherText == null) { - decryptionStatus.print('Encrypt data before export!'); - } else { - // TODO: fix export format to support chunks ! - Uint8List payload = cipherText.encode(); - String data = TypeHelper.bytesToBase64(payload); - decryptionStatus.print('CipherText successfully exported'); - cipherExport.print(data); - } - } - - void _import() async { - final String data = cipherExport.read(); - if (data.isEmpty) { - encryptionStatus.print('CipherText import failed'); - } else { - Uint8List payload = TypeHelper.base64ToBytes(data); - cipherText = AESCipherText.empty(); - cipherText.decode(payload); - encryptionStatus.print('CipherText successfully imported\n'); - encryptionStatus.append("IV: " + - cipherText.iv.toString() + - "\nCipherText: " + - cipherText.bytes.toString()); - } - } - - @override - void initState() { - super.initState(); - if (Session.secretKey != null) { - keyContent.print(Session.secretKey.encoded.toString()); - Session.aesCipher = AESCipher( - Session.secretKey, - CipherParameters( - BlockCipherMode.CBC, - PlainTextPadding.PKCS5, - ), - ); - } - } - - @override - void dispose() { - super.dispose(); - _plainTextController.dispose(); - } - - @override - Widget build(BuildContext context) { - return SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - Align( - child: Text("Secret Key"), - alignment: Alignment.centerLeft, - ), - keyContent, - TextField( - controller: _plainTextController, - decoration: InputDecoration( - hintText: 'Plain text', - ), - ), - Button( - onPressed: _encrypt, - label: "Encrypt", - ), - encryptionStatus, - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Button( - onPressed: _alter, - label: "Alter cipher", - ), - Button( - onPressed: _decrypt, - label: "Decrypt", - ), - ], - ), - decryptionStatus, - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Button( - onPressed: _export, - label: "Export cipher", - ), - Button( - onPressed: _import, - label: "Import cipher", - ), - ], - ), - cipherExport - ], - ), - ), - ); - } -} diff --git a/example/lib/pages/hashKeyDerivationPage.dart b/example/lib/pages/hashKeyDerivationPage.dart deleted file mode 100644 index 5219dc0..0000000 --- a/example/lib/pages/hashKeyDerivationPage.dart +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) 2020 -// Author: Hugo Pointcheval -import 'dart:typed_data'; - -import 'package:flutter/material.dart'; -import 'package:native_crypto/native_crypto.dart'; - -import '../session.dart'; -import '../utils.dart'; -import '../widgets/button.dart'; -import '../widgets/output.dart'; - -class HashKeyDerivationPage extends StatefulWidget { - const HashKeyDerivationPage({key}) : super(key: key); - - @override - _HashKeyDerivationPageState createState() => _HashKeyDerivationPageState(); -} - -class _HashKeyDerivationPageState extends State { - final Output keyContent = Output( - textEditingController: TextEditingController(), - ); - final Output keyStatus = Output( - textEditingController: TextEditingController(), - ); - final Output keyExport = Output( - textEditingController: TextEditingController(), - large: true, - editable: true, - ); - final Output pbkdf2Status = Output( - textEditingController: TextEditingController(), - ); - final Output hashStatus = Output( - textEditingController: TextEditingController(), - ); - - final TextEditingController _pwdTextController = TextEditingController(); - final TextEditingController _messageTextController = TextEditingController(); - final TextEditingController _keyTextController = TextEditingController(); - - void _generate() async { - try { - Session.secretKey = await SecretKey.generate(256, CipherAlgorithm.AES); - keyContent.print(Session.secretKey.encoded.toString()); - keyStatus.print( - "Secret Key successfully generated.\nLength: ${Session.secretKey.encoded.length} bytes"); - } catch (e) { - keyStatus.print(e.message); - } - } - - void _pbkdf2() async { - final password = _pwdTextController.text.trim(); - - if (password.isEmpty) { - pbkdf2Status.print('Password is empty'); - } else { - PBKDF2 _pbkdf2 = - PBKDF2(keyLength: 32, iteration: 1000, hash: HashAlgorithm.SHA512); - await _pbkdf2.derive(password: password, salt: 'salty'); - SecretKey key = _pbkdf2.key; - pbkdf2Status.print('Key successfully derived.'); - Session.secretKey = key; - keyContent.print(Session.secretKey.encoded.toString()); - } - } - - void _export() async { - if (Session.secretKey == null || Session.secretKey.isEmpty) { - keyStatus - .print('No SecretKey!\nGenerate or derive one before exporting!'); - } else { - String key = TypeHelper.bytesToBase64(Session.secretKey.encoded); - keyStatus.print('Key successfully exported'); - keyExport.print(key); - } - } - - void _import() async { - final String key = keyExport.read(); - if (key.isEmpty) { - keyStatus.print('Key import failed'); - } else { - Uint8List keyBytes = TypeHelper.base64ToBytes(key); - Session.secretKey = - SecretKey.fromBytes(keyBytes, algorithm: CipherAlgorithm.AES); - keyStatus.print('Key successfully imported'); - keyContent.print(Session.secretKey.encoded.toString()); - } - } - - void _hash() async { - final message = _messageTextController.text.trim(); - - if (message.isEmpty) { - hashStatus.print('Message is empty'); - } else { - MessageDigest md = MessageDigest.getInstance("sha256"); - Uint8List hash = await md.digest(TypeHelper.stringToBytes(message)); - hashStatus.print('Message successfully hashed.\n' + hash.toString()); - } - } - - @override - void initState() { - super.initState(); - if (Session.secretKey != null) { - keyContent.print(Session.secretKey.encoded.toString()); - } - } - - @override - void dispose() { - super.dispose(); - _pwdTextController.dispose(); - _messageTextController.dispose(); - _keyTextController.dispose(); - } - - @override - Widget build(BuildContext context) { - return SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - Align( - child: Text("Secret Key"), - alignment: Alignment.centerLeft, - ), - keyContent, - Button( - onPressed: _generate, - label: "Generate key", - ), - keyStatus, - TextField( - controller: _pwdTextController, - decoration: InputDecoration( - hintText: 'Password', - ), - ), - Button( - onPressed: _pbkdf2, - label: "Apply PBKDF2", - ), - pbkdf2Status, - TextField( - controller: _messageTextController, - decoration: InputDecoration( - hintText: 'Message', - ), - ), - Button( - onPressed: _hash, - label: "Hash", - ), - hashStatus, - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Button( - onPressed: _export, - label: "Export key", - ), - Button( - onPressed: _import, - label: "Import key", - ), - ], - ), - keyExport - ], - ), - ), - ); - } -} diff --git a/example/lib/pages/kemPage.dart b/example/lib/pages/kemPage.dart deleted file mode 100644 index 30e2fc6..0000000 --- a/example/lib/pages/kemPage.dart +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2020 -// Author: Hugo Pointcheval -import 'package:flutter/material.dart'; -import 'package:native_crypto/native_crypto.dart'; - -class KemPage extends StatefulWidget { - KemPage({key}) : super(key: key); - - @override - _KemPageState createState() => _KemPageState(); -} - -class _KemPageState extends State { - void test() async { - KeySpec specs = RSAKeySpec(2048); - KeyPair kp = await KeyPair.generate(specs); - print(kp.isComplete); - print(kp.privateKey); - print(kp.privateKey.encoded); - } - - @override - void initState() { - super.initState(); - test(); - } - - @override - Widget build(BuildContext context) { - return Container( - child: Center( - child: Text("Not implemented."), - ), - ); - } -} diff --git a/example/lib/session.dart b/example/lib/session.dart deleted file mode 100644 index 4f68f87..0000000 --- a/example/lib/session.dart +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2020 -// Author: Hugo Pointcheval - -import 'package:native_crypto/native_crypto.dart'; - -class Session { - static SecretKey secretKey; - static AESCipher aesCipher; -} diff --git a/example/lib/utils.dart b/example/lib/utils.dart deleted file mode 100644 index 3f03f32..0000000 --- a/example/lib/utils.dart +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2020 -// Author: Hugo Pointcheval -import 'dart:typed_data'; -import 'dart:convert'; - -/// Contains some useful functions. -class TypeHelper { - /// Returns bytes [Uint8List] from a [String]. - static Uint8List stringToBytes(String source) { - var list = source.runes.toList(); - var bytes = Uint8List.fromList(list); - return bytes; - } - - /// Returns a [String] from bytes [Uint8List]. - static String bytesToString(Uint8List bytes) { - var string = String.fromCharCodes(bytes); - return string; - } - - /// Returns a `base64` [String] from bytes [Uint8List]. - static String bytesToBase64(Uint8List bytes) { - return base64.encode(bytes); - } - - /// Returns a [Uint8List] from a `base64` [String]. - static Uint8List base64ToBytes(String encoded) { - return base64.decode(encoded); - } -} diff --git a/example/lib/widgets/button.dart b/example/lib/widgets/button.dart deleted file mode 100644 index 27c6db7..0000000 --- a/example/lib/widgets/button.dart +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2020 -// Author: Hugo Pointcheval -import 'package:flutter/material.dart'; - -class Button extends StatelessWidget { - const Button({Key key, this.onPressed, this.label}) : super(key: key); - - final void Function() onPressed; - final String label; - - @override - Widget build(BuildContext context) { - return Container( - child: FlatButton( - onPressed: onPressed, - color: Colors.blue, - child: Text( - label, - style: TextStyle(color: Colors.white), - ), - ), - ); - } -} diff --git a/example/lib/widgets/output.dart b/example/lib/widgets/output.dart deleted file mode 100644 index 45bdccb..0000000 --- a/example/lib/widgets/output.dart +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2020 -// Author: Hugo Pointcheval -import 'dart:developer'; - -import 'package:flutter/material.dart'; - -class Output extends StatelessWidget { - const Output( - {Key key, - this.textEditingController, - this.large: false, - this.editable: false}) - : super(key: key); - - final TextEditingController textEditingController; - final bool large; - final bool editable; - - void print(String message) { - log(message, name: "NativeCrypto Example"); - textEditingController.text = message; - } - - void append(String message) { - log(message, name: "NativeCrypto Example"); - textEditingController.text += message; - } - - void appendln(String message) { - log(message, name: "NativeCrypto Example"); - textEditingController.text += message + "\n"; - } - - void clear() { - textEditingController.clear(); - } - - String read() { - return textEditingController.text; - } - - @override - Widget build(BuildContext context) { - return Container( - child: TextField( - enableInteractiveSelection: true, - readOnly: editable ? false : true, - minLines: large ? 3 : 1, - maxLines: large ? 500 : 5, - decoration: InputDecoration(border: OutlineInputBorder()), - controller: textEditingController, - ), - ); - } -} diff --git a/ios/Classes/Cipher.swift b/ios/Classes/Cipher.swift deleted file mode 100644 index 5d92895..0000000 --- a/ios/Classes/Cipher.swift +++ /dev/null @@ -1,135 +0,0 @@ -// -// Cipher.swift -// -// NativeCryptoPlugin -// -// Copyright (c) 2020 -// Author: Hugo Pointcheval -// - -import Foundation -import CommonCrypto - -enum CipherAlgorithm: String { - case AES = "aes" - case BlowFish = "blowfish" - - var instance: Int { - switch self { - case .AES: return kCCAlgorithmAES - case .BlowFish: return kCCAlgorithmBlowfish - } - } -} - -enum BlockCipherMode: String { - case ECB = "ecb" - case CBC = "cbc" - - var instance: Int { - switch self { - case .CBC: return 0 - case .ECB: return kCCOptionECBMode - } - } -} - -enum Padding: String { - case PKCS5 = "pkcs5" - case None = "none" - - var instance: Int { - switch self { - case .PKCS5: return kCCOptionPKCS7Padding - case .None: return 0 - } - } -} - -class Cipher { - func encrypt(data : Data, key : Data, algorithm : CipherAlgorithm, mode : BlockCipherMode, padding : Padding) -> [Data]? { - // Calculate Mac - let mac = Hash().digest(data: key + data, algorithm: .SHA256) - let payload = mac! + data - - // Generate IV - let ivBytes = UnsafeMutableRawPointer.allocate(byteCount: kCCBlockSizeAES128, alignment: 1) - defer { ivBytes.deallocate() } - let ivStatus = CCRandomGenerateBytes(ivBytes, kCCBlockSizeAES128) - if (ivStatus != kCCSuccess) { - return nil - } - let ivData = Data(bytes: ivBytes, count: kCCBlockSizeAES128) - - let algo = algorithm.instance - let options: CCOptions = UInt32(mode.instance + padding.instance) - - - guard var ciphertext = crypt(operation: kCCEncrypt, - algorithm: algo, - options: options, - key: key, - initializationVector: ivData, - dataIn: payload) else { return nil } - - return [ciphertext, ivData] - } - - func decrypt(payload : [Data], key : Data, algorithm : CipherAlgorithm, mode : BlockCipherMode, padding : Padding) -> Data? { - let encrypted = payload[1] + payload[0] - - guard encrypted.count > kCCBlockSizeAES128 else { return nil } - let iv = encrypted.prefix(kCCBlockSizeAES128) - let ciphertext = encrypted.suffix(from: kCCBlockSizeAES128) - - let algo = algorithm.instance - let options: CCOptions = UInt32(mode.instance + padding.instance) - - guard var decrypted = crypt(operation: kCCDecrypt, - algorithm: algo, - options: options, - key: key, - initializationVector: iv, - dataIn: ciphertext) else {return nil} - - - // Create a range based on the length of data to return - let range = 0..<32 - - // Get a new copy of data - let mac = decrypted.subdata(in: range) - decrypted.removeSubrange(range) - - let vmac = Hash().digest(data: key + decrypted, algorithm: .SHA256) - - if (mac.base64EncodedData() == vmac!.base64EncodedData()) { - return decrypted - } else { - return nil - } - } - - private func crypt(operation: Int, algorithm: Int, options: UInt32, key: Data, - initializationVector: Data, dataIn: Data) -> Data? { - - return key.withUnsafeBytes { keyUnsafeRawBufferPointer in - return dataIn.withUnsafeBytes { dataInUnsafeRawBufferPointer in - return initializationVector.withUnsafeBytes { ivUnsafeRawBufferPointer in - let dataOutSize: Int = dataIn.count + kCCBlockSizeAES128*2 - let dataOut = UnsafeMutableRawPointer.allocate(byteCount: dataOutSize, - alignment: 1) - defer { dataOut.deallocate() } - var dataOutMoved: Int = 0 - let status = CCCrypt(CCOperation(operation), CCAlgorithm(algorithm), - CCOptions(options), - keyUnsafeRawBufferPointer.baseAddress, key.count, - ivUnsafeRawBufferPointer.baseAddress, - dataInUnsafeRawBufferPointer.baseAddress, dataIn.count, - dataOut, dataOutSize, &dataOutMoved) - guard status == kCCSuccess else { return nil } - return Data(bytes: dataOut, count: dataOutMoved) - } - } - } - } -} diff --git a/ios/Classes/Hash.swift b/ios/Classes/Hash.swift deleted file mode 100644 index 430e2a7..0000000 --- a/ios/Classes/Hash.swift +++ /dev/null @@ -1,74 +0,0 @@ -// -// Hash.swift -// -// NativeCryptoPlugin -// -// Copyright (c) 2020 -// Author: Hugo Pointcheval -// -import Foundation -import CommonCrypto - -enum HashAlgorithm: String { - case SHA1 = "sha1" - case SHA224 = "sha224" - case SHA256 = "sha256" - case SHA384 = "sha384" - case SHA512 = "sha512" - - var digestLength: Int { - switch self { - case .SHA1: return Int(CC_SHA1_DIGEST_LENGTH) - case .SHA224: return Int(CC_SHA224_DIGEST_LENGTH) - case .SHA256: return Int(CC_SHA256_DIGEST_LENGTH) - case .SHA384: return Int(CC_SHA384_DIGEST_LENGTH) - case .SHA512: return Int(CC_SHA512_DIGEST_LENGTH) - } - } - - var pbkdf2: UInt32 { - switch self { - case .SHA1: return CCPBKDFAlgorithm(kCCPRFHmacAlgSHA1) - case .SHA224: return CCPBKDFAlgorithm(kCCPRFHmacAlgSHA224) - case .SHA256: return CCPBKDFAlgorithm(kCCPRFHmacAlgSHA256) - case .SHA384: return CCPBKDFAlgorithm(kCCPRFHmacAlgSHA384) - case .SHA512: return CCPBKDFAlgorithm(kCCPRFHmacAlgSHA512) - } - } -} - -class Hash { - func digest(data: Data?, algorithm: HashAlgorithm) -> Data? { - if (data == nil) { - return nil - } - - let hashBytes = UnsafeMutablePointer.allocate(capacity: algorithm.digestLength) - defer { hashBytes.deallocate() } - - switch algorithm { - case .SHA1: - data!.withUnsafeBytes { (buffer) -> Void in - CC_SHA1(buffer.baseAddress!, CC_LONG(buffer.count), hashBytes) - } - case .SHA224: - data!.withUnsafeBytes { (buffer) -> Void in - CC_SHA224(buffer.baseAddress!, CC_LONG(buffer.count), hashBytes) - } - case .SHA256: - data!.withUnsafeBytes { (buffer) -> Void in - CC_SHA256(buffer.baseAddress!, CC_LONG(buffer.count), hashBytes) - } - case .SHA384: - data!.withUnsafeBytes { (buffer) -> Void in - CC_SHA384(buffer.baseAddress!, CC_LONG(buffer.count), hashBytes) - } - case .SHA512: - data!.withUnsafeBytes { (buffer) -> Void in - CC_SHA512(buffer.baseAddress!, CC_LONG(buffer.count), hashBytes) - } - } - - return Data(bytes: hashBytes, count: algorithm.digestLength) - } -} diff --git a/ios/Classes/KeyDerivation.swift b/ios/Classes/KeyDerivation.swift deleted file mode 100644 index b1a5954..0000000 --- a/ios/Classes/KeyDerivation.swift +++ /dev/null @@ -1,40 +0,0 @@ -// -// KeyDerivation.swift -// -// NativeCryptoPlugin -// -// Copyright (c) 2020 -// Author: Hugo Pointcheval -// - -import Foundation -import CommonCrypto - -class KeyDerivation { - func pbkdf2(password: String, salt: String, keyLength: Int, iteration: Int, algorithm: HashAlgorithm) -> Data? { - - let passwordData = password.data(using: .utf8)! - let saltData = salt.data(using: .utf8)! - - var derivedKeyData = Data(repeating: 0, count: keyLength) - var localDerivedKeyData = derivedKeyData - - let derivationStatus = derivedKeyData.withUnsafeMutableBytes { derivedKeyBytes in - saltData.withUnsafeBytes { saltBytes in - CCKeyDerivationPBKDF( - CCPBKDFAlgorithm(kCCPBKDF2), - password, passwordData.count, - saltBytes, saltData.count, - algorithm.pbkdf2, - UInt32(iteration), - derivedKeyBytes, localDerivedKeyData.count) - } - } - if (derivationStatus != kCCSuccess) { - print("Error: \(derivationStatus)") - return nil; - } - - return derivedKeyData - } -} diff --git a/ios/Classes/KeyGeneration.swift b/ios/Classes/KeyGeneration.swift deleted file mode 100644 index 76e0325..0000000 --- a/ios/Classes/KeyGeneration.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// KeyGeneration.swift -// -// NativeCryptoPlugin -// -// Copyright (c) 2020 -// Author: Hugo Pointcheval -// -import Foundation -import CommonCrypto - -class KeyGeneration { - func keygen(size : NSNumber) -> Data? { - var bytes = [Int8](repeating: 0, count: size.intValue / 8) - let status = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes) - - if status == errSecSuccess { - let keyBytes = bytes.withUnsafeBytes { - return Data(Array($0)) - - } - return keyBytes - } - return nil - } - - @available(iOS 10.0, watchOS 3.0, tvOS 10.0, *) - func rsaKeypairGen(size : NSNumber) throws -> [Data]? { - - let tagData = UUID().uuidString.data(using: .utf8) - - let isPermanent = true - - let attributes: [CFString: Any] = [ - kSecAttrKeyType: kSecAttrKeyTypeRSA, - kSecAttrKeySizeInBits: (size.intValue * 8), - kSecPrivateKeyAttrs: [ - kSecAttrIsPermanent: isPermanent, - kSecAttrApplicationTag: tagData! - ] - ] - - var error: Unmanaged? - guard let privKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else { - throw error!.takeRetainedValue() as Error - } - let pubKey = SecKeyCopyPublicKey(privKey) - - - var errorExport: Unmanaged? - let data1 = SecKeyCopyExternalRepresentation(pubKey!, &errorExport) - let unwrappedData1 = data1 as Data? - - let data2 = SecKeyCopyExternalRepresentation(privKey, &errorExport) - let unwrappedData2 = data2 as Data? - - return [unwrappedData1!, unwrappedData2!] - } -} diff --git a/ios/Classes/NativeCryptoPlugin.h b/ios/Classes/NativeCryptoPlugin.h deleted file mode 100644 index 0f584e1..0000000 --- a/ios/Classes/NativeCryptoPlugin.h +++ /dev/null @@ -1,4 +0,0 @@ -#import - -@interface NativeCryptoPlugin : NSObject -@end diff --git a/ios/Classes/SwiftNativeCryptoPlugin.swift b/ios/Classes/SwiftNativeCryptoPlugin.swift deleted file mode 100644 index f33cb88..0000000 --- a/ios/Classes/SwiftNativeCryptoPlugin.swift +++ /dev/null @@ -1,158 +0,0 @@ -// -// NativeCryptoPlugin -// -// Copyright (c) 2020 -// Author: Hugo Pointcheval -// -import Flutter - -extension FlutterStandardTypedData { - var uint8Array: Array { - return Array(data) - } - var int8Array: Array { - return data.withUnsafeBytes { raw in - [Int8](raw.bindMemory(to: Int8.self)) - } - } -} - -public class SwiftNativeCryptoPlugin: NSObject, FlutterPlugin { - public static func register(with registrar: FlutterPluginRegistrar) { - let channel = FlutterMethodChannel(name: "native.crypto", binaryMessenger: registrar.messenger()) - let instance = SwiftNativeCryptoPlugin() - registrar.addMethodCallDelegate(instance, channel: channel) - } - - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - switch call.method { - case "digest": - let args = call.arguments as! NSDictionary - - let message = (args["message"] as! FlutterStandardTypedData).data - let algo = args["algorithm"] as! String - - let algorithm : HashAlgorithm? = HashAlgorithm.init(rawValue: algo) - - let hash = Hash().digest(data: message, algorithm: algorithm!) - - if hash != nil { - result(FlutterStandardTypedData.init(bytes: hash!)) - } else { - result(FlutterError(code: "DIGESTERROR", - message: "DIGEST IS NIL.", - details: nil) - ) - } - case "pbkdf2": - let args = call.arguments as! NSDictionary - - let password = args["password"] as! String - let salt = args["salt"] as! String - let keyLength = args["keyLength"] as! NSNumber - let iteration = args["iteration"] as! NSNumber - let algo = args["algorithm"] as! String - - let algorithm : HashAlgorithm? = HashAlgorithm.init(rawValue: algo) - - let key = KeyDerivation().pbkdf2(password: password, salt: salt, keyLength: keyLength.intValue, iteration: iteration.intValue, algorithm: algorithm!) - - if key != nil { - result(FlutterStandardTypedData.init(bytes: key!)) - } else { - result(FlutterError(code: "PBKDF2ERROR", - message: "PBKDF2 KEY IS NIL.", - details: nil) - ) - } - case "keygen": - let args = call.arguments as! NSDictionary - - let size = args["size"] as! NSNumber - - let key = KeyGeneration().keygen(size: size) - - if key != nil { - result(FlutterStandardTypedData.init(bytes: key!)) - } else { - result(FlutterError(code: "KEYGENERROR", - message: "GENERATED KEY IS NIL.", - details: nil)) - } - case "rsaKeypairGen": - let args = call.arguments as! NSDictionary - - let size = args["size"] as! NSNumber - - let keypair : [Data]? - - if #available(iOS 10.0, *) { - do { - keypair = try KeyGeneration().rsaKeypairGen(size: size) - } catch { - keypair = nil - } - } else { - // Fallback on earlier versions - keypair = nil - } - - if keypair != nil { - result(keypair) - } else { - result(FlutterError(code: "KEYPAIRGENERROR", - message: "GENERATED KEYPAIR IS EMPTY.", - details: nil)) - } - case "encrypt": - let args = call.arguments as! NSDictionary - - let data = (args["data"] as! FlutterStandardTypedData).data - let key = (args["key"] as! FlutterStandardTypedData).data - let algo = args["algorithm"] as! String - let mode = args["mode"] as! String - let padding = args["padding"] as! String - - let algorithm : CipherAlgorithm? = CipherAlgorithm.init(rawValue: algo) - let modeEnum : BlockCipherMode? = BlockCipherMode.init(rawValue: mode) - let paddingEnum : Padding? = Padding.init(rawValue: padding) - - let ciphertext = Cipher().encrypt(data: data, key: key, algorithm: algorithm!, mode: modeEnum!, padding: paddingEnum!) - - if ciphertext != nil { - result(ciphertext) - } else { - result(FlutterError(code: "ENCRYPTIONERROR", - message: "ENCRYPTED PAYLOAD IS EMPTY.", - details: nil)) - } - case "decrypt": - let args = call.arguments as! NSDictionary - - let payload = args["payload"] as! NSArray - let key = (args["key"] as! FlutterStandardTypedData).data - let algo = args["algorithm"] as! String - let mode = args["mode"] as! String - let padding = args["padding"] as! String - - let encrypted = (payload[0] as! FlutterStandardTypedData).data - let iv = (payload[1] as! FlutterStandardTypedData).data - let encryptedPayload = [encrypted, iv] - - let algorithm : CipherAlgorithm? = CipherAlgorithm.init(rawValue: algo) - let modeEnum : BlockCipherMode? = BlockCipherMode.init(rawValue: mode) - let paddingEnum : Padding? = Padding.init(rawValue: padding) - - let decrypted = Cipher().decrypt(payload: encryptedPayload, key: key, algorithm: algorithm!, mode: modeEnum!, padding: paddingEnum!) - - if decrypted != nil { - result(FlutterStandardTypedData.init(bytes: decrypted!)) - } else { - result(FlutterError(code: "DECRYPTIONERROR", - message: "DECRYPTED PAYLOAD IS NIL. MAYBE VERIFICATION MAC IS UNVALID.", - details: nil)) - } - default: result(FlutterMethodNotImplemented) - } - } -} diff --git a/lib/native_crypto.dart b/lib/native_crypto.dart deleted file mode 100644 index 7f00d94..0000000 --- a/lib/native_crypto.dart +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2021 -// Author: Hugo Pointcheval -export './src/exceptions.dart'; -export './src/key.dart'; -export './src/keyspec.dart'; -export './src/keyderivation.dart'; -export './src/digest.dart'; -export './src/cipher.dart'; -export './src/kem.dart'; -export './src/platform.dart'; -export './src/utils.dart'; - -export './src/sym/AES.dart'; -export './src/asym/RSA.dart'; - -const String version = "0.0.6"; -const String author = "Hugo Pointcheval"; -const String website = "https://hugo.pointcheval.fr/"; -const String repository = "https://github.com/hugo-pcl/native-crypto-flutter"; diff --git a/lib/src/asym/RSA.dart b/lib/src/asym/RSA.dart deleted file mode 100644 index 96a1db3..0000000 --- a/lib/src/asym/RSA.dart +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) 2020 -// Author: Hugo Pointcheval - -import 'package:native_crypto/src/exceptions.dart'; -import 'package:native_crypto/src/kem.dart'; -import 'package:native_crypto/src/key.dart'; - -/// This represents RSA Key Encapsulation Mechanism -class RSAKeyEncapsulationMechanism implements KeyEncapsulationMechanism { - bool _isInit = false; - KemMode _mode; - - PublicKey _publicKey; - PrivateKey _privateKey; - - @override - KemAlgorithm get algorithm => KemAlgorithm.RSA; - - @override - Object get options => null; - - @override - bool get isInitialized => _isInit; - - @override - KemMode get mode => _mode; - - @override - KeyPair get keypair => KeyPair.from(_publicKey, _privateKey); - - RSAKeyEncapsulationMechanism( - KemMode mode, { - KeyPair keyPair, - PublicKey publicKey, - }) { - _mode = mode; - if (_mode == KemMode.ENCAPSULATION) { - if (publicKey != null) { - _isInit = true; - _publicKey = publicKey; - } else if (keyPair != null) { - if (keyPair.publicKey != null) { - _isInit = true; - _publicKey = keyPair.publicKey; - } - } - } else if (_mode == KemMode.DECAPSULATION) { - if (keyPair != null) { - if (keyPair.isComplete) { - _isInit = true; - _publicKey = keyPair.publicKey; - _privateKey = keyPair.privateKey; - } else { - throw KemInitException("Keypair must be complete for decapsulation."); - } - } else { - throw KemInitException("You must provide a keypair for decapsulation."); - } - } - } - - @override - Future encapsulate() { - if (!_isInit || _mode == KemMode.DECAPSULATION) { - throw KemInitException("KEM not properly initialized."); - } - throw UnimplementedError(); - } - - @override - Future decapsulate(Encapsulation encapsulation) { - if (!_isInit || _mode == KemMode.ENCAPSULATION) { - throw KemInitException("KEM not properly initialized."); - } - throw UnimplementedError(); - } -} diff --git a/lib/src/cipher.dart b/lib/src/cipher.dart deleted file mode 100644 index b1e34bf..0000000 --- a/lib/src/cipher.dart +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2021 -// Author: Hugo Pointcheval - -import 'dart:typed_data'; - -import 'key.dart'; - -/// Represents different cipher algorithms -enum CipherAlgorithm { AES, None } - -/// Represents different block cipher modes -enum BlockCipherMode { CBC, GCM } - -/// Represents different padding -enum PlainTextPadding { PKCS5, None } - -/// Represents a cipher. -/// -/// In cryptography, a cipher is an algorithm for performing encryption -/// or decryption - a series of well-defined steps that can -/// be followed as a procedure. -abstract class Cipher { - /// Returns the standard algorithm name for this cipher - CipherAlgorithm get algorithm; - - /// Returns the secret key used for this cipher - SecretKey get secretKey; - - /// Returns the parameters used for this cipher - CipherParameters get parameters; - - /// Returns true if cipher is initialized - bool get isInitialized; - - /// Returnes list of supported [CipherParameters] for this cipher - List get supportedParameters; - - /// Encrypts data. - /// - /// Takes [Uint8List] data as parameter. - /// Returns a [CipherText]. - Future encrypt(Uint8List data); - - /// Decrypts cipher text. - /// - /// Takes [CipherText] as parameter. - /// And returns plain text data as [Uint8List]. - Future decrypt(CipherText cipherText); -} - -/// Represents a cipher text. -/// -/// It's the result of an encryption. -abstract class CipherText { - /// Returns the standard algorithm name used for this ciphertext. - CipherAlgorithm get algorithm; - - /// Returns the data of this ciphertext (in chunks). - List get bytes; - - /// Returns the IV of this cipertext (in chunks). - List get iv; - - /// Returns the chunk number of this cipherText. - int get size; - - /// Returns this ciphertext in simple Byte Array format. - Uint8List encode(); - - /// Transforms a simple Byte Array to a NativeCrypto cipherText. - void decode(Uint8List src); -} - -/// Represents a pair of [BlockCipherMode] and [Padding] -class CipherParameters { - BlockCipherMode _mode; - PlainTextPadding _padding; - - /// Returns mode used in the cipher - BlockCipherMode get mode => _mode; - - /// Returns padding used in the cipher - PlainTextPadding get padding => _padding; - - CipherParameters(BlockCipherMode mode, PlainTextPadding padding) { - _mode = mode; - _padding = padding; - } - - @override - bool operator ==(Object o) { - if (identical(this, o)) return true; - - return o is CipherParameters && - o._mode.index == _mode.index && - o._padding.index == _padding.index; - } - - @override - int get hashCode => _mode.hashCode ^ _padding.hashCode; -} diff --git a/lib/src/digest.dart b/lib/src/digest.dart deleted file mode 100644 index 344d5c5..0000000 --- a/lib/src/digest.dart +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2020 -// Author: Hugo Pointcheval - -import 'dart:typed_data'; - -import 'exceptions.dart'; -import 'platform.dart'; -import 'utils.dart'; - -enum HashAlgorithm { SHA1, SHA224, SHA256, SHA384, SHA512 } - -/// Represents message digest, or hash function. -class MessageDigest { - HashAlgorithm _algo; - - /// Returns the standard algorithm name for this digest - HashAlgorithm get algorithm => _algo; - - /// Returns true if digest is initialized - bool get isInitialized => (_algo != null); - - /// Creates [MessageDigest] with a specific algorithm - MessageDigest(HashAlgorithm algorithm) { - _algo = algorithm; - } - - /// Creates [MessageDigest] from the name of an algorithm - MessageDigest.getInstance(String algorithm) { - _algo = Utils.getHashAlgorithm(algorithm); - } - - /// Hashes a message - Future digest(Uint8List data) async { - if (!isInitialized) { - throw DigestInitException('Digest not properly initialized.'); - } - - Uint8List hash = await Platform().digest(data, _algo); - return hash; - } -} diff --git a/lib/src/exceptions.dart b/lib/src/exceptions.dart deleted file mode 100644 index 690d137..0000000 --- a/lib/src/exceptions.dart +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2020 -// Author: Hugo Pointcheval - -class NativeCryptoException implements Exception { - String message; - NativeCryptoException(this.message); -} - -class UtilsException extends NativeCryptoException { - UtilsException(message) : super(message); -} - -class KeyException extends NativeCryptoException { - KeyException(message) : super(message); -} - -class KeyGenerationException extends NativeCryptoException { - KeyGenerationException(message) : super(message); -} - -class KeyPairGenerationException extends NativeCryptoException { - KeyPairGenerationException(message) : super(message); -} - -class KeyDerivationException extends NativeCryptoException { - KeyDerivationException(message) : super(message); -} - -class CipherInitException extends NativeCryptoException { - CipherInitException(message) : super(message); -} - -class KemInitException extends NativeCryptoException { - KemInitException(message) : super(message); -} - -class DigestInitException extends NativeCryptoException { - DigestInitException(message) : super(message); -} - -class DigestException extends NativeCryptoException { - DigestException(message) : super(message); -} - -class EncryptionException extends NativeCryptoException { - EncryptionException(message) : super(message); -} - -class DecryptionException extends NativeCryptoException { - DecryptionException(message) : super(message); -} - -class NotImplementedException extends NativeCryptoException { - NotImplementedException(message) : super(message); -} diff --git a/lib/src/kem.dart b/lib/src/kem.dart deleted file mode 100644 index e6a23dd..0000000 --- a/lib/src/kem.dart +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2020 -// Author: Hugo Pointcheval - -import 'dart:typed_data'; - -import 'key.dart'; - -enum KemAlgorithm { RSA, ECDH } - -enum KemMode { ENCAPSULATION, DECAPSULATION } - -abstract class KeyEncapsulationMechanism { - /// Returns the standard algorithm name for this kem - KemAlgorithm get algorithm; - - /// Returns the parameters used for this kem - Object get options; - - /// Returns true if kem is initialized - bool get isInitialized; - - /// Returns mode used in this kem. - KemMode get mode; - - /// Returns key pair used in this kem. - /// - /// Can be an incomplete if just have public key - /// for example. - KeyPair get keypair; - - /// Encapsulate key. - /// - /// Returns an [Encapsulation]. - Future encapsulate(); - - /// Decapsulate key. - /// - /// Takes [Encapsulation] as parameter. - /// And returns plain text key as [SecretKey]. - Future decapsulate(Encapsulation encapsulation); -} - -abstract class Encapsulation { - /// Returns the standard algorithm name used for this encapsulation - KemAlgorithm get algorithm; - - /// Returns the secret key used in this encapsulation - SecretKey get secretKey; - - /// Returns the encapsulated key - Uint8List get key; -} diff --git a/lib/src/key.dart b/lib/src/key.dart deleted file mode 100644 index 16ba29f..0000000 --- a/lib/src/key.dart +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2021 -// Author: Hugo Pointcheval - -import 'dart:typed_data'; - -import 'package:flutter/services.dart'; -import 'platform.dart'; - -import 'exceptions.dart'; -import 'keyspec.dart'; -import 'cipher.dart'; -import 'utils.dart'; - -/// This is the base class of all key types. -abstract class Key { - Uint8List _bytes; - String _algo; - - /// Returns key as raw byte array. - Uint8List get encoded => _bytes; - - /// Returns the standard algorithm name for this key - String get algorithm => _algo; - - /// Returns the true if this key is null or empty. - bool get isEmpty => (_bytes == null || _bytes.length == 0); - - Key({Uint8List bytes, String algorithm}) { - _bytes = bytes; - _algo = algorithm; - } -} - -/// This represents a secret key, usefull in -/// algorithms like AES or BlowFish. -class SecretKey extends Key { - /// Creates a key from raw byte array - SecretKey.fromBytes(Uint8List bytes, - {CipherAlgorithm algorithm: CipherAlgorithm.None}) - : super(bytes: bytes, algorithm: algorithm.name); - - /// Creates a key from a specific size. - static Future generate(int size, CipherAlgorithm algorithm) async { - if (algorithm == null) { - throw KeyException("Algorithm can't be null"); - } else if (algorithm == CipherAlgorithm.AES) { - List _supportedSizes = [128, 192, 256]; - if (!_supportedSizes.contains(size)) { - throw KeyException("AES must be 128, 192 or 256 bits long."); - } - } - - try { - Uint8List _key = await Platform().keygen(size); - return SecretKey.fromBytes(_key, algorithm: algorithm); - } on PlatformException catch (e) { - throw KeyException(e); - } - } -} - -/// This represents a keypair, usefull in -/// algorithms like RSA. -class KeyPair extends Key { - PublicKey _publicKey; - PrivateKey _privateKey; - - /// Returns public key of this key pair. - PublicKey get publicKey => _publicKey; - - /// Returns private key of this key pair. - PrivateKey get privateKey => _privateKey; - - /// Returns true if key pair contains public AND private keys - bool get isComplete => (_publicKey != null && _privateKey != null); - - /// Creates a key pair from public and private keys. - KeyPair.from(PublicKey publicKey, PrivateKey privateKey, {String algorithm}) { - _publicKey = publicKey; - _privateKey = privateKey; - _algo = algorithm; - } - - /// Creates a key pair from a specific size. - static Future generate(KeySpec keySpec) async { - List _supportedAlgorithms = ["RSA"]; - if (!_supportedAlgorithms.contains(keySpec.algorithm)) { - throw KeyException(keySpec.algorithm + " not supported!"); - } - if (keySpec.algorithm == "RSA") { - RSAKeySpec spec = keySpec; - try { - List kp = await Platform().rsaKeypairGen(spec.size); - PublicKey _publicKey = PublicKey.fromBytes(kp.first, "RSA"); - PrivateKey _privateKey = PrivateKey.fromBytes(kp.last, "RSA"); - return KeyPair.from(_publicKey, _privateKey, algorithm: "RSA"); - } on PlatformException catch (e) { - throw KeyException(e); - } - } else { - throw NotImplementedException("KeyPair generation not yet implemented."); - } - } -} - -/// This represents a public key -class PublicKey extends Key { - /// Creates a public key from raw byte array - PublicKey.fromBytes(Uint8List bytes, String algorithm) - : super(bytes: bytes, algorithm: algorithm); -} - -/// This represents a private key -class PrivateKey extends Key { - /// Creates a private key from raw byte array - PrivateKey.fromBytes(Uint8List bytes, String algorithm) - : super(bytes: bytes, algorithm: algorithm); -} diff --git a/lib/src/keyderivation.dart b/lib/src/keyderivation.dart deleted file mode 100644 index 37b67dc..0000000 --- a/lib/src/keyderivation.dart +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2020 -// Author: Hugo Pointcheval - -import 'dart:typed_data'; - -import 'package:native_crypto/src/digest.dart'; -import 'package:native_crypto/src/exceptions.dart'; -import 'package:native_crypto/src/key.dart'; - -import 'platform.dart'; - -enum KdfAlgorithm { PBKDF2, SCrypt } - -/// Represents a Key Derivation Function -abstract class KeyDerivation { - /// Returns the standard algorithm name for this key derivation function - KdfAlgorithm get algorithm; - - /// Returns the derivated key - SecretKey get key; - - /// Derive key - Future derive(); -} - -class PBKDF2 implements KeyDerivation { - SecretKey _sk; - - int _length; - int _iteration; - HashAlgorithm _hash; - - @override - KdfAlgorithm get algorithm => KdfAlgorithm.PBKDF2; - - @override - SecretKey get key => _sk; - - PBKDF2({ - int keyLength: 32, - int iteration: 10000, - HashAlgorithm hash: HashAlgorithm.SHA256, - }) { - _length = keyLength; - _iteration = iteration; - _hash = hash; - } - - @override - Future derive({String password, String salt}) async { - if (password == null || salt == null) { - throw KeyDerivationException("Password or Salt can't be null!"); - } - if (_hash == null) { - throw KeyDerivationException("Hash Algorithm can't be null!"); - } - - Uint8List derivation = await Platform().pbkdf2( - password, - salt, - keyLength: _length, - iteration: _iteration, - algorithm: _hash, - ); - - _sk = SecretKey.fromBytes(derivation); - } -} - -class Scrypt implements KeyDerivation { - @override - KdfAlgorithm get algorithm => KdfAlgorithm.SCrypt; - - @override - SecretKey get key => throw UnimplementedError(); - - @override - Future derive() { - throw UnimplementedError(); - } -} diff --git a/lib/src/keyspec.dart b/lib/src/keyspec.dart deleted file mode 100644 index 20b43df..0000000 --- a/lib/src/keyspec.dart +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2020 -// Author: Hugo Pointcheval - -/// This represents security parameters. -abstract class KeySpec { - /// Returns the standard algorithm name for this key - String get algorithm; -} - -class RSAKeySpec implements KeySpec { - int _size; - - String get algorithm => "RSA"; - - /// Returns the size of RSA keys - int get size => _size; - - RSAKeySpec(int size) { - _size = size; - } -} diff --git a/lib/src/platform.dart b/lib/src/platform.dart deleted file mode 100644 index ff3a75f..0000000 --- a/lib/src/platform.dart +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (c) 2020 -// Author: Hugo Pointcheval - -import 'dart:typed_data'; - -import 'package:flutter/services.dart'; - -import 'cipher.dart'; -import 'digest.dart'; -import 'exceptions.dart'; -import 'utils.dart'; - -/// Represents a platform, and is usefull to calling -/// methods from a specific platform. -class Platform { - /// Contains the channel for platform specific code. - static const MethodChannel _channel = const MethodChannel('native.crypto'); - - /// Calls native code. - static Future call(String method, [Map arguments]) { - return _channel.invokeMethod(method, arguments); - } - - /// Calls native code that return list. - static Future> callList(String method, - [Map arguments]) { - return _channel.invokeListMethod(method, arguments); - } - - /// Digests a message with a specific algorithm - /// - /// Takes message and algorithm as parameters. - /// - /// Returns a hash as [Uint8List]. - Future digest( - Uint8List message, - HashAlgorithm algorithm, - ) async { - try { - final Uint8List hash = await call('digest', { - 'message': message, - 'algorithm': algorithm.name, - }); - return hash; - } on PlatformException catch (e) { - throw DigestException(e.code + " : " + e.message); - } - } - - /// Calls native PBKDF2. - /// - /// Takes password and salt as parameters. - /// And optionnally keyLength in bytes, number of iterations and hash algorithm. - /// - /// Returns a key as [Uint8List]. - Future pbkdf2( - String password, - String salt, { - int keyLength: 32, - int iteration: 10000, - HashAlgorithm algorithm: HashAlgorithm.SHA256, - }) async { - try { - final Uint8List key = await call('pbkdf2', { - 'password': password, - 'salt': salt, - 'keyLength': keyLength, - 'iteration': iteration, - 'algorithm': algorithm.name, - }); - return key; - } on PlatformException catch (e) { - throw KeyDerivationException(e.code + " : " + e.message); - } - } - - /// Generates a random key. - /// - /// Takes size in bits. - /// - /// Returns a key as [Uint8List]. - Future keygen(int size) async { - try { - final Uint8List key = await call('keygen', { - 'size': size, - }); - return key; - } on PlatformException catch (e) { - throw KeyGenerationException(e.code + " : " + e.message); - } - } - - /// Generates an RSA key pair. - /// - /// Takes size in bits. - /// - /// Returns a key pair as list of [Uint8List], the public key is the - /// first element, and the private is the last. - Future> rsaKeypairGen(int size) async { - try { - final List keypair = - await callList('rsaKeypairGen', { - 'size': size, - }); - return keypair; - } on PlatformException catch (e) { - throw KeyPairGenerationException(e.code + " : " + e.message); - } - } - - /// Encrypts data with a secret key and algorithm. - /// - /// Takes data, key, algorithm, mode and padding as parameters. - /// - /// Encrypts data and returns cipher text - /// and IV as a list of [Uint8List]. - Future> encrypt( - Uint8List data, - Uint8List key, - CipherAlgorithm algorithm, - CipherParameters parameters, - ) async { - try { - final List payload = - await callList('encrypt', { - 'data': data, - 'key': key, - 'algorithm': algorithm.name, - 'mode': parameters.mode.name, - 'padding': parameters.padding.name, - }); - return payload; - } on PlatformException catch (e) { - throw EncryptionException(e.code + " : " + e.message); - } - } - - /// Decrypts a payload with a secret key and algorithm. - /// - /// The payload must be a list of `Uint8List` - /// with encrypted cipher as first and IV as second member. - Future decrypt( - List payload, - Uint8List key, - CipherAlgorithm algorithm, - CipherParameters parameters, - ) async { - try { - final Uint8List data = await call('decrypt', { - 'payload': payload, - 'key': key, - 'algorithm': algorithm.name, - 'mode': parameters.mode.name, - 'padding': parameters.padding.name, - }); - return data; - } on PlatformException catch (e) { - throw DecryptionException(e.code + " : " + e.message); - } - } -} diff --git a/lib/src/sym/AES.dart b/lib/src/sym/AES.dart deleted file mode 100644 index c352a89..0000000 --- a/lib/src/sym/AES.dart +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright (c) 2021 -// Author: Hugo Pointcheval - -import 'dart:typed_data'; - -import 'package:native_crypto/native_crypto.dart'; - -import '../cipher.dart'; -import '../exceptions.dart'; -import '../key.dart'; -import '../platform.dart'; -import '../utils.dart'; - -/// Defines all available key sizes. -enum AESKeySize { bits128, bits192, bits256 } - -extension AESKeySizeExtension on AESKeySize { - int get length { - Map table = { - AESKeySize.bits128: 128, - AESKeySize.bits192: 192, - AESKeySize.bits256: 256, - }; - return table[this]; - } -} - -class AESCipher implements Cipher { - SecretKey _sk; - CipherParameters _params; - bool _isInit; - - @override - CipherAlgorithm get algorithm => CipherAlgorithm.AES; - - @override - SecretKey get secretKey => _sk; - - @override - CipherParameters get parameters => _params; - - @override - bool get isInitialized => _isInit; - - @override - List get supportedParameters => [ - CipherParameters(BlockCipherMode.CBC, PlainTextPadding.PKCS5), - ]; - - /// Creates an AES cipher with specified secretKey and mode/padding - AESCipher(SecretKey secretKey, CipherParameters parameters) { - if (secretKey.algorithm != CipherAlgorithm.AES.name) { - List _supportedSizes = [128, 192, 256]; - if (!_supportedSizes.contains(secretKey.encoded.length)) { - throw CipherInitException("Invalid key length!"); - } - } else if (!supportedParameters.contains(parameters)) { - throw CipherInitException("Invalid cipher parameters."); - } - _sk = secretKey; - _params = parameters; - _isInit = true; - } - - /// Generates a secret key of specified size, then creates an AES cipher. - static Future generate( - AESKeySize size, CipherParameters parameters) async { - SecretKey _sk = await SecretKey.generate(size.length, CipherAlgorithm.AES); - return AESCipher(_sk, parameters); - } - - @override - Future encrypt(Uint8List data) async { - if (!_isInit) { - throw CipherInitException('Cipher not properly initialized.'); - } else if (_sk == null || _sk.isEmpty) { - throw CipherInitException('Invalid key size.'); - } - Uint8List dataToEncrypt; - int maxSize = 33554432; - AESCipherText cipherText = AESCipherText.empty(); - // If data is bigger than 32mB -> split in chunks - if (data.length > maxSize) { - int chunkNb = (data.length / maxSize).ceil(); - for (var i = 0; i < chunkNb; i++) { - if (i < (chunkNb - 1)) { - dataToEncrypt = data.sublist(i * maxSize, (i + 1) * maxSize); - } else { - dataToEncrypt = data.sublist(i * maxSize); - } - List c = await Platform() - .encrypt(dataToEncrypt, _sk.encoded, algorithm, _params); - cipherText.append(c[0], c[1]); - } - } else { - List c = - await Platform().encrypt(data, _sk.encoded, algorithm, _params); - cipherText.append(c[0], c[1]); - } - return cipherText; - } - - @override - Future decrypt(CipherText cipherText) async { - if (cipherText.algorithm != CipherAlgorithm.AES) { - throw DecryptionException("This cipher text's algorithm is not AES: " + - cipherText.algorithm.name + - "\nYou must use an AESCipherText."); - } else if (!_isInit) { - throw CipherInitException('Cipher not properly initialized.'); - } else if (_sk == null || _sk.isEmpty) { - throw CipherInitException('Invalid key size.'); - } else if (cipherText.bytes.length != cipherText.iv.length) { - throw DecryptionException( - "This cipher text's bytes chunks length is not the same as iv chunks length"); - } - - BytesBuilder decryptedData = BytesBuilder(); - if (cipherText.size > 1) { - for (var i = 0; i < cipherText.size; i++) { - List payload = [cipherText.bytes[i], cipherText.iv[i]]; - Uint8List d = - await Platform().decrypt(payload, _sk.encoded, algorithm, _params); - decryptedData.add(d); - } - } else { - List payload = [cipherText.bytes[0], cipherText.iv[0]]; - Uint8List d = - await Platform().decrypt(payload, _sk.encoded, algorithm, _params); - decryptedData.add(d); - } - return decryptedData.toBytes(); - } -} - -class AESCipherText implements CipherText { - List _bytes; - List _iv; - - @override - CipherAlgorithm get algorithm => CipherAlgorithm.AES; - - @override - List get bytes => _bytes; - - @override - List get iv => _iv; - - @override - int get size => _bytes.length; - - AESCipherText(Uint8List bytes, Uint8List iv) { - _bytes = List.from([bytes]); - _iv = List.from([iv]); - } - - AESCipherText.from(List bytes, List iv) { - _bytes = bytes; - _iv = iv; - } - - AESCipherText.empty() { - _bytes = []; - _iv = []; - } - - void append(Uint8List bytes, Uint8List iv) { - _bytes.add(bytes); - _iv.add(iv); - } - - /// Returns this ciphertext in [Uint8List] format. - /// - /// Encoding - /// -------- - /// Uint8List encoding is : IV_1 + M_1 + IV_2 + M_2 + ... + IV_n + M_n - /// - /// Where **IV_k** is the IV of the cipher text **M_k** - /// - /// IV is **always** 16 bytes long, And the **M** are all max - /// size (of 33 554 480 bytes) except the last one which is shorter than the others. - Uint8List encode() { - BytesBuilder builder = BytesBuilder(); - for (var i = 0; i < size; i++) { - builder.add(_iv[i]); - builder.add(_bytes[i]); - } - - return builder.toBytes(); - } - - /// Transforms a [Uint8List] to a *NativeCrypto* cipherText. - /// - /// Decoding - /// -------- - /// See the list as a chain of chunks (IV and Messages) - /// `[IV][MESSAGE][IV][MESSAGE] ... [IV][MESSA...]` - /// - /// Chunk length is IV length + Message length = 16 + 33 554 480 bytes - void decode(Uint8List src) { - ByteBuffer buffer = src.buffer; - - int chunkSize = 16 + 33554480; - int chunkNb = (buffer.lengthInBytes / chunkSize).ceil(); - - for (var i = 0; i < chunkNb; i++) { - _iv.add(buffer.asUint8List(i * chunkSize, 16)); - if (i < (chunkNb - 1)) { - _bytes.add(buffer.asUint8List(16 + i * chunkSize, 33554480)); - } else { - _bytes.add(buffer.asUint8List(16 + i * chunkSize)); - } - } - } -} diff --git a/lib/src/utils.dart b/lib/src/utils.dart deleted file mode 100644 index 3bce678..0000000 --- a/lib/src/utils.dart +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) 2020 -// Author: Hugo Pointcheval - -import 'package:flutter/foundation.dart'; - -import 'cipher.dart'; -import 'digest.dart'; -import 'exceptions.dart'; -import 'kem.dart'; -import 'keyderivation.dart'; - -extension HashAlgorithmExtension on HashAlgorithm { - String get name => describeEnum(this).toLowerCase(); -} - -extension KdfAlgorithmExtension on KdfAlgorithm { - String get name => describeEnum(this).toLowerCase(); -} - -extension CipherAlgorithmExtension on CipherAlgorithm { - String get name => describeEnum(this).toLowerCase(); -} - -extension KemAlgorithmExtension on KemAlgorithm { - String get name => describeEnum(this).toLowerCase(); -} - -extension BlockCipherModeExtension on BlockCipherMode { - String get name => describeEnum(this).toLowerCase(); -} - -extension PlainTextPaddingExtension on PlainTextPadding { - String get name => describeEnum(this).toLowerCase(); -} - -class Utils { - /// Returns [HashAlgorithm] from his name. - static HashAlgorithm getHashAlgorithm(String algorithm) { - String _query = algorithm.toLowerCase(); - for (HashAlgorithm h in HashAlgorithm.values) { - if (_query == h.name) { - return h; - } - } - throw UtilsException("Unknown hash algorithm!"); - } - - /// Returns all available [HashAlgorithm] as String list - static List getAvailableHashAlgorithms() { - List _res = []; - for (HashAlgorithm h in HashAlgorithm.values) { - _res.add(h.name); - } - return _res; - } - - /// Returns [KdfAlgorithm] from his name. - static KdfAlgorithm getKdfAlgorithm(String algorithm) { - String _query = algorithm.toLowerCase(); - for (KdfAlgorithm h in KdfAlgorithm.values) { - if (_query == h.name) { - return h; - } - } - throw UtilsException("Unknown key derivation algorithm!"); - } - - /// Returns all available [KdfAlgorithm] as String list - static List getAvailableKdfAlgorithms() { - List _res = []; - for (KdfAlgorithm h in KdfAlgorithm.values) { - _res.add(h.name); - } - return _res; - } - - /// Returns [CipherAlgorithm] from his name. - static CipherAlgorithm getCipherAlgorithm(String algorithm) { - String _query = algorithm.toLowerCase(); - for (CipherAlgorithm c in CipherAlgorithm.values) { - if (_query == c.name) { - return c; - } - } - throw UtilsException("Unknown cipher algorithm!"); - } - - /// Returns all available [CipherAlgorithm] as String list - static List getAvailableCipherAlgorithms() { - List _res = []; - for (CipherAlgorithm c in CipherAlgorithm.values) { - _res.add(c.name); - } - return _res; - } - - /// Returns [KemAlgorithm] from his name. - static KemAlgorithm getKemAlgorithm(String algorithm) { - String _query = algorithm.toLowerCase(); - for (KemAlgorithm k in KemAlgorithm.values) { - if (_query == k.name) { - return k; - } - } - throw UtilsException("Unknown KEM algorithm!"); - } - - /// Returns all available [KemAlgorithm] as String list - static List getAvailableKemAlgorithms() { - List _res = []; - for (KemAlgorithm k in KemAlgorithm.values) { - _res.add(k.name); - } - return _res; - } - - /// Returns [CipherParameters] from string. - /// - /// For example, `CBC/PKCS5` gives a CipherParameters with - /// CBC mode and PKCS5 as padding. - static CipherParameters getCipherParameters(String parameters) { - List _query = parameters.toLowerCase().split("/"); - BlockCipherMode _mode; - PlainTextPadding _padding; - for (BlockCipherMode b in BlockCipherMode.values) { - if (_query[0] == b.name) { - _mode = b; - } - } - for (PlainTextPadding p in PlainTextPadding.values) { - if (_query[1] == p.name) { - _padding = p; - } - } - if (_mode == null || _padding == null) { - throw UtilsException("Unknown parameters!"); - } else { - return CipherParameters(_mode, _padding); - } - } -} diff --git a/native_crypto/.gitignore b/native_crypto/.gitignore new file mode 100644 index 0000000..9a04984 --- /dev/null +++ b/native_crypto/.gitignore @@ -0,0 +1,389 @@ +# File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig + +# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,macos,dart,flutter,intellij+all,kotlin,linux,swift,windows +# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,macos,dart,flutter,intellij+all,kotlin,linux,swift,windows + +### Dart ### +# See https://www.dartlang.org/guides/libraries/private-files + +# Files and directories created by pub +.dart_tool/ +.packages +build/ +# If you're building an application, you may want to check-in your pubspec.lock +pubspec.lock + +# Directory created by dartdoc +# If you don't generate documentation locally you can remove this line. +doc/api/ + +# dotenv environment variables file +.env* + +# Avoid committing generated Javascript files: +*.dart.js +*.info.json # Produced by the --dump-info flag. +*.js # When generated by dart2js. Don't specify *.js if your + # project includes source files written in JavaScript. +*.js_ +*.js.deps +*.js.map + +.flutter-plugins +.flutter-plugins-dependencies + +### Dart Patch ### +# dotenv environment variables file +.env + +### Flutter ### +# Flutter/Dart/Pub related +**/doc/api/ +.fvm/ +.pub-cache/ +.pub/ +coverage/ +lib/generated_plugin_registrant.dart +# For library packages, don’t commit the pubspec.lock file. +# Regenerating the pubspec.lock file lets you test your package against the latest compatible versions of its dependencies. +# See https://dart.dev/guides/libraries/private-files#pubspeclock +#pubspec.lock + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/key.properties +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/.last_build_id +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages + +### Intellij+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Intellij+all Patch ### +# Ignores the whole .idea folder and all .iml files +# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 + +.idea/ + +# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 + +*.iml +modules.xml +.idea/misc.xml +*.ipr + +# Sonarlint plugin +.idea/sonarlint + +### Kotlin ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Swift ### +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## User settings +xcuserdata/ + +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) +*.xcscmblueprint +*.xccheckout + +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) +DerivedData/ +*.moved-aside +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 + +## Obj-C/Swift specific +*.hmap + +## App packaging +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +# *.xcodeproj +# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata +# hence it is not needed unless you have added a package configuration file to your project +# .swiftpm + +.build/ + +# CocoaPods +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# Pods/ +# Add this line if you want to avoid checking in source code from the Xcode workspace +# *.xcworkspace + +# Carthage +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build/ + +# Accio dependency management +Dependencies/ +.accio/ + +# fastlane +# It is recommended to not store the screenshots in the git repo. +# Instead, use fastlane to re-generate the screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output + +# Code Injection +# After new code Injection tools there's a generated folder /iOSInjectionProject +# https://github.com/johnno1962/injectionforxcode + +iOSInjectionProject/ + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +# Support for Project snippet scope +!.vscode/*.code-snippets + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,macos,dart,flutter,intellij+all,kotlin,linux,swift,windows + +# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) + diff --git a/.metadata b/native_crypto/.metadata similarity index 82% rename from .metadata rename to native_crypto/.metadata index 0b60be7..50d6e33 100644 --- a/.metadata +++ b/native_crypto/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled and should not be manually edited. version: - revision: f139b11009aeb8ed2a3a3aa8b0066e482709dde3 + revision: cf4400006550b70f28e4b4af815151d1e74846c6 channel: stable project_type: plugin diff --git a/native_crypto/CHANGELOG.md b/native_crypto/CHANGELOG.md new file mode 100644 index 0000000..41cc7d8 --- /dev/null +++ b/native_crypto/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/native_crypto/LICENSE b/native_crypto/LICENSE new file mode 100644 index 0000000..ba75c69 --- /dev/null +++ b/native_crypto/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/native_crypto/README.md b/native_crypto/README.md new file mode 100644 index 0000000..1bf39c0 --- /dev/null +++ b/native_crypto/README.md @@ -0,0 +1,18 @@ +# native_crypto + +A new flutter plugin project. + +## Getting Started + +This project is a starting point for a Flutter +[plug-in package](https://flutter.dev/developing-packages/), +a specialized package that includes platform-specific implementation code for +Android and/or iOS. + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. + +The plugin project was generated without specifying the `--platforms` flag, no platforms are currently supported. +To add platforms, run `flutter create -t plugin --platforms .` under the same +directory. You can also find a detailed instruction on how to add platforms in the `pubspec.yaml` at https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin-platforms. diff --git a/native_crypto/analysis_options.yaml b/native_crypto/analysis_options.yaml new file mode 100644 index 0000000..a5744c1 --- /dev/null +++ b/native_crypto/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/example/.gitignore b/native_crypto/example/.gitignore similarity index 70% rename from example/.gitignore rename to native_crypto/example/.gitignore index ae1f183..0fa6b67 100644 --- a/example/.gitignore +++ b/native_crypto/example/.gitignore @@ -22,6 +22,7 @@ # Flutter/Dart/Pub related **/doc/api/ +**/ios/Flutter/.last_build_id .dart_tool/ .flutter-plugins .flutter-plugins-dependencies @@ -33,5 +34,13 @@ # Web related lib/generated_plugin_registrant.dart -# Exceptions to above rules. -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/example/.metadata b/native_crypto/example/.metadata similarity index 82% rename from example/.metadata rename to native_crypto/example/.metadata index 4adf4bf..ee7f61d 100644 --- a/example/.metadata +++ b/native_crypto/example/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled and should not be manually edited. version: - revision: f139b11009aeb8ed2a3a3aa8b0066e482709dde3 + revision: cf4400006550b70f28e4b4af815151d1e74846c6 channel: stable project_type: app diff --git a/example/README.md b/native_crypto/example/README.md similarity index 100% rename from example/README.md rename to native_crypto/example/README.md diff --git a/native_crypto/example/analysis_options.yaml b/native_crypto/example/analysis_options.yaml new file mode 100644 index 0000000..61b6c4d --- /dev/null +++ b/native_crypto/example/analysis_options.yaml @@ -0,0 +1,29 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/native_crypto/example/android/.gitignore b/native_crypto/example/android/.gitignore new file mode 100644 index 0000000..6f56801 --- /dev/null +++ b/native_crypto/example/android/.gitignore @@ -0,0 +1,13 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +**/*.keystore +**/*.jks diff --git a/example/android/app/build.gradle b/native_crypto/example/android/app/build.gradle similarity index 81% rename from example/android/app/build.gradle rename to native_crypto/example/android/app/build.gradle index f6c24d7..803881a 100644 --- a/example/android/app/build.gradle +++ b/native_crypto/example/android/app/build.gradle @@ -26,24 +26,28 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 28 + compileSdkVersion flutter.compileSdkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } sourceSets { main.java.srcDirs += 'src/main/kotlin' } - lintOptions { - disable 'InvalidPackage' - } - defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "fr.pointcheval.native_crypto_example" - minSdkVersion 16 - targetSdkVersion 28 + minSdkVersion flutter.minSdkVersion + targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -61,7 +65,4 @@ flutter { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test:runner:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' } diff --git a/example/android/app/src/debug/AndroidManifest.xml b/native_crypto/example/android/app/src/debug/AndroidManifest.xml similarity index 100% rename from example/android/app/src/debug/AndroidManifest.xml rename to native_crypto/example/android/app/src/debug/AndroidManifest.xml diff --git a/example/android/app/src/main/AndroidManifest.xml b/native_crypto/example/android/app/src/main/AndroidManifest.xml similarity index 65% rename from example/android/app/src/main/AndroidManifest.xml rename to native_crypto/example/android/app/src/main/AndroidManifest.xml index 6e6213c..c55f004 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/native_crypto/example/android/app/src/main/AndroidManifest.xml @@ -1,21 +1,25 @@ - - + + diff --git a/native_crypto/example/android/app/src/main/kotlin/fr/pointcheval/native_crypto_example/MainActivity.kt b/native_crypto/example/android/app/src/main/kotlin/fr/pointcheval/native_crypto_example/MainActivity.kt new file mode 100644 index 0000000..de245bb --- /dev/null +++ b/native_crypto/example/android/app/src/main/kotlin/fr/pointcheval/native_crypto_example/MainActivity.kt @@ -0,0 +1,6 @@ +package fr.pointcheval.native_crypto_example + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/native_crypto/example/android/app/src/main/res/drawable-v21/launch_background.xml b/native_crypto/example/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/native_crypto/example/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/example/android/app/src/main/res/drawable/launch_background.xml b/native_crypto/example/android/app/src/main/res/drawable/launch_background.xml similarity index 100% rename from example/android/app/src/main/res/drawable/launch_background.xml rename to native_crypto/example/android/app/src/main/res/drawable/launch_background.xml diff --git a/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/native_crypto/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to native_crypto/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/native_crypto/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to native_crypto/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/native_crypto/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to native_crypto/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/native_crypto/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to native_crypto/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/native_crypto/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to native_crypto/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/native_crypto/example/android/app/src/main/res/values-night/styles.xml b/native_crypto/example/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..3db14bb --- /dev/null +++ b/native_crypto/example/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/native_crypto/example/android/app/src/main/res/values/styles.xml b/native_crypto/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..d460d1e --- /dev/null +++ b/native_crypto/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/example/android/app/src/profile/AndroidManifest.xml b/native_crypto/example/android/app/src/profile/AndroidManifest.xml similarity index 100% rename from example/android/app/src/profile/AndroidManifest.xml rename to native_crypto/example/android/app/src/profile/AndroidManifest.xml diff --git a/example/android/build.gradle b/native_crypto/example/android/build.gradle similarity index 82% rename from example/android/build.gradle rename to native_crypto/example/android/build.gradle index 59baba0..24047dc 100644 --- a/example/android/build.gradle +++ b/native_crypto/example/android/build.gradle @@ -2,11 +2,11 @@ buildscript { ext.kotlin_version = '1.3.50' repositories { google() - jcenter() + mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:4.1.1' + classpath 'com.android.tools.build:gradle:4.1.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -14,7 +14,7 @@ buildscript { allprojects { repositories { google() - jcenter() + mavenCentral() } } diff --git a/android/gradle.properties b/native_crypto/example/android/gradle.properties similarity index 78% rename from android/gradle.properties rename to native_crypto/example/android/gradle.properties index 38c8d45..94adc3a 100644 --- a/android/gradle.properties +++ b/native_crypto/example/android/gradle.properties @@ -1,4 +1,3 @@ org.gradle.jvmargs=-Xmx1536M -android.enableR8=true android.useAndroidX=true android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/native_crypto/example/android/gradle/wrapper/gradle-wrapper.properties similarity index 80% rename from android/gradle/wrapper/gradle-wrapper.properties rename to native_crypto/example/android/gradle/wrapper/gradle-wrapper.properties index 01a286e..bc6a58a 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/native_crypto/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/native_crypto/example/android/settings.gradle b/native_crypto/example/android/settings.gradle new file mode 100644 index 0000000..44e62bc --- /dev/null +++ b/native_crypto/example/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/example/ios/.gitignore b/native_crypto/example/ios/.gitignore similarity index 95% rename from example/ios/.gitignore rename to native_crypto/example/ios/.gitignore index e96ef60..7a7f987 100644 --- a/example/ios/.gitignore +++ b/native_crypto/example/ios/.gitignore @@ -1,3 +1,4 @@ +**/dgph *.mode1v3 *.mode2v3 *.moved-aside @@ -18,6 +19,7 @@ Flutter/App.framework Flutter/Flutter.framework Flutter/Flutter.podspec Flutter/Generated.xcconfig +Flutter/ephemeral/ Flutter/app.flx Flutter/app.zip Flutter/flutter_assets/ diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/native_crypto/example/ios/Flutter/AppFrameworkInfo.plist similarity index 91% rename from example/ios/Flutter/AppFrameworkInfo.plist rename to native_crypto/example/ios/Flutter/AppFrameworkInfo.plist index 6b4c0f7..8d4492f 100644 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ b/native_crypto/example/ios/Flutter/AppFrameworkInfo.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) + en CFBundleExecutable App CFBundleIdentifier @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 8.0 + 9.0 diff --git a/example/ios/Flutter/Debug.xcconfig b/native_crypto/example/ios/Flutter/Debug.xcconfig similarity index 58% rename from example/ios/Flutter/Debug.xcconfig rename to native_crypto/example/ios/Flutter/Debug.xcconfig index b2f5fae..ec97fc6 100644 --- a/example/ios/Flutter/Debug.xcconfig +++ b/native_crypto/example/ios/Flutter/Debug.xcconfig @@ -1,3 +1,2 @@ #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/example/ios/Flutter/Release.xcconfig b/native_crypto/example/ios/Flutter/Release.xcconfig similarity index 58% rename from example/ios/Flutter/Release.xcconfig rename to native_crypto/example/ios/Flutter/Release.xcconfig index 88c2914..c4855bf 100644 --- a/example/ios/Flutter/Release.xcconfig +++ b/native_crypto/example/ios/Flutter/Release.xcconfig @@ -1,3 +1,2 @@ #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/native_crypto/example/ios/Podfile b/native_crypto/example/ios/Podfile new file mode 100644 index 0000000..1e8c3c9 --- /dev/null +++ b/native_crypto/example/ios/Podfile @@ -0,0 +1,41 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/native_crypto/example/ios/Runner.xcodeproj/project.pbxproj b/native_crypto/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..6571d99 --- /dev/null +++ b/native_crypto/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,484 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 6Z5P8GG96U; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = fr.pointcheval.nativeCryptoExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 6Z5P8GG96U; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = fr.pointcheval.nativeCryptoExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 6Z5P8GG96U; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = fr.pointcheval.nativeCryptoExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/native_crypto/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/native_crypto/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/native_crypto/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/native_crypto/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to native_crypto/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/native_crypto/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/native_crypto/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/native_crypto/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/native_crypto/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 95% rename from example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to native_crypto/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index a28140c..c87d15a 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/native_crypto/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ - - - - + + - - + + + + PreviewsEnabled + + + diff --git a/example/ios/Runner/AppDelegate.swift b/native_crypto/example/ios/Runner/AppDelegate.swift similarity index 100% rename from example/ios/Runner/AppDelegate.swift rename to native_crypto/example/ios/Runner/AppDelegate.swift diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/native_crypto/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json similarity index 100% rename from example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json rename to native_crypto/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/native_crypto/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png rename to native_crypto/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/native_crypto/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/native_crypto/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png similarity index 100% rename from example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png rename to native_crypto/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/native_crypto/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md similarity index 100% rename from example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md rename to native_crypto/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md diff --git a/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/native_crypto/example/ios/Runner/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from example/ios/Runner/Base.lproj/LaunchScreen.storyboard rename to native_crypto/example/ios/Runner/Base.lproj/LaunchScreen.storyboard diff --git a/example/ios/Runner/Base.lproj/Main.storyboard b/native_crypto/example/ios/Runner/Base.lproj/Main.storyboard similarity index 100% rename from example/ios/Runner/Base.lproj/Main.storyboard rename to native_crypto/example/ios/Runner/Base.lproj/Main.storyboard diff --git a/example/ios/Runner/Info.plist b/native_crypto/example/ios/Runner/Info.plist similarity index 95% rename from example/ios/Runner/Info.plist rename to native_crypto/example/ios/Runner/Info.plist index 24b0528..58d9657 100644 --- a/example/ios/Runner/Info.plist +++ b/native_crypto/example/ios/Runner/Info.plist @@ -4,6 +4,8 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Native Crypto CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -40,6 +42,6 @@ UIInterfaceOrientationLandscapeRight UIViewControllerBasedStatusBarAppearance - + diff --git a/native_crypto/example/ios/Runner/Runner-Bridging-Header.h b/native_crypto/example/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/native_crypto/example/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/native_crypto/example/lib/main.dart b/native_crypto/example/lib/main.dart new file mode 100644 index 0000000..322f70f --- /dev/null +++ b/native_crypto/example/lib/main.dart @@ -0,0 +1,62 @@ +import 'package:flutter/material.dart'; +import 'dart:async'; + +import 'package:flutter/services.dart'; +import 'package:native_crypto/native_crypto.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatefulWidget { + const MyApp({Key? key}) : super(key: key); + + @override + State createState() => _MyAppState(); +} + +class _MyAppState extends State { + String _platformVersion = 'Unknown'; + + @override + void initState() { + super.initState(); + initPlatformState(); + } + + // Platform messages are asynchronous, so we initialize in an async method. + Future initPlatformState() async { + String platformVersion; + // Platform messages may fail, so we use a try/catch PlatformException. + // We also handle the message potentially returning null. + try { + platformVersion = + await NativeCrypto.platformVersion ?? 'Unknown platform version'; + } on PlatformException { + platformVersion = 'Failed to get platform version.'; + } + + // If the widget was removed from the tree while the asynchronous platform + // message was in flight, we want to discard the reply rather than calling + // setState to update our non-existent appearance. + if (!mounted) return; + + setState(() { + _platformVersion = platformVersion; + }); + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + appBar: AppBar( + title: const Text('Plugin example app'), + ), + body: Center( + child: Text('Running on: $_platformVersion\n'), + ), + ), + ); + } +} diff --git a/example/pubspec.yaml b/native_crypto/example/pubspec.yaml similarity index 55% rename from example/pubspec.yaml rename to native_crypto/example/pubspec.yaml index 21602e9..e6e3ec3 100644 --- a/example/pubspec.yaml +++ b/native_crypto/example/pubspec.yaml @@ -1,25 +1,45 @@ name: native_crypto_example description: Demonstrates how to use the native_crypto plugin. -version: 1.0.0+1 -publish_to: 'none' + +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.15.0 <3.0.0" +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. dependencies: flutter: sdk: flutter + native_crypto: + # When depending on this package from a real application you should use: + # native_crypto: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. + path: ../ + # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.2 + cupertino_icons: ^1.0.2 dev_dependencies: flutter_test: sdk: flutter - native_crypto: - path: ../ + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + flutter_lints: ^1.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec @@ -34,8 +54,8 @@ flutter: # To add assets to your application, add an assets section, like this: # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. diff --git a/example/test/widget_test.dart b/native_crypto/example/test/widget_test.dart similarity index 87% rename from example/test/widget_test.dart rename to native_crypto/example/test/widget_test.dart index 8e47dd6..ffdf51c 100644 --- a/example/test/widget_test.dart +++ b/native_crypto/example/test/widget_test.dart @@ -13,13 +13,13 @@ import 'package:native_crypto_example/main.dart'; void main() { testWidgets('Verify Platform version', (WidgetTester tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); + await tester.pumpWidget(const MyApp()); // Verify that platform version is retrieved. expect( find.byWidgetPredicate( (Widget widget) => widget is Text && - widget.data.startsWith('Running on:'), + widget.data!.startsWith('Running on:'), ), findsOneWidget, ); diff --git a/native_crypto/lib/native_crypto.dart b/native_crypto/lib/native_crypto.dart new file mode 100644 index 0000000..1036e3a --- /dev/null +++ b/native_crypto/lib/native_crypto.dart @@ -0,0 +1,17 @@ +// You have generated a new plugin project without +// specifying the `--platforms` flag. A plugin project supports no platforms is generated. +// To add platforms, run `flutter create -t plugin --platforms .` under the same +// directory. You can also find a detailed instruction on how to add platforms in the `pubspec.yaml` at https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin-platforms. + +import 'dart:async'; + +import 'package:flutter/services.dart'; + +class NativeCrypto { + static const MethodChannel _channel = MethodChannel('native_crypto'); + + static Future get platformVersion async { + final String? version = await _channel.invokeMethod('getPlatformVersion'); + return version; + } +} diff --git a/native_crypto/pubspec.yaml b/native_crypto/pubspec.yaml new file mode 100644 index 0000000..3baf2be --- /dev/null +++ b/native_crypto/pubspec.yaml @@ -0,0 +1,28 @@ +name: native_crypto +description: Fast and secure cryptography for Flutter. +version: 0.0.7 +publish_to: 'none' + +environment: + sdk: ">=2.15.0 <3.0.0" + flutter: ">=2.5.0" + +dependencies: + flutter: + sdk: flutter + + native_crypto_ios: + path: ../native_crypto_ios + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^1.0.4 + +flutter: + plugin: + platforms: + # android: + # default_package: native_crypto_android + ios: + default_package: native_crypto_ios \ No newline at end of file diff --git a/test/native_crypto_test.dart b/native_crypto/test/native_crypto_test.dart similarity index 72% rename from test/native_crypto_test.dart rename to native_crypto/test/native_crypto_test.dart index 1787622..5caceab 100644 --- a/test/native_crypto_test.dart +++ b/native_crypto/test/native_crypto_test.dart @@ -1,5 +1,6 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:native_crypto/native_crypto.dart'; void main() { const MethodChannel channel = MethodChannel('native_crypto'); @@ -15,4 +16,8 @@ void main() { tearDown(() { channel.setMockMethodCallHandler(null); }); + + test('getPlatformVersion', () async { + expect(await NativeCrypto.platformVersion, '42'); + }); } diff --git a/.gitignore b/native_crypto_ios/.gitignore similarity index 61% rename from .gitignore rename to native_crypto_ios/.gitignore index cea0a9c..23f216c 100644 --- a/.gitignore +++ b/native_crypto_ios/.gitignore @@ -1,107 +1,7 @@ # File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig -# Created by https://www.gitignore.io/api/windows,visualstudiocode,android,androidstudio,cocoapods,dart,flutter,intellij+all,kotlin,macos,swift,xcode,xcodeinjection -# Edit at https://www.gitignore.io/?templates=windows,visualstudiocode,android,androidstudio,cocoapods,dart,flutter,intellij+all,kotlin,macos,swift,xcode,xcodeinjection - -### Android ### -# Built application files -*.apk -*.ap_ -*.aab - -# Files for the ART/Dalvik VM -*.dex - -# Java class files -*.class - -# Generated files -bin/ -gen/ -out/ -release/ - -# Gradle files -.gradle/ -build/ - -# Local configuration file (sdk path, etc) -local.properties - -# Proguard folder generated by Eclipse -proguard/ - -# Log Files -*.log - -# Android Studio Navigation editor temp files -.navigation/ - -# Android Studio captures folder -captures/ - -# IntelliJ -*.iml -.idea/workspace.xml -.idea/tasks.xml -.idea/gradle.xml -.idea/assetWizardSettings.xml -.idea/dictionaries -.idea/libraries -# Android Studio 3 in .gitignore file. -.idea/caches -.idea/modules.xml -# Comment next line if keeping position of elements in Navigation Editor is relevant for you -.idea/navEditor.xml - -# Keystore files -# Uncomment the following lines if you do not want to check your keystore files in. -#*.jks -#*.keystore - -# External native build folder generated in Android Studio 2.2 and later -.externalNativeBuild - -# Google Services (e.g. APIs or Firebase) -# google-services.json - -# Freeline -freeline.py -freeline/ -freeline_project_description.json - -# fastlane -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots -fastlane/test_output -fastlane/readme.md - -# Version control -vcs.xml - -# lint -lint/intermediates/ -lint/generated/ -lint/outputs/ -lint/tmp/ -# lint/reports/ - -### Android Patch ### -gen-external-apklibs -output.json - -# Replacement of .externalNativeBuild directories introduced -# with Android Studio 3.5. -.cxx/ - -### CocoaPods ### -## CocoaPods GitIgnore Template - -# CocoaPods - Only use to conserve bandwidth / Save time on Pushing -# - Also handy if you have a large number of dependant pods -# - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGNORE THE LOCK FILE -Pods/ +# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,macos,dart,flutter,intellij+all,kotlin,linux,swift,windows +# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,macos,dart,flutter,intellij+all,kotlin,linux,swift,windows ### Dart ### # See https://www.dartlang.org/guides/libraries/private-files @@ -109,6 +9,7 @@ Pods/ # Files and directories created by pub .dart_tool/ .packages +build/ # If you're building an application, you may want to check-in your pubspec.lock pubspec.lock @@ -116,6 +17,9 @@ pubspec.lock # If you don't generate documentation locally you can remove this line. doc/api/ +# dotenv environment variables file +.env* + # Avoid committing generated Javascript files: *.dart.js *.info.json # Produced by the --dump-info flag. @@ -125,13 +29,25 @@ doc/api/ *.js.deps *.js.map +.flutter-plugins +.flutter-plugins-dependencies + +### Dart Patch ### +# dotenv environment variables file +.env + ### Flutter ### # Flutter/Dart/Pub related **/doc/api/ -.flutter-plugins -.flutter-plugins-dependencies +.fvm/ .pub-cache/ .pub/ +coverage/ +lib/generated_plugin_registrant.dart +# For library packages, don’t commit the pubspec.lock file. +# Regenerating the pubspec.lock file lets you test your package against the latest compatible versions of its dependencies. +# See https://dart.dev/guides/libraries/private-files#pubspeclock +#pubspec.lock # Android related **/android/**/gradle-wrapper.jar @@ -139,6 +55,7 @@ doc/api/ **/android/captures/ **/android/gradlew **/android/gradlew.bat +**/android/key.properties **/android/local.properties **/android/**/GeneratedPluginRegistrant.java @@ -159,12 +76,15 @@ doc/api/ **/ios/**/profile **/ios/**/xcuserdata **/ios/.generated/ +**/ios/Flutter/.last_build_id **/ios/Flutter/App.framework **/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec **/ios/Flutter/Generated.xcconfig **/ios/Flutter/app.flx **/ios/Flutter/app.zip **/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh **/ios/ServiceDefinitions.json **/ios/Runner/GeneratedPluginRegistrant.* @@ -176,7 +96,7 @@ doc/api/ !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages ### Intellij+all ### -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff @@ -186,6 +106,9 @@ doc/api/ .idea/**/dictionaries .idea/**/shelf +# AWS User-specific +.idea/**/aws.xml + # Generated files .idea/**/contentModel.xml @@ -206,6 +129,9 @@ doc/api/ # When using Gradle or Maven with auto-import, you should exclude module files, # since they will be recreated, and may cause churn. Uncomment if using # auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml # .idea/modules.xml # .idea/*.iml # .idea/modules @@ -222,6 +148,7 @@ cmake-build-*/ *.iws # IntelliJ +out/ # mpeltonen/sbt-idea plugin .idea_modules/ @@ -252,6 +179,7 @@ fabric.properties # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 +*.iml modules.xml .idea/misc.xml *.ipr @@ -261,8 +189,10 @@ modules.xml ### Kotlin ### # Compiled class file +*.class # Log file +*.log # BlueJ files *.ctxt @@ -282,6 +212,21 @@ modules.xml # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + ### macOS ### # General .DS_Store @@ -291,6 +236,7 @@ hs_err_pid* # Icon must end with two \r Icon + # Thumbnails ._* @@ -315,10 +261,16 @@ Temporary Items # # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore -## Build generated -DerivedData/ +## User settings +xcuserdata/ -## Various settings +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) +*.xcscmblueprint +*.xccheckout + +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) +DerivedData/ +*.moved-aside *.pbxuser !default.pbxuser *.mode1v3 @@ -327,15 +279,11 @@ DerivedData/ !default.mode2v3 *.perspectivev3 !default.perspectivev3 -xcuserdata/ - -## Other -*.moved-aside -*.xccheckout -*.xcscmblueprint ## Obj-C/Swift specific *.hmap + +## App packaging *.ipa *.dSYM.zip *.dSYM @@ -349,9 +297,12 @@ playground.xcworkspace # Packages/ # Package.pins # Package.resolved +# *.xcodeproj +# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata +# hence it is not needed unless you have added a package configuration file to your project +# .swiftpm + .build/ -# Add this line if you want to avoid checking in Xcode SPM integration. -# .swiftpm/xcode # CocoaPods # We recommend against adding the Pods directory to your .gitignore. However @@ -365,19 +316,22 @@ playground.xcworkspace # Add this line if you want to avoid checking in source code from Carthage dependencies. # Carthage/Checkouts -Carthage/Build +Carthage/Build/ # Accio dependency management Dependencies/ .accio/ # fastlane -# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the -# screenshots whenever they are needed. +# It is recommended to not store the screenshots in the git repo. +# Instead, use fastlane to re-generate the screenshots whenever they are needed. # For more information about the recommended setup visit: # https://docs.fastlane.tools/best-practices/source-control/#source-control +fastlane/report.xml +fastlane/Preview.html fastlane/screenshots/**/*.png +fastlane/test_output # Code Injection # After new code Injection tools there's a generated folder /iOSInjectionProject @@ -386,16 +340,23 @@ fastlane/screenshots/**/*.png iOSInjectionProject/ ### VisualStudioCode ### -.vscode .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ ### VisualStudioCode Patch ### # Ignore all local history of files .history +.ionide + +# Support for Project snippet scope +!.vscode/*.code-snippets ### Windows ### # Windows thumbnail cache files @@ -423,122 +384,7 @@ $RECYCLE.BIN/ # Windows shortcuts *.lnk -### Xcode ### -# Xcode -# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore - -## User settings - -## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) - -## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) - -## Xcode Patch -*.xcodeproj/* -!*.xcodeproj/project.pbxproj -!*.xcodeproj/xcshareddata/ -!*.xcworkspace/contents.xcworkspacedata -/*.gcno - -### Xcode Patch ### -**/xcshareddata/WorkspaceSettings.xcsettings - -### XcodeInjection ### -# Code Injection -# After new code Injection tools there's a generated folder /iOSInjectionProject -# https://github.com/johnno1962/injectionforxcode - - -### AndroidStudio ### -# Covers files to be ignored for android development using Android Studio. - -# Built application files - -# Files for the ART/Dalvik VM - -# Java class files - -# Generated files - -# Gradle files -.gradle - -# Signing files -.signing/ - -# Local configuration file (sdk path, etc) - -# Proguard folder generated by Eclipse - -# Log Files - -# Android Studio -/*/build/ -/*/local.properties -/*/out -/*/*/build -/*/*/production -*~ -*.swp - -# Android Patch - -# External native build folder generated in Android Studio 2.2 and later - -# NDK -obj/ - -# IntelliJ IDEA -/out/ - -# User-specific configurations -.idea/caches/ -.idea/libraries/ -.idea/shelf/ -.idea/.name -.idea/compiler.xml -.idea/copyright/profiles_settings.xml -.idea/encodings.xml -.idea/scopes/scope_settings.xml -.idea/vcs.xml -.idea/jsLibraryMappings.xml -.idea/datasources.xml -.idea/dataSources.ids -.idea/sqlDataSources.xml -.idea/dynamic.xml -.idea/uiDesigner.xml - -# OS-specific files -.DS_Store? - -# Legacy Eclipse project files -.classpath -.project -.cproject -.settings/ - -# Mobile Tools for Java (J2ME) - -# Package Files # - -# virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml) - -## Plugin-specific files: - -# mpeltonen/sbt-idea plugin - -# JIRA plugin - -# Mongo Explorer plugin -.idea/mongoSettings.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) - -### AndroidStudio Patch ### - -!/gradle/wrapper/gradle-wrapper.jar - -# End of https://www.gitignore.io/api/windows,visualstudiocode,android,androidstudio,cocoapods,dart,flutter,intellij+all,kotlin,macos,swift,xcode,xcodeinjection +# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,macos,dart,flutter,intellij+all,kotlin,linux,swift,windows # Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) diff --git a/native_crypto_ios/.metadata b/native_crypto_ios/.metadata new file mode 100644 index 0000000..50d6e33 --- /dev/null +++ b/native_crypto_ios/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: cf4400006550b70f28e4b4af815151d1e74846c6 + channel: stable + +project_type: plugin diff --git a/native_crypto_ios/CHANGELOG.md b/native_crypto_ios/CHANGELOG.md new file mode 100644 index 0000000..41cc7d8 --- /dev/null +++ b/native_crypto_ios/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/LICENSE b/native_crypto_ios/LICENSE similarity index 96% rename from LICENSE rename to native_crypto_ios/LICENSE index 3a5f8fe..a9f90ec 100644 --- a/LICENSE +++ b/native_crypto_ios/LICENSE @@ -1,4 +1,4 @@ -native_crypto +NativeCrypto - iOS Implementation MIT License diff --git a/native_crypto_ios/README.md b/native_crypto_ios/README.md new file mode 100644 index 0000000..302c828 --- /dev/null +++ b/native_crypto_ios/README.md @@ -0,0 +1,15 @@ +# native_crypto_ios + +A new flutter plugin project. + +## Getting Started + +This project is a starting point for a Flutter +[plug-in package](https://flutter.dev/developing-packages/), +a specialized package that includes platform-specific implementation code for +Android and/or iOS. + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. + diff --git a/native_crypto_ios/example/.gitignore b/native_crypto_ios/example/.gitignore new file mode 100644 index 0000000..0fa6b67 --- /dev/null +++ b/native_crypto_ios/example/.gitignore @@ -0,0 +1,46 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/native_crypto_ios/example/.metadata b/native_crypto_ios/example/.metadata new file mode 100644 index 0000000..ee7f61d --- /dev/null +++ b/native_crypto_ios/example/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: cf4400006550b70f28e4b4af815151d1e74846c6 + channel: stable + +project_type: app diff --git a/native_crypto_ios/example/README.md b/native_crypto_ios/example/README.md new file mode 100644 index 0000000..340d8c1 --- /dev/null +++ b/native_crypto_ios/example/README.md @@ -0,0 +1,16 @@ +# native_crypto_ios_example + +Demonstrates how to use the native_crypto_ios plugin. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/native_crypto_ios/example/analysis_options.yaml b/native_crypto_ios/example/analysis_options.yaml new file mode 100644 index 0000000..61b6c4d --- /dev/null +++ b/native_crypto_ios/example/analysis_options.yaml @@ -0,0 +1,29 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/native_crypto_ios/example/ios/.gitignore b/native_crypto_ios/example/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/native_crypto_ios/example/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/native_crypto_ios/example/ios/Flutter/AppFrameworkInfo.plist b/native_crypto_ios/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..8d4492f --- /dev/null +++ b/native_crypto_ios/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 9.0 + + diff --git a/native_crypto_ios/example/ios/Flutter/Debug.xcconfig b/native_crypto_ios/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..ec97fc6 --- /dev/null +++ b/native_crypto_ios/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/native_crypto_ios/example/ios/Flutter/Release.xcconfig b/native_crypto_ios/example/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..c4855bf --- /dev/null +++ b/native_crypto_ios/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/native_crypto_ios/example/ios/Podfile b/native_crypto_ios/example/ios/Podfile new file mode 100644 index 0000000..1e8c3c9 --- /dev/null +++ b/native_crypto_ios/example/ios/Podfile @@ -0,0 +1,41 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/native_crypto_ios/example/ios/Podfile.lock b/native_crypto_ios/example/ios/Podfile.lock new file mode 100644 index 0000000..d6ba796 --- /dev/null +++ b/native_crypto_ios/example/ios/Podfile.lock @@ -0,0 +1,22 @@ +PODS: + - Flutter (1.0.0) + - native_crypto_ios (0.0.1): + - Flutter + +DEPENDENCIES: + - Flutter (from `Flutter`) + - native_crypto_ios (from `.symlinks/plugins/native_crypto_ios/ios`) + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + native_crypto_ios: + :path: ".symlinks/plugins/native_crypto_ios/ios" + +SPEC CHECKSUMS: + Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a + native_crypto_ios: 01f5aa926eb715d08259fd20bb951ba0f69c4e74 + +PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c + +COCOAPODS: 1.10.1 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/native_crypto_ios/example/ios/Runner.xcodeproj/project.pbxproj similarity index 88% rename from example/ios/Runner.xcodeproj/project.pbxproj rename to native_crypto_ios/example/ios/Runner.xcodeproj/project.pbxproj index 76a945e..7156cef 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/native_crypto_ios/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,17 +3,17 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 20AC864B3037BB896BD381B1 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 056766980834B5FAC1C4D331 /* Pods_Runner.framework */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - D294241BEFD2D3EF500C0577 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C6CB4DB73769DFCBF23FCC12 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -30,9 +30,11 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 056766980834B5FAC1C4D331 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1180301722C337B6C625E46F /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 2DBF05A146610778D425B9D9 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 2A0F0FD6D80A80663D317892 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -44,9 +46,7 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - C6CB4DB73769DFCBF23FCC12 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D3EC88B33A6F35C67BAC8349 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - FB0023B75BB4BD74C9F8D280 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + EC40AF9C4AC2A38A0B8CC0E6 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -54,19 +54,22 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D294241BEFD2D3EF500C0577 /* Pods_Runner.framework in Frameworks */, + 20AC864B3037BB896BD381B1 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 8C27A9C4EB5E71366C317BF8 /* Frameworks */ = { + 3024D600AF0E0DED3BB44E03 /* Pods */ = { isa = PBXGroup; children = ( - C6CB4DB73769DFCBF23FCC12 /* Pods_Runner.framework */, + EC40AF9C4AC2A38A0B8CC0E6 /* Pods-Runner.debug.xcconfig */, + 2A0F0FD6D80A80663D317892 /* Pods-Runner.release.xcconfig */, + 1180301722C337B6C625E46F /* Pods-Runner.profile.xcconfig */, ); - name = Frameworks; + name = Pods; + path = Pods; sourceTree = ""; }; 9740EEB11CF90186004384FC /* Flutter */ = { @@ -86,8 +89,8 @@ 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, - 9F5A6E791DB57C1B2E0BF33E /* Pods */, - 8C27A9C4EB5E71366C317BF8 /* Frameworks */, + 3024D600AF0E0DED3BB44E03 /* Pods */, + F589250F1A900F4BC6E4BB56 /* Frameworks */, ); sourceTree = ""; }; @@ -106,7 +109,6 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, @@ -115,21 +117,12 @@ path = Runner; sourceTree = ""; }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { + F589250F1A900F4BC6E4BB56 /* Frameworks */ = { isa = PBXGroup; children = ( + 056766980834B5FAC1C4D331 /* Pods_Runner.framework */, ); - name = "Supporting Files"; - sourceTree = ""; - }; - 9F5A6E791DB57C1B2E0BF33E /* Pods */ = { - isa = PBXGroup; - children = ( - FB0023B75BB4BD74C9F8D280 /* Pods-Runner.debug.xcconfig */, - 2DBF05A146610778D425B9D9 /* Pods-Runner.release.xcconfig */, - D3EC88B33A6F35C67BAC8349 /* Pods-Runner.profile.xcconfig */, - ); - path = Pods; + name = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ @@ -139,14 +132,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - D72ACB84F79B4AD23991D136 /* [CP] Check Pods Manifest.lock */, + CE2C3E978245C5FF80E431AC /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - FF811A27CCC4B4D5EBD756CE /* [CP] Embed Pods Frameworks */, + ED05A5A0A8AF0FA8F71C2C2B /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -163,18 +156,17 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1020; - ORGANIZATIONNAME = "The Chromium Authors"; + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; - DevelopmentTeam = 6Z5P8GG96U; LastSwiftMigration = 1100; }; }; }; buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 3.2"; + compatibilityVersion = "Xcode 9.3"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -234,7 +226,7 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - D72ACB84F79B4AD23991D136 /* [CP] Check Pods Manifest.lock */ = { + CE2C3E978245C5FF80E431AC /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -256,15 +248,17 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - FF811A27CCC4B4D5EBD756CE /* [CP] Embed Pods Frameworks */ = { + ED05A5A0A8AF0FA8F71C2C2B /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputPaths = ( + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Embed Pods Frameworks"; - outputPaths = ( + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -346,7 +340,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -364,18 +358,12 @@ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = 6Z5P8GG96U; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( + LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/Flutter", + "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = fr.pointcheval.nativeCryptoFlutterExample; + PRODUCT_BUNDLE_IDENTIFIER = fr.pointcheval.nativeCryptoIosExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -430,7 +418,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -479,11 +467,12 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -498,18 +487,12 @@ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = 6Z5P8GG96U; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( + LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/Flutter", + "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = fr.pointcheval.nativeCryptoFlutterExample; + PRODUCT_BUNDLE_IDENTIFIER = fr.pointcheval.nativeCryptoIosExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -527,18 +510,12 @@ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = 6Z5P8GG96U; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( + LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/Flutter", + "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = fr.pointcheval.nativeCryptoFlutterExample; + PRODUCT_BUNDLE_IDENTIFIER = fr.pointcheval.nativeCryptoIosExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/native_crypto_ios/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/native_crypto_ios/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/native_crypto_ios/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/native_crypto_ios/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/native_crypto_ios/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/native_crypto_ios/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/native_crypto_ios/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/native_crypto_ios/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/native_crypto_ios/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/native_crypto_ios/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/native_crypto_ios/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..c87d15a --- /dev/null +++ b/native_crypto_ios/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/native_crypto_ios/example/ios/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from example/ios/Runner.xcworkspace/contents.xcworkspacedata rename to native_crypto_ios/example/ios/Runner.xcworkspace/contents.xcworkspacedata diff --git a/native_crypto_ios/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/native_crypto_ios/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/native_crypto_ios/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/native_crypto_ios/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/native_crypto_ios/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/native_crypto_ios/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/native_crypto_ios/example/ios/Runner/AppDelegate.swift b/native_crypto_ios/example/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..70693e4 --- /dev/null +++ b/native_crypto_ios/example/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..dc9ada4 Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..28c6bf0 Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..f091b6b Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cde121 Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..d0ef06e Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..dcdc230 Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..c8f9ed8 Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..75b2d16 Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..c4df70d Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..6a84f41 Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..d0e1f58 Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/native_crypto_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/native_crypto_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/native_crypto_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/native_crypto_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/native_crypto_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/native_crypto_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/native_crypto_ios/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/native_crypto_ios/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/native_crypto_ios/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/native_crypto_ios/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/native_crypto_ios/example/ios/Runner/Base.lproj/Main.storyboard b/native_crypto_ios/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/native_crypto_ios/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/native_crypto_ios/example/ios/Runner/Info.plist b/native_crypto_ios/example/ios/Runner/Info.plist new file mode 100644 index 0000000..292a791 --- /dev/null +++ b/native_crypto_ios/example/ios/Runner/Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Native Crypto Ios + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + native_crypto_ios_example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/native_crypto_ios/example/ios/Runner/Runner-Bridging-Header.h b/native_crypto_ios/example/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/native_crypto_ios/example/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/native_crypto_ios/example/lib/main.dart b/native_crypto_ios/example/lib/main.dart new file mode 100644 index 0000000..6636074 --- /dev/null +++ b/native_crypto_ios/example/lib/main.dart @@ -0,0 +1,79 @@ +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; +import 'dart:async'; + +import 'package:flutter/services.dart'; +import 'package:native_crypto_platform_interface/native_crypto_platform_interface.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatefulWidget { + const MyApp({Key? key}) : super(key: key); + + @override + State createState() => _MyAppState(); +} + +class _MyAppState extends State { + String _platformVersion = 'Unknown'; + + @override + void initState() { + super.initState(); + initPlatformState(); + } + + // Platform messages are asynchronous, so we initialize in an async method. + Future initPlatformState() async { + NativeCryptoPlatform _nativeCryptoPlatform = NativeCryptoPlatform.instance; + String platformVersion; + // Platform messages may fail, so we use a try/catch PlatformException. + // We also handle the message potentially returning null. + Uint8List? sk = await _nativeCryptoPlatform.generateSecretKey(256); + print(sk ?? 'null'); + + Uint8List? ciphertext = await _nativeCryptoPlatform.encrypt(Uint8List.fromList("abc".codeUnits), sk!, "aes"); + print(ciphertext ?? 'null'); + + Uint8List? plaintext = await _nativeCryptoPlatform.decrypt(ciphertext!, sk, "aes"); + print(plaintext ?? 'null'); + + Uint8List? kp = await _nativeCryptoPlatform.generateKeyPair(); + print(kp!.sublist(0, 31)); + print(kp.sublist(32).length); + + Uint8List? sharedSecret = await _nativeCryptoPlatform.generateSharedSecretKey(Uint8List.fromList("salt".codeUnits), 32, kp.sublist(0, 31), kp.sublist(32), "sha256"); + + try { + platformVersion = 'Unknown platform version'; + } on PlatformException { + platformVersion = 'Failed to get platform version.'; + } + + // If the widget was removed from the tree while the asynchronous platform + // message was in flight, we want to discard the reply rather than calling + // setState to update our non-existent appearance. + if (!mounted) return; + + setState(() { + _platformVersion = platformVersion; + }); + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + appBar: AppBar( + title: const Text('Plugin example app'), + ), + body: Center( + child: Text('Running on: $_platformVersion\n'), + ), + ), + ); + } +} diff --git a/native_crypto_ios/example/pubspec.yaml b/native_crypto_ios/example/pubspec.yaml new file mode 100644 index 0000000..ab0098f --- /dev/null +++ b/native_crypto_ios/example/pubspec.yaml @@ -0,0 +1,87 @@ +name: native_crypto_ios_example +description: Demonstrates how to use the native_crypto_ios plugin. + +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +environment: + sdk: ">=2.15.0 <3.0.0" + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + flutter: + sdk: flutter + + native_crypto_ios: + # When depending on this package from a real application you should use: + # native_crypto_ios: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. + path: ../ + + native_crypto_platform_interface: + path: ../../native_crypto_platform_interface + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + flutter_lints: ^1.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/native_crypto_ios/example/test/widget_test.dart b/native_crypto_ios/example/test/widget_test.dart new file mode 100644 index 0000000..75f369c --- /dev/null +++ b/native_crypto_ios/example/test/widget_test.dart @@ -0,0 +1,27 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:native_crypto_ios_example/main.dart'; + +void main() { + testWidgets('Verify Platform version', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that platform version is retrieved. + expect( + find.byWidgetPredicate( + (Widget widget) => widget is Text && + widget.data!.startsWith('Running on:'), + ), + findsOneWidget, + ); + }); +} diff --git a/ios/.gitignore b/native_crypto_ios/ios/.gitignore similarity index 95% rename from ios/.gitignore rename to native_crypto_ios/ios/.gitignore index aa479fd..0c88507 100644 --- a/ios/.gitignore +++ b/native_crypto_ios/ios/.gitignore @@ -34,4 +34,5 @@ Icon? .tags* /Flutter/Generated.xcconfig +/Flutter/ephemeral/ /Flutter/flutter_export_environment.sh \ No newline at end of file diff --git a/ios/Assets/.gitkeep b/native_crypto_ios/ios/Assets/.gitkeep similarity index 100% rename from ios/Assets/.gitkeep rename to native_crypto_ios/ios/Assets/.gitkeep diff --git a/native_crypto_ios/ios/Classes/Cipher.swift b/native_crypto_ios/ios/Classes/Cipher.swift new file mode 100644 index 0000000..7204680 --- /dev/null +++ b/native_crypto_ios/ios/Classes/Cipher.swift @@ -0,0 +1,53 @@ +/** + * Author: Hugo Pointcheval + * Email: git@pcl.ovh + * ----- + * File: Cipher.swift + * Created Date: 25/12/2021 18:31:28 + * Last Modified: 25/12/2021 18:38:53 + * ----- + * Copyright (c) 2021 + */ + +import Foundation +import CryptoKit + +class AESCipher { + /// Encrypts plaintext with key using AES GCM + @available(iOS 13.0, *) + static func encrypt(plaintext: Data, key: Data) -> Data? { + let symmetricKey = SymmetricKey.init(data: key) + let encrypted = try? AES.GCM.seal(plaintext, using: symmetricKey) + return encrypted?.combined + } + + /// Decrypts ciphertext with key using AES GCM + @available(iOS 13.0, *) + static func decrypt(ciphertext: Data, key: Data) -> Data? { + let symmetricKey = SymmetricKey.init(data: key) + let sealedBox = try? AES.GCM.SealedBox(combined: ciphertext) + if (sealedBox == nil) { return nil } + let decryptedData = try? AES.GCM.open(sealedBox!, using: symmetricKey) + return decryptedData + } +} + +class CHACHACipher { + /// Encrypts plaintext with key using CHACHAPOLY + @available(iOS 13.0, *) + static func encrypt(plaintext: Data, key: Data) -> Data? { + let symmetricKey = SymmetricKey.init(data: key) + let encrypted = try? ChaChaPoly.seal(plaintext, using: symmetricKey) + return encrypted?.combined + } + + /// Decrypts ciphertext with key using CHACHAPOLY + @available(iOS 13.0, *) + static func decrypt(ciphertext: Data, key: Data) -> Data? { + let symmetricKey = SymmetricKey.init(data: key) + let sealedBox = try? ChaChaPoly.SealedBox(combined: ciphertext) + if (sealedBox == nil) { return nil } + let decryptedData = try? ChaChaPoly.open(sealedBox!, using: symmetricKey) + return decryptedData + } +} diff --git a/native_crypto_ios/ios/Classes/Hash.swift b/native_crypto_ios/ios/Classes/Hash.swift new file mode 100644 index 0000000..94990ec --- /dev/null +++ b/native_crypto_ios/ios/Classes/Hash.swift @@ -0,0 +1,43 @@ +/** + * Author: Hugo Pointcheval + * Email: git@pcl.ovh + * ----- + * File: Hash.swift + * Created Date: 25/12/2021 18:31:11 + * Last Modified: 25/12/2021 18:38:20 + * ----- + * Copyright (c) 2021 + */ + +import Foundation +import CommonCrypto +import CryptoKit + +enum HashAlgorithm: String { + case HashSHA256 = "sha256" + case HashSHA384 = "sha384" + case HashSHA512 = "sha512" + + var commonCrypto: UInt32 { + switch self { + case .HashSHA256: return CCPBKDFAlgorithm(kCCPRFHmacAlgSHA256) + case .HashSHA384: return CCPBKDFAlgorithm(kCCPRFHmacAlgSHA384) + case .HashSHA512: return CCPBKDFAlgorithm(kCCPRFHmacAlgSHA512) + } + } +} + +@available(iOS 13.0, *) +class Hash { + /// Hash a message with a specified HashAlgorithm + static func digest(data: Data, algorithm: HashAlgorithm) -> Data { + switch algorithm { + case .HashSHA256: + return Data(SHA256.hash(data: data)) + case .HashSHA384: + return Data(SHA384.hash(data: data)) + case .HashSHA512: + return Data(SHA512.hash(data: data)) + } + } +} diff --git a/native_crypto_ios/ios/Classes/KEM.swift b/native_crypto_ios/ios/Classes/KEM.swift new file mode 100644 index 0000000..cf3a27b --- /dev/null +++ b/native_crypto_ios/ios/Classes/KEM.swift @@ -0,0 +1,78 @@ +/** + * Author: Hugo Pointcheval + * Email: git@pcl.ovh + * ----- + * File: KEM.swift + * Created Date: 25/12/2021 18:31:48 + * Last Modified: 25/12/2021 18:40:00 + * ----- + * Copyright (c) 2021 + */ + +import Foundation +import CryptoKit + +class KeyPair { + /// Generate a keypair. + @available(iOS 13.0, *) + static func fromCurve() -> Data { + let sk = P256.KeyAgreement.PrivateKey() + var kp = sk.rawRepresentation + kp.append(contentsOf: sk.publicKey.rawRepresentation) + return kp; + } + + /// Import private key from Data + @available(iOS 13.0, *) + static func importPrivateKey(privateKey: Data) throws -> P256.KeyAgreement.PrivateKey { + let sk = try P256.KeyAgreement.PrivateKey(rawRepresentation: privateKey) + + return sk; + } + + /// Import public key from Data + @available(iOS 13.0, *) + static func importPublicKey(publicKey: Data) throws -> P256.KeyAgreement.PublicKey { + let pk = try P256.KeyAgreement.PublicKey(rawRepresentation: publicKey) + + return pk; + } +} + +class ECDH { + /// Generate a shared secret with your private key and other party public key. + @available(iOS 13.0, *) + static func generateSharedSecretKey(salt: Data, hash: HashAlgorithm, keyBytesCount: Int ,privateKey: Data, publicKey: Data) -> Data? { + let sk = try? KeyPair.importPrivateKey(privateKey: privateKey) + if (sk == nil) {return nil} + + let pk = try? KeyPair.importPublicKey(publicKey: publicKey) + if (pk == nil) {return nil} + + let secret = try? sk!.sharedSecretFromKeyAgreement(with: pk!) + + switch hash { + case .HashSHA256: + let key = secret?.hkdfDerivedSymmetricKey(using: SHA256.self, salt: salt, sharedInfo: Data(), outputByteCount: keyBytesCount) + if (key == nil) { + return nil + } else { + return Key.toBytes(key: key!) + } + case .HashSHA384: + let key = secret?.hkdfDerivedSymmetricKey(using: SHA384.self, salt: salt, sharedInfo: Data(), outputByteCount: keyBytesCount) + if (key == nil) { + return nil + } else { + return Key.toBytes(key: key!) + } + case .HashSHA512: + let key = secret?.hkdfDerivedSymmetricKey(using: SHA512.self, salt: salt, sharedInfo: Data(), outputByteCount: keyBytesCount) + if (key == nil) { + return nil + } else { + return Key.toBytes(key: key!) + } + } + } +} diff --git a/native_crypto_ios/ios/Classes/Key.swift b/native_crypto_ios/ios/Classes/Key.swift new file mode 100644 index 0000000..b113df5 --- /dev/null +++ b/native_crypto_ios/ios/Classes/Key.swift @@ -0,0 +1,62 @@ +/** + * Author: Hugo Pointcheval + * Email: git@pcl.ovh + * ----- + * File: KDF.swift + * Created Date: 25/12/2021 17:45:28 + * Last Modified: 25/12/2021 17:45:38 + * ----- + * Copyright (c) 2021 + */ + +import Foundation +import CryptoKit +import CommonCrypto + +class Key { + /// Generate secret key of a specified length + @available(iOS 13.0, *) + static func fromSecureRandom(bitsCount : Int) -> Data { + let symmetricKey = SymmetricKey.init(size: SymmetricKeySize(bitCount: bitsCount)) + return toBytes(key: symmetricKey) + } + + /// Encode key as Data + @available(iOS 13.0, *) + static func toBytes(key: SymmetricKey) -> Data { + let keyBytes = key.withUnsafeBytes + { + return Data(Array($0)) + } + return keyBytes + } + + /// Derive a new secret key with PBKDF2 algorithm + static func fromPBKDF2(password: String, salt: String, keyBytesCount: Int, iterations: Int, algorithm: HashAlgorithm) -> Data? { + let passwordData = password.data(using: .utf8)! + let saltData = salt.data(using: .utf8)! + + var derivedKeyData = Data(repeating: 0, count: keyBytesCount) + let localDerivedKeyData = derivedKeyData + + let status = derivedKeyData.withUnsafeMutableBytes { (derivedKeyBytes: UnsafeMutableRawBufferPointer) in + saltData.withUnsafeBytes { (saltBytes: UnsafeRawBufferPointer) in + CCKeyDerivationPBKDF( + CCPBKDFAlgorithm(kCCPBKDF2), + password, + passwordData.count, + saltBytes.bindMemory(to: UInt8.self).baseAddress, + saltData.count, + algorithm.commonCrypto, + UInt32(iterations), + derivedKeyBytes.bindMemory(to: UInt8.self).baseAddress, + localDerivedKeyData.count) + } + } + if (status != kCCSuccess) { + return nil; + } + + return derivedKeyData + } +} diff --git a/native_crypto_ios/ios/Classes/NativeCryptoIosPlugin.h b/native_crypto_ios/ios/Classes/NativeCryptoIosPlugin.h new file mode 100644 index 0000000..4fa1376 --- /dev/null +++ b/native_crypto_ios/ios/Classes/NativeCryptoIosPlugin.h @@ -0,0 +1,4 @@ +#import + +@interface NativeCryptoIosPlugin : NSObject +@end diff --git a/ios/Classes/NativeCryptoPlugin.m b/native_crypto_ios/ios/Classes/NativeCryptoIosPlugin.m similarity index 52% rename from ios/Classes/NativeCryptoPlugin.m rename to native_crypto_ios/ios/Classes/NativeCryptoIosPlugin.m index c674cf7..e252c0b 100644 --- a/ios/Classes/NativeCryptoPlugin.m +++ b/native_crypto_ios/ios/Classes/NativeCryptoIosPlugin.m @@ -1,15 +1,15 @@ -#import "NativeCryptoPlugin.h" -#if __has_include() -#import +#import "NativeCryptoIosPlugin.h" +#if __has_include() +#import #else // Support project import fallback if the generated compatibility header // is not copied when this plugin is created as a library. // https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 -#import "native_crypto-Swift.h" +#import "native_crypto_ios-Swift.h" #endif -@implementation NativeCryptoPlugin +@implementation NativeCryptoIosPlugin + (void)registerWithRegistrar:(NSObject*)registrar { - [SwiftNativeCryptoPlugin registerWithRegistrar:registrar]; + [SwiftNativeCryptoIosPlugin registerWithRegistrar:registrar]; } @end diff --git a/native_crypto_ios/ios/Classes/SwiftNativeCryptoIosPlugin.swift b/native_crypto_ios/ios/Classes/SwiftNativeCryptoIosPlugin.swift new file mode 100644 index 0000000..00fdbb7 --- /dev/null +++ b/native_crypto_ios/ios/Classes/SwiftNativeCryptoIosPlugin.swift @@ -0,0 +1,95 @@ +import Flutter +import UIKit + +@available(iOS 13.0, *) +public class SwiftNativeCryptoIosPlugin: NSObject, FlutterPlugin { + public static func register(with registrar: FlutterPluginRegistrar) { + let channel = FlutterMethodChannel(name: "plugins.hugop.cl/native_crypto", binaryMessenger: registrar.messenger()) + let instance = SwiftNativeCryptoIosPlugin() + registrar.addMethodCallDelegate(instance, channel: channel) + } + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + switch call.method { + case "digest": + let args : NSDictionary = call.arguments as! NSDictionary + + let data : Data = (args["data"] as! FlutterStandardTypedData).data + let algo : String = args["algorithm"] as! String + let algorithm : HashAlgorithm? = HashAlgorithm.init(rawValue: algo) + // TODO(hpcl): check if algorithm is null + // TODO(hpcl): check if digest is null + result(FlutterStandardTypedData.init(bytes: Hash.digest(data: data, algorithm: algorithm!))) + case "generateSecretKey": + let args : NSDictionary = call.arguments as! NSDictionary + + let bitsCount : NSNumber = args["bitsCount"] as! NSNumber + // TODO(hpcl): check if secure random is null + result(FlutterStandardTypedData.init(bytes: Key.fromSecureRandom(bitsCount: bitsCount.intValue))) + case "generateKeyPair": + result(FlutterStandardTypedData.init(bytes: KeyPair.fromCurve())) + case "pbkdf2": + let args : NSDictionary = call.arguments as! NSDictionary + + let password : String = args["password"] as! String + let salt : String = args["salt"] as! String + let keyBytesCount : NSNumber = args["keyBytesCount"] as! NSNumber + let iterations : NSNumber = args["iterations"] as! NSNumber + let algo : String = args["algorithm"] as! String + let algorithm : HashAlgorithm? = HashAlgorithm.init(rawValue: algo) + // TODO(hpcl): check if algorithm is null + // TODO(hpcl): check if derivation is null + result(FlutterStandardTypedData.init(bytes: Key.fromPBKDF2(password: password, salt: salt, keyBytesCount: keyBytesCount.intValue, iterations: iterations.intValue, algorithm: algorithm!)!)) + case "encrypt": + let args : NSDictionary = call.arguments as! NSDictionary + + let data : Data = (args["data"] as! FlutterStandardTypedData).data + let key : Data = (args["key"] as! FlutterStandardTypedData).data + let algo : String = args["algorithm"] as! String + // TODO(hpcl): check if algorithm is null + // TODO(hpcl): check if ciphertext is null + var ciphertext : Data + switch algo { + case "aes": + ciphertext = AESCipher.encrypt(plaintext: data, key: key)! + case "chachapoly": + ciphertext = CHACHACipher.encrypt(plaintext: data, key: key)! + default: + ciphertext = Data.init(); + } + result(FlutterStandardTypedData.init(bytes: ciphertext)) + case "decrypt": + let args : NSDictionary = call.arguments as! NSDictionary + + let data : Data = (args["data"] as! FlutterStandardTypedData).data + let key : Data = (args["key"] as! FlutterStandardTypedData).data + let algo : String = args["algorithm"] as! String + // TODO(hpcl): check if algorithm is null + // TODO(hpcl): check if ciphertext is null + var ciphertext : Data + switch algo { + case "aes": + ciphertext = AESCipher.decrypt(ciphertext: data, key: key)! + case "chachapoly": + ciphertext = CHACHACipher.decrypt(ciphertext: data, key: key)! + default: + ciphertext = Data.init(); + } + result(FlutterStandardTypedData.init(bytes: ciphertext)) + case "generateSharedSecretKey": + let args : NSDictionary = call.arguments as! NSDictionary + + let salt : Data = (args["salt"] as! FlutterStandardTypedData).data + let keyBytesCount : NSNumber = args["keyBytesCount"] as! NSNumber + let ephemeralPrivateKey : Data = (args["ephemeralPrivateKey"] as! FlutterStandardTypedData).data + let otherPublicKey : Data = (args["otherPublicKey"] as! FlutterStandardTypedData).data + let hkdfAlgorithm : String = args["hkdfAlgorithm"] as! String + let algorithm : HashAlgorithm? = HashAlgorithm.init(rawValue: hkdfAlgorithm) + // TODO(hpcl): check if algorithm is null + // TODO(hpcl): check if generated key is null + result(FlutterStandardTypedData.init(bytes: ECDH.generateSharedSecretKey(salt: salt, hash: algorithm!, keyBytesCount: keyBytesCount.intValue, privateKey: ephemeralPrivateKey, publicKey: otherPublicKey)!)) + + default: result(FlutterMethodNotImplemented) + } + } +} diff --git a/ios/native_crypto.podspec b/native_crypto_ios/ios/native_crypto_ios.podspec similarity index 63% rename from ios/native_crypto.podspec rename to native_crypto_ios/ios/native_crypto_ios.podspec index 0ff9ea5..3701f76 100644 --- a/ios/native_crypto.podspec +++ b/native_crypto_ios/ios/native_crypto_ios.podspec @@ -1,9 +1,9 @@ # # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. -# Run `pod lib lint native_crypto.podspec' to validate before publishing. +# Run `pod lib lint native_crypto_ios.podspec` to validate before publishing. # Pod::Spec.new do |s| - s.name = 'native_crypto' + s.name = 'native_crypto_ios' s.version = '0.0.1' s.summary = 'A new flutter plugin project.' s.description = <<-DESC @@ -15,9 +15,9 @@ A new flutter plugin project. s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.dependency 'Flutter' - s.platform = :ios, '8.0' + s.platform = :ios, '13.0' - # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } + # Flutter.framework does not contain a i386 slice. + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } s.swift_version = '5.0' end diff --git a/native_crypto_ios/pubspec.yaml b/native_crypto_ios/pubspec.yaml new file mode 100644 index 0000000..211e4de --- /dev/null +++ b/native_crypto_ios/pubspec.yaml @@ -0,0 +1,22 @@ +name: native_crypto_ios +description: iOS implementation of NativeCrypto +version: 0.0.7 + +environment: + sdk: ">=2.15.0 <3.0.0" + flutter: ">=2.5.0" + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + +flutter: + plugin: + implements: native_crypto + platforms: + ios: + pluginClass: NativeCryptoIosPlugin \ No newline at end of file diff --git a/native_crypto_platform_interface/.gitignore b/native_crypto_platform_interface/.gitignore new file mode 100644 index 0000000..23f216c --- /dev/null +++ b/native_crypto_platform_interface/.gitignore @@ -0,0 +1,390 @@ +# File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig + +# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,macos,dart,flutter,intellij+all,kotlin,linux,swift,windows +# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,macos,dart,flutter,intellij+all,kotlin,linux,swift,windows + +### Dart ### +# See https://www.dartlang.org/guides/libraries/private-files + +# Files and directories created by pub +.dart_tool/ +.packages +build/ +# If you're building an application, you may want to check-in your pubspec.lock +pubspec.lock + +# Directory created by dartdoc +# If you don't generate documentation locally you can remove this line. +doc/api/ + +# dotenv environment variables file +.env* + +# Avoid committing generated Javascript files: +*.dart.js +*.info.json # Produced by the --dump-info flag. +*.js # When generated by dart2js. Don't specify *.js if your + # project includes source files written in JavaScript. +*.js_ +*.js.deps +*.js.map + +.flutter-plugins +.flutter-plugins-dependencies + +### Dart Patch ### +# dotenv environment variables file +.env + +### Flutter ### +# Flutter/Dart/Pub related +**/doc/api/ +.fvm/ +.pub-cache/ +.pub/ +coverage/ +lib/generated_plugin_registrant.dart +# For library packages, don’t commit the pubspec.lock file. +# Regenerating the pubspec.lock file lets you test your package against the latest compatible versions of its dependencies. +# See https://dart.dev/guides/libraries/private-files#pubspeclock +#pubspec.lock + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/key.properties +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/.last_build_id +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages + +### Intellij+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Intellij+all Patch ### +# Ignores the whole .idea folder and all .iml files +# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 + +.idea/ + +# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 + +*.iml +modules.xml +.idea/misc.xml +*.ipr + +# Sonarlint plugin +.idea/sonarlint + +### Kotlin ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Swift ### +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## User settings +xcuserdata/ + +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) +*.xcscmblueprint +*.xccheckout + +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) +DerivedData/ +*.moved-aside +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 + +## Obj-C/Swift specific +*.hmap + +## App packaging +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +# *.xcodeproj +# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata +# hence it is not needed unless you have added a package configuration file to your project +# .swiftpm + +.build/ + +# CocoaPods +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# Pods/ +# Add this line if you want to avoid checking in source code from the Xcode workspace +# *.xcworkspace + +# Carthage +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build/ + +# Accio dependency management +Dependencies/ +.accio/ + +# fastlane +# It is recommended to not store the screenshots in the git repo. +# Instead, use fastlane to re-generate the screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output + +# Code Injection +# After new code Injection tools there's a generated folder /iOSInjectionProject +# https://github.com/johnno1962/injectionforxcode + +iOSInjectionProject/ + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +# Support for Project snippet scope +!.vscode/*.code-snippets + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,macos,dart,flutter,intellij+all,kotlin,linux,swift,windows + +# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) + diff --git a/native_crypto_platform_interface/.metadata b/native_crypto_platform_interface/.metadata new file mode 100644 index 0000000..50d6e33 --- /dev/null +++ b/native_crypto_platform_interface/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: cf4400006550b70f28e4b4af815151d1e74846c6 + channel: stable + +project_type: plugin diff --git a/native_crypto_platform_interface/CHANGELOG.md b/native_crypto_platform_interface/CHANGELOG.md new file mode 100644 index 0000000..41cc7d8 --- /dev/null +++ b/native_crypto_platform_interface/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/native_crypto_platform_interface/LICENSE b/native_crypto_platform_interface/LICENSE new file mode 100644 index 0000000..ba75c69 --- /dev/null +++ b/native_crypto_platform_interface/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/native_crypto_platform_interface/README.md b/native_crypto_platform_interface/README.md new file mode 100644 index 0000000..7190aa2 --- /dev/null +++ b/native_crypto_platform_interface/README.md @@ -0,0 +1,18 @@ +# native_crypto_platform_interface + +A new flutter plugin project. + +## Getting Started + +This project is a starting point for a Flutter +[plug-in package](https://flutter.dev/developing-packages/), +a specialized package that includes platform-specific implementation code for +Android and/or iOS. + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. + +The plugin project was generated without specifying the `--platforms` flag, no platforms are currently supported. +To add platforms, run `flutter create -t plugin --platforms .` under the same +directory. You can also find a detailed instruction on how to add platforms in the `pubspec.yaml` at https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin-platforms. diff --git a/native_crypto_platform_interface/analysis_options.yaml b/native_crypto_platform_interface/analysis_options.yaml new file mode 100644 index 0000000..a5744c1 --- /dev/null +++ b/native_crypto_platform_interface/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/native_crypto_platform_interface/lib/native_crypto_platform_interface.dart b/native_crypto_platform_interface/lib/native_crypto_platform_interface.dart new file mode 100644 index 0000000..1d6fbd5 --- /dev/null +++ b/native_crypto_platform_interface/lib/native_crypto_platform_interface.dart @@ -0,0 +1,75 @@ +// Author: Hugo Pointcheval +// Email: git@pcl.ovh +// ----- +// File: native_crypto_platform_interface.dart +// Created Date: 25/12/2021 16:43:49 +// Last Modified: 25/12/2021 17:39:39 +// ----- +// Copyright (c) 2021 + +import 'dart:typed_data'; + +import './src/method_channel_native_crypto.dart'; +import './src/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 [MethodChannelPathProvider]. + 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.verifyToken(instance, _token); + _instance = instance; + } + + Future digest(Uint8List data, String algorithm) { + throw UnimplementedError('digest is not implemented'); + } + + Future generateSecretKey(int bitsCount) { + throw UnimplementedError('generateSecretKey is not implemented'); + } + + Future generateKeyPair() { + throw UnimplementedError('generateKeyPair is not implemented'); + } + + Future pbkdf2(String password, String salt, int keyBytesCount, + int iterations, String algorithm) { + throw UnimplementedError('pbkdf2 is not implemented'); + } + + Future encrypt(Uint8List data, Uint8List key, String algorithm) { + throw UnimplementedError('encrypt is not implemented'); + } + + Future decrypt(Uint8List data, Uint8List key, String algorithm) { + throw UnimplementedError('decrypt is not implemented'); + } + + Future generateSharedSecretKey( + Uint8List salt, + int keyBytesCount, + Uint8List ephemeralPrivateKey, + Uint8List otherPublicKey, + String hkdfAlgorithm) { + throw UnimplementedError('generateSharedSecretKey is not implemented'); + } +} diff --git a/native_crypto_platform_interface/lib/src/method_channel_native_crypto.dart b/native_crypto_platform_interface/lib/src/method_channel_native_crypto.dart new file mode 100644 index 0000000..3cab922 --- /dev/null +++ b/native_crypto_platform_interface/lib/src/method_channel_native_crypto.dart @@ -0,0 +1,107 @@ +// Author: Hugo Pointcheval +// Email: git@pcl.ovh +// ----- +// File: native_crypto_method_channel.dart +// Created Date: 25/12/2021 16:58:04 +// Last Modified: 25/12/2021 18:58:53 +// ----- +// Copyright (c) 2021 + +import 'dart:typed_data'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; + +import '../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 methodChannel = + const MethodChannel('plugins.hugop.cl/native_crypto'); + + @override + Future digest(Uint8List data, String algorithm) { + return methodChannel.invokeMethod( + 'digest', + { + 'data': data, + 'algorithm': algorithm, + }, + ); + } + + @override + Future generateSecretKey(int bitsCount) { + return methodChannel.invokeMethod( + 'generateSecretKey', + { + 'bitsCount': bitsCount, + }, + ); + } + + @override + Future generateKeyPair() { + return methodChannel.invokeMethod('generateKeyPair'); + } + + @override + Future pbkdf2(String password, String salt, int keyBytesCount, + int iterations, String algorithm) { + return methodChannel.invokeMethod( + 'pbkdf2', + { + 'password': password, + 'salt': salt, + 'keyBytesCount': keyBytesCount, + 'iterations': iterations, + 'algorithm': algorithm, + }, + ); + } + + @override + Future encrypt(Uint8List data, Uint8List key, String algorithm) { + return methodChannel.invokeMethod( + 'encrypt', + { + 'data': data, + 'key': key, + 'algorithm': algorithm, + }, + ); + } + + @override + Future decrypt(Uint8List data, Uint8List key, String algorithm) { + return methodChannel.invokeMethod( + 'decrypt', + { + 'data': data, + 'key': key, + 'algorithm': algorithm, + }, + ); + } + + @override + Future generateSharedSecretKey( + Uint8List salt, + int keyBytesCount, + Uint8List ephemeralPrivateKey, + Uint8List otherPublicKey, + String hkdfAlgorithm) { + return methodChannel.invokeMethod( + 'generateSharedSecretKey', + { + 'salt': salt, + 'keyBytesCount': keyBytesCount, + 'ephemeralPrivateKey': ephemeralPrivateKey, + 'otherPublicKey': otherPublicKey, + 'hkdfAlgorithm': hkdfAlgorithm, + }, + ); + } +} diff --git a/native_crypto_platform_interface/lib/src/platform_interface.dart b/native_crypto_platform_interface/lib/src/platform_interface.dart new file mode 100644 index 0000000..d0585c9 --- /dev/null +++ b/native_crypto_platform_interface/lib/src/platform_interface.dart @@ -0,0 +1,97 @@ +// Author: Hugo Pointcheval +// Email: git@pcl.ovh +// ----- +// File: platform_interface.dart +// Created Date: 25/12/2021 16:52:56 +// Last Modified: 25/12/2021 16:53:36 +// ----- +// Copyright (c) 2021 + +import 'package:meta/meta.dart'; + +/// Base class for platform interfaces. +/// +/// Provides a static helper method for ensuring that platform interfaces are +/// implemented using `extends` instead of `implements`. +/// +/// Platform interface classes are expected to have a private static token object which will be +/// be passed to [verifyToken] along with a platform interface object for verification. +/// +/// Sample usage: +/// +/// ```dart +/// abstract class UrlLauncherPlatform extends PlatformInterface { +/// UrlLauncherPlatform() : super(token: _token); +/// +/// static UrlLauncherPlatform _instance = MethodChannelUrlLauncher(); +/// +/// static const Object _token = Object(); +/// +/// static UrlLauncherPlatform get instance => _instance; +/// +/// /// Platform-specific plugins should set this with their own platform-specific +/// /// class that extends [UrlLauncherPlatform] when they register themselves. +/// static set instance(UrlLauncherPlatform instance) { +/// PlatformInterface.verifyToken(instance, _token); +/// _instance = instance; +/// } +/// +/// } +/// ``` +/// +/// Mockito mocks of platform interfaces will fail the verification, in test code only it is possible +/// to include the [MockPlatformInterfaceMixin] for the verification to be temporarily disabled. See +/// [MockPlatformInterfaceMixin] for a sample of using Mockito to mock a platform interface. +abstract class PlatformInterface { + /// Pass a private, class-specific `const Object()` as the `token`. + PlatformInterface({required Object token}) : _instanceToken = token; + + final Object? _instanceToken; + + /// Ensures that the platform instance has a token that matches the + /// provided token and throws [AssertionError] if not. + /// + /// This is used to ensure that implementers are using `extends` rather than + /// `implements`. + /// + /// Subclasses of [MockPlatformInterfaceMixin] are assumed to be valid in debug + /// builds. + /// + /// This is implemented as a static method so that it cannot be overridden + /// with `noSuchMethod`. + static void verifyToken(PlatformInterface instance, Object token) { + if (instance is MockPlatformInterfaceMixin) { + bool assertionsEnabled = false; + assert(() { + assertionsEnabled = true; + return true; + }()); + if (!assertionsEnabled) { + throw AssertionError( + '`MockPlatformInterfaceMixin` is not intended for use in release builds.'); + } + return; + } + if (!identical(token, instance._instanceToken)) { + throw AssertionError( + 'Platform interfaces must not be implemented with `implements`'); + } + } +} + +/// A [PlatformInterface] mixin that can be combined with mockito's `Mock`. +/// +/// It passes the [PlatformInterface.verifyToken] check even though it isn't +/// using `extends`. +/// +/// This class is intended for use in tests only. +/// +/// Sample usage (assuming UrlLauncherPlatform extends [PlatformInterface]: +/// +/// ```dart +/// class UrlLauncherPlatformMock extends Mock +/// with MockPlatformInterfaceMixin +/// implements UrlLauncherPlatform {} +/// ``` +@visibleForTesting +abstract class MockPlatformInterfaceMixin implements PlatformInterface {} \ No newline at end of file diff --git a/native_crypto_platform_interface/pubspec.yaml b/native_crypto_platform_interface/pubspec.yaml new file mode 100644 index 0000000..017ea35 --- /dev/null +++ b/native_crypto_platform_interface/pubspec.yaml @@ -0,0 +1,17 @@ +name: native_crypto_platform_interface +description: A common interface for NativeCrypto plugin. +version: 0.0.7 + +environment: + sdk: ">=2.15.0 <3.0.0" + flutter: ">=2.5.0" + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + + flutter_lints: ^1.0.4 \ No newline at end of file diff --git a/native_crypto_platform_interface/test/native_crypto_platform_interface_test.dart b/native_crypto_platform_interface/test/native_crypto_platform_interface_test.dart new file mode 100644 index 0000000..e69de29 diff --git a/pubspec.yaml b/pubspec.yaml deleted file mode 100644 index 431d835..0000000 --- a/pubspec.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: native_crypto -description: Fast crypto functions for Flutter. -version: 0.0.6 -author: Hugo Pointcheval -homepage: https://hugo.pointcheval.fr - -environment: - sdk: ">=2.6.0 <3.0.0" - -dependencies: - flutter: - sdk: flutter - -dev_dependencies: - flutter_test: - sdk: flutter - -flutter: - plugin: - androidPackage: fr.pointcheval.native_crypto - pluginClass: NativeCryptoPlugin \ No newline at end of file