aboutsummaryrefslogtreecommitdiffstats
path: root/src/cryptography
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2019-07-06 19:01:33 -0400
committerAlex Gaynor <alex.gaynor@gmail.com>2019-07-06 19:01:33 -0400
commit7b1391bfd4949140432bd003a8e43e32bfe968c5 (patch)
tree6bc6d5f26a767e47eb224a9d81224a2eea82986a /src/cryptography
parent7c2cec85975d8bc79ff09af92d7d7d7077c7b18f (diff)
downloadcryptography-7b1391bfd4949140432bd003a8e43e32bfe968c5.tar.gz
cryptography-7b1391bfd4949140432bd003a8e43e32bfe968c5.tar.bz2
cryptography-7b1391bfd4949140432bd003a8e43e32bfe968c5.zip
ed25519 support in x509 certificate builder (#4937)
* ed25519 support in x509 certificate builder This adds minimal ed25519 support. More to come. * Apply suggestions from code review Co-Authored-By: Alex Gaynor <alex.gaynor@gmail.com>
Diffstat (limited to 'src/cryptography')
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py18
-rw-r--r--src/cryptography/x509/base.py7
-rw-r--r--src/cryptography/x509/oid.py5
3 files changed, 23 insertions, 7 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index ca0a11bd..c24d334a 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -798,7 +798,12 @@ class Backend(object):
def create_x509_certificate(self, builder, private_key, algorithm):
if not isinstance(builder, x509.CertificateBuilder):
raise TypeError('Builder type mismatch.')
- if not isinstance(algorithm, hashes.HashAlgorithm):
+ if isinstance(private_key, ed25519.Ed25519PrivateKey):
+ if algorithm is not None:
+ raise ValueError(
+ "algorithm must be None when signing via ed25519"
+ )
+ elif not isinstance(algorithm, hashes.HashAlgorithm):
raise TypeError('Algorithm must be a registered hash algorithm.')
if (
@@ -806,11 +811,11 @@ class Backend(object):
isinstance(private_key, rsa.RSAPrivateKey)
):
raise ValueError(
- "MD5 is not a supported hash algorithm for EC/DSA certificates"
+ "MD5 is only (reluctantly) supported for RSA certificates"
)
# Resolve the signature algorithm.
- evp_md = self._evp_md_non_null_from_algorithm(algorithm)
+ evp_md = self._evp_md_x509_null_if_ed25519(private_key, algorithm)
# Create an empty certificate.
x509_cert = self._lib.X509_new()
@@ -878,6 +883,13 @@ 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
+ return self._ffi.NULL
+ else:
+ return self._evp_md_non_null_from_algorithm(algorithm)
+
def _set_asn1_time(self, asn1_time, time):
if time.year >= 2050:
asn1_str = time.strftime('%Y%m%d%H%M%SZ').encode('ascii')
diff --git a/src/cryptography/x509/base.py b/src/cryptography/x509/base.py
index 63c2e3c6..dc7eee94 100644
--- a/src/cryptography/x509/base.py
+++ b/src/cryptography/x509/base.py
@@ -12,7 +12,7 @@ from enum import Enum
import six
from cryptography import utils
-from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa
+from cryptography.hazmat.primitives.asymmetric import dsa, ec, ed25519, rsa
from cryptography.x509.extensions import Extension, ExtensionType
from cryptography.x509.name import Name
@@ -474,9 +474,10 @@ class CertificateBuilder(object):
Sets the requestor's public key (as found in the signing request).
"""
if not isinstance(key, (dsa.DSAPublicKey, rsa.RSAPublicKey,
- ec.EllipticCurvePublicKey)):
+ ec.EllipticCurvePublicKey,
+ ed25519.Ed25519PublicKey)):
raise TypeError('Expecting one of DSAPublicKey, RSAPublicKey,'
- ' or EllipticCurvePublicKey.')
+ ' EllipticCurvePublicKey, or Ed25519PublicKey.')
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/oid.py b/src/cryptography/x509/oid.py
index 1bfe58ca..ab01d67b 100644
--- a/src/cryptography/x509/oid.py
+++ b/src/cryptography/x509/oid.py
@@ -96,6 +96,7 @@ class SignatureAlgorithmOID(object):
DSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10040.4.3")
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")
_SIG_OIDS_TO_HASH = {
@@ -113,7 +114,8 @@ _SIG_OIDS_TO_HASH = {
SignatureAlgorithmOID.ECDSA_WITH_SHA512: hashes.SHA512(),
SignatureAlgorithmOID.DSA_WITH_SHA1: hashes.SHA1(),
SignatureAlgorithmOID.DSA_WITH_SHA224: hashes.SHA224(),
- SignatureAlgorithmOID.DSA_WITH_SHA256: hashes.SHA256()
+ SignatureAlgorithmOID.DSA_WITH_SHA256: hashes.SHA256(),
+ SignatureAlgorithmOID.ED25519: None,
}
@@ -181,6 +183,7 @@ _OID_NAMES = {
SignatureAlgorithmOID.DSA_WITH_SHA1: "dsa-with-sha1",
SignatureAlgorithmOID.DSA_WITH_SHA224: "dsa-with-sha224",
SignatureAlgorithmOID.DSA_WITH_SHA256: "dsa-with-sha256",
+ SignatureAlgorithmOID.ED25519: "ed25519",
ExtendedKeyUsageOID.SERVER_AUTH: "serverAuth",
ExtendedKeyUsageOID.CLIENT_AUTH: "clientAuth",
ExtendedKeyUsageOID.CODE_SIGNING: "codeSigning",