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