Skip to content

EU fork integration #9

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

Merged
merged 37 commits into from
Mar 18, 2025
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
39ab4fe
preprod version
LuisPereira23 Jul 1, 2024
b8f3bfe
Merge pull request #1 from niscy-eudiw/branch-preprod
LuisPereira23 Jul 1, 2024
ce8e898
initial update for revocation status lists
LuisPereira23 Oct 14, 2024
335c251
Merge pull request #1 from niscy-eudiw/branch-development
LuisPereira23 Jan 22, 2025
17723ee
Merge pull request #2 from niscy-eudiw/branch-preprod
LuisPereira23 Jan 22, 2025
963cc84
update status struct
LuisPereira23 Jan 23, 2025
142d556
add new attestations dc4eu support test
LuisPereira23 Jan 23, 2025
4e12bcf
update dict and list encode tag
LuisPereira23 Jan 28, 2025
fe83479
update PID 1.5 nationality
LuisPereira23 Feb 20, 2025
993a456
Merge pull request #2 from niscy-eudiw/branch-development
LuisPereira23 Mar 5, 2025
d46a5f7
Merge pull request #3 from niscy-eudiw/branch-preprod
LuisPereira23 Mar 5, 2025
c613407
fix: ci restore
PascalDR Mar 13, 2025
670bd33
fix: restore code
PascalDR Mar 13, 2025
8a37f52
tests: adapted tests
PascalDR Mar 13, 2025
86e7f7c
fix: install
PascalDR Mar 13, 2025
f2149e6
fix: try ubuntu 22
PascalDR Mar 13, 2025
c768740
fix: dependency
PascalDR Mar 13, 2025
6439edb
fix: typo
PascalDR Mar 13, 2025
db5b9c9
fix: updated python versions
PascalDR Mar 13, 2025
3104d19
Update pymdoccbor/mdoc/issuer.py
PascalDR Mar 14, 2025
8f10944
fix: private key handling
PascalDR Mar 14, 2025
bd2d133
fix: version
PascalDR Mar 14, 2025
719e3bf
fix: private key handling
PascalDR Mar 14, 2025
750f7b2
fix: readme
PascalDR Mar 14, 2025
07f692a
fix: readme
PascalDR Mar 14, 2025
4aff49a
fix: readme
PascalDR Mar 14, 2025
7694fe9
fix: readme
PascalDR Mar 14, 2025
4f17a86
fix: restored example
PascalDR Mar 14, 2025
c089290
fix: restored docstring and typing
PascalDR Mar 14, 2025
e661611
fix: error handling
PascalDR Mar 14, 2025
23e41c2
tests: restored tests
PascalDR Mar 14, 2025
6a432df
fix: restored specialized exceptions
PascalDR Mar 14, 2025
7e4737f
Update README.md
PascalDR Mar 17, 2025
58985b6
Apply suggestions from code review
peppelinux Mar 18, 2025
cffd8a0
Merge branch 'main' into fix/eu_integration
peppelinux Mar 18, 2025
1827086
Apply suggestions from code review
peppelinux Mar 18, 2025
8d3d2be
Apply suggestions from code review
peppelinux Mar 18, 2025
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
7 changes: 4 additions & 3 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ on:
jobs:
build:

runs-on: ubuntu-latest
runs-on: ubuntu-22.04

strategy:
fail-fast: false
matrix:
python-version:
- '3.10'
- '3.11'
- "3.11"
- "3.12"

steps:
- uses: actions/checkout@v2
Expand All @@ -30,7 +31,7 @@ jobs:
- name: Install system package
run: |
sudo apt update
sudo apt install python3-dev libssl-dev make automake gcc g++
sudo apt install python3-dev libssl-dev libffi-dev make automake gcc g++
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
110 changes: 72 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ Python parser and writer for EUDI Wallet MDOC CBOR for credential Type 1 and als
- [ISO 18013-5 - ISO-compliant driving licence — Mobile driving licence (mDL) application](https://www.iso.org/standard/69084.html)
- [RFC 8949 - Concise Binary Object Representation (CBOR)](https://datatracker.ietf.org/doc/html/rfc8949)
- [RFC 9052 - CBOR Object Signing and Encryption (COSE): Structures and Process](https://www.rfc-editor.org/rfc/rfc9052.html)
- deprecates [RFC 8152 - CBOR Object Signing and Encryption (COSE)](https://datatracker.ietf.org/doc/html/rfc8152)
- deprecates [RFC 8152 - CBOR Object Signing and Encryption (COSE)](https://datatracker.ietf.org/doc/html/rfc8152)
- [IANA Registry - Concise Binary Object Representation (CBOR) Tags](https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml)

COSE label 33 (x5chain) in MSO:

- [RFC 9360 CBOR Object Signing and Encryption (COSE) - Header Parameters for Carrying and Referencing X.509 Certificates](https://www.rfc-editor.org/rfc/rfc9360.html)

## Scope
## Scope

pyMDOC-CBOR is a
[cbor2](https://github.com/agronholm/cbor2)
and
[pycose](https://github.com/TimothyClaeys/pycose)
wrapper that parses, creates and validates MDOC CBOR encoded binaries
pyMDOC-CBOR is a
[cbor2](https://github.com/agronholm/cbor2)
and
[pycose](https://github.com/TimothyClaeys/pycose)
wrapper that parses, creates and validates MDOC CBOR encoded binaries
according to ISO 18013-5.

## Setup
Expand All @@ -39,14 +39,41 @@ pip install git+https://github.com/peppelinux/pyMDOC-CBOR.git

## Usage

### Issue an MDOC CBOR signed with HSM key

````
PID_DATA = {
"eu.europa.ec.eudiw.pid.1": {
"family_name": "Raffaello",
"given_name": "Mascetti",
"birth_date": "1922-03-13"
}
}

mdoci = MdocCborIssuer(
alg = 'ES256',
kid = "demo-kid",
hsm=True,
key_label="p256-1",
user_pin="1234",
lib_path="/etc/utimaco/libcs2_pkcs11.so",
slot_id=3
)

mdoc = mdoci.new(
doctype="eu.europa.ec.eudiw.pid.1",
data=PID_DATA,
cert_path="app/keys/IACAmDLRoot01.der" # DS certificate
)

````

### Issue an MDOC CBOR

`MdocCborIssuer` must be initialized with a private key.
The method `.new()` gets the user attributes, devicekeyinfo and doctype.

````
import os

from pymdoccbor.mdoc.issuer import MdocCborIssuer

PKEY = {
Expand All @@ -58,17 +85,14 @@ PKEY = {
}

PID_DATA = {
"eu.europa.ec.eudiw.pid.1": {
"family_name": "Raffaello",
"given_name": "Mascetti",
"birth_date": "1922-03-13",
"birth_place": "Rome",
"birth_country": "IT"
},
"eu.europa.ec.eudiw.pid.it.1": {
"tax_id_code": "TINIT-XXXXXXXXXXXXXXX"
"eu.europa.ec.eudiw.pid.1": {
"family_name": "Raffaello",
"given_name": "Mascetti",
"birth_date": "1922-03-13",
"birth_place": "Rome",
"birth_country": "IT"
}
}
}

mdoci = MdocCborIssuer(
private_key=PKEY
Expand All @@ -78,16 +102,20 @@ mdoc = mdoci.new(
doctype="eu.europa.ec.eudiw.pid.1",
data=PID_DATA,
devicekeyinfo=PKEY # TODO
cert_path="/path/"
)

mdoc
>> returns a python dictionay

mdoc.dump()
>> returns mdoc MSO bytes

mdoci.dump()
>> returns mdoc bytes

mdoci.dumps()
>> returns AF Binary string representation
>> returns AF Binary mdoc string representation
````

### Issue an MSO alone
Expand All @@ -96,7 +124,7 @@ MsoIssuer is a class that handles private keys, data processing, digests and sig

The `disclosure_map` is used in the Mdoc `nameSpaces` object for issuance and presentations,
it's carried in the mdoc but outside of the MSO, even if it is produced by `MsoIssuer`.
that's why `MsoIssuer.sign()` returns a pure MSO, while `disclosure_map`
that's why `MsoIssuer.sign()` returns a pure MSO, while `disclosure_map`
is an attribute of the `MsoIssuer` instance.

````
Expand Down Expand Up @@ -124,15 +152,16 @@ mso = msoi.sign()
````

API usage:
- `msoi.data`, user attributes to be encoded
- `msoi.private_key`, COSEKey
- `msoi.public_key`, COSEKey without `d` (for EC2Key)
- `msoi.selfsigned_x509cert`, using the private and the public keys returns a self-signed x509 certificate
- `msoi.hash_map`, digests that will be signed in the MSO
- `msoi.disclosure_map`, disclosure objects grouped by namespaces
- `msoi.sign`, signs the MSO and returns it

### Parse a binary Mdoc
- `msoi.data`, user attributes to be encoded
- `msoi.private_key`, COSEKey
- `msoi.public_key`, COSEKey without `d` (for EC2Key)
- `msoi.selfsigned_x509cert`, using the private and the public keys returns a self-signed x509 certificate
- `msoi.hash_map`, digests that will be signed in the MSO
- `msoi.disclosure_map`, disclosure objects grouped by namespaces
- `msoi.sign`, signs the MSO and returns it

### Parse a binary Mdoc

````
from pymdoccbor.mdoc.verifier import MdocCbor
Expand Down Expand Up @@ -166,13 +195,14 @@ msop.verify_signature()
````

API usage:
- `msop.payload_as_dict`: returns the MSO as Python dictionary.
- `msop.payload_as_raw`: returns the MSO as bytes in its original format.
- `msop.payload_as_cbor`: returns the MSO as CBOR encoded object.
- `msop.object`: returns a pycose COSE_Sign1 object.
- `msop.raw_public_keys`: returns the list of the public keys from the unprotected COSE header
- `msop.public_key`: returns `cryptography.hazmat` key.
- `msop.x509_certificates`: returns a list of `cryptography.x509` certificate objects

- `msop.payload_as_dict`: returns the MSO as Python dictionary.
- `msop.payload_as_raw`: returns the MSO as bytes in its original format.
- `msop.payload_as_cbor`: returns the MSO as CBOR encoded object.
- `msop.object`: returns a pycose COSE_Sign1 object.
- `msop.raw_public_keys`: returns the list of the public keys from the unprotected COSE header
- `msop.public_key`: returns `cryptography.hazmat` key.
- `msop.x509_certificates`: returns a list of `cryptography.x509` certificate objects

## Tests

Expand All @@ -184,6 +214,7 @@ pytest --cov-report term-missing --cov-report term:skip-covered --cov
## Other examples

Quick preview in bash using AF binary

````
# D.4.1.2 mdoc response
export ISSUED_MDOC="a36776657273696f6e63312e3069646f63756d656e747381a367646f6354797065756f72672e69736f2e31383031332e352e312e6d444c6c6973737565725369676e6564a26a6e616d65537061636573a1716f72672e69736f2e31383031332e352e3186d8185863a4686469676573744944006672616e646f6d58208798645b20ea200e19ffabac92624bee6aec63aceedecfb1b80077d22bfc20e971656c656d656e744964656e7469666965726b66616d696c795f6e616d656c656c656d656e7456616c756563446f65d818586ca4686469676573744944036672616e646f6d5820b23f627e8999c706df0c0a4ed98ad74af988af619b4bb078b89058553f44615d71656c656d656e744964656e7469666965726a69737375655f646174656c656c656d656e7456616c7565d903ec6a323031392d31302d3230d818586da4686469676573744944046672616e646f6d5820c7ffa307e5de921e67ba5878094787e8807ac8e7b5b3932d2ce80f00f3e9abaf71656c656d656e744964656e7469666965726b6578706972795f646174656c656c656d656e7456616c7565d903ec6a323032342d31302d3230d818586da4686469676573744944076672616e646f6d582026052a42e5880557a806c1459af3fb7eb505d3781566329d0b604b845b5f9e6871656c656d656e744964656e7469666965726f646f63756d656e745f6e756d6265726c656c656d656e7456616c756569313233343536373839d818590471a4686469676573744944086672616e646f6d5820d094dad764a2eb9deb5210e9d899643efbd1d069cc311d3295516ca0b024412d71656c656d656e744964656e74696669657268706f7274726169746c656c656d656e7456616c7565590412ffd8ffe000104a46494600010101009000900000ffdb004300130d0e110e0c13110f11151413171d301f1d1a1a1d3a2a2c2330453d4947443d43414c566d5d4c51685241435f82606871757b7c7b4a5c869085778f6d787b76ffdb0043011415151d191d381f1f38764f434f7676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676ffc00011080018006403012200021101031101ffc4001b00000301000301000000000000000000000005060401020307ffc400321000010303030205020309000000000000010203040005110612211331141551617122410781a1163542527391b2c1f1ffc4001501010100000000000000000000000000000001ffc4001a110101010003010000000000000000000000014111213161ffda000c03010002110311003f00a5bbde22da2329c7d692bc7d0d03f52cfb0ff75e7a7ef3e7709723a1d0dae146ddfbb3c039ce07ad2bd47a7e32dbb8dd1d52d6ef4b284f64a480067dfb51f87ffb95ff00eb9ff14d215de66af089ce44b7dbde9cb6890a2838eddf18078f7add62d411ef4db9b10a65d6b95a147381ea0d495b933275fe6bba75c114104a8ba410413e983dff004f5af5d34b4b4cde632d0bf1fd1592bdd91c6411f3934c2fa6af6b54975d106dcf4a65ae56e856001ebc03c7ce29dd9eef1ef10fc447dc9da76ad2aee93537a1ba7e4f70dd8eff0057c6dffb5e1a19854a83758e54528750946ec6704850cd037bceb08b6d7d2cc76d3317fc7b5cc04fb6707269c5c6e0c5b60ae549242123b0e493f602a075559e359970d98db89525456b51c951c8afa13ea8e98e3c596836783d5c63f5a61a99fdb7290875db4be88ab384bbbbbfc7183fdeaa633e8951db7da396dc48524fb1a8bd611a5aa2a2432f30ab420a7a6d3240c718cf031fa9ef4c9ad550205aa02951df4a1d6c8421b015b769db8c9229837ea2be8b1b0d39d0eba9c51484efdb8c0efd8d258daf3c449699f2edbd4584e7af9c64e3f96b9beb28d4ac40931e6478c8e76a24a825449501d867d2b1dcdebae99b9c752ae4ecd6dde4a179c1c1e460938f9149ef655e515c03919a289cb3dca278fb7bf177f4faa829dd8ce3f2ac9a7ecde490971fafd7dce15eed9b71c018c64fa514514b24e8e4f8c5c9b75c1e82579dc1233dfec08238f6add62d391acc1c5256a79e706d52d431c7a0145140b9fd149eb3a60dc5e88cbbc2da092411e9dc71f39a7766b447b344e847dcac9dcb5abba8d145061d43a6fcf1e65cf15d0e90231d3dd9cfe62995c6dcc5ca12a2c904a15f71dd27d451453e09d1a21450961cbb3ea8a956433b781f1ce33dfed54f0e2b50a2b71d84ed6db18028a28175f74fc6bda105c529a791c25c4f3c7a11f71586268f4a66b726e33de9ea6f1b52b181c760724e47b514520a5a28a283ffd9d81858ffa4686469676573744944096672616e646f6d58204599f81beaa2b20bd0ffcc9aa03a6f985befab3f6beaffa41e6354cdb2ab2ce471656c656d656e744964656e7469666965727264726976696e675f70726976696c656765736c656c656d656e7456616c756582a37576656869636c655f63617465676f72795f636f646561416a69737375655f64617465d903ec6a323031382d30382d30396b6578706972795f64617465d903ec6a323032342d31302d3230a37576656869636c655f63617465676f72795f636f646561426a69737375655f64617465d903ec6a323031372d30322d32336b6578706972795f64617465d903ec6a323032342d31302d32306a697373756572417574688443a10126a118215901d2308201ce30820174a003020102021401ec51916031e6898e8fc7864af5e6d5f86602b6300a06082a8648ce3d04030230233114301206035504030c0b75746f7069612069616361310b3009060355040613025553301e170d3230313030313030303030305a170d3231313030313030303030305a30213112301006035504030c0975746f706961206473310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d03010703420004ace7ab7340e5d9648c5a72a9a6f56745c7aad436a03a43efea77b5fa7b88f0197d57d8983e1b37d3a539f4d588365e38cbbf5b94d68c547b5bc8731dcd2f146ba38187308184301e0603551d120417301581136578616d706c65406578616d706c652e636f6d301c0603551d1f041530133011a00fa00d820b6578616d706c652e636f6d301d0603551d0e0416041414e29017a6c35621ffc7a686b7b72db06cd12351300e0603551d0f0101ff04040302078030150603551d250101ff040b3009060728818c5d050102300a06082a8648ce3d0403020348003045022100bac6f93a8bacf0fc9aeac1c89a5c9293af2076942e9e972882a113640330702702207b7b73c0444371a4c94c9c888ddfe553ffde84ca492fd64dfbf02ad46a31cbc85903a2d81859039da66776657273696f6e63312e306f646967657374416c676f726974686d675348412d3235366c76616c756544696765737473a2716f72672e69736f2e31383031332e352e31ad00582075167333b47b6c2bfb86eccc1f438cf57af055371ac55e1e359e20f254adcebf01582067e539d6139ebd131aef441b445645dd831b2b375b390ca5ef6279b205ed45710258203394372ddb78053f36d5d869780e61eda313d44a392092ad8e0527a2fbfe55ae0358202e35ad3c4e514bb67b1a9db51ce74e4cb9b7146e41ac52dac9ce86b8613db555045820ea5c3304bb7c4a8dcb51c4c13b65264f845541341342093cca786e058fac2d59055820fae487f68b7a0e87a749774e56e9e1dc3a8ec7b77e490d21f0e1d3475661aa1d0658207d83e507ae77db815de4d803b88555d0511d894c897439f5774056416a1c7533075820f0549a145f1cf75cbeeffa881d4857dd438d627cf32174b1731c4c38e12ca936085820b68c8afcb2aaf7c581411d2877def155be2eb121a42bc9ba5b7312377e068f660958200b3587d1dd0c2a07a35bfb120d99a0abfb5df56865bb7fa15cc8b56a66df6e0c0a5820c98a170cf36e11abb724e98a75a5343dfa2b6ed3df2ecfbb8ef2ee55dd41c8810b5820b57dd036782f7b14c6a30faaaae6ccd5054ce88bdfa51a016ba75eda1edea9480c5820651f8736b18480fe252a03224ea087b5d10ca5485146c67c74ac4ec3112d4c3a746f72672e69736f2e31383031332e352e312e5553a4005820d80b83d25173c484c5640610ff1a31c949c1d934bf4cf7f18d5223b15dd4f21c0158204d80e1e2e4fb246d97895427ce7000bb59bb24c8cd003ecf94bf35bbd2917e340258208b331f3b685bca372e85351a25c9484ab7afcdf0d2233105511f778d98c2f544035820c343af1bd1690715439161aba73702c474abf992b20c9fb55c36a336ebe01a876d6465766963654b6579496e666fa1696465766963654b6579a40102200121582096313d6c63e24e3372742bfdb1a33ba2c897dcd68ab8c753e4fbd48dca6b7f9a2258201fb3269edd418857de1b39a4e4a44b92fa484caa722c228288f01d0c03a2c3d667646f6354797065756f72672e69736f2e31383031332e352e312e6d444c6c76616c6964697479496e666fa3667369676e6564c074323032302d31302d30315431333a33303a30325a6976616c696446726f6dc074323032302d31302d30315431333a33303a30325a6a76616c6964556e74696cc074323032312d31302d30315431333a33303a30325a5840cff12c17d4739aba806035a9cb2b34ae8a830cef4f329289f9a3ebd302dd6b99c584068257569397b92ba9aa5128554eb05d1273dafea313da4aff6b01a5fb3f6c6465766963655369676e6564a26a6e616d65537061636573d81841a06a64657669636541757468a1696465766963654d61638443a10105a0f65820200d73ded787c64652dc8ee743ea83a5260d5a3283fddc919b7b9cfb486addb26673746174757300"
Expand All @@ -194,11 +225,13 @@ echo $ISSUED_MDOC | xxd -r -ps | python3 -m cbor2.tool --pretty
### using cbor-diag

Install cbor-diag

````
pip install cbor-diag
````

Print a cbor diagnostic representation

````
from cbor_diag import *

Expand All @@ -213,7 +246,7 @@ Other examples at [cbor official documentation](https://github.com/agronholm/cbo
#### CBOR Diagnostic representation

- [CBOR-DIAG-PY](https://github.com/chrysn/cbor-diag-py)
- [Authlete's CBOR diagnostic tools](https://nextdev-api.authlete.net/api/cbor)
- [Authlete's CBOR diagnostic tools](https://nextdev-api.authlete.net/api/cbor)
- [Auth0 CBOR diagnostic tool](https://www.mdl.me/)

#### X.509 certificates and chains
Expand All @@ -222,4 +255,5 @@ Other examples at [cbor official documentation](https://github.com/agronholm/cbo

## Authors and contributors

- Giuseppe De Marco
- Giuseppe De Marco
- Pasquale De Rose
10 changes: 7 additions & 3 deletions examples/it_data_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,19 @@
}

mdoci = MdocCborIssuer(
private_key=PKEY
private_key=PKEY,
alg="ES256",
)

mdoc = mdoci.new(
doctype="org.iso.18013.5.1.mDL",
data=PID_DATA,
devicekeyinfo=PKEY # TODO
validity={
"issuance_date": "2024-12-31",
"expiry_date": "2050-12-31"
},
)

mdoc
mdoci.dump()
mdoci.dumps()
mdoci.dumps()
2 changes: 1 addition & 1 deletion pymdoccbor/mdoc/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ class NoSignedDocumentProvided(Exception):
pass

class MissingIssuerAuth(Exception):
pass
pass
Loading