1 /* $NetBSD: oakley.c,v 1.9.6.2 2007/04/04 13:08:28 vanhu Exp $ */
3 /* Id: oakley.c,v 1.32 2006/05/26 12:19:46 manubsd Exp */
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
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 */
42 #include <openssl/pkcs7.h>
43 #include <openssl/x509.h>
50 #include <arpa/inet.h>
51 #include <TargetConditionals.h>
53 #if TIME_WITH_SYS_TIME
54 # include <sys/time.h>
58 # include <sys/time.h>
74 #include "isakmp_var.h"
77 #include "isakmp_xauth.h"
78 #include "isakmp_cfg.h"
81 #include "localconf.h"
84 #include "ipsec_doi.h"
85 #include "algorithm.h"
89 #include "crypto_openssl.h"
90 #include "crypto_cssm.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>
105 #include "vpn_control_var.h"
106 #include "ikev2_rfc.h"
109 #define OUTBOUND_SA 0
112 #define CERT_CHECKID_FROM_PEER 0
113 #define CERT_CHECKID_FROM_RMCONFIG 1
116 #define INITDHVAL(a, s, d, t) \
119 buf.v = str2val((s), 16, &buf.l); \
120 memset(&a, 0, sizeof(struct dhgroup)); \
122 a.prime = vdup(&buf); \
125 racoon_free(buf.v); \
127 #else /* HAVE_OPENSSL */
128 #define INITDHVAL(a, s, d, t) \
131 buf.v = str2val((s), 16, &buf.l); \
132 memset(&a, 0, sizeof(struct dhgroup)); \
135 a.prime = vdup(&buf); \
138 racoon_free(buf.v); \
140 #endif /* HAVE_OPENSSL */
142 struct dhgroup dh_modp768
;
143 struct dhgroup dh_modp1024
;
144 struct dhgroup dh_modp1536
;
145 struct dhgroup dh_modp2048
;
146 struct dhgroup dh_modp3072
;
147 struct dhgroup dh_modp4096
;
148 struct dhgroup dh_modp6144
;
149 struct dhgroup dh_modp8192
;
152 static int oakley_check_dh_pub (vchar_t
*, vchar_t
**);
153 static int oakley_compute_keymat_x (phase2_handle_t
*, int, int);
154 static int oakley_compute_ikev2_keymat_x (phase2_handle_t
*);
155 static int get_cert_fromlocal (phase1_handle_t
*, int);
156 static int oakley_check_certid (phase1_handle_t
*iph1
);
157 static int oakley_check_certid_1 (vchar_t
*, int, int, void*, cert_status_t
*certStatus
);
158 static vchar_t
* oakley_prf_plus (vchar_t
*, vchar_t
*, int, phase1_handle_t
*iph1
);
160 static int check_typeofcertname (int, int);
162 static cert_t
*save_certbuf (struct isakmp_gen
*);
163 static int oakley_padlen (int, int);
165 static int base64toCFData (vchar_t
*, CFDataRef
*);
166 static cert_t
*oakley_appendcert_to_certchain (cert_t
*, cert_t
*);
169 oakley_get_defaultlifetime()
171 return OAKLEY_ATTR_SA_LD_SEC_DEFAULT
;
178 INITDHVAL(dh_modp768
, OAKLEY_PRIME_MODP768
,
179 OAKLEY_ATTR_GRP_DESC_MODP768
, OAKLEY_ATTR_GRP_TYPE_MODP
);
180 INITDHVAL(dh_modp1024
, OAKLEY_PRIME_MODP1024
,
181 OAKLEY_ATTR_GRP_DESC_MODP1024
, OAKLEY_ATTR_GRP_TYPE_MODP
);
182 INITDHVAL(dh_modp1536
, OAKLEY_PRIME_MODP1536
,
183 OAKLEY_ATTR_GRP_DESC_MODP1536
, OAKLEY_ATTR_GRP_TYPE_MODP
);
184 INITDHVAL(dh_modp2048
, OAKLEY_PRIME_MODP2048
,
185 OAKLEY_ATTR_GRP_DESC_MODP2048
, OAKLEY_ATTR_GRP_TYPE_MODP
);
186 INITDHVAL(dh_modp3072
, OAKLEY_PRIME_MODP3072
,
187 OAKLEY_ATTR_GRP_DESC_MODP3072
, OAKLEY_ATTR_GRP_TYPE_MODP
);
188 INITDHVAL(dh_modp4096
, OAKLEY_PRIME_MODP4096
,
189 OAKLEY_ATTR_GRP_DESC_MODP4096
, OAKLEY_ATTR_GRP_TYPE_MODP
);
190 INITDHVAL(dh_modp6144
, OAKLEY_PRIME_MODP6144
,
191 OAKLEY_ATTR_GRP_DESC_MODP6144
, OAKLEY_ATTR_GRP_TYPE_MODP
);
192 INITDHVAL(dh_modp8192
, OAKLEY_PRIME_MODP8192
,
193 OAKLEY_ATTR_GRP_DESC_MODP8192
, OAKLEY_ATTR_GRP_TYPE_MODP
);
199 oakley_dhgrp_free(struct dhgroup
*dhgrp
)
201 VPTRINIT(dhgrp
->prime
);
202 VPTRINIT(dhgrp
->curve_a
);
203 VPTRINIT(dhgrp
->curve_b
);
204 VPTRINIT(dhgrp
->order
);
210 * The length of the Diffie-Hellman public value MUST be equal to the
211 * length of the prime modulus over which the exponentiation was
212 * performed, prepending zero bits to the value if necessary.
215 oakley_check_dh_pub(vchar_t
*prime
, vchar_t
**pub0
)
218 vchar_t
*pub
= *pub0
;
220 if (prime
->l
== pub
->l
)
223 if (prime
->l
< pub
->l
) {
224 /* what should i do ? */
226 "invalid public information was generated.\n");
230 /* prime->l > pub->l */
231 tmp
= vmalloc(prime
->l
);
234 "failed to get DH buffer.\n");
237 memcpy(tmp
->v
+ prime
->l
- pub
->l
, pub
->v
, pub
->l
);
246 * compute sharing secret of DH
247 * IN: *dh, *pub, *priv, *pub_p
252 oakley_dh_compute(const struct dhgroup
*dh
, vchar_t
*pub
, vchar_t
*priv
, vchar_t
*pub_p
, vchar_t
**gxy
)
255 struct timeval start
, end
;
257 if ((*gxy
= vmalloc(dh
->prime
->l
)) == NULL
) {
259 "failed to get DH buffer.\n");
264 gettimeofday(&start
, NULL
);
267 case OAKLEY_ATTR_GRP_TYPE_MODP
:
268 if (eay_dh_compute(dh
->prime
, dh
->gen1
, pub
, priv
, pub_p
, gxy
) < 0) {
270 "failed to compute dh value.\n");
274 case OAKLEY_ATTR_GRP_TYPE_ECP
:
275 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
277 "dh type %d isn't supported.\n", dh
->type
);
281 "invalid dh type %d.\n", dh
->type
);
286 gettimeofday(&end
, NULL
);
287 plog(ASL_LEVEL_NOTICE
, "%s(%s%d): %8.6f", __func__
,
288 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
289 timedelta(&start
, &end
));
292 plog(ASL_LEVEL_DEBUG
, "compute DH's shared.\n");
298 oakley_dh_compute(const struct dhgroup
*dh
, vchar_t
*pub_p
, size_t publicKeySize
, vchar_t
**gxy
, SecDHContext
*dhC
)
301 vchar_t
*computed_key
= NULL
;
302 size_t computed_keylen
;
306 struct timeval start
, end
;
307 gettimeofday(&start
, NULL
);
310 plog(ASL_LEVEL_DEBUG
, "compute DH result.\n");
312 maxKeyLen
= SecDHGetMaxKeyLength(*dhC
);
313 computed_key
= vmalloc(maxKeyLen
);
314 if (computed_key
== NULL
) {
315 plog(ASL_LEVEL_ERR
, "memory error.\n");
318 computed_keylen
= computed_key
->l
;
319 if (SecDHComputeKey(*dhC
, (uint8_t*)pub_p
->v
+ (maxKeyLen
- publicKeySize
), publicKeySize
,
320 (uint8_t*)computed_key
->v
, &computed_keylen
)) {
321 plog(ASL_LEVEL_ERR
, "failed to compute dh value.\n");
326 gettimeofday(&end
, NULL
);
327 plog(ASL_LEVEL_NOTICE
, "%s(%s%d): %8.6f", __func__
,
328 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
329 timedelta(&start
, &end
));
332 *gxy
= vmalloc(maxKeyLen
);
334 plog(ASL_LEVEL_ERR
, "memory error.\n");
337 memcpy((*gxy
)->v
+ (maxKeyLen
- computed_keylen
), computed_key
->v
, computed_keylen
);
338 plog(ASL_LEVEL_DEBUG
, "compute DH's shared.\n");
359 * generate values of DH
365 oakley_dh_generate(const struct dhgroup
*dh
, vchar_t
**pub
, vchar_t
**priv
)
368 struct timeval start
, end
;
369 gettimeofday(&start
, NULL
);
372 case OAKLEY_ATTR_GRP_TYPE_MODP
:
373 if (eay_dh_generate(dh
->prime
, dh
->gen1
, dh
->gen2
, pub
, priv
) < 0) {
375 "failed to compute dh value.\n");
380 case OAKLEY_ATTR_GRP_TYPE_ECP
:
381 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
383 "dh type %d isn't supported.\n", dh
->type
);
387 "invalid dh type %d.\n", dh
->type
);
392 gettimeofday(&end
, NULL
);
393 plog(ASL_LEVEL_NOTICE
, "%s(%s%d): %8.6f", __func__
,
394 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
395 timedelta(&start
, &end
));
398 if (oakley_check_dh_pub(dh
->prime
, pub
) != 0)
401 plog(ASL_LEVEL_DEBUG
, "compute DH's private.\n");
402 plog(ASL_LEVEL_DEBUG
, "compute DH's public.\n");
408 oakley_dh_generate(const struct dhgroup
*dh
, vchar_t
**pub
, size_t *publicKeySize
, SecDHContext
*dhC
)
410 vchar_t
*public = NULL
;
414 struct timeval start
, end
;
415 gettimeofday(&start
, NULL
);
418 plog(ASL_LEVEL_DEBUG
, "generate DH key pair.\n");
421 case OAKLEY_ATTR_GRP_TYPE_MODP
:
422 #define SECDH_MODP_GENERATOR 2
423 if (SecDHCreate(SECDH_MODP_GENERATOR
, (uint8_t*)dh
->prime
->v
, dh
->prime
->l
, 0, NULL
, 0, dhC
)) {
424 plog(ASL_LEVEL_ERR
, "failed to create dh context.\n");
427 maxKeyLen
= SecDHGetMaxKeyLength(*dhC
);
428 public = vmalloc(maxKeyLen
);
429 *publicKeySize
= public->l
;
430 if (public == NULL
) {
431 plog(ASL_LEVEL_ERR
, "memory error.\n");
434 if (SecDHGenerateKeypair(*dhC
, (uint8_t*)public->v
, publicKeySize
)) {
435 plog(ASL_LEVEL_ERR
, "failed to generate dh key pair.\n");
438 plog(ASL_LEVEL_DEBUG
, "got DH key pair.\n");
440 *pub
= vmalloc(maxKeyLen
);
442 plog(ASL_LEVEL_ERR
, "memory error.\n");
445 /* copy and fill with leading zeros */
446 memcpy((*pub
)->v
+ (maxKeyLen
- *publicKeySize
), public->v
, *publicKeySize
);
449 case OAKLEY_ATTR_GRP_TYPE_ECP
:
450 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
452 "dh type %d isn't supported.\n", dh
->type
);
456 "invalid dh type %d.\n", dh
->type
);
461 gettimeofday(&end
, NULL
);
462 plog(ASL_LEVEL_NOTICE
, "%s(%s%d): %8.6f", __func__
,
463 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
464 timedelta(&start
, &end
));
467 if (oakley_check_dh_pub(dh
->prime
, pub
) != 0) {
468 plog(ASL_LEVEL_DEBUG
, "failed DH public key size check.\n");
472 //plogdump(ASL_LEVEL_DEBUG, (*pub)->v, (*pub)->l, "compute DH's public.\n");
490 * copy pre-defined dhgroup values.
493 oakley_setdhgroup(int group
, struct dhgroup
**dhgrp
)
497 *dhgrp
= NULL
; /* just make sure, initialize */
499 g
= alg_oakley_dhdef_group(group
);
502 "invalid DH parameter grp=%d.\n", group
);
506 if (!g
->type
|| !g
->prime
|| !g
->gen1
) {
509 "unsupported DH parameters grp=%d.\n", group
);
513 *dhgrp
= racoon_calloc(1, sizeof(struct dhgroup
));
514 if (*dhgrp
== NULL
) {
516 "failed to get DH buffer.\n");
520 /* set defined dh vlaues */
521 memcpy(*dhgrp
, g
, sizeof(*g
));
522 (*dhgrp
)->prime
= vdup(g
->prime
);
530 * NOTE: we do not support prf with different input/output bitwidth,
531 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example) in
532 * oakley_compute_keymat(). If you add support for such prf function,
533 * modify oakley_compute_keymat() accordingly.
536 oakley_prf(vchar_t
*key
, vchar_t
*buf
, phase1_handle_t
*iph1
)
541 if (iph1
->approval
== NULL
) {
542 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
544 * it's before negotiating hash algorithm.
545 * We use md5 as default.
547 type
= OAKLEY_ATTR_HASH_ALG_MD5
;
549 type
= OAKLEY_ATTR_HASH_ALG_SHA
;
553 type
= iph1
->approval
->hashtype
;
555 res
= alg_oakley_hmacdef_one(type
, key
, buf
);
558 "invalid hmac algorithm %d.\n", type
);
569 oakley_hash(vchar_t
*buf
, phase1_handle_t
*iph1
)
574 if (iph1
->approval
== NULL
) {
575 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
577 * it's before negotiating hash algorithm.
578 * We use md5 as default.
580 type
= OAKLEY_ATTR_HASH_ALG_MD5
;
582 type
= OAKLEY_ATTR_HASH_ALG_SHA
;
585 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
586 type
= iph1
->approval
->hashtype
;
588 type
= OAKLEY_ATTR_HASH_ALG_SHA
;
592 res
= alg_oakley_hashdef_one(type
, buf
);
595 "invalid hash algorithm %d.\n", type
);
604 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
607 oakley_compute_keymat(phase2_handle_t
*iph2
, int side
)
611 /* compute sharing secret of DH when PFS */
612 if (iph2
->approval
->pfs_group
&& iph2
->dhpub_p
) {
614 if (oakley_dh_compute(iph2
->pfsgrp
, iph2
->dhpub
,
615 iph2
->dhpriv
, iph2
->dhpub_p
, &iph2
->dhgxy
) < 0)
617 if (oakley_dh_compute(iph2
->pfsgrp
, iph2
->dhpub_p
, iph2
->publicKeySize
, &iph2
->dhgxy
, &iph2
->dhC
) < 0)
623 if (oakley_compute_keymat_x(iph2
, side
, INBOUND_SA
) < 0
624 || oakley_compute_keymat_x(iph2
, side
, OUTBOUND_SA
) < 0)
627 plog(ASL_LEVEL_DEBUG
, "KEYMAT computed.\n");
638 * KEYMAT = prf(SKEYID_d, protocol | SPI | Ni_b | Nr_b).
639 * If PFS is desired and KE payloads were exchanged,
640 * KEYMAT = prf(SKEYID_d, g(qm)^xy | protocol | SPI | Ni_b | Nr_b)
642 * NOTE: we do not support prf with different input/output bitwidth,
643 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example).
646 oakley_compute_keymat_x(phase2_handle_t
*iph2
, int side
, int sa_dir
)
648 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
653 int dupkeymat
; /* generate K[1-dupkeymat] */
656 int encklen
, authklen
, l
;
658 pfs
= ((iph2
->approval
->pfs_group
&& iph2
->dhgxy
) ? 1 : 0);
660 len
= pfs
? iph2
->dhgxy
->l
: 0;
662 + sizeof(u_int32_t
) /* XXX SPI size */
668 "failed to get keymat buffer.\n");
672 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
677 memcpy(p
, iph2
->dhgxy
->v
, iph2
->dhgxy
->l
);
684 memcpy(p
, (sa_dir
== INBOUND_SA
? &pr
->spi
: &pr
->spi_p
),
686 p
+= sizeof(pr
->spi
);
688 bp
= (side
== INITIATOR
? iph2
->nonce
: iph2
->nonce_p
);
689 memcpy(p
, bp
->v
, bp
->l
);
692 bp
= (side
== INITIATOR
? iph2
->nonce_p
: iph2
->nonce
);
693 memcpy(p
, bp
->v
, bp
->l
);
697 //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "KEYMAT compute with\n");
700 res
= oakley_prf(iph2
->ph1
->skeyid_d
, buf
, iph2
->ph1
);
704 /* compute key length needed */
705 encklen
= authklen
= 0;
706 switch (pr
->proto_id
) {
707 case IPSECDOI_PROTO_IPSEC_ESP
:
708 for (tr
= pr
->head
; tr
; tr
= tr
->next
) {
709 l
= alg_ipsec_encdef_keylen(tr
->trns_id
,
714 l
= alg_ipsec_hmacdef_hashlen(tr
->authtype
);
719 case IPSECDOI_PROTO_IPSEC_AH
:
720 for (tr
= pr
->head
; tr
; tr
= tr
->next
) {
721 l
= alg_ipsec_hmacdef_hashlen(tr
->trns_id
);
729 plog(ASL_LEVEL_DEBUG
, "encklen=%d authklen=%d\n",
732 dupkeymat
= (encklen
+ authklen
) / 8 / res
->l
;
733 dupkeymat
+= 2; /* safety mergin */
736 //plog(ASL_LEVEL_DEBUG,
737 // "generating %zu bits of key (dupkeymat=%d)\n",
738 // dupkeymat * 8 * res->l, dupkeymat);
739 if (0 < --dupkeymat
) {
740 vchar_t
*prev
= res
; /* K(n-1) */
741 vchar_t
*seed
= NULL
; /* seed for Kn */
745 * generating long key (isakmp-oakley-08 5.5)
746 * KEYMAT = K1 | K2 | K3 | ...
748 * src = [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b
749 * K1 = prf(SKEYID_d, src)
750 * K2 = prf(SKEYID_d, K1 | src)
751 * K3 = prf(SKEYID_d, K2 | src)
752 * Kn = prf(SKEYID_d, K(n-1) | src)
754 //plog(ASL_LEVEL_DEBUG,
755 // "generating K1...K%d for KEYMAT.\n",
758 seed
= vmalloc(prev
->l
+ buf
->l
);
761 "failed to get keymat buffer.\n");
762 if (prev
&& prev
!= res
)
767 while (dupkeymat
--) {
768 vchar_t
*this = NULL
; /* Kn */
771 memcpy(seed
->v
, prev
->v
, prev
->l
);
772 memcpy(seed
->v
+ prev
->l
, buf
->v
, buf
->l
);
773 this = oakley_prf(iph2
->ph1
->skeyid_d
, seed
,
777 "oakley_prf memory overflow\n");
778 if (prev
&& prev
!= res
)
785 update_prev
= (prev
&& prev
== res
) ? 1 : 0;
788 res
= vrealloc(res
, l
+ this->l
);
795 "failed to get keymat buffer.\n");
796 if (prev
&& prev
!= res
)
802 memcpy(res
->v
+ l
, this->v
, this->l
);
804 if (prev
&& prev
!= res
)
810 if (prev
&& prev
!= res
)
815 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "");
817 if (sa_dir
== INBOUND_SA
)
828 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
850 * compute HASH(3) prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
851 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
854 oakley_compute_hash3(phase1_handle_t
*iph1
, u_int32_t msgid
, vchar_t
*body
)
856 vchar_t
*buf
= 0, *res
= 0;
861 len
= 1 + sizeof(u_int32_t
) + body
->l
;
864 plog(ASL_LEVEL_DEBUG
,
865 "failed to get hash buffer\n");
871 memcpy(buf
->v
+ 1, (char *)&msgid
, sizeof(msgid
));
873 memcpy(buf
->v
+ 1 + sizeof(u_int32_t
), body
->v
, body
->l
);
876 res
= oakley_prf(iph1
->skeyid_a
, buf
, iph1
);
882 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH computed:\n");
891 * compute HASH type of prf(SKEYID_a, M-ID | buffer)
893 * for quick mode HASH(1):
894 * prf(SKEYID_a, M-ID | SA | Ni [ | KE ] [ | IDci | IDcr ])
895 * for quick mode HASH(2):
896 * prf(SKEYID_a, M-ID | Ni_b | SA | Nr [ | KE ] [ | IDci | IDcr ])
897 * for Informational exchange:
898 * prf(SKEYID_a, M-ID | N/D)
901 oakley_compute_hash1(phase1_handle_t
*iph1
, u_int32_t msgid
, vchar_t
*body
)
903 vchar_t
*buf
= NULL
, *res
= NULL
;
909 len
= sizeof(u_int32_t
) + body
->l
;
912 plog(ASL_LEVEL_DEBUG
,
913 "failed to get hash buffer\n");
919 memcpy(buf
->v
, (char *)&msgid
, sizeof(msgid
));
920 p
+= sizeof(u_int32_t
);
922 memcpy(p
, body
->v
, body
->l
);
925 res
= oakley_prf(iph1
->skeyid_a
, buf
, iph1
);
931 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH computed:\n");
940 * compute phase1 HASH
942 * I-digest = prf(SKEYID, g^i | g^r | CKY-I | CKY-R | SAi_b | ID_i1_b)
943 * R-digest = prf(SKEYID, g^r | g^i | CKY-R | CKY-I | SAi_b | ID_r1_b)
944 * for gssapi, also include all GSS tokens, and call gss_wrap on the result
947 oakley_ph1hash_common(phase1_handle_t
*iph1
, int sw
)
949 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
957 + sizeof(cookie_t
) * 2
959 + (sw
== GENERATE
? iph1
->id
->l
: iph1
->id_p
->l
);
964 "failed to get hash buffer\n");
970 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
971 memcpy(p
, bp
->v
, bp
->l
);
974 bp
= (sw
== GENERATE
? iph1
->dhpub_p
: iph1
->dhpub
);
975 memcpy(p
, bp
->v
, bp
->l
);
978 if (iph1
->side
== INITIATOR
)
979 bp2
= (sw
== GENERATE
?
980 (char *)&iph1
->index
.i_ck
: (char *)&iph1
->index
.r_ck
);
982 bp2
= (sw
== GENERATE
?
983 (char *)&iph1
->index
.r_ck
: (char *)&iph1
->index
.i_ck
);
984 bl
= sizeof(cookie_t
);
988 if (iph1
->side
== INITIATOR
)
989 bp2
= (sw
== GENERATE
?
990 (char *)&iph1
->index
.r_ck
: (char *)&iph1
->index
.i_ck
);
992 bp2
= (sw
== GENERATE
?
993 (char *)&iph1
->index
.i_ck
: (char *)&iph1
->index
.r_ck
);
994 bl
= sizeof(cookie_t
);
999 memcpy(p
, bp
->v
, bp
->l
);
1002 bp
= (sw
== GENERATE
? iph1
->id
: iph1
->id_p
);
1003 memcpy(p
, bp
->v
, bp
->l
);
1007 res
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
1020 * compute HASH_I on base mode.
1022 * HASH_I = prf(SKEYID, g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
1024 * HASH_I = prf(hash(Ni_b | Nr_b), g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
1027 oakley_ph1hash_base_i(phase1_handle_t
*iph1
, int sw
)
1029 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
1030 vchar_t
*hashkey
= NULL
;
1031 vchar_t
*hash
= NULL
; /* for signature mode */
1037 if (iph1
->etype
!= ISAKMP_ETYPE_BASE
) {
1039 "invalid etype for this hash function\n");
1043 switch (AUTHMETHOD(iph1
)) {
1044 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
1045 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
1046 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
1047 #ifdef ENABLE_HYBRID
1048 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
1049 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
1050 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
1051 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
1052 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
1053 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
1055 if (iph1
->skeyid
== NULL
) {
1056 plog(ASL_LEVEL_ERR
, "no SKEYID found.\n");
1059 hashkey
= iph1
->skeyid
;
1062 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1063 #ifdef ENABLE_HYBRID
1064 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1065 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1066 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
1067 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1069 /* make hash for seed */
1070 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
1074 "failed to get hash buffer\n");
1079 bp
= (sw
== GENERATE
? iph1
->nonce_p
: iph1
->nonce
);
1080 memcpy(p
, bp
->v
, bp
->l
);
1083 bp
= (sw
== GENERATE
? iph1
->nonce
: iph1
->nonce_p
);
1084 memcpy(p
, bp
->v
, bp
->l
);
1087 hash
= oakley_hash(buf
, iph1
);
1098 "not supported authentication method %d\n",
1099 iph1
->approval
->authmethod
);
1104 len
= (sw
== GENERATE
? iph1
->dhpub
->l
: iph1
->dhpub_p
->l
)
1105 + sizeof(cookie_t
) * 2
1107 + (sw
== GENERATE
? iph1
->id
->l
: iph1
->id_p
->l
);
1111 "failed to get hash buffer\n");
1116 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
1117 memcpy(p
, bp
->v
, bp
->l
);
1120 memcpy(p
, &iph1
->index
.i_ck
, sizeof(cookie_t
));
1121 p
+= sizeof(cookie_t
);
1122 memcpy(p
, &iph1
->index
.r_ck
, sizeof(cookie_t
));
1123 p
+= sizeof(cookie_t
);
1125 memcpy(p
, iph1
->sa
->v
, iph1
->sa
->l
);
1128 bp
= (sw
== GENERATE
? iph1
->id
: iph1
->id_p
);
1129 memcpy(p
, bp
->v
, bp
->l
);
1132 //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "HASH_I with:\n");
1135 res
= oakley_prf(hashkey
, buf
, iph1
);
1141 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH_I computed:\n");
1152 * compute HASH_R on base mode for signature method.
1154 * HASH_R = prf(hash(Ni_b | Nr_b), g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b)
1157 oakley_ph1hash_base_r(phase1_handle_t
*iph1
, int sw
)
1159 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
1160 vchar_t
*hash
= NULL
;
1166 if (iph1
->etype
!= ISAKMP_ETYPE_BASE
) {
1168 "invalid etype for this hash function\n");
1172 switch(AUTHMETHOD(iph1
)) {
1173 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1174 #ifdef ENABLE_HYBRID
1175 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1176 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1177 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
1178 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1179 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
1184 "not supported authentication method %d\n",
1185 iph1
->approval
->authmethod
);
1190 /* make hash for seed */
1191 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
1195 "failed to get hash buffer\n");
1200 bp
= (sw
== GENERATE
? iph1
->nonce_p
: iph1
->nonce
);
1201 memcpy(p
, bp
->v
, bp
->l
);
1204 bp
= (sw
== GENERATE
? iph1
->nonce
: iph1
->nonce_p
);
1205 memcpy(p
, bp
->v
, bp
->l
);
1208 hash
= oakley_hash(buf
, iph1
);
1214 /* make really hash */
1215 len
= (sw
== GENERATE
? iph1
->dhpub_p
->l
: iph1
->dhpub
->l
)
1216 + (sw
== GENERATE
? iph1
->dhpub
->l
: iph1
->dhpub_p
->l
)
1217 + sizeof(cookie_t
) * 2
1219 + (sw
== GENERATE
? iph1
->id_p
->l
: iph1
->id
->l
);
1223 "failed to get hash buffer\n");
1229 bp
= (sw
== GENERATE
? iph1
->dhpub_p
: iph1
->dhpub
);
1230 memcpy(p
, bp
->v
, bp
->l
);
1233 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
1234 memcpy(p
, bp
->v
, bp
->l
);
1237 memcpy(p
, &iph1
->index
.i_ck
, sizeof(cookie_t
));
1238 p
+= sizeof(cookie_t
);
1239 memcpy(p
, &iph1
->index
.r_ck
, sizeof(cookie_t
));
1240 p
+= sizeof(cookie_t
);
1242 memcpy(p
, iph1
->sa
->v
, iph1
->sa
->l
);
1245 bp
= (sw
== GENERATE
? iph1
->id_p
: iph1
->id
);
1246 memcpy(p
, bp
->v
, bp
->l
);
1249 //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "HASH_R with:\n");
1252 res
= oakley_prf(hash
, buf
, iph1
);
1258 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH_R computed:\n");
1270 oakley_verify_userid(phase1_handle_t
*iph1
)
1274 int user_id_found
= 0;
1276 for (p
= iph1
->cert_p
; p
; p
= p
->chain
) {
1277 user_id
= eay_get_x509_common_name(&p
->cert
); //%%%%%%%% fix this
1280 // the following functions will check if user_id == 0
1281 if (open_dir_authorize_id(user_id
, iph1
->rmconf
->open_dir_auth_group
)) {
1288 if (user_id_found
) {
1290 "the peer is not authorized for access.\n");
1293 "the peer is not authorized for access - user ID not found.\n");
1295 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1297 #endif /* HAVE_OPENDIR */
1300 * compute each authentication method in phase 1.
1304 * other: error to be reply with notification.
1305 * the value is notification type.
1308 oakley_validate_auth(phase1_handle_t
*iph1
)
1310 vchar_t
*my_hash
= NULL
;
1313 struct timeval start
, end
;
1315 SecKeyRef publicKeyRef
= NULL
;
1318 gettimeofday(&start
, NULL
);
1321 switch (AUTHMETHOD(iph1
)) {
1322 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
1323 #ifdef ENABLE_HYBRID
1324 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
1325 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
1331 if (iph1
->id_p
== NULL
|| iph1
->pl_hash
== NULL
) {
1333 "few isakmp message received.\n");
1334 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1336 #ifdef ENABLE_HYBRID
1337 if (AUTHMETHOD(iph1
) == FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
&&
1338 ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_VENDORID_XAUTH
) == 0))
1340 plog(ASL_LEVEL_ERR
, "No SIG was passed, "
1341 "hybrid auth is enabled, "
1342 "but peer is no Xauth compliant\n");
1343 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED
;
1347 r_hash
= (caddr_t
)(iph1
->pl_hash
+ 1);
1349 //plogdump(ASL_LEVEL_DEBUG, r_hash,
1350 // ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash), "HASH received:\n");
1352 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
1353 switch (iph1
->etype
) {
1354 case ISAKMP_ETYPE_IDENT
:
1355 case ISAKMP_ETYPE_AGG
:
1356 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1358 case ISAKMP_ETYPE_BASE
:
1359 if (iph1
->side
== INITIATOR
)
1360 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1362 my_hash
= oakley_ph1hash_base_i(iph1
, VALIDATE
);
1366 "invalid etype %d\n", iph1
->etype
);
1367 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1370 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1372 if (my_hash
== NULL
)
1373 return ISAKMP_INTERNAL_ERROR
;
1375 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1379 plog(ASL_LEVEL_ERR
, "HASH mismatched\n");
1380 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1383 plog(ASL_LEVEL_DEBUG
, "HASH for PSK validated.\n");
1386 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1387 #ifdef ENABLE_HYBRID
1388 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1389 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
1390 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1397 if (iph1
->id_p
== NULL
) {
1399 "no ID payload was passed.\n");
1400 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1402 if (iph1
->sig_p
== NULL
) {
1404 "no SIG payload was passed.\n");
1405 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1408 plog(ASL_LEVEL_DEBUG
, "*** SIGN passed\n");
1410 /* get peer's cert */
1411 switch (iph1
->rmconf
->getcert_method
) {
1412 case ISAKMP_GETCERT_PAYLOAD
:
1413 if (iph1
->cert_p
== NULL
) {
1415 "no peer's CERT payload found.\n");
1416 return ISAKMP_INTERNAL_ERROR
;
1421 "invalid getcert_mothod: %d\n",
1422 iph1
->rmconf
->getcert_method
);
1423 return ISAKMP_INTERNAL_ERROR
;
1426 /* compare ID payload and certificate name */
1427 if (iph1
->rmconf
->verify_cert
&&
1428 (error
= oakley_check_certid(iph1
)) != 0)
1432 /* check cert common name against Open Directory authentication group */
1433 if (iph1
->rmconf
->cert_verification_option
== VERIFICATION_OPTION_OPEN_DIR
) {
1434 if (oakley_verify_userid(iph1
)) {
1435 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1438 #endif /* HAVE_OPENDIR */
1440 /* verify certificate */
1441 if (iph1
->rmconf
->verify_cert
1442 && iph1
->rmconf
->getcert_method
== ISAKMP_GETCERT_PAYLOAD
) {
1443 certtype
= iph1
->rmconf
->certtype
;
1444 #ifdef ENABLE_HYBRID
1445 switch (AUTHMETHOD(iph1
)) {
1446 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1447 certtype
= iph1
->cert_p
->type
;
1454 case ISAKMP_CERT_X509SIGN
:
1456 /* use ID from remote configuration */
1457 /* check each ID in list */
1458 struct idspec
*id_spec
;
1459 CFStringRef hostname
= NULL
;
1461 struct genlist_entry
*gpb
= NULL
;
1463 if (iph1
->rmconf
->cert_verification_option
== VERIFICATION_OPTION_PEERS_IDENTIFIER
) {
1464 id_spec
= genlist_next(iph1
->rmconf
->idvl_p
, &gpb
); /* expect only one id */
1465 if (id_spec
->idtype
== IDTYPE_ADDRESS
) {
1466 switch ((ALIGNED_CAST(struct sockaddr_storage
*)(id_spec
->id
->v
))->ss_family
) {
1468 peers_id
= inet_ntoa((ALIGNED_CAST(struct sockaddr_in
*)(id_spec
->id
->v
))->sin_addr
);
1469 hostname
= CFStringCreateWithCString(NULL
, peers_id
, kCFStringEncodingUTF8
);
1473 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
; /* not currently supported for embedded */
1478 "unknown address type for peers identifier.\n");
1479 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1483 hostname
= CFStringCreateWithBytes(NULL
, (u_int8_t
*)id_spec
->id
->v
, id_spec
->id
->l
, kCFStringEncodingUTF8
, FALSE
);
1485 error
= crypto_cssm_check_x509cert(oakley_get_peer_cert_from_certchain(iph1
), iph1
->cert_p
, hostname
, &publicKeyRef
);
1487 CFRelease(hostname
);
1493 "no supported certtype %d\n", certtype
);
1494 return ISAKMP_INTERNAL_ERROR
;
1498 "the peer's certificate is not verified.\n");
1499 return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY
;
1503 plog(ASL_LEVEL_DEBUG
, "CERT validated\n");
1505 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
1507 switch (iph1
->etype
) {
1508 case ISAKMP_ETYPE_IDENT
:
1509 case ISAKMP_ETYPE_AGG
:
1510 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1512 case ISAKMP_ETYPE_BASE
:
1513 if (iph1
->side
== INITIATOR
)
1514 my_hash
= oakley_ph1hash_base_r(iph1
, VALIDATE
);
1516 my_hash
= oakley_ph1hash_base_i(iph1
, VALIDATE
);
1520 "invalid etype %d\n", iph1
->etype
);
1521 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1524 vchar_t
*octets
= NULL
;
1525 octets
= ikev2_ike_sa_auth_get_octets(iph1
, (iph1
->side
== INITIATOR
)? FALSE
: TRUE
);
1526 my_hash
= alg_oakley_hashdef_one(OAKLEY_ATTR_HASH_ALG_SHA
, octets
);
1528 if (my_hash
== NULL
)
1529 return ISAKMP_INTERNAL_ERROR
;
1532 certtype
= iph1
->rmconf
->certtype
;
1533 #ifdef ENABLE_HYBRID
1534 switch (AUTHMETHOD(iph1
)) {
1535 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1536 certtype
= iph1
->cert_p
->type
;
1542 /* check signature */
1544 case ISAKMP_CERT_X509SIGN
:
1545 if (publicKeyRef
== NULL
) {
1546 plog(ASL_LEVEL_ERR
, "@@@@@@ publicKeyRef is NULL\n");
1548 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
1549 error
= crypto_cssm_verify_x509sign(publicKeyRef
, my_hash
, iph1
->sig_p
, FALSE
);
1551 error
= crypto_cssm_verify_x509sign(publicKeyRef
, my_hash
, iph1
->sig_p
, TRUE
);
1554 plog(ASL_LEVEL_ERR
, "error verifying signature %s\n", GetSecurityErrorString(error
));
1557 CFRelease(publicKeyRef
);
1561 "no supported certtype %d\n",
1564 return ISAKMP_INTERNAL_ERROR
;
1571 return ISAKMP_NTYPE_INVALID_SIGNATURE
;
1573 plog(ASL_LEVEL_DEBUG
, "SIG authenticated\n");
1576 #ifdef ENABLE_HYBRID
1577 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1579 if ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_VENDORID_XAUTH
) == 0) {
1580 plog(ASL_LEVEL_ERR
, "No SIG was passed, "
1581 "hybrid auth is enabled, "
1582 "but peer is no Xauth compliant\n");
1583 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED
;
1586 plog(ASL_LEVEL_INFO
, "No SIG was passed, "
1587 "but hybrid auth is enabled\n");
1593 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
1594 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
1595 #ifdef ENABLE_HYBRID
1596 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
1597 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
1598 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
1599 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
1601 if (iph1
->id_p
== NULL
|| iph1
->pl_hash
== NULL
) {
1603 "few isakmp message received.\n");
1604 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1607 "not supported authmethod type %s\n",
1608 s_oakley_attr_method(iph1
->approval
->authmethod
));
1609 return ISAKMP_INTERNAL_ERROR
;
1612 "invalid authmethod %d why ?\n",
1613 iph1
->approval
->authmethod
);
1614 return ISAKMP_INTERNAL_ERROR
;
1617 gettimeofday(&end
, NULL
);
1618 plog(ASL_LEVEL_NOTICE
, "%s(%s): %8.6f", __func__
,
1619 s_oakley_attr_method(iph1
->approval
->authmethod
),
1620 timedelta(&start
, &end
));
1627 oakley_find_status_in_certchain (cert_t
*certchain
, cert_status_t certStatus
)
1631 for (p
= certchain
; p
; p
= p
->chain
) {
1632 if (p
->status
== certStatus
) {
1641 oakley_vpncontrol_notify_ike_failed_if_mycert_invalid (phase1_handle_t
*iph1
, int notify_initiator
)
1643 #if TARGET_OS_EMBEDDED
1644 int premature
= oakley_find_status_in_certchain(iph1
->cert
, CERT_STATUS_PREMATURE
);
1645 int expired
= oakley_find_status_in_certchain(iph1
->cert
, CERT_STATUS_EXPIRED
);
1646 if (premature
|| expired
) {
1648 u_int32_t fail_reason
;
1650 if (iph1
->remote
->ss_family
== AF_INET
)
1651 address
= ((struct sockaddr_in
*)(iph1
->remote
))->sin_addr
.s_addr
;
1655 fail_reason
= VPNCTL_NTYPE_LOCAL_CERT_PREMATURE
;
1657 fail_reason
= VPNCTL_NTYPE_LOCAL_CERT_EXPIRED
;
1659 vpncontrol_notify_ike_failed(fail_reason
, notify_initiator
, address
, 0, NULL
);
1662 #endif /* TARGET_OS_EMBEDDED */
1666 /* get my certificate
1667 * NOTE: include certificate type.
1670 oakley_getmycert(phase1_handle_t
*iph1
)
1674 switch (iph1
->rmconf
->certtype
) {
1675 case ISAKMP_CERT_X509SIGN
:
1678 if ( !(err
= get_cert_fromlocal(iph1
, 1))){
1679 if (oakley_vpncontrol_notify_ike_failed_if_mycert_invalid(iph1
, FROM_LOCAL
)) {
1686 "Unknown certtype #%d\n",
1687 iph1
->rmconf
->certtype
);
1694 * get a CERT from local file.
1697 * my == 0 peer's cert.
1700 get_cert_fromlocal(phase1_handle_t
*iph1
, int my
)
1702 vchar_t
*cert
= NULL
;
1705 cert_status_t status
= CERT_STATUS_OK
;
1708 certpl
= &iph1
->cert
;
1710 certpl
= &iph1
->cert_p
;
1711 if (iph1
->rmconf
->identity_in_keychain
== 0) {
1712 plog(ASL_LEVEL_ERR
, "no CERT defined.\n");
1716 switch (iph1
->rmconf
->certtype
) {
1717 case ISAKMP_CERT_X509SIGN
:
1718 if (iph1
->rmconf
->identity_in_keychain
) {
1721 if (iph1
->rmconf
->keychainCertRef
== NULL
|| base64toCFData(iph1
->rmconf
->keychainCertRef
, &dataRef
))
1723 cert
= crypto_cssm_get_x509cert(dataRef
, &status
);
1724 plog(ASL_LEVEL_DEBUG
, "done with chking cert status %d\n",status
);
1730 "not supported certtype %d\n",
1731 iph1
->rmconf
->certtype
);
1737 "failed to get %s CERT.\n",
1738 my
? "my" : "peers");
1742 *certpl
= oakley_newcert();
1745 "failed to get cert buffer.\n");
1748 (*certpl
)->pl
= vmalloc(cert
->l
+ 1);
1749 if ((*certpl
)->pl
== NULL
) {
1751 "failed to get cert buffer\n");
1752 oakley_delcert(*certpl
);
1756 memcpy((*certpl
)->pl
->v
+ 1, cert
->v
, cert
->l
);
1757 (*certpl
)->pl
->v
[0] = iph1
->rmconf
->certtype
;
1758 (*certpl
)->type
= iph1
->rmconf
->certtype
;
1759 (*certpl
)->status
= status
;
1760 (*certpl
)->cert
.v
= (*certpl
)->pl
->v
+ 1;
1761 (*certpl
)->cert
.l
= (*certpl
)->pl
->l
- 1;
1763 plog(ASL_LEVEL_DEBUG
, "created CERT payload\n");
1777 oakley_getsign(phase1_handle_t
*iph1
)
1779 vchar_t
*privkey
= NULL
;
1782 switch (iph1
->rmconf
->certtype
) {
1783 case ISAKMP_CERT_X509SIGN
:
1784 // cert in keychain - use cssm to sign
1785 if (iph1
->rmconf
->identity_in_keychain
) {
1788 if (iph1
->rmconf
->keychainCertRef
== NULL
|| base64toCFData(iph1
->rmconf
->keychainCertRef
, &dataRef
))
1790 iph1
->sig
= crypto_cssm_getsign(dataRef
, iph1
->hash
);
1796 "Unknown certtype #%d\n",
1797 iph1
->rmconf
->certtype
);
1801 if (iph1
->sig
== NULL
) {
1802 plog(ASL_LEVEL_ERR
, "failed to sign.\n");
1806 //plogdump(ASL_LEVEL_DEBUG, iph1->sig->v, iph1->sig->l, "SIGN computed:\n");
1811 if (privkey
!= NULL
)
1818 oakley_verify_certid(phase1_handle_t
*iph1
)
1820 if (iph1
->rmconf
->verify_cert
&&
1821 oakley_check_certid(iph1
)){
1822 plog(ASL_LEVEL_DEBUG
,
1823 "Discarding CERT: does not match ID:\n");
1824 oakley_delcert(iph1
->cert_p
);
1825 iph1
->cert_p
= NULL
;
1830 oakley_check_certid_in_certchain(cert_t
*certchain
, int idtype
, int idlen
, void *id
)
1834 for (p
= certchain
; p
; p
= p
->chain
) {
1835 if (oakley_check_certid_1(&p
->cert
, idtype
, idlen
, id
, &p
->status
) == 0) {
1839 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1843 oakley_get_peer_cert_from_certchain(phase1_handle_t
* iph1
)
1846 struct ipsecdoi_id_b
*id_b
;
1850 if (!iph1
->id_p
|| !iph1
->cert_p
) {
1851 plog(ASL_LEVEL_ERR
, "no ID nor CERT found.\n");
1854 if (!iph1
->cert_p
->chain
) {
1855 // no chain: simply return the only cert
1856 return iph1
->cert_p
;
1859 id_b
= ALIGNED_CAST(struct ipsecdoi_id_b
*)iph1
->id_p
->v
;
1860 peers_id
= id_b
+ 1;
1861 idlen
= iph1
->id_p
->l
- sizeof(*id_b
);
1862 for (p
= iph1
->cert_p
; p
; p
= p
->chain
) {
1863 if (oakley_check_certid_1(&p
->cert
, id_b
->type
, idlen
, peers_id
, &p
->status
) == 0) {
1871 * compare certificate name and ID value.
1874 oakley_check_certid(phase1_handle_t
*iph1
)
1876 struct ipsecdoi_id_b
*id_b
;
1878 u_int8_t doi_type
= 255;
1879 void *peers_id
= NULL
;
1881 /* use ID from peer */
1882 if (iph1
->id_p
== NULL
|| iph1
->cert_p
== NULL
) {
1883 plog(ASL_LEVEL_ERR
, "no ID nor CERT found.\n");
1884 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1886 id_b
= ALIGNED_CAST(struct ipsecdoi_id_b
*)iph1
->id_p
->v
;
1887 doi_type
= id_b
->type
;
1888 peers_id
= id_b
+ 1;
1889 idlen
= iph1
->id_p
->l
- sizeof(*id_b
);
1891 return oakley_check_certid_in_certchain(iph1
->cert_p
, doi_type
, idlen
, peers_id
);
1896 oakley_check_certid_1(vchar_t
*cert
, int idtype
, int idlen
, void *id
, cert_status_t
*certStatus
)
1902 #if !TARGET_OS_EMBEDDED
1904 char *altname
= NULL
;
1908 case IPSECDOI_ID_DER_ASN1_DN
:
1911 SecCertificateRef certificate
;
1914 certificate
= crypto_cssm_x509cert_CreateSecCertificateRef(cert
);
1915 if (certificate
== NULL
) {
1917 "failed to get SecCertificateRef\n");
1918 if (certStatus
&& !*certStatus
) {
1919 *certStatus
= CERT_STATUS_INVALID
;
1921 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
1923 subject
= crypto_cssm_CopySubjectSequence(certificate
);
1924 if (subject
== NULL
) {
1925 plog(ASL_LEVEL_ERR
, "failed to get certificate subjectName\n");
1926 if (certStatus
&& !*certStatus
) {
1927 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
1929 error
= ISAKMP_NTYPE_INVALID_CERTIFICATE
;
1931 len
= CFDataGetLength(subject
);
1932 namePtr
= (UInt8
*)CFDataGetBytePtr(subject
);
1934 if (idlen
!= len
|| memcmp(id
, namePtr
, idlen
)) {
1935 plog(ASL_LEVEL_ERR
, "ID mismatched with certificate subjectName\n");
1936 error
=ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1939 plog(ASL_LEVEL_ERR
, "no certificate subjectName found\n");
1940 error
= ISAKMP_NTYPE_INVALID_CERTIFICATE
;
1945 "ID mismatched with certificate subjectName\n");
1946 plogdump(ASL_LEVEL_ERR
, namePtr
, len
, "subjectName (type %s):\n",
1947 s_ipsecdoi_ident(idtype
));
1948 plogdump(ASL_LEVEL_ERR
, id
, idlen
, "ID:\n");
1949 if (certStatus
&& !*certStatus
) {
1950 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
1953 CFRelease(certificate
);
1959 case IPSECDOI_ID_IPV4_ADDR
:
1960 case IPSECDOI_ID_IPV6_ADDR
:
1962 #if TARGET_OS_EMBEDDED
1964 SecCertificateRef certificate
;
1965 CFArrayRef addresses
;
1966 #define ADDRESS_BUF_SIZE 64
1968 certificate
= crypto_cssm_x509cert_CreateSecCertificateRef(cert
);
1969 if (certificate
== NULL
) {
1971 "failed to get SecCertificateRef\n");
1972 if (certStatus
&& !*certStatus
) {
1973 *certStatus
= CERT_STATUS_INVALID
;
1975 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
1977 addresses
= SecCertificateCopyIPAddresses(certificate
);
1978 if (addresses
== NULL
) {
1979 plog(ASL_LEVEL_ERR
, "failed to get subjectName\n");
1980 if (certStatus
&& !*certStatus
) {
1981 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
1983 CFRelease(certificate
);
1984 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
1986 count
= CFArrayGetCount(addresses
);
1987 for (pos
= 0; pos
< count
; pos
++) {
1989 CFStringRef address
;
1991 char *addressBuf
, numAddress
[128];
1994 address
= CFArrayGetValueAtIndex(addresses
, pos
);
1995 addressLen
= CFStringGetLength(address
);
1996 if (addressLen
== 0)
1998 addressBuf
= racoon_malloc(ADDRESS_BUF_SIZE
);
1999 if (addressBuf
== NULL
) {
2000 plog(ASL_LEVEL_ERR
, "out of memory\n");
2001 CFRelease(addresses
);
2002 CFRelease(certificate
);
2005 if (CFStringGetCString(address
, addressBuf
, ADDRESS_BUF_SIZE
, kCFStringEncodingUTF8
) == TRUE
) {
2006 result
= inet_pton(idtype
== IPSECDOI_ID_IPV4_ADDR
? AF_INET
: AF_INET6
, addressBuf
, numAddress
);
2007 racoon_free(addressBuf
);
2009 continue; // wrong type or invalid address
2010 if (!memcmp(id
, numAddress
, idtype
== IPSECDOI_ID_IPV4_ADDR
? 32 : 128) == 0) { // found a match ?
2011 CFRelease(addresses
);
2012 CFRelease(certificate
);
2016 racoon_free(addressBuf
);
2018 plog(ASL_LEVEL_ERR
, "ID mismatched with subjectAltName.\n");
2020 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype
));
2021 plogdump(ASL_LEVEL_ERR
, id
, idlen
, "ID:\n");
2022 CFRelease(addresses
);
2023 CFRelease(certificate
);
2024 if (certStatus
&& !*certStatus
) {
2025 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2027 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2030 * Openssl returns the IPAddress as an ASN1 octet string (binary format)
2031 * followed by a trailing NULL. 5 bytes for IPv4 and 17 bytes for IPv6
2033 #define SUBJ_ALT_NAME_IPV4_ADDRESS_LEN 5
2034 #define SUBJ_ALT_NAME_IPV6_ADDRESS_LEN 17
2038 if ((idtype
== IPSECDOI_ID_IPV4_ADDR
&& idlen
!= sizeof(struct in_addr
))
2039 || (idtype
== IPSECDOI_ID_IPV6_ADDR
&& idlen
!= sizeof(struct in6_addr
))) {
2041 "invalid address length passed.\n");
2042 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2045 for (pos
= 1; ; pos
++) {
2046 if (eay_get_x509subjectaltname(cert
, &altname
, &type
, pos
, &len
) !=0) {
2048 "failed to get subjectAltName\n");
2049 if (certStatus
&& !*certStatus
) {
2050 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2052 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2055 /* it's the end condition of the loop. */
2058 "invalid subjectAltName\n");
2059 if (certStatus
&& !*certStatus
) {
2060 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2062 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2065 if (check_typeofcertname(idtype
, type
) != 0) {
2066 /* wrong type - skip this one */
2067 racoon_free(altname
);
2072 if (len
== SUBJ_ALT_NAME_IPV4_ADDRESS_LEN
) { /* IPv4 */
2073 if (idtype
!= IPSECDOI_ID_IPV4_ADDR
) {
2074 /* wrong IP address type - skip this one */
2075 racoon_free(altname
);
2081 else if (len
== SUBJ_ALT_NAME_IPV6_ADDRESS_LEN
) { /* IPv6 */
2082 if (idtype
!= IPSECDOI_ID_IPV6_ADDR
) {
2083 /* wrong IP address type - skip this one */
2084 racoon_free(altname
);
2091 /* invalid IP address length in certificate - bad or bogus certificate */
2093 "invalid IP address in certificate.\n");
2094 plogdump(ASL_LEVEL_ERR
, altname
, len
, "subjectAltName (expected type %s, got type %s):\n",
2095 s_ipsecdoi_ident(idtype
),
2096 s_ipsecdoi_ident(type
));
2097 racoon_free(altname
);
2099 if (certStatus
&& !*certStatus
) {
2100 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2102 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2105 /* compare the addresses */
2106 error
= memcmp(id
, altname
, idlen
);
2109 racoon_free(altname
);
2112 /* failed to find a match */
2114 "ID mismatched with subjectAltName.\n");
2115 plogdump(ASL_LEVEL_ERR
, altname
, len
, "subjectAltName (expected type %s, got type %s):\n",
2116 s_ipsecdoi_ident(idtype
),
2117 s_ipsecdoi_ident(type
));
2118 plogdump(ASL_LEVEL_ERR
, id
, idlen
, "ID:\n");
2119 racoon_free(altname
);
2120 if (certStatus
&& !*certStatus
)
2121 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2122 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2124 #endif /* TARGET_OS_EMBEDDED */
2127 #if TARGET_OS_EMBEDDED
2128 case IPSECDOI_ID_FQDN
:
2131 SecCertificateRef certificate
;
2133 CFStringRef name
, ID
;
2135 certificate
= crypto_cssm_x509cert_CreateSecCertificateRef(cert
);
2136 if (certificate
== NULL
) {
2138 "failed to get SecCertificateRef\n");
2139 if (certStatus
&& !*certStatus
) {
2140 *certStatus
= CERT_STATUS_INVALID
;
2142 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2144 names
= SecCertificateCopyDNSNames(certificate
);
2145 if (names
== NULL
) {
2147 "failed to get subjectName\n");
2148 if (certStatus
&& !*certStatus
) {
2149 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2151 CFRelease(certificate
);
2152 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2154 count
= CFArrayGetCount(names
);
2155 ID
= CFStringCreateWithBytes(kCFAllocatorDefault
, id
, idlen
, kCFStringEncodingUTF8
, FALSE
);
2157 plog(ASL_LEVEL_ERR
, "memory error\n");
2159 CFRelease(certificate
);
2162 for (pos
= 0; pos
< count
; pos
++) {
2163 name
= CFArrayGetValueAtIndex(names
, pos
);
2164 if (CFStringCompare(name
, ID
, 0) == kCFCompareEqualTo
) {
2167 CFRelease(certificate
);
2171 plog(ASL_LEVEL_ERR
, "ID mismatched with subjectAltName.\n");
2173 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype
));
2174 plogdump(ASL_LEVEL_ERR
, id
, idlen
, "ID:\n");
2177 CFRelease(certificate
);
2178 if (certStatus
&& !*certStatus
) {
2179 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2181 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2184 case IPSECDOI_ID_USER_FQDN
:
2188 SecCertificateRef certificate
;
2190 CFStringRef name
, ID
;
2192 certificate
= crypto_cssm_x509cert_CreateSecCertificateRef(cert
);
2193 if (certificate
== NULL
) {
2195 "failed to get SecCertificateRef\n");
2196 if (certStatus
&& !*certStatus
) {
2197 *certStatus
= CERT_STATUS_INVALID
;
2199 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2201 names
= SecCertificateCopyRFC822Names(certificate
);
2202 if (names
== NULL
) {
2204 "failed to get subjectName\n");
2205 if (certStatus
&& !*certStatus
) {
2206 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2208 CFRelease(certificate
);
2209 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2211 count
= CFArrayGetCount(names
);
2212 ID
= CFStringCreateWithBytes(kCFAllocatorDefault
, id
, idlen
, kCFStringEncodingUTF8
, FALSE
);
2216 if (certStatus
&& !*certStatus
) {
2217 *certStatus
= CERT_STATUS_INVALID
;
2220 CFRelease(certificate
);
2221 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2223 for (pos
= 0; pos
< count
; pos
++) {
2224 name
= CFArrayGetValueAtIndex(names
, pos
);
2225 if (CFStringCompare(name
, ID
, 0) == kCFCompareEqualTo
) {
2228 CFRelease(certificate
);
2232 plog(ASL_LEVEL_ERR
, "ID mismatched with subjectAltName.\n");
2234 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype
));
2235 plogdump(ASL_LEVEL_ERR
, id
, idlen
, "ID:\n");
2238 CFRelease(certificate
);
2239 if (certStatus
&& !*certStatus
) {
2240 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2242 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2245 case IPSECDOI_ID_FQDN
:
2246 case IPSECDOI_ID_USER_FQDN
:
2250 for (pos
= 1; ; pos
++) {
2251 if (eay_get_x509subjectaltname(cert
, &altname
, &type
, pos
, &len
) != 0) {
2253 "failed to get subjectAltName\n");
2254 if (certStatus
&& !*certStatus
) {
2255 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2257 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2260 /* it's the end condition of the loop. */
2263 "invalid subjectAltName\n");
2264 if (certStatus
&& !*certStatus
) {
2265 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2267 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2270 if (check_typeofcertname(idtype
, type
) != 0) {
2271 /* wrong general type - skip this one */
2272 racoon_free(altname
);
2277 if (idlen
!= strlen(altname
)) {
2278 /* wrong length - skip this one */
2279 racoon_free(altname
);
2283 error
= memcmp(id
, altname
, idlen
);
2286 racoon_free(altname
);
2289 plog(ASL_LEVEL_ERR
, "ID mismatched with subjectAltName.\n");
2291 "subjectAltName (expected type %s, got type %s):\n",
2292 s_ipsecdoi_ident(idtype
),
2293 s_ipsecdoi_ident(type
));
2294 plogdump(ASL_LEVEL_ERR
, altname
, len
, "subjectAltName (expected type %s, got type %s):\n",
2295 s_ipsecdoi_ident(idtype
),
2296 s_ipsecdoi_ident(type
));
2297 plogdump(ASL_LEVEL_ERR
, id
, idlen
, "ID:\n");
2298 racoon_free(altname
);
2299 if (certStatus
&& !*certStatus
)
2300 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2301 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2306 "Impropper ID type passed: %s.\n",
2307 s_ipsecdoi_ident(idtype
));
2308 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2314 check_typeofcertname(int doi
, int genid
)
2317 case IPSECDOI_ID_IPV4_ADDR
:
2318 case IPSECDOI_ID_IPV4_ADDR_SUBNET
:
2319 case IPSECDOI_ID_IPV6_ADDR
:
2320 case IPSECDOI_ID_IPV6_ADDR_SUBNET
:
2321 case IPSECDOI_ID_IPV4_ADDR_RANGE
:
2322 case IPSECDOI_ID_IPV6_ADDR_RANGE
:
2323 if (genid
!= GENT_IPADD
)
2326 case IPSECDOI_ID_FQDN
:
2327 if (genid
!= GENT_DNS
)
2330 case IPSECDOI_ID_USER_FQDN
:
2331 if (genid
!= GENT_EMAIL
)
2334 case IPSECDOI_ID_DER_ASN1_DN
: /* should not be passed to this function*/
2335 case IPSECDOI_ID_DER_ASN1_GN
:
2336 case IPSECDOI_ID_KEY_ID
:
2345 * save certificate including certificate type.
2348 oakley_savecert(phase1_handle_t
*iph1
, struct isakmp_gen
*gen
)
2352 type
= *(u_int8_t
*)(gen
+ 1) & 0xff;
2355 case ISAKMP_CERT_X509SIGN
:
2360 "Invalid CERT type %d\n", type
);
2365 plog(ASL_LEVEL_WARNING
,
2366 "preexisting CERT payload... chaining.\n");
2370 new = save_certbuf(gen
);
2373 "Failed to get CERT buffer.\n");
2377 switch (new->type
) {
2378 case ISAKMP_CERT_X509SIGN
:
2379 /* Ignore cert if it doesn't match identity
2380 * XXX If verify cert is disabled, we still just take
2381 * the first certificate....
2383 *c
= oakley_appendcert_to_certchain(*c
, new);
2384 plog(ASL_LEVEL_DEBUG
, "CERT saved:\n");
2388 oakley_delcert(new);
2396 * save certificate including certificate type.
2399 oakley_savecr(phase1_handle_t
*iph1
, struct isakmp_gen
*gen
)
2405 type
= *(u_int8_t
*)(gen
+ 1) & 0xff;
2408 case ISAKMP_CERT_X509SIGN
:
2410 oakley_delcert(iph1
->cr_p
);
2417 "Invalid CR type %d\n", type
);
2421 new = save_certbuf(gen
);
2424 "Failed to get CR buffer.\n");
2427 *c
= oakley_appendcert_to_certchain(*c
, new);
2428 plog(ASL_LEVEL_DEBUG
, "CR saved\n");
2434 save_certbuf(struct isakmp_gen
*gen
)
2438 if(ntohs(gen
->len
) <= sizeof(*gen
)){
2440 "Len is too small !!.\n");
2444 new = oakley_newcert();
2447 "Failed to get CERT buffer.\n");
2451 new->pl
= vmalloc(ntohs(gen
->len
) - sizeof(*gen
));
2452 if (new->pl
== NULL
) {
2454 "Failed to copy CERT from packet.\n");
2455 oakley_delcert(new);
2459 memcpy(new->pl
->v
, gen
+ 1, new->pl
->l
);
2460 new->type
= new->pl
->v
[0] & 0xff;
2461 new->cert
.v
= new->pl
->v
+ 1;
2462 new->cert
.l
= new->pl
->l
- 1;
2469 * NOTE: No Certificate Authority field is included to CR payload at the
2470 * moment. Becuase any certificate authority are accepted without any check.
2471 * The section 3.10 in RFC2408 says that this field SHOULD not be included,
2472 * if there is no specific certificate authority requested.
2475 oakley_getcr(phase1_handle_t
*iph1
)
2482 "failed to get cr buffer\n");
2485 if(iph1
->rmconf
->certtype
== ISAKMP_CERT_NONE
) {
2486 buf
->v
[0] = iph1
->rmconf
->cacerttype
;
2487 plog(ASL_LEVEL_DEBUG
, "create my CR: NONE, using %s instead\n",
2488 s_isakmp_certtype(iph1
->rmconf
->cacerttype
));
2490 buf
->v
[0] = iph1
->rmconf
->certtype
;
2491 plog(ASL_LEVEL_DEBUG
, "create my CR: %s\n",
2492 s_isakmp_certtype(iph1
->rmconf
->certtype
));
2495 // plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "");
2504 oakley_checkcr(phase1_handle_t
*iph1
)
2506 if (iph1
->cr_p
== NULL
)
2509 plog(ASL_LEVEL_DEBUG
,
2510 "peer transmitted CR: %s\n",
2511 s_isakmp_certtype(iph1
->cr_p
->type
));
2513 if (iph1
->cr_p
->type
!= iph1
->rmconf
->certtype
) {
2515 "such a cert type isn't supported: %d\n",
2516 (char)iph1
->cr_p
->type
);
2524 * check to need CR payload.
2527 oakley_needcr(int type
)
2530 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
2531 #ifdef ENABLE_HYBRID
2532 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
2533 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
2534 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
2544 oakley_getpskall(phase1_handle_t
*iph1
)
2546 vchar_t
*secret
= NULL
;
2548 if (iph1
->rmconf
->shared_secret
) {
2550 switch (iph1
->rmconf
->secrettype
) {
2551 case SECRETTYPE_KEY
:
2552 /* in psk file - use KEY from remote configuration to locate it */
2553 secret
= getpsk(iph1
->rmconf
->shared_secret
->v
, iph1
->rmconf
->shared_secret
->l
-1);
2556 case SECRETTYPE_KEYCHAIN
:
2557 /* in the system keychain */
2558 secret
= getpskfromkeychain(iph1
->rmconf
->shared_secret
->v
, iph1
->etype
, iph1
->rmconf
->secrettype
, NULL
);
2560 case SECRETTYPE_KEYCHAIN_BY_ID
:
2561 /* in the system keychain - use peer id */
2562 secret
= getpskfromkeychain(iph1
->rmconf
->shared_secret
->v
, iph1
->etype
, iph1
->rmconf
->secrettype
, iph1
->id_p
);
2564 #endif // HAVE_KEYCHAIN
2565 case SECRETTYPE_USE
:
2566 /* in the remote configuration */
2568 /* rmconf->shared_secret is a string and contains a NULL character that must be removed */
2569 secret
= vmalloc(iph1
->rmconf
->shared_secret
->l
- 1);
2570 if (secret
== NULL
) {
2571 plog(ASL_LEVEL_ERR
, "memory error.\n");
2574 memcpy(secret
->v
, iph1
->rmconf
->shared_secret
->v
, secret
->l
);
2576 } else if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV2
||
2577 iph1
->etype
!= ISAKMP_ETYPE_IDENT
) {
2578 secret
= getpskbyname(iph1
->id_p
);
2580 if (iph1
->rmconf
->verify_identifier
) {
2581 plog(ASL_LEVEL_ERR
, "couldn't find pskey by peer's ID.\n");
2587 plog(ASL_LEVEL_NOTICE
, "try to get pskey by the peer's address.\n");
2588 secret
= getpskbyaddr(iph1
->remote
);
2591 "couldn't find the pskey by address %s.\n",
2592 saddrwop2str((struct sockaddr
*)iph1
->remote
));
2602 * see seciton 5. Exchanges in RFC 2409
2603 * psk: SKEYID = prf(pre-shared-key, Ni_b | Nr_b)
2604 * sig: SKEYID = prf(Ni_b | Nr_b, g^ir)
2605 * enc: SKEYID = prf(H(Ni_b | Nr_b), CKY-I | CKY-R)
2608 oakley_skeyid(phase1_handle_t
*iph1
)
2610 vchar_t
*key
= NULL
;
2611 vchar_t
*buf
= NULL
;
2619 switch (AUTHMETHOD(iph1
)) {
2620 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
2621 #ifdef ENABLE_HYBRID
2622 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
2623 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
2625 key
= oakley_getpskall(iph1
);
2628 "couldn't find the pskey for %s.\n",
2629 saddrwop2str((struct sockaddr
*)iph1
->remote
));
2632 plog(ASL_LEVEL_DEBUG
, "the psk found.\n");
2633 /* should be secret PSK */
2634 plogdump(ASL_LEVEL_DEBUG
, key
->v
, key
->l
, "psk: ");
2636 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
2640 "failed to get skeyid buffer\n");
2645 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce
: iph1
->nonce_p
);
2646 //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce 1: ");
2647 memcpy(p
, bp
->v
, bp
->l
);
2650 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce_p
: iph1
->nonce
);
2651 //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce 2: ");
2652 memcpy(p
, bp
->v
, bp
->l
);
2655 iph1
->skeyid
= oakley_prf(key
, buf
, iph1
);
2657 if (iph1
->skeyid
== NULL
)
2661 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
2662 #ifdef ENABLE_HYBRID
2663 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
2664 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
2665 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
2666 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
2668 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
2672 "failed to get nonce buffer\n");
2677 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce
: iph1
->nonce_p
);
2678 //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce1: ");
2679 memcpy(p
, bp
->v
, bp
->l
);
2682 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce_p
: iph1
->nonce
);
2683 //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce2: ");
2684 memcpy(p
, bp
->v
, bp
->l
);
2687 iph1
->skeyid
= oakley_prf(buf
, iph1
->dhgxy
, iph1
);
2688 if (iph1
->skeyid
== NULL
)
2691 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
2692 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
2693 #ifdef ENABLE_HYBRID
2694 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
2695 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
2696 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
2697 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
2699 plog(ASL_LEVEL_WARNING
,
2700 "not supported authentication method %s\n",
2701 s_oakley_attr_method(iph1
->approval
->authmethod
));
2705 "invalid authentication method %d\n",
2706 iph1
->approval
->authmethod
);
2710 //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid->v, iph1->skeyid->l, "IKEv1 SKEYID computed:\n");
2723 oakley_prf_plus (vchar_t
*key
, vchar_t
*buf
, int result_len
, phase1_handle_t
*iph1
)
2727 vchar_t
*result
= 0;
2736 prf+ (K,S) = T1 | T2 | T3 | T4 | ...
2739 T1 = prf (K, S | 0x01)
2740 T2 = prf (K, T1 | S | 0x02)
2741 T3 = prf (K, T2 | S | 0x03)
2742 T4 = prf (K, T3 | S | 0x04)
2745 if (!(result
= vmalloc(result_len
))) {
2750 * initial T0 = empty
2753 p
= (uint8_t *)result
->v
;
2754 for (byte_value
= 1; result_len
> 0; ++byte_value
) {
2756 * prf_output = prf(K, Ti-1 | S | byte)
2758 bp_len
= buf
->l
+ sizeof(byte_value
);
2762 bp
= vmalloc(bp_len
);
2766 tmp
= (__typeof__(tmp
))bp
->v
;
2769 memcpy(tmp
, t
->v
, t
->l
);
2772 memcpy(tmp
, buf
->v
, buf
->l
);
2774 memcpy(tmp
, &byte_value
, sizeof(byte_value
));
2775 tmp
+= sizeof(byte_value
);
2777 if (!(prf
= oakley_prf(key
, bp
, iph1
))) {
2779 return (vchar_t
*)-1;
2786 memcpy(p
, prf
->v
, prf
->l
> (size_t)result_len
? (size_t)result_len
: prf
->l
);
2788 result_len
-= prf
->l
;
2807 * compute SKEYID_[dae]
2810 oakley_skeyid_dae(phase1_handle_t
*iph1
)
2812 vchar_t
*buf
= NULL
, *bp
= NULL
;
2817 if (iph1
->skeyid
== NULL
) {
2818 plog(ASL_LEVEL_ERR
, "no SKEYID found.\n");
2822 * see seciton 5. Exchanges in RFC 2409
2823 * SKEYID_d = prf(SKEYID, g^ir | CKY-I | CKY-R | 0)
2824 * SKEYID_a = prf(SKEYID, SKEYID_d | g^ir | CKY-I | CKY-R | 1)
2825 * SKEYID_e = prf(SKEYID, SKEYID_a | g^ir | CKY-I | CKY-R | 2)
2828 /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
2829 len
= iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
2833 "failed to get skeyid buffer\n");
2838 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
2839 p
+= iph1
->dhgxy
->l
;
2840 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
2841 p
+= sizeof(cookie_t
);
2842 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
2843 p
+= sizeof(cookie_t
);
2845 iph1
->skeyid_d
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
2846 if (iph1
->skeyid_d
== NULL
)
2852 //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid_d->v, iph1->skeyid_d->l, "SKEYID_d computed:\n");
2855 /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
2856 len
= iph1
->skeyid_d
->l
+ iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
2860 "failed to get skeyid buffer\n");
2864 memcpy(p
, iph1
->skeyid_d
->v
, iph1
->skeyid_d
->l
);
2865 p
+= iph1
->skeyid_d
->l
;
2866 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
2867 p
+= iph1
->dhgxy
->l
;
2868 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
2869 p
+= sizeof(cookie_t
);
2870 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
2871 p
+= sizeof(cookie_t
);
2873 iph1
->skeyid_a
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
2874 if (iph1
->skeyid_a
== NULL
)
2880 //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid_a->v, iph1->skeyid_a->l, "SKEYID_a computed:\n");
2883 /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
2884 len
= iph1
->skeyid_a
->l
+ iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
2888 "failed to get skeyid buffer\n");
2892 memcpy(p
, iph1
->skeyid_a
->v
, iph1
->skeyid_a
->l
);
2893 p
+= iph1
->skeyid_a
->l
;
2894 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
2895 p
+= iph1
->dhgxy
->l
;
2896 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
2897 p
+= sizeof(cookie_t
);
2898 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
2899 p
+= sizeof(cookie_t
);
2901 iph1
->skeyid_e
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
2902 if (iph1
->skeyid_e
== NULL
)
2908 //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid_e->v, iph1->skeyid_e->l, "SKEYID_e computed:\n");
2919 * compute final encryption key.
2923 oakley_compute_enckey(phase1_handle_t
*iph1
)
2925 u_int keylen
, prflen
;
2929 keylen
= alg_oakley_encdef_keylen(iph1
->approval
->enctype
,
2930 iph1
->approval
->encklen
);
2933 "invalid encryption algoritym %d, "
2934 "or invalid key length %d.\n",
2935 iph1
->approval
->enctype
,
2936 iph1
->approval
->encklen
);
2939 iph1
->key
= vmalloc(keylen
>> 3);
2940 if (iph1
->key
== NULL
) {
2942 "failed to get key buffer\n");
2945 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV2
) {
2946 iph1
->key_p
= vmalloc(keylen
>> 3);
2947 if (iph1
->key_p
== NULL
) {
2949 "failed to get key buffer\n");
2953 if (iph1
->key
->l
<= iph1
->skeyid_e
->l
) {
2954 plog(ASL_LEVEL_DEBUG
,
2955 "%s setting key len %zd, val %d (len %zd)", __FUNCTION__
, iph1
->key
->l
, (int)iph1
->skeyid_e
->v
[0], iph1
->skeyid_e
->l
);
2957 * if length(Ka) <= length(SKEYID_e)
2958 * Ka = first length(K) bit of SKEYID_e
2960 memcpy(iph1
->key
->v
, iph1
->skeyid_e
->v
, iph1
->key
->l
);
2963 "unexpected key length error (exp %zd, got %zd)",
2964 iph1
->key
->l
, iph1
->skeyid_e
->l
);
2967 if (iph1
->key_p
->l
<= iph1
->skeyid_e_p
->l
) {
2968 plog(ASL_LEVEL_DEBUG
,
2969 "%s setting peer key len %zd, val %d (len %zd)", __FUNCTION__
, iph1
->key_p
->l
, (int)iph1
->skeyid_e_p
->v
[0], iph1
->skeyid_e_p
->l
);
2971 * if length(Ka) <= length(SKEYID_e)
2972 * Ka = first length(K) bit of SKEYID_e
2974 memcpy(iph1
->key_p
->v
, iph1
->skeyid_e_p
->v
, iph1
->key_p
->l
);
2977 "unexpected peer key length error (exp %zd, got %zd)",
2978 iph1
->key_p
->l
, iph1
->skeyid_e_p
->l
);
2983 /* set prf length */
2984 prflen
= alg_oakley_hashdef_hashlen(iph1
->approval
->hashtype
);
2987 "invalid hash type %d.\n", iph1
->approval
->hashtype
);
2991 /* see isakmp-oakley-08 5.3. */
2992 if (iph1
->key
->l
<= iph1
->skeyid_e
->l
) {
2994 * if length(Ka) <= length(SKEYID_e)
2995 * Ka = first length(K) bit of SKEYID_e
2997 memcpy(iph1
->key
->v
, iph1
->skeyid_e
->v
, iph1
->key
->l
);
2999 vchar_t
*buf
= NULL
, *res
= NULL
;
3004 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV2
) {
3006 "invalid key len (got %zu, expected %zu.\n", iph1
->key
->l
, iph1
->skeyid_e
->l
);
3014 * K1 = prf(SKEYID_e, 0)
3015 * K2 = prf(SKEYID_e, K1)
3016 * K3 = prf(SKEYID_e, K2)
3018 plog(ASL_LEVEL_DEBUG
,
3019 "len(SKEYID_e) < len(Ka) (%zu < %zu), "
3020 "generating long key (Ka = K1 | K2 | ...)\n",
3021 iph1
->skeyid_e
->l
, iph1
->key
->l
);
3023 if ((buf
= vmalloc(prflen
>> 3)) == 0) {
3025 "failed to get key buffer\n");
3028 p
= (u_char
*)iph1
->key
->v
;
3029 ep
= p
+ iph1
->key
->l
;
3033 if (p
== (u_char
*)iph1
->key
->v
) {
3034 /* just for computing K1 */
3038 res
= oakley_prf(iph1
->skeyid_e
, buf
, iph1
);
3043 plog(ASL_LEVEL_DEBUG
,
3044 "compute intermediate encryption key K%d\n",
3046 //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "");
3047 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "");
3049 cplen
= (res
->l
< ep
- p
) ? res
->l
: ep
- p
;
3050 memcpy(p
, res
->v
, cplen
);
3053 buf
->l
= prflen
>> 3; /* to cancel K1 speciality */
3054 if (res
->l
!= buf
->l
) {
3056 "internal error: res->l=%zu buf->l=%zu\n",
3062 memcpy(buf
->v
, res
->v
, res
->l
);
3071 * don't check any weak key or not.
3072 * draft-ietf-ipsec-ike-01.txt Appendix B.
3073 * draft-ietf-ipsec-ciph-aes-cbc-00.txt Section 2.3.
3076 //plogdump(ASL_LEVEL_DEBUG, iph1->key->v, iph1->key->l, "final encryption key computed:\n");
3084 /* allocated new buffer for CERT */
3086 oakley_newcert(void)
3090 new = racoon_calloc(1, sizeof(*new));
3093 "failed to get cert's buffer\n");
3103 /* delete buffer for CERT */
3105 oakley_delcert_1(cert_t
*cert
)
3114 /* delete buffer for CERT */
3116 oakley_delcert(cert_t
*cert
)
3118 cert_t
*p
, *to_delete
;
3123 for (p
= cert
; p
;) {
3126 oakley_delcert_1(to_delete
);
3130 /* delete buffer for CERT */
3132 oakley_appendcert_to_certchain(cert_t
*certchain
, cert_t
*new)
3139 for (p
= certchain
; p
; p
= p
->chain
) {
3149 * compute IV and set to ph1handle
3150 * IV = hash(g^xi | g^xr)
3151 * see 4.1 Phase 1 state in draft-ietf-ipsec-ike.
3154 oakley_newiv(phase1_handle_t
*iph1
)
3156 struct isakmp_ivm
*newivm
= NULL
;
3157 vchar_t
*buf
= NULL
, *bp
;
3162 len
= iph1
->dhpub
->l
+ iph1
->dhpub_p
->l
;
3166 "Failed to get IV buffer\n");
3172 bp
= (iph1
->side
== INITIATOR
? iph1
->dhpub
: iph1
->dhpub_p
);
3173 memcpy(p
, bp
->v
, bp
->l
);
3176 bp
= (iph1
->side
== INITIATOR
? iph1
->dhpub_p
: iph1
->dhpub
);
3177 memcpy(p
, bp
->v
, bp
->l
);
3181 newivm
= racoon_calloc(1, sizeof(struct isakmp_ivm
));
3182 if (newivm
== NULL
) {
3184 "Failed to get IV buffer\n");
3190 newivm
->iv
= oakley_hash(buf
, iph1
);
3191 if (newivm
->iv
== NULL
) {
3193 oakley_delivm(newivm
);
3197 /* adjust length of iv */
3198 newivm
->iv
->l
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3199 if (newivm
->iv
->l
== -1) {
3201 "Invalid encryption algorithm %d.\n",
3202 iph1
->approval
->enctype
);
3204 oakley_delivm(newivm
);
3208 /* create buffer to save iv */
3209 if ((newivm
->ive
= vdup(newivm
->iv
)) == NULL
) {
3211 "vdup (%s)\n", strerror(errno
));
3213 oakley_delivm(newivm
);
3219 //plogdump(ASL_LEVEL_DEBUG, newivm->iv->v, newivm->iv->l, "IV computed:\n");
3221 if (iph1
->ivm
!= NULL
)
3222 oakley_delivm(iph1
->ivm
);
3230 * compute IV for the payload after phase 1.
3231 * It's not limited for phase 2.
3232 * if pahse 1 was encrypted.
3233 * IV = hash(last CBC block of Phase 1 | M-ID)
3234 * if phase 1 was not encrypted.
3235 * IV = hash(phase 1 IV | M-ID)
3236 * see 4.2 Phase 2 state in draft-ietf-ipsec-ike.
3239 oakley_newiv2(phase1_handle_t
*iph1
, u_int32_t msgid
)
3241 struct isakmp_ivm
*newivm
= NULL
;
3242 vchar_t
*buf
= NULL
;
3248 len
= iph1
->ivm
->iv
->l
+ sizeof(msgid_t
);
3252 "Failed to get IV buffer\n");
3258 memcpy(p
, iph1
->ivm
->iv
->v
, iph1
->ivm
->iv
->l
);
3259 p
+= iph1
->ivm
->iv
->l
;
3261 memcpy(p
, &msgid
, sizeof(msgid
));
3263 plog(ASL_LEVEL_DEBUG
, "Compute IV for Phase 2\n");
3264 //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "Phase 1 last IV:\n");
3267 newivm
= racoon_calloc(1, sizeof(struct isakmp_ivm
));
3268 if (newivm
== NULL
) {
3270 "Failed to get IV buffer\n");
3275 if ((newivm
->iv
= oakley_hash(buf
, iph1
)) == NULL
)
3278 /* adjust length of iv */
3279 newivm
->iv
->l
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3280 if (newivm
->iv
->l
== -1) {
3282 "Invalid encryption algorithm %d.\n",
3283 iph1
->approval
->enctype
);
3287 /* create buffer to save new iv */
3288 if ((newivm
->ive
= vdup(newivm
->iv
)) == NULL
) {
3289 plog(ASL_LEVEL_ERR
, "vdup (%s)\n", strerror(errno
));
3295 //plogdump(ASL_LEVEL_DEBUG, newivm->iv->v, newivm->iv->l, "Phase 2 IV computed:\n");
3298 if (error
&& newivm
!= NULL
){
3299 oakley_delivm(newivm
);
3308 * Compute unpredictable IV for IKEv2.
3311 oakley_newiv_ikev2(phase1_handle_t
* iph1
)
3313 struct isakmp_ivm
*newivm
= NULL
;
3317 iv_length
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3318 if (iv_length
== -1) {
3319 plog(ASL_LEVEL_ERR
, "Invalid encryption algorithm %d.\n", iph1
->approval
->enctype
);
3322 /* Allocate IV Manager */
3323 newivm
= racoon_calloc(1, sizeof(struct isakmp_ivm
));
3324 if (newivm
== NULL
) {
3325 plog(ASL_LEVEL_ERR
, "Failed to allocate IV buffer.\n");
3330 /* There are two recommended methods for generating unpredictable IVs. The first method is to apply the forward cipher function, under the same key that is used for the encryption of the plaintext, to a nonce. The nonce must be a data block that is unique to each execution of the encryption operation. For example, the nonce may be a counter, as described in Appendix B, or a message number. The second method is to generate a random data block using a FIPS- approved random number generator.
3331 [National Institute of Standards and Technology, U.S.
3332 Department of Commerce, "Recommendation for Block Cipher
3333 Modes of Operation", SP 800-38A, 2001.]
3335 /* Currently, we implement the second scheme, which uses a random block */
3336 newivm
->iv
= eay_set_random(iv_length
);
3337 if (newivm
->iv
== NULL
) {
3338 oakley_delivm(newivm
);
3342 /* Adjust length of IV */
3343 if (newivm
->iv
->l
!= iv_length
) {
3344 plog(ASL_LEVEL_WARNING
, "IV length was adjusted.\n");
3345 newivm
->iv
->l
= iv_length
;
3348 /* Make copy of IV in IVe */
3349 if ((newivm
->ive
= vdup(newivm
->iv
)) == NULL
) {
3350 plog(ASL_LEVEL_ERR
, "vdup (%s)\n", strerror(errno
));
3351 oakley_delivm(newivm
);
3355 /* Delete old IV if there is one */
3356 if (iph1
->ivm
!= NULL
)
3357 oakley_delivm(iph1
->ivm
);
3366 oakley_delivm(struct isakmp_ivm
*ivm
)
3371 if (ivm
->iv
!= NULL
)
3373 if (ivm
->ive
!= NULL
)
3376 plog(ASL_LEVEL_DEBUG
, "IV freed\n");
3383 * save new iv and old iv.
3386 oakley_do_ikev1_decrypt(phase1_handle_t
*iph1
, vchar_t
*msg
, vchar_t
*ivdp
, vchar_t
*ivep
)
3388 vchar_t
*buf
= NULL
, *new = NULL
;
3395 plog(ASL_LEVEL_DEBUG
, "Begin decryption.\n");
3397 blen
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3400 "Invalid encryption algorithm %d.\n",
3401 iph1
->approval
->enctype
);
3405 /* save IV for next, but not sync. */
3406 memset(ivep
->v
, 0, ivep
->l
);
3407 memcpy(ivep
->v
, (caddr_t
)&msg
->v
[msg
->l
- blen
], blen
);
3409 plogdump(ASL_LEVEL_DEBUG
, ivep
->v
, ivep
->l
, "IV was saved for next processing:\n");
3411 pl
= msg
->v
+ sizeof(struct isakmp
);
3413 len
= msg
->l
- sizeof(struct isakmp
);
3419 "Failed to get buffer to decrypt.\n");
3422 memcpy(buf
->v
, pl
, len
);
3425 new = alg_oakley_encdef_decrypt(iph1
->approval
->enctype
,
3426 buf
, iph1
->key
, ivdp
);
3427 if (new == NULL
|| new->v
== NULL
|| new->l
== 0) {
3429 "Decryption %d failed.\n", iph1
->approval
->enctype
);
3432 //plogdump(ASL_LEVEL_DEBUG, iph1->key->v, iph1->key->l, "with key:\n");
3439 plog(ASL_LEVEL_DEBUG
, "decrypted payload by IV:\n");
3441 /* get padding length */
3442 if (lcconf
->pad_excltail
)
3443 padlen
= new->v
[new->l
- 1] + 1;
3445 padlen
= new->v
[new->l
- 1];
3446 plog(ASL_LEVEL_DEBUG
, "padding len=%u\n", padlen
);
3449 if (lcconf
->pad_strict
) {
3450 if (padlen
> new->l
) {
3451 plog(ASL_LEVEL_ERR
, "invalid padding len=%u, buflen=%zu.\n",
3456 plog(ASL_LEVEL_DEBUG
, "trimmed padding\n");
3458 plog(ASL_LEVEL_DEBUG
, "skip to trim padding.\n");
3461 /* create new buffer */
3462 len
= sizeof(struct isakmp
) + new->l
;
3466 "failed to get buffer to decrypt.\n");
3469 memcpy(buf
->v
, msg
->v
, sizeof(struct isakmp
));
3470 memcpy(buf
->v
+ sizeof(struct isakmp
), new->v
, new->l
);
3471 ((struct isakmp
*)buf
->v
)->len
= htonl(buf
->l
);
3473 plog(ASL_LEVEL_DEBUG
, "decrypted.\n");
3475 #ifdef HAVE_PRINT_ISAKMP_C
3476 isakmp_printpacket(buf
, iph1
->remote
, iph1
->local
, 1);
3482 if (error
&& buf
!= NULL
) {
3496 oakley_do_decrypt(phase1_handle_t
*iph1
, vchar_t
*msg
, vchar_t
*ivdp
, vchar_t
*ivep
)
3498 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
3499 return(oakley_do_ikev1_decrypt(iph1
, msg
, ivdp
, ivep
));
3501 plog(ASL_LEVEL_ERR
, "Failed to decrypt invalid IKE version");
3509 oakley_do_ikev1_encrypt(phase1_handle_t
*iph1
, vchar_t
*msg
, vchar_t
*ivep
, vchar_t
*ivp
)
3511 vchar_t
*buf
= 0, *new = 0;
3518 plog(ASL_LEVEL_DEBUG
, "Begin encryption.\n");
3520 /* set cbc block length */
3521 blen
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3524 "Invalid encryption algorithm %d.\n",
3525 iph1
->approval
->enctype
);
3529 pl
= msg
->v
+ sizeof(struct isakmp
);
3530 len
= msg
->l
- sizeof(struct isakmp
);
3533 padlen
= oakley_padlen(len
, blen
);
3534 plog(ASL_LEVEL_DEBUG
, "pad length = %u\n", padlen
);
3537 buf
= vmalloc(len
+ padlen
);
3540 "Failed to get buffer to encrypt.\n");
3545 char *p
= &buf
->v
[len
];
3546 if (lcconf
->pad_random
) {
3547 for (i
= 0; i
< padlen
; i
++)
3548 *p
++ = eay_random() & 0xff;
3551 memcpy(buf
->v
, pl
, len
);
3553 /* make pad into tail */
3554 if (lcconf
->pad_excltail
)
3555 buf
->v
[len
+ padlen
- 1] = padlen
- 1;
3557 buf
->v
[len
+ padlen
- 1] = padlen
;
3559 plogdump(ASL_LEVEL_DEBUG
, buf
->v
, buf
->l
, "About to encrypt %d bytes", buf
->l
);
3562 new = alg_oakley_encdef_encrypt(iph1
->approval
->enctype
,
3563 buf
, iph1
->key
, ivep
);
3566 "Encryption %d failed.\n", iph1
->approval
->enctype
);
3569 //plogdump(ASL_LEVEL_DEBUG, iph1->key->v, iph1->key->l, "with key:\n");
3576 //plogdump(ASL_LEVEL_DEBUG, ivep->v, ivep->l, "encrypted payload by IV:\n");
3578 /* save IV for next */
3579 memset(ivp
->v
, 0, ivp
->l
);
3580 memcpy(ivp
->v
, (caddr_t
)&new->v
[new->l
- blen
], blen
);
3582 //plogdump(ASL_LEVEL_DEBUG, ivp->v, ivp->l, "save IV for next:\n");
3584 /* create new buffer */
3585 len
= sizeof(struct isakmp
) + new->l
;
3589 "Failed to get buffer to encrypt.\n");
3592 memcpy(buf
->v
, msg
->v
, sizeof(struct isakmp
));
3593 memcpy(buf
->v
+ sizeof(struct isakmp
), new->v
, new->l
);
3594 ((struct isakmp
*)buf
->v
)->len
= htonl(buf
->l
);
3598 plog(ASL_LEVEL_DEBUG
, "Encrypted.\n");
3601 if (error
&& buf
!= NULL
) {
3616 oakley_do_encrypt(phase1_handle_t
*iph1
, vchar_t
*msg
, vchar_t
*ivep
, vchar_t
*ivp
)
3618 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
3619 return(oakley_do_ikev1_encrypt(iph1
, msg
, ivep
, ivp
));
3621 plog(ASL_LEVEL_ERR
, "Failed to encrypt invalid IKE version");
3625 /* culculate padding length */
3627 oakley_padlen(int len
, int base
)
3631 padlen
= base
- (len
% base
);
3633 if (lcconf
->pad_randomlen
)
3634 padlen
+= ((eay_random() % (lcconf
->pad_maxsize
+ 1) + 1) *
3640 /* -----------------------------------------------------------------------------
3641 The base-64 encoding packs three 8-bit bytes into four 7-bit ASCII
3642 characters. If the number of bytes in the original data isn't divisable
3643 by three, "=" characters are used to pad the encoded data. The complete
3644 set of characters used in base-64 are:
3652 ----------------------------------------------------------------------------- */
3653 static const signed char base64_DecodeTable
[128] = {
3654 /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
3655 /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
3656 /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
3657 /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
3658 /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
3659 /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
3660 /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
3661 /* '8' */ 60, 61, -1, -1, -1, 0, -1, -1,
3662 /* '@' */ -1, 0, 1, 2, 3, 4, 5, 6,
3663 /* 'H' */ 7, 8, 9, 10, 11, 12, 13, 14,
3664 /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
3665 /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
3666 /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
3667 /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
3668 /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
3669 /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
3672 static int base64toCFData(vchar_t
*textin
, CFDataRef
*dataRef
)
3680 uint8_t *textcur
= (__typeof__(textcur
))textin
->v
;
3681 int len
= textin
->l
;
3684 tmpbuf
= malloc(len
); // len of result will be less than encoded len
3685 if (tmpbuf
== NULL
) {
3686 yyerror("memory error - could not allocate buffer for certificate reference conversion from base-64.");
3690 for (i
= 0; i
< len
; i
++) {
3694 else if (!isspace(c
))
3696 if (base64_DecodeTable
[c
] < 0)
3700 acc
+= base64_DecodeTable
[c
];
3701 if (0 == (cntr
& 0x3)) {
3702 tmpbuf
[tmpbufpos
++] = (acc
>> 16) & 0xff;
3704 tmpbuf
[tmpbufpos
++] = (acc
>> 8) & 0xff;
3706 tmpbuf
[tmpbufpos
++] = acc
& 0xff;
3709 *dataRef
= CFDataCreate(NULL
, tmpbuf
, tmpbufpos
);