I use the following code to setup SSLHandler for POP3/SMTP sending/receiving app:
IdSSLHandler->SSLOptions->Mode = sslmClient;
IdSSLHandler->SSLOptions->Method = slvSSLv23;
IdSSLHandler->SSLOptions->SSLVersions = TIdSSLVersions() << sslvSSLv3 << sslvTLSv1 << sslvTLSv1_1 << sslvTLSv1_2;
So, the above code is supposed to support SSL 3, TLS 1, TLS 1.1 and TLS 1.2 automatically. This does not work well and reports "wrong version" error. When the SSLVersions
line is removed then it works but by defaults it includes sslvSSLv2
which I don't want to support. It is the same like:
IdSSLHandler->SSLOptions->Mode = sslmClient;
IdSSLHandler->SSLOptions->Method = slvSSLv23;
IdSSLHandler->SSLOptions->SSLVersions = TIdSSLVersions() << sslvSSLv2 << sslvSSLv3 << sslvTLSv1 << sslvTLSv1_1 << sslvTLSv1_2;
For some reason, this works and the above does not on same server. I know that slvSSLv23
is a kind of "use any available version" value. So why does it not work with above code where version 2 is not present?
Additionally, I can use TSL1 which seems to be widely deployed, but if the server supports 1.1 or 1.2 then my code won't be using more recent versions but will force 1.0 version unless something like above is used.
I would like to make an initialization with the following goals:
I thought the first version of the code would provide that but it reports version error. Are the above goals possible or a user-setting must be provided to select SSL version to use?
Setting the SSLVersions
to a single value automatically sets the Method
to the corresponding single version. Setting the SSLVersions
to multiple values automatically sets the Method
to slvSSLv23
.
Setting the Method
to a single version automatically sets the SSLVersions
to the corresponding single value. Setting the Method
to slvSSLv23
automatically sets the SSLVersions
to all supported values.
Indy activates/deactivates the appropriate SSL_OP_NO_SSL_v#
and SSL_OP_NO_TLS_v#
flags in OpenSSL depending on the values of Method
and SSLVersions
.
I would suggest the following approach, which is a slightly more future proof as new TLS versions are added:
IdSSLHandler->SSLOptions->Method = sslvSSLv23;
IdSSLHandler->SSLOptions->SSLVersions = IdSSLHandler->SSLOptions->SSLVersions >> sslvSSLv2;
Either way, Indy would be using SSLv23 with only the SSL_OP_NO_SSL_v2
flag activated.
In that configuration, a "wrong version" error typically means the server is using a specific version that does not support version negotiation (which uses an SSLv2-compatible client hello). In other words, an SSLv23 client connecting to a TLSv1 server will fail. The server must use SSLv23 in order to support version negotiation. Using SSLv23 on the server allows it to accept any version client, as the client initiates the handshake so the server can see which version header is being used. But using SSLv23 on the client DOES NOT allow it to connect to any server OTHER THAN an SSLv23 server. An SSLv2 server can only accept SSLv2 clients, an SSLv3 server can only accept SSLv3 clients, a TLSv1 server can only accept TLSv1 clients, and so on.
To truly connect to "any" server, you would have to detect a "wrong version" error and retry with a different specific Method
/SSLVersions
configuration. Unfortunately, the "wrong version" reply does not include the server's actual version, so you have to use trial-and-error. If SSLv23 fails, try TLSv1_2. If that fails, try TLSv1_1. If that fails, try TLSv1. If that fails, try SSLv3.