1 /* $Id: oakley.c,v 1.17.2.5 2005/10/04 09:54:27 manubsd Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/socket.h> /* XXX for subjectaltname */
37 #include <netinet/in.h> /* XXX for subjectaltname */
39 #include <openssl/x509.h>
40 #include <openssl/pkcs7.h>
47 #if TIME_WITH_SYS_TIME
48 # include <sys/time.h>
52 # include <sys/time.h>
65 #include "isakmp_var.h"
68 #include "isakmp_xauth.h"
69 #include "isakmp_cfg.h"
74 #include "localconf.h"
75 #include "remoteconf.h"
78 #include "ipsec_doi.h"
79 #include "algorithm.h"
83 #include "crypto_openssl.h"
85 #include "crypto_cssm.h"
94 #include <CoreFoundation/CFData.h>
102 #define OUTBOUND_SA 0
106 #define CERT_CHECKID_FROM_PEER 0
107 #define CERT_CHECKID_FROM_RMCONFIG 1
110 #define INITDHVAL(a, s, d, t) \
113 buf.v = str2val((s), 16, &buf.l); \
114 memset(&a, 0, sizeof(struct dhgroup)); \
116 a.prime = vdup(&buf); \
119 racoon_free(buf.v); \
122 struct dhgroup dh_modp768
;
123 struct dhgroup dh_modp1024
;
124 struct dhgroup dh_modp1536
;
125 struct dhgroup dh_modp2048
;
126 struct dhgroup dh_modp3072
;
127 struct dhgroup dh_modp4096
;
128 struct dhgroup dh_modp6144
;
129 struct dhgroup dh_modp8192
;
132 static int oakley_check_dh_pub
__P((vchar_t
*, vchar_t
**));
133 static int oakley_compute_keymat_x
__P((struct ph2handle
*, int, int));
134 static int get_cert_fromlocal
__P((struct ph1handle
*, int));
135 static int get_plainrsa_fromlocal
__P((struct ph1handle
*, int));
137 static int oakley_check_certid
__P((struct ph1handle
*iph1
, int));
138 static int oakley_check_certid_1
__P((struct ph1handle
*, int, int, void*));
140 static int oakley_check_certid
__P((struct ph1handle
*iph1
));
142 static int check_typeofcertname
__P((int, int));
143 static cert_t
*save_certbuf
__P((struct isakmp_gen
*));
144 static cert_t
*save_certx509
__P((X509
*));
145 static int oakley_padlen
__P((int, int));
148 static int base64toCFData(vchar_t
*, CFDataRef
*);
152 oakley_get_defaultlifetime()
154 return OAKLEY_ATTR_SA_LD_SEC_DEFAULT
;
161 INITDHVAL(dh_modp768
, OAKLEY_PRIME_MODP768
,
162 OAKLEY_ATTR_GRP_DESC_MODP768
, OAKLEY_ATTR_GRP_TYPE_MODP
);
163 INITDHVAL(dh_modp1024
, OAKLEY_PRIME_MODP1024
,
164 OAKLEY_ATTR_GRP_DESC_MODP1024
, OAKLEY_ATTR_GRP_TYPE_MODP
);
165 INITDHVAL(dh_modp1536
, OAKLEY_PRIME_MODP1536
,
166 OAKLEY_ATTR_GRP_DESC_MODP1536
, OAKLEY_ATTR_GRP_TYPE_MODP
);
167 INITDHVAL(dh_modp2048
, OAKLEY_PRIME_MODP2048
,
168 OAKLEY_ATTR_GRP_DESC_MODP2048
, OAKLEY_ATTR_GRP_TYPE_MODP
);
169 INITDHVAL(dh_modp3072
, OAKLEY_PRIME_MODP3072
,
170 OAKLEY_ATTR_GRP_DESC_MODP3072
, OAKLEY_ATTR_GRP_TYPE_MODP
);
171 INITDHVAL(dh_modp4096
, OAKLEY_PRIME_MODP4096
,
172 OAKLEY_ATTR_GRP_DESC_MODP4096
, OAKLEY_ATTR_GRP_TYPE_MODP
);
173 INITDHVAL(dh_modp6144
, OAKLEY_PRIME_MODP6144
,
174 OAKLEY_ATTR_GRP_DESC_MODP6144
, OAKLEY_ATTR_GRP_TYPE_MODP
);
175 INITDHVAL(dh_modp8192
, OAKLEY_PRIME_MODP8192
,
176 OAKLEY_ATTR_GRP_DESC_MODP8192
, OAKLEY_ATTR_GRP_TYPE_MODP
);
182 oakley_dhgrp_free(dhgrp
)
183 struct dhgroup
*dhgrp
;
188 vfree(dhgrp
->curve_a
);
190 vfree(dhgrp
->curve_b
);
198 * The length of the Diffie-Hellman public value MUST be equal to the
199 * length of the prime modulus over which the exponentiation was
200 * performed, prepending zero bits to the value if necessary.
203 oakley_check_dh_pub(prime
, pub0
)
204 vchar_t
*prime
, **pub0
;
207 vchar_t
*pub
= *pub0
;
209 if (prime
->l
== pub
->l
)
212 if (prime
->l
< pub
->l
) {
213 /* what should i do ? */
214 plog(LLV_ERROR
, LOCATION
, NULL
,
215 "invalid public information was generated.\n");
219 /* prime->l > pub->l */
220 tmp
= vmalloc(prime
->l
);
222 plog(LLV_ERROR
, LOCATION
, NULL
,
223 "failed to get DH buffer.\n");
226 memcpy(tmp
->v
+ prime
->l
- pub
->l
, pub
->v
, pub
->l
);
235 * compute sharing secret of DH
236 * IN: *dh, *pub, *priv, *pub_p
240 oakley_dh_compute(dh
, pub
, priv
, pub_p
, gxy
)
241 const struct dhgroup
*dh
;
242 vchar_t
*pub
, *priv
, *pub_p
, **gxy
;
245 struct timeval start
, end
;
247 if ((*gxy
= vmalloc(dh
->prime
->l
)) == NULL
) {
248 plog(LLV_ERROR
, LOCATION
, NULL
,
249 "failed to get DH buffer.\n");
254 gettimeofday(&start
, NULL
);
257 case OAKLEY_ATTR_GRP_TYPE_MODP
:
258 if (eay_dh_compute(dh
->prime
, dh
->gen1
, pub
, priv
, pub_p
, gxy
) < 0) {
259 plog(LLV_ERROR
, LOCATION
, NULL
,
260 "failed to compute dh value.\n");
264 case OAKLEY_ATTR_GRP_TYPE_ECP
:
265 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
266 plog(LLV_ERROR
, LOCATION
, NULL
,
267 "dh type %d isn't supported.\n", dh
->type
);
270 plog(LLV_ERROR
, LOCATION
, NULL
,
271 "invalid dh type %d.\n", dh
->type
);
276 gettimeofday(&end
, NULL
);
277 syslog(LOG_NOTICE
, "%s(%s%d): %8.6f", __func__
,
278 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
279 timedelta(&start
, &end
));
282 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's shared.\n");
283 plogdump(LLV_DEBUG
, (*gxy
)->v
, (*gxy
)->l
);
289 * generate values of DH
294 oakley_dh_generate(dh
, pub
, priv
)
295 const struct dhgroup
*dh
;
296 vchar_t
**pub
, **priv
;
299 struct timeval start
, end
;
300 gettimeofday(&start
, NULL
);
303 case OAKLEY_ATTR_GRP_TYPE_MODP
:
304 if (eay_dh_generate(dh
->prime
, dh
->gen1
, dh
->gen2
, pub
, priv
) < 0) {
305 plog(LLV_ERROR
, LOCATION
, NULL
,
306 "failed to compute dh value.\n");
311 case OAKLEY_ATTR_GRP_TYPE_ECP
:
312 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
313 plog(LLV_ERROR
, LOCATION
, NULL
,
314 "dh type %d isn't supported.\n", dh
->type
);
317 plog(LLV_ERROR
, LOCATION
, NULL
,
318 "invalid dh type %d.\n", dh
->type
);
323 gettimeofday(&end
, NULL
);
324 syslog(LOG_NOTICE
, "%s(%s%d): %8.6f", __func__
,
325 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
326 timedelta(&start
, &end
));
329 if (oakley_check_dh_pub(dh
->prime
, pub
) != 0)
332 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's private.\n");
333 plogdump(LLV_DEBUG
, (*priv
)->v
, (*priv
)->l
);
334 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's public.\n");
335 plogdump(LLV_DEBUG
, (*pub
)->v
, (*pub
)->l
);
341 * copy pre-defined dhgroup values.
344 oakley_setdhgroup(group
, dhgrp
)
346 struct dhgroup
**dhgrp
;
350 *dhgrp
= NULL
; /* just make sure, initialize */
352 g
= alg_oakley_dhdef_group(group
);
354 plog(LLV_ERROR
, LOCATION
, NULL
,
355 "invalid DH parameter grp=%d.\n", group
);
359 if (!g
->type
|| !g
->prime
|| !g
->gen1
) {
361 plog(LLV_ERROR
, LOCATION
, NULL
,
362 "unsupported DH parameters grp=%d.\n", group
);
366 *dhgrp
= racoon_calloc(1, sizeof(struct dhgroup
));
367 if (*dhgrp
== NULL
) {
368 plog(LLV_ERROR
, LOCATION
, NULL
,
369 "failed to get DH buffer.\n");
373 /* set defined dh vlaues */
374 memcpy(*dhgrp
, g
, sizeof(*g
));
375 (*dhgrp
)->prime
= vdup(g
->prime
);
383 * NOTE: we do not support prf with different input/output bitwidth,
384 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example) in
385 * oakley_compute_keymat(). If you add support for such prf function,
386 * modify oakley_compute_keymat() accordingly.
389 oakley_prf(key
, buf
, iph1
)
391 struct ph1handle
*iph1
;
396 if (iph1
->approval
== NULL
) {
398 * it's before negotiating hash algorithm.
399 * We use md5 as default.
401 type
= OAKLEY_ATTR_HASH_ALG_MD5
;
403 type
= iph1
->approval
->hashtype
;
405 res
= alg_oakley_hmacdef_one(type
, key
, buf
);
407 plog(LLV_ERROR
, LOCATION
, NULL
,
408 "invalid hmac algorithm %d.\n", type
);
419 oakley_hash(buf
, iph1
)
421 struct ph1handle
*iph1
;
426 if (iph1
->approval
== NULL
) {
428 * it's before negotiating hash algorithm.
429 * We use md5 as default.
431 type
= OAKLEY_ATTR_HASH_ALG_MD5
;
433 type
= iph1
->approval
->hashtype
;
435 res
= alg_oakley_hashdef_one(type
, buf
);
437 plog(LLV_ERROR
, LOCATION
, NULL
,
438 "invalid hash algorithm %d.\n", type
);
447 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
450 oakley_compute_keymat(iph2
, side
)
451 struct ph2handle
*iph2
;
456 /* compute sharing secret of DH when PFS */
457 if (iph2
->approval
->pfs_group
&& iph2
->dhpub_p
) {
458 if (oakley_dh_compute(iph2
->pfsgrp
, iph2
->dhpub
,
459 iph2
->dhpriv
, iph2
->dhpub_p
, &iph2
->dhgxy
) < 0)
464 if (oakley_compute_keymat_x(iph2
, side
, INBOUND_SA
) < 0
465 || oakley_compute_keymat_x(iph2
, side
, OUTBOUND_SA
) < 0)
468 plog(LLV_DEBUG
, LOCATION
, NULL
, "KEYMAT computed.\n");
478 * KEYMAT = prf(SKEYID_d, protocol | SPI | Ni_b | Nr_b).
479 * If PFS is desired and KE payloads were exchanged,
480 * KEYMAT = prf(SKEYID_d, g(qm)^xy | protocol | SPI | Ni_b | Nr_b)
482 * NOTE: we do not support prf with different input/output bitwidth,
483 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example).
486 oakley_compute_keymat_x(iph2
, side
, sa_dir
)
487 struct ph2handle
*iph2
;
491 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
496 int dupkeymat
; /* generate K[1-dupkeymat] */
499 int encklen
, authklen
, l
;
501 pfs
= ((iph2
->approval
->pfs_group
&& iph2
->dhgxy
) ? 1 : 0);
503 len
= pfs
? iph2
->dhgxy
->l
: 0;
505 + sizeof(u_int32_t
) /* XXX SPI size */
510 plog(LLV_ERROR
, LOCATION
, NULL
,
511 "failed to get keymat buffer.\n");
515 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
520 memcpy(p
, iph2
->dhgxy
->v
, iph2
->dhgxy
->l
);
527 memcpy(p
, (sa_dir
== INBOUND_SA
? &pr
->spi
: &pr
->spi_p
),
529 p
+= sizeof(pr
->spi
);
531 bp
= (side
== INITIATOR
? iph2
->nonce
: iph2
->nonce_p
);
532 memcpy(p
, bp
->v
, bp
->l
);
535 bp
= (side
== INITIATOR
? iph2
->nonce_p
: iph2
->nonce
);
536 memcpy(p
, bp
->v
, bp
->l
);
540 plog(LLV_DEBUG
, LOCATION
, NULL
, "KEYMAT compute with\n");
541 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
544 res
= oakley_prf(iph2
->ph1
->skeyid_d
, buf
, iph2
->ph1
);
548 /* compute key length needed */
549 encklen
= authklen
= 0;
550 switch (pr
->proto_id
) {
551 case IPSECDOI_PROTO_IPSEC_ESP
:
552 for (tr
= pr
->head
; tr
; tr
= tr
->next
) {
553 l
= alg_ipsec_encdef_keylen(tr
->trns_id
,
558 l
= alg_ipsec_hmacdef_hashlen(tr
->authtype
);
563 case IPSECDOI_PROTO_IPSEC_AH
:
564 for (tr
= pr
->head
; tr
; tr
= tr
->next
) {
565 l
= alg_ipsec_hmacdef_hashlen(tr
->trns_id
);
573 plog(LLV_DEBUG
, LOCATION
, NULL
, "encklen=%d authklen=%d\n",
576 dupkeymat
= (encklen
+ authklen
) / 8 / res
->l
;
577 dupkeymat
+= 2; /* safety mergin */
580 plog(LLV_DEBUG
, LOCATION
, NULL
,
581 "generating %zu bits of key (dupkeymat=%d)\n",
582 dupkeymat
* 8 * res
->l
, dupkeymat
);
583 if (0 < --dupkeymat
) {
584 vchar_t
*prev
= res
; /* K(n-1) */
585 vchar_t
*seed
= NULL
; /* seed for Kn */
589 * generating long key (isakmp-oakley-08 5.5)
590 * KEYMAT = K1 | K2 | K3 | ...
592 * src = [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b
593 * K1 = prf(SKEYID_d, src)
594 * K2 = prf(SKEYID_d, K1 | src)
595 * K3 = prf(SKEYID_d, K2 | src)
596 * Kn = prf(SKEYID_d, K(n-1) | src)
598 plog(LLV_DEBUG
, LOCATION
, NULL
,
599 "generating K1...K%d for KEYMAT.\n",
602 seed
= vmalloc(prev
->l
+ buf
->l
);
604 plog(LLV_ERROR
, LOCATION
, NULL
,
605 "failed to get keymat buffer.\n");
606 if (prev
&& prev
!= res
)
611 while (dupkeymat
--) {
612 vchar_t
*this = NULL
; /* Kn */
614 memcpy(seed
->v
, prev
->v
, prev
->l
);
615 memcpy(seed
->v
+ prev
->l
, buf
->v
, buf
->l
);
616 this = oakley_prf(iph2
->ph1
->skeyid_d
, seed
,
619 plog(LLV_ERROR
, LOCATION
, NULL
,
620 "oakley_prf memory overflow\n");
621 if (prev
&& prev
!= res
)
629 res
= vrealloc(res
, l
+ this->l
);
631 plog(LLV_ERROR
, LOCATION
, NULL
,
632 "failed to get keymat buffer.\n");
633 if (prev
&& prev
!= res
)
639 memcpy(res
->v
+ l
, this->v
, this->l
);
641 if (prev
&& prev
!= res
)
647 if (prev
&& prev
!= res
)
652 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
654 if (sa_dir
== INBOUND_SA
)
665 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
687 * NOTE: Must terminate by NULL.
690 oakley_compute_hashx(struct ph1handle
*iph1
, ...)
699 /* get buffer length */
702 while ((s
= va_arg(ap
, vchar_t
*)) != NULL
) {
709 plog(LLV_ERROR
, LOCATION
, NULL
,
710 "failed to get hash buffer\n");
717 while ((s
= va_arg(ap
, char *)) != NULL
) {
718 memcpy(p
, s
->v
, s
->l
);
723 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with: \n");
724 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
727 res
= oakley_prf(iph1
->skeyid_a
, buf
, iph1
);
732 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH computed:\n");
733 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
740 * compute HASH(3) prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
741 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
744 oakley_compute_hash3(iph1
, msgid
, body
)
745 struct ph1handle
*iph1
;
749 vchar_t
*buf
= 0, *res
= 0;
754 len
= 1 + sizeof(u_int32_t
) + body
->l
;
757 plog(LLV_DEBUG
, LOCATION
, NULL
,
758 "failed to get hash buffer\n");
764 memcpy(buf
->v
+ 1, (char *)&msgid
, sizeof(msgid
));
766 memcpy(buf
->v
+ 1 + sizeof(u_int32_t
), body
->v
, body
->l
);
768 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with: \n");
769 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
772 res
= oakley_prf(iph1
->skeyid_a
, buf
, iph1
);
778 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH computed:\n");
779 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
788 * compute HASH type of prf(SKEYID_a, M-ID | buffer)
790 * for quick mode HASH(1):
791 * prf(SKEYID_a, M-ID | SA | Ni [ | KE ] [ | IDci | IDcr ])
792 * for quick mode HASH(2):
793 * prf(SKEYID_a, M-ID | Ni_b | SA | Nr [ | KE ] [ | IDci | IDcr ])
794 * for Informational exchange:
795 * prf(SKEYID_a, M-ID | N/D)
798 oakley_compute_hash1(iph1
, msgid
, body
)
799 struct ph1handle
*iph1
;
803 vchar_t
*buf
= NULL
, *res
= NULL
;
809 len
= sizeof(u_int32_t
) + body
->l
;
812 plog(LLV_DEBUG
, LOCATION
, NULL
,
813 "failed to get hash buffer\n");
819 memcpy(buf
->v
, (char *)&msgid
, sizeof(msgid
));
820 p
+= sizeof(u_int32_t
);
822 memcpy(p
, body
->v
, body
->l
);
824 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with:\n");
825 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
828 res
= oakley_prf(iph1
->skeyid_a
, buf
, iph1
);
834 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH computed:\n");
835 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
844 * compute phase1 HASH
846 * I-digest = prf(SKEYID, g^i | g^r | CKY-I | CKY-R | SAi_b | ID_i1_b)
847 * R-digest = prf(SKEYID, g^r | g^i | CKY-R | CKY-I | SAi_b | ID_r1_b)
848 * for gssapi, also include all GSS tokens, and call gss_wrap on the result
851 oakley_ph1hash_common(iph1
, sw
)
852 struct ph1handle
*iph1
;
855 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
860 vchar_t
*gsstokens
= NULL
;
866 + sizeof(cookie_t
) * 2
868 + (sw
== GENERATE
? iph1
->id
->l
: iph1
->id_p
->l
);
871 if (iph1
->approval
->authmethod
== OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
) {
872 if (iph1
->gi_i
!= NULL
&& iph1
->gi_r
!= NULL
) {
873 bp
= (sw
== GENERATE
? iph1
->gi_i
: iph1
->gi_r
);
877 gssapi_get_itokens(iph1
, &gsstokens
);
879 gssapi_get_rtokens(iph1
, &gsstokens
);
880 if (gsstokens
== NULL
)
888 plog(LLV_ERROR
, LOCATION
, NULL
,
889 "failed to get hash buffer\n");
895 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
896 memcpy(p
, bp
->v
, bp
->l
);
899 bp
= (sw
== GENERATE
? iph1
->dhpub_p
: iph1
->dhpub
);
900 memcpy(p
, bp
->v
, bp
->l
);
903 if (iph1
->side
== INITIATOR
)
904 bp2
= (sw
== GENERATE
?
905 (char *)&iph1
->index
.i_ck
: (char *)&iph1
->index
.r_ck
);
907 bp2
= (sw
== GENERATE
?
908 (char *)&iph1
->index
.r_ck
: (char *)&iph1
->index
.i_ck
);
909 bl
= sizeof(cookie_t
);
913 if (iph1
->side
== INITIATOR
)
914 bp2
= (sw
== GENERATE
?
915 (char *)&iph1
->index
.r_ck
: (char *)&iph1
->index
.i_ck
);
917 bp2
= (sw
== GENERATE
?
918 (char *)&iph1
->index
.i_ck
: (char *)&iph1
->index
.r_ck
);
919 bl
= sizeof(cookie_t
);
924 memcpy(p
, bp
->v
, bp
->l
);
927 bp
= (sw
== GENERATE
? iph1
->id
: iph1
->id_p
);
928 memcpy(p
, bp
->v
, bp
->l
);
932 if (iph1
->approval
->authmethod
== OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
) {
933 if (iph1
->gi_i
!= NULL
&& iph1
->gi_r
!= NULL
) {
934 bp
= (sw
== GENERATE
? iph1
->gi_i
: iph1
->gi_r
);
935 memcpy(p
, bp
->v
, bp
->l
);
938 memcpy(p
, gsstokens
->v
, gsstokens
->l
);
943 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with:\n");
944 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
947 res
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
953 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH computed:\n");
954 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
960 if (gsstokens
!= NULL
)
967 * compute HASH_I on base mode.
969 * HASH_I = prf(SKEYID, g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
971 * HASH_I = prf(hash(Ni_b | Nr_b), g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
974 oakley_ph1hash_base_i(iph1
, sw
)
975 struct ph1handle
*iph1
;
978 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
979 vchar_t
*hashkey
= NULL
;
980 vchar_t
*hash
= NULL
; /* for signature mode */
986 if (iph1
->etype
!= ISAKMP_ETYPE_BASE
) {
987 plog(LLV_ERROR
, LOCATION
, NULL
,
988 "invalid etype for this hash function\n");
992 switch (iph1
->approval
->authmethod
) {
993 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
994 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
995 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
996 if (iph1
->skeyid
== NULL
) {
997 plog(LLV_ERROR
, LOCATION
, NULL
, "no SKEYID found.\n");
1000 hashkey
= iph1
->skeyid
;
1003 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
1004 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1005 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
1006 #ifdef ENABLE_HYBRID
1007 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1008 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
1009 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1010 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1012 /* make hash for seed */
1013 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
1016 plog(LLV_ERROR
, LOCATION
, NULL
,
1017 "failed to get hash buffer\n");
1022 bp
= (sw
== GENERATE
? iph1
->nonce_p
: iph1
->nonce
);
1023 memcpy(p
, bp
->v
, bp
->l
);
1026 bp
= (sw
== GENERATE
? iph1
->nonce
: iph1
->nonce_p
);
1027 memcpy(p
, bp
->v
, bp
->l
);
1030 hash
= oakley_hash(buf
, iph1
);
1040 plog(LLV_ERROR
, LOCATION
, NULL
,
1041 "not supported authentication method %d\n",
1042 iph1
->approval
->authmethod
);
1047 len
= (sw
== GENERATE
? iph1
->dhpub
->l
: iph1
->dhpub_p
->l
)
1048 + sizeof(cookie_t
) * 2
1050 + (sw
== GENERATE
? iph1
->id
->l
: iph1
->id_p
->l
);
1053 plog(LLV_ERROR
, LOCATION
, NULL
,
1054 "failed to get hash buffer\n");
1059 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
1060 memcpy(p
, bp
->v
, bp
->l
);
1063 memcpy(p
, &iph1
->index
.i_ck
, sizeof(cookie_t
));
1064 p
+= sizeof(cookie_t
);
1065 memcpy(p
, &iph1
->index
.r_ck
, sizeof(cookie_t
));
1066 p
+= sizeof(cookie_t
);
1068 memcpy(p
, iph1
->sa
->v
, iph1
->sa
->l
);
1071 bp
= (sw
== GENERATE
? iph1
->id
: iph1
->id_p
);
1072 memcpy(p
, bp
->v
, bp
->l
);
1075 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH_I with:\n");
1076 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
1079 res
= oakley_prf(hashkey
, buf
, iph1
);
1085 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH_I computed:\n");
1086 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
1097 * compute HASH_R on base mode for signature method.
1099 * HASH_R = prf(hash(Ni_b | Nr_b), g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b)
1102 oakley_ph1hash_base_r(iph1
, sw
)
1103 struct ph1handle
*iph1
;
1106 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
1107 vchar_t
*hash
= NULL
;
1113 if (iph1
->etype
!= ISAKMP_ETYPE_BASE
) {
1114 plog(LLV_ERROR
, LOCATION
, NULL
,
1115 "invalid etype for this hash function\n");
1118 if (iph1
->approval
->authmethod
!= OAKLEY_ATTR_AUTH_METHOD_DSSSIG
1119 #ifdef ENABLE_HYBRID
1120 && iph1
->approval
->authmethod
!= OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
1121 && iph1
->approval
->authmethod
!= OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
1123 && iph1
->approval
->authmethod
!= OAKLEY_ATTR_AUTH_METHOD_RSASIG
) {
1124 plog(LLV_ERROR
, LOCATION
, NULL
,
1125 "not supported authentication method %d\n",
1126 iph1
->approval
->authmethod
);
1130 /* make hash for seed */
1131 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
1134 plog(LLV_ERROR
, LOCATION
, NULL
,
1135 "failed to get hash buffer\n");
1140 bp
= (sw
== GENERATE
? iph1
->nonce_p
: iph1
->nonce
);
1141 memcpy(p
, bp
->v
, bp
->l
);
1144 bp
= (sw
== GENERATE
? iph1
->nonce
: iph1
->nonce_p
);
1145 memcpy(p
, bp
->v
, bp
->l
);
1148 hash
= oakley_hash(buf
, iph1
);
1154 /* make really hash */
1155 len
= (sw
== GENERATE
? iph1
->dhpub_p
->l
: iph1
->dhpub
->l
)
1156 + (sw
== GENERATE
? iph1
->dhpub
->l
: iph1
->dhpub_p
->l
)
1157 + sizeof(cookie_t
) * 2
1159 + (sw
== GENERATE
? iph1
->id_p
->l
: iph1
->id
->l
);
1162 plog(LLV_ERROR
, LOCATION
, NULL
,
1163 "failed to get hash buffer\n");
1169 bp
= (sw
== GENERATE
? iph1
->dhpub_p
: iph1
->dhpub
);
1170 memcpy(p
, bp
->v
, bp
->l
);
1173 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
1174 memcpy(p
, bp
->v
, bp
->l
);
1177 memcpy(p
, &iph1
->index
.i_ck
, sizeof(cookie_t
));
1178 p
+= sizeof(cookie_t
);
1179 memcpy(p
, &iph1
->index
.r_ck
, sizeof(cookie_t
));
1180 p
+= sizeof(cookie_t
);
1182 memcpy(p
, iph1
->sa
->v
, iph1
->sa
->l
);
1185 bp
= (sw
== GENERATE
? iph1
->id_p
: iph1
->id
);
1186 memcpy(p
, bp
->v
, bp
->l
);
1189 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with:\n");
1190 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
1193 res
= oakley_prf(hash
, buf
, iph1
);
1199 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH computed:\n");
1200 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
1211 * compute each authentication method in phase 1.
1215 * other: error to be reply with notification.
1216 * the value is notification type.
1219 oakley_validate_auth(iph1
)
1220 struct ph1handle
*iph1
;
1222 vchar_t
*my_hash
= NULL
;
1225 vchar_t
*gsshash
= NULL
;
1228 struct timeval start
, end
;
1232 gettimeofday(&start
, NULL
);
1234 switch (iph1
->approval
->authmethod
) {
1235 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
1240 if (iph1
->id_p
== NULL
|| iph1
->pl_hash
== NULL
) {
1241 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1242 "few isakmp message received.\n");
1243 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1246 r_hash
= (caddr_t
)(iph1
->pl_hash
+ 1);
1248 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH received:");
1249 plogdump(LLV_DEBUG
, r_hash
,
1250 ntohs(iph1
->pl_hash
->h
.len
) - sizeof(*iph1
->pl_hash
));
1252 switch (iph1
->etype
) {
1253 case ISAKMP_ETYPE_IDENT
:
1254 case ISAKMP_ETYPE_AGG
:
1255 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1257 case ISAKMP_ETYPE_BASE
:
1258 if (iph1
->side
== INITIATOR
)
1259 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1261 my_hash
= oakley_ph1hash_base_i(iph1
, VALIDATE
);
1264 plog(LLV_ERROR
, LOCATION
, NULL
,
1265 "invalid etype %d\n", iph1
->etype
);
1266 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1268 if (my_hash
== NULL
)
1269 return ISAKMP_INTERNAL_ERROR
;
1271 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1275 plog(LLV_ERROR
, LOCATION
, NULL
, "HASH mismatched\n");
1276 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1279 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH for PSK validated.\n");
1282 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
1283 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1284 #ifdef ENABLE_HYBRID
1285 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1286 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
1293 if (iph1
->id_p
== NULL
) {
1294 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1295 "no ID payload was passed.\n");
1296 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1298 if (iph1
->sig_p
== NULL
) {
1299 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1300 "no SIG payload was passed.\n");
1301 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1304 plog(LLV_DEBUG
, LOCATION
, NULL
, "SIGN passed:\n");
1305 plogdump(LLV_DEBUG
, iph1
->sig_p
->v
, iph1
->sig_p
->l
);
1307 /* get peer's cert */
1308 switch (iph1
->rmconf
->getcert_method
) {
1309 case ISAKMP_GETCERT_PAYLOAD
:
1310 if (iph1
->cert_p
== NULL
) {
1311 plog(LLV_ERROR
, LOCATION
, NULL
,
1312 "no peer's CERT payload found.\n");
1313 return ISAKMP_INTERNAL_ERROR
;
1316 case ISAKMP_GETCERT_LOCALFILE
:
1317 switch (iph1
->rmconf
->certtype
) {
1318 case ISAKMP_CERT_X509SIGN
:
1319 if (iph1
->rmconf
->peerscertfile
== NULL
) {
1320 plog(LLV_ERROR
, LOCATION
, NULL
,
1321 "no peer's CERT file found.\n");
1322 return ISAKMP_INTERNAL_ERROR
;
1325 /* don't use cached cert */
1326 if (iph1
->cert_p
!= NULL
) {
1327 oakley_delcert(iph1
->cert_p
);
1328 iph1
->cert_p
= NULL
;
1331 error
= get_cert_fromlocal(iph1
, 0);
1334 case ISAKMP_CERT_PLAINRSA
:
1335 error
= get_plainrsa_fromlocal(iph1
, 0);
1339 return ISAKMP_INTERNAL_ERROR
;
1341 case ISAKMP_GETCERT_DNS
:
1342 if (iph1
->rmconf
->peerscertfile
!= NULL
) {
1343 plog(LLV_ERROR
, LOCATION
, NULL
,
1344 "why peer's CERT file is defined "
1345 "though getcert method is dns ?\n");
1346 return ISAKMP_INTERNAL_ERROR
;
1349 /* don't use cached cert */
1350 if (iph1
->cert_p
!= NULL
) {
1351 oakley_delcert(iph1
->cert_p
);
1352 iph1
->cert_p
= NULL
;
1355 iph1
->cert_p
= dnssec_getcert(iph1
->id_p
);
1356 if (iph1
->cert_p
== NULL
) {
1357 plog(LLV_ERROR
, LOCATION
, NULL
,
1358 "no CERT RR found.\n");
1359 return ISAKMP_INTERNAL_ERROR
;
1363 plog(LLV_ERROR
, LOCATION
, NULL
,
1364 "invalid getcert_mothod: %d\n",
1365 iph1
->rmconf
->getcert_method
);
1366 return ISAKMP_INTERNAL_ERROR
;
1369 /* compare ID payload and certificate name */
1370 if (iph1
->rmconf
->verify_cert
&&
1372 (error
= oakley_check_certid(iph1
, CERT_CHECKID_FROM_PEER
)) != 0)
1374 (error
= oakley_check_certid(iph1
)) != 0)
1380 /* check configured peers identifier against cert IDs */
1381 /* allows checking of specified ID against multiple ids in the cert */
1382 /* such as multiple domain names */
1383 if (iph1
->rmconf
->cert_verification_option
== VERIFICATION_OPTION_PEERS_IDENTIFIER
&&
1384 (error
= oakley_check_certid(iph1
, CERT_CHECKID_FROM_RMCONFIG
)) != 0)
1387 /* check cert common name against Open Directory authentication group */
1388 if (iph1
->rmconf
->cert_verification_option
== VERIFICATION_OPTION_OPEN_DIR
) {
1390 vchar_t
*user_id
= NULL
;
1392 user_id
= eay_get_x509_common_name(&iph1
->cert_p
->cert
);
1394 // the following functions will check if user_id == 0
1395 if (open_dir_authorize_id(user_id
, iph1
->rmconf
->open_dir_auth_group
) == 0) {
1396 plog(LLV_ERROR
, LOCATION
, NULL
,
1397 "the peer is not authorized for access.\n");
1399 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1403 plog(LLV_ERROR
, LOCATION
, NULL
,
1404 "the peer is not authorized for access - user ID not found.\n");
1405 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1410 /* verify certificate */
1411 if (iph1
->rmconf
->verify_cert
1412 && iph1
->rmconf
->getcert_method
== ISAKMP_GETCERT_PAYLOAD
) {
1413 certtype
= iph1
->rmconf
->certtype
;
1414 #ifdef ENABLE_HYBRID
1415 switch (iph1
->approval
->authmethod
) {
1416 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1417 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
1418 certtype
= iph1
->cert_p
->type
;
1425 case ISAKMP_CERT_X509SIGN
:
1427 if (iph1
->rmconf
->cert_verification
== VERIFICATION_MODULE_SEC_FRAMEWORK
)
1428 error
= crypto_cssm_check_x509cert(&iph1
->cert_p
->cert
);
1432 char path
[MAXPATHLEN
];
1435 if (iph1
->rmconf
->cacertfile
!= NULL
) {
1436 getpathname(path
, sizeof(path
),
1438 iph1
->rmconf
->cacertfile
);
1444 error
= eay_check_x509cert(&iph1
->cert_p
->cert
,
1445 lcconf
->pathinfo
[LC_PATHTYPE_CERT
],
1451 plog(LLV_ERROR
, LOCATION
, NULL
,
1452 "no supported certtype %d\n", certtype
);
1453 return ISAKMP_INTERNAL_ERROR
;
1456 plog(LLV_ERROR
, LOCATION
, NULL
,
1457 "the peer's certificate is not verified.\n");
1458 return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY
;
1463 plog(LLV_DEBUG
, LOCATION
, NULL
, "CERT validated\n");
1466 switch (iph1
->etype
) {
1467 case ISAKMP_ETYPE_IDENT
:
1468 case ISAKMP_ETYPE_AGG
:
1469 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1471 case ISAKMP_ETYPE_BASE
:
1472 if (iph1
->side
== INITIATOR
)
1473 my_hash
= oakley_ph1hash_base_r(iph1
, VALIDATE
);
1475 my_hash
= oakley_ph1hash_base_i(iph1
, VALIDATE
);
1478 plog(LLV_ERROR
, LOCATION
, NULL
,
1479 "invalid etype %d\n", iph1
->etype
);
1480 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1482 if (my_hash
== NULL
)
1483 return ISAKMP_INTERNAL_ERROR
;
1486 certtype
= iph1
->rmconf
->certtype
;
1487 #ifdef ENABLE_HYBRID
1488 switch (iph1
->approval
->authmethod
) {
1489 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1490 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
1491 certtype
= iph1
->cert_p
->type
;
1497 /* check signature */
1499 case ISAKMP_CERT_X509SIGN
:
1500 case ISAKMP_CERT_DNS
:
1501 error
= eay_check_x509sign(my_hash
,
1503 &iph1
->cert_p
->cert
);
1505 case ISAKMP_CERT_PLAINRSA
:
1506 iph1
->rsa_p
= rsa_try_check_rsasign(my_hash
,
1507 iph1
->sig_p
, iph1
->rsa_candidates
);
1508 error
= iph1
->rsa_p
? 0 : -1;
1512 plog(LLV_ERROR
, LOCATION
, NULL
,
1513 "no supported certtype %d\n",
1516 return ISAKMP_INTERNAL_ERROR
;
1521 plog(LLV_ERROR
, LOCATION
, NULL
,
1523 return ISAKMP_NTYPE_INVALID_SIGNATURE
;
1525 plog(LLV_DEBUG
, LOCATION
, NULL
, "SIG authenticated\n");
1528 #ifdef ENABLE_HYBRID
1529 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1530 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1532 if ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_VENDORID_XAUTH
) == 0) {
1533 plog(LLV_ERROR
, LOCATION
, NULL
, "No SIG was passed, "
1534 "hybrid auth is enabled, "
1535 "but peer is no Xauth compliant\n");
1536 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED
;
1539 plog(LLV_INFO
, LOCATION
, NULL
, "No SIG was passed, "
1540 "but hybrid auth is enabled\n");
1547 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
1548 switch (iph1
->etype
) {
1549 case ISAKMP_ETYPE_IDENT
:
1550 case ISAKMP_ETYPE_AGG
:
1551 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1554 plog(LLV_ERROR
, LOCATION
, NULL
,
1555 "invalid etype %d\n", iph1
->etype
);
1556 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1559 if (my_hash
== NULL
) {
1560 if (gssapi_more_tokens(iph1
))
1561 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1563 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1566 gsshash
= gssapi_unwraphash(iph1
);
1567 if (gsshash
== NULL
) {
1569 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1572 result
= memcmp(my_hash
->v
, gsshash
->v
, my_hash
->l
);
1577 plog(LLV_ERROR
, LOCATION
, NULL
, "HASH mismatched\n");
1578 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1580 plog(LLV_DEBUG
, LOCATION
, NULL
, "hash compared OK\n");
1583 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
1584 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
1585 if (iph1
->id_p
== NULL
|| iph1
->pl_hash
== NULL
) {
1586 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1587 "few isakmp message received.\n");
1588 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1590 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1591 "not supported authmethod type %s\n",
1592 s_oakley_attr_method(iph1
->approval
->authmethod
));
1593 return ISAKMP_INTERNAL_ERROR
;
1595 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1596 "invalid authmethod %d why ?\n",
1597 iph1
->approval
->authmethod
);
1598 return ISAKMP_INTERNAL_ERROR
;
1601 gettimeofday(&end
, NULL
);
1602 syslog(LOG_NOTICE
, "%s(%s): %8.6f", __func__
,
1603 s_oakley_attr_method(iph1
->approval
->authmethod
),
1604 timedelta(&start
, &end
));
1610 /* get my certificate
1611 * NOTE: include certificate type.
1614 oakley_getmycert(iph1
)
1615 struct ph1handle
*iph1
;
1617 switch (iph1
->rmconf
->certtype
) {
1618 case ISAKMP_CERT_X509SIGN
:
1621 return get_cert_fromlocal(iph1
, 1);
1623 case ISAKMP_CERT_PLAINRSA
:
1626 return get_plainrsa_fromlocal(iph1
, 1);
1629 plog(LLV_ERROR
, LOCATION
, NULL
,
1630 "Unknown certtype #%d\n",
1631 iph1
->rmconf
->certtype
);
1638 * get a CERT from local file.
1641 * my == 0 peer's cert.
1644 get_cert_fromlocal(iph1
, my
)
1645 struct ph1handle
*iph1
;
1648 char path
[MAXPATHLEN
];
1649 vchar_t
*cert
= NULL
;
1655 certfile
= iph1
->rmconf
->mycertfile
;
1656 certpl
= &iph1
->cert
;
1658 certfile
= iph1
->rmconf
->peerscertfile
;
1659 certpl
= &iph1
->cert_p
;
1663 if (!certfile
&& iph1
->rmconf
->identity_in_keychain
== 0) {
1667 plog(LLV_ERROR
, LOCATION
, NULL
, "no CERT defined.\n");
1671 switch (iph1
->rmconf
->certtype
) {
1672 case ISAKMP_CERT_X509SIGN
:
1674 if (iph1
->rmconf
->identity_in_keychain
) {
1677 if (base64toCFData(iph1
->rmconf
->keychainCertRef
, &dataRef
))
1679 cert
= crypto_cssm_get_x509cert(dataRef
);
1684 case ISAKMP_CERT_DNS
:
1685 /* make public file name */
1686 getpathname(path
, sizeof(path
), LC_PATHTYPE_CERT
, certfile
);
1687 cert
= eay_get_x509cert(path
);
1690 p
= eay_get_x509text(cert
);
1691 plog(LLV_DEBUG
, LOCATION
, NULL
, "%s", p
? p
: "\n");
1697 plog(LLV_ERROR
, LOCATION
, NULL
,
1698 "not supported certtype %d\n",
1699 iph1
->rmconf
->certtype
);
1704 plog(LLV_ERROR
, LOCATION
, NULL
,
1705 "failed to get %s CERT.\n",
1706 my
? "my" : "peers");
1710 *certpl
= oakley_newcert();
1712 plog(LLV_ERROR
, LOCATION
, NULL
,
1713 "failed to get cert buffer.\n");
1716 (*certpl
)->pl
= vmalloc(cert
->l
+ 1);
1717 if ((*certpl
)->pl
== NULL
) {
1718 plog(LLV_ERROR
, LOCATION
, NULL
,
1719 "failed to get cert buffer\n");
1720 oakley_delcert(*certpl
);
1724 memcpy((*certpl
)->pl
->v
+ 1, cert
->v
, cert
->l
);
1725 (*certpl
)->pl
->v
[0] = iph1
->rmconf
->certtype
;
1726 (*certpl
)->type
= iph1
->rmconf
->certtype
;
1727 (*certpl
)->cert
.v
= (*certpl
)->pl
->v
+ 1;
1728 (*certpl
)->cert
.l
= (*certpl
)->pl
->l
- 1;
1730 plog(LLV_DEBUG
, LOCATION
, NULL
, "created CERT payload:\n");
1731 plogdump(LLV_DEBUG
, (*certpl
)->pl
->v
, (*certpl
)->pl
->l
);
1743 get_plainrsa_fromlocal(iph1
, my
)
1744 struct ph1handle
*iph1
;
1747 char path
[MAXPATHLEN
];
1748 vchar_t
*cert
= NULL
;
1752 iph1
->rsa_candidates
= rsa_lookup_keys(iph1
, my
);
1753 if (!iph1
->rsa_candidates
|| rsa_list_count(iph1
->rsa_candidates
) == 0) {
1754 plog(LLV_ERROR
, LOCATION
, NULL
,
1755 "%s RSA key not found for %s\n",
1756 my
? "Private" : "Public",
1757 saddr2str_fromto("%s <-> %s", iph1
->local
, iph1
->remote
));
1761 if (my
&& rsa_list_count(iph1
->rsa_candidates
) > 1) {
1762 plog(LLV_WARNING
, LOCATION
, NULL
,
1763 "More than one (=%lu) private PlainRSA key found for %s\n",
1764 rsa_list_count(iph1
->rsa_candidates
),
1765 saddr2str_fromto("%s <-> %s", iph1
->local
, iph1
->remote
));
1766 plog(LLV_WARNING
, LOCATION
, NULL
,
1767 "This may have unpredictable results, i.e. wrong key could be used!\n");
1768 plog(LLV_WARNING
, LOCATION
, NULL
,
1769 "Consider using only one single private key for all peers...\n");
1772 iph1
->rsa
= ((struct rsa_key
*)genlist_next(iph1
->rsa_candidates
, NULL
))->rsa
;
1773 genlist_free(iph1
->rsa_candidates
, NULL
);
1774 iph1
->rsa_candidates
= NULL
;
1785 oakley_getsign(iph1
)
1786 struct ph1handle
*iph1
;
1788 char path
[MAXPATHLEN
];
1789 vchar_t
*privkey
= NULL
;
1792 switch (iph1
->rmconf
->certtype
) {
1793 case ISAKMP_CERT_X509SIGN
:
1795 // cert in keychain - use cssm to sign
1796 if (iph1
->rmconf
->identity_in_keychain
) {
1799 if (base64toCFData(iph1
->rmconf
->keychainCertRef
, &dataRef
))
1801 iph1
->sig
= crypto_cssm_getsign(dataRef
, iph1
->hash
);
1806 case ISAKMP_CERT_DNS
:
1807 if (iph1
->rmconf
->myprivfile
== NULL
) {
1808 plog(LLV_ERROR
, LOCATION
, NULL
, "no cert defined.\n");
1812 /* make private file name */
1813 getpathname(path
, sizeof(path
),
1815 iph1
->rmconf
->myprivfile
);
1816 privkey
= privsep_eay_get_pkcs1privkey(path
);
1817 if (privkey
== NULL
) {
1818 plog(LLV_ERROR
, LOCATION
, NULL
,
1819 "failed to get private key.\n");
1822 plog(LLV_DEBUG2
, LOCATION
, NULL
, "private key:\n");
1823 plogdump(LLV_DEBUG2
, privkey
->v
, privkey
->l
);
1825 iph1
->sig
= eay_get_x509sign(iph1
->hash
, privkey
);
1827 case ISAKMP_CERT_PLAINRSA
:
1828 iph1
->sig
= eay_get_rsasign(iph1
->hash
, iph1
->rsa
);
1831 plog(LLV_ERROR
, LOCATION
, NULL
,
1832 "Unknown certtype #%d\n",
1833 iph1
->rmconf
->certtype
);
1837 if (iph1
->sig
== NULL
) {
1838 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to sign.\n");
1842 plog(LLV_DEBUG
, LOCATION
, NULL
, "SIGN computed:\n");
1843 plogdump(LLV_DEBUG
, iph1
->sig
->v
, iph1
->sig
->l
);
1848 if (privkey
!= NULL
)
1857 * compare certificate name and ID value.
1860 oakley_check_certid(iph1
, which_id
)
1861 struct ph1handle
*iph1
;
1864 struct ipsecdoi_id_b
*id_b
;
1866 u_int8_t doi_type
= 255;
1867 void *peers_id
= NULL
;
1868 struct genlist_entry
*gpb
= NULL
;
1870 if (which_id
== CERT_CHECKID_FROM_PEER
) {
1871 /* use ID from peer */
1872 if (iph1
->id_p
== NULL
|| iph1
->cert_p
== NULL
) {
1873 plog(LLV_ERROR
, LOCATION
, NULL
, "no ID nor CERT found.\n");
1874 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1876 id_b
= (struct ipsecdoi_id_b
*)iph1
->id_p
->v
;
1877 doi_type
= id_b
->type
;
1878 peers_id
= id_b
+ 1;
1879 idlen
= iph1
->id_p
->l
- sizeof(*id_b
);
1881 return oakley_check_certid_1(iph1
, doi_type
, idlen
, peers_id
);
1884 /* use ID from remote configuration */
1885 /* check each ID in list */
1886 struct idspec
*id_spec
;
1888 for (id_spec
= genlist_next (iph1
->rmconf
->idvl_p
, &gpb
); id_spec
; id_spec
= genlist_next (0, &gpb
)) {
1890 if (id_spec
->idtype
== IDTYPE_ADDRESS
) {
1891 switch (((struct sockaddr
*)(id_spec
->id
->v
))->sa_family
) {
1893 doi_type
= IPSECDOI_ID_IPV4_ADDR
;
1894 idlen
= sizeof(struct in_addr
);
1895 peers_id
= &(((struct sockaddr_in
*)(id_spec
->id
->v
))->sin_addr
.s_addr
);
1899 doi_type
= IPSECDOI_ID_IPV6_ADDR
;
1900 idlen
= sizeof(struct in6_addr
);
1901 peers_id
= &(((struct sockaddr_in6
*)(id_spec
->id
->v
))->sin6_addr
.s6_addr
);
1905 plog(LLV_ERROR
, LOCATION
, NULL
,
1906 "unknown address type for peers identifier.\n");
1907 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1912 doi_type
= idtype2doi(id_spec
->idtype
);
1913 peers_id
= id_spec
->id
->v
;
1914 idlen
= id_spec
->id
->l
;
1916 if (oakley_check_certid_1(iph1
, doi_type
, idlen
, peers_id
) == 0)
1919 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1924 oakley_check_certid_1(iph1
, idtype
, idlen
, id
)
1925 struct ph1handle
*iph1
;
1931 vchar_t
*name
= NULL
;
1932 char *altname
= NULL
;
1937 case IPSECDOI_ID_DER_ASN1_DN
:
1938 name
= eay_get_x509asn1subjectname(&iph1
->cert_p
->cert
);
1940 plog(LLV_ERROR
, LOCATION
, NULL
,
1941 "failed to get subjectName\n");
1942 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
1944 if (idlen
!= name
->l
) {
1945 plog(LLV_ERROR
, LOCATION
, NULL
,
1946 "Invalid ID length in phase 1.\n");
1948 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1950 error
= memcmp(id
, name
->v
, idlen
);
1953 plog(LLV_ERROR
, LOCATION
, NULL
,
1954 "ID mismatched with subjectName.\n");
1955 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1958 case IPSECDOI_ID_IPV4_ADDR
:
1959 case IPSECDOI_ID_IPV6_ADDR
:
1963 * Openssl returns the IPAddress as an ASN1 octet string (binary format)
1964 * followed by a trailing NULL. 5 bytes for IPv4 and 17 bytes for IPv6
1966 #define SUBJ_ALT_NAME_IPV4_ADDRESS_LEN 5
1967 #define SUBJ_ALT_NAME_IPV6_ADDRESS_LEN 17
1971 if (idtype
== IPSECDOI_ID_IPV4_ADDR
&& idlen
!= sizeof(struct in_addr
)
1972 || idtype
== IPSECDOI_ID_IPV6_ADDR
&& idlen
!= sizeof(struct in6_addr
)) {
1973 plog(LLV_ERROR
, LOCATION
, NULL
,
1974 "invalid address length passed.\n");
1975 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1978 for (pos
= 1; ; pos
++) {
1979 if (eay_get_x509subjectaltname(&iph1
->cert_p
->cert
, &altname
, &type
, pos
, &len
) !=0) {
1980 plog(LLV_ERROR
, LOCATION
, NULL
,
1981 "failed to get subjectAltName\n");
1982 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
1985 /* it's the end condition of the loop. */
1987 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1990 if (check_typeofcertname(idtype
, type
) != 0) {
1991 /* wrong type - skip this one */
1992 racoon_free(altname
);
1997 if (len
== SUBJ_ALT_NAME_IPV4_ADDRESS_LEN
) { /* IPv4 */
1998 if (idtype
!= IPSECDOI_ID_IPV4_ADDR
) {
1999 /* wrong IP address type - skip this one */
2000 racoon_free(altname
);
2006 else if (len
== SUBJ_ALT_NAME_IPV6_ADDRESS_LEN
) { /* IPv6 */
2007 if (idtype
!= IPSECDOI_ID_IPV6_ADDR
) {
2008 /* wrong IP address type - skip this one */
2009 racoon_free(altname
);
2016 /* invalid IP address length in certificate - bad or bogus certificate */
2017 plog(LLV_ERROR
, LOCATION
, NULL
,
2018 "invalid IP address in certificate.\n");
2019 racoon_free(altname
);
2021 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2024 /* compare the addresses */
2025 error
= memcmp(id
, altname
, idlen
);
2026 racoon_free(altname
);
2028 plog(LLV_ERROR
, LOCATION
, NULL
,
2029 "ID mismatched with subjectAltName.\n");
2030 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2035 case IPSECDOI_ID_FQDN
:
2036 case IPSECDOI_ID_USER_FQDN
:
2040 for (pos
= 1; ; pos
++) {
2041 if (eay_get_x509subjectaltname(&iph1
->cert_p
->cert
, &altname
, &type
, pos
, &len
) != 0) {
2042 plog(LLV_ERROR
, LOCATION
, NULL
,
2043 "failed to get subjectAltName\n");
2044 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2047 /* it's the end condition of the loop. */
2049 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2052 if (check_typeofcertname(idtype
, type
) != 0) {
2053 /* wrong general type - skip this one */
2054 racoon_free(altname
);
2059 if (idlen
!= strlen(altname
)) {
2060 /* wrong length - skip this one */
2061 racoon_free(altname
);
2065 error
= memcmp(id
, altname
, idlen
);
2066 racoon_free(altname
);
2068 plog(LLV_ERROR
, LOCATION
, NULL
, "ID mismatched.\n");
2069 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2075 plog(LLV_ERROR
, LOCATION
, NULL
,
2076 "Impropper ID type passed: %s.\n",
2077 s_ipsecdoi_ident(idtype
));
2078 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2083 #else /* __APPLE__ */
2086 * compare certificate name and ID value.
2089 oakley_check_certid(iph1
)
2090 struct ph1handle
*iph1
;
2092 struct ipsecdoi_id_b
*id_b
;
2093 vchar_t
*name
= NULL
;
2094 char *altname
= NULL
;
2098 if (iph1
->id_p
== NULL
|| iph1
->cert_p
== NULL
) {
2099 plog(LLV_ERROR
, LOCATION
, NULL
, "no ID nor CERT found.\n");
2100 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2103 id_b
= (struct ipsecdoi_id_b
*)iph1
->id_p
->v
;
2104 idlen
= iph1
->id_p
->l
- sizeof(*id_b
);
2106 switch (id_b
->type
) {
2107 case IPSECDOI_ID_DER_ASN1_DN
:
2108 name
= eay_get_x509asn1subjectname(&iph1
->cert_p
->cert
);
2110 plog(LLV_ERROR
, LOCATION
, NULL
,
2111 "failed to get subjectName\n");
2112 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2114 if (idlen
!= name
->l
) {
2115 plog(LLV_ERROR
, LOCATION
, NULL
,
2116 "Invalid ID length in phase 1.\n");
2118 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2120 error
= memcmp(id_b
+ 1, name
->v
, idlen
);
2123 plog(LLV_ERROR
, LOCATION
, NULL
,
2124 "ID mismatched with subjectAltName.\n");
2125 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2128 case IPSECDOI_ID_IPV4_ADDR
:
2129 case IPSECDOI_ID_IPV6_ADDR
:
2132 * converting to binary from string because openssl return
2133 * a string even if object is a binary.
2134 * XXX fix it ! access by ASN.1 directly without.
2136 struct addrinfo hints
, *res
;
2140 for (pos
= 1; ; pos
++) {
2141 if (eay_get_x509subjectaltname(&iph1
->cert_p
->cert
,
2142 &altname
, &type
, pos
) !=0) {
2143 plog(LLV_ERROR
, LOCATION
, NULL
,
2144 "failed to get subjectAltName\n");
2145 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2148 /* it's the end condition of the loop. */
2150 plog(LLV_ERROR
, LOCATION
, NULL
,
2151 "no proper subjectAltName.\n");
2152 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2155 if (check_typeofcertname(id_b
->type
, type
) == 0)
2159 racoon_free(altname
);
2162 memset(&hints
, 0, sizeof(hints
));
2163 hints
.ai_family
= PF_UNSPEC
;
2164 hints
.ai_socktype
= SOCK_RAW
;
2165 hints
.ai_flags
= AI_NUMERICHOST
;
2166 error
= getaddrinfo(altname
, NULL
, &hints
, &res
);
2168 plog(LLV_ERROR
, LOCATION
, NULL
,
2169 "no proper subjectAltName.\n");
2170 racoon_free(altname
);
2171 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2173 switch (res
->ai_family
) {
2175 a
= (caddr_t
)&((struct sockaddr_in
*)res
->ai_addr
)->sin_addr
.s_addr
;
2179 a
= (caddr_t
)&((struct sockaddr_in6
*)res
->ai_addr
)->sin6_addr
.s6_addr
;
2183 plog(LLV_ERROR
, LOCATION
, NULL
,
2184 "family not supported: %d.\n", res
->ai_family
);
2185 racoon_free(altname
);
2187 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2189 error
= memcmp(id_b
+ 1, a
, idlen
);
2193 plog(LLV_ERROR
, LOCATION
, NULL
,
2194 "ID mismatched with subjectAltName.\n");
2195 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2199 case IPSECDOI_ID_FQDN
:
2200 case IPSECDOI_ID_USER_FQDN
:
2204 for (pos
= 1; ; pos
++) {
2205 if (eay_get_x509subjectaltname(&iph1
->cert_p
->cert
,
2206 &altname
, &type
, pos
) != 0){
2207 plog(LLV_ERROR
, LOCATION
, NULL
,
2208 "failed to get subjectAltName\n");
2209 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2212 /* it's the end condition of the loop. */
2214 plog(LLV_ERROR
, LOCATION
, NULL
,
2215 "no proper subjectAltName.\n");
2216 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2219 if (check_typeofcertname(id_b
->type
, type
) == 0)
2223 racoon_free(altname
);
2226 if (idlen
!= strlen(altname
)) {
2227 plog(LLV_ERROR
, LOCATION
, NULL
,
2228 "Invalid ID length in phase 1.\n");
2229 racoon_free(altname
);
2230 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2232 if (check_typeofcertname(id_b
->type
, type
) != 0) {
2233 plog(LLV_ERROR
, LOCATION
, NULL
,
2234 "ID type mismatched. ID: %s CERT: %s.\n",
2235 s_ipsecdoi_ident(id_b
->type
),
2236 s_ipsecdoi_ident(type
));
2237 racoon_free(altname
);
2238 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2240 error
= memcmp(id_b
+ 1, altname
, idlen
);
2242 plog(LLV_ERROR
, LOCATION
, NULL
, "ID mismatched.\n");
2243 racoon_free(altname
);
2244 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2246 racoon_free(altname
);
2250 plog(LLV_ERROR
, LOCATION
, NULL
,
2251 "Impropper ID type passed: %s.\n",
2252 s_ipsecdoi_ident(id_b
->type
));
2253 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2258 #endif /* __APPLE__ */
2261 check_typeofcertname(doi
, genid
)
2265 case IPSECDOI_ID_IPV4_ADDR
:
2266 case IPSECDOI_ID_IPV4_ADDR_SUBNET
:
2267 case IPSECDOI_ID_IPV6_ADDR
:
2268 case IPSECDOI_ID_IPV6_ADDR_SUBNET
:
2269 case IPSECDOI_ID_IPV4_ADDR_RANGE
:
2270 case IPSECDOI_ID_IPV6_ADDR_RANGE
:
2271 if (genid
!= GENT_IPADD
)
2274 case IPSECDOI_ID_FQDN
:
2275 if (genid
!= GENT_DNS
)
2278 case IPSECDOI_ID_USER_FQDN
:
2279 if (genid
!= GENT_EMAIL
)
2282 case IPSECDOI_ID_DER_ASN1_DN
: /* should not be passed to this function*/
2283 case IPSECDOI_ID_DER_ASN1_GN
:
2284 case IPSECDOI_ID_KEY_ID
:
2292 * save certificate including certificate type.
2295 oakley_savecert(iph1
, gen
)
2296 struct ph1handle
*iph1
;
2297 struct isakmp_gen
*gen
;
2301 STACK_OF(X509
) *certs
=NULL
;
2304 type
= *(u_int8_t
*)(gen
+ 1) & 0xff;
2307 case ISAKMP_CERT_DNS
:
2308 plog(LLV_WARNING
, LOCATION
, NULL
,
2309 "CERT payload is unnecessary in DNSSEC. "
2310 "ignore this CERT payload.\n");
2312 case ISAKMP_CERT_PKCS7
:
2313 case ISAKMP_CERT_PGP
:
2314 case ISAKMP_CERT_X509SIGN
:
2315 case ISAKMP_CERT_KERBEROS
:
2316 case ISAKMP_CERT_SPKI
:
2319 case ISAKMP_CERT_CRL
:
2322 case ISAKMP_CERT_X509KE
:
2323 case ISAKMP_CERT_X509ATTR
:
2324 case ISAKMP_CERT_ARL
:
2325 plog(LLV_ERROR
, LOCATION
, NULL
,
2326 "No supported such CERT type %d\n", type
);
2329 plog(LLV_ERROR
, LOCATION
, NULL
,
2330 "Invalid CERT type %d\n", type
);
2334 /* XXX choice the 1th cert, ignore after the cert. */
2335 /* XXX should be processed. */
2337 plog(LLV_WARNING
, LOCATION
, NULL
,
2338 "ignore 2nd CERT payload.\n");
2342 if (type
== ISAKMP_CERT_PKCS7
) {
2346 /* Skip the header */
2347 bp
= (u_char
*)(gen
+ 1);
2348 /* And the first byte is the certificate type,
2349 * we know that already
2352 p7
= d2i_PKCS7(NULL
, (void *)&bp
,
2353 ntohs(gen
->len
) - sizeof(*gen
) - 1);
2356 plog(LLV_ERROR
, LOCATION
, NULL
,
2357 "Failed to parse PKCS#7 CERT.\n");
2361 /* Copied this from the openssl pkcs7 application;
2362 * there"s little by way of documentation for any of
2363 * it. I can only presume it"s correct.
2366 i
= OBJ_obj2nid(p7
->type
);
2368 case NID_pkcs7_signed
:
2369 certs
=p7
->d
.sign
->cert
;
2371 case NID_pkcs7_signedAndEnveloped
:
2372 certs
=p7
->d
.signed_and_enveloped
->cert
;
2379 plog(LLV_ERROR
, LOCATION
, NULL
,
2380 "CERT PKCS#7 bundle contains no certs.\n");
2385 for (i
= 0; i
< sk_X509_num(certs
); i
++) {
2388 X509
*cert
= sk_X509_value(certs
,i
);
2390 plog(LLV_DEBUG
, LOCATION
, NULL
,
2391 "Trying PKCS#7 cert %d.\n", i
);
2393 /* We'll just try each cert in turn */
2394 *c
= save_certx509(cert
);
2397 plog(LLV_ERROR
, LOCATION
, NULL
,
2398 "Failed to get CERT buffer.\n");
2402 /* Ignore cert if it doesn't match identity
2403 * XXX If verify cert is disabled, we still just take
2404 * the first certificate....
2406 if(iph1
->rmconf
->verify_cert
&&
2407 oakley_check_certid(iph1
, CERT_CHECKID_FROM_PEER
)) {
2408 plog(LLV_DEBUG
, LOCATION
, NULL
,
2409 "Discarding CERT: does not match ID.\n");
2410 oakley_delcert((*c
));
2416 char *p
= eay_get_x509text(&(*c
)->cert
);
2417 plog(LLV_DEBUG
, LOCATION
, NULL
, "CERT saved:\n");
2418 plogdump(LLV_DEBUG
, (*c
)->cert
.v
, (*c
)->cert
.l
);
2419 plog(LLV_DEBUG
, LOCATION
, NULL
, "%s",
2428 *c
= save_certbuf(gen
);
2430 plog(LLV_ERROR
, LOCATION
, NULL
,
2431 "Failed to get CERT buffer.\n");
2435 switch ((*c
)->type
) {
2436 case ISAKMP_CERT_DNS
:
2437 plog(LLV_WARNING
, LOCATION
, NULL
,
2438 "CERT payload is unnecessary in DNSSEC. "
2441 case ISAKMP_CERT_PGP
:
2442 case ISAKMP_CERT_X509SIGN
:
2443 case ISAKMP_CERT_KERBEROS
:
2444 case ISAKMP_CERT_SPKI
:
2445 /* Ignore cert if it doesn't match identity
2446 * XXX If verify cert is disabled, we still just take
2447 * the first certificate....
2449 if(iph1
->rmconf
->verify_cert
&&
2450 oakley_check_certid(iph1
, CERT_CHECKID_FROM_PEER
)){
2451 plog(LLV_DEBUG
, LOCATION
, NULL
,
2452 "Discarding CERT: does not match ID.\n");
2453 oakley_delcert((*c
));
2459 char *p
= eay_get_x509text(&(*c
)->cert
);
2460 plog(LLV_DEBUG
, LOCATION
, NULL
, "CERT saved:\n");
2461 plogdump(LLV_DEBUG
, (*c
)->cert
.v
, (*c
)->cert
.l
);
2462 plog(LLV_DEBUG
, LOCATION
, NULL
, "%s", p
? p
: "\n");
2466 case ISAKMP_CERT_CRL
:
2467 plog(LLV_DEBUG
, LOCATION
, NULL
, "CRL saved:\n");
2468 plogdump(LLV_DEBUG
, (*c
)->cert
.v
, (*c
)->cert
.l
);
2470 case ISAKMP_CERT_X509KE
:
2471 case ISAKMP_CERT_X509ATTR
:
2472 case ISAKMP_CERT_ARL
:
2475 oakley_delcert((*c
));
2485 * save certificate including certificate type.
2488 oakley_savecr(iph1
, gen
)
2489 struct ph1handle
*iph1
;
2490 struct isakmp_gen
*gen
;
2495 type
= *(u_int8_t
*)(gen
+ 1) & 0xff;
2498 case ISAKMP_CERT_DNS
:
2499 plog(LLV_WARNING
, LOCATION
, NULL
,
2500 "CERT payload is unnecessary in DNSSEC\n");
2502 case ISAKMP_CERT_PKCS7
:
2503 case ISAKMP_CERT_PGP
:
2504 case ISAKMP_CERT_X509SIGN
:
2505 case ISAKMP_CERT_KERBEROS
:
2506 case ISAKMP_CERT_SPKI
:
2509 case ISAKMP_CERT_X509KE
:
2510 case ISAKMP_CERT_X509ATTR
:
2511 case ISAKMP_CERT_ARL
:
2512 plog(LLV_ERROR
, LOCATION
, NULL
,
2513 "No supported such CR type %d\n", type
);
2515 case ISAKMP_CERT_CRL
:
2517 plog(LLV_ERROR
, LOCATION
, NULL
,
2518 "Invalid CR type %d\n", type
);
2522 *c
= save_certbuf(gen
);
2524 plog(LLV_ERROR
, LOCATION
, NULL
,
2525 "Failed to get CR buffer.\n");
2529 plog(LLV_DEBUG
, LOCATION
, NULL
, "CR saved:\n");
2530 plogdump(LLV_DEBUG
, (*c
)->cert
.v
, (*c
)->cert
.l
);
2537 struct isakmp_gen
*gen
;
2541 new = oakley_newcert();
2543 plog(LLV_ERROR
, LOCATION
, NULL
,
2544 "Failed to get CERT buffer.\n");
2548 new->pl
= vmalloc(ntohs(gen
->len
) - sizeof(*gen
));
2549 if (new->pl
== NULL
) {
2550 plog(LLV_ERROR
, LOCATION
, NULL
,
2551 "Failed to copy CERT from packet.\n");
2552 oakley_delcert(new);
2556 memcpy(new->pl
->v
, gen
+ 1, new->pl
->l
);
2557 new->type
= new->pl
->v
[0] & 0xff;
2558 new->cert
.v
= new->pl
->v
+ 1;
2559 new->cert
.l
= new->pl
->l
- 1;
2572 new = oakley_newcert();
2574 plog(LLV_ERROR
, LOCATION
, NULL
,
2575 "Failed to get CERT buffer.\n");
2579 len
= i2d_X509(cert
, NULL
);
2580 new->pl
= vmalloc(len
);
2581 if (new->pl
== NULL
) {
2582 plog(LLV_ERROR
, LOCATION
, NULL
,
2583 "Failed to copy CERT from packet.\n");
2584 oakley_delcert(new);
2588 bp
= (u_char
*) new->pl
->v
;
2589 len
= i2d_X509(cert
, &bp
);
2590 new->type
= ISAKMP_CERT_X509SIGN
;
2591 new->cert
.v
= new->pl
->v
;
2592 new->cert
.l
= new->pl
->l
;
2599 * NOTE: No Certificate Authority field is included to CR payload at the
2600 * moment. Becuase any certificate authority are accepted without any check.
2601 * The section 3.10 in RFC2408 says that this field SHOULD not be included,
2602 * if there is no specific certificate authority requested.
2606 struct ph1handle
*iph1
;
2612 plog(LLV_ERROR
, LOCATION
, NULL
,
2613 "failed to get cr buffer\n");
2616 buf
->v
[0] = iph1
->rmconf
->certtype
;
2618 plog(LLV_DEBUG
, LOCATION
, NULL
, "create my CR: %s\n",
2619 s_isakmp_certtype(iph1
->rmconf
->certtype
));
2621 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
2630 oakley_checkcr(iph1
)
2631 struct ph1handle
*iph1
;
2633 if (iph1
->cr_p
== NULL
)
2636 plog(LLV_DEBUG
, LOCATION
, iph1
->remote
,
2637 "peer transmitted CR: %s\n",
2638 s_isakmp_certtype(iph1
->cr_p
->type
));
2640 if (iph1
->cr_p
->type
!= iph1
->rmconf
->certtype
) {
2641 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
2642 "such a cert type isn't supported: %d\n",
2643 (char)iph1
->cr_p
->type
);
2651 * check to need CR payload.
2658 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
2659 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
2660 #ifdef ENABLE_HYBRID
2661 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
2662 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
2673 * see seciton 5. Exchanges in RFC 2409
2674 * psk: SKEYID = prf(pre-shared-key, Ni_b | Nr_b)
2675 * sig: SKEYID = prf(Ni_b | Nr_b, g^ir)
2676 * enc: SKEYID = prf(H(Ni_b | Nr_b), CKY-I | CKY-R)
2680 struct ph1handle
*iph1
;
2682 vchar_t
*buf
= NULL
, *bp
;
2688 switch(iph1
->approval
->authmethod
) {
2689 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
2691 if (iph1
->rmconf
->shared_secret
) {
2693 switch (iph1
->rmconf
->secrettype
) {
2694 case SECRETTYPE_KEY
:
2695 /* in psk file - use KEY from remote configuration to locate it */
2696 iph1
->authstr
= getpsk(iph1
->rmconf
->shared_secret
->v
, iph1
->rmconf
->shared_secret
->l
-1);
2698 case SECRETTYPE_KEYCHAIN
:
2699 /* in the system keychain */
2700 iph1
->authstr
= getpskfromkeychain(iph1
->rmconf
->shared_secret
->v
, iph1
->etype
, iph1
->rmconf
->secrettype
, NULL
);
2702 case SECRETTYPE_KEYCHAIN_BY_ID
:
2703 /* in the system keychain - use peer id */
2704 iph1
->authstr
= getpskfromkeychain(iph1
->rmconf
->shared_secret
->v
, iph1
->etype
, iph1
->rmconf
->secrettype
, iph1
->id_p
);
2706 case SECRETTYPE_USE
:
2707 /* in the remote configuration */
2709 iph1
->authstr
= vdup(iph1
->rmconf
->shared_secret
);
2715 if (iph1
->etype
!= ISAKMP_ETYPE_IDENT
) {
2716 iph1
->authstr
= getpskbyname(iph1
->id_p
);
2717 if (iph1
->authstr
== NULL
) {
2718 if (iph1
->rmconf
->verify_identifier
) {
2719 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
2720 "couldn't find the pskey.\n");
2723 plog(LLV_NOTIFY
, LOCATION
, iph1
->remote
,
2724 "couldn't find the proper pskey, "
2725 "try to get one by the peer's address.\n");
2728 if (iph1
->authstr
== NULL
) {
2730 * If the exchange type is the main mode or if it's
2731 * failed to get the psk by ID, racoon try to get
2732 * the psk by remote IP address.
2733 * It may be nonsense.
2735 iph1
->authstr
= getpskbyaddr(iph1
->remote
);
2736 if (iph1
->authstr
== NULL
) {
2737 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
2738 "couldn't find the pskey for %s.\n",
2739 saddrwop2str(iph1
->remote
));
2743 plog(LLV_DEBUG
, LOCATION
, NULL
, "the psk found.\n");
2744 /* should be secret PSK */
2745 plog(LLV_DEBUG2
, LOCATION
, NULL
, "psk: ");
2746 plogdump(LLV_DEBUG2
, iph1
->authstr
->v
, iph1
->authstr
->l
);
2748 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
2751 plog(LLV_ERROR
, LOCATION
, NULL
,
2752 "failed to get skeyid buffer\n");
2757 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce
: iph1
->nonce_p
);
2758 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce 1: ");
2759 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
2760 memcpy(p
, bp
->v
, bp
->l
);
2763 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce_p
: iph1
->nonce
);
2764 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce 2: ");
2765 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
2766 memcpy(p
, bp
->v
, bp
->l
);
2769 iph1
->skeyid
= oakley_prf(iph1
->authstr
, buf
, iph1
);
2770 if (iph1
->skeyid
== NULL
)
2774 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
2775 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
2776 #ifdef ENABLE_HYBRID
2777 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
2778 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
2779 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
2780 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
2783 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
2785 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
2788 plog(LLV_ERROR
, LOCATION
, NULL
,
2789 "failed to get nonce buffer\n");
2794 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce
: iph1
->nonce_p
);
2795 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce1: ");
2796 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
2797 memcpy(p
, bp
->v
, bp
->l
);
2800 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce_p
: iph1
->nonce
);
2801 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce2: ");
2802 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
2803 memcpy(p
, bp
->v
, bp
->l
);
2806 iph1
->skeyid
= oakley_prf(buf
, iph1
->dhgxy
, iph1
);
2807 if (iph1
->skeyid
== NULL
)
2810 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
2811 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
2812 plog(LLV_WARNING
, LOCATION
, NULL
,
2813 "not supported authentication method %s\n",
2814 s_oakley_attr_method(iph1
->approval
->authmethod
));
2817 plog(LLV_ERROR
, LOCATION
, NULL
,
2818 "invalid authentication method %d\n",
2819 iph1
->approval
->authmethod
);
2823 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID computed:\n");
2824 plogdump(LLV_DEBUG
, iph1
->skeyid
->v
, iph1
->skeyid
->l
);
2835 * compute SKEYID_[dae]
2836 * see seciton 5. Exchanges in RFC 2409
2837 * SKEYID_d = prf(SKEYID, g^ir | CKY-I | CKY-R | 0)
2838 * SKEYID_a = prf(SKEYID, SKEYID_d | g^ir | CKY-I | CKY-R | 1)
2839 * SKEYID_e = prf(SKEYID, SKEYID_a | g^ir | CKY-I | CKY-R | 2)
2842 oakley_skeyid_dae(iph1
)
2843 struct ph1handle
*iph1
;
2845 vchar_t
*buf
= NULL
;
2850 if (iph1
->skeyid
== NULL
) {
2851 plog(LLV_ERROR
, LOCATION
, NULL
, "no SKEYID found.\n");
2856 /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
2857 len
= iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
2860 plog(LLV_ERROR
, LOCATION
, NULL
,
2861 "failed to get skeyid buffer\n");
2866 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
2867 p
+= iph1
->dhgxy
->l
;
2868 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
2869 p
+= sizeof(cookie_t
);
2870 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
2871 p
+= sizeof(cookie_t
);
2873 iph1
->skeyid_d
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
2874 if (iph1
->skeyid_d
== NULL
)
2880 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID_d computed:\n");
2881 plogdump(LLV_DEBUG
, iph1
->skeyid_d
->v
, iph1
->skeyid
->l
);
2884 /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
2885 len
= iph1
->skeyid_d
->l
+ iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
2888 plog(LLV_ERROR
, LOCATION
, NULL
,
2889 "failed to get skeyid buffer\n");
2893 memcpy(p
, iph1
->skeyid_d
->v
, iph1
->skeyid_d
->l
);
2894 p
+= iph1
->skeyid_d
->l
;
2895 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
2896 p
+= iph1
->dhgxy
->l
;
2897 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
2898 p
+= sizeof(cookie_t
);
2899 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
2900 p
+= sizeof(cookie_t
);
2902 iph1
->skeyid_a
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
2903 if (iph1
->skeyid_a
== NULL
)
2909 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID_a computed:\n");
2910 plogdump(LLV_DEBUG
, iph1
->skeyid_a
->v
, iph1
->skeyid_a
->l
);
2913 /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
2914 len
= iph1
->skeyid_a
->l
+ iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
2917 plog(LLV_ERROR
, LOCATION
, NULL
,
2918 "failed to get skeyid buffer\n");
2922 memcpy(p
, iph1
->skeyid_a
->v
, iph1
->skeyid_a
->l
);
2923 p
+= iph1
->skeyid_a
->l
;
2924 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
2925 p
+= iph1
->dhgxy
->l
;
2926 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
2927 p
+= sizeof(cookie_t
);
2928 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
2929 p
+= sizeof(cookie_t
);
2931 iph1
->skeyid_e
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
2932 if (iph1
->skeyid_e
== NULL
)
2938 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID_e computed:\n");
2939 plogdump(LLV_DEBUG
, iph1
->skeyid_e
->v
, iph1
->skeyid_e
->l
);
2950 * compute final encryption key.
2954 oakley_compute_enckey(iph1
)
2955 struct ph1handle
*iph1
;
2957 u_int keylen
, prflen
;
2961 keylen
= alg_oakley_encdef_keylen(iph1
->approval
->enctype
,
2962 iph1
->approval
->encklen
);
2964 plog(LLV_ERROR
, LOCATION
, NULL
,
2965 "invalid encryption algoritym %d, "
2966 "or invalid key length %d.\n",
2967 iph1
->approval
->enctype
,
2968 iph1
->approval
->encklen
);
2971 iph1
->key
= vmalloc(keylen
>> 3);
2972 if (iph1
->key
== NULL
) {
2973 plog(LLV_ERROR
, LOCATION
, NULL
,
2974 "failed to get key buffer\n");
2978 /* set prf length */
2979 prflen
= alg_oakley_hashdef_hashlen(iph1
->approval
->hashtype
);
2981 plog(LLV_ERROR
, LOCATION
, NULL
,
2982 "invalid hash type %d.\n", iph1
->approval
->hashtype
);
2986 /* see isakmp-oakley-08 5.3. */
2987 if (iph1
->key
->l
<= iph1
->skeyid_e
->l
) {
2989 * if length(Ka) <= length(SKEYID_e)
2990 * Ka = first length(K) bit of SKEYID_e
2992 memcpy(iph1
->key
->v
, iph1
->skeyid_e
->v
, iph1
->key
->l
);
2994 vchar_t
*buf
= NULL
, *res
= NULL
;
3003 * K1 = prf(SKEYID_e, 0)
3004 * K2 = prf(SKEYID_e, K1)
3005 * K3 = prf(SKEYID_e, K2)
3007 plog(LLV_DEBUG
, LOCATION
, NULL
,
3008 "len(SKEYID_e) < len(Ka) (%zu < %zu), "
3009 "generating long key (Ka = K1 | K2 | ...)\n",
3010 iph1
->skeyid_e
->l
, iph1
->key
->l
);
3012 if ((buf
= vmalloc(prflen
>> 3)) == 0) {
3013 plog(LLV_ERROR
, LOCATION
, NULL
,
3014 "failed to get key buffer\n");
3017 p
= (u_char
*)iph1
->key
->v
;
3018 ep
= p
+ iph1
->key
->l
;
3022 if (p
== (u_char
*)iph1
->key
->v
) {
3023 /* just for computing K1 */
3027 res
= oakley_prf(iph1
->skeyid_e
, buf
, iph1
);
3032 plog(LLV_DEBUG
, LOCATION
, NULL
,
3033 "compute intermediate encryption key K%d\n",
3035 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3036 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
3038 cplen
= (res
->l
< ep
- p
) ? res
->l
: ep
- p
;
3039 memcpy(p
, res
->v
, cplen
);
3042 buf
->l
= prflen
>> 3; /* to cancel K1 speciality */
3043 if (res
->l
!= buf
->l
) {
3044 plog(LLV_ERROR
, LOCATION
, NULL
,
3045 "internal error: res->l=%zu buf->l=%zu\n",
3051 memcpy(buf
->v
, res
->v
, res
->l
);
3060 * don't check any weak key or not.
3061 * draft-ietf-ipsec-ike-01.txt Appendix B.
3062 * draft-ietf-ipsec-ciph-aes-cbc-00.txt Section 2.3.
3066 if (iph1
->approval
->enctype
> ARRAYLEN(oakley_encdef
)
3067 || oakley_encdef
[iph1
->approval
->enctype
].weakkey
== NULL
) {
3068 plog(LLV_ERROR
, LOCATION
, NULL
,
3069 "encryption algoritym %d isn't supported.\n",
3070 iph1
->approval
->enctype
);
3073 if ((oakley_encdef
[iph1
->approval
->enctype
].weakkey
)(iph1
->key
)) {
3074 plog(LLV_ERROR
, LOCATION
, NULL
,
3075 "weakkey was generated.\n");
3080 plog(LLV_DEBUG
, LOCATION
, NULL
, "final encryption key computed:\n");
3081 plogdump(LLV_DEBUG
, iph1
->key
->v
, iph1
->key
->l
);
3089 /* allocated new buffer for CERT */
3095 new = racoon_calloc(1, sizeof(*new));
3097 plog(LLV_ERROR
, LOCATION
, NULL
,
3098 "failed to get cert's buffer\n");
3107 /* delete buffer for CERT */
3109 oakley_delcert(cert
)
3120 * compute IV and set to ph1handle
3121 * IV = hash(g^xi | g^xr)
3122 * see 4.1 Phase 1 state in draft-ietf-ipsec-ike.
3126 struct ph1handle
*iph1
;
3128 struct isakmp_ivm
*newivm
= NULL
;
3129 vchar_t
*buf
= NULL
, *bp
;
3134 len
= iph1
->dhpub
->l
+ iph1
->dhpub_p
->l
;
3137 plog(LLV_ERROR
, LOCATION
, NULL
,
3138 "failed to get iv buffer\n");
3144 bp
= (iph1
->side
== INITIATOR
? iph1
->dhpub
: iph1
->dhpub_p
);
3145 memcpy(p
, bp
->v
, bp
->l
);
3148 bp
= (iph1
->side
== INITIATOR
? iph1
->dhpub_p
: iph1
->dhpub
);
3149 memcpy(p
, bp
->v
, bp
->l
);
3153 newivm
= racoon_calloc(1, sizeof(struct isakmp_ivm
));
3154 if (newivm
== NULL
) {
3155 plog(LLV_ERROR
, LOCATION
, NULL
,
3156 "failed to get iv buffer\n");
3162 newivm
->iv
= oakley_hash(buf
, iph1
);
3163 if (newivm
->iv
== NULL
) {
3165 oakley_delivm(newivm
);
3169 /* adjust length of iv */
3170 newivm
->iv
->l
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3171 if (newivm
->iv
->l
== -1) {
3172 plog(LLV_ERROR
, LOCATION
, NULL
,
3173 "invalid encryption algoriym %d.\n",
3174 iph1
->approval
->enctype
);
3176 oakley_delivm(newivm
);
3180 /* create buffer to save iv */
3181 if ((newivm
->ive
= vdup(newivm
->iv
)) == NULL
) {
3182 plog(LLV_ERROR
, LOCATION
, NULL
,
3183 "vdup (%s)\n", strerror(errno
));
3185 oakley_delivm(newivm
);
3191 plog(LLV_DEBUG
, LOCATION
, NULL
, "IV computed:\n");
3192 plogdump(LLV_DEBUG
, newivm
->iv
->v
, newivm
->iv
->l
);
3200 * compute IV for the payload after phase 1.
3201 * It's not limited for phase 2.
3202 * if pahse 1 was encrypted.
3203 * IV = hash(last CBC block of Phase 1 | M-ID)
3204 * if phase 1 was not encrypted.
3205 * IV = hash(phase 1 IV | M-ID)
3206 * see 4.2 Phase 2 state in draft-ietf-ipsec-ike.
3209 oakley_newiv2(iph1
, msgid
)
3210 struct ph1handle
*iph1
;
3213 struct isakmp_ivm
*newivm
= NULL
;
3214 vchar_t
*buf
= NULL
;
3220 len
= iph1
->ivm
->iv
->l
+ sizeof(msgid_t
);
3223 plog(LLV_ERROR
, LOCATION
, NULL
,
3224 "failed to get iv buffer\n");
3230 memcpy(p
, iph1
->ivm
->iv
->v
, iph1
->ivm
->iv
->l
);
3231 p
+= iph1
->ivm
->iv
->l
;
3233 memcpy(p
, &msgid
, sizeof(msgid
));
3235 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute IV for phase2\n");
3236 plog(LLV_DEBUG
, LOCATION
, NULL
, "phase1 last IV:\n");
3237 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3240 newivm
= racoon_calloc(1, sizeof(struct isakmp_ivm
));
3241 if (newivm
== NULL
) {
3242 plog(LLV_ERROR
, LOCATION
, NULL
,
3243 "failed to get iv buffer\n");
3248 if ((newivm
->iv
= oakley_hash(buf
, iph1
)) == NULL
)
3251 /* adjust length of iv */
3252 newivm
->iv
->l
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3253 if (newivm
->iv
->l
== -1) {
3254 plog(LLV_ERROR
, LOCATION
, NULL
,
3255 "invalid encryption algoriym %d.\n",
3256 iph1
->approval
->enctype
);
3260 /* create buffer to save new iv */
3261 if ((newivm
->ive
= vdup(newivm
->iv
)) == NULL
) {
3262 plog(LLV_ERROR
, LOCATION
, NULL
, "vdup (%s)\n", strerror(errno
));
3268 plog(LLV_DEBUG
, LOCATION
, NULL
, "phase2 IV computed:\n");
3269 plogdump(LLV_DEBUG
, newivm
->iv
->v
, newivm
->iv
->l
);
3272 if (error
&& newivm
!= NULL
){
3273 oakley_delivm(newivm
);
3283 struct isakmp_ivm
*ivm
;
3288 if (ivm
->iv
!= NULL
)
3290 if (ivm
->ive
!= NULL
)
3299 * save new iv and old iv.
3302 oakley_do_decrypt(iph1
, msg
, ivdp
, ivep
)
3303 struct ph1handle
*iph1
;
3304 vchar_t
*msg
, *ivdp
, *ivep
;
3306 vchar_t
*buf
= NULL
, *new = NULL
;
3313 plog(LLV_DEBUG
, LOCATION
, NULL
, "begin decryption.\n");
3315 blen
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3317 plog(LLV_ERROR
, LOCATION
, NULL
,
3318 "invalid encryption algoriym %d.\n",
3319 iph1
->approval
->enctype
);
3323 /* save IV for next, but not sync. */
3324 memset(ivep
->v
, 0, ivep
->l
);
3325 memcpy(ivep
->v
, (caddr_t
)&msg
->v
[msg
->l
- blen
], blen
);
3327 plog(LLV_DEBUG
, LOCATION
, NULL
,
3328 "IV was saved for next processing:\n");
3329 plogdump(LLV_DEBUG
, ivep
->v
, ivep
->l
);
3331 pl
= msg
->v
+ sizeof(struct isakmp
);
3333 len
= msg
->l
- sizeof(struct isakmp
);
3338 plog(LLV_ERROR
, LOCATION
, NULL
,
3339 "failed to get buffer to decrypt.\n");
3342 memcpy(buf
->v
, pl
, len
);
3345 new = alg_oakley_encdef_decrypt(iph1
->approval
->enctype
,
3346 buf
, iph1
->key
, ivdp
);
3348 plog(LLV_ERROR
, LOCATION
, NULL
,
3349 "decryption %d failed.\n", iph1
->approval
->enctype
);
3352 plog(LLV_DEBUG
, LOCATION
, NULL
, "with key:\n");
3353 plogdump(LLV_DEBUG
, iph1
->key
->v
, iph1
->key
->l
);
3360 plog(LLV_DEBUG
, LOCATION
, NULL
, "decrypted payload by IV:\n");
3361 plogdump(LLV_DEBUG
, ivdp
->v
, ivdp
->l
);
3363 plog(LLV_DEBUG
, LOCATION
, NULL
,
3364 "decrypted payload, but not trimed.\n");
3365 plogdump(LLV_DEBUG
, new->v
, new->l
);
3367 /* get padding length */
3368 if (lcconf
->pad_excltail
)
3369 padlen
= new->v
[new->l
- 1] + 1;
3371 padlen
= new->v
[new->l
- 1];
3372 plog(LLV_DEBUG
, LOCATION
, NULL
, "padding len=%u\n", padlen
);
3375 if (lcconf
->pad_strict
) {
3376 if (padlen
> new->l
) {
3377 plog(LLV_ERROR
, LOCATION
, NULL
,
3378 "invalid padding len=%u, buflen=%zu.\n",
3380 plogdump(LLV_ERROR
, new->v
, new->l
);
3384 plog(LLV_DEBUG
, LOCATION
, NULL
, "trimmed padding\n");
3386 plog(LLV_DEBUG
, LOCATION
, NULL
, "skip to trim padding.\n");
3389 /* create new buffer */
3390 len
= sizeof(struct isakmp
) + new->l
;
3393 plog(LLV_ERROR
, LOCATION
, NULL
,
3394 "failed to get buffer to decrypt.\n");
3397 memcpy(buf
->v
, msg
->v
, sizeof(struct isakmp
));
3398 memcpy(buf
->v
+ sizeof(struct isakmp
), new->v
, new->l
);
3399 ((struct isakmp
*)buf
->v
)->len
= htonl(buf
->l
);
3401 plog(LLV_DEBUG
, LOCATION
, NULL
, "decrypted.\n");
3402 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3404 #ifdef HAVE_PRINT_ISAKMP_C
3405 isakmp_printpacket(buf
, iph1
->remote
, iph1
->local
, 1);
3411 if (error
&& buf
!= NULL
) {
3425 oakley_do_encrypt(iph1
, msg
, ivep
, ivp
)
3426 struct ph1handle
*iph1
;
3427 vchar_t
*msg
, *ivep
, *ivp
;
3429 vchar_t
*buf
= 0, *new = 0;
3436 plog(LLV_DEBUG
, LOCATION
, NULL
, "begin encryption.\n");
3438 /* set cbc block length */
3439 blen
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3441 plog(LLV_ERROR
, LOCATION
, NULL
,
3442 "invalid encryption algoriym %d.\n",
3443 iph1
->approval
->enctype
);
3447 pl
= msg
->v
+ sizeof(struct isakmp
);
3448 len
= msg
->l
- sizeof(struct isakmp
);
3451 padlen
= oakley_padlen(len
, blen
);
3452 plog(LLV_DEBUG
, LOCATION
, NULL
, "pad length = %u\n", padlen
);
3455 buf
= vmalloc(len
+ padlen
);
3457 plog(LLV_ERROR
, LOCATION
, NULL
,
3458 "failed to get buffer to encrypt.\n");
3463 char *p
= &buf
->v
[len
];
3464 if (lcconf
->pad_random
) {
3465 for (i
= 0; i
< padlen
; i
++)
3466 *p
++ = eay_random() & 0xff;
3469 memcpy(buf
->v
, pl
, len
);
3471 /* make pad into tail */
3472 if (lcconf
->pad_excltail
)
3473 buf
->v
[len
+ padlen
- 1] = padlen
- 1;
3475 buf
->v
[len
+ padlen
- 1] = padlen
;
3477 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3480 new = alg_oakley_encdef_encrypt(iph1
->approval
->enctype
,
3481 buf
, iph1
->key
, ivep
);
3483 plog(LLV_ERROR
, LOCATION
, NULL
,
3484 "encryption %d failed.\n", iph1
->approval
->enctype
);
3487 plog(LLV_DEBUG
, LOCATION
, NULL
, "with key:\n");
3488 plogdump(LLV_DEBUG
, iph1
->key
->v
, iph1
->key
->l
);
3495 plog(LLV_DEBUG
, LOCATION
, NULL
, "encrypted payload by IV:\n");
3496 plogdump(LLV_DEBUG
, ivep
->v
, ivep
->l
);
3498 /* save IV for next */
3499 memset(ivp
->v
, 0, ivp
->l
);
3500 memcpy(ivp
->v
, (caddr_t
)&new->v
[new->l
- blen
], blen
);
3502 plog(LLV_DEBUG
, LOCATION
, NULL
, "save IV for next:\n");
3503 plogdump(LLV_DEBUG
, ivp
->v
, ivp
->l
);
3505 /* create new buffer */
3506 len
= sizeof(struct isakmp
) + new->l
;
3509 plog(LLV_ERROR
, LOCATION
, NULL
,
3510 "failed to get buffer to encrypt.\n");
3513 memcpy(buf
->v
, msg
->v
, sizeof(struct isakmp
));
3514 memcpy(buf
->v
+ sizeof(struct isakmp
), new->v
, new->l
);
3515 ((struct isakmp
*)buf
->v
)->len
= htonl(buf
->l
);
3519 plog(LLV_DEBUG
, LOCATION
, NULL
, "encrypted.\n");
3522 if (error
&& buf
!= NULL
) {
3532 /* culculate padding length */
3534 oakley_padlen(len
, base
)
3539 padlen
= base
- len
% base
;
3541 if (lcconf
->pad_randomlen
)
3542 padlen
+= ((eay_random() % (lcconf
->pad_maxsize
+ 1) + 1) *
3549 /* -----------------------------------------------------------------------------
3550 The base-64 encoding packs three 8-bit bytes into four 7-bit ASCII
3551 characters. If the number of bytes in the original data isn't divisable
3552 by three, "=" characters are used to pad the encoded data. The complete
3553 set of characters used in base-64 are:
3561 ----------------------------------------------------------------------------- */
3562 static const signed char base64_DecodeTable
[128] = {
3563 /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
3564 /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
3565 /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
3566 /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
3567 /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
3568 /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
3569 /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
3570 /* '8' */ 60, 61, -1, -1, -1, 0, -1, -1,
3571 /* '@' */ -1, 0, 1, 2, 3, 4, 5, 6,
3572 /* 'H' */ 7, 8, 9, 10, 11, 12, 13, 14,
3573 /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
3574 /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
3575 /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
3576 /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
3577 /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
3578 /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
3581 static int base64toCFData(vchar_t
*textin
, CFDataRef
*dataRef
)
3589 uint8_t *textcur
= textin
->v
;
3590 int len
= textin
->l
;
3593 tmpbuf
= malloc(len
); // len of result will be less than encoded len
3594 if (tmpbuf
== NULL
) {
3595 yyerror("memory error - could not allocate buffer for certificate reference conversion from base-64.");
3599 for (i
= 0; i
< len
; i
++) {
3603 else if (!isspace(c
))
3605 if (base64_DecodeTable
[c
] < 0)
3609 acc
+= base64_DecodeTable
[c
];
3610 if (0 == (cntr
& 0x3)) {
3611 tmpbuf
[tmpbufpos
++] = (acc
>> 16) & 0xff;
3613 tmpbuf
[tmpbufpos
++] = (acc
>> 8) & 0xff;
3615 tmpbuf
[tmpbufpos
++] = acc
& 0xff;
3618 *dataRef
= CFDataCreate(NULL
, tmpbuf
, tmpbufpos
);