diff options
-rw-r--r-- | cli/tests/unit/webcrypto_test.ts | 25 | ||||
-rw-r--r-- | ext/crypto/import_key.rs | 9 |
2 files changed, 31 insertions, 3 deletions
diff --git a/cli/tests/unit/webcrypto_test.ts b/cli/tests/unit/webcrypto_test.ts index c4958fbdf..2d101e975 100644 --- a/cli/tests/unit/webcrypto_test.ts +++ b/cli/tests/unit/webcrypto_test.ts @@ -1419,3 +1419,28 @@ Deno.test(async function testImportEcSpkiPkcs8() { assertEquals(new Uint8Array(expPrivateKeySPKI), spki);*/ } }); + +Deno.test(async function testBase64Forgiving() { + const keyData = `{ + "kty": "oct", + "k": "xxx", + "alg": "HS512", + "key_ops": ["sign", "verify"], + "ext": true + }`; + + const key = await crypto.subtle.importKey( + "jwk", + JSON.parse(keyData), + { name: "HMAC", hash: "SHA-512" }, + true, + ["sign", "verify"], + ); + + assert(key instanceof CryptoKey); + assertEquals(key.type, "secret"); + assertEquals((key.algorithm as HmacKeyAlgorithm).length, 16); + + const exportedKey = await crypto.subtle.exportKey("jwk", key); + assertEquals(exportedKey.k, "xxw"); +}); diff --git a/ext/crypto/import_key.rs b/ext/crypto/import_key.rs index c658d7c12..56fbfa111 100644 --- a/ext/crypto/import_key.rs +++ b/ext/crypto/import_key.rs @@ -105,9 +105,12 @@ pub fn op_crypto_import_key( } } +const URL_SAFE_FORGIVING: base64::Config = + base64::URL_SAFE_NO_PAD.decode_allow_trailing_bits(true); + macro_rules! jwt_b64_int_or_err { ($name:ident, $b64:expr, $err:expr) => { - let bytes = base64::decode_config($b64, base64::URL_SAFE) + let bytes = base64::decode_config($b64, URL_SAFE_FORGIVING) .map_err(|_| data_error($err))?; let $name = UIntBytes::new(&bytes).map_err(|_| data_error($err))?; }; @@ -1001,7 +1004,7 @@ fn import_key_ec( fn import_key_aes(key_data: KeyData) -> Result<ImportKeyResult, AnyError> { Ok(match key_data { KeyData::JwkSecret { k } => { - let data = base64::decode_config(k, base64::URL_SAFE) + let data = base64::decode_config(k, URL_SAFE_FORGIVING) .map_err(|_| data_error("invalid key data"))?; ImportKeyResult::Hmac { raw_data: RawKeyData::Secret(data.into()), @@ -1014,7 +1017,7 @@ fn import_key_aes(key_data: KeyData) -> Result<ImportKeyResult, AnyError> { fn import_key_hmac(key_data: KeyData) -> Result<ImportKeyResult, AnyError> { Ok(match key_data { KeyData::JwkSecret { k } => { - let data = base64::decode_config(k, base64::URL_SAFE) + let data = base64::decode_config(k, URL_SAFE_FORGIVING) .map_err(|_| data_error("invalid key data"))?; ImportKeyResult::Hmac { raw_data: RawKeyData::Secret(data.into()), |