Archived Forum Post

Index of archived forum posts

Question:

Sockets --> Rogue certificate (from an unknown source) appearing when client socket attempts to ValidateServerCerts

Apr 21 '17 at 19:48

I have about 2,000 clients running an application that connects to a Windows Azure server with Chilkat.Socket using TLS 1.2.

All 2,000 of the clients are connecting up just fine except for one client that is failing in validateServerCerts. This client receives two certs for some reason after it establishes the socket connection (certListSize: 2). It fails to validate the second, rogue certificate due to what appears to be a reason of 'expiredCert:'.

I call this second certificate a rogue certificate because I don't know where it is coming from -- I am only using one certificate on the Server-side. Also, the properties of the certificate in the chilkat log indicate that it is from an unknown source (it's not a server certificate of ours).

Below is the Chilkat log when it fails to connect:

EstablishTCPConnection on port 2113: ChilkatLog:
  Connect_Socket(390ms):
    DllDate: Dec 29 2015
    ChilkatVersion: 9.5.0.55
    UnlockPrefix: E3TEKC.CBX0816
    Username: ESITE007xx:SYSTEM
    Architecture: Little Endian; 32-bit
    Language: .NET 2.0
    VerboseLogging: 1
    objectId: 2
    Component successfully unlocked using purchased unlock code.
    connectInner(390ms):
      hostname: 40.118.254.111
      port: 2113
      tls: 1
      maxWaitMs: 30000
      socket2Connect(390ms):
        connect2(390ms):
          hostname: 40.118.254.111
          port: 2113
          ssl: 1
          connectImplicitSsl(390ms):
            Clearing TLS client certificates.
            connectSocket(62ms):
              domainOrIpAddress: 40.118.254.111
              port: 2113
              connectTimeoutMs: 30000
              connect_ipv6_or_ipv4(62ms):
                This is an IPV4 numeric address.
                Domain to IP address resolution not needed.
                connecting to IPV4 address...
                ipAddress: 40.118.254.111
                createSocket:
                  Setting SO_SNDBUF size
                  sendBufSize: 262144
                  Setting SO_RCVBUF size
                  recvBufSize: 4194304
                --createSocket
                connect(62ms):
                  Waiting for the connect to complete...
                  myIP: 192.168.2.70
                  myPort: 62988
                  socket connect successful.
                --connect
              --connect_ipv6_or_ipv4
            --connectSocket
            clientHandshake(328ms):
              The client cert chain is NULL.
              cacheClientCerts:
                Cached TLS client certificates.
                Client cert chain is NULL.
              --cacheClientCerts
              clientHandshake2(328ms):
                readHandshakeMessages(78ms):
                  processHandshakeRecord:
                    processHandshakeMessage:
                      processServerHello:
                        negotiatedTlsVersion: TLS 1.2
                        negotiatedCipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA256
                        minAcceptableRsaKeySize: 1024
                      --processServerHello
                    --processHandshakeMessage
                  --processHandshakeRecord
                --readHandshakeMessages
                buildClientKeyExchange:
                  buildClientKeyExchangeRsa:
                    modulus_bitlen: 2048
                    bigEndian: 1
                    padding: PKCS 1.5
                  --buildClientKeyExchangeRsa
                --buildClientKeyExchange
              --clientHandshake2
            --clientHandshake
            checkServerCert:
              Verifying server certificate...
              validateServerCerts:
                **certListSize: 2**
                verifyCertSignature:
                  certSubject: localhost, TheExpectedDomain.cloudapp.net
                  issuerDN: com, rogue, rogueDN
                  issuerSerialNumber: 7C2DAAB70DBBB8B049F565B747379E44
                  CertSignatureAlgorithmOid: 1.2.840.113549.1.1.11
                  unsignSslSig:
                    Zero-extending to match modulus byte length
                  --unsignSslSig
                  HashAlgorithmOid: 2.16.840.1.101.3.4.2.1
                  SignatureVerified: 1
                --verifyCertSignature
                verifyCertSignature:
                  certSubject: com, rogue, rogueDN
                  Verifying the signature of a self-signed/root certificate.
                  CertSignatureAlgorithmOid: 1.2.840.113549.1.1.5
                  unsignSslSig:
                    Zero-extending to match modulus byte length
                  --unsignSslSig
                  HashAlgorithmOid: 1.3.14.3.2.26
                  SignatureVerified: 1
                  This is an implicitly trusted root certificate.
                --verifyCertSignature
                expiredCert: com, rogue, rogueDN
              --validateServerCerts
              SSL server certificate verification failed.
            --checkServerCert
            Server certificate verification failed. (3)
          --connectImplicitSsl
          ConnectFailReason: Server certificate validation failed
        --connect2
      --socket2Connect
      Failed.
    --connectInner
    Failed.
  --Connect_Socket
--ChilkatLog

Notice above that the certlistSize is two but it should be one. The server is only using the one certificate (TheExpectedDomain.cloudapp.net) so I don't know where the additional rogue cert is coming from. When I connect with Verbose Logging enabled on the other ~2,000 working clients, only one certificate is validated in ValidateServerCerts and the certListSize is always = 1.

Does anyone have an idea as to where this second cert could be coming from? In the server-side service when I begin listening on the TLS port I am only using one certificate when I call InitSSLServer(cert) so I don't understand why this particular client is trying to validate a second certificate from an unknown source.

On the server-side I am using a self-signed certificate that I created when calling InitSSLServer(). Does that not make any difference in terms of the server sending a whole chain of certs to the client instead of just my single, self-signed cert?

Below is my server-side code that sets up the certStore and binds and listens on the socket:

        Chilkat.CertStore certStore = new Chilkat.CertStore();
        success = certStore.LoadPfxFile("C:\\MySelfSignedCert.pfx", "mycertpassword");
        if (success != true)
        {
            LogException(certStore.LastErrorText);
            return;
        }

        Chilkat.Cert cert = null;
        cert = certStore.GetCertificate(0); //get the cert in the store at index 0
        if (cert == null)
        {
            LogException(certStore.LastErrorText);
            return;
        }
        tcpSocket.SoReuseAddr = true;
        tcpSocket.VerboseLogging = true;
        tcpSocket.Ssl = true;
        tcpSocket.SslProtocol = "TLS 1.2";
        tcpSocket.SslAllowedCiphers = "TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA";

        //  Use the certificate:

        success = tcpSocket.InitSslServer(cert);

        if (success != true)
        {
            LogException(tcpSocket.LastErrorText);
            return;
        }

        tcpSocket.BindAndListen(port, 50);

Answer

In the SSL/TLS handshake protocol,when the server send's it's "Server Certificate" message, it's not just sending one certificate -- it's sending the server's certificate chain to the client. (i.e. the certs in the chain of authentication to the root, which could include intermediate certs). See Section 7.4.2 of RFC 5246 if you want to know the specifics..

(Of course, if the certs in the chain of authentication are not available to the server, then it may just send only it's cert, in which case the client may have the remainder of the chain already installed on it's system. In general, the root CA cert would need to be a trusted root, and the fact that it may be included as part of the ServerCertificate TLS handshake message is redundant.)