package Ġio . lib p 2 p . security . sec io Ċ Ċ import Ġcom . google . protobuf . Message Ċ import Ġcom . google . protobuf . Parser Ċ import Ġio . lib p 2 p . core . Peer Id Ċ import Ġio . lib p 2 p . core . crypto . Priv Key Ċ import Ġio . lib p 2 p . core . crypto . PubKey Ċ import Ġio . lib p 2 p . core . crypto . sha 2 5 6 Ċ import Ġio . lib p 2 p . core . crypto . un marshal PublicKey Ċ import Ġio . lib p 2 p . crypto . St ret ched Key Ċ import Ġio . lib p 2 p . crypto . keys . E cd sa PrivateKey Ċ import Ġio . lib p 2 p . crypto . keys . E cd sa PublicKey Ċ import Ġio . lib p 2 p . crypto . keys . decode E cd sa PublicKey Un compressed Ċ import Ġio . lib p 2 p . crypto . keys . generate E cd sa KeyPair Ċ import Ġio . lib p 2 p . crypto . stretch Keys Ċ import Ġio . lib p 2 p . etc . types . compareTo Ċ import Ġio . lib p 2 p . etc . types . toByteArray Ċ import Ġio . lib p 2 p . etc . types . to Byte Buf Ċ import Ġio . lib p 2 p . etc . types . to Protobuf Ċ import Ġio . netty . buffer . Byte Buf Ċ import Ġio . netty . buffer . Un p ooled Ċ import Ġorg . bouncycastle . crypto . digest s . SHA 2 5 6 Digest Ċ import Ġorg . bouncycastle . crypto . digest s . SHA 5 1 2 Digest Ċ import Ġorg . bouncycastle . crypto . macs . H Mac Ċ import Ġorg . bouncycastle . crypto . params . Key Parameter Ċ import Ġorg . bouncycastle . j ce . EC Named Curve Table Ċ import Ġs pipe . pb . S pipe Ċ import Ġjava . security . Secure Random Ċ Ċ data Ġclass ĠSec io Params ( ĊĠĠĠ Ġval Ġnonce : ĠByteArray , ĊĠĠĠ Ġval Ġpermanent PubKey : ĠPub Key , ĊĠĠĠ Ġval Ġep hemeral PubKey : ĠByteArray , ĊĠĠĠ Ġval Ġkeys : ĠSt ret ched Key , ĊĊĠĠĠ Ġval Ġcurve T : ĠString , ĊĠĠĠ Ġval Ġcipher T : ĠString , ĊĠĠĠ Ġval Ġhash T : ĠString , ĊĊĠĠĠ Ġval Ġmac : ĠH Mac Ċ ) Ċ Ċ /** Ċ Ġ* ĠCreated Ġby ĠAnt on ĠN ash at y rev Ġon Ġ 1 4 . 0 6 . 2 0 1 9 . Ċ Ġ*/ Ċ class ĠSec io Handshake ( ĊĠĠĠ Ġprivate Ġval Ġoutbound Channel : Ġ( Byte Buf ) Ġ-> ĠUnit , ĊĠĠĠ Ġval Ġlocal Key : ĠPriv Key , ĊĠĠĠ Ġval Ġremote Peer Id : ĠPeer Id ? Ċ ) Ġ{ ĊĊĠĠĠ Ġenum Ġclass ĠState Ġ{ ĊĠĠĠĠĠĠĠ ĠInitial , ĊĠĠĠĠĠĠĠ ĠPro pose Sent , ĊĠĠĠĠĠĠĠ ĠExchange Sent , ĊĠĠĠĠĠĠĠ ĠKeys Created , ĊĠĠĠĠĠĠĠ ĠSecure Channel Created , ĊĠĠĠĠĠĠĠ ĠFinal Validated ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġstate Ġ= ĠState . Initial ĊĊĠĠĠ Ġval Ġrandom Ġ= ĠSecure Random () ĊĠĠĠ Ġval Ġnonce Size Ġ= Ġ 1 6 ĊĠĠĠ Ġval Ġciph ers Ġ= Ġlinked Set Of (" AES - 1 2 8 ", Ġ" AES - 2 5 6 ") ĊĠĠĠ Ġval Ġhashes Ġ= Ġlinked Set Of (" SHA 2 5 6 ", Ġ" SHA 5 1 2 ") ĊĠĠĠ Ġval Ġcurves Ġ= Ġlinked Set Of (" P - 2 5 6 ", Ġ" P - 3 8 4 ", Ġ" P - 5 2 1 ") ĊĊĠĠĠ Ġprivate Ġval Ġnonce Ġ= ĠByteArray ( nonce Size ). apply Ġ{ Ġrandom . next Bytes ( this ) Ġ} ĊĠĠĠ Ġprivate Ġvar Ġpropose Msg : ĠS pipe . Pro pose ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġremote Pro pose : ĠS pipe . Pro pose ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġremote PubKey : ĠPub Key ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġorder : ĠInt ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġcurve : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġhash : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġcipher : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġe ph Priv Key : ĠE cd sa PrivateKey ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġe ph PubKey : ĠE cd sa PublicKey ? Ġ= Ġnull ĊĊĠĠĠ Ġfun Ġis Complete () Ġ= Ġstate Ġ== ĠState . Final Validated ĊĊĠĠĠ Ġfun Ġstart () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlocal PubKey Bytes Ġ= Ġlocal Key . publicKey (). bytes () ĊĊĠĠĠĠĠĠĠ Ġpropose Msg Ġ= ĠS pipe . Pro pose . newBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Rand ( nonce . to Protobuf ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Pub key ( local PubKey Bytes . to Protobuf ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Exchange s ( cur ves . join ToString ("," )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Hashes ( hashes . join ToString ("," )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set C iph ers ( ciph ers . join ToString ("," )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠ Ġstate Ġ= ĠState . Pro pose Sent ĊĠĠĠĠĠĠĠ Ġwrite ( pro pose Msg !! ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Secure Channel Setup () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( state Ġ!= ĠState . Keys Created ) Ġthrow ĠInvalid Neg otiation State () ĊĠĠĠĠĠĠĠ Ġoutbound Channel . invoke ( remote Pro pose !!. rand . toByteArray (). to Byte Buf ()) ĊĠĠĠĠĠĠĠ Ġstate Ġ= ĠState . Secure Channel Created ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon New Message ( buf : ĠByte Buf ): ĠPair < Sec io Params , ĠSec io Params >? Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠState . Pro pose Sent Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremote Pro pose Ġ= Ġread ( buf , ĠS pipe . Pro pose . parser ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremote PubKey Bytes Ġ= Ġremote Pro pose !!. pubkey . toByteArray () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremote PubKey Ġ= Ġunmarshal PublicKey ( remote PubKey Bytes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcal ced Peer Id Ġ= ĠPeer Id . from PubKey ( remote PubKey !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( remote Peer Id Ġ!= Ġnull Ġ&& Ġcal ced Peer Id Ġ!= Ġremote Peer Id ) Ġthrow ĠInvalid Remote PubKey () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġh 1 Ġ= Ġsha 2 5 6 ( remote PubKey Bytes Ġ+ Ġnonce ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġh 2 Ġ= Ġsha 2 5 6 ( local Key . publicKey (). bytes () Ġ+ Ġremote Pro pose !!. rand . toByteArray ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġorder Ġ= Ġh 1 . compareTo ( h 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( order Ġ== Ġ 0 ) Ġthrow ĠSelf Connecting () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurve Ġ= Ġselect Best ( order !! , Ġcurves , Ġremote Pro pose !!. exchange s . split ("," )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhash Ġ= Ġselect Best ( order !! , Ġhashes , Ġremote Pro pose !!. hashes . split ("," )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcipher Ġ= Ġselect Best ( order !! , Ġciph ers , Ġremote Pro pose !!. ciph ers . split ("," )) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( e ph Priv Key L , Ġe ph PubKey L ) Ġ= Ġgenerate E cd sa KeyPair ( curve !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe ph Priv Key Ġ= Ġe ph Priv Key L ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe ph PubKey Ġ= Ġe ph PubKey L ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexchange Msg Ġ= ĠS pipe . Exchange . newBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set E pubkey ( e ph PubKey L . to Un compressed Bytes (). to Protobuf ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Signature ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlocal Key . sign ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpropose Msg !!. toByteArray () Ġ+ Ġremote Pro pose !!. toByteArray () Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe ph PubKey L . to Un compressed Bytes () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ). to Protobuf () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ). build () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Ġ= ĠState . Exchange Sent ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( exchange Msg ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠState . Exchange Sent Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremote Exchange Msg Ġ= Ġread ( buf , ĠS pipe . Exchange . parser ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! remote PubKey !!. verify ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremote Pro pose !!. toByteArray () Ġ+ Ġpropose Msg !!. toByteArray () Ġ+ Ġremote Exchange Msg . ep ub key . toByteArray (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremote Exchange Msg . signature . toByteArray () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠInvalid Signature () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġec Curve Ġ= ĠEC Named Curve Table . getParameter Spec ( curve ). curve ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremote E ph Public k Key Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdecode E cd sa PublicKey Un compressed ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurve !! , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremote Exchange Msg . ep ub key . toByteArray () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremote E ph Pub Point Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġec Curve . validate Point ( remote E ph Public k Key . pub . w . affine X , Ġremote E ph Public k Key . pub . w . affine Y ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshared Secret Point Ġ= Ġec Curve . multiplier . multiply ( remote E ph Pub Point , Ġe ph Priv Key !!. priv . s ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshared Secret Ġ= Ġshared Secret Point . normalize (). affine X Coord . encoded ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( k 1 , Ġk 2 ) Ġ= Ġstretch Keys ( cipher !! , Ġhash !! , Ġshared Secret ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlocal Keys Ġ= Ġif Ġ( order !! Ġ> Ġ 0 ) Ġk 1 Ġelse Ġk 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremote Keys Ġ= Ġif Ġ( order !! Ġ> Ġ 0 ) Ġk 2 Ġelse Ġk 1 ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhmac Factory : Ġ( ByteArray ) Ġ-> ĠH Mac Ġ= Ġ{ Ġmac Key Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġret Ġ= Ġwhen Ġ( hash ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" SHA 2 5 6 " Ġ-> ĠH Mac ( SHA 2 5 6 Digest ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" SHA 5 1 2 " Ġ-> ĠH Mac ( SHA 5 1 2 Digest ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalArgumentException (" Unsupported Ġhash Ġfunction : Ġ$ hash ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġret . init ( Key Parameter ( mac Key )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġret ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Ġ= ĠState . Keys Created ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠPair ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSec io Params ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnonce , Ġlocal Key . publicKey (), Ġe ph PubKey !!. bytes (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlocal Keys , Ġcurve !! , Ġcipher !! , Ġhash !! , Ġhmac Factory . invoke ( local Keys . mac Key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSec io Params ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremote Pro pose !!. rand . toByteArray (), Ġremote PubKey !! , Ġremote E ph Pub Point . get Encoded ( true ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremote Keys , Ġcurve !! , Ġcipher !! , Ġhash !! , Ġhmac Factory . invoke ( remote Keys . mac Key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠState . Secure Channel Created Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! nonce . content Equals ( buf . toByteArray ())) Ġthrow ĠInvalid Initial Packet () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Ġ= ĠState . Final Validated ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠInvalid Neg otiation State () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġwrite ( out Msg : ĠMessage ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbyte Buf Ġ= ĠUn p ooled . buffer (). write Bytes ( out Msg . toByteArray ()) ĊĠĠĠĠĠĠĠ Ġoutbound Channel . invoke ( byte Buf ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġ< MessageType Ġ: ĠMessage > Ġread ( buf : ĠByte Buf , Ġparser : ĠParser < MessageType >): ĠMessageType Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġparser . parseFrom ( buf . nio Buffer ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġinline Ġfun Ġ< re ified ĠT > Ġselect Best ( order : ĠInt , Ġp 1 : ĠCollection < T >, Ġp 2 : ĠCollection < T >): ĠT Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġintersect Ġ= Ġlinked Set Of (*( if Ġ( order Ġ>= Ġ 0 ) Ġp 1 Ġelse Ġp 2 ). to Typed Array ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. intersect ( linked Set Of (*( if Ġ( order Ġ>= Ġ 0 ) Ġp 2 Ġelse Ġp 1 ). to Typed Array ())) ĊĠĠĠĠĠĠĠ Ġif Ġ( intersect . isEmpty ()) Ġthrow ĠNo Common Al gos () ĊĠĠĠĠĠĠĠ Ġreturn Ġintersect . first () ĊĠĠĠ Ġ} Ċ }