2 * @file authenticator.c
4 * @brief Implementation of authenticator_t.
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 #include "authenticator.h"
30 * Key pad for the AUTH method SHARED_KEY_MESSAGE_INTEGRITY_CODE.
32 #define IKEV2_KEY_PAD "Key Pad for IKEv2"
35 typedef struct private_authenticator_t private_authenticator_t
;
38 * Private data of an authenticator_t object.
40 struct private_authenticator_t
{
43 * Public authenticator_t interface.
45 authenticator_t
public;
48 * Assigned IKE_SA. Needed to get objects of type prf_t and logger_t.
50 protected_ike_sa_t
*ike_sa
;
53 * PRF taken from the IKE_SA.
60 * Using logger of IKE_SA.
65 * @brief Creates the octets which are signed (RSA) or MACed (shared secret) as described in section
68 * @param this calling object
69 * @param last_message the last message to include in created octets
70 * (either binary form of IKE_SA_INIT request or IKE_SA_INIT response)
71 * @param other_nonce Nonce data received from other peer
72 * @param my_id id_payload_t object representing an ID payload
73 * @param initiator Type of peer. TRUE, if it is original initiator, FALSE otherwise
74 * @return octets as described in section 2.15. Memory gets allocated and has to get
75 * destroyed by caller.
77 chunk_t (*allocate_octets
) (private_authenticator_t
*this,
84 * @brief Creates the AUTH data using auth method SHARED_KEY_MESSAGE_INTEGRITY_CODE.
86 * @param this calling object
87 * @param last_message the last message
88 * (either binary form of IKE_SA_INIT request or IKE_SA_INIT response)
89 * @param nonce Nonce data to include in auth data compution
90 * @param id_payload id_payload_t object representing an ID payload
91 * @param initiator Type of peer. TRUE, if it is original initiator, FALSE otherwise
92 * @param shared_secret shared secret as chunk_t. If shared secret is a string,
93 * the NULL termination is not included.
94 * @return AUTH data as dscribed in section 2.15 for
95 * AUTH method SHARED_KEY_MESSAGE_INTEGRITY_CODE.
96 * Memory gets allocated and has to get destroyed by caller.
98 chunk_t (*build_preshared_secret_signature
) (private_authenticator_t
*this,
101 id_payload_t
*id_payload
,
103 chunk_t preshared_secret
);
107 * Implementation of private_authenticator_t.allocate_octets.
109 static chunk_t
allocate_octets(private_authenticator_t
*this,
110 chunk_t last_message
,
116 chunk_t id_chunk
= my_id
->get_data(my_id
);
117 u_int8_t id_with_header
[4 + id_chunk
.len
];
119 * IKEv2 for linux (http://sf.net/projects/ikev2/)
120 * is not compatible with IKEv2 Draft and so not compatible with this
121 * implementation, cause AUTH data are computed without
122 * ID type and the three reserved bytes.
124 chunk_t id_with_header_chunk
= {ptr
:id_with_header
, len
: sizeof(id_with_header
)};
125 u_int8_t
*current_pos
;
128 id_with_header
[0] = my_id
->get_id_type(my_id
);
129 id_with_header
[1] = 0x00;
130 id_with_header
[2] = 0x00;
131 id_with_header
[3] = 0x00;
132 memcpy(id_with_header
+ 4,id_chunk
.ptr
,id_chunk
.len
);
136 prf
= this->ike_sa
->get_prf_auth_i(this->ike_sa
);
140 prf
= this->ike_sa
->get_prf_auth_r(this->ike_sa
);
143 /* 4 bytes are id type and reserved fields of id payload */
144 octets
.len
= last_message
.len
+ other_nonce
.len
+ prf
->get_block_size(prf
);
145 octets
.ptr
= malloc(octets
.len
);
146 current_pos
= octets
.ptr
;
147 memcpy(current_pos
,last_message
.ptr
,last_message
.len
);
148 current_pos
+= last_message
.len
;
149 memcpy(current_pos
,other_nonce
.ptr
,other_nonce
.len
);
150 current_pos
+= other_nonce
.len
;
151 prf
->get_bytes(prf
, id_with_header_chunk
, current_pos
);
153 this->logger
->log_chunk(this->logger
,RAW
| LEVEL2
, "Octets (Mesage + Nonce + prf(Sk_px,Idx)",octets
);
158 * Implementation of private_authenticator_t.build_preshared_secret_signature.
160 static chunk_t
build_preshared_secret_signature(private_authenticator_t
*this,
161 chunk_t last_message
,
163 id_payload_t
*id_payload
,
165 chunk_t preshared_secret
)
167 chunk_t key_pad
= {ptr
: IKEV2_KEY_PAD
, len
:strlen(IKEV2_KEY_PAD
)};
168 u_int8_t key_buffer
[this->prf
->get_block_size(this->prf
)];
169 chunk_t key
= {ptr
: key_buffer
, len
: sizeof(key_buffer
)};
172 chunk_t octets
= this->allocate_octets(this,last_message
,nonce
,id_payload
,initiator
);
174 /* AUTH = prf(prf(Shared Secret,"Key Pad for IKEv2"), <msg octets>) */
175 this->prf
->set_key(this->prf
, preshared_secret
);
176 this->prf
->get_bytes(this->prf
, key_pad
, key_buffer
);
177 this->prf
->set_key(this->prf
, key
);
178 this->prf
->allocate_bytes(this->prf
, octets
, &auth_data
);
180 this->logger
->log_chunk(this->logger
,RAW
| LEVEL2
, "Authenticated data",auth_data
);
186 * Implementation of authenticator_t.verify_auth_data.
188 static status_t
verify_auth_data (private_authenticator_t
*this,
189 auth_payload_t
*auth_payload
,
190 chunk_t last_received_packet
,
192 id_payload_t
*other_id_payload
,
195 switch(auth_payload
->get_auth_method(auth_payload
))
197 case SHARED_KEY_MESSAGE_INTEGRITY_CODE
:
199 identification_t
*other_id
= other_id_payload
->get_identification(other_id_payload
);
200 chunk_t auth_data
= auth_payload
->get_data(auth_payload
);
201 chunk_t preshared_secret
;
204 status
= charon
->credentials
->get_shared_secret(charon
->credentials
,
207 if (status
!= SUCCESS
)
209 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "No shared secret found for %s",
210 other_id
->get_string(other_id
));
211 other_id
->destroy(other_id
);
215 chunk_t my_auth_data
= this->build_preshared_secret_signature(this,
216 last_received_packet
,
221 chunk_free(&preshared_secret
);
223 if (auth_data
.len
!= my_auth_data
.len
)
225 chunk_free(&my_auth_data
);
228 else if (memcmp(auth_data
.ptr
,my_auth_data
.ptr
, my_auth_data
.len
) == 0)
230 this->logger
->log(this->logger
, CONTROL
, "Authentication of %s with preshared secret successful",
231 other_id
->get_string(other_id
));
236 this->logger
->log(this->logger
, CONTROL
, "Authentication of %s with preshared secret failed",
237 other_id
->get_string(other_id
));
240 other_id
->destroy(other_id
);
241 chunk_free(&my_auth_data
);
244 case RSA_DIGITAL_SIGNATURE
:
246 identification_t
*other_id
= other_id_payload
->get_identification(other_id_payload
);
247 rsa_public_key_t
*public_key
;
249 chunk_t octets
, auth_data
;
251 auth_data
= auth_payload
->get_data(auth_payload
);
253 public_key
= charon
->credentials
->get_rsa_public_key(charon
->credentials
,
255 if (public_key
== NULL
)
257 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "No RSA public key found for %s",
258 other_id
->get_string(other_id
));
259 other_id
->destroy(other_id
);
263 octets
= this->allocate_octets(this,last_received_packet
, my_nonce
,other_id_payload
, initiator
);
265 status
= public_key
->verify_emsa_pkcs1_signature(public_key
, octets
, auth_data
);
266 if (status
== SUCCESS
)
268 this->logger
->log(this->logger
, CONTROL
, "Authentication of %s with RSA successful",
269 other_id
->get_string(other_id
));
273 this->logger
->log(this->logger
, CONTROL
, "Authentication of %s with RSA failed",
274 other_id
->get_string(other_id
));
277 public_key
->destroy(public_key
);
278 other_id
->destroy(other_id
);
284 return NOT_SUPPORTED
;
290 * Implementation of authenticator_t.compute_auth_data.
292 static status_t
compute_auth_data (private_authenticator_t
*this,
293 auth_payload_t
**auth_payload
,
294 chunk_t last_sent_packet
,
296 id_payload_t
*my_id_payload
,
299 connection_t
*connection
= this->ike_sa
->get_connection(this->ike_sa
);
301 switch(connection
->get_auth_method(connection
))
303 case SHARED_KEY_MESSAGE_INTEGRITY_CODE
:
305 identification_t
*my_id
= my_id_payload
->get_identification(my_id_payload
);
306 chunk_t preshared_secret
;
310 status
= charon
->credentials
->get_shared_secret(charon
->credentials
,
314 if (status
!= SUCCESS
)
316 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "No shared secret found for %s",
317 my_id
->get_string(my_id
));
318 my_id
->destroy(my_id
);
321 my_id
->destroy(my_id
);
323 auth_data
= this->build_preshared_secret_signature(this, last_sent_packet
, other_nonce
,
324 my_id_payload
, initiator
, preshared_secret
);
325 chunk_free(&preshared_secret
);
326 *auth_payload
= auth_payload_create();
327 (*auth_payload
)->set_auth_method(*auth_payload
, SHARED_KEY_MESSAGE_INTEGRITY_CODE
);
328 (*auth_payload
)->set_data(*auth_payload
, auth_data
);
330 chunk_free(&auth_data
);
333 case RSA_DIGITAL_SIGNATURE
:
335 identification_t
*my_id
= my_id_payload
->get_identification(my_id_payload
);
336 rsa_private_key_t
*private_key
;
338 chunk_t octets
, auth_data
;
340 private_key
= charon
->credentials
->get_rsa_private_key(charon
->credentials
, my_id
);
341 if (private_key
== NULL
)
343 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "No RSA private key found for %s",
344 my_id
->get_string(my_id
));
345 my_id
->destroy(my_id
);
348 my_id
->destroy(my_id
);
350 octets
= this->allocate_octets(this,last_sent_packet
,other_nonce
,my_id_payload
,initiator
);
352 status
= private_key
->build_emsa_pkcs1_signature(private_key
, HASH_SHA1
, octets
, &auth_data
);
354 if (status
!= SUCCESS
)
356 private_key
->destroy(private_key
);
360 *auth_payload
= auth_payload_create();
361 (*auth_payload
)->set_auth_method(*auth_payload
, RSA_DIGITAL_SIGNATURE
);
362 (*auth_payload
)->set_data(*auth_payload
, auth_data
);
364 private_key
->destroy(private_key
);
365 chunk_free(&auth_data
);
370 return NOT_SUPPORTED
;
376 * Implementation of authenticator_t.destroy.
378 static void destroy (private_authenticator_t
*this)
384 * Described in header.
386 authenticator_t
*authenticator_create(protected_ike_sa_t
*ike_sa
)
388 private_authenticator_t
*this = malloc_thing(private_authenticator_t
);
390 /* Public functions */
391 this->public.destroy
= (void(*)(authenticator_t
*))destroy
;
392 this->public.verify_auth_data
= (status_t (*) (authenticator_t
*,auth_payload_t
*, chunk_t
,chunk_t
,id_payload_t
*,bool)) verify_auth_data
;
393 this->public.compute_auth_data
= (status_t (*) (authenticator_t
*,auth_payload_t
**, chunk_t
,chunk_t
,id_payload_t
*,bool)) compute_auth_data
;
395 /* private functions */
396 this->allocate_octets
= allocate_octets
;
397 this->build_preshared_secret_signature
= build_preshared_secret_signature
;
400 this->ike_sa
= ike_sa
;
401 this->prf
= this->ike_sa
->get_prf(this->ike_sa
);
402 this->logger
= logger_manager
->get_logger(logger_manager
, IKE_SA
);
404 return &(this->public);