Skip to content

Commit 96dc0f4

Browse files
smattinglepsa
authored andcommitted
Revert "Use openssl instead of tls in federator http2 client (wireapp#3051)" (wireapp#3148)
This reverts commit fd78663.
1 parent 9039d06 commit 96dc0f4

File tree

21 files changed

+428
-288
lines changed

21 files changed

+428
-288
lines changed

libs/wire-api-federation/default.nix

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
, errors
1616
, exceptions
1717
, gitignoreSource
18-
, HsOpenSSL
1918
, hspec
2019
, hspec-discover
2120
, http-media
@@ -68,7 +67,6 @@ mkDerivation {
6867
either
6968
errors
7069
exceptions
71-
HsOpenSSL
7270
http-media
7371
http-types
7472
http2

libs/wire-api-federation/src/Wire/API/Federation/Client.hs

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ import Data.Domain
4747
import qualified Data.Sequence as Seq
4848
import qualified Data.Set as Set
4949
import Data.Streaming.Network
50-
import qualified Data.Text as Text
5150
import qualified Data.Text.Encoding as Text
5251
import qualified Data.Text.Encoding.Error as Text
5352
import qualified Data.Text.Lazy.Encoding as LText
@@ -59,9 +58,8 @@ import qualified Network.HTTP.Media as HTTP
5958
import qualified Network.HTTP.Types as HTTP
6059
import qualified Network.HTTP2.Client as HTTP2
6160
import qualified Network.Socket as NS
61+
import qualified Network.TLS as TLS
6262
import qualified Network.Wai.Utilities.Error as Wai
63-
import OpenSSL.Session (SSL, SSLContext)
64-
import qualified OpenSSL.Session as SSL
6563
import Servant.Client
6664
import Servant.Client.Core
6765
import Servant.Types.SourceT
@@ -124,7 +122,7 @@ connectSocket hostname port =
124122
$ getSocketFamilyTCP hostname port NS.AF_UNSPEC
125123

126124
performHTTP2Request ::
127-
Maybe SSLContext ->
125+
Maybe TLS.ClientParams ->
128126
HTTP2.Request ->
129127
ByteString ->
130128
Int ->
@@ -140,42 +138,34 @@ performHTTP2Request mtlsConfig req hostname port = try $ do
140138
pure $ resp $> foldMap byteString b
141139

142140
withHTTP2Request ::
143-
Maybe SSLContext ->
141+
Maybe TLS.ClientParams ->
144142
HTTP2.Request ->
145143
ByteString ->
146144
Int ->
147145
(StreamingResponse -> IO a) ->
148146
IO a
149-
withHTTP2Request mSSLCtx req hostname port k = do
147+
withHTTP2Request mtlsConfig req hostname port k = do
150148
let clientConfig =
151149
HTTP2.ClientConfig
152-
{ HTTP2.scheme = "https",
153-
HTTP2.authority = hostname,
154-
HTTP2.cacheLimit = 20
155-
}
150+
"https"
151+
hostname
152+
{- cacheLimit: -} 20
156153
E.handle (E.throw . FederatorClientHTTP2Exception) $
157154
bracket (connectSocket hostname port) NS.close $ \sock -> do
158-
let withHTTP2Config k' = case mSSLCtx of
155+
let withHTTP2Config k' = case mtlsConfig of
159156
Nothing -> bracket (HTTP2.allocSimpleConfig sock 4096) HTTP2.freeSimpleConfig k'
160-
Just sslCtx -> do
161-
ssl <- E.handle (E.throw . FederatorClientTLSException) $ do
162-
ssl <- SSL.connection sslCtx sock
163-
-- We need to strip trailing dot because openssl doesn't ignore
164-
-- it. https://github.com/openssl/openssl/issues/11560
165-
let hostnameStr =
166-
Text.unpack $ case Text.decodeUtf8 hostname of
167-
(Text.stripSuffix "." -> Just withoutTrailingDot) -> withoutTrailingDot
168-
noTrailingDot -> noTrailingDot
169-
SSL.setTlsextHostName ssl hostnameStr
170-
SSL.enableHostnameValidation ssl hostnameStr
171-
SSL.connect ssl
172-
pure ssl
173-
bracket (allocTLSConfig ssl 4096) freeTLSConfig k'
157+
-- FUTUREWORK(federation): Use openssl
158+
Just tlsConfig -> do
159+
ctx <- E.handle (E.throw . FederatorClientTLSException) $ do
160+
ctx <- TLS.contextNew sock tlsConfig
161+
TLS.handshake ctx
162+
pure ctx
163+
bracket (allocTLSConfig ctx 4096) freeTLSConfig k'
174164
withHTTP2Config $ \conf -> do
175165
HTTP2.run clientConfig conf $ \sendRequest ->
176166
sendRequest req $ \resp -> do
177167
let headers = headersFromTable (HTTP2.responseHeaders resp)
178-
result = fromAction BS.null $ HTTP2.getResponseBodyChunk resp
168+
result = fromAction BS.null (HTTP2.getResponseBodyChunk resp)
179169
case HTTP2.responseStatus resp of
180170
Nothing -> E.throw FederatorClientNoStatusCode
181171
Just status ->
@@ -361,23 +351,31 @@ versionNegotiation =
361351
freeTLSConfig :: HTTP2.Config -> IO ()
362352
freeTLSConfig cfg = free (HTTP2.confWriteBuffer cfg)
363353

364-
allocTLSConfig :: SSL -> HTTP2.BufferSize -> IO HTTP2.Config
365-
allocTLSConfig ssl bufsize = do
354+
allocTLSConfig :: TLS.Context -> HTTP2.BufferSize -> IO HTTP2.Config
355+
allocTLSConfig ctx bufsize = do
366356
buf <- mallocBytes bufsize
367357
timmgr <- System.TimeManager.initialize $ 30 * 1000000
358+
ref <- newIORef mempty
368359
let readData :: Int -> IO ByteString
369-
-- Sometimes the frame header says that the payload length is 0. Reading 0
370-
-- bytes multiple times seems to be causing errors in openssl. I cannot
371-
-- figure out why. The previous implementation didn't try to read from the
372-
-- socket when trying to read 0 bytes, so special handling for 0 maintains
373-
-- that behaviour.
374-
readData 0 = pure ""
375-
readData n = SSL.read ssl n `catch` \(_ :: SSL.ConnectionAbruptlyTerminated) -> pure mempty
360+
readData n = do
361+
chunk <- readIORef ref
362+
if BS.length chunk >= n
363+
then case BS.splitAt n chunk of
364+
(result, chunk') -> do
365+
writeIORef ref chunk'
366+
pure result
367+
else do
368+
chunk' <- TLS.recvData ctx
369+
if BS.null chunk'
370+
then pure chunk
371+
else do
372+
modifyIORef ref (<> chunk')
373+
readData n
376374
pure
377375
HTTP2.Config
378376
{ HTTP2.confWriteBuffer = buf,
379377
HTTP2.confBufferSize = bufsize,
380-
HTTP2.confSendAll = SSL.write ssl,
378+
HTTP2.confSendAll = TLS.sendData ctx . LBS.fromStrict,
381379
HTTP2.confReadN = readData,
382380
HTTP2.confPositionReadMaker = HTTP2.defaultPositionReadMaker,
383381
HTTP2.confTimeoutManager = timmgr

libs/wire-api-federation/src/Wire/API/Federation/Error.hs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,16 @@ import Imports
8585
import Network.HTTP.Types.Status
8686
import qualified Network.HTTP.Types.Status as HTTP
8787
import qualified Network.HTTP2.Frame as HTTP2
88+
import Network.TLS
8889
import qualified Network.Wai.Utilities.Error as Wai
89-
import OpenSSL.Session (SomeSSLException)
9090
import Servant.Client
9191
import Wire.API.Error
9292

9393
-- | Transport-layer errors in federator client.
9494
data FederatorClientHTTP2Error
9595
= FederatorClientNoStatusCode
9696
| FederatorClientHTTP2Exception HTTP2.HTTP2Error
97-
| FederatorClientTLSException SomeSSLException
97+
| FederatorClientTLSException TLSException
9898
| FederatorClientConnectionError IOException
9999
deriving (Show, Typeable)
100100

@@ -213,7 +213,7 @@ federationRemoteHTTP2Error (FederatorClientTLSException e) =
213213
Wai.mkError
214214
(HTTP.mkStatus 525 "SSL Handshake Failure")
215215
"federation-tls-error"
216-
(LT.pack (displayException e))
216+
(LT.fromStrict (displayTLSException e))
217217
federationRemoteHTTP2Error (FederatorClientConnectionError e) =
218218
Wai.mkError
219219
federatorConnectionRefusedStatus
@@ -241,6 +241,22 @@ federationRemoteResponseError status =
241241
<> LT.pack (show (HTTP.statusCode status))
242242
)
243243

244+
displayTLSException :: TLSException -> Text
245+
displayTLSException (Terminated _ reason err) = T.pack reason <> ": " <> displayTLSError err
246+
displayTLSException (HandshakeFailed err) = T.pack "handshake failed: " <> displayTLSError err
247+
displayTLSException ConnectionNotEstablished = T.pack "connection not established"
248+
249+
displayTLSError :: TLSError -> Text
250+
displayTLSError (Error_Misc msg) = T.pack msg
251+
displayTLSError (Error_Protocol (msg, _, _)) = "protocol error: " <> T.pack msg
252+
displayTLSError (Error_Certificate msg) = "certificate error: " <> T.pack msg
253+
displayTLSError (Error_HandshakePolicy msg) = "handshake policy error: " <> T.pack msg
254+
displayTLSError Error_EOF = "end-of-file error"
255+
displayTLSError (Error_Packet msg) = "packet error: " <> T.pack msg
256+
displayTLSError (Error_Packet_unexpected actual expected) =
257+
"unexpected packet: " <> T.pack expected <> ", " <> "got " <> T.pack actual
258+
displayTLSError (Error_Packet_Parsing msg) = "packet parsing error: " <> T.pack msg
259+
244260
federationServantErrorToWai :: ClientError -> Wai.Error
245261
federationServantErrorToWai (DecodeFailure msg _) = federationInvalidBody msg
246262
-- the following error is never thrown by federator client

libs/wire-api-federation/wire-api-federation.cabal

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ library
8686
, either
8787
, errors
8888
, exceptions
89-
, HsOpenSSL
9089
, http-media
9190
, http-types
9291
, http2

services/federator/default.nix

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
, filepath
2626
, gitignoreSource
2727
, hinotify
28-
, HsOpenSSL
2928
, hspec
3029
, http-client
3130
, http-client-openssl
@@ -105,7 +104,6 @@ mkDerivation {
105104
extended
106105
filepath
107106
hinotify
108-
HsOpenSSL
109107
http-client
110108
http-client-openssl
111109
http-media
@@ -168,7 +166,6 @@ mkDerivation {
168166
extended
169167
filepath
170168
hinotify
171-
HsOpenSSL
172169
hspec
173170
http-client
174171
http-client-openssl
@@ -236,7 +233,6 @@ mkDerivation {
236233
extended
237234
filepath
238235
hinotify
239-
HsOpenSSL
240236
http-client
241237
http-client-openssl
242238
http-media

services/federator/exec/Main.hs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,10 @@ where
2222

2323
import Federator.Run (run)
2424
import Imports
25-
import OpenSSL
2625
import Util.Options (getOptions)
2726

2827
main :: IO ()
29-
main = withOpenSSL $ do
28+
main = do
3029
let desc = "Federation Service"
3130
defaultPath = "/etc/wire/federator/conf/federator.yaml"
3231
options <- getOptions desc Nothing defaultPath

services/federator/federator.cabal

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ library
116116
, extended
117117
, filepath
118118
, hinotify
119-
, HsOpenSSL
120119
, http-client
121120
, http-client-openssl
122121
, http-media
@@ -211,11 +210,63 @@ executable federator
211210
-Wredundant-constraints
212211

213212
build-depends:
214-
base
213+
aeson
214+
, async
215+
, base
216+
, bilge
217+
, binary
218+
, bytestring
219+
, bytestring-conversion
220+
, constraints
221+
, containers
222+
, data-default
223+
, dns
224+
, dns-util
225+
, either
226+
, exceptions
227+
, extended
215228
, federator
216-
, HsOpenSSL
229+
, filepath
230+
, hinotify
231+
, http-client
232+
, http-client-openssl
233+
, http-media
234+
, http-types
235+
, http2
217236
, imports
237+
, kan-extensions
238+
, lens
239+
, metrics-core
240+
, metrics-wai
241+
, mtl
242+
, network
243+
, network-uri
244+
, pem
245+
, polysemy
246+
, polysemy-wire-zoo
247+
, retry
248+
, servant
249+
, servant-client-core
250+
, streaming-commons
251+
, string-conversions
252+
, text
253+
, time-manager
254+
, tinylog
255+
, tls
218256
, types-common
257+
, unix
258+
, uri-bytestring
259+
, uuid
260+
, wai
261+
, wai-utilities
262+
, warp
263+
, warp-tls
264+
, wire-api
265+
, wire-api-federation
266+
, x509
267+
, x509-store
268+
, x509-system
269+
, x509-validation
219270

220271
default-language: Haskell2010
221272

@@ -272,7 +323,7 @@ executable federator-integration
272323
ghc-options:
273324
-O2 -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates
274325
-Wpartial-fields -fwarn-tabs -optP-Wno-nonportable-include-path
275-
-Wredundant-constraints -threaded -with-rtsopts=-N1
326+
-Wredundant-constraints
276327

277328
build-depends:
278329
aeson
@@ -296,7 +347,6 @@ executable federator-integration
296347
, federator
297348
, filepath
298349
, hinotify
299-
, HsOpenSSL
300350
, hspec
301351
, http-client
302352
, http-client-openssl
@@ -428,7 +478,6 @@ test-suite federator-tests
428478
, federator
429479
, filepath
430480
, hinotify
431-
, HsOpenSSL
432481
, http-client
433482
, http-client-openssl
434483
, http-media

services/federator/src/Federator/Env.hs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,21 @@ module Federator.Env where
2424
import Bilge (RequestId)
2525
import Control.Lens (makeLenses)
2626
import Data.Metrics (Metrics)
27+
import Data.X509.CertificateStore
2728
import Federator.Options (RunSettings)
2829
import Imports
2930
import Network.DNS.Resolver (Resolver)
3031
import qualified Network.HTTP.Client as HTTP
31-
import OpenSSL.Session (SSLContext)
32+
import qualified Network.TLS as TLS
3233
import qualified System.Logger.Class as LC
3334
import Util.Options
3435
import Wire.API.Federation.Component
3536

37+
data TLSSettings = TLSSettings
38+
{ _caStore :: CertificateStore,
39+
_creds :: TLS.Credential
40+
}
41+
3642
data Env = Env
3743
{ _metrics :: Metrics,
3844
_applog :: LC.Logger,
@@ -41,7 +47,8 @@ data Env = Env
4147
_runSettings :: RunSettings,
4248
_service :: Component -> Endpoint,
4349
_httpManager :: HTTP.Manager,
44-
_sslContext :: IORef SSLContext
50+
_tls :: IORef TLSSettings
4551
}
4652

53+
makeLenses ''TLSSettings
4754
makeLenses ''Env

0 commit comments

Comments
 (0)