implemented server side support for EAP-TTLS
[strongswan.git] / src / libcharon / plugins / eap_ttls / eap_ttls_avp.c
1 /*
2 * Copyright (C) 2010 Andreas Steffen
3 * Copyright (C) 2010 HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "eap_ttls_avp.h"
17
18 #include <debug.h>
19
20 #define AVP_EAP_MESSAGE 79
21
22 typedef struct private_eap_ttls_avp_t private_eap_ttls_avp_t;
23
24 /**
25 * Private data of an eap_ttls_avp_t object.
26 */
27 struct private_eap_ttls_avp_t {
28
29 /**
30 * Public eap_ttls_avp_t interface.
31 */
32 eap_ttls_avp_t public;
33 };
34
35 METHOD(eap_ttls_avp_t, build, void,
36 private_eap_ttls_avp_t *this, tls_writer_t *writer, chunk_t data)
37 {
38 char zero_padding[] = { 0x00, 0x00, 0x00 };
39 chunk_t avp_padding;
40 u_int8_t avp_flags;
41 u_int32_t avp_len;
42
43 avp_flags = 0x40;
44 avp_len = 8 + data.len;
45 avp_padding = chunk_create(zero_padding, (4 - data.len) % 4);
46
47 writer->write_uint32(writer, AVP_EAP_MESSAGE);
48 writer->write_uint8(writer, avp_flags);
49 writer->write_uint24(writer, avp_len);
50 writer->write_data(writer, data);
51 writer->write_data(writer, avp_padding);
52 }
53
54 METHOD(eap_ttls_avp_t, process, status_t,
55 private_eap_ttls_avp_t* this, tls_reader_t *reader, chunk_t *data)
56 {
57 u_int32_t avp_code;
58 u_int8_t avp_flags;
59 u_int32_t avp_len, data_len;
60
61 if (!reader->read_uint32(reader, &avp_code) ||
62 !reader->read_uint8(reader, &avp_flags) ||
63 !reader->read_uint24(reader, &avp_len))
64 {
65 DBG1(DBG_IKE, "received invalid AVP");
66 return FAILED;
67 }
68 if (avp_code != AVP_EAP_MESSAGE)
69 {
70 DBG1(DBG_IKE, "expected AVP_EAP_MESSAGE but received %u", avp_code);
71 return FAILED;
72 }
73 data_len = avp_len - 8;
74 if (!reader->read_data(reader, data_len + (4 - avp_len) % 4, data))
75 {
76 DBG1(DBG_IKE, "received insufficient AVP data");
77 return FAILED;
78 }
79 data->len = data_len;
80 return SUCCESS;
81 }
82
83 METHOD(eap_ttls_avp_t, destroy, void,
84 private_eap_ttls_avp_t *this)
85 {
86 free(this);
87 }
88
89 /**
90 * See header
91 */
92 eap_ttls_avp_t *eap_ttls_avp_create(void)
93 {
94 private_eap_ttls_avp_t *this;
95
96 INIT(this,
97 .public= {
98 .process = _process,
99 .build = _build,
100 .destroy = _destroy,
101 },
102 );
103
104 return &this->public;
105 }