Delphi Indy - How to get SSL certificates for a SSL-TCP Client/Server link with Indy 10 - delphi

I'm completely new to SSL and these ciphering stuff but I need to make communicate client and server Delphi XE6 apps running on mobile devices. The TCP communication has to be safely ciphered.
To start, I simply wrote the Delphi/Indy TIdTCPServer/TIdTCPClient based Win32 client and server exchanging strings. (Issued from the indy10clieservr demos found on SourceForge: svn://svn.code.sf.net/p/indy10clieservr/code/1_sample Simple String Exchange)
I tried to modify them to cipher the communication by adding a TIdServerIOHandlerSSLOpenSSL component on the Server, and a TIdSSLIOHandlerSocketOpenSSL on the Client, attaching them respectively to the TIdTCPServer and TIdTCPClient.
I set their following properties on both sides:
- SSLOptions.Method = sslvSSSv23
- SSLOptions.Mode = sslmServer / sslmClient (respectively)
- SSLOptions.VerifyDepth = 2
And I added an OnGetPassword Event handler setting the Password parameter to 'password' on both sides too.
(What is the role of this password ? Is it critical for the privacy of the communication ? What if it is found by analysing/reverse enginering the binary file ?)
Finaly, in the server's OnConnect event handler I set the TIdSSLIOHandlerSocketBase(AContext.Connection.IOHandler).PassThrough property to false.
But what about the 3 SSLOptions certificate properties ??
- CertFile
- KeyFile
- RootCertFile
How to generate and deploy them on my target devices to make run my SSL layer on the client and server ?
Moreover, is there something special to do or to take into acount if I intend to deploy later my server and/or clients on IOS or Android mobile device.
I'm aware that I have few knowledge on this SSL topic. Sorry if I ask something trivial. Any basic documentation explaining all of this tricky stuff to a newbie would be greatly appreciated.

As I told you in my answer to your same question on the Embarcadero forums, certificates are optional. They are used to allow peers to validate each other's identities, not for encryption. Certificates help avoid man-in-the-middle attacks, by allowing a client to verify it is connected to the correct server it is expecting to be connected to, and vice versa. It is not common for a client to have a certificate, except maybe when making a proprietary system where only authorized clients are allowed to connect. But it is pretty common for servers to have certificates, at least. Certificates can be password-protected, so if you do use them, you have to provide the correct password for the certificate(s) that you are actually using. A certificate's password can't be retrieved from the certificate itself, but if an attacker gains access to your certificate files then you have bigger issues to deal with.
As for SSLv23, it is a wildcard that allows dynamic version negotiation in cases where
client and server support different SSL/TLS versions. SSLv23 allows them
to figure out and use the highest version common to both parties. If a server
needs to support a wide range of clients, it makes sense to use SSLv23 on
the server side. Not so much on the client side. Since you control both
client and server, you should use use a specific version instead, preferrably
TLSv1 or higher.

Related

Chilkat Rest - How authorized with certificate

when I try to query a test, freely available, environment, the command below will return the required answer...
lnSuccess = loRest.Connect("https://api.test.....com", 443, 1, 1)
But how to ask the production environment where certificate verification is required?
Many thanks
J.B.
You would use the Chilkat Socket object to connect, then use Rest.UseConnection. See https://www.example-code.com/foxpro/rest_useSocketObject.asp
The reason Chilkat did it this way is to avoid needing to add all of the TLS connection related properties to Rest. Instead, you can use the full flexibility of the Socket object to make the connection, then just tell Rest to use the already-established connection.
To make the TLS connection with certificate verification, call Socket.SetSslClientCert, SetSslClientCertPem, or SetSslClientCertPfx (see https://www.example-code.com/foxpro/socket_tlsClientCert.asp) prior to connecting.

Port 443 Exact use and description

I had studied on many sites but got confused about port 443
Anyone please provide me complete information on Port no 443.
Thanks for your response.
Is it only for http or also used for ssl or any other
A port can be used for basically anything that is to be exposed on the network, 443 is no different from any other port really. But, I'm guessing you don't want info about how ports work, but rather what port 443 is used for by most often.
Port 443 is the default port for secure HTTP aka https, that is, http with Transport Layer Security (earlier called Secure Sockets Layer). Just as with http, it's a port that web servers uses but unlike standard http enforces the usage of secure certificates, most often created by a Certificate Authority that is known by the web browsers as a secure authority.
So when connecting to a page via https instead of http, using a certificate which the browser (or computer) have either added as a safe certificate or have not. If not, it will tell you so and show an exception or warning (at least most browsers will do that).
TLS requires the certificates, and the reason is that the server encrypts the data that it sends to the client, and then the client decrypt it making the whole stream of data less easy to catch for someone whom should not have the data, i.e., a hacker or similar.
If you are running a webpage, you should make sure that you have valid certificates. Both Chrome and Firefox marks pages without TLS as unsafe and if you have any type of data transfer from page to server (say a form with data for the user to add for example) TLS is pretty much a must to make the data transfer safe.
TLS certificates used to be quite costly, but now a days there are services such as Let's Encrypt and Cloudflare which provides safe and free certificates, either as one you install on the server, or a shared certificate as in the "free" version from Cloudflare.
Personally I find it worth to create a self signed certificate (a certificate from my own Certificate Authority, not a big one which is validated by the browsers) for local development too and add it to the certificate storage so that even my localhost uses TLS, but that might be overkill in some cases.
TLDR;
The port 443 is often used for HTTPS (http with TLS), it's good. Use it.

How to validate server certificate against list of CAs during HTTP request using Delphi + Indy

As far as I can tell, this is the process to create an HTTPS request using Indy:
Create a TIdHTTP object
Use a TIdSSLIOHandlerSocketOpenSSL object as its IOHandler
Set up this TIdSSLIOHandlerSocketOpenSSL object's SSLOptions and SSLContext to get the proper behaviour before starting the request
However, Indy's documentation is quite minimal as for the possible values for these two SSLOptions and SSLContext objects, even to achieve what seems to me to be pretty standard behaviour.
In particular, I would like to know how to do the following:
Validate the certificate against either (depending on what is more straightforward) :
The local system's trust store
A list of root certificates provided with the application
Drop the connection if the certificate has not been correctly validated.
It seems to me to be the most basic behaviour for an application that needs to call base once in a while: you want to make sure you're really speaking to your own back-end, but still leave you the possibility of changing CAs if you ever need it.
I guess the SSLContext's field rootCertFile should be used, however:
Nowhere is it said in what format the rootCertFile should be provided (pem? der? pkcs something?)
It is in no way obvious how one should process to configure several alternatives root certificates.
Can someone provide the method, and if possible, some sample code on how this behaviour can be achieved?

What do the SMTP Indy component security and authentication properties do?

I am using the indy components to implement emails in a delphi application. I am specifically using the TidSMTP component. I need to effectively support all major email servers. I use Mozilla Thunderbird as my email client and am comparing the smtp properties with those in the TidSMTP component. I have attempted to find documentation that describes the relationship between the TidSMTP properties, but have not been able to figure it out.
Can someone explain how these compare and what they do:
In Thunderbird:Connection Security: (None, STARTTLS, SSL/TLS).
In TidSMTP.UseTLS (utNoTLSSupport, utUseImplicitTLS, utUseRequireTLS, utUseExplicitTLS)
In Thunderbird:Authentication method: (No Authentication, Normal Password, Encrypted Password, Kerberos/GSSAPI, NTLM)
In TidSMTP (username, password, with useAuthentication method)
I also see other TidSMTP properties: UseEhlo, UseVerp, UseNagle. Do I need to be using these? What do they do?
When using STARTTLS, the server's listening port is initially unencrypted upon connecting. When a client connects, it can send an optional STARTTLS command to the server, if the server supports it, to dynamically perform the SSL/TLS handshake at that time. This allows legacy non-SSL/TLS clients to continue connecting to that same port, while allowing newer SSL/TLS-enabled clients to use SSL/TLS if available on the server. This corresponds to UseTLS=utUseExplicitTLS in Indy. You need to set UseEHLO to True in order to use UseTLS=utUseExplicitTLS, as the EHLO command is how TIdSMTP discovers whether the server supports the STARTTLS command or not.
When using SSL/TLS instead of STARTTLS, the server's listening port is always using encryption and the client must initiate the SSL/TLS handshake immediately upon connecting before any other data can be exchanged. This corresponds to UseTLS=utUseImplicitTLS in Indy. There is no STARTTLS command used.
For authentication, TIdSMTP has two options - the old (and unsecure) AUTH LOGIN command that is defined by the original SMTP spec, and SMTP extensions for SASL-based hashing/encryption algorithms (Kerberos, GSSAPI, NTLM, etc are implemented as SASL algorithms).
To use SASL, set TIdSMTP.AuthType to satSASL and then fill in the TIdSMTP.SASLMechanisms collection to point at separate TIdSASL-derived components for the algorithms you want to support in your app. Indy has native SASL components for DIGEST-MD5, CRAM-MD5, CRAM-SHA1, NTLM (experimental), ANONYMOUS, EXTERNAL, OTP, PLAIN, SKEY, and LOGIN (SASL wrapper for AUTH LOGIN). If you need another algorithm (Kerberos or GSSAPI, for instance), you will have to write your own TIdSASL-derived component. For algorithms that use Username/Password, the values must be assigned to a separate TIdUserPassProvider component that is then assigned to the SASL components (the TIdSMTP.UserName and TIdSMTP.Password properties are not used with SASL). The more SASL algorithms you support, the wider the number of servers you will be able to support.
For servers that still support AUTH LOGIN, it can be used either by setting TIdSMTP.AuthType to satDefault (and optionally setting TIdSMTP.ValidateAuthLoginCapability to False if the server supports AUTH LOGIN but does not report it in response to the EHLO command) and then filling in the TIdSMTP.UserName and TIdSMTP.Password properties, or by including the TIdSASLLogin component in the TIdSMTP.SASLMechanisms collection.
UseVerp and UseNagle have nothing to do with security. VERP is an SMTP extension for detecting bouncing emails due to undeliverable errors. Nagle is a networking algorithm for optimizing network data packets.

Delphi XE – Datasnap Filter problems

I have a tcp/ip Datasnap -XE Server that uses a PC1 and Zlib filter
On the Client both of these filters are defined in DataSnap TSqlConnection
When the client connects to the server I get a "Connection Closed Gracefully” error message
If I only use the PC1 filter on its own - there is no problem
If I only use the Zlib filter on its own - there is no problem
Any Ideas on how I can get both filters working at the same time?
You need to deploy the libeay32.dll and ssleay32.dll with your client application as well.
A quote from my Delphi XE DataSnap Development courseware manual:
"If you deploy the DataSnap standalone server, using TCP/IP and the RSA and PC1 filters, then you must also deploy two Indy specific SSL DLLs: libeay32.dll and ssleay32.dll – or make sure they already exist at the server machine. These DLLs are needed for the RSA filter (which encrypts the password used by the PC1 filter). Without these two DLLs, any client who wants to connect to the server will get an “Connection Closed Gracefully” message, because the server was unable to load the two DLLs to start the RSA filter to encrypt the PC1 keys, etc.
By the way, the same two DLLs will be required for any DataSnap client, whether connected to the TCP/IP server using the RSA and PC1 filters, or whether connected to the ISAPI filter using HTTPS."
Groetjes, Bob Swart
It is probably a bug in DataSnap. I have exactly the same problem and here is the QC report.
http://qc.embarcadero.com/wc/qcmain.aspx?d=91180
Vote on QC report to be fixed and wait for an update of Delphi-XE.
Edit 1
A crazy idea, don't specify filters on the client.
Here is a paper from Pawel Glowacki on Transport Filters.
http://edn.embarcadero.com/article/41293
He specifically mentions that you should add ZLibCompression to the Filters property of the DataSnap driver on the client.
I have tested not to do so and it works just fine. You do have to add DBXCompressionFilter to the uses clause otherwise you get "ZLibCompression is not registered" error.
With PC1 and ZLibCompression on the server and no filter on the client everything seams to work as expected. I have checked the traffic and it is encrypted and compressed.
Until someone from Embarcadero confirms that this is the way it should be I would think twice before I used it.
Edit 2 Here is a post on Embarcadero Discussion Forums by Bob Swart saying that it is enough to add the filters on the server. Not Embarcadero directly but pretty close :)
https://forums.embarcadero.com/thread.jspa?threadID=48875&tstart=0
Until someone from Embarcadero confirms that this is the way it should be I would think twice before I used it.
This is true. If you don't specify filters on the client, it is told in the initial handshake protocol during connection what the server's filters are, and it adds them automatically. This is a perfectly reasonable and safe way to use filters.
Note, however, that this isn't true in the reverse. Servers do not adopt filters from a connecting client. If you have an RSA filter on the client but not a matching one on the server, then you will get an exception on connection, saying the server has no matching RSA filter. Any other filter on the client but not on the server will be ignored.
Try reversing the order of the filters, leaving the client always contrary server.
eg
Server
Filters = <
item
FilterId = 'ZLibCompression'
Properties.Strings = (
'CompressMoreThan = 1024')
end
item
FilterId = 'PC1'
Properties.Strings = (
'Key = test')
end>
Client
Params.Add ('Filters = {"PC1": {"Key": "test"}, "ZLibCompression": {"CompressMoreThan": "1024"}}');

Resources