The PRF used by SSL/TLS varies based on the version of the protocol and (for TLS 1.2) possibly the Hash algorithm of the negotiated cipher suite. The various uses of the PRF (key derivation, computation of verify_data, computation of pre_master_secret values) for the different versi
| 175 | |
| 176 | |
| 177 | class PRF(object): |
| 178 | """ |
| 179 | The PRF used by SSL/TLS varies based on the version of the protocol and |
| 180 | (for TLS 1.2) possibly the Hash algorithm of the negotiated cipher suite. |
| 181 | The various uses of the PRF (key derivation, computation of verify_data, |
| 182 | computation of pre_master_secret values) for the different versions of the |
| 183 | protocol also changes. In order to abstract those elements, the common |
| 184 | _tls_PRF() object is provided. It is expected to be initialised in the |
| 185 | context of the connection state using the tls_version and the cipher suite. |
| 186 | """ |
| 187 | |
| 188 | def __init__(self, hash_name="SHA256", tls_version=0x0303): |
| 189 | self.tls_version = tls_version |
| 190 | self.hash_name = hash_name |
| 191 | |
| 192 | if tls_version < 0x0300: # SSLv2 |
| 193 | self.prf = _sslv2_PRF |
| 194 | elif tls_version == 0x0300: # SSLv3 |
| 195 | self.prf = _ssl_PRF |
| 196 | elif (tls_version == 0x0301 or # TLS 1.0 |
| 197 | tls_version == 0x0302): # TLS 1.1 |
| 198 | self.prf = _tls_PRF |
| 199 | elif tls_version == 0x0303: # TLS 1.2 |
| 200 | if hash_name == "SHA384": |
| 201 | self.prf = _tls12_SHA384PRF |
| 202 | elif hash_name == "SHA512": |
| 203 | self.prf = _tls12_SHA512PRF |
| 204 | else: |
| 205 | if hash_name in ["MD5", "SHA"]: |
| 206 | self.hash_name = "SHA256" |
| 207 | self.prf = _tls12_SHA256PRF |
| 208 | else: |
| 209 | warning("Unknown TLS version") |
| 210 | |
| 211 | def compute_master_secret(self, pre_master_secret, client_random, |
| 212 | server_random, extms=False, handshake_hash=None): |
| 213 | """ |
| 214 | Return the 48-byte master_secret, computed from pre_master_secret, |
| 215 | client_random and server_random. See RFC 5246, section 6.3. |
| 216 | Supports Extended Master Secret Derivation, see RFC 7627 |
| 217 | """ |
| 218 | seed = client_random + server_random |
| 219 | label = b'master secret' |
| 220 | |
| 221 | if extms is True and handshake_hash is not None: |
| 222 | seed = handshake_hash |
| 223 | label = b'extended master secret' |
| 224 | |
| 225 | if self.tls_version < 0x0300: |
| 226 | return None |
| 227 | elif self.tls_version == 0x0300: |
| 228 | return self.prf(pre_master_secret, seed, 48) |
| 229 | else: |
| 230 | return self.prf(pre_master_secret, label, seed, 48) |
| 231 | |
| 232 | def derive_key_block(self, master_secret, server_random, |
| 233 | client_random, req_len): |
| 234 | """ |
no outgoing calls
no test coverage detected