Skip to content

Commit

Permalink
make test sd jwt work
Browse files Browse the repository at this point in the history
Signed-off-by: F-Node-Karlsruhe <christian.fries@eecc.de>
  • Loading branch information
F-Node-Karlsruhe committed Sep 15, 2023
1 parent 758d9f7 commit b92bca2
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 45 deletions.
10 changes: 10 additions & 0 deletions api/__tests__/presentation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import request from "supertest";

import app from "../src/index";

const sdJWTPresentation: string = "eyJhbGciOiJFUzM4NCIsImtpZCI6ImRpZDpqd2s6ZXlKcmRIa2lPaUpGUXlJc0luZ2lPaUpJWTNRd1gyTmliRzVzYkV0VFYxOWFVVnBtUlhkRGIwbFFaRlpWYW1kTlNXMW1OWEZzUkRKVWVEaG1TM0ZLUTFoeVYxSnlOMVZwU2xCWGVsTldhbXBHSWl3aWVTSTZJbTAxTlhka1ZUbG1hVXROWDFWQmR6WlpTMWs1Ym1kdGEyZzRlbWhKVG1JM1V6bFhTVzVtTFhvelIxaENOR3RST0dJNGVtOVBla3RvWjB0elRqTm9jRzBpTENKamNuWWlPaUpRTFRNNE5DSjkjMCJ9.eyJhcnJheV93aXRoX3JlY3Vyc2l2ZV9zZCI6WyJib3JpbmciLHsiZm9vIjoiYmFyIiwiX3NkIjpbInFnSG0yNjAyTlFZQjh4Z0RISmEwRTZIeDJxZnM0UWNzRURqREcyRDlaOUUiXX0sW3siLi4uIjoiNWExUFRkX0xJUVd0djVBMWdxM0R5QXZyQTh0QnlVZDJaMHF0SlJGSzF4RSJ9LHsiLi4uIjoiWW1tN0d4MnZNSlVHaDVjQ2tsZUpkaEV3MWVlTHNLRWF2SVZFT1hBMXVOUSJ9XV0sInRlc3QyIjpbeyIuLi4iOiJ2RDYzS2Z1bGFUT2NlNlh6WUlsXy1RSGFCUUVxR1lfVXA0S1lCell5QUJZIn0seyIuLi4iOiI1Z3Q4ZzlkMlNXVUZIZklZYWJXUFM5TlIxTTVNb3pKbnoyNUlGR01tdmhjIn1dLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6ImRpZDpqd2s6ZXlKcmRIa2lPaUpGUXlJc0luZ2lPaUpJWTNRd1gyTmliRzVzYkV0VFYxOWFVVnBtUlhkRGIwbFFaRlpWYW1kTlNXMW1OWEZzUkRKVWVEaG1TM0ZLUTFoeVYxSnlOMVZwU2xCWGVsTldhbXBHSWl3aWVTSTZJbTAxTlhka1ZUbG1hVXROWDFWQmR6WlpTMWs1Ym1kdGEyZzRlbWhKVG1JM1V6bFhTVzVtTFhvelIxaENOR3RST0dJNGVtOVBla3RvWjB0elRqTm9jRzBpTENKamNuWWlPaUpRTFRNNE5DSjkiLCJpYXQiOjE2OTQ3Njk1NDUsImV4cCI6MTcyNjM5MTk0NSwiY25mIjp7Imp3ayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMzg0IiwieCI6InNoY24xeE43ODBLRWRuZVFVVXZ3bUhmQUM0Y0VWb2ZGSjlWc002RDlfLTdlaGtLdVdUN2NSUTZ3R0ZnU3hWbFEiLCJ5IjoiSHl2V1NYc25sT3RvRzJzNjB6a0ZTN2FmR01oU0pXUW5TX3BRaURfN0ptNHNQd3RMSnVnMy1OOW5pQjJOVl9DXyJ9fX0.JoD9gePif8jfnlf-45KwNMe1TuHWKWbWqbECzPHeY9vQVBMd3Sd0VrB2aXSlyKqDkZPPpQsVk5nSC3ofOEUAm7HHfHN42Vzr3-4XNPfoTJmarPZNFMtbjgWayBWyUuSX~WyI0SHdhRHk1dU9SczdMbjZ0b1NpR0N3IiwgImJheiIsIHsicXV4IjogInF1dXgifV0~WyJvdVl4cUZMRGZxZW5VUHptUWZBWEh3IiwgImJhciJd~WyJUMHpiWURfR1FSVVdocjJuYjc2SmpRIiwgImZvbyJd~WyJRRldFR1ZwNlNpZ19rdzJHYml1dnZBIiwgImJhciJd~eyJhbGciOiJFUzM4NCIsInR5cCI6ImtiK2p3dCJ9.eyJub25jZSI6Ijk4NzY1NDMyMTAiLCJhdWQiOiJkaWQ6d2ViOnZlcmlmaWVyLmV4YW1wbGUiLCJpYXQiOjE2OTQ3Njk1NDV9.zl9qYTnspJXq1EhMsQmgSfKixyVdruYX0JdGC26SygAKlvjL5UlUKb6LhjxF_tGw3MV5WIXdfGODlqjHmynPnRNAh8snXxn4j1ONUhuNHDqbxBEhGZKXIEJyIjj2Ibcf"

const multiPresentation: any = {
"@context": [
"https://www.w3.org/2018/credentials/v1",
Expand Down Expand Up @@ -242,4 +244,12 @@ describe("Verifier API Test for Presentations", () => {
expect(res.body[0].error.name).toBe('VerificationError');
});

test("Verify single SD-JWT presentation with challenge & domain", async () => {
const res = await request(app).post("/api/verifier").query({ nonce: '9876543210', aud: 'did:web:verifier.example' }).send([sdJWTPresentation]);
expect(res.statusCode).toEqual(200);
expect(res.body[0]).toHaveProperty('verified');
console.log(res.body[0])
expect(res.body[0].verified).toBe(true);
});

});
67 changes: 32 additions & 35 deletions api/package-lock.json

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

2 changes: 2 additions & 0 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@digitalbazaar/vc": "^6.0.2",
"@digitalbazaar/vc-revocation-list": "^5.0.0",
"@digitalbazaar/vc-status-list": "^7.0.0",
"@or13/did-jwk": "^0.0.4",
"@transmute/vc-jwt-sd": "^0.0.4",
"cors": "^2.8.5",
"did-resolver": "^4.1.0",
Expand All @@ -43,6 +44,7 @@
"http-status-codes": "^2.2.0",
"jsonld": "github:european-epc-competence-center/jsonld.js#cachefix",
"jsonld-signatures": "^11.2.1",
"moment": "^2.29.4",
"node-fetch": "^3.3.2",
"parse-link-header": "^2.0.0",
"web-did-resolver": "^2.0.27"
Expand Down
30 changes: 20 additions & 10 deletions api/src/services/verifier/sdjwt.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import SD from '@transmute/vc-jwt-sd';
import { Digest } from '@transmute/vc-jwt-sd/dist/types';

import moment from 'moment';
import crypto from "crypto";
import { base64url, decodeProtectedHeader, decodeJwt } from "jose";
import { dereferenceDID } from '../documentLoader/index.js';

const digester = (name: 'sha-256' = 'sha-256'): Digest => {
const vcjwtsd = (SD as any).default;

const digester = (name: 'sha-256' = 'sha-256'): any => {
if (name !== 'sha-256') {
throw new Error('hash function not supported')
}
Expand All @@ -20,7 +21,7 @@ const digester = (name: 'sha-256' = 'sha-256'): Digest => {

export async function verifySDJWT(verifiable: string, nonce?: string, aud?: string): Promise<VerificationResult> {

const parsed = SD.Parse.compact(verifiable)
const parsed = vcjwtsd.Parse.compact(verifiable);

const decodedHeader = decodeProtectedHeader(parsed.jwt)

Expand All @@ -39,15 +40,20 @@ export async function verifySDJWT(verifiable: string, nonce?: string, aud?: stri

const absoluteDidUrl = kid && kid.startsWith(iss) ? kid : `${iss}#${kid}`

const { publicKeyJwk } = (await dereferenceDID(absoluteDidUrl)).document;
console.log(await dereferenceDID(absoluteDidUrl))

let { publicKeyJwk } = (await dereferenceDID(absoluteDidUrl)).document;

const verifier = new SD.Verifier({
// in case of did:key use jwk from jwt
if (!publicKeyJwk) publicKeyJwk = (decodedPayload.cnf as any).jwk;

const verifier = new vcjwtsd.Verifier({
alg,
digester: digester(),
verifier: {
verify: async (token: string) => {
const parsed = SD.Parse.compact(token)
const verifier = await SD.JWS.verifier(publicKeyJwk)
const parsed = vcjwtsd.Parse.compact(token)
const verifier = await vcjwtsd.JWS.verifier(publicKeyJwk)
return verifier.verify(parsed.jwt)
}
}
Expand All @@ -58,10 +64,14 @@ export async function verifySDJWT(verifiable: string, nonce?: string, aud?: stri
aud
})

// TODO do sematic checks iat&exp
const now = moment().unix()

if (now < verified.claimset.iat) throw new Error('Credential is not yet valid!')
if (verified.claimset.exp && now > verified.claimset.exp) throw new Error('Credential expired!')

} catch (error: any) {
return { verified: false, error };
console.log(error)
return { verified: false, error: error.message };
}

return { verified: true };
Expand Down

0 comments on commit b92bca2

Please sign in to comment.