Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NullPointerException using OpenSSH RSA public key #484

Closed
talaieru opened this issue Jan 12, 2019 · 4 comments · Fixed by #485
Closed

NullPointerException using OpenSSH RSA public key #484

talaieru opened this issue Jan 12, 2019 · 4 comments · Fixed by #485

Comments

@talaieru
Copy link

When the authentication key (in ~/.ssh/id_rsa) is in OpenSSH format, then the OpenSSHKeyV1KeyFile key provider is used. Invoking SshClient.authPublicKey with such key results in a NullPointerException because the PasswordFinder pwdf is null. As far as I can see OpenSSHKeyV1KeyFile cannot handle correctly the case where no password is provided.

The following Java code can be used to reproduce the issue:

import java.nio.file.Path;
import java.nio.file.Paths;

import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.xfer.FileSystemFile;

public class BugWithOpenSshKey {
    public static void main(String[] args) throws Exception {
        Path parentPath = Paths.get("/tmp/certs");

        SSHClient ssh = new SSHClient();
        ssh.addHostKeyVerifier((hostname, port, key) -> true);
        ssh.addAlgorithmsVerifier(algorithms -> true);

        try {
            ssh.connect("remoteHost");
            ssh.authPublickey("root");
            ssh.newSCPFileTransfer().download("/var/opt/certs/nevisfido-metadata-keystore.p12",
                    new FileSystemFile(parentPath.toString()));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ssh.disconnect();
        }
    }
}

The output is:

15:09:43.601 [main] INFO net.schmizz.sshj.transport.random.BouncyCastleRandom - Generating random seed from SecureRandom.
15:09:43.605 [main] DEBUG net.schmizz.sshj.transport.random.BouncyCastleRandom - Creating random seed took 0 ms
15:09:43.659 [main] DEBUG net.schmizz.sshj.DefaultConfig - Available cipher factories: [aes128-cbc, aes128-ctr, aes192-cbc, aes192-ctr, aes256-cbc, aes256-ctr, blowfish-cbc, blowfish-ctr, cast128-cbc, cast128-ctr, idea-cbc, idea-ctr, serpent128-cbc, serpent128-ctr, serpent192-cbc, serpent192-ctr, serpent256-cbc, serpent256-ctr, 3des-cbc, 3des-ctr, twofish128-cbc, twofish128-ctr, twofish192-cbc, twofish192-ctr, twofish256-cbc, twofish256-ctr, twofish-cbc, arcfour, arcfour128, arcfour256]
15:09:43.692 [main] INFO net.schmizz.sshj.transport.TransportImpl - Client identity string: SSH-2.0-SSHJ_0.26.0
15:09:43.705 [main] INFO net.schmizz.sshj.transport.TransportImpl - Server identity string: SSH-2.0-OpenSSH_7.4
15:09:43.705 [main] DEBUG net.schmizz.concurrent.Promise - Setting <<kex done>> to `null`
15:09:43.705 [main] DEBUG net.schmizz.sshj.transport.KeyExchanger - Sending SSH_MSG_KEXINIT
15:09:43.712 [reader] DEBUG net.schmizz.sshj.transport.KeyExchanger - Received SSH_MSG_KEXINIT
15:09:43.713 [reader] DEBUG net.schmizz.concurrent.Promise - Awaiting <<kexinit sent>>
15:09:43.713 [main] DEBUG net.schmizz.concurrent.Promise - Setting <<kexinit sent>> to `SOME`
15:09:43.713 [main] DEBUG net.schmizz.concurrent.Promise - Awaiting <<kex done>>
15:09:43.714 [reader] DEBUG net.schmizz.sshj.transport.KeyExchanger - Negotiated algorithms: [ [email protected]; sig=ecdsa-sha2-nistp256; c2sCipher=aes128-cbc; s2cCipher=aes128-cbc; c2sMAC=hmac-sha1; s2cMAC=hmac-sha1; c2sComp=none; s2cComp=none ]
15:09:43.714 [reader] DEBUG net.schmizz.sshj.transport.KeyExchanger - Trying to verify algorithms with BugWithOpenSshKey$$Lambda$3/516934601@11cd711
15:09:43.775 [reader] DEBUG net.schmizz.sshj.transport.kex.Curve25519SHA256 - Sending SSH_MSG_KEXDH_INIT
15:09:43.787 [reader] DEBUG net.schmizz.sshj.transport.KeyExchanger - Received kex followup data
15:09:43.787 [reader] DEBUG net.schmizz.sshj.transport.kex.Curve25519SHA256 - Received SSH_MSG_KEXDH_REPLY
15:09:43.787 [reader] DEBUG net.schmizz.sshj.common.ECDSAVariationsAdapter - Key algo: ecdsa-sha2-nistp256, Key curve: nistp256, Key Len: 65, 0x04: 4
x: [-36, -56, -36, -60, 95, 80, 98, 117, 80, 46, 58, 121, 127, -112, -64, 0, -89, 67, 87, 122, 75, -86, -20, 1, -64, -108, -121, 23, -33, 87, 102, 16]
y: [-56, -34, -83, 25, 28, 39, 114, -24, 0, 105, -62, -13, -115, -58, 88, 126, 56, 86, -31, -48, 78, -114, 29, 8, -83, 5, 77, -27, -25, -8, -60, 18]
15:09:43.927 [reader] DEBUG net.schmizz.sshj.transport.KeyExchanger - Trying to verify host key with BugWithOpenSshKey$$Lambda$2/1386020581@32b1c013
15:09:43.928 [reader] DEBUG net.schmizz.sshj.transport.KeyExchanger - Sending SSH_MSG_NEWKEYS
15:09:43.930 [reader] DEBUG net.schmizz.sshj.transport.KeyExchanger - Received SSH_MSG_NEWKEYS
15:09:43.933 [reader] DEBUG net.schmizz.concurrent.Promise - Setting <<kexinit sent>> to `null`
15:09:43.933 [reader] DEBUG net.schmizz.concurrent.Promise - Setting <<kex done>> to `SOME`
15:09:43.934 [main] DEBUG net.schmizz.sshj.SSHClient - Key exchange took 0.229 seconds
15:09:43.934 [main] DEBUG net.schmizz.sshj.SSHClient - Attempting to load key from: /Users/josu/.ssh/id_rsa
15:09:43.936 [main] DEBUG net.schmizz.sshj.SSHClient - Attempting to load key from: /Users/josu/.ssh/id_dsa
15:09:43.936 [main] INFO net.schmizz.sshj.SSHClient - Could not load keys from /Users/josu/.ssh/id_dsa due to: /Users/josu/.ssh/id_dsa (No such file or directory)
15:09:43.937 [main] DEBUG net.schmizz.sshj.SSHClient - Attempting to load key from: /Users/josu/.ssh/id_ed25519
15:09:43.937 [main] INFO net.schmizz.sshj.SSHClient - Could not load keys from /Users/josu/.ssh/id_ed25519 due to: /Users/josu/.ssh/id_ed25519 (No such file or directory)
15:09:43.937 [main] DEBUG net.schmizz.sshj.SSHClient - Attempting to load key from: /Users/josu/.ssh/id_ecdsa
15:09:43.937 [main] INFO net.schmizz.sshj.SSHClient - Could not load keys from /Users/josu/.ssh/id_ecdsa due to: /Users/josu/.ssh/id_ecdsa (No such file or directory)
15:09:43.938 [main] DEBUG net.schmizz.concurrent.Promise - Setting <<service accept>> to `null`
15:09:43.938 [main] DEBUG net.schmizz.sshj.transport.TransportImpl - Sending SSH_MSG_SERVICE_REQUEST for ssh-userauth
15:09:43.938 [main] DEBUG net.schmizz.concurrent.Promise - Awaiting <<service accept>>
15:09:43.978 [reader] DEBUG net.schmizz.concurrent.Promise - Setting <<service accept>> to `SOME`
15:09:43.979 [main] DEBUG net.schmizz.sshj.transport.TransportImpl - Setting active service to ssh-userauth
15:09:43.979 [main] DEBUG net.schmizz.concurrent.Promise - Setting <<authenticated>> to `null`
15:09:43.979 [main] DEBUG net.schmizz.sshj.userauth.UserAuthImpl - Trying `publickey` auth...
15:09:43.979 [main] DEBUG net.schmizz.sshj.userauth.method.AuthPublickey - Attempting authentication using com.hierynomus.sshj.userauth.keyprovider.OpenSSHKeyV1KeyFile@22d9c961
15:09:43.983 [main] INFO com.hierynomus.sshj.userauth.keyprovider.OpenSSHKeyV1KeyFile - Keypair is encrypted with: aes256-ctr, bcrypt, [B@29f0c4f2
java.lang.NullPointerException
	at com.hierynomus.sshj.userauth.keyprovider.OpenSSHKeyV1KeyFile.initializeCipher(OpenSSHKeyV1KeyFile.java:127)
	at com.hierynomus.sshj.userauth.keyprovider.OpenSSHKeyV1KeyFile.decryptBuffer(OpenSSHKeyV1KeyFile.java:118)
	at com.hierynomus.sshj.userauth.keyprovider.OpenSSHKeyV1KeyFile.readDecodedKeyPair(OpenSSHKeyV1KeyFile.java:110)
	at com.hierynomus.sshj.userauth.keyprovider.OpenSSHKeyV1KeyFile.readKeyPair(OpenSSHKeyV1KeyFile.java:79)
	at net.schmizz.sshj.userauth.keyprovider.BaseFileKeyProvider.getPublic(BaseFileKeyProvider.java:81)
	at net.schmizz.sshj.userauth.method.KeyedAuthMethod.putPubKey(KeyedAuthMethod.java:44)
	at net.schmizz.sshj.userauth.method.AuthPublickey.buildReq(AuthPublickey.java:62)
	at net.schmizz.sshj.userauth.method.AuthPublickey.buildReq(AuthPublickey.java:81)
	at net.schmizz.sshj.userauth.method.AbstractAuthMethod.request(AbstractAuthMethod.java:68)
	at net.schmizz.sshj.userauth.UserAuthImpl.authenticate(UserAuthImpl.java:72)
	at net.schmizz.sshj.SSHClient.auth(SSHClient.java:225)
	at net.schmizz.sshj.SSHClient.authPublickey(SSHClient.java:346)
	at net.schmizz.sshj.SSHClient.authPublickey(SSHClient.java:395)
	at net.schmizz.sshj.SSHClient.authPublickey(SSHClient.java:325)
	at BugWithOpenSshKey.main(BugWithOpenSshKey.java:17)
15:09:43.985 [main] INFO net.schmizz.sshj.transport.TransportImpl - Disconnected - BY_APPLICATION
15:09:43.985 [main] DEBUG net.schmizz.sshj.userauth.UserAuthImpl - Notified of net.schmizz.sshj.transport.TransportException: [BY_APPLICATION] Disconnected
15:09:43.985 [main] DEBUG net.schmizz.sshj.transport.TransportImpl - Sending SSH_MSG_DISCONNECT: reason=[BY_APPLICATION], msg=[]
15:09:43.986 [main] DEBUG net.schmizz.concurrent.Promise - Setting <<transport close>> to `SOME`
15:09:43.986 [reader] DEBUG net.schmizz.sshj.transport.Reader - Stopping

This has been reproduced using Mac OS 10.14.2. An excerpt of my id_rsa contents:

cat ~/.ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABD3PhhEIe

@hierynomus
Copy link
Owner

Is your private key protected by a passphrase? SSHJ tries to decrypt the key. If it is not, I'd like to know the exact command to generate such a key.

I agree that an NPE is bad, but before deciding on the solution I'd need to know the above.

@talaieru
Copy link
Author

talaieru commented Jan 14, 2019 via email

@hierynomus
Copy link
Owner

Indeed, thanks for the reply. I also figured out that the RSA keytype in the new format does not work (yet). Will fix the following things:

  • Support RSA in OpenSSHv1 keyfile format
  • Check for set PasswordFinder in case of encrypted keyfile (prevent NPE)
  • Add an SSHClient.authPublicKey(String username, PasswordFinder pwdf)

Currently you could do it using the client.authPublicKey("root", client.loadKeys("/Users/josu/.ssh/id_rsa"));

@dkocher
Copy link
Contributor

dkocher commented Jan 16, 2019

Duplicate for #276.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants