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