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>
71 #include "isakmp_var.h"
74 #include "isakmp_xauth.h"
75 #include "isakmp_cfg.h"
78 #include "localconf.h"
81 #include "ipsec_doi.h"
82 #include "algorithm.h"
86 #include "crypto_openssl.h"
87 #include "crypto_cssm.h"
94 #include <CoreFoundation/CoreFoundation.h>
95 #include "remoteconf.h"
96 #include "vpn_control.h"
98 #include <Security/SecCertificate.h>
99 #include <Security/SecCertificatePriv.h>
101 #include "vpn_control_var.h"
104 #define OUTBOUND_SA 0
107 #define CERT_CHECKID_FROM_PEER 0
108 #define CERT_CHECKID_FROM_RMCONFIG 1
111 #define INITDHVAL(a, s, d, t) \
114 buf.v = str2val((s), 16, &buf.l); \
115 memset(&a, 0, sizeof(struct dhgroup)); \
117 a.prime = vdup(&buf); \
120 racoon_free(buf.v); \
122 #else /* HAVE_OPENSSL */
123 #define INITDHVAL(a, s, d, t) \
126 buf.v = str2val((s), 16, &buf.l); \
127 memset(&a, 0, sizeof(struct dhgroup)); \
130 a.prime = vdup(&buf); \
133 racoon_free(buf.v); \
135 #endif /* HAVE_OPENSSL */
137 struct dhgroup dh_modp768
;
138 struct dhgroup dh_modp1024
;
139 struct dhgroup dh_modp1536
;
140 struct dhgroup dh_modp2048
;
141 struct dhgroup dh_modp3072
;
142 struct dhgroup dh_modp4096
;
143 struct dhgroup dh_modp6144
;
144 struct dhgroup dh_modp8192
;
147 static int oakley_check_dh_pub (vchar_t
*, vchar_t
**);
148 static int oakley_compute_keymat_x (phase2_handle_t
*, int, int);
149 static int get_cert_fromlocal (phase1_handle_t
*, int);
150 static int oakley_check_certid (phase1_handle_t
*iph1
);
151 static int oakley_check_certid_1 (vchar_t
*, int, int, void*, cert_status_t
*certStatus
);
153 static int check_typeofcertname (int, int);
155 static cert_t
*save_certbuf (struct isakmp_gen
*);
156 static int oakley_padlen (int, int);
158 static int base64toCFData (vchar_t
*, CFDataRef
*);
159 static cert_t
*oakley_appendcert_to_certchain (cert_t
*, cert_t
*);
162 oakley_get_defaultlifetime()
164 return OAKLEY_ATTR_SA_LD_SEC_DEFAULT
;
171 INITDHVAL(dh_modp768
, OAKLEY_PRIME_MODP768
,
172 OAKLEY_ATTR_GRP_DESC_MODP768
, OAKLEY_ATTR_GRP_TYPE_MODP
);
173 INITDHVAL(dh_modp1024
, OAKLEY_PRIME_MODP1024
,
174 OAKLEY_ATTR_GRP_DESC_MODP1024
, OAKLEY_ATTR_GRP_TYPE_MODP
);
175 INITDHVAL(dh_modp1536
, OAKLEY_PRIME_MODP1536
,
176 OAKLEY_ATTR_GRP_DESC_MODP1536
, OAKLEY_ATTR_GRP_TYPE_MODP
);
177 INITDHVAL(dh_modp2048
, OAKLEY_PRIME_MODP2048
,
178 OAKLEY_ATTR_GRP_DESC_MODP2048
, OAKLEY_ATTR_GRP_TYPE_MODP
);
179 INITDHVAL(dh_modp3072
, OAKLEY_PRIME_MODP3072
,
180 OAKLEY_ATTR_GRP_DESC_MODP3072
, OAKLEY_ATTR_GRP_TYPE_MODP
);
181 INITDHVAL(dh_modp4096
, OAKLEY_PRIME_MODP4096
,
182 OAKLEY_ATTR_GRP_DESC_MODP4096
, OAKLEY_ATTR_GRP_TYPE_MODP
);
183 INITDHVAL(dh_modp6144
, OAKLEY_PRIME_MODP6144
,
184 OAKLEY_ATTR_GRP_DESC_MODP6144
, OAKLEY_ATTR_GRP_TYPE_MODP
);
185 INITDHVAL(dh_modp8192
, OAKLEY_PRIME_MODP8192
,
186 OAKLEY_ATTR_GRP_DESC_MODP8192
, OAKLEY_ATTR_GRP_TYPE_MODP
);
192 oakley_dhgrp_free(struct dhgroup
*dhgrp
)
194 VPTRINIT(dhgrp
->prime
);
195 VPTRINIT(dhgrp
->curve_a
);
196 VPTRINIT(dhgrp
->curve_b
);
197 VPTRINIT(dhgrp
->order
);
203 * The length of the Diffie-Hellman public value MUST be equal to the
204 * length of the prime modulus over which the exponentiation was
205 * performed, prepending zero bits to the value if necessary.
208 oakley_check_dh_pub(vchar_t
*prime
, vchar_t
**pub0
)
211 vchar_t
*pub
= *pub0
;
213 if (prime
->l
== pub
->l
)
216 if (prime
->l
< pub
->l
) {
217 /* what should i do ? */
219 "invalid public information was generated.\n");
223 /* prime->l > pub->l */
224 tmp
= vmalloc(prime
->l
);
227 "failed to get DH buffer.\n");
230 memcpy(tmp
->v
+ prime
->l
- pub
->l
, pub
->v
, pub
->l
);
239 * compute sharing secret of DH
240 * IN: *dh, *pub, *priv, *pub_p
245 oakley_dh_compute(const struct dhgroup
*dh
, vchar_t
*pub
, vchar_t
*priv
, vchar_t
*pub_p
, vchar_t
**gxy
)
248 struct timeval start
, end
;
250 if ((*gxy
= vmalloc(dh
->prime
->l
)) == NULL
) {
252 "failed to get DH buffer.\n");
257 gettimeofday(&start
, NULL
);
260 case OAKLEY_ATTR_GRP_TYPE_MODP
:
261 if (eay_dh_compute(dh
->prime
, dh
->gen1
, pub
, priv
, pub_p
, gxy
) < 0) {
263 "failed to compute dh value.\n");
267 case OAKLEY_ATTR_GRP_TYPE_ECP
:
268 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
270 "dh type %d isn't supported.\n", dh
->type
);
274 "invalid dh type %d.\n", dh
->type
);
279 gettimeofday(&end
, NULL
);
280 plog(ASL_LEVEL_NOTICE
, "%s(%s%d): %8.6f", __func__
,
281 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
282 timedelta(&start
, &end
));
285 plog(ASL_LEVEL_DEBUG
, "compute DH's shared.\n");
291 oakley_dh_compute(const struct dhgroup
*dh
, vchar_t
*pub_p
, size_t publicKeySize
, vchar_t
**gxy
, SecDHContext
*dhC
)
294 vchar_t
*computed_key
= NULL
;
295 size_t computed_keylen
;
299 struct timeval start
, end
;
300 gettimeofday(&start
, NULL
);
303 plog(ASL_LEVEL_DEBUG
, "compute DH result.\n");
305 maxKeyLen
= SecDHGetMaxKeyLength(*dhC
);
306 computed_key
= vmalloc(maxKeyLen
);
307 if (computed_key
== NULL
) {
308 plog(ASL_LEVEL_ERR
, "memory error.\n");
311 computed_keylen
= computed_key
->l
;
312 if (SecDHComputeKey(*dhC
, (uint8_t*)pub_p
->v
+ (maxKeyLen
- publicKeySize
), publicKeySize
,
313 (uint8_t*)computed_key
->v
, &computed_keylen
)) {
314 plog(ASL_LEVEL_ERR
, "failed to compute dh value.\n");
319 gettimeofday(&end
, NULL
);
320 plog(ASL_LEVEL_NOTICE
, "%s(%s%d): %8.6f", __func__
,
321 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
322 timedelta(&start
, &end
));
325 *gxy
= vmalloc(maxKeyLen
);
327 plog(ASL_LEVEL_ERR
, "memory error.\n");
330 memcpy((*gxy
)->v
+ (maxKeyLen
- computed_keylen
), computed_key
->v
, computed_keylen
);
331 plog(ASL_LEVEL_DEBUG
, "compute DH's shared.\n");
352 * generate values of DH
358 oakley_dh_generate(const struct dhgroup
*dh
, vchar_t
**pub
, vchar_t
**priv
)
361 struct timeval start
, end
;
362 gettimeofday(&start
, NULL
);
365 case OAKLEY_ATTR_GRP_TYPE_MODP
:
366 if (eay_dh_generate(dh
->prime
, dh
->gen1
, dh
->gen2
, pub
, priv
) < 0) {
368 "failed to compute dh value.\n");
373 case OAKLEY_ATTR_GRP_TYPE_ECP
:
374 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
376 "dh type %d isn't supported.\n", dh
->type
);
380 "invalid dh type %d.\n", dh
->type
);
385 gettimeofday(&end
, NULL
);
386 plog(ASL_LEVEL_NOTICE
, "%s(%s%d): %8.6f", __func__
,
387 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
388 timedelta(&start
, &end
));
391 if (oakley_check_dh_pub(dh
->prime
, pub
) != 0)
394 plog(ASL_LEVEL_DEBUG
, "compute DH's private.\n");
395 plog(ASL_LEVEL_DEBUG
, "compute DH's public.\n");
401 oakley_dh_generate(const struct dhgroup
*dh
, vchar_t
**pub
, size_t *publicKeySize
, SecDHContext
*dhC
)
403 vchar_t
*public = NULL
;
407 struct timeval start
, end
;
408 gettimeofday(&start
, NULL
);
411 plog(ASL_LEVEL_DEBUG
, "generate DH key pair.\n");
414 case OAKLEY_ATTR_GRP_TYPE_MODP
:
415 #define SECDH_MODP_GENERATOR 2
416 if (SecDHCreate(SECDH_MODP_GENERATOR
, (uint8_t*)dh
->prime
->v
, dh
->prime
->l
, 0, NULL
, 0, dhC
)) {
417 plog(ASL_LEVEL_ERR
, "failed to create dh context.\n");
420 maxKeyLen
= SecDHGetMaxKeyLength(*dhC
);
421 public = vmalloc(maxKeyLen
);
422 *publicKeySize
= public->l
;
423 if (public == NULL
) {
424 plog(ASL_LEVEL_ERR
, "memory error.\n");
427 if (SecDHGenerateKeypair(*dhC
, (uint8_t*)public->v
, publicKeySize
)) {
428 plog(ASL_LEVEL_ERR
, "failed to generate dh key pair.\n");
431 plog(ASL_LEVEL_DEBUG
, "got DH key pair.\n");
433 *pub
= vmalloc(maxKeyLen
);
435 plog(ASL_LEVEL_ERR
, "memory error.\n");
438 /* copy and fill with leading zeros */
439 memcpy((*pub
)->v
+ (maxKeyLen
- *publicKeySize
), public->v
, *publicKeySize
);
442 case OAKLEY_ATTR_GRP_TYPE_ECP
:
443 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
445 "dh type %d isn't supported.\n", dh
->type
);
449 "invalid dh type %d.\n", dh
->type
);
454 gettimeofday(&end
, NULL
);
455 plog(ASL_LEVEL_NOTICE
, "%s(%s%d): %8.6f", __func__
,
456 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
457 timedelta(&start
, &end
));
460 if (oakley_check_dh_pub(dh
->prime
, pub
) != 0) {
461 plog(ASL_LEVEL_DEBUG
, "failed DH public key size check.\n");
465 //plogdump(ASL_LEVEL_DEBUG, (*pub)->v, (*pub)->l, "compute DH's public.\n");
483 * copy pre-defined dhgroup values.
486 oakley_setdhgroup(int group
, struct dhgroup
**dhgrp
)
490 *dhgrp
= NULL
; /* just make sure, initialize */
492 g
= alg_oakley_dhdef_group(group
);
495 "invalid DH parameter grp=%d.\n", group
);
499 if (!g
->type
|| !g
->prime
|| !g
->gen1
) {
502 "unsupported DH parameters grp=%d.\n", group
);
506 *dhgrp
= racoon_calloc(1, sizeof(struct dhgroup
));
507 if (*dhgrp
== NULL
) {
509 "failed to get DH buffer.\n");
513 /* set defined dh vlaues */
514 memcpy(*dhgrp
, g
, sizeof(*g
));
515 (*dhgrp
)->prime
= vdup(g
->prime
);
523 * NOTE: we do not support prf with different input/output bitwidth,
524 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example) in
525 * oakley_compute_keymat(). If you add support for such prf function,
526 * modify oakley_compute_keymat() accordingly.
529 oakley_prf(vchar_t
*key
, vchar_t
*buf
, phase1_handle_t
*iph1
)
532 int type
= OAKLEY_ATTR_HASH_ALG_MD5
;
534 if (iph1
->approval
== NULL
) {
535 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
537 * it's before negotiating hash algorithm.
538 * We use md5 as default.
540 type
= OAKLEY_ATTR_HASH_ALG_MD5
;
544 type
= iph1
->approval
->hashtype
;
546 res
= alg_oakley_hmacdef_one(type
, key
, buf
);
549 "invalid hmac algorithm %d.\n", type
);
560 oakley_hash(vchar_t
*buf
, phase1_handle_t
*iph1
)
563 int type
= OAKLEY_ATTR_HASH_ALG_MD5
;
565 if (iph1
->approval
== NULL
) {
566 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
568 * it's before negotiating hash algorithm.
569 * We use md5 as default.
571 type
= OAKLEY_ATTR_HASH_ALG_MD5
;
574 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
575 type
= iph1
->approval
->hashtype
;
579 res
= alg_oakley_hashdef_one(type
, buf
);
582 "invalid hash algorithm %d.\n", type
);
591 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
594 oakley_compute_keymat(phase2_handle_t
*iph2
, int side
)
598 /* compute sharing secret of DH when PFS */
599 if (iph2
->approval
->pfs_group
&& iph2
->dhpub_p
) {
601 if (oakley_dh_compute(iph2
->pfsgrp
, iph2
->dhpub
,
602 iph2
->dhpriv
, iph2
->dhpub_p
, &iph2
->dhgxy
) < 0)
604 if (oakley_dh_compute(iph2
->pfsgrp
, iph2
->dhpub_p
, iph2
->publicKeySize
, &iph2
->dhgxy
, &iph2
->dhC
) < 0)
610 if (oakley_compute_keymat_x(iph2
, side
, INBOUND_SA
) < 0
611 || oakley_compute_keymat_x(iph2
, side
, OUTBOUND_SA
) < 0)
614 plog(ASL_LEVEL_DEBUG
, "KEYMAT computed.\n");
624 * KEYMAT = prf(SKEYID_d, protocol | SPI | Ni_b | Nr_b).
625 * If PFS is desired and KE payloads were exchanged,
626 * KEYMAT = prf(SKEYID_d, g(qm)^xy | protocol | SPI | Ni_b | Nr_b)
628 * NOTE: we do not support prf with different input/output bitwidth,
629 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example).
632 oakley_compute_keymat_x(phase2_handle_t
*iph2
, int side
, int sa_dir
)
634 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
639 int dupkeymat
; /* generate K[1-dupkeymat] */
642 int encklen
, authklen
, l
;
644 pfs
= ((iph2
->approval
->pfs_group
&& iph2
->dhgxy
) ? 1 : 0);
646 len
= pfs
? iph2
->dhgxy
->l
: 0;
648 + sizeof(u_int32_t
) /* XXX SPI size */
654 "failed to get keymat buffer.\n");
658 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
663 memcpy(p
, iph2
->dhgxy
->v
, iph2
->dhgxy
->l
);
670 memcpy(p
, (sa_dir
== INBOUND_SA
? &pr
->spi
: &pr
->spi_p
),
672 p
+= sizeof(pr
->spi
);
674 bp
= (side
== INITIATOR
? iph2
->nonce
: iph2
->nonce_p
);
675 memcpy(p
, bp
->v
, bp
->l
);
678 bp
= (side
== INITIATOR
? iph2
->nonce_p
: iph2
->nonce
);
679 memcpy(p
, bp
->v
, bp
->l
);
683 //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "KEYMAT compute with\n");
686 res
= oakley_prf(iph2
->ph1
->skeyid_d
, buf
, iph2
->ph1
);
690 /* compute key length needed */
691 encklen
= authklen
= 0;
692 switch (pr
->proto_id
) {
693 case IPSECDOI_PROTO_IPSEC_ESP
:
694 for (tr
= pr
->head
; tr
; tr
= tr
->next
) {
695 l
= alg_ipsec_encdef_keylen(tr
->trns_id
,
700 l
= alg_ipsec_hmacdef_hashlen(tr
->authtype
);
705 case IPSECDOI_PROTO_IPSEC_AH
:
706 for (tr
= pr
->head
; tr
; tr
= tr
->next
) {
707 l
= alg_ipsec_hmacdef_hashlen(tr
->trns_id
);
715 plog(ASL_LEVEL_DEBUG
, "encklen=%d authklen=%d\n",
718 dupkeymat
= (encklen
+ authklen
) / 8 / res
->l
;
719 dupkeymat
+= 2; /* safety mergin */
722 //plog(ASL_LEVEL_DEBUG,
723 // "generating %zu bits of key (dupkeymat=%d)\n",
724 // dupkeymat * 8 * res->l, dupkeymat);
725 if (0 < --dupkeymat
) {
726 vchar_t
*prev
= res
; /* K(n-1) */
727 vchar_t
*seed
= NULL
; /* seed for Kn */
731 * generating long key (isakmp-oakley-08 5.5)
732 * KEYMAT = K1 | K2 | K3 | ...
734 * src = [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b
735 * K1 = prf(SKEYID_d, src)
736 * K2 = prf(SKEYID_d, K1 | src)
737 * K3 = prf(SKEYID_d, K2 | src)
738 * Kn = prf(SKEYID_d, K(n-1) | src)
740 //plog(ASL_LEVEL_DEBUG,
741 // "generating K1...K%d for KEYMAT.\n",
744 seed
= vmalloc(prev
->l
+ buf
->l
);
747 "failed to get keymat buffer.\n");
748 if (prev
&& prev
!= res
)
753 while (dupkeymat
--) {
754 vchar_t
*this = NULL
; /* Kn */
757 memcpy(seed
->v
, prev
->v
, prev
->l
);
758 memcpy(seed
->v
+ prev
->l
, buf
->v
, buf
->l
);
759 this = oakley_prf(iph2
->ph1
->skeyid_d
, seed
,
763 "oakley_prf memory overflow\n");
764 if (prev
&& prev
!= res
)
771 update_prev
= (prev
&& prev
== res
) ? 1 : 0;
774 res
= vrealloc(res
, l
+ this->l
);
781 "failed to get keymat buffer.\n");
782 if (prev
&& prev
!= res
)
788 memcpy(res
->v
+ l
, this->v
, this->l
);
790 if (prev
&& prev
!= res
)
796 if (prev
&& prev
!= res
)
801 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "");
803 if (sa_dir
== INBOUND_SA
)
814 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
836 * compute HASH(3) prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
837 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
840 oakley_compute_hash3(phase1_handle_t
*iph1
, u_int32_t msgid
, vchar_t
*body
)
842 vchar_t
*buf
= 0, *res
= 0;
847 len
= 1 + sizeof(u_int32_t
) + body
->l
;
850 plog(ASL_LEVEL_NOTICE
,
851 "failed to get hash buffer\n");
857 memcpy(buf
->v
+ 1, (char *)&msgid
, sizeof(msgid
));
859 memcpy(buf
->v
+ 1 + sizeof(u_int32_t
), body
->v
, body
->l
);
862 res
= oakley_prf(iph1
->skeyid_a
, buf
, iph1
);
868 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH computed:\n");
877 * compute HASH type of prf(SKEYID_a, M-ID | buffer)
879 * for quick mode HASH(1):
880 * prf(SKEYID_a, M-ID | SA | Ni [ | KE ] [ | IDci | IDcr ])
881 * for quick mode HASH(2):
882 * prf(SKEYID_a, M-ID | Ni_b | SA | Nr [ | KE ] [ | IDci | IDcr ])
883 * for Informational exchange:
884 * prf(SKEYID_a, M-ID | N/D)
887 oakley_compute_hash1(phase1_handle_t
*iph1
, u_int32_t msgid
, vchar_t
*body
)
889 vchar_t
*buf
= NULL
, *res
= NULL
;
895 len
= sizeof(u_int32_t
) + body
->l
;
898 plog(ASL_LEVEL_NOTICE
,
899 "failed to get hash buffer\n");
905 memcpy(buf
->v
, (char *)&msgid
, sizeof(msgid
));
906 p
+= sizeof(u_int32_t
);
908 memcpy(p
, body
->v
, body
->l
);
911 res
= oakley_prf(iph1
->skeyid_a
, buf
, iph1
);
917 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH computed:\n");
926 * compute phase1 HASH
928 * I-digest = prf(SKEYID, g^i | g^r | CKY-I | CKY-R | SAi_b | ID_i1_b)
929 * R-digest = prf(SKEYID, g^r | g^i | CKY-R | CKY-I | SAi_b | ID_r1_b)
930 * for gssapi, also include all GSS tokens, and call gss_wrap on the result
933 oakley_ph1hash_common(phase1_handle_t
*iph1
, int sw
)
935 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
943 + sizeof(cookie_t
) * 2
945 + (sw
== GENERATE
? iph1
->id
->l
: iph1
->id_p
->l
);
950 "failed to get hash buffer\n");
956 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
957 memcpy(p
, bp
->v
, bp
->l
);
960 bp
= (sw
== GENERATE
? iph1
->dhpub_p
: iph1
->dhpub
);
961 memcpy(p
, bp
->v
, bp
->l
);
964 if (iph1
->side
== INITIATOR
)
965 bp2
= (sw
== GENERATE
?
966 (char *)&iph1
->index
.i_ck
: (char *)&iph1
->index
.r_ck
);
968 bp2
= (sw
== GENERATE
?
969 (char *)&iph1
->index
.r_ck
: (char *)&iph1
->index
.i_ck
);
970 bl
= sizeof(cookie_t
);
974 if (iph1
->side
== INITIATOR
)
975 bp2
= (sw
== GENERATE
?
976 (char *)&iph1
->index
.r_ck
: (char *)&iph1
->index
.i_ck
);
978 bp2
= (sw
== GENERATE
?
979 (char *)&iph1
->index
.i_ck
: (char *)&iph1
->index
.r_ck
);
980 bl
= sizeof(cookie_t
);
985 memcpy(p
, bp
->v
, bp
->l
);
988 bp
= (sw
== GENERATE
? iph1
->id
: iph1
->id_p
);
989 memcpy(p
, bp
->v
, bp
->l
);
993 res
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
1006 * compute HASH_I on base mode.
1008 * HASH_I = prf(SKEYID, g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
1010 * HASH_I = prf(hash(Ni_b | Nr_b), g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
1013 oakley_ph1hash_base_i(phase1_handle_t
*iph1
, int sw
)
1015 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
1016 vchar_t
*hashkey
= NULL
;
1017 vchar_t
*hash
= NULL
; /* for signature mode */
1023 if (iph1
->etype
!= ISAKMP_ETYPE_BASE
) {
1025 "invalid etype for this hash function\n");
1029 switch (AUTHMETHOD(iph1
)) {
1030 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
1031 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
1032 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
1033 #ifdef ENABLE_HYBRID
1034 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
1035 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
1036 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
1037 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
1038 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
1039 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
1041 if (iph1
->skeyid
== NULL
) {
1042 plog(ASL_LEVEL_ERR
, "no SKEYID found.\n");
1045 hashkey
= iph1
->skeyid
;
1048 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1049 #ifdef ENABLE_HYBRID
1050 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1051 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1052 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
1053 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1055 /* make hash for seed */
1056 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
1060 "failed to get hash buffer\n");
1065 bp
= (sw
== GENERATE
? iph1
->nonce_p
: iph1
->nonce
);
1066 memcpy(p
, bp
->v
, bp
->l
);
1069 bp
= (sw
== GENERATE
? iph1
->nonce
: iph1
->nonce_p
);
1070 memcpy(p
, bp
->v
, bp
->l
);
1073 hash
= oakley_hash(buf
, iph1
);
1084 "not supported authentication method %d\n",
1085 iph1
->approval
->authmethod
);
1090 len
= (sw
== GENERATE
? iph1
->dhpub
->l
: iph1
->dhpub_p
->l
)
1091 + sizeof(cookie_t
) * 2
1093 + (sw
== GENERATE
? iph1
->id
->l
: iph1
->id_p
->l
);
1097 "failed to get hash buffer\n");
1102 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
1103 memcpy(p
, bp
->v
, bp
->l
);
1106 memcpy(p
, &iph1
->index
.i_ck
, sizeof(cookie_t
));
1107 p
+= sizeof(cookie_t
);
1108 memcpy(p
, &iph1
->index
.r_ck
, sizeof(cookie_t
));
1109 p
+= sizeof(cookie_t
);
1111 memcpy(p
, iph1
->sa
->v
, iph1
->sa
->l
);
1114 bp
= (sw
== GENERATE
? iph1
->id
: iph1
->id_p
);
1115 memcpy(p
, bp
->v
, bp
->l
);
1118 //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "HASH_I with:\n");
1121 res
= oakley_prf(hashkey
, buf
, iph1
);
1127 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH_I computed:\n");
1138 * compute HASH_R on base mode for signature method.
1140 * HASH_R = prf(hash(Ni_b | Nr_b), g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b)
1143 oakley_ph1hash_base_r(phase1_handle_t
*iph1
, int sw
)
1145 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
1146 vchar_t
*hash
= NULL
;
1152 if (iph1
->etype
!= ISAKMP_ETYPE_BASE
) {
1154 "invalid etype for this hash function\n");
1158 switch(AUTHMETHOD(iph1
)) {
1159 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1160 #ifdef ENABLE_HYBRID
1161 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1162 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1163 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
1164 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1165 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
1170 "not supported authentication method %d\n",
1171 iph1
->approval
->authmethod
);
1176 /* make hash for seed */
1177 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
1181 "failed to get hash buffer\n");
1186 bp
= (sw
== GENERATE
? iph1
->nonce_p
: iph1
->nonce
);
1187 memcpy(p
, bp
->v
, bp
->l
);
1190 bp
= (sw
== GENERATE
? iph1
->nonce
: iph1
->nonce_p
);
1191 memcpy(p
, bp
->v
, bp
->l
);
1194 hash
= oakley_hash(buf
, iph1
);
1200 /* make really hash */
1201 len
= (sw
== GENERATE
? iph1
->dhpub_p
->l
: iph1
->dhpub
->l
)
1202 + (sw
== GENERATE
? iph1
->dhpub
->l
: iph1
->dhpub_p
->l
)
1203 + sizeof(cookie_t
) * 2
1205 + (sw
== GENERATE
? iph1
->id_p
->l
: iph1
->id
->l
);
1209 "failed to get hash buffer\n");
1215 bp
= (sw
== GENERATE
? iph1
->dhpub_p
: iph1
->dhpub
);
1216 memcpy(p
, bp
->v
, bp
->l
);
1219 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
1220 memcpy(p
, bp
->v
, bp
->l
);
1223 memcpy(p
, &iph1
->index
.i_ck
, sizeof(cookie_t
));
1224 p
+= sizeof(cookie_t
);
1225 memcpy(p
, &iph1
->index
.r_ck
, sizeof(cookie_t
));
1226 p
+= sizeof(cookie_t
);
1228 memcpy(p
, iph1
->sa
->v
, iph1
->sa
->l
);
1231 bp
= (sw
== GENERATE
? iph1
->id_p
: iph1
->id
);
1232 memcpy(p
, bp
->v
, bp
->l
);
1235 //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "HASH_R with:\n");
1238 res
= oakley_prf(hash
, buf
, iph1
);
1244 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH_R computed:\n");
1256 oakley_verify_userid(phase1_handle_t
*iph1
)
1260 int user_id_found
= 0;
1261 #ifndef HAVE_OPENSSL
1262 SecCertificateRef certificate
;
1263 CFArrayRef commonNames
;
1266 #endif /* HAVE_OPENSSL */
1268 for (p
= iph1
->cert_p
; p
; p
= p
->chain
) {
1270 user_id
= eay_get_x509_common_name(&p
->cert
); //%%%%%%%% fix this
1273 // the following functions will check if user_id == 0
1274 if (open_dir_authorize_id(user_id
, iph1
->rmconf
->open_dir_auth_group
)) {
1280 #else /* HAVE_OPENSSL */
1281 certificate
= crypto_cssm_x509cert_CreateSecCertificateRef(&p
->cert
);
1282 if (certificate
== NULL
) {
1284 "ovuid failed to get SecCertificateRef\n");
1288 commonNames
= SecCertificateCopyCommonNames(certificate
);
1289 if (commonNames
== NULL
) {
1291 "ovuid failed to get commonNames\n");
1292 CFRelease(certificate
);
1296 l
= CFArrayGetCount(commonNames
);
1297 for (i
= 0; i
< l
; i
++) {
1298 name
= CFArrayGetValueAtIndex(commonNames
, i
);
1299 user_id
= vmalloc(CFStringGetMaximumSizeForEncoding(CFStringGetLength(name
),
1300 kCFStringEncodingUTF8
) + 1);
1302 if (CFStringGetCString(name
, user_id
->v
, user_id
->l
,
1303 kCFStringEncodingUTF8
)) {
1305 // the following functions will check if user_id == 0
1306 if (open_dir_authorize_id(user_id
, iph1
->rmconf
->open_dir_auth_group
)) {
1308 CFRelease(certificate
);
1309 CFRelease(commonNames
);
1316 CFRelease(certificate
);
1317 CFRelease(commonNames
);
1318 #endif /* HAVE_OPENSSL */
1320 if (user_id_found
) {
1322 "the peer is not authorized for access.\n");
1325 "the peer is not authorized for access - user ID not found.\n");
1327 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1329 #endif /* HAVE_OPENDIR */
1332 * compute each authentication method in phase 1.
1336 * other: error to be reply with notification.
1337 * the value is notification type.
1340 oakley_validate_auth(phase1_handle_t
*iph1
)
1342 vchar_t
*my_hash
= NULL
;
1345 struct timeval start
, end
;
1347 SecKeyRef publicKeyRef
= NULL
;
1350 gettimeofday(&start
, NULL
);
1353 switch (AUTHMETHOD(iph1
)) {
1354 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
1355 #ifdef ENABLE_HYBRID
1356 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
1357 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
1363 if (iph1
->id_p
== NULL
|| iph1
->pl_hash
== NULL
) {
1365 "few isakmp message received.\n");
1366 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1368 #ifdef ENABLE_HYBRID
1369 if (AUTHMETHOD(iph1
) == FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
&&
1370 ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_VENDORID_XAUTH
) == 0))
1372 plog(ASL_LEVEL_ERR
, "No SIG was passed, "
1373 "hybrid auth is enabled, "
1374 "but peer is no Xauth compliant\n");
1375 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED
;
1379 r_hash
= (caddr_t
)(iph1
->pl_hash
+ 1);
1381 //plogdump(ASL_LEVEL_DEBUG, r_hash,
1382 // ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash), "HASH received:\n");
1384 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
1385 switch (iph1
->etype
) {
1386 case ISAKMP_ETYPE_IDENT
:
1387 case ISAKMP_ETYPE_AGG
:
1388 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1390 case ISAKMP_ETYPE_BASE
:
1391 if (iph1
->side
== INITIATOR
)
1392 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1394 my_hash
= oakley_ph1hash_base_i(iph1
, VALIDATE
);
1398 "invalid etype %d\n", iph1
->etype
);
1399 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1402 if (my_hash
== NULL
)
1403 return ISAKMP_INTERNAL_ERROR
;
1405 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1409 plog(ASL_LEVEL_ERR
, "HASH mismatched\n");
1410 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1413 plog(ASL_LEVEL_DEBUG
, "HASH for PSK validated.\n");
1416 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1417 #ifdef ENABLE_HYBRID
1418 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1419 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
1420 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1427 if (iph1
->id_p
== NULL
) {
1429 "no ID payload was passed.\n");
1430 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1432 if (iph1
->sig_p
== NULL
) {
1434 "no SIG payload was passed.\n");
1435 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1438 plog(ASL_LEVEL_DEBUG
, "SIGN passed\n");
1440 /* get peer's cert */
1441 switch (iph1
->rmconf
->getcert_method
) {
1442 case ISAKMP_GETCERT_PAYLOAD
:
1443 if (iph1
->cert_p
== NULL
) {
1445 "no peer's CERT payload found.\n");
1446 return ISAKMP_INTERNAL_ERROR
;
1451 "invalid getcert_mothod: %d\n",
1452 iph1
->rmconf
->getcert_method
);
1453 return ISAKMP_INTERNAL_ERROR
;
1456 /* compare ID payload and certificate name */
1457 if (iph1
->rmconf
->verify_cert
&&
1458 (error
= oakley_check_certid(iph1
)) != 0)
1462 /* check cert common name against Open Directory authentication group */
1463 if (iph1
->rmconf
->cert_verification_option
== VERIFICATION_OPTION_OPEN_DIR
) {
1464 if (oakley_verify_userid(iph1
)) {
1465 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1468 #endif /* HAVE_OPENDIR */
1470 /* verify certificate */
1471 if (iph1
->rmconf
->verify_cert
1472 && iph1
->rmconf
->getcert_method
== ISAKMP_GETCERT_PAYLOAD
) {
1473 certtype
= iph1
->rmconf
->certtype
;
1474 #ifdef ENABLE_HYBRID
1475 switch (AUTHMETHOD(iph1
)) {
1476 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1477 certtype
= iph1
->cert_p
->type
;
1484 case ISAKMP_CERT_X509SIGN
:
1486 /* use ID from remote configuration */
1487 /* check each ID in list */
1488 struct idspec
*id_spec
;
1489 CFStringRef hostname
= NULL
;
1491 struct genlist_entry
*gpb
= NULL
;
1493 if (iph1
->rmconf
->cert_verification_option
== VERIFICATION_OPTION_PEERS_IDENTIFIER
) {
1494 id_spec
= genlist_next(iph1
->rmconf
->idvl_p
, &gpb
); /* expect only one id */
1495 if (id_spec
->idtype
== IDTYPE_ADDRESS
) {
1496 switch ((ALIGNED_CAST(struct sockaddr_storage
*)(id_spec
->id
->v
))->ss_family
) {
1498 peers_id
= inet_ntoa((ALIGNED_CAST(struct sockaddr_in
*)(id_spec
->id
->v
))->sin_addr
);
1499 hostname
= CFStringCreateWithCString(NULL
, peers_id
, kCFStringEncodingUTF8
);
1503 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
; /* not currently supported for embedded */
1508 "unknown address type for peers identifier.\n");
1509 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1513 hostname
= CFStringCreateWithBytes(NULL
, (u_int8_t
*)id_spec
->id
->v
, id_spec
->id
->l
, kCFStringEncodingUTF8
, FALSE
);
1515 if (hostname
== NULL
) {
1516 plog(ASL_LEVEL_ERR
, "missing hostname for peers identifier.\n");
1517 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1520 error
= crypto_cssm_check_x509cert(oakley_get_peer_cert_from_certchain(iph1
), iph1
->cert_p
, hostname
, &publicKeyRef
);
1522 CFRelease(hostname
);
1528 "no supported certtype %d\n", certtype
);
1529 return ISAKMP_INTERNAL_ERROR
;
1533 "the peer's certificate is not verified.\n");
1534 return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY
;
1538 plog(ASL_LEVEL_DEBUG
, "CERT validated\n");
1540 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
1542 switch (iph1
->etype
) {
1543 case ISAKMP_ETYPE_IDENT
:
1544 case ISAKMP_ETYPE_AGG
:
1545 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1547 case ISAKMP_ETYPE_BASE
:
1548 if (iph1
->side
== INITIATOR
)
1549 my_hash
= oakley_ph1hash_base_r(iph1
, VALIDATE
);
1551 my_hash
= oakley_ph1hash_base_i(iph1
, VALIDATE
);
1555 "invalid etype %d\n", iph1
->etype
);
1556 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1559 if (my_hash
== NULL
)
1560 return ISAKMP_INTERNAL_ERROR
;
1563 certtype
= iph1
->rmconf
->certtype
;
1564 #ifdef ENABLE_HYBRID
1565 switch (AUTHMETHOD(iph1
)) {
1566 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1567 certtype
= iph1
->cert_p
->type
;
1573 /* check signature */
1575 case ISAKMP_CERT_X509SIGN
:
1576 if (publicKeyRef
== NULL
) {
1577 plog(ASL_LEVEL_ERR
, "@@@@@@ publicKeyRef is NULL\n");
1579 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
1580 error
= crypto_cssm_verify_x509sign(publicKeyRef
, my_hash
, iph1
->sig_p
, FALSE
);
1583 plog(ASL_LEVEL_ERR
, "error verifying signature %s\n", GetSecurityErrorString(error
));
1586 CFRelease(publicKeyRef
);
1590 "no supported certtype %d\n",
1593 return ISAKMP_INTERNAL_ERROR
;
1600 return ISAKMP_NTYPE_INVALID_SIGNATURE
;
1602 plog(ASL_LEVEL_DEBUG
, "SIG authenticated\n");
1605 #ifdef ENABLE_HYBRID
1606 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1608 if ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_VENDORID_XAUTH
) == 0) {
1609 plog(ASL_LEVEL_ERR
, "No SIG was passed, "
1610 "hybrid auth is enabled, "
1611 "but peer is no Xauth compliant\n");
1612 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED
;
1615 plog(ASL_LEVEL_NOTICE
, "No SIG was passed, "
1616 "but hybrid auth is enabled\n");
1622 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
1623 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
1624 #ifdef ENABLE_HYBRID
1625 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
1626 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
1627 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
1628 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
1630 if (iph1
->id_p
== NULL
|| iph1
->pl_hash
== NULL
) {
1632 "few isakmp message received.\n");
1633 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1636 "not supported authmethod type %s\n",
1637 s_oakley_attr_method(iph1
->approval
->authmethod
));
1638 return ISAKMP_INTERNAL_ERROR
;
1641 "invalid authmethod %d why ?\n",
1642 iph1
->approval
->authmethod
);
1643 return ISAKMP_INTERNAL_ERROR
;
1646 gettimeofday(&end
, NULL
);
1647 plog(ASL_LEVEL_NOTICE
, "%s(%s): %8.6f", __func__
,
1648 s_oakley_attr_method(iph1
->approval
->authmethod
),
1649 timedelta(&start
, &end
));
1656 oakley_find_status_in_certchain (cert_t
*certchain
, cert_status_t certStatus
)
1660 for (p
= certchain
; p
; p
= p
->chain
) {
1661 if (p
->status
== certStatus
) {
1670 oakley_vpncontrol_notify_ike_failed_if_mycert_invalid (phase1_handle_t
*iph1
, int notify_initiator
)
1672 #ifndef HAVE_OPENSSL
1673 int premature
= oakley_find_status_in_certchain(iph1
->cert
, CERT_STATUS_PREMATURE
);
1674 int expired
= oakley_find_status_in_certchain(iph1
->cert
, CERT_STATUS_EXPIRED
);
1675 if (premature
|| expired
) {
1676 u_int32_t fail_reason
;
1679 fail_reason
= VPNCTL_NTYPE_LOCAL_CERT_PREMATURE
;
1681 fail_reason
= VPNCTL_NTYPE_LOCAL_CERT_EXPIRED
;
1683 vpncontrol_notify_ike_failed(fail_reason
, notify_initiator
, iph1_get_remote_v4_address(iph1
), 0, NULL
);
1686 #endif /* HAVE_OPENSSL */
1690 /* get my certificate
1691 * NOTE: include certificate type.
1694 oakley_getmycert(phase1_handle_t
*iph1
)
1698 switch (iph1
->rmconf
->certtype
) {
1699 case ISAKMP_CERT_X509SIGN
:
1702 if ( !(err
= get_cert_fromlocal(iph1
, 1))){
1703 if (oakley_vpncontrol_notify_ike_failed_if_mycert_invalid(iph1
, FROM_LOCAL
)) {
1710 "Unknown certtype #%d\n",
1711 iph1
->rmconf
->certtype
);
1718 * get a CERT from local file.
1721 * my == 0 peer's cert.
1724 get_cert_fromlocal(phase1_handle_t
*iph1
, int my
)
1726 vchar_t
*cert
= NULL
;
1729 cert_status_t status
= CERT_STATUS_OK
;
1732 certpl
= &iph1
->cert
;
1734 certpl
= &iph1
->cert_p
;
1735 if (iph1
->rmconf
->identity_in_keychain
== 0) {
1736 plog(ASL_LEVEL_ERR
, "no CERT defined.\n");
1740 switch (iph1
->rmconf
->certtype
) {
1741 case ISAKMP_CERT_X509SIGN
:
1742 if (iph1
->rmconf
->identity_in_keychain
) {
1745 if (iph1
->rmconf
->keychainCertRef
== NULL
|| base64toCFData(iph1
->rmconf
->keychainCertRef
, &dataRef
))
1747 cert
= crypto_cssm_get_x509cert(dataRef
, &status
);
1748 plog(ASL_LEVEL_DEBUG
, "done with chking cert status %d\n",status
);
1754 "not supported certtype %d\n",
1755 iph1
->rmconf
->certtype
);
1761 "failed to get %s CERT.\n",
1762 my
? "my" : "peers");
1766 *certpl
= oakley_newcert();
1769 "failed to get cert buffer.\n");
1772 (*certpl
)->pl
= vmalloc(cert
->l
+ 1);
1773 if ((*certpl
)->pl
== NULL
) {
1775 "failed to get cert buffer\n");
1776 oakley_delcert(*certpl
);
1780 memcpy((*certpl
)->pl
->v
+ 1, cert
->v
, cert
->l
);
1781 (*certpl
)->pl
->v
[0] = iph1
->rmconf
->certtype
;
1782 (*certpl
)->type
= iph1
->rmconf
->certtype
;
1783 (*certpl
)->status
= status
;
1784 (*certpl
)->cert
.v
= (*certpl
)->pl
->v
+ 1;
1785 (*certpl
)->cert
.l
= (*certpl
)->pl
->l
- 1;
1787 plog(ASL_LEVEL_DEBUG
, "created CERT payload\n");
1801 oakley_getsign(phase1_handle_t
*iph1
)
1803 vchar_t
*privkey
= NULL
;
1806 switch (iph1
->rmconf
->certtype
) {
1807 case ISAKMP_CERT_X509SIGN
:
1808 // cert in keychain - use cssm to sign
1809 if (iph1
->rmconf
->identity_in_keychain
) {
1812 if (iph1
->rmconf
->keychainCertRef
== NULL
|| base64toCFData(iph1
->rmconf
->keychainCertRef
, &dataRef
))
1814 iph1
->sig
= crypto_cssm_getsign(dataRef
, iph1
->hash
);
1820 "Unknown certtype #%d\n",
1821 iph1
->rmconf
->certtype
);
1825 if (iph1
->sig
== NULL
) {
1826 plog(ASL_LEVEL_ERR
, "failed to sign.\n");
1830 //plogdump(ASL_LEVEL_DEBUG, iph1->sig->v, iph1->sig->l, "SIGN computed:\n");
1835 if (privkey
!= NULL
)
1842 oakley_verify_certid(phase1_handle_t
*iph1
)
1844 if (iph1
->rmconf
->verify_cert
&&
1845 oakley_check_certid(iph1
)){
1846 plog(ASL_LEVEL_DEBUG
,
1847 "Discarding CERT: does not match ID:\n");
1848 oakley_delcert(iph1
->cert_p
);
1849 iph1
->cert_p
= NULL
;
1854 oakley_check_certid_in_certchain(cert_t
*certchain
, int idtype
, int idlen
, void *id
)
1858 for (p
= certchain
; p
; p
= p
->chain
) {
1859 if (oakley_check_certid_1(&p
->cert
, idtype
, idlen
, id
, &p
->status
) == 0) {
1863 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1867 oakley_get_peer_cert_from_certchain(phase1_handle_t
* iph1
)
1870 struct ipsecdoi_id_b
*id_b
;
1874 if (!iph1
->id_p
|| !iph1
->cert_p
) {
1875 plog(ASL_LEVEL_ERR
, "no ID nor CERT found.\n");
1878 if (!iph1
->cert_p
->chain
) {
1879 // no chain: simply return the only cert
1880 return iph1
->cert_p
;
1883 id_b
= ALIGNED_CAST(struct ipsecdoi_id_b
*)iph1
->id_p
->v
;
1884 peers_id
= id_b
+ 1;
1885 idlen
= iph1
->id_p
->l
- sizeof(*id_b
);
1886 for (p
= iph1
->cert_p
; p
; p
= p
->chain
) {
1887 if (oakley_check_certid_1(&p
->cert
, id_b
->type
, idlen
, peers_id
, &p
->status
) == 0) {
1895 * compare certificate name and ID value.
1898 oakley_check_certid(phase1_handle_t
*iph1
)
1900 struct ipsecdoi_id_b
*id_b
;
1902 u_int8_t doi_type
= 255;
1903 void *peers_id
= NULL
;
1905 /* use ID from peer */
1906 if (iph1
->id_p
== NULL
|| iph1
->cert_p
== NULL
) {
1907 plog(ASL_LEVEL_ERR
, "no ID nor CERT found.\n");
1908 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1910 id_b
= ALIGNED_CAST(struct ipsecdoi_id_b
*)iph1
->id_p
->v
;
1911 doi_type
= id_b
->type
;
1912 peers_id
= id_b
+ 1;
1913 idlen
= iph1
->id_p
->l
- sizeof(*id_b
);
1915 return oakley_check_certid_in_certchain(iph1
->cert_p
, doi_type
, idlen
, peers_id
);
1920 oakley_check_certid_1(vchar_t
*cert
, int idtype
, int idlen
, void *id
, cert_status_t
*certStatus
)
1928 char *altname
= NULL
;
1932 case IPSECDOI_ID_DER_ASN1_DN
:
1935 SecCertificateRef certificate
;
1936 UInt8
* namePtr
= NULL
;
1938 certificate
= crypto_cssm_x509cert_CreateSecCertificateRef(cert
);
1939 if (certificate
== NULL
) {
1941 "failed to get SecCertificateRef\n");
1942 if (certStatus
&& !*certStatus
) {
1943 *certStatus
= CERT_STATUS_INVALID
;
1945 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
1947 subject
= crypto_cssm_CopySubjectSequence(certificate
);
1948 if (subject
== NULL
) {
1949 plog(ASL_LEVEL_ERR
, "failed to get certificate subjectName\n");
1950 if (certStatus
&& !*certStatus
) {
1951 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
1953 error
= ISAKMP_NTYPE_INVALID_CERTIFICATE
;
1955 len
= CFDataGetLength(subject
);
1956 namePtr
= (UInt8
*)CFDataGetBytePtr(subject
);
1958 if (idlen
!= len
|| memcmp(id
, namePtr
, idlen
)) {
1959 plog(ASL_LEVEL_ERR
, "ID mismatched with certificate subjectName\n");
1960 error
=ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1963 plog(ASL_LEVEL_ERR
, "no certificate subjectName found\n");
1964 error
= ISAKMP_NTYPE_INVALID_CERTIFICATE
;
1969 "ID mismatched with certificate subjectName\n");
1970 if (namePtr
!= NULL
) {
1971 plogdump(ASL_LEVEL_ERR
, namePtr
, len
, "subjectName (type %s):\n",
1972 s_ipsecdoi_ident(idtype
));
1974 plog(ASL_LEVEL_ERR
, "subjectName (type %s):\n", s_ipsecdoi_ident(idtype
));
1976 plogdump(ASL_LEVEL_ERR
, id
, idlen
, "ID:\n");
1977 if (certStatus
&& !*certStatus
) {
1978 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
1981 CFRelease(certificate
);
1982 if (subject
!= NULL
) {
1989 case IPSECDOI_ID_IPV4_ADDR
:
1990 case IPSECDOI_ID_IPV6_ADDR
:
1992 #ifndef HAVE_OPENSSL
1994 SecCertificateRef certificate
;
1995 CFArrayRef addresses
;
1996 #define ADDRESS_BUF_SIZE 64
1998 certificate
= crypto_cssm_x509cert_CreateSecCertificateRef(cert
);
1999 if (certificate
== NULL
) {
2001 "failed to get SecCertificateRef\n");
2002 if (certStatus
&& !*certStatus
) {
2003 *certStatus
= CERT_STATUS_INVALID
;
2005 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2007 addresses
= SecCertificateCopyIPAddresses(certificate
);
2008 if (addresses
== NULL
) {
2009 plog(ASL_LEVEL_ERR
, "failed to get subjectName\n");
2010 if (certStatus
&& !*certStatus
) {
2011 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2013 CFRelease(certificate
);
2014 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2016 count
= CFArrayGetCount(addresses
);
2017 for (pos
= 0; pos
< count
; pos
++) {
2019 CFStringRef address
;
2021 char *addressBuf
, numAddress
[128];
2024 address
= CFArrayGetValueAtIndex(addresses
, pos
);
2025 addressLen
= CFStringGetLength(address
);
2026 if (addressLen
== 0)
2028 addressBuf
= racoon_malloc(ADDRESS_BUF_SIZE
);
2029 if (addressBuf
== NULL
) {
2030 plog(ASL_LEVEL_ERR
, "out of memory\n");
2031 CFRelease(addresses
);
2032 CFRelease(certificate
);
2035 if (CFStringGetCString(address
, addressBuf
, ADDRESS_BUF_SIZE
, kCFStringEncodingUTF8
) == TRUE
) {
2036 result
= inet_pton(idtype
== IPSECDOI_ID_IPV4_ADDR
? AF_INET
: AF_INET6
, addressBuf
, numAddress
);
2037 racoon_free(addressBuf
);
2039 continue; // wrong type or invalid address
2040 if (!memcmp(id
, numAddress
, idtype
== IPSECDOI_ID_IPV4_ADDR
? 32 : 128) == 0) { // found a match ?
2041 CFRelease(addresses
);
2042 CFRelease(certificate
);
2046 racoon_free(addressBuf
);
2048 plog(ASL_LEVEL_ERR
, "ID mismatched with subjectAltName.\n");
2050 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype
));
2051 plogdump(ASL_LEVEL_ERR
, id
, idlen
, "ID:\n");
2052 CFRelease(addresses
);
2053 CFRelease(certificate
);
2054 if (certStatus
&& !*certStatus
) {
2055 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2057 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2060 * Openssl returns the IPAddress as an ASN1 octet string (binary format)
2061 * followed by a trailing NULL. 5 bytes for IPv4 and 17 bytes for IPv6
2063 #define SUBJ_ALT_NAME_IPV4_ADDRESS_LEN 5
2064 #define SUBJ_ALT_NAME_IPV6_ADDRESS_LEN 17
2068 if ((idtype
== IPSECDOI_ID_IPV4_ADDR
&& idlen
!= sizeof(struct in_addr
))
2069 || (idtype
== IPSECDOI_ID_IPV6_ADDR
&& idlen
!= sizeof(struct in6_addr
))) {
2071 "invalid address length passed.\n");
2072 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2075 for (pos
= 1; ; pos
++) {
2076 if (eay_get_x509subjectaltname(cert
, &altname
, &type
, pos
, &len
) !=0) {
2078 "failed to get subjectAltName\n");
2079 if (certStatus
&& !*certStatus
) {
2080 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2082 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2085 /* it's the end condition of the loop. */
2088 "invalid subjectAltName\n");
2089 if (certStatus
&& !*certStatus
) {
2090 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2092 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2095 if (check_typeofcertname(idtype
, type
) != 0) {
2096 /* wrong type - skip this one */
2097 racoon_free(altname
);
2102 if (len
== SUBJ_ALT_NAME_IPV4_ADDRESS_LEN
) { /* IPv4 */
2103 if (idtype
!= IPSECDOI_ID_IPV4_ADDR
) {
2104 /* wrong IP address type - skip this one */
2105 racoon_free(altname
);
2111 else if (len
== SUBJ_ALT_NAME_IPV6_ADDRESS_LEN
) { /* IPv6 */
2112 if (idtype
!= IPSECDOI_ID_IPV6_ADDR
) {
2113 /* wrong IP address type - skip this one */
2114 racoon_free(altname
);
2121 /* invalid IP address length in certificate - bad or bogus certificate */
2123 "invalid IP address in certificate.\n");
2124 plogdump(ASL_LEVEL_ERR
, altname
, len
, "subjectAltName (expected type %s, got type %s):\n",
2125 s_ipsecdoi_ident(idtype
),
2126 s_ipsecdoi_ident(type
));
2127 racoon_free(altname
);
2129 if (certStatus
&& !*certStatus
) {
2130 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2132 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2135 /* compare the addresses */
2136 error
= memcmp(id
, altname
, idlen
);
2139 racoon_free(altname
);
2142 /* failed to find a match */
2144 "ID mismatched with subjectAltName.\n");
2145 plogdump(ASL_LEVEL_ERR
, altname
, len
, "subjectAltName (expected type %s, got type %s):\n",
2146 s_ipsecdoi_ident(idtype
),
2147 s_ipsecdoi_ident(type
));
2148 plogdump(ASL_LEVEL_ERR
, id
, idlen
, "ID:\n");
2149 racoon_free(altname
);
2150 if (certStatus
&& !*certStatus
)
2151 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2152 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2154 #endif /* HAVE_OPENSSL */
2157 #ifndef HAVE_OPENSSL
2158 case IPSECDOI_ID_FQDN
:
2161 SecCertificateRef certificate
;
2163 CFStringRef name
, ID
;
2165 certificate
= crypto_cssm_x509cert_CreateSecCertificateRef(cert
);
2166 if (certificate
== NULL
) {
2168 "failed to get SecCertificateRef\n");
2169 if (certStatus
&& !*certStatus
) {
2170 *certStatus
= CERT_STATUS_INVALID
;
2172 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2174 names
= SecCertificateCopyDNSNames(certificate
);
2175 if (names
== NULL
) {
2177 "failed to get subjectName\n");
2178 if (certStatus
&& !*certStatus
) {
2179 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2181 CFRelease(certificate
);
2182 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2184 count
= CFArrayGetCount(names
);
2185 ID
= CFStringCreateWithBytes(kCFAllocatorDefault
, id
, idlen
, kCFStringEncodingUTF8
, FALSE
);
2187 plog(ASL_LEVEL_ERR
, "memory error\n");
2189 CFRelease(certificate
);
2192 for (pos
= 0; pos
< count
; pos
++) {
2193 name
= CFArrayGetValueAtIndex(names
, pos
);
2194 if (CFStringCompare(name
, ID
, 0) == kCFCompareEqualTo
) {
2197 CFRelease(certificate
);
2201 plog(ASL_LEVEL_ERR
, "ID mismatched with subjectAltName.\n");
2203 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype
));
2204 plogdump(ASL_LEVEL_ERR
, id
, idlen
, "ID:\n");
2207 CFRelease(certificate
);
2208 if (certStatus
&& !*certStatus
) {
2209 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2211 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2214 case IPSECDOI_ID_USER_FQDN
:
2218 SecCertificateRef certificate
;
2220 CFStringRef name
, ID
;
2222 certificate
= crypto_cssm_x509cert_CreateSecCertificateRef(cert
);
2223 if (certificate
== NULL
) {
2225 "failed to get SecCertificateRef\n");
2226 if (certStatus
&& !*certStatus
) {
2227 *certStatus
= CERT_STATUS_INVALID
;
2229 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2231 names
= SecCertificateCopyRFC822Names(certificate
);
2232 if (names
== NULL
) {
2234 "failed to get subjectName\n");
2235 if (certStatus
&& !*certStatus
) {
2236 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2238 CFRelease(certificate
);
2239 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2241 count
= CFArrayGetCount(names
);
2242 ID
= CFStringCreateWithBytes(kCFAllocatorDefault
, id
, idlen
, kCFStringEncodingUTF8
, FALSE
);
2246 if (certStatus
&& !*certStatus
) {
2247 *certStatus
= CERT_STATUS_INVALID
;
2250 CFRelease(certificate
);
2251 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2253 for (pos
= 0; pos
< count
; pos
++) {
2254 name
= CFArrayGetValueAtIndex(names
, pos
);
2255 if (CFStringCompare(name
, ID
, 0) == kCFCompareEqualTo
) {
2258 CFRelease(certificate
);
2262 plog(ASL_LEVEL_ERR
, "ID mismatched with subjectAltName.\n");
2264 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype
));
2265 plogdump(ASL_LEVEL_ERR
, id
, idlen
, "ID:\n");
2268 CFRelease(certificate
);
2269 if (certStatus
&& !*certStatus
) {
2270 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2272 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2275 case IPSECDOI_ID_FQDN
:
2276 case IPSECDOI_ID_USER_FQDN
:
2280 for (pos
= 1; ; pos
++) {
2281 if (eay_get_x509subjectaltname(cert
, &altname
, &type
, pos
, &len
) != 0) {
2283 "failed to get subjectAltName\n");
2284 if (certStatus
&& !*certStatus
) {
2285 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2287 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2290 /* it's the end condition of the loop. */
2293 "invalid subjectAltName\n");
2294 if (certStatus
&& !*certStatus
) {
2295 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2297 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2300 if (check_typeofcertname(idtype
, type
) != 0) {
2301 /* wrong general type - skip this one */
2302 racoon_free(altname
);
2307 if (idlen
!= strlen(altname
)) {
2308 /* wrong length - skip this one */
2309 racoon_free(altname
);
2313 error
= memcmp(id
, altname
, idlen
);
2316 racoon_free(altname
);
2319 plog(ASL_LEVEL_ERR
, "ID mismatched with subjectAltName.\n");
2321 "subjectAltName (expected type %s, got type %s):\n",
2322 s_ipsecdoi_ident(idtype
),
2323 s_ipsecdoi_ident(type
));
2324 plogdump(ASL_LEVEL_ERR
, altname
, len
, "subjectAltName (expected type %s, got type %s):\n",
2325 s_ipsecdoi_ident(idtype
),
2326 s_ipsecdoi_ident(type
));
2327 plogdump(ASL_LEVEL_ERR
, id
, idlen
, "ID:\n");
2328 racoon_free(altname
);
2329 if (certStatus
&& !*certStatus
)
2330 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2331 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2336 "Impropper ID type passed: %s.\n",
2337 s_ipsecdoi_ident(idtype
));
2338 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2344 check_typeofcertname(int doi
, int genid
)
2347 case IPSECDOI_ID_IPV4_ADDR
:
2348 case IPSECDOI_ID_IPV4_ADDR_SUBNET
:
2349 case IPSECDOI_ID_IPV6_ADDR
:
2350 case IPSECDOI_ID_IPV6_ADDR_SUBNET
:
2351 case IPSECDOI_ID_IPV4_ADDR_RANGE
:
2352 case IPSECDOI_ID_IPV6_ADDR_RANGE
:
2353 if (genid
!= GENT_IPADD
)
2356 case IPSECDOI_ID_FQDN
:
2357 if (genid
!= GENT_DNS
)
2360 case IPSECDOI_ID_USER_FQDN
:
2361 if (genid
!= GENT_EMAIL
)
2364 case IPSECDOI_ID_DER_ASN1_DN
: /* should not be passed to this function*/
2365 case IPSECDOI_ID_DER_ASN1_GN
:
2366 case IPSECDOI_ID_KEY_ID
:
2375 * save certificate including certificate type.
2378 oakley_savecert(phase1_handle_t
*iph1
, struct isakmp_gen
*gen
)
2382 type
= *(u_int8_t
*)(gen
+ 1) & 0xff;
2385 case ISAKMP_CERT_X509SIGN
:
2390 "Invalid CERT type %d\n", type
);
2395 plog(ASL_LEVEL_WARNING
,
2396 "preexisting CERT payload... chaining.\n");
2400 new = save_certbuf(gen
);
2403 "Failed to get CERT buffer.\n");
2407 switch (new->type
) {
2408 case ISAKMP_CERT_X509SIGN
:
2409 /* Ignore cert if it doesn't match identity
2410 * XXX If verify cert is disabled, we still just take
2411 * the first certificate....
2413 *c
= oakley_appendcert_to_certchain(*c
, new);
2414 plog(ASL_LEVEL_DEBUG
, "CERT saved:\n");
2418 oakley_delcert(new);
2426 * save certificate including certificate type.
2429 oakley_savecr(phase1_handle_t
*iph1
, struct isakmp_gen
*gen
)
2435 type
= *(u_int8_t
*)(gen
+ 1) & 0xff;
2438 case ISAKMP_CERT_X509SIGN
:
2440 oakley_delcert(iph1
->cr_p
);
2447 "Invalid CR type %d\n", type
);
2451 new = save_certbuf(gen
);
2454 "Failed to get CR buffer.\n");
2457 *c
= oakley_appendcert_to_certchain(*c
, new);
2458 plog(ASL_LEVEL_DEBUG
, "CR saved\n");
2464 save_certbuf(struct isakmp_gen
*gen
)
2468 if(ntohs(gen
->len
) <= sizeof(*gen
)){
2470 "Len is too small !!.\n");
2474 new = oakley_newcert();
2477 "Failed to get CERT buffer.\n");
2481 new->pl
= vmalloc(ntohs(gen
->len
) - sizeof(*gen
));
2482 if (new->pl
== NULL
) {
2484 "Failed to copy CERT from packet.\n");
2485 oakley_delcert(new);
2489 memcpy(new->pl
->v
, gen
+ 1, new->pl
->l
);
2490 new->type
= new->pl
->v
[0] & 0xff;
2491 new->cert
.v
= new->pl
->v
+ 1;
2492 new->cert
.l
= new->pl
->l
- 1;
2499 * NOTE: No Certificate Authority field is included to CR payload at the
2500 * moment. Becuase any certificate authority are accepted without any check.
2501 * The section 3.10 in RFC2408 says that this field SHOULD not be included,
2502 * if there is no specific certificate authority requested.
2505 oakley_getcr(phase1_handle_t
*iph1
)
2512 "failed to get cr buffer\n");
2515 if(iph1
->rmconf
->certtype
== ISAKMP_CERT_NONE
) {
2516 buf
->v
[0] = iph1
->rmconf
->cacerttype
;
2517 plog(ASL_LEVEL_DEBUG
, "create my CR: NONE, using %s instead\n",
2518 s_isakmp_certtype(iph1
->rmconf
->cacerttype
));
2520 buf
->v
[0] = iph1
->rmconf
->certtype
;
2521 plog(ASL_LEVEL_DEBUG
, "create my CR: %s\n",
2522 s_isakmp_certtype(iph1
->rmconf
->certtype
));
2525 // plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "");
2534 oakley_checkcr(phase1_handle_t
*iph1
)
2536 if (iph1
->cr_p
== NULL
)
2539 plog(ASL_LEVEL_DEBUG
,
2540 "peer transmitted CR: %s\n",
2541 s_isakmp_certtype(iph1
->cr_p
->type
));
2543 if (iph1
->cr_p
->type
!= iph1
->rmconf
->certtype
) {
2545 "such a cert type isn't supported: %d\n",
2546 (char)iph1
->cr_p
->type
);
2554 * check to need CR payload.
2557 oakley_needcr(int type
)
2560 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
2561 #ifdef ENABLE_HYBRID
2562 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
2563 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
2564 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
2574 oakley_getpskall(phase1_handle_t
*iph1
)
2576 vchar_t
*secret
= NULL
;
2578 if (iph1
->rmconf
->shared_secret
) {
2580 switch (iph1
->rmconf
->secrettype
) {
2581 case SECRETTYPE_KEY
:
2582 /* in psk file - use KEY from remote configuration to locate it */
2583 secret
= getpsk(iph1
->rmconf
->shared_secret
->v
, iph1
->rmconf
->shared_secret
->l
-1);
2586 case SECRETTYPE_KEYCHAIN
:
2587 /* in the system keychain */
2588 secret
= getpskfromkeychain(iph1
->rmconf
->shared_secret
->v
, iph1
->etype
, iph1
->rmconf
->secrettype
, NULL
);
2590 case SECRETTYPE_KEYCHAIN_BY_ID
:
2591 /* in the system keychain - use peer id */
2592 secret
= getpskfromkeychain(iph1
->rmconf
->shared_secret
->v
, iph1
->etype
, iph1
->rmconf
->secrettype
, iph1
->id_p
);
2594 #endif // HAVE_KEYCHAIN
2595 case SECRETTYPE_USE
:
2596 /* in the remote configuration */
2598 /* rmconf->shared_secret is a string and contains a NULL character that must be removed */
2599 secret
= vmalloc(iph1
->rmconf
->shared_secret
->l
- 1);
2600 if (secret
== NULL
) {
2601 plog(ASL_LEVEL_ERR
, "memory error.\n");
2604 memcpy(secret
->v
, iph1
->rmconf
->shared_secret
->v
, secret
->l
);
2606 } else if (iph1
->etype
!= ISAKMP_ETYPE_IDENT
) {
2607 secret
= getpskbyname(iph1
->id_p
);
2609 if (iph1
->rmconf
->verify_identifier
) {
2610 plog(ASL_LEVEL_ERR
, "couldn't find pskey by peer's ID.\n");
2616 plog(ASL_LEVEL_NOTICE
, "try to get pskey by the peer's address.\n");
2617 secret
= getpskbyaddr(iph1
->remote
);
2620 "couldn't find the pskey by address %s.\n",
2621 saddrwop2str((struct sockaddr
*)iph1
->remote
));
2631 * see seciton 5. Exchanges in RFC 2409
2632 * psk: SKEYID = prf(pre-shared-key, Ni_b | Nr_b)
2633 * sig: SKEYID = prf(Ni_b | Nr_b, g^ir)
2634 * enc: SKEYID = prf(H(Ni_b | Nr_b), CKY-I | CKY-R)
2637 oakley_skeyid(phase1_handle_t
*iph1
)
2639 vchar_t
*key
= NULL
;
2640 vchar_t
*buf
= NULL
;
2647 switch (AUTHMETHOD(iph1
)) {
2648 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
2649 #ifdef ENABLE_HYBRID
2650 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
2651 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
2653 key
= oakley_getpskall(iph1
);
2656 "couldn't find the pskey for %s.\n",
2657 saddrwop2str((struct sockaddr
*)iph1
->remote
));
2660 plog(ASL_LEVEL_DEBUG
, "the psk found.\n");
2661 /* should be secret PSK */
2662 plogdump(ASL_LEVEL_DEBUG
, key
->v
, key
->l
, "psk: ");
2664 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
2668 "failed to get skeyid buffer\n");
2673 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce
: iph1
->nonce_p
);
2674 //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce 1: ");
2675 memcpy(p
, bp
->v
, bp
->l
);
2678 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce_p
: iph1
->nonce
);
2679 //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce 2: ");
2680 memcpy(p
, bp
->v
, bp
->l
);
2683 iph1
->skeyid
= oakley_prf(key
, buf
, iph1
);
2685 if (iph1
->skeyid
== NULL
)
2689 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
2690 #ifdef ENABLE_HYBRID
2691 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
2692 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
2693 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
2694 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
2696 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
2700 "failed to get nonce buffer\n");
2705 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce
: iph1
->nonce_p
);
2706 //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce1: ");
2707 memcpy(p
, bp
->v
, bp
->l
);
2710 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce_p
: iph1
->nonce
);
2711 //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce2: ");
2712 memcpy(p
, bp
->v
, bp
->l
);
2715 iph1
->skeyid
= oakley_prf(buf
, iph1
->dhgxy
, iph1
);
2716 if (iph1
->skeyid
== NULL
)
2719 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
2720 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
2721 #ifdef ENABLE_HYBRID
2722 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
2723 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
2724 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
2725 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
2727 plog(ASL_LEVEL_WARNING
,
2728 "not supported authentication method %s\n",
2729 s_oakley_attr_method(iph1
->approval
->authmethod
));
2733 "invalid authentication method %d\n",
2734 iph1
->approval
->authmethod
);
2738 //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid->v, iph1->skeyid->l, "IKEv1 SKEYID computed:\n");
2751 * compute SKEYID_[dae]
2754 oakley_skeyid_dae(phase1_handle_t
*iph1
)
2756 vchar_t
*buf
= NULL
;
2761 if (iph1
->skeyid
== NULL
) {
2762 plog(ASL_LEVEL_ERR
, "no SKEYID found.\n");
2767 * see seciton 5. Exchanges in RFC 2409
2768 * SKEYID_d = prf(SKEYID, g^ir | CKY-I | CKY-R | 0)
2769 * SKEYID_a = prf(SKEYID, SKEYID_d | g^ir | CKY-I | CKY-R | 1)
2770 * SKEYID_e = prf(SKEYID, SKEYID_a | g^ir | CKY-I | CKY-R | 2)
2773 /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
2774 len
= iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
2778 "failed to get skeyid buffer\n");
2783 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
2784 p
+= iph1
->dhgxy
->l
;
2785 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
2786 p
+= sizeof(cookie_t
);
2787 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
2788 p
+= sizeof(cookie_t
);
2790 iph1
->skeyid_d
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
2791 if (iph1
->skeyid_d
== NULL
)
2797 //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid_d->v, iph1->skeyid_d->l, "SKEYID_d computed:\n");
2800 /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
2801 len
= iph1
->skeyid_d
->l
+ iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
2805 "failed to get skeyid buffer\n");
2809 memcpy(p
, iph1
->skeyid_d
->v
, iph1
->skeyid_d
->l
);
2810 p
+= iph1
->skeyid_d
->l
;
2811 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
2812 p
+= iph1
->dhgxy
->l
;
2813 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
2814 p
+= sizeof(cookie_t
);
2815 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
2816 p
+= sizeof(cookie_t
);
2818 iph1
->skeyid_a
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
2819 if (iph1
->skeyid_a
== NULL
)
2825 //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid_a->v, iph1->skeyid_a->l, "SKEYID_a computed:\n");
2828 /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
2829 len
= iph1
->skeyid_a
->l
+ iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
2833 "failed to get skeyid buffer\n");
2837 memcpy(p
, iph1
->skeyid_a
->v
, iph1
->skeyid_a
->l
);
2838 p
+= iph1
->skeyid_a
->l
;
2839 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
2840 p
+= iph1
->dhgxy
->l
;
2841 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
2842 p
+= sizeof(cookie_t
);
2843 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
2844 p
+= sizeof(cookie_t
);
2846 iph1
->skeyid_e
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
2847 if (iph1
->skeyid_e
== NULL
)
2853 //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid_e->v, iph1->skeyid_e->l, "SKEYID_e computed:\n");
2864 * compute final encryption key.
2868 oakley_compute_enckey(phase1_handle_t
*iph1
)
2870 u_int keylen
, prflen
;
2874 keylen
= alg_oakley_encdef_keylen(iph1
->approval
->enctype
,
2875 iph1
->approval
->encklen
);
2878 "invalid encryption algoritym %d, "
2879 "or invalid key length %d.\n",
2880 iph1
->approval
->enctype
,
2881 iph1
->approval
->encklen
);
2884 iph1
->key
= vmalloc(keylen
>> 3);
2885 if (iph1
->key
== NULL
) {
2887 "failed to get key buffer\n");
2891 /* set prf length */
2892 prflen
= alg_oakley_hashdef_hashlen(iph1
->approval
->hashtype
);
2895 "invalid hash type %d.\n", iph1
->approval
->hashtype
);
2899 /* see isakmp-oakley-08 5.3. */
2900 if (iph1
->key
->l
<= iph1
->skeyid_e
->l
) {
2902 * if length(Ka) <= length(SKEYID_e)
2903 * Ka = first length(K) bit of SKEYID_e
2905 memcpy(iph1
->key
->v
, iph1
->skeyid_e
->v
, iph1
->key
->l
);
2907 vchar_t
*buf
= NULL
, *res
= NULL
;
2916 * K1 = prf(SKEYID_e, 0)
2917 * K2 = prf(SKEYID_e, K1)
2918 * K3 = prf(SKEYID_e, K2)
2920 plog(ASL_LEVEL_DEBUG
,
2921 "len(SKEYID_e) < len(Ka) (%zu < %zu), "
2922 "generating long key (Ka = K1 | K2 | ...)\n",
2923 iph1
->skeyid_e
->l
, iph1
->key
->l
);
2925 if ((buf
= vmalloc(prflen
>> 3)) == 0) {
2927 "failed to get key buffer\n");
2930 p
= (u_char
*)iph1
->key
->v
;
2931 ep
= p
+ iph1
->key
->l
;
2935 if (p
== (u_char
*)iph1
->key
->v
) {
2936 /* just for computing K1 */
2940 res
= oakley_prf(iph1
->skeyid_e
, buf
, iph1
);
2945 plog(ASL_LEVEL_DEBUG
,
2946 "compute intermediate encryption key K%d\n",
2948 //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "");
2949 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "");
2951 cplen
= (res
->l
< ep
- p
) ? res
->l
: ep
- p
;
2952 memcpy(p
, res
->v
, cplen
);
2955 buf
->l
= prflen
>> 3; /* to cancel K1 speciality */
2956 if (res
->l
!= buf
->l
) {
2958 "internal error: res->l=%zu buf->l=%zu\n",
2964 memcpy(buf
->v
, res
->v
, res
->l
);
2973 * don't check any weak key or not.
2974 * draft-ietf-ipsec-ike-01.txt Appendix B.
2975 * draft-ietf-ipsec-ciph-aes-cbc-00.txt Section 2.3.
2978 //plogdump(ASL_LEVEL_DEBUG, iph1->key->v, iph1->key->l, "final encryption key computed:\n");
2986 /* allocated new buffer for CERT */
2988 oakley_newcert(void)
2992 new = racoon_calloc(1, sizeof(*new));
2995 "failed to get cert's buffer\n");
3005 /* delete buffer for CERT */
3007 oakley_delcert_1(cert_t
*cert
)
3016 /* delete buffer for CERT */
3018 oakley_delcert(cert_t
*cert
)
3020 cert_t
*p
, *to_delete
;
3025 for (p
= cert
; p
;) {
3028 oakley_delcert_1(to_delete
);
3032 /* delete buffer for CERT */
3034 oakley_appendcert_to_certchain(cert_t
*certchain
, cert_t
*new)
3041 for (p
= certchain
; p
; p
= p
->chain
) {
3051 * compute IV and set to ph1handle
3052 * IV = hash(g^xi | g^xr)
3053 * see 4.1 Phase 1 state in draft-ietf-ipsec-ike.
3056 oakley_newiv(phase1_handle_t
*iph1
)
3058 struct isakmp_ivm
*newivm
= NULL
;
3059 vchar_t
*buf
= NULL
, *bp
;
3064 len
= iph1
->dhpub
->l
+ iph1
->dhpub_p
->l
;
3068 "Failed to get IV buffer\n");
3074 bp
= (iph1
->side
== INITIATOR
? iph1
->dhpub
: iph1
->dhpub_p
);
3075 memcpy(p
, bp
->v
, bp
->l
);
3078 bp
= (iph1
->side
== INITIATOR
? iph1
->dhpub_p
: iph1
->dhpub
);
3079 memcpy(p
, bp
->v
, bp
->l
);
3083 newivm
= racoon_calloc(1, sizeof(struct isakmp_ivm
));
3084 if (newivm
== NULL
) {
3086 "Failed to get IV buffer\n");
3092 newivm
->iv
= oakley_hash(buf
, iph1
);
3093 if (newivm
->iv
== NULL
) {
3095 oakley_delivm(newivm
);
3099 /* adjust length of iv */
3100 newivm
->iv
->l
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3101 if (newivm
->iv
->l
== -1) {
3103 "Invalid encryption algorithm %d.\n",
3104 iph1
->approval
->enctype
);
3106 oakley_delivm(newivm
);
3110 /* create buffer to save iv */
3111 if ((newivm
->ive
= vdup(newivm
->iv
)) == NULL
) {
3113 "vdup (%s)\n", strerror(errno
));
3115 oakley_delivm(newivm
);
3121 //plogdump(ASL_LEVEL_DEBUG, newivm->iv->v, newivm->iv->l, "IV computed:\n");
3123 if (iph1
->ivm
!= NULL
)
3124 oakley_delivm(iph1
->ivm
);
3132 * compute IV for the payload after phase 1.
3133 * It's not limited for phase 2.
3134 * if pahse 1 was encrypted.
3135 * IV = hash(last CBC block of Phase 1 | M-ID)
3136 * if phase 1 was not encrypted.
3137 * IV = hash(phase 1 IV | M-ID)
3138 * see 4.2 Phase 2 state in draft-ietf-ipsec-ike.
3141 oakley_newiv2(phase1_handle_t
*iph1
, u_int32_t msgid
)
3143 struct isakmp_ivm
*newivm
= NULL
;
3144 vchar_t
*buf
= NULL
;
3150 len
= iph1
->ivm
->iv
->l
+ sizeof(msgid_t
);
3154 "Failed to get IV buffer\n");
3160 memcpy(p
, iph1
->ivm
->iv
->v
, iph1
->ivm
->iv
->l
);
3161 p
+= iph1
->ivm
->iv
->l
;
3163 memcpy(p
, &msgid
, sizeof(msgid
));
3165 plog(ASL_LEVEL_DEBUG
, "Compute IV for Phase 2\n");
3166 //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "Phase 1 last IV:\n");
3169 newivm
= racoon_calloc(1, sizeof(struct isakmp_ivm
));
3170 if (newivm
== NULL
) {
3172 "Failed to get IV buffer\n");
3177 if ((newivm
->iv
= oakley_hash(buf
, iph1
)) == NULL
)
3180 /* adjust length of iv */
3181 newivm
->iv
->l
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3182 if (newivm
->iv
->l
== -1) {
3184 "Invalid encryption algorithm %d.\n",
3185 iph1
->approval
->enctype
);
3189 /* create buffer to save new iv */
3190 if ((newivm
->ive
= vdup(newivm
->iv
)) == NULL
) {
3191 plog(ASL_LEVEL_ERR
, "vdup (%s)\n", strerror(errno
));
3197 //plogdump(ASL_LEVEL_DEBUG, newivm->iv->v, newivm->iv->l, "Phase 2 IV computed:\n");
3200 if (error
&& newivm
!= NULL
){
3201 oakley_delivm(newivm
);
3210 oakley_delivm(struct isakmp_ivm
*ivm
)
3215 if (ivm
->iv
!= NULL
)
3217 if (ivm
->ive
!= NULL
)
3220 plog(ASL_LEVEL_DEBUG
, "IV freed\n");
3227 * save new iv and old iv.
3230 oakley_do_ikev1_decrypt(phase1_handle_t
*iph1
, vchar_t
*msg
, vchar_t
*ivdp
, vchar_t
*ivep
)
3232 vchar_t
*buf
= NULL
, *new = NULL
;
3239 plog(ASL_LEVEL_DEBUG
, "Begin decryption.\n");
3241 blen
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3244 "Invalid encryption algorithm %d.\n",
3245 iph1
->approval
->enctype
);
3249 /* save IV for next, but not sync. */
3250 memset(ivep
->v
, 0, ivep
->l
);
3251 memcpy(ivep
->v
, (caddr_t
)&msg
->v
[msg
->l
- blen
], blen
);
3253 plogdump(ASL_LEVEL_DEBUG
, ivep
->v
, ivep
->l
, "IV was saved for next processing:\n");
3255 pl
= msg
->v
+ sizeof(struct isakmp
);
3257 len
= msg
->l
- sizeof(struct isakmp
);
3263 "Failed to get buffer to decrypt.\n");
3266 memcpy(buf
->v
, pl
, len
);
3269 new = alg_oakley_encdef_decrypt(iph1
->approval
->enctype
,
3270 buf
, iph1
->key
, ivdp
);
3271 if (new == NULL
|| new->v
== NULL
|| new->l
== 0) {
3273 "Decryption %d failed.\n", iph1
->approval
->enctype
);
3276 //plogdump(ASL_LEVEL_DEBUG, iph1->key->v, iph1->key->l, "with key:\n");
3283 plog(ASL_LEVEL_DEBUG
, "decrypted payload by IV:\n");
3285 /* get padding length */
3286 if (lcconf
->pad_excltail
)
3287 padlen
= new->v
[new->l
- 1] + 1;
3289 padlen
= new->v
[new->l
- 1];
3290 plog(ASL_LEVEL_DEBUG
, "padding len=%u\n", padlen
);
3293 if (lcconf
->pad_strict
) {
3294 if (padlen
> new->l
) {
3295 plog(ASL_LEVEL_ERR
, "invalid padding len=%u, buflen=%zu.\n",
3300 plog(ASL_LEVEL_DEBUG
, "trimmed padding\n");
3302 plog(ASL_LEVEL_DEBUG
, "skip to trim padding.\n");
3305 /* create new buffer */
3306 len
= sizeof(struct isakmp
) + new->l
;
3310 "failed to get buffer to decrypt.\n");
3313 memcpy(buf
->v
, msg
->v
, sizeof(struct isakmp
));
3314 memcpy(buf
->v
+ sizeof(struct isakmp
), new->v
, new->l
);
3315 ((struct isakmp
*)buf
->v
)->len
= htonl(buf
->l
);
3317 plog(ASL_LEVEL_DEBUG
, "decrypted.\n");
3319 #ifdef HAVE_PRINT_ISAKMP_C
3320 isakmp_printpacket(buf
, iph1
->remote
, iph1
->local
, 1);
3326 if (error
&& buf
!= NULL
) {
3340 oakley_do_decrypt(phase1_handle_t
*iph1
, vchar_t
*msg
, vchar_t
*ivdp
, vchar_t
*ivep
)
3342 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
3343 return(oakley_do_ikev1_decrypt(iph1
, msg
, ivdp
, ivep
));
3346 plog(ASL_LEVEL_ERR
, "Failed to decrypt invalid IKE version");
3354 oakley_do_ikev1_encrypt(phase1_handle_t
*iph1
, vchar_t
*msg
, vchar_t
*ivep
, vchar_t
*ivp
)
3356 vchar_t
*buf
= 0, *new = 0;
3363 plog(ASL_LEVEL_DEBUG
, "Begin encryption.\n");
3365 /* set cbc block length */
3366 blen
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3369 "Invalid encryption algorithm %d.\n",
3370 iph1
->approval
->enctype
);
3374 pl
= msg
->v
+ sizeof(struct isakmp
);
3375 len
= msg
->l
- sizeof(struct isakmp
);
3378 padlen
= oakley_padlen(len
, blen
);
3379 plog(ASL_LEVEL_DEBUG
, "pad length = %u\n", padlen
);
3382 buf
= vmalloc(len
+ padlen
);
3385 "Failed to get buffer to encrypt.\n");
3390 char *p
= &buf
->v
[len
];
3391 if (lcconf
->pad_random
) {
3392 for (i
= 0; i
< padlen
; i
++)
3393 *p
++ = eay_random() & 0xff;
3396 memcpy(buf
->v
, pl
, len
);
3398 /* make pad into tail */
3399 if (lcconf
->pad_excltail
)
3400 buf
->v
[len
+ padlen
- 1] = padlen
- 1;
3402 buf
->v
[len
+ padlen
- 1] = padlen
;
3404 plogdump(ASL_LEVEL_DEBUG
, buf
->v
, buf
->l
, "About to encrypt %d bytes", buf
->l
);
3407 new = alg_oakley_encdef_encrypt(iph1
->approval
->enctype
,
3408 buf
, iph1
->key
, ivep
);
3411 "Encryption %d failed.\n", iph1
->approval
->enctype
);
3414 //plogdump(ASL_LEVEL_DEBUG, iph1->key->v, iph1->key->l, "with key:\n");
3421 //plogdump(ASL_LEVEL_DEBUG, ivep->v, ivep->l, "encrypted payload by IV:\n");
3423 /* save IV for next */
3424 memset(ivp
->v
, 0, ivp
->l
);
3425 memcpy(ivp
->v
, (caddr_t
)&new->v
[new->l
- blen
], blen
);
3427 //plogdump(ASL_LEVEL_DEBUG, ivp->v, ivp->l, "save IV for next:\n");
3429 /* create new buffer */
3430 len
= sizeof(struct isakmp
) + new->l
;
3434 "Failed to get buffer to encrypt.\n");
3437 memcpy(buf
->v
, msg
->v
, sizeof(struct isakmp
));
3438 memcpy(buf
->v
+ sizeof(struct isakmp
), new->v
, new->l
);
3439 ((struct isakmp
*)buf
->v
)->len
= htonl(buf
->l
);
3443 plog(ASL_LEVEL_DEBUG
, "Encrypted.\n");
3446 if (error
&& buf
!= NULL
) {
3460 oakley_do_encrypt(phase1_handle_t
*iph1
, vchar_t
*msg
, vchar_t
*ivep
, vchar_t
*ivp
)
3462 if (iph1
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
3463 return(oakley_do_ikev1_encrypt(iph1
, msg
, ivep
, ivp
));
3466 plog(ASL_LEVEL_ERR
, "Failed to encrypt invalid IKE version");
3470 /* culculate padding length */
3472 oakley_padlen(int len
, int base
)
3476 padlen
= base
- (len
% base
);
3478 if (lcconf
->pad_randomlen
)
3479 padlen
+= ((eay_random() % (lcconf
->pad_maxsize
+ 1) + 1) *
3485 /* -----------------------------------------------------------------------------
3486 The base-64 encoding packs three 8-bit bytes into four 7-bit ASCII
3487 characters. If the number of bytes in the original data isn't divisable
3488 by three, "=" characters are used to pad the encoded data. The complete
3489 set of characters used in base-64 are:
3497 ----------------------------------------------------------------------------- */
3498 static const signed char base64_DecodeTable
[128] = {
3499 /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
3500 /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
3501 /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
3502 /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
3503 /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
3504 /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
3505 /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
3506 /* '8' */ 60, 61, -1, -1, -1, 0, -1, -1,
3507 /* '@' */ -1, 0, 1, 2, 3, 4, 5, 6,
3508 /* 'H' */ 7, 8, 9, 10, 11, 12, 13, 14,
3509 /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
3510 /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
3511 /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
3512 /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
3513 /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
3514 /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
3517 static int base64toCFData(vchar_t
*textin
, CFDataRef
*dataRef
)
3525 uint8_t *textcur
= (__typeof__(textcur
))textin
->v
;
3526 int len
= textin
->l
;
3529 tmpbuf
= malloc(len
); // len of result will be less than encoded len
3530 if (tmpbuf
== NULL
) {
3531 yyerror("memory error - could not allocate buffer for certificate reference conversion from base-64.");
3535 for (i
= 0; i
< len
; i
++) {
3539 else if (!isspace(c
))
3541 if (base64_DecodeTable
[c
] < 0)
3545 acc
+= base64_DecodeTable
[c
];
3546 if (0 == (cntr
& 0x3)) {
3547 tmpbuf
[tmpbufpos
++] = (acc
>> 16) & 0xff;
3549 tmpbuf
[tmpbufpos
++] = (acc
>> 8) & 0xff;
3551 tmpbuf
[tmpbufpos
++] = acc
& 0xff;
3554 *dataRef
= CFDataCreate(NULL
, tmpbuf
, tmpbufpos
);