From 96db4aa774d073b12929676f5ca39070bae0f1fa Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 16 May 2023 12:21:00 +0200 Subject: [PATCH 1/5] support did as id, ignore serialNumber in subject --- controllers/extparticipant/utils.js | 13 ------------- migrations/201802190008-CreateOAuthClientTable.js | 2 +- .../201802190065-CreateOAuthAccessTokenTable.js | 2 +- models/oauth2/oauth_client.js | 2 +- 4 files changed, 3 insertions(+), 16 deletions(-) diff --git a/controllers/extparticipant/utils.js b/controllers/extparticipant/utils.js index aa7137a6..aa15b892 100644 --- a/controllers/extparticipant/utils.js +++ b/controllers/extparticipant/utils.js @@ -116,19 +116,6 @@ exports.assert_client_using_jwt = async function assert_client_using_jwt(credent return forge.pki.certificateFromPem('-----BEGIN CERTIFICATE-----' + cert + '-----END CERTIFICATE-----'); }); - const serial_number_field = fullchain[0].subject.getField({ name: 'serialNumber' }); - if (serial_number_field == null) { - // JWT iss parameter does not match the serialNumber field of the signer certificate - throw new Error('Issuer certificate serialNumber parameter is missing'); - } - - const cert_serial_number = serial_number_field.value; - if (payload.iss !== cert_serial_number) { - // JWT iss parameter does not match the serialNumber field of the signer certificate - throw new Error( - `Issuer certificate serialNumber parameter does not match jwt iss parameter (${payload.iss} != ${cert_serial_number})` - ); - } await exports.validate_client_certificate(fullchain); return [payload, fullchain[0]]; diff --git a/migrations/201802190008-CreateOAuthClientTable.js b/migrations/201802190008-CreateOAuthClientTable.js index bf80bb9a..d8bf1f22 100755 --- a/migrations/201802190008-CreateOAuthClientTable.js +++ b/migrations/201802190008-CreateOAuthClientTable.js @@ -4,7 +4,7 @@ module.exports = { 'oauth_client', { id: { - type: Sequelize.STRING(36), //Sequelize.UUID, + type: Sequelize.STRING(255), //Sequelize.UUID, unique: true, //defaultValue: Sequelize.UUIDV4, primaryKey: true, diff --git a/migrations/201802190065-CreateOAuthAccessTokenTable.js b/migrations/201802190065-CreateOAuthAccessTokenTable.js index 1e958b9e..9364f768 100755 --- a/migrations/201802190065-CreateOAuthAccessTokenTable.js +++ b/migrations/201802190065-CreateOAuthAccessTokenTable.js @@ -15,7 +15,7 @@ module.exports = { valid: Sequelize.BOOLEAN, extra: Sequelize.JSON, oauth_client_id: { - type: Sequelize.STRING(36), //Sequelize.UUID, + type: Sequelize.STRING(255), //Sequelize.UUID, onDelete: 'CASCADE', references: { model: 'oauth_client', diff --git a/models/oauth2/oauth_client.js b/models/oauth2/oauth_client.js index 4b82da27..88ebad25 100755 --- a/models/oauth2/oauth_client.js +++ b/models/oauth2/oauth_client.js @@ -7,7 +7,7 @@ module.exports = function (sequelize, DataTypes) { 'OauthClient', { id: { - type: DataTypes.UUID, + type: DataTypes.STRING(255), defaultValue: DataTypes.UUIDV4, primaryKey: true }, From 37632039611256da46202d8813687d26fe04f7f1 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 19 Sep 2023 11:20:37 +0200 Subject: [PATCH 2/5] make attributes and identifiers optional(as defined by the spec) --- controllers/authregistry/authregistry.js | 56 ++++++++++++++---------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/controllers/authregistry/authregistry.js b/controllers/authregistry/authregistry.js index 726b94b2..76ebe0fe 100644 --- a/controllers/authregistry/authregistry.js +++ b/controllers/authregistry/authregistry.js @@ -114,28 +114,39 @@ const is_matching_policy = function is_matching_policy(policy_mask, policy) { const resource = policy.target.resource; - // Check identifiers - const id_match = policy_mask.target.resource.identifiers.every( - mid => {return resource.identifiers.length === 1 && resource.identifiers.includes("*") || resource.identifiers.includes(mid);} - ); - if (!id_match) { - return false; - } - - // Check attributes - const attributes_match = policy_mask.target.resource.attributes.every( - aid => {return resource.attributes.length === 1 && resource.attributes.includes("*") || resource.attributes.includes(aid);} - ); - if (!attributes_match) { + try { + // identifiers are optional + if(policy_mask.target.resource.identifiers != null) { + // Check identifiers + const id_match = policy_mask.target.resource.identifiers.every( + mid => {return resource.identifiers.length === 1 && resource.identifiers.includes("*") || resource.identifiers.includes(mid);} + ); + if (!id_match) { + return false; + } + } + // attributes are optional + if(policy_mask.target.resource.attributes != null) { + // Check attributes + const attributes_match = policy_mask.target.resource.attributes.every( + aid => {return resource.attributes.length === 1 && resource.attributes.includes("*") || resource.attributes.includes(aid);} + ); + if (!attributes_match) { + return false; + } + } + + // Check actions + return policy_mask.target.actions != null && + policy_mask.target.actions.length > 0 && + policy_mask.target.actions.every( + mact => {return policy.target.actions.length === 1 && policy.target.actions.includes("*") || policy.target.actions.includes(mact);} + ); + + } catch (error) { + debug(`unexpected error ` + error) return false; } - - // Check actions - return policy_mask.target.actions != null && - policy_mask.target.actions.length > 0 && - policy_mask.target.actions.every( - mact => {return policy.target.actions.length === 1 && policy.target.actions.includes("*") || policy.target.actions.includes(mact);} - ); }; const is_denying_permission = function is_denying_permission(policy_mask, policy) { @@ -187,7 +198,7 @@ const _query_evidences = async function _query_evidences(req, res) { }; response_policy_set.policies = policy_set_mask.policies.map((policy_mask, z) => { - debug(` Processing policy ${z} from the current policy set`); + debug(` Processing policy ${z} from the current policy set` + JSON.stringify(policy_set.policies)); const matching_policies = policy_set.policies.filter((policy) => is_matching_policy(policy_mask, policy)); return { target: policy_mask.target, @@ -215,9 +226,8 @@ const _query_evidences = async function _query_evidences(req, res) { delegationEvidence: evidence // eslint-disable-line snakecase/snakecase }); - debug("Delegation evidence processed"); res.status(200).json({delegation_token}); - + debug("Set") return false; }; From 0c49663ec139f8191cb873ec39e933a3f66546da Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 19 Sep 2023 13:25:41 +0200 Subject: [PATCH 3/5] cleanup --- controllers/authregistry/authregistry.js | 1 - 1 file changed, 1 deletion(-) diff --git a/controllers/authregistry/authregistry.js b/controllers/authregistry/authregistry.js index 76ebe0fe..88ebd901 100644 --- a/controllers/authregistry/authregistry.js +++ b/controllers/authregistry/authregistry.js @@ -227,7 +227,6 @@ const _query_evidences = async function _query_evidences(req, res) { }); res.status(200).json({delegation_token}); - debug("Set") return false; }; From d9d6e3ef1eb63f607be87b0f9af820d4484af802 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 19 Sep 2023 13:32:39 +0200 Subject: [PATCH 4/5] fix migrations --- .../201802190008-CreateOAuthClientTable.js | 2 +- ...01802190065-CreateOAuthAccessTokenTable.js | 2 +- migrations/202309190008-IncreaseClientId.js | 33 +++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100755 migrations/202309190008-IncreaseClientId.js diff --git a/migrations/201802190008-CreateOAuthClientTable.js b/migrations/201802190008-CreateOAuthClientTable.js index d8bf1f22..bf80bb9a 100755 --- a/migrations/201802190008-CreateOAuthClientTable.js +++ b/migrations/201802190008-CreateOAuthClientTable.js @@ -4,7 +4,7 @@ module.exports = { 'oauth_client', { id: { - type: Sequelize.STRING(255), //Sequelize.UUID, + type: Sequelize.STRING(36), //Sequelize.UUID, unique: true, //defaultValue: Sequelize.UUIDV4, primaryKey: true, diff --git a/migrations/201802190065-CreateOAuthAccessTokenTable.js b/migrations/201802190065-CreateOAuthAccessTokenTable.js index 9364f768..1e958b9e 100755 --- a/migrations/201802190065-CreateOAuthAccessTokenTable.js +++ b/migrations/201802190065-CreateOAuthAccessTokenTable.js @@ -15,7 +15,7 @@ module.exports = { valid: Sequelize.BOOLEAN, extra: Sequelize.JSON, oauth_client_id: { - type: Sequelize.STRING(255), //Sequelize.UUID, + type: Sequelize.STRING(36), //Sequelize.UUID, onDelete: 'CASCADE', references: { model: 'oauth_client', diff --git a/migrations/202309190008-IncreaseClientId.js b/migrations/202309190008-IncreaseClientId.js new file mode 100755 index 00000000..4749615b --- /dev/null +++ b/migrations/202309190008-IncreaseClientId.js @@ -0,0 +1,33 @@ +module.exports = { + up(queryInterface, Sequelize) { + return queryInterface.changeColumn( + 'oauth_client', + 'id', + { + type: Sequelize.STRING(255), + unique: true, + primaryKey: true, + }).then(() => + queryInterface.changeColumn('oauth_access_token', 'oauth_client_id', + { + type: Sequelize.STRING(255), + onDelete: 'CASCADE', + references: { + model: 'oauth_client', + key: 'id', + }, + }) + ); + }, + + down(queryInterface, Sequelize) { + return queryInterface.changeColumn( + 'oauth_client', + 'id', + { + type: Sequelize.STRING(36), + unique: true, + primaryKey: true, + }); + }, +}; From 7b7564a0033ebbf8f19c95febccb2d5237d32ee9 Mon Sep 17 00:00:00 2001 From: Stefan Wiedemann Date: Tue, 19 Sep 2023 13:40:00 +0200 Subject: [PATCH 5/5] fix merge issues --- controllers/extparticipant/utils.js | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/controllers/extparticipant/utils.js b/controllers/extparticipant/utils.js index 33f963ae..25514d03 100644 --- a/controllers/extparticipant/utils.js +++ b/controllers/extparticipant/utils.js @@ -85,7 +85,6 @@ exports.validate_client_certificate = function validate_client_certificate(chain check(errors, exports.verify_certificate_chain(chain), 'Certificate chain cannot be verified.'); check(errors, cert.signatureOid === forge.pki.oids.sha256WithRSAEncryption, 'Certificate signature invalid'); check(errors, cert.publicKey.n.bitLength() >= 2048, 'Certificate public key size is smaller than 2048'); - check(errors, cert.serialNumber != null && cert.serialNumber.trim() !== '', 'Certificate has no serial number'); const key_usage = cert.getExtension('keyUsage'); const digital_only = key_usage.digitalSignature && !(key_usage.keyCertSign || key_usage.cRLSign); @@ -161,19 +160,6 @@ exports.validate_jwt = async function validate_jwt(credentials, client_id) { return forge.pki.certificateFromPem('-----BEGIN CERTIFICATE-----' + cert + '-----END CERTIFICATE-----'); }); - const serial_number_field = fullchain[0].subject.getField({ name: 'serialNumber' }); - if (serial_number_field == null) { - // JWT iss parameter does not match the serialNumber field of the signer certificate - throw new Error('Issuer certificate serialNumber parameter is missing'); - } - - const cert_serial_number = serial_number_field.value; - if (payload.iss !== cert_serial_number) { - // JWT iss parameter does not match the serialNumber field of the signer certificate - throw new Error( - `Issuer certificate serialNumber parameter does not match jwt iss parameter (${payload.iss} != ${cert_serial_number})` - ); - } await exports.validate_client_certificate(fullchain); return { payload, fullchain }; @@ -197,8 +183,6 @@ exports.assert_client_using_jwt = async function assert_client_using_jwt(credent throw new Error('Missing response_type param in JWT'); } - await exports.validate_client_certificate(fullchain); - if (payload.response_type !== 'code') { throw new Error('Only code response_type is supported in JWT'); } @@ -416,4 +400,4 @@ const get_trusted_list = (function () { return trusted_list; } }; -})(); +})(); \ No newline at end of file