Archived Forum Post

Index of archived forum posts

Question:

Connecting via mutual SSL fails reading incoming changeCipherSpec

Jun 10 '15 at 10:55

We are having trouble connecting to a server using mutual SSL.

Initially I thought the server was requesting ciphers that we didn't have but they've confirmed this isn't the case. Then I tried changing the format of the pem file with no luck however I did notice that forcing it to fail does not change the error (indicating it is not being used at all?)

I also noticed the text:

processHandshakeMessage:
  MessageType: CertificateRequest
  CertificateRequest:
    NumCertificateTypes: 3
    Certificate Type: RSA Sign
    Certificate Type: DSS Sign
    OtherCertificateType: 64
    totalLen: 0
    NumDistinguishedNames: 0
    CertificateRequest message is OK.
    Queueing CertificateRequest message.
  --CertificateRequest
--processHandshakeMessage

Is this the server requesting a 0-length certificate from us and then failing when the component does just this? (Sending 0-length certificate (this is normal).)

I'm no longer sure what to look at in trying to solve this problem and any feedback would be greatly appreciated.

Useful info below

Full LastErrorText:

SynchronousRequest:
    DllDate: Dec 12 2012
    UnlockPrefix: [redacted]
    Username: [redacted]
    Architecture: Little Endian; 32-bit
    Language: ActiveX
    VerboseLogging: 0
    domain: [redacted]
    port: 9000
    ssl: 1
    RequestData:
      HttpVersion: 1.1
      Verb: POST
      Path: [redacted]
      Charset: utf-8
      SendCharset: 0
      MimeHeader: SOAPAction:
Content-Type: text/xml
    --RequestData
    ReadTimeout: 10
    ConnectTimeout: 10
    httpConnect:
      hostname: [redacted]
      port: 9000
      ssl: 1
      Need to establish connection to the HTTP server...
      ConnectTimeoutMs_1: 10000
      calling ConnectSocket2
      IPV6 enabled connect with NO heartbeat.
      connectingTo: [redacted]
      resolveHostname1:
        dnsCacheLookup: [redacted]
        dnsCacheHit: [redacted]
      --resolveHostname1
      GetHostByNameHB_ipv4: Elapsed time: 0 millisec
      myIP_1: [redacted]
      myPort_1: [redacted]
      connect successful (1)
      clientHelloMajorMinorVersion: 3.1
      buildClientHello:
        majorVersion: 3
        minorVersion: 1
        numRandomBytes: 32
        sessionIdSize: 0
        numCipherSuites: 10
        numCompressionMethods: 1
      --buildClientHello
      readIncomingTls_serverHello:
        processTlsRecord:
          processHandshake:
            handshakeMessageType: ServerHello
            handshakeMessageLen: 0x46
            processHandshakeMessage:
              MessageType: ServerHello
              Processing ServerHello...
              ServerHello:
                MajorVersion: 3
                MinorVersion: 1
                SessionIdLen: 32
                CipherSuite: RSA_WITH_AES_256_CBC_SHA
                CipherSuite: 00,35
                CompressionMethod: 0
                Queueing ServerHello message.
                ServerHello is OK.
              --ServerHello
            --processHandshakeMessage
          --processHandshake
        --processTlsRecord
      --readIncomingTls_serverHello
      HandshakeQueue:
        MessageType: ServerHello
      --HandshakeQueue
      Dequeued ServerHello message.
      readIncomingTls_6:
        processTlsRecord:
          processHandshake:
            handshakeMessageType: Certificate
            handshakeMessageLen: 0xf13
            processHandshakeMessage:
              MessageType: Certificate
              ProcessCertificates:
                Certificate:
                  [cert info]
                --Certificate
                Certificate:
                  [cert info]
                --Certificate
                Certificate:
                  [cert info]
                --Certificate
                NumCertificates: 3
                Queueing Certificates message...
              --ProcessCertificates
            --processHandshakeMessage
          --processHandshake
        --processTlsRecord
      --readIncomingTls_6
      Dequeued Certificate message.
      readIncomingTls_6:
        processTlsRecord:
          processHandshake:
            handshakeMessageType: CertificateRequest
            handshakeMessageLen: 0x6
            processHandshakeMessage:
              MessageType: CertificateRequest
              CertificateRequest:
                NumCertificateTypes: 3
                Certificate Type: RSA Sign
                Certificate Type: DSS Sign
                OtherCertificateType: 64
                totalLen: 0
                NumDistinguishedNames: 0
                CertificateRequest message is OK.
                Queueing CertificateRequest message.
              --CertificateRequest
            --processHandshakeMessage
            handshakeMessageType: ServerHelloDone
            handshakeMessageLen: 0x0
            processHandshakeMessage:
              MessageType: ServerHelloDone
              Queueing HelloDone message.
            --processHandshakeMessage
          --processHandshake
        --processTlsRecord
      --readIncomingTls_6
      Dequeued CertificateRequest message.
      DequeuedMessageType: ServerHelloDone
      OK to ServerHelloDone!
      Sending 0-length certificate (this is normal).
      CertificatesMessage:
        numCerts: 0
        CertificateSize: 0x3
      --CertificatesMessage
      Encrypted pre-master secret with server certificate RSA public key is OK.
      Sending ClientKeyExchange...
      Sent ClientKeyExchange message.
      Sending ChangeCipherSpec...
      Sent ChangeCipherSpec message.
      Derived keys.
      Installed new outgoing security params.
      Sending FINISHED message..
      algorithm: aes
      keyLength: 256
      Sent FINISHED message..
      readIncomingTls_changeCipherSpec2:
        processTlsRecord:
          processAlert:
            TlsAlert:
              level: fatal
              descrip: handshake failure
            --TlsAlert
          --processAlert
        --processTlsRecord
      --readIncomingTls_changeCipherSpec2
      Failed to read incoming handshake messages. (3)
      Client handshake failed. (3)
      Failed to connect.
    --httpConnect
    connectTime1: Elapsed time: 47 millisec
    totalTime: Elapsed time: 47 millisec
    Failed.
  --SynchronousRequest
--ChilkatLog

Relevant code:

var path = "path/to/service";

var postBodyRequest = new ActiveXObject("Chilkat.HttpRequest");
    postBodyRequest.Path = path;
    postBodyRequest.AddHeader("SOAPAction", "");
    postBodyRequest.HttpVerb = "POST";
    postBodyRequest.ContentType = "text/xml";
    postBodyRequest.Charset = "utf-8";
    postBodyRequest.LoadBodyFromString(SOAPDoc,"utf-8");

var endDomain = "https://service.domain.com"; // LIVE
var endPort = 9000; // live 9000, test 9005
var endSSL = 1;

var Gateway = new ActiveXObject("Chilkat.Http");
    Gateway.UnlockComponent("redacted");
var pemSuccess = Gateway.SetSslClientCertPem(Server.MapPath(certPath), "");
    Gateway.ConnectTimeout = 10;                
    Gateway.ReadTimeout = 10;

    Response.Write("certPath["+certPath+"]<br />"); // putputs correct path to file
    Response.Write("Server.MapPath(certPath)["+Server.MapPath(certPath)+"]<Response />"); // putputs correct full path to file
    Response.Write("pemSuccess["+pemSuccess+"] "+(pemSuccess?"true":"false")+" <br />"); // returns true
var Output = Gateway.SynchronousRequest(endDomain,endPort,endSSL,postBodyRequest);

The pem file being fed to SetSslClientCertPem contains the key generated at the same time as the Certificate Signing Request, and the Certificate returned to us by the server hosts we're trying to connect to in format:

-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDdZwhsIyekborm
[...]
WHCBmt7zxIvY6WKPUq7eaWeK
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIEeDCCA2CgAwIBAgIQEiZW9gYXj3L8gJPqm12+KTANBgkqhkiG9w0BAQUFADBg
[...]
B4l5fW/pNqIJjKKmkmqVd1pGzEUBs8KFEkqRtcaGmCusdYvr0pTExoM9u2g=
-----END CERTIFICATE-----

I noticed that the problem looked similar to the one found here but the same solution did not work.


Answer

Check to see if using the latest version of Chilkat solves the problem. If not, then make sure each Chilkat method call involving certificates (prior to calling SynchronousRequest) returned a success status. If something failed previous to the SyncronousRequest call such that no client-side certs were actually made available, then a 0-length cert message would be sent.