Botan 3.0.0-alpha0
Crypto and TLS for C&
tls_handshake_transitions.cpp
Go to the documentation of this file.
1/*
2* TLS Handshake State Transitions
3* (C) 2004-2006,2011,2012 Jack Lloyd
4* 2017 Harry Reimann, Rohde & Schwarz Cybersecurity
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#include <botan/internal/tls_handshake_transitions.h>
10
11#include <botan/tls_exceptn.h>
12
13#include <sstream>
14
15namespace Botan::TLS {
16
17namespace {
18
19uint32_t bitmask_for_handshake_type(Handshake_Type type)
20 {
21 switch(type)
22 {
24 return (1 << 0);
25
26 case HELLO_REQUEST:
27 return (1 << 1);
28
29 case CLIENT_HELLO:
30 return (1 << 2);
31
32 case SERVER_HELLO:
33 return (1 << 3);
34
35 case CERTIFICATE:
36 return (1 << 4);
37
38 case CERTIFICATE_URL:
39 return (1 << 5);
40
42 return (1 << 6);
43
44 case SERVER_KEX:
45 return (1 << 7);
46
48 return (1 << 8);
49
51 return (1 << 9);
52
54 return (1 << 10);
55
56 case CLIENT_KEX:
57 return (1 << 11);
58
60 return (1 << 12);
61
62 case HANDSHAKE_CCS:
63 return (1 << 13);
64
65 case FINISHED:
66 return (1 << 14);
67
68 case END_OF_EARLY_DATA: // RFC 8446
69 return (1 << 15);
70
71 case ENCRYPTED_EXTENSIONS: // RFC 8446
72 return (1 << 16);
73
74 case KEY_UPDATE: // RFC 8446
75 return (1 << 17);
76
77 case HELLO_RETRY_REQUEST: // RFC 8446
78 return (1 << 18);
79
80 // allow explicitly disabling new handshakes
81 case HANDSHAKE_NONE:
82 return 0;
83 }
84
85 throw TLS_Exception(Alert::UNEXPECTED_MESSAGE,
86 "Unknown TLS handshake message type " + std::to_string(type));
87 }
88
89std::string handshake_mask_to_string(uint32_t mask, char combiner)
90 {
91 const Handshake_Type types[] =
92 {
107 FINISHED,
111 };
112
113 std::ostringstream o;
114 bool empty = true;
115
116 for(auto&& t : types)
117 {
118 if(mask & bitmask_for_handshake_type(t))
119 {
120 if(!empty)
121 { o << combiner; }
123 empty = false;
124 }
125 }
126
127 return o.str();
128 }
129
130}
131
133 {
134 const uint32_t mask = bitmask_for_handshake_type(msg_type);
135
136 return (m_hand_received_mask & mask) != 0;
137 }
138
140 {
141 const uint32_t mask = bitmask_for_handshake_type(msg_type);
142
143 m_hand_received_mask |= mask;
144
145 const bool ok = (m_hand_expecting_mask & mask) != 0; // overlap?
146
147 if(!ok)
148 {
149 const uint32_t seen_so_far = m_hand_received_mask & ~mask;
150
151 std::ostringstream msg;
152
153 msg << "Unexpected state transition in handshake got a " << handshake_type_to_string(msg_type);
154
155 if(m_hand_expecting_mask == 0)
156 { msg << " not expecting messages"; }
157 else
158 { msg << " expected " << handshake_mask_to_string(m_hand_expecting_mask, '|'); }
159
160 if(seen_so_far != 0)
161 { msg << " seen " << handshake_mask_to_string(seen_so_far, '+'); }
162
163 throw Unexpected_Message(msg.str());
164 }
165
166 /* We don't know what to expect next, so force a call to
167 set_expected_next; if it doesn't happen, the next transition
168 check will always fail which is what we want.
169 */
170 m_hand_expecting_mask = 0;
171 }
172
174 {
175 m_hand_expecting_mask |= bitmask_for_handshake_type(msg_type);
176 }
177
178void Handshake_Transitions::set_expected_next(const std::vector<Handshake_Type>& msg_types)
179 {
180 for (const auto type : msg_types)
181 {
183 }
184 }
185
187 {
188 return (bitmask_for_handshake_type(HANDSHAKE_CCS) & m_hand_expecting_mask) != 0;
189 }
190
191}
void confirm_transition_to(Handshake_Type msg_type)
bool received_handshake_msg(Handshake_Type msg_type) const
void set_expected_next(Handshake_Type msg_type)
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:209
@ HELLO_VERIFY_REQUEST
Definition: tls_magic.h:67
@ CLIENT_KEX
Definition: tls_magic.h:78
@ HANDSHAKE_CCS
Definition: tls_magic.h:87
@ ENCRYPTED_EXTENSIONS
Definition: tls_magic.h:71
@ CERTIFICATE_URL
Definition: tls_magic.h:81
@ SERVER_HELLO
Definition: tls_magic.h:66
@ HELLO_RETRY_REQUEST
Definition: tls_magic.h:86
@ NEW_SESSION_TICKET
Definition: tls_magic.h:68
@ END_OF_EARLY_DATA
Definition: tls_magic.h:70
@ KEY_UPDATE
Definition: tls_magic.h:84
@ SERVER_HELLO_DONE
Definition: tls_magic.h:76
@ HELLO_REQUEST
Definition: tls_magic.h:64
@ CERTIFICATE_REQUEST
Definition: tls_magic.h:75
@ CERTIFICATE
Definition: tls_magic.h:73
@ CERTIFICATE_STATUS
Definition: tls_magic.h:82
@ CERTIFICATE_VERIFY
Definition: tls_magic.h:77
@ HANDSHAKE_NONE
Definition: tls_magic.h:88
@ SERVER_KEX
Definition: tls_magic.h:74
@ CLIENT_HELLO
Definition: tls_magic.h:65
const char * handshake_type_to_string(Handshake_Type type)
MechanismType type