]>
Commit | Line | Data |
---|---|---|
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 | ||
22 | namespace 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) | |
35 | class ErrorDetail: public ::ErrorDetail | |
36 | { | |
37 | MEMPROXY_CLASS(Security::ErrorDetail); | |
38 | ||
39 | public: | |
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 | ||
80 | private: | |
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) | |
123 | ErrorCode 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=" | |
127 | const char *ErrorNameFromCode(ErrorCode err, bool prefixRawCode = false); | |
128 | ||
129 | } | |
130 | ||
131 | #endif | |
132 |