]> git.ipfire.org Git - thirdparty/squid.git/blame - src/security/Handshake.h
Source Format Enforcement (#1234)
[thirdparty/squid.git] / src / security / Handshake.h
CommitLineData
9210f5ec 1/*
b8ae064d 2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
9210f5ec
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_SECURITY_HANDSHAKE_H
10#define SQUID_SECURITY_HANDSHAKE_H
11
67c99fc6 12#include "anyp/ProtocolVersion.h"
67c99fc6 13#include "base/YesNoNone.h"
9210f5ec 14#include "parser/BinaryTokenizer.h"
a34d1d2d 15#include "security/forward.h"
9210f5ec 16
c05c0c94 17#include <unordered_set>
2549b7ac 18
9210f5ec
CT
19namespace Security
20{
21
f0f2a850 22class TlsDetails: public RefCountable
9210f5ec
CT
23{
24public:
f0f2a850
CT
25 typedef RefCount<TlsDetails> Pointer;
26
27 TlsDetails();
21530947
CT
28 /// Prints to os stream a human readable form of TlsDetails object
29 std::ostream & print(std::ostream &os) const;
30
67c99fc6 31 AnyP::ProtocolVersion tlsVersion; ///< The TLS hello message version
cd29a421
CT
32
33 /// For most compliant TLS v1.3+ agents, this is supported_versions maximum.
34 /// For others agents, this is the legacy_version field.
35 AnyP::ProtocolVersion tlsSupportedVersion;
36
67c99fc6 37 bool compressionSupported; ///< The requested/used compressed method
f0f2a850
CT
38 SBuf serverName; ///< The SNI hostname, if any
39 bool doHeartBeats;
40 bool tlsTicketsExtension; ///< whether TLS tickets extension is enabled
41 bool hasTlsTicket; ///< whether a TLS ticket is included
42 bool tlsStatusRequest; ///< whether the TLS status request extension is set
c05c0c94 43 bool unsupportedExtensions; ///< whether any unsupported by Squid extensions are used
f0f2a850
CT
44 SBuf tlsAppLayerProtoNeg; ///< The value of the TLS application layer protocol extension if it is enabled
45 /// The client random number
46 SBuf clientRandom;
47 SBuf sessionId;
c05c0c94
AR
48
49 typedef std::unordered_set<uint16_t> Ciphers;
50 Ciphers ciphers;
9210f5ec
CT
51};
52
25ecffe5
AR
53inline std::ostream &
54operator <<(std::ostream &os, const TlsDetails &details)
9210f5ec 55{
21530947
CT
56 return details.print(os);
57}
9210f5ec 58
d9219c2b
CT
59/// Incremental TLS/SSL Handshake parser.
60class HandshakeParser
9210f5ec 61{
9210f5ec
CT
62public:
63 /// The parsing states
800967af 64 typedef enum { atHelloNone = 0, atHelloStarted, atHelloReceived, atHelloDoneReceived, atNstReceived, atCcsReceived, atFinishReceived } ParserState;
9210f5ec 65
cd29a421
CT
66 /// the originator of the TLS handshake being parsed
67 typedef enum { fromClient = 0, fromServer } MessageSource;
68
69 explicit HandshakeParser(MessageSource);
9210f5ec 70
d9219c2b 71 /// Parses the initial sequence of raw bytes sent by the TLS/SSL agent.
d20cf186
AR
72 /// Returns true upon successful completion (e.g., got HelloDone).
73 /// Returns false if more data is needed.
74 /// Throws on errors.
7706b2ef 75 bool parseHello(const SBuf &data);
f0f2a850 76
cd29a421 77 TlsDetails::Pointer details; ///< TLS handshake meta info. Never nil.
9210f5ec 78
9210f5ec
CT
79 ParserState state; ///< current parsing state.
80
d9219c2b 81 bool resumingSession; ///< True if this is a resuming session
9210f5ec 82
cd29a421
CT
83 /// whether we are parsing Server or Client TLS handshake messages
84 MessageSource messageSource;
85
9210f5ec 86private:
5ea53436 87 bool isSslv2Record(const SBuf &raw) const;
9210f5ec 88 void parseRecord();
8abcff99
CT
89 void parseModernRecord();
90 void parseVersion2Record();
9210f5ec
CT
91 void parseMessages();
92
93 void parseChangeCipherCpecMessage();
94 void parseAlertMessage();
95 void parseHandshakeMessage();
96 void parseApplicationDataMessage();
97 void skipMessage(const char *msgType);
98
21530947 99 bool parseRecordVersion2Try();
f0f2a850
CT
100 void parseVersion2HandshakeMessage(const SBuf &raw);
101 void parseClientHelloHandshakeMessage(const SBuf &raw);
102 void parseServerHelloHandshakeMessage(const SBuf &raw);
103
67c99fc6 104 bool parseCompressionMethods(const SBuf &raw);
f0f2a850 105 void parseExtensions(const SBuf &raw);
21f081e2 106 SBuf parseSniExtension(const SBuf &extensionData) const;
cd29a421 107 void parseSupportedVersionsExtension(const SBuf &extensionData) const;
21f081e2 108
f0f2a850
CT
109 void parseCiphers(const SBuf &raw);
110 void parseV23Ciphers(const SBuf &raw);
111
9210f5ec 112 void parseServerCertificates(const SBuf &raw);
9210f5ec 113
d9219c2b 114 unsigned int currentContentType; ///< The current TLS/SSL record content type
d20cf186 115
d9219c2b 116 const char *done; ///< not nil if we got what we were looking for
d20cf186 117
9210f5ec
CT
118 /// concatenated TLSPlaintext.fragments of TLSPlaintext.type
119 SBuf fragments;
120
d9219c2b
CT
121 /// TLS record layer (parsing uninterpreted data)
122 Parser::BinaryTokenizer tkRecords;
123
995365cd 124 /// TLS message layer (parsing fragments)
d9219c2b 125 Parser::BinaryTokenizer tkMessages;
f0f2a850 126
995365cd 127 /// Whether to use TLS parser or a V2 compatible parser
d9219c2b 128 YesNoNone expectingModernRecords;
9210f5ec
CT
129};
130
cd29a421
CT
131/// whether the given protocol belongs to the TLS/SSL group of protocols
132inline bool
133TlsFamilyProtocol(const AnyP::ProtocolVersion &version)
134{
135 return (version.protocol == AnyP::PROTO_TLS || version.protocol == AnyP::PROTO_SSL);
136}
137
138/// whether TLS/SSL protocol `a` precedes TLS/SSL protocol `b`
139inline bool
140TlsVersionEarlierThan(const AnyP::ProtocolVersion &a, const AnyP::ProtocolVersion &b)
141{
142 Must(TlsFamilyProtocol(a));
143 Must(TlsFamilyProtocol(b));
144
145 if (a.protocol == b.protocol)
146 return a < b;
147
148 return a.protocol == AnyP::PROTO_SSL; // implies that b is TLS
149}
150
151/// whether the given TLS/SSL protocol is TLS v1.2 or earlier, including SSL
152inline bool
153Tls1p2orEarlier(const AnyP::ProtocolVersion &p)
154{
155 return TlsVersionEarlierThan(p, AnyP::ProtocolVersion(AnyP::PROTO_TLS, 1, 3));
156}
157
158/// whether the given TLS/SSL protocol is TLS v1.3 or later
159inline bool
160Tls1p3orLater(const AnyP::ProtocolVersion &p)
161{
162 return !Tls1p2orEarlier(p);
163}
164
9210f5ec
CT
165}
166
167#endif // SQUID_SECURITY_HANDSHAKE_H
fde0b2ca 168