Compare commits

..

No commits in common. "045d9ad4174b2943775ab1124c6b002154791aaf" and "f9e64a73d911395adb648f9642ca1c9b1101b304" have entirely different histories.

3 changed files with 26 additions and 56 deletions

View File

@ -1,4 +1,4 @@
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36" version="26.1.3" pages="2"> <mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36" version="26.1.1" pages="2">
<diagram id="C5RBs43oDa-KdzZeNtuy" name="Logique"> <diagram id="C5RBs43oDa-KdzZeNtuy" name="Logique">
<mxGraphModel dx="735" dy="407" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0"> <mxGraphModel dx="735" dy="407" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root> <root>
@ -260,7 +260,7 @@
</mxGraphModel> </mxGraphModel>
</diagram> </diagram>
<diagram id="4Sb7mgJDpsadGym-U4wz" name="Echanges"> <diagram id="4Sb7mgJDpsadGym-U4wz" name="Echanges">
<mxGraphModel dx="1434" dy="793" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0"> <mxGraphModel dx="700" dy="387" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root> <root>
<mxCell id="0" /> <mxCell id="0" />
<mxCell id="1" parent="0" /> <mxCell id="1" parent="0" />
@ -414,7 +414,7 @@
<mxCell id="pP7SjZfcCiBg3d1TCkzP-62" value="32b" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1"> <mxCell id="pP7SjZfcCiBg3d1TCkzP-62" value="32b" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="463" y="210" width="60" height="30" as="geometry" /> <mxGeometry x="463" y="210" width="60" height="30" as="geometry" />
</mxCell> </mxCell>
<mxCell id="pP7SjZfcCiBg3d1TCkzP-63" value="= 295&lt;span style=&quot;background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));&quot;&gt;b (+1)&lt;/span&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1"> <mxCell id="pP7SjZfcCiBg3d1TCkzP-63" value="= 295&lt;span style=&quot;background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));&quot;&gt;b&lt;/span&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="530" y="210" width="60" height="30" as="geometry" /> <mxGeometry x="530" y="210" width="60" height="30" as="geometry" />
</mxCell> </mxCell>
<mxCell id="pP7SjZfcCiBg3d1TCkzP-66" value="32b" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1"> <mxCell id="pP7SjZfcCiBg3d1TCkzP-66" value="32b" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">

View File

@ -1,8 +1,11 @@
import os import os
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric.ec import ECDH
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import utils
from cryptography.exceptions import InvalidSignature from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import ec, utils
from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature, encode_dss_signature
def generate_identity_keys(): def generate_identity_keys():
""" """
@ -76,26 +79,3 @@ def compute_ecdh_shared_key(private_key, peer_pubkey_bytes: bytes) -> bytes:
peer_public_key = peer_public_numbers.public_key() peer_public_key = peer_public_numbers.public_key()
shared_key = private_key.exchange(ec.ECDH(), peer_public_key) shared_key = private_key.exchange(ec.ECDH(), peer_public_key)
return shared_key return shared_key
def der_to_raw(der_sig: bytes) -> bytes:
"""
Convert a DER-encoded ECDSA signature to a raw 64-byte signature (r||s),
where each component is padded to 32 bytes.
"""
r, s = decode_dss_signature(der_sig)
r_bytes = r.to_bytes(32, byteorder='big')
s_bytes = s.to_bytes(32, byteorder='big')
return r_bytes + s_bytes
def raw_signature_to_der(raw_sig: bytes) -> bytes:
"""
Convert a raw signature (64 bytes, concatenated r||s) to DER-encoded signature.
"""
if len(raw_sig) != 64:
raise ValueError("Raw signature must be 64 bytes (r||s).")
from cryptography.hazmat.primitives.asymmetric.utils import encode_dss_signature
r = int.from_bytes(raw_sig[:32], 'big')
s = int.from_bytes(raw_sig[32:], 'big')
return encode_dss_signature(r, s)

View File

@ -2,7 +2,6 @@ import random
import time import time
import threading import threading
from typing import List, Dict, Any from typing import List, Dict, Any
from crypto_utils import raw_signature_to_der
from crypto_utils import ( from crypto_utils import (
generate_identity_keys, generate_identity_keys,
@ -307,8 +306,9 @@ class IcingProtocol:
def generate_ecdhe(self, index: int): def generate_ecdhe(self, index: int):
""" """
Formerly 'respond_to_handshake'. Verifies ephemeral signature, computes ECDH, Formerly 'respond_to_handshake' - this verifies the inbound ephemeral signature
updates pfs_history, and stores shared_secret. Does NOT send a handshake back. and computes the ECDH shared secret, storing it in self.shared_secret.
It does NOT send a handshake back.
""" """
if index < 0 or index >= len(self.inbound_messages): if index < 0 or index >= len(self.inbound_messages):
print(f"{RED}[ERROR]{RESET} Invalid index {index}.") print(f"{RED}[ERROR]{RESET} Invalid index {index}.")
@ -318,36 +318,26 @@ class IcingProtocol:
print(f"{RED}[ERROR]{RESET} inbound_messages[{index}] is not a HANDSHAKE.") print(f"{RED}[ERROR]{RESET} inbound_messages[{index}] is not a HANDSHAKE.")
return return
# Parse fields ephemeral_pub = msg["parsed"]["ephemeral_pub"]
# (timestamp, ephemeral_pub, ephemeral_sig, pfs_hash) = ... ephemeral_sig = msg["parsed"]["ephemeral_sig"]
(ts32, ephemeral_pub, ephemeral_sig, pfs_val) = msg["parsed"]
# 1) Verify ephemeral signature # Verify ephemeral signature
if not self.peer_identity_pubkey_obj: if not self.peer_identity_pubkey_obj:
print(f"{RED}[ERROR]{RESET} Peer identity not set.") print(f"{RED}[ERROR]{RESET} Peer identity not set, cannot verify ephemeral signature.")
return return
# ephemeral_sig is raw r||s ok = verify_signature(self.peer_identity_pubkey_obj, ephemeral_sig, ephemeral_pub)
sig_der = raw_signature_to_der(ephemeral_sig)
ok = verify_signature(self.peer_identity_pubkey_obj, sig_der, ephemeral_pub)
if not ok: if not ok:
print(f"{RED}[ERROR]{RESET} Ephemeral signature invalid.") print(f"{RED}[ERROR]{RESET} Ephemeral signature is invalid.")
return return
print(f"{GREEN}[OK]{RESET} Ephemeral signature verified.") print(f"{GREEN}[OK]{RESET} Ephemeral signature verified successfully.")
# 2) ECDH # If we have ephemeral_privkey, compute ECDH shared key
if not self.ephemeral_privkey: if self.ephemeral_privkey:
print(f"{YELLOW}[WARN]{RESET} No ephemeral_privkey. Cannot compute shared secret.") shared = compute_ecdh_shared_key(self.ephemeral_privkey, ephemeral_pub)
return self.shared_secret = shared.hex()
shared = compute_ecdh_shared_key(self.ephemeral_privkey, ephemeral_pub) print(f"{GREEN}[OK]{RESET} Derived ECDH shared key = {self.shared_secret}")
self.shared_secret = shared.hex() else:
print(f"{GREEN}[OK]{RESET} Computed ECDH shared key = {self.shared_secret}") print(f"{YELLOW}[WARN]{RESET} No ephemeral_privkey available, cannot compute ECDH shared key.")
# 3) Update pfs_history
# If we have an entry, increment session_number, store new secret
# If none, create session_number=1, store new secret
old_session, _ = self.pfs_history.get(self.peer_identity_pubkey_bytes, (-1, ""))
new_session = 1 if old_session < 0 else old_session + 1
self.pfs_history[self.peer_identity_pubkey_bytes] = (new_session, self.shared_secret)
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
# Utility # Utility