-
Notifications
You must be signed in to change notification settings - Fork 0
feat: [SIW-2740] Add verify and parse mdoc #265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…upgrade io-react-native-crypto
Co-authored-by: grausof <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work 🎉
src/mdoc/index.ts
Outdated
/** | ||
* This function verifies that the signature is valid for all certificates in the x5c chain. | ||
* If not, it throws an error | ||
* | ||
* @param issuerSigned The decoded mdoc | ||
*/ | ||
const verifySignatures = async (issuerSigned: CBOR.IssuerSigned) => { | ||
await Promise.all( | ||
issuerSigned.issuerAuth.unprotectedHeader.x5chain!.map(async (cert) => { | ||
const pemcert = convertBase64DerToPem(b64utob64(cert)); | ||
const jwk = getSigninJwkFromCert(pemcert); | ||
|
||
jwk.x = b64utob64(jwk.x!); | ||
jwk.y = b64utob64(jwk.y!); | ||
|
||
console.info(b64utob64(issuerSigned.issuerAuth.rawValue!)); | ||
|
||
const signatureCorrect = await COSE.verify( | ||
b64utob64(issuerSigned.issuerAuth.rawValue!), | ||
jwk as PublicKey | ||
).catch((e: any) => console.error(e)); | ||
|
||
if (!signatureCorrect) throw new Error("Invalid mDoc signature"); | ||
}) | ||
); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The credential is signed only with the public key of the leaf certificate in the chain. Here, we're iterating through all the certificates, verifying the signature with all the public keys (this probably works now because there's only one certificate in the chain). My suggestion is to have a function that verifies the signature, like verifyMdocSignature(token, publicKey), and pass the public key from the caller, which in the example can be retrieved from the leaf certificate (usually the first in the X5c array).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I applied your suggestion! It’s actually working now because there’s only one certificate in the chain.
Let me know if it's ok now
src/utils/crypto.ts
Outdated
* This function takes two {@link PublicKey} and evaluates and compares their thumbprints | ||
* @param key1 The first key | ||
* @param key2 The second key | ||
* @returns true if the keys' thumbprints are equal, false otherwise | ||
*/ | ||
export const compareKeysByThumbprint = async ( | ||
key1: PublicKey, | ||
key2: PublicKey | ||
) => { | ||
//Parallel for optimization | ||
const [thumbprint1, thumbprint2] = await Promise.all([ | ||
thumbprint(key1), | ||
thumbprint(key2), | ||
]); | ||
return thumbprint1 === thumbprint2; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You already have isSameThumbprint
from utils/jwks.ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I hadn't noticed there was already a function for that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed here
const key = | ||
decodedCredential.issuerSigned.issuerAuth.payload.deviceKeyInfo.deviceKey; | ||
|
||
if (!isSameThumbprint(key, holderBindingKey as PublicKey)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (!isSameThumbprint(key, holderBindingKey as PublicKey)) { | |
if (!(await isSameThumbprint(key, holderBindingKey as PublicKey))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! Thank you!
List of Changes
@pagopa/io-react-native-iso18013
andjsrsasign
packages@pagopa/io-react-native-crypto
packageformat
type returned byobtainCredential
to a union of string literals (dc+sd-jwt
andmso_mdoc
)x5chain
verification and the signature validation for the credentials inmdoc
formatmdoc
format, preserving the namespace while keeping the structure ofParsedCredential
unchanged compared to thedc+sd-jwt
formatMotivation and Context
This PR adds support for credentials in
mdoc
format, integrating the verification and parsing mechanisms for the credentialHow to test it?
From the example app, once you have obtained what is needed to request credentials, request the MDL in
mdoc
format.The credential verification must succeed (using a proxy tool, verify that after the
/credential
call, the/pki/ta-sub.crl
endpoint is also called).Once the credential has been obtained, using the debug interface available in the app, make sure that the structure of the
parsedCredential
matches the example below:Note
The test can be performed in both the PRE and PROD environments.
Demo:
PRE_mdl_mdoc.mov
PROD_mdl_mdoc.mov
Checklist: