Skip to content

Commit

Permalink
fixes #20: allow verification with multiple keys
Browse files Browse the repository at this point in the history
  • Loading branch information
Carl Anderson committed Sep 14, 2021
1 parent e18e025 commit 6e73440
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 16 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/AuthorizeHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ class AuthorizeHandler extends SMARTHandler {
const res = this.response;
const sim = this.sim;

// console.log('AuthHandler.handle()', req); // XXX
// Handle response from picker, login or auth screen
if (this.inputs.patient ) sim.patient = this.inputs.patient;
if (this.inputs.provider ) sim.provider = this.inputs.provider;
Expand Down
32 changes: 16 additions & 16 deletions src/TokenHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,19 +172,25 @@ class TokenHandler extends SMARTHandler {
if (this.request.body.client_assertion_type != assertionType) {
console.error(`Missing expected request body field: client_assertion_type="${assertionType}"`);
}
var jwks = JSON.parse(token.context.jwks);

const keys = await jose.JWK.asKeyStore(token.context.jwks);
// TODO: don't crash if jwks is missing or malformed.
const uri = token.context.jwks_uri;
// TODO: if uri, fetch and replace jwks.
const key = await jose.JWK.asKey(jwks.keys[0], "public");
// TODO: if multiple keys, try them all.
// TODO: if uri, fetch and replace / add to jwks.
const jwt = this.request.body.client_assertion;
const validated = await jose.JWS.createVerify(key).verify(jwt);

// Note: at this point the signature is cryptographically verified.
const validated = await jose.JWS.createVerify(keys).verify(jwt);

// Inspect the verification result for standards compliance.
const payload = JSON.parse(validated.payload);

const kid = validated.header['kid'];
const key = keys.get(kid);
if (key.kid !== kid) {
throw Lib.OAuthError.from({
code : 403,
error: 'invalid key',
msg : `Expected JWT kid (${kid}) to match (${key.kid})`,
}, key.kid, kid);
}
const typ = validated.header['typ'];
if (typ !== 'JWT') {
throw Lib.OAuthError.from({
Expand All @@ -201,15 +207,9 @@ class TokenHandler extends SMARTHandler {
msg : `Expected one of ('ES384', 'RS384'), found: '${alg}'.`,
}, 'expected ES384 or RS384', alg);
}
const kid = validated.header['kid'];
if (key.kid !== kid) {
throw Lib.OAuthError.from({
code : 403,
error: 'invalid key',
msg : `Expected JWT kid (${kid}) to match (${key.kid})`,
}, key.kid, kid);
}

const fiveMinutesFromNow = Math.floor(Date.now() / 1000) + 300;
const payload = JSON.parse(validated.payload);
if (payload.exp > fiveMinutesFromNow) {
throw Lib.OAuthError.from({
code : 403,
Expand Down

0 comments on commit 6e73440

Please sign in to comment.