iaik.security.ssl
Class PSKManager

java.lang.Object
  extended by iaik.security.ssl.PSKManager
Direct Known Subclasses:
DefaultPSKManager

public abstract class PSKManager
extends java.lang.Object

Abstract parent class of all PSKManagers. A PSKManager is used to maintain and manage pre-shared keys for use with PSK cipher suites.

When client and server agree on a psk cipher suite, the client has to tell the server which pre-shared key (psk) shall be used by sending the psk identity within the ClientKeyExchange message. If the server has a pre-shared key for the received identity the handshake can continue, otherwise the handshake will fail. Before receiving the psk identity in the ClientKeyExchange message, the server may use the ServerKeyExchange message to send a psk identity hint to help the client to select a proper pre-shared key. However, the TLS-PSK specification recommends that an identity hint should not be sent by the server and that it must be ignored by the client (except for a special profile makes some other recommendation).

iSaSiLk wraps pre-shared keys into PSKCredentials. Each PSKCredential binds a pre-shared key to a psk identity. Optionally a PSKCredential may also contain a psk identity hint for the pre-shared key and identification information of the peer to which to authenticate with the pre-shared key of the credential.
The PSKManager is responsible for maintaining PSKCredentials to provide the right pre-shared key when going into a TLS connection with some particular peer. On the server side, the PSKManager searches for the psk by means of the psk identity received from the client. On the client side, the PSKManager needs to know the remote peer id to search for the right pre-shared key. You may write and plug-in your own PSKManager (or set it as default PSKManager); however, in general you may not take care about PSKManager details at all and only use the SSLContext addPSKCredential, setPSKCredential methods to add/set PSKCredentials for being used for psk cipher suite based TLS authentication. To, for instance, tell iSaSiLk to use a pre-shared key with identity "pskclient.iaik.tugraz.at" for communicating with a server named "pskserver.iaik.tugraz.at" you may create and add a PSKCredential in the following way:

 // psk identity
 String identity = "pskclient.iaik.tugraz.at";
 // server name (remote peer id)
 String serverName = "pskserver.iaik.tugraz.at";
 // the pre-shared key
 PreSharedKey psk = ...;
 // create PSKCredential
 PSKCredential pskCredential = new PSKCredential(identity, psk);
 // set remote peer id
 pskCredential.setRemotePeerId(serverName);
 // create client context
 SSLClientContext context = new SSLClientContext();
 // add PSKCredential
 context.addPSKCredential(pskCredential);
 // enable PSK cipher suites
 CipherSuiteList suites = new CipherSuiteList();
 suites.add(CipherSuite.CS_ALL_PSK);
 context.setEnabledCipherSuiteList(suites);
 context.updateCipherSuites();
 ...
 
When calling method addPSKCredential iSaSiLk forwards the given PSKCredential to the internal PSKManager. When then connecting to the server with the remote peer id specified in the credential just added, the PSKManager returns this credential and the client can use it for authenticating the TLS session with this server. Note, that you can disable the PSKManager at all by using method setPSKCredential for specifying an exclusive PSKCredential to be used only with some specific SSLContext. This may be suitable on the client side: since you already know the server when creating the SSLClientContext you also will know the pre-shared key to be used for establishing a TLS-PSK session with this server. Thus you may not neet a PSKManager and may explicitly set the corresponding PSKCredential to be used with this specific SSLClientContext. However, be careful to use setPSKCredential on the server side. In this case your server will only have one single pre-shared key to be used with any client that requests a PSK based TLS communication.

On the server side a remote peer id for a PSKCredential is only required when the server wants to send a psk identity hint to the client. However, usage of psk identity hints is not recommended by the TLS-PSK specification.

In the sample above we have enabled all psk based cipher suites by calling suites.add(CipherSuite.CS_ALL_PSK);. However, you also can enable one specific cipher suite only (e.g. CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA) or any of the three defined sets of psk based cipher suites:

  1. Cipher suites that use symmetric key operations for authentication only:
            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
            
  2. Cipher suites that use a Diffie-Hellman key exchange authenticated with a pre-shared key:
            TLS_DHE_PSK_WITH_RC4_128_SHA,
            TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
            TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
            TLS_DHE_PSK_WITH_AES_256_CBC_SHA  
            
  3. Cipher suites Cipher suites that use a RSA public key authentication of the server and pre-shared key authentication of the client:
            TLS_RSA_PSK_WITH_RC4_128_SHA,
            TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
            TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
            TLS_RSA_PSK_WITH_AES_256_CBC_SHA
            
As mentioned above, when calling the SSLContext method addPSKCredential, the credential is forwarded to the internal PSKManager. By default iSaSiLk uses the system-wide DefaultPSKManager, i.e. one PSKManager is used for maintaining the PSKCredentials for all SSLContext objects that may be created during the application lifetime. If you want to use a separate PSKManager for each SSLContext you may configure it with the PSKCredentials to be used and set it for a SSLContext by calling method sslContextsetPSKManager, e.g. (when using the DefaultPSKManager):
 // create PSKManager 
 PSKManager manager = new DefaultPSKManager();
 // add PSKCredential(s) as required
 PSKCredential credential = ...;
 manager.addPSKCredential(credential);
 ...
 // set the PSKManager for some SSLContext
 SSLContext context = ...;
 context.setPSKManager(manager);
 

See Also:
PreSharedKey, PSKCredential, DefaultPSKManager, SSLContext.setPSKManager(PSKManager), SSLContext.addPSKCredential(PSKCredential), SSLContext.setPSKCredential(PSKCredential), SSLContext.getPSKCredential(byte[], SSLTransport)

Constructor Summary
protected PSKManager()
          Constructor to be used by subclasses.
 
Method Summary
abstract  void addPSKCredential(PSKCredential pskCredential)
          Adds the given PSKCredential.
abstract  java.util.Enumeration getAll()
          Gets all PSKCredentials maintained by this PSKManager.
static PSKManager getDefault()
          Gets the current PSKManager.
 PSKCredential getPSKCredential(byte[] identity, SSLTransport transport)
          Searches the PSKManager for a PSKCredential.
abstract  PSKCredential getPSKCredential(java.lang.String identity, SSLTransport transport)
          Searches the PSKManager for a PSKCredential.
abstract  void removeAll()
          Removes all PSKCredentials from this PSKManager.
 PSKCredential removePSKCredential(byte[] identity)
          Removes the PSKCredential with the given identity.
abstract  PSKCredential removePSKCredential(PSKCredential pskCredential)
          Removes the given PSKCredential from this PSKManager.
abstract  PSKCredential removePSKCredential(java.lang.String identity)
          Removes the PSKCredential with the given identity.
abstract  PSKCredential removePSKCredentialWithRemotePeerId(java.lang.Object remotePeerId)
          Removes the PSKCredential associated with the given remote peer id.
static void setDefault(PSKManager manager)
          Sets the PSKManager.
abstract  int size()
          Gets the number of PSKCredentials maintained by this PSKManager.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

PSKManager

protected PSKManager()
Constructor to be used by subclasses.

Method Detail

getDefault

public static PSKManager getDefault()
Gets the current PSKManager. Initially set to an instance of DefaultPSKManager. An application may plug-in its own PSKManager implementation.

Returns:
the current PSKManager or null if PSK management is disabled

setDefault

public static void setDefault(PSKManager manager)
Sets the PSKManager. Set to null to disable PSK management for the whole application environment after (!) this call.


addPSKCredential

public abstract void addPSKCredential(PSKCredential pskCredential)
Adds the given PSKCredential.

Parameters:
pskCredential - the PSKCredential to be added

removePSKCredential

public abstract PSKCredential removePSKCredential(java.lang.String identity)
Removes the PSKCredential with the given identity.

Parameters:
identity - the identity of the PSKCredential to be removed
Returns:
the PSKCredential just removed, or null if no PSKCredential with the given identity is included

removePSKCredential

public PSKCredential removePSKCredential(byte[] identity)
                                  throws java.io.UnsupportedEncodingException
Removes the PSKCredential with the given identity.

Parameters:
identity - the identity of the PSKCredential to be removed
Returns:
the PSKCredential just removed, or null if no PSKCredential with the given identity is included
Throws:
java.io.UnsupportedEncodingException - if the given identity cannot be UTF-8 decoded to give the identity String key

removePSKCredentialWithRemotePeerId

public abstract PSKCredential removePSKCredentialWithRemotePeerId(java.lang.Object remotePeerId)
Removes the PSKCredential associated with the given remote peer id.

Parameters:
remotePeerId - the remote peer id associated with the PSKCredential to be removed
Returns:
the PSKCredential just removed, or null if no PSKCredential for the given remote peer id is included

removePSKCredential

public abstract PSKCredential removePSKCredential(PSKCredential pskCredential)
Removes the given PSKCredential from this PSKManager.

Parameters:
pskCredential - the PSKCredential to be removed
Returns:
the PSKCredential just removed, or null if no such PSKCredential is included

removeAll

public abstract void removeAll()
Removes all PSKCredentials from this PSKManager.


getAll

public abstract java.util.Enumeration getAll()
Gets all PSKCredentials maintained by this PSKManager.

Returns:
an Enumeration containing all PSKCredentials included in this PSKManager

size

public abstract int size()
Gets the number of PSKCredentials maintained by this PSKManager.

Returns:
the number of PSKCredentials included in this PSKManager

getPSKCredential

public abstract PSKCredential getPSKCredential(java.lang.String identity,
                                               SSLTransport transport)
                                        throws SSLException
Searches the PSKManager for a PSKCredential.

This method does the same as method getPSKCredential(byte[], SSLTransport) except for that the psk identity is given as String instead of a byte array

Parameters:
identity - the identity String, if not null identifying the PSK for which to search
transport - the SSLTransport to maybe used for getting information about the remote peer (if identity is null or if required by the psk management implementation)
Returns:
the PSKCredential fulfilling the given search requirements; or null if no such PSKCredential is included
Throws:
SSLException - if an error occurs when trying to get the requested PSKCredential

getPSKCredential

public PSKCredential getPSKCredential(byte[] identity,
                                      SSLTransport transport)
                               throws SSLException
Searches the PSKManager for a PSKCredential.

This method maybe called by iSaSiLk in two different situations, depending on if the identity argument is null or not. If not null the PSKManager is searched for a PSKCredential with the specific psk identity (see 1. below). If null the PSKManager is searched based on identification information provided by the second (SSLTransport) argument (see 2. below).

  1. If the identity argument is not null this method is called by iSaSiLk to search for a pre-shared key for the given identity. When called on the server side, the given identity represents the psk identity sent by the client within the ClientKeyExchange message. When called on the client side, the given identity represents the psk identity hint that may have been sent by the server within the ServerKeyExchange message. Note that the TLS-PSK specification (RFC 4279) does NOT recommend to use a psk identity hint. Unless not explicitly required by the application environment, the server SHOULD NOT send a psk identity hint, and the client MUST ignore a psk identity hint if sent by the server.
    The default PSKManager implementation requires that each identity is unique for the whole application environment. Thus, if the identity argument is not null the second argument (SSLTransport) of this method is not used by the DefaultPSKManager except for on the client side when having received a psk identity hint but not found a proper PSKCredential. In this case the DefaultPSKManager looks if he has a PSKCredential with the peer id of the server (got from the SSLTransport argument).
    However, an application-specific PSKManager implementation may need information provided by the SSLTransport object in any case (for instance, to support a psk management policy allowing to use same identities for different remote peer ids).

  2. If the identity argument is null this method is called by iSaSiLk to search for a pre-shared key based on peer information provided by the given SSLTransport object. The default PSKManager implementation asks the given SSLTransport for peer identification information by calling the following methods (in that order):

    If you are, for instance, on the client side and want to go into a psk based TLS session with a server "pskserver.iaik.tugraz.at" with ip address "129.27.142.47" listening on port 4433, the SSL(Socket)Transport methods above will return the following values (in that order):

    • pskserver.iaik.tugraz.at
    • 129.27.142.47
    • 129.27.142.47:4433

    Thus, when registering a PSKCredential to be used for a TLS communication with the "pskserver.iaik.tugraz.at" server, it must have one of the three identification information values from above as remote peer id, e.g.:

     // the psk identity
     String identity = ...;
     // the pre-shared key
     PreSharedKey psk = ...;
     // create PSKCredential
     PSKCredential pskCredential = new PSKCredential(identity, psk);
     // set remote peer id
     int serverPort = 4433;
     
     String serverName = "pskserver.iaik.tugraz.at";
     pskCredential.setRemotePeerId(serverName);
     
     // create SSLClientContext and add the credential
     SSLClientContext context = new SSLClientContext();
     // calling this method forwards the PSKCredential to the internal PSKManager
     context.addPSKCredential(pskCredential);
     
    When now connecting to server "pskserver.iaik.tugraz.at", iSaSiLk asks the PSK manager for a PSKCredential with remote peer id "pskserver.iaik.tugraz.at" and the connection can succeed if both parties support the negotiated cipher suite and have a corresponding pre-shared key:
     //  enable PSK cipher suites
     CipherSuiteList suites = new CipherSuiteList();
     suites.add(CipherSuite.CS_ALL_PSK);
     SSLSocket socket = new SSLSocket(serverName, serverPort, context);
     // start handshake
     socket.startHandshake();
     // psk identity
     String pskIdentity = socket.getPSKIdentity();
     if (pskIdentity != null) {
       System.out.println("PSK Identity: " + pskIdentity);
     }
     // send GET-request
     System.out.println("Sending HTTPS request to " + serverName);
     PrintWriter writer = Utils.getASCIIWriter(socket.getOutputStream());
     BufferedReader reader = Utils.getASCIIReader(socket.getInputStream());
     writer.println("GET / HTTP/1.0");
     writer.println();
     writer.flush();
     // read response
     while( true ) {
       String line = reader.readLine();
       if( line == null ) {
         break;
       }
       System.out.print(":");
       System.out.println(line);
     }
     socket.close();
     
    Note, that if the psk identity already represents any of the remote peer ids, it may be not necessary to explicitly set it as remote peer id for the psk credential (the DefaultPSKManager implementation looks for the id in this case, too), e.g.:
     String serverName = "pskserver.iaik.tugraz.at";
     // the psk identity
     String identity = serverName;
     // the pre-shared key
     PreSharedKey psk = ...;
     // create PSKCredential
     PSKCredential pskCredential = new PSKCredential(identity, psk);
     
    In similar way, if the remote peer id is equal to the psk identity hint, it may be sufficient to only set the psk identity hint.

    On the server side searching for a PSKCredential based on peer id is only required if the server is configured to send a psk identity hint. However, sending a psk identity hint is not recommended by the TLS-PSK specification (see RFC 4279).

Parameters:
identity - the identity, if not null identifying the PSK for which to search
transport - the SSLTransport to maybe used for getting information about the remote peer (if identity is null or if required by the psk management implementation)
Returns:
the PSKCredential fulfilling the given search requirements; or null if no such PSKCredential is included
Throws:
SSLException - if an error occurs when trying to get the requested PSKCredential (e.g. if the given identity cannot be UTF-8 decoded to give the identity String key)

This Javadoc may contain text parts from text parts from IETF Internet Standard specifications (see copyright note).

iSaSiLk 6.0, (c) 2002 IAIK, (c) 2003 - 2015 SIC