]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/oakley.c
ipsec-93.10.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / oakley.c
1 /* $NetBSD: oakley.c,v 1.9.6.2 2007/04/04 13:08:28 vanhu Exp $ */
2
3 /* Id: oakley.c,v 1.32 2006/05/26 12:19:46 manubsd Exp */
4
5 /*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include "config.h"
35
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h> /* XXX for subjectaltname */
39 #include <netinet/in.h> /* XXX for subjectaltname */
40
41 #include <openssl/pkcs7.h>
42 #include <openssl/x509.h>
43
44 #include <stdlib.h>
45 #include <stdio.h>
46 #include <string.h>
47 #include <errno.h>
48 #include <arpa/inet.h>
49 #include <TargetConditionals.h>
50
51 #if TIME_WITH_SYS_TIME
52 # include <sys/time.h>
53 # include <time.h>
54 #else
55 # if HAVE_SYS_TIME_H
56 # include <sys/time.h>
57 # else
58 # include <time.h>
59 # endif
60 #endif
61 #ifdef ENABLE_HYBRID
62 #include <resolv.h>
63 #endif
64
65 #include "var.h"
66 #include "misc.h"
67 #include "vmbuf.h"
68 #include "str2val.h"
69 #include "plog.h"
70 #include "debug.h"
71
72 #include "isakmp_var.h"
73 #include "isakmp.h"
74 #ifdef ENABLE_HYBRID
75 #include "isakmp_xauth.h"
76 #include "isakmp_cfg.h"
77 #endif
78 #include "oakley.h"
79 #include "admin.h"
80 #include "privsep.h"
81 #include "localconf.h"
82 #include "policy.h"
83 #include "handler.h"
84 #include "ipsec_doi.h"
85 #include "algorithm.h"
86 #include "dhgroup.h"
87 #include "sainfo.h"
88 #include "proposal.h"
89 #include "crypto_openssl.h"
90 #ifdef __APPLE__
91 #include "crypto_cssm.h"
92 #if HAVE_OPENDIR
93 #include "open_dir.h"
94 #endif
95 #endif
96 #include "dnssec.h"
97 #include "sockmisc.h"
98 #include "strnames.h"
99 #include "gcmalloc.h"
100 #include "rsalist.h"
101 #ifdef __APPLE__
102 #include <CoreFoundation/CoreFoundation.h>
103 #endif
104 #include "remoteconf.h"
105 #include "vpn_control.h"
106
107 #ifdef HAVE_GSSAPI
108 #include "gssapi.h"
109 #endif
110
111 #define OUTBOUND_SA 0
112 #define INBOUND_SA 1
113
114 #ifdef __APPLE__
115 #define CERT_CHECKID_FROM_PEER 0
116 #define CERT_CHECKID_FROM_RMCONFIG 1
117 #endif
118
119 #define INITDHVAL(a, s, d, t) \
120 do { \
121 vchar_t buf; \
122 buf.v = str2val((s), 16, &buf.l); \
123 memset(&a, 0, sizeof(struct dhgroup)); \
124 a.type = (t); \
125 a.prime = vdup(&buf); \
126 a.gen1 = 2; \
127 a.gen2 = 0; \
128 racoon_free(buf.v); \
129 } while(0);
130
131 struct dhgroup dh_modp768;
132 struct dhgroup dh_modp1024;
133 struct dhgroup dh_modp1536;
134 struct dhgroup dh_modp2048;
135 struct dhgroup dh_modp3072;
136 struct dhgroup dh_modp4096;
137 struct dhgroup dh_modp6144;
138 struct dhgroup dh_modp8192;
139
140
141 static int oakley_check_dh_pub __P((vchar_t *, vchar_t **));
142 static int oakley_compute_keymat_x __P((struct ph2handle *, int, int));
143 static int get_cert_fromlocal __P((struct ph1handle *, int));
144 static int get_plainrsa_fromlocal __P((struct ph1handle *, int));
145 #ifdef __APPLE__
146 static int oakley_check_certid __P((struct ph1handle *iph1, int));
147 static int oakley_check_certid_1 __P((struct ph1handle*, int, int, void*));
148 #else
149 static int oakley_check_certid __P((struct ph1handle *iph1));
150 #endif
151 static int check_typeofcertname __P((int, int));
152 static cert_t *save_certbuf __P((struct isakmp_gen *));
153 static cert_t *save_certx509 __P((X509 *));
154 static int oakley_padlen __P((int, int));
155
156 #ifdef __APPLE__
157 static int base64toCFData(vchar_t *, CFDataRef*);
158 #endif
159
160 int
161 oakley_get_defaultlifetime()
162 {
163 return OAKLEY_ATTR_SA_LD_SEC_DEFAULT;
164 }
165
166 int
167 oakley_dhinit()
168 {
169 /* set DH MODP */
170 INITDHVAL(dh_modp768, OAKLEY_PRIME_MODP768,
171 OAKLEY_ATTR_GRP_DESC_MODP768, OAKLEY_ATTR_GRP_TYPE_MODP);
172 INITDHVAL(dh_modp1024, OAKLEY_PRIME_MODP1024,
173 OAKLEY_ATTR_GRP_DESC_MODP1024, OAKLEY_ATTR_GRP_TYPE_MODP);
174 INITDHVAL(dh_modp1536, OAKLEY_PRIME_MODP1536,
175 OAKLEY_ATTR_GRP_DESC_MODP1536, OAKLEY_ATTR_GRP_TYPE_MODP);
176 INITDHVAL(dh_modp2048, OAKLEY_PRIME_MODP2048,
177 OAKLEY_ATTR_GRP_DESC_MODP2048, OAKLEY_ATTR_GRP_TYPE_MODP);
178 INITDHVAL(dh_modp3072, OAKLEY_PRIME_MODP3072,
179 OAKLEY_ATTR_GRP_DESC_MODP3072, OAKLEY_ATTR_GRP_TYPE_MODP);
180 INITDHVAL(dh_modp4096, OAKLEY_PRIME_MODP4096,
181 OAKLEY_ATTR_GRP_DESC_MODP4096, OAKLEY_ATTR_GRP_TYPE_MODP);
182 INITDHVAL(dh_modp6144, OAKLEY_PRIME_MODP6144,
183 OAKLEY_ATTR_GRP_DESC_MODP6144, OAKLEY_ATTR_GRP_TYPE_MODP);
184 INITDHVAL(dh_modp8192, OAKLEY_PRIME_MODP8192,
185 OAKLEY_ATTR_GRP_DESC_MODP8192, OAKLEY_ATTR_GRP_TYPE_MODP);
186
187 return 0;
188 }
189
190 void
191 oakley_dhgrp_free(dhgrp)
192 struct dhgroup *dhgrp;
193 {
194 if (dhgrp->prime)
195 vfree(dhgrp->prime);
196 if (dhgrp->curve_a)
197 vfree(dhgrp->curve_a);
198 if (dhgrp->curve_b)
199 vfree(dhgrp->curve_b);
200 if (dhgrp->order)
201 vfree(dhgrp->order);
202 racoon_free(dhgrp);
203 }
204
205 /*
206 * RFC2409 5
207 * The length of the Diffie-Hellman public value MUST be equal to the
208 * length of the prime modulus over which the exponentiation was
209 * performed, prepending zero bits to the value if necessary.
210 */
211 static int
212 oakley_check_dh_pub(prime, pub0)
213 vchar_t *prime, **pub0;
214 {
215 vchar_t *tmp;
216 vchar_t *pub = *pub0;
217
218 if (prime->l == pub->l)
219 return 0;
220
221 if (prime->l < pub->l) {
222 /* what should i do ? */
223 plog(LLV_ERROR, LOCATION, NULL,
224 "invalid public information was generated.\n");
225 return -1;
226 }
227
228 /* prime->l > pub->l */
229 tmp = vmalloc(prime->l);
230 if (tmp == NULL) {
231 plog(LLV_ERROR, LOCATION, NULL,
232 "failed to get DH buffer.\n");
233 return -1;
234 }
235 memcpy(tmp->v + prime->l - pub->l, pub->v, pub->l);
236
237 vfree(*pub0);
238 *pub0 = tmp;
239
240 return 0;
241 }
242
243 /*
244 * compute sharing secret of DH
245 * IN: *dh, *pub, *priv, *pub_p
246 * OUT: **gxy
247 */
248 int
249 oakley_dh_compute(dh, pub, priv, pub_p, gxy)
250 const struct dhgroup *dh;
251 vchar_t *pub, *priv, *pub_p, **gxy;
252 {
253 #ifdef ENABLE_STATS
254 struct timeval start, end;
255 #endif
256 if ((*gxy = vmalloc(dh->prime->l)) == NULL) {
257 plog(LLV_ERROR, LOCATION, NULL,
258 "failed to get DH buffer.\n");
259 return -1;
260 }
261
262 #ifdef ENABLE_STATS
263 gettimeofday(&start, NULL);
264 #endif
265 switch (dh->type) {
266 case OAKLEY_ATTR_GRP_TYPE_MODP:
267 if (eay_dh_compute(dh->prime, dh->gen1, pub, priv, pub_p, gxy) < 0) {
268 plog(LLV_ERROR, LOCATION, NULL,
269 "failed to compute dh value.\n");
270 return -1;
271 }
272 break;
273 case OAKLEY_ATTR_GRP_TYPE_ECP:
274 case OAKLEY_ATTR_GRP_TYPE_EC2N:
275 plog(LLV_ERROR, LOCATION, NULL,
276 "dh type %d isn't supported.\n", dh->type);
277 return -1;
278 default:
279 plog(LLV_ERROR, LOCATION, NULL,
280 "invalid dh type %d.\n", dh->type);
281 return -1;
282 }
283
284 #ifdef ENABLE_STATS
285 gettimeofday(&end, NULL);
286 syslog(LOG_NOTICE, "%s(%s%d): %8.6f", __func__,
287 s_attr_isakmp_group(dh->type), dh->prime->l << 3,
288 timedelta(&start, &end));
289 #endif
290
291 plog(LLV_DEBUG, LOCATION, NULL, "compute DH's shared.\n");
292 plogdump(LLV_DEBUG, (*gxy)->v, (*gxy)->l);
293
294 return 0;
295 }
296
297 /*
298 * generate values of DH
299 * IN: *dh
300 * OUT: **pub, **priv
301 */
302 int
303 oakley_dh_generate(dh, pub, priv)
304 const struct dhgroup *dh;
305 vchar_t **pub, **priv;
306 {
307 #ifdef ENABLE_STATS
308 struct timeval start, end;
309 gettimeofday(&start, NULL);
310 #endif
311 switch (dh->type) {
312 case OAKLEY_ATTR_GRP_TYPE_MODP:
313 if (eay_dh_generate(dh->prime, dh->gen1, dh->gen2, pub, priv) < 0) {
314 plog(LLV_ERROR, LOCATION, NULL,
315 "failed to compute dh value.\n");
316 return -1;
317 }
318 break;
319
320 case OAKLEY_ATTR_GRP_TYPE_ECP:
321 case OAKLEY_ATTR_GRP_TYPE_EC2N:
322 plog(LLV_ERROR, LOCATION, NULL,
323 "dh type %d isn't supported.\n", dh->type);
324 return -1;
325 default:
326 plog(LLV_ERROR, LOCATION, NULL,
327 "invalid dh type %d.\n", dh->type);
328 return -1;
329 }
330
331 #ifdef ENABLE_STATS
332 gettimeofday(&end, NULL);
333 syslog(LOG_NOTICE, "%s(%s%d): %8.6f", __func__,
334 s_attr_isakmp_group(dh->type), dh->prime->l << 3,
335 timedelta(&start, &end));
336 #endif
337
338 if (oakley_check_dh_pub(dh->prime, pub) != 0)
339 return -1;
340
341 plog(LLV_DEBUG, LOCATION, NULL, "compute DH's private.\n");
342 plogdump(LLV_DEBUG, (*priv)->v, (*priv)->l);
343 plog(LLV_DEBUG, LOCATION, NULL, "compute DH's public.\n");
344 plogdump(LLV_DEBUG, (*pub)->v, (*pub)->l);
345
346 return 0;
347 }
348
349 /*
350 * copy pre-defined dhgroup values.
351 */
352 int
353 oakley_setdhgroup(group, dhgrp)
354 int group;
355 struct dhgroup **dhgrp;
356 {
357 struct dhgroup *g;
358
359 *dhgrp = NULL; /* just make sure, initialize */
360
361 g = alg_oakley_dhdef_group(group);
362 if (g == NULL) {
363 plog(LLV_ERROR, LOCATION, NULL,
364 "invalid DH parameter grp=%d.\n", group);
365 return -1;
366 }
367
368 if (!g->type || !g->prime || !g->gen1) {
369 /* unsuported */
370 plog(LLV_ERROR, LOCATION, NULL,
371 "unsupported DH parameters grp=%d.\n", group);
372 return -1;
373 }
374
375 *dhgrp = racoon_calloc(1, sizeof(struct dhgroup));
376 if (*dhgrp == NULL) {
377 plog(LLV_ERROR, LOCATION, NULL,
378 "failed to get DH buffer.\n");
379 return 0;
380 }
381
382 /* set defined dh vlaues */
383 memcpy(*dhgrp, g, sizeof(*g));
384 (*dhgrp)->prime = vdup(g->prime);
385
386 return 0;
387 }
388
389 /*
390 * PRF
391 *
392 * NOTE: we do not support prf with different input/output bitwidth,
393 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example) in
394 * oakley_compute_keymat(). If you add support for such prf function,
395 * modify oakley_compute_keymat() accordingly.
396 */
397 vchar_t *
398 oakley_prf(key, buf, iph1)
399 vchar_t *key, *buf;
400 struct ph1handle *iph1;
401 {
402 vchar_t *res = NULL;
403 int type;
404
405 if (iph1->approval == NULL) {
406 /*
407 * it's before negotiating hash algorithm.
408 * We use md5 as default.
409 */
410 type = OAKLEY_ATTR_HASH_ALG_MD5;
411 } else
412 type = iph1->approval->hashtype;
413
414 res = alg_oakley_hmacdef_one(type, key, buf);
415 if (res == NULL) {
416 plog(LLV_ERROR, LOCATION, NULL,
417 "invalid hmac algorithm %d.\n", type);
418 return NULL;
419 }
420
421 return res;
422 }
423
424 /*
425 * hash
426 */
427 vchar_t *
428 oakley_hash(buf, iph1)
429 vchar_t *buf;
430 struct ph1handle *iph1;
431 {
432 vchar_t *res = NULL;
433 int type;
434
435 if (iph1->approval == NULL) {
436 /*
437 * it's before negotiating hash algorithm.
438 * We use md5 as default.
439 */
440 type = OAKLEY_ATTR_HASH_ALG_MD5;
441 } else
442 type = iph1->approval->hashtype;
443
444 res = alg_oakley_hashdef_one(type, buf);
445 if (res == NULL) {
446 plog(LLV_ERROR, LOCATION, NULL,
447 "invalid hash algorithm %d.\n", type);
448 return NULL;
449 }
450
451 return res;
452 }
453
454 /*
455 * compute KEYMAT
456 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
457 */
458 int
459 oakley_compute_keymat(iph2, side)
460 struct ph2handle *iph2;
461 int side;
462 {
463 int error = -1;
464
465 /* compute sharing secret of DH when PFS */
466 if (iph2->approval->pfs_group && iph2->dhpub_p) {
467 if (oakley_dh_compute(iph2->pfsgrp, iph2->dhpub,
468 iph2->dhpriv, iph2->dhpub_p, &iph2->dhgxy) < 0)
469 goto end;
470 }
471
472 /* compute keymat */
473 if (oakley_compute_keymat_x(iph2, side, INBOUND_SA) < 0
474 || oakley_compute_keymat_x(iph2, side, OUTBOUND_SA) < 0)
475 goto end;
476
477 plog(LLV_DEBUG, LOCATION, NULL, "KEYMAT computed.\n");
478
479 error = 0;
480
481 end:
482 return error;
483 }
484
485 /*
486 * compute KEYMAT.
487 * KEYMAT = prf(SKEYID_d, protocol | SPI | Ni_b | Nr_b).
488 * If PFS is desired and KE payloads were exchanged,
489 * KEYMAT = prf(SKEYID_d, g(qm)^xy | protocol | SPI | Ni_b | Nr_b)
490 *
491 * NOTE: we do not support prf with different input/output bitwidth,
492 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example).
493 */
494 static int
495 oakley_compute_keymat_x(iph2, side, sa_dir)
496 struct ph2handle *iph2;
497 int side;
498 int sa_dir;
499 {
500 vchar_t *buf = NULL, *res = NULL, *bp;
501 char *p;
502 int len;
503 int error = -1;
504 int pfs = 0;
505 int dupkeymat; /* generate K[1-dupkeymat] */
506 struct saproto *pr;
507 struct satrns *tr;
508 int encklen, authklen, l;
509
510 pfs = ((iph2->approval->pfs_group && iph2->dhgxy) ? 1 : 0);
511
512 len = pfs ? iph2->dhgxy->l : 0;
513 len += (1
514 + sizeof(u_int32_t) /* XXX SPI size */
515 + iph2->nonce->l
516 + iph2->nonce_p->l);
517 buf = vmalloc(len);
518 if (buf == NULL) {
519 plog(LLV_ERROR, LOCATION, NULL,
520 "failed to get keymat buffer.\n");
521 goto end;
522 }
523
524 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
525 p = buf->v;
526
527 /* if PFS */
528 if (pfs) {
529 memcpy(p, iph2->dhgxy->v, iph2->dhgxy->l);
530 p += iph2->dhgxy->l;
531 }
532
533 p[0] = pr->proto_id;
534 p += 1;
535
536 memcpy(p, (sa_dir == INBOUND_SA ? &pr->spi : &pr->spi_p),
537 sizeof(pr->spi));
538 p += sizeof(pr->spi);
539
540 bp = (side == INITIATOR ? iph2->nonce : iph2->nonce_p);
541 memcpy(p, bp->v, bp->l);
542 p += bp->l;
543
544 bp = (side == INITIATOR ? iph2->nonce_p : iph2->nonce);
545 memcpy(p, bp->v, bp->l);
546 p += bp->l;
547
548 /* compute IV */
549 plog(LLV_DEBUG, LOCATION, NULL, "KEYMAT compute with\n");
550 plogdump(LLV_DEBUG, buf->v, buf->l);
551
552 /* res = K1 */
553 res = oakley_prf(iph2->ph1->skeyid_d, buf, iph2->ph1);
554 if (res == NULL)
555 goto end;
556
557 /* compute key length needed */
558 encklen = authklen = 0;
559 switch (pr->proto_id) {
560 case IPSECDOI_PROTO_IPSEC_ESP:
561 for (tr = pr->head; tr; tr = tr->next) {
562 l = alg_ipsec_encdef_keylen(tr->trns_id,
563 tr->encklen);
564 if (l > encklen)
565 encklen = l;
566
567 l = alg_ipsec_hmacdef_hashlen(tr->authtype);
568 if (l > authklen)
569 authklen = l;
570 }
571 break;
572 case IPSECDOI_PROTO_IPSEC_AH:
573 for (tr = pr->head; tr; tr = tr->next) {
574 l = alg_ipsec_hmacdef_hashlen(tr->trns_id);
575 if (l > authklen)
576 authklen = l;
577 }
578 break;
579 default:
580 break;
581 }
582 plog(LLV_DEBUG, LOCATION, NULL, "encklen=%d authklen=%d\n",
583 encklen, authklen);
584
585 dupkeymat = (encklen + authklen) / 8 / res->l;
586 dupkeymat += 2; /* safety mergin */
587 if (dupkeymat < 3)
588 dupkeymat = 3;
589 plog(LLV_DEBUG, LOCATION, NULL,
590 "generating %zu bits of key (dupkeymat=%d)\n",
591 dupkeymat * 8 * res->l, dupkeymat);
592 if (0 < --dupkeymat) {
593 vchar_t *prev = res; /* K(n-1) */
594 vchar_t *seed = NULL; /* seed for Kn */
595 size_t l;
596
597 /*
598 * generating long key (isakmp-oakley-08 5.5)
599 * KEYMAT = K1 | K2 | K3 | ...
600 * where
601 * src = [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b
602 * K1 = prf(SKEYID_d, src)
603 * K2 = prf(SKEYID_d, K1 | src)
604 * K3 = prf(SKEYID_d, K2 | src)
605 * Kn = prf(SKEYID_d, K(n-1) | src)
606 */
607 plog(LLV_DEBUG, LOCATION, NULL,
608 "generating K1...K%d for KEYMAT.\n",
609 dupkeymat + 1);
610
611 seed = vmalloc(prev->l + buf->l);
612 if (seed == NULL) {
613 plog(LLV_ERROR, LOCATION, NULL,
614 "failed to get keymat buffer.\n");
615 if (prev && prev != res)
616 vfree(prev);
617 goto end;
618 }
619
620 while (dupkeymat--) {
621 vchar_t *this = NULL; /* Kn */
622 int update_prev;
623
624 memcpy(seed->v, prev->v, prev->l);
625 memcpy(seed->v + prev->l, buf->v, buf->l);
626 this = oakley_prf(iph2->ph1->skeyid_d, seed,
627 iph2->ph1);
628 if (!this) {
629 plog(LLV_ERROR, LOCATION, NULL,
630 "oakley_prf memory overflow\n");
631 if (prev && prev != res)
632 vfree(prev);
633 vfree(this);
634 vfree(seed);
635 goto end;
636 }
637
638 update_prev = (prev && prev == res) ? 1 : 0;
639
640 l = res->l;
641 res = vrealloc(res, l + this->l);
642
643 if (update_prev)
644 prev = res;
645
646 if (res == NULL) {
647 plog(LLV_ERROR, LOCATION, NULL,
648 "failed to get keymat buffer.\n");
649 if (prev && prev != res)
650 vfree(prev);
651 vfree(this);
652 vfree(seed);
653 goto end;
654 }
655 memcpy(res->v + l, this->v, this->l);
656
657 if (prev && prev != res)
658 vfree(prev);
659 prev = this;
660 this = NULL;
661 }
662
663 if (prev && prev != res)
664 vfree(prev);
665 vfree(seed);
666 }
667
668 plogdump(LLV_DEBUG, res->v, res->l);
669
670 if (sa_dir == INBOUND_SA)
671 pr->keymat = res;
672 else
673 pr->keymat_p = res;
674 res = NULL;
675 }
676
677 error = 0;
678
679 end:
680 if (error) {
681 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
682 if (pr->keymat) {
683 vfree(pr->keymat);
684 pr->keymat = NULL;
685 }
686 if (pr->keymat_p) {
687 vfree(pr->keymat_p);
688 pr->keymat_p = NULL;
689 }
690 }
691 }
692
693 if (buf != NULL)
694 vfree(buf);
695 if (res)
696 vfree(res);
697
698 return error;
699 }
700
701 #if notyet
702 /*
703 * NOTE: Must terminate by NULL.
704 */
705 vchar_t *
706 oakley_compute_hashx(struct ph1handle *iph1, ...)
707 {
708 vchar_t *buf, *res;
709 vchar_t *s;
710 caddr_t p;
711 int len;
712
713 va_list ap;
714
715 /* get buffer length */
716 va_start(ap, iph1);
717 len = 0;
718 while ((s = va_arg(ap, vchar_t *)) != NULL) {
719 len += s->l
720 }
721 va_end(ap);
722
723 buf = vmalloc(len);
724 if (buf == NULL) {
725 plog(LLV_ERROR, LOCATION, NULL,
726 "failed to get hash buffer\n");
727 return NULL;
728 }
729
730 /* set buffer */
731 va_start(ap, iph1);
732 p = buf->v;
733 while ((s = va_arg(ap, char *)) != NULL) {
734 memcpy(p, s->v, s->l);
735 p += s->l;
736 }
737 va_end(ap);
738
739 plog(LLV_DEBUG, LOCATION, NULL, "HASH with: \n");
740 plogdump(LLV_DEBUG, buf->v, buf->l);
741
742 /* compute HASH */
743 res = oakley_prf(iph1->skeyid_a, buf, iph1);
744 vfree(buf);
745 if (res == NULL)
746 return NULL;
747
748 plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
749 plogdump(LLV_DEBUG, res->v, res->l);
750
751 return res;
752 }
753 #endif
754
755 /*
756 * compute HASH(3) prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
757 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
758 */
759 vchar_t *
760 oakley_compute_hash3(iph1, msgid, body)
761 struct ph1handle *iph1;
762 u_int32_t msgid;
763 vchar_t *body;
764 {
765 vchar_t *buf = 0, *res = 0;
766 int len;
767 int error = -1;
768
769 /* create buffer */
770 len = 1 + sizeof(u_int32_t) + body->l;
771 buf = vmalloc(len);
772 if (buf == NULL) {
773 plog(LLV_DEBUG, LOCATION, NULL,
774 "failed to get hash buffer\n");
775 goto end;
776 }
777
778 buf->v[0] = 0;
779
780 memcpy(buf->v + 1, (char *)&msgid, sizeof(msgid));
781
782 memcpy(buf->v + 1 + sizeof(u_int32_t), body->v, body->l);
783
784 plog(LLV_DEBUG, LOCATION, NULL, "HASH with: \n");
785 plogdump(LLV_DEBUG, buf->v, buf->l);
786
787 /* compute HASH */
788 res = oakley_prf(iph1->skeyid_a, buf, iph1);
789 if (res == NULL)
790 goto end;
791
792 error = 0;
793
794 plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
795 plogdump(LLV_DEBUG, res->v, res->l);
796
797 end:
798 if (buf != NULL)
799 vfree(buf);
800 return res;
801 }
802
803 /*
804 * compute HASH type of prf(SKEYID_a, M-ID | buffer)
805 * e.g.
806 * for quick mode HASH(1):
807 * prf(SKEYID_a, M-ID | SA | Ni [ | KE ] [ | IDci | IDcr ])
808 * for quick mode HASH(2):
809 * prf(SKEYID_a, M-ID | Ni_b | SA | Nr [ | KE ] [ | IDci | IDcr ])
810 * for Informational exchange:
811 * prf(SKEYID_a, M-ID | N/D)
812 */
813 vchar_t *
814 oakley_compute_hash1(iph1, msgid, body)
815 struct ph1handle *iph1;
816 u_int32_t msgid;
817 vchar_t *body;
818 {
819 vchar_t *buf = NULL, *res = NULL;
820 char *p;
821 int len;
822 int error = -1;
823
824 /* create buffer */
825 len = sizeof(u_int32_t) + body->l;
826 buf = vmalloc(len);
827 if (buf == NULL) {
828 plog(LLV_DEBUG, LOCATION, NULL,
829 "failed to get hash buffer\n");
830 goto end;
831 }
832
833 p = buf->v;
834
835 memcpy(buf->v, (char *)&msgid, sizeof(msgid));
836 p += sizeof(u_int32_t);
837
838 memcpy(p, body->v, body->l);
839
840 plog(LLV_DEBUG, LOCATION, NULL, "HASH with:\n");
841 plogdump(LLV_DEBUG, buf->v, buf->l);
842
843 /* compute HASH */
844 res = oakley_prf(iph1->skeyid_a, buf, iph1);
845 if (res == NULL)
846 goto end;
847
848 error = 0;
849
850 plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
851 plogdump(LLV_DEBUG, res->v, res->l);
852
853 end:
854 if (buf != NULL)
855 vfree(buf);
856 return res;
857 }
858
859 /*
860 * compute phase1 HASH
861 * main/aggressive
862 * I-digest = prf(SKEYID, g^i | g^r | CKY-I | CKY-R | SAi_b | ID_i1_b)
863 * R-digest = prf(SKEYID, g^r | g^i | CKY-R | CKY-I | SAi_b | ID_r1_b)
864 * for gssapi, also include all GSS tokens, and call gss_wrap on the result
865 */
866 vchar_t *
867 oakley_ph1hash_common(iph1, sw)
868 struct ph1handle *iph1;
869 int sw;
870 {
871 vchar_t *buf = NULL, *res = NULL, *bp;
872 char *p, *bp2;
873 int len, bl;
874 int error = -1;
875 #ifdef HAVE_GSSAPI
876 vchar_t *gsstokens = NULL;
877 #endif
878
879 /* create buffer */
880 len = iph1->dhpub->l
881 + iph1->dhpub_p->l
882 + sizeof(cookie_t) * 2
883 + iph1->sa->l
884 + (sw == GENERATE ? iph1->id->l : iph1->id_p->l);
885
886 #ifdef HAVE_GSSAPI
887 if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
888 if (iph1->gi_i != NULL && iph1->gi_r != NULL) {
889 bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r);
890 len += bp->l;
891 }
892 if (sw == GENERATE)
893 gssapi_get_itokens(iph1, &gsstokens);
894 else
895 gssapi_get_rtokens(iph1, &gsstokens);
896 if (gsstokens == NULL)
897 return NULL;
898 len += gsstokens->l;
899 }
900 #endif
901
902 buf = vmalloc(len);
903 if (buf == NULL) {
904 plog(LLV_ERROR, LOCATION, NULL,
905 "failed to get hash buffer\n");
906 goto end;
907 }
908
909 p = buf->v;
910
911 bp = (sw == GENERATE ? iph1->dhpub : iph1->dhpub_p);
912 memcpy(p, bp->v, bp->l);
913 p += bp->l;
914
915 bp = (sw == GENERATE ? iph1->dhpub_p : iph1->dhpub);
916 memcpy(p, bp->v, bp->l);
917 p += bp->l;
918
919 if (iph1->side == INITIATOR)
920 bp2 = (sw == GENERATE ?
921 (char *)&iph1->index.i_ck : (char *)&iph1->index.r_ck);
922 else
923 bp2 = (sw == GENERATE ?
924 (char *)&iph1->index.r_ck : (char *)&iph1->index.i_ck);
925 bl = sizeof(cookie_t);
926 memcpy(p, bp2, bl);
927 p += bl;
928
929 if (iph1->side == INITIATOR)
930 bp2 = (sw == GENERATE ?
931 (char *)&iph1->index.r_ck : (char *)&iph1->index.i_ck);
932 else
933 bp2 = (sw == GENERATE ?
934 (char *)&iph1->index.i_ck : (char *)&iph1->index.r_ck);
935 bl = sizeof(cookie_t);
936 memcpy(p, bp2, bl);
937 p += bl;
938
939 bp = iph1->sa;
940 memcpy(p, bp->v, bp->l);
941 p += bp->l;
942
943 bp = (sw == GENERATE ? iph1->id : iph1->id_p);
944 memcpy(p, bp->v, bp->l);
945 p += bp->l;
946
947 #ifdef HAVE_GSSAPI
948 if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
949 if (iph1->gi_i != NULL && iph1->gi_r != NULL) {
950 bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r);
951 memcpy(p, bp->v, bp->l);
952 p += bp->l;
953 }
954 memcpy(p, gsstokens->v, gsstokens->l);
955 p += gsstokens->l;
956 }
957 #endif
958
959 plog(LLV_DEBUG, LOCATION, NULL, "HASH with:\n");
960 plogdump(LLV_DEBUG, buf->v, buf->l);
961
962 /* compute HASH */
963 res = oakley_prf(iph1->skeyid, buf, iph1);
964 if (res == NULL)
965 goto end;
966
967 error = 0;
968
969 plog(LLV_DEBUG, LOCATION, NULL, "HASH (%s) computed:\n",
970 iph1->side == INITIATOR ? "init" : "resp");
971 plogdump(LLV_DEBUG, res->v, res->l);
972
973 end:
974 if (buf != NULL)
975 vfree(buf);
976 #ifdef HAVE_GSSAPI
977 if (gsstokens != NULL)
978 vfree(gsstokens);
979 #endif
980 return res;
981 }
982
983 /*
984 * compute HASH_I on base mode.
985 * base:psk,rsa
986 * HASH_I = prf(SKEYID, g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
987 * base:sig
988 * HASH_I = prf(hash(Ni_b | Nr_b), g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
989 */
990 vchar_t *
991 oakley_ph1hash_base_i(iph1, sw)
992 struct ph1handle *iph1;
993 int sw;
994 {
995 vchar_t *buf = NULL, *res = NULL, *bp;
996 vchar_t *hashkey = NULL;
997 vchar_t *hash = NULL; /* for signature mode */
998 char *p;
999 int len;
1000 int error = -1;
1001
1002 /* sanity check */
1003 if (iph1->etype != ISAKMP_ETYPE_BASE) {
1004 plog(LLV_ERROR, LOCATION, NULL,
1005 "invalid etype for this hash function\n");
1006 return NULL;
1007 }
1008
1009 switch (AUTHMETHOD(iph1)) {
1010 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1011 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1012 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1013 #ifdef ENABLE_HYBRID
1014 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
1015 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1016 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
1017 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1018 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
1019 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1020 #endif
1021 if (iph1->skeyid == NULL) {
1022 plog(LLV_ERROR, LOCATION, NULL, "no SKEYID found.\n");
1023 return NULL;
1024 }
1025 hashkey = iph1->skeyid;
1026 break;
1027
1028 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1029 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1030 #ifdef HAVE_GSSAPI
1031 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1032 #endif
1033 #ifdef ENABLE_HYBRID
1034 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1035 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1036 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
1037 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1038 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
1039 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1040 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
1041 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1042 #endif
1043 /* make hash for seed */
1044 len = iph1->nonce->l + iph1->nonce_p->l;
1045 buf = vmalloc(len);
1046 if (buf == NULL) {
1047 plog(LLV_ERROR, LOCATION, NULL,
1048 "failed to get hash buffer\n");
1049 goto end;
1050 }
1051 p = buf->v;
1052
1053 bp = (sw == GENERATE ? iph1->nonce_p : iph1->nonce);
1054 memcpy(p, bp->v, bp->l);
1055 p += bp->l;
1056
1057 bp = (sw == GENERATE ? iph1->nonce : iph1->nonce_p);
1058 memcpy(p, bp->v, bp->l);
1059 p += bp->l;
1060
1061 hash = oakley_hash(buf, iph1);
1062 if (hash == NULL)
1063 goto end;
1064 vfree(buf);
1065 buf = NULL;
1066
1067 hashkey = hash;
1068 break;
1069
1070 default:
1071 plog(LLV_ERROR, LOCATION, NULL,
1072 "not supported authentication method %d\n",
1073 iph1->approval->authmethod);
1074 return NULL;
1075
1076 }
1077
1078 len = (sw == GENERATE ? iph1->dhpub->l : iph1->dhpub_p->l)
1079 + sizeof(cookie_t) * 2
1080 + iph1->sa->l
1081 + (sw == GENERATE ? iph1->id->l : iph1->id_p->l);
1082 buf = vmalloc(len);
1083 if (buf == NULL) {
1084 plog(LLV_ERROR, LOCATION, NULL,
1085 "failed to get hash buffer\n");
1086 goto end;
1087 }
1088 p = buf->v;
1089
1090 bp = (sw == GENERATE ? iph1->dhpub : iph1->dhpub_p);
1091 memcpy(p, bp->v, bp->l);
1092 p += bp->l;
1093
1094 memcpy(p, &iph1->index.i_ck, sizeof(cookie_t));
1095 p += sizeof(cookie_t);
1096 memcpy(p, &iph1->index.r_ck, sizeof(cookie_t));
1097 p += sizeof(cookie_t);
1098
1099 memcpy(p, iph1->sa->v, iph1->sa->l);
1100 p += iph1->sa->l;
1101
1102 bp = (sw == GENERATE ? iph1->id : iph1->id_p);
1103 memcpy(p, bp->v, bp->l);
1104 p += bp->l;
1105
1106 plog(LLV_DEBUG, LOCATION, NULL, "HASH_I with:\n");
1107 plogdump(LLV_DEBUG, buf->v, buf->l);
1108
1109 /* compute HASH */
1110 res = oakley_prf(hashkey, buf, iph1);
1111 if (res == NULL)
1112 goto end;
1113
1114 error = 0;
1115
1116 plog(LLV_DEBUG, LOCATION, NULL, "HASH_I computed:\n");
1117 plogdump(LLV_DEBUG, res->v, res->l);
1118
1119 end:
1120 if (hash != NULL)
1121 vfree(hash);
1122 if (buf != NULL)
1123 vfree(buf);
1124 return res;
1125 }
1126
1127 /*
1128 * compute HASH_R on base mode for signature method.
1129 * base:
1130 * HASH_R = prf(hash(Ni_b | Nr_b), g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b)
1131 */
1132 vchar_t *
1133 oakley_ph1hash_base_r(iph1, sw)
1134 struct ph1handle *iph1;
1135 int sw;
1136 {
1137 vchar_t *buf = NULL, *res = NULL, *bp;
1138 vchar_t *hash = NULL;
1139 char *p;
1140 int len;
1141 int error = -1;
1142
1143 /* sanity check */
1144 if (iph1->etype != ISAKMP_ETYPE_BASE) {
1145 plog(LLV_ERROR, LOCATION, NULL,
1146 "invalid etype for this hash function\n");
1147 return NULL;
1148 }
1149
1150 switch(AUTHMETHOD(iph1)) {
1151 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1152 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1153 #ifdef ENABLE_HYBRID
1154 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1155 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1156 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
1157 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1158 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
1159 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1160 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
1161 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1162 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
1163 #endif
1164 break;
1165 default:
1166 plog(LLV_ERROR, LOCATION, NULL,
1167 "not supported authentication method %d\n",
1168 iph1->approval->authmethod);
1169 return NULL;
1170 break;
1171 }
1172
1173 /* make hash for seed */
1174 len = iph1->nonce->l + iph1->nonce_p->l;
1175 buf = vmalloc(len);
1176 if (buf == NULL) {
1177 plog(LLV_ERROR, LOCATION, NULL,
1178 "failed to get hash buffer\n");
1179 goto end;
1180 }
1181 p = buf->v;
1182
1183 bp = (sw == GENERATE ? iph1->nonce_p : iph1->nonce);
1184 memcpy(p, bp->v, bp->l);
1185 p += bp->l;
1186
1187 bp = (sw == GENERATE ? iph1->nonce : iph1->nonce_p);
1188 memcpy(p, bp->v, bp->l);
1189 p += bp->l;
1190
1191 hash = oakley_hash(buf, iph1);
1192 if (hash == NULL)
1193 goto end;
1194 vfree(buf);
1195 buf = NULL;
1196
1197 /* make really hash */
1198 len = (sw == GENERATE ? iph1->dhpub_p->l : iph1->dhpub->l)
1199 + (sw == GENERATE ? iph1->dhpub->l : iph1->dhpub_p->l)
1200 + sizeof(cookie_t) * 2
1201 + iph1->sa->l
1202 + (sw == GENERATE ? iph1->id_p->l : iph1->id->l);
1203 buf = vmalloc(len);
1204 if (buf == NULL) {
1205 plog(LLV_ERROR, LOCATION, NULL,
1206 "failed to get hash buffer\n");
1207 goto end;
1208 }
1209 p = buf->v;
1210
1211
1212 bp = (sw == GENERATE ? iph1->dhpub_p : iph1->dhpub);
1213 memcpy(p, bp->v, bp->l);
1214 p += bp->l;
1215
1216 bp = (sw == GENERATE ? iph1->dhpub : iph1->dhpub_p);
1217 memcpy(p, bp->v, bp->l);
1218 p += bp->l;
1219
1220 memcpy(p, &iph1->index.i_ck, sizeof(cookie_t));
1221 p += sizeof(cookie_t);
1222 memcpy(p, &iph1->index.r_ck, sizeof(cookie_t));
1223 p += sizeof(cookie_t);
1224
1225 memcpy(p, iph1->sa->v, iph1->sa->l);
1226 p += iph1->sa->l;
1227
1228 bp = (sw == GENERATE ? iph1->id_p : iph1->id);
1229 memcpy(p, bp->v, bp->l);
1230 p += bp->l;
1231
1232 plog(LLV_DEBUG, LOCATION, NULL, "HASH_R with:\n");
1233 plogdump(LLV_DEBUG, buf->v, buf->l);
1234
1235 /* compute HASH */
1236 res = oakley_prf(hash, buf, iph1);
1237 if (res == NULL)
1238 goto end;
1239
1240 error = 0;
1241
1242 plog(LLV_DEBUG, LOCATION, NULL, "HASH_R computed:\n");
1243 plogdump(LLV_DEBUG, res->v, res->l);
1244
1245 end:
1246 if (buf != NULL)
1247 vfree(buf);
1248 if (hash)
1249 vfree(hash);
1250 return res;
1251 }
1252
1253 /*
1254 * compute each authentication method in phase 1.
1255 * OUT:
1256 * 0: OK
1257 * -1: error
1258 * other: error to be reply with notification.
1259 * the value is notification type.
1260 */
1261 int
1262 oakley_validate_auth(iph1)
1263 struct ph1handle *iph1;
1264 {
1265 vchar_t *my_hash = NULL;
1266 int result;
1267 #ifdef HAVE_GSSAPI
1268 vchar_t *gsshash = NULL;
1269 #endif
1270 #ifdef ENABLE_STATS
1271 struct timeval start, end;
1272 #endif
1273
1274 #ifdef ENABLE_STATS
1275 gettimeofday(&start, NULL);
1276 #endif
1277
1278 switch (AUTHMETHOD(iph1)) {
1279 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1280 #ifdef ENABLE_HYBRID
1281 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
1282 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1283 #endif
1284 /* validate HASH */
1285 {
1286 char *r_hash;
1287
1288 if (iph1->id_p == NULL || iph1->pl_hash == NULL) {
1289 plog(LLV_ERROR, LOCATION, iph1->remote,
1290 "few isakmp message received.\n");
1291 return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1292 }
1293 #ifdef ENABLE_HYBRID
1294 if (AUTHMETHOD(iph1) == FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I &&
1295 ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0))
1296 {
1297 plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, "
1298 "hybrid auth is enabled, "
1299 "but peer is no Xauth compliant\n");
1300 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED;
1301 break;
1302 }
1303 #endif
1304 r_hash = (caddr_t)(iph1->pl_hash + 1);
1305
1306 plog(LLV_DEBUG, LOCATION, NULL, "HASH received:\n");
1307 plogdump(LLV_DEBUG, r_hash,
1308 ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash));
1309
1310 switch (iph1->etype) {
1311 case ISAKMP_ETYPE_IDENT:
1312 case ISAKMP_ETYPE_AGG:
1313 my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1314 break;
1315 case ISAKMP_ETYPE_BASE:
1316 if (iph1->side == INITIATOR)
1317 my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1318 else
1319 my_hash = oakley_ph1hash_base_i(iph1, VALIDATE);
1320 break;
1321 default:
1322 plog(LLV_ERROR, LOCATION, NULL,
1323 "invalid etype %d\n", iph1->etype);
1324 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1325 }
1326 if (my_hash == NULL)
1327 return ISAKMP_INTERNAL_ERROR;
1328
1329 result = memcmp(my_hash->v, r_hash, my_hash->l);
1330 vfree(my_hash);
1331
1332 if (result) {
1333 plog(LLV_ERROR, LOCATION, NULL, "HASH mismatched\n");
1334 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1335 }
1336
1337 plog(LLV_DEBUG, LOCATION, NULL, "HASH for PSK validated.\n");
1338 }
1339 break;
1340 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1341 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1342 #ifdef ENABLE_HYBRID
1343 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1344 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
1345 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
1346 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1347 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
1348 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1349 #endif
1350 {
1351 int error = 0;
1352 int certtype = 0;
1353
1354 /* validation */
1355 if (iph1->id_p == NULL) {
1356 plog(LLV_ERROR, LOCATION, iph1->remote,
1357 "no ID payload was passed.\n");
1358 return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1359 }
1360 if (iph1->sig_p == NULL) {
1361 plog(LLV_ERROR, LOCATION, iph1->remote,
1362 "no SIG payload was passed.\n");
1363 return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1364 }
1365
1366 plog(LLV_DEBUG, LOCATION, NULL, "SIGN passed:\n");
1367 plogdump(LLV_DEBUG, iph1->sig_p->v, iph1->sig_p->l);
1368
1369 /* get peer's cert */
1370 switch (iph1->rmconf->getcert_method) {
1371 case ISAKMP_GETCERT_PAYLOAD:
1372 if (iph1->cert_p == NULL) {
1373 plog(LLV_ERROR, LOCATION, NULL,
1374 "no peer's CERT payload found.\n");
1375 return ISAKMP_INTERNAL_ERROR;
1376 }
1377 break;
1378 case ISAKMP_GETCERT_LOCALFILE:
1379 switch (iph1->rmconf->certtype) {
1380 case ISAKMP_CERT_X509SIGN:
1381 if (iph1->rmconf->peerscertfile == NULL) {
1382 plog(LLV_ERROR, LOCATION, NULL,
1383 "no peer's CERT file found.\n");
1384 return ISAKMP_INTERNAL_ERROR;
1385 }
1386
1387 /* don't use cached cert */
1388 if (iph1->cert_p != NULL) {
1389 oakley_delcert(iph1->cert_p);
1390 iph1->cert_p = NULL;
1391 }
1392
1393 error = get_cert_fromlocal(iph1, 0);
1394 break;
1395
1396 case ISAKMP_CERT_PLAINRSA:
1397 error = get_plainrsa_fromlocal(iph1, 0);
1398 break;
1399 }
1400 if (error)
1401 return ISAKMP_INTERNAL_ERROR;
1402 break;
1403 case ISAKMP_GETCERT_DNS:
1404 if (iph1->rmconf->peerscertfile != NULL) {
1405 plog(LLV_ERROR, LOCATION, NULL,
1406 "why peer's CERT file is defined "
1407 "though getcert method is dns ?\n");
1408 return ISAKMP_INTERNAL_ERROR;
1409 }
1410
1411 /* don't use cached cert */
1412 if (iph1->cert_p != NULL) {
1413 oakley_delcert(iph1->cert_p);
1414 iph1->cert_p = NULL;
1415 }
1416
1417 iph1->cert_p = dnssec_getcert(iph1->id_p);
1418 if (iph1->cert_p == NULL) {
1419 plog(LLV_ERROR, LOCATION, NULL,
1420 "no CERT RR found.\n");
1421 return ISAKMP_INTERNAL_ERROR;
1422 }
1423 break;
1424 default:
1425 plog(LLV_ERROR, LOCATION, NULL,
1426 "invalid getcert_mothod: %d\n",
1427 iph1->rmconf->getcert_method);
1428 return ISAKMP_INTERNAL_ERROR;
1429 }
1430
1431 /* compare ID payload and certificate name */
1432 if (iph1->rmconf->verify_cert &&
1433 #ifdef __APPLE__
1434 (error = oakley_check_certid(iph1, CERT_CHECKID_FROM_PEER)) != 0)
1435 #else
1436 (error = oakley_check_certid(iph1)) != 0)
1437 #endif
1438 return error;
1439
1440 #ifdef __APPLE__
1441
1442 /* check configured peers identifier against cert IDs */
1443 /* allows checking of specified ID against multiple ids in the cert */
1444 /* such as multiple domain names */
1445 #if !TARGET_OS_EMBEDDED
1446 if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_PEERS_IDENTIFIER &&
1447 (error = oakley_check_certid(iph1, CERT_CHECKID_FROM_RMCONFIG)) != 0)
1448 return error;
1449 #endif
1450
1451 #if HAVE_OPENDIR
1452 /* check cert common name against Open Directory authentication group */
1453 if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_OPEN_DIR) {
1454
1455 vchar_t *user_id = NULL;
1456
1457 user_id = eay_get_x509_common_name(&iph1->cert_p->cert);
1458 if (user_id) {
1459 // the following functions will check if user_id == 0
1460 if (open_dir_authorize_id(user_id, iph1->rmconf->open_dir_auth_group) == 0) {
1461 plog(LLV_ERROR, LOCATION, NULL,
1462 "the peer is not authorized for access.\n");
1463 vfree(user_id);
1464 return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
1465 }
1466 vfree(user_id);
1467 } else {
1468 plog(LLV_ERROR, LOCATION, NULL,
1469 "the peer is not authorized for access - user ID not found.\n");
1470 return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
1471 }
1472 }
1473 #endif /* HAVE_OPENDIR */
1474 #endif /* __APPLE__ */
1475
1476 /* verify certificate */
1477 if (iph1->rmconf->verify_cert
1478 && iph1->rmconf->getcert_method == ISAKMP_GETCERT_PAYLOAD) {
1479 certtype = iph1->rmconf->certtype;
1480 #ifdef ENABLE_HYBRID
1481 switch (AUTHMETHOD(iph1)) {
1482 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1483 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
1484 certtype = iph1->cert_p->type;
1485 break;
1486 default:
1487 break;
1488 }
1489 #endif
1490 switch (certtype) {
1491 case ISAKMP_CERT_X509SIGN:
1492
1493 #if TARGET_OS_EMBEDDED
1494 {
1495 /* use ID from remote configuration */
1496 /* check each ID in list */
1497 struct idspec *id_spec;
1498 CFStringRef hostname = NULL;
1499 char *peers_id;
1500 struct genlist_entry *gpb = NULL;
1501
1502 if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_PEERS_IDENTIFIER) {
1503 id_spec = genlist_next(iph1->rmconf->idvl_p, &gpb); /* expect only one id */
1504 if (id_spec->idtype == IDTYPE_ADDRESS) {
1505 switch (((struct sockaddr *)(id_spec->id->v))->sa_family) {
1506 case AF_INET:
1507 peers_id = inet_ntoa(((struct sockaddr_in *)(id_spec->id->v))->sin_addr);
1508 hostname = CFStringCreateWithCString(NULL, peers_id, kCFStringEncodingUTF8);
1509 break;
1510 #ifdef INET6
1511 case AF_INET6:
1512 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; /* not currently supported for embedded */
1513 break;
1514 #endif
1515 default:
1516 plog(LLV_ERROR, LOCATION, NULL,
1517 "unknown address type for peers identifier.\n");
1518 return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
1519 break;
1520 }
1521 } else
1522 hostname = CFStringCreateWithBytes(NULL, (u_int8_t *)id_spec->id->v, id_spec->id->l, kCFStringEncodingUTF8, FALSE);
1523 }
1524 error = crypto_cssm_check_x509cert(&iph1->cert_p->cert, hostname, iph1->cert_p->status);
1525 if (hostname)
1526 CFRelease(hostname);
1527 }
1528
1529 #else /* TARGET_OS_EMBEDDED */
1530 #ifdef __APPLE__
1531 if (iph1->rmconf->cert_verification == VERIFICATION_MODULE_SEC_FRAMEWORK)
1532 error = crypto_cssm_check_x509cert(&iph1->cert_p->cert, NULL, iph1->cert_p->status);
1533 else
1534 #endif /* __APPLE__ */
1535 {
1536 char path[MAXPATHLEN];
1537 char *ca;
1538
1539 if (iph1->rmconf->cacertfile != NULL) {
1540 getpathname(path, sizeof(path),
1541 LC_PATHTYPE_CERT,
1542 iph1->rmconf->cacertfile);
1543 ca = path;
1544 } else {
1545 ca = NULL;
1546 }
1547
1548 error = eay_check_x509cert(&iph1->cert_p->cert,
1549 lcconf->pathinfo[LC_PATHTYPE_CERT],
1550 ca, 0);
1551 }
1552 #endif /* TARGET_OS_EMBEDDED */
1553 break;
1554
1555 default:
1556 plog(LLV_ERROR, LOCATION, NULL,
1557 "no supported certtype %d\n", certtype);
1558 return ISAKMP_INTERNAL_ERROR;
1559 }
1560 if (error != 0) {
1561 plog(LLV_ERROR, LOCATION, NULL,
1562 "the peer's certificate is not verified.\n");
1563 return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY;
1564 }
1565 }
1566
1567 plog(LLV_DEBUG, LOCATION, NULL, "CERT validated\n");
1568
1569 /* compute hash */
1570 switch (iph1->etype) {
1571 case ISAKMP_ETYPE_IDENT:
1572 case ISAKMP_ETYPE_AGG:
1573 my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1574 break;
1575 case ISAKMP_ETYPE_BASE:
1576 if (iph1->side == INITIATOR)
1577 my_hash = oakley_ph1hash_base_r(iph1, VALIDATE);
1578 else
1579 my_hash = oakley_ph1hash_base_i(iph1, VALIDATE);
1580 break;
1581 default:
1582 plog(LLV_ERROR, LOCATION, NULL,
1583 "invalid etype %d\n", iph1->etype);
1584 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1585 }
1586 if (my_hash == NULL)
1587 return ISAKMP_INTERNAL_ERROR;
1588
1589
1590 certtype = iph1->rmconf->certtype;
1591 #ifdef ENABLE_HYBRID
1592 switch (AUTHMETHOD(iph1)) {
1593 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1594 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
1595 certtype = iph1->cert_p->type;
1596 break;
1597 default:
1598 break;
1599 }
1600 #endif
1601 /* check signature */
1602 switch (certtype) {
1603 case ISAKMP_CERT_X509SIGN:
1604 case ISAKMP_CERT_DNS:
1605 error = eay_check_x509sign(my_hash,
1606 iph1->sig_p,
1607 &iph1->cert_p->cert);
1608 break;
1609 case ISAKMP_CERT_PLAINRSA:
1610 iph1->rsa_p = rsa_try_check_rsasign(my_hash,
1611 iph1->sig_p, iph1->rsa_candidates);
1612 error = iph1->rsa_p ? 0 : -1;
1613
1614 break;
1615 default:
1616 plog(LLV_ERROR, LOCATION, NULL,
1617 "no supported certtype %d\n",
1618 certtype);
1619 vfree(my_hash);
1620 return ISAKMP_INTERNAL_ERROR;
1621 }
1622
1623 vfree(my_hash);
1624 if (error != 0) {
1625 plog(LLV_ERROR, LOCATION, NULL,
1626 "Invalid SIG.\n");
1627 return ISAKMP_NTYPE_INVALID_SIGNATURE;
1628 }
1629 plog(LLV_DEBUG, LOCATION, NULL, "SIG authenticated\n");
1630 }
1631 break;
1632 #ifdef ENABLE_HYBRID
1633 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1634 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1635 {
1636 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
1637 plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, "
1638 "hybrid auth is enabled, "
1639 "but peer is no Xauth compliant\n");
1640 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED;
1641 break;
1642 }
1643 plog(LLV_INFO, LOCATION, NULL, "No SIG was passed, "
1644 "but hybrid auth is enabled\n");
1645
1646 return 0;
1647 break;
1648 }
1649 #endif
1650 #ifdef HAVE_GSSAPI
1651 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1652 /* check if we're not into XAUTH_PSKEY_I instead */
1653 #ifdef ENABLE_HYBRID
1654 if (iph1->rmconf->xauth)
1655 break;
1656 #endif
1657 switch (iph1->etype) {
1658 case ISAKMP_ETYPE_IDENT:
1659 case ISAKMP_ETYPE_AGG:
1660 my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1661 break;
1662 default:
1663 plog(LLV_ERROR, LOCATION, NULL,
1664 "invalid etype %d\n", iph1->etype);
1665 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1666 }
1667
1668 if (my_hash == NULL) {
1669 if (gssapi_more_tokens(iph1))
1670 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1671 else
1672 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1673 }
1674
1675 gsshash = gssapi_unwraphash(iph1);
1676 if (gsshash == NULL) {
1677 vfree(my_hash);
1678 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1679 }
1680
1681 result = memcmp(my_hash->v, gsshash->v, my_hash->l);
1682 vfree(my_hash);
1683 vfree(gsshash);
1684
1685 if (result) {
1686 plog(LLV_ERROR, LOCATION, NULL, "HASH mismatched\n");
1687 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1688 }
1689 plog(LLV_DEBUG, LOCATION, NULL, "hash compared OK\n");
1690 break;
1691 #endif
1692 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1693 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1694 #ifdef ENABLE_HYBRID
1695 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
1696 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1697 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
1698 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1699 #endif
1700 if (iph1->id_p == NULL || iph1->pl_hash == NULL) {
1701 plog(LLV_ERROR, LOCATION, iph1->remote,
1702 "few isakmp message received.\n");
1703 return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1704 }
1705 plog(LLV_ERROR, LOCATION, iph1->remote,
1706 "not supported authmethod type %s\n",
1707 s_oakley_attr_method(iph1->approval->authmethod));
1708 return ISAKMP_INTERNAL_ERROR;
1709 default:
1710 plog(LLV_ERROR, LOCATION, iph1->remote,
1711 "invalid authmethod %d why ?\n",
1712 iph1->approval->authmethod);
1713 return ISAKMP_INTERNAL_ERROR;
1714 }
1715 #ifdef ENABLE_STATS
1716 gettimeofday(&end, NULL);
1717 syslog(LOG_NOTICE, "%s(%s): %8.6f", __func__,
1718 s_oakley_attr_method(iph1->approval->authmethod),
1719 timedelta(&start, &end));
1720 #endif
1721
1722 return 0;
1723 }
1724
1725 /* get my certificate
1726 * NOTE: include certificate type.
1727 */
1728 int
1729 oakley_getmycert(iph1)
1730 struct ph1handle *iph1;
1731 {
1732 int err;
1733 u_int32_t address;
1734
1735 switch (iph1->rmconf->certtype) {
1736 case ISAKMP_CERT_X509SIGN:
1737 if (iph1->cert)
1738 return 0;
1739 /* only do the local cert test on the phone */
1740 {
1741 if ( !(err = get_cert_fromlocal(iph1, 1))){
1742 if ( iph1->cert->status == CERT_STATUS_EXPIRED || iph1->cert->status == CERT_STATUS_PREMATURE){
1743 if (iph1->remote->sa_family == AF_INET)
1744 address = ((struct sockaddr_in *)(iph1->remote))->sin_addr.s_addr;
1745 else
1746 address = 0;
1747 vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PH1_DELETE_CERT_ERROR + iph1->cert->status, FROM_LOCAL, address, 0, NULL);
1748 return -1;
1749 }
1750 }
1751 }
1752 return err;
1753
1754 case ISAKMP_CERT_PLAINRSA:
1755 if (iph1->rsa)
1756 return 0;
1757 return get_plainrsa_fromlocal(iph1, 1);
1758
1759 default:
1760 plog(LLV_ERROR, LOCATION, NULL,
1761 "Unknown certtype #%d\n",
1762 iph1->rmconf->certtype);
1763 return -1;
1764 }
1765
1766 }
1767
1768 /*
1769 * get a CERT from local file.
1770 * IN:
1771 * my != 0 my cert.
1772 * my == 0 peer's cert.
1773 */
1774 static int
1775 get_cert_fromlocal(iph1, my)
1776 struct ph1handle *iph1;
1777 int my;
1778 {
1779 char path[MAXPATHLEN];
1780 vchar_t *cert = NULL;
1781 cert_t **certpl;
1782 char *certfile;
1783 int error = -1;
1784 cert_status_t status = CERT_STATUS_OK;
1785
1786 if (my) {
1787 certfile = iph1->rmconf->mycertfile;
1788 certpl = &iph1->cert;
1789 } else {
1790 certfile = iph1->rmconf->peerscertfile;
1791 certpl = &iph1->cert_p;
1792 }
1793
1794 #ifdef __APPLE__
1795 if (!certfile && iph1->rmconf->identity_in_keychain == 0) {
1796 #else
1797 if (!certfile) {
1798 #endif
1799 plog(LLV_ERROR, LOCATION, NULL, "no CERT defined.\n");
1800 return 0;
1801 }
1802
1803 switch (iph1->rmconf->certtype) {
1804 case ISAKMP_CERT_X509SIGN:
1805 #if defined(__APPLE__)
1806 if (iph1->rmconf->identity_in_keychain) {
1807 CFDataRef dataRef;
1808
1809 if (iph1->rmconf->keychainCertRef == NULL || base64toCFData(iph1->rmconf->keychainCertRef, &dataRef))
1810 goto end;
1811 cert = crypto_cssm_get_x509cert(dataRef, &status);
1812 plog(LLV_DEBUG, LOCATION, NULL, "done with chking cert status %d\n",status);
1813 CFRelease(dataRef);
1814 break;
1815 } // else fall thru
1816 #endif
1817 case ISAKMP_CERT_DNS:
1818 /* make public file name */
1819 getpathname(path, sizeof(path), LC_PATHTYPE_CERT, certfile);
1820 cert = eay_get_x509cert(path);
1821 if (cert) {
1822 char *p = NULL;
1823 p = eay_get_x509text(cert);
1824 plog(LLV_DEBUG, LOCATION, NULL, "%s", p ? p : "\n");
1825 racoon_free(p);
1826 };
1827 break;
1828
1829 default:
1830 plog(LLV_ERROR, LOCATION, NULL,
1831 "not supported certtype %d\n",
1832 iph1->rmconf->certtype);
1833 goto end;
1834 }
1835
1836 if (!cert) {
1837 plog(LLV_ERROR, LOCATION, NULL,
1838 "failed to get %s CERT.\n",
1839 my ? "my" : "peers");
1840 goto end;
1841 }
1842
1843 *certpl = oakley_newcert();
1844 if (!*certpl) {
1845 plog(LLV_ERROR, LOCATION, NULL,
1846 "failed to get cert buffer.\n");
1847 goto end;
1848 }
1849 (*certpl)->pl = vmalloc(cert->l + 1);
1850 if ((*certpl)->pl == NULL) {
1851 plog(LLV_ERROR, LOCATION, NULL,
1852 "failed to get cert buffer\n");
1853 oakley_delcert(*certpl);
1854 *certpl = NULL;
1855 goto end;
1856 }
1857 memcpy((*certpl)->pl->v + 1, cert->v, cert->l);
1858 (*certpl)->pl->v[0] = iph1->rmconf->certtype;
1859 (*certpl)->type = iph1->rmconf->certtype;
1860 (*certpl)->status = status;
1861 (*certpl)->cert.v = (*certpl)->pl->v + 1;
1862 (*certpl)->cert.l = (*certpl)->pl->l - 1;
1863
1864 plog(LLV_DEBUG, LOCATION, NULL, "created CERT payload:\n");
1865 plogdump(LLV_DEBUG, (*certpl)->pl->v, (*certpl)->pl->l);
1866
1867 error = 0;
1868
1869 end:
1870 if (cert != NULL)
1871 vfree(cert);
1872
1873 return error;
1874 }
1875
1876 static int
1877 get_plainrsa_fromlocal(iph1, my)
1878 struct ph1handle *iph1;
1879 int my;
1880 {
1881 char path[MAXPATHLEN];
1882 vchar_t *cert = NULL;
1883 char *certfile;
1884 int error = -1;
1885
1886 iph1->rsa_candidates = rsa_lookup_keys(iph1, my);
1887 if (!iph1->rsa_candidates ||
1888 rsa_list_count(iph1->rsa_candidates) == 0) {
1889 plog(LLV_ERROR, LOCATION, NULL,
1890 "%s RSA key not found for %s\n",
1891 my ? "Private" : "Public",
1892 saddr2str_fromto("%s <-> %s",
1893 iph1->local, iph1->remote));
1894 goto end;
1895 }
1896
1897 if (my && rsa_list_count(iph1->rsa_candidates) > 1) {
1898 plog(LLV_WARNING, LOCATION, NULL,
1899 "More than one (=%lu) private "
1900 "PlainRSA key found for %s\n",
1901 rsa_list_count(iph1->rsa_candidates),
1902 saddr2str_fromto("%s <-> %s",
1903 iph1->local, iph1->remote));
1904 plog(LLV_WARNING, LOCATION, NULL,
1905 "This may have unpredictable results, "
1906 "i.e. wrong key could be used!\n");
1907 plog(LLV_WARNING, LOCATION, NULL,
1908 "Consider using only one single private "
1909 "key for all peers...\n");
1910 }
1911 if (my) {
1912 iph1->rsa = ((struct rsa_key *)
1913 genlist_next(iph1->rsa_candidates, NULL))->rsa;
1914
1915 genlist_free(iph1->rsa_candidates, NULL);
1916 iph1->rsa_candidates = NULL;
1917
1918 if (iph1->rsa == NULL)
1919 goto end;
1920 }
1921
1922 error = 0;
1923
1924 end:
1925 return error;
1926 }
1927
1928 /* get signature */
1929 int
1930 oakley_getsign(iph1)
1931 struct ph1handle *iph1;
1932 {
1933 char path[MAXPATHLEN];
1934 vchar_t *privkey = NULL;
1935 int error = -1;
1936
1937 switch (iph1->rmconf->certtype) {
1938 case ISAKMP_CERT_X509SIGN:
1939 #if defined(__APPLE__)
1940 // cert in keychain - use cssm to sign
1941 if (iph1->rmconf->identity_in_keychain) {
1942 CFDataRef dataRef;
1943
1944 if (iph1->rmconf->keychainCertRef == NULL || base64toCFData(iph1->rmconf->keychainCertRef, &dataRef))
1945 goto end;
1946 iph1->sig = crypto_cssm_getsign(dataRef, iph1->hash);
1947 CFRelease(dataRef);
1948 break;
1949 } // else fall thru
1950 #endif
1951 case ISAKMP_CERT_DNS:
1952 if (iph1->rmconf->myprivfile == NULL) {
1953 plog(LLV_ERROR, LOCATION, NULL, "no cert defined.\n");
1954 goto end;
1955 }
1956
1957 /* make private file name */
1958 getpathname(path, sizeof(path),
1959 LC_PATHTYPE_CERT,
1960 iph1->rmconf->myprivfile);
1961 privkey = privsep_eay_get_pkcs1privkey(path);
1962 if (privkey == NULL) {
1963 plog(LLV_ERROR, LOCATION, NULL,
1964 "failed to get private key.\n");
1965 goto end;
1966 }
1967 plog(LLV_DEBUG2, LOCATION, NULL, "private key:\n");
1968 plogdump(LLV_DEBUG2, privkey->v, privkey->l);
1969
1970 iph1->sig = eay_get_x509sign(iph1->hash, privkey);
1971 break;
1972 case ISAKMP_CERT_PLAINRSA:
1973 iph1->sig = eay_get_rsasign(iph1->hash, iph1->rsa);
1974 break;
1975 default:
1976 plog(LLV_ERROR, LOCATION, NULL,
1977 "Unknown certtype #%d\n",
1978 iph1->rmconf->certtype);
1979 goto end;
1980 }
1981
1982 if (iph1->sig == NULL) {
1983 plog(LLV_ERROR, LOCATION, NULL, "failed to sign.\n");
1984 goto end;
1985 }
1986
1987 plog(LLV_DEBUG, LOCATION, NULL, "SIGN computed:\n");
1988 plogdump(LLV_DEBUG, iph1->sig->v, iph1->sig->l);
1989
1990 error = 0;
1991
1992 end:
1993 if (privkey != NULL)
1994 vfree(privkey);
1995
1996 return error;
1997 }
1998
1999 #ifdef __APPLE__
2000
2001 /*
2002 * compare certificate name and ID value.
2003 */
2004 static int
2005 oakley_check_certid(iph1, which_id)
2006 struct ph1handle *iph1;
2007 int which_id;
2008 {
2009 struct ipsecdoi_id_b *id_b;
2010 int idlen;
2011 u_int8_t doi_type = 255;
2012 void *peers_id = NULL;
2013 struct genlist_entry *gpb = NULL;
2014
2015 if (which_id == CERT_CHECKID_FROM_PEER) {
2016 /* use ID from peer */
2017 if (iph1->id_p == NULL || iph1->cert_p == NULL) {
2018 plog(LLV_ERROR, LOCATION, NULL, "no ID nor CERT found.\n");
2019 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2020 }
2021 id_b = (struct ipsecdoi_id_b *)iph1->id_p->v;
2022 doi_type = id_b->type;
2023 peers_id = id_b + 1;
2024 idlen = iph1->id_p->l - sizeof(*id_b);
2025
2026 return oakley_check_certid_1(iph1, doi_type, idlen, peers_id);
2027
2028 } else {
2029 /* use ID from remote configuration */
2030 /* check each ID in list */
2031 struct idspec *id_spec;
2032
2033 for (id_spec = genlist_next (iph1->rmconf->idvl_p, &gpb); id_spec; id_spec = genlist_next (0, &gpb)) {
2034
2035 if (id_spec->idtype == IDTYPE_ADDRESS) {
2036 switch (((struct sockaddr *)(id_spec->id->v))->sa_family) {
2037 case AF_INET:
2038 doi_type = IPSECDOI_ID_IPV4_ADDR;
2039 idlen = sizeof(struct in_addr);
2040 peers_id = &(((struct sockaddr_in *)(id_spec->id->v))->sin_addr.s_addr);
2041 break;
2042 #ifdef INET6
2043 case AF_INET6:
2044 doi_type = IPSECDOI_ID_IPV6_ADDR;
2045 idlen = sizeof(struct in6_addr);
2046 peers_id = &(((struct sockaddr_in6 *)(id_spec->id->v))->sin6_addr.s6_addr);
2047 break;
2048 #endif
2049 default:
2050 plog(LLV_ERROR, LOCATION, NULL,
2051 "unknown address type for peers identifier.\n");
2052 return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
2053 break;
2054 }
2055
2056 } else {
2057 doi_type = idtype2doi(id_spec->idtype);
2058 peers_id = id_spec->id->v;
2059 idlen = id_spec->id->l;
2060 }
2061 if (oakley_check_certid_1(iph1, doi_type, idlen, peers_id) == 0)
2062 return 0;
2063 }
2064 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2065 }
2066 }
2067
2068 static int
2069 oakley_check_certid_1(iph1, idtype, idlen, id)
2070 struct ph1handle *iph1;
2071 int idtype;
2072 int idlen;
2073 void *id;
2074 {
2075
2076 vchar_t *name = NULL;
2077 char *altname = NULL;
2078 int type, len;
2079 int error;
2080
2081 switch (idtype) {
2082 case IPSECDOI_ID_DER_ASN1_DN:
2083 name = eay_get_x509asn1subjectname(&iph1->cert_p->cert);
2084 if (!name) {
2085 plog(LLV_ERROR, LOCATION, NULL,
2086 "failed to get subjectName\n");
2087 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2088 }
2089 if (idlen != name->l) {
2090 plog(LLV_ERROR, LOCATION, NULL,
2091 "Invalid ID length in phase 1.\n");
2092 vfree(name);
2093 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2094 }
2095 error = memcmp(id, name->v, idlen);
2096 vfree(name);
2097 if (error != 0) {
2098 plog(LLV_ERROR, LOCATION, NULL,
2099 "ID mismatched with subjectName.\n");
2100 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2101 }
2102 return 0;
2103 case IPSECDOI_ID_IPV4_ADDR:
2104 case IPSECDOI_ID_IPV6_ADDR:
2105 {
2106
2107 /*
2108 * Openssl returns the IPAddress as an ASN1 octet string (binary format)
2109 * followed by a trailing NULL. 5 bytes for IPv4 and 17 bytes for IPv6
2110 */
2111 #define SUBJ_ALT_NAME_IPV4_ADDRESS_LEN 5
2112 #define SUBJ_ALT_NAME_IPV6_ADDRESS_LEN 17
2113
2114 int pos;
2115
2116 if (idtype == IPSECDOI_ID_IPV4_ADDR && idlen != sizeof(struct in_addr)
2117 || idtype == IPSECDOI_ID_IPV6_ADDR && idlen != sizeof(struct in6_addr)) {
2118 plog(LLV_ERROR, LOCATION, NULL,
2119 "invalid address length passed.\n");
2120 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2121 }
2122
2123 for (pos = 1; ; pos++) {
2124 if (eay_get_x509subjectaltname(&iph1->cert_p->cert, &altname, &type, pos, &len) !=0) {
2125 plog(LLV_ERROR, LOCATION, NULL,
2126 "failed to get subjectAltName\n");
2127 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2128 }
2129
2130 /* it's the end condition of the loop. */
2131 if (!altname) {
2132 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2133 }
2134
2135 if (check_typeofcertname(idtype, type) != 0) {
2136 /* wrong type - skip this one */
2137 racoon_free(altname);
2138 altname = NULL;
2139 continue;
2140 }
2141
2142 if (len == SUBJ_ALT_NAME_IPV4_ADDRESS_LEN) { /* IPv4 */
2143 if (idtype != IPSECDOI_ID_IPV4_ADDR) {
2144 /* wrong IP address type - skip this one */
2145 racoon_free(altname);
2146 altname = NULL;
2147 continue;
2148 }
2149 }
2150 #ifdef INET6
2151 else if (len == SUBJ_ALT_NAME_IPV6_ADDRESS_LEN) { /* IPv6 */
2152 if (idtype != IPSECDOI_ID_IPV6_ADDR) {
2153 /* wrong IP address type - skip this one */
2154 racoon_free(altname);
2155 altname = NULL;
2156 continue;
2157 }
2158 }
2159 #endif
2160 else {
2161 /* invalid IP address length in certificate - bad or bogus certificate */
2162 plog(LLV_ERROR, LOCATION, NULL,
2163 "invalid IP address in certificate.\n");
2164 racoon_free(altname);
2165 altname = NULL;
2166 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2167 }
2168
2169 /* compare the addresses */
2170 error = memcmp(id, altname, idlen);
2171 racoon_free(altname);
2172 if (error != 0) {
2173 plog(LLV_ERROR, LOCATION, NULL,
2174 "ID mismatched with subjectAltName.\n");
2175 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2176 }
2177 return 0;
2178 }
2179 }
2180 case IPSECDOI_ID_FQDN:
2181 case IPSECDOI_ID_USER_FQDN:
2182 {
2183 int pos;
2184
2185 for (pos = 1; ; pos++) {
2186 if (eay_get_x509subjectaltname(&iph1->cert_p->cert, &altname, &type, pos, &len) != 0) {
2187 plog(LLV_ERROR, LOCATION, NULL,
2188 "failed to get subjectAltName\n");
2189 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2190 }
2191
2192 /* it's the end condition of the loop. */
2193 if (!altname) {
2194 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2195 }
2196
2197 if (check_typeofcertname(idtype, type) != 0) {
2198 /* wrong general type - skip this one */
2199 racoon_free(altname);
2200 altname = NULL;
2201 continue;
2202 }
2203
2204 if (idlen != strlen(altname)) {
2205 /* wrong length - skip this one */
2206 racoon_free(altname);
2207 altname = NULL;
2208 continue;
2209 }
2210 error = memcmp(id, altname, idlen);
2211 racoon_free(altname);
2212 if (error) {
2213 plog(LLV_ERROR, LOCATION, NULL, "ID mismatched.\n");
2214 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2215 }
2216 return 0;
2217 }
2218 }
2219 default:
2220 plog(LLV_ERROR, LOCATION, NULL,
2221 "Impropper ID type passed: %s.\n",
2222 s_ipsecdoi_ident(idtype));
2223 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2224 }
2225 /*NOTREACHED*/
2226 }
2227
2228 #else /* __APPLE__ */
2229
2230 /*
2231 * compare certificate name and ID value.
2232 */
2233 static int
2234 oakley_check_certid(iph1)
2235 struct ph1handle *iph1;
2236 {
2237 struct ipsecdoi_id_b *id_b;
2238 vchar_t *name = NULL;
2239 char *altname = NULL;
2240 int idlen, type;
2241 int error;
2242
2243 if (iph1->id_p == NULL || iph1->cert_p == NULL) {
2244 plog(LLV_ERROR, LOCATION, NULL, "no ID nor CERT found.\n");
2245 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2246 }
2247
2248 id_b = (struct ipsecdoi_id_b *)iph1->id_p->v;
2249 idlen = iph1->id_p->l - sizeof(*id_b);
2250
2251 switch (id_b->type) {
2252 case IPSECDOI_ID_DER_ASN1_DN:
2253 name = eay_get_x509asn1subjectname(&iph1->cert_p->cert);
2254 if (!name) {
2255 plog(LLV_ERROR, LOCATION, NULL,
2256 "failed to get subjectName\n");
2257 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2258 }
2259 if (idlen != name->l) {
2260 plog(LLV_ERROR, LOCATION, NULL,
2261 "Invalid ID length in phase 1.\n");
2262 vfree(name);
2263 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2264 }
2265 error = memcmp(id_b + 1, name->v, idlen);
2266 vfree(name);
2267 if (error != 0) {
2268 plog(LLV_ERROR, LOCATION, NULL,
2269 "ID mismatched with ASN1 SubjectName.\n");
2270 plogdump(LLV_DEBUG, id_b + 1, idlen);
2271 plogdump(LLV_DEBUG, name->v, idlen);
2272 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2273 }
2274 return 0;
2275 case IPSECDOI_ID_IPV4_ADDR:
2276 case IPSECDOI_ID_IPV6_ADDR:
2277 {
2278 /*
2279 * converting to binary from string because openssl return
2280 * a string even if object is a binary.
2281 * XXX fix it ! access by ASN.1 directly without.
2282 */
2283 struct addrinfo hints, *res;
2284 caddr_t a = NULL;
2285 int pos;
2286
2287 for (pos = 1; ; pos++) {
2288 if (eay_get_x509subjectaltname(&iph1->cert_p->cert,
2289 &altname, &type, pos) !=0) {
2290 plog(LLV_ERROR, LOCATION, NULL,
2291 "failed to get subjectAltName\n");
2292 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2293 }
2294
2295 /* it's the end condition of the loop. */
2296 if (!altname) {
2297 plog(LLV_ERROR, LOCATION, NULL,
2298 "no proper subjectAltName.\n");
2299 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2300 }
2301
2302 if (check_typeofcertname(id_b->type, type) == 0)
2303 break;
2304
2305 /* next name */
2306 racoon_free(altname);
2307 altname = NULL;
2308 }
2309 memset(&hints, 0, sizeof(hints));
2310 hints.ai_family = PF_UNSPEC;
2311 hints.ai_socktype = SOCK_RAW;
2312 hints.ai_flags = AI_NUMERICHOST;
2313 error = getaddrinfo(altname, NULL, &hints, &res);
2314 if (error != 0) {
2315 plog(LLV_ERROR, LOCATION, NULL,
2316 "no proper subjectAltName.\n");
2317 racoon_free(altname);
2318 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2319 }
2320 switch (res->ai_family) {
2321 case AF_INET:
2322 a = (caddr_t)&((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr;
2323 break;
2324 #ifdef INET6
2325 case AF_INET6:
2326 a = (caddr_t)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr.s6_addr;
2327 break;
2328 #endif
2329 default:
2330 plog(LLV_ERROR, LOCATION, NULL,
2331 "family not supported: %d.\n", res->ai_family);
2332 racoon_free(altname);
2333 freeaddrinfo(res);
2334 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2335 }
2336 error = memcmp(id_b + 1, a, idlen);
2337 freeaddrinfo(res);
2338 vfree(name);
2339 if (error != 0) {
2340 plog(LLV_ERROR, LOCATION, NULL,
2341 "ID mismatched with subjectAltName.\n");
2342 plogdump(LLV_DEBUG, id_b + 1, idlen);
2343 plogdump(LLV_DEBUG, a, idlen);
2344 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2345 }
2346 return 0;
2347 }
2348 case IPSECDOI_ID_FQDN:
2349 case IPSECDOI_ID_USER_FQDN:
2350 {
2351 int pos;
2352
2353 for (pos = 1; ; pos++) {
2354 if (eay_get_x509subjectaltname(&iph1->cert_p->cert,
2355 &altname, &type, pos) != 0){
2356 plog(LLV_ERROR, LOCATION, NULL,
2357 "failed to get subjectAltName\n");
2358 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2359 }
2360
2361 /* it's the end condition of the loop. */
2362 if (!altname) {
2363 plog(LLV_ERROR, LOCATION, NULL,
2364 "no proper subjectAltName.\n");
2365 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2366 }
2367
2368 if (check_typeofcertname(id_b->type, type) == 0)
2369 break;
2370
2371 /* next name */
2372 racoon_free(altname);
2373 altname = NULL;
2374 }
2375 if (idlen != strlen(altname)) {
2376 plog(LLV_ERROR, LOCATION, NULL,
2377 "Invalid ID length in phase 1.\n");
2378 racoon_free(altname);
2379 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2380 }
2381 if (check_typeofcertname(id_b->type, type) != 0) {
2382 plog(LLV_ERROR, LOCATION, NULL,
2383 "ID type mismatched. ID: %s CERT: %s.\n",
2384 s_ipsecdoi_ident(id_b->type),
2385 s_ipsecdoi_ident(type));
2386 racoon_free(altname);
2387 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2388 }
2389 error = memcmp(id_b + 1, altname, idlen);
2390 if (error) {
2391 plog(LLV_ERROR, LOCATION, NULL, "ID mismatched.\n");
2392 plogdump(LLV_DEBUG, id_b + 1, idlen);
2393 plogdump(LLV_DEBUG, altname, idlen);
2394 racoon_free(altname);
2395 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2396 }
2397 racoon_free(altname);
2398 return 0;
2399 }
2400 default:
2401 plog(LLV_ERROR, LOCATION, NULL,
2402 "Impropper ID type passed: %s.\n",
2403 s_ipsecdoi_ident(id_b->type));
2404 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2405 }
2406 /*NOTREACHED*/
2407 }
2408
2409 #endif /* __APPLE__ */
2410
2411 static int
2412 check_typeofcertname(doi, genid)
2413 int doi, genid;
2414 {
2415 switch (doi) {
2416 case IPSECDOI_ID_IPV4_ADDR:
2417 case IPSECDOI_ID_IPV4_ADDR_SUBNET:
2418 case IPSECDOI_ID_IPV6_ADDR:
2419 case IPSECDOI_ID_IPV6_ADDR_SUBNET:
2420 case IPSECDOI_ID_IPV4_ADDR_RANGE:
2421 case IPSECDOI_ID_IPV6_ADDR_RANGE:
2422 if (genid != GENT_IPADD)
2423 return -1;
2424 return 0;
2425 case IPSECDOI_ID_FQDN:
2426 if (genid != GENT_DNS)
2427 return -1;
2428 return 0;
2429 case IPSECDOI_ID_USER_FQDN:
2430 if (genid != GENT_EMAIL)
2431 return -1;
2432 return 0;
2433 case IPSECDOI_ID_DER_ASN1_DN: /* should not be passed to this function*/
2434 case IPSECDOI_ID_DER_ASN1_GN:
2435 case IPSECDOI_ID_KEY_ID:
2436 default:
2437 return -1;
2438 }
2439 /*NOTREACHED*/
2440 }
2441
2442 /*
2443 * save certificate including certificate type.
2444 */
2445 int
2446 oakley_savecert(iph1, gen)
2447 struct ph1handle *iph1;
2448 struct isakmp_gen *gen;
2449 {
2450 cert_t **c;
2451 u_int8_t type;
2452 STACK_OF(X509) *certs=NULL;
2453 PKCS7 *p7;
2454
2455 type = *(u_int8_t *)(gen + 1) & 0xff;
2456
2457 switch (type) {
2458 case ISAKMP_CERT_DNS:
2459 plog(LLV_WARNING, LOCATION, NULL,
2460 "CERT payload is unnecessary in DNSSEC. "
2461 "ignore this CERT payload.\n");
2462 return 0;
2463 case ISAKMP_CERT_PKCS7:
2464 case ISAKMP_CERT_PGP:
2465 case ISAKMP_CERT_X509SIGN:
2466 case ISAKMP_CERT_KERBEROS:
2467 case ISAKMP_CERT_SPKI:
2468 c = &iph1->cert_p;
2469 break;
2470 case ISAKMP_CERT_CRL:
2471 c = &iph1->crl_p;
2472 break;
2473 case ISAKMP_CERT_X509KE:
2474 case ISAKMP_CERT_X509ATTR:
2475 case ISAKMP_CERT_ARL:
2476 plog(LLV_ERROR, LOCATION, NULL,
2477 "No supported such CERT type %d\n", type);
2478 return -1;
2479 default:
2480 plog(LLV_ERROR, LOCATION, NULL,
2481 "Invalid CERT type %d\n", type);
2482 return -1;
2483 }
2484
2485 /* XXX choice the 1th cert, ignore after the cert. */
2486 /* XXX should be processed. */
2487 if (*c) {
2488 plog(LLV_WARNING, LOCATION, NULL,
2489 "ignore 2nd CERT payload.\n");
2490 return 0;
2491 }
2492
2493 if (type == ISAKMP_CERT_PKCS7) {
2494 u_char *bp;
2495 int i;
2496
2497 /* Skip the header */
2498 bp = (u_char *)(gen + 1);
2499 /* And the first byte is the certificate type,
2500 * we know that already
2501 */
2502 bp++;
2503 p7 = d2i_PKCS7(NULL, (void *)&bp,
2504 ntohs(gen->len) - sizeof(*gen) - 1);
2505
2506 if (!p7) {
2507 plog(LLV_ERROR, LOCATION, NULL,
2508 "Failed to parse PKCS#7 CERT.\n");
2509 return -1;
2510 }
2511
2512 /* Copied this from the openssl pkcs7 application;
2513 * there"s little by way of documentation for any of
2514 * it. I can only presume it"s correct.
2515 */
2516
2517 i = OBJ_obj2nid(p7->type);
2518 switch (i) {
2519 case NID_pkcs7_signed:
2520 certs=p7->d.sign->cert;
2521 break;
2522 case NID_pkcs7_signedAndEnveloped:
2523 certs=p7->d.signed_and_enveloped->cert;
2524 break;
2525 default:
2526 break;
2527 }
2528
2529 if (!certs) {
2530 plog(LLV_ERROR, LOCATION, NULL,
2531 "CERT PKCS#7 bundle contains no certs.\n");
2532 PKCS7_free(p7);
2533 return -1;
2534 }
2535
2536 for (i = 0; i < sk_X509_num(certs); i++) {
2537 int len;
2538 u_char *bp;
2539 X509 *cert = sk_X509_value(certs,i);
2540
2541 plog(LLV_DEBUG, LOCATION, NULL,
2542 "Trying PKCS#7 cert %d.\n", i);
2543
2544 /* We'll just try each cert in turn */
2545 *c = save_certx509(cert);
2546
2547 if (!*c) {
2548 plog(LLV_ERROR, LOCATION, NULL,
2549 "Failed to get CERT buffer.\n");
2550 continue;
2551 }
2552
2553 /* Ignore cert if it doesn't match identity
2554 * XXX If verify cert is disabled, we still just take
2555 * the first certificate....
2556 */
2557 if(iph1->rmconf->verify_cert &&
2558 oakley_check_certid(iph1, CERT_CHECKID_FROM_PEER)) {
2559 plog(LLV_DEBUG, LOCATION, NULL,
2560 "Discarding CERT: does not match ID.\n");
2561 oakley_delcert((*c));
2562 *c = NULL;
2563 continue;
2564 }
2565
2566 {
2567 char *p = eay_get_x509text(&(*c)->cert);
2568 plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
2569 plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
2570 plog(LLV_DEBUG, LOCATION, NULL, "%s",
2571 p ? p : "\n");
2572 racoon_free(p);
2573 }
2574 break;
2575 }
2576 PKCS7_free(p7);
2577
2578 } else {
2579 *c = save_certbuf(gen);
2580 if (!*c) {
2581 plog(LLV_ERROR, LOCATION, NULL,
2582 "Failed to get CERT buffer.\n");
2583 return -1;
2584 }
2585
2586 switch ((*c)->type) {
2587 case ISAKMP_CERT_DNS:
2588 plog(LLV_WARNING, LOCATION, NULL,
2589 "CERT payload is unnecessary in DNSSEC. "
2590 "ignore it.\n");
2591 return 0;
2592 case ISAKMP_CERT_PGP:
2593 case ISAKMP_CERT_X509SIGN:
2594 case ISAKMP_CERT_KERBEROS:
2595 case ISAKMP_CERT_SPKI:
2596 /* Ignore cert if it doesn't match identity
2597 * XXX If verify cert is disabled, we still just take
2598 * the first certificate....
2599 */
2600 if(iph1->rmconf->verify_cert &&
2601 oakley_check_certid(iph1, CERT_CHECKID_FROM_PEER)){
2602 plog(LLV_DEBUG, LOCATION, NULL,
2603 "Discarding CERT: does not match ID.\n");
2604 oakley_delcert((*c));
2605 *c = NULL;
2606 return 0;
2607 }
2608
2609 {
2610 char *p = eay_get_x509text(&(*c)->cert);
2611 plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
2612 plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
2613 plog(LLV_DEBUG, LOCATION, NULL, "%s", p ? p : "\n");
2614 racoon_free(p);
2615 }
2616 break;
2617 case ISAKMP_CERT_CRL:
2618 plog(LLV_DEBUG, LOCATION, NULL, "CRL saved:\n");
2619 plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
2620 break;
2621 case ISAKMP_CERT_X509KE:
2622 case ISAKMP_CERT_X509ATTR:
2623 case ISAKMP_CERT_ARL:
2624 default:
2625 /* XXX */
2626 oakley_delcert((*c));
2627 *c = NULL;
2628 return 0;
2629 }
2630 }
2631
2632 return 0;
2633 }
2634
2635 /*
2636 * save certificate including certificate type.
2637 */
2638 int
2639 oakley_savecr(iph1, gen)
2640 struct ph1handle *iph1;
2641 struct isakmp_gen *gen;
2642 {
2643 cert_t **c;
2644 u_int8_t type;
2645
2646 type = *(u_int8_t *)(gen + 1) & 0xff;
2647
2648 switch (type) {
2649 case ISAKMP_CERT_DNS:
2650 plog(LLV_WARNING, LOCATION, NULL,
2651 "CERT payload is unnecessary in DNSSEC\n");
2652 /*FALLTHRU*/
2653 case ISAKMP_CERT_PKCS7:
2654 case ISAKMP_CERT_PGP:
2655 case ISAKMP_CERT_X509SIGN:
2656 case ISAKMP_CERT_KERBEROS:
2657 case ISAKMP_CERT_SPKI:
2658 c = &iph1->cr_p;
2659 break;
2660 case ISAKMP_CERT_X509KE:
2661 case ISAKMP_CERT_X509ATTR:
2662 case ISAKMP_CERT_ARL:
2663 plog(LLV_ERROR, LOCATION, NULL,
2664 "No supported such CR type %d\n", type);
2665 return -1;
2666 case ISAKMP_CERT_CRL:
2667 default:
2668 plog(LLV_ERROR, LOCATION, NULL,
2669 "Invalid CR type %d\n", type);
2670 return -1;
2671 }
2672
2673 *c = save_certbuf(gen);
2674 if (!*c) {
2675 plog(LLV_ERROR, LOCATION, NULL,
2676 "Failed to get CR buffer.\n");
2677 return -1;
2678 }
2679
2680 plog(LLV_DEBUG, LOCATION, NULL, "CR saved:\n");
2681 plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
2682
2683 return 0;
2684 }
2685
2686 static cert_t *
2687 save_certbuf(gen)
2688 struct isakmp_gen *gen;
2689 {
2690 cert_t *new;
2691
2692 if(ntohs(gen->len) <= sizeof(*gen)){
2693 plog(LLV_ERROR, LOCATION, NULL,
2694 "Len is too small !!.\n");
2695 return NULL;
2696 }
2697
2698 new = oakley_newcert();
2699 if (!new) {
2700 plog(LLV_ERROR, LOCATION, NULL,
2701 "Failed to get CERT buffer.\n");
2702 return NULL;
2703 }
2704
2705 new->pl = vmalloc(ntohs(gen->len) - sizeof(*gen));
2706 if (new->pl == NULL) {
2707 plog(LLV_ERROR, LOCATION, NULL,
2708 "Failed to copy CERT from packet.\n");
2709 oakley_delcert(new);
2710 new = NULL;
2711 return NULL;
2712 }
2713 memcpy(new->pl->v, gen + 1, new->pl->l);
2714 new->type = new->pl->v[0] & 0xff;
2715 new->cert.v = new->pl->v + 1;
2716 new->cert.l = new->pl->l - 1;
2717
2718 return new;
2719 }
2720
2721 static cert_t *
2722 save_certx509(cert)
2723 X509 *cert;
2724 {
2725 cert_t *new;
2726 int len;
2727 u_char *bp;
2728
2729 new = oakley_newcert();
2730 if (!new) {
2731 plog(LLV_ERROR, LOCATION, NULL,
2732 "Failed to get CERT buffer.\n");
2733 return NULL;
2734 }
2735
2736 len = i2d_X509(cert, NULL);
2737 new->pl = vmalloc(len);
2738 if (new->pl == NULL) {
2739 plog(LLV_ERROR, LOCATION, NULL,
2740 "Failed to copy CERT from packet.\n");
2741 oakley_delcert(new);
2742 new = NULL;
2743 return NULL;
2744 }
2745 bp = (u_char *) new->pl->v;
2746 len = i2d_X509(cert, &bp);
2747 new->type = ISAKMP_CERT_X509SIGN;
2748 new->cert.v = new->pl->v;
2749 new->cert.l = new->pl->l;
2750
2751 return new;
2752 }
2753
2754 /*
2755 * get my CR.
2756 * NOTE: No Certificate Authority field is included to CR payload at the
2757 * moment. Becuase any certificate authority are accepted without any check.
2758 * The section 3.10 in RFC2408 says that this field SHOULD not be included,
2759 * if there is no specific certificate authority requested.
2760 */
2761 vchar_t *
2762 oakley_getcr(iph1)
2763 struct ph1handle *iph1;
2764 {
2765 vchar_t *buf;
2766
2767 buf = vmalloc(1);
2768 if (buf == NULL) {
2769 plog(LLV_ERROR, LOCATION, NULL,
2770 "failed to get cr buffer\n");
2771 return NULL;
2772 }
2773 if(iph1->rmconf->certtype == ISAKMP_CERT_NONE) {
2774 buf->v[0] = iph1->rmconf->cacerttype;
2775 plog(LLV_DEBUG, LOCATION, NULL, "create my CR: NONE, using %s instead\n",
2776 s_isakmp_certtype(iph1->rmconf->cacerttype));
2777 } else {
2778 buf->v[0] = iph1->rmconf->certtype;
2779 plog(LLV_DEBUG, LOCATION, NULL, "create my CR: %s\n",
2780 s_isakmp_certtype(iph1->rmconf->certtype));
2781 }
2782 if (buf->l > 1)
2783 plogdump(LLV_DEBUG, buf->v, buf->l);
2784
2785 return buf;
2786 }
2787
2788 /*
2789 * check peer's CR.
2790 */
2791 int
2792 oakley_checkcr(iph1)
2793 struct ph1handle *iph1;
2794 {
2795 if (iph1->cr_p == NULL)
2796 return 0;
2797
2798 plog(LLV_DEBUG, LOCATION, iph1->remote,
2799 "peer transmitted CR: %s\n",
2800 s_isakmp_certtype(iph1->cr_p->type));
2801
2802 if (iph1->cr_p->type != iph1->rmconf->certtype) {
2803 plog(LLV_ERROR, LOCATION, iph1->remote,
2804 "such a cert type isn't supported: %d\n",
2805 (char)iph1->cr_p->type);
2806 return -1;
2807 }
2808
2809 return 0;
2810 }
2811
2812 /*
2813 * check to need CR payload.
2814 */
2815 int
2816 oakley_needcr(type)
2817 int type;
2818 {
2819 switch (type) {
2820 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
2821 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
2822 #ifdef ENABLE_HYBRID
2823 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
2824 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
2825 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
2826 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
2827 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
2828 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
2829 #endif
2830 return 1;
2831 default:
2832 return 0;
2833 }
2834 /*NOTREACHED*/
2835 }
2836
2837 /*
2838 * compute SKEYID
2839 * see seciton 5. Exchanges in RFC 2409
2840 * psk: SKEYID = prf(pre-shared-key, Ni_b | Nr_b)
2841 * sig: SKEYID = prf(Ni_b | Nr_b, g^ir)
2842 * enc: SKEYID = prf(H(Ni_b | Nr_b), CKY-I | CKY-R)
2843 */
2844 int
2845 oakley_skeyid(iph1)
2846 struct ph1handle *iph1;
2847 {
2848 vchar_t *buf = NULL, *bp;
2849 char *p;
2850 int len;
2851 int error = -1;
2852
2853 /* SKEYID */
2854 switch (AUTHMETHOD(iph1)) {
2855 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
2856 #ifdef ENABLE_HYBRID
2857 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
2858 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
2859 #endif
2860 #ifdef __APPLE__
2861 if (iph1->rmconf->shared_secret) {
2862
2863 switch (iph1->rmconf->secrettype) {
2864 case SECRETTYPE_KEY:
2865 /* in psk file - use KEY from remote configuration to locate it */
2866 iph1->authstr = getpsk(iph1->rmconf->shared_secret->v, iph1->rmconf->shared_secret->l-1);
2867 break;
2868 #if HAVE_KEYCHAIN
2869 case SECRETTYPE_KEYCHAIN:
2870 /* in the system keychain */
2871 iph1->authstr = getpskfromkeychain(iph1->rmconf->shared_secret->v, iph1->etype, iph1->rmconf->secrettype, NULL);
2872 break;
2873 case SECRETTYPE_KEYCHAIN_BY_ID:
2874 /* in the system keychain - use peer id */
2875 iph1->authstr = getpskfromkeychain(iph1->rmconf->shared_secret->v, iph1->etype, iph1->rmconf->secrettype, iph1->id_p);
2876 break;
2877 #endif HAVE_KEYCHAIN
2878 case SECRETTYPE_USE:
2879 /* in the remote configuration */
2880 default:
2881 iph1->authstr = vdup(iph1->rmconf->shared_secret);
2882 }
2883
2884 }
2885 else
2886 #endif
2887 if (iph1->etype != ISAKMP_ETYPE_IDENT) {
2888 iph1->authstr = getpskbyname(iph1->id_p);
2889 if (iph1->authstr == NULL) {
2890 if (iph1->rmconf->verify_identifier) {
2891 plog(LLV_ERROR, LOCATION, iph1->remote,
2892 "couldn't find the pskey.\n");
2893 goto end;
2894 }
2895 plog(LLV_NOTIFY, LOCATION, iph1->remote,
2896 "couldn't find the proper pskey, "
2897 "try to get one by the peer's address.\n");
2898 }
2899 }
2900 if (iph1->authstr == NULL) {
2901 /*
2902 * If the exchange type is the main mode or if it's
2903 * failed to get the psk by ID, racoon try to get
2904 * the psk by remote IP address.
2905 * It may be nonsense.
2906 */
2907 iph1->authstr = getpskbyaddr(iph1->remote);
2908 if (iph1->authstr == NULL) {
2909 plog(LLV_ERROR, LOCATION, iph1->remote,
2910 "couldn't find the pskey for %s.\n",
2911 saddrwop2str(iph1->remote));
2912 goto end;
2913 }
2914 }
2915 plog(LLV_DEBUG, LOCATION, NULL, "the psk found.\n");
2916 /* should be secret PSK */
2917 plog(LLV_DEBUG2, LOCATION, NULL, "psk: ");
2918 plogdump(LLV_DEBUG2, iph1->authstr->v, iph1->authstr->l);
2919
2920 len = iph1->nonce->l + iph1->nonce_p->l;
2921 buf = vmalloc(len);
2922 if (buf == NULL) {
2923 plog(LLV_ERROR, LOCATION, NULL,
2924 "failed to get skeyid buffer\n");
2925 goto end;
2926 }
2927 p = buf->v;
2928
2929 bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p);
2930 plog(LLV_DEBUG, LOCATION, NULL, "nonce 1: ");
2931 plogdump(LLV_DEBUG, bp->v, bp->l);
2932 memcpy(p, bp->v, bp->l);
2933 p += bp->l;
2934
2935 bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce);
2936 plog(LLV_DEBUG, LOCATION, NULL, "nonce 2: ");
2937 plogdump(LLV_DEBUG, bp->v, bp->l);
2938 memcpy(p, bp->v, bp->l);
2939 p += bp->l;
2940
2941 iph1->skeyid = oakley_prf(iph1->authstr, buf, iph1);
2942 if (iph1->skeyid == NULL)
2943 goto end;
2944 break;
2945
2946 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
2947 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
2948 #ifdef ENABLE_HYBRID
2949 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
2950 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
2951 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
2952 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
2953 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
2954 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
2955 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
2956 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
2957 #endif
2958 #ifdef HAVE_GSSAPI
2959 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
2960 #endif
2961 len = iph1->nonce->l + iph1->nonce_p->l;
2962 buf = vmalloc(len);
2963 if (buf == NULL) {
2964 plog(LLV_ERROR, LOCATION, NULL,
2965 "failed to get nonce buffer\n");
2966 goto end;
2967 }
2968 p = buf->v;
2969
2970 bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p);
2971 plog(LLV_DEBUG, LOCATION, NULL, "nonce1: ");
2972 plogdump(LLV_DEBUG, bp->v, bp->l);
2973 memcpy(p, bp->v, bp->l);
2974 p += bp->l;
2975
2976 bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce);
2977 plog(LLV_DEBUG, LOCATION, NULL, "nonce2: ");
2978 plogdump(LLV_DEBUG, bp->v, bp->l);
2979 memcpy(p, bp->v, bp->l);
2980 p += bp->l;
2981
2982 iph1->skeyid = oakley_prf(buf, iph1->dhgxy, iph1);
2983 if (iph1->skeyid == NULL)
2984 goto end;
2985 break;
2986 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
2987 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
2988 #ifdef ENABLE_HYBRID
2989 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
2990 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
2991 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
2992 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
2993 #endif
2994 plog(LLV_WARNING, LOCATION, NULL,
2995 "not supported authentication method %s\n",
2996 s_oakley_attr_method(iph1->approval->authmethod));
2997 goto end;
2998 default:
2999 plog(LLV_ERROR, LOCATION, NULL,
3000 "invalid authentication method %d\n",
3001 iph1->approval->authmethod);
3002 goto end;
3003 }
3004
3005 plog(LLV_DEBUG, LOCATION, NULL, "SKEYID computed:\n");
3006 plogdump(LLV_DEBUG, iph1->skeyid->v, iph1->skeyid->l);
3007
3008 error = 0;
3009
3010 end:
3011 if (buf != NULL)
3012 vfree(buf);
3013 return error;
3014 }
3015
3016 /*
3017 * compute SKEYID_[dae]
3018 * see seciton 5. Exchanges in RFC 2409
3019 * SKEYID_d = prf(SKEYID, g^ir | CKY-I | CKY-R | 0)
3020 * SKEYID_a = prf(SKEYID, SKEYID_d | g^ir | CKY-I | CKY-R | 1)
3021 * SKEYID_e = prf(SKEYID, SKEYID_a | g^ir | CKY-I | CKY-R | 2)
3022 */
3023 int
3024 oakley_skeyid_dae(iph1)
3025 struct ph1handle *iph1;
3026 {
3027 vchar_t *buf = NULL;
3028 char *p;
3029 int len;
3030 int error = -1;
3031
3032 if (iph1->skeyid == NULL) {
3033 plog(LLV_ERROR, LOCATION, NULL, "no SKEYID found.\n");
3034 goto end;
3035 }
3036
3037 /* SKEYID D */
3038 /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
3039 len = iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
3040 buf = vmalloc(len);
3041 if (buf == NULL) {
3042 plog(LLV_ERROR, LOCATION, NULL,
3043 "failed to get skeyid buffer\n");
3044 goto end;
3045 }
3046 p = buf->v;
3047
3048 memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l);
3049 p += iph1->dhgxy->l;
3050 memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t));
3051 p += sizeof(cookie_t);
3052 memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t));
3053 p += sizeof(cookie_t);
3054 *p = 0;
3055 iph1->skeyid_d = oakley_prf(iph1->skeyid, buf, iph1);
3056 if (iph1->skeyid_d == NULL)
3057 goto end;
3058
3059 vfree(buf);
3060 buf = NULL;
3061
3062 plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_d computed:\n");
3063 plogdump(LLV_DEBUG, iph1->skeyid_d->v, iph1->skeyid_d->l);
3064
3065 /* SKEYID A */
3066 /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
3067 len = iph1->skeyid_d->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
3068 buf = vmalloc(len);
3069 if (buf == NULL) {
3070 plog(LLV_ERROR, LOCATION, NULL,
3071 "failed to get skeyid buffer\n");
3072 goto end;
3073 }
3074 p = buf->v;
3075 memcpy(p, iph1->skeyid_d->v, iph1->skeyid_d->l);
3076 p += iph1->skeyid_d->l;
3077 memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l);
3078 p += iph1->dhgxy->l;
3079 memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t));
3080 p += sizeof(cookie_t);
3081 memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t));
3082 p += sizeof(cookie_t);
3083 *p = 1;
3084 iph1->skeyid_a = oakley_prf(iph1->skeyid, buf, iph1);
3085 if (iph1->skeyid_a == NULL)
3086 goto end;
3087
3088 vfree(buf);
3089 buf = NULL;
3090
3091 plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_a computed:\n");
3092 plogdump(LLV_DEBUG, iph1->skeyid_a->v, iph1->skeyid_a->l);
3093
3094 /* SKEYID E */
3095 /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
3096 len = iph1->skeyid_a->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
3097 buf = vmalloc(len);
3098 if (buf == NULL) {
3099 plog(LLV_ERROR, LOCATION, NULL,
3100 "failed to get skeyid buffer\n");
3101 goto end;
3102 }
3103 p = buf->v;
3104 memcpy(p, iph1->skeyid_a->v, iph1->skeyid_a->l);
3105 p += iph1->skeyid_a->l;
3106 memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l);
3107 p += iph1->dhgxy->l;
3108 memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t));
3109 p += sizeof(cookie_t);
3110 memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t));
3111 p += sizeof(cookie_t);
3112 *p = 2;
3113 iph1->skeyid_e = oakley_prf(iph1->skeyid, buf, iph1);
3114 if (iph1->skeyid_e == NULL)
3115 goto end;
3116
3117 vfree(buf);
3118 buf = NULL;
3119
3120 plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_e computed:\n");
3121 plogdump(LLV_DEBUG, iph1->skeyid_e->v, iph1->skeyid_e->l);
3122
3123 error = 0;
3124
3125 end:
3126 if (buf != NULL)
3127 vfree(buf);
3128 return error;
3129 }
3130
3131 /*
3132 * compute final encryption key.
3133 * see Appendix B.
3134 */
3135 int
3136 oakley_compute_enckey(iph1)
3137 struct ph1handle *iph1;
3138 {
3139 u_int keylen, prflen;
3140 int error = -1;
3141
3142 /* RFC2409 p39 */
3143 keylen = alg_oakley_encdef_keylen(iph1->approval->enctype,
3144 iph1->approval->encklen);
3145 if (keylen == -1) {
3146 plog(LLV_ERROR, LOCATION, NULL,
3147 "invalid encryption algoritym %d, "
3148 "or invalid key length %d.\n",
3149 iph1->approval->enctype,
3150 iph1->approval->encklen);
3151 goto end;
3152 }
3153 iph1->key = vmalloc(keylen >> 3);
3154 if (iph1->key == NULL) {
3155 plog(LLV_ERROR, LOCATION, NULL,
3156 "failed to get key buffer\n");
3157 goto end;
3158 }
3159
3160 /* set prf length */
3161 prflen = alg_oakley_hashdef_hashlen(iph1->approval->hashtype);
3162 if (prflen == -1) {
3163 plog(LLV_ERROR, LOCATION, NULL,
3164 "invalid hash type %d.\n", iph1->approval->hashtype);
3165 goto end;
3166 }
3167
3168 /* see isakmp-oakley-08 5.3. */
3169 if (iph1->key->l <= iph1->skeyid_e->l) {
3170 /*
3171 * if length(Ka) <= length(SKEYID_e)
3172 * Ka = first length(K) bit of SKEYID_e
3173 */
3174 memcpy(iph1->key->v, iph1->skeyid_e->v, iph1->key->l);
3175 } else {
3176 vchar_t *buf = NULL, *res = NULL;
3177 u_char *p, *ep;
3178 int cplen;
3179 int subkey;
3180
3181 /*
3182 * otherwise,
3183 * Ka = K1 | K2 | K3
3184 * where
3185 * K1 = prf(SKEYID_e, 0)
3186 * K2 = prf(SKEYID_e, K1)
3187 * K3 = prf(SKEYID_e, K2)
3188 */
3189 plog(LLV_DEBUG, LOCATION, NULL,
3190 "len(SKEYID_e) < len(Ka) (%zu < %zu), "
3191 "generating long key (Ka = K1 | K2 | ...)\n",
3192 iph1->skeyid_e->l, iph1->key->l);
3193
3194 if ((buf = vmalloc(prflen >> 3)) == 0) {
3195 plog(LLV_ERROR, LOCATION, NULL,
3196 "failed to get key buffer\n");
3197 goto end;
3198 }
3199 p = (u_char *)iph1->key->v;
3200 ep = p + iph1->key->l;
3201
3202 subkey = 1;
3203 while (p < ep) {
3204 if (p == (u_char *)iph1->key->v) {
3205 /* just for computing K1 */
3206 buf->v[0] = 0;
3207 buf->l = 1;
3208 }
3209 res = oakley_prf(iph1->skeyid_e, buf, iph1);
3210 if (res == NULL) {
3211 vfree(buf);
3212 goto end;
3213 }
3214 plog(LLV_DEBUG, LOCATION, NULL,
3215 "compute intermediate encryption key K%d\n",
3216 subkey);
3217 plogdump(LLV_DEBUG, buf->v, buf->l);
3218 plogdump(LLV_DEBUG, res->v, res->l);
3219
3220 cplen = (res->l < ep - p) ? res->l : ep - p;
3221 memcpy(p, res->v, cplen);
3222 p += cplen;
3223
3224 buf->l = prflen >> 3; /* to cancel K1 speciality */
3225 if (res->l != buf->l) {
3226 plog(LLV_ERROR, LOCATION, NULL,
3227 "internal error: res->l=%zu buf->l=%zu\n",
3228 res->l, buf->l);
3229 vfree(res);
3230 vfree(buf);
3231 goto end;
3232 }
3233 memcpy(buf->v, res->v, res->l);
3234 vfree(res);
3235 subkey++;
3236 }
3237
3238 vfree(buf);
3239 }
3240
3241 /*
3242 * don't check any weak key or not.
3243 * draft-ietf-ipsec-ike-01.txt Appendix B.
3244 * draft-ietf-ipsec-ciph-aes-cbc-00.txt Section 2.3.
3245 */
3246 #if 0
3247 /* weakkey check */
3248 if (iph1->approval->enctype > ARRAYLEN(oakley_encdef)
3249 || oakley_encdef[iph1->approval->enctype].weakkey == NULL) {
3250 plog(LLV_ERROR, LOCATION, NULL,
3251 "encryption algoritym %d isn't supported.\n",
3252 iph1->approval->enctype);
3253 goto end;
3254 }
3255 if ((oakley_encdef[iph1->approval->enctype].weakkey)(iph1->key)) {
3256 plog(LLV_ERROR, LOCATION, NULL,
3257 "weakkey was generated.\n");
3258 goto end;
3259 }
3260 #endif
3261
3262 plog(LLV_DEBUG, LOCATION, NULL, "final encryption key computed:\n");
3263 plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
3264
3265 error = 0;
3266
3267 end:
3268 return error;
3269 }
3270
3271 /* allocated new buffer for CERT */
3272 cert_t *
3273 oakley_newcert()
3274 {
3275 cert_t *new;
3276
3277 new = racoon_calloc(1, sizeof(*new));
3278 if (new == NULL) {
3279 plog(LLV_ERROR, LOCATION, NULL,
3280 "failed to get cert's buffer\n");
3281 return NULL;
3282 }
3283
3284 new->pl = NULL;
3285
3286 return new;
3287 }
3288
3289 /* delete buffer for CERT */
3290 void
3291 oakley_delcert(cert)
3292 cert_t *cert;
3293 {
3294 if (!cert)
3295 return;
3296 if (cert->pl)
3297 VPTRINIT(cert->pl);
3298 racoon_free(cert);
3299 }
3300
3301 /*
3302 * compute IV and set to ph1handle
3303 * IV = hash(g^xi | g^xr)
3304 * see 4.1 Phase 1 state in draft-ietf-ipsec-ike.
3305 */
3306 int
3307 oakley_newiv(iph1)
3308 struct ph1handle *iph1;
3309 {
3310 struct isakmp_ivm *newivm = NULL;
3311 vchar_t *buf = NULL, *bp;
3312 char *p;
3313 int len;
3314
3315 /* create buffer */
3316 len = iph1->dhpub->l + iph1->dhpub_p->l;
3317 buf = vmalloc(len);
3318 if (buf == NULL) {
3319 plog(LLV_ERROR, LOCATION, NULL,
3320 "failed to get iv buffer\n");
3321 return -1;
3322 }
3323
3324 p = buf->v;
3325
3326 bp = (iph1->side == INITIATOR ? iph1->dhpub : iph1->dhpub_p);
3327 memcpy(p, bp->v, bp->l);
3328 p += bp->l;
3329
3330 bp = (iph1->side == INITIATOR ? iph1->dhpub_p : iph1->dhpub);
3331 memcpy(p, bp->v, bp->l);
3332 p += bp->l;
3333
3334 /* allocate IVm */
3335 newivm = racoon_calloc(1, sizeof(struct isakmp_ivm));
3336 if (newivm == NULL) {
3337 plog(LLV_ERROR, LOCATION, NULL,
3338 "failed to get iv buffer\n");
3339 vfree(buf);
3340 return -1;
3341 }
3342
3343 /* compute IV */
3344 newivm->iv = oakley_hash(buf, iph1);
3345 if (newivm->iv == NULL) {
3346 vfree(buf);
3347 oakley_delivm(newivm);
3348 return -1;
3349 }
3350
3351 /* adjust length of iv */
3352 newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype);
3353 if (newivm->iv->l == -1) {
3354 plog(LLV_ERROR, LOCATION, NULL,
3355 "invalid encryption algoriym %d.\n",
3356 iph1->approval->enctype);
3357 vfree(buf);
3358 oakley_delivm(newivm);
3359 return -1;
3360 }
3361
3362 /* create buffer to save iv */
3363 if ((newivm->ive = vdup(newivm->iv)) == NULL) {
3364 plog(LLV_ERROR, LOCATION, NULL,
3365 "vdup (%s)\n", strerror(errno));
3366 vfree(buf);
3367 oakley_delivm(newivm);
3368 return -1;
3369 }
3370
3371 vfree(buf);
3372
3373 plog(LLV_DEBUG, LOCATION, NULL, "IV computed:\n");
3374 plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l);
3375
3376 if (iph1->ivm != NULL)
3377 oakley_delivm(iph1->ivm);
3378
3379 iph1->ivm = newivm;
3380
3381 return 0;
3382 }
3383
3384 /*
3385 * compute IV for the payload after phase 1.
3386 * It's not limited for phase 2.
3387 * if pahse 1 was encrypted.
3388 * IV = hash(last CBC block of Phase 1 | M-ID)
3389 * if phase 1 was not encrypted.
3390 * IV = hash(phase 1 IV | M-ID)
3391 * see 4.2 Phase 2 state in draft-ietf-ipsec-ike.
3392 */
3393 struct isakmp_ivm *
3394 oakley_newiv2(iph1, msgid)
3395 struct ph1handle *iph1;
3396 u_int32_t msgid;
3397 {
3398 struct isakmp_ivm *newivm = NULL;
3399 vchar_t *buf = NULL;
3400 char *p;
3401 int len;
3402 int error = -1;
3403
3404 /* create buffer */
3405 len = iph1->ivm->iv->l + sizeof(msgid_t);
3406 buf = vmalloc(len);
3407 if (buf == NULL) {
3408 plog(LLV_ERROR, LOCATION, NULL,
3409 "failed to get iv buffer\n");
3410 goto end;
3411 }
3412
3413 p = buf->v;
3414
3415 memcpy(p, iph1->ivm->iv->v, iph1->ivm->iv->l);
3416 p += iph1->ivm->iv->l;
3417
3418 memcpy(p, &msgid, sizeof(msgid));
3419
3420 plog(LLV_DEBUG, LOCATION, NULL, "compute IV for phase2\n");
3421 plog(LLV_DEBUG, LOCATION, NULL, "phase1 last IV:\n");
3422 plogdump(LLV_DEBUG, buf->v, buf->l);
3423
3424 /* allocate IVm */
3425 newivm = racoon_calloc(1, sizeof(struct isakmp_ivm));
3426 if (newivm == NULL) {
3427 plog(LLV_ERROR, LOCATION, NULL,
3428 "failed to get iv buffer\n");
3429 goto end;
3430 }
3431
3432 /* compute IV */
3433 if ((newivm->iv = oakley_hash(buf, iph1)) == NULL)
3434 goto end;
3435
3436 /* adjust length of iv */
3437 newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype);
3438 if (newivm->iv->l == -1) {
3439 plog(LLV_ERROR, LOCATION, NULL,
3440 "invalid encryption algoriym %d.\n",
3441 iph1->approval->enctype);
3442 goto end;
3443 }
3444
3445 /* create buffer to save new iv */
3446 if ((newivm->ive = vdup(newivm->iv)) == NULL) {
3447 plog(LLV_ERROR, LOCATION, NULL, "vdup (%s)\n", strerror(errno));
3448 goto end;
3449 }
3450
3451 error = 0;
3452
3453 plog(LLV_DEBUG, LOCATION, NULL, "phase2 IV computed:\n");
3454 plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l);
3455
3456 end:
3457 if (error && newivm != NULL){
3458 oakley_delivm(newivm);
3459 newivm=NULL;
3460 }
3461 if (buf != NULL)
3462 vfree(buf);
3463 return newivm;
3464 }
3465
3466 void
3467 oakley_delivm(ivm)
3468 struct isakmp_ivm *ivm;
3469 {
3470 if (ivm == NULL)
3471 return;
3472
3473 if (ivm->iv != NULL)
3474 vfree(ivm->iv);
3475 if (ivm->ive != NULL)
3476 vfree(ivm->ive);
3477 racoon_free(ivm);
3478 plog(LLV_DEBUG, LOCATION, NULL, "IV freed\n");
3479
3480 return;
3481 }
3482
3483 /*
3484 * decrypt packet.
3485 * save new iv and old iv.
3486 */
3487 vchar_t *
3488 oakley_do_decrypt(iph1, msg, ivdp, ivep)
3489 struct ph1handle *iph1;
3490 vchar_t *msg, *ivdp, *ivep;
3491 {
3492 vchar_t *buf = NULL, *new = NULL;
3493 char *pl;
3494 int len;
3495 u_int8_t padlen;
3496 int blen;
3497 int error = -1;
3498
3499 plog(LLV_DEBUG, LOCATION, NULL, "begin decryption.\n");
3500
3501 blen = alg_oakley_encdef_blocklen(iph1->approval->enctype);
3502 if (blen == -1) {
3503 plog(LLV_ERROR, LOCATION, NULL,
3504 "invalid encryption algoriym %d.\n",
3505 iph1->approval->enctype);
3506 goto end;
3507 }
3508
3509 /* save IV for next, but not sync. */
3510 memset(ivep->v, 0, ivep->l);
3511 memcpy(ivep->v, (caddr_t)&msg->v[msg->l - blen], blen);
3512
3513 plog(LLV_DEBUG, LOCATION, NULL,
3514 "IV was saved for next processing:\n");
3515 plogdump(LLV_DEBUG, ivep->v, ivep->l);
3516
3517 pl = msg->v + sizeof(struct isakmp);
3518
3519 len = msg->l - sizeof(struct isakmp);
3520
3521 /* create buffer */
3522 buf = vmalloc(len);
3523 if (buf == NULL) {
3524 plog(LLV_ERROR, LOCATION, NULL,
3525 "failed to get buffer to decrypt.\n");
3526 goto end;
3527 }
3528 memcpy(buf->v, pl, len);
3529
3530 /* do decrypt */
3531 new = alg_oakley_encdef_decrypt(iph1->approval->enctype,
3532 buf, iph1->key, ivdp);
3533 if (new == NULL || new->v == NULL || new->l == 0) {
3534 plog(LLV_ERROR, LOCATION, NULL,
3535 "decryption %d failed.\n", iph1->approval->enctype);
3536 goto end;
3537 }
3538 plog(LLV_DEBUG, LOCATION, NULL, "with key:\n");
3539 plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
3540
3541 vfree(buf);
3542 buf = NULL;
3543 if (new == NULL)
3544 goto end;
3545
3546 plog(LLV_DEBUG, LOCATION, NULL, "decrypted payload by IV:\n");
3547 plogdump(LLV_DEBUG, ivdp->v, ivdp->l);
3548
3549 plog(LLV_DEBUG, LOCATION, NULL,
3550 "decrypted payload, but not trimed.\n");
3551 plogdump(LLV_DEBUG, new->v, new->l);
3552
3553 /* get padding length */
3554 if (lcconf->pad_excltail)
3555 padlen = new->v[new->l - 1] + 1;
3556 else
3557 padlen = new->v[new->l - 1];
3558 plog(LLV_DEBUG, LOCATION, NULL, "padding len=%u\n", padlen);
3559
3560 /* trim padding */
3561 if (lcconf->pad_strict) {
3562 if (padlen > new->l) {
3563 plog(LLV_ERROR, LOCATION, NULL,
3564 "invalid padding len=%u, buflen=%zu.\n",
3565 padlen, new->l);
3566 plogdump(LLV_ERROR, new->v, new->l);
3567 goto end;
3568 }
3569 new->l -= padlen;
3570 plog(LLV_DEBUG, LOCATION, NULL, "trimmed padding\n");
3571 } else {
3572 plog(LLV_DEBUG, LOCATION, NULL, "skip to trim padding.\n");
3573 }
3574
3575 /* create new buffer */
3576 len = sizeof(struct isakmp) + new->l;
3577 buf = vmalloc(len);
3578 if (buf == NULL) {
3579 plog(LLV_ERROR, LOCATION, NULL,
3580 "failed to get buffer to decrypt.\n");
3581 goto end;
3582 }
3583 memcpy(buf->v, msg->v, sizeof(struct isakmp));
3584 memcpy(buf->v + sizeof(struct isakmp), new->v, new->l);
3585 ((struct isakmp *)buf->v)->len = htonl(buf->l);
3586
3587 plog(LLV_DEBUG, LOCATION, NULL, "decrypted.\n");
3588 plogdump(LLV_DEBUG, buf->v, buf->l);
3589
3590 #ifdef HAVE_PRINT_ISAKMP_C
3591 isakmp_printpacket(buf, iph1->remote, iph1->local, 1);
3592 #endif
3593
3594 error = 0;
3595
3596 end:
3597 if (error && buf != NULL) {
3598 vfree(buf);
3599 buf = NULL;
3600 }
3601 if (new != NULL)
3602 vfree(new);
3603
3604 return buf;
3605 }
3606
3607 /*
3608 * encrypt packet.
3609 */
3610 vchar_t *
3611 oakley_do_encrypt(iph1, msg, ivep, ivp)
3612 struct ph1handle *iph1;
3613 vchar_t *msg, *ivep, *ivp;
3614 {
3615 vchar_t *buf = 0, *new = 0;
3616 char *pl;
3617 int len;
3618 u_int padlen;
3619 int blen;
3620 int error = -1;
3621
3622 plog(LLV_DEBUG, LOCATION, NULL, "begin encryption.\n");
3623
3624 /* set cbc block length */
3625 blen = alg_oakley_encdef_blocklen(iph1->approval->enctype);
3626 if (blen == -1) {
3627 plog(LLV_ERROR, LOCATION, NULL,
3628 "invalid encryption algoriym %d.\n",
3629 iph1->approval->enctype);
3630 goto end;
3631 }
3632
3633 pl = msg->v + sizeof(struct isakmp);
3634 len = msg->l - sizeof(struct isakmp);
3635
3636 /* add padding */
3637 padlen = oakley_padlen(len, blen);
3638 plog(LLV_DEBUG, LOCATION, NULL, "pad length = %u\n", padlen);
3639
3640 /* create buffer */
3641 buf = vmalloc(len + padlen);
3642 if (buf == NULL) {
3643 plog(LLV_ERROR, LOCATION, NULL,
3644 "failed to get buffer to encrypt.\n");
3645 goto end;
3646 }
3647 if (padlen) {
3648 int i;
3649 char *p = &buf->v[len];
3650 if (lcconf->pad_random) {
3651 for (i = 0; i < padlen; i++)
3652 *p++ = eay_random() & 0xff;
3653 }
3654 }
3655 memcpy(buf->v, pl, len);
3656
3657 /* make pad into tail */
3658 if (lcconf->pad_excltail)
3659 buf->v[len + padlen - 1] = padlen - 1;
3660 else
3661 buf->v[len + padlen - 1] = padlen;
3662
3663 plogdump(LLV_DEBUG, buf->v, buf->l);
3664
3665 /* do encrypt */
3666 new = alg_oakley_encdef_encrypt(iph1->approval->enctype,
3667 buf, iph1->key, ivep);
3668 if (new == NULL) {
3669 plog(LLV_ERROR, LOCATION, NULL,
3670 "encryption %d failed.\n", iph1->approval->enctype);
3671 goto end;
3672 }
3673 plog(LLV_DEBUG, LOCATION, NULL, "with key:\n");
3674 plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
3675
3676 vfree(buf);
3677 buf = NULL;
3678 if (new == NULL)
3679 goto end;
3680
3681 plog(LLV_DEBUG, LOCATION, NULL, "encrypted payload by IV:\n");
3682 plogdump(LLV_DEBUG, ivep->v, ivep->l);
3683
3684 /* save IV for next */
3685 memset(ivp->v, 0, ivp->l);
3686 memcpy(ivp->v, (caddr_t)&new->v[new->l - blen], blen);
3687
3688 plog(LLV_DEBUG, LOCATION, NULL, "save IV for next:\n");
3689 plogdump(LLV_DEBUG, ivp->v, ivp->l);
3690
3691 /* create new buffer */
3692 len = sizeof(struct isakmp) + new->l;
3693 buf = vmalloc(len);
3694 if (buf == NULL) {
3695 plog(LLV_ERROR, LOCATION, NULL,
3696 "failed to get buffer to encrypt.\n");
3697 goto end;
3698 }
3699 memcpy(buf->v, msg->v, sizeof(struct isakmp));
3700 memcpy(buf->v + sizeof(struct isakmp), new->v, new->l);
3701 ((struct isakmp *)buf->v)->len = htonl(buf->l);
3702
3703 error = 0;
3704
3705 plog(LLV_DEBUG, LOCATION, NULL, "encrypted.\n");
3706
3707 end:
3708 if (error && buf != NULL) {
3709 vfree(buf);
3710 buf = NULL;
3711 }
3712 if (new != NULL)
3713 vfree(new);
3714
3715 return buf;
3716 }
3717
3718 /* culculate padding length */
3719 static int
3720 oakley_padlen(len, base)
3721 int len, base;
3722 {
3723 int padlen;
3724
3725 padlen = base - len % base;
3726
3727 if (lcconf->pad_randomlen)
3728 padlen += ((eay_random() % (lcconf->pad_maxsize + 1) + 1) *
3729 base);
3730
3731 return padlen;
3732 }
3733
3734 #ifdef __APPLE__
3735 /* -----------------------------------------------------------------------------
3736 The base-64 encoding packs three 8-bit bytes into four 7-bit ASCII
3737 characters. If the number of bytes in the original data isn't divisable
3738 by three, "=" characters are used to pad the encoded data. The complete
3739 set of characters used in base-64 are:
3740 'A'..'Z' => 00..25
3741 'a'..'z' => 26..51
3742 '0'..'9' => 52..61
3743 '+' => 62
3744 '/' => 63
3745 '=' => pad
3746
3747 ----------------------------------------------------------------------------- */
3748 static const signed char base64_DecodeTable[128] = {
3749 /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
3750 /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
3751 /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
3752 /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
3753 /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
3754 /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
3755 /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
3756 /* '8' */ 60, 61, -1, -1, -1, 0, -1, -1,
3757 /* '@' */ -1, 0, 1, 2, 3, 4, 5, 6,
3758 /* 'H' */ 7, 8, 9, 10, 11, 12, 13, 14,
3759 /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
3760 /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
3761 /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
3762 /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
3763 /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
3764 /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
3765 };
3766
3767 static int base64toCFData(vchar_t *textin, CFDataRef *dataRef)
3768 {
3769 uint8_t *tmpbuf;
3770 uint8_t c;
3771 int tmpbufpos = 0;
3772 int numeq = 0;
3773 int acc = 0;
3774 int cntr = 0;
3775 uint8_t *textcur = textin->v;
3776 int len = textin->l;
3777 int i;
3778
3779 tmpbuf = malloc(len); // len of result will be less than encoded len
3780 if (tmpbuf == NULL) {
3781 yyerror("memory error - could not allocate buffer for certificate reference conversion from base-64.");
3782 return -1;
3783 }
3784
3785 for (i = 0; i < len; i++) {
3786 c = *(textcur++);
3787 if (c == '=')
3788 numeq++;
3789 else if (!isspace(c))
3790 numeq = 0;
3791 if (base64_DecodeTable[c] < 0)
3792 continue;
3793 cntr++;
3794 acc <<= 6;
3795 acc += base64_DecodeTable[c];
3796 if (0 == (cntr & 0x3)) {
3797 tmpbuf[tmpbufpos++] = (acc >> 16) & 0xff;
3798 if (numeq < 2)
3799 tmpbuf[tmpbufpos++] = (acc >> 8) & 0xff;
3800 if (numeq < 1)
3801 tmpbuf[tmpbufpos++] = acc & 0xff;
3802 }
3803 }
3804 *dataRef = CFDataCreate(NULL, tmpbuf, tmpbufpos);
3805 free(tmpbuf);
3806 if (*dataRef)
3807 return 0;
3808 else
3809 return -1;
3810
3811 }
3812 #endif