Skip to content

Commit

Permalink
Feat/features by metadata (#138)
Browse files Browse the repository at this point in the history
* fix: refactoring to WalletRelyingParty class
* feat: added print of metadata  validation
* Moved code relative to openid4vp in the relative package
* fix: collapsed multiple warnings in one
* fix: moved VP data in __init__.py
* fix: removed pformat function

---------

Co-authored-by: Giuseppe De Marco <[email protected]>
  • Loading branch information
PascalDR and Giuseppe De Marco authored Nov 3, 2023
1 parent d46d395 commit 9a32ad1
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 91 deletions.
129 changes: 46 additions & 83 deletions pyeudiw/federation/schemas/wallet_relying_party.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,41 @@
from typing import Any, Dict, List

from pydantic import BaseModel, HttpUrl, field_validator
from pydantic_core.core_schema import FieldValidationInfo

from enum import Enum
from typing import Any, List
from pyeudiw.jwk.schema import JwksSchema

_default_algorithms = {
"authorization_signed_response_alg": [
"RS256",
"ES256"
],
"authorization_encrypted_response_alg": [
"RSA-OAEP",
"RSA-OAEP-256",
],
"authorization_encrypted_response_enc": [
"A128CBC-HS256",
"A192CBC-HS384",
"A256CBC-HS512",
"A128GCM",
"A192GCM",
"A256GCM",
],
"id_token_signed_response_alg": [
"RS256",
"ES256"
],
"id_token_encrypted_response_alg": [
"RSA-OAEP",
"RSA-OAEP-256",
],
"id_token_encrypted_response_enc": [
"A128CBC-HS256",
"A192CBC-HS384",
"A256CBC-HS512",
"A128GCM",
"A192GCM",
"A256GCM",
]
}

from pydantic import BaseModel, HttpUrl, PositiveInt
from pyeudiw.openid4vp.schemas import VPFormat

class AcrValuesSupported(str, Enum):
spid_l1 = "https://www.spid.gov.it/SpidL1"
spid_l2 = "https://www.spid.gov.it/SpidL2"
spid_l3 = "https://www.spid.gov.it/SpidL3"

class EncryptionAlgValuesSupported(str, Enum):
rsa_oaep = "RSA-OAEP"
ras_oaep_256 = "RSA-OAEP-256"
ecdh_es = "ECDH-ES"
ecdh_es_a128kw = "ECDH-ES+A128KW"
ecdh_es_a192kw = "ECDH-ES+A192KW"
ecdh_es_a256kw = "ECDH-ES+A256KW"

class EncryptionEncValuesSupported(str, Enum):
a128cbc_hs256 = "A128CBC-HS256"
a192cbc_hs384 = "A192CBC-HS384"
a256cbc_hs512 = "A256CBC-HS512"
a128gcm = "A128GCM"
a192gcm = "A192GCM"
a256gcm = "A256GCM"

class SigningAlgValuesSupported(str, Enum):
es256 = "ES256"
es384 = "ES384"
es512 = "ES512"
rs256 = "RS256"
rs384 = "RS384"
rs512 = "RS512"

class AuthorizationSignedResponseAlg(str, Enum):
rs256 = "RS256"
es256 = "ES256"

class WalletRelyingParty(BaseModel):
application_type: str
Expand All @@ -50,48 +46,15 @@ class WalletRelyingParty(BaseModel):
request_uris: List[HttpUrl]
redirect_uris: List[HttpUrl]
default_acr_values: List[HttpUrl]
vp_formats: Dict[str, Dict[str, List[str]]]
presentation_definitions: List[Any]
default_max_age: int
authorization_signed_response_alg: List[str]
authorization_encrypted_response_alg: List[str]
authorization_encrypted_response_enc: List[str]
authorization_signed_response_alg: List[AuthorizationSignedResponseAlg]
authorization_encrypted_response_alg: List[EncryptionAlgValuesSupported]
authorization_encrypted_response_enc: List[EncryptionEncValuesSupported]
subject_type: str
require_auth_time: bool
id_token_signed_response_alg: List[str]
id_token_encrypted_response_alg: List[str]
id_token_encrypted_response_enc: List[str]

@classmethod
def _get_algorithms_supported(cls, name: str, info: FieldValidationInfo) -> list[str]:
if not info.context:
return _default_algorithms[name]
return info.context.get(name, _default_algorithms[name])

@classmethod
def _check_algorithms(cls, algorithms: list[str], name: str, info: FieldValidationInfo):
supported_algorithms = WalletRelyingParty._get_algorithms_supported(
name, info)
for alg in algorithms:
if alg not in supported_algorithms:
raise ValueError(
f"Unsupported algorithm: {alg} for {name}. "
f"Supported algorithms: {supported_algorithms}."
)
return algorithms

@field_validator(
"authorization_signed_response_alg",
"authorization_encrypted_response_alg",
"authorization_encrypted_response_enc",
"id_token_signed_response_alg",
"id_token_encrypted_response_alg",
"id_token_encrypted_response_enc"
)
@classmethod
def check_alg(cls, value, info: FieldValidationInfo):
return WalletRelyingParty._check_algorithms(
value,
info.field_name,
info
)
id_token_encrypted_response_alg: List[EncryptionAlgValuesSupported]
id_token_encrypted_response_enc: List[EncryptionEncValuesSupported]
id_token_signed_response_alg: List[SigningAlgValuesSupported]
default_acr_values: List[AcrValuesSupported]
default_max_age: PositiveInt
vp_formats: VPFormat
13 changes: 13 additions & 0 deletions pyeudiw/openid4vp/schemas/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from enum import Enum
from typing import List
from pydantic import BaseModel

class VPSigningAlgResponseSupported(str, Enum):
eddsa = "EdDSA"
es256k = "ES256K"

class VPAlgorithmSchema(BaseModel):
alg: List[VPSigningAlgResponseSupported]

class VPFormat(BaseModel):
jwt_vp_json: VPAlgorithmSchema
11 changes: 10 additions & 1 deletion pyeudiw/satosa/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@
)
from pyeudiw.storage.db_engine import DBEngine
from pyeudiw.storage.exceptions import StorageWriteError
from pyeudiw.federation.schemas.wallet_relying_party import WalletRelyingParty

from pydantic import ValidationError


logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -65,6 +65,15 @@ def __init__(self, auth_callback_func, internal_attributes, config, base_url, na
"""
super().__init__(auth_callback_func, internal_attributes, base_url, name)

try:
WalletRelyingParty(**config['metadata'])
except ValidationError as e:
logger.warning(
"""
The backend configuration presents the following validation issues:
{}
""".format(logger.warning(e)))

self.config = config
self.client_id = self.config['metadata']['client_id']
self.default_exp = int(self.config['jwt']['default_exp'])
Expand Down
9 changes: 2 additions & 7 deletions pyeudiw/tests/openid4vp/schemas/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,8 @@ def test_entity_config_payload():
],
"authorization_encrypted_response_alg": [
"RSA-OAEP",
"RSA-OAEP-256"
"RSA-OAEP-256",
"ECDH-ES"
],
"authorization_encrypted_response_enc": [
"A128CBC-HS256",
Expand Down Expand Up @@ -318,9 +319,3 @@ def test_entity_config_payload():
]
}
EntityConfigurationPayload(**payload)
with pytest.raises(ValidationError):
EntityConfigurationPayload.model_validate(
payload, context={"authorization_encrypted_response_alg": ["ASD"]})
with pytest.raises(ValidationError):
EntityConfigurationPayload.model_validate(
payload, context={"authorization_encrypted_response_alg": []})

0 comments on commit 9a32ad1

Please sign in to comment.