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 setPSKManager
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.
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, setDefault
public void addPSKCredential(PSKCredential pskCredential)
addPSKCredential
in class PSKManager
pskCredential
- the PSKCredential to be addedpublic PSKCredential removePSKCredential(java.lang.String identity)
removePSKCredential
in class PSKManager
identity
- 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 PSKManager
remotePeerId
- 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 PSKManager
pskCredential
- the PSKCredential to be removednull
if
no such PSKCredential is includedpublic void removeAll()
removeAll
in class PSKManager
public java.util.Enumeration getAll()
getAll
in class PSKManager
public int size()
size
in class PSKManager
public 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 PSKManager
identity
- 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 null
public 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 null
public 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