[PATCH] ustream-ssl: store TLS peer cert data in a ustream_ssl structure

Luka Logar luka.logar at cifra.si
Fri Feb 19 15:01:50 EST 2021


Store peer certificate, it's sha256 hash and subject name in ustream_ssl struct, so the upper layer
can access and use this data. This data can then be used, for example, in client authentication.

Signed-off-by: Luka Logar <luka.logar at cifra.si>
---
 ustream-openssl.c | 22 ++++++++++++++++++++++
 ustream-ssl.c     |  5 +++++
 ustream-ssl.h     |  4 ++++
 3 files changed, 31 insertions(+)

diff --git a/ustream-openssl.c b/ustream-openssl.c
index 1ce796a..926fe71 100644
--- a/ustream-openssl.c
+++ b/ustream-openssl.c
@@ -267,6 +267,10 @@ static void ustream_ssl_verify_cert(struct ustream_ssl *us)
 	void *ssl = us->ssl;
 	X509 *cert;
 	int res;
+	BIO *bio;
+	char *ptr;
+	int len;
+	unsigned char md[32];
 
 	res = SSL_get_verify_result(ssl);
 	if (res != X509_V_OK) {
@@ -282,6 +286,24 @@ static void ustream_ssl_verify_cert(struct ustream_ssl *us)
 	us->valid_cert = true;
 	us->valid_cn = ustream_ssl_verify_cn(us, cert);
 
+	bio = BIO_new(BIO_s_mem());
+	PEM_write_bio_X509(bio, cert);
+	len = BIO_get_mem_data(bio, &ptr);
+	us->peer_cert = calloc(1, len + 1);
+	memcpy(us->peer_cert, ptr, len);
+	BIO_free(bio);
+
+	X509_digest(cert, EVP_sha256(), md, NULL);
+	for (int n = 0; n < 32; n++)
+		sprintf(&us->peer_cert_sha256[2*n], "%02X", md[n]);
+
+	bio = BIO_new(BIO_s_mem());
+	X509_NAME_print_ex(bio, X509_get_subject_name(cert), 0, 0);
+	len = BIO_get_mem_data(bio, &ptr);
+	us->peer_cert_sn = calloc(1, len + 1);
+	memcpy(us->peer_cert_sn, ptr, len);
+	BIO_free(bio);
+
 	X509_free(cert);
 }
 
diff --git a/ustream-ssl.c b/ustream-ssl.c
index cd69f9e..98435c8 100644
--- a/ustream-ssl.c
+++ b/ustream-ssl.c
@@ -156,6 +156,8 @@ static void ustream_ssl_free(struct ustream *s)
 	uloop_timeout_cancel(&us->error_timer);
 	__ustream_ssl_session_free(us->ssl);
 	free(us->peer_cn);
+	free(us->peer_cert);
+	free(us->peer_cert_sn);
 
 	us->ctx = NULL;
 	us->ssl = NULL;
@@ -199,6 +201,9 @@ static int _ustream_ssl_init(struct ustream_ssl *us, struct ustream *conn, struc
 	us->conn = conn;
 	us->ctx = ctx;
 
+	us->peer_cert = NULL;
+	us->peer_cert_sn = NULL;
+
 	us->ssl = __ustream_ssl_session_new(us->ctx);
 	if (!us->ssl)
 		return -ENOMEM;
diff --git a/ustream-ssl.h b/ustream-ssl.h
index 87c0ae6..fc80552 100644
--- a/ustream-ssl.h
+++ b/ustream-ssl.h
@@ -43,6 +43,10 @@ struct ustream_ssl {
 	bool valid_cert;
 	bool valid_cn;
 	bool require_validation;
+
+	char *peer_cert;
+	char  peer_cert_sha256[65];
+	char *peer_cert_sn;
 };
 
 struct ustream_ssl_ctx;
-- 
2.25.1





More information about the openwrt-devel mailing list