1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch# Authors:
2a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#   Trevor Perrin
3a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#   Dave Baggett (Arcode Corporation) - Added TLSUnsupportedError.
4a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#
5a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch# See the LICENSE file for legal information regarding use of this file.
6a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""Exception classes.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@sort: TLSError, TLSAbruptCloseError, TLSAlert, TLSLocalAlert, TLSRemoteAlert,
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TLSAuthenticationError, TLSNoAuthenticationError, TLSAuthenticationTypeError,
10a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochTLSFingerprintError, TLSAuthorizationError, TLSValidationError, TLSFaultError,
11a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochTLSUnsupportedError
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""
13a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochimport socket
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochfrom .constants import AlertDescription, AlertLevel
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TLSError(Exception):
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Base class for all TLS Lite exceptions."""
19a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
20a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    def __str__(self):
21a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        """"At least print out the Exception time for str(...)."""
22a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        return repr(self)
23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
24a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass TLSClosedConnectionError(TLSError, socket.error):
25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    """An attempt was made to use the connection after it was closed."""
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pass
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TLSAbruptCloseError(TLSError):
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """The socket was closed without a proper TLS shutdown.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    The TLS specification mandates that an alert of some sort
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    must be sent before the underlying socket is closed.  If the socket
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is closed without this, it could signify that an attacker is trying
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to truncate the connection.  It could also signify a misbehaving
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TLS implementation, or a random network failure.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pass
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TLSAlert(TLSError):
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """A TLS alert has been signalled."""
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pass
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    _descriptionStr = {\
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.close_notify: "close_notify",\
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.unexpected_message: "unexpected_message",\
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.bad_record_mac: "bad_record_mac",\
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.decryption_failed: "decryption_failed",\
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.record_overflow: "record_overflow",\
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.decompression_failure: "decompression_failure",\
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.handshake_failure: "handshake_failure",\
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.no_certificate: "no certificate",\
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.bad_certificate: "bad_certificate",\
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.unsupported_certificate: "unsupported_certificate",\
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.certificate_revoked: "certificate_revoked",\
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.certificate_expired: "certificate_expired",\
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.certificate_unknown: "certificate_unknown",\
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.illegal_parameter: "illegal_parameter",\
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.unknown_ca: "unknown_ca",\
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.access_denied: "access_denied",\
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.decode_error: "decode_error",\
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.decrypt_error: "decrypt_error",\
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.export_restriction: "export_restriction",\
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.protocol_version: "protocol_version",\
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.insufficient_security: "insufficient_security",\
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.internal_error: "internal_error",\
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        AlertDescription.inappropriate_fallback: "inappropriate_fallback",\
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.user_canceled: "user_canceled",\
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AlertDescription.no_renegotiation: "no_renegotiation",\
69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        AlertDescription.unknown_psk_identity: "unknown_psk_identity"}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TLSLocalAlert(TLSAlert):
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """A TLS alert has been signalled by the local implementation.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @type description: int
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @ivar description: Set to one of the constants in
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L{tlslite.constants.AlertDescription}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @type level: int
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @ivar level: Set to one of the constants in
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L{tlslite.constants.AlertLevel}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @type message: str
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @ivar message: Description of what went wrong.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def __init__(self, alert, message=None):
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.description = alert.description
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.level = alert.level
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.message = message
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def __str__(self):
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        alertStr = TLSAlert._descriptionStr.get(self.description)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if alertStr == None:
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            alertStr = str(self.description)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if self.message:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return alertStr + ": " + self.message
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else:
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return alertStr
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TLSRemoteAlert(TLSAlert):
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """A TLS alert has been signalled by the remote implementation.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @type description: int
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @ivar description: Set to one of the constants in
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L{tlslite.constants.AlertDescription}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @type level: int
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @ivar level: Set to one of the constants in
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L{tlslite.constants.AlertLevel}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def __init__(self, alert):
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.description = alert.description
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.level = alert.level
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def __str__(self):
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        alertStr = TLSAlert._descriptionStr.get(self.description)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if alertStr == None:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            alertStr = str(self.description)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return alertStr
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TLSAuthenticationError(TLSError):
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """The handshake succeeded, but the other party's authentication
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    was inadequate.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    This exception will only be raised when a
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L{tlslite.Checker.Checker} has been passed to a handshake function.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    The Checker will be invoked once the handshake completes, and if
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    the Checker objects to how the other party authenticated, a
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    subclass of this exception will be raised.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pass
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TLSNoAuthenticationError(TLSAuthenticationError):
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """The Checker was expecting the other party to authenticate with a
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    certificate chain, but this did not occur."""
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pass
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TLSAuthenticationTypeError(TLSAuthenticationError):
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """The Checker was expecting the other party to authenticate with a
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    different type of certificate chain."""
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pass
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TLSFingerprintError(TLSAuthenticationError):
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """The Checker was expecting the other party to authenticate with a
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    certificate chain that matches a different fingerprint."""
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pass
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TLSAuthorizationError(TLSAuthenticationError):
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """The Checker was expecting the other party to authenticate with a
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    certificate chain that has a different authorization."""
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pass
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TLSValidationError(TLSAuthenticationError):
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """The Checker has determined that the other party's certificate
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chain is invalid."""
155a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    def __init__(self, msg, info=None):
156a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        # Include a dict containing info about this validation failure
157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        TLSAuthenticationError.__init__(self, msg)
158a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        self.info = info
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TLSFaultError(TLSError):
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """The other party responded incorrectly to an induced fault.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    This exception will only occur during fault testing, when a
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TLSConnection's fault variable is set to induce some sort of
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    faulty behavior, and the other party doesn't respond appropriately.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pass
168a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
169a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
170a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass TLSUnsupportedError(TLSError):
171a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    """The implementation doesn't support the requested (or required)
172a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    capabilities."""
173a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    pass
174