You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2018/11/18 04:54:57 UTC

[02/12] mina-sshd git commit: [SSHD-862] Propagate available session context to code that deals with loading private keys

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/FileKeyPairProvider.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/FileKeyPairProvider.java b/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/FileKeyPairProvider.java
index a416871..f7de669 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/FileKeyPairProvider.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/FileKeyPairProvider.java
@@ -77,12 +77,15 @@ public class FileKeyPairProvider extends AbstractResourceKeyPairProvider<Path> {
     }
 
     @Override
-    protected KeyPair doLoadKey(SessionContext session, Path resource) throws IOException, GeneralSecurityException {
+    protected KeyPair doLoadKey(SessionContext session, Path resource)
+            throws IOException, GeneralSecurityException {
         return super.doLoadKey(session, (resource == null) ? null : resource.toAbsolutePath());
     }
 
     @Override
-    protected InputStream openKeyPairResource(String resourceKey, Path resource) throws IOException {
+    protected InputStream openKeyPairResource(
+            SessionContext session, String resourceKey, Path resource)
+                throws IOException {
         return Files.newInputStream(resource, IoUtils.EMPTY_OPEN_OPTIONS);
     }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java b/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java
index 46b6f52..3298f20 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java
@@ -19,6 +19,8 @@
 
 package org.apache.sshd.common.keyprovider;
 
+import java.io.IOException;
+import java.security.GeneralSecurityException;
 import java.security.KeyPair;
 import java.util.Collection;
 import java.util.Collections;
@@ -53,37 +55,11 @@ public interface KeyIdentityProvider {
      *
      * @param session The {@link SessionContext} for invoking this load command - may
      * be {@code null} if not invoked within a session context (e.g., offline tool or session unknown).
+     * @throws IOException If failed to read/parse the keys data
+     * @throws GeneralSecurityException If failed to generate the keys
      * @return an {@link Iterable} instance of available keys - ignored if {@code null}
      */
-    Iterable<KeyPair> loadKeys(SessionContext session);
-
-    /**
-     * Creates a &quot;unified&quot; {@link Iterator} of {@link KeyPair}s out of 2 possible
-     * {@link KeyIdentityProvider}
-     *
-     * @param session The {@link SessionContext} for invoking this load command - may
-     * be {@code null} if not invoked within a session context (e.g., offline tool or session unknown).
-     * @param identities The registered keys identities
-     * @param keys Extra available key pairs
-     * @return The wrapping iterator
-     * @see #resolveKeyIdentityProvider(KeyIdentityProvider, KeyIdentityProvider)
-     */
-    static Iterator<KeyPair> iteratorOf(
-            SessionContext session, KeyIdentityProvider identities, KeyIdentityProvider keys) {
-        return iteratorOf(session, resolveKeyIdentityProvider(identities, keys));
-    }
-
-    /**
-     * Resolves a non-{@code null} iterator of the available keys
-     *
-     * @param session The {@link SessionContext} for invoking this load command - may
-     * be {@code null} if not invoked within a session context (e.g., offline tool or session unknown).
-     * @param provider The {@link KeyIdentityProvider} - ignored if {@code null}
-     * @return A non-{@code null} iterator - which may be empty if no provider or no keys
-     */
-    static Iterator<KeyPair> iteratorOf(SessionContext session, KeyIdentityProvider provider) {
-        return GenericUtils.iteratorOf((provider == null) ? null : provider.loadKeys(session));
-    }
+    Iterable<KeyPair> loadKeys(SessionContext session) throws IOException, GeneralSecurityException;
 
     /**
      * <P>Creates a &quot;unified&quot; {@link KeyIdentityProvider} out of 2 possible ones
@@ -159,7 +135,12 @@ public interface KeyIdentityProvider {
             return Collections.emptyList();
         } else if (numProviders == 1) {
             KeyIdentityProvider p = GenericUtils.head(providers);
-            return p.loadKeys(session);
+            try {
+                return p.loadKeys(session);
+            } catch (IOException | GeneralSecurityException e) {
+                throw new RuntimeException("Unexpected " + e.getClass().getSimpleName() + ")"
+                    + " keys loading exception: " + e.getMessage(), e);
+            }
         } else {
             return new Iterable<KeyPair>() {
                 @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProvider.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProvider.java b/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProvider.java
index 6b2224f..237b61f 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProvider.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProvider.java
@@ -18,6 +18,8 @@
  */
 package org.apache.sshd.common.keyprovider;
 
+import java.io.IOException;
+import java.security.GeneralSecurityException;
 import java.security.KeyPair;
 import java.util.Arrays;
 import java.util.Collection;
@@ -105,8 +107,11 @@ public interface KeyPairProvider extends KeyIdentityProvider {
      * be {@code null} if not invoked within a session context (e.g., offline tool).
      * @param type the type of key to load
      * @return a valid key pair or {@code null} if this type of key is not available
+     * @throws IOException If failed to read/parse the keys data
+     * @throws GeneralSecurityException If failed to generate the keys
      */
-    default KeyPair loadKey(SessionContext session, String type) {
+    default KeyPair loadKey(SessionContext session, String type)
+            throws IOException, GeneralSecurityException {
         ValidateUtils.checkNotNullAndNotEmpty(type, "No key type to load");
         return GenericUtils.stream(loadKeys(session))
                 .filter(key -> type.equals(KeyUtils.getKeyType(key)))
@@ -118,8 +123,11 @@ public interface KeyPairProvider extends KeyIdentityProvider {
      * @param session The {@link SessionContext} for invoking this load command - may
      * be {@code null} if not invoked within a session context (e.g., offline tool).
      * @return The available {@link Iterable} key types in preferred order - never {@code null}
+     * @throws IOException If failed to read/parse the keys data
+     * @throws GeneralSecurityException If failed to generate the keys
      */
-    default Iterable<String> getKeyTypes(SessionContext session) {
+    default Iterable<String> getKeyTypes(SessionContext session)
+            throws IOException, GeneralSecurityException {
         return GenericUtils.stream(loadKeys(session))
                 .map(KeyUtils::getKeyType)
                 .filter(GenericUtils::isNotEmpty)

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/MultiKeyIdentityIterator.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/MultiKeyIdentityIterator.java b/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/MultiKeyIdentityIterator.java
index 9de7c17..09d5f29 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/MultiKeyIdentityIterator.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/MultiKeyIdentityIterator.java
@@ -19,6 +19,8 @@
 
 package org.apache.sshd.common.keyprovider;
 
+import java.io.IOException;
+import java.security.GeneralSecurityException;
 import java.security.KeyPair;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
@@ -69,7 +71,13 @@ public class MultiKeyIdentityIterator implements Iterator<KeyPair> {
         SessionContext session = getSessionContext();
         while (provs.hasNext()) {
             KeyIdentityProvider p = provs.next();
-            Iterable<KeyPair> keys = (p == null) ? null : p.loadKeys(session);
+            Iterable<KeyPair> keys;
+            try {
+                keys = (p == null) ? null : p.loadKeys(session);
+            } catch (IOException | GeneralSecurityException e) {
+                throw new RuntimeException("Unexpected " + e.getClass().getSimpleName() + ")"
+                    + " keys loading exception: " + e.getMessage(), e);
+            }
             currentProvider = (keys == null) ? null : keys.iterator();
 
             if ((currentProvider != null) && currentProvider.hasNext()) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/main/java/org/apache/sshd/common/session/SessionContext.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/session/SessionContext.java b/sshd-common/src/main/java/org/apache/sshd/common/session/SessionContext.java
index 87827bd..c937079 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/session/SessionContext.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/session/SessionContext.java
@@ -19,7 +19,7 @@
 
 package org.apache.sshd.common.session;
 
-import org.apache.sshd.common.AttributeRepository;
+import org.apache.sshd.common.AttributeStore;
 import org.apache.sshd.common.PropertyResolver;
 import org.apache.sshd.common.auth.UsernameHolder;
 import org.apache.sshd.common.util.GenericUtils;
@@ -34,7 +34,7 @@ public interface SessionContext
         extends ConnectionEndpointsIndicator,
                 UsernameHolder,
                 PropertyResolver,
-                AttributeRepository {
+                AttributeStore {
     /**
      * Default prefix expected for the client / server identification string
      * @see <A HREF="https://tools.ietf.org/html/rfc4253#section-4.2">RFC 4253 - section 4.2</A>

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/main/java/org/apache/sshd/common/util/ValidateUtils.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/ValidateUtils.java b/sshd-common/src/main/java/org/apache/sshd/common/util/ValidateUtils.java
index a55e5d6..35f46d9 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/util/ValidateUtils.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/util/ValidateUtils.java
@@ -213,4 +213,16 @@ public final class ValidateUtils {
         return constructor.apply(message);
     }
 
+    public static <T extends Throwable> T initializeExceptionCause(T err, Throwable cause) {
+        if (cause == null) {
+            return err;
+        }
+
+        if (err.getCause() != null) {
+            return err; // already initialized - avoid IllegalStateException
+        }
+
+        err.initCause(cause);
+        return err;
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java b/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
index 1534f95..2949875 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
@@ -67,6 +67,7 @@ import org.apache.sshd.common.config.keys.loader.pem.PEMResourceParserUtils;
 import org.apache.sshd.common.keyprovider.KeyPairProvider;
 import org.apache.sshd.common.random.JceRandomFactory;
 import org.apache.sshd.common.random.RandomFactory;
+import org.apache.sshd.common.session.SessionContext;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
@@ -468,9 +469,10 @@ public final class SecurityUtils {
     /* -------------------------------------------------------------------- */
 
     /**
+     * @param session The {@link SessionContext} for invoking this load command - may
+     * be {@code null} if not invoked within a session context (e.g., offline tool).
      * @param resourceKey An identifier of the key being loaded - used as
-     *                    argument to the {@link FilePasswordProvider#getPassword(String, int)}
-     *                    invocation
+     * argument to the {@code FilePasswordProvider#getPassword} invocation
      * @param inputStream The {@link InputStream} for the <U>private</U> key
      * @param provider    A {@link FilePasswordProvider} - may be {@code null}
      *                    if the loaded key is <U>guaranteed</U> not to be encrypted
@@ -478,23 +480,25 @@ public final class SecurityUtils {
      * @throws IOException              If failed to read/parse the input stream
      * @throws GeneralSecurityException If failed to generate the keys
      */
-    public static KeyPair loadKeyPairIdentity(String resourceKey, InputStream inputStream, FilePasswordProvider provider)
-            throws IOException, GeneralSecurityException {
+    public static KeyPair loadKeyPairIdentity(
+            SessionContext session, String resourceKey, InputStream inputStream, FilePasswordProvider provider)
+                throws IOException, GeneralSecurityException {
         KeyPairResourceParser parser = getKeyPairResourceParser();
         if (parser == null) {
             throw new NoSuchProviderException("No registered key-pair resource parser");
         }
 
-        Collection<KeyPair> ids = parser.loadKeyPairs(resourceKey, provider, inputStream);
+        Collection<KeyPair> ids = parser.loadKeyPairs(session, resourceKey, provider, inputStream);
         int numLoaded = GenericUtils.size(ids);
         if (numLoaded <= 0) {
-            throw new InvalidKeyException("Unsupported private key file format: " + resourceKey);
+            return null;
         }
+
         if (numLoaded != 1) {
             throw new InvalidKeySpecException("Multiple private key pairs N/A: " + resourceKey);
         }
 
-        return ids.iterator().next();
+        return GenericUtils.head(ids);
     }
 
     /* -------------------------------------------------------------------- */

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleKeyPairResourceParser.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleKeyPairResourceParser.java b/sshd-common/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleKeyPairResourceParser.java
index 5c8befb..881adff 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleKeyPairResourceParser.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleKeyPairResourceParser.java
@@ -39,6 +39,7 @@ import javax.security.auth.login.FailedLoginException;
 import org.apache.sshd.common.config.keys.FilePasswordProvider;
 import org.apache.sshd.common.config.keys.FilePasswordProvider.ResourceDecodeResult;
 import org.apache.sshd.common.config.keys.loader.AbstractKeyPairResourceParser;
+import org.apache.sshd.common.session.SessionContext;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.io.IoUtils;
 import org.apache.sshd.common.util.security.SecurityProviderRegistrar;
@@ -76,7 +77,7 @@ public class BouncyCastleKeyPairResourceParser extends AbstractKeyPairResourcePa
 
     @Override
     public Collection<KeyPair> extractKeyPairs(
-            String resourceKey, String beginMarker, String endMarker, FilePasswordProvider passwordProvider, List<String> lines)
+            SessionContext session, String resourceKey, String beginMarker, String endMarker, FilePasswordProvider passwordProvider, List<String> lines)
                 throws IOException, GeneralSecurityException {
         StringBuilder writer = new StringBuilder(beginMarker.length() + endMarker.length() + lines.size() * 80);
         writer.append(beginMarker).append(IoUtils.EOL);
@@ -86,20 +87,24 @@ public class BouncyCastleKeyPairResourceParser extends AbstractKeyPairResourcePa
         String data = writer.toString();
         byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
         try (InputStream bais = new ByteArrayInputStream(dataBytes)) {
-            return extractKeyPairs(resourceKey, beginMarker, endMarker, passwordProvider, bais);
+            return extractKeyPairs(session, resourceKey, beginMarker, endMarker, passwordProvider, bais);
         }
     }
 
     @Override
     public Collection<KeyPair> extractKeyPairs(
-            String resourceKey, String beginMarker, String endMarker, FilePasswordProvider passwordProvider, InputStream stream)
+            SessionContext session, String resourceKey,
+            String beginMarker, String endMarker,
+            FilePasswordProvider passwordProvider,
+            InputStream stream)
                 throws IOException, GeneralSecurityException {
-        KeyPair kp = loadKeyPair(resourceKey, stream, passwordProvider);
+        KeyPair kp = loadKeyPair(session, resourceKey, stream, passwordProvider);
         return (kp == null) ? Collections.emptyList() : Collections.singletonList(kp);
     }
 
-    public static KeyPair loadKeyPair(String resourceKey, InputStream inputStream, FilePasswordProvider provider)
-            throws IOException, GeneralSecurityException {
+    public static KeyPair loadKeyPair(
+            SessionContext session, String resourceKey, InputStream inputStream, FilePasswordProvider provider)
+                throws IOException, GeneralSecurityException {
         try (PEMParser r = new PEMParser(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
             Object o = r.readObject();
 
@@ -122,7 +127,7 @@ public class BouncyCastleKeyPairResourceParser extends AbstractKeyPairResourcePa
                 }
 
                 for (int retryIndex = 0;; retryIndex++) {
-                    String password = provider.getPassword(resourceKey, retryIndex);
+                    String password = provider.getPassword(session, resourceKey, retryIndex);
                     PEMKeyPair decoded;
                     try {
                         if (GenericUtils.isEmpty(password)) {
@@ -134,7 +139,7 @@ public class BouncyCastleKeyPairResourceParser extends AbstractKeyPairResourcePa
                         decoded = ((PEMEncryptedKeyPair) o).decryptKeyPair(pemDecryptor);
                     } catch (IOException | GeneralSecurityException | RuntimeException e) {
                         ResourceDecodeResult result =
-                            provider.handleDecodeAttemptResult(resourceKey, retryIndex, password, e);
+                            provider.handleDecodeAttemptResult(session, resourceKey, retryIndex, password, e);
                         if (result == null) {
                             result = ResourceDecodeResult.TERMINATE;
                         }
@@ -151,7 +156,7 @@ public class BouncyCastleKeyPairResourceParser extends AbstractKeyPairResourcePa
                     }
 
                     o = decoded;
-                    provider.handleDecodeAttemptResult(resourceKey, retryIndex, password, null);
+                    provider.handleDecodeAttemptResult(session, resourceKey, retryIndex, password, null);
                     break;
                 }
             }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/OpenSSHEd25519PrivateKeyEntryDecoder.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/OpenSSHEd25519PrivateKeyEntryDecoder.java b/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/OpenSSHEd25519PrivateKeyEntryDecoder.java
index 2f1d055..f9402eb 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/OpenSSHEd25519PrivateKeyEntryDecoder.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/OpenSSHEd25519PrivateKeyEntryDecoder.java
@@ -36,6 +36,7 @@ import org.apache.sshd.common.config.keys.FilePasswordProvider;
 import org.apache.sshd.common.config.keys.KeyEntryResolver;
 import org.apache.sshd.common.config.keys.impl.AbstractPrivateKeyEntryDecoder;
 import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.session.SessionContext;
 import org.apache.sshd.common.util.security.SecurityUtils;
 
 import net.i2p.crypto.eddsa.EdDSAPrivateKey;
@@ -62,8 +63,9 @@ public class OpenSSHEd25519PrivateKeyEntryDecoder extends AbstractPrivateKeyEntr
     }
 
     @Override
-    public EdDSAPrivateKey decodePrivateKey(String keyType, FilePasswordProvider passwordProvider, InputStream keyData)
-            throws IOException, GeneralSecurityException {
+    public EdDSAPrivateKey decodePrivateKey(
+            SessionContext session, String keyType, FilePasswordProvider passwordProvider, InputStream keyData)
+                throws IOException, GeneralSecurityException {
         if (!KeyPairProvider.SSH_ED25519.equals(keyType)) {
             throw new InvalidKeyException("Unsupported key type: " + keyType);
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java b/sshd-common/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
index d30b4b8..71e3a4f 100644
--- a/sshd-common/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
+++ b/sshd-common/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
@@ -249,7 +249,7 @@ public abstract class AbstractGeneratorHostKeyProvider extends AbstractKeyPairPr
 
     protected KeyPair doReadKeyPair(SessionContext session, String resourceKey, InputStream inputStream)
             throws IOException, GeneralSecurityException {
-        return SecurityUtils.loadKeyPairIdentity(resourceKey, inputStream, null);
+        return SecurityUtils.loadKeyPairIdentity(session, resourceKey, inputStream, null);
     }
 
     protected void writeKeyPair(KeyPair kp, Path keyPath, OpenOption... options)

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/test/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcherTest.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/test/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcherTest.java b/sshd-common/src/test/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcherTest.java
index 4f4b285..81c458f 100644
--- a/sshd-common/src/test/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcherTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcherTest.java
@@ -40,6 +40,7 @@ import org.apache.sshd.common.config.keys.FilePasswordProvider;
 import org.apache.sshd.common.config.keys.KeyUtils;
 import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
 import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.session.SessionContext;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.io.IoUtils;
@@ -78,7 +79,9 @@ public class BuiltinClientIdentitiesWatcherTest extends JUnitTestSupport {
 
         ClientIdentityLoader loader = new ClientIdentityLoader() {
             @Override
-            public KeyPair loadClientIdentity(String location, FilePasswordProvider provider) throws IOException, GeneralSecurityException {
+            public KeyPair loadClientIdentity(
+                    SessionContext session, String location, FilePasswordProvider provider)
+                        throws IOException, GeneralSecurityException {
                 BuiltinIdentities id = findIdentity(location);
                 assertNotNull("Invalid location: " + location, id);
                 return idsMap.get(id);
@@ -144,7 +147,9 @@ public class BuiltinClientIdentitiesWatcherTest extends JUnitTestSupport {
         }
     }
 
-    private static void testMultipleFilesWatch(String phase, KeyIdentityProvider watcher, Collection<? extends KeyPair> expected) {
+    private static void testMultipleFilesWatch(
+            String phase, KeyIdentityProvider watcher, Collection<? extends KeyPair> expected)
+                throws IOException, GeneralSecurityException {
         Iterable<KeyPair> keys = watcher.loadKeys(null);
         Collection<KeyPair> actual = new ArrayList<>();
         for (KeyPair kp : keys) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/test/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcherTest.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/test/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcherTest.java b/sshd-common/src/test/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcherTest.java
index 690a381..bd43f44 100644
--- a/sshd-common/src/test/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcherTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcherTest.java
@@ -60,7 +60,9 @@ public class ClientIdentityFileWatcherTest extends JUnitTestSupport {
         KeyPair identity = CommonTestSupportUtils.getFirstKeyPair(createTestHostKeyProvider());
         ClientIdentityLoader loader = new ClientIdentityLoader() {
             @Override
-            public KeyPair loadClientIdentity(String location, FilePasswordProvider provider) throws IOException, GeneralSecurityException {
+            public KeyPair loadClientIdentity(
+                    SessionContext session, String location, FilePasswordProvider provider)
+                        throws IOException, GeneralSecurityException {
                 assertTrue("Invalid location: " + location, isValidLocation(location));
                 return identity;
             }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/test/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParserTest.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/test/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParserTest.java b/sshd-common/src/test/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParserTest.java
index d5c6aba..680a53f 100644
--- a/sshd-common/src/test/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParserTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParserTest.java
@@ -73,7 +73,7 @@ public class OpenSSHKeyPairResourceParserTest extends JUnitTestSupport {
         URL urlKeyPair = getClass().getResource(resourceKey);
         assertNotNull("Missing key-pair resource: " + resourceKey, urlKeyPair);
 
-        Collection<KeyPair> pairs = PARSER.loadKeyPairs(urlKeyPair, FilePasswordProvider.EMPTY);
+        Collection<KeyPair> pairs = PARSER.loadKeyPairs(null, urlKeyPair, FilePasswordProvider.EMPTY);
         assertEquals("Mismatched pairs count", 1, GenericUtils.size(pairs));
 
         URL urlPubKey = getClass().getResource(resourceKey + ".pub");

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/test/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PEMResourceKeyPairParserTest.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/test/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PEMResourceKeyPairParserTest.java b/sshd-common/src/test/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PEMResourceKeyPairParserTest.java
index 406a273..9775e2c 100644
--- a/sshd-common/src/test/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PEMResourceKeyPairParserTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PEMResourceKeyPairParserTest.java
@@ -92,7 +92,7 @@ public class PKCS8PEMResourceKeyPairParserTest extends JUnitTestSupport {
             os.close();
 
             try (ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                KeyPair kp2 = SecurityUtils.loadKeyPairIdentity(getCurrentTestName(), bais, null);
+                KeyPair kp2 = SecurityUtils.loadKeyPairIdentity(null, getCurrentTestName(), bais, null);
 
                 assertEquals("Mismatched public key", kp.getPublic(), kp2.getPublic());
                 assertEquals("Mismatched private key", prv1, kp2.getPrivate());

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/test/java/org/apache/sshd/common/keyprovider/KeyPairProviderTest.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/test/java/org/apache/sshd/common/keyprovider/KeyPairProviderTest.java b/sshd-common/src/test/java/org/apache/sshd/common/keyprovider/KeyPairProviderTest.java
index 6f00621..fb9ed8c 100644
--- a/sshd-common/src/test/java/org/apache/sshd/common/keyprovider/KeyPairProviderTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/common/keyprovider/KeyPairProviderTest.java
@@ -19,6 +19,8 @@
 
 package org.apache.sshd.common.keyprovider;
 
+import java.io.IOException;
+import java.security.GeneralSecurityException;
 import java.security.KeyPair;
 import java.security.PrivateKey;
 import java.security.PublicKey;
@@ -46,7 +48,7 @@ public class KeyPairProviderTest extends JUnitTestSupport {
     }
 
     @Test
-    public void testEmptyKeyProvider() {
+    public void testEmptyKeyProvider() throws IOException, GeneralSecurityException {
         KeyPairProvider provider = KeyPairProvider.EMPTY_KEYPAIR_PROVIDER;
         assertTrue("Non empty loaded keys", GenericUtils.isEmpty(provider.loadKeys(null)));
         assertTrue("Non empty key type", GenericUtils.isEmpty(provider.getKeyTypes(null)));
@@ -57,7 +59,7 @@ public class KeyPairProviderTest extends JUnitTestSupport {
     }
 
     @Test
-    public void testMapToKeyPairProvider() {
+    public void testMapToKeyPairProvider() throws IOException, GeneralSecurityException {
         PublicKey pubKey = Mockito.mock(PublicKey.class);
         PrivateKey prvKey = Mockito.mock(PrivateKey.class);
         String[] testKeys = {getCurrentTestName(), getClass().getSimpleName()};
@@ -71,9 +73,11 @@ public class KeyPairProviderTest extends JUnitTestSupport {
         assertEquals("Key types", pairsMap.keySet(), provider.getKeyTypes(null));
         assertEquals("Key pairs", pairsMap.values(), provider.loadKeys(null));
 
-        pairsMap.forEach((keyType, expected) -> {
+        for (Map.Entry<String, KeyPair> pe : pairsMap.entrySet()) {
+            String keyType = pe.getKey();
+            KeyPair expected = pe.getValue();
             KeyPair actual = provider.loadKey(null, keyType);
             assertSame(keyType, expected, actual);
-        });
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/test/java/org/apache/sshd/common/keyprovider/MultiKeyIdentityProviderTest.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/test/java/org/apache/sshd/common/keyprovider/MultiKeyIdentityProviderTest.java b/sshd-common/src/test/java/org/apache/sshd/common/keyprovider/MultiKeyIdentityProviderTest.java
index e5a4329..a1a2dca 100644
--- a/sshd-common/src/test/java/org/apache/sshd/common/keyprovider/MultiKeyIdentityProviderTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/common/keyprovider/MultiKeyIdentityProviderTest.java
@@ -19,6 +19,8 @@
 
 package org.apache.sshd.common.keyprovider;
 
+import java.io.IOException;
+import java.security.GeneralSecurityException;
 import java.security.KeyPair;
 import java.security.PrivateKey;
 import java.security.PublicKey;
@@ -47,7 +49,7 @@ public class MultiKeyIdentityProviderTest extends JUnitTestSupport {
     }
 
     @Test   // see SSHD-860
-    public void testLazyKeyIdentityMultiProvider() {
+    public void testLazyKeyIdentityMultiProvider() throws IOException, GeneralSecurityException {
         List<KeyPair> expected = new ArrayList<>();
         for (int index = 1; index <= Short.SIZE; index++) {
             PublicKey pub = Mockito.mock(PublicKey.class);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityUtilsTest.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityUtilsTest.java b/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityUtilsTest.java
index 488d2ce..e6019fe 100644
--- a/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityUtilsTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityUtilsTest.java
@@ -67,7 +67,7 @@ public class SecurityUtilsTest extends JUnitTestSupport {
           + "." + SecurityProviderRegistrar.NAMED_PROVIDER_PROPERTY;
 
     private static final String DEFAULT_PASSWORD = "super secret passphrase";
-    private static final FilePasswordProvider TEST_PASSWORD_PROVIDER = (file, index) -> DEFAULT_PASSWORD;
+    private static final FilePasswordProvider TEST_PASSWORD_PROVIDER = (session, file, index) -> DEFAULT_PASSWORD;
 
     public SecurityUtilsTest() {
         super();
@@ -155,7 +155,7 @@ public class SecurityUtilsTest extends JUnitTestSupport {
         KeyPair kpFile = testLoadPrivateKeyFile(file, pubType, prvType);
         if (SecurityUtils.isBouncyCastleRegistered()) {
             KeyPairResourceLoader bcLoader = SecurityUtils.getBouncycastleKeyPairResourceParser();
-            Collection<KeyPair> kpList = bcLoader.loadKeyPairs(file, TEST_PASSWORD_PROVIDER);
+            Collection<KeyPair> kpList = bcLoader.loadKeyPairs(null, file, TEST_PASSWORD_PROVIDER);
             assertEquals(name + ": Mismatched loaded BouncyCastle keys count", 1, GenericUtils.size(kpList));
 
             KeyPair kpBC = kpList.iterator().next();
@@ -170,18 +170,21 @@ public class SecurityUtilsTest extends JUnitTestSupport {
     }
 
     private static KeyPair testLoadPrivateKeyResource(
-            String name, Class<? extends PublicKey> pubType, Class<? extends PrivateKey> prvType) {
+            String name, Class<? extends PublicKey> pubType, Class<? extends PrivateKey> prvType)
+                throws IOException, GeneralSecurityException {
         return testLoadPrivateKey(name, new ClassLoadableResourceKeyPairProvider(name), pubType, prvType);
     }
 
     private static KeyPair testLoadPrivateKeyFile(
-            Path file, Class<? extends PublicKey> pubType, Class<? extends PrivateKey> prvType) {
+            Path file, Class<? extends PublicKey> pubType, Class<? extends PrivateKey> prvType)
+                throws IOException, GeneralSecurityException {
         return testLoadPrivateKey(file.toString(), new FileKeyPairProvider(file), pubType, prvType);
     }
 
     private static KeyPair testLoadPrivateKey(
             String resourceKey, AbstractResourceKeyPairProvider<?> provider,
-            Class<? extends PublicKey> pubType, Class<? extends PrivateKey> prvType) {
+            Class<? extends PublicKey> pubType, Class<? extends PrivateKey> prvType)
+                throws IOException, GeneralSecurityException {
         provider.setPasswordFinder(TEST_PASSWORD_PROVIDER);
         Iterable<KeyPair> iterator = provider.loadKeys(null);
         List<KeyPair> pairs = new ArrayList<>();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/test/java/org/apache/sshd/server/keyprovider/PEMGeneratorHostKeyProviderTest.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/test/java/org/apache/sshd/server/keyprovider/PEMGeneratorHostKeyProviderTest.java b/sshd-common/src/test/java/org/apache/sshd/server/keyprovider/PEMGeneratorHostKeyProviderTest.java
index af4a6b7..a7a4659 100644
--- a/sshd-common/src/test/java/org/apache/sshd/server/keyprovider/PEMGeneratorHostKeyProviderTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/server/keyprovider/PEMGeneratorHostKeyProviderTest.java
@@ -21,6 +21,7 @@ package org.apache.sshd.server.keyprovider;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.security.GeneralSecurityException;
 import java.security.KeyPair;
 import java.security.PublicKey;
 import java.security.interfaces.ECPublicKey;
@@ -51,19 +52,19 @@ public class PEMGeneratorHostKeyProviderTest extends JUnitTestSupport {
     }
 
     @Test
-    public void testDSA() throws IOException {
+    public void testDSA() throws IOException, GeneralSecurityException {
         Assume.assumeTrue("BouncyCastle not registered", SecurityUtils.isBouncyCastleRegistered());
         testPEMGeneratorHostKeyProvider(KeyUtils.DSS_ALGORITHM, KeyPairProvider.SSH_DSS, 512, null);
     }
 
     @Test
-    public void testRSA() throws IOException {
+    public void testRSA() throws IOException, GeneralSecurityException {
         Assume.assumeTrue("BouncyCastle not registered", SecurityUtils.isBouncyCastleRegistered());
         testPEMGeneratorHostKeyProvider(KeyUtils.RSA_ALGORITHM, KeyPairProvider.SSH_RSA, 512, null);
     }
 
     @Test
-    public void testECnistp256() throws IOException {
+    public void testECnistp256() throws IOException, GeneralSecurityException {
         Assume.assumeTrue("BouncyCastle not registered", SecurityUtils.isBouncyCastleRegistered());
         Assume.assumeTrue("ECC not supported", SecurityUtils.isECCSupported());
         Assume.assumeTrue(ECCurves.nistp256 + " N/A", ECCurves.nistp256.isSupported());
@@ -71,7 +72,7 @@ public class PEMGeneratorHostKeyProviderTest extends JUnitTestSupport {
     }
 
     @Test
-    public void testECnistp384() throws IOException {
+    public void testECnistp384() throws IOException, GeneralSecurityException {
         Assume.assumeTrue("BouncyCastle not registered", SecurityUtils.isBouncyCastleRegistered());
         Assume.assumeTrue("ECC not supported", SecurityUtils.isECCSupported());
         Assume.assumeTrue(ECCurves.nistp384 + " N/A", ECCurves.nistp384.isSupported());
@@ -79,14 +80,16 @@ public class PEMGeneratorHostKeyProviderTest extends JUnitTestSupport {
     }
 
     @Test
-    public void testECnistp521() throws IOException {
+    public void testECnistp521() throws IOException, GeneralSecurityException {
         Assume.assumeTrue("BouncyCastle not registered", SecurityUtils.isBouncyCastleRegistered());
         Assume.assumeTrue("ECC not supported", SecurityUtils.isECCSupported());
         Assume.assumeTrue(ECCurves.nistp521 + " N/A", ECCurves.nistp521.isSupported());
         testPEMGeneratorHostKeyProvider(KeyUtils.EC_ALGORITHM, KeyPairProvider.ECDSA_SHA2_NISTP521, -1, new ECGenParameterSpec("P-521"));
     }
 
-    private Path testPEMGeneratorHostKeyProvider(String algorithm, String keyType, int keySize, AlgorithmParameterSpec keySpec) throws IOException {
+    private Path testPEMGeneratorHostKeyProvider(
+            String algorithm, String keyType, int keySize, AlgorithmParameterSpec keySpec)
+                throws IOException, GeneralSecurityException {
         Path path = initKeyFileLocation(algorithm);
         KeyPair kpWrite = invokePEMGeneratorHostKeyProvider(path, algorithm, keyType, keySize, keySpec);
         assertTrue("Key file not generated: " + path, Files.exists(path, IoUtils.EMPTY_LINK_OPTIONS));
@@ -103,7 +106,9 @@ public class PEMGeneratorHostKeyProviderTest extends JUnitTestSupport {
         return path;
     }
 
-    private static KeyPair invokePEMGeneratorHostKeyProvider(Path path, String algorithm, String keyType, int keySize, AlgorithmParameterSpec keySpec) {
+    private static KeyPair invokePEMGeneratorHostKeyProvider(
+            Path path, String algorithm, String keyType, int keySize, AlgorithmParameterSpec keySpec)
+                throws IOException, GeneralSecurityException {
         AbstractGeneratorHostKeyProvider provider = SecurityUtils.createGeneratorHostKeyProvider(path.toAbsolutePath().normalize());
         provider.setAlgorithm(algorithm);
         provider.setOverwriteAllowed(true);
@@ -117,7 +122,8 @@ public class PEMGeneratorHostKeyProviderTest extends JUnitTestSupport {
         return validateKeyPairProvider(provider, keyType);
     }
 
-    private static KeyPair validateKeyPairProvider(KeyPairProvider provider, String keyType) {
+    private static KeyPair validateKeyPairProvider(KeyPairProvider provider, String keyType)
+            throws IOException, GeneralSecurityException {
         Iterable<String> types = provider.getKeyTypes(null);
         KeyPair kp = null;
         for (String type : types) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/test/java/org/apache/sshd/server/keyprovider/SimpleGeneratorHostKeyProviderTest.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/test/java/org/apache/sshd/server/keyprovider/SimpleGeneratorHostKeyProviderTest.java b/sshd-common/src/test/java/org/apache/sshd/server/keyprovider/SimpleGeneratorHostKeyProviderTest.java
index ab0ff2c..fe4a7d0 100644
--- a/sshd-common/src/test/java/org/apache/sshd/server/keyprovider/SimpleGeneratorHostKeyProviderTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/server/keyprovider/SimpleGeneratorHostKeyProviderTest.java
@@ -21,6 +21,7 @@ package org.apache.sshd.server.keyprovider;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.security.GeneralSecurityException;
 import java.security.KeyPair;
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.ECGenParameterSpec;
@@ -51,17 +52,17 @@ public class SimpleGeneratorHostKeyProviderTest extends JUnitTestSupport {
     }
 
     @Test
-    public void testDSA() throws IOException {
+    public void testDSA() throws IOException, GeneralSecurityException {
         testSimpleGeneratorHostKeyProvider(KeyUtils.DSS_ALGORITHM, KeyPairProvider.SSH_DSS, 512, null);
     }
 
     @Test
-    public void testRSA() throws IOException {
+    public void testRSA() throws IOException, GeneralSecurityException {
         testSimpleGeneratorHostKeyProvider(KeyUtils.RSA_ALGORITHM, KeyPairProvider.SSH_RSA, 512, null);
     }
 
     @Test
-    public void testECnistp256() throws IOException {
+    public void testECnistp256() throws IOException, GeneralSecurityException {
         Assume.assumeTrue("BouncyCastle not registered", SecurityUtils.isBouncyCastleRegistered());
         Assume.assumeTrue("ECC not supported", SecurityUtils.isECCSupported());
         Assume.assumeTrue(ECCurves.nistp256 + " N/A", ECCurves.nistp256.isSupported());
@@ -69,7 +70,7 @@ public class SimpleGeneratorHostKeyProviderTest extends JUnitTestSupport {
     }
 
     @Test
-    public void testECnistp384() throws IOException {
+    public void testECnistp384() throws IOException, GeneralSecurityException {
         Assume.assumeTrue("BouncyCastle not registered", SecurityUtils.isBouncyCastleRegistered());
         Assume.assumeTrue("ECC not supported", SecurityUtils.isECCSupported());
         Assume.assumeTrue(ECCurves.nistp384 + " N/A", ECCurves.nistp384.isSupported());
@@ -77,14 +78,16 @@ public class SimpleGeneratorHostKeyProviderTest extends JUnitTestSupport {
     }
 
     @Test
-    public void testECnistp521() throws IOException {
+    public void testECnistp521() throws IOException, GeneralSecurityException {
         Assume.assumeTrue("BouncyCastle not registered", SecurityUtils.isBouncyCastleRegistered());
         Assume.assumeTrue("ECC not supported", SecurityUtils.isECCSupported());
         Assume.assumeTrue(ECCurves.nistp521 + " N/A", ECCurves.nistp521.isSupported());
         testSimpleGeneratorHostKeyProvider(KeyUtils.EC_ALGORITHM, KeyPairProvider.ECDSA_SHA2_NISTP521, -1, new ECGenParameterSpec("P-521"));
     }
 
-    private Path testSimpleGeneratorHostKeyProvider(String algorithm, String keyType, int keySize, AlgorithmParameterSpec keySpec) throws IOException {
+    private Path testSimpleGeneratorHostKeyProvider(
+            String algorithm, String keyType, int keySize, AlgorithmParameterSpec keySpec)
+                throws IOException, GeneralSecurityException {
         Path path = initKeyFileLocation(algorithm);
         KeyPair kpWrite = invokeSimpleGeneratorHostKeyProvider(path, algorithm, keyType, keySize, keySpec);
         assertTrue("Key file not generated: " + path, Files.exists(path, IoUtils.EMPTY_LINK_OPTIONS));
@@ -94,7 +97,9 @@ public class SimpleGeneratorHostKeyProviderTest extends JUnitTestSupport {
         return path;
     }
 
-    private static KeyPair invokeSimpleGeneratorHostKeyProvider(Path path, String algorithm, String keyType, int keySize, AlgorithmParameterSpec keySpec) {
+    private static KeyPair invokeSimpleGeneratorHostKeyProvider(
+            Path path, String algorithm, String keyType, int keySize, AlgorithmParameterSpec keySpec)
+                throws IOException, GeneralSecurityException {
         SimpleGeneratorHostKeyProvider provider = new SimpleGeneratorHostKeyProvider();
         provider.setAlgorithm(algorithm);
         provider.setOverwriteAllowed(true);
@@ -109,7 +114,9 @@ public class SimpleGeneratorHostKeyProviderTest extends JUnitTestSupport {
         return validateKeyPairProvider(provider, keyType);
     }
 
-    private static KeyPair validateKeyPairProvider(KeyPairProvider provider, String keyType) {
+    private static KeyPair validateKeyPairProvider(
+            KeyPairProvider provider, String keyType)
+                throws IOException, GeneralSecurityException {
         Iterable<String> types = provider.getKeyTypes(null);
         KeyPair kp = null;
         for (String type : types) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-common/src/test/java/org/apache/sshd/util/test/CommonTestSupportUtils.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/test/java/org/apache/sshd/util/test/CommonTestSupportUtils.java b/sshd-common/src/test/java/org/apache/sshd/util/test/CommonTestSupportUtils.java
index a1d77ef..d920344 100644
--- a/sshd-common/src/test/java/org/apache/sshd/util/test/CommonTestSupportUtils.java
+++ b/sshd-common/src/test/java/org/apache/sshd/util/test/CommonTestSupportUtils.java
@@ -453,7 +453,14 @@ public final class CommonTestSupportUtils {
 
     public static KeyPair getFirstKeyPair(KeyIdentityProvider provider) {
         Objects.requireNonNull(provider, "No key pair provider");
-        Iterable<? extends KeyPair> pairs = Objects.requireNonNull(provider.loadKeys(null), "No loaded keys");
+        Iterable<? extends KeyPair> pairs;
+        try {
+            pairs = Objects.requireNonNull(provider.loadKeys(null), "No loaded keys");
+        } catch (IOException | GeneralSecurityException e) {
+            throw new RuntimeException("Unexpected " + e.getClass().getSimpleName() + ")"
+                + " keys loading exception: " + e.getMessage(), e);
+        }
+
         Iterator<? extends KeyPair> iter = Objects.requireNonNull(pairs.iterator(), "No keys iterator");
         ValidateUtils.checkTrue(iter.hasNext(), "Empty loaded kyes iterator");
         return Objects.requireNonNull(iter.next(), "No key pair in iterator");
@@ -537,7 +544,14 @@ public final class CommonTestSupportUtils {
         Objects.requireNonNull(provider, "No provider");
 
         // get the I/O out of the way
-        Iterable<KeyPair> keys = Objects.requireNonNull(provider.loadKeys(null), "No keys loaded");
+        Iterable<KeyPair> keys;
+        try {
+            keys = Objects.requireNonNull(provider.loadKeys(null), "No keys loaded");
+        } catch (IOException | GeneralSecurityException e) {
+            throw new RuntimeException("Unexpected " + e.getClass().getSimpleName() + ")"
+                + " keys loading exception: " + e.getMessage(), e);
+        }
+
         if (keys instanceof Collection<?>) {
             ValidateUtils.checkNotNullAndNotEmpty((Collection<?>) keys, "Empty keys loaded");
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
index 6c3e9c8..6ece3d9 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
@@ -524,7 +524,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
         List<KeyPair> ids = new ArrayList<>(locations.size());
         boolean ignoreNonExisting = this.getBooleanProperty(IGNORE_INVALID_IDENTITIES, DEFAULT_IGNORE_INVALID_IDENTITIES);
         ClientIdentityLoader loader = Objects.requireNonNull(getClientIdentityLoader(), "No ClientIdentityLoader");
-        FilePasswordProvider provider = Objects.requireNonNull(getFilePasswordProvider(), "No FilePasswordProvider");
+        FilePasswordProvider provider = getFilePasswordProvider();
         boolean debugEnabled = log.isDebugEnabled();
         for (String l : locations) {
             if (!loader.isValidLocation(l)) {
@@ -539,14 +539,14 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
             }
 
             try {
-                KeyPair kp = loader.loadClientIdentity(l, provider);
+                KeyPair kp = loader.loadClientIdentity(null /* TODO use lazy-load here as well */, l, provider);
                 if (kp == null) {
                     throw new IOException("No identity loaded from " + l);
                 }
 
                 if (debugEnabled) {
                     log.debug("loadClientIdentities({}) type={}, fingerprint={}",
-                              l, KeyUtils.getKeyType(kp), KeyUtils.getFingerPrint(kp.getPublic()));
+                          l, KeyUtils.getKeyType(kp), KeyUtils.getFingerPrint(kp.getPublic()));
                 }
 
                 ids.add(kp);
@@ -561,7 +561,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
     protected ConnectFuture doConnect(
             String username, SocketAddress targetAddress,
             AttributeRepository context, SocketAddress localAddress,
-            Collection<? extends KeyPair> identities, boolean useDefaultIdentities)
+            Iterable<? extends KeyPair> identities, boolean useDefaultIdentities)
                 throws IOException {
         if (connector == null) {
             throw new IllegalStateException("SshClient not started. Please call start() method before connecting to a server");
@@ -578,7 +578,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
 
     protected SshFutureListener<IoConnectFuture> createConnectCompletionListener(
             ConnectFuture connectFuture, String username, SocketAddress address,
-            Collection<? extends KeyPair> identities, boolean useDefaultIdentities) {
+            Iterable<? extends KeyPair> identities, boolean useDefaultIdentities) {
         return new SshFutureListener<IoConnectFuture>() {
             @Override
             @SuppressWarnings("synthetic-access")
@@ -621,7 +621,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
 
     protected void onConnectOperationComplete(
             IoSession ioSession, ConnectFuture connectFuture,  String username,
-            SocketAddress address, Collection<? extends KeyPair> identities, boolean useDefaultIdentities) {
+            SocketAddress address, Iterable<? extends KeyPair> identities, boolean useDefaultIdentities) {
         AbstractClientSession session = (AbstractClientSession) AbstractSession.getSession(ioSession);
         session.setUsername(username);
         session.setConnectAddress(address);
@@ -630,12 +630,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
             setupDefaultSessionIdentities(session);
         }
 
-        int numIds = GenericUtils.size(identities);
-        if (numIds > 0) {
-            if (log.isDebugEnabled()) {
-                log.debug("onConnectOperationComplete({}) adding {} identities", session, numIds);
-            }
-
+        if (identities != null) {
             boolean traceEnabled = log.isTraceEnabled();
             for (KeyPair kp : identities) {
                 if (traceEnabled) {
@@ -792,7 +787,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
      *                      supported internally
      * @param provider      A {@link FilePasswordProvider} - may be {@code null}
      *                      if the loaded keys are <U>guaranteed</U> not to be encrypted. The argument
-     *                      to {@link FilePasswordProvider#getPassword(String, int)} is the path of the
+     *                      to {@code FilePasswordProvider#getPassword} is the path of the
      *                      file whose key is to be loaded
      * @param options       The {@link LinkOption}s to apply when checking
      *                      for existence
@@ -818,7 +813,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
      *                      supported internally
      * @param provider      A {@link FilePasswordProvider} - may be {@code null}
      *                      if the loaded keys are <U>guaranteed</U> not to be encrypted. The argument
-     *                      to {@link FilePasswordProvider#getPassword(String, int)} is the path of the
+     *                      to {@code FilePasswordProvider#getPassword} is the path of the
      *                      file whose key is to be loaded
      * @param options       The {@link LinkOption}s to apply when checking
      *                      for existence

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKeyIterator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKeyIterator.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKeyIterator.java
index d476464..a6f135c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKeyIterator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKeyIterator.java
@@ -21,6 +21,7 @@ package org.apache.sshd.client.auth.pubkey;
 
 import java.io.IOException;
 import java.nio.channels.Channel;
+import java.security.GeneralSecurityException;
 import java.security.KeyPair;
 import java.security.PublicKey;
 import java.util.ArrayList;
@@ -84,6 +85,7 @@ public class UserAuthPublicKeyIterator extends AbstractKeyPairIterator<PublicKey
         }
     }
 
+    @SuppressWarnings("checkstyle:anoninnerlength")
     protected Iterable<KeyPairIdentity> initializeSessionIdentities(
             ClientSession session, SignatureFactoriesManager signatureFactories) {
         return new Iterable<KeyPairIdentity>() {
@@ -94,8 +96,13 @@ public class UserAuthPublicKeyIterator extends AbstractKeyPairIterator<PublicKey
             public Iterator<KeyPairIdentity> iterator() {
                 // Lazy load the keys the 1st time the iterator is called
                 if (keysHolder.get() == null) {
-                    KeyIdentityProvider sessionKeysProvider = ClientSession.providerOf(session);
-                    keysHolder.set(sessionKeysProvider.loadKeys(session));
+                    try {
+                        KeyIdentityProvider sessionKeysProvider = ClientSession.providerOf(session);
+                        keysHolder.set(sessionKeysProvider.loadKeys(session));
+                    } catch (IOException | GeneralSecurityException e) {
+                        throw new RuntimeException("Unexpected " + e.getClass().getSimpleName() + ")"
+                            + " keys loading exception: " + e.getMessage(), e);
+                    }
                 }
 
                 return new Iterator<KeyPairIdentity>() {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
index b6d6235..b7b5377 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
@@ -385,21 +385,6 @@ public interface ClientSession
     }
 
     /**
-     * Creates a &quot;unified&quot; {@link Iterator} of key pairs out of the registered
-     * {@link KeyPair} identities and the extra available ones as a single iterator
-     * of key pairs
-     *
-     * @param session The {@link ClientSession} - ignored if {@code null} (i.e., empty
-     * iterator returned)
-     * @return The wrapping iterator
-     * @see ClientSession#getRegisteredIdentities()
-     * @see ClientSession#getKeyPairProvider()
-     */
-    static Iterator<KeyPair> keyPairIteratorOf(ClientSession session) {
-        return KeyIdentityProvider.iteratorOf(session, providerOf(session));
-    }
-
-    /**
      * Creates a &quot;unified&quot; {@link Iterator} of passwords out of the registered
      * passwords and the extra available ones as a single iterator of passwords
      *

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java b/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
index 0ecab07..8c094cd 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
@@ -24,7 +24,6 @@ import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.sshd.common.AttributeRepository;
-import org.apache.sshd.common.AttributeStore;
 import org.apache.sshd.common.Closeable;
 import org.apache.sshd.common.FactoryManager;
 import org.apache.sshd.common.FactoryManagerHolder;
@@ -54,7 +53,6 @@ import org.apache.sshd.common.util.buffer.Buffer;
  */
 public interface Session
         extends SessionContext,
-                AttributeStore,
                 MutableUserHolder,
                 KexFactoryManager,
                 SessionListenerManager,

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
index db3b17a..fc9958f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
@@ -20,8 +20,10 @@ package org.apache.sshd.common.session.helpers;
 
 import java.io.IOException;
 import java.io.InterruptedIOException;
+import java.net.ProtocolException;
 import java.net.SocketTimeoutException;
 import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
 import java.util.AbstractMap.SimpleImmutableEntry;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -711,7 +713,16 @@ public abstract class AbstractSession extends SessionHelper {
             return doWritePacket(buffer);
         } finally {
             resetIdleTimeout();
-            checkRekey();
+            try {
+                checkRekey();
+            } catch (GeneralSecurityException e) {
+                if (log.isDebugEnabled()) {
+                    log.debug("writePacket(" + this + ") rekey security exception details", e);
+                }
+                throw ValidateUtils.initializeExceptionCause(
+                    new ProtocolException("Failed (" + e.getClass().getSimpleName() + ")"
+                        + " to check re-key necessity: " + e.getMessage()), e);
+            }
         }
     }
 
@@ -1101,8 +1112,9 @@ public abstract class AbstractSession extends SessionHelper {
      * @return <code>true</code> if the identification has been fully read or
      * <code>false</code> if more data is needed
      * @throws IOException if an error occurs such as a bad protocol version
+     * @throws GeneralSecurityException If unsuccessful KEX was involved
      */
-    protected abstract boolean readIdentification(Buffer buffer) throws IOException;
+    protected abstract boolean readIdentification(Buffer buffer) throws IOException, GeneralSecurityException;
 
     /**
      * Send the key exchange initialization packet.
@@ -1607,7 +1619,17 @@ public abstract class AbstractSession extends SessionHelper {
 
     @Override
     public KeyExchangeFuture reExchangeKeys() throws IOException {
-        requestNewKeysExchange();
+        try {
+            requestNewKeysExchange();
+        } catch (GeneralSecurityException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("reExchangeKeys(" + this + ") security exception details", e);
+            }
+            throw ValidateUtils.initializeExceptionCause(
+                new ProtocolException("Failed (" + e.getClass().getSimpleName() + ")"
+                    + " to generate keys for exchange: " + e.getMessage()), e);
+        }
+
         return ValidateUtils.checkNotNull(kexFutureHolder.get(), "No current KEX future on state=%s", kexState.get());
     }
 
@@ -1616,11 +1638,12 @@ public abstract class AbstractSession extends SessionHelper {
      *
      * @return A {@link KeyExchangeFuture} to wait for the initiated exchange
      * or {@code null} if no need to re-key or an exchange is already in progress
-     * @throws IOException If failed to send the request
+     * @throws IOException If failed load the keys or send the request
+     * @throws GeneralSecurityException If failed to generate the necessary keys
      * @see #isRekeyRequired()
      * @see #requestNewKeysExchange()
      */
-    protected KeyExchangeFuture checkRekey() throws IOException {
+    protected KeyExchangeFuture checkRekey() throws IOException, GeneralSecurityException {
         return isRekeyRequired() ? requestNewKeysExchange() : null;
     }
 
@@ -1629,9 +1652,10 @@ public abstract class AbstractSession extends SessionHelper {
      *
      * @return A {@link KeyExchangeFuture} to wait for the initiated exchange
      * or {@code null} if an exchange is already in progress
-     * @throws IOException If failed to send the request
+     * @throws IOException If failed to load the keys or send the request
+     * @throws GeneralSecurityException If failed to generate the keys
      */
-    protected KeyExchangeFuture requestNewKeysExchange() throws IOException {
+    protected KeyExchangeFuture requestNewKeysExchange() throws IOException, GeneralSecurityException {
         if (!kexState.compareAndSet(KexState.DONE, KexState.INIT)) {
             if (log.isDebugEnabled()) {
                 log.debug("requestNewKeysExchange({}) KEX state not DONE: {}", this, kexState.get());
@@ -1740,7 +1764,7 @@ public abstract class AbstractSession extends SessionHelper {
         return rekey;
     }
 
-    protected byte[] sendKexInit() throws IOException {
+    protected byte[] sendKexInit() throws IOException, GeneralSecurityException {
         String resolvedAlgorithms = resolveAvailableSignaturesProposal();
         if (GenericUtils.isEmpty(resolvedAlgorithms)) {
             throw new SshException(SshConstants.SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE,
@@ -1794,10 +1818,12 @@ public abstract class AbstractSession extends SessionHelper {
     /**
      * @return A comma-separated list of all the signature protocols to be
      * included in the proposal - {@code null}/empty if no proposal
+     * @throws IOException If failed to read/parse the keys data
+     * @throws GeneralSecurityException If failed to generate the keys
      * @see #getFactoryManager()
      * @see #resolveAvailableSignaturesProposal(FactoryManager)
      */
-    protected String resolveAvailableSignaturesProposal() {
+    protected String resolveAvailableSignaturesProposal() throws IOException, GeneralSecurityException {
         return resolveAvailableSignaturesProposal(getFactoryManager());
     }
 
@@ -1805,8 +1831,11 @@ public abstract class AbstractSession extends SessionHelper {
      * @param manager The {@link FactoryManager}
      * @return A comma-separated list of all the signature protocols to be
      * included in the proposal - {@code null}/empty if no proposal
+     * @throws IOException If failed to read/parse the keys data
+     * @throws GeneralSecurityException If failed to generate the keys
      */
-    protected abstract String resolveAvailableSignaturesProposal(FactoryManager manager);
+    protected abstract String resolveAvailableSignaturesProposal(FactoryManager manager)
+            throws IOException, GeneralSecurityException;
 
     /**
      * Indicates the the key exchange is completed and the exchanged keys

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-core/src/main/java/org/apache/sshd/server/config/keys/ServerIdentity.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/config/keys/ServerIdentity.java b/sshd-core/src/main/java/org/apache/sshd/server/config/keys/ServerIdentity.java
index 0823a8f..4757838 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/config/keys/ServerIdentity.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/config/keys/ServerIdentity.java
@@ -117,9 +117,11 @@ public final class ServerIdentity {
      * @see #findIdentities(Properties, LinkOption...)
      * @see IdentityUtils#loadIdentities(Map, org.apache.sshd.common.config.keys.FilePasswordProvider, java.nio.file.OpenOption...)
      */
-    public static Map<String, KeyPair> loadIdentities(Properties props, LinkOption... options) throws IOException, GeneralSecurityException {
+    public static Map<String, KeyPair> loadIdentities(Properties props, LinkOption... options)
+            throws IOException, GeneralSecurityException {
         Map<String, Path> ids = findIdentities(props, options);
-        return IdentityUtils.loadIdentities(ids, null /* server key files are never encrypted */, IoUtils.EMPTY_OPEN_OPTIONS);
+        return IdentityUtils.loadIdentities(
+                null /* server keys are not loaded in a session context */, ids, null /* server key files are never encrypted */, IoUtils.EMPTY_OPEN_OPTIONS);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java b/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
index 69f450a..6af869e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
@@ -22,6 +22,7 @@ package org.apache.sshd.server.session;
 import java.io.IOException;
 import java.net.SocketAddress;
 import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
 import java.security.KeyPair;
 import java.util.Collection;
 import java.util.List;
@@ -247,7 +248,8 @@ public abstract class AbstractServerSession extends AbstractSession implements S
     }
 
     @Override
-    protected String resolveAvailableSignaturesProposal(FactoryManager proposedManager) {
+    protected String resolveAvailableSignaturesProposal(FactoryManager proposedManager)
+            throws IOException, GeneralSecurityException {
         /*
          * Make sure we can provide key(s) for the available signatures
          */
@@ -319,7 +321,7 @@ public abstract class AbstractServerSession extends AbstractSession implements S
     }
 
     @Override
-    protected boolean readIdentification(Buffer buffer) throws IOException {
+    protected boolean readIdentification(Buffer buffer) throws IOException, GeneralSecurityException {
         ServerProxyAcceptor acceptor = getServerProxyAcceptor();
         int rpos = buffer.rpos();
         boolean debugEnabled = log.isDebugEnabled();
@@ -395,7 +397,7 @@ public abstract class AbstractServerSession extends AbstractSession implements S
         KeyPairProvider provider = Objects.requireNonNull(getKeyPairProvider(), "No host keys provider");
         try {
             return provider.loadKey(this, keyType);
-        } catch (Error e) {
+        } catch (IOException | GeneralSecurityException | Error e) {
             log.warn("getHostKey({}) failed ({}) to load key of type={}: {}",
                  this, e.getClass().getSimpleName(), keyType, e.getMessage());
             if (log.isDebugEnabled()) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2b013cca/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java b/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
index 30cb1ff..3881890 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
@@ -153,8 +153,9 @@ public class HostConfigEntryResolverTest extends BaseTestSupport {
             }
 
             @Override
-            public KeyPair loadClientIdentity(String location, FilePasswordProvider provider)
-                    throws IOException, GeneralSecurityException {
+            public KeyPair loadClientIdentity(
+                    SessionContext session, String location, FilePasswordProvider provider)
+                        throws IOException, GeneralSecurityException {
                 if (isValidLocation(location)) {
                     return identity;
                 }
@@ -218,8 +219,9 @@ public class HostConfigEntryResolverTest extends BaseTestSupport {
             }
 
             @Override
-            public KeyPair loadClientIdentity(String location, FilePasswordProvider provider)
-                    throws IOException, GeneralSecurityException {
+            public KeyPair loadClientIdentity(
+                    SessionContext session, String location, FilePasswordProvider provider)
+                        throws IOException, GeneralSecurityException {
                 if (isValidLocation(location)) {
                     return specificIdentity;
                 }