Skip to content

Commit 3a5ea7a

Browse files
authored
Merge pull request #621 from dajiaji/ajitomi-add-alg-validation-for-fully-specified-algs
Add alg validation for fully-specified algs.
2 parents fa1ec2c + bddf449 commit 3a5ea7a

6 files changed

Lines changed: 190 additions & 12 deletions

File tree

cwt/algs/ec2.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,17 @@ def __init__(self, params: Dict[int, Any]):
8282
else:
8383
self._key_ops = [2]
8484
if self._alg:
85+
# Validate alg for EC2 curve.
86+
if self._crv == 1 and self._alg not in ([-7, -9, 35, 36] + list(COSE_ALGORITHMS_CKDM_KEY_AGREEMENT.values())):
87+
raise ValueError(f"Unsupported or unknown alg used with P-256: {self._alg}.")
88+
elif self._crv == 2 and self._alg not in ([-35, -51, 37, 38] + list(COSE_ALGORITHMS_CKDM_KEY_AGREEMENT.values())):
89+
raise ValueError(f"Unsupported or unknown alg used with P-384: {self._alg}.")
90+
elif self._crv == 3 and self._alg not in ([-36, -52, 39, 40] + list(COSE_ALGORITHMS_CKDM_KEY_AGREEMENT.values())):
91+
raise ValueError(f"Unsupported or unknown alg used with P-521: {self._alg}.")
92+
elif self._crv == 8 and self._alg != -47:
93+
raise ValueError(f"Unsupported or unknown alg used with secp256k1: {self._alg}.")
94+
95+
# Validate alg for key_ops.
8596
if self._alg in COSE_ALGORITHMS_SIG_EC2.values():
8697
if self._key_ops:
8798
if -4 in params:

cwt/algs/okp.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,12 @@ def __init__(self, params: Dict[int, Any]):
7575
self._hash_alg = hashes.SHA256 if self._crv == 4 else hashes.SHA512
7676
elif self._alg is not None:
7777
raise ValueError(f"Unsupported or unknown alg used with X25519/X448: {self._alg}.")
78-
elif self._crv in [6, 7]:
79-
if self._alg is not None and self._alg not in COSE_ALGORITHMS_SIG_OKP.values():
80-
raise ValueError(f"Unsupported or unknown alg used with Ed25519/Ed448: {self._alg}.")
78+
elif self._crv == 6:
79+
if self._alg is not None and self._alg not in [-8, -19]:
80+
raise ValueError(f"Unsupported or unknown alg used with Ed25519: {self._alg}.")
81+
elif self._crv == 7:
82+
if self._alg is not None and self._alg not in [-8, -53]:
83+
raise ValueError(f"Unsupported or unknown alg used with Ed448: {self._alg}.")
8184
else:
8285
raise ValueError(f"Unsupported or unknown crv(-1) for OKP: {self._crv}.")
8386

tests/test_algs_ec2.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ def test_cose_key_constructor_without_cose_key(self):
306306
-3: b"\xe2\xdb\xef\xfe\xb8\x8a\x12\xf27\xcb\x15:\x8a\xb9\x1a90B\x1a\x19^\xbc\xdc\xde\r\xb9s\xc1P\xf3\xaa\xdd",
307307
3: -8,
308308
},
309-
"Unsupported or unknown alg(3) for EC2: -8.",
309+
"Unsupported or unknown alg used with P-256: -8",
310310
),
311311
(
312312
{
@@ -325,7 +325,7 @@ def test_cose_key_constructor_without_cose_key(self):
325325
-1: 2,
326326
3: -8,
327327
},
328-
"Unsupported or unknown alg(3) for EC2: -8.",
328+
"Unsupported or unknown alg used with P-384: -8",
329329
),
330330
(
331331
{
@@ -344,7 +344,7 @@ def test_cose_key_constructor_without_cose_key(self):
344344
-1: 3,
345345
3: -8,
346346
},
347-
"Unsupported or unknown alg(3) for EC2: -8.",
347+
"Unsupported or unknown alg used with P-521: -8",
348348
),
349349
(
350350
{
@@ -363,7 +363,7 @@ def test_cose_key_constructor_without_cose_key(self):
363363
-1: 8,
364364
3: -8,
365365
},
366-
"Unsupported or unknown alg(3) for EC2: -8.",
366+
"Unsupported or unknown alg used with secp256k1: -8",
367367
),
368368
(
369369
{

tests/test_algs_okp.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ def test_okp_key_derive_bytes_with_raw_context(self):
362362
COSEKeyParams.ALG: -999,
363363
COSEKeyParams.X: b"\x18Es\xe0\x9a\x83\xfd\x0e\xe9K\xa8n\xf39i\x17\xfe\n2+|\xd1q\xcc\x87\xd2\xe9\xa9\xe8 \x9b\xd9",
364364
},
365-
"Unsupported or unknown alg used with Ed25519/Ed448: -999.",
365+
"Unsupported or unknown alg used with Ed25519: -999.",
366366
),
367367
(
368368
{
@@ -371,7 +371,7 @@ def test_okp_key_derive_bytes_with_raw_context(self):
371371
COSEKeyParams.ALG: 35,
372372
COSEKeyParams.X: b"\x18Es\xe0\x9a\x83\xfd\x0e\xe9K\xa8n\xf39i\x17\xfe\n2+|\xd1q\xcc\x87\xd2\xe9\xa9\xe8 \x9b\xd9",
373373
},
374-
"Unsupported or unknown alg used with Ed25519/Ed448: 35.",
374+
"Unsupported or unknown alg used with Ed25519: 35.",
375375
),
376376
(
377377
{

tests/test_cose_key.py

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,9 @@ def test_key_builder_from_pem_with_alg(self, private_key_path, public_key_path):
139139
"ECDH-SS+HKDF-256",
140140
"ECDH-ES+HKDF-512",
141141
"ECDH-ES+HKDF-256",
142-
"ES256K",
143-
"ES512",
144-
"ES384",
142+
# "ES256K",
143+
# "ES512",
144+
# "ES384",
145145
"ES256",
146146
],
147147
)
@@ -630,3 +630,89 @@ def test_cose_key_interface(self):
630630
ki.crv
631631
pytest.fail("crv should fail.")
632632
assert "" == str(err.value)
633+
634+
@pytest.mark.parametrize(
635+
"invalid, msg",
636+
[
637+
("Ed25519", "Unsupported or unknown alg used with P-256:"),
638+
("Ed448", "Unsupported or unknown alg used with P-256:"),
639+
# ("ES256", "Unsupported or unknown alg used with P-256:"),
640+
("ES384", "Unsupported or unknown alg used with P-256:"),
641+
("ES512", "Unsupported or unknown alg used with P-256:"),
642+
# ("ESP256", "Unsupported or unknown alg used with P-256:"),
643+
("ESP384", "Unsupported or unknown alg used with P-256:"),
644+
("ESP512", "Unsupported or unknown alg used with P-256:"),
645+
],
646+
)
647+
def test_key_builder_from_jwk_with_invalid_fully_specified_ec2_p256_alg(self, invalid, msg):
648+
with pytest.raises(ValueError) as err:
649+
COSEKey.from_jwk(
650+
{
651+
"kty": "EC",
652+
"use": "sig",
653+
"crv": "P-256",
654+
"kid": "P-256-01",
655+
"x": "usWxHK2PmfnHKwXPS54m0kTcGJ90UiglWiGahtagnv8",
656+
"y": "IBOL-C3BttVivg-lSreASjpkttcsz-1rb7btKLv8EX4",
657+
"d": "V8kgd2ZBRuh2dgyVINBUqpPDr7BOMGcF22CQMIUHtNM",
658+
"alg": invalid,
659+
}
660+
)
661+
pytest.fail("from_jwk should fail.")
662+
assert msg in str(err.value)
663+
664+
@pytest.mark.parametrize(
665+
"invalid, msg",
666+
[
667+
("Ed448", "Unsupported or unknown alg used with Ed25519:"),
668+
("ES256", "Unsupported or unknown alg used with Ed25519:"),
669+
("ESP256", "Unsupported or unknown alg used with Ed25519:"),
670+
("ES384", "Unsupported or unknown alg used with Ed25519:"),
671+
("ES512", "Unsupported or unknown alg used with Ed25519:"),
672+
("ESP384", "Unsupported or unknown alg used with Ed25519:"),
673+
("ESP512", "Unsupported or unknown alg used with Ed25519:"),
674+
],
675+
)
676+
def test_key_builder_from_jwk_with_invalid_fully_specified_okp_ed25519_alg(self, invalid, msg):
677+
with pytest.raises(ValueError) as err:
678+
COSEKey.from_jwk(
679+
{
680+
"kty": "OKP",
681+
"use": "sig",
682+
"crv": "Ed25519",
683+
"kid": "Ed25519-01",
684+
"x": "2E6dX83gqD_D0eAmqnaHe1TC1xuld6iAKXfw2OVATr0",
685+
"d": "L8JS08VsFZoZxGa9JvzYmCWOwg7zaKcei3KZmYsj7dc",
686+
"alg": invalid,
687+
}
688+
)
689+
pytest.fail("from_jwk should fail.")
690+
assert msg in str(err.value)
691+
692+
@pytest.mark.parametrize(
693+
"invalid, msg",
694+
[
695+
("Ed25519", "Unsupported or unknown alg used with Ed448:"),
696+
("ES256", "Unsupported or unknown alg used with Ed448:"),
697+
("ESP256", "Unsupported or unknown alg used with Ed448:"),
698+
("ES384", "Unsupported or unknown alg used with Ed448:"),
699+
("ES512", "Unsupported or unknown alg used with Ed448:"),
700+
("ESP384", "Unsupported or unknown alg used with Ed448:"),
701+
("ESP512", "Unsupported or unknown alg used with Ed448:"),
702+
],
703+
)
704+
def test_key_builder_from_jwk_with_invalid_fully_specified_okp_ed448_alg(self, invalid, msg):
705+
with pytest.raises(ValueError) as err:
706+
COSEKey.from_jwk(
707+
{
708+
"kty": "OKP",
709+
"use": "sig",
710+
"crv": "Ed448",
711+
"kid": "Ed448-01",
712+
"x": "25isUWIosUkM2ynOPFP5t7BbwM1_iFQmKBpHvA0hgXpRX6yyu-nq6BBmpS3J0DYTlZIoA4qwgSqA",
713+
"d": "vOHg3x9AXEBRDnzM5b68bLFswieywpJzTOkxafU5fiDxyKowuetnBgjQsgTRWoc067X9xvZWE0Sd",
714+
"alg": invalid,
715+
}
716+
)
717+
pytest.fail("from_jwk should fail.")
718+
assert msg in str(err.value)

tests/test_signer.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,58 @@ def test_signer_esp256(self):
248248
except Exception:
249249
pytest.fail("signer.sign and verify should not fail.")
250250

251+
def test_signer_esp384(self):
252+
signer = Signer.new(
253+
cose_key=COSEKey.from_jwk(
254+
{
255+
"kty": "EC",
256+
"kid": "P-384-01",
257+
"crv": "P-384",
258+
"x": "_XyN9woHaS0mPimSW-etwJMEDSzxIMjp4PjezavU8SHJoClz1bQrcmPb1ZJxHxhI",
259+
"y": "GCNfc32p9sRotx7u2oDGJ3Eqz6q5zPHLdizNn83oRsUTN31eCWfGLHWRury3xF50",
260+
"d": "1pImEKbrr771-RKi8Tb7tou_WjiR7kwui_nMu16449rk3lzAqf9buUhTkJ-pogkb",
261+
"alg": "ESP384",
262+
}
263+
),
264+
protected={"alg": "ESP384"},
265+
unprotected={"kid": "P-384-01"},
266+
)
267+
assert signer.unprotected[4] == b"P-384-01"
268+
assert cbor2.loads(signer.protected)[1] == -51
269+
assert signer.cose_key.alg == -51
270+
assert signer.cose_key.kid == b"P-384-01"
271+
try:
272+
signer.sign(b"Hello world!")
273+
signer.verify(b"Hello world!")
274+
except Exception:
275+
pytest.fail("signer.sign and verify should not fail.")
276+
277+
def test_signer_esp512(self):
278+
signer = Signer.new(
279+
cose_key=COSEKey.from_jwk(
280+
{
281+
"kty": "EC",
282+
"kid": "P-521-01",
283+
"crv": "P-521",
284+
"x": "APkZitSJMJUMB-iPCt47sWu_CrnUHg6IAR4qjmHON-2u41Rjg6DNOS0LZYJJt-AVH5NgGVi8ElIfjo71b9HXCTOc",
285+
"y": "ASx-Cb--149HJ-e1KlSaY-1BOhwOdcTkxSt8BGbW7_hnGfzHsoXM3ywwNcp1Yad-FHUKwmCyMelMQEn2Rh4V2l3I",
286+
"d": "ADYyo73ZKicOjwGDYQ_ybZKnVzdAcxGm9OVAxQjzgVM4jaS-Iwtkz90oLdDz3shgKlDgtRK2Aa9lMhqR94hBo4IE",
287+
"alg": "ESP512",
288+
}
289+
),
290+
protected={"alg": "ESP512"},
291+
unprotected={"kid": "P-521-01"},
292+
)
293+
assert signer.unprotected[4] == b"P-521-01"
294+
assert cbor2.loads(signer.protected)[1] == -52
295+
assert signer.cose_key.alg == -52
296+
assert signer.cose_key.kid == b"P-521-01"
297+
try:
298+
signer.sign(b"Hello world!")
299+
signer.verify(b"Hello world!")
300+
except Exception:
301+
pytest.fail("signer.sign and verify should not fail.")
302+
251303
def test_signer_ed25519(self):
252304
signer = Signer.new(
253305
cose_key=COSEKey.from_jwk(
@@ -273,3 +325,29 @@ def test_signer_ed25519(self):
273325
signer.verify(b"Hello world!")
274326
except Exception:
275327
pytest.fail("signer.sign and verify should not fail.")
328+
329+
def test_signer_ed448(self):
330+
signer = Signer.new(
331+
cose_key=COSEKey.from_jwk(
332+
{
333+
"kty": "OKP",
334+
"d": "vOHg3x9AXEBRDnzM5b68bLFswieywpJzTOkxafU5fiDxyKowuetnBgjQsgTRWoc067X9xvZWE0Sd",
335+
"use": "sig",
336+
"crv": "Ed448",
337+
"kid": "Ed448-01",
338+
"x": "25isUWIosUkM2ynOPFP5t7BbwM1_iFQmKBpHvA0hgXpRX6yyu-nq6BBmpS3J0DYTlZIoA4qwgSqA",
339+
"alg": "Ed448",
340+
}
341+
),
342+
protected={"alg": "Ed448"},
343+
unprotected={"kid": "Ed448-01"},
344+
)
345+
assert signer.unprotected[4] == b"Ed448-01"
346+
assert cbor2.loads(signer.protected)[1] == -53
347+
assert signer.cose_key.alg == -53
348+
assert signer.cose_key.kid == b"Ed448-01"
349+
try:
350+
signer.sign(b"Hello world!")
351+
signer.verify(b"Hello world!")
352+
except Exception:
353+
pytest.fail("signer.sign and verify should not fail.")

0 commit comments

Comments
 (0)