File: | src/sbin/isakmpd/ike_auth.c |
Warning: | line 980, column 11 Result of 'calloc' is converted to a pointer of type 'u_int8_t', which is incompatible with sizeof operand type 'char' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: ike_auth.c,v 1.118 2020/07/07 17:33:40 tobhe Exp $ */ |
2 | /* $EOM: ike_auth.c,v 1.59 2000/11/21 00:21:31 angelos Exp $ */ |
3 | |
4 | /* |
5 | * Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist. All rights reserved. |
6 | * Copyright (c) 1999 Niels Provos. All rights reserved. |
7 | * Copyright (c) 1999 Angelos D. Keromytis. All rights reserved. |
8 | * Copyright (c) 2000, 2001, 2003 Håkan Olsson. All rights reserved. |
9 | * |
10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions |
12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. |
18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | */ |
30 | |
31 | /* |
32 | * This code was written under funding by Ericsson Radio Systems. |
33 | */ |
34 | |
35 | #include <sys/types.h> |
36 | #include <sys/stat.h> |
37 | #include <netinet/in.h> |
38 | #include <arpa/inet.h> |
39 | |
40 | #include <errno(*__errno()).h> |
41 | #include <fcntl.h> |
42 | #include <stdlib.h> |
43 | #include <string.h> |
44 | #include <unistd.h> |
45 | #include <regex.h> |
46 | #include <keynote.h> |
47 | #include <policy.h> |
48 | |
49 | #include "cert.h" |
50 | #include "conf.h" |
51 | #include "constants.h" |
52 | #if defined (USE_DNSSEC) |
53 | #include "dnssec.h" |
54 | #endif |
55 | #include "exchange.h" |
56 | #include "hash.h" |
57 | #include "ike_auth.h" |
58 | #include "ipsec.h" |
59 | #include "ipsec_doi.h" |
60 | #include "libcrypto.h" |
61 | #include "log.h" |
62 | #include "message.h" |
63 | #include "monitor.h" |
64 | #include "prf.h" |
65 | #include "transport.h" |
66 | #include "util.h" |
67 | #include "key.h" |
68 | #include "x509.h" |
69 | |
70 | #ifdef notyet |
71 | static u_int8_t *enc_gen_skeyid(struct exchange *, size_t *); |
72 | #endif |
73 | static u_int8_t *pre_shared_gen_skeyid(struct exchange *, size_t *); |
74 | |
75 | static int pre_shared_decode_hash(struct message *); |
76 | static int pre_shared_encode_hash(struct message *); |
77 | |
78 | static u_int8_t *sig_gen_skeyid(struct exchange *, size_t *); |
79 | static int rsa_sig_decode_hash(struct message *); |
80 | static int rsa_sig_encode_hash(struct message *); |
81 | |
82 | static int get_raw_key_from_file(int, u_int8_t *, size_t, RSA **); |
83 | |
84 | static int ike_auth_hash(struct exchange *, u_int8_t *); |
85 | |
86 | static struct ike_auth ike_auth[] = { |
87 | { |
88 | IKE_AUTH_PRE_SHARED1, pre_shared_gen_skeyid, |
89 | pre_shared_decode_hash, |
90 | pre_shared_encode_hash |
91 | }, |
92 | #ifdef notdef |
93 | { |
94 | IKE_AUTH_DSS2, sig_gen_skeyid, |
95 | pre_shared_decode_hash, |
96 | pre_shared_encode_hash |
97 | }, |
98 | #endif |
99 | { |
100 | IKE_AUTH_RSA_SIG3, sig_gen_skeyid, |
101 | rsa_sig_decode_hash, |
102 | rsa_sig_encode_hash |
103 | }, |
104 | #ifdef notdef |
105 | { |
106 | IKE_AUTH_RSA_ENC4, enc_gen_skeyid, |
107 | pre_shared_decode_hash, |
108 | pre_shared_encode_hash |
109 | }, |
110 | { |
111 | IKE_AUTH_RSA_ENC_REV5, enc_gen_skeyid, |
112 | pre_shared_decode_hash, |
113 | pre_shared_encode_hash |
114 | }, |
115 | #endif |
116 | }; |
117 | |
118 | struct ike_auth * |
119 | ike_auth_get(u_int16_t id) |
120 | { |
121 | size_t i; |
122 | |
123 | for (i = 0; i < sizeof ike_auth / sizeof ike_auth[0]; i++) |
124 | if (id == ike_auth[i].id) |
125 | return &ike_auth[i]; |
126 | return 0; |
127 | } |
128 | |
129 | /* |
130 | * Find and decode the configured key (pre-shared or public) for the |
131 | * peer denoted by ID. Stash the len in KEYLEN. |
132 | */ |
133 | static void * |
134 | ike_auth_get_key(int type, char *id, char *local_id, size_t *keylen) |
135 | { |
136 | char *key, *buf; |
137 | char *keyfile, *privkeyfile; |
138 | FILE *keyfp; |
139 | RSA *rsakey; |
140 | size_t fsize, pkflen; |
141 | int fd; |
142 | |
143 | switch (type) { |
144 | case IKE_AUTH_PRE_SHARED1: |
145 | /* Get the pre-shared key for our peer. */ |
146 | key = conf_get_str(id, "Authentication"); |
147 | if (!key && local_id) |
148 | key = conf_get_str(local_id, "Authentication"); |
149 | |
150 | if (!key) { |
151 | log_print("ike_auth_get_key: " |
152 | "no key found for peer \"%s\" or local ID \"%s\"", |
153 | id, local_id ? local_id : "<none>"); |
154 | return 0; |
155 | } |
156 | /* If the key starts with 0x it is in hex format. */ |
157 | if (strncasecmp(key, "0x", 2) == 0) { |
158 | *keylen = (strlen(key) - 1) / 2; |
159 | buf = malloc(*keylen); |
160 | if (!buf) { |
161 | log_error("ike_auth_get_key: malloc (%lu) " |
162 | "failed", (unsigned long)*keylen); |
163 | return 0; |
164 | } |
165 | if (hex2raw(key + 2, (unsigned char *)buf, *keylen)) { |
166 | free(buf); |
167 | log_print("ike_auth_get_key: invalid hex key " |
168 | "%s", key); |
169 | return 0; |
170 | } |
171 | key = buf; |
172 | } else { |
173 | buf = key; |
174 | key = strdup(buf); |
175 | if (!key) { |
176 | log_error("ike_auth_get_key: strdup() failed"); |
177 | return 0; |
178 | } |
179 | *keylen = strlen(key); |
180 | } |
181 | break; |
182 | |
183 | case IKE_AUTH_RSA_SIG3: |
184 | if (local_id && (keyfile = conf_get_str("KeyNote", |
185 | "Credential-directory")) != 0) { |
186 | struct stat sb; |
187 | struct keynote_deckey dc; |
188 | char *privkeyfile, *buf2; |
189 | size_t size; |
190 | |
191 | if (asprintf(&privkeyfile, "%s/%s/%s", keyfile, |
192 | local_id, PRIVATE_KEY_FILE"private_key") == -1) { |
193 | log_print("ike_auth_get_key: failed to asprintf()"); |
194 | return 0; |
195 | } |
196 | keyfile = privkeyfile; |
197 | |
198 | fd = monitor_open(keyfile, O_RDONLY0x0000, 0); |
199 | if (fd < 0) { |
200 | free(keyfile); |
201 | goto ignorekeynote; |
202 | } |
203 | |
204 | if (fstat(fd, &sb) == -1) { |
205 | log_print("ike_auth_get_key: fstat failed"); |
206 | free(keyfile); |
207 | close(fd); |
208 | return 0; |
209 | } |
210 | size = (size_t)sb.st_size; |
211 | |
212 | buf = calloc(size + 1, sizeof(char)); |
213 | if (!buf) { |
214 | log_print("ike_auth_get_key: failed allocating" |
215 | " %lu bytes", (unsigned long)size + 1); |
216 | free(keyfile); |
217 | close(fd); |
218 | return 0; |
219 | } |
220 | if (read(fd, buf, size) != (ssize_t)size) { |
221 | free(buf); |
222 | log_print("ike_auth_get_key: " |
223 | "failed reading %lu bytes from \"%s\"", |
224 | (unsigned long)size, keyfile); |
225 | free(keyfile); |
226 | close(fd); |
227 | return 0; |
228 | } |
229 | close(fd); |
230 | |
231 | /* Parse private key string */ |
232 | buf2 = kn_get_string(buf); |
233 | free(buf); |
234 | |
235 | if (!buf2 || kn_decode_key(&dc, buf2, |
236 | KEYNOTE_PRIVATE_KEY1) == -1) { |
237 | free(buf2); |
238 | log_print("ike_auth_get_key: failed decoding " |
239 | "key in \"%s\"", keyfile); |
240 | free(keyfile); |
241 | return 0; |
242 | } |
243 | free(buf2); |
244 | |
245 | if (dc.dec_algorithm != KEYNOTE_ALGORITHM_RSA6) { |
246 | log_print("ike_auth_get_key: wrong algorithm " |
247 | "type %d in \"%s\"", dc.dec_algorithm, |
248 | keyfile); |
249 | free(keyfile); |
250 | kn_free_key(&dc); |
251 | return 0; |
252 | } |
253 | free(keyfile); |
254 | return dc.dec_key; |
255 | } |
256 | ignorekeynote: |
257 | /* Otherwise, try X.509 */ |
258 | |
259 | privkeyfile = keyfile = NULL((void*)0); |
260 | fd = -1; |
261 | |
262 | if (local_id) { |
263 | /* Look in Private-key-directory. */ |
264 | keyfile = conf_get_str("X509-certificates", |
265 | "Private-key-directory"); |
266 | pkflen = strlen(keyfile) + strlen(local_id) + sizeof "/"; |
267 | privkeyfile = calloc(pkflen, sizeof(char)); |
268 | if (!privkeyfile) { |
269 | log_print("ike_auth_get_key: failed to " |
270 | "allocate %lu bytes", (unsigned long)pkflen); |
271 | return 0; |
272 | } |
273 | |
274 | snprintf(privkeyfile, pkflen, "%s/%s", keyfile, |
275 | local_id); |
276 | keyfile = privkeyfile; |
277 | |
278 | fd = monitor_open(keyfile, O_RDONLY0x0000, 0); |
279 | if (fd == -1 && errno(*__errno()) != ENOENT2) { |
280 | log_print("ike_auth_get_key: failed opening " |
281 | "\"%s\"", keyfile); |
282 | free(privkeyfile); |
283 | privkeyfile = NULL((void*)0); |
284 | keyfile = NULL((void*)0); |
285 | } |
286 | } |
287 | |
288 | if (fd == -1) { |
289 | /* No key found, try default key. */ |
290 | keyfile = conf_get_str("X509-certificates", |
291 | "Private-key"); |
292 | |
293 | fd = monitor_open(keyfile, O_RDONLY0x0000, 0); |
294 | if (fd == -1) { |
295 | log_print("ike_auth_get_key: failed opening " |
296 | "\"%s\"", keyfile); |
297 | return 0; |
298 | } |
299 | } |
300 | |
301 | if (check_file_secrecy_fd(fd, keyfile, &fsize)) { |
302 | free(privkeyfile); |
303 | close(fd); |
304 | return 0; |
305 | } |
306 | |
307 | if ((keyfp = fdopen(fd, "r")) == NULL((void*)0)) { |
308 | log_print("ike_auth_get_key: fdopen failed"); |
309 | free(privkeyfile); |
310 | close(fd); |
311 | return 0; |
312 | } |
313 | #if SSLEAY_VERSION_NUMBER0x20000000L >= 0x00904100L |
314 | rsakey = PEM_read_RSAPrivateKey(keyfp, NULL((void*)0), NULL((void*)0), NULL((void*)0)); |
315 | #else |
316 | rsakey = PEM_read_RSAPrivateKey(keyfp, NULL((void*)0), NULL((void*)0)); |
317 | #endif |
318 | fclose(keyfp); |
319 | |
320 | free(privkeyfile); |
321 | |
322 | if (!rsakey) { |
323 | log_print("ike_auth_get_key: " |
324 | "PEM_read_bio_RSAPrivateKey failed"); |
325 | return 0; |
326 | } |
327 | return rsakey; |
328 | |
329 | default: |
330 | log_print("ike_auth_get_key: unknown key type %d", type); |
331 | return 0; |
332 | } |
333 | |
334 | return key; |
335 | } |
336 | |
337 | static u_int8_t * |
338 | pre_shared_gen_skeyid(struct exchange *exchange, size_t *sz) |
339 | { |
340 | struct prf *prf; |
341 | struct ipsec_exch *ie = exchange->data; |
342 | u_int8_t *skeyid, *buf = 0; |
343 | unsigned char *key; |
344 | size_t keylen; |
345 | |
346 | /* |
347 | * If we're the responder and have the initiator's ID (which is the |
348 | * case in Aggressive mode), try to find the preshared key in the |
349 | * section of the initiator's Phase 1 ID. This allows us to do |
350 | * mobile user support with preshared keys. |
351 | */ |
352 | if (!exchange->initiator && exchange->id_i) { |
353 | switch (exchange->id_i[0]) { |
354 | case IPSEC_ID_IPV4_ADDR1: |
355 | case IPSEC_ID_IPV6_ADDR5: |
356 | util_ntoa((char **) &buf, |
357 | exchange->id_i[0] == IPSEC_ID_IPV4_ADDR1 ? AF_INET2 : |
358 | AF_INET624, exchange->id_i + ISAKMP_ID_DATA_OFF8 - |
359 | ISAKMP_GEN_SZ4); |
360 | if (!buf) |
361 | return 0; |
362 | break; |
363 | |
364 | case IPSEC_ID_FQDN2: |
365 | case IPSEC_ID_USER_FQDN3: |
366 | buf = calloc(exchange->id_i_len - ISAKMP_ID_DATA_OFF8 + |
367 | ISAKMP_GEN_SZ4 + 1, sizeof(char)); |
368 | if (!buf) { |
369 | log_print("pre_shared_gen_skeyid: malloc (%lu" |
370 | ") failed", |
371 | (unsigned long)exchange->id_i_len - |
372 | ISAKMP_ID_DATA_OFF8 + ISAKMP_GEN_SZ4 + 1); |
373 | return 0; |
374 | } |
375 | memcpy(buf, |
376 | exchange->id_i + ISAKMP_ID_DATA_OFF8 - |
377 | ISAKMP_GEN_SZ4, |
378 | exchange->id_i_len - ISAKMP_ID_DATA_OFF8 + |
379 | ISAKMP_GEN_SZ4); |
380 | break; |
381 | |
382 | /* XXX Support more ID types ? */ |
383 | default: |
384 | break; |
385 | } |
386 | } |
387 | /* |
388 | * Get the pre-shared key for our peer. This will work even if the key |
389 | * has been passed to us through a mechanism like PFKEYv2. |
390 | */ |
391 | key = ike_auth_get_key(IKE_AUTH_PRE_SHARED1, exchange->name, |
392 | (char *)buf, &keylen); |
393 | free(buf); |
394 | |
395 | /* Fail if no key could be found. */ |
396 | if (!key) |
397 | return 0; |
398 | |
399 | /* Store the secret key for later policy processing. */ |
400 | exchange->recv_key = calloc(keylen + 1, sizeof(char)); |
401 | exchange->recv_keytype = ISAKMP_KEY_PASSPHRASE1; |
402 | if (!exchange->recv_key) { |
403 | log_error("pre_shared_gen_skeyid: malloc (%lu) failed", |
404 | (unsigned long)keylen); |
405 | free(key); |
406 | return 0; |
407 | } |
408 | memcpy(exchange->recv_key, key, keylen); |
409 | exchange->recv_certtype = ISAKMP_CERTENC_NONE0; |
410 | free(key); |
411 | |
412 | prf = prf_alloc(ie->prf_type, ie->hash->type, exchange->recv_key, |
413 | keylen); |
414 | if (!prf) |
415 | return 0; |
416 | |
417 | *sz = prf->blocksize; |
418 | skeyid = malloc(*sz); |
419 | if (!skeyid) { |
420 | log_error("pre_shared_gen_skeyid: malloc (%lu) failed", |
421 | (unsigned long)*sz); |
422 | prf_free(prf); |
423 | return 0; |
424 | } |
425 | prf->Init(prf->prfctx); |
426 | prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len); |
427 | prf->Update(prf->prfctx, exchange->nonce_r, exchange->nonce_r_len); |
428 | prf->Final(skeyid, prf->prfctx); |
429 | prf_free(prf); |
430 | return skeyid; |
431 | } |
432 | |
433 | /* Both DSS & RSA signature authentication use this algorithm. */ |
434 | static u_int8_t * |
435 | sig_gen_skeyid(struct exchange *exchange, size_t *sz) |
436 | { |
437 | struct prf *prf; |
438 | struct ipsec_exch *ie = exchange->data; |
439 | u_int8_t *skeyid; |
440 | unsigned char *key; |
441 | |
442 | key = malloc(exchange->nonce_i_len + exchange->nonce_r_len); |
443 | if (!key) |
444 | return 0; |
445 | memcpy(key, exchange->nonce_i, exchange->nonce_i_len); |
446 | memcpy(key + exchange->nonce_i_len, exchange->nonce_r, |
447 | exchange->nonce_r_len); |
448 | |
449 | LOG_DBG((LOG_NEGOTIATION, 80, "sig_gen_skeyid: PRF type %d, hash %d",log_debug (LOG_NEGOTIATION, 80, "sig_gen_skeyid: PRF type %d, hash %d" , ie->prf_type, ie->hash->type) |
450 | ie->prf_type, ie->hash->type))log_debug (LOG_NEGOTIATION, 80, "sig_gen_skeyid: PRF type %d, hash %d" , ie->prf_type, ie->hash->type); |
451 | LOG_DBG_BUF((LOG_NEGOTIATION, 80,log_debug_buf (LOG_NEGOTIATION, 80, "sig_gen_skeyid: SKEYID initialized with" , (u_int8_t *)key, exchange->nonce_i_len + exchange->nonce_r_len ) |
452 | "sig_gen_skeyid: SKEYID initialized with",log_debug_buf (LOG_NEGOTIATION, 80, "sig_gen_skeyid: SKEYID initialized with" , (u_int8_t *)key, exchange->nonce_i_len + exchange->nonce_r_len ) |
453 | (u_int8_t *)key, exchange->nonce_i_len + exchange->nonce_r_len))log_debug_buf (LOG_NEGOTIATION, 80, "sig_gen_skeyid: SKEYID initialized with" , (u_int8_t *)key, exchange->nonce_i_len + exchange->nonce_r_len ); |
454 | |
455 | prf = prf_alloc(ie->prf_type, ie->hash->type, key, |
456 | exchange->nonce_i_len + exchange->nonce_r_len); |
457 | free(key); |
458 | if (!prf) |
459 | return 0; |
460 | |
461 | *sz = prf->blocksize; |
462 | skeyid = malloc(*sz); |
463 | if (!skeyid) { |
464 | log_error("sig_gen_skeyid: malloc (%lu) failed", |
465 | (unsigned long)*sz); |
466 | prf_free(prf); |
467 | return 0; |
468 | } |
469 | LOG_DBG((LOG_NEGOTIATION, 80, "sig_gen_skeyid: g^xy length %lu",log_debug (LOG_NEGOTIATION, 80, "sig_gen_skeyid: g^xy length %lu" , (unsigned long)ie->g_xy_len) |
470 | (unsigned long)ie->g_xy_len))log_debug (LOG_NEGOTIATION, 80, "sig_gen_skeyid: g^xy length %lu" , (unsigned long)ie->g_xy_len); |
471 | LOG_DBG_BUF((LOG_NEGOTIATION, 80,log_debug_buf (LOG_NEGOTIATION, 80, "sig_gen_skeyid: SKEYID fed with g^xy" , ie->g_xy, ie->g_xy_len) |
472 | "sig_gen_skeyid: SKEYID fed with g^xy", ie->g_xy, ie->g_xy_len))log_debug_buf (LOG_NEGOTIATION, 80, "sig_gen_skeyid: SKEYID fed with g^xy" , ie->g_xy, ie->g_xy_len); |
473 | |
474 | prf->Init(prf->prfctx); |
475 | prf->Update(prf->prfctx, ie->g_xy, ie->g_xy_len); |
476 | prf->Final(skeyid, prf->prfctx); |
477 | prf_free(prf); |
478 | return skeyid; |
479 | } |
480 | |
481 | #ifdef notdef |
482 | /* |
483 | * Both standard and revised RSA encryption authentication use this SKEYID |
484 | * computation. |
485 | */ |
486 | static u_int8_t * |
487 | enc_gen_skeyid(struct exchange *exchange, size_t *sz) |
488 | { |
489 | struct prf *prf; |
490 | struct ipsec_exch *ie = exchange->data; |
491 | struct hash *hash = ie->hash; |
492 | u_int8_t *skeyid; |
493 | |
494 | hash->Init(hash->ctx); |
495 | hash->Update(hash->ctx, exchange->nonce_i, exchange->nonce_i_len); |
496 | hash->Update(hash->ctx, exchange->nonce_r, exchange->nonce_r_len); |
497 | hash->Final(hash->digest, hash->ctx); |
498 | prf = prf_alloc(ie->prf_type, hash->type, hash->digest, *sz); |
499 | if (!prf) |
500 | return 0; |
501 | |
502 | *sz = prf->blocksize; |
503 | skeyid = malloc(*sz); |
504 | if (!skeyid) { |
505 | log_error("enc_gen_skeyid: malloc (%d) failed", *sz); |
506 | prf_free(prf); |
507 | return 0; |
508 | } |
509 | prf->Init(prf->prfctx); |
510 | prf->Update(prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN(8 + 8)); |
511 | prf->Final(skeyid, prf->prfctx); |
512 | prf_free(prf); |
513 | return skeyid; |
514 | } |
515 | #endif /* notdef */ |
516 | |
517 | static int |
518 | pre_shared_decode_hash(struct message *msg) |
519 | { |
520 | struct exchange *exchange = msg->exchange; |
521 | struct ipsec_exch *ie = exchange->data; |
522 | struct payload *payload; |
523 | size_t hashsize = ie->hash->hashsize; |
524 | char header[80]; |
525 | int initiator = exchange->initiator; |
526 | u_int8_t **hash_p; |
527 | |
528 | /* Choose the right fields to fill-in. */ |
529 | hash_p = initiator ? &ie->hash_r : &ie->hash_i; |
530 | |
531 | payload = payload_first(msg, ISAKMP_PAYLOAD_HASH8); |
532 | if (!payload) { |
533 | log_print("pre_shared_decode_hash: no HASH payload found"); |
534 | return -1; |
535 | } |
536 | /* Check that the hash is of the correct size. */ |
537 | if (GET_ISAKMP_GEN_LENGTH(payload->p)field_get_num (isakmp_gen_fld + 2, payload->p) - ISAKMP_GEN_SZ4 != hashsize) |
538 | return -1; |
539 | |
540 | /* XXX Need this hash be in the SA? */ |
541 | *hash_p = malloc(hashsize); |
542 | if (!*hash_p) { |
543 | log_error("pre_shared_decode_hash: malloc (%lu) failed", |
544 | (unsigned long)hashsize); |
545 | return -1; |
546 | } |
547 | memcpy(*hash_p, payload->p + ISAKMP_HASH_DATA_OFF4, hashsize); |
548 | snprintf(header, sizeof header, "pre_shared_decode_hash: HASH_%c", |
549 | initiator ? 'R' : 'I'); |
550 | LOG_DBG_BUF((LOG_MISC, 80, header, *hash_p, hashsize))log_debug_buf (LOG_MISC, 80, header, *hash_p, hashsize); |
551 | |
552 | payload->flags |= PL_MARK1; |
553 | return 0; |
554 | } |
555 | |
556 | /* Decrypt the HASH in SIG, we already need a parsed ID payload. */ |
557 | static int |
558 | rsa_sig_decode_hash(struct message *msg) |
559 | { |
560 | struct cert_handler *handler; |
561 | struct exchange *exchange = msg->exchange; |
562 | struct ipsec_exch *ie = exchange->data; |
563 | struct payload *p; |
564 | void *cert = 0; |
565 | u_int8_t *rawcert = 0, **hash_p, **id_cert, *id; |
566 | u_int32_t rawcertlen, *id_cert_len; |
567 | RSA *key = 0; |
568 | size_t hashsize = ie->hash->hashsize, id_len; |
569 | char header[80]; |
570 | int len, initiator = exchange->initiator; |
571 | int found = 0, n, i, id_found; |
572 | #if defined (USE_DNSSEC) |
573 | u_int8_t *rawkey = 0; |
574 | u_int32_t rawkeylen; |
575 | #endif |
576 | |
577 | /* Choose the right fields to fill-in. */ |
578 | hash_p = initiator ? &ie->hash_r : &ie->hash_i; |
579 | id = initiator ? exchange->id_r : exchange->id_i; |
580 | id_len = initiator ? exchange->id_r_len : exchange->id_i_len; |
581 | |
582 | if (!id || id_len == 0) { |
583 | log_print("rsa_sig_decode_hash: ID is missing"); |
584 | return -1; |
585 | } |
586 | /* |
587 | * XXX Assume we should use the same kind of certification as the |
588 | * remote... moreover, just use the first CERT payload to decide what |
589 | * to use. |
590 | */ |
591 | p = payload_first(msg, ISAKMP_PAYLOAD_CERT6); |
592 | if (!p) |
593 | handler = cert_get(ISAKMP_CERTENC_KEYNOTE11); |
594 | else |
595 | handler = cert_get(GET_ISAKMP_CERT_ENCODING(p->p)field_get_num (isakmp_cert_fld + 0, p->p)); |
596 | if (!handler) { |
597 | log_print("rsa_sig_decode_hash: cert_get (%d) failed", |
598 | p ? GET_ISAKMP_CERT_ENCODING(p->p)field_get_num (isakmp_cert_fld + 0, p->p) : -1); |
599 | return -1; |
600 | } |
601 | /* |
602 | * We need the policy session initialized now, so we can add |
603 | * credentials etc. |
604 | */ |
605 | exchange->policy_id = kn_init(); |
606 | if (exchange->policy_id == -1) { |
607 | log_print("rsa_sig_decode_hash: failed to initialize policy " |
608 | "session"); |
609 | return -1; |
610 | } |
611 | |
612 | /* Obtain a certificate from our certificate storage. */ |
613 | if (handler->cert_obtain(id, id_len, 0, &rawcert, &rawcertlen)) { |
614 | if (handler->id == ISAKMP_CERTENC_X509_SIG4) { |
615 | cert = handler->cert_get(rawcert, rawcertlen); |
616 | if (!cert) |
617 | LOG_DBG((LOG_CRYPTO, 50, "rsa_sig_decode_hash:"log_debug (LOG_CRYPTO, 50, "rsa_sig_decode_hash:" " certificate malformed" ) |
618 | " certificate malformed"))log_debug (LOG_CRYPTO, 50, "rsa_sig_decode_hash:" " certificate malformed" ); |
619 | else { |
620 | if (!handler->cert_get_key(cert, &key)) { |
621 | log_print("rsa_sig_decode_hash: " |
622 | "decoding certificate failed"); |
623 | handler->cert_free(cert); |
624 | } else { |
625 | found++; |
626 | LOG_DBG((LOG_CRYPTO, 40,log_debug (LOG_CRYPTO, 40, "rsa_sig_decode_hash: using cert " "of type %d", handler->id) |
627 | "rsa_sig_decode_hash: using cert "log_debug (LOG_CRYPTO, 40, "rsa_sig_decode_hash: using cert " "of type %d", handler->id) |
628 | "of type %d", handler->id))log_debug (LOG_CRYPTO, 40, "rsa_sig_decode_hash: using cert " "of type %d", handler->id); |
629 | exchange->recv_cert = cert; |
630 | exchange->recv_certtype = handler->id; |
631 | x509_generate_kn(exchange->policy_id, |
632 | cert); |
633 | } |
634 | } |
635 | } else if (handler->id == ISAKMP_CERTENC_KEYNOTE11) |
636 | handler->cert_insert(exchange->policy_id, rawcert); |
637 | free(rawcert); |
638 | } |
639 | /* |
640 | * Walk over potential CERT payloads in this message. |
641 | * XXX I believe this is the wrong spot for this. CERTs can appear |
642 | * anytime. |
643 | */ |
644 | TAILQ_FOREACH(p, &msg->payload[ISAKMP_PAYLOAD_CERT], link)for((p) = ((&msg->payload[6])->tqh_first); (p) != ( (void*)0); (p) = ((p)->link.tqe_next)) { |
645 | p->flags |= PL_MARK1; |
646 | |
647 | /* |
648 | * When we have found a key, just walk over the rest, marking |
649 | * them. |
650 | */ |
651 | if (found) |
652 | continue; |
653 | |
654 | handler = cert_get(GET_ISAKMP_CERT_ENCODING(p->p)field_get_num (isakmp_cert_fld + 0, p->p)); |
655 | if (!handler) { |
656 | LOG_DBG((LOG_MISC, 30, "rsa_sig_decode_hash: "log_debug (LOG_MISC, 30, "rsa_sig_decode_hash: " "no handler for %s CERT encoding" , constant_name(isakmp_certenc_cst, field_get_num (isakmp_cert_fld + 0, p->p))) |
657 | "no handler for %s CERT encoding",log_debug (LOG_MISC, 30, "rsa_sig_decode_hash: " "no handler for %s CERT encoding" , constant_name(isakmp_certenc_cst, field_get_num (isakmp_cert_fld + 0, p->p))) |
658 | constant_name(isakmp_certenc_cst,log_debug (LOG_MISC, 30, "rsa_sig_decode_hash: " "no handler for %s CERT encoding" , constant_name(isakmp_certenc_cst, field_get_num (isakmp_cert_fld + 0, p->p))) |
659 | GET_ISAKMP_CERT_ENCODING(p->p))))log_debug (LOG_MISC, 30, "rsa_sig_decode_hash: " "no handler for %s CERT encoding" , constant_name(isakmp_certenc_cst, field_get_num (isakmp_cert_fld + 0, p->p))); |
660 | continue; |
661 | } |
662 | cert = handler->cert_get(p->p + ISAKMP_CERT_DATA_OFF5, |
663 | GET_ISAKMP_GEN_LENGTH(p->p)field_get_num (isakmp_gen_fld + 2, p->p) - ISAKMP_CERT_DATA_OFF5); |
664 | if (!cert) { |
665 | log_print("rsa_sig_decode_hash: " |
666 | "can not get data from CERT"); |
667 | continue; |
668 | } |
669 | if (!handler->cert_validate(cert)) { |
670 | handler->cert_free(cert); |
671 | log_print("rsa_sig_decode_hash: received CERT can't " |
672 | "be validated"); |
673 | continue; |
674 | } |
675 | if (GET_ISAKMP_CERT_ENCODING(p->p)field_get_num (isakmp_cert_fld + 0, p->p) == |
676 | ISAKMP_CERTENC_X509_SIG4) { |
677 | if (!handler->cert_get_subjects(cert, &n, &id_cert, |
678 | &id_cert_len)) { |
679 | handler->cert_free(cert); |
680 | log_print("rsa_sig_decode_hash: can not get " |
681 | "subject from CERT"); |
682 | continue; |
683 | } |
684 | id_found = 0; |
685 | for (i = 0; i < n; i++) |
686 | if (id_cert_len[i] == id_len && |
687 | id[0] == id_cert[i][0] && |
688 | memcmp(id + 4, id_cert[i] + 4, id_len - 4) |
689 | == 0) { |
690 | id_found++; |
691 | break; |
692 | } |
693 | if (!id_found) { |
694 | handler->cert_free(cert); |
695 | log_print("rsa_sig_decode_hash: no CERT " |
696 | "subject match the ID"); |
697 | free(id_cert); |
698 | continue; |
699 | } |
700 | cert_free_subjects(n, id_cert, id_cert_len); |
701 | } |
702 | if (!handler->cert_get_key(cert, &key)) { |
703 | handler->cert_free(cert); |
704 | log_print("rsa_sig_decode_hash: decoding payload CERT " |
705 | "failed"); |
706 | continue; |
707 | } |
708 | /* We validated the cert, cache it for later use. */ |
709 | handler->cert_insert(exchange->policy_id, cert); |
710 | |
711 | exchange->recv_cert = cert; |
712 | exchange->recv_certtype = GET_ISAKMP_CERT_ENCODING(p->p)field_get_num (isakmp_cert_fld + 0, p->p); |
713 | |
714 | if (exchange->recv_certtype == ISAKMP_CERTENC_KEYNOTE11) { |
715 | struct keynote_deckey dc; |
716 | char *pp; |
717 | |
718 | dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA6; |
719 | dc.dec_key = key; |
720 | |
721 | pp = kn_encode_key(&dc, INTERNAL_ENC_PKCS11, |
722 | ENCODING_HEX1, KEYNOTE_PUBLIC_KEY0); |
723 | if (pp == NULL((void*)0)) { |
724 | kn_free_key(&dc); |
725 | log_print("rsa_sig_decode_hash: failed to " |
726 | "ASCII-encode key"); |
727 | return -1; |
728 | } |
729 | if (asprintf(&exchange->keynote_key, "rsa-hex:%s", |
730 | pp) == -1) { |
731 | free(pp); |
732 | kn_free_key(&dc); |
733 | log_print("rsa_sig_decode_hash: failed to asprintf()"); |
734 | return -1; |
735 | } |
736 | free(pp); |
737 | } |
738 | found++; |
739 | } |
740 | |
741 | #if defined (USE_DNSSEC) |
742 | /* |
743 | * If no certificate provided a key, try to find a validated DNSSEC |
744 | * KEY. |
745 | */ |
746 | if (!found) { |
747 | rawkey = dns_get_key(IKE_AUTH_RSA_SIG3, msg, &rawkeylen); |
748 | |
749 | /* We need to convert 'void *rawkey' into 'RSA *key'. */ |
750 | if (dns_RSA_dns_to_x509(rawkey, rawkeylen, &key) == 0) |
751 | found++; |
752 | else |
753 | log_print("rsa_sig_decode_hash: KEY to RSA key " |
754 | "conversion failed"); |
755 | |
756 | free(rawkey); |
757 | } |
758 | #endif /* USE_DNSSEC */ |
759 | |
760 | /* If we still have not found a key, try to read it from a file. */ |
761 | if (!found) |
762 | if (get_raw_key_from_file(IKE_AUTH_RSA_SIG3, id, id_len, &key) |
763 | != -1) |
764 | found++; |
765 | |
766 | if (!found) { |
767 | log_print("rsa_sig_decode_hash: no public key found"); |
768 | return -1; |
769 | } |
770 | p = payload_first(msg, ISAKMP_PAYLOAD_SIG9); |
771 | if (!p) { |
772 | log_print("rsa_sig_decode_hash: missing signature payload"); |
773 | RSA_free(key); |
774 | return -1; |
775 | } |
776 | /* Check that the sig is of the correct size. */ |
777 | len = GET_ISAKMP_GEN_LENGTH(p->p)field_get_num (isakmp_gen_fld + 2, p->p) - ISAKMP_SIG_SZ4; |
778 | if (len != RSA_size(key)) { |
779 | RSA_free(key); |
780 | log_print("rsa_sig_decode_hash: " |
781 | "SIG payload length does not match public key"); |
782 | return -1; |
783 | } |
784 | *hash_p = malloc(len); |
785 | if (!*hash_p) { |
786 | RSA_free(key); |
787 | log_error("rsa_sig_decode_hash: malloc (%d) failed", len); |
788 | return -1; |
789 | } |
790 | len = RSA_public_decrypt(len, p->p + ISAKMP_SIG_DATA_OFF4, *hash_p, key, |
791 | RSA_PKCS1_PADDING1); |
792 | if (len == -1) { |
793 | RSA_free(key); |
794 | log_print("rsa_sig_decode_hash: RSA_public_decrypt () failed"); |
795 | return -1; |
796 | } |
797 | /* Store key for later use */ |
798 | exchange->recv_key = key; |
799 | exchange->recv_keytype = ISAKMP_KEY_RSA2; |
800 | |
801 | if (len != (int)hashsize) { |
802 | free(*hash_p); |
803 | *hash_p = 0; |
804 | log_print("rsa_sig_decode_hash: len %lu != hashsize %lu", |
805 | (unsigned long)len, (unsigned long)hashsize); |
806 | return -1; |
807 | } |
808 | snprintf(header, sizeof header, "rsa_sig_decode_hash: HASH_%c", |
809 | initiator ? 'R' : 'I'); |
810 | LOG_DBG_BUF((LOG_MISC, 80, header, *hash_p, hashsize))log_debug_buf (LOG_MISC, 80, header, *hash_p, hashsize); |
811 | |
812 | p->flags |= PL_MARK1; |
813 | return 0; |
814 | } |
815 | |
816 | static int |
817 | pre_shared_encode_hash(struct message *msg) |
818 | { |
819 | struct exchange *exchange = msg->exchange; |
820 | struct ipsec_exch *ie = exchange->data; |
821 | size_t hashsize = ie->hash->hashsize; |
822 | char header[80]; |
823 | int initiator = exchange->initiator; |
824 | u_int8_t *buf; |
825 | |
826 | buf = ipsec_add_hash_payload(msg, hashsize); |
827 | if (!buf) |
828 | return -1; |
829 | |
830 | if (ike_auth_hash(exchange, buf + ISAKMP_HASH_DATA_OFF4) == -1) |
831 | return -1; |
832 | |
833 | snprintf(header, sizeof header, "pre_shared_encode_hash: HASH_%c", |
834 | initiator ? 'I' : 'R'); |
835 | LOG_DBG_BUF((LOG_MISC, 80, header, buf + ISAKMP_HASH_DATA_OFF,log_debug_buf (LOG_MISC, 80, header, buf + 4, hashsize) |
836 | hashsize))log_debug_buf (LOG_MISC, 80, header, buf + 4, hashsize); |
837 | return 0; |
838 | } |
839 | |
840 | /* Encrypt the HASH into a SIG type. */ |
841 | static int |
842 | rsa_sig_encode_hash(struct message *msg) |
843 | { |
844 | struct exchange *exchange = msg->exchange; |
845 | struct ipsec_exch *ie = exchange->data; |
846 | size_t hashsize = ie->hash->hashsize, id_len; |
847 | struct cert_handler *handler; |
848 | char header[80]; |
849 | int initiator = exchange->initiator, idtype; |
850 | u_int8_t *buf, *data, *buf2, *id; |
851 | u_int32_t datalen; |
852 | int32_t sigsize; |
853 | void *sent_key; |
854 | |
855 | id = initiator ? exchange->id_i : exchange->id_r; |
856 | id_len = initiator ? exchange->id_i_len : exchange->id_r_len; |
857 | |
858 | /* We may have been provided these by the kernel */ |
859 | buf = (u_int8_t *)conf_get_str(exchange->name, "Credentials"); |
860 | if (buf && (idtype = conf_get_num(exchange->name, "Credential_Type", |
861 | -1)) != -1) { |
862 | exchange->sent_certtype = idtype; |
863 | handler = cert_get(idtype); |
864 | if (!handler) { |
865 | log_print("rsa_sig_encode_hash: cert_get (%d) failed", |
866 | idtype); |
867 | return -1; |
868 | } |
869 | exchange->sent_cert = |
870 | handler->cert_from_printable((char *)buf); |
871 | if (!exchange->sent_cert) { |
872 | log_print("rsa_sig_encode_hash: failed to retrieve " |
873 | "certificate"); |
874 | return -1; |
875 | } |
876 | handler->cert_serialize(exchange->sent_cert, &data, &datalen); |
877 | if (!data) { |
878 | log_print("rsa_sig_encode_hash: cert serialization " |
879 | "failed"); |
880 | return -1; |
881 | } |
882 | goto aftercert; /* Skip all the certificate discovery */ |
883 | } |
884 | /* XXX This needs to be configurable. */ |
885 | idtype = ISAKMP_CERTENC_KEYNOTE11; |
886 | |
887 | /* Find a certificate with subjectAltName = id. */ |
888 | handler = cert_get(idtype); |
889 | if (!handler) { |
890 | idtype = ISAKMP_CERTENC_X509_SIG4; |
891 | handler = cert_get(idtype); |
892 | if (!handler) { |
893 | log_print("rsa_sig_encode_hash: cert_get(%d) failed", |
894 | idtype); |
895 | return -1; |
896 | } |
897 | } |
898 | if (handler->cert_obtain(id, id_len, 0, &data, &datalen) == 0) { |
899 | if (idtype == ISAKMP_CERTENC_KEYNOTE11) { |
900 | idtype = ISAKMP_CERTENC_X509_SIG4; |
901 | handler = cert_get(idtype); |
902 | if (!handler) { |
903 | log_print("rsa_sig_encode_hash: cert_get(%d) " |
904 | "failed", idtype); |
905 | return -1; |
906 | } |
907 | if (handler->cert_obtain(id, id_len, 0, &data, |
908 | &datalen) == 0) { |
909 | LOG_DBG((LOG_MISC, 10, "rsa_sig_encode_hash: "log_debug (LOG_MISC, 10, "rsa_sig_encode_hash: " "no certificate to send for id %s" , ipsec_id_string(id, id_len)) |
910 | "no certificate to send for id %s",log_debug (LOG_MISC, 10, "rsa_sig_encode_hash: " "no certificate to send for id %s" , ipsec_id_string(id, id_len)) |
911 | ipsec_id_string(id, id_len)))log_debug (LOG_MISC, 10, "rsa_sig_encode_hash: " "no certificate to send for id %s" , ipsec_id_string(id, id_len)); |
912 | goto skipcert; |
913 | } |
914 | } else { |
915 | LOG_DBG((LOG_MISC, 10,log_debug (LOG_MISC, 10, "rsa_sig_encode_hash: no certificate to send" " for id %s", ipsec_id_string(id, id_len)) |
916 | "rsa_sig_encode_hash: no certificate to send"log_debug (LOG_MISC, 10, "rsa_sig_encode_hash: no certificate to send" " for id %s", ipsec_id_string(id, id_len)) |
917 | " for id %s", ipsec_id_string(id, id_len)))log_debug (LOG_MISC, 10, "rsa_sig_encode_hash: no certificate to send" " for id %s", ipsec_id_string(id, id_len)); |
918 | goto skipcert; |
919 | } |
920 | } |
921 | /* Let's store the certificate we are going to use */ |
922 | exchange->sent_certtype = idtype; |
923 | exchange->sent_cert = handler->cert_get(data, datalen); |
924 | if (!exchange->sent_cert) { |
925 | free(data); |
926 | log_print("rsa_sig_encode_hash: failed to get certificate " |
927 | "from wire encoding"); |
928 | return -1; |
929 | } |
930 | aftercert: |
931 | |
932 | buf = realloc(data, ISAKMP_CERT_SZ5 + datalen); |
933 | if (!buf) { |
934 | log_error("rsa_sig_encode_hash: realloc (%p, %d) failed", data, |
935 | ISAKMP_CERT_SZ5 + datalen); |
936 | free(data); |
937 | return -1; |
938 | } |
939 | memmove(buf + ISAKMP_CERT_SZ5, buf, datalen); |
940 | SET_ISAKMP_CERT_ENCODING(buf, idtype)field_set_num (isakmp_cert_fld + 0, buf, idtype); |
941 | if (message_add_payload(msg, ISAKMP_PAYLOAD_CERT6, buf, |
942 | ISAKMP_CERT_SZ5 + datalen, 1)) { |
943 | free(buf); |
944 | return -1; |
945 | } |
946 | skipcert: |
947 | |
948 | /* Again, we may have these from the kernel */ |
949 | buf = (u_int8_t *)conf_get_str(exchange->name, "PKAuthentication"); |
950 | if (buf) { |
951 | key_from_printable(ISAKMP_KEY_RSA2, ISAKMP_KEYTYPE_PRIVATE1, |
952 | (char *)buf, &data, &datalen); |
953 | if (!data) { |
954 | log_print("rsa_sig_encode_hash: badly formatted RSA " |
955 | "private key"); |
956 | return 0; |
957 | } |
958 | sent_key = key_internalize(ISAKMP_KEY_RSA2, |
959 | ISAKMP_KEYTYPE_PRIVATE1, data, datalen); |
960 | if (!sent_key) { |
961 | log_print("rsa_sig_encode_hash: bad RSA private key " |
962 | "from dynamic SA acquisition subsystem"); |
963 | return 0; |
964 | } |
965 | } else { |
966 | /* Try through the regular means. */ |
967 | switch (id[ISAKMP_ID_TYPE_OFF4 - ISAKMP_GEN_SZ4]) { |
968 | case IPSEC_ID_IPV4_ADDR1: |
969 | case IPSEC_ID_IPV6_ADDR5: |
970 | util_ntoa((char **)&buf2, |
971 | id[ISAKMP_ID_TYPE_OFF4 - ISAKMP_GEN_SZ4] == |
972 | IPSEC_ID_IPV4_ADDR1 ? AF_INET2 : AF_INET624, |
973 | id + ISAKMP_ID_DATA_OFF8 - ISAKMP_GEN_SZ4); |
974 | if (!buf2) |
975 | return 0; |
976 | break; |
977 | |
978 | case IPSEC_ID_FQDN2: |
979 | case IPSEC_ID_USER_FQDN3: |
980 | buf2 = calloc(id_len - ISAKMP_ID_DATA_OFF8 + |
Result of 'calloc' is converted to a pointer of type 'u_int8_t', which is incompatible with sizeof operand type 'char' | |
981 | ISAKMP_GEN_SZ4 + 1, sizeof(char)); |
982 | if (!buf2) { |
983 | log_print("rsa_sig_encode_hash: malloc (%lu) " |
984 | "failed", (unsigned long)id_len - |
985 | ISAKMP_ID_DATA_OFF8 + ISAKMP_GEN_SZ4 + 1); |
986 | return 0; |
987 | } |
988 | memcpy(buf2, id + ISAKMP_ID_DATA_OFF8 - ISAKMP_GEN_SZ4, |
989 | id_len - ISAKMP_ID_DATA_OFF8 + ISAKMP_GEN_SZ4); |
990 | break; |
991 | |
992 | /* XXX Support more ID types? */ |
993 | default: |
994 | buf2 = 0; |
995 | return 0; |
996 | } |
997 | |
998 | sent_key = ike_auth_get_key(IKE_AUTH_RSA_SIG3, exchange->name, |
999 | (char *)buf2, 0); |
1000 | free(buf2); |
1001 | |
1002 | /* Did we find a key? */ |
1003 | if (!sent_key) { |
1004 | log_print("rsa_sig_encode_hash: " |
1005 | "could not get private key"); |
1006 | return -1; |
1007 | } |
1008 | } |
1009 | |
1010 | /* Enable RSA blinding. */ |
1011 | if (RSA_blinding_on(sent_key, NULL((void*)0)) != 1) { |
1012 | log_error("rsa_sig_encode_hash: RSA_blinding_on () failed."); |
1013 | RSA_free(sent_key); |
1014 | return -1; |
1015 | } |
1016 | /* XXX hashsize is not necessarily prf->blocksize. */ |
1017 | buf = malloc(hashsize); |
1018 | if (!buf) { |
1019 | log_error("rsa_sig_encode_hash: malloc (%lu) failed", |
1020 | (unsigned long)hashsize); |
1021 | RSA_free(sent_key); |
1022 | return -1; |
1023 | } |
1024 | if (ike_auth_hash(exchange, buf) == -1) { |
1025 | free(buf); |
1026 | RSA_free(sent_key); |
1027 | return -1; |
1028 | } |
1029 | snprintf(header, sizeof header, "rsa_sig_encode_hash: HASH_%c", |
1030 | initiator ? 'I' : 'R'); |
1031 | LOG_DBG_BUF((LOG_MISC, 80, header, buf, hashsize))log_debug_buf (LOG_MISC, 80, header, buf, hashsize); |
1032 | |
1033 | data = malloc(RSA_size(sent_key)); |
1034 | if (!data) { |
1035 | log_error("rsa_sig_encode_hash: malloc (%d) failed", |
1036 | RSA_size(sent_key)); |
1037 | free(buf); |
1038 | RSA_free(sent_key); |
1039 | return -1; |
1040 | } |
1041 | sigsize = RSA_private_encrypt(hashsize, buf, data, sent_key, |
1042 | RSA_PKCS1_PADDING1); |
1043 | if (sigsize == -1) { |
1044 | log_print("rsa_sig_encode_hash: " |
1045 | "RSA_private_encrypt () failed"); |
1046 | free(data); |
1047 | free(buf); |
1048 | RSA_free(sent_key); |
1049 | return -1; |
1050 | } |
1051 | datalen = (u_int32_t) sigsize; |
1052 | |
1053 | free(buf); |
1054 | RSA_free(sent_key); |
1055 | |
1056 | buf = realloc(data, ISAKMP_SIG_SZ4 + datalen); |
1057 | if (!buf) { |
1058 | log_error("rsa_sig_encode_hash: realloc (%p, %d) failed", data, |
1059 | ISAKMP_SIG_SZ4 + datalen); |
1060 | free(data); |
1061 | return -1; |
1062 | } |
1063 | memmove(buf + ISAKMP_SIG_SZ4, buf, datalen); |
1064 | |
1065 | snprintf(header, sizeof header, "rsa_sig_encode_hash: SIG_%c", |
1066 | initiator ? 'I' : 'R'); |
1067 | LOG_DBG_BUF((LOG_MISC, 80, header, buf + ISAKMP_SIG_DATA_OFF,log_debug_buf (LOG_MISC, 80, header, buf + 4, datalen) |
1068 | datalen))log_debug_buf (LOG_MISC, 80, header, buf + 4, datalen); |
1069 | if (message_add_payload(msg, ISAKMP_PAYLOAD_SIG9, buf, |
1070 | ISAKMP_SIG_SZ4 + datalen, 1)) { |
1071 | free(buf); |
1072 | return -1; |
1073 | } |
1074 | return 0; |
1075 | } |
1076 | |
1077 | int |
1078 | ike_auth_hash(struct exchange *exchange, u_int8_t *buf) |
1079 | { |
1080 | struct ipsec_exch *ie = exchange->data; |
1081 | struct prf *prf; |
1082 | struct hash *hash = ie->hash; |
1083 | int initiator = exchange->initiator; |
1084 | u_int8_t *id; |
1085 | size_t id_len; |
1086 | |
1087 | /* Choose the right fields to fill-in. */ |
1088 | id = initiator ? exchange->id_i : exchange->id_r; |
1089 | id_len = initiator ? exchange->id_i_len : exchange->id_r_len; |
1090 | |
1091 | /* Allocate the prf and start calculating our HASH. */ |
1092 | prf = prf_alloc(ie->prf_type, hash->type, ie->skeyid, ie->skeyid_len); |
1093 | if (!prf) |
1094 | return -1; |
1095 | |
1096 | prf->Init(prf->prfctx); |
1097 | prf->Update(prf->prfctx, initiator ? ie->g_xi : ie->g_xr, ie->g_x_len); |
1098 | prf->Update(prf->prfctx, initiator ? ie->g_xr : ie->g_xi, ie->g_x_len); |
1099 | prf->Update(prf->prfctx, exchange->cookies + |
1100 | (initiator ? ISAKMP_HDR_ICOOKIE_OFF0 : ISAKMP_HDR_RCOOKIE_OFF8), |
1101 | ISAKMP_HDR_ICOOKIE_LEN8); |
1102 | prf->Update(prf->prfctx, exchange->cookies + |
1103 | (initiator ? ISAKMP_HDR_RCOOKIE_OFF8 : ISAKMP_HDR_ICOOKIE_OFF0), |
1104 | ISAKMP_HDR_ICOOKIE_LEN8); |
1105 | prf->Update(prf->prfctx, ie->sa_i_b, ie->sa_i_b_len); |
1106 | prf->Update(prf->prfctx, id, id_len); |
1107 | prf->Final(buf, prf->prfctx); |
1108 | prf_free(prf); |
1109 | return 0; |
1110 | } |
1111 | |
1112 | static int |
1113 | get_raw_key_from_file(int type, u_int8_t *id, size_t id_len, RSA **rsa) |
1114 | { |
1115 | char filename[FILENAME_MAX1024]; |
1116 | char *fstr; |
1117 | FILE *keyfp; |
1118 | |
1119 | if (type != IKE_AUTH_RSA_SIG3) { /* XXX More types? */ |
1120 | LOG_DBG((LOG_NEGOTIATION, 20, "get_raw_key_from_file: "log_debug (LOG_NEGOTIATION, 20, "get_raw_key_from_file: " "invalid auth type %d\n" , type) |
1121 | "invalid auth type %d\n", type))log_debug (LOG_NEGOTIATION, 20, "get_raw_key_from_file: " "invalid auth type %d\n" , type); |
1122 | return -1; |
1123 | } |
1124 | *rsa = 0; |
1125 | |
1126 | fstr = conf_get_str("General", "Pubkey-directory"); |
1127 | if (!fstr) |
1128 | fstr = CONF_DFLT_PUBKEY_DIR"/etc/isakmpd/" "pubkeys/"; |
1129 | |
1130 | if (snprintf(filename, sizeof filename, "%s/", fstr) > |
1131 | (int)sizeof filename - 1) |
1132 | return -1; |
1133 | |
1134 | fstr = ipsec_id_string(id, id_len); |
1135 | if (!fstr) { |
1136 | LOG_DBG((LOG_NEGOTIATION, 50, "get_raw_key_from_file: "log_debug (LOG_NEGOTIATION, 50, "get_raw_key_from_file: " "ipsec_id_string failed" ) |
1137 | "ipsec_id_string failed"))log_debug (LOG_NEGOTIATION, 50, "get_raw_key_from_file: " "ipsec_id_string failed" ); |
1138 | return -1; |
1139 | } |
1140 | strlcat(filename, fstr, sizeof filename - strlen(filename)); |
1141 | free(fstr); |
1142 | |
1143 | /* If the file does not exist, fail silently. */ |
1144 | keyfp = monitor_fopen(filename, "r"); |
1145 | if (keyfp) { |
1146 | *rsa = PEM_read_RSA_PUBKEY(keyfp, NULL((void*)0), NULL((void*)0), NULL((void*)0)); |
1147 | if (!*rsa) { |
1148 | rewind(keyfp); |
1149 | *rsa = PEM_read_RSAPublicKey(keyfp, NULL((void*)0), NULL((void*)0), NULL((void*)0)); |
1150 | } |
1151 | if (!*rsa) |
1152 | log_print("get_raw_key_from_file: failed to get " |
1153 | "public key %s", filename); |
1154 | fclose(keyfp); |
1155 | } else if (errno(*__errno()) != ENOENT2) { |
1156 | log_error("get_raw_key_from_file: monitor_fopen " |
1157 | "(\"%s\", \"r\") failed", filename); |
1158 | return -1; |
1159 | } else |
1160 | LOG_DBG((LOG_NEGOTIATION, 50,log_debug (LOG_NEGOTIATION, 50, "get_raw_key_from_file: file %s not found" , filename) |
1161 | "get_raw_key_from_file: file %s not found", filename))log_debug (LOG_NEGOTIATION, 50, "get_raw_key_from_file: file %s not found" , filename); |
1162 | |
1163 | return (*rsa ? 0 : -1); |
1164 | } |