Class ASYM_ENCRYPT

All Implemented Interfaces:
Lifecycle

public class ASYM_ENCRYPT extends Encrypt<KeyStore.PrivateKeyEntry>
Encrypts and decrypts communication in JGroups by using a secret key distributed to all cluster members by the key server (coordinator) using asymmetric (public/private key) encryption.
The secret key is identical for all cluster members and is used to encrypt messages when sending and decrypt them when receiving messages. This protocol is typically placed under NAKACK2.
The current keyserver (always the coordinator) generates a secret key. When a new member joins, it asks the keyserver for the secret key. The keyserver encrypts the secret key with the joiner's public key and the joiner decrypts it with its private key and then installs it and starts encrypting and decrypting messages with the secret key.
View changes that identify a new keyserver will result in a new secret key being generated and then distributed to all cluster members. This overhead can be substantial in an application with a reasonable member churn.
This protocol is suited for an application that does not ship with a known key but instead it is generated and distributed by the keyserver. Since messages can only get encrypted and decrypted when the secret key was received from the keyserver, messages are dropped when the secret key hasn't been installed yet.
  • Field Details

    • GMS_ID

      protected static final short GMS_ID
    • change_key_on_leave

      protected boolean change_key_on_leave
    • change_key_on_coord_leave

      protected boolean change_key_on_coord_leave
    • use_external_key_exchange

      protected boolean use_external_key_exchange
    • key_exchange

      protected KeyExchange key_exchange
    • key_server_addr

      protected volatile Address key_server_addr
    • send_group_keys

      protected volatile boolean send_group_keys
    • key_pair

      protected KeyPair key_pair
    • asym_cipher

      protected Cipher asym_cipher
    • pub_map

      protected final Map<Address,byte[]> pub_map
    • srv_addr

      protected static final ThreadLocal<Address> srv_addr
  • Constructor Details

    • ASYM_ENCRYPT

      public ASYM_ENCRYPT()
  • Method Details

    • setKeyStoreEntry

      public ASYM_ENCRYPT setKeyStoreEntry(KeyStore.PrivateKeyEntry entry)
      Description copied from class: Encrypt
      Sets the key store entry used to configure this protocol.
      Specified by:
      setKeyStoreEntry in class Encrypt<KeyStore.PrivateKeyEntry>
      Parameters:
      entry - a key store entry
    • getChangeKeyOnLeave

      public boolean getChangeKeyOnLeave()
    • setChangeKeyOnLeave

      public ASYM_ENCRYPT setChangeKeyOnLeave(boolean c)
    • getChangeKeyOnCoordLeave

      public boolean getChangeKeyOnCoordLeave()
    • setChangeKeyOnCoordLeave

      public ASYM_ENCRYPT setChangeKeyOnCoordLeave(boolean c)
    • getUseExternalKeyExchange

      public boolean getUseExternalKeyExchange()
    • setUseExternalKeyExchange

      public ASYM_ENCRYPT setUseExternalKeyExchange(boolean u)
    • keyPair

      public KeyPair keyPair()
    • asymCipher

      public Cipher asymCipher()
    • keyServerAddr

      public Address keyServerAddr()
    • keyServerAddr

      public ASYM_ENCRYPT keyServerAddr(Address ks)
    • providedDownServices

      public List<Integer> providedDownServices()
      Description copied from class: Protocol
      List of events that are provided to layers below (they will be handled when sent from down below)
      Overrides:
      providedDownServices in class Protocol
    • getPublicKeys

      public String getPublicKeys()
    • getKeyServerAddress

      public String getKeyServerAddress()
    • isKeyServer

      public boolean isKeyServer()
    • init

      public void init() throws Exception
      Description copied from class: Protocol
      Called after a protocol has been created and before the protocol is started. Attributes are already set. Other protocols are not yet connected and events cannot yet be sent.
      Specified by:
      init in interface Lifecycle
      Overrides:
      init in class Encrypt<KeyStore.PrivateKeyEntry>
      Throws:
      Exception - Thrown if protocol cannot be initialized successfully. This will cause the ProtocolStack to fail, so the the channel constructor will throw an exception
    • start

      public void start() throws Exception
      Description copied from class: Protocol
      This method is called on a JChannel.connect(String); starts work. Protocols are connected ready to receive events. Will be called from bottom to top.
      Specified by:
      start in interface Lifecycle
      Overrides:
      start in class Protocol
      Throws:
      Exception - Thrown if protocol cannot be started successfully. This will cause the ProtocolStack to fail, so JChannel.connect(String) will throw an exception
    • down

      public Object down(Event evt)
      Description copied from class: Protocol
      An event is to be sent down the stack. A protocol may want to examine its type and perform some action on it, depending on the event's type. If the event is a message MSG, then the protocol may need to add a header to it (or do nothing at all) before sending it down the stack using down_prot.down().
      Overrides:
      down in class Encrypt<KeyStore.PrivateKeyEntry>
    • down

      public Object down(Message msg)
      Description copied from class: Protocol
      A message is sent down the stack. Protocols may examine the message and do something (e.g. add a header) with it, before passing it down.
      Overrides:
      down in class Encrypt<KeyStore.PrivateKeyEntry>
    • up

      public Object up(Event evt)
      Description copied from class: Protocol
      An event was received from the protocol below. Usually the current protocol will want to examine the event type and - depending on its type - perform some computation (e.g. removing headers from a MSG event type, or updating the internal membership list when receiving a VIEW_CHANGE event). Finally, the event is either a) discarded, or b) an event is sent down the stack using down_prot.down() or c) the event (or another event) is sent up the stack using up_prot.up().
      Overrides:
      up in class Encrypt<KeyStore.PrivateKeyEntry>
    • up

      public Object up(Message msg)
      Description copied from class: Protocol
      A single message was received. Protocols may examine the message and do something (e.g. add a header) with it before passing it up.
      Overrides:
      up in class Encrypt<KeyStore.PrivateKeyEntry>
    • up

      public void up(MessageBatch batch)
      Description copied from class: Protocol
      Sends up a multiple messages in a MessageBatch. The sender of the batch is always the same, and so is the destination (null == multicast messages). Messages in a batch can be OOB messages, regular messages, or mixed messages, although the transport itself will create initial MessageBatches that contain only either OOB or regular messages.

      The default processing below sends messages up the stack individually, based on a matching criteria (calling Protocol.accept(Message)), and - if true - calls Protocol.up(org.jgroups.Event) for that message and removes the message. If the batch is not empty, it is passed up, or else it is dropped.

      Subclasses should check if there are any messages destined for them (e.g. using MessageBatch.iterator(Predicate)), then possibly remove and process them and finally pass the batch up to the next protocol. Protocols can also modify messages in place, e.g. ENCRYPT could decrypt all encrypted messages in the batch, not remove them, and pass the batch up when done.

      Overrides:
      up in class Encrypt<KeyStore.PrivateKeyEntry>
      Parameters:
      batch - The message batch
    • dropMulticastMessageFromNonMember

      protected boolean dropMulticastMessageFromNonMember(Message msg)
    • fetchAndSetKeyExchange

      public ASYM_ENCRYPT fetchAndSetKeyExchange()
    • cacheServerAddress

      protected static void cacheServerAddress(Address srv)
    • getCachedServerAddress

      protected static Address getCachedServerAddress()
    • skipDownMessage

      protected ASYM_ENCRYPT.Processing skipDownMessage(Message msg)
      Processes a message with a GMS header (e.g. by adding the secret key to a JOIN response) and returns true if the message should be passed down (not encrypted) or false if the message needs to be encrypted
      Returns:
      Processing ASYM_ENCRYPT.Processing.DROP if the message needs to be dropped, ASYM_ENCRYPT.Processing.SKIP if the message needs to be skipped (not encrypted), or ASYM_ENCRYPT.Processing.PROCESS if the message needs to be processed (= encrypted)
    • skipUpMessage

      protected boolean skipUpMessage(Message msg)
      Checks if the message contains a public key (and adds it to pub_map if present) or an encrypted group key (and installs it if present)
    • processEncryptMessage

      protected boolean processEncryptMessage(Message msg, EncryptHeader hdr, boolean retval)
    • installPublicKeys

      protected void installPublicKeys(Address sender, byte[] buf, int offset, int length)
    • addMetadata

      protected ASYM_ENCRYPT.Processing addMetadata(Message msg, boolean add_secret_keys, Address include_secret_key_only_for, boolean attach_fetch_key_header)
    • addKeysToMessage

      protected Message addKeysToMessage(Message msg, boolean copy, boolean add_secret_keys, Address serialize_only)
      Adds the public and/or encrypted shared keys to the payload of msg. If msg already has a payload, the message will be copied and the new payload consists of the keys and the original payload
      Parameters:
      msg - The original message
      Returns:
      A copy of the message
    • removeKeysFromMessageAndInstall

      protected void removeKeysFromMessageAndInstall(Message msg, byte[] version)
      Removes the public and/or private keys from the payload of msg and installs them. If there is some payload left (the original payload), the offset of the message will be changed. Otherwise, the payload will be nulled, to re-create the original message
    • serializeKeys

      protected void serializeKeys(ByteArrayDataOutputStream out, boolean serialize_shared_keys, Address serialize_only) throws Exception
      Serializes all public keys and their corresponding encrypted shared group keys into a buffer
      Throws:
      Exception
    • unserializeAndInstallKeys

      protected void unserializeAndInstallKeys(Address sender, byte[] version, ByteArrayDataInputStream in)
      Unserializes public keys and installs them to pub_map, then reads encrypted shared keys and install our own
    • serializeKeys

      protected static ByteArray serializeKeys(Map<Address,byte[]> keys) throws Exception
      Throws:
      Exception
    • unserializeKeys

      protected Map<Address,byte[]> unserializeKeys(Address sender, byte[] buf, int offset, int length)
    • createSecretKey

      protected SecretKey createSecretKey() throws Exception
      Initialise the symmetric key if none is supplied in a keystore
      Throws:
      Exception
    • initKeyPair

      protected void initKeyPair() throws Exception
      Generates the public/private key pair from the init params
      Throws:
      Exception
    • handleView

      protected void handleView(View v)
      Overrides:
      handleView in class Encrypt<KeyStore.PrivateKeyEntry>
    • createNewKey

      protected void createNewKey(String message)
    • installSharedGroupKey

      protected void installSharedGroupKey(Address sender, SecretKey key, byte[] version) throws Exception
      Throws:
      Exception
    • cacheGroupKey

      protected void cacheGroupKey(byte[] version) throws Exception
      Cache the current shared key to decrypt messages encrypted with the old shared group key
      Throws:
      Exception
    • encryptSecretKey

      protected byte[] encryptSecretKey(Key secret_key, PublicKey public_key) throws Exception
      Encrypts the current secret key with the requester's public key (the requester will decrypt it with its private key)
      Throws:
      Exception
    • decodeKey

      protected SecretKeySpec decodeKey(byte[] encodedKey) throws Exception
      Throws:
      Exception
    • makePublicKey

      protected PublicKey makePublicKey(byte[] encodedKey)
      Used to reconstitute public key sent in byte form from peer
    • getIv

      protected byte[] getIv(Message msg)