aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarko Kreen <markokr@gmail.com>2019-09-09 02:44:02 +0300
committerPaul Kehrer <paul.l.kehrer@gmail.com>2019-09-09 07:44:02 +0800
commitf7c77712d6611dc72cb2ef6fb1fe72fee4ab88de (patch)
tree7ff0841b1c2e9b29737874ff76c215de50ce0ee0 /src
parentc918fef88670fc46433d3edd91957231c654ff05 (diff)
downloadcryptography-f7c77712d6611dc72cb2ef6fb1fe72fee4ab88de.tar.gz
cryptography-f7c77712d6611dc72cb2ef6fb1fe72fee4ab88de.tar.bz2
cryptography-f7c77712d6611dc72cb2ef6fb1fe72fee4ab88de.zip
Finish ed25519 and ed448 support in x509 module (#4972)
* Support ed25519 in csr/crl creation * Tests for ed25519/x509 * Support ed448 in crt/csr/crl creation * Tests for ed448/x509 * Support ed25519/ed448 in OCSPResponseBuilder * Tests for eddsa in OCSPResponseBuilder * Builder check missing in create_x509_csr * Documentation update for ed25519+ed448 in x509
Diffstat (limited to 'src')
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py46
-rw-r--r--src/cryptography/x509/base.py10
-rw-r--r--src/cryptography/x509/ocsp.py9
-rw-r--r--src/cryptography/x509/oid.py3
4 files changed, 50 insertions, 18 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index eb6654b0..7e9fa202 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -74,7 +74,9 @@ from cryptography.hazmat.backends.openssl.x509 import (
)
from cryptography.hazmat.bindings.openssl import binding
from cryptography.hazmat.primitives import hashes, serialization
-from cryptography.hazmat.primitives.asymmetric import dsa, ec, ed25519, rsa
+from cryptography.hazmat.primitives.asymmetric import (
+ dsa, ec, ed25519, ed448, rsa
+)
from cryptography.hazmat.primitives.asymmetric.padding import (
MGF1, OAEP, PKCS1v15, PSS
)
@@ -722,10 +724,18 @@ class Backend(object):
return _CMACContext(self, algorithm)
def create_x509_csr(self, builder, private_key, algorithm):
- if not isinstance(algorithm, hashes.HashAlgorithm):
- raise TypeError('Algorithm must be a registered hash algorithm.')
+ if not isinstance(builder, x509.CertificateSigningRequestBuilder):
+ raise TypeError('Builder type mismatch.')
- if (
+ if isinstance(private_key,
+ (ed25519.Ed25519PrivateKey, ed448.Ed448PrivateKey)):
+ if algorithm is not None:
+ raise ValueError(
+ "algorithm must be None when signing via ed25519 or ed448"
+ )
+ elif not isinstance(algorithm, hashes.HashAlgorithm):
+ raise TypeError('Algorithm must be a registered hash algorithm.')
+ elif (
isinstance(algorithm, hashes.MD5) and not
isinstance(private_key, rsa.RSAPrivateKey)
):
@@ -734,7 +744,7 @@ class Backend(object):
)
# Resolve the signature algorithm.
- evp_md = self._evp_md_non_null_from_algorithm(algorithm)
+ evp_md = self._evp_md_x509_null_if_eddsa(private_key, algorithm)
# Create an empty request.
x509_req = self._lib.X509_REQ_new()
@@ -801,10 +811,11 @@ class Backend(object):
def create_x509_certificate(self, builder, private_key, algorithm):
if not isinstance(builder, x509.CertificateBuilder):
raise TypeError('Builder type mismatch.')
- if isinstance(private_key, ed25519.Ed25519PrivateKey):
+ if isinstance(private_key,
+ (ed25519.Ed25519PrivateKey, ed448.Ed448PrivateKey)):
if algorithm is not None:
raise ValueError(
- "algorithm must be None when signing via ed25519"
+ "algorithm must be None when signing via ed25519 or ed448"
)
elif not isinstance(algorithm, hashes.HashAlgorithm):
raise TypeError('Algorithm must be a registered hash algorithm.')
@@ -818,7 +829,7 @@ class Backend(object):
)
# Resolve the signature algorithm.
- evp_md = self._evp_md_x509_null_if_ed25519(private_key, algorithm)
+ evp_md = self._evp_md_x509_null_if_eddsa(private_key, algorithm)
# Create an empty certificate.
x509_cert = self._lib.X509_new()
@@ -886,9 +897,10 @@ class Backend(object):
return _Certificate(self, x509_cert)
- def _evp_md_x509_null_if_ed25519(self, private_key, algorithm):
- if isinstance(private_key, ed25519.Ed25519PrivateKey):
- # OpenSSL requires us to pass NULL for EVP_MD for ed25519 signing
+ def _evp_md_x509_null_if_eddsa(self, private_key, algorithm):
+ if isinstance(private_key,
+ (ed25519.Ed25519PrivateKey, ed448.Ed448PrivateKey)):
+ # OpenSSL requires us to pass NULL for EVP_MD for ed25519/ed448
return self._ffi.NULL
else:
return self._evp_md_non_null_from_algorithm(algorithm)
@@ -911,7 +923,13 @@ class Backend(object):
def create_x509_crl(self, builder, private_key, algorithm):
if not isinstance(builder, x509.CertificateRevocationListBuilder):
raise TypeError('Builder type mismatch.')
- if not isinstance(algorithm, hashes.HashAlgorithm):
+ if isinstance(private_key,
+ (ed25519.Ed25519PrivateKey, ed448.Ed448PrivateKey)):
+ if algorithm is not None:
+ raise ValueError(
+ "algorithm must be None when signing via ed25519 or ed448"
+ )
+ elif not isinstance(algorithm, hashes.HashAlgorithm):
raise TypeError('Algorithm must be a registered hash algorithm.')
if (
@@ -922,7 +940,7 @@ class Backend(object):
"MD5 is not a supported hash algorithm for EC/DSA CRLs"
)
- evp_md = self._evp_md_non_null_from_algorithm(algorithm)
+ evp_md = self._evp_md_x509_null_if_eddsa(private_key, algorithm)
# Create an empty CRL.
x509_crl = self._lib.X509_CRL_new()
@@ -1578,7 +1596,7 @@ class Backend(object):
)
self.openssl_assert(res != self._ffi.NULL)
# okay, now sign the basic structure
- evp_md = self._evp_md_non_null_from_algorithm(algorithm)
+ evp_md = self._evp_md_x509_null_if_eddsa(private_key, algorithm)
responder_cert, responder_encoding = builder._responder_id
flags = self._lib.OCSP_NOCERTS
if responder_encoding is ocsp.OCSPResponderEncoding.HASH:
diff --git a/src/cryptography/x509/base.py b/src/cryptography/x509/base.py
index dc7eee94..3983c9b3 100644
--- a/src/cryptography/x509/base.py
+++ b/src/cryptography/x509/base.py
@@ -12,7 +12,9 @@ from enum import Enum
import six
from cryptography import utils
-from cryptography.hazmat.primitives.asymmetric import dsa, ec, ed25519, rsa
+from cryptography.hazmat.primitives.asymmetric import (
+ dsa, ec, ed25519, ed448, rsa
+)
from cryptography.x509.extensions import Extension, ExtensionType
from cryptography.x509.name import Name
@@ -475,9 +477,11 @@ class CertificateBuilder(object):
"""
if not isinstance(key, (dsa.DSAPublicKey, rsa.RSAPublicKey,
ec.EllipticCurvePublicKey,
- ed25519.Ed25519PublicKey)):
+ ed25519.Ed25519PublicKey,
+ ed448.Ed448PublicKey)):
raise TypeError('Expecting one of DSAPublicKey, RSAPublicKey,'
- ' EllipticCurvePublicKey, or Ed25519PublicKey.')
+ ' EllipticCurvePublicKey, Ed25519PublicKey or'
+ ' Ed448PublicKey.')
if self._public_key is not None:
raise ValueError('The public key may only be set once.')
return CertificateBuilder(
diff --git a/src/cryptography/x509/ocsp.py b/src/cryptography/x509/ocsp.py
index aae9b626..b15063d1 100644
--- a/src/cryptography/x509/ocsp.py
+++ b/src/cryptography/x509/ocsp.py
@@ -12,6 +12,7 @@ import six
from cryptography import x509
from cryptography.hazmat.primitives import hashes
+from cryptography.hazmat.primitives.asymmetric import ed25519, ed448
from cryptography.x509.base import (
_EARLIEST_UTC_TIME, _convert_to_naive_utc_time, _reject_duplicate_extension
)
@@ -241,7 +242,13 @@ class OCSPResponseBuilder(object):
if self._responder_id is None:
raise ValueError("You must add a responder_id before signing")
- if not isinstance(algorithm, hashes.HashAlgorithm):
+ if isinstance(private_key,
+ (ed25519.Ed25519PrivateKey, ed448.Ed448PrivateKey)):
+ if algorithm is not None:
+ raise ValueError(
+ "algorithm must be None when signing via ed25519 or ed448"
+ )
+ elif not isinstance(algorithm, hashes.HashAlgorithm):
raise TypeError("Algorithm must be a registered hash algorithm.")
return backend.create_ocsp_response(
diff --git a/src/cryptography/x509/oid.py b/src/cryptography/x509/oid.py
index ab01d67b..c1e5dc53 100644
--- a/src/cryptography/x509/oid.py
+++ b/src/cryptography/x509/oid.py
@@ -97,6 +97,7 @@ class SignatureAlgorithmOID(object):
DSA_WITH_SHA224 = ObjectIdentifier("2.16.840.1.101.3.4.3.1")
DSA_WITH_SHA256 = ObjectIdentifier("2.16.840.1.101.3.4.3.2")
ED25519 = ObjectIdentifier("1.3.101.112")
+ ED448 = ObjectIdentifier("1.3.101.113")
_SIG_OIDS_TO_HASH = {
@@ -116,6 +117,7 @@ _SIG_OIDS_TO_HASH = {
SignatureAlgorithmOID.DSA_WITH_SHA224: hashes.SHA224(),
SignatureAlgorithmOID.DSA_WITH_SHA256: hashes.SHA256(),
SignatureAlgorithmOID.ED25519: None,
+ SignatureAlgorithmOID.ED448: None,
}
@@ -184,6 +186,7 @@ _OID_NAMES = {
SignatureAlgorithmOID.DSA_WITH_SHA224: "dsa-with-sha224",
SignatureAlgorithmOID.DSA_WITH_SHA256: "dsa-with-sha256",
SignatureAlgorithmOID.ED25519: "ed25519",
+ SignatureAlgorithmOID.ED448: "ed448",
ExtendedKeyUsageOID.SERVER_AUTH: "serverAuth",
ExtendedKeyUsageOID.CLIENT_AUTH: "clientAuth",
ExtendedKeyUsageOID.CODE_SIGNING: "codeSigning",