From bbd2f70ab542300d572c374c7048b97a5d271044 Mon Sep 17 00:00:00 2001 From: Michael R Sweet Date: Thu, 17 Oct 2024 20:07:18 -0400 Subject: [PATCH] Mirror X.509 updates from libcups v3: - cupsCreateCredentialsRequest now stores the new private key separately - cupsSaveCredentials now uses the CSR private key when saving just the new certificate - cupsSaveCredentials now does some sanity checks on the input values. - cupsSaveCredentials now supports credential removal as documented. --- cups/tls-gnutls.c | 2 +- cups/tls-openssl.c | 2 +- cups/tls.c | 55 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/cups/tls-gnutls.c b/cups/tls-gnutls.c index 2e85be805..a27a51ee3 100644 --- a/cups/tls-gnutls.c +++ b/cups/tls-gnutls.c @@ -525,7 +525,7 @@ cupsCreateCredentialsRequest( } http_make_path(csrfile, sizeof(csrfile), path, common_name, "csr"); - http_make_path(keyfile, sizeof(keyfile), path, common_name, "key"); + http_make_path(keyfile, sizeof(keyfile), path, common_name, "ktm"); // Create the encryption key... DEBUG_puts("1cupsCreateCredentialsRequest: Creating key pair."); diff --git a/cups/tls-openssl.c b/cups/tls-openssl.c index 6158dc24b..26884c89d 100644 --- a/cups/tls-openssl.c +++ b/cups/tls-openssl.c @@ -510,7 +510,7 @@ cupsCreateCredentialsRequest( } http_make_path(csrfile, sizeof(csrfile), path, common_name, "csr"); - http_make_path(keyfile, sizeof(keyfile), path, common_name, "key"); + http_make_path(keyfile, sizeof(keyfile), path, common_name, "ktm"); // Create the encryption key... DEBUG_puts("1cupsCreateCredentialsRequest: Creating key pair."); diff --git a/cups/tls.c b/cups/tls.c index bfec2b37d..6f2d1aef7 100644 --- a/cups/tls.c +++ b/cups/tls.c @@ -130,15 +130,62 @@ cupsSaveCredentials( const char *credentials, // I - PEM-encoded certificate chain or `NULL` to remove const char *key) // I - PEM-encoded private key or `NULL` for none { - if (http_save_file(path, common_name, "crt", credentials)) + bool ret = false; // Return value + char crtfile[1024], // Certificate filename + keyfile[1024], // Key filename + ktmfile[1024]; // Temporary key filename + + + // Validate input... + if (credentials) + { + // Make sure it looks like a PEM-encoded cert... + if (strncmp(credentials, "-----BEGIN CERTIFICATE-----", 27) || strstr(key, "-----END CERTIFICATE-----") == NULL) + return (false); + } + + if (key) { + // Make sure it looks like a PEM-encoded private key... + if (strncmp(key, "-----BEGIN PRIVATE KEY-----", 27) || strstr(key, "-----END PRIVATE KEY-----") == NULL) + return (false); + } + + // Save or delete credentials... + http_make_path(crtfile, sizeof(crtfile), path, common_name, "crt"); + http_make_path(keyfile, sizeof(keyfile), path, common_name, "key"); + http_make_path(ktmfile, sizeof(ktmfile), path, common_name, "ktm"); + + if (!credentials && !key) + { + // Delete credentials... + if (!unlink(crtfile) && !unlink(keyfile)) + ret = true; + else + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), false); + } + else if (!credentials && key) + { + // Bad arguments... + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), false); + } + else if (!key && access(keyfile, 0) && access(ktmfile, 0)) + { + // Missing key file... + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), false); + } + else if (http_save_file(path, common_name, "crt", credentials)) + { + // Certificate saved, save or rename key file as needed... if (key) - return (http_save_file(path, common_name, "key", key)); + ret = http_save_file(path, common_name, "key", key); + else if (!access(ktmfile, 0)) + ret = !rename(ktmfile, keyfile); else - return (true); + ret = true; } - return (false); + return (ret); }