11from core .requests import http_request
22from logic .storage import save_account_data
3- from logic .pfs import send_new_ephemeral_keys , rotate_ephemeral_keys
3+ from logic .pfs import send_new_ephemeral_keys
44from core .crypto import *
55from core .constants import *
66from base64 import b64decode , b64encode
@@ -74,10 +74,12 @@ def send_message_processor(user_data, user_data_lock, contact_id: str, message:
7474
7575
7676 contact_kyber_public_key = user_data ["contacts" ][contact_id ]["ephemeral_keys" ]["contact_public_key" ]
77- our_d5_private_key = user_data ["contacts" ][contact_id ]["message_sign_keys " ]["our_keys" ]["private_key" ]
77+ our_lt_private_key = user_data ["contacts" ][contact_id ]["lt_sign_keys " ]["our_keys" ]["private_key" ]
7878
7979
80- if (not contact_kyber_public_key ) or (not our_d5_private_key ):
80+
81+ if (not contact_kyber_public_key ):
82+ logger .debug ("This shouldn't usually happen, contact kyber keys are not initialized even once yet???" )
8183 ui_queue .put ({
8284 "type" : "showwarning" ,
8385 "title" : f"Warning for { contact_id [:32 ]} " ,
@@ -88,41 +90,46 @@ def send_message_processor(user_data, user_data_lock, contact_id: str, message:
8890 return False
8991
9092
91- with user_data_lock :
92- our_pads_empty = bool (user_data ["contacts" ][contact_id ]["our_pads" ]["pads" ])
9393
94+ with user_data_lock :
95+ our_pads = user_data ["contacts" ][contact_id ]["our_pads" ]["pads" ]
9496
95- # If we have keys, but not enough one-time-pads, we send new pads to the contact
96- if not our_pads_empty :
97- logger .debug ("Not enough pads to send message" )
97+ # If we have keys, but no one-time-pads, we send new pads to the contact
98+ if not our_pads :
99+ logger .debug ("We have no pads to send message" )
98100
99- if not generate_and_send_pads (user_data , user_data_lock , contact_id , contact_kyber_public_key , our_d5_private_key , ui_queue ):
100- return False
101-
102-
103101 with user_data_lock :
104- # Increment the rotation_counter
105- user_data ["contacts" ][contact_id ]["ephemeral_keys" ]["rotation_counter" ] += 1
106-
102+
107103 rotation_counter = user_data ["contacts" ][contact_id ]["ephemeral_keys" ]["rotation_counter" ]
108104 rotate_at = user_data ["contacts" ][contact_id ]["ephemeral_keys" ]["rotate_at" ]
109105
110-
111- logger .debug ("Incremented rotation_counter by 1. (%d)" , rotation_counter )
112106
113- # See if we should rotate our keys
107+ # We rotate keys before generating and sending new batch of pads because
108+ # ephemeral key exchanges always get processed before messages do.
109+ # Which means if we generate and send pads with contact's, we would be using his old key, which would get overriden by the request, even if we send pads first
110+ # This is because of our server archiecture which prioritizes PFS requests before messages.
111+ #
114112 if rotation_counter == rotate_at :
115113 logger .info ("We are rotating our ephemeral keys for contact (%s)" , contact_id )
116114 ui_queue .put ({"type" : "showinfo" , "title" : "Perfect Forward Secrecy" , "message" : f"We are rotating our ephemeral keys for contact ({ contact_id [:32 ]} )" })
117- rotate_ephemeral_keys (user_data , user_data_lock , contact_id , ui_queue )
115+ send_new_ephemeral_keys (user_data , user_data_lock , contact_id , ui_queue )
118116
119117 save_account_data (user_data , user_data_lock )
120118 return False
119+
120+ if not generate_and_send_pads (user_data , user_data_lock , contact_id , contact_kyber_public_key , our_lt_private_key , ui_queue ):
121+ return False
121122
123+
124+ with user_data_lock :
125+ our_pads = user_data ["contacts" ][contact_id ]["our_pads" ]["pads" ]
126+
127+ user_data ["contacts" ][contact_id ]["ephemeral_keys" ]["rotation_counter" ] += 1
128+
129+ logger .debug ("Incremented rotation_counter by 1. (%d)" , rotation_counter )
122130
123131
124132 with user_data_lock :
125- our_pads = user_data ["contacts" ][contact_id ]["our_pads" ]["pads" ]
126133 replay_protection_number = user_data ["contacts" ][contact_id ]["our_pads" ]["replay_protection_number" ]
127134
128135 message_encoded = message .encode ("utf-8" )
@@ -173,7 +180,7 @@ def send_message_processor(user_data, user_data_lock, contact_id: str, message:
173180 "replay_protection_number" : replay_protection_number
174181 })
175182
176- json_inner_payload_signature = create_signature ("Dilithium5" , json_inner_payload .encode ("utf-8" ), our_d5_private_key )
183+ json_inner_payload_signature = create_signature ("Dilithium5" , json_inner_payload .encode ("utf-8" ), our_lt_private_key )
177184 json_inner_payload_signature = b64encode (json_inner_payload_signature ).decode ()
178185
179186 payload = {
@@ -208,9 +215,9 @@ def messages_data_handler(user_data, user_data_lock, user_data_copied, ui_queue,
208215 return
209216
210217
211- contact_d5_public_key = user_data_copied ["contacts" ][contact_id ]["message_sign_keys " ]["contact_public_key" ]
218+ contact_public_key = user_data_copied ["contacts" ][contact_id ]["lt_sign_keys " ]["contact_public_key" ]
212219
213- if not contact_d5_public_key :
220+ if not contact_public_key :
214221 logger .warning ("Contact per-contact Dilithium5 public key is missing.. skipping message" )
215222 return
216223
@@ -219,7 +226,7 @@ def messages_data_handler(user_data, user_data_lock, user_data_copied, ui_queue,
219226
220227 if message ["msg_type" ] == "new_otp_batch" :
221228 payload_signature = b64decode (message ["payload_signature" ], validate = True )
222- valid_signature = verify_signature ("Dilithium5" , message ["json_payload" ].encode ("utf-8" ), payload_signature , contact_d5_public_key )
229+ valid_signature = verify_signature ("Dilithium5" , message ["json_payload" ].encode ("utf-8" ), payload_signature , contact_public_key )
223230 if not valid_signature :
224231 logger .debug ("Invalid OTP batch signature.. possible MiTM ?" )
225232 return
@@ -247,7 +254,7 @@ def messages_data_handler(user_data, user_data_lock, user_data_copied, ui_queue,
247254
248255 elif message ["msg_type" ] == "new_message" :
249256 payload_signature = b64decode (message ["payload_signature" ], validate = True )
250- valid_signature = verify_signature ("Dilithium5" , message ["json_payload" ].encode ("utf-8" ), payload_signature , contact_d5_public_key )
257+ valid_signature = verify_signature ("Dilithium5" , message ["json_payload" ].encode ("utf-8" ), payload_signature , contact_public_key )
251258 if not valid_signature :
252259 logger .debug ("Invalid new message signature.. possible MiTM ?" )
253260 return
0 commit comments