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