Trent Larson
4 months ago
4 changed files with 112 additions and 85 deletions
@ -0,0 +1,96 @@ |
|||
import {Buffer} from "buffer/"; |
|||
import {decode as cborDecode} from "cbor-x"; |
|||
import {bytesToMultibase, multibaseToBytes} from "did-jwt"; |
|||
|
|||
import {getWebCrypto} from "@/libs/crypto/vc/passkeyHelpers"; |
|||
|
|||
const PEER_DID_PREFIX = "did:peer:"; |
|||
const PEER_DID_MULTIBASE_PREFIX = PEER_DID_PREFIX + "0"; |
|||
|
|||
/** |
|||
* |
|||
* |
|||
* similar code is in crowd-funder-for-time-pwa libs/crypto/vc/passkeyDidPeer.ts verifyJwtWebCrypto |
|||
* |
|||
* @returns {Promise<boolean>} |
|||
*/ |
|||
export async function verifyPeerSignature( |
|||
payloadBytes: Buffer, |
|||
issuerDid: string, |
|||
signatureBytes: Uint8Array, |
|||
): Promise<boolean> { |
|||
const publicKeyBytes = peerDidToPublicKeyBytes(issuerDid); |
|||
|
|||
const WebCrypto = await getWebCrypto(); |
|||
const verifyAlgorithm = { |
|||
name: "ECDSA", |
|||
hash: { name: "SHA-256" }, |
|||
}; |
|||
const publicKeyJwk = cborToKeys(publicKeyBytes).publicKeyJwk; |
|||
const keyAlgorithm = { |
|||
name: "ECDSA", |
|||
namedCurve: publicKeyJwk.crv, |
|||
}; |
|||
const publicKeyCryptoKey = await WebCrypto.subtle.importKey( |
|||
"jwk", |
|||
publicKeyJwk, |
|||
keyAlgorithm, |
|||
false, |
|||
["verify"], |
|||
); |
|||
const verified = await WebCrypto.subtle.verify( |
|||
verifyAlgorithm, |
|||
publicKeyCryptoKey, |
|||
signatureBytes, |
|||
payloadBytes, |
|||
); |
|||
return verified; |
|||
} |
|||
|
|||
export function cborToKeys(publicKeyBytes: Uint8Array) { |
|||
const jwkObj = cborDecode(publicKeyBytes); |
|||
if ( |
|||
jwkObj[1] != 2 || // kty "EC"
|
|||
jwkObj[3] != -7 || // alg "ES256"
|
|||
jwkObj[-1] != 1 || // crv "P-256"
|
|||
jwkObj[-2].length != 32 || // x
|
|||
jwkObj[-3].length != 32 // y
|
|||
) { |
|||
throw new Error("Unable to extract key."); |
|||
} |
|||
const publicKeyJwk = { |
|||
alg: "ES256", |
|||
crv: "P-256", |
|||
kty: "EC", |
|||
x: arrayToBase64Url(jwkObj[-2]), |
|||
y: arrayToBase64Url(jwkObj[-3]), |
|||
}; |
|||
const publicKeyBuffer = Buffer.concat([ |
|||
Buffer.from(jwkObj[-2]), |
|||
Buffer.from(jwkObj[-3]), |
|||
]); |
|||
return { publicKeyJwk, publicKeyBuffer }; |
|||
} |
|||
|
|||
export function toBase64Url(anythingB64: string) { |
|||
return anythingB64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""); |
|||
} |
|||
|
|||
export function arrayToBase64Url(anything: Uint8Array) { |
|||
return toBase64Url(Buffer.from(anything).toString("base64")); |
|||
} |
|||
|
|||
export function peerDidToPublicKeyBytes(did: string) { |
|||
return multibaseToBytes(did.substring(PEER_DID_MULTIBASE_PREFIX.length)); |
|||
} |
|||
|
|||
export function createPeerDid(publicKeyBytes: 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( |
|||
publicKeyBytes, |
|||
"base58btc", |
|||
"p256-pub", |
|||
); |
|||
return PEER_DID_MULTIBASE_PREFIX + methodSpecificId; |
|||
} |
Loading…
Reference in new issue