more consistent authentication logging
[strongswan.git] / src / charon / sa / authenticator.c
1 /**
2 * @file authenticator.c
3 *
4 * @brief Implementation of authenticator_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005-2006 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 */
23
24 #include <string.h>
25
26 #include "authenticator.h"
27
28 #include <config/policies/policy.h>
29 #include <daemon.h>
30
31 /**
32 * Key pad for the AUTH method SHARED_KEY_MESSAGE_INTEGRITY_CODE.
33 */
34 #define IKEV2_KEY_PAD "Key Pad for IKEv2"
35
36
37 typedef struct private_authenticator_t private_authenticator_t;
38
39 /**
40 * Private data of an authenticator_t object.
41 */
42 struct private_authenticator_t {
43
44 /**
45 * Public authenticator_t interface.
46 */
47 authenticator_t public;
48
49 /**
50 * Assigned IKE_SA. Needed to get objects of type prf_t and logger_t.
51 */
52 ike_sa_t *ike_sa;
53
54 /**
55 * auth_method to create own signature/mac/whatever..
56 */
57 auth_method_t auth_method;
58
59 /**
60 * PRF taken from the IKE_SA.
61 */
62 prf_t *prf;
63
64 /**
65 * A logger for.
66 *
67 * Using logger of IKE_SA.
68 */
69 logger_t *logger;
70
71 /**
72 * @brief Builds the octets to be signed (RSA or PSK) as described in section 2.15 of RFC 4306.
73 *
74 * @param this calling object
75 * @param last_message the last message to include in created octets
76 * (either binary form of IKE_SA_INIT request or IKE_SA_INIT response)
77 * @param other_nonce Nonce data received from other peer
78 * @param id ID of signer
79 * @param initiator Type of peer. TRUE, if it is original initiator, FALSE otherwise
80 * @return octets as described in section 2.15. Memory gets allocated and has to get
81 * destroyed by caller.
82 */
83 chunk_t (*build_tbs_octets) (private_authenticator_t *this,
84 chunk_t last_message,
85 chunk_t other_nonce,
86 identification_t *id,
87 bool initiator);
88
89 /**
90 * @brief Creates the AUTH data using auth method SHARED_KEY_MESSAGE_INTEGRITY_CODE.
91 *
92 * @param this calling object
93 * @param last_message the last message
94 * (either binary form of IKE_SA_INIT request or IKE_SA_INIT response)
95 * @param nonce Nonce data to include in auth data compution
96 * @param id ID of signer
97 * @param initiator Type of peer. TRUE, if it is original initiator, FALSE otherwise
98 * @param secret shared secret as chunk_t. If shared secret is a string,
99 * the NULL termination is not included.
100 * @return AUTH data as dscribed in section 2.15 for
101 * AUTH method SHARED_KEY_MESSAGE_INTEGRITY_CODE.
102 * Memory gets allocated and has to get destroyed by caller.
103 */
104 chunk_t (*build_shared_key_signature) (private_authenticator_t *this,
105 chunk_t last_message,
106 chunk_t nonce,
107 identification_t *id,
108 bool initiator,
109 chunk_t secret);
110 };
111
112 /**
113 * Implementation of private_authenticator_t.build_tbs_octets.
114 */
115 static chunk_t build_tbs_octets(private_authenticator_t *this,
116 chunk_t last_message,
117 chunk_t other_nonce,
118 identification_t *id,
119 bool initiator)
120 {
121 prf_t *prf;
122
123 chunk_t id_encoding = id->get_encoding(id);
124 u_int8_t id_with_header[4 + id_encoding.len];
125 chunk_t id_with_header_chunk = {ptr:id_with_header, len: sizeof(id_with_header)};
126
127 u_int8_t *current_pos;
128 chunk_t octets;
129
130 id_with_header[0] = id->get_type(id);
131 id_with_header[1] = 0x00;
132 id_with_header[2] = 0x00;
133 id_with_header[3] = 0x00;
134 memcpy(id_with_header + 4, id_encoding.ptr, id_encoding.len);
135
136 if (initiator)
137 {
138 prf = this->ike_sa->get_prf_auth_i(this->ike_sa);
139 }
140 else
141 {
142 prf = this->ike_sa->get_prf_auth_r(this->ike_sa);
143 }
144
145 /* 4 bytes are id type and reserved fields of id payload */
146 octets.len = last_message.len + other_nonce.len + prf->get_block_size(prf);
147 octets.ptr = malloc(octets.len);
148 current_pos = octets.ptr;
149 memcpy(current_pos, last_message.ptr, last_message.len);
150 current_pos += last_message.len;
151 memcpy(current_pos, other_nonce.ptr, other_nonce.len);
152 current_pos += other_nonce.len;
153 prf->get_bytes(prf, id_with_header_chunk, current_pos);
154
155 return octets;
156 }
157
158 /**
159 * Implementation of private_authenticator_t.build_shared_key_signature.
160 */
161 static chunk_t build_shared_key_signature(private_authenticator_t *this,
162 chunk_t last_message,
163 chunk_t nonce,
164 identification_t *id,
165 bool initiator,
166 chunk_t secret)
167 {
168 chunk_t key_pad = {ptr: IKEV2_KEY_PAD, len:strlen(IKEV2_KEY_PAD)};
169 u_int8_t key_buffer[this->prf->get_block_size(this->prf)];
170 chunk_t key = {ptr: key_buffer, len: sizeof(key_buffer)};
171 chunk_t auth_data;
172
173 chunk_t octets = this->build_tbs_octets(this, last_message, nonce, id, initiator);
174
175 /* AUTH = prf(prf(Shared Secret,"Key Pad for IKEv2"), <msg octets>) */
176 this->prf->set_key(this->prf, secret);
177 this->prf->get_bytes(this->prf, key_pad, key_buffer);
178 this->prf->set_key(this->prf, key);
179 this->prf->allocate_bytes(this->prf, octets, &auth_data);
180 this->logger->log_chunk(this->logger, RAW|LEVEL2,
181 "octets = message + nonce + prf(Sk_px, IDx')", octets);
182 this->logger->log_chunk(this->logger, PRIVATE|LEVEL2,
183 "secret", secret);
184 this->logger->log_chunk(this->logger, RAW|LEVEL2,
185 "keypad", key_pad);
186 this->logger->log_chunk(this->logger, RAW|LEVEL2,
187 "prf(secret, keypad)", key);
188 this->logger->log_chunk(this->logger,RAW | LEVEL2,
189 "AUTH = prf(prf(secret, keypad), octets)", auth_data);
190 chunk_free(&octets);
191
192 return auth_data;
193 }
194
195 /**
196 * Implementation of authenticator_t.verify_auth_data.
197 */
198 static status_t verify_auth_data (private_authenticator_t *this,
199 auth_payload_t *auth_payload,
200 chunk_t last_received_packet,
201 chunk_t my_nonce,
202 identification_t *my_id,
203 identification_t *other_id,
204 bool initiator)
205 {
206 status_t status;
207 chunk_t auth_data = auth_payload->get_data(auth_payload);
208 auth_method_t auth_method = auth_payload->get_auth_method(auth_payload);
209
210 switch (auth_method)
211 {
212 case SHARED_KEY_MESSAGE_INTEGRITY_CODE:
213 {
214 chunk_t shared_key;
215 chunk_t my_auth_data;
216
217 status = charon->credentials->get_shared_key(charon->credentials,
218 my_id,
219 other_id,
220 &shared_key);
221 if (status != SUCCESS)
222 {
223 this->logger->log(this->logger, ERROR, "no shared key found for '%s' and '%s'",
224 my_id->get_string(my_id), other_id->get_string(other_id));
225 chunk_free(&shared_key);
226 break;
227 }
228
229 my_auth_data = this->build_shared_key_signature(this,
230 last_received_packet,
231 my_nonce,
232 other_id,
233 initiator,
234 shared_key);
235 chunk_free(&shared_key);
236
237 status = (auth_data.len == my_auth_data.len && memeq(auth_data.ptr, my_auth_data.ptr, my_auth_data.len))
238 ? SUCCESS : FAILED;
239 chunk_free(&my_auth_data);
240 break;
241 }
242 case RSA_DIGITAL_SIGNATURE:
243 {
244 chunk_t octets;
245
246 rsa_public_key_t *public_key =
247 charon->credentials->get_trusted_public_key(charon->credentials, other_id);
248
249 if (public_key == NULL)
250 {
251 this->logger->log(this->logger, ERROR, "no RSA public key found for '%s'",
252 other_id->get_string(other_id));
253 status = NOT_FOUND;
254 break;
255 }
256
257 octets = this->build_tbs_octets(this, last_received_packet, my_nonce, other_id, initiator);
258
259 status = public_key->verify_emsa_pkcs1_signature(public_key, octets, auth_data);
260 chunk_free(&octets);
261 break;
262 }
263 default:
264 {
265 return NOT_SUPPORTED;
266 }
267 }
268
269 this->logger->log(this->logger, CONTROL, "authentication of '%s' with %s %s",
270 other_id->get_string(other_id),
271 enum_name(&auth_method_names, auth_method),
272 (status == SUCCESS)? "successful":"failed");
273 return status;
274 }
275
276 /**
277 * Implementation of authenticator_t.compute_auth_data.
278 */
279 static status_t compute_auth_data (private_authenticator_t *this,
280 auth_payload_t **auth_payload,
281 chunk_t last_sent_packet,
282 chunk_t other_nonce,
283 identification_t *my_id,
284 identification_t *other_id,
285 bool initiator)
286 {
287 this->logger->log(this->logger, CONTROL, "authentication of '%s' with %s (myself)",
288 my_id->get_string(my_id),
289 enum_name(&auth_method_names, this->auth_method));
290
291 switch (this->auth_method)
292 {
293 case SHARED_KEY_MESSAGE_INTEGRITY_CODE:
294 {
295 chunk_t shared_key;
296 chunk_t auth_data;
297
298 status_t status = charon->credentials->get_shared_key(charon->credentials,
299 my_id,
300 other_id,
301 &shared_key);
302
303 if (status != SUCCESS)
304 {
305 this->logger->log(this->logger, ERROR, "no shared key found for '%s' and '%s'",
306 my_id->get_string(my_id), other_id->get_string(other_id));
307 return status;
308 }
309
310 auth_data = this->build_shared_key_signature(this,
311 last_sent_packet,
312 other_nonce,
313 my_id,
314 initiator,
315 shared_key);
316 chunk_free(&shared_key);
317 *auth_payload = auth_payload_create();
318 (*auth_payload)->set_auth_method(*auth_payload, SHARED_KEY_MESSAGE_INTEGRITY_CODE);
319 (*auth_payload)->set_data(*auth_payload, auth_data);
320
321 chunk_free(&auth_data);
322 return SUCCESS;
323 }
324 case RSA_DIGITAL_SIGNATURE:
325 {
326 char buf[BUF_LEN];
327 chunk_t octets;
328 chunk_t auth_data;
329 status_t status;
330 rsa_public_key_t *my_pubkey;
331 rsa_private_key_t *my_key;
332
333 this->logger->log(this->logger, CONTROL|LEVEL1, "looking for RSA public key belonging to '%s'",
334 my_id->get_string(my_id));
335
336 my_pubkey = charon->credentials->get_rsa_public_key(charon->credentials, my_id);
337 if (my_pubkey == NULL)
338 {
339 this->logger->log(this->logger, ERROR, "no RSA public key found for '%s'",
340 my_id->get_string(my_id));
341 return NOT_FOUND;
342 }
343 this->logger->log(this->logger, CONTROL|LEVEL2, "matching RSA public key found");
344
345 chunk_to_hex(buf, BUF_LEN, my_pubkey->get_keyid(my_pubkey));
346 this->logger->log(this->logger, CONTROL|LEVEL1, "looking for RSA private key with keyid %s", buf);
347
348 my_key = charon->credentials->get_rsa_private_key(charon->credentials, my_pubkey);
349 if (my_key == NULL)
350 {
351 char buf[BUF_LEN];
352
353 chunk_to_hex(buf, BUF_LEN, my_pubkey->get_keyid(my_pubkey));
354 this->logger->log(this->logger, ERROR, "no RSA private key found with for %s with keyid %s",
355 my_id->get_string(my_id), buf);
356 return NOT_FOUND;
357 }
358 this->logger->log(this->logger, CONTROL|LEVEL2, "matching RSA private key found");
359
360 octets = this->build_tbs_octets(this, last_sent_packet, other_nonce, my_id, initiator);
361 status = my_key->build_emsa_pkcs1_signature(my_key, HASH_SHA1, octets, &auth_data);
362 chunk_free(&octets);
363
364 if (status != SUCCESS)
365 {
366 my_key->destroy(my_key);
367 return status;
368 }
369 this->logger->log(this->logger, CONTROL|LEVEL2, "successfully signed with RSA private key");
370
371 *auth_payload = auth_payload_create();
372 (*auth_payload)->set_auth_method(*auth_payload, RSA_DIGITAL_SIGNATURE);
373 (*auth_payload)->set_data(*auth_payload, auth_data);
374
375 my_key->destroy(my_key);
376 chunk_free(&auth_data);
377 return SUCCESS;
378 }
379 default:
380 {
381 return NOT_SUPPORTED;
382 }
383 }
384 }
385
386 /**
387 * Implementation of authenticator_t.destroy.
388 */
389 static void destroy (private_authenticator_t *this)
390 {
391 free(this);
392 }
393
394 /*
395 * Described in header.
396 */
397 authenticator_t *authenticator_create(ike_sa_t *ike_sa, auth_method_t auth_method)
398 {
399 private_authenticator_t *this = malloc_thing(private_authenticator_t);
400
401 /* Public functions */
402 this->public.destroy = (void(*)(authenticator_t*))destroy;
403 this->public.verify_auth_data = (status_t (*) (authenticator_t*,auth_payload_t*,chunk_t,
404 chunk_t,identification_t*,identification_t*,bool)) verify_auth_data;
405 this->public.compute_auth_data = (status_t (*) (authenticator_t*,auth_payload_t**,chunk_t,
406 chunk_t,identification_t*,identification_t*,bool)) compute_auth_data;
407
408 /* private functions */
409 this->build_tbs_octets = build_tbs_octets;
410 this->build_shared_key_signature = build_shared_key_signature;
411
412 /* private data */
413 this->ike_sa = ike_sa;
414 this->auth_method = auth_method;
415 this->prf = this->ike_sa->get_prf(this->ike_sa);
416 this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
417
418 return &(this->public);
419 }