From 51d4873cb4e4c12551932e88f84d356d42644452 Mon Sep 17 00:00:00 2001 From: ljoy913 Date: Fri, 11 Mar 2022 11:34:51 -0800 Subject: [PATCH] Add jwk.crv validation --- src/error.ts | 2 ++ src/generate-test-data.ts | 2 +- src/shcKeyValidator.ts | 18 ++++++++++++++---- tests/keys.test.ts | 2 +- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/error.ts b/src/error.ts index 5f9e4be..806db91 100644 --- a/src/error.ts +++ b/src/error.ts @@ -44,6 +44,7 @@ export enum ErrorCode { INVALID_KEY_WRONG_ALG, INVALID_KEY_WRONG_USE, INVALID_KEY_WRONG_KID, + INVALID_KEY_WRONG_CRV, INVALID_KEY_SCHEMA, INVALID_KEY_PRIVATE, INVALID_KEY_X5C, @@ -74,6 +75,7 @@ export const ExcludableErrors: ExcludableError[] = [ new ExcludableError('invalid-key-wrong-alg', [ErrorCode.INVALID_KEY_WRONG_ALG]), new ExcludableError('invalid-key-wrong-use', [ErrorCode.INVALID_KEY_WRONG_USE]), new ExcludableError('invalid-key-wrong-kid', [ErrorCode.INVALID_KEY_WRONG_KID]), + new ExcludableError('invalid-key-wrong-crv', [ErrorCode.INVALID_KEY_WRONG_CRV]), new ExcludableError('invalid-key-schema', [ErrorCode.INVALID_KEY_SCHEMA]), new ExcludableError('not-yet-valid', [ErrorCode.NOT_YET_VALID]), new ExcludableError('fhir-schema-error', [ErrorCode.FHIR_SCHEMA_ERROR]), diff --git a/src/generate-test-data.ts b/src/generate-test-data.ts index 554667d..d404a5c 100644 --- a/src/generate-test-data.ts +++ b/src/generate-test-data.ts @@ -36,7 +36,7 @@ void generateAndStoreKey('valid_key.json', { kty: 'EC', size: 'P-256', props: { void generateAndStoreKey('private_key.json', { kty: 'EC', size: 'P-256', props: { alg: 'ES256', crv: 'P-256', use: 'sig' }}, 1, true); void generateAndStoreKey('valid_keys.json', { kty: 'EC', size: 'P-256', props: { alg: 'ES256', crv: 'P-256', use: 'sig' } }, 3); void generateAndStoreKey('wrong_kid_key.json', { kty: 'EC', size: 'P-256', props: { alg: 'ES256', crv: 'P-256', use: 'sig', kid: 'ThisIsNotTheThumbprintOfTheKey' } }); -void generateAndStoreKey('wrong_curve_key.json', { kty: 'EC', size: 'P-384', props: { alg: 'ES384', crv: 'P-384', use: 'sig' } }); +void generateAndStoreKey('wrong_curve_key.json', { kty: 'EC', size: 'P-384', props: { alg: 'ES256', crv: 'P-384', use: 'sig' } }); void generateAndStoreKey('wrong_use_key.json', { kty: 'EC', size: 'P-256', props: { alg: 'ES256', crv: 'P-256', use: 'enc' } }); void generateAndStoreKey('wrong_alg_key.json', { kty: 'EC', size: 'P-256', props: { alg: 'ES256K', crv: 'P-256', use: 'sig' } }); void generateAndStoreKey('wrong_kty_key.json', { kty: 'RSA', size: 2048 }); diff --git a/src/shcKeyValidator.ts b/src/shcKeyValidator.ts index 737c5dd..09ec3d1 100644 --- a/src/shcKeyValidator.ts +++ b/src/shcKeyValidator.ts @@ -237,8 +237,11 @@ export async function verifyAndImportHealthCardIssuerKey(keySet: KeySet, log = n } } + let addKey : JWK.Key; try { - key = await keys.add(key, issuerURL); + // Note: keys.add() returns a key that no longer has a .crv property - so the .crv test below was failing + // We assign this key to its own variable and do the key property checks on the original key variable below + addKey = await keys.add(key, issuerURL); } catch (error) { return log.error('Error adding key to keyStore : ' + (error as Error).message, ErrorCode.INVALID_KEY_UNKNOWN); } @@ -248,12 +251,12 @@ export async function verifyAndImportHealthCardIssuerKey(keySet: KeySet, log = n log.error(keyName + ': ' + "'kid' missing in issuer key", ErrorCode.INVALID_KEY_SCHEMA); } else { - await key.thumbprint('SHA-256') + await addKey.thumbprint('SHA-256') .then(tpDigest => { const thumbprint = jose.util.base64url.encode(tpDigest); - if (key.kid !== thumbprint) { + if (addKey.kid !== thumbprint) { log.error(keyName + ': ' + "'kid' does not match thumbprint in issuer key. expected: " - + thumbprint + ", actual: " + key.kid, ErrorCode.INVALID_KEY_WRONG_KID); + + thumbprint + ", actual: " + addKey.kid, ErrorCode.INVALID_KEY_WRONG_KID); } }) .catch(err => { @@ -281,6 +284,13 @@ export async function verifyAndImportHealthCardIssuerKey(keySet: KeySet, log = n } else if (key.use !== 'sig') { log.warn(keyName + ': ' + "wrong usage in issuer key. expected: 'sig', actual: " + key.use, ErrorCode.INVALID_KEY_WRONG_USE); } + + // check that curve is 'P-256' + if (!key.crv) { + log.error(keyName + ': ' + "'crv' missing in issuer key", ErrorCode.INVALID_KEY_SCHEMA); + } else if (key.crv !== 'P-256') { + log.warn(keyName + ': ' + "wrong curve in issuer key. expected: 'P-256', actual: " + key.crv, ErrorCode.INVALID_KEY_WRONG_CRV); + } } return log; diff --git a/tests/keys.test.ts b/tests/keys.test.ts index 20d791f..2465e68 100644 --- a/tests/keys.test.ts +++ b/tests/keys.test.ts @@ -41,7 +41,7 @@ test("Keys: wrong key identifier (kid)", async () => { }); test("Keys: wrong elliptic curve", async () => { - expect(await testKey('wrong_curve_key.json')).toContain(ErrorCode.INVALID_KEY_WRONG_ALG); + expect(await testKey('wrong_curve_key.json')).toContain(ErrorCode.INVALID_KEY_WRONG_CRV); }); test("Keys: wrong key use (use)", async () => {