]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Mirror GNU TLS fixes from libcups v3.
authorMichael R Sweet <msweet@msweet.org>
Tue, 18 Jun 2024 23:28:05 +0000 (19:28 -0400)
committerMichael R Sweet <msweet@msweet.org>
Tue, 18 Jun 2024 23:28:05 +0000 (19:28 -0400)
cups/tls-gnutls.c
cups/tls.c

index 65e07b58ffed70def2d2f540d16d288ae5a6cd09..7f3f59f35367008031f5b2e61475a93599b8649c 100644 (file)
@@ -1338,14 +1338,20 @@ httpCopyPeerCredentials(http_t *http)   // I - HTTP connection
       while (count > 0)
       {
        // Expand credentials string...
-       if ((credentials = realloc(credentials, alloc_creds + (size_t)certs->size + 1)) != NULL)
+       char *pem = http_der_to_pem(certs->data, certs->size);
+                                       // PEM-encoded certificate
+       size_t  pemsize;                // Length of PEM-encoded certificate
+
+       if (pem && (credentials = realloc(credentials, alloc_creds + (pemsize = strlen(pem)) + 1)) != NULL)
        {
          // Copy PEM-encoded data...
-         memcpy(credentials + alloc_creds, certs->data, certs->size);
-         credentials[alloc_creds + (size_t)certs->size] = '\0';
-         alloc_creds += (size_t)certs->size;
+         memcpy(credentials + alloc_creds, pem, pemsize);
+         credentials[alloc_creds + pemsize] = '\0';
+         alloc_creds += pemsize;
        }
 
+        free(pem);
+
         certs ++;
         count --;
       }
@@ -1375,9 +1381,6 @@ _httpCreateCredentials(
 
   DEBUG_printf("_httpCreateCredentials(credentials=\"%s\", key=\"%s\")", credentials, key);
 
-  if (!credentials || !*credentials || !key || !*key)
-    return (NULL);
-
   if ((hcreds = calloc(1, sizeof(_http_tls_credentials_t))) == NULL)
     return (NULL);
 
@@ -1390,18 +1393,21 @@ _httpCreateCredentials(
 
   hcreds->use  = 1;
 
-  cdatum.data = (void *)credentials;
-  cdatum.size = strlen(credentials);
-  kdatum.data = (void *)key;
-  kdatum.size = strlen(key);
-
-  if ((err = gnutls_certificate_set_x509_key_mem(hcreds->creds, &cdatum, &kdatum, GNUTLS_X509_FMT_PEM)) < 0)
+  if (credentials && *credentials && key && *key)
   {
-    DEBUG_printf("1_httpCreateCredentials: set_x509_key_mem error: %s", gnutls_strerror(err));
+    cdatum.data = (void *)credentials;
+    cdatum.size = strlen(credentials);
+    kdatum.data = (void *)key;
+    kdatum.size = strlen(key);
 
-    gnutls_certificate_free_credentials(hcreds->creds);
-    free(hcreds);
-    hcreds = NULL;
+    if ((err = gnutls_certificate_set_x509_key_mem(hcreds->creds, &cdatum, &kdatum, GNUTLS_X509_FMT_PEM)) < 0)
+    {
+      DEBUG_printf("1_httpCreateCredentials: set_x509_key_mem error: %s", gnutls_strerror(err));
+
+      gnutls_certificate_free_credentials(hcreds->creds);
+      free(hcreds);
+      hcreds = NULL;
+    }
   }
 
   DEBUG_printf("1_httpCreateCredentials: Returning %p.", hcreds);
@@ -1505,7 +1511,8 @@ _httpTLSStart(http_t *http)               // I - Connection to server
   char                 hostname[256],  // Hostname
                        *hostptr;       // Pointer into hostname
   int                  status;         // Status of handshake
-  _http_tls_credentials_t *credentials;        // TLS credentials
+  _http_tls_credentials_t *credentials = NULL;
+                                       // TLS credentials
   char                 priority_string[2048];
                                        // Priority string
   int                  version;        // Current version
@@ -1581,8 +1588,12 @@ _httpTLSStart(http_t *http)              // I - Connection to server
        *hostptr = '\0';
     }
 
-    status      = gnutls_server_name_set(http->tls, GNUTLS_NAME_DNS, hostname, strlen(hostname));
-    credentials = _httpUseCredentials(cg->tls_credentials);
+    status = gnutls_server_name_set(http->tls, GNUTLS_NAME_DNS, hostname, strlen(hostname));
+    if (!status && (credentials = _httpUseCredentials(cg->tls_credentials)) == NULL)
+    {
+      if ((credentials = _httpCreateCredentials(NULL, NULL)) == NULL)
+        status = -1;
+    }
   }
   else
   {
@@ -2035,13 +2046,15 @@ gnutls_import_certs(
   gnutls_datum_t       datum;          // Data record
 
 
+  DEBUG_printf("3gnutls_import_certs(credentials=\"%s\", num_certs=%p, certs=%p)", credentials, (void *)num_certs, (void *)certs);
+
   // Import all certificates from the string...
   datum.data = (void *)credentials;
   datum.size = strlen(credentials);
 
-  if ((err = gnutls_x509_crt_list_import(certs, num_certs, &datum, GNUTLS_X509_FMT_DER, 0)) < 0)
+  if ((err = gnutls_x509_crt_list_import(certs, num_certs, &datum, GNUTLS_X509_FMT_PEM, 0)) < 0)
   {
-    DEBUG_printf("4gnutls_create_cert: crt_list_import error: %s", gnutls_strerror(err));
+    DEBUG_printf("4gnutls_import_certs: crt_list_import error: %s", gnutls_strerror(err));
     return (NULL);
   }
 
index b80d1cc6786da1a05e56dc9bb7c218df5f7f321e..5e576282a9bbf67c3b70a9cbc3f9b9777c21f830 100644 (file)
@@ -56,9 +56,9 @@ static bool           http_check_roots(const char *creds);
 static char            *http_copy_file(const char *path, const char *common_name, const char *ext);
 static const char      *http_default_path(char *buffer, size_t bufsize);
 static bool            http_default_san_cb(const char *common_name, const char *subject_alt_name, void *data);
-#ifdef _WIN32
+#if defined(_WIN32) || defined(HAVE_GNUTLS)
 static char            *http_der_to_pem(const unsigned char *der, size_t dersize);
-#endif // _WIN32
+#endif // _WIN32 || HAVE_GNUTLS
 static const char      *http_make_path(char *buffer, size_t bufsize, const char *dirname, const char *filename, const char *ext);
 static bool            http_save_file(const char *path, const char *common_name, const char *ext, const char *value);
 
@@ -384,6 +384,8 @@ http_check_roots(const char *creds) // I - Credentials
   // Check all roots
   credslen = strlen(creds);
 
+  DEBUG_printf("4http_check_roots: %lu root certificates to check.", (unsigned long)cupsArrayGetCount(tls_root_certs));
+
   for (rcreds = (const char *)cupsArrayGetFirst(tls_root_certs); rcreds && !ret; rcreds = (const char *)cupsArrayGetNext(tls_root_certs))
   {
     // Compare the root against the tail of the current credentials...
@@ -519,7 +521,7 @@ http_default_san_cb(
 }
 
 
-#ifdef _WIN32
+#if defined(_WIN32) || defined(HAVE_GNUTLS)
 //
 // 'http_der_to_pem()' - Convert DER format certificate data to PEM.
 //
@@ -539,13 +541,13 @@ http_der_to_pem(
 
   // Calculate the size, accounting for Base64 expansion, line wrapping at
   // column 64, and the BEGIN/END CERTIFICATE text...
-  pemsize = 65 * 4 * dersize / 3 / 64 + /*"-----BEGIN CERTIFICATE-----"*/28 + /*"-----END CERTIFICATE-----"*/26 + 2;
+  pemsize = 2 * dersize + /*"-----BEGIN CERTIFICATE-----\n"*/28 + /*"-----END CERTIFICATE-----\n"*/26 + 1;
 
   if ((pem = calloc(1, pemsize)) == NULL)
     return (NULL);
 
   cupsCopyString(pem, "-----BEGIN CERTIFICATE-----\n", pemsize);
-  for (pemptr = pem, col = 0; dersize > 0; der += 3)
+  for (pemptr = pem + strlen(pem), col = 0; dersize > 0; der += 3)
   {
     // Encode the up to 3 characters as 4 Base64 numbers...
     switch (dersize)
@@ -591,7 +593,7 @@ http_der_to_pem(
   // Return the encoded string...
   return (pem);
 }
-#endif // _WIN32
+#endif // _WIN32 || HAVE_GNUTLS
 
 
 //