* property of Apple Inc. and are protected by Federal copyright
* law. Distribution and use rights are outlined in the file "LICENSE.txt"
* which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
+ * missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
if (!common_name)
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No common name specified."), 1);
return (HTTP_TRUST_UNKNOWN);
+ }
if ((cert = http_gnutls_create_credential((http_credential_t *)cupsArrayFirst(credentials))) == NULL)
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to create credentials from array."), 1);
return (HTTP_TRUST_UNKNOWN);
+ }
if (cg->any_root < 0)
{
* Do not trust certificates on first use...
*/
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Trust on first use is disabled."), 1);
+
trust = HTTP_TRUST_INVALID;
}
- else if (httpCredentialsGetExpiration(credentials) <= httpCredentialsGetExpiration(tcreds) || !httpCredentialsAreValidForName(credentials, common_name))
+ else if (httpCredentialsGetExpiration(credentials) <= httpCredentialsGetExpiration(tcreds))
{
/*
- * Either the new credentials are not newly issued, or the common name
- * does not match the issued certificate...
+ * The new credentials are not newly issued...
*/
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("New credentials are older than stored credentials."), 1);
+
+ trust = HTTP_TRUST_INVALID;
+ }
+ else if (!httpCredentialsAreValidForName(credentials, common_name))
+ {
+ /*
+ * The common name does not match the issued certificate...
+ */
+
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("New credentials are not valid for name."), 1);
+
trust = HTTP_TRUST_INVALID;
}
else if (httpCredentialsGetExpiration(tcreds) < time(NULL))
httpFreeCredentials(tcreds);
}
else if (cg->validate_certs && !httpCredentialsAreValidForName(credentials, common_name))
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No stored credentials, not valid for name."), 1);
trust = HTTP_TRUST_INVALID;
+ }
+ else if (!cg->trust_first)
+ {
+ /*
+ * See if we have a site CA certificate we can compare...
+ */
+
+ if (!httpLoadCredentials(NULL, &tcreds, "site"))
+ {
+ if (cupsArrayCount(credentials) != (cupsArrayCount(tcreds) + 1))
+ {
+ /*
+ * Certificate isn't directly generated from the CA cert...
+ */
+
+ trust = HTTP_TRUST_INVALID;
+ }
+ else
+ {
+ /*
+ * Do a tail comparison of the two certificates...
+ */
+
+ http_credential_t *a, *b; /* Certificates */
+
+ for (a = (http_credential_t *)cupsArrayFirst(tcreds), b = (http_credential_t *)cupsArrayIndex(credentials, 1);
+ a && b;
+ a = (http_credential_t *)cupsArrayNext(tcreds), b = (http_credential_t *)cupsArrayNext(credentials))
+ if (a->datalen != b->datalen || memcmp(a->data, b->data, a->datalen))
+ break;
+
+ if (a || b)
+ trust = HTTP_TRUST_INVALID;
+ }
+
+ if (trust != HTTP_TRUST_OK)
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Credentials do not validate against site CA certificate."), 1);
+ }
+ else
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Trust on first use is disabled."), 1);
+ trust = HTTP_TRUST_INVALID;
+ }
+ }
if (trust == HTTP_TRUST_OK && !cg->expired_certs)
{
time(&curtime);
if (curtime < gnutls_x509_crt_get_activation_time(cert) ||
curtime > gnutls_x509_crt_get_expiration_time(cert))
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Credentials have expired."), 1);
trust = HTTP_TRUST_EXPIRED;
+ }
}
if (trust == HTTP_TRUST_OK && !cg->any_root && cupsArrayCount(credentials) == 1)
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Self-signed credentials are blocked."), 1);
trust = HTTP_TRUST_INVALID;
+ }
gnutls_x509_crt_deinit(cert);
if (hostname[0])
{
/*
- * First look for CA certs...
+ * First look in the CUPS keystore...
*/
- snprintf(crtfile, sizeof(crtfile), "/etc/letsencrypt/live/%s/fullchain.pem", hostname);
- snprintf(keyfile, sizeof(keyfile), "/etc/letsencrypt/live/%s/privkey.pem", hostname);
-
- if ((access(crtfile, R_OK) || access(keyfile, R_OK)) && (hostptr = strchr(hostname, '.')) != NULL)
- {
- /*
- * Try just domain name...
- */
-
- hostptr ++;
- if (strchr(hostptr, '.'))
- {
- snprintf(crtfile, sizeof(crtfile), "/etc/letsencrypt/live/%s/fullchain.pem", hostptr);
- snprintf(keyfile, sizeof(keyfile), "/etc/letsencrypt/live/%s/privkey.pem", hostptr);
- }
- }
+ http_gnutls_make_path(crtfile, sizeof(crtfile), tls_keypath, hostname, "crt");
+ http_gnutls_make_path(keyfile, sizeof(keyfile), tls_keypath, hostname, "key");
if (access(crtfile, R_OK) || access(keyfile, R_OK))
{
/*
- * Then look in the CUPS keystore...
- */
-
- http_gnutls_make_path(crtfile, sizeof(crtfile), tls_keypath, hostname, "crt");
- http_gnutls_make_path(keyfile, sizeof(keyfile), tls_keypath, hostname, "key");
+ * No CUPS-managed certs, look for CA certs...
+ */
+
+ char cacrtfile[1024], cakeyfile[1024]; /* CA cert files */
+
+ snprintf(cacrtfile, sizeof(cacrtfile), "/etc/letsencrypt/live/%s/fullchain.pem", hostname);
+ snprintf(cakeyfile, sizeof(cakeyfile), "/etc/letsencrypt/live/%s/privkey.pem", hostname);
+
+ if ((access(cacrtfile, R_OK) || access(cakeyfile, R_OK)) && (hostptr = strchr(hostname, '.')) != NULL)
+ {
+ /*
+ * Try just domain name...
+ */
+
+ hostptr ++;
+ if (strchr(hostptr, '.'))
+ {
+ snprintf(cacrtfile, sizeof(cacrtfile), "/etc/letsencrypt/live/%s/fullchain.pem", hostptr);
+ snprintf(cakeyfile, sizeof(cakeyfile), "/etc/letsencrypt/live/%s/privkey.pem", hostptr);
+ }
+ }
+
+ if (!access(cacrtfile, R_OK) && !access(cakeyfile, R_OK))
+ {
+ /*
+ * Use the CA certs...
+ */
+
+ strlcpy(crtfile, cacrtfile, sizeof(crtfile));
+ strlcpy(keyfile, cakeyfile, sizeof(keyfile));
+ }
}
have_creds = !access(crtfile, R_OK) && !access(keyfile, R_OK);
else if (tls_common_name)
{
/*
- * First look for CA certs...
+ * First look in the CUPS keystore...
*/
- snprintf(crtfile, sizeof(crtfile), "/etc/letsencrypt/live/%s/fullchain.pem", tls_common_name);
- snprintf(keyfile, sizeof(keyfile), "/etc/letsencrypt/live/%s/privkey.pem", tls_common_name);
-
- if ((access(crtfile, R_OK) || access(keyfile, R_OK)) && (hostptr = strchr(tls_common_name, '.')) != NULL)
- {
- /*
- * Try just domain name...
- */
-
- hostptr ++;
- if (strchr(hostptr, '.'))
- {
- snprintf(crtfile, sizeof(crtfile), "/etc/letsencrypt/live/%s/fullchain.pem", hostptr);
- snprintf(keyfile, sizeof(keyfile), "/etc/letsencrypt/live/%s/privkey.pem", hostptr);
- }
- }
+ http_gnutls_make_path(crtfile, sizeof(crtfile), tls_keypath, tls_common_name, "crt");
+ http_gnutls_make_path(keyfile, sizeof(keyfile), tls_keypath, tls_common_name, "key");
if (access(crtfile, R_OK) || access(keyfile, R_OK))
{
/*
- * Then look in the CUPS keystore...
- */
-
- http_gnutls_make_path(crtfile, sizeof(crtfile), tls_keypath, tls_common_name, "crt");
- http_gnutls_make_path(keyfile, sizeof(keyfile), tls_keypath, tls_common_name, "key");
+ * No CUPS-managed certs, look for CA certs...
+ */
+
+ char cacrtfile[1024], cakeyfile[1024]; /* CA cert files */
+
+ snprintf(cacrtfile, sizeof(cacrtfile), "/etc/letsencrypt/live/%s/fullchain.pem", tls_common_name);
+ snprintf(cakeyfile, sizeof(cakeyfile), "/etc/letsencrypt/live/%s/privkey.pem", tls_common_name);
+
+ if ((access(cacrtfile, R_OK) || access(cakeyfile, R_OK)) && (hostptr = strchr(tls_common_name, '.')) != NULL)
+ {
+ /*
+ * Try just domain name...
+ */
+
+ hostptr ++;
+ if (strchr(hostptr, '.'))
+ {
+ snprintf(cacrtfile, sizeof(cacrtfile), "/etc/letsencrypt/live/%s/fullchain.pem", hostptr);
+ snprintf(cakeyfile, sizeof(cakeyfile), "/etc/letsencrypt/live/%s/privkey.pem", hostptr);
+ }
+ }
+
+ if (!access(cacrtfile, R_OK) && !access(cakeyfile, R_OK))
+ {
+ /*
+ * Use the CA certs...
+ */
+
+ strlcpy(crtfile, cacrtfile, sizeof(crtfile));
+ strlcpy(keyfile, cakeyfile, sizeof(keyfile));
+ }
}
have_creds = !access(crtfile, R_OK) && !access(keyfile, R_OK);