From b7901f6c8837bc7c3c3ca3bc302b41ae434789b6 Mon Sep 17 00:00:00 2001 From: Trent Larson Date: Sat, 25 May 2024 18:51:18 -0600 Subject: [PATCH] derive DID for issuer --- README.md | 2 +- package.json | 1 - src/libs/crypto/index.ts | 4 +++- src/libs/didPeer.ts | 43 ++++++++++++++++++++++++++++++---------- src/views/StartView.vue | 21 ++++++++++++++------ 5 files changed, 52 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 4a1f124..c79de4e 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ See [project.task.yaml](project.task.yaml) for current priorities. ## Setup -We have pkgx.dev set up in package.json, so you can use `dev` to set up the dev environment. +We like pkgx: `sh <(curl https://pkgx.sh) +npm sh` ``` npm install diff --git a/package.json b/package.json index 2c3ef3e..6b1b697 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,6 @@ { "name": "TimeSafari", "version": "0.3.14-beta", - "private": true, "scripts": { "dev": "vite", "serve": "vite preview", diff --git a/src/libs/crypto/index.ts b/src/libs/crypto/index.ts index 7afdf2c..71c67fe 100644 --- a/src/libs/crypto/index.ts +++ b/src/libs/crypto/index.ts @@ -11,6 +11,8 @@ import { DEFAULT_DID_PROVIDER_NAME } from "../veramo/setup"; export const DEFAULT_ROOT_DERIVATION_PATH = "m/84737769'/0'/0'/0'"; +export const LOCAL_KMS_NAME = "local"; + /** * * @@ -31,7 +33,7 @@ export const newIdentifier = ( keys: [ { kid: publicHex, - kms: "local", + kms: LOCAL_KMS_NAME, meta: { derivationPath: derivationPath }, privateKeyHex: privateHex, publicKeyHex: publicHex, diff --git a/src/libs/didPeer.ts b/src/libs/didPeer.ts index faabb73..b674ef2 100644 --- a/src/libs/didPeer.ts +++ b/src/libs/didPeer.ts @@ -2,6 +2,7 @@ import { Buffer } from "buffer/"; import { decode as cborDecode } from "cbor-x"; import { createJWS, JWTPayload, verifyJWT } from "did-jwt"; import { getResolver } from "@veramo/did-provider-peer"; +import { bytesToMultibase } from "@veramo/utils"; import { generateRandomBytes } from "@/libs/crypto"; @@ -28,7 +29,7 @@ export async function registerCredential( }, user: { id: userId, - name: "current-user", + name: "Current-User", displayName: "Current User", }, pubKeyCredParams: [ @@ -63,21 +64,27 @@ export async function registerCredential( ); console.log("attestationObject", attestationObject); - const authData = new Uint8Array(attestationObject.authData); - const publicKey = extractPublicKey(authData); + const publicKeyCose = extractPublicKeyCose(attestationObject.authData); + const publicKeyJwk = extractPublicKeyJwk(attestationObject.authData); - return { rawId: credential?.rawId, publicKey }; + return { rawId: credential?.rawId, publicKeyJwk, publicKeyCose }; } -function extractPublicKey(authData: Uint8Array) { - // Extract the public key from authData using appropriate parsing - // This involves extracting the COSE key format and converting it to JWK - // For simplicity, we'll assume the public key is at a certain position in authData - const publicKeyCose = authData.slice(authData.length - 77); // Example position +function extractPublicKeyJwk(authData: Uint8Array) { + const publicKeyCose = extractPublicKeyCose(authData); // Example position const publicKeyJwk = coseToJwk(publicKeyCose); return publicKeyJwk; } +function extractPublicKeyCose(authData: Uint8Array) { + // Extract the public key from authData using appropriate parsing. + // This involves extracting the COSE key format. + // For simplicity, we'll assume the public key is at a certain position in authData. + // Alternatively, see last answer here: https://chatgpt.com/share/78a5c91d-099d-46dc-aa6d-fc0c916509fa + const publicKeyCose = authData.slice(authData.length - 77); + return publicKeyCose; +} + function coseToJwk(coseKey: Uint8Array) { // Convert COSE key format to JWK // This is simplified and needs appropriate parsing and conversion logic @@ -89,6 +96,17 @@ function coseToJwk(coseKey: Uint8Array) { }; } +export function createPeerDid(publicKeyCose: Uint8Array) { + // https://github.com/decentralized-identity/veramo/blob/next/packages/did-provider-peer/src/peer-did-provider.ts#L67 + //const provider = new PeerDIDProvider({ defaultKms: LOCAL_KMS_NAME }); + const methodSpecificId = bytesToMultibase( + publicKeyCose, + "base58btc", + "ed25519-pub", + ); + return "did:peer:0" + methodSpecificId; +} + export async function createJwt( payload: object, issuerDid: string, @@ -150,10 +168,15 @@ async function generateWebAuthnSignature( }; } -export async function verifyJwt(jwt: string, publicKey: JWK) { +export async function verifyJwt( + jwt: string, + issuerDid: string, + publicKey: JWK, +) { const decoded = verifyJWT(jwt, { didAuthenticator: { authenticators: [{ publicKeyJwk: publicKey }], + issuer: issuerDid, }, resolver: getResolver(), }); diff --git a/src/views/StartView.vue b/src/views/StartView.vue index 93057ec..341afb7 100644 --- a/src/views/StartView.vue +++ b/src/views/StartView.vue @@ -66,14 +66,21 @@ import { Component, Vue } from "vue-facing-decorator"; import { accountsDB } from "@/db/index"; import { generateRandomBytes } from "@/libs/crypto"; -import { createJwt, JWK, registerCredential, verifyJwt } from "@/libs/didPeer"; +import { + createJwt, + createPeerDid, + JWK, + registerCredential, + verifyJwt, +} from "@/libs/didPeer"; @Component({ components: {}, }) export default class StartView extends Vue { numAccounts = 0; - publicKey?: JWK; + publicKeyJwk?: JWK; + publicKeyCose?: Uint8Array; userId?: Uint8Array; async mounted() { @@ -88,15 +95,17 @@ export default class StartView extends Vue { const cred = await registerCredential(this.userId, generateRandomBytes(32)); console.log("public key", cred); - this.publicKey = cred.publicKey; + this.publicKeyJwk = cred.publicKeyJwk; + this.publicKeyCose = cred.publicKeyCose; this.userId = cred.rawId as Uint8Array; //this.$router.push({ name: "new-identifier" }); } public async onClickNo() { const credArrBuff = this.userId; - - const jwt = await createJwt({ a: 1 }, "issuerDid", credArrBuff); + const did = createPeerDid(this.publicKeyCose as Uint8Array); + console.log("did", did); + const jwt = await createJwt({ a: 1 }, did, credArrBuff as Uint8Array); console.log("jwt", jwt); const jwt4url = jwt .replace(/\+/g, "-") @@ -104,7 +113,7 @@ export default class StartView extends Vue { .replace(/=+$/, ""); console.log("jwt4url", jwt4url); - const decoded = await verifyJwt(jwt, this.publicKey as JWK); + const decoded = await verifyJwt(jwt4url, did, this.publicKey as JWK); console.log("decoded", decoded); //this.$router.push({ name: "import-account" }); }