|
|
@ -23,7 +23,8 @@ import { |
|
|
|
|
|
|
|
import { getWebCrypto, unwrapEC2Signature } from "@/libs/crypto/passkeyHelpers"; |
|
|
|
|
|
|
|
const PEER_DID_PREFIX = "did:peer:0"; |
|
|
|
const PEER_DID_PREFIX = "did:peer:"; |
|
|
|
const PEER_DID_MULTIBASE_PREFIX = PEER_DID_PREFIX + "0"; |
|
|
|
export interface JWK { |
|
|
|
kty: string; |
|
|
|
crv: string; |
|
|
@ -99,11 +100,11 @@ export function createPeerDid(publicKeyBytes: Uint8Array) { |
|
|
|
"base58btc", |
|
|
|
"p256-pub", |
|
|
|
); |
|
|
|
return PEER_DID_PREFIX + methodSpecificId; |
|
|
|
return PEER_DID_MULTIBASE_PREFIX + methodSpecificId; |
|
|
|
} |
|
|
|
|
|
|
|
function peerDidToPublicKeyBytes(did: string) { |
|
|
|
return multibaseToBytes(did.substring(PEER_DID_PREFIX.length)); |
|
|
|
return multibaseToBytes(did.substring(PEER_DID_MULTIBASE_PREFIX.length)); |
|
|
|
} |
|
|
|
|
|
|
|
export class PeerSetup { |
|
|
@ -112,10 +113,19 @@ export class PeerSetup { |
|
|
|
public clientDataJsonBase64Url?: Base64URLString; |
|
|
|
public signature?: Base64URLString; |
|
|
|
|
|
|
|
public async createJwtSimplewebauthn(fullPayload: object, credIdHex: string) { |
|
|
|
public async createJwtSimplewebauthn( |
|
|
|
issuerDid: string, |
|
|
|
payload: object, |
|
|
|
credIdHex: string, |
|
|
|
) { |
|
|
|
const credentialId = arrayBufferToBase64URLString( |
|
|
|
Buffer.from(credIdHex, "hex").buffer, |
|
|
|
); |
|
|
|
const fullPayload = { |
|
|
|
...payload, |
|
|
|
iat: Math.floor(Date.now() / 1000), |
|
|
|
iss: issuerDid, |
|
|
|
}; |
|
|
|
this.challenge = new Uint8Array(Buffer.from(JSON.stringify(fullPayload))); |
|
|
|
// const payloadHash: Uint8Array = sha256(this.challenge);
|
|
|
|
const options: PublicKeyCredentialRequestOptionsJSON = |
|
|
@ -147,18 +157,33 @@ export class PeerSetup { |
|
|
|
.replace(/=+$/, ""); |
|
|
|
|
|
|
|
const dataInJwt = { |
|
|
|
AuthenticationData: authenticatorDataBase64Url, |
|
|
|
ClientDataJSON: this.clientDataJsonBase64Url, |
|
|
|
AuthenticationDataB64URL: authenticatorDataBase64Url, |
|
|
|
ClientDataJSONB64URL: this.clientDataJsonBase64Url, |
|
|
|
iat: Math.floor(Date.now() / 1000), |
|
|
|
iss: issuerDid, |
|
|
|
}; |
|
|
|
const dataInJwtString = JSON.stringify(dataInJwt); |
|
|
|
const payloadBase64 = Buffer.from(dataInJwtString).toString("base64"); |
|
|
|
const payloadBase64 = Buffer.from(dataInJwtString) |
|
|
|
.toString("base64") |
|
|
|
.replace(/\+/g, "-") |
|
|
|
.replace(/\//g, "_") |
|
|
|
.replace(/=+$/, ""); |
|
|
|
|
|
|
|
const signature = clientAuth.response.signature; |
|
|
|
|
|
|
|
return headerBase64 + "." + payloadBase64 + "." + signature; |
|
|
|
} |
|
|
|
|
|
|
|
public async createJwtNavigator(fullPayload: object, credIdHex: string) { |
|
|
|
public async createJwtNavigator( |
|
|
|
issuerDid: string, |
|
|
|
payload: object, |
|
|
|
credIdHex: string, |
|
|
|
) { |
|
|
|
const fullPayload = { |
|
|
|
...payload, |
|
|
|
iat: Math.floor(Date.now() / 1000), |
|
|
|
iss: issuerDid, |
|
|
|
}; |
|
|
|
const dataToSignString = JSON.stringify(fullPayload); |
|
|
|
const dataToSignBuffer = Buffer.from(dataToSignString); |
|
|
|
const credentialId = Buffer.from(credIdHex, "hex"); |
|
|
@ -200,8 +225,10 @@ export class PeerSetup { |
|
|
|
.replace(/=+$/, ""); |
|
|
|
|
|
|
|
const dataInJwt = { |
|
|
|
AuthenticationData: authenticatorDataBase64Url, |
|
|
|
ClientDataJSON: this.clientDataJsonBase64Url, |
|
|
|
AuthenticationDataB64URL: authenticatorDataBase64Url, |
|
|
|
ClientDataJSONB64URL: this.clientDataJsonBase64Url, |
|
|
|
iat: Math.floor(Date.now() / 1000), |
|
|
|
iss: issuerDid, |
|
|
|
}; |
|
|
|
const dataInJwtString = JSON.stringify(dataInJwt); |
|
|
|
const payloadBase64 = Buffer.from(dataInJwtString) |
|
|
@ -284,7 +311,7 @@ export class PeerSetup { |
|
|
|
// import { p256 } from "@noble/curves/p256";
|
|
|
|
export async function verifyJwtP256( |
|
|
|
credIdHex: string, |
|
|
|
did: string, |
|
|
|
issuerDid: string, |
|
|
|
authenticatorData: ArrayBuffer, |
|
|
|
challenge: Uint8Array, |
|
|
|
clientDataJsonBase64Url: Base64URLString, |
|
|
@ -294,7 +321,7 @@ export async function verifyJwtP256( |
|
|
|
const clientDataFromBase = Buffer.from(clientDataJsonBase64Url, "base64"); |
|
|
|
const sigBuffer = Buffer.from(signature, "base64"); |
|
|
|
const finalSigBuffer = unwrapEC2Signature(sigBuffer); |
|
|
|
const publicKeyBytes = peerDidToPublicKeyBytes(did); |
|
|
|
const publicKeyBytes = peerDidToPublicKeyBytes(issuerDid); |
|
|
|
|
|
|
|
// Hash the client data
|
|
|
|
const hash = sha256(clientDataFromBase); |
|
|
@ -312,14 +339,14 @@ export async function verifyJwtP256( |
|
|
|
|
|
|
|
export async function verifyJwtSimplewebauthn( |
|
|
|
credIdHex: string, |
|
|
|
did: string, |
|
|
|
issuerDid: string, |
|
|
|
authenticatorData: ArrayBuffer, |
|
|
|
challenge: Uint8Array, |
|
|
|
clientDataJsonBase64Url: Base64URLString, |
|
|
|
signature: Base64URLString, |
|
|
|
) { |
|
|
|
const authData = arrayToBase64Url(Buffer.from(authenticatorData)); |
|
|
|
const publicKeyBytes = peerDidToPublicKeyBytes(did); |
|
|
|
const publicKeyBytes = peerDidToPublicKeyBytes(issuerDid); |
|
|
|
const credId = arrayBufferToBase64URLString( |
|
|
|
Buffer.from(credIdHex, "hex").buffer, |
|
|
|
); |
|
|
@ -351,7 +378,7 @@ export async function verifyJwtSimplewebauthn( |
|
|
|
|
|
|
|
export async function verifyJwtWebCrypto( |
|
|
|
credId: Base64URLString, |
|
|
|
did: string, |
|
|
|
issuerDid: string, |
|
|
|
authenticatorData: ArrayBuffer, |
|
|
|
challenge: Uint8Array, |
|
|
|
clientDataJsonBase64Url: Base64URLString, |
|
|
@ -368,12 +395,13 @@ export async function verifyJwtWebCrypto( |
|
|
|
// Construct the preimage
|
|
|
|
const preimage = Buffer.concat([authDataFromBase, hash]); |
|
|
|
|
|
|
|
const publicKeyBytes = peerDidToPublicKeyBytes(issuerDid); |
|
|
|
|
|
|
|
const WebCrypto = await getWebCrypto(); |
|
|
|
const verifyAlgorithm = { |
|
|
|
name: "ECDSA", |
|
|
|
hash: { name: "SHA-256" }, |
|
|
|
}; |
|
|
|
const publicKeyBytes = peerDidToPublicKeyBytes(did); |
|
|
|
const publicKeyJwk = cborToKeys(publicKeyBytes).publicKeyJwk; |
|
|
|
const keyAlgorithm = { |
|
|
|
name: "ECDSA", |
|
|
|