You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by bs...@apache.org on 2018/01/31 00:18:45 UTC

[geode] branch feature/GEODE-4439 created (now fbefe7d)

This is an automated email from the ASF dual-hosted git repository.

bschuchardt pushed a change to branch feature/GEODE-4439
in repository https://gitbox.apache.org/repos/asf/geode.git.


      at fbefe7d  wip - tests are failing

This branch includes the following new commits:

     new ed20f214 GEODE-4439 Refactor HandShake.java
     new 4cd5b90  checkpoint - readMessage refactoring
     new fbefe7d  wip - tests are failing

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
bschuchardt@apache.org.

[geode] 03/03: wip - tests are failing

Posted by bs...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

bschuchardt pushed a commit to branch feature/GEODE-4439
in repository https://gitbox.apache.org/repos/asf/geode.git

commit fbefe7d7ca484cca781fff1b953d23d69a763b7d
Author: Bruce Schuchardt <bs...@pivotal.io>
AuthorDate: Tue Jan 30 15:56:43 2018 -0800

    wip - tests are failing
---
 .../client/internal/ClientSideHandshakeImpl.java   |  4 +++-
 .../internal/cache/tier/ClientSideHandshake.java   |  2 +-
 .../internal/cache/tier/ServerSideHandshake.java   |  2 +-
 .../internal/cache/tier/sockets/EncryptorImpl.java | 28 ++++++----------------
 .../internal/cache/tier/sockets/Handshake.java     | 20 +++++++++++++++-
 .../cache/tier/sockets/ServerConnection.java       | 10 ++++----
 .../tier/sockets/ServerSideHandshakeImpl.java      |  3 ++-
 .../cache/tier/sockets/ServerConnectionTest.java   |  2 +-
 8 files changed, 39 insertions(+), 32 deletions(-)

diff --git a/geode-core/src/main/java/org/apache/geode/cache/client/internal/ClientSideHandshakeImpl.java b/geode-core/src/main/java/org/apache/geode/cache/client/internal/ClientSideHandshakeImpl.java
index ea2a80a..8db79a3 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/client/internal/ClientSideHandshakeImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/client/internal/ClientSideHandshakeImpl.java
@@ -57,6 +57,7 @@ import org.apache.geode.internal.cache.tier.ClientSideHandshake;
 import org.apache.geode.internal.cache.tier.CommunicationMode;
 import org.apache.geode.internal.cache.tier.Encryptor;
 import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID;
+import org.apache.geode.internal.cache.tier.sockets.EncryptorImpl;
 import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.cache.tier.sockets.ServerQueueStatus;
 import org.apache.geode.internal.i18n.LocalizedStrings;
@@ -98,6 +99,7 @@ public class ClientSideHandshakeImpl extends Handshake implements ClientSideHand
     this.replyCode = REPLY_OK;
     setOverrides();
     this.credentials = null;
+    this.encryptor = new EncryptorImpl(distributedSystem.getSecurityLogWriter());
   }
 
   /**
@@ -454,6 +456,6 @@ public class ClientSideHandshakeImpl extends Handshake implements ClientSideHand
    * @return
    */
   public Encryptor getEncryptor() {
-    return this;
+    return encryptor;
   }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ClientSideHandshake.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ClientSideHandshake.java
index c472fcd..14877b4 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ClientSideHandshake.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ClientSideHandshake.java
@@ -25,7 +25,7 @@ import org.apache.geode.internal.cache.tier.sockets.ServerQueueStatus;
 import org.apache.geode.security.AuthenticationFailedException;
 import org.apache.geode.security.AuthenticationRequiredException;
 
-public interface ClientSideHandshake extends Encryptor {
+public interface ClientSideHandshake {
   Encryptor getEncryptor();
 
   ClientProxyMembershipID getMembershipId();
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ServerSideHandshake.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ServerSideHandshake.java
index f382609..ce8aa8f 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ServerSideHandshake.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ServerSideHandshake.java
@@ -27,7 +27,7 @@ import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID;
  * <code>ClientHandShake</code> represents a handshake from the client.
  *
  */
-public interface ServerSideHandshake extends Encryptor {
+public interface ServerSideHandshake {
   boolean isOK();
 
   ClientProxyMembershipID getMembershipId();
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/EncryptorImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/EncryptorImpl.java
index c6e73bf..323c09f 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/EncryptorImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/EncryptorImpl.java
@@ -130,7 +130,7 @@ public class EncryptorImpl implements Encryptor{
     this.appSecureMode = encryptor.appSecureMode;
   }
 
-  EncryptorImpl(LogWriter logWriter) {
+  public EncryptorImpl(LogWriter logWriter) {
     this.logWriter = logWriter;
   }
 
@@ -384,15 +384,7 @@ public class EncryptorImpl implements Encryptor{
 
       // Expect the alias and signature in the reply
       acceptanceCode = dis.readByte();
-      if (acceptanceCode != REPLY_OK && acceptanceCode != REPLY_AUTH_NOT_REQUIRED) {
-        // Ignore the useless data
-        dis.readByte();
-        dis.readInt();
-        if (!isNotification) {
-          DataSerializer.readByteArray(dis);
-        }
-        readMessage(dis, dos, acceptanceCode, member);
-      } else if (acceptanceCode == REPLY_OK) {
+      if (acceptanceCode == REPLY_OK) {
         // Get the public key of the other side
         keyBytes = DataSerializer.readByteArray(dis);
         if (requireAuthentication) {
@@ -448,10 +440,11 @@ public class EncryptorImpl implements Encryptor{
     return acceptanceCode;
   }
 
-  void writeEncryptedCredentials(DataOutputStream dos, DataInputStream dis,
+  byte writeEncryptedCredentials(DataOutputStream dos, DataInputStream dis,
                                  Properties p_credentials,
                                  boolean isNotification, DistributedMember member,
                                  HeapDataOutputStream heapdos) throws IOException {
+    byte acceptanceCode;
     try {
       logWriter.fine("HandShake: using Diffie-Hellman key exchange with algo " + dhSKAlgo);
       boolean requireAuthentication =
@@ -481,16 +474,8 @@ public class EncryptorImpl implements Encryptor{
       dos.flush();
 
       // Expect the alias and signature in the reply
-      byte acceptanceCode = dis.readByte();
-      if (acceptanceCode != REPLY_OK && acceptanceCode != REPLY_AUTH_NOT_REQUIRED) {
-        // Ignore the useless data
-        dis.readByte();
-        dis.readInt();
-        if (!isNotification) {
-          DataSerializer.readByteArray(dis);
-        }
-        readMessage(dis, dos, acceptanceCode, member);
-      } else if (acceptanceCode == REPLY_OK) {
+      acceptanceCode = dis.readByte();
+      if (acceptanceCode == REPLY_OK) {
         // Get the public key of the other side
         keyBytes = DataSerializer.readByteArray(dis);
         if (requireAuthentication) {
@@ -546,6 +531,7 @@ public class EncryptorImpl implements Encryptor{
       throw new AuthenticationFailedException("HandShake failed in Diffie-Hellman key exchange",
           ex);
     }
+    return acceptanceCode;
   }
 
   void readEncryptedCredentials(DataInputStream dis, DataOutputStream dos,
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/Handshake.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/Handshake.java
index 37412c4..e76ef7f 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/Handshake.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/Handshake.java
@@ -205,6 +205,15 @@ public abstract class Handshake {
     }
     byte acceptanceCode = -1;
     acceptanceCode = encryptor.writeEncryptedCredential(dos, dis, isNotification, member, heapdos);
+    if (acceptanceCode != REPLY_OK && acceptanceCode != REPLY_AUTH_NOT_REQUIRED) {
+      // Ignore the useless data
+      dis.readByte();
+      dis.readInt();
+      if (!isNotification) {
+        DataSerializer.readByteArray(dis);
+      }
+      readMessage(dis, dos, acceptanceCode, member);
+    }
     dos.flush();
     return acceptanceCode;
   }
@@ -246,7 +255,16 @@ public abstract class Handshake {
       return;
     }
 
-    encryptor.writeEncryptedCredentials(dos, dis, p_credentials, isNotification, member, heapdos);
+    byte acceptanceCode = encryptor.writeEncryptedCredentials(dos, dis, p_credentials, isNotification, member, heapdos);
+    if (acceptanceCode != REPLY_OK && acceptanceCode != REPLY_AUTH_NOT_REQUIRED) {
+      // Ignore the useless data
+      dis.readByte();
+      dis.readInt();
+      if (!isNotification) {
+        DataSerializer.readByteArray(dis);
+      }
+      readMessage(dis, dos, acceptanceCode, member);
+    }
     dos.flush();
   }
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerConnection.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerConnection.java
index 4e86396..56b18a0 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerConnection.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerConnection.java
@@ -620,7 +620,7 @@ public abstract class ServerConnection implements Runnable {
       try {
         byte[] secureBytes = this.requestMsg.getSecureBytes();
 
-        secureBytes = ((Handshake) this.handshake).decryptBytes(secureBytes);
+        secureBytes = this.handshake.getEncryptor().decryptBytes(secureBytes);
         AuthIds aIds = new AuthIds(secureBytes);
 
         long uniqueId = aIds.getUniqueId();
@@ -951,7 +951,7 @@ public abstract class ServerConnection implements Runnable {
     try {
       byte[] secureBytes = msg.getSecureBytes();
 
-      secureBytes = ((Handshake) this.handshake).decryptBytes(secureBytes);
+      secureBytes = this.handshake.getEncryptor().decryptBytes(secureBytes);
 
       // need to decrypt it first then get connectionid
       AuthIds aIds = new AuthIds(secureBytes);
@@ -1013,7 +1013,7 @@ public abstract class ServerConnection implements Runnable {
 
       byte[] secureBytes = msg.getSecureBytes();
 
-      secureBytes = ((Handshake) this.handshake).decryptBytes(secureBytes);
+      secureBytes = this.handshake.getEncryptor().decryptBytes(secureBytes);
 
       // need to decrypt it first then get connectionid
       AuthIds aIds = new AuthIds(secureBytes);
@@ -1026,7 +1026,7 @@ public abstract class ServerConnection implements Runnable {
 
       byte[] credBytes = msg.getPart(0).getSerializedForm();
 
-      credBytes = ((Handshake) this.handshake).decryptBytes(credBytes);
+      credBytes = this.handshake.getEncryptor().decryptBytes(credBytes);
 
       ByteArrayInputStream bis = new ByteArrayInputStream(credBytes);
       DataInputStream dinp = new DataInputStream(bis);
@@ -1727,7 +1727,7 @@ public abstract class ServerConnection implements Runnable {
 
       hdos.writeLong(id);
 
-      return ((Handshake) this.handshake).encryptBytes(hdos.toByteArray());
+      return this.handshake.getEncryptor().encryptBytes(hdos.toByteArray());
     } finally {
       hdos.close();
     }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerSideHandshakeImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerSideHandshakeImpl.java
index 8d2f77a..dea11e7 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerSideHandshakeImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerSideHandshakeImpl.java
@@ -51,6 +51,7 @@ public class ServerSideHandshakeImpl extends Handshake implements ServerSideHand
     this.clientVersion = clientVersion;
     this.system = sys;
     this.securityService = securityService;
+    this.encryptor = new EncryptorImpl(sys.getSecurityLogWriter());
 
     {
       int soTimeout = -1;
@@ -185,7 +186,7 @@ public class ServerSideHandshakeImpl extends Handshake implements ServerSideHand
 
   @Override
   public Encryptor getEncryptor() {
-    return this;
+    return encryptor;
   }
 
   private void sendCredentialsForWan(OutputStream out, InputStream in) {
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ServerConnectionTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ServerConnectionTest.java
index d5f8baf..fa08df8 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ServerConnectionTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ServerConnectionTest.java
@@ -231,7 +231,7 @@ public class ServerConnectionTest {
 
       long fakeId = -1;
       MessageIdExtractor extractor = mock(MessageIdExtractor.class);
-      when(extractor.getUniqueIdFromMessage(getRequestMessage(), handshake,
+      when(extractor.getUniqueIdFromMessage(getRequestMessage(), handshake.getEncryptor(),
           Connection.DEFAULT_CONNECTION_ID)).thenReturn(fakeId);
       setMessageIdExtractor(extractor);
     }

-- 
To stop receiving notification emails like this one, please contact
bschuchardt@apache.org.

[geode] 01/03: GEODE-4439 Refactor HandShake.java

Posted by bs...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

bschuchardt pushed a commit to branch feature/GEODE-4439
in repository https://gitbox.apache.org/repos/asf/geode.git

commit ed20f21477c0a45df069305e9b4ebd7c32582990
Author: Bruce Schuchardt <bs...@pivotal.io>
AuthorDate: Tue Jan 30 11:29:39 2018 -0800

    GEODE-4439 Refactor HandShake.java
    
    Created ServerSideHandshake and ServerSideHandshakeImpl for servers.
    
    Created ClientSideHandshake and ClientSideHandshakeImpl for clients.
    
    Message encryption/decryption is now in an Encryptor interface.
    
    HandShake is renamed Handshake.
---
 .../geode/cache/client/internal/AbstractOp.java    |   5 +-
 .../cache/client/internal/AuthenticateUserOp.java  |  15 +-
 .../client/internal/ClientSideHandshakeImpl.java   | 459 +++++++++++++
 .../client/internal/ConnectionFactoryImpl.java     |  53 +-
 .../cache/client/internal/ConnectionImpl.java      |  24 +-
 .../cache/client/internal/ProxyCacheCloseOp.java   |   2 +-
 .../internal/InternalDistributedSystem.java        |   8 +-
 .../membership/gms/auth/GMSAuthenticator.java      |   4 +-
 .../distributed/internal/tcpserver/TcpServer.java  |   5 +-
 .../apache/geode/internal/cache/LocalRegion.java   |   4 +-
 .../geode/internal/cache/ha/HARegionQueue.java     |  24 +-
 .../apache/geode/internal/cache/properties.html    |   4 +-
 .../internal/cache/tier/ClientSideHandshake.java   |  40 ++
 .../tier/{ClientHandShake.java => Encryptor.java}  |  28 +-
 ...ientHandShake.java => ServerSideHandshake.java} |  18 +-
 .../internal/cache/tier/sockets/AcceptorImpl.java  |  10 +-
 .../cache/tier/sockets/CacheClientNotifier.java    |  32 +-
 .../cache/tier/sockets/CacheClientProxy.java       |   4 +-
 .../cache/tier/sockets/CacheClientUpdater.java     |  11 +-
 .../tier/sockets/ClientUpdateMessageImpl.java      |   6 +-
 .../sockets/{HandShake.java => Handshake.java}     | 750 +++------------------
 .../cache/tier/sockets/MessageIdExtractor.java     |   6 +-
 .../cache/tier/sockets/ServerConnection.java       |  54 +-
 ...rocessor.java => ServerHandshakeProcessor.java} |  77 +--
 .../tier/sockets/ServerSideHandshakeImpl.java      | 209 ++++++
 .../tier/sockets/command/ExecuteFunction.java      |  12 +-
 .../tier/sockets/command/ExecuteFunction65.java    |  11 +-
 .../tier/sockets/command/ExecuteFunction66.java    |  10 +-
 .../sockets/command/ExecuteRegionFunction.java     |  11 +-
 .../sockets/command/ExecuteRegionFunction61.java   |  11 +-
 .../sockets/command/ExecuteRegionFunction65.java   |  11 +-
 .../sockets/command/ExecuteRegionFunction66.java   |  11 +-
 .../command/ExecuteRegionFunctionSingleHop.java    |  11 +-
 .../geode/internal/i18n/LocalizedStrings.java      |   2 -
 .../org/apache/geode/internal/tcp/Connection.java  |  12 +-
 .../ClientFunctionTimeoutRegressionTest.java       |   4 +-
 ...dCompatibilityHigherVersionClientDUnitTest.java |   5 +-
 .../{HandShakeTest.java => HandshakeTest.java}     |  10 +-
 .../cache/tier/sockets/MessageIdExtractorTest.java |   9 +-
 .../cache/tier/sockets/ServerConnectionTest.java   |  16 +-
 .../sockets/command/ExecuteFunction65Test.java     |   5 +-
 .../sockets/command/ExecuteFunction66Test.java     |   5 +-
 .../tier/sockets/command/ExecuteFunctionTest.java  |   7 +-
 .../generator/LdapUserCredentialGenerator.java     |  20 +-
 44 files changed, 1048 insertions(+), 987 deletions(-)

diff --git a/geode-core/src/main/java/org/apache/geode/cache/client/internal/AbstractOp.java b/geode-core/src/main/java/org/apache/geode/cache/client/internal/AbstractOp.java
index 3e95158..4eedff0 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/client/internal/AbstractOp.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/client/internal/AbstractOp.java
@@ -130,8 +130,7 @@ public abstract class AbstractOp implements Op {
       try {
         hdos.writeLong(cnx.getConnectionID());
         hdos.writeLong(userId);
-        getMessage()
-            .setSecurePart(((ConnectionImpl) cnx).getHandShake().encryptBytes(hdos.toByteArray()));
+        getMessage().setSecurePart(((ConnectionImpl) cnx).encryptBytes(hdos.toByteArray()));
       } finally {
         hdos.close();
       }
@@ -162,7 +161,7 @@ public abstract class AbstractOp implements Op {
         }
         return;
       }
-      byte[] bytes = ((ConnectionImpl) cnx).getHandShake().decryptBytes(partBytes);
+      byte[] bytes = ((ConnectionImpl) cnx).decryptBytes(partBytes);
       DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
       cnx.setConnectionID(dis.readLong());
     }
diff --git a/geode-core/src/main/java/org/apache/geode/cache/client/internal/AuthenticateUserOp.java b/geode-core/src/main/java/org/apache/geode/cache/client/internal/AuthenticateUserOp.java
index f4a93e2..7f3a778 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/client/internal/AuthenticateUserOp.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/client/internal/AuthenticateUserOp.java
@@ -35,7 +35,7 @@ import org.apache.geode.internal.HeapDataOutputStream;
 import org.apache.geode.internal.Version;
 import org.apache.geode.internal.cache.tier.MessageType;
 import org.apache.geode.internal.cache.tier.sockets.ChunkedMessage;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.cache.tier.sockets.Message;
 import org.apache.geode.internal.cache.tier.sockets.Part;
 import org.apache.geode.internal.cache.tier.sockets.command.PutUserCredentials;
@@ -107,7 +107,7 @@ public class AuthenticateUserOp {
       Properties tmpSecurityProperties = sys.getSecurityProperties();
 
       // LOG: following passes the DS API LogWriters into the security API
-      Properties credentials = HandShake.getCredentials(authInitMethod, tmpSecurityProperties,
+      Properties credentials = Handshake.getCredentials(authInitMethod, tmpSecurityProperties,
           server, false, (InternalLogWriter) sys.getLogWriter(),
           (InternalLogWriter) sys.getSecurityLogWriter());
 
@@ -115,7 +115,7 @@ public class AuthenticateUserOp {
       HeapDataOutputStream heapdos = new HeapDataOutputStream(Version.CURRENT);
       try {
         DataSerializer.writeProperties(credentials, heapdos);
-        credentialBytes = ((ConnectionImpl) con).getHandShake().encryptBytes(heapdos.toByteArray());
+        credentialBytes = ((ConnectionImpl) con).encryptBytes(heapdos.toByteArray());
       } catch (Exception e) {
         throw new ServerOperationException(e);
       } finally {
@@ -149,21 +149,20 @@ public class AuthenticateUserOp {
         DistributedSystem sys = InternalDistributedSystem.getConnectedInstance();
         String authInitMethod = sys.getProperties().getProperty(SECURITY_CLIENT_AUTH_INIT);
 
-        Properties credentials = HandShake.getCredentials(authInitMethod, this.securityProperties,
+        Properties credentials = Handshake.getCredentials(authInitMethod, this.securityProperties,
             server, false, (InternalLogWriter) sys.getLogWriter(),
             (InternalLogWriter) sys.getSecurityLogWriter());
         HeapDataOutputStream heapdos = new HeapDataOutputStream(Version.CURRENT);
         try {
           DataSerializer.writeProperties(credentials, heapdos);
-          credentialBytes =
-              ((ConnectionImpl) cnx).getHandShake().encryptBytes(heapdos.toByteArray());
+          credentialBytes = ((ConnectionImpl) cnx).encryptBytes(heapdos.toByteArray());
         } finally {
           heapdos.close();
         }
         getMessage().addBytesPart(credentialBytes);
       }
       try {
-        secureBytes = ((ConnectionImpl) cnx).getHandShake().encryptBytes(hdos.toByteArray());
+        secureBytes = ((ConnectionImpl) cnx).encryptBytes(hdos.toByteArray());
       } finally {
         hdos.close();
       }
@@ -218,7 +217,7 @@ public class AuthenticateUserOp {
           cnx.getServer().setRequiresCredentials(false);
         } else {
           cnx.getServer().setRequiresCredentials(true);
-          byte[] decrypted = ((ConnectionImpl) cnx).getHandShake().decryptBytes(bytes);
+          byte[] decrypted = ((ConnectionImpl) cnx).decryptBytes(bytes);
           DataInputStream dis = new DataInputStream(new ByteArrayInputStream(decrypted));
           userId = dis.readLong();
         }
diff --git a/geode-core/src/main/java/org/apache/geode/cache/client/internal/ClientSideHandshakeImpl.java b/geode-core/src/main/java/org/apache/geode/cache/client/internal/ClientSideHandshakeImpl.java
new file mode 100644
index 0000000..ea2a80a
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/cache/client/internal/ClientSideHandshakeImpl.java
@@ -0,0 +1,459 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.geode.cache.client.internal;
+
+import static org.apache.geode.distributed.ConfigurationProperties.CONFLATE_EVENTS;
+import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_CLIENT_AUTH_INIT;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.net.ssl.SSLSocket;
+
+import org.apache.geode.CancelCriterion;
+import org.apache.geode.DataSerializer;
+import org.apache.geode.GemFireConfigException;
+import org.apache.geode.InternalGemFireException;
+import org.apache.geode.cache.GatewayConfigurationException;
+import org.apache.geode.cache.client.ServerRefusedConnectionException;
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.distributed.internal.DistributionManager;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.distributed.internal.LonerDistributionManager;
+import org.apache.geode.distributed.internal.ServerLocation;
+import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
+import org.apache.geode.internal.HeapDataOutputStream;
+import org.apache.geode.internal.InternalDataSerializer;
+import org.apache.geode.internal.InternalInstantiator;
+import org.apache.geode.internal.Version;
+import org.apache.geode.internal.VersionedDataInputStream;
+import org.apache.geode.internal.VersionedDataOutputStream;
+import org.apache.geode.internal.cache.tier.ClientSideHandshake;
+import org.apache.geode.internal.cache.tier.CommunicationMode;
+import org.apache.geode.internal.cache.tier.Encryptor;
+import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
+import org.apache.geode.internal.cache.tier.sockets.ServerQueueStatus;
+import org.apache.geode.internal.i18n.LocalizedStrings;
+import org.apache.geode.internal.security.SecurityService;
+import org.apache.geode.security.AuthenticationFailedException;
+import org.apache.geode.security.AuthenticationRequiredException;
+import org.apache.geode.security.GemFireSecurityException;
+
+public class ClientSideHandshakeImpl extends Handshake implements ClientSideHandshake {
+  /**
+   * Used at client side, indicates whether the 'delta-propagation' property is enabled on the DS
+   * this client is connected to. This variable is used to decide whether to send delta bytes or
+   * full value to the server for a delta-update operation.
+   */
+  protected static boolean deltaEnabledOnServer = true;
+
+  /**
+   * If true, the client has configured multi-user security, meaning that each thread holds its own
+   * security principal.
+   */
+  private final boolean multiuserSecureMode;
+
+  /**
+   * Another test hook, holding a version ordinal that is higher than CURRENT
+   */
+  private static short overrideClientVersion = -1;
+
+  public static boolean isDeltaEnabledOnServer() {
+    return deltaEnabledOnServer;
+  }
+
+  public ClientSideHandshakeImpl(ClientProxyMembershipID proxyId,
+      InternalDistributedSystem distributedSystem, SecurityService securityService,
+      boolean multiuserSecureMode) {
+    this.multiuserSecureMode = multiuserSecureMode;
+    this.id = proxyId;
+    this.system = distributedSystem;
+    this.securityService = securityService;
+    this.replyCode = REPLY_OK;
+    setOverrides();
+    this.credentials = null;
+  }
+
+  /**
+   * Clone a HandShake to be used in creating other connections
+   */
+  public ClientSideHandshakeImpl(ClientSideHandshakeImpl handshake) {
+    super(handshake);
+    this.multiuserSecureMode = handshake.multiuserSecureMode;
+  }
+
+  public static void setVersionForTesting(short ver) {
+    if (ver > Version.CURRENT_ORDINAL) {
+      overrideClientVersion = ver;
+    } else {
+      currentClientVersion = Version.fromOrdinalOrCurrent(ver);
+      overrideClientVersion = -1;
+    }
+  }
+
+  // used by the client side
+  private void setOverrides() {
+    this.clientConflation = determineClientConflation();
+
+    // As of May 2009 ( GFE 6.0 ):
+    // Note that this.clientVersion is used by server side for accepting
+    // handshakes.
+    // Client side handshake code uses this.currentClientVersion which can be
+    // set via tests.
+    if (currentClientVersion.compareTo(Version.GFE_603) >= 0) {
+      byte override = 0;
+      /*
+       * override = this.notifyBySubscriptionOverride; override = (byte)((override << 2) |
+       * this.removeUnresponsiveClientOverride); override = (byte)((override << 2) |
+       * this.clientConflation);
+       */
+      override = this.clientConflation;
+      setOverrides(new byte[] {override});
+    }
+  }
+
+  // used by the client side
+  private byte determineClientConflation() {
+    byte result = CONFLATION_DEFAULT;
+
+    String clientConflationValue = this.system.getProperties().getProperty(CONFLATE_EVENTS);
+    if (DistributionConfig.CLIENT_CONFLATION_PROP_VALUE_ON
+        .equalsIgnoreCase(clientConflationValue)) {
+      result = CONFLATION_ON;
+    } else if (DistributionConfig.CLIENT_CONFLATION_PROP_VALUE_OFF
+        .equalsIgnoreCase(clientConflationValue)) {
+      result = CONFLATION_OFF;
+    }
+    return result;
+  }
+
+
+  /**
+   * Return fake, temporary DistributedMember to represent the other vm this vm is connecting to
+   *
+   * @param sock the socket this handshake is operating on
+   * @return temporary id to reprent the other vm
+   */
+  private DistributedMember getIDForSocket(Socket sock) {
+    return new InternalDistributedMember(sock.getInetAddress(), sock.getPort(), false);
+  }
+
+  /**
+   * Client-side handshake with a Server
+   */
+  @Override
+  public ServerQueueStatus handshakeWithServer(Connection conn, ServerLocation location,
+      CommunicationMode communicationMode) throws IOException, AuthenticationRequiredException,
+      AuthenticationFailedException, ServerRefusedConnectionException {
+    try {
+      ServerQueueStatus serverQStatus = null;
+      Socket sock = conn.getSocket();
+      DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
+      final InputStream in = sock.getInputStream();
+      DataInputStream dis = new DataInputStream(in);
+      DistributedMember member = getIDForSocket(sock);
+      // if running in a loner system, use the new port number in the ID to
+      // help differentiate from other clients
+      DistributionManager dm = ((InternalDistributedSystem) this.system).getDistributionManager();
+      InternalDistributedMember idm = dm.getDistributionManagerId();
+      synchronized (idm) {
+        if (idm.getPort() == 0 && dm instanceof LonerDistributionManager) {
+          int port = sock.getLocalPort();
+          ((LonerDistributionManager) dm).updateLonerPort(port);
+          this.id.updateID(dm.getDistributionManagerId());
+        }
+      }
+      if (communicationMode.isWAN()) {
+        this.credentials = getCredentials(member);
+      }
+      byte intermediateAcceptanceCode = write(dos, dis, communicationMode, REPLY_OK,
+          this.clientReadTimeout, null, this.credentials, member, false);
+
+      String authInit = this.system.getProperties().getProperty(SECURITY_CLIENT_AUTH_INIT);
+      if (!communicationMode.isWAN() && intermediateAcceptanceCode != REPLY_AUTH_NOT_REQUIRED
+          && (authInit != null && authInit.length() != 0)) {
+        location.compareAndSetRequiresCredentials(true);
+      }
+      // Read the acceptance code
+      byte acceptanceCode = dis.readByte();
+      if (acceptanceCode == (byte) 21 && !(sock instanceof SSLSocket)) {
+        // This is likely the case of server setup with SSL and client not using
+        // SSL
+        throw new AuthenticationRequiredException(
+            LocalizedStrings.HandShake_SERVER_EXPECTING_SSL_CONNECTION.toLocalizedString());
+      }
+      if (acceptanceCode == REPLY_SERVER_IS_LOCATOR) {
+        throw new GemFireConfigException("Improperly configured client detected.  " + "Server at "
+            + location + " is actually a locator.  Use addPoolLocator to configure locators.");
+      }
+
+      // Successful handshake for GATEWAY_TO_GATEWAY mode sets the peer version in connection
+      if (communicationMode.isWAN() && !(acceptanceCode == REPLY_EXCEPTION_AUTHENTICATION_REQUIRED
+          || acceptanceCode == REPLY_EXCEPTION_AUTHENTICATION_FAILED)) {
+        short wanSiteVersion = Version.readOrdinal(dis);
+        conn.setWanSiteVersion(wanSiteVersion);
+        // establish a versioned stream for the other site, if necessary
+        if (wanSiteVersion < Version.CURRENT_ORDINAL) {
+          dis = new VersionedDataInputStream(dis, Version.fromOrdinalOrCurrent(wanSiteVersion));
+        }
+      }
+
+      // No need to check for return value since DataInputStream already throws
+      // EOFException in case of EOF
+      byte epType = dis.readByte();
+      int qSize = dis.readInt();
+
+      member = readServerMember(dis);
+      serverQStatus = new ServerQueueStatus(epType, qSize, member);
+
+      // Read the message (if any)
+      readMessage(dis, dos, acceptanceCode, member);
+
+      // Read delta-propagation property value from server.
+      // [sumedh] Static variable below? Client can connect to different
+      // DSes with different values of this. It shoule be a member variable.
+      if (!communicationMode.isWAN() && currentClientVersion.compareTo(Version.GFE_61) >= 0) {
+        deltaEnabledOnServer = dis.readBoolean();
+      }
+
+      // validate that the remote side has a different distributed system id.
+      if (communicationMode.isWAN() && Version.GFE_66.compareTo(conn.getWanSiteVersion()) <= 0
+          && currentClientVersion.compareTo(Version.GFE_66) >= 0) {
+        int remoteDistributedSystemId = in.read();
+        int localDistributedSystemId =
+            ((InternalDistributedSystem) system).getDistributionManager().getDistributedSystemId();
+        if (localDistributedSystemId >= 0
+            && localDistributedSystemId == remoteDistributedSystemId) {
+          throw new GatewayConfigurationException(
+              "Remote WAN site's distributed system id " + remoteDistributedSystemId
+                  + " matches this sites distributed system id " + localDistributedSystemId);
+        }
+      }
+      // Read the PDX registry size from the remote size
+      if (communicationMode.isWAN() && Version.GFE_80.compareTo(conn.getWanSiteVersion()) <= 0
+          && currentClientVersion.compareTo(Version.GFE_80) >= 0) {
+        int remotePdxSize = dis.readInt();
+        serverQStatus.setPdxSize(remotePdxSize);
+      }
+
+      return serverQStatus;
+    } catch (IOException ex) {
+      CancelCriterion stopper = this.system.getCancelCriterion();
+      stopper.checkCancelInProgress(null);
+      throw ex;
+    }
+  }
+
+  private DistributedMember readServerMember(DataInputStream p_dis) throws IOException {
+
+    byte[] memberBytes = DataSerializer.readByteArray(p_dis);
+    ByteArrayInputStream bais = new ByteArrayInputStream(memberBytes);
+    DataInputStream dis = new DataInputStream(bais);
+    Version v = InternalDataSerializer.getVersionForDataStreamOrNull(p_dis);
+    if (v != null) {
+      dis = new VersionedDataInputStream(dis, v);
+    }
+    try {
+      return DataSerializer.readObject(dis);
+    } catch (EOFException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new InternalGemFireException(
+          LocalizedStrings.HandShake_UNABLE_TO_DESERIALIZE_MEMBER.toLocalizedString(), e);
+    }
+  }
+
+
+  /**
+   * Used by client-side CacheClientUpdater to handshake with a server in order to receive messages
+   * generated by subscriptions (register-interest, continuous query)
+   */
+  @Override
+  public ServerQueueStatus handshakeWithSubscriptionFeed(Socket sock, boolean isPrimary)
+      throws IOException, AuthenticationRequiredException, AuthenticationFailedException,
+      ServerRefusedConnectionException, ClassNotFoundException {
+    ServerQueueStatus sqs = null;
+    try {
+      DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
+      final InputStream in = sock.getInputStream();
+      DataInputStream dis = new DataInputStream(in);
+      DistributedMember member = getIDForSocket(sock);
+      if (!this.multiuserSecureMode) {
+        this.credentials = getCredentials(member);
+      }
+      CommunicationMode mode = isPrimary ? CommunicationMode.PrimaryServerToClient
+          : CommunicationMode.SecondaryServerToClient;
+      write(dos, dis, mode, REPLY_OK, 0, new ArrayList(), this.credentials, member, true);
+
+      // Wait here for a reply before continuing. This ensures that the client
+      // updater is registered with the server before continuing.
+      byte acceptanceCode = dis.readByte();
+      if (acceptanceCode == (byte) 21 && !(sock instanceof SSLSocket)) {
+        // This is likely the case of server setup with SSL and client not using
+        // SSL
+        throw new AuthenticationRequiredException(
+            LocalizedStrings.HandShake_SERVER_EXPECTING_SSL_CONNECTION.toLocalizedString());
+      }
+
+      // No need to check for return value since DataInputStream already throws
+      // EOFException in case of EOF
+      byte qType = dis.readByte();
+      // read and ignore qSize flag
+      int qSize = dis.readInt();
+      sqs = new ServerQueueStatus(qType, qSize, member);
+
+      // Read the message (if any)
+      readMessage(dis, dos, acceptanceCode, member);
+
+      // [sumedh] nothing more to be done for older clients used in tests
+      // there is a difference in serializer map registration for >= 6.5.1.6
+      // clients but that is not used in tests
+      if (currentClientVersion.compareTo(Version.GFE_61) < 0) {
+        return sqs;
+      }
+      HashMap instantiatorMap = DataSerializer.readHashMap(dis);
+      for (Iterator itr = instantiatorMap.entrySet().iterator(); itr.hasNext();) {
+        Map.Entry instantiator = (Map.Entry) itr.next();
+        Integer id = (Integer) instantiator.getKey();
+        ArrayList instantiatorArguments = (ArrayList) instantiator.getValue();
+        InternalInstantiator.register((String) instantiatorArguments.get(0),
+            (String) instantiatorArguments.get(1), id, false);
+      }
+
+      HashMap dataSerializersMap = DataSerializer.readHashMap(dis);
+      for (Iterator itr = dataSerializersMap.entrySet().iterator(); itr.hasNext();) {
+        Map.Entry dataSerializer = (Map.Entry) itr.next();
+        Integer id = (Integer) dataSerializer.getKey();
+        InternalDataSerializer.register((String) dataSerializer.getValue(), false, null, null, id);
+      }
+      HashMap<Integer, ArrayList<String>> dsToSupportedClassNames = DataSerializer.readHashMap(dis);
+      InternalDataSerializer.updateSupportedClassesMap(dsToSupportedClassNames);
+    } catch (IOException ex) {
+      CancelCriterion stopper = this.system.getCancelCriterion();
+      stopper.checkCancelInProgress(null);
+      throw ex;
+    } catch (ClassNotFoundException ex) {
+      CancelCriterion stopper = this.system.getCancelCriterion();
+      stopper.checkCancelInProgress(null);
+      throw ex;
+    }
+    return sqs;
+  }
+
+  /**
+   * client-to-server handshake. Nothing is sent to the server prior to invoking this method.
+   */
+  private byte write(DataOutputStream dos, DataInputStream dis, CommunicationMode communicationMode,
+      int replyCode, int readTimeout, List ports, Properties p_credentials,
+      DistributedMember member, boolean isCallbackConnection) throws IOException {
+    HeapDataOutputStream hdos = new HeapDataOutputStream(32, Version.CURRENT);
+    byte acceptanceCode = -1;
+    try {
+      hdos.writeByte(communicationMode.getModeNumber());
+      if (overrideClientVersion > 0) {
+        // for testing
+        Version.writeOrdinal(hdos, overrideClientVersion, true);
+      } else {
+        Version.writeOrdinal(hdos, currentClientVersion.ordinal(), true);
+      }
+
+      hdos.writeByte(replyCode);
+      if (ports != null) {
+        hdos.writeInt(ports.size());
+        for (int i = 0; i < ports.size(); i++) {
+          hdos.writeInt(Integer.parseInt((String) ports.get(i)));
+        }
+      } else {
+        hdos.writeInt(readTimeout);
+      }
+      // we do not know the receiver's version at this point, but the on-wire
+      // form of InternalDistributedMember changed in 9.0, so we must serialize
+      // it using the previous version
+      DataOutput idOut = new VersionedDataOutputStream(hdos, Version.GFE_82);
+      DataSerializer.writeObject(this.id, idOut);
+
+      if (currentClientVersion.compareTo(Version.GFE_603) >= 0) {
+        byte[] overrides = getOverrides();
+        for (int bytes = 0; bytes < overrides.length; bytes++) {
+          hdos.writeByte(overrides[bytes]);
+        }
+      } else {
+        // write the client conflation setting byte
+        if (setClientConflationForTesting) {
+          hdos.writeByte(clientConflationForTesting);
+        } else {
+          hdos.writeByte(this.clientConflation);
+        }
+      }
+
+      if (isCallbackConnection || communicationMode.isWAN()) {
+        if (isCallbackConnection && this.multiuserSecureMode && !communicationMode.isWAN()) {
+          hdos.writeByte(SECURITY_MULTIUSER_NOTIFICATIONCHANNEL);
+          hdos.flush();
+          dos.write(hdos.toByteArray());
+          dos.flush();
+        } else {
+          writeCredentials(dos, dis, p_credentials, ports != null, member, hdos);
+        }
+      } else {
+        String authInitMethod = this.system.getProperties().getProperty(SECURITY_CLIENT_AUTH_INIT);
+        acceptanceCode = writeCredential(dos, dis, authInitMethod, ports != null, member, hdos);
+      }
+    } finally {
+      hdos.close();
+    }
+    return acceptanceCode;
+  }
+
+  @Override
+  protected byte writeCredential(DataOutputStream dos, DataInputStream dis, String authInit,
+      boolean isNotification, DistributedMember member, HeapDataOutputStream heapdos)
+      throws IOException, GemFireSecurityException {
+
+    if (!this.multiuserSecureMode && (authInit == null || authInit.length() == 0)) {
+      // No credentials indicator
+      heapdos.writeByte(CREDENTIALS_NONE);
+      heapdos.flush();
+      dos.write(heapdos.toByteArray());
+      dos.flush();
+      return -1;
+    }
+
+    return super.writeCredential(dos, dis, authInit, isNotification, member, heapdos);
+  }
+
+  /**
+   * Handshake implements the Diffie-Hellman encryption algorithms
+   *
+   * @return
+   */
+  public Encryptor getEncryptor() {
+    return this;
+  }
+}
diff --git a/geode-core/src/main/java/org/apache/geode/cache/client/internal/ConnectionFactoryImpl.java b/geode-core/src/main/java/org/apache/geode/cache/client/internal/ConnectionFactoryImpl.java
index 942a1b9..32724d3 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/client/internal/ConnectionFactoryImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/client/internal/ConnectionFactoryImpl.java
@@ -29,10 +29,10 @@ import org.apache.geode.cache.client.internal.ServerBlackList.FailureTracker;
 import org.apache.geode.cache.wan.GatewaySender;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.distributed.internal.ServerLocation;
+import org.apache.geode.internal.cache.tier.ClientSideHandshake;
 import org.apache.geode.internal.cache.tier.CommunicationMode;
 import org.apache.geode.internal.cache.tier.sockets.CacheClientUpdater;
 import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
 import org.apache.geode.internal.i18n.LocalizedStrings;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.log4j.LocalizedMessage;
@@ -54,9 +54,9 @@ public class ConnectionFactoryImpl implements ConnectionFactory {
   // TODO - GEODE-1746, the handshake holds state. It seems like the code depends
   // on all of the handshake operations happening in a single thread. I don't think we
   // want that, need to refactor.
-  private final HandShake handshake;
+  private final ClientSideHandshakeImpl handshake;
   private final int socketBufferSize;
-  private final int handShakeTimeout;
+  private final int handshakeTimeout;
   private final boolean usedByGateway;
   private final ServerBlackList blackList;
   private final CancelCriterion cancelCriterion;
@@ -77,17 +77,17 @@ public class ConnectionFactoryImpl implements ConnectionFactory {
   public static boolean testFailedConnectionToServer = false;
 
   public ConnectionFactoryImpl(ConnectionSource source, EndpointManager endpointManager,
-      InternalDistributedSystem sys, int socketBufferSize, int handShakeTimeout, int readTimeout,
+      InternalDistributedSystem sys, int socketBufferSize, int handshakeTimeout, int readTimeout,
       ClientProxyMembershipID proxyId, CancelCriterion cancelCriterion, boolean usedByGateway,
       GatewaySender sender, long pingInterval, boolean multiuserSecureMode, PoolImpl pool) {
-    this.handshake = new HandShake(proxyId, sys, sys.getSecurityService());
+    this.handshake =
+        new ClientSideHandshakeImpl(proxyId, sys, sys.getSecurityService(), multiuserSecureMode);
     this.handshake.setClientReadTimeout(readTimeout);
     this.source = source;
     this.endpointManager = endpointManager;
     this.ds = sys;
     this.socketBufferSize = socketBufferSize;
-    this.handShakeTimeout = handShakeTimeout;
-    this.handshake.setMultiuserSecureMode(multiuserSecureMode);
+    this.handshakeTimeout = handshakeTimeout;
     this.readTimeout = readTimeout;
     this.usedByGateway = usedByGateway;
     this.gatewaySender = sender;
@@ -133,12 +133,12 @@ public class ConnectionFactoryImpl implements ConnectionFactory {
     boolean initialized = false;
 
     try {
-      HandShake connHandShake = new HandShake(handshake);
+      ClientSideHandshake connHandShake = new ClientSideHandshakeImpl(handshake);
       connection.connect(endpointManager, location, connHandShake, socketBufferSize,
-          handShakeTimeout, readTimeout, getCommMode(forQueue), this.gatewaySender,
+          handshakeTimeout, readTimeout, getCommMode(forQueue), this.gatewaySender,
           this.socketCreator);
       failureTracker.reset();
-      connection.setHandShake(connHandShake);
+      connection.setHandshake(connHandShake);
       authenticateIfRequired(connection);
       initialized = true;
     } catch (GemFireConfigException e) {
@@ -281,13 +281,6 @@ public class ConnectionFactoryImpl implements ConnectionFactory {
       excludedServers.add(server);
     } while (conn == null);
 
-    // if(conn == null) {
-    // logger.fine("Unable to create a connection in the allowed time.");
-    //
-    // if(fatalException!=null) {
-    // throw fatalException;
-    // }
-    // }
     return conn;
   }
 
@@ -300,8 +293,8 @@ public class ConnectionFactoryImpl implements ConnectionFactory {
     }
     // Launch the thread
     CacheClientUpdater updater = new CacheClientUpdater(clientUpdateName, endpoint.getLocation(),
-        isPrimary, ds, new HandShake(this.handshake), qManager, endpointManager, endpoint,
-        handShakeTimeout, this.socketCreator);
+        isPrimary, ds, new ClientSideHandshakeImpl(this.handshake), qManager, endpointManager,
+        endpoint, handshakeTimeout, this.socketCreator);
 
     if (!updater.isConnected()) {
       return null;
@@ -310,28 +303,6 @@ public class ConnectionFactoryImpl implements ConnectionFactory {
     updater.setFailedUpdater(failedUpdater);
     updater.start();
 
-    // Wait for the client update thread to be ready
-    // if (!updater.waitForInitialization()) {
-    // Yogesh : This doesn't wait for notify if the updater
-    // thread exits from the run in case of Exception in CCU thread
-    // Yogesh : fix for 36690
-    // because when CCU thread gets a ConnectException, it comes out of run method
-    // and when a thread is no more running it notifies all the waiting threads on the thread
-    // object.
-    // so above wait will come out irrelevant of notify from CCU thread, when CCU thread has got an
-    // exception
-    // To avoid this problem we check isAlive before returning from this method.
-    // if (logger != null && logger.infoEnabled()) {
-    // logger.info(LocalizedStrings.AutoConnectionSourceImpl_0_NOT_STARTED_1, new Object[] {this,
-    // clientUpdateName});
-    // }
-    // return null;
-    // }else {
-    // if (logger != null && logger.infoEnabled()) {
-    // logger.info(LocalizedStrings.AutoConnectionSourceImpl_0_STARTED_1, new Object[] {this,
-    // clientUpdateName});
-    // }
-    // }
     return updater;
   }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/cache/client/internal/ConnectionImpl.java b/geode-core/src/main/java/org/apache/geode/cache/client/internal/ConnectionImpl.java
index 0a74c46..1e54c42 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/client/internal/ConnectionImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/client/internal/ConnectionImpl.java
@@ -36,8 +36,8 @@ import org.apache.geode.cache.wan.GatewaySender;
 import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.distributed.internal.ServerLocation;
+import org.apache.geode.internal.cache.tier.ClientSideHandshake;
 import org.apache.geode.internal.cache.tier.CommunicationMode;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
 import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
 import org.apache.geode.internal.cache.tier.sockets.ServerQueueStatus;
 import org.apache.geode.internal.i18n.LocalizedStrings;
@@ -87,7 +87,7 @@ public class ConnectionImpl implements Connection {
 
   private long connectionID = Connection.DEFAULT_CONNECTION_ID;
 
-  private HandShake handShake;
+  private ClientSideHandshake handshake;
 
   public ConnectionImpl(InternalDistributedSystem ds, CancelCriterion cancelCriterion) {
     this.ds = ds;
@@ -100,10 +100,10 @@ public class ConnectionImpl implements Connection {
   }
 
   public ServerQueueStatus connect(EndpointManager endpointManager, ServerLocation location,
-      HandShake handShake, int socketBufferSize, int handShakeTimeout, int readTimeout,
+      ClientSideHandshake handshake, int socketBufferSize, int handshakeTimeout, int readTimeout,
       CommunicationMode communicationMode, GatewaySender sender, SocketCreator sc)
       throws IOException {
-    theSocket = sc.connectForClient(location.getHostName(), location.getPort(), handShakeTimeout,
+    theSocket = sc.connectForClient(location.getHostName(), location.getPort(), handshakeTimeout,
         socketBufferSize);
     theSocket.setTcpNoDelay(true);
     // System.out.println("ConnectionImpl setting buffer sizes: " +
@@ -114,10 +114,10 @@ public class ConnectionImpl implements Connection {
     verifySocketBufferSize(socketBufferSize, theSocket.getReceiveBufferSize(), "receive");
     verifySocketBufferSize(socketBufferSize, theSocket.getSendBufferSize(), "send");
 
-    theSocket.setSoTimeout(handShakeTimeout);
+    theSocket.setSoTimeout(handshakeTimeout);
     out = theSocket.getOutputStream();
     in = theSocket.getInputStream();
-    this.status = handShake.handshakeWithServer(this, location, communicationMode);
+    this.status = handshake.handshakeWithServer(this, location, communicationMode);
     commBuffer = ServerConnection.allocateCommBuffer(socketBufferSize, theSocket);
     if (sender != null) {
       commBufferForAsyncRead = ServerConnection.allocateCommBuffer(socketBufferSize, theSocket);
@@ -310,12 +310,16 @@ public class ConnectionImpl implements Connection {
     return this.connectionID;
   }
 
-  protected HandShake getHandShake() {
-    return handShake;
+  protected byte[] encryptBytes(byte[] messageBytes) throws Exception {
+    return handshake.getEncryptor().encryptBytes(messageBytes);
   }
 
-  protected void setHandShake(HandShake handShake) {
-    this.handShake = handShake;
+  protected byte[] decryptBytes(byte[] messageBytes) throws Exception {
+    return handshake.getEncryptor().decryptBytes(messageBytes);
+  }
+
+  protected void setHandshake(ClientSideHandshake handshake) {
+    this.handshake = handshake;
   }
 
   /**
diff --git a/geode-core/src/main/java/org/apache/geode/cache/client/internal/ProxyCacheCloseOp.java b/geode-core/src/main/java/org/apache/geode/cache/client/internal/ProxyCacheCloseOp.java
index 8b8cf19..b22fbe8 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/client/internal/ProxyCacheCloseOp.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/client/internal/ProxyCacheCloseOp.java
@@ -64,7 +64,7 @@ public class ProxyCacheCloseOp {
       }
       hdos.writeLong((Long) userId);
       try {
-        secureBytes = ((ConnectionImpl) cnx).getHandShake().encryptBytes(hdos.toByteArray());
+        secureBytes = ((ConnectionImpl) cnx).encryptBytes(hdos.toByteArray());
       } finally {
         hdos.close();
       }
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java
index fb45fc7..f16c630 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java
@@ -87,7 +87,7 @@ import org.apache.geode.internal.cache.GemFireCacheImpl;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.execute.FunctionServiceStats;
 import org.apache.geode.internal.cache.execute.FunctionStats;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.cache.xmlcache.CacheServerCreation;
 import org.apache.geode.internal.i18n.LocalizedStrings;
 import org.apache.geode.internal.logging.InternalLogWriter;
@@ -691,9 +691,9 @@ public class InternalDistributedSystem extends DistributedSystem
 
       // Initialize the Diffie-Hellman and public/private keys
       try {
-        HandShake.initCertsMap(this.config.getSecurityProps());
-        HandShake.initPrivateKey(this.config.getSecurityProps());
-        HandShake.initDHKeys(this.config);
+        Handshake.initCertsMap(this.config.getSecurityProps());
+        Handshake.initPrivateKey(this.config.getSecurityProps());
+        Handshake.initDHKeys(this.config);
       } catch (Exception ex) {
         throw new GemFireSecurityException(
             LocalizedStrings.InternalDistributedSystem_PROBLEM_IN_INITIALIZING_KEYS_FOR_CLIENT_AUTHENTICATION
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/auth/GMSAuthenticator.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/auth/GMSAuthenticator.java
index c15cb5e..4ea8065 100755
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/auth/GMSAuthenticator.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/auth/GMSAuthenticator.java
@@ -32,7 +32,7 @@ import org.apache.geode.distributed.internal.membership.InternalDistributedMembe
 import org.apache.geode.distributed.internal.membership.NetView;
 import org.apache.geode.distributed.internal.membership.gms.Services;
 import org.apache.geode.distributed.internal.membership.gms.interfaces.Authenticator;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.i18n.LocalizedStrings;
 import org.apache.geode.internal.logging.InternalLogWriter;
 import org.apache.geode.internal.security.CallbackInstantiator;
@@ -195,7 +195,7 @@ public class GMSAuthenticator implements Authenticator {
    */
   Properties getCredentials(DistributedMember member, Properties secProps) {
     String authMethod = secProps.getProperty(SECURITY_PEER_AUTH_INIT);
-    return HandShake.getCredentials(authMethod, secProps, member, true, services.getLogWriter(),
+    return Handshake.getCredentials(authMethod, secProps, member, true, services.getLogWriter(),
         services.getSecurityLogWriter());
   }
 
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpServer.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpServer.java
index 1ba0380..008156c 100755
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpServer.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpServer.java
@@ -27,7 +27,6 @@ import java.net.SocketAddress;
 import java.net.URL;
 import java.util.Date;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.SynchronousQueue;
@@ -65,7 +64,7 @@ import org.apache.geode.internal.cache.client.protocol.ClientProtocolServiceLoad
 import org.apache.geode.internal.cache.client.protocol.exception.ServiceLoadingFailureException;
 import org.apache.geode.internal.cache.client.protocol.exception.ServiceVersionNotFoundException;
 import org.apache.geode.internal.cache.tier.CommunicationMode;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.net.SocketCreator;
 import org.apache.geode.internal.net.SocketCreatorFactory;
@@ -382,7 +381,7 @@ public class TcpServer {
         } else if (firstByte == CommunicationMode.ProtobufClientServerProtocol.getModeNumber()) {
           handleProtobufConnection(socket, input);
         } else if (CommunicationMode.isValidMode(firstByte)) {
-          socket.getOutputStream().write(HandShake.REPLY_SERVER_IS_LOCATOR);
+          socket.getOutputStream().write(Handshake.REPLY_SERVER_IS_LOCATOR);
           throw new Exception("Improperly configured client detected - use addPoolLocator to "
               + "configure its locators instead of addPoolServer.");
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java
index aca96d0..f2b0dde 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java
@@ -113,6 +113,7 @@ import org.apache.geode.cache.TransactionId;
 import org.apache.geode.cache.client.PoolManager;
 import org.apache.geode.cache.client.ServerOperationException;
 import org.apache.geode.cache.client.SubscriptionNotEnabledException;
+import org.apache.geode.cache.client.internal.ClientSideHandshakeImpl;
 import org.apache.geode.cache.client.internal.Connection;
 import org.apache.geode.cache.client.internal.Endpoint;
 import org.apache.geode.cache.client.internal.PoolImpl;
@@ -196,7 +197,6 @@ import org.apache.geode.internal.cache.tier.sockets.ClientHealthMonitor;
 import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID;
 import org.apache.geode.internal.cache.tier.sockets.ClientTombstoneMessage;
 import org.apache.geode.internal.cache.tier.sockets.ClientUpdateMessage;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
 import org.apache.geode.internal.cache.tier.sockets.VersionedObjectList;
 import org.apache.geode.internal.cache.versions.ConcurrentCacheModificationException;
 import org.apache.geode.internal.cache.versions.RegionVersionHolder;
@@ -1670,7 +1670,7 @@ public class LocalRegion extends AbstractRegion implements LoaderHelperFactory,
           if (!extractDelta && ClientHealthMonitor.getInstance() != null) {
             extractDelta = ClientHealthMonitor.getInstance().hasDeltaClients();
           }
-        } else if (HandShake.isDeltaEnabledOnServer()) {
+        } else if (ClientSideHandshakeImpl.isDeltaEnabledOnServer()) {
           // This is a client region
           extractDelta = true;
         }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/ha/HARegionQueue.java b/geode-core/src/main/java/org/apache/geode/internal/cache/ha/HARegionQueue.java
index 13abbfe..1c84967 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/ha/HARegionQueue.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/ha/HARegionQueue.java
@@ -87,7 +87,7 @@ import org.apache.geode.internal.cache.tier.sockets.ClientUpdateMessage;
 import org.apache.geode.internal.cache.tier.sockets.ClientUpdateMessageImpl;
 import org.apache.geode.internal.cache.tier.sockets.ClientUpdateMessageImpl.CqNameToOp;
 import org.apache.geode.internal.cache.tier.sockets.HAEventWrapper;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.i18n.LocalizedStrings;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.log4j.LocalizedMessage;
@@ -276,7 +276,7 @@ public class HARegionQueue implements RegionQueue {
   private CancelCriterion stopper;
 
   /** @since GemFire 5.7 */
-  protected byte clientConflation = HandShake.CONFLATION_DEFAULT;
+  protected byte clientConflation = Handshake.CONFLATION_DEFAULT;
 
   /**
    * Boolean to indicate whether client is a slow receiver
@@ -567,9 +567,9 @@ public class HARegionQueue implements RegionQueue {
       return retVal;
     }
     switch (this.clientConflation) {
-      case HandShake.CONFLATION_OFF:
+      case Handshake.CONFLATION_OFF:
         return false; // always disable
-      case HandShake.CONFLATION_ON:
+      case Handshake.CONFLATION_ON:
         if (event instanceof HAEventWrapper) {
           ClientUpdateMessage cum = (ClientUpdateMessage) this.haContainer.get(event);
           if (cum != null) {
@@ -584,7 +584,7 @@ public class HARegionQueue implements RegionQueue {
         }
         // Oddness
         break;
-      case HandShake.CONFLATION_DEFAULT:
+      case Handshake.CONFLATION_DEFAULT:
         return retVal;
       default:
         throw new InternalGemFireError("Invalid clientConflation");
@@ -1949,7 +1949,7 @@ public class HARegionQueue implements RegionQueue {
 
     return getHARegionQueueInstance(regionName, cache,
         HARegionQueueAttributes.DEFAULT_HARQ_ATTRIBUTES, haRgnQType, isDurable, container, null,
-        HandShake.CONFLATION_DEFAULT, false, Boolean.FALSE);
+        Handshake.CONFLATION_DEFAULT, false, Boolean.FALSE);
   }
 
   /**
@@ -2019,7 +2019,7 @@ public class HARegionQueue implements RegionQueue {
     }
 
     return getHARegionQueueInstance(regionName, cache, hrqa, haRgnQType, isDurable, container, null,
-        HandShake.CONFLATION_DEFAULT, false, Boolean.FALSE);
+        Handshake.CONFLATION_DEFAULT, false, Boolean.FALSE);
   }
 
   public boolean isEmptyAckList() {
@@ -2593,14 +2593,14 @@ public class HARegionQueue implements RegionQueue {
     TestOnlyHARegionQueue(String regionName, InternalCache cache, Map haContainer)
         throws IOException, ClassNotFoundException, CacheException, InterruptedException {
       this(regionName, cache, HARegionQueueAttributes.DEFAULT_HARQ_ATTRIBUTES, haContainer,
-          HandShake.CONFLATION_DEFAULT, false);
+          Handshake.CONFLATION_DEFAULT, false);
       this.initialized.set(true);
     }
 
     TestOnlyHARegionQueue(String regionName, InternalCache cache)
         throws IOException, ClassNotFoundException, CacheException, InterruptedException {
       this(regionName, cache, HARegionQueueAttributes.DEFAULT_HARQ_ATTRIBUTES, new HashMap(),
-          HandShake.CONFLATION_DEFAULT, false);
+          Handshake.CONFLATION_DEFAULT, false);
     }
 
     TestOnlyHARegionQueue(String regionName, InternalCache cache, HARegionQueueAttributes hrqa,
@@ -2621,7 +2621,7 @@ public class HARegionQueue implements RegionQueue {
      */
     TestOnlyHARegionQueue(String regionName, InternalCache cache, HARegionQueueAttributes hrqa)
         throws IOException, ClassNotFoundException, CacheException, InterruptedException {
-      this(regionName, cache, hrqa, new HashMap(), HandShake.CONFLATION_DEFAULT, false);
+      this(regionName, cache, hrqa, new HashMap(), Handshake.CONFLATION_DEFAULT, false);
     }
   }
 
@@ -3699,8 +3699,8 @@ public class HARegionQueue implements RegionQueue {
    * @since GemFire 5.7
    */
   public void setClientConflation(byte value) {
-    if (value != HandShake.CONFLATION_OFF && value != HandShake.CONFLATION_ON
-        && value != HandShake.CONFLATION_DEFAULT) {
+    if (value != Handshake.CONFLATION_OFF && value != Handshake.CONFLATION_ON
+        && value != Handshake.CONFLATION_DEFAULT) {
       throw new IllegalArgumentException("illegal conflation value");
     }
     this.clientConflation = value;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/properties.html b/geode-core/src/main/java/org/apache/geode/internal/cache/properties.html
index 1369b8a..baa9784 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/properties.html
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/properties.html
@@ -271,13 +271,13 @@ This is the TCP accept backlog for the acceptor thread's listening socket.
 </dd>
 
 <!-- -------------------------------------------------------  -->
-<dt><strong>BridgeServer.handShakeTimeout</strong></dt>
+<dt><strong>BridgeServer.handshakeTimeout</strong></dt>
 <dd>
 <em>Public:</em> false
 <p>
 <em>Integer</em> (default is 59000)
 <p>
-See <code>org.apache.geode.internal.cache.tier.sockets.AcceptorImpl#handShakeTimeout</code>.
+See <code>org.apache.geode.internal.cache.tier.sockets.AcceptorImpl#handshakeTimeout</code>.
 <p>
 <pre>
   Test value for handshake timeout
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ClientSideHandshake.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ClientSideHandshake.java
new file mode 100644
index 0000000..c472fcd
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ClientSideHandshake.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.geode.internal.cache.tier;
+
+import java.io.IOException;
+import java.net.Socket;
+
+import org.apache.geode.cache.client.ServerRefusedConnectionException;
+import org.apache.geode.cache.client.internal.Connection;
+import org.apache.geode.distributed.internal.ServerLocation;
+import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID;
+import org.apache.geode.internal.cache.tier.sockets.ServerQueueStatus;
+import org.apache.geode.security.AuthenticationFailedException;
+import org.apache.geode.security.AuthenticationRequiredException;
+
+public interface ClientSideHandshake extends Encryptor {
+  Encryptor getEncryptor();
+
+  ClientProxyMembershipID getMembershipId();
+
+  ServerQueueStatus handshakeWithSubscriptionFeed(Socket socket, boolean isPrimary)
+      throws IOException, AuthenticationRequiredException, AuthenticationFailedException,
+      ServerRefusedConnectionException, ClassNotFoundException;
+
+  ServerQueueStatus handshakeWithServer(Connection conn, ServerLocation location,
+      CommunicationMode communicationMode) throws IOException, AuthenticationRequiredException,
+      AuthenticationFailedException, ServerRefusedConnectionException;
+}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ClientHandShake.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/Encryptor.java
old mode 100755
new mode 100644
similarity index 54%
copy from geode-core/src/main/java/org/apache/geode/internal/cache/tier/ClientHandShake.java
copy to geode-core/src/main/java/org/apache/geode/internal/cache/tier/Encryptor.java
index 4272593..75daf52
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ClientHandShake.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/Encryptor.java
@@ -12,33 +12,15 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package org.apache.geode.internal.cache.tier;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.Principal;
-
-import org.apache.geode.internal.Version;
-import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID;
-
 /**
- * <code>ClientHandShake</code> represents a handshake from the client.
+ * Diffie-Hellman data encryptor
  *
- * @since GemFire 5.7
+ * @deprecated this feature should be removed in Geode 2.0
  */
-public interface ClientHandShake {
-  public boolean isOK();
-
-  public byte getCode();
-
-  public ClientProxyMembershipID getMembership();
-
-  public int getClientReadTimeout();
-
-  public Version getVersion();
+public interface Encryptor {
+  byte[] encryptBytes(byte[] bytes) throws Exception;
 
-  public void accept(OutputStream out, InputStream in, byte epType, int qSize,
-      CommunicationMode communicationMode, Principal principal) throws IOException;
+  byte[] decryptBytes(byte[] bytes) throws Exception;
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ClientHandShake.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ServerSideHandshake.java
similarity index 80%
rename from geode-core/src/main/java/org/apache/geode/internal/cache/tier/ClientHandShake.java
rename to geode-core/src/main/java/org/apache/geode/internal/cache/tier/ServerSideHandshake.java
index 4272593..f382609 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ClientHandShake.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/ServerSideHandshake.java
@@ -26,19 +26,19 @@ import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID;
 /**
  * <code>ClientHandShake</code> represents a handshake from the client.
  *
- * @since GemFire 5.7
  */
-public interface ClientHandShake {
-  public boolean isOK();
+public interface ServerSideHandshake extends Encryptor {
+  boolean isOK();
 
-  public byte getCode();
+  ClientProxyMembershipID getMembershipId();
 
-  public ClientProxyMembershipID getMembership();
+  int getClientReadTimeout();
 
-  public int getClientReadTimeout();
+  Version getVersion();
 
-  public Version getVersion();
-
-  public void accept(OutputStream out, InputStream in, byte epType, int qSize,
+  void accept(OutputStream out, InputStream in, byte epType, int qSize,
       CommunicationMode communicationMode, Principal principal) throws IOException;
+
+  Encryptor getEncryptor();
+
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/AcceptorImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/AcceptorImpl.java
index 010e07c..08d237a 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/AcceptorImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/AcceptorImpl.java
@@ -176,7 +176,7 @@ public class AcceptorImpl implements Acceptor, Runnable, CommBufferPool {
    * The name of a system property that sets the hand shake timeout (in milliseconds). This is how
    * long a client will wait to hear back from a server.
    */
-  public static final String HANDSHAKE_TIMEOUT_PROPERTY_NAME = "BridgeServer.handShakeTimeout";
+  public static final String HANDSHAKE_TIMEOUT_PROPERTY_NAME = "BridgeServer.handshakeTimeout";
 
   /**
    * The default value of the {@link #HANDSHAKE_TIMEOUT_PROPERTY_NAME} system property.
@@ -186,7 +186,7 @@ public class AcceptorImpl implements Acceptor, Runnable, CommBufferPool {
   /**
    * Test value for handshake timeout
    */
-  protected static final int handShakeTimeout =
+  protected static final int handshakeTimeout =
       Integer.getInteger(HANDSHAKE_TIMEOUT_PROPERTY_NAME, DEFAULT_HANDSHAKE_TIMEOUT_MS).intValue();
 
   /**
@@ -1442,7 +1442,7 @@ public class AcceptorImpl implements Acceptor, Runnable, CommBufferPool {
                 Integer.valueOf(this.maxConnections)}));
         if (communicationMode.expectsConnectionRefusalMessage()) {
           try {
-            ServerHandShakeProcessor.refuse(socket.getOutputStream(),
+            ServerHandshakeProcessor.refuse(socket.getOutputStream(),
                 LocalizedStrings.AcceptorImpl_EXCEEDED_MAX_CONNECTIONS_0
                     .toLocalizedString(Integer.valueOf(this.maxConnections)));
           } catch (Exception ex) {
@@ -1456,7 +1456,7 @@ public class AcceptorImpl implements Acceptor, Runnable, CommBufferPool {
 
     ServerConnection serverConn =
         serverConnectionFactory.makeServerConnection(socket, this.cache, this.crHelper, this.stats,
-            AcceptorImpl.handShakeTimeout, this.socketBufferSize, communicationMode.toString(),
+            AcceptorImpl.handshakeTimeout, this.socketBufferSize, communicationMode.toString(),
             communicationMode.getModeNumber(), this, this.securityService);
 
     synchronized (this.allSCsLock) {
@@ -1480,7 +1480,7 @@ public class AcceptorImpl implements Acceptor, Runnable, CommBufferPool {
             LocalizedStrings.AcceptorImpl_REJECTED_CONNECTION_FROM_0_BECAUSE_REQUEST_REJECTED_BY_POOL,
             new Object[] {serverConn}));
         try {
-          ServerHandShakeProcessor.refuse(socket.getOutputStream(),
+          ServerHandshakeProcessor.refuse(socket.getOutputStream(),
               LocalizedStrings.AcceptorImpl_EXCEEDED_MAX_CONNECTIONS_0
                   .toLocalizedString(Integer.valueOf(this.maxConnections)));
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientNotifier.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientNotifier.java
index 81bad21..7110f6b 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientNotifier.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientNotifier.java
@@ -295,11 +295,11 @@ public class CacheClientNotifier {
     ClientProxyMembershipID proxyID = null;
     CacheClientProxy proxy;
     AccessControl authzCallback = null;
-    byte clientConflation = HandShake.CONFLATION_DEFAULT;
+    byte clientConflation = Handshake.CONFLATION_DEFAULT;
     try {
       proxyID = ClientProxyMembershipID.readCanonicalized(dis);
       if (getBlacklistedClient().contains(proxyID)) {
-        writeException(dos, HandShake.REPLY_INVALID,
+        writeException(dos, Handshake.REPLY_INVALID,
             new Exception("This client is blacklisted by server"), clientVersion);
         return;
       }
@@ -311,19 +311,19 @@ public class CacheClientNotifier {
       String authenticator = sysProps.getProperty(SECURITY_CLIENT_AUTHENTICATOR);
 
       if (clientVersion.compareTo(Version.GFE_603) >= 0) {
-        byte[] overrides = HandShake.extractOverrides(new byte[] {(byte) dis.read()});
+        byte[] overrides = Handshake.extractOverrides(new byte[] {(byte) dis.read()});
         clientConflation = overrides[0];
       } else {
         clientConflation = (byte) dis.read();
       }
 
       switch (clientConflation) {
-        case HandShake.CONFLATION_DEFAULT:
-        case HandShake.CONFLATION_OFF:
-        case HandShake.CONFLATION_ON:
+        case Handshake.CONFLATION_DEFAULT:
+        case Handshake.CONFLATION_OFF:
+        case Handshake.CONFLATION_ON:
           break;
         default:
-          writeException(dos, HandShake.REPLY_INVALID,
+          writeException(dos, Handshake.REPLY_INVALID,
               new IllegalArgumentException("Invalid conflation byte"), clientVersion);
           return;
       }
@@ -332,14 +332,14 @@ public class CacheClientNotifier {
           acceptorId, notifyBySubscription);
 
       Properties credentials =
-          HandShake.readCredentials(dis, dos, system, this.cache.getSecurityService());
+          Handshake.readCredentials(dis, dos, system, this.cache.getSecurityService());
       if (credentials != null && proxy != null) {
         if (securityLogWriter.fineEnabled()) {
           securityLogWriter
               .fine("CacheClientNotifier: verifying credentials for proxyID: " + proxyID);
         }
         Object subject =
-            HandShake.verifyCredentials(authenticator, credentials, system.getSecurityProperties(),
+            Handshake.verifyCredentials(authenticator, credentials, system.getSecurityProperties(),
                 this.logWriter, this.securityLogWriter, member, this.cache.getSecurityService());
         if (subject instanceof Principal) {
           Principal principal = (Principal) subject;
@@ -373,13 +373,13 @@ public class CacheClientNotifier {
       securityLogWriter.warning(
           LocalizedStrings.CacheClientNotifier_AN_EXCEPTION_WAS_THROWN_FOR_CLIENT_0_1,
           new Object[] {proxyID, ex});
-      writeException(dos, HandShake.REPLY_EXCEPTION_AUTHENTICATION_REQUIRED, ex, clientVersion);
+      writeException(dos, Handshake.REPLY_EXCEPTION_AUTHENTICATION_REQUIRED, ex, clientVersion);
       return;
     } catch (AuthenticationFailedException ex) {
       securityLogWriter.warning(
           LocalizedStrings.CacheClientNotifier_AN_EXCEPTION_WAS_THROWN_FOR_CLIENT_0_1,
           new Object[] {proxyID, ex});
-      writeException(dos, HandShake.REPLY_EXCEPTION_AUTHENTICATION_FAILED, ex, clientVersion);
+      writeException(dos, Handshake.REPLY_EXCEPTION_AUTHENTICATION_FAILED, ex, clientVersion);
       return;
     } catch (CacheException e) {
       logger.warn(LocalizedMessage.create(
@@ -494,7 +494,7 @@ public class CacheClientNotifier {
                 LocalizedStrings.CacheClientNotifier_COULD_NOT_CONNECT_DUE_TO_CQ_BEING_DRAINED
                     .toLocalizedString();
             logger.warn(unsuccessfulMsg);
-            responseByte = HandShake.REPLY_REFUSED;
+            responseByte = Handshake.REPLY_REFUSED;
             if (CacheClientProxy.testHook != null) {
               CacheClientProxy.testHook.doTestHook("CLIENT_REJECTED_DUE_TO_CQ_BEING_DRAINED");
             }
@@ -507,7 +507,7 @@ public class CacheClientNotifier {
                   .toLocalizedString(new Object[] {proxyId.getDurableId(), proxy});
           logger.warn(unsuccessfulMsg);
           // Set the unsuccessful response byte.
-          responseByte = HandShake.REPLY_EXCEPTION_DUPLICATE_DURABLE_CLIENT;
+          responseByte = Handshake.REPLY_EXCEPTION_DUPLICATE_DURABLE_CLIENT;
         }
       }
     } else {
@@ -542,7 +542,7 @@ public class CacheClientNotifier {
 
     if (!successful) {
       l_proxy = null;
-      responseByte = HandShake.REPLY_REFUSED;
+      responseByte = Handshake.REPLY_REFUSED;
       unsuccessfulMsg =
           LocalizedStrings.CacheClientNotifier_CACHECLIENTNOTIFIER_A_PREVIOUS_CONNECTION_ATTEMPT_FROM_THIS_CLIENT_IS_STILL_BEING_PROCESSED__0
               .toLocalizedString(new Object[] {proxyId});
@@ -1516,7 +1516,7 @@ public class CacheClientNotifier {
     // Remove this proxy from the init proxy list.
     removeClientInitProxy(proxy);
     this._connectionListener.queueAdded(proxy.getProxyID());
-    if (!(proxy.clientConflation == HandShake.CONFLATION_ON)) {
+    if (!(proxy.clientConflation == Handshake.CONFLATION_ON)) {
       // Delta not supported with conflation ON
       ClientHealthMonitor chm = ClientHealthMonitor.getInstance();
       /*
@@ -1661,7 +1661,7 @@ public class CacheClientNotifier {
     this._clientProxies.remove(client);
     this._connectionListener.queueRemoved();
     this.getCache().cleanupForClient(this, client);
-    if (!(proxy.clientConflation == HandShake.CONFLATION_ON)) {
+    if (!(proxy.clientConflation == Handshake.CONFLATION_ON)) {
       ClientHealthMonitor chm = ClientHealthMonitor.getInstance();
       if (chm != null) {
         chm.numOfClientsPerVersion.decrementAndGet(proxy.getVersion().ordinal());
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientProxy.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientProxy.java
index 5ba68b0..82c0bea 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientProxy.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientProxy.java
@@ -241,7 +241,7 @@ public class CacheClientProxy implements ClientSession {
   private boolean isPrimary;
 
   /** @since GemFire 5.7 */
-  protected byte clientConflation = HandShake.CONFLATION_DEFAULT;
+  protected byte clientConflation = Handshake.CONFLATION_DEFAULT;
 
   /**
    * Flag to indicate whether to keep a durable client's queue alive
@@ -2270,7 +2270,7 @@ public class CacheClientProxy implements ClientSession {
         boolean createDurableQueue = proxy.proxyID.isDurable();
         boolean canHandleDelta = (proxy.clientVersion.compareTo(Version.GFE_61) >= 0)
             && InternalDistributedSystem.getAnyInstance().getConfig().getDeltaPropagation()
-            && !(this._proxy.clientConflation == HandShake.CONFLATION_ON);
+            && !(this._proxy.clientConflation == Handshake.CONFLATION_ON);
         if ((createDurableQueue || canHandleDelta) && logger.isDebugEnabled()) {
           logger.debug("Creating a durable HA queue");
         }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java
index 6590a8d..43894d7 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java
@@ -74,6 +74,7 @@ import org.apache.geode.internal.cache.GemFireCacheImpl;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.LocalRegion;
 import org.apache.geode.internal.cache.tier.CachedRegionHelper;
+import org.apache.geode.internal.cache.tier.ClientSideHandshake;
 import org.apache.geode.internal.cache.tier.MessageType;
 import org.apache.geode.internal.cache.versions.ConcurrentCacheModificationException;
 import org.apache.geode.internal.cache.versions.VersionSource;
@@ -263,15 +264,15 @@ public class CacheClientUpdater extends Thread implements ClientUpdater, Disconn
    *         exception while reading handshake/verifying credentials
    */
   public CacheClientUpdater(String name, ServerLocation location, boolean primary,
-      DistributedSystem ids, HandShake handshake, QueueManager qManager, EndpointManager eManager,
-      Endpoint endpoint, int handshakeTimeout, SocketCreator socketCreator)
-      throws AuthenticationRequiredException, AuthenticationFailedException,
-      ServerRefusedConnectionException {
+      DistributedSystem ids, ClientSideHandshake handshake, QueueManager qManager,
+      EndpointManager eManager, Endpoint endpoint, int handshakeTimeout,
+      SocketCreator socketCreator) throws AuthenticationRequiredException,
+      AuthenticationFailedException, ServerRefusedConnectionException {
 
     super(LoggingThreadGroup.createThreadGroup("Client update thread"), name);
     this.setDaemon(true);
     this.system = (InternalDistributedSystem) ids;
-    this.isDurableClient = handshake.getMembership().isDurable();
+    this.isDurableClient = handshake.getMembershipId().isDurable();
     this.isPrimary = primary;
     this.location = location;
     this.qManager = qManager;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientUpdateMessageImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientUpdateMessageImpl.java
index 9acc003..4ba0cd7 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientUpdateMessageImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientUpdateMessageImpl.java
@@ -39,12 +39,10 @@ import org.apache.geode.internal.InternalDataSerializer;
 import org.apache.geode.internal.Sendable;
 import org.apache.geode.internal.Version;
 import org.apache.geode.internal.cache.CachedDeserializableFactory;
-import org.apache.geode.internal.cache.EntryEventImpl;
 import org.apache.geode.internal.cache.EntryEventImpl.NewValueImporter;
 import org.apache.geode.internal.cache.EnumListenerEvent;
 import org.apache.geode.internal.cache.EventID;
 import org.apache.geode.internal.cache.LocalRegion;
-import org.apache.geode.internal.cache.Token;
 import org.apache.geode.internal.cache.WrappedCallbackArgument;
 import org.apache.geode.internal.cache.ha.HAContainerRegion;
 import org.apache.geode.internal.cache.tier.MessageType;
@@ -347,8 +345,8 @@ public class ClientUpdateMessageImpl implements ClientUpdateMessage, Sizeable, N
     byte[] serializedValue = null;
     Message message = null;
     boolean conflation = false;
-    conflation = (proxy.clientConflation == HandShake.CONFLATION_ON)
-        || (proxy.clientConflation == HandShake.CONFLATION_DEFAULT && this.shouldBeConflated());
+    conflation = (proxy.clientConflation == Handshake.CONFLATION_ON)
+        || (proxy.clientConflation == Handshake.CONFLATION_DEFAULT && this.shouldBeConflated());
 
     if (latestValue != null) {
       serializedValue = latestValue;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/HandShake.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/Handshake.java
similarity index 64%
rename from geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/HandShake.java
rename to geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/Handshake.java
index 4b1f2c7..055d0bc 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/HandShake.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/Handshake.java
@@ -14,13 +14,11 @@
  */
 package org.apache.geode.internal.cache.tier.sockets;
 
-import static org.apache.geode.distributed.ConfigurationProperties.CONFLATE_EVENTS;
 import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_CLIENT_AUTHENTICATOR;
 import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_CLIENT_AUTH_INIT;
 
 import java.io.ByteArrayInputStream;
 import java.io.DataInputStream;
-import java.io.DataOutput;
 import java.io.DataOutputStream;
 import java.io.EOFException;
 import java.io.FileInputStream;
@@ -43,13 +41,9 @@ import java.security.Signature;
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
 import java.security.spec.X509EncodedKeySpec;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
 import java.util.Properties;
 
 import javax.crypto.Cipher;
@@ -58,37 +52,30 @@ import javax.crypto.SecretKey;
 import javax.crypto.spec.DHParameterSpec;
 import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.SecretKeySpec;
-import javax.net.ssl.SSLSocket;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.logging.log4j.Logger;
 
-import org.apache.geode.CancelCriterion;
 import org.apache.geode.DataSerializer;
-import org.apache.geode.GemFireConfigException;
 import org.apache.geode.InternalGemFireException;
-import org.apache.geode.cache.GatewayConfigurationException;
 import org.apache.geode.cache.client.PoolFactory;
 import org.apache.geode.cache.client.ServerRefusedConnectionException;
-import org.apache.geode.cache.client.internal.Connection;
+import org.apache.geode.cache.client.internal.ClientSideHandshakeImpl;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.DistributedSystem;
 import org.apache.geode.distributed.internal.DistributionConfig;
-import org.apache.geode.distributed.internal.DistributionManager;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
-import org.apache.geode.distributed.internal.LonerDistributionManager;
-import org.apache.geode.distributed.internal.ServerLocation;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.internal.ClassLoadUtil;
 import org.apache.geode.internal.HeapDataOutputStream;
 import org.apache.geode.internal.InternalDataSerializer;
-import org.apache.geode.internal.InternalInstantiator;
 import org.apache.geode.internal.Version;
 import org.apache.geode.internal.VersionedDataInputStream;
 import org.apache.geode.internal.VersionedDataOutputStream;
-import org.apache.geode.internal.cache.tier.ClientHandShake;
 import org.apache.geode.internal.cache.tier.CommunicationMode;
 import org.apache.geode.internal.cache.tier.ConnectionProxy;
+import org.apache.geode.internal.cache.tier.Encryptor;
+import org.apache.geode.internal.cache.tier.ServerSideHandshake;
 import org.apache.geode.internal.i18n.LocalizedStrings;
 import org.apache.geode.internal.logging.InternalLogWriter;
 import org.apache.geode.internal.logging.LogService;
@@ -103,7 +90,7 @@ import org.apache.geode.security.AuthenticationRequiredException;
 import org.apache.geode.security.Authenticator;
 import org.apache.geode.security.GemFireSecurityException;
 
-public class HandShake implements ClientHandShake {
+public abstract class Handshake {
   private static final Logger logger = LogService.getLogger();
 
   protected static final byte REPLY_OK = (byte) 59;
@@ -123,27 +110,24 @@ public class HandShake implements ClientHandShake {
   protected static final byte REPLY_AUTH_NOT_REQUIRED = (byte) 66;
 
   public static final byte REPLY_SERVER_IS_LOCATOR = (byte) 67;
+  /**
+   * Test hook for client version support
+   *
+   * @since GemFire 5.7
+   */
+  protected static Version currentClientVersion = ConnectionProxy.VERSION;
 
-  private final SecurityService securityService;
-
-  private byte code;
-  private int clientReadTimeout = PoolFactory.DEFAULT_READ_TIMEOUT;
+  protected SecurityService securityService;
 
-  private boolean isRead = false;
-  protected final DistributedSystem system;
+  protected byte replyCode;
 
-  protected final ClientProxyMembershipID id;
+  protected int clientReadTimeout = PoolFactory.DEFAULT_READ_TIMEOUT;
 
-  private Properties credentials;
+  protected DistributedSystem system;
 
-  private Version clientVersion;
+  protected ClientProxyMembershipID id;
 
-  /**
-   * Used at client side, indicates whether the 'delta-propagation' property is enabled on the DS
-   * this client is connected to. This variable is used to decide whether to send delta bytes or
-   * full value to the server for a delta-update operation.
-   */
-  private static boolean deltaEnabledOnServer = true;
+  protected Properties credentials;
 
   // Security mode flags
 
@@ -164,8 +148,6 @@ public class HandShake implements ClientHandShake {
 
   private String clientSKAlgo = null;
 
-  private boolean multiuserSecureMode = false;
-
   // Parameters for the Diffie-Hellman key exchange
   private static final BigInteger dhP =
       new BigInteger("13528702063991073999718992897071702177131142188276542919088770094024269"
@@ -222,12 +204,12 @@ public class HandShake implements ClientHandShake {
   /** @since GemFire 5.7 */
   public static final byte CONFLATION_OFF = 2;
   /** @since GemFire 5.7 */
-  private byte clientConflation = CONFLATION_DEFAULT;
+  protected byte clientConflation = CONFLATION_DEFAULT;
 
   /**
    * @since GemFire 6.0.3 List of per client property override bits.
    */
-  private byte[] overrides = null;
+  private byte[] overrides;
 
   /**
    * Test hooks for per client conflation
@@ -237,157 +219,30 @@ public class HandShake implements ClientHandShake {
   public static byte clientConflationForTesting = 0;
   public static boolean setClientConflationForTesting = false;
 
-  /**
-   * Test hook for client version support
-   *
-   * @since GemFire 5.7
-   */
-  private static Version currentClientVersion = ConnectionProxy.VERSION;
-  /**
-   * Another test hook, holding a version ordinal that is higher than CURRENT
-   */
-  private static short overrideClientVersion = -1;
-
-  /** Constructor used for mocking */
-  protected HandShake() {
-    system = null;
-    id = null;
-    this.securityService = SecurityServiceFactory.create();
-  }
-
-  /**
-   * HandShake Constructor used by server side connection
-   */
-  public HandShake(Socket sock, int timeout, DistributedSystem sys, Version clientVersion,
-      CommunicationMode communicationMode, SecurityService securityService)
-      throws IOException, AuthenticationRequiredException {
-
-    this.clientVersion = clientVersion;
-    this.system = sys;
-    this.securityService = securityService;
-
-    {
-      int soTimeout = -1;
-      try {
-        soTimeout = sock.getSoTimeout();
-        sock.setSoTimeout(timeout);
-        InputStream is = sock.getInputStream();
-        int valRead = is.read();
-        // this.code = (byte)is.read();
-        if (valRead == -1) {
-          throw new EOFException(
-              LocalizedStrings.HandShake_HANDSHAKE_EOF_REACHED_BEFORE_CLIENT_CODE_COULD_BE_READ
-                  .toLocalizedString());
-        }
-        this.code = (byte) valRead;
-        if (this.code != REPLY_OK) {
-          throw new IOException(
-              LocalizedStrings.HandShake_HANDSHAKE_REPLY_CODE_IS_NOT_OK.toLocalizedString());
-        }
-        try {
-          DataInputStream dis = new DataInputStream(is);
-          DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
-          this.clientReadTimeout = dis.readInt();
-          if (clientVersion.compareTo(Version.CURRENT) < 0) {
-            // versioned streams allow object serialization code to deal with older clients
-            dis = new VersionedDataInputStream(dis, clientVersion);
-            dos = new VersionedDataOutputStream(dos, clientVersion);
-          }
-          this.id = ClientProxyMembershipID.readCanonicalized(dis);
-          // Note: credentials should always be the last piece in handshake for
-          // Diffie-Hellman key exchange to work
-          if (clientVersion.compareTo(Version.GFE_603) >= 0) {
-            setOverrides(new byte[] {dis.readByte()});
-          } else {
-            setClientConflation(dis.readByte());
-          }
-          // Hitesh
-          if (this.clientVersion.compareTo(Version.GFE_65) < 0 || communicationMode.isWAN()) {
-            this.credentials = readCredentials(dis, dos, sys, this.securityService);
-          } else {
-            this.credentials = this.readCredential(dis, dos, sys);
-          }
-        } catch (IOException ioe) {
-          this.code = -2;
-          throw ioe;
-        } catch (ClassNotFoundException cnfe) {
-          this.code = -3;
-          throw new IOException(
-              LocalizedStrings.HandShake_CLIENTPROXYMEMBERSHIPID_CLASS_COULD_NOT_BE_FOUND_WHILE_DESERIALIZING_THE_OBJECT
-                  .toLocalizedString());
-        }
-      } finally {
-        if (soTimeout != -1) {
-          try {
-            sock.setSoTimeout(soTimeout);
-          } catch (IOException ignore) {
-          }
-        }
-      }
-    }
-  }
-
-  public Version getClientVersion() {
-    return this.clientVersion;
-  }
-
-  /**
-   * Client-side handshake. This form of HandShake can communicate with a server
-   */
-  public HandShake(ClientProxyMembershipID id, DistributedSystem sys,
-      SecurityService securityService) {
-    this.id = id;
-    this.code = REPLY_OK;
-    this.system = sys;
-    setOverrides();
-    this.credentials = null;
-    this.securityService = securityService;
-  }
-
-  public void updateProxyID(InternalDistributedMember idm) {
-    this.id.updateID(idm);
-  }
+  /** Constructor used for subclasses */
+  protected Handshake() {}
 
   /**
    * Clone a HandShake to be used in creating other connections
    */
-  public HandShake(HandShake handShake) {
-    this.appSecureMode = handShake.appSecureMode;
-    this.clientConflation = handShake.clientConflation;
+  protected Handshake(Handshake handshake) {
+    this.appSecureMode = handshake.appSecureMode;
+    this.clientConflation = handshake.clientConflation;
     this.clientPublicKey = null;
-    this.clientReadTimeout = handShake.clientReadTimeout;
+    this.clientReadTimeout = handshake.clientReadTimeout;
     this.clientSKAlgo = null;
-    this.clientVersion = handShake.clientVersion;
-    this.code = handShake.code;
-    this.credentials = handShake.credentials;
-    this.isRead = handShake.isRead;
-    this.multiuserSecureMode = handShake.multiuserSecureMode;
-    this.overrides = handShake.overrides;
-    this.system = handShake.system;
-    this.id = handShake.id;
-    this.securityService = handShake.securityService;
+    this.replyCode = handshake.replyCode;
+    this.credentials = handshake.credentials;
+    this.overrides = handshake.overrides;
+    this.system = handshake.system;
+    this.id = handshake.id;
+    this.securityService = handshake.securityService;
     // create new one
     this._decrypt = null;
     this._encrypt = null;
   }
 
-  // used by the client side
-  private byte setClientConflation() {
-    byte result = CONFLATION_DEFAULT;
-
-    String clientConflationValue = this.system.getProperties().getProperty(CONFLATE_EVENTS);
-    if (DistributionConfig.CLIENT_CONFLATION_PROP_VALUE_ON
-        .equalsIgnoreCase(clientConflationValue)) {
-      result = CONFLATION_ON;
-    } else if (DistributionConfig.CLIENT_CONFLATION_PROP_VALUE_OFF
-        .equalsIgnoreCase(clientConflationValue)) {
-      result = CONFLATION_OFF;
-    }
-    return result;
-  }
-
-  // used by the server side
-  private void setClientConflation(byte value) {
+  protected void setClientConflation(byte value) {
     this.clientConflation = value;
     switch (this.clientConflation) {
       case CONFLATION_DEFAULT:
@@ -399,36 +254,13 @@ public class HandShake implements ClientHandShake {
     }
   }
 
-  // used by the client side
-  private void setOverrides() {
-    this.clientConflation = setClientConflation();
-
-    // As of May 2009 ( GFE 6.0 ):
-    // Note that this.clientVersion is used by server side for accepting
-    // handshakes.
-    // Client side handshake code uses this.currentClientVersion which can be
-    // set via tests.
-    if (HandShake.currentClientVersion.compareTo(Version.GFE_603) >= 0) {
-      byte override = 0;
-      /*
-       * override = this.notifyBySubscriptionOverride; override = (byte)((override << 2) |
-       * this.removeUnresponsiveClientOverride); override = (byte)((override << 2) |
-       * this.clientConflation);
-       */
-      override = this.clientConflation;
-      this.overrides = new byte[] {override};
-    }
+  protected byte[] getOverrides() {
+    return overrides;
   }
 
-  // used by the server side
-  private void setOverrides(byte[] values) {
+  protected void setOverrides(byte[] values) {
     byte override = values[0];
     setClientConflation(((byte) (override & 0x03)));
-    /*
-     * override = (byte)(override >>> 2); setRemoveUnresponsiveClientOverride(((byte)(override &
-     * 0x03))); override = (byte)(override >>> 2); setNotifyBySubscriptionOverride(((byte)(override
-     * & 0x03)));
-     */
   }
 
   // used by CacheClientNotifier's handshake reading code
@@ -442,116 +274,28 @@ public class HandShake implements ClientHandShake {
     return overrides;
   }
 
-  public static void setVersionForTesting(short ver) {
-    if (ver > Version.CURRENT_ORDINAL) {
-      overrideClientVersion = ver;
-    } else {
-      currentClientVersion = Version.fromOrdinalOrCurrent(ver);
-      overrideClientVersion = -1;
-    }
-  }
-
   /**
-   * client-to-server handshake. Nothing is sent to the server prior to invoking this method.
-   */
-  private byte write(DataOutputStream dos, DataInputStream dis, CommunicationMode communicationMode,
-      int replyCode, int readTimeout, List ports, Properties p_credentials,
-      DistributedMember member, boolean isCallbackConnection) throws IOException {
-    HeapDataOutputStream hdos = new HeapDataOutputStream(32, Version.CURRENT);
-    byte acceptanceCode = -1;
-    try {
-      hdos.writeByte(communicationMode.getModeNumber());
-      if (overrideClientVersion > 0) {
-        // for testing
-        Version.writeOrdinal(hdos, overrideClientVersion, true);
-      } else {
-        Version.writeOrdinal(hdos, currentClientVersion.ordinal(), true);
-      }
-
-      hdos.writeByte(replyCode);
-      if (ports != null) {
-        hdos.writeInt(ports.size());
-        for (int i = 0; i < ports.size(); i++) {
-          hdos.writeInt(Integer.parseInt((String) ports.get(i)));
-        }
-      } else {
-        hdos.writeInt(readTimeout);
-      }
-      // we do not know the receiver's version at this point, but the on-wire
-      // form of InternalDistributedMember changed in 9.0, so we must serialize
-      // it using the previous version
-      DataOutput idOut = new VersionedDataOutputStream(hdos, Version.GFE_82);
-      DataSerializer.writeObject(this.id, idOut);
-
-      if (currentClientVersion.compareTo(Version.GFE_603) >= 0) {
-        for (int bytes = 0; bytes < this.overrides.length; bytes++) {
-          hdos.writeByte(this.overrides[bytes]);
-        }
-      } else {
-        // write the client conflation setting byte
-        if (setClientConflationForTesting) {
-          hdos.writeByte(clientConflationForTesting);
-        } else {
-          hdos.writeByte(this.clientConflation);
-        }
-      }
-
-      if (isCallbackConnection || communicationMode.isWAN()) {
-        if (isCallbackConnection && this.multiuserSecureMode && !communicationMode.isWAN()) {
-          hdos.writeByte(SECURITY_MULTIUSER_NOTIFICATIONCHANNEL);
-          hdos.flush();
-          dos.write(hdos.toByteArray());
-          dos.flush();
-        } else {
-          writeCredentials(dos, dis, p_credentials, ports != null, member, hdos);
-        }
-      } else {
-        String authInitMethod = this.system.getProperties().getProperty(SECURITY_CLIENT_AUTH_INIT);
-        acceptanceCode = writeCredential(dos, dis, authInitMethod, ports != null, member, hdos);
-      }
-    } finally {
-      hdos.close();
-    }
-    return acceptanceCode;
-  }
-
-  public void writeCredentials(DataOutputStream dos, DataInputStream dis, Properties p_credentials,
-      boolean isNotification, DistributedMember member)
-      throws IOException, GemFireSecurityException {
-    HeapDataOutputStream hdos = new HeapDataOutputStream(32, Version.CURRENT);
-    try {
-      writeCredentials(dos, dis, p_credentials, isNotification, member, hdos);
-    } finally {
-      hdos.close();
-    }
-  }
-
-  /**
-   * This assumes that authentication is the last piece of info in handshake
+   * This method writes what readCredential() method expects to read. (Note the use of singular
+   * credential). It is similar to writeCredentials(), except that it doesn't write
+   * credential-properties.
+   *
+   * This is only used by the {@link ClientSideHandshakeImpl}.
    */
-  public void writeCredentials(DataOutputStream dos, DataInputStream dis, Properties p_credentials,
+  protected byte writeCredential(DataOutputStream dos, DataInputStream dis, String authInit,
       boolean isNotification, DistributedMember member, HeapDataOutputStream heapdos)
       throws IOException, GemFireSecurityException {
 
-    if (p_credentials == null) {
-      // No credentials indicator
-      heapdos.writeByte(CREDENTIALS_NONE);
-      heapdos.flush();
-      dos.write(heapdos.toByteArray());
-      dos.flush();
-      return;
-    }
-
     if (dhSKAlgo == null || dhSKAlgo.length() == 0) {
       // Normal credentials without encryption indicator
       heapdos.writeByte(CREDENTIALS_NORMAL);
-      DataSerializer.writeProperties(p_credentials, heapdos);
+      this.appSecureMode = CREDENTIALS_NORMAL;
+      // DataSerializer.writeProperties(p_credentials, heapdos);
       heapdos.flush();
       dos.write(heapdos.toByteArray());
       dos.flush();
-      return;
+      return -1;
     }
-
+    byte acceptanceCode = -1;
     try {
       InternalLogWriter securityLogWriter = (InternalLogWriter) this.system.getSecurityLogWriter();
       securityLogWriter.fine("HandShake: using Diffie-Hellman key exchange with algo " + dhSKAlgo);
@@ -563,6 +307,7 @@ public class HandShake implements ClientHandShake {
       }
       // Credentials with encryption indicator
       heapdos.writeByte(CREDENTIALS_DHENCRYPT);
+      this.appSecureMode = CREDENTIALS_DHENCRYPT;
       heapdos.writeBoolean(requireAuthentication);
       // Send the symmetric encryption algorithm name
       DataSerializer.writeString(dhSKAlgo, heapdos);
@@ -582,7 +327,7 @@ public class HandShake implements ClientHandShake {
       dos.flush();
 
       // Expect the alias and signature in the reply
-      byte acceptanceCode = dis.readByte();
+      acceptanceCode = dis.readByte();
       if (acceptanceCode != REPLY_OK && acceptanceCode != REPLY_AUTH_NOT_REQUIRED) {
         // Ignore the useless data
         dis.readByte();
@@ -617,20 +362,17 @@ public class HandShake implements ClientHandShake {
               .fine("HandShake: Successfully verified the " + "digital signature from server");
         }
 
-        byte[] challenge = DataSerializer.readByteArray(dis);
+        // Read server challenge bytes
+        byte[] serverChallenge = DataSerializer.readByteArray(dis);
         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
         KeyFactory keyFact = KeyFactory.getInstance("DH");
         // PublicKey pubKey = keyFact.generatePublic(x509KeySpec);
         this.clientPublicKey = keyFact.generatePublic(x509KeySpec);
 
-
-
         HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
         try {
-          DataSerializer.writeProperties(p_credentials, hdos);
-          // Also add the challenge string
-          DataSerializer.writeByteArray(challenge, hdos);
-
+          // Add the challenge string
+          DataSerializer.writeByteArray(serverChallenge, hdos);
           // byte[] encBytes = encrypt.doFinal(hdos.toByteArray());
           byte[] encBytes =
               encryptBytes(hdos.toByteArray(), getEncryptCipher(dhSKAlgo, this.clientPublicKey));
@@ -648,37 +390,46 @@ public class HandShake implements ClientHandShake {
           ex);
     }
     dos.flush();
+    return acceptanceCode;
+  }
+
+  public void writeCredentials(DataOutputStream dos, DataInputStream dis, Properties p_credentials,
+      boolean isNotification, DistributedMember member)
+      throws IOException, GemFireSecurityException {
+    HeapDataOutputStream hdos = new HeapDataOutputStream(32, Version.CURRENT);
+    try {
+      writeCredentials(dos, dis, p_credentials, isNotification, member, hdos);
+    } finally {
+      hdos.close();
+    }
   }
 
   /**
-   * This method writes what readCredential() method expects to read. (Note the use of singular
-   * credential). It is similar to writeCredentials(), except that it doesn't write
-   * credential-properties.
+   * This assumes that authentication is the last piece of info in handshake
    */
-  public byte writeCredential(DataOutputStream dos, DataInputStream dis, String authInit,
+  public void writeCredentials(DataOutputStream dos, DataInputStream dis, Properties p_credentials,
       boolean isNotification, DistributedMember member, HeapDataOutputStream heapdos)
       throws IOException, GemFireSecurityException {
 
-    if (!this.multiuserSecureMode && (authInit == null || authInit.length() == 0)) {
+    if (p_credentials == null) {
       // No credentials indicator
       heapdos.writeByte(CREDENTIALS_NONE);
       heapdos.flush();
       dos.write(heapdos.toByteArray());
       dos.flush();
-      return -1;
+      return;
     }
 
     if (dhSKAlgo == null || dhSKAlgo.length() == 0) {
       // Normal credentials without encryption indicator
       heapdos.writeByte(CREDENTIALS_NORMAL);
-      this.appSecureMode = CREDENTIALS_NORMAL;
-      // DataSerializer.writeProperties(p_credentials, heapdos);
+      DataSerializer.writeProperties(p_credentials, heapdos);
       heapdos.flush();
       dos.write(heapdos.toByteArray());
       dos.flush();
-      return -1;
+      return;
     }
-    byte acceptanceCode = -1;
+
     try {
       InternalLogWriter securityLogWriter = (InternalLogWriter) this.system.getSecurityLogWriter();
       securityLogWriter.fine("HandShake: using Diffie-Hellman key exchange with algo " + dhSKAlgo);
@@ -690,7 +441,6 @@ public class HandShake implements ClientHandShake {
       }
       // Credentials with encryption indicator
       heapdos.writeByte(CREDENTIALS_DHENCRYPT);
-      this.appSecureMode = CREDENTIALS_DHENCRYPT;
       heapdos.writeBoolean(requireAuthentication);
       // Send the symmetric encryption algorithm name
       DataSerializer.writeString(dhSKAlgo, heapdos);
@@ -710,7 +460,7 @@ public class HandShake implements ClientHandShake {
       dos.flush();
 
       // Expect the alias and signature in the reply
-      acceptanceCode = dis.readByte();
+      byte acceptanceCode = dis.readByte();
       if (acceptanceCode != REPLY_OK && acceptanceCode != REPLY_AUTH_NOT_REQUIRED) {
         // Ignore the useless data
         dis.readByte();
@@ -745,17 +495,20 @@ public class HandShake implements ClientHandShake {
               .fine("HandShake: Successfully verified the " + "digital signature from server");
         }
 
-        // Read server challenge bytes
-        byte[] serverChallenge = DataSerializer.readByteArray(dis);
+        byte[] challenge = DataSerializer.readByteArray(dis);
         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
         KeyFactory keyFact = KeyFactory.getInstance("DH");
         // PublicKey pubKey = keyFact.generatePublic(x509KeySpec);
         this.clientPublicKey = keyFact.generatePublic(x509KeySpec);
 
+
+
         HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
         try {
-          // Add the challenge string
-          DataSerializer.writeByteArray(serverChallenge, hdos);
+          DataSerializer.writeProperties(p_credentials, hdos);
+          // Also add the challenge string
+          DataSerializer.writeByteArray(challenge, hdos);
+
           // byte[] encBytes = encrypt.doFinal(hdos.toByteArray());
           byte[] encBytes =
               encryptBytes(hdos.toByteArray(), getEncryptCipher(dhSKAlgo, this.clientPublicKey));
@@ -773,7 +526,6 @@ public class HandShake implements ClientHandShake {
           ex);
     }
     dos.flush();
-    return acceptanceCode;
   }
 
   public byte[] encryptBytes(byte[] data) throws Exception {
@@ -971,8 +723,6 @@ public class HandShake implements ClientHandShake {
     }
   }
 
-
-
   public static byte[] decryptBytes(byte[] data, Cipher decrypt) throws Exception {
     try {
       byte[] decrptBytes = decrypt.doFinal(data);
@@ -1110,278 +860,6 @@ public class HandShake implements ClientHandShake {
     }
   }
 
-  public void accept(OutputStream out, InputStream in, byte epType, int qSize,
-      CommunicationMode communicationMode, Principal principal) throws IOException {
-    DataOutputStream dos = new DataOutputStream(out);
-    DataInputStream dis;
-    if (clientVersion.compareTo(Version.CURRENT) < 0) {
-      dis = new VersionedDataInputStream(in, clientVersion);
-      dos = new VersionedDataOutputStream(dos, clientVersion);
-    } else {
-      dis = new DataInputStream(in);
-    }
-    // Write ok reply
-    if (communicationMode.isWAN() && principal != null) {
-      dos.writeByte(REPLY_WAN_CREDENTIALS);
-    } else {
-      dos.writeByte(REPLY_OK);// byte 59
-    }
-
-
-    // additional byte of wan site needs to send for Gateway BC
-    if (communicationMode.isWAN()) {
-      Version.writeOrdinal(dos, ServerHandShakeProcessor.currentServerVersion.ordinal(), true);
-    }
-
-    dos.writeByte(epType);
-    dos.writeInt(qSize);
-
-    // Write the server's member
-    DistributedMember member = this.system.getDistributedMember();
-    ServerHandShakeProcessor.writeServerMember(member, dos);
-
-    // Write no message
-    dos.writeUTF("");
-
-    // Write delta-propagation property value if this is not WAN.
-    if (!communicationMode.isWAN() && this.clientVersion.compareTo(Version.GFE_61) >= 0) {
-      dos.writeBoolean(((InternalDistributedSystem) this.system).getConfig().getDeltaPropagation());
-    }
-
-    // Neeraj: Now if the communication mode is GATEWAY_TO_GATEWAY
-    // and principal not equal to null then send the credentials also
-    if (communicationMode.isWAN() && principal != null) {
-      sendCredentialsForWan(dos, dis);
-    }
-
-    // Write the distributed system id if this is a 6.6 or greater client
-    // on the remote side of the gateway
-    if (communicationMode.isWAN() && this.clientVersion.compareTo(Version.GFE_66) >= 0
-        && ServerHandShakeProcessor.currentServerVersion.compareTo(Version.GFE_66) >= 0) {
-      dos.writeByte(((InternalDistributedSystem) this.system).getDistributionManager()
-          .getDistributedSystemId());
-    }
-
-    if ((communicationMode.isWAN()) && this.clientVersion.compareTo(Version.GFE_80) >= 0
-        && ServerHandShakeProcessor.currentServerVersion.compareTo(Version.GFE_80) >= 0) {
-      int pdxSize = PeerTypeRegistration.getPdxRegistrySize();
-      dos.writeInt(pdxSize);
-    }
-
-    // Flush
-    dos.flush();
-  }
-
-  /**
-   * Return fake, temporary DistributedMember to represent the other vm this vm is connecting to
-   *
-   * @param sock the socket this handshake is operating on
-   * @return temporary id to reprent the other vm
-   */
-  private DistributedMember getIDForSocket(Socket sock) {
-    return new InternalDistributedMember(sock.getInetAddress(), sock.getPort(), false);
-  }
-
-  /**
-   * Client-side handshake with a Server
-   */
-  public ServerQueueStatus handshakeWithServer(Connection conn, ServerLocation location,
-      CommunicationMode communicationMode) throws IOException, AuthenticationRequiredException,
-      AuthenticationFailedException, ServerRefusedConnectionException {
-    try {
-      ServerQueueStatus serverQStatus = null;
-      Socket sock = conn.getSocket();
-      DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
-      final InputStream in = sock.getInputStream();
-      DataInputStream dis = new DataInputStream(in);
-      DistributedMember member = getIDForSocket(sock);
-      // if running in a loner system, use the new port number in the ID to
-      // help differentiate from other clients
-      DistributionManager dm = ((InternalDistributedSystem) this.system).getDistributionManager();
-      InternalDistributedMember idm = dm.getDistributionManagerId();
-      synchronized (idm) {
-        if (idm.getPort() == 0 && dm instanceof LonerDistributionManager) {
-          int port = sock.getLocalPort();
-          ((LonerDistributionManager) dm).updateLonerPort(port);
-          updateProxyID(dm.getDistributionManagerId());
-        }
-      }
-      if (communicationMode.isWAN()) {
-        this.credentials = getCredentials(member);
-      }
-      byte intermediateAcceptanceCode = write(dos, dis, communicationMode, REPLY_OK,
-          this.clientReadTimeout, null, this.credentials, member, false);
-
-      String authInit = this.system.getProperties().getProperty(SECURITY_CLIENT_AUTH_INIT);
-      if (!communicationMode.isWAN() && intermediateAcceptanceCode != REPLY_AUTH_NOT_REQUIRED
-          && (authInit != null && authInit.length() != 0)) {
-        location.compareAndSetRequiresCredentials(true);
-      }
-      // Read the acceptance code
-      byte acceptanceCode = dis.readByte();
-      if (acceptanceCode == (byte) 21 && !(sock instanceof SSLSocket)) {
-        // This is likely the case of server setup with SSL and client not using
-        // SSL
-        throw new AuthenticationRequiredException(
-            LocalizedStrings.HandShake_SERVER_EXPECTING_SSL_CONNECTION.toLocalizedString());
-      }
-      if (acceptanceCode == REPLY_SERVER_IS_LOCATOR) {
-        throw new GemFireConfigException("Improperly configured client detected.  " + "Server at "
-            + location + " is actually a locator.  Use addPoolLocator to configure locators.");
-      }
-
-      // Successful handshake for GATEWAY_TO_GATEWAY mode sets the peer version in connection
-      if (communicationMode.isWAN() && !(acceptanceCode == REPLY_EXCEPTION_AUTHENTICATION_REQUIRED
-          || acceptanceCode == REPLY_EXCEPTION_AUTHENTICATION_FAILED)) {
-        short wanSiteVersion = Version.readOrdinal(dis);
-        conn.setWanSiteVersion(wanSiteVersion);
-        // establish a versioned stream for the other site, if necessary
-        if (wanSiteVersion < Version.CURRENT_ORDINAL) {
-          dis = new VersionedDataInputStream(dis, Version.fromOrdinalOrCurrent(wanSiteVersion));
-        }
-      }
-
-      // No need to check for return value since DataInputStream already throws
-      // EOFException in case of EOF
-      byte epType = dis.readByte();
-      int qSize = dis.readInt();
-
-      // Read the server member
-      member = readServerMember(dis);
-      serverQStatus = new ServerQueueStatus(epType, qSize, member);
-
-      // Read the message (if any)
-      readMessage(dis, dos, acceptanceCode, member);
-
-      // Read delta-propagation property value from server.
-      // [sumedh] Static variable below? Client can connect to different
-      // DSes with different values of this. It shoule be a member variable.
-      if (!communicationMode.isWAN() && currentClientVersion.compareTo(Version.GFE_61) >= 0) {
-        deltaEnabledOnServer = dis.readBoolean();
-      }
-
-      // validate that the remote side has a different distributed system id.
-      if (communicationMode.isWAN() && Version.GFE_66.compareTo(conn.getWanSiteVersion()) <= 0
-          && currentClientVersion.compareTo(Version.GFE_66) >= 0) {
-        int remoteDistributedSystemId = in.read();
-        int localDistributedSystemId =
-            ((InternalDistributedSystem) system).getDistributionManager().getDistributedSystemId();
-        if (localDistributedSystemId >= 0
-            && localDistributedSystemId == remoteDistributedSystemId) {
-          throw new GatewayConfigurationException(
-              "Remote WAN site's distributed system id " + remoteDistributedSystemId
-                  + " matches this sites distributed system id " + localDistributedSystemId);
-        }
-      }
-      // Read the PDX registry size from the remote size
-      if (communicationMode.isWAN() && Version.GFE_80.compareTo(conn.getWanSiteVersion()) <= 0
-          && currentClientVersion.compareTo(Version.GFE_80) >= 0) {
-        int remotePdxSize = dis.readInt();
-        serverQStatus.setPdxSize(remotePdxSize);
-      }
-
-      return serverQStatus;
-    } catch (IOException ex) {
-      CancelCriterion stopper = this.system.getCancelCriterion();
-      stopper.checkCancelInProgress(null);
-      throw ex;
-    }
-  }
-
-  /**
-   * Used by client-side CacheClientUpdater to handshake with a server in order to receive messages
-   * generated by subscriptions (register-interest, continuous query)
-   */
-  public ServerQueueStatus handshakeWithSubscriptionFeed(Socket sock, boolean isPrimary)
-      throws IOException, AuthenticationRequiredException, AuthenticationFailedException,
-      ServerRefusedConnectionException, ClassNotFoundException {
-    ServerQueueStatus sqs = null;
-    try {
-      DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
-      final InputStream in = sock.getInputStream();
-      DataInputStream dis = new DataInputStream(in);
-      DistributedMember member = getIDForSocket(sock);
-      if (!this.multiuserSecureMode) {
-        this.credentials = getCredentials(member);
-      }
-      CommunicationMode mode = isPrimary ? CommunicationMode.PrimaryServerToClient
-          : CommunicationMode.SecondaryServerToClient;
-      write(dos, dis, mode, REPLY_OK, 0, new ArrayList(), this.credentials, member, true);
-
-      // Wait here for a reply before continuing. This ensures that the client
-      // updater is registered with the server before continuing.
-      byte acceptanceCode = dis.readByte();
-      if (acceptanceCode == (byte) 21 && !(sock instanceof SSLSocket)) {
-        // This is likely the case of server setup with SSL and client not using
-        // SSL
-        throw new AuthenticationRequiredException(
-            LocalizedStrings.HandShake_SERVER_EXPECTING_SSL_CONNECTION.toLocalizedString());
-      }
-
-      // No need to check for return value since DataInputStream already throws
-      // EOFException in case of EOF
-      byte qType = dis.readByte();
-      // read and ignore qSize flag
-      int qSize = dis.readInt();
-      sqs = new ServerQueueStatus(qType, qSize, member);
-
-      // Read the message (if any)
-      readMessage(dis, dos, acceptanceCode, member);
-
-      // [sumedh] nothing more to be done for older clients used in tests
-      // there is a difference in serializer map registration for >= 6.5.1.6
-      // clients but that is not used in tests
-      if (currentClientVersion.compareTo(Version.GFE_61) < 0) {
-        return sqs;
-      }
-      HashMap instantiatorMap = DataSerializer.readHashMap(dis);
-      for (Iterator itr = instantiatorMap.entrySet().iterator(); itr.hasNext();) {
-        Map.Entry instantiator = (Map.Entry) itr.next();
-        Integer id = (Integer) instantiator.getKey();
-        ArrayList instantiatorArguments = (ArrayList) instantiator.getValue();
-        InternalInstantiator.register((String) instantiatorArguments.get(0),
-            (String) instantiatorArguments.get(1), id, false);
-      }
-
-      HashMap dataSerializersMap = DataSerializer.readHashMap(dis);
-      for (Iterator itr = dataSerializersMap.entrySet().iterator(); itr.hasNext();) {
-        Map.Entry dataSerializer = (Map.Entry) itr.next();
-        Integer id = (Integer) dataSerializer.getKey();
-        InternalDataSerializer.register((String) dataSerializer.getValue(), false, null, null, id);
-      }
-      HashMap<Integer, ArrayList<String>> dsToSupportedClassNames = DataSerializer.readHashMap(dis);
-      InternalDataSerializer.updateSupportedClassesMap(dsToSupportedClassNames);
-    } catch (IOException ex) {
-      CancelCriterion stopper = this.system.getCancelCriterion();
-      stopper.checkCancelInProgress(null);
-      throw ex;
-    } catch (ClassNotFoundException ex) {
-      CancelCriterion stopper = this.system.getCancelCriterion();
-      stopper.checkCancelInProgress(null);
-      throw ex;
-    }
-    return sqs;
-  }
-
-  protected DistributedMember readServerMember(DataInputStream p_dis) throws IOException {
-
-    byte[] memberBytes = DataSerializer.readByteArray(p_dis);
-    ByteArrayInputStream bais = new ByteArrayInputStream(memberBytes);
-    DataInputStream dis = new DataInputStream(bais);
-    Version v = InternalDataSerializer.getVersionForDataStreamOrNull(p_dis);
-    if (v != null) {
-      dis = new VersionedDataInputStream(dis, v);
-    }
-    try {
-      return DataSerializer.readObject(dis);
-    } catch (EOFException e) {
-      throw e;
-    } catch (Exception e) {
-      throw new InternalGemFireException(
-          LocalizedStrings.HandShake_UNABLE_TO_DESERIALIZE_MEMBER.toLocalizedString(), e);
-    }
-  }
-
   protected void readMessage(DataInputStream dis, DataOutputStream dos, byte acceptanceCode,
       DistributedMember member) throws IOException, AuthenticationRequiredException,
       AuthenticationFailedException, ServerRefusedConnectionException {
@@ -1406,16 +884,8 @@ public class HandShake implements ClientHandShake {
     }
   }
 
-  public byte getCode() {
-    return this.code;
-  }
-
-  public boolean isRead() {
-    return this.isRead;
-  }
-
   public boolean isOK() {
-    return getCode() == REPLY_OK;
+    return this.replyCode == REPLY_OK;
   }
 
   public void setClientReadTimeout(int clientReadTimeout) {
@@ -1426,14 +896,6 @@ public class HandShake implements ClientHandShake {
     return this.clientReadTimeout;
   }
 
-  public void setMultiuserSecureMode(boolean bool) {
-    this.multiuserSecureMode = bool;
-  }
-
-  public boolean isMultiuserSecureMode() {
-    return this.multiuserSecureMode;
-  }
-
   /**
    * Indicates whether some other object is "equal to" this one.
    *
@@ -1445,35 +907,24 @@ public class HandShake implements ClientHandShake {
     if (other == this)
       return true;
     // if (other == null) return false;
-    if (!(other instanceof HandShake))
+    if (!(other instanceof Handshake))
       return false;
-    final HandShake that = (HandShake) other;
+    final Handshake that = (Handshake) other;
 
-    if (this.id.isSameDSMember(that.id) && this.code == that.code) {
+    if (this.id.isSameDSMember(that.id) && this.replyCode == that.replyCode) {
       return true;
     } else {
       return false;
     }
   }
 
-
-  /**
-   * Returns a hash code for the object. This method is supported for the benefit of hashtables such
-   * as those provided by java.util.Hashtable.
-   *
-   * @return the integer 0 if description is null; otherwise a unique integer.
-   */
   @Override
   public int hashCode() {
     int result = 17;
     final int mult = 37;
 
-    /*
-     * if (this.identity != null && this.identity.length > 0) { for (int i = 0; i <
-     * this.identity.length; i++) { result = mult * result + (int) this.identity[i]; } }
-     */
     result = this.id.hashCode();
-    result = mult * result + this.code;
+    result = mult * result + this.replyCode;
 
     return result;
   }
@@ -1481,18 +932,15 @@ public class HandShake implements ClientHandShake {
   @Override
   public String toString() {
     StringBuffer buf = new StringBuffer().append("HandShake@").append(System.identityHashCode(this))
-        .append(" code: ").append(this.code);
+        .append(" code: ").append(this.replyCode);
     if (this.id != null) {
       buf.append(" identity: ");
-      /*
-       * for(int i=0; i<this.identity.length; ++i) { buf.append(this.identity[i]); }
-       */
       buf.append(this.id.toString());
     }
     return buf.toString();
   }
 
-  public ClientProxyMembershipID getMembership() {
+  public ClientProxyMembershipID getMembershipId() {
     return this.id;
   }
 
@@ -1527,7 +975,7 @@ public class HandShake implements ClientHandShake {
     return credentials;
   }
 
-  private Properties getCredentials(DistributedMember member) {
+  protected Properties getCredentials(DistributedMember member) {
 
     String authInitMethod = this.system.getProperties().getProperty(SECURITY_CLIENT_AUTH_INIT);
     return getCredentials(authInitMethod, this.system.getSecurityProperties(), member, false,
@@ -1712,22 +1160,6 @@ public class HandShake implements ClientHandShake {
         this.securityService);
   }
 
-  public void sendCredentialsForWan(OutputStream out, InputStream in) {
-
-    try {
-      Properties wanCredentials = getCredentials(this.id.getDistributedMember());
-      DataOutputStream dos = new DataOutputStream(out);
-      DataInputStream dis = new DataInputStream(in);
-      writeCredentials(dos, dis, wanCredentials, false, this.system.getDistributedMember());
-    }
-    // The exception while getting the credentials is just logged as severe
-    catch (Exception e) {
-      this.system.getSecurityLogWriter().convertToLogWriterI18n().severe(
-          LocalizedStrings.HandShake_AN_EXCEPTION_WAS_THROWN_WHILE_SENDING_WAN_CREDENTIALS_0,
-          e.getLocalizedMessage());
-    }
-  }
-
   private void checkIfAuthenticWanSite(DataInputStream dis, DataOutputStream dos,
       DistributedMember member) throws GemFireSecurityException, IOException {
 
@@ -1786,16 +1218,4 @@ public class HandShake implements ClientHandShake {
     }
     return blocksize;
   }
-
-  public Version getVersion() {
-    return this.clientVersion;
-  }
-
-  public static boolean isDeltaEnabledOnServer() {
-    return deltaEnabledOnServer;
-  }
-
-  public boolean hasCredentials() {
-    return this.credentials != null;
-  }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/MessageIdExtractor.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/MessageIdExtractor.java
index 311c074..2cd5aca 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/MessageIdExtractor.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/MessageIdExtractor.java
@@ -15,11 +15,13 @@
  */
 package org.apache.geode.internal.cache.tier.sockets;
 
+import org.apache.geode.internal.cache.tier.Encryptor;
+import org.apache.geode.internal.cache.tier.ServerSideHandshake;
 import org.apache.geode.internal.i18n.LocalizedStrings;
 import org.apache.geode.security.AuthenticationRequiredException;
 
 public class MessageIdExtractor {
-  public long getUniqueIdFromMessage(Message requestMessage, HandShake handshake, long connectionId)
+  public long getUniqueIdFromMessage(Message requestMessage, Encryptor handshake, long connectionId)
       throws AuthenticationRequiredException {
     AuthIds aIds = getAuthIdsFromMessage(requestMessage, handshake);
     if (connectionId != aIds.getConnectionId()) {
@@ -29,7 +31,7 @@ public class MessageIdExtractor {
     return aIds.getUniqueId();
   }
 
-  private AuthIds getAuthIdsFromMessage(Message requestMessage, HandShake handshake)
+  private AuthIds getAuthIdsFromMessage(Message requestMessage, Encryptor handshake)
       throws AuthenticationRequiredException {
     try {
       byte[] secureBytes = requestMessage.getSecureBytes();
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerConnection.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerConnection.java
index 99919fa..4e86396 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerConnection.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerConnection.java
@@ -49,11 +49,11 @@ import org.apache.geode.internal.cache.EventID;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.tier.Acceptor;
 import org.apache.geode.internal.cache.tier.CachedRegionHelper;
-import org.apache.geode.internal.cache.tier.ClientHandShake;
 import org.apache.geode.internal.cache.tier.Command;
 import org.apache.geode.internal.cache.tier.CommunicationMode;
 import org.apache.geode.internal.cache.tier.InternalClientMembership;
 import org.apache.geode.internal.cache.tier.MessageType;
+import org.apache.geode.internal.cache.tier.ServerSideHandshake;
 import org.apache.geode.internal.cache.tier.sockets.command.Default;
 import org.apache.geode.internal.i18n.LocalizedStrings;
 import org.apache.geode.internal.logging.InternalLogWriter;
@@ -179,9 +179,9 @@ public abstract class ServerConnection implements Runnable {
   /**
    * Handshake reference uniquely identifying a client
    */
-  protected ClientHandShake handshake;
-  private int handShakeTimeout;
-  private final Object handShakeMonitor = new Object();
+  protected ServerSideHandshake handshake;
+  private int handshakeTimeout;
+  private final Object handshakeMonitor = new Object();
 
   /*
    * This timeout is request specific which come with message itself Otherwise, timeout which comes
@@ -292,7 +292,7 @@ public abstract class ServerConnection implements Runnable {
             getName(), communicationModeStr, socket.getInetAddress().getCanonicalHostName(),
             socket.getInetAddress().getHostAddress(), socket.getPort());
       }
-      this.handShakeTimeout = hsTimeout;
+      this.handshakeTimeout = hsTimeout;
     } catch (Exception e) {
       if (isDebugEnabled) {
         logger.debug("While creating server connection", e);
@@ -321,12 +321,13 @@ public abstract class ServerConnection implements Runnable {
   }
 
   private boolean verifyClientConnection() {
-    synchronized (this.handShakeMonitor) {
+    synchronized (this.handshakeMonitor) {
       if (this.handshake == null) {
         // synchronized (getCleanupTable()) {
-        boolean readHandShake =
-            ServerHandShakeProcessor.readHandShake(this, getSecurityService(), acceptor);
-        if (readHandShake) {
+        boolean readHandshake =
+            ServerHandshakeProcessor.readHandshake(this, getSecurityService(), acceptor);
+        if (readHandshake) {
+          // readHandshake will establish a handshake object in this ServerConnection
           if (this.handshake.isOK()) {
             try {
               return processHandShake();
@@ -339,12 +340,12 @@ public abstract class ServerConnection implements Runnable {
               return false;
             }
           } else {
+            // is this branch ever taken?
             this.crHelper.checkCancelInProgress(null); // bug 37113?
-            logger.warn(LocalizedMessage.create(
-                LocalizedStrings.ServerConnection_0_RECEIVED_UNKNOWN_HANDSHAKE_REPLY_CODE_1,
-                new Object[] {this.name, new Byte(this.handshake.getCode())}));
+            logger.warn(LocalizedMessage
+                .create(LocalizedStrings.ServerConnection_RECEIVED_UNKNOWN_HANDSHAKE_REPLY_CODE));
             refuseHandshake(LocalizedStrings.ServerConnection_RECEIVED_UNKNOWN_HANDSHAKE_REPLY_CODE
-                .toLocalizedString(), ServerHandShakeProcessor.REPLY_INVALID);
+                .toLocalizedString(), ServerHandshakeProcessor.REPLY_INVALID);
             return false;
           }
         } else {
@@ -352,7 +353,6 @@ public abstract class ServerConnection implements Runnable {
           cleanup();
           return false;
         }
-        // }
       }
     }
     return true;
@@ -367,7 +367,7 @@ public abstract class ServerConnection implements Runnable {
   }
 
   protected int getHandShakeTimeout() {
-    return this.handShakeTimeout;
+    return this.handshakeTimeout;
   }
 
   protected DistributedSystem getDistributedSystem() {
@@ -378,11 +378,11 @@ public abstract class ServerConnection implements Runnable {
     return this.crHelper.getCache();
   }
 
-  public ClientHandShake getHandshake() {
+  public ServerSideHandshake getHandshake() {
     return this.handshake;
   }
 
-  public void setHandshake(ClientHandShake handshake) {
+  public void setHandshake(ServerSideHandshake handshake) {
     this.handshake = handshake;
     Version v = handshake.getVersion();
 
@@ -508,7 +508,7 @@ public abstract class ServerConnection implements Runnable {
               logger.warn(LocalizedMessage.create(LocalizedStrings.TWO_ARG_COLON,
                   new Object[] {this.name, handshakeRefusalMessage}));
               refuseHandshake(handshakeRefusalMessage,
-                  HandShake.REPLY_EXCEPTION_DUPLICATE_DURABLE_CLIENT);
+                  Handshake.REPLY_EXCEPTION_DUPLICATE_DURABLE_CLIENT);
               return result;
             }
           }
@@ -583,7 +583,7 @@ public abstract class ServerConnection implements Runnable {
 
   protected void refuseHandshake(String msg, byte exception) {
     try {
-      ServerHandShakeProcessor.refuse(this.theSocket.getOutputStream(), msg, exception);
+      ServerHandshakeProcessor.refuse(this.theSocket.getOutputStream(), msg, exception);
     } catch (IOException ignore) {
     } finally {
       this.stats.incFailedConnectionAttempts();
@@ -620,7 +620,7 @@ public abstract class ServerConnection implements Runnable {
       try {
         byte[] secureBytes = this.requestMsg.getSecureBytes();
 
-        secureBytes = ((HandShake) this.handshake).decryptBytes(secureBytes);
+        secureBytes = ((Handshake) this.handshake).decryptBytes(secureBytes);
         AuthIds aIds = new AuthIds(secureBytes);
 
         long uniqueId = aIds.getUniqueId();
@@ -951,7 +951,7 @@ public abstract class ServerConnection implements Runnable {
     try {
       byte[] secureBytes = msg.getSecureBytes();
 
-      secureBytes = ((HandShake) this.handshake).decryptBytes(secureBytes);
+      secureBytes = ((Handshake) this.handshake).decryptBytes(secureBytes);
 
       // need to decrypt it first then get connectionid
       AuthIds aIds = new AuthIds(secureBytes);
@@ -1013,7 +1013,7 @@ public abstract class ServerConnection implements Runnable {
 
       byte[] secureBytes = msg.getSecureBytes();
 
-      secureBytes = ((HandShake) this.handshake).decryptBytes(secureBytes);
+      secureBytes = ((Handshake) this.handshake).decryptBytes(secureBytes);
 
       // need to decrypt it first then get connectionid
       AuthIds aIds = new AuthIds(secureBytes);
@@ -1026,7 +1026,7 @@ public abstract class ServerConnection implements Runnable {
 
       byte[] credBytes = msg.getPart(0).getSerializedForm();
 
-      credBytes = ((HandShake) this.handshake).decryptBytes(credBytes);
+      credBytes = ((Handshake) this.handshake).decryptBytes(credBytes);
 
       ByteArrayInputStream bis = new ByteArrayInputStream(credBytes);
       DataInputStream dinp = new DataInputStream(bis);
@@ -1039,7 +1039,7 @@ public abstract class ServerConnection implements Runnable {
       DistributedSystem system = this.getDistributedSystem();
       String methodName = system.getProperties().getProperty(SECURITY_CLIENT_AUTHENTICATOR);
 
-      Object principal = HandShake.verifyCredentials(methodName, credentials,
+      Object principal = Handshake.verifyCredentials(methodName, credentials,
           system.getSecurityProperties(), (InternalLogWriter) system.getLogWriter(),
           (InternalLogWriter) system.getSecurityLogWriter(), this.proxyId.getDistributedMember(),
           this.securityService);
@@ -1048,7 +1048,7 @@ public abstract class ServerConnection implements Runnable {
         uniqueId = this.clientUserAuths.putSubject(subject);
       } else {
         // this sets principal in map as well....
-        uniqueId = ServerHandShakeProcessor.getUniqueId(this, (Principal) principal);
+        uniqueId = ServerHandshakeProcessor.getUniqueId(this, (Principal) principal);
       }
 
       // create secure part which will be send in respones
@@ -1727,7 +1727,7 @@ public abstract class ServerConnection implements Runnable {
 
       hdos.writeLong(id);
 
-      return ((HandShake) this.handshake).encryptBytes(hdos.toByteArray());
+      return ((Handshake) this.handshake).encryptBytes(hdos.toByteArray());
     } finally {
       hdos.close();
     }
@@ -1740,7 +1740,7 @@ public abstract class ServerConnection implements Runnable {
       uniqueId = this.userAuthId;
     } else if (this.requestMsg.isSecureMode()) {
       uniqueId = messageIdExtractor.getUniqueIdFromMessage(this.requestMsg,
-          (HandShake) this.handshake, this.connectionId);
+          this.handshake.getEncryptor(), this.connectionId);
     } else {
       throw new AuthenticationRequiredException(
           LocalizedStrings.HandShake_NO_SECURITY_CREDENTIALS_ARE_PROVIDED.toLocalizedString());
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerHandShakeProcessor.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerHandshakeProcessor.java
similarity index 90%
rename from geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerHandShakeProcessor.java
rename to geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerHandshakeProcessor.java
index e292813..fcc8ac2 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerHandShakeProcessor.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerHandshakeProcessor.java
@@ -43,7 +43,7 @@ import org.apache.geode.internal.HeapDataOutputStream;
 import org.apache.geode.internal.Version;
 import org.apache.geode.internal.VersionedDataStream;
 import org.apache.geode.internal.cache.tier.Acceptor;
-import org.apache.geode.internal.cache.tier.CommunicationMode;
+import org.apache.geode.internal.cache.tier.ServerSideHandshake;
 import org.apache.geode.internal.i18n.LocalizedStrings;
 import org.apache.geode.internal.logging.InternalLogWriter;
 import org.apache.geode.internal.logging.LogService;
@@ -61,7 +61,7 @@ import org.apache.geode.security.AuthenticationRequiredException;
  */
 
 
-public class ServerHandShakeProcessor {
+public class ServerHandshakeProcessor {
   private static final Logger logger = LogService.getLogger();
 
   protected static final byte REPLY_REFUSED = (byte) 60;
@@ -70,22 +70,25 @@ public class ServerHandShakeProcessor {
 
   public static Version currentServerVersion = Acceptor.VERSION;
 
-  /**
-   * Test hook for server version support
-   *
-   * @since GemFire 5.7
-   */
-  public static void setSeverVersionForTesting(short ver) {
-    currentServerVersion = Version.fromOrdinalOrCurrent(ver);
-  }
-
-  public static boolean readHandShake(ServerConnection connection, SecurityService securityService,
+  public static boolean readHandshake(ServerConnection connection, SecurityService securityService,
       AcceptorImpl acceptorImpl) {
-    boolean validHandShake = false;
-    Version clientVersion = null;
     try {
       // Read the version byte from the socket
-      clientVersion = readClientVersion(connection);
+      Version clientVersion = readClientVersion(connection);
+
+      if (logger.isDebugEnabled()) {
+        logger.debug("Client version: {}", clientVersion);
+      }
+
+      // Read the appropriate handshake
+      if (clientVersion.compareTo(Version.GFE_57) >= 0) {
+        return readGFEHandshake(connection, clientVersion, securityService, acceptorImpl);
+      } else {
+        connection.refuseHandshake(
+            "Unsupported version " + clientVersion + "Server's current version " + Acceptor.VERSION,
+            REPLY_REFUSED);
+        return false;
+      }
     } catch (IOException e) {
       // Only log an exception if the server is still running.
       if (connection.getAcceptor().isRunning()) {
@@ -94,7 +97,6 @@ public class ServerHandShakeProcessor {
       }
       connection.stats.incFailedConnectionAttempts();
       connection.cleanup();
-      validHandShake = false;
     } catch (UnsupportedVersionException uve) {
       // Server logging
       logger.warn("{} {}", connection.getName(), uve.getMessage(), uve);
@@ -102,7 +104,6 @@ public class ServerHandShakeProcessor {
       connection.refuseHandshake(uve.getMessage(), REPLY_REFUSED);
       connection.stats.incFailedConnectionAttempts();
       connection.cleanup();
-      validHandShake = false;
     } catch (Exception e) {
       // Server logging
       logger.warn("{} {}", connection.getName(), e.getMessage(), e);
@@ -113,25 +114,9 @@ public class ServerHandShakeProcessor {
           REPLY_REFUSED);
       connection.stats.incFailedConnectionAttempts();
       connection.cleanup();
-      validHandShake = false;
     }
 
-    if (clientVersion != null) {
-
-      if (logger.isDebugEnabled())
-        logger.debug("Client version: {}", clientVersion);
-
-      // Read the appropriate handshake
-      if (clientVersion.compareTo(Version.GFE_57) >= 0) {
-        validHandShake = readGFEHandshake(connection, clientVersion, securityService, acceptorImpl);
-      } else {
-        connection.refuseHandshake(
-            "Unsupported version " + clientVersion + "Server's current version " + Acceptor.VERSION,
-            REPLY_REFUSED);
-      }
-    }
-
-    return validHandShake;
+    return false;
   }
 
   /**
@@ -201,16 +186,16 @@ public class ServerHandShakeProcessor {
 
   private static boolean readGFEHandshake(ServerConnection connection, Version clientVersion,
       SecurityService securityService, AcceptorImpl acceptorImpl) {
-    int handShakeTimeout = connection.getHandShakeTimeout();
+    int handshakeTimeout = connection.getHandShakeTimeout();
     InternalLogWriter securityLogWriter = connection.getSecurityLogWriter();
     try {
       Socket socket = connection.getSocket();
       DistributedSystem system = connection.getDistributedSystem();
       // hitesh:it will set credentials and principals
-      HandShake handshake = new HandShake(socket, handShakeTimeout, system, clientVersion,
-          connection.getCommunicationMode(), securityService);
+      ServerSideHandshake handshake = new ServerSideHandshakeImpl(socket, handshakeTimeout, system,
+          clientVersion, connection.getCommunicationMode(), securityService);
       connection.setHandshake(handshake);
-      ClientProxyMembershipID proxyId = handshake.getMembership();
+      ClientProxyMembershipID proxyId = handshake.getMembershipId();
       connection.setProxyId(proxyId);
       // hitesh: it gets principals
       // Hitesh:for older version we should set this
@@ -222,23 +207,17 @@ public class ServerHandShakeProcessor {
     } catch (SocketTimeoutException timeout) {
       logger.warn(LocalizedMessage.create(
           LocalizedStrings.ServerHandShakeProcessor_0_HANDSHAKE_REPLY_CODE_TIMEOUT_NOT_RECEIVED_WITH_IN_1_MS,
-          new Object[] {connection.getName(), Integer.valueOf(handShakeTimeout)}));
+          new Object[] {connection.getName(), Integer.valueOf(handshakeTimeout)}));
       connection.stats.incFailedConnectionAttempts();
       connection.cleanup();
       return false;
-    } catch (EOFException e) {
+    } catch (EOFException | SocketException e) {
       // no need to warn client just gave up on this server before we could
       // handshake
       logger.info("{} {}", connection.getName(), e);
       connection.stats.incFailedConnectionAttempts();
       connection.cleanup();
       return false;
-    } catch (SocketException e) { // no need to warn client just gave up on this
-      // server before we could handshake
-      logger.info("{} {}", connection.getName(), e);
-      connection.stats.incFailedConnectionAttempts();
-      connection.cleanup();
-      return false;
     } catch (IOException e) {
       logger.warn(LocalizedMessage.create(
           LocalizedStrings.ServerHandShakeProcessor_0_RECEIVED_NO_HANDSHAKE_REPLY_CODE,
@@ -257,7 +236,7 @@ public class ServerHandShakeProcessor {
       }
       connection.stats.incFailedConnectionAttempts();
       connection.refuseHandshake(noauth.getMessage(),
-          HandShake.REPLY_EXCEPTION_AUTHENTICATION_REQUIRED);
+          Handshake.REPLY_EXCEPTION_AUTHENTICATION_REQUIRED);
       connection.cleanup();
       return false;
     } catch (AuthenticationFailedException failed) {
@@ -271,7 +250,7 @@ public class ServerHandShakeProcessor {
       }
       connection.stats.incFailedConnectionAttempts();
       connection.refuseHandshake(failed.getMessage(),
-          HandShake.REPLY_EXCEPTION_AUTHENTICATION_FAILED);
+          Handshake.REPLY_EXCEPTION_AUTHENTICATION_FAILED);
       connection.cleanup();
       return false;
     } catch (Exception ex) {
@@ -287,7 +266,7 @@ public class ServerHandShakeProcessor {
   public static long setAuthAttributes(ServerConnection connection) throws Exception {
     try {
       logger.debug("setAttributes()");
-      Object principal = ((HandShake) connection.getHandshake()).verifyCredentials();
+      Object principal = ((Handshake) connection.getHandshake()).verifyCredentials();
 
       long uniqueId;
       if (principal instanceof Subject) {
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerSideHandshakeImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerSideHandshakeImpl.java
new file mode 100644
index 0000000..8d2f77a
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ServerSideHandshakeImpl.java
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.geode.internal.cache.tier.sockets;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.security.Principal;
+import java.util.Properties;
+
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.distributed.DistributedSystem;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.internal.Version;
+import org.apache.geode.internal.VersionedDataInputStream;
+import org.apache.geode.internal.VersionedDataOutputStream;
+import org.apache.geode.internal.cache.tier.CommunicationMode;
+import org.apache.geode.internal.cache.tier.Encryptor;
+import org.apache.geode.internal.cache.tier.ServerSideHandshake;
+import org.apache.geode.internal.i18n.LocalizedStrings;
+import org.apache.geode.internal.security.SecurityService;
+import org.apache.geode.pdx.internal.PeerTypeRegistration;
+import org.apache.geode.security.AuthenticationRequiredException;
+
+public class ServerSideHandshakeImpl extends Handshake implements ServerSideHandshake {
+  private Version clientVersion;
+
+  /**
+   * HandShake Constructor used by server side connection
+   */
+  public ServerSideHandshakeImpl(Socket sock, int timeout, DistributedSystem sys,
+      Version clientVersion, CommunicationMode communicationMode, SecurityService securityService)
+      throws IOException, AuthenticationRequiredException {
+
+    this.clientVersion = clientVersion;
+    this.system = sys;
+    this.securityService = securityService;
+
+    {
+      int soTimeout = -1;
+      try {
+        soTimeout = sock.getSoTimeout();
+        sock.setSoTimeout(timeout);
+        InputStream is = sock.getInputStream();
+        int valRead = is.read();
+        // this.code = (byte)is.read();
+        if (valRead == -1) {
+          throw new EOFException(
+              LocalizedStrings.HandShake_HANDSHAKE_EOF_REACHED_BEFORE_CLIENT_CODE_COULD_BE_READ
+                  .toLocalizedString());
+        }
+        this.replyCode = (byte) valRead;
+        if (this.replyCode != REPLY_OK) {
+          throw new IOException(
+              LocalizedStrings.HandShake_HANDSHAKE_REPLY_CODE_IS_NOT_OK.toLocalizedString());
+        }
+        try {
+          DataInputStream dis = new DataInputStream(is);
+          DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
+          this.clientReadTimeout = dis.readInt();
+          if (clientVersion.compareTo(Version.CURRENT) < 0) {
+            // versioned streams allow object serialization code to deal with older clients
+            dis = new VersionedDataInputStream(dis, clientVersion);
+            dos = new VersionedDataOutputStream(dos, clientVersion);
+          }
+          this.id = ClientProxyMembershipID.readCanonicalized(dis);
+          // Note: credentials should always be the last piece in handshake for
+          // Diffie-Hellman key exchange to work
+          if (clientVersion.compareTo(Version.GFE_603) >= 0) {
+            setOverrides(new byte[] {dis.readByte()});
+          } else {
+            setClientConflation(dis.readByte());
+          }
+          // Hitesh
+          if (this.clientVersion.compareTo(Version.GFE_65) < 0 || communicationMode.isWAN()) {
+            this.credentials = readCredentials(dis, dos, sys, this.securityService);
+          } else {
+            this.credentials = this.readCredential(dis, dos, sys);
+          }
+        } catch (IOException ioe) {
+          this.replyCode = -2;
+          throw ioe;
+        } catch (ClassNotFoundException cnfe) {
+          this.replyCode = -3;
+          throw new IOException(
+              LocalizedStrings.HandShake_CLIENTPROXYMEMBERSHIPID_CLASS_COULD_NOT_BE_FOUND_WHILE_DESERIALIZING_THE_OBJECT
+                  .toLocalizedString());
+        }
+      } finally {
+        if (soTimeout != -1) {
+          try {
+            sock.setSoTimeout(soTimeout);
+          } catch (IOException ignore) {
+          }
+        }
+      }
+    }
+  }
+
+  public Version getClientVersion() {
+    return this.clientVersion;
+  }
+
+  public Version getVersion() {
+    return this.clientVersion;
+  }
+
+  public void accept(OutputStream out, InputStream in, byte epType, int qSize,
+      CommunicationMode communicationMode, Principal principal) throws IOException {
+    DataOutputStream dos = new DataOutputStream(out);
+    DataInputStream dis;
+    if (clientVersion.compareTo(Version.CURRENT) < 0) {
+      dis = new VersionedDataInputStream(in, clientVersion);
+      dos = new VersionedDataOutputStream(dos, clientVersion);
+    } else {
+      dis = new DataInputStream(in);
+    }
+    // Write ok reply
+    if (communicationMode.isWAN() && principal != null) {
+      dos.writeByte(REPLY_WAN_CREDENTIALS);
+    } else {
+      dos.writeByte(REPLY_OK);// byte 59
+    }
+
+
+    // additional byte of wan site needs to send for Gateway BC
+    if (communicationMode.isWAN()) {
+      Version.writeOrdinal(dos, ServerHandshakeProcessor.currentServerVersion.ordinal(), true);
+    }
+
+    dos.writeByte(epType);
+    dos.writeInt(qSize);
+
+    // Write the server's member
+    DistributedMember member = this.system.getDistributedMember();
+    ServerHandshakeProcessor.writeServerMember(member, dos);
+
+    // Write no message
+    dos.writeUTF("");
+
+    // Write delta-propagation property value if this is not WAN.
+    if (!communicationMode.isWAN() && this.clientVersion.compareTo(Version.GFE_61) >= 0) {
+      dos.writeBoolean(((InternalDistributedSystem) this.system).getConfig().getDeltaPropagation());
+    }
+
+    // Neeraj: Now if the communication mode is GATEWAY_TO_GATEWAY
+    // and principal not equal to null then send the credentials also
+    if (communicationMode.isWAN() && principal != null) {
+      sendCredentialsForWan(dos, dis);
+    }
+
+    // Write the distributed system id if this is a 6.6 or greater client
+    // on the remote side of the gateway
+    if (communicationMode.isWAN() && this.clientVersion.compareTo(Version.GFE_66) >= 0
+        && ServerHandshakeProcessor.currentServerVersion.compareTo(Version.GFE_66) >= 0) {
+      dos.writeByte(((InternalDistributedSystem) this.system).getDistributionManager()
+          .getDistributedSystemId());
+    }
+
+    if ((communicationMode.isWAN()) && this.clientVersion.compareTo(Version.GFE_80) >= 0
+        && ServerHandshakeProcessor.currentServerVersion.compareTo(Version.GFE_80) >= 0) {
+      int pdxSize = PeerTypeRegistration.getPdxRegistrySize();
+      dos.writeInt(pdxSize);
+    }
+
+    // Flush
+    dos.flush();
+  }
+
+  @Override
+  public Encryptor getEncryptor() {
+    return this;
+  }
+
+  private void sendCredentialsForWan(OutputStream out, InputStream in) {
+    try {
+      Properties wanCredentials = getCredentials(this.id.getDistributedMember());
+      DataOutputStream dos = new DataOutputStream(out);
+      DataInputStream dis = new DataInputStream(in);
+      writeCredentials(dos, dis, wanCredentials, false, this.system.getDistributedMember());
+    }
+    // The exception while getting the credentials is just logged as severe
+    catch (Exception e) {
+      this.system.getSecurityLogWriter().convertToLogWriterI18n().severe(
+          LocalizedStrings.HandShake_AN_EXCEPTION_WAS_THROWN_WHILE_SENDING_WAN_CREDENTIALS_0,
+          e.getLocalizedMessage());
+    }
+  }
+
+  public int getClientReadTimeout() {
+    return this.clientReadTimeout;
+  }
+}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction.java
index e91da91..1ffadf3 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction.java
@@ -16,7 +16,6 @@ package org.apache.geode.internal.cache.tier.sockets.command;
 
 import java.io.IOException;
 import java.util.Collections;
-import java.util.Optional;
 import java.util.Set;
 
 import org.apache.geode.cache.LowMemoryException;
@@ -39,9 +38,10 @@ import org.apache.geode.internal.cache.execute.MemberMappedArgument;
 import org.apache.geode.internal.cache.execute.ServerToClientFunctionResultSender;
 import org.apache.geode.internal.cache.tier.Command;
 import org.apache.geode.internal.cache.tier.MessageType;
+import org.apache.geode.internal.cache.tier.ServerSideHandshake;
 import org.apache.geode.internal.cache.tier.sockets.BaseCommand;
 import org.apache.geode.internal.cache.tier.sockets.ChunkedMessage;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.cache.tier.sockets.Message;
 import org.apache.geode.internal.cache.tier.sockets.Part;
 import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
@@ -149,9 +149,9 @@ public class ExecuteFunction extends BaseCommand {
         context = new FunctionContextImpl(cache, functionObject.getId(), args, resultSender);
       }
 
-      HandShake handShake = (HandShake) serverConnection.getHandshake();
-      int earlierClientReadTimeout = handShake.getClientReadTimeout();
-      handShake.setClientReadTimeout(0);
+      Handshake handshake = (Handshake) serverConnection.getHandshake();
+      int earlierClientReadTimeout = handshake.getClientReadTimeout();
+      handshake.setClientReadTimeout(0);
       try {
         long startExecution = stats.startTime();
         stats.startFunctionExecution(functionObject.hasResult());
@@ -179,7 +179,7 @@ public class ExecuteFunction extends BaseCommand {
         stats.endFunctionExecutionWithException(functionObject.hasResult());
         throw new FunctionException(exception);
       } finally {
-        handShake.setClientReadTimeout(earlierClientReadTimeout);
+        handshake.setClientReadTimeout(earlierClientReadTimeout);
       }
     } catch (IOException ioException) {
       logger.warn(LocalizedMessage.create(
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction65.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction65.java
index 3c6272c..c8212cf 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction65.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction65.java
@@ -16,7 +16,6 @@ package org.apache.geode.internal.cache.tier.sockets.command;
 
 import java.io.IOException;
 import java.util.Collections;
-import java.util.Optional;
 import java.util.Set;
 
 import org.apache.geode.cache.LowMemoryException;
@@ -42,7 +41,7 @@ import org.apache.geode.internal.cache.tier.Command;
 import org.apache.geode.internal.cache.tier.MessageType;
 import org.apache.geode.internal.cache.tier.sockets.BaseCommand;
 import org.apache.geode.internal.cache.tier.sockets.ChunkedMessage;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.cache.tier.sockets.Message;
 import org.apache.geode.internal.cache.tier.sockets.Part;
 import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
@@ -180,9 +179,9 @@ public class ExecuteFunction65 extends BaseCommand {
             new FunctionContextImpl(cache, functionObject.getId(), args, resultSender, isReexecute);
       }
 
-      HandShake handShake = (HandShake) serverConnection.getHandshake();
-      int earlierClientReadTimeout = handShake.getClientReadTimeout();
-      handShake.setClientReadTimeout(0);
+      Handshake handshake = (Handshake) serverConnection.getHandshake();
+      int earlierClientReadTimeout = handshake.getClientReadTimeout();
+      handshake.setClientReadTimeout(0);
       try {
         long startExecution = stats.startTime();
         stats.startFunctionExecution(functionObject.hasResult());
@@ -220,7 +219,7 @@ public class ExecuteFunction65 extends BaseCommand {
         stats.endFunctionExecutionWithException(functionObject.hasResult());
         throw new FunctionException(exception);
       } finally {
-        handShake.setClientReadTimeout(earlierClientReadTimeout);
+        handshake.setClientReadTimeout(earlierClientReadTimeout);
       }
     } catch (IOException ioException) {
       logger.warn(LocalizedMessage.create(
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction66.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction66.java
index db20d50..5091ac2 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction66.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction66.java
@@ -53,7 +53,7 @@ import org.apache.geode.internal.cache.tier.Command;
 import org.apache.geode.internal.cache.tier.MessageType;
 import org.apache.geode.internal.cache.tier.sockets.BaseCommand;
 import org.apache.geode.internal.cache.tier.sockets.ChunkedMessage;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.cache.tier.sockets.Message;
 import org.apache.geode.internal.cache.tier.sockets.Part;
 import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
@@ -220,9 +220,9 @@ public class ExecuteFunction66 extends BaseCommand {
             new FunctionContextImpl(cache, functionObject.getId(), args, resultSender, isReexecute);
       }
 
-      HandShake handShake = (HandShake) serverConnection.getHandshake();
-      int earlierClientReadTimeout = handShake.getClientReadTimeout();
-      handShake.setClientReadTimeout(functionTimeout);
+      Handshake handshake = (Handshake) serverConnection.getHandshake();
+      int earlierClientReadTimeout = handshake.getClientReadTimeout();
+      handshake.setClientReadTimeout(functionTimeout);
       try {
         if (logger.isDebugEnabled()) {
           logger.debug("Executing Function on Server: {} with context: {}", serverConnection,
@@ -268,7 +268,7 @@ public class ExecuteFunction66 extends BaseCommand {
         stats.endFunctionExecutionWithException(functionObject.hasResult());
         throw new FunctionException(exception);
       } finally {
-        handShake.setClientReadTimeout(earlierClientReadTimeout);
+        handshake.setClientReadTimeout(earlierClientReadTimeout);
       }
     } catch (IOException ioException) {
       logger.warn(LocalizedMessage.create(
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction.java
index 289db3d..b6e9f06 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction.java
@@ -16,7 +16,6 @@ package org.apache.geode.internal.cache.tier.sockets.command;
 
 import java.io.IOException;
 import java.util.HashSet;
-import java.util.Optional;
 import java.util.Set;
 
 import org.apache.geode.cache.Region;
@@ -37,7 +36,7 @@ import org.apache.geode.internal.cache.tier.Command;
 import org.apache.geode.internal.cache.tier.MessageType;
 import org.apache.geode.internal.cache.tier.sockets.BaseCommand;
 import org.apache.geode.internal.cache.tier.sockets.ChunkedMessage;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.cache.tier.sockets.Message;
 import org.apache.geode.internal.cache.tier.sockets.Part;
 import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
@@ -137,9 +136,9 @@ public class ExecuteRegionFunction extends BaseCommand {
       return;
     }
 
-    HandShake handShake = (HandShake) serverConnection.getHandshake();
-    int earlierClientReadTimeout = handShake.getClientReadTimeout();
-    handShake.setClientReadTimeout(0);
+    Handshake handshake = (Handshake) serverConnection.getHandshake();
+    int earlierClientReadTimeout = handshake.getClientReadTimeout();
+    handshake.setClientReadTimeout(0);
     ServerToClientFunctionResultSender resultSender = null;
     Function<?> functionObject = null;
     try {
@@ -240,7 +239,7 @@ public class ExecuteRegionFunction extends BaseCommand {
       String message = e.getMessage();
       sendException(hasResult, clientMessage, message, serverConnection, e);
     } finally {
-      handShake.setClientReadTimeout(earlierClientReadTimeout);
+      handshake.setClientReadTimeout(earlierClientReadTimeout);
     }
   }
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction61.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction61.java
index 3421a5a..60d190b 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction61.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction61.java
@@ -17,7 +17,6 @@ package org.apache.geode.internal.cache.tier.sockets.command;
 
 import java.io.IOException;
 import java.util.HashSet;
-import java.util.Optional;
 import java.util.Set;
 
 import org.apache.geode.cache.Region;
@@ -39,7 +38,7 @@ import org.apache.geode.internal.cache.tier.Command;
 import org.apache.geode.internal.cache.tier.MessageType;
 import org.apache.geode.internal.cache.tier.sockets.BaseCommand;
 import org.apache.geode.internal.cache.tier.sockets.ChunkedMessage;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.cache.tier.sockets.Message;
 import org.apache.geode.internal.cache.tier.sockets.Part;
 import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
@@ -150,9 +149,9 @@ public class ExecuteRegionFunction61 extends BaseCommand {
         sendError(hasResult, clientMessage, message, serverConnection);
         return;
       }
-      HandShake handShake = (HandShake) serverConnection.getHandshake();
-      int earlierClientReadTimeout = handShake.getClientReadTimeout();
-      handShake.setClientReadTimeout(0);
+      Handshake handshake = (Handshake) serverConnection.getHandshake();
+      int earlierClientReadTimeout = handshake.getClientReadTimeout();
+      handshake.setClientReadTimeout(0);
       ServerToClientFunctionResultSender resultSender = null;
       Function<?> functionObject = null;
       try {
@@ -272,7 +271,7 @@ public class ExecuteRegionFunction61 extends BaseCommand {
       }
 
       finally {
-        handShake.setClientReadTimeout(earlierClientReadTimeout);
+        handshake.setClientReadTimeout(earlierClientReadTimeout);
       }
     }
   }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction65.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction65.java
index a78ec9b..e471e46 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction65.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction65.java
@@ -16,7 +16,6 @@ package org.apache.geode.internal.cache.tier.sockets.command;
 
 import java.io.IOException;
 import java.util.HashSet;
-import java.util.Optional;
 import java.util.Set;
 
 import org.apache.geode.cache.Region;
@@ -39,7 +38,7 @@ import org.apache.geode.internal.cache.tier.Command;
 import org.apache.geode.internal.cache.tier.MessageType;
 import org.apache.geode.internal.cache.tier.sockets.BaseCommand;
 import org.apache.geode.internal.cache.tier.sockets.ChunkedMessage;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.cache.tier.sockets.Message;
 import org.apache.geode.internal.cache.tier.sockets.Part;
 import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
@@ -156,9 +155,9 @@ public class ExecuteRegionFunction65 extends BaseCommand {
       return;
     }
 
-    HandShake handShake = (HandShake) serverConnection.getHandshake();
-    int earlierClientReadTimeout = handShake.getClientReadTimeout();
-    handShake.setClientReadTimeout(0);
+    Handshake handshake = (Handshake) serverConnection.getHandshake();
+    int earlierClientReadTimeout = handshake.getClientReadTimeout();
+    handshake.setClientReadTimeout(0);
     ServerToClientFunctionResultSender resultSender = null;
     Function<?> functionObject = null;
     try {
@@ -312,7 +311,7 @@ public class ExecuteRegionFunction65 extends BaseCommand {
       String message = e.getMessage();
       sendException(hasResult, clientMessage, message, serverConnection, e);
     } finally {
-      handShake.setClientReadTimeout(earlierClientReadTimeout);
+      handshake.setClientReadTimeout(earlierClientReadTimeout);
     }
   }
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction66.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction66.java
index 7882511..6876cfb 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction66.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction66.java
@@ -16,7 +16,6 @@ package org.apache.geode.internal.cache.tier.sockets.command;
 
 import java.io.IOException;
 import java.util.HashSet;
-import java.util.Optional;
 import java.util.Set;
 
 import org.apache.geode.cache.Region;
@@ -43,7 +42,7 @@ import org.apache.geode.internal.cache.tier.Command;
 import org.apache.geode.internal.cache.tier.MessageType;
 import org.apache.geode.internal.cache.tier.sockets.BaseCommand;
 import org.apache.geode.internal.cache.tier.sockets.ChunkedMessage;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.cache.tier.sockets.Message;
 import org.apache.geode.internal.cache.tier.sockets.Part;
 import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
@@ -175,9 +174,9 @@ public class ExecuteRegionFunction66 extends BaseCommand {
       sendError(hasResult, clientMessage, message, serverConnection);
       return;
     }
-    HandShake handShake = (HandShake) serverConnection.getHandshake();
-    int earlierClientReadTimeout = handShake.getClientReadTimeout();
-    handShake.setClientReadTimeout(functionTimeout);
+    Handshake handshake = (Handshake) serverConnection.getHandshake();
+    int earlierClientReadTimeout = handshake.getClientReadTimeout();
+    handshake.setClientReadTimeout(functionTimeout);
     ServerToClientFunctionResultSender resultSender = null;
     Function<?> functionObject = null;
     try {
@@ -335,7 +334,7 @@ public class ExecuteRegionFunction66 extends BaseCommand {
       String message = e.getMessage();
       sendException(hasResult, clientMessage, message, serverConnection, e);
     } finally {
-      handShake.setClientReadTimeout(earlierClientReadTimeout);
+      handshake.setClientReadTimeout(earlierClientReadTimeout);
       ServerConnection.executeFunctionOnLocalNodeOnly((byte) 0);
     }
   }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunctionSingleHop.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunctionSingleHop.java
index 44c661b..0652b4d 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunctionSingleHop.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunctionSingleHop.java
@@ -17,7 +17,6 @@ package org.apache.geode.internal.cache.tier.sockets.command;
 import java.io.IOException;
 import java.util.HashSet;
 import java.util.NoSuchElementException;
-import java.util.Optional;
 import java.util.Set;
 
 import org.apache.geode.cache.Region;
@@ -40,7 +39,7 @@ import org.apache.geode.internal.cache.tier.Command;
 import org.apache.geode.internal.cache.tier.MessageType;
 import org.apache.geode.internal.cache.tier.sockets.BaseCommand;
 import org.apache.geode.internal.cache.tier.sockets.ChunkedMessage;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.cache.tier.sockets.Message;
 import org.apache.geode.internal.cache.tier.sockets.Part;
 import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
@@ -179,9 +178,9 @@ public class ExecuteRegionFunctionSingleHop extends BaseCommand {
       sendError(hasResult, clientMessage, message, serverConnection);
       return;
     }
-    HandShake handShake = (HandShake) serverConnection.getHandshake();
-    int earlierClientReadTimeout = handShake.getClientReadTimeout();
-    handShake.setClientReadTimeout(functionTimeout);
+    Handshake handshake = (Handshake) serverConnection.getHandshake();
+    int earlierClientReadTimeout = handshake.getClientReadTimeout();
+    handshake.setClientReadTimeout(functionTimeout);
     ServerToClientFunctionResultSender resultSender = null;
     Function<?> functionObject = null;
     try {
@@ -320,7 +319,7 @@ public class ExecuteRegionFunctionSingleHop extends BaseCommand {
       String message = e.getMessage();
       sendException(hasResult, clientMessage, message, serverConnection, e);
     } finally {
-      handShake.setClientReadTimeout(earlierClientReadTimeout);
+      handshake.setClientReadTimeout(earlierClientReadTimeout);
       ServerConnection.executeFunctionOnLocalNodeOnly((byte) 0);
     }
   }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/i18n/LocalizedStrings.java b/geode-core/src/main/java/org/apache/geode/internal/i18n/LocalizedStrings.java
index ad8fa64..06b3643 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/i18n/LocalizedStrings.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/i18n/LocalizedStrings.java
@@ -1594,8 +1594,6 @@ public class LocalizedStrings {
   public static final StringId ServerConnection_0_HANDSHAKE_ACCEPT_FAILED_ON_SOCKET_1_2 =
       new StringId(1988, "{0}: Handshake accept failed on socket {1}: {2}");
 
-  public static final StringId ServerConnection_0_RECEIVED_UNKNOWN_HANDSHAKE_REPLY_CODE_1 =
-      new StringId(1991, "{0}: Received Unknown handshake reply code: {1}");
   public static final StringId ServerConnection_RECEIVED_UNKNOWN_HANDSHAKE_REPLY_CODE =
       new StringId(1992, "Received Unknown handshake reply code.");
   public static final StringId ServerConnection_0_UNEXPECTED_CANCELLATION =
diff --git a/geode-core/src/main/java/org/apache/geode/internal/tcp/Connection.java b/geode-core/src/main/java/org/apache/geode/internal/tcp/Connection.java
index 0532ab1..f106444 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/tcp/Connection.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/tcp/Connection.java
@@ -2301,12 +2301,12 @@ public class Connection implements Runnable {
                     LocalizedStrings.Connection_DETECTED_OLD_VERSION_PRE_5_0_1_OF_GEMFIRE_OR_NONGEMFIRE_DURING_HANDSHAKE_DUE_TO_INITIAL_BYTE_BEING_0
                         .toLocalizedString(new Byte(b)));
               }
-              byte handShakeByte = dis.readByte();
-              if (handShakeByte != HANDSHAKE_VERSION) {
+              byte handshakeByte = dis.readByte();
+              if (handshakeByte != HANDSHAKE_VERSION) {
                 throw new IllegalStateException(
                     LocalizedStrings.Connection_DETECTED_WRONG_VERSION_OF_GEMFIRE_PRODUCT_DURING_HANDSHAKE_EXPECTED_0_BUT_FOUND_1
                         .toLocalizedString(
-                            new Object[] {new Byte(HANDSHAKE_VERSION), new Byte(handShakeByte)}));
+                            new Object[] {new Byte(HANDSHAKE_VERSION), new Byte(handshakeByte)}));
               }
               InternalDistributedMember remote = DSFIDFactory.readInternalDistributedMember(dis);
               setRemoteAddr(remote);
@@ -3796,12 +3796,12 @@ public class Connection implements Runnable {
                       LocalizedStrings.Connection_DETECTED_OLD_VERSION_PRE_501_OF_GEMFIRE_OR_NONGEMFIRE_DURING_HANDSHAKE_DUE_TO_INITIAL_BYTE_BEING_0
                           .toLocalizedString(new Byte(b)));
                 }
-                byte handShakeByte = dis.readByte();
-                if (handShakeByte != HANDSHAKE_VERSION) {
+                byte handshakeByte = dis.readByte();
+                if (handshakeByte != HANDSHAKE_VERSION) {
                   throw new IllegalStateException(
                       LocalizedStrings.Connection_DETECTED_WRONG_VERSION_OF_GEMFIRE_PRODUCT_DURING_HANDSHAKE_EXPECTED_0_BUT_FOUND_1
                           .toLocalizedString(
-                              new Object[] {new Byte(HANDSHAKE_VERSION), new Byte(handShakeByte)}));
+                              new Object[] {new Byte(HANDSHAKE_VERSION), new Byte(handshakeByte)}));
                 }
                 InternalDistributedMember remote = DSFIDFactory.readInternalDistributedMember(dis);
                 setRemoteAddr(remote);
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/execute/ClientFunctionTimeoutRegressionTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/execute/ClientFunctionTimeoutRegressionTest.java
index 6de8616..1851b0e 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/execute/ClientFunctionTimeoutRegressionTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/execute/ClientFunctionTimeoutRegressionTest.java
@@ -51,7 +51,7 @@ import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.internal.AvailablePort;
 import org.apache.geode.internal.cache.CacheServerImpl;
 import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.internal.cache.tier.ClientHandShake;
+import org.apache.geode.internal.cache.tier.ServerSideHandshake;
 import org.apache.geode.internal.cache.tier.sockets.AcceptorImpl;
 import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
 import org.apache.geode.test.dunit.DistributedTestUtils;
@@ -204,7 +204,7 @@ public class ClientFunctionTimeoutRegressionTest extends JUnit4DistributedTestCa
           ((CacheServerImpl) serverCache.getCacheServers().get(0)).getAcceptor();
       ServerConnection[] scs = acceptor.getAllServerConnectionList();
       for (ServerConnection sc : scs) {
-        ClientHandShake hs = sc.getHandshake();
+        ServerSideHandshake hs = sc.getHandshake();
         if (hs != null && expected == hs.getClientReadTimeout()) {
           timeoutMatches = true;
         }
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/BackwardCompatibilityHigherVersionClientDUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/BackwardCompatibilityHigherVersionClientDUnitTest.java
index 3dedc01..eb5c1d9 100755
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/BackwardCompatibilityHigherVersionClientDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/BackwardCompatibilityHigherVersionClientDUnitTest.java
@@ -30,6 +30,7 @@ import org.apache.geode.cache.Region;
 import org.apache.geode.cache.RegionAttributes;
 import org.apache.geode.cache.Scope;
 import org.apache.geode.cache.client.PoolManager;
+import org.apache.geode.cache.client.internal.ClientSideHandshakeImpl;
 import org.apache.geode.cache.client.internal.ConnectionFactoryImpl;
 import org.apache.geode.cache.client.internal.PoolImpl;
 import org.apache.geode.cache.server.CacheServer;
@@ -169,7 +170,7 @@ public class BackwardCompatibilityHigherVersionClientDUnitTest extends JUnit4Dis
    * handshake.
    */
   public static void setHandshakeVersionForTesting() throws Exception {
-    HandShake.setVersionForTesting((short) (currentClientVersion + 1));
+    ClientSideHandshakeImpl.setVersionForTesting((short) (currentClientVersion + 1));
   }
 
   public static void addExceptions() throws Exception {
@@ -211,7 +212,7 @@ public class BackwardCompatibilityHigherVersionClientDUnitTest extends JUnit4Dis
    * handshake.
    */
   public static void unsetHandshakeVersionForTesting() throws Exception {
-    HandShake.setVersionForTesting(currentClientVersion);
+    ClientSideHandshakeImpl.setVersionForTesting(currentClientVersion);
   }
 
   /*
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/HandShakeTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/HandshakeTest.java
similarity index 86%
rename from geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/HandShakeTest.java
rename to geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/HandshakeTest.java
index 266ce43..82535dc 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/HandShakeTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/HandshakeTest.java
@@ -26,28 +26,28 @@ import org.apache.geode.security.AuthenticationRequiredException;
 import org.apache.geode.test.junit.categories.UnitTest;
 
 @Category(UnitTest.class)
-public class HandShakeTest {
+public class HandshakeTest {
 
   @Test
   public void authRequiredHasCredentials() throws Exception {
-    HandShake.throwIfMissingRequiredCredentials(true, true);
+    Handshake.throwIfMissingRequiredCredentials(true, true);
   }
 
   @Test
   public void authRequiredHasNoCredentials() throws Exception {
-    assertThatThrownBy(() -> HandShake.throwIfMissingRequiredCredentials(true, false))
+    assertThatThrownBy(() -> Handshake.throwIfMissingRequiredCredentials(true, false))
         .isExactlyInstanceOf(AuthenticationRequiredException.class)
         .hasMessage(HandShake_NO_SECURITY_CREDENTIALS_ARE_PROVIDED.toLocalizedString());
   }
 
   @Test
   public void authNotRequiredHasCredentials() throws Exception {
-    HandShake.throwIfMissingRequiredCredentials(false, true);
+    Handshake.throwIfMissingRequiredCredentials(false, true);
   }
 
   @Test
   public void authNotRequiredHasNoCredentials() throws Exception {
-    HandShake.throwIfMissingRequiredCredentials(false, false);
+    Handshake.throwIfMissingRequiredCredentials(false, false);
   }
 
 }
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/MessageIdExtractorTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/MessageIdExtractorTest.java
index acfd072..80aac2d 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/MessageIdExtractorTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/MessageIdExtractorTest.java
@@ -31,6 +31,7 @@ import org.junit.experimental.categories.Category;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import org.apache.geode.internal.cache.tier.Encryptor;
 import org.apache.geode.security.AuthenticationRequiredException;
 import org.apache.geode.test.junit.categories.UnitTest;
 
@@ -40,7 +41,7 @@ public class MessageIdExtractorTest {
   Message requestMessage;
 
   @Mock
-  HandShake handshake;
+  Encryptor encryptor;
 
   private MessageIdExtractor messageIdExtractor;
 
@@ -55,12 +56,12 @@ public class MessageIdExtractorTest {
 
     MockitoAnnotations.initMocks(this);
 
-    when(handshake.decryptBytes(any())).thenReturn(decryptedBytes);
+    when(encryptor.decryptBytes(any())).thenReturn(decryptedBytes);
   }
 
   @Test
   public void getUniqueIdFromMessage() throws Exception {
-    assertThat(messageIdExtractor.getUniqueIdFromMessage(requestMessage, handshake, connectionId))
+    assertThat(messageIdExtractor.getUniqueIdFromMessage(requestMessage, encryptor, connectionId))
         .isEqualTo(uniqueId);
   }
 
@@ -68,7 +69,7 @@ public class MessageIdExtractorTest {
   public void throwsWhenConnectionIdsDoNotMatch() throws Exception {
     long otherConnectionId = 789L;
 
-    assertThatThrownBy(() -> messageIdExtractor.getUniqueIdFromMessage(requestMessage, handshake,
+    assertThatThrownBy(() -> messageIdExtractor.getUniqueIdFromMessage(requestMessage, encryptor,
         otherConnectionId)).isInstanceOf(AuthenticationRequiredException.class);
   }
 
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ServerConnectionTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ServerConnectionTest.java
index 373ee67..d5f8baf 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ServerConnectionTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/ServerConnectionTest.java
@@ -52,7 +52,9 @@ import org.apache.geode.internal.cache.TXManagerImpl;
 import org.apache.geode.internal.cache.tier.Acceptor;
 import org.apache.geode.internal.cache.tier.CachedRegionHelper;
 import org.apache.geode.internal.cache.tier.CommunicationMode;
+import org.apache.geode.internal.cache.tier.Encryptor;
 import org.apache.geode.internal.cache.tier.MessageType;
+import org.apache.geode.internal.cache.tier.ServerSideHandshake;
 import org.apache.geode.internal.security.SecurityService;
 import org.apache.geode.security.AuthenticationRequiredException;
 import org.apache.geode.test.junit.categories.UnitTest;
@@ -73,7 +75,7 @@ public class ServerConnectionTest {
   private Message requestMsg;
 
   @Mock
-  private HandShake handshake;
+  private ServerSideHandshake handshake;
 
   @Mock
   private MessageIdExtractor messageIdExtractor;
@@ -141,7 +143,7 @@ public class ServerConnectionTest {
     assertThat(serverConnection.getRequestMessage()).isSameAs(requestMsg);
     when(requestMsg.isSecureMode()).thenReturn(true);
 
-    when(messageIdExtractor.getUniqueIdFromMessage(any(Message.class), any(HandShake.class),
+    when(messageIdExtractor.getUniqueIdFromMessage(any(Message.class), any(Encryptor.class),
         anyLong())).thenReturn(uniqueIdFromMessage);
     serverConnection.setMessageIdExtractor(messageIdExtractor);
 
@@ -215,11 +217,11 @@ public class ServerConnectionTest {
     protected void doHandshake() {
       ClientProxyMembershipID proxyID = mock(ClientProxyMembershipID.class);
       when(proxyID.getDistributedMember()).thenReturn(mock(InternalDistributedMember.class));
-      HandShake handShake = mock(HandShake.class);
-      when(handShake.getMembership()).thenReturn(proxyID);
-      when(handShake.getVersion()).thenReturn(Version.CURRENT);
+      ServerSideHandshake handshake = mock(ServerSideHandshake.class);
+      when(handshake.getMembershipId()).thenReturn(proxyID);
+      when(handshake.getVersion()).thenReturn(Version.CURRENT);
 
-      setHandshake(handShake);
+      setHandshake(handshake);
       setProxyId(proxyID);
 
       processHandShake();
@@ -229,7 +231,7 @@ public class ServerConnectionTest {
 
       long fakeId = -1;
       MessageIdExtractor extractor = mock(MessageIdExtractor.class);
-      when(extractor.getUniqueIdFromMessage(getRequestMessage(), handShake,
+      when(extractor.getUniqueIdFromMessage(getRequestMessage(), handshake,
           Connection.DEFAULT_CONNECTION_ID)).thenReturn(fakeId);
       setMessageIdExtractor(extractor);
     }
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction65Test.java b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction65Test.java
index eb35c11..1d11272 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction65Test.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction65Test.java
@@ -49,10 +49,11 @@ import org.apache.geode.internal.cache.control.InternalResourceManager;
 import org.apache.geode.internal.cache.tier.CachedRegionHelper;
 import org.apache.geode.internal.cache.tier.sockets.AcceptorImpl;
 import org.apache.geode.internal.cache.tier.sockets.ChunkedMessage;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.cache.tier.sockets.Message;
 import org.apache.geode.internal.cache.tier.sockets.Part;
 import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
+import org.apache.geode.internal.cache.tier.sockets.ServerSideHandshakeImpl;
 import org.apache.geode.internal.security.AuthorizeRequest;
 import org.apache.geode.internal.security.SecurityService;
 import org.apache.geode.management.internal.security.ResourcePermissions;
@@ -151,7 +152,7 @@ public class ExecuteFunction65Test {
         .thenReturn(this.functionResponseMessage);
     when(this.serverConnection.getChunkedResponseMessage()).thenReturn(this.chunkedResponseMessage);
     when(this.serverConnection.getAcceptor()).thenReturn(this.acceptor);
-    when(this.serverConnection.getHandshake()).thenReturn(mock(HandShake.class));
+    when(this.serverConnection.getHandshake()).thenReturn(mock(ServerSideHandshakeImpl.class));
 
     PowerMockito.mockStatic(FunctionService.class);
     PowerMockito.when(FunctionService.getFunction(eq(FUNCTION))).thenReturn(functionObject);
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction66Test.java b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction66Test.java
index 6546aa0..9f70e0e 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction66Test.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction66Test.java
@@ -47,9 +47,10 @@ import org.apache.geode.internal.cache.GemFireCacheImpl;
 import org.apache.geode.internal.cache.LocalRegion;
 import org.apache.geode.internal.cache.control.InternalResourceManager;
 import org.apache.geode.internal.cache.tier.CachedRegionHelper;
+import org.apache.geode.internal.cache.tier.ServerSideHandshake;
 import org.apache.geode.internal.cache.tier.sockets.AcceptorImpl;
 import org.apache.geode.internal.cache.tier.sockets.ChunkedMessage;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.cache.tier.sockets.Message;
 import org.apache.geode.internal.cache.tier.sockets.Part;
 import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
@@ -147,7 +148,7 @@ public class ExecuteFunction66Test {
         .thenReturn(this.functionResponseMessage);
     when(this.serverConnection.getReplyMessage()).thenReturn(this.replyMessage);
     when(this.serverConnection.getAcceptor()).thenReturn(this.acceptor);
-    when(this.serverConnection.getHandshake()).thenReturn(mock(HandShake.class));
+    when(this.serverConnection.getHandshake()).thenReturn(mock(ServerSideHandshake.class));
 
     PowerMockito.mockStatic(FunctionService.class);
     PowerMockito.when(FunctionService.getFunction(eq(FUNCTION))).thenReturn(this.functionObject);
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunctionTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunctionTest.java
index 3862880..f61b26a 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunctionTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunctionTest.java
@@ -47,9 +47,10 @@ import org.apache.geode.internal.cache.LocalRegion;
 import org.apache.geode.internal.cache.control.HeapMemoryMonitor;
 import org.apache.geode.internal.cache.control.InternalResourceManager;
 import org.apache.geode.internal.cache.tier.CachedRegionHelper;
+import org.apache.geode.internal.cache.tier.ServerSideHandshake;
 import org.apache.geode.internal.cache.tier.sockets.AcceptorImpl;
 import org.apache.geode.internal.cache.tier.sockets.ChunkedMessage;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.cache.tier.sockets.Message;
 import org.apache.geode.internal.cache.tier.sockets.Part;
 import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
@@ -101,7 +102,7 @@ public class ExecuteFunctionTest {
   @Mock
   private AcceptorImpl acceptor;
   @Mock
-  private HandShake handShake;
+  private ServerSideHandshake handshake;
   @Mock
   private InternalResourceManager internalResourceManager;
   @Mock
@@ -151,7 +152,7 @@ public class ExecuteFunctionTest {
         .thenReturn(this.functionResponseMessage);
     when(this.serverConnection.getChunkedResponseMessage()).thenReturn(this.chunkedResponseMessage);
     when(this.serverConnection.getAcceptor()).thenReturn(this.acceptor);
-    when(this.serverConnection.getHandshake()).thenReturn(this.handShake);
+    when(this.serverConnection.getHandshake()).thenReturn(this.handshake);
 
     PowerMockito.mockStatic(FunctionService.class);
     PowerMockito.when(FunctionService.getFunction(eq(FUNCTION))).thenReturn(functionObject);
diff --git a/geode-core/src/test/java/org/apache/geode/security/generator/LdapUserCredentialGenerator.java b/geode-core/src/test/java/org/apache/geode/security/generator/LdapUserCredentialGenerator.java
index 804ba32..bf80702 100755
--- a/geode-core/src/test/java/org/apache/geode/security/generator/LdapUserCredentialGenerator.java
+++ b/geode-core/src/test/java/org/apache/geode/security/generator/LdapUserCredentialGenerator.java
@@ -23,7 +23,7 @@ import java.util.Random;
 import org.apache.logging.log4j.Logger;
 
 import org.apache.geode.distributed.internal.DistributionConfig;
-import org.apache.geode.internal.cache.tier.sockets.HandShake;
+import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.security.templates.LdapUserAuthenticator;
 import org.apache.geode.security.templates.UserPasswordAuthInit;
@@ -68,9 +68,9 @@ public class LdapUserCredentialGenerator extends CredentialGenerator {
     if (serverAuthEnabled) {
       String keyStoreFile = TestUtil.getResourcePath(LdapUserCredentialGenerator.class,
           PKCSCredentialGenerator.keyStoreDir + "/gemfire1.keystore");
-      extraProps.setProperty(HandShake.PRIVATE_KEY_FILE_PROP, keyStoreFile);
-      extraProps.setProperty(HandShake.PRIVATE_KEY_ALIAS_PROP, DistributionConfig.GEMFIRE_PREFIX);
-      extraProps.setProperty(HandShake.PRIVATE_KEY_PASSWD_PROP, "gemfire");
+      extraProps.setProperty(Handshake.PRIVATE_KEY_FILE_PROP, keyStoreFile);
+      extraProps.setProperty(Handshake.PRIVATE_KEY_ALIAS_PROP, DistributionConfig.GEMFIRE_PREFIX);
+      extraProps.setProperty(Handshake.PRIVATE_KEY_PASSWD_PROP, "gemfire");
     }
 
     Assert.assertNotNull(extraProps.getProperty(LdapUserAuthenticator.LDAP_BASEDN_NAME));
@@ -105,8 +105,8 @@ public class LdapUserCredentialGenerator extends CredentialGenerator {
     if (serverAuthEnabled) {
       final String keyStoreFile = TestUtil.getResourcePath(PKCSCredentialGenerator.class,
           PKCSCredentialGenerator.keyStoreDir + "/publickeyfile");
-      props.setProperty(HandShake.PUBLIC_KEY_FILE_PROP, keyStoreFile);
-      props.setProperty(HandShake.PUBLIC_KEY_PASSWD_PROP, "gemfire");
+      props.setProperty(Handshake.PUBLIC_KEY_FILE_PROP, keyStoreFile);
+      props.setProperty(Handshake.PUBLIC_KEY_PASSWD_PROP, "gemfire");
     }
 
     return props;
@@ -143,8 +143,8 @@ public class LdapUserCredentialGenerator extends CredentialGenerator {
     if (serverAuthEnabled) {
       final String keyStoreFile = TestUtil.getResourcePath(PKCSCredentialGenerator.class,
           PKCSCredentialGenerator.keyStoreDir + "/publickeyfile");
-      props.setProperty(HandShake.PUBLIC_KEY_FILE_PROP, keyStoreFile);
-      props.setProperty(HandShake.PUBLIC_KEY_PASSWD_PROP, "gemfire");
+      props.setProperty(Handshake.PUBLIC_KEY_FILE_PROP, keyStoreFile);
+      props.setProperty(Handshake.PUBLIC_KEY_PASSWD_PROP, "gemfire");
     }
 
     return props;
@@ -160,8 +160,8 @@ public class LdapUserCredentialGenerator extends CredentialGenerator {
     if (serverAuthEnabled) {
       final String keyStoreFile = TestUtil.getResourcePath(PKCSCredentialGenerator.class,
           PKCSCredentialGenerator.keyStoreDir + "/publickeyfile");
-      props.setProperty(HandShake.PUBLIC_KEY_FILE_PROP, keyStoreFile);
-      props.setProperty(HandShake.PUBLIC_KEY_PASSWD_PROP, "gemfire");
+      props.setProperty(Handshake.PUBLIC_KEY_FILE_PROP, keyStoreFile);
+      props.setProperty(Handshake.PUBLIC_KEY_PASSWD_PROP, "gemfire");
     }
 
     return props;

-- 
To stop receiving notification emails like this one, please contact
bschuchardt@apache.org.

[geode] 02/03: checkpoint - readMessage refactoring

Posted by bs...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

bschuchardt pushed a commit to branch feature/GEODE-4439
in repository https://gitbox.apache.org/repos/asf/geode.git

commit 4cd5b90a9aac07d7a2b7daabde65b79a09ce2bce
Author: Bruce Schuchardt <bs...@pivotal.io>
AuthorDate: Tue Jan 30 15:28:17 2018 -0800

    checkpoint - readMessage refactoring
---
 .../internal/InternalDistributedSystem.java        |   7 +-
 .../internal/cache/tier/sockets/EncryptorImpl.java | 791 +++++++++++++++++++++
 .../internal/cache/tier/sockets/Handshake.java     | 740 +------------------
 3 files changed, 807 insertions(+), 731 deletions(-)

diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java
index f16c630..acf1b2e 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java
@@ -87,6 +87,7 @@ import org.apache.geode.internal.cache.GemFireCacheImpl;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.execute.FunctionServiceStats;
 import org.apache.geode.internal.cache.execute.FunctionStats;
+import org.apache.geode.internal.cache.tier.sockets.EncryptorImpl;
 import org.apache.geode.internal.cache.tier.sockets.Handshake;
 import org.apache.geode.internal.cache.xmlcache.CacheServerCreation;
 import org.apache.geode.internal.i18n.LocalizedStrings;
@@ -691,9 +692,9 @@ public class InternalDistributedSystem extends DistributedSystem
 
       // Initialize the Diffie-Hellman and public/private keys
       try {
-        Handshake.initCertsMap(this.config.getSecurityProps());
-        Handshake.initPrivateKey(this.config.getSecurityProps());
-        Handshake.initDHKeys(this.config);
+        EncryptorImpl.initCertsMap(this.config.getSecurityProps());
+        EncryptorImpl.initPrivateKey(this.config.getSecurityProps());
+        EncryptorImpl.initDHKeys(this.config);
       } catch (Exception ex) {
         throw new GemFireSecurityException(
             LocalizedStrings.InternalDistributedSystem_PROBLEM_IN_INITIALIZING_KEYS_FOR_CLIENT_AUTHENTICATION
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/EncryptorImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/EncryptorImpl.java
new file mode 100644
index 0000000..c6e73bf
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/EncryptorImpl.java
@@ -0,0 +1,791 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.geode.internal.cache.tier.sockets;
+
+import static org.apache.geode.internal.cache.tier.sockets.Handshake.CREDENTIALS_DHENCRYPT;
+import static org.apache.geode.internal.cache.tier.sockets.Handshake.PRIVATE_KEY_ALIAS_PROP;
+import static org.apache.geode.internal.cache.tier.sockets.Handshake.PRIVATE_KEY_FILE_PROP;
+import static org.apache.geode.internal.cache.tier.sockets.Handshake.PRIVATE_KEY_PASSWD_PROP;
+import static org.apache.geode.internal.cache.tier.sockets.Handshake.PUBLIC_KEY_FILE_PROP;
+import static org.apache.geode.internal.cache.tier.sockets.Handshake.PUBLIC_KEY_PASSWD_PROP;
+import static org.apache.geode.internal.cache.tier.sockets.Handshake.REPLY_AUTH_NOT_REQUIRED;
+import static org.apache.geode.internal.cache.tier.sockets.Handshake.REPLY_OK;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Properties;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyAgreement;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.geode.DataSerializer;
+import org.apache.geode.LogWriter;
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.distributed.DistributedSystem;
+import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.internal.HeapDataOutputStream;
+import org.apache.geode.internal.Version;
+import org.apache.geode.internal.cache.tier.Encryptor;
+import org.apache.geode.internal.i18n.LocalizedStrings;
+import org.apache.geode.internal.logging.InternalLogWriter;
+import org.apache.geode.security.AuthenticationFailedException;
+import org.apache.geode.security.GemFireSecurityException;
+
+public class EncryptorImpl implements Encryptor{
+  // Parameters for the Diffie-Hellman key exchange
+  private static final BigInteger dhP =
+      new BigInteger("13528702063991073999718992897071702177131142188276542919088770094024269"
+          + "73079899070080419278066109785292538223079165925365098181867673946"
+          + "34756714063947534092593553024224277712367371302394452615862654308"
+          + "11180902979719649450105660478776364198726078338308557022096810447"
+          + "3500348898008043285865193451061481841186553");
+
+  private static final BigInteger dhG =
+      new BigInteger("13058345680719715096166513407513969537624553636623932169016704425008150"
+          + "56576152779768716554354314319087014857769741104157332735258102835"
+          + "93126577393912282416840649805564834470583437473176415335737232689"
+          + "81480201869671811010996732593655666464627559582258861254878896534"
+          + "1273697569202082715873518528062345259949959");
+
+  private static final int dhL = 1023;
+
+  private Cipher _encrypt;
+  private Cipher _decrypt = null;
+
+  private PublicKey clientPublicKey = null;
+
+  private String clientSKAlgo = null;
+
+  private static PrivateKey dhPrivateKey = null;
+
+  private static PublicKey dhPublicKey = null;
+
+  private static String dhSKAlgo = null;
+
+  // Members for server authentication using digital signature
+
+  private static String certificateFilePath = null;
+
+  private static HashMap certificateMap = null;
+
+  private static String privateKeyAlias = null;
+
+  private static String privateKeySubject = null;
+
+  private static PrivateKey privateKeyEncrypt = null;
+
+  private static String privateKeySignAlgo = null;
+
+  private static SecureRandom random = null;
+
+  private byte appSecureMode = (byte) 0;
+
+  private LogWriter logWriter;
+
+
+  EncryptorImpl(EncryptorImpl encryptor) {
+    this.appSecureMode = encryptor.appSecureMode;
+  }
+
+  EncryptorImpl(LogWriter logWriter) {
+    this.logWriter = logWriter;
+  }
+
+
+  void setAppSecureMode(byte appSecureMode) {
+    this.appSecureMode = appSecureMode;
+  }
+
+  public static byte[] decryptBytes(byte[] data, Cipher decrypt) throws Exception {
+      return decrypt.doFinal(data);
+  }
+
+  protected Cipher getDecryptCipher(String dhSKAlgo, PublicKey publicKey) throws Exception {
+    if (_decrypt == null) {
+      try {
+        KeyAgreement ka = KeyAgreement.getInstance("DH");
+        ka.init(dhPrivateKey);
+        ka.doPhase(publicKey, true);
+
+        Cipher decrypt;
+
+        int keysize = getKeySize(dhSKAlgo);
+        int blocksize = getBlockSize(dhSKAlgo);
+
+        if (keysize == -1 || blocksize == -1) {
+          SecretKey sKey = ka.generateSecret(dhSKAlgo);
+          decrypt = Cipher.getInstance(dhSKAlgo);
+          decrypt.init(Cipher.DECRYPT_MODE, sKey);
+        } else {
+          String algoStr = getDhAlgoStr(dhSKAlgo);
+
+          byte[] sKeyBytes = ka.generateSecret();
+          SecretKeySpec sks = new SecretKeySpec(sKeyBytes, 0, keysize, algoStr);
+          IvParameterSpec ivps = new IvParameterSpec(sKeyBytes, keysize, blocksize);
+
+          decrypt = Cipher.getInstance(algoStr + "/CBC/PKCS5Padding");
+          decrypt.init(Cipher.DECRYPT_MODE, sks, ivps);
+        }
+
+        _decrypt = decrypt;
+      } catch (Exception ex) {
+        throw ex;
+      }
+    }
+    return _decrypt;
+  }
+
+  /**
+   * Populate the available server public keys into a local static HashMap. This method is not
+   * thread safe.
+   */
+  public static void initCertsMap(Properties props) throws Exception {
+
+    certificateMap = new HashMap();
+    certificateFilePath = props.getProperty(PUBLIC_KEY_FILE_PROP);
+    if (certificateFilePath != null && certificateFilePath.length() > 0) {
+      KeyStore ks = KeyStore.getInstance("JKS");
+      String keyStorePass = props.getProperty(PUBLIC_KEY_PASSWD_PROP);
+      char[] passPhrase = (keyStorePass != null ? keyStorePass.toCharArray() : null);
+      FileInputStream keystorefile = new FileInputStream(certificateFilePath);
+      try {
+        ks.load(keystorefile, passPhrase);
+      } finally {
+        keystorefile.close();
+      }
+      Enumeration aliases = ks.aliases();
+      while (aliases.hasMoreElements()) {
+        String alias = (String) aliases.nextElement();
+        Certificate cert = ks.getCertificate(alias);
+        if (cert instanceof X509Certificate) {
+          String subject = ((X509Certificate) cert).getSubjectDN().getName();
+          certificateMap.put(subject, cert);
+        }
+      }
+    }
+  }
+
+  /**
+   * Load the private key of the server. This method is not thread safe.
+   */
+  public static void initPrivateKey(Properties props) throws Exception {
+
+    String privateKeyFilePath = props.getProperty(PRIVATE_KEY_FILE_PROP);
+    privateKeyAlias = "";
+    privateKeyEncrypt = null;
+    if (privateKeyFilePath != null && privateKeyFilePath.length() > 0) {
+      KeyStore ks = KeyStore.getInstance("PKCS12");
+      privateKeyAlias = props.getProperty(PRIVATE_KEY_ALIAS_PROP);
+      if (privateKeyAlias == null) {
+        privateKeyAlias = "";
+      }
+      String keyStorePass = props.getProperty(PRIVATE_KEY_PASSWD_PROP);
+      char[] passPhrase = (keyStorePass != null ? keyStorePass.toCharArray() : null);
+      FileInputStream privateKeyFile = new FileInputStream(privateKeyFilePath);
+      try {
+        ks.load(privateKeyFile, passPhrase);
+      } finally {
+        privateKeyFile.close();
+      }
+      Key key = ks.getKey(privateKeyAlias, passPhrase);
+      Certificate keyCert = ks.getCertificate(privateKeyAlias);
+      if (key instanceof PrivateKey && keyCert instanceof X509Certificate) {
+        privateKeyEncrypt = (PrivateKey) key;
+        privateKeySignAlgo = ((X509Certificate) keyCert).getSigAlgName();
+        privateKeySubject = ((X509Certificate) keyCert).getSubjectDN().getName();
+      }
+    }
+  }
+
+  /**
+   * Initialize the Diffie-Hellman keys. This method is not thread safe
+   */
+  public static void initDHKeys(DistributionConfig config) throws Exception {
+
+    dhSKAlgo = config.getSecurityClientDHAlgo();
+    dhPrivateKey = null;
+    dhPublicKey = null;
+    // Initialize the keys when either the host is a client that has
+    // non-blank setting for DH symmetric algo, or this is a server
+    // that has authenticator defined.
+    if ((dhSKAlgo != null
+        && dhSKAlgo.length() > 0) /* || securityService.isClientSecurityRequired() */) {
+      KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH");
+      DHParameterSpec dhSpec = new DHParameterSpec(dhP, dhG, dhL);
+      keyGen.initialize(dhSpec);
+      KeyPair keypair = keyGen.generateKeyPair();
+
+      // Get the generated public and private keys
+      dhPrivateKey = keypair.getPrivate();
+      dhPublicKey = keypair.getPublic();
+
+      random = new SecureRandom();
+      // Force the random generator to seed itself.
+      byte[] someBytes = new byte[48];
+      random.nextBytes(someBytes);
+    }
+  }
+
+  public byte[] decryptBytes(byte[] data) throws Exception {
+    if (this.appSecureMode == CREDENTIALS_DHENCRYPT) {
+      String algo = null;
+      if (this.clientSKAlgo != null) {
+        algo = this.clientSKAlgo;
+      } else {
+        algo = dhSKAlgo;
+      }
+      Cipher c = getDecryptCipher(algo, this.clientPublicKey);
+      return decryptBytes(data, c);
+    } else {
+      return data;
+    }
+  }
+
+
+
+  public byte[] encryptBytes(byte[] data) throws Exception {
+    if (this.appSecureMode == CREDENTIALS_DHENCRYPT) {
+      String algo = null;
+      if (this.clientSKAlgo != null) {
+        algo = this.clientSKAlgo;
+      } else {
+        algo = dhSKAlgo;
+      }
+      return encryptBytes(data, getEncryptCipher(algo, this.clientPublicKey));
+    } else {
+      return data;
+    }
+  }
+
+  public static byte[] encryptBytes(byte[] data, Cipher encrypt) throws Exception {
+
+
+    try {
+      byte[] encBytes = encrypt.doFinal(data);
+      return encBytes;
+    } catch (Exception ex) {
+      throw ex;
+    }
+  }
+
+  protected Cipher getEncryptCipher(String dhSKAlgo, PublicKey publicKey) throws Exception {
+    try {
+      if (_encrypt == null) {
+        KeyAgreement ka = KeyAgreement.getInstance("DH");
+        ka.init(dhPrivateKey);
+        ka.doPhase(publicKey, true);
+
+        Cipher encrypt;
+
+        int keysize = getKeySize(dhSKAlgo);
+        int blocksize = getBlockSize(dhSKAlgo);
+
+        if (keysize == -1 || blocksize == -1) {
+          SecretKey sKey = ka.generateSecret(dhSKAlgo);
+          encrypt = Cipher.getInstance(dhSKAlgo);
+          encrypt.init(Cipher.ENCRYPT_MODE, sKey);
+        } else {
+          String dhAlgoStr = getDhAlgoStr(dhSKAlgo);
+
+          byte[] sKeyBytes = ka.generateSecret();
+          SecretKeySpec sks = new SecretKeySpec(sKeyBytes, 0, keysize, dhAlgoStr);
+          IvParameterSpec ivps = new IvParameterSpec(sKeyBytes, keysize, blocksize);
+
+          encrypt = Cipher.getInstance(dhAlgoStr + "/CBC/PKCS5Padding");
+          encrypt.init(Cipher.ENCRYPT_MODE, sks, ivps);
+        }
+        _encrypt = encrypt;
+      }
+    } catch (Exception ex) {
+      throw ex;
+    }
+    return _encrypt;
+  }
+
+  boolean isEnabled() {
+    return dhSKAlgo == null || dhSKAlgo.length() == 0;
+  }
+
+  byte writeEncryptedCredential(DataOutputStream dos, DataInputStream dis, boolean isNotification,
+                                        DistributedMember member, HeapDataOutputStream heapdos)
+      throws IOException {
+    byte acceptanceCode;
+    try {
+      logWriter.fine("HandShake: using Diffie-Hellman key exchange with algo " + dhSKAlgo);
+      boolean requireAuthentication =
+          (certificateFilePath != null && certificateFilePath.length() > 0);
+      if (requireAuthentication) {
+        logWriter
+            .fine("HandShake: server authentication using digital " + "signature required");
+      }
+      // Credentials with encryption indicator
+      heapdos.writeByte(CREDENTIALS_DHENCRYPT);
+      this.appSecureMode = CREDENTIALS_DHENCRYPT;
+      heapdos.writeBoolean(requireAuthentication);
+      // Send the symmetric encryption algorithm name
+      DataSerializer.writeString(dhSKAlgo, heapdos);
+      // Send the DH public key
+      byte[] keyBytes = dhPublicKey.getEncoded();
+      DataSerializer.writeByteArray(keyBytes, heapdos);
+      byte[] clientChallenge = null;
+      if (requireAuthentication) {
+        // Authentication of server should be with the client supplied
+        // challenge
+        clientChallenge = new byte[64];
+        random.nextBytes(clientChallenge);
+        DataSerializer.writeByteArray(clientChallenge, heapdos);
+      }
+      heapdos.flush();
+      dos.write(heapdos.toByteArray());
+      dos.flush();
+
+      // Expect the alias and signature in the reply
+      acceptanceCode = dis.readByte();
+      if (acceptanceCode != REPLY_OK && acceptanceCode != REPLY_AUTH_NOT_REQUIRED) {
+        // Ignore the useless data
+        dis.readByte();
+        dis.readInt();
+        if (!isNotification) {
+          DataSerializer.readByteArray(dis);
+        }
+        readMessage(dis, dos, acceptanceCode, member);
+      } else if (acceptanceCode == REPLY_OK) {
+        // Get the public key of the other side
+        keyBytes = DataSerializer.readByteArray(dis);
+        if (requireAuthentication) {
+          String subject = DataSerializer.readString(dis);
+          byte[] signatureBytes = DataSerializer.readByteArray(dis);
+          if (!certificateMap.containsKey(subject)) {
+            throw new AuthenticationFailedException(
+                LocalizedStrings.HandShake_HANDSHAKE_FAILED_TO_FIND_PUBLIC_KEY_FOR_SERVER_WITH_SUBJECT_0
+                    .toLocalizedString(subject));
+          }
+
+          // Check the signature with the public key
+          X509Certificate cert = (X509Certificate) certificateMap.get(subject);
+          Signature sig = Signature.getInstance(cert.getSigAlgName());
+          sig.initVerify(cert);
+          sig.update(clientChallenge);
+          // Check the challenge string
+          if (!sig.verify(signatureBytes)) {
+            throw new AuthenticationFailedException(
+                "Mismatch in client " + "challenge bytes. Malicious server?");
+          }
+          logWriter
+              .fine("HandShake: Successfully verified the " + "digital signature from server");
+        }
+
+        // Read server challenge bytes
+        byte[] serverChallenge = DataSerializer.readByteArray(dis);
+        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
+        KeyFactory keyFact = KeyFactory.getInstance("DH");
+        // PublicKey pubKey = keyFact.generatePublic(x509KeySpec);
+        this.clientPublicKey = keyFact.generatePublic(x509KeySpec);
+
+        HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
+        try {
+          // Add the challenge string
+          DataSerializer.writeByteArray(serverChallenge, hdos);
+          // byte[] encBytes = encrypt.doFinal(hdos.toByteArray());
+          byte[] encBytes =
+              encryptBytes(hdos.toByteArray(), getEncryptCipher(dhSKAlgo, this.clientPublicKey));
+          DataSerializer.writeByteArray(encBytes, dos);
+        } finally {
+          hdos.close();
+        }
+      }
+    } catch (IOException ex) {
+      throw ex;
+    } catch (GemFireSecurityException ex) {
+      throw ex;
+    } catch (Exception ex) {
+      throw new AuthenticationFailedException("HandShake failed in Diffie-Hellman key exchange",
+          ex);
+    }
+    return acceptanceCode;
+  }
+
+  void writeEncryptedCredentials(DataOutputStream dos, DataInputStream dis,
+                                 Properties p_credentials,
+                                 boolean isNotification, DistributedMember member,
+                                 HeapDataOutputStream heapdos) throws IOException {
+    try {
+      logWriter.fine("HandShake: using Diffie-Hellman key exchange with algo " + dhSKAlgo);
+      boolean requireAuthentication =
+          (certificateFilePath != null && certificateFilePath.length() > 0);
+      if (requireAuthentication) {
+        logWriter
+            .fine("HandShake: server authentication using digital " + "signature required");
+      }
+      // Credentials with encryption indicator
+      heapdos.writeByte(CREDENTIALS_DHENCRYPT);
+      heapdos.writeBoolean(requireAuthentication);
+      // Send the symmetric encryption algorithm name
+      DataSerializer.writeString(dhSKAlgo, heapdos);
+      // Send the DH public key
+      byte[] keyBytes = dhPublicKey.getEncoded();
+      DataSerializer.writeByteArray(keyBytes, heapdos);
+      byte[] clientChallenge = null;
+      if (requireAuthentication) {
+        // Authentication of server should be with the client supplied
+        // challenge
+        clientChallenge = new byte[64];
+        random.nextBytes(clientChallenge);
+        DataSerializer.writeByteArray(clientChallenge, heapdos);
+      }
+      heapdos.flush();
+      dos.write(heapdos.toByteArray());
+      dos.flush();
+
+      // Expect the alias and signature in the reply
+      byte acceptanceCode = dis.readByte();
+      if (acceptanceCode != REPLY_OK && acceptanceCode != REPLY_AUTH_NOT_REQUIRED) {
+        // Ignore the useless data
+        dis.readByte();
+        dis.readInt();
+        if (!isNotification) {
+          DataSerializer.readByteArray(dis);
+        }
+        readMessage(dis, dos, acceptanceCode, member);
+      } else if (acceptanceCode == REPLY_OK) {
+        // Get the public key of the other side
+        keyBytes = DataSerializer.readByteArray(dis);
+        if (requireAuthentication) {
+          String subject = DataSerializer.readString(dis);
+          byte[] signatureBytes = DataSerializer.readByteArray(dis);
+          if (!certificateMap.containsKey(subject)) {
+            throw new AuthenticationFailedException(
+                LocalizedStrings.HandShake_HANDSHAKE_FAILED_TO_FIND_PUBLIC_KEY_FOR_SERVER_WITH_SUBJECT_0
+                    .toLocalizedString(subject));
+          }
+
+          // Check the signature with the public key
+          X509Certificate cert = (X509Certificate) certificateMap.get(subject);
+          Signature sig = Signature.getInstance(cert.getSigAlgName());
+          sig.initVerify(cert);
+          sig.update(clientChallenge);
+          // Check the challenge string
+          if (!sig.verify(signatureBytes)) {
+            throw new AuthenticationFailedException(
+                "Mismatch in client " + "challenge bytes. Malicious server?");
+          }
+          logWriter
+              .fine("HandShake: Successfully verified the " + "digital signature from server");
+        }
+
+        byte[] challenge = DataSerializer.readByteArray(dis);
+        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
+        KeyFactory keyFact = KeyFactory.getInstance("DH");
+        // PublicKey pubKey = keyFact.generatePublic(x509KeySpec);
+        this.clientPublicKey = keyFact.generatePublic(x509KeySpec);
+
+
+
+        HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
+        try {
+          DataSerializer.writeProperties(p_credentials, hdos);
+          // Also add the challenge string
+          DataSerializer.writeByteArray(challenge, hdos);
+
+          // byte[] encBytes = encrypt.doFinal(hdos.toByteArray());
+          byte[] encBytes =
+              encryptBytes(hdos.toByteArray(), getEncryptCipher(dhSKAlgo, this.clientPublicKey));
+          DataSerializer.writeByteArray(encBytes, dos);
+        } finally {
+          hdos.close();
+        }
+      }
+    } catch (IOException ex) {
+      throw ex;
+    } catch (GemFireSecurityException ex) {
+      throw ex;
+    } catch (Exception ex) {
+      throw new AuthenticationFailedException("HandShake failed in Diffie-Hellman key exchange",
+          ex);
+    }
+  }
+
+  void readEncryptedCredentials(DataInputStream dis, DataOutputStream dos,
+                                DistributedSystem system, boolean requireAuthentication)
+      throws Exception {
+    this.appSecureMode = CREDENTIALS_DHENCRYPT;
+    boolean sendAuthentication = dis.readBoolean();
+    InternalLogWriter securityLogWriter = (InternalLogWriter) system.getSecurityLogWriter();
+    // Get the symmetric encryption algorithm to be used
+    this.clientSKAlgo = DataSerializer.readString(dis);
+    // Get the public key of the other side
+    byte[] keyBytes = DataSerializer.readByteArray(dis);
+    byte[] challenge = null;
+    // PublicKey pubKey = null;
+    if (requireAuthentication) {
+      // Generate PublicKey from encoded form
+      X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
+      KeyFactory keyFact = KeyFactory.getInstance("DH");
+      this.clientPublicKey = keyFact.generatePublic(x509KeySpec);
+
+      // Send the public key to other side
+      keyBytes = dhPublicKey.getEncoded();
+      challenge = new byte[64];
+      random.nextBytes(challenge);
+
+      // If the server has to also authenticate itself then
+      // sign the challenge from client.
+      if (sendAuthentication) {
+        // Get the challenge string from client
+        byte[] clientChallenge = DataSerializer.readByteArray(dis);
+        if (privateKeyEncrypt == null) {
+          throw new AuthenticationFailedException(
+              LocalizedStrings.HandShake_SERVER_PRIVATE_KEY_NOT_AVAILABLE_FOR_CREATING_SIGNATURE
+                  .toLocalizedString());
+        }
+        // Sign the challenge from client and send it to the client
+        Signature sig = Signature.getInstance(privateKeySignAlgo);
+        sig.initSign(privateKeyEncrypt);
+        sig.update(clientChallenge);
+        byte[] signedBytes = sig.sign();
+        dos.writeByte(REPLY_OK);
+        DataSerializer.writeByteArray(keyBytes, dos);
+        // DataSerializer.writeString(privateKeyAlias, dos);
+        DataSerializer.writeString(privateKeySubject, dos);
+        DataSerializer.writeByteArray(signedBytes, dos);
+        securityLogWriter.fine("HandShake: sent the signed client challenge");
+      } else {
+        // These two lines should not be moved before the if{} statement in
+        // a common block for both if...then...else parts. This is to handle
+        // the case when an AuthenticationFailedException is thrown by the
+        // if...then part when sending the signature.
+        dos.writeByte(REPLY_OK);
+        DataSerializer.writeByteArray(keyBytes, dos);
+      }
+      // Now send the server challenge
+      DataSerializer.writeByteArray(challenge, dos);
+      securityLogWriter.fine("HandShake: sent the public key and challenge");
+      dos.flush();
+
+      // Read and decrypt the credentials
+      byte[] encBytes = DataSerializer.readByteArray(dis);
+      Cipher c = getDecryptCipher(this.clientSKAlgo, this.clientPublicKey);
+      byte[] credentialBytes = decryptBytes(encBytes, c);
+      ByteArrayInputStream bis = new ByteArrayInputStream(credentialBytes);
+      DataInputStream dinp = new DataInputStream(bis);
+      // credentials = DataSerializer.readProperties(dinp);//Hitesh: we don't send in handshake
+      // now
+      byte[] challengeRes = DataSerializer.readByteArray(dinp);
+      // Check the challenge string
+      if (!Arrays.equals(challenge, challengeRes)) {
+        throw new AuthenticationFailedException(
+            LocalizedStrings.HandShake_MISMATCH_IN_CHALLENGE_BYTES_MALICIOUS_CLIENT
+                .toLocalizedString());
+      }
+      dinp.close();
+    } else {
+      if (sendAuthentication) {
+        // Read and ignore the client challenge
+        DataSerializer.readByteArray(dis);
+      }
+      dos.writeByte(REPLY_AUTH_NOT_REQUIRED);
+      dos.flush();
+    }
+  }
+
+  static Properties getDecryptedCredentials(DataInputStream dis, DataOutputStream dos,
+                                            DistributedSystem system,
+                                            boolean requireAuthentication,
+                                            Properties credentials)
+      throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException,
+      SignatureException, NoSuchPaddingException, InvalidAlgorithmParameterException,
+      IllegalBlockSizeException, BadPaddingException, ClassNotFoundException {
+    boolean sendAuthentication = dis.readBoolean();
+    InternalLogWriter securityLogWriter = (InternalLogWriter) system.getSecurityLogWriter();
+    // Get the symmetric encryption algorithm to be used
+    String skAlgo = DataSerializer.readString(dis);
+    // Get the public key of the other side
+    byte[] keyBytes = DataSerializer.readByteArray(dis);
+    byte[] challenge = null;
+    PublicKey pubKey = null;
+    if (requireAuthentication) {
+      // Generate PublicKey from encoded form
+      X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
+      KeyFactory keyFact = KeyFactory.getInstance("DH");
+      pubKey = keyFact.generatePublic(x509KeySpec);
+
+      // Send the public key to other side
+      keyBytes = dhPublicKey.getEncoded();
+      challenge = new byte[64];
+      random.nextBytes(challenge);
+
+      // If the server has to also authenticate itself then
+      // sign the challenge from client.
+      if (sendAuthentication) {
+        // Get the challenge string from client
+        byte[] clientChallenge = DataSerializer.readByteArray(dis);
+        if (privateKeyEncrypt == null) {
+          throw new AuthenticationFailedException(
+              LocalizedStrings.HandShake_SERVER_PRIVATE_KEY_NOT_AVAILABLE_FOR_CREATING_SIGNATURE
+                  .toLocalizedString());
+        }
+        // Sign the challenge from client and send it to the client
+        Signature sig = Signature.getInstance(privateKeySignAlgo);
+        sig.initSign(privateKeyEncrypt);
+        sig.update(clientChallenge);
+        byte[] signedBytes = sig.sign();
+        dos.writeByte(REPLY_OK);
+        DataSerializer.writeByteArray(keyBytes, dos);
+        // DataSerializer.writeString(privateKeyAlias, dos);
+        DataSerializer.writeString(privateKeySubject, dos);
+        DataSerializer.writeByteArray(signedBytes, dos);
+        securityLogWriter.fine("HandShake: sent the signed client challenge");
+      } else {
+        // These two lines should not be moved before the if{} statement in
+        // a common block for both if...then...else parts. This is to handle
+        // the case when an AuthenticationFailedException is thrown by the
+        // if...then part when sending the signature.
+        dos.writeByte(REPLY_OK);
+        DataSerializer.writeByteArray(keyBytes, dos);
+      }
+      // Now send the server challenge
+      DataSerializer.writeByteArray(challenge, dos);
+      securityLogWriter.fine("HandShake: sent the public key and challenge");
+      dos.flush();
+
+      // Read and decrypt the credentials
+      byte[] encBytes = DataSerializer.readByteArray(dis);
+      KeyAgreement ka = KeyAgreement.getInstance("DH");
+      ka.init(dhPrivateKey);
+      ka.doPhase(pubKey, true);
+
+      Cipher decrypt;
+
+      int keysize = getKeySize(skAlgo);
+      int blocksize = getBlockSize(skAlgo);
+
+      if (keysize == -1 || blocksize == -1) {
+        SecretKey sKey = ka.generateSecret(skAlgo);
+        decrypt = Cipher.getInstance(skAlgo);
+        decrypt.init(Cipher.DECRYPT_MODE, sKey);
+      } else {
+        String algoStr = getDhAlgoStr(skAlgo);
+
+        byte[] sKeyBytes = ka.generateSecret();
+        SecretKeySpec sks = new SecretKeySpec(sKeyBytes, 0, keysize, algoStr);
+        IvParameterSpec ivps = new IvParameterSpec(sKeyBytes, keysize, blocksize);
+
+        decrypt = Cipher.getInstance(algoStr + "/CBC/PKCS5Padding");
+        decrypt.init(Cipher.DECRYPT_MODE, sks, ivps);
+      }
+
+      byte[] credentialBytes = decrypt.doFinal(encBytes);
+      ByteArrayInputStream bis = new ByteArrayInputStream(credentialBytes);
+      DataInputStream dinp = new DataInputStream(bis);
+      credentials = DataSerializer.readProperties(dinp);
+      byte[] challengeRes = DataSerializer.readByteArray(dinp);
+      // Check the challenge string
+      if (!Arrays.equals(challenge, challengeRes)) {
+        throw new AuthenticationFailedException(
+            LocalizedStrings.HandShake_MISMATCH_IN_CHALLENGE_BYTES_MALICIOUS_CLIENT
+                .toLocalizedString());
+      }
+      dinp.close();
+    } else {
+      if (sendAuthentication) {
+        // Read and ignore the client challenge
+        DataSerializer.readByteArray(dis);
+      }
+      dos.writeByte(REPLY_AUTH_NOT_REQUIRED);
+      dos.flush();
+    }
+    return credentials;
+  }
+
+
+  private static int getKeySize(String skAlgo) {
+    // skAlgo contain both algo and key size info
+    int colIdx = skAlgo.indexOf(':');
+    String algoStr;
+    int algoKeySize = 0;
+    if (colIdx >= 0) {
+      algoStr = skAlgo.substring(0, colIdx);
+      algoKeySize = Integer.parseInt(skAlgo.substring(colIdx + 1));
+    } else {
+      algoStr = skAlgo;
+    }
+    int keysize = -1;
+    if (algoStr.equalsIgnoreCase("DESede")) {
+      keysize = 24;
+    } else if (algoStr.equalsIgnoreCase("Blowfish")) {
+      keysize = algoKeySize > 128 ? algoKeySize / 8 : 16;
+    } else if (algoStr.equalsIgnoreCase("AES")) {
+      keysize = (algoKeySize != 192 && algoKeySize != 256) ? 16 : algoKeySize / 8;
+    }
+    return keysize;
+  }
+
+  private static String getDhAlgoStr(String skAlgo) {
+    int colIdx = skAlgo.indexOf(':');
+    String algoStr;
+    if (colIdx >= 0) {
+      algoStr = skAlgo.substring(0, colIdx);
+    } else {
+      algoStr = skAlgo;
+    }
+    return algoStr;
+  }
+
+  private static int getBlockSize(String skAlgo) {
+    int blocksize = -1;
+    String algoStr = getDhAlgoStr(skAlgo);
+    if (algoStr.equalsIgnoreCase("DESede")) {
+      blocksize = 8;
+    } else if (algoStr.equalsIgnoreCase("Blowfish")) {
+      blocksize = 8;
+    } else if (algoStr.equalsIgnoreCase("AES")) {
+      blocksize = 16;
+    }
+    return blocksize;
+  }
+
+
+}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/Handshake.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/Handshake.java
index 055d0bc..37412c4 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/Handshake.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/Handshake.java
@@ -17,73 +17,31 @@ package org.apache.geode.internal.cache.tier.sockets;
 import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_CLIENT_AUTHENTICATOR;
 import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_CLIENT_AUTH_INIT;
 
-import java.io.ByteArrayInputStream;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
-import java.io.EOFException;
-import java.io.FileInputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.lang.reflect.Method;
-import java.math.BigInteger;
-import java.net.Socket;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.KeyStore;
-import java.security.Principal;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.Signature;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.Properties;
 
-import javax.crypto.Cipher;
-import javax.crypto.KeyAgreement;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.DHParameterSpec;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
 import org.apache.commons.lang.StringUtils;
 import org.apache.logging.log4j.Logger;
 
 import org.apache.geode.DataSerializer;
-import org.apache.geode.InternalGemFireException;
 import org.apache.geode.cache.client.PoolFactory;
 import org.apache.geode.cache.client.ServerRefusedConnectionException;
 import org.apache.geode.cache.client.internal.ClientSideHandshakeImpl;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.DistributedSystem;
-import org.apache.geode.distributed.internal.DistributionConfig;
-import org.apache.geode.distributed.internal.InternalDistributedSystem;
-import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.internal.ClassLoadUtil;
 import org.apache.geode.internal.HeapDataOutputStream;
-import org.apache.geode.internal.InternalDataSerializer;
 import org.apache.geode.internal.Version;
-import org.apache.geode.internal.VersionedDataInputStream;
-import org.apache.geode.internal.VersionedDataOutputStream;
-import org.apache.geode.internal.cache.tier.CommunicationMode;
 import org.apache.geode.internal.cache.tier.ConnectionProxy;
-import org.apache.geode.internal.cache.tier.Encryptor;
-import org.apache.geode.internal.cache.tier.ServerSideHandshake;
 import org.apache.geode.internal.i18n.LocalizedStrings;
 import org.apache.geode.internal.logging.InternalLogWriter;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.security.CallbackInstantiator;
 import org.apache.geode.internal.security.Credentials;
 import org.apache.geode.internal.security.SecurityService;
-import org.apache.geode.internal.security.SecurityServiceFactory;
-import org.apache.geode.pdx.internal.PeerTypeRegistration;
 import org.apache.geode.security.AuthInitialize;
 import org.apache.geode.security.AuthenticationFailedException;
 import org.apache.geode.security.AuthenticationRequiredException;
@@ -129,6 +87,8 @@ public abstract class Handshake {
 
   protected Properties credentials;
 
+  protected EncryptorImpl encryptor;
+
   // Security mode flags
 
   /** No credentials being sent */
@@ -142,51 +102,6 @@ public abstract class Handshake {
 
   public static final byte SECURITY_MULTIUSER_NOTIFICATIONCHANNEL = (byte) 3;
 
-  private byte appSecureMode = (byte) 0;
-
-  private PublicKey clientPublicKey = null;
-
-  private String clientSKAlgo = null;
-
-  // Parameters for the Diffie-Hellman key exchange
-  private static final BigInteger dhP =
-      new BigInteger("13528702063991073999718992897071702177131142188276542919088770094024269"
-          + "73079899070080419278066109785292538223079165925365098181867673946"
-          + "34756714063947534092593553024224277712367371302394452615862654308"
-          + "11180902979719649450105660478776364198726078338308557022096810447"
-          + "3500348898008043285865193451061481841186553");
-
-  private static final BigInteger dhG =
-      new BigInteger("13058345680719715096166513407513969537624553636623932169016704425008150"
-          + "56576152779768716554354314319087014857769741104157332735258102835"
-          + "93126577393912282416840649805564834470583437473176415335737232689"
-          + "81480201869671811010996732593655666464627559582258861254878896534"
-          + "1273697569202082715873518528062345259949959");
-
-  private static final int dhL = 1023;
-
-  private static PrivateKey dhPrivateKey = null;
-
-  private static PublicKey dhPublicKey = null;
-
-  private static String dhSKAlgo = null;
-
-  // Members for server authentication using digital signature
-
-  private static String certificateFilePath = null;
-
-  private static HashMap certificateMap = null;
-
-  private static String privateKeyAlias = null;
-
-  private static String privateKeySubject = null;
-
-  private static PrivateKey privateKeyEncrypt = null;
-
-  private static String privateKeySignAlgo = null;
-
-  private static SecureRandom random = null;
-
   public static final String PUBLIC_KEY_FILE_PROP = "security-client-kspath";
 
   public static final String PUBLIC_KEY_PASSWD_PROP = "security-client-kspasswd";
@@ -226,20 +141,15 @@ public abstract class Handshake {
    * Clone a HandShake to be used in creating other connections
    */
   protected Handshake(Handshake handshake) {
-    this.appSecureMode = handshake.appSecureMode;
     this.clientConflation = handshake.clientConflation;
-    this.clientPublicKey = null;
     this.clientReadTimeout = handshake.clientReadTimeout;
-    this.clientSKAlgo = null;
     this.replyCode = handshake.replyCode;
     this.credentials = handshake.credentials;
     this.overrides = handshake.overrides;
     this.system = handshake.system;
     this.id = handshake.id;
     this.securityService = handshake.securityService;
-    // create new one
-    this._decrypt = null;
-    this._encrypt = null;
+    this.encryptor = new EncryptorImpl(handshake.encryptor);
   }
 
   protected void setClientConflation(byte value) {
@@ -285,110 +195,16 @@ public abstract class Handshake {
       boolean isNotification, DistributedMember member, HeapDataOutputStream heapdos)
       throws IOException, GemFireSecurityException {
 
-    if (dhSKAlgo == null || dhSKAlgo.length() == 0) {
-      // Normal credentials without encryption indicator
+    if (!encryptor.isEnabled()) {
       heapdos.writeByte(CREDENTIALS_NORMAL);
-      this.appSecureMode = CREDENTIALS_NORMAL;
-      // DataSerializer.writeProperties(p_credentials, heapdos);
+      encryptor.setAppSecureMode(CREDENTIALS_NORMAL);
       heapdos.flush();
       dos.write(heapdos.toByteArray());
       dos.flush();
       return -1;
     }
     byte acceptanceCode = -1;
-    try {
-      InternalLogWriter securityLogWriter = (InternalLogWriter) this.system.getSecurityLogWriter();
-      securityLogWriter.fine("HandShake: using Diffie-Hellman key exchange with algo " + dhSKAlgo);
-      boolean requireAuthentication =
-          (certificateFilePath != null && certificateFilePath.length() > 0);
-      if (requireAuthentication) {
-        securityLogWriter
-            .fine("HandShake: server authentication using digital " + "signature required");
-      }
-      // Credentials with encryption indicator
-      heapdos.writeByte(CREDENTIALS_DHENCRYPT);
-      this.appSecureMode = CREDENTIALS_DHENCRYPT;
-      heapdos.writeBoolean(requireAuthentication);
-      // Send the symmetric encryption algorithm name
-      DataSerializer.writeString(dhSKAlgo, heapdos);
-      // Send the DH public key
-      byte[] keyBytes = dhPublicKey.getEncoded();
-      DataSerializer.writeByteArray(keyBytes, heapdos);
-      byte[] clientChallenge = null;
-      if (requireAuthentication) {
-        // Authentication of server should be with the client supplied
-        // challenge
-        clientChallenge = new byte[64];
-        random.nextBytes(clientChallenge);
-        DataSerializer.writeByteArray(clientChallenge, heapdos);
-      }
-      heapdos.flush();
-      dos.write(heapdos.toByteArray());
-      dos.flush();
-
-      // Expect the alias and signature in the reply
-      acceptanceCode = dis.readByte();
-      if (acceptanceCode != REPLY_OK && acceptanceCode != REPLY_AUTH_NOT_REQUIRED) {
-        // Ignore the useless data
-        dis.readByte();
-        dis.readInt();
-        if (!isNotification) {
-          DataSerializer.readByteArray(dis);
-        }
-        readMessage(dis, dos, acceptanceCode, member);
-      } else if (acceptanceCode == REPLY_OK) {
-        // Get the public key of the other side
-        keyBytes = DataSerializer.readByteArray(dis);
-        if (requireAuthentication) {
-          String subject = DataSerializer.readString(dis);
-          byte[] signatureBytes = DataSerializer.readByteArray(dis);
-          if (!certificateMap.containsKey(subject)) {
-            throw new AuthenticationFailedException(
-                LocalizedStrings.HandShake_HANDSHAKE_FAILED_TO_FIND_PUBLIC_KEY_FOR_SERVER_WITH_SUBJECT_0
-                    .toLocalizedString(subject));
-          }
-
-          // Check the signature with the public key
-          X509Certificate cert = (X509Certificate) certificateMap.get(subject);
-          Signature sig = Signature.getInstance(cert.getSigAlgName());
-          sig.initVerify(cert);
-          sig.update(clientChallenge);
-          // Check the challenge string
-          if (!sig.verify(signatureBytes)) {
-            throw new AuthenticationFailedException(
-                "Mismatch in client " + "challenge bytes. Malicious server?");
-          }
-          securityLogWriter
-              .fine("HandShake: Successfully verified the " + "digital signature from server");
-        }
-
-        // Read server challenge bytes
-        byte[] serverChallenge = DataSerializer.readByteArray(dis);
-        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
-        KeyFactory keyFact = KeyFactory.getInstance("DH");
-        // PublicKey pubKey = keyFact.generatePublic(x509KeySpec);
-        this.clientPublicKey = keyFact.generatePublic(x509KeySpec);
-
-        HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
-        try {
-          // Add the challenge string
-          DataSerializer.writeByteArray(serverChallenge, hdos);
-          // byte[] encBytes = encrypt.doFinal(hdos.toByteArray());
-          byte[] encBytes =
-              encryptBytes(hdos.toByteArray(), getEncryptCipher(dhSKAlgo, this.clientPublicKey));
-          DataSerializer.writeByteArray(encBytes, dos);
-        } finally {
-          hdos.close();
-        }
-      }
-    } catch (IOException ex) {
-      throw ex;
-    } catch (GemFireSecurityException ex) {
-      throw ex;
-    } catch (Exception ex) {
-      throw new AuthenticationFailedException("HandShake failed in Diffie-Hellman key exchange",
-          ex);
-    }
+    acceptanceCode = encryptor.writeEncryptedCredential(dos, dis, isNotification, member, heapdos);
     dos.flush();
     return acceptanceCode;
   }
@@ -420,7 +236,7 @@ public abstract class Handshake {
       return;
     }
 
-    if (dhSKAlgo == null || dhSKAlgo.length() == 0) {
+    if (!encryptor.isEnabled()) {
       // Normal credentials without encryption indicator
       heapdos.writeByte(CREDENTIALS_NORMAL);
       DataSerializer.writeProperties(p_credentials, heapdos);
@@ -430,165 +246,10 @@ public abstract class Handshake {
       return;
     }
 
-    try {
-      InternalLogWriter securityLogWriter = (InternalLogWriter) this.system.getSecurityLogWriter();
-      securityLogWriter.fine("HandShake: using Diffie-Hellman key exchange with algo " + dhSKAlgo);
-      boolean requireAuthentication =
-          (certificateFilePath != null && certificateFilePath.length() > 0);
-      if (requireAuthentication) {
-        securityLogWriter
-            .fine("HandShake: server authentication using digital " + "signature required");
-      }
-      // Credentials with encryption indicator
-      heapdos.writeByte(CREDENTIALS_DHENCRYPT);
-      heapdos.writeBoolean(requireAuthentication);
-      // Send the symmetric encryption algorithm name
-      DataSerializer.writeString(dhSKAlgo, heapdos);
-      // Send the DH public key
-      byte[] keyBytes = dhPublicKey.getEncoded();
-      DataSerializer.writeByteArray(keyBytes, heapdos);
-      byte[] clientChallenge = null;
-      if (requireAuthentication) {
-        // Authentication of server should be with the client supplied
-        // challenge
-        clientChallenge = new byte[64];
-        random.nextBytes(clientChallenge);
-        DataSerializer.writeByteArray(clientChallenge, heapdos);
-      }
-      heapdos.flush();
-      dos.write(heapdos.toByteArray());
-      dos.flush();
-
-      // Expect the alias and signature in the reply
-      byte acceptanceCode = dis.readByte();
-      if (acceptanceCode != REPLY_OK && acceptanceCode != REPLY_AUTH_NOT_REQUIRED) {
-        // Ignore the useless data
-        dis.readByte();
-        dis.readInt();
-        if (!isNotification) {
-          DataSerializer.readByteArray(dis);
-        }
-        readMessage(dis, dos, acceptanceCode, member);
-      } else if (acceptanceCode == REPLY_OK) {
-        // Get the public key of the other side
-        keyBytes = DataSerializer.readByteArray(dis);
-        if (requireAuthentication) {
-          String subject = DataSerializer.readString(dis);
-          byte[] signatureBytes = DataSerializer.readByteArray(dis);
-          if (!certificateMap.containsKey(subject)) {
-            throw new AuthenticationFailedException(
-                LocalizedStrings.HandShake_HANDSHAKE_FAILED_TO_FIND_PUBLIC_KEY_FOR_SERVER_WITH_SUBJECT_0
-                    .toLocalizedString(subject));
-          }
-
-          // Check the signature with the public key
-          X509Certificate cert = (X509Certificate) certificateMap.get(subject);
-          Signature sig = Signature.getInstance(cert.getSigAlgName());
-          sig.initVerify(cert);
-          sig.update(clientChallenge);
-          // Check the challenge string
-          if (!sig.verify(signatureBytes)) {
-            throw new AuthenticationFailedException(
-                "Mismatch in client " + "challenge bytes. Malicious server?");
-          }
-          securityLogWriter
-              .fine("HandShake: Successfully verified the " + "digital signature from server");
-        }
-
-        byte[] challenge = DataSerializer.readByteArray(dis);
-        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
-        KeyFactory keyFact = KeyFactory.getInstance("DH");
-        // PublicKey pubKey = keyFact.generatePublic(x509KeySpec);
-        this.clientPublicKey = keyFact.generatePublic(x509KeySpec);
-
-
-
-        HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
-        try {
-          DataSerializer.writeProperties(p_credentials, hdos);
-          // Also add the challenge string
-          DataSerializer.writeByteArray(challenge, hdos);
-
-          // byte[] encBytes = encrypt.doFinal(hdos.toByteArray());
-          byte[] encBytes =
-              encryptBytes(hdos.toByteArray(), getEncryptCipher(dhSKAlgo, this.clientPublicKey));
-          DataSerializer.writeByteArray(encBytes, dos);
-        } finally {
-          hdos.close();
-        }
-      }
-    } catch (IOException ex) {
-      throw ex;
-    } catch (GemFireSecurityException ex) {
-      throw ex;
-    } catch (Exception ex) {
-      throw new AuthenticationFailedException("HandShake failed in Diffie-Hellman key exchange",
-          ex);
-    }
+    encryptor.writeEncryptedCredentials(dos, dis, p_credentials, isNotification, member, heapdos);
     dos.flush();
   }
 
-  public byte[] encryptBytes(byte[] data) throws Exception {
-    if (this.appSecureMode == CREDENTIALS_DHENCRYPT) {
-      String algo = null;
-      if (this.clientSKAlgo != null) {
-        algo = this.clientSKAlgo;
-      } else {
-        algo = dhSKAlgo;
-      }
-      return encryptBytes(data, getEncryptCipher(algo, this.clientPublicKey));
-    } else {
-      return data;
-    }
-  }
-
-  public static byte[] encryptBytes(byte[] data, Cipher encrypt) throws Exception {
-
-
-    try {
-      byte[] encBytes = encrypt.doFinal(data);
-      return encBytes;
-    } catch (Exception ex) {
-      throw ex;
-    }
-  }
-
-  private Cipher _encrypt;
-
-  private Cipher getEncryptCipher(String dhSKAlgo, PublicKey publicKey) throws Exception {
-    try {
-      if (_encrypt == null) {
-        KeyAgreement ka = KeyAgreement.getInstance("DH");
-        ka.init(dhPrivateKey);
-        ka.doPhase(publicKey, true);
-
-        Cipher encrypt;
-
-        int keysize = getKeySize(dhSKAlgo);
-        int blocksize = getBlockSize(dhSKAlgo);
-
-        if (keysize == -1 || blocksize == -1) {
-          SecretKey sKey = ka.generateSecret(dhSKAlgo);
-          encrypt = Cipher.getInstance(dhSKAlgo);
-          encrypt.init(Cipher.ENCRYPT_MODE, sKey);
-        } else {
-          String dhAlgoStr = getDhAlgoStr(dhSKAlgo);
-
-          byte[] sKeyBytes = ka.generateSecret();
-          SecretKeySpec sks = new SecretKeySpec(sKeyBytes, 0, keysize, dhAlgoStr);
-          IvParameterSpec ivps = new IvParameterSpec(sKeyBytes, keysize, blocksize);
-
-          encrypt = Cipher.getInstance(dhAlgoStr + "/CBC/PKCS5Padding");
-          encrypt.init(Cipher.ENCRYPT_MODE, sks, ivps);
-        }
-        _encrypt = encrypt;
-      }
-    } catch (Exception ex) {
-      throw ex;
-    }
-    return _encrypt;
-  }
-
   /**
    * Throws AuthenticationRequiredException if authentication is required but there are no
    * credentials.
@@ -602,7 +263,7 @@ public abstract class Handshake {
   }
 
   // This assumes that authentication is the last piece of info in handshake
-  public Properties readCredential(DataInputStream dis, DataOutputStream dos,
+  Properties readCredential(DataInputStream dis, DataOutputStream dos,
       DistributedSystem system) throws GemFireSecurityException, IOException {
 
     Properties credentials = null;
@@ -611,91 +272,9 @@ public abstract class Handshake {
       byte secureMode = dis.readByte();
       throwIfMissingRequiredCredentials(requireAuthentication, secureMode != CREDENTIALS_NONE);
       if (secureMode == CREDENTIALS_NORMAL) {
-        this.appSecureMode = CREDENTIALS_NORMAL;
-        /*
-         * if (requireAuthentication) { credentials = DataSerializer.readProperties(dis); } else {
-         * DataSerializer.readProperties(dis); // ignore the credentials }
-         */
+encryptor.setAppSecureMode(CREDENTIALS_NORMAL);
       } else if (secureMode == CREDENTIALS_DHENCRYPT) {
-        this.appSecureMode = CREDENTIALS_DHENCRYPT;
-        boolean sendAuthentication = dis.readBoolean();
-        InternalLogWriter securityLogWriter = (InternalLogWriter) system.getSecurityLogWriter();
-        // Get the symmetric encryption algorithm to be used
-        // String skAlgo = DataSerializer.readString(dis);
-        this.clientSKAlgo = DataSerializer.readString(dis);
-        // Get the public key of the other side
-        byte[] keyBytes = DataSerializer.readByteArray(dis);
-        byte[] challenge = null;
-        // PublicKey pubKey = null;
-        if (requireAuthentication) {
-          // Generate PublicKey from encoded form
-          X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
-          KeyFactory keyFact = KeyFactory.getInstance("DH");
-          this.clientPublicKey = keyFact.generatePublic(x509KeySpec);
-
-          // Send the public key to other side
-          keyBytes = dhPublicKey.getEncoded();
-          challenge = new byte[64];
-          random.nextBytes(challenge);
-
-          // If the server has to also authenticate itself then
-          // sign the challenge from client.
-          if (sendAuthentication) {
-            // Get the challenge string from client
-            byte[] clientChallenge = DataSerializer.readByteArray(dis);
-            if (privateKeyEncrypt == null) {
-              throw new AuthenticationFailedException(
-                  LocalizedStrings.HandShake_SERVER_PRIVATE_KEY_NOT_AVAILABLE_FOR_CREATING_SIGNATURE
-                      .toLocalizedString());
-            }
-            // Sign the challenge from client and send it to the client
-            Signature sig = Signature.getInstance(privateKeySignAlgo);
-            sig.initSign(privateKeyEncrypt);
-            sig.update(clientChallenge);
-            byte[] signedBytes = sig.sign();
-            dos.writeByte(REPLY_OK);
-            DataSerializer.writeByteArray(keyBytes, dos);
-            // DataSerializer.writeString(privateKeyAlias, dos);
-            DataSerializer.writeString(privateKeySubject, dos);
-            DataSerializer.writeByteArray(signedBytes, dos);
-            securityLogWriter.fine("HandShake: sent the signed client challenge");
-          } else {
-            // These two lines should not be moved before the if{} statement in
-            // a common block for both if...then...else parts. This is to handle
-            // the case when an AuthenticationFailedException is thrown by the
-            // if...then part when sending the signature.
-            dos.writeByte(REPLY_OK);
-            DataSerializer.writeByteArray(keyBytes, dos);
-          }
-          // Now send the server challenge
-          DataSerializer.writeByteArray(challenge, dos);
-          securityLogWriter.fine("HandShake: sent the public key and challenge");
-          dos.flush();
-
-          // Read and decrypt the credentials
-          byte[] encBytes = DataSerializer.readByteArray(dis);
-          Cipher c = getDecryptCipher(this.clientSKAlgo, this.clientPublicKey);
-          byte[] credentialBytes = decryptBytes(encBytes, c);
-          ByteArrayInputStream bis = new ByteArrayInputStream(credentialBytes);
-          DataInputStream dinp = new DataInputStream(bis);
-          // credentials = DataSerializer.readProperties(dinp);//Hitesh: we don't send in handshake
-          // now
-          byte[] challengeRes = DataSerializer.readByteArray(dinp);
-          // Check the challenge string
-          if (!Arrays.equals(challenge, challengeRes)) {
-            throw new AuthenticationFailedException(
-                LocalizedStrings.HandShake_MISMATCH_IN_CHALLENGE_BYTES_MALICIOUS_CLIENT
-                    .toLocalizedString());
-          }
-          dinp.close();
-        } else {
-          if (sendAuthentication) {
-            // Read and ignore the client challenge
-            DataSerializer.readByteArray(dis);
-          }
-          dos.writeByte(REPLY_AUTH_NOT_REQUIRED);
-          dos.flush();
-        }
+        encryptor.readEncryptedCredentials(dis, dos, system, requireAuthentication);
       }
     } catch (IOException ex) {
       throw ex;
@@ -708,157 +287,6 @@ public abstract class Handshake {
     return credentials;
   }
 
-  public byte[] decryptBytes(byte[] data) throws Exception {
-    if (this.appSecureMode == CREDENTIALS_DHENCRYPT) {
-      String algo = null;
-      if (this.clientSKAlgo != null) {
-        algo = this.clientSKAlgo;
-      } else {
-        algo = dhSKAlgo;
-      }
-      Cipher c = getDecryptCipher(algo, this.clientPublicKey);
-      return decryptBytes(data, c);
-    } else {
-      return data;
-    }
-  }
-
-  public static byte[] decryptBytes(byte[] data, Cipher decrypt) throws Exception {
-    try {
-      byte[] decrptBytes = decrypt.doFinal(data);
-      return decrptBytes;
-    } catch (Exception ex) {
-      throw ex;
-    }
-  }
-
-  private Cipher _decrypt = null;
-
-  private Cipher getDecryptCipher(String dhSKAlgo, PublicKey publicKey) throws Exception {
-    if (_decrypt == null) {
-      try {
-        KeyAgreement ka = KeyAgreement.getInstance("DH");
-        ka.init(dhPrivateKey);
-        ka.doPhase(publicKey, true);
-
-        Cipher decrypt;
-
-        int keysize = getKeySize(dhSKAlgo);
-        int blocksize = getBlockSize(dhSKAlgo);
-
-        if (keysize == -1 || blocksize == -1) {
-          SecretKey sKey = ka.generateSecret(dhSKAlgo);
-          decrypt = Cipher.getInstance(dhSKAlgo);
-          decrypt.init(Cipher.DECRYPT_MODE, sKey);
-        } else {
-          String algoStr = getDhAlgoStr(dhSKAlgo);
-
-          byte[] sKeyBytes = ka.generateSecret();
-          SecretKeySpec sks = new SecretKeySpec(sKeyBytes, 0, keysize, algoStr);
-          IvParameterSpec ivps = new IvParameterSpec(sKeyBytes, keysize, blocksize);
-
-          decrypt = Cipher.getInstance(algoStr + "/CBC/PKCS5Padding");
-          decrypt.init(Cipher.DECRYPT_MODE, sks, ivps);
-        }
-
-        _decrypt = decrypt;
-      } catch (Exception ex) {
-        throw ex;
-      }
-    }
-    return _decrypt;
-  }
-
-  /**
-   * Populate the available server public keys into a local static HashMap. This method is not
-   * thread safe.
-   */
-  public static void initCertsMap(Properties props) throws Exception {
-
-    certificateMap = new HashMap();
-    certificateFilePath = props.getProperty(PUBLIC_KEY_FILE_PROP);
-    if (certificateFilePath != null && certificateFilePath.length() > 0) {
-      KeyStore ks = KeyStore.getInstance("JKS");
-      String keyStorePass = props.getProperty(PUBLIC_KEY_PASSWD_PROP);
-      char[] passPhrase = (keyStorePass != null ? keyStorePass.toCharArray() : null);
-      FileInputStream keystorefile = new FileInputStream(certificateFilePath);
-      try {
-        ks.load(keystorefile, passPhrase);
-      } finally {
-        keystorefile.close();
-      }
-      Enumeration aliases = ks.aliases();
-      while (aliases.hasMoreElements()) {
-        String alias = (String) aliases.nextElement();
-        Certificate cert = ks.getCertificate(alias);
-        if (cert instanceof X509Certificate) {
-          String subject = ((X509Certificate) cert).getSubjectDN().getName();
-          certificateMap.put(subject, cert);
-        }
-      }
-    }
-  }
-
-  /**
-   * Load the private key of the server. This method is not thread safe.
-   */
-  public static void initPrivateKey(Properties props) throws Exception {
-
-    String privateKeyFilePath = props.getProperty(PRIVATE_KEY_FILE_PROP);
-    privateKeyAlias = "";
-    privateKeyEncrypt = null;
-    if (privateKeyFilePath != null && privateKeyFilePath.length() > 0) {
-      KeyStore ks = KeyStore.getInstance("PKCS12");
-      privateKeyAlias = props.getProperty(PRIVATE_KEY_ALIAS_PROP);
-      if (privateKeyAlias == null) {
-        privateKeyAlias = "";
-      }
-      String keyStorePass = props.getProperty(PRIVATE_KEY_PASSWD_PROP);
-      char[] passPhrase = (keyStorePass != null ? keyStorePass.toCharArray() : null);
-      FileInputStream privateKeyFile = new FileInputStream(privateKeyFilePath);
-      try {
-        ks.load(privateKeyFile, passPhrase);
-      } finally {
-        privateKeyFile.close();
-      }
-      Key key = ks.getKey(privateKeyAlias, passPhrase);
-      Certificate keyCert = ks.getCertificate(privateKeyAlias);
-      if (key instanceof PrivateKey && keyCert instanceof X509Certificate) {
-        privateKeyEncrypt = (PrivateKey) key;
-        privateKeySignAlgo = ((X509Certificate) keyCert).getSigAlgName();
-        privateKeySubject = ((X509Certificate) keyCert).getSubjectDN().getName();
-      }
-    }
-  }
-
-  /**
-   * Initialize the Diffie-Hellman keys. This method is not thread safe
-   */
-  public static void initDHKeys(DistributionConfig config) throws Exception {
-
-    dhSKAlgo = config.getSecurityClientDHAlgo();
-    dhPrivateKey = null;
-    dhPublicKey = null;
-    // Initialize the keys when either the host is a client that has
-    // non-blank setting for DH symmetric algo, or this is a server
-    // that has authenticator defined.
-    if ((dhSKAlgo != null
-        && dhSKAlgo.length() > 0) /* || securityService.isClientSecurityRequired() */) {
-      KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH");
-      DHParameterSpec dhSpec = new DHParameterSpec(dhP, dhG, dhL);
-      keyGen.initialize(dhSpec);
-      KeyPair keypair = keyGen.generateKeyPair();
-
-      // Get the generated public and private keys
-      dhPrivateKey = keypair.getPrivate();
-      dhPublicKey = keypair.getPublic();
-
-      random = new SecureRandom();
-      // Force the random generator to seed itself.
-      byte[] someBytes = new byte[48];
-      random.nextBytes(someBytes);
-    }
-  }
 
   protected void readMessage(DataInputStream dis, DataOutputStream dos, byte acceptanceCode,
       DistributedMember member) throws IOException, AuthenticationRequiredException,
@@ -1000,105 +428,7 @@ public abstract class Handshake {
           DataSerializer.readProperties(dis); // ignore the credentials
         }
       } else if (secureMode == CREDENTIALS_DHENCRYPT) {
-        boolean sendAuthentication = dis.readBoolean();
-        InternalLogWriter securityLogWriter = (InternalLogWriter) system.getSecurityLogWriter();
-        // Get the symmetric encryption algorithm to be used
-        String skAlgo = DataSerializer.readString(dis);
-        // Get the public key of the other side
-        byte[] keyBytes = DataSerializer.readByteArray(dis);
-        byte[] challenge = null;
-        PublicKey pubKey = null;
-        if (requireAuthentication) {
-          // Generate PublicKey from encoded form
-          X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
-          KeyFactory keyFact = KeyFactory.getInstance("DH");
-          pubKey = keyFact.generatePublic(x509KeySpec);
-
-          // Send the public key to other side
-          keyBytes = dhPublicKey.getEncoded();
-          challenge = new byte[64];
-          random.nextBytes(challenge);
-
-          // If the server has to also authenticate itself then
-          // sign the challenge from client.
-          if (sendAuthentication) {
-            // Get the challenge string from client
-            byte[] clientChallenge = DataSerializer.readByteArray(dis);
-            if (privateKeyEncrypt == null) {
-              throw new AuthenticationFailedException(
-                  LocalizedStrings.HandShake_SERVER_PRIVATE_KEY_NOT_AVAILABLE_FOR_CREATING_SIGNATURE
-                      .toLocalizedString());
-            }
-            // Sign the challenge from client and send it to the client
-            Signature sig = Signature.getInstance(privateKeySignAlgo);
-            sig.initSign(privateKeyEncrypt);
-            sig.update(clientChallenge);
-            byte[] signedBytes = sig.sign();
-            dos.writeByte(REPLY_OK);
-            DataSerializer.writeByteArray(keyBytes, dos);
-            // DataSerializer.writeString(privateKeyAlias, dos);
-            DataSerializer.writeString(privateKeySubject, dos);
-            DataSerializer.writeByteArray(signedBytes, dos);
-            securityLogWriter.fine("HandShake: sent the signed client challenge");
-          } else {
-            // These two lines should not be moved before the if{} statement in
-            // a common block for both if...then...else parts. This is to handle
-            // the case when an AuthenticationFailedException is thrown by the
-            // if...then part when sending the signature.
-            dos.writeByte(REPLY_OK);
-            DataSerializer.writeByteArray(keyBytes, dos);
-          }
-          // Now send the server challenge
-          DataSerializer.writeByteArray(challenge, dos);
-          securityLogWriter.fine("HandShake: sent the public key and challenge");
-          dos.flush();
-
-          // Read and decrypt the credentials
-          byte[] encBytes = DataSerializer.readByteArray(dis);
-          KeyAgreement ka = KeyAgreement.getInstance("DH");
-          ka.init(dhPrivateKey);
-          ka.doPhase(pubKey, true);
-
-          Cipher decrypt;
-
-          int keysize = getKeySize(skAlgo);
-          int blocksize = getBlockSize(skAlgo);
-
-          if (keysize == -1 || blocksize == -1) {
-            SecretKey sKey = ka.generateSecret(skAlgo);
-            decrypt = Cipher.getInstance(skAlgo);
-            decrypt.init(Cipher.DECRYPT_MODE, sKey);
-          } else {
-            String algoStr = getDhAlgoStr(skAlgo);
-
-            byte[] sKeyBytes = ka.generateSecret();
-            SecretKeySpec sks = new SecretKeySpec(sKeyBytes, 0, keysize, algoStr);
-            IvParameterSpec ivps = new IvParameterSpec(sKeyBytes, keysize, blocksize);
-
-            decrypt = Cipher.getInstance(algoStr + "/CBC/PKCS5Padding");
-            decrypt.init(Cipher.DECRYPT_MODE, sks, ivps);
-          }
-
-          byte[] credentialBytes = decrypt.doFinal(encBytes);
-          ByteArrayInputStream bis = new ByteArrayInputStream(credentialBytes);
-          DataInputStream dinp = new DataInputStream(bis);
-          credentials = DataSerializer.readProperties(dinp);
-          byte[] challengeRes = DataSerializer.readByteArray(dinp);
-          // Check the challenge string
-          if (!Arrays.equals(challenge, challengeRes)) {
-            throw new AuthenticationFailedException(
-                LocalizedStrings.HandShake_MISMATCH_IN_CHALLENGE_BYTES_MALICIOUS_CLIENT
-                    .toLocalizedString());
-          }
-          dinp.close();
-        } else {
-          if (sendAuthentication) {
-            // Read and ignore the client challenge
-            DataSerializer.readByteArray(dis);
-          }
-          dos.writeByte(REPLY_AUTH_NOT_REQUIRED);
-          dos.flush();
-        }
+        credentials = EncryptorImpl.getDecryptedCredentials(dis, dos, system, requireAuthentication, credentials);
       } else if (secureMode == SECURITY_MULTIUSER_NOTIFICATIONCHANNEL) {
         // hitesh there will be no credential CCP will get credential(Principal) using
         // ServerConnection..
@@ -1172,50 +502,4 @@ public abstract class Handshake {
         (InternalLogWriter) this.system.getLogWriter(),
         (InternalLogWriter) this.system.getSecurityLogWriter(), member, this.securityService);
   }
-
-  private static int getKeySize(String skAlgo) {
-    // skAlgo contain both algo and key size info
-    int colIdx = skAlgo.indexOf(':');
-    String algoStr;
-    int algoKeySize = 0;
-    if (colIdx >= 0) {
-      algoStr = skAlgo.substring(0, colIdx);
-      algoKeySize = Integer.parseInt(skAlgo.substring(colIdx + 1));
-    } else {
-      algoStr = skAlgo;
-    }
-    int keysize = -1;
-    if (algoStr.equalsIgnoreCase("DESede")) {
-      keysize = 24;
-    } else if (algoStr.equalsIgnoreCase("Blowfish")) {
-      keysize = algoKeySize > 128 ? algoKeySize / 8 : 16;
-    } else if (algoStr.equalsIgnoreCase("AES")) {
-      keysize = (algoKeySize != 192 && algoKeySize != 256) ? 16 : algoKeySize / 8;
-    }
-    return keysize;
-  }
-
-  private static String getDhAlgoStr(String skAlgo) {
-    int colIdx = skAlgo.indexOf(':');
-    String algoStr;
-    if (colIdx >= 0) {
-      algoStr = skAlgo.substring(0, colIdx);
-    } else {
-      algoStr = skAlgo;
-    }
-    return algoStr;
-  }
-
-  private static int getBlockSize(String skAlgo) {
-    int blocksize = -1;
-    String algoStr = getDhAlgoStr(skAlgo);
-    if (algoStr.equalsIgnoreCase("DESede")) {
-      blocksize = 8;
-    } else if (algoStr.equalsIgnoreCase("Blowfish")) {
-      blocksize = 8;
-    } else if (algoStr.equalsIgnoreCase("AES")) {
-      blocksize = 16;
-    }
-    return blocksize;
-  }
 }

-- 
To stop receiving notification emails like this one, please contact
bschuchardt@apache.org.