kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit ca4ffa457c0f93d20e70de92b2f64f4e291207aa
parent cf6cf5f820e4531c548bca18806570730207a429
Author: Joris Vink <joris@coders.se>
Date:   Sat, 11 Dec 2021 22:36:31 +0100

Add a kore_x509_issuer_name() function.

Rework the underlying X509_NAME juggling into a kore_x509name_foreach()
so that it can be called for multiple locations.

Diffstat:
include/kore/kore.h | 4++++
src/utils.c | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
2 files changed, 84 insertions(+), 30 deletions(-)

diff --git a/include/kore/kore.h b/include/kore/kore.h @@ -910,7 +910,11 @@ char *kore_read_line(FILE *, char *, size_t); EVP_PKEY *kore_rsakey_load(const char *); EVP_PKEY *kore_rsakey_generate(const char *); +int kore_x509_issuer_name(struct connection *, char **, int); int kore_x509_subject_name(struct connection *, char **, int); +int kore_x509name_foreach(X509_NAME *, int, void *, + int (*)(void *, int, int, const char *, + const void *, size_t, int)); #if !defined(KORE_NO_HTTP) void kore_websocket_handshake(struct http_request *, diff --git a/src/utils.c b/src/utils.c @@ -54,6 +54,9 @@ static int utils_base64_encode(const void *, size_t, char **, const char *, int); static int utils_base64_decode(const char *, u_int8_t **, size_t *, const char *, int); +static int utils_x509name_tobuf(void *, int, int, const char *, + const void *, size_t, int); + static char b64_table[] = \ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -546,34 +549,71 @@ kore_worker_name(int id) } int +kore_x509_issuer_name(struct connection *c, char **out, int flags) +{ + struct kore_buf buf; + X509_NAME *name; + + if ((name = X509_get_issuer_name(c->cert)) == NULL) + return (KORE_RESULT_ERROR); + + kore_buf_init(&buf, 1024); + + if (!kore_x509name_foreach(name, flags, &buf, utils_x509name_tobuf)) { + kore_buf_cleanup(&buf); + return (KORE_RESULT_ERROR); + } + + *out = kore_buf_stringify(&buf, NULL); + + buf.offset = 0; + buf.data = NULL; + + return (KORE_RESULT_OK); +} + +int kore_x509_subject_name(struct connection *c, char **out, int flags) { struct kore_buf buf; + X509_NAME *name; + + if ((name = X509_get_subject_name(c->cert)) == NULL) + return (KORE_RESULT_ERROR); + + kore_buf_init(&buf, 1024); + + if (!kore_x509name_foreach(name, flags, &buf, utils_x509name_tobuf)) { + kore_buf_cleanup(&buf); + return (KORE_RESULT_ERROR); + } + + *out = kore_buf_stringify(&buf, NULL); + + buf.offset = 0; + buf.data = NULL; + + return (KORE_RESULT_OK); +} + +int +kore_x509name_foreach(X509_NAME *name, int flags, void *udata, + int (*cb)(void *, int, int, const char *, const void *, size_t, int)) +{ u_int8_t *data; ASN1_STRING *astr; - X509_NAME *name; X509_NAME_ENTRY *entry; const char *field; - int ret, idx, namelen, nid, len; + int islast, ret, idx, namelen, nid, len; data = NULL; ret = KORE_RESULT_ERROR; - kore_buf_init(&buf, 1024); - - if (c->cert == NULL) - goto cleanup; - - if ((name = X509_get_subject_name(c->cert)) == NULL) - goto cleanup; - - namelen = X509_NAME_entry_count(name); - if (namelen == 0) + if ((namelen = X509_NAME_entry_count(name)) == 0) goto cleanup; for (idx = 0; idx < namelen; idx++) { - entry = X509_NAME_get_entry(name, idx); - if (entry == NULL) + if ((entry = X509_NAME_get_entry(name, idx)) == NULL) goto cleanup; nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(entry)); @@ -587,33 +627,24 @@ kore_x509_subject_name(struct connection *c, char **out, int flags) if ((len = ASN1_STRING_to_UTF8(&data, astr)) < 0) goto cleanup; - if (flags & KORE_X509_COMMON_NAME_ONLY) { - if (nid == NID_commonName) { - kore_buf_append(&buf, data, len); - break; - } - } else { - kore_buf_appendf(&buf, "%s=", field); - kore_buf_append(&buf, data, len); - if (idx != (namelen - 1)) - kore_buf_appendf(&buf, " "); - } + if (idx != (namelen - 1)) + islast = 0; + else + islast = 1; + + if (!cb(udata, islast, nid, field, data, len, flags)) + goto cleanup; OPENSSL_free(data); data = NULL; } ret = KORE_RESULT_OK; - *out = kore_buf_stringify(&buf, NULL); - - buf.offset = 0; - buf.data = NULL; cleanup: if (data != NULL) OPENSSL_free(data); - kore_buf_cleanup(&buf); return (ret); } @@ -658,6 +689,25 @@ fatal_log(const char *fmt, va_list args) } static int +utils_x509name_tobuf(void *udata, int islast, int nid, const char *field, + const void *data, size_t len, int flags) +{ + struct kore_buf *buf = udata; + + if (flags & KORE_X509_COMMON_NAME_ONLY) { + if (nid == NID_commonName) + kore_buf_append(buf, data, len); + } else { + kore_buf_appendf(buf, "%s=", field); + kore_buf_append(buf, data, len); + if (!islast) + kore_buf_appendf(buf, " "); + } + + return (KORE_RESULT_OK); +} + +static int utils_base64_encode(const void *data, size_t len, char **out, const char *table, int flags) {