Annotation of embedaddon/ipsec-tools/src/racoon/oakley.c, revision 1.1.1.2
1.1.1.2 ! misho 1: /* $NetBSD: oakley.c,v 1.22.2.2 2012/08/29 11:35:09 tteras Exp $ */
1.1 misho 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:
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 *
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 *
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
185: oakley_get_defaultlifetime()
186: {
187: return OAKLEY_ATTR_SA_LD_SEC_DEFAULT;
188: }
189:
190: int
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
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
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
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
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
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 *
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 *
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
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
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 *
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 *
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 *
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 *
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 *
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 *
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
1286: oakley_validate_auth(iph1)
1287: struct ph1handle *iph1;
1288: {
1289: vchar_t *my_hash = NULL;
1290: int result;
1.1.1.2 ! misho 1291: int no_verify_needed = -1;
1.1 misho 1292: #ifdef HAVE_GSSAPI
1293: vchar_t *gsshash = NULL;
1294: #endif
1295: #ifdef ENABLE_STATS
1296: struct timeval start, end;
1297: #endif
1298:
1299: #ifdef ENABLE_STATS
1300: gettimeofday(&start, NULL);
1301: #endif
1302:
1303: switch (iph1->approval->authmethod) {
1304: case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1305: #ifdef ENABLE_HYBRID
1306: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
1307: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1308: #endif
1309: /* validate HASH */
1310: {
1311: char *r_hash;
1312:
1313: if (iph1->id_p == NULL || iph1->pl_hash == NULL) {
1314: plog(LLV_ERROR, LOCATION, iph1->remote,
1315: "few isakmp message received.\n");
1316: return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1317: }
1318: #ifdef ENABLE_HYBRID
1319: if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I &&
1320: ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0))
1321: {
1322: plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, "
1323: "hybrid auth is enabled, "
1324: "but peer is no Xauth compliant\n");
1325: return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED;
1326: break;
1327: }
1328: #endif
1329: r_hash = (caddr_t)(iph1->pl_hash + 1);
1330:
1331: plog(LLV_DEBUG, LOCATION, NULL, "HASH received:\n");
1332: plogdump(LLV_DEBUG, r_hash,
1333: ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash));
1334:
1335: switch (iph1->etype) {
1336: case ISAKMP_ETYPE_IDENT:
1337: case ISAKMP_ETYPE_AGG:
1338: my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1339: break;
1340: case ISAKMP_ETYPE_BASE:
1341: if (iph1->side == INITIATOR)
1342: my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1343: else
1344: my_hash = oakley_ph1hash_base_i(iph1, VALIDATE);
1345: break;
1346: default:
1347: plog(LLV_ERROR, LOCATION, NULL,
1348: "invalid etype %d\n", iph1->etype);
1349: return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1350: }
1351: if (my_hash == NULL)
1352: return ISAKMP_INTERNAL_ERROR;
1353:
1354: result = memcmp(my_hash->v, r_hash, my_hash->l);
1355: vfree(my_hash);
1356:
1357: if (result) {
1358: plog(LLV_ERROR, LOCATION, NULL, "HASH mismatched\n");
1359: return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1360: }
1361:
1362: plog(LLV_DEBUG, LOCATION, NULL, "HASH for PSK validated.\n");
1363: }
1364: break;
1365: #ifdef ENABLE_HYBRID
1366: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1367: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
1368: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
1369: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1370: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
1371: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1.1.1.2 ! misho 1372: no_verify_needed = 0;
1.1 misho 1373: #endif
1.1.1.2 ! misho 1374: case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
! 1375: case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1.1 misho 1376: {
1377: int error = 0;
1378: int certtype;
1379:
1380: /* validation */
1381: if (iph1->id_p == NULL) {
1382: plog(LLV_ERROR, LOCATION, iph1->remote,
1383: "no ID payload was passed.\n");
1384: return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1385: }
1386: if (iph1->sig_p == NULL) {
1387: plog(LLV_ERROR, LOCATION, iph1->remote,
1388: "no SIG payload was passed.\n");
1389: return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1390: }
1391:
1392: plog(LLV_DEBUG, LOCATION, NULL, "SIGN passed:\n");
1393: plogdump(LLV_DEBUG, iph1->sig_p->v, iph1->sig_p->l);
1394:
1395: /* get peer's cert */
1396: certtype = oakley_get_certtype(iph1->rmconf->peerscert);
1397: switch (certtype) {
1398: case ISAKMP_CERT_NONE:
1399: /* expect to receive one from peer */
1400: if (iph1->cert_p == NULL) {
1401: plog(LLV_ERROR, LOCATION, NULL,
1402: "no peer's CERT payload found.\n");
1403: return ISAKMP_INTERNAL_ERROR;
1404: }
1405: /* verify the cert if needed */
1406: if (!iph1->rmconf->verify_cert)
1407: break;
1408:
1409: switch (oakley_get_certtype(iph1->cert_p)) {
1410: case ISAKMP_CERT_X509SIGN: {
1411: char path[MAXPATHLEN];
1412: char *ca;
1413:
1414: if (iph1->rmconf->cacertfile != NULL) {
1415: getpathname(path, sizeof(path),
1416: LC_PATHTYPE_CERT,
1417: iph1->rmconf->cacertfile);
1418: ca = path;
1419: } else {
1420: ca = NULL;
1421: }
1422:
1423: error = eay_check_x509cert(
1424: iph1->cert_p,
1425: lcconf->pathinfo[LC_PATHTYPE_CERT],
1426: ca, 0);
1427: break;
1428: }
1429: default:
1430: plog(LLV_ERROR, LOCATION, NULL,
1431: "peers_cert certtype %d was not expected\n",
1432: certtype);
1433: return ISAKMP_INTERNAL_ERROR;
1434: }
1435:
1436: if (error != 0) {
1.1.1.2 ! misho 1437: plog(LLV_ERROR, LOCATION, iph1->remote,
1.1 misho 1438: "the peer's certificate is not verified.\n");
1439: return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY;
1440: }
1441: break;
1442: case ISAKMP_CERT_X509SIGN:
1443: if (iph1->rmconf->peerscert == NULL) {
1444: plog(LLV_ERROR, LOCATION, NULL,
1445: "no peer's CERT file found.\n");
1446: return ISAKMP_INTERNAL_ERROR;
1447: }
1448: /* don't use received cert */
1449: if (iph1->cert_p != NULL) {
1450: vfree(iph1->cert_p);
1451: iph1->cert_p = NULL;
1452: }
1453: /* copy from remoteconf instead */
1454: iph1->cert_p = vdup(iph1->rmconf->peerscert);
1455: break;
1456: case ISAKMP_CERT_PLAINRSA:
1457: if (get_plainrsa_fromlocal(iph1, 0))
1458: return ISAKMP_INTERNAL_ERROR;
1.1.1.2 ! misho 1459: /* suppress CERT validation warning, unless hybrid mode in use */
! 1460: if (no_verify_needed == -1)
! 1461: no_verify_needed = 1;
1.1 misho 1462: break;
1463: case ISAKMP_CERT_DNS:
1464: /* don't use received cert */
1465: if (iph1->cert_p != NULL) {
1466: vfree(iph1->cert_p);
1467: iph1->cert_p = NULL;
1468: }
1469:
1470: iph1->cert_p = dnssec_getcert(iph1->id_p);
1471: if (iph1->cert_p == NULL) {
1472: plog(LLV_ERROR, LOCATION, NULL,
1473: "no CERT RR found.\n");
1474: return ISAKMP_INTERNAL_ERROR;
1475: }
1476: break;
1477: default:
1478: plog(LLV_ERROR, LOCATION, NULL,
1479: "invalid certificate type: %d\n",
1480: oakley_get_certtype(iph1->rmconf->peerscert));
1481: return ISAKMP_INTERNAL_ERROR;
1482: }
1483:
1484: /* compare ID payload and certificate name */
1485: if ((error = oakley_check_certid(iph1)) != 0)
1486: return error;
1487:
1.1.1.2 ! misho 1488: /* Generate a warning unless verify_cert */
1.1 misho 1489: if (iph1->rmconf->verify_cert) {
1.1.1.2 ! misho 1490: plog(LLV_DEBUG, LOCATION, iph1->remote,
1.1 misho 1491: "CERT validated\n");
1.1.1.2 ! misho 1492: } else if (no_verify_needed != 1) {
! 1493: plog(LLV_WARNING, LOCATION, iph1->remote,
1.1 misho 1494: "CERT validation disabled by configuration\n");
1495: }
1496:
1497: /* compute hash */
1498: switch (iph1->etype) {
1499: case ISAKMP_ETYPE_IDENT:
1500: case ISAKMP_ETYPE_AGG:
1501: my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1502: break;
1503: case ISAKMP_ETYPE_BASE:
1504: if (iph1->side == INITIATOR)
1505: my_hash = oakley_ph1hash_base_r(iph1, VALIDATE);
1506: else
1507: my_hash = oakley_ph1hash_base_i(iph1, VALIDATE);
1508: break;
1509: default:
1510: plog(LLV_ERROR, LOCATION, NULL,
1511: "invalid etype %d\n", iph1->etype);
1512: return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1513: }
1514: if (my_hash == NULL)
1515: return ISAKMP_INTERNAL_ERROR;
1516:
1517: /* check signature */
1518: certtype = oakley_get_certtype(iph1->cert_p);
1519: if (certtype == ISAKMP_CERT_NONE)
1520: certtype = oakley_get_certtype(iph1->rmconf->peerscert);
1521: switch (certtype) {
1522: case ISAKMP_CERT_X509SIGN:
1523: case ISAKMP_CERT_DNS:
1524: error = eay_check_x509sign(my_hash,
1525: iph1->sig_p,
1526: iph1->cert_p);
1527: break;
1528: case ISAKMP_CERT_PLAINRSA:
1529: iph1->rsa_p = rsa_try_check_rsasign(my_hash,
1530: iph1->sig_p, iph1->rsa_candidates);
1531: error = iph1->rsa_p ? 0 : -1;
1532: genlist_free(iph1->rsa_candidates, NULL);
1533: iph1->rsa_candidates = NULL;
1534: break;
1535: default:
1536: plog(LLV_ERROR, LOCATION, NULL,
1537: "cannot check signature for certtype %d\n",
1538: certtype);
1539: vfree(my_hash);
1540: return ISAKMP_INTERNAL_ERROR;
1541: }
1542:
1543: vfree(my_hash);
1544: if (error != 0) {
1545: plog(LLV_ERROR, LOCATION, NULL,
1546: "Invalid SIG.\n");
1547: return ISAKMP_NTYPE_INVALID_SIGNATURE;
1548: }
1549: plog(LLV_DEBUG, LOCATION, NULL, "SIG authenticated\n");
1550: }
1551: break;
1552: #ifdef ENABLE_HYBRID
1553: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1554: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1555: {
1556: if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
1557: plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, "
1558: "hybrid auth is enabled, "
1559: "but peer is no Xauth compliant\n");
1560: return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED;
1561: break;
1562: }
1563: plog(LLV_INFO, LOCATION, NULL, "No SIG was passed, "
1564: "but hybrid auth is enabled\n");
1565:
1566: return 0;
1567: break;
1568: }
1569: #endif
1570: #ifdef HAVE_GSSAPI
1571: case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1572: /* check if we're not into XAUTH_PSKEY_I instead */
1573: #ifdef ENABLE_HYBRID
1574: if (iph1->rmconf->xauth)
1575: break;
1576: #endif
1577: switch (iph1->etype) {
1578: case ISAKMP_ETYPE_IDENT:
1579: case ISAKMP_ETYPE_AGG:
1580: my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1581: break;
1582: default:
1583: plog(LLV_ERROR, LOCATION, NULL,
1584: "invalid etype %d\n", iph1->etype);
1585: return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1586: }
1587:
1588: if (my_hash == NULL) {
1589: if (gssapi_more_tokens(iph1))
1590: return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1591: else
1592: return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1593: }
1594:
1595: gsshash = gssapi_unwraphash(iph1);
1596: if (gsshash == NULL) {
1597: vfree(my_hash);
1598: return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1599: }
1600:
1601: result = memcmp(my_hash->v, gsshash->v, my_hash->l);
1602: vfree(my_hash);
1603: vfree(gsshash);
1604:
1605: if (result) {
1606: plog(LLV_ERROR, LOCATION, NULL, "HASH mismatched\n");
1607: return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1608: }
1609: plog(LLV_DEBUG, LOCATION, NULL, "hash compared OK\n");
1610: break;
1611: #endif
1612: case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1613: case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1614: #ifdef ENABLE_HYBRID
1615: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
1616: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1617: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
1618: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1619: #endif
1620: if (iph1->id_p == NULL || iph1->pl_hash == NULL) {
1621: plog(LLV_ERROR, LOCATION, iph1->remote,
1622: "few isakmp message received.\n");
1623: return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1624: }
1625: plog(LLV_ERROR, LOCATION, iph1->remote,
1626: "not supported authmethod type %s\n",
1627: s_oakley_attr_method(iph1->approval->authmethod));
1628: return ISAKMP_INTERNAL_ERROR;
1629: default:
1630: plog(LLV_ERROR, LOCATION, iph1->remote,
1631: "invalid authmethod %d why ?\n",
1632: iph1->approval->authmethod);
1633: return ISAKMP_INTERNAL_ERROR;
1634: }
1635: #ifdef ENABLE_STATS
1636: gettimeofday(&end, NULL);
1637: syslog(LOG_NOTICE, "%s(%s): %8.6f", __func__,
1638: s_oakley_attr_method(iph1->approval->authmethod),
1639: timedelta(&start, &end));
1640: #endif
1641:
1642: return 0;
1643: }
1644:
1645: /* get my certificate
1646: * NOTE: include certificate type.
1647: */
1648: int
1649: oakley_getmycert(iph1)
1650: struct ph1handle *iph1;
1651: {
1652: switch (oakley_get_certtype(iph1->rmconf->mycert)) {
1653: case ISAKMP_CERT_X509SIGN:
1654: if (iph1->cert)
1655: return 0;
1656: iph1->cert = vdup(iph1->rmconf->mycert);
1657: break;
1658: case ISAKMP_CERT_PLAINRSA:
1659: if (iph1->rsa)
1660: return 0;
1661: return get_plainrsa_fromlocal(iph1, 1);
1662: default:
1663: plog(LLV_ERROR, LOCATION, NULL,
1664: "Unknown certtype #%d\n",
1665: oakley_get_certtype(iph1->rmconf->mycert));
1666: return -1;
1667: }
1668:
1669: return 0;
1670: }
1671:
1672: static int
1673: get_plainrsa_fromlocal(iph1, my)
1674: struct ph1handle *iph1;
1675: int my;
1676: {
1677: char path[MAXPATHLEN];
1678: vchar_t *cert = NULL;
1679: char *certfile;
1680: int error = -1;
1681:
1682: iph1->rsa_candidates = rsa_lookup_keys(iph1, my);
1683: if (!iph1->rsa_candidates ||
1684: rsa_list_count(iph1->rsa_candidates) == 0) {
1685: plog(LLV_ERROR, LOCATION, NULL,
1686: "%s RSA key not found for %s\n",
1687: my ? "Private" : "Public",
1688: saddr2str_fromto("%s <-> %s",
1689: iph1->local, iph1->remote));
1690: goto end;
1691: }
1692:
1693: if (my && rsa_list_count(iph1->rsa_candidates) > 1) {
1694: plog(LLV_WARNING, LOCATION, NULL,
1695: "More than one (=%lu) private "
1696: "PlainRSA key found for %s\n",
1697: rsa_list_count(iph1->rsa_candidates),
1698: saddr2str_fromto("%s <-> %s",
1699: iph1->local, iph1->remote));
1700: plog(LLV_WARNING, LOCATION, NULL,
1701: "This may have unpredictable results, "
1702: "i.e. wrong key could be used!\n");
1703: plog(LLV_WARNING, LOCATION, NULL,
1704: "Consider using only one single private "
1705: "key for all peers...\n");
1706: }
1707: if (my) {
1708: iph1->rsa = ((struct rsa_key *)
1709: genlist_next(iph1->rsa_candidates, NULL))->rsa;
1710:
1711: genlist_free(iph1->rsa_candidates, NULL);
1712: iph1->rsa_candidates = NULL;
1713:
1714: if (iph1->rsa == NULL)
1715: goto end;
1716: }
1717:
1718: error = 0;
1719:
1720: end:
1721: return error;
1722: }
1723:
1724: /* get signature */
1725: int
1726: oakley_getsign(iph1)
1727: struct ph1handle *iph1;
1728: {
1729: char path[MAXPATHLEN];
1730: vchar_t *privkey = NULL;
1731: int error = -1;
1732:
1733: switch (oakley_get_certtype(iph1->rmconf->mycert)) {
1734: case ISAKMP_CERT_X509SIGN:
1735: case ISAKMP_CERT_DNS:
1736: if (iph1->rmconf->myprivfile == NULL) {
1737: plog(LLV_ERROR, LOCATION, NULL, "no cert defined.\n");
1738: goto end;
1739: }
1740:
1741: /* make private file name */
1742: getpathname(path, sizeof(path),
1743: LC_PATHTYPE_CERT,
1744: iph1->rmconf->myprivfile);
1745: privkey = privsep_eay_get_pkcs1privkey(path);
1746: if (privkey == NULL) {
1747: plog(LLV_ERROR, LOCATION, NULL,
1748: "failed to get private key.\n");
1749: goto end;
1750: }
1751: plog(LLV_DEBUG2, LOCATION, NULL, "private key:\n");
1752: plogdump(LLV_DEBUG2, privkey->v, privkey->l);
1753: iph1->sig = eay_get_x509sign(iph1->hash, privkey);
1754: break;
1755: case ISAKMP_CERT_PLAINRSA:
1756: iph1->sig = eay_get_rsasign(iph1->hash, iph1->rsa);
1757: break;
1758: default:
1759: plog(LLV_ERROR, LOCATION, NULL,
1760: "Unknown certtype #%d\n",
1761: oakley_get_certtype(iph1->rmconf->mycert));
1762: goto end;
1763: }
1764:
1765: if (iph1->sig == NULL) {
1766: plog(LLV_ERROR, LOCATION, NULL, "failed to sign.\n");
1767: goto end;
1768: }
1769:
1770: plog(LLV_DEBUG, LOCATION, NULL, "SIGN computed:\n");
1771: plogdump(LLV_DEBUG, iph1->sig->v, iph1->sig->l);
1772:
1773: error = 0;
1774:
1775: end:
1776: if (privkey != NULL)
1777: vfree(privkey);
1778:
1779: return error;
1780: }
1781:
1782: /*
1783: * compare certificate name and ID value.
1784: */
1785: static int
1786: oakley_check_certid(iph1)
1787: struct ph1handle *iph1;
1788: {
1789: struct ipsecdoi_id_b *id_b;
1790: vchar_t *name = NULL;
1791: char *altname = NULL;
1792: int idlen, type;
1793: int error;
1794:
1795: if (iph1->rmconf == NULL || iph1->rmconf->verify_cert == FALSE)
1796: return 0;
1797:
1798: if (iph1->id_p == NULL || iph1->cert_p == NULL) {
1799: plog(LLV_ERROR, LOCATION, iph1->remote, "no ID nor CERT found.\n");
1800: return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1801: }
1802:
1803: id_b = (struct ipsecdoi_id_b *)iph1->id_p->v;
1804: idlen = iph1->id_p->l - sizeof(*id_b);
1805:
1806: switch (id_b->type) {
1807: case IPSECDOI_ID_DER_ASN1_DN:
1808: name = eay_get_x509asn1subjectname(iph1->cert_p);
1809: if (!name) {
1810: plog(LLV_ERROR, LOCATION, iph1->remote,
1811: "failed to get subjectName\n");
1812: return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1813: }
1814: if (idlen != name->l) {
1815: plog(LLV_ERROR, LOCATION, iph1->remote,
1816: "Invalid ID length in phase 1.\n");
1817: vfree(name);
1818: return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1819: }
1820: error = memcmp(id_b + 1, name->v, idlen);
1821: if (error != 0) {
1822: plog(LLV_ERROR, LOCATION, iph1->remote,
1823: "ID mismatched with ASN1 SubjectName.\n");
1824: plogdump(LLV_DEBUG, id_b + 1, idlen);
1825: plogdump(LLV_DEBUG, name->v, idlen);
1826: if (iph1->rmconf->verify_identifier) {
1827: vfree(name);
1828: return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1829: }
1830: }
1831: vfree(name);
1832: return 0;
1833: case IPSECDOI_ID_IPV4_ADDR:
1834: case IPSECDOI_ID_IPV6_ADDR:
1835: {
1836: /*
1837: * converting to binary from string because openssl return
1838: * a string even if object is a binary.
1839: * XXX fix it ! access by ASN.1 directly without.
1840: */
1841: struct addrinfo hints, *res;
1842: caddr_t a = NULL;
1843: int pos;
1844:
1845: for (pos = 1; ; pos++) {
1846: if (eay_get_x509subjectaltname(iph1->cert_p,
1847: &altname, &type, pos) !=0) {
1848: plog(LLV_ERROR, LOCATION, NULL,
1849: "failed to get subjectAltName\n");
1850: return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1851: }
1852:
1853: /* it's the end condition of the loop. */
1854: if (!altname) {
1855: plog(LLV_ERROR, LOCATION, NULL,
1856: "no proper subjectAltName.\n");
1857: return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1858: }
1859:
1860: if (check_typeofcertname(id_b->type, type) == 0)
1861: break;
1862:
1863: /* next name */
1864: racoon_free(altname);
1865: altname = NULL;
1866: }
1867: memset(&hints, 0, sizeof(hints));
1868: hints.ai_family = PF_UNSPEC;
1869: hints.ai_socktype = SOCK_RAW;
1870: hints.ai_flags = AI_NUMERICHOST;
1871: error = getaddrinfo(altname, NULL, &hints, &res);
1872: racoon_free(altname);
1873: altname = NULL;
1874: if (error != 0) {
1875: plog(LLV_ERROR, LOCATION, NULL,
1876: "no proper subjectAltName.\n");
1877: return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1878: }
1879: switch (res->ai_family) {
1880: case AF_INET:
1881: a = (caddr_t)&((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr;
1882: break;
1883: #ifdef INET6
1884: case AF_INET6:
1885: a = (caddr_t)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr.s6_addr;
1886: break;
1887: #endif
1888: default:
1889: plog(LLV_ERROR, LOCATION, NULL,
1890: "family not supported: %d.\n", res->ai_family);
1891: freeaddrinfo(res);
1892: return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1893: }
1894: error = memcmp(id_b + 1, a, idlen);
1895: freeaddrinfo(res);
1896: vfree(name);
1897: if (error != 0) {
1898: plog(LLV_ERROR, LOCATION, NULL,
1899: "ID mismatched with subjectAltName.\n");
1900: plogdump(LLV_DEBUG, id_b + 1, idlen);
1901: plogdump(LLV_DEBUG, a, idlen);
1902: if (iph1->rmconf->verify_identifier)
1903: return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1904: }
1905: return 0;
1906: }
1907: case IPSECDOI_ID_FQDN:
1908: case IPSECDOI_ID_USER_FQDN:
1909: {
1910: int pos;
1911:
1912: for (pos = 1; ; pos++) {
1913: if (eay_get_x509subjectaltname(iph1->cert_p,
1914: &altname, &type, pos) != 0){
1915: plog(LLV_ERROR, LOCATION, NULL,
1916: "failed to get subjectAltName\n");
1917: return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1918: }
1919:
1920: /* it's the end condition of the loop. */
1921: if (!altname) {
1922: plog(LLV_ERROR, LOCATION, NULL,
1923: "no proper subjectAltName.\n");
1924: return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1925: }
1926:
1927: if (check_typeofcertname(id_b->type, type) == 0)
1928: break;
1929:
1930: /* next name */
1931: racoon_free(altname);
1932: altname = NULL;
1933: }
1934: if (idlen != strlen(altname)) {
1935: plog(LLV_ERROR, LOCATION, NULL,
1936: "Invalid ID length in phase 1.\n");
1937: racoon_free(altname);
1938: return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1939: }
1940: if (check_typeofcertname(id_b->type, type) != 0) {
1941: plog(LLV_ERROR, LOCATION, NULL,
1942: "ID type mismatched. ID: %s CERT: %s.\n",
1943: s_ipsecdoi_ident(id_b->type),
1944: s_ipsecdoi_ident(type));
1945: racoon_free(altname);
1946: return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1947: }
1948: error = memcmp(id_b + 1, altname, idlen);
1949: if (error) {
1950: plog(LLV_ERROR, LOCATION, NULL, "ID mismatched.\n");
1951: plogdump(LLV_DEBUG, id_b + 1, idlen);
1952: plogdump(LLV_DEBUG, altname, idlen);
1953: racoon_free(altname);
1954: return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1955: }
1956: racoon_free(altname);
1957: return 0;
1958: }
1959: default:
1960: plog(LLV_ERROR, LOCATION, NULL,
1961: "Inpropper ID type passed: %s.\n",
1962: s_ipsecdoi_ident(id_b->type));
1963: return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1964: }
1965: /*NOTREACHED*/
1966: }
1967:
1968: static int
1969: check_typeofcertname(doi, genid)
1970: int doi, genid;
1971: {
1972: switch (doi) {
1973: case IPSECDOI_ID_IPV4_ADDR:
1974: case IPSECDOI_ID_IPV4_ADDR_SUBNET:
1975: case IPSECDOI_ID_IPV6_ADDR:
1976: case IPSECDOI_ID_IPV6_ADDR_SUBNET:
1977: case IPSECDOI_ID_IPV4_ADDR_RANGE:
1978: case IPSECDOI_ID_IPV6_ADDR_RANGE:
1979: if (genid != GENT_IPADD)
1980: return -1;
1981: return 0;
1982: case IPSECDOI_ID_FQDN:
1983: if (genid != GENT_DNS)
1984: return -1;
1985: return 0;
1986: case IPSECDOI_ID_USER_FQDN:
1987: if (genid != GENT_EMAIL)
1988: return -1;
1989: return 0;
1990: case IPSECDOI_ID_DER_ASN1_DN: /* should not be passed to this function*/
1991: case IPSECDOI_ID_DER_ASN1_GN:
1992: case IPSECDOI_ID_KEY_ID:
1993: default:
1994: return -1;
1995: }
1996: /*NOTREACHED*/
1997: }
1998:
1999: /*
2000: * save certificate including certificate type.
2001: */
2002: int
2003: oakley_savecert(iph1, gen)
2004: struct ph1handle *iph1;
2005: struct isakmp_gen *gen;
2006: {
2007: vchar_t **c;
2008: u_int8_t type;
2009: STACK_OF(X509) *certs=NULL;
2010: PKCS7 *p7;
2011:
2012: type = *(u_int8_t *)(gen + 1) & 0xff;
2013:
2014: switch (type) {
2015: case ISAKMP_CERT_DNS:
2016: plog(LLV_WARNING, LOCATION, NULL,
2017: "CERT payload is unnecessary in DNSSEC. "
2018: "ignore this CERT payload.\n");
2019: return 0;
2020: case ISAKMP_CERT_PKCS7:
2021: case ISAKMP_CERT_PGP:
2022: case ISAKMP_CERT_X509SIGN:
2023: case ISAKMP_CERT_KERBEROS:
2024: case ISAKMP_CERT_SPKI:
2025: c = &iph1->cert_p;
2026: break;
2027: case ISAKMP_CERT_CRL:
2028: c = &iph1->crl_p;
2029: break;
2030: case ISAKMP_CERT_X509KE:
2031: case ISAKMP_CERT_X509ATTR:
2032: case ISAKMP_CERT_ARL:
2033: plog(LLV_ERROR, LOCATION, NULL,
2034: "No supported such CERT type %d\n", type);
2035: return -1;
2036: default:
2037: plog(LLV_ERROR, LOCATION, NULL,
2038: "Invalid CERT type %d\n", type);
2039: return -1;
2040: }
2041:
2042: /* XXX choice the 1th cert, ignore after the cert. */
2043: /* XXX should be processed. */
2044: if (*c) {
2045: plog(LLV_WARNING, LOCATION, NULL,
2046: "ignore 2nd CERT payload.\n");
2047: return 0;
2048: }
2049:
2050: if (type == ISAKMP_CERT_PKCS7) {
2051: u_char *bp;
2052: int i;
2053:
2054: /* Skip the header */
2055: bp = (u_char *)(gen + 1);
2056: /* And the first byte is the certificate type,
2057: * we know that already
2058: */
2059: bp++;
2060: p7 = d2i_PKCS7(NULL, (void *)&bp,
2061: ntohs(gen->len) - sizeof(*gen) - 1);
2062:
2063: if (!p7) {
2064: plog(LLV_ERROR, LOCATION, NULL,
2065: "Failed to parse PKCS#7 CERT.\n");
2066: return -1;
2067: }
2068:
2069: /* Copied this from the openssl pkcs7 application;
2070: * there"s little by way of documentation for any of
2071: * it. I can only presume it"s correct.
2072: */
2073:
2074: i = OBJ_obj2nid(p7->type);
2075: switch (i) {
2076: case NID_pkcs7_signed:
2077: certs=p7->d.sign->cert;
2078: break;
2079: case NID_pkcs7_signedAndEnveloped:
2080: certs=p7->d.signed_and_enveloped->cert;
2081: break;
2082: default:
2083: break;
2084: }
2085:
2086: if (!certs) {
2087: plog(LLV_ERROR, LOCATION, NULL,
2088: "CERT PKCS#7 bundle contains no certs.\n");
2089: PKCS7_free(p7);
2090: return -1;
2091: }
2092:
2093: for (i = 0; i < sk_X509_num(certs); i++) {
2094: int len;
2095: u_char *bp;
2096: X509 *cert = sk_X509_value(certs,i);
2097:
2098: plog(LLV_DEBUG, LOCATION, NULL,
2099: "Trying PKCS#7 cert %d.\n", i);
2100:
2101: /* We'll just try each cert in turn */
2102: *c = dump_x509(cert);
2103:
2104: if (!*c) {
2105: plog(LLV_ERROR, LOCATION, NULL,
2106: "Failed to get CERT buffer.\n");
2107: continue;
2108: }
2109:
2110: /* Ignore cert if it doesn't match identity
2111: * XXX If verify cert is disabled, we still just take
2112: * the first certificate....
2113: */
2114: if (oakley_check_certid(iph1)) {
2115: plog(LLV_DEBUG, LOCATION, NULL,
2116: "Discarding CERT: does not match ID.\n");
2117: vfree((*c));
2118: *c = NULL;
2119: continue;
2120: }
2121:
2122: {
2123: char *p = eay_get_x509text(*c);
2124: plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
2125: plogdump(LLV_DEBUG, (*c)->v, (*c)->l);
2126: plog(LLV_DEBUG, LOCATION, NULL, "%s",
2127: p ? p : "\n");
2128: racoon_free(p);
2129: }
2130: break;
2131: }
2132: PKCS7_free(p7);
2133: } else {
2134: *c = dump_isakmp_payload(gen);
2135: if (!*c) {
2136: plog(LLV_ERROR, LOCATION, NULL,
2137: "Failed to get CERT buffer.\n");
2138: return -1;
2139: }
2140:
2141: switch (type) {
2142: case ISAKMP_CERT_PGP:
2143: case ISAKMP_CERT_X509SIGN:
2144: case ISAKMP_CERT_KERBEROS:
2145: case ISAKMP_CERT_SPKI:
2146: /* Ignore cert if it doesn't match identity
2147: * XXX If verify cert is disabled, we still just take
2148: * the first certificate....
2149: */
2150: if (oakley_check_certid(iph1)){
2151: plog(LLV_DEBUG, LOCATION, NULL,
2152: "Discarding CERT: does not match ID.\n");
2153: vfree((*c));
2154: *c = NULL;
2155: return 0;
2156: }
2157:
2158: {
2159: char *p = eay_get_x509text(*c);
2160: plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
2161: plogdump(LLV_DEBUG, (*c)->v, (*c)->l);
2162: plog(LLV_DEBUG, LOCATION, NULL, "%s", p ? p : "\n");
2163: racoon_free(p);
2164: }
2165: break;
2166: case ISAKMP_CERT_CRL:
2167: plog(LLV_DEBUG, LOCATION, NULL, "CRL saved:\n");
2168: plogdump(LLV_DEBUG, (*c)->v, (*c)->l);
2169: break;
2170: case ISAKMP_CERT_X509KE:
2171: case ISAKMP_CERT_X509ATTR:
2172: case ISAKMP_CERT_ARL:
2173: default:
2174: /* XXX */
2175: vfree(*c);
2176: *c = NULL;
2177: return 0;
2178: }
2179: }
2180:
2181: return 0;
2182: }
2183:
2184: /*
2185: * save certificate including certificate type.
2186: */
2187: int
2188: oakley_savecr(iph1, gen)
2189: struct ph1handle *iph1;
2190: struct isakmp_gen *gen;
2191: {
2192: vchar_t *cert;
2193: vchar_t **c;
2194: u_int8_t type;
2195:
2196: type = *(u_int8_t *)(gen + 1) & 0xff;
2197: switch (type) {
2198: case ISAKMP_CERT_DNS:
2199: plog(LLV_WARNING, LOCATION, NULL,
2200: "CERT payload is unnecessary in DNSSEC\n");
2201: /*FALLTHRU*/
2202: case ISAKMP_CERT_PKCS7:
2203: case ISAKMP_CERT_PGP:
2204: case ISAKMP_CERT_X509SIGN:
2205: case ISAKMP_CERT_KERBEROS:
2206: case ISAKMP_CERT_SPKI:
2207: c = &iph1->cr_p;
2208: break;
2209: case ISAKMP_CERT_X509KE:
2210: case ISAKMP_CERT_X509ATTR:
2211: case ISAKMP_CERT_ARL:
2212: plog(LLV_ERROR, LOCATION, NULL,
2213: "No supported such CR type %d\n", type);
2214: return -1;
2215: case ISAKMP_CERT_CRL:
2216: default:
2217: plog(LLV_ERROR, LOCATION, NULL,
2218: "Invalid CR type %d\n", type);
2219: return -1;
2220: }
2221:
2222: /* Already found an acceptable CR? */
2223: if (*c != NULL)
2224: return 0;
2225:
2226: cert = dump_isakmp_payload(gen);
2227: if (cert == NULL) {
2228: plog(LLV_ERROR, LOCATION, NULL,
2229: "Failed to get CR buffer.\n");
2230: return -1;
2231: }
2232:
2233: plog(LLV_DEBUG, LOCATION, NULL, "CR received:\n");
2234: plogdump(LLV_DEBUG, cert->v, cert->l);
2235:
2236: *c = cert;
2237: if (resolveph1rmconf(iph1) == 0) {
2238: /* Found unique match */
2239: plog(LLV_DEBUG, LOCATION, NULL, "CR saved.\n");
2240: } else {
2241: /* Still ambiguous or matches nothing, ignore this CR */
2242: *c = NULL;
2243: vfree(cert);
2244: }
2245: return 0;
2246: }
2247:
2248: /*
2249: * Add a single CR.
2250: */
2251: struct append_cr_ctx {
2252: struct ph1handle *iph1;
2253: struct payload_list *plist;
2254: };
2255:
2256: static int
2257: oakley_append_rmconf_cr(rmconf, ctx)
2258: struct remoteconf *rmconf;
2259: void *ctx;
2260: {
2261: struct append_cr_ctx *actx = (struct append_cr_ctx *) ctx;
2262: vchar_t *buf, *asn1dn = NULL;
2263: int type;
2264:
2265: /* Do we want to send CR about this? */
2266: if (rmconf->send_cr == FALSE)
2267: return 0;
2268:
2269: if (rmconf->peerscert != NULL) {
2270: type = oakley_get_certtype(rmconf->peerscert);
2271: asn1dn = eay_get_x509asn1issuername(rmconf->peerscert);
2272: } else if (rmconf->cacert != NULL) {
2273: type = oakley_get_certtype(rmconf->cacert);
2274: asn1dn = eay_get_x509asn1subjectname(rmconf->cacert);
2275: } else
2276: return 0;
2277:
2278: if (asn1dn == NULL) {
2279: plog(LLV_ERROR, LOCATION, actx->iph1->remote,
2280: "Failed to get CR ASN1 DN from certificate\n");
2281: return 0;
2282: }
2283:
2284: buf = vmalloc(1 + asn1dn->l);
2285: if (buf == NULL)
2286: goto err;
2287:
2288: buf->v[0] = type;
2289: memcpy(&buf->v[1], asn1dn->v, asn1dn->l);
2290:
2291: plog(LLV_DEBUG, LOCATION, actx->iph1->remote,
2292: "appending CR: %s\n",
2293: s_isakmp_certtype(buf->v[0]));
2294: plogdump(LLV_DEBUG, buf->v, buf->l);
2295:
2296: actx->plist = isakmp_plist_append_full(actx->plist, buf, ISAKMP_NPTYPE_CR, 1);
2297:
2298: err:
2299: vfree(asn1dn);
2300: return 0;
2301: }
2302:
2303: /*
2304: * Append list of acceptable CRs.
2305: * RFC2048 3.10
2306: */
2307: struct payload_list *
2308: oakley_append_cr(plist, iph1)
2309: struct payload_list *plist;
2310: struct ph1handle *iph1;
2311: {
2312: struct append_cr_ctx ctx;
2313: struct rmconfselector sel;
2314:
2315: ctx.iph1 = iph1;
2316: ctx.plist = plist;
2317: if (iph1->rmconf == NULL) {
2318: rmconf_selector_from_ph1(&sel, iph1);
2319: enumrmconf(&sel, oakley_append_rmconf_cr, &ctx);
2320: } else {
2321: oakley_append_rmconf_cr(iph1->rmconf, &ctx);
2322: }
2323:
2324: return ctx.plist;
2325: }
2326:
2327: /*
2328: * check peer's CR.
2329: */
2330: int
2331: oakley_checkcr(iph1)
2332: struct ph1handle *iph1;
2333: {
2334: int type;
2335:
2336: if (iph1->cr_p == NULL)
2337: return 0;
2338:
2339: plog(LLV_DEBUG, LOCATION, iph1->remote,
2340: "peer transmitted CR: %s\n",
2341: s_isakmp_certtype(oakley_get_certtype(iph1->cr_p)));
2342:
2343: type = oakley_get_certtype(iph1->cr_p);
2344: if (type != oakley_get_certtype(iph1->rmconf->mycert)) {
2345: plog(LLV_ERROR, LOCATION, iph1->remote,
2346: "such a cert type isn't supported: %d\n",
2347: type);
2348: return -1;
2349: }
2350:
2351: return 0;
2352: }
2353:
2354: /*
2355: * check to need CR payload.
2356: */
2357: int
2358: oakley_needcr(type)
2359: int type;
2360: {
2361: switch (type) {
2362: case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
2363: case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
2364: #ifdef ENABLE_HYBRID
2365: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
2366: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
2367: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
2368: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
2369: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
2370: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
2371: #endif
2372: return 1;
2373: default:
2374: return 0;
2375: }
2376: /*NOTREACHED*/
2377: }
2378:
2379: /*
2380: * compute SKEYID
2381: * see seciton 5. Exchanges in RFC 2409
2382: * psk: SKEYID = prf(pre-shared-key, Ni_b | Nr_b)
2383: * sig: SKEYID = prf(Ni_b | Nr_b, g^ir)
2384: * enc: SKEYID = prf(H(Ni_b | Nr_b), CKY-I | CKY-R)
2385: */
2386: int
2387: oakley_skeyid(iph1)
2388: struct ph1handle *iph1;
2389: {
2390: vchar_t *buf = NULL, *bp;
2391: char *p;
2392: int len;
2393: int error = -1;
2394:
2395: /* SKEYID */
2396: switch (iph1->approval->authmethod) {
2397: case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
2398: #ifdef ENABLE_HYBRID
2399: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
2400: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
2401: #endif
2402: if (iph1->etype != ISAKMP_ETYPE_IDENT) {
2403: iph1->authstr = getpskbyname(iph1->id_p);
2404: if (iph1->authstr == NULL) {
2405: if (iph1->rmconf->verify_identifier) {
2406: plog(LLV_ERROR, LOCATION, iph1->remote,
2407: "couldn't find the pskey.\n");
2408: goto end;
2409: }
2410: plog(LLV_NOTIFY, LOCATION, iph1->remote,
2411: "couldn't find the proper pskey, "
2412: "try to get one by the peer's address.\n");
2413: }
2414: }
2415: if (iph1->authstr == NULL) {
2416: /*
2417: * If the exchange type is the main mode or if it's
2418: * failed to get the psk by ID, racoon try to get
2419: * the psk by remote IP address.
2420: * It may be nonsense.
2421: */
2422: iph1->authstr = getpskbyaddr(iph1->remote);
2423: if (iph1->authstr == NULL) {
2424: plog(LLV_ERROR, LOCATION, iph1->remote,
2425: "couldn't find the pskey for %s.\n",
2426: saddrwop2str(iph1->remote));
2427: goto end;
2428: }
2429: }
2430: plog(LLV_DEBUG, LOCATION, NULL, "the psk found.\n");
2431: /* should be secret PSK */
2432: plog(LLV_DEBUG2, LOCATION, NULL, "psk: ");
2433: plogdump(LLV_DEBUG2, iph1->authstr->v, iph1->authstr->l);
2434:
2435: len = iph1->nonce->l + iph1->nonce_p->l;
2436: buf = vmalloc(len);
2437: if (buf == NULL) {
2438: plog(LLV_ERROR, LOCATION, NULL,
2439: "failed to get skeyid buffer\n");
2440: goto end;
2441: }
2442: p = buf->v;
2443:
2444: bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p);
2445: plog(LLV_DEBUG, LOCATION, NULL, "nonce 1: ");
2446: plogdump(LLV_DEBUG, bp->v, bp->l);
2447: memcpy(p, bp->v, bp->l);
2448: p += bp->l;
2449:
2450: bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce);
2451: plog(LLV_DEBUG, LOCATION, NULL, "nonce 2: ");
2452: plogdump(LLV_DEBUG, bp->v, bp->l);
2453: memcpy(p, bp->v, bp->l);
2454: p += bp->l;
2455:
2456: iph1->skeyid = oakley_prf(iph1->authstr, buf, iph1);
2457: if (iph1->skeyid == NULL)
2458: goto end;
2459: break;
2460:
2461: case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
2462: case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
2463: #ifdef ENABLE_HYBRID
2464: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
2465: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
2466: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
2467: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
2468: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
2469: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
2470: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
2471: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
2472: #endif
2473: #ifdef HAVE_GSSAPI
2474: case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
2475: #endif
2476: len = iph1->nonce->l + iph1->nonce_p->l;
2477: buf = vmalloc(len);
2478: if (buf == NULL) {
2479: plog(LLV_ERROR, LOCATION, NULL,
2480: "failed to get nonce buffer\n");
2481: goto end;
2482: }
2483: p = buf->v;
2484:
2485: bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p);
2486: plog(LLV_DEBUG, LOCATION, NULL, "nonce1: ");
2487: plogdump(LLV_DEBUG, bp->v, bp->l);
2488: memcpy(p, bp->v, bp->l);
2489: p += bp->l;
2490:
2491: bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce);
2492: plog(LLV_DEBUG, LOCATION, NULL, "nonce2: ");
2493: plogdump(LLV_DEBUG, bp->v, bp->l);
2494: memcpy(p, bp->v, bp->l);
2495: p += bp->l;
2496:
2497: iph1->skeyid = oakley_prf(buf, iph1->dhgxy, iph1);
2498: if (iph1->skeyid == NULL)
2499: goto end;
2500: break;
2501: case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
2502: case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
2503: #ifdef ENABLE_HYBRID
2504: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
2505: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
2506: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
2507: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
2508: #endif
2509: plog(LLV_WARNING, LOCATION, NULL,
2510: "not supported authentication method %s\n",
2511: s_oakley_attr_method(iph1->approval->authmethod));
2512: goto end;
2513: default:
2514: plog(LLV_ERROR, LOCATION, NULL,
2515: "invalid authentication method %d\n",
2516: iph1->approval->authmethod);
2517: goto end;
2518: }
2519:
2520: plog(LLV_DEBUG, LOCATION, NULL, "SKEYID computed:\n");
2521: plogdump(LLV_DEBUG, iph1->skeyid->v, iph1->skeyid->l);
2522:
2523: error = 0;
2524:
2525: end:
2526: if (buf != NULL)
2527: vfree(buf);
2528: return error;
2529: }
2530:
2531: /*
2532: * compute SKEYID_[dae]
2533: * see seciton 5. Exchanges in RFC 2409
2534: * SKEYID_d = prf(SKEYID, g^ir | CKY-I | CKY-R | 0)
2535: * SKEYID_a = prf(SKEYID, SKEYID_d | g^ir | CKY-I | CKY-R | 1)
2536: * SKEYID_e = prf(SKEYID, SKEYID_a | g^ir | CKY-I | CKY-R | 2)
2537: */
2538: int
2539: oakley_skeyid_dae(iph1)
2540: struct ph1handle *iph1;
2541: {
2542: vchar_t *buf = NULL;
2543: char *p;
2544: int len;
2545: int error = -1;
2546:
2547: if (iph1->skeyid == NULL) {
2548: plog(LLV_ERROR, LOCATION, NULL, "no SKEYID found.\n");
2549: goto end;
2550: }
2551:
2552: /* SKEYID D */
2553: /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
2554: len = iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
2555: buf = vmalloc(len);
2556: if (buf == NULL) {
2557: plog(LLV_ERROR, LOCATION, NULL,
2558: "failed to get skeyid buffer\n");
2559: goto end;
2560: }
2561: p = buf->v;
2562:
2563: memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l);
2564: p += iph1->dhgxy->l;
2565: memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t));
2566: p += sizeof(cookie_t);
2567: memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t));
2568: p += sizeof(cookie_t);
2569: *p = 0;
2570: iph1->skeyid_d = oakley_prf(iph1->skeyid, buf, iph1);
2571: if (iph1->skeyid_d == NULL)
2572: goto end;
2573:
2574: vfree(buf);
2575: buf = NULL;
2576:
2577: plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_d computed:\n");
2578: plogdump(LLV_DEBUG, iph1->skeyid_d->v, iph1->skeyid_d->l);
2579:
2580: /* SKEYID A */
2581: /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
2582: len = iph1->skeyid_d->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
2583: buf = vmalloc(len);
2584: if (buf == NULL) {
2585: plog(LLV_ERROR, LOCATION, NULL,
2586: "failed to get skeyid buffer\n");
2587: goto end;
2588: }
2589: p = buf->v;
2590: memcpy(p, iph1->skeyid_d->v, iph1->skeyid_d->l);
2591: p += iph1->skeyid_d->l;
2592: memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l);
2593: p += iph1->dhgxy->l;
2594: memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t));
2595: p += sizeof(cookie_t);
2596: memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t));
2597: p += sizeof(cookie_t);
2598: *p = 1;
2599: iph1->skeyid_a = oakley_prf(iph1->skeyid, buf, iph1);
2600: if (iph1->skeyid_a == NULL)
2601: goto end;
2602:
2603: vfree(buf);
2604: buf = NULL;
2605:
2606: plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_a computed:\n");
2607: plogdump(LLV_DEBUG, iph1->skeyid_a->v, iph1->skeyid_a->l);
2608:
2609: /* SKEYID E */
2610: /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
2611: len = iph1->skeyid_a->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
2612: buf = vmalloc(len);
2613: if (buf == NULL) {
2614: plog(LLV_ERROR, LOCATION, NULL,
2615: "failed to get skeyid buffer\n");
2616: goto end;
2617: }
2618: p = buf->v;
2619: memcpy(p, iph1->skeyid_a->v, iph1->skeyid_a->l);
2620: p += iph1->skeyid_a->l;
2621: memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l);
2622: p += iph1->dhgxy->l;
2623: memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t));
2624: p += sizeof(cookie_t);
2625: memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t));
2626: p += sizeof(cookie_t);
2627: *p = 2;
2628: iph1->skeyid_e = oakley_prf(iph1->skeyid, buf, iph1);
2629: if (iph1->skeyid_e == NULL)
2630: goto end;
2631:
2632: vfree(buf);
2633: buf = NULL;
2634:
2635: plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_e computed:\n");
2636: plogdump(LLV_DEBUG, iph1->skeyid_e->v, iph1->skeyid_e->l);
2637:
2638: error = 0;
2639:
2640: end:
2641: if (buf != NULL)
2642: vfree(buf);
2643: return error;
2644: }
2645:
2646: /*
2647: * compute final encryption key.
2648: * see Appendix B.
2649: */
2650: int
2651: oakley_compute_enckey(iph1)
2652: struct ph1handle *iph1;
2653: {
2654: u_int keylen, prflen;
2655: int error = -1;
2656:
2657: /* RFC2409 p39 */
2658: keylen = alg_oakley_encdef_keylen(iph1->approval->enctype,
2659: iph1->approval->encklen);
2660: if (keylen == -1) {
2661: plog(LLV_ERROR, LOCATION, NULL,
2662: "invalid encryption algorithm %d, "
2663: "or invalid key length %d.\n",
2664: iph1->approval->enctype,
2665: iph1->approval->encklen);
2666: goto end;
2667: }
2668: iph1->key = vmalloc(keylen >> 3);
2669: if (iph1->key == NULL) {
2670: plog(LLV_ERROR, LOCATION, NULL,
2671: "failed to get key buffer\n");
2672: goto end;
2673: }
2674:
2675: /* set prf length */
2676: prflen = alg_oakley_hashdef_hashlen(iph1->approval->hashtype);
2677: if (prflen == -1) {
2678: plog(LLV_ERROR, LOCATION, NULL,
2679: "invalid hash type %d.\n", iph1->approval->hashtype);
2680: goto end;
2681: }
2682:
2683: /* see isakmp-oakley-08 5.3. */
2684: if (iph1->key->l <= iph1->skeyid_e->l) {
2685: /*
2686: * if length(Ka) <= length(SKEYID_e)
2687: * Ka = first length(K) bit of SKEYID_e
2688: */
2689: memcpy(iph1->key->v, iph1->skeyid_e->v, iph1->key->l);
2690: } else {
2691: vchar_t *buf = NULL, *res = NULL;
2692: u_char *p, *ep;
2693: int cplen;
2694: int subkey;
2695:
2696: /*
2697: * otherwise,
2698: * Ka = K1 | K2 | K3
2699: * where
2700: * K1 = prf(SKEYID_e, 0)
2701: * K2 = prf(SKEYID_e, K1)
2702: * K3 = prf(SKEYID_e, K2)
2703: */
2704: plog(LLV_DEBUG, LOCATION, NULL,
2705: "len(SKEYID_e) < len(Ka) (%zu < %zu), "
2706: "generating long key (Ka = K1 | K2 | ...)\n",
2707: iph1->skeyid_e->l, iph1->key->l);
2708:
2709: if ((buf = vmalloc(prflen >> 3)) == 0) {
2710: plog(LLV_ERROR, LOCATION, NULL,
2711: "failed to get key buffer\n");
2712: goto end;
2713: }
2714: p = (u_char *)iph1->key->v;
2715: ep = p + iph1->key->l;
2716:
2717: subkey = 1;
2718: while (p < ep) {
2719: if (p == (u_char *)iph1->key->v) {
2720: /* just for computing K1 */
2721: buf->v[0] = 0;
2722: buf->l = 1;
2723: }
2724: res = oakley_prf(iph1->skeyid_e, buf, iph1);
2725: if (res == NULL) {
2726: vfree(buf);
2727: goto end;
2728: }
2729: plog(LLV_DEBUG, LOCATION, NULL,
2730: "compute intermediate encryption key K%d\n",
2731: subkey);
2732: plogdump(LLV_DEBUG, buf->v, buf->l);
2733: plogdump(LLV_DEBUG, res->v, res->l);
2734:
2735: cplen = (res->l < ep - p) ? res->l : ep - p;
2736: memcpy(p, res->v, cplen);
2737: p += cplen;
2738:
2739: buf->l = prflen >> 3; /* to cancel K1 speciality */
2740: if (res->l != buf->l) {
2741: plog(LLV_ERROR, LOCATION, NULL,
2742: "internal error: res->l=%zu buf->l=%zu\n",
2743: res->l, buf->l);
2744: vfree(res);
2745: vfree(buf);
2746: goto end;
2747: }
2748: memcpy(buf->v, res->v, res->l);
2749: vfree(res);
2750: subkey++;
2751: }
2752:
2753: vfree(buf);
2754: }
2755:
2756: /*
2757: * don't check any weak key or not.
2758: * draft-ietf-ipsec-ike-01.txt Appendix B.
2759: * draft-ietf-ipsec-ciph-aes-cbc-00.txt Section 2.3.
2760: */
2761: #if 0
2762: /* weakkey check */
2763: if (iph1->approval->enctype > ARRAYLEN(oakley_encdef)
2764: || oakley_encdef[iph1->approval->enctype].weakkey == NULL) {
2765: plog(LLV_ERROR, LOCATION, NULL,
2766: "encryption algorithm %d isn't supported.\n",
2767: iph1->approval->enctype);
2768: goto end;
2769: }
2770: if ((oakley_encdef[iph1->approval->enctype].weakkey)(iph1->key)) {
2771: plog(LLV_ERROR, LOCATION, NULL,
2772: "weakkey was generated.\n");
2773: goto end;
2774: }
2775: #endif
2776:
2777: plog(LLV_DEBUG, LOCATION, NULL, "final encryption key computed:\n");
2778: plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
2779:
2780: error = 0;
2781:
2782: end:
2783: return error;
2784: }
2785:
2786: /*
2787: * compute IV and set to ph1handle
2788: * IV = hash(g^xi | g^xr)
2789: * see 4.1 Phase 1 state in draft-ietf-ipsec-ike.
2790: */
2791: int
2792: oakley_newiv(iph1)
2793: struct ph1handle *iph1;
2794: {
2795: struct isakmp_ivm *newivm = NULL;
2796: vchar_t *buf = NULL, *bp;
2797: char *p;
2798: int len;
2799:
2800: /* create buffer */
2801: len = iph1->dhpub->l + iph1->dhpub_p->l;
2802: buf = vmalloc(len);
2803: if (buf == NULL) {
2804: plog(LLV_ERROR, LOCATION, NULL,
2805: "failed to get iv buffer\n");
2806: return -1;
2807: }
2808:
2809: p = buf->v;
2810:
2811: bp = (iph1->side == INITIATOR ? iph1->dhpub : iph1->dhpub_p);
2812: memcpy(p, bp->v, bp->l);
2813: p += bp->l;
2814:
2815: bp = (iph1->side == INITIATOR ? iph1->dhpub_p : iph1->dhpub);
2816: memcpy(p, bp->v, bp->l);
2817: p += bp->l;
2818:
2819: /* allocate IVm */
2820: newivm = racoon_calloc(1, sizeof(struct isakmp_ivm));
2821: if (newivm == NULL) {
2822: plog(LLV_ERROR, LOCATION, NULL,
2823: "failed to get iv buffer\n");
2824: vfree(buf);
2825: return -1;
2826: }
2827:
2828: /* compute IV */
2829: newivm->iv = oakley_hash(buf, iph1);
2830: if (newivm->iv == NULL) {
2831: vfree(buf);
2832: oakley_delivm(newivm);
2833: return -1;
2834: }
2835:
2836: /* adjust length of iv */
2837: newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype);
2838: if (newivm->iv->l == -1) {
2839: plog(LLV_ERROR, LOCATION, NULL,
2840: "invalid encryption algorithm %d.\n",
2841: iph1->approval->enctype);
2842: vfree(buf);
2843: oakley_delivm(newivm);
2844: return -1;
2845: }
2846:
2847: /* create buffer to save iv */
2848: if ((newivm->ive = vdup(newivm->iv)) == NULL) {
2849: plog(LLV_ERROR, LOCATION, NULL,
2850: "vdup (%s)\n", strerror(errno));
2851: vfree(buf);
2852: oakley_delivm(newivm);
2853: return -1;
2854: }
2855:
2856: vfree(buf);
2857:
2858: plog(LLV_DEBUG, LOCATION, NULL, "IV computed:\n");
2859: plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l);
2860:
2861: iph1->ivm = newivm;
2862:
2863: return 0;
2864: }
2865:
2866: /*
2867: * compute IV for the payload after phase 1.
2868: * It's not limited for phase 2.
2869: * if pahse 1 was encrypted.
2870: * IV = hash(last CBC block of Phase 1 | M-ID)
2871: * if phase 1 was not encrypted.
2872: * IV = hash(phase 1 IV | M-ID)
2873: * see 4.2 Phase 2 state in draft-ietf-ipsec-ike.
2874: */
2875: struct isakmp_ivm *
2876: oakley_newiv2(iph1, msgid)
2877: struct ph1handle *iph1;
2878: u_int32_t msgid;
2879: {
2880: struct isakmp_ivm *newivm = NULL;
2881: vchar_t *buf = NULL;
2882: char *p;
2883: int len;
2884: int error = -1;
2885:
2886: /* create buffer */
2887: len = iph1->ivm->iv->l + sizeof(msgid_t);
2888: buf = vmalloc(len);
2889: if (buf == NULL) {
2890: plog(LLV_ERROR, LOCATION, NULL,
2891: "failed to get iv buffer\n");
2892: goto end;
2893: }
2894:
2895: p = buf->v;
2896:
2897: memcpy(p, iph1->ivm->iv->v, iph1->ivm->iv->l);
2898: p += iph1->ivm->iv->l;
2899:
2900: memcpy(p, &msgid, sizeof(msgid));
2901:
2902: plog(LLV_DEBUG, LOCATION, NULL, "compute IV for phase2\n");
2903: plog(LLV_DEBUG, LOCATION, NULL, "phase1 last IV:\n");
2904: plogdump(LLV_DEBUG, buf->v, buf->l);
2905:
2906: /* allocate IVm */
2907: newivm = racoon_calloc(1, sizeof(struct isakmp_ivm));
2908: if (newivm == NULL) {
2909: plog(LLV_ERROR, LOCATION, NULL,
2910: "failed to get iv buffer\n");
2911: goto end;
2912: }
2913:
2914: /* compute IV */
2915: if ((newivm->iv = oakley_hash(buf, iph1)) == NULL)
2916: goto end;
2917:
2918: /* adjust length of iv */
2919: newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype);
2920: if (newivm->iv->l == -1) {
2921: plog(LLV_ERROR, LOCATION, NULL,
2922: "invalid encryption algorithm %d.\n",
2923: iph1->approval->enctype);
2924: goto end;
2925: }
2926:
2927: /* create buffer to save new iv */
2928: if ((newivm->ive = vdup(newivm->iv)) == NULL) {
2929: plog(LLV_ERROR, LOCATION, NULL, "vdup (%s)\n", strerror(errno));
2930: goto end;
2931: }
2932:
2933: error = 0;
2934:
2935: plog(LLV_DEBUG, LOCATION, NULL, "phase2 IV computed:\n");
2936: plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l);
2937:
2938: end:
2939: if (error && newivm != NULL){
2940: oakley_delivm(newivm);
2941: newivm=NULL;
2942: }
2943: if (buf != NULL)
2944: vfree(buf);
2945: return newivm;
2946: }
2947:
2948: void
2949: oakley_delivm(ivm)
2950: struct isakmp_ivm *ivm;
2951: {
2952: if (ivm == NULL)
2953: return;
2954:
2955: if (ivm->iv != NULL)
2956: vfree(ivm->iv);
2957: if (ivm->ive != NULL)
2958: vfree(ivm->ive);
2959: racoon_free(ivm);
2960: plog(LLV_DEBUG, LOCATION, NULL, "IV freed\n");
2961:
2962: return;
2963: }
2964:
2965: /*
2966: * decrypt packet.
2967: * save new iv and old iv.
2968: */
2969: vchar_t *
2970: oakley_do_decrypt(iph1, msg, ivdp, ivep)
2971: struct ph1handle *iph1;
2972: vchar_t *msg, *ivdp, *ivep;
2973: {
2974: vchar_t *buf = NULL, *new = NULL;
2975: char *pl;
2976: int len;
2977: u_int8_t padlen;
2978: int blen;
2979: int error = -1;
2980:
2981: plog(LLV_DEBUG, LOCATION, NULL, "begin decryption.\n");
2982:
2983: blen = alg_oakley_encdef_blocklen(iph1->approval->enctype);
2984: if (blen == -1) {
2985: plog(LLV_ERROR, LOCATION, NULL,
2986: "invalid encryption algorithm %d.\n",
2987: iph1->approval->enctype);
2988: goto end;
2989: }
2990:
2991: /* save IV for next, but not sync. */
2992: memset(ivep->v, 0, ivep->l);
2993: memcpy(ivep->v, (caddr_t)&msg->v[msg->l - blen], blen);
2994:
2995: plog(LLV_DEBUG, LOCATION, NULL,
2996: "IV was saved for next processing:\n");
2997: plogdump(LLV_DEBUG, ivep->v, ivep->l);
2998:
2999: pl = msg->v + sizeof(struct isakmp);
3000:
3001: len = msg->l - sizeof(struct isakmp);
3002:
3003: /* create buffer */
3004: buf = vmalloc(len);
3005: if (buf == NULL) {
3006: plog(LLV_ERROR, LOCATION, NULL,
3007: "failed to get buffer to decrypt.\n");
3008: goto end;
3009: }
3010: memcpy(buf->v, pl, len);
3011:
3012: /* do decrypt */
3013: new = alg_oakley_encdef_decrypt(iph1->approval->enctype,
3014: buf, iph1->key, ivdp);
3015: if (new == NULL || new->v == NULL || new->l == 0) {
3016: plog(LLV_ERROR, LOCATION, NULL,
3017: "decryption %d failed.\n", iph1->approval->enctype);
3018: goto end;
3019: }
3020: plog(LLV_DEBUG, LOCATION, NULL, "with key:\n");
3021: plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
3022:
3023: vfree(buf);
3024: buf = NULL;
3025:
3026: plog(LLV_DEBUG, LOCATION, NULL, "decrypted payload by IV:\n");
3027: plogdump(LLV_DEBUG, ivdp->v, ivdp->l);
3028:
3029: plog(LLV_DEBUG, LOCATION, NULL,
3030: "decrypted payload, but not trimed.\n");
3031: plogdump(LLV_DEBUG, new->v, new->l);
3032:
3033: /* get padding length */
3034: if (lcconf->pad_excltail)
3035: padlen = new->v[new->l - 1] + 1;
3036: else
3037: padlen = new->v[new->l - 1];
3038: plog(LLV_DEBUG, LOCATION, NULL, "padding len=%u\n", padlen);
3039:
3040: /* trim padding */
3041: if (lcconf->pad_strict) {
3042: if (padlen > new->l) {
3043: plog(LLV_ERROR, LOCATION, NULL,
3044: "invalied padding len=%u, buflen=%zu.\n",
3045: padlen, new->l);
3046: plogdump(LLV_ERROR, new->v, new->l);
3047: goto end;
3048: }
3049: new->l -= padlen;
3050: plog(LLV_DEBUG, LOCATION, NULL, "trimmed padding\n");
3051: } else {
3052: plog(LLV_DEBUG, LOCATION, NULL, "skip to trim padding.\n");
3053: }
3054:
3055: /* create new buffer */
3056: len = sizeof(struct isakmp) + new->l;
3057: buf = vmalloc(len);
3058: if (buf == NULL) {
3059: plog(LLV_ERROR, LOCATION, NULL,
3060: "failed to get buffer to decrypt.\n");
3061: goto end;
3062: }
3063: memcpy(buf->v, msg->v, sizeof(struct isakmp));
3064: memcpy(buf->v + sizeof(struct isakmp), new->v, new->l);
3065: ((struct isakmp *)buf->v)->len = htonl(buf->l);
3066:
3067: plog(LLV_DEBUG, LOCATION, NULL, "decrypted.\n");
3068: plogdump(LLV_DEBUG, buf->v, buf->l);
3069:
3070: #ifdef HAVE_PRINT_ISAKMP_C
3071: isakmp_printpacket(buf, iph1->remote, iph1->local, 1);
3072: #endif
3073:
3074: error = 0;
3075:
3076: end:
3077: if (error && buf != NULL) {
3078: vfree(buf);
3079: buf = NULL;
3080: }
3081: if (new != NULL)
3082: vfree(new);
3083:
3084: return buf;
3085: }
3086:
3087: /*
3088: * encrypt packet.
3089: */
3090: vchar_t *
3091: oakley_do_encrypt(iph1, msg, ivep, ivp)
3092: struct ph1handle *iph1;
3093: vchar_t *msg, *ivep, *ivp;
3094: {
3095: vchar_t *buf = 0, *new = 0;
3096: char *pl;
3097: int len;
3098: u_int padlen;
3099: int blen;
3100: int error = -1;
3101:
3102: plog(LLV_DEBUG, LOCATION, NULL, "begin encryption.\n");
3103:
3104: /* set cbc block length */
3105: blen = alg_oakley_encdef_blocklen(iph1->approval->enctype);
3106: if (blen == -1) {
3107: plog(LLV_ERROR, LOCATION, NULL,
3108: "invalid encryption algorithm %d.\n",
3109: iph1->approval->enctype);
3110: goto end;
3111: }
3112:
3113: pl = msg->v + sizeof(struct isakmp);
3114: len = msg->l - sizeof(struct isakmp);
3115:
3116: /* add padding */
3117: padlen = oakley_padlen(len, blen);
3118: plog(LLV_DEBUG, LOCATION, NULL, "pad length = %u\n", padlen);
3119:
3120: /* create buffer */
3121: buf = vmalloc(len + padlen);
3122: if (buf == NULL) {
3123: plog(LLV_ERROR, LOCATION, NULL,
3124: "failed to get buffer to encrypt.\n");
3125: goto end;
3126: }
3127: if (padlen) {
3128: int i;
3129: char *p = &buf->v[len];
3130: if (lcconf->pad_random) {
3131: for (i = 0; i < padlen; i++)
3132: *p++ = eay_random() & 0xff;
3133: }
3134: }
3135: memcpy(buf->v, pl, len);
3136:
3137: /* make pad into tail */
3138: if (lcconf->pad_excltail)
3139: buf->v[len + padlen - 1] = padlen - 1;
3140: else
3141: buf->v[len + padlen - 1] = padlen;
3142:
3143: plogdump(LLV_DEBUG, buf->v, buf->l);
3144:
3145: /* do encrypt */
3146: new = alg_oakley_encdef_encrypt(iph1->approval->enctype,
3147: buf, iph1->key, ivep);
3148: if (new == NULL) {
3149: plog(LLV_ERROR, LOCATION, NULL,
3150: "encryption %d failed.\n", iph1->approval->enctype);
3151: goto end;
3152: }
3153: plog(LLV_DEBUG, LOCATION, NULL, "with key:\n");
3154: plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
3155:
3156: vfree(buf);
3157: buf = NULL;
3158:
3159: plog(LLV_DEBUG, LOCATION, NULL, "encrypted payload by IV:\n");
3160: plogdump(LLV_DEBUG, ivep->v, ivep->l);
3161:
3162: /* save IV for next */
3163: memset(ivp->v, 0, ivp->l);
3164: memcpy(ivp->v, (caddr_t)&new->v[new->l - blen], blen);
3165:
3166: plog(LLV_DEBUG, LOCATION, NULL, "save IV for next:\n");
3167: plogdump(LLV_DEBUG, ivp->v, ivp->l);
3168:
3169: /* create new buffer */
3170: len = sizeof(struct isakmp) + new->l;
3171: buf = vmalloc(len);
3172: if (buf == NULL) {
3173: plog(LLV_ERROR, LOCATION, NULL,
3174: "failed to get buffer to encrypt.\n");
3175: goto end;
3176: }
3177: memcpy(buf->v, msg->v, sizeof(struct isakmp));
3178: memcpy(buf->v + sizeof(struct isakmp), new->v, new->l);
3179: ((struct isakmp *)buf->v)->len = htonl(buf->l);
3180:
3181: error = 0;
3182:
3183: plog(LLV_DEBUG, LOCATION, NULL, "encrypted.\n");
3184:
3185: end:
3186: if (error && buf != NULL) {
3187: vfree(buf);
3188: buf = NULL;
3189: }
3190: if (new != NULL)
3191: vfree(new);
3192:
3193: return buf;
3194: }
3195:
3196: /* culculate padding length */
3197: static int
3198: oakley_padlen(len, base)
3199: int len, base;
3200: {
3201: int padlen;
3202:
3203: padlen = base - len % base;
3204:
3205: if (lcconf->pad_randomlen)
3206: padlen += ((eay_random() % (lcconf->pad_maxsize + 1) + 1) *
3207: base);
3208:
3209: return padlen;
3210: }
3211:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>