From 35c402a5e10b05097a7e4e511fe348642e8adb98 Mon Sep 17 00:00:00 2001 From: Marcel Poul Date: Fri, 2 Dec 2011 10:40:32 +0000 Subject: [PATCH] set options to SSL_CTX on server as well as client side --- emi.canl.canl-c/src/canl.c | 4 +- emi.canl.canl-c/src/canl.h | 3 +- emi.canl.canl-c/src/canl_locl.h | 3 +- emi.canl.canl-c/src/canl_sample_server.c | 15 ++++-- emi.canl.canl-c/src/canl_ssl.c | 91 ++++++++++++++++++++++++++++---- 5 files changed, 98 insertions(+), 18 deletions(-) diff --git a/emi.canl.canl-c/src/canl.c b/emi.canl.canl-c/src/canl.c index 18a46ab..0955e58 100644 --- a/emi.canl.canl-c/src/canl.c +++ b/emi.canl.canl-c/src/canl.c @@ -212,7 +212,7 @@ int canl_io_connect(canl_ctx cc, canl_io_handler io, char * host, int port, } /*call openssl */ - err = ssl_init(glb_cc, io_cc); + err = ssl_client_init(glb_cc, io_cc); if (err) goto end; err = ssl_connect(glb_cc, io_cc, timeout); //TODO timeout @@ -319,7 +319,7 @@ int canl_io_accept(canl_ctx cc, canl_io_handler io, int port, /* TODO everything fine - set new_io_cc according to their_addr*/ /*call openssl */ - err = ssl_init(glb_cc, *io_new_cc); + err = ssl_server_init(glb_cc, *io_new_cc); if (err) goto end; err = ssl_accept(glb_cc, io_cc, (*io_new_cc), timeout); diff --git a/emi.canl.canl-c/src/canl.h b/emi.canl.canl-c/src/canl.h index a7ad639..b6ac2d0 100644 --- a/emi.canl.canl-c/src/canl.h +++ b/emi.canl.canl-c/src/canl.h @@ -30,5 +30,6 @@ int canl_io_destroy(canl_ctx cc, canl_io_handler io); int canl_set_ctx_own_cert(canl_ctx cc, canl_x509 cert, canl_stack_of_x509 chain, canl_pkey key); - +int canl_set_ctx_own_cert_file(canl_ctx cc, char *cert, char *key, + canl_password_callback cb, void *userdata); #endif diff --git a/emi.canl.canl-c/src/canl_locl.h b/emi.canl.canl-c/src/canl_locl.h index 4ebf187..b721530 100644 --- a/emi.canl.canl-c/src/canl_locl.h +++ b/emi.canl.canl-c/src/canl_locl.h @@ -57,7 +57,8 @@ void update_error (glb_ctx *cc, const char *err_format, ...); void free_hostent(struct hostent *h); //TODO is there some standard funcion to free hostent? int asyn_getservbyname(int a_family, asyn_result *ares_result,char const *name, struct timeval *timeout); -int ssl_init(glb_ctx *cc, io_handler *io); +int ssl_client_init(glb_ctx *cc, io_handler *io); +int ssl_server_init(glb_ctx *cc, io_handler *io); int ssl_connect(glb_ctx *cc, io_handler *io, struct timeval *timeout); int ssl_accept(glb_ctx *cc, io_handler *io, io_handler *new_io, struct timeval *timeout); diff --git a/emi.canl.canl-c/src/canl_sample_server.c b/emi.canl.canl-c/src/canl_sample_server.c index 667a27b..a6d7a91 100644 --- a/emi.canl.canl-c/src/canl_sample_server.c +++ b/emi.canl.canl-c/src/canl_sample_server.c @@ -60,6 +60,11 @@ int main(int argc, char *argv[]) goto end; } + err = canl_set_ctx_own_cert_file(my_ctx, serv_cert, serv_key, NULL, NULL); + if (err) { + printf("[SERVER] cannot set certificate or file to context\n"); + } + timeout.tv_sec = 15; timeout.tv_usec = 0; @@ -67,25 +72,25 @@ int main(int argc, char *argv[]) /* TODO timeout in this function?*/ err = canl_io_accept(my_ctx, my_io_h, port, 0, NULL, &timeout, &my_new_io_h); if (err) { - printf("connection cannot be established\n"); + printf("[SERVER] connection cannot be established\n"); goto end; } else { - printf("connection established\n"); + printf("[SERVER] connection established\n"); } strcpy(buf, "This is the testing message to send"); buf_len = strlen(buf) + 1; - printf("Trying to send sth to the client\n"); + printf("[SERVER] Trying to send sth to the client\n"); err = canl_io_write (my_ctx, my_new_io_h, buf, buf_len, &timeout); if (err) { - printf("cannot send message to the client\n"); + printf("[SERVER] cannot send message to the client\n"); goto end; } else { buf[err] = '\0'; - printf("message \"%s\" sent successfully\n", buf); + printf("[SERVER] message \"%s\" sent successfully\n", buf); } err = canl_io_read (my_ctx, my_io_h, buf, sizeof(buf)-1, NULL); diff --git a/emi.canl.canl-c/src/canl_ssl.c b/emi.canl.canl-c/src/canl_ssl.c index 2526d7a..a6ce0af 100644 --- a/emi.canl.canl-c/src/canl_ssl.c +++ b/emi.canl.canl-c/src/canl_ssl.c @@ -1,13 +1,71 @@ #include "canl_locl.h" +#define SSL_SERVER_METH SSLv3_server_method() +#define SSL_CLIENT_METH SSLv3_client_method() + static int do_ssl_connect( glb_ctx *cc, io_handler *io, struct timeval *timeout); static int do_ssl_accept( glb_ctx *cc, io_handler *io, struct timeval *timeout); -int ssl_init(glb_ctx *cc, io_handler *io) +int ssl_server_init(glb_ctx *cc, io_handler *io) +{ + int err = 0; + CANL_ERROR_ORIGIN e_orig = unknown_error; + + if (!cc) { + return EINVAL; + } + if (!io) { + err = EINVAL; + e_orig = posix_error; + goto end; + } + + SSL_load_error_strings(); + SSL_library_init(); + + cc->ssl_ctx = SSL_CTX_new(SSL_SERVER_METH); + if (!cc->ssl_ctx){ + err = ERR_get_error(); + e_orig = ssl_error; + goto end; + } + + SSL_CTX_set_cipher_list(cc->ssl_ctx, "ALL:!LOW:!EXP:!MD5:!MD2"); + SSL_CTX_set_purpose(cc->ssl_ctx, X509_PURPOSE_ANY); + SSL_CTX_set_mode(cc->ssl_ctx, SSL_MODE_AUTO_RETRY); + // TODO proxy_verify_callback !!!!!!! + //SSL_CTX_set_verify(cc->ssl_ctx, SSL_VERIFY_PEER, NULL); + //SSL_CTX_set_verify_depth(ctx, 100); + //SSL_CTX_set_cert_verify_callback(ctx, proxy_app_verify_callback, 0); + if (cc->cert_key) { + if (cc->cert_key->key) { + err = SSL_CTX_use_PrivateKey(cc->ssl_ctx, cc->cert_key->key); + if (err) { + err = ERR_get_error(); + e_orig = ssl_error; + goto end; + } + } + else if (cc->cert_key->cert) { + err = SSL_CTX_use_certificate(cc->ssl_ctx, cc->cert_key->cert); + if (err) { + err = ERR_get_error(); + e_orig = ssl_error; + goto end; + } + } + } + +end: + if (err) + set_error(cc, err, e_orig, "cannot initialize SSL context (ssl_server_init)"); + return err; +} + +int ssl_client_init(glb_ctx *cc, io_handler *io) { int err = 0; CANL_ERROR_ORIGIN e_orig = unknown_error; - SSL_METHOD *ssl_meth; if (!cc) { return EINVAL; @@ -21,13 +79,21 @@ int ssl_init(glb_ctx *cc, io_handler *io) SSL_load_error_strings(); SSL_library_init(); - ssl_meth = SSLv23_method(); //TODO dynamically - cc->ssl_ctx = SSL_CTX_new(ssl_meth); + cc->ssl_ctx = SSL_CTX_new(SSL_CLIENT_METH); if (!cc->ssl_ctx){ err = ERR_get_error(); e_orig = ssl_error; goto end; } + + SSL_CTX_set_options(cc->ssl_ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS | SSL_OP_NO_SSLv2); + //SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, proxy_verify_callback); + //SSL_CTX_set_verify_depth(ctx, 100); + //SSL_CTX_load_verify_locations(ctx, NULL, cacertdir); + SSL_CTX_set_cipher_list(cc->ssl_ctx, "ALL:!LOW:!EXP:!MD5:!MD2"); + SSL_CTX_set_purpose(cc->ssl_ctx, X509_PURPOSE_ANY); + SSL_CTX_set_mode(cc->ssl_ctx, SSL_MODE_AUTO_RETRY); + if (cc->cert_key) { if (cc->cert_key->key) { @@ -50,7 +116,7 @@ int ssl_init(glb_ctx *cc, io_handler *io) end: if (err) - set_error(cc, err, e_orig, "cannot initialize SSL context (ssl_init)"); + set_error(cc, err, e_orig, "cannot initialize SSL context (ssl_client_init)"); return err; } @@ -198,6 +264,7 @@ static int do_ssl_connect( glb_ctx *cc, io_handler *io, struct timeval *timeout) { time_t starttime, curtime; int ret = -1, ret2 = -1, err = 0; + CANL_ERROR_ORIGIN e_orig = unknown_error; long errorcode = 0; int expected = 0; int locl_timeout = -1; @@ -213,6 +280,10 @@ static int do_ssl_connect( glb_ctx *cc, io_handler *io, struct timeval *timeout) ret = do_select(io->sock, starttime, locl_timeout, expected); if (ret > 0) { ret2 = SSL_connect(io->s_ctx->ssl_io); + if (ret2 < 0) { + err = ERR_get_error(); + e_orig = ssl_error; + } expected = errorcode = SSL_get_error(io->s_ctx->ssl_io, ret2); } curtime = time(NULL); @@ -226,10 +297,12 @@ static int do_ssl_connect( glb_ctx *cc, io_handler *io, struct timeval *timeout) err = ETIMEDOUT; set_error (cc, err, posix_error, "Connection stuck during handshake: timeout reached (do_ssl_connect)"); } - else{ - err = -1; //TODO set approp. error message - set_error (cc, err, unknown_error,"Error during SSL handshake (do_ssl_connect)"); - } + else if (ret2 < 0) + set_error (cc, err, e_orig, "Error during SSL handshake" + " (do_ssl_connect)"); + else + set_error (cc, err, unknown_error, "Error during SSL handshake" + " (do_ssl_connect)"); return err; } -- 1.8.2.3