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

55-freebsd-126-freebsd-12
Last change on this file since b376ae1 was b376ae1, checked in by Christian Mauderer <christian.mauderer@…>, on 05/03/18 at 12:15:11

ipsec-tools: Port libipsec, setkey and racoon.

Note that this replaces the libipsec from FreeBSD with the one provided
by ipsec-tools.

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