Security: ensure remote pubkeys are stored
parent
e02bba93b1
commit
48a7c1a969
|
@ -11,20 +11,22 @@ class BaseSession(ISecureConn):
|
||||||
|
|
||||||
local_peer: ID
|
local_peer: ID
|
||||||
local_private_key: PrivateKey
|
local_private_key: PrivateKey
|
||||||
remote_peer_id: ID
|
remote_peer: ID
|
||||||
remote_permanent_pubkey: PublicKey
|
remote_permanent_pubkey: PublicKey
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
*,
|
||||||
local_peer: ID,
|
local_peer: ID,
|
||||||
local_private_key: PrivateKey,
|
local_private_key: PrivateKey,
|
||||||
|
remote_peer: ID,
|
||||||
|
remote_permanent_pubkey: PublicKey,
|
||||||
is_initiator: bool,
|
is_initiator: bool,
|
||||||
peer_id: Optional[ID] = None,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
self.local_peer = local_peer
|
self.local_peer = local_peer
|
||||||
self.local_private_key = local_private_key
|
self.local_private_key = local_private_key
|
||||||
self.remote_peer_id = peer_id
|
self.remote_peer = remote_peer
|
||||||
self.remote_permanent_pubkey = None
|
self.remote_permanent_pubkey = remote_permanent_pubkey
|
||||||
self.is_initiator = is_initiator
|
self.is_initiator = is_initiator
|
||||||
|
|
||||||
def get_local_peer(self) -> ID:
|
def get_local_peer(self) -> ID:
|
||||||
|
@ -34,7 +36,7 @@ class BaseSession(ISecureConn):
|
||||||
return self.local_private_key
|
return self.local_private_key
|
||||||
|
|
||||||
def get_remote_peer(self) -> ID:
|
def get_remote_peer(self) -> ID:
|
||||||
return self.remote_peer_id
|
return self.remote_peer
|
||||||
|
|
||||||
def get_remote_public_key(self) -> Optional[PublicKey]:
|
def get_remote_public_key(self) -> Optional[PublicKey]:
|
||||||
return self.remote_permanent_pubkey
|
return self.remote_permanent_pubkey
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from libp2p.crypto.exceptions import MissingDeserializerError
|
from libp2p.crypto.exceptions import MissingDeserializerError
|
||||||
from libp2p.crypto.keys import PrivateKey, PublicKey
|
from libp2p.crypto.keys import PrivateKey, PublicKey
|
||||||
from libp2p.crypto.pb import crypto_pb2
|
from libp2p.crypto.pb import crypto_pb2
|
||||||
|
@ -32,13 +30,21 @@ class PlaintextHandshakeReadWriter(BaseMsgReadWriter):
|
||||||
class InsecureSession(BaseSession):
|
class InsecureSession(BaseSession):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
*,
|
||||||
local_peer: ID,
|
local_peer: ID,
|
||||||
local_private_key: PrivateKey,
|
local_private_key: PrivateKey,
|
||||||
conn: ReadWriteCloser,
|
remote_peer: ID,
|
||||||
|
remote_permanent_pubkey: PublicKey,
|
||||||
is_initiator: bool,
|
is_initiator: bool,
|
||||||
peer_id: Optional[ID] = None,
|
conn: ReadWriteCloser,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(local_peer, local_private_key, is_initiator, peer_id)
|
super().__init__(
|
||||||
|
local_peer=local_peer,
|
||||||
|
local_private_key=local_private_key,
|
||||||
|
remote_peer=remote_peer,
|
||||||
|
remote_permanent_pubkey=remote_permanent_pubkey,
|
||||||
|
is_initiator=is_initiator,
|
||||||
|
)
|
||||||
self.conn = conn
|
self.conn = conn
|
||||||
|
|
||||||
async def write(self, data: bytes) -> None:
|
async def write(self, data: bytes) -> None:
|
||||||
|
@ -102,11 +108,14 @@ async def run_handshake(
|
||||||
)
|
)
|
||||||
|
|
||||||
secure_conn = InsecureSession(
|
secure_conn = InsecureSession(
|
||||||
local_peer, local_private_key, conn, is_initiator, received_peer_id
|
local_peer=local_peer,
|
||||||
|
local_private_key=local_private_key,
|
||||||
|
remote_peer=received_peer_id,
|
||||||
|
remote_permanent_pubkey=received_pubkey,
|
||||||
|
is_initiator=is_initiator,
|
||||||
|
conn=conn,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Nothing is wrong. Store the `pubkey` and `peer_id` in the session.
|
|
||||||
secure_conn.remote_permanent_pubkey = received_pubkey
|
|
||||||
# TODO: Store `pubkey` and `peer_id` to `PeerStore`
|
# TODO: Store `pubkey` and `peer_id` to `PeerStore`
|
||||||
|
|
||||||
return secure_conn
|
return secure_conn
|
||||||
|
|
|
@ -108,11 +108,12 @@ class PatternXX(BasePattern):
|
||||||
)
|
)
|
||||||
transport_read_writer = NoiseTransportReadWriter(conn, noise_state)
|
transport_read_writer = NoiseTransportReadWriter(conn, noise_state)
|
||||||
return SecureSession(
|
return SecureSession(
|
||||||
self.local_peer,
|
local_peer=self.local_peer,
|
||||||
self.libp2p_privkey,
|
local_private_key=self.libp2p_privkey,
|
||||||
remote_peer_id_from_pubkey,
|
remote_peer=remote_peer_id_from_pubkey,
|
||||||
transport_read_writer,
|
remote_permanent_pubkey=remote_pubkey,
|
||||||
False,
|
is_initiator=False,
|
||||||
|
conn=transport_read_writer,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def handshake_outbound(
|
async def handshake_outbound(
|
||||||
|
@ -161,11 +162,11 @@ class PatternXX(BasePattern):
|
||||||
"handshake is done but it is not marked as finished in `noise_state`"
|
"handshake is done but it is not marked as finished in `noise_state`"
|
||||||
)
|
)
|
||||||
transport_read_writer = NoiseTransportReadWriter(conn, noise_state)
|
transport_read_writer = NoiseTransportReadWriter(conn, noise_state)
|
||||||
|
|
||||||
return SecureSession(
|
return SecureSession(
|
||||||
self.local_peer,
|
local_peer=self.local_peer,
|
||||||
self.libp2p_privkey,
|
local_private_key=self.libp2p_privkey,
|
||||||
remote_peer,
|
remote_peer=remote_peer_id_from_pubkey,
|
||||||
transport_read_writer,
|
remote_permanent_pubkey=remote_pubkey,
|
||||||
False,
|
is_initiator=True,
|
||||||
|
conn=transport_read_writer,
|
||||||
)
|
)
|
||||||
|
|
|
@ -338,12 +338,16 @@ def _mk_session_from(
|
||||||
if session_parameters.order < 0:
|
if session_parameters.order < 0:
|
||||||
key_set1, key_set2 = key_set2, key_set1
|
key_set1, key_set2 = key_set2, key_set1
|
||||||
secio_read_writer = SecioMsgReadWriter(key_set1, key_set2, conn)
|
secio_read_writer = SecioMsgReadWriter(key_set1, key_set2, conn)
|
||||||
|
remote_permanent_pubkey = (
|
||||||
|
session_parameters.remote_encryption_parameters.permanent_public_key
|
||||||
|
)
|
||||||
session = SecureSession(
|
session = SecureSession(
|
||||||
session_parameters.local_peer,
|
local_peer=session_parameters.local_peer,
|
||||||
local_private_key,
|
local_private_key=local_private_key,
|
||||||
session_parameters.remote_peer,
|
remote_peer=session_parameters.remote_peer,
|
||||||
secio_read_writer,
|
remote_permanent_pubkey=remote_permanent_pubkey,
|
||||||
is_initiator,
|
is_initiator=is_initiator,
|
||||||
|
conn=secio_read_writer,
|
||||||
)
|
)
|
||||||
return session
|
return session
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import io
|
import io
|
||||||
|
|
||||||
from libp2p.crypto.keys import PrivateKey
|
from libp2p.crypto.keys import PrivateKey, PublicKey
|
||||||
from libp2p.io.abc import EncryptedMsgReadWriter
|
from libp2p.io.abc import EncryptedMsgReadWriter
|
||||||
from libp2p.peer.id import ID
|
from libp2p.peer.id import ID
|
||||||
from libp2p.security.base_session import BaseSession
|
from libp2p.security.base_session import BaseSession
|
||||||
|
@ -13,13 +13,21 @@ class SecureSession(BaseSession):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
*,
|
||||||
local_peer: ID,
|
local_peer: ID,
|
||||||
local_private_key: PrivateKey,
|
local_private_key: PrivateKey,
|
||||||
remote_peer: ID,
|
remote_peer: ID,
|
||||||
conn: EncryptedMsgReadWriter,
|
remote_permanent_pubkey: PublicKey,
|
||||||
is_initiator: bool,
|
is_initiator: bool,
|
||||||
|
conn: EncryptedMsgReadWriter,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(local_peer, local_private_key, is_initiator, remote_peer)
|
super().__init__(
|
||||||
|
local_peer=local_peer,
|
||||||
|
local_private_key=local_private_key,
|
||||||
|
remote_peer=remote_peer,
|
||||||
|
remote_permanent_pubkey=remote_permanent_pubkey,
|
||||||
|
is_initiator=is_initiator,
|
||||||
|
)
|
||||||
self.conn = conn
|
self.conn = conn
|
||||||
|
|
||||||
self._reset_internal_buffer()
|
self._reset_internal_buffer()
|
||||||
|
|
Loading…
Reference in New Issue