Why use certificates?
There is a number of cipher suites (combination of encryption, signing and hashing algorithms) used in SSL/TLS. For example, there exists a cipher suite SB_SUITE_NULL_NULL_NULL which provides no encryption at all. Some cipher suites, ex. SB_SUITE_DH_ANON_*_*, provide encryption based on Diffie-Hellman key agreement protocol, which doesn't require certificates. While using one of these cipher suites is the simplest way to establish SSL/TLS session, such cipher suites make Man-In-The-Middle (MITM, see description here) attacks possible. MITM attack can be prevented only when the server is authenticated by the certificate. The main idea behind certificates is that the attacker can't present fake ceritficate to the client because the client validates server certificate. Note, that self-signed certificate won't work for this because the attacker can present his self-signed certificate. So CA-given certificate is needed (see Introduction to Certificates for description of CAs).
Which parties need certificates?
To prevent MITM attack you need to give a certificate to the server. A client-side certificate is needed for authentication of the clients. Note, that assigning a server-side certificate without checking it later on the client side doesn't make your communication more secure. Validation of certificate is described on Certificate Validation how-to.
How to get and set certificates?
The certificate can be obtained in two ways:
- Use some well-known CA to create a certificate.
- Become a CA for means of generation of certificates for the server and (optionally) for the client.
Then you need to do the next steps:
- Put CA certificate without private key to client software
- Put server certificate with a private key to server software. Optionally you can put CA certificate without private key to server software too (to send the whole chain to the client). But this is not necessary in this simple scenario
- When the client receives server certificate, validate it using CA certificate that the client has.
- If the client-side certificate is requested by the server (for example, for client authentication), then, when the server receives client certificate, the server should validate received certificate using CA certificate that the server has.
Certificate chain consists of several certificates, where one certificate is a CA certificate for another, and so on. Certificate chains are needed, when the party sends the certificate, which was issued not directly by well-known CA, but using some intermediate CA certificate, which in turn was issued by either well-known CA, or other intermediate CA.
The bank receives a certificate from well-known CA (for example, Thawte). The bank issues certificates for its branches and uses Thawte-issued certificate as a CA certificate. In this case, if the branch builds a web site or implements client-bank system, it needs to use a certificate chain that includes Thawte-issued certificate and branch’s certificate. This way the client will be able to validate branch’s certificate completely.
Setting server-side certificates in SSL server
To setup certificate(s) in your SSL server, do the following:
- Create an instance of TElMemoryCertStorage.
- Load the certificate(s) that will be presented to the user. You will need more than one certificate in several cases. Most common case is when you have to present the certificate chain to the user. Another common case is when you have different certificates with different signature algorithms (i.e. RSA and DSA). Note: the server’s certificate must have an associated private key. If you are building the certificate chain, CA certificates don’t (and can’t) include a private key.
First create an instance of TElX509Certificate class, then use one of its LoadFrom*() methods to load the certificate data.
- Add the created certificate(s) to the certificate storage using TElMemoryCertStorage.Add() method.
- Set TElSecureServer.CertStorage property to the reference to the certificate storage.
Handling client-side certificates in SSL server
- (optionally) set-up client-side certificate storage, which will be used to automatically validate client-side certificates. To do this
- Create an instance of a certificate storage class, which is a descendant of TElCustomCertStorage.
- Load the certificate(s), that belong to the user(s) that are allowed to connect. The certificate(s) must not contain private key(s). Depending, on what storage class is used, you can load the whole certificate storage from file, or add certificates one by one, or even use Windows certificate storage.
- Assign the instance of the storage class to TElSecureServer.ClientCertStorage
- (optionally) Implement OnCertificateValidate event handler to validate client-side certificates, sent by the user. The event is fired in all cases, even when client-side certificate storage is assigned to TElSecureServer.ClientCertStorage property.
To validate the certificates in application code, see Certificate Validation tutorial.
Handling server-side certificates in TLS client
Passing client-side certificates to the server in TLS client
- Implement OnCertificateNeededEx event handler.
- When the event is fired, the application needs to pass a certificate back to the component. To do this create an instance of TElX509Certificate class, then use one of its LoadFrom*() methods to load the certificate data. After that assign the created instance to Certificate parameter of the event handler.
- If you have no certificate to pass, set Certificate parameter of the event handler to nil / null / Nothing.
OnCertificateNeededEx event handler is fired as long, as you assign non-empty value to Certificate parameter. I.e. to tell the SSL client component, that you don’t have any more certificates to pass to the server, set Certificate to nil / null / Nothing. Why is this approach used?
Sometimes you need to pass certificate chains not from server to client, but from client to server. To do this, pass the certificates of the chain one by one. To track, which certificate from the chain to pass, you can do the following:
- Create some class-level variable, let’s call it CurrentCertificate.
- Initialize this variable to 0.
- In OnCertificateNeededEx event handler, implement the following logic (Visual Basic notation is used):
If (CurrentCertificate = TheTotalNumberOfCertificates) then CurrentCertificate = 0 Certificate = Nothing Else Certificate = Certificates(CurrentCertificate) CurrentCertificate = CurrentCertificate + 1 End If