diff --git a/CHANGELOG.md b/CHANGELOG.md index 90d2690..0a405c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +# freeRASP 4.0.0 +A new round of fixes and improvements! Here's the list of all the new things we included in the latest release. + +## What's new in 4.0.0? +- ❗ BREAKING API CHANGE: Added multi-signature support for certificate hashes of Android apps +- ✔️ Fixed `NullPointerException` in RootDetector when there are no running processes ([issue](https://github.com/talsec/Free-RASP-Flutter/issues/40)) on Android +- ✔️ Removed deprecated SafetyNet dependency ([issue](https://github.com/talsec/Free-RASP-Flutter/issues/28)) on Android +- ✔️ Fixed the ANR issue ([issue](https://github.com/talsec/Free-RASP-Flutter/issues/32)) on Android +- ✔️ Updated HMS and GMS dependencies on Android +- 🔎 Improved detection of BlueStacks and Nox emulators ([issue](https://github.com/talsec/Free-RASP-Android/issues/6)) on Android +- ❗ Improved device binding detection to not trigger for moving the app to a new device on iOS +- ⚡ Improved hook detection and logging on iOS +- 🔎 Improved logging of non-existing hardware for biometrics on iOS + # freeRASP 3.0.2 We are constantly listening to our community to make freeRASP better. This update contain fixes to [reported issues](https://github.com/talsec/Free-RASP-Flutter/issues). diff --git a/README.md b/README.md index 6751ddd..f719a6f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![FreeRasp](https://raw.githubusercontent.com/talsec/Free-RASP-Community/master/visuals/freeRASP.png) -![GitHub Repo stars](https://img.shields.io/github/stars/talsec/Free-RASP-Community?color=green) ![Likes](https://img.shields.io/pub/likes/freerasp?color=green!) ![Likes](https://img.shields.io/pub/points/freerasp) ![GitHub](https://img.shields.io/github/license/talsec/Free-RASP-Community) ![GitHub](https://img.shields.io/github/last-commit/talsec/Free-RASP-Community) [![extra_pedantic on pub.dev](https://img.shields.io/badge/style-extra__pedantic-blue)](https://pub.dev/packages/extra_pedantic) +![GitHub Repo stars](https://img.shields.io/github/stars/talsec/Free-RASP-Community?color=green) ![Likes](https://img.shields.io/pub/likes/freerasp?color=green!) ![Likes](https://img.shields.io/pub/points/freerasp) ![GitHub](https://img.shields.io/github/license/talsec/Free-RASP-Community) ![GitHub](https://img.shields.io/github/last-commit/talsec/Free-RASP-Community) [![style: very good analysis](https://img.shields.io/badge/style-very_good_analysis-B22C89.svg)](https://pub.dev/packages/very_good_analysis) ![Publisher](https://img.shields.io/pub/publisher/freerasp) # freeRASP for Flutter @@ -18,12 +18,12 @@ freeRASP for Flutter is a mobile in-app protection and security monitoring SDK. * [Handle detected threats](#step-3-handle-detected-threats) - [Troubleshooting](#troubleshooting) - [Security Report](#security-report) -- [Enterprise Services](#enterprise-services) +- [Enterprise Services](#bar_chart-enterprise-services) * [Plans comparison](#plans-comparison) # Overview -The freeRASP is available for Flutter, Cordova, Android, and iOS developers. We encourage community contributions, investigations of attack cases, joint data research, and other activities aiming to make better app security and app safety for end-users. +The freeRASP is available for Flutter, Android, and iOS developers. We encourage community contributions, investigations of attack cases, joint data research, and other activities aiming to make better app security and app safety for end-users. freeRASP SDK is designed to combat @@ -66,7 +66,7 @@ Add dependency to your `pubspec.yaml` file ```yaml dependencies: - freerasp: 3.0.2 + freerasp: 4.0.0 ``` and run `pub get` @@ -143,12 +143,11 @@ defaultConfig { ``` ### Dev vs Release version -The Dev version is used to not complicate the development process of the application, e.g. if you would implement killing of the application on the debugger callback. It disables some checks which won't be triggered during the development process: +The Dev version is used during the development of the application. It separates development and production data and disables some checks which won't be triggered during the development process: * Emulator-usage (onEmulatorDetected, onSimulatorDetected) * Debugging (onDebuggerDetected) * Signing (onTamperDetected, onSignatureDetected) -* Unofficial store (onUntrustedInstallationDetected, onUnofficialStoreDetected) Which version of freeRASP is used is tied to the application's development stage - more precisely, how the application is compiled. @@ -188,7 +187,7 @@ class _MyAppState extends State { and then create a Talsec config and insert `AndroidConfig` and/or `IOSConfig` with highlighted identifiers: `expectedPackageName` and `expectedSigningCertificateHash` are needed for Android version. * `expectedPackageName` - package name of your app you chose when you created it -* `expectedSigningCertificateHash` - hash of the certificate of the key which was used to sign the application. **Hash which is passed here must be encoded in Base64 form** +* `expectedSigningCertificateHashes` - list of hashes of the certificates of the keys which were used to sign the application. At least one hash value must be provided. **Hashes which are passed here must be encoded in Base64 form** We provide a handy util tool to help you convert your SHA-256 hash to Base64: @@ -198,9 +197,9 @@ We provide a handy util tool to help you convert your SHA-256 hash to Base64: String base64Hash = hashConverter.fromSha256toBase64(sha256HashHex); ``` -We strongly recommend providing **result value** of this tool as expectedSigningCertificateHash. +We strongly recommend using **result value** of this tool in expectedSigningCertificateHashes. -**Do not use this tool directly** in `expectedSigningCertificateHash` to get value. +**Do not use this tool directly** in `expectedSigningCertificateHashes` to get value. If you are not sure how to get your hash certificate, you can check out the guide on our [Github wiki](https://github.com/talsec/Free-RASP-Community/wiki/Getting-your-signing-certificate-hash-of-app). @@ -223,7 +222,7 @@ Future initSecurityState() async { // For Android androidConfig: AndroidConfig( expectedPackageName: 'YOUR_PACKAGE_NAME', - expectedSigningCertificateHash: 'HASH_OF_YOUR_APP', + expectedSigningCertificateHashes: ['HASH_OF_YOUR_APP'], supportedAlternativeStores: ["com.sec.android.app.samsungapps"], ), @@ -241,10 +240,7 @@ Future initSecurityState() async { ## Step 3: Handle detected threats -Create `AndroidCallback` and/or `IOSCallback` objects and provide `VoidCallback` function pointers to handle detected threats. If you are developing only for one of the platforms, you can leave the callback definition for the other one, i.e., delete the other callback definition. - -You can provide a function (or an anonymous function like in this example) to tell Talsec what to do. If you decide to kill the application from the callback, make sure that you use an appropriate way of killing it (see the [link](https://stackoverflow.com/questions/45109557/flutter-how-to-programmatically-exit-the-app)). - +Create `AndroidCallback` and/or `IOSCallback` objects and provide `VoidCallback` function pointers to handle detected threats: ```dart @override void initState() { @@ -278,6 +274,7 @@ void initState() { ); } ``` +If you are developing only for one of the platforms, you can leave the callback definition for the other one, i.e., delete the other callback definition. Visit our [wiki](https://github.com/talsec/Free-RASP-Community/wiki/Threat-detection) to learn more details about the performed checks and their importance for app security. @@ -301,11 +298,6 @@ void initState() { } ``` -If you are initializing Talsec from the main() function before runApp(), make sure that you place the following before initialization of the Talsec: -```dart -WidgetsFlutterBinding.ensureInitialized(); -``` - ## Step 5: User Data Policies Google Play [requires](https://support.google.com/googleplay/android-developer/answer/10787469?hl=en) all app publishers to declare how they collect and handle user data for the apps they publish on Google Play. They should inform users properly of the data collected by the apps and how the data is shared and processed. Therefore, Google will reject the apps which do not comply with the policy. @@ -353,13 +345,12 @@ Add this rule to your `proguard-rules.pro` file: ``` -keepclasseswithmembernames,includedescriptorclasses class * { -native *; +native ; } ``` ### \[iOS] Building using Codemagic fails: `No such module 'TalsecRuntime'` -**Solution:** You have to adjust Codemagic building pipeline. Instructions how to do it are [here](https://github.com/talsec/Free-RASP-Flutter/issues/22#issuecomment-1383964470). - + **Solution:** You have to adjust Codemagic building pipeline. Instructions how to do it are [here](https://github.com/talsec/Free-RASP-Flutter/issues/22#issuecomment-1383964470). If you encounter any other issues, you can see the list of solved issues [here](https://github.com/talsec/Free-RASP-Flutter/issues?q=is%3Aissue+is%3Aclosed), or open up a [new one](https://github.com/talsec/Free-RASP-Flutter/issues?q=is%3Aopen+is%3Aissue). @@ -373,12 +364,26 @@ To receive Security Reports, fill out the _watcherMail_ field in [Talsec config] ![enter image description here](https://raw.githubusercontent.com/talsec/Free-RASP-Community/master/visuals/dashboard.png) -# Enterprise Services +# :bar_chart: Enterprise Services +We provide app security hardening SDK: i.e. AppiCrypt®, Customer Data Encryption (local storage), End-to-end encryption, Strings protection (e.g. API keys) and Dynamic Certificate Pinning to our commercial customers as well. To get the most advanced protection compliant with PSD2 RT and eIDAS and support from our experts, contact us at [talsec.app](https://talsec.app). + +## Commercial version +The commercial version provides a top-notch protection level, extra features, support, and maintenance. One of the most valued commercial features is [AppiCrypt®](https://www.talsec.app/appicrypt) - App Integrity Cryptogram. -We provide extended services (AppiCrypt, Hardening, Secure Storage, and Certificate Pinning) to our commercial customers as well. To get the most advanced protection compliant with PSD2 RT and eIDAS and support from our experts, contact us at [talsec.app](https://talsec.app). +It allows easy to implement API protection and App Integrity verification on the backend to prevent API abuse: + +- Bruteforce attacks +- Botnets +- Session-hijacking +- DDoS + +It is a unified solution that works across all mobile platforms without dependency on external web services (i.e., without extra latency, an additional point of failure, and maintenance costs). + +Learn more about commercial features at [https://talsec.app](https://talsec.app/). **TIP:** You can try freeRASP and then upgrade easily to an enterprise service. + ## Plans Comparison @@ -386,7 +391,7 @@ We provide extended services (AppiCrypt, Hardening, Secure Storage, and Certific - + @@ -403,7 +408,7 @@ We provide extended services (AppiCrypt, Hardening, Secure Storage, and Certific
  • Debug
  • Emulator
  • -
  • Hooking protections
  • +
  • Hooking protections (e.g. Frida)
@@ -415,6 +420,7 @@ We provide extended services (AppiCrypt, Hardening, Secure Storage, and Certific
  • Tamper protection
  • Repackaging / Cloning protection
  • Device binding protection
  • +
  • Unofficial store detection
  • @@ -424,8 +430,7 @@ We provide extended services (AppiCrypt, Hardening, Secure Storage, and Certific @@ -447,23 +452,23 @@ We provide extended services (AppiCrypt, Hardening, Secure Storage, and Certific - - - - - - - - + + + + + + + + @@ -487,5 +492,19 @@ We provide extended services (AppiCrypt, Hardening, Secure Storage, and Certific + + + + + + + + + + + +
    freeRASPBusinessBusiness RASP+
    basic basicDevice OS security status check
    • HW security module control
    • -
    • Device lock control
    • -
    • Device lock change control
    • +
    • Screen lock control
    yes
    Security hardening suite
      +
    • Customer Data Encryption (local storage)
    • +
    • End-to-end encryption
    • +
    • Strings protection (e.g. API keys)
    • Dynamic certificate pinning
    • -
    • Obfuscation
    • -
    • Secure storage hardening
    • -
    • Secure pinpad
    no yes
    AppiCrypt® - App Integrity Cryptogram
    API protection by mobile client integrity check, online risk scoring, online fraud prevention, client App integrity check. The cryptographic proof of app & device integrity.noyes
    AppiCrypt® - App Integrity Cryptogram
    API protection by mobile client integrity check, online risk scoring, online fraud prevention, client App integrity check. The cryptographic proof of app & device integrity.noyes
    Monitoring
    no yes
    Fair usage policy
    Mentioning of the app name in Talsec marketing communication (e.g. "Trusted by Talsec section" on social media)over 100k downloadsno
    Threat signals data collection to Talsec database for processing and product improvementyesno
    + +For further comparison details (and planned features), follow our [discussion](https://github.com/talsec/Free-RASP-Community/discussions/5). diff --git a/analysis_options.yaml b/analysis_options.yaml index 260d663..273cb60 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,4 +1 @@ -include: package:extra_pedantic/analysis_options.yaml - -analyzer: - exclude: [test/**] +include: package:very_good_analysis/analysis_options.3.1.0.yaml diff --git a/android/build.gradle b/android/build.gradle index 9eaddf7..83b0e12 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -2,7 +2,7 @@ group 'com.aheaditec.freerasp' version '1.0-SNAPSHOT' buildscript { - ext.kotlin_version = '1.6.10' + ext.kotlin_version = '1.7.20' repositories { google() mavenCentral() @@ -20,6 +20,7 @@ rootProject.allprojects { mavenCentral() maven { url "https://nexus3-public.monetplus.cz/repository/ahead-talsec-free-rasp" } maven { url "https://developer.huawei.com/repo/" } + maven { url 'https://jitpack.io' } } } @@ -57,11 +58,11 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" // Talsec Release - releaseImplementation 'com.aheaditec.talsec.security:TalsecSecurity-Community-Flutter:4.2.3-release' + releaseImplementation 'com.aheaditec.talsec.security:TalsecSecurity-Community-Flutter:6.0.0-release' // Talsec Debug - debugImplementation 'com.aheaditec.talsec.security:TalsecSecurity-Community-Flutter:4.2.3-dev' + debugImplementation 'com.aheaditec.talsec.security:TalsecSecurity-Community-Flutter:6.0.0-dev' // Talsec Profile - profileImplementation 'com.aheaditec.talsec.security:TalsecSecurity-Community-Flutter:4.2.3-dev' + profileImplementation 'com.aheaditec.talsec.security:TalsecSecurity-Community-Flutter:6.0.0-dev' } diff --git a/android/src/main/kotlin/com/aheaditec/freerasp/MethodCallHandlerImpl.kt b/android/src/main/kotlin/com/aheaditec/freerasp/MethodCallHandlerImpl.kt index 43be3a1..d8d8d77 100644 --- a/android/src/main/kotlin/com/aheaditec/freerasp/MethodCallHandlerImpl.kt +++ b/android/src/main/kotlin/com/aheaditec/freerasp/MethodCallHandlerImpl.kt @@ -46,14 +46,14 @@ class MethodCallHandlerImpl : MethodCallHandler { private fun init(call: MethodCall, result: Result) { try { val packageName = call.argument("expectedPackageName") - val signingHash = call.argument("expectedSigningCertificateHash") + val signingHashes = call.argument>("expectedSigningCertificateHashes") val watcherMail = call.argument("watcherMail") val supportedStores = call.argument>("supportedAlternativeStores") - if (packageName != null && signingHash != null && watcherMail != null && supportedStores != null) { + if (packageName != null && signingHashes != null && watcherMail != null && supportedStores != null) { talsecApp?.init( packageName, - signingHash, + signingHashes.toTypedArray(), watcherMail, supportedStores.toTypedArray() ) ?: Log.w("SET_CONFIG", "Tried to initialize null Talsec object") diff --git a/android/src/main/kotlin/com/aheaditec/freerasp/TalsecApp.kt b/android/src/main/kotlin/com/aheaditec/freerasp/TalsecApp.kt index 9f1e680..463a5dc 100644 --- a/android/src/main/kotlin/com/aheaditec/freerasp/TalsecApp.kt +++ b/android/src/main/kotlin/com/aheaditec/freerasp/TalsecApp.kt @@ -13,13 +13,13 @@ class TalsecApp(private val context: Context) : ThreatListener.ThreatDetected { fun init( packageName: String, - signingHash: String, + signingHashes: Array, watcherMail: String, alternativeStores: Array ) { val config = TalsecConfig( packageName, - signingHash, + signingHashes, watcherMail, alternativeStores ) diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml index 22cb76b..273cb60 100644 --- a/example/analysis_options.yaml +++ b/example/analysis_options.yaml @@ -1 +1 @@ -include: package:extra_pedantic/analysis_options.yaml \ No newline at end of file +include: package:very_good_analysis/analysis_options.3.1.0.yaml diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist index 8d4492f..9625e10 100644 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 9.0 + 11.0 diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 0e4fd68..4ed9516 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -14,9 +14,9 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/freerasp/ios" SPEC CHECKSUMS: - Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a + Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 freerasp: 3516f6bd34a4d386ab4a20aa7a5ca8310d5c3a09 -PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c +PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 COCOAPODS: 1.11.3 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 6836e8e..bf0025b 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -199,6 +199,7 @@ /* Begin PBXShellScriptBuildPhase section */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -230,6 +231,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index bba6b57..ca3b5e3 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -10,7 +10,7 @@ ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction"> + scriptText = "cd "${SRCROOT}/.symlinks/plugins/freerasp/ios" if [ "${CONFIGURATION}" = "Debug" ]; then rm -rf ./TalsecRuntime.xcframework ln -s ./Release/TalsecRuntime.xcframework/ TalsecRuntime.xcframework else rm -rf ./TalsecRuntime.xcframework ln -s ./Debug/TalsecRuntime.xcframework/ TalsecRuntime.xcframework fi "> UIViewControllerBasedStatusBarAppearance + UIApplicationSupportsIndirectInputEvents + diff --git a/example/lib/main.dart b/example/lib/main.dart index b83b8e0..6c23fdd 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,3 +1,5 @@ +// ignore_for_file: cascade_invocations + import 'dart:async'; import 'dart:io'; @@ -8,36 +10,38 @@ void main() { runApp(const MyApp()); } +/// Main app widget. class MyApp extends StatefulWidget { - const MyApp({final Key? key}) : super(key: key); + /// Constructor for main app widget. + const MyApp({Key? key}) : super(key: key); @override - _MyAppState createState() => _MyAppState(); + State createState() => _MyAppState(); } class _MyAppState extends State { /// ThreatTypes to hold current state (Android) - final ThreatType _root = ThreatType("Root"); - final ThreatType _emulator = ThreatType("Emulator"); - final ThreatType _tamper = ThreatType("Tamper"); - final ThreatType _hook = ThreatType("Hook"); - final ThreatType _deviceBinding = ThreatType("Device binding"); + final ThreatType _root = ThreatType('Root'); + final ThreatType _emulator = ThreatType('Emulator'); + final ThreatType _tamper = ThreatType('Tamper'); + final ThreatType _hook = ThreatType('Hook'); + final ThreatType _deviceBinding = ThreatType('Device binding'); final ThreatType _untrustedSource = - ThreatType("Untrusted source of installation"); + ThreatType('Untrusted source of installation'); /// ThreatTypes to hold current state (iOS) - final ThreatType _signature = ThreatType("Signature"); - final ThreatType _jailbreak = ThreatType("Jailbreak"); - final ThreatType _runtimeManipulation = ThreatType("Runtime Manipulation"); - final ThreatType _simulator = ThreatType("Simulator"); - final ThreatType _deviceChange = ThreatType("Device change"); - final ThreatType _deviceId = ThreatType("Device ID"); - final ThreatType _unofficialStore = ThreatType("Unofficial Store"); - final ThreatType _passcode = ThreatType("Passcode"); - final ThreatType _missingSecureEnclave = ThreatType("Missing secure enclave"); + final ThreatType _signature = ThreatType('Signature'); + final ThreatType _jailbreak = ThreatType('Jailbreak'); + final ThreatType _runtimeManipulation = ThreatType('Runtime Manipulation'); + final ThreatType _simulator = ThreatType('Simulator'); + final ThreatType _deviceChange = ThreatType('Device change'); + final ThreatType _deviceId = ThreatType('Device ID'); + final ThreatType _unofficialStore = ThreatType('Unofficial Store'); + final ThreatType _passcode = ThreatType('Passcode'); + final ThreatType _missingSecureEnclave = ThreatType('Missing secure enclave'); /// ThreatTypes to hold current state (common) - final ThreatType _debugger = ThreatType("Debugger"); + final ThreatType _debugger = ThreatType('Debugger'); /// Getter to determine which states we care about List get overview { @@ -76,12 +80,14 @@ class _MyAppState extends State { Future initSecurityState() async { /// Provide TalsecConfig your expected data and then use them in TalsecApp - final TalsecConfig config = TalsecConfig( + final config = TalsecConfig( /// For Android androidConfig: AndroidConfig( expectedPackageName: 'com.aheaditec.freeraspExample', - expectedSigningCertificateHash: 'ek124Mj...', - supportedAlternativeStores: ["com.sec.android.app.samsungapps"], + expectedSigningCertificateHashes: [ + 'AKoRuyLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0=' + ], + supportedAlternativeStores: ['com.sec.android.app.samsungapps'], ), /// For iOS @@ -94,7 +100,7 @@ class _MyAppState extends State { ); /// Callbacks thrown by library - final TalsecCallback callback = TalsecCallback( + final callback = TalsecCallback( /// For Android androidCallback: AndroidCallback( onRootDetected: () => _updateState(_root), @@ -123,7 +129,7 @@ class _MyAppState extends State { onDebuggerDetected: () => _updateState(_debugger), ); - final TalsecApp app = TalsecApp( + final app = TalsecApp( config: config, callback: callback, ); @@ -134,15 +140,12 @@ class _MyAppState extends State { if (!mounted) return; } - void _updateState(final ThreatType type) { - setState(() { - // ignore: parameter_assignments - type.threatFound(); - }); + void _updateState(ThreatType type) { + setState(type.threatFound); } @override - Widget build(final BuildContext context) { + Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( @@ -159,13 +162,17 @@ class _MyAppState extends State { } } +/// A class which holds state about threat. class ThreatType { + /// Threat constructor. + ThreatType(this._text); + final String _text; bool _isSecure = true; - ThreatType(this._text); - + /// Update state. void threatFound() => _isSecure = false; + /// Return current state. String get state => '$_text: ${_isSecure ? "Secured" : "Detected"}\n'; } diff --git a/example/pubspec.lock b/example/pubspec.lock index 9651cce..75024f5 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,65 +5,58 @@ packages: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.dev" source: hosted - version: "2.8.2" + version: "2.10.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" characters: dependency: transitive description: name: characters - url: "https://pub.dartlang.org" + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.dev" source: hosted - version: "1.2.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" + version: "1.2.1" clock: dependency: transitive description: name: clock - url: "https://pub.dartlang.org" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" convert: dependency: transitive description: name: convert - url: "https://pub.dartlang.org" + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" source: hosted - version: "3.0.1" - extra_pedantic: - dependency: "direct dev" - description: - name: extra_pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" + version: "3.1.1" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.dartlang.org" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.3.1" flutter: dependency: "direct main" description: flutter @@ -80,35 +73,47 @@ packages: path: ".." relative: true source: path - version: "3.0.2" + version: "4.0.0" + js: + dependency: transitive + description: + name: js + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.dev" + source: hosted + version: "0.6.5" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + url: "https://pub.dev" source: hosted - version: "0.12.11" + version: "0.12.13" material_color_utilities: dependency: transitive description: name: material_color_utilities - url: "https://pub.dartlang.org" + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" source: hosted - version: "0.1.4" + version: "0.2.0" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.dev" source: hosted - version: "1.7.0" + version: "1.8.0" path: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + url: "https://pub.dev" source: hosted - version: "1.8.1" + version: "1.8.2" sky_engine: dependency: transitive description: flutter @@ -118,58 +123,74 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.9.1" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.1" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + url: "https://pub.dev" source: hosted - version: "0.4.9" + version: "0.4.16" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.dartlang.org" + sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.3.1" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.dartlang.org" + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + very_good_analysis: + dependency: "direct dev" + description: + name: very_good_analysis + sha256: "4815adc7ded57657038d2bb2a7f332c50e3c8152f7d3c6acf8f6b7c0cc81e5e2" + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "3.1.0" sdks: - dart: ">=2.17.0-0 <3.0.0" + dart: ">=2.18.0 <4.0.0" flutter: ">=1.20.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index a16a47e..e600229 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -19,9 +19,9 @@ dependencies: path: ../ dev_dependencies: - extra_pedantic: ^2.0.0 flutter_test: sdk: flutter + very_good_analysis: ^3.1.0 flutter: diff --git a/ios/Debug/TalsecRuntime.xcframework/Info.plist b/ios/Debug/TalsecRuntime.xcframework/Info.plist index 40a3758..4c340e4 100644 --- a/ios/Debug/TalsecRuntime.xcframework/Info.plist +++ b/ios/Debug/TalsecRuntime.xcframework/Info.plist @@ -6,30 +6,30 @@ LibraryIdentifier - ios-arm64 + ios-arm64_x86_64-simulator LibraryPath TalsecRuntime.framework SupportedArchitectures arm64 + x86_64 SupportedPlatform ios + SupportedPlatformVariant + simulator LibraryIdentifier - ios-arm64_x86_64-simulator + ios-arm64 LibraryPath TalsecRuntime.framework SupportedArchitectures arm64 - x86_64 SupportedPlatform ios - SupportedPlatformVariant - simulator CFBundlePackageType diff --git a/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/CurlWrapper.h b/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/CurlWrapper.h index 05aff2c..f88f20e 100644 --- a/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/CurlWrapper.h +++ b/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/CurlWrapper.h @@ -16,7 +16,7 @@ #include #include -struct ysLRNARmRJRU { +struct lCRkBkeOPbmb { char *memory; size_t size; CURLcode ret; diff --git a/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h b/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h index e13be90..1f98639 100644 --- a/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +++ b/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h @@ -1,4 +1,4 @@ -// Generated by Apple Swift version 5.5.1 (swiftlang-1300.0.31.4 clang-1300.0.29.6) +// Generated by Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12) #ifndef TALSECRUNTIME_SWIFT_H #define TALSECRUNTIME_SWIFT_H #pragma clang diagnostic push @@ -184,6 +184,13 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); #if !defined(IBSegueAction) # define IBSegueAction #endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif #if __has_feature(modules) #if __has_warning("-Watimport-in-framework-header") #pragma clang diagnostic ignored "-Watimport-in-framework-header" @@ -205,7 +212,9 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); # pragma pop_macro("any") #endif -void __gvMpyMINelNmJztSEQqmQSt(void); + +SWIFT_EXTERN void __UNZLYksHChDolvKsNoUnHGQ(void); + #if __has_attribute(external_source_symbol) # pragma clang attribute pop #endif diff --git a/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Info.plist b/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Info.plist index 1527495..5427cf0 100644 Binary files a/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Info.plist and b/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Info.plist differ diff --git a/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftdoc b/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftdoc index 85d3e97..0243cae 100644 Binary files a/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftdoc and b/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftdoc differ diff --git a/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftinterface b/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftinterface index 4e3b3bf..628f15e 100644 --- a/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftinterface +++ b/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftinterface @@ -1,6 +1,6 @@ // swift-interface-format-version: 1.0 -// swift-compiler-version: Apple Swift version 5.5.1 (swiftlang-1300.0.31.4 clang-1300.0.29.6) -// swift-module-flags: -target arm64-apple-ios11.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name TalsecRuntime +// swift-compiler-version: Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12) +// swift-module-flags: -target arm64-apple-ios11.2 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name TalsecRuntime import Foundation import LocalAuthentication import TalsecRuntime.Private diff --git a/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/TalsecRuntime b/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/TalsecRuntime index 2274f24..98bb70b 100755 Binary files a/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/TalsecRuntime and b/ios/Debug/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/TalsecRuntime differ diff --git a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/CurlWrapper.h b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/CurlWrapper.h index 05aff2c..f88f20e 100644 --- a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/CurlWrapper.h +++ b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/CurlWrapper.h @@ -16,7 +16,7 @@ #include #include -struct ysLRNARmRJRU { +struct lCRkBkeOPbmb { char *memory; size_t size; CURLcode ret; diff --git a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h index 14c4b64..3d0414c 100644 --- a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +++ b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h @@ -1,6 +1,6 @@ #if 0 #elif defined(__arm64__) && __arm64__ -// Generated by Apple Swift version 5.5.1 (swiftlang-1300.0.31.4 clang-1300.0.29.6) +// Generated by Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12) #ifndef TALSECRUNTIME_SWIFT_H #define TALSECRUNTIME_SWIFT_H #pragma clang diagnostic push @@ -186,6 +186,13 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); #if !defined(IBSegueAction) # define IBSegueAction #endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif #if __has_feature(modules) #if __has_warning("-Watimport-in-framework-header") #pragma clang diagnostic ignored "-Watimport-in-framework-header" @@ -207,7 +214,9 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); # pragma pop_macro("any") #endif -void __gvMpyMINelNmJztSEQqmQSt(void); + +SWIFT_EXTERN void __UNZLYksHChDolvKsNoUnHGQ(void); + #if __has_attribute(external_source_symbol) # pragma clang attribute pop #endif @@ -215,7 +224,7 @@ void __gvMpyMINelNmJztSEQqmQSt(void); #endif #elif defined(__x86_64__) && __x86_64__ -// Generated by Apple Swift version 5.5.1 (swiftlang-1300.0.31.4 clang-1300.0.29.6) +// Generated by Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12) #ifndef TALSECRUNTIME_SWIFT_H #define TALSECRUNTIME_SWIFT_H #pragma clang diagnostic push @@ -401,6 +410,13 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); #if !defined(IBSegueAction) # define IBSegueAction #endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif #if __has_feature(modules) #if __has_warning("-Watimport-in-framework-header") #pragma clang diagnostic ignored "-Watimport-in-framework-header" @@ -422,7 +438,9 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); # pragma pop_macro("any") #endif -void __gvMpyMINelNmJztSEQqmQSt(void); + +SWIFT_EXTERN void __UNZLYksHChDolvKsNoUnHGQ(void); + #if __has_attribute(external_source_symbol) # pragma clang attribute pop #endif diff --git a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Info.plist b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Info.plist index 5adcebd..fd15323 100644 Binary files a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Info.plist and b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Info.plist differ diff --git a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftdoc b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftdoc index a913f04..956621c 100644 Binary files a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftdoc and b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftdoc differ diff --git a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface index 448ba73..7a1301d 100644 --- a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface +++ b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface @@ -1,6 +1,6 @@ // swift-interface-format-version: 1.0 -// swift-compiler-version: Apple Swift version 5.5.1 (swiftlang-1300.0.31.4 clang-1300.0.29.6) -// swift-module-flags: -target arm64-apple-ios11.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name TalsecRuntime +// swift-compiler-version: Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12) +// swift-module-flags: -target arm64-apple-ios11.2-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name TalsecRuntime import Foundation import LocalAuthentication import TalsecRuntime.Private diff --git a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc index 3227bcb..f524967 100644 Binary files a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc and b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc differ diff --git a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface index d8441df..30d41c1 100644 --- a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +++ b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface @@ -1,6 +1,6 @@ // swift-interface-format-version: 1.0 -// swift-compiler-version: Apple Swift version 5.5.1 (swiftlang-1300.0.31.4 clang-1300.0.29.6) -// swift-module-flags: -target x86_64-apple-ios11.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name TalsecRuntime +// swift-compiler-version: Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12) +// swift-module-flags: -target x86_64-apple-ios11.2-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name TalsecRuntime import Foundation import LocalAuthentication import TalsecRuntime.Private diff --git a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/TalsecRuntime b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/TalsecRuntime index bd79b5d..e044789 100755 Binary files a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/TalsecRuntime and b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/TalsecRuntime differ diff --git a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/_CodeSignature/CodeResources b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/_CodeSignature/CodeResources index c77104b..b9d4b98 100644 --- a/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/_CodeSignature/CodeResources +++ b/ios/Debug/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/_CodeSignature/CodeResources @@ -10,11 +10,11 @@ Headers/CurlWrapper.h - 3UaaPf8QSH7GRgFOG5rBmhsl1UM= + 55rnOFtX651FnvO8joG8oC0vI5c= Headers/TalsecRuntime-Swift.h - gPP7qjltbO2Neji6goS4FWvqK3w= + Gk5gqAMZBMR+HJOyQjWf3c8Xn+s= Headers/TalsecRuntime_iOS.h @@ -58,55 +58,31 @@ Info.plist - L9JlsC1FmLt5qMRrgncOaPGj+Z8= + 3zU1Ce0KYONYrxaR9soFItn/jco= Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftdoc - Lc3AuM6SNVNAE/ZKspRGN8foEC4= + OdithZlCwhNivI4CRL/6DwAf1oA= Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface - WoChNU4Ct3nQ3IodkczjJCiKcMc= + SiXUBIZsFShGLEKzPhY3pIHWI7k= Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftmodule - hqK51VxP1MRV253JFASr/vqjy5E= - - Modules/TalsecRuntime.swiftmodule/arm64.swiftdoc - - Lc3AuM6SNVNAE/ZKspRGN8foEC4= - - Modules/TalsecRuntime.swiftmodule/arm64.swiftinterface - - WoChNU4Ct3nQ3IodkczjJCiKcMc= - - Modules/TalsecRuntime.swiftmodule/arm64.swiftmodule - - hqK51VxP1MRV253JFASr/vqjy5E= + ngmhfL8tVdx/ykETmnAC12OCLRY= Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc - oBmsk6is5kpee/oNkmJ1xAhp9k8= + qnaimKYJP6OPuIoSDcbMmt68vw0= Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface - yogGkYoVzcvVjgEuaIVZ2j5sIKM= + 8tuJ/J40k7umK3MPbEGxvSB0Y/M= Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftmodule - J38E87PX6nFWCTZlmgtShJWcn+k= - - Modules/TalsecRuntime.swiftmodule/x86_64.swiftdoc - - oBmsk6is5kpee/oNkmJ1xAhp9k8= - - Modules/TalsecRuntime.swiftmodule/x86_64.swiftinterface - - yogGkYoVzcvVjgEuaIVZ2j5sIKM= - - Modules/TalsecRuntime.swiftmodule/x86_64.swiftmodule - - J38E87PX6nFWCTZlmgtShJWcn+k= + vlOZPH4uutcC3TghDKH1uWytwLs= Modules/module.modulemap @@ -134,14 +110,14 @@ hash2 - 04bBQUJGhdydrhGt4dxU28J77IHrwNVpWMt2N+RASnU= + ps63qHPN0fbjkxIWqCaRVcb9KGhncupOYIriLnsfW5E= Headers/TalsecRuntime-Swift.h hash2 - N4vHhMesbeX+hKcEDGmm72x6yZkGvoRa5u4eUYRj83w= + dtiwbHqdKf/2Uq6+hCf/N98rlUnjP1QaYDIH/ckG3w8= Headers/TalsecRuntime_iOS.h @@ -218,84 +194,42 @@ hash2 - dnHGn+EZAhHQYXoHG2gSf7h+821+nPK6K5ME7l+Kdj4= + ujbFogGJYPuZTLpwXsqdXpO7WN+6mtPfQtJK52DgryY= Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface hash2 - UBr0BBEEf7ZjZoARA52gIa65v5IxVKUpAm/Ztvbf3Ac= + VbpQZ87ArQQH5ZXpo0hbz1dfKWHmOSUdonwckOnGix8= Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftmodule hash2 - kl3q5YJPLr4g7VN3L8qvOFn9G8768KoUNHAvO4X9u7Y= - - - Modules/TalsecRuntime.swiftmodule/arm64.swiftdoc - - hash2 - - dnHGn+EZAhHQYXoHG2gSf7h+821+nPK6K5ME7l+Kdj4= - - - Modules/TalsecRuntime.swiftmodule/arm64.swiftinterface - - hash2 - - UBr0BBEEf7ZjZoARA52gIa65v5IxVKUpAm/Ztvbf3Ac= - - - Modules/TalsecRuntime.swiftmodule/arm64.swiftmodule - - hash2 - - kl3q5YJPLr4g7VN3L8qvOFn9G8768KoUNHAvO4X9u7Y= + wG+MrZQJydbg8oy2ctERR4qIZKrD8sNAxUN61wB/LkI= Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc hash2 - 6pGoe0lDNqaxn1UfAB6r+dVObbl1SqxRAA4pJ2xDBX4= + CKNQAck1XKQHWS7alfrqWziRJvm4XKD972h2v4/SrmY= Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface hash2 - tz8XDbUas1J3XebXlmTAfAwreOjvI03ErFy9+ZuBi2I= + n0jUGwgfEbjzOImmmLg+9DMOjUeT8IG7ouKoDuYflHw= Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftmodule hash2 - EDYIjIpWThgP5VDcQeIaOEJZfcLDnOkjUDyzEZ6Ythc= - - - Modules/TalsecRuntime.swiftmodule/x86_64.swiftdoc - - hash2 - - 6pGoe0lDNqaxn1UfAB6r+dVObbl1SqxRAA4pJ2xDBX4= - - - Modules/TalsecRuntime.swiftmodule/x86_64.swiftinterface - - hash2 - - tz8XDbUas1J3XebXlmTAfAwreOjvI03ErFy9+ZuBi2I= - - - Modules/TalsecRuntime.swiftmodule/x86_64.swiftmodule - - hash2 - - EDYIjIpWThgP5VDcQeIaOEJZfcLDnOkjUDyzEZ6Ythc= + ln3iwMP107Yxr8gbPtVOksyoGXBjjwKvhDZnC+GgybA= Modules/module.modulemap diff --git a/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/CurlWrapper.h b/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/CurlWrapper.h index fae393d..74eed67 100644 --- a/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/CurlWrapper.h +++ b/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/CurlWrapper.h @@ -16,7 +16,7 @@ #include #include -struct RAUqKRKBVreA { +struct gKSEtJMglUSg { char *memory; size_t size; CURLcode ret; diff --git a/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h b/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h index e61e8a4..8e560ed 100644 --- a/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +++ b/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h @@ -1,4 +1,4 @@ -// Generated by Apple Swift version 5.5.1 (swiftlang-1300.0.31.4 clang-1300.0.29.6) +// Generated by Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12) #ifndef TALSECRUNTIME_SWIFT_H #define TALSECRUNTIME_SWIFT_H #pragma clang diagnostic push @@ -184,6 +184,13 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); #if !defined(IBSegueAction) # define IBSegueAction #endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif #if __has_feature(modules) #if __has_warning("-Watimport-in-framework-header") #pragma clang diagnostic ignored "-Watimport-in-framework-header" @@ -205,7 +212,9 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); # pragma pop_macro("any") #endif -void __HNHaTxuRuaISNMVyXzBiKwJ(void); + +SWIFT_EXTERN void __CvOtICkCDGgehAhjsSIuWlM(void); + #if __has_attribute(external_source_symbol) # pragma clang attribute pop #endif diff --git a/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Info.plist b/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Info.plist index 1527495..5427cf0 100644 Binary files a/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Info.plist and b/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Info.plist differ diff --git a/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftdoc b/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftdoc index 85d3e97..0243cae 100644 Binary files a/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftdoc and b/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftdoc differ diff --git a/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftinterface b/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftinterface index 4e3b3bf..628f15e 100644 --- a/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftinterface +++ b/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftinterface @@ -1,6 +1,6 @@ // swift-interface-format-version: 1.0 -// swift-compiler-version: Apple Swift version 5.5.1 (swiftlang-1300.0.31.4 clang-1300.0.29.6) -// swift-module-flags: -target arm64-apple-ios11.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name TalsecRuntime +// swift-compiler-version: Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12) +// swift-module-flags: -target arm64-apple-ios11.2 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name TalsecRuntime import Foundation import LocalAuthentication import TalsecRuntime.Private diff --git a/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/TalsecRuntime b/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/TalsecRuntime index 8efb3af..e33ddab 100755 Binary files a/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/TalsecRuntime and b/ios/Release/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/TalsecRuntime differ diff --git a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/CurlWrapper.h b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/CurlWrapper.h index fae393d..74eed67 100644 --- a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/CurlWrapper.h +++ b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/CurlWrapper.h @@ -16,7 +16,7 @@ #include #include -struct RAUqKRKBVreA { +struct gKSEtJMglUSg { char *memory; size_t size; CURLcode ret; diff --git a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h index 47c69f6..d54344b 100644 --- a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +++ b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h @@ -1,6 +1,6 @@ #if 0 #elif defined(__arm64__) && __arm64__ -// Generated by Apple Swift version 5.5.1 (swiftlang-1300.0.31.4 clang-1300.0.29.6) +// Generated by Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12) #ifndef TALSECRUNTIME_SWIFT_H #define TALSECRUNTIME_SWIFT_H #pragma clang diagnostic push @@ -186,6 +186,13 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); #if !defined(IBSegueAction) # define IBSegueAction #endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif #if __has_feature(modules) #if __has_warning("-Watimport-in-framework-header") #pragma clang diagnostic ignored "-Watimport-in-framework-header" @@ -207,7 +214,9 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); # pragma pop_macro("any") #endif -void __HNHaTxuRuaISNMVyXzBiKwJ(void); + +SWIFT_EXTERN void __CvOtICkCDGgehAhjsSIuWlM(void); + #if __has_attribute(external_source_symbol) # pragma clang attribute pop #endif @@ -215,7 +224,7 @@ void __HNHaTxuRuaISNMVyXzBiKwJ(void); #endif #elif defined(__x86_64__) && __x86_64__ -// Generated by Apple Swift version 5.5.1 (swiftlang-1300.0.31.4 clang-1300.0.29.6) +// Generated by Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12) #ifndef TALSECRUNTIME_SWIFT_H #define TALSECRUNTIME_SWIFT_H #pragma clang diagnostic push @@ -401,6 +410,13 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); #if !defined(IBSegueAction) # define IBSegueAction #endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif #if __has_feature(modules) #if __has_warning("-Watimport-in-framework-header") #pragma clang diagnostic ignored "-Watimport-in-framework-header" @@ -422,7 +438,9 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); # pragma pop_macro("any") #endif -void __HNHaTxuRuaISNMVyXzBiKwJ(void); + +SWIFT_EXTERN void __CvOtICkCDGgehAhjsSIuWlM(void); + #if __has_attribute(external_source_symbol) # pragma clang attribute pop #endif diff --git a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Info.plist b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Info.plist index 5adcebd..fd15323 100644 Binary files a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Info.plist and b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Info.plist differ diff --git a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftdoc b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftdoc index a913f04..956621c 100644 Binary files a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftdoc and b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftdoc differ diff --git a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface index 448ba73..7a1301d 100644 --- a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface +++ b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface @@ -1,6 +1,6 @@ // swift-interface-format-version: 1.0 -// swift-compiler-version: Apple Swift version 5.5.1 (swiftlang-1300.0.31.4 clang-1300.0.29.6) -// swift-module-flags: -target arm64-apple-ios11.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name TalsecRuntime +// swift-compiler-version: Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12) +// swift-module-flags: -target arm64-apple-ios11.2-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name TalsecRuntime import Foundation import LocalAuthentication import TalsecRuntime.Private diff --git a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc index 3227bcb..f524967 100644 Binary files a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc and b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc differ diff --git a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface index d8441df..30d41c1 100644 --- a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +++ b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface @@ -1,6 +1,6 @@ // swift-interface-format-version: 1.0 -// swift-compiler-version: Apple Swift version 5.5.1 (swiftlang-1300.0.31.4 clang-1300.0.29.6) -// swift-module-flags: -target x86_64-apple-ios11.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name TalsecRuntime +// swift-compiler-version: Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12) +// swift-module-flags: -target x86_64-apple-ios11.2-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name TalsecRuntime import Foundation import LocalAuthentication import TalsecRuntime.Private diff --git a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/TalsecRuntime b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/TalsecRuntime index 72d3307..b4fc0df 100755 Binary files a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/TalsecRuntime and b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/TalsecRuntime differ diff --git a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/_CodeSignature/CodeResources b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/_CodeSignature/CodeResources index a4e2326..d450530 100644 --- a/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/_CodeSignature/CodeResources +++ b/ios/Release/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/_CodeSignature/CodeResources @@ -10,11 +10,11 @@ Headers/CurlWrapper.h - PEsyB71ojn5jcA0PA1N0YIdXilI= + 5CWddo1wLaKIp7qQgQh1AYkxjJ0= Headers/TalsecRuntime-Swift.h - 0XJ8gXao2gmqvtYXM5iVDJAfpls= + O7TjBQ0trn89LgjYbJrt6nvgK7I= Headers/TalsecRuntime_iOS.h @@ -58,55 +58,31 @@ Info.plist - L9JlsC1FmLt5qMRrgncOaPGj+Z8= + 3zU1Ce0KYONYrxaR9soFItn/jco= Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftdoc - Lc3AuM6SNVNAE/ZKspRGN8foEC4= + OdithZlCwhNivI4CRL/6DwAf1oA= Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface - WoChNU4Ct3nQ3IodkczjJCiKcMc= + SiXUBIZsFShGLEKzPhY3pIHWI7k= Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftmodule - ykx2GNWUxDrUFjY7+kPaU0TnNb8= - - Modules/TalsecRuntime.swiftmodule/arm64.swiftdoc - - Lc3AuM6SNVNAE/ZKspRGN8foEC4= - - Modules/TalsecRuntime.swiftmodule/arm64.swiftinterface - - WoChNU4Ct3nQ3IodkczjJCiKcMc= - - Modules/TalsecRuntime.swiftmodule/arm64.swiftmodule - - ykx2GNWUxDrUFjY7+kPaU0TnNb8= + RARC13g/cHc9F464nVIvPc2xfyw= Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc - oBmsk6is5kpee/oNkmJ1xAhp9k8= + qnaimKYJP6OPuIoSDcbMmt68vw0= Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface - yogGkYoVzcvVjgEuaIVZ2j5sIKM= + 8tuJ/J40k7umK3MPbEGxvSB0Y/M= Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftmodule - yx6Ej7meaDrSPRLN/nyTHRwgk2g= - - Modules/TalsecRuntime.swiftmodule/x86_64.swiftdoc - - oBmsk6is5kpee/oNkmJ1xAhp9k8= - - Modules/TalsecRuntime.swiftmodule/x86_64.swiftinterface - - yogGkYoVzcvVjgEuaIVZ2j5sIKM= - - Modules/TalsecRuntime.swiftmodule/x86_64.swiftmodule - - yx6Ej7meaDrSPRLN/nyTHRwgk2g= + lctP6lQOU3DmeSfMF6VOInB95cw= Modules/module.modulemap @@ -134,14 +110,14 @@ hash2 - VPfFjL+wOzo5C1+y/3kyC4bloTFggtuOUCfK5qWmv+I= + lZuWoE/FdvP9ydU8ZTP6maT5u8xOiJn0hGGITeenY6w= Headers/TalsecRuntime-Swift.h hash2 - AA85PB/ijHBLXoYi6tfvkbn6LMssQ33UOIJ8Uxs7x/0= + suQeMrSY6mxhhpnqNCN8ggVzzpCZDct/R9ucsjMk+Nk= Headers/TalsecRuntime_iOS.h @@ -218,84 +194,42 @@ hash2 - dnHGn+EZAhHQYXoHG2gSf7h+821+nPK6K5ME7l+Kdj4= + ujbFogGJYPuZTLpwXsqdXpO7WN+6mtPfQtJK52DgryY= Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface hash2 - UBr0BBEEf7ZjZoARA52gIa65v5IxVKUpAm/Ztvbf3Ac= + VbpQZ87ArQQH5ZXpo0hbz1dfKWHmOSUdonwckOnGix8= Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftmodule hash2 - whibxA45RsKr9Aidq/TKGkIi7y5/q7vw/SPJ/GvGkE4= - - - Modules/TalsecRuntime.swiftmodule/arm64.swiftdoc - - hash2 - - dnHGn+EZAhHQYXoHG2gSf7h+821+nPK6K5ME7l+Kdj4= - - - Modules/TalsecRuntime.swiftmodule/arm64.swiftinterface - - hash2 - - UBr0BBEEf7ZjZoARA52gIa65v5IxVKUpAm/Ztvbf3Ac= - - - Modules/TalsecRuntime.swiftmodule/arm64.swiftmodule - - hash2 - - whibxA45RsKr9Aidq/TKGkIi7y5/q7vw/SPJ/GvGkE4= + m3DQ4F2keNSg/IQqzbj1uHlBkR+2MO/ztIrf4cdzd9I= Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc hash2 - 6pGoe0lDNqaxn1UfAB6r+dVObbl1SqxRAA4pJ2xDBX4= + CKNQAck1XKQHWS7alfrqWziRJvm4XKD972h2v4/SrmY= Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface hash2 - tz8XDbUas1J3XebXlmTAfAwreOjvI03ErFy9+ZuBi2I= + n0jUGwgfEbjzOImmmLg+9DMOjUeT8IG7ouKoDuYflHw= Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftmodule hash2 - /xnT8ZGvcBVvVCgTMPPm/4zdRrVg7p79BVy5tumeFWQ= - - - Modules/TalsecRuntime.swiftmodule/x86_64.swiftdoc - - hash2 - - 6pGoe0lDNqaxn1UfAB6r+dVObbl1SqxRAA4pJ2xDBX4= - - - Modules/TalsecRuntime.swiftmodule/x86_64.swiftinterface - - hash2 - - tz8XDbUas1J3XebXlmTAfAwreOjvI03ErFy9+ZuBi2I= - - - Modules/TalsecRuntime.swiftmodule/x86_64.swiftmodule - - hash2 - - /xnT8ZGvcBVvVCgTMPPm/4zdRrVg7p79BVy5tumeFWQ= + Yn5qi0NtWcyVlf/ZVf5EiXgyl9XB2V4z7YIIVzoN8PI= Modules/module.modulemap diff --git a/lib/android/android_callback.dart b/lib/android/android_callback.dart index 53ad6b5..1727a52 100644 --- a/lib/android/android_callback.dart +++ b/lib/android/android_callback.dart @@ -1,34 +1,39 @@ import 'package:flutter/foundation.dart'; -/// Model class for Android callbacks. +/// A class for Android callbacks. +/// +/// When threat is detected, callback is called according to its type. /// /// Callbacks (pointers) are called in talsec_config. class AndroidCallback { - /// Callback called when device is rooted + /// Constructor for Android callbacks. + /// + /// If callback is not implemented, implicit null is applied. + const AndroidCallback({ + this.onRootDetected, + this.onEmulatorDetected, + this.onTamperDetected, + this.onHookDetected, + this.onDeviceBindingDetected, + this.onUntrustedInstallationDetected, + }); + + /// Callback called when device is rooted. final VoidCallback? onRootDetected; - /// Callback called when app is running on emulator + /// Callback called when app is running on emulator. final VoidCallback? onEmulatorDetected; - /// Callback called when app code integrity is disturbed + /// Callback called when app code integrity is disturbed. final VoidCallback? onTamperDetected; - /// Callback called when hooking framework is present or used + /// Callback called when hooking framework is present or used. final VoidCallback? onHookDetected; - /// Callback called when binding of device is disrupted + /// Callback called when binding of device is disrupted. final VoidCallback? onDeviceBindingDetected; /// Callback called when application is installed from unrecognised source - /// such as unofficial store or other not explicitly allow source + /// such as unofficial store or other not explicitly allow source. final VoidCallback? onUntrustedInstallationDetected; - - const AndroidCallback({ - final this.onRootDetected, - final this.onEmulatorDetected, - final this.onTamperDetected, - final this.onHookDetected, - final this.onDeviceBindingDetected, - final this.onUntrustedInstallationDetected, - }); } diff --git a/lib/android/android_config.dart b/lib/android/android_config.dart index bc9da97..1bb0d18 100644 --- a/lib/android/android_config.dart +++ b/lib/android/android_config.dart @@ -1,46 +1,76 @@ import 'dart:convert'; // ignore_for_file: tighten_type_of_initializing_formals -/// Model class for Android config. +/// A class which holds Android config. /// -/// Contains crucial data that are passed to native side in order to secure Android device. +/// These data are used to check if device is trusted. +/// +/// On initialization, these data are passed to native code which then +/// initializes Talsec. class AndroidConfig { + /// Constructor checks whether [expectedPackageName] and + /// [expectedSigningCertificateHashes] are provided. + /// Both arguments are MANDATORY. + AndroidConfig({ + required this.expectedPackageName, + required this.expectedSigningCertificateHashes, + this.supportedAlternativeStores = const [], + }) : assert( + expectedPackageName != null, + 'expectedPackageName cannot be null.', + ), + assert( + expectedSigningCertificateHashes != null, + 'expectedSigningCertificateHashes cannot be null.', + ), + assert( + expectedSigningCertificateHashes!.isNotEmpty, + 'expectedSigningCertificateHashes cannot be empty.', + ), + assert( + supportedAlternativeStores != null, + 'supportedAlternativeStores cannot be null.', + ), + assert( + _areSigningHashesBase64(expectedSigningCertificateHashes!), + 'some of expectedSigningCertificateHashes are not in base64 form.', + ), + assert( + _areSigningHashesValid(expectedSigningCertificateHashes!), + 'some of expectedSigningCertificateHashes do NOT contain ' + 'SHA-256 value.'); + // Nullable because of older Flutter SDK versions + // ignore: flutter_style_todos // TODO: Rewrite when Flutter version >= 2.0 // see issue https://github.com/talsec/Free-RASP-Flutter/issues/6 + /// Package name of the application. final String? expectedPackageName; - final String? expectedSigningCertificateHash; - final List? supportedAlternativeStores; - /// Constructor checks whether [expectedPackageName] and - /// [expectedSigningCertificateHash] are provided. - /// Both arguments are MANDATORY. - AndroidConfig( - {required final this.expectedPackageName, - required final this.expectedSigningCertificateHash, - final this.supportedAlternativeStores = const []}) - : assert( - expectedPackageName != null, 'expectedPackageName cannot be null.'), - assert(expectedSigningCertificateHash != null, - 'expectedSigningCertificateHash cannot be null.'), - assert(supportedAlternativeStores != null, - 'supportedAlternativeStores cannot be null.'), - assert(_isSigningHashBase64(expectedSigningCertificateHash!), - 'expectedSigningCertificateHash is not in base64 form.'), - assert(_isSigningHashValid(expectedSigningCertificateHash!), - 'expectedSigningCertificateHash does NOT contain SHA-256 value.'); + /// List of expected signing hashes. + final List? expectedSigningCertificateHashes; - static bool _isSigningHashBase64(final String hashEncoded) { - try { - base64.decode(hashEncoded); - return true; - } on FormatException { - return false; + /// List of supported sources where application can be installed from. + final List? supportedAlternativeStores; + + static bool _areSigningHashesBase64(List hashesEncoded) { + for (final item in hashesEncoded) { + try { + base64.decode(item); + } on FormatException { + return false; + } } + return true; } - static bool _isSigningHashValid(final String hashEncoded) { - final bytes = base64.decode(hashEncoded); - return bytes.length == 32; + static bool _areSigningHashesValid(List hashesEncoded) { + for (final item in hashesEncoded) { + final bytes = base64.decode(item); + if (bytes.length != 32) { + return false; + } + } + return true; } } diff --git a/lib/ios/ios_callback.dart b/lib/ios/ios_callback.dart index 7c138cf..029b085 100644 --- a/lib/ios/ios_callback.dart +++ b/lib/ios/ios_callback.dart @@ -4,6 +4,21 @@ import 'package:flutter/foundation.dart'; /// /// Callbacks (pointers) are called in talsec_config. class IOSCallback { + /// Constructor for iOS callbacks. + /// + /// If callback is not implemented, implicit null is applied. + const IOSCallback({ + this.onSignatureDetected, + this.onJailbreakDetected, + this.onRuntimeManipulationDetected, + this.onPasscodeDetected, + this.onSimulatorDetected, + this.onMissingSecureEnclaveDetected, + this.onDeviceChangeDetected, + this.onDeviceIdDetected, + this.onUnofficialStoreDetected, + }); + /// Callback called when app signature does not match expected one final VoidCallback? onSignatureDetected; @@ -30,16 +45,4 @@ class IOSCallback { /// Callback called when application is not installed from official store final VoidCallback? onUnofficialStoreDetected; - - const IOSCallback({ - final this.onSignatureDetected, - final this.onJailbreakDetected, - final this.onRuntimeManipulationDetected, - final this.onPasscodeDetected, - final this.onSimulatorDetected, - final this.onMissingSecureEnclaveDetected, - final this.onDeviceChangeDetected, - final this.onDeviceIdDetected, - final this.onUnofficialStoreDetected, - }); } diff --git a/lib/ios/ios_config.dart b/lib/ios/ios_config.dart index f699106..100fddd 100644 --- a/lib/ios/ios_config.dart +++ b/lib/ios/ios_config.dart @@ -1,19 +1,23 @@ -/// Model class for iOS config +/// A class which holds iOS config. /// -/// Contains crucial data that are passed to native side in order to secure Android device. +/// Contains crucial data that are passed to native side in order to secure +/// iOS device. class IOSconfig { - // Nullable because of older Dart SDK versions - // see issue https://github.com/talsec/Free-RASP-Flutter/issues/6 - final String? appBundleId; - final String? appTeamId; - /// Constructor checks whether [appTeamId] and [appBundleId] are provided. /// Both arguments are MANDATORY. const IOSconfig({ - required final this.appBundleId, - required final this.appTeamId, + required this.appBundleId, + required this.appTeamId, }) : assert( appBundleId != null && appTeamId != null, 'appBundleId and appTeamId cannot be null.', ); + + // Nullable because of older Dart SDK versions + // see issue https://github.com/talsec/Free-RASP-Flutter/issues/6 + /// Bundle ID of the app. + final String? appBundleId; + + /// Team ID of the app. + final String? appTeamId; } diff --git a/lib/talsec_app.dart b/lib/talsec_app.dart index 2235446..84d7114 100644 --- a/lib/talsec_app.dart +++ b/lib/talsec_app.dart @@ -2,31 +2,34 @@ import 'dart:io'; import 'package:flutter/services.dart'; -import './talsec_callback.dart'; -import './talsec_config.dart'; +import 'package:freerasp/talsec_callback.dart'; +import 'package:freerasp/talsec_config.dart'; export './talsec_callback.dart'; export './talsec_config.dart'; /// Wrapper of general config and general callbacks. /// -/// Sends and receive data from native side, decides which callbacks should be called. +/// Sends and receive data from native side, decides which callbacks should be +/// called. class TalsecApp { - late TalsecConfig _config; - late TalsecCallback _callback; - /// Constructor checks whether [config] and [callback] are provided. /// Both arguments are MANDATORY. Callback can be provided just as empty /// [TalsecCallback] object. TalsecApp({ - required final TalsecConfig? config, - required final TalsecCallback? callback, - }) : assert(config != null && callback != null, - 'config and callback cannot be null') { + required TalsecConfig? config, + required TalsecCallback? callback, + }) : assert( + config != null && callback != null, + 'config and callback cannot be null', + ) { _config = config!; _callback = callback!; } + late TalsecConfig _config; + late TalsecCallback _callback; + /// [EventChannel] used to receive Threats from the native platform. static const EventChannel _channel = EventChannel('plugins.aheaditec.com/events'); @@ -40,14 +43,14 @@ class TalsecApp { /// device for threats. void start() { /// Android device - final AndroidConfig? androidConfig = _config.androidConfig; - final IOSconfig? iosConfig = _config.iosConfig; + final androidConfig = _config.androidConfig; + final iosConfig = _config.iosConfig; if (Platform.isAndroid && androidConfig != null) { _configChannel.invokeListMethod('setConfig', { 'expectedPackageName': androidConfig.expectedPackageName, - 'expectedSigningCertificateHash': - androidConfig.expectedSigningCertificateHash, + 'expectedSigningCertificateHashes': + androidConfig.expectedSigningCertificateHashes, 'watcherMail': _config.watcherMail, 'supportedAlternativeStores': androidConfig.supportedAlternativeStores }); @@ -62,7 +65,8 @@ class TalsecApp { }); } else { throw MissingPluginException( - '${Platform.isAndroid ? "androidConfig" : "IOSconfig"} is not provided.'); + '${Platform.isAndroid ? "androidConfig" : "IOSconfig"} is not ' + 'provided.'); } /// Listen to changes from native side @@ -70,32 +74,31 @@ class TalsecApp { } /// Receive different events from native side - void _setListener(final EventChannel channel) { - channel.receiveBroadcastStream().listen((final dynamic event) { + void _setListener(EventChannel channel) { + channel.receiveBroadcastStream().listen((dynamic event) { switch (event) { - /// Android: Event received when device is rooted - case "onRootDetected": + case 'onRootDetected': _callback.androidCallback?.onRootDetected?.call(); break; /// Android & iOS: Event received when app is running in debug mode - case "onDebuggerDetected": + case 'onDebuggerDetected': _callback.onDebuggerDetected?.call(); break; /// Android: Event received when app is running on emulator - case "onEmulatorDetected": + case 'onEmulatorDetected': _callback.androidCallback?.onEmulatorDetected?.call(); break; /// Android: Event received when app code integrity is disturbed - case "onTamperDetected": + case 'onTamperDetected': _callback.androidCallback?.onTamperDetected?.call(); break; /// Android: Event received when hooking framework is present or used - case "onHookDetected": + case 'onHookDetected': _callback.androidCallback?.onHookDetected?.call(); break; @@ -108,51 +111,51 @@ class TalsecApp { break; /// iOS: Event received when app signature does not match expected one - case "onSignatureDetected": + case 'onSignatureDetected': _callback.iosCallback?.onSignatureDetected?.call(); break; /// iOS: Event received when jailbreak on device is detected - case "onJailbreakDetected": + case 'onJailbreakDetected': _callback.iosCallback?.onJailbreakDetected?.call(); break; /// iOS: Event received when app is manipulated on runtime - case "onRuntimeManipulationDetected": + case 'onRuntimeManipulationDetected': _callback.iosCallback?.onRuntimeManipulationDetected?.call(); break; /// iOS: Event received when device is not protected by passcode - case "onPasscodeDetected": + case 'onPasscodeDetected': _callback.iosCallback?.onPasscodeDetected?.call(); break; - case "onPasscodeChangeDetected": + case 'onPasscodeChangeDetected': break; /// iOS: Event received when app is running on simulator - case "onSimulatorDetected": + case 'onSimulatorDetected': _callback.iosCallback?.onSimulatorDetected?.call(); break; /// iOS: Event received when secure enclave layer is missing - case "onMissingSecureEnclaveDetected": + case 'onMissingSecureEnclaveDetected': _callback.iosCallback?.onMissingSecureEnclaveDetected?.call(); break; /// iOS: Event received when device was changed since last check - case "onDeviceChangeDetected": + case 'onDeviceChangeDetected': _callback.iosCallback?.onDeviceChangeDetected?.call(); break; /// iOS: Event received when device id was detected - case "onDeviceIdDetected": + case 'onDeviceIdDetected': _callback.iosCallback?.onDeviceIdDetected?.call(); break; /// iOS: Event received when installation from unofficial store was /// detected - case "onUnofficialStoreDetected": + case 'onUnofficialStoreDetected': _callback.iosCallback?.onUnofficialStoreDetected?.call(); break; } diff --git a/lib/talsec_callback.dart b/lib/talsec_callback.dart index 4d7d840..92ae49f 100644 --- a/lib/talsec_callback.dart +++ b/lib/talsec_callback.dart @@ -1,7 +1,7 @@ import 'package:flutter/foundation.dart'; -import 'android/android_callback.dart'; -import 'ios/ios_callback.dart'; +import 'package:freerasp/android/android_callback.dart'; +import 'package:freerasp/ios/ios_callback.dart'; export 'android/android_callback.dart'; export 'ios/ios_callback.dart'; @@ -12,13 +12,19 @@ export 'ios/ios_callback.dart'; /// general [TalsecCallback]. /// Also takes [onDebuggerDetected] which is common for both platforms. class TalsecCallback { + /// Callbacks for Talsec. + const TalsecCallback({ + this.onDebuggerDetected, + this.androidCallback, + this.iosCallback, + }); + + /// Callback called when debugger is detected. final VoidCallback? onDebuggerDetected; + + /// Callbacks for Android. final AndroidCallback? androidCallback; - final IOSCallback? iosCallback; - const TalsecCallback({ - final this.onDebuggerDetected, - final this.androidCallback, - final this.iosCallback, - }); + /// Callbacks for iOS. + final IOSCallback? iosCallback; } diff --git a/lib/talsec_config.dart b/lib/talsec_config.dart index 32bc253..2e84878 100644 --- a/lib/talsec_config.dart +++ b/lib/talsec_config.dart @@ -1,5 +1,5 @@ -import 'android/android_config.dart'; -import 'ios/ios_config.dart'; +import 'package:freerasp/android/android_config.dart'; +import 'package:freerasp/ios/ios_config.dart'; export 'android/android_config.dart'; export 'ios/ios_config.dart'; @@ -10,16 +10,23 @@ export 'ios/ios_config.dart'; /// general [TalsecConfig]. /// Also contains [watcherMail] for alerts and reports. class TalsecConfig { - final AndroidConfig? androidConfig; - final IOSconfig? iosConfig; - final String? watcherMail; - + /// Configuration for [TalsecConfig]. const TalsecConfig({ - required final this.watcherMail, - final this.androidConfig, - final this.iosConfig, + required this.watcherMail, + this.androidConfig, + this.iosConfig, }) : assert( (androidConfig != null || iosConfig != null) && watcherMail != null, - 'Configuration for targeted platform and watcherMail has to be provided', + 'Configuration for targeted platform and watcherMail has to be ' + 'provided', ); + + /// Android configuration. + final AndroidConfig? androidConfig; + + /// iOS configuration. + final IOSconfig? iosConfig; + + /// Mail for security reports. + final String? watcherMail; } diff --git a/lib/utils/hash_converter.dart b/lib/utils/hash_converter.dart index bea9117..cf791b5 100644 --- a/lib/utils/hash_converter.dart +++ b/lib/utils/hash_converter.dart @@ -2,51 +2,70 @@ import 'dart:convert'; import 'package:convert/convert.dart'; +/// Static variable for [HashConverter]. const hashConverter = HashConverter._(); +/// A class for checking and converting SHA-256 hashes. +/// +/// Class is initialized as a static variable [hashConverter]. class HashConverter { const HashConverter._(); - String fromSha256toBase64(final String value) { - final String formattedValue = value.replaceAll(':', ''); + /// Converts given SHA-256 hash [String] to Base64 format [String]. + /// + /// Throws [FormatException] if given [value] is not a valid SHA-256 hash. + /// + /// Returns base64 encoded [String]. + String fromSha256toBase64(String value) { + final formattedValue = value.replaceAll(':', ''); if (!isValidSha256Format(formattedValue)) { throw const FormatException('Value is not SHA-256'); } - final List bytes = hex.decode(formattedValue); - final String base64Form = base64.encode(bytes); + final bytes = hex.decode(formattedValue); + final base64Form = base64.encode(bytes); return base64Form; } - String fromBase64toSha256(final String value) { + /// Converts given Base64 [String] to SHA-256 format [String]. + /// + /// Throws [FormatException] if given [value] cannot be a valid SHA-256 hash. + /// + /// Returns base64 encoded [String]. + String fromBase64toSha256(String value) { final List bytes = base64.decode(value); - final String hexForm = hex.encode(bytes); + final hexForm = hex.encode(bytes); if (!isValidSha256Format(hexForm)) { throw const FormatException('Value is not SHA-256'); } - final String sha256Form = _formatSha(hexForm); + final sha256Form = _formatSha(hexForm); return sha256Form; } - String _formatSha(final String value) { - final String formattedValue = value.toUpperCase(); - const String delimiter = ':'; + String _formatSha(String value) { + final formattedValue = value.toUpperCase(); + const delimiter = ':'; final buffer = StringBuffer(); - for (int i = 0; i < formattedValue.length; i = i + 2) { - buffer.write(formattedValue.substring(i, i + 2) + - (i == formattedValue.length - 2 ? '' : delimiter)); + for (var i = 0; i < formattedValue.length; i = i + 2) { + buffer.write( + formattedValue.substring(i, i + 2) + + (i == formattedValue.length - 2 ? '' : delimiter), + ); } return buffer.toString(); } - bool isValidSha256Format(final String value) { - final validator = RegExp(r'[A-Fa-f0-9]{64}'); + /// Checks whether given [String] is valid SHA-256 format. + /// + /// Returns true if given [String] is valid SHA-256 format, otherwise false. + bool isValidSha256Format(String value) { + final validator = RegExp('[A-Fa-f0-9]{64}'); return validator.hasMatch(value); } } diff --git a/pubspec.yaml b/pubspec.yaml index 3df77da..e3df410 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: freerasp description: Flutter library for improving app security and threat monitoring on Android and iOS mobile devices. Learn more about provided features on the freeRASP's homepage first. -version: 3.0.2 +version: 4.0.0 homepage: https://www.talsec.app/freerasp-in-app-protection-security-talsec repository: https://github.com/talsec/Free-RASP-Flutter @@ -14,9 +14,9 @@ dependencies: sdk: flutter dev_dependencies: - extra_pedantic: ^2.0.0 flutter_test: sdk: flutter + very_good_analysis: ^3.1.0 flutter: plugin: diff --git a/test/android/android_config_test.dart b/test/android/android_config_test.dart index aaafa51..2b47908 100644 --- a/test/android/android_config_test.dart +++ b/test/android/android_config_test.dart @@ -2,59 +2,85 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:freerasp/android/android_config.dart'; void main() { - AndroidConfig createConfiguration(final String? packageName, - final String? signingHash, final List? alternativeStores) { + AndroidConfig createConfiguration( + String? packageName, + List? signingHashes, + List? alternativeStores, + ) { return AndroidConfig( expectedPackageName: packageName, - expectedSigningCertificateHash: signingHash, + expectedSigningCertificateHashes: signingHashes, supportedAlternativeStores: alternativeStores, ); } AndroidConfig createDefaultConfiguration( - final String? packageName, final String? signingHash) { + String? packageName, + List? signingHashes, + ) { return AndroidConfig( expectedPackageName: packageName, - expectedSigningCertificateHash: signingHash, + expectedSigningCertificateHashes: signingHashes, ); } - const String packageName = 'packageName'; - const String signingHash = 'AKoRuyLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0='; - const List alternativeStores = ['someAppStore']; + const packageName = 'packageName'; + const signingHashes = [ + 'AKoRuyLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0=' + ]; + const alternativeStores = ['someAppStore']; test('Object should be created', () { expect( - () => createConfiguration(packageName, signingHash, alternativeStores), - returnsNormally); + () => createConfiguration(packageName, signingHashes, alternativeStores), + returnsNormally, + ); }); group('Null checks', () { test('Only expectedPackageName is provided', () { - expect(() => createConfiguration(packageName, null, alternativeStores), - throwsAssertionError); - expect(() => createConfiguration(packageName, signingHash, null), - throwsAssertionError); - expect(() => createConfiguration(packageName, null, null), - throwsAssertionError); + expect( + () => createConfiguration(packageName, null, alternativeStores), + throwsAssertionError, + ); + expect( + () => createConfiguration(packageName, signingHashes, null), + throwsAssertionError, + ); + expect( + () => createConfiguration(packageName, null, null), + throwsAssertionError, + ); }); - test('Only expectedSigningHash is provided', () { - expect(() => createConfiguration(null, signingHash, alternativeStores), - throwsAssertionError); - expect(() => createConfiguration(packageName, signingHash, null), - throwsAssertionError); - expect(() => createConfiguration(null, signingHash, null), - throwsAssertionError); + test('Only expectedsigningHashes is provided', () { + expect( + () => createConfiguration(null, signingHashes, alternativeStores), + throwsAssertionError, + ); + expect( + () => createConfiguration(packageName, signingHashes, null), + throwsAssertionError, + ); + expect( + () => createConfiguration(null, signingHashes, null), + throwsAssertionError, + ); }); test('Only alternativeStores is provided', () { - expect(() => createConfiguration(null, signingHash, alternativeStores), - throwsAssertionError); - expect(() => createConfiguration(packageName, null, alternativeStores), - throwsAssertionError); - expect(() => createConfiguration(null, null, alternativeStores), - throwsAssertionError); + expect( + () => createConfiguration(null, signingHashes, alternativeStores), + throwsAssertionError, + ); + expect( + () => createConfiguration(packageName, null, alternativeStores), + throwsAssertionError, + ); + expect( + () => createConfiguration(null, null, alternativeStores), + throwsAssertionError, + ); }); test('Nothing is provided', () { @@ -63,30 +89,44 @@ void main() { test('Relying on default parameters', () { expect( - () => createDefaultConfiguration(null, null), throwsAssertionError); - expect(() => createDefaultConfiguration(packageName, null), - throwsAssertionError); - expect(() => createDefaultConfiguration(null, signingHash), - throwsAssertionError); - expect(() => createDefaultConfiguration(packageName, signingHash), - returnsNormally); + () => createDefaultConfiguration(null, null), + throwsAssertionError, + ); + expect( + () => createDefaultConfiguration(packageName, null), + throwsAssertionError, + ); + expect( + () => createDefaultConfiguration(null, signingHashes), + throwsAssertionError, + ); + expect( + () => createDefaultConfiguration(packageName, signingHashes), + returnsNormally, + ); }); }); group('Hash checks', () { test('Invalid base64 value', () { - expect(() => createDefaultConfiguration(packageName, '0:0:0:0'), - throwsAssertionError); + expect( + () => createDefaultConfiguration(packageName, ['0:0:0:0']), + throwsAssertionError, + ); }); test('Valid base64 value but not SHA-256 value', () { - expect(() => createDefaultConfiguration(packageName, 'AAA='), - throwsAssertionError); + expect( + () => createDefaultConfiguration(packageName, ['AAA=']), + throwsAssertionError, + ); }); test('Valid base64 value', () { - expect(() => createDefaultConfiguration(packageName, signingHash), - returnsNormally); + expect( + () => createDefaultConfiguration(packageName, signingHashes), + returnsNormally, + ); }); }); } diff --git a/test/ios/ios_config_test.dart b/test/ios/ios_config_test.dart index f406164..e4a6a18 100644 --- a/test/ios/ios_config_test.dart +++ b/test/ios/ios_config_test.dart @@ -3,12 +3,14 @@ import 'package:freerasp/ios/ios_config.dart'; void main() { IOSconfig createConfiguration( - final String? appBundleId, final String? appTeamId) { + String? appBundleId, + String? appTeamId, + ) { return IOSconfig(appBundleId: appBundleId, appTeamId: appTeamId); } - const String appBundleId = 'appBundleId'; - const String appTeamId = 'appTeamId'; + const appBundleId = 'appBundleId'; + const appTeamId = 'appTeamId'; test('Object should be created', () { expect(() => createConfiguration(appBundleId, appTeamId), isNotNull); diff --git a/test/talsec_app_test.dart b/test/talsec_app_test.dart index d70f28e..72ba870 100644 --- a/test/talsec_app_test.dart +++ b/test/talsec_app_test.dart @@ -2,11 +2,12 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:freerasp/talsec_app.dart'; void main() { - final TalsecConfig config = TalsecConfig( + final config = TalsecConfig( androidConfig: AndroidConfig( expectedPackageName: 'PACKAGE_NAME', - expectedSigningCertificateHash: - 'AKoRuyLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0=', + expectedSigningCertificateHashes: [ + 'AKoRuyLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0=' + ], ), iosConfig: const IOSconfig( appBundleId: 'BUNDLE_ID', @@ -14,23 +15,33 @@ void main() { ), watcherMail: 'john@example.com', ); - const TalsecCallback callback = TalsecCallback(); + const callback = TalsecCallback(); test('Passing null values', () { - expect(() => TalsecApp(config: null, callback: callback), - throwsAssertionError); expect( - () => TalsecApp(config: config, callback: null), throwsAssertionError); + () => TalsecApp(config: null, callback: callback), + throwsAssertionError, + ); + expect( + () => TalsecApp(config: config, callback: null), + throwsAssertionError, + ); }); test('Passing empty objects', () { expect( - () => TalsecApp( - config: TalsecConfig(watcherMail: null), callback: callback), - throwsAssertionError); + () => TalsecApp( + config: TalsecConfig(watcherMail: null), + callback: callback, + ), + throwsAssertionError, + ); - // Callback CAN be unimplemented but at least [TalsecCallback] has to be provided. - expect(() => TalsecApp(config: config, callback: const TalsecCallback()), - returnsNormally); + // Callback CAN be unimplemented but at least [TalsecCallback] has to be + // provided. + expect( + () => TalsecApp(config: config, callback: const TalsecCallback()), + returnsNormally, + ); }); } diff --git a/test/talsec_config_test.dart b/test/talsec_config_test.dart index fda6127..acc20dd 100644 --- a/test/talsec_config_test.dart +++ b/test/talsec_config_test.dart @@ -2,63 +2,77 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:freerasp/talsec_app.dart'; void main() { - const String packageName = 'packageName'; - const String signingHash = 'AKoRuyLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0='; + const packageName = 'packageName'; + const signingHashes = [ + 'AKoRuyLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0=' + ]; - const String appBundleId = 'appBundleId'; - const String appTeamId = 'appTeamId'; + const appBundleId = 'appBundleId'; + const appTeamId = 'appTeamId'; - const String watcherMail = 'john@example.com'; + const watcherMail = 'john@example.com'; - final AndroidConfig androidConfig = AndroidConfig( + final androidConfig = AndroidConfig( expectedPackageName: packageName, - expectedSigningCertificateHash: signingHash, + expectedSigningCertificateHashes: signingHashes, ); - const IOSconfig iosConfig = IOSconfig( + const iosConfig = IOSconfig( appBundleId: appBundleId, appTeamId: appTeamId, ); test('Provide configuration for each platform', () { expect( - () => TalsecConfig( - androidConfig: androidConfig, - iosConfig: null, - watcherMail: watcherMail), - returnsNormally); + () => TalsecConfig( + androidConfig: androidConfig, + watcherMail: watcherMail, + ), + returnsNormally, + ); expect( - () => const TalsecConfig( - androidConfig: null, - iosConfig: iosConfig, - watcherMail: watcherMail), - returnsNormally); + () => const TalsecConfig( + iosConfig: iosConfig, + watcherMail: watcherMail, + ), + returnsNormally, + ); }); test('Provide no configuration at all', () { expect( - () => TalsecConfig( - androidConfig: null, iosConfig: null, watcherMail: watcherMail), - throwsAssertionError); + () => TalsecConfig( + watcherMail: watcherMail, + ), + throwsAssertionError, + ); }); test('Provide no watcher mail', () { expect( - () => TalsecConfig( - androidConfig: androidConfig, - iosConfig: iosConfig, - watcherMail: null), - throwsAssertionError); + () => TalsecConfig( + androidConfig: androidConfig, + iosConfig: iosConfig, + watcherMail: null, + ), + throwsAssertionError, + ); expect( - () => TalsecConfig( - androidConfig: androidConfig, iosConfig: null, watcherMail: null), - throwsAssertionError); + () => TalsecConfig( + androidConfig: androidConfig, + watcherMail: null, + ), + throwsAssertionError, + ); expect( - () => TalsecConfig( - androidConfig: null, iosConfig: iosConfig, watcherMail: null), - throwsAssertionError); + () => TalsecConfig( + iosConfig: iosConfig, + watcherMail: null, + ), + throwsAssertionError, + ); }); } diff --git a/test/utils/hash_converter_test.dart b/test/utils/hash_converter_test.dart index df2dce0..511d92b 100644 --- a/test/utils/hash_converter_test.dart +++ b/test/utils/hash_converter_test.dart @@ -12,27 +12,36 @@ void main() { setUp(() { validShaValue = - '00:AA:11:BB:22:CC:33:DD:44:EE:55:FF:66:AA:77:BB:88:CC:99:DD:00:EE:11:FF:22:AA:33:BB:44:CC:55:DD'; + '00:AA:11:BB:22:CC:33:DD:44:EE:55:FF:66:AA:77:BB:88:CC:99:DD:00:' + 'EE:11:FF:22:AA:33:BB:44:CC:55:DD'; validBase64Value = 'AKoRuyLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0='; }); test('standard SHA-256 value', () { - expect(hashConverter.fromSha256toBase64(validShaValue), - equals(validBase64Value)); + expect( + hashConverter.fromSha256toBase64(validShaValue), + equals(validBase64Value), + ); validShaValue = validShaValue.replaceAll(':', ''); - expect(hashConverter.fromSha256toBase64(validShaValue), - equals(validBase64Value)); + expect( + hashConverter.fromSha256toBase64(validShaValue), + equals(validBase64Value), + ); }); test('lowerCase SHA-256 value', () { validShaValue = validShaValue.toLowerCase(); - expect(hashConverter.fromSha256toBase64(validShaValue), - equals(validBase64Value)); + expect( + hashConverter.fromSha256toBase64(validShaValue), + equals(validBase64Value), + ); validShaValue = validShaValue.replaceAll(':', ''); - expect(hashConverter.fromSha256toBase64(validShaValue), - equals(validBase64Value)); + expect( + hashConverter.fromSha256toBase64(validShaValue), + equals(validBase64Value), + ); }); }); @@ -41,59 +50,70 @@ void main() { setUp(() { validShaValue = - '00:AA:11:BB:22:CC:33:DD:44:EE:55:FF:66:AA:77:BB:88:CC:99:DD:00:EE:11:FF:22:AA:33:BB:44:CC:55:DD'; + '00:AA:11:BB:22:CC:33:DD:44:EE:55:FF:66:AA:77:BB:88:CC:99:DD:00:' + 'EE:11:FF:22:AA:33:BB:44:CC:55:DD'; }); test('unknown delimiter', () { - final String invalidShaValue = validShaValue.replaceAll(':', '|'); - expect(() => hashConverter.fromSha256toBase64(invalidShaValue), - throwsA(isA())); + final invalidShaValue = validShaValue.replaceAll(':', '|'); + expect( + () => hashConverter.fromSha256toBase64(invalidShaValue), + throwsA(isA()), + ); }); test('invalid length', () { - final String invalidLongerShaValue = validShaValue + 'A'; - expect(() => hashConverter.fromSha256toBase64(invalidLongerShaValue), - throwsA(isA())); + final invalidLongerShaValue = '${validShaValue}A'; + expect( + () => hashConverter.fromSha256toBase64(invalidLongerShaValue), + throwsA(isA()), + ); - final String invalidLongerStrippedShaValue = + final invalidLongerStrippedShaValue = invalidLongerShaValue.replaceAll(':', ''); expect( - () => hashConverter - .fromSha256toBase64(invalidLongerStrippedShaValue), - throwsA(isA())); + () => + hashConverter.fromSha256toBase64(invalidLongerStrippedShaValue), + throwsA(isA()), + ); - final String invalidShorterShaValue = - validShaValue.replaceFirst('F', ''); - expect(() => hashConverter.fromSha256toBase64(invalidShorterShaValue), - throwsA(isA())); + final invalidShorterShaValue = validShaValue.replaceFirst('F', ''); + expect( + () => hashConverter.fromSha256toBase64(invalidShorterShaValue), + throwsA(isA()), + ); - final String invalidShorterStrippedShaValue = + final invalidShorterStrippedShaValue = invalidShorterShaValue.replaceAll(':', ''); expect( - () => hashConverter - .fromSha256toBase64(invalidShorterStrippedShaValue), - throwsA(isA())); + () => hashConverter + .fromSha256toBase64(invalidShorterStrippedShaValue), + throwsA(isA()), + ); }); test('contains non hex byte', () { - final String invalidHexShaValue = - validShaValue.replaceFirst('F', '@'); - expect(() => hashConverter.fromSha256toBase64(invalidHexShaValue), - throwsA(isA())); + final invalidHexShaValue = validShaValue.replaceFirst('F', '@'); + expect( + () => hashConverter.fromSha256toBase64(invalidHexShaValue), + throwsA(isA()), + ); - final String invalidHexStrippedShaValue = + final invalidHexStrippedShaValue = invalidHexShaValue.replaceFirst(':', ''); expect( - () => - hashConverter.fromSha256toBase64(invalidHexStrippedShaValue), - throwsA(isA())); + () => hashConverter.fromSha256toBase64(invalidHexStrippedShaValue), + throwsA(isA()), + ); }); test('is SHA-1 value', () { - const String sha1Value = + const sha1Value = '00:AA:11:BB:22:CC:33:DD:44:EE:55:FF:66:AA:77:BB:88:CC:99:DD'; - expect(() => hashConverter.fromSha256toBase64(sha1Value), - throwsA(isA())); + expect( + () => hashConverter.fromSha256toBase64(sha1Value), + throwsA(isA()), + ); }); }); }); @@ -105,13 +125,16 @@ void main() { setUp(() { validShaValue = - '00:AA:11:BB:22:CC:33:DD:44:EE:55:FF:66:AA:77:BB:88:CC:99:DD:00:EE:11:FF:22:AA:33:BB:44:CC:55:DD'; + '00:AA:11:BB:22:CC:33:DD:44:EE:55:FF:66:AA:77:BB:88:CC:99:DD:00:' + 'EE:11:FF:22:AA:33:BB:44:CC:55:DD'; validBase64Value = 'AKoRuyLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0='; }); test('standard base64 value which is sha-256', () { - expect(hashConverter.fromBase64toSha256(validBase64Value), - equals(validShaValue)); + expect( + hashConverter.fromBase64toSha256(validBase64Value), + equals(validShaValue), + ); }); }); @@ -124,15 +147,19 @@ void main() { test('invalid base64 value', () { validBase64Value = validBase64Value.replaceFirst('/', ''); - expect(() => hashConverter.fromBase64toSha256(validBase64Value), - throwsA(isA())); + expect( + () => hashConverter.fromBase64toSha256(validBase64Value), + throwsA(isA()), + ); }); test('valid base64 value but invalid sha-256 value', () { validBase64Value = 'q83vEjRWq83vEjRW'; expect(base64.decode(validBase64Value), isNotNull); - expect(() => hashConverter.fromBase64toSha256(validBase64Value), - throwsA(isA())); + expect( + () => hashConverter.fromBase64toSha256(validBase64Value), + throwsA(isA()), + ); }); }); });