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

Error_EOF connecting to google domains #152

Closed
hesselink opened this issue Aug 4, 2016 · 22 comments
Closed

Error_EOF connecting to google domains #152

hesselink opened this issue Aug 4, 2016 · 22 comments

Comments

@hesselink
Copy link

I'm getting HandshakeFailed Error_EOF when connecting to google domains. For example:

$ stack exec -- tls-simpleclient spreadsheets.google.com -d -v
sending query:
GET / HTTP/1.0



debug: >> Handshake [ClientHello TLS12 (ClientRandom {unClientRandom = "7 \169\DLEE\245\179\249\167\DC1\\\142\145\195\153s\212\b\RS\ETB\n#\202\&4\255\&5P\235\250+K\128"}) (Session Nothing) [107,103,57,51,56,50,47,53,4,5,10,158,49172,49199,49195] [0] [ExtensionRaw 0 "001a0000177370726561647368656574732e676f6f676c652e636f6d",ExtensionRaw 65281 "00",ExtensionRaw 10 "000400170019",ExtensionRaw 11 "0100",ExtensionRaw 13 "000c060105010401030102010202"] Nothing]
debug: >> Alert [(AlertLevel_Fatal,InternalError)]
tls-simpleclient: HandshakeFailed Error_EOF

And:

$ stack exec -- tls-simpleclient google.com -d -v
sending query:
GET / HTTP/1.0



debug: >> Handshake [ClientHello TLS12 (ClientRandom {unClientRandom = "\170T.\199\a\154\GS\USiP\143b\203$\US*\140;\f_\ETB\ai\NUL\136i\178\245\242\211\233\ESC"}) (Session Nothing) [107,103,57,51,56,50,47,53,4,5,10,158,49172,49199,49195] [0] [ExtensionRaw 0 "000d00000a676f6f676c652e636f6d",ExtensionRaw 65281 "00",ExtensionRaw 10 "000400170019",ExtensionRaw 11 "0100",ExtensionRaw 13 "000c060105010401030102010202"] Nothing]
debug: >> Alert [(AlertLevel_Fatal,InternalError)]
tls-simpleclient: HandshakeFailed Error_EOF

This is using tls 1.3.8. Forcing TLS 1.1 makes it work. Any idea what's going on here? And perhaps a workaround? I guess I could patch the used libraries to use TLS 1.1...

@mb21
Copy link

mb21 commented Aug 6, 2016

(I was just about to post the same! Funny to hear from you here again Erik, hope you and silk are doing good :))

So I ran into it this working on pandoc-placetable...

$ tls-simpleclient -d -v 'docs.google.com'
sending query:
GET / HTTP/1.0



debug: >> Handshake [ClientHello TLS12 (ClientRandom {unClientRandom = "\191\USJ\139\252PC\223/\224\207\190\189\166,\226\196\179pgZ\175*nn\169u\185\169D\198\240"}) (Session Nothing) [107,103,57,51,56,50,47,53,4,5,10,158,49199,49195] [0] [ExtensionRaw 0 "001200000f646f63732e676f6f676c652e636f6d",ExtensionRaw 65281 "00",ExtensionRaw 10 "000400170019",ExtensionRaw 11 "0100",ExtensionRaw 13 "000c060105010401030102010202"] Nothing]
debug: >> Alert [(AlertLevel_Fatal,InternalError)]
tls-simpleclient: HandshakeFailed Error_EOF

Maybe #109 wasn't completely fixed with cryptonite > 0.6?

@xnyhps
Copy link

xnyhps commented Aug 6, 2016

I've been having this problem too. Interestingly, it seems that aside from forcing TLS 1.1 or 1.0, it also seems to work with tls-simpleclient when using --no-sni. I've been trying to compare the ClientHello to one sent by curl/openssl s_client/Firefox, but nothing is standing out.

@xnyhps
Copy link

xnyhps commented Aug 6, 2016

Okay, I finally pinned it down. The problematic option is the cipher ECDHE-ECDSA-AES128GCM-SHA256 (0xc02b), recompiling tls-debug without this line:

https://github.com/vincenthz/hs-tls/blob/1415d7330d90049fc5f813afb7fcc116a31b6f7d/debug/src/SimpleClient.hs#L47

made it work again.

The reason Google hangs up the connection is probably because the combination of a ECDSA-authenticated cipher (which they probably prefer over the others) but no advertised ECDSA signature algorithm is causing an unexpected error causing the connection to be closed immediately. Adding at least one ECDSA option also solved this problem:

https://github.com/vincenthz/hs-tls/blob/86080b70167d0bf943b64c0468c3df3198a292ec/core/Network/TLS/Parameters.hs#L184

However, it seems that this sometimes leads to the signature verification to fail, so I guess there's a reason this code is not yet enabled by default:

debug: << Handshake [ServerKeyXchg (SKX_ECDHE_ECDSA (ServerECDHParams (ECDHParams (CurveFP (CurvePrime 115792089210356248762697446949407573530086143415290314195533631308867097853951 (CurveCommon {ecc_a = 115792089210356248762697446949407573530086143415290314195533631308867097853948, ecc_b = 41058363725152142129326129780047268409114441015993725554835256314039467401291, ecc_g = Point 48439561293906451759052585252797914202762949526041747995844080717082404635286 36134250956749795798585127919587881956611106672985015071877198253568414405109, ecc_n = 115792089210356248762697446949407573529996955224135760342422259061068512044369, ecc_h = 1}))) SEC_p256r1) (ECDHPublic (Point 26708436239070440446859528680538632615785287973594904378968739373406720063508 41640453024580522082702145584982534797624706510542987001261748661305002218865) 32)) (DigitallySigned (Just (HashSHA512,SignatureECDSA)) "0E\STX \f\208wd\SUB\171\181a\191I\250\EM?\172u\199\DLE\214s\168\198\246\v\220\211\231~\154\&8\n0h\STX!\NUL\190\CAN/\128$s$\b\252zn\195\191\162;7U\131\230Bk\136\225\&4\ACK\229\EM\134\FS\143i\160"))]
debug: >> Alert [(AlertLevel_Fatal,HandshakeFailure)]
tls-simpleclient: HandshakeFailed (Error_Protocol ("bad SignatureECDSA for ecdhparams",True,HandshakeFailure))

hesselink added a commit to silkapp/hs-tls that referenced this issue Aug 9, 2016
@vincenthz
Copy link
Collaborator

vincenthz commented Aug 10, 2016

Thanks @xnyhps about the detailed analysis. I'll see about adding the signature ECDSA

@xnyhps
Copy link

xnyhps commented Aug 10, 2016

I tested it a bit more and found that:

  • (Struct.HashSHA1, SignatureECDSA) always worked
  • (Struct.HashSHA256, SignatureECDSA) always worked
  • (Struct.HashSHA384, SignatureECDSA) worked about half the time
  • (Struct.HashSHA512, SignatureECDSA) worked about half the time

I think, but I have not dived into the RFCs enough to say for sure, that the problem is when truncating a SHA-512/SHA-384 hash when verifying a ECDSA signature generated on P-256 (which is what Google's ECC certs used):

https://hackage.haskell.org/package/cryptonite-0.17/docs/src/Crypto-PubKey-ECC-ECDSA.html#tHash

This shifts the hash right as an integer until it is less than the upper bound, but I think TLS requires you to only take the leftmost x bytes. This will fail about half the time as it will shift by one less if the first bit of the hash is 0.

@ocheron
Copy link
Contributor

ocheron commented Aug 24, 2016

I'm no expert either but I think your analysis is right. The hash truncation
is described in FIPS 186-4 at §6.4 as well as the Wikipedia page for ECDSA:
use the Ln leftmost bits of e, where Ln is the bit length of the
group order n

The current implementation in function tHash shifts the hash number
incorrectly because it uses the bit length of n as well as the bit length
of the hash value e. But for the hash value the length is fixed and defined
by the algorithm. Leading zeros should be counted when present.

So the variable d can be changed to:

d = hashDigestSize hashAlg * 8 - numBits n

@tolysz
Copy link
Contributor

tolysz commented Aug 24, 2016

@ocheron Could you create a PR for it?

@ocheron
Copy link
Contributor

ocheron commented Aug 24, 2016

Yes I work on it. I just need to finish converting new test vectors to add to the test suite.

@tolysz
Copy link
Contributor

tolysz commented Sep 7, 2016

Is there enything outstanding for this issue?

@ocheron
Copy link
Contributor

ocheron commented Sep 7, 2016

There is still an issue about inconsistent extensions being sent: in ciphersuite_all one cipher is ECDSA-based, but ECDSA is not listed as a supported signature algorithm in the default configuration. Possible solutions would be to remove one or add the other (depending on whether ECC implementation is considered ready or not).

@horejsek
Copy link

I'm little bit lost in this discussion. :-) What's current status of this issue? There is more pages using ECDHE_ECDSA for key exchange. Will be this fixed soon or is there some workaround? Or is it possible somehow help (even if I'm not SSL guru)? :-) Thanks!

@ocheron
Copy link
Contributor

ocheron commented Oct 25, 2016

This issue still exists: a connection to spreadsheets.google.com:443 fails with the error described above.

The workaround is simple if the API you use gives control over TLS parameters supportedHashSignatures or supportedCiphers: you just need to enable ECDSA in one or disable it in the other.

@horejsek
Copy link

I use http from Network.HTTP.Conduit to do the job which doesn't provides those options. Or do I missed something or is there some better library?

@tolysz
Copy link
Contributor

tolysz commented Oct 25, 2016

@horejsek it would be awesome if you could create the change for that library... it should be as easy as discussing the change and expose tls settings there

@hesselink
Copy link
Author

Another option is to use our fork of tls. It just turns off this cipher so you don't have to pass in the options.

@horejsek
Copy link

@tolysz I'm not sure if it's good idea. It sounds like high-level library for me where you just want to do some request without worrying about lower level. But maybe it could be done by allowing to create manager from http-client-tls with options for ciphers which is used for making requests. Anyway I still think programmer shouldn't tweak security problems in app layer. Someone else more clever should decide what's best to use. What do you think?

@hasselink Thanks! I will think about it. :-)

@mb21
Copy link

mb21 commented Oct 25, 2016

Well, it seems it's rather hard to construct the proper TLSSettings to pass on to Network.HTTP.Conduit.

It seems this should really be fixed in hs-tls... @ocheron, are you still undecided on whether to enable ECDSA in supportedHashSignatures or disable it in supportedCiphers? or are you waiting for @vincenthz, or...?

@tolysz
Copy link
Contributor

tolysz commented Oct 25, 2016

Maybe there should be a web usable subset of protocols and any "normal" client will use just that?

@ocheron
Copy link
Contributor

ocheron commented Oct 26, 2016

I'm still undecided concerning the exact direction because I'm not sure of the consequences for security and performance (enabling ECDSA), or interoperability (disabling).

A first step could be to change the default set of algorithms only in the connection package:

@mb21
Copy link

mb21 commented Oct 27, 2016

Yes, I think the default generated by TLSSettingsSimple False False False should result in settings that are able to connect to google domains (guess this must be fixed in the hs-connection package). Whether to enable ECDSA in supportedHashSignatures or disable it in supportedCiphers, I cannot say. But either one or the other should be done quickly to make the default settings usable again.

an intermediate between TLSSettings and TLSSettingsSimple

Indeed, but as you mentioned, that's a separate issue.

@ocheron
Copy link
Contributor

ocheron commented Nov 1, 2016

It's a different issue, however I feel more comfortable changing default parameters when it is easy to override. So I worked on a possible solution for both issues and located in the package connection.

@vincenthz
Copy link
Collaborator

fixed in 1.3.9

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

7 participants