ErrorDetail.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
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 
9 #include "squid.h"
10 #include "errorpage.h"
11 #include "fatal.h"
12 #include "sbuf/SBuf.h"
13 #include "ssl/ErrorDetail.h"
14 #include "ssl/ErrorDetailManager.h"
15 
16 #include <map>
17 
18 static 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",
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",
61  nullptr
62 };
63 
64 struct SslErrorAlias {
65  const char *name;
67 };
68 
69 static const Security::ErrorCode hasExpired[] = {X509_V_ERR_CERT_HAS_EXPIRED, SSL_ERROR_NONE};
70 static const Security::ErrorCode notYetValid[] = {X509_V_ERR_CERT_NOT_YET_VALID, SSL_ERROR_NONE};
72 static const Security::ErrorCode certUntrusted[] = {X509_V_ERR_INVALID_CA,
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  };
79 static const Security::ErrorCode certSelfSigned[] = {X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT, SSL_ERROR_NONE};
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
84 // carefully stripping the scope prefix in Ssl::ParseErrorString().
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},
96  {nullptr, nullptr}
97 };
98 
99 // Use std::map to optimize search.
100 typedef std::map<std::string, const Security::ErrorCode *> SslErrorShortcuts;
102 
104 {
105  assert(TheSslErrorShortcuts.empty());
106  for (int i = 0; TheSslErrorShortcutsArray[i].name; ++i)
108 }
109 
110 bool
111 Ssl::ParseErrorString(const char *name, Security::Errors &errors)
112 {
113  assert(name);
114 
115  const Security::ErrorCode ssl_error = GetErrorCode(name);
116  if (ssl_error != SSL_ERROR_NONE) {
117  errors.emplace(ssl_error);
118  return true;
119  }
120 
121  if (xisdigit(*name)) {
122  const long int value = strtol(name, nullptr, 0);
123  if ((SQUID_TLS_ERR_OFFSET < value && value < SQUID_TLS_ERR_END) || // custom
124  (value >= 0)) { // an official error, including SSL_ERROR_NONE
125  errors.emplace(value);
126  return true;
127  }
128  fatalf("Too small or too big TLS error code '%s'", name);
129  }
130 
131  if (TheSslErrorShortcuts.empty())
133 
134  const SslErrorShortcuts::const_iterator it = TheSslErrorShortcuts.find(name);
135  if (it != TheSslErrorShortcuts.end()) {
136  // Should not be empty...
137  assert(it->second[0] != SSL_ERROR_NONE);
138  for (int i = 0; it->second[i] != SSL_ERROR_NONE; ++i) {
139  errors.emplace(it->second[i]);
140  }
141  return true;
142  }
143 
144  fatalf("Unknown TLS error name '%s'", name);
145  return false; // not reached
146 }
147 
148 bool
149 Ssl::ErrorIsOptional(const char *name)
150 {
151  for (int i = 0; OptionalSslErrors[i] != nullptr; ++i) {
152  if (strcmp(name, OptionalSslErrors[i]) == 0)
153  return true;
154  }
155  return false;
156 }
157 
158 std::optional<SBuf>
160 {
161  if (const auto detail = ErrorDetailsManager::GetInstance().findDefaultDetail(value))
162  return detail->descr;
163  return std::nullopt;
164 }
165 
int ErrorCode
Squid-defined error code (<0), an error code returned by X.509 API, or zero.
Definition: forward.h:131
std::map< std::string, const Security::ErrorCode * > SslErrorShortcuts
Definition: ErrorDetail.cc:100
std::optional< SBuf > GetErrorDescr(Security::ErrorCode)
Definition: ErrorDetail.cc:159
@ SQUID_X509_V_ERR_DOMAIN_MISMATCH
Definition: forward.h:238
static SslErrorAlias TheSslErrorShortcutsArray[]
Definition: ErrorDetail.cc:85
const char * name
Definition: ErrorDetail.cc:65
static const char * OptionalSslErrors[]
Definition: ErrorDetail.cc:18
bool ParseErrorString(const char *name, Security::Errors &)
Definition: ErrorDetail.cc:111
const Security::ErrorCode * errors
Definition: ErrorDetail.cc:66
#define assert(EX)
Definition: assert.h:17
static void loadSslErrorShortcutsMap()
Definition: ErrorDetail.cc:103
void fatalf(const char *fmt,...)
Definition: fatal.cc:68
#define xisdigit(x)
Definition: xis.h:18
static const Security::ErrorCode certSelfSigned[]
Definition: ErrorDetail.cc:79
static const Security::ErrorCode hasExpired[]
Definition: ErrorDetail.cc:69
Security::ErrorCode GetErrorCode(const char *name)
The Security::ErrorCode code of the error described by "name".
Definition: ErrorDetail.h:30
SslErrorShortcuts TheSslErrorShortcuts
Definition: ErrorDetail.cc:101
static const Security::ErrorCode domainMismatch[]
Definition: ErrorDetail.cc:71
@ SQUID_TLS_ERR_END
Definition: forward.h:241
static const Security::ErrorCode notYetValid[]
Definition: ErrorDetail.cc:70
@ SQUID_TLS_ERR_OFFSET
Definition: forward.h:230
static const Security::ErrorCode certUntrusted[]
Definition: ErrorDetail.cc:72
std::unordered_set< Security::ErrorCode > Errors
Definition: forward.h:165
bool ErrorIsOptional(const char *name)
Definition: ErrorDetail.cc:149

 

Introduction

Documentation

Support

Miscellaneous