- forgot to add
[strongswan.git] / Source / charon / sa / authenticator.c
1 /**
2 * @file authenticator.c
3 *
4 * @brief Implementation of authenticator.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
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>.
16 *
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
20 * for more details.
21 */
22
23 #include "authenticator.h"
24
25 #include <utils/allocator.h>
26
27 typedef struct private_authenticator_t private_authenticator_t;
28
29 /**
30 * Private data of an authenticator_t object.
31 */
32 struct private_authenticator_t {
33
34 /**
35 * Public interface.
36 */
37 authenticator_t public;
38
39 /**
40 * IKE_SA.
41 */
42 protected_ike_sa_t *ike_sa;
43
44 /**
45 * A logger for.
46 *
47 * Using logger of IKE_SA.
48 */
49 logger_t *logger;
50
51 /**
52 * TODO
53 */
54 chunk_t (*allocate_octets) (private_authenticator_t *this,chunk_t last_message, chunk_t other_nonce,identification_t *my_id);
55
56 chunk_t (*allocate_auth_data_with_preshared_secret) (private_authenticator_t *this,chunk_t octets,chunk_t preshared_secret);
57 };
58
59 /**
60 * Implementation of authenticator_t.private_authenticator_t.
61 */
62 static chunk_t allocate_octets(private_authenticator_t *this,chunk_t last_message, chunk_t other_nonce,identification_t *my_id)
63 {
64 chunk_t id_chunk = my_id->get_encoding(my_id);
65 u_int8_t id_with_header[4 + id_chunk.len];
66 chunk_t id_with_header_chunk;
67 chunk_t octets;
68 u_int8_t *current_pos;
69 prf_t *prf;
70
71 id_with_header[0] = my_id->get_type(my_id);
72 id_with_header[1] = 0x00;
73 id_with_header[2] = 0x00;
74 id_with_header[3] = 0x00;
75 memcpy(id_with_header + 4,id_chunk.ptr,id_chunk.len);
76 id_with_header_chunk.ptr = id_with_header;
77 id_with_header_chunk.len = sizeof(id_with_header);
78
79 prf = this->ike_sa->get_prf(this->ike_sa);
80
81 prf->set_key(prf,this->ike_sa->get_key_pr(this->ike_sa));
82
83
84 /* 4 bytes are id type and reserved fields of id payload */
85 octets.len = last_message.len + other_nonce.len + prf->get_block_size(prf);
86 octets.ptr = allocator_alloc(octets.len);
87 current_pos = octets.ptr;
88 memcpy(current_pos,last_message.ptr,last_message.len);
89 current_pos += last_message.len;
90 memcpy(current_pos,other_nonce.ptr,other_nonce.len);
91 current_pos += other_nonce.len;
92 prf->get_bytes(prf,id_with_header_chunk,current_pos);
93
94 this->logger->log_chunk(this->logger,RAW | MORE, "Octets (Mesage + Nonce + prf(Sk_px,Idx)",&octets);
95 return octets;
96 }
97
98 /**
99 * Implementation of authenticator_t.allocate_auth_data_with_preshared_secret.
100 */
101 static chunk_t allocate_auth_data_with_preshared_secret (private_authenticator_t *this,chunk_t octets,chunk_t preshared_secret)
102 {
103 prf_t *prf = this->ike_sa->get_prf(this->ike_sa);
104 chunk_t auth_data;
105 chunk_t key_pad;
106 chunk_t key;
107
108 key_pad.ptr = "Key Pad for IKEv2";
109 key_pad.len = strlen(key_pad.ptr);
110
111 prf->set_key(prf,preshared_secret);
112 prf->allocate_bytes(prf,key_pad,&key);
113 prf->set_key(prf,key);
114 allocator_free_chunk(&key);
115 prf->allocate_bytes(prf,octets,&auth_data);
116 this->logger->log_chunk(this->logger,RAW | MORE, "Authenticated data",&auth_data);
117
118 return auth_data;
119 }
120
121
122 /**
123 * Implementation of authenticator_t.verify_authentication.
124 */
125 static status_t verify_authentication (private_authenticator_t *this,auth_method_t auth_method, chunk_t auth_data, chunk_t last_message, chunk_t other_nonce,identification_t *my_id,bool *verified)
126 {
127 switch(auth_method)
128 {
129 case SHARED_KEY_MESSAGE_INTEGRITY_CODE:
130 {
131
132 chunk_t preshared_secret;
133
134 preshared_secret.ptr = "secret";
135 preshared_secret.len = strlen(preshared_secret.ptr);
136
137 chunk_t octets = this->allocate_octets(this,last_message, other_nonce,my_id);
138 chunk_t my_auth_data = this->allocate_auth_data_with_preshared_secret(this,octets,preshared_secret);
139
140 allocator_free_chunk(&octets);
141
142 if (auth_data.len != my_auth_data.len)
143 {
144 *verified = FALSE;
145 allocator_free_chunk(&my_auth_data);
146 return SUCCESS;
147 }
148 if (memcmp(auth_data.ptr,my_auth_data.ptr,my_auth_data.len) == 0)
149 {
150 *verified = TRUE;
151 }
152 else
153 {
154 *verified = FALSE;
155 }
156 allocator_free_chunk(&my_auth_data);
157 return SUCCESS;
158 }
159 default:
160 {
161 return NOT_SUPPORTED;
162 }
163 }
164 }
165
166 /**
167 * Implementation of authenticator_t.allocate_auth_data.
168 */
169 static status_t allocate_auth_data (private_authenticator_t *this,auth_method_t auth_method,chunk_t last_message, chunk_t other_nonce,identification_t *my_id,chunk_t *auth_data)
170 {
171 switch(auth_method)
172 {
173 case SHARED_KEY_MESSAGE_INTEGRITY_CODE:
174 {
175 chunk_t preshared_secret;
176
177 preshared_secret.ptr = "secret";
178 preshared_secret.len = strlen(preshared_secret.ptr);
179
180 chunk_t octets = this->allocate_octets(this,last_message, other_nonce,my_id);
181 chunk_t my_auth_data = allocate_auth_data_with_preshared_secret(this,octets,preshared_secret);
182
183 allocator_free_chunk(&octets);
184
185 *auth_data = my_auth_data;
186
187 return SUCCESS;
188 }
189 default:
190 {
191 return NOT_SUPPORTED;
192 }
193 }
194 }
195
196 /**
197 * Implementation of authenticator_t.destroy.
198 */
199 static void destroy (private_authenticator_t *this)
200 {
201 allocator_free(this);
202 }
203
204 /*
205 * Described in header.
206 */
207 authenticator_t *authenticator_create(protected_ike_sa_t *ike_sa)
208 {
209 private_authenticator_t *this = allocator_alloc_thing(private_authenticator_t);
210
211 /* Public functions */
212 this->public.destroy = (void(*)(authenticator_t*))destroy;
213 this->public.verify_authentication = (status_t (*) (authenticator_t *,auth_method_t , chunk_t , chunk_t , chunk_t ,identification_t *,bool *) )verify_authentication;
214 this->public.allocate_auth_data = (status_t (*) (authenticator_t *,auth_method_t ,chunk_t , chunk_t ,identification_t *,chunk_t *)) allocate_auth_data;
215
216 /* private functions */
217 this->allocate_octets = allocate_octets;
218 this->allocate_auth_data_with_preshared_secret = allocate_auth_data_with_preshared_secret;
219
220 /* private data */
221 this->ike_sa = ike_sa;
222 this->logger = this->ike_sa->get_logger(this->ike_sa);
223
224 return &(this->public);
225 }