Bug Summary

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'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ike_auth.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sbin/isakmpd/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sbin/isakmpd -I . -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/sbin/isakmpd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/sbin/isakmpd/ike_auth.c
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
71static u_int8_t *enc_gen_skeyid(struct exchange *, size_t *);
72#endif
73static u_int8_t *pre_shared_gen_skeyid(struct exchange *, size_t *);
74
75static int pre_shared_decode_hash(struct message *);
76static int pre_shared_encode_hash(struct message *);
77
78static u_int8_t *sig_gen_skeyid(struct exchange *, size_t *);
79static int rsa_sig_decode_hash(struct message *);
80static int rsa_sig_encode_hash(struct message *);
81
82static int get_raw_key_from_file(int, u_int8_t *, size_t, RSA **);
83
84static int ike_auth_hash(struct exchange *, u_int8_t *);
85
86static 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
118struct ike_auth *
119ike_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 */
133static void *
134ike_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 }
256ignorekeynote:
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
337static u_int8_t *
338pre_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. */
434static u_int8_t *
435sig_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 */
486static u_int8_t *
487enc_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
517static int
518pre_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. */
557static int
558rsa_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
816static int
817pre_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. */
841static int
842rsa_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 }
930aftercert:
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 }
946skipcert:
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
1077int
1078ike_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
1112static int
1113get_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}