haskell-tls / hs-tls

TLS/SSL implementation in haskell
Other
403 stars 92 forks source link

Question: no ciphers available with those parameters #156

Open mdibaiee opened 8 years ago

mdibaiee commented 8 years ago

Hey,

First, thank you for creating this.

I'm switching from HsOpenSSL (it doesn't support ALPN), but I'm getting no ciphers available with those parameters, here is my code:

server :: Settings -> Worker -> IO ()
server (Settings bindAddr port bufferSize cert key) worker =
  do
    chain <- credentialLoadX509 cert key

    let (cc, pkey) = either error id chain
        (CertificateChain c) = cc
        params = ServerParams { serverCACertificates = def c
                              , serverWantClientCert = False
                              , serverShared         = def
                              , serverHooks          = def
                              , serverSupported      = def { supportedCiphers = ciphersuite_all }
                              , serverDebug = def
                              }

    serve HostAny port $ \(socket, remoteAddr) -> do
      ctx <- contextNew socket params

      let write = sendData ctx . BL.fromStrict
           read  = recvData ctx
      worker write rcv `catch` \e -> print (e :: SomeException)

    return ()

I generated my certificate and key using openssl: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -days 365

I digged into the code, and I see ciphers get filtered out in getCiphers, but I don't understand why all the ciphers get filtered out in my case.

P.S: I think it would be great to have examples, makes usage much easier for users.

tolysz commented 8 years ago

Could you specify which ciphers your client supports and which ones should match the server in your config?

mdibaiee commented 8 years ago

@tolysz: Well, as for client, Firefox and cURL, neither work, I think Firefox supports most, if not all, ciphers known to hs-tls and I've enabled all ciphers in the server, and they are all filtered out before reaching onCipherChoosing hook.

Did I understand your question correctly?

ocheron commented 8 years ago

Comparing with the example in tls-simpleserver, you could try to add:

serverShared = def { sharedCredentials = Credentials [(cc, pkey)] }
vincenthz commented 8 years ago

On the server side, the ciphers are going to be filtered according to what the whole configuration will permit.

For example if you want to have a DH based cipher, you need to have setup DH in the TLS structure.

Also the filtering happens with what the certificates you have loaded. If you certificates doesn't allow signing with the RSA keys for example, if it will effectively filter out ciphers that requires RSA signing.

mdibaiee commented 8 years ago

@ocheron's solution actually worked! Thanks! I'm wondering why though, may someone explain?

@vincenthz I see, as a beginner in the field of the whole SSL/TLS thing, I couldn't understand how things got together, examples / documentation would really help, thank you!

ocheron commented 7 years ago

At minimum you need to provide the certificate and private key that the server must use to secure the communication. Without this, no key exchange can happen: none of the commonly-used ciphers are applicable and you get the error you reported.

As Vincent mentioned, you can get increased security by providing Diffie-Hellman parameters in serverDHEParams (using standardized parameters, or generating your own using cryptonite generateParams in Crypto.PubKey.DH)