Class Account

java.lang.Object
io.github.fherbreteau.vodozemac.NativeHandle
io.github.fherbreteau.vodozemac.account.Account
All Implemented Interfaces:
AutoCloseable

public final class Account extends NativeHandle
An Olm Account manages all cryptographic keys used on a device.

An account holds identity keys (Ed25519 for signing, Curve25519 for key agreement), one-time keys, and fallback keys. It is used to create Olm sessions for end-to-end encrypted communication with other devices.

This class implements AutoCloseable and should be used in a try-with-resources block to ensure native resources are properly released.

Author:
François HERBRETEAU
  • Constructor Details

    • Account

      public Account()
      Creates a new Account with new random identity keys.
  • Method Details

    • identityKeys

      public IdentityKeys identityKeys()
      Returns the identity keys of this account.
      Returns:
      the IdentityKeys containing both Ed25519 and Curve25519 public keys
      Throws:
      IllegalStateException - if this account has been closed
    • ed25519Key

      public Ed25519PublicKey ed25519Key()
      Returns the public Ed25519 key of this account.
      Returns:
      the Ed25519 public key
      Throws:
      IllegalStateException - if this account has been closed
    • curve25519Key

      public Curve25519PublicKey curve25519Key()
      Returns the public Curve25519 key of this account.
      Returns:
      the Curve25519 public key
      Throws:
      IllegalStateException - if this account has been closed
    • sign

      public Ed25519Signature sign(String message)
      Signs the given message using the Ed25519 fingerprint key.
      Parameters:
      message - the message to sign
      Returns:
      the signature
      Throws:
      IllegalStateException - if this account has been closed
    • sign

      public Ed25519Signature sign(byte[] message)
      Signs the given message using the Ed25519 fingerprint key.
      Parameters:
      message - the message to sign
      Returns:
      the signature
      Throws:
      IllegalStateException - if this account has been closed
    • maxNumberOfOneTimeKeys

      public long maxNumberOfOneTimeKeys()
      Returns the maximum number of one-time keys the client should keep on the server.
      Returns:
      the maximum number of one-time keys
      Throws:
      IllegalStateException - if this account has been closed
    • createOutboundSession

      public OlmSession createOutboundSession(Curve25519PublicKey identityKey, Curve25519PublicKey oneTimeKey)
      Creates an OlmSession with the given identity key and one-time key, using the default session version.
      Parameters:
      identityKey - the recipient's Curve25519 identity key
      oneTimeKey - the recipient's Curve25519 one-time key
      Returns:
      a new OlmSession
      Throws:
      IllegalStateException - if this account has been closed
      KeyException - if the keys cannot be decoded
      SessionCreationException - if session creation fails
    • createOutboundSession

      public OlmSession createOutboundSession(OlmSessionVersion sessionVersion, Curve25519PublicKey identityKey, Curve25519PublicKey oneTimeKey)
      Creates an OlmSession with the given identity key and one-time key.
      Parameters:
      sessionVersion - the Olm session protocol version to use
      identityKey - the recipient's Curve25519 identity key
      oneTimeKey - the recipient's Curve25519 one-time key
      Returns:
      a new OlmSession
      Throws:
      IllegalStateException - if this account has been closed
      KeyException - if the keys cannot be decoded
      SessionCreationException - if session creation fails
    • createInboundSession

      public InboundCreationResult createInboundSession(Curve25519PublicKey theirIdentityKey, OlmMessage preKeyMessage)
      Creates an inbound OlmSession from a pre-key message, using the default session version.
      Parameters:
      theirIdentityKey - the sender's Curve25519 identity key
      preKeyMessage - the OlmMessage received from the sender; must be a pre-key message
      Returns:
      an InboundCreationResult containing the new session and the decrypted plaintext of the pre-key message
      Throws:
      IllegalStateException - if this account has been closed
      KeyException - if the identity key cannot be decoded
      SessionCreationException - if session creation fails
    • createInboundSession

      public InboundCreationResult createInboundSession(OlmSessionVersion sessionVersion, Curve25519PublicKey theirIdentityKey, OlmMessage preKeyMessage)
      Creates an inbound OlmSession from a pre-key message.
      Parameters:
      sessionVersion - the Olm session protocol version to use
      theirIdentityKey - the sender's Curve25519 identity key
      preKeyMessage - the OlmMessage received from the sender; must be a pre-key message
      Returns:
      an InboundCreationResult containing the new session and the decrypted plaintext of the pre-key message
      Throws:
      IllegalStateException - if this account has been closed
      KeyException - if the identity key cannot be decoded
      SessionCreationException - if session creation fails
    • generateOneTimeKeys

      public OneTimeKeyGenerationResult generateOneTimeKeys(long count)
      Generates the supplied number of one-time keys.

      The one-time key store has a limited capacity. If new keys are generated while the store is full, the oldest keys are discarded.

      Parameters:
      count - the number of keys to generate
      Returns:
      a OneTimeKeyGenerationResult containing the created and discarded keys
      Throws:
      IllegalStateException - if this account has been closed
    • storedOneTimeKeyCount

      public long storedOneTimeKeyCount()
      Returns the number of one-time keys stored locally.

      This will be equal to or greater than the number of one-time keys that have been published. Each time a new session is created using createInboundSession(Curve25519PublicKey, OlmMessage), a one-time key is used and removed.

      Returns:
      the number of stored one-time keys
      Throws:
      IllegalStateException - if this account has been closed
    • unpublishedOneTimeKeys

      public Map<String, Curve25519PublicKey> unpublishedOneTimeKeys()
      Returns the currently unpublished one-time keys.

      The one-time keys should be published to a server and marked as published using markKeysAsPublished().

      Returns:
      a map of key ID to base64-encoded Curve25519 public key
      Throws:
      IllegalStateException - if this account has been closed
    • generateFallbackKey

      public Optional<Curve25519PublicKey> generateFallbackKey()
      Generates a single new fallback key.

      The fallback key will be used by other users to establish a session if all the one-time keys on the server have been used up.

      Returns:
      the public Curve25519 key of the previous fallback key, or an empty Optional if there was no previous key
      Throws:
      IllegalStateException - if this account has been closed
    • unpublishedFallbackKey

      public Map<String, Curve25519PublicKey> unpublishedFallbackKey()
      Returns the currently unpublished fallback key.

      The fallback key should be published just like the one-time keys, and marked as published using markKeysAsPublished().

      Returns:
      a map of key ID to base64-encoded Curve25519 public key
      Throws:
      IllegalStateException - if this account has been closed
    • forgetFallbackKey

      public boolean forgetFallbackKey()
      Forgets the previously used fallback key.

      The account stores at most two private parts of the fallback key. This method lets us forget the previously used one.

      Returns:
      true if the previous key was forgotten, false otherwise
      Throws:
      IllegalStateException - if this account has been closed
    • markKeysAsPublished

      public void markKeysAsPublished()
      Marks all currently unpublished one-time and fallback keys as published.
      Throws:
      IllegalStateException - if this account has been closed
    • pickle

      public String pickle()
      Converts the account into a JSON string representation.
      Returns:
      a JSON string representing the account
      Throws:
      IllegalStateException - if this account has been closed
    • pickle

      public String pickle(byte[] key)
      Encrypts the account using the given 32-byte key and returns the encrypted representation.
      Parameters:
      key - a 256-bit (32-byte) key for encrypting the account
      Returns:
      an encrypted string representation of the account
      Throws:
      IllegalStateException - if this account has been closed
      KeyException - if the key is not 32 bytes
    • pickleLegacy

      public String pickleLegacy(byte[] pickleKey)
      Converts the account into the libolm pickle format, encrypted with the given 32-byte key.

      This produces a binary pickle compatible with the original libolm library, useful for migrating away from libolm. The counterpart is unpickleLegacy(String, byte[]).

      Parameters:
      pickleKey - a 256-bit (32-byte) key for encrypting the pickle
      Returns:
      the libolm-format pickle string of the Account
      Throws:
      IllegalStateException - if this account has been closed
      KeyException - if the key is not 32 bytes
      PickleException - if the pickle could not be created
    • unpickle

      public static Account unpickle(String pickleData)
      Restores an Account from a previously saved JSON string.
      Parameters:
      pickleData - the JSON string from pickle()
      Returns:
      a restored Account
      Throws:
      PickleException - if the data cannot be deserialized
    • unpickle

      public static Account unpickle(String pickleData, byte[] key)
      Restores an Account from an encrypted string using a 32-byte key.
      Parameters:
      pickleData - the encrypted pickle data from pickle(byte[])
      key - a 256-bit (32-byte) key for decrypting the account
      Returns:
      a restored Account
      Throws:
      KeyException - if the key is not 32 bytes
      PickleException - if the data cannot be decrypted or deserialized
    • unpickleLegacy

      public static Account unpickleLegacy(String pickleData, byte[] pickleKey)
      Restores an Account from a legacy libolm pickle format. The pickle must be encrypted with the provided key.
      Parameters:
      pickleData - the libolm pickle data
      pickleKey - the key used to encrypt the pickle data
      Returns:
      a restored Account
      Throws:
      PickleException - if the data cannot be decrypted or deserialized
    • toDehydratedDevice

      public DehydratedDeviceResult toDehydratedDevice(byte[] key)
      Creates a dehydrated device from the account.

      A dehydrated device is a device that is stored encrypted on the server that can receive messages when the user has no other active devices. Upon login, the user can rehydrate the device (using fromDehydratedDevice(String, String, byte[])) and decrypt the messages sent to the dehydrated device.

      The account must be a newly-created account that does not have any Olm sessions, since the dehydrated device format does not store sessions.

      The format used is defined in MSC3814.

      Parameters:
      key - a 256-bit (32-byte) key for encrypting the device
      Returns:
      the ciphertext and nonce
      Throws:
      IllegalStateException - if this account has been closed
      KeyException - if the key is not 32 bytes
      PickleException - if creating the dehydrated device fails
    • fromDehydratedDevice

      public static Account fromDehydratedDevice(String ciphertext, String nonce, byte[] key)
      Creates an Account object from a dehydrated device.
      Parameters:
      ciphertext - the ciphertext generated by toDehydratedDevice(byte[])
      nonce - the nonce generated by toDehydratedDevice(byte[])
      key - a 256-bit (32-byte) key for decrypting the device
      Returns:
      a restored Account
      Throws:
      KeyException - if the key is not 32 bytes
      PickleException - if the dehydrated device cannot be decrypted