00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "crypto/sha1.h"
00019 #include "crypto/tls.h"
00020 #include "eap_i.h"
00021 #include "eap_tls_common.h"
00022
00023
00024 static void eap_server_tls_free_in_buf(struct eap_ssl_data *data);
00025
00026
00027 int eap_server_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
00028 int verify_peer)
00029 {
00030 data->eap = sm;
00031 data->phase2 = sm->init_phase2;
00032
00033 data->conn = tls_connection_init(sm->ssl_ctx);
00034 if (data->conn == NULL) {
00035 wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS "
00036 "connection");
00037 return -1;
00038 }
00039
00040 if (tls_connection_set_verify(sm->ssl_ctx, data->conn, verify_peer)) {
00041 wpa_printf(MSG_INFO, "SSL: Failed to configure verification "
00042 "of TLS peer certificate");
00043 tls_connection_deinit(sm->ssl_ctx, data->conn);
00044 data->conn = NULL;
00045 return -1;
00046 }
00047
00048
00049 data->tls_out_limit = 1398;
00050 if (data->phase2) {
00051
00052
00053
00054 if (data->tls_out_limit > 100)
00055 data->tls_out_limit -= 100;
00056 }
00057 return 0;
00058 }
00059
00060
00061 void eap_server_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
00062 {
00063 tls_connection_deinit(sm->ssl_ctx, data->conn);
00064 eap_server_tls_free_in_buf(data);
00065 wpabuf_free(data->tls_out);
00066 data->tls_out = NULL;
00067 }
00068
00069
00070 u8 * eap_server_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
00071 char *label, size_t len)
00072 {
00073 struct tls_keys keys;
00074 u8 *rnd = NULL, *out;
00075
00076 out = os_malloc(len);
00077 if (out == NULL)
00078 return NULL;
00079
00080 if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, out, len) ==
00081 0)
00082 return out;
00083
00084 if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
00085 goto fail;
00086
00087 if (keys.client_random == NULL || keys.server_random == NULL ||
00088 keys.master_key == NULL)
00089 goto fail;
00090
00091 rnd = os_malloc(keys.client_random_len + keys.server_random_len);
00092 if (rnd == NULL)
00093 goto fail;
00094 os_memcpy(rnd, keys.client_random, keys.client_random_len);
00095 os_memcpy(rnd + keys.client_random_len, keys.server_random,
00096 keys.server_random_len);
00097
00098 if (tls_prf(keys.master_key, keys.master_key_len,
00099 label, rnd, keys.client_random_len +
00100 keys.server_random_len, out, len))
00101 goto fail;
00102
00103 os_free(rnd);
00104 return out;
00105
00106 fail:
00107 os_free(out);
00108 os_free(rnd);
00109 return NULL;
00110 }
00111
00112
00113 struct wpabuf * eap_server_tls_build_msg(struct eap_ssl_data *data,
00114 int eap_type, int version, u8 id)
00115 {
00116 struct wpabuf *req;
00117 u8 flags;
00118 size_t send_len, plen;
00119
00120 wpa_printf(MSG_DEBUG, "SSL: Generating Request");
00121 if (data->tls_out == NULL) {
00122 wpa_printf(MSG_ERROR, "SSL: tls_out NULL in %s", __func__);
00123 return NULL;
00124 }
00125
00126 flags = version;
00127 send_len = wpabuf_len(data->tls_out) - data->tls_out_pos;
00128 if (1 + send_len > data->tls_out_limit) {
00129 send_len = data->tls_out_limit - 1;
00130 flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS;
00131 if (data->tls_out_pos == 0) {
00132 flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED;
00133 send_len -= 4;
00134 }
00135 }
00136
00137 plen = 1 + send_len;
00138 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED)
00139 plen += 4;
00140
00141 req = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, plen,
00142 EAP_CODE_REQUEST, id);
00143 if (req == NULL)
00144 return NULL;
00145
00146 wpabuf_put_u8(req, flags);
00147 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED)
00148 wpabuf_put_be32(req, wpabuf_len(data->tls_out));
00149
00150 wpabuf_put_data(req, wpabuf_head_u8(data->tls_out) + data->tls_out_pos,
00151 send_len);
00152 data->tls_out_pos += send_len;
00153
00154 if (data->tls_out_pos == wpabuf_len(data->tls_out)) {
00155 wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes "
00156 "(message sent completely)",
00157 (unsigned long) send_len);
00158 wpabuf_free(data->tls_out);
00159 data->tls_out = NULL;
00160 data->tls_out_pos = 0;
00161 data->state = MSG;
00162 } else {
00163 wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes "
00164 "(%lu more to send)", (unsigned long) send_len,
00165 (unsigned long) wpabuf_len(data->tls_out) -
00166 data->tls_out_pos);
00167 data->state = WAIT_FRAG_ACK;
00168 }
00169
00170 return req;
00171 }
00172
00173
00174 struct wpabuf * eap_server_tls_build_ack(u8 id, int eap_type, int version)
00175 {
00176 struct wpabuf *req;
00177
00178 req = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, 1, EAP_CODE_REQUEST,
00179 id);
00180 if (req == NULL)
00181 return NULL;
00182 wpa_printf(MSG_DEBUG, "SSL: Building ACK");
00183 wpabuf_put_u8(req, version);
00184 return req;
00185 }
00186
00187
00188 static int eap_server_tls_process_cont(struct eap_ssl_data *data,
00189 const u8 *buf, size_t len)
00190 {
00191
00192 if (len > wpabuf_tailroom(data->tls_in)) {
00193 wpa_printf(MSG_DEBUG, "SSL: Fragment overflow");
00194 return -1;
00195 }
00196
00197 wpabuf_put_data(data->tls_in, buf, len);
00198 wpa_printf(MSG_DEBUG, "SSL: Received %lu bytes, waiting for %lu "
00199 "bytes more", (unsigned long) len,
00200 (unsigned long) wpabuf_tailroom(data->tls_in));
00201
00202 return 0;
00203 }
00204
00205
00206 static int eap_server_tls_process_fragment(struct eap_ssl_data *data,
00207 u8 flags, u32 message_length,
00208 const u8 *buf, size_t len)
00209 {
00210
00211 if (data->tls_in == NULL && !(flags & EAP_TLS_FLAGS_LENGTH_INCLUDED)) {
00212 wpa_printf(MSG_DEBUG, "SSL: No Message Length field in a "
00213 "fragmented packet");
00214 return -1;
00215 }
00216
00217 if (data->tls_in == NULL) {
00218
00219
00220
00221
00222 if (message_length > 65536) {
00223 wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size"
00224 " over 64 kB)");
00225 return -1;
00226 }
00227
00228 data->tls_in = wpabuf_alloc(message_length);
00229 if (data->tls_in == NULL) {
00230 wpa_printf(MSG_DEBUG, "SSL: No memory for message");
00231 return -1;
00232 }
00233 wpabuf_put_data(data->tls_in, buf, len);
00234 wpa_printf(MSG_DEBUG, "SSL: Received %lu bytes in first "
00235 "fragment, waiting for %lu bytes more",
00236 (unsigned long) len,
00237 (unsigned long) wpabuf_tailroom(data->tls_in));
00238 }
00239
00240 return 0;
00241 }
00242
00243
00244 int eap_server_tls_phase1(struct eap_sm *sm, struct eap_ssl_data *data)
00245 {
00246 if (data->tls_out) {
00247
00248 wpa_printf(MSG_INFO, "SSL: pending tls_out data when "
00249 "processing new message");
00250 wpabuf_free(data->tls_out);
00251 WPA_ASSERT(data->tls_out == NULL);
00252 }
00253
00254 data->tls_out = tls_connection_server_handshake(sm->ssl_ctx,
00255 data->conn,
00256 data->tls_in, NULL);
00257 if (data->tls_out == NULL) {
00258 wpa_printf(MSG_INFO, "SSL: TLS processing failed");
00259 return -1;
00260 }
00261 if (tls_connection_get_failed(sm->ssl_ctx, data->conn)) {
00262
00263 wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to "
00264 "report error");
00265 return -1;
00266 }
00267
00268 return 0;
00269 }
00270
00271
00272 static int eap_server_tls_reassemble(struct eap_ssl_data *data, u8 flags,
00273 const u8 **pos, size_t *left)
00274 {
00275 unsigned int tls_msg_len = 0;
00276 const u8 *end = *pos + *left;
00277
00278 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
00279 if (*left < 4) {
00280 wpa_printf(MSG_INFO, "SSL: Short frame with TLS "
00281 "length");
00282 return -1;
00283 }
00284 tls_msg_len = WPA_GET_BE32(*pos);
00285 wpa_printf(MSG_DEBUG, "SSL: TLS Message Length: %d",
00286 tls_msg_len);
00287 *pos += 4;
00288 *left -= 4;
00289 }
00290
00291 wpa_printf(MSG_DEBUG, "SSL: Received packet: Flags 0x%x "
00292 "Message Length %u", flags, tls_msg_len);
00293
00294 if (data->state == WAIT_FRAG_ACK) {
00295 if (*left != 0) {
00296 wpa_printf(MSG_DEBUG, "SSL: Unexpected payload in "
00297 "WAIT_FRAG_ACK state");
00298 return -1;
00299 }
00300 wpa_printf(MSG_DEBUG, "SSL: Fragment acknowledged");
00301 return 1;
00302 }
00303
00304 if (data->tls_in &&
00305 eap_server_tls_process_cont(data, *pos, end - *pos) < 0)
00306 return -1;
00307
00308 if (flags & EAP_TLS_FLAGS_MORE_FRAGMENTS) {
00309 if (eap_server_tls_process_fragment(data, flags, tls_msg_len,
00310 *pos, end - *pos) < 0)
00311 return -1;
00312
00313 data->state = FRAG_ACK;
00314 return 1;
00315 }
00316
00317 if (data->state == FRAG_ACK) {
00318 wpa_printf(MSG_DEBUG, "SSL: All fragments received");
00319 data->state = MSG;
00320 }
00321
00322 if (data->tls_in == NULL) {
00323
00324 wpabuf_set(&data->tmpbuf, *pos, end - *pos);
00325 data->tls_in = &data->tmpbuf;
00326 }
00327
00328 return 0;
00329 }
00330
00331
00332 static void eap_server_tls_free_in_buf(struct eap_ssl_data *data)
00333 {
00334 if (data->tls_in != &data->tmpbuf)
00335 wpabuf_free(data->tls_in);
00336 data->tls_in = NULL;
00337 }
00338
00339
00340 struct wpabuf * eap_server_tls_encrypt(struct eap_sm *sm,
00341 struct eap_ssl_data *data,
00342 const struct wpabuf *plain)
00343 {
00344 struct wpabuf *buf;
00345
00346 buf = tls_connection_encrypt(sm->ssl_ctx, data->conn,
00347 plain);
00348 if (buf == NULL) {
00349 wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 data");
00350 return NULL;
00351 }
00352
00353 return buf;
00354 }
00355
00356
00357 int eap_server_tls_process(struct eap_sm *sm, struct eap_ssl_data *data,
00358 struct wpabuf *respData, void *priv, int eap_type,
00359 int (*proc_version)(struct eap_sm *sm, void *priv,
00360 int peer_version),
00361 void (*proc_msg)(struct eap_sm *sm, void *priv,
00362 const struct wpabuf *respData))
00363 {
00364 const u8 *pos;
00365 u8 flags;
00366 size_t left;
00367 int ret, res = 0;
00368
00369 pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, respData, &left);
00370 if (pos == NULL || left < 1)
00371 return 0;
00372 flags = *pos++;
00373 left--;
00374 wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - Flags 0x%02x",
00375 (unsigned long) wpabuf_len(respData), flags);
00376
00377 if (proc_version &&
00378 proc_version(sm, priv, flags & EAP_TLS_VERSION_MASK) < 0)
00379 return -1;
00380
00381 ret = eap_server_tls_reassemble(data, flags, &pos, &left);
00382 if (ret < 0) {
00383 res = -1;
00384 goto done;
00385 } else if (ret == 1)
00386 return 0;
00387
00388 if (proc_msg)
00389 proc_msg(sm, priv, respData);
00390
00391 if (tls_connection_get_write_alerts(sm->ssl_ctx, data->conn) > 1) {
00392 wpa_printf(MSG_INFO, "SSL: Locally detected fatal error in "
00393 "TLS processing");
00394 res = -1;
00395 }
00396
00397 done:
00398 eap_server_tls_free_in_buf(data);
00399
00400 return res;
00401 }