source: rtems-libbsd/ipsec-tools/src/racoon/oakley.c @ ff36f5e

55-freebsd-126-freebsd-12
Last change on this file since ff36f5e was ff36f5e, checked in by Christian Mauderer <christian.mauderer@…>, on 05/30/18 at 12:27:35

Import ipsec-tools 0.8.2.

Import unchanged ipsec-tools sources in the release version 0.8.2. The
homepage of ipsec-tools is http://ipsec-tools.sourceforge.net/. The
sources can be obtained from there.

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