diff options
author | Paul Kehrer <paul.l.kehrer@gmail.com> | 2013-12-29 19:51:17 -0600 |
---|---|---|
committer | Paul Kehrer <paul.l.kehrer@gmail.com> | 2013-12-30 11:17:09 -0600 |
commit | 026168cc80c964b237ebd65a20c05679acd48332 (patch) | |
tree | e4b0bd76ee6037f11c08cb4b1f7e721b0f2a5297 | |
parent | fbd7ffcdcda0269a654ebf373d4ec5f1e6d6d3f4 (diff) | |
download | cryptography-026168cc80c964b237ebd65a20c05679acd48332.tar.gz cryptography-026168cc80c964b237ebd65a20c05679acd48332.tar.bz2 cryptography-026168cc80c964b237ebd65a20c05679acd48332.zip |
add urandom engine and set it as default RAND method.
This is a proposed solution to the OpenSSL fork problem.
-rw-r--r-- | cryptography/hazmat/backends/openssl/backend.py | 10 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/urand_engine.py | 155 |
2 files changed, 165 insertions, 0 deletions
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 6231aadb..d6a77640 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -93,6 +93,7 @@ class Backend(object): "rand", "rsa", "ssl", + "urand_engine", "x509", "x509name", "x509v3", @@ -170,6 +171,15 @@ class Backend(object): cls.lib.OpenSSL_add_all_algorithms() cls.lib.SSL_load_error_strings() + res = cls.lib.Cryptography_add_urandom_engine() + assert res == 1 + e = cls.lib.ENGINE_by_id("urandom") + assert e != cls.ffi.NULL + res = cls.lib.ENGINE_init(e) + assert res == 1 + res = cls.lib.ENGINE_set_default_RAND(e) + assert res == 1 + def openssl_version_text(self): """ Friendly string name of linked OpenSSL. diff --git a/cryptography/hazmat/backends/openssl/urand_engine.py b/cryptography/hazmat/backends/openssl/urand_engine.py new file mode 100644 index 00000000..479bbb2c --- /dev/null +++ b/cryptography/hazmat/backends/openssl/urand_engine.py @@ -0,0 +1,155 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +INCLUDES = """ +#ifdef _WIN32 +#include <Wincrypt.h> +#else +#include <fcntl.h> +#include <unistd.h> +#endif +""" + +TYPES = """ +""" + +FUNCTIONS = """ +int Cryptography_add_urandom_engine(void); +""" + +MACROS = """ +""" + +CUSTOMIZATIONS = """ +static const char *urandom_engine_id= "urandom"; +static const char *urandom_engine_name = "urandom engine"; + +#ifndef _WIN32 +static int urandom_fd; + +static int urandom_rand_bytes(unsigned char *buffer, int size) { + ssize_t n; + while (0 < size) { + do { + n = read(urandom_fd, buffer, (size_t)size); + } while (n < 0 && errno == EINTR); + if (n <= 0) { + return 0; + break; + } + buffer += n; + size -= n; + } + return 1; +} + +static int urandom_rand_status(void) { + return 1; +} + +static int urandom_init(ENGINE *e) { + urandom_fd = open("/dev/urandom", O_RDONLY); + if (urandom_fd > 0) { + return 1; + } else { + printf("crap"); + return 0; + } +} + +static int urandom_finish(ENGINE *e) { + int n; + do { + n = close(urandom_fd); + } while (n < 0 && errno == EINTR); + if (n < 0) { + return 0; + } else { + return 1; + } +} +#endif + +#ifdef _WIN32 +/* This handle is never explicitly released. Instead, the operating + system will release it when the process terminates. */ +static HCRYPTPROV hCryptProv = 0; + +static int urandom_init(ENGINE *e) { + /* Acquire context */ + if (CryptAcquireContext(&hCryptProv, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { + return 1; + } else { + return 0; + } +} + +static int urandom_rand_bytes(unsigned char *buffer, int size) { + size_t chunk; + + if (hCryptProv == 0) { + return 0; + } + + while (size > 0) { + chunk = size > INT_MAX ? INT_MAX : size; + if (!CryptGenRandom(hCryptProv, (DWORD)chunk, buffer)) { + return 0; + } + buffer += chunk; + size -= chunk; + } + return 1; +} + +static int urandom_finish(ENGINE *e) { + return 1; +} + +static int urandom_rand_status(void) { + return 1; +} +#endif /* MS_WINDOWS */ + +static RAND_METHOD urandom_rand = { + NULL, + urandom_rand_bytes, + NULL, + NULL, + urandom_rand_bytes, + urandom_rand_status, +}; + +int Cryptography_add_urandom_engine(void) { + ENGINE *e = ENGINE_new(); + if(!ENGINE_set_id(e, urandom_engine_id) || + !ENGINE_set_name(e, urandom_engine_name) || + !ENGINE_set_RAND(e, &urandom_rand) || + !ENGINE_set_init_function(e, urandom_init) || + !ENGINE_set_finish_function(e, urandom_finish)) { + return 0; + } + if (!ENGINE_add(e)) { + ENGINE_free(e); + return 0; + } + if (!ENGINE_free(e)) { + return 0; + } + + return 1; +} +""" + +CONDITIONAL_NAMES = {} |