SecureBlackbox 16: Certificate Setup in Client-Server Systems
TLS/SSL uses a number of cipher suites (a combination of encryption, signing, and hashing algorithms). For example, there exists a cipher suite SB_SUITE_NULL_NULL_NULL that provides no encryption at all. Some cipher suites, e.g., SB_SUITE_DH_ANON_*_*, provide encryption based on the Diffie-Hellman key agreement protocol, which doesn't require certificates. While using one of these cipher suites is the simplest way to establish a SSL/TLS session, such cipher suites make man-in-the-middle (MITM) attacks possible. A MITM attack can be prevented only when the server is authenticated by the certificate.
The main idea behind certificates is that the attacker cannot present a fake certificate to the client because the client validates the server certificate. Note that a self-signed certificate is not suitable for this: a certificate issued from a CA is needed to prevent an attacker from presenting a self-signed certificate. See Introduction to Certificates for a description of CAs.
Which Parties Need Certificates
To prevent a MITM attack, you need to present a certificate to the server. A client-side certificate is needed to authenticate clients. Note that assigning a server-side certificate without checking it later on the client side does not make your communication more secure.
How to Get and Set Certificates
A certificate can be obtained in two ways:
- Use a well-known CA to create a certificate.
- Act as your own CA and generate certificates for the server and (optionally) for the client.
If you are the CA, you need to create a self-signed root certificate, which will be used to sign the server and (optionally) client certificates. If you use a well-known CA, it will give you all the certificates.
The following steps show how to set the certificates to perform validation. For the validation procedure, see Certificate Validation.
- Set the CA certificate without the private key in the client software.
- Set the server certificate with the private key in the server software. Optionally, you can set a CA certificate without the private key in the server software to send the whole chain to the client. But, this is not necessary in this simple scenario.
- When the client receives the server certificate, validate it using the client's CA certificate.
- If the client-side certificate is requested by the server (for example, for client authentication), then, when the server receives the client certificate, the server should validate the received certificate using the server's CA certificate.
Certificate Chains
A certificate chain consists of several certificates, where one certificate is a CA certificate for another, and so on. Certificate chains are needed when a party sends a certificate that was not issued directly by a well-known CA, but by some intermediate CA certificate, which in turn was issued by either a well-known CA or another intermediate CA.
Example: A bank receives a certificate from a well-known CA (for example, Thawte). The bank issues certificates for its branches and uses a Thawte-issued certificate as a CA certificate. In this case, if the branch builds a website or implements a client-bank system, it needs to use a certificate chain that includes the Thawte-issued certificate and the branch’s certificate. This way, the client will be able to validate the branch’s certificate completely.
Setting Server-Side Certificates in the SSL Server
To setup certificates in your SSL server, follow the steps below:
- Create an instance of TElMemoryCertStorage.
Load the certificates that will be presented to the user. You will need more than one certificate in several cases. The 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 (e.g., RSA and DSA). Note: The server's certificate must have an associated private key. If you are building a certificate chain, CA certificates don’t (and can’t) include a private key.
- Add the created certificates to the certificate storage using the TElMemoryCertStorage.Add method.
- Set the TElSecureServer.CertStorage property to the reference to the certificate storage.
To load the certificate, create an instance of the TElX509Certificate class, then use one of its LoadFrom*() methods to load the certificate data.
Handling Client-Side Certificates in the SSL Server
To enable authentication with client-side certificates, you can optionally set up a client-side certificate storage that will be used to automatically validate client-side certificates.
- Create an instance of a certificate storage class that is a descendant of TElCustomCertStorage.
- Load the certificates that belong to the users who are allowed to connect. The certificates must not contain private keys. Depending on what storage class is used, you can load the whole certificate storage from a file, add certificates one by one, or even use Windows certificate storage.
- Assign the instance of the storage class to TElSecureServer.ClientCertStorage.
Optionally, you can also implement the OnCertificateValidate event handler to validate client-side certificates sent by the user. The event is fired in all cases, even when a client-side certificate storage is assigned to the TElSecureServer.ClientCertStorage property.
Handling Server-Side Certificates in the TLS Client
Implement the OnCertificateValidate event handler to validate the certificates sent by the server.
Passing Client-Side Certificates to the Server in the TLS Client
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, CurrentCertificate in this example.
- Initialize this variable to 0.
- In the 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
Implement the OnCertificateNeededEx event handler to pass the certificate. When the event is fired, the application needs to pass a certificate back to the component:
- Create an instance of the TElX509Certificate class.
- Use one of its LoadFrom*() methods to load the certificate data.
- Assign the created instance to the Certificate parameter of the event handler.
- If you have no certificate to pass, set the Certificate parameter of the event handler to nil / null / Nothing.
The OnCertificateNeededEx event handler is fired as a long, as you assign a non-empty value to the Certificate parameter. That is, to tell the SSL client component that you don’t have any more certificates to pass to the server, set the Certificate to nil / null / Nothing.
We appreciate your feedback. If you have any questions, comments, or suggestions about this article please contact our support team at support@nsoftware.com.