]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/oakley.c
ipsec-146.1.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / oakley.c
1 /* $NetBSD: oakley.c,v 1.9.6.2 2007/04/04 13:08:28 vanhu Exp $ */
2
3 /* Id: oakley.c,v 1.32 2006/05/26 12:19:46 manubsd Exp */
4
5 /*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include "config.h"
35
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h> /* XXX for subjectaltname */
39 #include <netinet/in.h> /* XXX for subjectaltname */
40
41 #ifdef HAVE_OPENSSL
42 #include <openssl/pkcs7.h>
43 #include <openssl/x509.h>
44 #endif
45
46 #include <stdlib.h>
47 #include <stdio.h>
48 #include <string.h>
49 #include <errno.h>
50 #include <arpa/inet.h>
51 #include <TargetConditionals.h>
52
53 #if TIME_WITH_SYS_TIME
54 # include <sys/time.h>
55 # include <time.h>
56 #else
57 # if HAVE_SYS_TIME_H
58 # include <sys/time.h>
59 # else
60 # include <time.h>
61 # endif
62 #endif
63 #ifdef ENABLE_HYBRID
64 #include <resolv.h>
65 #endif
66
67 #include "var.h"
68 #include "misc.h"
69 #include "vmbuf.h"
70 #include "str2val.h"
71 #include "plog.h"
72 #include "debug.h"
73
74 #include "isakmp_var.h"
75 #include "isakmp.h"
76 #ifdef ENABLE_HYBRID
77 #include "isakmp_xauth.h"
78 #include "isakmp_cfg.h"
79 #endif
80 #include "oakley.h"
81 #include "admin.h"
82 #include "privsep.h"
83 #include "localconf.h"
84 #include "policy.h"
85 #include "handler.h"
86 #include "ipsec_doi.h"
87 #include "algorithm.h"
88 #include "dhgroup.h"
89 #include "sainfo.h"
90 #include "proposal.h"
91 #include "crypto_openssl.h"
92 #include "crypto_cssm.h"
93 #if HAVE_OPENDIR
94 #include "open_dir.h"
95 #endif
96 #include "dnssec.h"
97 #include "sockmisc.h"
98 #include "strnames.h"
99 #include "gcmalloc.h"
100 #ifdef HAVE_OPENSSL
101 #include "rsalist.h"
102 #endif
103 #include <CoreFoundation/CoreFoundation.h>
104 #include "remoteconf.h"
105 #include "vpn_control.h"
106 #if TARGET_OS_EMBEDDED
107 #include <Security/SecCertificate.h>
108 #include <Security/SecCertificatePriv.h>
109 #endif
110 #ifdef HAVE_GSSAPI
111 #include "gssapi.h"
112 #endif
113 #include "vpn_control_var.h"
114
115 #define OUTBOUND_SA 0
116 #define INBOUND_SA 1
117
118 #define CERT_CHECKID_FROM_PEER 0
119 #define CERT_CHECKID_FROM_RMCONFIG 1
120
121 #ifdef HAVE_OPENSSL
122 #define INITDHVAL(a, s, d, t) \
123 do { \
124 vchar_t buf; \
125 buf.v = str2val((s), 16, &buf.l); \
126 memset(&a, 0, sizeof(struct dhgroup)); \
127 a.type = (t); \
128 a.prime = vdup(&buf); \
129 a.gen1 = 2; \
130 a.gen2 = 0; \
131 racoon_free(buf.v); \
132 } while(0);
133 #else /* HAVE_OPENSSL */
134 #define INITDHVAL(a, s, d, t) \
135 do { \
136 vchar_t buf; \
137 buf.v = str2val((s), 16, &buf.l); \
138 memset(&a, 0, sizeof(struct dhgroup)); \
139 a.desc = (d); \
140 a.type = (t); \
141 a.prime = vdup(&buf); \
142 a.gen1 = 2; \
143 a.gen2 = 0; \
144 racoon_free(buf.v); \
145 } while(0);
146 #endif /* HAVE_OPENSSL */
147
148 struct dhgroup dh_modp768;
149 struct dhgroup dh_modp1024;
150 struct dhgroup dh_modp1536;
151 struct dhgroup dh_modp2048;
152 struct dhgroup dh_modp3072;
153 struct dhgroup dh_modp4096;
154 struct dhgroup dh_modp6144;
155 struct dhgroup dh_modp8192;
156
157
158 static int oakley_check_dh_pub __P((vchar_t *, vchar_t **));
159 static int oakley_compute_keymat_x __P((struct ph2handle *, int, int));
160 static int get_cert_fromlocal __P((struct ph1handle *, int));
161 #ifdef HAVE_OPENSSL
162 static int get_plainrsa_fromlocal __P((struct ph1handle *, int));
163 #endif
164 static int oakley_check_certid __P((struct ph1handle *iph1, int));
165 static int oakley_check_certid_1 __P((vchar_t *, int, int, void*, cert_status_t *certStatus));
166 static int check_typeofcertname __P((int, int));
167 static cert_t *save_certbuf __P((struct isakmp_gen *));
168 #ifdef HAVE_OPENSSL
169 static cert_t *save_certx509 __P((X509 *));
170 #endif
171 static int oakley_padlen __P((int, int));
172
173 static int base64toCFData(vchar_t *, CFDataRef*);
174 static cert_t *oakley_appendcert_to_certchain(cert_t *, cert_t *);
175
176 static void oakley_cert_prettyprint (vchar_t *cert)
177 {
178 char *p = NULL;
179 #ifdef HAVE_OPENSSL
180 p = eay_get_x509text(cert);
181 #else
182 /* add new cert dump code here */
183 #endif
184 plog(LLV_DEBUG, LOCATION, NULL, "%s", p ? p : "\n");
185 racoon_free(p);
186 }
187
188 int
189 oakley_get_defaultlifetime()
190 {
191 return OAKLEY_ATTR_SA_LD_SEC_DEFAULT;
192 }
193
194 int
195 oakley_dhinit()
196 {
197 /* set DH MODP */
198 INITDHVAL(dh_modp768, OAKLEY_PRIME_MODP768,
199 OAKLEY_ATTR_GRP_DESC_MODP768, OAKLEY_ATTR_GRP_TYPE_MODP);
200 INITDHVAL(dh_modp1024, OAKLEY_PRIME_MODP1024,
201 OAKLEY_ATTR_GRP_DESC_MODP1024, OAKLEY_ATTR_GRP_TYPE_MODP);
202 INITDHVAL(dh_modp1536, OAKLEY_PRIME_MODP1536,
203 OAKLEY_ATTR_GRP_DESC_MODP1536, OAKLEY_ATTR_GRP_TYPE_MODP);
204 INITDHVAL(dh_modp2048, OAKLEY_PRIME_MODP2048,
205 OAKLEY_ATTR_GRP_DESC_MODP2048, OAKLEY_ATTR_GRP_TYPE_MODP);
206 INITDHVAL(dh_modp3072, OAKLEY_PRIME_MODP3072,
207 OAKLEY_ATTR_GRP_DESC_MODP3072, OAKLEY_ATTR_GRP_TYPE_MODP);
208 INITDHVAL(dh_modp4096, OAKLEY_PRIME_MODP4096,
209 OAKLEY_ATTR_GRP_DESC_MODP4096, OAKLEY_ATTR_GRP_TYPE_MODP);
210 INITDHVAL(dh_modp6144, OAKLEY_PRIME_MODP6144,
211 OAKLEY_ATTR_GRP_DESC_MODP6144, OAKLEY_ATTR_GRP_TYPE_MODP);
212 INITDHVAL(dh_modp8192, OAKLEY_PRIME_MODP8192,
213 OAKLEY_ATTR_GRP_DESC_MODP8192, OAKLEY_ATTR_GRP_TYPE_MODP);
214
215 return 0;
216 }
217
218 void
219 oakley_dhgrp_free(dhgrp)
220 struct dhgroup *dhgrp;
221 {
222 if (dhgrp->prime)
223 vfree(dhgrp->prime);
224 if (dhgrp->curve_a)
225 vfree(dhgrp->curve_a);
226 if (dhgrp->curve_b)
227 vfree(dhgrp->curve_b);
228 if (dhgrp->order)
229 vfree(dhgrp->order);
230 racoon_free(dhgrp);
231 }
232
233 /*
234 * RFC2409 5
235 * The length of the Diffie-Hellman public value MUST be equal to the
236 * length of the prime modulus over which the exponentiation was
237 * performed, prepending zero bits to the value if necessary.
238 */
239 static int
240 oakley_check_dh_pub(prime, pub0)
241 vchar_t *prime, **pub0;
242 {
243 vchar_t *tmp;
244 vchar_t *pub = *pub0;
245
246 if (prime->l == pub->l)
247 return 0;
248
249 if (prime->l < pub->l) {
250 /* what should i do ? */
251 plog(LLV_ERROR, LOCATION, NULL,
252 "invalid public information was generated.\n");
253 return -1;
254 }
255
256 /* prime->l > pub->l */
257 tmp = vmalloc(prime->l);
258 if (tmp == NULL) {
259 plog(LLV_ERROR, LOCATION, NULL,
260 "failed to get DH buffer.\n");
261 return -1;
262 }
263 memcpy(tmp->v + prime->l - pub->l, pub->v, pub->l);
264
265 vfree(*pub0);
266 *pub0 = tmp;
267
268 return 0;
269 }
270
271 /*
272 * compute sharing secret of DH
273 * IN: *dh, *pub, *priv, *pub_p
274 * OUT: **gxy
275 */
276 #ifdef HAVE_OPENSSL
277 int
278 oakley_dh_compute(const struct dhgroup *dh, vchar_t *pub, vchar_t *priv, vchar_t *pub_p, vchar_t **gxy)
279 {
280 #ifdef ENABLE_STATS
281 struct timeval start, end;
282 #endif
283 if ((*gxy = vmalloc(dh->prime->l)) == NULL) {
284 plog(LLV_ERROR, LOCATION, NULL,
285 "failed to get DH buffer.\n");
286 return -1;
287 }
288
289 #ifdef ENABLE_STATS
290 gettimeofday(&start, NULL);
291 #endif
292 switch (dh->type) {
293 case OAKLEY_ATTR_GRP_TYPE_MODP:
294 if (eay_dh_compute(dh->prime, dh->gen1, pub, priv, pub_p, gxy) < 0) {
295 plog(LLV_ERROR, LOCATION, NULL,
296 "failed to compute dh value.\n");
297 return -1;
298 }
299 break;
300 case OAKLEY_ATTR_GRP_TYPE_ECP:
301 case OAKLEY_ATTR_GRP_TYPE_EC2N:
302 plog(LLV_ERROR, LOCATION, NULL,
303 "dh type %d isn't supported.\n", dh->type);
304 return -1;
305 default:
306 plog(LLV_ERROR, LOCATION, NULL,
307 "invalid dh type %d.\n", dh->type);
308 return -1;
309 }
310
311 #ifdef ENABLE_STATS
312 gettimeofday(&end, NULL);
313 syslog(LOG_NOTICE, "%s(%s%d): %8.6f", __func__,
314 s_attr_isakmp_group(dh->type), dh->prime->l << 3,
315 timedelta(&start, &end));
316 #endif
317
318 plog(LLV_DEBUG, LOCATION, NULL, "compute DH's shared.\n");
319 plogdump(LLV_DEBUG, (*gxy)->v, (*gxy)->l);
320
321 return 0;
322 }
323 #else
324 int
325 oakley_dh_compute(const struct dhgroup *dh, vchar_t *pub_p, size_t publicKeySize, vchar_t **gxy, SecDHContext dhC)
326 {
327
328 vchar_t *computed_key = NULL;
329 size_t computed_keylen;
330 size_t maxKeyLen;
331
332 #ifdef ENABLE_STATS
333 struct timeval start, end;
334 gettimeofday(&start, NULL);
335 #endif
336
337 plog(LLV_DEBUG, LOCATION, NULL, "compute DH result.\n");
338
339 maxKeyLen = SecDHGetMaxKeyLength(dhC);
340 computed_key = vmalloc(maxKeyLen);
341 if (computed_key == NULL) {
342 plog(LLV_ERROR, LOCATION, NULL, "memory error.\n");
343 goto fail;
344 }
345 computed_keylen = computed_key->l;
346 if (SecDHComputeKey(dhC, pub_p->v + (maxKeyLen - publicKeySize), publicKeySize,
347 computed_key->v, &computed_keylen)) {
348 plog(LLV_ERROR, LOCATION, NULL, "failed to compute dh value.\n");
349 goto fail;
350 }
351
352 #ifdef ENABLE_STATS
353 gettimeofday(&end, NULL);
354 syslog(LOG_NOTICE, "%s(%s%d): %8.6f", __func__,
355 s_attr_isakmp_group(dh->type), dh->prime->l << 3,
356 timedelta(&start, &end));
357 #endif
358
359 *gxy = vmalloc(maxKeyLen);
360 if (*gxy == NULL) {
361 plog(LLV_ERROR, LOCATION, NULL, "memory error.\n");
362 goto fail;
363 }
364 memcpy((*gxy)->v + (maxKeyLen - computed_keylen), computed_key->v, computed_keylen);
365 plog(LLV_DEBUG, LOCATION, NULL, "compute DH's shared.\n");
366 plogdump(LLV_DEBUG, (*gxy)->v, (*gxy)->l);
367 SecDHDestroy(dhC);
368 vfree(computed_key);
369 return 0;
370
371 fail:
372 SecDHDestroy(dhC);
373 vfree(*gxy);
374 vfree(computed_key);
375 return -1;
376 }
377
378 #endif
379
380 /*
381 * generate values of DH
382 * IN: *dh
383 * OUT: **pub, **priv
384 */
385 #ifdef HAVE_OPENSSL
386 int
387 oakley_dh_generate(dh, pub, priv)
388 const struct dhgroup *dh;
389 vchar_t **pub, **priv;
390 {
391 #ifdef ENABLE_STATS
392 struct timeval start, end;
393 gettimeofday(&start, NULL);
394 #endif
395 switch (dh->type) {
396 case OAKLEY_ATTR_GRP_TYPE_MODP:
397 if (eay_dh_generate(dh->prime, dh->gen1, dh->gen2, pub, priv) < 0) {
398 plog(LLV_ERROR, LOCATION, NULL,
399 "failed to compute dh value.\n");
400 return -1;
401 }
402 break;
403
404 case OAKLEY_ATTR_GRP_TYPE_ECP:
405 case OAKLEY_ATTR_GRP_TYPE_EC2N:
406 plog(LLV_ERROR, LOCATION, NULL,
407 "dh type %d isn't supported.\n", dh->type);
408 return -1;
409 default:
410 plog(LLV_ERROR, LOCATION, NULL,
411 "invalid dh type %d.\n", dh->type);
412 return -1;
413 }
414
415 #ifdef ENABLE_STATS
416 gettimeofday(&end, NULL);
417 syslog(LOG_NOTICE, "%s(%s%d): %8.6f", __func__,
418 s_attr_isakmp_group(dh->type), dh->prime->l << 3,
419 timedelta(&start, &end));
420 #endif
421
422 if (oakley_check_dh_pub(dh->prime, pub) != 0)
423 return -1;
424
425 plog(LLV_DEBUG, LOCATION, NULL, "compute DH's private.\n");
426 plogdump(LLV_DEBUG, (*priv)->v, (*priv)->l);
427 plog(LLV_DEBUG, LOCATION, NULL, "compute DH's public.\n");
428 plogdump(LLV_DEBUG, (*pub)->v, (*pub)->l);
429
430 return 0;
431 }
432 #else
433 int
434 oakley_dh_generate(const struct dhgroup *dh, vchar_t **pub, size_t *publicKeySize, SecDHContext *dhC)
435 {
436 vchar_t *public = NULL;
437 size_t maxKeyLen;
438
439 #ifdef ENABLE_STATS
440 struct timeval start, end;
441 gettimeofday(&start, NULL);
442 #endif
443
444 plog(LLV_DEBUG, LOCATION, NULL, "generate DH key pair.\n");
445 *pub = NULL;
446 switch (dh->type) {
447 case OAKLEY_ATTR_GRP_TYPE_MODP:
448 if (dh->desc != OAKLEY_ATTR_GRP_DESC_MODP1024 && dh->desc != OAKLEY_ATTR_GRP_DESC_MODP1536) {
449 plog(LLV_ERROR, LOCATION, NULL, "Invalid dh group.\n");
450 goto fail;
451 }
452 if (SecDHCreate(dh->desc, dh->prime->v, dh->prime->l, 0, NULL, 0, dhC)) {
453 plog(LLV_ERROR, LOCATION, NULL, "failed to create dh context.\n");
454 goto fail;
455 }
456 maxKeyLen = SecDHGetMaxKeyLength(*dhC);
457 public = vmalloc(maxKeyLen);
458 *publicKeySize = public->l;
459 if (public == NULL) {
460 plog(LLV_ERROR, LOCATION, NULL, "memory error.\n");
461 goto fail;
462 }
463 if (SecDHGenerateKeypair(*dhC, public->v, publicKeySize)) {
464 plog(LLV_ERROR, LOCATION, NULL, "failed to generate dh key pair.\n");
465 goto fail;
466 }
467 plog(LLV_DEBUG, LOCATION, NULL, "got DH key pair.\n");
468
469 *pub = vmalloc(maxKeyLen);
470 if (*pub == NULL) {
471 plog(LLV_ERROR, LOCATION, NULL, "memory error.\n");
472 goto fail;
473 }
474 /* copy and fill with leading zeros */
475 memcpy((*pub)->v + (maxKeyLen - *publicKeySize), public->v, *publicKeySize);
476 break;
477
478 case OAKLEY_ATTR_GRP_TYPE_ECP:
479 case OAKLEY_ATTR_GRP_TYPE_EC2N:
480 plog(LLV_ERROR, LOCATION, NULL,
481 "dh type %d isn't supported.\n", dh->type);
482 goto fail;
483 default:
484 plog(LLV_ERROR, LOCATION, NULL,
485 "invalid dh type %d.\n", dh->type);
486 goto fail;
487 }
488
489 #ifdef ENABLE_STATS
490 gettimeofday(&end, NULL);
491 syslog(LOG_NOTICE, "%s(%s%d): %8.6f", __func__,
492 s_attr_isakmp_group(dh->type), dh->prime->l << 3,
493 timedelta(&start, &end));
494 #endif
495
496 if (oakley_check_dh_pub(dh->prime, pub) != 0) {
497 plog(LLV_DEBUG, LOCATION, NULL, "failed DH public key size check.\n");
498 goto fail;
499 }
500
501 plog(LLV_DEBUG, LOCATION, NULL, "compute DH's private.\n");
502 plog(LLV_DEBUG, LOCATION, NULL, "compute DH's public.\n");
503 plogdump(LLV_DEBUG, (*pub)->v, (*pub)->l);
504
505 vfree(public);
506 return 0;
507
508 fail:
509 SecDHDestroy(*dhC);
510 vfree(*pub);
511 vfree(public);
512 return -1;
513
514 }
515 #endif
516
517 /*
518 * copy pre-defined dhgroup values.
519 */
520 int
521 oakley_setdhgroup(group, dhgrp)
522 int group;
523 struct dhgroup **dhgrp;
524 {
525 struct dhgroup *g;
526
527 *dhgrp = NULL; /* just make sure, initialize */
528
529 g = alg_oakley_dhdef_group(group);
530 if (g == NULL) {
531 plog(LLV_ERROR, LOCATION, NULL,
532 "invalid DH parameter grp=%d.\n", group);
533 return -1;
534 }
535
536 if (!g->type || !g->prime || !g->gen1) {
537 /* unsuported */
538 plog(LLV_ERROR, LOCATION, NULL,
539 "unsupported DH parameters grp=%d.\n", group);
540 return -1;
541 }
542
543 *dhgrp = racoon_calloc(1, sizeof(struct dhgroup));
544 if (*dhgrp == NULL) {
545 plog(LLV_ERROR, LOCATION, NULL,
546 "failed to get DH buffer.\n");
547 return 0;
548 }
549
550 /* set defined dh vlaues */
551 memcpy(*dhgrp, g, sizeof(*g));
552 (*dhgrp)->prime = vdup(g->prime);
553
554 return 0;
555 }
556
557 /*
558 * PRF
559 *
560 * NOTE: we do not support prf with different input/output bitwidth,
561 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example) in
562 * oakley_compute_keymat(). If you add support for such prf function,
563 * modify oakley_compute_keymat() accordingly.
564 */
565 vchar_t *
566 oakley_prf(key, buf, iph1)
567 vchar_t *key, *buf;
568 struct ph1handle *iph1;
569 {
570 vchar_t *res = NULL;
571 int type;
572
573 if (iph1->approval == NULL) {
574 /*
575 * it's before negotiating hash algorithm.
576 * We use md5 as default.
577 */
578 type = OAKLEY_ATTR_HASH_ALG_MD5;
579 } else
580 type = iph1->approval->hashtype;
581
582 res = alg_oakley_hmacdef_one(type, key, buf);
583 if (res == NULL) {
584 plog(LLV_ERROR, LOCATION, NULL,
585 "invalid hmac algorithm %d.\n", type);
586 return NULL;
587 }
588
589 return res;
590 }
591
592 /*
593 * hash
594 */
595 vchar_t *
596 oakley_hash(buf, iph1)
597 vchar_t *buf;
598 struct ph1handle *iph1;
599 {
600 vchar_t *res = NULL;
601 int type;
602
603 if (iph1->approval == NULL) {
604 /*
605 * it's before negotiating hash algorithm.
606 * We use md5 as default.
607 */
608 type = OAKLEY_ATTR_HASH_ALG_MD5;
609 } else
610 type = iph1->approval->hashtype;
611
612 res = alg_oakley_hashdef_one(type, buf);
613 if (res == NULL) {
614 plog(LLV_ERROR, LOCATION, NULL,
615 "invalid hash algorithm %d.\n", type);
616 return NULL;
617 }
618
619 return res;
620 }
621
622 /*
623 * compute KEYMAT
624 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
625 */
626 int
627 oakley_compute_keymat(iph2, side)
628 struct ph2handle *iph2;
629 int side;
630 {
631 int error = -1;
632
633 /* compute sharing secret of DH when PFS */
634 if (iph2->approval->pfs_group && iph2->dhpub_p) {
635 #ifdef HAVE_OPENSSL
636 if (oakley_dh_compute(iph2->pfsgrp, iph2->dhpub,
637 iph2->dhpriv, iph2->dhpub_p, &iph2->dhgxy) < 0)
638 #else
639 if (oakley_dh_compute(iph2->pfsgrp, iph2->dhpub_p, iph2->publicKeySize, &iph2->dhgxy, iph2->dhC) < 0)
640 #endif
641 goto end;
642 }
643
644 /* compute keymat */
645 if (oakley_compute_keymat_x(iph2, side, INBOUND_SA) < 0
646 || oakley_compute_keymat_x(iph2, side, OUTBOUND_SA) < 0)
647 goto end;
648
649 plog(LLV_DEBUG, LOCATION, NULL, "KEYMAT computed.\n");
650
651 error = 0;
652
653 end:
654 return error;
655 }
656
657 /*
658 * compute KEYMAT.
659 * KEYMAT = prf(SKEYID_d, protocol | SPI | Ni_b | Nr_b).
660 * If PFS is desired and KE payloads were exchanged,
661 * KEYMAT = prf(SKEYID_d, g(qm)^xy | protocol | SPI | Ni_b | Nr_b)
662 *
663 * NOTE: we do not support prf with different input/output bitwidth,
664 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example).
665 */
666 static int
667 oakley_compute_keymat_x(iph2, side, sa_dir)
668 struct ph2handle *iph2;
669 int side;
670 int sa_dir;
671 {
672 vchar_t *buf = NULL, *res = NULL, *bp;
673 char *p;
674 int len;
675 int error = -1;
676 int pfs = 0;
677 int dupkeymat; /* generate K[1-dupkeymat] */
678 struct saproto *pr;
679 struct satrns *tr;
680 int encklen, authklen, l;
681
682 pfs = ((iph2->approval->pfs_group && iph2->dhgxy) ? 1 : 0);
683
684 len = pfs ? iph2->dhgxy->l : 0;
685 len += (1
686 + sizeof(u_int32_t) /* XXX SPI size */
687 + iph2->nonce->l
688 + iph2->nonce_p->l);
689 buf = vmalloc(len);
690 if (buf == NULL) {
691 plog(LLV_ERROR, LOCATION, NULL,
692 "failed to get keymat buffer.\n");
693 goto end;
694 }
695
696 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
697 p = buf->v;
698
699 /* if PFS */
700 if (pfs) {
701 memcpy(p, iph2->dhgxy->v, iph2->dhgxy->l);
702 p += iph2->dhgxy->l;
703 }
704
705 p[0] = pr->proto_id;
706 p += 1;
707
708 memcpy(p, (sa_dir == INBOUND_SA ? &pr->spi : &pr->spi_p),
709 sizeof(pr->spi));
710 p += sizeof(pr->spi);
711
712 bp = (side == INITIATOR ? iph2->nonce : iph2->nonce_p);
713 memcpy(p, bp->v, bp->l);
714 p += bp->l;
715
716 bp = (side == INITIATOR ? iph2->nonce_p : iph2->nonce);
717 memcpy(p, bp->v, bp->l);
718 p += bp->l;
719
720 /* compute IV */
721 plog(LLV_DEBUG, LOCATION, NULL, "KEYMAT compute with\n");
722 plogdump(LLV_DEBUG, buf->v, buf->l);
723
724 /* res = K1 */
725 res = oakley_prf(iph2->ph1->skeyid_d, buf, iph2->ph1);
726 if (res == NULL)
727 goto end;
728
729 /* compute key length needed */
730 encklen = authklen = 0;
731 switch (pr->proto_id) {
732 case IPSECDOI_PROTO_IPSEC_ESP:
733 for (tr = pr->head; tr; tr = tr->next) {
734 l = alg_ipsec_encdef_keylen(tr->trns_id,
735 tr->encklen);
736 if (l > encklen)
737 encklen = l;
738
739 l = alg_ipsec_hmacdef_hashlen(tr->authtype);
740 if (l > authklen)
741 authklen = l;
742 }
743 break;
744 case IPSECDOI_PROTO_IPSEC_AH:
745 for (tr = pr->head; tr; tr = tr->next) {
746 l = alg_ipsec_hmacdef_hashlen(tr->trns_id);
747 if (l > authklen)
748 authklen = l;
749 }
750 break;
751 default:
752 break;
753 }
754 plog(LLV_DEBUG, LOCATION, NULL, "encklen=%d authklen=%d\n",
755 encklen, authklen);
756
757 dupkeymat = (encklen + authklen) / 8 / res->l;
758 dupkeymat += 2; /* safety mergin */
759 if (dupkeymat < 3)
760 dupkeymat = 3;
761 plog(LLV_DEBUG, LOCATION, NULL,
762 "generating %zu bits of key (dupkeymat=%d)\n",
763 dupkeymat * 8 * res->l, dupkeymat);
764 if (0 < --dupkeymat) {
765 vchar_t *prev = res; /* K(n-1) */
766 vchar_t *seed = NULL; /* seed for Kn */
767 size_t l;
768
769 /*
770 * generating long key (isakmp-oakley-08 5.5)
771 * KEYMAT = K1 | K2 | K3 | ...
772 * where
773 * src = [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b
774 * K1 = prf(SKEYID_d, src)
775 * K2 = prf(SKEYID_d, K1 | src)
776 * K3 = prf(SKEYID_d, K2 | src)
777 * Kn = prf(SKEYID_d, K(n-1) | src)
778 */
779 plog(LLV_DEBUG, LOCATION, NULL,
780 "generating K1...K%d for KEYMAT.\n",
781 dupkeymat + 1);
782
783 seed = vmalloc(prev->l + buf->l);
784 if (seed == NULL) {
785 plog(LLV_ERROR, LOCATION, NULL,
786 "failed to get keymat buffer.\n");
787 if (prev && prev != res)
788 vfree(prev);
789 goto end;
790 }
791
792 while (dupkeymat--) {
793 vchar_t *this = NULL; /* Kn */
794 int update_prev;
795
796 memcpy(seed->v, prev->v, prev->l);
797 memcpy(seed->v + prev->l, buf->v, buf->l);
798 this = oakley_prf(iph2->ph1->skeyid_d, seed,
799 iph2->ph1);
800 if (!this) {
801 plog(LLV_ERROR, LOCATION, NULL,
802 "oakley_prf memory overflow\n");
803 if (prev && prev != res)
804 vfree(prev);
805 vfree(this);
806 vfree(seed);
807 goto end;
808 }
809
810 update_prev = (prev && prev == res) ? 1 : 0;
811
812 l = res->l;
813 res = vrealloc(res, l + this->l);
814
815 if (update_prev)
816 prev = res;
817
818 if (res == NULL) {
819 plog(LLV_ERROR, LOCATION, NULL,
820 "failed to get keymat buffer.\n");
821 if (prev && prev != res)
822 vfree(prev);
823 vfree(this);
824 vfree(seed);
825 goto end;
826 }
827 memcpy(res->v + l, this->v, this->l);
828
829 if (prev && prev != res)
830 vfree(prev);
831 prev = this;
832 this = NULL;
833 }
834
835 if (prev && prev != res)
836 vfree(prev);
837 vfree(seed);
838 }
839
840 plogdump(LLV_DEBUG, res->v, res->l);
841
842 if (sa_dir == INBOUND_SA)
843 pr->keymat = res;
844 else
845 pr->keymat_p = res;
846 res = NULL;
847 }
848
849 error = 0;
850
851 end:
852 if (error) {
853 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
854 if (pr->keymat) {
855 vfree(pr->keymat);
856 pr->keymat = NULL;
857 }
858 if (pr->keymat_p) {
859 vfree(pr->keymat_p);
860 pr->keymat_p = NULL;
861 }
862 }
863 }
864
865 if (buf != NULL)
866 vfree(buf);
867 if (res)
868 vfree(res);
869
870 return error;
871 }
872
873 #if notyet
874 /*
875 * NOTE: Must terminate by NULL.
876 */
877 vchar_t *
878 oakley_compute_hashx(struct ph1handle *iph1, ...)
879 {
880 vchar_t *buf, *res;
881 vchar_t *s;
882 caddr_t p;
883 int len;
884
885 va_list ap;
886
887 /* get buffer length */
888 va_start(ap, iph1);
889 len = 0;
890 while ((s = va_arg(ap, vchar_t *)) != NULL) {
891 len += s->l
892 }
893 va_end(ap);
894
895 buf = vmalloc(len);
896 if (buf == NULL) {
897 plog(LLV_ERROR, LOCATION, NULL,
898 "failed to get hash buffer\n");
899 return NULL;
900 }
901
902 /* set buffer */
903 va_start(ap, iph1);
904 p = buf->v;
905 while ((s = va_arg(ap, char *)) != NULL) {
906 memcpy(p, s->v, s->l);
907 p += s->l;
908 }
909 va_end(ap);
910
911 plog(LLV_DEBUG, LOCATION, NULL, "HASH with: \n");
912 plogdump(LLV_DEBUG, buf->v, buf->l);
913
914 /* compute HASH */
915 res = oakley_prf(iph1->skeyid_a, buf, iph1);
916 vfree(buf);
917 if (res == NULL)
918 return NULL;
919
920 plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
921 plogdump(LLV_DEBUG, res->v, res->l);
922
923 return res;
924 }
925 #endif
926
927 /*
928 * compute HASH(3) prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
929 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
930 */
931 vchar_t *
932 oakley_compute_hash3(iph1, msgid, body)
933 struct ph1handle *iph1;
934 u_int32_t msgid;
935 vchar_t *body;
936 {
937 vchar_t *buf = 0, *res = 0;
938 int len;
939 int error = -1;
940
941 /* create buffer */
942 len = 1 + sizeof(u_int32_t) + body->l;
943 buf = vmalloc(len);
944 if (buf == NULL) {
945 plog(LLV_DEBUG, LOCATION, NULL,
946 "failed to get hash buffer\n");
947 goto end;
948 }
949
950 buf->v[0] = 0;
951
952 memcpy(buf->v + 1, (char *)&msgid, sizeof(msgid));
953
954 memcpy(buf->v + 1 + sizeof(u_int32_t), body->v, body->l);
955
956 plog(LLV_DEBUG, LOCATION, NULL, "HASH with: \n");
957 plogdump(LLV_DEBUG, buf->v, buf->l);
958
959 /* compute HASH */
960 res = oakley_prf(iph1->skeyid_a, buf, iph1);
961 if (res == NULL)
962 goto end;
963
964 error = 0;
965
966 plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
967 plogdump(LLV_DEBUG, res->v, res->l);
968
969 end:
970 if (buf != NULL)
971 vfree(buf);
972 return res;
973 }
974
975 /*
976 * compute HASH type of prf(SKEYID_a, M-ID | buffer)
977 * e.g.
978 * for quick mode HASH(1):
979 * prf(SKEYID_a, M-ID | SA | Ni [ | KE ] [ | IDci | IDcr ])
980 * for quick mode HASH(2):
981 * prf(SKEYID_a, M-ID | Ni_b | SA | Nr [ | KE ] [ | IDci | IDcr ])
982 * for Informational exchange:
983 * prf(SKEYID_a, M-ID | N/D)
984 */
985 vchar_t *
986 oakley_compute_hash1(iph1, msgid, body)
987 struct ph1handle *iph1;
988 u_int32_t msgid;
989 vchar_t *body;
990 {
991 vchar_t *buf = NULL, *res = NULL;
992 char *p;
993 int len;
994 int error = -1;
995
996 /* create buffer */
997 len = sizeof(u_int32_t) + body->l;
998 buf = vmalloc(len);
999 if (buf == NULL) {
1000 plog(LLV_DEBUG, LOCATION, NULL,
1001 "failed to get hash buffer\n");
1002 goto end;
1003 }
1004
1005 p = buf->v;
1006
1007 memcpy(buf->v, (char *)&msgid, sizeof(msgid));
1008 p += sizeof(u_int32_t);
1009
1010 memcpy(p, body->v, body->l);
1011
1012 plog(LLV_DEBUG, LOCATION, NULL, "HASH with:\n");
1013 plogdump(LLV_DEBUG, buf->v, buf->l);
1014
1015 /* compute HASH */
1016 res = oakley_prf(iph1->skeyid_a, buf, iph1);
1017 if (res == NULL)
1018 goto end;
1019
1020 error = 0;
1021
1022 plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
1023 plogdump(LLV_DEBUG, res->v, res->l);
1024
1025 end:
1026 if (buf != NULL)
1027 vfree(buf);
1028 return res;
1029 }
1030
1031 /*
1032 * compute phase1 HASH
1033 * main/aggressive
1034 * I-digest = prf(SKEYID, g^i | g^r | CKY-I | CKY-R | SAi_b | ID_i1_b)
1035 * R-digest = prf(SKEYID, g^r | g^i | CKY-R | CKY-I | SAi_b | ID_r1_b)
1036 * for gssapi, also include all GSS tokens, and call gss_wrap on the result
1037 */
1038 vchar_t *
1039 oakley_ph1hash_common(iph1, sw)
1040 struct ph1handle *iph1;
1041 int sw;
1042 {
1043 vchar_t *buf = NULL, *res = NULL, *bp;
1044 char *p, *bp2;
1045 int len, bl;
1046 int error = -1;
1047 #ifdef HAVE_GSSAPI
1048 vchar_t *gsstokens = NULL;
1049 #endif
1050
1051 /* create buffer */
1052 len = iph1->dhpub->l
1053 + iph1->dhpub_p->l
1054 + sizeof(cookie_t) * 2
1055 + iph1->sa->l
1056 + (sw == GENERATE ? iph1->id->l : iph1->id_p->l);
1057
1058 #ifdef HAVE_GSSAPI
1059 if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
1060 if (iph1->gi_i != NULL && iph1->gi_r != NULL) {
1061 bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r);
1062 len += bp->l;
1063 }
1064 if (sw == GENERATE)
1065 gssapi_get_itokens(iph1, &gsstokens);
1066 else
1067 gssapi_get_rtokens(iph1, &gsstokens);
1068 if (gsstokens == NULL)
1069 return NULL;
1070 len += gsstokens->l;
1071 }
1072 #endif
1073
1074 buf = vmalloc(len);
1075 if (buf == NULL) {
1076 plog(LLV_ERROR, LOCATION, NULL,
1077 "failed to get hash buffer\n");
1078 goto end;
1079 }
1080
1081 p = buf->v;
1082
1083 bp = (sw == GENERATE ? iph1->dhpub : iph1->dhpub_p);
1084 memcpy(p, bp->v, bp->l);
1085 p += bp->l;
1086
1087 bp = (sw == GENERATE ? iph1->dhpub_p : iph1->dhpub);
1088 memcpy(p, bp->v, bp->l);
1089 p += bp->l;
1090
1091 if (iph1->side == INITIATOR)
1092 bp2 = (sw == GENERATE ?
1093 (char *)&iph1->index.i_ck : (char *)&iph1->index.r_ck);
1094 else
1095 bp2 = (sw == GENERATE ?
1096 (char *)&iph1->index.r_ck : (char *)&iph1->index.i_ck);
1097 bl = sizeof(cookie_t);
1098 memcpy(p, bp2, bl);
1099 p += bl;
1100
1101 if (iph1->side == INITIATOR)
1102 bp2 = (sw == GENERATE ?
1103 (char *)&iph1->index.r_ck : (char *)&iph1->index.i_ck);
1104 else
1105 bp2 = (sw == GENERATE ?
1106 (char *)&iph1->index.i_ck : (char *)&iph1->index.r_ck);
1107 bl = sizeof(cookie_t);
1108 memcpy(p, bp2, bl);
1109 p += bl;
1110
1111 bp = iph1->sa;
1112 memcpy(p, bp->v, bp->l);
1113 p += bp->l;
1114
1115 bp = (sw == GENERATE ? iph1->id : iph1->id_p);
1116 memcpy(p, bp->v, bp->l);
1117 p += bp->l;
1118
1119 #ifdef HAVE_GSSAPI
1120 if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
1121 if (iph1->gi_i != NULL && iph1->gi_r != NULL) {
1122 bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r);
1123 memcpy(p, bp->v, bp->l);
1124 p += bp->l;
1125 }
1126 memcpy(p, gsstokens->v, gsstokens->l);
1127 p += gsstokens->l;
1128 }
1129 #endif
1130
1131 plog(LLV_DEBUG, LOCATION, NULL, "HASH with:\n");
1132 plogdump(LLV_DEBUG, buf->v, buf->l);
1133
1134 /* compute HASH */
1135 res = oakley_prf(iph1->skeyid, buf, iph1);
1136 if (res == NULL)
1137 goto end;
1138
1139 error = 0;
1140
1141 plog(LLV_DEBUG, LOCATION, NULL, "HASH (%s) computed:\n",
1142 iph1->side == INITIATOR ? "init" : "resp");
1143 plogdump(LLV_DEBUG, res->v, res->l);
1144
1145 end:
1146 if (buf != NULL)
1147 vfree(buf);
1148 #ifdef HAVE_GSSAPI
1149 if (gsstokens != NULL)
1150 vfree(gsstokens);
1151 #endif
1152 return res;
1153 }
1154
1155 /*
1156 * compute HASH_I on base mode.
1157 * base:psk,rsa
1158 * HASH_I = prf(SKEYID, g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
1159 * base:sig
1160 * HASH_I = prf(hash(Ni_b | Nr_b), g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
1161 */
1162 vchar_t *
1163 oakley_ph1hash_base_i(iph1, sw)
1164 struct ph1handle *iph1;
1165 int sw;
1166 {
1167 vchar_t *buf = NULL, *res = NULL, *bp;
1168 vchar_t *hashkey = NULL;
1169 vchar_t *hash = NULL; /* for signature mode */
1170 char *p;
1171 int len;
1172 int error = -1;
1173
1174 /* sanity check */
1175 if (iph1->etype != ISAKMP_ETYPE_BASE) {
1176 plog(LLV_ERROR, LOCATION, NULL,
1177 "invalid etype for this hash function\n");
1178 return NULL;
1179 }
1180
1181 switch (AUTHMETHOD(iph1)) {
1182 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1183 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1184 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1185 #ifdef ENABLE_HYBRID
1186 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
1187 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1188 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
1189 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1190 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
1191 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1192 #endif
1193 if (iph1->skeyid == NULL) {
1194 plog(LLV_ERROR, LOCATION, NULL, "no SKEYID found.\n");
1195 return NULL;
1196 }
1197 hashkey = iph1->skeyid;
1198 break;
1199
1200 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1201 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1202 #ifdef HAVE_GSSAPI
1203 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1204 #endif
1205 #ifdef ENABLE_HYBRID
1206 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1207 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1208 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
1209 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1210 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
1211 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1212 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
1213 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1214 #endif
1215 /* make hash for seed */
1216 len = iph1->nonce->l + iph1->nonce_p->l;
1217 buf = vmalloc(len);
1218 if (buf == NULL) {
1219 plog(LLV_ERROR, LOCATION, NULL,
1220 "failed to get hash buffer\n");
1221 goto end;
1222 }
1223 p = buf->v;
1224
1225 bp = (sw == GENERATE ? iph1->nonce_p : iph1->nonce);
1226 memcpy(p, bp->v, bp->l);
1227 p += bp->l;
1228
1229 bp = (sw == GENERATE ? iph1->nonce : iph1->nonce_p);
1230 memcpy(p, bp->v, bp->l);
1231 p += bp->l;
1232
1233 hash = oakley_hash(buf, iph1);
1234 if (hash == NULL)
1235 goto end;
1236 vfree(buf);
1237 buf = NULL;
1238
1239 hashkey = hash;
1240 break;
1241
1242 default:
1243 plog(LLV_ERROR, LOCATION, NULL,
1244 "not supported authentication method %d\n",
1245 iph1->approval->authmethod);
1246 return NULL;
1247
1248 }
1249
1250 len = (sw == GENERATE ? iph1->dhpub->l : iph1->dhpub_p->l)
1251 + sizeof(cookie_t) * 2
1252 + iph1->sa->l
1253 + (sw == GENERATE ? iph1->id->l : iph1->id_p->l);
1254 buf = vmalloc(len);
1255 if (buf == NULL) {
1256 plog(LLV_ERROR, LOCATION, NULL,
1257 "failed to get hash buffer\n");
1258 goto end;
1259 }
1260 p = buf->v;
1261
1262 bp = (sw == GENERATE ? iph1->dhpub : iph1->dhpub_p);
1263 memcpy(p, bp->v, bp->l);
1264 p += bp->l;
1265
1266 memcpy(p, &iph1->index.i_ck, sizeof(cookie_t));
1267 p += sizeof(cookie_t);
1268 memcpy(p, &iph1->index.r_ck, sizeof(cookie_t));
1269 p += sizeof(cookie_t);
1270
1271 memcpy(p, iph1->sa->v, iph1->sa->l);
1272 p += iph1->sa->l;
1273
1274 bp = (sw == GENERATE ? iph1->id : iph1->id_p);
1275 memcpy(p, bp->v, bp->l);
1276 p += bp->l;
1277
1278 plog(LLV_DEBUG, LOCATION, NULL, "HASH_I with:\n");
1279 plogdump(LLV_DEBUG, buf->v, buf->l);
1280
1281 /* compute HASH */
1282 res = oakley_prf(hashkey, buf, iph1);
1283 if (res == NULL)
1284 goto end;
1285
1286 error = 0;
1287
1288 plog(LLV_DEBUG, LOCATION, NULL, "HASH_I computed:\n");
1289 plogdump(LLV_DEBUG, res->v, res->l);
1290
1291 end:
1292 if (hash != NULL)
1293 vfree(hash);
1294 if (buf != NULL)
1295 vfree(buf);
1296 return res;
1297 }
1298
1299 /*
1300 * compute HASH_R on base mode for signature method.
1301 * base:
1302 * HASH_R = prf(hash(Ni_b | Nr_b), g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b)
1303 */
1304 vchar_t *
1305 oakley_ph1hash_base_r(iph1, sw)
1306 struct ph1handle *iph1;
1307 int sw;
1308 {
1309 vchar_t *buf = NULL, *res = NULL, *bp;
1310 vchar_t *hash = NULL;
1311 char *p;
1312 int len;
1313 int error = -1;
1314
1315 /* sanity check */
1316 if (iph1->etype != ISAKMP_ETYPE_BASE) {
1317 plog(LLV_ERROR, LOCATION, NULL,
1318 "invalid etype for this hash function\n");
1319 return NULL;
1320 }
1321
1322 switch(AUTHMETHOD(iph1)) {
1323 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1324 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1325 #ifdef ENABLE_HYBRID
1326 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1327 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1328 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
1329 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1330 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
1331 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1332 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
1333 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1334 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
1335 #endif
1336 break;
1337 default:
1338 plog(LLV_ERROR, LOCATION, NULL,
1339 "not supported authentication method %d\n",
1340 iph1->approval->authmethod);
1341 return NULL;
1342 break;
1343 }
1344
1345 /* make hash for seed */
1346 len = iph1->nonce->l + iph1->nonce_p->l;
1347 buf = vmalloc(len);
1348 if (buf == NULL) {
1349 plog(LLV_ERROR, LOCATION, NULL,
1350 "failed to get hash buffer\n");
1351 goto end;
1352 }
1353 p = buf->v;
1354
1355 bp = (sw == GENERATE ? iph1->nonce_p : iph1->nonce);
1356 memcpy(p, bp->v, bp->l);
1357 p += bp->l;
1358
1359 bp = (sw == GENERATE ? iph1->nonce : iph1->nonce_p);
1360 memcpy(p, bp->v, bp->l);
1361 p += bp->l;
1362
1363 hash = oakley_hash(buf, iph1);
1364 if (hash == NULL)
1365 goto end;
1366 vfree(buf);
1367 buf = NULL;
1368
1369 /* make really hash */
1370 len = (sw == GENERATE ? iph1->dhpub_p->l : iph1->dhpub->l)
1371 + (sw == GENERATE ? iph1->dhpub->l : iph1->dhpub_p->l)
1372 + sizeof(cookie_t) * 2
1373 + iph1->sa->l
1374 + (sw == GENERATE ? iph1->id_p->l : iph1->id->l);
1375 buf = vmalloc(len);
1376 if (buf == NULL) {
1377 plog(LLV_ERROR, LOCATION, NULL,
1378 "failed to get hash buffer\n");
1379 goto end;
1380 }
1381 p = buf->v;
1382
1383
1384 bp = (sw == GENERATE ? iph1->dhpub_p : iph1->dhpub);
1385 memcpy(p, bp->v, bp->l);
1386 p += bp->l;
1387
1388 bp = (sw == GENERATE ? iph1->dhpub : iph1->dhpub_p);
1389 memcpy(p, bp->v, bp->l);
1390 p += bp->l;
1391
1392 memcpy(p, &iph1->index.i_ck, sizeof(cookie_t));
1393 p += sizeof(cookie_t);
1394 memcpy(p, &iph1->index.r_ck, sizeof(cookie_t));
1395 p += sizeof(cookie_t);
1396
1397 memcpy(p, iph1->sa->v, iph1->sa->l);
1398 p += iph1->sa->l;
1399
1400 bp = (sw == GENERATE ? iph1->id_p : iph1->id);
1401 memcpy(p, bp->v, bp->l);
1402 p += bp->l;
1403
1404 plog(LLV_DEBUG, LOCATION, NULL, "HASH_R with:\n");
1405 plogdump(LLV_DEBUG, buf->v, buf->l);
1406
1407 /* compute HASH */
1408 res = oakley_prf(hash, buf, iph1);
1409 if (res == NULL)
1410 goto end;
1411
1412 error = 0;
1413
1414 plog(LLV_DEBUG, LOCATION, NULL, "HASH_R computed:\n");
1415 plogdump(LLV_DEBUG, res->v, res->l);
1416
1417 end:
1418 if (buf != NULL)
1419 vfree(buf);
1420 if (hash)
1421 vfree(hash);
1422 return res;
1423 }
1424
1425 #if HAVE_OPENDIR
1426 static int
1427 oakley_verify_userid(iph1)
1428 struct ph1handle *iph1;
1429 {
1430 cert_t *p;
1431 vchar_t *user_id;
1432 int user_id_found = 0;
1433
1434 for (p = iph1->cert_p; p; p = p->chain) {
1435 user_id = eay_get_x509_common_name(&p->cert);
1436 if (user_id) {
1437 user_id_found = 1;
1438 // the following functions will check if user_id == 0
1439 if (open_dir_authorize_id(user_id, iph1->rmconf->open_dir_auth_group)) {
1440 vfree(user_id);
1441 return 0;
1442 }
1443 vfree(user_id);
1444 }
1445 }
1446 if (user_id_found) {
1447 plog(LLV_ERROR, LOCATION, NULL,
1448 "the peer is not authorized for access.\n");
1449 } else {
1450 plog(LLV_ERROR, LOCATION, NULL,
1451 "the peer is not authorized for access - user ID not found.\n");
1452 }
1453 return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
1454 }
1455 #endif /* HAVE_OPENDIR */
1456
1457 #ifdef HAVE_OPENSSL
1458 static int
1459 oakley_verify_x509sign(certchain, my_hash, my_sig)
1460 cert_t *certchain;
1461 vchar_t *my_hash;
1462 vchar_t *my_sig;
1463 {
1464 cert_t *p;
1465 int result = -1;
1466
1467 for (p = certchain; p; p = p->chain) {
1468 if ((result = eay_check_x509sign(my_hash,
1469 my_sig,
1470 &p->cert)) == 0) {
1471 break;
1472 }
1473 }
1474 return result;
1475 }
1476 #endif
1477 #ifdef HAVE_OPENSSL
1478 static int
1479 oakley_check_x509cert(certchain, capath, cafile, local)
1480 cert_t *certchain;
1481 char *capath;
1482 char *cafile;
1483 int local;
1484 {
1485 cert_t *p;
1486 int result = 0;
1487
1488 for (p = certchain; p; p = p->chain) {
1489 if ((result = eay_check_x509cert(&p->cert,
1490 capath,
1491 cafile,
1492 local))) {
1493 break;
1494 }
1495 }
1496 return result;
1497 }
1498 #endif /* HAVE_OPENSSL */
1499
1500 /*
1501 * compute each authentication method in phase 1.
1502 * OUT:
1503 * 0: OK
1504 * -1: error
1505 * other: error to be reply with notification.
1506 * the value is notification type.
1507 */
1508 int
1509 oakley_validate_auth(iph1)
1510 struct ph1handle *iph1;
1511 {
1512 vchar_t *my_hash = NULL;
1513 int result;
1514 #ifdef HAVE_GSSAPI
1515 vchar_t *gsshash = NULL;
1516 #endif
1517 #ifdef ENABLE_STATS
1518 struct timeval start, end;
1519 #endif
1520 #if TARGET_OS_EMBEDDED
1521 SecKeyRef publicKeyRef;
1522 #endif
1523
1524 #ifdef ENABLE_STATS
1525 gettimeofday(&start, NULL);
1526 #endif
1527
1528 switch (AUTHMETHOD(iph1)) {
1529 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1530 #ifdef ENABLE_HYBRID
1531 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
1532 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1533 #endif
1534 /* validate HASH */
1535 {
1536 char *r_hash;
1537
1538 if (iph1->id_p == NULL || iph1->pl_hash == NULL) {
1539 plog(LLV_ERROR, LOCATION, iph1->remote,
1540 "few isakmp message received.\n");
1541 return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1542 }
1543 #ifdef ENABLE_HYBRID
1544 if (AUTHMETHOD(iph1) == FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I &&
1545 ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0))
1546 {
1547 plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, "
1548 "hybrid auth is enabled, "
1549 "but peer is no Xauth compliant\n");
1550 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED;
1551 break;
1552 }
1553 #endif
1554 r_hash = (caddr_t)(iph1->pl_hash + 1);
1555
1556 plog(LLV_DEBUG, LOCATION, NULL, "HASH received:\n");
1557 plogdump(LLV_DEBUG, r_hash,
1558 ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash));
1559
1560 switch (iph1->etype) {
1561 case ISAKMP_ETYPE_IDENT:
1562 case ISAKMP_ETYPE_AGG:
1563 my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1564 break;
1565 case ISAKMP_ETYPE_BASE:
1566 if (iph1->side == INITIATOR)
1567 my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1568 else
1569 my_hash = oakley_ph1hash_base_i(iph1, VALIDATE);
1570 break;
1571 default:
1572 plog(LLV_ERROR, LOCATION, NULL,
1573 "invalid etype %d\n", iph1->etype);
1574 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1575 }
1576 if (my_hash == NULL)
1577 return ISAKMP_INTERNAL_ERROR;
1578
1579 result = memcmp(my_hash->v, r_hash, my_hash->l);
1580 vfree(my_hash);
1581
1582 if (result) {
1583 plog(LLV_ERROR, LOCATION, NULL, "HASH mismatched\n");
1584 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1585 }
1586
1587 plog(LLV_DEBUG, LOCATION, NULL, "HASH for PSK validated.\n");
1588 }
1589 break;
1590 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1591 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1592 #ifdef ENABLE_HYBRID
1593 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1594 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
1595 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
1596 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1597 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
1598 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1599 #endif
1600 {
1601 int error = 0;
1602 int certtype = 0;
1603
1604 /* validation */
1605 if (iph1->id_p == NULL) {
1606 plog(LLV_ERROR, LOCATION, iph1->remote,
1607 "no ID payload was passed.\n");
1608 return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1609 }
1610 if (iph1->sig_p == NULL) {
1611 plog(LLV_ERROR, LOCATION, iph1->remote,
1612 "no SIG payload was passed.\n");
1613 return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1614 }
1615
1616 plog(LLV_DEBUG, LOCATION, NULL, "SIGN passed:\n");
1617 plogdump(LLV_DEBUG, iph1->sig_p->v, iph1->sig_p->l);
1618
1619 /* get peer's cert */
1620 switch (iph1->rmconf->getcert_method) {
1621 case ISAKMP_GETCERT_PAYLOAD:
1622 if (iph1->cert_p == NULL) {
1623 plog(LLV_ERROR, LOCATION, NULL,
1624 "no peer's CERT payload found.\n");
1625 return ISAKMP_INTERNAL_ERROR;
1626 }
1627 break;
1628 #ifdef HAVE_OPENSSL
1629 case ISAKMP_GETCERT_LOCALFILE:
1630 switch (iph1->rmconf->certtype) {
1631 case ISAKMP_CERT_X509SIGN:
1632 if (iph1->rmconf->peerscertfile == NULL) {
1633 plog(LLV_ERROR, LOCATION, NULL,
1634 "no peer's CERT file found.\n");
1635 return ISAKMP_INTERNAL_ERROR;
1636 }
1637
1638 /* don't use cached cert */
1639 if (iph1->cert_p != NULL) {
1640 oakley_delcert(iph1->cert_p);
1641 iph1->cert_p = NULL;
1642 }
1643
1644 error = get_cert_fromlocal(iph1, 0);
1645 break;
1646
1647 case ISAKMP_CERT_PLAINRSA:
1648 error = get_plainrsa_fromlocal(iph1, 0);
1649 break;
1650 }
1651 if (error)
1652 return ISAKMP_INTERNAL_ERROR;
1653 break;
1654 #endif
1655 case ISAKMP_GETCERT_DNS:
1656 if (iph1->rmconf->peerscertfile != NULL) {
1657 plog(LLV_ERROR, LOCATION, NULL,
1658 "why peer's CERT file is defined "
1659 "though getcert method is dns ?\n");
1660 return ISAKMP_INTERNAL_ERROR;
1661 }
1662
1663 /* don't use cached cert */
1664 if (iph1->cert_p != NULL) {
1665 oakley_delcert(iph1->cert_p);
1666 iph1->cert_p = NULL;
1667 }
1668
1669 iph1->cert_p = dnssec_getcert(iph1->id_p);
1670 if (iph1->cert_p == NULL) {
1671 plog(LLV_ERROR, LOCATION, NULL,
1672 "no CERT RR found.\n");
1673 return ISAKMP_INTERNAL_ERROR;
1674 }
1675 break;
1676 default:
1677 plog(LLV_ERROR, LOCATION, NULL,
1678 "invalid getcert_mothod: %d\n",
1679 iph1->rmconf->getcert_method);
1680 return ISAKMP_INTERNAL_ERROR;
1681 }
1682
1683 /* compare ID payload and certificate name */
1684 if (iph1->rmconf->verify_cert &&
1685 (error = oakley_check_certid(iph1, CERT_CHECKID_FROM_PEER)) != 0)
1686 return error;
1687
1688 /* check configured peers identifier against cert IDs */
1689 /* allows checking of specified ID against multiple ids in the cert */
1690 /* such as multiple domain names */
1691 #if !TARGET_OS_EMBEDDED
1692 if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_PEERS_IDENTIFIER &&
1693 (error = oakley_check_certid(iph1, CERT_CHECKID_FROM_RMCONFIG)) != 0)
1694 return error;
1695 #endif
1696
1697 #if HAVE_OPENDIR
1698 /* check cert common name against Open Directory authentication group */
1699 if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_OPEN_DIR) {
1700 if (oakley_verify_userid(iph1)) {
1701 return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
1702 }
1703 }
1704 #endif /* HAVE_OPENDIR */
1705
1706 /* verify certificate */
1707 if (iph1->rmconf->verify_cert
1708 && iph1->rmconf->getcert_method == ISAKMP_GETCERT_PAYLOAD) {
1709 certtype = iph1->rmconf->certtype;
1710 #ifdef ENABLE_HYBRID
1711 switch (AUTHMETHOD(iph1)) {
1712 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1713 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
1714 certtype = iph1->cert_p->type;
1715 break;
1716 default:
1717 break;
1718 }
1719 #endif
1720 switch (certtype) {
1721 case ISAKMP_CERT_X509SIGN:
1722
1723 #if TARGET_OS_EMBEDDED
1724 {
1725 /* use ID from remote configuration */
1726 /* check each ID in list */
1727 struct idspec *id_spec;
1728 CFStringRef hostname = NULL;
1729 char *peers_id;
1730 struct genlist_entry *gpb = NULL;
1731
1732 if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_PEERS_IDENTIFIER) {
1733 id_spec = genlist_next(iph1->rmconf->idvl_p, &gpb); /* expect only one id */
1734 if (id_spec->idtype == IDTYPE_ADDRESS) {
1735 switch (((struct sockaddr *)(id_spec->id->v))->sa_family) {
1736 case AF_INET:
1737 peers_id = inet_ntoa(((struct sockaddr_in *)(id_spec->id->v))->sin_addr);
1738 hostname = CFStringCreateWithCString(NULL, peers_id, kCFStringEncodingUTF8);
1739 break;
1740 #ifdef INET6
1741 case AF_INET6:
1742 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; /* not currently supported for embedded */
1743 break;
1744 #endif
1745 default:
1746 plog(LLV_ERROR, LOCATION, NULL,
1747 "unknown address type for peers identifier.\n");
1748 return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
1749 break;
1750 }
1751 } else
1752 hostname = CFStringCreateWithBytes(NULL, (u_int8_t *)id_spec->id->v, id_spec->id->l, kCFStringEncodingUTF8, FALSE);
1753 }
1754 error = crypto_cssm_check_x509cert(oakley_get_peer_cert_from_certchain(iph1), iph1->cert_p, hostname, &publicKeyRef);
1755 if (hostname)
1756 CFRelease(hostname);
1757 }
1758
1759 #else /* TARGET_OS_EMBEDDED */
1760 if (iph1->rmconf->cert_verification == VERIFICATION_MODULE_SEC_FRAMEWORK)
1761 error = crypto_cssm_check_x509cert(oakley_get_peer_cert_from_certchain(iph1),
1762 iph1->cert_p,
1763 NULL);
1764 else
1765 {
1766 char path[MAXPATHLEN];
1767 char *ca;
1768
1769 if (iph1->rmconf->cacertfile != NULL) {
1770 getpathname(path, sizeof(path),
1771 LC_PATHTYPE_CERT,
1772 iph1->rmconf->cacertfile);
1773 ca = path;
1774 } else {
1775 ca = NULL;
1776 }
1777
1778 error = oakley_check_x509cert(iph1->cert_p,
1779 lcconf->pathinfo[LC_PATHTYPE_CERT],
1780 ca, 0);
1781 }
1782 #endif /* TARGET_OS_EMBEDDED */
1783 break;
1784
1785 default:
1786 plog(LLV_ERROR, LOCATION, NULL,
1787 "no supported certtype %d\n", certtype);
1788 return ISAKMP_INTERNAL_ERROR;
1789 }
1790 if (error != 0) {
1791 plog(LLV_ERROR, LOCATION, NULL,
1792 "the peer's certificate is not verified.\n");
1793 return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY;
1794 }
1795 }
1796
1797 plog(LLV_DEBUG, LOCATION, NULL, "CERT validated\n");
1798
1799 /* compute hash */
1800 switch (iph1->etype) {
1801 case ISAKMP_ETYPE_IDENT:
1802 case ISAKMP_ETYPE_AGG:
1803 my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1804 break;
1805 case ISAKMP_ETYPE_BASE:
1806 if (iph1->side == INITIATOR)
1807 my_hash = oakley_ph1hash_base_r(iph1, VALIDATE);
1808 else
1809 my_hash = oakley_ph1hash_base_i(iph1, VALIDATE);
1810 break;
1811 default:
1812 plog(LLV_ERROR, LOCATION, NULL,
1813 "invalid etype %d\n", iph1->etype);
1814 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1815 }
1816 if (my_hash == NULL)
1817 return ISAKMP_INTERNAL_ERROR;
1818
1819
1820 certtype = iph1->rmconf->certtype;
1821 #ifdef ENABLE_HYBRID
1822 switch (AUTHMETHOD(iph1)) {
1823 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1824 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
1825 certtype = iph1->cert_p->type;
1826 break;
1827 default:
1828 break;
1829 }
1830 #endif
1831 /* check signature */
1832 switch (certtype) {
1833 case ISAKMP_CERT_X509SIGN:
1834 case ISAKMP_CERT_DNS:
1835 #if TARGET_OS_EMBEDDED
1836 error = crypto_cssm_verify_x509sign(publicKeyRef, my_hash, iph1->sig_p);
1837 if (error)
1838 plog(LLV_ERROR, LOCATION, NULL, "error verifying signature %s\n", GetSecurityErrorString(error));
1839
1840 CFRelease(publicKeyRef);
1841 #else
1842 error = oakley_verify_x509sign(iph1->cert_p, my_hash, iph1->sig_p);
1843 #endif
1844 break;
1845 #ifdef HAVE_OPENSSL
1846 case ISAKMP_CERT_PLAINRSA:
1847 iph1->rsa_p = rsa_try_check_rsasign(my_hash,
1848 iph1->sig_p, iph1->rsa_candidates);
1849 error = iph1->rsa_p ? 0 : -1;
1850
1851 break;
1852 #endif
1853 default:
1854 plog(LLV_ERROR, LOCATION, NULL,
1855 "no supported certtype %d\n",
1856 certtype);
1857 vfree(my_hash);
1858 return ISAKMP_INTERNAL_ERROR;
1859 }
1860
1861 vfree(my_hash);
1862 if (error != 0) {
1863 plog(LLV_ERROR, LOCATION, NULL,
1864 "Invalid SIG.\n");
1865 return ISAKMP_NTYPE_INVALID_SIGNATURE;
1866 }
1867 plog(LLV_DEBUG, LOCATION, NULL, "SIG authenticated\n");
1868 }
1869 break;
1870 #ifdef ENABLE_HYBRID
1871 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1872 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1873 {
1874 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
1875 plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, "
1876 "hybrid auth is enabled, "
1877 "but peer is no Xauth compliant\n");
1878 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED;
1879 break;
1880 }
1881 plog(LLV_INFO, LOCATION, NULL, "No SIG was passed, "
1882 "but hybrid auth is enabled\n");
1883
1884 return 0;
1885 break;
1886 }
1887 #endif
1888 #ifdef HAVE_GSSAPI
1889 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1890 /* check if we're not into XAUTH_PSKEY_I instead */
1891 #ifdef ENABLE_HYBRID
1892 if (iph1->rmconf->xauth)
1893 break;
1894 #endif
1895 switch (iph1->etype) {
1896 case ISAKMP_ETYPE_IDENT:
1897 case ISAKMP_ETYPE_AGG:
1898 my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1899 break;
1900 default:
1901 plog(LLV_ERROR, LOCATION, NULL,
1902 "invalid etype %d\n", iph1->etype);
1903 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1904 }
1905
1906 if (my_hash == NULL) {
1907 if (gssapi_more_tokens(iph1))
1908 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1909 else
1910 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1911 }
1912
1913 gsshash = gssapi_unwraphash(iph1);
1914 if (gsshash == NULL) {
1915 vfree(my_hash);
1916 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1917 }
1918
1919 result = memcmp(my_hash->v, gsshash->v, my_hash->l);
1920 vfree(my_hash);
1921 vfree(gsshash);
1922
1923 if (result) {
1924 plog(LLV_ERROR, LOCATION, NULL, "HASH mismatched\n");
1925 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1926 }
1927 plog(LLV_DEBUG, LOCATION, NULL, "hash compared OK\n");
1928 break;
1929 #endif
1930 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1931 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1932 #ifdef ENABLE_HYBRID
1933 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
1934 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1935 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
1936 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1937 #endif
1938 if (iph1->id_p == NULL || iph1->pl_hash == NULL) {
1939 plog(LLV_ERROR, LOCATION, iph1->remote,
1940 "few isakmp message received.\n");
1941 return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1942 }
1943 plog(LLV_ERROR, LOCATION, iph1->remote,
1944 "not supported authmethod type %s\n",
1945 s_oakley_attr_method(iph1->approval->authmethod));
1946 return ISAKMP_INTERNAL_ERROR;
1947 default:
1948 plog(LLV_ERROR, LOCATION, iph1->remote,
1949 "invalid authmethod %d why ?\n",
1950 iph1->approval->authmethod);
1951 return ISAKMP_INTERNAL_ERROR;
1952 }
1953 #ifdef ENABLE_STATS
1954 gettimeofday(&end, NULL);
1955 syslog(LOG_NOTICE, "%s(%s): %8.6f", __func__,
1956 s_oakley_attr_method(iph1->approval->authmethod),
1957 timedelta(&start, &end));
1958 #endif
1959
1960 return 0;
1961 }
1962
1963 int
1964 oakley_find_status_in_certchain (cert_t *certchain, cert_status_t certStatus)
1965 {
1966 cert_t *p;
1967
1968 for (p = certchain; p; p = p->chain) {
1969 if (p->status == certStatus) {
1970 return 1;
1971 }
1972 }
1973 return 0;
1974 }
1975
1976 static
1977 int
1978 oakley_vpncontrol_notify_ike_failed_if_mycert_invalid (struct ph1handle *iph1,
1979 int notify_initiator)
1980 {
1981 #if TARGET_OS_EMBEDDED
1982 int premature = oakley_find_status_in_certchain(iph1->cert, CERT_STATUS_PREMATURE);
1983 int expired = oakley_find_status_in_certchain(iph1->cert, CERT_STATUS_EXPIRED);
1984 if (premature || expired) {
1985 u_int32_t address;
1986 u_int32_t fail_reason;
1987
1988 if (iph1->remote->sa_family == AF_INET)
1989 address = ((struct sockaddr_in *)(iph1->remote))->sin_addr.s_addr;
1990 else
1991 address = 0;
1992 if (premature) {
1993 fail_reason = VPNCTL_NTYPE_LOCAL_CERT_PREMATURE;
1994 } else {
1995 fail_reason = VPNCTL_NTYPE_LOCAL_CERT_EXPIRED;
1996 }
1997 vpncontrol_notify_ike_failed(fail_reason, notify_initiator, address, 0, NULL);
1998 return -1;
1999 }
2000 #endif /* TARGET_OS_EMBEDDED */
2001 return 0;
2002 }
2003
2004 /* get my certificate
2005 * NOTE: include certificate type.
2006 */
2007 int
2008 oakley_getmycert(iph1)
2009 struct ph1handle *iph1;
2010 {
2011 int err;
2012 u_int32_t address;
2013
2014 switch (iph1->rmconf->certtype) {
2015 case ISAKMP_CERT_X509SIGN:
2016 if (iph1->cert)
2017 return 0;
2018 if ( !(err = get_cert_fromlocal(iph1, 1))){
2019 if (oakley_vpncontrol_notify_ike_failed_if_mycert_invalid(iph1, FROM_LOCAL)) {
2020 return -1;
2021 }
2022 }
2023 return err;
2024 #ifdef HAVE_OPENSSL
2025 case ISAKMP_CERT_PLAINRSA:
2026 if (iph1->rsa)
2027 return 0;
2028 return get_plainrsa_fromlocal(iph1, 1);
2029 #endif
2030 default:
2031 plog(LLV_ERROR, LOCATION, NULL,
2032 "Unknown certtype #%d\n",
2033 iph1->rmconf->certtype);
2034 return -1;
2035 }
2036
2037 }
2038
2039 /*
2040 * get a CERT from local file.
2041 * IN:
2042 * my != 0 my cert.
2043 * my == 0 peer's cert.
2044 */
2045 static int
2046 get_cert_fromlocal(iph1, my)
2047 struct ph1handle *iph1;
2048 int my;
2049 {
2050 char path[MAXPATHLEN];
2051 vchar_t *cert = NULL;
2052 cert_t **certpl;
2053 char *certfile;
2054 int error = -1;
2055 cert_status_t status = CERT_STATUS_OK;
2056
2057 if (my) {
2058 certfile = iph1->rmconf->mycertfile;
2059 certpl = &iph1->cert;
2060 } else {
2061 certfile = iph1->rmconf->peerscertfile;
2062 certpl = &iph1->cert_p;
2063 }
2064 if (!certfile && iph1->rmconf->identity_in_keychain == 0) {
2065 plog(LLV_ERROR, LOCATION, NULL, "no CERT defined.\n");
2066 return 0;
2067 }
2068
2069 switch (iph1->rmconf->certtype) {
2070 case ISAKMP_CERT_X509SIGN:
2071 if (iph1->rmconf->identity_in_keychain) {
2072 CFDataRef dataRef;
2073
2074 if (iph1->rmconf->keychainCertRef == NULL || base64toCFData(iph1->rmconf->keychainCertRef, &dataRef))
2075 goto end;
2076 cert = crypto_cssm_get_x509cert(dataRef, &status);
2077 plog(LLV_DEBUG, LOCATION, NULL, "done with chking cert status %d\n",status);
2078 CFRelease(dataRef);
2079 break;
2080 } // else fall thru
2081 #ifdef HAVE_OPENSSL
2082 case ISAKMP_CERT_DNS:
2083 /* make public file name */
2084 getpathname(path, sizeof(path), LC_PATHTYPE_CERT, certfile);
2085 cert = eay_get_x509cert(path);
2086 if (cert) {
2087 oakley_cert_prettyprint(cert);
2088 };
2089 break;
2090 #endif
2091 default:
2092 plog(LLV_ERROR, LOCATION, NULL,
2093 "not supported certtype %d\n",
2094 iph1->rmconf->certtype);
2095 goto end;
2096 }
2097
2098 if (!cert) {
2099 plog(LLV_ERROR, LOCATION, NULL,
2100 "failed to get %s CERT.\n",
2101 my ? "my" : "peers");
2102 goto end;
2103 }
2104
2105 *certpl = oakley_newcert();
2106 if (!*certpl) {
2107 plog(LLV_ERROR, LOCATION, NULL,
2108 "failed to get cert buffer.\n");
2109 goto end;
2110 }
2111 (*certpl)->pl = vmalloc(cert->l + 1);
2112 if ((*certpl)->pl == NULL) {
2113 plog(LLV_ERROR, LOCATION, NULL,
2114 "failed to get cert buffer\n");
2115 oakley_delcert(*certpl);
2116 *certpl = NULL;
2117 goto end;
2118 }
2119 memcpy((*certpl)->pl->v + 1, cert->v, cert->l);
2120 (*certpl)->pl->v[0] = iph1->rmconf->certtype;
2121 (*certpl)->type = iph1->rmconf->certtype;
2122 (*certpl)->status = status;
2123 (*certpl)->cert.v = (*certpl)->pl->v + 1;
2124 (*certpl)->cert.l = (*certpl)->pl->l - 1;
2125
2126 plog(LLV_DEBUG, LOCATION, NULL, "created CERT payload:\n");
2127 plogdump(LLV_DEBUG, (*certpl)->pl->v, (*certpl)->pl->l);
2128 oakley_cert_prettyprint(cert);
2129
2130 error = 0;
2131
2132 end:
2133 if (cert != NULL)
2134 vfree(cert);
2135
2136 return error;
2137 }
2138
2139 #ifdef HAVE_OPENSSL
2140 static int
2141 get_plainrsa_fromlocal(iph1, my)
2142 struct ph1handle *iph1;
2143 int my;
2144 {
2145 char path[MAXPATHLEN];
2146 vchar_t *cert = NULL;
2147 char *certfile;
2148 int error = -1;
2149
2150 iph1->rsa_candidates = rsa_lookup_keys(iph1, my);
2151 if (!iph1->rsa_candidates ||
2152 rsa_list_count(iph1->rsa_candidates) == 0) {
2153 plog(LLV_ERROR, LOCATION, NULL,
2154 "%s RSA key not found for %s\n",
2155 my ? "Private" : "Public",
2156 saddr2str_fromto("%s <-> %s",
2157 iph1->local, iph1->remote));
2158 goto end;
2159 }
2160
2161 if (my && rsa_list_count(iph1->rsa_candidates) > 1) {
2162 plog(LLV_WARNING, LOCATION, NULL,
2163 "More than one (=%lu) private "
2164 "PlainRSA key found for %s\n",
2165 rsa_list_count(iph1->rsa_candidates),
2166 saddr2str_fromto("%s <-> %s",
2167 iph1->local, iph1->remote));
2168 plog(LLV_WARNING, LOCATION, NULL,
2169 "This may have unpredictable results, "
2170 "i.e. wrong key could be used!\n");
2171 plog(LLV_WARNING, LOCATION, NULL,
2172 "Consider using only one single private "
2173 "key for all peers...\n");
2174 }
2175 if (my) {
2176 iph1->rsa = ((struct rsa_key *)
2177 genlist_next(iph1->rsa_candidates, NULL))->rsa;
2178
2179 genlist_free(iph1->rsa_candidates, NULL);
2180 iph1->rsa_candidates = NULL;
2181
2182 if (iph1->rsa == NULL)
2183 goto end;
2184 }
2185
2186 error = 0;
2187
2188 end:
2189 return error;
2190 }
2191 #endif
2192
2193 /* get signature */
2194 int
2195 oakley_getsign(iph1)
2196 struct ph1handle *iph1;
2197 {
2198 char path[MAXPATHLEN];
2199 vchar_t *privkey = NULL;
2200 int error = -1;
2201
2202 switch (iph1->rmconf->certtype) {
2203 case ISAKMP_CERT_X509SIGN:
2204 // cert in keychain - use cssm to sign
2205 if (iph1->rmconf->identity_in_keychain) {
2206 CFDataRef dataRef;
2207
2208 if (iph1->rmconf->keychainCertRef == NULL || base64toCFData(iph1->rmconf->keychainCertRef, &dataRef))
2209 goto end;
2210 iph1->sig = crypto_cssm_getsign(dataRef, iph1->hash);
2211 CFRelease(dataRef);
2212 break;
2213 } // else fall thru
2214 #ifdef HAVE_OPENSSL
2215 case ISAKMP_CERT_DNS:
2216 if (iph1->rmconf->myprivfile == NULL) {
2217 plog(LLV_ERROR, LOCATION, NULL, "no cert defined.\n");
2218 goto end;
2219 }
2220
2221 /* make private file name */
2222 getpathname(path, sizeof(path),
2223 LC_PATHTYPE_CERT,
2224 iph1->rmconf->myprivfile);
2225 privkey = privsep_eay_get_pkcs1privkey(path);
2226 if (privkey == NULL) {
2227 plog(LLV_ERROR, LOCATION, NULL,
2228 "failed to get private key.\n");
2229 goto end;
2230 }
2231 plog(LLV_DEBUG2, LOCATION, NULL, "private key:\n");
2232 plogdump(LLV_DEBUG2, privkey->v, privkey->l);
2233
2234 iph1->sig = eay_get_x509sign(iph1->hash, privkey);
2235 break;
2236 case ISAKMP_CERT_PLAINRSA:
2237 iph1->sig = eay_get_rsasign(iph1->hash, iph1->rsa);
2238 break;
2239 #endif
2240 default:
2241 plog(LLV_ERROR, LOCATION, NULL,
2242 "Unknown certtype #%d\n",
2243 iph1->rmconf->certtype);
2244 goto end;
2245 }
2246
2247 if (iph1->sig == NULL) {
2248 plog(LLV_ERROR, LOCATION, NULL, "failed to sign.\n");
2249 goto end;
2250 }
2251
2252 plog(LLV_DEBUG, LOCATION, NULL, "SIGN computed:\n");
2253 plogdump(LLV_DEBUG, iph1->sig->v, iph1->sig->l);
2254
2255 error = 0;
2256
2257 end:
2258 if (privkey != NULL)
2259 vfree(privkey);
2260
2261 return error;
2262 }
2263
2264 void
2265 oakley_verify_certid(iph1)
2266 struct ph1handle *iph1;
2267 {
2268 if (iph1->rmconf->verify_cert &&
2269 oakley_check_certid(iph1, CERT_CHECKID_FROM_PEER)){
2270 plog(LLV_DEBUG, LOCATION, NULL,
2271 "Discarding CERT: does not match ID:\n");
2272 oakley_delcert(iph1->cert_p);
2273 iph1->cert_p = NULL;
2274 }
2275 }
2276
2277 static int
2278 oakley_check_certid_in_certchain(certchain, idtype, idlen, id)
2279 cert_t *certchain;
2280 int idtype;
2281 int idlen;
2282 void *id;
2283 {
2284 cert_t *p;
2285
2286 for (p = certchain; p; p = p->chain) {
2287 if (oakley_check_certid_1(&p->cert, idtype, idlen, id, &p->status) == 0) {
2288 return 0;
2289 }
2290 }
2291 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2292 }
2293
2294 cert_t *
2295 oakley_get_peer_cert_from_certchain(iph1)
2296 struct ph1handle * iph1;
2297 {
2298 cert_t *p;
2299 struct ipsecdoi_id_b *id_b;
2300 int idlen;
2301 void *peers_id;
2302
2303 if (!iph1->id_p || !iph1->cert_p) {
2304 plog(LLV_ERROR, LOCATION, NULL, "no ID nor CERT found.\n");
2305 return NULL;
2306 }
2307 if (!iph1->cert_p->chain) {
2308 // no chain: simply return the only cert
2309 return iph1->cert_p;
2310 }
2311
2312 id_b = (struct ipsecdoi_id_b *)iph1->id_p->v;
2313 peers_id = id_b + 1;
2314 idlen = iph1->id_p->l - sizeof(*id_b);
2315 for (p = iph1->cert_p; p; p = p->chain) {
2316 if (oakley_check_certid_1(&p->cert, id_b->type, idlen, peers_id, &p->status) == 0) {
2317 return p;
2318 }
2319 }
2320 return NULL;
2321 }
2322
2323 /*
2324 * compare certificate name and ID value.
2325 */
2326 static int
2327 oakley_check_certid(iph1, which_id)
2328 struct ph1handle *iph1;
2329 int which_id;
2330 {
2331 struct ipsecdoi_id_b *id_b;
2332 int idlen;
2333 u_int8_t doi_type = 255;
2334 void *peers_id = NULL;
2335 struct genlist_entry *gpb = NULL;
2336
2337 if (which_id == CERT_CHECKID_FROM_PEER) {
2338 /* use ID from peer */
2339 if (iph1->id_p == NULL || iph1->cert_p == NULL) {
2340 plog(LLV_ERROR, LOCATION, NULL, "no ID nor CERT found.\n");
2341 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2342 }
2343 id_b = (struct ipsecdoi_id_b *)iph1->id_p->v;
2344 doi_type = id_b->type;
2345 peers_id = id_b + 1;
2346 idlen = iph1->id_p->l - sizeof(*id_b);
2347
2348 return oakley_check_certid_in_certchain(iph1->cert_p, doi_type, idlen, peers_id);
2349
2350 } else {
2351 /* use ID from remote configuration */
2352 /* check each ID in list */
2353 struct idspec *id_spec;
2354
2355 for (id_spec = genlist_next (iph1->rmconf->idvl_p, &gpb); id_spec; id_spec = genlist_next (0, &gpb)) {
2356
2357 if (id_spec->idtype == IDTYPE_ADDRESS) {
2358 switch (((struct sockaddr *)(id_spec->id->v))->sa_family) {
2359 case AF_INET:
2360 doi_type = IPSECDOI_ID_IPV4_ADDR;
2361 idlen = sizeof(struct in_addr);
2362 peers_id = &(((struct sockaddr_in *)(id_spec->id->v))->sin_addr.s_addr);
2363 break;
2364 #ifdef INET6
2365 case AF_INET6:
2366 doi_type = IPSECDOI_ID_IPV6_ADDR;
2367 idlen = sizeof(struct in6_addr);
2368 peers_id = &(((struct sockaddr_in6 *)(id_spec->id->v))->sin6_addr.s6_addr);
2369 break;
2370 #endif
2371 default:
2372 plog(LLV_ERROR, LOCATION, NULL,
2373 "unknown address type for peers identifier.\n");
2374 return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
2375 break;
2376 }
2377
2378 } else {
2379 doi_type = idtype2doi(id_spec->idtype);
2380 peers_id = id_spec->id->v;
2381 idlen = id_spec->id->l;
2382 }
2383 if (oakley_check_certid_in_certchain(iph1->cert_p, doi_type, idlen, peers_id) == 0)
2384 return 0;
2385 }
2386 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2387 }
2388 }
2389
2390 static int
2391 oakley_check_certid_1(cert, idtype, idlen, id, certStatus)
2392 vchar_t *cert;
2393 int idtype;
2394 int idlen;
2395 void *id;
2396 cert_status_t *certStatus;
2397 {
2398
2399 vchar_t *name = NULL;
2400 char *altname = NULL;
2401 int type, len;
2402 int error;
2403
2404 switch (idtype) {
2405 case IPSECDOI_ID_DER_ASN1_DN:
2406 #if TARGET_OS_EMBEDDED
2407 {
2408 SecCertificateRef certificate;
2409 CFDataRef subject;
2410 UInt8* namePtr;
2411
2412 certificate = crypto_cssm_x509cert_get_SecCertificateRef(cert);
2413 if (certificate == NULL) {
2414 plog(LLV_ERROR, LOCATION, NULL, "failed to get SecCertificateRef\n");
2415 if (certStatus && !*certStatus) {
2416 *certStatus = CERT_STATUS_INVALID;
2417 }
2418 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2419 }
2420 subject = SecCertificateCopySubjectSequence(certificate);
2421 if (subject == NULL) {
2422 plog(LLV_ERROR, LOCATION, NULL, "failed to get subjectName\n");
2423 if (certStatus && !*certStatus) {
2424 *certStatus = CERT_STATUS_INVALID_SUBJNAME;
2425 }
2426 CFRelease(certificate);
2427 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2428 }
2429 len = CFDataGetLength(subject);
2430 namePtr = CFDataGetBytePtr(subject);
2431 if (idlen != len) {
2432 plog(LLV_ERROR, LOCATION, NULL, "Invalid ID length in phase 1.\n");
2433 if (certStatus && !*certStatus) {
2434 *certStatus = CERT_STATUS_INVALID_SUBJNAME;
2435 }
2436 CFRelease(subject);
2437 CFRelease(certificate);
2438 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2439 }
2440 error = memcmp(id, namePtr, idlen);
2441 if (error != 0) {
2442 plog(LLV_ERROR, LOCATION, NULL,
2443 "ID mismatched with subjectName.\n");
2444 plog(LLV_ERROR, LOCATION, NULL,
2445 "subjectName (type %s):\n",
2446 s_ipsecdoi_ident(idtype));
2447 plogdump(LLV_ERROR, namePtr, len);
2448 plog(LLV_ERROR, LOCATION, NULL,
2449 "ID:\n");
2450 plogdump(LLV_ERROR, id, idlen);
2451 if (certStatus && !*certStatus) {
2452 *certStatus = CERT_STATUS_INVALID_SUBJNAME;
2453 }
2454 CFRelease(certificate);
2455 CFRelease(subject);
2456 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2457 }
2458 }
2459 #else
2460 name = eay_get_x509asn1subjectname(cert);
2461 if (!name) {
2462 plog(LLV_ERROR, LOCATION, NULL,
2463 "failed to get subjectName\n");
2464 if (certStatus && !*certStatus) {
2465 *certStatus = CERT_STATUS_INVALID_SUBJNAME;
2466 }
2467 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2468 }
2469 if (idlen != name->l) {
2470 plog(LLV_ERROR, LOCATION, NULL,
2471 "Invalid ID length in phase 1.\n");
2472 vfree(name);
2473 if (certStatus && !*certStatus) {
2474 *certStatus = CERT_STATUS_INVALID_SUBJNAME;
2475 }
2476 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2477 }
2478 error = memcmp(id, name->v, idlen);
2479 if (error != 0) {
2480 plog(LLV_ERROR, LOCATION, NULL,
2481 "ID mismatched with subjectName.\n");
2482 plog(LLV_ERROR, LOCATION, NULL,
2483 "subjectName (type %s):\n",
2484 s_ipsecdoi_ident(idtype));
2485 plogdump(LLV_ERROR, name->v, name->l);
2486 plog(LLV_ERROR, LOCATION, NULL,
2487 "ID:\n");
2488 plogdump(LLV_ERROR, id, idlen);
2489 vfree(name);
2490 if (certStatus && !*certStatus) {
2491 *certStatus = CERT_STATUS_INVALID_SUBJNAME;
2492 }
2493 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2494 }
2495 vfree(name);
2496 #endif
2497 return 0;
2498
2499 case IPSECDOI_ID_IPV4_ADDR:
2500 case IPSECDOI_ID_IPV6_ADDR:
2501 {
2502 #if TARGET_OS_EMBEDDED
2503 CFIndex pos, count;
2504 SecCertificateRef certificate;
2505 CFArrayRef addresses;
2506
2507 certificate = crypto_cssm_x509cert_get_SecCertificateRef(cert);
2508 if (certificate == NULL) {
2509 plog(LLV_ERROR, LOCATION, NULL,
2510 "failed to get SecCertificateRef\n");
2511 if (certStatus && !*certStatus) {
2512 *certStatus = CERT_STATUS_INVALID;
2513 }
2514 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2515 }
2516 addresses = SecCertificateCopyIPAddresses(certificate);
2517 if (addresses == NULL) {
2518 plog(LLV_ERROR, LOCATION, NULL, "failed to get subjectName\n");
2519 if (certStatus && !*certStatus) {
2520 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
2521 }
2522 CFRelease(certificate);
2523 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2524 }
2525 count = CFArrayGetCount(addresses);
2526 for (pos = 0; pos < count; pos++) {
2527
2528 CFStringRef address;
2529 CFIndex addressLen;
2530 char *addressBuf, numAddress[128];
2531 int result;
2532
2533 address = CFArrayGetValueAtIndex(addresses, pos);
2534 addressLen = CFStringGetLength(address);
2535 if (addressLen == 0)
2536 continue;
2537 addressBuf = racoon_malloc(addressLen + 1);
2538 if (addressBuf == NULL) {
2539 plog(LLV_ERROR, LOCATION, NULL, "out of memory\n");
2540 return -1;
2541 }
2542 if (CFStringGetCString(address, addressBuf, addressLen + 1, kCFStringEncodingUTF8) == TRUE) {
2543 result = inet_pton(idtype == IPSECDOI_ID_IPV4_ADDR ? AF_INET : AF_INET6, addressBuf, numAddress);
2544 racoon_free(addressBuf);
2545 if (result == 0)
2546 continue; // wrong type or invalid address
2547 if (memcmp(id, numAddress, idtype == IPSECDOI_ID_IPV4_ADDR ? 32 : 128) == 0) { // found a match ?
2548 CFRelease(addresses);
2549 CFRelease(certificate);
2550 return 0;
2551 }
2552 } else
2553 racoon_free(addressBuf);
2554 }
2555 plog(LLV_ERROR, LOCATION, NULL, "ID mismatched with subjectAltName.\n");
2556 plog(LLV_ERROR, LOCATION, NULL,
2557 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype));
2558 plog(LLV_ERROR, LOCATION, NULL, "ID:\n");
2559 plogdump(LLV_ERROR, id, idlen);
2560 CFRelease(addresses);
2561 CFRelease(certificate);
2562 if (certStatus && !*certStatus) {
2563 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
2564 }
2565 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2566 #else
2567 /*
2568 * Openssl returns the IPAddress as an ASN1 octet string (binary format)
2569 * followed by a trailing NULL. 5 bytes for IPv4 and 17 bytes for IPv6
2570 */
2571 #define SUBJ_ALT_NAME_IPV4_ADDRESS_LEN 5
2572 #define SUBJ_ALT_NAME_IPV6_ADDRESS_LEN 17
2573
2574 int pos;
2575
2576 if (idtype == IPSECDOI_ID_IPV4_ADDR && idlen != sizeof(struct in_addr)
2577 || idtype == IPSECDOI_ID_IPV6_ADDR && idlen != sizeof(struct in6_addr)) {
2578 plog(LLV_ERROR, LOCATION, NULL,
2579 "invalid address length passed.\n");
2580 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2581 }
2582
2583 for (pos = 1; ; pos++) {
2584 if (eay_get_x509subjectaltname(cert, &altname, &type, pos, &len) !=0) {
2585 plog(LLV_ERROR, LOCATION, NULL,
2586 "failed to get subjectAltName\n");
2587 if (certStatus && !*certStatus) {
2588 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
2589 }
2590 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2591 }
2592
2593 /* it's the end condition of the loop. */
2594 if (!altname) {
2595 plog(LLV_ERROR, LOCATION, NULL,
2596 "invalid subjectAltName\n");
2597 if (certStatus && !*certStatus) {
2598 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
2599 }
2600 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2601 }
2602
2603 if (check_typeofcertname(idtype, type) != 0) {
2604 /* wrong type - skip this one */
2605 racoon_free(altname);
2606 altname = NULL;
2607 continue;
2608 }
2609
2610 if (len == SUBJ_ALT_NAME_IPV4_ADDRESS_LEN) { /* IPv4 */
2611 if (idtype != IPSECDOI_ID_IPV4_ADDR) {
2612 /* wrong IP address type - skip this one */
2613 racoon_free(altname);
2614 altname = NULL;
2615 continue;
2616 }
2617 }
2618 #ifdef INET6
2619 else if (len == SUBJ_ALT_NAME_IPV6_ADDRESS_LEN) { /* IPv6 */
2620 if (idtype != IPSECDOI_ID_IPV6_ADDR) {
2621 /* wrong IP address type - skip this one */
2622 racoon_free(altname);
2623 altname = NULL;
2624 continue;
2625 }
2626 }
2627 #endif
2628 else {
2629 /* invalid IP address length in certificate - bad or bogus certificate */
2630 plog(LLV_ERROR, LOCATION, NULL,
2631 "invalid IP address in certificate.\n");
2632 plog(LLV_ERROR, LOCATION, NULL,
2633 "subjectAltName (expected type %s, got type %s):\n",
2634 s_ipsecdoi_ident(idtype),
2635 s_ipsecdoi_ident(type));
2636 plogdump(LLV_ERROR, altname, len);
2637 racoon_free(altname);
2638 altname = NULL;
2639 if (certStatus && !*certStatus) {
2640 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
2641 }
2642 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2643 }
2644
2645 /* compare the addresses */
2646 error = memcmp(id, altname, idlen);
2647 if (error)
2648 continue;
2649 racoon_free(altname);
2650 return 0;
2651 }
2652 /* failed to find a match */
2653 plog(LLV_ERROR, LOCATION, NULL,
2654 "ID mismatched with subjectAltName.\n");
2655 plog(LLV_ERROR, LOCATION, NULL,
2656 "subjectAltName (expected type %s, got type %s):\n",
2657 s_ipsecdoi_ident(idtype),
2658 s_ipsecdoi_ident(type));
2659 plogdump(LLV_ERROR, altname, len);
2660 plog(LLV_ERROR, LOCATION, NULL,
2661 "ID:\n");
2662 plogdump(LLV_ERROR, id, idlen);
2663 racoon_free(altname);
2664 if (certStatus && !*certStatus)
2665 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
2666 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2667
2668 #endif /* TARGET_OS_EMBEDDED */
2669 }
2670
2671 #if TARGET_OS_EMBEDDED
2672 case IPSECDOI_ID_FQDN:
2673 {
2674 CFIndex pos, count;
2675 SecCertificateRef certificate;
2676 CFArrayRef names;
2677 CFStringRef name, ID;
2678
2679 certificate = crypto_cssm_x509cert_get_SecCertificateRef(cert);
2680 if (certificate == NULL) {
2681 plog(LLV_ERROR, LOCATION, NULL,
2682 "failed to get SecCertificateRef\n");
2683 if (certStatus && !*certStatus) {
2684 *certStatus = CERT_STATUS_INVALID;
2685 }
2686 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2687 }
2688 names = SecCertificateCopyDNSNames(certificate);
2689 if (names == NULL) {
2690 plog(LLV_ERROR, LOCATION, NULL,
2691 "failed to get subjectName\n");
2692 if (certStatus && !*certStatus) {
2693 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
2694 }
2695 CFRelease(certificate);
2696 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2697 }
2698 count = CFArrayGetCount(names);
2699 ID = CFStringCreateWithCString(NULL, id, kCFStringEncodingUTF8);
2700 if (ID== NULL) {
2701 plog(LLV_ERROR, LOCATION, NULL, "memory error\n");
2702 CFRelease(names);
2703 CFRelease(certificate);
2704
2705 }
2706 for (pos = 0; pos < count; pos++) {
2707 name = CFArrayGetValueAtIndex(names, pos);
2708 if (CFStringCompare(name, ID, 0) == kCFCompareEqualTo) {
2709 CFRelease(ID);
2710 CFRelease(names);
2711 CFRelease(certificate);
2712 return 0;
2713 }
2714 }
2715 plog(LLV_ERROR, LOCATION, NULL, "ID mismatched with subjectAltName.\n");
2716 plog(LLV_ERROR, LOCATION, NULL,
2717 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype));
2718 plog(LLV_ERROR, LOCATION, NULL, "ID:\n");
2719 plogdump(LLV_ERROR, id, idlen);
2720 CFRelease(ID);
2721 CFRelease(names);
2722 CFRelease(certificate);
2723 if (certStatus && !*certStatus) {
2724 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
2725 }
2726 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2727 }
2728
2729 case IPSECDOI_ID_USER_FQDN:
2730 {
2731 CFIndex pos, count;
2732
2733 SecCertificateRef certificate;
2734 CFArrayRef names;
2735 CFStringRef name, ID;
2736
2737 certificate = crypto_cssm_x509cert_get_SecCertificateRef(cert);
2738 if (certificate == NULL) {
2739 plog(LLV_ERROR, LOCATION, NULL,
2740 "failed to get SecCertificateRef\n");
2741 if (certStatus && !*certStatus) {
2742 *certStatus = CERT_STATUS_INVALID;
2743 }
2744 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2745 }
2746 names = SecCertificateCopyRFC822Names(certificate);
2747 if (names == NULL) {
2748 plog(LLV_ERROR, LOCATION, NULL,
2749 "failed to get subjectName\n");
2750 if (certStatus && !*certStatus) {
2751 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
2752 }
2753 CFRelease(certificate);
2754 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2755 }
2756 count = CFArrayGetCount(names);
2757 ID = CFStringCreateWithCString(NULL, id, kCFStringEncodingUTF8);
2758 if (ID == NULL) {
2759 plog(LLV_ERROR, LOCATION, NULL,
2760 "memory error\n");
2761 if (certStatus && !*certStatus) {
2762 *certStatus = CERT_STATUS_INVALID;
2763 }
2764 CFRelease(names);
2765 CFRelease(certificate);
2766 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2767 }
2768 for (pos = 0; pos < count; pos++) {
2769 name = CFArrayGetValueAtIndex(names, pos);
2770 if (CFStringCompare(name, ID, 0) == kCFCompareEqualTo) {
2771 CFRelease(ID);
2772 CFRelease(names);
2773 CFRelease(certificate);
2774 return 0;
2775 }
2776 }
2777 plog(LLV_ERROR, LOCATION, NULL, "ID mismatched with subjectAltName.\n");
2778 plog(LLV_ERROR, LOCATION, NULL,
2779 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype));
2780 plog(LLV_ERROR, LOCATION, NULL, "ID:\n");
2781 plogdump(LLV_ERROR, id, idlen);
2782 CFRelease(ID);
2783 CFRelease(names);
2784 CFRelease(certificate);
2785 if (certStatus && !*certStatus) {
2786 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
2787 }
2788 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2789 }
2790 #else
2791 case IPSECDOI_ID_FQDN:
2792 case IPSECDOI_ID_USER_FQDN:
2793 {
2794 int pos;
2795
2796 for (pos = 1; ; pos++) {
2797 if (eay_get_x509subjectaltname(cert, &altname, &type, pos, &len) != 0) {
2798 plog(LLV_ERROR, LOCATION, NULL,
2799 "failed to get subjectAltName\n");
2800 if (certStatus && !*certStatus) {
2801 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
2802 }
2803 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
2804 }
2805
2806 /* it's the end condition of the loop. */
2807 if (!altname) {
2808 plog(LLV_ERROR, LOCATION, NULL,
2809 "invalid subjectAltName\n");
2810 if (certStatus && !*certStatus) {
2811 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
2812 }
2813 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2814 }
2815
2816 if (check_typeofcertname(idtype, type) != 0) {
2817 /* wrong general type - skip this one */
2818 racoon_free(altname);
2819 altname = NULL;
2820 continue;
2821 }
2822
2823 if (idlen != strlen(altname)) {
2824 /* wrong length - skip this one */
2825 racoon_free(altname);
2826 altname = NULL;
2827 continue;
2828 }
2829 error = memcmp(id, altname, idlen);
2830 if (error)
2831 continue;
2832 racoon_free(altname);
2833 return 0;
2834 }
2835 plog(LLV_ERROR, LOCATION, NULL, "ID mismatched with subjectAltName.\n");
2836 plog(LLV_ERROR, LOCATION, NULL,
2837 "subjectAltName (expected type %s, got type %s):\n",
2838 s_ipsecdoi_ident(idtype),
2839 s_ipsecdoi_ident(type));
2840 plogdump(LLV_ERROR, altname, len);
2841 plog(LLV_ERROR, LOCATION, NULL,
2842 "ID:\n");
2843 plogdump(LLV_ERROR, id, idlen);
2844 racoon_free(altname);
2845 if (certStatus && !*certStatus)
2846 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
2847 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2848 }
2849 #endif
2850 default:
2851 plog(LLV_ERROR, LOCATION, NULL,
2852 "Impropper ID type passed: %s.\n",
2853 s_ipsecdoi_ident(idtype));
2854 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2855 }
2856 /*NOTREACHED*/
2857 }
2858 #ifdef HAVE_OPENSSL
2859 static int
2860 check_typeofcertname(doi, genid)
2861 int doi, genid;
2862 {
2863 switch (doi) {
2864 case IPSECDOI_ID_IPV4_ADDR:
2865 case IPSECDOI_ID_IPV4_ADDR_SUBNET:
2866 case IPSECDOI_ID_IPV6_ADDR:
2867 case IPSECDOI_ID_IPV6_ADDR_SUBNET:
2868 case IPSECDOI_ID_IPV4_ADDR_RANGE:
2869 case IPSECDOI_ID_IPV6_ADDR_RANGE:
2870 if (genid != GENT_IPADD)
2871 return -1;
2872 return 0;
2873 case IPSECDOI_ID_FQDN:
2874 if (genid != GENT_DNS)
2875 return -1;
2876 return 0;
2877 case IPSECDOI_ID_USER_FQDN:
2878 if (genid != GENT_EMAIL)
2879 return -1;
2880 return 0;
2881 case IPSECDOI_ID_DER_ASN1_DN: /* should not be passed to this function*/
2882 case IPSECDOI_ID_DER_ASN1_GN:
2883 case IPSECDOI_ID_KEY_ID:
2884 default:
2885 return -1;
2886 }
2887 /*NOTREACHED*/
2888 }
2889 #endif
2890
2891 /*
2892 * save certificate including certificate type.
2893 */
2894 int
2895 oakley_savecert(iph1, gen)
2896 struct ph1handle *iph1;
2897 struct isakmp_gen *gen;
2898 {
2899 cert_t **c;
2900 u_int8_t type;
2901 #ifdef HAVE_OPENSSL
2902 STACK_OF(X509) *certs=NULL;
2903 PKCS7 *p7;
2904 #endif
2905 type = *(u_int8_t *)(gen + 1) & 0xff;
2906
2907 switch (type) {
2908 case ISAKMP_CERT_DNS:
2909 plog(LLV_WARNING, LOCATION, NULL,
2910 "CERT payload is unnecessary in DNSSEC. "
2911 "ignore this CERT payload.\n");
2912 return 0;
2913 case ISAKMP_CERT_PKCS7:
2914 case ISAKMP_CERT_PGP:
2915 case ISAKMP_CERT_X509SIGN:
2916 case ISAKMP_CERT_KERBEROS:
2917 case ISAKMP_CERT_SPKI:
2918 c = &iph1->cert_p;
2919 break;
2920 case ISAKMP_CERT_CRL:
2921 c = &iph1->crl_p;
2922 break;
2923 case ISAKMP_CERT_X509KE:
2924 case ISAKMP_CERT_X509ATTR:
2925 case ISAKMP_CERT_ARL:
2926 plog(LLV_ERROR, LOCATION, NULL,
2927 "No supported such CERT type %d\n", type);
2928 return -1;
2929 default:
2930 plog(LLV_ERROR, LOCATION, NULL,
2931 "Invalid CERT type %d\n", type);
2932 return -1;
2933 }
2934
2935 if (*c) {
2936 plog(LLV_WARNING, LOCATION, NULL,
2937 "preexisting CERT payload... chaining.\n");
2938 }
2939 #ifdef HAVE_OPENSSL
2940 if (type == ISAKMP_CERT_PKCS7) {
2941 u_char *bp;
2942 int i;
2943
2944 /* Skip the header */
2945 bp = (u_char *)(gen + 1);
2946 /* And the first byte is the certificate type,
2947 * we know that already
2948 */
2949 bp++;
2950 p7 = d2i_PKCS7(NULL, (void *)&bp,
2951 ntohs(gen->len) - sizeof(*gen) - 1);
2952
2953 if (!p7) {
2954 plog(LLV_ERROR, LOCATION, NULL,
2955 "Failed to parse PKCS#7 CERT.\n");
2956 return -1;
2957 }
2958
2959 /* Copied this from the openssl pkcs7 application;
2960 * there"s little by way of documentation for any of
2961 * it. I can only presume it"s correct.
2962 */
2963
2964 i = OBJ_obj2nid(p7->type);
2965 switch (i) {
2966 case NID_pkcs7_signed:
2967 certs=p7->d.sign->cert;
2968 break;
2969 case NID_pkcs7_signedAndEnveloped:
2970 certs=p7->d.signed_and_enveloped->cert;
2971 break;
2972 default:
2973 break;
2974 }
2975
2976 if (!certs) {
2977 plog(LLV_ERROR, LOCATION, NULL,
2978 "CERT PKCS#7 bundle contains no certs.\n");
2979 PKCS7_free(p7);
2980 return -1;
2981 }
2982
2983 for (i = 0; i < sk_X509_num(certs); i++) {
2984 int len;
2985 u_char *bp;
2986 cert_t *new;
2987 X509 *cert = sk_X509_value(certs,i);
2988
2989 plog(LLV_DEBUG, LOCATION, NULL,
2990 "Trying PKCS#7 cert %d.\n", i);
2991
2992 /* We'll just try each cert in turn */
2993 new = save_certx509(cert);
2994 if (!new) {
2995 plog(LLV_ERROR, LOCATION, NULL,
2996 "Failed to get CERT buffer.\n");
2997 continue;
2998 }
2999 *c = oakley_appendcert_to_certchain(*c, new);
3000 plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
3001 plogdump(LLV_DEBUG, new->cert.v, new->cert.l);
3002 oakley_cert_prettyprint(&new->cert);
3003 }
3004 PKCS7_free(p7);
3005
3006 } else
3007 #endif
3008 {
3009 cert_t *new;
3010 new = save_certbuf(gen);
3011 if (!new) {
3012 plog(LLV_ERROR, LOCATION, NULL,
3013 "Failed to get CERT buffer.\n");
3014 return -1;
3015 }
3016
3017 switch (new->type) {
3018 case ISAKMP_CERT_DNS:
3019 plog(LLV_WARNING, LOCATION, NULL,
3020 "CERT payload is unnecessary in DNSSEC. "
3021 "ignore it.\n");
3022 return 0;
3023 case ISAKMP_CERT_PGP:
3024 case ISAKMP_CERT_X509SIGN:
3025 case ISAKMP_CERT_KERBEROS:
3026 case ISAKMP_CERT_SPKI:
3027 /* Ignore cert if it doesn't match identity
3028 * XXX If verify cert is disabled, we still just take
3029 * the first certificate....
3030 */
3031 *c = oakley_appendcert_to_certchain(*c, new);
3032 plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
3033 plogdump(LLV_DEBUG, new->cert.v, new->cert.l);
3034 oakley_cert_prettyprint(&new->cert);
3035 break;
3036 case ISAKMP_CERT_CRL:
3037 *c = oakley_appendcert_to_certchain(*c, new);
3038 plog(LLV_DEBUG, LOCATION, NULL, "CRL saved:\n");
3039 plogdump(LLV_DEBUG, new->cert.v, new->cert.l);
3040 oakley_cert_prettyprint(&new->cert);
3041 break;
3042 case ISAKMP_CERT_X509KE:
3043 case ISAKMP_CERT_X509ATTR:
3044 case ISAKMP_CERT_ARL:
3045 default:
3046 /* XXX */
3047 oakley_delcert(new);
3048 return 0;
3049 }
3050 }
3051
3052 return 0;
3053 }
3054
3055 /*
3056 * save certificate including certificate type.
3057 */
3058 int
3059 oakley_savecr(iph1, gen)
3060 struct ph1handle *iph1;
3061 struct isakmp_gen *gen;
3062 {
3063 cert_t **c;
3064 u_int8_t type;
3065 cert_t *new;
3066
3067 type = *(u_int8_t *)(gen + 1) & 0xff;
3068
3069 switch (type) {
3070 case ISAKMP_CERT_DNS:
3071 plog(LLV_WARNING, LOCATION, NULL,
3072 "CERT payload is unnecessary in DNSSEC\n");
3073 /*FALLTHRU*/
3074 case ISAKMP_CERT_PKCS7:
3075 case ISAKMP_CERT_PGP:
3076 case ISAKMP_CERT_X509SIGN:
3077 case ISAKMP_CERT_KERBEROS:
3078 case ISAKMP_CERT_SPKI:
3079 if (iph1->cr_p) {
3080 oakley_delcert(iph1->cr_p);
3081 iph1->cr_p = NULL;
3082 }
3083 c = &iph1->cr_p;
3084 break;
3085 case ISAKMP_CERT_X509KE:
3086 case ISAKMP_CERT_X509ATTR:
3087 case ISAKMP_CERT_ARL:
3088 plog(LLV_ERROR, LOCATION, NULL,
3089 "No supported such CR type %d\n", type);
3090 return -1;
3091 case ISAKMP_CERT_CRL:
3092 default:
3093 plog(LLV_ERROR, LOCATION, NULL,
3094 "Invalid CR type %d\n", type);
3095 return -1;
3096 }
3097
3098 new = save_certbuf(gen);
3099 if (!new) {
3100 plog(LLV_ERROR, LOCATION, NULL,
3101 "Failed to get CR buffer.\n");
3102 return -1;
3103 }
3104 *c = oakley_appendcert_to_certchain(*c, new);
3105 plog(LLV_DEBUG, LOCATION, NULL, "CR saved:\n");
3106 plogdump(LLV_DEBUG, new->cert.v, new->cert.l);
3107
3108 return 0;
3109 }
3110
3111 static cert_t *
3112 save_certbuf(gen)
3113 struct isakmp_gen *gen;
3114 {
3115 cert_t *new;
3116
3117 if(ntohs(gen->len) <= sizeof(*gen)){
3118 plog(LLV_ERROR, LOCATION, NULL,
3119 "Len is too small !!.\n");
3120 return NULL;
3121 }
3122
3123 new = oakley_newcert();
3124 if (!new) {
3125 plog(LLV_ERROR, LOCATION, NULL,
3126 "Failed to get CERT buffer.\n");
3127 return NULL;
3128 }
3129
3130 new->pl = vmalloc(ntohs(gen->len) - sizeof(*gen));
3131 if (new->pl == NULL) {
3132 plog(LLV_ERROR, LOCATION, NULL,
3133 "Failed to copy CERT from packet.\n");
3134 oakley_delcert(new);
3135 new = NULL;
3136 return NULL;
3137 }
3138 memcpy(new->pl->v, gen + 1, new->pl->l);
3139 new->type = new->pl->v[0] & 0xff;
3140 new->cert.v = new->pl->v + 1;
3141 new->cert.l = new->pl->l - 1;
3142
3143 return new;
3144 }
3145
3146 #ifdef HAVE_OPENSSL
3147 static cert_t *
3148 save_certx509(cert)
3149 X509 *cert;
3150 {
3151 cert_t *new;
3152 int len;
3153 u_char *bp;
3154
3155 new = oakley_newcert();
3156 if (!new) {
3157 plog(LLV_ERROR, LOCATION, NULL,
3158 "Failed to get CERT buffer.\n");
3159 return NULL;
3160 }
3161
3162 len = i2d_X509(cert, NULL);
3163 new->pl = vmalloc(len);
3164 if (new->pl == NULL) {
3165 plog(LLV_ERROR, LOCATION, NULL,
3166 "Failed to copy CERT from packet.\n");
3167 oakley_delcert(new);
3168 new = NULL;
3169 return NULL;
3170 }
3171 bp = (u_char *) new->pl->v;
3172 len = i2d_X509(cert, &bp);
3173 new->type = ISAKMP_CERT_X509SIGN;
3174 new->cert.v = new->pl->v;
3175 new->cert.l = new->pl->l;
3176
3177 return new;
3178 }
3179 #endif
3180
3181 /*
3182 * get my CR.
3183 * NOTE: No Certificate Authority field is included to CR payload at the
3184 * moment. Becuase any certificate authority are accepted without any check.
3185 * The section 3.10 in RFC2408 says that this field SHOULD not be included,
3186 * if there is no specific certificate authority requested.
3187 */
3188 vchar_t *
3189 oakley_getcr(iph1)
3190 struct ph1handle *iph1;
3191 {
3192 vchar_t *buf;
3193
3194 buf = vmalloc(1);
3195 if (buf == NULL) {
3196 plog(LLV_ERROR, LOCATION, NULL,
3197 "failed to get cr buffer\n");
3198 return NULL;
3199 }
3200 if(iph1->rmconf->certtype == ISAKMP_CERT_NONE) {
3201 buf->v[0] = iph1->rmconf->cacerttype;
3202 plog(LLV_DEBUG, LOCATION, NULL, "create my CR: NONE, using %s instead\n",
3203 s_isakmp_certtype(iph1->rmconf->cacerttype));
3204 } else {
3205 buf->v[0] = iph1->rmconf->certtype;
3206 plog(LLV_DEBUG, LOCATION, NULL, "create my CR: %s\n",
3207 s_isakmp_certtype(iph1->rmconf->certtype));
3208 }
3209 if (buf->l > 1)
3210 plogdump(LLV_DEBUG, buf->v, buf->l);
3211
3212 return buf;
3213 }
3214
3215 /*
3216 * check peer's CR.
3217 */
3218 int
3219 oakley_checkcr(iph1)
3220 struct ph1handle *iph1;
3221 {
3222 if (iph1->cr_p == NULL)
3223 return 0;
3224
3225 plog(LLV_DEBUG, LOCATION, iph1->remote,
3226 "peer transmitted CR: %s\n",
3227 s_isakmp_certtype(iph1->cr_p->type));
3228
3229 if (iph1->cr_p->type != iph1->rmconf->certtype) {
3230 plog(LLV_ERROR, LOCATION, iph1->remote,
3231 "such a cert type isn't supported: %d\n",
3232 (char)iph1->cr_p->type);
3233 return -1;
3234 }
3235
3236 return 0;
3237 }
3238
3239 /*
3240 * check to need CR payload.
3241 */
3242 int
3243 oakley_needcr(type)
3244 int type;
3245 {
3246 switch (type) {
3247 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
3248 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
3249 #ifdef ENABLE_HYBRID
3250 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
3251 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
3252 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
3253 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
3254 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
3255 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
3256 #endif
3257 return 1;
3258 default:
3259 return 0;
3260 }
3261 /*NOTREACHED*/
3262 }
3263
3264 /*
3265 * compute SKEYID
3266 * see seciton 5. Exchanges in RFC 2409
3267 * psk: SKEYID = prf(pre-shared-key, Ni_b | Nr_b)
3268 * sig: SKEYID = prf(Ni_b | Nr_b, g^ir)
3269 * enc: SKEYID = prf(H(Ni_b | Nr_b), CKY-I | CKY-R)
3270 */
3271 int
3272 oakley_skeyid(iph1)
3273 struct ph1handle *iph1;
3274 {
3275 vchar_t *buf = NULL, *bp;
3276 char *p;
3277 int len;
3278 int error = -1;
3279
3280 /* SKEYID */
3281 switch (AUTHMETHOD(iph1)) {
3282 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
3283 #ifdef ENABLE_HYBRID
3284 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
3285 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
3286 #endif
3287 if (iph1->rmconf->shared_secret) {
3288
3289 switch (iph1->rmconf->secrettype) {
3290 case SECRETTYPE_KEY:
3291 /* in psk file - use KEY from remote configuration to locate it */
3292 iph1->authstr = getpsk(iph1->rmconf->shared_secret->v, iph1->rmconf->shared_secret->l-1);
3293 break;
3294 #if HAVE_KEYCHAIN
3295 case SECRETTYPE_KEYCHAIN:
3296 /* in the system keychain */
3297 iph1->authstr = getpskfromkeychain(iph1->rmconf->shared_secret->v, iph1->etype, iph1->rmconf->secrettype, NULL);
3298 break;
3299 case SECRETTYPE_KEYCHAIN_BY_ID:
3300 /* in the system keychain - use peer id */
3301 iph1->authstr = getpskfromkeychain(iph1->rmconf->shared_secret->v, iph1->etype, iph1->rmconf->secrettype, iph1->id_p);
3302 break;
3303 #endif HAVE_KEYCHAIN
3304 case SECRETTYPE_USE:
3305 /* in the remote configuration */
3306 default:
3307 /* rmconf->shared_secret is a string and contains a NULL character that must be removed */
3308 iph1->authstr = vmalloc(iph1->rmconf->shared_secret->l - 1);
3309 if (iph1->authstr == NULL) {
3310 plog(LLV_ERROR, LOCATION, NULL, "memory error.\n");
3311 break;
3312 }
3313 memcpy(iph1->authstr->v, iph1->rmconf->shared_secret->v, iph1->authstr->l);
3314 }
3315 }
3316 else
3317 if (iph1->etype != ISAKMP_ETYPE_IDENT) {
3318 iph1->authstr = getpskbyname(iph1->id_p);
3319 if (iph1->authstr == NULL) {
3320 if (iph1->rmconf->verify_identifier) {
3321 plog(LLV_ERROR, LOCATION, iph1->remote,
3322 "couldn't find the pskey.\n");
3323 goto end;
3324 }
3325 plog(LLV_NOTIFY, LOCATION, iph1->remote,
3326 "couldn't find the proper pskey, "
3327 "try to get one by the peer's address.\n");
3328 }
3329 }
3330 if (iph1->authstr == NULL) {
3331 /*
3332 * If the exchange type is the main mode or if it's
3333 * failed to get the psk by ID, racoon try to get
3334 * the psk by remote IP address.
3335 * It may be nonsense.
3336 */
3337 iph1->authstr = getpskbyaddr(iph1->remote);
3338 if (iph1->authstr == NULL) {
3339 plog(LLV_ERROR, LOCATION, iph1->remote,
3340 "couldn't find the pskey for %s.\n",
3341 saddrwop2str(iph1->remote));
3342 goto end;
3343 }
3344 }
3345 plog(LLV_DEBUG, LOCATION, NULL, "the psk found.\n");
3346 /* should be secret PSK */
3347 plog(LLV_DEBUG2, LOCATION, NULL, "psk: ");
3348 plogdump(LLV_DEBUG2, iph1->authstr->v, iph1->authstr->l);
3349
3350 len = iph1->nonce->l + iph1->nonce_p->l;
3351 buf = vmalloc(len);
3352 if (buf == NULL) {
3353 plog(LLV_ERROR, LOCATION, NULL,
3354 "failed to get skeyid buffer\n");
3355 goto end;
3356 }
3357 p = buf->v;
3358
3359 bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p);
3360 plog(LLV_DEBUG, LOCATION, NULL, "nonce 1: ");
3361 plogdump(LLV_DEBUG, bp->v, bp->l);
3362 memcpy(p, bp->v, bp->l);
3363 p += bp->l;
3364
3365 bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce);
3366 plog(LLV_DEBUG, LOCATION, NULL, "nonce 2: ");
3367 plogdump(LLV_DEBUG, bp->v, bp->l);
3368 memcpy(p, bp->v, bp->l);
3369 p += bp->l;
3370
3371 iph1->skeyid = oakley_prf(iph1->authstr, buf, iph1);
3372 if (iph1->skeyid == NULL)
3373 goto end;
3374 break;
3375
3376 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
3377 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
3378 #ifdef ENABLE_HYBRID
3379 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
3380 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
3381 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
3382 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
3383 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
3384 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
3385 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
3386 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
3387 #endif
3388 #ifdef HAVE_GSSAPI
3389 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
3390 #endif
3391 len = iph1->nonce->l + iph1->nonce_p->l;
3392 buf = vmalloc(len);
3393 if (buf == NULL) {
3394 plog(LLV_ERROR, LOCATION, NULL,
3395 "failed to get nonce buffer\n");
3396 goto end;
3397 }
3398 p = buf->v;
3399
3400 bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p);
3401 plog(LLV_DEBUG, LOCATION, NULL, "nonce1: ");
3402 plogdump(LLV_DEBUG, bp->v, bp->l);
3403 memcpy(p, bp->v, bp->l);
3404 p += bp->l;
3405
3406 bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce);
3407 plog(LLV_DEBUG, LOCATION, NULL, "nonce2: ");
3408 plogdump(LLV_DEBUG, bp->v, bp->l);
3409 memcpy(p, bp->v, bp->l);
3410 p += bp->l;
3411
3412 iph1->skeyid = oakley_prf(buf, iph1->dhgxy, iph1);
3413 if (iph1->skeyid == NULL)
3414 goto end;
3415 break;
3416 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
3417 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
3418 #ifdef ENABLE_HYBRID
3419 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
3420 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
3421 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
3422 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
3423 #endif
3424 plog(LLV_WARNING, LOCATION, NULL,
3425 "not supported authentication method %s\n",
3426 s_oakley_attr_method(iph1->approval->authmethod));
3427 goto end;
3428 default:
3429 plog(LLV_ERROR, LOCATION, NULL,
3430 "invalid authentication method %d\n",
3431 iph1->approval->authmethod);
3432 goto end;
3433 }
3434
3435 plog(LLV_DEBUG, LOCATION, NULL, "SKEYID computed:\n");
3436 plogdump(LLV_DEBUG, iph1->skeyid->v, iph1->skeyid->l);
3437
3438 error = 0;
3439
3440 end:
3441 if (buf != NULL)
3442 vfree(buf);
3443 return error;
3444 }
3445
3446 /*
3447 * compute SKEYID_[dae]
3448 * see seciton 5. Exchanges in RFC 2409
3449 * SKEYID_d = prf(SKEYID, g^ir | CKY-I | CKY-R | 0)
3450 * SKEYID_a = prf(SKEYID, SKEYID_d | g^ir | CKY-I | CKY-R | 1)
3451 * SKEYID_e = prf(SKEYID, SKEYID_a | g^ir | CKY-I | CKY-R | 2)
3452 */
3453 int
3454 oakley_skeyid_dae(iph1)
3455 struct ph1handle *iph1;
3456 {
3457 vchar_t *buf = NULL;
3458 char *p;
3459 int len;
3460 int error = -1;
3461
3462 if (iph1->skeyid == NULL) {
3463 plog(LLV_ERROR, LOCATION, NULL, "no SKEYID found.\n");
3464 goto end;
3465 }
3466
3467 /* SKEYID D */
3468 /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
3469 len = iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
3470 buf = vmalloc(len);
3471 if (buf == NULL) {
3472 plog(LLV_ERROR, LOCATION, NULL,
3473 "failed to get skeyid buffer\n");
3474 goto end;
3475 }
3476 p = buf->v;
3477
3478 memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l);
3479 p += iph1->dhgxy->l;
3480 memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t));
3481 p += sizeof(cookie_t);
3482 memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t));
3483 p += sizeof(cookie_t);
3484 *p = 0;
3485 iph1->skeyid_d = oakley_prf(iph1->skeyid, buf, iph1);
3486 if (iph1->skeyid_d == NULL)
3487 goto end;
3488
3489 vfree(buf);
3490 buf = NULL;
3491
3492 plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_d computed:\n");
3493 plogdump(LLV_DEBUG, iph1->skeyid_d->v, iph1->skeyid_d->l);
3494
3495 /* SKEYID A */
3496 /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
3497 len = iph1->skeyid_d->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
3498 buf = vmalloc(len);
3499 if (buf == NULL) {
3500 plog(LLV_ERROR, LOCATION, NULL,
3501 "failed to get skeyid buffer\n");
3502 goto end;
3503 }
3504 p = buf->v;
3505 memcpy(p, iph1->skeyid_d->v, iph1->skeyid_d->l);
3506 p += iph1->skeyid_d->l;
3507 memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l);
3508 p += iph1->dhgxy->l;
3509 memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t));
3510 p += sizeof(cookie_t);
3511 memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t));
3512 p += sizeof(cookie_t);
3513 *p = 1;
3514 iph1->skeyid_a = oakley_prf(iph1->skeyid, buf, iph1);
3515 if (iph1->skeyid_a == NULL)
3516 goto end;
3517
3518 vfree(buf);
3519 buf = NULL;
3520
3521 plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_a computed:\n");
3522 plogdump(LLV_DEBUG, iph1->skeyid_a->v, iph1->skeyid_a->l);
3523
3524 /* SKEYID E */
3525 /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
3526 len = iph1->skeyid_a->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
3527 buf = vmalloc(len);
3528 if (buf == NULL) {
3529 plog(LLV_ERROR, LOCATION, NULL,
3530 "failed to get skeyid buffer\n");
3531 goto end;
3532 }
3533 p = buf->v;
3534 memcpy(p, iph1->skeyid_a->v, iph1->skeyid_a->l);
3535 p += iph1->skeyid_a->l;
3536 memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l);
3537 p += iph1->dhgxy->l;
3538 memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t));
3539 p += sizeof(cookie_t);
3540 memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t));
3541 p += sizeof(cookie_t);
3542 *p = 2;
3543 iph1->skeyid_e = oakley_prf(iph1->skeyid, buf, iph1);
3544 if (iph1->skeyid_e == NULL)
3545 goto end;
3546
3547 vfree(buf);
3548 buf = NULL;
3549
3550 plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_e computed:\n");
3551 plogdump(LLV_DEBUG, iph1->skeyid_e->v, iph1->skeyid_e->l);
3552
3553 error = 0;
3554
3555 end:
3556 if (buf != NULL)
3557 vfree(buf);
3558 return error;
3559 }
3560
3561 /*
3562 * compute final encryption key.
3563 * see Appendix B.
3564 */
3565 int
3566 oakley_compute_enckey(iph1)
3567 struct ph1handle *iph1;
3568 {
3569 u_int keylen, prflen;
3570 int error = -1;
3571
3572 /* RFC2409 p39 */
3573 keylen = alg_oakley_encdef_keylen(iph1->approval->enctype,
3574 iph1->approval->encklen);
3575 if (keylen == -1) {
3576 plog(LLV_ERROR, LOCATION, NULL,
3577 "invalid encryption algoritym %d, "
3578 "or invalid key length %d.\n",
3579 iph1->approval->enctype,
3580 iph1->approval->encklen);
3581 goto end;
3582 }
3583 iph1->key = vmalloc(keylen >> 3);
3584 if (iph1->key == NULL) {
3585 plog(LLV_ERROR, LOCATION, NULL,
3586 "failed to get key buffer\n");
3587 goto end;
3588 }
3589
3590 /* set prf length */
3591 prflen = alg_oakley_hashdef_hashlen(iph1->approval->hashtype);
3592 if (prflen == -1) {
3593 plog(LLV_ERROR, LOCATION, NULL,
3594 "invalid hash type %d.\n", iph1->approval->hashtype);
3595 goto end;
3596 }
3597
3598 /* see isakmp-oakley-08 5.3. */
3599 if (iph1->key->l <= iph1->skeyid_e->l) {
3600 /*
3601 * if length(Ka) <= length(SKEYID_e)
3602 * Ka = first length(K) bit of SKEYID_e
3603 */
3604 memcpy(iph1->key->v, iph1->skeyid_e->v, iph1->key->l);
3605 } else {
3606 vchar_t *buf = NULL, *res = NULL;
3607 u_char *p, *ep;
3608 int cplen;
3609 int subkey;
3610
3611 /*
3612 * otherwise,
3613 * Ka = K1 | K2 | K3
3614 * where
3615 * K1 = prf(SKEYID_e, 0)
3616 * K2 = prf(SKEYID_e, K1)
3617 * K3 = prf(SKEYID_e, K2)
3618 */
3619 plog(LLV_DEBUG, LOCATION, NULL,
3620 "len(SKEYID_e) < len(Ka) (%zu < %zu), "
3621 "generating long key (Ka = K1 | K2 | ...)\n",
3622 iph1->skeyid_e->l, iph1->key->l);
3623
3624 if ((buf = vmalloc(prflen >> 3)) == 0) {
3625 plog(LLV_ERROR, LOCATION, NULL,
3626 "failed to get key buffer\n");
3627 goto end;
3628 }
3629 p = (u_char *)iph1->key->v;
3630 ep = p + iph1->key->l;
3631
3632 subkey = 1;
3633 while (p < ep) {
3634 if (p == (u_char *)iph1->key->v) {
3635 /* just for computing K1 */
3636 buf->v[0] = 0;
3637 buf->l = 1;
3638 }
3639 res = oakley_prf(iph1->skeyid_e, buf, iph1);
3640 if (res == NULL) {
3641 vfree(buf);
3642 goto end;
3643 }
3644 plog(LLV_DEBUG, LOCATION, NULL,
3645 "compute intermediate encryption key K%d\n",
3646 subkey);
3647 plogdump(LLV_DEBUG, buf->v, buf->l);
3648 plogdump(LLV_DEBUG, res->v, res->l);
3649
3650 cplen = (res->l < ep - p) ? res->l : ep - p;
3651 memcpy(p, res->v, cplen);
3652 p += cplen;
3653
3654 buf->l = prflen >> 3; /* to cancel K1 speciality */
3655 if (res->l != buf->l) {
3656 plog(LLV_ERROR, LOCATION, NULL,
3657 "internal error: res->l=%zu buf->l=%zu\n",
3658 res->l, buf->l);
3659 vfree(res);
3660 vfree(buf);
3661 goto end;
3662 }
3663 memcpy(buf->v, res->v, res->l);
3664 vfree(res);
3665 subkey++;
3666 }
3667
3668 vfree(buf);
3669 }
3670
3671 /*
3672 * don't check any weak key or not.
3673 * draft-ietf-ipsec-ike-01.txt Appendix B.
3674 * draft-ietf-ipsec-ciph-aes-cbc-00.txt Section 2.3.
3675 */
3676 #if 0
3677 /* weakkey check */
3678 if (iph1->approval->enctype > ARRAYLEN(oakley_encdef)
3679 || oakley_encdef[iph1->approval->enctype].weakkey == NULL) {
3680 plog(LLV_ERROR, LOCATION, NULL,
3681 "encryption algoritym %d isn't supported.\n",
3682 iph1->approval->enctype);
3683 goto end;
3684 }
3685 if ((oakley_encdef[iph1->approval->enctype].weakkey)(iph1->key)) {
3686 plog(LLV_ERROR, LOCATION, NULL,
3687 "weakkey was generated.\n");
3688 goto end;
3689 }
3690 #endif
3691
3692 plog(LLV_DEBUG, LOCATION, NULL, "final encryption key computed:\n");
3693 plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
3694
3695 error = 0;
3696
3697 end:
3698 return error;
3699 }
3700
3701 /* allocated new buffer for CERT */
3702 cert_t *
3703 oakley_newcert()
3704 {
3705 cert_t *new;
3706
3707 new = racoon_calloc(1, sizeof(*new));
3708 if (new == NULL) {
3709 plog(LLV_ERROR, LOCATION, NULL,
3710 "failed to get cert's buffer\n");
3711 return NULL;
3712 }
3713
3714 new->pl = NULL;
3715 new->chain = NULL;
3716
3717 return new;
3718 }
3719
3720 /* delete buffer for CERT */
3721 void
3722 oakley_delcert_1(cert)
3723 cert_t *cert;
3724 {
3725 if (!cert)
3726 return;
3727 if (cert->pl)
3728 VPTRINIT(cert->pl);
3729 racoon_free(cert);
3730 }
3731
3732 /* delete buffer for CERT */
3733 void
3734 oakley_delcert(cert)
3735 cert_t *cert;
3736 {
3737 cert_t *p, *to_delete;
3738
3739 if (!cert)
3740 return;
3741
3742 for (p = cert; p;) {
3743 to_delete = p;
3744 p = p->chain;
3745 oakley_delcert_1(to_delete);
3746 }
3747 }
3748
3749 /* delete buffer for CERT */
3750 static cert_t *
3751 oakley_appendcert_to_certchain(certchain, new)
3752 cert_t *certchain;
3753 cert_t *new;
3754 {
3755 cert_t *p;
3756
3757 if (!certchain)
3758 return new;
3759
3760 for (p = certchain; p; p = p->chain) {
3761 if (!p->chain) {
3762 p->chain = new;
3763 return certchain;
3764 }
3765 }
3766 return NULL;
3767 }
3768
3769 /*
3770 * compute IV and set to ph1handle
3771 * IV = hash(g^xi | g^xr)
3772 * see 4.1 Phase 1 state in draft-ietf-ipsec-ike.
3773 */
3774 int
3775 oakley_newiv(iph1)
3776 struct ph1handle *iph1;
3777 {
3778 struct isakmp_ivm *newivm = NULL;
3779 vchar_t *buf = NULL, *bp;
3780 char *p;
3781 int len;
3782
3783 /* create buffer */
3784 len = iph1->dhpub->l + iph1->dhpub_p->l;
3785 buf = vmalloc(len);
3786 if (buf == NULL) {
3787 plog(LLV_ERROR, LOCATION, NULL,
3788 "failed to get iv buffer\n");
3789 return -1;
3790 }
3791
3792 p = buf->v;
3793
3794 bp = (iph1->side == INITIATOR ? iph1->dhpub : iph1->dhpub_p);
3795 memcpy(p, bp->v, bp->l);
3796 p += bp->l;
3797
3798 bp = (iph1->side == INITIATOR ? iph1->dhpub_p : iph1->dhpub);
3799 memcpy(p, bp->v, bp->l);
3800 p += bp->l;
3801
3802 /* allocate IVm */
3803 newivm = racoon_calloc(1, sizeof(struct isakmp_ivm));
3804 if (newivm == NULL) {
3805 plog(LLV_ERROR, LOCATION, NULL,
3806 "failed to get iv buffer\n");
3807 vfree(buf);
3808 return -1;
3809 }
3810
3811 /* compute IV */
3812 newivm->iv = oakley_hash(buf, iph1);
3813 if (newivm->iv == NULL) {
3814 vfree(buf);
3815 oakley_delivm(newivm);
3816 return -1;
3817 }
3818
3819 /* adjust length of iv */
3820 newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype);
3821 if (newivm->iv->l == -1) {
3822 plog(LLV_ERROR, LOCATION, NULL,
3823 "invalid encryption algoriym %d.\n",
3824 iph1->approval->enctype);
3825 vfree(buf);
3826 oakley_delivm(newivm);
3827 return -1;
3828 }
3829
3830 /* create buffer to save iv */
3831 if ((newivm->ive = vdup(newivm->iv)) == NULL) {
3832 plog(LLV_ERROR, LOCATION, NULL,
3833 "vdup (%s)\n", strerror(errno));
3834 vfree(buf);
3835 oakley_delivm(newivm);
3836 return -1;
3837 }
3838
3839 vfree(buf);
3840
3841 plog(LLV_DEBUG, LOCATION, NULL, "IV computed:\n");
3842 plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l);
3843
3844 if (iph1->ivm != NULL)
3845 oakley_delivm(iph1->ivm);
3846
3847 iph1->ivm = newivm;
3848
3849 return 0;
3850 }
3851
3852 /*
3853 * compute IV for the payload after phase 1.
3854 * It's not limited for phase 2.
3855 * if pahse 1 was encrypted.
3856 * IV = hash(last CBC block of Phase 1 | M-ID)
3857 * if phase 1 was not encrypted.
3858 * IV = hash(phase 1 IV | M-ID)
3859 * see 4.2 Phase 2 state in draft-ietf-ipsec-ike.
3860 */
3861 struct isakmp_ivm *
3862 oakley_newiv2(iph1, msgid)
3863 struct ph1handle *iph1;
3864 u_int32_t msgid;
3865 {
3866 struct isakmp_ivm *newivm = NULL;
3867 vchar_t *buf = NULL;
3868 char *p;
3869 int len;
3870 int error = -1;
3871
3872 /* create buffer */
3873 len = iph1->ivm->iv->l + sizeof(msgid_t);
3874 buf = vmalloc(len);
3875 if (buf == NULL) {
3876 plog(LLV_ERROR, LOCATION, NULL,
3877 "failed to get iv buffer\n");
3878 goto end;
3879 }
3880
3881 p = buf->v;
3882
3883 memcpy(p, iph1->ivm->iv->v, iph1->ivm->iv->l);
3884 p += iph1->ivm->iv->l;
3885
3886 memcpy(p, &msgid, sizeof(msgid));
3887
3888 plog(LLV_DEBUG, LOCATION, NULL, "compute IV for phase2\n");
3889 plog(LLV_DEBUG, LOCATION, NULL, "phase1 last IV:\n");
3890 plogdump(LLV_DEBUG, buf->v, buf->l);
3891
3892 /* allocate IVm */
3893 newivm = racoon_calloc(1, sizeof(struct isakmp_ivm));
3894 if (newivm == NULL) {
3895 plog(LLV_ERROR, LOCATION, NULL,
3896 "failed to get iv buffer\n");
3897 goto end;
3898 }
3899
3900 /* compute IV */
3901 if ((newivm->iv = oakley_hash(buf, iph1)) == NULL)
3902 goto end;
3903
3904 /* adjust length of iv */
3905 newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype);
3906 if (newivm->iv->l == -1) {
3907 plog(LLV_ERROR, LOCATION, NULL,
3908 "invalid encryption algoriym %d.\n",
3909 iph1->approval->enctype);
3910 goto end;
3911 }
3912
3913 /* create buffer to save new iv */
3914 if ((newivm->ive = vdup(newivm->iv)) == NULL) {
3915 plog(LLV_ERROR, LOCATION, NULL, "vdup (%s)\n", strerror(errno));
3916 goto end;
3917 }
3918
3919 error = 0;
3920
3921 plog(LLV_DEBUG, LOCATION, NULL, "phase2 IV computed:\n");
3922 plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l);
3923
3924 end:
3925 if (error && newivm != NULL){
3926 oakley_delivm(newivm);
3927 newivm=NULL;
3928 }
3929 if (buf != NULL)
3930 vfree(buf);
3931 return newivm;
3932 }
3933
3934 void
3935 oakley_delivm(ivm)
3936 struct isakmp_ivm *ivm;
3937 {
3938 if (ivm == NULL)
3939 return;
3940
3941 if (ivm->iv != NULL)
3942 vfree(ivm->iv);
3943 if (ivm->ive != NULL)
3944 vfree(ivm->ive);
3945 racoon_free(ivm);
3946 plog(LLV_DEBUG, LOCATION, NULL, "IV freed\n");
3947
3948 return;
3949 }
3950
3951 /*
3952 * decrypt packet.
3953 * save new iv and old iv.
3954 */
3955 vchar_t *
3956 oakley_do_decrypt(iph1, msg, ivdp, ivep)
3957 struct ph1handle *iph1;
3958 vchar_t *msg, *ivdp, *ivep;
3959 {
3960 vchar_t *buf = NULL, *new = NULL;
3961 char *pl;
3962 int len;
3963 u_int8_t padlen;
3964 int blen;
3965 int error = -1;
3966
3967 plog(LLV_DEBUG, LOCATION, NULL, "begin decryption.\n");
3968
3969 blen = alg_oakley_encdef_blocklen(iph1->approval->enctype);
3970 if (blen == -1) {
3971 plog(LLV_ERROR, LOCATION, NULL,
3972 "invalid encryption algoriym %d.\n",
3973 iph1->approval->enctype);
3974 goto end;
3975 }
3976
3977 /* save IV for next, but not sync. */
3978 memset(ivep->v, 0, ivep->l);
3979 memcpy(ivep->v, (caddr_t)&msg->v[msg->l - blen], blen);
3980
3981 plog(LLV_DEBUG, LOCATION, NULL,
3982 "IV was saved for next processing:\n");
3983 plogdump(LLV_DEBUG, ivep->v, ivep->l);
3984
3985 pl = msg->v + sizeof(struct isakmp);
3986
3987 len = msg->l - sizeof(struct isakmp);
3988
3989 /* create buffer */
3990 buf = vmalloc(len);
3991 if (buf == NULL) {
3992 plog(LLV_ERROR, LOCATION, NULL,
3993 "failed to get buffer to decrypt.\n");
3994 goto end;
3995 }
3996 memcpy(buf->v, pl, len);
3997
3998 /* do decrypt */
3999 new = alg_oakley_encdef_decrypt(iph1->approval->enctype,
4000 buf, iph1->key, ivdp);
4001 if (new == NULL || new->v == NULL || new->l == 0) {
4002 plog(LLV_ERROR, LOCATION, NULL,
4003 "decryption %d failed.\n", iph1->approval->enctype);
4004 goto end;
4005 }
4006 plog(LLV_DEBUG, LOCATION, NULL, "with key:\n");
4007 plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
4008
4009 vfree(buf);
4010 buf = NULL;
4011 if (new == NULL)
4012 goto end;
4013
4014 plog(LLV_DEBUG, LOCATION, NULL, "decrypted payload by IV:\n");
4015 plogdump(LLV_DEBUG, ivdp->v, ivdp->l);
4016
4017 plog(LLV_DEBUG, LOCATION, NULL,
4018 "decrypted payload, but not trimed.\n");
4019 plogdump(LLV_DEBUG, new->v, new->l);
4020
4021 /* get padding length */
4022 if (lcconf->pad_excltail)
4023 padlen = new->v[new->l - 1] + 1;
4024 else
4025 padlen = new->v[new->l - 1];
4026 plog(LLV_DEBUG, LOCATION, NULL, "padding len=%u\n", padlen);
4027
4028 /* trim padding */
4029 if (lcconf->pad_strict) {
4030 if (padlen > new->l) {
4031 plog(LLV_ERROR, LOCATION, NULL,
4032 "invalid padding len=%u, buflen=%zu.\n",
4033 padlen, new->l);
4034 plogdump(LLV_ERROR, new->v, new->l);
4035 goto end;
4036 }
4037 new->l -= padlen;
4038 plog(LLV_DEBUG, LOCATION, NULL, "trimmed padding\n");
4039 } else {
4040 plog(LLV_DEBUG, LOCATION, NULL, "skip to trim padding.\n");
4041 }
4042
4043 /* create new buffer */
4044 len = sizeof(struct isakmp) + new->l;
4045 buf = vmalloc(len);
4046 if (buf == NULL) {
4047 plog(LLV_ERROR, LOCATION, NULL,
4048 "failed to get buffer to decrypt.\n");
4049 goto end;
4050 }
4051 memcpy(buf->v, msg->v, sizeof(struct isakmp));
4052 memcpy(buf->v + sizeof(struct isakmp), new->v, new->l);
4053 ((struct isakmp *)buf->v)->len = htonl(buf->l);
4054
4055 plog(LLV_DEBUG, LOCATION, NULL, "decrypted.\n");
4056 plogdump(LLV_DEBUG, buf->v, buf->l);
4057
4058 #ifdef HAVE_PRINT_ISAKMP_C
4059 isakmp_printpacket(buf, iph1->remote, iph1->local, 1);
4060 #endif
4061
4062 error = 0;
4063
4064 end:
4065 if (error && buf != NULL) {
4066 vfree(buf);
4067 buf = NULL;
4068 }
4069 if (new != NULL)
4070 vfree(new);
4071
4072 return buf;
4073 }
4074
4075 /*
4076 * encrypt packet.
4077 */
4078 vchar_t *
4079 oakley_do_encrypt(iph1, msg, ivep, ivp)
4080 struct ph1handle *iph1;
4081 vchar_t *msg, *ivep, *ivp;
4082 {
4083 vchar_t *buf = 0, *new = 0;
4084 char *pl;
4085 int len;
4086 u_int padlen;
4087 int blen;
4088 int error = -1;
4089
4090 plog(LLV_DEBUG, LOCATION, NULL, "begin encryption.\n");
4091
4092 /* set cbc block length */
4093 blen = alg_oakley_encdef_blocklen(iph1->approval->enctype);
4094 if (blen == -1) {
4095 plog(LLV_ERROR, LOCATION, NULL,
4096 "invalid encryption algoriym %d.\n",
4097 iph1->approval->enctype);
4098 goto end;
4099 }
4100
4101 pl = msg->v + sizeof(struct isakmp);
4102 len = msg->l - sizeof(struct isakmp);
4103
4104 /* add padding */
4105 padlen = oakley_padlen(len, blen);
4106 plog(LLV_DEBUG, LOCATION, NULL, "pad length = %u\n", padlen);
4107
4108 /* create buffer */
4109 buf = vmalloc(len + padlen);
4110 if (buf == NULL) {
4111 plog(LLV_ERROR, LOCATION, NULL,
4112 "failed to get buffer to encrypt.\n");
4113 goto end;
4114 }
4115 if (padlen) {
4116 int i;
4117 char *p = &buf->v[len];
4118 if (lcconf->pad_random) {
4119 for (i = 0; i < padlen; i++)
4120 *p++ = eay_random() & 0xff;
4121 }
4122 }
4123 memcpy(buf->v, pl, len);
4124
4125 /* make pad into tail */
4126 if (lcconf->pad_excltail)
4127 buf->v[len + padlen - 1] = padlen - 1;
4128 else
4129 buf->v[len + padlen - 1] = padlen;
4130
4131 plogdump(LLV_DEBUG, buf->v, buf->l);
4132
4133 /* do encrypt */
4134 new = alg_oakley_encdef_encrypt(iph1->approval->enctype,
4135 buf, iph1->key, ivep);
4136 if (new == NULL) {
4137 plog(LLV_ERROR, LOCATION, NULL,
4138 "encryption %d failed.\n", iph1->approval->enctype);
4139 goto end;
4140 }
4141 plog(LLV_DEBUG, LOCATION, NULL, "with key:\n");
4142 plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
4143
4144 vfree(buf);
4145 buf = NULL;
4146 if (new == NULL)
4147 goto end;
4148
4149 plog(LLV_DEBUG, LOCATION, NULL, "encrypted payload by IV:\n");
4150 plogdump(LLV_DEBUG, ivep->v, ivep->l);
4151
4152 /* save IV for next */
4153 memset(ivp->v, 0, ivp->l);
4154 memcpy(ivp->v, (caddr_t)&new->v[new->l - blen], blen);
4155
4156 plog(LLV_DEBUG, LOCATION, NULL, "save IV for next:\n");
4157 plogdump(LLV_DEBUG, ivp->v, ivp->l);
4158
4159 /* create new buffer */
4160 len = sizeof(struct isakmp) + new->l;
4161 buf = vmalloc(len);
4162 if (buf == NULL) {
4163 plog(LLV_ERROR, LOCATION, NULL,
4164 "failed to get buffer to encrypt.\n");
4165 goto end;
4166 }
4167 memcpy(buf->v, msg->v, sizeof(struct isakmp));
4168 memcpy(buf->v + sizeof(struct isakmp), new->v, new->l);
4169 ((struct isakmp *)buf->v)->len = htonl(buf->l);
4170
4171 error = 0;
4172
4173 plog(LLV_DEBUG, LOCATION, NULL, "encrypted.\n");
4174
4175 end:
4176 if (error && buf != NULL) {
4177 vfree(buf);
4178 buf = NULL;
4179 }
4180 if (new != NULL)
4181 vfree(new);
4182
4183 return buf;
4184 }
4185
4186 /* culculate padding length */
4187 static int
4188 oakley_padlen(len, base)
4189 int len, base;
4190 {
4191 int padlen;
4192
4193 padlen = base - len % base;
4194
4195 if (lcconf->pad_randomlen)
4196 padlen += ((eay_random() % (lcconf->pad_maxsize + 1) + 1) *
4197 base);
4198
4199 return padlen;
4200 }
4201
4202 /* -----------------------------------------------------------------------------
4203 The base-64 encoding packs three 8-bit bytes into four 7-bit ASCII
4204 characters. If the number of bytes in the original data isn't divisable
4205 by three, "=" characters are used to pad the encoded data. The complete
4206 set of characters used in base-64 are:
4207 'A'..'Z' => 00..25
4208 'a'..'z' => 26..51
4209 '0'..'9' => 52..61
4210 '+' => 62
4211 '/' => 63
4212 '=' => pad
4213
4214 ----------------------------------------------------------------------------- */
4215 static const signed char base64_DecodeTable[128] = {
4216 /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
4217 /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
4218 /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
4219 /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
4220 /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
4221 /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
4222 /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
4223 /* '8' */ 60, 61, -1, -1, -1, 0, -1, -1,
4224 /* '@' */ -1, 0, 1, 2, 3, 4, 5, 6,
4225 /* 'H' */ 7, 8, 9, 10, 11, 12, 13, 14,
4226 /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
4227 /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
4228 /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
4229 /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
4230 /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
4231 /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
4232 };
4233
4234 static int base64toCFData(vchar_t *textin, CFDataRef *dataRef)
4235 {
4236 uint8_t *tmpbuf;
4237 uint8_t c;
4238 int tmpbufpos = 0;
4239 int numeq = 0;
4240 int acc = 0;
4241 int cntr = 0;
4242 uint8_t *textcur = textin->v;
4243 int len = textin->l;
4244 int i;
4245
4246 tmpbuf = malloc(len); // len of result will be less than encoded len
4247 if (tmpbuf == NULL) {
4248 yyerror("memory error - could not allocate buffer for certificate reference conversion from base-64.");
4249 return -1;
4250 }
4251
4252 for (i = 0; i < len; i++) {
4253 c = *(textcur++);
4254 if (c == '=')
4255 numeq++;
4256 else if (!isspace(c))
4257 numeq = 0;
4258 if (base64_DecodeTable[c] < 0)
4259 continue;
4260 cntr++;
4261 acc <<= 6;
4262 acc += base64_DecodeTable[c];
4263 if (0 == (cntr & 0x3)) {
4264 tmpbuf[tmpbufpos++] = (acc >> 16) & 0xff;
4265 if (numeq < 2)
4266 tmpbuf[tmpbufpos++] = (acc >> 8) & 0xff;
4267 if (numeq < 1)
4268 tmpbuf[tmpbufpos++] = acc & 0xff;
4269 }
4270 }
4271 *dataRef = CFDataCreate(NULL, tmpbuf, tmpbufpos);
4272 free(tmpbuf);
4273 if (*dataRef)
4274 return 0;
4275 else
4276 return -1;
4277
4278 }
4279