Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/violet-needles-own.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@animo-id/mdoc": patch
---

fix: always true statement throws error. In the DeviceResponse model there was an always true if statement that throws an error before allowing the creation of the response.
20 changes: 11 additions & 9 deletions src/mdoc/models/device-response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { DeviceSigned } from './device-signed'
import type { DocRequest } from './doc-request'
import { Document, type DocumentStructure } from './document'
import { DocumentError, type DocumentErrorStructure } from './document-error'
import type { IssuerSigned } from './issuer-signed'
import { IssuerSigned } from './issuer-signed'
import {
findMdocMatchingDocType,
limitDisclosureToDeviceRequestNameSpaces,
Expand Down Expand Up @@ -161,12 +161,11 @@ export class DeviceResponse extends CborStructure {
},
ctx: Pick<MdocContext, 'crypto' | 'cose'>
) {
if (!(options.mac && options.signature) || (options.mac && options.signature)) {
throw new EitherSignatureOrMacMustBeProvidedError()
}

const useMac = !!options.mac
const useSignature = !!options.signature
const signingKey = useSignature ? options.mac.signingKey : options.signature.signingKey
if (useMac === useSignature) throw new EitherSignatureOrMacMustBeProvidedError()

const signingKey = useSignature ? options.signature!.signingKey : options.mac!.signingKey

const documents = await Promise.all(
options.inputDescriptorsOrRequests.map(async (idOrRequest) => {
Expand All @@ -182,7 +181,7 @@ export class DeviceResponse extends CborStructure {
const deviceAuthenticationBytes = new DeviceAuthentication({
sessionTranscript: options.sessionTranscript,
docType: document.docType,
deviceNamespaces: document.deviceSigned.deviceNamespaces,
deviceNamespaces,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is still incorrect maybe, since we don't want to do any limit disclosure on the device namespaces (as devicenamesaces is the return value of limitDisclosureCb).

See also the 0.5 implementation: https://github.com/animo/mdoc/blob/v0.5.3-alpha-20250322020612/src/mdoc/model/device-response.ts#L353-L376

}).encode({ asDataItem: true })

const unprotectedHeaders = signingKey.keyId
Expand Down Expand Up @@ -218,7 +217,7 @@ export class DeviceResponse extends CborStructure {
await deviceMac.addTag(
{
privateKey: signingKey,
ephemeralKey: (options.mac as Required<typeof options.mac>).ephemeralKey,
ephemeralKey: (options.mac as Required<typeof options.mac>)!.ephemeralKey,
sessionTranscript: options.sessionTranscript,
},
ctx
Expand All @@ -229,7 +228,10 @@ export class DeviceResponse extends CborStructure {

return new Document({
docType: document.docType,
issuerSigned: document.issuerSigned,
issuerSigned: new IssuerSigned({
issuerNamespaces: document.issuerSigned.issuerNamespaces,
issuerAuth: document.issuerSigned.issuerAuth,
}),
deviceSigned: new DeviceSigned({
deviceNamespaces,
deviceAuth: new DeviceAuth(deviceAuthOptions),
Expand Down
29 changes: 17 additions & 12 deletions src/mdoc/models/pex-limit-disclosure.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import type { DataElementIdentifier } from './data-element-identifier.js'
import type { DataElementValue } from './data-element-value.js'
import { DeviceNamespaces } from './device-namespaces.js'
import { DeviceSignedItems } from './device-signed-items.js'
import type { DocRequest } from './doc-request.js'
import type { DocType } from './doctype.js'
import type { Document } from './document.js'
import type { IssuerNamespace } from './issuer-namespace.js'
import type { IssuerSignedItem } from './issuer-signed-item.js'
import type { IssuerSigned } from './issuer-signed.js'
import type { InputDescriptor } from './presentation-definition.js'
import type { DataElementIdentifier } from './data-element-identifier'
import type { DataElementValue } from './data-element-value'
import { DeviceNamespaces } from './device-namespaces'
import { DeviceSignedItems } from './device-signed-items'
import type { DocRequest } from './doc-request'
import type { DocType } from './doctype'
import type { Document } from './document'
import { IssuerNamespace } from './issuer-namespace'
import type { IssuerSignedItem } from './issuer-signed-item'
import type { IssuerSigned } from './issuer-signed'
import type { InputDescriptor } from './presentation-definition'

export const limitDisclosureToDeviceRequestNameSpaces = (
issuerSigned: IssuerSigned,
Expand All @@ -34,6 +34,7 @@ export const limitDisclosureToDeviceRequestNameSpaces = (
deviceSignedItems.set(issuerSignedItem.elementIdentifier, issuerSignedItem.elementValue)
}

issuerSigned.issuerNamespaces?.issuerNamespaces.set(nameSpace, issuerSignedItems)
deviceNamespaces.set(nameSpace, new DeviceSignedItems({ deviceSignedItems }))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should set the device namespaces. Also not sure if we should modify the issuer signed directly (input mdoc).

If you look at the 0.5 implementaiton we don't modify the input: https://github.com/animo/mdoc/blob/v0.5.3-alpha-20250322020612/src/mdoc/model/pex-limit-disclosure.ts#L8-L27. So we sohuld update the device namespace to issuer namespaces, and create a new map/object and return that.

}

Expand Down Expand Up @@ -147,6 +148,8 @@ export const limitDisclosureToInputDescriptor = (
): DeviceNamespaces => {
const deviceNamespaces: Map<string, DeviceSignedItems> = new Map()

const issuerNamespaces = new Map()

for (const field of inputDescriptor.constraints.fields) {
const result = prepareDigestForInputDescriptor(field.path, issuerSigned.issuerNamespaces)

Expand All @@ -163,12 +166,14 @@ export const limitDisclosureToInputDescriptor = (
const { namespace, digest } = result
const entry = deviceNamespaces.get(namespace)
if (!entry) {
issuerNamespaces.set(namespace, [digest])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SAme here, device namespaces logic needs to be removed, and we only keep issuer namespaces.

Baiscally just copy the 0.5 implementation

deviceNamespaces.set(namespace, issuerSignedItemToDeviceSignedItems(digest))
} else {
issuerNamespaces.get(namespace).push(digest)
entry.deviceSignedItems.set(digest.elementIdentifier, digest.elementValue)
}
}

issuerSigned.issuerNamespaces = new IssuerNamespace({ issuerNamespaces })
return new DeviceNamespaces({ deviceNamespaces })
}

Expand Down