Merge branch 'Protocol_00' of git.gmoker.com:icing/monorepo into Protocol_00
All checks were successful
/ mirror (push) Successful in 4s
All checks were successful
/ mirror (push) Successful in 4s
This commit is contained in:
commit
6155955cca
@ -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.1" 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.3" 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="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">
|
||||
<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">
|
||||
<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<span style="background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));">b</span>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxCell id="pP7SjZfcCiBg3d1TCkzP-63" value="= 295<span style="background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));">b (+1)</span>" 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">
|
||||
|
@ -1,11 +1,8 @@
|
||||
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():
|
||||
"""
|
||||
@ -79,3 +76,26 @@ 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)
|
||||
|
@ -2,6 +2,7 @@ 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,
|
||||
@ -306,9 +307,8 @@ class IcingProtocol:
|
||||
|
||||
def generate_ecdhe(self, index: int):
|
||||
"""
|
||||
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.
|
||||
Formerly 'respond_to_handshake'. Verifies the inbound ephemeral signature
|
||||
and computes the ECDH shared secret, updating PFS history.
|
||||
"""
|
||||
if index < 0 or index >= len(self.inbound_messages):
|
||||
print(f"{RED}[ERROR]{RESET} Invalid index {index}.")
|
||||
@ -321,23 +321,30 @@ class IcingProtocol:
|
||||
ephemeral_pub = msg["parsed"]["ephemeral_pub"]
|
||||
ephemeral_sig = msg["parsed"]["ephemeral_sig"]
|
||||
|
||||
# Verify ephemeral signature
|
||||
if not self.peer_identity_pubkey_obj:
|
||||
print(f"{RED}[ERROR]{RESET} Peer identity not set, cannot verify ephemeral signature.")
|
||||
return
|
||||
ok = verify_signature(self.peer_identity_pubkey_obj, ephemeral_sig, ephemeral_pub)
|
||||
if not ok:
|
||||
print(f"{RED}[ERROR]{RESET} Ephemeral signature is invalid.")
|
||||
return
|
||||
print(f"{GREEN}[OK]{RESET} Ephemeral signature verified successfully.")
|
||||
|
||||
# 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}")
|
||||
# Use our raw_signature_to_der wrapper only if signature is 64 bytes.
|
||||
# Otherwise, assume the signature is already DER-encoded.
|
||||
from crypto_utils import raw_signature_to_der
|
||||
if len(ephemeral_sig) == 64:
|
||||
sig_der = raw_signature_to_der(ephemeral_sig)
|
||||
else:
|
||||
print(f"{YELLOW}[WARN]{RESET} No ephemeral_privkey available, cannot compute ECDH shared key.")
|
||||
sig_der = ephemeral_sig
|
||||
|
||||
ok = verify_signature(self.peer_identity_pubkey_obj, sig_der, ephemeral_pub)
|
||||
if not ok:
|
||||
print(f"{RED}[ERROR]{RESET} Ephemeral signature invalid.")
|
||||
return
|
||||
print(f"{GREEN}[OK]{RESET} Ephemeral signature verified.")
|
||||
|
||||
if not self.ephemeral_privkey:
|
||||
print(f"{YELLOW}[WARN]{RESET} No ephemeral_privkey available, 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}")
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user