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; }
static int _gnutls_ia_server_handshake (gnutls_session_t session) { gnutls_ia_apptype_t msg_type; ssize_t len; char buf[1024]; int ret; const struct gnutls_ia_server_credentials_st *cred = _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL); if (cred == NULL) return GNUTLS_E_INTERNAL_ERROR; do { char *avp; size_t avplen; len = gnutls_ia_recv (session, buf, sizeof (buf)); if (len == GNUTLS_E_WARNING_IA_IPHF_RECEIVED || len == GNUTLS_E_WARNING_IA_FPHF_RECEIVED) { ret = gnutls_ia_verify_endphase (session, buf); if (ret < 0) return ret; } if (len == GNUTLS_E_WARNING_IA_IPHF_RECEIVED) continue; else if (len == GNUTLS_E_WARNING_IA_FPHF_RECEIVED) break; if (len < 0) return len; avp = NULL; avplen = 0; ret = cred->avp_func (session, cred->avp_ptr, buf, len, &avp, &avplen); if (ret < 0) { int tmpret; tmpret = gnutls_alert_send (session, GNUTLS_AL_FATAL, GNUTLS_A_INNER_APPLICATION_FAILURE); if (tmpret < 0) gnutls_assert (); return ret; } msg_type = ret; if (msg_type != GNUTLS_IA_APPLICATION_PAYLOAD) { ret = gnutls_ia_endphase_send (session, msg_type == GNUTLS_IA_FINAL_PHASE_FINISHED); if (ret < 0) return ret; } else { len = gnutls_ia_send (session, avp, avplen); gnutls_free (avp); if (len < 0) return len; } } while (1); return 0; }
static int _gnutls_ia_client_handshake (gnutls_session_t session) { char *buf = NULL; size_t buflen = 0; char tmp[1024]; /* XXX */ ssize_t len; int ret; const struct gnutls_ia_client_credentials_st *cred = _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL); if (cred == NULL) return GNUTLS_E_INTERNAL_ERROR; while (1) { char *avp; size_t avplen; ret = cred->avp_func (session, cred->avp_ptr, buf, buflen, &avp, &avplen); if (ret) { int tmpret; tmpret = gnutls_alert_send (session, GNUTLS_AL_FATAL, GNUTLS_A_INNER_APPLICATION_FAILURE); if (tmpret < 0) gnutls_assert (); return ret; } len = gnutls_ia_send (session, avp, avplen); gnutls_free (avp); if (len < 0) return len; len = gnutls_ia_recv (session, tmp, sizeof (tmp)); if (len == GNUTLS_E_WARNING_IA_IPHF_RECEIVED || len == GNUTLS_E_WARNING_IA_FPHF_RECEIVED) { ret = gnutls_ia_verify_endphase (session, tmp); if (ret < 0) return ret; ret = gnutls_ia_endphase_send (session, len == GNUTLS_E_WARNING_IA_FPHF_RECEIVED); if (ret < 0) return ret; } if (len == GNUTLS_E_WARNING_IA_IPHF_RECEIVED) { buf = NULL; buflen = 0; continue; } else if (len == GNUTLS_E_WARNING_IA_FPHF_RECEIVED) break; if (len < 0) return len; buflen = len; buf = tmp; } return 0; }
#ifdef GNUTLS_IA if (conn->tls_ia) res = gnutls_ia_send(conn->session, wpabuf_head(in_data), wpabuf_len(in_data)); else #endif /* GNUTLS_IA */ res = gnutls_record_send(conn->session, wpabuf_head(in_data), wpabuf_len(in_data));