Skip to content

Commit

Permalink
Merge pull request #142 from jschlyter/eddsa
Browse files Browse the repository at this point in the history
EdDSA (Ed25519/Ed448)
  • Loading branch information
jschlyter committed May 25, 2023
2 parents 0a5a521 + cb12605 commit 330d273
Show file tree
Hide file tree
Showing 15 changed files with 724 additions and 10 deletions.
4 changes: 4 additions & 0 deletions src/cryptojwt/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,7 @@ class HTTPException(JWKESTException):

class UnsupportedECurve(Unsupported):
pass


class UnsupportedOKPCurve(Unsupported):
pass
30 changes: 30 additions & 0 deletions src/cryptojwt/jwk/jwk.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from cryptography.hazmat import backends
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric import ed448
from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.asymmetric.rsa import rsa_crt_dmp1
from cryptography.hazmat.primitives.asymmetric.rsa import rsa_crt_dmq1
Expand All @@ -17,6 +19,7 @@
from .ec import NIST2SEC
from .ec import ECKey
from .hmac import SYMKey
from .okp import OKPKey
from .rsa import RSAKey

EC_PUBLIC_REQUIRED = frozenset(["crv", "x", "y"])
Expand All @@ -25,6 +28,12 @@
EC_PRIVATE_OPTIONAL = frozenset()
EC_PRIVATE = EC_PRIVATE_REQUIRED | EC_PRIVATE_OPTIONAL

OKP_PUBLIC_REQUIRED = frozenset(["crv", "x"])
OKP_PUBLIC = OKP_PUBLIC_REQUIRED
OKP_PRIVATE_REQUIRED = frozenset(["d"])
OKP_PRIVATE_OPTIONAL = frozenset()
OKP_PRIVATE = OKP_PRIVATE_REQUIRED | OKP_PRIVATE_OPTIONAL

RSA_PUBLIC_REQUIRED = frozenset(["e", "n"])
RSA_PUBLIC = RSA_PUBLIC_REQUIRED
RSA_PRIVATE_REQUIRED = frozenset(["p", "q", "d"])
Expand All @@ -42,6 +51,16 @@ def ensure_ec_params(jwk_dict, private):
return ensure_params("EC", provided, required)


def ensure_okp_params(jwk_dict, private):
"""Ensure all required OKP parameters are present in dictionary"""
provided = frozenset(jwk_dict.keys())
if private is not None and private:
required = OKP_PUBLIC_REQUIRED | OKP_PRIVATE_REQUIRED
else:
required = OKP_PUBLIC_REQUIRED
return ensure_params("OKP", provided, required)


def ensure_rsa_params(jwk_dict, private):
"""Ensure all required RSA parameters are present in dictionary"""
provided = frozenset(jwk_dict.keys())
Expand Down Expand Up @@ -140,6 +159,15 @@ def key_from_jwk_dict(jwk_dict, private=None):
if _jwk_dict["kty"] != "RSA":
raise WrongKeyType('"{}" should have been "RSA"'.format(_jwk_dict["kty"]))
return RSAKey(**_jwk_dict)
elif _jwk_dict["kty"] == "OKP":
ensure_okp_params(_jwk_dict, private)

if private is not None and not private:
# remove private components
for v in OKP_PRIVATE:
_jwk_dict.pop(v, None)

return OKPKey(**_jwk_dict)
elif _jwk_dict["kty"] == "oct":
if "key" not in _jwk_dict and "k" not in _jwk_dict:
raise MissingValue('There has to be one of "k" or "key" in a symmetric key')
Expand All @@ -164,6 +192,8 @@ def jwk_wrap(key, use="", kid=""):
kspec = SYMKey(key=key, use=use, kid=kid)
elif isinstance(key, ec.EllipticCurvePublicKey):
kspec = ECKey(use=use, kid=kid).load_key(key)
elif isinstance(key, (ed25519.Ed25519PublicKey, ed448.Ed448PublicKey)):
kspec = OKPKey(use=use, kid=kid).load_key(key)
else:
raise Exception("Unknown key type:key=" + str(type(key)))

Expand Down

0 comments on commit 330d273

Please sign in to comment.