Browse Source

derive DID for issuer

pull/116/head
Trent Larson 4 months ago
parent
commit
b7901f6c88
  1. 2
      README.md
  2. 1
      package.json
  3. 4
      src/libs/crypto/index.ts
  4. 43
      src/libs/didPeer.ts
  5. 21
      src/views/StartView.vue

2
README.md

@ -10,7 +10,7 @@ See [project.task.yaml](project.task.yaml) for current priorities.
## Setup ## 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 npm install

1
package.json

@ -1,7 +1,6 @@
{ {
"name": "TimeSafari", "name": "TimeSafari",
"version": "0.3.14-beta", "version": "0.3.14-beta",
"private": true,
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"serve": "vite preview", "serve": "vite preview",

4
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 DEFAULT_ROOT_DERIVATION_PATH = "m/84737769'/0'/0'/0'";
export const LOCAL_KMS_NAME = "local";
/** /**
* *
* *
@ -31,7 +33,7 @@ export const newIdentifier = (
keys: [ keys: [
{ {
kid: publicHex, kid: publicHex,
kms: "local", kms: LOCAL_KMS_NAME,
meta: { derivationPath: derivationPath }, meta: { derivationPath: derivationPath },
privateKeyHex: privateHex, privateKeyHex: privateHex,
publicKeyHex: publicHex, publicKeyHex: publicHex,

43
src/libs/didPeer.ts

@ -2,6 +2,7 @@ import { Buffer } from "buffer/";
import { decode as cborDecode } from "cbor-x"; import { decode as cborDecode } from "cbor-x";
import { createJWS, JWTPayload, verifyJWT } from "did-jwt"; import { createJWS, JWTPayload, verifyJWT } from "did-jwt";
import { getResolver } from "@veramo/did-provider-peer"; import { getResolver } from "@veramo/did-provider-peer";
import { bytesToMultibase } from "@veramo/utils";
import { generateRandomBytes } from "@/libs/crypto"; import { generateRandomBytes } from "@/libs/crypto";
@ -28,7 +29,7 @@ export async function registerCredential(
}, },
user: { user: {
id: userId, id: userId,
name: "current-user", name: "Current-User",
displayName: "Current User", displayName: "Current User",
}, },
pubKeyCredParams: [ pubKeyCredParams: [
@ -63,21 +64,27 @@ export async function registerCredential(
); );
console.log("attestationObject", attestationObject); console.log("attestationObject", attestationObject);
const authData = new Uint8Array(attestationObject.authData); const publicKeyCose = extractPublicKeyCose(attestationObject.authData);
const publicKey = extractPublicKey(authData); const publicKeyJwk = extractPublicKeyJwk(attestationObject.authData);
return { rawId: credential?.rawId, publicKey }; return { rawId: credential?.rawId, publicKeyJwk, publicKeyCose };
} }
function extractPublicKey(authData: Uint8Array) { function extractPublicKeyJwk(authData: Uint8Array) {
// Extract the public key from authData using appropriate parsing const publicKeyCose = extractPublicKeyCose(authData); // Example position
// 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
const publicKeyJwk = coseToJwk(publicKeyCose); const publicKeyJwk = coseToJwk(publicKeyCose);
return publicKeyJwk; 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) { function coseToJwk(coseKey: Uint8Array) {
// Convert COSE key format to JWK // Convert COSE key format to JWK
// This is simplified and needs appropriate parsing and conversion logic // 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( export async function createJwt(
payload: object, payload: object,
issuerDid: string, 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, { const decoded = verifyJWT(jwt, {
didAuthenticator: { didAuthenticator: {
authenticators: [{ publicKeyJwk: publicKey }], authenticators: [{ publicKeyJwk: publicKey }],
issuer: issuerDid,
}, },
resolver: getResolver(), resolver: getResolver(),
}); });

21
src/views/StartView.vue

@ -66,14 +66,21 @@ import { Component, Vue } from "vue-facing-decorator";
import { accountsDB } from "@/db/index"; import { accountsDB } from "@/db/index";
import { generateRandomBytes } from "@/libs/crypto"; import { generateRandomBytes } from "@/libs/crypto";
import { createJwt, JWK, registerCredential, verifyJwt } from "@/libs/didPeer"; import {
createJwt,
createPeerDid,
JWK,
registerCredential,
verifyJwt,
} from "@/libs/didPeer";
@Component({ @Component({
components: {}, components: {},
}) })
export default class StartView extends Vue { export default class StartView extends Vue {
numAccounts = 0; numAccounts = 0;
publicKey?: JWK; publicKeyJwk?: JWK;
publicKeyCose?: Uint8Array;
userId?: Uint8Array; userId?: Uint8Array;
async mounted() { async mounted() {
@ -88,15 +95,17 @@ export default class StartView extends Vue {
const cred = await registerCredential(this.userId, generateRandomBytes(32)); const cred = await registerCredential(this.userId, generateRandomBytes(32));
console.log("public key", cred); console.log("public key", cred);
this.publicKey = cred.publicKey; this.publicKeyJwk = cred.publicKeyJwk;
this.publicKeyCose = cred.publicKeyCose;
this.userId = cred.rawId as Uint8Array; this.userId = cred.rawId as Uint8Array;
//this.$router.push({ name: "new-identifier" }); //this.$router.push({ name: "new-identifier" });
} }
public async onClickNo() { public async onClickNo() {
const credArrBuff = this.userId; const credArrBuff = this.userId;
const did = createPeerDid(this.publicKeyCose as Uint8Array);
const jwt = await createJwt({ a: 1 }, "issuerDid", credArrBuff); console.log("did", did);
const jwt = await createJwt({ a: 1 }, did, credArrBuff as Uint8Array);
console.log("jwt", jwt); console.log("jwt", jwt);
const jwt4url = jwt const jwt4url = jwt
.replace(/\+/g, "-") .replace(/\+/g, "-")
@ -104,7 +113,7 @@ export default class StartView extends Vue {
.replace(/=+$/, ""); .replace(/=+$/, "");
console.log("jwt4url", jwt4url); 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); console.log("decoded", decoded);
//this.$router.push({ name: "import-account" }); //this.$router.push({ name: "import-account" });
} }

Loading…
Cancel
Save