1 /* $NetBSD: oakley.c,v 1.9.6.2 2007/04/04 13:08:28 vanhu Exp $ */
3 /* Id: oakley.c,v 1.32 2006/05/26 12:19:46 manubsd Exp */
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h> /* XXX for subjectaltname */
39 #include <netinet/in.h> /* XXX for subjectaltname */
42 #include <openssl/pkcs7.h>
43 #include <openssl/x509.h>
50 #include <arpa/inet.h>
51 #include <TargetConditionals.h>
53 #if TIME_WITH_SYS_TIME
54 # include <sys/time.h>
58 # include <sys/time.h>
74 #include "isakmp_var.h"
77 #include "isakmp_xauth.h"
78 #include "isakmp_cfg.h"
83 #include "localconf.h"
86 #include "ipsec_doi.h"
87 #include "algorithm.h"
91 #include "crypto_openssl.h"
92 #include "crypto_cssm.h"
100 #include <CoreFoundation/CoreFoundation.h>
101 #include "remoteconf.h"
102 #include "vpn_control.h"
103 #if TARGET_OS_EMBEDDED
104 #include <Security/SecCertificate.h>
105 #include <Security/SecCertificatePriv.h>
110 #include "vpn_control_var.h"
112 #define OUTBOUND_SA 0
115 #define CERT_CHECKID_FROM_PEER 0
116 #define CERT_CHECKID_FROM_RMCONFIG 1
119 #define INITDHVAL(a, s, d, t) \
122 buf.v = str2val((s), 16, &buf.l); \
123 memset(&a, 0, sizeof(struct dhgroup)); \
125 a.prime = vdup(&buf); \
128 racoon_free(buf.v); \
130 #else /* HAVE_OPENSSL */
131 #define INITDHVAL(a, s, d, t) \
134 buf.v = str2val((s), 16, &buf.l); \
135 memset(&a, 0, sizeof(struct dhgroup)); \
138 a.prime = vdup(&buf); \
141 racoon_free(buf.v); \
143 #endif /* HAVE_OPENSSL */
145 struct dhgroup dh_modp768
;
146 struct dhgroup dh_modp1024
;
147 struct dhgroup dh_modp1536
;
148 struct dhgroup dh_modp2048
;
149 struct dhgroup dh_modp3072
;
150 struct dhgroup dh_modp4096
;
151 struct dhgroup dh_modp6144
;
152 struct dhgroup dh_modp8192
;
155 static int oakley_check_dh_pub
__P((vchar_t
*, vchar_t
**));
156 static int oakley_compute_keymat_x
__P((struct ph2handle
*, int, int));
157 static int get_cert_fromlocal
__P((struct ph1handle
*, int));
158 static int oakley_check_certid
__P((struct ph1handle
*iph1
, int));
159 static int oakley_check_certid_1
__P((vchar_t
*, int, int, void*, cert_status_t
*certStatus
));
160 static int check_typeofcertname
__P((int, int));
161 static cert_t
*save_certbuf
__P((struct isakmp_gen
*));
163 static cert_t
*save_certx509
__P((X509
*));
165 static int oakley_padlen
__P((int, int));
167 static int base64toCFData(vchar_t
*, CFDataRef
*);
168 static cert_t
*oakley_appendcert_to_certchain(cert_t
*, cert_t
*);
170 static void oakley_cert_prettyprint (vchar_t
*cert
)
174 p
= eay_get_x509text(cert
);
176 /* add new cert dump code here */
178 plog(LLV_DEBUG
, LOCATION
, NULL
, "%s", p
? p
: "\n");
183 oakley_get_defaultlifetime()
185 return OAKLEY_ATTR_SA_LD_SEC_DEFAULT
;
192 INITDHVAL(dh_modp768
, OAKLEY_PRIME_MODP768
,
193 OAKLEY_ATTR_GRP_DESC_MODP768
, OAKLEY_ATTR_GRP_TYPE_MODP
);
194 INITDHVAL(dh_modp1024
, OAKLEY_PRIME_MODP1024
,
195 OAKLEY_ATTR_GRP_DESC_MODP1024
, OAKLEY_ATTR_GRP_TYPE_MODP
);
196 INITDHVAL(dh_modp1536
, OAKLEY_PRIME_MODP1536
,
197 OAKLEY_ATTR_GRP_DESC_MODP1536
, OAKLEY_ATTR_GRP_TYPE_MODP
);
198 INITDHVAL(dh_modp2048
, OAKLEY_PRIME_MODP2048
,
199 OAKLEY_ATTR_GRP_DESC_MODP2048
, OAKLEY_ATTR_GRP_TYPE_MODP
);
200 INITDHVAL(dh_modp3072
, OAKLEY_PRIME_MODP3072
,
201 OAKLEY_ATTR_GRP_DESC_MODP3072
, OAKLEY_ATTR_GRP_TYPE_MODP
);
202 INITDHVAL(dh_modp4096
, OAKLEY_PRIME_MODP4096
,
203 OAKLEY_ATTR_GRP_DESC_MODP4096
, OAKLEY_ATTR_GRP_TYPE_MODP
);
204 INITDHVAL(dh_modp6144
, OAKLEY_PRIME_MODP6144
,
205 OAKLEY_ATTR_GRP_DESC_MODP6144
, OAKLEY_ATTR_GRP_TYPE_MODP
);
206 INITDHVAL(dh_modp8192
, OAKLEY_PRIME_MODP8192
,
207 OAKLEY_ATTR_GRP_DESC_MODP8192
, OAKLEY_ATTR_GRP_TYPE_MODP
);
213 oakley_dhgrp_free(dhgrp
)
214 struct dhgroup
*dhgrp
;
219 vfree(dhgrp
->curve_a
);
221 vfree(dhgrp
->curve_b
);
229 * The length of the Diffie-Hellman public value MUST be equal to the
230 * length of the prime modulus over which the exponentiation was
231 * performed, prepending zero bits to the value if necessary.
234 oakley_check_dh_pub(prime
, pub0
)
235 vchar_t
*prime
, **pub0
;
238 vchar_t
*pub
= *pub0
;
240 if (prime
->l
== pub
->l
)
243 if (prime
->l
< pub
->l
) {
244 /* what should i do ? */
245 plog(LLV_ERROR
, LOCATION
, NULL
,
246 "invalid public information was generated.\n");
250 /* prime->l > pub->l */
251 tmp
= vmalloc(prime
->l
);
253 plog(LLV_ERROR
, LOCATION
, NULL
,
254 "failed to get DH buffer.\n");
257 memcpy(tmp
->v
+ prime
->l
- pub
->l
, pub
->v
, pub
->l
);
266 * compute sharing secret of DH
267 * IN: *dh, *pub, *priv, *pub_p
272 oakley_dh_compute(const struct dhgroup
*dh
, vchar_t
*pub
, vchar_t
*priv
, vchar_t
*pub_p
, vchar_t
**gxy
)
275 struct timeval start
, end
;
277 if ((*gxy
= vmalloc(dh
->prime
->l
)) == NULL
) {
278 plog(LLV_ERROR
, LOCATION
, NULL
,
279 "failed to get DH buffer.\n");
284 gettimeofday(&start
, NULL
);
287 case OAKLEY_ATTR_GRP_TYPE_MODP
:
288 if (eay_dh_compute(dh
->prime
, dh
->gen1
, pub
, priv
, pub_p
, gxy
) < 0) {
289 plog(LLV_ERROR
, LOCATION
, NULL
,
290 "failed to compute dh value.\n");
294 case OAKLEY_ATTR_GRP_TYPE_ECP
:
295 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
296 plog(LLV_ERROR
, LOCATION
, NULL
,
297 "dh type %d isn't supported.\n", dh
->type
);
300 plog(LLV_ERROR
, LOCATION
, NULL
,
301 "invalid dh type %d.\n", dh
->type
);
306 gettimeofday(&end
, NULL
);
307 syslog(LOG_NOTICE
, "%s(%s%d): %8.6f", __func__
,
308 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
309 timedelta(&start
, &end
));
312 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's shared.\n");
313 plogdump(LLV_DEBUG
, (*gxy
)->v
, (*gxy
)->l
);
319 oakley_dh_compute(const struct dhgroup
*dh
, vchar_t
*pub_p
, size_t publicKeySize
, vchar_t
**gxy
, SecDHContext dhC
)
322 vchar_t
*computed_key
= NULL
;
323 size_t computed_keylen
;
327 struct timeval start
, end
;
328 gettimeofday(&start
, NULL
);
331 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH result.\n");
333 maxKeyLen
= SecDHGetMaxKeyLength(dhC
);
334 computed_key
= vmalloc(maxKeyLen
);
335 if (computed_key
== NULL
) {
336 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error.\n");
339 computed_keylen
= computed_key
->l
;
340 if (SecDHComputeKey(dhC
, pub_p
->v
+ (maxKeyLen
- publicKeySize
), publicKeySize
,
341 computed_key
->v
, &computed_keylen
)) {
342 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to compute dh value.\n");
347 gettimeofday(&end
, NULL
);
348 syslog(LOG_NOTICE
, "%s(%s%d): %8.6f", __func__
,
349 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
350 timedelta(&start
, &end
));
353 *gxy
= vmalloc(maxKeyLen
);
355 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error.\n");
358 memcpy((*gxy
)->v
+ (maxKeyLen
- computed_keylen
), computed_key
->v
, computed_keylen
);
359 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's shared.\n");
360 plogdump(LLV_DEBUG
, (*gxy
)->v
, (*gxy
)->l
);
375 * generate values of DH
381 oakley_dh_generate(dh
, pub
, priv
)
382 const struct dhgroup
*dh
;
383 vchar_t
**pub
, **priv
;
386 struct timeval start
, end
;
387 gettimeofday(&start
, NULL
);
390 case OAKLEY_ATTR_GRP_TYPE_MODP
:
391 if (eay_dh_generate(dh
->prime
, dh
->gen1
, dh
->gen2
, pub
, priv
) < 0) {
392 plog(LLV_ERROR
, LOCATION
, NULL
,
393 "failed to compute dh value.\n");
398 case OAKLEY_ATTR_GRP_TYPE_ECP
:
399 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
400 plog(LLV_ERROR
, LOCATION
, NULL
,
401 "dh type %d isn't supported.\n", dh
->type
);
404 plog(LLV_ERROR
, LOCATION
, NULL
,
405 "invalid dh type %d.\n", dh
->type
);
410 gettimeofday(&end
, NULL
);
411 syslog(LOG_NOTICE
, "%s(%s%d): %8.6f", __func__
,
412 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
413 timedelta(&start
, &end
));
416 if (oakley_check_dh_pub(dh
->prime
, pub
) != 0)
419 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's private.\n");
420 plogdump(LLV_DEBUG
, (*priv
)->v
, (*priv
)->l
);
421 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's public.\n");
422 plogdump(LLV_DEBUG
, (*pub
)->v
, (*pub
)->l
);
428 oakley_dh_generate(const struct dhgroup
*dh
, vchar_t
**pub
, size_t *publicKeySize
, SecDHContext
*dhC
)
430 vchar_t
*public = NULL
;
434 struct timeval start
, end
;
435 gettimeofday(&start
, NULL
);
438 plog(LLV_DEBUG
, LOCATION
, NULL
, "generate DH key pair.\n");
441 case OAKLEY_ATTR_GRP_TYPE_MODP
:
442 #define SECDH_MODP_GENERATOR OAKLEY_ATTR_GRP_DESC_MODP1024
443 if (dh
->desc
!= OAKLEY_ATTR_GRP_DESC_MODP1024
&& dh
->desc
!= OAKLEY_ATTR_GRP_DESC_MODP1536
) {
444 plog(LLV_ERROR
, LOCATION
, NULL
, "Invalid dh group.\n");
447 if (SecDHCreate(SECDH_MODP_GENERATOR
, dh
->prime
->v
, dh
->prime
->l
, 0, NULL
, 0, dhC
)) {
448 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to create dh context.\n");
451 maxKeyLen
= SecDHGetMaxKeyLength(*dhC
);
452 public = vmalloc(maxKeyLen
);
453 *publicKeySize
= public->l
;
454 if (public == NULL
) {
455 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error.\n");
458 if (SecDHGenerateKeypair(*dhC
, public->v
, publicKeySize
)) {
459 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to generate dh key pair.\n");
462 plog(LLV_DEBUG
, LOCATION
, NULL
, "got DH key pair.\n");
464 *pub
= vmalloc(maxKeyLen
);
466 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error.\n");
469 /* copy and fill with leading zeros */
470 memcpy((*pub
)->v
+ (maxKeyLen
- *publicKeySize
), public->v
, *publicKeySize
);
473 case OAKLEY_ATTR_GRP_TYPE_ECP
:
474 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
475 plog(LLV_ERROR
, LOCATION
, NULL
,
476 "dh type %d isn't supported.\n", dh
->type
);
479 plog(LLV_ERROR
, LOCATION
, NULL
,
480 "invalid dh type %d.\n", dh
->type
);
485 gettimeofday(&end
, NULL
);
486 syslog(LOG_NOTICE
, "%s(%s%d): %8.6f", __func__
,
487 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
488 timedelta(&start
, &end
));
491 if (oakley_check_dh_pub(dh
->prime
, pub
) != 0) {
492 plog(LLV_DEBUG
, LOCATION
, NULL
, "failed DH public key size check.\n");
496 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's private.\n");
497 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's public.\n");
498 plogdump(LLV_DEBUG
, (*pub
)->v
, (*pub
)->l
);
513 * copy pre-defined dhgroup values.
516 oakley_setdhgroup(group
, dhgrp
)
518 struct dhgroup
**dhgrp
;
522 *dhgrp
= NULL
; /* just make sure, initialize */
524 g
= alg_oakley_dhdef_group(group
);
526 plog(LLV_ERROR
, LOCATION
, NULL
,
527 "invalid DH parameter grp=%d.\n", group
);
531 if (!g
->type
|| !g
->prime
|| !g
->gen1
) {
533 plog(LLV_ERROR
, LOCATION
, NULL
,
534 "unsupported DH parameters grp=%d.\n", group
);
538 *dhgrp
= racoon_calloc(1, sizeof(struct dhgroup
));
539 if (*dhgrp
== NULL
) {
540 plog(LLV_ERROR
, LOCATION
, NULL
,
541 "failed to get DH buffer.\n");
545 /* set defined dh vlaues */
546 memcpy(*dhgrp
, g
, sizeof(*g
));
547 (*dhgrp
)->prime
= vdup(g
->prime
);
555 * NOTE: we do not support prf with different input/output bitwidth,
556 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example) in
557 * oakley_compute_keymat(). If you add support for such prf function,
558 * modify oakley_compute_keymat() accordingly.
561 oakley_prf(key
, buf
, iph1
)
563 struct ph1handle
*iph1
;
568 if (iph1
->approval
== NULL
) {
570 * it's before negotiating hash algorithm.
571 * We use md5 as default.
573 type
= OAKLEY_ATTR_HASH_ALG_MD5
;
575 type
= iph1
->approval
->hashtype
;
577 res
= alg_oakley_hmacdef_one(type
, key
, buf
);
579 plog(LLV_ERROR
, LOCATION
, NULL
,
580 "invalid hmac algorithm %d.\n", type
);
591 oakley_hash(buf
, iph1
)
593 struct ph1handle
*iph1
;
598 if (iph1
->approval
== NULL
) {
600 * it's before negotiating hash algorithm.
601 * We use md5 as default.
603 type
= OAKLEY_ATTR_HASH_ALG_MD5
;
605 type
= iph1
->approval
->hashtype
;
607 res
= alg_oakley_hashdef_one(type
, buf
);
609 plog(LLV_ERROR
, LOCATION
, NULL
,
610 "invalid hash algorithm %d.\n", type
);
619 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
622 oakley_compute_keymat(iph2
, side
)
623 struct ph2handle
*iph2
;
628 /* compute sharing secret of DH when PFS */
629 if (iph2
->approval
->pfs_group
&& iph2
->dhpub_p
) {
631 if (oakley_dh_compute(iph2
->pfsgrp
, iph2
->dhpub
,
632 iph2
->dhpriv
, iph2
->dhpub_p
, &iph2
->dhgxy
) < 0)
634 if (oakley_dh_compute(iph2
->pfsgrp
, iph2
->dhpub_p
, iph2
->publicKeySize
, &iph2
->dhgxy
, iph2
->dhC
) < 0)
640 if (oakley_compute_keymat_x(iph2
, side
, INBOUND_SA
) < 0
641 || oakley_compute_keymat_x(iph2
, side
, OUTBOUND_SA
) < 0)
644 plog(LLV_DEBUG
, LOCATION
, NULL
, "KEYMAT computed.\n");
654 * KEYMAT = prf(SKEYID_d, protocol | SPI | Ni_b | Nr_b).
655 * If PFS is desired and KE payloads were exchanged,
656 * KEYMAT = prf(SKEYID_d, g(qm)^xy | protocol | SPI | Ni_b | Nr_b)
658 * NOTE: we do not support prf with different input/output bitwidth,
659 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example).
662 oakley_compute_keymat_x(iph2
, side
, sa_dir
)
663 struct ph2handle
*iph2
;
667 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
672 int dupkeymat
; /* generate K[1-dupkeymat] */
675 int encklen
, authklen
, l
;
677 pfs
= ((iph2
->approval
->pfs_group
&& iph2
->dhgxy
) ? 1 : 0);
679 len
= pfs
? iph2
->dhgxy
->l
: 0;
681 + sizeof(u_int32_t
) /* XXX SPI size */
686 plog(LLV_ERROR
, LOCATION
, NULL
,
687 "failed to get keymat buffer.\n");
691 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
696 memcpy(p
, iph2
->dhgxy
->v
, iph2
->dhgxy
->l
);
703 memcpy(p
, (sa_dir
== INBOUND_SA
? &pr
->spi
: &pr
->spi_p
),
705 p
+= sizeof(pr
->spi
);
707 bp
= (side
== INITIATOR
? iph2
->nonce
: iph2
->nonce_p
);
708 memcpy(p
, bp
->v
, bp
->l
);
711 bp
= (side
== INITIATOR
? iph2
->nonce_p
: iph2
->nonce
);
712 memcpy(p
, bp
->v
, bp
->l
);
716 plog(LLV_DEBUG
, LOCATION
, NULL
, "KEYMAT compute with\n");
717 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
720 res
= oakley_prf(iph2
->ph1
->skeyid_d
, buf
, iph2
->ph1
);
724 /* compute key length needed */
725 encklen
= authklen
= 0;
726 switch (pr
->proto_id
) {
727 case IPSECDOI_PROTO_IPSEC_ESP
:
728 for (tr
= pr
->head
; tr
; tr
= tr
->next
) {
729 l
= alg_ipsec_encdef_keylen(tr
->trns_id
,
734 l
= alg_ipsec_hmacdef_hashlen(tr
->authtype
);
739 case IPSECDOI_PROTO_IPSEC_AH
:
740 for (tr
= pr
->head
; tr
; tr
= tr
->next
) {
741 l
= alg_ipsec_hmacdef_hashlen(tr
->trns_id
);
749 plog(LLV_DEBUG
, LOCATION
, NULL
, "encklen=%d authklen=%d\n",
752 dupkeymat
= (encklen
+ authklen
) / 8 / res
->l
;
753 dupkeymat
+= 2; /* safety mergin */
756 plog(LLV_DEBUG
, LOCATION
, NULL
,
757 "generating %zu bits of key (dupkeymat=%d)\n",
758 dupkeymat
* 8 * res
->l
, dupkeymat
);
759 if (0 < --dupkeymat
) {
760 vchar_t
*prev
= res
; /* K(n-1) */
761 vchar_t
*seed
= NULL
; /* seed for Kn */
765 * generating long key (isakmp-oakley-08 5.5)
766 * KEYMAT = K1 | K2 | K3 | ...
768 * src = [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b
769 * K1 = prf(SKEYID_d, src)
770 * K2 = prf(SKEYID_d, K1 | src)
771 * K3 = prf(SKEYID_d, K2 | src)
772 * Kn = prf(SKEYID_d, K(n-1) | src)
774 plog(LLV_DEBUG
, LOCATION
, NULL
,
775 "generating K1...K%d for KEYMAT.\n",
778 seed
= vmalloc(prev
->l
+ buf
->l
);
780 plog(LLV_ERROR
, LOCATION
, NULL
,
781 "failed to get keymat buffer.\n");
782 if (prev
&& prev
!= res
)
787 while (dupkeymat
--) {
788 vchar_t
*this = NULL
; /* Kn */
791 memcpy(seed
->v
, prev
->v
, prev
->l
);
792 memcpy(seed
->v
+ prev
->l
, buf
->v
, buf
->l
);
793 this = oakley_prf(iph2
->ph1
->skeyid_d
, seed
,
796 plog(LLV_ERROR
, LOCATION
, NULL
,
797 "oakley_prf memory overflow\n");
798 if (prev
&& prev
!= res
)
805 update_prev
= (prev
&& prev
== res
) ? 1 : 0;
808 res
= vrealloc(res
, l
+ this->l
);
814 plog(LLV_ERROR
, LOCATION
, NULL
,
815 "failed to get keymat buffer.\n");
816 if (prev
&& prev
!= res
)
822 memcpy(res
->v
+ l
, this->v
, this->l
);
824 if (prev
&& prev
!= res
)
830 if (prev
&& prev
!= res
)
835 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
837 if (sa_dir
== INBOUND_SA
)
848 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
870 * compute HASH(3) prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
871 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
874 oakley_compute_hash3(iph1
, msgid
, body
)
875 struct ph1handle
*iph1
;
879 vchar_t
*buf
= 0, *res
= 0;
884 len
= 1 + sizeof(u_int32_t
) + body
->l
;
887 plog(LLV_DEBUG
, LOCATION
, NULL
,
888 "failed to get hash buffer\n");
894 memcpy(buf
->v
+ 1, (char *)&msgid
, sizeof(msgid
));
896 memcpy(buf
->v
+ 1 + sizeof(u_int32_t
), body
->v
, body
->l
);
898 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with: \n");
899 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
902 res
= oakley_prf(iph1
->skeyid_a
, buf
, iph1
);
908 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH computed:\n");
909 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
918 * compute HASH type of prf(SKEYID_a, M-ID | buffer)
920 * for quick mode HASH(1):
921 * prf(SKEYID_a, M-ID | SA | Ni [ | KE ] [ | IDci | IDcr ])
922 * for quick mode HASH(2):
923 * prf(SKEYID_a, M-ID | Ni_b | SA | Nr [ | KE ] [ | IDci | IDcr ])
924 * for Informational exchange:
925 * prf(SKEYID_a, M-ID | N/D)
928 oakley_compute_hash1(iph1
, msgid
, body
)
929 struct ph1handle
*iph1
;
933 vchar_t
*buf
= NULL
, *res
= NULL
;
939 len
= sizeof(u_int32_t
) + body
->l
;
942 plog(LLV_DEBUG
, LOCATION
, NULL
,
943 "failed to get hash buffer\n");
949 memcpy(buf
->v
, (char *)&msgid
, sizeof(msgid
));
950 p
+= sizeof(u_int32_t
);
952 memcpy(p
, body
->v
, body
->l
);
954 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with:\n");
955 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
958 res
= oakley_prf(iph1
->skeyid_a
, buf
, iph1
);
964 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH computed:\n");
965 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
974 * compute phase1 HASH
976 * I-digest = prf(SKEYID, g^i | g^r | CKY-I | CKY-R | SAi_b | ID_i1_b)
977 * R-digest = prf(SKEYID, g^r | g^i | CKY-R | CKY-I | SAi_b | ID_r1_b)
978 * for gssapi, also include all GSS tokens, and call gss_wrap on the result
981 oakley_ph1hash_common(iph1
, sw
)
982 struct ph1handle
*iph1
;
985 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
990 vchar_t
*gsstokens
= NULL
;
996 + sizeof(cookie_t
) * 2
998 + (sw
== GENERATE
? iph1
->id
->l
: iph1
->id_p
->l
);
1001 if (AUTHMETHOD(iph1
) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
) {
1002 if (iph1
->gi_i
!= NULL
&& iph1
->gi_r
!= NULL
) {
1003 bp
= (sw
== GENERATE
? iph1
->gi_i
: iph1
->gi_r
);
1007 gssapi_get_itokens(iph1
, &gsstokens
);
1009 gssapi_get_rtokens(iph1
, &gsstokens
);
1010 if (gsstokens
== NULL
)
1012 len
+= gsstokens
->l
;
1018 plog(LLV_ERROR
, LOCATION
, NULL
,
1019 "failed to get hash buffer\n");
1025 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
1026 memcpy(p
, bp
->v
, bp
->l
);
1029 bp
= (sw
== GENERATE
? iph1
->dhpub_p
: iph1
->dhpub
);
1030 memcpy(p
, bp
->v
, bp
->l
);
1033 if (iph1
->side
== INITIATOR
)
1034 bp2
= (sw
== GENERATE
?
1035 (char *)&iph1
->index
.i_ck
: (char *)&iph1
->index
.r_ck
);
1037 bp2
= (sw
== GENERATE
?
1038 (char *)&iph1
->index
.r_ck
: (char *)&iph1
->index
.i_ck
);
1039 bl
= sizeof(cookie_t
);
1043 if (iph1
->side
== INITIATOR
)
1044 bp2
= (sw
== GENERATE
?
1045 (char *)&iph1
->index
.r_ck
: (char *)&iph1
->index
.i_ck
);
1047 bp2
= (sw
== GENERATE
?
1048 (char *)&iph1
->index
.i_ck
: (char *)&iph1
->index
.r_ck
);
1049 bl
= sizeof(cookie_t
);
1054 memcpy(p
, bp
->v
, bp
->l
);
1057 bp
= (sw
== GENERATE
? iph1
->id
: iph1
->id_p
);
1058 memcpy(p
, bp
->v
, bp
->l
);
1062 if (AUTHMETHOD(iph1
) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
) {
1063 if (iph1
->gi_i
!= NULL
&& iph1
->gi_r
!= NULL
) {
1064 bp
= (sw
== GENERATE
? iph1
->gi_i
: iph1
->gi_r
);
1065 memcpy(p
, bp
->v
, bp
->l
);
1068 memcpy(p
, gsstokens
->v
, gsstokens
->l
);
1073 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with:\n");
1074 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
1077 res
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
1083 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH (%s) computed:\n",
1084 iph1
->side
== INITIATOR
? "init" : "resp");
1085 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
1091 if (gsstokens
!= NULL
)
1098 * compute HASH_I on base mode.
1100 * HASH_I = prf(SKEYID, g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
1102 * HASH_I = prf(hash(Ni_b | Nr_b), g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
1105 oakley_ph1hash_base_i(iph1
, sw
)
1106 struct ph1handle
*iph1
;
1109 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
1110 vchar_t
*hashkey
= NULL
;
1111 vchar_t
*hash
= NULL
; /* for signature mode */
1117 if (iph1
->etype
!= ISAKMP_ETYPE_BASE
) {
1118 plog(LLV_ERROR
, LOCATION
, NULL
,
1119 "invalid etype for this hash function\n");
1123 switch (AUTHMETHOD(iph1
)) {
1124 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
1125 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
1126 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
1127 #ifdef ENABLE_HYBRID
1128 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
1129 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
1130 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
1131 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
1132 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
1133 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
1135 if (iph1
->skeyid
== NULL
) {
1136 plog(LLV_ERROR
, LOCATION
, NULL
, "no SKEYID found.\n");
1139 hashkey
= iph1
->skeyid
;
1142 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
1143 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1145 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
1147 #ifdef ENABLE_HYBRID
1148 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1149 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1150 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1151 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
1152 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
1153 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1154 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
1155 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
1157 /* make hash for seed */
1158 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
1161 plog(LLV_ERROR
, LOCATION
, NULL
,
1162 "failed to get hash buffer\n");
1167 bp
= (sw
== GENERATE
? iph1
->nonce_p
: iph1
->nonce
);
1168 memcpy(p
, bp
->v
, bp
->l
);
1171 bp
= (sw
== GENERATE
? iph1
->nonce
: iph1
->nonce_p
);
1172 memcpy(p
, bp
->v
, bp
->l
);
1175 hash
= oakley_hash(buf
, iph1
);
1185 plog(LLV_ERROR
, LOCATION
, NULL
,
1186 "not supported authentication method %d\n",
1187 iph1
->approval
->authmethod
);
1192 len
= (sw
== GENERATE
? iph1
->dhpub
->l
: iph1
->dhpub_p
->l
)
1193 + sizeof(cookie_t
) * 2
1195 + (sw
== GENERATE
? iph1
->id
->l
: iph1
->id_p
->l
);
1198 plog(LLV_ERROR
, LOCATION
, NULL
,
1199 "failed to get hash buffer\n");
1204 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
1205 memcpy(p
, bp
->v
, bp
->l
);
1208 memcpy(p
, &iph1
->index
.i_ck
, sizeof(cookie_t
));
1209 p
+= sizeof(cookie_t
);
1210 memcpy(p
, &iph1
->index
.r_ck
, sizeof(cookie_t
));
1211 p
+= sizeof(cookie_t
);
1213 memcpy(p
, iph1
->sa
->v
, iph1
->sa
->l
);
1216 bp
= (sw
== GENERATE
? iph1
->id
: iph1
->id_p
);
1217 memcpy(p
, bp
->v
, bp
->l
);
1220 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH_I with:\n");
1221 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
1224 res
= oakley_prf(hashkey
, buf
, iph1
);
1230 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH_I computed:\n");
1231 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
1242 * compute HASH_R on base mode for signature method.
1244 * HASH_R = prf(hash(Ni_b | Nr_b), g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b)
1247 oakley_ph1hash_base_r(iph1
, sw
)
1248 struct ph1handle
*iph1
;
1251 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
1252 vchar_t
*hash
= NULL
;
1258 if (iph1
->etype
!= ISAKMP_ETYPE_BASE
) {
1259 plog(LLV_ERROR
, LOCATION
, NULL
,
1260 "invalid etype for this hash function\n");
1264 switch(AUTHMETHOD(iph1
)) {
1265 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
1266 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1267 #ifdef ENABLE_HYBRID
1268 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1269 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1270 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1271 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
1272 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
1273 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1274 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
1275 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
1276 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
1280 plog(LLV_ERROR
, LOCATION
, NULL
,
1281 "not supported authentication method %d\n",
1282 iph1
->approval
->authmethod
);
1287 /* make hash for seed */
1288 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
1291 plog(LLV_ERROR
, LOCATION
, NULL
,
1292 "failed to get hash buffer\n");
1297 bp
= (sw
== GENERATE
? iph1
->nonce_p
: iph1
->nonce
);
1298 memcpy(p
, bp
->v
, bp
->l
);
1301 bp
= (sw
== GENERATE
? iph1
->nonce
: iph1
->nonce_p
);
1302 memcpy(p
, bp
->v
, bp
->l
);
1305 hash
= oakley_hash(buf
, iph1
);
1311 /* make really hash */
1312 len
= (sw
== GENERATE
? iph1
->dhpub_p
->l
: iph1
->dhpub
->l
)
1313 + (sw
== GENERATE
? iph1
->dhpub
->l
: iph1
->dhpub_p
->l
)
1314 + sizeof(cookie_t
) * 2
1316 + (sw
== GENERATE
? iph1
->id_p
->l
: iph1
->id
->l
);
1319 plog(LLV_ERROR
, LOCATION
, NULL
,
1320 "failed to get hash buffer\n");
1326 bp
= (sw
== GENERATE
? iph1
->dhpub_p
: iph1
->dhpub
);
1327 memcpy(p
, bp
->v
, bp
->l
);
1330 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
1331 memcpy(p
, bp
->v
, bp
->l
);
1334 memcpy(p
, &iph1
->index
.i_ck
, sizeof(cookie_t
));
1335 p
+= sizeof(cookie_t
);
1336 memcpy(p
, &iph1
->index
.r_ck
, sizeof(cookie_t
));
1337 p
+= sizeof(cookie_t
);
1339 memcpy(p
, iph1
->sa
->v
, iph1
->sa
->l
);
1342 bp
= (sw
== GENERATE
? iph1
->id_p
: iph1
->id
);
1343 memcpy(p
, bp
->v
, bp
->l
);
1346 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH_R with:\n");
1347 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
1350 res
= oakley_prf(hash
, buf
, iph1
);
1356 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH_R computed:\n");
1357 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
1369 oakley_verify_userid(iph1
)
1370 struct ph1handle
*iph1
;
1374 int user_id_found
= 0;
1376 for (p
= iph1
->cert_p
; p
; p
= p
->chain
) {
1377 user_id
= eay_get_x509_common_name(&p
->cert
);
1380 // the following functions will check if user_id == 0
1381 if (open_dir_authorize_id(user_id
, iph1
->rmconf
->open_dir_auth_group
)) {
1388 if (user_id_found
) {
1389 plog(LLV_ERROR
, LOCATION
, NULL
,
1390 "the peer is not authorized for access.\n");
1392 plog(LLV_ERROR
, LOCATION
, NULL
,
1393 "the peer is not authorized for access - user ID not found.\n");
1395 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1397 #endif /* HAVE_OPENDIR */
1401 oakley_check_x509cert(certchain
, capath
, cafile
, local
)
1410 for (p
= certchain
; p
; p
= p
->chain
) {
1411 if ((result
= eay_check_x509cert(&p
->cert
,
1420 #endif /* HAVE_OPENSSL */
1423 * compute each authentication method in phase 1.
1427 * other: error to be reply with notification.
1428 * the value is notification type.
1431 oakley_validate_auth(iph1
)
1432 struct ph1handle
*iph1
;
1434 vchar_t
*my_hash
= NULL
;
1437 vchar_t
*gsshash
= NULL
;
1440 struct timeval start
, end
;
1442 SecKeyRef publicKeyRef
;
1445 gettimeofday(&start
, NULL
);
1448 switch (AUTHMETHOD(iph1
)) {
1449 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
1450 #ifdef ENABLE_HYBRID
1451 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
1452 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
1458 if (iph1
->id_p
== NULL
|| iph1
->pl_hash
== NULL
) {
1459 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1460 "few isakmp message received.\n");
1461 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1463 #ifdef ENABLE_HYBRID
1464 if (AUTHMETHOD(iph1
) == FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
&&
1465 ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_VENDORID_XAUTH
) == 0))
1467 plog(LLV_ERROR
, LOCATION
, NULL
, "No SIG was passed, "
1468 "hybrid auth is enabled, "
1469 "but peer is no Xauth compliant\n");
1470 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED
;
1474 r_hash
= (caddr_t
)(iph1
->pl_hash
+ 1);
1476 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH received:\n");
1477 plogdump(LLV_DEBUG
, r_hash
,
1478 ntohs(iph1
->pl_hash
->h
.len
) - sizeof(*iph1
->pl_hash
));
1480 switch (iph1
->etype
) {
1481 case ISAKMP_ETYPE_IDENT
:
1482 case ISAKMP_ETYPE_AGG
:
1483 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1485 case ISAKMP_ETYPE_BASE
:
1486 if (iph1
->side
== INITIATOR
)
1487 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1489 my_hash
= oakley_ph1hash_base_i(iph1
, VALIDATE
);
1492 plog(LLV_ERROR
, LOCATION
, NULL
,
1493 "invalid etype %d\n", iph1
->etype
);
1494 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1496 if (my_hash
== NULL
)
1497 return ISAKMP_INTERNAL_ERROR
;
1499 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1503 plog(LLV_ERROR
, LOCATION
, NULL
, "HASH mismatched\n");
1504 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1507 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH for PSK validated.\n");
1510 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
1511 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1512 #ifdef ENABLE_HYBRID
1513 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1514 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1515 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
1516 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1517 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
1518 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
1525 if (iph1
->id_p
== NULL
) {
1526 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1527 "no ID payload was passed.\n");
1528 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1530 if (iph1
->sig_p
== NULL
) {
1531 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1532 "no SIG payload was passed.\n");
1533 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1536 plog(LLV_DEBUG
, LOCATION
, NULL
, "SIGN passed:\n");
1537 plogdump(LLV_DEBUG
, iph1
->sig_p
->v
, iph1
->sig_p
->l
);
1539 /* get peer's cert */
1540 switch (iph1
->rmconf
->getcert_method
) {
1541 case ISAKMP_GETCERT_PAYLOAD
:
1542 if (iph1
->cert_p
== NULL
) {
1543 plog(LLV_ERROR
, LOCATION
, NULL
,
1544 "no peer's CERT payload found.\n");
1545 return ISAKMP_INTERNAL_ERROR
;
1549 case ISAKMP_GETCERT_LOCALFILE
:
1550 switch (iph1
->rmconf
->certtype
) {
1551 case ISAKMP_CERT_X509SIGN
:
1552 if (iph1
->rmconf
->peerscertfile
== NULL
) {
1553 plog(LLV_ERROR
, LOCATION
, NULL
,
1554 "no peer's CERT file found.\n");
1555 return ISAKMP_INTERNAL_ERROR
;
1558 /* don't use cached cert */
1559 if (iph1
->cert_p
!= NULL
) {
1560 oakley_delcert(iph1
->cert_p
);
1561 iph1
->cert_p
= NULL
;
1564 error
= get_cert_fromlocal(iph1
, 0);
1569 return ISAKMP_INTERNAL_ERROR
;
1572 case ISAKMP_GETCERT_DNS
:
1573 if (iph1
->rmconf
->peerscertfile
!= NULL
) {
1574 plog(LLV_ERROR
, LOCATION
, NULL
,
1575 "why peer's CERT file is defined "
1576 "though getcert method is dns ?\n");
1577 return ISAKMP_INTERNAL_ERROR
;
1580 /* don't use cached cert */
1581 if (iph1
->cert_p
!= NULL
) {
1582 oakley_delcert(iph1
->cert_p
);
1583 iph1
->cert_p
= NULL
;
1586 iph1
->cert_p
= dnssec_getcert(iph1
->id_p
);
1587 if (iph1
->cert_p
== NULL
) {
1588 plog(LLV_ERROR
, LOCATION
, NULL
,
1589 "no CERT RR found.\n");
1590 return ISAKMP_INTERNAL_ERROR
;
1594 plog(LLV_ERROR
, LOCATION
, NULL
,
1595 "invalid getcert_mothod: %d\n",
1596 iph1
->rmconf
->getcert_method
);
1597 return ISAKMP_INTERNAL_ERROR
;
1600 /* compare ID payload and certificate name */
1601 if (iph1
->rmconf
->verify_cert
&&
1602 (error
= oakley_check_certid(iph1
, CERT_CHECKID_FROM_PEER
)) != 0)
1605 /* check configured peers identifier against cert IDs */
1606 /* allows checking of specified ID against multiple ids in the cert */
1607 /* such as multiple domain names */
1608 #if !TARGET_OS_EMBEDDED
1609 if (iph1
->rmconf
->cert_verification_option
== VERIFICATION_OPTION_PEERS_IDENTIFIER
&&
1610 (error
= oakley_check_certid(iph1
, CERT_CHECKID_FROM_RMCONFIG
)) != 0)
1615 /* check cert common name against Open Directory authentication group */
1616 if (iph1
->rmconf
->cert_verification_option
== VERIFICATION_OPTION_OPEN_DIR
) {
1617 if (oakley_verify_userid(iph1
)) {
1618 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1621 #endif /* HAVE_OPENDIR */
1623 /* verify certificate */
1624 if (iph1
->rmconf
->verify_cert
1625 && iph1
->rmconf
->getcert_method
== ISAKMP_GETCERT_PAYLOAD
) {
1626 certtype
= iph1
->rmconf
->certtype
;
1627 #ifdef ENABLE_HYBRID
1628 switch (AUTHMETHOD(iph1
)) {
1629 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1630 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1631 certtype
= iph1
->cert_p
->type
;
1638 case ISAKMP_CERT_X509SIGN
:
1640 /* use ID from remote configuration */
1641 /* check each ID in list */
1642 struct idspec
*id_spec
;
1643 CFStringRef hostname
= NULL
;
1645 struct genlist_entry
*gpb
= NULL
;
1647 if (iph1
->rmconf
->cert_verification_option
== VERIFICATION_OPTION_PEERS_IDENTIFIER
) {
1648 id_spec
= genlist_next(iph1
->rmconf
->idvl_p
, &gpb
); /* expect only one id */
1649 if (id_spec
->idtype
== IDTYPE_ADDRESS
) {
1650 switch ((ALIGNED_CAST(struct sockaddr_storage
*)(id_spec
->id
->v
))->ss_family
) {
1652 peers_id
= inet_ntoa((ALIGNED_CAST(struct sockaddr_in
*)(id_spec
->id
->v
))->sin_addr
);
1653 hostname
= CFStringCreateWithCString(NULL
, peers_id
, kCFStringEncodingUTF8
);
1657 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
; /* not currently supported for embedded */
1661 plog(LLV_ERROR
, LOCATION
, NULL
,
1662 "unknown address type for peers identifier.\n");
1663 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1667 hostname
= CFStringCreateWithBytes(NULL
, (u_int8_t
*)id_spec
->id
->v
, id_spec
->id
->l
, kCFStringEncodingUTF8
, FALSE
);
1669 error
= crypto_cssm_check_x509cert(oakley_get_peer_cert_from_certchain(iph1
), iph1
->cert_p
, hostname
, &publicKeyRef
);
1671 CFRelease(hostname
);
1676 plog(LLV_ERROR
, LOCATION
, NULL
,
1677 "no supported certtype %d\n", certtype
);
1678 return ISAKMP_INTERNAL_ERROR
;
1681 plog(LLV_ERROR
, LOCATION
, NULL
,
1682 "the peer's certificate is not verified.\n");
1683 return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY
;
1687 plog(LLV_DEBUG
, LOCATION
, NULL
, "CERT validated\n");
1690 switch (iph1
->etype
) {
1691 case ISAKMP_ETYPE_IDENT
:
1692 case ISAKMP_ETYPE_AGG
:
1693 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1695 case ISAKMP_ETYPE_BASE
:
1696 if (iph1
->side
== INITIATOR
)
1697 my_hash
= oakley_ph1hash_base_r(iph1
, VALIDATE
);
1699 my_hash
= oakley_ph1hash_base_i(iph1
, VALIDATE
);
1702 plog(LLV_ERROR
, LOCATION
, NULL
,
1703 "invalid etype %d\n", iph1
->etype
);
1704 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1706 if (my_hash
== NULL
)
1707 return ISAKMP_INTERNAL_ERROR
;
1710 certtype
= iph1
->rmconf
->certtype
;
1711 #ifdef ENABLE_HYBRID
1712 switch (AUTHMETHOD(iph1
)) {
1713 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1714 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1715 certtype
= iph1
->cert_p
->type
;
1721 /* check signature */
1723 case ISAKMP_CERT_X509SIGN
:
1724 case ISAKMP_CERT_DNS
:
1725 if (publicKeyRef
== NULL
)
1726 plog(LLV_ERROR
, LOCATION
, NULL
, "@@@@@@ publicKeyRef is NULL\n");
1727 error
= crypto_cssm_verify_x509sign(publicKeyRef
, my_hash
, iph1
->sig_p
);
1729 plog(LLV_ERROR
, LOCATION
, NULL
, "error verifying signature %s\n", GetSecurityErrorString(error
));
1731 CFRelease(publicKeyRef
);
1735 plog(LLV_ERROR
, LOCATION
, NULL
,
1736 "no supported certtype %d\n",
1739 return ISAKMP_INTERNAL_ERROR
;
1744 plog(LLV_ERROR
, LOCATION
, NULL
,
1746 return ISAKMP_NTYPE_INVALID_SIGNATURE
;
1748 plog(LLV_DEBUG
, LOCATION
, NULL
, "SIG authenticated\n");
1751 #ifdef ENABLE_HYBRID
1752 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1753 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
1755 if ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_VENDORID_XAUTH
) == 0) {
1756 plog(LLV_ERROR
, LOCATION
, NULL
, "No SIG was passed, "
1757 "hybrid auth is enabled, "
1758 "but peer is no Xauth compliant\n");
1759 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED
;
1762 plog(LLV_INFO
, LOCATION
, NULL
, "No SIG was passed, "
1763 "but hybrid auth is enabled\n");
1770 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
1771 /* check if we're not into XAUTH_PSKEY_I instead */
1772 #ifdef ENABLE_HYBRID
1773 if (iph1
->rmconf
->xauth
)
1776 switch (iph1
->etype
) {
1777 case ISAKMP_ETYPE_IDENT
:
1778 case ISAKMP_ETYPE_AGG
:
1779 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1782 plog(LLV_ERROR
, LOCATION
, NULL
,
1783 "invalid etype %d\n", iph1
->etype
);
1784 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1787 if (my_hash
== NULL
) {
1788 if (gssapi_more_tokens(iph1
))
1789 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1791 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1794 gsshash
= gssapi_unwraphash(iph1
);
1795 if (gsshash
== NULL
) {
1797 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1800 result
= memcmp(my_hash
->v
, gsshash
->v
, my_hash
->l
);
1805 plog(LLV_ERROR
, LOCATION
, NULL
, "HASH mismatched\n");
1806 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1808 plog(LLV_DEBUG
, LOCATION
, NULL
, "hash compared OK\n");
1811 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
1812 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
1813 #ifdef ENABLE_HYBRID
1814 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
1815 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
1816 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
1817 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
1819 if (iph1
->id_p
== NULL
|| iph1
->pl_hash
== NULL
) {
1820 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1821 "few isakmp message received.\n");
1822 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1824 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1825 "not supported authmethod type %s\n",
1826 s_oakley_attr_method(iph1
->approval
->authmethod
));
1827 return ISAKMP_INTERNAL_ERROR
;
1829 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1830 "invalid authmethod %d why ?\n",
1831 iph1
->approval
->authmethod
);
1832 return ISAKMP_INTERNAL_ERROR
;
1835 gettimeofday(&end
, NULL
);
1836 syslog(LOG_NOTICE
, "%s(%s): %8.6f", __func__
,
1837 s_oakley_attr_method(iph1
->approval
->authmethod
),
1838 timedelta(&start
, &end
));
1845 oakley_find_status_in_certchain (cert_t
*certchain
, cert_status_t certStatus
)
1849 for (p
= certchain
; p
; p
= p
->chain
) {
1850 if (p
->status
== certStatus
) {
1859 oakley_vpncontrol_notify_ike_failed_if_mycert_invalid (struct ph1handle
*iph1
,
1860 int notify_initiator
)
1862 #if TARGET_OS_EMBEDDED
1863 int premature
= oakley_find_status_in_certchain(iph1
->cert
, CERT_STATUS_PREMATURE
);
1864 int expired
= oakley_find_status_in_certchain(iph1
->cert
, CERT_STATUS_EXPIRED
);
1865 if (premature
|| expired
) {
1867 u_int32_t fail_reason
;
1869 if (iph1
->remote
->ss_family
== AF_INET
)
1870 address
= ((struct sockaddr_in
*)(iph1
->remote
))->sin_addr
.s_addr
;
1874 fail_reason
= VPNCTL_NTYPE_LOCAL_CERT_PREMATURE
;
1876 fail_reason
= VPNCTL_NTYPE_LOCAL_CERT_EXPIRED
;
1878 vpncontrol_notify_ike_failed(fail_reason
, notify_initiator
, address
, 0, NULL
);
1881 #endif /* TARGET_OS_EMBEDDED */
1885 /* get my certificate
1886 * NOTE: include certificate type.
1889 oakley_getmycert(iph1
)
1890 struct ph1handle
*iph1
;
1894 switch (iph1
->rmconf
->certtype
) {
1895 case ISAKMP_CERT_X509SIGN
:
1898 if ( !(err
= get_cert_fromlocal(iph1
, 1))){
1899 if (oakley_vpncontrol_notify_ike_failed_if_mycert_invalid(iph1
, FROM_LOCAL
)) {
1906 plog(LLV_ERROR
, LOCATION
, NULL
,
1907 "Unknown certtype #%d\n",
1908 iph1
->rmconf
->certtype
);
1915 * get a CERT from local file.
1918 * my == 0 peer's cert.
1921 get_cert_fromlocal(iph1
, my
)
1922 struct ph1handle
*iph1
;
1926 char path
[MAXPATHLEN
];
1928 vchar_t
*cert
= NULL
;
1932 cert_status_t status
= CERT_STATUS_OK
;
1935 certfile
= iph1
->rmconf
->mycertfile
;
1936 certpl
= &iph1
->cert
;
1938 certfile
= iph1
->rmconf
->peerscertfile
;
1939 certpl
= &iph1
->cert_p
;
1941 if (!certfile
&& iph1
->rmconf
->identity_in_keychain
== 0) {
1942 plog(LLV_ERROR
, LOCATION
, NULL
, "no CERT defined.\n");
1946 switch (iph1
->rmconf
->certtype
) {
1947 case ISAKMP_CERT_X509SIGN
:
1948 if (iph1
->rmconf
->identity_in_keychain
) {
1951 if (iph1
->rmconf
->keychainCertRef
== NULL
|| base64toCFData(iph1
->rmconf
->keychainCertRef
, &dataRef
))
1953 cert
= crypto_cssm_get_x509cert(dataRef
, &status
);
1954 plog(LLV_DEBUG
, LOCATION
, NULL
, "done with chking cert status %d\n",status
);
1959 case ISAKMP_CERT_DNS
:
1960 /* make public file name */
1961 getpathname(path
, sizeof(path
), LC_PATHTYPE_CERT
, certfile
);
1962 cert
= eay_get_x509cert(path
);
1964 oakley_cert_prettyprint(cert
);
1969 plog(LLV_ERROR
, LOCATION
, NULL
,
1970 "not supported certtype %d\n",
1971 iph1
->rmconf
->certtype
);
1976 plog(LLV_ERROR
, LOCATION
, NULL
,
1977 "failed to get %s CERT.\n",
1978 my
? "my" : "peers");
1982 *certpl
= oakley_newcert();
1984 plog(LLV_ERROR
, LOCATION
, NULL
,
1985 "failed to get cert buffer.\n");
1988 (*certpl
)->pl
= vmalloc(cert
->l
+ 1);
1989 if ((*certpl
)->pl
== NULL
) {
1990 plog(LLV_ERROR
, LOCATION
, NULL
,
1991 "failed to get cert buffer\n");
1992 oakley_delcert(*certpl
);
1996 memcpy((*certpl
)->pl
->v
+ 1, cert
->v
, cert
->l
);
1997 (*certpl
)->pl
->v
[0] = iph1
->rmconf
->certtype
;
1998 (*certpl
)->type
= iph1
->rmconf
->certtype
;
1999 (*certpl
)->status
= status
;
2000 (*certpl
)->cert
.v
= (*certpl
)->pl
->v
+ 1;
2001 (*certpl
)->cert
.l
= (*certpl
)->pl
->l
- 1;
2003 plog(LLV_DEBUG
, LOCATION
, NULL
, "created CERT payload:\n");
2004 plogdump(LLV_DEBUG
, (*certpl
)->pl
->v
, (*certpl
)->pl
->l
);
2005 oakley_cert_prettyprint(cert
);
2019 oakley_getsign(iph1
)
2020 struct ph1handle
*iph1
;
2023 char path
[MAXPATHLEN
];
2025 vchar_t
*privkey
= NULL
;
2028 switch (iph1
->rmconf
->certtype
) {
2029 case ISAKMP_CERT_X509SIGN
:
2030 // cert in keychain - use cssm to sign
2031 if (iph1
->rmconf
->identity_in_keychain
) {
2034 if (iph1
->rmconf
->keychainCertRef
== NULL
|| base64toCFData(iph1
->rmconf
->keychainCertRef
, &dataRef
))
2036 iph1
->sig
= crypto_cssm_getsign(dataRef
, iph1
->hash
);
2041 plog(LLV_ERROR
, LOCATION
, NULL
,
2042 "Unknown certtype #%d\n",
2043 iph1
->rmconf
->certtype
);
2047 if (iph1
->sig
== NULL
) {
2048 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to sign.\n");
2052 plog(LLV_DEBUG
, LOCATION
, NULL
, "SIGN computed:\n");
2053 plogdump(LLV_DEBUG
, iph1
->sig
->v
, iph1
->sig
->l
);
2058 if (privkey
!= NULL
)
2065 oakley_verify_certid(iph1
)
2066 struct ph1handle
*iph1
;
2068 if (iph1
->rmconf
->verify_cert
&&
2069 oakley_check_certid(iph1
, CERT_CHECKID_FROM_PEER
)){
2070 plog(LLV_DEBUG
, LOCATION
, NULL
,
2071 "Discarding CERT: does not match ID:\n");
2072 oakley_delcert(iph1
->cert_p
);
2073 iph1
->cert_p
= NULL
;
2078 oakley_check_certid_in_certchain(certchain
, idtype
, idlen
, id
)
2086 for (p
= certchain
; p
; p
= p
->chain
) {
2087 if (oakley_check_certid_1(&p
->cert
, idtype
, idlen
, id
, &p
->status
) == 0) {
2091 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2095 oakley_get_peer_cert_from_certchain(iph1
)
2096 struct ph1handle
* iph1
;
2099 struct ipsecdoi_id_b
*id_b
;
2103 if (!iph1
->id_p
|| !iph1
->cert_p
) {
2104 plog(LLV_ERROR
, LOCATION
, NULL
, "no ID nor CERT found.\n");
2107 if (!iph1
->cert_p
->chain
) {
2108 // no chain: simply return the only cert
2109 return iph1
->cert_p
;
2112 id_b
= ALIGNED_CAST(struct ipsecdoi_id_b
*)iph1
->id_p
->v
;
2113 peers_id
= id_b
+ 1;
2114 idlen
= iph1
->id_p
->l
- sizeof(*id_b
);
2115 for (p
= iph1
->cert_p
; p
; p
= p
->chain
) {
2116 if (oakley_check_certid_1(&p
->cert
, id_b
->type
, idlen
, peers_id
, &p
->status
) == 0) {
2124 * compare certificate name and ID value.
2127 oakley_check_certid(iph1
, which_id
)
2128 struct ph1handle
*iph1
;
2131 struct ipsecdoi_id_b
*id_b
;
2133 u_int8_t doi_type
= 255;
2134 void *peers_id
= NULL
;
2135 struct genlist_entry
*gpb
= NULL
;
2137 if (which_id
== CERT_CHECKID_FROM_PEER
) {
2138 /* use ID from peer */
2139 if (iph1
->id_p
== NULL
|| iph1
->cert_p
== NULL
) {
2140 plog(LLV_ERROR
, LOCATION
, NULL
, "no ID nor CERT found.\n");
2141 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2143 id_b
= ALIGNED_CAST(struct ipsecdoi_id_b
*)iph1
->id_p
->v
;
2144 doi_type
= id_b
->type
;
2145 peers_id
= id_b
+ 1;
2146 idlen
= iph1
->id_p
->l
- sizeof(*id_b
);
2148 return oakley_check_certid_in_certchain(iph1
->cert_p
, doi_type
, idlen
, peers_id
);
2151 /* use ID from remote configuration */
2152 /* check each ID in list */
2153 struct idspec
*id_spec
;
2155 for (id_spec
= genlist_next (iph1
->rmconf
->idvl_p
, &gpb
); id_spec
; id_spec
= genlist_next (0, &gpb
)) {
2157 if (id_spec
->idtype
== IDTYPE_ADDRESS
) {
2158 switch ((ALIGNED_CAST(struct sockaddr_storage
*)(id_spec
->id
->v
))->ss_family
) {
2160 doi_type
= IPSECDOI_ID_IPV4_ADDR
;
2161 idlen
= sizeof(struct in_addr
);
2162 peers_id
= &((ALIGNED_CAST(struct sockaddr_in
*)(id_spec
->id
->v
))->sin_addr
.s_addr
);
2166 doi_type
= IPSECDOI_ID_IPV6_ADDR
;
2167 idlen
= sizeof(struct in6_addr
);
2168 peers_id
= &((ALIGNED_CAST(struct sockaddr_in6
*)(id_spec
->id
->v
))->sin6_addr
.s6_addr
);
2172 plog(LLV_ERROR
, LOCATION
, NULL
,
2173 "unknown address type for peers identifier.\n");
2174 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
2179 doi_type
= idtype2doi(id_spec
->idtype
);
2180 peers_id
= id_spec
->id
->v
;
2181 idlen
= id_spec
->id
->l
;
2183 if (oakley_check_certid_in_certchain(iph1
->cert_p
, doi_type
, idlen
, peers_id
) == 0)
2186 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2191 oakley_check_certid_1(cert
, idtype
, idlen
, id
, certStatus
)
2196 cert_status_t
*certStatus
;
2202 #if !TARGET_OS_EMBEDDED
2204 vchar_t
*name
= NULL
;
2205 char *altname
= NULL
;
2209 case IPSECDOI_ID_DER_ASN1_DN
:
2210 #if TARGET_OS_EMBEDDED
2212 SecCertificateRef certificate
;
2216 certificate
= crypto_cssm_x509cert_get_SecCertificateRef(cert
);
2217 if (certificate
== NULL
) {
2218 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to get SecCertificateRef\n");
2219 if (certStatus
&& !*certStatus
) {
2220 *certStatus
= CERT_STATUS_INVALID
;
2222 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2224 subject
= SecCertificateCopySubjectSequence(certificate
);
2225 if (subject
== NULL
) {
2226 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to get subjectName\n");
2227 if (certStatus
&& !*certStatus
) {
2228 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
2230 CFRelease(certificate
);
2231 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2233 len
= CFDataGetLength(subject
);
2234 namePtr
= CFDataGetBytePtr(subject
);
2236 plog(LLV_ERROR
, LOCATION
, NULL
, "Invalid ID length in phase 1.\n");
2237 if (certStatus
&& !*certStatus
) {
2238 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
2241 CFRelease(certificate
);
2242 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2244 error
= memcmp(id
, namePtr
, idlen
);
2246 plog(LLV_ERROR
, LOCATION
, NULL
,
2247 "ID mismatched with subjectName.\n");
2248 plog(LLV_ERROR
, LOCATION
, NULL
,
2249 "subjectName (type %s):\n",
2250 s_ipsecdoi_ident(idtype
));
2251 plogdump(LLV_ERROR
, namePtr
, len
);
2252 plog(LLV_ERROR
, LOCATION
, NULL
,
2254 plogdump(LLV_ERROR
, id
, idlen
);
2255 if (certStatus
&& !*certStatus
) {
2256 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
2258 CFRelease(certificate
);
2260 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2262 CFRelease(certificate
);
2266 name
= eay_get_x509asn1subjectname(cert
);
2268 plog(LLV_ERROR
, LOCATION
, NULL
,
2269 "failed to get subjectName\n");
2270 if (certStatus
&& !*certStatus
) {
2271 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
2273 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2275 if (idlen
!= name
->l
) {
2276 plog(LLV_ERROR
, LOCATION
, NULL
,
2277 "Invalid ID length in phase 1.\n");
2279 if (certStatus
&& !*certStatus
) {
2280 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
2282 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2284 error
= memcmp(id
, name
->v
, idlen
);
2286 plog(LLV_ERROR
, LOCATION
, NULL
,
2287 "ID mismatched with subjectName.\n");
2288 plog(LLV_ERROR
, LOCATION
, NULL
,
2289 "subjectName (type %s):\n",
2290 s_ipsecdoi_ident(idtype
));
2291 plogdump(LLV_ERROR
, name
->v
, name
->l
);
2292 plog(LLV_ERROR
, LOCATION
, NULL
,
2294 plogdump(LLV_ERROR
, id
, idlen
);
2296 if (certStatus
&& !*certStatus
) {
2297 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
2299 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2305 case IPSECDOI_ID_IPV4_ADDR
:
2306 case IPSECDOI_ID_IPV6_ADDR
:
2308 #if TARGET_OS_EMBEDDED
2310 SecCertificateRef certificate
;
2311 CFArrayRef addresses
;
2312 #define ADDRESS_BUF_SIZE 64
2314 certificate
= crypto_cssm_x509cert_get_SecCertificateRef(cert
);
2315 if (certificate
== NULL
) {
2316 plog(LLV_ERROR
, LOCATION
, NULL
,
2317 "failed to get SecCertificateRef\n");
2318 if (certStatus
&& !*certStatus
) {
2319 *certStatus
= CERT_STATUS_INVALID
;
2321 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2323 addresses
= SecCertificateCopyIPAddresses(certificate
);
2324 if (addresses
== NULL
) {
2325 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to get subjectName\n");
2326 if (certStatus
&& !*certStatus
) {
2327 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2329 CFRelease(certificate
);
2330 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2332 count
= CFArrayGetCount(addresses
);
2333 for (pos
= 0; pos
< count
; pos
++) {
2335 CFStringRef address
;
2337 char *addressBuf
, numAddress
[128];
2340 address
= CFArrayGetValueAtIndex(addresses
, pos
);
2341 addressLen
= CFStringGetLength(address
);
2342 if (addressLen
== 0)
2344 addressBuf
= racoon_malloc(ADDRESS_BUF_SIZE
);
2345 if (addressBuf
== NULL
) {
2346 plog(LLV_ERROR
, LOCATION
, NULL
, "out of memory\n");
2347 CFRelease(addresses
);
2348 CFRelease(certificate
);
2351 if (CFStringGetCString(address
, addressBuf
, ADDRESS_BUF_SIZE
, kCFStringEncodingUTF8
) == TRUE
) {
2352 result
= inet_pton(idtype
== IPSECDOI_ID_IPV4_ADDR
? AF_INET
: AF_INET6
, addressBuf
, numAddress
);
2353 racoon_free(addressBuf
);
2355 continue; // wrong type or invalid address
2356 if (!memcmp(id
, numAddress
, idtype
== IPSECDOI_ID_IPV4_ADDR
? 32 : 128) == 0) { // found a match ?
2357 CFRelease(addresses
);
2358 CFRelease(certificate
);
2362 racoon_free(addressBuf
);
2364 plog(LLV_ERROR
, LOCATION
, NULL
, "ID mismatched with subjectAltName.\n");
2365 plog(LLV_ERROR
, LOCATION
, NULL
,
2366 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype
));
2367 plog(LLV_ERROR
, LOCATION
, NULL
, "ID:\n");
2368 plogdump(LLV_ERROR
, id
, idlen
);
2369 CFRelease(addresses
);
2370 CFRelease(certificate
);
2371 if (certStatus
&& !*certStatus
) {
2372 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2374 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2377 * Openssl returns the IPAddress as an ASN1 octet string (binary format)
2378 * followed by a trailing NULL. 5 bytes for IPv4 and 17 bytes for IPv6
2380 #define SUBJ_ALT_NAME_IPV4_ADDRESS_LEN 5
2381 #define SUBJ_ALT_NAME_IPV6_ADDRESS_LEN 17
2385 if (idtype
== IPSECDOI_ID_IPV4_ADDR
&& idlen
!= sizeof(struct in_addr
)
2386 || idtype
== IPSECDOI_ID_IPV6_ADDR
&& idlen
!= sizeof(struct in6_addr
)) {
2387 plog(LLV_ERROR
, LOCATION
, NULL
,
2388 "invalid address length passed.\n");
2389 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2392 for (pos
= 1; ; pos
++) {
2393 if (eay_get_x509subjectaltname(cert
, &altname
, &type
, pos
, &len
) !=0) {
2394 plog(LLV_ERROR
, LOCATION
, NULL
,
2395 "failed to get subjectAltName\n");
2396 if (certStatus
&& !*certStatus
) {
2397 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2399 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2402 /* it's the end condition of the loop. */
2404 plog(LLV_ERROR
, LOCATION
, NULL
,
2405 "invalid subjectAltName\n");
2406 if (certStatus
&& !*certStatus
) {
2407 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2409 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2412 if (check_typeofcertname(idtype
, type
) != 0) {
2413 /* wrong type - skip this one */
2414 racoon_free(altname
);
2419 if (len
== SUBJ_ALT_NAME_IPV4_ADDRESS_LEN
) { /* IPv4 */
2420 if (idtype
!= IPSECDOI_ID_IPV4_ADDR
) {
2421 /* wrong IP address type - skip this one */
2422 racoon_free(altname
);
2428 else if (len
== SUBJ_ALT_NAME_IPV6_ADDRESS_LEN
) { /* IPv6 */
2429 if (idtype
!= IPSECDOI_ID_IPV6_ADDR
) {
2430 /* wrong IP address type - skip this one */
2431 racoon_free(altname
);
2438 /* invalid IP address length in certificate - bad or bogus certificate */
2439 plog(LLV_ERROR
, LOCATION
, NULL
,
2440 "invalid IP address in certificate.\n");
2441 plog(LLV_ERROR
, LOCATION
, NULL
,
2442 "subjectAltName (expected type %s, got type %s):\n",
2443 s_ipsecdoi_ident(idtype
),
2444 s_ipsecdoi_ident(type
));
2445 plogdump(LLV_ERROR
, altname
, len
);
2446 racoon_free(altname
);
2448 if (certStatus
&& !*certStatus
) {
2449 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2451 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2454 /* compare the addresses */
2455 error
= memcmp(id
, altname
, idlen
);
2458 racoon_free(altname
);
2461 /* failed to find a match */
2462 plog(LLV_ERROR
, LOCATION
, NULL
,
2463 "ID mismatched with subjectAltName.\n");
2464 plog(LLV_ERROR
, LOCATION
, NULL
,
2465 "subjectAltName (expected type %s, got type %s):\n",
2466 s_ipsecdoi_ident(idtype
),
2467 s_ipsecdoi_ident(type
));
2468 plogdump(LLV_ERROR
, altname
, len
);
2469 plog(LLV_ERROR
, LOCATION
, NULL
,
2471 plogdump(LLV_ERROR
, id
, idlen
);
2472 racoon_free(altname
);
2473 if (certStatus
&& !*certStatus
)
2474 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2475 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2477 #endif /* TARGET_OS_EMBEDDED */
2480 #if TARGET_OS_EMBEDDED
2481 case IPSECDOI_ID_FQDN
:
2484 SecCertificateRef certificate
;
2486 CFStringRef name
, ID
;
2488 certificate
= crypto_cssm_x509cert_get_SecCertificateRef(cert
);
2489 if (certificate
== NULL
) {
2490 plog(LLV_ERROR
, LOCATION
, NULL
,
2491 "failed to get SecCertificateRef\n");
2492 if (certStatus
&& !*certStatus
) {
2493 *certStatus
= CERT_STATUS_INVALID
;
2495 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2497 names
= SecCertificateCopyDNSNames(certificate
);
2498 if (names
== NULL
) {
2499 plog(LLV_ERROR
, LOCATION
, NULL
,
2500 "failed to get subjectName\n");
2501 if (certStatus
&& !*certStatus
) {
2502 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2504 CFRelease(certificate
);
2505 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2507 count
= CFArrayGetCount(names
);
2508 ID
= CFStringCreateWithCString(NULL
, id
, kCFStringEncodingUTF8
);
2510 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error\n");
2512 CFRelease(certificate
);
2515 for (pos
= 0; pos
< count
; pos
++) {
2516 name
= CFArrayGetValueAtIndex(names
, pos
);
2517 if (CFStringCompare(name
, ID
, 0) == kCFCompareEqualTo
) {
2520 CFRelease(certificate
);
2524 plog(LLV_ERROR
, LOCATION
, NULL
, "ID mismatched with subjectAltName.\n");
2525 plog(LLV_ERROR
, LOCATION
, NULL
,
2526 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype
));
2527 plog(LLV_ERROR
, LOCATION
, NULL
, "ID:\n");
2528 plogdump(LLV_ERROR
, id
, idlen
);
2531 CFRelease(certificate
);
2532 if (certStatus
&& !*certStatus
) {
2533 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2535 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2538 case IPSECDOI_ID_USER_FQDN
:
2542 SecCertificateRef certificate
;
2544 CFStringRef name
, ID
;
2546 certificate
= crypto_cssm_x509cert_get_SecCertificateRef(cert
);
2547 if (certificate
== NULL
) {
2548 plog(LLV_ERROR
, LOCATION
, NULL
,
2549 "failed to get SecCertificateRef\n");
2550 if (certStatus
&& !*certStatus
) {
2551 *certStatus
= CERT_STATUS_INVALID
;
2553 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2555 names
= SecCertificateCopyRFC822Names(certificate
);
2556 if (names
== NULL
) {
2557 plog(LLV_ERROR
, LOCATION
, NULL
,
2558 "failed to get subjectName\n");
2559 if (certStatus
&& !*certStatus
) {
2560 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2562 CFRelease(certificate
);
2563 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2565 count
= CFArrayGetCount(names
);
2566 ID
= CFStringCreateWithCString(NULL
, id
, kCFStringEncodingUTF8
);
2568 plog(LLV_ERROR
, LOCATION
, NULL
,
2570 if (certStatus
&& !*certStatus
) {
2571 *certStatus
= CERT_STATUS_INVALID
;
2574 CFRelease(certificate
);
2575 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2577 for (pos
= 0; pos
< count
; pos
++) {
2578 name
= CFArrayGetValueAtIndex(names
, pos
);
2579 if (CFStringCompare(name
, ID
, 0) == kCFCompareEqualTo
) {
2582 CFRelease(certificate
);
2586 plog(LLV_ERROR
, LOCATION
, NULL
, "ID mismatched with subjectAltName.\n");
2587 plog(LLV_ERROR
, LOCATION
, NULL
,
2588 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype
));
2589 plog(LLV_ERROR
, LOCATION
, NULL
, "ID:\n");
2590 plogdump(LLV_ERROR
, id
, idlen
);
2593 CFRelease(certificate
);
2594 if (certStatus
&& !*certStatus
) {
2595 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2597 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2600 case IPSECDOI_ID_FQDN
:
2601 case IPSECDOI_ID_USER_FQDN
:
2605 for (pos
= 1; ; pos
++) {
2606 if (eay_get_x509subjectaltname(cert
, &altname
, &type
, pos
, &len
) != 0) {
2607 plog(LLV_ERROR
, LOCATION
, NULL
,
2608 "failed to get subjectAltName\n");
2609 if (certStatus
&& !*certStatus
) {
2610 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2612 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2615 /* it's the end condition of the loop. */
2617 plog(LLV_ERROR
, LOCATION
, NULL
,
2618 "invalid subjectAltName\n");
2619 if (certStatus
&& !*certStatus
) {
2620 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2622 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2625 if (check_typeofcertname(idtype
, type
) != 0) {
2626 /* wrong general type - skip this one */
2627 racoon_free(altname
);
2632 if (idlen
!= strlen(altname
)) {
2633 /* wrong length - skip this one */
2634 racoon_free(altname
);
2638 error
= memcmp(id
, altname
, idlen
);
2641 racoon_free(altname
);
2644 plog(LLV_ERROR
, LOCATION
, NULL
, "ID mismatched with subjectAltName.\n");
2645 plog(LLV_ERROR
, LOCATION
, NULL
,
2646 "subjectAltName (expected type %s, got type %s):\n",
2647 s_ipsecdoi_ident(idtype
),
2648 s_ipsecdoi_ident(type
));
2649 plogdump(LLV_ERROR
, altname
, len
);
2650 plog(LLV_ERROR
, LOCATION
, NULL
,
2652 plogdump(LLV_ERROR
, id
, idlen
);
2653 racoon_free(altname
);
2654 if (certStatus
&& !*certStatus
)
2655 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2656 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2660 plog(LLV_ERROR
, LOCATION
, NULL
,
2661 "Impropper ID type passed: %s.\n",
2662 s_ipsecdoi_ident(idtype
));
2663 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2669 check_typeofcertname(doi
, genid
)
2673 case IPSECDOI_ID_IPV4_ADDR
:
2674 case IPSECDOI_ID_IPV4_ADDR_SUBNET
:
2675 case IPSECDOI_ID_IPV6_ADDR
:
2676 case IPSECDOI_ID_IPV6_ADDR_SUBNET
:
2677 case IPSECDOI_ID_IPV4_ADDR_RANGE
:
2678 case IPSECDOI_ID_IPV6_ADDR_RANGE
:
2679 if (genid
!= GENT_IPADD
)
2682 case IPSECDOI_ID_FQDN
:
2683 if (genid
!= GENT_DNS
)
2686 case IPSECDOI_ID_USER_FQDN
:
2687 if (genid
!= GENT_EMAIL
)
2690 case IPSECDOI_ID_DER_ASN1_DN
: /* should not be passed to this function*/
2691 case IPSECDOI_ID_DER_ASN1_GN
:
2692 case IPSECDOI_ID_KEY_ID
:
2701 * save certificate including certificate type.
2704 oakley_savecert(iph1
, gen
)
2705 struct ph1handle
*iph1
;
2706 struct isakmp_gen
*gen
;
2711 STACK_OF(X509
) *certs
=NULL
;
2714 type
= *(u_int8_t
*)(gen
+ 1) & 0xff;
2717 case ISAKMP_CERT_DNS
:
2718 plog(LLV_WARNING
, LOCATION
, NULL
,
2719 "CERT payload is unnecessary in DNSSEC. "
2720 "ignore this CERT payload.\n");
2722 case ISAKMP_CERT_PKCS7
:
2723 case ISAKMP_CERT_PGP
:
2724 case ISAKMP_CERT_X509SIGN
:
2725 case ISAKMP_CERT_KERBEROS
:
2726 case ISAKMP_CERT_SPKI
:
2729 case ISAKMP_CERT_CRL
:
2732 case ISAKMP_CERT_X509KE
:
2733 case ISAKMP_CERT_X509ATTR
:
2734 case ISAKMP_CERT_ARL
:
2735 plog(LLV_ERROR
, LOCATION
, NULL
,
2736 "No supported such CERT type %d\n", type
);
2739 plog(LLV_ERROR
, LOCATION
, NULL
,
2740 "Invalid CERT type %d\n", type
);
2745 plog(LLV_WARNING
, LOCATION
, NULL
,
2746 "preexisting CERT payload... chaining.\n");
2749 if (type
== ISAKMP_CERT_PKCS7
) {
2753 /* Skip the header */
2754 bp
= (u_char
*)(gen
+ 1);
2755 /* And the first byte is the certificate type,
2756 * we know that already
2759 p7
= d2i_PKCS7(NULL
, (void *)&bp
,
2760 ntohs(gen
->len
) - sizeof(*gen
) - 1);
2763 plog(LLV_ERROR
, LOCATION
, NULL
,
2764 "Failed to parse PKCS#7 CERT.\n");
2768 /* Copied this from the openssl pkcs7 application;
2769 * there"s little by way of documentation for any of
2770 * it. I can only presume it"s correct.
2773 i
= OBJ_obj2nid(p7
->type
);
2775 case NID_pkcs7_signed
:
2776 certs
=p7
->d
.sign
->cert
;
2778 case NID_pkcs7_signedAndEnveloped
:
2779 certs
=p7
->d
.signed_and_enveloped
->cert
;
2786 plog(LLV_ERROR
, LOCATION
, NULL
,
2787 "CERT PKCS#7 bundle contains no certs.\n");
2792 for (i
= 0; i
< sk_X509_num(certs
); i
++) {
2796 X509
*cert
= sk_X509_value(certs
,i
);
2798 plog(LLV_DEBUG
, LOCATION
, NULL
,
2799 "Trying PKCS#7 cert %d.\n", i
);
2801 /* We'll just try each cert in turn */
2802 new = save_certx509(cert
);
2804 plog(LLV_ERROR
, LOCATION
, NULL
,
2805 "Failed to get CERT buffer.\n");
2808 *c
= oakley_appendcert_to_certchain(*c
, new);
2809 plog(LLV_DEBUG
, LOCATION
, NULL
, "CERT saved:\n");
2810 plogdump(LLV_DEBUG
, new->cert
.v
, new->cert
.l
);
2811 oakley_cert_prettyprint(&new->cert
);
2819 new = save_certbuf(gen
);
2821 plog(LLV_ERROR
, LOCATION
, NULL
,
2822 "Failed to get CERT buffer.\n");
2826 switch (new->type
) {
2827 case ISAKMP_CERT_DNS
:
2828 plog(LLV_WARNING
, LOCATION
, NULL
,
2829 "CERT payload is unnecessary in DNSSEC. "
2832 case ISAKMP_CERT_PGP
:
2833 case ISAKMP_CERT_X509SIGN
:
2834 case ISAKMP_CERT_KERBEROS
:
2835 case ISAKMP_CERT_SPKI
:
2836 /* Ignore cert if it doesn't match identity
2837 * XXX If verify cert is disabled, we still just take
2838 * the first certificate....
2840 *c
= oakley_appendcert_to_certchain(*c
, new);
2841 plog(LLV_DEBUG
, LOCATION
, NULL
, "CERT saved:\n");
2842 plogdump(LLV_DEBUG
, new->cert
.v
, new->cert
.l
);
2843 oakley_cert_prettyprint(&new->cert
);
2845 case ISAKMP_CERT_CRL
:
2846 *c
= oakley_appendcert_to_certchain(*c
, new);
2847 plog(LLV_DEBUG
, LOCATION
, NULL
, "CRL saved:\n");
2848 plogdump(LLV_DEBUG
, new->cert
.v
, new->cert
.l
);
2849 oakley_cert_prettyprint(&new->cert
);
2851 case ISAKMP_CERT_X509KE
:
2852 case ISAKMP_CERT_X509ATTR
:
2853 case ISAKMP_CERT_ARL
:
2856 oakley_delcert(new);
2865 * save certificate including certificate type.
2868 oakley_savecr(iph1
, gen
)
2869 struct ph1handle
*iph1
;
2870 struct isakmp_gen
*gen
;
2876 type
= *(u_int8_t
*)(gen
+ 1) & 0xff;
2879 case ISAKMP_CERT_DNS
:
2880 plog(LLV_WARNING
, LOCATION
, NULL
,
2881 "CERT payload is unnecessary in DNSSEC\n");
2883 case ISAKMP_CERT_PKCS7
:
2884 case ISAKMP_CERT_PGP
:
2885 case ISAKMP_CERT_X509SIGN
:
2886 case ISAKMP_CERT_KERBEROS
:
2887 case ISAKMP_CERT_SPKI
:
2889 oakley_delcert(iph1
->cr_p
);
2894 case ISAKMP_CERT_X509KE
:
2895 case ISAKMP_CERT_X509ATTR
:
2896 case ISAKMP_CERT_ARL
:
2897 plog(LLV_ERROR
, LOCATION
, NULL
,
2898 "No supported such CR type %d\n", type
);
2900 case ISAKMP_CERT_CRL
:
2902 plog(LLV_ERROR
, LOCATION
, NULL
,
2903 "Invalid CR type %d\n", type
);
2907 new = save_certbuf(gen
);
2909 plog(LLV_ERROR
, LOCATION
, NULL
,
2910 "Failed to get CR buffer.\n");
2913 *c
= oakley_appendcert_to_certchain(*c
, new);
2914 plog(LLV_DEBUG
, LOCATION
, NULL
, "CR saved:\n");
2915 plogdump(LLV_DEBUG
, new->cert
.v
, new->cert
.l
);
2922 struct isakmp_gen
*gen
;
2926 if(ntohs(gen
->len
) <= sizeof(*gen
)){
2927 plog(LLV_ERROR
, LOCATION
, NULL
,
2928 "Len is too small !!.\n");
2932 new = oakley_newcert();
2934 plog(LLV_ERROR
, LOCATION
, NULL
,
2935 "Failed to get CERT buffer.\n");
2939 new->pl
= vmalloc(ntohs(gen
->len
) - sizeof(*gen
));
2940 if (new->pl
== NULL
) {
2941 plog(LLV_ERROR
, LOCATION
, NULL
,
2942 "Failed to copy CERT from packet.\n");
2943 oakley_delcert(new);
2947 memcpy(new->pl
->v
, gen
+ 1, new->pl
->l
);
2948 new->type
= new->pl
->v
[0] & 0xff;
2949 new->cert
.v
= new->pl
->v
+ 1;
2950 new->cert
.l
= new->pl
->l
- 1;
2964 new = oakley_newcert();
2966 plog(LLV_ERROR
, LOCATION
, NULL
,
2967 "Failed to get CERT buffer.\n");
2971 len
= i2d_X509(cert
, NULL
);
2972 new->pl
= vmalloc(len
);
2973 if (new->pl
== NULL
) {
2974 plog(LLV_ERROR
, LOCATION
, NULL
,
2975 "Failed to copy CERT from packet.\n");
2976 oakley_delcert(new);
2980 bp
= (u_char
*) new->pl
->v
;
2981 len
= i2d_X509(cert
, &bp
);
2982 new->type
= ISAKMP_CERT_X509SIGN
;
2983 new->cert
.v
= new->pl
->v
;
2984 new->cert
.l
= new->pl
->l
;
2992 * NOTE: No Certificate Authority field is included to CR payload at the
2993 * moment. Becuase any certificate authority are accepted without any check.
2994 * The section 3.10 in RFC2408 says that this field SHOULD not be included,
2995 * if there is no specific certificate authority requested.
2999 struct ph1handle
*iph1
;
3005 plog(LLV_ERROR
, LOCATION
, NULL
,
3006 "failed to get cr buffer\n");
3009 if(iph1
->rmconf
->certtype
== ISAKMP_CERT_NONE
) {
3010 buf
->v
[0] = iph1
->rmconf
->cacerttype
;
3011 plog(LLV_DEBUG
, LOCATION
, NULL
, "create my CR: NONE, using %s instead\n",
3012 s_isakmp_certtype(iph1
->rmconf
->cacerttype
));
3014 buf
->v
[0] = iph1
->rmconf
->certtype
;
3015 plog(LLV_DEBUG
, LOCATION
, NULL
, "create my CR: %s\n",
3016 s_isakmp_certtype(iph1
->rmconf
->certtype
));
3019 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3028 oakley_checkcr(iph1
)
3029 struct ph1handle
*iph1
;
3031 if (iph1
->cr_p
== NULL
)
3034 plog(LLV_DEBUG
, LOCATION
, iph1
->remote
,
3035 "peer transmitted CR: %s\n",
3036 s_isakmp_certtype(iph1
->cr_p
->type
));
3038 if (iph1
->cr_p
->type
!= iph1
->rmconf
->certtype
) {
3039 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
3040 "such a cert type isn't supported: %d\n",
3041 (char)iph1
->cr_p
->type
);
3049 * check to need CR payload.
3056 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
3057 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
3058 #ifdef ENABLE_HYBRID
3059 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
3060 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
3061 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
3062 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
3063 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
3064 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
3074 oakley_getpskall(iph1
)
3075 struct ph1handle
*iph1
;
3077 vchar_t
*secret
= NULL
;
3079 if (iph1
->rmconf
->shared_secret
) {
3081 switch (iph1
->rmconf
->secrettype
) {
3082 case SECRETTYPE_KEY
:
3083 /* in psk file - use KEY from remote configuration to locate it */
3084 secret
= getpsk(iph1
->rmconf
->shared_secret
->v
, iph1
->rmconf
->shared_secret
->l
-1);
3087 case SECRETTYPE_KEYCHAIN
:
3088 /* in the system keychain */
3089 secret
= getpskfromkeychain(iph1
->rmconf
->shared_secret
->v
, iph1
->etype
, iph1
->rmconf
->secrettype
, NULL
);
3091 case SECRETTYPE_KEYCHAIN_BY_ID
:
3092 /* in the system keychain - use peer id */
3093 secret
= getpskfromkeychain(iph1
->rmconf
->shared_secret
->v
, iph1
->etype
, iph1
->rmconf
->secrettype
, iph1
->id_p
);
3095 #endif // HAVE_KEYCHAIN
3096 case SECRETTYPE_USE
:
3097 /* in the remote configuration */
3099 /* rmconf->shared_secret is a string and contains a NULL character that must be removed */
3100 secret
= vmalloc(iph1
->rmconf
->shared_secret
->l
- 1);
3101 if (secret
== NULL
) {
3102 plog(LLV_ERROR
, LOCATION
, iph1
->remote
, "memory error.\n");
3105 memcpy(secret
->v
, iph1
->rmconf
->shared_secret
->v
, secret
->l
);
3108 secret
= getpskbyname(iph1
->id_p
);
3110 if (iph1
->rmconf
->verify_identifier
) {
3111 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
3112 "couldn't find the Hybrid pskey.\n");
3118 plog(LLV_NOTIFY
, LOCATION
, iph1
->remote
,
3119 "couldn't find the Hybrid pskey, "
3120 "try to get one by the peer's address.\n");
3121 secret
= getpskbyaddr(iph1
->remote
);
3130 * see seciton 5. Exchanges in RFC 2409
3131 * psk: SKEYID = prf(pre-shared-key, Ni_b | Nr_b)
3132 * sig: SKEYID = prf(Ni_b | Nr_b, g^ir)
3133 * enc: SKEYID = prf(H(Ni_b | Nr_b), CKY-I | CKY-R)
3137 struct ph1handle
*iph1
;
3139 vchar_t
*buf
= NULL
, *bp
;
3145 switch (AUTHMETHOD(iph1
)) {
3146 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
3147 #ifdef ENABLE_HYBRID
3148 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
3149 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
3151 if (iph1
->rmconf
->shared_secret
) {
3153 switch (iph1
->rmconf
->secrettype
) {
3154 case SECRETTYPE_KEY
:
3155 /* in psk file - use KEY from remote configuration to locate it */
3156 iph1
->authstr
= getpsk(iph1
->rmconf
->shared_secret
->v
, iph1
->rmconf
->shared_secret
->l
-1);
3159 case SECRETTYPE_KEYCHAIN
:
3160 /* in the system keychain */
3161 iph1
->authstr
= getpskfromkeychain(iph1
->rmconf
->shared_secret
->v
, iph1
->etype
, iph1
->rmconf
->secrettype
, NULL
);
3163 case SECRETTYPE_KEYCHAIN_BY_ID
:
3164 /* in the system keychain - use peer id */
3165 iph1
->authstr
= getpskfromkeychain(iph1
->rmconf
->shared_secret
->v
, iph1
->etype
, iph1
->rmconf
->secrettype
, iph1
->id_p
);
3167 #endif // HAVE_KEYCHAIN
3168 case SECRETTYPE_USE
:
3169 /* in the remote configuration */
3171 /* rmconf->shared_secret is a string and contains a NULL character that must be removed */
3172 iph1
->authstr
= vmalloc(iph1
->rmconf
->shared_secret
->l
- 1);
3173 if (iph1
->authstr
== NULL
) {
3174 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error.\n");
3177 memcpy(iph1
->authstr
->v
, iph1
->rmconf
->shared_secret
->v
, iph1
->authstr
->l
);
3181 if (iph1
->etype
!= ISAKMP_ETYPE_IDENT
) {
3182 iph1
->authstr
= getpskbyname(iph1
->id_p
);
3183 if (iph1
->authstr
== NULL
) {
3184 if (iph1
->rmconf
->verify_identifier
) {
3185 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
3186 "couldn't find the pskey.\n");
3189 plog(LLV_NOTIFY
, LOCATION
, iph1
->remote
,
3190 "couldn't find the proper pskey, "
3191 "try to get one by the peer's address.\n");
3194 if (iph1
->authstr
== NULL
) {
3196 * If the exchange type is the main mode or if it's
3197 * failed to get the psk by ID, racoon try to get
3198 * the psk by remote IP address.
3199 * It may be nonsense.
3201 iph1
->authstr
= getpskbyaddr(iph1
->remote
);
3202 if (iph1
->authstr
== NULL
) {
3203 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
3204 "couldn't find the pskey for %s.\n",
3205 saddrwop2str((struct sockaddr
*)iph1
->remote
));
3209 plog(LLV_DEBUG
, LOCATION
, NULL
, "the psk found.\n");
3210 /* should be secret PSK */
3211 plog(LLV_DEBUG2
, LOCATION
, NULL
, "psk: ");
3212 plogdump(LLV_DEBUG2
, iph1
->authstr
->v
, iph1
->authstr
->l
);
3214 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
3217 plog(LLV_ERROR
, LOCATION
, NULL
,
3218 "failed to get skeyid buffer\n");
3223 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce
: iph1
->nonce_p
);
3224 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce 1: ");
3225 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
3226 memcpy(p
, bp
->v
, bp
->l
);
3229 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce_p
: iph1
->nonce
);
3230 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce 2: ");
3231 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
3232 memcpy(p
, bp
->v
, bp
->l
);
3235 iph1
->skeyid
= oakley_prf(iph1
->authstr
, buf
, iph1
);
3236 if (iph1
->skeyid
== NULL
)
3240 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
3241 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
3242 #ifdef ENABLE_HYBRID
3243 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
3244 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
3245 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
3246 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
3247 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
3248 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
3249 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
3250 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
3253 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
3255 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
3258 plog(LLV_ERROR
, LOCATION
, NULL
,
3259 "failed to get nonce buffer\n");
3264 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce
: iph1
->nonce_p
);
3265 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce1: ");
3266 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
3267 memcpy(p
, bp
->v
, bp
->l
);
3270 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce_p
: iph1
->nonce
);
3271 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce2: ");
3272 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
3273 memcpy(p
, bp
->v
, bp
->l
);
3276 iph1
->skeyid
= oakley_prf(buf
, iph1
->dhgxy
, iph1
);
3277 if (iph1
->skeyid
== NULL
)
3280 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
3281 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
3282 #ifdef ENABLE_HYBRID
3283 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
3284 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
3285 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
3286 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
3288 plog(LLV_WARNING
, LOCATION
, NULL
,
3289 "not supported authentication method %s\n",
3290 s_oakley_attr_method(iph1
->approval
->authmethod
));
3293 plog(LLV_ERROR
, LOCATION
, NULL
,
3294 "invalid authentication method %d\n",
3295 iph1
->approval
->authmethod
);
3299 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID computed:\n");
3300 plogdump(LLV_DEBUG
, iph1
->skeyid
->v
, iph1
->skeyid
->l
);
3311 * compute SKEYID_[dae]
3312 * see seciton 5. Exchanges in RFC 2409
3313 * SKEYID_d = prf(SKEYID, g^ir | CKY-I | CKY-R | 0)
3314 * SKEYID_a = prf(SKEYID, SKEYID_d | g^ir | CKY-I | CKY-R | 1)
3315 * SKEYID_e = prf(SKEYID, SKEYID_a | g^ir | CKY-I | CKY-R | 2)
3318 oakley_skeyid_dae(iph1
)
3319 struct ph1handle
*iph1
;
3321 vchar_t
*buf
= NULL
;
3326 if (iph1
->skeyid
== NULL
) {
3327 plog(LLV_ERROR
, LOCATION
, NULL
, "no SKEYID found.\n");
3332 /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
3333 len
= iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
3336 plog(LLV_ERROR
, LOCATION
, NULL
,
3337 "failed to get skeyid buffer\n");
3342 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
3343 p
+= iph1
->dhgxy
->l
;
3344 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
3345 p
+= sizeof(cookie_t
);
3346 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
3347 p
+= sizeof(cookie_t
);
3349 iph1
->skeyid_d
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
3350 if (iph1
->skeyid_d
== NULL
)
3356 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID_d computed:\n");
3357 plogdump(LLV_DEBUG
, iph1
->skeyid_d
->v
, iph1
->skeyid_d
->l
);
3360 /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
3361 len
= iph1
->skeyid_d
->l
+ iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
3364 plog(LLV_ERROR
, LOCATION
, NULL
,
3365 "failed to get skeyid buffer\n");
3369 memcpy(p
, iph1
->skeyid_d
->v
, iph1
->skeyid_d
->l
);
3370 p
+= iph1
->skeyid_d
->l
;
3371 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
3372 p
+= iph1
->dhgxy
->l
;
3373 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
3374 p
+= sizeof(cookie_t
);
3375 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
3376 p
+= sizeof(cookie_t
);
3378 iph1
->skeyid_a
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
3379 if (iph1
->skeyid_a
== NULL
)
3385 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID_a computed:\n");
3386 plogdump(LLV_DEBUG
, iph1
->skeyid_a
->v
, iph1
->skeyid_a
->l
);
3389 /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
3390 len
= iph1
->skeyid_a
->l
+ iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
3393 plog(LLV_ERROR
, LOCATION
, NULL
,
3394 "failed to get skeyid buffer\n");
3398 memcpy(p
, iph1
->skeyid_a
->v
, iph1
->skeyid_a
->l
);
3399 p
+= iph1
->skeyid_a
->l
;
3400 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
3401 p
+= iph1
->dhgxy
->l
;
3402 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
3403 p
+= sizeof(cookie_t
);
3404 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
3405 p
+= sizeof(cookie_t
);
3407 iph1
->skeyid_e
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
3408 if (iph1
->skeyid_e
== NULL
)
3414 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID_e computed:\n");
3415 plogdump(LLV_DEBUG
, iph1
->skeyid_e
->v
, iph1
->skeyid_e
->l
);
3426 * compute final encryption key.
3430 oakley_compute_enckey(iph1
)
3431 struct ph1handle
*iph1
;
3433 u_int keylen
, prflen
;
3437 keylen
= alg_oakley_encdef_keylen(iph1
->approval
->enctype
,
3438 iph1
->approval
->encklen
);
3440 plog(LLV_ERROR
, LOCATION
, NULL
,
3441 "invalid encryption algoritym %d, "
3442 "or invalid key length %d.\n",
3443 iph1
->approval
->enctype
,
3444 iph1
->approval
->encklen
);
3447 iph1
->key
= vmalloc(keylen
>> 3);
3448 if (iph1
->key
== NULL
) {
3449 plog(LLV_ERROR
, LOCATION
, NULL
,
3450 "failed to get key buffer\n");
3454 /* set prf length */
3455 prflen
= alg_oakley_hashdef_hashlen(iph1
->approval
->hashtype
);
3457 plog(LLV_ERROR
, LOCATION
, NULL
,
3458 "invalid hash type %d.\n", iph1
->approval
->hashtype
);
3462 /* see isakmp-oakley-08 5.3. */
3463 if (iph1
->key
->l
<= iph1
->skeyid_e
->l
) {
3465 * if length(Ka) <= length(SKEYID_e)
3466 * Ka = first length(K) bit of SKEYID_e
3468 memcpy(iph1
->key
->v
, iph1
->skeyid_e
->v
, iph1
->key
->l
);
3470 vchar_t
*buf
= NULL
, *res
= NULL
;
3479 * K1 = prf(SKEYID_e, 0)
3480 * K2 = prf(SKEYID_e, K1)
3481 * K3 = prf(SKEYID_e, K2)
3483 plog(LLV_DEBUG
, LOCATION
, NULL
,
3484 "len(SKEYID_e) < len(Ka) (%zu < %zu), "
3485 "generating long key (Ka = K1 | K2 | ...)\n",
3486 iph1
->skeyid_e
->l
, iph1
->key
->l
);
3488 if ((buf
= vmalloc(prflen
>> 3)) == 0) {
3489 plog(LLV_ERROR
, LOCATION
, NULL
,
3490 "failed to get key buffer\n");
3493 p
= (u_char
*)iph1
->key
->v
;
3494 ep
= p
+ iph1
->key
->l
;
3498 if (p
== (u_char
*)iph1
->key
->v
) {
3499 /* just for computing K1 */
3503 res
= oakley_prf(iph1
->skeyid_e
, buf
, iph1
);
3508 plog(LLV_DEBUG
, LOCATION
, NULL
,
3509 "compute intermediate encryption key K%d\n",
3511 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3512 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
3514 cplen
= (res
->l
< ep
- p
) ? res
->l
: ep
- p
;
3515 memcpy(p
, res
->v
, cplen
);
3518 buf
->l
= prflen
>> 3; /* to cancel K1 speciality */
3519 if (res
->l
!= buf
->l
) {
3520 plog(LLV_ERROR
, LOCATION
, NULL
,
3521 "internal error: res->l=%zu buf->l=%zu\n",
3527 memcpy(buf
->v
, res
->v
, res
->l
);
3536 * don't check any weak key or not.
3537 * draft-ietf-ipsec-ike-01.txt Appendix B.
3538 * draft-ietf-ipsec-ciph-aes-cbc-00.txt Section 2.3.
3542 if (iph1
->approval
->enctype
> ARRAYLEN(oakley_encdef
)
3543 || oakley_encdef
[iph1
->approval
->enctype
].weakkey
== NULL
) {
3544 plog(LLV_ERROR
, LOCATION
, NULL
,
3545 "encryption algoritym %d isn't supported.\n",
3546 iph1
->approval
->enctype
);
3549 if ((oakley_encdef
[iph1
->approval
->enctype
].weakkey
)(iph1
->key
)) {
3550 plog(LLV_ERROR
, LOCATION
, NULL
,
3551 "weakkey was generated.\n");
3556 plog(LLV_DEBUG
, LOCATION
, NULL
, "final encryption key computed:\n");
3557 plogdump(LLV_DEBUG
, iph1
->key
->v
, iph1
->key
->l
);
3565 /* allocated new buffer for CERT */
3571 new = racoon_calloc(1, sizeof(*new));
3573 plog(LLV_ERROR
, LOCATION
, NULL
,
3574 "failed to get cert's buffer\n");
3584 /* delete buffer for CERT */
3586 oakley_delcert_1(cert
)
3596 /* delete buffer for CERT */
3598 oakley_delcert(cert
)
3601 cert_t
*p
, *to_delete
;
3606 for (p
= cert
; p
;) {
3609 oakley_delcert_1(to_delete
);
3613 /* delete buffer for CERT */
3615 oakley_appendcert_to_certchain(certchain
, new)
3624 for (p
= certchain
; p
; p
= p
->chain
) {
3634 * compute IV and set to ph1handle
3635 * IV = hash(g^xi | g^xr)
3636 * see 4.1 Phase 1 state in draft-ietf-ipsec-ike.
3640 struct ph1handle
*iph1
;
3642 struct isakmp_ivm
*newivm
= NULL
;
3643 vchar_t
*buf
= NULL
, *bp
;
3648 len
= iph1
->dhpub
->l
+ iph1
->dhpub_p
->l
;
3651 plog(LLV_ERROR
, LOCATION
, NULL
,
3652 "failed to get iv buffer\n");
3658 bp
= (iph1
->side
== INITIATOR
? iph1
->dhpub
: iph1
->dhpub_p
);
3659 memcpy(p
, bp
->v
, bp
->l
);
3662 bp
= (iph1
->side
== INITIATOR
? iph1
->dhpub_p
: iph1
->dhpub
);
3663 memcpy(p
, bp
->v
, bp
->l
);
3667 newivm
= racoon_calloc(1, sizeof(struct isakmp_ivm
));
3668 if (newivm
== NULL
) {
3669 plog(LLV_ERROR
, LOCATION
, NULL
,
3670 "failed to get iv buffer\n");
3676 newivm
->iv
= oakley_hash(buf
, iph1
);
3677 if (newivm
->iv
== NULL
) {
3679 oakley_delivm(newivm
);
3683 /* adjust length of iv */
3684 newivm
->iv
->l
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3685 if (newivm
->iv
->l
== -1) {
3686 plog(LLV_ERROR
, LOCATION
, NULL
,
3687 "invalid encryption algoriym %d.\n",
3688 iph1
->approval
->enctype
);
3690 oakley_delivm(newivm
);
3694 /* create buffer to save iv */
3695 if ((newivm
->ive
= vdup(newivm
->iv
)) == NULL
) {
3696 plog(LLV_ERROR
, LOCATION
, NULL
,
3697 "vdup (%s)\n", strerror(errno
));
3699 oakley_delivm(newivm
);
3705 plog(LLV_DEBUG
, LOCATION
, NULL
, "IV computed:\n");
3706 plogdump(LLV_DEBUG
, newivm
->iv
->v
, newivm
->iv
->l
);
3708 if (iph1
->ivm
!= NULL
)
3709 oakley_delivm(iph1
->ivm
);
3717 * compute IV for the payload after phase 1.
3718 * It's not limited for phase 2.
3719 * if pahse 1 was encrypted.
3720 * IV = hash(last CBC block of Phase 1 | M-ID)
3721 * if phase 1 was not encrypted.
3722 * IV = hash(phase 1 IV | M-ID)
3723 * see 4.2 Phase 2 state in draft-ietf-ipsec-ike.
3726 oakley_newiv2(iph1
, msgid
)
3727 struct ph1handle
*iph1
;
3730 struct isakmp_ivm
*newivm
= NULL
;
3731 vchar_t
*buf
= NULL
;
3737 len
= iph1
->ivm
->iv
->l
+ sizeof(msgid_t
);
3740 plog(LLV_ERROR
, LOCATION
, NULL
,
3741 "failed to get iv buffer\n");
3747 memcpy(p
, iph1
->ivm
->iv
->v
, iph1
->ivm
->iv
->l
);
3748 p
+= iph1
->ivm
->iv
->l
;
3750 memcpy(p
, &msgid
, sizeof(msgid
));
3752 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute IV for phase2\n");
3753 plog(LLV_DEBUG
, LOCATION
, NULL
, "phase1 last IV:\n");
3754 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3757 newivm
= racoon_calloc(1, sizeof(struct isakmp_ivm
));
3758 if (newivm
== NULL
) {
3759 plog(LLV_ERROR
, LOCATION
, NULL
,
3760 "failed to get iv buffer\n");
3765 if ((newivm
->iv
= oakley_hash(buf
, iph1
)) == NULL
)
3768 /* adjust length of iv */
3769 newivm
->iv
->l
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3770 if (newivm
->iv
->l
== -1) {
3771 plog(LLV_ERROR
, LOCATION
, NULL
,
3772 "invalid encryption algoriym %d.\n",
3773 iph1
->approval
->enctype
);
3777 /* create buffer to save new iv */
3778 if ((newivm
->ive
= vdup(newivm
->iv
)) == NULL
) {
3779 plog(LLV_ERROR
, LOCATION
, NULL
, "vdup (%s)\n", strerror(errno
));
3785 plog(LLV_DEBUG
, LOCATION
, NULL
, "phase2 IV computed:\n");
3786 plogdump(LLV_DEBUG
, newivm
->iv
->v
, newivm
->iv
->l
);
3789 if (error
&& newivm
!= NULL
){
3790 oakley_delivm(newivm
);
3800 struct isakmp_ivm
*ivm
;
3805 if (ivm
->iv
!= NULL
)
3807 if (ivm
->ive
!= NULL
)
3810 plog(LLV_DEBUG
, LOCATION
, NULL
, "IV freed\n");
3817 * save new iv and old iv.
3820 oakley_do_decrypt(iph1
, msg
, ivdp
, ivep
)
3821 struct ph1handle
*iph1
;
3822 vchar_t
*msg
, *ivdp
, *ivep
;
3824 vchar_t
*buf
= NULL
, *new = NULL
;
3831 plog(LLV_DEBUG
, LOCATION
, NULL
, "begin decryption.\n");
3833 blen
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3835 plog(LLV_ERROR
, LOCATION
, NULL
,
3836 "invalid encryption algoriym %d.\n",
3837 iph1
->approval
->enctype
);
3841 /* save IV for next, but not sync. */
3842 memset(ivep
->v
, 0, ivep
->l
);
3843 memcpy(ivep
->v
, (caddr_t
)&msg
->v
[msg
->l
- blen
], blen
);
3845 plog(LLV_DEBUG
, LOCATION
, NULL
,
3846 "IV was saved for next processing:\n");
3847 plogdump(LLV_DEBUG
, ivep
->v
, ivep
->l
);
3849 pl
= msg
->v
+ sizeof(struct isakmp
);
3851 len
= msg
->l
- sizeof(struct isakmp
);
3856 plog(LLV_ERROR
, LOCATION
, NULL
,
3857 "failed to get buffer to decrypt.\n");
3860 memcpy(buf
->v
, pl
, len
);
3863 new = alg_oakley_encdef_decrypt(iph1
->approval
->enctype
,
3864 buf
, iph1
->key
, ivdp
);
3865 if (new == NULL
|| new->v
== NULL
|| new->l
== 0) {
3866 plog(LLV_ERROR
, LOCATION
, NULL
,
3867 "decryption %d failed.\n", iph1
->approval
->enctype
);
3870 plog(LLV_DEBUG
, LOCATION
, NULL
, "with key:\n");
3871 plogdump(LLV_DEBUG
, iph1
->key
->v
, iph1
->key
->l
);
3878 plog(LLV_DEBUG
, LOCATION
, NULL
, "decrypted payload by IV:\n");
3879 plogdump(LLV_DEBUG
, ivdp
->v
, ivdp
->l
);
3881 plog(LLV_DEBUG
, LOCATION
, NULL
,
3882 "decrypted payload, but not trimed.\n");
3883 plogdump(LLV_DEBUG
, new->v
, new->l
);
3885 /* get padding length */
3886 if (lcconf
->pad_excltail
)
3887 padlen
= new->v
[new->l
- 1] + 1;
3889 padlen
= new->v
[new->l
- 1];
3890 plog(LLV_DEBUG
, LOCATION
, NULL
, "padding len=%u\n", padlen
);
3893 if (lcconf
->pad_strict
) {
3894 if (padlen
> new->l
) {
3895 plog(LLV_ERROR
, LOCATION
, NULL
,
3896 "invalid padding len=%u, buflen=%zu.\n",
3898 plogdump(LLV_ERROR
, new->v
, new->l
);
3902 plog(LLV_DEBUG
, LOCATION
, NULL
, "trimmed padding\n");
3904 plog(LLV_DEBUG
, LOCATION
, NULL
, "skip to trim padding.\n");
3907 /* create new buffer */
3908 len
= sizeof(struct isakmp
) + new->l
;
3911 plog(LLV_ERROR
, LOCATION
, NULL
,
3912 "failed to get buffer to decrypt.\n");
3915 memcpy(buf
->v
, msg
->v
, sizeof(struct isakmp
));
3916 memcpy(buf
->v
+ sizeof(struct isakmp
), new->v
, new->l
);
3917 ((struct isakmp
*)buf
->v
)->len
= htonl(buf
->l
);
3919 plog(LLV_DEBUG
, LOCATION
, NULL
, "decrypted.\n");
3920 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3922 #ifdef HAVE_PRINT_ISAKMP_C
3923 isakmp_printpacket(buf
, iph1
->remote
, iph1
->local
, 1);
3929 if (error
&& buf
!= NULL
) {
3943 oakley_do_encrypt(iph1
, msg
, ivep
, ivp
)
3944 struct ph1handle
*iph1
;
3945 vchar_t
*msg
, *ivep
, *ivp
;
3947 vchar_t
*buf
= 0, *new = 0;
3954 plog(LLV_DEBUG
, LOCATION
, NULL
, "begin encryption.\n");
3956 /* set cbc block length */
3957 blen
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3959 plog(LLV_ERROR
, LOCATION
, NULL
,
3960 "invalid encryption algoriym %d.\n",
3961 iph1
->approval
->enctype
);
3965 pl
= msg
->v
+ sizeof(struct isakmp
);
3966 len
= msg
->l
- sizeof(struct isakmp
);
3969 padlen
= oakley_padlen(len
, blen
);
3970 plog(LLV_DEBUG
, LOCATION
, NULL
, "pad length = %u\n", padlen
);
3973 buf
= vmalloc(len
+ padlen
);
3975 plog(LLV_ERROR
, LOCATION
, NULL
,
3976 "failed to get buffer to encrypt.\n");
3981 char *p
= &buf
->v
[len
];
3982 if (lcconf
->pad_random
) {
3983 for (i
= 0; i
< padlen
; i
++)
3984 *p
++ = eay_random() & 0xff;
3987 memcpy(buf
->v
, pl
, len
);
3989 /* make pad into tail */
3990 if (lcconf
->pad_excltail
)
3991 buf
->v
[len
+ padlen
- 1] = padlen
- 1;
3993 buf
->v
[len
+ padlen
- 1] = padlen
;
3995 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3998 new = alg_oakley_encdef_encrypt(iph1
->approval
->enctype
,
3999 buf
, iph1
->key
, ivep
);
4001 plog(LLV_ERROR
, LOCATION
, NULL
,
4002 "encryption %d failed.\n", iph1
->approval
->enctype
);
4005 plog(LLV_DEBUG
, LOCATION
, NULL
, "with key:\n");
4006 plogdump(LLV_DEBUG
, iph1
->key
->v
, iph1
->key
->l
);
4013 plog(LLV_DEBUG
, LOCATION
, NULL
, "encrypted payload by IV:\n");
4014 plogdump(LLV_DEBUG
, ivep
->v
, ivep
->l
);
4016 /* save IV for next */
4017 memset(ivp
->v
, 0, ivp
->l
);
4018 memcpy(ivp
->v
, (caddr_t
)&new->v
[new->l
- blen
], blen
);
4020 plog(LLV_DEBUG
, LOCATION
, NULL
, "save IV for next:\n");
4021 plogdump(LLV_DEBUG
, ivp
->v
, ivp
->l
);
4023 /* create new buffer */
4024 len
= sizeof(struct isakmp
) + new->l
;
4027 plog(LLV_ERROR
, LOCATION
, NULL
,
4028 "failed to get buffer to encrypt.\n");
4031 memcpy(buf
->v
, msg
->v
, sizeof(struct isakmp
));
4032 memcpy(buf
->v
+ sizeof(struct isakmp
), new->v
, new->l
);
4033 ((struct isakmp
*)buf
->v
)->len
= htonl(buf
->l
);
4037 plog(LLV_DEBUG
, LOCATION
, NULL
, "encrypted.\n");
4040 if (error
&& buf
!= NULL
) {
4050 /* culculate padding length */
4052 oakley_padlen(len
, base
)
4057 padlen
= base
- len
% base
;
4059 if (lcconf
->pad_randomlen
)
4060 padlen
+= ((eay_random() % (lcconf
->pad_maxsize
+ 1) + 1) *
4066 /* -----------------------------------------------------------------------------
4067 The base-64 encoding packs three 8-bit bytes into four 7-bit ASCII
4068 characters. If the number of bytes in the original data isn't divisable
4069 by three, "=" characters are used to pad the encoded data. The complete
4070 set of characters used in base-64 are:
4078 ----------------------------------------------------------------------------- */
4079 static const signed char base64_DecodeTable
[128] = {
4080 /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
4081 /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
4082 /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
4083 /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
4084 /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
4085 /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
4086 /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
4087 /* '8' */ 60, 61, -1, -1, -1, 0, -1, -1,
4088 /* '@' */ -1, 0, 1, 2, 3, 4, 5, 6,
4089 /* 'H' */ 7, 8, 9, 10, 11, 12, 13, 14,
4090 /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
4091 /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
4092 /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
4093 /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
4094 /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
4095 /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
4098 static int base64toCFData(vchar_t
*textin
, CFDataRef
*dataRef
)
4106 uint8_t *textcur
= textin
->v
;
4107 int len
= textin
->l
;
4110 tmpbuf
= malloc(len
); // len of result will be less than encoded len
4111 if (tmpbuf
== NULL
) {
4112 yyerror("memory error - could not allocate buffer for certificate reference conversion from base-64.");
4116 for (i
= 0; i
< len
; i
++) {
4120 else if (!isspace(c
))
4122 if (base64_DecodeTable
[c
] < 0)
4126 acc
+= base64_DecodeTable
[c
];
4127 if (0 == (cntr
& 0x3)) {
4128 tmpbuf
[tmpbufpos
++] = (acc
>> 16) & 0xff;
4130 tmpbuf
[tmpbufpos
++] = (acc
>> 8) & 0xff;
4132 tmpbuf
[tmpbufpos
++] = acc
& 0xff;
4135 *dataRef
= CFDataCreate(NULL
, tmpbuf
, tmpbufpos
);