Skip to content

Commit

Permalink
Fix: SICPA issuance with Ed25519 signature
Browse files Browse the repository at this point in the history
Signed-off-by: GitHub <[email protected]>
  • Loading branch information
georgepadayatti authored May 21, 2024
1 parent 882fc74 commit 081bcc4
Show file tree
Hide file tree
Showing 4 changed files with 585 additions and 47 deletions.
63 changes: 56 additions & 7 deletions eudi_wallet/did_key/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric import ec, ed25519
from jwcrypto import jwk, jwt
from multiformats import multibase, multicodec


@dataclass
class PublicKeyJWK:
crv: str
kty: str
x: str
y: str
crv: str = None
kty: str = None
x: str = None
y: str = None
kid: str = None


class KeyDid:
Expand All @@ -42,6 +43,30 @@ def private_key_jwk(self):
@property
def public_key_jwk(self):
return self._public_key_jwk

def create_keypairEd25519(self):

private_key = ed25519.Ed25519PrivateKey.generate()
public_key = private_key.public_key()

private_key_jwk = jwk.JWK.from_pem(
private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption(),
)
)
public_key_jwk = jwk.JWK.from_pem(
public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo,
)
)

self._key = private_key_jwk
self._public_key = public_key_jwk
self._public_key_jwk = public_key_jwk.export_public(as_dict=True)
self._private_key_jwk = private_key_jwk.export_private(as_dict=True)

def create_keypair(self):
curve = ec.SECP256R1()
Expand Down Expand Up @@ -96,7 +121,9 @@ def method_specific_identifier_to_jwk(
jwk_dict = json.loads(jwk_str)
return jwk.JWK(**jwk_dict)

def generate_id_token(self, did: str = None, auth_server_uri: str = None, nonce: str = None) -> str:
def generate_id_token(
self, did: str = None, auth_server_uri: str = None, nonce: str = None
) -> str:
header = {
"typ": "JWT",
"alg": "ES256",
Expand All @@ -116,7 +143,9 @@ def generate_id_token(self, did: str = None, auth_server_uri: str = None, nonce:

return token.serialize()

def generate_credential_request(self, did: str = None, issuer_uri: str = None, nonce: str = None) -> str:
def generate_credential_request(
self, did: str = None, issuer_uri: str = None, nonce: str = None
) -> str:
header = {
"typ": "openid4vci-proof+jwt",
"alg": "ES256",
Expand All @@ -134,6 +163,26 @@ def generate_credential_request(self, did: str = None, issuer_uri: str = None, n

return token.serialize()

def generate_credential_requestEd25519(
self, did: str = None, issuer_uri: str = None, nonce: str = None
) -> str:
header = {
"typ": "openid4vci-proof+jwt",
"alg": "EdDSA",
"kid": f"{did or self._did}#{self._key.key_id if did else self._method_specific_id}",
}
payload = {
"iss": self._did,
"iat": int(time.time()),
"aud": issuer_uri,
"exp": int(time.time()) + 86400,
"nonce": nonce,
}
token = jwt.JWT(header=header, claims=payload)
token.make_signed_token(self._key)

return token.serialize()

def generate_vp_token_response(
self, auth_server_uri: str, nonce: str, verifiable_credentials: typing.List[str]
) -> str:
Expand Down
86 changes: 48 additions & 38 deletions eudi_wallet/siop_auth/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ async def accept_and_fetch_credential_offer(
credential_offer_uri: str,
) -> CredentialOffer:
cred_offer = await http_call(credential_offer_uri, "GET", data=None, headers=None)
print(cred_offer)
return CredentialOffer(**cred_offer)


Expand Down Expand Up @@ -172,10 +171,12 @@ class Credential:
@dataclass
class OpenIDCredentialIssuerConfig:
credential_issuer: str
authorization_server: str
authorization_servers: typing.List[str]
token_endpoint: str
credential_endpoint: str
deferred_credential_endpoint: str
credentials_supported: typing.List[Credential]
deferred_credential_endpoint: str = None
authorization_server: str = None
display: typing.Optional[str] = None


Expand Down Expand Up @@ -207,27 +208,29 @@ class VPFormatsSupported:

@dataclass
class OpenIDAuthServerConfig:
redirect_uris: typing.List[str]
issuer: str
authorization_endpoint: str
token_endpoint: str
jwks_uri: str
scopes_supported: typing.List[str]
response_types_supported: typing.List[str]
response_modes_supported: typing.List[str]
grant_types_supported: typing.List[str]
subject_types_supported: typing.List[str]
id_token_signing_alg_values_supported: typing.List[str]
request_object_signing_alg_values_supported: typing.List[str]
request_parameter_supported: bool
request_uri_parameter_supported: bool
token_endpoint_auth_methods_supported: typing.List[str]
request_authentication_methods_supported: RequestAuthenticationMethodsSupported
vp_formats_supported: VPFormatsSupported
subject_syntax_types_supported: typing.List[str]
subject_syntax_types_discriminations: typing.List[str]
subject_trust_frameworks_supported: typing.List[str]
id_token_types_supported: typing.List[str]
redirect_uris: typing.List[str] = None
issuer: str = None
authorization_endpoint: str = None
token_endpoint: str = None
jwks_uri: str = None
scopes_supported: typing.List[str] = None
response_types_supported: typing.List[str] = None
response_modes_supported: typing.List[str] = None
grant_types_supported: typing.List[str] = None
subject_types_supported: typing.List[str] = None
id_token_signing_alg_values_supported: typing.List[str] = None
request_object_signing_alg_values_supported: typing.List[str] = None
request_parameter_supported: bool = None
request_uri_parameter_supported: bool = None
token_endpoint_auth_methods_supported: typing.List[str] = None
request_authentication_methods_supported: RequestAuthenticationMethodsSupported = (
None
)
vp_formats_supported: VPFormatsSupported = None
subject_syntax_types_supported: typing.List[str] = None
subject_syntax_types_discriminations: typing.List[str] = None
subject_trust_frameworks_supported: typing.List[str] = None
id_token_types_supported: typing.List[str] = None


async def fetch_openid_auth_server_configuration(authorization_server_uri: str) -> dict:
Expand Down Expand Up @@ -412,12 +415,12 @@ async def send_vp_token_response(

@dataclass
class AccessTokenResponse:
access_token: str
token_type: str
expires_in: int
id_token: str
c_nonce: str
c_nonce_expires_in: int
access_token: str = None
token_type: str = None
expires_in: int = None
id_token: str = None
c_nonce: str = None
c_nonce_expires_in: int = None
scope: typing.Optional[str] = None


Expand Down Expand Up @@ -445,16 +448,21 @@ async def exchange_pre_authorized_code_for_access_token(
) -> AccessTokenResponse:
headers = {"Content-Type": "application/x-www-form-urlencoded"}

query_params = {
"grant_type": "urn:ietf:params:oauth:grant-type:pre-authorized_code",
"user_pin": user_pin,
"pre-authorized_code": pre_authorized_code,
}
if user_pin:
query_params = {
"grant_type": "urn:ietf:params:oauth:grant-type:pre-authorized_code",
"user_pin": user_pin,
"pre-authorized_code": pre_authorized_code,
}
else:
query_params = {
"grant_type": "urn:ietf:params:oauth:grant-type:pre-authorized_code",
"pre-authorized_code": pre_authorized_code,
}
encoded_params = urllib.parse.urlencode(query_params)
access_token_response = await http_call(
token_uri, "POST", data=encoded_params, headers=headers
)
print(access_token_response)
return AccessTokenResponse(**access_token_response)


Expand All @@ -470,8 +478,10 @@ async def send_credential_request(
}

data = {
"types": credential_types,
"format": "jwt_vc",
"credential_definition": {
"type": credential_types,
},
"format": "jwt_vc_json",
"proof": {"proof_type": "jwt", "jwt": credential_request_jwt},
}
credential_response = await http_call(
Expand Down
2 changes: 0 additions & 2 deletions eudi_wallet/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ async def http_call_text_redirects_disabled(url, method, data=None, headers=None
async with session.request(
method, url, data=data, allow_redirects=False
) as resp:
print(await resp.text())
return resp


Expand Down Expand Up @@ -97,7 +96,6 @@ async def http_call(url, method, data=None, headers=None):
"""
async with aiohttp.ClientSession(headers=headers) as session:
async with session.request(method, url, data=data) as resp:
print(await resp.text())
return await resp.json()


Expand Down
Loading

0 comments on commit 081bcc4

Please sign in to comment.