# Path: src/net/tls/common.py
# class TLSError(Exception):
#     """
#     Base class for all TLS/SSL exceptions.
# 
#     Exception args is a message string.
#     """
#     pass
# 
# class TLSProtocolError(TLSError):
#     """
#     Raised when a protocol-related problem occurs, such as the remote end does
#     not speak TLS, or when no shared cipher could be established.
#     """
#     pass
# 
# class TLSVerificationError(TLSError):
#     """
#     Raised when the remote end's certificate did not verify correctly.
#     """
#     pass
# 
# class TLSSocketBase(kaa.Socket):
#     # list of suuported TLS authentication mechanisms (subclass must override)
#     supported_methods = []
#     
#     # Cached system-wide CA cert file (as detected), or None if none was found.
#     _cafile = False
# 
#     __kaasignals__ = {
#         'tls':
#             '''
#             Emitted when a TLS handshake has been successfully completed.
#             '''
#     }
# 
#     def __init__(self, cafile=None):
#         super(TLSSocketBase, self).__init__()
#         self._handshake = False
#         self._pre_handshake_write_queue = []
# 
#         if cafile:
#             self._cafile = cafile
#         elif TLSSocketBase._cafile is False:
#             self._cafile = None
#             for path in CA_SEARCH_PATH:
#                 if os.path.exists(path):
#                     cafile = path
#                     break
#             else:
#                 # Maybe locate(1) can help.
#                 # XXX: assumes this is fast.  Maybe this should be done async.
#                 path = os.popen('locate -l 1 ca-certificates.crt ca-bundle.crt 2>/dev/null').readline().strip()
#                 if os.path.exists(path):
#                     cafile = path
# 
#             TLSSocketBase._cafile = self._cafile = cafile


import logging
import os
import M2Crypto
import kaa
from M2Crypto import m2, X509
from .common import TLSError, TLSProtocolError, TLSVerificationError, TLSSocketBase
                raise TLSVerificationError('Peer certificate is not signed by a known CA')

        x509 = self._m2_check_err(m2.ssl_get_peer_cert(self._ssl.obj), TLSVerificationError)
        if x509 is not None:
            self.peer_cert = X509.X509(x509, 1)
        else:
            self.peer_cert = None

        if 'check' in kwargs or self.peer_cert:
            check = kwargs.get('check', (None, None))
            if check[0] is None:
                # Validate peer CN by default.
                host = self.peer[5]
            elif check[0] is False:
                # User requested to disable CN verification.
                host = None
            else:
                # User override for peer CN.
                host = check[0]
            fingerprint = check[1] if len(check) > 1 else None
            # TODO: normalize exceptions raised by Checker.
            M2Crypto.SSL.Checker.Checker(host, fingerprint)(self.peer_cert)

        self._validated = True


    def _read(self, chunk):
        data = super(M2TLSSocket, self)._read(chunk)
        if not self._tls_started or not data:
            if self._tls_started and not self._tls_ip.finished:

# Path: src/net/tls/common.py
# class TLSError(Exception):
#     """
#     Base class for all TLS/SSL exceptions.
# 
#     Exception args is a message string.
#     """
#     pass
# 
# class TLSProtocolError(TLSError):
#     """
#     Raised when a protocol-related problem occurs, such as the remote end does
#     not speak TLS, or when no shared cipher could be established.
#     """
#     pass
# 
# class TLSVerificationError(TLSError):
#     """
#     Raised when the remote end's certificate did not verify correctly.
#     """
#     pass
# 
# class TLSSocketBase(kaa.Socket):
#     # list of suuported TLS authentication mechanisms (subclass must override)
#     supported_methods = []
#     
#     # Cached system-wide CA cert file (as detected), or None if none was found.
#     _cafile = False
# 
#     __kaasignals__ = {
#         'tls':
#             '''
#             Emitted when a TLS handshake has been successfully completed.
#             '''
#     }
# 
#     def __init__(self, cafile=None):
#         super(TLSSocketBase, self).__init__()
#         self._handshake = False
#         self._pre_handshake_write_queue = []
# 
#         if cafile:
#             self._cafile = cafile
#         elif TLSSocketBase._cafile is False:
#             self._cafile = None
#             for path in CA_SEARCH_PATH:
#                 if os.path.exists(path):
#                     cafile = path
#                     break
#             else:
#                 # Maybe locate(1) can help.
#                 # XXX: assumes this is fast.  Maybe this should be done async.
#                 path = os.popen('locate -l 1 ca-certificates.crt ca-bundle.crt 2>/dev/null').readline().strip()
#                 if os.path.exists(path):
#                     cafile = path
# 
#             TLSSocketBase._cafile = self._cafile = cafile


# Path: src/net/tls/m2.py
import logging
import os
import M2Crypto
import kaa
from M2Crypto import m2, X509
from .common import TLSError, TLSProtocolError, TLSVerificationError, TLSSocketBase

                raise TLSVerificationError('Peer certificate is not signed by a known CA')

        x509 = self._m2_check_err(m2.ssl_get_peer_cert(self._ssl.obj), TLSVerificationError)
        if x509 is not None:
            self.peer_cert = X509.X509(x509, 1)
        else:
            self.peer_cert = None

        if 'check' in kwargs or self.peer_cert:
            check = kwargs.get('check', (None, None))
            if check[0] is None:
                # Validate peer CN by default.
                host = self.peer[5]
            elif check[0] is False:
                # User requested to disable CN verification.
                host = None
            else:
                # User override for peer CN.
                host = check[0]
            fingerprint = check[1] if len(check) > 1 else None
            # TODO: normalize exceptions raised by Checker.
            M2Crypto.SSL.Checker.Checker(host, fingerprint)(self.peer_cert)

        self._validated = True


    def _read(self, chunk):
        data = super(M2TLSSocket, self)._read(chunk)
        if not self._tls_started or not data:
            if self._tls_started and not self._tls_ip.finished:

                e = TLSProtocolError('Peer terminated connection before TLS handshake completed')