aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2015-03-02 15:18:14 -0600
committerPaul Kehrer <paul.l.kehrer@gmail.com>2015-03-05 16:01:40 -0600
commitc5cdc4ef541f5db74fd899cd32c458797ad9ea37 (patch)
tree548708c0240509ec6dab8f77f6e6ffc1b7f6bdf9
parent7bdb2d8a1f4c8837f06d7f78a04d18c6ac3e5240 (diff)
downloadcryptography-c5cdc4ef541f5db74fd899cd32c458797ad9ea37.tar.gz
cryptography-c5cdc4ef541f5db74fd899cd32c458797ad9ea37.tar.bz2
cryptography-c5cdc4ef541f5db74fd899cd32c458797ad9ea37.zip
support "PKCS1" RSA public keys
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py46
-rw-r--r--tests/hazmat/primitives/test_serialization.py10
2 files changed, 45 insertions, 11 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index de653032..613931f7 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -690,12 +690,27 @@ class Backend(object):
)
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,
+ mem_bio = self._bytes_to_bio(data)
+ evp_pkey = self._lib.PEM_read_bio_PUBKEY(
+ mem_bio.bio, self._ffi.NULL, self._ffi.NULL, self._ffi.NULL
)
+ if evp_pkey != self._ffi.NULL:
+ evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free)
+ return self._evp_pkey_to_public_key(evp_pkey)
+ else:
+ # It's not a (RSA/DSA/ECDSA) subjectPublicKeyInfo, but we still
+ # need to check to see if it is a pure PKCS1 RSA public key (not
+ # embedded in a subjectPublicKeyInfo)
+ self._consume_errors()
+ res = self._lib.BIO_reset(mem_bio.bio)
+ assert res == 1
+ rsa_cdata = self._lib.PEM_read_bio_RSAPublicKey(
+ mem_bio.bio, self._ffi.NULL, self._ffi.NULL, self._ffi.NULL
+ )
+ if rsa_cdata != self._ffi.NULL:
+ return _RSAPublicKey(self, rsa_cdata)
+ else:
+ self._handle_key_loading_error()
def load_der_private_key(self, data, password):
# OpenSSL has a function called d2i_AutoPrivateKey that can simplify
@@ -760,12 +775,23 @@ class Backend(object):
def load_der_public_key(self, data):
mem_bio = self._bytes_to_bio(data)
evp_pkey = self._lib.d2i_PUBKEY_bio(mem_bio.bio, self._ffi.NULL)
- if evp_pkey == self._ffi.NULL:
+ if evp_pkey != self._ffi.NULL:
+ evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free)
+ return self._evp_pkey_to_public_key(evp_pkey)
+ else:
+ # It's not a (RSA/DSA/ECDSA) subjectPublicKeyInfo, but we still
+ # need to check to see if it is a pure PKCS1 RSA public key (not
+ # embedded in a subjectPublicKeyInfo)
self._consume_errors()
- raise ValueError("Could not unserialize key data.")
-
- evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free)
- return self._evp_pkey_to_public_key(evp_pkey)
+ res = self._lib.BIO_reset(mem_bio.bio)
+ assert res == 1
+ rsa_cdata = self._lib.d2i_RSAPublicKey_bio(
+ mem_bio.bio, self._ffi.NULL
+ )
+ if rsa_cdata != self._ffi.NULL:
+ return _RSAPublicKey(self, rsa_cdata)
+ else:
+ self._handle_key_loading_error()
def load_pem_x509_certificate(self, data):
mem_bio = self._bytes_to_bio(data)
diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py
index fc8f8664..07a8f02e 100644
--- a/tests/hazmat/primitives/test_serialization.py
+++ b/tests/hazmat/primitives/test_serialization.py
@@ -233,6 +233,7 @@ class TestDERSerialization(object):
"asymmetric", "DER_Serialization", "unenc-rsa-pkcs8.pub.der"),
os.path.join(
"asymmetric", "DER_Serialization", "rsa_public_key.der"),
+ os.path.join("asymmetric", "public", "PKCS1", "rsa.pub.der"),
]
)
@pytest.mark.requires_backend_interface(interface=RSABackend)
@@ -384,6 +385,7 @@ class TestPEMSerialization(object):
os.path.join("asymmetric", "PKCS8", "unenc-rsa-pkcs8.pub.pem"),
os.path.join(
"asymmetric", "PEM_Serialization", "rsa_public_key.pem"),
+ os.path.join("asymmetric", "public", "PKCS1", "rsa.pub.pem"),
]
)
def test_load_pem_rsa_public_key(self, key_file, backend):
@@ -537,7 +539,7 @@ class TestPEMSerialization(object):
)
)
- def test_wrong_format(self, backend):
+ def test_wrong_private_format(self, backend):
key_data = b"---- NOT A KEY ----\n"
with pytest.raises(ValueError):
@@ -550,6 +552,12 @@ class TestPEMSerialization(object):
key_data, b"this password will not be used", backend
)
+ def test_wrong_public_format(self, backend):
+ key_data = b"---- NOT A KEY ----\n"
+
+ with pytest.raises(ValueError):
+ load_pem_public_key(key_data, backend)
+
def test_corrupt_traditional_format(self, backend):
# privkey.pem with a bunch of data missing.
key_data = textwrap.dedent("""\