Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/scapy/layers/tls/crypto/hash.py: 76%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

75 statements  

1# SPDX-License-Identifier: GPL-2.0-only 

2# This file is part of Scapy 

3# See https://scapy.net/ for more information 

4# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard 

5# 2015, 2016 Maxence Tury 

6 

7""" 

8Hash classes. 

9""" 

10 

11from scapy.config import conf, crypto_validator 

12from scapy.layers.tls.crypto.md4 import MD4 as md4 

13 

14if conf.crypto_valid: 

15 from cryptography.hazmat.backends import default_backend 

16 from cryptography.hazmat.primitives import hashes 

17 from cryptography.hazmat.primitives.hashes import ( 

18 MD5, 

19 SHA1, 

20 SHA224, 

21 SHA256, 

22 SHA384, 

23 SHA512, 

24 SHAKE256, 

25 ) 

26 from cryptography.hazmat.primitives.hashes import HashAlgorithm 

27else: 

28 MD5 = SHA1 = SHA224 = SHA256 = SHA384 = SHA512 = SHAKE256 = None 

29 HashAlgorithm = object 

30 

31_tls_hash_algs = {} 

32 

33 

34class _GenericHashMetaclass(type): 

35 """ 

36 Hash classes are automatically registered through this metaclass. 

37 Furthermore, their name attribute is extracted from their class name. 

38 """ 

39 

40 def __new__(cls, hash_name, bases, dct): 

41 if hash_name != "_GenericHash": 

42 dct["name"] = hash_name[5:].lower() # remove leading "Hash_" 

43 the_class = super(_GenericHashMetaclass, cls).__new__( 

44 cls, hash_name, bases, dct 

45 ) 

46 if hash_name != "_GenericHash": 

47 _tls_hash_algs[dct["name"]] = the_class 

48 return the_class 

49 

50 

51class _GenericHash(metaclass=_GenericHashMetaclass): 

52 def digest(self, tbd): 

53 digest = hashes.Hash(self.hash_cls(), backend=default_backend()) 

54 digest.update(tbd) 

55 return digest.finalize() 

56 

57 

58class Hash_NULL(_GenericHash): 

59 hash_len = 0 

60 

61 def digest(self, tbd): 

62 return b"" 

63 

64 

65class Hash_MD4(_GenericHash): 

66 hash_cls = md4 

67 hash_len = 16 

68 

69 def digest(self, tbd): 

70 return self.hash_cls(tbd).digest() 

71 

72 

73class Hash_MD5(_GenericHash): 

74 hash_cls = MD5 

75 hash_len = 16 

76 

77 

78class Hash_SHA(_GenericHash): 

79 hash_cls = SHA1 

80 hash_len = 20 

81 

82 

83_tls_hash_algs["sha1"] = Hash_SHA 

84 

85 

86class Hash_SHA224(_GenericHash): 

87 hash_cls = SHA224 

88 hash_len = 28 

89 

90 

91class Hash_SHA256(_GenericHash): 

92 hash_cls = SHA256 

93 hash_len = 32 

94 

95 

96class Hash_SHA384(_GenericHash): 

97 hash_cls = SHA384 

98 hash_len = 48 

99 

100 

101class Hash_SHA512(_GenericHash): 

102 hash_cls = SHA512 

103 hash_len = 64 

104 

105 

106# first, we add the "md5-sha1" hash from openssl to python-cryptography 

107class MD5_SHA1(HashAlgorithm): 

108 name = "md5-sha1" 

109 digest_size = 36 

110 block_size = 64 

111 

112 

113class Hash_MD5SHA1(_GenericHash): 

114 hash_cls = MD5_SHA1 

115 hash_len = 36 

116 

117 

118_tls_hash_algs["md5-sha1"] = Hash_MD5SHA1 

119 

120 

121class Hash_SHAKE256(_GenericHash): 

122 hash_cls = SHAKE256 

123 

124 def __init__(self, digest_size: int): 

125 self.hash_len = digest_size 

126 

127 def digest(self, tbd): 

128 digest = hashes.Hash(self.hash_cls(self.hash_len), backend=default_backend()) 

129 digest.update(tbd) 

130 return digest.finalize() 

131 

132 

133@crypto_validator 

134def _get_hash(hashStr): 

135 """ 

136 Return a cryptography-hash by its name 

137 """ 

138 try: 

139 return _tls_hash_algs[hashStr].hash_cls() 

140 except KeyError: 

141 raise KeyError("Unknown hash function %s" % hashStr)