Class ASYM_ENCRYPT

  • All Implemented Interfaces:
    Lifecycle

    public class ASYM_ENCRYPT
    extends Encrypt<java.security.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.
    Author:
    Bela Ban, Steve Woodcock
    • Field Detail

      • 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_server_addr

        protected volatile Address key_server_addr
      • send_group_keys

        protected volatile boolean send_group_keys
      • key_pair

        protected java.security.KeyPair key_pair
      • asym_cipher

        protected javax.crypto.Cipher asym_cipher
      • pub_map

        protected final java.util.Map<Address,​byte[]> pub_map
      • srv_addr

        protected static final java.lang.ThreadLocal<Address> srv_addr
    • Constructor Detail

      • ASYM_ENCRYPT

        public ASYM_ENCRYPT()
    • Method Detail

      • setKeyStoreEntry

        public ASYM_ENCRYPT setKeyStoreEntry​(java.security.KeyStore.PrivateKeyEntry entry)
        Description copied from class: Encrypt
        Sets the key store entry used to configure this protocol.
        Specified by:
        setKeyStoreEntry in class Encrypt<java.security.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 java.security.KeyPair keyPair()
      • asymCipher

        public javax.crypto.Cipher asymCipher()
      • keyServerAddr

        public Address keyServerAddr()
      • providedDownServices

        public java.util.List<java.lang.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 java.lang.String getPublicKeys()
      • getKeyServerAddress

        public java.lang.String getKeyServerAddress()
      • isKeyServer

        public boolean isKeyServer()
      • init

        public void init()
                  throws java.lang.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<java.security.KeyStore.PrivateKeyEntry>
        Throws:
        java.lang.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 java.lang.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:
        java.lang.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 java.lang.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<java.security.KeyStore.PrivateKeyEntry>
      • down

        public java.lang.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<java.security.KeyStore.PrivateKeyEntry>
      • up

        public java.lang.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<java.security.KeyStore.PrivateKeyEntry>
      • up

        public java.lang.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<java.security.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<java.security.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()
      • 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)
      • 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 java.lang.Exception
        Serializes all public keys and their corresponding encrypted shared group keys into a buffer
        Throws:
        java.lang.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​(java.util.Map<Address,​byte[]> keys)
                                          throws java.lang.Exception
        Throws:
        java.lang.Exception
      • unserializeKeys

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

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

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

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

        protected void createNewKey​(java.lang.String message)
      • installSharedGroupKey

        protected void installSharedGroupKey​(Address sender,
                                             javax.crypto.SecretKey key,
                                             byte[] version)
                                      throws java.lang.Exception
        Throws:
        java.lang.Exception
      • cacheGroupKey

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

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

        protected javax.crypto.spec.SecretKeySpec decodeKey​(byte[] encodedKey)
                                                     throws java.lang.Exception
        Throws:
        java.lang.Exception
      • makePublicKey

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

        protected byte[] getIv​(Message msg)