243
244
struct tls_connection *conn = (struct tls_connection *) ptr;
245
246
if (conn->pull_buf == NULL) {
246
247
errno = EWOULDBLOCK;
250
end = conn->pull_buf + conn->pull_buf_len;
251
end = wpabuf_head_u8(conn->pull_buf) + wpabuf_len(conn->pull_buf);
251
252
if ((size_t) (end - conn->pull_buf_offset) < len)
252
253
len = end - conn->pull_buf_offset;
253
254
os_memcpy(buf, conn->pull_buf_offset, len);
254
255
conn->pull_buf_offset += len;
255
256
if (conn->pull_buf_offset == end) {
256
257
wpa_printf(MSG_DEBUG, "%s - pull_buf consumed", __func__);
257
os_free(conn->pull_buf);
258
conn->pull_buf = conn->pull_buf_offset = NULL;
259
conn->pull_buf_len = 0;
258
wpabuf_free(conn->pull_buf);
259
conn->pull_buf = NULL;
260
conn->pull_buf_offset = NULL;
261
262
wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in pull_buf",
982
u8 * tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn,
983
const u8 *in_data, size_t in_len,
984
size_t *out_len, u8 **appl_data,
985
size_t *appl_data_len)
987
struct tls_global *global = ssl_ctx;
978
static struct wpabuf * gnutls_get_appl_data(struct tls_connection *conn)
982
wpa_printf(MSG_DEBUG, "GnuTLS: Check for possible Application Data");
983
ad = wpabuf_alloc((wpabuf_len(conn->pull_buf) + 500) * 3);
987
res = gnutls_record_recv(conn->session, wpabuf_mhead(ad),
989
wpa_printf(MSG_DEBUG, "GnuTLS: gnutls_record_recv: %d", res);
991
wpa_printf(MSG_DEBUG, "%s - gnutls_ia_recv failed: %d "
992
"(%s)", __func__, (int) res,
993
gnutls_strerror(res));
999
wpa_printf(MSG_DEBUG, "GnuTLS: Received %d bytes of Application Data",
1005
struct wpabuf * tls_connection_handshake(void *tls_ctx,
1006
struct tls_connection *conn,
1007
const struct wpabuf *in_data,
1008
struct wpabuf **appl_data)
1010
struct tls_global *global = tls_ctx;
1011
struct wpabuf *out_data;
992
1015
*appl_data = NULL;
994
if (in_data && in_len) {
1017
if (in_data && wpabuf_len(in_data) > 0) {
995
1018
if (conn->pull_buf) {
996
1019
wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
997
1020
"pull_buf", __func__,
998
(unsigned long) conn->pull_buf_len);
999
os_free(conn->pull_buf);
1021
(unsigned long) wpabuf_len(conn->pull_buf));
1022
wpabuf_free(conn->pull_buf);
1001
conn->pull_buf = os_malloc(in_len);
1024
conn->pull_buf = wpabuf_dup(in_data);
1002
1025
if (conn->pull_buf == NULL)
1004
os_memcpy(conn->pull_buf, in_data, in_len);
1005
conn->pull_buf_offset = conn->pull_buf;
1006
conn->pull_buf_len = in_len;
1027
conn->pull_buf_offset = wpabuf_head(conn->pull_buf);
1009
1030
ret = gnutls_handshake(conn->session);
1073
1094
global->session_data,
1074
1095
&global->session_data_size);
1098
if (conn->pull_buf && appl_data)
1099
*appl_data = gnutls_get_appl_data(conn);
1079
1103
out_data = conn->push_buf;
1080
*out_len = conn->push_buf_len;
1081
1104
conn->push_buf = NULL;
1082
conn->push_buf_len = 0;
1083
1105
return out_data;
1087
u8 * tls_connection_server_handshake(void *ssl_ctx,
1088
struct tls_connection *conn,
1089
const u8 *in_data, size_t in_len,
1109
struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
1110
struct tls_connection *conn,
1111
const struct wpabuf *in_data,
1112
struct wpabuf **appl_data)
1092
return tls_connection_handshake(ssl_ctx, conn, in_data, in_len,
1093
out_len, NULL, NULL);
1114
return tls_connection_handshake(tls_ctx, conn, in_data, appl_data);
1097
int tls_connection_encrypt(void *ssl_ctx, struct tls_connection *conn,
1098
const u8 *in_data, size_t in_len,
1099
u8 *out_data, size_t out_len)
1118
struct wpabuf * tls_connection_encrypt(void *tls_ctx,
1119
struct tls_connection *conn,
1120
const struct wpabuf *in_data)
1103
1125
#ifdef GNUTLS_IA
1104
1126
if (conn->tls_ia)
1105
res = gnutls_ia_send(conn->session, (char *) in_data, in_len);
1127
res = gnutls_ia_send(conn->session, wpabuf_head(in_data),
1128
wpabuf_len(in_data));
1107
1130
#endif /* GNUTLS_IA */
1108
res = gnutls_record_send(conn->session, in_data, in_len);
1131
res = gnutls_record_send(conn->session, wpabuf_head(in_data),
1132
wpabuf_len(in_data));
1110
1134
wpa_printf(MSG_INFO, "%s: Encryption failed: %s",
1111
1135
__func__, gnutls_strerror(res));
1114
if (conn->push_buf == NULL)
1116
if (conn->push_buf_len < out_len)
1117
out_len = conn->push_buf_len;
1118
else if (conn->push_buf_len > out_len) {
1119
wpa_printf(MSG_INFO, "GnuTLS: Not enough buffer space for "
1120
"encrypted message (in_len=%lu push_buf_len=%lu "
1122
(unsigned long) in_len,
1123
(unsigned long) conn->push_buf_len,
1124
(unsigned long) out_len);
1126
os_memcpy(out_data, conn->push_buf, out_len);
1127
os_free(conn->push_buf);
1139
buf = conn->push_buf;
1128
1140
conn->push_buf = NULL;
1129
conn->push_buf_len = 0;
1134
int tls_connection_decrypt(void *ssl_ctx, struct tls_connection *conn,
1135
const u8 *in_data, size_t in_len,
1136
u8 *out_data, size_t out_len)
1145
struct wpabuf * tls_connection_decrypt(void *tls_ctx,
1146
struct tls_connection *conn,
1147
const struct wpabuf *in_data)
1140
1152
if (conn->pull_buf) {
1141
1153
wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
1142
1154
"pull_buf", __func__,
1143
(unsigned long) conn->pull_buf_len);
1144
os_free(conn->pull_buf);
1155
(unsigned long) wpabuf_len(conn->pull_buf));
1156
wpabuf_free(conn->pull_buf);
1146
conn->pull_buf = os_malloc(in_len);
1158
conn->pull_buf = wpabuf_dup(in_data);
1147
1159
if (conn->pull_buf == NULL)
1149
os_memcpy(conn->pull_buf, in_data, in_len);
1150
conn->pull_buf_offset = conn->pull_buf;
1151
conn->pull_buf_len = in_len;
1161
conn->pull_buf_offset = wpabuf_head(conn->pull_buf);
1164
* Even though we try to disable TLS compression, it is possible that
1165
* this cannot be done with all TLS libraries. Add extra buffer space
1166
* to handle the possibility of the decrypted data being longer than
1169
out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
1153
1173
#ifdef GNUTLS_IA
1154
1174
if (conn->tls_ia) {
1155
res = gnutls_ia_recv(conn->session, (char *) out_data,
1157
if (out_len >= 12 &&
1158
(res == GNUTLS_E_WARNING_IA_IPHF_RECEIVED ||
1159
res == GNUTLS_E_WARNING_IA_FPHF_RECEIVED)) {
1175
res = gnutls_ia_recv(conn->session, wpabuf_mhead(out),
1177
if (res == GNUTLS_E_WARNING_IA_IPHF_RECEIVED ||
1178
res == GNUTLS_E_WARNING_IA_FPHF_RECEIVED) {
1160
1179
int final = res == GNUTLS_E_WARNING_IA_FPHF_RECEIVED;
1161
1180
wpa_printf(MSG_DEBUG, "%s: Received %sPhaseFinished",
1162
1181
__func__, final ? "Final" : "Intermediate");
1187
1207
wpa_printf(MSG_INFO, "%s: Endphase "
1188
1208
"verification failed: %s",
1189
1209
__func__, gnutls_strerror(res));
1194
1215
conn->final_phase_finished = 1;
1200
1221
wpa_printf(MSG_DEBUG, "%s - gnutls_ia_recv failed: %d "
1201
1222
"(%s)", __func__, (int) res,
1202
1223
gnutls_strerror(res));
1227
wpabuf_put(out, res);
1206
1230
#endif /* GNUTLS_IA */
1208
res = gnutls_record_recv(conn->session, out_data, out_len);
1232
res = gnutls_record_recv(conn->session, wpabuf_mhead(out),
1210
1235
wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d "
1211
1236
"(%s)", __func__, (int) res, gnutls_strerror(res));
1240
wpabuf_put(out, res);