[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[Libevent-users] Negotiating SSL over a already connected socket



Is it possible to negotiate SSL over an already connected socket in libevent2
(libevent-2.0.21-stable)? I am trying to do SMTP STARTTLS with smtp.gmail.com
at port 587.

Note: SMTP over ssl at port 465 of smtp.gmail.com works fine with
bufferevent_openssl_socket_new() and then bufferevent_socket_connect().

Example of a SMTP session:
Problem starts after step 10.

Normal connect to smtp.gmail.com at port 587

1.  S: 220 mx.google.com ESMTP xyz.xx - gsmtp
2.  C: EHLO localhost
3.  S: 250-mx.google.com at your service, [xxx.xxx.xxx.xxx]
4.  S: 250-SIZE 35882577
5.  S: 250-8BITMIME
6.  S: 250-STARTTLS
7.  S: 250-ENHANCEDSTATUSCODES
8.  S: 250 CHUNKING
9.  C: STARTTLS
10. S: 220 2.0.0 Ready to start TLS

**SSL negotiation happens here**

In case of a blocking socket, without libevent, it will be something like:

    SSL_set_fd(ssl, fd);
    SSL_connect(ssl);

Everything is encrypted at this point. Use usual SSL read/write functions.
I can not make it work with libevent2. EHLO is issued if SSL negotation worked.

10. C: EHLO localhost
11. S: 250-mx.google.com at your service, [xxx.xxx.xxx.xxx]
12. S: 250-SIZE 35882577
13. S: 250-8BITMIME
14. S: 250-AUTH LOGIN PLAIN XOAUTH XOAUTH2 PLAIN-CLIENTTOKEN
15. S: 250-ENHANCEDSTATUSCODES
16. S: 250 CHUNKING
17. C: QUIT
S: 221 2.0.0 closing connection xxxx.xx - gsmtp

bufferevent_openssl_filter_new() seems ideal for it but I get the
error 'tlsv1 alert protocol version in SSL routines SSL3_READ_BYTES'
if SSLv23_client_method()) method is used in SSL_CTX_new(). Changing
methods does not make any difference (error messages are different).

Sample code to negotiate SSL follows (bev is used from step 1 to 10).

    SSL_CTX *ssl_ctx=(SSL_CTX *) NULL;
    SSL *ssl=NULL;
    SSL_library_init();
    SSL_load_error_strings();
    RAND_seed(rnd_seed,sizeof(rnd_seed));
    OpenSSL_add_all_algorithms();
    // tried TLSv1_1_client_method(), SSLv3_client_method()
    ssl_ctx=SSL_CTX_new(SSLv23_client_method());
    if (ssl_ctx == NULL)
    {
        log_error("Could not create SSL context\n");
        return;
    }
    ssl=SSL_new(ssl_ctx);

    bev_ssl = bufferevent_openssl_filter_new(cb_data->base,
            bev,
            ssl,
            BUFFEREVENT_SSL_CONNECTING,
            BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
    if (!bev_ssl)
    {
        log_error("bufferevent_openssl_filter_new failed");
        exit(1);
    }
    bev = bev_ssl;
    bufferevent_setcb(bev_ssl, ssl_read_callback, NULL,
event_callback, cb_data);
    bufferevent_enable(bev_ssl, EV_READ | EV_WRITE);

I can see fatal protocol version error in server hello in wireshark and then
client sending RST at the end. Note: I see client/server both using TLS v1.1.

Thanks.
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.