Skip to content

Commit

Permalink
crypto: refactor verify acceptable key usage functions
Browse files Browse the repository at this point in the history
PR-URL: nodejs#45569
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
  • Loading branch information
panva authored and ErickWendel committed Nov 30, 2022
1 parent 93d4ef1 commit c43ec11
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 66 deletions.
32 changes: 11 additions & 21 deletions lib/internal/crypto/cfrg.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,32 +47,22 @@ const {

const generateKeyPair = promisify(_generateKeyPair);

function verifyAcceptableCfrgKeyUse(name, type, usages) {
function verifyAcceptableCfrgKeyUse(name, isPublic, usages) {
let checkSet;
switch (name) {
case 'X25519':
// Fall through
case 'X448':
switch (type) {
case 'private':
checkSet = ['deriveKey', 'deriveBits'];
break;
case 'public':
checkSet = [];
break;
}
checkSet = isPublic ? [] : ['deriveKey', 'deriveBits'];
break;
case 'Ed25519':
// Fall through
case 'Ed448':
switch (type) {
case 'private':
checkSet = ['sign'];
break;
case 'public':
checkSet = ['verify'];
break;
}
checkSet = isPublic ? ['verify'] : ['sign'];
break;
default:
throw lazyDOMException(
'The algorithm is not supported', 'NotSupportedError');
}
if (hasAnyNotIn(usages, checkSet)) {
throw lazyDOMException(
Expand Down Expand Up @@ -219,7 +209,7 @@ async function cfrgImportKey(
const usagesSet = new SafeSet(keyUsages);
switch (format) {
case 'spki': {
verifyAcceptableCfrgKeyUse(name, 'public', usagesSet);
verifyAcceptableCfrgKeyUse(name, true, usagesSet);
try {
keyObject = createPublicKey({
key: keyData,
Expand All @@ -233,7 +223,7 @@ async function cfrgImportKey(
break;
}
case 'pkcs8': {
verifyAcceptableCfrgKeyUse(name, 'private', usagesSet);
verifyAcceptableCfrgKeyUse(name, false, usagesSet);
try {
keyObject = createPrivateKey({
key: keyData,
Expand Down Expand Up @@ -298,7 +288,7 @@ async function cfrgImportKey(

verifyAcceptableCfrgKeyUse(
name,
isPublic ? 'public' : 'private',
isPublic,
usagesSet);

const publicKeyObject = createCFRGRawKey(
Expand All @@ -321,7 +311,7 @@ async function cfrgImportKey(
break;
}
case 'raw': {
verifyAcceptableCfrgKeyUse(name, 'public', usagesSet);
verifyAcceptableCfrgKeyUse(name, true, usagesSet);
keyObject = createCFRGRawKey(name, keyData, true);
break;
}
Expand Down
39 changes: 14 additions & 25 deletions lib/internal/crypto/ec.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,28 +54,18 @@ const {

const generateKeyPair = promisify(_generateKeyPair);

function verifyAcceptableEcKeyUse(name, type, usages) {
function verifyAcceptableEcKeyUse(name, isPublic, usages) {
let checkSet;
switch (name) {
case 'ECDH':
switch (type) {
case 'private':
checkSet = ['deriveKey', 'deriveBits'];
break;
case 'public':
checkSet = [];
break;
}
checkSet = isPublic ? [] : ['deriveKey', 'deriveBits'];
break;
case 'ECDSA':
switch (type) {
case 'private':
checkSet = ['sign'];
break;
case 'public':
checkSet = ['verify'];
break;
}
checkSet = isPublic ? ['verify'] : ['sign'];
break;
default:
throw lazyDOMException(
'The algorithm is not supported', 'NotSupportedError');
}
if (hasAnyNotIn(usages, checkSet)) {
throw lazyDOMException(
Expand Down Expand Up @@ -186,7 +176,7 @@ async function ecImportKey(
const usagesSet = new SafeSet(keyUsages);
switch (format) {
case 'spki': {
verifyAcceptableEcKeyUse(name, 'public', usagesSet);
verifyAcceptableEcKeyUse(name, true, usagesSet);
try {
keyObject = createPublicKey({
key: keyData,
Expand All @@ -200,7 +190,7 @@ async function ecImportKey(
break;
}
case 'pkcs8': {
verifyAcceptableEcKeyUse(name, 'private', usagesSet);
verifyAcceptableEcKeyUse(name, false, usagesSet);
try {
keyObject = createPrivateKey({
key: keyData,
Expand All @@ -221,11 +211,10 @@ async function ecImportKey(
if (keyData.crv !== namedCurve)
throw lazyDOMException('Named curve mismatch', 'DataError');

if (keyData.d !== undefined) {
verifyAcceptableEcKeyUse(name, 'private', usagesSet);
} else {
verifyAcceptableEcKeyUse(name, 'public', usagesSet);
}
verifyAcceptableEcKeyUse(
name,
keyData.d === undefined,
usagesSet);

if (usagesSet.size > 0 && keyData.use !== undefined) {
if (algorithm.name === 'ECDSA' && keyData.use !== 'sig')
Expand Down Expand Up @@ -265,7 +254,7 @@ async function ecImportKey(
break;
}
case 'raw': {
verifyAcceptableEcKeyUse(name, 'public', usagesSet);
verifyAcceptableEcKeyUse(name, true, usagesSet);
keyObject = createECPublicKeyRaw(namedCurve, keyData);
break;
}
Expand Down
32 changes: 12 additions & 20 deletions lib/internal/crypto/rsa.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,28 +74,20 @@ const kRsaVariants = {
};
const generateKeyPair = promisify(_generateKeyPair);

function verifyAcceptableRsaKeyUse(name, type, usages) {
function verifyAcceptableRsaKeyUse(name, isPublic, usages) {
let checkSet;
switch (name) {
case 'RSA-OAEP':
switch (type) {
case 'private':
checkSet = ['decrypt', 'unwrapKey'];
break;
case 'public':
checkSet = ['encrypt', 'wrapKey'];
break;
}
checkSet = isPublic ? ['encrypt', 'wrapKey'] : ['decrypt', 'unwrapKey'];
break;
case 'RSA-PSS':
// Fall through
case 'RSASSA-PKCS1-v1_5':
checkSet = isPublic ? ['verify'] : ['sign'];
break;
default:
switch (type) {
case 'private':
checkSet = ['sign'];
break;
case 'public':
checkSet = ['verify'];
break;
}
throw lazyDOMException(
'The algorithm is not supported', 'NotSupportedError');
}
if (hasAnyNotIn(usages, checkSet)) {
throw lazyDOMException(
Expand Down Expand Up @@ -244,7 +236,7 @@ async function rsaImportKey(
let keyObject;
switch (format) {
case 'spki': {
verifyAcceptableRsaKeyUse(algorithm.name, 'public', usagesSet);
verifyAcceptableRsaKeyUse(algorithm.name, true, usagesSet);
try {
keyObject = createPublicKey({
key: keyData,
Expand All @@ -258,7 +250,7 @@ async function rsaImportKey(
break;
}
case 'pkcs8': {
verifyAcceptableRsaKeyUse(algorithm.name, 'private', usagesSet);
verifyAcceptableRsaKeyUse(algorithm.name, false, usagesSet);
try {
keyObject = createPrivateKey({
key: keyData,
Expand All @@ -277,7 +269,7 @@ async function rsaImportKey(

verifyAcceptableRsaKeyUse(
algorithm.name,
keyData.d !== undefined ? 'private' : 'public',
keyData.d === undefined,
usagesSet);

if (keyData.kty !== 'RSA')
Expand Down

0 comments on commit c43ec11

Please sign in to comment.