## Configuration/data files parsing support
Most of the configuration data files parsing support resides in the _sshd-common_ artfiact:

```xml
    <dependency>
        <groupId>org.apache.sshd</groupId>
        <artifactId>sshd-common</artifactId>
        <version>...same version as the rest of the artifacts...</version>
    </dependency>
```

The code contains support for parsing the [_authorized_keys_](http://man.openbsd.org/sshd.8#AUTHORIZED_KEYS_FILE_FORMAT),
[_known\_hosts_](http://www.manpagez.com/man/8/sshd/), [_ssh\_config_, _sshd\_config_](https://www.freebsd.org/cgi/man.cgi?query=ssh_config&sektion=5),
and [_~/config_](http://www.gsp.com/cgi-bin/man.cgi?topic=ssh_config) files. The code resides in the _sshd-common_ artifact - specifically
the `KeyUtils#getPublicKeyEntryDecoder`, `AuthorizedKeyEntry#readAuthorizedKeys`, `KnownHostEntry#readKnownHostEntries`
and `HostConfigEntry#readHostConfigEntries`.

### PEM/OpenSSH

The common code contains built-in support for parsing PEM and/or _OpenSSH_ formatted key files and using them for authentication purposes.
As mentioned previously, it can leverage _Bouncy Castle_ if available, but can do most of the work without it as well. For _ed25519_ support,
one must provide either `net.i2p.crypto.eddsa` or _Bouncy Castle_ as a dependency; if both are present `net.i2p.crypto.eddsa` is used. 

### [PUTTY](https://www.putty.org/)

The code contains built-in support for parsing PUTTY key files (usually _.ppk_) and using them same as SSH ones as key-pair
providers for autentication purposes. The PUTTY key file(s) readers are contained in the `org.apache.sshd.common.config.keys.loader.putty`
package (specifically `PuttyKeyUtils#DEFAULT_INSTANCE KeyPairResourceParser`) of the _sshd-putty_ artifact. **Note:** the artifact should
be included as an extra dependency:

```xml
    <dependency>
        <groupId>org.apache.sshd</groupId>
        <artifactId>sshd-putty</artifactId>
        <version>...same version as the rest of the artifacts...</version>
    </dependency>
```

### [OpenPGP](https://www.openpgp.org/)

The code contains the _sshd-openpgp_ module that enables using _OpenPGP_ private key files as identity providers.

```xml
    <dependency>
        <groupId>org.apache.sshd</groupId>
        <artifactId>sshd-openpgp</artifactId>
        <version>...same version as the rest of the artifacts...</version>
    </dependency>
```

The [support](https://issues.apache.org/jira/browse/SSHD-757) for it is currently still in its infancy, and therefore
this feature should be considered **experimental** for the time being. However, within its limitations it supports

* RSA keys
* DSA keys
* ECDSA keys

(*) For now `ed25519` keys are not supported by this module.

The code reads **all** the available key pairs in the key file without any distinction between encryption, decryption,
authentication or signature ones.

This code relies on the [jpgpj](https://github.com/justinludwig/jpgpj) support module

```xml
    <dependency>
        <groupId>org.c02e.jpgpj</groupId>
        <artifactId>jpgpj</artifactId>
        <version>...</version>
    </dependency>
```

(which in turn automatically uses _Bouncycastle_ - so if one does not want _Bouncycastle_ one cannot use this module).

#### Using OpenPGP authorized keys entries

In order to be able to read `authorized_keys` files that may contain _OpenPGP_ keys references, one needs to register
the relevant `PublicKeyEntryDataResolver`-s. This is done by calling `PGPPublicKeyEntryDataResolver#registerDefaultKeyEntryDataResolvers`
once during the _main_ code setup. This will enable the code to safely read authorized keys entries having the format
specified in the [OpenSSH PGP configuration](https://www.red-bean.com/~nemo/openssh-gpg/):

```
    pgp-sign-dss 87C36E60187451050A4F26B134824FC95C781A18 with-comment
    pgp-sign-rsa 87C36E60187451050A4F26B134824FC95C781A18
```

Where the key data following the key type specification is the fingerprint value of the referenced key. In order to
use a "mixed mode" file (i.e., one that has both SSH and _OpenPGP_ keys) one needs to replace the default `AuthorizedKeysAuthenticator`
instance with one that is derived from it and overrides the `createDelegateAuthenticator` method in a manner similar
as shown below:

```java
// Using PGPAuthorizedEntriesTracker
public class MyAuthorizedKeysAuthenticatorWithBothPGPAndSsh extends AuthorizedKeysAuthenticator {
    ... constructor(s) ...

    @Override
    protected PublickeyAuthenticator createDelegateAuthenticator(
            String username, ServerSession session, Path path,
            Collection<AuthorizedKeyEntry> entries, PublicKeyEntryResolver fallbackResolver)
                throws IOException, GeneralSecurityException {
        PGPAuthorizedEntriesTracker tracker = ... obtain an instance ...
        // Note: need to catch the PGPException and transform it into either an IOException or a GeneralSecurityException
        Collection<PublicKey> keys = tracker.resolveAuthorizedEntries(session, entries, fallbackResolver);
        if (GenericUtils.isEmpty(keys)) {
            return RejectAllPublickeyAuthenticator.INSTANCE;
        } else {
            return new KeySetPublickeyAuthenticator(id, keys);
        }
    }
}

// Using PGPPublicRingWatcher
public class MyAuthorizedKeysAuthenticatorWithBothPGPAndSsh extends AuthorizedKeysAuthenticator {
    ... constructor(s) ...

    @Override
    protected PublickeyAuthenticator createDelegateAuthenticator(
            String username, ServerSession session, Path path,
            Collection<AuthorizedKeyEntry> entries, PublicKeyEntryResolver fallbackResolver)
                throws IOException, GeneralSecurityException {
        PGPPublicRingWatcher watcher = ... obtain an instance ...
        // Note: need to catch the PGPException and transform it into either an IOException or a GeneralSecurityException
        Collection<PublicKey> keys = watcher.resolveAuthorizedEntries(session, entries, fallbackResolver);
        if (GenericUtils.isEmpty(keys)) {
            return RejectAllPublickeyAuthenticator.INSTANCE;
        } else {
            return new KeySetPublickeyAuthenticator(id, keys);
        }
    }
}

```

**Note:** in order to support GPG v2 `.kbx` files one requires up-to-date [Bouncycastle](https://mvnrepository.com/artifact/org.bouncycastle/bcpg-jdk15on/1.61)
and [jpgpj](https://mvnrepository.com/artifact/org.c02e.jpgpj/jpgpj/0.6.1) versions.
