/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 1 8 ĠSquare , ĠInc . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġokhttp 3 . tls Ċ Ċ import Ġjava . net . Inet Address Ċ import Ġjava . net . Inet SocketAddress Ċ import Ġjava . net . Server Socket Ċ import Ġjava . security . PrivateKey Ċ import Ġjava . util . concurrent . ExecutorService Ċ import Ġjava . util . concurrent . Executors Ċ import Ġjava . util . concurrent . Future Ċ import Ġjavax . net . Server Socket Factory Ċ import Ġjavax . net . Socket Factory Ċ import Ġjavax . net . ssl . SS LS ocket Ċ import Ġokhttp 3 . Handshake Ċ import Ġokhttp 3 . Handshake . Companion . handshake Ċ import Ġokhttp 3 . internal . close Quiet ly Ċ import Ġokhttp 3 . testing . Platform Rule Ċ import Ġok io . ByteString . Companion . to ByteString Ċ import Ġorg . assertj . core . api . Assertions . assertThat Ċ import Ġorg . junit . jupiter . api . After Each Ċ import Ġorg . junit . jupiter . api . BeforeEach Ċ import Ġorg . junit . jupiter . api . Test Ċ import Ġorg . junit . jupiter . api . extension . Register Extension Ċ Ċ class ĠHand shake Certificates Test Ġ{ ĊĠ Ġ@ Register Extension ĊĠ Ġvar Ġplatform Ġ= ĠPlatform Rule () ĊĊĠ Ġprivate Ġlateinit Ġvar ĠexecutorService : ĠExecutor Service ĊĊĠ Ġprivate Ġvar Ġserver Socket : ĠServer Socket ? Ġ= Ġnull ĊĊĠ Ġ@ BeforeEach Ġfun ĠsetUp () Ġ{ ĊĠĠĠ ĠexecutorService Ġ= ĠExec utors . new Cached ThreadPool () ĊĠ Ġ} ĊĊĠ Ġ@ After Each Ġfun ĠtearDown () Ġ{ ĊĠĠĠ ĠexecutorService . shutdown () ĊĠĠĠ Ġserver Socket ?. close Quiet ly () ĊĠ Ġ} ĊĊĠ Ġ@ Test Ġfun Ġclient And Server () Ġ{ ĊĠĠĠ Ġplatform . assume Not Con sc rypt () ĊĠĠĠ Ġplatform . assume Not Bo unc y Castle () ĊĠĠĠ Ġval Ġclient Root Ġ= ĠHel d Certificate . Builder () ĊĠĠĠĠĠ Ġ. certificate Authority ( 1 ) ĊĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġval Ġclient Intermediate Ġ= ĠHel d Certificate . Builder () ĊĠĠĠĠĠ Ġ. certificate Authority ( 0 ) ĊĠĠĠĠĠ Ġ. signed By ( client Root ) ĊĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġval Ġclient Certificate Ġ= ĠHel d Certificate . Builder () ĊĠĠĠĠĠ Ġ. signed By ( client Intermediate ) ĊĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġval Ġserver Root Ġ= ĠHel d Certificate . Builder () ĊĠĠĠĠĠ Ġ. certificate Authority ( 1 ) ĊĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġval Ġserver Intermediate Ġ= ĠHel d Certificate . Builder () ĊĠĠĠĠĠ Ġ. certificate Authority ( 0 ) ĊĠĠĠĠĠ Ġ. signed By ( server Root ) ĊĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġval Ġserver Certificate Ġ= ĠHel d Certificate . Builder () ĊĠĠĠĠĠ Ġ. signed By ( server Intermediate ) ĊĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġval Ġserver Ġ= ĠHand shake Certificates . Builder () ĊĠĠĠĠĠ Ġ. add Trusted Certificate ( client Root . certificate ) ĊĠĠĠĠĠ Ġ. held Certificate ( server Certificate , Ġserver Intermediate . certificate ) ĊĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġval Ġclient Ġ= ĠHand shake Certificates . Builder () ĊĠĠĠĠĠ Ġ. add Trusted Certificate ( server Root . certificate ) ĊĠĠĠĠĠ Ġ. held Certificate ( client Certificate , Ġclient Intermediate . certificate ) ĊĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġval Ġserver Address Ġ= Ġstart Tls Server () ĊĠĠĠ Ġval Ġserver Handshake Future Ġ= Ġdo Server Handshake ( server ) ĊĠĠĠ Ġval Ġclient Handshake Future Ġ= Ġdo Client Handshake ( client , Ġserver Address ) ĊĠĠĠ Ġval Ġserver Handshake Ġ= Ġserver Handshake Future . get () ĊĠĠĠ ĠassertThat ( listOf ( client Certificate . certificate , Ġclient Intermediate . certificate )) ĊĠĠĠĠĠ Ġ. isEqualTo ( server Handshake . peer Certificates ) ĊĠĠĠ ĠassertThat ( listOf ( server Certificate . certificate , Ġserver Intermediate . certificate )) ĊĠĠĠĠĠ Ġ. isEqualTo ( server Handshake . local Certificates ) ĊĠĠĠ Ġval Ġclient Handshake Ġ= Ġclient Handshake Future . get () ĊĠĠĠ ĠassertThat ( listOf ( server Certificate . certificate , Ġserver Intermediate . certificate )) ĊĠĠĠĠĠ Ġ. isEqualTo ( client Handshake . peer Certificates ) ĊĠĠĠ ĠassertThat ( listOf ( client Certificate . certificate , Ġclient Intermediate . certificate )) ĊĠĠĠĠĠ Ġ. isEqualTo ( client Handshake . local Certificates ) ĊĠ Ġ} ĊĊĠ Ġ@ Test Ġfun Ġkey Manager () Ġ{ ĊĠĠĠ Ġval Ġroot Ġ= ĠHel d Certificate . Builder () ĊĠĠĠĠĠ Ġ. certificate Authority ( 1 ) ĊĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġval Ġintermediate Ġ= ĠHel d Certificate . Builder () ĊĠĠĠĠĠ Ġ. certificate Authority ( 0 ) ĊĠĠĠĠĠ Ġ. signed By ( root ) ĊĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġval Ġcertificate Ġ= ĠHel d Certificate . Builder () ĊĠĠĠĠĠ Ġ. signed By ( intermediate ) ĊĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġval Ġhandshake Certificates Ġ= ĠHand shake Certificates . Builder () ĊĠĠĠĠĠ Ġ. add Trusted Certificate ( root . certificate ) Ġ// ĠBo unc y Castle Ġrequires Ġat Ġleast Ġone ĊĠĠĠĠĠ Ġ. held Certificate ( certificate , Ġintermediate . certificate ) ĊĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġassert Private Keys Equals ( ĊĠĠĠĠĠ Ġcertificate . key Pair . private , ĊĠĠĠĠĠ Ġhandshake Certificates . key Manager . get PrivateKey (" private ") ĊĠĠĠ Ġ) ĊĠĠĠ ĠassertThat ( handshake Certificates . key Manager . get Certificate Chain (" private "). toList ()) ĊĠĠĠĠĠ Ġ. isEqualTo ( listOf ( certificate . certificate , Ġintermediate . certificate )) ĊĠ Ġ} ĊĊĠ Ġ@ Test Ġfun Ġplatform Trusted Certificates () Ġ{ ĊĠĠĠ Ġval Ġhandshake Certificates Ġ= ĠHand shake Certificates . Builder () ĊĠĠĠĠĠ Ġ. add Platform Trusted Certificates () ĊĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġval Ġaccepted Iss u ers Ġ= Ġhandshake Certificates . trust Manager . accepted Iss u ers ĊĠĠĠ Ġval Ġnames Ġ= Ġaccepted Iss u ers ĊĠĠĠĠĠ Ġ. map Ġ{ Ġit . subject DN . name Ġ} ĊĠĠĠĠĠ Ġ. toSet () ĊĊĠĠĠ Ġ// ĠIt 's Ġsafe Ġto Ġassume Ġall Ġplatforms Ġwill Ġhave Ġa Ġmajor ĠInternet Ġcertificate Ġissuer . ĊĠĠĠ ĠassertThat ( names ). any Match Ġ{ Ġit . matches ( Regex ("[ A - Z ]+ = En trust .* ")) Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġstart Tls Server (): ĠInet SocketAddress Ġ{ ĊĠĠĠ Ġval Ġserver Socket Factory Ġ= ĠServer Socket Factory . getDefault () ĊĠĠĠ Ġserver Socket Ġ= Ġserver Socket Factory . create Server Socket () ĊĠĠĠ Ġval Ġserver Address Ġ= ĠInet Address . get ByName (" localhost ") ĊĠĠĠ Ġserver Socket !!. bind ( Inet SocketAddress ( server Address , Ġ 0 ), Ġ 5 0 ) ĊĠĠĠ Ġreturn ĠInet SocketAddress ( server Address , Ġserver Socket !!. local Port ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġdo Server Handshake ( server : ĠHand shake Certificates ): ĠFuture < Handshake > Ġ{ ĊĠĠĠ Ġreturn ĠexecutorService . submit < Handshake > Ġ{ ĊĠĠĠĠĠ Ġserver Socket !!. accept (). use Ġ{ Ġraw Socket Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġssl Socket Ġ= Ġserver . ssl Socket Factory (). create Socket ( ĊĠĠĠĠĠĠĠĠĠ Ġraw Socket , ĊĠĠĠĠĠĠĠĠĠ Ġraw Socket . inet Address . host Address , ĊĠĠĠĠĠĠĠĠĠ Ġraw Socket . port , ĊĠĠĠĠĠĠĠĠĠ Ġtrue Ġ/* Ġauto Close Ġ*/ ĊĠĠĠĠĠĠĠ Ġ) Ġas ĠSSL Socket ĊĠĠĠĠĠĠĠ Ġssl Socket . use Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġssl Socket . use Client Mode Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠ Ġssl Socket . want Client Auth Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠ Ġssl Socket . start Handshake () ĊĠĠĠĠĠĠĠĠĠ Ġreturn @ submit Ġssl Socket . session . handshake () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġdo Client Handshake ( ĊĠĠĠ Ġclient : ĠHand shake Certificates , Ġserver Address : ĠInet SocketAddress ĊĠ Ġ): ĠFuture < Handshake > Ġ{ ĊĠĠĠ Ġreturn ĠexecutorService . submit < Handshake > Ġ{ ĊĠĠĠĠĠ ĠSocket Factory . getDefault (). create Socket (). use Ġ{ Ġraw Socket Ġ-> ĊĠĠĠĠĠĠĠ Ġraw Socket . connect ( server Address ) ĊĠĠĠĠĠĠĠ Ġval Ġssl Socket Ġ= Ġclient . ssl Socket Factory (). create Socket ( ĊĠĠĠĠĠĠĠĠĠ Ġraw Socket , ĊĠĠĠĠĠĠĠĠĠ Ġraw Socket . inet Address . host Address , ĊĠĠĠĠĠĠĠĠĠ Ġraw Socket . port , ĊĠĠĠĠĠĠĠĠĠ Ġtrue Ġ/* Ġauto Close Ġ*/ ĊĠĠĠĠĠĠĠ Ġ) Ġas ĠSSL Socket ĊĠĠĠĠĠĠĠ Ġssl Socket . use Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġssl Socket . start Handshake () ĊĠĠĠĠĠĠĠĠĠ Ġreturn @ submit Ġssl Socket . session . handshake () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġassert Private Keys Equals ( expected : ĠPrivate Key , Ġactual : ĠPrivate Key ) Ġ{ ĊĠĠĠ ĠassertThat ( actual . encoded . to ByteString ()). isEqualTo ( expected . encoded . to ByteString ()) ĊĠ Ġ} Ċ } Ċ