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