diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cryptography/x509.py | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 978eb560..b58166f6 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -5,22 +5,34 @@ from __future__ import absolute_import, division, print_function import abc +import binascii import datetime +import hashlib import ipaddress from email.utils import parseaddr from enum import Enum import idna +from pyasn1.codec.der import decoder +from pyasn1.type import namedtype, univ + import six from six.moves import urllib_parse from cryptography import utils -from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa +class _SubjectPublicKeyInfo(univ.Sequence): + componentType = namedtype.NamedTypes( + namedtype.NamedType('algorithm', univ.Sequence()), + namedtype.NamedType('subjectPublicKey', univ.BitString()) + ) + + _OID_NAMES = { "2.5.4.3": "commonName", "2.5.4.6": "countryName", @@ -669,6 +681,29 @@ class SubjectKeyIdentifier(object): def __init__(self, digest): self._digest = digest + @classmethod + def create_from_public_key(cls, 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() + ) + # 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, hex it, then decode the hex. + bits = 0 + for bit in spki.getComponentByName("subjectPublicKey"): + bits = bits << 1 | bit + + # convert the integer to bytes + hex_string = '%x' % bits + n = len(hex_string) + data = binascii.unhexlify(hex_string.zfill(n + (n & 1))) + return cls(hashlib.sha1(data).digest()) + digest = utils.read_only_property("_digest") def __repr__(self): |