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