Esempio n. 1
0
/**
 * Callback function to process the SSL handshake.
 */
static gboolean
ssl_connect_cb(gint sk, gpointer user_data)
{
    gint                 l;
    gboolean             res;
    HybridSslConnection *ssl_conn = (HybridSslConnection*)user_data;

    if (!SSL_set_fd(ssl_conn->ssl, sk)) {

        hybrid_debug_error("ssl", "add ssl to tcp socket:%s",
                           ERR_reason_error_string(ERR_get_error()));
        return FALSE;
    }

    ssl_conn->sk = sk;
    SSL_set_connect_state(ssl_conn->ssl);

 ssl_reconnect:
    l = SSL_connect(ssl_conn->ssl);

    switch (SSL_get_error(ssl_conn->ssl, l)) {
    case SSL_ERROR_NONE:
        goto ssl_ok;
    case SSL_ERROR_WANT_WRITE:
    case SSL_ERROR_WANT_READ:
        usleep(100);
        goto ssl_reconnect;
    case SSL_ERROR_SYSCALL:
    case SSL_ERROR_WANT_X509_LOOKUP:
    case SSL_ERROR_ZERO_RETURN:
    case SSL_ERROR_SSL:
    default:
        ERR_print_errors_fp(stderr);
        goto ssl_err;
        break;
    }

ssl_ok:
    if (HYBRID_OK != ssl_verify_certs(ssl_conn->ssl)) {
        return FALSE;
    }

    res = ssl_conn->conn_cb(ssl_conn, ssl_conn->conn_data);
    return res;

ssl_err:
    {
	    // TODO network error
    }
    return FALSE;
}
Esempio n. 2
0
HybridSslConnection*
hybrid_ssl_connect_with_fd(gint sk,    ssl_callback func, gpointer user_data)
{
    gint                 l;
    SSL                 *ssl;
    BIO                 *sbio;
    BIO                 *buf_io;
    BIO                 *ssl_bio;
    SSL_CTX             *ssl_ctx;
    HybridSslConnection *ssl_conn;

    SSL_load_error_strings();
    SSL_library_init();

    if (!(ssl_ctx = SSL_CTX_new(TLSv1_client_method()))) {

        hybrid_debug_error("ssl", "initialize SSL CTX: %s",
                           ERR_reason_error_string(ERR_get_error()));
        return NULL;
    }

    if (!(ssl = ssl_new_with_certs(ssl_ctx))) {
        return NULL;
    }

    if (!SSL_set_fd(ssl, sk)) {
        hybrid_debug_error("ssl", "add ssl to tcp socket:%s",
                           ERR_reason_error_string(ERR_get_error()));
        return NULL;
    }

    sbio = BIO_new(BIO_s_socket());
    BIO_set_fd(sbio, sk, BIO_NOCLOSE);
    SSL_set_bio(ssl, sbio, sbio);

    SSL_set_connect_state(ssl);

 reconnect:
    l = SSL_connect(ssl);

    switch (SSL_get_error(ssl, l)) {
    case SSL_ERROR_NONE:
        goto ssl_conn_sk_ok;
    case SSL_ERROR_WANT_WRITE:
    case SSL_ERROR_WANT_READ:
        usleep(100);
        goto reconnect;
    case SSL_ERROR_SYSCALL:
    case SSL_ERROR_WANT_X509_LOOKUP:
    case SSL_ERROR_ZERO_RETURN:
    case SSL_ERROR_SSL:
    default:
        hybrid_debug_error("ssl", "ssl hand-shake error:%s",
                           ERR_reason_error_string(ERR_get_error()));
        return NULL;
    }

ssl_conn_sk_ok:

    if (HYBRID_OK != ssl_verify_certs(ssl)) {
        return NULL;
    }

    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

    buf_io = BIO_new(BIO_f_buffer());
    ssl_bio = BIO_new(BIO_f_ssl());

    BIO_set_ssl(ssl_bio, ssl, BIO_NOCLOSE);
    BIO_push(buf_io, ssl_bio);

    ssl_conn = g_new0(HybridSslConnection, 1);

    ssl_conn->sk        = sk;
    ssl_conn->ssl       = ssl;
    ssl_conn->ssl_ctx   = ssl_ctx;
    ssl_conn->conn_cb   = func;
    ssl_conn->conn_data = user_data;
    ssl_conn->rbio      = buf_io;
    ssl_conn->wbio      = sbio;

    if (func) {
        func(ssl_conn, user_data);
    }

    return ssl_conn;
}