aboutsummaryrefslogtreecommitdiffstats
path: root/src/_cffi_src/openssl/callbacks.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/_cffi_src/openssl/callbacks.py')
-rw-r--r--src/_cffi_src/openssl/callbacks.py168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/_cffi_src/openssl/callbacks.py b/src/_cffi_src/openssl/callbacks.py
new file mode 100644
index 00000000..8ee01e0e
--- /dev/null
+++ b/src/_cffi_src/openssl/callbacks.py
@@ -0,0 +1,168 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+INCLUDES = """
+#include <openssl/ssl.h>
+#include <openssl/x509.h>
+#include <openssl/x509_vfy.h>
+#include <openssl/crypto.h>
+
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#include <Wincrypt.h>
+#include <Winsock2.h>
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#endif
+"""
+
+TYPES = """
+typedef struct {
+ char *password;
+ int length;
+ int called;
+ int error;
+ int maxsize;
+} CRYPTOGRAPHY_PASSWORD_DATA;
+"""
+
+FUNCTIONS = """
+int Cryptography_setup_ssl_threads(void);
+int Cryptography_pem_password_cb(char *, int, int, void *);
+"""
+
+CUSTOMIZATIONS = """
+/* This code is derived from the locking code found in the Python _ssl module's
+ locking callback for OpenSSL.
+
+ Copyright 2001-2016 Python Software Foundation; All Rights Reserved.
+
+ It has been subsequently modified to use cross platform locking without
+ using CPython APIs by Armin Rigo of the PyPy project.
+*/
+
+#if CRYPTOGRAPHY_OPENSSL_LESS_THAN_110
+#ifdef _WIN32
+typedef CRITICAL_SECTION Cryptography_mutex;
+static __inline void cryptography_mutex_init(Cryptography_mutex *mutex) {
+ InitializeCriticalSection(mutex);
+}
+static __inline void cryptography_mutex_lock(Cryptography_mutex *mutex) {
+ EnterCriticalSection(mutex);
+}
+static __inline void cryptography_mutex_unlock(Cryptography_mutex *mutex) {
+ LeaveCriticalSection(mutex);
+}
+#else
+typedef pthread_mutex_t Cryptography_mutex;
+#define ASSERT_STATUS(call) \
+ if ((call) != 0) { \
+ perror("Fatal error in callback initialization: " #call); \
+ abort(); \
+ }
+static inline void cryptography_mutex_init(Cryptography_mutex *mutex) {
+#if !defined(pthread_mutexattr_default)
+# define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL)
+#endif
+ ASSERT_STATUS(pthread_mutex_init(mutex, pthread_mutexattr_default));
+}
+static inline void cryptography_mutex_lock(Cryptography_mutex *mutex) {
+ ASSERT_STATUS(pthread_mutex_lock(mutex));
+}
+static inline void cryptography_mutex_unlock(Cryptography_mutex *mutex) {
+ ASSERT_STATUS(pthread_mutex_unlock(mutex));
+}
+#endif
+
+
+static int _ssl_locks_count = 0;
+static Cryptography_mutex *_ssl_locks = NULL;
+
+static void _ssl_thread_locking_function(int mode, int n, const char *file,
+ int line) {
+ /* this function is needed to perform locking on shared data
+ structures. (Note that OpenSSL uses a number of global data
+ structures that will be implicitly shared whenever multiple
+ threads use OpenSSL.) Multi-threaded applications will
+ crash at random if it is not set.
+
+ locking_function() must be able to handle up to
+ CRYPTO_num_locks() different mutex locks. It sets the n-th
+ lock if mode & CRYPTO_LOCK, and releases it otherwise.
+
+ file and line are the file number of the function setting the
+ lock. They can be useful for debugging.
+ */
+
+ if ((_ssl_locks == NULL) ||
+ (n < 0) || (n >= _ssl_locks_count)) {
+ return;
+ }
+
+ if (mode & CRYPTO_LOCK) {
+ cryptography_mutex_lock(_ssl_locks + n);
+ } else {
+ cryptography_mutex_unlock(_ssl_locks + n);
+ }
+}
+
+static void init_mutexes(void) {
+ int i;
+ for (i = 0; i < _ssl_locks_count; i++) {
+ cryptography_mutex_init(_ssl_locks + i);
+ }
+}
+
+
+int Cryptography_setup_ssl_threads(void) {
+ if (_ssl_locks == NULL) {
+ _ssl_locks_count = CRYPTO_num_locks();
+ _ssl_locks = calloc(_ssl_locks_count, sizeof(Cryptography_mutex));
+ if (_ssl_locks == NULL) {
+ return 0;
+ }
+ init_mutexes();
+ CRYPTO_set_locking_callback(_ssl_thread_locking_function);
+#ifndef _WIN32
+ pthread_atfork(NULL, NULL, &init_mutexes);
+#endif
+ }
+ return 1;
+}
+#else
+int (*Cryptography_setup_ssl_threads)(void) = NULL;
+#endif
+
+typedef struct {
+ char *password;
+ int length;
+ int called;
+ int error;
+ int maxsize;
+} CRYPTOGRAPHY_PASSWORD_DATA;
+
+int Cryptography_pem_password_cb(char *buf, int size,
+ int rwflag, void *userdata) {
+ /* The password cb is only invoked if OpenSSL decides the private
+ key is encrypted. So this path only occurs if it needs a password */
+ CRYPTOGRAPHY_PASSWORD_DATA *st = (CRYPTOGRAPHY_PASSWORD_DATA *)userdata;
+ st->called += 1;
+ st->maxsize = size;
+ if (st->length == 0) {
+ st->error = -1;
+ return 0;
+ } else if (st->length < size) {
+ memcpy(buf, st->password, st->length);
+ return st->length;
+ } else {
+ st->error = -2;
+ return 0;
+ }
+}
+"""