Use message instead of attributes in hook
[strongswan.git] / src / libsimaka / simaka_message.h
1 /*
2 * Copyright (C) 2009 Martin Willi
3 * 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 /**
17 * @defgroup libsimaka libsimaka
18 *
19 * @addtogroup libsimaka
20 * Library providing functions shared between EAP-SIM and EAP-AKA plugins.
21 *
22 * @defgroup simaka_message simaka_message
23 * @{ @ingroup libsimaka
24 */
25
26 #ifndef SIMAKA_MESSAGE_H_
27 #define SIMAKA_MESSAGE_H_
28
29 #include <enum.h>
30 #include <daemon.h>
31
32 #include "simaka_crypto.h"
33
34 typedef enum simaka_attribute_t simaka_attribute_t;
35 typedef enum simaka_subtype_t simaka_subtype_t;
36 typedef enum simaka_notification_t simaka_notification_t;
37 typedef enum simaka_client_error_t simaka_client_error_t;
38
39 /**
40 * Subtypes of EAP-SIM/AKA messages
41 */
42 enum simaka_subtype_t {
43 AKA_CHALLENGE = 1,
44 AKA_AUTHENTICATION_REJECT = 2,
45 AKA_SYNCHRONIZATION_FAILURE = 4,
46 AKA_IDENTITY = 5,
47 SIM_START = 10,
48 SIM_CHALLENGE = 11,
49 SIM_NOTIFICATION = 12,
50 AKA_NOTIFICATION = 12,
51 SIM_REAUTHENTICATION = 13,
52 AKA_REAUTHENTICATION = 13,
53 SIM_CLIENT_ERROR = 14,
54 AKA_CLIENT_ERROR = 14,
55 };
56
57 /**
58 * Enum names for simaka_subtype_t
59 */
60 extern enum_name_t *simaka_subtype_names;
61
62 /**
63 * Attributes in EAP-SIM/AKA messages
64 */
65 enum simaka_attribute_t {
66 AT_RAND = 1,
67 AT_AUTN = 2,
68 AT_RES = 3,
69 AT_AUTS = 4,
70 AT_PADDING = 6,
71 AT_NONCE_MT = 7,
72 AT_PERMANENT_ID_REQ = 10,
73 AT_MAC = 11,
74 AT_NOTIFICATION = 12,
75 AT_ANY_ID_REQ = 13,
76 AT_IDENTITY = 14,
77 AT_VERSION_LIST = 15,
78 AT_SELECTED_VERSION = 16,
79 AT_FULLAUTH_ID_REQ = 17,
80 AT_COUNTER = 19,
81 AT_COUNTER_TOO_SMALL = 20,
82 AT_NONCE_S = 21,
83 AT_CLIENT_ERROR_CODE = 22,
84 AT_IV = 129,
85 AT_ENCR_DATA = 130,
86 AT_NEXT_PSEUDONYM = 132,
87 AT_NEXT_REAUTH_ID = 133,
88 AT_CHECKCODE = 134,
89 AT_RESULT_IND = 135,
90 };
91
92 /**
93 * Enum names for simaka_attribute_t
94 */
95 extern enum_name_t *simaka_attribute_names;
96
97 /**
98 * Notification codes used within AT_NOTIFICATION attribute.
99 */
100 enum simaka_notification_t {
101 /** SIM General failure after authentication. (Implies failure) */
102 SIM_GENERAL_FAILURE_AA = 0,
103 /** AKA General failure after authentication. (Implies failure) */
104 AKA_GENERAL_FAILURE_AA = 0,
105 /** SIM General failure. (Implies failure, used before authentication) */
106 SIM_GENERAL_FAILURE = 16384,
107 /** AKA General failure. (Implies failure, used before authentication) */
108 AKA_GENERAL_FAILURE = 16384,
109 /** SIM User has been temporarily denied access to the requested service. */
110 SIM_TEMP_DENIED = 1026,
111 /** AKA User has been temporarily denied access to the requested service. */
112 AKA_TEMP_DENIED = 1026,
113 /** SIM User has not subscribed to the requested service. */
114 SIM_NOT_SUBSCRIBED = 1031,
115 /** AKA User has not subscribed to the requested service. */
116 AKA_NOT_SUBSCRIBED = 1031,
117 /** SIM Success. User has been successfully authenticated. */
118 SIM_SUCCESS = 32768,
119 /** AKA Success. User has been successfully authenticated. */
120 AKA_SUCCESS = 32768,
121 };
122
123 /**
124 * Enum names for simaka_notification_t
125 */
126 extern enum_name_t *simaka_notification_names;
127
128 /**
129 * Error codes sent in AT_CLIENT_ERROR_CODE attribute
130 */
131 enum simaka_client_error_t {
132 /** AKA unable to process packet */
133 AKA_UNABLE_TO_PROCESS = 0,
134 /** SIM unable to process packet */
135 SIM_UNABLE_TO_PROCESS = 0,
136 /** SIM unsupported version */
137 SIM_UNSUPPORTED_VERSION = 1,
138 /** SIM insufficient number of challenges */
139 SIM_INSUFFICIENT_CHALLENGES = 2,
140 /** SIM RANDs are not fresh */
141 SIM_RANDS_NOT_FRESH = 3,
142 };
143
144 /**
145 * Enum names for simaka_client_error_t
146 */
147 extern enum_name_t *simaka_client_error_names;
148
149 /**
150 * Check if an EAP-SIM/AKA attribute is "skippable".
151 *
152 * @param attribute attribute to check
153 * @return TRUE if attribute skippable, FALSE if non-skippable
154 */
155 bool simaka_attribute_skippable(simaka_attribute_t attribute);
156
157 /**
158 * EAP-SIM and EAP-AKA message abstraction.
159 *
160 * Messages for EAP-SIM and EAP-AKA share a common format, this class
161 * abstracts such a message and provides encoding/encryption/signing
162 * functionality.
163 */
164 struct simaka_message_t {
165
166 /**
167 * Check if the given message is a request or response.
168 *
169 * @return TRUE if request, FALSE if response
170 */
171 bool (*is_request)(simaka_message_t *this);
172
173 /**
174 * Get the EAP message identifier.
175 *
176 * @return EAP message identifier
177 */
178 u_int8_t (*get_identifier)(simaka_message_t *this);
179
180 /**
181 * Get the EAP type of the message.
182 *
183 * @return EAP type: EAP-SIM or EAP-AKA
184 */
185 eap_type_t (*get_type)(simaka_message_t *this);
186
187 /**
188 * Get the subtype of an EAP-SIM message.
189 *
190 * @return subtype of message
191 */
192 simaka_subtype_t (*get_subtype)(simaka_message_t *this);
193
194 /**
195 * Create an enumerator over message attributes.
196 *
197 * @return enumerator over (simaka_attribute_t, chunk_t)
198 */
199 enumerator_t* (*create_attribute_enumerator)(simaka_message_t *this);
200
201 /**
202 * Append an attribute to the EAP-SIM message.
203 *
204 * Make sure to pass only data of correct length for the given attribute.
205 *
206 * @param type type of attribute to add to message
207 * @param data unpadded attribute data to add
208 */
209 void (*add_attribute)(simaka_message_t *this, simaka_attribute_t type,
210 chunk_t data);
211
212 /**
213 * Parse a message, with optional attribute decryption.
214 *
215 * This method does not verify message integrity, as the key is available
216 * only after the payload has been parsed. It might be necessary to call
217 * parse twice, as key derivation data in EAP-SIM/AKA is in the same
218 * packet as encrypted data.
219 *
220 * @param crypto EAP-SIM/AKA crypto helper
221 * @return TRUE if message parsed successfully
222 */
223 bool (*parse)(simaka_message_t *this);
224
225 /**
226 * Verify the message integrity of a parsed message.
227 *
228 * @param crypto EAP-SIM/AKA crypto helper
229 * @param sigdata additional data to include in signature, if any
230 * @return TRUE if message integrity check successful
231 */
232 bool (*verify)(simaka_message_t *this, chunk_t sigdata);
233
234 /**
235 * Generate a message, optionally encrypt attributes and create a MAC.
236 *
237 * @param sigdata additional data to include in signature, if any
238 * @return generated eap payload, NULL if failed
239 */
240 eap_payload_t* (*generate)(simaka_message_t *this, chunk_t sigdata);
241
242 /**
243 * Destroy a simaka_message_t.
244 */
245 void (*destroy)(simaka_message_t *this);
246 };
247
248 /**
249 * Create an empty simaka_message.
250 *
251 * @param request TRUE for a request message, FALSE for a response
252 * @param identifier EAP message identifier
253 * @param type EAP type: EAP-SIM or EAP-AKA
254 * @param subtype subtype of the EAP message
255 * @param crypto EAP-SIM/AKA crypto helper
256 * @return empty message of requested kind, NULL on error
257 */
258 simaka_message_t *simaka_message_create(bool request, u_int8_t identifier,
259 eap_type_t type, simaka_subtype_t subtype,
260 simaka_crypto_t *crypto);
261
262 /**
263 * Create an simaka_message from a chunk of data.
264 *
265 * @param payload payload to create message from
266 * @param crypto EAP-SIM/AKA crypto helper
267 * @return EAP message, NULL on error
268 */
269 simaka_message_t *simaka_message_create_from_payload(eap_payload_t *payload,
270 simaka_crypto_t *crypto);
271
272 #endif /** SIMAKA_MESSAGE_H_ @}*/