rust-italia / dgc

A parser and validator for the EU Digital Green Certificate (dgc) a.k.a. greenpass

Home Page:https://github.com/rust-italia/dgc

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support kid in unprotected header

lmammino opened this issue · comments

Test file common/2DCode/raw/CO20.json fails because the KID is saved in the unprotected header rather than in the protected header of the COSE payload.

Apparently this is perfectly valid behaviour and the signature should use the KID in the unprotected header (if there is none in the protected header).

test data:

{
    "CBOR": "bf6376657265312e322e31636e616dbf62666e754d7573746572667261752d47c3b6c39f696e67657263666e74754d5553544552465241553c474f455353494e47455262676e684761627269656c6563676e74684741425249454c45ff63646f626a313939382d30322d3236617481bf62746769383430353339303036627474684c50363436342d34626e6d76526f636865204c696768744379636c6572207150435262736374323032312d30322d32305431323a33343a35365a627472693236303431353030306274637754657374696e672063656e746572205669656e6e61203162636f624154626973781b4d696e6973747279206f66204865616c74682c2041757374726961626369783155524e3a555643493a30313a41543a42353932314133354436413044363936343231423345323436323137383239372349ffff",
    "COSE": "d28440a204483248bc38d9547e630126590154a4041a6092dd20061a60903a2001624154390103a101a4617481a962736374323032312d30322d32305431323a33343a35365a627474684c50363436342d34626e6d76526f636865204c696768744379636c657220715043526274637754657374696e672063656e746572205669656e6e61203162636f624154626369783155524e3a555643493a30313a41543a42353932314133354436413044363936343231423345323436323137383239372349626973781b4d696e6973747279206f66204865616c74682c20417573747269616274676938343035333930303662747269323630343135303030636e616da463666e74754d5553544552465241553c474f455353494e47455262666e754d7573746572667261752d47c3b6c39f696e67657263676e74684741425249454c4562676e684761627269656c656376657265312e322e3163646f626a313939382d30322d323658405272eaa283596735aac167d1f8ae95253c70cbcb60c98006514ee02ca315f83a35dd2b7983b7980ecec645cef705b1913aac525034db103e2668d1c6f31e5ee8",
    "PREFIX": "HC1:NCFRY37C8OJ2500S6C+QDGTSB4J7F6T6VKOA7+4RZQY8AGTJF.R5LIE05*ICA79*5PB7UQYES-DT$D+95E:V5E5D7S8OJEG4203+AF-G8%E1LJF-A5UR2-+3GNQOYT:CFBPU5Y74-76RLFVT7UQI8DNH7KPDAT6GQJ1*7YL0AXM6.4+77%4IKDT-L5CH2H19  OCHBV96668FDO%I8UT2ITE8Y74$DC3E4H82EGBWMH-PFG64EK:UIT/ANQMGI6N0RE9EM:S/ZKV.AGO0: CW5QPHB7I2*T4434AE2BDU5$19RMVLD52PEKCN*O*2M0HI%VE3BLU3B5:8E/8GKCQA1QAD6ZG4/O4Z677HN0BFURLKKO3PGDQ1YAQCVDF7I+V:$5G 2 JQDG0YLK984QJN4C1CJERZGSZO-M2YM69-QS$M6DGMSS*1D7ZN*%M/-M1435KQ%SKJ2KWOMF%2+G1JOSVWO7OV5.I$*OBV61YP**2DK0*AJ:WHB1L-4CI%DBC5V8G/BIJ36F T2YUPEWBOKW6J2AV/8CNX5JBS1C9PCQT28+4O5GF8.RWTV/SVO$U$/V/HJ/6TZ.RLCUPLFQPT 35COVGPUTRA+1I/FP3VP DT:XQF08EFUHRVZ$2Y%I",
    "TESTCTX": {
        "VERSION": 1,
        "SCHEMA": "1.0.0",
        "CERTIFICATE": "MIIBVzCB/6ADAgECAgRzLoFUMAoGCCqGSM49BAMCMBAxDjAMBgNVBAMMBUVDLU1lMB4XDTIxMDUwMzE4MDAwMFoXDTIxMDYwMjE4MDAwMFowEDEOMAwGA1UEAwwFRUMtTWUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQkI7eQFjMDlzlZE76ey3MxeRRXqe19Gz5zI534UOGwz0uk3rC1lzMRKFjlMYqi/vEbZerv5xjysRnzhyo1P/P9o0cwRTAOBgNVHQ8BAf8EBAMCBaAwMwYDVR0lBCwwKgYMKwYBBAEAjjePZQEBBgwrBgEEAQCON49lAQIGDCsGAQQBAI43j2UBAzAKBggqhkjOPQQDAgNHADBEAiBS0ew1ZTfhrMdiOqGuSiRAe9kpg9jNZoHBICd0rAEjvQIgeFUhq00LEJHST3StBaww1NrZpEyYgh7XeC5ZK7UbRDE=",
        "VALIDATIONCLOCK": "2021-05-03T18:00:00Z",
        "DESCRIPTION": "VALID: KID in protected header correct, KID in unprotected header correct"
    },
    "EXPECTEDRESULTS": {
        "EXPECTEDVERIFY": true
    }
}

NOTE: This should be done also for alg

I had a quick stab at this one and I bumped into this other test case:

tests/data/common/2DCode/raw/CO22.json

{
    "CBOR": "bf6376657265312e322e31636e616dbf62666e754d7573746572667261752d47c3b6c39f696e67657263666e74754d5553544552465241553c474f455353494e47455262676e684761627269656c6563676e74684741425249454c45ff63646f626a313939382d30322d3236617481bf62746769383430353339303036627474684c50363436342d34626e6d76526f636865204c696768744379636c6572207150435262736374323032312d30322d32305431323a33343a35365a627472693236303431353030306274637754657374696e672063656e746572205669656e6e61203162636f624154626973781b4d696e6973747279206f66204865616c74682c2041757374726961626369783155524e3a555643493a30313a41543a42353932314133354436413044363936343231423345323436323137383239372349ffff",
    "COSE": "d28446a10443666f6fa20448f818bebd44ff0fb60126590154a4041a6092dd20061a60903a2001624154390103a101a4617481a962736374323032312d30322d32305431323a33343a35365a627474684c50363436342d34626e6d76526f636865204c696768744379636c657220715043526274637754657374696e672063656e746572205669656e6e61203162636f624154626369783155524e3a555643493a30313a41543a42353932314133354436413044363936343231423345323436323137383239372349626973781b4d696e6973747279206f66204865616c74682c20417573747269616274676938343035333930303662747269323630343135303030636e616da463666e74754d5553544552465241553c474f455353494e47455262666e754d7573746572667261752d47c3b6c39f696e67657263676e74684741425249454c4562676e684761627269656c656376657265312e322e3163646f626a313939382d30322d323658409617cd3bd816b1a1c7ecc170e7d7f36329ffc44de58d99770b525f4ce6ff72141335804df3f1ecd0c17bae2af2931ee318eb3009e19310cf36eade63a79da093",
    "PREFIX": "HC1:NCFOXNXTSQDICA7A18 92J7P7HH QFHAWU3E/UA7TCSFBXG4B86-:LTSJXNOXJ592PK7PAN9I6T5XH3E2%E3T 4A05423423ZQTW63LD3LVG+E3UA319BSMJ X48YI.FV5DJ5DJBIT+T441TOX07:4-XK3IVT1L9XIZ0BZCT3 2-N2X37 X47S4T6HN%20YCS*KNS4Y6T/20KUOQRA5RUXT2NTICZU:Z2ZW4Z*AK.GNNVR*G0C7PHBO33BC7+6BIHJLD3OF7-UJ:AJ0H3VBJMOJ423NF7ITNZIJZ735NJN332MJQPF3ZCO1B8ZVV5TN%2UP20J5/5LEBFD-48YIWFT-67-C0*E6-RI PQVW5/O16%HAT1Z%P.8GM+8:Y001HCY0R%0IGF5JNCPIGSUYI93O89N86UG8KGQN88.R: BRQG84W: BBPIGSU:%F-/C$%2DU2O3J$NNP5S29FPIQ/HLTNP8EFNC3P:HDD8B1MM1M9NTNC30GH.Z8VHL+KLF%CD 810H.+8Z1HZD5CC9T0H$/I*HSOH6OAE:%4:7R52HG4P2CPCP3LAF%1WXRMKBWT2O1RF+0J9:0BYV1ZVPP4BYD+JSQQV1RJS/0KARO*F U5TABW*MLDTNIPVDTU:BYN9G+78KOT50SDVV0",
    "TESTCTX": {
        "VERSION": 1,
        "SCHEMA": "1.0.0",
        "CERTIFICATE": "MIIBWDCB/6ADAgECAgQkAvVZMAoGCCqGSM49BAMCMBAxDjAMBgNVBAMMBUVDLU1lMB4XDTIxMDUwMzE4MDAwMFoXDTIxMDYwMjE4MDAwMFowEDEOMAwGA1UEAwwFRUMtTWUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATBI2PXG75hBJ/waeZPXCStOm1AB5VTB2rsKEz7kgrlYNWgJqV9LJzVB+moIrGZqmhmcWXGXzc+YwWb4TBNk7reo0cwRTAOBgNVHQ8BAf8EBAMCBaAwMwYDVR0lBCwwKgYMKwYBBAEAjjePZQEBBgwrBgEEAQCON49lAQIGDCsGAQQBAI43j2UBAzAKBggqhkjOPQQDAgNIADBFAiEAv7k643O/MebICElvO9Ke2Q/ECEvuoyZ6G2qfexoWnUkCIBUzkfOv8LyYaB/bBQwISRUo9aFotPeaULaLbO6wX1sF",
        "VALIDATIONCLOCK": "2021-05-03T18:00:00Z",
        "DESCRIPTION": "INVALID: KID in protected header not correct, KID in unprotected header correct"
    },
    "EXPECTEDRESULTS": {
        "EXPECTEDVERIFY": false
    }
}

Note the DESCRIPTION:

INVALID: KID in protected header not correct, KID in unprotected header correct

And the EXPECTEDVERIFY (false).

In my initial draft implementation i was overriding the kid from the protected header, with the kid in the unprotected header.

I guess this logic should be reversed....

I also realised that this last case is a bit hard to test. There is no explicit KID in the test data, so the current implementation assigned to the test public key certificate is the one found in the CWT header.

I found this interesting comment:

[...] The kid is defined as the first 8 bytes of the SHA256 hash of the certificate.

This should allow us to pre-compute the test KID and this way we don't have to guess what that is. This way we should be in a position to test against invalid KIDs.