summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRiza Sulistyo <riza@teluu.com>2016-01-27 09:55:13 +0000
committerRiza Sulistyo <riza@teluu.com>2016-01-27 09:55:13 +0000
commite6a13543eb90a73b095c4aa84038753d31ff2b39 (patch)
treef4b4d8276de42b66042d99d462a0e081b83408a0
parent687340a74c5c791f11590893a6ed909e98c860e7 (diff)
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
-rw-r--r--pjlib/include/pj/ssl_sock.h3
-rw-r--r--pjlib/src/pj/ssl_sock_ossl.c31
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 {