Using Pre-Shared Keys with Transport Layer Security : Tutorial

This topic describes how to use Pre-Shared Keys (PSKs) with Transport Layer Security (TLS). This tutorial is useful for licensees and third-party developers.

TLS_PSK is a standard for using PSKs with Transport Layer Security (TLS). You can use TLS_PSK instead of certificate authentication. The benefits of using TLS_PSK are as follows:

  • Easy to manage - For example, PSK can derive from a "secret key" that vendors deploy in the SIM card of each phone.

  • It improves the connection setup performance and battery life, as the key exchange algorithm takes less time to run.

Symbian maintains the following TLS_PSK ciphersuites:

  • TLS_PSK_WITH_RC4_128_SHA

  • TLS_PSK_WITH_3DES_EDE_CBC_SHA

  • TLS_PSK_WITH_AES_128_CBC_SHA

  • TLS_PSK_WITH_AES_256_CBC_SHA

The ciphersuite is made up of a key exchange (for example PSK), a cipher (for example RC4_128) and a hash (for example SHA).

Note: TLS_PSK operation is specified by RFC4279 .

For a client to make a secure connection with a TLS_PSK server, it must provide a pre-shared key and an identity. To provide a pre-shared key and an identity, do the following steps:

  1. Configure a PSK key handler

  2. Set available ciphersuites. There are two possibilities for offering PSK ciphersuites:
    1. Specify an explicit ordered list of ciphersuites for the server to select from. To do this call SetAvailableCipherSuites() . You can do this only after configuring the PSK key handler.
    2. Use the default list, which is automatically generated. If you do not specify an explicit list, the stack automatically includes the PSK ciphersuites in addition to any other ciphersuites supported.
    If you specify an explicit list by calling SetAvailableCipherSuites() , and you later deconfigure the PSK key handler, you must remove the PSK ciphersuites from the list by calling SetAvailableCipherSuites() again.

  3. Start a connection. The server chooses a ciphersuite from those offered by the client. If the server chooses a PSK ciphersuite, the following sequence of events occurs:
    1. The server can optionally send a “PSK identity hint” to the client. This PSK identity hint might influence the choice of key and identity the client makes. If the server sends one, it is passed to the key handler. If it does not send one, NULL is passed to the key handler. Note: The PSK identity hint is optional and its meaning is not defined (format must be UTF8). Applications using TLS-PSK may left out it or use it for any action (for example SUPL uses it to indicate the SUPL protocol version and to present a list of allowed PSK generators).
    2. The TLS stack on the client calls ptrToKeyHandler->getPskL() The TLS stack on the client calls getPskL() for the instance of the key handler (in this case ptrToKeyHandler). See MSoPskKeyHandler:: GetPskL() for the prototype. This call returns the PSK identity and value to be used to secure the connection.
    3. The TLS stack sends the PSK identity to the server. The TLS stack sends the PSK identity (chosen in Step 2) to the server so it can retrieve the matching PSK value to secure the connection.
    After the client has chosen which PSK to use, it sends an identity to the server and the server can use this to obtain a matching PSK. Again the meaning of the identity field is not specified, but its format must be UTF8. An application may choose to use it or leave it empty. Note: In the example, the server must select a PSK ciphersuite, because the client provides only PSK ciphersuites. The connection fails, if the server selects a PSK ciphersuite and fails to get a key that matches with the client. The TLS assumes that the first common ciphersuite cannot fail and does not implement connection retry.

TLS_PSK example

The following example code shows how to configure TLS_PSK:

       
        
       
       //Configure a PSK key handler

TPckgBuf<MSoPskKeyHandler *> pskConfigPkg;
pskConfigPkg() = ptrToKeyHandler;
User::LeaveIfError(secureSocket->SetOpt(KSoPskConfig, KSolInetSSL, pskConfigPkg));

//set available ciphersuites 

TBuf8<8> buf;    
for(TInt i=0; i<4; ++i)
{
 // The supported PSK ciphersuites are as follows:-
 // TLS_PSK_WITH_RC4_128_SHA          = { 0x00, 0x8A };
 // TLS_PSK_WITH_3DES_EDE_CBC_SHA     = { 0x00, 0x8B };
 // TLS_PSK_WITH_AES_128_CBC_SHA      = { 0x00, 0x8C };
 // TLS_PSK_WITH_AES_256_CBC_SHA      = { 0x00, 0x8D };
 buf[i*2]=0;
 buf[i*2+1]=0x8a+i;
}
secureSocket->SetAvailableCipherSuites( buf );

//Start a connection

secureSocket->StartClientHandshake( iStatus );