diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a6a88353..cbac6a02 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -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 diff --git a/darwin/webcrypto.podspec b/darwin/webcrypto.podspec index 13c9d766..14a1d006 100644 --- a/darwin/webcrypto.podspec +++ b/darwin/webcrypto.podspec @@ -28,7 +28,6 @@ Pod::Spec.new do |s| s.compiler_flags = [ '-DOPENSSL_NO_ASM', '-DDOPENSSL_SMALL', - '-GCC_WARN_INHIBIT_ALL_WARNINGS', '-w', ] diff --git a/lib/src/impl_ffi/impl_ffi.dart b/lib/src/impl_ffi/impl_ffi.dart index a228134f..d0bedf10 100644 --- a/lib/src/impl_ffi/impl_ffi.dart +++ b/lib/src/impl_ffi/impl_ffi.dart @@ -92,4 +92,7 @@ final class _WebCryptoImpl implements WebCryptoImpl { @override final rsaOaepPublicKey = const _StaticRsaOaepPublicKeyImpl(); + + @override + final pbkdf2SecretKey = const _StaticPbkdf2SecretKeyImpl(); } diff --git a/lib/src/impl_ffi/impl_ffi.pbkdf2.dart b/lib/src/impl_ffi/impl_ffi.pbkdf2.dart index 153eaa26..c9d4b16f 100644 --- a/lib/src/impl_ffi/impl_ffi.pbkdf2.dart +++ b/lib/src/impl_ffi/impl_ffi.pbkdf2.dart @@ -16,14 +16,23 @@ part of 'impl_ffi.dart'; -Future pbkdf2SecretKey_importRawKey(List keyData) async { - return _Pbkdf2SecretKey(Uint8List.fromList(keyData)); +Future pbkdf2SecretKey_importRawKey(List keyData) async { + return _Pbkdf2SecretKeyImpl(Uint8List.fromList(keyData)); } -class _Pbkdf2SecretKey implements Pbkdf2SecretKey { +final class _StaticPbkdf2SecretKeyImpl implements StaticPbkdf2SecretKeyImpl { + const _StaticPbkdf2SecretKeyImpl(); + + @override + Future importRawKey(List keyData) { + return pbkdf2SecretKey_importRawKey(keyData); + } +} + +final class _Pbkdf2SecretKeyImpl implements Pbkdf2SecretKeyImpl { final Uint8List _key; - _Pbkdf2SecretKey(this._key); + _Pbkdf2SecretKeyImpl(this._key); @override String toString() { diff --git a/lib/src/impl_interface/impl_interface.dart b/lib/src/impl_interface/impl_interface.dart index 72c90f42..149d7aac 100644 --- a/lib/src/impl_interface/impl_interface.dart +++ b/lib/src/impl_interface/impl_interface.dart @@ -24,6 +24,7 @@ part 'impl_interface.aescbc.dart'; part 'impl_interface.aesctr.dart'; part 'impl_interface.hmac.dart'; part 'impl_interface.rsaoaep.dart'; +part 'impl_interface.pbkdf2.dart'; part 'impl_interface.aesgcm.dart'; /// Interface to be provided by platform implementations. @@ -49,4 +50,5 @@ abstract interface class WebCryptoImpl { StaticHmacSecretKeyImpl get hmacSecretKey; StaticRsaOaepPrivateKeyImpl get rsaOaepPrivateKey; StaticRsaOaepPublicKeyImpl get rsaOaepPublicKey; + StaticPbkdf2SecretKeyImpl get pbkdf2SecretKey; } diff --git a/lib/src/impl_interface/impl_interface.pbkdf2.dart b/lib/src/impl_interface/impl_interface.pbkdf2.dart new file mode 100644 index 00000000..26f1d1ea --- /dev/null +++ b/lib/src/impl_interface/impl_interface.pbkdf2.dart @@ -0,0 +1,23 @@ +// 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 StaticPbkdf2SecretKeyImpl { + Future importRawKey(List keyData); +} + +abstract interface class Pbkdf2SecretKeyImpl { + Future deriveBits(int length, Hash hash, List salt, int iterations); +} diff --git a/lib/src/impl_js/impl_js.dart b/lib/src/impl_js/impl_js.dart index 13a06273..e5bb3cf9 100644 --- a/lib/src/impl_js/impl_js.dart +++ b/lib/src/impl_js/impl_js.dart @@ -78,4 +78,7 @@ final class _WebCryptoImpl implements WebCryptoImpl { @override final rsaOaepPublicKey = const _StaticRsaOaepPublicKeyImpl(); + + @override + final pbkdf2SecretKey = const _StaticPbkdf2SecretKeyImpl(); } diff --git a/lib/src/impl_js/impl_js.pbkdf2.dart b/lib/src/impl_js/impl_js.pbkdf2.dart index b8479971..8f72f857 100644 --- a/lib/src/impl_js/impl_js.pbkdf2.dart +++ b/lib/src/impl_js/impl_js.pbkdf2.dart @@ -18,8 +18,8 @@ part of 'impl_js.dart'; const _pbkdf2AlgorithmName = 'PBKDF2'; -Future pbkdf2SecretKey_importRawKey(List keyData) async { - return _Pbkdf2SecretKey(await _importKey( +Future pbkdf2SecretKey_importRawKey(List keyData) async { + return _Pbkdf2SecretKeyImpl(await _importKey( 'raw', keyData, const subtle.Algorithm(name: _pbkdf2AlgorithmName), @@ -31,9 +31,18 @@ Future pbkdf2SecretKey_importRawKey(List keyData) async { )); } -class _Pbkdf2SecretKey implements Pbkdf2SecretKey { +final class _StaticPbkdf2SecretKeyImpl implements StaticPbkdf2SecretKeyImpl { + const _StaticPbkdf2SecretKeyImpl(); + + @override + Future importRawKey(List keyData) { + return pbkdf2SecretKey_importRawKey(keyData); + } +} + +final class _Pbkdf2SecretKeyImpl implements Pbkdf2SecretKeyImpl { final subtle.JSCryptoKey _key; - _Pbkdf2SecretKey(this._key); + _Pbkdf2SecretKeyImpl(this._key); @override String toString() { diff --git a/lib/src/impl_stub.dart b/lib/src/impl_stub.dart index 697b0c97..25e90a32 100644 --- a/lib/src/impl_stub.dart +++ b/lib/src/impl_stub.dart @@ -202,5 +202,3 @@ Future hkdfSecretKey_importRawKey(List keyData) => //---------------------- PBKDF2 -Future pbkdf2SecretKey_importRawKey(List keyData) => - throw _notImplemented; diff --git a/lib/src/impl_stub/impl_stub.dart b/lib/src/impl_stub/impl_stub.dart index d3e8ea67..86ad67d0 100644 --- a/lib/src/impl_stub/impl_stub.dart +++ b/lib/src/impl_stub/impl_stub.dart @@ -22,6 +22,7 @@ part 'impl_stub.aesctr.dart'; part 'impl_stub.aesgcm.dart'; part 'impl_stub.hmac.dart'; part 'impl_stub.rsaoaep.dart'; +part 'impl_stub.pbkdf2.dart'; const WebCryptoImpl webCryptImpl = _WebCryptoImpl(); @@ -45,4 +46,7 @@ final class _WebCryptoImpl implements WebCryptoImpl { @override final rsaOaepPublicKey = const _StaticRsaOaepPublicKeyImpl(); + + @override + final pbkdf2SecretKey = const _StaticPbkdf2SecretKeyImpl(); } diff --git a/lib/src/impl_stub/impl_stub.pbkdf2.dart b/lib/src/impl_stub/impl_stub.pbkdf2.dart new file mode 100644 index 00000000..e1fc586f --- /dev/null +++ b/lib/src/impl_stub/impl_stub.pbkdf2.dart @@ -0,0 +1,24 @@ +// 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_stub.dart'; + +final class _StaticPbkdf2SecretKeyImpl implements StaticPbkdf2SecretKeyImpl { + const _StaticPbkdf2SecretKeyImpl(); + + @override + Future importRawKey(List keyData) { + throw UnimplementedError('Not implemented'); + } +} diff --git a/lib/src/webcrypto/webcrypto.pbkdf2.dart b/lib/src/webcrypto/webcrypto.pbkdf2.dart index 4c6892bf..f35fc5ee 100644 --- a/lib/src/webcrypto/webcrypto.pbkdf2.dart +++ b/lib/src/webcrypto/webcrypto.pbkdf2.dart @@ -50,17 +50,20 @@ part of 'webcrypto.dart'; /// /// [1]: https://tools.ietf.org/html/rfc8018 // TODO: Rewrite all RFC links to use https://www.rfc-editor.org/rfc/rfcXXXX -@sealed -abstract class Pbkdf2SecretKey { - Pbkdf2SecretKey._(); // keep the constructor private. + +final class Pbkdf2SecretKey { + final Pbkdf2SecretKeyImpl _impl; + + Pbkdf2SecretKey._(this._impl); // keep the constructor private. /// Import [Pbkdf2SecretKey] from raw [keyData]. /// /// Creates a [Pbkdf2SecretKey] for key derivation using [keyData]. /// /// {@macro Pbkdf2SecretKey:example} - static Future importRawKey(List keyData) { - return impl.pbkdf2SecretKey_importRawKey(keyData); + static Future importRawKey(List keyData) async { + final impl = await webCryptImpl.pbkdf2SecretKey.importRawKey(keyData); + return Pbkdf2SecretKey._(impl); } /// Derive key from [salt] and password specified as `keyData` in @@ -90,5 +93,6 @@ abstract class Pbkdf2SecretKey { Hash hash, List salt, int iterations, - ); + ) => + _impl.deriveBits(length, hash, salt, iterations); }