]> git.ipfire.org Git - thirdparty/squid.git/blame - src/security/ErrorDetail.h
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / security / ErrorDetail.h
CommitLineData
83b053a0 1/*
f70aedc4 2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
83b053a0
CT
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#ifndef SQUID_SRC_SECURITY_DETAIL_H
10#define SQUID_SRC_SECURITY_DETAIL_H
11
12#include "base/RefCount.h"
13#include "error/Detail.h"
14#include "http/forward.h"
15#include "security/forward.h"
16#include "SquidString.h"
17
18#if USE_OPENSSL
19#include "ssl/ErrorDetailManager.h"
20#endif
21
22namespace Security {
23
24/// Details a TLS-related error. Two kinds of errors can be detailed:
25/// * certificate validation errors (including built-in and helper-driven) and
26/// * TLS logic and I/O errors (detected by Squid or the TLS library).
27///
28/// The following details may be available (only the first one is required):
29/// * for all errors: problem classification (\see ErrorCode)
30/// * for all errors: peer certificate
31/// * for certificate validation errors: the broken certificate
32/// * for certificate validation errors: validation failure reason
33/// * for non-validation errors: TLS library-reported error(s)
34/// * for non-validation errors: system call errno(3)
35class ErrorDetail: public ::ErrorDetail
36{
37 MEMPROXY_CLASS(Security::ErrorDetail);
38
39public:
40 typedef ErrorDetailPointer Pointer;
41
42 /// Details a server-side certificate verification failure.
43 /// If `broken` is nil, then the broken certificate is the peer certificate.
44 ErrorDetail(ErrorCode err_no, const CertPointer &peer, const CertPointer &broken, const char *aReason = NULL);
45
46#if USE_OPENSSL
47 /// Details (or starts detailing) a non-validation failure.
48 /// \param anIoErrorNo TLS I/O function outcome; \see ErrorDetail::ioErrorNo
49 /// \param aSysErrorNo saved errno(3); \see ErrorDetail::sysErrorNo
50 ErrorDetail(ErrorCode anErrorCode, int anIoErrorNo, int aSysErrorNo);
51#elif USE_GNUTLS
52 /// Details (or starts detailing) a non-validation failure.
53 /// \param anLibErrorNo TLS function outcome; \see ErrorDetail::lib_error_no
54 /// \param aSysErrorNo saved errno(3); \see ErrorDetail::sysErrorNo
55 ErrorDetail(ErrorCode anErrorCode, LibErrorCode aLibErrorNo, int aSysErrorNo);
56#endif
57
83b053a0
CT
58 /* ErrorDetail API */
59 virtual SBuf brief() const;
60 virtual SBuf verbose(const HttpRequestPointer &) const;
61
62 /// \returns error category; \see ErrorCode
63 ErrorCode errorNo() const { return error_no; }
64
65 /// \returns the previously saved errno(3) or zero
66 int sysError() const { return sysErrorNo; }
67
68 /* Certificate manipulation API. TODO: Add GnuTLS implementations, users. */
69
70 /// the peer certificate (or nil)
71 Certificate *peerCert() { return peer_cert.get(); }
72
73 /// peer or intermediate certificate that failed validation (or nil)
74 Certificate *brokenCert() {return broken_cert.get(); }
75
76 /// remember the SSL certificate of our peer; requires nil peerCert()
77 /// unlike the cert-setting constructor, does not assume the cert is bad
78 void setPeerCertificate(const CertPointer &);
79
80private:
81 ErrorDetail(ErrorCode err, int aSysErrorNo);
82
83 /* methods for formatting error details using admin-configurable %codes */
84 const char *subject() const;
85 const char *ca_name() const;
86 const char *cn() const;
87 const char *notbefore() const;
88 const char *notafter() const;
89 const char *err_code() const;
90 const char *err_descr() const;
91 const char *err_lib_error() const;
92 size_t convert(const char *code, const char **value) const;
93
83b053a0
CT
94 CertPointer peer_cert; ///< A pointer to the peer certificate
95 CertPointer broken_cert; ///< A pointer to the broken certificate (peer or intermediate)
96
97 /// Squid-discovered error, validation error, or zero; \see ErrorCode
98 ErrorCode error_no = 0;
99
100 /// TLS library-reported non-validation error or zero; \see LibErrorCode
101 LibErrorCode lib_error_no = 0;
102
103 /// errno(3); system call failure code or zero
104 int sysErrorNo = 0;
105
106#if USE_OPENSSL
107 /// OpenSSL-specific (first-level or intermediate) TLS I/O operation result
108 /// reported by SSL_get_error(3SSL) (e.g., SSL_ERROR_SYSCALL) or zero.
109 /// Unlike lib_error_no, this error is mostly meant for I/O control and has
110 /// no OpenSSL-provided human-friendly text representation.
111 int ioErrorNo = 0;
112
113 using ErrorDetailEntry = Ssl::ErrorDetailEntry;
114 mutable ErrorDetailEntry detailEntry;
115#else
116 // other TLS libraries do not use custom ErrorDetail members
117#endif
118
119 String errReason; ///< a custom reason for the error
120};
121
122/// \returns ErrorCode with a given name (or zero)
123ErrorCode ErrorCodeFromName(const char *name);
124
125/// \returns string representation of ErrorCode, including raw X.509 error codes
126/// \param prefixRawCode whether to prefix raw codes with "SSL_ERR="
127const char *ErrorNameFromCode(ErrorCode err, bool prefixRawCode = false);
128
129}
130
131#endif
132