extended logging for OpenSSL library errors

Artem Pylypchuk <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
Hi! I have a new patch to gwlib, it adds two different features related to openssl.

1)

When sending to a proprietary SSL server which has trouble with SSL method chosen, one may receive errors like:

ERROR: SSL write failed: OpenSSL error 1: error:00000001:lib(0):func(0):reason(1)

which aren't very verbose :(

While connection and negotiation errors can be traced by the user outside gwlib, there is the unlocked_write() function inside conn.c that produces these write errors. The following patch has allowed me to trace it into this openssl bug http://cvs.openssl.org/chngview?cn=22565 (bad renegotiation):

ERROR: SSL write failed: OpenSSL error 1: error:00000001:lib(0):func(0):reason(1)
ERROR: SSL error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number

2)
The other part of the patch allows the user to manually set the SSL for Connection, in a workflow like this:

(it uses a config option use_ssl, that switches either from strictly TLSv1 to a negotiation that disallows SSLv2 and TLSv1_1, usually ending up in SSLv3 for my server )


my_ssl_context = SSL_CTX_new(use_ssl ? SSLv23_client_method() : TLSv1_client_method());
    SSL_CTX_set_mode(my_ssl_context, 
        SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
if (use_ssl) {
    SSL_CTX_set_options(my_ssl_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_TLSv1_1); //tweak SSLv23_client_method()
}

con = conn_open_tcp_nb(server_addr, server_port, NULL);
SSL *ssl = SSL_new(my_ssl_context);
conn_set_ssl(pc->con, ssl, NULL); //needs patch to Kannel


Otherwise, without this second part of the patch, using a SSL method other than the gwlib-hardcoded default SSLv23_client_method() would require a workaround like this, creating the SSL inside gwlib and then resetting it:

con = conn_open_ssl_nb(server_addr, server_port, NULL, NULL);
SSL *conn_ssl = conn_get_ssl(pc->con);
SSL_clear(conn_ssl);
SSL_set_ssl_method(conn_ssl, use_ssl ? SSLv23_client_method() : TLSv1_client_method());
if (use_ssl) SSL_set_options(conn_ssl, SSL_OP_NO_SSLv2 | SSL_OP_NO_TLSv1_1);


Note, the conn_set_ssl() public function introduced into conn.h, sets the SSL only to a Connection created with conn_open_tcp*, and does not override the existing SSL inside a Connection created by conn_open_ssl*. It also needs the certkeyfile argument. Some essential reorganization of where SSL_new from the global context is called inside conn.c was needed to implement this.


The first part is very useful to trace openssl library errors on write, and I think it should be definitely added to Kannel source. The second reorganizes code inside conn.c and is not quite essential to the user, so you may or may not accept it.


Cheers!
Artem

-- реклама -----------------------------------------------------------
Быстрый виртуальный хостинг с SSD. Домен в подарок!
http://freehost.com.ua/unix/
ssl_set.patch (text/x-patch, 2.7 KB)
diff -rupN ./gateway-1.5.0/gwlib/conn.c ./gateway-1.5.0/gwlib/conn.c
--- ./gateway-1.5.0/gwlib/conn.c	2010-10-07 17:03:35.000000000 +0300
+++ ./gateway-1.5.0/gwlib/conn.c	2014-09-02 11:20:12.972673046 +0300
@@ -249,6 +249,11 @@ static long unlocked_write(Connection *c
             } else {
                 error(errno, "SSL write failed: OpenSSL error %d: %s",
                       SSL_error, ERR_error_string(SSL_error, NULL));
+		if (SSL_error == SSL_ERROR_SSL) { /* trace library errors */
+		long err;
+		while ((err = ERR_get_error()) != 0) 
+		error(0, "SSL %s", ERR_error_string(err, NULL));
+		}
                 return -1;
             }
         }
@@ -397,9 +402,10 @@ static void unlocked_register_pollout(Co
 }
 
 #ifdef HAVE_LIBSSL
-static int conn_init_client_ssl(Connection *ret, Octstr *certkeyfile)
+static int conn_init_client_ssl(Connection *ret, SSL *ssl, Octstr *certkeyfile)
 {
-    ret->ssl = SSL_new(global_ssl_context);
+  
+    ret->ssl = ssl;
 
     /*
      * The current thread's error queue must be empty before
@@ -452,7 +458,8 @@ Connection *conn_open_ssl_nb(Octstr *hos
         return NULL;
     }
     
-    if (conn_init_client_ssl(ret, certkeyfile) == -1) {
+    SSL *ssl = SSL_new(global_ssl_context);
+    if (conn_init_client_ssl(ret, ssl, certkeyfile) == -1) {
         conn_destroy(ret);
         return NULL;
     }
@@ -469,8 +476,9 @@ Connection *conn_open_ssl(Octstr *host,
     if (!(ret = conn_open_tcp(host, port, our_host))) {
         return NULL;
     }
-
-    if (conn_init_client_ssl(ret, certkeyfile) == -1) {
+    
+    SSL *ssl = SSL_new(global_ssl_context);
+    if (conn_init_client_ssl(ret, ssl, certkeyfile) == -1) {
         conn_destroy(ret);
         return NULL;
     }
@@ -1460,6 +1468,14 @@ SSL *conn_get_ssl(Connection *conn)
         return NULL;
 }
 
+int conn_set_ssl(Connection *conn, SSL *ssl, Octstr *certkeyfile)
+{
+    if ((conn != NULL) && (conn->ssl == NULL) && (conn_init_client_ssl(conn, ssl, certkeyfile) != -1))
+        return 0;
+    else
+        return -1;
+}
+
 #else
 
 void conn_config_ssl (CfgGroup *grp)
diff -rupN ./gateway-1.5.0/gwlib/conn.h ./gateway-1.5.0/gwlib/conn.h
--- ./gateway-1.5.0/gwlib/conn.h	2010-10-07 17:03:35.000000000 +0300
+++ ./gateway-1.5.0/gwlib/conn.h	2014-09-02 09:05:12.673072696 +0300
@@ -341,6 +341,11 @@ void conn_config_ssl(CfgGroup *grp);
  */
 SSL *conn_get_ssl(Connection *conn);
 
+/* Sets the SSL structure currently used for current Connection.
+ * If the previous structure wasn't NULL or there was an error, returns -1,
+ * else returns 0.
+ */
+int conn_set_ssl(Connection *conn, SSL *ssl, Octstr *certkeyfile);
 
 X509 *conn_get_peer_certificate(Connection *conn);
 #endif /* HAVE_LIBSSL */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.