[PATCH 1/6] rpc: Resize dname for longer DN from TLS certs

Martin Kletzander mkletzan at redhat.com
Thu Nov 11 15:06:41 UTC 2021


And to make that easier, allocate it on the heap.

Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
---
 src/rpc/virnettlscontext.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c
index 1340faa22485..3babf3ee4dc3 100644
--- a/src/rpc/virnettlscontext.c
+++ b/src/rpc/virnettlscontext.c
@@ -980,11 +980,9 @@ static int virNetTLSContextValidCertificate(virNetTLSContext *ctxt,
     const gnutls_datum_t *certs;
     unsigned int nCerts;
     size_t i;
-    char dname[256];
+    size_t dnamesize = 256;
+    g_autofree char *dname = g_new0(char, dnamesize);
     char *dnameptr = dname;
-    size_t dnamesize = sizeof(dname);
-
-    memset(dname, 0, dnamesize);
 
     if ((ret = gnutls_certificate_verify_peers2(sess->session, &status)) < 0) {
         virReportError(VIR_ERR_SYSTEM_ERROR,
@@ -1050,17 +1048,23 @@ static int virNetTLSContextValidCertificate(virNetTLSContext *ctxt,
 
         if (i == 0) {
             ret = gnutls_x509_crt_get_dn(cert, dname, &dnamesize);
+            if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
+                VIR_DEBUG("Reallocating dname to fit %zu bytes", dnamesize);
+                dname = g_realloc(dname, dnamesize);
+                dnameptr = dname;
+                ret = gnutls_x509_crt_get_dn(cert, dname, &dnamesize);
+            }
             if (ret != 0) {
                 virReportError(VIR_ERR_SYSTEM_ERROR,
                                _("Failed to get certificate %s distinguished name: %s"),
                                "[session]", gnutls_strerror(ret));
                 goto authfail;
             }
-            sess->x509dname = g_strdup(dname);
-            VIR_DEBUG("Peer DN is %s", dname);
+            sess->x509dname = g_steal_pointer(&dname);
+            VIR_DEBUG("Peer DN is %s", dnameptr);
 
-            if (virNetTLSContextCheckCertDN(cert, "[session]", sess->hostname, dname,
-                                            ctxt->x509dnACL) < 0) {
+            if (virNetTLSContextCheckCertDN(cert, "[session]", sess->hostname,
+                                            dnameptr, ctxt->x509dnACL) < 0) {
                 gnutls_x509_crt_deinit(cert);
                 goto authdeny;
             }
-- 
2.33.1




More information about the libvir-list mailing list