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