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"
103 #include <CoreFoundation/CoreFoundation.h>
104 #include "remoteconf.h"
105 #include "vpn_control.h"
106 #if TARGET_OS_EMBEDDED
107 #include <Security/SecCertificate.h>
108 #include <Security/SecCertificatePriv.h>
113 #include "vpn_control_var.h"
115 #define OUTBOUND_SA 0
118 #define CERT_CHECKID_FROM_PEER 0
119 #define CERT_CHECKID_FROM_RMCONFIG 1
122 #define INITDHVAL(a, s, d, t) \
125 buf.v = str2val((s), 16, &buf.l); \
126 memset(&a, 0, sizeof(struct dhgroup)); \
128 a.prime = vdup(&buf); \
131 racoon_free(buf.v); \
133 #else /* HAVE_OPENSSL */
134 #define INITDHVAL(a, s, d, t) \
137 buf.v = str2val((s), 16, &buf.l); \
138 memset(&a, 0, sizeof(struct dhgroup)); \
141 a.prime = vdup(&buf); \
144 racoon_free(buf.v); \
146 #endif /* HAVE_OPENSSL */
148 struct dhgroup dh_modp768
;
149 struct dhgroup dh_modp1024
;
150 struct dhgroup dh_modp1536
;
151 struct dhgroup dh_modp2048
;
152 struct dhgroup dh_modp3072
;
153 struct dhgroup dh_modp4096
;
154 struct dhgroup dh_modp6144
;
155 struct dhgroup dh_modp8192
;
158 static int oakley_check_dh_pub
__P((vchar_t
*, vchar_t
**));
159 static int oakley_compute_keymat_x
__P((struct ph2handle
*, int, int));
160 static int get_cert_fromlocal
__P((struct ph1handle
*, int));
162 static int get_plainrsa_fromlocal
__P((struct ph1handle
*, int));
164 static int oakley_check_certid
__P((struct ph1handle
*iph1
, int));
165 static int oakley_check_certid_1
__P((vchar_t
*, int, int, void*, cert_status_t
*certStatus
));
166 static int check_typeofcertname
__P((int, int));
167 static cert_t
*save_certbuf
__P((struct isakmp_gen
*));
169 static cert_t
*save_certx509
__P((X509
*));
171 static int oakley_padlen
__P((int, int));
173 static int base64toCFData(vchar_t
*, CFDataRef
*);
174 static cert_t
*oakley_appendcert_to_certchain(cert_t
*, cert_t
*);
176 static void oakley_cert_prettyprint (vchar_t
*cert
)
180 p
= eay_get_x509text(cert
);
182 /* add new cert dump code here */
184 plog(LLV_DEBUG
, LOCATION
, NULL
, "%s", p
? p
: "\n");
189 oakley_get_defaultlifetime()
191 return OAKLEY_ATTR_SA_LD_SEC_DEFAULT
;
198 INITDHVAL(dh_modp768
, OAKLEY_PRIME_MODP768
,
199 OAKLEY_ATTR_GRP_DESC_MODP768
, OAKLEY_ATTR_GRP_TYPE_MODP
);
200 INITDHVAL(dh_modp1024
, OAKLEY_PRIME_MODP1024
,
201 OAKLEY_ATTR_GRP_DESC_MODP1024
, OAKLEY_ATTR_GRP_TYPE_MODP
);
202 INITDHVAL(dh_modp1536
, OAKLEY_PRIME_MODP1536
,
203 OAKLEY_ATTR_GRP_DESC_MODP1536
, OAKLEY_ATTR_GRP_TYPE_MODP
);
204 INITDHVAL(dh_modp2048
, OAKLEY_PRIME_MODP2048
,
205 OAKLEY_ATTR_GRP_DESC_MODP2048
, OAKLEY_ATTR_GRP_TYPE_MODP
);
206 INITDHVAL(dh_modp3072
, OAKLEY_PRIME_MODP3072
,
207 OAKLEY_ATTR_GRP_DESC_MODP3072
, OAKLEY_ATTR_GRP_TYPE_MODP
);
208 INITDHVAL(dh_modp4096
, OAKLEY_PRIME_MODP4096
,
209 OAKLEY_ATTR_GRP_DESC_MODP4096
, OAKLEY_ATTR_GRP_TYPE_MODP
);
210 INITDHVAL(dh_modp6144
, OAKLEY_PRIME_MODP6144
,
211 OAKLEY_ATTR_GRP_DESC_MODP6144
, OAKLEY_ATTR_GRP_TYPE_MODP
);
212 INITDHVAL(dh_modp8192
, OAKLEY_PRIME_MODP8192
,
213 OAKLEY_ATTR_GRP_DESC_MODP8192
, OAKLEY_ATTR_GRP_TYPE_MODP
);
219 oakley_dhgrp_free(dhgrp
)
220 struct dhgroup
*dhgrp
;
225 vfree(dhgrp
->curve_a
);
227 vfree(dhgrp
->curve_b
);
235 * The length of the Diffie-Hellman public value MUST be equal to the
236 * length of the prime modulus over which the exponentiation was
237 * performed, prepending zero bits to the value if necessary.
240 oakley_check_dh_pub(prime
, pub0
)
241 vchar_t
*prime
, **pub0
;
244 vchar_t
*pub
= *pub0
;
246 if (prime
->l
== pub
->l
)
249 if (prime
->l
< pub
->l
) {
250 /* what should i do ? */
251 plog(LLV_ERROR
, LOCATION
, NULL
,
252 "invalid public information was generated.\n");
256 /* prime->l > pub->l */
257 tmp
= vmalloc(prime
->l
);
259 plog(LLV_ERROR
, LOCATION
, NULL
,
260 "failed to get DH buffer.\n");
263 memcpy(tmp
->v
+ prime
->l
- pub
->l
, pub
->v
, pub
->l
);
272 * compute sharing secret of DH
273 * IN: *dh, *pub, *priv, *pub_p
278 oakley_dh_compute(const struct dhgroup
*dh
, vchar_t
*pub
, vchar_t
*priv
, vchar_t
*pub_p
, vchar_t
**gxy
)
281 struct timeval start
, end
;
283 if ((*gxy
= vmalloc(dh
->prime
->l
)) == NULL
) {
284 plog(LLV_ERROR
, LOCATION
, NULL
,
285 "failed to get DH buffer.\n");
290 gettimeofday(&start
, NULL
);
293 case OAKLEY_ATTR_GRP_TYPE_MODP
:
294 if (eay_dh_compute(dh
->prime
, dh
->gen1
, pub
, priv
, pub_p
, gxy
) < 0) {
295 plog(LLV_ERROR
, LOCATION
, NULL
,
296 "failed to compute dh value.\n");
300 case OAKLEY_ATTR_GRP_TYPE_ECP
:
301 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
302 plog(LLV_ERROR
, LOCATION
, NULL
,
303 "dh type %d isn't supported.\n", dh
->type
);
306 plog(LLV_ERROR
, LOCATION
, NULL
,
307 "invalid dh type %d.\n", dh
->type
);
312 gettimeofday(&end
, NULL
);
313 syslog(LOG_NOTICE
, "%s(%s%d): %8.6f", __func__
,
314 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
315 timedelta(&start
, &end
));
318 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's shared.\n");
319 plogdump(LLV_DEBUG
, (*gxy
)->v
, (*gxy
)->l
);
325 oakley_dh_compute(const struct dhgroup
*dh
, vchar_t
*pub_p
, size_t publicKeySize
, vchar_t
**gxy
, SecDHContext dhC
)
328 vchar_t
*computed_key
= NULL
;
329 size_t computed_keylen
;
333 struct timeval start
, end
;
334 gettimeofday(&start
, NULL
);
337 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH result.\n");
339 maxKeyLen
= SecDHGetMaxKeyLength(dhC
);
340 computed_key
= vmalloc(maxKeyLen
);
341 if (computed_key
== NULL
) {
342 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error.\n");
345 computed_keylen
= computed_key
->l
;
346 if (SecDHComputeKey(dhC
, pub_p
->v
+ (maxKeyLen
- publicKeySize
), publicKeySize
,
347 computed_key
->v
, &computed_keylen
)) {
348 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to compute dh value.\n");
353 gettimeofday(&end
, NULL
);
354 syslog(LOG_NOTICE
, "%s(%s%d): %8.6f", __func__
,
355 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
356 timedelta(&start
, &end
));
359 *gxy
= vmalloc(maxKeyLen
);
361 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error.\n");
364 memcpy((*gxy
)->v
+ (maxKeyLen
- computed_keylen
), computed_key
->v
, computed_keylen
);
365 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's shared.\n");
366 plogdump(LLV_DEBUG
, (*gxy
)->v
, (*gxy
)->l
);
381 * generate values of DH
387 oakley_dh_generate(dh
, pub
, priv
)
388 const struct dhgroup
*dh
;
389 vchar_t
**pub
, **priv
;
392 struct timeval start
, end
;
393 gettimeofday(&start
, NULL
);
396 case OAKLEY_ATTR_GRP_TYPE_MODP
:
397 if (eay_dh_generate(dh
->prime
, dh
->gen1
, dh
->gen2
, pub
, priv
) < 0) {
398 plog(LLV_ERROR
, LOCATION
, NULL
,
399 "failed to compute dh value.\n");
404 case OAKLEY_ATTR_GRP_TYPE_ECP
:
405 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
406 plog(LLV_ERROR
, LOCATION
, NULL
,
407 "dh type %d isn't supported.\n", dh
->type
);
410 plog(LLV_ERROR
, LOCATION
, NULL
,
411 "invalid dh type %d.\n", dh
->type
);
416 gettimeofday(&end
, NULL
);
417 syslog(LOG_NOTICE
, "%s(%s%d): %8.6f", __func__
,
418 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
419 timedelta(&start
, &end
));
422 if (oakley_check_dh_pub(dh
->prime
, pub
) != 0)
425 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's private.\n");
426 plogdump(LLV_DEBUG
, (*priv
)->v
, (*priv
)->l
);
427 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's public.\n");
428 plogdump(LLV_DEBUG
, (*pub
)->v
, (*pub
)->l
);
434 oakley_dh_generate(const struct dhgroup
*dh
, vchar_t
**pub
, size_t *publicKeySize
, SecDHContext
*dhC
)
436 vchar_t
*public = NULL
;
440 struct timeval start
, end
;
441 gettimeofday(&start
, NULL
);
444 plog(LLV_DEBUG
, LOCATION
, NULL
, "generate DH key pair.\n");
447 case OAKLEY_ATTR_GRP_TYPE_MODP
:
448 if (dh
->desc
!= OAKLEY_ATTR_GRP_DESC_MODP1024
&& dh
->desc
!= OAKLEY_ATTR_GRP_DESC_MODP1536
) {
449 plog(LLV_ERROR
, LOCATION
, NULL
, "Invalid dh group.\n");
452 if (SecDHCreate(dh
->desc
, dh
->prime
->v
, dh
->prime
->l
, 0, NULL
, 0, dhC
)) {
453 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to create dh context.\n");
456 maxKeyLen
= SecDHGetMaxKeyLength(*dhC
);
457 public = vmalloc(maxKeyLen
);
458 *publicKeySize
= public->l
;
459 if (public == NULL
) {
460 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error.\n");
463 if (SecDHGenerateKeypair(*dhC
, public->v
, publicKeySize
)) {
464 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to generate dh key pair.\n");
467 plog(LLV_DEBUG
, LOCATION
, NULL
, "got DH key pair.\n");
469 *pub
= vmalloc(maxKeyLen
);
471 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error.\n");
474 /* copy and fill with leading zeros */
475 memcpy((*pub
)->v
+ (maxKeyLen
- *publicKeySize
), public->v
, *publicKeySize
);
478 case OAKLEY_ATTR_GRP_TYPE_ECP
:
479 case OAKLEY_ATTR_GRP_TYPE_EC2N
:
480 plog(LLV_ERROR
, LOCATION
, NULL
,
481 "dh type %d isn't supported.\n", dh
->type
);
484 plog(LLV_ERROR
, LOCATION
, NULL
,
485 "invalid dh type %d.\n", dh
->type
);
490 gettimeofday(&end
, NULL
);
491 syslog(LOG_NOTICE
, "%s(%s%d): %8.6f", __func__
,
492 s_attr_isakmp_group(dh
->type
), dh
->prime
->l
<< 3,
493 timedelta(&start
, &end
));
496 if (oakley_check_dh_pub(dh
->prime
, pub
) != 0) {
497 plog(LLV_DEBUG
, LOCATION
, NULL
, "failed DH public key size check.\n");
501 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's private.\n");
502 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute DH's public.\n");
503 plogdump(LLV_DEBUG
, (*pub
)->v
, (*pub
)->l
);
518 * copy pre-defined dhgroup values.
521 oakley_setdhgroup(group
, dhgrp
)
523 struct dhgroup
**dhgrp
;
527 *dhgrp
= NULL
; /* just make sure, initialize */
529 g
= alg_oakley_dhdef_group(group
);
531 plog(LLV_ERROR
, LOCATION
, NULL
,
532 "invalid DH parameter grp=%d.\n", group
);
536 if (!g
->type
|| !g
->prime
|| !g
->gen1
) {
538 plog(LLV_ERROR
, LOCATION
, NULL
,
539 "unsupported DH parameters grp=%d.\n", group
);
543 *dhgrp
= racoon_calloc(1, sizeof(struct dhgroup
));
544 if (*dhgrp
== NULL
) {
545 plog(LLV_ERROR
, LOCATION
, NULL
,
546 "failed to get DH buffer.\n");
550 /* set defined dh vlaues */
551 memcpy(*dhgrp
, g
, sizeof(*g
));
552 (*dhgrp
)->prime
= vdup(g
->prime
);
560 * NOTE: we do not support prf with different input/output bitwidth,
561 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example) in
562 * oakley_compute_keymat(). If you add support for such prf function,
563 * modify oakley_compute_keymat() accordingly.
566 oakley_prf(key
, buf
, iph1
)
568 struct ph1handle
*iph1
;
573 if (iph1
->approval
== NULL
) {
575 * it's before negotiating hash algorithm.
576 * We use md5 as default.
578 type
= OAKLEY_ATTR_HASH_ALG_MD5
;
580 type
= iph1
->approval
->hashtype
;
582 res
= alg_oakley_hmacdef_one(type
, key
, buf
);
584 plog(LLV_ERROR
, LOCATION
, NULL
,
585 "invalid hmac algorithm %d.\n", type
);
596 oakley_hash(buf
, iph1
)
598 struct ph1handle
*iph1
;
603 if (iph1
->approval
== NULL
) {
605 * it's before negotiating hash algorithm.
606 * We use md5 as default.
608 type
= OAKLEY_ATTR_HASH_ALG_MD5
;
610 type
= iph1
->approval
->hashtype
;
612 res
= alg_oakley_hashdef_one(type
, buf
);
614 plog(LLV_ERROR
, LOCATION
, NULL
,
615 "invalid hash algorithm %d.\n", type
);
624 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
627 oakley_compute_keymat(iph2
, side
)
628 struct ph2handle
*iph2
;
633 /* compute sharing secret of DH when PFS */
634 if (iph2
->approval
->pfs_group
&& iph2
->dhpub_p
) {
636 if (oakley_dh_compute(iph2
->pfsgrp
, iph2
->dhpub
,
637 iph2
->dhpriv
, iph2
->dhpub_p
, &iph2
->dhgxy
) < 0)
639 if (oakley_dh_compute(iph2
->pfsgrp
, iph2
->dhpub_p
, iph2
->publicKeySize
, &iph2
->dhgxy
, iph2
->dhC
) < 0)
645 if (oakley_compute_keymat_x(iph2
, side
, INBOUND_SA
) < 0
646 || oakley_compute_keymat_x(iph2
, side
, OUTBOUND_SA
) < 0)
649 plog(LLV_DEBUG
, LOCATION
, NULL
, "KEYMAT computed.\n");
659 * KEYMAT = prf(SKEYID_d, protocol | SPI | Ni_b | Nr_b).
660 * If PFS is desired and KE payloads were exchanged,
661 * KEYMAT = prf(SKEYID_d, g(qm)^xy | protocol | SPI | Ni_b | Nr_b)
663 * NOTE: we do not support prf with different input/output bitwidth,
664 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example).
667 oakley_compute_keymat_x(iph2
, side
, sa_dir
)
668 struct ph2handle
*iph2
;
672 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
677 int dupkeymat
; /* generate K[1-dupkeymat] */
680 int encklen
, authklen
, l
;
682 pfs
= ((iph2
->approval
->pfs_group
&& iph2
->dhgxy
) ? 1 : 0);
684 len
= pfs
? iph2
->dhgxy
->l
: 0;
686 + sizeof(u_int32_t
) /* XXX SPI size */
691 plog(LLV_ERROR
, LOCATION
, NULL
,
692 "failed to get keymat buffer.\n");
696 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
701 memcpy(p
, iph2
->dhgxy
->v
, iph2
->dhgxy
->l
);
708 memcpy(p
, (sa_dir
== INBOUND_SA
? &pr
->spi
: &pr
->spi_p
),
710 p
+= sizeof(pr
->spi
);
712 bp
= (side
== INITIATOR
? iph2
->nonce
: iph2
->nonce_p
);
713 memcpy(p
, bp
->v
, bp
->l
);
716 bp
= (side
== INITIATOR
? iph2
->nonce_p
: iph2
->nonce
);
717 memcpy(p
, bp
->v
, bp
->l
);
721 plog(LLV_DEBUG
, LOCATION
, NULL
, "KEYMAT compute with\n");
722 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
725 res
= oakley_prf(iph2
->ph1
->skeyid_d
, buf
, iph2
->ph1
);
729 /* compute key length needed */
730 encklen
= authklen
= 0;
731 switch (pr
->proto_id
) {
732 case IPSECDOI_PROTO_IPSEC_ESP
:
733 for (tr
= pr
->head
; tr
; tr
= tr
->next
) {
734 l
= alg_ipsec_encdef_keylen(tr
->trns_id
,
739 l
= alg_ipsec_hmacdef_hashlen(tr
->authtype
);
744 case IPSECDOI_PROTO_IPSEC_AH
:
745 for (tr
= pr
->head
; tr
; tr
= tr
->next
) {
746 l
= alg_ipsec_hmacdef_hashlen(tr
->trns_id
);
754 plog(LLV_DEBUG
, LOCATION
, NULL
, "encklen=%d authklen=%d\n",
757 dupkeymat
= (encklen
+ authklen
) / 8 / res
->l
;
758 dupkeymat
+= 2; /* safety mergin */
761 plog(LLV_DEBUG
, LOCATION
, NULL
,
762 "generating %zu bits of key (dupkeymat=%d)\n",
763 dupkeymat
* 8 * res
->l
, dupkeymat
);
764 if (0 < --dupkeymat
) {
765 vchar_t
*prev
= res
; /* K(n-1) */
766 vchar_t
*seed
= NULL
; /* seed for Kn */
770 * generating long key (isakmp-oakley-08 5.5)
771 * KEYMAT = K1 | K2 | K3 | ...
773 * src = [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b
774 * K1 = prf(SKEYID_d, src)
775 * K2 = prf(SKEYID_d, K1 | src)
776 * K3 = prf(SKEYID_d, K2 | src)
777 * Kn = prf(SKEYID_d, K(n-1) | src)
779 plog(LLV_DEBUG
, LOCATION
, NULL
,
780 "generating K1...K%d for KEYMAT.\n",
783 seed
= vmalloc(prev
->l
+ buf
->l
);
785 plog(LLV_ERROR
, LOCATION
, NULL
,
786 "failed to get keymat buffer.\n");
787 if (prev
&& prev
!= res
)
792 while (dupkeymat
--) {
793 vchar_t
*this = NULL
; /* Kn */
796 memcpy(seed
->v
, prev
->v
, prev
->l
);
797 memcpy(seed
->v
+ prev
->l
, buf
->v
, buf
->l
);
798 this = oakley_prf(iph2
->ph1
->skeyid_d
, seed
,
801 plog(LLV_ERROR
, LOCATION
, NULL
,
802 "oakley_prf memory overflow\n");
803 if (prev
&& prev
!= res
)
810 update_prev
= (prev
&& prev
== res
) ? 1 : 0;
813 res
= vrealloc(res
, l
+ this->l
);
819 plog(LLV_ERROR
, LOCATION
, NULL
,
820 "failed to get keymat buffer.\n");
821 if (prev
&& prev
!= res
)
827 memcpy(res
->v
+ l
, this->v
, this->l
);
829 if (prev
&& prev
!= res
)
835 if (prev
&& prev
!= res
)
840 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
842 if (sa_dir
== INBOUND_SA
)
853 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
875 * NOTE: Must terminate by NULL.
878 oakley_compute_hashx(struct ph1handle
*iph1
, ...)
887 /* get buffer length */
890 while ((s
= va_arg(ap
, vchar_t
*)) != NULL
) {
897 plog(LLV_ERROR
, LOCATION
, NULL
,
898 "failed to get hash buffer\n");
905 while ((s
= va_arg(ap
, char *)) != NULL
) {
906 memcpy(p
, s
->v
, s
->l
);
911 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with: \n");
912 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
915 res
= oakley_prf(iph1
->skeyid_a
, buf
, iph1
);
920 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH computed:\n");
921 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
928 * compute HASH(3) prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
929 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
932 oakley_compute_hash3(iph1
, msgid
, body
)
933 struct ph1handle
*iph1
;
937 vchar_t
*buf
= 0, *res
= 0;
942 len
= 1 + sizeof(u_int32_t
) + body
->l
;
945 plog(LLV_DEBUG
, LOCATION
, NULL
,
946 "failed to get hash buffer\n");
952 memcpy(buf
->v
+ 1, (char *)&msgid
, sizeof(msgid
));
954 memcpy(buf
->v
+ 1 + sizeof(u_int32_t
), body
->v
, body
->l
);
956 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with: \n");
957 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
960 res
= oakley_prf(iph1
->skeyid_a
, buf
, iph1
);
966 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH computed:\n");
967 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
976 * compute HASH type of prf(SKEYID_a, M-ID | buffer)
978 * for quick mode HASH(1):
979 * prf(SKEYID_a, M-ID | SA | Ni [ | KE ] [ | IDci | IDcr ])
980 * for quick mode HASH(2):
981 * prf(SKEYID_a, M-ID | Ni_b | SA | Nr [ | KE ] [ | IDci | IDcr ])
982 * for Informational exchange:
983 * prf(SKEYID_a, M-ID | N/D)
986 oakley_compute_hash1(iph1
, msgid
, body
)
987 struct ph1handle
*iph1
;
991 vchar_t
*buf
= NULL
, *res
= NULL
;
997 len
= sizeof(u_int32_t
) + body
->l
;
1000 plog(LLV_DEBUG
, LOCATION
, NULL
,
1001 "failed to get hash buffer\n");
1007 memcpy(buf
->v
, (char *)&msgid
, sizeof(msgid
));
1008 p
+= sizeof(u_int32_t
);
1010 memcpy(p
, body
->v
, body
->l
);
1012 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with:\n");
1013 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
1016 res
= oakley_prf(iph1
->skeyid_a
, buf
, iph1
);
1022 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH computed:\n");
1023 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
1032 * compute phase1 HASH
1034 * I-digest = prf(SKEYID, g^i | g^r | CKY-I | CKY-R | SAi_b | ID_i1_b)
1035 * R-digest = prf(SKEYID, g^r | g^i | CKY-R | CKY-I | SAi_b | ID_r1_b)
1036 * for gssapi, also include all GSS tokens, and call gss_wrap on the result
1039 oakley_ph1hash_common(iph1
, sw
)
1040 struct ph1handle
*iph1
;
1043 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
1048 vchar_t
*gsstokens
= NULL
;
1052 len
= iph1
->dhpub
->l
1054 + sizeof(cookie_t
) * 2
1056 + (sw
== GENERATE
? iph1
->id
->l
: iph1
->id_p
->l
);
1059 if (AUTHMETHOD(iph1
) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
) {
1060 if (iph1
->gi_i
!= NULL
&& iph1
->gi_r
!= NULL
) {
1061 bp
= (sw
== GENERATE
? iph1
->gi_i
: iph1
->gi_r
);
1065 gssapi_get_itokens(iph1
, &gsstokens
);
1067 gssapi_get_rtokens(iph1
, &gsstokens
);
1068 if (gsstokens
== NULL
)
1070 len
+= gsstokens
->l
;
1076 plog(LLV_ERROR
, LOCATION
, NULL
,
1077 "failed to get hash buffer\n");
1083 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
1084 memcpy(p
, bp
->v
, bp
->l
);
1087 bp
= (sw
== GENERATE
? iph1
->dhpub_p
: iph1
->dhpub
);
1088 memcpy(p
, bp
->v
, bp
->l
);
1091 if (iph1
->side
== INITIATOR
)
1092 bp2
= (sw
== GENERATE
?
1093 (char *)&iph1
->index
.i_ck
: (char *)&iph1
->index
.r_ck
);
1095 bp2
= (sw
== GENERATE
?
1096 (char *)&iph1
->index
.r_ck
: (char *)&iph1
->index
.i_ck
);
1097 bl
= sizeof(cookie_t
);
1101 if (iph1
->side
== INITIATOR
)
1102 bp2
= (sw
== GENERATE
?
1103 (char *)&iph1
->index
.r_ck
: (char *)&iph1
->index
.i_ck
);
1105 bp2
= (sw
== GENERATE
?
1106 (char *)&iph1
->index
.i_ck
: (char *)&iph1
->index
.r_ck
);
1107 bl
= sizeof(cookie_t
);
1112 memcpy(p
, bp
->v
, bp
->l
);
1115 bp
= (sw
== GENERATE
? iph1
->id
: iph1
->id_p
);
1116 memcpy(p
, bp
->v
, bp
->l
);
1120 if (AUTHMETHOD(iph1
) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
) {
1121 if (iph1
->gi_i
!= NULL
&& iph1
->gi_r
!= NULL
) {
1122 bp
= (sw
== GENERATE
? iph1
->gi_i
: iph1
->gi_r
);
1123 memcpy(p
, bp
->v
, bp
->l
);
1126 memcpy(p
, gsstokens
->v
, gsstokens
->l
);
1131 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH with:\n");
1132 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
1135 res
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
1141 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH (%s) computed:\n",
1142 iph1
->side
== INITIATOR
? "init" : "resp");
1143 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
1149 if (gsstokens
!= NULL
)
1156 * compute HASH_I on base mode.
1158 * HASH_I = prf(SKEYID, g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
1160 * HASH_I = prf(hash(Ni_b | Nr_b), g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
1163 oakley_ph1hash_base_i(iph1
, sw
)
1164 struct ph1handle
*iph1
;
1167 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
1168 vchar_t
*hashkey
= NULL
;
1169 vchar_t
*hash
= NULL
; /* for signature mode */
1175 if (iph1
->etype
!= ISAKMP_ETYPE_BASE
) {
1176 plog(LLV_ERROR
, LOCATION
, NULL
,
1177 "invalid etype for this hash function\n");
1181 switch (AUTHMETHOD(iph1
)) {
1182 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
1183 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
1184 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
1185 #ifdef ENABLE_HYBRID
1186 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
1187 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
1188 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
1189 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
1190 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
1191 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
1193 if (iph1
->skeyid
== NULL
) {
1194 plog(LLV_ERROR
, LOCATION
, NULL
, "no SKEYID found.\n");
1197 hashkey
= iph1
->skeyid
;
1200 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
1201 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1203 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
1205 #ifdef ENABLE_HYBRID
1206 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1207 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1208 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1209 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
1210 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
1211 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1212 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
1213 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
1215 /* make hash for seed */
1216 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
1219 plog(LLV_ERROR
, LOCATION
, NULL
,
1220 "failed to get hash buffer\n");
1225 bp
= (sw
== GENERATE
? iph1
->nonce_p
: iph1
->nonce
);
1226 memcpy(p
, bp
->v
, bp
->l
);
1229 bp
= (sw
== GENERATE
? iph1
->nonce
: iph1
->nonce_p
);
1230 memcpy(p
, bp
->v
, bp
->l
);
1233 hash
= oakley_hash(buf
, iph1
);
1243 plog(LLV_ERROR
, LOCATION
, NULL
,
1244 "not supported authentication method %d\n",
1245 iph1
->approval
->authmethod
);
1250 len
= (sw
== GENERATE
? iph1
->dhpub
->l
: iph1
->dhpub_p
->l
)
1251 + sizeof(cookie_t
) * 2
1253 + (sw
== GENERATE
? iph1
->id
->l
: iph1
->id_p
->l
);
1256 plog(LLV_ERROR
, LOCATION
, NULL
,
1257 "failed to get hash buffer\n");
1262 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
1263 memcpy(p
, bp
->v
, bp
->l
);
1266 memcpy(p
, &iph1
->index
.i_ck
, sizeof(cookie_t
));
1267 p
+= sizeof(cookie_t
);
1268 memcpy(p
, &iph1
->index
.r_ck
, sizeof(cookie_t
));
1269 p
+= sizeof(cookie_t
);
1271 memcpy(p
, iph1
->sa
->v
, iph1
->sa
->l
);
1274 bp
= (sw
== GENERATE
? iph1
->id
: iph1
->id_p
);
1275 memcpy(p
, bp
->v
, bp
->l
);
1278 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH_I with:\n");
1279 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
1282 res
= oakley_prf(hashkey
, buf
, iph1
);
1288 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH_I computed:\n");
1289 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
1300 * compute HASH_R on base mode for signature method.
1302 * HASH_R = prf(hash(Ni_b | Nr_b), g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b)
1305 oakley_ph1hash_base_r(iph1
, sw
)
1306 struct ph1handle
*iph1
;
1309 vchar_t
*buf
= NULL
, *res
= NULL
, *bp
;
1310 vchar_t
*hash
= NULL
;
1316 if (iph1
->etype
!= ISAKMP_ETYPE_BASE
) {
1317 plog(LLV_ERROR
, LOCATION
, NULL
,
1318 "invalid etype for this hash function\n");
1322 switch(AUTHMETHOD(iph1
)) {
1323 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
1324 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1325 #ifdef ENABLE_HYBRID
1326 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1327 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1328 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1329 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
1330 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
1331 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1332 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
1333 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
1334 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
1338 plog(LLV_ERROR
, LOCATION
, NULL
,
1339 "not supported authentication method %d\n",
1340 iph1
->approval
->authmethod
);
1345 /* make hash for seed */
1346 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
1349 plog(LLV_ERROR
, LOCATION
, NULL
,
1350 "failed to get hash buffer\n");
1355 bp
= (sw
== GENERATE
? iph1
->nonce_p
: iph1
->nonce
);
1356 memcpy(p
, bp
->v
, bp
->l
);
1359 bp
= (sw
== GENERATE
? iph1
->nonce
: iph1
->nonce_p
);
1360 memcpy(p
, bp
->v
, bp
->l
);
1363 hash
= oakley_hash(buf
, iph1
);
1369 /* make really hash */
1370 len
= (sw
== GENERATE
? iph1
->dhpub_p
->l
: iph1
->dhpub
->l
)
1371 + (sw
== GENERATE
? iph1
->dhpub
->l
: iph1
->dhpub_p
->l
)
1372 + sizeof(cookie_t
) * 2
1374 + (sw
== GENERATE
? iph1
->id_p
->l
: iph1
->id
->l
);
1377 plog(LLV_ERROR
, LOCATION
, NULL
,
1378 "failed to get hash buffer\n");
1384 bp
= (sw
== GENERATE
? iph1
->dhpub_p
: iph1
->dhpub
);
1385 memcpy(p
, bp
->v
, bp
->l
);
1388 bp
= (sw
== GENERATE
? iph1
->dhpub
: iph1
->dhpub_p
);
1389 memcpy(p
, bp
->v
, bp
->l
);
1392 memcpy(p
, &iph1
->index
.i_ck
, sizeof(cookie_t
));
1393 p
+= sizeof(cookie_t
);
1394 memcpy(p
, &iph1
->index
.r_ck
, sizeof(cookie_t
));
1395 p
+= sizeof(cookie_t
);
1397 memcpy(p
, iph1
->sa
->v
, iph1
->sa
->l
);
1400 bp
= (sw
== GENERATE
? iph1
->id_p
: iph1
->id
);
1401 memcpy(p
, bp
->v
, bp
->l
);
1404 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH_R with:\n");
1405 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
1408 res
= oakley_prf(hash
, buf
, iph1
);
1414 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH_R computed:\n");
1415 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
1427 oakley_verify_userid(iph1
)
1428 struct ph1handle
*iph1
;
1432 int user_id_found
= 0;
1434 for (p
= iph1
->cert_p
; p
; p
= p
->chain
) {
1435 user_id
= eay_get_x509_common_name(&p
->cert
);
1438 // the following functions will check if user_id == 0
1439 if (open_dir_authorize_id(user_id
, iph1
->rmconf
->open_dir_auth_group
)) {
1446 if (user_id_found
) {
1447 plog(LLV_ERROR
, LOCATION
, NULL
,
1448 "the peer is not authorized for access.\n");
1450 plog(LLV_ERROR
, LOCATION
, NULL
,
1451 "the peer is not authorized for access - user ID not found.\n");
1453 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1455 #endif /* HAVE_OPENDIR */
1459 oakley_verify_x509sign(certchain
, my_hash
, my_sig
)
1467 for (p
= certchain
; p
; p
= p
->chain
) {
1468 if ((result
= eay_check_x509sign(my_hash
,
1479 oakley_check_x509cert(certchain
, capath
, cafile
, local
)
1488 for (p
= certchain
; p
; p
= p
->chain
) {
1489 if ((result
= eay_check_x509cert(&p
->cert
,
1498 #endif /* HAVE_OPENSSL */
1501 * compute each authentication method in phase 1.
1505 * other: error to be reply with notification.
1506 * the value is notification type.
1509 oakley_validate_auth(iph1
)
1510 struct ph1handle
*iph1
;
1512 vchar_t
*my_hash
= NULL
;
1515 vchar_t
*gsshash
= NULL
;
1518 struct timeval start
, end
;
1520 #if TARGET_OS_EMBEDDED
1521 SecKeyRef publicKeyRef
;
1525 gettimeofday(&start
, NULL
);
1528 switch (AUTHMETHOD(iph1
)) {
1529 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
1530 #ifdef ENABLE_HYBRID
1531 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
1532 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
1538 if (iph1
->id_p
== NULL
|| iph1
->pl_hash
== NULL
) {
1539 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1540 "few isakmp message received.\n");
1541 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1543 #ifdef ENABLE_HYBRID
1544 if (AUTHMETHOD(iph1
) == FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
&&
1545 ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_VENDORID_XAUTH
) == 0))
1547 plog(LLV_ERROR
, LOCATION
, NULL
, "No SIG was passed, "
1548 "hybrid auth is enabled, "
1549 "but peer is no Xauth compliant\n");
1550 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED
;
1554 r_hash
= (caddr_t
)(iph1
->pl_hash
+ 1);
1556 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH received:\n");
1557 plogdump(LLV_DEBUG
, r_hash
,
1558 ntohs(iph1
->pl_hash
->h
.len
) - sizeof(*iph1
->pl_hash
));
1560 switch (iph1
->etype
) {
1561 case ISAKMP_ETYPE_IDENT
:
1562 case ISAKMP_ETYPE_AGG
:
1563 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1565 case ISAKMP_ETYPE_BASE
:
1566 if (iph1
->side
== INITIATOR
)
1567 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1569 my_hash
= oakley_ph1hash_base_i(iph1
, VALIDATE
);
1572 plog(LLV_ERROR
, LOCATION
, NULL
,
1573 "invalid etype %d\n", iph1
->etype
);
1574 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1576 if (my_hash
== NULL
)
1577 return ISAKMP_INTERNAL_ERROR
;
1579 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1583 plog(LLV_ERROR
, LOCATION
, NULL
, "HASH mismatched\n");
1584 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1587 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH for PSK validated.\n");
1590 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
1591 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1592 #ifdef ENABLE_HYBRID
1593 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1594 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1595 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
1596 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1597 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
1598 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
1605 if (iph1
->id_p
== NULL
) {
1606 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1607 "no ID payload was passed.\n");
1608 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1610 if (iph1
->sig_p
== NULL
) {
1611 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1612 "no SIG payload was passed.\n");
1613 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1616 plog(LLV_DEBUG
, LOCATION
, NULL
, "SIGN passed:\n");
1617 plogdump(LLV_DEBUG
, iph1
->sig_p
->v
, iph1
->sig_p
->l
);
1619 /* get peer's cert */
1620 switch (iph1
->rmconf
->getcert_method
) {
1621 case ISAKMP_GETCERT_PAYLOAD
:
1622 if (iph1
->cert_p
== NULL
) {
1623 plog(LLV_ERROR
, LOCATION
, NULL
,
1624 "no peer's CERT payload found.\n");
1625 return ISAKMP_INTERNAL_ERROR
;
1629 case ISAKMP_GETCERT_LOCALFILE
:
1630 switch (iph1
->rmconf
->certtype
) {
1631 case ISAKMP_CERT_X509SIGN
:
1632 if (iph1
->rmconf
->peerscertfile
== NULL
) {
1633 plog(LLV_ERROR
, LOCATION
, NULL
,
1634 "no peer's CERT file found.\n");
1635 return ISAKMP_INTERNAL_ERROR
;
1638 /* don't use cached cert */
1639 if (iph1
->cert_p
!= NULL
) {
1640 oakley_delcert(iph1
->cert_p
);
1641 iph1
->cert_p
= NULL
;
1644 error
= get_cert_fromlocal(iph1
, 0);
1647 case ISAKMP_CERT_PLAINRSA
:
1648 error
= get_plainrsa_fromlocal(iph1
, 0);
1652 return ISAKMP_INTERNAL_ERROR
;
1655 case ISAKMP_GETCERT_DNS
:
1656 if (iph1
->rmconf
->peerscertfile
!= NULL
) {
1657 plog(LLV_ERROR
, LOCATION
, NULL
,
1658 "why peer's CERT file is defined "
1659 "though getcert method is dns ?\n");
1660 return ISAKMP_INTERNAL_ERROR
;
1663 /* don't use cached cert */
1664 if (iph1
->cert_p
!= NULL
) {
1665 oakley_delcert(iph1
->cert_p
);
1666 iph1
->cert_p
= NULL
;
1669 iph1
->cert_p
= dnssec_getcert(iph1
->id_p
);
1670 if (iph1
->cert_p
== NULL
) {
1671 plog(LLV_ERROR
, LOCATION
, NULL
,
1672 "no CERT RR found.\n");
1673 return ISAKMP_INTERNAL_ERROR
;
1677 plog(LLV_ERROR
, LOCATION
, NULL
,
1678 "invalid getcert_mothod: %d\n",
1679 iph1
->rmconf
->getcert_method
);
1680 return ISAKMP_INTERNAL_ERROR
;
1683 /* compare ID payload and certificate name */
1684 if (iph1
->rmconf
->verify_cert
&&
1685 (error
= oakley_check_certid(iph1
, CERT_CHECKID_FROM_PEER
)) != 0)
1688 /* check configured peers identifier against cert IDs */
1689 /* allows checking of specified ID against multiple ids in the cert */
1690 /* such as multiple domain names */
1691 #if !TARGET_OS_EMBEDDED
1692 if (iph1
->rmconf
->cert_verification_option
== VERIFICATION_OPTION_PEERS_IDENTIFIER
&&
1693 (error
= oakley_check_certid(iph1
, CERT_CHECKID_FROM_RMCONFIG
)) != 0)
1698 /* check cert common name against Open Directory authentication group */
1699 if (iph1
->rmconf
->cert_verification_option
== VERIFICATION_OPTION_OPEN_DIR
) {
1700 if (oakley_verify_userid(iph1
)) {
1701 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1704 #endif /* HAVE_OPENDIR */
1706 /* verify certificate */
1707 if (iph1
->rmconf
->verify_cert
1708 && iph1
->rmconf
->getcert_method
== ISAKMP_GETCERT_PAYLOAD
) {
1709 certtype
= iph1
->rmconf
->certtype
;
1710 #ifdef ENABLE_HYBRID
1711 switch (AUTHMETHOD(iph1
)) {
1712 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1713 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1714 certtype
= iph1
->cert_p
->type
;
1721 case ISAKMP_CERT_X509SIGN
:
1723 #if TARGET_OS_EMBEDDED
1725 /* use ID from remote configuration */
1726 /* check each ID in list */
1727 struct idspec
*id_spec
;
1728 CFStringRef hostname
= NULL
;
1730 struct genlist_entry
*gpb
= NULL
;
1732 if (iph1
->rmconf
->cert_verification_option
== VERIFICATION_OPTION_PEERS_IDENTIFIER
) {
1733 id_spec
= genlist_next(iph1
->rmconf
->idvl_p
, &gpb
); /* expect only one id */
1734 if (id_spec
->idtype
== IDTYPE_ADDRESS
) {
1735 switch (((struct sockaddr
*)(id_spec
->id
->v
))->sa_family
) {
1737 peers_id
= inet_ntoa(((struct sockaddr_in
*)(id_spec
->id
->v
))->sin_addr
);
1738 hostname
= CFStringCreateWithCString(NULL
, peers_id
, kCFStringEncodingUTF8
);
1742 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
; /* not currently supported for embedded */
1746 plog(LLV_ERROR
, LOCATION
, NULL
,
1747 "unknown address type for peers identifier.\n");
1748 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
1752 hostname
= CFStringCreateWithBytes(NULL
, (u_int8_t
*)id_spec
->id
->v
, id_spec
->id
->l
, kCFStringEncodingUTF8
, FALSE
);
1754 error
= crypto_cssm_check_x509cert(oakley_get_peer_cert_from_certchain(iph1
), iph1
->cert_p
, hostname
, &publicKeyRef
);
1756 CFRelease(hostname
);
1759 #else /* TARGET_OS_EMBEDDED */
1760 if (iph1
->rmconf
->cert_verification
== VERIFICATION_MODULE_SEC_FRAMEWORK
)
1761 error
= crypto_cssm_check_x509cert(oakley_get_peer_cert_from_certchain(iph1
),
1766 char path
[MAXPATHLEN
];
1769 if (iph1
->rmconf
->cacertfile
!= NULL
) {
1770 getpathname(path
, sizeof(path
),
1772 iph1
->rmconf
->cacertfile
);
1778 error
= oakley_check_x509cert(iph1
->cert_p
,
1779 lcconf
->pathinfo
[LC_PATHTYPE_CERT
],
1782 #endif /* TARGET_OS_EMBEDDED */
1786 plog(LLV_ERROR
, LOCATION
, NULL
,
1787 "no supported certtype %d\n", certtype
);
1788 return ISAKMP_INTERNAL_ERROR
;
1791 plog(LLV_ERROR
, LOCATION
, NULL
,
1792 "the peer's certificate is not verified.\n");
1793 return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY
;
1797 plog(LLV_DEBUG
, LOCATION
, NULL
, "CERT validated\n");
1800 switch (iph1
->etype
) {
1801 case ISAKMP_ETYPE_IDENT
:
1802 case ISAKMP_ETYPE_AGG
:
1803 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1805 case ISAKMP_ETYPE_BASE
:
1806 if (iph1
->side
== INITIATOR
)
1807 my_hash
= oakley_ph1hash_base_r(iph1
, VALIDATE
);
1809 my_hash
= oakley_ph1hash_base_i(iph1
, VALIDATE
);
1812 plog(LLV_ERROR
, LOCATION
, NULL
,
1813 "invalid etype %d\n", iph1
->etype
);
1814 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1816 if (my_hash
== NULL
)
1817 return ISAKMP_INTERNAL_ERROR
;
1820 certtype
= iph1
->rmconf
->certtype
;
1821 #ifdef ENABLE_HYBRID
1822 switch (AUTHMETHOD(iph1
)) {
1823 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
1824 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
1825 certtype
= iph1
->cert_p
->type
;
1831 /* check signature */
1833 case ISAKMP_CERT_X509SIGN
:
1834 case ISAKMP_CERT_DNS
:
1835 #if TARGET_OS_EMBEDDED
1836 error
= crypto_cssm_verify_x509sign(publicKeyRef
, my_hash
, iph1
->sig_p
);
1838 plog(LLV_ERROR
, LOCATION
, NULL
, "error verifying signature %s\n", GetSecurityErrorString(error
));
1840 CFRelease(publicKeyRef
);
1842 error
= oakley_verify_x509sign(iph1
->cert_p
, my_hash
, iph1
->sig_p
);
1846 case ISAKMP_CERT_PLAINRSA
:
1847 iph1
->rsa_p
= rsa_try_check_rsasign(my_hash
,
1848 iph1
->sig_p
, iph1
->rsa_candidates
);
1849 error
= iph1
->rsa_p
? 0 : -1;
1854 plog(LLV_ERROR
, LOCATION
, NULL
,
1855 "no supported certtype %d\n",
1858 return ISAKMP_INTERNAL_ERROR
;
1863 plog(LLV_ERROR
, LOCATION
, NULL
,
1865 return ISAKMP_NTYPE_INVALID_SIGNATURE
;
1867 plog(LLV_DEBUG
, LOCATION
, NULL
, "SIG authenticated\n");
1870 #ifdef ENABLE_HYBRID
1871 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1872 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
1874 if ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_VENDORID_XAUTH
) == 0) {
1875 plog(LLV_ERROR
, LOCATION
, NULL
, "No SIG was passed, "
1876 "hybrid auth is enabled, "
1877 "but peer is no Xauth compliant\n");
1878 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED
;
1881 plog(LLV_INFO
, LOCATION
, NULL
, "No SIG was passed, "
1882 "but hybrid auth is enabled\n");
1889 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
1890 /* check if we're not into XAUTH_PSKEY_I instead */
1891 #ifdef ENABLE_HYBRID
1892 if (iph1
->rmconf
->xauth
)
1895 switch (iph1
->etype
) {
1896 case ISAKMP_ETYPE_IDENT
:
1897 case ISAKMP_ETYPE_AGG
:
1898 my_hash
= oakley_ph1hash_common(iph1
, VALIDATE
);
1901 plog(LLV_ERROR
, LOCATION
, NULL
,
1902 "invalid etype %d\n", iph1
->etype
);
1903 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1906 if (my_hash
== NULL
) {
1907 if (gssapi_more_tokens(iph1
))
1908 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
;
1910 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1913 gsshash
= gssapi_unwraphash(iph1
);
1914 if (gsshash
== NULL
) {
1916 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1919 result
= memcmp(my_hash
->v
, gsshash
->v
, my_hash
->l
);
1924 plog(LLV_ERROR
, LOCATION
, NULL
, "HASH mismatched\n");
1925 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1927 plog(LLV_DEBUG
, LOCATION
, NULL
, "hash compared OK\n");
1930 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
1931 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
1932 #ifdef ENABLE_HYBRID
1933 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
1934 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
1935 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
1936 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
1938 if (iph1
->id_p
== NULL
|| iph1
->pl_hash
== NULL
) {
1939 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1940 "few isakmp message received.\n");
1941 return ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1943 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1944 "not supported authmethod type %s\n",
1945 s_oakley_attr_method(iph1
->approval
->authmethod
));
1946 return ISAKMP_INTERNAL_ERROR
;
1948 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1949 "invalid authmethod %d why ?\n",
1950 iph1
->approval
->authmethod
);
1951 return ISAKMP_INTERNAL_ERROR
;
1954 gettimeofday(&end
, NULL
);
1955 syslog(LOG_NOTICE
, "%s(%s): %8.6f", __func__
,
1956 s_oakley_attr_method(iph1
->approval
->authmethod
),
1957 timedelta(&start
, &end
));
1964 oakley_find_status_in_certchain (cert_t
*certchain
, cert_status_t certStatus
)
1968 for (p
= certchain
; p
; p
= p
->chain
) {
1969 if (p
->status
== certStatus
) {
1978 oakley_vpncontrol_notify_ike_failed_if_mycert_invalid (struct ph1handle
*iph1
,
1979 int notify_initiator
)
1981 #if TARGET_OS_EMBEDDED
1982 int premature
= oakley_find_status_in_certchain(iph1
->cert
, CERT_STATUS_PREMATURE
);
1983 int expired
= oakley_find_status_in_certchain(iph1
->cert
, CERT_STATUS_EXPIRED
);
1984 if (premature
|| expired
) {
1986 u_int32_t fail_reason
;
1988 if (iph1
->remote
->sa_family
== AF_INET
)
1989 address
= ((struct sockaddr_in
*)(iph1
->remote
))->sin_addr
.s_addr
;
1993 fail_reason
= VPNCTL_NTYPE_LOCAL_CERT_PREMATURE
;
1995 fail_reason
= VPNCTL_NTYPE_LOCAL_CERT_EXPIRED
;
1997 vpncontrol_notify_ike_failed(fail_reason
, notify_initiator
, address
, 0, NULL
);
2000 #endif /* TARGET_OS_EMBEDDED */
2004 /* get my certificate
2005 * NOTE: include certificate type.
2008 oakley_getmycert(iph1
)
2009 struct ph1handle
*iph1
;
2014 switch (iph1
->rmconf
->certtype
) {
2015 case ISAKMP_CERT_X509SIGN
:
2018 if ( !(err
= get_cert_fromlocal(iph1
, 1))){
2019 if (oakley_vpncontrol_notify_ike_failed_if_mycert_invalid(iph1
, FROM_LOCAL
)) {
2025 case ISAKMP_CERT_PLAINRSA
:
2028 return get_plainrsa_fromlocal(iph1
, 1);
2031 plog(LLV_ERROR
, LOCATION
, NULL
,
2032 "Unknown certtype #%d\n",
2033 iph1
->rmconf
->certtype
);
2040 * get a CERT from local file.
2043 * my == 0 peer's cert.
2046 get_cert_fromlocal(iph1
, my
)
2047 struct ph1handle
*iph1
;
2050 char path
[MAXPATHLEN
];
2051 vchar_t
*cert
= NULL
;
2055 cert_status_t status
= CERT_STATUS_OK
;
2058 certfile
= iph1
->rmconf
->mycertfile
;
2059 certpl
= &iph1
->cert
;
2061 certfile
= iph1
->rmconf
->peerscertfile
;
2062 certpl
= &iph1
->cert_p
;
2064 if (!certfile
&& iph1
->rmconf
->identity_in_keychain
== 0) {
2065 plog(LLV_ERROR
, LOCATION
, NULL
, "no CERT defined.\n");
2069 switch (iph1
->rmconf
->certtype
) {
2070 case ISAKMP_CERT_X509SIGN
:
2071 if (iph1
->rmconf
->identity_in_keychain
) {
2074 if (iph1
->rmconf
->keychainCertRef
== NULL
|| base64toCFData(iph1
->rmconf
->keychainCertRef
, &dataRef
))
2076 cert
= crypto_cssm_get_x509cert(dataRef
, &status
);
2077 plog(LLV_DEBUG
, LOCATION
, NULL
, "done with chking cert status %d\n",status
);
2082 case ISAKMP_CERT_DNS
:
2083 /* make public file name */
2084 getpathname(path
, sizeof(path
), LC_PATHTYPE_CERT
, certfile
);
2085 cert
= eay_get_x509cert(path
);
2087 oakley_cert_prettyprint(cert
);
2092 plog(LLV_ERROR
, LOCATION
, NULL
,
2093 "not supported certtype %d\n",
2094 iph1
->rmconf
->certtype
);
2099 plog(LLV_ERROR
, LOCATION
, NULL
,
2100 "failed to get %s CERT.\n",
2101 my
? "my" : "peers");
2105 *certpl
= oakley_newcert();
2107 plog(LLV_ERROR
, LOCATION
, NULL
,
2108 "failed to get cert buffer.\n");
2111 (*certpl
)->pl
= vmalloc(cert
->l
+ 1);
2112 if ((*certpl
)->pl
== NULL
) {
2113 plog(LLV_ERROR
, LOCATION
, NULL
,
2114 "failed to get cert buffer\n");
2115 oakley_delcert(*certpl
);
2119 memcpy((*certpl
)->pl
->v
+ 1, cert
->v
, cert
->l
);
2120 (*certpl
)->pl
->v
[0] = iph1
->rmconf
->certtype
;
2121 (*certpl
)->type
= iph1
->rmconf
->certtype
;
2122 (*certpl
)->status
= status
;
2123 (*certpl
)->cert
.v
= (*certpl
)->pl
->v
+ 1;
2124 (*certpl
)->cert
.l
= (*certpl
)->pl
->l
- 1;
2126 plog(LLV_DEBUG
, LOCATION
, NULL
, "created CERT payload:\n");
2127 plogdump(LLV_DEBUG
, (*certpl
)->pl
->v
, (*certpl
)->pl
->l
);
2128 oakley_cert_prettyprint(cert
);
2141 get_plainrsa_fromlocal(iph1
, my
)
2142 struct ph1handle
*iph1
;
2145 char path
[MAXPATHLEN
];
2146 vchar_t
*cert
= NULL
;
2150 iph1
->rsa_candidates
= rsa_lookup_keys(iph1
, my
);
2151 if (!iph1
->rsa_candidates
||
2152 rsa_list_count(iph1
->rsa_candidates
) == 0) {
2153 plog(LLV_ERROR
, LOCATION
, NULL
,
2154 "%s RSA key not found for %s\n",
2155 my
? "Private" : "Public",
2156 saddr2str_fromto("%s <-> %s",
2157 iph1
->local
, iph1
->remote
));
2161 if (my
&& rsa_list_count(iph1
->rsa_candidates
) > 1) {
2162 plog(LLV_WARNING
, LOCATION
, NULL
,
2163 "More than one (=%lu) private "
2164 "PlainRSA key found for %s\n",
2165 rsa_list_count(iph1
->rsa_candidates
),
2166 saddr2str_fromto("%s <-> %s",
2167 iph1
->local
, iph1
->remote
));
2168 plog(LLV_WARNING
, LOCATION
, NULL
,
2169 "This may have unpredictable results, "
2170 "i.e. wrong key could be used!\n");
2171 plog(LLV_WARNING
, LOCATION
, NULL
,
2172 "Consider using only one single private "
2173 "key for all peers...\n");
2176 iph1
->rsa
= ((struct rsa_key
*)
2177 genlist_next(iph1
->rsa_candidates
, NULL
))->rsa
;
2179 genlist_free(iph1
->rsa_candidates
, NULL
);
2180 iph1
->rsa_candidates
= NULL
;
2182 if (iph1
->rsa
== NULL
)
2195 oakley_getsign(iph1
)
2196 struct ph1handle
*iph1
;
2198 char path
[MAXPATHLEN
];
2199 vchar_t
*privkey
= NULL
;
2202 switch (iph1
->rmconf
->certtype
) {
2203 case ISAKMP_CERT_X509SIGN
:
2204 // cert in keychain - use cssm to sign
2205 if (iph1
->rmconf
->identity_in_keychain
) {
2208 if (iph1
->rmconf
->keychainCertRef
== NULL
|| base64toCFData(iph1
->rmconf
->keychainCertRef
, &dataRef
))
2210 iph1
->sig
= crypto_cssm_getsign(dataRef
, iph1
->hash
);
2215 case ISAKMP_CERT_DNS
:
2216 if (iph1
->rmconf
->myprivfile
== NULL
) {
2217 plog(LLV_ERROR
, LOCATION
, NULL
, "no cert defined.\n");
2221 /* make private file name */
2222 getpathname(path
, sizeof(path
),
2224 iph1
->rmconf
->myprivfile
);
2225 privkey
= privsep_eay_get_pkcs1privkey(path
);
2226 if (privkey
== NULL
) {
2227 plog(LLV_ERROR
, LOCATION
, NULL
,
2228 "failed to get private key.\n");
2231 plog(LLV_DEBUG2
, LOCATION
, NULL
, "private key:\n");
2232 plogdump(LLV_DEBUG2
, privkey
->v
, privkey
->l
);
2234 iph1
->sig
= eay_get_x509sign(iph1
->hash
, privkey
);
2236 case ISAKMP_CERT_PLAINRSA
:
2237 iph1
->sig
= eay_get_rsasign(iph1
->hash
, iph1
->rsa
);
2241 plog(LLV_ERROR
, LOCATION
, NULL
,
2242 "Unknown certtype #%d\n",
2243 iph1
->rmconf
->certtype
);
2247 if (iph1
->sig
== NULL
) {
2248 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to sign.\n");
2252 plog(LLV_DEBUG
, LOCATION
, NULL
, "SIGN computed:\n");
2253 plogdump(LLV_DEBUG
, iph1
->sig
->v
, iph1
->sig
->l
);
2258 if (privkey
!= NULL
)
2265 oakley_verify_certid(iph1
)
2266 struct ph1handle
*iph1
;
2268 if (iph1
->rmconf
->verify_cert
&&
2269 oakley_check_certid(iph1
, CERT_CHECKID_FROM_PEER
)){
2270 plog(LLV_DEBUG
, LOCATION
, NULL
,
2271 "Discarding CERT: does not match ID:\n");
2272 oakley_delcert(iph1
->cert_p
);
2273 iph1
->cert_p
= NULL
;
2278 oakley_check_certid_in_certchain(certchain
, idtype
, idlen
, id
)
2286 for (p
= certchain
; p
; p
= p
->chain
) {
2287 if (oakley_check_certid_1(&p
->cert
, idtype
, idlen
, id
, &p
->status
) == 0) {
2291 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2295 oakley_get_peer_cert_from_certchain(iph1
)
2296 struct ph1handle
* iph1
;
2299 struct ipsecdoi_id_b
*id_b
;
2303 if (!iph1
->id_p
|| !iph1
->cert_p
) {
2304 plog(LLV_ERROR
, LOCATION
, NULL
, "no ID nor CERT found.\n");
2307 if (!iph1
->cert_p
->chain
) {
2308 // no chain: simply return the only cert
2309 return iph1
->cert_p
;
2312 id_b
= (struct ipsecdoi_id_b
*)iph1
->id_p
->v
;
2313 peers_id
= id_b
+ 1;
2314 idlen
= iph1
->id_p
->l
- sizeof(*id_b
);
2315 for (p
= iph1
->cert_p
; p
; p
= p
->chain
) {
2316 if (oakley_check_certid_1(&p
->cert
, id_b
->type
, idlen
, peers_id
, &p
->status
) == 0) {
2324 * compare certificate name and ID value.
2327 oakley_check_certid(iph1
, which_id
)
2328 struct ph1handle
*iph1
;
2331 struct ipsecdoi_id_b
*id_b
;
2333 u_int8_t doi_type
= 255;
2334 void *peers_id
= NULL
;
2335 struct genlist_entry
*gpb
= NULL
;
2337 if (which_id
== CERT_CHECKID_FROM_PEER
) {
2338 /* use ID from peer */
2339 if (iph1
->id_p
== NULL
|| iph1
->cert_p
== NULL
) {
2340 plog(LLV_ERROR
, LOCATION
, NULL
, "no ID nor CERT found.\n");
2341 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2343 id_b
= (struct ipsecdoi_id_b
*)iph1
->id_p
->v
;
2344 doi_type
= id_b
->type
;
2345 peers_id
= id_b
+ 1;
2346 idlen
= iph1
->id_p
->l
- sizeof(*id_b
);
2348 return oakley_check_certid_in_certchain(iph1
->cert_p
, doi_type
, idlen
, peers_id
);
2351 /* use ID from remote configuration */
2352 /* check each ID in list */
2353 struct idspec
*id_spec
;
2355 for (id_spec
= genlist_next (iph1
->rmconf
->idvl_p
, &gpb
); id_spec
; id_spec
= genlist_next (0, &gpb
)) {
2357 if (id_spec
->idtype
== IDTYPE_ADDRESS
) {
2358 switch (((struct sockaddr
*)(id_spec
->id
->v
))->sa_family
) {
2360 doi_type
= IPSECDOI_ID_IPV4_ADDR
;
2361 idlen
= sizeof(struct in_addr
);
2362 peers_id
= &(((struct sockaddr_in
*)(id_spec
->id
->v
))->sin_addr
.s_addr
);
2366 doi_type
= IPSECDOI_ID_IPV6_ADDR
;
2367 idlen
= sizeof(struct in6_addr
);
2368 peers_id
= &(((struct sockaddr_in6
*)(id_spec
->id
->v
))->sin6_addr
.s6_addr
);
2372 plog(LLV_ERROR
, LOCATION
, NULL
,
2373 "unknown address type for peers identifier.\n");
2374 return ISAKMP_NTYPE_AUTHENTICATION_FAILED
;
2379 doi_type
= idtype2doi(id_spec
->idtype
);
2380 peers_id
= id_spec
->id
->v
;
2381 idlen
= id_spec
->id
->l
;
2383 if (oakley_check_certid_in_certchain(iph1
->cert_p
, doi_type
, idlen
, peers_id
) == 0)
2386 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2391 oakley_check_certid_1(cert
, idtype
, idlen
, id
, certStatus
)
2396 cert_status_t
*certStatus
;
2399 vchar_t
*name
= NULL
;
2400 char *altname
= NULL
;
2405 case IPSECDOI_ID_DER_ASN1_DN
:
2406 #if TARGET_OS_EMBEDDED
2408 SecCertificateRef certificate
;
2412 certificate
= crypto_cssm_x509cert_get_SecCertificateRef(cert
);
2413 if (certificate
== NULL
) {
2414 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to get SecCertificateRef\n");
2415 if (certStatus
&& !*certStatus
) {
2416 *certStatus
= CERT_STATUS_INVALID
;
2418 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2420 subject
= SecCertificateCopySubjectSequence(certificate
);
2421 if (subject
== NULL
) {
2422 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to get subjectName\n");
2423 if (certStatus
&& !*certStatus
) {
2424 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
2426 CFRelease(certificate
);
2427 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2429 len
= CFDataGetLength(subject
);
2430 namePtr
= CFDataGetBytePtr(subject
);
2432 plog(LLV_ERROR
, LOCATION
, NULL
, "Invalid ID length in phase 1.\n");
2433 if (certStatus
&& !*certStatus
) {
2434 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
2437 CFRelease(certificate
);
2438 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2440 error
= memcmp(id
, namePtr
, idlen
);
2442 plog(LLV_ERROR
, LOCATION
, NULL
,
2443 "ID mismatched with subjectName.\n");
2444 plog(LLV_ERROR
, LOCATION
, NULL
,
2445 "subjectName (type %s):\n",
2446 s_ipsecdoi_ident(idtype
));
2447 plogdump(LLV_ERROR
, namePtr
, len
);
2448 plog(LLV_ERROR
, LOCATION
, NULL
,
2450 plogdump(LLV_ERROR
, id
, idlen
);
2451 if (certStatus
&& !*certStatus
) {
2452 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
2454 CFRelease(certificate
);
2456 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2460 name
= eay_get_x509asn1subjectname(cert
);
2462 plog(LLV_ERROR
, LOCATION
, NULL
,
2463 "failed to get subjectName\n");
2464 if (certStatus
&& !*certStatus
) {
2465 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
2467 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2469 if (idlen
!= name
->l
) {
2470 plog(LLV_ERROR
, LOCATION
, NULL
,
2471 "Invalid ID length in phase 1.\n");
2473 if (certStatus
&& !*certStatus
) {
2474 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
2476 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2478 error
= memcmp(id
, name
->v
, idlen
);
2480 plog(LLV_ERROR
, LOCATION
, NULL
,
2481 "ID mismatched with subjectName.\n");
2482 plog(LLV_ERROR
, LOCATION
, NULL
,
2483 "subjectName (type %s):\n",
2484 s_ipsecdoi_ident(idtype
));
2485 plogdump(LLV_ERROR
, name
->v
, name
->l
);
2486 plog(LLV_ERROR
, LOCATION
, NULL
,
2488 plogdump(LLV_ERROR
, id
, idlen
);
2490 if (certStatus
&& !*certStatus
) {
2491 *certStatus
= CERT_STATUS_INVALID_SUBJNAME
;
2493 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2499 case IPSECDOI_ID_IPV4_ADDR
:
2500 case IPSECDOI_ID_IPV6_ADDR
:
2502 #if TARGET_OS_EMBEDDED
2504 SecCertificateRef certificate
;
2505 CFArrayRef addresses
;
2507 certificate
= crypto_cssm_x509cert_get_SecCertificateRef(cert
);
2508 if (certificate
== NULL
) {
2509 plog(LLV_ERROR
, LOCATION
, NULL
,
2510 "failed to get SecCertificateRef\n");
2511 if (certStatus
&& !*certStatus
) {
2512 *certStatus
= CERT_STATUS_INVALID
;
2514 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2516 addresses
= SecCertificateCopyIPAddresses(certificate
);
2517 if (addresses
== NULL
) {
2518 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to get subjectName\n");
2519 if (certStatus
&& !*certStatus
) {
2520 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2522 CFRelease(certificate
);
2523 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2525 count
= CFArrayGetCount(addresses
);
2526 for (pos
= 0; pos
< count
; pos
++) {
2528 CFStringRef address
;
2530 char *addressBuf
, numAddress
[128];
2533 address
= CFArrayGetValueAtIndex(addresses
, pos
);
2534 addressLen
= CFStringGetLength(address
);
2535 if (addressLen
== 0)
2537 addressBuf
= racoon_malloc(addressLen
+ 1);
2538 if (addressBuf
== NULL
) {
2539 plog(LLV_ERROR
, LOCATION
, NULL
, "out of memory\n");
2542 if (CFStringGetCString(address
, addressBuf
, addressLen
+ 1, kCFStringEncodingUTF8
) == TRUE
) {
2543 result
= inet_pton(idtype
== IPSECDOI_ID_IPV4_ADDR
? AF_INET
: AF_INET6
, addressBuf
, numAddress
);
2544 racoon_free(addressBuf
);
2546 continue; // wrong type or invalid address
2547 if (memcmp(id
, numAddress
, idtype
== IPSECDOI_ID_IPV4_ADDR
? 32 : 128) == 0) { // found a match ?
2548 CFRelease(addresses
);
2549 CFRelease(certificate
);
2553 racoon_free(addressBuf
);
2555 plog(LLV_ERROR
, LOCATION
, NULL
, "ID mismatched with subjectAltName.\n");
2556 plog(LLV_ERROR
, LOCATION
, NULL
,
2557 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype
));
2558 plog(LLV_ERROR
, LOCATION
, NULL
, "ID:\n");
2559 plogdump(LLV_ERROR
, id
, idlen
);
2560 CFRelease(addresses
);
2561 CFRelease(certificate
);
2562 if (certStatus
&& !*certStatus
) {
2563 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2565 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2568 * Openssl returns the IPAddress as an ASN1 octet string (binary format)
2569 * followed by a trailing NULL. 5 bytes for IPv4 and 17 bytes for IPv6
2571 #define SUBJ_ALT_NAME_IPV4_ADDRESS_LEN 5
2572 #define SUBJ_ALT_NAME_IPV6_ADDRESS_LEN 17
2576 if (idtype
== IPSECDOI_ID_IPV4_ADDR
&& idlen
!= sizeof(struct in_addr
)
2577 || idtype
== IPSECDOI_ID_IPV6_ADDR
&& idlen
!= sizeof(struct in6_addr
)) {
2578 plog(LLV_ERROR
, LOCATION
, NULL
,
2579 "invalid address length passed.\n");
2580 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2583 for (pos
= 1; ; pos
++) {
2584 if (eay_get_x509subjectaltname(cert
, &altname
, &type
, pos
, &len
) !=0) {
2585 plog(LLV_ERROR
, LOCATION
, NULL
,
2586 "failed to get subjectAltName\n");
2587 if (certStatus
&& !*certStatus
) {
2588 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2590 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2593 /* it's the end condition of the loop. */
2595 plog(LLV_ERROR
, LOCATION
, NULL
,
2596 "invalid subjectAltName\n");
2597 if (certStatus
&& !*certStatus
) {
2598 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2600 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2603 if (check_typeofcertname(idtype
, type
) != 0) {
2604 /* wrong type - skip this one */
2605 racoon_free(altname
);
2610 if (len
== SUBJ_ALT_NAME_IPV4_ADDRESS_LEN
) { /* IPv4 */
2611 if (idtype
!= IPSECDOI_ID_IPV4_ADDR
) {
2612 /* wrong IP address type - skip this one */
2613 racoon_free(altname
);
2619 else if (len
== SUBJ_ALT_NAME_IPV6_ADDRESS_LEN
) { /* IPv6 */
2620 if (idtype
!= IPSECDOI_ID_IPV6_ADDR
) {
2621 /* wrong IP address type - skip this one */
2622 racoon_free(altname
);
2629 /* invalid IP address length in certificate - bad or bogus certificate */
2630 plog(LLV_ERROR
, LOCATION
, NULL
,
2631 "invalid IP address in certificate.\n");
2632 plog(LLV_ERROR
, LOCATION
, NULL
,
2633 "subjectAltName (expected type %s, got type %s):\n",
2634 s_ipsecdoi_ident(idtype
),
2635 s_ipsecdoi_ident(type
));
2636 plogdump(LLV_ERROR
, altname
, len
);
2637 racoon_free(altname
);
2639 if (certStatus
&& !*certStatus
) {
2640 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2642 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2645 /* compare the addresses */
2646 error
= memcmp(id
, altname
, idlen
);
2649 racoon_free(altname
);
2652 /* failed to find a match */
2653 plog(LLV_ERROR
, LOCATION
, NULL
,
2654 "ID mismatched with subjectAltName.\n");
2655 plog(LLV_ERROR
, LOCATION
, NULL
,
2656 "subjectAltName (expected type %s, got type %s):\n",
2657 s_ipsecdoi_ident(idtype
),
2658 s_ipsecdoi_ident(type
));
2659 plogdump(LLV_ERROR
, altname
, len
);
2660 plog(LLV_ERROR
, LOCATION
, NULL
,
2662 plogdump(LLV_ERROR
, id
, idlen
);
2663 racoon_free(altname
);
2664 if (certStatus
&& !*certStatus
)
2665 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2666 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2668 #endif /* TARGET_OS_EMBEDDED */
2671 #if TARGET_OS_EMBEDDED
2672 case IPSECDOI_ID_FQDN
:
2675 SecCertificateRef certificate
;
2677 CFStringRef name
, ID
;
2679 certificate
= crypto_cssm_x509cert_get_SecCertificateRef(cert
);
2680 if (certificate
== NULL
) {
2681 plog(LLV_ERROR
, LOCATION
, NULL
,
2682 "failed to get SecCertificateRef\n");
2683 if (certStatus
&& !*certStatus
) {
2684 *certStatus
= CERT_STATUS_INVALID
;
2686 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2688 names
= SecCertificateCopyDNSNames(certificate
);
2689 if (names
== NULL
) {
2690 plog(LLV_ERROR
, LOCATION
, NULL
,
2691 "failed to get subjectName\n");
2692 if (certStatus
&& !*certStatus
) {
2693 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2695 CFRelease(certificate
);
2696 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2698 count
= CFArrayGetCount(names
);
2699 ID
= CFStringCreateWithCString(NULL
, id
, kCFStringEncodingUTF8
);
2701 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error\n");
2703 CFRelease(certificate
);
2706 for (pos
= 0; pos
< count
; pos
++) {
2707 name
= CFArrayGetValueAtIndex(names
, pos
);
2708 if (CFStringCompare(name
, ID
, 0) == kCFCompareEqualTo
) {
2711 CFRelease(certificate
);
2715 plog(LLV_ERROR
, LOCATION
, NULL
, "ID mismatched with subjectAltName.\n");
2716 plog(LLV_ERROR
, LOCATION
, NULL
,
2717 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype
));
2718 plog(LLV_ERROR
, LOCATION
, NULL
, "ID:\n");
2719 plogdump(LLV_ERROR
, id
, idlen
);
2722 CFRelease(certificate
);
2723 if (certStatus
&& !*certStatus
) {
2724 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2726 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2729 case IPSECDOI_ID_USER_FQDN
:
2733 SecCertificateRef certificate
;
2735 CFStringRef name
, ID
;
2737 certificate
= crypto_cssm_x509cert_get_SecCertificateRef(cert
);
2738 if (certificate
== NULL
) {
2739 plog(LLV_ERROR
, LOCATION
, NULL
,
2740 "failed to get SecCertificateRef\n");
2741 if (certStatus
&& !*certStatus
) {
2742 *certStatus
= CERT_STATUS_INVALID
;
2744 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2746 names
= SecCertificateCopyRFC822Names(certificate
);
2747 if (names
== NULL
) {
2748 plog(LLV_ERROR
, LOCATION
, NULL
,
2749 "failed to get subjectName\n");
2750 if (certStatus
&& !*certStatus
) {
2751 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2753 CFRelease(certificate
);
2754 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2756 count
= CFArrayGetCount(names
);
2757 ID
= CFStringCreateWithCString(NULL
, id
, kCFStringEncodingUTF8
);
2759 plog(LLV_ERROR
, LOCATION
, NULL
,
2761 if (certStatus
&& !*certStatus
) {
2762 *certStatus
= CERT_STATUS_INVALID
;
2765 CFRelease(certificate
);
2766 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2768 for (pos
= 0; pos
< count
; pos
++) {
2769 name
= CFArrayGetValueAtIndex(names
, pos
);
2770 if (CFStringCompare(name
, ID
, 0) == kCFCompareEqualTo
) {
2773 CFRelease(certificate
);
2777 plog(LLV_ERROR
, LOCATION
, NULL
, "ID mismatched with subjectAltName.\n");
2778 plog(LLV_ERROR
, LOCATION
, NULL
,
2779 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype
));
2780 plog(LLV_ERROR
, LOCATION
, NULL
, "ID:\n");
2781 plogdump(LLV_ERROR
, id
, idlen
);
2784 CFRelease(certificate
);
2785 if (certStatus
&& !*certStatus
) {
2786 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2788 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2791 case IPSECDOI_ID_FQDN
:
2792 case IPSECDOI_ID_USER_FQDN
:
2796 for (pos
= 1; ; pos
++) {
2797 if (eay_get_x509subjectaltname(cert
, &altname
, &type
, pos
, &len
) != 0) {
2798 plog(LLV_ERROR
, LOCATION
, NULL
,
2799 "failed to get subjectAltName\n");
2800 if (certStatus
&& !*certStatus
) {
2801 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2803 return ISAKMP_NTYPE_INVALID_CERTIFICATE
;
2806 /* it's the end condition of the loop. */
2808 plog(LLV_ERROR
, LOCATION
, NULL
,
2809 "invalid subjectAltName\n");
2810 if (certStatus
&& !*certStatus
) {
2811 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2813 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2816 if (check_typeofcertname(idtype
, type
) != 0) {
2817 /* wrong general type - skip this one */
2818 racoon_free(altname
);
2823 if (idlen
!= strlen(altname
)) {
2824 /* wrong length - skip this one */
2825 racoon_free(altname
);
2829 error
= memcmp(id
, altname
, idlen
);
2832 racoon_free(altname
);
2835 plog(LLV_ERROR
, LOCATION
, NULL
, "ID mismatched with subjectAltName.\n");
2836 plog(LLV_ERROR
, LOCATION
, NULL
,
2837 "subjectAltName (expected type %s, got type %s):\n",
2838 s_ipsecdoi_ident(idtype
),
2839 s_ipsecdoi_ident(type
));
2840 plogdump(LLV_ERROR
, altname
, len
);
2841 plog(LLV_ERROR
, LOCATION
, NULL
,
2843 plogdump(LLV_ERROR
, id
, idlen
);
2844 racoon_free(altname
);
2845 if (certStatus
&& !*certStatus
)
2846 *certStatus
= CERT_STATUS_INVALID_SUBJALTNAME
;
2847 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2851 plog(LLV_ERROR
, LOCATION
, NULL
,
2852 "Impropper ID type passed: %s.\n",
2853 s_ipsecdoi_ident(idtype
));
2854 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2860 check_typeofcertname(doi
, genid
)
2864 case IPSECDOI_ID_IPV4_ADDR
:
2865 case IPSECDOI_ID_IPV4_ADDR_SUBNET
:
2866 case IPSECDOI_ID_IPV6_ADDR
:
2867 case IPSECDOI_ID_IPV6_ADDR_SUBNET
:
2868 case IPSECDOI_ID_IPV4_ADDR_RANGE
:
2869 case IPSECDOI_ID_IPV6_ADDR_RANGE
:
2870 if (genid
!= GENT_IPADD
)
2873 case IPSECDOI_ID_FQDN
:
2874 if (genid
!= GENT_DNS
)
2877 case IPSECDOI_ID_USER_FQDN
:
2878 if (genid
!= GENT_EMAIL
)
2881 case IPSECDOI_ID_DER_ASN1_DN
: /* should not be passed to this function*/
2882 case IPSECDOI_ID_DER_ASN1_GN
:
2883 case IPSECDOI_ID_KEY_ID
:
2892 * save certificate including certificate type.
2895 oakley_savecert(iph1
, gen
)
2896 struct ph1handle
*iph1
;
2897 struct isakmp_gen
*gen
;
2902 STACK_OF(X509
) *certs
=NULL
;
2905 type
= *(u_int8_t
*)(gen
+ 1) & 0xff;
2908 case ISAKMP_CERT_DNS
:
2909 plog(LLV_WARNING
, LOCATION
, NULL
,
2910 "CERT payload is unnecessary in DNSSEC. "
2911 "ignore this CERT payload.\n");
2913 case ISAKMP_CERT_PKCS7
:
2914 case ISAKMP_CERT_PGP
:
2915 case ISAKMP_CERT_X509SIGN
:
2916 case ISAKMP_CERT_KERBEROS
:
2917 case ISAKMP_CERT_SPKI
:
2920 case ISAKMP_CERT_CRL
:
2923 case ISAKMP_CERT_X509KE
:
2924 case ISAKMP_CERT_X509ATTR
:
2925 case ISAKMP_CERT_ARL
:
2926 plog(LLV_ERROR
, LOCATION
, NULL
,
2927 "No supported such CERT type %d\n", type
);
2930 plog(LLV_ERROR
, LOCATION
, NULL
,
2931 "Invalid CERT type %d\n", type
);
2936 plog(LLV_WARNING
, LOCATION
, NULL
,
2937 "preexisting CERT payload... chaining.\n");
2940 if (type
== ISAKMP_CERT_PKCS7
) {
2944 /* Skip the header */
2945 bp
= (u_char
*)(gen
+ 1);
2946 /* And the first byte is the certificate type,
2947 * we know that already
2950 p7
= d2i_PKCS7(NULL
, (void *)&bp
,
2951 ntohs(gen
->len
) - sizeof(*gen
) - 1);
2954 plog(LLV_ERROR
, LOCATION
, NULL
,
2955 "Failed to parse PKCS#7 CERT.\n");
2959 /* Copied this from the openssl pkcs7 application;
2960 * there"s little by way of documentation for any of
2961 * it. I can only presume it"s correct.
2964 i
= OBJ_obj2nid(p7
->type
);
2966 case NID_pkcs7_signed
:
2967 certs
=p7
->d
.sign
->cert
;
2969 case NID_pkcs7_signedAndEnveloped
:
2970 certs
=p7
->d
.signed_and_enveloped
->cert
;
2977 plog(LLV_ERROR
, LOCATION
, NULL
,
2978 "CERT PKCS#7 bundle contains no certs.\n");
2983 for (i
= 0; i
< sk_X509_num(certs
); i
++) {
2987 X509
*cert
= sk_X509_value(certs
,i
);
2989 plog(LLV_DEBUG
, LOCATION
, NULL
,
2990 "Trying PKCS#7 cert %d.\n", i
);
2992 /* We'll just try each cert in turn */
2993 new = save_certx509(cert
);
2995 plog(LLV_ERROR
, LOCATION
, NULL
,
2996 "Failed to get CERT buffer.\n");
2999 *c
= oakley_appendcert_to_certchain(*c
, new);
3000 plog(LLV_DEBUG
, LOCATION
, NULL
, "CERT saved:\n");
3001 plogdump(LLV_DEBUG
, new->cert
.v
, new->cert
.l
);
3002 oakley_cert_prettyprint(&new->cert
);
3010 new = save_certbuf(gen
);
3012 plog(LLV_ERROR
, LOCATION
, NULL
,
3013 "Failed to get CERT buffer.\n");
3017 switch (new->type
) {
3018 case ISAKMP_CERT_DNS
:
3019 plog(LLV_WARNING
, LOCATION
, NULL
,
3020 "CERT payload is unnecessary in DNSSEC. "
3023 case ISAKMP_CERT_PGP
:
3024 case ISAKMP_CERT_X509SIGN
:
3025 case ISAKMP_CERT_KERBEROS
:
3026 case ISAKMP_CERT_SPKI
:
3027 /* Ignore cert if it doesn't match identity
3028 * XXX If verify cert is disabled, we still just take
3029 * the first certificate....
3031 *c
= oakley_appendcert_to_certchain(*c
, new);
3032 plog(LLV_DEBUG
, LOCATION
, NULL
, "CERT saved:\n");
3033 plogdump(LLV_DEBUG
, new->cert
.v
, new->cert
.l
);
3034 oakley_cert_prettyprint(&new->cert
);
3036 case ISAKMP_CERT_CRL
:
3037 *c
= oakley_appendcert_to_certchain(*c
, new);
3038 plog(LLV_DEBUG
, LOCATION
, NULL
, "CRL saved:\n");
3039 plogdump(LLV_DEBUG
, new->cert
.v
, new->cert
.l
);
3040 oakley_cert_prettyprint(&new->cert
);
3042 case ISAKMP_CERT_X509KE
:
3043 case ISAKMP_CERT_X509ATTR
:
3044 case ISAKMP_CERT_ARL
:
3047 oakley_delcert(new);
3056 * save certificate including certificate type.
3059 oakley_savecr(iph1
, gen
)
3060 struct ph1handle
*iph1
;
3061 struct isakmp_gen
*gen
;
3067 type
= *(u_int8_t
*)(gen
+ 1) & 0xff;
3070 case ISAKMP_CERT_DNS
:
3071 plog(LLV_WARNING
, LOCATION
, NULL
,
3072 "CERT payload is unnecessary in DNSSEC\n");
3074 case ISAKMP_CERT_PKCS7
:
3075 case ISAKMP_CERT_PGP
:
3076 case ISAKMP_CERT_X509SIGN
:
3077 case ISAKMP_CERT_KERBEROS
:
3078 case ISAKMP_CERT_SPKI
:
3080 oakley_delcert(iph1
->cr_p
);
3085 case ISAKMP_CERT_X509KE
:
3086 case ISAKMP_CERT_X509ATTR
:
3087 case ISAKMP_CERT_ARL
:
3088 plog(LLV_ERROR
, LOCATION
, NULL
,
3089 "No supported such CR type %d\n", type
);
3091 case ISAKMP_CERT_CRL
:
3093 plog(LLV_ERROR
, LOCATION
, NULL
,
3094 "Invalid CR type %d\n", type
);
3098 new = save_certbuf(gen
);
3100 plog(LLV_ERROR
, LOCATION
, NULL
,
3101 "Failed to get CR buffer.\n");
3104 *c
= oakley_appendcert_to_certchain(*c
, new);
3105 plog(LLV_DEBUG
, LOCATION
, NULL
, "CR saved:\n");
3106 plogdump(LLV_DEBUG
, new->cert
.v
, new->cert
.l
);
3113 struct isakmp_gen
*gen
;
3117 if(ntohs(gen
->len
) <= sizeof(*gen
)){
3118 plog(LLV_ERROR
, LOCATION
, NULL
,
3119 "Len is too small !!.\n");
3123 new = oakley_newcert();
3125 plog(LLV_ERROR
, LOCATION
, NULL
,
3126 "Failed to get CERT buffer.\n");
3130 new->pl
= vmalloc(ntohs(gen
->len
) - sizeof(*gen
));
3131 if (new->pl
== NULL
) {
3132 plog(LLV_ERROR
, LOCATION
, NULL
,
3133 "Failed to copy CERT from packet.\n");
3134 oakley_delcert(new);
3138 memcpy(new->pl
->v
, gen
+ 1, new->pl
->l
);
3139 new->type
= new->pl
->v
[0] & 0xff;
3140 new->cert
.v
= new->pl
->v
+ 1;
3141 new->cert
.l
= new->pl
->l
- 1;
3155 new = oakley_newcert();
3157 plog(LLV_ERROR
, LOCATION
, NULL
,
3158 "Failed to get CERT buffer.\n");
3162 len
= i2d_X509(cert
, NULL
);
3163 new->pl
= vmalloc(len
);
3164 if (new->pl
== NULL
) {
3165 plog(LLV_ERROR
, LOCATION
, NULL
,
3166 "Failed to copy CERT from packet.\n");
3167 oakley_delcert(new);
3171 bp
= (u_char
*) new->pl
->v
;
3172 len
= i2d_X509(cert
, &bp
);
3173 new->type
= ISAKMP_CERT_X509SIGN
;
3174 new->cert
.v
= new->pl
->v
;
3175 new->cert
.l
= new->pl
->l
;
3183 * NOTE: No Certificate Authority field is included to CR payload at the
3184 * moment. Becuase any certificate authority are accepted without any check.
3185 * The section 3.10 in RFC2408 says that this field SHOULD not be included,
3186 * if there is no specific certificate authority requested.
3190 struct ph1handle
*iph1
;
3196 plog(LLV_ERROR
, LOCATION
, NULL
,
3197 "failed to get cr buffer\n");
3200 if(iph1
->rmconf
->certtype
== ISAKMP_CERT_NONE
) {
3201 buf
->v
[0] = iph1
->rmconf
->cacerttype
;
3202 plog(LLV_DEBUG
, LOCATION
, NULL
, "create my CR: NONE, using %s instead\n",
3203 s_isakmp_certtype(iph1
->rmconf
->cacerttype
));
3205 buf
->v
[0] = iph1
->rmconf
->certtype
;
3206 plog(LLV_DEBUG
, LOCATION
, NULL
, "create my CR: %s\n",
3207 s_isakmp_certtype(iph1
->rmconf
->certtype
));
3210 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3219 oakley_checkcr(iph1
)
3220 struct ph1handle
*iph1
;
3222 if (iph1
->cr_p
== NULL
)
3225 plog(LLV_DEBUG
, LOCATION
, iph1
->remote
,
3226 "peer transmitted CR: %s\n",
3227 s_isakmp_certtype(iph1
->cr_p
->type
));
3229 if (iph1
->cr_p
->type
!= iph1
->rmconf
->certtype
) {
3230 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
3231 "such a cert type isn't supported: %d\n",
3232 (char)iph1
->cr_p
->type
);
3240 * check to need CR payload.
3247 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
3248 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
3249 #ifdef ENABLE_HYBRID
3250 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
3251 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
3252 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
3253 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
3254 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
3255 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
3266 * see seciton 5. Exchanges in RFC 2409
3267 * psk: SKEYID = prf(pre-shared-key, Ni_b | Nr_b)
3268 * sig: SKEYID = prf(Ni_b | Nr_b, g^ir)
3269 * enc: SKEYID = prf(H(Ni_b | Nr_b), CKY-I | CKY-R)
3273 struct ph1handle
*iph1
;
3275 vchar_t
*buf
= NULL
, *bp
;
3281 switch (AUTHMETHOD(iph1
)) {
3282 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
3283 #ifdef ENABLE_HYBRID
3284 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I
:
3285 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
3287 if (iph1
->rmconf
->shared_secret
) {
3289 switch (iph1
->rmconf
->secrettype
) {
3290 case SECRETTYPE_KEY
:
3291 /* in psk file - use KEY from remote configuration to locate it */
3292 iph1
->authstr
= getpsk(iph1
->rmconf
->shared_secret
->v
, iph1
->rmconf
->shared_secret
->l
-1);
3295 case SECRETTYPE_KEYCHAIN
:
3296 /* in the system keychain */
3297 iph1
->authstr
= getpskfromkeychain(iph1
->rmconf
->shared_secret
->v
, iph1
->etype
, iph1
->rmconf
->secrettype
, NULL
);
3299 case SECRETTYPE_KEYCHAIN_BY_ID
:
3300 /* in the system keychain - use peer id */
3301 iph1
->authstr
= getpskfromkeychain(iph1
->rmconf
->shared_secret
->v
, iph1
->etype
, iph1
->rmconf
->secrettype
, iph1
->id_p
);
3303 #endif HAVE_KEYCHAIN
3304 case SECRETTYPE_USE
:
3305 /* in the remote configuration */
3307 /* rmconf->shared_secret is a string and contains a NULL character that must be removed */
3308 iph1
->authstr
= vmalloc(iph1
->rmconf
->shared_secret
->l
- 1);
3309 if (iph1
->authstr
== NULL
) {
3310 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error.\n");
3313 memcpy(iph1
->authstr
->v
, iph1
->rmconf
->shared_secret
->v
, iph1
->authstr
->l
);
3317 if (iph1
->etype
!= ISAKMP_ETYPE_IDENT
) {
3318 iph1
->authstr
= getpskbyname(iph1
->id_p
);
3319 if (iph1
->authstr
== NULL
) {
3320 if (iph1
->rmconf
->verify_identifier
) {
3321 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
3322 "couldn't find the pskey.\n");
3325 plog(LLV_NOTIFY
, LOCATION
, iph1
->remote
,
3326 "couldn't find the proper pskey, "
3327 "try to get one by the peer's address.\n");
3330 if (iph1
->authstr
== NULL
) {
3332 * If the exchange type is the main mode or if it's
3333 * failed to get the psk by ID, racoon try to get
3334 * the psk by remote IP address.
3335 * It may be nonsense.
3337 iph1
->authstr
= getpskbyaddr(iph1
->remote
);
3338 if (iph1
->authstr
== NULL
) {
3339 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
3340 "couldn't find the pskey for %s.\n",
3341 saddrwop2str(iph1
->remote
));
3345 plog(LLV_DEBUG
, LOCATION
, NULL
, "the psk found.\n");
3346 /* should be secret PSK */
3347 plog(LLV_DEBUG2
, LOCATION
, NULL
, "psk: ");
3348 plogdump(LLV_DEBUG2
, iph1
->authstr
->v
, iph1
->authstr
->l
);
3350 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
3353 plog(LLV_ERROR
, LOCATION
, NULL
,
3354 "failed to get skeyid buffer\n");
3359 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce
: iph1
->nonce_p
);
3360 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce 1: ");
3361 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
3362 memcpy(p
, bp
->v
, bp
->l
);
3365 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce_p
: iph1
->nonce
);
3366 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce 2: ");
3367 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
3368 memcpy(p
, bp
->v
, bp
->l
);
3371 iph1
->skeyid
= oakley_prf(iph1
->authstr
, buf
, iph1
);
3372 if (iph1
->skeyid
== NULL
)
3376 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
3377 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
3378 #ifdef ENABLE_HYBRID
3379 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
3380 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
3381 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
3382 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
3383 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
3384 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
3385 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
3386 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
3389 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
3391 len
= iph1
->nonce
->l
+ iph1
->nonce_p
->l
;
3394 plog(LLV_ERROR
, LOCATION
, NULL
,
3395 "failed to get nonce buffer\n");
3400 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce
: iph1
->nonce_p
);
3401 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce1: ");
3402 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
3403 memcpy(p
, bp
->v
, bp
->l
);
3406 bp
= (iph1
->side
== INITIATOR
? iph1
->nonce_p
: iph1
->nonce
);
3407 plog(LLV_DEBUG
, LOCATION
, NULL
, "nonce2: ");
3408 plogdump(LLV_DEBUG
, bp
->v
, bp
->l
);
3409 memcpy(p
, bp
->v
, bp
->l
);
3412 iph1
->skeyid
= oakley_prf(buf
, iph1
->dhgxy
, iph1
);
3413 if (iph1
->skeyid
== NULL
)
3416 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
3417 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
3418 #ifdef ENABLE_HYBRID
3419 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
3420 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
3421 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
3422 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
3424 plog(LLV_WARNING
, LOCATION
, NULL
,
3425 "not supported authentication method %s\n",
3426 s_oakley_attr_method(iph1
->approval
->authmethod
));
3429 plog(LLV_ERROR
, LOCATION
, NULL
,
3430 "invalid authentication method %d\n",
3431 iph1
->approval
->authmethod
);
3435 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID computed:\n");
3436 plogdump(LLV_DEBUG
, iph1
->skeyid
->v
, iph1
->skeyid
->l
);
3447 * compute SKEYID_[dae]
3448 * see seciton 5. Exchanges in RFC 2409
3449 * SKEYID_d = prf(SKEYID, g^ir | CKY-I | CKY-R | 0)
3450 * SKEYID_a = prf(SKEYID, SKEYID_d | g^ir | CKY-I | CKY-R | 1)
3451 * SKEYID_e = prf(SKEYID, SKEYID_a | g^ir | CKY-I | CKY-R | 2)
3454 oakley_skeyid_dae(iph1
)
3455 struct ph1handle
*iph1
;
3457 vchar_t
*buf
= NULL
;
3462 if (iph1
->skeyid
== NULL
) {
3463 plog(LLV_ERROR
, LOCATION
, NULL
, "no SKEYID found.\n");
3468 /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
3469 len
= iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
3472 plog(LLV_ERROR
, LOCATION
, NULL
,
3473 "failed to get skeyid buffer\n");
3478 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
3479 p
+= iph1
->dhgxy
->l
;
3480 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
3481 p
+= sizeof(cookie_t
);
3482 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
3483 p
+= sizeof(cookie_t
);
3485 iph1
->skeyid_d
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
3486 if (iph1
->skeyid_d
== NULL
)
3492 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID_d computed:\n");
3493 plogdump(LLV_DEBUG
, iph1
->skeyid_d
->v
, iph1
->skeyid_d
->l
);
3496 /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
3497 len
= iph1
->skeyid_d
->l
+ iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
3500 plog(LLV_ERROR
, LOCATION
, NULL
,
3501 "failed to get skeyid buffer\n");
3505 memcpy(p
, iph1
->skeyid_d
->v
, iph1
->skeyid_d
->l
);
3506 p
+= iph1
->skeyid_d
->l
;
3507 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
3508 p
+= iph1
->dhgxy
->l
;
3509 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
3510 p
+= sizeof(cookie_t
);
3511 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
3512 p
+= sizeof(cookie_t
);
3514 iph1
->skeyid_a
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
3515 if (iph1
->skeyid_a
== NULL
)
3521 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID_a computed:\n");
3522 plogdump(LLV_DEBUG
, iph1
->skeyid_a
->v
, iph1
->skeyid_a
->l
);
3525 /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
3526 len
= iph1
->skeyid_a
->l
+ iph1
->dhgxy
->l
+ sizeof(cookie_t
) * 2 + 1;
3529 plog(LLV_ERROR
, LOCATION
, NULL
,
3530 "failed to get skeyid buffer\n");
3534 memcpy(p
, iph1
->skeyid_a
->v
, iph1
->skeyid_a
->l
);
3535 p
+= iph1
->skeyid_a
->l
;
3536 memcpy(p
, iph1
->dhgxy
->v
, iph1
->dhgxy
->l
);
3537 p
+= iph1
->dhgxy
->l
;
3538 memcpy(p
, (caddr_t
)&iph1
->index
.i_ck
, sizeof(cookie_t
));
3539 p
+= sizeof(cookie_t
);
3540 memcpy(p
, (caddr_t
)&iph1
->index
.r_ck
, sizeof(cookie_t
));
3541 p
+= sizeof(cookie_t
);
3543 iph1
->skeyid_e
= oakley_prf(iph1
->skeyid
, buf
, iph1
);
3544 if (iph1
->skeyid_e
== NULL
)
3550 plog(LLV_DEBUG
, LOCATION
, NULL
, "SKEYID_e computed:\n");
3551 plogdump(LLV_DEBUG
, iph1
->skeyid_e
->v
, iph1
->skeyid_e
->l
);
3562 * compute final encryption key.
3566 oakley_compute_enckey(iph1
)
3567 struct ph1handle
*iph1
;
3569 u_int keylen
, prflen
;
3573 keylen
= alg_oakley_encdef_keylen(iph1
->approval
->enctype
,
3574 iph1
->approval
->encklen
);
3576 plog(LLV_ERROR
, LOCATION
, NULL
,
3577 "invalid encryption algoritym %d, "
3578 "or invalid key length %d.\n",
3579 iph1
->approval
->enctype
,
3580 iph1
->approval
->encklen
);
3583 iph1
->key
= vmalloc(keylen
>> 3);
3584 if (iph1
->key
== NULL
) {
3585 plog(LLV_ERROR
, LOCATION
, NULL
,
3586 "failed to get key buffer\n");
3590 /* set prf length */
3591 prflen
= alg_oakley_hashdef_hashlen(iph1
->approval
->hashtype
);
3593 plog(LLV_ERROR
, LOCATION
, NULL
,
3594 "invalid hash type %d.\n", iph1
->approval
->hashtype
);
3598 /* see isakmp-oakley-08 5.3. */
3599 if (iph1
->key
->l
<= iph1
->skeyid_e
->l
) {
3601 * if length(Ka) <= length(SKEYID_e)
3602 * Ka = first length(K) bit of SKEYID_e
3604 memcpy(iph1
->key
->v
, iph1
->skeyid_e
->v
, iph1
->key
->l
);
3606 vchar_t
*buf
= NULL
, *res
= NULL
;
3615 * K1 = prf(SKEYID_e, 0)
3616 * K2 = prf(SKEYID_e, K1)
3617 * K3 = prf(SKEYID_e, K2)
3619 plog(LLV_DEBUG
, LOCATION
, NULL
,
3620 "len(SKEYID_e) < len(Ka) (%zu < %zu), "
3621 "generating long key (Ka = K1 | K2 | ...)\n",
3622 iph1
->skeyid_e
->l
, iph1
->key
->l
);
3624 if ((buf
= vmalloc(prflen
>> 3)) == 0) {
3625 plog(LLV_ERROR
, LOCATION
, NULL
,
3626 "failed to get key buffer\n");
3629 p
= (u_char
*)iph1
->key
->v
;
3630 ep
= p
+ iph1
->key
->l
;
3634 if (p
== (u_char
*)iph1
->key
->v
) {
3635 /* just for computing K1 */
3639 res
= oakley_prf(iph1
->skeyid_e
, buf
, iph1
);
3644 plog(LLV_DEBUG
, LOCATION
, NULL
,
3645 "compute intermediate encryption key K%d\n",
3647 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3648 plogdump(LLV_DEBUG
, res
->v
, res
->l
);
3650 cplen
= (res
->l
< ep
- p
) ? res
->l
: ep
- p
;
3651 memcpy(p
, res
->v
, cplen
);
3654 buf
->l
= prflen
>> 3; /* to cancel K1 speciality */
3655 if (res
->l
!= buf
->l
) {
3656 plog(LLV_ERROR
, LOCATION
, NULL
,
3657 "internal error: res->l=%zu buf->l=%zu\n",
3663 memcpy(buf
->v
, res
->v
, res
->l
);
3672 * don't check any weak key or not.
3673 * draft-ietf-ipsec-ike-01.txt Appendix B.
3674 * draft-ietf-ipsec-ciph-aes-cbc-00.txt Section 2.3.
3678 if (iph1
->approval
->enctype
> ARRAYLEN(oakley_encdef
)
3679 || oakley_encdef
[iph1
->approval
->enctype
].weakkey
== NULL
) {
3680 plog(LLV_ERROR
, LOCATION
, NULL
,
3681 "encryption algoritym %d isn't supported.\n",
3682 iph1
->approval
->enctype
);
3685 if ((oakley_encdef
[iph1
->approval
->enctype
].weakkey
)(iph1
->key
)) {
3686 plog(LLV_ERROR
, LOCATION
, NULL
,
3687 "weakkey was generated.\n");
3692 plog(LLV_DEBUG
, LOCATION
, NULL
, "final encryption key computed:\n");
3693 plogdump(LLV_DEBUG
, iph1
->key
->v
, iph1
->key
->l
);
3701 /* allocated new buffer for CERT */
3707 new = racoon_calloc(1, sizeof(*new));
3709 plog(LLV_ERROR
, LOCATION
, NULL
,
3710 "failed to get cert's buffer\n");
3720 /* delete buffer for CERT */
3722 oakley_delcert_1(cert
)
3732 /* delete buffer for CERT */
3734 oakley_delcert(cert
)
3737 cert_t
*p
, *to_delete
;
3742 for (p
= cert
; p
;) {
3745 oakley_delcert_1(to_delete
);
3749 /* delete buffer for CERT */
3751 oakley_appendcert_to_certchain(certchain
, new)
3760 for (p
= certchain
; p
; p
= p
->chain
) {
3770 * compute IV and set to ph1handle
3771 * IV = hash(g^xi | g^xr)
3772 * see 4.1 Phase 1 state in draft-ietf-ipsec-ike.
3776 struct ph1handle
*iph1
;
3778 struct isakmp_ivm
*newivm
= NULL
;
3779 vchar_t
*buf
= NULL
, *bp
;
3784 len
= iph1
->dhpub
->l
+ iph1
->dhpub_p
->l
;
3787 plog(LLV_ERROR
, LOCATION
, NULL
,
3788 "failed to get iv buffer\n");
3794 bp
= (iph1
->side
== INITIATOR
? iph1
->dhpub
: iph1
->dhpub_p
);
3795 memcpy(p
, bp
->v
, bp
->l
);
3798 bp
= (iph1
->side
== INITIATOR
? iph1
->dhpub_p
: iph1
->dhpub
);
3799 memcpy(p
, bp
->v
, bp
->l
);
3803 newivm
= racoon_calloc(1, sizeof(struct isakmp_ivm
));
3804 if (newivm
== NULL
) {
3805 plog(LLV_ERROR
, LOCATION
, NULL
,
3806 "failed to get iv buffer\n");
3812 newivm
->iv
= oakley_hash(buf
, iph1
);
3813 if (newivm
->iv
== NULL
) {
3815 oakley_delivm(newivm
);
3819 /* adjust length of iv */
3820 newivm
->iv
->l
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3821 if (newivm
->iv
->l
== -1) {
3822 plog(LLV_ERROR
, LOCATION
, NULL
,
3823 "invalid encryption algoriym %d.\n",
3824 iph1
->approval
->enctype
);
3826 oakley_delivm(newivm
);
3830 /* create buffer to save iv */
3831 if ((newivm
->ive
= vdup(newivm
->iv
)) == NULL
) {
3832 plog(LLV_ERROR
, LOCATION
, NULL
,
3833 "vdup (%s)\n", strerror(errno
));
3835 oakley_delivm(newivm
);
3841 plog(LLV_DEBUG
, LOCATION
, NULL
, "IV computed:\n");
3842 plogdump(LLV_DEBUG
, newivm
->iv
->v
, newivm
->iv
->l
);
3844 if (iph1
->ivm
!= NULL
)
3845 oakley_delivm(iph1
->ivm
);
3853 * compute IV for the payload after phase 1.
3854 * It's not limited for phase 2.
3855 * if pahse 1 was encrypted.
3856 * IV = hash(last CBC block of Phase 1 | M-ID)
3857 * if phase 1 was not encrypted.
3858 * IV = hash(phase 1 IV | M-ID)
3859 * see 4.2 Phase 2 state in draft-ietf-ipsec-ike.
3862 oakley_newiv2(iph1
, msgid
)
3863 struct ph1handle
*iph1
;
3866 struct isakmp_ivm
*newivm
= NULL
;
3867 vchar_t
*buf
= NULL
;
3873 len
= iph1
->ivm
->iv
->l
+ sizeof(msgid_t
);
3876 plog(LLV_ERROR
, LOCATION
, NULL
,
3877 "failed to get iv buffer\n");
3883 memcpy(p
, iph1
->ivm
->iv
->v
, iph1
->ivm
->iv
->l
);
3884 p
+= iph1
->ivm
->iv
->l
;
3886 memcpy(p
, &msgid
, sizeof(msgid
));
3888 plog(LLV_DEBUG
, LOCATION
, NULL
, "compute IV for phase2\n");
3889 plog(LLV_DEBUG
, LOCATION
, NULL
, "phase1 last IV:\n");
3890 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
3893 newivm
= racoon_calloc(1, sizeof(struct isakmp_ivm
));
3894 if (newivm
== NULL
) {
3895 plog(LLV_ERROR
, LOCATION
, NULL
,
3896 "failed to get iv buffer\n");
3901 if ((newivm
->iv
= oakley_hash(buf
, iph1
)) == NULL
)
3904 /* adjust length of iv */
3905 newivm
->iv
->l
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3906 if (newivm
->iv
->l
== -1) {
3907 plog(LLV_ERROR
, LOCATION
, NULL
,
3908 "invalid encryption algoriym %d.\n",
3909 iph1
->approval
->enctype
);
3913 /* create buffer to save new iv */
3914 if ((newivm
->ive
= vdup(newivm
->iv
)) == NULL
) {
3915 plog(LLV_ERROR
, LOCATION
, NULL
, "vdup (%s)\n", strerror(errno
));
3921 plog(LLV_DEBUG
, LOCATION
, NULL
, "phase2 IV computed:\n");
3922 plogdump(LLV_DEBUG
, newivm
->iv
->v
, newivm
->iv
->l
);
3925 if (error
&& newivm
!= NULL
){
3926 oakley_delivm(newivm
);
3936 struct isakmp_ivm
*ivm
;
3941 if (ivm
->iv
!= NULL
)
3943 if (ivm
->ive
!= NULL
)
3946 plog(LLV_DEBUG
, LOCATION
, NULL
, "IV freed\n");
3953 * save new iv and old iv.
3956 oakley_do_decrypt(iph1
, msg
, ivdp
, ivep
)
3957 struct ph1handle
*iph1
;
3958 vchar_t
*msg
, *ivdp
, *ivep
;
3960 vchar_t
*buf
= NULL
, *new = NULL
;
3967 plog(LLV_DEBUG
, LOCATION
, NULL
, "begin decryption.\n");
3969 blen
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
3971 plog(LLV_ERROR
, LOCATION
, NULL
,
3972 "invalid encryption algoriym %d.\n",
3973 iph1
->approval
->enctype
);
3977 /* save IV for next, but not sync. */
3978 memset(ivep
->v
, 0, ivep
->l
);
3979 memcpy(ivep
->v
, (caddr_t
)&msg
->v
[msg
->l
- blen
], blen
);
3981 plog(LLV_DEBUG
, LOCATION
, NULL
,
3982 "IV was saved for next processing:\n");
3983 plogdump(LLV_DEBUG
, ivep
->v
, ivep
->l
);
3985 pl
= msg
->v
+ sizeof(struct isakmp
);
3987 len
= msg
->l
- sizeof(struct isakmp
);
3992 plog(LLV_ERROR
, LOCATION
, NULL
,
3993 "failed to get buffer to decrypt.\n");
3996 memcpy(buf
->v
, pl
, len
);
3999 new = alg_oakley_encdef_decrypt(iph1
->approval
->enctype
,
4000 buf
, iph1
->key
, ivdp
);
4001 if (new == NULL
|| new->v
== NULL
|| new->l
== 0) {
4002 plog(LLV_ERROR
, LOCATION
, NULL
,
4003 "decryption %d failed.\n", iph1
->approval
->enctype
);
4006 plog(LLV_DEBUG
, LOCATION
, NULL
, "with key:\n");
4007 plogdump(LLV_DEBUG
, iph1
->key
->v
, iph1
->key
->l
);
4014 plog(LLV_DEBUG
, LOCATION
, NULL
, "decrypted payload by IV:\n");
4015 plogdump(LLV_DEBUG
, ivdp
->v
, ivdp
->l
);
4017 plog(LLV_DEBUG
, LOCATION
, NULL
,
4018 "decrypted payload, but not trimed.\n");
4019 plogdump(LLV_DEBUG
, new->v
, new->l
);
4021 /* get padding length */
4022 if (lcconf
->pad_excltail
)
4023 padlen
= new->v
[new->l
- 1] + 1;
4025 padlen
= new->v
[new->l
- 1];
4026 plog(LLV_DEBUG
, LOCATION
, NULL
, "padding len=%u\n", padlen
);
4029 if (lcconf
->pad_strict
) {
4030 if (padlen
> new->l
) {
4031 plog(LLV_ERROR
, LOCATION
, NULL
,
4032 "invalid padding len=%u, buflen=%zu.\n",
4034 plogdump(LLV_ERROR
, new->v
, new->l
);
4038 plog(LLV_DEBUG
, LOCATION
, NULL
, "trimmed padding\n");
4040 plog(LLV_DEBUG
, LOCATION
, NULL
, "skip to trim padding.\n");
4043 /* create new buffer */
4044 len
= sizeof(struct isakmp
) + new->l
;
4047 plog(LLV_ERROR
, LOCATION
, NULL
,
4048 "failed to get buffer to decrypt.\n");
4051 memcpy(buf
->v
, msg
->v
, sizeof(struct isakmp
));
4052 memcpy(buf
->v
+ sizeof(struct isakmp
), new->v
, new->l
);
4053 ((struct isakmp
*)buf
->v
)->len
= htonl(buf
->l
);
4055 plog(LLV_DEBUG
, LOCATION
, NULL
, "decrypted.\n");
4056 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
4058 #ifdef HAVE_PRINT_ISAKMP_C
4059 isakmp_printpacket(buf
, iph1
->remote
, iph1
->local
, 1);
4065 if (error
&& buf
!= NULL
) {
4079 oakley_do_encrypt(iph1
, msg
, ivep
, ivp
)
4080 struct ph1handle
*iph1
;
4081 vchar_t
*msg
, *ivep
, *ivp
;
4083 vchar_t
*buf
= 0, *new = 0;
4090 plog(LLV_DEBUG
, LOCATION
, NULL
, "begin encryption.\n");
4092 /* set cbc block length */
4093 blen
= alg_oakley_encdef_blocklen(iph1
->approval
->enctype
);
4095 plog(LLV_ERROR
, LOCATION
, NULL
,
4096 "invalid encryption algoriym %d.\n",
4097 iph1
->approval
->enctype
);
4101 pl
= msg
->v
+ sizeof(struct isakmp
);
4102 len
= msg
->l
- sizeof(struct isakmp
);
4105 padlen
= oakley_padlen(len
, blen
);
4106 plog(LLV_DEBUG
, LOCATION
, NULL
, "pad length = %u\n", padlen
);
4109 buf
= vmalloc(len
+ padlen
);
4111 plog(LLV_ERROR
, LOCATION
, NULL
,
4112 "failed to get buffer to encrypt.\n");
4117 char *p
= &buf
->v
[len
];
4118 if (lcconf
->pad_random
) {
4119 for (i
= 0; i
< padlen
; i
++)
4120 *p
++ = eay_random() & 0xff;
4123 memcpy(buf
->v
, pl
, len
);
4125 /* make pad into tail */
4126 if (lcconf
->pad_excltail
)
4127 buf
->v
[len
+ padlen
- 1] = padlen
- 1;
4129 buf
->v
[len
+ padlen
- 1] = padlen
;
4131 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
4134 new = alg_oakley_encdef_encrypt(iph1
->approval
->enctype
,
4135 buf
, iph1
->key
, ivep
);
4137 plog(LLV_ERROR
, LOCATION
, NULL
,
4138 "encryption %d failed.\n", iph1
->approval
->enctype
);
4141 plog(LLV_DEBUG
, LOCATION
, NULL
, "with key:\n");
4142 plogdump(LLV_DEBUG
, iph1
->key
->v
, iph1
->key
->l
);
4149 plog(LLV_DEBUG
, LOCATION
, NULL
, "encrypted payload by IV:\n");
4150 plogdump(LLV_DEBUG
, ivep
->v
, ivep
->l
);
4152 /* save IV for next */
4153 memset(ivp
->v
, 0, ivp
->l
);
4154 memcpy(ivp
->v
, (caddr_t
)&new->v
[new->l
- blen
], blen
);
4156 plog(LLV_DEBUG
, LOCATION
, NULL
, "save IV for next:\n");
4157 plogdump(LLV_DEBUG
, ivp
->v
, ivp
->l
);
4159 /* create new buffer */
4160 len
= sizeof(struct isakmp
) + new->l
;
4163 plog(LLV_ERROR
, LOCATION
, NULL
,
4164 "failed to get buffer to encrypt.\n");
4167 memcpy(buf
->v
, msg
->v
, sizeof(struct isakmp
));
4168 memcpy(buf
->v
+ sizeof(struct isakmp
), new->v
, new->l
);
4169 ((struct isakmp
*)buf
->v
)->len
= htonl(buf
->l
);
4173 plog(LLV_DEBUG
, LOCATION
, NULL
, "encrypted.\n");
4176 if (error
&& buf
!= NULL
) {
4186 /* culculate padding length */
4188 oakley_padlen(len
, base
)
4193 padlen
= base
- len
% base
;
4195 if (lcconf
->pad_randomlen
)
4196 padlen
+= ((eay_random() % (lcconf
->pad_maxsize
+ 1) + 1) *
4202 /* -----------------------------------------------------------------------------
4203 The base-64 encoding packs three 8-bit bytes into four 7-bit ASCII
4204 characters. If the number of bytes in the original data isn't divisable
4205 by three, "=" characters are used to pad the encoded data. The complete
4206 set of characters used in base-64 are:
4214 ----------------------------------------------------------------------------- */
4215 static const signed char base64_DecodeTable
[128] = {
4216 /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
4217 /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
4218 /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
4219 /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
4220 /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
4221 /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
4222 /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
4223 /* '8' */ 60, 61, -1, -1, -1, 0, -1, -1,
4224 /* '@' */ -1, 0, 1, 2, 3, 4, 5, 6,
4225 /* 'H' */ 7, 8, 9, 10, 11, 12, 13, 14,
4226 /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
4227 /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
4228 /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
4229 /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
4230 /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
4231 /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
4234 static int base64toCFData(vchar_t
*textin
, CFDataRef
*dataRef
)
4242 uint8_t *textcur
= textin
->v
;
4243 int len
= textin
->l
;
4246 tmpbuf
= malloc(len
); // len of result will be less than encoded len
4247 if (tmpbuf
== NULL
) {
4248 yyerror("memory error - could not allocate buffer for certificate reference conversion from base-64.");
4252 for (i
= 0; i
< len
; i
++) {
4256 else if (!isspace(c
))
4258 if (base64_DecodeTable
[c
] < 0)
4262 acc
+= base64_DecodeTable
[c
];
4263 if (0 == (cntr
& 0x3)) {
4264 tmpbuf
[tmpbufpos
++] = (acc
>> 16) & 0xff;
4266 tmpbuf
[tmpbufpos
++] = (acc
>> 8) & 0xff;
4268 tmpbuf
[tmpbufpos
++] = acc
& 0xff;
4271 *dataRef
= CFDataCreate(NULL
, tmpbuf
, tmpbufpos
);