OSDN Git Service

am be5cce4a: Check if interface is valid in wpa_ctrl_close()
[android-x86/external-wpa_supplicant.git] / eap_tls_common.c
1 /*
2  * EAP peer: EAP-TLS/PEAP/TTLS/FAST common functions
3  * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "includes.h"
16
17 #include "common.h"
18 #include "eap_i.h"
19 #include "eap_tls_common.h"
20 #include "config_ssid.h"
21 #include "md5.h"
22 #include "sha1.h"
23 #include "tls.h"
24 #include "config.h"
25
26 static int eap_tls_check_blob(struct eap_sm *sm, const char **name,
27                               const u8 **data, size_t *data_len)
28 {
29         const struct wpa_config_blob *blob;
30
31         if (*name == NULL || os_strncmp(*name, "blob://", 7) != 0)
32                 return 0;
33
34         blob = eap_get_config_blob(sm, *name + 7);
35         if (blob == NULL) {
36                 wpa_printf(MSG_ERROR, "%s: Named configuration blob '%s' not "
37                            "found", __func__, *name + 7);
38                 return -1;
39         }
40         *name = NULL;
41         *data = blob->data;
42         *data_len = blob->len;
43
44         return 0;
45 }
46
47
48 static void eap_tls_params_from_conf1(struct tls_connection_params *params,
49                                       struct wpa_ssid *config)
50 {
51         params->ca_cert = (char *) config->ca_cert;
52         params->ca_path = (char *) config->ca_path;
53         params->client_cert = (char *) config->client_cert;
54         params->private_key = (char *) config->private_key;
55         params->private_key_passwd = (char *) config->private_key_passwd;
56         params->dh_file = (char *) config->dh_file;
57         params->subject_match = (char *) config->subject_match;
58         params->altsubject_match = (char *) config->altsubject_match;
59         params->engine_id = config->engine_id;
60         params->pin = config->pin;
61         params->key_id = config->key_id;
62 }
63
64
65 static void eap_tls_params_from_conf2(struct tls_connection_params *params,
66                                       struct wpa_ssid *config)
67 {
68         params->ca_cert = (char *) config->ca_cert2;
69         params->ca_path = (char *) config->ca_path2;
70         params->client_cert = (char *) config->client_cert2;
71         params->private_key = (char *) config->private_key2;
72         params->private_key_passwd = (char *) config->private_key2_passwd;
73         params->dh_file = (char *) config->dh_file2;
74         params->subject_match = (char *) config->subject_match2;
75         params->altsubject_match = (char *) config->altsubject_match2;
76 }
77
78
79 static int eap_tls_params_from_conf(struct eap_sm *sm,
80                                     struct eap_ssl_data *data,
81                                     struct tls_connection_params *params,
82                                     struct wpa_ssid *config, int phase2)
83 {
84         os_memset(params, 0, sizeof(*params));
85         params->engine = config->engine;
86         if (phase2)
87                 eap_tls_params_from_conf2(params, config);
88         else
89                 eap_tls_params_from_conf1(params, config);
90         params->tls_ia = data->tls_ia;
91
92
93         if (eap_tls_check_blob(sm, &params->ca_cert, &params->ca_cert_blob,
94                                &params->ca_cert_blob_len) ||
95             eap_tls_check_blob(sm, &params->client_cert,
96                                &params->client_cert_blob,
97                                &params->client_cert_blob_len) ||
98             eap_tls_check_blob(sm, &params->private_key,
99                                &params->private_key_blob,
100                                &params->private_key_blob_len) ||
101             eap_tls_check_blob(sm, &params->dh_file, &params->dh_blob,
102                                &params->dh_blob_len)) {
103                 wpa_printf(MSG_INFO, "SSL: Failed to get configuration blobs");
104                 return -1;
105         }
106
107         return 0;
108 }
109
110
111 static int eap_tls_init_connection(struct eap_sm *sm,
112                                    struct eap_ssl_data *data,
113                                    struct wpa_ssid *config,
114                                    struct tls_connection_params *params)
115 {
116         int res;
117
118         data->conn = tls_connection_init(sm->ssl_ctx);
119         if (data->conn == NULL) {
120                 wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS "
121                            "connection");
122                 return -1;
123         }
124
125         res = tls_connection_set_params(sm->ssl_ctx, data->conn, params);
126         if (res == TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED) {
127                 /* At this point with the pkcs11 engine the PIN might be wrong.
128                  * We reset the PIN in the configuration to be sure to not use
129                  * it again and the calling function must request a new one */
130                 os_free(config->pin);
131                 config->pin = NULL;
132         } else if (res == TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED) {
133                 wpa_printf(MSG_INFO, "TLS: Failed to load private key");
134                 /* We don't know exactly but maybe the PIN was wrong,
135                  * so ask for a new one. */
136                 os_free(config->pin);
137                 config->pin = NULL;
138                 eap_sm_request_pin(sm);
139                 sm->ignore = TRUE;
140                 return -1;
141         } else if (res) {
142                 wpa_printf(MSG_INFO, "TLS: Failed to set TLS connection "
143                            "parameters");
144                 return -1;
145         }
146
147         return 0;
148 }
149
150
151 /**
152  * eap_tls_ssl_init - Initialize shared TLS functionality
153  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
154  * @data: Data for TLS processing
155  * @config: Pointer to the network configuration
156  * Returns: 0 on success, -1 on failure
157  *
158  * This function is used to initialize shared TLS functionality for EAP-TLS,
159  * EAP-PEAP, EAP-TTLS, and EAP-FAST.
160  */
161 int eap_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
162                      struct wpa_ssid *config)
163 {
164         int ret = -1;
165         struct tls_connection_params params;
166
167         if (config == NULL)
168                 return -1;
169
170         data->eap = sm;
171         data->phase2 = sm->init_phase2;
172         if (eap_tls_params_from_conf(sm, data, &params, config, data->phase2) <
173             0)
174                 goto done;
175
176         if (eap_tls_init_connection(sm, data, config, &params) < 0)
177                 goto done;
178
179         data->tls_out_limit = config->fragment_size;
180         if (data->phase2) {
181                 /* Limit the fragment size in the inner TLS authentication
182                  * since the outer authentication with EAP-PEAP does not yet
183                  * support fragmentation */
184                 if (data->tls_out_limit > 100)
185                         data->tls_out_limit -= 100;
186         }
187
188         if (config->phase1 &&
189             os_strstr(config->phase1, "include_tls_length=1")) {
190                 wpa_printf(MSG_DEBUG, "TLS: Include TLS Message Length in "
191                            "unfragmented packets");
192                 data->include_tls_length = 1;
193         }
194
195         ret = 0;
196
197 done:
198         return ret;
199 }
200
201
202 /**
203  * eap_tls_ssl_deinit - Deinitialize shared TLS functionality
204  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
205  * @data: Data for TLS processing
206  *
207  * This function deinitializes shared TLS functionality that was initialized
208  * with eap_tls_ssl_init().
209  */
210 void eap_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
211 {
212         tls_connection_deinit(sm->ssl_ctx, data->conn);
213         os_free(data->tls_in);
214         os_free(data->tls_out);
215 }
216
217
218 /**
219  * eap_tls_derive_key - Derive a key based on TLS session data
220  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
221  * @data: Data for TLS processing
222  * @label: Label string for deriving the keys, e.g., "client EAP encryption"
223  * @len: Length of the key material to generate (usually 64 for MSK)
224  * Returns: Pointer to allocated key on success or %NULL on failure
225  *
226  * This function uses TLS-PRF to generate pseudo-random data based on the TLS
227  * session data (client/server random and master key). Each key type may use a
228  * different label to bind the key usage into the generated material.
229  *
230  * The caller is responsible for freeing the returned buffer.
231  */
232 u8 * eap_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
233                         const char *label, size_t len)
234 {
235         struct tls_keys keys;
236         u8 *rnd = NULL, *out;
237
238         out = os_malloc(len);
239         if (out == NULL)
240                 return NULL;
241
242         /* First, try to use TLS library function for PRF, if available. */
243         if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, out, len) ==
244             0)
245                 return out;
246
247         /*
248          * TLS library did not support key generation, so get the needed TLS
249          * session parameters and use an internal implementation of TLS PRF to
250          * derive the key.
251          */
252         if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
253                 goto fail;
254
255         if (keys.client_random == NULL || keys.server_random == NULL ||
256             keys.master_key == NULL)
257                 goto fail;
258
259         rnd = os_malloc(keys.client_random_len + keys.server_random_len);
260         if (rnd == NULL)
261                 goto fail;
262         os_memcpy(rnd, keys.client_random, keys.client_random_len);
263         os_memcpy(rnd + keys.client_random_len, keys.server_random,
264                   keys.server_random_len);
265
266         if (tls_prf(keys.master_key, keys.master_key_len,
267                     label, rnd, keys.client_random_len +
268                     keys.server_random_len, out, len))
269                 goto fail;
270
271         os_free(rnd);
272         return out;
273
274 fail:
275         os_free(out);
276         os_free(rnd);
277         return NULL;
278 }
279
280
281 /**
282  * eap_tls_data_reassemble - Reassemble TLS data
283  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
284  * @data: Data for TLS processing
285  * @in_data: Next incoming TLS segment
286  * @in_len: Length of in_data
287  * @out_len: Variable for returning output data length
288  * @need_more_input: Variable for returning whether more input data is needed
289  * to reassemble this TLS packet
290  * Returns: Pointer to output data, %NULL on error or when more data is needed
291  * for the full message (in which case, *need_more_input is also set to 1).
292  *
293  * This function reassembles TLS fragments. Caller must not free the returned
294  * data buffer since an internal pointer to it is maintained.
295  */
296 const u8 * eap_tls_data_reassemble(
297         struct eap_sm *sm, struct eap_ssl_data *data, const u8 *in_data,
298         size_t in_len, size_t *out_len, int *need_more_input)
299 {
300         u8 *buf;
301
302         *need_more_input = 0;
303
304         if (data->tls_in_left > in_len || data->tls_in) {
305                 if (data->tls_in_len + in_len == 0) {
306                         os_free(data->tls_in);
307                         data->tls_in = NULL;
308                         data->tls_in_len = 0;
309                         wpa_printf(MSG_WARNING, "SSL: Invalid reassembly "
310                                    "state: tls_in_left=%lu tls_in_len=%lu "
311                                    "in_len=%lu",
312                                    (unsigned long) data->tls_in_left,
313                                    (unsigned long) data->tls_in_len,
314                                    (unsigned long) in_len);
315                         return NULL;
316                 }
317                 if (data->tls_in_len + in_len > 65536) {
318                         /* Limit length to avoid rogue servers from causing
319                          * large memory allocations. */
320                         os_free(data->tls_in);
321                         data->tls_in = NULL;
322                         data->tls_in_len = 0;
323                         wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size"
324                                    " over 64 kB)");
325                         return NULL;
326                 }
327                 buf = os_realloc(data->tls_in, data->tls_in_len + in_len);
328                 if (buf == NULL) {
329                         os_free(data->tls_in);
330                         data->tls_in = NULL;
331                         data->tls_in_len = 0;
332                         wpa_printf(MSG_INFO, "SSL: Could not allocate memory "
333                                    "for TLS data");
334                         return NULL;
335                 }
336                 os_memcpy(buf + data->tls_in_len, in_data, in_len);
337                 data->tls_in = buf;
338                 data->tls_in_len += in_len;
339                 if (in_len > data->tls_in_left) {
340                         wpa_printf(MSG_INFO, "SSL: more data than TLS message "
341                                    "length indicated");
342                         data->tls_in_left = 0;
343                         return NULL;
344                 }
345                 data->tls_in_left -= in_len;
346                 if (data->tls_in_left > 0) {
347                         wpa_printf(MSG_DEBUG, "SSL: Need %lu bytes more input "
348                                    "data", (unsigned long) data->tls_in_left);
349                         *need_more_input = 1;
350                         return NULL;
351                 }
352         } else {
353                 data->tls_in_left = 0;
354                 data->tls_in = os_malloc(in_len ? in_len : 1);
355                 if (data->tls_in == NULL)
356                         return NULL;
357                 os_memcpy(data->tls_in, in_data, in_len);
358                 data->tls_in_len = in_len;
359         }
360
361         *out_len = data->tls_in_len;
362         return data->tls_in;
363 }
364
365
366 static int eap_tls_process_input(struct eap_sm *sm, struct eap_ssl_data *data,
367                                  const u8 *in_data, size_t in_len,
368                                  u8 **out_data, size_t *out_len)
369 {
370         const u8 *msg;
371         size_t msg_len;
372         int need_more_input;
373         u8 *appl_data;
374         size_t appl_data_len;
375
376         msg = eap_tls_data_reassemble(sm, data, in_data, in_len,
377                                       &msg_len, &need_more_input);
378         if (msg == NULL)
379                 return need_more_input ? 1 : -1;
380
381         /* Full TLS message reassembled - continue handshake processing */
382         if (data->tls_out) {
383                 /* This should not happen.. */
384                 wpa_printf(MSG_INFO, "SSL: eap_tls_process_helper - pending "
385                            "tls_out data even though tls_out_len = 0");
386                 os_free(data->tls_out);
387                 WPA_ASSERT(data->tls_out == NULL);
388         }
389         appl_data = NULL;
390         data->tls_out = tls_connection_handshake(sm->ssl_ctx, data->conn,
391                                                  msg, msg_len,
392                                                  &data->tls_out_len,
393                                                  &appl_data, &appl_data_len);
394
395         /* Clear reassembled input data (if the buffer was needed). */
396         data->tls_in_left = data->tls_in_total = data->tls_in_len = 0;
397         os_free(data->tls_in);
398         data->tls_in = NULL;
399
400         if (appl_data &&
401             tls_connection_established(sm->ssl_ctx, data->conn) &&
402             !tls_connection_get_failed(sm->ssl_ctx, data->conn)) {
403                 wpa_hexdump_key(MSG_MSGDUMP, "SSL: Application data",
404                                 appl_data, appl_data_len);
405                 *out_data = appl_data;
406                 *out_len = appl_data_len;
407                 return 2;
408         }
409
410         os_free(appl_data);
411
412         return 0;
413 }
414
415
416 static int eap_tls_process_output(struct eap_ssl_data *data, EapType eap_type,
417                                   int peap_version, u8 id, int ret,
418                                   u8 **out_data, size_t *out_len)
419 {
420         size_t len;
421         u8 *pos, *flags;
422         int more_fragments, length_included;
423         
424         wpa_printf(MSG_DEBUG, "SSL: %lu bytes left to be sent out (of total "
425                    "%lu bytes)",
426                    (unsigned long) data->tls_out_len - data->tls_out_pos,
427                    (unsigned long) data->tls_out_len);
428
429         len = data->tls_out_len - data->tls_out_pos;
430         if (len > data->tls_out_limit) {
431                 more_fragments = 1;
432                 len = data->tls_out_limit;
433                 wpa_printf(MSG_DEBUG, "SSL: sending %lu bytes, more fragments "
434                            "will follow", (unsigned long) len);
435         } else
436                 more_fragments = 0;
437
438         length_included = data->tls_out_pos == 0 &&
439                 (data->tls_out_len > data->tls_out_limit ||
440                  data->include_tls_length);
441
442         *out_data = (u8 *)
443                 eap_msg_alloc(EAP_VENDOR_IETF, eap_type, out_len,
444                               1 + length_included * 4 + len, EAP_CODE_RESPONSE,
445                               id, &pos);
446         if (*out_data == NULL)
447                 return -1;
448
449         flags = pos++;
450         *flags = peap_version;
451         if (more_fragments)
452                 *flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS;
453         if (length_included) {
454                 *flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED;
455                 WPA_PUT_BE32(pos, data->tls_out_len);
456                 pos += 4;
457         }
458
459         os_memcpy(pos, &data->tls_out[data->tls_out_pos], len);
460         data->tls_out_pos += len;
461
462         if (!more_fragments) {
463                 data->tls_out_len = 0;
464                 data->tls_out_pos = 0;
465                 os_free(data->tls_out);
466                 data->tls_out = NULL;
467         }
468
469         return ret;
470 }
471
472
473 /**
474  * eap_tls_process_helper - Process TLS handshake message
475  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
476  * @data: Data for TLS processing
477  * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...)
478  * @peap_version: Version number for EAP-PEAP/TTLS
479  * @id: EAP identifier for the response
480  * @in_data: Message received from the server
481  * @in_len: Length of in_data
482  * @out_data: Buffer for returning a pointer to the response message
483  * @out_len: Buffer for returning the length of the response message
484  * Returns: 0 on success, 1 if more input data is needed, or -1 on failure
485  *
486  * This function can be used to process TLS handshake messages. It reassembles
487  * the received fragments and uses a TLS library to process the messages. The
488  * response data from the TLS library is fragmented to suitable output messages
489  * that the caller can send out.
490  *
491  * out_data is used to return the response message if the return value of this
492  * function is 0 or -1. In case of failure, the message is likely a TLS alarm
493  * message. The caller is responsible for freeing the allocated buffer if
494  * *out_data is not %NULL.
495  */
496 int eap_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
497                            EapType eap_type, int peap_version,
498                            u8 id, const u8 *in_data, size_t in_len,
499                            u8 **out_data, size_t *out_len)
500 {
501         int ret = 0;
502
503         WPA_ASSERT(data->tls_out_len == 0 || in_len == 0);
504         *out_len = 0;
505         *out_data = NULL;
506
507         if (data->tls_out_len == 0) {
508                 /* No more data to send out - expect to receive more data from
509                  * the AS. */
510                 int res = eap_tls_process_input(sm, data, in_data, in_len,
511                                                 out_data, out_len);
512                 if (res)
513                         return res;
514         }
515
516         if (data->tls_out == NULL) {
517                 data->tls_out_len = 0;
518                 return -1;
519         }
520
521         if (tls_connection_get_failed(sm->ssl_ctx, data->conn)) {
522                 wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to "
523                            "report error");
524                 ret = -1;
525                 /* TODO: clean pin if engine used? */
526         }
527
528         if (data->tls_out_len == 0) {
529                 /* TLS negotiation should now be complete since all other cases
530                  * needing more data should have been caught above based on
531                  * the TLS Message Length field. */
532                 wpa_printf(MSG_DEBUG, "SSL: No data to be sent out");
533                 os_free(data->tls_out);
534                 data->tls_out = NULL;
535                 return 1;
536         }
537
538         return eap_tls_process_output(data, eap_type, peap_version, id, ret,
539                                       out_data, out_len);
540 }
541
542
543 /**
544  * eap_tls_build_ack - Build a TLS ACK frames
545  * @data: Data for TLS processing
546  * @respDataLen: Buffer for returning the length of the response message
547  * @id: EAP identifier for the response
548  * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...)
549  * @peap_version: Version number for EAP-PEAP/TTLS
550  * Returns: Pointer to allocated ACK frames or %NULL on failure
551  */
552 u8 * eap_tls_build_ack(struct eap_ssl_data *data, size_t *respDataLen, u8 id,
553                        EapType eap_type, int peap_version)
554 {
555         struct eap_hdr *resp;
556         u8 *pos;
557
558         resp = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, respDataLen,
559                              1, EAP_CODE_RESPONSE, id, &pos);
560         if (resp == NULL)
561                 return NULL;
562         wpa_printf(MSG_DEBUG, "SSL: Building ACK");
563         *pos = peap_version; /* Flags */
564         return (u8 *) resp;
565 }
566
567
568 /**
569  * eap_tls_reauth_init - Re-initialize shared TLS for session resumption
570  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
571  * @data: Data for TLS processing
572  * Returns: 0 on success, -1 on failure
573  */
574 int eap_tls_reauth_init(struct eap_sm *sm, struct eap_ssl_data *data)
575 {
576         os_free(data->tls_in);
577         data->tls_in = NULL;
578         data->tls_in_len = data->tls_in_left = data->tls_in_total = 0;
579         os_free(data->tls_out);
580         data->tls_out = NULL;
581         data->tls_out_len = data->tls_out_pos = 0;
582
583         return tls_connection_shutdown(sm->ssl_ctx, data->conn);
584 }
585
586
587 /**
588  * eap_tls_status - Get TLS status
589  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
590  * @data: Data for TLS processing
591  * @buf: Buffer for status information
592  * @buflen: Maximum buffer length
593  * @verbose: Whether to include verbose status information
594  * Returns: Number of bytes written to buf.
595  */
596 int eap_tls_status(struct eap_sm *sm, struct eap_ssl_data *data, char *buf,
597                    size_t buflen, int verbose)
598 {
599         char name[128];
600         int len = 0, ret;
601
602         if (tls_get_cipher(sm->ssl_ctx, data->conn, name, sizeof(name)) == 0) {
603                 ret = os_snprintf(buf + len, buflen - len,
604                                   "EAP TLS cipher=%s\n", name);
605                 if (ret < 0 || (size_t) ret >= buflen - len)
606                         return len;
607                 len += ret;
608         }
609
610         return len;
611 }
612
613
614 /**
615  * eap_tls_process_init - Initial validation and processing of EAP requests
616  * @sm: Pointer to EAP state machine allocated with eap_sm_init()
617  * @data: Data for TLS processing
618  * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...)
619  * @ret: Return values from EAP request validation and processing
620  * @reqData: EAP request to be processed (eapReqData)
621  * @reqDataLen: Length of the EAP request
622  * @len: Buffer for returning length of the remaining payload
623  * @flags: Buffer for returning TLS flags
624  * Returns: Buffer to payload after TLS flags and length or %NULL on failure
625  */
626 const u8 * eap_tls_process_init(struct eap_sm *sm, struct eap_ssl_data *data,
627                                 EapType eap_type, struct eap_method_ret *ret,
628                                 const u8 *reqData, size_t reqDataLen,
629                                 size_t *len, u8 *flags)
630 {
631         const u8 *pos;
632         size_t left;
633         unsigned int tls_msg_len;
634
635         if (tls_get_errors(sm->ssl_ctx)) {
636                 wpa_printf(MSG_INFO, "SSL: TLS errors detected");
637                 ret->ignore = TRUE;
638                 return NULL;
639         }
640
641         pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, reqData, reqDataLen,
642                                &left);
643         if (pos == NULL) {
644                 ret->ignore = TRUE;
645                 return NULL;
646         }
647         *flags = *pos++;
648         left--;
649         wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - "
650                    "Flags 0x%02x", (unsigned long) reqDataLen, *flags);
651         if (*flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
652                 if (left < 4) {
653                         wpa_printf(MSG_INFO, "SSL: Short frame with TLS "
654                                    "length");
655                         ret->ignore = TRUE;
656                         return NULL;
657                 }
658                 tls_msg_len = WPA_GET_BE32(pos);
659                 wpa_printf(MSG_DEBUG, "SSL: TLS Message Length: %d",
660                            tls_msg_len);
661                 if (data->tls_in_left == 0) {
662                         data->tls_in_total = tls_msg_len;
663                         data->tls_in_left = tls_msg_len;
664                         os_free(data->tls_in);
665                         data->tls_in = NULL;
666                         data->tls_in_len = 0;
667                 }
668                 pos += 4;
669                 left -= 4;
670         }
671
672         ret->ignore = FALSE;
673         ret->methodState = METHOD_MAY_CONT;
674         ret->decision = DECISION_FAIL;
675         ret->allowNotifications = TRUE;
676
677         *len = (size_t) left;
678         return pos;
679 }