public class DefaultPSKManager extends PSKManager
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 sslContext, e.g. (when using the setPSKManagerDefaultPSKManager):
// 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.
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);
| Constructor and Description |
|---|
DefaultPSKManager()
Creates a new DefaultPSKManager.
|
| Modifier and Type | Method and Description |
|---|---|
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.
|
getDefault, getPSKCredential, removePSKCredential, setDefaultpublic void addPSKCredential(PSKCredential pskCredential)
addPSKCredential in class PSKManagerpskCredential - the PSKCredential to be addedpublic PSKCredential removePSKCredential(java.lang.String identity)
removePSKCredential in class PSKManageridentity - the identity of the PSKCredential to be removednull if
no PSKCredential with the given identity is includedpublic PSKCredential removePSKCredentialWithRemotePeerId(java.lang.Object remotePeerId)
removePSKCredentialWithRemotePeerId in class PSKManagerremotePeerId - the remote peer id associated with the PSKCredential to be removednull if
no PSKCredential for the given remote peer id is includedpublic PSKCredential removePSKCredential(PSKCredential pskCredential)
removePSKCredential in class PSKManagerpskCredential - the PSKCredential to be removednull if
no such PSKCredential is includedpublic void removeAll()
removeAll in class PSKManagerpublic java.util.Enumeration getAll()
getAll in class PSKManagerpublic int size()
size in class PSKManagerpublic PSKCredential getPSKCredential(java.lang.String identity, SSLTransport transport) throws SSLException
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).
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.
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).
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):
transport.getRemotePeerName()
transport.getRemoteIndetAddress().getHostAddress()
transport.getRemotePeerId()
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).
getPSKCredential in class PSKManageridentity - the identity, if not null identifying the PSK
for which to searchtransport - the SSLTransport to maybe used for getting information
about the remote peer (if identity is
null or if required by the psk management
implementation)null if no such PSKCredential is includedSSLException - if an error occurs when trying to get the requested
PSKCredentialpublic byte[] encodeRemotePeerId(java.lang.Object peerId)
throws java.io.UnsupportedEncodingException
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.
peerId - the peer id to be encodedjava.io.UnsupportedEncodingException - if the remote peerId is not given
as String or an error occurs when
trying to UTF-8 encode the peer id
Stringjava.lang.NullPointerException - if the given peer id is nullpublic java.lang.Object decodeRemotePeerId(byte[] encodedPeerId)
throws java.io.UnsupportedEncodingException
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.
encodedPeerId - the encoded peer id to be decodedjava.io.UnsupportedEncodingException - if the remote peerId cannot be UTF-8
decoded into a String objectjava.lang.NullPointerException - if the given peer id is nullpublic void load(java.io.InputStream in,
char[] password)
throws java.io.IOException,
java.security.InvalidKeyException,
java.security.KeyStoreException
store. Any psk credentials that may have been added so
far are cleared.in - the input stream from which to read the psk manager
contentspassword - the password to be used for decrypting the
contentsjava.io.IOException - if an error occurs while reading from the streamjava.security.InvalidKeyException - if an error occurs when deriving the
content decryption key from the passwordjava.security.KeyStoreException - if an error occurs while decrypting the
contents and parsing the PSKCredentialspublic void store(java.io.OutputStream out,
char[] password)
throws java.io.IOException,
java.security.InvalidKeyException,
java.security.KeyStoreException
load.out - the output stream to which to write the contents of
this psk managerpassword - the password to be used for encrypting the
contentsjava.io.IOException - if an error occurs while writing to the streamjava.security.InvalidKeyException - if an error occurs when deriving the
content encryption key from the passwordjava.security.KeyStoreException - if an error occurs while encrypting/storing
the contents