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
[JENKINS-42959] Support Ed25519 and EDDSA host keys #51
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ | |
package hudson.plugins.sshslaves.verifiers; | ||
|
||
import java.io.IOException; | ||
import java.lang.reflect.InvocationTargetException; | ||
import java.util.StringTokenizer; | ||
|
||
import org.kohsuke.stapler.DataBoundConstructor; | ||
|
@@ -92,18 +93,36 @@ private static HostKey parseKey(String key) { | |
RSASHA1Verify.decodeSSHRSAPublicKey(keyValue); | ||
} else if ("ssh-dss".equals(algorithm)) { | ||
DSASHA1Verify.decodeSSHDSAPublicKey(keyValue); | ||
} else if (isClass("com.trilead.ssh2.signature.ED25519KeyAlgorithm") && "ssh-ed25519".equals(algorithm)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would reorder operations. |
||
decodePublicKey("com.trilead.ssh2.signature.ED25519KeyAlgorithm", keyValue); | ||
} else if (isClass("com.trilead.ssh2.signature.ECDSAKeyAlgorithm") && "ecdsa-sha2-nistp256".equals(algorithm)) { | ||
decodePublicKey("com.trilead.ssh2.signature.ECDSAKeyAlgorithm", keyValue); | ||
} else if (isClass("com.trilead.ssh2.signature.ECDSAKeyAlgorithm") && "ecdsa-sha2-nistp384".equals(algorithm)) { | ||
decodePublicKey("com.trilead.ssh2.signature.ECDSAKeyAlgorithm", keyValue); | ||
} else if (isClass("ECDSAKeyAlgorithm") && "ecdsa-sha2-nistp521".equals(algorithm)) { | ||
decodePublicKey("com.trilead.ssh2.signature.ECDSAKeyAlgorithm", keyValue); | ||
} else { | ||
throw new IllegalArgumentException("Key algorithm should be one of ssh-rsa or ssh-dss"); | ||
throw new IllegalArgumentException(Messages.ManualKeyProvidedHostKeyVerifier_UnknownKeyAlgorithm()); | ||
} | ||
} catch (IOException ex) { | ||
throw new IllegalArgumentException(Messages.ManualKeyProvidedHostKeyVerifier_KeyValueDoesNotParse(algorithm), ex); | ||
} catch (StringIndexOutOfBoundsException ex) { | ||
// can happen in DSASHA1Verifier with certain values (from quick testing) | ||
} catch (IOException | StringIndexOutOfBoundsException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | ClassNotFoundException ex) { | ||
throw new IllegalArgumentException(Messages.ManualKeyProvidedHostKeyVerifier_KeyValueDoesNotParse(algorithm), ex); | ||
} | ||
|
||
return new HostKey(algorithm, keyValue); | ||
} | ||
|
||
private static void decodePublicKey(String className, byte[] keyValue) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would rather handle these exceptions within the method |
||
Class.forName(className).getMethod("decodePublicKey", byte[].class).invoke(keyValue); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some logging on the FINE/FINEST level would be really useful. Just to know when the new algorithm decoding fails |
||
} | ||
|
||
private static boolean isClass(String className) { | ||
try { | ||
Class.forName(className); | ||
return true; | ||
} catch (ClassNotFoundException ex) { | ||
return false; | ||
} | ||
} | ||
|
||
@Extension | ||
public static class ManuallyProvidedKeyVerificationStrategyDescriptor extends SshHostKeyVerificationStrategyDescriptor { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,7 +39,7 @@ SSHLauncher.PortLessThanZero=The port value must be greater than 0 | |
SSHLauncher.PortMoreThan65535=The port value must be less than 65536 | ||
ManualTrustingHostKeyVerifier.KeyNotTrusted={0} [SSH] WARNING: The SSH key for this host is not currently trusted. Connections will be denied until this new key is authorised. | ||
ManualTrustingHostKeyVerifier.KeyAutoTrusted={0} [SSH] The SSH key with fingerprint {1} has been automatically trusted for connections to this machine. | ||
ManualTrustingHostKeyVerifier.KeyTrused={0} [SSH] SSH host key matches key seen previously for this host. Connection will be allowed. | ||
ManualTrustingHostKeyVerifier.KeyTrusted={0} [SSH] SSH host key matches key seen previously for this host. Connection will be allowed. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Translations are OK since there is no translations of this field |
||
ManualTrustingHostKeyVerifier.DescriptorDisplayName=Manually trusted key Verification Strategy | ||
NonVerifyingHostKeyVerifier.NoVerificationWarning={0} [SSH] WARNING: SSH Host Keys are not being verified. Man-in-the-middle attacks may be possible against this connection. | ||
NonVerifyingHostKeyVerifier.DescriptorDisplayName=Non verifying Verification Strategy | ||
|
@@ -49,9 +49,10 @@ ManualKeyProvidedHostKeyVerifier.KeyTrusted={0} [SSH] SSH host key matched the k | |
ManualKeyProvidedHostKeyVerifier.TwoPartKey=Key should be 2 parts: algorithm and Base 64 encoded key value. | ||
ManualKeyProvidedHostKeyVerifier.Base64EncodedKeyValueRequired=The value part of the key should be a Base64 encoded value. | ||
ManualKeyProvidedHostKeyVerifier.KeyValueDoesNotParse=Key value does not parse into a valid {0} key | ||
ManualKeyProvidedHostKeyVerifier.UnknownKeyAlgorithm=Key algorithm should be one of ssh-rsa, ssh-dss, ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, or ecdsa-sha2-nistp521. | ||
ManualKeyProvidedHostKeyVerifier.DisplayName=Manually provided key Verification Strategy | ||
KnownHostsFileHostKeyVerifier.DisplayName=Known hosts file Verification Strategy | ||
KnownHostsFileHostKeyVerifier.NewKeyNotTrusted={0} [SSH] WARNING: No entry currently exists in the Known Hosts file for this host. Connections will be denied until this new host and its associated key is added to the Known Hosts file. | ||
KnownHostsFileHostKeyVerifier.ChangedKeyNotTrusted={0} [SSH] The SSH key presented by the remote host does not match the key saved in the Known Hosts file against this host. Connections to this host will be denied until the two keys match. | ||
KnownHostsFileHostKeyVerifier.KeyTrused={0} [SSH] SSH host key matches key in Known Hosts file. Connection will be allowed. | ||
KnownHostsFileHostKeyVerifier.KeyTrusted={0} [SSH] SSH host key matches key in Known Hosts file. Connection will be allowed. | ||
KnownHostsFileHostKeyVerifier.NoKnownHostsFile={0} [SSH] No Known Hosts file was found at {0}. Please ensure one is created at this path and that Jenkins can read it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🐛 Jenkins core needs to be bumped to 1.625+ then