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