summaryrefslogtreecommitdiff
path: root/src/irmd/oap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/irmd/oap.c')
-rw-r--r--src/irmd/oap.c290
1 files changed, 66 insertions, 224 deletions
diff --git a/src/irmd/oap.c b/src/irmd/oap.c
index 500da6f1..085e06a3 100644
--- a/src/irmd/oap.c
+++ b/src/irmd/oap.c
@@ -1,7 +1,7 @@
/*
* Ouroboros - Copyright (C) 2016 - 2024
*
- * Ouroboros flow allocation protocol header
+ * OAP - Shared credential and configuration loading
*
* Dimitri Staessens <dimitri@ouroboros.rocks>
* Sander Vrijders <sander@ouroboros.rocks>
@@ -29,260 +29,102 @@
#define OUROBOROS_PREFIX "irmd/oap"
#include <ouroboros/crypt.h>
-#include <ouroboros/endian.h>
+#include <ouroboros/errno.h>
#include <ouroboros/logs.h>
-#include <ouroboros/rib.h>
-#include <ouroboros/time.h>
#include "config.h"
-#include "oap.h"
-
#include <assert.h>
+#include <string.h>
+#include <sys/stat.h>
-int oap_hdr_init(buffer_t id,
- void * pkp,
- void * pubcrt,
- buffer_t ephkey,
- buffer_t data,
- struct oap_hdr * oap_hdr)
-{
- struct timespec now;
- uint64_t stamp;
- buffer_t hdr;
- buffer_t der = BUF_INIT;
- buffer_t sig = BUF_INIT;
- buffer_t sign;
- uint16_t len;
- off_t offset;
-
- assert(id.data != NULL && id.len == OAP_ID_SIZE);
- assert(oap_hdr != NULL);
- memset(oap_hdr, 0, sizeof(*oap_hdr));
-
- clock_gettime(CLOCK_REALTIME, &now);
- stamp = hton64(TS_TO_UINT64(now));
-
- if (pubcrt != NULL && crypt_crt_der(pubcrt, &der) < 0)
- goto fail_der;
-
- hdr.len = id.len +
- sizeof(stamp) +
- sizeof(len) + der.len +
- sizeof(len) + ephkey.len +
- sizeof(len) + data.len +
- sizeof(len); /* sig len */
-
- hdr.data = malloc(hdr.len);
- if (hdr.data == NULL)
- goto fail_hdr;
-
- offset = 0;
-
- memcpy(hdr.data, id.data, id.len);
- offset += id.len;
-
- memcpy(hdr.data + offset, &stamp, sizeof(stamp));
- offset += sizeof(stamp);
-
- /* pubcrt */
- len = hton16((uint16_t) der.len);
- memcpy(hdr.data + offset, &len, sizeof(len));
- offset += sizeof(len);
- if (der.len != 0)
- memcpy(hdr.data + offset, der.data, der.len);
- offset += der.len;
-
- /* ephkey */
- len = hton16((uint16_t) ephkey.len);
- memcpy(hdr.data + offset, &len, sizeof(len));
- offset += sizeof(len);
- if (ephkey.len != 0)
- memcpy(hdr.data + offset, ephkey.data, ephkey.len);
- offset += ephkey.len;
-
- /* data */
- len = hton16((uint16_t) data.len);
- memcpy(hdr.data + offset, &len, sizeof(len));
- offset += sizeof(len);
- if (data.len != 0)
- memcpy(hdr.data + offset, data.data, data.len);
- offset += data.len;
-
- sign.data = hdr.data;
- sign.len = hdr.len - sizeof(len);
-
- if (pkp != NULL && auth_sign(pkp, sign, &sig) < 0)
- goto fail_sig;
-
- len = hton16((uint16_t) sig.len);
- memcpy(hdr.data + offset, &len, sizeof(len));
- offset += sizeof(len);
-
- oap_hdr->hdr = hdr;
+/*
+ * Shared credential and configuration loading helpers
+ */
- assert((size_t) offset == hdr.len);
+#ifndef OAP_TEST_MODE
- if (sig.len > 0) {
- oap_hdr->hdr.len += sig.len;
- oap_hdr->hdr.data = realloc(hdr.data, oap_hdr->hdr.len);
- if (oap_hdr->hdr.data == NULL)
- goto fail_oap_hdr;
+static bool file_exists(const char * path)
+{
+ struct stat s;
- memcpy(oap_hdr->hdr.data + offset, sig.data, sig.len);
- clrbuf(hdr);
+ if (stat(path, &s) < 0 && errno == ENOENT) {
+ log_dbg("File %s does not exist.", path);
+ return false;
}
- if (oap_hdr_decode(oap_hdr->hdr, oap_hdr) < 0)
- goto fail_decode;
-
- freebuf(der);
- freebuf(sig);
-
- return 0;
-
- fail_decode:
- oap_hdr_fini(oap_hdr);
- fail_oap_hdr:
- freebuf(sig);
- fail_sig:
- freebuf(hdr);
- fail_hdr:
- freebuf(der);
- fail_der:
- memset(oap_hdr, 0, sizeof(*oap_hdr));
- return -1;
+ return true;
}
-void oap_hdr_fini(struct oap_hdr * oap_hdr)
+int load_credentials(const char * name,
+ const struct name_sec_paths * paths,
+ void ** pkp,
+ void ** crt)
{
- assert(oap_hdr != NULL);
-
- freebuf(oap_hdr->hdr);
- memset(oap_hdr, 0, sizeof(*oap_hdr));
-}
-
-int oap_hdr_decode(buffer_t hdr,
- struct oap_hdr * oap_hdr)
-{
- off_t offset;
-
- assert(oap_hdr != NULL);
- memset(oap_hdr, 0, sizeof(*oap_hdr));
-
- if (hdr.len < OAP_HDR_MIN_SIZE)
- goto fail_decode;
-
- oap_hdr->id.data = hdr.data;
- oap_hdr->id.len = OAP_ID_SIZE;
+ assert(paths != NULL);
+ assert(pkp != NULL);
+ assert(crt != NULL);
- offset = OAP_ID_SIZE;
+ *pkp = NULL;
+ *crt = NULL;
- oap_hdr->timestamp = ntoh64(*(uint64_t *)(hdr.data + offset));
-
- offset += sizeof(uint64_t);
-
- oap_hdr->crt.len = (size_t) ntoh16(*(uint16_t *)(hdr.data + offset));
- oap_hdr->crt.data = hdr.data + offset + sizeof(uint16_t);
-
- offset += sizeof(uint16_t) + oap_hdr->crt.len;
-
- if ((size_t) offset + sizeof(uint16_t) >= hdr.len)
- goto fail_decode;
-
- oap_hdr->eph.len = (size_t) ntoh16(*(uint16_t *)(hdr.data + offset));
- oap_hdr->eph.data = hdr.data + offset + sizeof(uint16_t);
-
- offset += sizeof(uint16_t) + oap_hdr->eph.len;
-
- if ((size_t) offset + sizeof(uint16_t) >= hdr.len)
- goto fail_decode;
-
- oap_hdr->data.len = (size_t) ntoh16(*(uint16_t *)(hdr.data + offset));
- oap_hdr->data.data = hdr.data + offset + sizeof(uint16_t);
-
- offset += sizeof(uint16_t) + oap_hdr->data.len;
-
- if ((size_t) offset + sizeof(uint16_t) > hdr.len)
- goto fail_decode;
-
- oap_hdr->sig.len = (size_t) ntoh16(*(uint16_t *)(hdr.data + offset));
- oap_hdr->sig.data = hdr.data + offset + sizeof(uint16_t);
+ if (!file_exists(paths->crt) || !file_exists(paths->key)) {
+ log_info("No authentication certificates for %s.", name);
+ return 0;
+ }
- offset += sizeof(uint16_t) + oap_hdr->sig.len;
+ if (crypt_load_crt_file(paths->crt, crt) < 0) {
+ log_err("Failed to load %s for %s.", paths->crt, name);
+ goto fail_crt;
+ }
- if ((size_t) offset != hdr.len)
- goto fail_decode;
+ if (crypt_load_privkey_file(paths->key, pkp) < 0) {
+ log_err("Failed to load %s for %s.", paths->key, name);
+ goto fail_key;
+ }
- oap_hdr->hdr = hdr;
+ log_info("Loaded authentication certificates for %s.", name);
return 0;
- fail_decode:
- memset(oap_hdr, 0, sizeof(*oap_hdr));
- return -1;
-}
-
-#ifdef DEBUG_PROTO_OAP
-static void debug_oap_hdr(const struct oap_hdr * hdr)
-{
- assert(hdr);
-
- if (hdr->crt.len > 0)
- log_proto(" Certificate: [%zu bytes]", hdr->crt.len);
- else
- log_proto(" Certificate: <none>");
-
- if (hdr->eph.len > 0)
- log_proto(" Ephemeral Public Key: [%zu bytes]", hdr->eph.len);
- else
- log_proto(" Ephemeral Public Key: <none>");
- if (hdr->data.len > 0)
- log_proto(" Data: [%zu bytes]", hdr->data.len);
- else
- log_proto(" Data: <none>");
- if (hdr->sig.len > 0)
- log_proto(" Signature: [%zu bytes]", hdr->sig.len);
- else
- log_proto(" Signature: <none>");
+ fail_key:
+ crypt_free_crt(*crt);
+ *crt = NULL;
+ fail_crt:
+ return -EAUTH;
}
-void debug_oap_hdr_rcv(const struct oap_hdr * hdr)
+int load_kex_config(const char * name,
+ const char * path,
+ struct sec_config * cfg)
{
- struct tm * tm;
- char tmstr[RIB_TM_STRLEN];
- time_t stamp;
+ assert(name != NULL);
+ assert(cfg != NULL);
- assert(hdr);
+ memset(cfg, 0, sizeof(*cfg));
- stamp = (time_t) hdr->timestamp / BILLION;
-
- tm = gmtime(&stamp);
- strftime(tmstr, sizeof(tmstr), RIB_TM_FORMAT, tm);
-
- log_proto("OAP_HDR [" HASH_FMT64 " @ %s ] <--",
- HASH_VAL64(hdr->id.data), tmstr);
-
- debug_oap_hdr(hdr);
-}
+ /* Load encryption config */
+ if (!file_exists(path))
+ log_dbg("No encryption %s for %s.", path, name);
-void debug_oap_hdr_snd(const struct oap_hdr * hdr)
-{
- struct tm * tm;
- char tmstr[RIB_TM_STRLEN];
- time_t stamp;
-
- assert(hdr);
+ if (load_sec_config_file(cfg, path) < 0) {
+ log_warn("Failed to load %s for %s.", path, name);
+ return -1;
+ }
- stamp = (time_t) hdr->timestamp / BILLION;
+ if (!IS_KEX_ALGO_SET(cfg)) {
+ log_info("Key exchange not configured for %s.", name);
+ return 0;
+ }
- tm = gmtime(&stamp);
- strftime(tmstr, sizeof(tmstr), RIB_TM_FORMAT, tm);
+ if (cfg->c.nid == NID_undef || crypt_nid_to_str(cfg->c.nid) == NULL) {
+ log_err("Invalid cipher NID %d for %s.", cfg->c.nid, name);
+ return -ECRYPT;
+ }
- log_proto("OAP_HDR [" HASH_FMT64 " @ %s ] -->",
- HASH_VAL64(hdr->id.data), tmstr);
+ log_info("Encryption enabled for %s.", name);
- debug_oap_hdr(hdr);
+ return 0;
}
-#endif
+#endif /* OAP_TEST_MODE */