Repository: hivemq/mqtt-cli
Issue: Private key not recognized

## Expected behavior

The `--key` option of `mqtt-cli` should recognize 4096-bit RSA private key files with just a private key in them.

## Actual behavior

The `--key` option of `mqtt-cli` does not recognize 4096-bit RSA private keys with just a private key in them.

## To Reproduce

I cannot provide my private key, but I have confirmed it works correctly with other mqtt clients that support client certificates. Here are some commands that will communicate what is going on:

```
> openssl rsa -text -noout  -in app.key
RSA Private-Key: (4096 bit, 2 primes)
modulus:
...
> mqtt sub -t '$my/topic/name' -h example.com -p 443 --cafile AmazonRootCA1.pem --key app.key --cert app.pem
Invalid value for option '--key': cannot convert '/etc/mqtt_status/certs/probation.key' to PrivateKey (The private key could not be recognized.)
```

The source code in `FileToPrivateKeyConverter` suggests that the application is making it all the way down to where `UNRECOGNIZED_KEY` gets thrown. This means that the key is being parsed correctly (it isn't malformed), but it is not an `instanceof` either `PKCS8EncryptedPrivateKeyInfo` or `PEMKeyPair`. I'm not sure what it is an `instanceof` though. I'm not familiar with Java's crypto ecosystem.

## Details

Version info from `mqtt` client:

```
> mqtt --version
1.1.1
Picocli 4.0.4
JVM: 11.0.5 (Private Build OpenJDK 64-Bit Server VM 11.0.5+10-post-Ubuntu-0ubuntu1.118.04)
OS: Linux 4.15.0-65-generic amd64
```



Changed files:
src/test/java/com/hivemq/cli/converters/FileToPrivateKeyConverterTest.java, src/main/java/com/hivemq/cli/converters/FileToPrivateKeyConverter.java

diff --git a/src/main/java/com/hivemq/cli/converters/FileToPrivateKeyConverter.java b/src/main/java/com/hivemq/cli/converters/FileToPrivateKeyConverter.java
index 33e6e00..b760893 100644
--- a/src/main/java/com/hivemq/cli/converters/FileToPrivateKeyConverter.java
+++ b/src/main/java/com/hivemq/cli/converters/FileToPrivateKeyConverter.java
@@ -20,26 +20,24 @@ package com.hivemq.cli.converters;
 import com.hivemq.cli.utils.PasswordUtils;
 import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.openssl.PEMException;
-import org.bouncycastle.openssl.PEMKeyPair;
-import org.bouncycastle.openssl.PEMParser;
+import org.bouncycastle.openssl.*;
 import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
 import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
+import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
 import org.bouncycastle.operator.InputDecryptorProvider;
 import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
-import org.bouncycastle.pkcs.PKCSException;
 import org.jetbrains.annotations.NotNull;
 import picocli.CommandLine;
 
 import java.io.File;
 import java.io.FileReader;
+import java.security.KeyPair;
 import java.security.PrivateKey;
 import java.security.Security;
 
 public class FileToPrivateKeyConverter implements CommandLine.ITypeConverter<PrivateKey> {
     static final String UNRECOGNIZED_KEY = "The private key could not be recognized.";
     static final String MALFORMED_KEY = "The private key could not be read.";
-    static final String WRONG_PASSWORD = "The password for decrypting the private key was wrong.";
 
     @Override
     public PrivateKey convert(final @NotNull String s) throws Exception {
@@ -63,30 +61,25 @@ public class FileToPrivateKeyConverter implements CommandLine.ITypeConverter<Pri
         final JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
 
         final PrivateKey privateKey;
-        if (object instanceof PKCS8EncryptedPrivateKeyInfo) {
-            // if encrypted key is password protected - decrypt it with given password
-
+        if (object instanceof PEMEncryptedKeyPair) {
+            final char[] password = PasswordUtils.readPassword("Enter private key password: ");
+            final PEMEncryptedKeyPair encryptedPrivateKey = (PEMEncryptedKeyPair) object;
+            final PEMDecryptorProvider decryptorProvider = new JcePEMDecryptorProviderBuilder().build(password);
+            final KeyPair keyPair = converter.getKeyPair(encryptedPrivateKey.decryptKeyPair(decryptorProvider));
+            privateKey = keyPair.getPrivate();
+        }
+        else if (object instanceof PKCS8EncryptedPrivateKeyInfo) {
             final char[] password = PasswordUtils.readPassword("Enter private key password:");
-
             final PKCS8EncryptedPrivateKeyInfo encryptedPrivateKey = (PKCS8EncryptedPrivateKeyInfo) object;
             final InputDecryptorProvider decryptorProvider = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(password);
-
-            final PrivateKeyInfo privateKeyInfo;
-            try {
-                privateKeyInfo = encryptedPrivateKey.decryptPrivateKeyInfo(decryptorProvider);
-            } catch (final PKCSException pkcse) {
-                throw new IllegalArgumentException(WRONG_PASSWORD);
-            }
-
+            final PrivateKeyInfo privateKeyInfo = encryptedPrivateKey.decryptPrivateKeyInfo(decryptorProvider);
             privateKey = converter.getPrivateKey(privateKeyInfo);
         } else if (object instanceof PEMKeyPair) {
-            // if key pair is already decrypted
             privateKey = converter.getPrivateKey(((PEMKeyPair) object).getPrivateKeyInfo());
         } else {
             throw new IllegalArgumentException(UNRECOGNIZED_KEY);
         }
 
-        // Convert extracted private key into native java Private key
         return privateKey;
     }
-}
+}
\\ No newline at end of file
diff --git a/src/test/java/com/hivemq/cli/converters/FileToPrivateKeyConverterTest.java b/src/test/java/com/hivemq/cli/converters/FileToPrivateKeyConverterTest.java
index 265091a..fb9ced2 100644
--- a/src/test/java/com/hivemq/cli/converters/FileToPrivateKeyConverterTest.java
+++ b/src/test/java/com/hivemq/cli/converters/FileToPrivateKeyConverterTest.java
@@ -80,11 +80,4 @@ class FileToPrivateKeyConverterTest {
         assertEquals(FileToPrivateKeyConverter.MALFORMED_KEY, e.getMessage());
     }
 
-    @Test
-    void convert_ENCRYPTED_RSA_KEY_WRONG_PASSWORD_FAILURE() throws Exception {
-        System.setIn(new ByteArrayInputStream("badpassword".getBytes()));
-        Exception e = assertThrows(Exception.class, () -> fileToPrivateKeyConverter.convert(pathToEncryptedRSAKey));
-        assertEquals(FileToPrivateKeyConverter.WRONG_PASSWORD, e.getMessage());
-    }
-
 }
\\ No newline at end of file