From beb25516644666c058d6d4ee83a87148a06e78d0 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 27 Mar 2016 16:39:49 -0400 Subject: Fixes #2856 -- add a fast path to _key_identifier_from_public_key for RSA keys --- src/cryptography/x509/extensions.py | 42 ++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py index 87d2de1c..b3c007cd 100644 --- a/src/cryptography/x509/extensions.py +++ b/src/cryptography/x509/extensions.py @@ -17,6 +17,7 @@ import six from cryptography import utils from cryptography.hazmat.primitives import constant_time, serialization +from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey from cryptography.x509.general_name import GeneralName, IPAddress, OtherName from cryptography.x509.name import Name from cryptography.x509.oid import ( @@ -32,23 +33,30 @@ class _SubjectPublicKeyInfo(univ.Sequence): def _key_identifier_from_public_key(public_key): - # This is a very slow way to do this. - serialized = public_key.public_bytes( - serialization.Encoding.DER, - serialization.PublicFormat.SubjectPublicKeyInfo - ) - spki, remaining = decoder.decode( - serialized, asn1Spec=_SubjectPublicKeyInfo() - ) - assert not remaining - # the univ.BitString object is a tuple of bits. We need bytes and - # pyasn1 really doesn't want to give them to us. To get it we'll - # build an integer and convert that to bytes. - bits = 0 - for bit in spki.getComponentByName("subjectPublicKey"): - bits = bits << 1 | bit - - data = utils.int_to_bytes(bits) + if isinstance(public_key, RSAPublicKey): + data = public_key.public_bytes( + serialization.Encoding.DER, + serialization.PublicFormat.PKCS1, + ) + else: + # This is a very slow way to do this. + serialized = public_key.public_bytes( + serialization.Encoding.DER, + serialization.PublicFormat.SubjectPublicKeyInfo + ) + spki, remaining = decoder.decode( + serialized, asn1Spec=_SubjectPublicKeyInfo() + ) + assert not remaining + # the univ.BitString object is a tuple of bits. We need bytes and + # pyasn1 really doesn't want to give them to us. To get it we'll + # build an integer and convert that to bytes. + bits = 0 + for bit in spki.getComponentByName("subjectPublicKey"): + bits = bits << 1 | bit + + data = utils.int_to_bytes(bits) + return hashlib.sha1(data).digest() -- cgit v1.2.3 From 01c704992dd6b4bcb04c9760aa2a024979ef6d13 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 27 Mar 2016 17:00:59 -0400 Subject: Added a special case for EC as well --- src/cryptography/x509/extensions.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py index b3c007cd..b7ea72cd 100644 --- a/src/cryptography/x509/extensions.py +++ b/src/cryptography/x509/extensions.py @@ -17,6 +17,7 @@ import six from cryptography import utils from cryptography.hazmat.primitives import constant_time, serialization +from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePublicKey from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey from cryptography.x509.general_name import GeneralName, IPAddress, OtherName from cryptography.x509.name import Name @@ -38,6 +39,8 @@ def _key_identifier_from_public_key(public_key): serialization.Encoding.DER, serialization.PublicFormat.PKCS1, ) + elif isinstance(public_key, EllipticCurvePublicKey): + data = public_key.public_numbers().encode_point() else: # This is a very slow way to do this. serialized = public_key.public_bytes( -- cgit v1.2.3