From d84fc4f0c80588eb10a903a43d2ffb6ff4503439 Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Wed, 23 Oct 2019 13:13:13 +0000
Subject: [PATCH] Data: Add LeaseSet methods to get encryption key by type

---
 .../src/net/i2p/data/EncryptedLeaseSet.java   | 15 ++++++++++++
 core/java/src/net/i2p/data/LeaseSet.java      | 19 +++++++++++++++
 core/java/src/net/i2p/data/LeaseSet2.java     | 24 +++++++++++++++++++
 3 files changed, 58 insertions(+)

diff --git a/core/java/src/net/i2p/data/EncryptedLeaseSet.java b/core/java/src/net/i2p/data/EncryptedLeaseSet.java
index 7d3bef8f7b..4bc4e9c0ff 100644
--- a/core/java/src/net/i2p/data/EncryptedLeaseSet.java
+++ b/core/java/src/net/i2p/data/EncryptedLeaseSet.java
@@ -7,6 +7,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 
 import net.i2p.I2PAppContext;
 import net.i2p.crypto.Blinding;
@@ -132,6 +133,20 @@ public class EncryptedLeaseSet extends LeaseSet2 {
         return super.getEncryptionKeys();
     }
 
+    /**
+     *  If more than one key, return the first supported one.
+     *  If none supported, return null.
+     *
+     *  @return first supported key or null
+     *  @since 0.9.44
+     */
+    @Override
+    public PublicKey getEncryptionKey(Set<EncType> supported) {
+        if (_decryptedLS2 != null)
+            return _decryptedLS2.getEncryptionKey(supported);
+        return super.getEncryptionKey(supported);
+    }
+
     /**
      * Overridden to set the blinded key.
      * setSecret() MUST be called before this for non-null secret, or alpha will be wrong.
diff --git a/core/java/src/net/i2p/data/LeaseSet.java b/core/java/src/net/i2p/data/LeaseSet.java
index cf88f9fa04..d2dd4a82c6 100644
--- a/core/java/src/net/i2p/data/LeaseSet.java
+++ b/core/java/src/net/i2p/data/LeaseSet.java
@@ -16,9 +16,11 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 import net.i2p.I2PAppContext;
 import net.i2p.crypto.DSAEngine;
+import net.i2p.crypto.EncType;
 import net.i2p.crypto.SigType;
 import net.i2p.util.Clock;
 import net.i2p.util.Log;
@@ -131,12 +133,29 @@ public class LeaseSet extends DatabaseEntry {
         return _encryptionKey;
     }
 
+    /**
+     *  If more than one key, return the first supported one.
+     *  If none supported, return null.
+     *
+     *  @param supported what return types are allowed
+     *  @return ElGamal key or null if ElGamal not in supported
+     *  @since 0.9.44
+     */
+    public PublicKey getEncryptionKey(Set<EncType> supported) {
+        if (supported.contains(EncType.ELGAMAL_2048))
+                return _encryptionKey;
+        return null;
+    }
+
     /**
      * @throws IllegalStateException if already signed
      */
     public void setEncryptionKey(PublicKey encryptionKey) {
         if (_signature != null)
             throw new IllegalStateException();
+        // subclasses may set an ECIES key
+        //if (encryptionKey.getType() != EncType.ELGAMAL_2048)
+        //    throw new IllegalArgumentException();
         _encryptionKey = encryptionKey;
     }
 
diff --git a/core/java/src/net/i2p/data/LeaseSet2.java b/core/java/src/net/i2p/data/LeaseSet2.java
index 6e61ac17da..3c290c080f 100644
--- a/core/java/src/net/i2p/data/LeaseSet2.java
+++ b/core/java/src/net/i2p/data/LeaseSet2.java
@@ -9,6 +9,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
 
 import net.i2p.I2PAppContext;
 import net.i2p.crypto.DSAEngine;
@@ -140,8 +141,26 @@ public class LeaseSet2 extends LeaseSet {
         return _encryptionKey;
     }
 
+    /**
+     *  If more than one key, return the first supported one.
+     *  If none supported, return null.
+     *
+     *  @return first supported key or null
+     *  @since 0.9.44
+     */
+    @Override
+    public PublicKey getEncryptionKey(Set<EncType> supported) {
+        for (PublicKey pk : getEncryptionKeys()) {
+            if (supported.contains(pk.getType()))
+                return pk;
+        }
+        return null;
+    }
+
     /**
      *  Add an encryption key.
+     *
+     *  Encryption keys should be added in order of server preference, most-preferred first.
      */
     public void addEncryptionKey(PublicKey key) {
         if (_encryptionKey == null) {
@@ -160,6 +179,11 @@ public class LeaseSet2 extends LeaseSet {
 
     /**
      *  This returns all the keys. getEncryptionKey() returns the first one.
+     *
+     *  Encryption keys should be in order of server preference, most-preferred first.
+     *  Client behavior should be to select the first key with a supported encryption type.
+     *  Clients may use other selection algorithms based on encryption support, relative performance, and other factors.
+     *
      *  @return not a copy, do not modify, null if none
      */
     public List<PublicKey> getEncryptionKeys() {
-- 
GitLab