Skip to content

Commit

Permalink
mv to openid jwt verifier
Browse files Browse the repository at this point in the history
Signed-off-by: F-Node-Karlsruhe <[email protected]>
  • Loading branch information
F-Node-Karlsruhe committed Apr 23, 2024
1 parent 9915eab commit 5ffcc87
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 26 deletions.
2 changes: 1 addition & 1 deletion api/__tests__/presentation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ afterAll((done) => {
});

const sdJWTPresentation: string =
"eyJ0eXAiOiJzZC1qd3QiLCJhbGciOiJFZERTQSJ9.eyJ0ZXN0Ijp7Il9zZCI6WyJqVEszMHNleDZhYV9kUk1KSWZDR056Q0FwbVB5MzRRNjNBa3QzS3hhSktzIl19LCJfc2QiOlsiME9nMi1ReG95eW1UOGNnVzZZUjVSSFpQLUJuR2tHUi1NM2otLV92RWlzSSIsIkcwZ3lHNnExVFMyUlQxMkZ3X2RRRDVVcjlZc1AwZlVWOXVtQWdGMC1jQ1EiXSwiX3NkX2FsZyI6InNoYS0yNTYifQ.ggEyE4SeDO2Hu3tol3VLmi7NQj56yKzKQDaafocgkLrUBdivghohtzrfcbrMN7CRufJ_Cnh0EL54kymXLGTdDQ~WyIwNGU0MjAzOWU4ZWFiOWRjIiwiYSIsIjEiXQ~WyIwOGE1Yjc5MjMyYjAzYzBhIiwiMSJd~WyJiNWE2YjUzZGQwYTFmMGIwIiwienp6IiwieHh4Il0~WyIxYzdmOTE4ZTE0MjA2NzZiIiwiZm9vIiwiYmFyIl0~WyJmZjYxYzQ5ZGU2NjFiYzMxIiwiYXJyIixbeyIuLi4iOiJTSG96VW5KNUpkd0ZtTjVCbXB5dXZCWGZfZWRjckVvcExPYThTVlBFUmg0In0sIjIiLHsiX3NkIjpbIkpuODNhZkp0OGx4NG1FMzZpRkZyS2U2R2VnN0dlVUQ4Z3UwdVo3NnRZcW8iXX1dXQ~";
"eyJhbGciOiAiRVMyNTYiLCAia2lkIjogImRvYy1zaWduZXItMDUtMjUtMjAyMiIsICJ0eXAiOiAidmMrc2Qtand0In0.eyJfc2QiOiBbIjA5dktySk1PbHlUV00wc2pwdV9wZE9CVkJRMk0xeTNLaHBINTE1blhrcFkiLCAiMnJzakdiYUMwa3k4bVQwcEpyUGlvV1RxMF9kYXcxc1g3NnBvVWxnQ3diSSIsICJFa084ZGhXMGRIRUpidlVIbEVfVkNldUM5dVJFTE9pZUxaaGg3WGJVVHRBIiwgIklsRHpJS2VpWmREd3BxcEs2WmZieXBoRnZ6NUZnbldhLXNONndxUVhDaXciLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiamRyVEU4WWNiWTRFaWZ1Z2loaUFlX0JQZWt4SlFaSUNlaVVRd1k5UXF4SSIsICJqc3U5eVZ1bHdRUWxoRmxNXzNKbHpNYVNGemdsaFFHMERwZmF5UXdMVUs0Il0sICJpc3MiOiAiaHR0cHM6Ly9leGFtcGxlLmNvbS9pc3N1ZXIiLCAiaWF0IjogMTY4MzAwMDAwMCwgImV4cCI6IDE4ODMwMDAwMDAsICJkY3QiOiAiaHR0cHM6Ly9jcmVkZW50aWFscy5leGFtcGxlLmNvbS9pZGVudGl0eV9jcmVkZW50aWFsIiwgIl9zZF9hbGciOiAic2hhLTI1NiIsICJjbmYiOiB7Imp3ayI6IHsia3R5IjogIkVDIiwgImNydiI6ICJQLTI1NiIsICJ4IjogIlRDQUVSMTladnUzT0hGNGo0VzR2ZlNWb0hJUDFJTGlsRGxzN3ZDZUdlbWMiLCAieSI6ICJaeGppV1diWk1RR0hWV0tWUTRoYlNJaXJzVmZ1ZWNDRTZ0NGpUOUYySFpRIn19fQ.b036DutqQ72WszrCq0GuqZnbws3MApQyzA41I5DSJmenUfsADtqW8FbI_N04FP1wZDF_JtV6a6Ke3Z7apkoTLA~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImtiK2p3dCJ9.eyJub25jZSI6ICIxMjM0NTY3ODkwIiwgImF1ZCI6ICJodHRwczovL2V4YW1wbGUuY29tL3ZlcmlmaWVyIiwgImlhdCI6IDE2OTgwODAwMTR9.2tyXCwCi-LRVW4eoFxZFr5ryYWRczatgWrnG13rktjYunChVT9_qIkKL_ClfNM1WKoPT5IsTrxEnaSGKbUQwrw";

const multiPresentation: any = {
"@context": [
Expand Down
103 changes: 78 additions & 25 deletions api/src/services/verifier/sdjwt.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,89 @@
import { SDJwtVcInstance } from "@sd-jwt/sd-jwt-vc";
import type { DisclosureFrame } from "@sd-jwt/types";
import { ES256, digest, generateSalt } from "@sd-jwt/crypto-nodejs";
import type { Verifier, KbVerifier } from "@sd-jwt/types";
import { ES256, digest } from "@sd-jwt/crypto-nodejs";
import { importJWK, JWK, JWTPayload, jwtVerify } from "jose";
import { dereferenceDID } from "../documentLoader/index.js";
import { fetch_json, isURL } from "../fetch/index.js";

const createSignerVerifier = async () => {
const { privateKey, publicKey } = await ES256.generateKeyPair();
return {
signer: await ES256.getSigner(privateKey),
verifier: await ES256.getVerifier(publicKey),
};
};

const { signer, verifier } = await createSignerVerifier();
async function getPublicKey(issuer: string, kid: string): Promise<JWK> {
if (isURL(issuer)) {
const response = await fetch_json(`${issuer}/.well-known/jwt-vc-issuer`)
.then((r: any) => r.data)
.catch(() => {
throw new Error("Error on fetching public key from " + issuer);
});
const key = response.jwks.keys.find((key: any) => key.kid === kid);
if (!key) {
throw new Error("Key not found und well-known");
}
return key;
}
if (kid && kid.startsWith("did:")) {
const absoluteDidUrl =
kid && kid.startsWith(issuer) ? kid : `${issuer}#${kid}`;
const { publicKeyJwk } = (await dereferenceDID(absoluteDidUrl))?.document;
if (!publicKeyJwk) {
throw new Error("Key not found in did");
}
return publicKeyJwk;
}
throw new Error("Could not resolve public keys");
}

export async function verifySDJWT(
verifiable: string,
nonce?: string,
aud?: string
): Promise<VerificationResult> {
const sdjwt = new SDJwtVcInstance({
signer,
verifier,
signAlg: "EdDSA",
hasher: digest,
hashAlg: "SHA-256",
saltGenerator: generateSalt,
});

const decodedObject = await sdjwt.decode(verifiable);

const verified = await sdjwt.verify(verifiable, []);
try {
let sdjwtInstance: SDJwtVcInstance;
/**
* The verifier function. This function will verify the signature of the vc.
* @param data encoded header and payload of the jwt
* @param signature signature of the jwt
* @returns true if the signature is valid
*/
const verifier: Verifier = async (data, signature) => {
const decodedVC = await sdjwtInstance.decode(`${data}.${signature}`);
const payload = decodedVC.jwt?.payload as JWTPayload;
const header = decodedVC.jwt?.header as JWK;
const publicKey = await getPublicKey(
payload.iss as string,
header.kid as string
);
const verify = await ES256.getVerifier(publicKey);
return verify(data, signature);
};

console.log(verified);
/**
* The kb verifier function. This function will verify the signature for the key binding
* @param data
* @param signature
* @param payload
* @returns
*/
const kbVerifier: KbVerifier = async (data, signature, payload) => {
if (!payload.cnf) {
throw new Error("No cnf found in the payload");
}
const key = await importJWK(payload.cnf.jwk as JWK, "ES256");
return jwtVerify(`${data}.${signature}`, key).then(
() => true,
() => false
);
};

return { verified: true };
// initialize the sdjwt instance.
sdjwtInstance = new SDJwtVcInstance({
hasher: digest,
verifier,
kbVerifier,
});
// verify the presentation.
await sdjwtInstance.verify(verifiable, [], true);
return Promise.resolve({ verified: true });
} catch (e) {
console.error(e);
return Promise.reject({ verified: false, error: (e as Error).message });
}
}

0 comments on commit 5ffcc87

Please sign in to comment.