Home | History | Annotate | Download | only in patches
      1 diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py
      2 index d132b78..ceaa903 100755
      3 --- a/third_party/tlslite/tlslite/constants.py
      4 +++ b/third_party/tlslite/tlslite/constants.py
      5 @@ -30,6 +30,7 @@ class HandshakeType:
      6      certificate_verify = 15
      7      client_key_exchange = 16
      8      finished = 20
      9 +    certificate_status = 22
     10      next_protocol = 67
     11      encrypted_extensions = 203
     12  
     13 @@ -40,8 +41,12 @@ class ContentType:
     14      application_data = 23
     15      all = (20,21,22,23)
     16  
     17 +class CertificateStatusType:
     18 +    ocsp = 1
     19 +
     20  class ExtensionType:    # RFC 6066 / 4366
     21      server_name = 0     # RFC 6066 / 4366
     22 +    status_request = 5  # RFC 6066 / 4366
     23      srp = 12            # RFC 5054  
     24      cert_type = 9       # RFC 6091
     25      signed_cert_timestamps = 18  # RFC 6962
     26 diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py
     27 index 5a2cd6c..532d86b 100755
     28 --- a/third_party/tlslite/tlslite/messages.py
     29 +++ b/third_party/tlslite/tlslite/messages.py
     30 @@ -114,6 +114,7 @@ class ClientHello(HandshakeMsg):
     31          self.server_name = bytearray(0)
     32          self.channel_id = False
     33          self.support_signed_cert_timestamps = False
     34 +        self.status_request = False
     35  
     36      def create(self, version, random, session_id, cipher_suites,
     37                 certificate_types=None, srpUsername=None,
     38 @@ -187,6 +188,19 @@ class ClientHello(HandshakeMsg):
     39                          if extLength:
     40                              raise SyntaxError()
     41                          self.support_signed_cert_timestamps = True
     42 +                    elif extType == ExtensionType.status_request:
     43 +                        # Extension contents are currently ignored.
     44 +                        # According to RFC 6066, this is not strictly forbidden
     45 +                        # (although it is suboptimal):
     46 +                        # Servers that receive a client hello containing the
     47 +                        # "status_request" extension MAY return a suitable
     48 +                        # certificate status response to the client along with
     49 +                        # their certificate.  If OCSP is requested, they
     50 +                        # SHOULD use the information contained in the extension
     51 +                        # when selecting an OCSP responder and SHOULD include
     52 +                        # request_extensions in the OCSP request.
     53 +                        p.getFixBytes(extLength)
     54 +                        self.status_request = True
     55                      else:
     56                          _ = p.getFixBytes(extLength)
     57                      index2 = p.index
     58 @@ -253,6 +267,7 @@ class ServerHello(HandshakeMsg):
     59          self.next_protos = None
     60          self.channel_id = False
     61          self.signed_cert_timestamps = None
     62 +        self.status_request = False
     63  
     64      def create(self, version, random, session_id, cipher_suite,
     65                 certificate_type, tackExt, next_protos_advertised):
     66 @@ -345,6 +360,9 @@ class ServerHello(HandshakeMsg):
     67          if self.signed_cert_timestamps:
     68              w2.add(ExtensionType.signed_cert_timestamps, 2)
     69              w2.addVarSeq(bytearray(self.signed_cert_timestamps), 1, 2)
     70 +        if self.status_request:
     71 +            w2.add(ExtensionType.status_request, 2)
     72 +            w2.add(0, 2)
     73          if len(w2.bytes):
     74              w.add(len(w2.bytes), 2)
     75              w.bytes += w2.bytes        
     76 @@ -402,6 +420,37 @@ class Certificate(HandshakeMsg):
     77              raise AssertionError()
     78          return self.postWrite(w)
     79  
     80 +class CertificateStatus(HandshakeMsg):
     81 +    def __init__(self):
     82 +        HandshakeMsg.__init__(self, HandshakeType.certificate_status)
     83 +
     84 +    def create(self, ocsp_response):
     85 +        self.ocsp_response = ocsp_response
     86 +        return self
     87 +
     88 +    # Defined for the sake of completeness, even though we currently only
     89 +    # support sending the status message (server-side), not requesting
     90 +    # or receiving it (client-side).
     91 +    def parse(self, p):
     92 +        p.startLengthCheck(3)
     93 +        status_type = p.get(1)
     94 +        # Only one type is specified, so hardwire it.
     95 +        if status_type != CertificateStatusType.ocsp:
     96 +            raise SyntaxError()
     97 +        ocsp_response = p.getVarBytes(3)
     98 +        if not ocsp_response:
     99 +            # Can't be empty
    100 +            raise SyntaxError()
    101 +        self.ocsp_response = ocsp_response
    102 +        p.stopLengthCheck()
    103 +        return self
    104 +
    105 +    def write(self):
    106 +        w = Writer()
    107 +        w.add(CertificateStatusType.ocsp, 1)
    108 +        w.addVarSeq(bytearray(self.ocsp_response), 1, 3)
    109 +        return self.postWrite(w)
    110 +
    111  class CertificateRequest(HandshakeMsg):
    112      def __init__(self):
    113          HandshakeMsg.__init__(self, HandshakeType.certificate_request)
    114 diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py
    115 index bd92161..b9797d2 100755
    116 --- a/third_party/tlslite/tlslite/tlsconnection.py
    117 +++ b/third_party/tlslite/tlslite/tlsconnection.py
    118 @@ -967,7 +967,7 @@ class TLSConnection(TLSRecordLayer):
    119                          tacks=None, activationFlags=0,
    120                          nextProtos=None, anon=False,
    121                          tlsIntolerant=None, signedCertTimestamps=None,
    122 -                        fallbackSCSV=False):
    123 +                        fallbackSCSV=False, ocspResponse=None):
    124          """Perform a handshake in the role of server.
    125  
    126          This function performs an SSL or TLS handshake.  Depending on
    127 @@ -1051,6 +1051,16 @@ class TLSConnection(TLSRecordLayer):
    128          TLS_FALLBACK_SCSV and thus reject connections using less than the
    129          server's maximum TLS version that include this cipher suite.
    130  
    131 +        @type ocspResponse: str
    132 +        @param ocspResponse: An OCSP response (as a binary 8-bit string) that
    133 +        will be sent stapled in the handshake whenever the client announces
    134 +        support for the status_request extension.
    135 +        Note that the response is sent independent of the ClientHello
    136 +        status_request extension contents, and is thus only meant for testing
    137 +        environments. Real OCSP stapling is more complicated as it requires
    138 +        choosing a suitable response based on the ClientHello status_request
    139 +        extension contents.
    140 +
    141          @raise socket.error: If a socket error occurs.
    142          @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
    143          without a preceding alert.
    144 @@ -1064,7 +1074,7 @@ class TLSConnection(TLSRecordLayer):
    145                  tacks=tacks, activationFlags=activationFlags, 
    146                  nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant,
    147                  signedCertTimestamps=signedCertTimestamps,
    148 -                fallbackSCSV=fallbackSCSV):
    149 +                fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse):
    150              pass
    151  
    152  
    153 @@ -1076,7 +1086,8 @@ class TLSConnection(TLSRecordLayer):
    154                               nextProtos=None, anon=False,
    155                               tlsIntolerant=None,
    156                               signedCertTimestamps=None,
    157 -                             fallbackSCSV=False
    158 +                             fallbackSCSV=False,
    159 +                             ocspResponse=None
    160                               ):
    161          """Start a server handshake operation on the TLS connection.
    162  
    163 @@ -1098,7 +1109,8 @@ class TLSConnection(TLSRecordLayer):
    164              nextProtos=nextProtos, anon=anon,
    165              tlsIntolerant=tlsIntolerant,
    166              signedCertTimestamps=signedCertTimestamps,
    167 -            fallbackSCSV=fallbackSCSV)
    168 +            fallbackSCSV=fallbackSCSV,
    169 +            ocspResponse=ocspResponse)
    170          for result in self._handshakeWrapperAsync(handshaker, checker):
    171              yield result
    172  
    173 @@ -1108,7 +1120,8 @@ class TLSConnection(TLSRecordLayer):
    174                               settings, reqCAs, 
    175                               tacks, activationFlags, 
    176                               nextProtos, anon,
    177 -                             tlsIntolerant, signedCertTimestamps, fallbackSCSV):
    178 +                             tlsIntolerant, signedCertTimestamps, fallbackSCSV,
    179 +                             ocspResponse):
    180  
    181          self._handshakeStart(client=False)
    182  
    183 @@ -1178,6 +1191,8 @@ class TLSConnection(TLSRecordLayer):
    184          serverHello.channel_id = clientHello.channel_id
    185          if clientHello.support_signed_cert_timestamps:
    186              serverHello.signed_cert_timestamps = signedCertTimestamps
    187 +        if clientHello.status_request:
    188 +            serverHello.status_request = ocspResponse
    189  
    190          # Perform the SRP key exchange
    191          clientCertChain = None
    192 @@ -1194,7 +1209,7 @@ class TLSConnection(TLSRecordLayer):
    193              for result in self._serverCertKeyExchange(clientHello, serverHello, 
    194                                          certChain, privateKey,
    195                                          reqCert, reqCAs, cipherSuite,
    196 -                                        settings):
    197 +                                        settings, ocspResponse):
    198                  if result in (0,1): yield result
    199                  else: break
    200              (premasterSecret, clientCertChain) = result
    201 @@ -1471,7 +1486,7 @@ class TLSConnection(TLSRecordLayer):
    202      def _serverCertKeyExchange(self, clientHello, serverHello, 
    203                                  serverCertChain, privateKey,
    204                                  reqCert, reqCAs, cipherSuite,
    205 -                                settings):
    206 +                                settings, ocspResponse):
    207          #Send ServerHello, Certificate[, CertificateRequest],
    208          #ServerHelloDone
    209          msgs = []
    210 @@ -1481,6 +1496,8 @@ class TLSConnection(TLSRecordLayer):
    211  
    212          msgs.append(serverHello)
    213          msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
    214 +        if serverHello.status_request:
    215 +            msgs.append(CertificateStatus().create(ocspResponse))
    216          if reqCert and reqCAs:
    217              msgs.append(CertificateRequest().create(\
    218                  [ClientCertificateType.rsa_sign], reqCAs))
    219