Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/main/java/com/jcraft/jsch/IdentityFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,48 @@

package com.jcraft.jsch;

import java.io.IOException;

class IdentityFile implements Identity {
private KeyPair kpair;
private String identity;

static IdentityFile newInstance(String prvfile, String pubfile, JSch.InstanceLogger instLogger)
throws JSchException {
KeyPair kpair = KeyPair.load(instLogger, prvfile, pubfile);
// if both keys are provided, make sure they match
if (prvfile != null && pubfile != null) {
byte[] pubkey;
try {
pubkey = Util.fromFile(pubfile);
} catch (IOException e) {
throw new JSchException("Error opening publickey", e);
}
KeyPair kpairVal = KeyPair.load(instLogger, null, pubkey);
if (kpairVal == null) {
throw new JSchException("invalid publickey");
}
if (!Util.arraysequals(kpair.getPublicKeyBlob(), kpairVal.getPublicKeyBlob())) {
throw new JSchException("Public key does not match private key");
}
}
return new IdentityFile(prvfile, kpair);
}

static IdentityFile newInstance(String name, byte[] prvkey, byte[] pubkey,
JSch.InstanceLogger instLogger) throws JSchException {

KeyPair kpair = KeyPair.load(instLogger, prvkey, pubkey);
// if both keys are provided, make sure they match
if (prvkey != null && pubkey != null) {
KeyPair kpairVal = KeyPair.load(instLogger, null, pubkey);
if (kpairVal == null) {
throw new JSchException("invalid publickey");
}
if (!Util.arraysequals(kpair.getPublicKeyBlob(), kpairVal.getPublicKeyBlob())) {
throw new JSchException("Public key does not match private key");
Comment thread
AlainKnaff marked this conversation as resolved.
}
}
return new IdentityFile(name, kpair);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ static Identity newInstance(String name, byte[] prvkey, byte[] certificateFileCo
throw new JSchException("Invalid certificate: missing public key");
}
kpair = KeyPair.load(instLogger, prvkey, certPublicKey);
if (prvkey != null && !Util.arraysequals(kpair.getPublicKeyBlob(), certPublicKey)) {
throw new JSchException("Certificate does not match private key");
}

} catch (IllegalArgumentException e) {
throw new JSchException("Invalid certificate format: " + e.getMessage(), e);
Expand Down
75 changes: 75 additions & 0 deletions src/test/java/com/jcraft/jsch/OpenSshCertificateKeyCompatTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.jcraft.jsch;

import static com.jcraft.jsch.ResourceUtil.getResourceFile;
import static org.junit.jupiter.api.Assertions.assertThrows;

import org.junit.jupiter.api.Test;

/**
* Unit tests for openssh certificate key compatibility: does public key signed by certificate match
* private key
*/
public class OpenSshCertificateKeyCompatTest {

Check warning on line 12 in src/test/java/com/jcraft/jsch/OpenSshCertificateKeyCompatTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove redundant visibility modifiers from the methods of this test class.

See more on https://sonarcloud.io/project/issues?id=mwiede_jsch&issues=AaD5hHlvEf_aNPJeWX_1&open=AaD5hHlvEf_aNPJeWX_1&pullRequest=1168

/**
* Test that adding an identity of a private key with matching user certificate succeeds
*/
@Test
public void testCheckPrivKeyWithMatchingUserCert() throws Exception {
JSch jsch = new JSch();
jsch.addIdentity(getResourceFile("certificates/ed25519/root_ed25519_key"),
getResourceFile("certificates/ed25519/root_ed25519_key-cert.pub"), null);
}

/**
* Test that adding an identity of a private key with unmatching user certificate fails
*/
@Test
public void testCheckPrivKeyWithNonMatchingUserCert() throws Exception {

Check warning on line 28 in src/test/java/com/jcraft/jsch/OpenSshCertificateKeyCompatTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the declaration of thrown exception 'java.lang.Exception', as it cannot be thrown from method's body.

See more on https://sonarcloud.io/project/issues?id=mwiede_jsch&issues=AaD5hHlvEf_aNPJeWX_3&open=AaD5hHlvEf_aNPJeWX_3&pullRequest=1168

Check warning on line 28 in src/test/java/com/jcraft/jsch/OpenSshCertificateKeyCompatTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace these 3 tests with a single Parameterized one.

See more on https://sonarcloud.io/project/issues?id=mwiede_jsch&issues=AaD5hHlvEf_aNPJeWX_2&open=AaD5hHlvEf_aNPJeWX_2&pullRequest=1168
JSch jsch = new JSch();
assertThrows(JSchException.class,

() -> jsch.addIdentity(getResourceFile("docker/id_ed25519"),
getResourceFile("certificates/ed25519/root_ed25519_key-cert.pub"), null));
}

/**
* Test that adding an identity of a private key with matching public key succeeds
*/
@Test
public void testCheckPrivKeyWithMatchingPubKey() throws Exception {
JSch jsch = new JSch();
jsch.addIdentity(getResourceFile("docker/id_ed25519"), getResourceFile("docker/id_ed25519.pub"),
null);
}

/**
* Test that adding an identity of a private key with non-matching public key fails
*/
@Test
public void testCheckPrivKeyWithNonMatchingPubKey() throws Exception {

Check warning on line 50 in src/test/java/com/jcraft/jsch/OpenSshCertificateKeyCompatTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the declaration of thrown exception 'java.lang.Exception', as it cannot be thrown from method's body.

See more on https://sonarcloud.io/project/issues?id=mwiede_jsch&issues=AaD5hHlvEf_aNPJeWX_4&open=AaD5hHlvEf_aNPJeWX_4&pullRequest=1168
JSch jsch = new JSch();
assertThrows(JSchException.class,

() -> jsch.addIdentity(getResourceFile("docker/id_ed25519"),
getResourceFile("certificates/ed25519/root_ed25519_key.pub"), null));
}

/**
* Test that adding an identity of a private key with something that is neither a public key nor a
* certificate fails
*/
@Test
public void testCheckPrivKeyWithNonPubKey() throws Exception {

Check warning on line 63 in src/test/java/com/jcraft/jsch/OpenSshCertificateKeyCompatTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the declaration of thrown exception 'java.lang.Exception', as it cannot be thrown from method's body.

See more on https://sonarcloud.io/project/issues?id=mwiede_jsch&issues=AaD5hHlvEf_aNPJeWX_5&open=AaD5hHlvEf_aNPJeWX_5&pullRequest=1168
JSch jsch = new JSch();
assertThrows(JSchException.class,

() -> jsch.addIdentity(getResourceFile("docker/id_ed25519"),
getResourceFile("certificates/host/sshd_config"), null));
}


private String getResourceFile(String fileName) {
return ResourceUtil.getResourceFile(getClass(), fileName);
}
}
Loading