]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
cups/tls-openssl.c: Use general names in certificates (fixes #652)
authorZdenek Dohnal <zdohnal@redhat.com>
Thu, 13 Apr 2023 08:31:58 +0000 (10:31 +0200)
committerZdenek Dohnal <zdohnal@redhat.com>
Thu, 13 Apr 2023 08:31:58 +0000 (10:31 +0200)
This results into having only one Subject Alternative Name extension,
which fixes SEC_ERROR_EXTENSION_VALUE_INVALID in Firefox.

CHANGES.md
cups/tls-openssl.c

index b0aa9e260f25868a9eefe947b4ba33e77b9959ec..992b8045f627f0bb6e7a92b5c2a90ab9ab7fe359 100644 (file)
@@ -22,6 +22,7 @@ Changes in CUPS v2.4.3 (TBA)
 - Fixed `cupsd` default keychain location when building with OpenSSL
   (Issue #529)
 - Fixed TLS certificate generation bugs.
+- Generate only one SAN extension for certificate via OpenSSL (Issue #652)
 - `ippDeleteValues` would not delete the last value (Issue #556)
 - Ignore some of IPP defaults if the application sends its PPD alternative
   (Issue #484)
index 7c769623b2a7d0c560f275a4cc339beac46e05cf..8f02a3cb71170dbc1241dafe3416333a86316857 100644 (file)
@@ -36,7 +36,7 @@ static time_t         http_get_date(X509 *cert, int which);
 //static void          http_load_crl(void);
 static const char      *http_make_path(char *buffer, size_t bufsize, const char *dirname, const char *filename, const char *ext);
 static int             http_x509_add_ext(X509 *cert, int nid, const char *value);
-static void            http_x509_add_san(X509 *cert, const char *name);
+static void            http_x509_add_san(GENERAL_NAMES *gens, const char *name);
 
 
 /*
@@ -88,7 +88,7 @@ cupsMakeServerCredentials(
                crtfile[1024],          // Certificate filename
                keyfile[1024];          // Private key filename
   const char   *common_ptr;            // Pointer into common name
-
+  GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null(); // Names for SubjectAltName certificate extension
 
   DEBUG_printf(("cupsMakeServerCredentials(path=\"%s\", common_name=\"%s\", num_alt_names=%d, alt_names=%p, expiration_date=%d)", path, common_name, num_alt_names, alt_names, (int)expiration_date));
 
@@ -170,7 +170,7 @@ cupsMakeServerCredentials(
   X509_set_subject_name(cert, name);
   X509_NAME_free(name);
 
-  http_x509_add_san(cert, common_name);
+  http_x509_add_san(gens, common_name);
   if ((common_ptr = strstr(common_name, ".local")) == NULL)
   {
     // Add common_name.local to the list, too...
@@ -182,7 +182,7 @@ cupsMakeServerCredentials(
       *localptr = '\0';
     strlcat(localname, ".local", sizeof(localname));
 
-    http_x509_add_san(cert, localname);
+    http_x509_add_san(gens, localname);
   }
 
   if (num_alt_names > 0)
@@ -192,10 +192,14 @@ cupsMakeServerCredentials(
     for (i = 0; i < num_alt_names; i ++)
     {
       if (strcmp(alt_names[i], "localhost"))
-        http_x509_add_san(cert, alt_names[i]);
+        http_x509_add_san(gens, alt_names[i]);
     }
   }
 
+  // Add extension with dns names and free buffer for GENERAL_NAME
+  X509_add1_ext_i2d(cert, NID_subject_alt_name, gens, 0, X509V3_ADD_DEFAULT);
+  sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+
   // Add extensions that are required to make Chrome happy...
   http_x509_add_ext(cert, NID_basic_constraints, "critical,CA:FALSE,pathlen:0");
   http_x509_add_ext(cert, NID_key_usage, "critical,digitalSignature,keyEncipherment");
@@ -1669,17 +1673,18 @@ http_x509_add_ext(X509       *cert,     // I - Certificate
 
 
 //
-// 'http_x509_add_san()' - Add a subjectAltName extension to an X.509 certificate.
+// 'http_x509_add_san()' - Add a subjectAltName to GENERAL_NAMES used for
+// the extension to an X.509 certificate.
 //
 
 static void
-http_x509_add_san(X509       *cert,    // I - Certificate
-                  const char *name)    // I - Hostname
+http_x509_add_san(GENERAL_NAMES *gens, // I - Concatenation of dns names
+                  const char    *name) // I - Hostname
 {
-  char         dns_name[1024];         // DNS: prefixed hostname
-
 
-  // The subjectAltName value for DNS names starts with a DNS: prefix...
-  snprintf(dns_name, sizeof(dns_name), "DNS:%s", name);
-  http_x509_add_ext(cert, NID_subject_alt_name, dns_name);
+  GENERAL_NAME *gen_dns = GENERAL_NAME_new();
+  ASN1_IA5STRING *ia5 = ASN1_IA5STRING_new();
+  ASN1_STRING_set(ia5, name, strlen(name));
+  GENERAL_NAME_set0_value(gen_dns, GEN_DNS, ia5);
+  sk_GENERAL_NAME_push(gens, gen_dns);
 }