tls: functions to get the certificate issuer and subject
MODIFY
include/re_tls.h
include/re_tls.h
@@ -61,6 +61,8 @@ int tls_set_ciphers(struct tls *tls, const char *cipherv[], size_t count);
int tls_set_servername(struct tls_conn *tc, const char *servername);
int tls_set_verify_server(struct tls_conn *tc, const char *host);
+int tls_get_issuer(struct tls *tls, struct mbuf *mb);
+int tls_get_subject(struct tls *tls, struct mbuf *mb);
/* TCP */

MODIFY
src/tls/openssl/tls.c
src/tls/openssl/tls.c
@@ -1033,3 +1033,129 @@ struct ssl_ctx_st *tls_openssl_context(const struct tls *tls)
{
return tls ? tls->ctx : NULL;
}
+
+
+/**
+ * Convert a X509_NAME object into a human-readable form placed in an mbuf
+ *
+ * @param field X509_NAME of Cert field
+ * @param mb Memorybuffer to store the readable format
+ * @param flags X509_NAME_print_ex flags
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+static int convert_X509_NAME_to_mbuf(X509_NAME *field, struct mbuf *mb,
+ unsigned long flags)
+{
+ BIO *outbio;
+ char *p;
+ long size;
+ int err = ENOMEM;
+
+ if (!field || !mb)
+ return EINVAL;
+
+ outbio = BIO_new(BIO_s_mem());
+ if (!outbio)
+ return ENOMEM;
+
+ if (X509_NAME_print_ex(outbio, field, 1, flags) <= 0)
+ goto out;
+
+ if (BIO_eof(outbio))
+ goto out;
+
+ size = BIO_get_mem_data(outbio, &p);
+ err = mbuf_write_mem(mb, (uint8_t *)p, size);
+ if (err)
+ goto out;
+
+ err = 0;
+
+ out:
+ if (outbio)
+ BIO_free(outbio);
+
+ return err;
+}
+
+
+/**
+ * Extract a X509 certficate issuer/subject and write the result into an mbuf
+ *
+ * @param tls TLS Object
+ * @param mb Memory buffer
+ * @param field_getter Functionpointer to the X509 getter functon
+ * @param flags X509_NAME_print_ex flags
+ *
+ * @return 0 if success, othewise errorcode
+ */
+static int tls_get_ca_chain_field(struct tls *tls, struct mbuf *mb,
+ tls_get_certfield_h *field_getter, unsigned long flags)
+{
+ STACK_OF(X509) *certstack;
+ X509 *cert;
+ X509_NAME *field;
+ int err = EINVAL;
+
+ if (!field_getter)
+ return EINVAL;
+
+ if (!SSL_CTX_get0_chain_certs(tls->ctx, &certstack) || !certstack)
+ goto out;
+
+ for (int i = 0; i < sk_X509_num(certstack); i++) {
+ cert = sk_X509_value(certstack, i);
+ if (!cert)
+ goto out;
+
+ field = field_getter(cert);
+ if (!field)
+ goto out;
+
+ err = convert_X509_NAME_to_mbuf(field, mb, flags);
+ if (err)
+ goto out;
+ }
+
+ err = 0;
+
+ out:
+ return err;
+}
+
+
+/**
+ * Get the issuers fields of a certificate chain
+ *
+ * @param tls TLS Object
+ * @param mb Memory Buffer
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int tls_get_issuer(struct tls *tls, struct mbuf *mb)
+{
+ if (!tls || !tls->ctx || !mb)
+ return EINVAL;
+
+ return tls_get_ca_chain_field(tls, mb, &X509_get_issuer_name,
+ XN_FLAG_RFC2253);
+}
+
+
+/**
+ * Get the subject fields of a certificate chain
+ *
+ * @param tls TLS Object
+ * @param mb Memory Buffer
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int tls_get_subject(struct tls *tls, struct mbuf *mb)
+{
+ if (!tls || !tls->ctx || !mb)
+ return EINVAL;
+
+ return tls_get_ca_chain_field(tls, mb, &X509_get_subject_name,
+ XN_FLAG_RFC2253);
+}

MODIFY
src/tls/openssl/tls.h
src/tls/openssl/tls.h
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+typedef X509_NAME*(tls_get_certfield_h)(const X509 *);
+#else
+typedef X509_NAME*(tls_get_certfield_h)(X509 *);
+#endif
+
+
struct tls {
SSL_CTX *ctx;
X509 *cert;

tls: functions to get the certificate issuer and subject