Skip to content

Commit

Permalink
crypto: fix JWK RSA-PSS SubtleCrypto.exportKey
Browse files Browse the repository at this point in the history
PR-URL: #39828
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
panva authored and jasnell committed Aug 25, 2021
1 parent 367c624 commit 4441c3e
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 10 deletions.
6 changes: 3 additions & 3 deletions lib/internal/crypto/keys.js
Expand Up @@ -141,7 +141,7 @@ const {
validateOneOf(
options.format, 'options.format', [undefined, 'buffer', 'jwk']);
if (options.format === 'jwk') {
return this[kHandle].exportJwk({});
return this[kHandle].exportJwk({}, false);
}
}
return this[kHandle].export();
Expand Down Expand Up @@ -196,7 +196,7 @@ const {

export(options) {
if (options && options.format === 'jwk') {
return this[kHandle].exportJwk({});
return this[kHandle].exportJwk({}, false);
}
const {
format,
Expand All @@ -217,7 +217,7 @@ const {
throw new ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS(
'jwk', 'does not support encryption');
}
return this[kHandle].exportJwk({});
return this[kHandle].exportJwk({}, false);
}
const {
format,
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/crypto/webcrypto.js
Expand Up @@ -328,7 +328,7 @@ async function exportKeyJWK(key) {
const jwk = key[kKeyObject][kHandle].exportJwk({
key_ops: key.usages,
ext: key.extractable,
});
}, true);
switch (key.algorithm.name) {
case 'RSASSA-PKCS1-v1_5':
jwk.alg = normalizeHashName(
Expand Down
20 changes: 14 additions & 6 deletions src/crypto/crypto_keys.cc
Expand Up @@ -489,8 +489,13 @@ std::shared_ptr<KeyObjectData> ImportJWKSecretKey(
Maybe<bool> ExportJWKAsymmetricKey(
Environment* env,
std::shared_ptr<KeyObjectData> key,
Local<Object> target) {
Local<Object> target,
bool handleRsaPss) {
switch (EVP_PKEY_id(key->GetAsymmetricKey().get())) {
case EVP_PKEY_RSA_PSS: {
if (handleRsaPss) return ExportJWKRsaKey(env, key, target);
break;
}
case EVP_PKEY_RSA: return ExportJWKRsaKey(env, key, target);
case EVP_PKEY_EC: return ExportJWKEcKey(env, key, target);
case EVP_PKEY_ED25519:
Expand Down Expand Up @@ -609,14 +614,16 @@ static inline Maybe<bool> Tristate(bool b) {

Maybe<bool> ExportJWKInner(Environment* env,
std::shared_ptr<KeyObjectData> key,
Local<Value> result) {
Local<Value> result,
bool handleRsaPss) {
switch (key->GetKeyType()) {
case kKeyTypeSecret:
return ExportJWKSecretKey(env, key, result.As<Object>());
case kKeyTypePublic:
// Fall through
case kKeyTypePrivate:
return ExportJWKAsymmetricKey(env, key, result.As<Object>());
return ExportJWKAsymmetricKey(
env, key, result.As<Object>(), handleRsaPss);
default:
UNREACHABLE();
}
Expand All @@ -638,7 +645,7 @@ Maybe<bool> ManagedEVPPKey::ToEncodedPublicKey(
std::shared_ptr<KeyObjectData> data =
KeyObjectData::CreateAsymmetric(kKeyTypePublic, std::move(key));
*out = Object::New(env->isolate());
return ExportJWKInner(env, data, *out);
return ExportJWKInner(env, data, *out, false);
}

return Tristate(WritePublicKey(env, key.get(), config).ToLocal(out));
Expand All @@ -658,7 +665,7 @@ Maybe<bool> ManagedEVPPKey::ToEncodedPrivateKey(
std::shared_ptr<KeyObjectData> data =
KeyObjectData::CreateAsymmetric(kKeyTypePrivate, std::move(key));
*out = Object::New(env->isolate());
return ExportJWKInner(env, data, *out);
return ExportJWKInner(env, data, *out, false);
}

return Tristate(WritePrivateKey(env, key.get(), config).ToLocal(out));
Expand Down Expand Up @@ -1237,8 +1244,9 @@ void KeyObjectHandle::ExportJWK(
ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder());

CHECK(args[0]->IsObject());
CHECK(args[1]->IsBoolean());

ExportJWKInner(env, key->Data(), args[0]);
ExportJWKInner(env, key->Data(), args[0], args[1]->IsTrue());

args.GetReturnValue().Set(args[0]);
}
Expand Down
43 changes: 43 additions & 0 deletions test/parallel/test-webcrypto-export-import-rsa.js
@@ -1,6 +1,7 @@
'use strict';

const common = require('../common');
const fixtures = require('../common/fixtures');

if (!common.hasCrypto)
common.skip('missing crypto');
Expand Down Expand Up @@ -478,3 +479,45 @@ const testVectors = [
});
await Promise.all(variations);
})().then(common.mustCall());

{
const publicPem = fixtures.readKey('rsa_pss_public_2048.pem', 'ascii');
const privatePem = fixtures.readKey('rsa_pss_private_2048.pem', 'ascii');

const publicDer = Buffer.from(
publicPem.replace(
/(?:-----(?:BEGIN|END) PUBLIC KEY-----|\s)/g,
''
),
'base64'
);
const privateDer = Buffer.from(
privatePem.replace(
/(?:-----(?:BEGIN|END) PRIVATE KEY-----|\s)/g,
''
),
'base64'
);

(async () => {
const key = await subtle.importKey(
'spki',
publicDer,
{ name: 'RSA-PSS', hash: 'SHA-256' },
true,
['verify']);
const jwk = await subtle.exportKey('jwk', key);
assert.strictEqual(jwk.alg, 'PS256');
})().then(common.mustCall());

(async () => {
const key = await subtle.importKey(
'pkcs8',
privateDer,
{ name: 'RSA-PSS', hash: 'SHA-256' },
true,
['sign']);
const jwk = await subtle.exportKey('jwk', key);
assert.strictEqual(jwk.alg, 'PS256');
})().then(common.mustCall());
}

0 comments on commit 4441c3e

Please sign in to comment.