From 7eea71154b3b75958508112a0f54def6b6929473 Mon Sep 17 00:00:00 2001 From: Tan Cher Shen Date: Mon, 25 Nov 2024 11:53:55 +0800 Subject: [PATCH 1/5] feat: add support for OCSP reason code suspended --- .../documentStatus/didSigned/didSignedDocumentStatus.type.ts | 2 +- src/verifiers/documentStatus/revocation.types.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.type.ts b/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.type.ts index 0b4ba084..bfdb71cc 100644 --- a/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.type.ts +++ b/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.type.ts @@ -40,7 +40,7 @@ export type DidSignedIssuanceStatusArray = Static n >= 0 && n <= 10 && n != 7); +export const ValidOcspReasonCode = Number.withConstraint((n) => [1, 2, 3, 4, 5, 6, 8, 9, 10, 1001].includes(n)); export const ValidOcspResponse = Record({ revoked: Literal(false), diff --git a/src/verifiers/documentStatus/revocation.types.ts b/src/verifiers/documentStatus/revocation.types.ts index 940608b1..8fa1a172 100644 --- a/src/verifiers/documentStatus/revocation.types.ts +++ b/src/verifiers/documentStatus/revocation.types.ts @@ -32,4 +32,5 @@ export enum OcspResponderRevocationReason { REMOVE_FROM_CRL = 8, PRIVILEGE_WITHDRAWN = 9, A_A_COMPROMISE = 10, + SUSPENDED = 1001, } From 86fa4289ed50438a72bfef85ac8b3f4b87ed2017 Mon Sep 17 00:00:00 2001 From: Tan Cher Shen Date: Mon, 25 Nov 2024 11:54:43 +0800 Subject: [PATCH 2/5] test: add test case for OCSP reason code suspended and a test case for invalid OCSP reason code --- .../didSigned/didSignedDocumentStatus.test.ts | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.test.ts b/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.test.ts index 047b5f1a..941d3968 100644 --- a/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.test.ts +++ b/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.test.ts @@ -595,6 +595,127 @@ describe("verify", () => { server.close(); }); + + it("should fail when DID document is signed but is found by an OCSP with reasoncode for suspended", async () => { + whenPublicKeyResolvesSuccessfully(); + + const handlers = [ + rest.get( + "https://ocsp.example.com/0x28b221f6287d8e4f8da09a835bcb750537cc8385e2535ff63591fdf0162be824", + (_, res, ctx) => { + return res( + ctx.json({ + revoked: true, + documentHash: "0x28b221f6287d8e4f8da09a835bcb750537cc8385e2535ff63591fdf0162be824", + reasonCode: 1001, + }) + ); + } + ), + rest.get( + "https://ocsp.example.com/0x56961854a82feafe9a56eb57acfe3b97f17eda5d497b622c9acc9f03c412618c", + (_, res, ctx) => { + return res( + ctx.json({ + revoked: false, + documentHash: "0x56961854a82feafe9a56eb57acfe3b97f17eda5d497b622c9acc9f03c412618c", + }) + ); + } + ), + ]; + + const server: SetupServerApi = setupServer(...handlers); + server.listen(); + + const res = await openAttestationDidSignedDocumentStatus.verify(didSignedOcspResponderV2, options); + expect(res).toMatchInlineSnapshot(` + Object { + "data": Object { + "details": Object { + "issuance": Array [ + Object { + "did": "did:ethr:0xB26B4941941C51a4885E5B7D3A1B861E54405f90", + "issued": true, + }, + ], + "revocation": Array [ + Object { + "address": "https://ocsp.example.com", + "reason": Object { + "code": 1001, + "codeString": "SUSPENDED", + "message": "Document 0x56961854a82feafe9a56eb57acfe3b97f17eda5d497b622c9acc9f03c412618c has been revoked under OCSP Responder: https://ocsp.example.com", + }, + "revoked": true, + }, + ], + }, + "issuedOnAll": true, + "revokedOnAny": true, + }, + "name": "OpenAttestationDidSignedDocumentStatus", + "reason": Object { + "code": 1001, + "codeString": "SUSPENDED", + "message": "Document 0x56961854a82feafe9a56eb57acfe3b97f17eda5d497b622c9acc9f03c412618c has been revoked under OCSP Responder: https://ocsp.example.com", + }, + "status": "INVALID", + "type": "DOCUMENT_STATUS", + } + `); + + server.close(); + }); + it("should thwow an invalid ocsp response error when DID document is signed but is found by an OCSP with an invalid reasoncode", async () => { + whenPublicKeyResolvesSuccessfully(); + + const handlers = [ + rest.get( + "https://ocsp.example.com/0x28b221f6287d8e4f8da09a835bcb750537cc8385e2535ff63591fdf0162be824", + (_, res, ctx) => { + return res( + ctx.json({ + revoked: true, + documentHash: "0x28b221f6287d8e4f8da09a835bcb750537cc8385e2535ff63591fdf0162be824", + reasonCode: 7, + }) + ); + } + ), + rest.get( + "https://ocsp.example.com/0x56961854a82feafe9a56eb57acfe3b97f17eda5d497b622c9acc9f03c412618c", + (_, res, ctx) => { + return res( + ctx.json({ + revoked: false, + documentHash: "0x56961854a82feafe9a56eb57acfe3b97f17eda5d497b622c9acc9f03c412618c", + }) + ); + } + ), + ]; + + const server: SetupServerApi = setupServer(...handlers); + server.listen(); + + const res = await openAttestationDidSignedDocumentStatus.verify(didSignedOcspResponderV2, options); + expect(res).toMatchInlineSnapshot(` + Object { + "data": [Error: Invalid or unexpected response from OCSP Responder], + "name": "OpenAttestationDidSignedDocumentStatus", + "reason": Object { + "code": 11, + "codeString": "OCSP_RESPONSE_INVALID", + "message": "Invalid or unexpected response from OCSP Responder", + }, + "status": "ERROR", + "type": "DOCUMENT_STATUS", + } + `); + + server.close(); + }); }); describe("v3", () => { From ebf0d2be87a8136b78b95fb6f9bc86b2452aa93a Mon Sep 17 00:00:00 2001 From: Tan Cher Shen Date: Mon, 25 Nov 2024 13:53:21 +0800 Subject: [PATCH 3/5] test: add test case "should throw an invalid ocsp response error when DID document is signed but is found by an OCSP with an invalid reasoncode" for v3 --- .../didSigned/didSignedDocumentStatus.test.ts | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.test.ts b/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.test.ts index 941d3968..5ba8f426 100644 --- a/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.test.ts +++ b/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.test.ts @@ -1111,6 +1111,44 @@ describe("verify", () => { } `); + server.close(); + }); + it("should throw an invalid ocsp response error when DID document is signed but is found by an OCSP with an invalid reasoncode", async () => { + whenPublicKeyResolvesSuccessfully("0x1245e5B64D785b25057f7438F715f4aA5D965733"); + + const handlers = [ + rest.get( + "https://ocsp.example.com/0x69e1a174ea67e1c3119639f713f8a7348bbda54fdce60903621398cc2fea4d40", + (_, res, ctx) => { + return res( + ctx.json({ + revoked: true, + documentHash: "0x69e1a174ea67e1c3119639f713f8a7348bbda54fdce60903621398cc2fea4d40", + reasonCode: 7, + }) + ); + } + ), + ]; + + const server: SetupServerApi = setupServer(...handlers); + server.listen(); + + const res = await openAttestationDidSignedDocumentStatus.verify(didSignedOcspResponderV3, options); + expect(res).toMatchInlineSnapshot(` + Object { + "data": [Error: Invalid or unexpected response from OCSP Responder], + "name": "OpenAttestationDidSignedDocumentStatus", + "reason": Object { + "code": 11, + "codeString": "OCSP_RESPONSE_INVALID", + "message": "Invalid or unexpected response from OCSP Responder", + }, + "status": "ERROR", + "type": "DOCUMENT_STATUS", + } + `); + server.close(); }); }); From 295e15422e06072b657971d1c15d595df66d38ae Mon Sep 17 00:00:00 2001 From: Tan Cher Shen Date: Tue, 26 Nov 2024 14:54:19 +0800 Subject: [PATCH 4/5] refactor: use values of OcspResponderRevocationReason for ValidOcspReasonCode check --- .../documentStatus/didSigned/didSignedDocumentStatus.type.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.type.ts b/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.type.ts index bfdb71cc..81eb7e83 100644 --- a/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.type.ts +++ b/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.type.ts @@ -7,6 +7,7 @@ import { } from "../../../types/core"; import { Reason } from "../../../types/error"; import { + OcspResponderRevocationReason, RevocationStatus, RevocationStatusArray, ValidRevocationStatus, @@ -40,7 +41,7 @@ export type DidSignedIssuanceStatusArray = Static [1, 2, 3, 4, 5, 6, 8, 9, 10, 1001].includes(n)); +export const ValidOcspReasonCode = Number.withConstraint((n) => Object.values(OcspResponderRevocationReason).includes(n)); export const ValidOcspResponse = Record({ revoked: Literal(false), From 06134d2d4e7f38158d74f5d8b16456bb9dae3ea1 Mon Sep 17 00:00:00 2001 From: chershentan Date: Tue, 26 Nov 2024 14:59:00 +0800 Subject: [PATCH 5/5] Update src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.type.ts Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../documentStatus/didSigned/didSignedDocumentStatus.type.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.type.ts b/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.type.ts index 81eb7e83..d843a613 100644 --- a/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.type.ts +++ b/src/verifiers/documentStatus/didSigned/didSignedDocumentStatus.type.ts @@ -41,7 +41,9 @@ export type DidSignedIssuanceStatusArray = Static Object.values(OcspResponderRevocationReason).includes(n)); +export const ValidOcspReasonCode = Number.withConstraint((n) => + Object.values(OcspResponderRevocationReason).includes(n) +); export const ValidOcspResponse = Record({ revoked: Literal(false),