Skip to content

Commit 0ea93dc

Browse files
TimoGlastraGHkrishna
authored andcommitted
fix: skip signature validation of the trusted certificate (#2248)
Signed-off-by: Timo Glastra <[email protected]>
1 parent be21dd4 commit 0ea93dc

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed

packages/core/src/modules/mdoc/__tests__/mdocDeviceResponse.test.ts

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { MdocDeviceResponse } from '../MdocDeviceResponse'
99

1010
describe('mdoc device-response test', () => {
1111
const agent = new Agent(getInMemoryAgentOptions('mdoc-test-agent', {}))
12-
beforeEach(async () => {
12+
beforeAll(async () => {
1313
await agent.initialize()
1414
})
1515

@@ -82,4 +82,71 @@ describe('mdoc device-response test', () => {
8282
},
8383
})
8484
})
85+
86+
test('verify OpenID4VP device response from Google CM Wallet', async () => {
87+
const rootCertificate = `-----BEGIN CERTIFICATE-----
88+
MIICkjCCAjmgAwIBAgIUIrllgKEU8qxSupeyniOVstAG4SgwCgYIKoZIzj0EAwIw
89+
eTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1v
90+
dW50YWluIFZpZXcxHDAaBgNVBAoME0RpZ2l0YWwgQ3JlZGVudGlhbHMxHzAdBgNV
91+
BAMMFmRpZ2l0YWxjcmVkZW50aWFscy5kZXYwHhcNMjUwMjE4MTg0MDU3WhcNMzUw
92+
MjA2MTg0MDU3WjB5MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEW
93+
MBQGA1UEBwwNTW91bnRhaW4gVmlldzEcMBoGA1UECgwTRGlnaXRhbCBDcmVkZW50
94+
aWFsczEfMB0GA1UEAwwWZGlnaXRhbGNyZWRlbnRpYWxzLmRldjBZMBMGByqGSM49
95+
AgEGCCqGSM49AwEHA0IABNcHRK+Y2b9qPzjSGABUP3IKOJu5/sYBCur6sTV7AHIb
96+
OG/YbBPCOWwAQQNnTaBWk8tey63NgOvp8IphAjuSVlqjgZ4wgZswHQYDVR0OBBYE
97+
FKJP9InZfEbobqOG2UdIzsy+3M/1MB8GA1UdIwQYMBaAFKJP9InZfEbobqOG2UdI
98+
zsy+3M/1MBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMCoGA1Ud
99+
EgQjMCGGH2h0dHBzOi8vZGlnaXRhbC1jcmVkZW50aWFscy5kZXYwCQYDVR0fBAIw
100+
ADAKBggqhkjOPQQDAgNHADBEAiA1snaKSxWSuQc45aZ5mBdYI7OVB1qzAiel0vVA
101+
B+kN6gIgKp/V7J2+2AAIRFfgexm7+72NaWGCkygXWfRPpbJ1eDk=
102+
-----END CERTIFICATE-----`
103+
104+
const documentSignerCertificate = `-----BEGIN CERTIFICATE-----
105+
MIICwDCCAmegAwIBAgIUHn8bMq1PNO/ksMwHt7DjM6cLGE0wCgYIKoZIzj0EAwIw
106+
eTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1v
107+
dW50YWluIFZpZXcxHDAaBgNVBAoME0RpZ2l0YWwgQ3JlZGVudGlhbHMxHzAdBgNV
108+
BAMMFmRpZ2l0YWxjcmVkZW50aWFscy5kZXYwHhcNMjUwMjE5MjMzMDE4WhcNMjYw
109+
MjE5MjMzMDE4WjB5MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEW
110+
MBQGA1UEBwwNTW91bnRhaW4gVmlldzEcMBoGA1UECgwTRGlnaXRhbCBDcmVkZW50
111+
aWFsczEfMB0GA1UEAwwWZGlnaXRhbGNyZWRlbnRpYWxzLmRldjBZMBMGByqGSM49
112+
AgEGCCqGSM49AwEHA0IABOt5Nivi1/OXw1AEfYPh42Is41VrNg9qaMdYuw3cavhs
113+
Ca+aXV0NmTl2EsNaJ5GWmMoAD8ikwAFszYhIeNgF42mjgcwwgckwHwYDVR0jBBgw
114+
FoAUok/0idl8Ruhuo4bZR0jOzL7cz/UwHQYDVR0OBBYEFN/+aloS6cBixLyYpyXS
115+
2XD3emAoMDQGA1UdHwQtMCswKaAnoCWGI2h0dHBzOi8vZGlnaXRhbC1jcmVkZW50
116+
aWFscy5kZXYvY3JsMCoGA1UdEgQjMCGGH2h0dHBzOi8vZGlnaXRhbC1jcmVkZW50
117+
aWFscy5kZXYwDgYDVR0PAQH/BAQDAgeAMBUGA1UdJQEB/wQLMAkGByiBjF0FAQIw
118+
CgYIKoZIzj0EAwIDRwAwRAIgYcXL9XzB43vy4LEz2h8gMQRdcJtaIRQOemgwm8sH
119+
QucCIHCvouHEm/unjBXMCeUZ7QR/ympjGyHITw25/B9H9QsC
120+
-----END CERTIFICATE-----`
121+
122+
const deviceResponseBase64url =
123+
'o2d2ZXJzaW9uYzEuMGlkb2N1bWVudHOBo2dkb2NUeXBldW9yZy5pc28uMTgwMTMuNS4xLm1ETGxpc3N1ZXJTaWduZWSiam5hbWVTcGFjZXOhcW9yZy5pc28uMTgwMTMuNS4xgtgYWFGkaGRpZ2VzdElEAWZyYW5kb21QnJ-3pUCHnDHOH9ioS9e08HFlbGVtZW50SWRlbnRpZmllcmpnaXZlbl9uYW1lbGVsZW1lbnRWYWx1ZWNKb27YGFhUpGhkaWdlc3RJRABmcmFuZG9tUIdrm-vaYFzySJaTmIQCWF9xZWxlbWVudElkZW50aWZpZXJrZmFtaWx5X25hbWVsZWxlbWVudFZhbHVlZVNtaXRoamlzc3VlckF1dGiEQ6EBJqEYIVkCxDCCAsAwggJnoAMCAQICFB5_GzKtTzTv5LDMB7ew4zOnCxhNMAoGCCqGSM49BAMCMHkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRwwGgYDVQQKDBNEaWdpdGFsIENyZWRlbnRpYWxzMR8wHQYDVQQDDBZkaWdpdGFsY3JlZGVudGlhbHMuZGV2MB4XDTI1MDIxOTIzMzAxOFoXDTI2MDIxOTIzMzAxOFoweTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHDAaBgNVBAoME0RpZ2l0YWwgQ3JlZGVudGlhbHMxHzAdBgNVBAMMFmRpZ2l0YWxjcmVkZW50aWFscy5kZXYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATreTYr4tfzl8NQBH2D4eNiLONVazYPamjHWLsN3Gr4bAmvml1dDZk5dhLDWieRlpjKAA_IpMABbM2ISHjYBeNpo4HMMIHJMB8GA1UdIwQYMBaAFKJP9InZfEbobqOG2UdIzsy-3M_1MB0GA1UdDgQWBBTf_mpaEunAYsS8mKcl0tlw93pgKDA0BgNVHR8ELTArMCmgJ6AlhiNodHRwczovL2RpZ2l0YWwtY3JlZGVudGlhbHMuZGV2L2NybDAqBgNVHRIEIzAhhh9odHRwczovL2RpZ2l0YWwtY3JlZGVudGlhbHMuZGV2MA4GA1UdDwEB_wQEAwIHgDAVBgNVHSUBAf8ECzAJBgcogYxdBQECMAoGCCqGSM49BAMCA0cAMEQCIGHFy_V8weN78uCxM9ofIDEEXXCbWiEUDnpoMJvLB0LnAiBwr6LhxJv7p4wVzAnlGe0Ef8pqYxshyE8NufwfR_ULAlkButgYWQG1pmd2ZXJzaW9uYzEuMG9kaWdlc3RBbGdvcml0aG1nU0hBLTI1Nmdkb2NUeXBldW9yZy5pc28uMTgwMTMuNS4xLm1ETGx2YWx1ZURpZ2VzdHOhcW9yZy5pc28uMTgwMTMuNS4xowBYIF4np1s8h5zq4R447fmweHJCW6Nd0X9qIlFVmdBckcxQAVgg5epO0W1CanUYkN3my72qMFM_NnUTmlUcXuYpkzhCK8ICWCAA5AsOZa7MqBIVYBoG7kGirGgnXgj2gW5ZN1MtEKKJvm1kZXZpY2VLZXlJbmZvoWlkZXZpY2VLZXmkAQIgASFYIITrf6TK84s7dF1jir4ZcQ3mnpOnnBLlOgI_rhbTqBfeIlgg4-d5b1QVCsUwKg3UoYLAn22ttZofjKqX6ajH0Jq7TeJsdmFsaWRpdHlJbmZvo2ZzaWduZWTAeBsyMDI1LTAyLTE5VDIzOjM2OjU4LjIxMDM5MVppdmFsaWRGcm9twHgbMjAyNS0wMi0xOVQyMzozNjo1OC4yMTAzOTlaanZhbGlkVW50aWzAeBsyMDM1LTAyLTA3VDIzOjM2OjU4LjIxMDM5OVpYQH2YP3brP6bfJDJO_FoaPUWwB5LtpYVYKChulL-3yQesOMekny68Gt-G9J3rEZMw7MUI64Y35nWJMqIF_9xB9zFsZGV2aWNlU2lnbmVkompuYW1lU3BhY2Vz2BhBoGpkZXZpY2VBdXRooW9kZXZpY2VTaWduYXR1cmWEQ6EBJqD2WEB40fYSCEZYZoYJAFRJYzez9XksFIHLwTU8b8a3vIalmOaVSFPuc_J-qzjAVrxLL1Lxq1qU0whasZmYSp337uqqZnN0YXR1cwA'
124+
125+
const chain = await X509Service.validateCertificateChain(agent.context, {
126+
certificateChain: [documentSignerCertificate],
127+
trustedCertificates: [rootCertificate],
128+
verificationDate: new Date('2025-04-04'),
129+
})
130+
expect(chain.length).toEqual(2)
131+
132+
const chainWithSignerCertificateTrusted = await X509Service.validateCertificateChain(agent.context, {
133+
certificateChain: [documentSignerCertificate],
134+
trustedCertificates: [documentSignerCertificate],
135+
verificationDate: new Date('2025-04-04'),
136+
})
137+
expect(chainWithSignerCertificateTrusted.length).toEqual(1)
138+
139+
const deviceResponse = MdocDeviceResponse.fromBase64Url(deviceResponseBase64url)
140+
141+
await deviceResponse.verify(agent.context, {
142+
trustedCertificates: [rootCertificate],
143+
now: new Date('2025-04-04'),
144+
sessionTranscriptOptions: {
145+
type: 'openId4VpDcApi',
146+
clientId: 'x509_san_dns:7f95-217-123-18-26.ngrok-free.app',
147+
origin: 'https://0663-217-123-18-26.ngrok-free.app',
148+
verifierGeneratedNonce: '121784205639044947422645',
149+
},
150+
})
151+
})
85152
})

packages/core/src/modules/x509/X509Service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ export class X509Service {
114114
// In this case we could skip the signature verification (not other verifications), as we already trust the signer certificate,
115115
// but i think the purpose of ISO 18013-5 mDL is that you trust the root certificate. If we can't verify the whole chain e.g.
116116
// when we receive a credential we have the chance it will fail later on.
117-
const skipSignatureVerification = i === 0 && trustedCertificates && cert.issuer !== cert.subject && !publicKey
117+
const skipSignatureVerification = i === 0 && trustedCertificates && !publicKey
118118
// NOTE: at some point we might want to change this to throw an error instead of skipping the signature verification of the trusted
119119
// but it would basically prevent mDOCs from unknown issuers to be verified in the wallet. Verifiers should only trust the root certificate
120120
// anyway.

0 commit comments

Comments
 (0)