📄 tls_gnutls.c
字号:
/* TODO: validate subject_match and altsubject_match */ } os_free(buf); if (gnutls_x509_crt_get_expiration_time(cert) < now.sec || gnutls_x509_crt_get_activation_time(cert) > now.sec) { wpa_printf(MSG_INFO, "TLS: Peer certificate %d/%d is " "not valid at this time", i + 1, num_certs); gnutls_x509_crt_deinit(cert); return -1; } gnutls_x509_crt_deinit(cert); } return 0;}u8 * tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn, const u8 *in_data, size_t in_len, size_t *out_len, u8 **appl_data, size_t *appl_data_len){ struct tls_global *global = ssl_ctx; u8 *out_data; int ret; if (appl_data) *appl_data = NULL; if (in_data && in_len) { if (conn->pull_buf) { wpa_printf(MSG_DEBUG, "%s - %d bytes remaining in " "pull_buf", __func__, conn->pull_buf_len); os_free(conn->pull_buf); } conn->pull_buf = os_malloc(in_len); if (conn->pull_buf == NULL) return NULL; os_memcpy(conn->pull_buf, in_data, in_len); conn->pull_buf_offset = conn->pull_buf; conn->pull_buf_len = in_len; } ret = gnutls_handshake(conn->session); if (ret < 0) { switch (ret) { case GNUTLS_E_AGAIN: if (global->server && conn->established && conn->push_buf == NULL) { /* Need to return something to trigger * completion of EAP-TLS. */ conn->push_buf = os_malloc(1); } break; case GNUTLS_E_FATAL_ALERT_RECEIVED: wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert", __func__, gnutls_alert_get_name( gnutls_alert_get(conn->session))); conn->read_alerts++; /* continue */ default: wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed " "-> %s", __func__, gnutls_strerror(ret)); conn->failed++; } } else { size_t size; if (conn->verify_peer && tls_connection_verify_peer(conn)) { wpa_printf(MSG_INFO, "TLS: Peer certificate chain " "failed validation"); conn->failed++; return NULL; } if (conn->tls_ia && !gnutls_ia_handshake_p(conn->session)) { wpa_printf(MSG_INFO, "TLS: No TLS/IA negotiation"); conn->failed++; return NULL; } if (conn->tls_ia) wpa_printf(MSG_DEBUG, "TLS: Start TLS/IA handshake"); else { wpa_printf(MSG_DEBUG, "TLS: Handshake completed " "successfully"); } conn->established = 1; if (conn->push_buf == NULL) { /* Need to return something to get final TLS ACK. */ conn->push_buf = os_malloc(1); } gnutls_session_get_data(conn->session, NULL, &size); if (global->session_data == NULL || global->session_data_size < size) { os_free(global->session_data); global->session_data = os_malloc(size); } if (global->session_data) { global->session_data_size = size; gnutls_session_get_data(conn->session, global->session_data, &global->session_data_size); } } out_data = conn->push_buf; *out_len = conn->push_buf_len; conn->push_buf = NULL; conn->push_buf_len = 0; return out_data;}u8 * tls_connection_server_handshake(void *ssl_ctx, struct tls_connection *conn, const u8 *in_data, size_t in_len, size_t *out_len){ return tls_connection_handshake(ssl_ctx, conn, in_data, in_len, out_len, NULL, NULL);}int tls_connection_encrypt(void *ssl_ctx, struct tls_connection *conn, const u8 *in_data, size_t in_len, u8 *out_data, size_t out_len){ ssize_t res;#ifdef GNUTLS_IA if (conn->tls_ia) res = gnutls_ia_send(conn->session, (char *) in_data, in_len); else#endif /* GNUTLS_IA */ res = gnutls_record_send(conn->session, in_data, in_len); if (res < 0) { wpa_printf(MSG_INFO, "%s: Encryption failed: %s", __func__, gnutls_strerror(res)); return -1; } if (conn->push_buf == NULL) return -1; if (conn->push_buf_len < out_len) out_len = conn->push_buf_len; os_memcpy(out_data, conn->push_buf, out_len); os_free(conn->push_buf); conn->push_buf = NULL; conn->push_buf_len = 0; return out_len;}int tls_connection_decrypt(void *ssl_ctx, struct tls_connection *conn, const u8 *in_data, size_t in_len, u8 *out_data, size_t out_len){ ssize_t res; if (conn->pull_buf) { wpa_printf(MSG_DEBUG, "%s - %d bytes remaining in " "pull_buf", __func__, conn->pull_buf_len); os_free(conn->pull_buf); } conn->pull_buf = os_malloc(in_len); if (conn->pull_buf == NULL) return -1; os_memcpy(conn->pull_buf, in_data, in_len); conn->pull_buf_offset = conn->pull_buf; conn->pull_buf_len = in_len;#ifdef GNUTLS_IA if (conn->tls_ia) { res = gnutls_ia_recv(conn->session, (char *) out_data, out_len); if (out_len >= 12 && (res == GNUTLS_E_WARNING_IA_IPHF_RECEIVED || res == GNUTLS_E_WARNING_IA_FPHF_RECEIVED)) { int final = res == GNUTLS_E_WARNING_IA_FPHF_RECEIVED; wpa_printf(MSG_DEBUG, "%s: Received %sPhaseFinished", __func__, final ? "Final" : "Intermediate"); res = gnutls_ia_permute_inner_secret( conn->session, conn->session_keys_len, (char *) conn->session_keys); if (conn->session_keys) { os_memset(conn->session_keys, 0, conn->session_keys_len); os_free(conn->session_keys); } conn->session_keys = NULL; conn->session_keys_len = 0; if (res) { wpa_printf(MSG_DEBUG, "%s: Failed to permute " "inner secret: %s", __func__, gnutls_strerror(res)); return -1; } res = gnutls_ia_verify_endphase(conn->session, (char *) out_data); if (res == 0) { wpa_printf(MSG_DEBUG, "%s: Correct endphase " "checksum", __func__); } else { wpa_printf(MSG_INFO, "%s: Endphase " "verification failed: %s", __func__, gnutls_strerror(res)); return -1; } if (final) conn->final_phase_finished = 1; return 0; } if (res < 0) { wpa_printf(MSG_DEBUG, "%s - gnutls_ia_recv failed: %d " "(%s)", __func__, res, gnutls_strerror(res)); } return res; }#endif /* GNUTLS_IA */ res = gnutls_record_recv(conn->session, out_data, out_len); if (res < 0) { wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d " "(%s)", __func__, res, gnutls_strerror(res)); } return res;}int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn){ if (conn == NULL) return 0; return gnutls_session_is_resumed(conn->session);}int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, u8 *ciphers){ /* TODO */ return -1;}int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, char *buf, size_t buflen){ /* TODO */ buf[0] = '\0'; return 0;}int tls_connection_enable_workaround(void *ssl_ctx, struct tls_connection *conn){ /* TODO: set SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS */ return 0;}int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, int ext_type, const u8 *data, size_t data_len){ /* TODO */ return -1;}int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn){ if (conn == NULL) return -1; return conn->failed;}int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn){ if (conn == NULL) return -1; return conn->read_alerts;}int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn){ if (conn == NULL) return -1; return conn->write_alerts;}int tls_connection_get_keyblock_size(void *tls_ctx, struct tls_connection *conn){ /* TODO */ return -1;}unsigned int tls_capabilities(void *tls_ctx){ unsigned int capa = 0;#ifdef GNUTLS_IA capa |= TLS_CAPABILITY_IA;#endif /* GNUTLS_IA */ return capa;}int tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn, int tls_ia){#ifdef GNUTLS_IA int ret; if (conn == NULL) return -1; conn->tls_ia = tls_ia; if (!tls_ia) return 0; ret = gnutls_ia_allocate_server_credentials(&conn->iacred_srv); if (ret) { wpa_printf(MSG_DEBUG, "Failed to allocate IA credentials: %s", gnutls_strerror(ret)); return -1; } ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_IA, conn->iacred_srv); if (ret) { wpa_printf(MSG_DEBUG, "Failed to configure IA credentials: %s", gnutls_strerror(ret)); gnutls_ia_free_server_credentials(conn->iacred_srv); conn->iacred_srv = NULL; return -1; } return 0;#else /* GNUTLS_IA */ return -1;#endif /* GNUTLS_IA */}int tls_connection_ia_send_phase_finished(void *tls_ctx, struct tls_connection *conn, int final, u8 *out_data, size_t out_len){#ifdef GNUTLS_IA int ret; if (conn == NULL || conn->session == NULL || !conn->tls_ia) return -1; ret = gnutls_ia_permute_inner_secret(conn->session, conn->session_keys_len, (char *) conn->session_keys); if (conn->session_keys) { os_memset(conn->session_keys, 0, conn->session_keys_len); os_free(conn->session_keys); } conn->session_keys = NULL; conn->session_keys_len = 0; if (ret) { wpa_printf(MSG_DEBUG, "%s: Failed to permute inner secret: %s", __func__, gnutls_strerror(ret)); return -1; } ret = gnutls_ia_endphase_send(conn->session, final); if (ret) { wpa_printf(MSG_DEBUG, "%s: Failed to send endphase: %s", __func__, gnutls_strerror(ret)); return -1; } if (conn->push_buf == NULL) return -1; if (conn->push_buf_len < out_len) out_len = conn->push_buf_len; os_memcpy(out_data, conn->push_buf, out_len); os_free(conn->push_buf); conn->push_buf = NULL; conn->push_buf_len = 0; return out_len;#else /* GNUTLS_IA */ return -1;#endif /* GNUTLS_IA */}int tls_connection_ia_final_phase_finished(void *tls_ctx, struct tls_connection *conn){ if (conn == NULL) return -1; return conn->final_phase_finished;}int tls_connection_ia_permute_inner_secret(void *tls_ctx, struct tls_connection *conn, const u8 *key, size_t key_len){#ifdef GNUTLS_IA if (conn == NULL || !conn->tls_ia) return -1; if (conn->session_keys) { os_memset(conn->session_keys, 0, conn->session_keys_len); os_free(conn->session_keys); } conn->session_keys_len = 0; if (key) { conn->session_keys = os_malloc(key_len); if (conn->session_keys == NULL) return -1; os_memcpy(conn->session_keys, key, key_len); conn->session_keys_len = key_len; } else { conn->session_keys = NULL; conn->session_keys_len = 0; } return 0;#else /* GNUTLS_IA */ return -1;#endif /* GNUTLS_IA */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -