Skip to content

Commit

Permalink
tls: functions to get the certificate issuer and subject
Browse files Browse the repository at this point in the history
  • Loading branch information
cHuberCoffee committed Sep 4, 2020
1 parent 53ad99f commit bd8c78e
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/re_tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down
126 changes: 126 additions & 0 deletions src/tls/openssl/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
7 changes: 7 additions & 0 deletions src/tls/openssl/tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@
#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;
Expand Down

0 comments on commit bd8c78e

Please sign in to comment.