Question:
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);
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.)