This commit is contained in:
Sergey Ivanov 2023-07-05 18:14:18 +04:00
parent d1318c6fd1
commit fdf5a72765
5 changed files with 166 additions and 4 deletions

View File

@ -1,5 +1,6 @@
{-# Language TemplateHaskell #-} {-# Language TemplateHaskell #-}
{-# Language UndecidableInstances #-} {-# Language UndecidableInstances #-}
module HBS2.Net.Proto.EncryptionHandshake where module HBS2.Net.Proto.EncryptionHandshake where
import HBS2.Actors.Peer import HBS2.Actors.Peer
@ -50,6 +51,11 @@ sendEncryptionPubKey pip pubkey = do
tt <- liftIO $ getTimeCoarse tt <- liftIO $ getTimeCoarse
request pip (BeginEncryptionExchange @e nonce pubkey) request pip (BeginEncryptionExchange @e nonce pubkey)
data EncryptionHandshakeAdapter e m s = EncryptionHandshakeAdapter
{ encHandshake_considerPeerAsymmKey :: PeerAddr e -> Encrypt.PublicKey -> m ()
}
encryptionHandshakeProto :: forall e s m . ( MonadIO m encryptionHandshakeProto :: forall e s m . ( MonadIO m
, Response e (EncryptionHandshake e) m , Response e (EncryptionHandshake e) m
, Request e (EncryptionHandshake e) m , Request e (EncryptionHandshake e) m
@ -66,17 +72,22 @@ encryptionHandshakeProto :: forall e s m . ( MonadIO m
, Serialise (PubKey 'Encrypt (Encryption e)) , Serialise (PubKey 'Encrypt (Encryption e))
, s ~ Encryption e , s ~ Encryption e
, e ~ L4Proto , e ~ L4Proto
, PubKey Encrypt s ~ Encrypt.PublicKey
) )
=> PeerEnv e => EncryptionHandshakeAdapter e m s
-> PeerEnv e
-> EncryptionHandshake e -> EncryptionHandshake e
-> m () -> m ()
encryptionHandshakeProto penv = \case encryptionHandshakeProto EncryptionHandshakeAdapter{..} penv = \case
BeginEncryptionExchange nonce theirpubkey -> do BeginEncryptionExchange nonce theirpubkey -> do
pip <- thatPeer proto pip <- thatPeer proto
trace $ "GOT BeginEncryptionExchange from" <+> pretty pip trace $ "GOT BeginEncryptionExchange from" <+> pretty pip
paddr <- toPeerAddr pip
encHandshake_considerPeerAsymmKey paddr theirpubkey
-- взять свои ключи -- взять свои ключи
creds <- getCredentials @s creds <- getCredentials @s
@ -86,7 +97,7 @@ encryptionHandshakeProto penv = \case
let sign = makeSign @s (view peerSignSk creds) (unEENonce nonce <> (cs . serialise) ourpubkey) let sign = makeSign @s (view peerSignSk creds) (unEENonce nonce <> (cs . serialise) ourpubkey)
-- отправить обратно вместе с публичным ключом -- отправить обратно вместе с публичным ключом
-- response (AckEncryptionExchange @e nonce sign ourpubkey (PeerData (view peerSignPk creds))) response (AckEncryptionExchange @e nonce sign ourpubkey)
-- Нужно ли запомнить его theirpubkey или достаточно того, что будет -- Нужно ли запомнить его theirpubkey или достаточно того, что будет
-- получено в обратном AckEncryptionExchange? -- получено в обратном AckEncryptionExchange?
@ -101,6 +112,9 @@ encryptionHandshakeProto penv = \case
pip <- thatPeer proto pip <- thatPeer proto
-- trace $ "AckEncryptionExchange" <+> pretty pip -- trace $ "AckEncryptionExchange" <+> pretty pip
paddr <- toPeerAddr pip
encHandshake_considerPeerAsymmKey paddr theirpubkey
emit PeerAsymmInfoKey (PeerAsymmPubKey pip theirpubkey) emit PeerAsymmInfoKey (PeerAsymmPubKey pip theirpubkey)
where where

View File

@ -13,6 +13,7 @@ import HBS2.System.Logger.Simple
import PeerConfig import PeerConfig
import Crypto.Saltine.Core.Box qualified as Encrypt
import Data.Maybe import Data.Maybe
import Control.Monad import Control.Monad
import Control.Exception import Control.Exception
@ -602,6 +603,46 @@ transactional brains action = do
err $ "BRAINS: " <+> viaShow e err $ "BRAINS: " <+> viaShow e
execute_ conn [qc|ROLLBACK TO SAVEPOINT {sp}|] execute_ conn [qc|ROLLBACK TO SAVEPOINT {sp}|]
insertPeerAsymmKey :: forall e m .
( e ~ L4Proto
, MonadIO m
)
=> BasicBrains e
-> PeerAddr e
-> Encrypt.PublicKey
-> m ()
insertPeerAsymmKey br peer hAsymmKey = do
let conn = view brainsDb br
void $ liftIO $ execute conn [qc|
INSERT INTO peer_asymmkey (peer,asymmkey)
VALUES (?,?)
ON CONFLICT (peer)
DO UPDATE SET
asymmkey = excluded.asymmkey
|] (show $ pretty peer, show hAsymmKey)
insertPeerSymmKey :: forall e m .
( e ~ L4Proto
, MonadIO m
)
=> BasicBrains e
-> PeerAddr e
-> Encrypt.CombinedKey
-> m ()
insertPeerSymmKey br peer hSymmKey = do
let conn = view brainsDb br
void $ liftIO $ execute conn [qc|
INSERT INTO peer_symmkey (peer,symmkey)
VALUES (?,?)
ON CONFLICT (peer)
DO UPDATE SET
symmkey = excluded.symmkey
|] (show $ pretty peer, show hSymmKey)
-- FIXME: eventually-close-db -- FIXME: eventually-close-db
newBasicBrains :: forall e m . (Hashable (Peer e), MonadIO m) newBasicBrains :: forall e m . (Hashable (Peer e), MonadIO m)
=> PeerConfig => PeerConfig
@ -690,6 +731,22 @@ newBasicBrains cfg = liftIO do
) )
|] |]
execute_ conn [qc|
create table if not exists peer_asymmkey
( peer text not null
, asymmkey text not null
, primary key (peer)
)
|]
execute_ conn [qc|
create table if not exists peer_symmkey
( peer text not null
, symmkey text not null
, primary key (peer)
)
|]
BasicBrains <$> newTVarIO mempty BasicBrains <$> newTVarIO mempty
<*> newTVarIO mempty <*> newTVarIO mempty
<*> Cache.newCache (Just (toTimeSpec (30 :: Timeout 'Seconds))) <*> Cache.newCache (Just (toTimeSpec (30 :: Timeout 'Seconds)))

View File

@ -0,0 +1,74 @@
module EncryptionKeys where
import HBS2.Actors.Peer
import HBS2.Base58
import HBS2.Clock
import HBS2.Data.Detect
import HBS2.Data.Types.Refs
import HBS2.Events
import HBS2.Hash
import HBS2.Merkle
import HBS2.Net.Auth.Credentials
import HBS2.Net.PeerLocator
import HBS2.Net.Proto
import HBS2.Net.Proto.EncryptionHandshake
import HBS2.Net.Proto.Peer
import HBS2.Net.Proto.Sessions
import HBS2.Prelude.Plated
import HBS2.Storage
import HBS2.System.Logger.Simple
import PeerConfig
import PeerTypes
import Codec.Serialise
import Control.Concurrent.Async
import Control.Concurrent.STM
import Control.Monad
import Control.Monad.Reader
import Control.Monad.Trans.Maybe
import Data.ByteString qualified as BS
import Data.ByteString.Lazy qualified as LBS
import Data.Foldable(for_)
import Data.Function(fix)
import Data.Functor
import Data.HashMap.Strict qualified as HashMap
import Data.HashSet (HashSet)
import Data.HashSet qualified as HashSet
import Data.Maybe
import Data.Text qualified as Text
encryptionHandshakeWorker :: forall e m s .
( MonadIO m
, m ~ PeerM e IO
, s ~ Encryption e
, e ~ L4Proto
, HasPeerLocator e m
-- , HasPeer e
-- , HasNonces (EncryptionHandshake e) m
-- , Request e (EncryptionHandshake e) m
-- , Sessions e (EncryptionHandshake e) m
-- , Sessions e (PeerInfo e) m
-- , Sessions e (KnownPeer e) m
-- , Pretty (Peer e)
)
=> PeerConfig
-> PeerEnv e
-> EncryptionHandshakeAdapter e m s
-> m ()
encryptionHandshakeWorker pconf penv EncryptionHandshakeAdapter{..} = do
-- e <- ask
let ourpubkey = pubKeyFromKeypair @s $ _envAsymmetricKeyPair penv
pl <- getPeerLocator @e
forever do
liftIO $ pause @'Seconds 10
pips <- knownPeers @e pl
forM_ pips \p -> do
sendEncryptionPubKey @e p ourpubkey

View File

@ -45,6 +45,7 @@ import PeerInfo
import PeerConfig import PeerConfig
import Bootstrap import Bootstrap
import CheckMetrics import CheckMetrics
import EncryptionKeys
import RefLog qualified import RefLog qualified
import RefLog (reflogWorker) import RefLog (reflogWorker)
import HttpWorker import HttpWorker
@ -645,6 +646,18 @@ runPeer opts = U.handle (\e -> myException e
let hshakeAdapter = PeerHandshakeAdapter addNewRtt let hshakeAdapter = PeerHandshakeAdapter addNewRtt
let encryptionHshakeAdapter ::
( MonadIO m
) => EncryptionHandshakeAdapter L4Proto m s
encryptionHshakeAdapter = EncryptionHandshakeAdapter
{ encHandshake_considerPeerAsymmKey = \addr pk -> do
insertPeerAsymmKey brains addr pk
insertPeerSymmKey brains addr $
genCommonSecret @s
(privKeyFromKeypair @s (view envAsymmetricKeyPair penv))
pk
}
env <- ask env <- ask
pnonce <- peerNonce @e pnonce <- peerNonce @e
@ -793,6 +806,9 @@ runPeer opts = U.handle (\e -> myException e
peerThread "blockDownloadLoop" (blockDownloadLoop denv) peerThread "blockDownloadLoop" (blockDownloadLoop denv)
peerThread "encryptionHandshakeWorker"
(EncryptionKeys.encryptionHandshakeWorker @e conf penv encryptionHshakeAdapter)
let tcpProbeWait :: Timeout 'Seconds let tcpProbeWait :: Timeout 'Seconds
tcpProbeWait = (fromInteger . fromMaybe 300) (cfgValue @PeerTcpProbeWaitKey conf) tcpProbeWait = (fromInteger . fromMaybe 300) (cfgValue @PeerTcpProbeWaitKey conf)
@ -909,7 +925,7 @@ runPeer opts = U.handle (\e -> myException e
, makeResponse (blockChunksProto adapter) , makeResponse (blockChunksProto adapter)
, makeResponse blockAnnounceProto , makeResponse blockAnnounceProto
, makeResponse (withCredentials @e pc . peerHandShakeProto hshakeAdapter penv) , makeResponse (withCredentials @e pc . peerHandShakeProto hshakeAdapter penv)
, makeResponse (withCredentials @e pc . encryptionHandshakeProto penv) , makeResponse (withCredentials @e pc . encryptionHandshakeProto encryptionHshakeAdapter penv)
, makeResponse (peerExchangeProto pexFilt) , makeResponse (peerExchangeProto pexFilt)
, makeResponse (refLogUpdateProto reflogAdapter) , makeResponse (refLogUpdateProto reflogAdapter)
, makeResponse (refLogRequestProto reflogReqAdapter) , makeResponse (refLogRequestProto reflogReqAdapter)

View File

@ -122,6 +122,7 @@ executable hbs2-peer
other-modules: BlockDownload other-modules: BlockDownload
, BlockHttpDownload , BlockHttpDownload
, DownloadQ , DownloadQ
, EncryptionKeys
, Bootstrap , Bootstrap
, PeerInfo , PeerInfo
, PeerMeta , PeerMeta