aboutsummaryrefslogtreecommitdiffstats
path: root/cryptography
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2014-09-26 15:43:47 -0500
committerPaul Kehrer <paul.l.kehrer@gmail.com>2014-09-26 15:43:47 -0500
commit58f63ed781b73478ee3fe60ebe1cfdfd85df5186 (patch)
tree32673233373345e277af0176a46351841e46d0c1 /cryptography
parent0520a2512d461b100ce1988ad094f76a219528b5 (diff)
parentebba1b0db3975c81742e8092619133fe2349124e (diff)
downloadcryptography-58f63ed781b73478ee3fe60ebe1cfdfd85df5186.tar.gz
cryptography-58f63ed781b73478ee3fe60ebe1cfdfd85df5186.tar.bz2
cryptography-58f63ed781b73478ee3fe60ebe1cfdfd85df5186.zip
Merge pull request #1331 from michael-hart/public_key_pem
Add support for .PEM public keys, with tests and docs
Diffstat (limited to 'cryptography')
-rw-r--r--cryptography/hazmat/backends/interfaces.py8
-rw-r--r--cryptography/hazmat/backends/multibackend.py9
-rw-r--r--cryptography/hazmat/backends/openssl/backend.py35
-rw-r--r--cryptography/hazmat/primitives/serialization.py4
4 files changed, 55 insertions, 1 deletions
diff --git a/cryptography/hazmat/backends/interfaces.py b/cryptography/hazmat/backends/interfaces.py
index 3761e254..dc720ad3 100644
--- a/cryptography/hazmat/backends/interfaces.py
+++ b/cryptography/hazmat/backends/interfaces.py
@@ -281,6 +281,12 @@ class PEMSerializationBackend(object):
if the data is encrypted.
"""
+ @abc.abstractmethod
+ def load_pem_public_key(self, data):
+ """
+ Loads a public key from PEM encoded data.
+ """
+
@six.add_metaclass(abc.ABCMeta)
class TraditionalOpenSSLSerializationBackend(object):
@@ -297,6 +303,6 @@ class PKCS8SerializationBackend(object):
@abc.abstractmethod
def load_pkcs8_pem_private_key(self, data, password):
"""
- Load a private key from PEM encoded data, using password if the data
+ Load a private key from PKCS8 encoded data, using password if the data
is encrypted.
"""
diff --git a/cryptography/hazmat/backends/multibackend.py b/cryptography/hazmat/backends/multibackend.py
index 221f1a1e..163dd0ee 100644
--- a/cryptography/hazmat/backends/multibackend.py
+++ b/cryptography/hazmat/backends/multibackend.py
@@ -329,6 +329,15 @@ class MultiBackend(object):
_Reasons.UNSUPPORTED_SERIALIZATION
)
+ def load_pem_public_key(self, data):
+ for b in self._filtered_backends(PEMSerializationBackend):
+ return b.load_pem_public_key(data)
+
+ raise UnsupportedAlgorithm(
+ "This backend does not support this key serialization.",
+ _Reasons.UNSUPPORTED_SERIALIZATION
+ )
+
def load_pkcs8_pem_private_key(self, data, password):
for b in self._filtered_backends(PKCS8SerializationBackend):
return b.load_pkcs8_pem_private_key(data, password)
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py
index cb988ac9..0b129d1a 100644
--- a/cryptography/hazmat/backends/openssl/backend.py
+++ b/cryptography/hazmat/backends/openssl/backend.py
@@ -483,6 +483,33 @@ class Backend(object):
else:
raise UnsupportedAlgorithm("Unsupported key type.")
+ def _evp_pkey_to_public_key(self, evp_pkey):
+ """
+ Return the appropriate type of PublicKey given an evp_pkey cdata
+ pointer.
+ """
+
+ type = evp_pkey.type
+
+ if type == self._lib.EVP_PKEY_RSA:
+ rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey)
+ assert rsa_cdata != self._ffi.NULL
+ rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free)
+ return _RSAPublicKey(self, rsa_cdata)
+ elif type == self._lib.EVP_PKEY_DSA:
+ dsa_cdata = self._lib.EVP_PKEY_get1_DSA(evp_pkey)
+ assert dsa_cdata != self._ffi.NULL
+ dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free)
+ return _DSAPublicKey(self, dsa_cdata)
+ elif self._lib.Cryptography_HAS_EC == 1 \
+ and type == self._lib.EVP_PKEY_EC:
+ ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey)
+ assert ec_cdata != self._ffi.NULL
+ ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free)
+ return _EllipticCurvePublicKey(self, ec_cdata, None)
+ else:
+ raise UnsupportedAlgorithm("Unsupported key type.")
+
def _pem_password_cb(self, password):
"""
Generate a pem_password_cb function pointer that copied the password to
@@ -787,6 +814,14 @@ class Backend(object):
password,
)
+ def load_pem_public_key(self, data):
+ return self._load_key(
+ self._lib.PEM_read_bio_PUBKEY,
+ self._evp_pkey_to_public_key,
+ data,
+ None,
+ )
+
def load_traditional_openssl_pem_private_key(self, data, password):
warnings.warn(
"load_traditional_openssl_pem_private_key is deprecated and will "
diff --git a/cryptography/hazmat/primitives/serialization.py b/cryptography/hazmat/primitives/serialization.py
index cf1ca8ec..0fb560e0 100644
--- a/cryptography/hazmat/primitives/serialization.py
+++ b/cryptography/hazmat/primitives/serialization.py
@@ -44,3 +44,7 @@ def load_pem_pkcs8_private_key(data, password, backend):
def load_pem_private_key(data, password, backend):
return backend.load_pem_private_key(data, password)
+
+
+def load_pem_public_key(data, backend):
+ return backend.load_pem_public_key(data)