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