set options to SSL_CTX on server as well as client side
authorMarcel Poul <marcel.poul@cern.ch>
Fri, 2 Dec 2011 10:40:32 +0000 (10:40 +0000)
committerMarcel Poul <marcel.poul@cern.ch>
Fri, 2 Dec 2011 10:40:32 +0000 (10:40 +0000)
emi.canl.canl-c/src/canl.c
emi.canl.canl-c/src/canl.h
emi.canl.canl-c/src/canl_locl.h
emi.canl.canl-c/src/canl_sample_server.c
emi.canl.canl-c/src/canl_ssl.c

index 18a46ab..0955e58 100644 (file)
@@ -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); 
index a7ad639..b6ac2d0 100644 (file)
@@ -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
index 4ebf187..b721530 100644 (file)
@@ -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);
index 667a27b..a6d7a91 100644 (file)
@@ -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);
index 2526d7a..a6ce0af 100644 (file)
@@ -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;
     }