]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ssl/ErrorDetail.cc
Use ERR_ACCESS_DENIED for HTTP 403 (Forbidden) errors (#1899)
[thirdparty/squid.git] / src / ssl / ErrorDetail.cc
CommitLineData
bbc27441 1/*
b8ae064d 2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
bbc27441
AJ
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
582c2af2 9#include "squid.h"
02259ff8 10#include "errorpage.h"
ed6e9fb9 11#include "fatal.h"
4e143970 12#include "sbuf/SBuf.h"
4d16918e 13#include "ssl/ErrorDetail.h"
83b053a0 14#include "ssl/ErrorDetailManager.h"
074d6a40 15
074d6a40 16#include <map>
4d16918e 17
645deacc
CT
18static const char *OptionalSslErrors[] = {
19 "X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER",
20 "X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION",
21 "X509_V_ERR_KEYUSAGE_NO_CRL_SIGN",
22 "X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION",
23 "X509_V_ERR_INVALID_NON_CA",
24 "X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED",
25 "X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE",
26 "X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED",
27 "X509_V_ERR_INVALID_EXTENSION",
28 "X509_V_ERR_INVALID_POLICY_EXTENSION",
29 "X509_V_ERR_NO_EXPLICIT_POLICY",
30 "X509_V_ERR_DIFFERENT_CRL_SCOPE",
31 "X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE",
32 "X509_V_ERR_UNNESTED_RESOURCE",
33 "X509_V_ERR_PERMITTED_VIOLATION",
34 "X509_V_ERR_EXCLUDED_VIOLATION",
35 "X509_V_ERR_SUBTREE_MINMAX",
36 "X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE",
37 "X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX",
38 "X509_V_ERR_UNSUPPORTED_NAME_SYNTAX",
39 "X509_V_ERR_CRL_PATH_VALIDATION_ERROR",
1dcb1d49
CT
40 "X509_V_ERR_PATH_LOOP",
41 "X509_V_ERR_SUITE_B_INVALID_VERSION",
42 "X509_V_ERR_SUITE_B_INVALID_ALGORITHM",
43 "X509_V_ERR_SUITE_B_INVALID_CURVE",
44 "X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM",
45 "X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED",
46 "X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256",
47 "X509_V_ERR_HOSTNAME_MISMATCH",
48 "X509_V_ERR_EMAIL_MISMATCH",
49 "X509_V_ERR_IP_ADDRESS_MISMATCH",
50 "X509_V_ERR_DANE_NO_MATCH",
51 "X509_V_ERR_EE_KEY_TOO_SMALL",
52 "X509_V_ERR_CA_KEY_TOO_SMALL",
53 "X509_V_ERR_CA_MD_TOO_WEAK",
54 "X509_V_ERR_INVALID_CALL",
55 "X509_V_ERR_STORE_LOOKUP",
56 "X509_V_ERR_NO_VALID_SCTS",
57 "X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION",
58 "X509_V_ERR_OCSP_VERIFY_NEEDED",
59 "X509_V_ERR_OCSP_VERIFY_FAILED",
60 "X509_V_ERR_OCSP_CERT_UNKNOWN",
aee3523a 61 nullptr
645deacc
CT
62};
63
cf1c09f6
CT
64struct SslErrorAlias {
65 const char *name;
13cd7dee 66 const Security::ErrorCode *errors;
cf1c09f6
CT
67};
68
13cd7dee
AJ
69static const Security::ErrorCode hasExpired[] = {X509_V_ERR_CERT_HAS_EXPIRED, SSL_ERROR_NONE};
70static const Security::ErrorCode notYetValid[] = {X509_V_ERR_CERT_NOT_YET_VALID, SSL_ERROR_NONE};
71static const Security::ErrorCode domainMismatch[] = {SQUID_X509_V_ERR_DOMAIN_MISMATCH, SSL_ERROR_NONE};
72static const Security::ErrorCode certUntrusted[] = {X509_V_ERR_INVALID_CA,
83317b32
SM
73 X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN,
74 X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE,
75 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT,
76 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
77 X509_V_ERR_CERT_UNTRUSTED, SSL_ERROR_NONE
78 };
13cd7dee 79static const Security::ErrorCode certSelfSigned[] = {X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT, SSL_ERROR_NONE};
cf1c09f6
CT
80
81// The list of error name shortcuts for use with ssl_error acls.
82// The keys without the "ssl::" scope prefix allow shorter error
83// names within the SSL options scope. This is easier than
7a957a93 84// carefully stripping the scope prefix in Ssl::ParseErrorString().
cf1c09f6
CT
85static SslErrorAlias TheSslErrorShortcutsArray[] = {
86 {"ssl::certHasExpired", hasExpired},
87 {"certHasExpired", hasExpired},
88 {"ssl::certNotYetValid", notYetValid},
89 {"certNotYetValid", notYetValid},
90 {"ssl::certDomainMismatch", domainMismatch},
91 {"certDomainMismatch", domainMismatch},
92 {"ssl::certUntrusted", certUntrusted},
93 {"certUntrusted", certUntrusted},
94 {"ssl::certSelfSigned", certSelfSigned},
95 {"certSelfSigned", certSelfSigned},
aee3523a 96 {nullptr, nullptr}
cf1c09f6
CT
97};
98
7a957a93 99// Use std::map to optimize search.
13cd7dee 100typedef std::map<std::string, const Security::ErrorCode *> SslErrorShortcuts;
cf1c09f6
CT
101SslErrorShortcuts TheSslErrorShortcuts;
102
cf1c09f6
CT
103static void loadSslErrorShortcutsMap()
104{
105 assert(TheSslErrorShortcuts.empty());
a38ec4b1 106 for (int i = 0; TheSslErrorShortcutsArray[i].name; ++i)
cf1c09f6
CT
107 TheSslErrorShortcuts[TheSslErrorShortcutsArray[i].name] = TheSslErrorShortcutsArray[i].errors;
108}
109
83f8d8f9
AJ
110bool
111Ssl::ParseErrorString(const char *name, Security::Errors &errors)
4d16918e
CT
112{
113 assert(name);
114
13cd7dee 115 const Security::ErrorCode ssl_error = GetErrorCode(name);
83f8d8f9
AJ
116 if (ssl_error != SSL_ERROR_NONE) {
117 errors.emplace(ssl_error);
118 return true;
119 }
4d16918e
CT
120
121 if (xisdigit(*name)) {
aee3523a 122 const long int value = strtol(name, nullptr, 0);
83b053a0
CT
123 if ((SQUID_TLS_ERR_OFFSET < value && value < SQUID_TLS_ERR_END) || // custom
124 (value >= 0)) { // an official error, including SSL_ERROR_NONE
83f8d8f9
AJ
125 errors.emplace(value);
126 return true;
127 }
128 fatalf("Too small or too big TLS error code '%s'", name);
4d16918e
CT
129 }
130
cf1c09f6
CT
131 if (TheSslErrorShortcuts.empty())
132 loadSslErrorShortcutsMap();
133
134 const SslErrorShortcuts::const_iterator it = TheSslErrorShortcuts.find(name);
135 if (it != TheSslErrorShortcuts.end()) {
136 // Should not be empty...
87f237a9 137 assert(it->second[0] != SSL_ERROR_NONE);
83f8d8f9
AJ
138 for (int i = 0; it->second[i] != SSL_ERROR_NONE; ++i) {
139 errors.emplace(it->second[i]);
cf1c09f6 140 }
83f8d8f9 141 return true;
cf1c09f6
CT
142 }
143
83f8d8f9
AJ
144 fatalf("Unknown TLS error name '%s'", name);
145 return false; // not reached
4d16918e
CT
146}
147
645deacc
CT
148bool
149Ssl::ErrorIsOptional(const char *name)
150{
aee3523a 151 for (int i = 0; OptionalSslErrors[i] != nullptr; ++i) {
645deacc
CT
152 if (strcmp(name, OptionalSslErrors[i]) == 0)
153 return true;
154 }
155 return false;
156}
157
4e143970 158std::optional<SBuf>
13cd7dee 159Ssl::GetErrorDescr(Security::ErrorCode value)
cf09bec7 160{
4e143970
FC
161 if (const auto detail = ErrorDetailsManager::GetInstance().findDefaultDetail(value))
162 return detail->descr;
163 return std::nullopt;
cf09bec7
CT
164}
165