Coverage for oarepo_c4gh / crypt4gh / common / header_packet.py: 100%

43 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2025-12-06 16:58 +0000

1"""Header packet data structure. 

2 

3""" 

4 

5from ...exceptions import Crypt4GHHeaderPacketException 

6 

7 

8class HeaderPacket: 

9 """Represents a single Crypt4GH header packet. If it was possible 

10 to decrypt it, the parsed contents are made available as well. 

11 

12 """ 

13 

14 def __init__( 

15 self, 

16 packet_length, 

17 packet_data, 

18 content, 

19 reader_key, 

20 packet_type, 

21 data_encryption_method, 

22 data_encryption_key, 

23 lengths, 

24 ): 

25 """Initializes the packet structure with all fields given.""" 

26 self._packet_length = packet_length 

27 self._packet_data = packet_data 

28 self._content = content 

29 self._reader_key = reader_key 

30 self._packet_type = packet_type 

31 self._data_encryption_method = data_encryption_method 

32 self._data_encryption_key = data_encryption_key 

33 self._lengths = lengths 

34 

35 @property 

36 def is_data_encryption_parameters(self) -> bool: 

37 """A predicate for checking whether this packet contains DEK. 

38 

39 Returns: 

40 True if this packet was successfully decrypted and it is 

41 an encryption parameters type packet. 

42 

43 """ 

44 return self._content is not None and self._packet_type == 0 

45 

46 @property 

47 def data_encryption_key(self) -> bytes: 

48 """Getter for the symmetric encryption key. 

49 

50 Returns: 

51 32 bytes of the symmetric key. 

52 

53 Raises: 

54 Crypt4GHHeaderPacketException: if this packet does not contain DEK 

55 

56 """ 

57 if not self.is_data_encryption_parameters: 

58 raise Crypt4GHHeaderPacketException("No encryption key available.") 

59 return self._data_encryption_key 

60 

61 @property 

62 def is_edit_list(self) -> bool: 

63 """A predicate for checking whether this packet contains edit 

64 list. 

65 

66 Returns: 

67 True if it is a successfully decrypted edit list packet. 

68 

69 """ 

70 return self._content is not None and self._packet_type == 1 

71 

72 @property 

73 def is_readable(self) -> bool: 

74 """A predicate for checking whether the packet was 

75 successfully decrypted. 

76 

77 """ 

78 return self._content is not None 

79 

80 @property 

81 def reader_key(self) -> bytes: 

82 """Returns public key used for decrypting this header packet 

83 or None if the decryption was not successful. 

84 

85 """ 

86 return self._reader_key 

87 

88 @property 

89 def packet_data(self) -> bytes: 

90 """Returns the original packet data (for serialization).""" 

91 return self._packet_data 

92 

93 @property 

94 def packet_type(self) -> int: 

95 """Returns the numerical representation of packet type.""" 

96 return self._packet_type 

97 

98 @property 

99 def content(self) -> bytes: 

100 """Returns the encrypted packet content.""" 

101 return self._content 

102 

103 @property 

104 def length(self) -> int: 

105 """Returns the packet length in bytes - including the packet 

106 length 4-byte value at the beginning. 

107 

108 """ 

109 return self._packet_length 

110 

111 @property 

112 def lengths(self) -> list[int]: 

113 """Returns the alternating skip and keep lengths of an edit 

114 list. This is valid only if `is_edit_list` is true. 

115 

116 """ 

117 return self._lengths