1# SPDX-License-Identifier: GPL-2.0-only 2# This file is part of Scapy 3# See https://scapy.net/ for more information 4# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard 5# 2015, 2016, 2017 Maxence Tury 6# 2019 Romain Perez 7 8""" 9TLS server automaton. This makes for a primitive TLS stack. 10Obviously you need rights for network access. 11 12We support versions SSLv2 to TLS 1.3, along with many features. 13 14In order to run a server listening on tcp/4433:: 15 16 from scapy.layers.tls import * 17 t = TLSServerAutomaton(mycert='<cert.pem>', mykey='<key.pem>') 18 t.run() 19""" 20 21import socket 22import binascii 23import struct 24import time 25 26from scapy.config import conf 27from scapy.packet import Raw 28from scapy.pton_ntop import inet_pton 29from scapy.utils import get_temp_file, randstring, repr_hex 30from scapy.automaton import ATMT 31from scapy.error import warning 32from scapy.layers.tls.automaton import _TLSAutomaton 33from scapy.layers.tls.cert import PrivKeyRSA, PrivKeyECDSA, PrivKeyEdDSA 34from scapy.layers.tls.basefields import _tls_version 35from scapy.layers.tls.session import tlsSession 36from scapy.layers.tls.crypto.groups import _tls_named_groups 37from scapy.layers.tls.extensions import ( 38 TLS_Ext_Cookie, 39 TLS_Ext_EarlyDataIndicationTicket, 40 TLS_Ext_PSKKeyExchangeModes, 41 TLS_Ext_RenegotiationInfo, 42 TLS_Ext_SignatureAlgorithms, 43 TLS_Ext_SupportedGroups, 44 TLS_Ext_SupportedVersion_SH, 45) 46from scapy.layers.tls.keyexchange import _tls_hash_sig 47from scapy.layers.tls.keyexchange_tls13 import ( 48 TLS_Ext_KeyShare_SH, 49 KeyShareEntry, 50 TLS_Ext_KeyShare_HRR, 51 TLS_Ext_PreSharedKey_CH, 52 TLS_Ext_PreSharedKey_SH, 53 get_usable_tls13_sigalgs, 54) 55from scapy.layers.tls.handshake import TLSCertificate, TLSCertificateRequest, \ 56 TLSCertificateVerify, TLSClientHello, TLSClientKeyExchange, TLSFinished, \ 57 TLSServerHello, TLSServerHelloDone, TLSServerKeyExchange, \ 58 _ASN1CertAndExt, TLS13ServerHello, TLS13Certificate, TLS13ClientHello, \ 59 TLSEncryptedExtensions, TLS13HelloRetryRequest, TLS13CertificateRequest, \ 60 TLS13KeyUpdate, TLS13NewSessionTicket 61from scapy.layers.tls.handshake_sslv2 import SSLv2ClientCertificate, \ 62 SSLv2ClientFinished, SSLv2ClientHello, SSLv2ClientMasterKey, \ 63 SSLv2RequestCertificate, SSLv2ServerFinished, SSLv2ServerHello, \ 64 SSLv2ServerVerify 65from scapy.layers.tls.record import TLSAlert, TLSChangeCipherSpec, \ 66 TLSApplicationData 67from scapy.layers.tls.record_tls13 import TLS13 68from scapy.layers.tls.crypto.hkdf import TLS13_HKDF 69from scapy.layers.tls.crypto.suites import ( 70 _tls_cipher_suites_cls, 71 _tls_cipher_suites, 72 get_usable_ciphersuites, 73) 74 75# Typing imports 76from typing import ( 77 Optional, 78 Union, 79) 80 81if conf.crypto_valid: 82 from cryptography.hazmat.backends import default_backend 83 from cryptography.hazmat.primitives import hashes 84 85 86class TLSServerAutomaton(_TLSAutomaton): 87 """ 88 A simple TLS test server automaton. Try to overload some states or 89 conditions and see what happens on the other side. 90 91 Because of socket and automaton limitations, for now, the best way to 92 interrupt the server is by sending him 'stop_server'. Interruptions with 93 Ctrl-Z should work, but this might leave a loose listening socket behind. 94 95 In case the server receives a TLSAlert (whatever its type), or a 'goodbye' 96 message in a SSLv2 version, he will close the client session with a 97 similar message, and start waiting for new client connections. 98 99 _'mycert' and 'mykey' may be provided as filenames. They are needed for any 100 server authenticated handshake. 101 _'preferred_ciphersuite' allows the automaton to choose a cipher suite when 102 offered in the ClientHello. If absent, another one will be chosen. 103 _'client_auth' means the client has to provide a certificate. 104 _'is_echo_server' means that everything received will be sent back. 105 _'max_client_idle_time' is the maximum silence duration from the client. 106 Once this limit has been reached, the client (if still here) is dropped, 107 and we wait for a new connection. 108 """ 109 110 def parse_args(self, server="127.0.0.1", sport=4433, 111 mycert=None, mykey=None, 112 preferred_ciphersuite: Optional[int] = None, 113 preferred_signature_algorithm: Union[str, int, None] = None, 114 client_auth=False, 115 is_echo_server=True, 116 max_client_idle_time=60, 117 handle_session_ticket=None, 118 session_ticket_file=None, 119 curve=None, 120 cookie=False, 121 psk=None, 122 psk_mode=None, 123 **kargs): 124 125 super(TLSServerAutomaton, self).parse_args(mycert=mycert, 126 mykey=mykey, 127 **kargs) 128 try: 129 if ':' in server: 130 inet_pton(socket.AF_INET6, server) 131 else: 132 inet_pton(socket.AF_INET, server) 133 tmp = socket.getaddrinfo(server, sport) 134 except Exception: 135 tmp = socket.getaddrinfo(socket.getfqdn(server), sport) 136 137 self.serversocket = None 138 self.ip_family = tmp[0][0] 139 self.local_ip = tmp[0][4][0] 140 self.local_port = sport 141 self.remote_ip = None 142 self.remote_port = None 143 144 self.client_auth = client_auth 145 self.is_echo_server = is_echo_server 146 self.max_client_idle_time = max_client_idle_time 147 self.curve = None 148 self.preferred_ciphersuite = None 149 self.preferred_signature_algorithm = None 150 self.cookie = cookie 151 self.psk_secret = psk 152 self.psk_mode = psk_mode 153 154 if handle_session_ticket is None: 155 handle_session_ticket = session_ticket_file is not None 156 if handle_session_ticket: 157 session_ticket_file = session_ticket_file or get_temp_file() 158 self.handle_session_ticket = handle_session_ticket 159 self.session_ticket_file = session_ticket_file 160 161 if preferred_ciphersuite is not None: 162 if preferred_ciphersuite in _tls_cipher_suites: 163 self.preferred_ciphersuite = preferred_ciphersuite 164 else: 165 self.vprint("Unrecognized cipher suite.") 166 167 if preferred_signature_algorithm is not None: 168 if preferred_signature_algorithm in _tls_hash_sig: 169 self.preferred_signature_algorithm = preferred_signature_algorithm 170 else: 171 for (sig_id, nc) in _tls_hash_sig.items(): 172 if nc == preferred_signature_algorithm: 173 self.preferred_signature_algorithm = sig_id 174 break 175 else: 176 self.vprint("Unrecognized signature algorithm.") 177 178 if curve: 179 for (group_id, ng) in _tls_named_groups.items(): 180 if ng == curve: 181 self.curve = group_id 182 break 183 else: 184 self.vprint("Unrecognized curve.") 185 186 def vprint_sessioninfo(self): 187 if self.verbose: 188 s = self.cur_session 189 v = _tls_version[s.tls_version] 190 self.vprint("Version : %s" % v) 191 cs = s.wcs.ciphersuite.name 192 self.vprint("Cipher suite : %s" % cs) 193 kx_groupname = s.kx_group 194 self.vprint("Server temp key : %s" % kx_groupname) 195 if s.tls_version >= 0x0304: 196 sigalg = _tls_hash_sig[s.selected_sig_alg] 197 self.vprint("Negotiated sig_alg : %s" % sigalg) 198 if s.tls_version < 0x0304: 199 ms = s.master_secret 200 else: 201 ms = s.tls13_master_secret 202 self.vprint("Master secret : %s" % repr_hex(ms)) 203 if s.client_certs: 204 self.vprint("Client certificate chain: %r" % s.client_certs) 205 206 if s.tls_version >= 0x0304: 207 res_secret = s.tls13_derived_secrets["resumption_secret"] 208 self.vprint("Resumption master secret : %s" % 209 repr_hex(res_secret)) 210 self.vprint() 211 212 def http_sessioninfo(self): 213 header = "HTTP/1.1 200 OK\r\n" 214 header += "Server: Scapy TLS Extension\r\n" 215 header += "Content-type: text/html\r\n" 216 header += "Content-length: %d\r\n\r\n" 217 s = "----- Scapy TLS Server Automaton -----\n\n" 218 s += "Information on current TLS session:\n\n" 219 s += "Local end : %s:%d\n" % (self.local_ip, self.local_port) 220 s += "Remote end : %s:%d\n" % (self.remote_ip, self.remote_port) 221 v = _tls_version[self.cur_session.tls_version] 222 s += "Version : %s\n" % v 223 cs = self.cur_session.wcs.ciphersuite.name 224 s += "Cipher suite : %s\n" % cs 225 if self.cur_session.tls_version < 0x0304: 226 ms = self.cur_session.master_secret 227 else: 228 ms = self.cur_session.tls13_master_secret 229 230 s += "Master secret : %s\n" % repr_hex(ms) 231 body = "<html><body><pre>%s</pre></body></html>\r\n\r\n" % s 232 answer = (header + body) % len(body) 233 return answer 234 235 @ATMT.state(initial=True) 236 def INITIAL(self): 237 self.vprint("Starting TLS server automaton.") 238 self.vprint("Receiving 'stop_server' will cause a graceful exit.") 239 self.vprint("Interrupting with Ctrl-Z might leave a loose socket hanging.") # noqa: E501 240 raise self.BIND() 241 242 @ATMT.state() 243 def BIND(self): 244 s = socket.socket(self.ip_family, socket.SOCK_STREAM) 245 self.serversocket = s 246 s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 247 try: 248 s.bind((self.local_ip, self.local_port)) 249 s.listen(1) 250 except Exception as e: 251 m = "Unable to bind on %s:%d! (%s)" % ( 252 self.local_ip, 253 self.local_port, 254 e 255 ) 256 self.vprint() 257 self.vprint(m) 258 self.vprint("Maybe some server is already listening there?") 259 self.vprint() 260 raise self.FINAL() 261 raise self.WAITING_CLIENT() 262 263 @ATMT.state() 264 def SOCKET_CLOSED(self): 265 self.socket.close() 266 raise self.WAITING_CLIENT() 267 268 @ATMT.state() 269 def WAITING_CLIENT(self): 270 self.buffer_out = [] 271 self.buffer_in = [] 272 self.vprint() 273 self.vprint("Waiting for a new client on %s:%d" % (self.local_ip, 274 self.local_port)) 275 self.socket, addr = self.serversocket.accept() 276 if not isinstance(addr, tuple): 277 addr = self.socket.getpeername() 278 if len(addr) > 2: 279 addr = (addr[0], addr[1]) 280 self.remote_ip, self.remote_port = addr 281 self.vprint("Accepted connection from %s:%d" % (self.remote_ip, 282 self.remote_port)) 283 self.vprint() 284 raise self.INIT_TLS_SESSION() 285 286 @ATMT.state() 287 def INIT_TLS_SESSION(self): 288 """ 289 XXX We should offer the right key according to the client's suites. For 290 now server_rsa_key is only used for RSAkx, but we should try to replace 291 every server_key with both server_rsa_key and server_ecdsa_key. 292 """ 293 self.cur_session = tlsSession(connection_end="server") 294 self.cur_session.server_certs = [self.mycert] 295 self.cur_session.server_key = self.mykey 296 if isinstance(self.mykey, PrivKeyRSA): 297 self.cur_session.server_rsa_key = self.mykey 298 # elif isinstance(self.mykey, PrivKeyECDSA): 299 # self.cur_session.server_ecdsa_key = self.mykey 300 raise self.WAITING_CLIENTFLIGHT1() 301 302 @ATMT.state() 303 def WAITING_CLIENTFLIGHT1(self): 304 self.get_next_msg() 305 raise self.RECEIVED_CLIENTFLIGHT1() 306 307 @ATMT.state() 308 def RECEIVED_CLIENTFLIGHT1(self): 309 pass 310 311 # TLS handshake # 312 313 @ATMT.condition(RECEIVED_CLIENTFLIGHT1, prio=1) 314 def tls13_should_handle_ClientHello(self): 315 self.raise_on_packet(TLS13ClientHello, 316 self.tls13_HANDLED_CLIENTHELLO) 317 if self.cur_session.advertised_tls_version == 0x0304: 318 self.raise_on_packet(TLSClientHello, 319 self.tls13_HANDLED_CLIENTHELLO) 320 321 @ATMT.condition(RECEIVED_CLIENTFLIGHT1, prio=2) 322 def should_handle_ClientHello(self): 323 self.raise_on_packet(TLSClientHello, 324 self.HANDLED_CLIENTHELLO) 325 326 @ATMT.condition(RECEIVED_CLIENTFLIGHT1, prio=3) 327 def tls13_should_handle_ChangeCipherSpec_after_tls13_retry(self): 328 # Middlebox compatibility mode after a HelloRetryRequest. 329 if self.cur_session.tls13_retry: 330 self.raise_on_packet(TLSChangeCipherSpec, 331 self.RECEIVED_CLIENTFLIGHT1) 332 333 @ATMT.state() 334 def HANDLED_CLIENTHELLO(self): 335 """ 336 We extract cipher suites candidates from the client's proposition. 337 """ 338 if isinstance(self.mykey, PrivKeyRSA): 339 kx = "RSA" 340 elif isinstance(self.mykey, PrivKeyECDSA): 341 kx = "ECDSA" 342 elif isinstance(self.mykey, PrivKeyEdDSA): 343 kx = "" 344 if get_usable_ciphersuites(self.cur_pkt.ciphers, kx): 345 raise self.PREPARE_SERVERFLIGHT1() 346 raise self.NO_USABLE_CIPHERSUITE() 347 348 @ATMT.state() 349 def NO_USABLE_CIPHERSUITE(self): 350 self.vprint("No usable cipher suite!") 351 raise self.CLOSE_NOTIFY() 352 353 @ATMT.condition(RECEIVED_CLIENTFLIGHT1, prio=3) 354 def missing_ClientHello(self): 355 raise self.MISSING_CLIENTHELLO() 356 357 @ATMT.state(final=True) 358 def MISSING_CLIENTHELLO(self): 359 self.vprint("Missing ClientHello message!") 360 raise self.CLOSE_NOTIFY() 361 362 @ATMT.state() 363 def PREPARE_SERVERFLIGHT1(self): 364 self.add_record() 365 366 @ATMT.condition(PREPARE_SERVERFLIGHT1) 367 def should_add_ServerHello(self): 368 """ 369 Selecting a cipher suite should be no trouble as we already caught 370 the None case previously. 371 """ 372 if isinstance(self.mykey, PrivKeyRSA): 373 kx = "RSA" 374 elif isinstance(self.mykey, PrivKeyECDSA): 375 kx = "ECDSA" 376 elif isinstance(self.mykey, PrivKeyEdDSA): 377 kx = "" 378 usable_suites = get_usable_ciphersuites(self.cur_pkt.ciphers, kx) 379 c = usable_suites[0] 380 if self.preferred_ciphersuite in usable_suites: 381 c = self.preferred_ciphersuite 382 383 # Some extensions 384 ext = [TLS_Ext_RenegotiationInfo()] 385 386 self.add_msg(TLSServerHello(cipher=c, ext=ext)) 387 raise self.ADDED_SERVERHELLO() 388 389 @ATMT.state() 390 def ADDED_SERVERHELLO(self): 391 pass 392 393 @ATMT.condition(ADDED_SERVERHELLO) 394 def should_add_Certificate(self): 395 c = self.buffer_out[-1].msg[0].cipher 396 if not _tls_cipher_suites_cls[c].kx_alg.anonymous: 397 self.add_msg(TLSCertificate(certs=self.cur_session.server_certs)) 398 raise self.ADDED_CERTIFICATE() 399 400 @ATMT.state() 401 def ADDED_CERTIFICATE(self): 402 pass 403 404 @ATMT.condition(ADDED_CERTIFICATE) 405 def should_add_ServerKeyExchange(self): 406 c = self.buffer_out[-1].msg[0].cipher 407 if not _tls_cipher_suites_cls[c].kx_alg.no_ske: 408 self.add_msg(TLSServerKeyExchange()) 409 raise self.ADDED_SERVERKEYEXCHANGE() 410 411 @ATMT.state() 412 def ADDED_SERVERKEYEXCHANGE(self): 413 pass 414 415 @ATMT.condition(ADDED_SERVERKEYEXCHANGE) 416 def should_add_CertificateRequest(self): 417 if self.client_auth: 418 self.add_msg(TLSCertificateRequest()) 419 raise self.ADDED_CERTIFICATEREQUEST() 420 421 @ATMT.state() 422 def ADDED_CERTIFICATEREQUEST(self): 423 pass 424 425 @ATMT.condition(ADDED_CERTIFICATEREQUEST) 426 def should_add_ServerHelloDone(self): 427 self.add_msg(TLSServerHelloDone()) 428 raise self.ADDED_SERVERHELLODONE() 429 430 @ATMT.state() 431 def ADDED_SERVERHELLODONE(self): 432 pass 433 434 @ATMT.condition(ADDED_SERVERHELLODONE) 435 def should_send_ServerFlight1(self): 436 self.flush_records() 437 raise self.WAITING_CLIENTFLIGHT2() 438 439 @ATMT.state() 440 def WAITING_CLIENTFLIGHT2(self): 441 self.get_next_msg() 442 raise self.RECEIVED_CLIENTFLIGHT2() 443 444 @ATMT.state() 445 def RECEIVED_CLIENTFLIGHT2(self): 446 pass 447 448 @ATMT.condition(RECEIVED_CLIENTFLIGHT2, prio=1) 449 def should_handle_ClientCertificate(self): 450 self.raise_on_packet(TLSCertificate, 451 self.HANDLED_CLIENTCERTIFICATE) 452 453 @ATMT.condition(RECEIVED_CLIENTFLIGHT2, prio=2) 454 def no_ClientCertificate(self): 455 if self.client_auth: 456 raise self.MISSING_CLIENTCERTIFICATE() 457 raise self.HANDLED_CLIENTCERTIFICATE() 458 459 @ATMT.state() 460 def MISSING_CLIENTCERTIFICATE(self): 461 self.vprint("Missing ClientCertificate!") 462 raise self.CLOSE_NOTIFY() 463 464 @ATMT.state() 465 def HANDLED_CLIENTCERTIFICATE(self): 466 if self.client_auth: 467 self.vprint("Received client certificate chain...") 468 469 @ATMT.condition(HANDLED_CLIENTCERTIFICATE, prio=1) 470 def should_handle_ClientKeyExchange(self): 471 self.raise_on_packet(TLSClientKeyExchange, 472 self.HANDLED_CLIENTKEYEXCHANGE) 473 474 @ATMT.state() 475 def HANDLED_CLIENTKEYEXCHANGE(self): 476 pass 477 478 @ATMT.condition(HANDLED_CLIENTCERTIFICATE, prio=2) 479 def should_handle_Alert_from_ClientCertificate(self): 480 self.raise_on_packet(TLSAlert, 481 self.HANDLED_ALERT_FROM_CLIENTCERTIFICATE) 482 483 @ATMT.state() 484 def HANDLED_ALERT_FROM_CLIENTCERTIFICATE(self): 485 self.vprint("Received Alert message instead of ClientKeyExchange!") 486 self.vprint(self.cur_pkt.mysummary()) 487 raise self.CLOSE_NOTIFY() 488 489 @ATMT.condition(HANDLED_CLIENTCERTIFICATE, prio=3) 490 def missing_ClientKeyExchange(self): 491 raise self.MISSING_CLIENTKEYEXCHANGE() 492 493 @ATMT.state() 494 def MISSING_CLIENTKEYEXCHANGE(self): 495 self.vprint("Missing ClientKeyExchange!") 496 raise self.CLOSE_NOTIFY() 497 498 @ATMT.condition(HANDLED_CLIENTKEYEXCHANGE, prio=1) 499 def should_handle_CertificateVerify(self): 500 self.raise_on_packet(TLSCertificateVerify, 501 self.HANDLED_CERTIFICATEVERIFY) 502 503 @ATMT.condition(HANDLED_CLIENTKEYEXCHANGE, prio=2) 504 def no_CertificateVerify(self): 505 if self.client_auth: 506 raise self.MISSING_CERTIFICATEVERIFY() 507 raise self.HANDLED_CERTIFICATEVERIFY() 508 509 @ATMT.state() 510 def MISSING_CERTIFICATEVERIFY(self): 511 self.vprint("Missing CertificateVerify!") 512 raise self.CLOSE_NOTIFY() 513 514 @ATMT.state() 515 def HANDLED_CERTIFICATEVERIFY(self): 516 pass 517 518 @ATMT.condition(HANDLED_CERTIFICATEVERIFY, prio=1) 519 def should_handle_ChangeCipherSpec(self): 520 self.raise_on_packet(TLSChangeCipherSpec, 521 self.HANDLED_CHANGECIPHERSPEC) 522 523 @ATMT.state() 524 def HANDLED_CHANGECIPHERSPEC(self): 525 pass 526 527 @ATMT.condition(HANDLED_CERTIFICATEVERIFY, prio=2) 528 def should_handle_Alert_from_ClientKeyExchange(self): 529 self.raise_on_packet(TLSAlert, 530 self.HANDLED_ALERT_FROM_CLIENTKEYEXCHANGE) 531 532 @ATMT.state() 533 def HANDLED_ALERT_FROM_CLIENTKEYEXCHANGE(self): 534 self.vprint("Received Alert message instead of ChangeCipherSpec!") 535 self.vprint(self.cur_pkt.mysummary()) 536 raise self.CLOSE_NOTIFY() 537 538 @ATMT.condition(HANDLED_CERTIFICATEVERIFY, prio=3) 539 def missing_ChangeCipherSpec(self): 540 raise self.MISSING_CHANGECIPHERSPEC() 541 542 @ATMT.state() 543 def MISSING_CHANGECIPHERSPEC(self): 544 self.vprint("Missing ChangeCipherSpec!") 545 raise self.CLOSE_NOTIFY() 546 547 @ATMT.condition(HANDLED_CHANGECIPHERSPEC, prio=1) 548 def should_handle_ClientFinished(self): 549 self.raise_on_packet(TLSFinished, 550 self.HANDLED_CLIENTFINISHED) 551 552 @ATMT.state() 553 def HANDLED_CLIENTFINISHED(self): 554 raise self.PREPARE_SERVERFLIGHT2() 555 556 @ATMT.condition(HANDLED_CHANGECIPHERSPEC, prio=2) 557 def should_handle_Alert_from_ClientFinished(self): 558 self.raise_on_packet(TLSAlert, 559 self.HANDLED_ALERT_FROM_CHANGECIPHERSPEC) 560 561 @ATMT.state() 562 def HANDLED_ALERT_FROM_CHANGECIPHERSPEC(self): 563 self.vprint("Received Alert message instead of Finished!") 564 raise self.CLOSE_NOTIFY() 565 566 @ATMT.condition(HANDLED_CHANGECIPHERSPEC, prio=3) 567 def missing_ClientFinished(self): 568 raise self.MISSING_CLIENTFINISHED() 569 570 @ATMT.state() 571 def MISSING_CLIENTFINISHED(self): 572 self.vprint("Missing Finished!") 573 raise self.CLOSE_NOTIFY() 574 575 @ATMT.state() 576 def PREPARE_SERVERFLIGHT2(self): 577 self.add_record() 578 579 @ATMT.condition(PREPARE_SERVERFLIGHT2) 580 def should_add_ChangeCipherSpec(self): 581 self.add_msg(TLSChangeCipherSpec()) 582 raise self.ADDED_CHANGECIPHERSPEC() 583 584 @ATMT.state() 585 def ADDED_CHANGECIPHERSPEC(self): 586 pass 587 588 @ATMT.condition(ADDED_CHANGECIPHERSPEC) 589 def should_add_ServerFinished(self): 590 self.add_record() 591 self.add_msg(TLSFinished()) 592 raise self.ADDED_SERVERFINISHED() 593 594 @ATMT.state() 595 def ADDED_SERVERFINISHED(self): 596 pass 597 598 @ATMT.condition(ADDED_SERVERFINISHED) 599 def should_send_ServerFlight2(self): 600 self.flush_records() 601 raise self.SENT_SERVERFLIGHT2() 602 603 @ATMT.state() 604 def SENT_SERVERFLIGHT2(self): 605 self.vprint("TLS handshake completed!") 606 self.vprint_sessioninfo() 607 if self.is_echo_server: 608 self.vprint("Will now act as a simple echo server.") 609 raise self.WAITING_CLIENTDATA() 610 611 # end of TLS handshake # 612 613 # TLS 1.3 handshake # 614 @ATMT.state() 615 def tls13_HANDLED_CLIENTHELLO(self): 616 """ 617 Check if we have to send an HelloRetryRequest 618 XXX check also with non ECC groups 619 """ 620 s = self.cur_session 621 m = s.handshake_messages_parsed[-1] 622 # Check if we have to send an HelloRetryRequest 623 # XXX check also with non ECC groups 624 if self.curve: 625 # We first look for a KeyShareEntry with same group as self.curve 626 if not _tls_named_groups[self.curve] in s.tls13_client_pubshares: 627 # We then check if self.curve was advertised in SupportedGroups 628 # extension 629 for e in m.ext: 630 if isinstance(e, TLS_Ext_SupportedGroups): 631 if self.curve in e.groups: 632 # Here, we need to send an HelloRetryRequest 633 raise self.tls13_PREPARE_HELLORETRYREQUEST() 634 635 # Signature Algorithms extension is mandatory 636 if not s.advertised_sig_algs: 637 self.vprint("Missing signature_algorithms extension in ClientHello!") 638 raise self.CLOSE_NOTIFY() 639 640 raise self.tls13_PREPARE_SERVERFLIGHT1() 641 642 @ATMT.state() 643 def tls13_PREPARE_HELLORETRYREQUEST(self): 644 pass 645 646 @ATMT.condition(tls13_PREPARE_HELLORETRYREQUEST) 647 def tls13_should_add_HelloRetryRequest(self): 648 self.add_record(is_tls13=False) 649 if isinstance(self.mykey, PrivKeyRSA): 650 kx = "RSA" 651 elif isinstance(self.mykey, PrivKeyECDSA): 652 kx = "ECDSA" 653 elif isinstance(self.mykey, PrivKeyEdDSA): 654 kx = "" 655 usable_suites = get_usable_ciphersuites(self.cur_pkt.ciphers, kx) 656 c = usable_suites[0] 657 ext = [TLS_Ext_SupportedVersion_SH(version="TLS 1.3"), 658 TLS_Ext_KeyShare_HRR(selected_group=_tls_named_groups[self.curve])] # noqa: E501 659 if self.cookie: 660 ext += TLS_Ext_Cookie() 661 p = TLS13HelloRetryRequest(cipher=c, ext=ext) 662 self.add_msg(p) 663 self.flush_records() 664 raise self.tls13_HANDLED_HELLORETRYREQUEST() 665 666 @ATMT.state() 667 def tls13_HANDLED_HELLORETRYREQUEST(self): 668 pass 669 670 @ATMT.condition(tls13_HANDLED_HELLORETRYREQUEST) 671 def tls13_should_add_ServerHello_from_HRR(self): 672 raise self.WAITING_CLIENTFLIGHT1() 673 674 @ATMT.state() 675 def tls13_PREPARE_SERVERFLIGHT1(self): 676 self.add_record(is_tls13=False) 677 678 def verify_psk_binder(self, psk_identity, obfuscated_age, binder): 679 """ 680 This function verifies the binder received in the 'pre_shared_key' 681 extension and return the resumption PSK associated with those 682 values. 683 684 The arguments psk_identity, obfuscated_age and binder are taken 685 from 'pre_shared_key' in the ClientHello. 686 """ 687 with open(self.session_ticket_file, "rb") as f: 688 for line in f: 689 s = line.strip().split(b';') 690 if len(s) < 8: 691 continue 692 ticket_label = binascii.unhexlify(s[0]) 693 ticket_nonce = binascii.unhexlify(s[1]) 694 tmp = binascii.unhexlify(s[2]) 695 ticket_lifetime = struct.unpack("!I", tmp)[0] 696 tmp = binascii.unhexlify(s[3]) 697 ticket_age_add = struct.unpack("!I", tmp)[0] 698 tmp = binascii.unhexlify(s[4]) 699 ticket_start_time = struct.unpack("!I", tmp)[0] 700 resumption_secret = binascii.unhexlify(s[5]) 701 tmp = binascii.unhexlify(s[6]) 702 res_ciphersuite = struct.unpack("!H", tmp)[0] 703 tmp = binascii.unhexlify(s[7]) 704 max_early_data_size = struct.unpack("!I", tmp)[0] 705 706 # Here psk_identity is a Ticket type but ticket_label is bytes, 707 # we need to convert psk_identiy to bytes in order to compare 708 # both strings 709 if psk_identity.__bytes__() == ticket_label: 710 711 # We compute the resumed PSK associated the resumption 712 # secret 713 self.vprint("Ticket found in database !") 714 if res_ciphersuite not in _tls_cipher_suites_cls: 715 warning("Unknown cipher suite %d", res_ciphersuite) 716 # we do not try to set a default nor stop the execution 717 else: 718 cs_cls = _tls_cipher_suites_cls[res_ciphersuite] 719 720 hkdf = TLS13_HKDF(cs_cls.hash_alg.name.lower()) 721 hash_len = hkdf.hash.digest_size 722 723 tls13_psk_secret = hkdf.expand_label(resumption_secret, 724 b"resumption", 725 ticket_nonce, 726 hash_len) 727 # We verify that ticket age is not expired 728 agesec = int((time.time() - ticket_start_time)) 729 # agems = agesec * 1000 730 ticket_age = (obfuscated_age - ticket_age_add) % 0xffffffff # noqa: F841, E501 731 732 # We verify the PSK binder 733 s = self.cur_session 734 if s.tls13_retry: 735 handshake_context = struct.pack("B", 254) 736 handshake_context += struct.pack("B", 0) 737 handshake_context += struct.pack("B", 0) 738 handshake_context += struct.pack("B", hash_len) 739 digest = hashes.Hash(hkdf.hash, backend=default_backend()) # noqa: E501 740 digest.update(s.handshake_messages[0]) 741 handshake_context += digest.finalize() 742 for m in s.handshake_messages[1:]: 743 if (isinstance(TLS13ClientHello) or 744 isinstance(TLSClientHello)): 745 handshake_context += m[:-hash_len - 3] 746 else: 747 handshake_context += m 748 else: 749 handshake_context = s.handshake_messages[0][:-hash_len - 3] # noqa: E501 750 751 # We compute the binder key 752 # XXX use the compute_tls13_early_secrets() function 753 tls13_early_secret = hkdf.extract(None, tls13_psk_secret) 754 binder_key = hkdf.derive_secret(tls13_early_secret, 755 b"res binder", 756 b"") 757 computed_binder = hkdf.compute_verify_data(binder_key, 758 handshake_context) # noqa: E501 759 if (agesec < ticket_lifetime and 760 computed_binder == binder): 761 self.vprint("Ticket has been accepted ! ") 762 self.max_early_data_size = max_early_data_size 763 self.resumed_ciphersuite = res_ciphersuite 764 return tls13_psk_secret 765 self.vprint("Ticket has not been accepted ! Fallback to a complete handshake") # noqa: E501 766 return None 767 768 @ATMT.condition(tls13_PREPARE_SERVERFLIGHT1) 769 def tls13_should_add_ServerHello(self): 770 771 psk_identity = None 772 psk_key_exchange_mode = None 773 obfuscated_age = None 774 # XXX check ClientHello extensions... 775 for m in reversed(self.cur_session.handshake_messages_parsed): 776 if isinstance(m, (TLS13ClientHello, TLSClientHello)): 777 for e in m.ext: 778 if isinstance(e, TLS_Ext_PreSharedKey_CH): 779 psk_identity = e.identities[0].identity 780 obfuscated_age = e.identities[0].obfuscated_ticket_age 781 binder = e.binders[0].binder 782 783 # For out-of-bound PSK, obfuscated_ticket_age should be 784 # 0. We use this field to distinguish between out-of- 785 # bound PSK and resumed PSK 786 is_out_of_band_psk = (obfuscated_age == 0) 787 788 if isinstance(e, TLS_Ext_PSKKeyExchangeModes): 789 psk_key_exchange_mode = e.kxmodes[0] 790 791 if isinstance(self.mykey, PrivKeyRSA): 792 kx = "RSA" 793 elif isinstance(self.mykey, PrivKeyECDSA): 794 kx = "ECDSA" 795 elif isinstance(self.mykey, PrivKeyEdDSA): 796 kx = "" 797 usable_suites = get_usable_ciphersuites(self.cur_pkt.ciphers, kx) 798 c = usable_suites[0] 799 group = next(iter(self.cur_session.tls13_client_pubshares)) 800 ext = [TLS_Ext_SupportedVersion_SH(version="TLS 1.3")] 801 if (psk_identity and obfuscated_age and psk_key_exchange_mode): 802 s = self.cur_session 803 if is_out_of_band_psk: 804 # Handshake with external PSK authentication 805 # XXX test that self.psk_secret is set 806 s.tls13_psk_secret = binascii.unhexlify(self.psk_secret) 807 # 0: "psk_ke" 808 # 1: "psk_dhe_ke" 809 if psk_key_exchange_mode == 1: 810 server_kse = KeyShareEntry(group=group) 811 ext += TLS_Ext_KeyShare_SH(server_share=server_kse) 812 ext += TLS_Ext_PreSharedKey_SH(selected_identity=0) 813 else: 814 resumption_psk = self.verify_psk_binder(psk_identity, 815 obfuscated_age, 816 binder) 817 if resumption_psk is None: 818 # We did not find a ticket matching the one provided in the 819 # ClientHello. We fallback to a regular 1-RTT handshake 820 server_kse = KeyShareEntry(group=group) 821 ext += [TLS_Ext_KeyShare_SH(server_share=server_kse)] 822 else: 823 # 0: "psk_ke" 824 # 1: "psk_dhe_ke" 825 if psk_key_exchange_mode == 1: 826 server_kse = KeyShareEntry(group=group) 827 ext += [TLS_Ext_KeyShare_SH(server_share=server_kse)] 828 829 ext += [TLS_Ext_PreSharedKey_SH(selected_identity=0)] 830 self.cur_session.tls13_psk_secret = resumption_psk 831 else: 832 # Standard Handshake 833 ext += TLS_Ext_KeyShare_SH(server_share=KeyShareEntry(group=group)) 834 835 if self.cur_session.sid is not None: 836 p = TLS13ServerHello(cipher=c, sid=self.cur_session.sid, ext=ext) 837 else: 838 p = TLS13ServerHello(cipher=c, ext=ext) 839 self.add_msg(p) 840 raise self.tls13_ADDED_SERVERHELLO() 841 842 @ATMT.state() 843 def tls13_ADDED_SERVERHELLO(self): 844 # If the client proposed a non-empty session ID in his ClientHello 845 # he requested the middlebox compatibility mode (RFC8446, appendix D.4) 846 # In this case, the server should send a dummy ChangeCipherSpec in 847 # between the ServerHello and the encrypted handshake messages 848 if self.cur_session.sid is not None: 849 self.add_record(is_tls12=True) 850 self.add_msg(TLSChangeCipherSpec()) 851 852 @ATMT.condition(tls13_ADDED_SERVERHELLO) 853 def tls13_should_add_EncryptedExtensions(self): 854 self.add_record(is_tls13=True) 855 self.add_msg(TLSEncryptedExtensions(extlen=0)) 856 raise self.tls13_ADDED_ENCRYPTEDEXTENSIONS() 857 858 @ATMT.state() 859 def tls13_ADDED_ENCRYPTEDEXTENSIONS(self): 860 pass 861 862 @ATMT.condition(tls13_ADDED_ENCRYPTEDEXTENSIONS) 863 def tls13_should_add_CertificateRequest(self): 864 if self.client_auth: 865 ext = [TLS_Ext_SignatureAlgorithms(sig_algs=["sha256+rsaepss"])] 866 p = TLS13CertificateRequest(ext=ext) 867 self.add_msg(p) 868 raise self.tls13_ADDED_CERTIFICATEREQUEST() 869 870 @ATMT.state() 871 def tls13_ADDED_CERTIFICATEREQUEST(self): 872 pass 873 874 @ATMT.condition(tls13_ADDED_CERTIFICATEREQUEST) 875 def tls13_should_add_Certificate(self): 876 # If a PSK is set, an extension pre_shared_key 877 # was send in the ServerHello. No certificate should 878 # be send here 879 if not self.cur_session.tls13_psk_secret: 880 certs = [] 881 for c in self.cur_session.server_certs: 882 certs += _ASN1CertAndExt(cert=c) 883 884 self.add_msg(TLS13Certificate(certs=certs)) 885 raise self.tls13_ADDED_CERTIFICATE() 886 887 @ATMT.state() 888 def tls13_ADDED_CERTIFICATE(self): 889 pass 890 891 @ATMT.condition(tls13_ADDED_CERTIFICATE) 892 def tls13_should_add_CertificateVerifiy(self): 893 if not self.cur_session.tls13_psk_secret: 894 # If we have a preferred signature algorithm, and the client supports 895 # it, use that. 896 if self.cur_session.advertised_sig_algs: 897 usable_sigalgs = get_usable_tls13_sigalgs( 898 self.cur_session.advertised_sig_algs, 899 self.mykey, 900 location="certificateverify", 901 ) 902 if not usable_sigalgs: 903 self.vprint("No usable signature algorithm!") 904 raise self.CLOSE_NOTIFY() 905 pref_alg = self.preferred_signature_algorithm 906 if pref_alg in usable_sigalgs: 907 self.cur_session.selected_sig_alg = pref_alg 908 else: 909 self.cur_session.selected_sig_alg = usable_sigalgs[0] 910 self.add_msg(TLSCertificateVerify()) 911 raise self.tls13_ADDED_CERTIFICATEVERIFY() 912 913 @ATMT.state() 914 def tls13_ADDED_CERTIFICATEVERIFY(self): 915 pass 916 917 @ATMT.condition(tls13_ADDED_CERTIFICATEVERIFY) 918 def tls13_should_add_Finished(self): 919 self.add_msg(TLSFinished()) 920 raise self.tls13_ADDED_SERVERFINISHED() 921 922 @ATMT.state() 923 def tls13_ADDED_SERVERFINISHED(self): 924 pass 925 926 @ATMT.condition(tls13_ADDED_SERVERFINISHED) 927 def tls13_should_send_ServerFlight1(self): 928 self.flush_records() 929 raise self.tls13_WAITING_CLIENTFLIGHT2() 930 931 @ATMT.state() 932 def tls13_WAITING_CLIENTFLIGHT2(self): 933 self.get_next_msg() 934 raise self.tls13_RECEIVED_CLIENTFLIGHT2() 935 936 @ATMT.state() 937 def tls13_RECEIVED_CLIENTFLIGHT2(self): 938 pass 939 940 @ATMT.condition(tls13_RECEIVED_CLIENTFLIGHT2, prio=1) 941 def tls13_should_handle_ClientFlight2(self): 942 self.raise_on_packet(TLS13Certificate, 943 self.TLS13_HANDLED_CLIENTCERTIFICATE) 944 945 @ATMT.condition(tls13_RECEIVED_CLIENTFLIGHT2, prio=2) 946 def tls13_should_handle_Alert_from_ClientCertificate(self): 947 self.raise_on_packet(TLSAlert, 948 self.TLS13_HANDLED_ALERT_FROM_CLIENTCERTIFICATE) 949 950 @ATMT.state() 951 def TLS13_HANDLED_ALERT_FROM_CLIENTCERTIFICATE(self): 952 self.vprint("Received Alert message instead of ClientKeyExchange!") 953 self.vprint(self.cur_pkt.mysummary()) 954 raise self.CLOSE_NOTIFY() 955 956 # For Middlebox compatibility (see RFC8446, appendix D.4) 957 # a dummy ChangeCipherSpec record can be send. In this case, 958 # this function just read the ChangeCipherSpec message and 959 # go back in a previous state continuing with the next TLS 1.3 960 # record 961 @ATMT.condition(tls13_RECEIVED_CLIENTFLIGHT2, prio=3) 962 def tls13_should_handle_ClientCCS(self): 963 self.raise_on_packet(TLSChangeCipherSpec, 964 self.tls13_RECEIVED_CLIENTFLIGHT2) 965 966 @ATMT.condition(tls13_RECEIVED_CLIENTFLIGHT2, prio=4) 967 def tls13_no_ClientCertificate(self): 968 if self.client_auth: 969 raise self.TLS13_MISSING_CLIENTCERTIFICATE() 970 self.raise_on_packet(TLSFinished, 971 self.TLS13_HANDLED_CLIENTFINISHED) 972 973 # RFC8446, section 4.4.2.4 : 974 # "If the client does not send any certificates (i.e., it sends an empty 975 # Certificate message), the server MAY at its discretion either 976 # continue the handshake without client authentication or abort the 977 # handshake with a "certificate_required" alert." 978 # Here, we abort the handshake. 979 @ATMT.state() 980 def TLS13_HANDLED_CLIENTCERTIFICATE(self): 981 if self.client_auth: 982 self.vprint("Received client certificate chain...") 983 if isinstance(self.cur_pkt, TLS13Certificate): 984 if self.cur_pkt.certslen == 0: 985 self.vprint("but it's empty !") 986 raise self.TLS13_MISSING_CLIENTCERTIFICATE() 987 988 @ATMT.condition(TLS13_HANDLED_CLIENTCERTIFICATE) 989 def tls13_should_handle_ClientCertificateVerify(self): 990 self.raise_on_packet(TLSCertificateVerify, 991 self.TLS13_HANDLED_CLIENT_CERTIFICATEVERIFY) 992 993 @ATMT.condition(TLS13_HANDLED_CLIENTCERTIFICATE, prio=2) 994 def tls13_no_Client_CertificateVerify(self): 995 if self.client_auth: 996 raise self.TLS13_MISSING_CLIENTCERTIFICATE() 997 raise self.TLS13_HANDLED_CLIENT_CERTIFICATEVERIFY() 998 999 @ATMT.state() 1000 def TLS13_HANDLED_CLIENT_CERTIFICATEVERIFY(self): 1001 pass 1002 1003 @ATMT.condition(TLS13_HANDLED_CLIENT_CERTIFICATEVERIFY) 1004 def tls13_should_handle_ClientFinished(self): 1005 self.raise_on_packet(TLSFinished, 1006 self.TLS13_HANDLED_CLIENTFINISHED) 1007 1008 @ATMT.state() 1009 def TLS13_MISSING_CLIENTCERTIFICATE(self): 1010 self.vprint("Missing ClientCertificate!") 1011 self.add_record() 1012 self.add_msg(TLSAlert(level=2, descr=0x74)) 1013 self.flush_records() 1014 self.vprint("Sending TLSAlert 116") 1015 self.socket.close() 1016 raise self.WAITING_CLIENT() 1017 1018 @ATMT.state() 1019 def TLS13_HANDLED_CLIENTFINISHED(self): 1020 self.vprint("TLS handshake completed!") 1021 self.vprint_sessioninfo() 1022 if self.is_echo_server: 1023 self.vprint("Will now act as a simple echo server.") 1024 raise self.WAITING_CLIENTDATA() 1025 1026 # end of TLS 1.3 handshake # 1027 1028 @ATMT.state() 1029 def WAITING_CLIENTDATA(self): 1030 self.get_next_msg(self.max_client_idle_time, 1) 1031 raise self.RECEIVED_CLIENTDATA() 1032 1033 @ATMT.state() 1034 def RECEIVED_CLIENTDATA(self): 1035 pass 1036 1037 def save_ticket(self, ticket): 1038 """ 1039 This function save a ticket and others parameters in the 1040 file given as argument to the automaton 1041 Warning : The file is not protected and contains sensitive 1042 information. It should be used only for testing purpose. 1043 """ 1044 if (not isinstance(ticket, TLS13NewSessionTicket) or 1045 self.session_ticket_file is None): 1046 return 1047 1048 s = self.cur_session 1049 with open(self.session_ticket_file, "ab") as f: 1050 # ticket;ticket_nonce;obfuscated_age;start_time;resumption_secret 1051 line = binascii.hexlify(ticket.ticket) 1052 line += b";" 1053 line += binascii.hexlify(ticket.ticket_nonce) 1054 line += b";" 1055 line += binascii.hexlify(struct.pack("!I", ticket.ticket_lifetime)) 1056 line += b";" 1057 line += binascii.hexlify(struct.pack("!I", ticket.ticket_age_add)) 1058 line += b";" 1059 line += binascii.hexlify(struct.pack("!I", int(time.time()))) 1060 line += b";" 1061 line += binascii.hexlify(s.tls13_derived_secrets["resumption_secret"]) # noqa: E501 1062 line += b";" 1063 line += binascii.hexlify(struct.pack("!H", s.wcs.ciphersuite.val)) 1064 line += b";" 1065 if (ticket.ext is None or ticket.extlen is None or 1066 ticket.extlen == 0): 1067 line += binascii.hexlify(struct.pack("!I", 0)) 1068 else: 1069 for e in ticket.ext: 1070 if isinstance(e, TLS_Ext_EarlyDataIndicationTicket): 1071 max_size = struct.pack("!I", e.max_early_data_size) 1072 line += binascii.hexlify(max_size) 1073 line += b"\n" 1074 f.write(line) 1075 1076 @ATMT.condition(RECEIVED_CLIENTDATA) 1077 def should_handle_ClientData(self): 1078 if not self.buffer_in: 1079 self.vprint("Client idle time maxed out.") 1080 raise self.CLOSE_NOTIFY() 1081 p = self.buffer_in[0] 1082 self.buffer_in = self.buffer_in[1:] 1083 1084 recv_data = b"" 1085 if isinstance(p, TLSApplicationData): 1086 print("> Received: %r" % p.data) 1087 recv_data = p.data 1088 lines = recv_data.split(b"\n") 1089 for line in lines: 1090 if line.startswith(b"stop_server"): 1091 raise self.CLOSE_NOTIFY_FINAL() 1092 elif isinstance(p, TLSAlert): 1093 print("> Received: %r" % p) 1094 raise self.CLOSE_NOTIFY() 1095 elif isinstance(p, TLS13KeyUpdate): 1096 print("> Received: %r" % p) 1097 p = TLS13KeyUpdate(request_update=0) 1098 self.add_record() 1099 self.add_msg(p) 1100 raise self.ADDED_SERVERDATA() 1101 else: 1102 print("> Received: %r" % p) 1103 1104 if recv_data.startswith(b"GET / HTTP/1.1"): 1105 p = TLSApplicationData(data=self.http_sessioninfo()) 1106 1107 if self.is_echo_server or recv_data.startswith(b"GET / HTTP/1.1"): 1108 self.add_record() 1109 self.add_msg(p) 1110 if self.handle_session_ticket: 1111 self.add_record() 1112 ticket = TLS13NewSessionTicket(ext=[]) 1113 self.add_msg(ticket) 1114 raise self.ADDED_SERVERDATA() 1115 1116 raise self.HANDLED_CLIENTDATA() 1117 1118 @ATMT.state() 1119 def HANDLED_CLIENTDATA(self): 1120 raise self.WAITING_CLIENTDATA() 1121 1122 @ATMT.state() 1123 def ADDED_SERVERDATA(self): 1124 pass 1125 1126 @ATMT.condition(ADDED_SERVERDATA) 1127 def should_send_ServerData(self): 1128 if self.session_ticket_file: 1129 save_ticket = False 1130 for p in self.buffer_out: 1131 if isinstance(p, TLS13): 1132 # Check if there's a NewSessionTicket to send 1133 save_ticket = all(map(lambda x: isinstance(x, TLS13NewSessionTicket), # noqa: E501 1134 p.inner.msg)) 1135 if save_ticket: 1136 break 1137 self.flush_records() 1138 if self.session_ticket_file and save_ticket: 1139 # Loop backward in message send to retrieve the parsed 1140 # NewSessionTicket. This message is not completely build before the 1141 # flush_records() call. Other way to build this message before ? 1142 for p in reversed(self.cur_session.handshake_messages_parsed): 1143 if isinstance(p, TLS13NewSessionTicket): 1144 self.save_ticket(p) 1145 break 1146 raise self.SENT_SERVERDATA() 1147 1148 @ATMT.state() 1149 def SENT_SERVERDATA(self): 1150 raise self.WAITING_CLIENTDATA() 1151 1152 @ATMT.state() 1153 def CLOSE_NOTIFY(self): 1154 self.vprint() 1155 self.vprint("Sending a TLSAlert to the client...") 1156 1157 @ATMT.condition(CLOSE_NOTIFY) 1158 def close_session(self): 1159 self.add_record() 1160 self.add_msg(TLSAlert(level=1, descr=0)) 1161 try: 1162 self.flush_records() 1163 except Exception: 1164 self.vprint("Could not send termination Alert, maybe the client left?") # noqa: E501 1165 self.buffer_out = [] 1166 self.socket.close() 1167 raise self.WAITING_CLIENT() 1168 1169 @ATMT.state() 1170 def CLOSE_NOTIFY_FINAL(self): 1171 self.vprint() 1172 self.vprint("Sending a TLSAlert to the client...") 1173 1174 @ATMT.condition(CLOSE_NOTIFY_FINAL) 1175 def close_session_final(self): 1176 self.add_record() 1177 self.add_msg(TLSAlert(level=1, descr=0)) 1178 try: 1179 self.flush_records() 1180 except Exception: 1181 self.vprint("Could not send termination Alert, maybe the client left?") # noqa: E501 1182 # We might call shutdown, but unit tests with s_client fail with this 1183 # self.socket.shutdown(1) 1184 self.socket.close() 1185 raise self.FINAL() 1186 1187 # SSLv2 handshake # 1188 1189 @ATMT.condition(RECEIVED_CLIENTFLIGHT1, prio=2) 1190 def sslv2_should_handle_ClientHello(self): 1191 self.raise_on_packet(SSLv2ClientHello, 1192 self.SSLv2_HANDLED_CLIENTHELLO) 1193 1194 @ATMT.state() 1195 def SSLv2_HANDLED_CLIENTHELLO(self): 1196 pass 1197 1198 @ATMT.condition(SSLv2_HANDLED_CLIENTHELLO) 1199 def sslv2_should_add_ServerHello(self): 1200 self.add_record(is_sslv2=True) 1201 cert = self.mycert 1202 ciphers = [0x010080, 0x020080, 0x030080, 0x040080, 1203 0x050080, 0x060040, 0x0700C0] 1204 connection_id = randstring(16) 1205 p = SSLv2ServerHello(cert=cert, 1206 ciphers=ciphers, 1207 connection_id=connection_id) 1208 self.add_msg(p) 1209 raise self.SSLv2_ADDED_SERVERHELLO() 1210 1211 @ATMT.state() 1212 def SSLv2_ADDED_SERVERHELLO(self): 1213 pass 1214 1215 @ATMT.condition(SSLv2_ADDED_SERVERHELLO) 1216 def sslv2_should_send_ServerHello(self): 1217 self.flush_records() 1218 raise self.SSLv2_SENT_SERVERHELLO() 1219 1220 @ATMT.state() 1221 def SSLv2_SENT_SERVERHELLO(self): 1222 raise self.SSLv2_WAITING_CLIENTMASTERKEY() 1223 1224 @ATMT.state() 1225 def SSLv2_WAITING_CLIENTMASTERKEY(self): 1226 self.get_next_msg() 1227 raise self.SSLv2_RECEIVED_CLIENTMASTERKEY() 1228 1229 @ATMT.state() 1230 def SSLv2_RECEIVED_CLIENTMASTERKEY(self): 1231 pass 1232 1233 @ATMT.condition(SSLv2_RECEIVED_CLIENTMASTERKEY, prio=1) 1234 def sslv2_should_handle_ClientMasterKey(self): 1235 self.raise_on_packet(SSLv2ClientMasterKey, 1236 self.SSLv2_HANDLED_CLIENTMASTERKEY) 1237 1238 @ATMT.condition(SSLv2_RECEIVED_CLIENTMASTERKEY, prio=2) 1239 def missing_ClientMasterKey(self): 1240 raise self.SSLv2_MISSING_CLIENTMASTERKEY() 1241 1242 @ATMT.state() 1243 def SSLv2_MISSING_CLIENTMASTERKEY(self): 1244 self.vprint("Missing SSLv2 ClientMasterKey!") 1245 raise self.SSLv2_CLOSE_NOTIFY() 1246 1247 @ATMT.state() 1248 def SSLv2_HANDLED_CLIENTMASTERKEY(self): 1249 raise self.SSLv2_RECEIVED_CLIENTFINISHED() 1250 1251 @ATMT.state() 1252 def SSLv2_RECEIVED_CLIENTFINISHED(self): 1253 pass 1254 1255 @ATMT.condition(SSLv2_RECEIVED_CLIENTFINISHED, prio=1) 1256 def sslv2_should_handle_ClientFinished(self): 1257 self.raise_on_packet(SSLv2ClientFinished, 1258 self.SSLv2_HANDLED_CLIENTFINISHED) 1259 1260 @ATMT.state() 1261 def SSLv2_HANDLED_CLIENTFINISHED(self): 1262 pass 1263 1264 @ATMT.condition(SSLv2_HANDLED_CLIENTFINISHED, prio=1) 1265 def sslv2_should_add_ServerVerify_from_ClientFinished(self): 1266 if self.in_handshake(SSLv2ServerVerify): 1267 return 1268 self.add_record(is_sslv2=True) 1269 p = SSLv2ServerVerify(challenge=self.cur_session.sslv2_challenge) 1270 self.add_msg(p) 1271 raise self.SSLv2_ADDED_SERVERVERIFY() 1272 1273 @ATMT.condition(SSLv2_RECEIVED_CLIENTFINISHED, prio=2) 1274 def sslv2_should_add_ServerVerify_from_NoClientFinished(self): 1275 if self.in_handshake(SSLv2ServerVerify): 1276 return 1277 self.add_record(is_sslv2=True) 1278 p = SSLv2ServerVerify(challenge=self.cur_session.sslv2_challenge) 1279 self.add_msg(p) 1280 raise self.SSLv2_ADDED_SERVERVERIFY() 1281 1282 @ATMT.condition(SSLv2_RECEIVED_CLIENTFINISHED, prio=3) 1283 def sslv2_missing_ClientFinished(self): 1284 raise self.SSLv2_MISSING_CLIENTFINISHED() 1285 1286 @ATMT.state() 1287 def SSLv2_MISSING_CLIENTFINISHED(self): 1288 self.vprint("Missing SSLv2 ClientFinished!") 1289 raise self.SSLv2_CLOSE_NOTIFY() 1290 1291 @ATMT.state() 1292 def SSLv2_ADDED_SERVERVERIFY(self): 1293 pass 1294 1295 @ATMT.condition(SSLv2_ADDED_SERVERVERIFY) 1296 def sslv2_should_send_ServerVerify(self): 1297 self.flush_records() 1298 raise self.SSLv2_SENT_SERVERVERIFY() 1299 1300 @ATMT.state() 1301 def SSLv2_SENT_SERVERVERIFY(self): 1302 if self.in_handshake(SSLv2ClientFinished): 1303 raise self.SSLv2_HANDLED_CLIENTFINISHED() 1304 else: 1305 raise self.SSLv2_RECEIVED_CLIENTFINISHED() 1306 1307 # SSLv2 client authentication # 1308 1309 @ATMT.condition(SSLv2_HANDLED_CLIENTFINISHED, prio=2) 1310 def sslv2_should_add_RequestCertificate(self): 1311 if not self.client_auth or self.in_handshake(SSLv2RequestCertificate): 1312 return 1313 self.add_record(is_sslv2=True) 1314 self.add_msg(SSLv2RequestCertificate(challenge=randstring(16))) 1315 raise self.SSLv2_ADDED_REQUESTCERTIFICATE() 1316 1317 @ATMT.state() 1318 def SSLv2_ADDED_REQUESTCERTIFICATE(self): 1319 pass 1320 1321 @ATMT.condition(SSLv2_ADDED_REQUESTCERTIFICATE) 1322 def sslv2_should_send_RequestCertificate(self): 1323 self.flush_records() 1324 raise self.SSLv2_SENT_REQUESTCERTIFICATE() 1325 1326 @ATMT.state() 1327 def SSLv2_SENT_REQUESTCERTIFICATE(self): 1328 raise self.SSLv2_WAITING_CLIENTCERTIFICATE() 1329 1330 @ATMT.state() 1331 def SSLv2_WAITING_CLIENTCERTIFICATE(self): 1332 self.get_next_msg() 1333 raise self.SSLv2_RECEIVED_CLIENTCERTIFICATE() 1334 1335 @ATMT.state() 1336 def SSLv2_RECEIVED_CLIENTCERTIFICATE(self): 1337 pass 1338 1339 @ATMT.condition(SSLv2_RECEIVED_CLIENTCERTIFICATE, prio=1) 1340 def sslv2_should_handle_ClientCertificate(self): 1341 self.raise_on_packet(SSLv2ClientCertificate, 1342 self.SSLv2_HANDLED_CLIENTCERTIFICATE) 1343 1344 @ATMT.condition(SSLv2_RECEIVED_CLIENTCERTIFICATE, prio=2) 1345 def sslv2_missing_ClientCertificate(self): 1346 raise self.SSLv2_MISSING_CLIENTCERTIFICATE() 1347 1348 @ATMT.state() 1349 def SSLv2_MISSING_CLIENTCERTIFICATE(self): 1350 self.vprint("Missing SSLv2 ClientCertificate!") 1351 raise self.SSLv2_CLOSE_NOTIFY() 1352 1353 @ATMT.state() 1354 def SSLv2_HANDLED_CLIENTCERTIFICATE(self): 1355 self.vprint("Received client certificate...") 1356 # We could care about the client CA, but we don't. 1357 raise self.SSLv2_HANDLED_CLIENTFINISHED() 1358 1359 # end of SSLv2 client authentication # 1360 1361 @ATMT.condition(SSLv2_HANDLED_CLIENTFINISHED, prio=3) 1362 def sslv2_should_add_ServerFinished(self): 1363 self.add_record(is_sslv2=True) 1364 self.add_msg(SSLv2ServerFinished(sid=randstring(16))) 1365 raise self.SSLv2_ADDED_SERVERFINISHED() 1366 1367 @ATMT.state() 1368 def SSLv2_ADDED_SERVERFINISHED(self): 1369 pass 1370 1371 @ATMT.condition(SSLv2_ADDED_SERVERFINISHED) 1372 def sslv2_should_send_ServerFinished(self): 1373 self.flush_records() 1374 raise self.SSLv2_SENT_SERVERFINISHED() 1375 1376 @ATMT.state() 1377 def SSLv2_SENT_SERVERFINISHED(self): 1378 self.vprint("SSLv2 handshake completed!") 1379 self.vprint_sessioninfo() 1380 if self.is_echo_server: 1381 self.vprint("Will now act as a simple echo server.") 1382 raise self.SSLv2_WAITING_CLIENTDATA() 1383 1384 # end of SSLv2 handshake # 1385 1386 @ATMT.state() 1387 def SSLv2_WAITING_CLIENTDATA(self): 1388 self.get_next_msg(self.max_client_idle_time, 1) 1389 raise self.SSLv2_RECEIVED_CLIENTDATA() 1390 1391 @ATMT.state() 1392 def SSLv2_RECEIVED_CLIENTDATA(self): 1393 pass 1394 1395 @ATMT.condition(SSLv2_RECEIVED_CLIENTDATA) 1396 def sslv2_should_handle_ClientData(self): 1397 if not self.buffer_in: 1398 self.vprint("Client idle time maxed out.") 1399 raise self.SSLv2_CLOSE_NOTIFY() 1400 p = self.buffer_in[0] 1401 self.buffer_in = self.buffer_in[1:] 1402 if hasattr(p, "load"): 1403 cli_data = p.load 1404 print("> Received: %r" % cli_data) 1405 if cli_data.startswith(b"goodbye"): 1406 self.vprint() 1407 self.vprint("Seems like the client left...") 1408 raise self.WAITING_CLIENT() 1409 else: 1410 cli_data = str(p) 1411 print("> Received: %r" % p) 1412 1413 lines = cli_data.split(b"\n") 1414 for line in lines: 1415 if line.startswith(b"stop_server"): 1416 raise self.SSLv2_CLOSE_NOTIFY_FINAL() 1417 1418 if cli_data.startswith(b"GET / HTTP/1.1"): 1419 p = Raw(self.http_sessioninfo()) 1420 1421 if self.is_echo_server or cli_data.startswith(b"GET / HTTP/1.1"): 1422 self.add_record(is_sslv2=True) 1423 self.add_msg(p) 1424 raise self.SSLv2_ADDED_SERVERDATA() 1425 1426 raise self.SSLv2_HANDLED_CLIENTDATA() 1427 1428 @ATMT.state() 1429 def SSLv2_HANDLED_CLIENTDATA(self): 1430 raise self.SSLv2_WAITING_CLIENTDATA() 1431 1432 @ATMT.state() 1433 def SSLv2_ADDED_SERVERDATA(self): 1434 pass 1435 1436 @ATMT.condition(SSLv2_ADDED_SERVERDATA) 1437 def sslv2_should_send_ServerData(self): 1438 self.flush_records() 1439 raise self.SSLv2_SENT_SERVERDATA() 1440 1441 @ATMT.state() 1442 def SSLv2_SENT_SERVERDATA(self): 1443 raise self.SSLv2_WAITING_CLIENTDATA() 1444 1445 @ATMT.state() 1446 def SSLv2_CLOSE_NOTIFY(self): 1447 """ 1448 There is no proper way to end an SSLv2 session. 1449 We try and send a 'goodbye' message as a substitute. 1450 """ 1451 self.vprint() 1452 self.vprint("Trying to send 'goodbye' to the client...") 1453 1454 @ATMT.condition(SSLv2_CLOSE_NOTIFY) 1455 def sslv2_close_session(self): 1456 self.add_record() 1457 self.add_msg(Raw('goodbye')) 1458 try: 1459 self.flush_records() 1460 except Exception: 1461 self.vprint("Could not send our goodbye. The client probably left.") # noqa: E501 1462 self.buffer_out = [] 1463 self.socket.close() 1464 raise self.WAITING_CLIENT() 1465 1466 @ATMT.state() 1467 def SSLv2_CLOSE_NOTIFY_FINAL(self): 1468 """ 1469 There is no proper way to end an SSLv2 session. 1470 We try and send a 'goodbye' message as a substitute. 1471 """ 1472 self.vprint() 1473 self.vprint("Trying to send 'goodbye' to the client...") 1474 1475 @ATMT.condition(SSLv2_CLOSE_NOTIFY_FINAL) 1476 def sslv2_close_session_final(self): 1477 self.add_record() 1478 self.add_msg(Raw('goodbye')) 1479 try: 1480 self.flush_records() 1481 except Exception: 1482 self.vprint("Could not send our goodbye. The client probably left.") # noqa: E501 1483 self.socket.close() 1484 raise self.FINAL() 1485 1486 @ATMT.state(stop=True, final=True) 1487 def FINAL(self): 1488 self.vprint("Closing server socket...") 1489 self.serversocket.close() 1490 self.vprint("Ending TLS server automaton.") 1491