From e6a13543eb90a73b095c4aa84038753d31ff2b39 Mon Sep 17 00:00:00 2001 From: Riza Sulistyo Date: Wed, 27 Jan 2016 09:55:13 +0000 Subject: Misc (Re #1882): Add raw certificate information to pj_ssl_cert_info data. Thanks to Peter Koletzki for the suggestion. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5238 74dad513-b988-da41-8d7b-12977e46ad98 --- pjlib/include/pj/ssl_sock.h | 3 +++ pjlib/src/pj/ssl_sock_ossl.c | 31 +++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/pjlib/include/pj/ssl_sock.h b/pjlib/include/pj/ssl_sock.h index f31a0452..e69d2624 100644 --- a/pjlib/include/pj/ssl_sock.h +++ b/pjlib/include/pj/ssl_sock.h @@ -181,6 +181,9 @@ typedef struct pj_ssl_cert_info { } subj_alt_name; /**< Subject alternative name extension */ + pj_str_t raw; /**< Raw certificate in PEM format, only + available for remote certificate. */ + } pj_ssl_cert_info; diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c index 58c36e44..b9c9bd99 100644 --- a/pjlib/src/pj/ssl_sock_ossl.c +++ b/pjlib/src/pj/ssl_sock_ossl.c @@ -983,12 +983,13 @@ static void get_cn_from_gen_name(const pj_str_t *gen_name, pj_str_t *cn) * hal already populated, this function will check if the contents need * to be updated by inspecting the issuer and the serial number. */ -static void get_cert_info(pj_pool_t *pool, pj_ssl_cert_info *ci, X509 *x) +static void get_cert_info(pj_pool_t *pool, pj_ssl_cert_info *ci, X509 *x, + pj_bool_t get_pem) { pj_bool_t update_needed; char buf[512]; pj_uint8_t serial_no[64] = {0}; /* should be >= sizeof(ci->serial_no) */ - pj_uint8_t *p; + pj_uint8_t *q; unsigned len; GENERAL_NAMES *names = NULL; @@ -998,11 +999,11 @@ static void get_cert_info(pj_pool_t *pool, pj_ssl_cert_info *ci, X509 *x) X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof(buf)); /* Get serial no */ - p = (pj_uint8_t*) M_ASN1_STRING_data(X509_get_serialNumber(x)); + q = (pj_uint8_t*) M_ASN1_STRING_data(X509_get_serialNumber(x)); len = M_ASN1_STRING_length(X509_get_serialNumber(x)); if (len > sizeof(ci->serial_no)) len = sizeof(ci->serial_no); - pj_memcpy(serial_no + sizeof(ci->serial_no) - len, p, len); + pj_memcpy(serial_no + sizeof(ci->serial_no) - len, q, len); /* Check if the contents need to be updated. */ update_needed = pj_strcmp2(&ci->issuer.info, buf) || @@ -1096,6 +1097,24 @@ static void get_cert_info(pj_pool_t *pool, pj_ssl_cert_info *ci, X509 *x) } } } + + if (get_pem) { + /* Update raw Certificate info in PEM format. */ + BIO *bio; + BUF_MEM *ptr; + + bio = BIO_new(BIO_s_mem()); + if (!PEM_write_bio_X509(bio, x)) { + PJ_LOG(3,(THIS_FILE, "Error retrieving raw certificate info")); + ci->raw.ptr = NULL; + ci->raw.slen = 0; + } else { + BIO_write(bio, "\0", 1); + BIO_get_mem_ptr(bio, &ptr); + pj_strdup2(pool, &ci->raw, ptr->data); + } + BIO_free(bio); + } } @@ -1111,7 +1130,7 @@ static void update_certs_info(pj_ssl_sock_t *ssock) /* Active local certificate */ x = SSL_get_certificate(ssock->ossl_ssl); if (x) { - get_cert_info(ssock->pool, &ssock->local_cert_info, x); + get_cert_info(ssock->pool, &ssock->local_cert_info, x, PJ_FALSE); /* Don't free local's X509! */ } else { pj_bzero(&ssock->local_cert_info, sizeof(pj_ssl_cert_info)); @@ -1120,7 +1139,7 @@ static void update_certs_info(pj_ssl_sock_t *ssock) /* Active remote certificate */ x = SSL_get_peer_certificate(ssock->ossl_ssl); if (x) { - get_cert_info(ssock->pool, &ssock->remote_cert_info, x); + get_cert_info(ssock->pool, &ssock->remote_cert_info, x, PJ_TRUE); /* Free peer's X509 */ X509_free(x); } else { -- cgit v1.2.3