aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.ssh.apache.test
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit.ssh.apache.test')
-rw-r--r--org.eclipse.jgit.ssh.apache.test/.classpath7
-rw-r--r--org.eclipse.jgit.ssh.apache.test/.gitattributes2
-rw-r--r--org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.jdt.core.prefs6
-rw-r--r--org.eclipse.jgit.ssh.apache.test/BUILD50
-rw-r--r--org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF69
-rw-r--r--org.eclipse.jgit.ssh.apache.test/build.properties2
-rw-r--r--org.eclipse.jgit.ssh.apache.test/pom.xml8
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/allowed_signers2
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key7
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key27
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key2.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/expired.cert1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/no_principals.cert1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/other-ca.cert1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/other.cert1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/tester.cert1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/two_principals.cert1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krlbin0 -> 17185 bytes
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-allbin0 -> 792 bytes
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-cabin0 -> 104 bytes
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-certbin0 -> 182 bytes
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-emptybin0 -> 44 bytes
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-hashbin0 -> 445 bytes
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-keyidbin0 -> 7783 bytes
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-keyid-wildbin0 -> 7732 bytes
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-keysbin0 -> 654 bytes
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-serialbin0 -> 382 bytes
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-serial-wildbin0 -> 162 bytes
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-sha1bin0 -> 313 bytes
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-sha256bin0 -> 445 bytes
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-text11
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-00017
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0001-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0001.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-00047
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0004-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0004.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-00107
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0010-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0010.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-00507
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0050-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0050.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-00907
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0090-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0090.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-05007
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0500-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0500.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-05107
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0510-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0510.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-05207
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0520-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0520.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-05507
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0550-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0550.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-07997
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0799-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0799.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-09997
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0999-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0999.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca7
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca27
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca2.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-hash11
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-keyid512
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-serials19
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-sha111
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-sha25611
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-00057
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0005-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0005.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-00097
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0009-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0009.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-00147
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0014-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0014.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-00167
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0016-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0016.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-00297
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0029-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0029.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-00497
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0049-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0049.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-00517
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0051-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0051.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-04997
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0499-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0499.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-08007
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0800-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0800.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-10107
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1010-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1010.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-10117
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1011-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1011.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/other_key7
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/other_key-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/other_key.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/repo.bundlebin0 -> 5402 bytes
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/signing_key7
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/signing_key-cert.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/signing_key.pub1
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/AbstractSshSignatureTest.java119
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/AllowedSignersParseTest.java211
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/OpenSshBinaryKrlLoadTest.java32
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/OpenSshKrlTest.java146
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SerialRangeSetTest.java124
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SshCertificateUtilsTest.java107
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SshSignatureVerifierTest.java151
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SshSignerTest.java62
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/VerifyGitSignaturesTest.java154
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/transport/sshd/KnownHostEntryReaderTest.java29
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabaseTest.java586
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshProtocol2Test.java4
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java33
127 files changed, 2688 insertions, 45 deletions
diff --git a/org.eclipse.jgit.ssh.apache.test/.classpath b/org.eclipse.jgit.ssh.apache.test/.classpath
index 5899a4e74e..5be47afffb 100644
--- a/org.eclipse.jgit.ssh.apache.test/.classpath
+++ b/org.eclipse.jgit.ssh.apache.test/.classpath
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
<attributes>
<attribute name="module" value="true"/>
</attributes>
@@ -11,5 +11,10 @@
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
+ <classpathentry kind="src" path="tst-rsrc">
+ <attributes>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/org.eclipse.jgit.ssh.apache.test/.gitattributes b/org.eclipse.jgit.ssh.apache.test/.gitattributes
new file mode 100644
index 0000000000..b5b937561d
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/.gitattributes
@@ -0,0 +1,2 @@
+/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/repo.bundle binary
+/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl* binary
diff --git a/org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.jdt.core.prefs
index 76f48d86d5..489fd959f1 100644
--- a/org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.jdt.core.prefs
@@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -115,7 +115,7 @@ org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
org.eclipse.jdt.core.compiler.release=enabled
-org.eclipse.jdt.core.compiler.source=11
+org.eclipse.jdt.core.compiler.source=17
org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
diff --git a/org.eclipse.jgit.ssh.apache.test/BUILD b/org.eclipse.jgit.ssh.apache.test/BUILD
index b384464484..bf796c058e 100644
--- a/org.eclipse.jgit.ssh.apache.test/BUILD
+++ b/org.eclipse.jgit.ssh.apache.test/BUILD
@@ -1,19 +1,51 @@
load(
+ "@com_googlesource_gerrit_bazlets//tools:genrule2.bzl",
+ "genrule2",
+)
+load(
"@com_googlesource_gerrit_bazlets//tools:junit.bzl",
"junit_tests",
)
+DEPS = [
+ "//lib:bcpkix",
+ "//lib:bcprov",
+ "//lib:bcutil",
+ "//lib:junit",
+ "//lib:slf4j-api",
+ "//lib:sshd-osgi",
+ "//lib:sshd-sftp",
+ "//org.eclipse.jgit:jgit",
+ "//org.eclipse.jgit.junit:junit",
+ "//org.eclipse.jgit.junit.ssh:junit-ssh",
+ "//org.eclipse.jgit.ssh.apache:ssh-apache",
+]
+
+HELPERS = ["tst/org/eclipse/jgit/internal/signing/ssh/AbstractSshSignatureTest.java"]
+
junit_tests(
name = "sshd_apache",
- srcs = glob(["tst/**/*.java"]),
+ srcs = glob(
+ ["tst/**/*.java"],
+ exclude = HELPERS,
+ ),
tags = ["sshd"],
- deps = [
- "//lib:eddsa",
- "//lib:junit",
- "//lib:sshd-osgi",
- "//lib:sshd-sftp",
- "//org.eclipse.jgit:jgit",
- "//org.eclipse.jgit.junit.ssh:junit-ssh",
- "//org.eclipse.jgit.ssh.apache:ssh-apache",
+ runtime_deps = [":tst_rsrc"],
+ deps = DEPS + [
+ ":helpers",
],
)
+
+java_library(
+ name = "helpers",
+ testonly = 1,
+ srcs = HELPERS,
+ deps = DEPS,
+)
+
+genrule2(
+ name = "tst_rsrc",
+ srcs = glob(["tst-rsrc/**"]),
+ outs = ["tst_rsrc.jar"],
+ cmd = "tar cf - $(SRCS) | tar -C $$TMP --strip-components=2 -xf - && cd $$TMP && zip -qr $$ROOT/$@ .",
+)
diff --git a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
index 1e74f2baee..78dfd14a42 100644
--- a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
@@ -3,35 +3,48 @@ Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.ssh.apache.test
Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.test
-Bundle-Version: 6.6.0.qualifier
+Bundle-Version: 7.4.0.qualifier
Bundle-Vendor: %Bundle-Vendor
Bundle-Localization: plugin
-Bundle-RequiredExecutionEnvironment: JavaSE-11
-Import-Package: org.apache.sshd.client.config.hosts;version="[2.9.2,2.10.0)",
- org.apache.sshd.common;version="[2.9.2,2.10.0)",
- org.apache.sshd.common.auth;version="[2.9.2,2.10.0)",
- org.apache.sshd.common.config.keys;version="[2.9.2,2.10.0)",
- org.apache.sshd.common.helpers;version="[2.9.2,2.10.0)",
- org.apache.sshd.common.kex;version="[2.9.2,2.10.0)",
- org.apache.sshd.common.keyprovider;version="[2.9.2,2.10.0)",
- org.apache.sshd.common.session;version="[2.9.2,2.10.0)",
- org.apache.sshd.common.signature;version="[2.9.2,2.10.0)",
- org.apache.sshd.common.util.net;version="[2.9.2,2.10.0)",
- org.apache.sshd.common.util.security;version="[2.9.2,2.10.0)",
- org.apache.sshd.core;version="[2.9.2,2.10.0)",
- org.apache.sshd.server;version="[2.9.2,2.10.0)",
- org.apache.sshd.server.forward;version="[2.9.2,2.10.0)",
- org.eclipse.jgit.api;version="[6.6.0,6.7.0)",
- org.eclipse.jgit.api.errors;version="[6.6.0,6.7.0)",
- org.eclipse.jgit.internal.transport.sshd.proxy;version="[6.6.0,6.7.0)",
- org.eclipse.jgit.junit;version="[6.6.0,6.7.0)",
- org.eclipse.jgit.junit.ssh;version="[6.6.0,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.0,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.0,6.7.0)",
- org.eclipse.jgit.transport.sshd;version="[6.6.0,6.7.0)",
- org.eclipse.jgit.transport.sshd.agent;version="[6.6.0,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.0,6.7.0)",
- org.hamcrest;version="[1.1.0,3.0.0)",
+Bundle-RequiredExecutionEnvironment: JavaSE-17
+Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git
+Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)"
+Import-Package: org.apache.sshd.certificate;version="[2.15.0,2.16.0)",
+ org.apache.sshd.client.config.hosts;version="[2.15.0,2.16.0)",
+ org.apache.sshd.common;version="[2.15.0,2.16.0)",
+ org.apache.sshd.common.auth;version="[2.15.0,2.16.0)",
+ org.apache.sshd.common.cipher;version="[2.15.0,2.16.0)",
+ org.apache.sshd.common.config.keys;version="[2.15.0,2.16.0)",
+ org.apache.sshd.common.helpers;version="[2.15.0,2.16.0)",
+ org.apache.sshd.common.kex;version="[2.15.0,2.16.0)",
+ org.apache.sshd.common.keyprovider;version="[2.15.0,2.16.0)",
+ org.apache.sshd.common.session;version="[2.15.0,2.16.0)",
+ org.apache.sshd.common.signature;version="[2.15.0,2.16.0)",
+ org.apache.sshd.common.util.buffer;version="[2.15.0,2.16.0)",
+ org.apache.sshd.common.util.net;version="[2.15.0,2.16.0)",
+ org.apache.sshd.common.util.security;version="[2.15.0,2.16.0)",
+ org.apache.sshd.core;version="[2.15.0,2.16.0)",
+ org.apache.sshd.server;version="[2.15.0,2.16.0)",
+ org.apache.sshd.server.forward;version="[2.15.0,2.16.0)",
+ org.eclipse.jgit.annotations;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.api;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.api.errors;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.errors;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.internal.signing.ssh;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.internal.transport.sshd;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.internal.transport.sshd.proxy;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.junit;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.junit.ssh;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.lib;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.revwalk;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.transport;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.transport.sshd;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.transport.sshd.agent;version="[7.4.0,7.5.0)",
+ org.eclipse.jgit.util;version="[7.4.0,7.5.0)",
org.junit;version="[4.13,5.0.0)",
org.junit.experimental.theories;version="[4.13,5.0.0)",
- org.junit.runner;version="[4.13,5.0.0)"
+ org.junit.rules;version="[4.13.0,5.0.0)",
+ org.junit.runner;version="[4.13,5.0.0)",
+ org.junit.runners;version="[4.13.0,5.0.0)",
+ org.slf4j;version="[1.7.0,3.0.0)"
diff --git a/org.eclipse.jgit.ssh.apache.test/build.properties b/org.eclipse.jgit.ssh.apache.test/build.properties
index 35d7145160..0e94aa00ef 100644
--- a/org.eclipse.jgit.ssh.apache.test/build.properties
+++ b/org.eclipse.jgit.ssh.apache.test/build.properties
@@ -3,4 +3,4 @@ output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.properties
-additional.bundles = org.slf4j.binding.simple
+additional.bundles = slf4j.simple
diff --git a/org.eclipse.jgit.ssh.apache.test/pom.xml b/org.eclipse.jgit.ssh.apache.test/pom.xml
index d7c2146371..7768e95694 100644
--- a/org.eclipse.jgit.ssh.apache.test/pom.xml
+++ b/org.eclipse.jgit.ssh.apache.test/pom.xml
@@ -17,7 +17,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>6.6.0-SNAPSHOT</version>
+ <version>7.4.0-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.ssh.apache.test</artifactId>
@@ -91,6 +91,12 @@
<sourceDirectory>src/</sourceDirectory>
<testSourceDirectory>tst/</testSourceDirectory>
+ <testResources>
+ <testResource>
+ <directory>tst-rsrc/</directory>
+ </testResource>
+ </testResources>
+
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/allowed_signers b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/allowed_signers
new file mode 100644
index 0000000000..ec74409e54
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/allowed_signers
@@ -0,0 +1,2 @@
+tester@example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO
+*@example.com cert-authority ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMdEl+iOTEbf1RC3uicECtid+SaIMsAw7wrlWhOQTyBV
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key
new file mode 100644
index 0000000000..b8de8c3353
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACDHRJfojkxG39UQt7onBArYnfkmiDLAMO8K5VoTkE8gVQAAAJAhCMgzIQjI
+MwAAAAtzc2gtZWQyNTUxOQAAACDHRJfojkxG39UQt7onBArYnfkmiDLAMO8K5VoTkE8gVQ
+AAAEBmcXpast20+B4IzA0Xex2CKYiiWJj3NFJ5F0kil113vcdEl+iOTEbf1RC3uicECtid
++SaIMsAw7wrlWhOQTyBVAAAADVRIV09AU0VBR044MDA=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key.pub
new file mode 100644
index 0000000000..842415b0e8
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMdEl+iOTEbf1RC3uicECtid+SaIMsAw7wrlWhOQTyBV
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key2 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key2
new file mode 100644
index 0000000000..a4af0479bc
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key2
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACA7S4ycIB6oTx4UN8l9N+u016UgMzkrbT7E+2XbG35jgwAAAJAa2jfBGto3
+wQAAAAtzc2gtZWQyNTUxOQAAACA7S4ycIB6oTx4UN8l9N+u016UgMzkrbT7E+2XbG35jgw
+AAAEBothGMqFaA5aTO8MLx9wm1oDRfzQCSsu7uJwrOiUFTTTtLjJwgHqhPHhQ3yX0367TX
+pSAzOSttPsT7ZdsbfmODAAAADVRIV09AU0VBR044MDA=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key2.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key2.pub
new file mode 100644
index 0000000000..e46c87e83f
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/ca_key2.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDtLjJwgHqhPHhQ3yX0367TXpSAzOSttPsT7ZdsbfmOD
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/expired.cert b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/expired.cert
new file mode 100644
index 0000000000..9da63ec900
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/expired.cert
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAINFZ5NKywAWh1G1P6BiBKArmYKs1BDhJBOawJKlS29VXAAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzOAAAAAAAAAAEAAAABAAAADGV4cGlyZWRfY2VydAAAAAAAAAAAZtOugAAAAABm1QAAAAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgx0SX6I5MRt/VELe6JwQK2J35JogywDDvCuVaE5BPIFUAAABTAAAAC3NzaC1lZDI1NTE5AAAAQNf8i5dhRqWRe06epIRrZ5V+QZHq3ZrlJtlx98UJya9GAeCrJ5oHwBjr5O5TL5wNJS5Hz+T1qsJNFU9d1wdcuwI=
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/no_principals.cert b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/no_principals.cert
new file mode 100644
index 0000000000..101e37469d
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/no_principals.cert
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAILzuED1RSloB/enTghTEKSACVOuEARP0f8UVXSRwEXN6AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzOAAAAAAAAAAIAAAABAAAADW5vX3ByaW5jaXBhbHMAAAAAAAAAAGbTroAAAAAAZyLIgAAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIMdEl+iOTEbf1RC3uicECtid+SaIMsAw7wrlWhOQTyBVAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEBwEQ2D0OHn4QDHnsINlgWUWpmhukseQCJu3Adulz28fFtewp1LLqkBy50wR6vJe1ifYbY4hzReXOSyoTmHSXEN
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/other-ca.cert b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/other-ca.cert
new file mode 100644
index 0000000000..752fee1778
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/other-ca.cert
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIHNW2bzSS61lvgHippv3Ymx4cVEAXBVCb8lFXHnVpsSyAAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzOAAAAAAAAAAYAAAABAAAAB3Rlc3RlcjIAAAAWAAAAEnRlc3RlckBleGFtcGxlLmNvbQAAAABm066AAAAAAGciyIAAAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACA7S4ycIB6oTx4UN8l9N+u016UgMzkrbT7E+2XbG35jgwAAAFMAAAALc3NoLWVkMjU1MTkAAABAuJ8zBazcaYTbUEr9QtoYox0MkVBg+8LANxJxc885M2vmg9yPHpTfV/emupqhBwuYcPJSskTxl7WX4TUNvhMsAA==
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/other.cert b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/other.cert
new file mode 100644
index 0000000000..15825f6055
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/other.cert
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIGKXzyrvDzj9ObQ4SuzqytK6nomOV8DhgdzODfWuup1sAAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzOAAAAAAAAAAQAAAABAAAABW90aGVyAAAAFQAAABFvdGhlckBleGFtcGxlLmNvbQAAAABm066AAAAAAGciyIAAAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACDHRJfojkxG39UQt7onBArYnfkmiDLAMO8K5VoTkE8gVQAAAFMAAAALc3NoLWVkMjU1MTkAAABA1ycFqWehyC6pIISEkXSTtHbatLWl9HHAoUFouQiDdubAnMDRSkyHipXR62rq+8yEAvtqm1mXBzO8nLalkF9xAA==
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/tester.cert b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/tester.cert
new file mode 100644
index 0000000000..a2b241c241
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/tester.cert
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAICSl1xsyTWb23YlKo21musxOzj4L4eD2coTkHbBw2uOyAAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzOAAAAAAAAAAMAAAABAAAABnRlc3RlcgAAABYAAAASdGVzdGVyQGV4YW1wbGUuY29tAAAAAGbTroAAAAAAZyLIgAAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIMdEl+iOTEbf1RC3uicECtid+SaIMsAw7wrlWhOQTyBVAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEDyjzq/0Egm1OxwrvqPZKUihE3w357Ji9Nd3j7VnUuvSYTXAdB9P0E+a2hyCcemmsil1MsvWTiCSSOsrHVB6FEO
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/two_principals.cert b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/two_principals.cert
new file mode 100644
index 0000000000..5f7164a7fc
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/certs/two_principals.cert
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIFmWKr9gNSQT0vna7k3uOyUF9CTcMGw2zxTFBf2Ev8TzAAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzOAAAAAAAAAAgAAAABAAAABnRlc3RlcgAAACkAAAAPZm9vQGV4YW1wbGUuY29tAAAAEnRlc3RlckBleGFtcGxlLmNvbQAAAABm066AAAAAAGciyIAAAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACDHRJfojkxG39UQt7onBArYnfkmiDLAMO8K5VoTkE8gVQAAAFMAAAALc3NoLWVkMjU1MTkAAABAqlSX2GzLz5U+hN/gF9UUyAkE6h5BgVFYhsyf1MR/B7Hoxa29wGLbJpUplrqEHMxoud2zfH2Nhj00unc3lr5bBA== ./signing_key.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl
new file mode 100644
index 0000000000..9469340ed3
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl
Binary files differ
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-all b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-all
new file mode 100644
index 0000000000..6f744c3a2d
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-all
Binary files differ
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-ca b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-ca
new file mode 100644
index 0000000000..84a8bc6b38
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-ca
Binary files differ
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-cert b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-cert
new file mode 100644
index 0000000000..26f29b2ba5
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-cert
Binary files differ
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-empty b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-empty
new file mode 100644
index 0000000000..78e5187f29
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-empty
Binary files differ
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-hash b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-hash
new file mode 100644
index 0000000000..cdd1351598
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-hash
Binary files differ
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-keyid b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-keyid
new file mode 100644
index 0000000000..1a65243f44
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-keyid
Binary files differ
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-keyid-wild b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-keyid-wild
new file mode 100644
index 0000000000..9ba549f363
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-keyid-wild
Binary files differ
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-keys b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-keys
new file mode 100644
index 0000000000..8dd496d7c1
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-keys
Binary files differ
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-serial b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-serial
new file mode 100644
index 0000000000..9965e2e36f
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-serial
Binary files differ
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-serial-wild b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-serial-wild
new file mode 100644
index 0000000000..aefd2b1a84
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-serial-wild
Binary files differ
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-sha1 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-sha1
new file mode 100644
index 0000000000..3928543ad1
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-sha1
Binary files differ
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-sha256 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-sha256
new file mode 100644
index 0000000000..cdd1351598
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-sha256
Binary files differ
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-text b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-text
new file mode 100644
index 0000000000..77ddd5e0d0
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl-text
@@ -0,0 +1,11 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC29QZ72HtyCdaNo6p2GH3fJpUynwkvs8Acwn66G7YTh
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0ZC4fqgbBgROeX1sOEPr4uMVNfPdJ62bVo/zvSMRQx
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG5IH9T7FY47VJDUoyOlB/iqCN4pO8dgOrxclmKN5R5w
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINjhG4+EnQy8YHLsfE8+IQwNWZVn1GBYX75pwxBCZGmy
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJXm+qgTs+sO+9zvoZBxkQD39R2rQqQCVezxQoGjKui5
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL8+aQKja+SbqxfWR61FCcsbBw2jaF/KHvcqdP2Fbp6Q
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAOL7IULalT2Izo9TgRf1t2HNpZ5WCZJH5oRCd9LK3BN
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGVaSedhPkl2Hrx1nOOKT2E52ADsBebawws87NN1+P6e
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICxyaxj7pRVDeh/gxJem9BLhoUQKGnKXHfDrB/GtC1KB
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID96GKtj4wN+OwvrQsgP37fQVUXThCML796qqFNLVDCA
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEh3BFcTzXmg1Fi5LvWiUDWORsHzVhUCm8ekrEJG6+6A
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0001 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0001
new file mode 100644
index 0000000000..893fd5e776
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0001
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACAtvUGe9h7cgnWjaOqdhh93yaVMp8JL7PAHMJ+uhu2E4QAAAIhUa4KiVGuC
+ogAAAAtzc2gtZWQyNTUxOQAAACAtvUGe9h7cgnWjaOqdhh93yaVMp8JL7PAHMJ+uhu2E4Q
+AAAECKgy+3FBgpdfxjOtNy9TamhadMWSyPlPiwu06mYVReyS29QZ72HtyCdaNo6p2GH3fJ
+pUynwkvs8Acwn66G7YThAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0001-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0001-cert.pub
new file mode 100644
index 0000000000..e2bcd25964
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0001-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIE1UUsQ+sncsuST6eGe3B5Se7purqhGcWrkyIwUnQM/jAAAAIC29QZ72HtyCdaNo6p2GH3fJpUynwkvs8Acwn66G7YThAAAAAAAAAAEAAAABAAAACXJldm9rZWQgMQAAAAAAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgFtF5l68spzOFrIpQANF0C9nkNdXMAmlCRwHgw91C784AAABTAAAAC3NzaC1lZDI1NTE5AAAAQCjDATJVQs3odl9fsqaxyx/18qrodZEDyYZAsdqg0GMx8CvLYt4xHENyVm7kyBRxOeh3EKfII0WFoYCV4mGZ/wU= ./tst-keys/revoked-0001.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0001.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0001.pub
new file mode 100644
index 0000000000..f561982278
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0001.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC29QZ72HtyCdaNo6p2GH3fJpUynwkvs8Acwn66G7YTh
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0004 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0004
new file mode 100644
index 0000000000..e50a4fefe9
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0004
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACC9GQuH6oGwYETnl9bDhD6+LjFTXz3Setm1aP870jEUMQAAAIiQzZzikM2c
+4gAAAAtzc2gtZWQyNTUxOQAAACC9GQuH6oGwYETnl9bDhD6+LjFTXz3Setm1aP870jEUMQ
+AAAEBpn5dxbvHhqAsSVN3IqRwzbFFgOhdmpkOP+nvoKq+rSr0ZC4fqgbBgROeX1sOEPr4u
+MVNfPdJ62bVo/zvSMRQxAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0004-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0004-cert.pub
new file mode 100644
index 0000000000..8e92fa7c86
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0004-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIC5jMLPDlEVbyPU/Icb04BF5jxN+OT8kpuO5c0CV6/AYAAAAIL0ZC4fqgbBgROeX1sOEPr4uMVNfPdJ62bVo/zvSMRQxAAAAAAAAAAQAAAABAAAACXJldm9rZWQgNAAAAAAAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgFtF5l68spzOFrIpQANF0C9nkNdXMAmlCRwHgw91C784AAABTAAAAC3NzaC1lZDI1NTE5AAAAQOH4yNn7+zyvsCV8BCoop5xYv4uFk27VZRjmscuy3J66KNwLay9XkvkRNArDaWBwH47dmkcU7F6fLLpY4vN2jgM= ./tst-keys/revoked-0004.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0004.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0004.pub
new file mode 100644
index 0000000000..1d7fe7fa7f
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0004.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0ZC4fqgbBgROeX1sOEPr4uMVNfPdJ62bVo/zvSMRQx
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0010 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0010
new file mode 100644
index 0000000000..fb457df249
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0010
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACBuSB/U+xWOO1SQ1KMjpQf4qgjeKTvHYDq8XJZijeUecAAAAIgvtSiML7Uo
+jAAAAAtzc2gtZWQyNTUxOQAAACBuSB/U+xWOO1SQ1KMjpQf4qgjeKTvHYDq8XJZijeUecA
+AAAECI2si7/SGjMM1UyhrFPXx4laQIfFUsb1+yfXKwQyeOXW5IH9T7FY47VJDUoyOlB/iq
+CN4pO8dgOrxclmKN5R5wAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0010-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0010-cert.pub
new file mode 100644
index 0000000000..9492f88a90
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0010-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIN2arXaBzVIdxAFfU+XU1Uc788HKlDH3tOLdDtcoORLmAAAAIG5IH9T7FY47VJDUoyOlB/iqCN4pO8dgOrxclmKN5R5wAAAAAAAAAAoAAAABAAAACnJldm9rZWQgMTAAAAAAAAAAAAAAAAD//////////wAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIBbReZevLKczhayKUADRdAvZ5DXVzAJpQkcB4MPdQu/OAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEDwhgQsYOG/eKf8EfH+fAmEW+88/ZJCmxAExEFPxkGL59waZcGiOJqquTKiqN5Kod8hpUrvZywrA0tjrRkYw8wH ./tst-keys/revoked-0010.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0010.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0010.pub
new file mode 100644
index 0000000000..37a0d84e7a
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0010.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG5IH9T7FY47VJDUoyOlB/iqCN4pO8dgOrxclmKN5R5w
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0050 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0050
new file mode 100644
index 0000000000..b02e9df821
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0050
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACDY4RuPhJ0MvGBy7HxPPiEMDVmVZ9RgWF++acMQQmRpsgAAAIgCZLe5AmS3
+uQAAAAtzc2gtZWQyNTUxOQAAACDY4RuPhJ0MvGBy7HxPPiEMDVmVZ9RgWF++acMQQmRpsg
+AAAEB9Q6rpWK04mQDoeKSB2I7p/rb8pu00ClhR+vRATl4TYdjhG4+EnQy8YHLsfE8+IQwN
+WZVn1GBYX75pwxBCZGmyAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0050-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0050-cert.pub
new file mode 100644
index 0000000000..90bb86f9b5
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0050-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIIecNj2Es6VfyCrhol4swP9lutvphd3seh+/b2LpD0EsAAAAINjhG4+EnQy8YHLsfE8+IQwNWZVn1GBYX75pwxBCZGmyAAAAAAAAADIAAAABAAAACnJldm9rZWQgNTAAAAAAAAAAAAAAAAD//////////wAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIBbReZevLKczhayKUADRdAvZ5DXVzAJpQkcB4MPdQu/OAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEA2q8tCXV8FXkB0QWnFNWfCL7zz5jCXL9ZQADM1DaGi8oUU/dxmlQtWgMxuu5vNuvOYQGPDcBLj+by8VqAdvZMP ./tst-keys/revoked-0050.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0050.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0050.pub
new file mode 100644
index 0000000000..f3ad249daa
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0050.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINjhG4+EnQy8YHLsfE8+IQwNWZVn1GBYX75pwxBCZGmy
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0090 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0090
new file mode 100644
index 0000000000..efa3d5ef0a
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0090
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACCV5vqoE7PrDvvc76GQcZEA9/Udq0KkAlXs8UKBoyrouQAAAIg3mgznN5oM
+5wAAAAtzc2gtZWQyNTUxOQAAACCV5vqoE7PrDvvc76GQcZEA9/Udq0KkAlXs8UKBoyrouQ
+AAAEAkRynGUH9n5hcp/S1WALvuIEDtbkMi2A7yNWze0o4gWpXm+qgTs+sO+9zvoZBxkQD3
+9R2rQqQCVezxQoGjKui5AAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0090-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0090-cert.pub
new file mode 100644
index 0000000000..26e61e0abb
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0090-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIOjIztpPiaKY0hztHWtWpX+4LEoyy8qYPPT277K3bykSAAAAIJXm+qgTs+sO+9zvoZBxkQD39R2rQqQCVezxQoGjKui5AAAAAAAAAFoAAAABAAAACnJldm9rZWQgOTAAAAAAAAAAAAAAAAD//////////wAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIBbReZevLKczhayKUADRdAvZ5DXVzAJpQkcB4MPdQu/OAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEBUaAWyv/jZrbrCO5zw2HuZcWYBig8R2jdvkKr5yzWMWEVRtn97gnAUsIGxkgUnUAs3B2En2FH2NaicC1F1n3sF ./tst-keys/revoked-0090.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0090.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0090.pub
new file mode 100644
index 0000000000..e51b88c268
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0090.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJXm+qgTs+sO+9zvoZBxkQD39R2rQqQCVezxQoGjKui5
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0500 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0500
new file mode 100644
index 0000000000..900d444363
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0500
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACC/PmkCo2vkm6sX1ketRQnLGwcNo2hfyh73KnT9hW6ekAAAAIhDam0PQ2pt
+DwAAAAtzc2gtZWQyNTUxOQAAACC/PmkCo2vkm6sX1ketRQnLGwcNo2hfyh73KnT9hW6ekA
+AAAED606GrYWlY7TOXcr8vAr3fjMtCtetdpwFHi2pzgf2Bbb8+aQKja+SbqxfWR61FCcsb
+Bw2jaF/KHvcqdP2Fbp6QAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0500-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0500-cert.pub
new file mode 100644
index 0000000000..07096182b4
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0500-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIIEblAg4b1eJ5KnT7KvYoOfe24La+nAKKLIYdsR6CdreAAAAIL8+aQKja+SbqxfWR61FCcsbBw2jaF/KHvcqdP2Fbp6QAAAAAAAAAfQAAAABAAAAC3Jldm9rZWQgNTAwAAAAAAAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAW0XmXryynM4WsilAA0XQL2eQ11cwCaUJHAeDD3ULvzgAAAFMAAAALc3NoLWVkMjU1MTkAAABAc0WEuRfi9LG9uTfKY4Dh5MJCHUG7Dqp1J4S4Gs1iOzFX2YKgYXc0O+9j3jJ5/fB4z960Y1AxYR4TWEo1pNjzBQ== ./tst-keys/revoked-0500.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0500.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0500.pub
new file mode 100644
index 0000000000..13d1aa4238
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0500.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL8+aQKja+SbqxfWR61FCcsbBw2jaF/KHvcqdP2Fbp6Q
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0510 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0510
new file mode 100644
index 0000000000..a58675ec55
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0510
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACADi+yFC2pU9iM6PU4EX9bdhzaWeVgmSR+aEQnfSytwTQAAAIgigF2AIoBd
+gAAAAAtzc2gtZWQyNTUxOQAAACADi+yFC2pU9iM6PU4EX9bdhzaWeVgmSR+aEQnfSytwTQ
+AAAEBWpyFpK0a+cdNPFMsvHTHtjBJpX4aMHxBAcEPN8hnpWAOL7IULalT2Izo9TgRf1t2H
+NpZ5WCZJH5oRCd9LK3BNAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0510-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0510-cert.pub
new file mode 100644
index 0000000000..1431af306f
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0510-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAII8u8ho0YtDyXWYKv4WeOXSaRUxU8sUV0dQujB2J9VLaAAAAIAOL7IULalT2Izo9TgRf1t2HNpZ5WCZJH5oRCd9LK3BNAAAAAAAAAf4AAAABAAAAC3Jldm9rZWQgNTEwAAAAAAAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAW0XmXryynM4WsilAA0XQL2eQ11cwCaUJHAeDD3ULvzgAAAFMAAAALc3NoLWVkMjU1MTkAAABA3aijJnt8mJ8vLtr7H2PBVJHtNJpL6MQZNXHC6svzygIqZwEq3tDHGR00TPHaCYAqDEXQZysONciOQtQHzKXuBw== ./tst-keys/revoked-0510.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0510.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0510.pub
new file mode 100644
index 0000000000..33ad644ab3
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0510.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAOL7IULalT2Izo9TgRf1t2HNpZ5WCZJH5oRCd9LK3BN
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0520 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0520
new file mode 100644
index 0000000000..630316c0ae
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0520
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACBlWknnYT5Jdh68dZzjik9hOdgA7AXm2sMLPOzTdfj+ngAAAIghEm1OIRJt
+TgAAAAtzc2gtZWQyNTUxOQAAACBlWknnYT5Jdh68dZzjik9hOdgA7AXm2sMLPOzTdfj+ng
+AAAEDfVYURudvfzK3ZFx6T2O1CWi0emOZ0MYPcDzUVlu1WmGVaSedhPkl2Hrx1nOOKT2E5
+2ADsBebawws87NN1+P6eAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0520-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0520-cert.pub
new file mode 100644
index 0000000000..b2909431ad
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0520-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAID/r9T2Sv0NGmlcHl6Fw8rVPIupmsqwq3WAG1NvW7WRcAAAAIGVaSedhPkl2Hrx1nOOKT2E52ADsBebawws87NN1+P6eAAAAAAAAAggAAAABAAAAC3Jldm9rZWQgNTIwAAAAAAAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAW0XmXryynM4WsilAA0XQL2eQ11cwCaUJHAeDD3ULvzgAAAFMAAAALc3NoLWVkMjU1MTkAAABAF8zkeAqwtlxF4iy4mDEHkzVaRqcS0sZ57gcZBWGn/peGFy3MpSxlFQM/IC2pNZ7GuCVSIPV6rRLJC65YMMOEDQ== ./tst-keys/revoked-0520.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0520.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0520.pub
new file mode 100644
index 0000000000..fc13d37d33
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0520.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGVaSedhPkl2Hrx1nOOKT2E52ADsBebawws87NN1+P6e
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0550 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0550
new file mode 100644
index 0000000000..5e671b4ee0
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0550
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACAscmsY+6UVQ3of4MSXpvQS4aFEChpylx3w6wfxrQtSgQAAAIj/9GKZ//Ri
+mQAAAAtzc2gtZWQyNTUxOQAAACAscmsY+6UVQ3of4MSXpvQS4aFEChpylx3w6wfxrQtSgQ
+AAAEDKC3eEgvCMy86rktq7VU1YQjjKY1iDFPVxWgKKcGJKkyxyaxj7pRVDeh/gxJem9BLh
+oUQKGnKXHfDrB/GtC1KBAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0550-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0550-cert.pub
new file mode 100644
index 0000000000..f529a91713
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0550-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIF9q+Cg+9DSKt09eW1NXqVC4dZ3v80sZIYtc0/yqHRb+AAAAICxyaxj7pRVDeh/gxJem9BLhoUQKGnKXHfDrB/GtC1KBAAAAAAAAAiYAAAABAAAAC3Jldm9rZWQgNTUwAAAAAAAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAW0XmXryynM4WsilAA0XQL2eQ11cwCaUJHAeDD3ULvzgAAAFMAAAALc3NoLWVkMjU1MTkAAABAovTuFOXLNCc4hQcI2hatXe2hbBQYbcnUo2BNdJ9EvIOsH/T0DzzEfRQajMQ+QD6oujIx7fb1Z2sRVPOAb3AcBg== ./tst-keys/revoked-0550.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0550.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0550.pub
new file mode 100644
index 0000000000..e09316a37e
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0550.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICxyaxj7pRVDeh/gxJem9BLhoUQKGnKXHfDrB/GtC1KB
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0799 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0799
new file mode 100644
index 0000000000..8edd73662b
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0799
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACA/ehirY+MDfjsL60LID9+30FVF04QjC+/eqqhTS1QwgAAAAIjdntzR3Z7c
+0QAAAAtzc2gtZWQyNTUxOQAAACA/ehirY+MDfjsL60LID9+30FVF04QjC+/eqqhTS1QwgA
+AAAEDQEb+IFCIz+yvkhmrOQ85GafOm9ra0oNRontpox62UTj96GKtj4wN+OwvrQsgP37fQ
+VUXThCML796qqFNLVDCAAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0799-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0799-cert.pub
new file mode 100644
index 0000000000..80312fbe0d
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0799-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIC1z1LkrZhMz1mBWPU8sJIuH59v+ig4OK/B4/x8jLAtUAAAAID96GKtj4wN+OwvrQsgP37fQVUXThCML796qqFNLVDCAAAAAAAAAAx8AAAABAAAAC3Jldm9rZWQgNzk5AAAAAAAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAW0XmXryynM4WsilAA0XQL2eQ11cwCaUJHAeDD3ULvzgAAAFMAAAALc3NoLWVkMjU1MTkAAABASNkJSbdRDARfgbqPOnuES0o6m6VZ7RC2XLPm3uwTqCvMqtHbFvq9etMddSUIR4XXah6ef+O7CJDk/Yjpkn+2CA== ./tst-keys/revoked-0799.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0799.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0799.pub
new file mode 100644
index 0000000000..1f0556cd05
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0799.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID96GKtj4wN+OwvrQsgP37fQVUXThCML796qqFNLVDCA
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0999 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0999
new file mode 100644
index 0000000000..f05a1e41fc
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0999
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACBIdwRXE815oNRYuS71olA1jkbB81YVApvHpKxCRuvugAAAAIgzBpObMwaT
+mwAAAAtzc2gtZWQyNTUxOQAAACBIdwRXE815oNRYuS71olA1jkbB81YVApvHpKxCRuvugA
+AAAECxY5wx3XKIhMT+ajMZXPl51x8rkCPBq6gUgZV3Uqpu7Eh3BFcTzXmg1Fi5LvWiUDWO
+RsHzVhUCm8ekrEJG6+6AAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0999-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0999-cert.pub
new file mode 100644
index 0000000000..4aedb7770f
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0999-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIGt3nV/XJmtz9sQGP2fiZiKOH7mkPhezN3S+8TnsVcQjAAAAIEh3BFcTzXmg1Fi5LvWiUDWORsHzVhUCm8ekrEJG6+6AAAAAAAAAA+cAAAABAAAAC3Jldm9rZWQgOTk5AAAAAAAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAW0XmXryynM4WsilAA0XQL2eQ11cwCaUJHAeDD3ULvzgAAAFMAAAALc3NoLWVkMjU1MTkAAABAvLVCRCs7CV0JSXYL8ge4iRxL4y48bYuvu3YimKZDg7NdCXqw/jkaCsxJykRzb/xVnQDoNVCQQuzydt/I13FdBA== ./tst-keys/revoked-0999.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0999.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0999.pub
new file mode 100644
index 0000000000..c837fe06ae
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-0999.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEh3BFcTzXmg1Fi5LvWiUDWORsHzVhUCm8ekrEJG6+6A
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca
new file mode 100644
index 0000000000..47e01fb5c2
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACAW0XmXryynM4WsilAA0XQL2eQ11cwCaUJHAeDD3ULvzgAAAIgok4I2KJOC
+NgAAAAtzc2gtZWQyNTUxOQAAACAW0XmXryynM4WsilAA0XQL2eQ11cwCaUJHAeDD3ULvzg
+AAAEAEN+knz2qOyj+jbY+SJSHYQhlJoB1u9jLqoQoiAerI3hbReZevLKczhayKUADRdAvZ
+5DXVzAJpQkcB4MPdQu/OAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca.pub
new file mode 100644
index 0000000000..2b92f89e71
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBbReZevLKczhayKUADRdAvZ5DXVzAJpQkcB4MPdQu/O
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca2 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca2
new file mode 100644
index 0000000000..770ceee2e7
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca2
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACDsEBCX5jBwggkpt4XZXct1fOhDBuvgLL0KMpGoHRtj9wAAAIjMEwOtzBMD
+rQAAAAtzc2gtZWQyNTUxOQAAACDsEBCX5jBwggkpt4XZXct1fOhDBuvgLL0KMpGoHRtj9w
+AAAEAurE2/d7VhoEJeNFdDnVS7lpBRoMe/zAjA8dJRP1Z/I+wQEJfmMHCCCSm3hdldy3V8
+6EMG6+AsvQoykagdG2P3AAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca2.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca2.pub
new file mode 100644
index 0000000000..a177fd0f24
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-ca2.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOwQEJfmMHCCCSm3hdldy3V86EMG6+AsvQoykagdG2P3
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-hash b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-hash
new file mode 100644
index 0000000000..c6f2361ffd
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-hash
@@ -0,0 +1,11 @@
+hash: SHA256:RvNFBEc/N9jsm3toDkitgr/wnWu/6qWBHo4Xmh5ZUpM
+hash: SHA256:qu2IwCnItWWX+orXv0rjCeT4i++2O6ViTzLye6kyWzU
+hash: SHA256:qQTACAkAJxYk1zvSQ+Rx9wa2IuOFJKtaEy/XwxM89J0
+hash: SHA256:Fe4GdmipzulS9oMB/h3U69tSm5wil6bTUKSJCT+Jf3E
+hash: SHA256:esUK/whZ5oJeRFNeOrHK1bbx9dKC+nRITZ7up7HJaGA
+hash: SHA256:xkii+r6t9rEBFYkx1b3dGNXzEs69M5NUMfHP05ypSdI
+hash: SHA256:lZrSycKcBNvUafU9y4R0EEbDaQWqMFvIGM9M+VKt2zk
+hash: SHA256:/2bgZOiYEH2UVahUllNaQ5P0advEB7liCPkp+aNVKDk
+hash: SHA256:He3c0W5o/P1I0pK5/VusqD5V6duAMeZl6f+6Yy5P1z0
+hash: SHA256:5V5Xw2lgcAGR8dO9cbgRmCNlhcCsBBv/hmEstKsqKr4
+hash: SHA256:T7s26JPzzRP2WHOcw3OjLwWo8ZZTkfo2jBCrRfJ6BR4
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-keyid b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-keyid
new file mode 100644
index 0000000000..592ddb4e78
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-keyid
@@ -0,0 +1,512 @@
+id: revoked 1
+id: revoked 2
+id: revoked 3
+id: revoked 4
+id: revoked 10
+id: revoked 15
+id: revoked 30
+id: revoked 50
+id: revoked 90
+id: revoked 300
+id: revoked 301
+id: revoked 302
+id: revoked 303
+id: revoked 304
+id: revoked 305
+id: revoked 306
+id: revoked 307
+id: revoked 308
+id: revoked 309
+id: revoked 310
+id: revoked 311
+id: revoked 312
+id: revoked 313
+id: revoked 314
+id: revoked 315
+id: revoked 316
+id: revoked 317
+id: revoked 318
+id: revoked 319
+id: revoked 320
+id: revoked 321
+id: revoked 322
+id: revoked 323
+id: revoked 324
+id: revoked 325
+id: revoked 326
+id: revoked 327
+id: revoked 328
+id: revoked 329
+id: revoked 330
+id: revoked 331
+id: revoked 332
+id: revoked 333
+id: revoked 334
+id: revoked 335
+id: revoked 336
+id: revoked 337
+id: revoked 338
+id: revoked 339
+id: revoked 340
+id: revoked 341
+id: revoked 342
+id: revoked 343
+id: revoked 344
+id: revoked 345
+id: revoked 346
+id: revoked 347
+id: revoked 348
+id: revoked 349
+id: revoked 350
+id: revoked 351
+id: revoked 352
+id: revoked 353
+id: revoked 354
+id: revoked 355
+id: revoked 356
+id: revoked 357
+id: revoked 358
+id: revoked 359
+id: revoked 360
+id: revoked 361
+id: revoked 362
+id: revoked 363
+id: revoked 364
+id: revoked 365
+id: revoked 366
+id: revoked 367
+id: revoked 368
+id: revoked 369
+id: revoked 370
+id: revoked 371
+id: revoked 372
+id: revoked 373
+id: revoked 374
+id: revoked 375
+id: revoked 376
+id: revoked 377
+id: revoked 378
+id: revoked 379
+id: revoked 380
+id: revoked 381
+id: revoked 382
+id: revoked 383
+id: revoked 384
+id: revoked 385
+id: revoked 386
+id: revoked 387
+id: revoked 388
+id: revoked 389
+id: revoked 390
+id: revoked 391
+id: revoked 392
+id: revoked 393
+id: revoked 394
+id: revoked 395
+id: revoked 396
+id: revoked 397
+id: revoked 398
+id: revoked 399
+id: revoked 400
+id: revoked 401
+id: revoked 402
+id: revoked 403
+id: revoked 404
+id: revoked 405
+id: revoked 406
+id: revoked 407
+id: revoked 408
+id: revoked 409
+id: revoked 410
+id: revoked 411
+id: revoked 412
+id: revoked 413
+id: revoked 414
+id: revoked 415
+id: revoked 416
+id: revoked 417
+id: revoked 418
+id: revoked 419
+id: revoked 420
+id: revoked 421
+id: revoked 422
+id: revoked 423
+id: revoked 424
+id: revoked 425
+id: revoked 426
+id: revoked 427
+id: revoked 428
+id: revoked 429
+id: revoked 430
+id: revoked 431
+id: revoked 432
+id: revoked 433
+id: revoked 434
+id: revoked 435
+id: revoked 436
+id: revoked 437
+id: revoked 438
+id: revoked 439
+id: revoked 440
+id: revoked 441
+id: revoked 442
+id: revoked 443
+id: revoked 444
+id: revoked 445
+id: revoked 446
+id: revoked 447
+id: revoked 448
+id: revoked 449
+id: revoked 450
+id: revoked 451
+id: revoked 452
+id: revoked 453
+id: revoked 454
+id: revoked 455
+id: revoked 456
+id: revoked 457
+id: revoked 458
+id: revoked 459
+id: revoked 460
+id: revoked 461
+id: revoked 462
+id: revoked 463
+id: revoked 464
+id: revoked 465
+id: revoked 466
+id: revoked 467
+id: revoked 468
+id: revoked 469
+id: revoked 470
+id: revoked 471
+id: revoked 472
+id: revoked 473
+id: revoked 474
+id: revoked 475
+id: revoked 476
+id: revoked 477
+id: revoked 478
+id: revoked 479
+id: revoked 480
+id: revoked 481
+id: revoked 482
+id: revoked 483
+id: revoked 484
+id: revoked 485
+id: revoked 486
+id: revoked 487
+id: revoked 488
+id: revoked 489
+id: revoked 490
+id: revoked 491
+id: revoked 492
+id: revoked 493
+id: revoked 494
+id: revoked 495
+id: revoked 496
+id: revoked 497
+id: revoked 498
+id: revoked 500
+id: revoked 501
+id: revoked 502
+id: revoked 503
+id: revoked 504
+id: revoked 505
+id: revoked 506
+id: revoked 507
+id: revoked 508
+id: revoked 509
+id: revoked 510
+id: revoked 511
+id: revoked 512
+id: revoked 513
+id: revoked 514
+id: revoked 515
+id: revoked 516
+id: revoked 517
+id: revoked 518
+id: revoked 519
+id: revoked 520
+id: revoked 521
+id: revoked 522
+id: revoked 523
+id: revoked 524
+id: revoked 525
+id: revoked 526
+id: revoked 527
+id: revoked 528
+id: revoked 529
+id: revoked 530
+id: revoked 531
+id: revoked 532
+id: revoked 533
+id: revoked 534
+id: revoked 535
+id: revoked 536
+id: revoked 537
+id: revoked 538
+id: revoked 539
+id: revoked 540
+id: revoked 541
+id: revoked 542
+id: revoked 543
+id: revoked 544
+id: revoked 545
+id: revoked 546
+id: revoked 547
+id: revoked 548
+id: revoked 549
+id: revoked 550
+id: revoked 551
+id: revoked 552
+id: revoked 553
+id: revoked 554
+id: revoked 555
+id: revoked 556
+id: revoked 557
+id: revoked 558
+id: revoked 559
+id: revoked 560
+id: revoked 561
+id: revoked 562
+id: revoked 563
+id: revoked 564
+id: revoked 565
+id: revoked 566
+id: revoked 567
+id: revoked 568
+id: revoked 569
+id: revoked 570
+id: revoked 571
+id: revoked 572
+id: revoked 573
+id: revoked 574
+id: revoked 575
+id: revoked 576
+id: revoked 577
+id: revoked 578
+id: revoked 579
+id: revoked 580
+id: revoked 581
+id: revoked 582
+id: revoked 583
+id: revoked 584
+id: revoked 585
+id: revoked 586
+id: revoked 587
+id: revoked 588
+id: revoked 589
+id: revoked 590
+id: revoked 591
+id: revoked 592
+id: revoked 593
+id: revoked 594
+id: revoked 595
+id: revoked 596
+id: revoked 597
+id: revoked 598
+id: revoked 599
+id: revoked 600
+id: revoked 601
+id: revoked 602
+id: revoked 603
+id: revoked 604
+id: revoked 605
+id: revoked 606
+id: revoked 607
+id: revoked 608
+id: revoked 609
+id: revoked 610
+id: revoked 611
+id: revoked 612
+id: revoked 613
+id: revoked 614
+id: revoked 615
+id: revoked 616
+id: revoked 617
+id: revoked 618
+id: revoked 619
+id: revoked 620
+id: revoked 621
+id: revoked 622
+id: revoked 623
+id: revoked 624
+id: revoked 625
+id: revoked 626
+id: revoked 627
+id: revoked 628
+id: revoked 629
+id: revoked 630
+id: revoked 631
+id: revoked 632
+id: revoked 633
+id: revoked 634
+id: revoked 635
+id: revoked 636
+id: revoked 637
+id: revoked 638
+id: revoked 639
+id: revoked 640
+id: revoked 641
+id: revoked 642
+id: revoked 643
+id: revoked 644
+id: revoked 645
+id: revoked 646
+id: revoked 647
+id: revoked 648
+id: revoked 649
+id: revoked 650
+id: revoked 651
+id: revoked 652
+id: revoked 653
+id: revoked 654
+id: revoked 655
+id: revoked 656
+id: revoked 657
+id: revoked 658
+id: revoked 659
+id: revoked 660
+id: revoked 661
+id: revoked 662
+id: revoked 663
+id: revoked 664
+id: revoked 665
+id: revoked 666
+id: revoked 667
+id: revoked 668
+id: revoked 669
+id: revoked 670
+id: revoked 671
+id: revoked 672
+id: revoked 673
+id: revoked 674
+id: revoked 675
+id: revoked 676
+id: revoked 677
+id: revoked 678
+id: revoked 679
+id: revoked 680
+id: revoked 681
+id: revoked 682
+id: revoked 683
+id: revoked 684
+id: revoked 685
+id: revoked 686
+id: revoked 687
+id: revoked 688
+id: revoked 689
+id: revoked 690
+id: revoked 691
+id: revoked 692
+id: revoked 693
+id: revoked 694
+id: revoked 695
+id: revoked 696
+id: revoked 697
+id: revoked 698
+id: revoked 699
+id: revoked 700
+id: revoked 701
+id: revoked 702
+id: revoked 703
+id: revoked 704
+id: revoked 705
+id: revoked 706
+id: revoked 707
+id: revoked 708
+id: revoked 709
+id: revoked 710
+id: revoked 711
+id: revoked 712
+id: revoked 713
+id: revoked 714
+id: revoked 715
+id: revoked 716
+id: revoked 717
+id: revoked 718
+id: revoked 719
+id: revoked 720
+id: revoked 721
+id: revoked 722
+id: revoked 723
+id: revoked 724
+id: revoked 725
+id: revoked 726
+id: revoked 727
+id: revoked 728
+id: revoked 729
+id: revoked 730
+id: revoked 731
+id: revoked 732
+id: revoked 733
+id: revoked 734
+id: revoked 735
+id: revoked 736
+id: revoked 737
+id: revoked 738
+id: revoked 739
+id: revoked 740
+id: revoked 741
+id: revoked 742
+id: revoked 743
+id: revoked 744
+id: revoked 745
+id: revoked 746
+id: revoked 747
+id: revoked 748
+id: revoked 749
+id: revoked 750
+id: revoked 751
+id: revoked 752
+id: revoked 753
+id: revoked 754
+id: revoked 755
+id: revoked 756
+id: revoked 757
+id: revoked 758
+id: revoked 759
+id: revoked 760
+id: revoked 761
+id: revoked 762
+id: revoked 763
+id: revoked 764
+id: revoked 765
+id: revoked 766
+id: revoked 767
+id: revoked 768
+id: revoked 769
+id: revoked 770
+id: revoked 771
+id: revoked 772
+id: revoked 773
+id: revoked 774
+id: revoked 775
+id: revoked 776
+id: revoked 777
+id: revoked 778
+id: revoked 779
+id: revoked 780
+id: revoked 781
+id: revoked 782
+id: revoked 783
+id: revoked 784
+id: revoked 785
+id: revoked 786
+id: revoked 787
+id: revoked 788
+id: revoked 789
+id: revoked 790
+id: revoked 791
+id: revoked 792
+id: revoked 793
+id: revoked 794
+id: revoked 795
+id: revoked 796
+id: revoked 797
+id: revoked 798
+id: revoked 799
+id: revoked 999
+id: revoked 1000
+id: revoked 1001
+id: revoked 1002
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-serials b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-serials
new file mode 100644
index 0000000000..b20fec292d
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-serials
@@ -0,0 +1,19 @@
+serial: 1-4
+serial: 10
+serial: 15
+serial: 30
+serial: 50
+serial: 90
+serial: 999
+# The following sum to 500-799
+serial: 500
+serial: 501
+serial: 502
+serial: 503-600
+serial: 700-797
+serial: 798
+serial: 799
+serial: 599-701
+# Some multiple consecutive serial number ranges
+serial: 10000-20000
+serial: 30000-40000
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-sha1 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-sha1
new file mode 100644
index 0000000000..475e90cb1c
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-sha1
@@ -0,0 +1,11 @@
+sha1: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC29QZ72HtyCdaNo6p2GH3fJpUynwkvs8Acwn66G7YTh
+sha1: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0ZC4fqgbBgROeX1sOEPr4uMVNfPdJ62bVo/zvSMRQx
+sha1: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG5IH9T7FY47VJDUoyOlB/iqCN4pO8dgOrxclmKN5R5w
+sha1: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINjhG4+EnQy8YHLsfE8+IQwNWZVn1GBYX75pwxBCZGmy
+sha1: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJXm+qgTs+sO+9zvoZBxkQD39R2rQqQCVezxQoGjKui5
+sha1: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL8+aQKja+SbqxfWR61FCcsbBw2jaF/KHvcqdP2Fbp6Q
+sha1: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAOL7IULalT2Izo9TgRf1t2HNpZ5WCZJH5oRCd9LK3BN
+sha1: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGVaSedhPkl2Hrx1nOOKT2E52ADsBebawws87NN1+P6e
+sha1: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICxyaxj7pRVDeh/gxJem9BLhoUQKGnKXHfDrB/GtC1KB
+sha1: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID96GKtj4wN+OwvrQsgP37fQVUXThCML796qqFNLVDCA
+sha1: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEh3BFcTzXmg1Fi5LvWiUDWORsHzVhUCm8ekrEJG6+6A
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-sha256 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-sha256
new file mode 100644
index 0000000000..13109e9049
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/revoked-sha256
@@ -0,0 +1,11 @@
+sha256: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC29QZ72HtyCdaNo6p2GH3fJpUynwkvs8Acwn66G7YTh
+sha256: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0ZC4fqgbBgROeX1sOEPr4uMVNfPdJ62bVo/zvSMRQx
+sha256: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG5IH9T7FY47VJDUoyOlB/iqCN4pO8dgOrxclmKN5R5w
+sha256: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINjhG4+EnQy8YHLsfE8+IQwNWZVn1GBYX75pwxBCZGmy
+sha256: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJXm+qgTs+sO+9zvoZBxkQD39R2rQqQCVezxQoGjKui5
+sha256: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL8+aQKja+SbqxfWR61FCcsbBw2jaF/KHvcqdP2Fbp6Q
+sha256: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAOL7IULalT2Izo9TgRf1t2HNpZ5WCZJH5oRCd9LK3BN
+sha256: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGVaSedhPkl2Hrx1nOOKT2E52ADsBebawws87NN1+P6e
+sha256: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICxyaxj7pRVDeh/gxJem9BLhoUQKGnKXHfDrB/GtC1KB
+sha256: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID96GKtj4wN+OwvrQsgP37fQVUXThCML796qqFNLVDCA
+sha256: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEh3BFcTzXmg1Fi5LvWiUDWORsHzVhUCm8ekrEJG6+6A
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0005 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0005
new file mode 100644
index 0000000000..d82a0b5d3c
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0005
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACDqONQediveIXoseoT+MWp9yEdMO7hP7F4fAno6gunyoAAAAIig1MZroNTG
+awAAAAtzc2gtZWQyNTUxOQAAACDqONQediveIXoseoT+MWp9yEdMO7hP7F4fAno6gunyoA
+AAAEBSEPLoX4NVkAchYZEGi7hjd5NoVBWuoxqluCGt/fWrYeo41B52K94heix6hP4xan3I
+R0w7uE/sXh8CejqC6fKgAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0005-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0005-cert.pub
new file mode 100644
index 0000000000..59ea422c2a
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0005-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIGnzDhP/hp83ipkW8T7f0CIXJuPK7ldbJFKDUrkvn6J1AAAAIOo41B52K94heix6hP4xan3IR0w7uE/sXh8CejqC6fKgAAAAAAAAAAUAAAABAAAACXJldm9rZWQgNQAAAAAAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgFtF5l68spzOFrIpQANF0C9nkNdXMAmlCRwHgw91C784AAABTAAAAC3NzaC1lZDI1NTE5AAAAQO9W58IrK+I0o2us9Hs/QBkrEe1YIgl6PzCMsu/Zu/tdZxGDK5Pxoz7tKzXezS9LPGQfZ3fVdl58PZC1DtxQ5gU= ./tst-keys/unrevoked-0005.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0005.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0005.pub
new file mode 100644
index 0000000000..081ac6c63a
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0005.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOo41B52K94heix6hP4xan3IR0w7uE/sXh8CejqC6fKg
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0009 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0009
new file mode 100644
index 0000000000..947949847c
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0009
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACDXQqTeALQCMo64B4EX5abjRvrjVu69Mnxgg2q0SB5/oQAAAIgIqeXLCKnl
+ywAAAAtzc2gtZWQyNTUxOQAAACDXQqTeALQCMo64B4EX5abjRvrjVu69Mnxgg2q0SB5/oQ
+AAAECubGChJGu90ZNiP/zF+tTtr0+l7y8BrTDMQ0m0+cU0qtdCpN4AtAIyjrgHgRflpuNG
++uNW7r0yfGCDarRIHn+hAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0009-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0009-cert.pub
new file mode 100644
index 0000000000..9ee889075b
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0009-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIERRY0M1bHm2Qjyo105OCHWp0UCRHLP0xkMuHnkMDP5eAAAAINdCpN4AtAIyjrgHgRflpuNG+uNW7r0yfGCDarRIHn+hAAAAAAAAAAkAAAABAAAACXJldm9rZWQgOQAAAAAAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgFtF5l68spzOFrIpQANF0C9nkNdXMAmlCRwHgw91C784AAABTAAAAC3NzaC1lZDI1NTE5AAAAQFsA4xJHRCXSyq6GHkKdemfbg+jvUZxHlu/UBoZf4esEHAtx0mXiajbUwkWzkh1vCtxZNZhiLIhxqDcNMu+O+wo= ./tst-keys/unrevoked-0009.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0009.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0009.pub
new file mode 100644
index 0000000000..74a797b960
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0009.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINdCpN4AtAIyjrgHgRflpuNG+uNW7r0yfGCDarRIHn+h
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0014 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0014
new file mode 100644
index 0000000000..6fa4fd93bd
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0014
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACDvTTMHyjozzZabuUzy61XOKBm4klUjUGSWYtX6T4XtEwAAAIhyFdxYchXc
+WAAAAAtzc2gtZWQyNTUxOQAAACDvTTMHyjozzZabuUzy61XOKBm4klUjUGSWYtX6T4XtEw
+AAAEBtC+f4bz1/qtq5K2Rf+0bPeY3P0OWdD3rvrlGPh8wN5u9NMwfKOjPNlpu5TPLrVc4o
+GbiSVSNQZJZi1fpPhe0TAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0014-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0014-cert.pub
new file mode 100644
index 0000000000..bb954f9337
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0014-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIPes2n/Xk4mm4OpuvHDqx9+76vm+SmFgc9d7ATGT1+C8AAAAIO9NMwfKOjPNlpu5TPLrVc4oGbiSVSNQZJZi1fpPhe0TAAAAAAAAAA4AAAABAAAACnJldm9rZWQgMTQAAAAAAAAAAAAAAAD//////////wAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIBbReZevLKczhayKUADRdAvZ5DXVzAJpQkcB4MPdQu/OAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEDGVORypw3DoMuWBu0V4cH/OgRBstD5cY37CfLrVZpmGv9jDRXVNQee7vYowk0r3XvQPoUecQBIMZGAQtEiw18E ./tst-keys/unrevoked-0014.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0014.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0014.pub
new file mode 100644
index 0000000000..4a866e41b8
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0014.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO9NMwfKOjPNlpu5TPLrVc4oGbiSVSNQZJZi1fpPhe0T
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0016 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0016
new file mode 100644
index 0000000000..62d5027eff
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0016
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACBWKMDlSwSGo4dcBAZmL+Xxk64Wp/ZfFSu2vkp82JXQCQAAAIjUcNt51HDb
+eQAAAAtzc2gtZWQyNTUxOQAAACBWKMDlSwSGo4dcBAZmL+Xxk64Wp/ZfFSu2vkp82JXQCQ
+AAAEC1V7PD5tJSOUZtpfqVfWyiSIMJkCDFZzTmFs7GBpJE71YowOVLBIajh1wEBmYv5fGT
+rhan9l8VK7a+SnzYldAJAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0016-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0016-cert.pub
new file mode 100644
index 0000000000..367e4ab70a
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0016-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAICGqa0xwr0etbKquuBy5/hYQ/rbMrKfEE6XShgb4YWpUAAAAIFYowOVLBIajh1wEBmYv5fGTrhan9l8VK7a+SnzYldAJAAAAAAAAABAAAAABAAAACnJldm9rZWQgMTYAAAAAAAAAAAAAAAD//////////wAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIBbReZevLKczhayKUADRdAvZ5DXVzAJpQkcB4MPdQu/OAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEBKVetE3dsch2wjMIHGoiH8zp6gFMn1KgGKn01EPc1A08a/JKNvaSDYhlARLjiBzjIUGlykhHTTr4EcHTPWl58P ./tst-keys/unrevoked-0016.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0016.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0016.pub
new file mode 100644
index 0000000000..47cac1e76c
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0016.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFYowOVLBIajh1wEBmYv5fGTrhan9l8VK7a+SnzYldAJ
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0029 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0029
new file mode 100644
index 0000000000..589daa6afe
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0029
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACA3B1NQ9RFEkJUGcIUcCL22yMVEeob8/PUsk9lYH43vPwAAAIjxPrzV8T68
+1QAAAAtzc2gtZWQyNTUxOQAAACA3B1NQ9RFEkJUGcIUcCL22yMVEeob8/PUsk9lYH43vPw
+AAAED89ht9KdlYRfsKwh+pzh6BOvPf/U58QBkw1d3LfKnn+jcHU1D1EUSQlQZwhRwIvbbI
+xUR6hvz89SyT2Vgfje8/AAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0029-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0029-cert.pub
new file mode 100644
index 0000000000..1bf3883ce0
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0029-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIEVLRuchC4z7/EqITmyqCxOyhC7/enmFWsalP8FFFYiXAAAAIDcHU1D1EUSQlQZwhRwIvbbIxUR6hvz89SyT2Vgfje8/AAAAAAAAAB0AAAABAAAACnJldm9rZWQgMjkAAAAAAAAAAAAAAAD//////////wAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIBbReZevLKczhayKUADRdAvZ5DXVzAJpQkcB4MPdQu/OAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEChRFz/Zb6b3znoIWJjd8OTmCIEH7YE/fKWtyWHoGjz02G4VnCfwuHp23yD+k1XsoOGC7xcSnQeqZ19160HDNgC ./tst-keys/unrevoked-0029.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0029.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0029.pub
new file mode 100644
index 0000000000..4072d920bd
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0029.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDcHU1D1EUSQlQZwhRwIvbbIxUR6hvz89SyT2Vgfje8/
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0049 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0049
new file mode 100644
index 0000000000..b5788a0b5e
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0049
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACD2mB5GBuavtb/bX7W54OmUCCJzUWBwG7cQ4q/jon1MBQAAAIjRkEU40ZBF
+OAAAAAtzc2gtZWQyNTUxOQAAACD2mB5GBuavtb/bX7W54OmUCCJzUWBwG7cQ4q/jon1MBQ
+AAAECuUtJb+T0um2mGvjD/ZZpbtjIhWc3jGVbzuDnEovOjnPaYHkYG5q+1v9tftbng6ZQI
+InNRYHAbtxDir+OifUwFAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0049-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0049-cert.pub
new file mode 100644
index 0000000000..587cf6220b
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0049-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAILZPLEL5xQ8HDLa8pJhchJ3EEhZcjMqACCAEeL+U6c/QAAAAIPaYHkYG5q+1v9tftbng6ZQIInNRYHAbtxDir+OifUwFAAAAAAAAADEAAAABAAAACnJldm9rZWQgNDkAAAAAAAAAAAAAAAD//////////wAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIBbReZevLKczhayKUADRdAvZ5DXVzAJpQkcB4MPdQu/OAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEB2GglzoC1VgsYNAVd5BDsLbeR5M5hHcVVvNsGnK1QCXMj56cgfkbXLj6W6tjJEEFY4G+KPJh1F/SGJi02P5lkJ ./tst-keys/unrevoked-0049.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0049.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0049.pub
new file mode 100644
index 0000000000..07d5369090
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0049.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPaYHkYG5q+1v9tftbng6ZQIInNRYHAbtxDir+OifUwF
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0051 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0051
new file mode 100644
index 0000000000..52d3283a79
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0051
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACD39ygfAlHPhZWU8inWu1hypIlQTChQxSKKB6iaV6Q0lQAAAIgMawsqDGsL
+KgAAAAtzc2gtZWQyNTUxOQAAACD39ygfAlHPhZWU8inWu1hypIlQTChQxSKKB6iaV6Q0lQ
+AAAEB4Ng9MekhsMKYDaBcOUWdxmi1rjgCsPOOfpABTxiCef/f3KB8CUc+FlZTyKda7WHKk
+iVBMKFDFIooHqJpXpDSVAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0051-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0051-cert.pub
new file mode 100644
index 0000000000..5b4bd11247
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0051-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIGTNYRrlJ1vExK7dume319Krn4YW6wyZc4PzZLjZoB8zAAAAIPf3KB8CUc+FlZTyKda7WHKkiVBMKFDFIooHqJpXpDSVAAAAAAAAADMAAAABAAAACnJldm9rZWQgNTEAAAAAAAAAAAAAAAD//////////wAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIBbReZevLKczhayKUADRdAvZ5DXVzAJpQkcB4MPdQu/OAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEAgUiwWKerMo8nuejTER/EmM6ZUpmXjgFwPCpb1LAxBJH71iOnyF9S0gp+CSmjqiTS2yuQajSMen64wOdJCX7wF ./tst-keys/unrevoked-0051.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0051.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0051.pub
new file mode 100644
index 0000000000..88867e58da
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0051.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPf3KB8CUc+FlZTyKda7WHKkiVBMKFDFIooHqJpXpDSV
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0499 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0499
new file mode 100644
index 0000000000..8f59be9e5d
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0499
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACCpwI1aCbAOVvA7NJhLtBNpR4tiGGtTQ019wjKL6zJ/uQAAAIhllrzrZZa8
+6wAAAAtzc2gtZWQyNTUxOQAAACCpwI1aCbAOVvA7NJhLtBNpR4tiGGtTQ019wjKL6zJ/uQ
+AAAECQ6o+3J9W3wXFWEcrPJl5qJZudUPmPdKF7SYxcMTrVP6nAjVoJsA5W8Ds0mEu0E2lH
+i2IYa1NDTX3CMovrMn+5AAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0499-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0499-cert.pub
new file mode 100644
index 0000000000..a6e76f12f7
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0499-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIJvt1IxZsGIIS9DDCCKiD13Dbs5Af5ouews+YwZ9FoydAAAAIKnAjVoJsA5W8Ds0mEu0E2lHi2IYa1NDTX3CMovrMn+5AAAAAAAAAfMAAAABAAAAC3Jldm9rZWQgNDk5AAAAAAAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAW0XmXryynM4WsilAA0XQL2eQ11cwCaUJHAeDD3ULvzgAAAFMAAAALc3NoLWVkMjU1MTkAAABAMaA4UjND4LX9kdHjhgWJjGzzs/xUBwxQQcAmNgwmmQzmkwj8ctWBBA1+TkBMcZbSNUWBdclT4UcnDPEYqG1NBg== ./tst-keys/unrevoked-0499.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0499.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0499.pub
new file mode 100644
index 0000000000..5a3acbb245
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0499.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKnAjVoJsA5W8Ds0mEu0E2lHi2IYa1NDTX3CMovrMn+5
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0800 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0800
new file mode 100644
index 0000000000..9684d727f5
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0800
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACAn5h8A2vYJ1+IWVtdLMulUQKCqlVLHpcHEFqYC5gtGlwAAAIh2lf7UdpX+
+1AAAAAtzc2gtZWQyNTUxOQAAACAn5h8A2vYJ1+IWVtdLMulUQKCqlVLHpcHEFqYC5gtGlw
+AAAEAEXGgMPKs3HwkQmNdVkbO3PcaBVCBEv1l8yy/ly30jPSfmHwDa9gnX4hZW10sy6VRA
+oKqVUselwcQWpgLmC0aXAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0800-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0800-cert.pub
new file mode 100644
index 0000000000..ab47a2bcf4
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0800-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIPAKFTJ25v9CsCppsQ/FwXAZgntAIdQHUXo0KQ3FrlTzAAAAICfmHwDa9gnX4hZW10sy6VRAoKqVUselwcQWpgLmC0aXAAAAAAAAAyAAAAABAAAAC3Jldm9rZWQgODAwAAAAAAAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAW0XmXryynM4WsilAA0XQL2eQ11cwCaUJHAeDD3ULvzgAAAFMAAAALc3NoLWVkMjU1MTkAAABA16aKfsgD0iZ+qc2b1AxBHZ/nyczN2Xjbhg4eJm/6cPSkBHs8uan5e8yPBIQJq2LztC3If6Z6PARoWUnIKb43CQ== ./tst-keys/unrevoked-0800.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0800.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0800.pub
new file mode 100644
index 0000000000..3a41f29a84
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-0800.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICfmHwDa9gnX4hZW10sy6VRAoKqVUselwcQWpgLmC0aX
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1010 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1010
new file mode 100644
index 0000000000..89df71745a
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1010
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACAg0jawQzRMO/ESfFm6yDc66J5kjasOqTb7rmQSU6Nk3QAAAIhczXMoXM1z
+KAAAAAtzc2gtZWQyNTUxOQAAACAg0jawQzRMO/ESfFm6yDc66J5kjasOqTb7rmQSU6Nk3Q
+AAAEAdeQiqpyZqBaffmgy+UrvFVpygD0n8isn3zjumVNtKxiDSNrBDNEw78RJ8WbrINzro
+nmSNqw6pNvuuZBJTo2TdAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1010-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1010-cert.pub
new file mode 100644
index 0000000000..2d0fe53663
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1010-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIITg9nSjjofIKXTKf2byvYL3Ce43PP9Dtrbj/+AlfgEtAAAAICDSNrBDNEw78RJ8WbrINzronmSNqw6pNvuuZBJTo2TdAAAAAAAAA/IAAAABAAAADHJldm9rZWQgMTAxMAAAAAAAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgFtF5l68spzOFrIpQANF0C9nkNdXMAmlCRwHgw91C784AAABTAAAAC3NzaC1lZDI1NTE5AAAAQIndHhKILtU0+FkKKw1KmhaHQS3p1KiQdld/2P5jpcEgb292iY+ICU+aHXKvS8qGM2aMImv8835NEyWy/MB74QM= ./tst-keys/unrevoked-1010.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1010.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1010.pub
new file mode 100644
index 0000000000..05c5eac539
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1010.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICDSNrBDNEw78RJ8WbrINzronmSNqw6pNvuuZBJTo2Td
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1011 b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1011
new file mode 100644
index 0000000000..38b823270e
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1011
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACCd4IBQx9BhO9FzYMOKu3cKgBcwUwb7XzS3uI26RgmEYgAAAIjHvhtux74b
+bgAAAAtzc2gtZWQyNTUxOQAAACCd4IBQx9BhO9FzYMOKu3cKgBcwUwb7XzS3uI26RgmEYg
+AAAEBsteyDUYUNwgY3SMkMs0guy8MJfek2kuvH35zEpVf6Hp3ggFDH0GE70XNgw4q7dwqA
+FzBTBvtfNLe4jbpGCYRiAAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1011-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1011-cert.pub
new file mode 100644
index 0000000000..46716383ce
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1011-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIMjD2+xjmUC1VviOH+peT9C81Y4xjyTue/F69nFKmQBMAAAAIJ3ggFDH0GE70XNgw4q7dwqAFzBTBvtfNLe4jbpGCYRiAAAAAAAAA/MAAAABAAAADHJldm9rZWQgMTAxMQAAAAAAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgFtF5l68spzOFrIpQANF0C9nkNdXMAmlCRwHgw91C784AAABTAAAAC3NzaC1lZDI1NTE5AAAAQNENdVFCE02X6z+wFJtm2DQcgdc4oov9DyFKLPqLrogo+pVao5QwOkeJ2J/tmp40H2+uP/jrDlQuCvOcoQGHqwY= ./tst-keys/unrevoked-1011.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1011.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1011.pub
new file mode 100644
index 0000000000..080907734c
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/unrevoked-1011.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ3ggFDH0GE70XNgw4q7dwqAFzBTBvtfNLe4jbpGCYRi
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/other_key b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/other_key
new file mode 100644
index 0000000000..ee3f922c2f
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/other_key
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACA3ivU7wf37jE1ITC5KQjVeVlyFTkgWJxub8t380ovjiwAAAJDdMhQO3TIU
+DgAAAAtzc2gtZWQyNTUxOQAAACA3ivU7wf37jE1ITC5KQjVeVlyFTkgWJxub8t380ovjiw
+AAAEA4NlTFs3h2zqt5pSZ5S3dJb42GE7EjG16coKj70eELNDeK9TvB/fuMTUhMLkpCNV5W
+XIVOSBYnG5vy3fzSi+OLAAAADVRIV09AU0VBR044MDA=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/other_key-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/other_key-cert.pub
new file mode 100644
index 0000000000..2be08be740
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/other_key-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIGXo4+L/NyBl1VQDP39PxJP3LSzaqopqZGVP3cG0WoFAAAAAIDeK9TvB/fuMTUhMLkpCNV5WXIVOSBYnG5vy3fzSi+OLAAAAAAAAAAUAAAABAAAABnRlc3RlcgAAABYAAAASdGVzdGVyQGV4YW1wbGUuY29tAAAAAGbTroAAAAAAZyLIgAAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIMdEl+iOTEbf1RC3uicECtid+SaIMsAw7wrlWhOQTyBVAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEA/HwKB8J/kvkEsdxDou+UebnR9u30xPH6FEnbHLlfKbKMIXwLFIHnf9F6bTL36WhFDEDcSBGS19VBWBDRosM8L
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/other_key.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/other_key.pub
new file mode 100644
index 0000000000..0255005400
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/other_key.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDeK9TvB/fuMTUhMLkpCNV5WXIVOSBYnG5vy3fzSi+OL
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/repo.bundle b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/repo.bundle
new file mode 100644
index 0000000000..c402f549cf
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/repo.bundle
Binary files differ
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/signing_key b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/signing_key
new file mode 100644
index 0000000000..3dd37be6b2
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/signing_key
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACBgEzmfD3DinWPe/H8yLLZ2dPhbnnyFiqe8EWcp0C3czgAAAJDhSMqA4UjK
+gAAAAAtzc2gtZWQyNTUxOQAAACBgEzmfD3DinWPe/H8yLLZ2dPhbnnyFiqe8EWcp0C3czg
+AAAEB1yC00NMYEAVzhDj9odGVL0EonaIkf5jdUZ/czJ0+SPWATOZ8PcOKdY978fzIstnZ0
++FuefIWKp7wRZynQLdzOAAAADVRIV09AU0VBR044MDA=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/signing_key-cert.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/signing_key-cert.pub
new file mode 100644
index 0000000000..de191d1870
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/signing_key-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIFEmoWkYraMju0JI0b/0RQtR6RYo/OVp53EVf48L/Pu/AAAAIBmHlkHFlA7HkoTZcau80PH5zduQu41m8BqnH/1v2BwVAAAAAAAAAAEAAAABAAAACGFfa2V5X2lkAAAAFgAAABJ0ZXN0ZXJAZXhhbXBsZS5jb20AAAAAZtOugAAAAABm1QAAAAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAg2ifM9NMuXwQf7H/H5LCMhMjVqugyyN+jmcMoJUL2YLAAAABTAAAAC3NzaC1lZDI1NTE5AAAAQG1kXUido46YOnmwvkJuIAKyp6Q9Gr+lbdOQvU0St/Hc9HTTIxgDGyLpv0alIJpHOuSYUUUxDufvGKtLJK1duwg= ./signing_key.pub
diff --git a/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/signing_key.pub b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/signing_key.pub
new file mode 100644
index 0000000000..e1210e72c0
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/signing_key.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/AbstractSshSignatureTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/AbstractSshSignatureTest.java
new file mode 100644
index 0000000000..fdfffce810
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/AbstractSshSignatureTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2024, Thomas Wolf <twolf@apache.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.signing.ssh;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.time.Instant;
+import java.time.ZoneOffset;
+
+import org.eclipse.jgit.api.CommitCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * Common setup for SSH signature tests.
+ */
+public abstract class AbstractSshSignatureTest extends RepositoryTestCase {
+
+ @Rule
+ public TemporaryFolder keys = new TemporaryFolder();
+
+ protected File certs;
+
+ protected Instant commitTime;
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ copyResource("allowed_signers", keys.getRoot());
+ copyResource("other_key", keys.getRoot());
+ copyResource("other_key.pub", keys.getRoot());
+ copyResource("other_key-cert.pub", keys.getRoot());
+ copyResource("signing_key", keys.getRoot());
+ copyResource("signing_key.pub", keys.getRoot());
+ certs = keys.newFolder("certs");
+ copyResource("certs/expired.cert", certs);
+ copyResource("certs/no_principals.cert", certs);
+ copyResource("certs/other.cert", certs);
+ copyResource("certs/other-ca.cert", certs);
+ copyResource("certs/tester.cert", certs);
+ copyResource("certs/two_principals.cert", certs);
+ Repository repo = db;
+ StoredConfig config = repo.getConfig();
+ config.setString("gpg", null, "format", "ssh");
+ config.setString("gpg", "ssh", "allowedSignersFile",
+ keys.getRoot().toPath().resolve("allowed_signers").toString()
+ .replace('\\', '/'));
+ config.save();
+ // Run all tests with commit times on 2024-10-02T12:00:00Z. The test
+ // certificates are valid from 2024-09-01 to 2024-10-31, except the
+ // "expired" certificate which is valid only on 2024-09-01.
+ commitTime = Instant.parse("2024-10-02T12:00:00.00Z");
+ }
+
+ private void copyResource(String name, File directory) throws IOException {
+ try (InputStream in = this.getClass().getResourceAsStream(name)) {
+ int i = name.lastIndexOf('/');
+ String fileName = i < 0 ? name : name.substring(i + 1);
+ Files.copy(in, directory.toPath().resolve(fileName));
+ }
+ }
+
+ protected RevCommit createSignedCommit(String certificate,
+ String signingKey) throws Exception {
+ Repository repo = db;
+ Path key = keys.getRoot().toPath().resolve(signingKey);
+ if (certificate != null) {
+ Files.copy(certs.toPath().resolve(certificate),
+ keys.getRoot().toPath().resolve(signingKey),
+ StandardCopyOption.REPLACE_EXISTING);
+ }
+ PersonIdent commitAuthor = new PersonIdent("tester",
+ "tester@example.com", commitTime, ZoneOffset.UTC);
+ try (Git git = Git.wrap(repo)) {
+ writeTrashFile("foo.txt", "foo");
+ git.add().addFilepattern("foo.txt").call();
+ CommitCommand commit = git.commit();
+ commit.setAuthor(commitAuthor);
+ commit.setCommitter(commitAuthor);
+ commit.setMessage("Message");
+ commit.setSign(Boolean.TRUE);
+ commit.setSigningKey(key.toAbsolutePath().toString());
+ return commit.call();
+ }
+ }
+
+ protected RevCommit checkSshSignature(RevCommit c) {
+ byte[] sig = c.getRawGpgSignature();
+ assertNotNull(sig);
+ String signature = new String(sig, StandardCharsets.US_ASCII);
+ assertTrue("Not an SSH signature:\n" + signature,
+ signature.startsWith(Constants.SSH_SIGNATURE_PREFIX));
+ return c;
+ }
+}
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/AllowedSignersParseTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/AllowedSignersParseTest.java
new file mode 100644
index 0000000000..84d8179a3d
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/AllowedSignersParseTest.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2024, Thomas Wolf <twolf@apache.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.signing.ssh;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+
+import java.io.StreamCorruptedException;
+import java.time.Instant;
+
+import org.eclipse.jgit.junit.MockSystemReader;
+import org.eclipse.jgit.util.SystemReader;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for the line parsing in {@link AllowedSigners}.
+ */
+public class AllowedSignersParseTest {
+
+ @Before
+ public void setup() {
+ // Uses GMT-03:30 as time zone.
+ SystemReader.setInstance(new MockSystemReader());
+ }
+
+ @After
+ public void tearDown() {
+ SystemReader.setInstance(null);
+ }
+
+ @Test
+ public void testValidDate() {
+ assertEquals(Instant.parse("2024-09-01T00:00:00.00Z"),
+ AllowedSigners.parseDate("20240901Z"));
+ assertEquals(Instant.parse("2024-09-01T01:02:00.00Z"),
+ AllowedSigners.parseDate("202409010102Z"));
+ assertEquals(Instant.parse("2024-09-01T01:02:03.00Z"),
+ AllowedSigners.parseDate("20240901010203Z"));
+ assertEquals(Instant.parse("2024-09-01T03:30:00.00Z"),
+ AllowedSigners.parseDate("20240901"));
+ assertEquals(Instant.parse("2024-09-01T04:32:00.00Z"),
+ AllowedSigners.parseDate("202409010102"));
+ assertEquals(Instant.parse("2024-09-01T04:32:03.00Z"),
+ AllowedSigners.parseDate("20240901010203"));
+ }
+
+ @Test
+ public void testInvalidDate() {
+ assertThrows(Exception.class, () -> AllowedSigners.parseDate("1234"));
+ assertThrows(Exception.class,
+ () -> AllowedSigners.parseDate("09/01/2024"));
+ assertThrows(Exception.class,
+ () -> AllowedSigners.parseDate("2024-09-01"));
+ }
+
+ private void checkValidKey(String expected, String input, int from)
+ throws StreamCorruptedException {
+ assertEquals(expected, AllowedSigners.parsePublicKey(input, from));
+ }
+ @Test
+ public void testValidPublicKey() throws StreamCorruptedException {
+ checkValidKey(
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO",
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO",
+ 0);
+ checkValidKey(
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO",
+ "xyzssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO",
+ 3);
+ checkValidKey(
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO",
+ "xyz ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO abc",
+ 3);
+ checkValidKey(
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO",
+ "xyz\tssh-ed25519 \tAAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO abc",
+ 3);
+ }
+
+ @Test
+ public void testInvalidPublicKey() {
+ assertThrows(Exception.class,
+ () -> AllowedSigners.parsePublicKey(null, 0));
+ assertThrows(Exception.class,
+ () -> AllowedSigners.parsePublicKey("", 0));
+ assertThrows(Exception.class,
+ () -> AllowedSigners.parsePublicKey("foo", 0));
+ assertThrows(Exception.class,
+ () -> AllowedSigners.parsePublicKey("ssh-ed25519 bar", -1));
+ assertThrows(Exception.class,
+ () -> AllowedSigners.parsePublicKey("ssh-ed25519 bar", 12));
+ assertThrows(Exception.class,
+ () -> AllowedSigners.parsePublicKey("ssh-ed25519 bar", 13));
+ assertThrows(Exception.class,
+ () -> AllowedSigners.parsePublicKey("ssh-ed25519 bar", 16));
+ }
+
+ @Test
+ public void testValidDequote() {
+ assertEquals(new AllowedSigners.Dequoted("a\\bc", 4),
+ AllowedSigners.dequote("a\\bc", 0));
+ assertEquals(new AllowedSigners.Dequoted("a\\bc\"", 5),
+ AllowedSigners.dequote("a\\bc\"", 0));
+ assertEquals(new AllowedSigners.Dequoted("a\\b\"c", 5),
+ AllowedSigners.dequote("a\\b\"c", 0));
+ assertEquals(new AllowedSigners.Dequoted("a\\b\"c", 8),
+ AllowedSigners.dequote("\"a\\b\\\"c\"", 0));
+ assertEquals(new AllowedSigners.Dequoted("a\\b\"c", 11),
+ AllowedSigners.dequote("xyz\"a\\b\\\"c\"", 3));
+ assertEquals(new AllowedSigners.Dequoted("abc", 6),
+ AllowedSigners.dequote(" abc def", 3));
+ }
+
+ @Test
+ public void testInvalidDequote() {
+ assertThrows(Exception.class, () -> AllowedSigners.dequote("\"abc", 0));
+ assertThrows(Exception.class,
+ () -> AllowedSigners.dequote("\"abc\\\"", 0));
+ }
+
+ @Test
+ public void testValidLine() throws Exception {
+ assertEquals(new AllowedSigners.AllowedEntry(
+ new String[] { "*@a.com" },
+ true, null, null, null,
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"),
+ AllowedSigners.parseLine(
+ "*@a.com cert-authority ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"));
+ assertEquals(new AllowedSigners.AllowedEntry(
+ new String[] { "*@a.com", "*@b.a.com" },
+ true, null, null, null,
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"),
+ AllowedSigners.parseLine(
+ "*@a.com,*@b.a.com cert-authority ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"));
+ assertEquals(new AllowedSigners.AllowedEntry(
+ new String[] { "foo@a.com" },
+ false, null, null, null,
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"),
+ AllowedSigners.parseLine(
+ "foo@a.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"));
+ assertEquals(new AllowedSigners.AllowedEntry(
+ new String[] { "foo@a.com" },
+ false, new String[] { "foo", "bar" }, null, null,
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"),
+ AllowedSigners.parseLine(
+ "foo@a.com namespaces=\"foo,bar\" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"));
+ assertEquals(new AllowedSigners.AllowedEntry(
+ new String[] { "foo@a.com" },
+ false, null, Instant.parse("2024-09-01T03:30:00.00Z"), null,
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"),
+ AllowedSigners.parseLine(
+ "foo@a.com valid-After=\"20240901\" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"));
+ assertEquals(new AllowedSigners.AllowedEntry(
+ new String[] { "*@a.com", "*@b.a.com" },
+ true, new String[] { "git" },
+ Instant.parse("2024-09-01T03:30:00.00Z"),
+ Instant.parse("2024-09-01T12:00:00.00Z"),
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"),
+ AllowedSigners.parseLine(
+ "*@a.com,*@b.a.com cert-authority namespaces=\"git\" valid-after=\"20240901\" valid-before=\"202409011200Z\" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"));
+ assertEquals(new AllowedSigners.AllowedEntry(
+ new String[] { "foo@a.com" },
+ false, new String[] { "git" },
+ Instant.parse("2024-09-01T03:30:00.00Z"),
+ Instant.parse("2024-09-01T12:00:00.00Z"),
+ "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGxkz2AUld8eitmyIYlVV+Sot4jT3CigyBmvFRff0q4cSsKLx4x2TxGQeKKVueJEawtsUC2GNRV9FxXsTCUGcZU="),
+ AllowedSigners.parseLine(
+ "foo@a.com namespaces=\"git\" valid-after=\"20240901\" valid-before=\"202409011200Z\" ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGxkz2AUld8eitmyIYlVV+Sot4jT3CigyBmvFRff0q4cSsKLx4x2TxGQeKKVueJEawtsUC2GNRV9FxXsTCUGcZU="));
+ }
+
+ @Test
+ public void testInvalidLine() {
+ assertThrows(Exception.class, () -> AllowedSigners.parseLine(
+ "cert-authority ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"));
+ assertThrows(Exception.class, () -> AllowedSigners.parseLine(
+ "namespaces=\"git\" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"));
+ assertThrows(Exception.class, () -> AllowedSigners.parseLine(
+ "valid-after=\"20240901\" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"));
+ assertThrows(Exception.class, () -> AllowedSigners.parseLine(
+ "valid-before=\"20240901\" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"));
+ assertThrows(Exception.class, () -> AllowedSigners.parseLine(
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"));
+ assertThrows(Exception.class, () -> AllowedSigners.parseLine(
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO foo@bar.com"));
+ assertThrows(Exception.class, () -> AllowedSigners.parseLine(
+ "AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"));
+ assertThrows(Exception.class, () -> AllowedSigners.parseLine(
+ "a@a.com namespaces=\"\" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"));
+ assertThrows(Exception.class, () -> AllowedSigners.parseLine(
+ "a@a.com namespaces=\",,,\" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"));
+ assertThrows(Exception.class, () -> AllowedSigners.parseLine(
+ "a@a.com,,b@a.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATOZ8PcOKdY978fzIstnZ0+FuefIWKp7wRZynQLdzO"));
+ }
+
+ @Test
+ public void testSkippedLine() throws Exception {
+ assertNull(AllowedSigners.parseLine(null));
+ assertNull(AllowedSigners.parseLine(""));
+ assertNull(AllowedSigners.parseLine("# Comment"));
+ }
+}
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/OpenSshBinaryKrlLoadTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/OpenSshBinaryKrlLoadTest.java
new file mode 100644
index 0000000000..9f9c3ca303
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/OpenSshBinaryKrlLoadTest.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024, Thomas Wolf <twolf@apache.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.signing.ssh;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+
+import org.junit.Test;
+
+/**
+ * Tests loading an {@link OpenSshBinaryKrl}.
+ */
+public class OpenSshBinaryKrlLoadTest {
+
+ @Test
+ public void testLoad() throws Exception {
+ try (InputStream in = new BufferedInputStream(
+ this.getClass().getResourceAsStream("krl/krl"))) {
+ OpenSshBinaryKrl krl = OpenSshBinaryKrl.load(in, false);
+ assertNotNull(krl);
+ }
+ }
+}
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/OpenSshKrlTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/OpenSshKrlTest.java
new file mode 100644
index 0000000000..2fd7756d10
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/OpenSshKrlTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2024, Thomas Wolf <twolf@apache.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.signing.ssh;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
+import org.apache.sshd.common.config.keys.PublicKeyEntryResolver;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Tests for {@link OpenSshKrl} using binary KRLs.
+ */
+@RunWith(Parameterized.class)
+public class OpenSshKrlTest {
+
+ // The test data was generated using the public domain OpenSSH test script
+ // with some minor modifications (une ed25519 always, generate a "includes
+ // everything KRl, name the unrekoked keys "unrevoked*", generate a plain
+ // text KRL, and don't run the ssh-keygen tests). The original script is
+ // available at
+ // https://github.com/openssh/openssh-portable/blob/67a115e/regress/krl.sh
+
+ private static final String[] KRLS = {
+ "krl-empty", "krl-keys", "krl-all",
+ "krl-sha1", "krl-sha256", "krl-hash",
+ "krl-serial", "krl-keyid", "krl-cert", "krl-ca",
+ "krl-serial-wild", "krl-keyid-wild", "krl-text" };
+
+ private static final int[] REVOKED = { 1, 4, 10, 50, 90, 500, 510, 520, 550,
+ 799, 999 };
+
+ private static final int[] UNREVOKED = { 5, 9, 14, 16, 29, 49, 51, 499, 800,
+ 1010, 1011 };
+
+ private static class TestData {
+
+ String key;
+
+ String krl;
+
+ Boolean expected;
+
+ TestData(String key, String krl, boolean expected) {
+ this.key = key;
+ this.krl = krl;
+ this.expected = Boolean.valueOf(expected);
+ }
+
+ @Override
+ public String toString() {
+ return key + '-' + krl;
+ }
+ }
+
+ @Parameters(name = "{0}")
+ public static List<TestData> initTestData() {
+ List<TestData> tests = new ArrayList<>();
+ for (int i = 0; i < REVOKED.length; i++) {
+ String key = String.format("revoked-%04d",
+ Integer.valueOf(REVOKED[i]));
+ for (String krl : KRLS) {
+ boolean expected = !krl.endsWith("-empty");
+ tests.add(new TestData(key + "-cert.pub", krl, expected));
+ expected = krl.endsWith("-keys") || krl.endsWith("-all")
+ || krl.endsWith("-hash") || krl.endsWith("-sha1")
+ || krl.endsWith("-sha256") || krl.endsWith("-text");
+ tests.add(new TestData(key + ".pub", krl, expected));
+ }
+ }
+ for (int i = 0; i < UNREVOKED.length; i++) {
+ String key = String.format("unrevoked-%04d",
+ Integer.valueOf(UNREVOKED[i]));
+ for (String krl : KRLS) {
+ boolean expected = false;
+ tests.add(new TestData(key + ".pub", krl, expected));
+ expected = krl.endsWith("-ca");
+ tests.add(new TestData(key + "-cert.pub", krl, expected));
+ }
+ }
+ return tests;
+ }
+
+ private static Path tmp;
+
+ @BeforeClass
+ public static void setUp() throws IOException {
+ tmp = Files.createTempDirectory("krls");
+ for (String krl : KRLS) {
+ copyResource("krl/" + krl, tmp);
+ }
+ }
+
+ private static void copyResource(String name, Path directory)
+ throws IOException {
+ try (InputStream in = OpenSshKrlTest.class
+ .getResourceAsStream(name)) {
+ int i = name.lastIndexOf('/');
+ String fileName = i < 0 ? name : name.substring(i + 1);
+ Files.copy(in, directory.resolve(fileName));
+ }
+ }
+
+ @AfterClass
+ public static void cleanUp() throws Exception {
+ FileUtils.delete(tmp.toFile(), FileUtils.RECURSIVE);
+ }
+
+ // Injected by JUnit
+ @Parameter
+ public TestData data;
+
+ @Test
+ public void testIsRevoked() throws Exception {
+ OpenSshKrl krl = new OpenSshKrl(tmp.resolve(data.krl));
+ try (InputStream in = this.getClass()
+ .getResourceAsStream("krl/" + data.key)) {
+ PublicKey key = AuthorizedKeyEntry.readAuthorizedKeys(in, true)
+ .get(0)
+ .resolvePublicKey(null, PublicKeyEntryResolver.FAILING);
+ assertEquals(data.expected, Boolean.valueOf(krl.isRevoked(key)));
+ }
+ }
+}
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SerialRangeSetTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SerialRangeSetTest.java
new file mode 100644
index 0000000000..e6709adebc
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SerialRangeSetTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2024, Thomas Wolf <twolf@apache.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.signing.ssh;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Tests for the set of serial number ranges.
+ */
+public class SerialRangeSetTest {
+
+ private SerialRangeSet ranges = new SerialRangeSet();
+
+ @Test
+ public void testInsertSimple() {
+ ranges.add(1);
+ ranges.add(3);
+ ranges.add(5);
+ assertEquals(3, ranges.size());
+ assertFalse(ranges.contains(0));
+ assertTrue(ranges.contains(1));
+ assertFalse(ranges.contains(2));
+ assertTrue(ranges.contains(3));
+ assertFalse(ranges.contains(4));
+ assertTrue(ranges.contains(5));
+ assertFalse(ranges.contains(6));
+ }
+
+ @Test
+ public void testInsertSimpleRanges() {
+ ranges.add(1, 2);
+ ranges.add(4, 5);
+ ranges.add(7, 8);
+ assertEquals(3, ranges.size());
+ assertFalse(ranges.contains(0));
+ assertTrue(ranges.contains(1));
+ assertTrue(ranges.contains(2));
+ assertFalse(ranges.contains(3));
+ assertTrue(ranges.contains(4));
+ assertTrue(ranges.contains(5));
+ assertFalse(ranges.contains(6));
+ assertTrue(ranges.contains(7));
+ assertTrue(ranges.contains(8));
+ assertFalse(ranges.contains(9));
+ }
+
+ @Test
+ public void testInsertCoalesce() {
+ ranges.add(5);
+ ranges.add(1);
+ ranges.add(2);
+ ranges.add(4);
+ ranges.add(7);
+ ranges.add(3);
+ assertEquals(2, ranges.size());
+ assertFalse(ranges.contains(0));
+ assertTrue(ranges.contains(1));
+ assertTrue(ranges.contains(2));
+ assertTrue(ranges.contains(3));
+ assertTrue(ranges.contains(4));
+ assertTrue(ranges.contains(5));
+ assertFalse(ranges.contains(6));
+ assertTrue(ranges.contains(7));
+ assertFalse(ranges.contains(8));
+ }
+
+ @Test
+ public void testInsertOverlap() {
+ ranges.add(1, 3);
+ ranges.add(6);
+ ranges.add(2, 5);
+ assertEquals(1, ranges.size());
+ assertFalse(ranges.contains(0));
+ assertTrue(ranges.contains(1));
+ assertTrue(ranges.contains(2));
+ assertTrue(ranges.contains(3));
+ assertTrue(ranges.contains(4));
+ assertTrue(ranges.contains(5));
+ assertTrue(ranges.contains(6));
+ assertFalse(ranges.contains(7));
+ }
+
+ @Test
+ public void testInsertOverlapMultiple() {
+ ranges.add(1, 3);
+ ranges.add(5, 6);
+ ranges.add(8);
+ ranges.add(2, 5);
+ assertEquals(2, ranges.size());
+ assertFalse(ranges.contains(0));
+ assertTrue(ranges.contains(1));
+ assertTrue(ranges.contains(2));
+ assertTrue(ranges.contains(3));
+ assertTrue(ranges.contains(4));
+ assertTrue(ranges.contains(5));
+ assertTrue(ranges.contains(6));
+ assertFalse(ranges.contains(7));
+ assertTrue(ranges.contains(8));
+ assertFalse(ranges.contains(9));
+ }
+
+ @Test
+ public void testInsertOverlapTotal() {
+ ranges.add(1, 3);
+ ranges.add(2, 3);
+ assertEquals(1, ranges.size());
+ assertFalse(ranges.contains(0));
+ assertTrue(ranges.contains(1));
+ assertTrue(ranges.contains(2));
+ assertTrue(ranges.contains(3));
+ assertFalse(ranges.contains(4));
+ }
+}
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SshCertificateUtilsTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SshCertificateUtilsTest.java
new file mode 100644
index 0000000000..79ca21fa35
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SshCertificateUtilsTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2024, Thomas Wolf <twolf@apache.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.signing.ssh;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.security.PublicKey;
+import java.time.Instant;
+import java.util.List;
+
+import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
+import org.apache.sshd.common.config.keys.OpenSshCertificate;
+import org.apache.sshd.common.config.keys.PublicKeyEntryResolver;
+import org.apache.sshd.common.util.buffer.Buffer;
+import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for {@link SshCertificateUtils}. They use a certificate valid from
+ * 2024-09-01 00:00:00 to 2024-09-02 00:00:00 UTC.
+ */
+public class SshCertificateUtilsTest {
+
+ private OpenSshCertificate certificate;
+
+ @Before
+ public void loadCertificate() throws Exception {
+ try (InputStream in = this.getClass().getResourceAsStream(
+ "certs/expired.cert")) {
+ List<AuthorizedKeyEntry> keys = AuthorizedKeyEntry
+ .readAuthorizedKeys(in, true);
+ if (keys.isEmpty()) {
+ certificate = null;
+ }
+ PublicKey key = keys.get(0).resolvePublicKey(null,
+ PublicKeyEntryResolver.FAILING);
+ assertTrue(
+ "Expected an OpenSshKeyCertificate but got a "
+ + key.getClass().getName(),
+ key instanceof OpenSshCertificate);
+ certificate = (OpenSshCertificate) key;
+ }
+ }
+
+ @Test
+ public void testValidUserCertificate() {
+ assertNull(SshCertificateUtils.verify(certificate, null));
+ Instant validTime = Instant.parse("2024-09-01T00:00:00.00Z");
+ assertNull(SshCertificateUtils.verify(certificate, validTime));
+ assertNull(SshCertificateUtils.checkExpiration(certificate, validTime));
+ }
+
+ @Test
+ public void testCheckTooEarly() {
+ Instant invalidTime = Instant.parse("2024-08-31T23:59:59.00Z");
+ assertNotNull(
+ SshCertificateUtils.checkExpiration(certificate, invalidTime));
+ assertNotNull(SshCertificateUtils.verify(certificate, invalidTime));
+ }
+
+ @Test
+ public void testCheckExpired() {
+ Instant invalidTime = Instant.parse("2024-09-02T00:00:01.00Z");
+ assertNotNull(
+ SshCertificateUtils.checkExpiration(certificate, invalidTime));
+ assertNotNull(SshCertificateUtils.verify(certificate, invalidTime));
+ }
+
+ @Test
+ public void testInvalidSignature() throws Exception {
+ // Modify the serialized certificate, then re-load it again. To check that
+ // serialization per se works fine, also check an unmodified version.
+ Buffer buffer = new ByteArrayBuffer();
+ buffer.putPublicKey(certificate);
+ int pos = buffer.rpos();
+ PublicKey unchanged = buffer.getPublicKey();
+ assertTrue(
+ "Expected an OpenSshCertificate but got a "
+ + unchanged.getClass().getName(),
+ unchanged instanceof OpenSshCertificate);
+ assertNull(SshCertificateUtils.verify((OpenSshCertificate) unchanged,
+ null));
+ buffer.rpos(pos);
+ // Change a byte. The test certificate has the key ID at offset 128.
+ // Changing a byte in the key ID should still result in a successful
+ // deserialization, but then fail the signature check.
+ buffer.array()[pos + 128]++;
+ PublicKey changed = buffer.getPublicKey();
+ assertTrue(
+ "Expected an OpenSshCertificate but got a "
+ + changed.getClass().getName(),
+ changed instanceof OpenSshCertificate);
+ assertNotNull(
+ SshCertificateUtils.verify((OpenSshCertificate) changed, null));
+ }
+}
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SshSignatureVerifierTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SshSignatureVerifierTest.java
new file mode 100644
index 0000000000..e5dfe497ca
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SshSignatureVerifierTest.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2024, Thomas Wolf <twolf@apache.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.signing.ssh;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.VerificationResult;
+import org.eclipse.jgit.lib.SignatureVerifier;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.util.StringUtils;
+import org.junit.Test;
+
+/**
+ * Tests for the {@link SshSignatureVerifier}.
+ */
+public class SshSignatureVerifierTest extends AbstractSshSignatureTest {
+
+ @Test
+ public void testPlainSignature() throws Exception {
+ RevCommit c = checkSshSignature(
+ createSignedCommit(null, "signing_key.pub"));
+ try (Git git = new Git(db)) {
+ Map<String, VerificationResult> results = git.verifySignature()
+ .addName(c.getName()).call();
+ assertEquals(1, results.size());
+ VerificationResult verified = results.get(c.getName());
+ assertNotNull(verified);
+ assertNull(verified.getException());
+ SignatureVerifier.SignatureVerification v = verified
+ .getVerification();
+ assertTrue(v.verified());
+ assertFalse(v.expired());
+ assertTrue(StringUtils.isEmptyOrNull(v.message()));
+ assertEquals("tester@example.com", v.keyUser());
+ assertEquals("SHA256:GKW0xy+XKnJGs0CJqP6j5bd4FdiwWNaUbwvUbHvhQKo",
+ v.keyFingerprint());
+ assertEquals(SignatureVerifier.TrustLevel.FULL, v.trustLevel());
+ assertEquals(commitTime, v.creationDate().toInstant());
+ }
+ }
+
+ @Test
+ public void testCertificateSignature() throws Exception {
+ RevCommit c = checkSshSignature(
+ createSignedCommit("tester.cert", "signing_key-cert.pub"));
+ try (Git git = new Git(db)) {
+ Map<String, VerificationResult> results = git.verifySignature()
+ .addName(c.getName()).call();
+ assertEquals(1, results.size());
+ VerificationResult verified = results.get(c.getName());
+ assertNotNull(verified);
+ assertNull(verified.getException());
+ SignatureVerifier.SignatureVerification v = verified
+ .getVerification();
+ assertTrue(v.verified());
+ assertFalse(v.expired());
+ assertTrue(StringUtils.isEmptyOrNull(v.message()));
+ assertEquals("tester@example.com", v.keyUser());
+ assertEquals("SHA256:GKW0xy+XKnJGs0CJqP6j5bd4FdiwWNaUbwvUbHvhQKo",
+ v.keyFingerprint());
+ assertEquals(SignatureVerifier.TrustLevel.FULL, v.trustLevel());
+ assertEquals(commitTime, v.creationDate().toInstant());
+ }
+ }
+
+ @Test
+ public void testNoPrincipalsSignature() throws Exception {
+ RevCommit c = checkSshSignature(createSignedCommit("no_principals.cert",
+ "signing_key-cert.pub"));
+ try (Git git = new Git(db)) {
+ Map<String, VerificationResult> results = git.verifySignature()
+ .addName(c.getName()).call();
+ assertEquals(1, results.size());
+ VerificationResult verified = results.get(c.getName());
+ assertNotNull(verified);
+ assertNull(verified.getException());
+ SignatureVerifier.SignatureVerification v = verified
+ .getVerification();
+ assertFalse(v.verified());
+ assertFalse(v.expired());
+ assertNull(v.keyUser());
+ assertEquals("SHA256:GKW0xy+XKnJGs0CJqP6j5bd4FdiwWNaUbwvUbHvhQKo",
+ v.keyFingerprint());
+ assertEquals(SignatureVerifier.TrustLevel.NEVER, v.trustLevel());
+ assertTrue(v.message().contains("*@example.com"));
+ assertEquals(commitTime, v.creationDate().toInstant());
+ }
+ }
+
+ @Test
+ public void testOtherCertificateSignature() throws Exception {
+ RevCommit c = checkSshSignature(
+ createSignedCommit("other.cert", "signing_key-cert.pub"));
+ try (Git git = new Git(db)) {
+ Map<String, VerificationResult> results = git.verifySignature()
+ .addName(c.getName()).call();
+ assertEquals(1, results.size());
+ VerificationResult verified = results.get(c.getName());
+ assertNotNull(verified);
+ assertNull(verified.getException());
+ SignatureVerifier.SignatureVerification v = verified
+ .getVerification();
+ assertTrue(v.verified());
+ assertFalse(v.expired());
+ assertTrue(StringUtils.isEmptyOrNull(v.message()));
+ assertEquals("other@example.com", v.keyUser());
+ assertEquals("SHA256:GKW0xy+XKnJGs0CJqP6j5bd4FdiwWNaUbwvUbHvhQKo",
+ v.keyFingerprint());
+ assertEquals(SignatureVerifier.TrustLevel.FULL, v.trustLevel());
+ assertEquals(commitTime, v.creationDate().toInstant());
+ }
+ }
+
+ @Test
+ public void testTwoPrincipalsCertificateSignature() throws Exception {
+ RevCommit c = checkSshSignature(createSignedCommit(
+ "two_principals.cert", "signing_key-cert.pub"));
+ try (Git git = new Git(db)) {
+ Map<String, VerificationResult> results = git.verifySignature()
+ .addName(c.getName()).call();
+ assertEquals(1, results.size());
+ VerificationResult verified = results.get(c.getName());
+ assertNotNull(verified);
+ assertNull(verified.getException());
+ SignatureVerifier.SignatureVerification v = verified
+ .getVerification();
+ assertTrue(v.verified());
+ assertFalse(v.expired());
+ assertTrue(StringUtils.isEmptyOrNull(v.message()));
+ assertEquals("foo@example.com,tester@example.com", v.keyUser());
+ assertEquals("SHA256:GKW0xy+XKnJGs0CJqP6j5bd4FdiwWNaUbwvUbHvhQKo",
+ v.keyFingerprint());
+ assertEquals(SignatureVerifier.TrustLevel.FULL, v.trustLevel());
+ assertEquals(commitTime, v.creationDate().toInstant());
+ }
+ }
+}
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SshSignerTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SshSignerTest.java
new file mode 100644
index 0000000000..b3a4482d23
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/SshSignerTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2024, Thomas Wolf <twolf@apache.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.signing.ssh;
+
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+
+/**
+ * Tests for the {@link SshSigner}.
+ */
+public class SshSignerTest extends AbstractSshSignatureTest {
+
+ @Test
+ public void testPlainSignature() throws Exception {
+ checkSshSignature(createSignedCommit(null, "signing_key.pub"));
+ }
+
+ @Test
+ public void testExpiredSignature() throws Exception {
+ Throwable t = assertThrows(Throwable.class,
+ () -> createSignedCommit("expired.cert",
+ "signing_key-cert.pub"));
+ // The exception or one of its causes should mention "[Ee]xpired" and
+ // "[Cc]ertificate" in the message
+ while (t != null) {
+ String message = t.getMessage();
+ if (message.contains("xpired") && message.contains("ertificate")) {
+ return;
+ }
+ t = t.getCause();
+ }
+ fail("Expected exception message not found");
+ }
+
+ @Test
+ public void testCertificateSignature() throws Exception {
+ checkSshSignature(createSignedCommit("tester.cert", "signing_key.pub"));
+ }
+
+ @Test
+ public void testNoPrincipalsSignature() throws Exception {
+ // Certificate has no principals; should still work
+ checkSshSignature(
+ createSignedCommit("no_principals.cert", "signing_key.pub"));
+ }
+
+ @Test
+ public void testOtherSignature() throws Exception {
+ // Certificate has a principal different that tester@example.com; should
+ // still work
+ checkSshSignature(createSignedCommit("other.cert", "signing_key.pub"));
+ }
+}
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/VerifyGitSignaturesTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/VerifyGitSignaturesTest.java
new file mode 100644
index 0000000000..30ddee559c
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/VerifyGitSignaturesTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2024, Thomas Wolf <twolf@apache.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.signing.ssh;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.io.File;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.VerificationResult;
+import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.SignatureVerifier;
+import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.util.GitDateFormatter;
+import org.eclipse.jgit.util.SignatureUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Verifies signatures made with C git and OpenSSH 9.0 to ensure we arrive at
+ * the same good/bad decisions, and that we can verify signatures not created by
+ * ourselves.
+ * <p>
+ * Clones a JGit repo from a git bundle file created with C git, then checks all
+ * the commits and their signatures. (All commits in that bundle have SSH
+ * signatures.)
+ * </p>
+ */
+public class VerifyGitSignaturesTest extends LocalDiskRepositoryTestCase {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(VerifyGitSignaturesTest.class);
+
+ @Rule
+ public TemporaryFolder bundleDir = new TemporaryFolder();
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ try (InputStream in = this.getClass()
+ .getResourceAsStream("repo.bundle")) {
+ Files.copy(in, bundleDir.getRoot().toPath().resolve("repo.bundle"));
+ }
+ try (InputStream in = this.getClass()
+ .getResourceAsStream("allowed_signers")) {
+ Files.copy(in,
+ bundleDir.getRoot().toPath().resolve("allowed_signers"));
+ }
+ }
+
+ /**
+ * Tests signatures created by C git using OpenSSH 9.0.
+ */
+ @Test
+ public void testGitSignatures() throws Exception {
+ File gitDir = new File(getTemporaryDirectory(), "repo.git");
+ try (Git git = Git.cloneRepository().setBare(true)
+ .setGitDir(gitDir)
+ .setURI(new File(bundleDir.getRoot(), "repo.bundle").toURI()
+ .toString())
+ .setBranch("master")
+ .call()) {
+ StoredConfig config = git.getRepository().getConfig();
+ config.setString("gpg", "ssh", "allowedSignersFile",
+ bundleDir.getRoot().toPath().resolve("allowed_signers")
+ .toAbsolutePath().toString().replace('\\', '/'));
+ config.save();
+ List<String> commits = new ArrayList<>();
+ Map<String, PersonIdent> committers = new HashMap<>();
+ git.log().all().call().forEach(c -> {
+ commits.add(c.getName());
+ committers.put(c.getName(), c.getCommitterIdent());
+ });
+ Map<String, Boolean> expected = new HashMap<>();
+ // These two commits do have multiple principals. GIT just reports
+ // the first one; we report both.
+ expected.put("9f79a7b661a22ab1ddf8af880d23678ae7696b71",
+ Boolean.TRUE);
+ expected.put("435108d157440e77d61a914b6a5736bc831c874d",
+ Boolean.TRUE);
+ // This commit has a wrong commit message; the certificate used
+ // did _not_ have two principals, but only a single principal
+ // foo@example.org.
+ expected.put("779dac7de40ebc3886af87d5e6680a09f8b13a3e",
+ Boolean.TRUE);
+ // Signed with other_key-cert.pub: we still don't know the key,
+ // but we do know the certificate's CA key, and trust it, so it's
+ // accepted as a signature from the principal(s) listed in the
+ // certificate.
+ expected.put("951f06d5b5598b721b98d98b04e491f234c1926a",
+ Boolean.TRUE);
+ // Signature with other_key.pub not listed in allowed_signers
+ expected.put("984e629c6d543a7f77eb49a8c9316f2ae4416375",
+ Boolean.FALSE);
+ // Signed with other-ca.cert (CA key not in allowed_signers), but
+ // the certified key _is_ listed in allowed_signers.
+ expected.put("1d7ac6d91747a9c9a777df238fbdaeffa7731a6c",
+ Boolean.FALSE);
+ expected.put("a297bcfbf5c4a850f9770655fef7315328a4b3fb",
+ Boolean.TRUE);
+ expected.put("852729d54676cb83826ed821dc7734013e97950d",
+ Boolean.TRUE);
+ // Signature with a certificate without principals.
+ expected.put("e39a049f75fe127eb74b30aba4b64e171d4281dd",
+ Boolean.FALSE);
+ // Signature made with expired.cert (expired at the commit time).
+ // git/OpenSSH 9.0 allows to create such signatures, but reports
+ // them as FALSE. Our SshSigner doesn't allow creating such
+ // signatures.
+ expected.put("303ea5e61feacdad4cb012b4cb6b0cea3fbcef9f",
+ Boolean.FALSE);
+ expected.put("1ae4b120a869b72a7a2d4ad4d7a8c9d454384333",
+ Boolean.TRUE);
+ Map<String, VerificationResult> results = git.verifySignature()
+ .addNames(commits).call();
+ GitDateFormatter dateFormat = new GitDateFormatter(
+ GitDateFormatter.Format.ISO);
+ for (String oid : commits) {
+ VerificationResult v = results.get(oid);
+ assertNotNull(v);
+ assertNull(v.getException());
+ SignatureVerifier.SignatureVerification sv = v
+ .getVerification();
+ assertNotNull(sv);
+ LOG.info("Commit {}\n{}", oid, SignatureUtils.toString(sv,
+ committers.get(oid), dateFormat));
+ Boolean wanted = expected.get(oid);
+ assertNotNull(wanted);
+ assertEquals(wanted, Boolean.valueOf(sv.verified()));
+ }
+ }
+ }
+}
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/transport/sshd/KnownHostEntryReaderTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/transport/sshd/KnownHostEntryReaderTest.java
new file mode 100644
index 0000000000..d36c38f335
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/transport/sshd/KnownHostEntryReaderTest.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 Thomas Wolf <twolf@apache.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.transport.sshd;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.apache.sshd.client.config.hosts.KnownHostEntry;
+import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
+import org.junit.Test;
+
+public class KnownHostEntryReaderTest {
+
+ @Test
+ public void testUnsupportedHostKeyLine() {
+ KnownHostEntry entry = KnownHostEntryReader.parseHostEntry(
+ "[localhost]:2222 ssh-unknown AAAAC3NzaC1lZDI1NTE5AAAAIPu6ntmyfSOkqLl3qPxD5XxwW7OONwwSG3KO+TGn+PFu");
+ AuthorizedKeyEntry keyEntry = entry.getKeyEntry();
+ assertNotNull(keyEntry);
+ assertEquals("ssh-unknown", keyEntry.getKeyType());
+ }
+}
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabaseTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabaseTest.java
new file mode 100644
index 0000000000..6b61821a0f
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabaseTest.java
@@ -0,0 +1,586 @@
+/*
+ * Copyright (C) 2025 Thomas Wolf <twolf@apache.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.transport.sshd;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.sshd.certificate.OpenSshCertificateBuilder;
+import org.apache.sshd.common.SshConstants;
+import org.apache.sshd.common.cipher.ECCurves;
+import org.apache.sshd.common.config.keys.KeyUtils;
+import org.apache.sshd.common.config.keys.PublicKeyEntry;
+import org.apache.sshd.common.util.security.SecurityUtils;
+import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.errors.UnsupportedCredentialItem;
+import org.eclipse.jgit.transport.CredentialItem;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.transport.sshd.ServerKeyDatabase;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * Tests for {@link OpenSshServerKeyDatabase}.
+ */
+public class OpenSshServerKeyDatabaseTest {
+
+ private static final InetSocketAddress LOCAL = new InetSocketAddress(
+ InetAddress.getLoopbackAddress(), SshConstants.DEFAULT_PORT);
+
+ private static final InetSocketAddress LOCAL_29418 = new InetSocketAddress(
+ InetAddress.getLoopbackAddress(), 29418);
+
+ private static PublicKey rsa1024;
+ private static PublicKey rsa2048;
+ private static PublicKey ec256;
+ private static PublicKey ec384;
+ private static PublicKey caKey;
+ private static PublicKey certificate;
+
+ @BeforeClass
+ public static void initKeys() throws Exception {
+ // Generate a few keys that we can use
+ KeyPairGenerator gen = SecurityUtils.getKeyPairGenerator(KeyUtils.RSA_ALGORITHM);
+ gen.initialize(1024);
+ rsa1024 = gen.generateKeyPair().getPublic();
+ gen.initialize(2048);
+ rsa2048 = gen.generateKeyPair().getPublic();
+ gen = SecurityUtils.getKeyPairGenerator(KeyUtils.EC_ALGORITHM);
+ ECCurves curve = ECCurves.fromCurveSize(256);
+ gen.initialize(curve.getParameters());
+ ec256 = gen.generateKeyPair().getPublic();
+ PublicKey certKey = gen.generateKeyPair().getPublic();
+ curve = ECCurves.fromCurveSize(384);
+ gen.initialize(curve.getParameters());
+ ec384 = gen.generateKeyPair().getPublic();
+ // Generate a certificate for some key
+ gen.initialize(curve.getParameters());
+ KeyPair ca = gen.generateKeyPair();
+ caKey = ca.getPublic();
+ certificate = OpenSshCertificateBuilder
+ .hostCertificate()
+ .serial(System.currentTimeMillis())
+ .publicKey(certKey)
+ .id("test-host-cert")
+ .validBefore(
+ System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1))
+ .principals(List.of("localhost", "127.0.0.1"))
+ .sign(ca, "ecdsa-sha2-nistp384");
+ }
+
+ @Rule
+ public TemporaryFolder tmp = new TemporaryFolder();
+
+ private Path knownHosts;
+ private Path knownHosts2;
+ private ServerKeyDatabase database;
+
+ @Before
+ public void setupDatabase() throws Exception {
+ Path root = tmp.getRoot().toPath();
+ knownHosts = root.resolve("known_hosts");
+ knownHosts2 = root.resolve("known_hosts2");
+ database = new OpenSshServerKeyDatabase(false, List.of(knownHosts, knownHosts2));
+ }
+
+ @Test
+ public void testFindInSecondFile() throws Exception {
+ Files.write(knownHosts,
+ List.of(
+ "some.other.host " + PublicKeyEntry.toString(rsa1024),
+ "some.other.com " + PublicKeyEntry.toString(ec384)));
+ Files.write(knownHosts2,
+ List.of(
+ "localhost,127.0.0.1 " + PublicKeyEntry.toString(ec256),
+ "some.other.com " + PublicKeyEntry.toString(rsa2048)));
+ assertTrue(database.accept("localhost", LOCAL, ec256,
+ new KnownHostsConfig(), null));
+ assertFalse(database.accept("localhost", LOCAL, ec384,
+ new KnownHostsConfig(), null));
+ }
+
+ @Test
+ public void testNoFirstFile() throws Exception {
+ Files.write(knownHosts2,
+ List.of("localhost,127.0.0.1 " + PublicKeyEntry.toString(ec256),
+ "some.other.com " + PublicKeyEntry.toString(rsa2048)));
+ assertTrue(database.accept("localhost", LOCAL, ec256,
+ new KnownHostsConfig(), null));
+ }
+
+ @Test
+ public void testFind() throws Exception {
+ Files.write(knownHosts,
+ List.of("localhost,127.0.0.1 "
+ + PublicKeyEntry.toString(rsa1024),
+ "some.other.com " + PublicKeyEntry.toString(ec384)));
+ Files.write(knownHosts2,
+ List.of("localhost,127.0.0.1 " + PublicKeyEntry.toString(ec256),
+ "some.other.com " + PublicKeyEntry.toString(rsa2048)));
+ assertTrue(database.accept("localhost", LOCAL, ec256,
+ new KnownHostsConfig(), null));
+ assertTrue(database.accept("localhost:22", LOCAL, ec256,
+ new KnownHostsConfig(), null));
+ assertTrue(database.accept("127.0.0.1", LOCAL, rsa1024,
+ new KnownHostsConfig(), null));
+ assertTrue(database.accept("[127.0.0.1]:22", LOCAL, rsa1024,
+ new KnownHostsConfig(), null));
+ assertFalse(database.accept("localhost:29418", LOCAL_29418, ec256,
+ new KnownHostsConfig(), null));
+ assertFalse(database.accept("localhost", LOCAL, ec384,
+ new KnownHostsConfig(), null));
+ }
+
+ @Test
+ public void testFindCertificate() throws Exception {
+ Files.write(knownHosts,
+ List.of("localhost,127.0.0.1 "
+ + PublicKeyEntry.toString(rsa1024),
+ "some.other.com " + PublicKeyEntry.toString(ec384),
+ "@cert-authority localhost,127.0.0.1 "
+ + PublicKeyEntry.toString(caKey)));
+ assertTrue(database.accept("localhost", LOCAL, certificate,
+ new KnownHostsConfig(), null));
+ }
+
+ @Test
+ public void testCaKeyNotConsidered() throws Exception {
+ Files.write(knownHosts,
+ List.of("localhost,127.0.0.1 "
+ + PublicKeyEntry.toString(rsa1024),
+ "some.other.com " + PublicKeyEntry.toString(ec384),
+ "@cert-authority localhost,127.0.0.1 "
+ + PublicKeyEntry.toString(ec256)));
+ assertFalse(database.accept("localhost", LOCAL, ec256,
+ new KnownHostsConfig(), null));
+ }
+
+ @Test
+ public void testkeyPlainAndCa() throws Exception {
+ Files.write(knownHosts, List.of(
+ "localhost,127.0.0.1 " + PublicKeyEntry.toString(rsa1024),
+ "some.other.com " + PublicKeyEntry.toString(ec384),
+ "@cert-authority localhost,127.0.0.1 "
+ + PublicKeyEntry.toString(ec256),
+ "localhost,127.0.0.1 " + PublicKeyEntry.toString(ec256)));
+ // ec256 is a CA key, but also a valid direct host key for localhost
+ assertTrue(database.accept("localhost", LOCAL, ec256,
+ new KnownHostsConfig(), null));
+ }
+
+ @Test
+ public void testLookupCertificate() throws Exception {
+ List<PublicKey> keys = database.lookup("localhost", LOCAL,
+ new KnownHostsConfig());
+ // Certificates or CA keys are not reported via lookup.
+ assertTrue(keys.isEmpty());
+ }
+
+ @Test
+ public void testCertificateNotAdded() throws Exception {
+ List<String> initialKnownHosts = List.of(
+ "localhost,127.0.0.1 " + PublicKeyEntry.toString(rsa1024),
+ "some.other.com " + PublicKeyEntry.toString(ec384));
+ Files.write(knownHosts, initialKnownHosts);
+ assertFalse(database.accept("localhost", LOCAL, certificate,
+ new KnownHostsConfig(), null));
+ TestCredentialsProvider ui = new TestCredentialsProvider(true, true);
+ assertFalse(
+ database.accept("localhost", LOCAL, certificate,
+ new KnownHostsConfig(
+ KnownHostsConfig.StrictHostKeyChecking.ASK),
+ ui));
+ assertEquals(0, ui.invocations);
+ assertFile(knownHosts, initialKnownHosts);
+ }
+
+ @Test
+ public void testCertificateNotModified() throws Exception {
+ List<String> initialKnownHosts = List.of(
+ "@cert-authority localhost,127.0.0.1 "
+ + PublicKeyEntry.toString(ec384),
+ "some.other.com " + PublicKeyEntry.toString(ec256));
+ Files.write(knownHosts, initialKnownHosts);
+ assertFalse(database.accept("localhost", LOCAL, certificate,
+ new KnownHostsConfig(), null));
+ TestCredentialsProvider ui = new TestCredentialsProvider(true, true);
+ assertFalse(
+ database.accept("localhost", LOCAL, certificate,
+ new KnownHostsConfig(
+ KnownHostsConfig.StrictHostKeyChecking.ASK),
+ ui));
+ assertEquals(0, ui.invocations);
+ assertFile(knownHosts, initialKnownHosts);
+ }
+
+ @Test
+ public void testModifyFile() throws Exception {
+ List<String> initialKnownHosts = List.of(
+ "some.other.host " + PublicKeyEntry.toString(rsa1024),
+ "some.other.com " + PublicKeyEntry.toString(ec384));
+ Files.write(knownHosts, initialKnownHosts);
+ List<String> initialKnownHosts2 = List.of(
+ "localhost,127.0.0.1 " + PublicKeyEntry.toString(ec256),
+ "some.other.com " + PublicKeyEntry.toString(rsa2048));
+ Files.write(knownHosts2, initialKnownHosts2);
+ assertFalse(database.accept("localhost", LOCAL, ec384,
+ new KnownHostsConfig(), null));
+ assertFile(knownHosts, initialKnownHosts);
+ assertFile(knownHosts2, initialKnownHosts2);
+ assertFalse(database.accept("localhost", LOCAL, ec384,
+ new KnownHostsConfig(
+ ServerKeyDatabase.Configuration.StrictHostKeyChecking.ACCEPT_NEW),
+ null));
+ assertFile(knownHosts, initialKnownHosts);
+ assertFile(knownHosts2, initialKnownHosts2);
+ assertTrue(database.accept("localhost", LOCAL, ec384,
+ new KnownHostsConfig(
+ ServerKeyDatabase.Configuration.StrictHostKeyChecking.ACCEPT_ANY),
+ null));
+ assertFile(knownHosts, initialKnownHosts);
+ assertFile(knownHosts2, initialKnownHosts2);
+ assertFalse(database.accept("localhost", LOCAL, ec384,
+ new KnownHostsConfig(
+ ServerKeyDatabase.Configuration.StrictHostKeyChecking.ASK),
+ null));
+ assertFile(knownHosts, initialKnownHosts);
+ assertFile(knownHosts2, initialKnownHosts2);
+
+ TestCredentialsProvider ui = new TestCredentialsProvider(true, false);
+ assertTrue(database.accept("localhost", LOCAL, ec384,
+ new KnownHostsConfig(
+ ServerKeyDatabase.Configuration.StrictHostKeyChecking.ASK),
+ ui));
+ assertEquals(1, ui.invocations);
+ assertFile(knownHosts, initialKnownHosts);
+ assertFile(knownHosts2, initialKnownHosts2);
+
+ ui = new TestCredentialsProvider(true, true);
+ assertTrue(database.accept("localhost", LOCAL, ec384,
+ new KnownHostsConfig(
+ ServerKeyDatabase.Configuration.StrictHostKeyChecking.ASK),
+ ui));
+ assertEquals(1, ui.invocations);
+ assertFile(knownHosts, initialKnownHosts);
+ assertFile(knownHosts2, List.of(
+ "localhost,127.0.0.1 " + PublicKeyEntry.toString(ec384),
+ "some.other.com " + PublicKeyEntry.toString(rsa2048)));
+ assertTrue(database.accept("127.0.0.1", LOCAL, ec384,
+ new KnownHostsConfig(), null));
+ }
+
+ @Test
+ public void testModifyFirstFile() throws Exception {
+ List<String> initialKnownHosts = List.of(
+ "localhost,127.0.0.1 " + PublicKeyEntry.toString(rsa1024),
+ "some.other.com " + PublicKeyEntry.toString(ec384));
+ Files.write(knownHosts, initialKnownHosts);
+ List<String> initialKnownHosts2 = List.of(
+ "some.other.host " + PublicKeyEntry.toString(ec256),
+ "some.other.com " + PublicKeyEntry.toString(rsa2048));
+ Files.write(knownHosts2, initialKnownHosts2);
+ TestCredentialsProvider ui = new TestCredentialsProvider(true, true);
+ assertTrue(database.accept("localhost", LOCAL, ec384,
+ new KnownHostsConfig(
+ ServerKeyDatabase.Configuration.StrictHostKeyChecking.ASK),
+ ui));
+ assertEquals(1, ui.invocations);
+ assertFile(knownHosts,
+ List.of("localhost,127.0.0.1 " + PublicKeyEntry.toString(ec384),
+ "some.other.com " + PublicKeyEntry.toString(ec384)));
+ assertFile(knownHosts2, initialKnownHosts2);
+ assertTrue(database.accept("127.0.0.1:22", LOCAL, ec384,
+ new KnownHostsConfig(), null));
+ }
+
+ @Test
+ public void testModifyMatchingKeyType() throws Exception {
+ List<String> initialKnownHosts = List.of(
+ "localhost,127.0.0.1 " + PublicKeyEntry.toString(rsa1024),
+ "some.other.com " + PublicKeyEntry.toString(ec384));
+ Files.write(knownHosts, initialKnownHosts);
+ List<String> initialKnownHosts2 = List.of(
+ "localhost,127.0.0.1 " + PublicKeyEntry.toString(ec256),
+ "some.other.com " + PublicKeyEntry.toString(rsa2048));
+ Files.write(knownHosts2, initialKnownHosts2);
+ TestCredentialsProvider ui = new TestCredentialsProvider(true, true);
+ assertTrue(database.accept("localhost", LOCAL, rsa2048,
+ new KnownHostsConfig(
+ ServerKeyDatabase.Configuration.StrictHostKeyChecking.ASK),
+ ui));
+ assertEquals(1, ui.invocations);
+ assertFile(knownHosts,
+ List.of("localhost,127.0.0.1 "
+ + PublicKeyEntry.toString(rsa2048),
+ "some.other.com " + PublicKeyEntry.toString(ec384)));
+ assertFile(knownHosts2, initialKnownHosts2);
+ assertTrue(database.accept("127.0.0.1:22", LOCAL, rsa2048,
+ new KnownHostsConfig(), null));
+ }
+
+ @Test
+ public void testModifyMatchingKeyType2() throws Exception {
+ List<String> initialKnownHosts = List.of(
+ "localhost,127.0.0.1 " + PublicKeyEntry.toString(ec256),
+ "some.other.com " + PublicKeyEntry.toString(ec384));
+ Files.write(knownHosts, initialKnownHosts);
+ List<String> initialKnownHosts2 = List.of(
+ "localhost,127.0.0.1 " + PublicKeyEntry.toString(rsa1024),
+ "some.other.com " + PublicKeyEntry.toString(rsa2048));
+ Files.write(knownHosts2, initialKnownHosts2);
+ TestCredentialsProvider ui = new TestCredentialsProvider(true, true);
+ assertTrue(database.accept("localhost", LOCAL, ec384,
+ new KnownHostsConfig(
+ ServerKeyDatabase.Configuration.StrictHostKeyChecking.ASK),
+ ui));
+ assertEquals(1, ui.invocations);
+ assertFile(knownHosts,
+ List.of("localhost,127.0.0.1 " + PublicKeyEntry.toString(ec384),
+ "some.other.com " + PublicKeyEntry.toString(ec384)));
+ assertFile(knownHosts2, initialKnownHosts2);
+ assertTrue(database.accept("127.0.0.1:22", LOCAL, ec384,
+ new KnownHostsConfig(), null));
+ }
+
+ @Test
+ public void testModifySecondFile() throws Exception {
+ List<String> initialKnownHosts = List.of(
+ "localhost,127.0.0.1 " + PublicKeyEntry.toString(rsa1024),
+ "some.other.com " + PublicKeyEntry.toString(ec384));
+ Files.write(knownHosts, initialKnownHosts);
+ List<String> initialKnownHosts2 = List.of(
+ "localhost,127.0.0.1 " + PublicKeyEntry.toString(ec256),
+ "some.other.com " + PublicKeyEntry.toString(rsa2048));
+ Files.write(knownHosts2, initialKnownHosts2);
+ TestCredentialsProvider ui = new TestCredentialsProvider(true, true);
+ assertTrue(database.accept("localhost", LOCAL, ec384,
+ new KnownHostsConfig(
+ ServerKeyDatabase.Configuration.StrictHostKeyChecking.ASK),
+ ui));
+ assertEquals(1, ui.invocations);
+ assertFile(knownHosts, initialKnownHosts);
+ assertFile(knownHosts2,
+ List.of("localhost,127.0.0.1 " + PublicKeyEntry.toString(ec384),
+ "some.other.com " + PublicKeyEntry.toString(rsa2048)));
+ assertTrue(database.accept("127.0.0.1:22", LOCAL, ec384,
+ new KnownHostsConfig(), null));
+ }
+
+ @Test
+ public void testAddNewKey() throws Exception {
+ List<String> initialKnownHosts = List.of(
+ "some.other.host " + PublicKeyEntry.toString(rsa1024),
+ "some.other.com " + PublicKeyEntry.toString(ec256));
+ Files.write(knownHosts, initialKnownHosts);
+ List<String> initialKnownHosts2 = List
+ .of("some.other.com " + PublicKeyEntry.toString(rsa2048));
+ Files.write(knownHosts2, initialKnownHosts2);
+ TestCredentialsProvider ui = new TestCredentialsProvider(true, true);
+ assertTrue(database.accept("localhost", LOCAL, ec384,
+ new KnownHostsConfig(
+ ServerKeyDatabase.Configuration.StrictHostKeyChecking.ASK),
+ ui));
+ assertEquals(1, ui.invocations);
+ List<String> expected = new ArrayList<>(initialKnownHosts);
+ expected.add("localhost,127.0.0.1 " + PublicKeyEntry.toString(ec384));
+ assertFile(knownHosts, expected);
+ assertFile(knownHosts2, initialKnownHosts2);
+ assertTrue(database.accept("127.0.0.1:22", LOCAL, ec384,
+ new KnownHostsConfig(), null));
+ }
+
+ @Test
+ public void testCreateNewFile() throws Exception {
+ List<String> initialKnownHosts2 = List
+ .of("some.other.com " + PublicKeyEntry.toString(ec256));
+ Files.write(knownHosts2, initialKnownHosts2);
+ TestCredentialsProvider ui = new TestCredentialsProvider(true, true);
+ assertTrue(database.accept("localhost", LOCAL, ec384,
+ new KnownHostsConfig(
+ ServerKeyDatabase.Configuration.StrictHostKeyChecking.ASK),
+ ui));
+ assertEquals(1, ui.invocations);
+ assertFile(knownHosts, List
+ .of("localhost,127.0.0.1 " + PublicKeyEntry.toString(ec384)));
+ assertFile(knownHosts2, initialKnownHosts2);
+ assertTrue(database.accept("127.0.0.1:22", LOCAL, ec384,
+ new KnownHostsConfig(), null));
+ }
+
+ @Test
+ public void testAddNewKey2() throws Exception {
+ List<String> initialKnownHosts = List.of(
+ "some.other.host " + PublicKeyEntry.toString(rsa1024),
+ "some.other.com " + PublicKeyEntry.toString(ec256));
+ Files.write(knownHosts, initialKnownHosts);
+ List<String> initialKnownHosts2 = List
+ .of("some.other.com " + PublicKeyEntry.toString(rsa2048));
+ Files.write(knownHosts2, initialKnownHosts2);
+ TestCredentialsProvider ui = new TestCredentialsProvider(true, true);
+ assertTrue(database.accept("127.0.0.1:29418", LOCAL_29418, ec384,
+ new KnownHostsConfig(
+ ServerKeyDatabase.Configuration.StrictHostKeyChecking.ASK),
+ ui));
+ assertEquals(1, ui.invocations);
+ List<String> expected = new ArrayList<>(initialKnownHosts);
+ expected.add("[127.0.0.1]:29418,[localhost]:29418 "
+ + PublicKeyEntry.toString(ec384));
+ assertFile(knownHosts, expected);
+ assertFile(knownHosts2, initialKnownHosts2);
+ assertTrue(database.accept("localhost:29418", LOCAL_29418, ec384,
+ new KnownHostsConfig(), null));
+ }
+
+ @Test
+ public void testAddNewKey3() throws Exception {
+ List<String> initialKnownHosts = List.of(
+ "some.other.host " + PublicKeyEntry.toString(rsa1024),
+ "some.other.com " + PublicKeyEntry.toString(ec256));
+ Files.write(knownHosts, initialKnownHosts);
+ List<String> initialKnownHosts2 = List
+ .of("some.other.com " + PublicKeyEntry.toString(rsa2048));
+ Files.write(knownHosts2, initialKnownHosts2);
+ TestCredentialsProvider ui = new TestCredentialsProvider(true, true);
+ assertTrue(database.accept("localhost:29418", LOCAL_29418, ec384,
+ new KnownHostsConfig(
+ ServerKeyDatabase.Configuration.StrictHostKeyChecking.ASK),
+ ui));
+ assertEquals(1, ui.invocations);
+ List<String> expected = new ArrayList<>(initialKnownHosts);
+ expected.add("[localhost]:29418,[127.0.0.1]:29418 "
+ + PublicKeyEntry.toString(ec384));
+ assertFile(knownHosts, expected);
+ assertFile(knownHosts2, initialKnownHosts2);
+ assertTrue(database.accept("127.0.0.1:29418", LOCAL_29418, ec384,
+ new KnownHostsConfig(), null));
+ }
+
+ @Test
+ public void testUnknownKeyType() throws Exception {
+ List<String> initialKnownHosts = List.of(
+ "localhost,127.0.0.1 " + PublicKeyEntry.toString(ec384)
+ .replace("ecdsa", "foo"),
+ "some.other.com " + PublicKeyEntry.toString(ec384));
+ Files.write(knownHosts, initialKnownHosts);
+ TestCredentialsProvider ui = new TestCredentialsProvider(true, true);
+ assertTrue(database.accept("localhost", LOCAL, ec384,
+ new KnownHostsConfig(
+ ServerKeyDatabase.Configuration.StrictHostKeyChecking.ASK),
+ ui));
+ assertEquals(1, ui.invocations);
+ // The "modified key" dialog has two questions; whereas the "add new
+ // key" is just a simple question.
+ assertEquals(2, ui.questions);
+ List<String> expected = new ArrayList<>(initialKnownHosts);
+ expected.add("localhost,127.0.0.1 " + PublicKeyEntry.toString(ec384));
+ assertFile(knownHosts, expected);
+ assertTrue(database.accept("127.0.0.1:22", LOCAL, ec384,
+ new KnownHostsConfig(), null));
+ }
+
+ private void assertFile(Path path, List<String> lines) throws Exception {
+ assertEquals(lines, Files.readAllLines(path).stream()
+ .filter(s -> !s.isBlank()).toList());
+ }
+
+ private static class TestCredentialsProvider extends CredentialsProvider {
+
+ private final boolean[] values;
+
+ int invocations = 0;
+
+ int questions = 0;
+
+ TestCredentialsProvider(boolean accept, boolean store) {
+ values = new boolean[] { accept, store };
+ }
+
+ @Override
+ public boolean isInteractive() {
+ return true;
+ }
+
+ @Override
+ public boolean supports(CredentialItem... items) {
+ return true;
+ }
+
+ @Override
+ public boolean get(URIish uri, CredentialItem... items)
+ throws UnsupportedCredentialItem {
+ invocations++;
+ int i = 0;
+ for (CredentialItem item : items) {
+ if (item instanceof CredentialItem.YesNoType) {
+ ((CredentialItem.YesNoType) item)
+ .setValue(i < values.length && values[i++]);
+ questions++;
+ }
+ }
+ return true;
+ }
+ }
+
+ private static class KnownHostsConfig implements ServerKeyDatabase.Configuration {
+
+ @NonNull
+ private final StrictHostKeyChecking check;
+
+ KnownHostsConfig() {
+ this(StrictHostKeyChecking.REQUIRE_MATCH);
+ }
+
+ KnownHostsConfig(@NonNull StrictHostKeyChecking check) {
+ this.check = check;
+ }
+
+ @Override
+ public List<String> getUserKnownHostsFiles() {
+ return List.of();
+ }
+
+ @Override
+ public List<String> getGlobalKnownHostsFiles() {
+ return List.of();
+ }
+
+ @Override
+ public StrictHostKeyChecking getStrictHostKeyChecking() {
+ return check;
+ }
+
+ @Override
+ public boolean getHashKnownHosts() {
+ return false;
+ }
+
+ @Override
+ public String getUsername() {
+ return "user";
+ }
+
+ }
+}
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshProtocol2Test.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshProtocol2Test.java
index eef0402b07..69bd5c501a 100644
--- a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshProtocol2Test.java
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshProtocol2Test.java
@@ -17,7 +17,6 @@ import java.util.Arrays;
import org.eclipse.jgit.junit.ssh.SshBasicTestBase;
import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.util.FS;
@@ -52,7 +51,8 @@ public class ApacheSshProtocol2Test extends SshBasicTestBase {
@Override
public void setUp() throws Exception {
super.setUp();
- StoredConfig config = ((Repository) db).getConfig();
+ @SuppressWarnings("restriction")
+ StoredConfig config = db.getConfig();
config.setInt("protocol", null, "version", 2);
config.save();
}
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java
index a8fcca7b8e..873945780f 100644
--- a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java
@@ -861,4 +861,37 @@ public class ApacheSshTest extends SshTestBase {
verifyAuthLog(e.getMessage(), "log in");
}
+ @Test
+ public void testCipherModificationSingle() throws Exception {
+ cloneWith(
+ "ssh://" + TEST_USER + "@localhost:" + testPort
+ + "/doesntmatter",
+ defaultCloneDir, null,
+ "IdentityFile " + privateKey1.getAbsolutePath(),
+ "Ciphers aes192-ctr");
+ }
+
+ @Test
+ public void testCipherModificationAdd() throws Exception {
+ cloneWith(
+ "ssh://" + TEST_USER + "@localhost:" + testPort
+ + "/doesntmatter",
+ defaultCloneDir, null,
+ "IdentityFile " + privateKey1.getAbsolutePath(),
+ "Ciphers +3des-cbc");
+ }
+
+ @Test
+ public void testCipherModificationUnknown() throws Exception {
+ TransportException e = assertThrows(TransportException.class,
+ () -> cloneWith(
+ "ssh://" + TEST_USER + "@localhost:" + testPort
+ + "/doesntmatter",
+ defaultCloneDir, null,
+ "IdentityFile " + privateKey1.getAbsolutePath(),
+ // The server is not configured to use this deprecated
+ // algorithm
+ "Ciphers 3des-cbc"));
+ assertTrue(e.getLocalizedMessage().contains("3des-cbc"));
+ }
}