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">
<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>
@ -260,7 +260,7 @@
</mxGraphModel>
</diagram>
<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>
<mxCell id="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">
<mxGeometry x="463" y="210" width="60" height="30" as="geometry" />
</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" />
</mxCell>
<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
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.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():
"""
@ -76,26 +79,3 @@ def compute_ecdh_shared_key(private_key, peer_pubkey_bytes: bytes) -> bytes:
peer_public_key = peer_public_numbers.public_key()
shared_key = private_key.exchange(ec.ECDH(), peer_public_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 threading
from typing import List, Dict, Any
from crypto_utils import raw_signature_to_der
from crypto_utils import (
generate_identity_keys,
@ -307,8 +306,9 @@ class IcingProtocol:
def generate_ecdhe(self, index: int):
"""
Formerly 'respond_to_handshake'. Verifies ephemeral signature, computes ECDH,
updates pfs_history, and stores shared_secret. Does NOT send a handshake back.
Formerly 'respond_to_handshake' - this verifies the inbound ephemeral signature
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):
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.")
return
# Parse fields
# (timestamp, ephemeral_pub, ephemeral_sig, pfs_hash) = ...
(ts32, ephemeral_pub, ephemeral_sig, pfs_val) = msg["parsed"]
ephemeral_pub = msg["parsed"]["ephemeral_pub"]
ephemeral_sig = msg["parsed"]["ephemeral_sig"]
# 1) Verify ephemeral signature
# Verify ephemeral signature
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
# ephemeral_sig is raw r||s
sig_der = raw_signature_to_der(ephemeral_sig)
ok = verify_signature(self.peer_identity_pubkey_obj, sig_der, ephemeral_pub)
ok = verify_signature(self.peer_identity_pubkey_obj, ephemeral_sig, ephemeral_pub)
if not ok:
print(f"{RED}[ERROR]{RESET} Ephemeral signature invalid.")
print(f"{RED}[ERROR]{RESET} Ephemeral signature is invalid.")
return
print(f"{GREEN}[OK]{RESET} Ephemeral signature verified.")
print(f"{GREEN}[OK]{RESET} Ephemeral signature verified successfully.")
# 2) ECDH
if not self.ephemeral_privkey:
print(f"{YELLOW}[WARN]{RESET} No ephemeral_privkey. Cannot compute shared secret.")
return
shared = compute_ecdh_shared_key(self.ephemeral_privkey, ephemeral_pub)
self.shared_secret = shared.hex()
print(f"{GREEN}[OK]{RESET} Computed ECDH shared key = {self.shared_secret}")
# 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)
# If we have ephemeral_privkey, compute ECDH shared key
if self.ephemeral_privkey:
shared = compute_ecdh_shared_key(self.ephemeral_privkey, ephemeral_pub)
self.shared_secret = shared.hex()
print(f"{GREEN}[OK]{RESET} Derived ECDH shared key = {self.shared_secret}")
else:
print(f"{YELLOW}[WARN]{RESET} No ephemeral_privkey available, cannot compute ECDH shared key.")
# -------------------------------------------------------------------------
# Utility