Blob Blame History Raw
From 2cfe657672636aa5d7d2a14cfcb0a6ab9d1f00cf Mon Sep 17 00:00:00 2001
From: Rainer Gerhards <rgerhards@adiscon.com>
Date: Tue, 20 Mar 2018 12:30:12 +0100
Subject: [PATCH] unify error message generation

---
 src/tcp.c | 38 +++++++++++++++++++++++++++++++++-----
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/src/tcp.c b/src/tcp.c
index a587627..d2d48f5 100644
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -1172,9 +1172,35 @@ relpTcpGetCN(relpTcp_t *pThis, gnutls_x509_crt_t cert, char *namebuf, int lenNam
 	return r;
 }
 
+
+/* helper to consistently add names to error message buffer */
+static int
+relpTcpAddToCertNamesBuffer(relpTcp_t *const pThis,
+	char *const buf,
+	const size_t buflen,
+	int *p_currIdx,
+	const char *const certName)
+{
+	int r = 0;
+	assert(buf != NULL);
+	assert(p_currIdx != NULL);
+	const int currIdx = *p_currIdx;
+	const int n = snprintf(buf + currIdx, buflen - currIdx,
+		"DNSname: %s; ", certName);
+	if(n < 0 || n >= (int) (buflen - currIdx)) {
+		callOnAuthErr(pThis, "", "certificate validation failed, names "
+			"inside certifcate are way to long (> 32KiB)",
+			RELP_RET_AUTH_CERT_INVL);
+		r = GNUTLS_E_CERTIFICATE_ERROR;
+	} else {
+		*p_currIdx += n;
+	}
+	return r;
+}
+
 /* Check the peer's ID in name auth mode. */
 static int
-relpTcpChkPeerName(relpTcp_t *pThis, gnutls_x509_crt_t cert)
+relpTcpChkPeerName(relpTcp_t *const pThis, gnutls_x509_crt_t cert)
 {
 	int r = 0;
 	int ret;
@@ -1213,8 +1239,9 @@ relpTcpChkPeerName(relpTcp_t *pThis, gnutls_x509_crt_t cert)
 			break;
 		else if(gnuRet == GNUTLS_SAN_DNSNAME) {
 			pThis->pEngine->dbgprint("librelp: subject alt dnsName: '%s'\n", szAltName);
-			iAllNames += snprintf(allNames+iAllNames, sizeof(allNames)-iAllNames,
-					      "DNSname: %s; ", szAltName);
+			r = relpTcpAddToCertNamesBuffer(pThis, allNames, sizeof(allNames),
+				&iAllNames, szAltName);
+			if(r != 0) goto done;
 			relpTcpChkOnePeerName(pThis, szAltName, &bFoundPositiveMatch);
 			/* do NOT break, because there may be multiple dNSName's! */
 		}
@@ -1225,8 +1252,9 @@ relpTcpChkPeerName(relpTcp_t *pThis, gnutls_x509_crt_t cert)
 		/* if we did not succeed so far, we try the CN part of the DN... */
 		if(relpTcpGetCN(pThis, cert, cnBuf, sizeof(cnBuf)) == 0) {
 			pThis->pEngine->dbgprint("librelp: relpTcp now checking auth for CN '%s'\n", cnBuf);
-			iAllNames += snprintf(allNames+iAllNames, sizeof(allNames)-iAllNames,
-					      "CN: %s; ", cnBuf);
+			r = relpTcpAddToCertNamesBuffer(pThis, allNames, sizeof(allNames),
+				&iAllNames, cnBuf);
+			if(r != 0) goto done;
 			relpTcpChkOnePeerName(pThis, cnBuf, &bFoundPositiveMatch);
 		}
 	}