From 1e6714f7badd27dc9b8d8700d90f2b18f9970107 Mon Sep 17 00:00:00 2001 From: hahaliu <13220810376@163.com> Date: Thu, 15 Dec 2022 10:11:52 +0800 Subject: [PATCH] gtls unsafe --- rust/rust_project/src/vtls/gtls.rs | 6656 ++++++++++++++-------------- 1 file changed, 3338 insertions(+), 3318 deletions(-) diff --git a/rust/rust_project/src/vtls/gtls.rs b/rust/rust_project/src/vtls/gtls.rs index e4ee80a..60196a2 100644 --- a/rust/rust_project/src/vtls/gtls.rs +++ b/rust/rust_project/src/vtls/gtls.rs @@ -12,3330 +12,3350 @@ * Create: 2022-10-31 * Description: support gnutls backend ******************************************************************************/ -use crate::src::vtls::vtls::*; -use libc; -use rust_ffi::src::ffi_alias::type_alias::*; -use rust_ffi::src::ffi_fun::fun_call::*; -use rust_ffi::src::ffi_struct::struct_define::*; - -static mut gtls_inited: bool = 0 as i32 != 0; -extern "C" fn gtls_push( - mut s: *mut libc::c_void, - mut buf: *const libc::c_void, - mut len: size_t, -) -> ssize_t { - unsafe { - let mut sock: curl_socket_t = *(s as *mut curl_socket_t); - #[cfg(not(CURLDEBUG))] - let mut ret: ssize_t = send(sock, buf, len, MSG_NOSIGNAL as i32); - - #[cfg(CURLDEBUG)] - let mut ret: ssize_t = curl_dbg_send( - sock, - buf, - len, - MSG_NOSIGNAL as i32, - 86 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - return ret; - } -} -extern "C" fn gtls_pull( - mut s: *mut libc::c_void, - mut buf: *mut libc::c_void, - mut len: size_t, -) -> ssize_t { - unsafe { - let mut sock: curl_socket_t = *(s as *mut curl_socket_t); - #[cfg(not(CURLDEBUG))] - let mut ret: ssize_t = recv(sock, buf, len, 0 as i32); - - #[cfg(CURLDEBUG)] - let mut ret: ssize_t = curl_dbg_recv( - sock, - buf, - len, - 0 as i32, - 93 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - return ret; - } -} -extern "C" fn gtls_push_ssl( - mut s: *mut libc::c_void, - mut buf: *const libc::c_void, - mut len: size_t, -) -> ssize_t { - unsafe { - return gnutls_record_send(s as gnutls_session_t, buf, len); - } -} -extern "C" fn gtls_pull_ssl( - mut s: *mut libc::c_void, - mut buf: *mut libc::c_void, - mut len: size_t, -) -> ssize_t { - unsafe { - return gnutls_record_recv(s as gnutls_session_t, buf, len); - } -} - -/* gtls_init() - * - * Global GnuTLS init, called from Curl_ssl_init(). This calls functions that - * are not thread-safe and thus this function itself is not thread-safe and - * must only be called from within curl_global_init() to keep the thread - * situation under control! - */ -extern "C" fn gtls_init() -> i32 { - unsafe { - let mut ret: i32 = 1 as i32; - if !gtls_inited { - ret = if gnutls_global_init() != 0 { - 0 as i32 - } else { - 1 as i32 - }; - - // #[cfg(GTLSDEBUG)] - gtls_inited = 1 as i32 != 0; - } - return ret; - } -} - -extern "C" fn gtls_cleanup() { - unsafe { - if gtls_inited { - gnutls_global_deinit(); - gtls_inited = 0 as i32 != 0; - } - } -} -#[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] -extern "C" fn showtime(mut data: *mut Curl_easy, mut text: *const libc::c_char, mut stamp: time_t) { - unsafe { - let mut buffer: tm = tm { - tm_sec: 0, - tm_min: 0, - tm_hour: 0, - tm_mday: 0, - tm_mon: 0, - tm_year: 0, - tm_wday: 0, - tm_yday: 0, - tm_isdst: 0, - tm_gmtoff: 0, - tm_zone: 0 as *const libc::c_char, - }; - let mut tm: *const tm = &mut buffer; - let mut str: [libc::c_char; 96] = [0; 96]; - let mut result: CURLcode = Curl_gmtime(stamp, &mut buffer); - if result as u64 != 0 { - return; - } - curl_msnprintf( - str.as_mut_ptr(), - ::std::mem::size_of::<[libc::c_char; 96]>() as u64, - b" %s: %s, %02d %s %4d %02d:%02d:%02d GMT\0" as *const u8 as *const libc::c_char, - text, - Curl_wkday[(if (*tm).tm_wday != 0 { - (*tm).tm_wday - 1 as i32 - } else { - 6 as i32 - }) as usize], - (*tm).tm_mday, - Curl_month[(*tm).tm_mon as usize], - (*tm).tm_year + 1900 as i32, - (*tm).tm_hour, - (*tm).tm_min, - (*tm).tm_sec, - ); - Curl_infof( - data, - b"%s\0" as *const u8 as *const libc::c_char, - str.as_mut_ptr(), - ); - } -} -extern "C" fn load_file(mut file: *const libc::c_char) -> gnutls_datum_t { - unsafe { - let mut f: *mut FILE = 0 as *mut FILE; - let mut loaded_file: gnutls_datum_t = { - gnutls_datum_t { - data: 0 as *mut u8, - size: 0 as u32, - } - }; - let mut filelen: i64 = 0; - let mut ptr: *mut libc::c_void = 0 as *mut libc::c_void; - match () { - #[cfg(not(CURLDEBUG))] - _ => { - f = fopen(file, b"rb\0" as *const u8 as *const libc::c_char); - } - #[cfg(CURLDEBUG)] - _ => { - f = curl_dbg_fopen( - file, - b"rb\0" as *const u8 as *const libc::c_char, - 170 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - } - } - - if f.is_null() { - return loaded_file; - } - 'out: loop { - if !(fseek(f, 0 as i64, 2 as i32) != 0 as i32 - || { - filelen = ftell(f); - filelen < 0 as i64 - } - || fseek(f, 0 as i64, 0 as i32) != 0 as i32 - || { - match () { - #[cfg(not(CURLDEBUG))] - _ => { - ptr = - Curl_cmalloc.expect("non-null function pointer")(filelen as size_t); - } - #[cfg(CURLDEBUG)] - _ => { - ptr = curl_dbg_malloc( - filelen as size_t, - 176 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - } - } - - ptr.is_null() - }) - { - break 'out; - } - - if fread(ptr, 1 as u64, filelen as size_t, f) < filelen as size_t { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(ptr); - - #[cfg(CURLDEBUG)] - curl_dbg_free( - ptr, - 179 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - - break 'out; - } else { - loaded_file.data = ptr as *mut u8; - loaded_file.size = filelen as u32; - } - - break 'out; - } - #[cfg(not(CURLDEBUG))] - fclose(f); - - #[cfg(CURLDEBUG)] - curl_dbg_fclose( - f, - 186 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - return loaded_file; - } -} -extern "C" fn unload_file(mut data: gnutls_datum_t) { - unsafe { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(data.data as *mut libc::c_void); - - #[cfg(CURLDEBUG)] - curl_dbg_free( - data.data as *mut libc::c_void, - 192 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - } -} - -/* this function does a SSL/TLS (re-)handshake */ -extern "C" fn handshake( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - mut duringconnect: bool, - mut nonblocking: bool, -) -> CURLcode { - unsafe { - let mut connssl: *mut ssl_connect_data = - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data; - let mut backend: *mut ssl_backend_data = (*connssl).backend; - let mut session: gnutls_session_t = (*backend).session; - let mut sockfd: curl_socket_t = (*conn).sock[sockindex as usize]; - loop { - let mut timeout_ms: timediff_t = 0; - let mut rc: i32 = 0; - /* check allowed time left */ - timeout_ms = Curl_timeleft(data, 0 as *mut curltime, duringconnect); - if timeout_ms < 0 as i64 { - /* no need to continue if time already is up */ - Curl_failf( - data, - b"SSL connection timeout\0" as *const u8 as *const libc::c_char, - ); - return CURLE_OPERATION_TIMEDOUT; - } - /* if ssl is expecting something, check if it's available. */ - if (*connssl).connecting_state as u32 == ssl_connect_2_reading as u32 - || (*connssl).connecting_state as u32 == ssl_connect_2_writing as u32 - { - let mut what: i32 = 0; - let mut writefd: curl_socket_t = - if ssl_connect_2_writing as u32 == (*connssl).connecting_state as u32 { - sockfd - } else { - -(1 as i32) - }; - let mut readfd: curl_socket_t = - if ssl_connect_2_reading as u32 == (*connssl).connecting_state as u32 { - sockfd - } else { - -(1 as i32) - }; - what = Curl_socket_check( - readfd, - -(1 as i32), - writefd, - if nonblocking as i32 != 0 { - 0 as i64 - } else if timeout_ms != 0 { - timeout_ms - } else { - 1000 as i64 - }, - ); - if what < 0 as i32 { - /* fatal error */ - Curl_failf( - data, - b"select/poll on SSL socket, errno: %d\0" as *const u8 - as *const libc::c_char, - *__errno_location(), - ); - return CURLE_SSL_CONNECT_ERROR; - } else { - if 0 as i32 == what { - if nonblocking { - return CURLE_OK; - } else { - if timeout_ms != 0 { - /* timeout */ - Curl_failf( - data, - b"SSL connection timeout at %ld\0" as *const u8 - as *const libc::c_char, - timeout_ms, - ); - return CURLE_OPERATION_TIMEDOUT; - } - } - } - } - /* socket is readable or writable */ - } - rc = gnutls_handshake(session); - if rc == -(28 as i32) || rc == -(52 as i32) { - (*connssl).connecting_state = (if gnutls_record_get_direction(session) != 0 { - ssl_connect_2_writing as i32 - } else { - ssl_connect_2_reading as i32 - }) as ssl_connect_state; - } else if rc < 0 as i32 && gnutls_error_is_fatal(rc) == 0 { - let mut strerr: *const libc::c_char = 0 as *const libc::c_char; - if rc == -(16 as i32) { - let mut alert: i32 = gnutls_alert_get(session) as i32; - strerr = gnutls_alert_get_name(alert as gnutls_alert_description_t); - } - if strerr.is_null() { - strerr = gnutls_strerror(rc); - } - Curl_infof( - data, - b"gnutls_handshake() warning: %s\0" as *const u8 as *const libc::c_char, - strerr, - ); - } else { - if rc < 0 as i32 { - let mut strerr_0: *const libc::c_char = 0 as *const libc::c_char; - if rc == -(12 as i32) { - let mut alert_0: i32 = gnutls_alert_get(session) as i32; - strerr_0 = gnutls_alert_get_name(alert_0 as gnutls_alert_description_t); - } - if strerr_0.is_null() { - strerr_0 = gnutls_strerror(rc); - } - Curl_failf( - data, - b"gnutls_handshake() failed: %s\0" as *const u8 as *const libc::c_char, - strerr_0, - ); - return CURLE_SSL_CONNECT_ERROR; - } - /* Reset our connect state machine */ - (*connssl).connecting_state = ssl_connect_1; - return CURLE_OK; - } - } - } -} -extern "C" fn do_file_type(mut type_0: *const libc::c_char) -> gnutls_x509_crt_fmt_t { - unsafe { - if type_0.is_null() || *type_0.offset(0 as isize) == 0 { - return GNUTLS_X509_FMT_PEM; - } - if Curl_strcasecompare(type_0, b"PEM\0" as *const u8 as *const libc::c_char) != 0 { - return GNUTLS_X509_FMT_PEM; - } - if Curl_strcasecompare(type_0, b"DER\0" as *const u8 as *const libc::c_char) != 0 { - return GNUTLS_X509_FMT_DER; - } - return GNUTLS_X509_FMT_PEM; - } -} -extern "C" fn set_ssl_version_min_max( - mut data: *mut Curl_easy, - mut prioritylist: *mut *const libc::c_char, - mut tls13support: *const libc::c_char, -) -> CURLcode { - unsafe { - let mut conn: *mut connectdata = (*data).conn; - #[cfg(not(CURL_DISABLE_PROXY))] - let mut ssl_version: i64 = if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.version - } else { - (*conn).ssl_config.version - }; - #[cfg(CURL_DISABLE_PROXY)] - let mut ssl_version: i64 = (*conn).ssl_config.version; - - #[cfg(not(CURL_DISABLE_PROXY))] - let mut ssl_version_max: i64 = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.version_max - } else { - (*conn).ssl_config.version_max - }; - #[cfg(CURL_DISABLE_PROXY)] - let mut ssl_version_max: i64 = (*conn).ssl_config.version_max; - - if ssl_version == CURL_SSLVERSION_DEFAULT as i64 - || ssl_version == CURL_SSLVERSION_TLSv1 as i64 - { - ssl_version = CURL_SSLVERSION_TLSv1_0 as i64; - } - if ssl_version_max == CURL_SSLVERSION_MAX_NONE as i64 { - ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT as i64; - } - if tls13support.is_null() { - /* If the running GnuTLS doesn't support TLS 1.3, we must not specify a - prioritylist involving that since it will make GnuTLS return an en - error back at us */ - if ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3 as i64 - || ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT as i64 - { - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2 as i64; - } - } else if ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT as i64 { - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3 as i64; - } - match ssl_version | ssl_version_max { - 262148 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.0\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 327684 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.1:+VERS-TLS1.0\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 393220 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 327685 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.1\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 393221 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.2:+VERS-TLS1.1\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 393222 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.2\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 458759 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.3\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 458756 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 458757 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:+VERS-TLS1.1\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - 458758 => { - *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.3:+VERS-TLS1.2\0" - as *const u8 as *const libc::c_char; - return CURLE_OK; - } - _ => {} - } - Curl_failf( - data, - b"GnuTLS: cannot set ssl protocol\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_CONNECT_ERROR; - } -} - -extern "C" fn gtls_connect_step1( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, -) -> CURLcode { - unsafe { - let mut connssl: *mut ssl_connect_data = - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data; - let mut backend: *mut ssl_backend_data = (*connssl).backend; - let mut init_flags: u32 = 0; - let mut session: gnutls_session_t = 0 as *mut gnutls_session_int; - let mut rc: i32 = 0; - let mut sni: bool = 1 as i32 != 0; /* default is SNI enabled */ - let mut transport_ptr: *mut libc::c_void = 0 as *mut libc::c_void; - let mut gnutls_transport_push: gnutls_push_func = None; - let mut gnutls_transport_pull: gnutls_pull_func = None; - #[cfg(ENABLE_IPV6)] - let mut addr: in6_addr = in6_addr { - __in6_u: C2RustUnnamed_8 { - __u6_addr8: [0; 16], - }, - }; - // 选项 - 不开启 ENABLE_IPV6 - #[cfg(not(ENABLE_IPV6))] - let mut addr: in_addr = in_addr { s_addr: 0 }; - let mut prioritylist: *const libc::c_char = 0 as *const libc::c_char; - let mut err: *const libc::c_char = 0 as *const libc::c_char; - #[cfg(not(CURL_DISABLE_PROXY))] - let hostname: *const libc::c_char = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).http_proxy.host.name - } else { - (*conn).host.name - }; - #[cfg(CURL_DISABLE_PROXY)] - let hostname: *const libc::c_char = (*conn).host.name; - - #[cfg(not(CURL_DISABLE_PROXY))] - let certverifyresult: *mut i64 = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - &mut (*data).set.proxy_ssl.certverifyresult - } else { - &mut (*data).set.ssl.certverifyresult - }; - #[cfg(CURL_DISABLE_PROXY)] - let certverifyresult: *mut i64 = &mut (*data).set.ssl.certverifyresult; - - let mut tls13support: *const libc::c_char = 0 as *const libc::c_char; - if (*connssl).state as u32 == ssl_connection_complete as u32 { - /* to make us tolerant against being called more than once for the - same connection */ - return CURLE_OK; - } - if !gtls_inited { - gtls_init(); - } - /* Initialize certverifyresult to OK */ - *certverifyresult = 0 as i64; - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_version = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.version - } else { - (*conn).ssl_config.version - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_version = (*conn).ssl_config.version; - if SSL_CONN_CONFIG_version == CURL_SSLVERSION_SSLv2 as i64 { - Curl_failf( - data, - b"GnuTLS does not support SSLv2\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_CONNECT_ERROR; - } else { - if SSL_CONN_CONFIG_version == CURL_SSLVERSION_SSLv3 as i64 { - sni = 0 as i32 != 0; /* SSLv3 has no SNI */ - } - } - /* allocate a cred struct */ - rc = gnutls_certificate_allocate_credentials(&mut (*backend).cred); - if rc != 0 as i32 { - Curl_failf( - data, - b"gnutls_cert_all_cred() failed: %s\0" as *const u8 as *const libc::c_char, - gnutls_strerror(rc), - ); - return CURLE_SSL_CONNECT_ERROR; - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_authtype = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.authtype as u32 - } else { - (*data).set.ssl.authtype as u32 - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_authtype = (*data).set.ssl.authtype as u32; - #[cfg(HAVE_GNUTLS_SRP)] - if SSL_SET_OPTION_authtype == CURL_TLSAUTH_SRP as u32 { - #[cfg(not(CURL_DISABLE_PROXY))] - Curl_infof( - data, - b"Using TLS-SRP username: %s\0" as *const u8 as *const libc::c_char, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.username - } else { - (*data).set.ssl.username - }, - ); - #[cfg(CURL_DISABLE_PROXY)] - Curl_infof( - data, - b"Using TLS-SRP username: %s\0" as *const u8 as *const libc::c_char, - (*data).set.ssl.username, - ); - rc = gnutls_srp_allocate_client_credentials(&mut (*backend).srp_client_cred); - if rc != 0 as i32 { - Curl_failf( - data, - b"gnutls_srp_allocate_client_cred() failed: %s\0" as *const u8 - as *const libc::c_char, - gnutls_strerror(rc), - ); - return CURLE_OUT_OF_MEMORY; - } - #[cfg(not(CURL_DISABLE_PROXY))] - if true { - rc = gnutls_srp_set_client_credentials( - (*backend).srp_client_cred, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.username - } else { - (*data).set.ssl.username - }, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.password - } else { - (*data).set.ssl.password - }, - ); - } - #[cfg(CURL_DISABLE_PROXY)] - if true { - rc = gnutls_srp_set_client_credentials( - (*backend).srp_client_cred, - (*data).set.ssl.username, - (*data).set.ssl.password, - ); - } - if rc != 0 as i32 { - Curl_failf( - data, - b"gnutls_srp_set_client_cred() failed: %s\0" as *const u8 - as *const libc::c_char, - gnutls_strerror(rc), - ); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - } - #[cfg(not(CURL_DISABLE_PROXY))] - if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CAfile - } else { - (*conn).ssl_config.CAfile - } - .is_null() - { - gnutls_certificate_set_verify_flags((*backend).cred, 0 as u32); - rc = gnutls_certificate_set_x509_trust_file( - (*backend).cred, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CAfile - } else { - (*conn).ssl_config.CAfile - }, - GNUTLS_X509_FMT_PEM, - ); - if rc < 0 as i32 { - Curl_infof( - data, - b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CAfile - } else { - (*conn).ssl_config.CAfile - }, - gnutls_strerror(rc), - ); - if if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifypeer() as i32 - } else { - ((*conn).ssl_config).verifypeer() as i32 - } != 0 - { - *certverifyresult = rc as i64; - return CURLE_SSL_CACERT_BADFILE; - } - } else { - Curl_infof( - data, - b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, - rc, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CAfile - } else { - (*conn).ssl_config.CAfile - }, - ); - } - } - #[cfg(CURL_DISABLE_PROXY)] - if !((*conn).ssl_config.CAfile).is_null() { - /* set the trusted CA cert bundle file */ - gnutls_certificate_set_verify_flags((*backend).cred, 0 as u32); - rc = gnutls_certificate_set_x509_trust_file( - (*backend).cred, - (*conn).ssl_config.CAfile, - GNUTLS_X509_FMT_PEM, - ); - if rc < 0 as i32 { - Curl_infof( - data, - b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, - (*conn).ssl_config.CAfile, - gnutls_strerror(rc), - ); - if ((*conn).ssl_config).verifypeer() != 0 { - *certverifyresult = rc as i64; - return CURLE_SSL_CACERT_BADFILE; - } - } else { - Curl_infof( - data, - b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, - rc, - (*conn).ssl_config.CAfile, - ); - } - } - - #[cfg(not(CURL_DISABLE_PROXY))] - if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CApath - } else { - (*conn).ssl_config.CApath - } - .is_null() - { - rc = gnutls_certificate_set_x509_trust_dir( - (*backend).cred, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CApath - } else { - (*conn).ssl_config.CApath - }, - GNUTLS_X509_FMT_PEM, - ); - if rc < 0 as i32 { - Curl_infof( - data, - b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CApath - } else { - (*conn).ssl_config.CApath - }, - gnutls_strerror(rc), - ); - if if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifypeer() as i32 - } else { - ((*conn).ssl_config).verifypeer() as i32 - } != 0 - { - *certverifyresult = rc as i64; - return CURLE_SSL_CACERT_BADFILE; - } - } else { - Curl_infof( - data, - b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, - rc, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CApath - } else { - (*conn).ssl_config.CApath - }, - ); - } - } - #[cfg(CURL_DISABLE_PROXY)] - if !((*conn).ssl_config.CApath).is_null() { - /* set the trusted CA cert directory */ - rc = gnutls_certificate_set_x509_trust_dir( - (*backend).cred, - (*conn).ssl_config.CApath, - GNUTLS_X509_FMT_PEM, - ); - if rc < 0 as i32 { - Curl_infof( - data, - b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, - (*conn).ssl_config.CApath, - gnutls_strerror(rc), - ); - if ((*conn).ssl_config).verifypeer() != 0 { - *certverifyresult = rc as i64; - return CURLE_SSL_CACERT_BADFILE; - } - } else { - Curl_infof( - data, - b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, - rc, - (*conn).ssl_config.CApath, - ); - } - } - - // todo - 497 - // #[cfg(CURL_CA_FALLBACK)] - #[cfg(not(CURL_DISABLE_PROXY))] - if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.CRLfile - } else { - (*data).set.ssl.CRLfile - } - .is_null() - { - rc = gnutls_certificate_set_x509_crl_file( - (*backend).cred, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.CRLfile - } else { - (*data).set.ssl.CRLfile - }, - GNUTLS_X509_FMT_PEM, - ); - if rc < 0 as i32 { - Curl_failf( - data, - b"error reading crl file %s (%s)\0" as *const u8 as *const libc::c_char, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.CRLfile - } else { - (*data).set.ssl.CRLfile - }, - gnutls_strerror(rc), - ); - return CURLE_SSL_CRL_BADFILE; - } else { - Curl_infof( - data, - b"found %d CRL in %s\0" as *const u8 as *const libc::c_char, - rc, - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.CRLfile - } else { - (*data).set.ssl.CRLfile - }, - ); - } - } - #[cfg(CURL_DISABLE_PROXY)] - if !((*data).set.ssl.CRLfile).is_null() { - /* set the CRL list file */ - rc = gnutls_certificate_set_x509_crl_file( - (*backend).cred, - (*data).set.ssl.CRLfile, - GNUTLS_X509_FMT_PEM, - ); - if rc < 0 as i32 { - Curl_failf( - data, - b"error reading crl file %s (%s)\0" as *const u8 as *const libc::c_char, - (*data).set.ssl.CRLfile, - gnutls_strerror(rc), - ); - return CURLE_SSL_CRL_BADFILE; - } else { - Curl_infof( - data, - b"found %d CRL in %s\0" as *const u8 as *const libc::c_char, - rc, - (*data).set.ssl.CRLfile, - ); - } - } - /* Initialize TLS session as a client */ - init_flags = ((1 as i32) << 1 as i32) as u32; - #[cfg(GNUTLS_FORCE_CLIENT_CERT)] - if true { - init_flags |= ((1 as i32) << 9 as i32) as u32; - } - #[cfg(GNUTLS_NO_TICKETS)] - if true { - /* Disable TLS session tickets */ - init_flags |= ((1 as i32) << 10 as i32) as u32; - } - rc = gnutls_init(&mut (*backend).session, init_flags); - if rc != 0 as i32 { - Curl_failf( - data, - b"gnutls_init() failed: %d\0" as *const u8 as *const libc::c_char, - rc, - ); - return CURLE_SSL_CONNECT_ERROR; - } - /* convenient assign */ - session = (*backend).session; - // done - 条件编译 - 542 - #[cfg(ENABLE_IPV6)] - if 0 as i32 - == inet_pton( - 2 as i32, - hostname, - &mut addr as *mut in6_addr as *mut libc::c_void, - ) - && 0 as i32 - == inet_pton( - 10 as i32, - hostname, - &mut addr as *mut in6_addr as *mut libc::c_void, - ) - && sni as i32 != 0 - && gnutls_server_name_set( - session, - GNUTLS_NAME_DNS, - hostname as *const libc::c_void, - strlen(hostname), - ) < 0 as i32 - { - Curl_infof( - data, - b"WARNING: failed to configure server name indication (SNI) TLS extension\0" - as *const u8 as *const libc::c_char, - ); - } - #[cfg(not(ENABLE_IPV6))] - if 0 as i32 - == inet_pton( - 2 as i32, - hostname, - &mut addr as *mut in_addr as *mut libc::c_void, - ) - && sni as i32 != 0 - && gnutls_server_name_set( - session, - GNUTLS_NAME_DNS, - hostname as *const libc::c_void, - strlen(hostname), - ) < 0 as i32 - { - Curl_infof( - data, - b"WARNING: failed to configure server name indication (SNI) TLS extension\0" - as *const u8 as *const libc::c_char, - ); - } - /* Use default priorities */ - rc = gnutls_set_default_priority(session); - if rc != 0 as i32 { - return CURLE_SSL_CONNECT_ERROR; - } - /* "In GnuTLS 3.6.5, TLS 1.3 is enabled by default" */ - tls13support = gnutls_check_version(b"3.6.5\0" as *const u8 as *const libc::c_char); - /* Ensure +SRP comes at the *end* of all relevant strings so that it can be - * removed if a run-time error indicates that SRP is not supported by this - * GnuTLS version */ - match SSL_CONN_CONFIG_version { - 7 => { - if tls13support.is_null() { - Curl_failf( - data, - b"This GnuTLS installation does not support TLS 1.3\0" as *const u8 - as *const libc::c_char, - ); - return CURLE_SSL_CONNECT_ERROR; + use crate::src::vtls::vtls::*; + use libc; + use rust_ffi::src::ffi_alias::type_alias::*; + use rust_ffi::src::ffi_fun::fun_call::*; + use rust_ffi::src::ffi_struct::struct_define::*; + + static mut gtls_inited: bool = 0 as i32 != 0; + extern "C" fn gtls_push( + mut s: *mut libc::c_void, + mut buf: *const libc::c_void, + mut len: size_t, + ) -> ssize_t { + let mut sock: curl_socket_t = unsafe{*(s as *mut curl_socket_t)}; + #[cfg(not(CURLDEBUG))] + let mut ret: ssize_t = unsafe{send(sock, buf, len, MSG_NOSIGNAL as i32)}; + + #[cfg(CURLDEBUG)] + let mut ret: ssize_t = unsafe{curl_dbg_send( + sock, + buf, + len, + MSG_NOSIGNAL as i32, + 86 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + )}; + return ret; + } + extern "C" fn gtls_pull( + mut s: *mut libc::c_void, + mut buf: *mut libc::c_void, + mut len: size_t, + ) -> ssize_t { + let mut sock: curl_socket_t = unsafe{*(s as *mut curl_socket_t)}; + #[cfg(not(CURLDEBUG))] + let mut ret: ssize_t = unsafe{recv(sock, buf, len, 0 as i32)}; + + #[cfg(CURLDEBUG)] + let mut ret: ssize_t = unsafe{curl_dbg_recv( + sock, + buf, + len, + 0 as i32, + 93 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + )}; + return ret; + } + extern "C" fn gtls_push_ssl( + mut s: *mut libc::c_void, + mut buf: *const libc::c_void, + mut len: size_t, + ) -> ssize_t { + unsafe { + return gnutls_record_send(s as gnutls_session_t, buf, len); + } + } + extern "C" fn gtls_pull_ssl( + mut s: *mut libc::c_void, + mut buf: *mut libc::c_void, + mut len: size_t, + ) -> ssize_t { + unsafe { + return gnutls_record_recv(s as gnutls_session_t, buf, len); + } + } + + /* gtls_init() + * + * Global GnuTLS init, called from Curl_ssl_init(). This calls functions that + * are not thread-safe and thus this function itself is not thread-safe and + * must only be called from within curl_global_init() to keep the thread + * situation under control! + */ + extern "C" fn gtls_init() -> i32 { + + let mut ret: i32 = 1 as i32; + if unsafe{!gtls_inited} { + ret = if unsafe{gnutls_global_init()} != 0 { + 0 as i32 + } else { + 1 as i32 + }; + + // #[cfg(GTLSDEBUG)] + unsafe{gtls_inited = 1 as i32 != 0;} + } + return ret; + } + + extern "C" fn gtls_cleanup() { + + if unsafe{gtls_inited} { + unsafe{gnutls_global_deinit(); + gtls_inited = 0 as i32 != 0;} + } + + } + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + extern "C" fn showtime(mut data: *mut Curl_easy, mut text: *const libc::c_char, mut stamp: time_t) { + let mut buffer: tm = tm { + tm_sec: 0, + tm_min: 0, + tm_hour: 0, + tm_mday: 0, + tm_mon: 0, + tm_year: 0, + tm_wday: 0, + tm_yday: 0, + tm_isdst: 0, + tm_gmtoff: 0, + tm_zone: 0 as *const libc::c_char, + }; + let mut tm: *const tm = &mut buffer; + let mut str: [libc::c_char; 96] = [0; 96]; + let mut result: CURLcode = unsafe{Curl_gmtime(stamp, &mut buffer)}; + if result as u64 != 0 { + return; + } + unsafe{ curl_msnprintf( + str.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 96]>() as u64, + b" %s: %s, %02d %s %4d %02d:%02d:%02d GMT\0" as *const u8 as *const libc::c_char, + text, + Curl_wkday[(if (*tm).tm_wday != 0 { + (*tm).tm_wday - 1 as i32 + } else { + 6 as i32 + }) as usize], + (*tm).tm_mday, + Curl_month[(*tm).tm_mon as usize], + (*tm).tm_year + 1900 as i32, + (*tm).tm_hour, + (*tm).tm_min, + (*tm).tm_sec, + ); + Curl_infof( + data, + b"%s\0" as *const u8 as *const libc::c_char, + str.as_mut_ptr(), + );} + + } + extern "C" fn load_file(mut file: *const libc::c_char) -> gnutls_datum_t { + let mut f: *mut FILE = 0 as *mut FILE; + let mut loaded_file: gnutls_datum_t = { + gnutls_datum_t { + data: 0 as *mut u8, + size: 0 as u32, + } + }; + let mut filelen: i64 = 0; + let mut ptr: *mut libc::c_void = 0 as *mut libc::c_void; + unsafe{ + match () { + #[cfg(not(CURLDEBUG))] + _ => { + f = fopen(file, b"rb\0" as *const u8 as *const libc::c_char); + } + #[cfg(CURLDEBUG)] + _ => { + f = curl_dbg_fopen( + file, + b"rb\0" as *const u8 as *const libc::c_char, + 170 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ); + } + } + } + if f.is_null() { + return loaded_file; + } + unsafe{ + 'out: loop { + if !(fseek(f, 0 as i64, 2 as i32) != 0 as i32 + || { + filelen = ftell(f); + filelen < 0 as i64 + } + || fseek(f, 0 as i64, 0 as i32) != 0 as i32 + || { + match () { + #[cfg(not(CURLDEBUG))] + _ => { + ptr = + Curl_cmalloc.expect("non-null function pointer")(filelen as size_t); + } + #[cfg(CURLDEBUG)] + _ => { + ptr = curl_dbg_malloc( + filelen as size_t, + 176 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ); + } + } + + ptr.is_null() + }) + { + break 'out; + } + + if fread(ptr, 1 as u64, filelen as size_t, f) < filelen as size_t { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(ptr); + + #[cfg(CURLDEBUG)] + curl_dbg_free( + ptr, + 179 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ); + + break 'out; + } else { + loaded_file.data = ptr as *mut u8; + loaded_file.size = filelen as u32; + } + + break 'out; + } + } + #[cfg(not(CURLDEBUG))] + unsafe{fclose(f);} + + #[cfg(CURLDEBUG)] + unsafe{curl_dbg_fclose( + f, + 186 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + );} + return loaded_file; + + } + extern "C" fn unload_file(mut data: gnutls_datum_t) { + #[cfg(not(CURLDEBUG))] + unsafe{Curl_cfree.expect("non-null function pointer")(data.data as *mut libc::c_void);} + + #[cfg(CURLDEBUG)] + unsafe{curl_dbg_free( + data.data as *mut libc::c_void, + 192 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + );} + } + + /* this function does a SSL/TLS (re-)handshake */ + extern "C" fn handshake( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + mut duringconnect: bool, + mut nonblocking: bool, + ) -> CURLcode { + let mut connssl: *mut ssl_connect_data =unsafe{ + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; + let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; + let mut session: gnutls_session_t = unsafe{(*backend).session}; + let mut sockfd: curl_socket_t = unsafe{(*conn).sock[sockindex as usize]}; + loop { + let mut timeout_ms: timediff_t = 0; + let mut rc: i32 = 0; + /* check allowed time left */ + timeout_ms = unsafe{Curl_timeleft(data, 0 as *mut curltime, duringconnect)}; + if timeout_ms < 0 as i64 { + /* no need to continue if time already is up */ + unsafe{Curl_failf( + data, + b"SSL connection timeout\0" as *const u8 as *const libc::c_char, + )}; + return CURLE_OPERATION_TIMEDOUT; + } + /* if ssl is expecting something, check if it's available. */ + if unsafe{(*connssl).connecting_state as u32} == ssl_connect_2_reading as u32 + || unsafe{(*connssl).connecting_state as u32} == ssl_connect_2_writing as u32 + { + let mut what: i32 = 0; + let mut writefd: curl_socket_t = + if ssl_connect_2_writing as u32 == unsafe{(*connssl).connecting_state as u32} { + sockfd + } else { + -(1 as i32) + }; + let mut readfd: curl_socket_t = + if ssl_connect_2_reading as u32 == unsafe{(*connssl).connecting_state as u32} { + sockfd + } else { + -(1 as i32) + }; + what = unsafe{Curl_socket_check( + readfd, + -(1 as i32), + writefd, + if nonblocking as i32 != 0 { + 0 as i64 + } else if timeout_ms != 0 { + timeout_ms + } else { + 1000 as i64 + }, + )}; + if what < 0 as i32 { + /* fatal error */ + unsafe{Curl_failf( + data, + b"select/poll on SSL socket, errno: %d\0" as *const u8 + as *const libc::c_char, + *__errno_location(), + );} + return CURLE_SSL_CONNECT_ERROR; + } else { + if 0 as i32 == what { + if nonblocking { + return CURLE_OK; + } else { + if timeout_ms != 0 { + /* timeout */ + unsafe{Curl_failf( + data, + b"SSL connection timeout at %ld\0" as *const u8 + as *const libc::c_char, + timeout_ms, + );} + return CURLE_OPERATION_TIMEDOUT; + } + } + } + } + /* socket is readable or writable */ + } + rc = unsafe{gnutls_handshake(session)}; + if rc == -(28 as i32) || rc == -(52 as i32) { + unsafe{ + (*connssl).connecting_state = (if gnutls_record_get_direction(session) != 0 { + ssl_connect_2_writing as i32 + } else { + ssl_connect_2_reading as i32 + }) as ssl_connect_state; + } + } else if rc < 0 as i32 && unsafe{gnutls_error_is_fatal(rc) }== 0 { + let mut strerr: *const libc::c_char = 0 as *const libc::c_char; + if rc == -(16 as i32) { + let mut alert: i32 = unsafe{gnutls_alert_get(session) as i32}; + strerr = unsafe{gnutls_alert_get_name(alert as gnutls_alert_description_t)}; + } + if strerr.is_null() { + strerr = unsafe{gnutls_strerror(rc)}; + } + unsafe{Curl_infof( + data, + b"gnutls_handshake() warning: %s\0" as *const u8 as *const libc::c_char, + strerr, + );} + } else { + if rc < 0 as i32 { + let mut strerr_0: *const libc::c_char = 0 as *const libc::c_char; + if rc == -(12 as i32) { + let mut alert_0: i32 = unsafe{gnutls_alert_get(session) as i32}; + strerr_0 = unsafe{gnutls_alert_get_name(alert_0 as gnutls_alert_description_t)}; + } + if strerr_0.is_null() { + strerr_0 = unsafe{gnutls_strerror(rc)}; + } + unsafe{Curl_failf( + data, + b"gnutls_handshake() failed: %s\0" as *const u8 as *const libc::c_char, + strerr_0, + );} + return CURLE_SSL_CONNECT_ERROR; + } + /* Reset our connect state machine */ + unsafe{ (*connssl).connecting_state = ssl_connect_1;} + return CURLE_OK; + } + } + } + extern "C" fn do_file_type(mut type_0: *const libc::c_char) -> gnutls_x509_crt_fmt_t { + if type_0.is_null() || unsafe{*type_0.offset(0 as isize)} == 0 { + return GNUTLS_X509_FMT_PEM; + } + if unsafe{Curl_strcasecompare(type_0, b"PEM\0" as *const u8 as *const libc::c_char)} != 0 { + return GNUTLS_X509_FMT_PEM; + } + if unsafe{Curl_strcasecompare(type_0, b"DER\0" as *const u8 as *const libc::c_char)} != 0 { + return GNUTLS_X509_FMT_DER; + } + return GNUTLS_X509_FMT_PEM; + + } + extern "C" fn set_ssl_version_min_max( + mut data: *mut Curl_easy, + mut prioritylist: *mut *const libc::c_char, + mut tls13support: *const libc::c_char, + ) -> CURLcode { + let mut conn: *mut connectdata = unsafe{(*data).conn}; + #[cfg(not(CURL_DISABLE_PROXY))] + unsafe{let mut ssl_version: i64 = if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.version + } else { + (*conn).ssl_config.version + };} + #[cfg(CURL_DISABLE_PROXY)] + unsafe{let mut ssl_version: i64 = (*conn).ssl_config.version;} + + #[cfg(not(CURL_DISABLE_PROXY))] + unsafe{let mut ssl_version_max: i64 = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.version_max + } else { + (*conn).ssl_config.version_max + };} + #[cfg(CURL_DISABLE_PROXY)] + unsafe{let mut ssl_version_max: i64 = (*conn).ssl_config.version_max; + + if ssl_version == CURL_SSLVERSION_DEFAULT as i64 + || ssl_version == CURL_SSLVERSION_TLSv1 as i64 + { + ssl_version = CURL_SSLVERSION_TLSv1_0 as i64; + } + if ssl_version_max == CURL_SSLVERSION_MAX_NONE as i64 { + ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT as i64; + } + if tls13support.is_null() { + /* If the running GnuTLS doesn't support TLS 1.3, we must not specify a + prioritylist involving that since it will make GnuTLS return an en + error back at us */ + if ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3 as i64 + || ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT as i64 + { + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2 as i64; + } + } else if ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT as i64 { + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3 as i64; + } + match ssl_version | ssl_version_max { + 262148 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.0\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 327684 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.1:+VERS-TLS1.0\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 393220 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 327685 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.1\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 393221 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.2:+VERS-TLS1.1\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 393222 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.2\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 458759 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.3\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 458756 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 458757 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:+VERS-TLS1.1\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + 458758 => { + *prioritylist = b"NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509:-VERS-SSL3.0:-VERS-TLS-ALL:+VERS-TLS1.3:+VERS-TLS1.2\0" + as *const u8 as *const libc::c_char; + return CURLE_OK; + } + _ => {} + } + Curl_failf( + data, + b"GnuTLS: cannot set ssl protocol\0" as *const u8 as *const libc::c_char, + );} + return CURLE_SSL_CONNECT_ERROR; + + } + + extern "C" fn gtls_connect_step1( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + ) -> CURLcode { + let mut connssl: *mut ssl_connect_data =unsafe{ + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; + let mut backend: *mut ssl_backend_data =unsafe{ (*connssl).backend}; + let mut init_flags: u32 = 0; + let mut session: gnutls_session_t = 0 as *mut gnutls_session_int; + let mut rc: i32 = 0; + let mut sni: bool = 1 as i32 != 0; /* default is SNI enabled */ + let mut transport_ptr: *mut libc::c_void = 0 as *mut libc::c_void; + let mut gnutls_transport_push: gnutls_push_func = None; + let mut gnutls_transport_pull: gnutls_pull_func = None; + #[cfg(ENABLE_IPV6)] + let mut addr: in6_addr = in6_addr { + __in6_u: C2RustUnnamed_8 { + __u6_addr8: [0; 16], + }, + }; + // 选项 - 不开启 ENABLE_IPV6 + #[cfg(not(ENABLE_IPV6))] + let mut addr: in_addr = in_addr { s_addr: 0 }; + let mut prioritylist: *const libc::c_char = 0 as *const libc::c_char; + let mut err: *const libc::c_char = 0 as *const libc::c_char; + #[cfg(not(CURL_DISABLE_PROXY))] + let hostname: *const libc::c_char = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).http_proxy.host.name + } else { + (*conn).host.name + }}; + #[cfg(CURL_DISABLE_PROXY)] + let hostname: *const libc::c_char = unsafe{(*conn).host.name}; + + #[cfg(not(CURL_DISABLE_PROXY))] + let certverifyresult: *mut i64 = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + &mut (*data).set.proxy_ssl.certverifyresult + } else { + &mut (*data).set.ssl.certverifyresult + }}; + #[cfg(CURL_DISABLE_PROXY)] + let certverifyresult: *mut i64 =unsafe{ &mut (*data).set.ssl.certverifyresult}; + + let mut tls13support: *const libc::c_char = 0 as *const libc::c_char; + if unsafe{(*connssl).state as u32 == ssl_connection_complete as u32 }{ + /* to make us tolerant against being called more than once for the + same connection */ + return CURLE_OK; + } + if unsafe{ !gtls_inited }{ + gtls_init(); + } + /* Initialize certverifyresult to OK */ + unsafe{*certverifyresult = 0 as i64;} + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_version = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.version + } else { + (*conn).ssl_config.version + }}; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_version = unsafe{(*conn).ssl_config.version}; + if SSL_CONN_CONFIG_version == CURL_SSLVERSION_SSLv2 as i64 { + unsafe{ + Curl_failf( + data, + b"GnuTLS does not support SSLv2\0" as *const u8 as *const libc::c_char, + );} + return CURLE_SSL_CONNECT_ERROR; + } else { + if SSL_CONN_CONFIG_version == CURL_SSLVERSION_SSLv3 as i64 { + sni = 0 as i32 != 0; /* SSLv3 has no SNI */ + } + } + /* allocate a cred struct */ + rc = unsafe{gnutls_certificate_allocate_credentials(&mut (*backend).cred)}; + if rc != 0 as i32 { + unsafe{ Curl_failf( + data, + b"gnutls_cert_all_cred() failed: %s\0" as *const u8 as *const libc::c_char, + gnutls_strerror(rc), + );} + return CURLE_SSL_CONNECT_ERROR; + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_authtype = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.authtype as u32 + } else { + (*data).set.ssl.authtype as u32 + }}; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_authtype = unsafe{(*data).set.ssl.authtype as u32}; + #[cfg(HAVE_GNUTLS_SRP)] + if SSL_SET_OPTION_authtype == CURL_TLSAUTH_SRP as u32 { + #[cfg(not(CURL_DISABLE_PROXY))] + unsafe{Curl_infof( + data, + b"Using TLS-SRP username: %s\0" as *const u8 as *const libc::c_char, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.username + } else { + (*data).set.ssl.username + }, + );} + #[cfg(CURL_DISABLE_PROXY)] + unsafe{Curl_infof( + data, + b"Using TLS-SRP username: %s\0" as *const u8 as *const libc::c_char, + (*data).set.ssl.username, + ); + rc = gnutls_srp_allocate_client_credentials(&mut (*backend).srp_client_cred); + if rc != 0 as i32 { + Curl_failf( + data, + b"gnutls_srp_allocate_client_cred() failed: %s\0" as *const u8 + as *const libc::c_char, + gnutls_strerror(rc), + ); + return CURLE_OUT_OF_MEMORY; + }} + #[cfg(not(CURL_DISABLE_PROXY))] + if true { + unsafe{rc = gnutls_srp_set_client_credentials( + (*backend).srp_client_cred, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.username + } else { + (*data).set.ssl.username + }, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.password + } else { + (*data).set.ssl.password + }, + ); + } + } + #[cfg(CURL_DISABLE_PROXY)] + if true { + unsafe{ + rc = gnutls_srp_set_client_credentials( + (*backend).srp_client_cred, + (*data).set.ssl.username, + (*data).set.ssl.password, + ); + } + } + if rc != 0 as i32 { + unsafe{Curl_failf( + data, + b"gnutls_srp_set_client_cred() failed: %s\0" as *const u8 + as *const libc::c_char, + gnutls_strerror(rc), + );} + return CURLE_BAD_FUNCTION_ARGUMENT; + } + } + #[cfg(not(CURL_DISABLE_PROXY))] + if !if CURLPROXY_HTTPS as u32 == unsafe{(*conn).http_proxy.proxytype as u32} + && ssl_connection_complete as u32 + != unsafe{(*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32} + { + unsafe{(*conn).proxy_ssl_config.CAfile} + } else { + unsafe{(*conn).ssl_config.CAfile} + } + .is_null() + { + unsafe{gnutls_certificate_set_verify_flags((*backend).cred, 0 as u32); + rc = gnutls_certificate_set_x509_trust_file( + (*backend).cred, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CAfile + } else { + (*conn).ssl_config.CAfile + }, + GNUTLS_X509_FMT_PEM, + );} + if rc < 0 as i32 { + unsafe{ + Curl_infof( + data, + b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CAfile + } else { + (*conn).ssl_config.CAfile + }, + gnutls_strerror(rc), + );} + if if CURLPROXY_HTTPS as u32 == unsafe{(*conn).http_proxy.proxytype as u32} + && ssl_connection_complete as u32 + != unsafe{(*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32} + { + unsafe{ ((*conn).proxy_ssl_config).verifypeer() as i32} + } else { + unsafe{((*conn).ssl_config).verifypeer() as i32} + } != 0 + { + unsafe{*certverifyresult = rc as i64;} + return CURLE_SSL_CACERT_BADFILE; + } + } else { + unsafe{Curl_infof( + data, + b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, + rc, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CAfile + } else { + (*conn).ssl_config.CAfile + }, + );} + } + } + // #[cfg(CURL_DISABLE_PROXY)] + if unsafe{!((*conn).ssl_config.CAfile).is_null()} { + /* set the trusted CA cert bundle file */ + unsafe{gnutls_certificate_set_verify_flags((*backend).cred, 0 as u32); + rc = gnutls_certificate_set_x509_trust_file( + (*backend).cred, + (*conn).ssl_config.CAfile, + GNUTLS_X509_FMT_PEM, + );} + if rc < 0 as i32 { + unsafe{Curl_infof( + data, + b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, + (*conn).ssl_config.CAfile, + gnutls_strerror(rc), + );} + if unsafe{((*conn).ssl_config).verifypeer() != 0} { + unsafe{ *certverifyresult = rc as i64;} + return CURLE_SSL_CACERT_BADFILE; + } + } else { + unsafe{Curl_infof( + data, + b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, + rc, + (*conn).ssl_config.CAfile, + );} + } + } + + #[cfg(not(CURL_DISABLE_PROXY))] + if !if CURLPROXY_HTTPS as u32 == unsafe{(*conn).http_proxy.proxytype as u32} + && ssl_connection_complete as u32 + != unsafe{(*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32} + { + unsafe{(*conn).proxy_ssl_config.CApath} + } else { + unsafe{(*conn).ssl_config.CApath} + } + .is_null() + { + rc =unsafe{gnutls_certificate_set_x509_trust_dir( + (*backend).cred, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CApath + } else { + (*conn).ssl_config.CApath + }, + GNUTLS_X509_FMT_PEM, + )}; + if rc < 0 as i32 { + unsafe{Curl_infof( + data, + b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CApath + } else { + (*conn).ssl_config.CApath + }, + gnutls_strerror(rc), + )}; + unsafe{ + if if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifypeer() as i32 + } else { + ((*conn).ssl_config).verifypeer() as i32 + } != 0 + { + *certverifyresult = rc as i64; + return CURLE_SSL_CACERT_BADFILE; + }} + } else { + unsafe{Curl_infof( + data, + b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, + rc, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CApath + } else { + (*conn).ssl_config.CApath + }, + );} + } + } + // #[cfg(CURL_DISABLE_PROXY)] + if unsafe{!((*conn).ssl_config.CApath).is_null()} { + /* set the trusted CA cert directory */ + rc = unsafe{gnutls_certificate_set_x509_trust_dir( + (*backend).cred, + (*conn).ssl_config.CApath, + GNUTLS_X509_FMT_PEM, + )}; + if rc < 0 as i32 { + unsafe{Curl_infof( + data, + b"error reading ca cert file %s (%s)\0" as *const u8 as *const libc::c_char, + (*conn).ssl_config.CApath, + gnutls_strerror(rc), + ); + if ((*conn).ssl_config).verifypeer() != 0 { + *certverifyresult = rc as i64; + return CURLE_SSL_CACERT_BADFILE; + }} + } else { + unsafe{Curl_infof( + data, + b"found %d certificates in %s\0" as *const u8 as *const libc::c_char, + rc, + (*conn).ssl_config.CApath, + );} + } + } + + // todo - 497 + // #[cfg(CURL_CA_FALLBACK)] + #[cfg(not(CURL_DISABLE_PROXY))] + if !if CURLPROXY_HTTPS as u32 == unsafe{(*conn).http_proxy.proxytype as u32} + && unsafe{ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32} + { + unsafe{(*data).set.proxy_ssl.CRLfile} + } else { + unsafe{(*data).set.ssl.CRLfile} + } + .is_null() + { + rc = unsafe{gnutls_certificate_set_x509_crl_file( + (*backend).cred, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.CRLfile + } else { + (*data).set.ssl.CRLfile + }, + GNUTLS_X509_FMT_PEM, + )}; + if rc < 0 as i32 { + unsafe{Curl_failf( + data, + b"error reading crl file %s (%s)\0" as *const u8 as *const libc::c_char, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.CRLfile + } else { + (*data).set.ssl.CRLfile + }, + gnutls_strerror(rc), + )}; + return CURLE_SSL_CRL_BADFILE; + } else { + unsafe{Curl_infof( + data, + b"found %d CRL in %s\0" as *const u8 as *const libc::c_char, + rc, + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.CRLfile + } else { + (*data).set.ssl.CRLfile + }, + )}; + } + } + // #[cfg(CURL_DISABLE_PROXY)] + if unsafe{!((*data).set.ssl.CRLfile).is_null()} { + /* set the CRL list file */ + rc = unsafe{gnutls_certificate_set_x509_crl_file( + (*backend).cred, + (*data).set.ssl.CRLfile, + GNUTLS_X509_FMT_PEM, + )}; + if rc < 0 as i32 { + unsafe{Curl_failf( + data, + b"error reading crl file %s (%s)\0" as *const u8 as *const libc::c_char, + (*data).set.ssl.CRLfile, + gnutls_strerror(rc), + );} + return CURLE_SSL_CRL_BADFILE; + } else { + unsafe{Curl_infof( + data, + b"found %d CRL in %s\0" as *const u8 as *const libc::c_char, + rc, + (*data).set.ssl.CRLfile, + );} + } + } + /* Initialize TLS session as a client */ + init_flags = ((1 as i32) << 1 as i32) as u32; + #[cfg(GNUTLS_FORCE_CLIENT_CERT)] + if true { + init_flags |= ((1 as i32) << 9 as i32) as u32; + } + #[cfg(GNUTLS_NO_TICKETS)] + if true { + /* Disable TLS session tickets */ + init_flags |= ((1 as i32) << 10 as i32) as u32; + } + rc = unsafe{gnutls_init(&mut (*backend).session, init_flags)}; + if rc != 0 as i32 { + unsafe{Curl_failf( + data, + b"gnutls_init() failed: %d\0" as *const u8 as *const libc::c_char, + rc, + );} + return CURLE_SSL_CONNECT_ERROR; + } + /* convenient assign */ + session = unsafe{(*backend).session}; + // done - 条件编译 - 542 + #[cfg(ENABLE_IPV6)] + if 0 as i32 + == unsafe{inet_pton( + 2 as i32, + hostname, + &mut addr as *mut in6_addr as *mut libc::c_void, + )} + && 0 as i32 + == unsafe{inet_pton( + 10 as i32, + hostname, + &mut addr as *mut in6_addr as *mut libc::c_void, + )} + && sni as i32 != 0 + && unsafe{gnutls_server_name_set( + session, + GNUTLS_NAME_DNS, + hostname as *const libc::c_void, + strlen(hostname), + ) < 0 as i32} + { + unsafe{ Curl_infof( + data, + b"WARNING: failed to configure server name indication (SNI) TLS extension\0" + as *const u8 as *const libc::c_char, + ); + } + #[cfg(not(ENABLE_IPV6))] + if unsafe{0 as i32 + == inet_pton( + 2 as i32, + hostname, + &mut addr as *mut in_addr as *mut libc::c_void, + ) + && sni as i32 != 0 + && gnutls_server_name_set( + session, + GNUTLS_NAME_DNS, + hostname as *const libc::c_void, + strlen(hostname), + ) < 0 as i32} + { + unsafe{Curl_infof( + data, + b"WARNING: failed to configure server name indication (SNI) TLS extension\0" + as *const u8 as *const libc::c_char, + );} + } + /* Use default priorities */ + rc = unsafe{gnutls_set_default_priority(session)}; + if rc != 0 as i32 { + return CURLE_SSL_CONNECT_ERROR; + } + /* "In GnuTLS 3.6.5, TLS 1.3 is enabled by default" */ + tls13support = unsafe{gnutls_check_version(b"3.6.5\0" as *const u8 as *const libc::c_char)}; + /* Ensure +SRP comes at the *end* of all relevant strings so that it can be + * removed if a run-time error indicates that SRP is not supported by this + * GnuTLS version */ + unsafe{ + match SSL_CONN_CONFIG_version { + 7 => { + if tls13support.is_null() { + Curl_failf( + data, + b"This GnuTLS installation does not support TLS 1.3\0" as *const u8 + as *const libc::c_char, + ); + return CURLE_SSL_CONNECT_ERROR; + } + } + 0 | 1 | 4 | 5 | 6 => {} + 2 | 3 | _ => { + Curl_failf( + data, + b"GnuTLS does not support SSLv2 or SSLv3\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_CONNECT_ERROR; + } + } + } + let mut result: CURLcode = set_ssl_version_min_max(data, &mut prioritylist, tls13support); + if result as u64 != 0 { + return result; + } + /* Only add SRP to the cipher list if SRP is requested. Otherwise + * GnuTLS will disable TLS 1.3 support. */ + #[cfg(HAVE_GNUTLS_SRP)] + if SSL_SET_OPTION_authtype as u32 == CURL_TLSAUTH_SRP as i32 as u32 { + let mut len: size_t = unsafe{strlen(prioritylist)}; + #[cfg(not(CURLDEBUG))] + let mut prioritysrp: *mut libc::c_char = unsafe{Curl_cmalloc + .expect("non-null function pointer")( + len.wrapping_add(::std::mem::size_of::<[libc::c_char; 5]>() as u64) + .wrapping_add(1 as u64), + ) as *mut libc::c_char}; + #[cfg(CURLDEBUG)] + let mut prioritysrp: *mut libc::c_char = unsafe{curl_dbg_malloc( + len.wrapping_add(::std::mem::size_of::<[libc::c_char; 5]>() as u64) + .wrapping_add(1 as u64), + 591 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ) as *mut libc::c_char}; + if prioritysrp.is_null() { + return CURLE_OUT_OF_MEMORY; + } + unsafe{strcpy(prioritysrp, prioritylist); + strcpy( + prioritysrp.offset(len as isize), + b":+SRP\0" as *const u8 as *const libc::c_char, + ); + rc = gnutls_priority_set_direct(session, prioritysrp, &mut err);} + #[cfg(not(CURLDEBUG))] + unsafe{Curl_cfree.expect("non-null function pointer")(prioritysrp as *mut libc::c_void);} + + #[cfg(CURLDEBUG)] + unsafe{curl_dbg_free( + prioritysrp as *mut libc::c_void, + 597 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + );} + if rc == -(50 as i32) && !err.is_null() { + unsafe{Curl_infof( + data, + b"This GnuTLS does not support SRP\0" as *const u8 as *const libc::c_char, + );} + } + } else { + unsafe{Curl_infof( + data, + b"GnuTLS ciphers: %s\0" as *const u8 as *const libc::c_char, + prioritylist, + );} + rc = unsafe{gnutls_priority_set_direct(session, prioritylist, &mut err)}; + } + #[cfg(not(HAVE_GNUTLS_SRP))] + if true { + unsafe{Curl_infof( + data, + b"GnuTLS ciphers: %s\0" as *const u8 as *const libc::c_char, + prioritylist, + ); + rc = gnutls_priority_set_direct(session, prioritylist, &mut err);} + } + if rc != 0 as i32 { + unsafe{Curl_failf( + data, + b"Error %d setting GnuTLS cipher list starting with %s\0" as *const u8 + as *const libc::c_char, + rc, + err, + );} + return CURLE_SSL_CONNECT_ERROR; + } + if unsafe{((*conn).bits).tls_enable_alpn() != 0 }{ + let mut cur: i32 = 0 as i32; + let mut protocols: [gnutls_datum_t; 2] = [gnutls_datum_t { + data: 0 as *mut u8, + size: 0, + }; 2]; + // done - 623 + #[cfg(not(CURL_DISABLE_PROXY))] + let CURL_DISABLE_PROXY_flag = unsafe{(!(CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32) + || ((*conn).bits).tunnel_proxy() == 0)}; + + #[cfg(CURL_DISABLE_PROXY)] + let CURL_DISABLE_PROXY_flag = true; + #[cfg(USE_HTTP2)] + if unsafe{(*data).state.httpwant as i32} >= CURL_HTTP_VERSION_2_0 as i32 + && CURL_DISABLE_PROXY_flag + { + protocols[cur as usize].data = + b"h2\0" as *const u8 as *const libc::c_char as *mut u8; + protocols[cur as usize].size = 2 as u32; + cur += 1; + unsafe{Curl_infof( + data, + b"ALPN, offering %.*s\0" as *const u8 as *const libc::c_char, + 2 as i32, + b"h2\0" as *const u8 as *const libc::c_char, + );} + } + protocols[cur as usize].data = + b"http/1.1\0" as *const u8 as *const libc::c_char as *mut u8; + protocols[cur as usize].size = 8 as u32; + cur += 1; + unsafe{ Curl_infof( + data, + b"ALPN, offering %s\0" as *const u8 as *const libc::c_char, + b"http/1.1\0" as *const u8 as *const libc::c_char, + ); + gnutls_alpn_set_protocols(session, protocols.as_mut_ptr(), cur as u32, 0 as u32);}} + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_primary_clientcert = if CURLPROXY_HTTPS as u32 + == unsafe{(*conn).http_proxy.proxytype as u32} + && ssl_connection_complete as u32 + != unsafe{(*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32} + { + unsafe{(*data).set.proxy_ssl.primary.clientcert} + } else { + unsafe{(*data).set.ssl.primary.clientcert} + }; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_primary_clientcert = (*data).set.ssl.primary.clientcert; + + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_key_passwd = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.key_passwd + } else { + (*data).set.ssl.key_passwd + }}; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_key_passwd = unsafe{(*data).set.ssl.key_passwd}; + + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_key = unsafe{if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.key + } else { + (*data).set.ssl.key + }}; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_key = unsafe{(*data).set.ssl.key}; + + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_cert_type = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.cert_type + } else { + (*data).set.ssl.cert_type + }}; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_cert_type = unsafe{(*data).set.ssl.cert_type}; + unsafe{ + if !SSL_SET_OPTION_primary_clientcert.is_null() { + if !SSL_SET_OPTION_key_passwd.is_null() { + let supported_key_encryption_algorithms: u32 = (GNUTLS_PKCS_PKCS12_3DES as i32 + | GNUTLS_PKCS_PKCS12_ARCFOUR as i32 + | GNUTLS_PKCS_PKCS12_RC2_40 as i32 + | GNUTLS_PKCS_PBES2_3DES as i32 + | GNUTLS_PKCS_PBES2_AES_128 as i32 + | GNUTLS_PKCS_PBES2_AES_192 as i32 + | GNUTLS_PKCS_PBES2_AES_256 as i32) + as u32; + rc = gnutls_certificate_set_x509_key_file2( + (*backend).cred, + SSL_SET_OPTION_primary_clientcert, + if !SSL_SET_OPTION_key.is_null() { + SSL_SET_OPTION_key + } else { + SSL_SET_OPTION_primary_clientcert + }, + do_file_type(SSL_SET_OPTION_cert_type), + SSL_SET_OPTION_key_passwd, + supported_key_encryption_algorithms, + ); + if rc != 0 as i32 { + Curl_failf( + data, + b"error reading X.509 potentially-encrypted key file: %s\0" as *const u8 + as *const libc::c_char, + gnutls_strerror(rc), + ); + return CURLE_SSL_CONNECT_ERROR; + } + } else if gnutls_certificate_set_x509_key_file( + (*backend).cred, + SSL_SET_OPTION_primary_clientcert, + if !(SSL_SET_OPTION_key).is_null() { + SSL_SET_OPTION_key + } else { + SSL_SET_OPTION_primary_clientcert + }, + do_file_type(SSL_SET_OPTION_cert_type), + ) != 0 as i32 + { + Curl_failf( + data, + b"error reading X.509 key or certificate file\0" as *const u8 + as *const libc::c_char, + ); + return CURLE_SSL_CONNECT_ERROR; + } + + } + } + /* put the credentials to the current session */ + #[cfg(HAVE_GNUTLS_SRP)] + if SSL_SET_OPTION_authtype == CURL_TLSAUTH_SRP as u32 { + rc = unsafe{gnutls_credentials_set( + session, + GNUTLS_CRD_SRP, + (*backend).srp_client_cred as *mut libc::c_void, + )}; + if rc != 0 as i32 { + unsafe{ + Curl_failf( + data, + b"gnutls_credentials_set() failed: %s\0" as *const u8 as *const libc::c_char, + gnutls_strerror(rc), + ); + return CURLE_SSL_CONNECT_ERROR; + }} + } else { + rc = unsafe{gnutls_credentials_set( + session, + GNUTLS_CRD_CERTIFICATE, + (*backend).cred as *mut libc::c_void, + )}; + if rc != 0 as i32 { + unsafe{Curl_failf( + data, + b"gnutls_credentials_set() failed: %s\0" as *const u8 as *const libc::c_char, + gnutls_strerror(rc), + );} + return CURLE_SSL_CONNECT_ERROR; + } + } + #[cfg(not(HAVE_GNUTLS_SRP))] + if true { + rc = unsafe{gnutls_credentials_set( + session, + GNUTLS_CRD_CERTIFICATE, + (*backend).cred as *mut libc::c_void, + )}; + if rc != 0 as i32 { + unsafe{Curl_failf( + data, + b"gnutls_credentials_set() failed: %s\0" as *const u8 as *const libc::c_char, + gnutls_strerror(rc), + );} + return CURLE_SSL_CONNECT_ERROR; + } + } + + #[cfg(not(CURL_DISABLE_PROXY))] + if unsafe{((*conn).proxy_ssl[sockindex as usize]).use_0()} != 0 { + unsafe{ + transport_ptr = + (*(*conn).proxy_ssl[sockindex as usize].backend).session as *mut libc::c_void; + gnutls_transport_push = Some( + gtls_push_ssl + as unsafe extern "C" fn( + *mut libc::c_void, + *const libc::c_void, + size_t, + ) -> ssize_t, + ); + gnutls_transport_pull = Some( + gtls_pull_ssl + as unsafe extern "C" fn( + *mut libc::c_void, + *mut libc::c_void, + size_t, + ) -> ssize_t, + );} + } else { + unsafe{ + transport_ptr = &mut *((*conn).sock).as_mut_ptr().offset(sockindex as isize) + as *mut curl_socket_t as *mut libc::c_void; + gnutls_transport_push = Some( + gtls_push + as unsafe extern "C" fn( + *mut libc::c_void, + *const libc::c_void, + size_t, + ) -> ssize_t, + ); + gnutls_transport_pull = Some( + gtls_pull + as unsafe extern "C" fn( + *mut libc::c_void, + *mut libc::c_void, + size_t, + ) -> ssize_t, + );} + } + #[cfg(CURL_DISABLE_PROXY)] + if true { + unsafe{ + /* file descriptor for the socket */ + transport_ptr = &mut *((*conn).sock).as_mut_ptr().offset(sockindex as isize) + as *mut curl_socket_t as *mut libc::c_void; + gnutls_transport_push = Some( + gtls_push + as unsafe extern "C" fn( + *mut libc::c_void, + *const libc::c_void, + size_t, + ) -> ssize_t, + ); + gnutls_transport_pull = Some( + gtls_pull + as unsafe extern "C" fn( + *mut libc::c_void, + *mut libc::c_void, + size_t, + ) -> ssize_t, + ); + } + } + unsafe{ + /* set the connection handle */ + gnutls_transport_set_ptr(session, transport_ptr); + /* register callback functions to send and receive data. */ + gnutls_transport_set_push_function(session, gnutls_transport_push); + gnutls_transport_set_pull_function(session, gnutls_transport_pull);} + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifystatus = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifystatus() as i32 + } else { + ((*conn).ssl_config).verifystatus() as i32 + }}; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_verifystatus = ((*conn).ssl_config).verifystatus(); + if SSL_CONN_CONFIG_verifystatus != 0 { + rc = unsafe{gnutls_ocsp_status_request_enable_client( + session, + 0 as *mut gnutls_datum_t, + 0 as size_t, + 0 as *mut gnutls_datum_t, + )}; + if rc != 0 as i32 { + unsafe{ Curl_failf( + data, + b"gnutls_ocsp_status_request_enable_client() failed: %d\0" as *const u8 + as *const libc::c_char, + rc, + );} + return CURLE_SSL_CONNECT_ERROR; + } + } + /* This might be a reconnect, so we check for a session ID in the cache + to speed up things */ + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_primary_sessionid = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*data).set.proxy_ssl.primary).sessionid() as i32 + } else { + ((*data).set.ssl.primary).sessionid() as i32 + }}; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_primary_sessionid = unsafe{((*data).set.ssl.primary).sessionid()}; + unsafe{ + if SSL_SET_OPTION_primary_sessionid != 0 { + let mut ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; + let mut ssl_idsize: size_t = 0; + Curl_ssl_sessionid_lock(data); + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_IS_PROXY_void_1 = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + 1 as i32 + } else { + 0 as i32 + } != 0; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_IS_PROXY_void_1 = if 0 as i32 != 0 { 1 as i32 } else { 0 as i32 } != 0; + if !Curl_ssl_getsessionid( + data, + conn, + SSL_IS_PROXY_void_1, + &mut ssl_sessionid, + &mut ssl_idsize, + sockindex, + ) { + /* we got a session id, use it! */ + gnutls_session_set_data(session, ssl_sessionid, ssl_idsize); + /* Informational message */ + Curl_infof( + data, + b"SSL re-using session ID\0" as *const u8 as *const libc::c_char, + ); + } + Curl_ssl_sessionid_unlock(data); + } + } + return CURLE_OK; + + } + extern "C" fn pkp_pin_peer_pubkey( + mut data: *mut Curl_easy, + mut cert: gnutls_x509_crt_t, + mut pinnedpubkey: *const libc::c_char, + ) -> CURLcode { + /* Scratch */ + let mut len1: size_t = 0 as size_t; + let mut len2: size_t = 0 as size_t; + let mut buff1: *mut u8 = 0 as *mut u8; + let mut key: gnutls_pubkey_t = 0 as gnutls_pubkey_t; + /* Result is returned to caller */ + let mut result: CURLcode = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + /* if a path wasn't specified, don't pin */ + if pinnedpubkey.is_null() { + return CURLE_OK; + } + if cert.is_null() { + return result; + } + let mut ret: i32 = 0; + /* Begin Gyrations to get the public key */ + unsafe{gnutls_pubkey_init(&mut key); + ret = gnutls_pubkey_import_x509(key, cert, 0 as u32);} + if !(ret < 0 as i32) { + ret = unsafe{gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, 0 as *mut libc::c_void, &mut len1)}; + if !(ret != -(51 as i32) || len1 == 0 as u64) { + unsafe{ + match () { + #[cfg(not(CURLDEBUG))] + _ => { + buff1 = Curl_cmalloc.expect("non-null function pointer")(len1) as *mut u8; + } + #[cfg(CURLDEBUG)] + _ => { + buff1 = curl_dbg_malloc( + len1, + 785 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ) as *mut u8; + } + } } - } - 0 | 1 | 4 | 5 | 6 => {} - 2 | 3 | _ => { - Curl_failf( - data, - b"GnuTLS does not support SSLv2 or SSLv3\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_CONNECT_ERROR; - } - } - let mut result: CURLcode = set_ssl_version_min_max(data, &mut prioritylist, tls13support); - if result as u64 != 0 { - return result; - } - /* Only add SRP to the cipher list if SRP is requested. Otherwise - * GnuTLS will disable TLS 1.3 support. */ - #[cfg(HAVE_GNUTLS_SRP)] - if SSL_SET_OPTION_authtype as u32 == CURL_TLSAUTH_SRP as i32 as u32 { - let mut len: size_t = strlen(prioritylist); - #[cfg(not(CURLDEBUG))] - let mut prioritysrp: *mut libc::c_char = Curl_cmalloc - .expect("non-null function pointer")( - len.wrapping_add(::std::mem::size_of::<[libc::c_char; 5]>() as u64) - .wrapping_add(1 as u64), - ) as *mut libc::c_char; - #[cfg(CURLDEBUG)] - let mut prioritysrp: *mut libc::c_char = curl_dbg_malloc( - len.wrapping_add(::std::mem::size_of::<[libc::c_char; 5]>() as u64) - .wrapping_add(1 as u64), - 591 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ) as *mut libc::c_char; - if prioritysrp.is_null() { - return CURLE_OUT_OF_MEMORY; - } - strcpy(prioritysrp, prioritylist); - strcpy( - prioritysrp.offset(len as isize), - b":+SRP\0" as *const u8 as *const libc::c_char, - ); - rc = gnutls_priority_set_direct(session, prioritysrp, &mut err); - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(prioritysrp as *mut libc::c_void); - - #[cfg(CURLDEBUG)] - curl_dbg_free( - prioritysrp as *mut libc::c_void, - 597 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - if rc == -(50 as i32) && !err.is_null() { - Curl_infof( - data, - b"This GnuTLS does not support SRP\0" as *const u8 as *const libc::c_char, - ); - } - } else { - Curl_infof( - data, - b"GnuTLS ciphers: %s\0" as *const u8 as *const libc::c_char, - prioritylist, - ); - rc = gnutls_priority_set_direct(session, prioritylist, &mut err); - } - #[cfg(not(HAVE_GNUTLS_SRP))] - if true { - Curl_infof( - data, - b"GnuTLS ciphers: %s\0" as *const u8 as *const libc::c_char, - prioritylist, - ); - rc = gnutls_priority_set_direct(session, prioritylist, &mut err); - } - if rc != 0 as i32 { - Curl_failf( - data, - b"Error %d setting GnuTLS cipher list starting with %s\0" as *const u8 - as *const libc::c_char, - rc, - err, - ); - return CURLE_SSL_CONNECT_ERROR; - } - if ((*conn).bits).tls_enable_alpn() != 0 { - let mut cur: i32 = 0 as i32; - let mut protocols: [gnutls_datum_t; 2] = [gnutls_datum_t { - data: 0 as *mut u8, - size: 0, - }; 2]; - // done - 623 - #[cfg(not(CURL_DISABLE_PROXY))] - let CURL_DISABLE_PROXY_flag = (!(CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32) - || ((*conn).bits).tunnel_proxy() == 0); - #[cfg(CURL_DISABLE_PROXY)] - let CURL_DISABLE_PROXY_flag = true; - #[cfg(USE_HTTP2)] - if (*data).state.httpwant as i32 >= CURL_HTTP_VERSION_2_0 as i32 - && CURL_DISABLE_PROXY_flag - { - protocols[cur as usize].data = - b"h2\0" as *const u8 as *const libc::c_char as *mut u8; - protocols[cur as usize].size = 2 as u32; - cur += 1; - Curl_infof( - data, - b"ALPN, offering %.*s\0" as *const u8 as *const libc::c_char, - 2 as i32, - b"h2\0" as *const u8 as *const libc::c_char, - ); - } - protocols[cur as usize].data = - b"http/1.1\0" as *const u8 as *const libc::c_char as *mut u8; - protocols[cur as usize].size = 8 as u32; - cur += 1; - Curl_infof( - data, - b"ALPN, offering %s\0" as *const u8 as *const libc::c_char, - b"http/1.1\0" as *const u8 as *const libc::c_char, - ); - gnutls_alpn_set_protocols(session, protocols.as_mut_ptr(), cur as u32, 0 as u32); - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_primary_clientcert = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.primary.clientcert - } else { - (*data).set.ssl.primary.clientcert - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_primary_clientcert = (*data).set.ssl.primary.clientcert; - - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_key_passwd = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.key_passwd - } else { - (*data).set.ssl.key_passwd - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_key_passwd = (*data).set.ssl.key_passwd; - - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_key = if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.key - } else { - (*data).set.ssl.key - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_key = (*data).set.ssl.key; - - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_cert_type = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.cert_type - } else { - (*data).set.ssl.cert_type - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_cert_type = (*data).set.ssl.cert_type; - - if !SSL_SET_OPTION_primary_clientcert.is_null() { - if !SSL_SET_OPTION_key_passwd.is_null() { - let supported_key_encryption_algorithms: u32 = (GNUTLS_PKCS_PKCS12_3DES as i32 - | GNUTLS_PKCS_PKCS12_ARCFOUR as i32 - | GNUTLS_PKCS_PKCS12_RC2_40 as i32 - | GNUTLS_PKCS_PBES2_3DES as i32 - | GNUTLS_PKCS_PBES2_AES_128 as i32 - | GNUTLS_PKCS_PBES2_AES_192 as i32 - | GNUTLS_PKCS_PBES2_AES_256 as i32) - as u32; - rc = gnutls_certificate_set_x509_key_file2( - (*backend).cred, - SSL_SET_OPTION_primary_clientcert, - if !SSL_SET_OPTION_key.is_null() { - SSL_SET_OPTION_key - } else { - SSL_SET_OPTION_primary_clientcert - }, - do_file_type(SSL_SET_OPTION_cert_type), - SSL_SET_OPTION_key_passwd, - supported_key_encryption_algorithms, - ); - if rc != 0 as i32 { - Curl_failf( - data, - b"error reading X.509 potentially-encrypted key file: %s\0" as *const u8 - as *const libc::c_char, - gnutls_strerror(rc), - ); - return CURLE_SSL_CONNECT_ERROR; + if !buff1.is_null() { + len2 = len1; + ret = unsafe{gnutls_pubkey_export( + key, + GNUTLS_X509_FMT_DER, + buff1 as *mut libc::c_void, + &mut len2, + )}; + if !(ret < 0 as i32 || len1 != len2) { + /* End Gyrations */ + + /* The one good exit point */ + result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1); + } + } + } + } + if !key.is_null() { + unsafe{ gnutls_pubkey_deinit(key);} + } + #[cfg(not(CURLDEBUG))] + unsafe{Curl_cfree.expect("non-null function pointer")(buff1 as *mut libc::c_void);} + + #[cfg(CURLDEBUG)] + unsafe{curl_dbg_free( + buff1 as *mut libc::c_void, + 804 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + );} + buff1 = 0 as *mut u8; + return result; + + } + + extern "C" fn gtls_connect_step3( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + ) -> CURLcode { + let mut cert_list_size: u32 = 0; + let mut chainp: *const gnutls_datum_t = 0 as *const gnutls_datum_t; + let mut verify_status: u32 = 0 as u32; + let mut x509_cert: gnutls_x509_crt_t = 0 as *mut gnutls_x509_crt_int; + let mut x509_issuer: gnutls_x509_crt_t = 0 as *mut gnutls_x509_crt_int; + let mut issuerp: gnutls_datum_t = gnutls_datum_t { + data: 0 as *mut u8, + size: 0, + }; + let mut certfields: gnutls_datum_t = gnutls_datum_t { + data: 0 as *mut u8, + size: 0, + }; + let mut certname: [libc::c_char; 65] =unsafe{ *::std::mem::transmute::< + &[u8; 65], + &mut [libc::c_char; 65], + >( + b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + )}; /* limited to 64 chars by ASN.1 */ + let mut size: size_t = 0; + let mut certclock: time_t = 0; + let mut ptr: *const libc::c_char = 0 as *const libc::c_char; + let mut connssl: *mut ssl_connect_data = + unsafe{&mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; + let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; + let mut session: gnutls_session_t =unsafe{ (*backend).session}; + let mut rc: i32 = 0; + let mut proto: gnutls_datum_t = gnutls_datum_t { + data: 0 as *mut u8, + size: 0, + }; + let mut result: CURLcode = CURLE_OK; + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + let mut algo: u32 = 0; + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + let mut bits: u32 = 0; + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + let mut version: gnutls_protocol_t = unsafe{gnutls_protocol_get_version(session)}; + #[cfg(not(CURL_DISABLE_PROXY))] + let hostname: *const libc::c_char = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).http_proxy.host.name + } else { + (*conn).host.name + }}; + #[cfg(CURL_DISABLE_PROXY)] + let hostname: *const libc::c_char = unsafe{(*conn).host.name}; + + #[cfg(not(CURL_DISABLE_PROXY))] + let certverifyresult: *mut i64 = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + &mut (*data).set.proxy_ssl.certverifyresult + } else { + &mut (*data).set.ssl.certverifyresult + }}; + #[cfg(CURL_DISABLE_PROXY)] + let certverifyresult: *mut i64 =unsafe{ &mut (*data).set.ssl.certverifyresult}; + /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */ + ptr = unsafe{gnutls_cipher_suite_get_name( + gnutls_kx_get(session), + gnutls_cipher_get(session), + gnutls_mac_get(session), + )}; + unsafe{Curl_infof( + data, + b"SSL connection using %s / %s\0" as *const u8 as *const libc::c_char, + gnutls_protocol_get_name(version), + ptr, + );} + + /* This function will return the peer's raw certificate (chain) as sent by + the peer. These certificates are in raw format (DER encoded for + X.509). In case of a X.509 then a certificate list may be present. The + first certificate in the list is the peer's certificate, following the + issuer's certificate, then the issuer's issuer etc. */ + chainp = unsafe{gnutls_certificate_get_peers(session, &mut cert_list_size)}; + unsafe{ + #[cfg(not(CURL_DISABLE_PROXY))] + if chainp.is_null() { + if (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifypeer() as i32 + } else { + ((*conn).ssl_config).verifypeer() as i32 + }) != 0 + || (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifyhost() as i32 + } else { + ((*conn).ssl_config).verifyhost() as i32 + }) != 0 + || !(if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.issuercert + } else { + (*conn).ssl_config.issuercert + }) + .is_null() + { + #[cfg(HAVE_GNUTLS_SRP)] + if (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.authtype as u32 + } else { + (*data).set.ssl.authtype as u32 + }) == CURL_TLSAUTH_SRP as u32 + && !(if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.username + } else { + (*data).set.ssl.username + }) + .is_null() + && (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifypeer() as i32 + } else { + ((*conn).ssl_config).verifypeer() as i32 + }) == 0 + && gnutls_cipher_get(session) as u32 != 0 + { + /* no peer cert, but auth is ok if we have SRP user and cipher and no + peer verify */ + } else { + Curl_failf( + data, + b"failed to get server cert\0" as *const u8 as *const libc::c_char, + ); + *certverifyresult = -(49 as i32) as i64; + return CURLE_PEER_FAILED_VERIFICATION; + } + #[cfg(not(HAVE_GNUTLS_SRP))] + if true { + Curl_failf( + data, + b"failed to get server cert\0" as *const u8 as *const libc::c_char, + ); + *certverifyresult = -(49 as i32) as i64; + return CURLE_PEER_FAILED_VERIFICATION; + } + } + Curl_infof( + data, + b" common name: WARNING couldn't obtain\0" as *const u8 as *const libc::c_char, + ); + } + + #[cfg(CURL_DISABLE_PROXY)] + if chainp.is_null() { + if ((*conn).ssl_config).verifypeer() as i32 != 0 + || ((*conn).ssl_config).verifyhost() as i32 != 0 + || !((*conn).ssl_config.issuercert).is_null() + { + #[cfg(HAVE_GNUTLS_SRP)] + if (*data).set.ssl.authtype as u32 == CURL_TLSAUTH_SRP as u32 + && !((*data).set.ssl.username).is_null() + && ((*conn).ssl_config).verifypeer() == 0 + && gnutls_cipher_get(session) as u32 != 0 + { + } else { + Curl_failf( + data, + b"failed to get server cert\0" as *const u8 as *const libc::c_char, + ); + *certverifyresult = -(49 as i32) as i64; + return CURLE_PEER_FAILED_VERIFICATION; + } + #[cfg(not(HAVE_GNUTLS_SRP))] + if true { + Curl_failf( + data, + b"failed to get server cert\0" as *const u8 as *const libc::c_char, + ); + *certverifyresult = -(49 as i32) as i64; + return CURLE_PEER_FAILED_VERIFICATION; + } + } + Curl_infof( + data, + b" common name: WARNING couldn't obtain\0" as *const u8 as *const libc::c_char, + ); + }} + if unsafe{((*data).set.ssl).certinfo() as i32 }!= 0 &&unsafe{ !chainp.is_null()} { + let mut i: u32 = 0; + result = Curl_ssl_init_certinfo(data, cert_list_size as i32); + if result as u64 != 0 { + return result; + } + i = 0 as i32 as u32; + while i < cert_list_size { + let mut beg: *const libc::c_char = + unsafe{(*chainp.offset(i as isize)).data as *const libc::c_char}; + let mut end: *const libc::c_char = + unsafe{ beg.offset((*chainp.offset(i as isize)).size as isize)}; + result = unsafe{Curl_extract_certinfo(data, i as i32, beg, end)}; + if result as u64 != 0 { + return result; + } + i = i.wrapping_add(1); + } + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifypeer =unsafe{ if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifypeer() as i32 + } else { + ((*conn).ssl_config).verifypeer() as i32 + }}; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_verifypeer =unsafe{ ((*conn).ssl_config).verifypeer()}; + + if SSL_CONN_CONFIG_verifypeer != 0 { + /* This function will try to verify the peer's certificate and return its + status (trusted, invalid etc.). The value of status should be one or + more of the gnutls_certificate_status_t enumerated elements bitwise + or'd. To avoid denial of service attacks some default upper limits + regarding the certificate key size and chain size are set. To override + them use gnutls_certificate_set_verify_limits(). */ + rc = unsafe{gnutls_certificate_verify_peers2(session, &mut verify_status)}; + if rc < 0 as i32 {unsafe{ + Curl_failf( + data, + b"server cert verify failed: %d\0" as *const u8 as *const libc::c_char, + rc, + ); + *certverifyresult = rc as i64;} + return CURLE_SSL_CONNECT_ERROR; + } + unsafe{*certverifyresult = verify_status as i64;} + + /* verify_status is a bitmask of gnutls_certificate_status bits */ + if verify_status & GNUTLS_CERT_INVALID as u32 != 0 { + if SSL_CONN_CONFIG_verifypeer != 0 { + unsafe{ + #[cfg(not(CURL_DISABLE_PROXY))] + Curl_failf( + data, + b"server certificate verification failed. CAfile: %s CRLfile: %s\0" + as *const u8 as *const libc::c_char, + if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CAfile + } else { + (*conn).ssl_config.CAfile + } + .is_null() + { + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) + { + 0 as i32 + } else { + 1 as i32 + }) + as usize] + .state as u32 + { + (*conn).proxy_ssl_config.CAfile + } else { + (*conn).ssl_config.CAfile + }) as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.CRLfile + } else { + (*data).set.ssl.CRLfile + } + .is_null() + { + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) + { + 0 as i32 + } else { + 1 as i32 + }) + as usize] + .state as u32 + { + (*data).set.proxy_ssl.CRLfile + } else { + (*data).set.ssl.CRLfile + }) as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + #[cfg(CURL_DISABLE_PROXY)] + Curl_failf( + data, + b"server certificate verification failed. CAfile: %s CRLfile: %s\0" + as *const u8 as *const libc::c_char, + if !((*conn).ssl_config.CAfile).is_null() { + (*conn).ssl_config.CAfile as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + if !((*data).set.ssl.CRLfile).is_null() { + (*data).set.ssl.CRLfile as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + return CURLE_PEER_FAILED_VERIFICATION;} + } else { + unsafe{ + Curl_infof( + data, + b" server certificate verification FAILED\0" as *const u8 + as *const libc::c_char, + );} + } + } else { + unsafe{ + Curl_infof( + data, + b" server certificate verification OK\0" as *const u8 as *const libc::c_char, + );} + } + } else { + unsafe{ + Curl_infof( + data, + b" server certificate verification SKIPPED\0" as *const u8 as *const libc::c_char, + );} + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifystatus_1 = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifystatus() as i32 + } else { + ((*conn).ssl_config).verifystatus() as i32 + }}; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_verifystatus_1 = unsafe{((*conn).ssl_config).verifystatus()}; + unsafe{ + if SSL_CONN_CONFIG_verifystatus_1 != 0 { + + if gnutls_ocsp_status_request_is_checked(session, 0 as u32) == 0 as u32 { + let mut status_request: gnutls_datum_t = gnutls_datum_t { + data: 0 as *mut u8, + size: 0, + }; + let mut ocsp_resp: gnutls_ocsp_resp_t = 0 as *mut gnutls_ocsp_resp_int; + let mut status: gnutls_ocsp_cert_status_t = GNUTLS_OCSP_CERT_GOOD; + let mut reason: gnutls_x509_crl_reason_t = GNUTLS_X509_CRLREASON_UNSPECIFIED; + rc = gnutls_ocsp_status_request_get(session, &mut status_request); + Curl_infof( + data, + b" server certificate status verification FAILED\0" as *const u8 + as *const libc::c_char, + ); + if rc == -(56 as i32) { + Curl_failf( + data, + b"No OCSP response received\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_INVALIDCERTSTATUS; + } + if rc < 0 as i32 { + Curl_failf( + data, + b"Invalid OCSP response received\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_INVALIDCERTSTATUS; + } + gnutls_ocsp_resp_init(&mut ocsp_resp); + rc = gnutls_ocsp_resp_import(ocsp_resp, &mut status_request); + if rc < 0 as i32 { + Curl_failf( + data, + b"Invalid OCSP response received\0" as *const u8 as *const libc::c_char, + ); + return CURLE_SSL_INVALIDCERTSTATUS; + } + gnutls_ocsp_resp_get_single( + ocsp_resp as gnutls_ocsp_resp_const_t, + 0 as u32, + 0 as *mut gnutls_digest_algorithm_t, + 0 as *mut gnutls_datum_t, + 0 as *mut gnutls_datum_t, + 0 as *mut gnutls_datum_t, + &mut status as *mut gnutls_ocsp_cert_status_t as *mut u32, + 0 as *mut time_t, + 0 as *mut time_t, + 0 as *mut time_t, + &mut reason as *mut gnutls_x509_crl_reason_t as *mut u32, + ); + match status as u32 { + 0 => {} + 1 => { + let mut crl_reason: *const libc::c_char = 0 as *const libc::c_char; + match reason as u32 { + 1 => { + crl_reason = b"private key compromised\0" as *const u8 + as *const libc::c_char; + } + 2 => { + crl_reason = + b"CA compromised\0" as *const u8 as *const libc::c_char; + } + 3 => { + crl_reason = b"affiliation has changed\0" as *const u8 + as *const libc::c_char; + } + 4 => { + crl_reason = + b"certificate superseded\0" as *const u8 as *const libc::c_char; + } + 5 => { + crl_reason = + b"operation has ceased\0" as *const u8 as *const libc::c_char; + } + 6 => { + crl_reason = + b"certificate is on hold\0" as *const u8 as *const libc::c_char; + } + 8 => { + crl_reason = b"will be removed from delta CRL\0" as *const u8 + as *const libc::c_char; + } + 9 => { + crl_reason = + b"privilege withdrawn\0" as *const u8 as *const libc::c_char; + } + 10 => { + crl_reason = + b"AA compromised\0" as *const u8 as *const libc::c_char; + } + 0 | _ => { + crl_reason = + b"unspecified reason\0" as *const u8 as *const libc::c_char; + } + } + Curl_failf( + data, + b"Server certificate was revoked: %s\0" as *const u8 + as *const libc::c_char, + crl_reason, + ); + } + 2 | _ => { + Curl_failf( + data, + b"Server certificate status is unknown\0" as *const u8 + as *const libc::c_char, + ); + } + } + gnutls_ocsp_resp_deinit(ocsp_resp); + return CURLE_SSL_INVALIDCERTSTATUS; + } else { + Curl_infof( + data, + b" server certificate status verification OK\0" as *const u8 + as *const libc::c_char, + ); + } + } else { + Curl_infof( + data, + b" server certificate status verification SKIPPED\0" as *const u8 + as *const libc::c_char, + ); + }} + + /* initialize an X.509 certificate structure. */ + unsafe{ gnutls_x509_crt_init(&mut x509_cert);} + if !chainp.is_null() { + /* convert the given DER or PEM encoded Certificate to the native + gnutls_x509_crt_t format */ + unsafe{ gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);} + } + unsafe{ + #[cfg(not(CURL_DISABLE_PROXY))] + if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.issuercert + } else { + (*conn).ssl_config.issuercert + } + .is_null() + { + gnutls_x509_crt_init(&mut x509_issuer); + issuerp = load_file( + if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.issuercert + } else { + (*conn).ssl_config.issuercert + }, + ); + gnutls_x509_crt_import(x509_issuer, &mut issuerp, GNUTLS_X509_FMT_PEM); + rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer) as i32; + gnutls_x509_crt_deinit(x509_issuer); + unload_file(issuerp); + if rc <= 0 as i32 { + Curl_failf( + data, + b"server certificate issuer check failed (IssuerCert: %s)\0" as *const u8 + as *const libc::c_char, + if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.issuercert + } else { + (*conn).ssl_config.issuercert + } + .is_null() + { + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.issuercert + } else { + (*conn).ssl_config.issuercert + }) as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + gnutls_x509_crt_deinit(x509_cert); + return CURLE_SSL_ISSUER_ERROR; + } + Curl_infof( + data, + b" server certificate issuer check OK (Issuer Cert: %s)\0" as *const u8 + as *const libc::c_char, + if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.issuercert + } else { + (*conn).ssl_config.issuercert + } + .is_null() + { + (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).proxy_ssl_config.issuercert + } else { + (*conn).ssl_config.issuercert + }) as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + } + } + unsafe{ + #[cfg(CURL_DISABLE_PROXY)] + if !((*conn).ssl_config.issuercert).is_null() { + gnutls_x509_crt_init(&mut x509_issuer); + issuerp = load_file((*conn).ssl_config.issuercert); + gnutls_x509_crt_import(x509_issuer, &mut issuerp, GNUTLS_X509_FMT_PEM); + rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer) as i32; + gnutls_x509_crt_deinit(x509_issuer); + unload_file(issuerp); + if rc <= 0 as i32 { + Curl_failf( + data, + b"server certificate issuer check failed (IssuerCert: %s)\0" as *const u8 + as *const libc::c_char, + if !((*conn).ssl_config.issuercert).is_null() { + (*conn).ssl_config.issuercert as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + gnutls_x509_crt_deinit(x509_cert); + return CURLE_SSL_ISSUER_ERROR; + } + Curl_infof( + data, + b" server certificate issuer check OK (Issuer Cert: %s)\0" as *const u8 + as *const libc::c_char, + if !((*conn).ssl_config.issuercert).is_null() { + (*conn).ssl_config.issuercert as *const libc::c_char + } else { + b"none\0" as *const u8 as *const libc::c_char + }, + ); + } + } + size = ::std::mem::size_of::<[libc::c_char; 65]>() as u64; + rc = unsafe{gnutls_x509_crt_get_dn_by_oid( + x509_cert, + b"2.5.4.3\0" as *const u8 as *const libc::c_char, + 0 as u32, + 0 as u32, + certname.as_mut_ptr() as *mut libc::c_void, + &mut size, + )}; + if rc != 0 { + unsafe{Curl_infof( + data, + b"error fetching CN from cert:%s\0" as *const u8 as *const libc::c_char, + gnutls_strerror(rc), + );} + } + + /* This function will check if the given certificate's subject matches the + given hostname. This is a basic implementation of the matching described + in RFC2818 (HTTPS), which takes into account wildcards, and the subject + alternative name PKIX extension. Returns non zero on success, and zero on + failure. */ + rc = unsafe{gnutls_x509_crt_check_hostname(x509_cert, hostname) as i32}; + // todo - GNUTLS_VERSION_NUMBER < 0x030306 + // 1079 + /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP + addresses. */ + if rc == 0 { + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_HOST_DISPNAME_void = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*conn).http_proxy.host.dispname + } else { + (*conn).host.dispname + }}; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_HOST_DISPNAME_void = unsafe{(*conn).host.dispname}; + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifyhost = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifyhost() as i32 + } else { + ((*conn).ssl_config).verifyhost() as i32 + }}; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_verifyhost = unsafe{((*conn).ssl_config).verifyhost()}; + if SSL_CONN_CONFIG_verifyhost != 0 { + unsafe{Curl_failf( + data, + b"SSL: certificate subject name (%s) does not match target host name '%s'\0" + as *const u8 as *const libc::c_char, + certname.as_mut_ptr(), + SSL_HOST_DISPNAME_void, + ); + gnutls_x509_crt_deinit(x509_cert);} + return CURLE_PEER_FAILED_VERIFICATION; + } else { + unsafe{Curl_infof( + data, + b" common name: %s (does not match '%s')\0" as *const u8 + as *const libc::c_char, + certname.as_mut_ptr(), + SSL_HOST_DISPNAME_void, + );} + } + } else { + unsafe{Curl_infof( + data, + b" common name: %s (matched)\0" as *const u8 as *const libc::c_char, + certname.as_mut_ptr(), + );} + } + certclock = unsafe{gnutls_x509_crt_get_expiration_time(x509_cert)}; + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_CONN_CONFIG_verifypeer_1 = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*conn).proxy_ssl_config).verifypeer() as i32 + } else { + ((*conn).ssl_config).verifypeer() as i32 + }}; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_CONN_CONFIG_verifypeer_1 = unsafe{((*conn).ssl_config).verifypeer()}; + if certclock == -(1 as i32) as time_t { + if SSL_CONN_CONFIG_verifypeer_1 != 0 { + unsafe{Curl_failf( + data, + b"server cert expiration date verify failed\0" as *const u8 + as *const libc::c_char, + ); + *certverifyresult = GNUTLS_CERT_EXPIRED as i64; + gnutls_x509_crt_deinit(x509_cert);} + return CURLE_SSL_CONNECT_ERROR; + } else { + unsafe{ Curl_infof( + data, + b" server certificate expiration date verify FAILED\0" as *const u8 + as *const libc::c_char, + );} + } + } else if certclock < unsafe{time(0 as *mut time_t) }{ + if SSL_CONN_CONFIG_verifypeer_1 != 0 { + unsafe{Curl_failf( + data, + b"server certificate expiration date has passed.\0" as *const u8 + as *const libc::c_char, + ); + *certverifyresult = GNUTLS_CERT_EXPIRED as i32 as i64; + gnutls_x509_crt_deinit(x509_cert);} + return CURLE_PEER_FAILED_VERIFICATION; + } else { + unsafe{Curl_infof( + data, + b" server certificate expiration date FAILED\0" as *const u8 + as *const libc::c_char, + );} + } + } else { + unsafe{ Curl_infof( + data, + b" server certificate expiration date OK\0" as *const u8 as *const libc::c_char, + );} + } + /* Check for time-based validity */ + certclock = unsafe{gnutls_x509_crt_get_activation_time(x509_cert)}; + if certclock == -(1 as i32) as time_t { + if SSL_CONN_CONFIG_verifypeer_1 != 0 { + unsafe{ Curl_failf( + data, + b"server cert activation date verify failed\0" as *const u8 + as *const libc::c_char, + ); + *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED as i64; + gnutls_x509_crt_deinit(x509_cert);} + return CURLE_SSL_CONNECT_ERROR; + } else { + unsafe{Curl_infof( + data, + b" server certificate activation date verify FAILED\0" as *const u8 + as *const libc::c_char, + );} + } + } else if certclock > unsafe{time(0 as *mut time_t) }{ + if SSL_CONN_CONFIG_verifypeer_1 != 0 { + unsafe{Curl_failf( + data, + b"server certificate not activated yet.\0" as *const u8 as *const libc::c_char, + ); + *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED as i64; + gnutls_x509_crt_deinit(x509_cert);} + return CURLE_PEER_FAILED_VERIFICATION; + } else { + unsafe{Curl_infof( + data, + b" server certificate activation date FAILED\0" as *const u8 + as *const libc::c_char, + );} + } + } else { + unsafe{ Curl_infof( + data, + b" server certificate activation date OK\0" as *const u8 as *const libc::c_char, + );} + } + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_PINNED_PUB_KEY_void = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY_PROXY as usize] + } else { + (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize] + }}; + #[cfg(CURL_DISABLE_PROXY)] + let SSL_PINNED_PUB_KEY_void = unsafe{(*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize]}; + ptr = SSL_PINNED_PUB_KEY_void; + if !ptr.is_null() { + result = pkp_pin_peer_pubkey(data, x509_cert, ptr); + if result as u32 != CURLE_OK as u32 { + unsafe{Curl_failf( + data, + b"SSL: public key does not match pinned public key!\0" as *const u8 + as *const libc::c_char, + ); + gnutls_x509_crt_deinit(x509_cert);} + return result; + } + } + + /* Show: + + - subject + - start date + - expire date + - common name + - issuer + + */ + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + algo = unsafe{gnutls_x509_crt_get_pk_algorithm(x509_cert, &mut bits) as u32}; /* public key algorithm's parameters */ + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + unsafe{Curl_infof( + data, + b" certificate public key: %s\0" as *const u8 as *const libc::c_char, + gnutls_pk_algorithm_get_name(algo as gnutls_pk_algorithm_t), + );} + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + unsafe{Curl_infof( + data, + b" certificate version: #%d\0" as *const u8 as *const libc::c_char, + gnutls_x509_crt_get_version(x509_cert), + ); /* version of the X.509 certificate. */} + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + rc = unsafe{gnutls_x509_crt_get_dn2(x509_cert, &mut certfields)}; + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + if rc != 0 { + unsafe{ Curl_infof( + data, + b"Failed to get certificate name\0" as *const u8 as *const libc::c_char, + );} + } else { + unsafe{Curl_infof( + data, + b" subject: %s\0" as *const u8 as *const libc::c_char, + certfields.data, + );} + certclock = unsafe{gnutls_x509_crt_get_activation_time(x509_cert)}; + showtime( + data, + b"start date\0" as *const u8 as *const libc::c_char, + certclock, + ); + certclock = unsafe{gnutls_x509_crt_get_expiration_time(x509_cert)}; + showtime( + data, + b"expire date\0" as *const u8 as *const libc::c_char, + certclock, + ); + unsafe{gnutls_free.expect("non-null function pointer")(certfields.data as *mut libc::c_void);} + } + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + rc = unsafe{gnutls_x509_crt_get_issuer_dn2(x509_cert, &mut certfields)}; + #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] + if rc != 0 { + unsafe{ Curl_infof( + data, + b"Failed to get certificate issuer\0" as *const u8 as *const libc::c_char, + );} + } else { + unsafe{Curl_infof( + data, + b" issuer: %s\0" as *const u8 as *const libc::c_char, + certfields.data, + ); + gnutls_free.expect("non-null function pointer")(certfields.data as *mut libc::c_void);} + } + unsafe{gnutls_x509_crt_deinit(x509_cert);} + if unsafe{((*conn).bits).tls_enable_alpn()} != 0 { + rc = unsafe{gnutls_alpn_get_selected_protocol(session, &mut proto)}; + if rc == 0 as i32 { + unsafe{Curl_infof( + data, + b"ALPN, server accepted to use %.*s\0" as *const u8 as *const libc::c_char, + proto.size, + proto.data, + );} + // done - 1254 + #[cfg(USE_HTTP2)] + let USE_HTTP2_flag = unsafe{proto.size == 2 as u32 + && memcmp( + b"h2\0" as *const u8 as *const libc::c_char as *const libc::c_void, + proto.data as *const libc::c_void, + 2 as u64, + ) == 0}; + #[cfg(not(USE_HTTP2))] + let USE_HTTP2_flag = false; + if USE_HTTP2_flag { + unsafe{(*conn).negnpn = CURL_HTTP_VERSION_2_0 as i32;} + } else if proto.size == 8 as u32 + && unsafe{memcmp( + b"http/1.1\0" as *const u8 as *const libc::c_char as *const libc::c_void, + proto.data as *const libc::c_void, + 8 as u64, + ) == 0} + { + unsafe{ (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32;} + } + } else { + unsafe{Curl_infof( + data, + b"ALPN, server did not agree to a protocol\0" as *const u8 + as *const libc::c_char, + );} + } + unsafe{Curl_multiuse_state( + data, + if (*conn).negnpn == CURL_HTTP_VERSION_2_0 as i32 { + 2 as i32 + } else { + -(1 as i32) + }, + );} + } + unsafe{ (*conn).ssl[sockindex as usize].state = ssl_connection_complete; + (*conn).recv[sockindex as usize] = Some(gtls_recv as Curl_recv); + (*conn).send[sockindex as usize] = Some(gtls_send as Curl_send);} + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_SET_OPTION_primary_sessionid = unsafe{if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + ((*data).set.proxy_ssl.primary).sessionid() as i32 + } else { + ((*data).set.ssl.primary).sessionid() as i32 + }}; + + #[cfg(CURL_DISABLE_PROXY)] + let SSL_SET_OPTION_primary_sessionid =unsafe{ ((*data).set.ssl.primary).sessionid()}; + if SSL_SET_OPTION_primary_sessionid != 0 { + /* we always unconditionally get the session id here, as even if we + already got it from the cache and asked to use it in the connection, it + might've been rejected and then a new one is in use now and we need to + detect that. */ + let mut connect_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; + let mut connect_idsize: size_t = 0 as size_t; + /* get the session ID data size */ + unsafe{gnutls_session_get_data(session, 0 as *mut libc::c_void, &mut connect_idsize);} + /* get a buffer for it */ + unsafe{ + match () { + #[cfg(not(CURLDEBUG))] + _ => { + connect_sessionid = + Curl_cmalloc.expect("non-null function pointer")(connect_idsize); + } + #[cfg(CURLDEBUG)] + _ => { + connect_sessionid = curl_dbg_malloc( + connect_idsize, + 1286 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ); + } + } + } + if !connect_sessionid.is_null() { + let mut incache: bool = false; + let mut ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; + /* extract session ID to the allocated buffer */ + unsafe{gnutls_session_get_data(session, connect_sessionid, &mut connect_idsize);} + Curl_ssl_sessionid_lock(data); + unsafe{ + #[cfg(not(CURL_DISABLE_PROXY))] + let SSL_IS_PROXY_void_1 = if CURLPROXY_HTTPS as u32 + == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + 1 as i32 + } else { + 0 as i32 + } != 0; + + #[cfg(CURL_DISABLE_PROXY)] + let SSL_IS_PROXY_void_1 = if 0 as i32 != 0 { 1 as i32 } else { 0 as i32 } != 0; + incache = !Curl_ssl_getsessionid( + data, + conn, + SSL_IS_PROXY_void_1, + &mut ssl_sessionid, + 0 as *mut size_t, + sockindex, + ); + if incache { + /* there was one before in the cache, so instead of risking that the + previous one was rejected, we just kill that and store the new */ + Curl_ssl_delsessionid(data, ssl_sessionid); + } + /* store this session id */ + result = Curl_ssl_addsessionid( + data, + conn, + SSL_IS_PROXY_void_1, + connect_sessionid, + connect_idsize, + sockindex, + ); + Curl_ssl_sessionid_unlock(data); + if result as u64 != 0 { + #[cfg(not(CURLDEBUG))] + Curl_cfree.expect("non-null function pointer")(connect_sessionid); + + #[cfg(CURLDEBUG)] + curl_dbg_free( + connect_sessionid, + 1312 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + ); + result = CURLE_OUT_OF_MEMORY; + } } - } else if gnutls_certificate_set_x509_key_file( - (*backend).cred, - SSL_SET_OPTION_primary_clientcert, - if !(SSL_SET_OPTION_key).is_null() { - SSL_SET_OPTION_key - } else { - SSL_SET_OPTION_primary_clientcert - }, - do_file_type(SSL_SET_OPTION_cert_type), - ) != 0 as i32 - { - Curl_failf( - data, - b"error reading X.509 key or certificate file\0" as *const u8 - as *const libc::c_char, - ); - return CURLE_SSL_CONNECT_ERROR; - } - } - /* put the credentials to the current session */ - #[cfg(HAVE_GNUTLS_SRP)] - if SSL_SET_OPTION_authtype == CURL_TLSAUTH_SRP as u32 { - rc = gnutls_credentials_set( - session, - GNUTLS_CRD_SRP, - (*backend).srp_client_cred as *mut libc::c_void, - ); - if rc != 0 as i32 { - Curl_failf( - data, - b"gnutls_credentials_set() failed: %s\0" as *const u8 as *const libc::c_char, - gnutls_strerror(rc), - ); - return CURLE_SSL_CONNECT_ERROR; - } - } else { - rc = gnutls_credentials_set( - session, - GNUTLS_CRD_CERTIFICATE, - (*backend).cred as *mut libc::c_void, - ); - if rc != 0 as i32 { - Curl_failf( - data, - b"gnutls_credentials_set() failed: %s\0" as *const u8 as *const libc::c_char, - gnutls_strerror(rc), - ); - return CURLE_SSL_CONNECT_ERROR; - } - } - #[cfg(not(HAVE_GNUTLS_SRP))] - if true { - rc = gnutls_credentials_set( - session, - GNUTLS_CRD_CERTIFICATE, - (*backend).cred as *mut libc::c_void, - ); - if rc != 0 as i32 { - Curl_failf( - data, - b"gnutls_credentials_set() failed: %s\0" as *const u8 as *const libc::c_char, - gnutls_strerror(rc), - ); - return CURLE_SSL_CONNECT_ERROR; - } - } - - #[cfg(not(CURL_DISABLE_PROXY))] - if ((*conn).proxy_ssl[sockindex as usize]).use_0() != 0 { - transport_ptr = - (*(*conn).proxy_ssl[sockindex as usize].backend).session as *mut libc::c_void; - gnutls_transport_push = Some( - gtls_push_ssl - as unsafe extern "C" fn( - *mut libc::c_void, - *const libc::c_void, - size_t, - ) -> ssize_t, - ); - gnutls_transport_pull = Some( - gtls_pull_ssl - as unsafe extern "C" fn( - *mut libc::c_void, - *mut libc::c_void, - size_t, - ) -> ssize_t, - ); - } else { - transport_ptr = &mut *((*conn).sock).as_mut_ptr().offset(sockindex as isize) - as *mut curl_socket_t as *mut libc::c_void; - gnutls_transport_push = Some( - gtls_push - as unsafe extern "C" fn( - *mut libc::c_void, - *const libc::c_void, - size_t, - ) -> ssize_t, - ); - gnutls_transport_pull = Some( - gtls_pull - as unsafe extern "C" fn( - *mut libc::c_void, - *mut libc::c_void, - size_t, - ) -> ssize_t, - ); - } - #[cfg(CURL_DISABLE_PROXY)] - if true { - /* file descriptor for the socket */ - transport_ptr = &mut *((*conn).sock).as_mut_ptr().offset(sockindex as isize) - as *mut curl_socket_t as *mut libc::c_void; - gnutls_transport_push = Some( - gtls_push - as unsafe extern "C" fn( - *mut libc::c_void, - *const libc::c_void, - size_t, - ) -> ssize_t, - ); - gnutls_transport_pull = Some( - gtls_pull - as unsafe extern "C" fn( - *mut libc::c_void, - *mut libc::c_void, - size_t, - ) -> ssize_t, - ); - } - /* set the connection handle */ - gnutls_transport_set_ptr(session, transport_ptr); - /* register callback functions to send and receive data. */ - gnutls_transport_set_push_function(session, gnutls_transport_push); - gnutls_transport_set_pull_function(session, gnutls_transport_pull); - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifystatus = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifystatus() as i32 - } else { - ((*conn).ssl_config).verifystatus() as i32 - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_verifystatus = ((*conn).ssl_config).verifystatus(); - if SSL_CONN_CONFIG_verifystatus != 0 { - rc = gnutls_ocsp_status_request_enable_client( - session, - 0 as *mut gnutls_datum_t, - 0 as size_t, - 0 as *mut gnutls_datum_t, - ); - if rc != 0 as i32 { - Curl_failf( - data, - b"gnutls_ocsp_status_request_enable_client() failed: %d\0" as *const u8 - as *const libc::c_char, - rc, - ); - return CURLE_SSL_CONNECT_ERROR; - } - } - /* This might be a reconnect, so we check for a session ID in the cache - to speed up things */ - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*data).set.proxy_ssl.primary).sessionid() as i32 - } else { - ((*data).set.ssl.primary).sessionid() as i32 - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_primary_sessionid = ((*data).set.ssl.primary).sessionid(); - if SSL_SET_OPTION_primary_sessionid != 0 { - let mut ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; - let mut ssl_idsize: size_t = 0; - Curl_ssl_sessionid_lock(data); - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_IS_PROXY_void_1 = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - 1 as i32 - } else { - 0 as i32 - } != 0; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_IS_PROXY_void_1 = if 0 as i32 != 0 { 1 as i32 } else { 0 as i32 } != 0; - if !Curl_ssl_getsessionid( - data, - conn, - SSL_IS_PROXY_void_1, - &mut ssl_sessionid, - &mut ssl_idsize, - sockindex, - ) { - /* we got a session id, use it! */ - gnutls_session_set_data(session, ssl_sessionid, ssl_idsize); - /* Informational message */ - Curl_infof( - data, - b"SSL re-using session ID\0" as *const u8 as *const libc::c_char, - ); - } - Curl_ssl_sessionid_unlock(data); - } - return CURLE_OK; - } -} -extern "C" fn pkp_pin_peer_pubkey( - mut data: *mut Curl_easy, - mut cert: gnutls_x509_crt_t, - mut pinnedpubkey: *const libc::c_char, -) -> CURLcode { - unsafe { - /* Scratch */ - let mut len1: size_t = 0 as size_t; - let mut len2: size_t = 0 as size_t; - let mut buff1: *mut u8 = 0 as *mut u8; - let mut key: gnutls_pubkey_t = 0 as gnutls_pubkey_t; - /* Result is returned to caller */ - let mut result: CURLcode = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - /* if a path wasn't specified, don't pin */ - if pinnedpubkey.is_null() { - return CURLE_OK; - } - if cert.is_null() { - return result; - } - let mut ret: i32 = 0; - /* Begin Gyrations to get the public key */ - gnutls_pubkey_init(&mut key); - ret = gnutls_pubkey_import_x509(key, cert, 0 as u32); - if !(ret < 0 as i32) { - ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, 0 as *mut libc::c_void, &mut len1); - if !(ret != -(51 as i32) || len1 == 0 as u64) { - match () { - #[cfg(not(CURLDEBUG))] - _ => { - buff1 = Curl_cmalloc.expect("non-null function pointer")(len1) as *mut u8; - } - #[cfg(CURLDEBUG)] - _ => { - buff1 = curl_dbg_malloc( - len1, - 785 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ) as *mut u8; - } - } - - if !buff1.is_null() { - len2 = len1; - ret = gnutls_pubkey_export( - key, - GNUTLS_X509_FMT_DER, - buff1 as *mut libc::c_void, - &mut len2, - ); - if !(ret < 0 as i32 || len1 != len2) { - /* End Gyrations */ - - /* The one good exit point */ - result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1); - } - } - } - } - if !key.is_null() { - gnutls_pubkey_deinit(key); - } - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(buff1 as *mut libc::c_void); - - #[cfg(CURLDEBUG)] - curl_dbg_free( - buff1 as *mut libc::c_void, - 804 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - buff1 = 0 as *mut u8; - return result; - } -} - -extern "C" fn gtls_connect_step3( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, -) -> CURLcode { - unsafe { - let mut cert_list_size: u32 = 0; - let mut chainp: *const gnutls_datum_t = 0 as *const gnutls_datum_t; - let mut verify_status: u32 = 0 as u32; - let mut x509_cert: gnutls_x509_crt_t = 0 as *mut gnutls_x509_crt_int; - let mut x509_issuer: gnutls_x509_crt_t = 0 as *mut gnutls_x509_crt_int; - let mut issuerp: gnutls_datum_t = gnutls_datum_t { - data: 0 as *mut u8, - size: 0, - }; - let mut certfields: gnutls_datum_t = gnutls_datum_t { - data: 0 as *mut u8, - size: 0, - }; - let mut certname: [libc::c_char; 65] = *::std::mem::transmute::< - &[u8; 65], - &mut [libc::c_char; 65], - >( - b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", - ); /* limited to 64 chars by ASN.1 */ - let mut size: size_t = 0; - let mut certclock: time_t = 0; - let mut ptr: *const libc::c_char = 0 as *const libc::c_char; - let mut connssl: *mut ssl_connect_data = - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data; - let mut backend: *mut ssl_backend_data = (*connssl).backend; - let mut session: gnutls_session_t = (*backend).session; - let mut rc: i32 = 0; - let mut proto: gnutls_datum_t = gnutls_datum_t { - data: 0 as *mut u8, - size: 0, - }; - let mut result: CURLcode = CURLE_OK; - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - let mut algo: u32 = 0; - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - let mut bits: u32 = 0; - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - let mut version: gnutls_protocol_t = gnutls_protocol_get_version(session); - #[cfg(not(CURL_DISABLE_PROXY))] - let hostname: *const libc::c_char = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).http_proxy.host.name - } else { - (*conn).host.name - }; - #[cfg(CURL_DISABLE_PROXY)] - let hostname: *const libc::c_char = (*conn).host.name; - - #[cfg(not(CURL_DISABLE_PROXY))] - let certverifyresult: *mut i64 = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - &mut (*data).set.proxy_ssl.certverifyresult - } else { - &mut (*data).set.ssl.certverifyresult - }; - #[cfg(CURL_DISABLE_PROXY)] - let certverifyresult: *mut i64 = &mut (*data).set.ssl.certverifyresult; - /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */ - ptr = gnutls_cipher_suite_get_name( - gnutls_kx_get(session), - gnutls_cipher_get(session), - gnutls_mac_get(session), - ); - Curl_infof( - data, - b"SSL connection using %s / %s\0" as *const u8 as *const libc::c_char, - gnutls_protocol_get_name(version), - ptr, - ); - - /* This function will return the peer's raw certificate (chain) as sent by - the peer. These certificates are in raw format (DER encoded for - X.509). In case of a X.509 then a certificate list may be present. The - first certificate in the list is the peer's certificate, following the - issuer's certificate, then the issuer's issuer etc. */ - chainp = gnutls_certificate_get_peers(session, &mut cert_list_size); - #[cfg(not(CURL_DISABLE_PROXY))] - if chainp.is_null() { - if (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifypeer() as i32 - } else { - ((*conn).ssl_config).verifypeer() as i32 - }) != 0 - || (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifyhost() as i32 - } else { - ((*conn).ssl_config).verifyhost() as i32 - }) != 0 - || !(if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.issuercert - } else { - (*conn).ssl_config.issuercert - }) - .is_null() - { - #[cfg(HAVE_GNUTLS_SRP)] - if (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.authtype as u32 - } else { - (*data).set.ssl.authtype as u32 - }) == CURL_TLSAUTH_SRP as u32 - && !(if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.username - } else { - (*data).set.ssl.username - }) - .is_null() - && (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifypeer() as i32 - } else { - ((*conn).ssl_config).verifypeer() as i32 - }) == 0 - && gnutls_cipher_get(session) as u32 != 0 - { - /* no peer cert, but auth is ok if we have SRP user and cipher and no - peer verify */ - } else { - Curl_failf( - data, - b"failed to get server cert\0" as *const u8 as *const libc::c_char, - ); - *certverifyresult = -(49 as i32) as i64; - return CURLE_PEER_FAILED_VERIFICATION; - } - #[cfg(not(HAVE_GNUTLS_SRP))] - if true { - Curl_failf( - data, - b"failed to get server cert\0" as *const u8 as *const libc::c_char, - ); - *certverifyresult = -(49 as i32) as i64; - return CURLE_PEER_FAILED_VERIFICATION; - } - } - Curl_infof( - data, - b" common name: WARNING couldn't obtain\0" as *const u8 as *const libc::c_char, - ); - } - #[cfg(CURL_DISABLE_PROXY)] - if chainp.is_null() { - if ((*conn).ssl_config).verifypeer() as i32 != 0 - || ((*conn).ssl_config).verifyhost() as i32 != 0 - || !((*conn).ssl_config.issuercert).is_null() - { - #[cfg(HAVE_GNUTLS_SRP)] - if (*data).set.ssl.authtype as u32 == CURL_TLSAUTH_SRP as u32 - && !((*data).set.ssl.username).is_null() - && ((*conn).ssl_config).verifypeer() == 0 - && gnutls_cipher_get(session) as u32 != 0 - { - } else { - Curl_failf( - data, - b"failed to get server cert\0" as *const u8 as *const libc::c_char, - ); - *certverifyresult = -(49 as i32) as i64; - return CURLE_PEER_FAILED_VERIFICATION; - } - #[cfg(not(HAVE_GNUTLS_SRP))] - if true { - Curl_failf( - data, - b"failed to get server cert\0" as *const u8 as *const libc::c_char, - ); - *certverifyresult = -(49 as i32) as i64; - return CURLE_PEER_FAILED_VERIFICATION; - } - } - Curl_infof( - data, - b" common name: WARNING couldn't obtain\0" as *const u8 as *const libc::c_char, - ); - } - if ((*data).set.ssl).certinfo() as i32 != 0 && !chainp.is_null() { - let mut i: u32 = 0; - result = Curl_ssl_init_certinfo(data, cert_list_size as i32); - if result as u64 != 0 { - return result; - } - i = 0 as i32 as u32; - while i < cert_list_size { - let mut beg: *const libc::c_char = - (*chainp.offset(i as isize)).data as *const libc::c_char; - let mut end: *const libc::c_char = - beg.offset((*chainp.offset(i as isize)).size as isize); - result = Curl_extract_certinfo(data, i as i32, beg, end); - if result as u64 != 0 { - return result; - } - i = i.wrapping_add(1); - } - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifypeer = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifypeer() as i32 - } else { - ((*conn).ssl_config).verifypeer() as i32 - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_verifypeer = ((*conn).ssl_config).verifypeer(); - - if SSL_CONN_CONFIG_verifypeer != 0 { - /* This function will try to verify the peer's certificate and return its - status (trusted, invalid etc.). The value of status should be one or - more of the gnutls_certificate_status_t enumerated elements bitwise - or'd. To avoid denial of service attacks some default upper limits - regarding the certificate key size and chain size are set. To override - them use gnutls_certificate_set_verify_limits(). */ - rc = gnutls_certificate_verify_peers2(session, &mut verify_status); - if rc < 0 as i32 { - Curl_failf( - data, - b"server cert verify failed: %d\0" as *const u8 as *const libc::c_char, - rc, - ); - *certverifyresult = rc as i64; - return CURLE_SSL_CONNECT_ERROR; - } - *certverifyresult = verify_status as i64; - - /* verify_status is a bitmask of gnutls_certificate_status bits */ - if verify_status & GNUTLS_CERT_INVALID as u32 != 0 { - if SSL_CONN_CONFIG_verifypeer != 0 { - #[cfg(not(CURL_DISABLE_PROXY))] - Curl_failf( - data, - b"server certificate verification failed. CAfile: %s CRLfile: %s\0" - as *const u8 as *const libc::c_char, - if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CAfile - } else { - (*conn).ssl_config.CAfile - } - .is_null() - { - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) - { - 0 as i32 - } else { - 1 as i32 - }) - as usize] - .state as u32 - { - (*conn).proxy_ssl_config.CAfile - } else { - (*conn).ssl_config.CAfile - }) as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.CRLfile - } else { - (*data).set.ssl.CRLfile - } - .is_null() - { - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) - { - 0 as i32 - } else { - 1 as i32 - }) - as usize] - .state as u32 - { - (*data).set.proxy_ssl.CRLfile - } else { - (*data).set.ssl.CRLfile - }) as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - #[cfg(CURL_DISABLE_PROXY)] - Curl_failf( - data, - b"server certificate verification failed. CAfile: %s CRLfile: %s\0" - as *const u8 as *const libc::c_char, - if !((*conn).ssl_config.CAfile).is_null() { - (*conn).ssl_config.CAfile as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - if !((*data).set.ssl.CRLfile).is_null() { - (*data).set.ssl.CRLfile as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - return CURLE_PEER_FAILED_VERIFICATION; - } else { - Curl_infof( - data, - b" server certificate verification FAILED\0" as *const u8 - as *const libc::c_char, - ); - } - } else { - Curl_infof( - data, - b" server certificate verification OK\0" as *const u8 as *const libc::c_char, - ); - } - } else { - Curl_infof( - data, - b" server certificate verification SKIPPED\0" as *const u8 as *const libc::c_char, - ); - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifystatus_1 = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifystatus() as i32 - } else { - ((*conn).ssl_config).verifystatus() as i32 - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_verifystatus_1 = ((*conn).ssl_config).verifystatus(); - if SSL_CONN_CONFIG_verifystatus_1 != 0 { - if gnutls_ocsp_status_request_is_checked(session, 0 as u32) == 0 as u32 { - let mut status_request: gnutls_datum_t = gnutls_datum_t { - data: 0 as *mut u8, - size: 0, - }; - let mut ocsp_resp: gnutls_ocsp_resp_t = 0 as *mut gnutls_ocsp_resp_int; - let mut status: gnutls_ocsp_cert_status_t = GNUTLS_OCSP_CERT_GOOD; - let mut reason: gnutls_x509_crl_reason_t = GNUTLS_X509_CRLREASON_UNSPECIFIED; - rc = gnutls_ocsp_status_request_get(session, &mut status_request); - Curl_infof( - data, - b" server certificate status verification FAILED\0" as *const u8 - as *const libc::c_char, - ); - if rc == -(56 as i32) { - Curl_failf( - data, - b"No OCSP response received\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_INVALIDCERTSTATUS; - } - if rc < 0 as i32 { - Curl_failf( - data, - b"Invalid OCSP response received\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_INVALIDCERTSTATUS; - } - gnutls_ocsp_resp_init(&mut ocsp_resp); - rc = gnutls_ocsp_resp_import(ocsp_resp, &mut status_request); - if rc < 0 as i32 { - Curl_failf( - data, - b"Invalid OCSP response received\0" as *const u8 as *const libc::c_char, - ); - return CURLE_SSL_INVALIDCERTSTATUS; - } - gnutls_ocsp_resp_get_single( - ocsp_resp as gnutls_ocsp_resp_const_t, - 0 as u32, - 0 as *mut gnutls_digest_algorithm_t, - 0 as *mut gnutls_datum_t, - 0 as *mut gnutls_datum_t, - 0 as *mut gnutls_datum_t, - &mut status as *mut gnutls_ocsp_cert_status_t as *mut u32, - 0 as *mut time_t, - 0 as *mut time_t, - 0 as *mut time_t, - &mut reason as *mut gnutls_x509_crl_reason_t as *mut u32, - ); - match status as u32 { - 0 => {} - 1 => { - let mut crl_reason: *const libc::c_char = 0 as *const libc::c_char; - match reason as u32 { - 1 => { - crl_reason = b"private key compromised\0" as *const u8 - as *const libc::c_char; - } - 2 => { - crl_reason = - b"CA compromised\0" as *const u8 as *const libc::c_char; - } - 3 => { - crl_reason = b"affiliation has changed\0" as *const u8 - as *const libc::c_char; - } - 4 => { - crl_reason = - b"certificate superseded\0" as *const u8 as *const libc::c_char; - } - 5 => { - crl_reason = - b"operation has ceased\0" as *const u8 as *const libc::c_char; - } - 6 => { - crl_reason = - b"certificate is on hold\0" as *const u8 as *const libc::c_char; - } - 8 => { - crl_reason = b"will be removed from delta CRL\0" as *const u8 - as *const libc::c_char; - } - 9 => { - crl_reason = - b"privilege withdrawn\0" as *const u8 as *const libc::c_char; - } - 10 => { - crl_reason = - b"AA compromised\0" as *const u8 as *const libc::c_char; - } - 0 | _ => { - crl_reason = - b"unspecified reason\0" as *const u8 as *const libc::c_char; - } - } - Curl_failf( - data, - b"Server certificate was revoked: %s\0" as *const u8 - as *const libc::c_char, - crl_reason, - ); - } - 2 | _ => { - Curl_failf( - data, - b"Server certificate status is unknown\0" as *const u8 - as *const libc::c_char, - ); - } - } - gnutls_ocsp_resp_deinit(ocsp_resp); - return CURLE_SSL_INVALIDCERTSTATUS; - } else { - Curl_infof( - data, - b" server certificate status verification OK\0" as *const u8 - as *const libc::c_char, - ); - } - } else { - Curl_infof( - data, - b" server certificate status verification SKIPPED\0" as *const u8 - as *const libc::c_char, - ); - } - - /* initialize an X.509 certificate structure. */ - gnutls_x509_crt_init(&mut x509_cert); - if !chainp.is_null() { - /* convert the given DER or PEM encoded Certificate to the native - gnutls_x509_crt_t format */ - gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER); - } - #[cfg(not(CURL_DISABLE_PROXY))] - if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.issuercert - } else { - (*conn).ssl_config.issuercert - } - .is_null() - { - gnutls_x509_crt_init(&mut x509_issuer); - issuerp = load_file( - if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.issuercert - } else { - (*conn).ssl_config.issuercert - }, - ); - gnutls_x509_crt_import(x509_issuer, &mut issuerp, GNUTLS_X509_FMT_PEM); - rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer) as i32; - gnutls_x509_crt_deinit(x509_issuer); - unload_file(issuerp); - if rc <= 0 as i32 { - Curl_failf( - data, - b"server certificate issuer check failed (IssuerCert: %s)\0" as *const u8 - as *const libc::c_char, - if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.issuercert - } else { - (*conn).ssl_config.issuercert - } - .is_null() - { - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.issuercert - } else { - (*conn).ssl_config.issuercert - }) as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - gnutls_x509_crt_deinit(x509_cert); - return CURLE_SSL_ISSUER_ERROR; - } - Curl_infof( - data, - b" server certificate issuer check OK (Issuer Cert: %s)\0" as *const u8 - as *const libc::c_char, - if !if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.issuercert - } else { - (*conn).ssl_config.issuercert - } - .is_null() - { - (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).proxy_ssl_config.issuercert - } else { - (*conn).ssl_config.issuercert - }) as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - } - #[cfg(CURL_DISABLE_PROXY)] - if !((*conn).ssl_config.issuercert).is_null() { - gnutls_x509_crt_init(&mut x509_issuer); - issuerp = load_file((*conn).ssl_config.issuercert); - gnutls_x509_crt_import(x509_issuer, &mut issuerp, GNUTLS_X509_FMT_PEM); - rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer) as i32; - gnutls_x509_crt_deinit(x509_issuer); - unload_file(issuerp); - if rc <= 0 as i32 { - Curl_failf( - data, - b"server certificate issuer check failed (IssuerCert: %s)\0" as *const u8 - as *const libc::c_char, - if !((*conn).ssl_config.issuercert).is_null() { - (*conn).ssl_config.issuercert as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - gnutls_x509_crt_deinit(x509_cert); - return CURLE_SSL_ISSUER_ERROR; - } - Curl_infof( - data, - b" server certificate issuer check OK (Issuer Cert: %s)\0" as *const u8 - as *const libc::c_char, - if !((*conn).ssl_config.issuercert).is_null() { - (*conn).ssl_config.issuercert as *const libc::c_char - } else { - b"none\0" as *const u8 as *const libc::c_char - }, - ); - } - size = ::std::mem::size_of::<[libc::c_char; 65]>() as u64; - rc = gnutls_x509_crt_get_dn_by_oid( - x509_cert, - b"2.5.4.3\0" as *const u8 as *const libc::c_char, - 0 as u32, - 0 as u32, - certname.as_mut_ptr() as *mut libc::c_void, - &mut size, - ); - if rc != 0 { - Curl_infof( - data, - b"error fetching CN from cert:%s\0" as *const u8 as *const libc::c_char, - gnutls_strerror(rc), - ); - } - - /* This function will check if the given certificate's subject matches the - given hostname. This is a basic implementation of the matching described - in RFC2818 (HTTPS), which takes into account wildcards, and the subject - alternative name PKIX extension. Returns non zero on success, and zero on - failure. */ - rc = gnutls_x509_crt_check_hostname(x509_cert, hostname) as i32; - // todo - GNUTLS_VERSION_NUMBER < 0x030306 - // 1079 - /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP - addresses. */ - if rc == 0 { - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_HOST_DISPNAME_void = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*conn).http_proxy.host.dispname - } else { - (*conn).host.dispname - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_HOST_DISPNAME_void = (*conn).host.dispname; - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifyhost = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifyhost() as i32 - } else { - ((*conn).ssl_config).verifyhost() as i32 - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_verifyhost = ((*conn).ssl_config).verifyhost(); - if SSL_CONN_CONFIG_verifyhost != 0 { - Curl_failf( - data, - b"SSL: certificate subject name (%s) does not match target host name '%s'\0" - as *const u8 as *const libc::c_char, - certname.as_mut_ptr(), - SSL_HOST_DISPNAME_void, - ); - gnutls_x509_crt_deinit(x509_cert); - return CURLE_PEER_FAILED_VERIFICATION; - } else { - Curl_infof( - data, - b" common name: %s (does not match '%s')\0" as *const u8 - as *const libc::c_char, - certname.as_mut_ptr(), - SSL_HOST_DISPNAME_void, - ); - } - } else { - Curl_infof( - data, - b" common name: %s (matched)\0" as *const u8 as *const libc::c_char, - certname.as_mut_ptr(), - ); - } - certclock = gnutls_x509_crt_get_expiration_time(x509_cert); - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_CONN_CONFIG_verifypeer_1 = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as i32 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*conn).proxy_ssl_config).verifypeer() as i32 - } else { - ((*conn).ssl_config).verifypeer() as i32 - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_CONN_CONFIG_verifypeer_1 = ((*conn).ssl_config).verifypeer(); - if certclock == -(1 as i32) as time_t { - if SSL_CONN_CONFIG_verifypeer_1 != 0 { - Curl_failf( - data, - b"server cert expiration date verify failed\0" as *const u8 - as *const libc::c_char, - ); - *certverifyresult = GNUTLS_CERT_EXPIRED as i64; - gnutls_x509_crt_deinit(x509_cert); - return CURLE_SSL_CONNECT_ERROR; - } else { - Curl_infof( - data, - b" server certificate expiration date verify FAILED\0" as *const u8 - as *const libc::c_char, - ); - } - } else if certclock < time(0 as *mut time_t) { - if SSL_CONN_CONFIG_verifypeer_1 != 0 { - Curl_failf( - data, - b"server certificate expiration date has passed.\0" as *const u8 - as *const libc::c_char, - ); - *certverifyresult = GNUTLS_CERT_EXPIRED as i32 as i64; - gnutls_x509_crt_deinit(x509_cert); - return CURLE_PEER_FAILED_VERIFICATION; - } else { - Curl_infof( - data, - b" server certificate expiration date FAILED\0" as *const u8 - as *const libc::c_char, - ); - } - } else { - Curl_infof( - data, - b" server certificate expiration date OK\0" as *const u8 as *const libc::c_char, - ); - } - /* Check for time-based validity */ - certclock = gnutls_x509_crt_get_activation_time(x509_cert); - if certclock == -(1 as i32) as time_t { - if SSL_CONN_CONFIG_verifypeer_1 != 0 { - Curl_failf( - data, - b"server cert activation date verify failed\0" as *const u8 - as *const libc::c_char, - ); - *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED as i64; - gnutls_x509_crt_deinit(x509_cert); - return CURLE_SSL_CONNECT_ERROR; - } else { - Curl_infof( - data, - b" server certificate activation date verify FAILED\0" as *const u8 - as *const libc::c_char, - ); - } - } else if certclock > time(0 as *mut time_t) { - if SSL_CONN_CONFIG_verifypeer_1 != 0 { - Curl_failf( - data, - b"server certificate not activated yet.\0" as *const u8 as *const libc::c_char, - ); - *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED as i64; - gnutls_x509_crt_deinit(x509_cert); - return CURLE_PEER_FAILED_VERIFICATION; - } else { - Curl_infof( - data, - b" server certificate activation date FAILED\0" as *const u8 - as *const libc::c_char, - ); - } - } else { - Curl_infof( - data, - b" server certificate activation date OK\0" as *const u8 as *const libc::c_char, - ); - } - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_PINNED_PUB_KEY_void = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY_PROXY as usize] - } else { - (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize] - }; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_PINNED_PUB_KEY_void = (*data).set.str_0[STRING_SSL_PINNEDPUBLICKEY as usize]; - ptr = SSL_PINNED_PUB_KEY_void; - if !ptr.is_null() { - result = pkp_pin_peer_pubkey(data, x509_cert, ptr); - if result as u32 != CURLE_OK as u32 { - Curl_failf( - data, - b"SSL: public key does not match pinned public key!\0" as *const u8 - as *const libc::c_char, - ); - gnutls_x509_crt_deinit(x509_cert); - return result; - } - } - - /* Show: - - - subject - - start date - - expire date - - common name - - issuer - - */ - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &mut bits) as u32; /* public key algorithm's parameters */ - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - Curl_infof( - data, - b" certificate public key: %s\0" as *const u8 as *const libc::c_char, - gnutls_pk_algorithm_get_name(algo as gnutls_pk_algorithm_t), - ); - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - Curl_infof( - data, - b" certificate version: #%d\0" as *const u8 as *const libc::c_char, - gnutls_x509_crt_get_version(x509_cert), - ); /* version of the X.509 certificate. */ - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - rc = gnutls_x509_crt_get_dn2(x509_cert, &mut certfields); - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - if rc != 0 { - Curl_infof( - data, - b"Failed to get certificate name\0" as *const u8 as *const libc::c_char, - ); - } else { - Curl_infof( - data, - b" subject: %s\0" as *const u8 as *const libc::c_char, - certfields.data, - ); - certclock = gnutls_x509_crt_get_activation_time(x509_cert); - showtime( - data, - b"start date\0" as *const u8 as *const libc::c_char, - certclock, - ); - certclock = gnutls_x509_crt_get_expiration_time(x509_cert); - showtime( - data, - b"expire date\0" as *const u8 as *const libc::c_char, - certclock, - ); - gnutls_free.expect("non-null function pointer")(certfields.data as *mut libc::c_void); - } - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &mut certfields); - #[cfg(not(CURL_DISABLE_VERBOSE_STRINGS))] - if rc != 0 { - Curl_infof( - data, - b"Failed to get certificate issuer\0" as *const u8 as *const libc::c_char, - ); - } else { - Curl_infof( - data, - b" issuer: %s\0" as *const u8 as *const libc::c_char, - certfields.data, - ); - gnutls_free.expect("non-null function pointer")(certfields.data as *mut libc::c_void); - } - gnutls_x509_crt_deinit(x509_cert); - if ((*conn).bits).tls_enable_alpn() != 0 { - rc = gnutls_alpn_get_selected_protocol(session, &mut proto); - if rc == 0 as i32 { - Curl_infof( - data, - b"ALPN, server accepted to use %.*s\0" as *const u8 as *const libc::c_char, - proto.size, - proto.data, - ); - // done - 1254 - #[cfg(USE_HTTP2)] - let USE_HTTP2_flag = proto.size == 2 as u32 - && memcmp( - b"h2\0" as *const u8 as *const libc::c_char as *const libc::c_void, - proto.data as *const libc::c_void, - 2 as u64, - ) == 0; - #[cfg(not(USE_HTTP2))] - let USE_HTTP2_flag = false; - if USE_HTTP2_flag { - (*conn).negnpn = CURL_HTTP_VERSION_2_0 as i32; - } else if proto.size == 8 as u32 - && memcmp( - b"http/1.1\0" as *const u8 as *const libc::c_char as *const libc::c_void, - proto.data as *const libc::c_void, - 8 as u64, - ) == 0 - { - (*conn).negnpn = CURL_HTTP_VERSION_1_1 as i32; - } - } else { - Curl_infof( - data, - b"ALPN, server did not agree to a protocol\0" as *const u8 - as *const libc::c_char, - ); - } - Curl_multiuse_state( - data, - if (*conn).negnpn == CURL_HTTP_VERSION_2_0 as i32 { - 2 as i32 - } else { - -(1 as i32) - }, - ); - } - (*conn).ssl[sockindex as usize].state = ssl_connection_complete; - (*conn).recv[sockindex as usize] = Some(gtls_recv as Curl_recv); - (*conn).send[sockindex as usize] = Some(gtls_send as Curl_send); - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_SET_OPTION_primary_sessionid = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - ((*data).set.proxy_ssl.primary).sessionid() as i32 - } else { - ((*data).set.ssl.primary).sessionid() as i32 - }; - - #[cfg(CURL_DISABLE_PROXY)] - let SSL_SET_OPTION_primary_sessionid = ((*data).set.ssl.primary).sessionid(); - if SSL_SET_OPTION_primary_sessionid != 0 { - /* we always unconditionally get the session id here, as even if we - already got it from the cache and asked to use it in the connection, it - might've been rejected and then a new one is in use now and we need to - detect that. */ - let mut connect_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; - let mut connect_idsize: size_t = 0 as size_t; - /* get the session ID data size */ - gnutls_session_get_data(session, 0 as *mut libc::c_void, &mut connect_idsize); - /* get a buffer for it */ - match () { - #[cfg(not(CURLDEBUG))] - _ => { - connect_sessionid = - Curl_cmalloc.expect("non-null function pointer")(connect_idsize); - } - #[cfg(CURLDEBUG)] - _ => { - connect_sessionid = curl_dbg_malloc( - connect_idsize, - 1286 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - } - } - - if !connect_sessionid.is_null() { - let mut incache: bool = false; - let mut ssl_sessionid: *mut libc::c_void = 0 as *mut libc::c_void; - /* extract session ID to the allocated buffer */ - gnutls_session_get_data(session, connect_sessionid, &mut connect_idsize); - Curl_ssl_sessionid_lock(data); - #[cfg(not(CURL_DISABLE_PROXY))] - let SSL_IS_PROXY_void_1 = if CURLPROXY_HTTPS as u32 - == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - 1 as i32 - } else { - 0 as i32 - } != 0; - #[cfg(CURL_DISABLE_PROXY)] - let SSL_IS_PROXY_void_1 = if 0 as i32 != 0 { 1 as i32 } else { 0 as i32 } != 0; - incache = !Curl_ssl_getsessionid( - data, - conn, - SSL_IS_PROXY_void_1, - &mut ssl_sessionid, - 0 as *mut size_t, - sockindex, - ); - if incache { - /* there was one before in the cache, so instead of risking that the - previous one was rejected, we just kill that and store the new */ - Curl_ssl_delsessionid(data, ssl_sessionid); - } - /* store this session id */ - result = Curl_ssl_addsessionid( - data, - conn, - SSL_IS_PROXY_void_1, - connect_sessionid, - connect_idsize, - sockindex, - ); - Curl_ssl_sessionid_unlock(data); - if result as u64 != 0 { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(connect_sessionid); - - #[cfg(CURLDEBUG)] - curl_dbg_free( - connect_sessionid, - 1312 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - result = CURLE_OUT_OF_MEMORY; - } - } else { - result = CURLE_OUT_OF_MEMORY; - } - } - return result; - } -} - -/* - * This function is called after the TCP connect has completed. Setup the TLS - * layer and do all necessary magic. + } else { + result = CURLE_OUT_OF_MEMORY; + } + } + return result; + + } + + /* + * This function is called after the TCP connect has completed. Setup the TLS + * layer and do all necessary magic. + */ + /* We use connssl->connecting_state to keep track of the connection status; + there are three states: 'ssl_connect_1' (not started yet or complete), + 'ssl_connect_2_reading' (waiting for data from server), and + 'ssl_connect_2_writing' (waiting to be able to write). */ -/* We use connssl->connecting_state to keep track of the connection status; - there are three states: 'ssl_connect_1' (not started yet or complete), - 'ssl_connect_2_reading' (waiting for data from server), and - 'ssl_connect_2_writing' (waiting to be able to write). -*/ -extern "C" fn gtls_connect_common( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - mut nonblocking: bool, - mut done: *mut bool, -) -> CURLcode { - unsafe { - let mut rc: i32 = 0; - let mut connssl: *mut ssl_connect_data = - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data; - /* Initiate the connection, if not already done */ - if ssl_connect_1 as u32 == (*connssl).connecting_state as u32 { - rc = gtls_connect_step1(data, conn, sockindex) as i32; - if rc != 0 { - return rc as CURLcode; - } - } - rc = handshake(data, conn, sockindex, 1 as i32 != 0, nonblocking) as i32; - if rc != 0 { - /* handshake() sets its own error message with failf() */ - return rc as CURLcode; - } - - /* Finish connecting once the handshake is done */ - if ssl_connect_1 as u32 == (*connssl).connecting_state as u32 { - rc = gtls_connect_step3(data, conn, sockindex) as i32; - if rc != 0 { - return rc as CURLcode; - } - } - *done = ssl_connect_1 as u32 == (*connssl).connecting_state as u32; - return CURLE_OK; - } -} -extern "C" fn gtls_connect_nonblocking( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, - mut done: *mut bool, -) -> CURLcode { - unsafe { - return gtls_connect_common(data, conn, sockindex, 1 as i32 != 0, done); - } -} -extern "C" fn gtls_connect( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, -) -> CURLcode { - unsafe { - let mut result: CURLcode = CURLE_OK; - let mut done: bool = 0 as i32 != 0; - result = gtls_connect_common(data, conn, sockindex, 0 as i32 != 0, &mut done); - if result as u64 != 0 { - return result; - } - #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] - if done { - } else { - __assert_fail( - b"done\0" as *const u8 as *const libc::c_char, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - 1384 as u32, - (*::std::mem::transmute::<&[u8; 69], &[libc::c_char; 69]>( - b"CURLcode gtls_connect(struct Curl_easy *, struct connectdata *, int)\0", - )) - .as_ptr(), - ); - } - return CURLE_OK; - } -} -extern "C" fn gtls_data_pending(mut conn: *const connectdata, mut connindex: i32) -> bool { - unsafe { - let mut connssl: *const ssl_connect_data = - &*((*conn).ssl).as_ptr().offset(connindex as isize) as *const ssl_connect_data; - let mut res: bool = 0 as i32 != 0; - let mut backend: *mut ssl_backend_data = (*connssl).backend; - if !((*backend).session).is_null() - && 0 as u64 != gnutls_record_check_pending((*backend).session) - { - res = 1 as i32 != 0; - } - #[cfg(not(CURL_DISABLE_PROXY))] - if true { - connssl = &*((*conn).proxy_ssl).as_ptr().offset(connindex as isize) - as *const ssl_connect_data; - backend = (*connssl).backend; - if !((*backend).session).is_null() - && 0 as u64 != gnutls_record_check_pending((*backend).session) - { - res = 1 as i32 != 0; - } - } + extern "C" fn gtls_connect_common( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + mut nonblocking: bool, + mut done: *mut bool, + ) -> CURLcode { + let mut rc: i32 = 0; + let mut connssl: *mut ssl_connect_data =unsafe{ + &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; + /* Initiate the connection, if not already done */ + if ssl_connect_1 as u32 ==unsafe{ (*connssl).connecting_state as u32} { + rc = gtls_connect_step1(data, conn, sockindex) as i32; + if rc != 0 { + return rc as CURLcode; + } + } + rc = handshake(data, conn, sockindex, 1 as i32 != 0, nonblocking) as i32; + if rc != 0 { + /* handshake() sets its own error message with failf() */ + return rc as CURLcode; + } + + /* Finish connecting once the handshake is done */ + if ssl_connect_1 as u32 == unsafe{(*connssl).connecting_state as u32 }{ + rc = gtls_connect_step3(data, conn, sockindex) as i32; + if rc != 0 { + return rc as CURLcode; + } + } + unsafe{*done = ssl_connect_1 as u32 == (*connssl).connecting_state as u32;} + return CURLE_OK; + } + extern "C" fn gtls_connect_nonblocking( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + mut done: *mut bool, + ) -> CURLcode { + unsafe { + return gtls_connect_common(data, conn, sockindex, 1 as i32 != 0, done); + } + } + extern "C" fn gtls_connect( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + ) -> CURLcode { + let mut result: CURLcode = CURLE_OK; + let mut done: bool = 0 as i32 != 0; + result = gtls_connect_common(data, conn, sockindex, 0 as i32 != 0, &mut done); + if result as u64 != 0 { + return result; + } + #[cfg(all(DEBUGBUILD, HAVE_ASSERT_H))] + if done { + } else { + unsafe{ + __assert_fail( + b"done\0" as *const u8 as *const libc::c_char, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + 1384 as u32, + (*::std::mem::transmute::<&[u8; 69], &[libc::c_char; 69]>( + b"CURLcode gtls_connect(struct Curl_easy *, struct connectdata *, int)\0", + )) + .as_ptr(), + );} + } + return CURLE_OK; + + } + extern "C" fn gtls_data_pending(mut conn: *const connectdata, mut connindex: i32) -> bool { + let mut connssl: *const ssl_connect_data =unsafe{ + &*((*conn).ssl).as_ptr().offset(connindex as isize) as *const ssl_connect_data}; + let mut res: bool = 0 as i32 != 0; + let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; + if unsafe{!((*backend).session).is_null() + && 0 as u64 != gnutls_record_check_pending((*backend).session)} + { + res = 1 as i32 != 0; + } + #[cfg(not(CURL_DISABLE_PROXY))] + if true { + connssl =unsafe{ &*((*conn).proxy_ssl).as_ptr().offset(connindex as isize) + as *const ssl_connect_data}; + backend = unsafe{(*connssl).backend}; + if unsafe{!((*backend).session).is_null() + && 0 as u64 != gnutls_record_check_pending((*backend).session)} + { + res = 1 as i32 != 0; + } + } + + return res; + } + extern "C" fn gtls_send( + mut data: *mut Curl_easy, + mut sockindex: i32, + mut mem: *const libc::c_void, + mut len: size_t, + mut curlcode: *mut CURLcode, + ) -> ssize_t { + let mut conn: *mut connectdata =unsafe{ (*data).conn}; + let mut connssl: *mut ssl_connect_data = + unsafe{&mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; + let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; + let mut rc: ssize_t =unsafe{ gnutls_record_send((*backend).session, mem, len)}; + if rc < 0 as i64 { + unsafe{ *curlcode = (if rc == -(28 as i32) as i64 { + CURLE_AGAIN as i32 + } else { + CURLE_SEND_ERROR as i32 + }) as CURLcode; + rc = -(1 as i32) as ssize_t;} + } + return rc; + } + + extern "C" fn close_one(mut connssl: *mut ssl_connect_data) { + let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; + if unsafe{!((*backend).session).is_null()} { + let mut buf: [libc::c_char; 32] = [0; 32]; + /* Maybe the server has already sent a close notify alert. + Read it to avoid an RST on the TCP connection. */ + + unsafe{ gnutls_record_recv( + (*backend).session, + buf.as_mut_ptr() as *mut libc::c_void, + ::std::mem::size_of::<[libc::c_char; 32]>() as u64, + ); + gnutls_bye((*backend).session, GNUTLS_SHUT_WR); + gnutls_deinit((*backend).session); + (*backend).session = 0 as gnutls_session_t;} + } + if unsafe{!((*backend).cred).is_null()} { + unsafe{ + gnutls_certificate_free_credentials((*backend).cred); + (*backend).cred = 0 as gnutls_certificate_credentials_t;} + } + unsafe{ + #[cfg(HAVE_GNUTLS_SRP)] + if !((*backend).srp_client_cred).is_null() { + gnutls_srp_free_client_credentials((*backend).srp_client_cred); + (*backend).srp_client_cred = 0 as gnutls_srp_client_credentials_t; + }} - return res; - } -} -extern "C" fn gtls_send( - mut data: *mut Curl_easy, - mut sockindex: i32, - mut mem: *const libc::c_void, - mut len: size_t, - mut curlcode: *mut CURLcode, -) -> ssize_t { - unsafe { - let mut conn: *mut connectdata = (*data).conn; - let mut connssl: *mut ssl_connect_data = - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data; - let mut backend: *mut ssl_backend_data = (*connssl).backend; - let mut rc: ssize_t = gnutls_record_send((*backend).session, mem, len); - if rc < 0 as i64 { - *curlcode = (if rc == -(28 as i32) as i64 { - CURLE_AGAIN as i32 - } else { - CURLE_SEND_ERROR as i32 - }) as CURLcode; - rc = -(1 as i32) as ssize_t; - } - return rc; - } -} - -extern "C" fn close_one(mut connssl: *mut ssl_connect_data) { - unsafe { - let mut backend: *mut ssl_backend_data = (*connssl).backend; - if !((*backend).session).is_null() { - let mut buf: [libc::c_char; 32] = [0; 32]; - /* Maybe the server has already sent a close notify alert. - Read it to avoid an RST on the TCP connection. */ - - gnutls_record_recv( - (*backend).session, - buf.as_mut_ptr() as *mut libc::c_void, - ::std::mem::size_of::<[libc::c_char; 32]>() as u64, - ); - gnutls_bye((*backend).session, GNUTLS_SHUT_WR); - gnutls_deinit((*backend).session); - (*backend).session = 0 as gnutls_session_t; - } - if !((*backend).cred).is_null() { - gnutls_certificate_free_credentials((*backend).cred); - (*backend).cred = 0 as gnutls_certificate_credentials_t; - } - #[cfg(HAVE_GNUTLS_SRP)] - if !((*backend).srp_client_cred).is_null() { - gnutls_srp_free_client_credentials((*backend).srp_client_cred); - (*backend).srp_client_cred = 0 as gnutls_srp_client_credentials_t; - } - } -} -extern "C" fn gtls_close(mut data: *mut Curl_easy, mut conn: *mut connectdata, mut sockindex: i32) { - unsafe { - close_one(&mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize)); - #[cfg(not(CURL_DISABLE_PROXY))] - close_one(&mut *((*conn).proxy_ssl).as_mut_ptr().offset(sockindex as isize)); - } -} + } + extern "C" fn gtls_close(mut data: *mut Curl_easy, mut conn: *mut connectdata, mut sockindex: i32) { + unsafe { + close_one(&mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize)); + #[cfg(not(CURL_DISABLE_PROXY))] + close_one(&mut *((*conn).proxy_ssl).as_mut_ptr().offset(sockindex as isize)); + } + } + + /* + * This function is called to shut down the SSL layer but keep the + * socket open (CCC - Clear Command Channel) + */ + extern "C" fn gtls_shutdown( + mut data: *mut Curl_easy, + mut conn: *mut connectdata, + mut sockindex: i32, + ) -> i32 { + let mut connssl: *mut ssl_connect_data = + unsafe{ &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data}; + let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; + let mut retval: i32 = 0 as i32; + + /* This has only been tested on the proftpd server, and the mod_tls code + sends a close notify alert without waiting for a close notify alert in + response. Thus we wait for a close notify alert from the server, but + we do not send one. Let's hope other servers do the same... */ + unsafe{ + #[cfg(not(CURL_DISABLE_FTP))] + if (*data).set.ftp_ccc as u32 == CURLFTPSSL_CCC_ACTIVE as u32 { + gnutls_bye((*backend).session, GNUTLS_SHUT_WR); + } + if !((*backend).session).is_null() { + let mut result: ssize_t = 0; + let mut done: bool = 0 as i32 != 0; + let mut buf: [libc::c_char; 120] = [0; 120]; + while !done { + let mut what: i32 = Curl_socket_check( + (*conn).sock[sockindex as usize], + -(1 as i32), + -(1 as i32), + 10000 as timediff_t, + ); + if what > 0 as i32 { + /* Something to read, let's do it and hope that it is the close + notify alert from the server */ + result = gnutls_record_recv( + (*backend).session, + buf.as_mut_ptr() as *mut libc::c_void, + ::std::mem::size_of::<[libc::c_char; 120]>() as u64, + ); + match result { + 0 => { + /* This is the expected response. There was no data but only + the close notify alert */ + done = 1 as i32 != 0; + } + -28 | -52 => { + Curl_infof( + data, + b"GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\0" as *const u8 + as *const libc::c_char, + ); + } + _ => { + retval = -(1 as i32); + done = 1 as i32 != 0; + } + } + } else if 0 as i32 == what { + /* timeout */ + Curl_failf( + data, + b"SSL shutdown timeout\0" as *const u8 as *const libc::c_char, + ); + done = 1 as i32 != 0; + } else { + /* anything that gets here is fatally bad */ + Curl_failf( + data, + b"select/poll on SSL socket, errno: %d\0" as *const u8 + as *const libc::c_char, + *__errno_location(), + ); + retval = -(1 as i32); + done = 1 as i32 != 0; + } + } + gnutls_deinit((*backend).session); + } + gnutls_certificate_free_credentials((*backend).cred); + #[cfg(all(HAVE_GNUTLS_SRP, not(CURL_DISABLE_PROXY)))] + if (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.authtype as u32 + } else { + (*data).set.ssl.authtype as u32 + }) == CURL_TLSAUTH_SRP as u32 + && !(if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 + && ssl_connection_complete as u32 + != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { + 0 as i32 + } else { + 1 as i32 + }) as usize] + .state as u32 + { + (*data).set.proxy_ssl.username + } else { + (*data).set.ssl.username + }) + .is_null() + { + gnutls_srp_free_client_credentials((*backend).srp_client_cred); + } + #[cfg(all(HAVE_GNUTLS_SRP, CURL_DISABLE_PROXY))] + if (*data).set.ssl.authtype as u32 == CURL_TLSAUTH_SRP as u32 + && !((*data).set.ssl.username).is_null() + { + gnutls_srp_free_client_credentials((*backend).srp_client_cred); + } + (*backend).cred = 0 as gnutls_certificate_credentials_t; + (*backend).session = 0 as gnutls_session_t;} + return retval; + + } + + extern "C" fn gtls_recv( + mut data: *mut Curl_easy, + mut num: i32, + mut buf: *mut libc::c_char, + mut buffersize: size_t, + mut curlcode: *mut CURLcode, + ) -> ssize_t { -/* - * This function is called to shut down the SSL layer but keep the - * socket open (CCC - Clear Command Channel) - */ -extern "C" fn gtls_shutdown( - mut data: *mut Curl_easy, - mut conn: *mut connectdata, - mut sockindex: i32, -) -> i32 { - unsafe { - let mut connssl: *mut ssl_connect_data = - &mut *((*conn).ssl).as_mut_ptr().offset(sockindex as isize) as *mut ssl_connect_data; - let mut backend: *mut ssl_backend_data = (*connssl).backend; - let mut retval: i32 = 0 as i32; + let mut conn: *mut connectdata = unsafe{(*data).conn}; + let mut connssl: *mut ssl_connect_data =unsafe{ + &mut *((*conn).ssl).as_mut_ptr().offset(num as isize) as *mut ssl_connect_data}; + let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; + let mut ret: ssize_t = 0; + ret = unsafe{gnutls_record_recv((*backend).session, buf as *mut libc::c_void, buffersize)}; + if ret == -(28 as i32) as i64 || ret == -(52 as i32) as i64 { + unsafe{*curlcode = CURLE_AGAIN; + return -(1 as i32) as ssize_t;} + } + if ret == -(37 as i32) as i64 { + /* BLOCKING call, this is bad but a work-around for now. Fixing this "the + proper way" takes a whole lot of work. */ + let mut result: CURLcode = handshake(data, conn, num, 0 as i32 != 0, 0 as i32 != 0); + if result as u64 != 0 { + /* handshake() writes error message on its own */ + unsafe{ *curlcode = result;} + } else { + unsafe{ *curlcode = CURLE_AGAIN;} /* then return as if this was a wouldblock */ + } + return -(1 as i32) as ssize_t; + } + if ret < 0 as i32 as i64 { + unsafe{Curl_failf( + data, + b"GnuTLS recv error (%d): %s\0" as *const u8 as *const libc::c_char, + ret as i32, + gnutls_strerror(ret as i32), + ); + *curlcode = CURLE_RECV_ERROR;} + return -(1 as i32) as ssize_t; + } + return ret; + + } + extern "C" fn gtls_session_free(mut ptr: *mut libc::c_void) { - /* This has only been tested on the proftpd server, and the mod_tls code - sends a close notify alert without waiting for a close notify alert in - response. Thus we wait for a close notify alert from the server, but - we do not send one. Let's hope other servers do the same... */ - #[cfg(not(CURL_DISABLE_FTP))] - if (*data).set.ftp_ccc as u32 == CURLFTPSSL_CCC_ACTIVE as u32 { - gnutls_bye((*backend).session, GNUTLS_SHUT_WR); - } - if !((*backend).session).is_null() { - let mut result: ssize_t = 0; - let mut done: bool = 0 as i32 != 0; - let mut buf: [libc::c_char; 120] = [0; 120]; - while !done { - let mut what: i32 = Curl_socket_check( - (*conn).sock[sockindex as usize], - -(1 as i32), - -(1 as i32), - 10000 as timediff_t, - ); - if what > 0 as i32 { - /* Something to read, let's do it and hope that it is the close - notify alert from the server */ - result = gnutls_record_recv( - (*backend).session, - buf.as_mut_ptr() as *mut libc::c_void, - ::std::mem::size_of::<[libc::c_char; 120]>() as u64, - ); - match result { - 0 => { - /* This is the expected response. There was no data but only - the close notify alert */ - done = 1 as i32 != 0; - } - -28 | -52 => { - Curl_infof( - data, - b"GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\0" as *const u8 - as *const libc::c_char, - ); - } - _ => { - retval = -(1 as i32); - done = 1 as i32 != 0; - } - } - } else if 0 as i32 == what { - /* timeout */ - Curl_failf( - data, - b"SSL shutdown timeout\0" as *const u8 as *const libc::c_char, - ); - done = 1 as i32 != 0; - } else { - /* anything that gets here is fatally bad */ - Curl_failf( - data, - b"select/poll on SSL socket, errno: %d\0" as *const u8 - as *const libc::c_char, - *__errno_location(), - ); - retval = -(1 as i32); - done = 1 as i32 != 0; - } - } - gnutls_deinit((*backend).session); - } - gnutls_certificate_free_credentials((*backend).cred); - #[cfg(all(HAVE_GNUTLS_SRP, not(CURL_DISABLE_PROXY)))] - if (if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.authtype as u32 - } else { - (*data).set.ssl.authtype as u32 - }) == CURL_TLSAUTH_SRP as u32 - && !(if CURLPROXY_HTTPS as u32 == (*conn).http_proxy.proxytype as u32 - && ssl_connection_complete as u32 - != (*conn).proxy_ssl[(if (*conn).sock[1 as usize] == -(1 as i32) { - 0 as i32 - } else { - 1 as i32 - }) as usize] - .state as u32 - { - (*data).set.proxy_ssl.username - } else { - (*data).set.ssl.username - }) - .is_null() - { - gnutls_srp_free_client_credentials((*backend).srp_client_cred); - } - #[cfg(all(HAVE_GNUTLS_SRP, CURL_DISABLE_PROXY))] - if (*data).set.ssl.authtype as u32 == CURL_TLSAUTH_SRP as u32 - && !((*data).set.ssl.username).is_null() - { - gnutls_srp_free_client_credentials((*backend).srp_client_cred); - } - (*backend).cred = 0 as gnutls_certificate_credentials_t; - (*backend).session = 0 as gnutls_session_t; - return retval; - } -} + #[cfg(not(CURLDEBUG))] + unsafe{Curl_cfree.expect("non-null function pointer")(ptr)}; + + #[cfg(CURLDEBUG)] + unsafe{curl_dbg_free( + ptr, + 1586 as i32, + b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, + )}; + } + extern "C" fn gtls_version(mut buffer: *mut libc::c_char, mut size: size_t) -> size_t { + unsafe { + return curl_msnprintf( + buffer, + size, + b"GnuTLS/%s\0" as *const u8 as *const libc::c_char, + gnutls_check_version(0 as *const libc::c_char), + ) as size_t; + } + } + + /* data might be NULL! */ + extern "C" fn gtls_random( + mut data: *mut Curl_easy, + mut entropy: *mut u8, + mut length: size_t, + ) -> CURLcode { -extern "C" fn gtls_recv( - mut data: *mut Curl_easy, - mut num: i32, - mut buf: *mut libc::c_char, - mut buffersize: size_t, - mut curlcode: *mut CURLcode, -) -> ssize_t { - unsafe { - let mut conn: *mut connectdata = (*data).conn; - let mut connssl: *mut ssl_connect_data = - &mut *((*conn).ssl).as_mut_ptr().offset(num as isize) as *mut ssl_connect_data; - let mut backend: *mut ssl_backend_data = (*connssl).backend; - let mut ret: ssize_t = 0; - ret = gnutls_record_recv((*backend).session, buf as *mut libc::c_void, buffersize); - if ret == -(28 as i32) as i64 || ret == -(52 as i32) as i64 { - *curlcode = CURLE_AGAIN; - return -(1 as i32) as ssize_t; - } - if ret == -(37 as i32) as i64 { - /* BLOCKING call, this is bad but a work-around for now. Fixing this "the - proper way" takes a whole lot of work. */ - let mut result: CURLcode = handshake(data, conn, num, 0 as i32 != 0, 0 as i32 != 0); - if result as u64 != 0 { - /* handshake() writes error message on its own */ - *curlcode = result; - } else { - *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */ - } - return -(1 as i32) as ssize_t; - } - if ret < 0 as i32 as i64 { - Curl_failf( - data, - b"GnuTLS recv error (%d): %s\0" as *const u8 as *const libc::c_char, - ret as i32, - gnutls_strerror(ret as i32), - ); - *curlcode = CURLE_RECV_ERROR; - return -(1 as i32) as ssize_t; - } - return ret; - } -} -extern "C" fn gtls_session_free(mut ptr: *mut libc::c_void) { - unsafe { - #[cfg(not(CURLDEBUG))] - Curl_cfree.expect("non-null function pointer")(ptr); + let mut rc: i32 = 0; + rc = unsafe{gnutls_rnd(GNUTLS_RND_RANDOM, entropy as *mut libc::c_void, length)}; + return (if rc != 0 { + CURLE_FAILED_INIT as i32 + } else { + CURLE_OK as i32 + }) as CURLcode; + + } + extern "C" fn gtls_sha256sum( + mut tmp: *const u8, + mut tmplen: size_t, + mut sha256sum: *mut u8, + mut sha256len: size_t, + ) -> CURLcode { - #[cfg(CURLDEBUG)] - curl_dbg_free( - ptr, - 1586 as i32, - b"vtls/gtls.c\0" as *const u8 as *const libc::c_char, - ); - } -} -extern "C" fn gtls_version(mut buffer: *mut libc::c_char, mut size: size_t) -> size_t { - unsafe { - return curl_msnprintf( - buffer, - size, - b"GnuTLS/%s\0" as *const u8 as *const libc::c_char, - gnutls_check_version(0 as *const libc::c_char), - ) as size_t; - } -} + let mut SHA256pw: sha256_ctx = sha256_ctx { + state: [0; 8], + count: 0, + block: [0; 64], + index: 0, + }; + unsafe{ + nettle_sha256_init(&mut SHA256pw); + nettle_sha256_update(&mut SHA256pw, tmplen as size_t, tmp); + nettle_sha256_digest(&mut SHA256pw, sha256len as size_t, sha256sum);} + return CURLE_OK; + } + extern "C" fn gtls_cert_status_request() -> bool { + unsafe { + return 1 as i32 != 0; + } + } + extern "C" fn gtls_get_internals( + mut connssl: *mut ssl_connect_data, + mut info: CURLINFO, + ) -> *mut libc::c_void { -/* data might be NULL! */ -extern "C" fn gtls_random( - mut data: *mut Curl_easy, - mut entropy: *mut u8, - mut length: size_t, -) -> CURLcode { - unsafe { - let mut rc: i32 = 0; - rc = gnutls_rnd(GNUTLS_RND_RANDOM, entropy as *mut libc::c_void, length); - return (if rc != 0 { - CURLE_FAILED_INIT as i32 - } else { - CURLE_OK as i32 - }) as CURLcode; - } -} -extern "C" fn gtls_sha256sum( - mut tmp: *const u8, - mut tmplen: size_t, - mut sha256sum: *mut u8, - mut sha256len: size_t, -) -> CURLcode { - unsafe { - let mut SHA256pw: sha256_ctx = sha256_ctx { - state: [0; 8], - count: 0, - block: [0; 64], - index: 0, - }; - nettle_sha256_init(&mut SHA256pw); - nettle_sha256_update(&mut SHA256pw, tmplen as size_t, tmp); - nettle_sha256_digest(&mut SHA256pw, sha256len as size_t, sha256sum); - return CURLE_OK; - } -} -extern "C" fn gtls_cert_status_request() -> bool { - unsafe { - return 1 as i32 != 0; - } -} -extern "C" fn gtls_get_internals( - mut connssl: *mut ssl_connect_data, - mut info: CURLINFO, -) -> *mut libc::c_void { - unsafe { - let mut backend: *mut ssl_backend_data = (*connssl).backend; - return (*backend).session as *mut libc::c_void; - } -} -#[no_mangle] -pub static mut Curl_ssl_gnutls: Curl_ssl = Curl_ssl { - info: { - curl_ssl_backend { - id: CURLSSLBACKEND_GNUTLS, - name: b"gnutls\0" as *const u8 as *const libc::c_char, - } - }, - supports: ((1 as i32) << 0 as i32 - | (1 as i32) << 1 as i32 - | (1 as i32) << 2 as i32 - | (1 as i32) << 4 as i32) as u32, - sizeof_ssl_backend_data: ::std::mem::size_of::() as u64, - init: Some(gtls_init as unsafe extern "C" fn() -> i32), - cleanup: Some(gtls_cleanup as unsafe extern "C" fn() -> ()), - version: Some(gtls_version as unsafe extern "C" fn(*mut libc::c_char, size_t) -> size_t), - check_cxn: Some(Curl_none_check_cxn as unsafe extern "C" fn(*mut connectdata) -> i32), - shut_down: Some( - gtls_shutdown as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> i32, - ), - data_pending: Some(gtls_data_pending as unsafe extern "C" fn(*const connectdata, i32) -> bool), - random: Some(gtls_random as unsafe extern "C" fn(*mut Curl_easy, *mut u8, size_t) -> CURLcode), - cert_status_request: Some(gtls_cert_status_request as unsafe extern "C" fn() -> bool), - connect_blocking: Some( - gtls_connect as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> CURLcode, - ), - connect_nonblocking: Some( - gtls_connect_nonblocking - as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32, *mut bool) -> CURLcode, - ), - getsock: Some( - Curl_ssl_getsock as unsafe extern "C" fn(*mut connectdata, *mut curl_socket_t) -> i32, - ), - get_internals: Some( - gtls_get_internals - as unsafe extern "C" fn(*mut ssl_connect_data, CURLINFO) -> *mut libc::c_void, - ), - close_one: Some( - gtls_close as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> (), - ), - close_all: Some(Curl_none_close_all as unsafe extern "C" fn(*mut Curl_easy) -> ()), - session_free: Some(gtls_session_free as unsafe extern "C" fn(*mut libc::c_void) -> ()), - set_engine: Some( - Curl_none_set_engine - as unsafe extern "C" fn(*mut Curl_easy, *const libc::c_char) -> CURLcode, - ), - set_engine_default: Some( - Curl_none_set_engine_default as unsafe extern "C" fn(*mut Curl_easy) -> CURLcode, - ), - engines_list: Some( - Curl_none_engines_list as unsafe extern "C" fn(*mut Curl_easy) -> *mut curl_slist, - ), - false_start: Some(Curl_none_false_start as unsafe extern "C" fn() -> bool), - sha256sum: Some( - gtls_sha256sum as unsafe extern "C" fn(*const u8, size_t, *mut u8, size_t) -> CURLcode, - ), - associate_connection: None, - disassociate_connection: None, -}; + let mut backend: *mut ssl_backend_data = unsafe{(*connssl).backend}; + unsafe{ + return (*backend).session as *mut libc::c_void;} + } + #[no_mangle] + pub static mut Curl_ssl_gnutls: Curl_ssl = Curl_ssl { + info: { + curl_ssl_backend { + id: CURLSSLBACKEND_GNUTLS, + name: b"gnutls\0" as *const u8 as *const libc::c_char, + } + }, + supports: ((1 as i32) << 0 as i32 + | (1 as i32) << 1 as i32 + | (1 as i32) << 2 as i32 + | (1 as i32) << 4 as i32) as u32, + sizeof_ssl_backend_data: ::std::mem::size_of::() as u64, + init: Some(gtls_init as unsafe extern "C" fn() -> i32), + cleanup: Some(gtls_cleanup as unsafe extern "C" fn() -> ()), + version: Some(gtls_version as unsafe extern "C" fn(*mut libc::c_char, size_t) -> size_t), + check_cxn: Some(Curl_none_check_cxn as unsafe extern "C" fn(*mut connectdata) -> i32), + shut_down: Some( + gtls_shutdown as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> i32, + ), + data_pending: Some(gtls_data_pending as unsafe extern "C" fn(*const connectdata, i32) -> bool), + random: Some(gtls_random as unsafe extern "C" fn(*mut Curl_easy, *mut u8, size_t) -> CURLcode), + cert_status_request: Some(gtls_cert_status_request as unsafe extern "C" fn() -> bool), + connect_blocking: Some( + gtls_connect as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> CURLcode, + ), + connect_nonblocking: Some( + gtls_connect_nonblocking + as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32, *mut bool) -> CURLcode, + ), + getsock: Some( + Curl_ssl_getsock as unsafe extern "C" fn(*mut connectdata, *mut curl_socket_t) -> i32, + ), + get_internals: Some( + gtls_get_internals + as unsafe extern "C" fn(*mut ssl_connect_data, CURLINFO) -> *mut libc::c_void, + ), + close_one: Some( + gtls_close as unsafe extern "C" fn(*mut Curl_easy, *mut connectdata, i32) -> (), + ), + close_all: Some(Curl_none_close_all as unsafe extern "C" fn(*mut Curl_easy) -> ()), + session_free: Some(gtls_session_free as unsafe extern "C" fn(*mut libc::c_void) -> ()), + set_engine: Some( + Curl_none_set_engine + as unsafe extern "C" fn(*mut Curl_easy, *const libc::c_char) -> CURLcode, + ), + set_engine_default: Some( + Curl_none_set_engine_default as unsafe extern "C" fn(*mut Curl_easy) -> CURLcode, + ), + engines_list: Some( + Curl_none_engines_list as unsafe extern "C" fn(*mut Curl_easy) -> *mut curl_slist, + ), + false_start: Some(Curl_none_false_start as unsafe extern "C" fn() -> bool), + sha256sum: Some( + gtls_sha256sum as unsafe extern "C" fn(*const u8, size_t, *mut u8, size_t) -> CURLcode, + ), + associate_connection: None, + disassociate_connection: None, + }; + \ No newline at end of file -- Gitee