|
43 | 43 | BRAINPOOLP320r1, |
44 | 44 | BRAINPOOLP384r1, |
45 | 45 | BRAINPOOLP512r1, |
| 46 | + Ed25519, |
| 47 | + Ed448, |
46 | 48 | curves, |
47 | 49 | ) |
48 | 50 | from .ecdsa import ( |
@@ -1354,6 +1356,120 @@ def do_test_to_openssl(self, curve, hash_name="SHA1"): |
1354 | 1356 | % mdarg |
1355 | 1357 | ) |
1356 | 1358 |
|
| 1359 | + OPENSSL_SUPPORTED_TYPES = set() |
| 1360 | + try: |
| 1361 | + if "-rawin" in run_openssl("pkeyutl -help"): |
| 1362 | + OPENSSL_SUPPORTED_TYPES = set( |
| 1363 | + c.lower() |
| 1364 | + for c in ("ED25519", "ED448") |
| 1365 | + if c in run_openssl("list -public-key-methods") |
| 1366 | + ) |
| 1367 | + except SubprocessError: |
| 1368 | + pass |
| 1369 | + |
| 1370 | + def do_eddsa_test_to_openssl(self, curve): |
| 1371 | + curvename = curve.name.upper() |
| 1372 | + |
| 1373 | + if os.path.isdir("t"): |
| 1374 | + shutil.rmtree("t") |
| 1375 | + os.mkdir("t") |
| 1376 | + |
| 1377 | + sk = SigningKey.generate(curve=curve) |
| 1378 | + vk = sk.get_verifying_key() |
| 1379 | + |
| 1380 | + data = b"data" |
| 1381 | + with open("t/pubkey.der", "wb") as e: |
| 1382 | + e.write(vk.to_der()) |
| 1383 | + with open("t/pubkey.pem", "wb") as e: |
| 1384 | + e.write(vk.to_pem()) |
| 1385 | + |
| 1386 | + sig = sk.sign(data) |
| 1387 | + |
| 1388 | + with open("t/data.sig", "wb") as e: |
| 1389 | + e.write(sig) |
| 1390 | + with open("t/data.txt", "wb") as e: |
| 1391 | + e.write(data) |
| 1392 | + with open("t/baddata.txt", "wb") as e: |
| 1393 | + e.write(data + b"corrupt") |
| 1394 | + |
| 1395 | + with self.assertRaises(SubprocessError): |
| 1396 | + run_openssl( |
| 1397 | + "pkeyutl -verify -pubin -inkey t/pubkey.pem -rawin " |
| 1398 | + "-in t/baddata.txt -sigfile t/data.sig" |
| 1399 | + ) |
| 1400 | + run_openssl( |
| 1401 | + "pkeyutl -verify -pubin -inkey t/pubkey.pem -rawin " |
| 1402 | + "-in t/data.txt -sigfile t/data.sig" |
| 1403 | + ) |
| 1404 | + |
| 1405 | + shutil.rmtree("t") |
| 1406 | + |
| 1407 | + # in practice at least OpenSSL 3.0.0 is needed to make EdDSA signatures |
| 1408 | + # earlier versions support EdDSA only in X.509 certificates |
| 1409 | + @pytest.mark.skipif( |
| 1410 | + "ed25519" not in OPENSSL_SUPPORTED_TYPES, |
| 1411 | + reason="system openssl does not support signing with Ed25519", |
| 1412 | + ) |
| 1413 | + def test_to_openssl_ed25519(self): |
| 1414 | + return self.do_eddsa_test_to_openssl(Ed25519) |
| 1415 | + |
| 1416 | + @pytest.mark.skipif( |
| 1417 | + "ed448" not in OPENSSL_SUPPORTED_TYPES, |
| 1418 | + reason="system openssl does not support signing with Ed448", |
| 1419 | + ) |
| 1420 | + def test_to_openssl_ed448(self): |
| 1421 | + return self.do_eddsa_test_to_openssl(Ed448) |
| 1422 | + |
| 1423 | + def do_eddsa_test_from_openssl(self, curve): |
| 1424 | + curvename = curve.name |
| 1425 | + |
| 1426 | + if os.path.isdir("t"): |
| 1427 | + shutil.rmtree("t") |
| 1428 | + os.mkdir("t") |
| 1429 | + |
| 1430 | + data = b"data" |
| 1431 | + |
| 1432 | + run_openssl( |
| 1433 | + "genpkey -algorithm {0} -outform PEM -out t/privkey.pem".format( |
| 1434 | + curvename |
| 1435 | + ) |
| 1436 | + ) |
| 1437 | + run_openssl( |
| 1438 | + "pkey -outform PEM -pubout -in t/privkey.pem -out t/pubkey.pem" |
| 1439 | + ) |
| 1440 | + |
| 1441 | + with open("t/data.txt", "wb") as e: |
| 1442 | + e.write(data) |
| 1443 | + run_openssl( |
| 1444 | + "pkeyutl -sign -inkey t/privkey.pem " |
| 1445 | + "-rawin -in t/data.txt -out t/data.sig" |
| 1446 | + ) |
| 1447 | + |
| 1448 | + with open("t/data.sig", "rb") as e: |
| 1449 | + sig = e.read() |
| 1450 | + with open("t/pubkey.pem", "rb") as e: |
| 1451 | + vk = VerifyingKey.from_pem(e.read()) |
| 1452 | + |
| 1453 | + self.assertIs(vk.curve, curve) |
| 1454 | + |
| 1455 | + vk.verify(sig, data) |
| 1456 | + |
| 1457 | + shutil.rmtree("t") |
| 1458 | + |
| 1459 | + @pytest.mark.skipif( |
| 1460 | + "ed25519" not in OPENSSL_SUPPORTED_TYPES, |
| 1461 | + reason="system openssl does not support signing with Ed25519", |
| 1462 | + ) |
| 1463 | + def test_from_openssl_ed25519(self): |
| 1464 | + return self.do_eddsa_test_from_openssl(Ed25519) |
| 1465 | + |
| 1466 | + @pytest.mark.skipif( |
| 1467 | + "ed448" not in OPENSSL_SUPPORTED_TYPES, |
| 1468 | + reason="system openssl does not support signing with Ed448", |
| 1469 | + ) |
| 1470 | + def test_from_openssl_ed448(self): |
| 1471 | + return self.do_eddsa_test_from_openssl(Ed448) |
| 1472 | + |
1357 | 1473 |
|
1358 | 1474 | class TooSmallCurve(unittest.TestCase): |
1359 | 1475 | OPENSSL_SUPPORTED_CURVES = set( |
|
0 commit comments