Exemplo n.º 1
0
int
ca_setauth(struct iked *env, struct iked_sa *sa,
    struct ibuf *authmsg, enum privsep_procid id)
{
	struct iovec		 iov[3];
	int			 iovcnt = 3;
	struct iked_policy	*policy = sa->sa_policy;
	u_int8_t		 type = policy->pol_auth.auth_method;

	if (type == IKEV2_AUTH_SHARED_KEY_MIC) {
		sa->sa_stateflags |= IKED_REQ_AUTH;
		return (ikev2_msg_authsign(env, sa,
		    &policy->pol_auth, authmsg));
	}

	iov[0].iov_base = &sa->sa_hdr;
	iov[0].iov_len = sizeof(sa->sa_hdr);
	iov[1].iov_base = &type;
	iov[1].iov_len = sizeof(type);
	if (type == IKEV2_AUTH_NONE)
		iovcnt--;
	else {
		iov[2].iov_base = ibuf_data(authmsg);
		iov[2].iov_len = ibuf_size(authmsg);
		log_debug("%s: auth length %d", __func__, ibuf_size(authmsg));
	}

	if (proc_composev_imsg(env, id, IMSG_AUTH, -1, iov, iovcnt) == -1)
		return (-1);
	return (0);
}
Exemplo n.º 2
0
void
ikev2_msg_cb(int fd, short event, void *arg)
{
	struct iked_socket	*sock = arg;
	struct iked		*env = sock->sock_env;
	struct iked_message	 msg;
	struct ike_header	 hdr;
	u_int32_t		 natt = 0x00000000;
	u_int8_t		 buf[IKED_MSGBUF_MAX];
	ssize_t			 len;
	off_t			 off;
	struct iovec		 iov[2];

	bzero(&msg, sizeof(msg));
	bzero(buf, sizeof(buf));

	msg.msg_peerlen = sizeof(msg.msg_peer);
	msg.msg_locallen = sizeof(msg.msg_local);
	msg.msg_parent = &msg;
	memcpy(&msg.msg_local, &sock->sock_addr, sizeof(sock->sock_addr));

	if ((len = recvfromto(fd, buf, sizeof(buf), 0,
	    (struct sockaddr *)&msg.msg_peer, &msg.msg_peerlen,
	    (struct sockaddr *)&msg.msg_local, &msg.msg_locallen)) <
	    (ssize_t)sizeof(natt))
		return;

	if (socket_getport(&msg.msg_local) == IKED_NATT_PORT) {
		if (bcmp(&natt, buf, sizeof(natt)) != 0)
			return;
		msg.msg_natt = 1;
		off = sizeof(natt);
	} else
		off = 0;

	if ((size_t)(len - off) <= sizeof(hdr))
		return;
	memcpy(&hdr, buf + off, sizeof(hdr));

	if ((msg.msg_data = ibuf_new(buf + off, len - off)) == NULL)
		return;

	if (hdr.ike_version == IKEV1_VERSION) {
		iov[0].iov_base = &msg;
		iov[0].iov_len = sizeof(msg);
		iov[1].iov_base = buf;
		iov[1].iov_len = len;

		proc_composev_imsg(env, PROC_IKEV1, IMSG_IKE_MESSAGE, -1,
		    iov, 2);
		goto done;
	}
	TAILQ_INIT(&msg.msg_proposals);

	msg.msg_fd = fd;
	ikev2_recv(env, &msg);

 done:
	ikev2_msg_cleanup(env, &msg);
}
Exemplo n.º 3
0
int
ca_getcert(struct iked *env, struct imsg *imsg)
{
	struct iked_sahdr	 sh;
	u_int8_t		 type;
	u_int8_t		*ptr;
	size_t			 len;
	struct iked_static_id	 id;
	u_int			 i;
	struct iovec		 iov[2];
	int			 iovcnt = 2, cmd, ret = 0;

	ptr = (u_int8_t *)imsg->data;
	len = IMSG_DATA_SIZE(imsg);
	i = sizeof(id) + sizeof(sh) + sizeof(type);
	if (len <= i)
		return (-1);

	memcpy(&id, ptr, sizeof(id));
	if (id.id_type == IKEV2_ID_NONE)
		return (-1);
	memcpy(&sh, ptr + sizeof(id), sizeof(sh));
	memcpy(&type, ptr + sizeof(id) + sizeof(sh), sizeof(u_int8_t));

	ptr += i;
	len -= i;

	switch (type) {
	case IKEV2_CERT_X509_CERT:
		ret = ca_validate_cert(env, &id, ptr, len);
		if (ret == 0 && env->sc_ocsp_url) {
			ret = ocsp_validate_cert(env, &id, ptr, len, sh, type);
			if (ret == 0)
				return (0);
		}
		break;
	case IKEV2_CERT_RSA_KEY:
		ret = ca_validate_pubkey(env, &id, ptr, len);
		break;
	default:
		log_debug("%s: unsupported cert type %d", __func__, type);
		ret = -1;
		break;
	}

	if (ret == 0)
		cmd = IMSG_CERTVALID;
	else
		cmd = IMSG_CERTINVALID;

	iov[0].iov_base = &sh;
	iov[0].iov_len = sizeof(sh);
	iov[1].iov_base = &type;
	iov[1].iov_len = sizeof(type);

	if (proc_composev_imsg(&env->sc_ps, PROC_IKEV2, -1,
	    cmd, -1, iov, iovcnt) == -1)
		return (-1);
	return (0);
}
Exemplo n.º 4
0
int
ca_setreq(struct iked *env, struct iked_sahdr *sh,
    struct iked_static_id *localid, u_int8_t type, u_int8_t *data,
    size_t len, enum privsep_procid procid)
{
	struct iovec		iov[4];
	int			iovcnt = 0;
	struct iked_static_id	idb;
	struct iked_id		id;
	int			ret = -1;

	/* Convert to a static Id */
	bzero(&id, sizeof(id));
	if (ikev2_policy2id(localid, &id, 1) != 0)
		return (-1);

	bzero(&idb, sizeof(idb));
	idb.id_type = id.id_type;
	idb.id_offset = id.id_offset;
	idb.id_length = ibuf_length(id.id_buf);
	memcpy(&idb.id_data, ibuf_data(id.id_buf),
	    ibuf_length(id.id_buf));
	iov[iovcnt].iov_base = &idb;
	iov[iovcnt].iov_len = sizeof(idb);
	iovcnt++;

	iov[iovcnt].iov_base = sh;
	iov[iovcnt].iov_len = sizeof(*sh);
	iovcnt++;
	iov[iovcnt].iov_base = &type;
	iov[iovcnt].iov_len = sizeof(type);
	iovcnt++;
	iov[iovcnt].iov_base = data;
	iov[iovcnt].iov_len = len;
	iovcnt++;

	if (proc_composev_imsg(env, procid,
	    IMSG_CERTREQ, -1, iov, iovcnt) == -1)
		goto done;

	ret = 0;
 done:
	ibuf_release(id.id_buf);
	return (ret);
}
Exemplo n.º 5
0
/*
 * finish the ocsp_validate_cert() RPC by sending the appropriate
 * message back to the IKEv2 process
 */
int
ocsp_validate_finish(struct iked_ocsp *ocsp, int valid)
{
	struct iked		*env = ocsp->ocsp_env;
	struct iovec		 iov[2];
	int			 iovcnt = 2, ret, cmd;

	iov[0].iov_base = &ocsp->ocsp_sh;
	iov[0].iov_len = sizeof(ocsp->ocsp_sh);
	iov[1].iov_base = &ocsp->ocsp_type;
	iov[1].iov_len = sizeof(ocsp->ocsp_type);

	cmd = valid ? IMSG_CERTVALID : IMSG_CERTINVALID;
	ret = proc_composev_imsg(&env->sc_ps, PROC_IKEV2, -1,
	    cmd, -1, iov, iovcnt);

	ocsp_free(ocsp);
	return (ret);
}
Exemplo n.º 6
0
void
ikev1_msg_cb(int fd, short event, void *arg)
{
	struct iked_socket	*sock = arg;
	struct iked		*env = sock->sock_env;
	struct iked_message	 msg;
	struct ike_header	 hdr;
	uint8_t			 buf[IKED_MSGBUF_MAX];
	size_t			 len;
	struct iovec		 iov[2];

	msg.msg_peerlen = sizeof(msg.msg_peer);
	msg.msg_locallen = sizeof(msg.msg_local);

	if ((len = recvfromto(fd, buf, sizeof(buf), 0,
	    (struct sockaddr*)&msg.msg_peer, &msg.msg_peerlen,
	    (struct sockaddr*)&msg.msg_local, &msg.msg_locallen)) < 1)
		return;

	if ((size_t)len <= sizeof(hdr))
		return;
	memcpy(&hdr, buf, sizeof(hdr));

	if ((msg.msg_data = ibuf_new(buf, len)) == NULL)
		return;

	if (hdr.ike_version == IKEV2_VERSION) {
		iov[0].iov_base = &msg;
		iov[0].iov_len = sizeof(msg);
		iov[1].iov_base = buf;
		iov[1].iov_len = len;

		proc_composev_imsg(&env->sc_ps, PROC_IKEV2, -1,
		    IMSG_IKE_MESSAGE, -1, iov, 2);
		goto done;
	}

	ikev1_recv(env, &msg);

 done:
	ikev2_msg_cleanup(env, &msg);
}
Exemplo n.º 7
0
int
ca_setcert(struct iked *env, struct iked_sahdr *sh, struct iked_id *id,
    u_int8_t type, u_int8_t *data, size_t len, enum privsep_procid procid)
{
	struct iovec		iov[4];
	int			iovcnt = 0;
	struct iked_static_id	idb;

	/* Must send the cert and a valid Id to the ca process */
	if (procid == PROC_CERT) {
		if (id == NULL || id->id_type == IKEV2_ID_NONE ||
		    ibuf_length(id->id_buf) > IKED_ID_SIZE)
			return (-1);
		bzero(&idb, sizeof(idb));

		/* Convert to a static Id */
		idb.id_type = id->id_type;
		idb.id_offset = id->id_offset;
		idb.id_length = ibuf_length(id->id_buf);
		memcpy(&idb.id_data, ibuf_data(id->id_buf),
		    ibuf_length(id->id_buf));

		iov[iovcnt].iov_base = &idb;
		iov[iovcnt].iov_len = sizeof(idb);
		iovcnt++;
	}

	iov[iovcnt].iov_base = sh;
	iov[iovcnt].iov_len = sizeof(*sh);
	iovcnt++;
	iov[iovcnt].iov_base = &type;
	iov[iovcnt].iov_len = sizeof(type);
	iovcnt++;
	iov[iovcnt].iov_base = data;
	iov[iovcnt].iov_len = len;
	iovcnt++;

	if (proc_composev_imsg(&env->sc_ps, procid, -1,
	    IMSG_CERT, -1, iov, iovcnt) == -1)
		return (-1);
	return (0);
}
Exemplo n.º 8
0
/* send FD+path or error back to CA process */
int
ocsp_connect_finish(struct iked *env, int fd, struct ocsp_connect *oc)
{
	struct iovec		 iov[1];
	int			 iovcnt = 1, ret;

	if (oc && fd >= 0) {
		/* the imsg framework will close the FD after send */
		iov[0].iov_base = oc->oc_path;
		iov[0].iov_len = strlen(oc->oc_path);
		ret = proc_composev_imsg(&env->sc_ps, PROC_CERT, -1,
		    IMSG_OCSP_FD, fd, iov, iovcnt);
	} else {
		ret = proc_compose_imsg(&env->sc_ps, PROC_CERT, -1,
		    IMSG_OCSP_FD, -1, NULL, 0);
		if (fd >= 0)
			close(fd);
	}
	if (oc) {
		free(oc->oc_path);
		free(oc);
	}
	return (ret);
}
Exemplo n.º 9
0
int
ca_reload(struct iked *env)
{
	struct ca_store	*store = env->sc_priv;
	DIR			*dir;
	struct dirent		*entry;
	char			 file[PATH_MAX];
	STACK_OF(X509_OBJECT)	*h;
	X509_OBJECT		*xo;
	X509			*x509;
	int			 i, len;
	u_int8_t		 md[EVP_MAX_MD_SIZE];
	struct iovec		 iov[2];
	int			 iovcnt = 2;

	/*
	 * Load CAs
	 */
	if ((dir = opendir(IKED_CA_DIR)) == NULL)
		return (-1);

	while ((entry = readdir(dir)) != NULL) {
		if ((entry->d_type != DT_REG) &&
		    (entry->d_type != DT_LNK))
			continue;

		if (snprintf(file, sizeof(file), "%s%s",
		    IKED_CA_DIR, entry->d_name) == -1)
			continue;

		if (!X509_load_cert_file(store->ca_calookup, file,
		    X509_FILETYPE_PEM)) {
			log_warn("%s: failed to load ca file %s", __func__,
			    entry->d_name);
			ca_sslerror();
			continue;
		}
		log_debug("%s: loaded ca file %s", __func__, entry->d_name);
	}
	closedir(dir);

	/*
	 * Load CRLs for the CAs
	 */
	if ((dir = opendir(IKED_CRL_DIR)) == NULL)
		return (-1);

	while ((entry = readdir(dir)) != NULL) {
		if ((entry->d_type != DT_REG) &&
		    (entry->d_type != DT_LNK))
			continue;

		if (snprintf(file, sizeof(file), "%s%s",
		    IKED_CRL_DIR, entry->d_name) == -1)
			continue;

		if (!X509_load_crl_file(store->ca_calookup, file,
		    X509_FILETYPE_PEM)) {
			log_warn("%s: failed to load crl file %s", __func__,
			    entry->d_name);
			ca_sslerror();
			continue;
		}

		/* Only enable CRL checks if we actually loaded a CRL */
		X509_STORE_set_flags(store->ca_cas, X509_V_FLAG_CRL_CHECK);

		log_debug("%s: loaded crl file %s", __func__, entry->d_name);
	}
	closedir(dir);

	/*
	 * Save CAs signatures for the IKEv2 CERTREQ
	 */
	ibuf_release(env->sc_certreq);
	if ((env->sc_certreq = ibuf_new(NULL, 0)) == NULL)
		return (-1);

	h = store->ca_cas->objs;
	for (i = 0; i < sk_X509_OBJECT_num(h); i++) {
		xo = sk_X509_OBJECT_value(h, i);
		if (xo->type != X509_LU_X509)
			continue;

		x509 = xo->data.x509;
		len = sizeof(md);
		ca_subjectpubkey_digest(x509, md, &len);
		log_debug("%s: %s", __func__, x509->name);

		if (ibuf_add(env->sc_certreq, md, len) != 0) {
			ibuf_release(env->sc_certreq);
			return (-1);
		}
	}

	if (ibuf_length(env->sc_certreq)) {
		env->sc_certreqtype = IKEV2_CERT_X509_CERT;
		iov[0].iov_base = &env->sc_certreqtype;
		iov[0].iov_len = sizeof(env->sc_certreqtype);
		iov[1].iov_base = ibuf_data(env->sc_certreq);
		iov[1].iov_len = ibuf_length(env->sc_certreq);

		log_debug("%s: loaded %d ca certificate%s", __func__,
		    ibuf_length(env->sc_certreq) / SHA_DIGEST_LENGTH,
		    ibuf_length(env->sc_certreq) == SHA_DIGEST_LENGTH ?
		    "" : "s");

		(void)proc_composev_imsg(env, PROC_IKEV2, IMSG_CERTREQ, -1,
		    iov, iovcnt);
	}

	/*
	 * Load certificates
	 */
	if ((dir = opendir(IKED_CERT_DIR)) == NULL)
		return (-1);

	while ((entry = readdir(dir)) != NULL) {
		if ((entry->d_type != DT_REG) &&
		    (entry->d_type != DT_LNK))
			continue;

		if (snprintf(file, sizeof(file), "%s%s",
		    IKED_CERT_DIR, entry->d_name) == -1)
			continue;

		if (!X509_load_cert_file(store->ca_certlookup, file,
		    X509_FILETYPE_PEM)) {
			log_warn("%s: failed to load cert file %s", __func__,
			    entry->d_name);
			ca_sslerror();
			continue;
		}
		log_debug("%s: loaded cert file %s", __func__, entry->d_name);
	}
	closedir(dir);

	h = store->ca_certs->objs;
	for (i = 0; i < sk_X509_OBJECT_num(h); i++) {
		xo = sk_X509_OBJECT_value(h, i);
		if (xo->type != X509_LU_X509)
			continue;

		x509 = xo->data.x509;

		(void)ca_validate_cert(env, NULL, x509, 0);
	}

	return (0);
}