print Print
Logo: Stiftung Secure Information and Communication Technologies SIC Stiftung Secure Information and Communication Technologies SIC

certificates & authentication

 This document describes how the TLS protocol uses certificates for authentication and the role of the iSaSiLk library and the application.

General

 The TLS protocol uses public key cryptography for authentication. In all ciphersuites except DH_anon the server is authenticated, client authentication is optional for all ciphersuites except DH_anon. Peer authentication in this case means verification that the peer has access to the private key corresponding to the public key contained in the certificate he provided.

 This is part of the TLS protocol and as such performed by the library automatically as configured. What remains for the application is to input its certificates and private keys, specify its algorithm preferences, and, very importantly, verify that the certificate provided by the remote peer is actually trusted.

 Note that this document only describes the new framework and not the old model using TrustDeciders. It is still supported for compatibility though,
 please see the documentation from earlier releases for information about how to use it.
 

Certificates Types

 In TLS the types of certificates used are determined by the ciphersuite. For all standard ciphersuites X.509 certificates are used and the following types of certificates are distinguished

  • RSA. Certificates containing an RSA public key. The algorithm used to
    sign the certificate should also be RSA.
  • DSS. Certificates containing a DSA public key. The algorithm used to
    sign the certificate should also be DSA.
  • DH_RSA. Certificates containing a Diffie-Hellman public key. The algorithm
    used to sign the certificate should be RSA.
  • DH_DSS. Certificates containing a Diffie-Hellman public key. The algorithm
    used to sign the certificate should be DSA.
  • ECDH_RSA. Certificates containing an EC Diffie-Hellman public key. The algorithm
    used to sign the certificate should be RSA.
  • ECDH_ECDSA. Certificates containing an EC Diffie-Hellman public key. The algorithm
    used to sign the certificate should be ECDSA.
  • ECDSA. Certificates containing an ECDSA public key. The algorithm used to
    sign the certificate should also be ECDSA.

Note that we refer to the algorithm DSA digital signature of an SHA-1hash as DSA while the TLS specification uses the name DSS. Both terms
describe the same algorithm and we use them interchangeably.
DH_RSA and DH_DSS certificates both contain a Diffie-Hellman public key and as such are functionally identical. The distinction based on the certificate signature algorithm is only made to allow a peer to advertise that does or does not implement the RSA or DSA algorithm. In the same way ECDH_RSA and ECDH_ECDSA are functionally identical but the algorithm used to sign the certificate is different.

The Server Side

 The server requires certificates if a non-anonymous ciphersuite is used. In iSaSiLk you can set the server certificates using the

addServerCredentials() method of the SSLServerContext class. You can pass either a PrivateKey object and an array of X509Certificates or a KeyAndCert object (KeyAndCert is a simple class that stores a private key and the corresponding certificate chain), or a KeyStore object (which may
contain multiple server credentials, i.e. private key entries and corresponding certificate chains).. The addServerCredentials() method automatically determines the type of certificate used and stores it replacing existing credentials of the same type.
 

Certificates

 Below is a table of the certificate types and the ciphersuites that require its presence to function. Ciphersuites are identified via their TLS keyexchange algorithm.

 Certificate type

 Key exchange algorithm requiring this type of certificate

RSA

RSA, RSA_EXPORT, RSA_EXPORT1024, DHE_RSA, DHE_RSA_EXPORT, ECDHE_RSA

DSS

DHE_DSS, DHE_DSS_EXPORT, DHE_DSS_EXPORT1024

DH_RSA

DH_RSA, DH_RSA_EXPORT

DH_DSS

DH_DSS, DH_DSS_EXPORT

ECDH_RSA

ECDH_RSA

ECDH_ECDSA

ECDH_ECDSA

ECDSA

ECDHE_ECDSA

No certificate

DH_anon, DH_anon_EXPORT, ECDH_anon

 

 Unless the required certificate is available that ciphersuite cannot be used. Calling updateCipherSuites() on the SSLServerContext object will
 automatically disable all those ciphersuites that cannot be used.
 

Temporary Parameters

 In addition to certificates and a private key some ciphersuites require additional parameters. In particular, DHE ciphersuites require temporary Diffie-Hellman parameters (prime modulus and a generator), and ECDHE ciphersuites require temporary EC parameters (elliptic curve domain parameters, i.e. named_curve). Also exportable RSA ciphersuites require a temporary RSA keypair if the public key in the certificate is longer than the limit for that ciphersuite (i.e. 512 bit for EXPORT, 1024 bit for EXPORT1024).

For DHE and RSA those parameters can be set using the addTemporaryParameter() method of SSLServerContext. If a temporary parameter is not set but a ciphersuite is chosen in the handshake that requires it defaults are used. For DHE this means pre-generated Diffie-Hellman parameters of 512 or 1024 are used, for
RSA a new 512 or 1024 bit RSA keypair is generated on the fly. For ECDHE the curve is negotiated by means of the SupportedEllipticCurves extension.
 

 RSA keypair generator may take a few seconds, especially for 1024 bit keys. If this is a concern you should not use the defaults and set a temporary keypair manually, but note that the keypair generation will only be performed once per JVM invocation anyway. For additional information about temporary parameters please see the JavaDoc.

The Client Side

 The client does not require certificates per se, but as noted above the server may request client authentication and choose not to accept clients with an appropriate certificate.

 In TLS client authentication works as follows: during the handshake the server may request a client certificate. While doing that he also specifies which types of client certificates he wants to accept (and same four basic types described above) and optionally which certificate authorities he trusts (he lists their subject distinguished names). Both of this is done to make it easier for the client to choose the correct certificate. The server may also choose not to tell which CAs he trusts and send an empty list instead.

Note that client authentication with RSA, ECDSA and DSS certificates is available for all ciphersuites, DH_RSA and DH_DSS is only available for DH_ ciphersuites, and ECDH_RSA and ECDH_ECDSA is only available for ECDH_ ciphersuites, i.e. those where the server uses (EC)DH certificates as well. These are a special case because the EC(DH) keys cannot be used for signatures and authentication has to be performed differently. For this and other reasons we generally recommend ECDHE, DHE, ECDSA and RSA over (EC)DH.

Requesting Client Authentication

 In iSaSiLk the server can request client authentication by calling serverContext.setRequestClientCertificate(true). The valid certificate types and trusted CAs are determined automatically. You can also restrict the types of client certificates you wish to accept, e.g. not allow DSS certificates. Use the method

serverContext.setAllowedCertificateTypes(). The trusted certificate authorities are determined using the ChainVerifier's getTrustedPrincipalsArray() method, see below for more information about the ChainVerifier class.
 

Adding Credentials

 For client authentication with iSaSiLk the client only needs to add this private keys and certificates, the library will automatically select the appropriate ones. To add credentials use the clientContext.addCredentials() method. You can add as many as you want, they will automatically be stored in a database. You can pass either a PrivateKey object and an array of X509Certificates or a KeyAndCert object (KeyAndCert is a simple class that stores a private key and the corresponding certificate chain), or a KeyStore object (which may contain multiple client credentials, i.e. private key entries and corresponding certificate chains).

 During the handshake the library code calls the clientContext.getClientCredentials() method to retrieve client certificates. If you want to implement your own storage mechanism you only need to override this method.

Trust Settings and Verification

 There are two basic parts to verifying trust: (a) specifying which certificates (and CA trees) to trust and (b) a profile to follow when verifying certificate chains.

 In iSaSiLk this is handled by the ChainVerifier class. It also you to specify trusted certificates and its code implements a basic X.509v1 style profile to verify certificate chains. It can be replaced by a more advanced implementation if desired, for example it would be possible to use the IAIK Trust Manager. For information about custom ChainVerifier please see the JavaDoc API documentation.

 You can specify trusted certificates by calling e.g. context.addTrustedCertificate(), which is a shorthand for context.getChainVerifier().addTrustedCertificate(). The library code will call the ChainVerifier during the handshake as described below.

Client Side Trust Verification

 The client verifiers that the server has an acceptable certificate. The following cases arise (assuming the default ChainVerifier implementation is used):

  •   ChainVerifier is null: If the ChainVerifier for the current SSLContext is null all certificates are accepted. Note that the ChainVerifier is only null when explicitly set to null by the application.
  •   CipherSuite is (EC)DH_anon: If the active ciphersuite is anonymous the ChainVerifier is not called and the connection is accepted. The reasoning is that (EC)DH_anon is only used when explicitly enabled by the user making an additional check of the always server certificate redundant (for (EC)DH_anon the server certificate is of course actually null).
  •   No trusted certificates set: If no trusted certificates have been specified all valid certificate chains are accepted. Valid in this case means that all signature verify, no certificates are expired, etc.
  •   One or more trusted certificates set: If trusted certificate have been specified only chains that are valid and contain a trusted certificate are accepted.

 For more information please the the JavaDoc for the ChainVerifier class.

Server Side Trust Verification

 The client verifiers that the server has an acceptable certificate. The following cases arise (assuming the default ChainVerifier implementation is used):

  •   Client authentication disabled: If client authentication is disabled the client is always accepted. The ChainVerifier is not callled.
  •   ChainVerifier is null: If client authentication is enabled but the current ChainVerifier is null, all client certificates and clients which do not send a certificate are accepted.
  •   Client does not send a certificate: If client authentication is enabled, the ChainVerifier is not null, but the client does not send a certificate, the connection is only accepted if null was specified as a trusted certificate (via context.addTrustedCertificate(null)).
  •   No trusted certificates specified: If the client sends a certificate but no trusted certificates have been specified in the ChainVerifier (except for possibly null), all valid certificate chains are accepted. Valid in this case means that all signature verify, no certificates are expired, etc.
  •   One or more trusted certificates specified: If the client sends a certificate and some trusted certificates have been specified in the
     ChainVerifier only chains that are valid and contain a trusted certificate are accepted.

 For more information please the the JavaDoc for the ChainVerifier class.

Key and Certificate Handling for TLS extensions

 Some TLS extensions may require an additional/alternative key or certificate handling. If, for instance, the client sends an OCSP certificate status_request extension to the server, it may have to validate the OCSP status response sent back by the server. In this case the alternative OCSPCertStatusChainVerifier maybe enabled to check the OCSP response got from the server:

SSLClientContext clientContext = new SSLClientContext();
OCSPCertStatusChainVerifier ocspChainVerifier = new OCSPCertStatusChainVerifier();
clientContext.setChainVerifier(ocspChainVerifier);

 See the iSaSiLk

TLS extensions (143.81 kB)
 

print Print