aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.rst2
-rw-r--r--docs/spelling_wordlist.txt1
-rw-r--r--docs/x509.rst15
-rw-r--r--src/cryptography/hazmat/backends/openssl/x509.py12
-rw-r--r--src/cryptography/x509.py23
-rw-r--r--tests/test_x509.py18
6 files changed, 55 insertions, 16 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index df78acd3..f903b7f9 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -9,7 +9,7 @@ Changelog
* :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_key` can
now load elliptic curve public keys.
* Added
- :attr:`~cryptography.x509.Certificate.signature_algorithm` support to
+ :attr:`~cryptography.x509.Certificate.signature_hash_algorithm` support to
:class:`~cryptography.x509.Certificate`.
* Added
:func:`~cryptography.hazmat.primitives.asymmetric.rsa.rsa_recover_prime_factors`
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index fefd26b3..ddd37897 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -51,3 +51,4 @@ Ubuntu
unencrypted
unpadded
unpadding
+Verisign
diff --git a/docs/x509.rst b/docs/x509.rst
index 8043b367..193b8452 100644
--- a/docs/x509.rst
+++ b/docs/x509.rst
@@ -182,18 +182,19 @@ X.509 Certificate Object
The :class:`Name` of the subject.
- .. attribute:: signature_algorithm
+ .. attribute:: signature_hash_algorithm
- :type: :class:`ObjectIdentifier`
+ :type: :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`
- An :class:`ObjectIdentifier` instance corresponding to the signature
- algorithm used to sign the certificate. This is both the digest
- used as well as the asymmetric type.
+ A :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`
+ corresponding to the hash algorithm used within the certificate
+ signature.
.. doctest::
- >>> cert.signature_algorithm
- <ObjectIdentifier(oid=1.2.840.113549.1.1.11, name=sha256WithRSAEncryption)>
+ >>> from cryptography.hazmat.primitives import hashes
+ >>> isinstance(cert.signature_hash_algorithm, hashes.SHA256)
+ True
.. class:: Name
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index a3dddc49..989a9dd7 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -16,6 +16,7 @@ from __future__ import absolute_import, division, print_function
import datetime
from cryptography import utils, x509
+from cryptography.exceptions import UnsupportedAlgorithm
from cryptography.hazmat.primitives import hashes
@@ -138,7 +139,16 @@ class _Certificate(object):
return x509.Name(attributes)
@property
- def signature_algorithm(self):
+ def signature_hash_algorithm(self):
+ oid = self._signature_algorithm()
+ try:
+ return x509._SIG_OIDS_TO_HASH[oid.dotted_string]
+ except KeyError:
+ raise UnsupportedAlgorithm(
+ "Signature algorithm {0} not recognized".format(oid)
+ )
+
+ def _signature_algorithm(self):
buf_len = 50
buf = self._backend._ffi.new("char[]", buf_len)
res = self._backend._lib.OBJ_obj2txt(
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index c4d87bb7..c6ce61d1 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -10,6 +10,7 @@ from enum import Enum
import six
from cryptography import utils
+from cryptography.hazmat.primitives import hashes
_OID_NAMES = {
@@ -170,6 +171,22 @@ OID_DSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10040.4.3")
OID_DSA_WITH_SHA224 = ObjectIdentifier("2.16.840.1.101.3.4.3.1")
OID_DSA_WITH_SHA256 = ObjectIdentifier("2.16.840.1.101.3.4.3.2")
+_SIG_OIDS_TO_HASH = {
+ "1.2.840.113549.1.1.4": hashes.MD5(),
+ "1.2.840.113549.1.1.5": hashes.SHA1(),
+ "1.2.840.113549.1.1.14": hashes.SHA224(),
+ "1.2.840.113549.1.1.11": hashes.SHA256(),
+ "1.2.840.113549.1.1.12": hashes.SHA384(),
+ "1.2.840.113549.1.1.13": hashes.SHA512(),
+ "1.2.840.10045.4.3.1": hashes.SHA224(),
+ "1.2.840.10045.4.3.2": hashes.SHA256(),
+ "1.2.840.10045.4.3.3": hashes.SHA384(),
+ "1.2.840.10045.4.3.4": hashes.SHA512(),
+ "1.2.840.10040.4.3": hashes.SHA1(),
+ "2.16.840.1.101.3.4.3.1": hashes.SHA224(),
+ "2.16.840.1.101.3.4.3.2": hashes.SHA256()
+}
+
@six.add_metaclass(abc.ABCMeta)
class Certificate(object):
@@ -222,8 +239,8 @@ class Certificate(object):
"""
@abc.abstractproperty
- def signature_algorithm(self):
+ def signature_hash_algorithm(self):
"""
- Returns an ObjectIdentifier corresponding to the signature algorithm of
- the certificate.
+ Returns a HashAlgorithm corresponding to the type of the digest signed
+ in the certificate.
"""
diff --git a/tests/test_x509.py b/tests/test_x509.py
index 613263d1..8f00eeed 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -13,6 +13,7 @@ import pytest
import six
from cryptography import x509
+from cryptography.exceptions import UnsupportedAlgorithm
from cryptography.hazmat.backends.interfaces import (
DSABackend, EllipticCurveBackend, RSABackend, X509Backend
)
@@ -45,7 +46,7 @@ class TestRSACertificate(object):
assert cert.serial == 11559813051657483483
fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
assert fingerprint == b"2b619ed04bfc9c3b08eb677d272192286a0947a8"
- assert cert.signature_algorithm == x509.OID_SHA1_WITH_RSA
+ assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
def test_load_der_cert(self, backend):
cert = _load_cert(
@@ -57,7 +58,7 @@ class TestRSACertificate(object):
assert cert.serial == 2
fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
- assert cert.signature_algorithm == x509.OID_SHA256_WITH_RSA
+ assert isinstance(cert.signature_hash_algorithm, hashes.SHA256)
def test_issuer(self, backend):
cert = _load_cert(
@@ -330,6 +331,15 @@ class TestRSACertificate(object):
with pytest.raises(ValueError):
x509.load_der_x509_certificate(b"notacert", backend)
+ def test_unsupported_signature_hash_algorithm_cert(self, backend):
+ cert = _load_cert(
+ os.path.join("x509", "verisign_md2_root.pem"),
+ x509.load_pem_x509_certificate,
+ backend
+ )
+ with pytest.raises(UnsupportedAlgorithm):
+ cert.signature_hash_algorithm
+
@pytest.mark.requires_backend_interface(interface=DSABackend)
@pytest.mark.requires_backend_interface(interface=X509Backend)
@@ -340,7 +350,7 @@ class TestDSACertificate(object):
x509.load_pem_x509_certificate,
backend
)
- assert cert.signature_algorithm == x509.OID_DSA_WITH_SHA1
+ assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
public_key = cert.public_key()
assert isinstance(public_key, interfaces.DSAPublicKey)
if isinstance(public_key, interfaces.DSAPublicKeyWithNumbers):
@@ -393,7 +403,7 @@ class TestECDSACertificate(object):
x509.load_pem_x509_certificate,
backend
)
- assert cert.signature_algorithm == x509.OID_ECDSA_WITH_SHA384
+ assert isinstance(cert.signature_hash_algorithm, hashes.SHA384)
public_key = cert.public_key()
assert isinstance(public_key, interfaces.EllipticCurvePublicKey)
if isinstance(