haskell-tls / hs-tls

TLS/SSL implementation in haskell
Other
402 stars 88 forks source link

HandshakeFailed (Error_Packet_unexpected "Alert [(AlertLevel_Fatal,DecryptError)]" " expected: change cipher") #111

Closed lippling closed 7 years ago

lippling commented 9 years ago

Hello,

I have an application that connects to the Apple Push Notification Service. Everything worked well in 1.2.17, but today I upgraded to 1.3.1 and the handshake fails.

Any ideas? Downgrade to 1.2.17 helps, but I want to use a newer nightlty Stackage for GHC 7.10.1.

My ClientSettings are:

createTLSParams :: HostName -> Credential -> ClientParams
createTLSParams hostname credential = (defaultParamsClient hostname B.empty) {
    clientHooks = def {
        onCertificateRequest = const $ return $ Just credential
      , onServerCertificate = \ _ _ _ _ -> return []
    },
    clientSupported = def {
      supportedCiphers = ciphersuite_strong
    }
}

debug: S Handshake [ClientHello TLS12 (ClientRandom "%\FS\196\200\ETX\255\185?e@)\181;&\fp\237\233\142V\176\EM\134\201_,5\133\172&8A\213") (Session Nothing) [107,103,57,51,56,50,60,61,47,53,102,5,4,10,158] [0] [(0,"\NUL\EM\NUL\NUL\SYNgateway.push.apple.com"),(65281,"\NUL"),(13,"\NUL\f\ACK\SOH\ENQ\SOH\EOT\SOH\ETX\SOH\STX\SOH\STX\STX")] Nothing] debug: R Handshake [ServerHello TLS11 (ServerRandom "\235)mIG(\212\140\&3w\183\224\221\135r\162\222\150Pm\DC4\DC3\f2J\202\142i\177\233\168") (Session Nothing) 47 0 [(65281,"\NUL")]] debug: R Handshake [Certificates (CertificateChain ....... debug: R Handshake [CertRequest [CertificateType_RSA_Sign,CertificateType_DSS_Sign,CertificateType_Unknown 64] Nothing []] debug: R Handshake [ServerHelloDone] debug: S Handshake [Certificates (CertificateChain ................... debug: S Handshake [ClientKeyXchg (CKX_RSA "\SOH\NUL\177\CANOm<@A\181\184\138.H\232\217\143\137NU\133*\164\215\248\160\DC3\221+\255\ENQ\132Q((\168\169\EOTQ\204\ra\180\217,\ETBE\171\FS#\150\SUB\135\RS\174U\SYN\216y\189L)\202y\224\167\v\176\162\EOTj;\DC4\162\GS\191i1\204\154\234\217\218\174\224\157\147\143\161\170\200\251\181\246\164=\244\218r\217\"j\252\246\bYw\133\&6R#g/\SYN\243\195/8\v\ACKf{\158\NUL\ETX\155\177\249;om\168e\v\225\129]I\EM.'\133\214\199<\206\DC3\RS\171\152}\213J\SUB(\SOy'\129J9\237\157\232\254\161L\169t\199k\136\235\242J\r\224\CANi\161\181\146y\217U\219\158\134\209\EM\192b]\194\149\ETB\DC3'\EOT1_C\227\142\178\183\vv[m5\240i\148\189E\142\209\STX(.\EM*MM\138\142FS^4\129\225\239^\128q)\173\v\FSO\188g\203_RsJ@\179\228\176\160{f")] debug: S Handshake [CertVerify (DigitallySigned Nothing "\DC3\220y\241Rhf\237\207x\239\208[\132\171\254`\208snO\DC4\218\199uW\184\168\FSI@C\233C{\144Z3\FS\195&8u\245\149\t\ETX\185\229P\NUL \169h\219{6\165\195\140{\246\138fS\154\198&1B\SI#i\t\205\179GYi\131\251FK\201F\156<9\211tN\164W\138\v|H\ESC<JN\249\254\NUL)\SUB\SUB{\172\SOy\214\162\238\254C\137.\197]\b\229\245\132\241\162\217\DEL\164\165\183+\171\134\140B\240\175\221G\212OMD\153\140c_a\151\201\151\146\225\r\158\205\EOT\220\254\NAK\226\128\tt\ENQ\ETB\221t\197d\242\219\145\172&9s\212\213\DC2sn\161\164\CAN\169\156\178\153e\207\140\190\b\241\180\141\245I\176\161\175\240&9=C\191\SI.U\194/\b\166\197dtl\245f6\NAK\155\142S[\182\140\207v\ESC\232\222\255B~\149\216\b\180X\147\237\ACK\151\214\228\139\DC1Lq\ETX\162Q\207")] debug: S ChangeCipherSpec debug: S Handshake [Finished "zw}U\168\rXA\207\254a5"] debug: R Alert [(AlertLevel_Fatal,DecryptError)] debug: S Alert [(AlertLevel_Fatal,InternalError)] debug: S Alert [(AlertLevelFatal,InternalError)] ** Exception: HandshakeFailed (Error_Packet_unexpected "Alert [(AlertLevel_Fatal,DecryptError)]" " expected: change cipher")

vincenthz commented 9 years ago

What is the algorithm used for signing in your client certificate ? DSA, RSA, ECDSA ?

lippling commented 9 years ago

Does this help?

openssl x509 -in Production.pem -inform pem -noout -text

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            78:a4:90:dc:39:xx:xx:xx
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=US, O=Apple Inc., OU=Apple Worldwide Developer Relations, CN=Apple Worldwide Developer Relations Certification Authority
        Validity
            Not Before: Feb  2 15:12:01 2015 GMT
            Not After : Feb  2 15:12:01 2016 GMT
        Subject: UID=xxxxxxx, CN=Apple Production IOS Push Services: xxxxxxx, OU=xxxxxxx, C=xx
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (2048 bit)
                Modulus (2048 bit):
                    00:d3:08:21:8e:5e:39:e6:98:e9:0f:1c:28:20:13:
                    54:61:de:33:e7:28:b3:a5:91:73:04:77:34:ef:76:
                    3b:67:cd:b9:4c:03:da:ca:a0:5f:2a:d2:2a:0f:d4:
                    66:f2:95:79:73:43:5d:8a:b7:07:38:c8:8d:d2:0d:
                    d2:e1:ee:3c:76:d6:59:91:38:31:ab:a8:b7:34:a0:
                    66:35:47:de:1b:6b:fb:53:49:4e:eb:e3:8e:19:54:
                    41:5d:9e:2b:54:28:ab:6d:da:62:18:13:37:75:a1:
                    12:e8:db:64:91:d5:91:a5:1d:4a:02:92:10:7d:e0:
                    db:4c:24:8e:fb:eb:3c:9b:80:e2:ce:e7:12:b6:a8:
                    76:5b:0b:c8:bf:a6:d8:55:0e:37:a5:5a:6d:81:07:
                    87:75:b1:a8:cd:d7:21:51:39:9e:2d:53:5c:67:70:
                    88:1a:64:af:54:d0:98:56:a3:58:4b:16:a0:40:5c:
                    1a:d4:41:f8:8e:07:28:7b:15:a5:64:1f:3c:b3:43:
                    0b:64:89:56:d2:64:73:35:55:94:3b:32:89:0c:db:
                    3d:ef:dd:81:17:a8:06:df:f1:2e:71:83:35:05:d5:
                    6a:a7:76:83:55:31:fc:8c:bb:61:44:1c:92:a2:ff:
                    ae:9f:20:25:91:70:d6:0b:a9:e3:fe:cb:ae:32:dc:
                    54:c1
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                AE:77:B5:0C:59:06:0B:0E:26:80:62:70:E9:D1:1B:0B:E7:5B:02:96
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Authority Key Identifier: 
                keyid:88:27:17:09:A9:B6:18:60:8B:EC:EB:BA:F6:47:59:C5:52:54:A3:B7

            X509v3 Certificate Policies: 
                Policy: 1.2.840.113635.100.5.1
                  User Notice:
                    Explicit Text: Reliance on this certificate by any party assumes acceptance of the then applicable standard terms and conditions of use, certificate policy and certification practice statements.
                  CPS: http://www.apple.com/appleca/

            X509v3 CRL Distribution Points: 
                URI:http://developer.apple.com/certificationauthority/wwdrca.crl

            X509v3 Key Usage: 
                Digital Signature
            X509v3 Extended Key Usage: 
                TLS Web Client Authentication
            1.2.840.113635.100.6.3.2: 
                ..
    Signature Algorithm: sha1WithRSAEncryption
        14:91:35:48:0c:71:2b:3f:cf:87:c3:25:6b:b9:00:d6:15:c1:
        93:37:d0:a0:df:87:2f:fc:64:dc:37:55:7b:58:83:26:dd:74:
        04:e2:25:27:60:90:32:09:4f:7d:c2:c7:f0:e5:a8:c2:55:3f:
        33:ae:7a:83:8f:75:4d:db:64:cc:81:32:e0:4c:2b:27:fd:70:
        f9:5a:cc:7f:b5:8d:7b:5a:02:25:37:fd:30:22:12:e1:3b:4d:
        1a:68:08:76:cc:72:f2:46:21:59:b5:dc:87:92:46:60:06:d9:
        57:f3:e2:53:93:fb:47:01:c9:61:27:a3:bd:4e:bf:4e:13:9d:
        00:c1:35:2f:06:13:0f:1e:b2:b7:86:49:13:cd:22:0f:fa:db:
        38:d2:a8:ea:6f:99:aa:4d:45:99:7d:d0:89:cb:88:a1:c6:a9:
        1d:86:09:7d:c2:db:aa:44:b3:86:43:48:42:82:79:39:a4:13:
        e5:76:d9:43:02:4e:c2:15:77:f3:6a:2f:ea:fc:3c:75:85:71:
        03:42:c5:d7:ad:65:bc:bd:6c:85:e9:ac:a2:e7:d3:06:ad:ec:
        f5:4c:4b:c0:a6:5d:11:19:70:6d:69:fc:95:3b:c9:b2:4e:10:
        bc:ad:6e:57:d3:7c:87:8a:e4:21:4a:fa:f8:3f:c2:93:73:ae:
        b0:16:6e:17
lippling commented 9 years ago

@vincenthz Any news here? It still doesn't work with 1.3.3.

lippling commented 8 years ago

I switched to HsOpenSSL and now everything is working fine.

ssgreg commented 8 years ago

I have the similar issue. Is switching to HsOpenSSL the only way to fix the issue?

ssgreg commented 8 years ago

Switched to HsOpenSSL. @vincenthz please fix the issue. it's impossible to use hs-tls in such a way.

mageshb commented 7 years ago

I'm getting following error with tls-1.3.9 while trying to connect to Apple Push Notification Service.

HandshakeFailed (Error_Packet_unexpected "Alert [(AlertLevel_Fatal,HandshakeFailure)]" " expected: change cipher")

Is there any fix/workaround to resolve this issue?

ocheron commented 7 years ago

I have good news. I'm able to reproduce locally with an OpenSSL server, TLS 1.0 or 1.1, cipher RSA-AES128-SHA1, and a client certificate.

I believe the bug occurs because certificateVerifyCreate performs SHA1_MD5 hashing twice: once in prepareCertificateVerifySignatureData, and again in signatureCreate.

Will need more time to find where a fix is best located.

ocheron commented 7 years ago

Above all my comment was very late because gateway.push.apple.com:2195 now accepts TLS 1.2, so it's a different reason.

@mageshb Did you configure a client certificate that this service requires? Can you capture a trace with tls-simpleclient from package tls-debug like above?

waern commented 7 years ago

Has anything been done to fix this? I have this error message:

TlsExceptionHostPort (HandshakeFailed (Error_Packet_unexpected "Alert [(AlertLevel_Fatal,BadRecordMac)]" " expected: change cipher

I'm using tls-1.3.4. Should I upgrade?

mageshb commented 7 years ago

@ocheron Yes I did configure client certificate for this request. I forced the connection to use TLS 1.2 (by setting supportedVersions = [TLS12]) and still I'm facing the same issue.

testAPNSHS :: APNsSetting -> IO ()
testAPNSHS apnsSetting = do
  let host' = host apnsSetting -- gateway.sandbox.push.apple.com
      PortNumber port' = port apnsSetting -- 2195
      cred  = credential apnsSetting
  let clientParams = (defaultParamsClient host' "")  {
        clientShared = def {
            sharedCredentials = Credentials [cred]
            }
        , clientSupported = def {
            supportedCiphers = ciphersuite_all
            , supportedVersions = [TLS12]
            }
        , clientHooks = def {
            onServerCertificate = \_cstore _vcach _srvId _certChain -> do
                pure []
            }
        }
  ctx <- initConnectionContext
  print "Before HS"
  con <- NetCon.connectTo ctx $ ConnectionParams
    { connectionHostname  = host'
    , connectionPort      = port'
    , connectionUseSecure = Just $ TLSSettings clientParams
    , connectionUseSocks  = Nothing
    }
  print "DONE HS"
  connectionClose con

When I run tls-simpleclient, --tls12 is succeding

% tls-simpleclient --tls12 --client-cert=/home/magesh/Downloads/pushtest.pem:/home/magesh/Downloads/pushtest.pem gateway.sandbox.push.apple.com 2195  
magesh@magesh-dell ~/Work/haskell-app-service/hspush

But --tls10 is failing

 % tls-simpleclient --tls10 --client-cert=/home/magesh/Downloads/pushtest.pem:/home/magesh/Downloads/pushtest.pem gateway.sandbox.push.apple.com 2195 -d
tls-simpleclient: HandshakeFailed (Error_Packet_unexpected "Alert [(AlertLevel_Fatal,DecryptError)]" " expected: change cipher")

debug: >> Handshake [CertVerify (DigitallySigned Nothing "\148\180\251\179u\192\160\179\218g.\242\132\DC2-\157\STX\250\&4;\163q\166\241Z\204\RSW\176\186\&0w,\ENQ\207\DLEKg\162\160\DLE\147.\237\CANw8F\168^\DLE4W\169\&8\209Z&\235\176\\)F\161\238S\194\t\168[B(\143\182\217\174\EM\233'\154\201\&5T\131\235Il\202\153\&5\226\213\RSexy\190c1^|W\193\247zz<\135\162X\209\173\236\EM\ETX\176_\198U,\207Gv\US\205\252|\152\ETB{WI\159\ACKc\171\196v@\132\175\&4\252'\213\RSr\SO\166\t\255b\249\209\233\236\ETX\198\171\RS\186\144\178\197\204\168\218}\234=\137\236~\\\241\165\223]\189Nq\180\138m0*J\227V\168\167\177\163\154^\243\136\177\&3\189\223\204J\EOTT/\181\138D\255\219W0\SI\131\USM\173\242S\208\181[y\v\177\&3\128\193m,Tfb\a\163\144\244+v\aJ\156\162\224\209\150\DC1u\154\183E\174^L\DEL")]
debug: >> ChangeCipherSpec
debug: >> Handshake [Finished "1\150m,\241\GS\169\248Z\146\246}"]
debug: << Alert [(AlertLevel_Fatal,DecryptError)]
debug: >> Alert [(AlertLevel_Fatal,InternalError)]
tls-simpleclient: HandshakeFailed (Error_Packet_unexpected "Alert [(AlertLevel_Fatal,DecryptError)]" " expected: change cipher")

Am I doing something wrong in the code?

mageshb commented 7 years ago

Sorry for confusion, for TLS 1.2 is working fine. I missed to set onCertificateRequest in the example. But TLS 1.0 is giving the DecryptError

ocheron commented 7 years ago

@waern The BadRecordMac error probably comes from another issue. In #124 we have reports that it went away with an upgrade. Difficult to be sure because you did not explain much what you do. So yes, you can try to upgrade, and please give more details if an error still occurs.

@mageshb Thanks, it's good to know that TLS 1.2 works with an actual client certificate for Apple Push Notification Service.

I opened a PR to fix the behaviour with older protocol versions.

ocheron commented 7 years ago

The fix for HandshakeFailure has been released in tls -1.3.10, so I close this. Unfortunately this new release still contains a rare possibility of BadRecordMac error that we will address.

portnov commented 7 years ago

I have similar error on tls-1.3.10 :(

(InternalException (HandshakeFailed (Error_Packet_unexpected "Alert [(AlertLevel_Fatal,DecryptError)]" " expected: change cipher")))

My params are

     hooks = if disableServerCertCheck -- this is true in my case
               then def {
                      onCertificateRequest = clientCertHook,
                      onServerCertificate = skip -- just return []
                    }
               else def {
                      onCertificateRequest = clientCertHook
                       }

     clientParams = (defaultParamsClient "" "")
                    { clientHooks = hooks,
                      clientUseServerNameIndication = True,
                      clientShared = shared, -- just def in my case
                      clientSupported = def { supportedCiphers = ciphersuite_all, supportedVersions = [TLS12] }
                    }

I tried with supportedVersions and without it, no change.

portnov commented 7 years ago

In server error log, I see

2017/05/17 17:31:17 [crit] 6#6: *7 SSL_do_handshake() failed (SSL: error:04091077:rsa routines:int_rsa_verify:wrong signature length error:1417B07B:SSL routines:tls_process_cert_verify:bad signature) while SSL handshaking, client: 172.17.0.1, server: 0.0.0.0:443

any ideas?

portnov commented 7 years ago

Eh, nevermind. It seems that problem was in client certificate. Initially I had a client.p12 file, and generated client.pem with

openssl pkcs12 -in client.pem -nokeys -nodes -out client.pem

but it is required to generate it with

openssl pkcs12 -in client.pem -clcerts -nodes -out client.pem

(note: not -nokeys, but, -clcerts). Now it works fine.

ocheron commented 7 years ago

Thank you for documenting this.

The reason is very well explained in pkcs12 man page:

There is no guarantee that the first certificate present is the one corresponding to the private key.

That probably configured tls client with the CA as client certificate and end-entity key as private key. Both have distinct RSA key sizes but tls does not check this condition and simply uses what is configured. So the server detects that the size of the PKCS1.5-padded signature, based on the private key, does not match what is expected from the certificate public key.