summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreyk <reyk@openbsd.org>2010-06-29 21:04:42 +0000
committerreyk <reyk@openbsd.org>2010-06-29 21:04:42 +0000
commit9474eae8fba8dd2040fa14c4b2ec15dfd0b1030f (patch)
tree204b7f5dad4fb8f629e5f8f2441bcaf22fa1a1b3
parentShave off some instructions: (diff)
downloadwireguard-openbsd-9474eae8fba8dd2040fa14c4b2ec15dfd0b1030f.tar.xz
wireguard-openbsd-9474eae8fba8dd2040fa14c4b2ec15dfd0b1030f.zip
add code to lookup the RSA public keys in /etc/iked/pubkeys/ as an
alternative to X.509 CA verification. this will be needed to support public key authentication like isakmpd does; a few bits are still missing.
-rw-r--r--sbin/iked/ca.c114
-rw-r--r--sbin/iked/iked.h3
-rw-r--r--sbin/iked/types.h3
-rw-r--r--sbin/iked/util.c9
4 files changed, 121 insertions, 8 deletions
diff --git a/sbin/iked/ca.c b/sbin/iked/ca.c
index 197e0ad3dc4..7d9bbe20e82 100644
--- a/sbin/iked/ca.c
+++ b/sbin/iked/ca.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ca.c,v 1.9 2010/06/27 05:49:05 reyk Exp $ */
+/* $OpenBSD: ca.c,v 1.10 2010/06/29 21:04:42 reyk Exp $ */
/* $vantronix: ca.c,v 1.29 2010/06/02 12:22:58 reyk Exp $ */
/*
@@ -58,6 +58,8 @@ int ca_getauth(struct iked *, struct imsg *);
X509 *ca_by_subjectpubkey(X509_STORE *, u_int8_t *, size_t);
X509 *ca_by_issuer(X509_STORE *, X509_NAME *, struct iked_static_id *);
int ca_subjectpubkey_digest(X509 *, u_int8_t *, u_int *);
+int ca_validate_pubkey(struct iked *, struct iked_static_id *,
+ void *, size_t);
int ca_validate_cert(struct iked *, struct iked_static_id *,
void *, size_t);
struct ibuf *
@@ -320,7 +322,7 @@ ca_getcert(struct iked *env, struct imsg *imsg)
struct iked_static_id id;
u_int i;
struct iovec iov[2];
- int iovcnt = 2, cmd;
+ int iovcnt = 2, cmd, ret = 0;
ptr = (u_int8_t *)imsg->data;
len = IMSG_DATA_SIZE(imsg);
@@ -333,13 +335,24 @@ ca_getcert(struct iked *env, struct imsg *imsg)
return (-1);
memcpy(&sh, ptr + sizeof(id), sizeof(sh));
memcpy(&type, ptr + sizeof(id) + sizeof(sh), sizeof(u_int8_t));
- if (type != IKEV2_CERT_X509_CERT)
- return (-1);
ptr += i;
len -= i;
- if (ca_validate_cert(env, &id, ptr, len) == 0)
+ switch (type) {
+ case IKEV2_CERT_X509_CERT:
+ ret = ca_validate_cert(env, &id, ptr, len);
+ 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;
@@ -801,6 +814,91 @@ ca_x509_name(void *ptr)
}
int
+ca_validate_pubkey(struct iked *env, struct iked_static_id *id,
+ void *data, size_t len)
+{
+ BIO *rawcert = NULL;
+ RSA *rsa = NULL;
+ EVP_PKEY *peerkey = NULL, *localkey = NULL;
+ int ret = -1;
+ FILE *fp = NULL;
+ char idstr[IKED_ID_SIZE];
+ char file[MAXPATHLEN];
+ struct iked_id idp;
+
+ if (len == 0 && data == NULL)
+ return (-1);
+
+ switch (id->id_type) {
+ case IKEV2_ID_IPV4:
+ case IKEV2_ID_FQDN:
+ case IKEV2_ID_UFQDN:
+ case IKEV2_ID_IPV6:
+ break;
+ default:
+ /* Some types like ASN1_DN will not be mapped to file names */
+ return (-1);
+ }
+
+ bzero(&idp, sizeof(idp));
+ if ((idp.id_buf = ibuf_new(id->id_data, id->id_length)) == NULL)
+ goto done;
+
+ idp.id_type = id->id_type;
+ idp.id_offset = id->id_offset;
+ if (print_id(&idp, idstr, sizeof(idstr)) == -1)
+ goto done;
+
+ if (len == 0) {
+ /* Data is already an public key */
+ peerkey = (EVP_PKEY *)data;
+ } else {
+ if ((rawcert = BIO_new_mem_buf(data, len)) == NULL)
+ goto done;
+
+ if ((rsa = d2i_RSAPublicKey_bio(rawcert, NULL)) == NULL)
+ goto sslerr;
+ if ((peerkey = EVP_PKEY_new()) == NULL)
+ goto sslerr;
+ if (!EVP_PKEY_set1_RSA(peerkey, rsa))
+ goto sslerr;
+ }
+
+ lc_string(idstr);
+ if (strlcpy(file, IKED_PUBKEY_DIR, sizeof(file)) >= sizeof(file) ||
+ strlcpy(file, idstr, sizeof(file)) >= sizeof(file))
+ goto done;
+
+ log_debug("%s: looking up %s", __func__, file);
+
+ if ((fp = fopen(file, "r")) == NULL)
+ goto done;
+
+ localkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL);
+ fclose(fp);
+ if (localkey == NULL)
+ goto sslerr;
+
+ if (!EVP_PKEY_cmp(peerkey, localkey))
+ goto done;
+
+ ret = 0;
+ sslerr:
+ if (ret != 0)
+ ca_sslerror();
+ done:
+ ibuf_release(idp.id_buf);
+ if (peerkey != NULL)
+ EVP_PKEY_free(peerkey);
+ if (rsa != NULL)
+ RSA_free(rsa);
+ if (rawcert != NULL)
+ BIO_free(rawcert);
+
+ return (ret);
+}
+
+int
ca_validate_cert(struct iked *env, struct iked_static_id *id,
void *data, size_t len)
{
@@ -832,6 +930,12 @@ ca_validate_cert(struct iked *env, struct iked_static_id *id,
}
if (id != NULL) {
+ if ((ret = ca_validate_pubkey(env, id, X509_get_pubkey(cert),
+ 0)) == 0) {
+ errstr = "public key found, ok";
+ goto done;
+ }
+
switch (id->id_type) {
case IKEV2_ID_ASN1_DN:
idoff = id->id_offset;
diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h
index 15281d0ce92..b02d00d02b7 100644
--- a/sbin/iked/iked.h
+++ b/sbin/iked/iked.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: iked.h,v 1.16 2010/06/27 05:49:05 reyk Exp $ */
+/* $OpenBSD: iked.h,v 1.17 2010/06/29 21:04:42 reyk Exp $ */
/* $vantronix: iked.h,v 1.61 2010/06/03 07:57:33 reyk Exp $ */
/*
@@ -714,6 +714,7 @@ const char *
print_spi(u_int64_t, int);
const char *
print_map(u_int, struct iked_constmap *);
+void lc_string(char *);
void print_hex(u_int8_t *, off_t, size_t);
void print_hexval(u_int8_t *, off_t, size_t);
const char *
diff --git a/sbin/iked/types.h b/sbin/iked/types.h
index 97c24c7c684..0347e74fe1a 100644
--- a/sbin/iked/types.h
+++ b/sbin/iked/types.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: types.h,v 1.5 2010/06/10 14:17:48 reyk Exp $ */
+/* $OpenBSD: types.h,v 1.6 2010/06/29 21:04:42 reyk Exp $ */
/* $vantronix: types.h,v 1.24 2010/05/11 12:05:56 reyk Exp $ */
/*
@@ -33,6 +33,7 @@
#define IKED_CA_DIR "ca/"
#define IKED_CRL_DIR "crls/"
#define IKED_CERT_DIR "certs/"
+#define IKED_PUBKEY_DIR "pubkey/"
#define IKED_PRIVKEY IKED_CA "private/local.key"
#define IKED_PUBKEY "local.pub"
diff --git a/sbin/iked/util.c b/sbin/iked/util.c
index 77804d00540..ed6ffd7258f 100644
--- a/sbin/iked/util.c
+++ b/sbin/iked/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.6 2010/06/27 00:32:06 reyk Exp $ */
+/* $OpenBSD: util.c,v 1.7 2010/06/29 21:04:42 reyk Exp $ */
/* $vantronix: util.c,v 1.39 2010/06/02 12:22:58 reyk Exp $ */
/*
@@ -475,6 +475,13 @@ print_map(u_int type, struct iked_constmap *map)
}
void
+lc_string(char *str)
+{
+ for (; *str != '\0'; str++)
+ *str = tolower(*str);
+}
+
+void
print_hex(u_int8_t *buf, off_t offset, size_t length)
{
u_int i;