2 * Copyright (C) 2010 Andreas Steffen
3 * Copyright (C) 2010 HSR Hochschule fuer Technik Rapperswil
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>.
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
16 #include "eap_ttls_avp.h"
20 #define AVP_EAP_MESSAGE 79
21 #define AVP_HEADER_LEN 8
23 typedef struct private_eap_ttls_avp_t private_eap_ttls_avp_t
;
26 * Private data of an eap_ttls_avp_t object.
28 struct private_eap_ttls_avp_t
{
31 * Public eap_ttls_avp_t interface.
33 eap_ttls_avp_t
public;
41 * Position in input buffer
46 * process header (TRUE) or body (FALSE)
56 METHOD(eap_ttls_avp_t
, build
, void,
57 private_eap_ttls_avp_t
*this, tls_writer_t
*writer
, chunk_t data
)
59 char zero_padding
[] = { 0x00, 0x00, 0x00 };
65 avp_len
= 8 + data
.len
;
66 avp_padding
= chunk_create(zero_padding
, (4 - data
.len
) % 4);
68 writer
->write_uint32(writer
, AVP_EAP_MESSAGE
);
69 writer
->write_uint8(writer
, avp_flags
);
70 writer
->write_uint24(writer
, avp_len
);
71 writer
->write_data(writer
, data
);
72 writer
->write_data(writer
, avp_padding
);
75 METHOD(eap_ttls_avp_t
, process
, status_t
,
76 private_eap_ttls_avp_t
* this, tls_reader_t
*reader
, chunk_t
*data
)
81 if (this->process_header
)
89 len
= min(reader
->remaining(reader
), AVP_HEADER_LEN
- this->inpos
);
90 if (!reader
->read_data(reader
, len
, &buf
))
94 if (this->input
.len
== 0)
96 /* start of a new AVP header */
97 this->input
= chunk_alloc(AVP_HEADER_LEN
);
98 memcpy(this->input
.ptr
, buf
.ptr
, len
);
103 memcpy(this->input
.ptr
+ this->inpos
, buf
.ptr
, len
);
107 if (this->inpos
< AVP_HEADER_LEN
)
112 /* parse AVP header */
113 header
= tls_reader_create(this->input
);
114 success
= header
->read_uint32(header
, &avp_code
) &&
115 header
->read_uint8(header
, &avp_flags
) &&
116 header
->read_uint24(header
, &avp_len
);
117 header
->destroy(header
);
118 chunk_free(&this->input
);
123 DBG1(DBG_IKE
, "received invalid AVP header");
126 if (avp_code
!= AVP_EAP_MESSAGE
)
128 DBG1(DBG_IKE
, "expected AVP_EAP_MESSAGE but received %u", avp_code
);
131 this->process_header
= FALSE
;
132 this->data_len
= avp_len
- 8;
133 this->input
= chunk_alloc(this->data_len
+ (4 - avp_len
) % 4);
136 /* process AVP data */
137 len
= min(reader
->remaining(reader
), this->input
.len
- this->inpos
);
138 if (!reader
->read_data(reader
, len
, &buf
))
142 memcpy(this->input
.ptr
+ this->inpos
, buf
.ptr
, len
);
144 if (this->inpos
< this->input
.len
)
150 data
->len
= this->data_len
;
152 /* preparing for next AVP */
153 this->input
= chunk_empty
;
155 this->process_header
= TRUE
;
160 METHOD(eap_ttls_avp_t
, destroy
, void,
161 private_eap_ttls_avp_t
*this)
163 chunk_free(&this->input
);
170 eap_ttls_avp_t
*eap_ttls_avp_create(void)
172 private_eap_ttls_avp_t
*this;
180 .input
= chunk_empty
,
182 .process_header
= TRUE
,
186 return &this->public;