From f22f61234470bd5c86c80ae409b2698d2a2da1a5 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 5 Aug 2015 12:57:13 +0100 Subject: add SubjectKeyIdentifier.create_from_public_key --- src/cryptography/x509.py | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'src') 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): -- cgit v1.2.3 From d4a7f062d7dc9330fb701086dd06ac81a5b1e3d5 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 5 Aug 2015 18:32:18 +0100 Subject: rename to classmethod to from_public_key --- src/cryptography/x509.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index b58166f6..6c9cd562 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -682,7 +682,7 @@ class SubjectKeyIdentifier(object): self._digest = digest @classmethod - def create_from_public_key(cls, public_key): + def from_public_key(cls, public_key): # This is a very slow way to do this. serialized = public_key.public_bytes( serialization.Encoding.DER, -- cgit v1.2.3 From 73cd392198ed800dcd20f67d838f8a451e2bdf8c Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 7 Aug 2015 14:08:01 -0500 Subject: assert not remaining in SKI classmethod --- src/cryptography/x509.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 6c9cd562..f54eccf4 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -691,6 +691,7 @@ class SubjectKeyIdentifier(object): 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, hex it, then decode the hex. -- cgit v1.2.3 From 679e8f5b825be0d4f6c5ee77bff639efcaeac873 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 8 Aug 2015 09:59:48 -0500 Subject: refactor integer to bytes as utils.int_to_bytes --- src/cryptography/utils.py | 13 +++++++++++++ src/cryptography/x509.py | 6 +----- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index 24afe612..4ca4a7a2 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,18 @@ else: return result +if hasattr(int, "to_bytes"): + int_to_bytes = int.to_bytes +else: + def int_to_bytes(integer, byteorder, signed=False): + assert byteorder == 'big' + assert not signed + + 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 f54eccf4..3fff218a 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -5,7 +5,6 @@ from __future__ import absolute_import, division, print_function import abc -import binascii import datetime import hashlib import ipaddress @@ -699,10 +698,7 @@ class SubjectKeyIdentifier(object): 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))) + data = utils.int_to_bytes(bits, "big") return cls(hashlib.sha1(data).digest()) digest = utils.read_only_property("_digest") -- cgit v1.2.3 From dbd47de45a7dd40ea1e2d1bc941ee07ddf6b1a59 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 8 Aug 2015 10:29:39 -0500 Subject: update comment --- src/cryptography/x509.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 3fff218a..3254f26f 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -693,7 +693,7 @@ class SubjectKeyIdentifier(object): 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, hex it, then decode the hex. + # build an integer and convert that to bytes. bits = 0 for bit in spki.getComponentByName("subjectPublicKey"): bits = bits << 1 | bit -- cgit v1.2.3 From a39e3d165bfc3e4dd94a80d8ff17af356113d918 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 8 Aug 2015 11:10:32 -0500 Subject: py3 int.to_bytes is dead to me --- src/cryptography/utils.py | 14 ++++---------- src/cryptography/x509.py | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index 4ca4a7a2..993571bd 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -47,16 +47,10 @@ else: return result -if hasattr(int, "to_bytes"): - int_to_bytes = int.to_bytes -else: - def int_to_bytes(integer, byteorder, signed=False): - assert byteorder == 'big' - assert not signed - - hex_string = '%x' % integer - n = len(hex_string) - return binascii.unhexlify(hex_string.zfill(n + (n & 1))) +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): diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 3254f26f..82b8bd36 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -698,7 +698,7 @@ class SubjectKeyIdentifier(object): for bit in spki.getComponentByName("subjectPublicKey"): bits = bits << 1 | bit - data = utils.int_to_bytes(bits, "big") + data = utils.int_to_bytes(bits) return cls(hashlib.sha1(data).digest()) digest = utils.read_only_property("_digest") -- cgit v1.2.3