mirror of
https://github.com/saymrwulf/cryptography.git
synced 2026-05-14 20:37:55 +00:00
Add a bytes method to get the DER ASN.1 encoding of an X509 name. (#3236)
* Add a bytes method to get the DER ASN.1 encoding of an X509 name. This is useful for creating an OpenSSL style subject_name_hash (#3011) * add to backend interface and update multibackend * bytes -> public_bytes
This commit is contained in:
parent
d862933de5
commit
3a15b03e92
9 changed files with 65 additions and 0 deletions
|
|
@ -26,6 +26,7 @@ Changelog
|
|||
:meth:`~cryptography.x509.random_serial_number`.
|
||||
* Added support for encoding ``IPv4Network`` and ``IPv6Network`` in X.509
|
||||
certificates for use with :class:`~cryptography.x509.NameConstraints`.
|
||||
* Added :meth:`~cryptography.x509.Name.public_bytes`.
|
||||
* Added :class:`~cryptography.x509.RelativeDistinguishedName`
|
||||
* :class:`~cryptography.x509.DistributionPoint` now accepts
|
||||
:class:`~cryptography.x509.RelativeDistinguishedName` for
|
||||
|
|
|
|||
|
|
@ -585,6 +585,14 @@ A specific ``backend`` may provide one or more of these interfaces.
|
|||
:returns: A new instance of
|
||||
:class:`~cryptography.x509.RevokedCertificate`.
|
||||
|
||||
.. method:: x509_name_bytes(name)
|
||||
|
||||
.. versionadded:: 1.6
|
||||
|
||||
:param name: An instance of :class:`~cryptography.x509.Name`.
|
||||
|
||||
:return bytes: The DER encoded bytes.
|
||||
|
||||
.. class:: DHBackend
|
||||
|
||||
.. versionadded:: 0.9
|
||||
|
|
|
|||
|
|
@ -1142,6 +1142,16 @@ X.509 CSR (Certificate Signing Request) Builder Object
|
|||
>>> cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME)
|
||||
[<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commonName)>, value=u'Good CA')>]
|
||||
|
||||
.. method:: public_bytes(backend)
|
||||
|
||||
.. versionadded:: 1.6
|
||||
|
||||
:param backend: A backend supporting the
|
||||
:class:`~cryptography.hazmat.backends.interfaces.X509Backend`
|
||||
interface.
|
||||
|
||||
:return bytes: The DER encoded name.
|
||||
|
||||
.. class:: Version
|
||||
|
||||
.. versionadded:: 0.7
|
||||
|
|
|
|||
|
|
@ -312,6 +312,12 @@ class X509Backend(object):
|
|||
object.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def x509_name_bytes(self, name):
|
||||
"""
|
||||
Compute the DER encoded bytes of an X509 Name object.
|
||||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class DHBackend(object):
|
||||
|
|
|
|||
|
|
@ -424,6 +424,15 @@ class MultiBackend(object):
|
|||
_Reasons.UNSUPPORTED_X509
|
||||
)
|
||||
|
||||
def x509_name_bytes(self, name):
|
||||
for b in self._filtered_backends(X509Backend):
|
||||
return b.x509_name_bytes(name)
|
||||
|
||||
raise UnsupportedAlgorithm(
|
||||
"This backend does not support X.509.",
|
||||
_Reasons.UNSUPPORTED_X509
|
||||
)
|
||||
|
||||
def derive_scrypt(self, key_material, salt, length, n, r, p):
|
||||
for b in self._filtered_backends(ScryptBackend):
|
||||
return b.derive_scrypt(key_material, salt, length, n, r, p)
|
||||
|
|
|
|||
|
|
@ -1729,6 +1729,17 @@ class Backend(object):
|
|||
serialization._ssh_write_string(public_numbers.encode_point())
|
||||
)
|
||||
|
||||
def x509_name_bytes(self, name):
|
||||
x509_name = _encode_name_gc(self, name)
|
||||
pp = self._ffi.new("unsigned char **")
|
||||
res = self._lib.i2d_X509_NAME(x509_name, pp)
|
||||
self.openssl_assert(pp[0] != self._ffi.NULL)
|
||||
pp = self._ffi.gc(
|
||||
pp, lambda pointer: self._lib.OPENSSL_free(pointer[0])
|
||||
)
|
||||
self.openssl_assert(res > 0)
|
||||
return self._ffi.buffer(pp[0], res)[:]
|
||||
|
||||
def derive_scrypt(self, key_material, salt, length, n, r, p):
|
||||
buf = self._ffi.new("unsigned char[]", length)
|
||||
res = self._lib.EVP_PBE_scrypt(key_material, len(key_material), salt,
|
||||
|
|
|
|||
|
|
@ -109,6 +109,9 @@ class Name(object):
|
|||
def rdns(self):
|
||||
return self._attributes
|
||||
|
||||
def public_bytes(self, backend):
|
||||
return backend.x509_name_bytes(self)
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, Name):
|
||||
return NotImplemented
|
||||
|
|
|
|||
|
|
@ -240,6 +240,9 @@ class DummyX509Backend(object):
|
|||
def create_x509_revoked_certificate(self, builder):
|
||||
pass
|
||||
|
||||
def x509_name_bytes(self, name):
|
||||
pass
|
||||
|
||||
|
||||
@utils.register_interface(ScryptBackend)
|
||||
class DummyScryptBackend(object):
|
||||
|
|
@ -554,6 +557,7 @@ class TestMultiBackend(object):
|
|||
backend.create_x509_certificate(object(), b"privatekey", hashes.SHA1())
|
||||
backend.create_x509_crl(object(), b"privatekey", hashes.SHA1())
|
||||
backend.create_x509_revoked_certificate(object())
|
||||
backend.x509_name_bytes(object())
|
||||
|
||||
backend = MultiBackend([DummyBackend()])
|
||||
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_X509):
|
||||
|
|
@ -580,6 +584,8 @@ class TestMultiBackend(object):
|
|||
)
|
||||
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_X509):
|
||||
backend.create_x509_revoked_certificate(object())
|
||||
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_X509):
|
||||
backend.x509_name_bytes(object())
|
||||
|
||||
def test_scrypt(self):
|
||||
backend = MultiBackend([DummyScryptBackend()])
|
||||
|
|
|
|||
|
|
@ -3842,6 +3842,17 @@ class TestName(object):
|
|||
with pytest.raises(TypeError):
|
||||
x509.Name(["not-a-NameAttribute"])
|
||||
|
||||
@pytest.mark.requires_backend_interface(interface=X509Backend)
|
||||
def test_bytes(self, backend):
|
||||
name = x509.Name([
|
||||
x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
|
||||
x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
|
||||
])
|
||||
assert name.public_bytes(backend) == binascii.unhexlify(
|
||||
b"30293118301606035504030c0f63727970746f6772617068792e696f310d300"
|
||||
b"b060355040a0c0450794341"
|
||||
)
|
||||
|
||||
|
||||
def test_random_serial_number(monkeypatch):
|
||||
sample_data = os.urandom(20)
|
||||
|
|
|
|||
Loading…
Reference in a new issue