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