Skip to content

Commit

Permalink
Merge pull request #256 from tlsfuzzer/eddsa
Browse files Browse the repository at this point in the history
EdDSA support
  • Loading branch information
tomato42 committed Apr 22, 2022
2 parents 6c20190 + 82da89c commit ef01e3b
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 1 deletion.
12 changes: 11 additions & 1 deletion .github/workflows/ci.yml
Expand Up @@ -18,6 +18,11 @@ jobs:
os: ubuntu-latest
container: centos:6
python-version: 2.6
- name: py3.10 with ossl3.0
os: ubuntu-latest
container: ubuntu:22.04
python-version: "3.10"
tox-env: py310
- name: py2.7
os: ubuntu-18.04
python-version: 2.7
Expand Down Expand Up @@ -115,7 +120,7 @@ jobs:
with:
fetch-depth: 50
- name: Ensure dependencies on CentOS
if: ${{ matrix.container }}
if: ${{ matrix.container == 'centos:6' }}
run: |
ls /etc/yum.repos.d/
cat /etc/yum.repos.d/CentOS-Base.repo
Expand Down Expand Up @@ -144,6 +149,11 @@ jobs:
yum clean all
yum repolist all
yum install -y git make python curl gcc libffi-devel python-devel glibc-devel openssl-devel wget
- name: Ensure dependencies on Ubuntu 22.04
if: ${{ matrix.container == 'ubuntu:22.04' }}
run: |
apt-get update
apt-get install -y git make python-is-python3 python3 curl wget python3-distutils python3-pip
- name: Verify git status
run: |
git status
Expand Down
6 changes: 6 additions & 0 deletions src/ecdsa/test_keys.py
Expand Up @@ -336,6 +336,9 @@ def test_load_ed25519_from_pem(self):

vk = VerifyingKey.from_pem(vk_pem)

self.assertIsInstance(vk.curve, Curve)
self.assertIs(vk.curve, Ed25519)

vk_str = (
b"\x23\x00\x50\xd0\xd6\x64\x22\x28\x8e\xe3\x55\x89\x7e\x6e\x41\x57"
b"\x8d\xae\xde\x44\x26\xee\x56\x27\xbc\x85\xe6\x0b\x2f\x2a\xcb\x65"
Expand Down Expand Up @@ -400,6 +403,9 @@ def test_ed448_from_pem(self):

vk = VerifyingKey.from_pem(pem_str)

self.assertIsInstance(vk.curve, Curve)
self.assertIs(vk.curve, Ed448)

vk_str = (
b"\x79\x0b\x5e\xb5\x2b\xbb\x08\xc1\x33\x13\xe5\xd6\x07\x5d\x01\x83"
b"\x8e\xcb\x08\x0d\x20\x88\xd8\xa4\x3b\x11\xf3\x76\x9f\xad\x67\xf7"
Expand Down
8 changes: 8 additions & 0 deletions src/ecdsa/test_malformed_sigs.py
Expand Up @@ -13,6 +13,14 @@
"sha384",
"sha512",
]
# skip algorithms broken by change to OpenSSL 3.0 and early versions
# of hashlib that list algorithms that require the legacy provider to work
# https://bugs.python.org/issue38820
algorithms_available = [
i
for i in algorithms_available
if i not in ("mdc2", "md2", "md4", "whirlpool", "ripemd160")
]
from functools import partial
import pytest
import sys
Expand Down
116 changes: 116 additions & 0 deletions src/ecdsa/test_pyecdsa.py
Expand Up @@ -43,6 +43,8 @@
BRAINPOOLP320r1,
BRAINPOOLP384r1,
BRAINPOOLP512r1,
Ed25519,
Ed448,
curves,
)
from .ecdsa import (
Expand Down Expand Up @@ -1354,6 +1356,120 @@ def do_test_to_openssl(self, curve, hash_name="SHA1"):
% mdarg
)

OPENSSL_SUPPORTED_TYPES = set()
try:
if "-rawin" in run_openssl("pkeyutl -help"):
OPENSSL_SUPPORTED_TYPES = set(
c.lower()
for c in ("ED25519", "ED448")
if c in run_openssl("list -public-key-methods")
)
except SubprocessError:
pass

def do_eddsa_test_to_openssl(self, curve):
curvename = curve.name.upper()

if os.path.isdir("t"):
shutil.rmtree("t")
os.mkdir("t")

sk = SigningKey.generate(curve=curve)
vk = sk.get_verifying_key()

data = b"data"
with open("t/pubkey.der", "wb") as e:
e.write(vk.to_der())
with open("t/pubkey.pem", "wb") as e:
e.write(vk.to_pem())

sig = sk.sign(data)

with open("t/data.sig", "wb") as e:
e.write(sig)
with open("t/data.txt", "wb") as e:
e.write(data)
with open("t/baddata.txt", "wb") as e:
e.write(data + b"corrupt")

with self.assertRaises(SubprocessError):
run_openssl(
"pkeyutl -verify -pubin -inkey t/pubkey.pem -rawin "
"-in t/baddata.txt -sigfile t/data.sig"
)
run_openssl(
"pkeyutl -verify -pubin -inkey t/pubkey.pem -rawin "
"-in t/data.txt -sigfile t/data.sig"
)

shutil.rmtree("t")

# in practice at least OpenSSL 3.0.0 is needed to make EdDSA signatures
# earlier versions support EdDSA only in X.509 certificates
@pytest.mark.skipif(
"ed25519" not in OPENSSL_SUPPORTED_TYPES,
reason="system openssl does not support signing with Ed25519",
)
def test_to_openssl_ed25519(self):
return self.do_eddsa_test_to_openssl(Ed25519)

@pytest.mark.skipif(
"ed448" not in OPENSSL_SUPPORTED_TYPES,
reason="system openssl does not support signing with Ed448",
)
def test_to_openssl_ed448(self):
return self.do_eddsa_test_to_openssl(Ed448)

def do_eddsa_test_from_openssl(self, curve):
curvename = curve.name

if os.path.isdir("t"):
shutil.rmtree("t")
os.mkdir("t")

data = b"data"

run_openssl(
"genpkey -algorithm {0} -outform PEM -out t/privkey.pem".format(
curvename
)
)
run_openssl(
"pkey -outform PEM -pubout -in t/privkey.pem -out t/pubkey.pem"
)

with open("t/data.txt", "wb") as e:
e.write(data)
run_openssl(
"pkeyutl -sign -inkey t/privkey.pem "
"-rawin -in t/data.txt -out t/data.sig"
)

with open("t/data.sig", "rb") as e:
sig = e.read()
with open("t/pubkey.pem", "rb") as e:
vk = VerifyingKey.from_pem(e.read())

self.assertIs(vk.curve, curve)

vk.verify(sig, data)

shutil.rmtree("t")

@pytest.mark.skipif(
"ed25519" not in OPENSSL_SUPPORTED_TYPES,
reason="system openssl does not support signing with Ed25519",
)
def test_from_openssl_ed25519(self):
return self.do_eddsa_test_from_openssl(Ed25519)

@pytest.mark.skipif(
"ed448" not in OPENSSL_SUPPORTED_TYPES,
reason="system openssl does not support signing with Ed448",
)
def test_from_openssl_ed448(self):
return self.do_eddsa_test_from_openssl(Ed448)


class TooSmallCurve(unittest.TestCase):
OPENSSL_SUPPORTED_CURVES = set(
Expand Down

0 comments on commit ef01e3b

Please sign in to comment.