Package org.ka2ddo.yaac.auth
Class YAACKeyManager
java.lang.Object
org.ka2ddo.yaac.auth.YAACKeyManager
- All Implemented Interfaces:
KeyManager
,X509KeyManager
This class stores encryption keys used for signing and verifying messages.
There are two meanings of signing:
- public key signing with the sender's private key and verifying with their public key.
- secret key Hashed Message Authentication Code for signing and verifying.
This class is the repository for keys used for this signing and verifying, backed by a Java keystore. It supports:
- private keys with associated public key certificate chains,
- public key certificates of other users,
- secret keys of the local user or other users.
It also provides the APRS message signing and verifying logic, and provides a means to associate other station's callsigns with keys and certificates. This class also provides services to create, export, import, and delete keys and certificates.
This is based on research reported by Bryan Hoyer KG6GEU in a presentation to the NW Digital Radio group on 2013-Mar-31
- Author:
- Andrew Pavlin, KA2DDO
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic enum
Enumeration identifying different types of encryption keys that can be stored in the KeyManager. -
Method Summary
Modifier and TypeMethodDescriptionchooseClientAlias
(String[] keyTypes, Principal[] principals, Socket socket) Choose an alias to authenticate the client side of a secure socket given the public key type and the list of certificate issuer authorities recognized by the peer (if any).chooseServerAlias
(String algChoice, Principal[] principals, Socket socket) Choose an alias to authenticate the server side of a secure socket given the public key type and the list of certificate issuer authorities recognized by the peer (if any).void
createSecretKey
(String alias) Create a new secret (symmetric) key.void
Delete a key from the local keystore.boolean
Test if the keystore has been created yet,String[]
findMatchingKeys
(String callsign, YAACKeyManager.KeyType keyType) Search the keystore for keys that match the destination addressee of the specified message.String[]
Get all key aliases stored in the keystore.String[]
getAssociations
(String alias) Get all the associated callsigns allowed to use the key specified by the alias.getCertificateChain
(String alias) Returns the certificate chain associated with the given alias.String[]
getClientAliases
(String algChoice, Principal[] principals) Get the matching aliases for authenticating the client side of a secure socket given the public key type and the list of certificate issuer authorities recognized by the peer (if any).static YAACKeyManager
Get the KeyManager singleton.Get the key associated with the specified alias.getKeyType
(String alias) Get the type of key associated with the specified alias.getPrivateKey
(String alias) Get the PrivateKey associated with the specified alias.String[]
getServerAliases
(String algChoice, Principal[] principals) Get the matching aliases for authenticating the server side of a secure socket given the public key type and the list of certificate issuer authorities recognized by the peer (if any).void
insertPrivateKey
(String alias, PrivateKey key, Certificate[] certs) Insert a private key with its associated public key certificate chain.void
insertPublicCertificateChain
(String alias, CertPath chain) Store the public key certificates for some other station into the keystore.void
insertSecretKey
(String alias, byte[] encoded) Store a byte-encoded secret (symmetric) key in the keystore.boolean
Test if the backing keystore's password has been set.static void
unit test.void
setAssociations
(String alias, String[] associations) Get all the associated callsigns allowed to use the key specified by the alias.void
setPassword
(char[] password) Set the password to be used to decode keys in the backing keystore.void
sign
(AprsSignableMessage mm, String alias) Sign a timestamped APRS message with the specified key.Verify the signature (if any) in an APRS message against the keys in the local keystore.
-
Method Details
-
getInstance
Get the KeyManager singleton.- Returns:
- instance of KeyManager
-
isPasswordSet
public boolean isPasswordSet()Test if the backing keystore's password has been set.- Returns:
- boolean true if password has been successfully set
-
setPassword
public void setPassword(char[] password) throws NullPointerException, IOException, GeneralSecurityException Set the password to be used to decode keys in the backing keystore.- Parameters:
password
- char array of the password- Throws:
NullPointerException
- if password was nullIOException
- if keystore file could not be read for any reasonGeneralSecurityException
- if keystore file could not be decoded for any reason
-
doesKeystoreExistYet
public boolean doesKeystoreExistYet()Test if the keystore has been created yet,- Returns:
- boolean true if keystore backing file exists (i.e., the keystore has been created)
-
getKey
Get the key associated with the specified alias.- Parameters:
alias
- String alias name for a key- Returns:
- the Key associated with the alias
- Throws:
NullPointerException
- if the keystore's password was not successfully set yet
-
getAliases
Get all key aliases stored in the keystore.- Returns:
- array of String aliases
- Throws:
NullPointerException
- if the keystore's password was not successfully set yet
-
getKeyType
Get the type of key associated with the specified alias.- Parameters:
alias
- String name associated with the desired key- Returns:
- KeyType specifying the kind of key associated with the alias, or null if no key with the specified alias
- Throws:
NullPointerException
- if the keystore's password was not successfully set yet
-
getAssociations
Get all the associated callsigns allowed to use the key specified by the alias.- Parameters:
alias
- String name of the key to query- Returns:
- array of callsigns and broadcast aliases associated with the named key (possibly zero length if no associations)
-
setAssociations
Get all the associated callsigns allowed to use the key specified by the alias.- Parameters:
alias
- String name of the key to modifyassociations
- array of callsign Strings to associate with named key
-
createSecretKey
Create a new secret (symmetric) key.- Parameters:
alias
- String name to label the key- Throws:
NullPointerException
- if keystore password hasn't been correctly set yetKeyStoreException
- if key can't be stored in backing keystore file
-
insertSecretKey
public void insertSecretKey(String alias, byte[] encoded) throws NullPointerException, KeyStoreException Store a byte-encoded secret (symmetric) key in the keystore. Used to import a key generated by someone else.- Parameters:
alias
- String name to associate with keyencoded
- byte array of the encoded key- Throws:
NullPointerException
- if keystore password hasn't been correctly set yetKeyStoreException
- if key can't be stored in backing keystore file
-
insertPublicCertificateChain
Store the public key certificates for some other station into the keystore.- Parameters:
alias
- String name to associate with this public keychain
- array of Certificates containing the public key and identifying the issuers up to the certificate authority
-
insertPrivateKey
public void insertPrivateKey(String alias, PrivateKey key, Certificate[] certs) throws KeyStoreException Insert a private key with its associated public key certificate chain.- Parameters:
alias
- String name to associate with this key pairkey
- PrivateKeycerts
- array of Certificates listing the public key associated with the private key and the issuers up to the certificate authority- Throws:
KeyStoreException
- if the key pair could not be stored
-
deleteKey
Delete a key from the local keystore.- Parameters:
alias
- String name of the key- Throws:
KeyStoreException
- if the keystore can't be modifiedIOException
- if the altered keystore can't be checkpointed to the backing disk file
-
findMatchingKeys
Search the keystore for keys that match the destination addressee of the specified message.- Parameters:
callsign
- String callsign to be matched against the known keyskeyType
- KeyType of keys to be searched for, or null to search for all types- Returns:
- array of String names of keys that are associated with the specified callsign string (may be zero-length if no matches)
-
sign
public void sign(AprsSignableMessage mm, String alias) throws NullPointerException, IllegalStateException, IllegalArgumentException, GeneralSecurityException Sign a timestamped APRS message with the specified key.- Parameters:
mm
- MessageMessage to signalias
- String name of key to use for signature- Throws:
NullPointerException
- if keystore password hasn't been correctly set yetIllegalStateException
- if message has already been signedIllegalArgumentException
- if no such key for specified aliasGeneralSecurityException
- if key does not exist or signature algorithm doesn't work or isn't available
-
verify
public SignableMessage.SignatureState verify(AprsSignableMessage mm) throws GeneralSecurityException Verify the signature (if any) in an APRS message against the keys in the local keystore.- Parameters:
mm
- MessageMessage to verify- Returns:
- SignatureState of the message
- Throws:
GeneralSecurityException
- if key does not exist or signature algorithm doesn't work or isn't available
-
main
unit test.- Parameters:
args
- String array, [0] = password, [1] = alias to use for test- Throws:
Exception
- if test fails
-
chooseClientAlias
Choose an alias to authenticate the client side of a secure socket given the public key type and the list of certificate issuer authorities recognized by the peer (if any).- Specified by:
chooseClientAlias
in interfaceX509KeyManager
- Parameters:
keyTypes
- the key algorithm type name(s), ordered with the most-preferred key type first.principals
- the list of acceptable CA issuer subject names or null if it does not matter which issuers are used.socket
- he socket to be used for this connection. This parameter can be null, which indicates that implementations are free to select an alias applicable to any socket.- Returns:
- the alias name for the desired key, or null if there are no matches
-
getClientAliases
Get the matching aliases for authenticating the client side of a secure socket given the public key type and the list of certificate issuer authorities recognized by the peer (if any).- Specified by:
getClientAliases
in interfaceX509KeyManager
- Parameters:
algChoice
- the key algorithm type nameprincipals
- the list of acceptable CA issuer subject names, or null if it does not matter which issuers are used.- Returns:
- an array of the matching alias names, or null if there were no matches.
-
getServerAliases
Get the matching aliases for authenticating the server side of a secure socket given the public key type and the list of certificate issuer authorities recognized by the peer (if any).- Specified by:
getServerAliases
in interfaceX509KeyManager
- Parameters:
algChoice
- the key algorithm type nameprincipals
- the list of acceptable CA issuer subject names or null if it does not matter which issuers are used.- Returns:
- an array of the matching alias names, or null if there were no matches.
-
chooseServerAlias
Choose an alias to authenticate the server side of a secure socket given the public key type and the list of certificate issuer authorities recognized by the peer (if any).- Specified by:
chooseServerAlias
in interfaceX509KeyManager
- Parameters:
algChoice
- the key algorithm type name.principals
- the list of acceptable CA issuer subject names or null if it does not matter which issuers are used.socket
- the socket to be used for this connection. This parameter can be null, which indicates that implementations are free to select an alias applicable to any socket.- Returns:
- the alias name for the desired key, or null if there are no matches.
-
getCertificateChain
Returns the certificate chain associated with the given alias.- Specified by:
getCertificateChain
in interfaceX509KeyManager
- Parameters:
alias
- the alias name- Returns:
- the certificate chain (ordered with the user's certificate first and the root certificate authority last), or null if the alias can't be found.
-
getPrivateKey
Get the PrivateKey associated with the specified alias.- Specified by:
getPrivateKey
in interfaceX509KeyManager
- Parameters:
alias
- String name of key to look up- Returns:
- PrivateKey for the alias, or null if no such key
- Throws:
NullPointerException
- if the keystore has not been opened yet
-