Skip to content

Commit

Permalink
Merge branch 'master' into refactor-ecdh
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasfj authored Oct 17, 2024
2 parents 86b35f7 + cdf81ad commit a74fbc2
Show file tree
Hide file tree
Showing 30 changed files with 449 additions and 148 deletions.
17 changes: 9 additions & 8 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,15 @@ jobs:
- run: flutter test --platform chrome
- run: flutter test integration_test/webcrypto_test.dart -d macos
working-directory: ./example
- uses: nanasess/setup-chromedriver@v2
- name: Run integration_test with chromedriver
working-directory: ./example
run: |
../tool/with-chromedriver.sh flutter drive \
--driver=test_driver/integration_test.dart \
--target=integration_test/webcrypto_test.dart \
-d chrome
# TODO: Enable chromdriver testing on MacOS when it works reliably
#- uses: nanasess/setup-chromedriver@v2
#- name: Run integration_test with chromedriver
# working-directory: ./example
# run: |
# ../tool/with-chromedriver.sh flutter drive \
# --driver=test_driver/integration_test.dart \
# --target=integration_test/webcrypto_test.dart \
# -d chrome
- run: flutter pub run test -p vm,chrome # TODO: Enable firefox if it works
windows:
name: webcrypto on Windows desktop / Chrome / Firefox
Expand Down
1 change: 0 additions & 1 deletion darwin/webcrypto.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ Pod::Spec.new do |s|
s.compiler_flags = [
'-DOPENSSL_NO_ASM',
'-DDOPENSSL_SMALL',
'-GCC_WARN_INHIBIT_ALL_WARNINGS',
'-w',
]

Expand Down
16 changes: 6 additions & 10 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
Expand All @@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
}
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
Expand All @@ -21,10 +22,6 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
Expand Down Expand Up @@ -66,5 +63,4 @@ flutter {
}

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
13 changes: 0 additions & 13 deletions example/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
buildscript {
ext.kotlin_version = '1.6.21'
repositories {
google()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:8.4.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

allprojects {
repositories {
google()
Expand Down
30 changes: 22 additions & 8 deletions example/android/settings.gradle
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
include ':app'
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}()

def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}

def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.4.1" apply false
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
}

include ":app"
2 changes: 1 addition & 1 deletion lib/src/impl_ffi/impl_ffi.aescbc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ final class _StaticAesCbcSecretKeyImpl implements StaticAesCbcSecretKeyImpl {
}
}

final class _AesCbcSecretKeyImpl extends AesCbcSecretKeyImpl {
final class _AesCbcSecretKeyImpl implements AesCbcSecretKeyImpl {
final Uint8List _key;
_AesCbcSecretKeyImpl(this._key);

Expand Down
2 changes: 1 addition & 1 deletion lib/src/impl_ffi/impl_ffi.aesctr.dart
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ final class _StaticAesCtrSecretKeyImpl implements StaticAesCtrSecretKeyImpl {
}
}

final class _AesCtrSecretKeyImpl extends AesCtrSecretKeyImpl {
final class _AesCtrSecretKeyImpl implements AesCtrSecretKeyImpl {
final Uint8List _key;
_AesCtrSecretKeyImpl(this._key);

Expand Down
35 changes: 27 additions & 8 deletions lib/src/impl_ffi/impl_ffi.aesgcm.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@

part of 'impl_ffi.dart';

Future<AesGcmSecretKey> aesGcm_importRawKey(List<int> keyData) async =>
_AesGcmSecretKey(_aesImportRawKey(keyData));
Future<AesGcmSecretKeyImpl> aesGcm_importRawKey(List<int> keyData) async =>
_AesGcmSecretKeyImpl(_aesImportRawKey(keyData));

Future<AesGcmSecretKey> aesGcm_importJsonWebKey(
Future<AesGcmSecretKeyImpl> aesGcm_importJsonWebKey(
Map<String, dynamic> jwk,
) async =>
_AesGcmSecretKey(_aesImportJwkKey(
_AesGcmSecretKeyImpl(_aesImportJwkKey(
jwk,
expectedJwkAlgSuffix: 'GCM',
));

Future<AesGcmSecretKey> aesGcm_generateKey(int length) async =>
_AesGcmSecretKey(_aesGenerateKey(length));
Future<AesGcmSecretKeyImpl> aesGcm_generateKey(int length) async =>
_AesGcmSecretKeyImpl(_aesGenerateKey(length));

Future<Uint8List> _aesGcmEncryptDecrypt(
List<int> key,
Expand Down Expand Up @@ -111,9 +111,28 @@ Future<Uint8List> _aesGcmEncryptDecrypt(
});
}

class _AesGcmSecretKey implements AesGcmSecretKey {
final class _StaticAesGcmSecretKeyImpl implements StaticAesGcmSecretKeyImpl {
const _StaticAesGcmSecretKeyImpl();

@override
Future<AesGcmSecretKeyImpl> importRawKey(List<int> keyData) async {
return await aesGcm_importRawKey(keyData);
}

@override
Future<AesGcmSecretKeyImpl> importJsonWebKey(Map<String, dynamic> jwk) async {
return await aesGcm_importJsonWebKey(jwk);
}

@override
Future<AesGcmSecretKeyImpl> generateKey(int length) async {
return await aesGcm_generateKey(length);
}
}

final class _AesGcmSecretKeyImpl implements AesGcmSecretKeyImpl {
final Uint8List _key;
_AesGcmSecretKey(this._key);
_AesGcmSecretKeyImpl(this._key);

@override
String toString() {
Expand Down
9 changes: 9 additions & 0 deletions lib/src/impl_ffi/impl_ffi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,13 @@ final class _WebCryptoImpl implements WebCryptoImpl {

@override
final ecdhPublicKey = const _StaticEcdhPublicKeyImpl();

@override
final aesGcmSecretKey = const _StaticAesGcmSecretKeyImpl();

@override
final hmacSecretKey = const _StaticHmacSecretKeyImpl();

@override
final pbkdf2SecretKey = const _StaticPbkdf2SecretKeyImpl();
}
37 changes: 28 additions & 9 deletions lib/src/impl_ffi/impl_ffi.hmac.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,18 @@ String _hmacJwkAlgFromHash(_Hash hash) {
throw UnsupportedError('hash is not supported');
}

Future<HmacSecretKey> hmacSecretKey_importRawKey(
Future<HmacSecretKeyImpl> hmacSecretKey_importRawKey(
List<int> keyData,
Hash hash, {
int? length,
}) async {
return _HmacSecretKey(
return _HmacSecretKeyImpl(
_asUint8ListZeroedToBitLength(keyData, length),
_Hash.fromHash(hash),
);
}

Future<HmacSecretKey> hmacSecretKey_importJsonWebKey(
Future<HmacSecretKeyImpl> hmacSecretKey_importJsonWebKey(
Map<String, dynamic> jwk,
Hash hash, {
int? length,
Expand All @@ -86,7 +86,7 @@ Future<HmacSecretKey> hmacSecretKey_importJsonWebKey(
return hmacSecretKey_importRawKey(keyData, hash, length: length);
}

Future<HmacSecretKey> hmacSecretKey_generateKey(
Future<HmacSecretKeyImpl> hmacSecretKey_generateKey(
Hash hash, {
int? length,
}) async {
Expand All @@ -95,25 +95,44 @@ Future<HmacSecretKey> hmacSecretKey_generateKey(
final keyData = Uint8List((length / 8).ceil());
fillRandomBytes(keyData);

return _HmacSecretKey(
return _HmacSecretKeyImpl(
_asUint8ListZeroedToBitLength(keyData, length),
h,
);
}

class _HmacSecretKey implements HmacSecretKey {
final class _StaticHmacSecretKeyImpl implements StaticHmacSecretKeyImpl {
const _StaticHmacSecretKeyImpl();

@override
Future<HmacSecretKeyImpl> importRawKey(List<int> keyData, Hash hash, {int? length}) {
return hmacSecretKey_importRawKey(keyData, hash, length: length);
}

@override
Future<HmacSecretKeyImpl> importJsonWebKey(Map<String, dynamic> jwk, Hash hash, {int? length}) {
return hmacSecretKey_importJsonWebKey(jwk, hash, length: length);
}

@override
Future<HmacSecretKeyImpl> generateKey(Hash hash, {int? length = 32}) {
return hmacSecretKey_generateKey(hash, length: length);
}
}

final class _HmacSecretKeyImpl implements HmacSecretKeyImpl {
final _Hash _hash;
final Uint8List _keyData;

_HmacSecretKey(this._keyData, this._hash);
_HmacSecretKeyImpl(this._keyData, this._hash);

@override
String toString() {
return 'Instance of \'HmacSecretKey\'';
return 'Instance of \'HmacSecretKeyImpl\'';
}

@override
Future<Uint8List> signBytes(List<int> data) => signStream(Stream.value(data));
Future<Uint8List> signBytes(List<int> data) => signStream(Stream.value(data));

@override
Future<Uint8List> signStream(Stream<List<int>> data) {
Expand Down
17 changes: 13 additions & 4 deletions lib/src/impl_ffi/impl_ffi.pbkdf2.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,23 @@

part of 'impl_ffi.dart';

Future<Pbkdf2SecretKey> pbkdf2SecretKey_importRawKey(List<int> keyData) async {
return _Pbkdf2SecretKey(Uint8List.fromList(keyData));
Future<Pbkdf2SecretKeyImpl> pbkdf2SecretKey_importRawKey(List<int> keyData) async {
return _Pbkdf2SecretKeyImpl(Uint8List.fromList(keyData));
}

class _Pbkdf2SecretKey implements Pbkdf2SecretKey {
final class _StaticPbkdf2SecretKeyImpl implements StaticPbkdf2SecretKeyImpl {
const _StaticPbkdf2SecretKeyImpl();

@override
Future<Pbkdf2SecretKeyImpl> importRawKey(List<int> keyData) {
return pbkdf2SecretKey_importRawKey(keyData);
}
}

final class _Pbkdf2SecretKeyImpl implements Pbkdf2SecretKeyImpl {
final Uint8List _key;

_Pbkdf2SecretKey(this._key);
_Pbkdf2SecretKeyImpl(this._key);

@override
String toString() {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/impl_interface/impl_interface.aescbc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ abstract interface class StaticAesCbcSecretKeyImpl {
Future<AesCbcSecretKeyImpl> generateKey(int length);
}

abstract class AesCbcSecretKeyImpl {
abstract interface class AesCbcSecretKeyImpl {
Future<Uint8List> encryptBytes(List<int> data, List<int> iv);
Future<Uint8List> decryptBytes(List<int> data, List<int> iv);
Stream<Uint8List> encryptStream(Stream<List<int>> data, List<int> iv);
Expand Down
2 changes: 1 addition & 1 deletion lib/src/impl_interface/impl_interface.aesctr.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ abstract interface class StaticAesCtrSecretKeyImpl {
Future<AesCtrSecretKeyImpl> generateKey(int length);
}

abstract class AesCtrSecretKeyImpl {
abstract interface class AesCtrSecretKeyImpl {
Future<Uint8List> encryptBytes(List<int> data, List<int> counter, int length);
Future<Uint8List> decryptBytes(List<int> data, List<int> counter, int length);
Stream<Uint8List> encryptStream(Stream<List<int>> data, List<int> counter, int length);
Expand Down
28 changes: 28 additions & 0 deletions lib/src/impl_interface/impl_interface.aesgcm.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

part of 'impl_interface.dart';

abstract interface class StaticAesGcmSecretKeyImpl {
Future<AesGcmSecretKeyImpl> importRawKey(List<int> keyData);
Future<AesGcmSecretKeyImpl> importJsonWebKey(Map<String, dynamic> jwk);
Future<AesGcmSecretKeyImpl> generateKey(int length);
}

abstract interface class AesGcmSecretKeyImpl {
Future<Uint8List> encryptBytes(List<int> data, List<int> iv, {List<int>? additionalData, int? tagLength});
Future<Uint8List> decryptBytes(List<int> data, List<int> iv, {List<int>? additionalData, int? tagLength});
Future<Uint8List> exportRawKey();
Future<Map<String, dynamic>> exportJsonWebKey();
}
11 changes: 11 additions & 0 deletions lib/src/impl_interface/impl_interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ part 'impl_interface.aescbc.dart';
part 'impl_interface.aesctr.dart';
part 'impl_interface.ecdh.dart';

import 'package:webcrypto/webcrypto.dart';


part 'impl_interface.aescbc.dart';
part 'impl_interface.aesctr.dart';
part 'impl_interface.hmac.dart';
part 'impl_interface.pbkdf2.dart';
part 'impl_interface.aesgcm.dart';

/// Interface to be provided by platform implementations.
///
Expand All @@ -45,4 +53,7 @@ abstract interface class WebCryptoImpl {
StaticAesCtrSecretKeyImpl get aesCtrSecretKey;
StaticEcdhPrivateKeyImpl get ecdhPrivateKey;
StaticEcdhPublicKeyImpl get ecdhPublicKey;
StaticAesGcmSecretKeyImpl get aesGcmSecretKey;
StaticHmacSecretKeyImpl get hmacSecretKey;
StaticPbkdf2SecretKeyImpl get pbkdf2SecretKey;
}
Loading

0 comments on commit a74fbc2

Please sign in to comment.