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