gboolean _lm_ssl_begin (LmSSL *ssl, gint fd, const gchar *server, GError **error) { gint ssl_ret; GIOStatus status; if (!ssl->ssl_ctx) { g_set_error (error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, "No SSL Context for OpenSSL"); return FALSE; } ssl->ssl = SSL_new(ssl->ssl_ctx); if (ssl->ssl == NULL) { g_warning ("SSL_new() == NULL"); g_set_error(error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, "SSL_new()"); return FALSE; } if (!SSL_set_fd (ssl->ssl, fd)) { g_warning ("SSL_set_fd() failed"); g_set_error(error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, "SSL_set_fd()"); return FALSE; } /*ssl->bio = BIO_new_socket (fd, BIO_NOCLOSE); if (ssl->bio == NULL) { g_warning("BIO_new_socket() failed"); g_set_error(error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, "BIO_new_socket()"); return FALSE; } SSL_set_bio(ssl->ssl, ssl->bio, ssl->bio);*/ do { ssl_ret = SSL_connect(ssl->ssl); if (ssl_ret <= 0) { status = ssl_io_status_from_return(ssl, ssl_ret); if (status != G_IO_STATUS_AGAIN) { ssl_print_state(ssl, "SSL_connect", ssl_ret); g_set_error(error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, "SSL_connect()"); return FALSE; } } } while (ssl_ret <= 0); if (!ssl_verify_certificate (ssl, server)) { g_set_error (error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, "*** SSL certificate verification failed"); return FALSE; } return TRUE; }
gboolean _lm_ssl_begin (LmSSL *ssl, gint fd, const gchar *server, GError **error) { int ret; gboolean auth_ok = TRUE; const int cert_type_priority[2] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP }; gnutls_init (&ssl->gnutls_session, GNUTLS_CLIENT); gnutls_set_default_priority (ssl->gnutls_session); gnutls_certificate_type_set_priority (ssl->gnutls_session, cert_type_priority); gnutls_credentials_set (ssl->gnutls_session, GNUTLS_CRD_CERTIFICATE, ssl->gnutls_xcred); gnutls_transport_set_ptr (ssl->gnutls_session, (gnutls_transport_ptr) fd); ret = gnutls_handshake (ssl->gnutls_session); if (ret >= 0) { auth_ok = ssl_verify_certificate (ssl, server); } if (ret < 0 || !auth_ok) { char *errmsg; gnutls_perror (ret); if (!auth_ok) { errmsg = "*** GNUTLS authentication error"; } else { errmsg = "*** GNUTLS handshake failed"; } g_set_error (error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, errmsg); return FALSE; } return TRUE; }
gboolean _lm_ssl_begin (LmSSL *ssl, gint fd, const gchar *server, GError **error) { int ret; LmSSLBase *base; gboolean auth_ok = TRUE; base = LM_SSL_BASE(ssl); gnutls_init (&ssl->gnutls_session, GNUTLS_CLIENT); if (base->cipher_list) { gnutls_priority_set_direct (ssl->gnutls_session, base->cipher_list, NULL); } else { gnutls_priority_set_direct (ssl->gnutls_session, "NORMAL", NULL); } if (base->ca_path) { _lm_ssl_set_ca(ssl, base->ca_path); } else { gnutls_certificate_set_x509_system_trust(ssl->gnutls_xcred); } gnutls_credentials_set (ssl->gnutls_session, GNUTLS_CRD_CERTIFICATE, ssl->gnutls_xcred); gnutls_transport_set_ptr (ssl->gnutls_session, (gnutls_transport_ptr_t)(glong) fd); ret = gnutls_handshake (ssl->gnutls_session); if (ret >= 0) { auth_ok = ssl_verify_certificate (ssl, server); } if (ret < 0 || !auth_ok) { char *errmsg; if (!auth_ok) { errmsg = "authentication error"; } else { errmsg = "handshake failed"; } g_set_error (error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, "*** GNUTLS %s: %s", errmsg, gnutls_strerror (ret)); return FALSE; } lm_verbose ("GNUTLS negotiated cipher suite: %s", gnutls_cipher_suite_get_name(gnutls_kx_get(ssl->gnutls_session), gnutls_cipher_get(ssl->gnutls_session), gnutls_mac_get(ssl->gnutls_session))); lm_verbose ("GNUTLS negotiated compression: %s", gnutls_compression_get_name (gnutls_compression_get (ssl->gnutls_session))); ssl->started = TRUE; return TRUE; }
gboolean _lm_ssl_begin (LmSSL *ssl, gint fd, const gchar *server, GError **error) { gint ssl_ret; GIOStatus status; LmSSLBase *base; base = LM_SSL_BASE(ssl); if (!ssl->ssl_ctx) { g_set_error (error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, "No SSL Context for OpenSSL"); return FALSE; } if (base->cipher_list) { SSL_CTX_set_cipher_list(ssl->ssl_ctx, base->cipher_list); } if (base->ca_path) { _lm_ssl_set_ca (ssl, base->ca_path); } else { SSL_CTX_set_default_verify_paths (ssl->ssl_ctx); } ssl->ssl = SSL_new(ssl->ssl_ctx); if (ssl->ssl == NULL) { g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SSL, "SSL_new() == NULL"); g_set_error(error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, "SSL_new()"); return FALSE; } if (!SSL_set_fd (ssl->ssl, fd)) { g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SSL, "SSL_set_fd() failed"); g_set_error(error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, "SSL_set_fd()"); return FALSE; } /*ssl->bio = BIO_new_socket (fd, BIO_NOCLOSE); if (ssl->bio == NULL) { g_warning("BIO_new_socket() failed"); g_set_error(error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, "BIO_new_socket()"); return FALSE; } SSL_set_bio(ssl->ssl, ssl->bio, ssl->bio);*/ do { ssl_ret = SSL_connect(ssl->ssl); if (ssl_ret <= 0) { status = ssl_io_status_from_return(ssl, ssl_ret); if (status != G_IO_STATUS_AGAIN) { ssl_print_state(ssl, "SSL_connect", ssl_ret); g_set_error(error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, "SSL_connect()"); return FALSE; } } } while (ssl_ret <= 0); if (!ssl_verify_certificate (ssl, server)) { g_set_error (error, LM_ERROR, LM_ERROR_CONNECTION_OPEN, "*** SSL certificate verification failed"); return FALSE; } return TRUE; }