diff --git a/lib/src/impl_ffi/impl_ffi.aesgcm.dart b/lib/src/impl_ffi/impl_ffi.aesgcm.dart index 7922dd1a..cfff22bb 100644 --- a/lib/src/impl_ffi/impl_ffi.aesgcm.dart +++ b/lib/src/impl_ffi/impl_ffi.aesgcm.dart @@ -41,7 +41,7 @@ Future _aesGcmEncryptDecrypt( final additionalData_ = additionalData ??= []; if (isEncrypt && data.length > (1 << 39) - 256) { // More than this is not allowed by Web crypto spec, we shall honor that. - throw _OperationError('data may not be more than 2^39 - 256 bytes'); + throw operationError('data may not be more than 2^39 - 256 bytes'); } if (tagLength != 32 && tagLength != 64 && @@ -50,7 +50,7 @@ Future _aesGcmEncryptDecrypt( tagLength != 112 && tagLength != 120 && tagLength != 128) { - throw _OperationError('tagLength must be 32, 64, 96, 104, 112, 120 or 128'); + throw operationError('tagLength must be 32, 64, 96, 104, 112, 120 or 128'); } // TODO: Check iv length is less than EVP_AEAD_nonce_length, if this is a requirement! diff --git a/lib/src/impl_ffi/impl_ffi.dart b/lib/src/impl_ffi/impl_ffi.dart index cbcb64bb..980d8931 100644 --- a/lib/src/impl_ffi/impl_ffi.dart +++ b/lib/src/impl_ffi/impl_ffi.dart @@ -48,16 +48,6 @@ part 'impl_ffi.rsa_common.dart'; part 'impl_ffi.ec_common.dart'; part 'impl_ffi.aes_common.dart'; -/// Implementation of [OperationError]. -class _OperationError extends Error implements OperationError { - final String _message; - - _OperationError(this._message); - - @override - String toString() => _message; -} - const WebCryptoImpl webCryptImpl = _WebCryptoImpl(); final class _WebCryptoImpl implements WebCryptoImpl { diff --git a/lib/src/impl_ffi/impl_ffi.ec_common.dart b/lib/src/impl_ffi/impl_ffi.ec_common.dart index bc7b37f1..77bb89be 100644 --- a/lib/src/impl_ffi/impl_ffi.ec_common.dart +++ b/lib/src/impl_ffi/impl_ffi.ec_common.dart @@ -41,7 +41,7 @@ EllipticCurve _ecCurveFromNID(int nid) { return EllipticCurve.p521; } // This should never happen! - throw _OperationError('internal error detecting curve'); + throw operationError('internal error detecting curve'); } String _ecCurveToJwkCrv(EllipticCurve curve) { diff --git a/lib/src/impl_ffi/impl_ffi.ecdh.dart b/lib/src/impl_ffi/impl_ffi.ecdh.dart index 76e8f3e7..fb720822 100644 --- a/lib/src/impl_ffi/impl_ffi.ecdh.dart +++ b/lib/src/impl_ffi/impl_ffi.ecdh.dart @@ -142,7 +142,7 @@ final class _EcdhPrivateKeyImpl implements EcdhPrivateKeyImpl { ssl.EC_GROUP_get_degree(ssl.EC_KEY_get0_group(privEcKey)); final maxLength = 8 * (fieldSize / 8).ceil(); if (length > maxLength) { - throw _OperationError( + throw operationError( 'Length in ECDH key derivation is too large. ' 'Maximum allowed is $maxLength bits.', ); diff --git a/lib/src/impl_ffi/impl_ffi.hkdf.dart b/lib/src/impl_ffi/impl_ffi.hkdf.dart index 0d49a35b..9ea1cb6b 100644 --- a/lib/src/impl_ffi/impl_ffi.hkdf.dart +++ b/lib/src/impl_ffi/impl_ffi.hkdf.dart @@ -53,7 +53,7 @@ final class _HkdfSecretKeyImpl implements HkdfSecretKeyImpl { // Mirroring limitations in chromium: // https://chromium.googlesource.com/chromium/src/+/43d62c50b705f88c67b14539e91fd8fd017f70c4/components/webcrypto/algorithms/hkdf.cc#74 if (length % 8 != 0) { - throw _OperationError('The length for HKDF must be a multiple of 8 bits'); + throw operationError('The length for HKDF must be a multiple of 8 bits'); } final lengthInBytes = length ~/ 8; @@ -76,7 +76,7 @@ final class _HkdfSecretKeyImpl implements HkdfSecretKeyImpl { if (ERR_GET_LIB(packed_error) == ERR_LIB_HKDF && ERR_GET_REASON(packed_error) == HKDF_R_OUTPUT_TOO_LARGE) { ssl.ERR_clear_error(); - throw _OperationError( + throw operationError( 'Length specified for HkdfSecretKey.deriveBits is too long', ); } diff --git a/lib/src/impl_ffi/impl_ffi.pbkdf2.dart b/lib/src/impl_ffi/impl_ffi.pbkdf2.dart index eb06cf60..9a88d3b4 100644 --- a/lib/src/impl_ffi/impl_ffi.pbkdf2.dart +++ b/lib/src/impl_ffi/impl_ffi.pbkdf2.dart @@ -55,15 +55,15 @@ final class _Pbkdf2SecretKeyImpl implements Pbkdf2SecretKeyImpl { // Mirroring limitations in chromium: // https://chromium.googlesource.com/chromium/src/+/43d62c50b705f88c67b14539e91fd8fd017f70c4/components/webcrypto/algorithms/pbkdf2.cc#75 if (length % 8 != 0) { - throw _OperationError( + throw operationError( 'The length for PBKDF2 must be a multiple of 8 bits'); } if (length == 0) { - throw _OperationError( + throw operationError( 'A length of zero is not allowed Pbkdf2SecretKey.deriveBits'); } if (iterations <= 0) { - throw _OperationError( + throw operationError( 'Iterations <= 0 is not allowed for Pbkdf2SecretKey.deriveBits'); } diff --git a/lib/src/impl_ffi/impl_ffi.utils.dart b/lib/src/impl_ffi/impl_ffi.utils.dart index 1ba74e40..1837e9f1 100644 --- a/lib/src/impl_ffi/impl_ffi.utils.dart +++ b/lib/src/impl_ffi/impl_ffi.utils.dart @@ -102,7 +102,7 @@ void _checkOp(bool condition, {String? message, String? fallback}) { // Always extract the error to ensure we clear the error queue. final err = _extractError(); message ??= err ?? fallback ?? 'unknown error'; - throw _OperationError(message); + throw operationError(message); } } diff --git a/lib/src/impl_interface/impl_interface.dart b/lib/src/impl_interface/impl_interface.dart index e4f25060..330f9d22 100644 --- a/lib/src/impl_interface/impl_interface.dart +++ b/lib/src/impl_interface/impl_interface.dart @@ -17,6 +17,8 @@ library impl_stub; import 'dart:typed_data'; import 'dart:async'; +import 'package:meta/meta.dart'; + part 'impl_interface.aescbc.dart'; part 'impl_interface.aesctr.dart'; part 'impl_interface.hmac.dart'; @@ -62,6 +64,20 @@ enum EllipticCurve { p521, } +/// Thrown when an operation failed for an operation-specific reason. +final class OperationError extends Error { + final String _message; + + OperationError._(this._message); // keep the constructor private. + + @override + String toString() => _message; +} + +/// Creating an [OperationError]. +@internal +OperationError operationError(String message) => OperationError._(message); + /// Interface to be provided by platform implementations. /// /// A platform implementation of `package:webcrypto` must define a diff --git a/lib/src/impl_js/impl_js.dart b/lib/src/impl_js/impl_js.dart index 3d24d93a..69f127a3 100644 --- a/lib/src/impl_js/impl_js.dart +++ b/lib/src/impl_js/impl_js.dart @@ -19,7 +19,6 @@ import 'dart:typed_data'; import 'package:webcrypto/src/impl_interface/impl_interface.dart'; -import '../webcrypto/webcrypto.dart'; import '../crypto_subtle.dart' as subtle; part 'impl_js.aescbc.dart'; @@ -37,14 +36,6 @@ part 'impl_js.rsapss.dart'; part 'impl_js.rsassapkcs1v15.dart'; part 'impl_js.utils.dart'; -/// Implementation of [OperationError]. -class _OperationError extends Error implements OperationError { - final String _message; - _OperationError(this._message); - @override - String toString() => _message; -} - const WebCryptoImpl webCryptImpl = _WebCryptoImpl(); final class _WebCryptoImpl implements WebCryptoImpl { diff --git a/lib/src/impl_js/impl_js.utils.dart b/lib/src/impl_js/impl_js.utils.dart index f2bc5bb8..0f799c75 100644 --- a/lib/src/impl_js/impl_js.utils.dart +++ b/lib/src/impl_js/impl_js.utils.dart @@ -69,7 +69,7 @@ Object _translateDomException( case 'DataError': return FormatException(message); case 'OperationError': - return _OperationError(message); + return operationError(message); case 'InvalidAccessError': // InvalidAccessError occurs when the request operation is not valid for // the provided key. This is typically because: diff --git a/lib/src/webcrypto/webcrypto.dart b/lib/src/webcrypto/webcrypto.dart index d6bf9dc0..93f1645b 100644 --- a/lib/src/webcrypto/webcrypto.dart +++ b/lib/src/webcrypto/webcrypto.dart @@ -20,7 +20,6 @@ /// This could be documented for each method or at library level. library webcrypto; -import 'package:meta/meta.dart'; import 'dart:convert'; import 'dart:async'; import 'dart:typed_data'; @@ -32,7 +31,8 @@ import '../impl_stub/impl_stub.dart' if (dart.library.ffi) '../impl_ffi/impl_ffi.dart' if (dart.library.js) '../impl_js/impl_js.dart' show webCryptImpl; -export '../impl_interface/impl_interface.dart' show KeyPair, EllipticCurve; +export '../impl_interface/impl_interface.dart' + show KeyPair, EllipticCurve, OperationError; part 'webcrypto.aescbc.dart'; part 'webcrypto.aesctr.dart'; @@ -47,9 +47,3 @@ part 'webcrypto.random.dart'; part 'webcrypto.rsaoaep.dart'; part 'webcrypto.rsapss.dart'; part 'webcrypto.rsassapkcs1v15.dart'; - -/// Thrown when an operation failed for an operation-specific reason. -@sealed -abstract class OperationError extends Error { - OperationError._(); // keep the constructor private. -}