diff options
author | David Reid <dreid@dreid.org> | 2014-02-11 13:42:57 -0800 |
---|---|---|
committer | David Reid <dreid@dreid.org> | 2014-02-11 13:42:57 -0800 |
commit | ecfcf0f46af3d9f13406ec277d8dd078a59d8d8b (patch) | |
tree | 88aca587555380ec9967d1c382f5eab68e6914f7 /cryptography | |
parent | ce6bdf4742739050f90883f0911bb9b9976ecc56 (diff) | |
parent | 8f2250fcfa477731a1a880a467b58198db8790aa (diff) | |
download | cryptography-ecfcf0f46af3d9f13406ec277d8dd078a59d8d8b.tar.gz cryptography-ecfcf0f46af3d9f13406ec277d8dd078a59d8d8b.tar.bz2 cryptography-ecfcf0f46af3d9f13406ec277d8dd078a59d8d8b.zip |
Merge pull request #580 from public/openssl-gen-rsa-key
Generate RSA Keys with OpenSSL
Diffstat (limited to 'cryptography')
-rw-r--r-- | cryptography/hazmat/backends/openssl/backend.py | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 6da90cef..d8869328 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -20,7 +20,7 @@ from cryptography.exceptions import ( UnsupportedAlgorithm, InvalidTag, InternalError ) from cryptography.hazmat.backends.interfaces import ( - CipherBackend, HashBackend, HMACBackend, PBKDF2HMACBackend + CipherBackend, HashBackend, HMACBackend, PBKDF2HMACBackend, RSABackend ) from cryptography.hazmat.primitives import interfaces, hashes from cryptography.hazmat.primitives.ciphers.algorithms import ( @@ -30,12 +30,14 @@ from cryptography.hazmat.primitives.ciphers.modes import ( CBC, CTR, ECB, OFB, CFB, GCM, ) from cryptography.hazmat.bindings.openssl.binding import Binding +from cryptography.hazmat.primitives.asymmetric import rsa @utils.register_interface(CipherBackend) @utils.register_interface(HashBackend) @utils.register_interface(HMACBackend) @utils.register_interface(PBKDF2HMACBackend) +@utils.register_interface(RSABackend) class Backend(object): """ OpenSSL API binding interfaces. @@ -259,6 +261,46 @@ class Backend(object): ) ) + def _bn_to_int(self, bn): + hex_cdata = self._lib.BN_bn2hex(bn) + assert hex_cdata != self._ffi.NULL + hex_str = self._ffi.string(hex_cdata) + self._lib.OPENSSL_free(hex_cdata) + return int(hex_str, 16) + + def generate_rsa_private_key(self, public_exponent, key_size): + if public_exponent < 3: + raise ValueError("public_exponent must be >= 3") + + if public_exponent & 1 == 0: + raise ValueError("public_exponent must be odd") + + if key_size < 512: + raise ValueError("key_size must be at least 512-bits") + + ctx = backend._lib.RSA_new() + ctx = backend._ffi.gc(ctx, backend._lib.RSA_free) + + bn = backend._lib.BN_new() + assert bn != self._ffi.NULL + bn = backend._ffi.gc(bn, backend._lib.BN_free) + + res = backend._lib.BN_set_word(bn, public_exponent) + assert res == 1 + + res = backend._lib.RSA_generate_key_ex( + ctx, key_size, bn, backend._ffi.NULL + ) + assert res == 1 + + return rsa.RSAPrivateKey( + p=self._bn_to_int(ctx.p), + q=self._bn_to_int(ctx.q), + private_exponent=self._bn_to_int(ctx.d), + public_exponent=self._bn_to_int(ctx.e), + modulus=self._bn_to_int(ctx.n), + ) + class GetCipherByName(object): def __init__(self, fmt): |