Skip to content

Commit

Permalink
fix: Fix relative DID resolution and Json websignature 2020 verificat…
Browse files Browse the repository at this point in the history
…ion for ED25519 and some other algs
  • Loading branch information
nklomp committed Jul 12, 2023
1 parent aa3f3f1 commit ca2682c
Show file tree
Hide file tree
Showing 15 changed files with 1,069 additions and 1,021 deletions.
8 changes: 4 additions & 4 deletions packages/oid4vci-issuer-rest-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
"@sphereon/did-uni-client": "^0.6.0",
"@sphereon/pex": "^2.0.1",
"@sphereon/pex-models": "^2.0.2",
"@sphereon/ssi-sdk-ext.did-provider-jwk": "0.12.2-next.3",
"@sphereon/ssi-sdk-ext.key-manager": "0.12.2-next.3",
"@sphereon/ssi-sdk-ext.key-utils": "0.12.2-next.3",
"@sphereon/ssi-sdk-ext.kms-local": "0.12.2-next.3",
"@sphereon/ssi-sdk-ext.did-provider-jwk": "0.12.2-next.4",
"@sphereon/ssi-sdk-ext.key-manager": "0.12.2-next.4",
"@sphereon/ssi-sdk-ext.key-utils": "0.12.2-next.4",
"@sphereon/ssi-sdk-ext.kms-local": "0.12.2-next.4",
"@sphereon/ssi-sdk.data-store": "workspace:*",
"@sphereon/ssi-sdk.vc-handler-ld-local": "workspace:*",
"@types/body-parser": "^1.19.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/oid4vci-issuer-store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
},
"dependencies": {
"@sphereon/oid4vci-common": "0.6.0",
"@sphereon/ssi-sdk-ext.did-utils": "0.12.2-next.3",
"@sphereon/ssi-sdk-ext.did-utils": "0.12.2-next.4",
"@sphereon/ssi-sdk.kv-store-temp": "workspace:*",
"@types/uuid": "^9.0.1",
"@veramo/core": "4.2.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/oid4vci-issuer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"dependencies": {
"@sphereon/oid4vci-common": "0.6.0",
"@sphereon/oid4vci-issuer": "0.6.0",
"@sphereon/ssi-sdk-ext.did-utils": "0.12.2-next.3",
"@sphereon/ssi-sdk-ext.did-utils": "0.12.2-next.4",
"@sphereon/ssi-sdk.core": "workspace:*",
"@sphereon/ssi-sdk.kv-store-temp": "workspace:*",
"@sphereon/ssi-sdk.oid4vci-issuer-store": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/presentation-exchange/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"dependencies": {
"@sphereon/pex": "2.0.1",
"@sphereon/pex-models": "^2.0.2",
"@sphereon/ssi-sdk-ext.did-utils": "0.12.2-next.3",
"@sphereon/ssi-sdk-ext.did-utils": "0.12.2-next.4",
"@sphereon/ssi-sdk.kv-store-temp": "workspace:*",
"@sphereon/ssi-types": "workspace:*",
"@veramo/core": "4.2.0"
Expand Down
2 changes: 1 addition & 1 deletion packages/siopv2-oid4vp-op-auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@sphereon/did-auth-siop": "0.3.2-unstable.6",
"@sphereon/pex": "2.0.1",
"@sphereon/pex-models": "2.0.2",
"@sphereon/ssi-sdk-ext.did-utils": "0.12.2-next.3",
"@sphereon/ssi-sdk-ext.did-utils": "0.12.2-next.4",
"@sphereon/ssi-sdk.core": "workspace:*",
"@sphereon/ssi-sdk.presentation-exchange": "workspace:*",
"@sphereon/ssi-types": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/siopv2-oid4vp-rp-auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"dependencies": {
"@sphereon/did-auth-siop": "0.3.2-unstable.6",
"@sphereon/pex": "2.0.1",
"@sphereon/ssi-sdk-ext.did-utils": "0.12.2-next.3",
"@sphereon/ssi-sdk-ext.did-utils": "0.12.2-next.4",
"@sphereon/ssi-sdk.core": "workspace:*",
"@sphereon/ssi-sdk.kv-store-temp": "workspace:*",
"@sphereon/ssi-sdk.presentation-exchange": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/siopv2-oid4vp-rp-rest-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"@sphereon/did-uni-client": "^0.6.0",
"@sphereon/pex": "^2.0.1",
"@sphereon/pex-models": "^2.0.2",
"@sphereon/ssi-sdk-ext.did-provider-jwk": "0.12.2-next.3",
"@sphereon/ssi-sdk-ext.did-provider-jwk": "0.12.2-next.4",
"@sphereon/ssi-sdk.data-store": "workspace:*",
"@sphereon/ssi-sdk.vc-handler-ld-local": "workspace:*",
"@types/body-parser": "^1.19.2",
Expand Down
1 change: 1 addition & 0 deletions packages/ssi-sdk-core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './utils'
export {
agentContext,
VerifiablePresentationSP,
UnsignedPresentationSP,
VerifiableCredentialSP,
Expand Down
7 changes: 7 additions & 0 deletions packages/ssi-sdk-core/src/types/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { IAgentContext, IPluginMethodMap, TAgent } from '@veramo/core'

export function agentContext<TAgentTypes extends IPluginMethodMap>(agent: TAgent<TAgentTypes>): IAgentContext<TAgentTypes> {
return {
agent,
}
}
1 change: 1 addition & 0 deletions packages/ssi-sdk-core/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './vc-data-models'
export * from './signatures'
export * from './images'
export * from './context'
10 changes: 5 additions & 5 deletions packages/vc-handler-ld-local/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@mattrglobal/jsonld-signatures-bbs": "^1.1.1",
"@sphereon/ed25519-signature-2018": "0.7.0-unstable.6",
"@sphereon/isomorphic-webcrypto": "^2.4.0-unstable.4",
"@sphereon/ssi-sdk-ext.did-utils": "0.12.2-next.3",
"@sphereon/ssi-sdk-ext.did-utils": "0.12.2-next.4",
"@sphereon/ssi-sdk.core": "workspace:*",
"@sphereon/ssi-types": "workspace:*",
"@transmute/ed25519-key-pair": "0.7.0-unstable.80",
Expand All @@ -50,10 +50,10 @@
},
"devDependencies": {
"@sphereon/did-uni-client": "^0.6.0",
"@sphereon/ssi-sdk-ext.did-provider-key": "0.12.2-next.3",
"@sphereon/ssi-sdk-ext.did-provider-lto": "0.12.2-next.3",
"@sphereon/ssi-sdk-ext.key-manager": "0.12.2-next.3",
"@sphereon/ssi-sdk-ext.kms-local": "0.12.2-next.3",
"@sphereon/ssi-sdk-ext.did-provider-key": "0.12.2-next.4",
"@sphereon/ssi-sdk-ext.did-provider-lto": "0.12.2-next.4",
"@sphereon/ssi-sdk-ext.key-manager": "0.12.2-next.4",
"@sphereon/ssi-sdk-ext.kms-local": "0.12.2-next.4",
"@sphereon/ssi-sdk.agent-config": "workspace:*",
"@transmute/lds-ecdsa-secp256k1-recovery2020": "^0.0.7",
"@types/nock": "^11.1.0",
Expand Down
12 changes: 6 additions & 6 deletions packages/vc-handler-ld-local/src/ld-credential-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class LdCredentialModule {
): Promise<VerifiableCredentialSP> {
debug(`Issue VC method called for ${key.kid}...`)
const suite = this.ldSuiteLoader.getSignatureSuiteForKeyType(key.type, key.meta?.verificationMethod?.type)
const documentLoader = this.ldDocumentLoader.getLoader(context, true)
const documentLoader = this.ldDocumentLoader.getLoader(context, { attemptToFetchContexts: true, verifiableData: credential })

// some suites can modify the incoming credential (e.g. add required contexts)
suite.preSigningCredModification(credential)
Expand Down Expand Up @@ -97,7 +97,7 @@ export class LdCredentialModule {
context: IAgentContext<RequiredAgentMethods>
): Promise<VerifiablePresentationSP> {
const suite = this.ldSuiteLoader.getSignatureSuiteForKeyType(key.type, key.meta?.verificationMethod?.type)
const documentLoader = this.ldDocumentLoader.getLoader(context, true)
const documentLoader = this.ldDocumentLoader.getLoader(context, { attemptToFetchContexts: true, verifiableData: presentation })

suite.preSigningPresModification(presentation)

Expand Down Expand Up @@ -141,14 +141,14 @@ export class LdCredentialModule {
result = await jsigs.verify(credential, {
suite,
purpose,
documentLoader: this.ldDocumentLoader.getLoader(context, fetchRemoteContexts),
documentLoader: this.ldDocumentLoader.getLoader(context, { attemptToFetchContexts: fetchRemoteContexts, verifiableData: credential }),
compactProof: true,
})
} else {
result = await vc.verifyCredential({
credential,
suite: verificationSuites,
documentLoader: this.ldDocumentLoader.getLoader(context, fetchRemoteContexts),
documentLoader: this.ldDocumentLoader.getLoader(context, { attemptToFetchContexts: fetchRemoteContexts, verifiableData: credential }),
purpose,
compactProof: false,
checkStatus,
Expand Down Expand Up @@ -191,14 +191,14 @@ export class LdCredentialModule {
result = await jsigs.verify(presentation, {
suite,
purpose: presentationPurpose,
documentLoader: this.ldDocumentLoader.getLoader(context, fetchRemoteContexts),
documentLoader: this.ldDocumentLoader.getLoader(context, { attemptToFetchContexts: fetchRemoteContexts, verifiableData: presentation }),
compactProof: true,
})
} else {
result = await vc.verify({
presentation,
suite: this.getAllVerificationSuites(),
documentLoader: this.ldDocumentLoader.getLoader(context, fetchRemoteContexts),
documentLoader: this.ldDocumentLoader.getLoader(context, { attemptToFetchContexts: fetchRemoteContexts, verifiableData: presentation }),
challenge,
domain,
presentationPurpose,
Expand Down
58 changes: 40 additions & 18 deletions packages/vc-handler-ld-local/src/ld-document-loader.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { extendContextLoader } from '@digitalcredentials/jsonld-signatures'
import vc from '@digitalcredentials/vc'
import { DIDDocument, IAgentContext, IResolver } from '@veramo/core'

import {
CredentialPayload,
DIDDocument,
IAgentContext,
IResolver,
PresentationPayload,
VerifiableCredential,
VerifiablePresentation,
} from '@veramo/core'
import { fetch } from 'cross-fetch'
import Debug from 'debug'

import { LdContextLoader } from './ld-context-loader'
import { LdSuiteLoader } from './ld-suite-loader'

import { fetch } from 'cross-fetch'

const debug = Debug('sphereon:ssi-sdk:vc-handler-ld-local')

/**
Expand All @@ -23,24 +29,33 @@ export class LdDocumentLoader {
this.ldSuiteLoader = options.ldSuiteLoader
}

getLoader(context: IAgentContext<IResolver>, attemptToFetchContexts = false) {
getLoader(
context: IAgentContext<IResolver>,
{
attemptToFetchContexts = false,
verifiableData,
}: { attemptToFetchContexts: boolean; verifiableData: VerifiableCredential | VerifiablePresentation | CredentialPayload | PresentationPayload }
) {
return extendContextLoader(async (url: string) => {
if (!url || url.trim().length === 0) {
throw Error('URL needs to be provided to load a context!')
}
const origUrl = url
if (url.startsWith('#') && verifiableData.issuer !== undefined) {
url = (typeof verifiableData.issuer === 'string' ? verifiableData.issuer : verifiableData.issuer.id) + url
console.log(url)
}
// did resolution
if (url.toLowerCase().startsWith('did:')) {
let didDoc: DIDDocument | null
/* if (url.toLowerCase().startsWith('did:key:')) {
// const suite = this.ldSuiteLoader.getAllSignatureSuites()[0].getSuiteForVerification();
didDoc = await new DidKeyDriver().get({url});
} else {*/
const resolutionResult = await context.agent.resolveDid({ didUrl: url })
didDoc = resolutionResult.didDocument
// }
let didDoc: DIDDocument | null = resolutionResult.didDocument
if (!didDoc) {
throw new Error(`Could not fetch DID document with url: ${url}. Did you enable the the driver?`)
}
// currently Veramo LD suites can modify the resolution response for DIDs from
// the document Loader. This allows to fix incompatibilities between DID Documents
// and LD suites to be fixed specifically within the Veramo LD Suites definition
this.ldSuiteLoader.getAllSignatureSuites().forEach((x) => x.preDidResolutionModification(url, didDoc as DIDDocument))

// Move legacy publicKey to verificationMethod, so any dependency that does not support it, keeps functioning
if (didDoc.publicKey) {
Expand All @@ -55,8 +70,20 @@ export class LdDocumentLoader {
}

if (url.indexOf('#') > 0 && didDoc['@context']) {
if (origUrl !== url) {
// Make sure we replace the result URLs with the original URLs, so framing keeps working
didDoc = JSON.parse(JSON.stringify(didDoc).replace(url, origUrl)) as DIDDocument
console.log('CHANGED:')
console.log(didDoc)
}

// Apparently we got a whole DID document, but we are looking for a verification method
const component = await context.agent.getDIDComponentById({ didDocument: didDoc, didUrl: url })
// We use origUrl here, as that is how it was used in the VM
const component = await context.agent.getDIDComponentById({ didDocument: didDoc, didUrl: origUrl })
console.log('Component:')
console.log(component)
console.log('Component stringified:')
console.log(JSON.stringify(component))
if (component && typeof component !== 'string' && component.id) {
// We have to provide a context
const contexts = this.ldSuiteLoader
Expand All @@ -74,11 +101,6 @@ export class LdDocumentLoader {
}
}

// currently Veramo LD suites can modify the resolution response for DIDs from
// the document Loader. This allows to fix incompatibilities between DID Documents
// and LD suites to be fixed specifically within the Veramo LD Suites definition
this.ldSuiteLoader.getAllSignatureSuites().forEach((x) => x.preDidResolutionModification(url, didDoc as DIDDocument))

return {
contextUrl: null,
documentUrl: url,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Verifier } from '@transmute/jose-ld'
import sec from '@transmute/security-context'
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import jsonld from 'jsonld'
import * as u8a from 'uint8arrays'

const crypto = require('@sphereon/isomorphic-webcrypto')
import { JsonWebKey } from './JsonWebKeyWithRSASupport'
import * as u8a from 'uint8arrays'
import { Verifier } from '@transmute/jose-ld'

import sec from '@transmute/security-context'
// eslint-disable-next-line @typescript-eslint/no-var-requires
const crypto = require('@sphereon/isomorphic-webcrypto')

const subtle = crypto.subtle

Expand All @@ -21,11 +23,11 @@ export interface JsonWebSignatureOptions {
}

export class JsonWebSignature {
public useNativeCanonize: boolean = false
public useNativeCanonize = false
public key?: JsonWebKey
public proof: any
public date: any
public type: string = 'JsonWebSignature2020'
public type = 'JsonWebSignature2020'
public verificationMethod?: string
public verifier?: Verifier

Expand Down Expand Up @@ -226,23 +228,33 @@ export class JsonWebSignature {
return framed
}

return JsonWebKey.from(document, { signer: false, verifier: this.verifier })
return await JsonWebKey.from(document, { signer: false, verifier: this.verifier })
}

async verifySignature({ verifyData, verificationMethod, proof }: any) {
if (verificationMethod.publicKey) {
verificationMethod.publicKey.algorithm.name = 'RSA-PSS'
const key = verificationMethod.publicKey as CryptoKey
async verifySignature({ verifyData, verificationMethod, proof, document }: any) {
if (verificationMethod.publicKey && typeof verificationMethod.publicKey === 'object' && !(verificationMethod.publicKey instanceof Uint8Array)) {
// const key = verificationMethod.publicKey as CryptoKey
// key.algorithm = {name: 'RSA-PSS'}
const signature = proof.jws.split('.')[2]
const headerString = proof.jws.split('.')[0]
const messageBuffer = u8a.concat([u8a.fromString(`${headerString}.`, 'utf-8'), verifyData])

if (!verificationMethod.publicKey.algorithm) {
verificationMethod.publicKey.algorithm = {}
}
if (!verificationMethod.publicKey.algorithm.name) {
verificationMethod.publicKey.algorithm.name = 'RSA-PSS'
}
const key = verificationMethod.publicKey as CryptoKey
const algName = verificationMethod.publicKey.algorithm.name ?? key?.algorithm?.name ?? 'RSA-PSS'
return await subtle.verify(
{
saltLength: 32,
name: 'RSA-PSS', //key.algorithm?.name ? key.algorithm.name : 'RSASSA-PKCS1-V1_5',
// hash: 'SHA-256', // todo get from proof.jws header
},
algName === 'RSA-PSS'
? {
saltLength: 32,
name: algName,
// hash: 'SHA-256', // todo get from proof.jws header
}
: { name: algName },
key,
u8a.fromString(signature, 'base64url'),
messageBuffer
Expand Down
Loading

0 comments on commit ca2682c

Please sign in to comment.