Skip to content

Commit d8999d2

Browse files
committed
more OKP
1 parent 411cb0f commit d8999d2

File tree

2 files changed

+77
-9
lines changed

2 files changed

+77
-9
lines changed

src/cryptojwt/key_bundle.py

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
from cryptojwt.jwk.ec import NIST2SEC
1717
from cryptojwt.jwk.hmac import new_sym_key
18+
from cryptojwt.jwk.okp import OKP_CRV2PUBLIC
1819
from cryptojwt.jwk.x509 import import_private_key_from_pem_file
1920

2021
from .exception import JWKException
@@ -27,6 +28,8 @@
2728
from .jwk.hmac import SYMKey
2829
from .jwk.jwk import dump_jwk
2930
from .jwk.jwk import import_jwk
31+
from .jwk.okp import OKPKey
32+
from .jwk.okp import new_okp_key
3033
from .jwk.rsa import RSAKey
3134
from .jwk.rsa import new_rsa_key
3235
from .utils import as_unicode
@@ -46,7 +49,7 @@
4649
# raise excep(_err, 'application/json')
4750

4851
# Make sure the keys are all uppercase
49-
K2C = {"RSA": RSAKey, "EC": ECKey, "oct": SYMKey}
52+
K2C = {"RSA": RSAKey, "EC": ECKey, "oct": SYMKey, "OKP": OKPKey}
5053

5154
MAP = {"dec": "enc", "enc": "enc", "ver": "sig", "sig": "sig"}
5255

@@ -154,6 +157,29 @@ def ec_init(spec):
154157
return _kb
155158

156159

160+
def okp_init(spec):
161+
"""
162+
Initiate a key bundle with an Octet Key Pair.
163+
164+
:param spec: Key specifics of the form::
165+
{"type": "OKP", "crv": "Ed25519", "use": ["sig"]}
166+
167+
:return: A KeyBundle instance
168+
"""
169+
curve = spec.get("crv", "Ed25519")
170+
171+
_kb = KeyBundle(keytype="OKP")
172+
if "use" in spec:
173+
for use in spec["use"]:
174+
eck = new_okp_key(crv=curve, use=use)
175+
_kb.append(eck)
176+
else:
177+
eck = new_okp_key(crv=curve)
178+
_kb.append(eck)
179+
180+
return _kb
181+
182+
157183
def keys_writer(func):
158184
def wrapper(self, *args, **kwargs):
159185
with self._lock_writer:
@@ -1003,6 +1029,17 @@ def build_key_bundle(key_conf, kid_template=""):
10031029
)
10041030
else:
10051031
_bundle = ec_init(spec)
1032+
elif typ == "OKP":
1033+
if "key" in spec and spec["key"]:
1034+
if os.path.isfile(spec["key"]):
1035+
_bundle = KeyBundle(
1036+
source="file://%s" % spec["key"],
1037+
fileformat="der",
1038+
keytype=typ,
1039+
keyusage=spec["use"],
1040+
)
1041+
else:
1042+
_bundle = okp_init(spec)
10061043
elif typ.lower() == "oct":
10071044
_bundle = sym_init(spec)
10081045
else:
@@ -1047,7 +1084,7 @@ def type_order(kd1, kd2):
10471084
if _l:
10481085
return _l
10491086

1050-
if kd1["type"] == "EC":
1087+
if kd1["type"] in ["EC", "OKP"]:
10511088
_l = _cmp(kd1["crv"], kd2["crv"])
10521089
if _l:
10531090
return _l
@@ -1155,8 +1192,8 @@ def key_diff(key_bundle, key_defs):
11551192
if key.kty != key_def["type"]:
11561193
continue
11571194

1158-
if key.kty == "EC":
1159-
# special test only for EC keys
1195+
if key.kty in ["EC", "OKP"]:
1196+
# special test only for EC and OKP keys
11601197
if key.crv != key_def["crv"]:
11611198
continue
11621199

@@ -1230,7 +1267,7 @@ def key_rollover(bundle):
12301267
key_spec = []
12311268
for key in bundle.get():
12321269
_spec = {"type": key.kty, "use": [key.use]}
1233-
if key.kty == "EC":
1270+
if key.kty in ["EC", "OKP"):
12341271
_spec["crv"] = key.crv
12351272

12361273
key_spec.append(_spec)
@@ -1264,6 +1301,7 @@ def unique_keys(keys):
12641301
DEFAULT_RSA_KEYSIZE = 2048
12651302
DEFAULT_RSA_EXP = 65537
12661303
DEFAULT_EC_CURVE = "P-256"
1304+
DEFAULT_OKP_CURVE = "Ed25519"
12671305

12681306

12691307
def key_gen(type, **kwargs):
@@ -1290,6 +1328,12 @@ def key_gen(type, **kwargs):
12901328
logging.error("Unknown curve: %s", crv)
12911329
raise ValueError("Unknown curve: {}".format(crv))
12921330
_key = new_ec_key(crv=crv, **kargs)
1331+
elif type.upper() == "OKP":
1332+
crv = kwargs.get("crv", DEFAULT_OKP_CURVE)
1333+
if crv not in OKP_CRV2PUBLIC:
1334+
logging.error("Unknown curve: %s", crv)
1335+
raise ValueError("Unknown curve: {}".format(crv))
1336+
_key = new_okp_key(crv=crv, **kargs)
12931337
elif type.lower() in ["sym", "oct"]:
12941338
keysize = kwargs.get("bytes", 24)
12951339
randomkey = os.urandom(keysize)
@@ -1324,6 +1368,8 @@ def key_by_alg(alg: str):
13241368
return key_gen("EC", crv="P-384")
13251369
elif alg == "ES512":
13261370
return key_gen("EC", crv="P-521")
1371+
elif alg == "EdDSA":
1372+
return key_gen("OKP", crv=DEFAULT_OKP_CURVE)
13271373
elif alg.startswith("HS"):
13281374
return key_gen("sym")
13291375

tests/test_03_key_bundle.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
from cryptojwt.jwk.ec import ECKey
1515
from cryptojwt.jwk.ec import new_ec_key
1616
from cryptojwt.jwk.hmac import SYMKey
17+
from cryptojwt.jwk.okp import OKPKey
18+
from cryptojwt.jwk.okp import new_okp_key
1719
from cryptojwt.jwk.rsa import RSAKey
1820
from cryptojwt.jwk.rsa import import_rsa_key_from_cert_file
1921
from cryptojwt.jwk.rsa import new_rsa_key
@@ -620,24 +622,33 @@ def test_dump_jwk():
620622
"y": "GOd2jL_6wa0cfnyA0SmEhok9fkYEnAHFKLLM79BZ8_E",
621623
"crv": "P-256",
622624
},
625+
{
626+
"kty": "OKP",
627+
"kid": "xyzzy",
628+
"use": "sig",
629+
"x": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo",
630+
"crv": "Ed25519",
631+
},
623632
]
624633
}
625634

626635

627636
def test_keys():
628637
kb = KeyBundle(JWKS_DICT)
629638

630-
assert len(kb) == 3
639+
assert len(kb) == 4
631640

632641
assert len(kb.get("rsa")) == 1
633642
assert len(kb.get("oct")) == 1
634643
assert len(kb.get("ec")) == 1
644+
assert len(kb.get("okp")) == 1
635645

636646

637647
EXPECTED = [
638648
b"iA7PvG_DfJIeeqQcuXFmvUGjqBkda8In_uMpZrcodVA",
639649
b"akXzyGlXg8yLhsCczKb_r8VERLx7-iZBUMIVgg2K7p4",
640650
b"kLsuyGef1kfw5-t-N9CJLIHx_dpZ79-KemwqjwdrvTI",
651+
b"kPrK_qmxVWaYVA9wwBF6Iuo3vVzz7TxHCTwXBygrS4k",
641652
]
642653

643654

@@ -860,6 +871,15 @@ def test_key_gen_rsa():
860871
assert isinstance(_jwk, RSAKey)
861872

862873

874+
def test_key_gen_okp():
875+
_jwk = key_gen("OKP", kid="kid1")
876+
assert _jwk
877+
assert _jwk.kty == "OKP"
878+
assert _jwk.kid == "kid1"
879+
880+
assert isinstance(_jwk, OKPKey)
881+
882+
863883
def test_init_key():
864884
spec = {"type": "RSA", "kid": "one"}
865885

@@ -932,10 +952,11 @@ def test_remote():
932952
exp = kb.dump()
933953
kb2 = KeyBundle().load(exp)
934954
assert kb2.source == source
935-
assert len(kb2.keys()) == 3
955+
assert len(kb2.keys()) == 4
936956
assert len(kb2.get("rsa")) == 1
937957
assert len(kb2.get("oct")) == 1
938958
assert len(kb2.get("ec")) == 1
959+
assert len(kb2.get("okp")) == 1
939960
assert kb2.httpc_params == {"timeout": (2, 2)}
940961
assert kb2.imp_jwks
941962
assert kb2.last_updated
@@ -972,11 +993,12 @@ def test_remote_not_modified():
972993
exp = kb.dump()
973994
kb2 = KeyBundle().load(exp)
974995
assert kb2.source == source
975-
assert len(kb2.keys()) == 3
976-
assert len(kb2.active_keys()) == 3
996+
assert len(kb2.keys()) == 4
997+
assert len(kb2.active_keys()) == 4
977998
assert len(kb2.get("rsa")) == 1
978999
assert len(kb2.get("oct")) == 1
9791000
assert len(kb2.get("ec")) == 1
1001+
assert len(kb2.get("okp")) == 1
9801002
assert kb2.httpc_params == {"timeout": (2, 2)}
9811003
assert kb2.imp_jwks
9821004
assert kb2.last_updated

0 commit comments

Comments
 (0)