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