-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #315 from LadyCodesItBetter/pas_merge
Pas merge
- Loading branch information
Showing
94 changed files
with
4,399 additions
and
1,858 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,12 +5,11 @@ name: pyeudiw | |
|
||
on: | ||
push: | ||
branches: [ "*" ] | ||
branches: ["*"] | ||
pull_request: | ||
branches: [ "*" ] | ||
branches: ["*"] | ||
|
||
jobs: | ||
|
||
pre_job: | ||
runs-on: ubuntu-latest | ||
outputs: | ||
|
@@ -19,11 +18,10 @@ jobs: | |
- id: skip_check | ||
uses: fkirc/[email protected] | ||
with: | ||
skip_after_successful_duplicate: 'true' | ||
same_content_newer: 'true' | ||
skip_after_successful_duplicate: "true" | ||
same_content_newer: "true" | ||
|
||
main_job: | ||
|
||
needs: pre_job | ||
if: needs.pre_job.outputs.should_skip != 'true' | ||
|
||
|
@@ -33,72 +31,70 @@ jobs: | |
fail-fast: false | ||
matrix: | ||
python-version: | ||
- '3.10' | ||
- '3.11' | ||
- '3.12' | ||
- "3.10" | ||
- "3.11" | ||
- "3.12" | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- name: Install system package | ||
run: | | ||
sudo apt update | ||
sudo apt install python3-dev python3-pip | ||
- name: Install MongoDB | ||
run: | | ||
sudo apt-get install -y gnupg wget | ||
sudo wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add - | ||
sudo echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list | ||
sudo apt-get update | ||
sudo apt-get install -y mongodb-org | ||
- name: Start MongoDB | ||
run: sudo systemctl start mongod | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
if [ -f requirements-dev.txt ]; then pip install -r requirements-dev.txt; fi | ||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi | ||
if [ -f requirements-customizations.txt ]; then pip install -r requirements-customizations.txt; fi | ||
python -m pip install -U setuptools | ||
python -m pip install -e . | ||
python -m pip install "Pillow>=10.0.0,<10.1" "device_detector>=5.0,<6" "satosa>=8.4,<8.6" "jinja2>=3.0,<4" "pymongo>=4.4.1,<4.5" aiohttp | ||
python -m pip install git+https://github.com/openwallet-foundation-labs/sd-jwt-python.git | ||
python -m pip install git+https://github.com/peppelinux/pyMDOC-CBOR.git | ||
- uses: actions/checkout@v2 | ||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- name: Install system package | ||
run: | | ||
sudo apt update | ||
sudo apt install python3-dev python3-pip | ||
- name: Install MongoDB | ||
run: | | ||
sudo apt-get install -y gnupg curl | ||
sudo curl -fsSL https://pgp.mongodb.com/server-7.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor | ||
sudo echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list | ||
sudo apt-get update | ||
sudo apt-get install -y mongodb-org | ||
- name: Start MongoDB | ||
run: sudo systemctl start mongod | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
if [ -f requirements-dev.txt ]; then pip install -r requirements-dev.txt; fi | ||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi | ||
if [ -f requirements-customizations.txt ]; then pip install -r requirements-customizations.txt; fi | ||
python -m pip install -U setuptools | ||
python -m pip install -e . | ||
python -m pip install "Pillow>=10.0.0,<10.1" "device_detector>=5.0,<6" "satosa>=8.4,<8.6" "jinja2>=3.0,<4" "pymongo>=4.4.1,<4.5" aiohttp | ||
python -m pip install git+https://github.com/peppelinux/pyMDOC-CBOR.git | ||
- name: Lint with flake8 | ||
run: | | ||
# stop the build if there are Python syntax errors or undefined names | ||
flake8 pyeudiw --count --select=E9,F63,F7,F82 --show-source --statistics | ||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide | ||
flake8 pyeudiw --count --exit-zero --statistics --max-line-length 160 | ||
- name: Tests | ||
run: | | ||
# pytest --cov=pyeudiw --cov-fail-under=90 pyeudiw | ||
pytest --cov=pyeudiw pyeudiw | ||
coverage report -m --skip-covered | ||
- name: Bandit Security Scan | ||
run: | | ||
bandit -r -x pyeudiw/tests* pyeudiw/* | ||
- name: Lint with html linter | ||
run: | | ||
echo -e '\nHTML:' | ||
readarray -d '' array < <(find $SRC example -name "*.html" -print0) | ||
echo "Running linter on (${#array[@]}): " | ||
printf '\t- %s\n' "${array[@]}" | ||
echo "Linter output:" | ||
- name: Lint with flake8 | ||
run: | | ||
# stop the build if there are Python syntax errors or undefined names | ||
flake8 pyeudiw --count --select=E9,F63,F7,F82 --show-source --statistics | ||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide | ||
flake8 pyeudiw --count --exit-zero --statistics --max-line-length 160 | ||
- name: Tests | ||
run: | | ||
# pytest --cov=pyeudiw --cov-fail-under=90 pyeudiw | ||
pytest --cov=pyeudiw pyeudiw | ||
coverage report -m --skip-covered | ||
- name: Bandit Security Scan | ||
run: | | ||
bandit -r -x pyeudiw/tests* pyeudiw/* | ||
- name: Lint with html linter | ||
run: | | ||
echo -e '\nHTML:' | ||
readarray -d '' array < <(find $SRC example -name "*.html" -print0) | ||
echo "Running linter on (${#array[@]}): " | ||
printf '\t- %s\n' "${array[@]}" | ||
echo "Linter output:" | ||
for file in "${array[@]}" | ||
do | ||
echo -e "\n$file:" | ||
html_lint.py "$file" | awk -v path="file://$PWD/$file:" '$0=path$0' | sed -e 's/: /:\n\t/'; | ||
done | ||
for file in "${array[@]}" | ||
do | ||
echo -e "\n$file:" | ||
html_lint.py "$file" | awk -v path="file://$PWD/$file:" '$0=path$0' | sed -e 's/: /:\n\t/'; | ||
done | ||
# block if the html linter fails | ||
#for file in "${array[@]}" | ||
#do | ||
#errors=$(html_lint.py "$file" | grep -c 'Error') | ||
#if [ "$errors" -gt 0 ]; then exit 1; fi; | ||
#done | ||
# block if the html linter fails | ||
#for file in "${array[@]}" | ||
#do | ||
#errors=$(html_lint.py "$file" | grep -c 'Error') | ||
#if [ "$errors" -gt 0 ]; then exit 1; fi; | ||
#done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -169,4 +169,8 @@ env | |
|
||
.DS_Store | ||
|
||
docs/source | ||
docs/source | ||
|
||
# VSCode | ||
# VSCode specific settings | ||
.vscode/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
# sd-jwt-python Fork with cryptojwt | ||
|
||
## Introduction | ||
|
||
This module is a fork of [sd-jwt-python](https://github.com/openwallet-foundation-labs/sd-jwt-python) project. It has been adapted to use the [`cryptojwt`](https://github.com/IdentityPython/JWTConnect-Python-CryptoJWT) library as the core JWT implementation. | ||
|
||
|
||
If you're familiar with the original `sd-jwt-python` library, this fork retains similar functionality with minimal API changes, if needed. | ||
|
||
--- | ||
|
||
## Features | ||
|
||
- **SD-JWT Support**: Implements the Selective Disclosure JWT standard. | ||
- **`cryptojwt` Integration**: Leverages a mature and feature-rich library for JWT operations. | ||
- **Backward Compatibility**: Minimal changes required for existing users of `sd-jwt-python`. | ||
- **Improved Flexibility**: Extensible for custom SD-JWT use cases. | ||
|
||
--- | ||
|
||
# SD-JWT Library Usage Documentation | ||
|
||
## Introduction | ||
|
||
This library provides an implementation of the SD-JWT (Selective Disclosure for JWT) standard. This document explains how to create and verify a Selected-Disclosure JWT (SD-JWT) using the EUDI Wallet IT Python library. It also covers how to validate proof of possession enabling three key operations: | ||
1. **Issuer**: Generate an SD-JWT with selective disclosure capabilities. | ||
2. **Holder**: Select claims to disclose and create a presentation. | ||
3. **Verifier**: Validate the SD-JWT and verify the disclosed claims. | ||
|
||
### Requirements | ||
- Python version as configured in the CI of this project. | ||
- Install the library via `pip`: | ||
```bash | ||
pip install pyeudiw | ||
``` | ||
|
||
- **Key Requirements**: | ||
- All keys must be in JWK (JSON Web Key) format, conforming to [RFC 7517](https://datatracker.ietf.org/doc/html/rfc7517). | ||
- You can use a library like `cryptojwt` to generate or manage JWKs. Example: | ||
|
||
```bash | ||
from cryptojwt.jwk.ec import new_ec_key | ||
|
||
# Generate an EC key pair | ||
issuer_private_key = new_ec_key('P-256') | ||
|
||
# Serialize the keys | ||
issuer_keys = [issuer_private_key.serialize(private=True)] # List of private keys | ||
public_key = issuer_private_key.serialize() # Public key | ||
``` | ||
--- | ||
|
||
## 1. Issuer: Generating an SD-JWT | ||
|
||
The Issuer creates an SD-JWT using the user's claims (`user_claims`) and a private key in JWK format to sign the token. | ||
|
||
### Example | ||
|
||
```bash | ||
from pyeudiw.sd_jwt.issuer import SDJWTIssuer | ||
|
||
# User claims | ||
user_claims = { | ||
"sub": "john_doe_42", | ||
"given_name": "John", | ||
"family_name": "Doe", | ||
"email": "[email protected]", | ||
} | ||
|
||
# Generate private keys | ||
issuer_private_key = new_ec_key('P-256') | ||
issuer_keys = [issuer_private_key.serialize(private=True)] # List of private JWKs | ||
holder_key = new_ec_key('P-256').serialize(private=True) # Holder private key (optional) | ||
|
||
# Create SD-JWT | ||
sdjwt_issuer = SDJWTIssuer( | ||
user_claims=user_claims, | ||
issuer_keys=issuer_keys, # List of private JWKs | ||
holder_key=holder_key, # Holder key (optional) | ||
add_decoy_claims=True, # Add decoy claims for privacy | ||
serialization_format="compact" # Compact JWS format | ||
) | ||
|
||
# Output SD-JWT and disclosures | ||
print("SD-JWT Issuance:", sdjwt_issuer.sd_jwt_issuance) | ||
``` | ||
|
||
--- | ||
|
||
## 2. Holder: Creating a Selective Disclosure Presentation | ||
|
||
The Holder receives the SD-JWT from the Issuer and selects which claims to disclose to the Verifier. | ||
|
||
### Example | ||
|
||
```bash | ||
from pyeudiw.sd_jwt.holder import SDJWTHolder | ||
|
||
# Claims to disclose | ||
holder_disclosed_claims = { | ||
"given_name": True, | ||
"family_name": True | ||
} | ||
|
||
# Initialize Holder | ||
sdjwt_holder = SDJWTHolder(sdjwt_issuer.sd_jwt_issuance) | ||
|
||
# Create presentation with selected claims | ||
sdjwt_holder.create_presentation( | ||
disclosed_claims=holder_disclosed_claims, | ||
nonce=None, # Optional: Used for key binding | ||
verifier=None, # Optional: Verifier identifier for key binding | ||
holder_key=holder_key # Optional: Holder private key for key binding | ||
) | ||
|
||
# Output the presentation | ||
print("SD-JWT Presentation:", sdjwt_holder.sd_jwt_presentation) | ||
``` | ||
|
||
## 3. Verifier: Verifying an SD-JWT | ||
|
||
The Verifier validates the SD-JWT and checks the disclosed claims. | ||
|
||
### Example | ||
|
||
```python | ||
from pyeudiw.sd_jwt.verifier import SDJWTVerifier | ||
|
||
# Callback to retrieve Issuer's public key | ||
def get_issuer_public_key(issuer, header_parameters): | ||
# Return the public key(s) in JWK format | ||
return [issuer_private_key.serialize()] | ||
|
||
# Initialize Verifier | ||
sdjwt_verifier = SDJWTVerifier( | ||
sdjwt_presentation=sdjwt_holder.sd_jwt_presentation, | ||
cb_get_issuer_key=get_issuer_public_key | ||
) | ||
|
||
# Verify and retrieve payload | ||
verified_payload = sdjwt_verifier.get_verified_payload() | ||
|
||
# Verified claims | ||
print("Verified Claims:", verified_payload) | ||
``` | ||
|
||
|
||
--- | ||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
PYEUDIW_MONGO_TEST_AUTH_INLINE=satosa:thatpassword@ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.