SSL/TLS Error – SEC_E_INTERNAL_ERROR

Problem:
An SSL/TLS connection failed and the LastErrorText contains “SEC_E_INTERNAL_ERROR”, such as in the error text below:

(See cause solution below)

ChilkatLog:
  Connect:
    DllDate: Dec  4 2009
    UnlockPrefix: ****
    Username: ****
    Component: .NET 2.0
    objectId: 1
    hostname: *.*.*.*
    port: 443
    ssl: 1
    maxWaitMs: 20000
    windowsAccount: ****
    ClientCertDN: ****
    protocol: default
    An existing connection was forcibly closed by the remote host.
    Failed to receive on the TCP socket
    connectionClosed: 0
    timedOut: 0
    Error reading data from server in handshake loop
    Setting scRet = SEC_E_INTERNAL_ERROR
    Error performing handshake
    Failed.

Cause #1:
This is caused when the server-side expect an SSL 3.0 initial packet and cannot handle an SSL 2.0 initial packet. Normally, when a client and server connect and begin the SSL/TLS handshake, the SSL 2.0 packet is the first one sent. It allows the client and server to negotiate and agree upon protocols starting from SSL 2.0 and up (SSL 2.0, SSL 3.0, TLS 1.0, etc.) Normally, the most secure protocol is used and SSL 2.0 is never actually used (unless there is some very very old legacy server that only supports SSL 2.0).

In some cases, the server does not expect the 1st packet to be SSL 2.0 formatted. One such case is the following OpenSSL command:

OpenSSL> s_server -accept 443 -Verify 5 -ssl3 -cert c:\certs\server.pem


Solution #1:

Set the SslProtocol property equal to the string “SSL 3.0”. For example:

socket.SslProtocol = "SSL 3.0";

This applies to all components capable of using SSL/TLS connections: FTP2, HTTP, Socket, IMAP, MailMan, etc.

Cause #2
The server requires the client to provide a certificate for authentication, but none was provided.

Solution #2
Load a Chilkat certificate object with the appropriate client-side certificate (there are many ways of doing this..) and then set the clients-side certificate by calling the SetSslClientCert method. This method exists on all Chilkat objects that use SSL/TLS connections (FTP2, HTTP, Socket, IMAP, MailMan, etc.)

Important: It’s entirely possible that your application might need to apply both solutions.

Client-Side SSL/TLS Authentication

This blog post is here to clarify a very common misunderstanding. The various Chilkat components that provide SSL/TLS support also provide an option that allows a client-side digital certificate to be used with the secure connection. A certificate identifies you to the server. In 99% of cases you do not need a client certificate. It is usually not necessary for the server-side of the SSL connection to identify you by means of a digital certificate. For example, when you are purchasing something online at Amazon.com, there are two important things regarding the connection: (1) you know you are really talking to Amazon.com (i.e. the server’s SSL certificate is verifiable) and (2) the connection is secure. Amazon.com does not require you to have a client-side certificate to communicate over SSL. If it did, then anybody wishing to do anything over SSL on the Internet would need to first purchase a digital certificate from a company such as Verisign, Thawte, Comodo, etc., be verified by that certificate authority, and then renew the certificate every year. Sites usually require you to login with a username/password, and this is what verifies your identity. Login/password identification applies to HTTP, FTP, POP3, SMTP, IMAP, etc., all of which have SSL support in Chilkat. It’s the login that provides client-side identification. Therefore, the SSL client certificate is usually never needed. (In fact, the login usually occurs over a secure SSL/TLS connection.)

The one place where a client-side certificate is required is this: When the client-side certificate takes the place of a login/password. This option is sometimes seen w/ high-security FTP servers involving financial transactions.