#include <sys/socket.h> /* XXX for subjectaltname */
#include <netinet/in.h> /* XXX for subjectaltname */
+#ifdef HAVE_OPENSSL
#include <openssl/pkcs7.h>
#include <openssl/x509.h>
+#endif
#include <stdlib.h>
#include <stdio.h>
# include <time.h>
# endif
#endif
-#ifdef ENABLE_HYBRID
-#include <resolv.h>
-#endif
#include "var.h"
#include "misc.h"
#include "isakmp_cfg.h"
#endif
#include "oakley.h"
-#include "admin.h"
-#include "privsep.h"
#include "localconf.h"
#include "policy.h"
#include "handler.h"
#include "sainfo.h"
#include "proposal.h"
#include "crypto_openssl.h"
-#ifdef __APPLE__
#include "crypto_cssm.h"
#if HAVE_OPENDIR
#include "open_dir.h"
#endif
-#endif
-#include "dnssec.h"
#include "sockmisc.h"
#include "strnames.h"
#include "gcmalloc.h"
-#include "rsalist.h"
-#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
-#endif
#include "remoteconf.h"
-
-#ifdef HAVE_GSSAPI
-#include "gssapi.h"
+#include "vpn_control.h"
+#ifndef HAVE_OPENSSL
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
#endif
+#include "vpn_control_var.h"
+#include "extern.h"
#define OUTBOUND_SA 0
#define INBOUND_SA 1
-#ifdef __APPLE__
#define CERT_CHECKID_FROM_PEER 0
#define CERT_CHECKID_FROM_RMCONFIG 1
-#endif
+#ifdef HAVE_OPENSSL
+#define INITDHVAL(a, s, d, t) \
+do { \
+vchar_t buf; \
+buf.v = str2val((s), 16, &buf.l); \
+memset(&a, 0, sizeof(struct dhgroup)); \
+a.type = (t); \
+a.prime = vdup(&buf); \
+a.gen1 = 2; \
+a.gen2 = 0; \
+racoon_free(buf.v); \
+} while(0);
+#else /* HAVE_OPENSSL */
#define INITDHVAL(a, s, d, t) \
do { \
- vchar_t buf; \
- buf.v = str2val((s), 16, &buf.l); \
- memset(&a, 0, sizeof(struct dhgroup)); \
- a.type = (t); \
- a.prime = vdup(&buf); \
- a.gen1 = 2; \
- a.gen2 = 0; \
- racoon_free(buf.v); \
+vchar_t buf; \
+buf.v = str2val((s), 16, &buf.l); \
+memset(&a, 0, sizeof(struct dhgroup)); \
+a.desc = (d); \
+a.type = (t); \
+a.prime = vdup(&buf); \
+a.gen1 = 2; \
+a.gen2 = 0; \
+racoon_free(buf.v); \
} while(0);
+#endif /* HAVE_OPENSSL */
struct dhgroup dh_modp768;
struct dhgroup dh_modp1024;
struct dhgroup dh_modp8192;
-static int oakley_check_dh_pub __P((vchar_t *, vchar_t **));
-static int oakley_compute_keymat_x __P((struct ph2handle *, int, int));
-static int get_cert_fromlocal __P((struct ph1handle *, int));
-static int get_plainrsa_fromlocal __P((struct ph1handle *, int));
-#ifdef __APPLE__
-static int oakley_check_certid __P((struct ph1handle *iph1, int));
-static int oakley_check_certid_1 __P((struct ph1handle*, int, int, void*));
-#else
-static int oakley_check_certid __P((struct ph1handle *iph1));
+static int oakley_check_dh_pub (vchar_t *, vchar_t **);
+static int oakley_compute_keymat_x (phase2_handle_t *, int, int);
+static int get_cert_fromlocal (phase1_handle_t *, int);
+static int oakley_check_certid (phase1_handle_t *iph1);
+static int oakley_check_certid_1 (vchar_t *, int, int, void*, cert_status_t *certStatus);
+#ifdef HAVE_OPENSSL
+static int check_typeofcertname (int, int);
#endif
-static int check_typeofcertname __P((int, int));
-static cert_t *save_certbuf __P((struct isakmp_gen *));
-static cert_t *save_certx509 __P((X509 *));
-static int oakley_padlen __P((int, int));
+static cert_t *save_certbuf (struct isakmp_gen *);
+static int oakley_padlen (int, int);
-#ifdef __APPLE__
-static int base64toCFData(vchar_t *, CFDataRef*);
-#endif
+static int base64toCFData (vchar_t *, CFDataRef*);
+static cert_t *oakley_appendcert_to_certchain (cert_t *, cert_t *);
int
oakley_get_defaultlifetime()
}
void
-oakley_dhgrp_free(dhgrp)
- struct dhgroup *dhgrp;
+oakley_dhgrp_free(struct dhgroup *dhgrp)
{
- if (dhgrp->prime)
- vfree(dhgrp->prime);
- if (dhgrp->curve_a)
- vfree(dhgrp->curve_a);
- if (dhgrp->curve_b)
- vfree(dhgrp->curve_b);
- if (dhgrp->order)
- vfree(dhgrp->order);
+ VPTRINIT(dhgrp->prime);
+ VPTRINIT(dhgrp->curve_a);
+ VPTRINIT(dhgrp->curve_b);
+ VPTRINIT(dhgrp->order);
racoon_free(dhgrp);
}
* performed, prepending zero bits to the value if necessary.
*/
static int
-oakley_check_dh_pub(prime, pub0)
- vchar_t *prime, **pub0;
+oakley_check_dh_pub(vchar_t *prime, vchar_t **pub0)
{
vchar_t *tmp;
vchar_t *pub = *pub0;
if (prime->l < pub->l) {
/* what should i do ? */
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"invalid public information was generated.\n");
return -1;
}
/* prime->l > pub->l */
tmp = vmalloc(prime->l);
if (tmp == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get DH buffer.\n");
return -1;
}
* IN: *dh, *pub, *priv, *pub_p
* OUT: **gxy
*/
+#ifdef HAVE_OPENSSL
int
-oakley_dh_compute(dh, pub, priv, pub_p, gxy)
- const struct dhgroup *dh;
- vchar_t *pub, *priv, *pub_p, **gxy;
+oakley_dh_compute(const struct dhgroup *dh, vchar_t *pub, vchar_t *priv, vchar_t *pub_p, vchar_t **gxy)
{
#ifdef ENABLE_STATS
struct timeval start, end;
#endif
if ((*gxy = vmalloc(dh->prime->l)) == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get DH buffer.\n");
return -1;
}
switch (dh->type) {
case OAKLEY_ATTR_GRP_TYPE_MODP:
if (eay_dh_compute(dh->prime, dh->gen1, pub, priv, pub_p, gxy) < 0) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to compute dh value.\n");
return -1;
}
break;
case OAKLEY_ATTR_GRP_TYPE_ECP:
case OAKLEY_ATTR_GRP_TYPE_EC2N:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"dh type %d isn't supported.\n", dh->type);
return -1;
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"invalid dh type %d.\n", dh->type);
return -1;
}
#ifdef ENABLE_STATS
gettimeofday(&end, NULL);
- syslog(LOG_NOTICE, "%s(%s%d): %8.6f", __func__,
+ plog(ASL_LEVEL_NOTICE, "%s(%s%d): %8.6f", __func__,
s_attr_isakmp_group(dh->type), dh->prime->l << 3,
timedelta(&start, &end));
#endif
- plog(LLV_DEBUG, LOCATION, NULL, "compute DH's shared.\n");
- plogdump(LLV_DEBUG, (*gxy)->v, (*gxy)->l);
+ plog(ASL_LEVEL_DEBUG, "compute DH's shared.\n");
+
+ return 0;
+}
+#else
+int
+oakley_dh_compute(const struct dhgroup *dh, vchar_t *pub_p, size_t publicKeySize, vchar_t **gxy, SecDHContext *dhC)
+{
+
+ vchar_t *computed_key = NULL;
+ size_t computed_keylen;
+ size_t maxKeyLen;
+
+#ifdef ENABLE_STATS
+ struct timeval start, end;
+ gettimeofday(&start, NULL);
+#endif
+
+ plog(ASL_LEVEL_DEBUG, "compute DH result.\n");
+ maxKeyLen = SecDHGetMaxKeyLength(*dhC);
+ computed_key = vmalloc(maxKeyLen);
+ if (computed_key == NULL) {
+ plog(ASL_LEVEL_ERR, "memory error.\n");
+ goto fail;
+ }
+ computed_keylen = computed_key->l;
+ if (SecDHComputeKey(*dhC, (uint8_t*)pub_p->v + (maxKeyLen - publicKeySize), publicKeySize,
+ (uint8_t*)computed_key->v, &computed_keylen)) {
+ plog(ASL_LEVEL_ERR, "failed to compute dh value.\n");
+ goto fail;
+ }
+
+#ifdef ENABLE_STATS
+ gettimeofday(&end, NULL);
+ plog(ASL_LEVEL_NOTICE, "%s(%s%d): %8.6f", __func__,
+ s_attr_isakmp_group(dh->type), dh->prime->l << 3,
+ timedelta(&start, &end));
+#endif
+
+ *gxy = vmalloc(maxKeyLen);
+ if (*gxy == NULL) {
+ plog(ASL_LEVEL_ERR, "memory error.\n");
+ goto fail;
+ }
+ memcpy((*gxy)->v + (maxKeyLen - computed_keylen), computed_key->v, computed_keylen);
+ plog(ASL_LEVEL_DEBUG, "compute DH's shared.\n");
+ if (*dhC) {
+ SecDHDestroy(*dhC);
+ *dhC = NULL;
+ }
+ vfree(computed_key);
return 0;
+
+fail:
+ if (*dhC) {
+ SecDHDestroy(*dhC);
+ *dhC = NULL;
+ }
+ vfree(*gxy);
+ vfree(computed_key);
+ return -1;
}
+#endif
+
/*
* generate values of DH
* IN: *dh
* OUT: **pub, **priv
*/
+#ifdef HAVE_OPENSSL
int
-oakley_dh_generate(dh, pub, priv)
- const struct dhgroup *dh;
- vchar_t **pub, **priv;
+oakley_dh_generate(const struct dhgroup *dh, vchar_t **pub, vchar_t **priv)
{
#ifdef ENABLE_STATS
struct timeval start, end;
switch (dh->type) {
case OAKLEY_ATTR_GRP_TYPE_MODP:
if (eay_dh_generate(dh->prime, dh->gen1, dh->gen2, pub, priv) < 0) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to compute dh value.\n");
return -1;
}
case OAKLEY_ATTR_GRP_TYPE_ECP:
case OAKLEY_ATTR_GRP_TYPE_EC2N:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"dh type %d isn't supported.\n", dh->type);
return -1;
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"invalid dh type %d.\n", dh->type);
return -1;
}
#ifdef ENABLE_STATS
gettimeofday(&end, NULL);
- syslog(LOG_NOTICE, "%s(%s%d): %8.6f", __func__,
+ plog(ASL_LEVEL_NOTICE, "%s(%s%d): %8.6f", __func__,
s_attr_isakmp_group(dh->type), dh->prime->l << 3,
timedelta(&start, &end));
#endif
if (oakley_check_dh_pub(dh->prime, pub) != 0)
return -1;
- plog(LLV_DEBUG, LOCATION, NULL, "compute DH's private.\n");
- plogdump(LLV_DEBUG, (*priv)->v, (*priv)->l);
- plog(LLV_DEBUG, LOCATION, NULL, "compute DH's public.\n");
- plogdump(LLV_DEBUG, (*pub)->v, (*pub)->l);
+ plog(ASL_LEVEL_DEBUG, "compute DH's private.\n");
+ plog(ASL_LEVEL_DEBUG, "compute DH's public.\n");
return 0;
}
+#else
+int
+oakley_dh_generate(const struct dhgroup *dh, vchar_t **pub, size_t *publicKeySize, SecDHContext *dhC)
+{
+ vchar_t *public = NULL;
+ size_t maxKeyLen;
+
+#ifdef ENABLE_STATS
+ struct timeval start, end;
+ gettimeofday(&start, NULL);
+#endif
+
+ plog(ASL_LEVEL_DEBUG, "generate DH key pair.\n");
+ *pub = NULL;
+ switch (dh->type) {
+ case OAKLEY_ATTR_GRP_TYPE_MODP:
+#define SECDH_MODP_GENERATOR 2
+ if (SecDHCreate(SECDH_MODP_GENERATOR, (uint8_t*)dh->prime->v, dh->prime->l, 0, NULL, 0, dhC)) {
+ plog(ASL_LEVEL_ERR, "failed to create dh context.\n");
+ goto fail;
+ }
+ maxKeyLen = SecDHGetMaxKeyLength(*dhC);
+ public = vmalloc(maxKeyLen);
+ *publicKeySize = public->l;
+ if (public == NULL) {
+ plog(ASL_LEVEL_ERR, "memory error.\n");
+ goto fail;
+ }
+ if (SecDHGenerateKeypair(*dhC, (uint8_t*)public->v, publicKeySize)) {
+ plog(ASL_LEVEL_ERR, "failed to generate dh key pair.\n");
+ goto fail;
+ }
+ plog(ASL_LEVEL_DEBUG, "got DH key pair.\n");
+
+ *pub = vmalloc(maxKeyLen);
+ if (*pub == NULL) {
+ plog(ASL_LEVEL_ERR, "memory error.\n");
+ goto fail;
+ }
+ /* copy and fill with leading zeros */
+ memcpy((*pub)->v + (maxKeyLen - *publicKeySize), public->v, *publicKeySize);
+ break;
+
+ case OAKLEY_ATTR_GRP_TYPE_ECP:
+ case OAKLEY_ATTR_GRP_TYPE_EC2N:
+ plog(ASL_LEVEL_ERR,
+ "dh type %d isn't supported.\n", dh->type);
+ goto fail;
+ default:
+ plog(ASL_LEVEL_ERR,
+ "invalid dh type %d.\n", dh->type);
+ goto fail;
+ }
+
+#ifdef ENABLE_STATS
+ gettimeofday(&end, NULL);
+ plog(ASL_LEVEL_NOTICE, "%s(%s%d): %8.6f", __func__,
+ s_attr_isakmp_group(dh->type), dh->prime->l << 3,
+ timedelta(&start, &end));
+#endif
+
+ if (oakley_check_dh_pub(dh->prime, pub) != 0) {
+ plog(ASL_LEVEL_DEBUG, "failed DH public key size check.\n");
+ goto fail;
+ }
+
+ //plogdump(ASL_LEVEL_DEBUG, (*pub)->v, (*pub)->l, "compute DH's public.\n");
+
+ vfree(public);
+ return 0;
+
+fail:
+ if (*dhC) {
+ SecDHDestroy(*dhC);
+ *dhC = NULL;
+ }
+ vfree(*pub);
+ vfree(public);
+ return -1;
+
+}
+#endif
/*
* copy pre-defined dhgroup values.
*/
int
-oakley_setdhgroup(group, dhgrp)
- int group;
- struct dhgroup **dhgrp;
+oakley_setdhgroup(int group, struct dhgroup **dhgrp)
{
struct dhgroup *g;
g = alg_oakley_dhdef_group(group);
if (g == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"invalid DH parameter grp=%d.\n", group);
return -1;
}
if (!g->type || !g->prime || !g->gen1) {
/* unsuported */
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"unsupported DH parameters grp=%d.\n", group);
return -1;
}
*dhgrp = racoon_calloc(1, sizeof(struct dhgroup));
if (*dhgrp == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get DH buffer.\n");
return 0;
}
* modify oakley_compute_keymat() accordingly.
*/
vchar_t *
-oakley_prf(key, buf, iph1)
- vchar_t *key, *buf;
- struct ph1handle *iph1;
+oakley_prf(vchar_t *key, vchar_t *buf, phase1_handle_t *iph1)
{
vchar_t *res = NULL;
- int type;
+ int type = OAKLEY_ATTR_HASH_ALG_MD5;
if (iph1->approval == NULL) {
- /*
- * it's before negotiating hash algorithm.
- * We use md5 as default.
- */
- type = OAKLEY_ATTR_HASH_ALG_MD5;
+ if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) {
+ /*
+ * it's before negotiating hash algorithm.
+ * We use md5 as default.
+ */
+ type = OAKLEY_ATTR_HASH_ALG_MD5;
+ }
} else
- type = iph1->approval->hashtype;
-
- res = alg_oakley_hmacdef_one(type, key, buf);
+ {
+ type = iph1->approval->hashtype;
+ }
+ res = alg_oakley_hmacdef_one(type, key, buf);
if (res == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"invalid hmac algorithm %d.\n", type);
return NULL;
}
* hash
*/
vchar_t *
-oakley_hash(buf, iph1)
- vchar_t *buf;
- struct ph1handle *iph1;
+oakley_hash(vchar_t *buf, phase1_handle_t *iph1)
{
vchar_t *res = NULL;
- int type;
+ int type = OAKLEY_ATTR_HASH_ALG_MD5;
if (iph1->approval == NULL) {
- /*
- * it's before negotiating hash algorithm.
- * We use md5 as default.
- */
- type = OAKLEY_ATTR_HASH_ALG_MD5;
- } else
- type = iph1->approval->hashtype;
+ if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) {
+ /*
+ * it's before negotiating hash algorithm.
+ * We use md5 as default.
+ */
+ type = OAKLEY_ATTR_HASH_ALG_MD5;
+ }
+ } else {
+ if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) {
+ type = iph1->approval->hashtype;
+ }
+ }
res = alg_oakley_hashdef_one(type, buf);
if (res == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"invalid hash algorithm %d.\n", type);
return NULL;
}
* see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
*/
int
-oakley_compute_keymat(iph2, side)
- struct ph2handle *iph2;
- int side;
+oakley_compute_keymat(phase2_handle_t *iph2, int side)
{
int error = -1;
/* compute sharing secret of DH when PFS */
if (iph2->approval->pfs_group && iph2->dhpub_p) {
+#ifdef HAVE_OPENSSL
if (oakley_dh_compute(iph2->pfsgrp, iph2->dhpub,
- iph2->dhpriv, iph2->dhpub_p, &iph2->dhgxy) < 0)
+ iph2->dhpriv, iph2->dhpub_p, &iph2->dhgxy) < 0)
+#else
+ if (oakley_dh_compute(iph2->pfsgrp, iph2->dhpub_p, iph2->publicKeySize, &iph2->dhgxy, &iph2->dhC) < 0)
+#endif
goto end;
}
|| oakley_compute_keymat_x(iph2, side, OUTBOUND_SA) < 0)
goto end;
- plog(LLV_DEBUG, LOCATION, NULL, "KEYMAT computed.\n");
+ plog(ASL_LEVEL_DEBUG, "KEYMAT computed.\n");
error = 0;
* so we do not implement RFC2409 Appendix B (DOORAK-MAC example).
*/
static int
-oakley_compute_keymat_x(iph2, side, sa_dir)
- struct ph2handle *iph2;
- int side;
- int sa_dir;
+oakley_compute_keymat_x(phase2_handle_t *iph2, int side, int sa_dir)
{
vchar_t *buf = NULL, *res = NULL, *bp;
char *p;
+ iph2->nonce_p->l);
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get keymat buffer.\n");
goto end;
}
p += bp->l;
/* compute IV */
- plog(LLV_DEBUG, LOCATION, NULL, "KEYMAT compute with\n");
- plogdump(LLV_DEBUG, buf->v, buf->l);
+ //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "KEYMAT compute with\n");
/* res = K1 */
res = oakley_prf(iph2->ph1->skeyid_d, buf, iph2->ph1);
default:
break;
}
- plog(LLV_DEBUG, LOCATION, NULL, "encklen=%d authklen=%d\n",
+ plog(ASL_LEVEL_DEBUG, "encklen=%d authklen=%d\n",
encklen, authklen);
dupkeymat = (encklen + authklen) / 8 / res->l;
dupkeymat += 2; /* safety mergin */
if (dupkeymat < 3)
dupkeymat = 3;
- plog(LLV_DEBUG, LOCATION, NULL,
- "generating %zu bits of key (dupkeymat=%d)\n",
- dupkeymat * 8 * res->l, dupkeymat);
+ //plog(ASL_LEVEL_DEBUG,
+ // "generating %zu bits of key (dupkeymat=%d)\n",
+ // dupkeymat * 8 * res->l, dupkeymat);
if (0 < --dupkeymat) {
vchar_t *prev = res; /* K(n-1) */
vchar_t *seed = NULL; /* seed for Kn */
* K3 = prf(SKEYID_d, K2 | src)
* Kn = prf(SKEYID_d, K(n-1) | src)
*/
- plog(LLV_DEBUG, LOCATION, NULL,
- "generating K1...K%d for KEYMAT.\n",
- dupkeymat + 1);
+ //plog(ASL_LEVEL_DEBUG,
+ // "generating K1...K%d for KEYMAT.\n",
+ // dupkeymat + 1);
seed = vmalloc(prev->l + buf->l);
if (seed == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get keymat buffer.\n");
if (prev && prev != res)
vfree(prev);
this = oakley_prf(iph2->ph1->skeyid_d, seed,
iph2->ph1);
if (!this) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"oakley_prf memory overflow\n");
if (prev && prev != res)
vfree(prev);
prev = res;
if (res == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get keymat buffer.\n");
if (prev && prev != res)
vfree(prev);
vfree(seed);
}
- plogdump(LLV_DEBUG, res->v, res->l);
+ //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "");
if (sa_dir == INBOUND_SA)
pr->keymat = res;
return error;
}
-#if notyet
-/*
- * NOTE: Must terminate by NULL.
- */
-vchar_t *
-oakley_compute_hashx(struct ph1handle *iph1, ...)
-{
- vchar_t *buf, *res;
- vchar_t *s;
- caddr_t p;
- int len;
-
- va_list ap;
-
- /* get buffer length */
- va_start(ap, iph1);
- len = 0;
- while ((s = va_arg(ap, vchar_t *)) != NULL) {
- len += s->l
- }
- va_end(ap);
-
- buf = vmalloc(len);
- if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get hash buffer\n");
- return NULL;
- }
-
- /* set buffer */
- va_start(ap, iph1);
- p = buf->v;
- while ((s = va_arg(ap, char *)) != NULL) {
- memcpy(p, s->v, s->l);
- p += s->l;
- }
- va_end(ap);
-
- plog(LLV_DEBUG, LOCATION, NULL, "HASH with: \n");
- plogdump(LLV_DEBUG, buf->v, buf->l);
-
- /* compute HASH */
- res = oakley_prf(iph1->skeyid_a, buf, iph1);
- vfree(buf);
- if (res == NULL)
- return NULL;
-
- plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
- plogdump(LLV_DEBUG, res->v, res->l);
-
- return res;
-}
-#endif
/*
* compute HASH(3) prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
* see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
*/
vchar_t *
-oakley_compute_hash3(iph1, msgid, body)
- struct ph1handle *iph1;
- u_int32_t msgid;
- vchar_t *body;
+oakley_compute_hash3(phase1_handle_t *iph1, u_int32_t msgid, vchar_t *body)
{
vchar_t *buf = 0, *res = 0;
int len;
len = 1 + sizeof(u_int32_t) + body->l;
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_NOTICE,
"failed to get hash buffer\n");
goto end;
}
memcpy(buf->v + 1 + sizeof(u_int32_t), body->v, body->l);
- plog(LLV_DEBUG, LOCATION, NULL, "HASH with: \n");
- plogdump(LLV_DEBUG, buf->v, buf->l);
-
/* compute HASH */
res = oakley_prf(iph1->skeyid_a, buf, iph1);
if (res == NULL)
error = 0;
- plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
- plogdump(LLV_DEBUG, res->v, res->l);
+ //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH computed:\n");
end:
if (buf != NULL)
* prf(SKEYID_a, M-ID | N/D)
*/
vchar_t *
-oakley_compute_hash1(iph1, msgid, body)
- struct ph1handle *iph1;
- u_int32_t msgid;
- vchar_t *body;
+oakley_compute_hash1(phase1_handle_t *iph1, u_int32_t msgid, vchar_t *body)
{
vchar_t *buf = NULL, *res = NULL;
char *p;
len = sizeof(u_int32_t) + body->l;
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_NOTICE,
"failed to get hash buffer\n");
goto end;
}
memcpy(p, body->v, body->l);
- plog(LLV_DEBUG, LOCATION, NULL, "HASH with:\n");
- plogdump(LLV_DEBUG, buf->v, buf->l);
-
/* compute HASH */
res = oakley_prf(iph1->skeyid_a, buf, iph1);
if (res == NULL)
error = 0;
- plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
- plogdump(LLV_DEBUG, res->v, res->l);
+ //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH computed:\n");
end:
if (buf != NULL)
* for gssapi, also include all GSS tokens, and call gss_wrap on the result
*/
vchar_t *
-oakley_ph1hash_common(iph1, sw)
- struct ph1handle *iph1;
- int sw;
+oakley_ph1hash_common(phase1_handle_t *iph1, int sw)
{
vchar_t *buf = NULL, *res = NULL, *bp;
char *p, *bp2;
int len, bl;
int error = -1;
-#ifdef HAVE_GSSAPI
- vchar_t *gsstokens = NULL;
-#endif
/* create buffer */
len = iph1->dhpub->l
+ iph1->sa->l
+ (sw == GENERATE ? iph1->id->l : iph1->id_p->l);
-#ifdef HAVE_GSSAPI
- if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
- if (iph1->gi_i != NULL && iph1->gi_r != NULL) {
- bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r);
- len += bp->l;
- }
- if (sw == GENERATE)
- gssapi_get_itokens(iph1, &gsstokens);
- else
- gssapi_get_rtokens(iph1, &gsstokens);
- if (gsstokens == NULL)
- return NULL;
- len += gsstokens->l;
- }
-#endif
-
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get hash buffer\n");
goto end;
}
memcpy(p, bp->v, bp->l);
p += bp->l;
-#ifdef HAVE_GSSAPI
- if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
- if (iph1->gi_i != NULL && iph1->gi_r != NULL) {
- bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r);
- memcpy(p, bp->v, bp->l);
- p += bp->l;
- }
- memcpy(p, gsstokens->v, gsstokens->l);
- p += gsstokens->l;
- }
-#endif
-
- plog(LLV_DEBUG, LOCATION, NULL, "HASH with:\n");
- plogdump(LLV_DEBUG, buf->v, buf->l);
-
/* compute HASH */
res = oakley_prf(iph1->skeyid, buf, iph1);
if (res == NULL)
error = 0;
- plog(LLV_DEBUG, LOCATION, NULL, "HASH (%s) computed:\n",
- iph1->side == INITIATOR ? "init" : "resp");
- plogdump(LLV_DEBUG, res->v, res->l);
-
end:
if (buf != NULL)
vfree(buf);
-#ifdef HAVE_GSSAPI
- if (gsstokens != NULL)
- vfree(gsstokens);
-#endif
return res;
}
* HASH_I = prf(hash(Ni_b | Nr_b), g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
*/
vchar_t *
-oakley_ph1hash_base_i(iph1, sw)
- struct ph1handle *iph1;
- int sw;
+oakley_ph1hash_base_i(phase1_handle_t *iph1, int sw)
{
vchar_t *buf = NULL, *res = NULL, *bp;
vchar_t *hashkey = NULL;
/* sanity check */
if (iph1->etype != ISAKMP_ETYPE_BASE) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"invalid etype for this hash function\n");
return NULL;
}
case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
#endif
if (iph1->skeyid == NULL) {
- plog(LLV_ERROR, LOCATION, NULL, "no SKEYID found.\n");
+ plog(ASL_LEVEL_ERR, "no SKEYID found.\n");
return NULL;
}
hashkey = iph1->skeyid;
break;
- case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
-#ifdef HAVE_GSSAPI
- case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
-#endif
#ifdef ENABLE_HYBRID
case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
- case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
- case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
#endif
/* make hash for seed */
len = iph1->nonce->l + iph1->nonce_p->l;
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get hash buffer\n");
goto end;
}
break;
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"not supported authentication method %d\n",
iph1->approval->authmethod);
return NULL;
+ (sw == GENERATE ? iph1->id->l : iph1->id_p->l);
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get hash buffer\n");
goto end;
}
memcpy(p, bp->v, bp->l);
p += bp->l;
- plog(LLV_DEBUG, LOCATION, NULL, "HASH_I with:\n");
- plogdump(LLV_DEBUG, buf->v, buf->l);
+ //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "HASH_I with:\n");
/* compute HASH */
res = oakley_prf(hashkey, buf, iph1);
error = 0;
- plog(LLV_DEBUG, LOCATION, NULL, "HASH_I computed:\n");
- plogdump(LLV_DEBUG, res->v, res->l);
+ //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH_I computed:\n");
end:
if (hash != NULL)
* HASH_R = prf(hash(Ni_b | Nr_b), g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b)
*/
vchar_t *
-oakley_ph1hash_base_r(iph1, sw)
- struct ph1handle *iph1;
- int sw;
+oakley_ph1hash_base_r(phase1_handle_t *iph1, int sw)
{
vchar_t *buf = NULL, *res = NULL, *bp;
vchar_t *hash = NULL;
/* sanity check */
if (iph1->etype != ISAKMP_ETYPE_BASE) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"invalid etype for this hash function\n");
return NULL;
}
switch(AUTHMETHOD(iph1)) {
- case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
#ifdef ENABLE_HYBRID
case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
- case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
- case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
#endif
break;
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"not supported authentication method %d\n",
iph1->approval->authmethod);
return NULL;
len = iph1->nonce->l + iph1->nonce_p->l;
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get hash buffer\n");
goto end;
}
+ (sw == GENERATE ? iph1->id_p->l : iph1->id->l);
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get hash buffer\n");
goto end;
}
memcpy(p, bp->v, bp->l);
p += bp->l;
- plog(LLV_DEBUG, LOCATION, NULL, "HASH_R with:\n");
- plogdump(LLV_DEBUG, buf->v, buf->l);
+ //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "HASH_R with:\n");
/* compute HASH */
res = oakley_prf(hash, buf, iph1);
error = 0;
- plog(LLV_DEBUG, LOCATION, NULL, "HASH_R computed:\n");
- plogdump(LLV_DEBUG, res->v, res->l);
+ //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH_R computed:\n");
end:
if (buf != NULL)
return res;
}
+#if HAVE_OPENDIR
+static int
+oakley_verify_userid(phase1_handle_t *iph1)
+{
+ cert_t *p;
+ vchar_t *user_id;
+ int user_id_found = 0;
+#ifndef HAVE_OPENSSL
+ SecCertificateRef certificate;
+ CFArrayRef commonNames;
+ CFIndex i, l;
+ CFStringRef name;
+#endif /* HAVE_OPENSSL */
+
+ for (p = iph1->cert_p; p; p = p->chain) {
+#ifdef HAVE_OPENSSL
+ user_id = eay_get_x509_common_name(&p->cert); //%%%%%%%% fix this
+ if (user_id) {
+ user_id_found = 1;
+ // the following functions will check if user_id == 0
+ if (open_dir_authorize_id(user_id, iph1->rmconf->open_dir_auth_group)) {
+ vfree(user_id);
+ return 0;
+ }
+ vfree(user_id);
+ }
+#else /* HAVE_OPENSSL */
+ certificate = crypto_cssm_x509cert_CreateSecCertificateRef(&p->cert);
+ if (certificate == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "ovuid failed to get SecCertificateRef\n");
+ continue;
+ }
+
+ commonNames = SecCertificateCopyCommonNames(certificate);
+ if (commonNames == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "ovuid failed to get commonNames\n");
+ CFRelease(certificate);
+ continue;
+ }
+
+ l = CFArrayGetCount(commonNames);
+ for (i = 0; i < l; i++) {
+ name = CFArrayGetValueAtIndex(commonNames, i);
+ user_id = vmalloc(CFStringGetMaximumSizeForEncoding(CFStringGetLength(name),
+ kCFStringEncodingUTF8) + 1);
+ if (user_id) {
+ if (CFStringGetCString(name, user_id->v, user_id->l,
+ kCFStringEncodingUTF8)) {
+ user_id_found = 1;
+ // the following functions will check if user_id == 0
+ if (open_dir_authorize_id(user_id, iph1->rmconf->open_dir_auth_group)) {
+ vfree(user_id);
+ CFRelease(certificate);
+ CFRelease(commonNames);
+ return 0;
+ }
+ }
+ vfree(user_id);
+ }
+ }
+ CFRelease(certificate);
+ CFRelease(commonNames);
+#endif /* HAVE_OPENSSL */
+ }
+ if (user_id_found) {
+ plog(ASL_LEVEL_ERR,
+ "the peer is not authorized for access.\n");
+ } else {
+ plog(ASL_LEVEL_ERR,
+ "the peer is not authorized for access - user ID not found.\n");
+ }
+ return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
+}
+#endif /* HAVE_OPENDIR */
+
/*
* compute each authentication method in phase 1.
* OUT:
* the value is notification type.
*/
int
-oakley_validate_auth(iph1)
- struct ph1handle *iph1;
+oakley_validate_auth(phase1_handle_t *iph1)
{
vchar_t *my_hash = NULL;
int result;
-#ifdef HAVE_GSSAPI
- vchar_t *gsshash = NULL;
-#endif
#ifdef ENABLE_STATS
struct timeval start, end;
#endif
+ SecKeyRef publicKeyRef = NULL;
#ifdef ENABLE_STATS
gettimeofday(&start, NULL);
char *r_hash;
if (iph1->id_p == NULL || iph1->pl_hash == NULL) {
- plog(LLV_ERROR, LOCATION, iph1->remote,
+ plog(ASL_LEVEL_ERR,
"few isakmp message received.\n");
return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
}
if (AUTHMETHOD(iph1) == FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I &&
((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0))
{
- plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, "
+ plog(ASL_LEVEL_ERR, "No SIG was passed, "
"hybrid auth is enabled, "
"but peer is no Xauth compliant\n");
return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED;
#endif
r_hash = (caddr_t)(iph1->pl_hash + 1);
- plog(LLV_DEBUG, LOCATION, NULL, "HASH received:\n");
- plogdump(LLV_DEBUG, r_hash,
- ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash));
+ //plogdump(ASL_LEVEL_DEBUG, r_hash,
+ // ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash), "HASH received:\n");
- switch (iph1->etype) {
- case ISAKMP_ETYPE_IDENT:
- case ISAKMP_ETYPE_AGG:
- my_hash = oakley_ph1hash_common(iph1, VALIDATE);
- break;
- case ISAKMP_ETYPE_BASE:
- if (iph1->side == INITIATOR)
+ if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) {
+ switch (iph1->etype) {
+ case ISAKMP_ETYPE_IDENT:
+ case ISAKMP_ETYPE_AGG:
my_hash = oakley_ph1hash_common(iph1, VALIDATE);
- else
- my_hash = oakley_ph1hash_base_i(iph1, VALIDATE);
- break;
- default:
- plog(LLV_ERROR, LOCATION, NULL,
- "invalid etype %d\n", iph1->etype);
- return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
+ break;
+ case ISAKMP_ETYPE_BASE:
+ if (iph1->side == INITIATOR)
+ my_hash = oakley_ph1hash_common(iph1, VALIDATE);
+ else
+ my_hash = oakley_ph1hash_base_i(iph1, VALIDATE);
+ break;
+ default:
+ plog(ASL_LEVEL_ERR,
+ "invalid etype %d\n", iph1->etype);
+ return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
+ }
}
if (my_hash == NULL)
return ISAKMP_INTERNAL_ERROR;
vfree(my_hash);
if (result) {
- plog(LLV_ERROR, LOCATION, NULL, "HASH mismatched\n");
+ plog(ASL_LEVEL_ERR, "HASH mismatched\n");
return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
}
- plog(LLV_DEBUG, LOCATION, NULL, "HASH for PSK validated.\n");
+ plog(ASL_LEVEL_DEBUG, "HASH for PSK validated.\n");
}
break;
- case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
#ifdef ENABLE_HYBRID
case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
- case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
#endif
{
int error = 0;
/* validation */
if (iph1->id_p == NULL) {
- plog(LLV_ERROR, LOCATION, iph1->remote,
+ plog(ASL_LEVEL_ERR,
"no ID payload was passed.\n");
return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
}
if (iph1->sig_p == NULL) {
- plog(LLV_ERROR, LOCATION, iph1->remote,
+ plog(ASL_LEVEL_ERR,
"no SIG payload was passed.\n");
return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
}
- plog(LLV_DEBUG, LOCATION, NULL, "SIGN passed:\n");
- plogdump(LLV_DEBUG, iph1->sig_p->v, iph1->sig_p->l);
+ plog(ASL_LEVEL_DEBUG, "SIGN passed\n");
/* get peer's cert */
switch (iph1->rmconf->getcert_method) {
case ISAKMP_GETCERT_PAYLOAD:
if (iph1->cert_p == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"no peer's CERT payload found.\n");
return ISAKMP_INTERNAL_ERROR;
}
break;
- case ISAKMP_GETCERT_LOCALFILE:
- switch (iph1->rmconf->certtype) {
- case ISAKMP_CERT_X509SIGN:
- if (iph1->rmconf->peerscertfile == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "no peer's CERT file found.\n");
- return ISAKMP_INTERNAL_ERROR;
- }
-
- /* don't use cached cert */
- if (iph1->cert_p != NULL) {
- oakley_delcert(iph1->cert_p);
- iph1->cert_p = NULL;
- }
-
- error = get_cert_fromlocal(iph1, 0);
- break;
-
- case ISAKMP_CERT_PLAINRSA:
- error = get_plainrsa_fromlocal(iph1, 0);
- break;
- }
- if (error)
- return ISAKMP_INTERNAL_ERROR;
- break;
- case ISAKMP_GETCERT_DNS:
- if (iph1->rmconf->peerscertfile != NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "why peer's CERT file is defined "
- "though getcert method is dns ?\n");
- return ISAKMP_INTERNAL_ERROR;
- }
-
- /* don't use cached cert */
- if (iph1->cert_p != NULL) {
- oakley_delcert(iph1->cert_p);
- iph1->cert_p = NULL;
- }
-
- iph1->cert_p = dnssec_getcert(iph1->id_p);
- if (iph1->cert_p == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "no CERT RR found.\n");
- return ISAKMP_INTERNAL_ERROR;
- }
- break;
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"invalid getcert_mothod: %d\n",
iph1->rmconf->getcert_method);
return ISAKMP_INTERNAL_ERROR;
/* compare ID payload and certificate name */
if (iph1->rmconf->verify_cert &&
-#ifdef __APPLE__
- (error = oakley_check_certid(iph1, CERT_CHECKID_FROM_PEER)) != 0)
-#else
- (error = oakley_check_certid(iph1)) != 0)
-#endif
- return error;
-
-#ifdef __APPLE__
-
- /* check configured peers identifier against cert IDs */
- /* allows checking of specified ID against multiple ids in the cert */
- /* such as multiple domain names */
-#if !TARGET_OS_EMBEDDED
- if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_PEERS_IDENTIFIER &&
- (error = oakley_check_certid(iph1, CERT_CHECKID_FROM_RMCONFIG)) != 0)
+ (error = oakley_check_certid(iph1)) != 0)
return error;
-#endif
#if HAVE_OPENDIR
/* check cert common name against Open Directory authentication group */
if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_OPEN_DIR) {
-
- vchar_t *user_id = NULL;
-
- user_id = eay_get_x509_common_name(&iph1->cert_p->cert);
- if (user_id) {
- // the following functions will check if user_id == 0
- if (open_dir_authorize_id(user_id, iph1->rmconf->open_dir_auth_group) == 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "the peer is not authorized for access.\n");
- vfree(user_id);
- return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
- }
- vfree(user_id);
- } else {
- plog(LLV_ERROR, LOCATION, NULL,
- "the peer is not authorized for access - user ID not found.\n");
- return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
+ if (oakley_verify_userid(iph1)) {
+ return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
}
}
#endif /* HAVE_OPENDIR */
-#endif /* __APPLE__ */
/* verify certificate */
if (iph1->rmconf->verify_cert
#ifdef ENABLE_HYBRID
switch (AUTHMETHOD(iph1)) {
case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
- case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
certtype = iph1->cert_p->type;
break;
default:
#endif
switch (certtype) {
case ISAKMP_CERT_X509SIGN:
-
-#if TARGET_OS_EMBEDDED
{
/* use ID from remote configuration */
/* check each ID in list */
if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_PEERS_IDENTIFIER) {
id_spec = genlist_next(iph1->rmconf->idvl_p, &gpb); /* expect only one id */
if (id_spec->idtype == IDTYPE_ADDRESS) {
- switch (((struct sockaddr *)(id_spec->id->v))->sa_family) {
+ switch ((ALIGNED_CAST(struct sockaddr_storage *)(id_spec->id->v))->ss_family) {
case AF_INET:
- peers_id = inet_ntoa(((struct sockaddr_in *)(id_spec->id->v))->sin_addr);
+ peers_id = inet_ntoa((ALIGNED_CAST(struct sockaddr_in *)(id_spec->id->v))->sin_addr);
hostname = CFStringCreateWithCString(NULL, peers_id, kCFStringEncodingUTF8);
break;
#ifdef INET6
break;
#endif
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"unknown address type for peers identifier.\n");
return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
break;
} else
hostname = CFStringCreateWithBytes(NULL, (u_int8_t *)id_spec->id->v, id_spec->id->l, kCFStringEncodingUTF8, FALSE);
}
- error = crypto_cssm_check_x509cert(&iph1->cert_p->cert, hostname);
+ error = crypto_cssm_check_x509cert(oakley_get_peer_cert_from_certchain(iph1), iph1->cert_p, hostname, &publicKeyRef);
if (hostname)
CFRelease(hostname);
}
-
-#else /* TARGET_OS_EMBEDDED */
-#ifdef __APPLE__
- if (iph1->rmconf->cert_verification == VERIFICATION_MODULE_SEC_FRAMEWORK)
- error = crypto_cssm_check_x509cert(&iph1->cert_p->cert, NULL);
- else
-#endif /* __APPLE__ */
- {
- char path[MAXPATHLEN];
- char *ca;
-
- if (iph1->rmconf->cacertfile != NULL) {
- getpathname(path, sizeof(path),
- LC_PATHTYPE_CERT,
- iph1->rmconf->cacertfile);
- ca = path;
- } else {
- ca = NULL;
- }
-
- error = eay_check_x509cert(&iph1->cert_p->cert,
- lcconf->pathinfo[LC_PATHTYPE_CERT],
- ca, 0);
- }
-#endif /* TARGET_OS_EMBEDDED */
- break;
+ break;
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"no supported certtype %d\n", certtype);
return ISAKMP_INTERNAL_ERROR;
}
if (error != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"the peer's certificate is not verified.\n");
return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY;
}
}
- plog(LLV_DEBUG, LOCATION, NULL, "CERT validated\n");
+ plog(ASL_LEVEL_DEBUG, "CERT validated\n");
- /* compute hash */
- switch (iph1->etype) {
- case ISAKMP_ETYPE_IDENT:
- case ISAKMP_ETYPE_AGG:
- my_hash = oakley_ph1hash_common(iph1, VALIDATE);
- break;
- case ISAKMP_ETYPE_BASE:
- if (iph1->side == INITIATOR)
- my_hash = oakley_ph1hash_base_r(iph1, VALIDATE);
- else
- my_hash = oakley_ph1hash_base_i(iph1, VALIDATE);
- break;
- default:
- plog(LLV_ERROR, LOCATION, NULL,
- "invalid etype %d\n", iph1->etype);
- return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
+ if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) {
+ /* compute hash */
+ switch (iph1->etype) {
+ case ISAKMP_ETYPE_IDENT:
+ case ISAKMP_ETYPE_AGG:
+ my_hash = oakley_ph1hash_common(iph1, VALIDATE);
+ break;
+ case ISAKMP_ETYPE_BASE:
+ if (iph1->side == INITIATOR)
+ my_hash = oakley_ph1hash_base_r(iph1, VALIDATE);
+ else
+ my_hash = oakley_ph1hash_base_i(iph1, VALIDATE);
+ break;
+ default:
+ plog(ASL_LEVEL_ERR,
+ "invalid etype %d\n", iph1->etype);
+ return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
+ }
}
if (my_hash == NULL)
return ISAKMP_INTERNAL_ERROR;
#ifdef ENABLE_HYBRID
switch (AUTHMETHOD(iph1)) {
case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
- case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
certtype = iph1->cert_p->type;
break;
default:
#endif
/* check signature */
switch (certtype) {
- case ISAKMP_CERT_X509SIGN:
- case ISAKMP_CERT_DNS:
- error = eay_check_x509sign(my_hash,
- iph1->sig_p,
- &iph1->cert_p->cert);
- break;
- case ISAKMP_CERT_PLAINRSA:
- iph1->rsa_p = rsa_try_check_rsasign(my_hash,
- iph1->sig_p, iph1->rsa_candidates);
- error = iph1->rsa_p ? 0 : -1;
-
- break;
- default:
- plog(LLV_ERROR, LOCATION, NULL,
- "no supported certtype %d\n",
- certtype);
- vfree(my_hash);
- return ISAKMP_INTERNAL_ERROR;
+ case ISAKMP_CERT_X509SIGN:
+ if (publicKeyRef == NULL) {
+ plog(ASL_LEVEL_ERR, "@@@@@@ publicKeyRef is NULL\n");
+ }
+ if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) {
+ error = crypto_cssm_verify_x509sign(publicKeyRef, my_hash, iph1->sig_p, FALSE);
+ }
+ if (error) {
+ plog(ASL_LEVEL_ERR, "error verifying signature %s\n", GetSecurityErrorString(error));
+ }
+
+ CFRelease(publicKeyRef);
+ break;
+ default:
+ plog(ASL_LEVEL_ERR,
+ "no supported certtype %d\n",
+ certtype);
+ vfree(my_hash);
+ return ISAKMP_INTERNAL_ERROR;
}
vfree(my_hash);
if (error != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Invalid SIG.\n");
return ISAKMP_NTYPE_INVALID_SIGNATURE;
}
- plog(LLV_DEBUG, LOCATION, NULL, "SIG authenticated\n");
+ plog(ASL_LEVEL_DEBUG, "SIG authenticated\n");
}
break;
#ifdef ENABLE_HYBRID
case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
- case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
{
if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
- plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, "
+ plog(ASL_LEVEL_ERR, "No SIG was passed, "
"hybrid auth is enabled, "
"but peer is no Xauth compliant\n");
return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED;
break;
}
- plog(LLV_INFO, LOCATION, NULL, "No SIG was passed, "
+ plog(ASL_LEVEL_NOTICE, "No SIG was passed, "
"but hybrid auth is enabled\n");
return 0;
break;
}
-#endif
-#ifdef HAVE_GSSAPI
- case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
- /* check if we're not into XAUTH_PSKEY_I instead */
-#ifdef ENABLE_HYBRID
- if (iph1->rmconf->xauth)
- break;
-#endif
- switch (iph1->etype) {
- case ISAKMP_ETYPE_IDENT:
- case ISAKMP_ETYPE_AGG:
- my_hash = oakley_ph1hash_common(iph1, VALIDATE);
- break;
- default:
- plog(LLV_ERROR, LOCATION, NULL,
- "invalid etype %d\n", iph1->etype);
- return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
- }
-
- if (my_hash == NULL) {
- if (gssapi_more_tokens(iph1))
- return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
- else
- return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
- }
-
- gsshash = gssapi_unwraphash(iph1);
- if (gsshash == NULL) {
- vfree(my_hash);
- return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
- }
-
- result = memcmp(my_hash->v, gsshash->v, my_hash->l);
- vfree(my_hash);
- vfree(gsshash);
-
- if (result) {
- plog(LLV_ERROR, LOCATION, NULL, "HASH mismatched\n");
- return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
- }
- plog(LLV_DEBUG, LOCATION, NULL, "hash compared OK\n");
- break;
#endif
case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
#endif
if (iph1->id_p == NULL || iph1->pl_hash == NULL) {
- plog(LLV_ERROR, LOCATION, iph1->remote,
+ plog(ASL_LEVEL_ERR,
"few isakmp message received.\n");
return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
}
- plog(LLV_ERROR, LOCATION, iph1->remote,
+ plog(ASL_LEVEL_ERR,
"not supported authmethod type %s\n",
s_oakley_attr_method(iph1->approval->authmethod));
return ISAKMP_INTERNAL_ERROR;
default:
- plog(LLV_ERROR, LOCATION, iph1->remote,
+ plog(ASL_LEVEL_ERR,
"invalid authmethod %d why ?\n",
iph1->approval->authmethod);
return ISAKMP_INTERNAL_ERROR;
}
#ifdef ENABLE_STATS
gettimeofday(&end, NULL);
- syslog(LOG_NOTICE, "%s(%s): %8.6f", __func__,
+ plog(ASL_LEVEL_NOTICE, "%s(%s): %8.6f", __func__,
s_oakley_attr_method(iph1->approval->authmethod),
timedelta(&start, &end));
#endif
return 0;
}
+int
+oakley_find_status_in_certchain (cert_t *certchain, cert_status_t certStatus)
+{
+ cert_t *p;
+
+ for (p = certchain; p; p = p->chain) {
+ if (p->status == certStatus) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static
+int
+oakley_vpncontrol_notify_ike_failed_if_mycert_invalid (phase1_handle_t *iph1, int notify_initiator)
+{
+#ifndef HAVE_OPENSSL
+ int premature = oakley_find_status_in_certchain(iph1->cert, CERT_STATUS_PREMATURE);
+ int expired = oakley_find_status_in_certchain(iph1->cert, CERT_STATUS_EXPIRED);
+ if (premature || expired) {
+ u_int32_t fail_reason;
+
+ if (premature) {
+ fail_reason = VPNCTL_NTYPE_LOCAL_CERT_PREMATURE;
+ } else {
+ fail_reason = VPNCTL_NTYPE_LOCAL_CERT_EXPIRED;
+ }
+ vpncontrol_notify_ike_failed(fail_reason, notify_initiator, iph1_get_remote_v4_address(iph1), 0, NULL);
+ return -1;
+ }
+#endif /* HAVE_OPENSSL */
+ return 0;
+}
+
/* get my certificate
* NOTE: include certificate type.
*/
int
-oakley_getmycert(iph1)
- struct ph1handle *iph1;
+oakley_getmycert(phase1_handle_t *iph1)
{
+ int err;
+
switch (iph1->rmconf->certtype) {
case ISAKMP_CERT_X509SIGN:
if (iph1->cert)
return 0;
- return get_cert_fromlocal(iph1, 1);
-
- case ISAKMP_CERT_PLAINRSA:
- if (iph1->rsa)
- return 0;
- return get_plainrsa_fromlocal(iph1, 1);
-
+ if ( !(err = get_cert_fromlocal(iph1, 1))){
+ if (oakley_vpncontrol_notify_ike_failed_if_mycert_invalid(iph1, FROM_LOCAL)) {
+ return -1;
+ }
+ }
+ return err;
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Unknown certtype #%d\n",
iph1->rmconf->certtype);
return -1;
* my == 0 peer's cert.
*/
static int
-get_cert_fromlocal(iph1, my)
- struct ph1handle *iph1;
- int my;
+get_cert_fromlocal(phase1_handle_t *iph1, int my)
{
- char path[MAXPATHLEN];
vchar_t *cert = NULL;
cert_t **certpl;
- char *certfile;
int error = -1;
+ cert_status_t status = CERT_STATUS_OK;
- if (my) {
- certfile = iph1->rmconf->mycertfile;
+ if (my)
certpl = &iph1->cert;
- } else {
- certfile = iph1->rmconf->peerscertfile;
+ else
certpl = &iph1->cert_p;
- }
-
-#ifdef __APPLE__
- if (!certfile && iph1->rmconf->identity_in_keychain == 0) {
-#else
- if (!certfile) {
-#endif
- plog(LLV_ERROR, LOCATION, NULL, "no CERT defined.\n");
+ if (iph1->rmconf->identity_in_keychain == 0) {
+ plog(ASL_LEVEL_ERR, "no CERT defined.\n");
return 0;
}
switch (iph1->rmconf->certtype) {
case ISAKMP_CERT_X509SIGN:
-#if defined(__APPLE__)
if (iph1->rmconf->identity_in_keychain) {
CFDataRef dataRef;
if (iph1->rmconf->keychainCertRef == NULL || base64toCFData(iph1->rmconf->keychainCertRef, &dataRef))
goto end;
- cert = crypto_cssm_get_x509cert(dataRef);
+ cert = crypto_cssm_get_x509cert(dataRef, &status);
+ plog(ASL_LEVEL_DEBUG, "done with chking cert status %d\n",status);
CFRelease(dataRef);
break;
} // else fall thru
-#endif
- case ISAKMP_CERT_DNS:
- /* make public file name */
- getpathname(path, sizeof(path), LC_PATHTYPE_CERT, certfile);
- cert = eay_get_x509cert(path);
- if (cert) {
- char *p = NULL;
- p = eay_get_x509text(cert);
- plog(LLV_DEBUG, LOCATION, NULL, "%s", p ? p : "\n");
- racoon_free(p);
- };
- break;
-
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"not supported certtype %d\n",
iph1->rmconf->certtype);
goto end;
}
if (!cert) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get %s CERT.\n",
my ? "my" : "peers");
goto end;
*certpl = oakley_newcert();
if (!*certpl) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get cert buffer.\n");
goto end;
}
(*certpl)->pl = vmalloc(cert->l + 1);
if ((*certpl)->pl == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get cert buffer\n");
oakley_delcert(*certpl);
*certpl = NULL;
memcpy((*certpl)->pl->v + 1, cert->v, cert->l);
(*certpl)->pl->v[0] = iph1->rmconf->certtype;
(*certpl)->type = iph1->rmconf->certtype;
+ (*certpl)->status = status;
(*certpl)->cert.v = (*certpl)->pl->v + 1;
(*certpl)->cert.l = (*certpl)->pl->l - 1;
- plog(LLV_DEBUG, LOCATION, NULL, "created CERT payload:\n");
- plogdump(LLV_DEBUG, (*certpl)->pl->v, (*certpl)->pl->l);
-
+ plog(ASL_LEVEL_DEBUG, "created CERT payload\n");
+
error = 0;
end:
return error;
}
-static int
-get_plainrsa_fromlocal(iph1, my)
- struct ph1handle *iph1;
- int my;
-{
- char path[MAXPATHLEN];
- vchar_t *cert = NULL;
- char *certfile;
- int error = -1;
-
- iph1->rsa_candidates = rsa_lookup_keys(iph1, my);
- if (!iph1->rsa_candidates ||
- rsa_list_count(iph1->rsa_candidates) == 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "%s RSA key not found for %s\n",
- my ? "Private" : "Public",
- saddr2str_fromto("%s <-> %s",
- iph1->local, iph1->remote));
- goto end;
- }
-
- if (my && rsa_list_count(iph1->rsa_candidates) > 1) {
- plog(LLV_WARNING, LOCATION, NULL,
- "More than one (=%lu) private "
- "PlainRSA key found for %s\n",
- rsa_list_count(iph1->rsa_candidates),
- saddr2str_fromto("%s <-> %s",
- iph1->local, iph1->remote));
- plog(LLV_WARNING, LOCATION, NULL,
- "This may have unpredictable results, "
- "i.e. wrong key could be used!\n");
- plog(LLV_WARNING, LOCATION, NULL,
- "Consider using only one single private "
- "key for all peers...\n");
- }
- if (my) {
- iph1->rsa = ((struct rsa_key *)
- genlist_next(iph1->rsa_candidates, NULL))->rsa;
-
- genlist_free(iph1->rsa_candidates, NULL);
- iph1->rsa_candidates = NULL;
-
- if (iph1->rsa == NULL)
- goto end;
- }
-
- error = 0;
-
-end:
- return error;
-}
/* get signature */
int
-oakley_getsign(iph1)
- struct ph1handle *iph1;
+oakley_getsign(phase1_handle_t *iph1)
{
- char path[MAXPATHLEN];
vchar_t *privkey = NULL;
int error = -1;
switch (iph1->rmconf->certtype) {
case ISAKMP_CERT_X509SIGN:
-#if defined(__APPLE__)
// cert in keychain - use cssm to sign
if (iph1->rmconf->identity_in_keychain) {
CFDataRef dataRef;
CFRelease(dataRef);
break;
} // else fall thru
-#endif
- case ISAKMP_CERT_DNS:
- if (iph1->rmconf->myprivfile == NULL) {
- plog(LLV_ERROR, LOCATION, NULL, "no cert defined.\n");
- goto end;
- }
-
- /* make private file name */
- getpathname(path, sizeof(path),
- LC_PATHTYPE_CERT,
- iph1->rmconf->myprivfile);
- privkey = privsep_eay_get_pkcs1privkey(path);
- if (privkey == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get private key.\n");
- goto end;
- }
- plog(LLV_DEBUG2, LOCATION, NULL, "private key:\n");
- plogdump(LLV_DEBUG2, privkey->v, privkey->l);
-
- iph1->sig = eay_get_x509sign(iph1->hash, privkey);
- break;
- case ISAKMP_CERT_PLAINRSA:
- iph1->sig = eay_get_rsasign(iph1->hash, iph1->rsa);
- break;
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Unknown certtype #%d\n",
iph1->rmconf->certtype);
goto end;
}
if (iph1->sig == NULL) {
- plog(LLV_ERROR, LOCATION, NULL, "failed to sign.\n");
+ plog(ASL_LEVEL_ERR, "failed to sign.\n");
goto end;
}
- plog(LLV_DEBUG, LOCATION, NULL, "SIGN computed:\n");
- plogdump(LLV_DEBUG, iph1->sig->v, iph1->sig->l);
+ //plogdump(ASL_LEVEL_DEBUG, iph1->sig->v, iph1->sig->l, "SIGN computed:\n");
error = 0;
return error;
}
-#ifdef __APPLE__
+void
+oakley_verify_certid(phase1_handle_t *iph1)
+{
+ if (iph1->rmconf->verify_cert &&
+ oakley_check_certid(iph1)){
+ plog(ASL_LEVEL_DEBUG,
+ "Discarding CERT: does not match ID:\n");
+ oakley_delcert(iph1->cert_p);
+ iph1->cert_p = NULL;
+ }
+}
+
+static int
+oakley_check_certid_in_certchain(cert_t *certchain, int idtype, int idlen, void *id)
+{
+ cert_t *p;
+
+ for (p = certchain; p; p = p->chain) {
+ if (oakley_check_certid_1(&p->cert, idtype, idlen, id, &p->status) == 0) {
+ return 0;
+ }
+ }
+ return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
+}
+
+cert_t *
+oakley_get_peer_cert_from_certchain(phase1_handle_t * iph1)
+{
+ cert_t *p;
+ struct ipsecdoi_id_b *id_b;
+ int idlen;
+ void *peers_id;
+
+ if (!iph1->id_p || !iph1->cert_p) {
+ plog(ASL_LEVEL_ERR, "no ID nor CERT found.\n");
+ return NULL;
+ }
+ if (!iph1->cert_p->chain) {
+ // no chain: simply return the only cert
+ return iph1->cert_p;
+ }
+
+ id_b = ALIGNED_CAST(struct ipsecdoi_id_b *)iph1->id_p->v;
+ peers_id = id_b + 1;
+ idlen = iph1->id_p->l - sizeof(*id_b);
+ for (p = iph1->cert_p; p; p = p->chain) {
+ if (oakley_check_certid_1(&p->cert, id_b->type, idlen, peers_id, &p->status) == 0) {
+ return p;
+ }
+ }
+ return NULL;
+}
/*
* compare certificate name and ID value.
*/
static int
-oakley_check_certid(iph1, which_id)
- struct ph1handle *iph1;
- int which_id;
+oakley_check_certid(phase1_handle_t *iph1)
{
struct ipsecdoi_id_b *id_b;
int idlen;
u_int8_t doi_type = 255;
void *peers_id = NULL;
- struct genlist_entry *gpb = NULL;
- if (which_id == CERT_CHECKID_FROM_PEER) {
- /* use ID from peer */
- if (iph1->id_p == NULL || iph1->cert_p == NULL) {
- plog(LLV_ERROR, LOCATION, NULL, "no ID nor CERT found.\n");
- return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
- }
- id_b = (struct ipsecdoi_id_b *)iph1->id_p->v;
- doi_type = id_b->type;
- peers_id = id_b + 1;
- idlen = iph1->id_p->l - sizeof(*id_b);
-
- return oakley_check_certid_1(iph1, doi_type, idlen, peers_id);
+ /* use ID from peer */
+ if (iph1->id_p == NULL || iph1->cert_p == NULL) {
+ plog(ASL_LEVEL_ERR, "no ID nor CERT found.\n");
+ return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
+ }
+ id_b = ALIGNED_CAST(struct ipsecdoi_id_b *)iph1->id_p->v;
+ doi_type = id_b->type;
+ peers_id = id_b + 1;
+ idlen = iph1->id_p->l - sizeof(*id_b);
+
+ return oakley_check_certid_in_certchain(iph1->cert_p, doi_type, idlen, peers_id);
- } else {
- /* use ID from remote configuration */
- /* check each ID in list */
- struct idspec *id_spec;
-
- for (id_spec = genlist_next (iph1->rmconf->idvl_p, &gpb); id_spec; id_spec = genlist_next (0, &gpb)) {
-
- if (id_spec->idtype == IDTYPE_ADDRESS) {
- switch (((struct sockaddr *)(id_spec->id->v))->sa_family) {
- case AF_INET:
- doi_type = IPSECDOI_ID_IPV4_ADDR;
- idlen = sizeof(struct in_addr);
- peers_id = &(((struct sockaddr_in *)(id_spec->id->v))->sin_addr.s_addr);
- break;
- #ifdef INET6
- case AF_INET6:
- doi_type = IPSECDOI_ID_IPV6_ADDR;
- idlen = sizeof(struct in6_addr);
- peers_id = &(((struct sockaddr_in6 *)(id_spec->id->v))->sin6_addr.s6_addr);
- break;
- #endif
- default:
- plog(LLV_ERROR, LOCATION, NULL,
- "unknown address type for peers identifier.\n");
- return ISAKMP_NTYPE_AUTHENTICATION_FAILED;
- break;
- }
-
- } else {
- doi_type = idtype2doi(id_spec->idtype);
- peers_id = id_spec->id->v;
- idlen = id_spec->id->l;
- }
- if (oakley_check_certid_1(iph1, doi_type, idlen, peers_id) == 0)
- return 0;
- }
- return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
- }
}
-
+
static int
-oakley_check_certid_1(iph1, idtype, idlen, id)
- struct ph1handle *iph1;
- int idtype;
- int idlen;
- void *id;
+oakley_check_certid_1(vchar_t *cert, int idtype, int idlen, void *id, cert_status_t *certStatus)
{
- vchar_t *name = NULL;
- char *altname = NULL;
- int type, len;
- int error;
+ int len = 0;
+ int error = 0;
+#ifdef HAVE_OPENSSL
+ int type;
+ char *altname = NULL;
+#endif
+
switch (idtype) {
case IPSECDOI_ID_DER_ASN1_DN:
- name = eay_get_x509asn1subjectname(&iph1->cert_p->cert);
- if (!name) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get subjectName\n");
+ {
+ CFDataRef subject;
+ SecCertificateRef certificate;
+ UInt8* namePtr = NULL;
+
+ certificate = crypto_cssm_x509cert_CreateSecCertificateRef(cert);
+ if (certificate == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "failed to get SecCertificateRef\n");
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID;
+ }
return ISAKMP_NTYPE_INVALID_CERTIFICATE;
- }
- if (idlen != name->l) {
- plog(LLV_ERROR, LOCATION, NULL,
- "Invalid ID length in phase 1.\n");
- vfree(name);
- return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
- }
- error = memcmp(id, name->v, idlen);
- vfree(name);
- if (error != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "ID mismatched with subjectName.\n");
- return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
- }
- return 0;
+ }
+ subject = crypto_cssm_CopySubjectSequence(certificate);
+ if (subject == NULL) {
+ plog(ASL_LEVEL_ERR, "failed to get certificate subjectName\n");
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID_SUBJNAME;
+ }
+ error = ISAKMP_NTYPE_INVALID_CERTIFICATE;
+ } else {
+ len = CFDataGetLength(subject);
+ namePtr = (UInt8*)CFDataGetBytePtr(subject);
+ if (namePtr) {
+ if (idlen != len || memcmp(id, namePtr, idlen)) {
+ plog(ASL_LEVEL_ERR, "ID mismatched with certificate subjectName\n");
+ error =ISAKMP_NTYPE_INVALID_ID_INFORMATION;
+ }
+ } else {
+ plog(ASL_LEVEL_ERR, "no certificate subjectName found\n");
+ error = ISAKMP_NTYPE_INVALID_CERTIFICATE;
+ }
+ }
+ if (error) {
+ plog(ASL_LEVEL_ERR,
+ "ID mismatched with certificate subjectName\n");
+ if (namePtr != NULL) {
+ plogdump(ASL_LEVEL_ERR, namePtr, len, "subjectName (type %s):\n",
+ s_ipsecdoi_ident(idtype));
+ } else {
+ plog(ASL_LEVEL_ERR, "subjectName (type %s):\n", s_ipsecdoi_ident(idtype));
+ }
+ plogdump(ASL_LEVEL_ERR, id, idlen, "ID:\n");
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID_SUBJNAME;
+ }
+ }
+ CFRelease(certificate);
+ if (subject != NULL) {
+ CFRelease(subject);
+ }
+ return 0;
+ }
+ break;
+
case IPSECDOI_ID_IPV4_ADDR:
case IPSECDOI_ID_IPV6_ADDR:
{
-
+#ifndef HAVE_OPENSSL
+ CFIndex pos, count;
+ SecCertificateRef certificate;
+ CFArrayRef addresses;
+#define ADDRESS_BUF_SIZE 64
+
+ certificate = crypto_cssm_x509cert_CreateSecCertificateRef(cert);
+ if (certificate == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "failed to get SecCertificateRef\n");
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID;
+ }
+ return ISAKMP_NTYPE_INVALID_CERTIFICATE;
+ }
+ addresses = SecCertificateCopyIPAddresses(certificate);
+ if (addresses == NULL) {
+ plog(ASL_LEVEL_ERR, "failed to get subjectName\n");
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
+ }
+ CFRelease(certificate);
+ return ISAKMP_NTYPE_INVALID_CERTIFICATE;
+ }
+ count = CFArrayGetCount(addresses);
+ for (pos = 0; pos < count; pos++) {
+
+ CFStringRef address;
+ CFIndex addressLen;
+ char *addressBuf, numAddress[128];
+ int result;
+
+ address = CFArrayGetValueAtIndex(addresses, pos);
+ addressLen = CFStringGetLength(address);
+ if (addressLen == 0)
+ continue;
+ addressBuf = racoon_malloc(ADDRESS_BUF_SIZE);
+ if (addressBuf == NULL) {
+ plog(ASL_LEVEL_ERR, "out of memory\n");
+ CFRelease(addresses);
+ CFRelease(certificate);
+ return -1;
+ }
+ if (CFStringGetCString(address, addressBuf, ADDRESS_BUF_SIZE, kCFStringEncodingUTF8) == TRUE) {
+ result = inet_pton(idtype == IPSECDOI_ID_IPV4_ADDR ? AF_INET : AF_INET6, addressBuf, numAddress);
+ racoon_free(addressBuf);
+ if (result == 0)
+ continue; // wrong type or invalid address
+ if (!memcmp(id, numAddress, idtype == IPSECDOI_ID_IPV4_ADDR ? 32 : 128) == 0) { // found a match ?
+ CFRelease(addresses);
+ CFRelease(certificate);
+ return 0;
+ }
+ } else
+ racoon_free(addressBuf);
+ }
+ plog(ASL_LEVEL_ERR, "ID mismatched with subjectAltName.\n");
+ plog(ASL_LEVEL_ERR,
+ "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype));
+ plogdump(ASL_LEVEL_ERR, id, idlen, "ID:\n");
+ CFRelease(addresses);
+ CFRelease(certificate);
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
+ }
+ return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
+#else
/*
* Openssl returns the IPAddress as an ASN1 octet string (binary format)
* followed by a trailing NULL. 5 bytes for IPv4 and 17 bytes for IPv6
int pos;
- if (idtype == IPSECDOI_ID_IPV4_ADDR && idlen != sizeof(struct in_addr)
- || idtype == IPSECDOI_ID_IPV6_ADDR && idlen != sizeof(struct in6_addr)) {
- plog(LLV_ERROR, LOCATION, NULL,
+ if ((idtype == IPSECDOI_ID_IPV4_ADDR && idlen != sizeof(struct in_addr))
+ || (idtype == IPSECDOI_ID_IPV6_ADDR && idlen != sizeof(struct in6_addr))) {
+ plog(ASL_LEVEL_ERR,
"invalid address length passed.\n");
return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
}
for (pos = 1; ; pos++) {
- if (eay_get_x509subjectaltname(&iph1->cert_p->cert, &altname, &type, pos, &len) !=0) {
- plog(LLV_ERROR, LOCATION, NULL,
+ if (eay_get_x509subjectaltname(cert, &altname, &type, pos, &len) !=0) {
+ plog(ASL_LEVEL_ERR,
"failed to get subjectAltName\n");
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
+ }
return ISAKMP_NTYPE_INVALID_CERTIFICATE;
}
/* it's the end condition of the loop. */
if (!altname) {
+ plog(ASL_LEVEL_ERR,
+ "invalid subjectAltName\n");
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
+ }
return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
}
#endif
else {
/* invalid IP address length in certificate - bad or bogus certificate */
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"invalid IP address in certificate.\n");
+ plogdump(ASL_LEVEL_ERR, altname, len, "subjectAltName (expected type %s, got type %s):\n",
+ s_ipsecdoi_ident(idtype),
+ s_ipsecdoi_ident(type));
racoon_free(altname);
altname = NULL;
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
+ }
return ISAKMP_NTYPE_INVALID_CERTIFICATE;
}
/* compare the addresses */
error = memcmp(id, altname, idlen);
+ if (error)
+ continue;
racoon_free(altname);
- if (error != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "ID mismatched with subjectAltName.\n");
- return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
+ return 0;
+ }
+ /* failed to find a match */
+ plog(ASL_LEVEL_ERR,
+ "ID mismatched with subjectAltName.\n");
+ plogdump(ASL_LEVEL_ERR, altname, len, "subjectAltName (expected type %s, got type %s):\n",
+ s_ipsecdoi_ident(idtype),
+ s_ipsecdoi_ident(type));
+ plogdump(ASL_LEVEL_ERR, id, idlen, "ID:\n");
+ racoon_free(altname);
+ if (certStatus && !*certStatus)
+ *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
+ return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
+
+#endif /* HAVE_OPENSSL */
+ }
+
+#ifndef HAVE_OPENSSL
+ case IPSECDOI_ID_FQDN:
+ {
+ CFIndex pos, count;
+ SecCertificateRef certificate;
+ CFArrayRef names;
+ CFStringRef name, ID;
+
+ certificate = crypto_cssm_x509cert_CreateSecCertificateRef(cert);
+ if (certificate == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "failed to get SecCertificateRef\n");
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID;
}
+ return ISAKMP_NTYPE_INVALID_CERTIFICATE;
+ }
+ names = SecCertificateCopyDNSNames(certificate);
+ if (names == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "failed to get subjectName\n");
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
+ }
+ CFRelease(certificate);
+ return ISAKMP_NTYPE_INVALID_CERTIFICATE;
+ }
+ count = CFArrayGetCount(names);
+ ID = CFStringCreateWithBytes(kCFAllocatorDefault, id, idlen, kCFStringEncodingUTF8, FALSE);
+ if (ID== NULL) {
+ plog(ASL_LEVEL_ERR, "memory error\n");
+ CFRelease(names);
+ CFRelease(certificate);
return 0;
}
+ for (pos = 0; pos < count; pos++) {
+ name = CFArrayGetValueAtIndex(names, pos);
+ if (CFStringCompare(name, ID, 0) == kCFCompareEqualTo) {
+ CFRelease(ID);
+ CFRelease(names);
+ CFRelease(certificate);
+ return 0;
+ }
+ }
+ plog(ASL_LEVEL_ERR, "ID mismatched with subjectAltName.\n");
+ plog(ASL_LEVEL_ERR,
+ "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype));
+ plogdump(ASL_LEVEL_ERR, id, idlen, "ID:\n");
+ CFRelease(ID);
+ CFRelease(names);
+ CFRelease(certificate);
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
+ }
+ return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
}
+
+ case IPSECDOI_ID_USER_FQDN:
+ {
+ CFIndex pos, count;
+
+ SecCertificateRef certificate;
+ CFArrayRef names;
+ CFStringRef name, ID;
+
+ certificate = crypto_cssm_x509cert_CreateSecCertificateRef(cert);
+ if (certificate == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "failed to get SecCertificateRef\n");
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID;
+ }
+ return ISAKMP_NTYPE_INVALID_CERTIFICATE;
+ }
+ names = SecCertificateCopyRFC822Names(certificate);
+ if (names == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "failed to get subjectName\n");
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
+ }
+ CFRelease(certificate);
+ return ISAKMP_NTYPE_INVALID_CERTIFICATE;
+ }
+ count = CFArrayGetCount(names);
+ ID = CFStringCreateWithBytes(kCFAllocatorDefault, id, idlen, kCFStringEncodingUTF8, FALSE);
+ if (ID == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "memory error\n");
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID;
+ }
+ CFRelease(names);
+ CFRelease(certificate);
+ return ISAKMP_NTYPE_INVALID_CERTIFICATE;
+ }
+ for (pos = 0; pos < count; pos++) {
+ name = CFArrayGetValueAtIndex(names, pos);
+ if (CFStringCompare(name, ID, 0) == kCFCompareEqualTo) {
+ CFRelease(ID);
+ CFRelease(names);
+ CFRelease(certificate);
+ return 0;
+ }
+ }
+ plog(ASL_LEVEL_ERR, "ID mismatched with subjectAltName.\n");
+ plog(ASL_LEVEL_ERR,
+ "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype));
+ plogdump(ASL_LEVEL_ERR, id, idlen, "ID:\n");
+ CFRelease(ID);
+ CFRelease(names);
+ CFRelease(certificate);
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
+ }
+ return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
+ }
+#else
case IPSECDOI_ID_FQDN:
case IPSECDOI_ID_USER_FQDN:
{
int pos;
for (pos = 1; ; pos++) {
- if (eay_get_x509subjectaltname(&iph1->cert_p->cert, &altname, &type, pos, &len) != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
+ if (eay_get_x509subjectaltname(cert, &altname, &type, pos, &len) != 0) {
+ plog(ASL_LEVEL_ERR,
"failed to get subjectAltName\n");
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
+ }
return ISAKMP_NTYPE_INVALID_CERTIFICATE;
}
/* it's the end condition of the loop. */
if (!altname) {
+ plog(ASL_LEVEL_ERR,
+ "invalid subjectAltName\n");
+ if (certStatus && !*certStatus) {
+ *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
+ }
return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
}
continue;
}
error = memcmp(id, altname, idlen);
+ if (error)
+ continue;
racoon_free(altname);
- if (error) {
- plog(LLV_ERROR, LOCATION, NULL, "ID mismatched.\n");
- return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
- }
return 0;
}
+ plog(ASL_LEVEL_ERR, "ID mismatched with subjectAltName.\n");
+ plog(ASL_LEVEL_ERR,
+ "subjectAltName (expected type %s, got type %s):\n",
+ s_ipsecdoi_ident(idtype),
+ s_ipsecdoi_ident(type));
+ plogdump(ASL_LEVEL_ERR, altname, len, "subjectAltName (expected type %s, got type %s):\n",
+ s_ipsecdoi_ident(idtype),
+ s_ipsecdoi_ident(type));
+ plogdump(ASL_LEVEL_ERR, id, idlen, "ID:\n");
+ racoon_free(altname);
+ if (certStatus && !*certStatus)
+ *certStatus = CERT_STATUS_INVALID_SUBJALTNAME;
+ return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
}
+#endif
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Impropper ID type passed: %s.\n",
s_ipsecdoi_ident(idtype));
return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
}
/*NOTREACHED*/
}
-
-#else /* __APPLE__ */
-
-/*
- * compare certificate name and ID value.
- */
-static int
-oakley_check_certid(iph1)
- struct ph1handle *iph1;
-{
- struct ipsecdoi_id_b *id_b;
- vchar_t *name = NULL;
- char *altname = NULL;
- int idlen, type;
- int error;
-
- if (iph1->id_p == NULL || iph1->cert_p == NULL) {
- plog(LLV_ERROR, LOCATION, NULL, "no ID nor CERT found.\n");
- return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
- }
-
- id_b = (struct ipsecdoi_id_b *)iph1->id_p->v;
- idlen = iph1->id_p->l - sizeof(*id_b);
-
- switch (id_b->type) {
- case IPSECDOI_ID_DER_ASN1_DN:
- name = eay_get_x509asn1subjectname(&iph1->cert_p->cert);
- if (!name) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get subjectName\n");
- return ISAKMP_NTYPE_INVALID_CERTIFICATE;
- }
- if (idlen != name->l) {
- plog(LLV_ERROR, LOCATION, NULL,
- "Invalid ID length in phase 1.\n");
- vfree(name);
- return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
- }
- error = memcmp(id_b + 1, name->v, idlen);
- vfree(name);
- if (error != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "ID mismatched with ASN1 SubjectName.\n");
- plogdump(LLV_DEBUG, id_b + 1, idlen);
- plogdump(LLV_DEBUG, name->v, idlen);
- return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
- }
- return 0;
- case IPSECDOI_ID_IPV4_ADDR:
- case IPSECDOI_ID_IPV6_ADDR:
- {
- /*
- * converting to binary from string because openssl return
- * a string even if object is a binary.
- * XXX fix it ! access by ASN.1 directly without.
- */
- struct addrinfo hints, *res;
- caddr_t a = NULL;
- int pos;
-
- for (pos = 1; ; pos++) {
- if (eay_get_x509subjectaltname(&iph1->cert_p->cert,
- &altname, &type, pos) !=0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get subjectAltName\n");
- return ISAKMP_NTYPE_INVALID_CERTIFICATE;
- }
-
- /* it's the end condition of the loop. */
- if (!altname) {
- plog(LLV_ERROR, LOCATION, NULL,
- "no proper subjectAltName.\n");
- return ISAKMP_NTYPE_INVALID_CERTIFICATE;
- }
-
- if (check_typeofcertname(id_b->type, type) == 0)
- break;
-
- /* next name */
- racoon_free(altname);
- altname = NULL;
- }
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = PF_UNSPEC;
- hints.ai_socktype = SOCK_RAW;
- hints.ai_flags = AI_NUMERICHOST;
- error = getaddrinfo(altname, NULL, &hints, &res);
- if (error != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "no proper subjectAltName.\n");
- racoon_free(altname);
- return ISAKMP_NTYPE_INVALID_CERTIFICATE;
- }
- switch (res->ai_family) {
- case AF_INET:
- a = (caddr_t)&((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr;
- break;
-#ifdef INET6
- case AF_INET6:
- a = (caddr_t)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr.s6_addr;
- break;
-#endif
- default:
- plog(LLV_ERROR, LOCATION, NULL,
- "family not supported: %d.\n", res->ai_family);
- racoon_free(altname);
- freeaddrinfo(res);
- return ISAKMP_NTYPE_INVALID_CERTIFICATE;
- }
- error = memcmp(id_b + 1, a, idlen);
- freeaddrinfo(res);
- vfree(name);
- if (error != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "ID mismatched with subjectAltName.\n");
- plogdump(LLV_DEBUG, id_b + 1, idlen);
- plogdump(LLV_DEBUG, a, idlen);
- return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
- }
- return 0;
- }
- case IPSECDOI_ID_FQDN:
- case IPSECDOI_ID_USER_FQDN:
- {
- int pos;
-
- for (pos = 1; ; pos++) {
- if (eay_get_x509subjectaltname(&iph1->cert_p->cert,
- &altname, &type, pos) != 0){
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get subjectAltName\n");
- return ISAKMP_NTYPE_INVALID_CERTIFICATE;
- }
-
- /* it's the end condition of the loop. */
- if (!altname) {
- plog(LLV_ERROR, LOCATION, NULL,
- "no proper subjectAltName.\n");
- return ISAKMP_NTYPE_INVALID_CERTIFICATE;
- }
-
- if (check_typeofcertname(id_b->type, type) == 0)
- break;
-
- /* next name */
- racoon_free(altname);
- altname = NULL;
- }
- if (idlen != strlen(altname)) {
- plog(LLV_ERROR, LOCATION, NULL,
- "Invalid ID length in phase 1.\n");
- racoon_free(altname);
- return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
- }
- if (check_typeofcertname(id_b->type, type) != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "ID type mismatched. ID: %s CERT: %s.\n",
- s_ipsecdoi_ident(id_b->type),
- s_ipsecdoi_ident(type));
- racoon_free(altname);
- return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
- }
- error = memcmp(id_b + 1, altname, idlen);
- if (error) {
- plog(LLV_ERROR, LOCATION, NULL, "ID mismatched.\n");
- plogdump(LLV_DEBUG, id_b + 1, idlen);
- plogdump(LLV_DEBUG, altname, idlen);
- racoon_free(altname);
- return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
- }
- racoon_free(altname);
- return 0;
- }
- default:
- plog(LLV_ERROR, LOCATION, NULL,
- "Impropper ID type passed: %s.\n",
- s_ipsecdoi_ident(id_b->type));
- return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
- }
- /*NOTREACHED*/
-}
-
-#endif /* __APPLE__ */
-
+#ifdef HAVE_OPENSSL
static int
-check_typeofcertname(doi, genid)
- int doi, genid;
+check_typeofcertname(int doi, int genid)
{
switch (doi) {
case IPSECDOI_ID_IPV4_ADDR:
}
/*NOTREACHED*/
}
+#endif
/*
* save certificate including certificate type.
*/
int
-oakley_savecert(iph1, gen)
- struct ph1handle *iph1;
- struct isakmp_gen *gen;
+oakley_savecert(phase1_handle_t *iph1, struct isakmp_gen *gen)
{
cert_t **c;
u_int8_t type;
- STACK_OF(X509) *certs=NULL;
- PKCS7 *p7;
-
type = *(u_int8_t *)(gen + 1) & 0xff;
switch (type) {
- case ISAKMP_CERT_DNS:
- plog(LLV_WARNING, LOCATION, NULL,
- "CERT payload is unnecessary in DNSSEC. "
- "ignore this CERT payload.\n");
- return 0;
- case ISAKMP_CERT_PKCS7:
- case ISAKMP_CERT_PGP:
case ISAKMP_CERT_X509SIGN:
- case ISAKMP_CERT_KERBEROS:
- case ISAKMP_CERT_SPKI:
c = &iph1->cert_p;
break;
- case ISAKMP_CERT_CRL:
- c = &iph1->crl_p;
- break;
- case ISAKMP_CERT_X509KE:
- case ISAKMP_CERT_X509ATTR:
- case ISAKMP_CERT_ARL:
- plog(LLV_ERROR, LOCATION, NULL,
- "No supported such CERT type %d\n", type);
- return -1;
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Invalid CERT type %d\n", type);
return -1;
}
- /* XXX choice the 1th cert, ignore after the cert. */
- /* XXX should be processed. */
if (*c) {
- plog(LLV_WARNING, LOCATION, NULL,
- "ignore 2nd CERT payload.\n");
- return 0;
+ plog(ASL_LEVEL_WARNING,
+ "preexisting CERT payload... chaining.\n");
}
- if (type == ISAKMP_CERT_PKCS7) {
- u_char *bp;
- int i;
-
- /* Skip the header */
- bp = (u_char *)(gen + 1);
- /* And the first byte is the certificate type,
- * we know that already
- */
- bp++;
- p7 = d2i_PKCS7(NULL, (void *)&bp,
- ntohs(gen->len) - sizeof(*gen) - 1);
-
- if (!p7) {
- plog(LLV_ERROR, LOCATION, NULL,
- "Failed to parse PKCS#7 CERT.\n");
- return -1;
- }
-
- /* Copied this from the openssl pkcs7 application;
- * there"s little by way of documentation for any of
- * it. I can only presume it"s correct.
- */
-
- i = OBJ_obj2nid(p7->type);
- switch (i) {
- case NID_pkcs7_signed:
- certs=p7->d.sign->cert;
- break;
- case NID_pkcs7_signedAndEnveloped:
- certs=p7->d.signed_and_enveloped->cert;
- break;
- default:
- break;
- }
-
- if (!certs) {
- plog(LLV_ERROR, LOCATION, NULL,
- "CERT PKCS#7 bundle contains no certs.\n");
- PKCS7_free(p7);
- return -1;
- }
-
- for (i = 0; i < sk_X509_num(certs); i++) {
- int len;
- u_char *bp;
- X509 *cert = sk_X509_value(certs,i);
-
- plog(LLV_DEBUG, LOCATION, NULL,
- "Trying PKCS#7 cert %d.\n", i);
-
- /* We'll just try each cert in turn */
- *c = save_certx509(cert);
-
- if (!*c) {
- plog(LLV_ERROR, LOCATION, NULL,
- "Failed to get CERT buffer.\n");
- continue;
- }
-
- /* Ignore cert if it doesn't match identity
- * XXX If verify cert is disabled, we still just take
- * the first certificate....
- */
- if(iph1->rmconf->verify_cert &&
- oakley_check_certid(iph1, CERT_CHECKID_FROM_PEER)) {
- plog(LLV_DEBUG, LOCATION, NULL,
- "Discarding CERT: does not match ID.\n");
- oakley_delcert((*c));
- *c = NULL;
- continue;
- }
-
- {
- char *p = eay_get_x509text(&(*c)->cert);
- plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
- plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
- plog(LLV_DEBUG, LOCATION, NULL, "%s",
- p ? p : "\n");
- racoon_free(p);
- }
- break;
- }
- PKCS7_free(p7);
-
- } else {
- *c = save_certbuf(gen);
- if (!*c) {
- plog(LLV_ERROR, LOCATION, NULL,
- "Failed to get CERT buffer.\n");
- return -1;
- }
-
- switch ((*c)->type) {
- case ISAKMP_CERT_DNS:
- plog(LLV_WARNING, LOCATION, NULL,
- "CERT payload is unnecessary in DNSSEC. "
- "ignore it.\n");
- return 0;
- case ISAKMP_CERT_PGP:
- case ISAKMP_CERT_X509SIGN:
- case ISAKMP_CERT_KERBEROS:
- case ISAKMP_CERT_SPKI:
- /* Ignore cert if it doesn't match identity
- * XXX If verify cert is disabled, we still just take
- * the first certificate....
- */
- if(iph1->rmconf->verify_cert &&
- oakley_check_certid(iph1, CERT_CHECKID_FROM_PEER)){
- plog(LLV_DEBUG, LOCATION, NULL,
- "Discarding CERT: does not match ID.\n");
- oakley_delcert((*c));
- *c = NULL;
- return 0;
- }
+ cert_t *new;
+ new = save_certbuf(gen);
+ if (!new) {
+ plog(ASL_LEVEL_ERR,
+ "Failed to get CERT buffer.\n");
+ return -1;
+ }
- {
- char *p = eay_get_x509text(&(*c)->cert);
- plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
- plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
- plog(LLV_DEBUG, LOCATION, NULL, "%s", p ? p : "\n");
- racoon_free(p);
- }
- break;
- case ISAKMP_CERT_CRL:
- plog(LLV_DEBUG, LOCATION, NULL, "CRL saved:\n");
- plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
- break;
- case ISAKMP_CERT_X509KE:
- case ISAKMP_CERT_X509ATTR:
- case ISAKMP_CERT_ARL:
- default:
- /* XXX */
- oakley_delcert((*c));
- *c = NULL;
- return 0;
- }
- }
+ switch (new->type) {
+ case ISAKMP_CERT_X509SIGN:
+ /* Ignore cert if it doesn't match identity
+ * XXX If verify cert is disabled, we still just take
+ * the first certificate....
+ */
+ *c = oakley_appendcert_to_certchain(*c, new);
+ plog(ASL_LEVEL_DEBUG, "CERT saved:\n");
+ break;
+ default:
+ /* XXX */
+ oakley_delcert(new);
+ return 0;
+ }
return 0;
}
* save certificate including certificate type.
*/
int
-oakley_savecr(iph1, gen)
- struct ph1handle *iph1;
- struct isakmp_gen *gen;
+oakley_savecr(phase1_handle_t *iph1, struct isakmp_gen *gen)
{
cert_t **c;
u_int8_t type;
+ cert_t *new;
type = *(u_int8_t *)(gen + 1) & 0xff;
switch (type) {
- case ISAKMP_CERT_DNS:
- plog(LLV_WARNING, LOCATION, NULL,
- "CERT payload is unnecessary in DNSSEC\n");
- /*FALLTHRU*/
- case ISAKMP_CERT_PKCS7:
- case ISAKMP_CERT_PGP:
case ISAKMP_CERT_X509SIGN:
- case ISAKMP_CERT_KERBEROS:
- case ISAKMP_CERT_SPKI:
+ if (iph1->cr_p) {
+ oakley_delcert(iph1->cr_p);
+ iph1->cr_p = NULL;
+ }
c = &iph1->cr_p;
break;
- case ISAKMP_CERT_X509KE:
- case ISAKMP_CERT_X509ATTR:
- case ISAKMP_CERT_ARL:
- plog(LLV_ERROR, LOCATION, NULL,
- "No supported such CR type %d\n", type);
- return -1;
- case ISAKMP_CERT_CRL:
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Invalid CR type %d\n", type);
return -1;
}
- *c = save_certbuf(gen);
- if (!*c) {
- plog(LLV_ERROR, LOCATION, NULL,
+ new = save_certbuf(gen);
+ if (!new) {
+ plog(ASL_LEVEL_ERR,
"Failed to get CR buffer.\n");
return -1;
}
-
- plog(LLV_DEBUG, LOCATION, NULL, "CR saved:\n");
- plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
+ *c = oakley_appendcert_to_certchain(*c, new);
+ plog(ASL_LEVEL_DEBUG, "CR saved\n");
return 0;
}
static cert_t *
-save_certbuf(gen)
- struct isakmp_gen *gen;
+save_certbuf(struct isakmp_gen *gen)
{
cert_t *new;
if(ntohs(gen->len) <= sizeof(*gen)){
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Len is too small !!.\n");
return NULL;
}
new = oakley_newcert();
if (!new) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Failed to get CERT buffer.\n");
return NULL;
}
new->pl = vmalloc(ntohs(gen->len) - sizeof(*gen));
if (new->pl == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Failed to copy CERT from packet.\n");
oakley_delcert(new);
new = NULL;
return new;
}
-static cert_t *
-save_certx509(cert)
- X509 *cert;
-{
- cert_t *new;
- int len;
- u_char *bp;
-
- new = oakley_newcert();
- if (!new) {
- plog(LLV_ERROR, LOCATION, NULL,
- "Failed to get CERT buffer.\n");
- return NULL;
- }
-
- len = i2d_X509(cert, NULL);
- new->pl = vmalloc(len);
- if (new->pl == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "Failed to copy CERT from packet.\n");
- oakley_delcert(new);
- new = NULL;
- return NULL;
- }
- bp = (u_char *) new->pl->v;
- len = i2d_X509(cert, &bp);
- new->type = ISAKMP_CERT_X509SIGN;
- new->cert.v = new->pl->v;
- new->cert.l = new->pl->l;
-
- return new;
-}
-
/*
* get my CR.
* NOTE: No Certificate Authority field is included to CR payload at the
* if there is no specific certificate authority requested.
*/
vchar_t *
-oakley_getcr(iph1)
- struct ph1handle *iph1;
+oakley_getcr(phase1_handle_t *iph1)
{
vchar_t *buf;
buf = vmalloc(1);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get cr buffer\n");
return NULL;
}
if(iph1->rmconf->certtype == ISAKMP_CERT_NONE) {
buf->v[0] = iph1->rmconf->cacerttype;
- plog(LLV_DEBUG, LOCATION, NULL, "create my CR: NONE, using %s instead\n",
+ plog(ASL_LEVEL_DEBUG, "create my CR: NONE, using %s instead\n",
s_isakmp_certtype(iph1->rmconf->cacerttype));
} else {
buf->v[0] = iph1->rmconf->certtype;
- plog(LLV_DEBUG, LOCATION, NULL, "create my CR: %s\n",
+ plog(ASL_LEVEL_DEBUG, "create my CR: %s\n",
s_isakmp_certtype(iph1->rmconf->certtype));
}
- if (buf->l > 1)
- plogdump(LLV_DEBUG, buf->v, buf->l);
+ //if (buf->l > 1)
+ // plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "");
return buf;
}
* check peer's CR.
*/
int
-oakley_checkcr(iph1)
- struct ph1handle *iph1;
+oakley_checkcr(phase1_handle_t *iph1)
{
if (iph1->cr_p == NULL)
return 0;
- plog(LLV_DEBUG, LOCATION, iph1->remote,
+ plog(ASL_LEVEL_DEBUG,
"peer transmitted CR: %s\n",
s_isakmp_certtype(iph1->cr_p->type));
if (iph1->cr_p->type != iph1->rmconf->certtype) {
- plog(LLV_ERROR, LOCATION, iph1->remote,
+ plog(ASL_LEVEL_ERR,
"such a cert type isn't supported: %d\n",
(char)iph1->cr_p->type);
return -1;
* check to need CR payload.
*/
int
-oakley_needcr(type)
- int type;
+oakley_needcr(int type)
{
switch (type) {
- case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
#ifdef ENABLE_HYBRID
case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
- case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
#endif
return 1;
default:
/*NOTREACHED*/
}
+vchar_t *
+oakley_getpskall(phase1_handle_t *iph1)
+{
+ vchar_t *secret = NULL;
+
+ if (iph1->rmconf->shared_secret) {
+
+ switch (iph1->rmconf->secrettype) {
+ case SECRETTYPE_KEY:
+ /* in psk file - use KEY from remote configuration to locate it */
+ secret = getpsk(iph1->rmconf->shared_secret->v, iph1->rmconf->shared_secret->l-1);
+ break;
+#if HAVE_KEYCHAIN
+ case SECRETTYPE_KEYCHAIN:
+ /* in the system keychain */
+ secret = getpskfromkeychain(iph1->rmconf->shared_secret->v, iph1->etype, iph1->rmconf->secrettype, NULL);
+ break;
+ case SECRETTYPE_KEYCHAIN_BY_ID:
+ /* in the system keychain - use peer id */
+ secret = getpskfromkeychain(iph1->rmconf->shared_secret->v, iph1->etype, iph1->rmconf->secrettype, iph1->id_p);
+ break;
+#endif // HAVE_KEYCHAIN
+ case SECRETTYPE_USE:
+ /* in the remote configuration */
+ default:
+ /* rmconf->shared_secret is a string and contains a NULL character that must be removed */
+ secret = vmalloc(iph1->rmconf->shared_secret->l - 1);
+ if (secret == NULL) {
+ plog(ASL_LEVEL_ERR, "memory error.\n");
+ goto end;
+ }
+ memcpy(secret->v, iph1->rmconf->shared_secret->v, secret->l);
+ }
+ } else if (iph1->etype != ISAKMP_ETYPE_IDENT) {
+ secret = getpskbyname(iph1->id_p);
+ if (!secret) {
+ if (iph1->rmconf->verify_identifier) {
+ plog(ASL_LEVEL_ERR, "couldn't find pskey by peer's ID.\n");
+ goto end;
+ }
+ }
+ }
+ if (!secret) {
+ plog(ASL_LEVEL_NOTICE, "try to get pskey by the peer's address.\n");
+ secret = getpskbyaddr(iph1->remote);
+ if (!secret) {
+ plog(ASL_LEVEL_ERR,
+ "couldn't find the pskey by address %s.\n",
+ saddrwop2str((struct sockaddr *)iph1->remote));
+ }
+ }
+
+end:
+ return secret;
+}
+
/*
* compute SKEYID
* see seciton 5. Exchanges in RFC 2409
* enc: SKEYID = prf(H(Ni_b | Nr_b), CKY-I | CKY-R)
*/
int
-oakley_skeyid(iph1)
- struct ph1handle *iph1;
+oakley_skeyid(phase1_handle_t *iph1)
{
- vchar_t *buf = NULL, *bp;
+ vchar_t *key = NULL;
+ vchar_t *buf = NULL;
+ vchar_t *bp;
char *p;
int len;
int error = -1;
-
+
/* SKEYID */
switch (AUTHMETHOD(iph1)) {
- case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
+ case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
#ifdef ENABLE_HYBRID
- case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
-#endif
-#ifdef __APPLE__
- if (iph1->rmconf->shared_secret) {
-
- switch (iph1->rmconf->secrettype) {
- case SECRETTYPE_KEY:
- /* in psk file - use KEY from remote configuration to locate it */
- iph1->authstr = getpsk(iph1->rmconf->shared_secret->v, iph1->rmconf->shared_secret->l-1);
- break;
-#if HAVE_KEYCHAIN
- case SECRETTYPE_KEYCHAIN:
- /* in the system keychain */
- iph1->authstr = getpskfromkeychain(iph1->rmconf->shared_secret->v, iph1->etype, iph1->rmconf->secrettype, NULL);
- break;
- case SECRETTYPE_KEYCHAIN_BY_ID:
- /* in the system keychain - use peer id */
- iph1->authstr = getpskfromkeychain(iph1->rmconf->shared_secret->v, iph1->etype, iph1->rmconf->secrettype, iph1->id_p);
- break;
-#endif HAVE_KEYCHAIN
- case SECRETTYPE_USE:
- /* in the remote configuration */
- default:
- iph1->authstr = vdup(iph1->rmconf->shared_secret);
- }
-
- }
- else
+ case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
+ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
#endif
- if (iph1->etype != ISAKMP_ETYPE_IDENT) {
- iph1->authstr = getpskbyname(iph1->id_p);
- if (iph1->authstr == NULL) {
- if (iph1->rmconf->verify_identifier) {
- plog(LLV_ERROR, LOCATION, iph1->remote,
- "couldn't find the pskey.\n");
- goto end;
- }
- plog(LLV_NOTIFY, LOCATION, iph1->remote,
- "couldn't find the proper pskey, "
- "try to get one by the peer's address.\n");
- }
- }
- if (iph1->authstr == NULL) {
- /*
- * If the exchange type is the main mode or if it's
- * failed to get the psk by ID, racoon try to get
- * the psk by remote IP address.
- * It may be nonsense.
- */
- iph1->authstr = getpskbyaddr(iph1->remote);
- if (iph1->authstr == NULL) {
- plog(LLV_ERROR, LOCATION, iph1->remote,
- "couldn't find the pskey for %s.\n",
- saddrwop2str(iph1->remote));
- goto end;
- }
- }
- plog(LLV_DEBUG, LOCATION, NULL, "the psk found.\n");
- /* should be secret PSK */
- plog(LLV_DEBUG2, LOCATION, NULL, "psk: ");
- plogdump(LLV_DEBUG2, iph1->authstr->v, iph1->authstr->l);
-
- len = iph1->nonce->l + iph1->nonce_p->l;
- buf = vmalloc(len);
- if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get skeyid buffer\n");
- goto end;
- }
- p = buf->v;
-
- bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p);
- plog(LLV_DEBUG, LOCATION, NULL, "nonce 1: ");
- plogdump(LLV_DEBUG, bp->v, bp->l);
- memcpy(p, bp->v, bp->l);
- p += bp->l;
-
- bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce);
- plog(LLV_DEBUG, LOCATION, NULL, "nonce 2: ");
- plogdump(LLV_DEBUG, bp->v, bp->l);
- memcpy(p, bp->v, bp->l);
- p += bp->l;
-
- iph1->skeyid = oakley_prf(iph1->authstr, buf, iph1);
- if (iph1->skeyid == NULL)
- goto end;
- break;
-
- case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
- case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
+ key = oakley_getpskall(iph1);
+ if (key == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "couldn't find the pskey for %s.\n",
+ saddrwop2str((struct sockaddr *)iph1->remote));
+ goto end;
+ }
+ plog(ASL_LEVEL_DEBUG, "the psk found.\n");
+ /* should be secret PSK */
+ plogdump(ASL_LEVEL_DEBUG, key->v, key->l, "psk: ");
+
+ len = iph1->nonce->l + iph1->nonce_p->l;
+ buf = vmalloc(len);
+ if (buf == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "failed to get skeyid buffer\n");
+ goto end;
+ }
+ p = buf->v;
+
+ bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p);
+ //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce 1: ");
+ memcpy(p, bp->v, bp->l);
+ p += bp->l;
+
+ bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce);
+ //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce 2: ");
+ memcpy(p, bp->v, bp->l);
+ p += bp->l;
+
+ iph1->skeyid = oakley_prf(key, buf, iph1);
+
+ if (iph1->skeyid == NULL)
+ goto end;
+ break;
+
+ case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
#ifdef ENABLE_HYBRID
- case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
- case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
- case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
- case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
+ case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+ case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
#endif
-#ifdef HAVE_GSSAPI
- case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
-#endif
- len = iph1->nonce->l + iph1->nonce_p->l;
- buf = vmalloc(len);
- if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get nonce buffer\n");
- goto end;
- }
- p = buf->v;
-
- bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p);
- plog(LLV_DEBUG, LOCATION, NULL, "nonce1: ");
- plogdump(LLV_DEBUG, bp->v, bp->l);
- memcpy(p, bp->v, bp->l);
- p += bp->l;
-
- bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce);
- plog(LLV_DEBUG, LOCATION, NULL, "nonce2: ");
- plogdump(LLV_DEBUG, bp->v, bp->l);
- memcpy(p, bp->v, bp->l);
- p += bp->l;
-
- iph1->skeyid = oakley_prf(buf, iph1->dhgxy, iph1);
- if (iph1->skeyid == NULL)
- goto end;
- break;
- case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
- case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
+ len = iph1->nonce->l + iph1->nonce_p->l;
+ buf = vmalloc(len);
+ if (buf == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "failed to get nonce buffer\n");
+ goto end;
+ }
+ p = buf->v;
+
+ bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p);
+ //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce1: ");
+ memcpy(p, bp->v, bp->l);
+ p += bp->l;
+
+ bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce);
+ //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce2: ");
+ memcpy(p, bp->v, bp->l);
+ p += bp->l;
+
+ iph1->skeyid = oakley_prf(buf, iph1->dhgxy, iph1);
+ if (iph1->skeyid == NULL)
+ goto end;
+ break;
+ case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
+ case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
#ifdef ENABLE_HYBRID
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
+ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
+ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
+ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
#endif
- plog(LLV_WARNING, LOCATION, NULL,
- "not supported authentication method %s\n",
- s_oakley_attr_method(iph1->approval->authmethod));
- goto end;
- default:
- plog(LLV_ERROR, LOCATION, NULL,
- "invalid authentication method %d\n",
- iph1->approval->authmethod);
- goto end;
- }
-
- plog(LLV_DEBUG, LOCATION, NULL, "SKEYID computed:\n");
- plogdump(LLV_DEBUG, iph1->skeyid->v, iph1->skeyid->l);
-
+ plog(ASL_LEVEL_WARNING,
+ "not supported authentication method %s\n",
+ s_oakley_attr_method(iph1->approval->authmethod));
+ goto end;
+ default:
+ plog(ASL_LEVEL_ERR,
+ "invalid authentication method %d\n",
+ iph1->approval->authmethod);
+ goto end;
+ }
+
+ //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid->v, iph1->skeyid->l, "IKEv1 SKEYID computed:\n");
+
error = 0;
-
+
end:
+ if (key != NULL)
+ vfree(key);
if (buf != NULL)
vfree(buf);
return error;
/*
* compute SKEYID_[dae]
- * see seciton 5. Exchanges in RFC 2409
- * SKEYID_d = prf(SKEYID, g^ir | CKY-I | CKY-R | 0)
- * SKEYID_a = prf(SKEYID, SKEYID_d | g^ir | CKY-I | CKY-R | 1)
- * SKEYID_e = prf(SKEYID, SKEYID_a | g^ir | CKY-I | CKY-R | 2)
*/
int
-oakley_skeyid_dae(iph1)
- struct ph1handle *iph1;
+oakley_skeyid_dae(phase1_handle_t *iph1)
{
vchar_t *buf = NULL;
char *p;
int error = -1;
if (iph1->skeyid == NULL) {
- plog(LLV_ERROR, LOCATION, NULL, "no SKEYID found.\n");
+ plog(ASL_LEVEL_ERR, "no SKEYID found.\n");
goto end;
}
-
+
+ /*
+ * see seciton 5. Exchanges in RFC 2409
+ * SKEYID_d = prf(SKEYID, g^ir | CKY-I | CKY-R | 0)
+ * SKEYID_a = prf(SKEYID, SKEYID_d | g^ir | CKY-I | CKY-R | 1)
+ * SKEYID_e = prf(SKEYID, SKEYID_a | g^ir | CKY-I | CKY-R | 2)
+ */
/* SKEYID D */
/* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
len = iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get skeyid buffer\n");
goto end;
}
vfree(buf);
buf = NULL;
- plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_d computed:\n");
- plogdump(LLV_DEBUG, iph1->skeyid_d->v, iph1->skeyid_d->l);
+ //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid_d->v, iph1->skeyid_d->l, "SKEYID_d computed:\n");
/* SKEYID A */
/* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
len = iph1->skeyid_d->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get skeyid buffer\n");
goto end;
}
vfree(buf);
buf = NULL;
- plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_a computed:\n");
- plogdump(LLV_DEBUG, iph1->skeyid_a->v, iph1->skeyid_a->l);
+ //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid_a->v, iph1->skeyid_a->l, "SKEYID_a computed:\n");
/* SKEYID E */
/* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
len = iph1->skeyid_a->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get skeyid buffer\n");
goto end;
}
vfree(buf);
buf = NULL;
- plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_e computed:\n");
- plogdump(LLV_DEBUG, iph1->skeyid_e->v, iph1->skeyid_e->l);
+ //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid_e->v, iph1->skeyid_e->l, "SKEYID_e computed:\n");
error = 0;
* see Appendix B.
*/
int
-oakley_compute_enckey(iph1)
- struct ph1handle *iph1;
+oakley_compute_enckey(phase1_handle_t *iph1)
{
u_int keylen, prflen;
int error = -1;
keylen = alg_oakley_encdef_keylen(iph1->approval->enctype,
iph1->approval->encklen);
if (keylen == -1) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"invalid encryption algoritym %d, "
"or invalid key length %d.\n",
iph1->approval->enctype,
}
iph1->key = vmalloc(keylen >> 3);
if (iph1->key == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get key buffer\n");
goto end;
}
/* set prf length */
prflen = alg_oakley_hashdef_hashlen(iph1->approval->hashtype);
if (prflen == -1) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"invalid hash type %d.\n", iph1->approval->hashtype);
goto end;
}
* K2 = prf(SKEYID_e, K1)
* K3 = prf(SKEYID_e, K2)
*/
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"len(SKEYID_e) < len(Ka) (%zu < %zu), "
"generating long key (Ka = K1 | K2 | ...)\n",
iph1->skeyid_e->l, iph1->key->l);
if ((buf = vmalloc(prflen >> 3)) == 0) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get key buffer\n");
goto end;
}
vfree(buf);
goto end;
}
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"compute intermediate encryption key K%d\n",
subkey);
- plogdump(LLV_DEBUG, buf->v, buf->l);
- plogdump(LLV_DEBUG, res->v, res->l);
+ //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "");
+ //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "");
cplen = (res->l < ep - p) ? res->l : ep - p;
memcpy(p, res->v, cplen);
buf->l = prflen >> 3; /* to cancel K1 speciality */
if (res->l != buf->l) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"internal error: res->l=%zu buf->l=%zu\n",
res->l, buf->l);
vfree(res);
* draft-ietf-ipsec-ike-01.txt Appendix B.
* draft-ietf-ipsec-ciph-aes-cbc-00.txt Section 2.3.
*/
-#if 0
- /* weakkey check */
- if (iph1->approval->enctype > ARRAYLEN(oakley_encdef)
- || oakley_encdef[iph1->approval->enctype].weakkey == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "encryption algoritym %d isn't supported.\n",
- iph1->approval->enctype);
- goto end;
- }
- if ((oakley_encdef[iph1->approval->enctype].weakkey)(iph1->key)) {
- plog(LLV_ERROR, LOCATION, NULL,
- "weakkey was generated.\n");
- goto end;
- }
-#endif
- plog(LLV_DEBUG, LOCATION, NULL, "final encryption key computed:\n");
- plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
+ //plogdump(ASL_LEVEL_DEBUG, iph1->key->v, iph1->key->l, "final encryption key computed:\n");
error = 0;
/* allocated new buffer for CERT */
cert_t *
-oakley_newcert()
+oakley_newcert(void)
{
cert_t *new;
new = racoon_calloc(1, sizeof(*new));
if (new == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get cert's buffer\n");
return NULL;
}
new->pl = NULL;
+ new->chain = NULL;
return new;
}
/* delete buffer for CERT */
void
-oakley_delcert(cert)
- cert_t *cert;
+oakley_delcert_1(cert_t *cert)
{
if (!cert)
return;
racoon_free(cert);
}
+/* delete buffer for CERT */
+void
+oakley_delcert(cert_t *cert)
+{
+ cert_t *p, *to_delete;
+
+ if (!cert)
+ return;
+
+ for (p = cert; p;) {
+ to_delete = p;
+ p = p->chain;
+ oakley_delcert_1(to_delete);
+ }
+}
+
+/* delete buffer for CERT */
+static cert_t *
+oakley_appendcert_to_certchain(cert_t *certchain, cert_t *new)
+{
+ cert_t *p;
+
+ if (!certchain)
+ return new;
+
+ for (p = certchain; p; p = p->chain) {
+ if (!p->chain) {
+ p->chain = new;
+ return certchain;
+ }
+ }
+ return NULL;
+}
+
/*
* compute IV and set to ph1handle
* IV = hash(g^xi | g^xr)
* see 4.1 Phase 1 state in draft-ietf-ipsec-ike.
*/
int
-oakley_newiv(iph1)
- struct ph1handle *iph1;
+oakley_newiv(phase1_handle_t *iph1)
{
struct isakmp_ivm *newivm = NULL;
vchar_t *buf = NULL, *bp;
len = iph1->dhpub->l + iph1->dhpub_p->l;
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get iv buffer\n");
+ plog(ASL_LEVEL_ERR,
+ "Failed to get IV buffer\n");
return -1;
}
/* allocate IVm */
newivm = racoon_calloc(1, sizeof(struct isakmp_ivm));
if (newivm == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get iv buffer\n");
+ plog(ASL_LEVEL_ERR,
+ "Failed to get IV buffer\n");
vfree(buf);
return -1;
}
/* adjust length of iv */
newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype);
if (newivm->iv->l == -1) {
- plog(LLV_ERROR, LOCATION, NULL,
- "invalid encryption algoriym %d.\n",
+ plog(ASL_LEVEL_ERR,
+ "Invalid encryption algorithm %d.\n",
iph1->approval->enctype);
vfree(buf);
oakley_delivm(newivm);
/* create buffer to save iv */
if ((newivm->ive = vdup(newivm->iv)) == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"vdup (%s)\n", strerror(errno));
vfree(buf);
oakley_delivm(newivm);
vfree(buf);
- plog(LLV_DEBUG, LOCATION, NULL, "IV computed:\n");
- plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l);
+ //plogdump(ASL_LEVEL_DEBUG, newivm->iv->v, newivm->iv->l, "IV computed:\n");
if (iph1->ivm != NULL)
oakley_delivm(iph1->ivm);
* see 4.2 Phase 2 state in draft-ietf-ipsec-ike.
*/
struct isakmp_ivm *
-oakley_newiv2(iph1, msgid)
- struct ph1handle *iph1;
- u_int32_t msgid;
+oakley_newiv2(phase1_handle_t *iph1, u_int32_t msgid)
{
struct isakmp_ivm *newivm = NULL;
vchar_t *buf = NULL;
len = iph1->ivm->iv->l + sizeof(msgid_t);
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get iv buffer\n");
+ plog(ASL_LEVEL_ERR,
+ "Failed to get IV buffer\n");
goto end;
}
memcpy(p, &msgid, sizeof(msgid));
- plog(LLV_DEBUG, LOCATION, NULL, "compute IV for phase2\n");
- plog(LLV_DEBUG, LOCATION, NULL, "phase1 last IV:\n");
- plogdump(LLV_DEBUG, buf->v, buf->l);
+ plog(ASL_LEVEL_DEBUG, "Compute IV for Phase 2\n");
+ //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "Phase 1 last IV:\n");
/* allocate IVm */
newivm = racoon_calloc(1, sizeof(struct isakmp_ivm));
if (newivm == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get iv buffer\n");
+ plog(ASL_LEVEL_ERR,
+ "Failed to get IV buffer\n");
goto end;
}
/* adjust length of iv */
newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype);
if (newivm->iv->l == -1) {
- plog(LLV_ERROR, LOCATION, NULL,
- "invalid encryption algoriym %d.\n",
+ plog(ASL_LEVEL_ERR,
+ "Invalid encryption algorithm %d.\n",
iph1->approval->enctype);
goto end;
}
/* create buffer to save new iv */
if ((newivm->ive = vdup(newivm->iv)) == NULL) {
- plog(LLV_ERROR, LOCATION, NULL, "vdup (%s)\n", strerror(errno));
+ plog(ASL_LEVEL_ERR, "vdup (%s)\n", strerror(errno));
goto end;
}
error = 0;
- plog(LLV_DEBUG, LOCATION, NULL, "phase2 IV computed:\n");
- plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l);
+ //plogdump(ASL_LEVEL_DEBUG, newivm->iv->v, newivm->iv->l, "Phase 2 IV computed:\n");
end:
if (error && newivm != NULL){
}
void
-oakley_delivm(ivm)
- struct isakmp_ivm *ivm;
+oakley_delivm(struct isakmp_ivm *ivm)
{
if (ivm == NULL)
return;
if (ivm->ive != NULL)
vfree(ivm->ive);
racoon_free(ivm);
- plog(LLV_DEBUG, LOCATION, NULL, "IV freed\n");
+ plog(ASL_LEVEL_DEBUG, "IV freed\n");
return;
}
* save new iv and old iv.
*/
vchar_t *
-oakley_do_decrypt(iph1, msg, ivdp, ivep)
- struct ph1handle *iph1;
- vchar_t *msg, *ivdp, *ivep;
+oakley_do_ikev1_decrypt(phase1_handle_t *iph1, vchar_t *msg, vchar_t *ivdp, vchar_t *ivep)
{
vchar_t *buf = NULL, *new = NULL;
char *pl;
int blen;
int error = -1;
- plog(LLV_DEBUG, LOCATION, NULL, "begin decryption.\n");
+ plog(ASL_LEVEL_DEBUG, "Begin decryption.\n");
blen = alg_oakley_encdef_blocklen(iph1->approval->enctype);
if (blen == -1) {
- plog(LLV_ERROR, LOCATION, NULL,
- "invalid encryption algoriym %d.\n",
+ plog(ASL_LEVEL_ERR,
+ "Invalid encryption algorithm %d.\n",
iph1->approval->enctype);
goto end;
}
memset(ivep->v, 0, ivep->l);
memcpy(ivep->v, (caddr_t)&msg->v[msg->l - blen], blen);
- plog(LLV_DEBUG, LOCATION, NULL,
- "IV was saved for next processing:\n");
- plogdump(LLV_DEBUG, ivep->v, ivep->l);
+ plogdump(ASL_LEVEL_DEBUG, ivep->v, ivep->l, "IV was saved for next processing:\n");
pl = msg->v + sizeof(struct isakmp);
/* create buffer */
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get buffer to decrypt.\n");
+ plog(ASL_LEVEL_ERR,
+ "Failed to get buffer to decrypt.\n");
goto end;
}
memcpy(buf->v, pl, len);
new = alg_oakley_encdef_decrypt(iph1->approval->enctype,
buf, iph1->key, ivdp);
if (new == NULL || new->v == NULL || new->l == 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "decryption %d failed.\n", iph1->approval->enctype);
+ plog(ASL_LEVEL_ERR,
+ "Decryption %d failed.\n", iph1->approval->enctype);
goto end;
}
- plog(LLV_DEBUG, LOCATION, NULL, "with key:\n");
- plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
+ //plogdump(ASL_LEVEL_DEBUG, iph1->key->v, iph1->key->l, "with key:\n");
vfree(buf);
buf = NULL;
if (new == NULL)
goto end;
- plog(LLV_DEBUG, LOCATION, NULL, "decrypted payload by IV:\n");
- plogdump(LLV_DEBUG, ivdp->v, ivdp->l);
-
- plog(LLV_DEBUG, LOCATION, NULL,
- "decrypted payload, but not trimed.\n");
- plogdump(LLV_DEBUG, new->v, new->l);
+ plog(ASL_LEVEL_DEBUG, "decrypted payload by IV:\n");
/* get padding length */
if (lcconf->pad_excltail)
padlen = new->v[new->l - 1] + 1;
else
padlen = new->v[new->l - 1];
- plog(LLV_DEBUG, LOCATION, NULL, "padding len=%u\n", padlen);
+ plog(ASL_LEVEL_DEBUG, "padding len=%u\n", padlen);
/* trim padding */
if (lcconf->pad_strict) {
if (padlen > new->l) {
- plog(LLV_ERROR, LOCATION, NULL,
- "invalid padding len=%u, buflen=%zu.\n",
- padlen, new->l);
- plogdump(LLV_ERROR, new->v, new->l);
+ plog(ASL_LEVEL_ERR, "invalid padding len=%u, buflen=%zu.\n",
+ padlen, new->l);
goto end;
}
new->l -= padlen;
- plog(LLV_DEBUG, LOCATION, NULL, "trimmed padding\n");
+ plog(ASL_LEVEL_DEBUG, "trimmed padding\n");
} else {
- plog(LLV_DEBUG, LOCATION, NULL, "skip to trim padding.\n");
+ plog(ASL_LEVEL_DEBUG, "skip to trim padding.\n");
}
/* create new buffer */
len = sizeof(struct isakmp) + new->l;
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to get buffer to decrypt.\n");
goto end;
}
memcpy(buf->v + sizeof(struct isakmp), new->v, new->l);
((struct isakmp *)buf->v)->len = htonl(buf->l);
- plog(LLV_DEBUG, LOCATION, NULL, "decrypted.\n");
- plogdump(LLV_DEBUG, buf->v, buf->l);
+ plog(ASL_LEVEL_DEBUG, "decrypted.\n");
#ifdef HAVE_PRINT_ISAKMP_C
isakmp_printpacket(buf, iph1->remote, iph1->local, 1);
return buf;
}
+/*
+ * decrypt packet.
+ */
+vchar_t *
+oakley_do_decrypt(phase1_handle_t *iph1, vchar_t *msg, vchar_t *ivdp, vchar_t *ivep)
+{
+ if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) {
+ return(oakley_do_ikev1_decrypt(iph1, msg, ivdp, ivep));
+ }
+
+ plog(ASL_LEVEL_ERR, "Failed to decrypt invalid IKE version");
+ return NULL;
+}
+
/*
* encrypt packet.
*/
vchar_t *
-oakley_do_encrypt(iph1, msg, ivep, ivp)
- struct ph1handle *iph1;
- vchar_t *msg, *ivep, *ivp;
+oakley_do_ikev1_encrypt(phase1_handle_t *iph1, vchar_t *msg, vchar_t *ivep, vchar_t *ivp)
{
vchar_t *buf = 0, *new = 0;
char *pl;
int blen;
int error = -1;
- plog(LLV_DEBUG, LOCATION, NULL, "begin encryption.\n");
+ plog(ASL_LEVEL_DEBUG, "Begin encryption.\n");
/* set cbc block length */
blen = alg_oakley_encdef_blocklen(iph1->approval->enctype);
if (blen == -1) {
- plog(LLV_ERROR, LOCATION, NULL,
- "invalid encryption algoriym %d.\n",
+ plog(ASL_LEVEL_ERR,
+ "Invalid encryption algorithm %d.\n",
iph1->approval->enctype);
goto end;
}
/* add padding */
padlen = oakley_padlen(len, blen);
- plog(LLV_DEBUG, LOCATION, NULL, "pad length = %u\n", padlen);
+ plog(ASL_LEVEL_DEBUG, "pad length = %u\n", padlen);
/* create buffer */
buf = vmalloc(len + padlen);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get buffer to encrypt.\n");
+ plog(ASL_LEVEL_ERR,
+ "Failed to get buffer to encrypt.\n");
goto end;
}
if (padlen) {
else
buf->v[len + padlen - 1] = padlen;
- plogdump(LLV_DEBUG, buf->v, buf->l);
+ plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "About to encrypt %d bytes", buf->l);
/* do encrypt */
new = alg_oakley_encdef_encrypt(iph1->approval->enctype,
buf, iph1->key, ivep);
if (new == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "encryption %d failed.\n", iph1->approval->enctype);
+ plog(ASL_LEVEL_ERR,
+ "Encryption %d failed.\n", iph1->approval->enctype);
goto end;
}
- plog(LLV_DEBUG, LOCATION, NULL, "with key:\n");
- plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
+ //plogdump(ASL_LEVEL_DEBUG, iph1->key->v, iph1->key->l, "with key:\n");
vfree(buf);
buf = NULL;
if (new == NULL)
goto end;
- plog(LLV_DEBUG, LOCATION, NULL, "encrypted payload by IV:\n");
- plogdump(LLV_DEBUG, ivep->v, ivep->l);
+ //plogdump(ASL_LEVEL_DEBUG, ivep->v, ivep->l, "encrypted payload by IV:\n");
/* save IV for next */
memset(ivp->v, 0, ivp->l);
memcpy(ivp->v, (caddr_t)&new->v[new->l - blen], blen);
- plog(LLV_DEBUG, LOCATION, NULL, "save IV for next:\n");
- plogdump(LLV_DEBUG, ivp->v, ivp->l);
+ //plogdump(ASL_LEVEL_DEBUG, ivp->v, ivp->l, "save IV for next:\n");
/* create new buffer */
len = sizeof(struct isakmp) + new->l;
buf = vmalloc(len);
if (buf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get buffer to encrypt.\n");
+ plog(ASL_LEVEL_ERR,
+ "Failed to get buffer to encrypt.\n");
goto end;
}
memcpy(buf->v, msg->v, sizeof(struct isakmp));
error = 0;
- plog(LLV_DEBUG, LOCATION, NULL, "encrypted.\n");
+ plog(ASL_LEVEL_DEBUG, "Encrypted.\n");
end:
if (error && buf != NULL) {
return buf;
}
+/*
+ * encrypt packet.
+ */
+vchar_t *
+oakley_do_encrypt(phase1_handle_t *iph1, vchar_t *msg, vchar_t *ivep, vchar_t *ivp)
+{
+ if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) {
+ return(oakley_do_ikev1_encrypt(iph1, msg, ivep, ivp));
+ }
+
+ plog(ASL_LEVEL_ERR, "Failed to encrypt invalid IKE version");
+ return NULL;
+}
+
/* culculate padding length */
static int
-oakley_padlen(len, base)
- int len, base;
+oakley_padlen(int len, int base)
{
int padlen;
- padlen = base - len % base;
+ padlen = base - (len % base);
if (lcconf->pad_randomlen)
padlen += ((eay_random() % (lcconf->pad_maxsize + 1) + 1) *
return padlen;
}
-#ifdef __APPLE__
/* -----------------------------------------------------------------------------
The base-64 encoding packs three 8-bit bytes into four 7-bit ASCII
characters. If the number of bytes in the original data isn't divisable
int numeq = 0;
int acc = 0;
int cntr = 0;
- uint8_t *textcur = textin->v;
+ uint8_t *textcur = (__typeof__(textcur))textin->v;
int len = textin->l;
int i;
return -1;
}
-#endif
+