haskell-tls / hs-certificate

Certificate and Key Reader/Writer in haskell
60 stars 57 forks source link

Order of certificates loaded by readSignedObject #57

Closed DaveCTurner closed 8 years ago

DaveCTurner commented 9 years ago

Hi,

The function readSignedObject reverses the order of the objects read from the file. The order of objects is important (see e.g. http://tools.ietf.org/html/rfc4346#section-7.4.2) and this reversal is deeply surprising.

Typically, certificate chains are stored in a file in order from leaf to root. For instance, nginx and Apache expect this ordering. Additionally, this is the order that a CertificateChain must be in e.g. the return value to onCertificateRequest.

Probably a duplicate of #31 which was closed due to lack of interest, but consider me interested now!

Cheers,

David

DaveCTurner commented 8 years ago

We were bitten by this again recently so I've sent a PR.

A simple test program showing the problem:

import Data.Monoid
import Network.HTTP.Types.Status
import Network.TLS
import Network.TLS.Extra.Cipher
import Network.Wai
import Network.Wai.Handler.Warp
import Network.Wai.Handler.WarpTLS
import System.Environment

main :: IO ()
main = do
  [certFile, keyFile] <- getArgs
  runTLS
    ((tlsSettings certFile keyFile) {tlsCiphers = ciphersuite_strong})
    (setPort 17167 defaultSettings)
    (\_ respond -> respond $ responseBuilder status200 [] mempty)

If this is pointed at a cert chain (of at least two certs) that you give to Apache or nginx then it fails with the error

no ciphers available with those parameters

but if the order of certs in the cert chain is reversed then it works as expected.

The attached PR makes things behave as expected.

Cheers,

DaveCTurner commented 8 years ago

In case it helps, here's a certificate chain ordered from leaf to root which works in nginx but not in warp-tls:

-----BEGIN CERTIFICATE-----
MIIB/DCCAWWgAwIBAgIBAzANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDExtFeGFt
cGxlIGludGVybWVkaWF0ZSBDQSBrZXkwHhcNMTUwODA3MTA1ODExWhcNMzMwMTAx
MTA1ODExWjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQAD
gY0AMIGJAoGBAKseFAA35fRf/3Hoj9sB9xIhBmQbI6wyw1G7lboW7397Oc5Jr6Y0
KNtMjP3opBoC+ZY0Rep49KjgLMq+77YXM8ptdRP029VRWH304Lhfii/UThpmJxKw
x3PCC+sf52dTyOPsDiVlXYPENCaG+7FSgFsQaT08qlMsWcu8bZ8uJJf/AgMBAAGj
TDBKMDAGA1UdIwQpMCehIqQgMB4xHDAaBgNVBAMTE0V4YW1wbGUgcm9vdCBDQSBr
ZXmCAQIwCQYDVR0TBAIwADALBgNVHQ8EBAMCBPAwDQYJKoZIhvcNAQELBQADgYEA
OIoRtw9HqUaRdafcE0F8tWUNaYdYbiZ4P421hEYejx2EsEvV633L4BeE5qRcZhke
f5FfXkFRu2gPvmqYi72JS9RIcDBZ+XIEU3J0epq0GnD2IuqSiHsHnheiEqzJJXYq
cB1De+FoJYDPfV8M6hHDFVb/rzk+drWB6kn6+0VrjB8=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICCTCCAXKgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDExNFeGFt
cGxlIHJvb3QgQ0Ega2V5MB4XDTE1MDgwNzEwNTgxMVoXDTM0MDEwMTEwNTgxMVow
JjEkMCIGA1UEAxMbRXhhbXBsZSBpbnRlcm1lZGlhdGUgQ0Ega2V5MIGfMA0GCSqG
SIb3DQEBAQUAA4GNADCBiQKBgQCcye2QW7I3bzarZmmsZ/9HJ2IyhrTJKywT/j/G
fuJm+DpJzsmCI9eCIIYzhmFIlyb8LmWM7PmQ3nPoeum+MdtdfVnbeoDzzhRjwzER
ytjGCIgSiDeAQmB2ewRJhgdFzm/kSuK6fwGW9VzYnQ8dp3v24f/FHXHXo9D5F+Ah
MsG5kwIDAQABo08wTTAwBgNVHSMEKTAnoSKkIDAeMRwwGgYDVQQDExNFeGFtcGxl
IHJvb3QgQ0Ega2V5ggEBMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqG
SIb3DQEBCwUAA4GBAMOfb2ol6eu4sMqsjErIDa5aThfxtadzMxQFz3rKcQ0iwpW2
CPn7TAsbYxXS1DAeqYMUBp/C5L+IuxqxGM/nPx5C0dMZpLFavGKid0ttz2jkvTEt
tv0/nphP34yN3Ye4d9gETJkD1RKcPSSsRSO8AhBNIJxFpt57tE7Bm1scEeeb
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICATCCAWqgAwIBAgIBATANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDExNFeGFt
cGxlIHJvb3QgQ0Ega2V5MB4XDTE1MDgwNzEwNTgxMVoXDTM1MDEwMTEwNTgxMVow
HjEcMBoGA1UEAxMTRXhhbXBsZSByb290IENBIGtleTCBnzANBgkqhkiG9w0BAQEF
AAOBjQAwgYkCgYEA8y3u+KhRfuOBYroLAdkYZCx667kFjMIt89NHa5hWaj2HVtEK
phPBH7qyS5VukAZf4jOU1b9Kui4N/8Fc1hwMWC9FieoJ6fKdn3C+FdWyrY0zlo6C
zFSPYTRhFX7JwecLDTO2FApLIypAOXvlgZztwEhc2/LcFTU24FWX9H5DrJcCAwEA
AaNPME0wMAYDVR0jBCkwJ6EipCAwHjEcMBoGA1UEAxMTRXhhbXBsZSByb290IENB
IGtleYIBATAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsF
AAOBgQB24iPP6COK3mLxWGszA+dMGbp5jsKWKrgRKKBDlg0798OlAolnIBYkKgUY
qrZAztm1Nw9orVHuJC9My40midu1IIDfnzFv2Titya9hF1F7jO3QzJv4y+WeRmxN
kN6QGeRftLRdIvYhPfZnOvdA4mA1N0hSCJZP6rlC11/yjPxwHw==
-----END CERTIFICATE-----

and here is the private key for the leaf:

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCrHhQAN+X0X/9x6I/bAfcSIQZkGyOsMsNRu5W6Fu9/eznOSa+m
NCjbTIz96KQaAvmWNEXqePSo4CzKvu+2FzPKbXUT9NvVUVh99OC4X4ov1E4aZicS
sMdzwgvrH+dnU8jj7A4lZV2DxDQmhvuxUoBbEGk9PKpTLFnLvG2fLiSX/wIDAQAB
AoGAGQoftyB239mkUZDMbCnPc7Gtc7yc7bfH6Q/gCwkMJsVrYgpaT6HWULDU+Nqw
GLZSu24OxQ7KDmQvacOi5CxlAX7EDFockuFc5mXkhXOQmu9JqPTNrvmsGrPqf0zR
x9UntvJ4jEmM6YV5tq9PncUIjTUzxqsjfNr4TI1BtlChOzECQQDdpMk5kWRrKYno
U46PCBuSash0led/QHiNYXPXvmg8lhFoSNmwAiv2LhzG6G+UwTvUUFPH7DvUYp7+
y4b2kG7zAkEAxaRSrqqRaiqwRvze2qaHyz3qJKSpXmYHwGf22Ke5ckrKjgjrVrg2
DXhW7GFIWBXfY12FKstwRwKqiXcTFSetxQJALZGNlXpg7O9TXSKgsqN2F7pAkEep
mq4EmvyoNnj9MUehOJGRv/ASXcDJRdPP7QN1a4dAUmAtRNMp4TSzAMpdJQJAfvAn
Wp+afcGlLjLDP1Ot6898TsSjM0n8uIsNc+Flrg5zQf5giHYP4V7lFTT2Lfz+WOd7
3ByFpFYGCfw8eV3esQJBAM3Je6JQg1Hs/YIWXurQKQEZBuuFf7XMnUyNL1cpxkOT
EW3GV0miHFvu3/vVM8vs1rHgkyRDsJykuvLPMGgHvFk=
-----END RSA PRIVATE KEY-----

If you feed these into the above program then do

openssl s_client -connect localhost:17167

the server will report

no ciphers available with those parameters

and the client won't get anything. This PR fixes this.