[PATCH 2/9] rpc: refactor method for checking session certificates

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This will facilitate moving much of the code into a new file in the
subsequent commit.

Signed-off-by: Daniel P. Berrangé <berrange@xxxxxxxxxx>
---
 src/rpc/virnettlscontext.c | 109 ++++++++++++++++++++++---------------
 1 file changed, 66 insertions(+), 43 deletions(-)

diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c
index 4223043bc9..a56abee009 100644
--- a/src/rpc/virnettlscontext.c
+++ b/src/rpc/virnettlscontext.c
@@ -876,6 +876,65 @@ virNetTLSContext *virNetTLSContextNewClient(const char *cacert,
                                sanityCheckCert, requireValidCert, false);
 }
 
+static int virNetTLSContextCertValidateCA(gnutls_x509_crt_t cert,
+                                          bool isServer)
+{
+    if (virNetTLSContextCheckCertTimes(cert, "[session]", isServer, true) < 0)
+        return -1;
+
+    return 0;
+}
+
+static char *virNetTLSContextCertValidate(gnutls_x509_crt_t cert,
+                                          bool isServer,
+                                          const char *hostname,
+                                          const char *const *x509dnACL)
+{
+    size_t dnamesize = 256;
+    g_autofree char *dname = g_new0(char, dnamesize);
+    int ret;
+
+    if (virNetTLSContextCheckCertTimes(cert, "[session]",
+                                       isServer, false) < 0)
+        return NULL;
+
+    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);
+        ret = gnutls_x509_crt_get_dn(cert, dname, &dnamesize);
+    }
+    if (ret != 0) {
+        virReportError(VIR_ERR_SYSTEM_ERROR,
+                       _("Failed to get certificate %1$s distinguished name: %2$s"),
+                       "[session]", gnutls_strerror(ret));
+        return NULL;
+    }
+
+    VIR_DEBUG("Peer DN is %s", dname);
+
+    if (virNetTLSContextCheckCertDN(cert, "[session]", hostname,
+                                    dname, x509dnACL) < 0)
+        return NULL;
+
+    /* !isServer, since on the client, we're validating the
+     * server's cert, and on the server, the client's cert
+     */
+    if (virNetTLSContextCheckCertBasicConstraints(cert, "[session]",
+                                                  !isServer, false) < 0)
+        return NULL;
+
+    if (virNetTLSContextCheckCertKeyUsage(cert, "[session]",
+                                          false) < 0)
+        return NULL;
+
+    /* !isServer - as above */
+    if (virNetTLSContextCheckCertKeyPurpose(cert, "[session]",
+                                            !isServer) < 0)
+        return NULL;
+
+    return g_steal_pointer(&dname);
+}
 
 static int virNetTLSContextValidCertificate(virNetTLSContext *ctxt,
                                             virNetTLSSession *sess)
@@ -945,57 +1004,21 @@ static int virNetTLSContextValidCertificate(virNetTLSContext *ctxt,
             goto authfail;
         }
 
-        if (virNetTLSContextCheckCertTimes(cert, "[session]",
-                                           sess->isServer, i > 0) < 0) {
-            gnutls_x509_crt_deinit(cert);
-            goto authdeny;
-        }
-
         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 %1$s distinguished name: %2$s"),
-                               "[session]", gnutls_strerror(ret));
-                goto authfail;
-            }
-            sess->x509dname = g_steal_pointer(&dname);
-            VIR_DEBUG("Peer DN is %s", dnameptr);
-
-            if (virNetTLSContextCheckCertDN(cert, "[session]", sess->hostname,
-                                            dnameptr, ctxt->x509dnACL) < 0) {
-                gnutls_x509_crt_deinit(cert);
-                goto authdeny;
-            }
-
-            /* !sess->isServer, since on the client, we're validating the
-             * server's cert, and on the server, the client's cert
-             */
-            if (virNetTLSContextCheckCertBasicConstraints(cert, "[session]",
-                                                          !sess->isServer, false) < 0) {
-                gnutls_x509_crt_deinit(cert);
-                goto authdeny;
-            }
-
-            if (virNetTLSContextCheckCertKeyUsage(cert, "[session]",
-                                                  false) < 0) {
+            if (!(sess->x509dname = virNetTLSContextCertValidate(cert,
+                                                                 sess->isServer,
+                                                                 sess->hostname,
+                                                                 ctxt->x509dnACL))) {
                 gnutls_x509_crt_deinit(cert);
                 goto authdeny;
             }
-
-            /* !sess->isServer - as above */
-            if (virNetTLSContextCheckCertKeyPurpose(cert, "[session]",
-                                                    !sess->isServer) < 0) {
+        } else {
+            if (virNetTLSContextCertValidateCA(cert, sess->isServer) < 0) {
                 gnutls_x509_crt_deinit(cert);
                 goto authdeny;
             }
         }
+
         gnutls_x509_crt_deinit(cert);
     }
 
-- 
2.43.0




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux