Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
nitro-neal committed Feb 6, 2024
1 parent 1730ef1 commit 0c1337a
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 249 deletions.
104 changes: 33 additions & 71 deletions packages/credentials/src/jwt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import type {
Web5Crypto,
CryptoAlgorithm,
JwtHeaderParams,
JwkParamsEcPrivate,
JwkParamsOkpPrivate,
JwkParamsEcPublic,
JwkParamsOkpPublic,
} from '@web5/crypto';
Expand Down Expand Up @@ -49,7 +47,7 @@ export type ParseJwtOptions = {
* Parameters for signing a JWT.
*/
export type SignJwtOptions = {
signerDid: PortableDid | BearerDid
signerDid: BearerDid
payload: JwtPayload
}

Expand Down Expand Up @@ -116,80 +114,48 @@ export class Jwt {
* @returns The compact JWT as a string.
*/
static async sign(options: SignJwtOptions): Promise<string> {
let { signerDid, payload } = options;
const { signerDid, payload } = options;

if (isPortableDid(signerDid)) {
signerDid = signerDid as PortableDid;

const privateKeyJwk = signerDid.verificationMethods![0].privateKeyJwk! as JwkParamsEcPrivate | JwkParamsOkpPrivate;

let vmId = signerDid.verificationMethods![0].id!;
if (vmId.charAt(0) === '#') {
vmId = `${signerDid.uri}${vmId}`;
}

const header: JwtHeaderParams = {
typ : 'JWT',
alg : privateKeyJwk.alg!,
kid : vmId
};

const base64UrlEncodedHeader = Convert.object(header).toBase64Url();
const base64UrlEncodedPayload = Convert.object(payload).toBase64Url();

const toSign = `${base64UrlEncodedHeader}.${base64UrlEncodedPayload}`;
const toSignBytes = Convert.string(toSign).toUint8Array();

const algorithmId = `${header.alg}:${privateKeyJwk['crv'] || ''}`;
if (!(algorithmId in Jwt.algorithms)) {
throw new Error(`Signing failed: ${algorithmId} not supported`);
}

const { signer, options: signatureAlgorithm } = Jwt.algorithms[algorithmId];

const signatureBytes = await signer.sign({ key: privateKeyJwk, data: toSignBytes, algorithm: signatureAlgorithm! });
const base64UrlEncodedSignature = Convert.uint8Array(signatureBytes).toBase64Url();
let vmId = signerDid.didDocument.verificationMethod![0].id!;
if (vmId.charAt(0) === '#') {
vmId = `${signerDid.uri}${vmId}`;
}

return `${toSign}.${base64UrlEncodedSignature}`;
// TODO: Change once signer has a method to get the alg and kid
// const header = {
// typ : 'JWT',
// alg: signer.alg,
// kid: signer.kid
// }

let alg;
if(signerDid.didDocument.verificationMethod![0].publicKeyJwk?.crv === 'Ed25519') {
alg = 'EdDSA';
} else if(signerDid.didDocument.verificationMethod![0].publicKeyJwk?.crv === 'secp256k1'){
alg = 'ES256K';
} else {
signerDid = signerDid as BearerDid;

let vmId = signerDid.didDocument.verificationMethod![0].id!;
if (vmId.charAt(0) === '#') {
vmId = `${signerDid.uri}${vmId}`;
}

// TODO: Is this correct?
let alg;
if(signerDid.didDocument.verificationMethod![0].publicKeyJwk?.crv === 'Ed25519') {
alg = 'EdDSA';
} else if(signerDid.didDocument.verificationMethod![0].publicKeyJwk?.crv === 'secp256k1'){
alg = 'ES256K';
} else {
throw new Error(`Signing failed: alg not supported`);
}

const header: JwtHeaderParams = {
typ : 'JWT',
alg : alg!,
kid : vmId,
};
throw new Error(`Signing failed: alg not supported`);
}

const base64UrlEncodedHeader = Convert.object(header).toBase64Url();
const base64UrlEncodedPayload = Convert.object(payload).toBase64Url();
const header: JwtHeaderParams = {
typ : 'JWT',
alg : alg!,
kid : vmId,
};

const toSign = `${base64UrlEncodedHeader}.${base64UrlEncodedPayload}`;
const toSignBytes = Convert.string(toSign).toUint8Array();
const base64UrlEncodedHeader = Convert.object(header).toBase64Url();
const base64UrlEncodedPayload = Convert.object(payload).toBase64Url();

const signer = await signerDid.getSigner();
const toSign = `${base64UrlEncodedHeader}.${base64UrlEncodedPayload}`;
const toSignBytes = Convert.string(toSign).toUint8Array();

const signatureBytes = await signer.sign({data: toSignBytes});
const signer = await signerDid.getSigner();

const base64UrlEncodedSignature = Convert.uint8Array(signatureBytes).toBase64Url();
const signatureBytes = await signer.sign({data: toSignBytes});

return `${toSign}.${base64UrlEncodedSignature}`;
}
const base64UrlEncodedSignature = Convert.uint8Array(signatureBytes).toBase64Url();

return `${toSign}.${base64UrlEncodedSignature}`;
}

/**
Expand Down Expand Up @@ -307,8 +273,4 @@ export class Jwt {
}
};
}
}

function isPortableDid(did: PortableDid | BearerDid): did is PortableDid {
return (did as PortableDid).verificationMethods !== undefined;
}
4 changes: 2 additions & 2 deletions packages/credentials/src/verifiable-credential.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { PortableDid, BearerDid } from '@web5/dids';
import type { BearerDid } from '@web5/dids';
import type { ICredential, ICredentialSubject} from '@sphereon/ssi-types';

import { utils as cryptoUtils } from '@web5/crypto';
Expand Down Expand Up @@ -41,7 +41,7 @@ export type VerifiableCredentialCreateOptions = {
* @param did - The issuer DID of the credential, represented as a PortableDid.
*/
export type VerifiableCredentialSignOptions = {
did: PortableDid | BearerDid;
did: BearerDid;
};

type CredentialSubject = ICredentialSubject;
Expand Down
7 changes: 3 additions & 4 deletions packages/credentials/tests/presentation-exchange.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from 'chai';
import { DidKey, PortableDid } from '@web5/dids';
import { BearerDid, DidKey } from '@web5/dids';

import type { Validated, PresentationDefinitionV2 } from '../src/presentation-exchange.js';

Expand All @@ -22,14 +22,13 @@ class OtherCredential {

describe('PresentationExchange', () => {
describe('Full Presentation Exchange', () => {
let issuerDid: PortableDid;
let issuerDid: BearerDid;
let btcCredentialJwt: string;
let presentationDefinition: PresentationDefinitionV2;
let groupPresentationDefinition: PresentationDefinitionV2;

before(async () => {
const did = await DidKey.create();
issuerDid = await DidKey.toKeys({ did });
issuerDid = await DidKey.create();

const vc = await VerifiableCredential.create({
type : 'StreetCred',
Expand Down
Loading

0 comments on commit 0c1337a

Please sign in to comment.