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 */
41 #include <openssl/pkcs7.h>
42 #include <openssl/x509.h>
48 #include <arpa/inet.h>
49 #include <TargetConditionals.h>
51 #if TIME_WITH_SYS_TIME
52 # include <sys/time.h>
56 # include <sys/time.h>
72 #include "isakmp_var.h"
75 #include "isakmp_xauth.h"
76 #include "isakmp_cfg.h"
81 #include "localconf.h"
84 #include "ipsec_doi.h"
85 #include "algorithm.h"
89 #include "crypto_openssl.h"
91 #include "crypto_cssm.h"
102 #include <CoreFoundation/CoreFoundation.h>
104 #include "remoteconf.h"
110 #define OUTBOUND_SA 0
114 #define CERT_CHECKID_FROM_PEER 0
115 #define CERT_CHECKID_FROM_RMCONFIG 1
118 #define INITDHVAL(a, s, d, t) \
121 buf.v = str2val((s), 16, &buf.l); \
122 memset(&a, 0, sizeof(struct dhgroup)); \
124 a.prime = vdup(&buf); \
127 racoon_free(buf.v); \
130 struct dhgroup dh_modp768
;
131 struct dhgroup dh_modp1024
;
132 struct dhgroup dh_modp1536
;
133 struct dhgroup dh_modp2048
;
134 struct dhgroup dh_modp3072
;
135 struct dhgroup dh_modp4096
;
136 struct dhgroup dh_modp6144
;
137 struct dhgroup dh_modp8192
;
140 static int oakley_check_dh_pub
__P((vchar_t
*, vchar_t
**));
141 static int oakley_compute_keymat_x
__P((struct ph2handle
*, int, int));
142 static int get_cert_fromlocal
__P((struct ph1handle
*, int));
143 static int get_plainrsa_fromlocal
__P((struct ph1handle
*, int));
145 static int oakley_check_certid
__P((struct ph1handle
*iph1
, int));
146 static int oakley_check_certid_1
__P((struct ph1handle
*, int, int, void*));
148 static int oakley_check_certid
__P((struct ph1handle
*iph1
));
150 static int check_typeofcertname
__P((int, int));
151 static cert_t
*save_certbuf
__P((struct isakmp_gen
*));
152 static cert_t
*save_certx509
__P((X509
*));
153 static int oakley_padlen
__P((int, int));
156 static int base64toCFData(vchar_t
*, CFDataRef
*);
160 oakley_get_defaultlifetime()
162 return OAKLEY_ATTR_SA_LD_SEC_DEFAULT
;
169 INITDHVAL(dh_modp768
, OAKLEY_PRIME_MODP768
,
170 OAKLEY_ATTR_GRP_DESC_MODP768
, OAKLEY_ATTR_GRP_TYPE_MODP
);
171 INITDHVAL(dh_modp1024
, OAKLEY_PRIME_MODP1024
,
172 OAKLEY_ATTR_GRP_DESC_MODP1024
, OAKLEY_ATTR_GRP_TYPE_MODP
);
173 INITDHVAL(dh_modp1536
, OAKLEY_PRIME_MODP1536
,
174 OAKLEY_ATTR_GRP_DESC_MODP1536
, OAKLEY_ATTR_GRP_TYPE_MODP
);
175 INITDHVAL(dh_modp2048
, OAKLEY_PRIME_MODP2048
,
176 OAKLEY_ATTR_GRP_DESC_MODP2048
, OAKLEY_ATTR_GRP_TYPE_MODP
);
177 INITDHVAL(dh_modp3072
, OAKLEY_PRIME_MODP3072
,
178 OAKLEY_ATTR_GRP_DESC_MODP3072
, OAKLEY_ATTR_GRP_TYPE_MODP
);
179 INITDHVAL(dh_modp4096
, OAKLEY_PRIME_MODP4096
,
180 OAKLEY_ATTR_GRP_DESC_MODP4096
, OAKLEY_ATTR_GRP_TYPE_MODP
);
181 INITDHVAL(dh_modp6144
, OAKLEY_PRIME_MODP6144
,
182 OAKLEY_ATTR_GRP_DESC_MODP6144
, OAKLEY_ATTR_GRP_TYPE_MODP
);
183 INITDHVAL(dh_modp8192
, OAKLEY_PRIME_MODP8192
,
184 OAKLEY_ATTR_GRP_DESC_MODP8192
, OAKLEY_ATTR_GRP_TYPE_MODP
);
190 oakley_dhgrp_free(dhgrp
)
191 struct dhgroup
*dhgrp
;
196 vfree(dhgrp
->curve_a
);
198 vfree(dhgrp
->curve_b
);
206 * The length of the Diffie-Hellman public value MUST be equal to the
207 * length of the prime modulus over which the exponentiation was
208 * performed, prepending zero bits to the value if necessary.
211 oakley_check_dh_pub(prime
, pub0
)
212 vchar_t
*prime
, **pub0
;
215 vchar_t
*pub
= *pub0
;
217 if (prime
->l
== pub
->l
)
220 if (prime
->l
< pub
->l
) {
221 /* what should i do ? */
222 plog(LLV_ERROR
, LOCATION
, NULL
,
223 "invalid public information was generated.\n");
227 /* prime->l > pub->l */
228 tmp
= vmalloc(prime
->l
);
230 plog(LLV_ERROR
, LOCATION
, NULL
,
231 "failed to get DH buffer.\n");
234 memcpy(tmp
->v
+ prime
->l
- pub
->l
, pub
->v
, pub
->l
);
243 * compute sharing secret of DH
244 * IN: *dh, *pub, *priv, *pub_p
248 oakley_dh_compute(dh
, pub
, priv
, pub_p
, gxy
)
249 const struct dhgroup
*dh
;
250 vchar_t
*pub
, *priv
, *pub_p
, **gxy
;
253 struct timeval start
, end
;
255 if ((*gxy
= vmalloc(dh
->prime
->l
)) == NULL
) {
256 plog(LLV_ERROR
, LOCATION
, NULL
,
257 "failed to get DH buffer.\n");
262 gettimeofday(&start
, NULL
);
265 case OAKLEY_ATTR_GRP_TYPE_MODP
:
266 if (eay_dh_compute(dh
->prime
, dh
->gen1
, pub
, priv
, pub_p
, gxy
) < 0) {
267 plog(LLV_ERROR
, LOCATION
, NULL
,
268 "failed to compute dh value.\n");
272 case OAKLEY_ATTR_GRP_TYPE_ECP
:
273 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
274 plog(LLV_ERROR
, LOCATION
, NULL
,
275 "dh type %d isn't supported.\n", dh
->type
);
278 plog(LLV_ERROR
, LOCATION
, NULL
,
279 "invalid dh type %d.\n", dh
->type
);
284 gettimeofday(&end
, NULL
);
285 syslog(LOG_NOTICE
, "%s(%s%d): %8.6f", __func__
,
286 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
287 timedelta(&start
, &end
));
290 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's shared.\n");
291 plogdump(LLV_DEBUG
, (*gxy
)->v
, (*gxy
)->l
);
297 * generate values of DH
302 oakley_dh_generate(dh
, pub
, priv
)
303 const struct dhgroup
*dh
;
304 vchar_t
**pub
, **priv
;
307 struct timeval start
, end
;
308 gettimeofday(&start
, NULL
);
311 case OAKLEY_ATTR_GRP_TYPE_MODP
:
312 if (eay_dh_generate(dh
->prime
, dh
->gen1
, dh
->gen2
, pub
, priv
) < 0) {
313 plog(LLV_ERROR
, LOCATION
, NULL
,
314 "failed to compute dh value.\n");
319 case OAKLEY_ATTR_GRP_TYPE_ECP
:
320 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
321 plog(LLV_ERROR
, LOCATION
, NULL
,
322 "dh type %d isn't supported.\n", dh
->type
);
325 plog(LLV_ERROR
, LOCATION
, NULL
,
326 "invalid dh type %d.\n", dh
->type
);
331 gettimeofday(&end
, NULL
);
332 syslog(LOG_NOTICE
, "%s(%s%d): %8.6f", __func__
,
333 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
334 timedelta(&start
, &end
));
337 if (oakley_check_dh_pub(dh
->prime
, pub
) != 0)
340 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's private.\n");
341 plogdump(LLV_DEBUG
, (*priv
)->v
, (*priv
)->l
);
342 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's public.\n");
343 plogdump(LLV_DEBUG
, (*pub
)->v
, (*pub
)->l
);
349 * copy pre-defined dhgroup values.
352 oakley_setdhgroup(group
, dhgrp
)
354 struct dhgroup
**dhgrp
;
358 *dhgrp
= NULL
; /* just make sure, initialize */
360 g
= alg_oakley_dhdef_group(group
);
362 plog(LLV_ERROR
, LOCATION
, NULL
,
363 "invalid DH parameter grp=%d.\n", group
);
367 if (!g
->type
|| !g
->prime
|| !g
->gen1
) {
369 plog(LLV_ERROR
, LOCATION
, NULL
,
370 "unsupported DH parameters grp=%d.\n", group
);
374 *dhgrp
= racoon_calloc(1, sizeof(struct dhgroup
));
375 if (*dhgrp
== NULL
) {
376 plog(LLV_ERROR
, LOCATION
, NULL
,
377 "failed to get DH buffer.\n");
381 /* set defined dh vlaues */
382 memcpy(*dhgrp
, g
, sizeof(*g
));
383 (*dhgrp
)->prime
= vdup(g
->prime
);
391 * NOTE: we do not support prf with different input/output bitwidth,
392 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example) in
393 * oakley_compute_keymat(). If you add support for such prf function,
394 * modify oakley_compute_keymat() accordingly.
397 oakley_prf(key
, buf
, iph1
)
399 struct ph1handle
*iph1
;
404 if (iph1
->approval
== NULL
) {
406 * it's before negotiating hash algorithm.
407 * We use md5 as default.
409 type
= OAKLEY_ATTR_HASH_ALG_MD5
;
411 type
= iph1
->approval
->hashtype
;
413 res
= alg_oakley_hmacdef_one(type
, key
, buf
);
415 plog(LLV_ERROR
, LOCATION
, NULL
,
416 "invalid hmac algorithm %d.\n", type
);
427 oakley_hash(buf
, iph1
)
429 struct ph1handle
*iph1
;
434 if (iph1
->approval
== NULL
) {
436 * it's before negotiating hash algorithm.
437 * We use md5 as default.
439 type
= OAKLEY_ATTR_HASH_ALG_MD5
;
441 type
= iph1
->approval
->hashtype
;
443 res
= alg_oakley_hashdef_one(type
, buf
);
445 plog(LLV_ERROR
, LOCATION
, NULL
,
446 "invalid hash algorithm %d.\n", type
);
455 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
458 oakley_compute_keymat(iph2
, side
)
459 struct ph2handle
*iph2
;
464 /* compute sharing secret of DH when PFS */
465 if (iph2
->approval
->pfs_group
&& iph2
->dhpub_p
) {
466 if (oakley_dh_compute(iph2
->pfsgrp
, iph2
->dhpub
,
467 iph2
->dhpriv
, iph2
->dhpub_p
, &iph2
->dhgxy
) < 0)
472 if (oakley_compute_keymat_x(iph2
, side
, INBOUND_SA
) < 0
473 || oakley_compute_keymat_x(iph2
, side
, OUTBOUND_SA
) < 0)
476 plog(LLV_DEBUG
, LOCATION
, NULL
, "KEYMAT computed.\n");
486 * KEYMAT = prf(SKEYID_d, protocol | SPI | Ni_b | Nr_b).
487 * If PFS is desired and KE payloads were exchanged,
488 * KEYMAT = prf(SKEYID_d, g(qm)^xy | protocol | SPI | Ni_b | Nr_b)
490 * NOTE: we do not support prf with different input/output bitwidth,
491 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example).
494 oakley_compute_keymat_x(iph2
, side
, sa_dir
)
495 struct ph2handle
*iph2
;
499 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
504 int dupkeymat
; /* generate K[1-dupkeymat] */
507 int encklen
, authklen
, l
;
509 pfs
= ((iph2
->approval
->pfs_group
&& iph2
->dhgxy
) ? 1 : 0);
511 len
= pfs
? iph2
->dhgxy
->l
: 0;
513 + sizeof(u_int32_t
) /* XXX SPI size */
518 plog(LLV_ERROR
, LOCATION
, NULL
,
519 "failed to get keymat buffer.\n");
523 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
528 memcpy(p
, iph2
->dhgxy
->v
, iph2
->dhgxy
->l
);
535 memcpy(p
, (sa_dir
== INBOUND_SA
? &pr
->spi
: &pr
->spi_p
),
537 p
+= sizeof(pr
->spi
);
539 bp
= (side
== INITIATOR
? iph2
->nonce
: iph2
->nonce_p
);
540 memcpy(p
, bp
->v
, bp
->l
);
543 bp
= (side
== INITIATOR
? iph2
->nonce_p
: iph2
->nonce
);
544 memcpy(p
, bp
->v
, bp
->l
);
548 plog(LLV_DEBUG
, LOCATION
, NULL
, "KEYMAT compute with\n");
549 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
552 res
= oakley_prf(iph2
->ph1
->skeyid_d
, buf
, iph2
->ph1
);
556 /* compute key length needed */
557 encklen
= authklen
= 0;
558 switch (pr
->proto_id
) {
559 case IPSECDOI_PROTO_IPSEC_ESP
:
560 for (tr
= pr
->head
; tr
; tr
= tr
->next
) {
561 l
= alg_ipsec_encdef_keylen(tr
->trns_id
,
566 l
= alg_ipsec_hmacdef_hashlen(tr
->authtype
);
571 case IPSECDOI_PROTO_IPSEC_AH
:
572 for (tr
= pr
->head
; tr
; tr
= tr
->next
) {
573 l
= alg_ipsec_hmacdef_hashlen(tr
->trns_id
);
581 plog(LLV_DEBUG
, LOCATION
, NULL
, "encklen=%d authklen=%d\n",
584 dupkeymat
= (encklen
+ authklen
) / 8 / res
->l
;
585 dupkeymat
+= 2; /* safety mergin */
588 plog(LLV_DEBUG
, LOCATION
, NULL
,
589 "generating %zu bits of key (dupkeymat=%d)\n",
590 dupkeymat
* 8 * res
->l
, dupkeymat
);
591 if (0 < --dupkeymat
) {
592 vchar_t
*prev
= res
; /* K(n-1) */
593 vchar_t
*seed
= NULL
; /* seed for Kn */
597 * generating long key (isakmp-oakley-08 5.5)
598 * KEYMAT = K1 | K2 | K3 | ...
600 * src = [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b
601 * K1 = prf(SKEYID_d, src)
602 * K2 = prf(SKEYID_d, K1 | src)
603 * K3 = prf(SKEYID_d, K2 | src)
604 * Kn = prf(SKEYID_d, K(n-1) | src)
606 plog(LLV_DEBUG
, LOCATION
, NULL
,
607 "generating K1...K%d for KEYMAT.\n",
610 seed
= vmalloc(prev
->l
+ buf
->l
);
612 plog(LLV_ERROR
, LOCATION
, NULL
,
613 "failed to get keymat buffer.\n");
614 if (prev
&& prev
!= res
)
619 while (dupkeymat
--) {
620 vchar_t
*this = NULL
; /* Kn */
623 memcpy(seed
->v
, prev
->v
, prev
->l
);
624 memcpy(seed
->v
+ prev
->l
, buf
->v
, buf
->l
);
625 this = oakley_prf(iph2
->ph1
->skeyid_d
, seed
,
628 plog(LLV_ERROR
, LOCATION
, NULL
,
629 "oakley_prf memory overflow\n");
630 if (prev
&& prev
!= res
)
637 update_prev
= (prev
&& prev
== res
) ? 1 : 0;
640 res
= vrealloc(res
, l
+ this->l
);
646 plog(LLV_ERROR
, LOCATION
, NULL
,
647 "failed to get keymat buffer.\n");
648 if (prev
&& prev
!= res
)
654 memcpy(res
->v
+ l
, this->v
, this->l
);
656 if (prev
&& prev
!= res
)
662 if (prev
&& prev
!= res
)
667 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
669 if (sa_dir
== INBOUND_SA
)
680 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
702 * NOTE: Must terminate by NULL.
705 oakley_compute_hashx(struct ph1handle
*iph1
, ...)
714 /* get buffer length */
717 while ((s
= va_arg(ap
, vchar_t
*)) != NULL
) {
724 plog(LLV_ERROR
, LOCATION
, NULL
,
725 "failed to get hash buffer\n");
732 while ((s
= va_arg(ap
, char *)) != NULL
) {
733 memcpy(p
, s
->v
, s
->l
);
738 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with: \n");
739 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
742 res
= oakley_prf(iph1
->skeyid_a
, buf
, iph1
);
747 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH computed:\n");
748 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
755 * compute HASH(3) prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
756 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
759 oakley_compute_hash3(iph1
, msgid
, body
)
760 struct ph1handle
*iph1
;
764 vchar_t
*buf
= 0, *res
= 0;
769 len
= 1 + sizeof(u_int32_t
) + body
->l
;
772 plog(LLV_DEBUG
, LOCATION
, NULL
,
773 "failed to get hash buffer\n");
779 memcpy(buf
->v
+ 1, (char *)&msgid
, sizeof(msgid
));
781 memcpy(buf
->v
+ 1 + sizeof(u_int32_t
), body
->v
, body
->l
);
783 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with: \n");
784 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
787 res
= oakley_prf(iph1
->skeyid_a
, buf
, iph1
);
793 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH computed:\n");
794 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
803 * compute HASH type of prf(SKEYID_a, M-ID | buffer)
805 * for quick mode HASH(1):
806 * prf(SKEYID_a, M-ID | SA | Ni [ | KE ] [ | IDci | IDcr ])
807 * for quick mode HASH(2):
808 * prf(SKEYID_a, M-ID | Ni_b | SA | Nr [ | KE ] [ | IDci | IDcr ])
809 * for Informational exchange:
810 * prf(SKEYID_a, M-ID | N/D)
813 oakley_compute_hash1(iph1
, msgid
, body
)
814 struct ph1handle
*iph1
;
818 vchar_t
*buf
= NULL
, *res
= NULL
;
824 len
= sizeof(u_int32_t
) + body
->l
;
827 plog(LLV_DEBUG
, LOCATION
, NULL
,
828 "failed to get hash buffer\n");
834 memcpy(buf
->v
, (char *)&msgid
, sizeof(msgid
));
835 p
+= sizeof(u_int32_t
);
837 memcpy(p
, body
->v
, body
->l
);
839 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with:\n");
840 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
843 res
= oakley_prf(iph1
->skeyid_a
, buf
, iph1
);
849 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH computed:\n");
850 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
859 * compute phase1 HASH
861 * I-digest = prf(SKEYID, g^i | g^r | CKY-I | CKY-R | SAi_b | ID_i1_b)
862 * R-digest = prf(SKEYID, g^r | g^i | CKY-R | CKY-I | SAi_b | ID_r1_b)
863 * for gssapi, also include all GSS tokens, and call gss_wrap on the result
866 oakley_ph1hash_common(iph1
, sw
)
867 struct ph1handle
*iph1
;
870 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
875 vchar_t
*gsstokens
= NULL
;
881 + sizeof(cookie_t
) * 2
883 + (sw
== GENERATE
? iph1
->id
->l
: iph1
->id_p
->l
);
886 if (AUTHMETHOD(iph1
) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
) {
887 if (iph1
->gi_i
!= NULL
&& iph1
->gi_r
!= NULL
) {
888 bp
= (sw
== GENERATE
? iph1
->gi_i
: iph1
->gi_r
);
892 gssapi_get_itokens(iph1
, &gsstokens
);
894 gssapi_get_rtokens(iph1
, &gsstokens
);
895 if (gsstokens
== NULL
)
903 plog(LLV_ERROR
, LOCATION
, NULL
,
904 "failed to get hash buffer\n");
910 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
911 memcpy(p
, bp
->v
, bp
->l
);
914 bp
= (sw
== GENERATE
? iph1
->dhpub_p
: iph1
->dhpub
);
915 memcpy(p
, bp
->v
, bp
->l
);
918 if (iph1
->side
== INITIATOR
)
919 bp2
= (sw
== GENERATE
?
920 (char *)&iph1
->index
.i_ck
: (char *)&iph1
->index
.r_ck
);
922 bp2
= (sw
== GENERATE
?
923 (char *)&iph1
->index
.r_ck
: (char *)&iph1
->index
.i_ck
);
924 bl
= sizeof(cookie_t
);
928 if (iph1
->side
== INITIATOR
)
929 bp2
= (sw
== GENERATE
?
930 (char *)&iph1
->index
.r_ck
: (char *)&iph1
->index
.i_ck
);
932 bp2
= (sw
== GENERATE
?
933 (char *)&iph1
->index
.i_ck
: (char *)&iph1
->index
.r_ck
);
934 bl
= sizeof(cookie_t
);
939 memcpy(p
, bp
->v
, bp
->l
);
942 bp
= (sw
== GENERATE
? iph1
->id
: iph1
->id_p
);
943 memcpy(p
, bp
->v
, bp
->l
);
947 if (AUTHMETHOD(iph1
) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
) {
948 if (iph1
->gi_i
!= NULL
&& iph1
->gi_r
!= NULL
) {
949 bp
= (sw
== GENERATE
? iph1
->gi_i
: iph1
->gi_r
);
950 memcpy(p
, bp
->v
, bp
->l
);
953 memcpy(p
, gsstokens
->v
, gsstokens
->l
);
958 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with:\n");
959 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
962 res
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
968 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH (%s) computed:\n",
969 iph1
->side
== INITIATOR
? "init" : "resp");
970 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
976 if (gsstokens
!= NULL
)
983 * compute HASH_I on base mode.
985 * HASH_I = prf(SKEYID, g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
987 * HASH_I = prf(hash(Ni_b | Nr_b), g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
990 oakley_ph1hash_base_i(iph1
, sw
)
991 struct ph1handle
*iph1
;
994 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
995 vchar_t
*hashkey
= NULL
;
996 vchar_t
*hash
= NULL
; /* for signature mode */
1002 if (iph1
->etype
!= ISAKMP_ETYPE_BASE
) {
1003 plog(LLV_ERROR
, LOCATION
, NULL
,
1004 "invalid etype for this hash function\n");
1008 switch (AUTHMETHOD(iph1
)) {
1009 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
1010 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
1011 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
1012 #ifdef ENABLE_HYBRID
1013 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
1014 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
1015 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
1016 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
1017 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
1018 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
1020 if (iph1
->skeyid
== NULL
) {
1021 plog(LLV_ERROR
, LOCATION
, NULL
, "no SKEYID found.\n");
1024 hashkey
= iph1
->skeyid
;
1027 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
1028 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1030 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
1032 #ifdef ENABLE_HYBRID
1033 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1034 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1035 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1036 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
1037 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
1038 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1039 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
1040 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
1042 /* make hash for seed */
1043 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
1046 plog(LLV_ERROR
, LOCATION
, NULL
,
1047 "failed to get hash buffer\n");
1052 bp
= (sw
== GENERATE
? iph1
->nonce_p
: iph1
->nonce
);
1053 memcpy(p
, bp
->v
, bp
->l
);
1056 bp
= (sw
== GENERATE
? iph1
->nonce
: iph1
->nonce_p
);
1057 memcpy(p
, bp
->v
, bp
->l
);
1060 hash
= oakley_hash(buf
, iph1
);
1070 plog(LLV_ERROR
, LOCATION
, NULL
,
1071 "not supported authentication method %d\n",
1072 iph1
->approval
->authmethod
);
1077 len
= (sw
== GENERATE
? iph1
->dhpub
->l
: iph1
->dhpub_p
->l
)
1078 + sizeof(cookie_t
) * 2
1080 + (sw
== GENERATE
? iph1
->id
->l
: iph1
->id_p
->l
);
1083 plog(LLV_ERROR
, LOCATION
, NULL
,
1084 "failed to get hash buffer\n");
1089 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
1090 memcpy(p
, bp
->v
, bp
->l
);
1093 memcpy(p
, &iph1
->index
.i_ck
, sizeof(cookie_t
));
1094 p
+= sizeof(cookie_t
);
1095 memcpy(p
, &iph1
->index
.r_ck
, sizeof(cookie_t
));
1096 p
+= sizeof(cookie_t
);
1098 memcpy(p
, iph1
->sa
->v
, iph1
->sa
->l
);
1101 bp
= (sw
== GENERATE
? iph1
->id
: iph1
->id_p
);
1102 memcpy(p
, bp
->v
, bp
->l
);
1105 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH_I with:\n");
1106 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
1109 res
= oakley_prf(hashkey
, buf
, iph1
);
1115 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH_I computed:\n");
1116 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
1127 * compute HASH_R on base mode for signature method.
1129 * HASH_R = prf(hash(Ni_b | Nr_b), g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b)
1132 oakley_ph1hash_base_r(iph1
, sw
)
1133 struct ph1handle
*iph1
;
1136 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
1137 vchar_t
*hash
= NULL
;
1143 if (iph1
->etype
!= ISAKMP_ETYPE_BASE
) {
1144 plog(LLV_ERROR
, LOCATION
, NULL
,
1145 "invalid etype for this hash function\n");
1149 switch(AUTHMETHOD(iph1
)) {
1150 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
1151 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1152 #ifdef ENABLE_HYBRID
1153 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1154 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1155 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1156 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
1157 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
1158 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1159 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
1160 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
1161 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
1165 plog(LLV_ERROR
, LOCATION
, NULL
,
1166 "not supported authentication method %d\n",
1167 iph1
->approval
->authmethod
);
1172 /* make hash for seed */
1173 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
1176 plog(LLV_ERROR
, LOCATION
, NULL
,
1177 "failed to get hash buffer\n");
1182 bp
= (sw
== GENERATE
? iph1
->nonce_p
: iph1
->nonce
);
1183 memcpy(p
, bp
->v
, bp
->l
);
1186 bp
= (sw
== GENERATE
? iph1
->nonce
: iph1
->nonce_p
);
1187 memcpy(p
, bp
->v
, bp
->l
);
1190 hash
= oakley_hash(buf
, iph1
);
1196 /* make really hash */
1197 len
= (sw
== GENERATE
? iph1
->dhpub_p
->l
: iph1
->dhpub
->l
)
1198 + (sw
== GENERATE
? iph1
->dhpub
->l
: iph1
->dhpub_p
->l
)
1199 + sizeof(cookie_t
) * 2
1201 + (sw
== GENERATE
? iph1
->id_p
->l
: iph1
->id
->l
);
1204 plog(LLV_ERROR
, LOCATION
, NULL
,
1205 "failed to get hash buffer\n");
1211 bp
= (sw
== GENERATE
? iph1
->dhpub_p
: iph1
->dhpub
);
1212 memcpy(p
, bp
->v
, bp
->l
);
1215 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
1216 memcpy(p
, bp
->v
, bp
->l
);
1219 memcpy(p
, &iph1
->index
.i_ck
, sizeof(cookie_t
));
1220 p
+= sizeof(cookie_t
);
1221 memcpy(p
, &iph1
->index
.r_ck
, sizeof(cookie_t
));
1222 p
+= sizeof(cookie_t
);
1224 memcpy(p
, iph1
->sa
->v
, iph1
->sa
->l
);
1227 bp
= (sw
== GENERATE
? iph1
->id_p
: iph1
->id
);
1228 memcpy(p
, bp
->v
, bp
->l
);
1231 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH_R with:\n");
1232 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
1235 res
= oakley_prf(hash
, buf
, iph1
);
1241 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH_R computed:\n");
1242 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
1253 * compute each authentication method in phase 1.
1257 * other: error to be reply with notification.
1258 * the value is notification type.
1261 oakley_validate_auth(iph1
)
1262 struct ph1handle
*iph1
;
1264 vchar_t
*my_hash
= NULL
;
1267 vchar_t
*gsshash
= NULL
;
1270 struct timeval start
, end
;
1274 gettimeofday(&start
, NULL
);
1277 switch (AUTHMETHOD(iph1
)) {
1278 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
1279 #ifdef ENABLE_HYBRID
1280 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
1281 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
1287 if (iph1
->id_p
== NULL
|| iph1
->pl_hash
== NULL
) {
1288 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1289 "few isakmp message received.\n");
1290 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1292 #ifdef ENABLE_HYBRID
1293 if (AUTHMETHOD(iph1
) == FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
&&
1294 ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_VENDORID_XAUTH
) == 0))
1296 plog(LLV_ERROR
, LOCATION
, NULL
, "No SIG was passed, "
1297 "hybrid auth is enabled, "
1298 "but peer is no Xauth compliant\n");
1299 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED
;
1303 r_hash
= (caddr_t
)(iph1
->pl_hash
+ 1);
1305 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH received:\n");
1306 plogdump(LLV_DEBUG
, r_hash
,
1307 ntohs(iph1
->pl_hash
->h
.len
) - sizeof(*iph1
->pl_hash
));
1309 switch (iph1
->etype
) {
1310 case ISAKMP_ETYPE_IDENT
:
1311 case ISAKMP_ETYPE_AGG
:
1312 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1314 case ISAKMP_ETYPE_BASE
:
1315 if (iph1
->side
== INITIATOR
)
1316 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1318 my_hash
= oakley_ph1hash_base_i(iph1
, VALIDATE
);
1321 plog(LLV_ERROR
, LOCATION
, NULL
,
1322 "invalid etype %d\n", iph1
->etype
);
1323 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1325 if (my_hash
== NULL
)
1326 return ISAKMP_INTERNAL_ERROR
;
1328 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1332 plog(LLV_ERROR
, LOCATION
, NULL
, "HASH mismatched\n");
1333 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1336 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH for PSK validated.\n");
1339 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
1340 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1341 #ifdef ENABLE_HYBRID
1342 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1343 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1344 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
1345 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1346 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
1347 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
1354 if (iph1
->id_p
== NULL
) {
1355 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1356 "no ID payload was passed.\n");
1357 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1359 if (iph1
->sig_p
== NULL
) {
1360 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1361 "no SIG payload was passed.\n");
1362 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1365 plog(LLV_DEBUG
, LOCATION
, NULL
, "SIGN passed:\n");
1366 plogdump(LLV_DEBUG
, iph1
->sig_p
->v
, iph1
->sig_p
->l
);
1368 /* get peer's cert */
1369 switch (iph1
->rmconf
->getcert_method
) {
1370 case ISAKMP_GETCERT_PAYLOAD
:
1371 if (iph1
->cert_p
== NULL
) {
1372 plog(LLV_ERROR
, LOCATION
, NULL
,
1373 "no peer's CERT payload found.\n");
1374 return ISAKMP_INTERNAL_ERROR
;
1377 case ISAKMP_GETCERT_LOCALFILE
:
1378 switch (iph1
->rmconf
->certtype
) {
1379 case ISAKMP_CERT_X509SIGN
:
1380 if (iph1
->rmconf
->peerscertfile
== NULL
) {
1381 plog(LLV_ERROR
, LOCATION
, NULL
,
1382 "no peer's CERT file found.\n");
1383 return ISAKMP_INTERNAL_ERROR
;
1386 /* don't use cached cert */
1387 if (iph1
->cert_p
!= NULL
) {
1388 oakley_delcert(iph1
->cert_p
);
1389 iph1
->cert_p
= NULL
;
1392 error
= get_cert_fromlocal(iph1
, 0);
1395 case ISAKMP_CERT_PLAINRSA
:
1396 error
= get_plainrsa_fromlocal(iph1
, 0);
1400 return ISAKMP_INTERNAL_ERROR
;
1402 case ISAKMP_GETCERT_DNS
:
1403 if (iph1
->rmconf
->peerscertfile
!= NULL
) {
1404 plog(LLV_ERROR
, LOCATION
, NULL
,
1405 "why peer's CERT file is defined "
1406 "though getcert method is dns ?\n");
1407 return ISAKMP_INTERNAL_ERROR
;
1410 /* don't use cached cert */
1411 if (iph1
->cert_p
!= NULL
) {
1412 oakley_delcert(iph1
->cert_p
);
1413 iph1
->cert_p
= NULL
;
1416 iph1
->cert_p
= dnssec_getcert(iph1
->id_p
);
1417 if (iph1
->cert_p
== NULL
) {
1418 plog(LLV_ERROR
, LOCATION
, NULL
,
1419 "no CERT RR found.\n");
1420 return ISAKMP_INTERNAL_ERROR
;
1424 plog(LLV_ERROR
, LOCATION
, NULL
,
1425 "invalid getcert_mothod: %d\n",
1426 iph1
->rmconf
->getcert_method
);
1427 return ISAKMP_INTERNAL_ERROR
;
1430 /* compare ID payload and certificate name */
1431 if (iph1
->rmconf
->verify_cert
&&
1433 (error
= oakley_check_certid(iph1
, CERT_CHECKID_FROM_PEER
)) != 0)
1435 (error
= oakley_check_certid(iph1
)) != 0)
1441 /* check configured peers identifier against cert IDs */
1442 /* allows checking of specified ID against multiple ids in the cert */
1443 /* such as multiple domain names */
1444 #if !TARGET_OS_EMBEDDED
1445 if (iph1
->rmconf
->cert_verification_option
== VERIFICATION_OPTION_PEERS_IDENTIFIER
&&
1446 (error
= oakley_check_certid(iph1
, CERT_CHECKID_FROM_RMCONFIG
)) != 0)
1451 /* check cert common name against Open Directory authentication group */
1452 if (iph1
->rmconf
->cert_verification_option
== VERIFICATION_OPTION_OPEN_DIR
) {
1454 vchar_t
*user_id
= NULL
;
1456 user_id
= eay_get_x509_common_name(&iph1
->cert_p
->cert
);
1458 // the following functions will check if user_id == 0
1459 if (open_dir_authorize_id(user_id
, iph1
->rmconf
->open_dir_auth_group
) == 0) {
1460 plog(LLV_ERROR
, LOCATION
, NULL
,
1461 "the peer is not authorized for access.\n");
1463 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1467 plog(LLV_ERROR
, LOCATION
, NULL
,
1468 "the peer is not authorized for access - user ID not found.\n");
1469 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1472 #endif /* HAVE_OPENDIR */
1473 #endif /* __APPLE__ */
1475 /* verify certificate */
1476 if (iph1
->rmconf
->verify_cert
1477 && iph1
->rmconf
->getcert_method
== ISAKMP_GETCERT_PAYLOAD
) {
1478 certtype
= iph1
->rmconf
->certtype
;
1479 #ifdef ENABLE_HYBRID
1480 switch (AUTHMETHOD(iph1
)) {
1481 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1482 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1483 certtype
= iph1
->cert_p
->type
;
1490 case ISAKMP_CERT_X509SIGN
:
1492 #if TARGET_OS_EMBEDDED
1494 /* use ID from remote configuration */
1495 /* check each ID in list */
1496 struct idspec
*id_spec
;
1497 CFStringRef hostname
= NULL
;
1499 struct genlist_entry
*gpb
= NULL
;
1501 if (iph1
->rmconf
->cert_verification_option
== VERIFICATION_OPTION_PEERS_IDENTIFIER
) {
1502 id_spec
= genlist_next(iph1
->rmconf
->idvl_p
, &gpb
); /* expect only one id */
1503 if (id_spec
->idtype
== IDTYPE_ADDRESS
) {
1504 switch (((struct sockaddr
*)(id_spec
->id
->v
))->sa_family
) {
1506 peers_id
= inet_ntoa(((struct sockaddr_in
*)(id_spec
->id
->v
))->sin_addr
);
1507 hostname
= CFStringCreateWithCString(NULL
, peers_id
, kCFStringEncodingUTF8
);
1511 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
; /* not currently supported for embedded */
1515 plog(LLV_ERROR
, LOCATION
, NULL
,
1516 "unknown address type for peers identifier.\n");
1517 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1521 hostname
= CFStringCreateWithBytes(NULL
, (u_int8_t
*)id_spec
->id
->v
, id_spec
->id
->l
, kCFStringEncodingUTF8
, FALSE
);
1523 error
= crypto_cssm_check_x509cert(&iph1
->cert_p
->cert
, hostname
);
1525 CFRelease(hostname
);
1528 #else /* TARGET_OS_EMBEDDED */
1530 if (iph1
->rmconf
->cert_verification
== VERIFICATION_MODULE_SEC_FRAMEWORK
)
1531 error
= crypto_cssm_check_x509cert(&iph1
->cert_p
->cert
, NULL
);
1533 #endif /* __APPLE__ */
1535 char path
[MAXPATHLEN
];
1538 if (iph1
->rmconf
->cacertfile
!= NULL
) {
1539 getpathname(path
, sizeof(path
),
1541 iph1
->rmconf
->cacertfile
);
1547 error
= eay_check_x509cert(&iph1
->cert_p
->cert
,
1548 lcconf
->pathinfo
[LC_PATHTYPE_CERT
],
1551 #endif /* TARGET_OS_EMBEDDED */
1555 plog(LLV_ERROR
, LOCATION
, NULL
,
1556 "no supported certtype %d\n", certtype
);
1557 return ISAKMP_INTERNAL_ERROR
;
1560 plog(LLV_ERROR
, LOCATION
, NULL
,
1561 "the peer's certificate is not verified.\n");
1562 return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY
;
1566 plog(LLV_DEBUG
, LOCATION
, NULL
, "CERT validated\n");
1569 switch (iph1
->etype
) {
1570 case ISAKMP_ETYPE_IDENT
:
1571 case ISAKMP_ETYPE_AGG
:
1572 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1574 case ISAKMP_ETYPE_BASE
:
1575 if (iph1
->side
== INITIATOR
)
1576 my_hash
= oakley_ph1hash_base_r(iph1
, VALIDATE
);
1578 my_hash
= oakley_ph1hash_base_i(iph1
, VALIDATE
);
1581 plog(LLV_ERROR
, LOCATION
, NULL
,
1582 "invalid etype %d\n", iph1
->etype
);
1583 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1585 if (my_hash
== NULL
)
1586 return ISAKMP_INTERNAL_ERROR
;
1589 certtype
= iph1
->rmconf
->certtype
;
1590 #ifdef ENABLE_HYBRID
1591 switch (AUTHMETHOD(iph1
)) {
1592 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1593 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1594 certtype
= iph1
->cert_p
->type
;
1600 /* check signature */
1602 case ISAKMP_CERT_X509SIGN
:
1603 case ISAKMP_CERT_DNS
:
1604 error
= eay_check_x509sign(my_hash
,
1606 &iph1
->cert_p
->cert
);
1608 case ISAKMP_CERT_PLAINRSA
:
1609 iph1
->rsa_p
= rsa_try_check_rsasign(my_hash
,
1610 iph1
->sig_p
, iph1
->rsa_candidates
);
1611 error
= iph1
->rsa_p
? 0 : -1;
1615 plog(LLV_ERROR
, LOCATION
, NULL
,
1616 "no supported certtype %d\n",
1619 return ISAKMP_INTERNAL_ERROR
;
1624 plog(LLV_ERROR
, LOCATION
, NULL
,
1626 return ISAKMP_NTYPE_INVALID_SIGNATURE
;
1628 plog(LLV_DEBUG
, LOCATION
, NULL
, "SIG authenticated\n");
1631 #ifdef ENABLE_HYBRID
1632 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1633 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
1635 if ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_VENDORID_XAUTH
) == 0) {
1636 plog(LLV_ERROR
, LOCATION
, NULL
, "No SIG was passed, "
1637 "hybrid auth is enabled, "
1638 "but peer is no Xauth compliant\n");
1639 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED
;
1642 plog(LLV_INFO
, LOCATION
, NULL
, "No SIG was passed, "
1643 "but hybrid auth is enabled\n");
1650 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
1651 /* check if we're not into XAUTH_PSKEY_I instead */
1652 #ifdef ENABLE_HYBRID
1653 if (iph1
->rmconf
->xauth
)
1656 switch (iph1
->etype
) {
1657 case ISAKMP_ETYPE_IDENT
:
1658 case ISAKMP_ETYPE_AGG
:
1659 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1662 plog(LLV_ERROR
, LOCATION
, NULL
,
1663 "invalid etype %d\n", iph1
->etype
);
1664 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1667 if (my_hash
== NULL
) {
1668 if (gssapi_more_tokens(iph1
))
1669 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1671 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1674 gsshash
= gssapi_unwraphash(iph1
);
1675 if (gsshash
== NULL
) {
1677 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1680 result
= memcmp(my_hash
->v
, gsshash
->v
, my_hash
->l
);
1685 plog(LLV_ERROR
, LOCATION
, NULL
, "HASH mismatched\n");
1686 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1688 plog(LLV_DEBUG
, LOCATION
, NULL
, "hash compared OK\n");
1691 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
1692 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
1693 #ifdef ENABLE_HYBRID
1694 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
1695 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
1696 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
1697 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
1699 if (iph1
->id_p
== NULL
|| iph1
->pl_hash
== NULL
) {
1700 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1701 "few isakmp message received.\n");
1702 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1704 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1705 "not supported authmethod type %s\n",
1706 s_oakley_attr_method(iph1
->approval
->authmethod
));
1707 return ISAKMP_INTERNAL_ERROR
;
1709 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1710 "invalid authmethod %d why ?\n",
1711 iph1
->approval
->authmethod
);
1712 return ISAKMP_INTERNAL_ERROR
;
1715 gettimeofday(&end
, NULL
);
1716 syslog(LOG_NOTICE
, "%s(%s): %8.6f", __func__
,
1717 s_oakley_attr_method(iph1
->approval
->authmethod
),
1718 timedelta(&start
, &end
));
1724 /* get my certificate
1725 * NOTE: include certificate type.
1728 oakley_getmycert(iph1
)
1729 struct ph1handle
*iph1
;
1731 switch (iph1
->rmconf
->certtype
) {
1732 case ISAKMP_CERT_X509SIGN
:
1735 return get_cert_fromlocal(iph1
, 1);
1737 case ISAKMP_CERT_PLAINRSA
:
1740 return get_plainrsa_fromlocal(iph1
, 1);
1743 plog(LLV_ERROR
, LOCATION
, NULL
,
1744 "Unknown certtype #%d\n",
1745 iph1
->rmconf
->certtype
);
1752 * get a CERT from local file.
1755 * my == 0 peer's cert.
1758 get_cert_fromlocal(iph1
, my
)
1759 struct ph1handle
*iph1
;
1762 char path
[MAXPATHLEN
];
1763 vchar_t
*cert
= NULL
;
1769 certfile
= iph1
->rmconf
->mycertfile
;
1770 certpl
= &iph1
->cert
;
1772 certfile
= iph1
->rmconf
->peerscertfile
;
1773 certpl
= &iph1
->cert_p
;
1777 if (!certfile
&& iph1
->rmconf
->identity_in_keychain
== 0) {
1781 plog(LLV_ERROR
, LOCATION
, NULL
, "no CERT defined.\n");
1785 switch (iph1
->rmconf
->certtype
) {
1786 case ISAKMP_CERT_X509SIGN
:
1787 #if defined(__APPLE__)
1788 if (iph1
->rmconf
->identity_in_keychain
) {
1791 if (iph1
->rmconf
->keychainCertRef
== NULL
|| base64toCFData(iph1
->rmconf
->keychainCertRef
, &dataRef
))
1793 cert
= crypto_cssm_get_x509cert(dataRef
);
1798 case ISAKMP_CERT_DNS
:
1799 /* make public file name */
1800 getpathname(path
, sizeof(path
), LC_PATHTYPE_CERT
, certfile
);
1801 cert
= eay_get_x509cert(path
);
1804 p
= eay_get_x509text(cert
);
1805 plog(LLV_DEBUG
, LOCATION
, NULL
, "%s", p
? p
: "\n");
1811 plog(LLV_ERROR
, LOCATION
, NULL
,
1812 "not supported certtype %d\n",
1813 iph1
->rmconf
->certtype
);
1818 plog(LLV_ERROR
, LOCATION
, NULL
,
1819 "failed to get %s CERT.\n",
1820 my
? "my" : "peers");
1824 *certpl
= oakley_newcert();
1826 plog(LLV_ERROR
, LOCATION
, NULL
,
1827 "failed to get cert buffer.\n");
1830 (*certpl
)->pl
= vmalloc(cert
->l
+ 1);
1831 if ((*certpl
)->pl
== NULL
) {
1832 plog(LLV_ERROR
, LOCATION
, NULL
,
1833 "failed to get cert buffer\n");
1834 oakley_delcert(*certpl
);
1838 memcpy((*certpl
)->pl
->v
+ 1, cert
->v
, cert
->l
);
1839 (*certpl
)->pl
->v
[0] = iph1
->rmconf
->certtype
;
1840 (*certpl
)->type
= iph1
->rmconf
->certtype
;
1841 (*certpl
)->cert
.v
= (*certpl
)->pl
->v
+ 1;
1842 (*certpl
)->cert
.l
= (*certpl
)->pl
->l
- 1;
1844 plog(LLV_DEBUG
, LOCATION
, NULL
, "created CERT payload:\n");
1845 plogdump(LLV_DEBUG
, (*certpl
)->pl
->v
, (*certpl
)->pl
->l
);
1857 get_plainrsa_fromlocal(iph1
, my
)
1858 struct ph1handle
*iph1
;
1861 char path
[MAXPATHLEN
];
1862 vchar_t
*cert
= NULL
;
1866 iph1
->rsa_candidates
= rsa_lookup_keys(iph1
, my
);
1867 if (!iph1
->rsa_candidates
||
1868 rsa_list_count(iph1
->rsa_candidates
) == 0) {
1869 plog(LLV_ERROR
, LOCATION
, NULL
,
1870 "%s RSA key not found for %s\n",
1871 my
? "Private" : "Public",
1872 saddr2str_fromto("%s <-> %s",
1873 iph1
->local
, iph1
->remote
));
1877 if (my
&& rsa_list_count(iph1
->rsa_candidates
) > 1) {
1878 plog(LLV_WARNING
, LOCATION
, NULL
,
1879 "More than one (=%lu) private "
1880 "PlainRSA key found for %s\n",
1881 rsa_list_count(iph1
->rsa_candidates
),
1882 saddr2str_fromto("%s <-> %s",
1883 iph1
->local
, iph1
->remote
));
1884 plog(LLV_WARNING
, LOCATION
, NULL
,
1885 "This may have unpredictable results, "
1886 "i.e. wrong key could be used!\n");
1887 plog(LLV_WARNING
, LOCATION
, NULL
,
1888 "Consider using only one single private "
1889 "key for all peers...\n");
1892 iph1
->rsa
= ((struct rsa_key
*)
1893 genlist_next(iph1
->rsa_candidates
, NULL
))->rsa
;
1895 genlist_free(iph1
->rsa_candidates
, NULL
);
1896 iph1
->rsa_candidates
= NULL
;
1898 if (iph1
->rsa
== NULL
)
1910 oakley_getsign(iph1
)
1911 struct ph1handle
*iph1
;
1913 char path
[MAXPATHLEN
];
1914 vchar_t
*privkey
= NULL
;
1917 switch (iph1
->rmconf
->certtype
) {
1918 case ISAKMP_CERT_X509SIGN
:
1919 #if defined(__APPLE__)
1920 // cert in keychain - use cssm to sign
1921 if (iph1
->rmconf
->identity_in_keychain
) {
1924 if (iph1
->rmconf
->keychainCertRef
== NULL
|| base64toCFData(iph1
->rmconf
->keychainCertRef
, &dataRef
))
1926 iph1
->sig
= crypto_cssm_getsign(dataRef
, iph1
->hash
);
1931 case ISAKMP_CERT_DNS
:
1932 if (iph1
->rmconf
->myprivfile
== NULL
) {
1933 plog(LLV_ERROR
, LOCATION
, NULL
, "no cert defined.\n");
1937 /* make private file name */
1938 getpathname(path
, sizeof(path
),
1940 iph1
->rmconf
->myprivfile
);
1941 privkey
= privsep_eay_get_pkcs1privkey(path
);
1942 if (privkey
== NULL
) {
1943 plog(LLV_ERROR
, LOCATION
, NULL
,
1944 "failed to get private key.\n");
1947 plog(LLV_DEBUG2
, LOCATION
, NULL
, "private key:\n");
1948 plogdump(LLV_DEBUG2
, privkey
->v
, privkey
->l
);
1950 iph1
->sig
= eay_get_x509sign(iph1
->hash
, privkey
);
1952 case ISAKMP_CERT_PLAINRSA
:
1953 iph1
->sig
= eay_get_rsasign(iph1
->hash
, iph1
->rsa
);
1956 plog(LLV_ERROR
, LOCATION
, NULL
,
1957 "Unknown certtype #%d\n",
1958 iph1
->rmconf
->certtype
);
1962 if (iph1
->sig
== NULL
) {
1963 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to sign.\n");
1967 plog(LLV_DEBUG
, LOCATION
, NULL
, "SIGN computed:\n");
1968 plogdump(LLV_DEBUG
, iph1
->sig
->v
, iph1
->sig
->l
);
1973 if (privkey
!= NULL
)
1982 * compare certificate name and ID value.
1985 oakley_check_certid(iph1
, which_id
)
1986 struct ph1handle
*iph1
;
1989 struct ipsecdoi_id_b
*id_b
;
1991 u_int8_t doi_type
= 255;
1992 void *peers_id
= NULL
;
1993 struct genlist_entry
*gpb
= NULL
;
1995 if (which_id
== CERT_CHECKID_FROM_PEER
) {
1996 /* use ID from peer */
1997 if (iph1
->id_p
== NULL
|| iph1
->cert_p
== NULL
) {
1998 plog(LLV_ERROR
, LOCATION
, NULL
, "no ID nor CERT found.\n");
1999 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2001 id_b
= (struct ipsecdoi_id_b
*)iph1
->id_p
->v
;
2002 doi_type
= id_b
->type
;
2003 peers_id
= id_b
+ 1;
2004 idlen
= iph1
->id_p
->l
- sizeof(*id_b
);
2006 return oakley_check_certid_1(iph1
, doi_type
, idlen
, peers_id
);
2009 /* use ID from remote configuration */
2010 /* check each ID in list */
2011 struct idspec
*id_spec
;
2013 for (id_spec
= genlist_next (iph1
->rmconf
->idvl_p
, &gpb
); id_spec
; id_spec
= genlist_next (0, &gpb
)) {
2015 if (id_spec
->idtype
== IDTYPE_ADDRESS
) {
2016 switch (((struct sockaddr
*)(id_spec
->id
->v
))->sa_family
) {
2018 doi_type
= IPSECDOI_ID_IPV4_ADDR
;
2019 idlen
= sizeof(struct in_addr
);
2020 peers_id
= &(((struct sockaddr_in
*)(id_spec
->id
->v
))->sin_addr
.s_addr
);
2024 doi_type
= IPSECDOI_ID_IPV6_ADDR
;
2025 idlen
= sizeof(struct in6_addr
);
2026 peers_id
= &(((struct sockaddr_in6
*)(id_spec
->id
->v
))->sin6_addr
.s6_addr
);
2030 plog(LLV_ERROR
, LOCATION
, NULL
,
2031 "unknown address type for peers identifier.\n");
2032 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
2037 doi_type
= idtype2doi(id_spec
->idtype
);
2038 peers_id
= id_spec
->id
->v
;
2039 idlen
= id_spec
->id
->l
;
2041 if (oakley_check_certid_1(iph1
, doi_type
, idlen
, peers_id
) == 0)
2044 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2049 oakley_check_certid_1(iph1
, idtype
, idlen
, id
)
2050 struct ph1handle
*iph1
;
2056 vchar_t
*name
= NULL
;
2057 char *altname
= NULL
;
2062 case IPSECDOI_ID_DER_ASN1_DN
:
2063 name
= eay_get_x509asn1subjectname(&iph1
->cert_p
->cert
);
2065 plog(LLV_ERROR
, LOCATION
, NULL
,
2066 "failed to get subjectName\n");
2067 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2069 if (idlen
!= name
->l
) {
2070 plog(LLV_ERROR
, LOCATION
, NULL
,
2071 "Invalid ID length in phase 1.\n");
2073 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2075 error
= memcmp(id
, name
->v
, idlen
);
2078 plog(LLV_ERROR
, LOCATION
, NULL
,
2079 "ID mismatched with subjectName.\n");
2080 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2083 case IPSECDOI_ID_IPV4_ADDR
:
2084 case IPSECDOI_ID_IPV6_ADDR
:
2088 * Openssl returns the IPAddress as an ASN1 octet string (binary format)
2089 * followed by a trailing NULL. 5 bytes for IPv4 and 17 bytes for IPv6
2091 #define SUBJ_ALT_NAME_IPV4_ADDRESS_LEN 5
2092 #define SUBJ_ALT_NAME_IPV6_ADDRESS_LEN 17
2096 if (idtype
== IPSECDOI_ID_IPV4_ADDR
&& idlen
!= sizeof(struct in_addr
)
2097 || idtype
== IPSECDOI_ID_IPV6_ADDR
&& idlen
!= sizeof(struct in6_addr
)) {
2098 plog(LLV_ERROR
, LOCATION
, NULL
,
2099 "invalid address length passed.\n");
2100 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2103 for (pos
= 1; ; pos
++) {
2104 if (eay_get_x509subjectaltname(&iph1
->cert_p
->cert
, &altname
, &type
, pos
, &len
) !=0) {
2105 plog(LLV_ERROR
, LOCATION
, NULL
,
2106 "failed to get subjectAltName\n");
2107 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2110 /* it's the end condition of the loop. */
2112 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2115 if (check_typeofcertname(idtype
, type
) != 0) {
2116 /* wrong type - skip this one */
2117 racoon_free(altname
);
2122 if (len
== SUBJ_ALT_NAME_IPV4_ADDRESS_LEN
) { /* IPv4 */
2123 if (idtype
!= IPSECDOI_ID_IPV4_ADDR
) {
2124 /* wrong IP address type - skip this one */
2125 racoon_free(altname
);
2131 else if (len
== SUBJ_ALT_NAME_IPV6_ADDRESS_LEN
) { /* IPv6 */
2132 if (idtype
!= IPSECDOI_ID_IPV6_ADDR
) {
2133 /* wrong IP address type - skip this one */
2134 racoon_free(altname
);
2141 /* invalid IP address length in certificate - bad or bogus certificate */
2142 plog(LLV_ERROR
, LOCATION
, NULL
,
2143 "invalid IP address in certificate.\n");
2144 racoon_free(altname
);
2146 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2149 /* compare the addresses */
2150 error
= memcmp(id
, altname
, idlen
);
2151 racoon_free(altname
);
2153 plog(LLV_ERROR
, LOCATION
, NULL
,
2154 "ID mismatched with subjectAltName.\n");
2155 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2160 case IPSECDOI_ID_FQDN
:
2161 case IPSECDOI_ID_USER_FQDN
:
2165 for (pos
= 1; ; pos
++) {
2166 if (eay_get_x509subjectaltname(&iph1
->cert_p
->cert
, &altname
, &type
, pos
, &len
) != 0) {
2167 plog(LLV_ERROR
, LOCATION
, NULL
,
2168 "failed to get subjectAltName\n");
2169 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2172 /* it's the end condition of the loop. */
2174 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2177 if (check_typeofcertname(idtype
, type
) != 0) {
2178 /* wrong general type - skip this one */
2179 racoon_free(altname
);
2184 if (idlen
!= strlen(altname
)) {
2185 /* wrong length - skip this one */
2186 racoon_free(altname
);
2190 error
= memcmp(id
, altname
, idlen
);
2191 racoon_free(altname
);
2193 plog(LLV_ERROR
, LOCATION
, NULL
, "ID mismatched.\n");
2194 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2200 plog(LLV_ERROR
, LOCATION
, NULL
,
2201 "Impropper ID type passed: %s.\n",
2202 s_ipsecdoi_ident(idtype
));
2203 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2208 #else /* __APPLE__ */
2211 * compare certificate name and ID value.
2214 oakley_check_certid(iph1
)
2215 struct ph1handle
*iph1
;
2217 struct ipsecdoi_id_b
*id_b
;
2218 vchar_t
*name
= NULL
;
2219 char *altname
= NULL
;
2223 if (iph1
->id_p
== NULL
|| iph1
->cert_p
== NULL
) {
2224 plog(LLV_ERROR
, LOCATION
, NULL
, "no ID nor CERT found.\n");
2225 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2228 id_b
= (struct ipsecdoi_id_b
*)iph1
->id_p
->v
;
2229 idlen
= iph1
->id_p
->l
- sizeof(*id_b
);
2231 switch (id_b
->type
) {
2232 case IPSECDOI_ID_DER_ASN1_DN
:
2233 name
= eay_get_x509asn1subjectname(&iph1
->cert_p
->cert
);
2235 plog(LLV_ERROR
, LOCATION
, NULL
,
2236 "failed to get subjectName\n");
2237 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2239 if (idlen
!= name
->l
) {
2240 plog(LLV_ERROR
, LOCATION
, NULL
,
2241 "Invalid ID length in phase 1.\n");
2243 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2245 error
= memcmp(id_b
+ 1, name
->v
, idlen
);
2248 plog(LLV_ERROR
, LOCATION
, NULL
,
2249 "ID mismatched with ASN1 SubjectName.\n");
2250 plogdump(LLV_DEBUG
, id_b
+ 1, idlen
);
2251 plogdump(LLV_DEBUG
, name
->v
, idlen
);
2252 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2255 case IPSECDOI_ID_IPV4_ADDR
:
2256 case IPSECDOI_ID_IPV6_ADDR
:
2259 * converting to binary from string because openssl return
2260 * a string even if object is a binary.
2261 * XXX fix it ! access by ASN.1 directly without.
2263 struct addrinfo hints
, *res
;
2267 for (pos
= 1; ; pos
++) {
2268 if (eay_get_x509subjectaltname(&iph1
->cert_p
->cert
,
2269 &altname
, &type
, pos
) !=0) {
2270 plog(LLV_ERROR
, LOCATION
, NULL
,
2271 "failed to get subjectAltName\n");
2272 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2275 /* it's the end condition of the loop. */
2277 plog(LLV_ERROR
, LOCATION
, NULL
,
2278 "no proper subjectAltName.\n");
2279 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2282 if (check_typeofcertname(id_b
->type
, type
) == 0)
2286 racoon_free(altname
);
2289 memset(&hints
, 0, sizeof(hints
));
2290 hints
.ai_family
= PF_UNSPEC
;
2291 hints
.ai_socktype
= SOCK_RAW
;
2292 hints
.ai_flags
= AI_NUMERICHOST
;
2293 error
= getaddrinfo(altname
, NULL
, &hints
, &res
);
2295 plog(LLV_ERROR
, LOCATION
, NULL
,
2296 "no proper subjectAltName.\n");
2297 racoon_free(altname
);
2298 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2300 switch (res
->ai_family
) {
2302 a
= (caddr_t
)&((struct sockaddr_in
*)res
->ai_addr
)->sin_addr
.s_addr
;
2306 a
= (caddr_t
)&((struct sockaddr_in6
*)res
->ai_addr
)->sin6_addr
.s6_addr
;
2310 plog(LLV_ERROR
, LOCATION
, NULL
,
2311 "family not supported: %d.\n", res
->ai_family
);
2312 racoon_free(altname
);
2314 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2316 error
= memcmp(id_b
+ 1, a
, idlen
);
2320 plog(LLV_ERROR
, LOCATION
, NULL
,
2321 "ID mismatched with subjectAltName.\n");
2322 plogdump(LLV_DEBUG
, id_b
+ 1, idlen
);
2323 plogdump(LLV_DEBUG
, a
, idlen
);
2324 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2328 case IPSECDOI_ID_FQDN
:
2329 case IPSECDOI_ID_USER_FQDN
:
2333 for (pos
= 1; ; pos
++) {
2334 if (eay_get_x509subjectaltname(&iph1
->cert_p
->cert
,
2335 &altname
, &type
, pos
) != 0){
2336 plog(LLV_ERROR
, LOCATION
, NULL
,
2337 "failed to get subjectAltName\n");
2338 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2341 /* it's the end condition of the loop. */
2343 plog(LLV_ERROR
, LOCATION
, NULL
,
2344 "no proper subjectAltName.\n");
2345 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2348 if (check_typeofcertname(id_b
->type
, type
) == 0)
2352 racoon_free(altname
);
2355 if (idlen
!= strlen(altname
)) {
2356 plog(LLV_ERROR
, LOCATION
, NULL
,
2357 "Invalid ID length in phase 1.\n");
2358 racoon_free(altname
);
2359 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2361 if (check_typeofcertname(id_b
->type
, type
) != 0) {
2362 plog(LLV_ERROR
, LOCATION
, NULL
,
2363 "ID type mismatched. ID: %s CERT: %s.\n",
2364 s_ipsecdoi_ident(id_b
->type
),
2365 s_ipsecdoi_ident(type
));
2366 racoon_free(altname
);
2367 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2369 error
= memcmp(id_b
+ 1, altname
, idlen
);
2371 plog(LLV_ERROR
, LOCATION
, NULL
, "ID mismatched.\n");
2372 plogdump(LLV_DEBUG
, id_b
+ 1, idlen
);
2373 plogdump(LLV_DEBUG
, altname
, idlen
);
2374 racoon_free(altname
);
2375 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2377 racoon_free(altname
);
2381 plog(LLV_ERROR
, LOCATION
, NULL
,
2382 "Impropper ID type passed: %s.\n",
2383 s_ipsecdoi_ident(id_b
->type
));
2384 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2389 #endif /* __APPLE__ */
2392 check_typeofcertname(doi
, genid
)
2396 case IPSECDOI_ID_IPV4_ADDR
:
2397 case IPSECDOI_ID_IPV4_ADDR_SUBNET
:
2398 case IPSECDOI_ID_IPV6_ADDR
:
2399 case IPSECDOI_ID_IPV6_ADDR_SUBNET
:
2400 case IPSECDOI_ID_IPV4_ADDR_RANGE
:
2401 case IPSECDOI_ID_IPV6_ADDR_RANGE
:
2402 if (genid
!= GENT_IPADD
)
2405 case IPSECDOI_ID_FQDN
:
2406 if (genid
!= GENT_DNS
)
2409 case IPSECDOI_ID_USER_FQDN
:
2410 if (genid
!= GENT_EMAIL
)
2413 case IPSECDOI_ID_DER_ASN1_DN
: /* should not be passed to this function*/
2414 case IPSECDOI_ID_DER_ASN1_GN
:
2415 case IPSECDOI_ID_KEY_ID
:
2423 * save certificate including certificate type.
2426 oakley_savecert(iph1
, gen
)
2427 struct ph1handle
*iph1
;
2428 struct isakmp_gen
*gen
;
2432 STACK_OF(X509
) *certs
=NULL
;
2435 type
= *(u_int8_t
*)(gen
+ 1) & 0xff;
2438 case ISAKMP_CERT_DNS
:
2439 plog(LLV_WARNING
, LOCATION
, NULL
,
2440 "CERT payload is unnecessary in DNSSEC. "
2441 "ignore this CERT payload.\n");
2443 case ISAKMP_CERT_PKCS7
:
2444 case ISAKMP_CERT_PGP
:
2445 case ISAKMP_CERT_X509SIGN
:
2446 case ISAKMP_CERT_KERBEROS
:
2447 case ISAKMP_CERT_SPKI
:
2450 case ISAKMP_CERT_CRL
:
2453 case ISAKMP_CERT_X509KE
:
2454 case ISAKMP_CERT_X509ATTR
:
2455 case ISAKMP_CERT_ARL
:
2456 plog(LLV_ERROR
, LOCATION
, NULL
,
2457 "No supported such CERT type %d\n", type
);
2460 plog(LLV_ERROR
, LOCATION
, NULL
,
2461 "Invalid CERT type %d\n", type
);
2465 /* XXX choice the 1th cert, ignore after the cert. */
2466 /* XXX should be processed. */
2468 plog(LLV_WARNING
, LOCATION
, NULL
,
2469 "ignore 2nd CERT payload.\n");
2473 if (type
== ISAKMP_CERT_PKCS7
) {
2477 /* Skip the header */
2478 bp
= (u_char
*)(gen
+ 1);
2479 /* And the first byte is the certificate type,
2480 * we know that already
2483 p7
= d2i_PKCS7(NULL
, (void *)&bp
,
2484 ntohs(gen
->len
) - sizeof(*gen
) - 1);
2487 plog(LLV_ERROR
, LOCATION
, NULL
,
2488 "Failed to parse PKCS#7 CERT.\n");
2492 /* Copied this from the openssl pkcs7 application;
2493 * there"s little by way of documentation for any of
2494 * it. I can only presume it"s correct.
2497 i
= OBJ_obj2nid(p7
->type
);
2499 case NID_pkcs7_signed
:
2500 certs
=p7
->d
.sign
->cert
;
2502 case NID_pkcs7_signedAndEnveloped
:
2503 certs
=p7
->d
.signed_and_enveloped
->cert
;
2510 plog(LLV_ERROR
, LOCATION
, NULL
,
2511 "CERT PKCS#7 bundle contains no certs.\n");
2516 for (i
= 0; i
< sk_X509_num(certs
); i
++) {
2519 X509
*cert
= sk_X509_value(certs
,i
);
2521 plog(LLV_DEBUG
, LOCATION
, NULL
,
2522 "Trying PKCS#7 cert %d.\n", i
);
2524 /* We'll just try each cert in turn */
2525 *c
= save_certx509(cert
);
2528 plog(LLV_ERROR
, LOCATION
, NULL
,
2529 "Failed to get CERT buffer.\n");
2533 /* Ignore cert if it doesn't match identity
2534 * XXX If verify cert is disabled, we still just take
2535 * the first certificate....
2537 if(iph1
->rmconf
->verify_cert
&&
2538 oakley_check_certid(iph1
, CERT_CHECKID_FROM_PEER
)) {
2539 plog(LLV_DEBUG
, LOCATION
, NULL
,
2540 "Discarding CERT: does not match ID.\n");
2541 oakley_delcert((*c
));
2547 char *p
= eay_get_x509text(&(*c
)->cert
);
2548 plog(LLV_DEBUG
, LOCATION
, NULL
, "CERT saved:\n");
2549 plogdump(LLV_DEBUG
, (*c
)->cert
.v
, (*c
)->cert
.l
);
2550 plog(LLV_DEBUG
, LOCATION
, NULL
, "%s",
2559 *c
= save_certbuf(gen
);
2561 plog(LLV_ERROR
, LOCATION
, NULL
,
2562 "Failed to get CERT buffer.\n");
2566 switch ((*c
)->type
) {
2567 case ISAKMP_CERT_DNS
:
2568 plog(LLV_WARNING
, LOCATION
, NULL
,
2569 "CERT payload is unnecessary in DNSSEC. "
2572 case ISAKMP_CERT_PGP
:
2573 case ISAKMP_CERT_X509SIGN
:
2574 case ISAKMP_CERT_KERBEROS
:
2575 case ISAKMP_CERT_SPKI
:
2576 /* Ignore cert if it doesn't match identity
2577 * XXX If verify cert is disabled, we still just take
2578 * the first certificate....
2580 if(iph1
->rmconf
->verify_cert
&&
2581 oakley_check_certid(iph1
, CERT_CHECKID_FROM_PEER
)){
2582 plog(LLV_DEBUG
, LOCATION
, NULL
,
2583 "Discarding CERT: does not match ID.\n");
2584 oakley_delcert((*c
));
2590 char *p
= eay_get_x509text(&(*c
)->cert
);
2591 plog(LLV_DEBUG
, LOCATION
, NULL
, "CERT saved:\n");
2592 plogdump(LLV_DEBUG
, (*c
)->cert
.v
, (*c
)->cert
.l
);
2593 plog(LLV_DEBUG
, LOCATION
, NULL
, "%s", p
? p
: "\n");
2597 case ISAKMP_CERT_CRL
:
2598 plog(LLV_DEBUG
, LOCATION
, NULL
, "CRL saved:\n");
2599 plogdump(LLV_DEBUG
, (*c
)->cert
.v
, (*c
)->cert
.l
);
2601 case ISAKMP_CERT_X509KE
:
2602 case ISAKMP_CERT_X509ATTR
:
2603 case ISAKMP_CERT_ARL
:
2606 oakley_delcert((*c
));
2616 * save certificate including certificate type.
2619 oakley_savecr(iph1
, gen
)
2620 struct ph1handle
*iph1
;
2621 struct isakmp_gen
*gen
;
2626 type
= *(u_int8_t
*)(gen
+ 1) & 0xff;
2629 case ISAKMP_CERT_DNS
:
2630 plog(LLV_WARNING
, LOCATION
, NULL
,
2631 "CERT payload is unnecessary in DNSSEC\n");
2633 case ISAKMP_CERT_PKCS7
:
2634 case ISAKMP_CERT_PGP
:
2635 case ISAKMP_CERT_X509SIGN
:
2636 case ISAKMP_CERT_KERBEROS
:
2637 case ISAKMP_CERT_SPKI
:
2640 case ISAKMP_CERT_X509KE
:
2641 case ISAKMP_CERT_X509ATTR
:
2642 case ISAKMP_CERT_ARL
:
2643 plog(LLV_ERROR
, LOCATION
, NULL
,
2644 "No supported such CR type %d\n", type
);
2646 case ISAKMP_CERT_CRL
:
2648 plog(LLV_ERROR
, LOCATION
, NULL
,
2649 "Invalid CR type %d\n", type
);
2653 *c
= save_certbuf(gen
);
2655 plog(LLV_ERROR
, LOCATION
, NULL
,
2656 "Failed to get CR buffer.\n");
2660 plog(LLV_DEBUG
, LOCATION
, NULL
, "CR saved:\n");
2661 plogdump(LLV_DEBUG
, (*c
)->cert
.v
, (*c
)->cert
.l
);
2668 struct isakmp_gen
*gen
;
2672 if(ntohs(gen
->len
) <= sizeof(*gen
)){
2673 plog(LLV_ERROR
, LOCATION
, NULL
,
2674 "Len is too small !!.\n");
2678 new = oakley_newcert();
2680 plog(LLV_ERROR
, LOCATION
, NULL
,
2681 "Failed to get CERT buffer.\n");
2685 new->pl
= vmalloc(ntohs(gen
->len
) - sizeof(*gen
));
2686 if (new->pl
== NULL
) {
2687 plog(LLV_ERROR
, LOCATION
, NULL
,
2688 "Failed to copy CERT from packet.\n");
2689 oakley_delcert(new);
2693 memcpy(new->pl
->v
, gen
+ 1, new->pl
->l
);
2694 new->type
= new->pl
->v
[0] & 0xff;
2695 new->cert
.v
= new->pl
->v
+ 1;
2696 new->cert
.l
= new->pl
->l
- 1;
2709 new = oakley_newcert();
2711 plog(LLV_ERROR
, LOCATION
, NULL
,
2712 "Failed to get CERT buffer.\n");
2716 len
= i2d_X509(cert
, NULL
);
2717 new->pl
= vmalloc(len
);
2718 if (new->pl
== NULL
) {
2719 plog(LLV_ERROR
, LOCATION
, NULL
,
2720 "Failed to copy CERT from packet.\n");
2721 oakley_delcert(new);
2725 bp
= (u_char
*) new->pl
->v
;
2726 len
= i2d_X509(cert
, &bp
);
2727 new->type
= ISAKMP_CERT_X509SIGN
;
2728 new->cert
.v
= new->pl
->v
;
2729 new->cert
.l
= new->pl
->l
;
2736 * NOTE: No Certificate Authority field is included to CR payload at the
2737 * moment. Becuase any certificate authority are accepted without any check.
2738 * The section 3.10 in RFC2408 says that this field SHOULD not be included,
2739 * if there is no specific certificate authority requested.
2743 struct ph1handle
*iph1
;
2749 plog(LLV_ERROR
, LOCATION
, NULL
,
2750 "failed to get cr buffer\n");
2753 if(iph1
->rmconf
->certtype
== ISAKMP_CERT_NONE
) {
2754 buf
->v
[0] = iph1
->rmconf
->cacerttype
;
2755 plog(LLV_DEBUG
, LOCATION
, NULL
, "create my CR: NONE, using %s instead\n",
2756 s_isakmp_certtype(iph1
->rmconf
->cacerttype
));
2758 buf
->v
[0] = iph1
->rmconf
->certtype
;
2759 plog(LLV_DEBUG
, LOCATION
, NULL
, "create my CR: %s\n",
2760 s_isakmp_certtype(iph1
->rmconf
->certtype
));
2763 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
2772 oakley_checkcr(iph1
)
2773 struct ph1handle
*iph1
;
2775 if (iph1
->cr_p
== NULL
)
2778 plog(LLV_DEBUG
, LOCATION
, iph1
->remote
,
2779 "peer transmitted CR: %s\n",
2780 s_isakmp_certtype(iph1
->cr_p
->type
));
2782 if (iph1
->cr_p
->type
!= iph1
->rmconf
->certtype
) {
2783 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
2784 "such a cert type isn't supported: %d\n",
2785 (char)iph1
->cr_p
->type
);
2793 * check to need CR payload.
2800 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
2801 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
2802 #ifdef ENABLE_HYBRID
2803 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
2804 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
2805 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
2806 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
2807 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
2808 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
2819 * see seciton 5. Exchanges in RFC 2409
2820 * psk: SKEYID = prf(pre-shared-key, Ni_b | Nr_b)
2821 * sig: SKEYID = prf(Ni_b | Nr_b, g^ir)
2822 * enc: SKEYID = prf(H(Ni_b | Nr_b), CKY-I | CKY-R)
2826 struct ph1handle
*iph1
;
2828 vchar_t
*buf
= NULL
, *bp
;
2834 switch (AUTHMETHOD(iph1
)) {
2835 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
2836 #ifdef ENABLE_HYBRID
2837 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
2838 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
2841 if (iph1
->rmconf
->shared_secret
) {
2843 switch (iph1
->rmconf
->secrettype
) {
2844 case SECRETTYPE_KEY
:
2845 /* in psk file - use KEY from remote configuration to locate it */
2846 iph1
->authstr
= getpsk(iph1
->rmconf
->shared_secret
->v
, iph1
->rmconf
->shared_secret
->l
-1);
2849 case SECRETTYPE_KEYCHAIN
:
2850 /* in the system keychain */
2851 iph1
->authstr
= getpskfromkeychain(iph1
->rmconf
->shared_secret
->v
, iph1
->etype
, iph1
->rmconf
->secrettype
, NULL
);
2853 case SECRETTYPE_KEYCHAIN_BY_ID
:
2854 /* in the system keychain - use peer id */
2855 iph1
->authstr
= getpskfromkeychain(iph1
->rmconf
->shared_secret
->v
, iph1
->etype
, iph1
->rmconf
->secrettype
, iph1
->id_p
);
2857 #endif HAVE_KEYCHAIN
2858 case SECRETTYPE_USE
:
2859 /* in the remote configuration */
2861 iph1
->authstr
= vdup(iph1
->rmconf
->shared_secret
);
2867 if (iph1
->etype
!= ISAKMP_ETYPE_IDENT
) {
2868 iph1
->authstr
= getpskbyname(iph1
->id_p
);
2869 if (iph1
->authstr
== NULL
) {
2870 if (iph1
->rmconf
->verify_identifier
) {
2871 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
2872 "couldn't find the pskey.\n");
2875 plog(LLV_NOTIFY
, LOCATION
, iph1
->remote
,
2876 "couldn't find the proper pskey, "
2877 "try to get one by the peer's address.\n");
2880 if (iph1
->authstr
== NULL
) {
2882 * If the exchange type is the main mode or if it's
2883 * failed to get the psk by ID, racoon try to get
2884 * the psk by remote IP address.
2885 * It may be nonsense.
2887 iph1
->authstr
= getpskbyaddr(iph1
->remote
);
2888 if (iph1
->authstr
== NULL
) {
2889 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
2890 "couldn't find the pskey for %s.\n",
2891 saddrwop2str(iph1
->remote
));
2895 plog(LLV_DEBUG
, LOCATION
, NULL
, "the psk found.\n");
2896 /* should be secret PSK */
2897 plog(LLV_DEBUG2
, LOCATION
, NULL
, "psk: ");
2898 plogdump(LLV_DEBUG2
, iph1
->authstr
->v
, iph1
->authstr
->l
);
2900 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
2903 plog(LLV_ERROR
, LOCATION
, NULL
,
2904 "failed to get skeyid buffer\n");
2909 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce
: iph1
->nonce_p
);
2910 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce 1: ");
2911 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
2912 memcpy(p
, bp
->v
, bp
->l
);
2915 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce_p
: iph1
->nonce
);
2916 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce 2: ");
2917 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
2918 memcpy(p
, bp
->v
, bp
->l
);
2921 iph1
->skeyid
= oakley_prf(iph1
->authstr
, buf
, iph1
);
2922 if (iph1
->skeyid
== NULL
)
2926 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
2927 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
2928 #ifdef ENABLE_HYBRID
2929 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
2930 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
2931 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
2932 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
2933 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
2934 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
2935 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
2936 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
2939 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
2941 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
2944 plog(LLV_ERROR
, LOCATION
, NULL
,
2945 "failed to get nonce buffer\n");
2950 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce
: iph1
->nonce_p
);
2951 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce1: ");
2952 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
2953 memcpy(p
, bp
->v
, bp
->l
);
2956 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce_p
: iph1
->nonce
);
2957 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce2: ");
2958 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
2959 memcpy(p
, bp
->v
, bp
->l
);
2962 iph1
->skeyid
= oakley_prf(buf
, iph1
->dhgxy
, iph1
);
2963 if (iph1
->skeyid
== NULL
)
2966 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
2967 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
2968 #ifdef ENABLE_HYBRID
2969 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
2970 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
2971 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
2972 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
2974 plog(LLV_WARNING
, LOCATION
, NULL
,
2975 "not supported authentication method %s\n",
2976 s_oakley_attr_method(iph1
->approval
->authmethod
));
2979 plog(LLV_ERROR
, LOCATION
, NULL
,
2980 "invalid authentication method %d\n",
2981 iph1
->approval
->authmethod
);
2985 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID computed:\n");
2986 plogdump(LLV_DEBUG
, iph1
->skeyid
->v
, iph1
->skeyid
->l
);
2997 * compute SKEYID_[dae]
2998 * see seciton 5. Exchanges in RFC 2409
2999 * SKEYID_d = prf(SKEYID, g^ir | CKY-I | CKY-R | 0)
3000 * SKEYID_a = prf(SKEYID, SKEYID_d | g^ir | CKY-I | CKY-R | 1)
3001 * SKEYID_e = prf(SKEYID, SKEYID_a | g^ir | CKY-I | CKY-R | 2)
3004 oakley_skeyid_dae(iph1
)
3005 struct ph1handle
*iph1
;
3007 vchar_t
*buf
= NULL
;
3012 if (iph1
->skeyid
== NULL
) {
3013 plog(LLV_ERROR
, LOCATION
, NULL
, "no SKEYID found.\n");
3018 /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
3019 len
= iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
3022 plog(LLV_ERROR
, LOCATION
, NULL
,
3023 "failed to get skeyid buffer\n");
3028 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
3029 p
+= iph1
->dhgxy
->l
;
3030 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
3031 p
+= sizeof(cookie_t
);
3032 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
3033 p
+= sizeof(cookie_t
);
3035 iph1
->skeyid_d
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
3036 if (iph1
->skeyid_d
== NULL
)
3042 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID_d computed:\n");
3043 plogdump(LLV_DEBUG
, iph1
->skeyid_d
->v
, iph1
->skeyid_d
->l
);
3046 /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
3047 len
= iph1
->skeyid_d
->l
+ iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
3050 plog(LLV_ERROR
, LOCATION
, NULL
,
3051 "failed to get skeyid buffer\n");
3055 memcpy(p
, iph1
->skeyid_d
->v
, iph1
->skeyid_d
->l
);
3056 p
+= iph1
->skeyid_d
->l
;
3057 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
3058 p
+= iph1
->dhgxy
->l
;
3059 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
3060 p
+= sizeof(cookie_t
);
3061 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
3062 p
+= sizeof(cookie_t
);
3064 iph1
->skeyid_a
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
3065 if (iph1
->skeyid_a
== NULL
)
3071 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID_a computed:\n");
3072 plogdump(LLV_DEBUG
, iph1
->skeyid_a
->v
, iph1
->skeyid_a
->l
);
3075 /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
3076 len
= iph1
->skeyid_a
->l
+ iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
3079 plog(LLV_ERROR
, LOCATION
, NULL
,
3080 "failed to get skeyid buffer\n");
3084 memcpy(p
, iph1
->skeyid_a
->v
, iph1
->skeyid_a
->l
);
3085 p
+= iph1
->skeyid_a
->l
;
3086 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
3087 p
+= iph1
->dhgxy
->l
;
3088 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
3089 p
+= sizeof(cookie_t
);
3090 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
3091 p
+= sizeof(cookie_t
);
3093 iph1
->skeyid_e
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
3094 if (iph1
->skeyid_e
== NULL
)
3100 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID_e computed:\n");
3101 plogdump(LLV_DEBUG
, iph1
->skeyid_e
->v
, iph1
->skeyid_e
->l
);
3112 * compute final encryption key.
3116 oakley_compute_enckey(iph1
)
3117 struct ph1handle
*iph1
;
3119 u_int keylen
, prflen
;
3123 keylen
= alg_oakley_encdef_keylen(iph1
->approval
->enctype
,
3124 iph1
->approval
->encklen
);
3126 plog(LLV_ERROR
, LOCATION
, NULL
,
3127 "invalid encryption algoritym %d, "
3128 "or invalid key length %d.\n",
3129 iph1
->approval
->enctype
,
3130 iph1
->approval
->encklen
);
3133 iph1
->key
= vmalloc(keylen
>> 3);
3134 if (iph1
->key
== NULL
) {
3135 plog(LLV_ERROR
, LOCATION
, NULL
,
3136 "failed to get key buffer\n");
3140 /* set prf length */
3141 prflen
= alg_oakley_hashdef_hashlen(iph1
->approval
->hashtype
);
3143 plog(LLV_ERROR
, LOCATION
, NULL
,
3144 "invalid hash type %d.\n", iph1
->approval
->hashtype
);
3148 /* see isakmp-oakley-08 5.3. */
3149 if (iph1
->key
->l
<= iph1
->skeyid_e
->l
) {
3151 * if length(Ka) <= length(SKEYID_e)
3152 * Ka = first length(K) bit of SKEYID_e
3154 memcpy(iph1
->key
->v
, iph1
->skeyid_e
->v
, iph1
->key
->l
);
3156 vchar_t
*buf
= NULL
, *res
= NULL
;
3165 * K1 = prf(SKEYID_e, 0)
3166 * K2 = prf(SKEYID_e, K1)
3167 * K3 = prf(SKEYID_e, K2)
3169 plog(LLV_DEBUG
, LOCATION
, NULL
,
3170 "len(SKEYID_e) < len(Ka) (%zu < %zu), "
3171 "generating long key (Ka = K1 | K2 | ...)\n",
3172 iph1
->skeyid_e
->l
, iph1
->key
->l
);
3174 if ((buf
= vmalloc(prflen
>> 3)) == 0) {
3175 plog(LLV_ERROR
, LOCATION
, NULL
,
3176 "failed to get key buffer\n");
3179 p
= (u_char
*)iph1
->key
->v
;
3180 ep
= p
+ iph1
->key
->l
;
3184 if (p
== (u_char
*)iph1
->key
->v
) {
3185 /* just for computing K1 */
3189 res
= oakley_prf(iph1
->skeyid_e
, buf
, iph1
);
3194 plog(LLV_DEBUG
, LOCATION
, NULL
,
3195 "compute intermediate encryption key K%d\n",
3197 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3198 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
3200 cplen
= (res
->l
< ep
- p
) ? res
->l
: ep
- p
;
3201 memcpy(p
, res
->v
, cplen
);
3204 buf
->l
= prflen
>> 3; /* to cancel K1 speciality */
3205 if (res
->l
!= buf
->l
) {
3206 plog(LLV_ERROR
, LOCATION
, NULL
,
3207 "internal error: res->l=%zu buf->l=%zu\n",
3213 memcpy(buf
->v
, res
->v
, res
->l
);
3222 * don't check any weak key or not.
3223 * draft-ietf-ipsec-ike-01.txt Appendix B.
3224 * draft-ietf-ipsec-ciph-aes-cbc-00.txt Section 2.3.
3228 if (iph1
->approval
->enctype
> ARRAYLEN(oakley_encdef
)
3229 || oakley_encdef
[iph1
->approval
->enctype
].weakkey
== NULL
) {
3230 plog(LLV_ERROR
, LOCATION
, NULL
,
3231 "encryption algoritym %d isn't supported.\n",
3232 iph1
->approval
->enctype
);
3235 if ((oakley_encdef
[iph1
->approval
->enctype
].weakkey
)(iph1
->key
)) {
3236 plog(LLV_ERROR
, LOCATION
, NULL
,
3237 "weakkey was generated.\n");
3242 plog(LLV_DEBUG
, LOCATION
, NULL
, "final encryption key computed:\n");
3243 plogdump(LLV_DEBUG
, iph1
->key
->v
, iph1
->key
->l
);
3251 /* allocated new buffer for CERT */
3257 new = racoon_calloc(1, sizeof(*new));
3259 plog(LLV_ERROR
, LOCATION
, NULL
,
3260 "failed to get cert's buffer\n");
3269 /* delete buffer for CERT */
3271 oakley_delcert(cert
)
3282 * compute IV and set to ph1handle
3283 * IV = hash(g^xi | g^xr)
3284 * see 4.1 Phase 1 state in draft-ietf-ipsec-ike.
3288 struct ph1handle
*iph1
;
3290 struct isakmp_ivm
*newivm
= NULL
;
3291 vchar_t
*buf
= NULL
, *bp
;
3296 len
= iph1
->dhpub
->l
+ iph1
->dhpub_p
->l
;
3299 plog(LLV_ERROR
, LOCATION
, NULL
,
3300 "failed to get iv buffer\n");
3306 bp
= (iph1
->side
== INITIATOR
? iph1
->dhpub
: iph1
->dhpub_p
);
3307 memcpy(p
, bp
->v
, bp
->l
);
3310 bp
= (iph1
->side
== INITIATOR
? iph1
->dhpub_p
: iph1
->dhpub
);
3311 memcpy(p
, bp
->v
, bp
->l
);
3315 newivm
= racoon_calloc(1, sizeof(struct isakmp_ivm
));
3316 if (newivm
== NULL
) {
3317 plog(LLV_ERROR
, LOCATION
, NULL
,
3318 "failed to get iv buffer\n");
3324 newivm
->iv
= oakley_hash(buf
, iph1
);
3325 if (newivm
->iv
== NULL
) {
3327 oakley_delivm(newivm
);
3331 /* adjust length of iv */
3332 newivm
->iv
->l
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3333 if (newivm
->iv
->l
== -1) {
3334 plog(LLV_ERROR
, LOCATION
, NULL
,
3335 "invalid encryption algoriym %d.\n",
3336 iph1
->approval
->enctype
);
3338 oakley_delivm(newivm
);
3342 /* create buffer to save iv */
3343 if ((newivm
->ive
= vdup(newivm
->iv
)) == NULL
) {
3344 plog(LLV_ERROR
, LOCATION
, NULL
,
3345 "vdup (%s)\n", strerror(errno
));
3347 oakley_delivm(newivm
);
3353 plog(LLV_DEBUG
, LOCATION
, NULL
, "IV computed:\n");
3354 plogdump(LLV_DEBUG
, newivm
->iv
->v
, newivm
->iv
->l
);
3356 if (iph1
->ivm
!= NULL
)
3357 oakley_delivm(iph1
->ivm
);
3365 * compute IV for the payload after phase 1.
3366 * It's not limited for phase 2.
3367 * if pahse 1 was encrypted.
3368 * IV = hash(last CBC block of Phase 1 | M-ID)
3369 * if phase 1 was not encrypted.
3370 * IV = hash(phase 1 IV | M-ID)
3371 * see 4.2 Phase 2 state in draft-ietf-ipsec-ike.
3374 oakley_newiv2(iph1
, msgid
)
3375 struct ph1handle
*iph1
;
3378 struct isakmp_ivm
*newivm
= NULL
;
3379 vchar_t
*buf
= NULL
;
3385 len
= iph1
->ivm
->iv
->l
+ sizeof(msgid_t
);
3388 plog(LLV_ERROR
, LOCATION
, NULL
,
3389 "failed to get iv buffer\n");
3395 memcpy(p
, iph1
->ivm
->iv
->v
, iph1
->ivm
->iv
->l
);
3396 p
+= iph1
->ivm
->iv
->l
;
3398 memcpy(p
, &msgid
, sizeof(msgid
));
3400 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute IV for phase2\n");
3401 plog(LLV_DEBUG
, LOCATION
, NULL
, "phase1 last IV:\n");
3402 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3405 newivm
= racoon_calloc(1, sizeof(struct isakmp_ivm
));
3406 if (newivm
== NULL
) {
3407 plog(LLV_ERROR
, LOCATION
, NULL
,
3408 "failed to get iv buffer\n");
3413 if ((newivm
->iv
= oakley_hash(buf
, iph1
)) == NULL
)
3416 /* adjust length of iv */
3417 newivm
->iv
->l
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3418 if (newivm
->iv
->l
== -1) {
3419 plog(LLV_ERROR
, LOCATION
, NULL
,
3420 "invalid encryption algoriym %d.\n",
3421 iph1
->approval
->enctype
);
3425 /* create buffer to save new iv */
3426 if ((newivm
->ive
= vdup(newivm
->iv
)) == NULL
) {
3427 plog(LLV_ERROR
, LOCATION
, NULL
, "vdup (%s)\n", strerror(errno
));
3433 plog(LLV_DEBUG
, LOCATION
, NULL
, "phase2 IV computed:\n");
3434 plogdump(LLV_DEBUG
, newivm
->iv
->v
, newivm
->iv
->l
);
3437 if (error
&& newivm
!= NULL
){
3438 oakley_delivm(newivm
);
3448 struct isakmp_ivm
*ivm
;
3453 if (ivm
->iv
!= NULL
)
3455 if (ivm
->ive
!= NULL
)
3458 plog(LLV_DEBUG
, LOCATION
, NULL
, "IV freed\n");
3465 * save new iv and old iv.
3468 oakley_do_decrypt(iph1
, msg
, ivdp
, ivep
)
3469 struct ph1handle
*iph1
;
3470 vchar_t
*msg
, *ivdp
, *ivep
;
3472 vchar_t
*buf
= NULL
, *new = NULL
;
3479 plog(LLV_DEBUG
, LOCATION
, NULL
, "begin decryption.\n");
3481 blen
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3483 plog(LLV_ERROR
, LOCATION
, NULL
,
3484 "invalid encryption algoriym %d.\n",
3485 iph1
->approval
->enctype
);
3489 /* save IV for next, but not sync. */
3490 memset(ivep
->v
, 0, ivep
->l
);
3491 memcpy(ivep
->v
, (caddr_t
)&msg
->v
[msg
->l
- blen
], blen
);
3493 plog(LLV_DEBUG
, LOCATION
, NULL
,
3494 "IV was saved for next processing:\n");
3495 plogdump(LLV_DEBUG
, ivep
->v
, ivep
->l
);
3497 pl
= msg
->v
+ sizeof(struct isakmp
);
3499 len
= msg
->l
- sizeof(struct isakmp
);
3504 plog(LLV_ERROR
, LOCATION
, NULL
,
3505 "failed to get buffer to decrypt.\n");
3508 memcpy(buf
->v
, pl
, len
);
3511 new = alg_oakley_encdef_decrypt(iph1
->approval
->enctype
,
3512 buf
, iph1
->key
, ivdp
);
3514 plog(LLV_ERROR
, LOCATION
, NULL
,
3515 "decryption %d failed.\n", iph1
->approval
->enctype
);
3518 plog(LLV_DEBUG
, LOCATION
, NULL
, "with key:\n");
3519 plogdump(LLV_DEBUG
, iph1
->key
->v
, iph1
->key
->l
);
3526 plog(LLV_DEBUG
, LOCATION
, NULL
, "decrypted payload by IV:\n");
3527 plogdump(LLV_DEBUG
, ivdp
->v
, ivdp
->l
);
3529 plog(LLV_DEBUG
, LOCATION
, NULL
,
3530 "decrypted payload, but not trimed.\n");
3531 plogdump(LLV_DEBUG
, new->v
, new->l
);
3533 /* get padding length */
3534 if (lcconf
->pad_excltail
)
3535 padlen
= new->v
[new->l
- 1] + 1;
3537 padlen
= new->v
[new->l
- 1];
3538 plog(LLV_DEBUG
, LOCATION
, NULL
, "padding len=%u\n", padlen
);
3541 if (lcconf
->pad_strict
) {
3542 if (padlen
> new->l
) {
3543 plog(LLV_ERROR
, LOCATION
, NULL
,
3544 "invalid padding len=%u, buflen=%zu.\n",
3546 plogdump(LLV_ERROR
, new->v
, new->l
);
3550 plog(LLV_DEBUG
, LOCATION
, NULL
, "trimmed padding\n");
3552 plog(LLV_DEBUG
, LOCATION
, NULL
, "skip to trim padding.\n");
3555 /* create new buffer */
3556 len
= sizeof(struct isakmp
) + new->l
;
3559 plog(LLV_ERROR
, LOCATION
, NULL
,
3560 "failed to get buffer to decrypt.\n");
3563 memcpy(buf
->v
, msg
->v
, sizeof(struct isakmp
));
3564 memcpy(buf
->v
+ sizeof(struct isakmp
), new->v
, new->l
);
3565 ((struct isakmp
*)buf
->v
)->len
= htonl(buf
->l
);
3567 plog(LLV_DEBUG
, LOCATION
, NULL
, "decrypted.\n");
3568 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3570 #ifdef HAVE_PRINT_ISAKMP_C
3571 isakmp_printpacket(buf
, iph1
->remote
, iph1
->local
, 1);
3577 if (error
&& buf
!= NULL
) {
3591 oakley_do_encrypt(iph1
, msg
, ivep
, ivp
)
3592 struct ph1handle
*iph1
;
3593 vchar_t
*msg
, *ivep
, *ivp
;
3595 vchar_t
*buf
= 0, *new = 0;
3602 plog(LLV_DEBUG
, LOCATION
, NULL
, "begin encryption.\n");
3604 /* set cbc block length */
3605 blen
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3607 plog(LLV_ERROR
, LOCATION
, NULL
,
3608 "invalid encryption algoriym %d.\n",
3609 iph1
->approval
->enctype
);
3613 pl
= msg
->v
+ sizeof(struct isakmp
);
3614 len
= msg
->l
- sizeof(struct isakmp
);
3617 padlen
= oakley_padlen(len
, blen
);
3618 plog(LLV_DEBUG
, LOCATION
, NULL
, "pad length = %u\n", padlen
);
3621 buf
= vmalloc(len
+ padlen
);
3623 plog(LLV_ERROR
, LOCATION
, NULL
,
3624 "failed to get buffer to encrypt.\n");
3629 char *p
= &buf
->v
[len
];
3630 if (lcconf
->pad_random
) {
3631 for (i
= 0; i
< padlen
; i
++)
3632 *p
++ = eay_random() & 0xff;
3635 memcpy(buf
->v
, pl
, len
);
3637 /* make pad into tail */
3638 if (lcconf
->pad_excltail
)
3639 buf
->v
[len
+ padlen
- 1] = padlen
- 1;
3641 buf
->v
[len
+ padlen
- 1] = padlen
;
3643 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3646 new = alg_oakley_encdef_encrypt(iph1
->approval
->enctype
,
3647 buf
, iph1
->key
, ivep
);
3649 plog(LLV_ERROR
, LOCATION
, NULL
,
3650 "encryption %d failed.\n", iph1
->approval
->enctype
);
3653 plog(LLV_DEBUG
, LOCATION
, NULL
, "with key:\n");
3654 plogdump(LLV_DEBUG
, iph1
->key
->v
, iph1
->key
->l
);
3661 plog(LLV_DEBUG
, LOCATION
, NULL
, "encrypted payload by IV:\n");
3662 plogdump(LLV_DEBUG
, ivep
->v
, ivep
->l
);
3664 /* save IV for next */
3665 memset(ivp
->v
, 0, ivp
->l
);
3666 memcpy(ivp
->v
, (caddr_t
)&new->v
[new->l
- blen
], blen
);
3668 plog(LLV_DEBUG
, LOCATION
, NULL
, "save IV for next:\n");
3669 plogdump(LLV_DEBUG
, ivp
->v
, ivp
->l
);
3671 /* create new buffer */
3672 len
= sizeof(struct isakmp
) + new->l
;
3675 plog(LLV_ERROR
, LOCATION
, NULL
,
3676 "failed to get buffer to encrypt.\n");
3679 memcpy(buf
->v
, msg
->v
, sizeof(struct isakmp
));
3680 memcpy(buf
->v
+ sizeof(struct isakmp
), new->v
, new->l
);
3681 ((struct isakmp
*)buf
->v
)->len
= htonl(buf
->l
);
3685 plog(LLV_DEBUG
, LOCATION
, NULL
, "encrypted.\n");
3688 if (error
&& buf
!= NULL
) {
3698 /* culculate padding length */
3700 oakley_padlen(len
, base
)
3705 padlen
= base
- len
% base
;
3707 if (lcconf
->pad_randomlen
)
3708 padlen
+= ((eay_random() % (lcconf
->pad_maxsize
+ 1) + 1) *
3715 /* -----------------------------------------------------------------------------
3716 The base-64 encoding packs three 8-bit bytes into four 7-bit ASCII
3717 characters. If the number of bytes in the original data isn't divisable
3718 by three, "=" characters are used to pad the encoded data. The complete
3719 set of characters used in base-64 are:
3727 ----------------------------------------------------------------------------- */
3728 static const signed char base64_DecodeTable
[128] = {
3729 /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
3730 /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
3731 /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
3732 /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
3733 /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
3734 /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
3735 /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
3736 /* '8' */ 60, 61, -1, -1, -1, 0, -1, -1,
3737 /* '@' */ -1, 0, 1, 2, 3, 4, 5, 6,
3738 /* 'H' */ 7, 8, 9, 10, 11, 12, 13, 14,
3739 /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
3740 /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
3741 /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
3742 /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
3743 /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
3744 /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
3747 static int base64toCFData(vchar_t
*textin
, CFDataRef
*dataRef
)
3755 uint8_t *textcur
= textin
->v
;
3756 int len
= textin
->l
;
3759 tmpbuf
= malloc(len
); // len of result will be less than encoded len
3760 if (tmpbuf
== NULL
) {
3761 yyerror("memory error - could not allocate buffer for certificate reference conversion from base-64.");
3765 for (i
= 0; i
< len
; i
++) {
3769 else if (!isspace(c
))
3771 if (base64_DecodeTable
[c
] < 0)
3775 acc
+= base64_DecodeTable
[c
];
3776 if (0 == (cntr
& 0x3)) {
3777 tmpbuf
[tmpbufpos
++] = (acc
>> 16) & 0xff;
3779 tmpbuf
[tmpbufpos
++] = (acc
>> 8) & 0xff;
3781 tmpbuf
[tmpbufpos
++] = acc
& 0xff;
3784 *dataRef
= CFDataCreate(NULL
, tmpbuf
, tmpbufpos
);