/*
 * Copyright (C) Tildeslash Ltd. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 *
 * You must obey the GNU Affero General Public License in all respects
 * for all of the code used other than OpenSSL.  
 */


#include "config.h"


#ifdef HAVE_OPENSSL


#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif

#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif

#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif

#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif

#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif

#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif

#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#endif


#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/bio.h>

#include "monit.h"
#include "net.h"
#include "ssl.h"


/* -------------------------------------------------------------- Prototypes */


#define SSLERROR ERR_error_string(ERR_get_error(),NULL)

static int unsigned long ssl_thread_id();
static void ssl_mutex_lock(int, int n, const char *, int );
static int verify_init(ssl_server_connection *);
static int verify_callback(int, X509_STORE_CTX *);
static int check_preverify(X509_STORE_CTX *);
static void cleanup_ssl_socket(ssl_connection *);
static void cleanup_ssl_server_socket(ssl_server_connection *);
static int handle_error(int, ssl_connection *);
static int update_ssl_cert_data(ssl_connection *);
static ssl_server_connection *new_ssl_server_connection(char *, char *);
static int start_ssl();

static int              ssl_initialized          = FALSE;
static pthread_mutex_t  ssl_mutex                = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t *ssl_mutex_table;


/* ------------------------------------------------------------- Definitions */


/**
 * Number of random bytes to obtain
 */
#define RANDOM_BYTES 1024

/**
 * The PRIMARY random device selected for seeding the PRNG. We use a
 * non-blocking pseudo random device, to generate pseudo entropy.
 */
#define URANDOM_DEVICE "/dev/urandom"

/**
 * If a non-blocking device is not found on the system a blocking
 * entropy producer is tried instead.
 */
#define RANDOM_DEVICE "/dev/random"


/* The list of all ciphers suites in order of strength except those containing
 anonymous DH ciphers, low  bit-size ciphers, export-crippled ciphers or the
 MD5 hash algorithm */
#define CIPHER_LIST "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"


/**
 *  SSL Socket methods.
 *
 *  @file
 */


/* ------------------------------------------------------------------ Public */


/**
 * Embeds a socket in a ssl connection.
 * @param socket the socket to be used.
 * @return The ssl connection or NULL if an error occured.
 */
int embed_ssl_socket(ssl_connection *ssl, int socket) {
        int ssl_error;
        time_t ssl_time;
        
        if (!ssl)
                return FALSE;
        
        if (!ssl_initialized)
                start_ssl();
        
        if (socket >= 0) {
                ssl->socket = socket;
        } else {
                LogError("%s: Socket error!\n", prog);
                goto sslerror;
        }
        
        if ((ssl->handler = SSL_new (ssl->ctx)) == NULL) {
                LogError("%s: Cannot initialize the SSL handler -- %s\n", prog, SSLERROR);
                goto sslerror;
        }
        
        if (SSL_CTX_set_cipher_list(ssl->ctx, CIPHER_LIST) != 1) {
                LogError("%s: Error setting cipher list '" CIPHER_LIST "' (no valid ciphers)", prog);
                goto sslerror;
        }
        
        set_noblock(ssl->socket);
        
        if ((ssl->socket_bio = BIO_new_socket(ssl->socket, BIO_NOCLOSE)) == NULL) {
                LogError("%s: Cannot generate IO buffer -- %s\n", prog, SSLERROR);
                goto sslerror;
        }
        
        SSL_set_bio(ssl->handler, ssl->socket_bio, ssl->socket_bio);
        ssl_time = time(NULL);
        
        while ((ssl_error = SSL_connect (ssl->handler)) < 0) {
                if ((time(NULL) - ssl_time) > SSL_TIMEOUT) {
                        LogError("%s: SSL service timeout!\n", prog);
                        goto sslerror;
                }
                
                if (!handle_error(ssl_error, ssl))
                        goto sslerror;
                
                if (!BIO_should_retry(ssl->socket_bio))
                        goto sslerror;
        }
        
        ssl->cipher = (char *) SSL_get_cipher(ssl->handler);
        
        if (! update_ssl_cert_data(ssl)) {
                LogError("%s: Cannot get the SSL server certificate!\n", prog);
                goto sslerror;
        }
        
        return TRUE;
        
sslerror:
        cleanup_ssl_socket(ssl);
        return FALSE;
} 


/**
 * Compare certificate with given md5 sum
 * @param ssl reference to ssl connection 
 * @param md5sum string of the md5sum to test against
 * @return TRUE, if sums do not match FALSE 
 */
int check_ssl_md5sum(ssl_connection *ssl, char *md5sum) {
        unsigned int i = 0;
        
        ASSERT(md5sum);
        
        while ((i < ssl->cert_md5_len) && (md5sum[2*i] != '\0') && (md5sum[2*i+1] != '\0')) {
                unsigned char c = (md5sum[2*i] > 57 ? md5sum[2*i] - 87 : md5sum[2*i] - 48) * 0x10+ (md5sum[2*i+1] > 57 ? md5sum[2*i+1] - 87 : md5sum[2*i+1] - 48);
                if (c != ssl->cert_md5[i])
                        return FALSE;
                i++;
        }
        return TRUE;
}


/**
 * Closes a ssl connection (ssl socket + net socket)
 * @param ssl ssl connection
 * @return TRUE, or FALSE if an error has occured.
 */
int close_ssl_socket(ssl_connection *ssl) {
        int rv;
        
        if (!ssl)
                return FALSE;
        
        if (! (rv = SSL_shutdown(ssl->handler))) {
                shutdown(ssl->socket, 1);
                rv = SSL_shutdown(ssl->handler);
        }
        
        close_socket(ssl->socket);
        cleanup_ssl_socket(ssl);
        
        return (rv > 0) ? TRUE : FALSE;
}


/**
 * Garbage collection for non-reusable parts a ssl connection
 * @param ssl ssl connection
 */
void delete_ssl_socket(ssl_connection *ssl) {
        if (!ssl)
                return;
        
        cleanup_ssl_socket(ssl);
        
        if (ssl->ctx && !ssl->accepted)
                SSL_CTX_free(ssl->ctx);
        
        ssl->ctx = NULL;
        
        FREE(ssl);
}


/**
 * Initializes a ssl connection for server use.
 * @param pemfilename Filename for the key/cert file
 * @return An ssl connection, or NULL if an error occured.
 */
ssl_server_connection *init_ssl_server(char *pemfile, char *clientpemfile) {
        SSL_METHOD *server_method = NULL;
        ssl_server_connection *ssl_server;
        
        ASSERT(pemfile);
        
        if (!ssl_initialized)
                start_ssl();
        
        ssl_server = new_ssl_server_connection(pemfile, clientpemfile);
#ifdef OPENSSL_FIPS
        if (FIPS_mode())
                server_method = TLSv1_server_method();
        else
#endif
                server_method = SSLv23_server_method();
        if (!(ssl_server->method = server_method)) {
                LogError("%s: Cannot initialize the SSL method -- %s\n", prog, SSLERROR);
                goto sslerror;
        }
        
        if (!(ssl_server->ctx = SSL_CTX_new(ssl_server->method))) {
                LogError("%s: Cannot initialize SSL server certificate handler -- %s\n", prog, SSLERROR);
                goto sslerror;
        }
        
        if (SSL_CTX_use_certificate_chain_file(ssl_server->ctx, pemfile) != 1) {
                LogError("%s: Cannot initialize SSL server certificate -- %s\n", prog, SSLERROR);
                goto sslerror;
        }
        
        if (SSL_CTX_use_PrivateKey_file(ssl_server->ctx, pemfile, SSL_FILETYPE_PEM) != 1) {
                LogError("%s: Cannot initialize SSL server private key -- %s\n", prog, SSLERROR);
                goto sslerror;
        }
        
        if (SSL_CTX_check_private_key(ssl_server->ctx) != 1) {
                LogError("%s: The private key doesn't match the certificate public key -- %s\n", prog, SSLERROR);
                goto sslerror;
        }
        
        /* Disable session cache */
        SSL_CTX_set_session_cache_mode(ssl_server->ctx, SSL_SESS_CACHE_OFF);
        
        /*
         * We need this to force transmission of client certs
         */
        if (!verify_init(ssl_server)) {
                LogError("%s: Verification engine was not properly initialized -- %s\n", prog, SSLERROR);
                goto sslerror;
        }
        
        if (ssl_server->clientpemfile) {
                STACK_OF(X509_NAME) *stack = SSL_CTX_get_client_CA_list(ssl_server->ctx);
                LogInfo("%s: Found %d client certificates\n", prog, sk_X509_NAME_num(stack));
        }
        
        return ssl_server;
        
sslerror:
        delete_ssl_server_socket(ssl_server);
        return NULL;
}


/**
 * Deletes a SSL server connection. 
 * @param ssl_server data for ssl server connection
 */
void delete_ssl_server_socket(ssl_server_connection *ssl_server) {
        if (!ssl_server)
                return;
        
        cleanup_ssl_server_socket(ssl_server);
        
        if (ssl_server->ctx)
                SSL_CTX_free(ssl_server->ctx);
        
        FREE(ssl_server);
}


/**
 * Inserts an SSL connection in the connection list of a server.
 * @param ssl_server data for ssl server connection
 * @return new SSL connection for the connection, or NULL if failed
 */
ssl_connection *insert_accepted_ssl_socket(ssl_server_connection *ssl_server) {
        ssl_connection *ssl;
        
        ASSERT(ssl_server);
        
        if (!ssl_initialized)
                start_ssl();
        
        NEW(ssl);
        ssl->method = NULL;
        ssl->handler = NULL;
        ssl->cert = NULL;
        ssl->cipher = NULL;
        ssl->socket = 0;
        ssl->next = NULL;
        ssl->accepted = FALSE;
        ssl->cert_md5= NULL;
        ssl->cert_md5_len = 0;
        ssl->clientpemfile = NULL;
        
        if (ssl_server->clientpemfile != NULL)
                ssl->clientpemfile = Str_dup(ssl_server->clientpemfile);
        
        LOCK(ssl_mutex);
        
        ssl->prev = NULL;
        ssl->next = ssl_server->ssl_conn_list;
        
        if ( ssl->next != NULL )
                ssl->next->prev = ssl;
        
        END_LOCK;
        
        ssl_server->ssl_conn_list = ssl;
        ssl->ctx = ssl_server->ctx;
        ssl->accepted = TRUE;
        
        return ssl;
}


/**
 * Closes an accepted SSL server connection and deletes it form the 
 * connection list. 
 * @param ssl_server data for ssl server connection
 * @param ssl data the connection to be deleted
 */
void close_accepted_ssl_socket(ssl_server_connection *ssl_server, ssl_connection *ssl) {
        if (!ssl || !ssl_server)
                return;
        
        close_socket(ssl->socket);
        
        LOCK(ssl_mutex);
        
        if (ssl->prev == NULL)
                ssl_server->ssl_conn_list = ssl->next;
        else
                ssl->prev->next = ssl->next;
        
        END_LOCK;  
        
        delete_ssl_socket(ssl);
}


/**
 * Embeds an accepted server socket in an existing ssl connection.
 * @param ssl ssl connection
 * @param socket the socket to be used.
 * @return TRUE, or FALSE if an error has occured.
 */
int embed_accepted_ssl_socket(ssl_connection *ssl, int socket) {
        int ssl_error;
        time_t ssl_time;
        
        ASSERT(ssl);
        
        ssl->socket = socket;
        
        if (!ssl_initialized)
                start_ssl();
        
        if (!(ssl->handler = SSL_new(ssl->ctx))) { 
                LogError("%s: Cannot initialize the SSL handler -- %s\n", prog, SSLERROR);
                return FALSE;
        } 
        
        if (socket < 0) {
                LogError("%s: Socket error!\n", prog);
                return FALSE;
        }
        
        set_noblock(ssl->socket);
        
        if (!(ssl->socket_bio = BIO_new_socket(ssl->socket, BIO_NOCLOSE))) {
                LogError("%s: Cannot generate IO buffer -- %s\n", prog, SSLERROR);
                return FALSE;
        }
        
        SSL_set_bio(ssl->handler, ssl->socket_bio, ssl->socket_bio);
        
        ssl_time = time(NULL);
        
        while ((ssl_error = SSL_accept(ssl->handler)) < 0) {
                
                if ((time(NULL) - ssl_time) > SSL_TIMEOUT) {
                        LogError("%s: SSL service timeout!\n", prog);
                        return FALSE;
                }
                
                if (!handle_error(ssl_error, ssl))
                        return FALSE;
                
                if (!BIO_should_retry(ssl->socket_bio))
                        return FALSE;
                
        }
        
        ssl->cipher = (char *)SSL_get_cipher(ssl->handler);
        
        if (!update_ssl_cert_data(ssl) && ssl->clientpemfile) {
                LogError("%s: The client did not supply a required client certificate!\n",
                         prog);
                return FALSE;
        }
        
        if (SSL_get_verify_result(ssl->handler) > 0) {
                LogError("%s: Verification of the certificate has failed!\n", prog);
                return FALSE;
        }
        
        return TRUE;
}


/**
 * Send data package though the ssl connection 
 * @param ssl ssl connection
 * @param buffer array containg the data
 * @param len size of the data container
 * @param timeout Seconds to wait for data to be written
 * @return number of bytes transmitted, -1 in case of an error
 */
int send_ssl_socket(ssl_connection *ssl, void *buffer, size_t len, int timeout) {
        int n = 0;
        
        ASSERT(ssl);
        
        do {
                n = SSL_write(ssl->handler, buffer, (int)len);
        } while (n <= 0 && BIO_should_retry(ssl->socket_bio) && can_write(ssl->socket, timeout));
        
        return (n > 0) ? n : -1;
}


/**
 * Receive data package though the ssl connection 
 * @param ssl ssl connection
 * @param buffer array to hold the data
 * @param len size of the data container
 * @param timeout Seconds to wait for data to be available
 * @return number of bytes transmitted, -1 in case of an error
 */
int recv_ssl_socket(ssl_connection *ssl, void *buffer, int len, int timeout) {
        int n = 0;
        
        ASSERT(ssl);
        
        do {
                n = SSL_read(ssl->handler, buffer, len);
        } while (n < 0 && BIO_should_retry(ssl->socket_bio) && can_read(ssl->socket, timeout));
        
        return (n >= 0) ? n : -1;
}


/**
 * Stop SSL support library
 * @return TRUE, or FALSE if an error has occured.
 */
void stop_ssl() {
        if (ssl_initialized) {
                int i;
                ssl_initialized = FALSE;
                ERR_free_strings();
                CRYPTO_set_id_callback(NULL);
                CRYPTO_set_locking_callback(NULL);
                for (i = 0; i < CRYPTO_num_locks(); i++)
                        assert(pthread_mutex_destroy(&ssl_mutex_table[i]) == 0);
                FREE(ssl_mutex_table);
                RAND_cleanup();
        }
}


/**
 * Generate a new ssl connection
 * @return ssl connection container
 */
ssl_connection *new_ssl_connection(char *clientpemfile, int sslversion) {
        ssl_connection *ssl;
        
        if (!ssl_initialized)
                start_ssl();
        
        NEW(ssl);
        ssl->socket_bio = NULL; 
        ssl->handler = NULL;
        ssl->cert = NULL;
        ssl->cipher = NULL;
        ssl->socket = 0;
        ssl->next = NULL;
        ssl->accepted = FALSE;
        ssl->cert_md5 = NULL;
        ssl->cert_md5_len = 0;
        ssl->clientpemfile = clientpemfile ? Str_dup(clientpemfile) : NULL;
        
        switch (sslversion) {
                        
                case SSL_VERSION_AUTO:
#ifdef OPENSSL_FIPS
                        if (FIPS_mode()) {
                                ssl->method = TLSv1_client_method();
                        } else
#endif
                                ssl->method = SSLv23_client_method();
                        break;
                        
                case SSL_VERSION_SSLV2:
#ifdef OPENSSL_NO_SSL2
                        LogError("SSLv2 is not allowed - use either SSLv3 or TLSv1");
                        goto sslerror;
#else
#ifdef OPENSSL_FIPS
                        if (FIPS_mode()) {
                                LogError("SSLv2 is not allowed in FIPS mode - use TLSv1");
                                goto sslerror;
                        } else
#endif
                                ssl->method = SSLv2_client_method();
#endif
                        break;
                        
                case SSL_VERSION_SSLV3:
#ifdef OPENSSL_FIPS
                        if (FIPS_mode()) {
                                LogError("SSLv3 is not allowed in FIPS mode - use TLSv1");
                                goto sslerror;
                        } else
#endif
                                ssl->method = SSLv3_client_method();
                        break;
                        
                case SSL_VERSION_TLS:
                        /* fall through */
                default:
                        ssl->method = TLSv1_client_method();
                        break;
                        
        }
        
        if (!ssl->method) {
                LogError("%s: Cannot initialize SSL method -- %s\n", prog, SSLERROR);
                goto sslerror;
        } 
        
        if (!(ssl->ctx = SSL_CTX_new(ssl->method))) {
                LogError("%s: Cannot initialize SSL server certificate handler -- %s\n", prog, SSLERROR);
                goto sslerror;
        }
        
        if (ssl->clientpemfile) {
                
                if (SSL_CTX_use_certificate_chain_file(ssl->ctx, ssl->clientpemfile) <= 0) {
                        LogError("%s: Cannot initialize SSL server certificate -- %s\n", prog, SSLERROR);
                        goto sslerror;
                }
                
                if (SSL_CTX_use_PrivateKey_file(ssl->ctx, ssl->clientpemfile, SSL_FILETYPE_PEM) <= 0) {
                        LogError("%s: Cannot initialize SSL server private key -- %s\n", prog, SSLERROR);
                        goto sslerror;
                }
                
                if (!SSL_CTX_check_private_key(ssl->ctx)) {
                        LogError("%s: Private key does not match the certificate public key -- %s\n", prog, SSLERROR);
                        goto sslerror;
                }
                
        }
        
        return ssl;
        
sslerror:
        delete_ssl_socket(ssl);
        return NULL;
}


/* ----------------------------------------------------------------- Private */


/**
 * Init verification of transmitted client certs
 */
static int verify_init(ssl_server_connection *ssl_server) {
        struct stat stat_buf;
        
        if (!ssl_server->clientpemfile) {
                SSL_CTX_set_verify(ssl_server->ctx, SSL_VERIFY_NONE, NULL);
                return TRUE;
        }
        
        if (stat(ssl_server->clientpemfile, &stat_buf) == -1) {
                LogError("%s: Cannot stat the SSL pem path '%s' -- %s\n", prog, Run.httpsslclientpem, STRERROR);
                return FALSE;
        }
        
        if (S_ISDIR(stat_buf.st_mode)) {
                
                if (!SSL_CTX_load_verify_locations(ssl_server->ctx, NULL , ssl_server->clientpemfile)) {
                        LogError("%s: Error setting verify directory to %s -- %s\n", prog, Run.httpsslclientpem, SSLERROR);
                        return FALSE;
                }
                
                LogInfo("%s: Loaded SSL client pem directory '%s'\n", prog, ssl_server->clientpemfile);
                
                /* Monit's server cert for cli support */
                
                if (!SSL_CTX_load_verify_locations(ssl_server->ctx, ssl_server->pemfile, NULL)) {
                        LogError("%s: Error loading verify certificates from %s -- %s\n", prog, ssl_server->pemfile, SSLERROR);
                        return FALSE;
                }
                
                LogInfo("%s: Loaded monit's SSL pem server file '%s'\n", prog, ssl_server->pemfile);
                
        } else if (S_ISREG(stat_buf.st_mode)) {
                
                if (!SSL_CTX_load_verify_locations(ssl_server->ctx, ssl_server->clientpemfile, NULL)) {
                        LogError("%s: Error loading verify certificates from %s -- %s\n", prog, Run.httpsslclientpem, SSLERROR);
                        return FALSE;
                }
                
                LogInfo("%s: Loaded SSL pem client file '%s'\n", prog, ssl_server->clientpemfile);
                
                /* Monits server cert for cli support ! */
                
                if (!SSL_CTX_load_verify_locations(ssl_server->ctx, ssl_server->pemfile, NULL)) {
                        LogError("%s: Error loading verify certificates from %s -- %s\n", prog, ssl_server->pemfile, SSLERROR);
                        return FALSE;
                }
                
                LogInfo("%s: Loaded monit's SSL pem server file '%s'\n", prog, ssl_server->pemfile);
                
                SSL_CTX_set_client_CA_list(ssl_server->ctx, SSL_load_client_CA_file(ssl_server->clientpemfile));
                
        } else {
                LogError("%s: SSL client pem path is no file or directory %s\n", prog, ssl_server->clientpemfile);
                return FALSE;
        }
        
        SSL_CTX_set_verify(ssl_server->ctx, SSL_VERIFY_PEER, verify_callback);
        
        return TRUE;
}


/**
 * Check the transmitted client certs and a compare with client cert database
 */
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {
        char subject[STRLEN];
        X509_OBJECT found_cert;
        
        X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), subject, STRLEN-1);
        
        if (!preverify_ok && !check_preverify(ctx))
                return 0;
        
        if (ctx->error_depth == 0 && X509_STORE_get_by_subject(ctx, X509_LU_X509, X509_get_subject_name(ctx->current_cert), &found_cert) != 1) {
                LogError("%s: SSL connection rejected. No matching certificate found -- %s\n", prog, SSLERROR);
                return 0;
        }
        
        return 1; 
}


/**
 * Analyse errors found before actual verification
 * @return TRUE if successful
 */
static int check_preverify(X509_STORE_CTX *ctx) {
        if ((ctx->error != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) && (ctx->error != X509_V_ERR_INVALID_PURPOSE)) {
                /* Remote site specified a certificate, but it's not correct */
                LogError("%s: SSL connection rejected because certificate verification has failed -- error %i\n", prog, ctx->error);
                /* Reject connection */
                return FALSE;
        } 
        
        if (Run.allowselfcert && (ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)) {
                /* Let's accept self signed certs for the moment! */
                LogInfo("%s: SSL connection accepted with self signed certificate!\n", prog);
                ctx->error = 0;
                return TRUE;
        } 
        
        /* Reject connection */
        LogError("%s: SSL connection rejected because certificate verification has failed -- error %i!\n", prog, ctx->error);
        return FALSE;
}


/**
 * Helper function for the SSL threadding support
 * @return current thread number
 */
static int unsigned long ssl_thread_id() {
        return ((unsigned long) pthread_self());
}


/**
 * Helper function for the SSL threadding support
 */
static void ssl_mutex_lock(int mode, int n, const char *file, int line) {
        if (mode & CRYPTO_LOCK)
                assert(pthread_mutex_lock( & ssl_mutex_table[n]) == 0);
        else
                assert(pthread_mutex_unlock( & ssl_mutex_table[n]) == 0);
}


/**
 * Handle errors during read, write, connect and accept
 * @return TRUE if non fatal, FALSE if non fatal and retry
 */
static int handle_error(int code, ssl_connection *ssl) {
        int ssl_error = SSL_get_error(ssl->handler, code);
        
        switch (ssl_error) {
                        
                case SSL_ERROR_WANT_READ:
                        if (can_read(ssl->socket, SSL_TIMEOUT))
                                return TRUE;
                        LogError("%s: Openssl read timeout error!\n", prog);
                        break;
                        
                case SSL_ERROR_WANT_WRITE:
                        if (can_read(ssl->socket, SSL_TIMEOUT))
                                return TRUE;
                        LogError("%s: Openssl write timeout error!\n", prog);
                        break;
                        
                case SSL_ERROR_SYSCALL:
                        LogError("%s: Openssl syscall error: %s!\n", prog, STRERROR);
                        break;
                        
                case SSL_ERROR_SSL:
                        LogError("%s: Openssl engine error: %s\n", prog, SSLERROR);
                        break;
                        
                default:
                        LogError("%s: Openssl error!\n", prog);
                        break;
                        
        }
        
        return FALSE;
}


/**
 * Garbage collection for non reusable parts of the ssl connection
 * @param ssl ssl connection
 */
static void cleanup_ssl_socket(ssl_connection *ssl) {
        if (!ssl)
                return;
        
        if (ssl->cert) {
                X509_free(ssl->cert);
                ssl->cert = NULL;
        }
        
        if (ssl->handler) {
                SSL_free(ssl->handler);
                ssl->handler = NULL;
        }
        
        if (ssl->socket_bio) {
                /* no BIO_free(ssl->socket_bio); necessary, because BIO is freed by ssl->handler */
                ssl->socket_bio = NULL;
        }
        
        FREE(ssl->cert_issuer);
        FREE(ssl->cert_subject);
        FREE(ssl->cert_md5);
        FREE(ssl->clientpemfile);
}


/**
 * Garbage collection for a SSL server connection. 
 * @param ssl_server data for ssl server connection
 */
static void cleanup_ssl_server_socket(ssl_server_connection *ssl_server) {
        if (!ssl_server)
                return;
        
        FREE(ssl_server->pemfile);
        FREE(ssl_server->clientpemfile);
        
        while (ssl_server->ssl_conn_list) {
                ssl_connection *ssl = ssl_server->ssl_conn_list;
                ssl_server->ssl_conn_list = ssl_server->ssl_conn_list->next;
                close_accepted_ssl_socket(ssl_server, ssl);
        }
}


/**
 * Updates some data in the ssl connection
 * @param ssl reference to ssl connection 
 * @return TRUE, if not successful FALSE 
 */
static int update_ssl_cert_data(ssl_connection *ssl) {
        unsigned char md5[EVP_MAX_MD_SIZE];
        
        ASSERT(ssl);
        
        if (!(ssl->cert = SSL_get_peer_certificate(ssl->handler)))
                return FALSE;
        
#ifdef OPENSSL_FIPS
        if (!FIPS_mode()) {
                /* In FIPS-140 mode, MD5 is unavailable. */
#endif
                ssl->cert_issuer = X509_NAME_oneline (X509_get_issuer_name(ssl->cert), 0, 0);
                ssl->cert_subject = X509_NAME_oneline (X509_get_subject_name(ssl->cert), 0, 0);
                X509_digest(ssl->cert, EVP_md5(), md5, &ssl->cert_md5_len);
                ssl->cert_md5= (unsigned char *)Str_dup((char *)md5);
#ifdef OPENSSL_FIPS
        }
#endif
        return TRUE;
}


/**
 * Generate a new ssl server connection
 * @return ssl server connection container
 */
static ssl_server_connection *new_ssl_server_connection(char * pemfile, char * clientpemfile) {
        ssl_server_connection *ssl_server;
        
        ASSERT(pemfile);
        
        NEW(ssl_server);
        ssl_server->ctx = NULL;
        ssl_server->method = NULL;
        ssl_server->server_socket = 0;
        ssl_server->ssl_conn_list = NULL;
        ssl_server->pemfile = Str_dup(pemfile);
        ssl_server->clientpemfile = clientpemfile ? Str_dup(clientpemfile) : NULL;
        
        return ssl_server;
}

#ifdef OPENSSL_FIPS
/**
 * Enable FIPS mode, if it isn't enabled yet.
 */
void enable_fips_mode() {
        if (!FIPS_mode()) {
                ASSERT(FIPS_mode_set(1));
                LogInfo("FIPS-140 mode is enabled\n");
        }
}
#endif

/**
 * Start SSL support library. It has to be run before the SSL support
 * can be used.
 * @return TRUE, or FALSE if an error has occured.
 */
static int start_ssl() {
        if (! ssl_initialized) {
                int i;
                int locks = CRYPTO_num_locks();
                
#ifdef OPENSSL_FIPS
                if (Run.fipsEnabled)
                        enable_fips_mode();
#endif
                
                ssl_initialized = TRUE;
                ERR_load_crypto_strings();
                ssl_mutex_table = CALLOC(locks, sizeof(pthread_mutex_t));
                for (i = 0; i < locks; i++)
                        pthread_mutex_init(&ssl_mutex_table[i], NULL);
                CRYPTO_set_id_callback(ssl_thread_id);
                CRYPTO_set_locking_callback(ssl_mutex_lock);
                SSL_library_init();
                if (file_exist(URANDOM_DEVICE)) {
                        return(RAND_load_file(URANDOM_DEVICE, RANDOM_BYTES)==RANDOM_BYTES);
                } else if (file_exist(RANDOM_DEVICE)) {
                        DEBUG("Gathering entropy from the random device\n");
                        return(RAND_load_file(RANDOM_DEVICE, RANDOM_BYTES)==RANDOM_BYTES);
                }
                return FALSE;
        }
        
        return TRUE;
}


#endif


