Package org.jivesoftware.smackx.ox
Class OpenPgpManager
- java.lang.Object
-
- org.jivesoftware.smack.Manager
-
- org.jivesoftware.smackx.ox.OpenPgpManager
-
public final class OpenPgpManager extends Manager
Entry point for Smacks API for OpenPGP for XMPP.Setup
In order to use OpenPGP for XMPP in Smack, just follow the following procedure.
First, acquire an instance of theOpenPgpManager
for yourXMPPConnection
usinggetInstanceFor(XMPPConnection)
.OpenPgpManager openPgpManager = OpenPgpManager.getInstanceFor(connection);
OpenPgpProvider
, as well as anOpenPgpStore
. The provider must be registered usingsetOpenPgpProvider(OpenPgpProvider)
.OpenPgpStore store = new FileBasedOpenPgpStore(storePath); OpenPgpProvider provider = new PainlessOpenPgpProvider(connection, store); openPgpManager.setOpenPgpProvider(provider);
SecretKeyRingProtector
usingOpenPgpStore.setKeyRingProtector(SecretKeyRingProtector)
in order to be able to handle password protected secret keys.
Speaking of keys, you can now check, if you have any keys available in yourOpenPgpStore
by doinghasSecretKeysAvailable()
.
If you do, you can now announce support for OX and publish those keys usingannounceSupportAndPublish()
.
Otherwise, you can either generate fresh keys usinggenerateAndImportKeyPair(BareJid)
, or try to restore a secret key backup from your private PubSub node by doingrestoreSecretKeyServerBackup(AskForBackupCodeCallback)
.
In any case you should still do anannounceSupportAndPublish()
afterwards.
Contacts are represented byOpenPgpContact
s in the context of OpenPGP for XMPP. You can get those by usinggetOpenPgpContact(EntityBareJid)
. The main function ofOpenPgpContact
s is to bundle information about the OpenPGP capabilities of a contact in one spot. The pendant to theOpenPgpContact
is theOpenPgpSelf
, which encapsulates your own OpenPGP identity. Both classes can be used to acquire information about the OpenPGP keys of a user.Elements
OpenPGP for XMPP defines multiple different element classes which contain the users messages. The outermost element is theOpenPgpElement
, which contains an OpenPGP encrypted content element. The content can be either aSignElement
,CryptElement
orSigncryptElement
, depending on the use-case. Those content elements contain the actual payload. If anOpenPgpElement
is decrypted, it will be returned in form of anOpenPgpMessage
, which represents the decrypted message + metadata.- See Also:
- XEP-0373: OpenPGP for XMPP
-
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description void
announceSupportAndPublish()
Generate a fresh OpenPGP key pair, given we don't have one already.OpenPgpSecretKeyBackupPassphrase
backupSecretKeyToServer(SecretKeyBackupSelectionCallback selectKeyCallback)
Upload the encrypted secret key to a private PEP node.void
backupSecretKeyToServer(SecretKeyBackupSelectionCallback selectKeyCallback, OpenPgpSecretKeyBackupPassphrase passphrase)
Upload the encrypted secret key to a private PEP node.OpenPgpMessage
decryptOpenPgpElement(OpenPgpElement element, OpenPgpContact sender)
Decrypt and or verify anOpenPgpElement
and return the decryptedOpenPgpMessage
.void
deleteSecretKeyServerBackup()
Delete the privateLeafNode
containing our secret key backup.org.pgpainless.key.OpenPgpV4Fingerprint
generateAndImportKeyPair(BareJid ourJid)
Generate a fresh OpenPGP key pair and import it.org.pgpainless.key.collection.PGPKeyRing
generateKeyRing(BareJid ourJid)
static OpenPgpManager
getInstanceFor(XMPPConnection connection)
Get the instance of theOpenPgpManager
which belongs to theconnection
.BareJid
getJidOrThrow()
Return our ownBareJid
.OpenPgpContact
getOpenPgpContact(EntityBareJid jid)
Return an OpenPGP capable contact.OpenPgpProvider
getOpenPgpProvider()
OpenPgpSelf
getOpenPgpSelf()
Get our OpenPGP self.org.pgpainless.key.OpenPgpV4Fingerprint
getOurFingerprint()
Return the upper-case hex encoded OpenPGP v4 fingerprint of our key pair.boolean
hasSecretKeysAvailable()
Return true, if we have a secret key available, otherwise false.void
registerSigncryptReceivedListener(SigncryptElementReceivedListener listener)
Register aSigncryptElementReceivedListener
on theOpenPgpManager
.org.pgpainless.key.OpenPgpV4Fingerprint
restoreSecretKeyServerBackup(AskForBackupCodeCallback codeCallback)
Fetch a secret key backup from the server and try to restore a selected secret key from it.static boolean
serverSupportsSecretKeyBackups(XMPPConnection connection)
Determine, if we can sync secret keys using private PEP nodes as described in the XEP.void
setOpenPgpProvider(OpenPgpProvider provider)
Set theOpenPgpProvider
which will be used to process incoming OpenPGP elements, as well as to execute cryptographic operations.void
stopMetadataListener()
Remove the metadata listener.-
Methods inherited from class org.jivesoftware.smack.Manager
connection, getAuthenticatedConnectionOrThrow, schedule, schedule, scheduleBlocking
-
-
-
-
Method Detail
-
getInstanceFor
public static OpenPgpManager getInstanceFor(XMPPConnection connection)
Get the instance of theOpenPgpManager
which belongs to theconnection
.- Parameters:
connection
- xmpp connection.- Returns:
- instance of the manager.
-
getJidOrThrow
public BareJid getJidOrThrow() throws SmackException.NotLoggedInException
Return our ownBareJid
.- Returns:
- our bareJid
- Throws:
SmackException.NotLoggedInException
- in case our connection is not logged in, which means our BareJid is unknown.
-
setOpenPgpProvider
public void setOpenPgpProvider(OpenPgpProvider provider)
Set theOpenPgpProvider
which will be used to process incoming OpenPGP elements, as well as to execute cryptographic operations.- Parameters:
provider
- OpenPgpProvider.
-
getOpenPgpProvider
public OpenPgpProvider getOpenPgpProvider()
-
getOpenPgpSelf
public OpenPgpSelf getOpenPgpSelf() throws SmackException.NotLoggedInException
Get our OpenPGP self.- Returns:
- self TODO javadoc me please
- Throws:
SmackException.NotLoggedInException
- if we are not logged in
-
announceSupportAndPublish
public void announceSupportAndPublish() throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.lang.InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException, java.io.IOException, java.security.InvalidAlgorithmParameterException, SmackException.NotLoggedInException, org.bouncycastle.openpgp.PGPException
Generate a fresh OpenPGP key pair, given we don't have one already. Publish the public key to the Public Key Node and update the Public Key Metadata Node with our keys fingerprint. Lastly register aPepListener
which listens for updates to Public Key Metadata Nodes.- Throws:
java.security.NoSuchAlgorithmException
- if we are missing an algorithm to generate a fresh key pair.java.security.NoSuchProviderException
- if we are missing a suitableProvider
.java.lang.InterruptedException
- if the thread gets interrupted.PubSubException.NotALeafNodeException
- if one of the PubSub nodes is not aLeafNode
.XMPPException.XMPPErrorException
- in case of an XMPP protocol error.SmackException.NotConnectedException
- if we are not connected.SmackException.NoResponseException
- if the server doesn't respond.java.io.IOException
- IO is dangerous.java.security.InvalidAlgorithmParameterException
- if illegal algorithm parameters are used for key generation.SmackException.NotLoggedInException
- if we are not logged in.org.bouncycastle.openpgp.PGPException
- if something goes wrong during key loading/generating
-
generateAndImportKeyPair
public org.pgpainless.key.OpenPgpV4Fingerprint generateAndImportKeyPair(BareJid ourJid) throws java.security.NoSuchAlgorithmException, java.security.InvalidAlgorithmParameterException, java.security.NoSuchProviderException, org.bouncycastle.openpgp.PGPException, java.io.IOException
Generate a fresh OpenPGP key pair and import it.- Parameters:
ourJid
- ourBareJid
.- Returns:
OpenPgpV4Fingerprint
of the generated key.- Throws:
java.security.NoSuchAlgorithmException
- if the JVM doesn't support one of the used algorithms.java.security.InvalidAlgorithmParameterException
- if the used algorithm parameters are invalid.java.security.NoSuchProviderException
- if we are missing a cryptographic provider.org.bouncycastle.openpgp.PGPException
- PGP is brittle.java.io.IOException
- IO is dangerous.
-
generateKeyRing
public org.pgpainless.key.collection.PGPKeyRing generateKeyRing(BareJid ourJid) throws org.bouncycastle.openpgp.PGPException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.InvalidAlgorithmParameterException
- Throws:
org.bouncycastle.openpgp.PGPException
java.security.NoSuchAlgorithmException
java.security.NoSuchProviderException
java.security.InvalidAlgorithmParameterException
-
getOurFingerprint
public org.pgpainless.key.OpenPgpV4Fingerprint getOurFingerprint() throws SmackException.NotLoggedInException, java.io.IOException, org.bouncycastle.openpgp.PGPException
Return the upper-case hex encoded OpenPGP v4 fingerprint of our key pair.- Returns:
- fingerprint.
- Throws:
SmackException.NotLoggedInException
- in case we are not logged in.java.io.IOException
- IO is dangerous.org.bouncycastle.openpgp.PGPException
- PGP is brittle.
-
getOpenPgpContact
public OpenPgpContact getOpenPgpContact(EntityBareJid jid)
Return an OpenPGP capable contact. This object can be used as an entry point to OpenPGP related API.- Parameters:
jid
-BareJid
of the contact.- Returns:
OpenPgpContact
.
-
hasSecretKeysAvailable
public boolean hasSecretKeysAvailable() throws SmackException.NotLoggedInException, org.bouncycastle.openpgp.PGPException, java.io.IOException
Return true, if we have a secret key available, otherwise false.- Returns:
- true if secret key available
- Throws:
SmackException.NotLoggedInException
- If we are not logged in (we need to know our jid in order to look up our keys in the key store.org.bouncycastle.openpgp.PGPException
- in case the keys in the store are damaged somehow.java.io.IOException
- IO is dangerous.
-
serverSupportsSecretKeyBackups
public static boolean serverSupportsSecretKeyBackups(XMPPConnection connection) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, java.lang.InterruptedException, SmackException.NoResponseException
Determine, if we can sync secret keys using private PEP nodes as described in the XEP. Requirements on the server side are support for PEP and support for the whitelist access model of PubSub.- Parameters:
connection
- XMPP connection- Returns:
- true, if the server supports secret key backups, otherwise false.
- Throws:
XMPPException.XMPPErrorException
- in case of an XMPP protocol error.SmackException.NotConnectedException
- if we are not connected.java.lang.InterruptedException
- if the thread is interrupted.SmackException.NoResponseException
- if the server doesn't respond.- See Also:
- XEP-0373 §5
-
stopMetadataListener
public void stopMetadataListener()
Remove the metadata listener. This method is mainly used in tests.
-
backupSecretKeyToServer
public OpenPgpSecretKeyBackupPassphrase backupSecretKeyToServer(SecretKeyBackupSelectionCallback selectKeyCallback) throws java.lang.InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException, SmackException.NotLoggedInException, java.io.IOException, SmackException.FeatureNotSupportedException, org.bouncycastle.openpgp.PGPException, MissingOpenPgpKeyException
Upload the encrypted secret key to a private PEP node.- Parameters:
selectKeyCallback
- callback, which will receive the users choice of which keys will be backed up.- Returns:
- secret key passphrase used to encrypt the backup.
- Throws:
java.lang.InterruptedException
- if the thread is interrupted.PubSubException.NotALeafNodeException
- if the private node is not aLeafNode
.XMPPException.XMPPErrorException
- in case of an XMPP protocol error.SmackException.NotConnectedException
- if we are not connected.SmackException.NoResponseException
- if the server doesn't respond.SmackException.NotLoggedInException
- if we are not logged in.java.io.IOException
- IO is dangerous.SmackException.FeatureNotSupportedException
- if the server doesn't support the PubSub whitelist access model.org.bouncycastle.openpgp.PGPException
- PGP is brittleMissingOpenPgpKeyException
- in case we have no OpenPGP key pair to back up.- See Also:
- XEP-0373 §5
-
backupSecretKeyToServer
public void backupSecretKeyToServer(SecretKeyBackupSelectionCallback selectKeyCallback, OpenPgpSecretKeyBackupPassphrase passphrase) throws java.lang.InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException, SmackException.NotLoggedInException, java.io.IOException, SmackException.FeatureNotSupportedException, org.bouncycastle.openpgp.PGPException, MissingOpenPgpKeyException
Upload the encrypted secret key to a private PEP node. The backup is encrypted using the provided secret key passphrase.- Parameters:
selectKeyCallback
- callback, which will receive the users choice of which keys will be backed up. @param selectKeyCallbackpassphrase
- secret key passphrase- Throws:
java.lang.InterruptedException
- if the thread is interrupted.PubSubException.NotALeafNodeException
- if the private node is not aLeafNode
.XMPPException.XMPPErrorException
- in case of an XMPP protocol error.SmackException.NotConnectedException
- if we are not connected.SmackException.NoResponseException
- if the server doesn't respond.SmackException.NotLoggedInException
- if we are not logged in.java.io.IOException
- IO is dangerous.SmackException.FeatureNotSupportedException
- if the server doesn't support the PubSub whitelist access model.org.bouncycastle.openpgp.PGPException
- PGP is brittleMissingOpenPgpKeyException
- in case we have no OpenPGP key pair to back up.- See Also:
- XEP-0373 §5
-
deleteSecretKeyServerBackup
public void deleteSecretKeyServerBackup() throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, java.lang.InterruptedException, SmackException.NoResponseException, SmackException.NotLoggedInException
Delete the privateLeafNode
containing our secret key backup.- Throws:
XMPPException.XMPPErrorException
- in case of an XMPP protocol error.SmackException.NotConnectedException
- if we are not connected.java.lang.InterruptedException
- if the thread gets interrupted.SmackException.NoResponseException
- if the server doesn't respond.SmackException.NotLoggedInException
- if we are not logged in.
-
restoreSecretKeyServerBackup
public org.pgpainless.key.OpenPgpV4Fingerprint restoreSecretKeyServerBackup(AskForBackupCodeCallback codeCallback) throws java.lang.InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException, InvalidBackupCodeException, SmackException.NotLoggedInException, java.io.IOException, MissingUserIdOnKeyException, NoBackupFoundException, org.bouncycastle.openpgp.PGPException
Fetch a secret key backup from the server and try to restore a selected secret key from it.- Parameters:
codeCallback
- callback for prompting the user to provide the secret backup code.- Returns:
- fingerprint of the restored secret key
- Throws:
java.lang.InterruptedException
- if the thread gets interrupted.PubSubException.NotALeafNodeException
- if the private node is not aLeafNode
.XMPPException.XMPPErrorException
- in case of an XMPP protocol error.SmackException.NotConnectedException
- if we are not connected.SmackException.NoResponseException
- if the server doesn't respond.InvalidBackupCodeException
- if the user-provided backup code is invalid.SmackException.NotLoggedInException
- if we are not logged injava.io.IOException
- IO is dangerousMissingUserIdOnKeyException
- if the key that is to be imported is missing a user-id with our jidNoBackupFoundException
- if no secret key backup has been foundorg.bouncycastle.openpgp.PGPException
- in case the restored secret key is damaged.
-
decryptOpenPgpElement
public OpenPgpMessage decryptOpenPgpElement(OpenPgpElement element, OpenPgpContact sender) throws SmackException.NotLoggedInException, java.io.IOException, org.bouncycastle.openpgp.PGPException
Decrypt and or verify anOpenPgpElement
and return the decryptedOpenPgpMessage
.- Parameters:
element
-OpenPgpElement
containing the message.sender
-OpenPgpContact
who sent the message.- Returns:
- decrypted and/or verified message
- Throws:
SmackException.NotLoggedInException
- in case we aren't logged in (we need to know our jid)java.io.IOException
- IO error (reading keys, streams etc)org.bouncycastle.openpgp.PGPException
- in case of an PGP error
-
registerSigncryptReceivedListener
public void registerSigncryptReceivedListener(SigncryptElementReceivedListener listener)
Register aSigncryptElementReceivedListener
on theOpenPgpManager
. That listener will get informed whenever aSigncryptElement
has been received and successfully decrypted. Note: This method is not intended for clients to listen for incomingSigncryptElement
s. Instead its purpose is to allow easy extension of XEP-0373 for custom OpenPGP profiles such as OpenPGP for XMPP: Instant Messaging.- Parameters:
listener
- listener that gets registered
-
-