[SSHD-846] Garbage-collect the KeyAgreement instance used in the DH KEX once 
public & private part have been calculated


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/9335f22c
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/9335f22c
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/9335f22c

Branch: refs/heads/master
Commit: 9335f22c6fd1003a610fcf4f469697a398d80225
Parents: 36853fd
Author: Goldstein Lyor <[email protected]>
Authored: Tue Oct 2 09:03:43 2018 +0300
Committer: Lyor Goldstein <[email protected]>
Committed: Wed Oct 3 20:05:17 2018 +0300

----------------------------------------------------------------------
 .../org/apache/sshd/common/kex/AbstractDH.java  | 46 +++++++++++++++++++-
 1 file changed, 44 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9335f22c/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractDH.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractDH.java 
b/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractDH.java
index d5beccb..77b0a85 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractDH.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractDH.java
@@ -27,7 +27,6 @@ import org.apache.sshd.common.util.NumberUtils;
  * Base class for the Diffie-Hellman key agreement.
  */
 public abstract class AbstractDH {
-
     protected KeyAgreement myKeyAgree;
 
     private byte[] k_array; // shared secret key
@@ -37,27 +36,70 @@ public abstract class AbstractDH {
         super();
     }
 
-    public abstract void setF(byte[] e);
+    public abstract void setF(byte[] f);
 
+    /**
+     * Lazy-called by {@link #getE()} if the public key data has not
+     * been generated yet.
+     *
+     * @return The calculated public key data
+     * @throws Exception If failed to generate the relevant data
+     */
     protected abstract byte[] calculateE() throws Exception;
 
+    /**
+     * @return The local public key data
+     * @throws Exception If failed to calculate it
+     */
     public byte[] getE() throws Exception {
         if (e_array == null) {
             e_array = calculateE();
+            checkKeyAgreementNecessity();
         }
 
         return e_array;
     }
 
+    /**
+     * Lazy-called by {@link #getK()} if the shared secret data has
+     * not been calculated yet
+     *
+     * @return The shared secret data
+     * @throws Exception If failed to calculate it
+     */
     protected abstract byte[] calculateK() throws Exception;
 
+    /**
+     * @return The shared secret key
+     * @throws Exception If failed to calculate it
+     */
     public byte[] getK() throws Exception {
         if (k_array == null) {
             k_array = calculateK();
+            checkKeyAgreementNecessity();
         }
         return k_array;
     }
 
+    /**
+     * Called after either public or private parts have been calculated
+     * in order to check if the key-agreement mediator is still required.
+     * By default, if both public and private parts have been calculated
+     * then key-agreement mediator is null-ified to enable GC for it.
+     *
+     * @see #getE()
+     * @see #getK()
+     */
+    protected void checkKeyAgreementNecessity() {
+        if ((e_array == null) || (k_array == null)) {
+            return;
+        }
+
+        if (myKeyAgree != null) {
+            myKeyAgree = null;  // allow GC for key agreement object
+        }
+    }
+
     public abstract Digest getHash() throws Exception;
 
     /**

Reply via email to