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