diff --git a/lib/src/testing/utils/testrunner.dart b/lib/src/testing/utils/testrunner.dart index 6aed509a..f61dee65 100644 --- a/lib/src/testing/utils/testrunner.dart +++ b/lib/src/testing/utils/testrunner.dart @@ -63,6 +63,10 @@ class _TestCase { // Parameters for key import (always required) final Map? importKeyParams; + // If not `null`, then importing private or public key MUST throw + // an exception that contains this string. + final String? importKeyException; + // Parameters for sign/verify (required, if there is a signature) final Map? signVerifyParams; @@ -90,6 +94,7 @@ class _TestCase { this.signVerifyParams, this.encryptDecryptParams, this.deriveParams, + this.importKeyException, }); factory _TestCase.fromJson(Map json) { @@ -110,6 +115,7 @@ class _TestCase { derivedBits: _optionalBase64Decode(json['derivedBits']), derivedLength: json['derivedLength'] as int?, importKeyParams: _optionalStringMapDecode(json['importKeyParams']), + importKeyException: json['importKeyException'] as String?, signVerifyParams: _optionalStringMapDecode(json['signVerifyParams']), encryptDecryptParams: _optionalStringMapDecode(json['encryptDecryptParams']), @@ -691,7 +697,14 @@ void _validateTestCase( check(c.importKeyParams != null); check((c.signVerifyParams != null) == (r._signBytes != null)); check((c.encryptDecryptParams != null) == (r._encryptBytes != null)); - check((c.deriveParams != null) == (r._deriveBits != null)); + + if (c.deriveParams != null) { + check((c.deriveParams != null) == (r._deriveBits != null)); + + if (r._deriveBits != null) { + check(c.derivedLength != null); + } + } if (c.signature != null) { check(r._signBytes != null); } @@ -701,9 +714,6 @@ void _validateTestCase( if (c.derivedBits != null) { check(r._deriveBits != null); } - if (r._deriveBits != null) { - check(c.derivedLength != null); - } // Check that data matches the methods we have in the runner. check(r._importPrivateRawKey != null || c.privateRawKeyData == null); @@ -712,6 +722,30 @@ void _validateTestCase( check(r._importPublicRawKey != null || c.publicRawKeyData == null); check(r._importPublicSpkiKey != null || c.publicSpkiKeyData == null); check(r._importPublicJsonWebKey != null || c.publicJsonWebKeyData == null); + + if (c.generateKeyParams != null) { + check(c.importKeyException == null, + 'importKeyException must be null when generateKeyParams is provided'); + } + + if (c.importKeyException != null) { + check(c.plaintext == null, + 'plaintext must be null when importKeyException is provided'); + check(c.signature == null, + 'signature must be null when importKeyException is provided'); + check(c.ciphertext == null, + 'ciphertext must be null when importKeyException is provided'); + check(c.derivedBits == null, + 'derivedBits must be null when importKeyException is provided'); + check(c.derivedLength == null, + 'derivedLength must be null when importKeyException is provided'); + check(c.signVerifyParams == null, + 'signVerifyParams must be null when importKeyException is provided'); + check(c.encryptDecryptParams == null, + 'encryptDecryptParams must be null when importKeyException is provided'); + check(c.deriveParams == null, + 'deriveParams must be null when importKeyException is provided'); + } } void _runTests( @@ -746,6 +780,30 @@ void _runTests( publicKey = pair.publicKey; privateKey = pair.privateKey; }); + } else if (c.importKeyException != null) { + if (c.privatePkcs8KeyData != null) { + test('pkcs8 import exception', () async { + try { + await r._importPrivatePkcs8Key!( + c.privatePkcs8KeyData!, {'curve': 'p-521'}); + check(false, 'Expected an exception for P-512 import'); + } catch (e) { + check(e.toString().contains(c.importKeyException!)); + } + }); + } + if (c.privateJsonWebKeyData != null) { + test('jwk import exception', () async { + try { + await r._importPrivateJsonWebKey!( + c.privateJsonWebKeyData!, {'curve': 'p-521'}); + check(false, 'Expected an exception for P-512 import'); + } catch (e) { + check(e.toString().contains(c.importKeyException!)); + } + }); + } + return; } else { test('import key-pair', () async { // Get a privateKey diff --git a/lib/src/testing/webcrypto/ecdh.dart b/lib/src/testing/webcrypto/ecdh.dart index 2d3c18ac..bd4bd216 100644 --- a/lib/src/testing/webcrypto/ecdh.dart +++ b/lib/src/testing/webcrypto/ecdh.dart @@ -111,6 +111,39 @@ final _testData = [ "importKeyParams": {"curve": "p-256"}, "deriveParams": {} }, + { + "name": "generated on boringssl/linux (pkcs8 import key exception) at 2020-01-22T23:24:34", + "privatePkcs8KeyData": + "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg3aTiZ7odKAODYk4BpZlzulBCB/BptmxjtvrzyXI71UyhRANCAATl0GVa8O1sXXf2NV5qGJ/9/Vq8PVWCZuezADa1F0Vr2TaB8BseZIW+rhmEmLC2FfCdxj9NmLp00SilRTm40Hxm", + "publicRawKeyData": + "BHiIXxrwhM92v4ueDrj3x1JJY4uS+II/IJPjqMvaKj/QfoOllnEkrnaOW1owBYRBMnP0pPouPkqbVfPACMUsfKs=", + "publicSpkiKeyData": + "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeIhfGvCEz3a/i54OuPfHUklji5L4gj8gk+Ooy9oqP9B+g6WWcSSudo5bWjAFhEEyc/Sk+i4+SptV88AIxSx8qw==", + "importKeyParams": {"curve": "p-256"}, + "importKeyException": "FormatException: incorrect elliptic curve" + }, + { + "name": "generated on boringssl/linux (jwk import key exception) at 2020-01-22T23:24:34", + "privateJsonWebKeyData": { + "kty": "EC", + "crv": "P-256", + "x": "5dBlWvDtbF139jVeahif_f1avD1VgmbnswA2tRdFa9k", + "y": "NoHwGx5khb6uGYSYsLYV8J3GP02YunTRKKVFObjQfGY", + "d": "3aTiZ7odKAODYk4BpZlzulBCB_BptmxjtvrzyXI71Uw" + }, + "publicRawKeyData": + "BHiIXxrwhM92v4ueDrj3x1JJY4uS+II/IJPjqMvaKj/QfoOllnEkrnaOW1owBYRBMnP0pPouPkqbVfPACMUsfKs=", + "publicSpkiKeyData": + "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeIhfGvCEz3a/i54OuPfHUklji5L4gj8gk+Ooy9oqP9B+g6WWcSSudo5bWjAFhEEyc/Sk+i4+SptV88AIxSx8qw==", + "publicJsonWebKeyData": { + "kty": "EC", + "crv": "P-256", + "x": "eIhfGvCEz3a_i54OuPfHUklji5L4gj8gk-Ooy9oqP9A", + "y": "foOllnEkrnaOW1owBYRBMnP0pPouPkqbVfPACMUsfKs" + }, + "importKeyParams": {"curve": "p-256"}, + "importKeyException": "JWK property \"crv\" is not" + }, { "name": "generated on chrome/linux at 2020-01-22T23:24:39", "privatePkcs8KeyData":