Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to connect via TLS #34

Open
RonNabuurs opened this issue Jun 25, 2019 · 4 comments
Open

Unable to connect via TLS #34

RonNabuurs opened this issue Jun 25, 2019 · 4 comments

Comments

@RonNabuurs
Copy link

RonNabuurs commented Jun 25, 2019

Im running a MySQL server with a CA. I want to connect to this server with server verification.

This is my setup. It's an edited variant of the bench TLS script.

{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Main where

import           Control.Concurrent.Async
import           Control.Monad
import           Database.MySQL.Base  hiding (connect, connectDetail)
import           Database.MySQL.TLS
import           System.Environment
import           System.IO.Streams        (fold)
import  qualified Data.ByteString as B

main :: IO ()
main = do
    args <- getArgs
    case args of [threadNum] -> go (read threadNum)
                 _ -> putStrLn "No thread number provided."

go :: Int -> IO ()
go n = do
    cparams <- makeClientParams (CustomCAStore "/path/to/server-ca.pem")

    void . flip mapConcurrently [1..n] $ \ _ -> do
        c <- connect defaultConnectInfo { ciUser = "dev-ssl"
                                        , ciDatabase = "testdb"
                                        , ciPassword = "dev-ssl"
                                        , ciHost = "database.dev"
                                        , ciPort = 3306
                                        }
                     (cparams, "database.dev")

        (fs, is) <- query_ c "SELECT * FROM test"
        (rowCount :: Int) <- fold (\s _ -> s+1) 0 is
        putStr "field name: "
        forM_ fs $ \ f -> B.putStr (columnName f) >> B.putStr ", "
        putStr "\n"
        putStr "numbers of rows: "
        print rowCount

I compile this script with ghc -o test MySQLHaskellTLS.hs
And then run ./test 1

The certificate is valid and signed by the CA. Also the CN and SAN is correct.

The error I get is
test: Short read, expected 4 bytes

I've ran Wireshark and it looks like the TLS handshake works as expected, but when I run the first query the above error pops up. If I look into the package send over the network it seems like the ssl packages is not encrypted, because the SQL query is readable in plain text. I've added a Wireshark file.

The pcap file has 2 connections in it. The first one is when the connection goes wrong (With Haskell TLS) and the second connection is when I connect with the mysql client in my cli. The messages that's most interesting is the message on Arrival Time: Jun 26, 2019 10:18:26.635008878 CEST in the first stream and has as info Ignored Unknown Record.
haskell-tls-bug.zip

Edit:
I've tried to connect with mysql-haskell-openssl and then the SSL connection works as intended.

@winterland1989
Copy link
Owner

This is a bug that's not very easy to debug since tls wrap the connection, could you directly send query packets using combinators from Database.MySQL.Connection to get more details?

@ocheron
Copy link

ocheron commented Nov 13, 2019

It looks writing and closing do not use the SSL stream (c instead of tc):

let conn = MySQLConn tlsIs' (write c) (TCP.close c) consumed

@winterland1989
Copy link
Owner

I see, it's introduced by this commit, Can you revert this and report the result?

@ocheron
Copy link

ocheron commented Dec 29, 2019

I don't use this package. The issue just caught my eye while looking at packages removed from stackage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants