Skip to content

Commit a74fbc2

Browse files
authored
Merge branch 'master' into refactor-ecdh
2 parents 86b35f7 + cdf81ad commit a74fbc2

30 files changed

+449
-148
lines changed

Diff for: .github/workflows/test.yml

+9-8
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,15 @@ jobs:
5656
- run: flutter test --platform chrome
5757
- run: flutter test integration_test/webcrypto_test.dart -d macos
5858
working-directory: ./example
59-
- uses: nanasess/setup-chromedriver@v2
60-
- name: Run integration_test with chromedriver
61-
working-directory: ./example
62-
run: |
63-
../tool/with-chromedriver.sh flutter drive \
64-
--driver=test_driver/integration_test.dart \
65-
--target=integration_test/webcrypto_test.dart \
66-
-d chrome
59+
# TODO: Enable chromdriver testing on MacOS when it works reliably
60+
#- uses: nanasess/setup-chromedriver@v2
61+
#- name: Run integration_test with chromedriver
62+
# working-directory: ./example
63+
# run: |
64+
# ../tool/with-chromedriver.sh flutter drive \
65+
# --driver=test_driver/integration_test.dart \
66+
# --target=integration_test/webcrypto_test.dart \
67+
# -d chrome
6768
- run: flutter pub run test -p vm,chrome # TODO: Enable firefox if it works
6869
windows:
6970
name: webcrypto on Windows desktop / Chrome / Firefox

Diff for: darwin/webcrypto.podspec

-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ Pod::Spec.new do |s|
2828
s.compiler_flags = [
2929
'-DOPENSSL_NO_ASM',
3030
'-DDOPENSSL_SMALL',
31-
'-GCC_WARN_INHIBIT_ALL_WARNINGS',
3231
'-w',
3332
]
3433

Diff for: example/android/app/build.gradle

+6-10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
plugins {
2+
id "com.android.application"
3+
id "kotlin-android"
4+
id "dev.flutter.flutter-gradle-plugin"
5+
}
6+
17
def localProperties = new Properties()
28
def localPropertiesFile = rootProject.file('local.properties')
39
if (localPropertiesFile.exists()) {
@@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
612
}
713
}
814

9-
def flutterRoot = localProperties.getProperty('flutter.sdk')
10-
if (flutterRoot == null) {
11-
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12-
}
13-
1415
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
1516
if (flutterVersionCode == null) {
1617
flutterVersionCode = '1'
@@ -21,10 +22,6 @@ if (flutterVersionName == null) {
2122
flutterVersionName = '1.0'
2223
}
2324

24-
apply plugin: 'com.android.application'
25-
apply plugin: 'kotlin-android'
26-
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27-
2825
android {
2926
compileSdkVersion flutter.compileSdkVersion
3027
ndkVersion flutter.ndkVersion
@@ -66,5 +63,4 @@ flutter {
6663
}
6764

6865
dependencies {
69-
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
7066
}

Diff for: example/android/build.gradle

-13
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,3 @@
1-
buildscript {
2-
ext.kotlin_version = '1.6.21'
3-
repositories {
4-
google()
5-
mavenCentral()
6-
}
7-
8-
dependencies {
9-
classpath 'com.android.tools.build:gradle:8.4.1'
10-
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11-
}
12-
}
13-
141
allprojects {
152
repositories {
163
google()

Diff for: example/android/settings.gradle

+22-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
1-
include ':app'
1+
pluginManagement {
2+
def flutterSdkPath = {
3+
def properties = new Properties()
4+
file("local.properties").withInputStream { properties.load(it) }
5+
def flutterSdkPath = properties.getProperty("flutter.sdk")
6+
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
7+
return flutterSdkPath
8+
}()
29

3-
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4-
def properties = new Properties()
10+
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
511

6-
assert localPropertiesFile.exists()
7-
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
12+
repositories {
13+
google()
14+
mavenCentral()
15+
gradlePluginPortal()
16+
}
17+
}
818

9-
def flutterSdkPath = properties.getProperty("flutter.sdk")
10-
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11-
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
19+
plugins {
20+
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
21+
id "com.android.application" version "8.4.1" apply false
22+
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
23+
}
24+
25+
include ":app"

Diff for: lib/src/impl_ffi/impl_ffi.aescbc.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ final class _StaticAesCbcSecretKeyImpl implements StaticAesCbcSecretKeyImpl {
114114
}
115115
}
116116

117-
final class _AesCbcSecretKeyImpl extends AesCbcSecretKeyImpl {
117+
final class _AesCbcSecretKeyImpl implements AesCbcSecretKeyImpl {
118118
final Uint8List _key;
119119
_AesCbcSecretKeyImpl(this._key);
120120

Diff for: lib/src/impl_ffi/impl_ffi.aesctr.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ final class _StaticAesCtrSecretKeyImpl implements StaticAesCtrSecretKeyImpl {
221221
}
222222
}
223223

224-
final class _AesCtrSecretKeyImpl extends AesCtrSecretKeyImpl {
224+
final class _AesCtrSecretKeyImpl implements AesCtrSecretKeyImpl {
225225
final Uint8List _key;
226226
_AesCtrSecretKeyImpl(this._key);
227227

Diff for: lib/src/impl_ffi/impl_ffi.aesgcm.dart

+27-8
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,19 @@
1616

1717
part of 'impl_ffi.dart';
1818

19-
Future<AesGcmSecretKey> aesGcm_importRawKey(List<int> keyData) async =>
20-
_AesGcmSecretKey(_aesImportRawKey(keyData));
19+
Future<AesGcmSecretKeyImpl> aesGcm_importRawKey(List<int> keyData) async =>
20+
_AesGcmSecretKeyImpl(_aesImportRawKey(keyData));
2121

22-
Future<AesGcmSecretKey> aesGcm_importJsonWebKey(
22+
Future<AesGcmSecretKeyImpl> aesGcm_importJsonWebKey(
2323
Map<String, dynamic> jwk,
2424
) async =>
25-
_AesGcmSecretKey(_aesImportJwkKey(
25+
_AesGcmSecretKeyImpl(_aesImportJwkKey(
2626
jwk,
2727
expectedJwkAlgSuffix: 'GCM',
2828
));
2929

30-
Future<AesGcmSecretKey> aesGcm_generateKey(int length) async =>
31-
_AesGcmSecretKey(_aesGenerateKey(length));
30+
Future<AesGcmSecretKeyImpl> aesGcm_generateKey(int length) async =>
31+
_AesGcmSecretKeyImpl(_aesGenerateKey(length));
3232

3333
Future<Uint8List> _aesGcmEncryptDecrypt(
3434
List<int> key,
@@ -111,9 +111,28 @@ Future<Uint8List> _aesGcmEncryptDecrypt(
111111
});
112112
}
113113

114-
class _AesGcmSecretKey implements AesGcmSecretKey {
114+
final class _StaticAesGcmSecretKeyImpl implements StaticAesGcmSecretKeyImpl {
115+
const _StaticAesGcmSecretKeyImpl();
116+
117+
@override
118+
Future<AesGcmSecretKeyImpl> importRawKey(List<int> keyData) async {
119+
return await aesGcm_importRawKey(keyData);
120+
}
121+
122+
@override
123+
Future<AesGcmSecretKeyImpl> importJsonWebKey(Map<String, dynamic> jwk) async {
124+
return await aesGcm_importJsonWebKey(jwk);
125+
}
126+
127+
@override
128+
Future<AesGcmSecretKeyImpl> generateKey(int length) async {
129+
return await aesGcm_generateKey(length);
130+
}
131+
}
132+
133+
final class _AesGcmSecretKeyImpl implements AesGcmSecretKeyImpl {
115134
final Uint8List _key;
116-
_AesGcmSecretKey(this._key);
135+
_AesGcmSecretKeyImpl(this._key);
117136

118137
@override
119138
String toString() {

Diff for: lib/src/impl_ffi/impl_ffi.dart

+9
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,13 @@ final class _WebCryptoImpl implements WebCryptoImpl {
8686

8787
@override
8888
final ecdhPublicKey = const _StaticEcdhPublicKeyImpl();
89+
90+
@override
91+
final aesGcmSecretKey = const _StaticAesGcmSecretKeyImpl();
92+
93+
@override
94+
final hmacSecretKey = const _StaticHmacSecretKeyImpl();
95+
96+
@override
97+
final pbkdf2SecretKey = const _StaticPbkdf2SecretKeyImpl();
8998
}

Diff for: lib/src/impl_ffi/impl_ffi.hmac.dart

+28-9
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,18 @@ String _hmacJwkAlgFromHash(_Hash hash) {
4949
throw UnsupportedError('hash is not supported');
5050
}
5151

52-
Future<HmacSecretKey> hmacSecretKey_importRawKey(
52+
Future<HmacSecretKeyImpl> hmacSecretKey_importRawKey(
5353
List<int> keyData,
5454
Hash hash, {
5555
int? length,
5656
}) async {
57-
return _HmacSecretKey(
57+
return _HmacSecretKeyImpl(
5858
_asUint8ListZeroedToBitLength(keyData, length),
5959
_Hash.fromHash(hash),
6060
);
6161
}
6262

63-
Future<HmacSecretKey> hmacSecretKey_importJsonWebKey(
63+
Future<HmacSecretKeyImpl> hmacSecretKey_importJsonWebKey(
6464
Map<String, dynamic> jwk,
6565
Hash hash, {
6666
int? length,
@@ -86,7 +86,7 @@ Future<HmacSecretKey> hmacSecretKey_importJsonWebKey(
8686
return hmacSecretKey_importRawKey(keyData, hash, length: length);
8787
}
8888

89-
Future<HmacSecretKey> hmacSecretKey_generateKey(
89+
Future<HmacSecretKeyImpl> hmacSecretKey_generateKey(
9090
Hash hash, {
9191
int? length,
9292
}) async {
@@ -95,25 +95,44 @@ Future<HmacSecretKey> hmacSecretKey_generateKey(
9595
final keyData = Uint8List((length / 8).ceil());
9696
fillRandomBytes(keyData);
9797

98-
return _HmacSecretKey(
98+
return _HmacSecretKeyImpl(
9999
_asUint8ListZeroedToBitLength(keyData, length),
100100
h,
101101
);
102102
}
103103

104-
class _HmacSecretKey implements HmacSecretKey {
104+
final class _StaticHmacSecretKeyImpl implements StaticHmacSecretKeyImpl {
105+
const _StaticHmacSecretKeyImpl();
106+
107+
@override
108+
Future<HmacSecretKeyImpl> importRawKey(List<int> keyData, Hash hash, {int? length}) {
109+
return hmacSecretKey_importRawKey(keyData, hash, length: length);
110+
}
111+
112+
@override
113+
Future<HmacSecretKeyImpl> importJsonWebKey(Map<String, dynamic> jwk, Hash hash, {int? length}) {
114+
return hmacSecretKey_importJsonWebKey(jwk, hash, length: length);
115+
}
116+
117+
@override
118+
Future<HmacSecretKeyImpl> generateKey(Hash hash, {int? length = 32}) {
119+
return hmacSecretKey_generateKey(hash, length: length);
120+
}
121+
}
122+
123+
final class _HmacSecretKeyImpl implements HmacSecretKeyImpl {
105124
final _Hash _hash;
106125
final Uint8List _keyData;
107126

108-
_HmacSecretKey(this._keyData, this._hash);
127+
_HmacSecretKeyImpl(this._keyData, this._hash);
109128

110129
@override
111130
String toString() {
112-
return 'Instance of \'HmacSecretKey\'';
131+
return 'Instance of \'HmacSecretKeyImpl\'';
113132
}
114133

115134
@override
116-
Future<Uint8List> signBytes(List<int> data) => signStream(Stream.value(data));
135+
Future<Uint8List> signBytes(List<int> data) => signStream(Stream.value(data));
117136

118137
@override
119138
Future<Uint8List> signStream(Stream<List<int>> data) {

Diff for: lib/src/impl_ffi/impl_ffi.pbkdf2.dart

+13-4
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,23 @@
1616

1717
part of 'impl_ffi.dart';
1818

19-
Future<Pbkdf2SecretKey> pbkdf2SecretKey_importRawKey(List<int> keyData) async {
20-
return _Pbkdf2SecretKey(Uint8List.fromList(keyData));
19+
Future<Pbkdf2SecretKeyImpl> pbkdf2SecretKey_importRawKey(List<int> keyData) async {
20+
return _Pbkdf2SecretKeyImpl(Uint8List.fromList(keyData));
2121
}
2222

23-
class _Pbkdf2SecretKey implements Pbkdf2SecretKey {
23+
final class _StaticPbkdf2SecretKeyImpl implements StaticPbkdf2SecretKeyImpl {
24+
const _StaticPbkdf2SecretKeyImpl();
25+
26+
@override
27+
Future<Pbkdf2SecretKeyImpl> importRawKey(List<int> keyData) {
28+
return pbkdf2SecretKey_importRawKey(keyData);
29+
}
30+
}
31+
32+
final class _Pbkdf2SecretKeyImpl implements Pbkdf2SecretKeyImpl {
2433
final Uint8List _key;
2534

26-
_Pbkdf2SecretKey(this._key);
35+
_Pbkdf2SecretKeyImpl(this._key);
2736

2837
@override
2938
String toString() {

Diff for: lib/src/impl_interface/impl_interface.aescbc.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ abstract interface class StaticAesCbcSecretKeyImpl {
2020
Future<AesCbcSecretKeyImpl> generateKey(int length);
2121
}
2222

23-
abstract class AesCbcSecretKeyImpl {
23+
abstract interface class AesCbcSecretKeyImpl {
2424
Future<Uint8List> encryptBytes(List<int> data, List<int> iv);
2525
Future<Uint8List> decryptBytes(List<int> data, List<int> iv);
2626
Stream<Uint8List> encryptStream(Stream<List<int>> data, List<int> iv);

Diff for: lib/src/impl_interface/impl_interface.aesctr.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ abstract interface class StaticAesCtrSecretKeyImpl {
2020
Future<AesCtrSecretKeyImpl> generateKey(int length);
2121
}
2222

23-
abstract class AesCtrSecretKeyImpl {
23+
abstract interface class AesCtrSecretKeyImpl {
2424
Future<Uint8List> encryptBytes(List<int> data, List<int> counter, int length);
2525
Future<Uint8List> decryptBytes(List<int> data, List<int> counter, int length);
2626
Stream<Uint8List> encryptStream(Stream<List<int>> data, List<int> counter, int length);

Diff for: lib/src/impl_interface/impl_interface.aesgcm.dart

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
part of 'impl_interface.dart';
16+
17+
abstract interface class StaticAesGcmSecretKeyImpl {
18+
Future<AesGcmSecretKeyImpl> importRawKey(List<int> keyData);
19+
Future<AesGcmSecretKeyImpl> importJsonWebKey(Map<String, dynamic> jwk);
20+
Future<AesGcmSecretKeyImpl> generateKey(int length);
21+
}
22+
23+
abstract interface class AesGcmSecretKeyImpl {
24+
Future<Uint8List> encryptBytes(List<int> data, List<int> iv, {List<int>? additionalData, int? tagLength});
25+
Future<Uint8List> decryptBytes(List<int> data, List<int> iv, {List<int>? additionalData, int? tagLength});
26+
Future<Uint8List> exportRawKey();
27+
Future<Map<String, dynamic>> exportJsonWebKey();
28+
}

Diff for: lib/src/impl_interface/impl_interface.dart

+11
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ part 'impl_interface.aescbc.dart';
2323
part 'impl_interface.aesctr.dart';
2424
part 'impl_interface.ecdh.dart';
2525

26+
import 'package:webcrypto/webcrypto.dart';
27+
28+
29+
part 'impl_interface.aescbc.dart';
30+
part 'impl_interface.aesctr.dart';
31+
part 'impl_interface.hmac.dart';
32+
part 'impl_interface.pbkdf2.dart';
33+
part 'impl_interface.aesgcm.dart';
2634

2735
/// Interface to be provided by platform implementations.
2836
///
@@ -45,4 +53,7 @@ abstract interface class WebCryptoImpl {
4553
StaticAesCtrSecretKeyImpl get aesCtrSecretKey;
4654
StaticEcdhPrivateKeyImpl get ecdhPrivateKey;
4755
StaticEcdhPublicKeyImpl get ecdhPublicKey;
56+
StaticAesGcmSecretKeyImpl get aesGcmSecretKey;
57+
StaticHmacSecretKeyImpl get hmacSecretKey;
58+
StaticPbkdf2SecretKeyImpl get pbkdf2SecretKey;
4859
}

0 commit comments

Comments
 (0)