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