1
2
3
4 """Class for post-handshake certificate checking."""
5
6 from .x509 import X509
7 from .x509certchain import X509CertChain
8 from .errors import *
9 from .utils.tackwrapper import *
10
11
13 """This class is passed to a handshake function to check the other
14 party's certificate chain.
15
16 If a handshake function completes successfully, but the Checker
17 judges the other party's certificate chain to be missing or
18 inadequate, a subclass of
19 L{tlslite.errors.TLSAuthenticationError} will be raised.
20
21 Currently, the Checker can check an X.509 chain.
22 """
23
24 - def __init__(self,
25 x509Fingerprint=None,
26 tackID=None,
27 hardTack=None,
28 checkResumedSession=False):
29 """Create a new Checker instance.
30
31 You must pass in one of these argument combinations:
32 - x509Fingerprint
33
34 @type x509Fingerprint: str
35 @param x509Fingerprint: A hex-encoded X.509 end-entity
36 fingerprint which the other party's end-entity certificate must
37 match.
38
39 @type tackID: str
40 @param tackID: TACK ID for server authentication.
41
42 @type hardTack: bool
43 @param hardTack: Whether to raise TackBreakSigError on TACK Break.
44
45 @type checkResumedSession: bool
46 @param checkResumedSession: If resumed sessions should be
47 checked. This defaults to False, on the theory that if the
48 session was checked once, we don't need to bother
49 re-checking it.
50 """
51
52 if tackID and not tackpyLoaded:
53 raise ValueError("TACKpy not loaded")
54 if tackID and hardTack == None:
55 raise ValueError("hardTack must be set with tackID")
56 self.x509Fingerprint = x509Fingerprint
57 self.tackID = tackID
58 self.hardTack = hardTack
59 self.checkResumedSession = checkResumedSession
60
62 """Check a TLSConnection.
63
64 When a Checker is passed to a handshake function, this will
65 be called at the end of the function.
66
67 @type connection: L{tlslite.tlsconnection.TLSConnection}
68 @param connection: The TLSConnection to examine.
69
70 @raise tlslite.errors.TLSAuthenticationError: If the other
71 party's certificate chain is missing or bad.
72 """
73 if not self.checkResumedSession and connection.resumed:
74 return
75
76 if self.x509Fingerprint:
77 if connection._client:
78 chain = connection.session.serverCertChain
79 else:
80 chain = connection.session.clientCertChain
81
82 if self.x509Fingerprint:
83 if isinstance(chain, X509CertChain):
84 if self.x509Fingerprint:
85 if chain.getFingerprint() != self.x509Fingerprint:
86 raise TLSFingerprintError(\
87 "X.509 fingerprint mismatch: %s, %s" % \
88 (chain.getFingerprint(), self.x509Fingerprint))
89 elif chain:
90 raise TLSAuthenticationTypeError()
91 else:
92 raise TLSNoAuthenticationError()
93
94 if self.tackID:
95 tackID = connection.session.getTACKID()
96
97 if not tackID:
98 raise TLSTackMissingError()
99
100 if tackID == self.tackID:
101 return
102
103
104 breakSigs = connection.session.getBreakSigs()
105 if breakSigs:
106 if self.tackID in [bs.getTACKID() for bs in breakSigs]:
107
108
109 if self.hardTack:
110 raise TLSTackBreakError()
111 else:
112
113 return
114
115
116 raise TLSTackMismatchError()
117