iaik.security.ssl
Class DefaultPSKManager

java.lang.Object
  extended by iaik.security.ssl.PSKManager
      extended by iaik.security.ssl.DefaultPSKManager

public class DefaultPSKManager
extends PSKManager

Default PSKManager. Used by iSaSiLk by default for maintaining pre-shared keys (wrapped into PSKCredentials) for use with psk based cipher suites according to 4279.

An instance of this DefaultPSKManager automatically is installed as application-wide default PSKManager; i.e. one (Default)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);
 
You also may write and plug-in your own PSKManager implementation as default PSKManager to be used:
 public class MyPSKManager extends PSKManager {
   ...
 }
 
 PSKManager.setDefault(new MyPSKManager);
 
PSKCredentials can be added to the DefaultPSKManager by either immediately calling its addPSKCredential method, or -- if not configured to use another PSKManager -- by callin method addPSKCredential of a SSLContext object. 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 (Default)PSKManager. When then connecting to the server with the remote peer id specified in the credential just added, the (Default)PSKManager returns this credential and the client can use it for authenticating the TLS session with this server.
When asking the (Default)PSKManager for a PSKCredential iSaSiLk calls method getPSKCredential(identity, SSLTransport). Depending on if the first argument (identity) is null or not, the PSKManager will search for a PSKCredential based on the psk identity (hint) or based on peer identification information got from the second (SSLTransport) argument.

This default PSK manager allows you to store the contents of the PSK manager password based protected to some file to be later loaded and used:

 DefaultPSKManager manager = new DefaultPSKManager();
 ...
 // add PSKCredentials as required
 ...
 // store PSK manager
 char[] password = ...;
 FileOutputStream fos = ...;
 manager.store(fos, password);
 ...
 // load psk manager
 DefaultPSKManager manager = new DefaultPSKManager();
 FileInputStream fis = ...;
 manager.load(fis, password);
 // set as DefaultManager
 PSKManager.setDefault(manager); 
 

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

Constructor Summary
DefaultPSKManager()
          Creates a new DefaultPSKManager.
 
Method Summary
 void addPSKCredential(PSKCredential pskCredential)
          Adds the given PSKCredential.
 java.lang.Object decodeRemotePeerId(byte[] encodedPeerId)
          Decodes the given encoded remote peer id.
 byte[] encodeRemotePeerId(java.lang.Object peerId)
          Encodes the given remote peer id.
 java.util.Enumeration getAll()
          Gets all PSKCredentials maintained by this PSKManager.
 PSKCredential getPSKCredential(java.lang.String identity, SSLTransport transport)
          Searches the PSKManager for a PSKCredential.
 void load(java.io.InputStream in, char[] password)
          Loads a psk manager from the given input stream.
 void removeAll()
          Removes all PSKCredentials from this PSKManager.
 PSKCredential removePSKCredential(PSKCredential pskCredential)
          Removes the given PSKCredential from this PSKManager.
 PSKCredential removePSKCredential(java.lang.String identity)
          Removes the PSKCredential with the given identity.
 PSKCredential removePSKCredentialWithRemotePeerId(java.lang.Object remotePeerId)
          Removes the given PSKCredential associated with the given remote peer id.
 int size()
          Gets the number of PSKCredentials maintained by this PSKManager.
 void store(java.io.OutputStream out, char[] password)
          Writes the contents of this psk manager pbe encrypted to the given output stream.
 
Methods inherited from class iaik.security.ssl.PSKManager
getDefault, getPSKCredential, removePSKCredential, setDefault
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

DefaultPSKManager

public DefaultPSKManager()
Creates a new DefaultPSKManager.

Method Detail

addPSKCredential

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

Specified by:
addPSKCredential in class PSKManager
Parameters:
pskCredential - the PSKCredential to be added

removePSKCredential

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

Specified by:
removePSKCredential in class PSKManager
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

removePSKCredentialWithRemotePeerId

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

Specified by:
removePSKCredentialWithRemotePeerId in class PSKManager
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 PSKCredential removePSKCredential(PSKCredential pskCredential)
Removes the given PSKCredential from this PSKManager.

Specified by:
removePSKCredential in class PSKManager
Parameters:
pskCredential - the PSKCredential to be removed
Returns:
the PSKCredential just removed, or null if no such PSKCredential is included

removeAll

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

Specified by:
removeAll in class PSKManager

getAll

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

Specified by:
getAll in class PSKManager
Returns:
an Enumeration containing all PSKCredentials included in this PSKManager

size

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

Specified by:
size in class PSKManager
Returns:
the number of PSKCredentials included in this PSKManager

getPSKCredential

public PSKCredential getPSKCredential(java.lang.String 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.
    This 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 this DefaultPSKManager except for on the client side when having received a psk identity hint but not found a proper PSKCredential. In this case this 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. This 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).

Specified by:
getPSKCredential in class PSKManager
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

encodeRemotePeerId

public byte[] encodeRemotePeerId(java.lang.Object peerId)
                          throws java.io.UnsupportedEncodingException
Encodes the given remote peer id.

The default implementation expects that the remote peer id is given as String object. In this case this method returns the UTF-8 encoding of the remote peer id. If not given as String, this method throws an UnsupportedEncodingException. You may override this method if you want to support encoding of remote peer id types that are not given as String objects.

Parameters:
peerId - the peer id to be encoded
Returns:
the encoded peer id
Throws:
java.io.UnsupportedEncodingException - if the remote peerId is not given as String or an error occurs when trying to UTF-8 encode the peer id String
java.lang.NullPointerException - if the given peer id is null

decodeRemotePeerId

public java.lang.Object decodeRemotePeerId(byte[] encodedPeerId)
                                    throws java.io.UnsupportedEncodingException
Decodes the given encoded remote peer id.

The default implementation expects that the given byte array represents an UTF-8 encoded String. In this case this method decodes the UTF-8 encoding to a String peer id. If UTF-8 encoding is not supported or an error occurs when trying to decode the remote peer id, this method throws an UnsupportedEncodingException. You may override this method if you want to support remote peer if formats that are different from UTF-8 and/or remote peer ids other than String objects.

Parameters:
encodedPeerId - the encoded peer id to be decoded
Returns:
the decoded peer id
Throws:
java.io.UnsupportedEncodingException - if the remote peerId cannot be UTF-8 decoded into a String object
java.lang.NullPointerException - if the given peer id is null

load

public void load(java.io.InputStream in,
                 char[] password)
          throws java.io.IOException,
                 java.security.InvalidKeyException,
                 java.security.KeyStoreException
Loads a psk manager from the given input stream. The psk manager has been stored password based encrypted by using method store. Any psk credentials that may have been added so far are cleared.

Parameters:
in - the input stream from which to read the psk manager contents
password - the password to be used for decrypting the contents
Throws:
java.io.IOException - if an error occurs while reading from the stream
java.security.InvalidKeyException - if an error occurs when deriving the content decryption key from the password
java.security.KeyStoreException - if an error occurs while decrypting the contents and parsing the PSKCredentials

store

public void store(java.io.OutputStream out,
                  char[] password)
           throws java.io.IOException,
                  java.security.InvalidKeyException,
                  java.security.KeyStoreException
Writes the contents of this psk manager pbe encrypted to the given output stream. The contents can be restored by calling method load.

Parameters:
out - the output stream to which to write the contents of this psk manager
password - the password to be used for encrypting the contents
Throws:
java.io.IOException - if an error occurs while writing to the stream
java.security.InvalidKeyException - if an error occurs when deriving the content encryption key from the password
java.security.KeyStoreException - if an error occurs while encrypting/storing the contents

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