]>
Commit | Line | Data |
---|---|---|
21079538 MW |
1 | /* |
2 | * Copyright (C) 2010 Martin Willi | |
3 | * Copyright (C) 2010 revosec AG | |
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_tls.h" | |
17 | ||
be751012 | 18 | #include <tls_eap.h> |
dcbbeb2d | 19 | |
21079538 MW |
20 | #include <daemon.h> |
21 | #include <library.h> | |
22 | ||
23 | typedef struct private_eap_tls_t private_eap_tls_t; | |
24 | ||
25 | /** | |
26 | * Private data of an eap_tls_t object. | |
27 | */ | |
28 | struct private_eap_tls_t { | |
29 | ||
30 | /** | |
31 | * Public interface. | |
32 | */ | |
33 | eap_tls_t public; | |
34 | ||
21079538 | 35 | /** |
be751012 | 36 | * TLS stack, wrapped by EAP helper |
21079538 | 37 | */ |
be751012 | 38 | tls_eap_t *tls_eap; |
21079538 MW |
39 | }; |
40 | ||
c8a2fca5 | 41 | /** Maximum number of EAP-TLS messages/fragments allowed */ |
6a5c86b7 | 42 | #define MAX_MESSAGE_COUNT 32 |
f9fc5f20 MW |
43 | /** Default size of a EAP-TLS fragment */ |
44 | #define MAX_FRAGMENT_LEN 1024 | |
b173819e | 45 | |
21079538 MW |
46 | METHOD(eap_method_t, initiate, status_t, |
47 | private_eap_tls_t *this, eap_payload_t **out) | |
48 | { | |
4c0124a0 | 49 | chunk_t data; |
b173819e | 50 | |
be751012 | 51 | if (this->tls_eap->initiate(this->tls_eap, &data) == NEED_MORE) |
4c0124a0 | 52 | { |
be751012 MW |
53 | *out = eap_payload_create_data(data); |
54 | free(data.ptr); | |
55 | return NEED_MORE; | |
b173819e | 56 | } |
be751012 | 57 | return FAILED; |
b173819e MW |
58 | } |
59 | ||
21079538 MW |
60 | METHOD(eap_method_t, process, status_t, |
61 | private_eap_tls_t *this, eap_payload_t *in, eap_payload_t **out) | |
62 | { | |
b173819e | 63 | status_t status; |
be751012 | 64 | chunk_t data; |
b173819e MW |
65 | |
66 | data = in->get_data(in); | |
be751012 | 67 | status = this->tls_eap->process(this->tls_eap, data, &data); |
b173819e MW |
68 | if (status == NEED_MORE) |
69 | { | |
be751012 MW |
70 | *out = eap_payload_create_data(data); |
71 | free(data.ptr); | |
5ff8c627 | 72 | } |
b173819e | 73 | return status; |
21079538 MW |
74 | } |
75 | ||
76 | METHOD(eap_method_t, get_type, eap_type_t, | |
77 | private_eap_tls_t *this, u_int32_t *vendor) | |
78 | { | |
79 | *vendor = 0; | |
80 | return EAP_TLS; | |
81 | } | |
82 | ||
83 | METHOD(eap_method_t, get_msk, status_t, | |
84 | private_eap_tls_t *this, chunk_t *msk) | |
85 | { | |
be751012 | 86 | *msk = this->tls_eap->get_msk(this->tls_eap); |
51313a39 MW |
87 | if (msk->len) |
88 | { | |
89 | return SUCCESS; | |
90 | } | |
21079538 MW |
91 | return FAILED; |
92 | } | |
93 | ||
934216df AS |
94 | METHOD(eap_method_t, get_identifier, u_int8_t, |
95 | private_eap_tls_t *this) | |
96 | { | |
97 | return this->tls_eap->get_identifier(this->tls_eap); | |
98 | } | |
99 | ||
100 | METHOD(eap_method_t, set_identifier, void, | |
101 | private_eap_tls_t *this, u_int8_t identifier) | |
102 | { | |
103 | this->tls_eap->set_identifier(this->tls_eap, identifier); | |
104 | } | |
105 | ||
21079538 MW |
106 | METHOD(eap_method_t, is_mutual, bool, |
107 | private_eap_tls_t *this) | |
108 | { | |
109 | return TRUE; | |
110 | } | |
111 | ||
112 | METHOD(eap_method_t, destroy, void, | |
113 | private_eap_tls_t *this) | |
114 | { | |
be751012 | 115 | this->tls_eap->destroy(this->tls_eap); |
21079538 MW |
116 | free(this); |
117 | } | |
118 | ||
119 | /** | |
120 | * Generic private constructor | |
121 | */ | |
122 | static eap_tls_t *eap_tls_create(identification_t *server, | |
123 | identification_t *peer, bool is_server) | |
124 | { | |
125 | private_eap_tls_t *this; | |
f9fc5f20 | 126 | size_t frag_size; |
de29e3a6 | 127 | int max_msg_count; |
2778b664 | 128 | bool include_length; |
d2b1d437 | 129 | tls_t *tls; |
21079538 MW |
130 | |
131 | INIT(this, | |
ba31fe1f MW |
132 | .public = { |
133 | .eap_method = { | |
134 | .initiate = _initiate, | |
135 | .process = _process, | |
136 | .get_type = _get_type, | |
137 | .is_mutual = _is_mutual, | |
138 | .get_msk = _get_msk, | |
934216df AS |
139 | .get_identifier = _get_identifier, |
140 | .set_identifier = _set_identifier, | |
ba31fe1f MW |
141 | .destroy = _destroy, |
142 | }, | |
21079538 | 143 | }, |
21079538 | 144 | ); |
b173819e | 145 | |
f9fc5f20 MW |
146 | frag_size = lib->settings->get_int(lib->settings, |
147 | "charon.plugins.eap-tls.fragment_size", MAX_FRAGMENT_LEN); | |
de29e3a6 AS |
148 | max_msg_count = lib->settings->get_int(lib->settings, |
149 | "charon.plugins.eap-tls.max_message_count", MAX_MESSAGE_COUNT); | |
2778b664 | 150 | include_length = lib->settings->get_bool(lib->settings, |
6a5c86b7 MW |
151 | "charon.plugins.eap-tls.include_length", TRUE); |
152 | tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TLS, NULL, NULL); | |
2778b664 AS |
153 | this->tls_eap = tls_eap_create(EAP_TLS, tls, frag_size, max_msg_count, |
154 | include_length); | |
be751012 | 155 | if (!this->tls_eap) |
96b2fbcc MW |
156 | { |
157 | free(this); | |
158 | return NULL; | |
159 | } | |
21079538 MW |
160 | return &this->public; |
161 | } | |
162 | ||
163 | eap_tls_t *eap_tls_create_server(identification_t *server, | |
164 | identification_t *peer) | |
165 | { | |
166 | return eap_tls_create(server, peer, TRUE); | |
167 | } | |
168 | ||
169 | eap_tls_t *eap_tls_create_peer(identification_t *server, | |
170 | identification_t *peer) | |
171 | { | |
172 | return eap_tls_create(server, peer, FALSE); | |
173 | } |