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