aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2015-08-05 12:57:13 +0100
committerPaul Kehrer <paul.l.kehrer@gmail.com>2015-08-05 12:57:13 +0100
commitf22f61234470bd5c86c80ae409b2698d2a2da1a5 (patch)
tree1ce20e46595c9af7fe3e06e8d0c247f3fd4a7218 /src
parenteca59b7064be4c2e0b7f8255431060e271a7f67d (diff)
downloadcryptography-f22f61234470bd5c86c80ae409b2698d2a2da1a5.tar.gz
cryptography-f22f61234470bd5c86c80ae409b2698d2a2da1a5.tar.bz2
cryptography-f22f61234470bd5c86c80ae409b2698d2a2da1a5.zip
add SubjectKeyIdentifier.create_from_public_key
Diffstat (limited to 'src')
-rw-r--r--src/cryptography/x509.py37
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):