]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ssl/bio.h
Source Format Enforcement (#963)
[thirdparty/squid.git] / src / ssl / bio.h
CommitLineData
bbc27441 1/*
bf95c10a 2 * Copyright (C) 1996-2022 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
b3a8ae1b
AR
9#ifndef SQUID_SSL_BIO_H
10#define SQUID_SSL_BIO_H
11
86f77270
AJ
12#if USE_OPENSSL
13
24b30fdc 14#include "compat/openssl.h"
edb876ab 15#include "FadingCounter.h"
8693472e 16#include "fd.h"
51e09c08 17#include "MemBuf.h"
7c8ee688 18#include "security/Handshake.h"
51e09c08 19#include "ssl/support.h"
8693472e 20
d620ae0e 21#include <iosfwd>
7f4e9b73 22#include <list>
b3a8ae1b
AR
23#if HAVE_OPENSSL_BIO_H
24#include <openssl/bio.h>
25#endif
b3a8ae1b 26#include <string>
2e198b84
AR
27#include <type_traits>
28
e1f72a8b
CT
29namespace Ssl
30{
2e198b84 31
b3a8ae1b 32/// BIO source and sink node, handling socket I/O and monitoring SSL state
e1f72a8b
CT
33class Bio
34{
b3a8ae1b
AR
35public:
36 explicit Bio(const int anFd);
5d65362c 37 virtual ~Bio();
b3a8ae1b 38
d620ae0e
CT
39 /// Writes the given data to socket
40 virtual int write(const char *buf, int size, BIO *table);
41
42 /// Reads data from socket
43 virtual int read(char *buf, int size, BIO *table);
b3a8ae1b 44
d620ae0e
CT
45 /// Flushes any buffered data to socket.
46 /// The Ssl::Bio does not buffer any data, so this method has nothing to do
8b082ed9 47 virtual void flush(BIO *) {}
d620ae0e
CT
48
49 int fd() const { return fd_; } ///< The SSL socket descriptor
b3a8ae1b
AR
50
51 /// Called by linked SSL connection whenever state changes, an alert
52 /// appears, or an error occurs. See SSL_set_info_callback().
d620ae0e 53 virtual void stateChanged(const SSL *ssl, int where, int ret);
b3a8ae1b
AR
54
55 /// Creates a low-level BIO table, creates a high-level Ssl::Bio object
56 /// for a given socket, and then links the two together via BIO_C_SET_FD.
86f77270 57 static BIO *Create(const int fd, Security::Io::Type type);
b3a8ae1b
AR
58 /// Tells ssl connection to use BIO and monitor state via stateChanged()
59 static void Link(SSL *ssl, BIO *bio);
60
d9219c2b 61 const SBuf &rBufData() {return rbuf;} ///< The buffered input data
d620ae0e 62protected:
b3a8ae1b 63 const int fd_; ///< the SSL socket we are reading and writing
91f15461 64 SBuf rbuf; ///< Used to buffer input data.
b3a8ae1b
AR
65};
66
d620ae0e 67/// BIO node to handle socket IO for squid client side
a95989ed
CT
68/// If bumping is enabled this Bio detects and analyses client hello message
69/// to retrieve the SSL features supported by the client
e1f72a8b
CT
70class ClientBio: public Bio
71{
d620ae0e 72public:
edb876ab 73 explicit ClientBio(const int anFd);
d620ae0e
CT
74
75 /// The ClientBio version of the Ssl::Bio::stateChanged method
e1f72a8b 76 /// When the client hello message retrieved, fill the
2f8abb64 77 /// "features" member with the client provided information.
d620ae0e
CT
78 virtual void stateChanged(const SSL *ssl, int where, int ret);
79 /// The ClientBio version of the Ssl::Bio::write method
80 virtual int write(const char *buf, int size, BIO *table);
81 /// The ClientBio version of the Ssl::Bio::read method
82 /// If the holdRead flag is true then it does not write any data
83 /// to socket and sets the "read retry" flag of the BIO to true
84 virtual int read(char *buf, int size, BIO *table);
2f8abb64 85 /// Prevents or allow writing on socket.
d620ae0e 86 void hold(bool h) {holdRead_ = holdWrite_ = h;}
d9219c2b
CT
87
88 /// Sets the buffered input data (Bio::rbuf).
89 /// Used to pass payload data (normally client HELLO data) retrieved
90 /// by the caller.
3cae14a6 91 void setReadBufData(SBuf &data) {rbuf = data;}
d620ae0e 92private:
edb876ab
CT
93 /// approximate size of a time window for computing client-initiated renegotiation rate (in seconds)
94 static const time_t RenegotiationsWindow = 10;
95
96 /// the maximum tolerated number of client-initiated renegotiations in RenegotiationsWindow
97 static const int RenegotiationsLimit = 5;
bcbe37da 98
d620ae0e
CT
99 bool holdRead_; ///< The read hold state of the bio.
100 bool holdWrite_; ///< The write hold state of the bio.
edb876ab
CT
101 FadingCounter renegotiations; ///< client requested renegotiations limit control
102
103 /// why we should terminate the connection during next TLS operation (or nil)
104 const char *abortReason;
d620ae0e
CT
105};
106
107/// BIO node to handle socket IO for squid server side
a95989ed
CT
108/// If bumping is enabled, analyses the SSL hello message sent by squid OpenSSL
109/// subsystem (step3 bumping step) against bumping mode:
110/// * Peek mode: Send client hello message instead of the openSSL generated
2f8abb64 111/// hello message and normally denies bumping and allow only
a95989ed 112/// splice or terminate the SSL connection
2f8abb64 113/// * Stare mode: Sends the openSSL generated hello message and normally
a95989ed
CT
114/// denies splicing and allow bump or terminate the SSL
115/// connection
116/// If SQUID_USE_OPENSSL_HELLO_OVERWRITE_HACK is enabled also checks if the
117/// openSSL library features are compatible with the features reported in
118/// web client SSL hello message and if it is, overwrites the openSSL SSL
119/// object members to replace hello message with web client hello message.
120/// This is may allow bumping in peek mode and splicing in stare mode after
121/// the server hello message received.
e1f72a8b
CT
122class ServerBio: public Bio
123{
d620ae0e 124public:
d20cf186
AR
125 explicit ServerBio(const int anFd);
126
d620ae0e
CT
127 /// The ServerBio version of the Ssl::Bio::stateChanged method
128 virtual void stateChanged(const SSL *ssl, int where, int ret);
129 /// The ServerBio version of the Ssl::Bio::write method
130 /// If a clientRandom number is set then rewrites the raw hello message
131 /// "client random" field with the provided random number.
132 /// It may buffer the output packets.
133 virtual int write(const char *buf, int size, BIO *table);
134 /// The ServerBio version of the Ssl::Bio::read method
135 /// If the record flag is set then append the data to the rbuf member
136 virtual int read(char *buf, int size, BIO *table);
137 /// The ServerBio version of the Ssl::Bio::flush method.
138 /// Flushes any buffered data
139 virtual void flush(BIO *table);
140 /// Sets the random number to use in client SSL HELLO message
21530947 141 void setClientFeatures(Security::TlsDetails::Pointer const &details, SBuf const &hello);
2bcab852 142
89c5ca0f 143 bool resumingSession();
55369ae6 144
cd29a421
CT
145 /// whether the server encrypts its certificate (e.g., TLS v1.3)
146 /// \retval false the server uses plain certs or its intent is unknown
147 bool encryptedCertificates() const;
148
a95989ed 149 /// The write hold state
d620ae0e 150 bool holdWrite() const {return holdWrite_;}
a95989ed 151 /// Enables or disables the write hold state
d620ae0e 152 void holdWrite(bool h) {holdWrite_ = h;}
ffbfd5be
CT
153 /// Enables or disables the input data recording, for internal analysis.
154 void recordInput(bool r) {record_ = r;}
a95989ed 155 /// Whether we can splice or not the SSL stream
7f4e9b73 156 bool canSplice() {return allowSplice;}
a95989ed 157 /// Whether we can bump or not the SSL stream
5d65362c 158 bool canBump() {return allowBump;}
a95989ed 159 /// The bumping mode
5d65362c 160 void mode(Ssl::BumpMode m) {bumpMode_ = m;}
92d867c5 161 Ssl::BumpMode bumpMode() {return bumpMode_;} ///< return the bumping mode
55369ae6 162
4b5ea8a6 163 /// \retval true if the Server hello message received
0bffe3ce 164 bool gotHello() const { return (parsedHandshake && !parseError); }
55369ae6
AR
165
166 /// Return true if the Server Hello parsing failed
0bffe3ce 167 bool gotHelloFailed() const { return (parsedHandshake && parseError); }
55369ae6 168
d9219c2b 169 /// \return the TLS Details advertised by TLS server.
3cae14a6 170 const Security::TlsDetails::Pointer &receivedHelloDetails() const {return parser_.details;}
6821c276 171
d620ae0e 172private:
a465cd53
AR
173 int readAndGive(char *buf, const int size, BIO *table);
174 int readAndParse(char *buf, const int size, BIO *table);
175 int readAndBuffer(BIO *table);
176 int giveBuffered(char *buf, const int size);
177
21530947
CT
178 /// SSL client features extracted from ClientHello message or SSL object
179 Security::TlsDetails::Pointer clientTlsDetails;
180 /// TLS client hello message, used to adapt our tls Hello message to the server
6744c1a8 181 SBuf clientSentHello;
8693472e
CT
182 SBuf helloMsg; ///< Used to buffer output data.
183 mb_size_t helloMsgSize;
d620ae0e 184 bool helloBuild; ///< True if the client hello message sent to the server
a95989ed
CT
185 bool allowSplice; ///< True if the SSL stream can be spliced
186 bool allowBump; ///< True if the SSL stream can be bumped
d620ae0e 187 bool holdWrite_; ///< The write hold state of the bio.
ffbfd5be 188 bool record_; ///< If true the input data recorded to rbuf for internal use
d20cf186 189 bool parsedHandshake; ///< whether we are done parsing TLS Hello
0bffe3ce 190 bool parseError; ///< error while parsing server hello message
5d65362c 191 Ssl::BumpMode bumpMode_;
55369ae6 192
d9219c2b 193 /// The size of data stored in rbuf which passed to the openSSL
55369ae6 194 size_t rbufConsumePos;
d9219c2b 195 Security::HandshakeParser parser_; ///< The TLS/SSL messages parser.
d620ae0e
CT
196};
197
b3a8ae1b
AR
198} // namespace Ssl
199
21530947
CT
200void
201applyTlsDetailsToSSL(SSL *ssl, Security::TlsDetails::Pointer const &details, Ssl::BumpMode bumpMode);
202
86f77270 203#endif /* USE_OPENSSL */
b3a8ae1b 204#endif /* SQUID_SSL_BIO_H */
f53969cc 205