diff options
author | Alex Gaynor <alex.gaynor@gmail.com> | 2015-08-08 12:57:48 -0400 |
---|---|---|
committer | Alex Gaynor <alex.gaynor@gmail.com> | 2015-08-08 12:57:48 -0400 |
commit | d5bf17ad99939920aa73e6d00a36818ecaf1c2cc (patch) | |
tree | d61e4033c163d5d0539122098d5422b8e568dd04 /src | |
parent | c9ee947f528269ea7a907a592219a788edf1a279 (diff) | |
parent | a39e3d165bfc3e4dd94a80d8ff17af356113d918 (diff) | |
download | cryptography-d5bf17ad99939920aa73e6d00a36818ecaf1c2cc.tar.gz cryptography-d5bf17ad99939920aa73e6d00a36818ecaf1c2cc.tar.bz2 cryptography-d5bf17ad99939920aa73e6d00a36818ecaf1c2cc.zip |
Merge pull request #2204 from reaperhulk/ski-classmethod
SubjectKeyIdentifier classmethod
Diffstat (limited to 'src')
-rw-r--r-- | src/cryptography/utils.py | 7 | ||||
-rw-r--r-- | src/cryptography/x509.py | 34 |
2 files changed, 40 insertions, 1 deletions
diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index 24afe612..993571bd 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -5,6 +5,7 @@ from __future__ import absolute_import, division, print_function import abc +import binascii import inspect import struct import sys @@ -46,6 +47,12 @@ else: return result +def int_to_bytes(integer): + hex_string = '%x' % integer + n = len(hex_string) + return binascii.unhexlify(hex_string.zfill(n + (n & 1))) + + class InterfaceNotImplemented(Exception): pass diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 45a302ba..5ed3c094 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -6,21 +6,32 @@ from __future__ import absolute_import, division, print_function import abc 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", @@ -697,6 +708,27 @@ class SubjectKeyIdentifier(object): def __init__(self, digest): self._digest = digest + @classmethod + def 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() + ) + 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 cls(hashlib.sha1(data).digest()) + digest = utils.read_only_property("_digest") def __repr__(self): |