diff options
115 files changed, 3757 insertions, 2 deletions
diff --git a/org.eclipse.jgit.ssh.apache.test/.gitattributes b/org.eclipse.jgit.ssh.apache.test/.gitattributes index c1f1b7371a..b5b937561d 100644 --- a/org.eclipse.jgit.ssh.apache.test/.gitattributes +++ b/org.eclipse.jgit.ssh.apache.test/.gitattributes @@ -1 +1,2 @@ -/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/repo.bundle binary
\ No newline at end of file +/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/BUILD b/org.eclipse.jgit.ssh.apache.test/BUILD index bb31f8b3c7..dfc059f0a3 100644 --- a/org.eclipse.jgit.ssh.apache.test/BUILD +++ b/org.eclipse.jgit.ssh.apache.test/BUILD @@ -10,6 +10,7 @@ load( DEPS = [ "//lib:eddsa", "//lib:junit", + "//lib:slf4j-api", "//lib:sshd-osgi", "//lib:sshd-sftp", "//org.eclipse.jgit:jgit", 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/krl/krl b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/krl/krl Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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/repo.bundle b/org.eclipse.jgit.ssh.apache.test/tst-rsrc/org/eclipse/jgit/internal/signing/ssh/repo.bundle Binary files differnew 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 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 index e13379be72..fdfffce810 100644 --- 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 @@ -50,6 +50,7 @@ public abstract class AbstractSshSignatureTest extends RepositoryTestCase { @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()); @@ -65,6 +66,9 @@ public abstract class AbstractSshSignatureTest extends RepositoryTestCase { 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 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..90fde3fb28 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/signing/ssh/AllowedSignersParseTest.java @@ -0,0 +1,201 @@ +/* + * 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")); + } + + @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( + "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/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/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/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF index 512c19f4c2..826d33009b 100644 --- a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF @@ -28,6 +28,7 @@ Export-Package: org.eclipse.jgit.internal.signing.ssh;version="7.1.0";x-friends: org.eclipse.jgit.internal.transport.sshd.auth;version="7.1.0";x-internal:=true, org.eclipse.jgit.internal.transport.sshd.pkcs11;version="7.1.0";x-internal:=true, org.eclipse.jgit.internal.transport.sshd.proxy;version="7.1.0";x-friends:="org.eclipse.jgit.ssh.apache.test", + org.eclipse.jgit.signing.ssh;version="7.1.0";uses:="org.eclipse.jgit.lib", org.eclipse.jgit.transport.sshd;version="7.1.0"; uses:="org.eclipse.jgit.transport, org.apache.sshd.client.config.hosts, diff --git a/org.eclipse.jgit.ssh.apache/resources/META-INF/services/org.eclipse.jgit.lib.SignatureVerifierFactory b/org.eclipse.jgit.ssh.apache/resources/META-INF/services/org.eclipse.jgit.lib.SignatureVerifierFactory new file mode 100644 index 0000000000..4a0f553c81 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/resources/META-INF/services/org.eclipse.jgit.lib.SignatureVerifierFactory @@ -0,0 +1 @@ +org.eclipse.jgit.signing.ssh.SshSignatureVerifierFactory
\ No newline at end of file diff --git a/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties b/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties index e51c80a5ac..6048239391 100644 --- a/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties +++ b/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties @@ -125,17 +125,59 @@ sshClosingDown=Apache MINA sshd session factory is closing down; cannot create n sshCommandTimeout={0} timed out after {1} seconds while opening the channel sshProcessStillRunning={0} is not yet completed, cannot get exit code sshProxySessionCloseFailed=Error while closing proxy session {0} +signAllowedSignersCertAuthorityError=Garbage after cert-authority +signAllowedSignersEmptyIdentity=Identities contains an empty identity; check for spurious extra commas: {0} +signAllowedSignersEmptyNamespaces=Empty namespaces= is not allowed; to allow a key for any namespace, omit the namespaces option +signAllowedSignersFormatError=Cannot parse allowed signers file {0}, problem at line {1}: {2} +signAllowedSignersInvalidDate=Cannot parse valid-before or valid-after date {0} +signAllowedSignersLineFormat=Invalid line format +signAllowedSignersMultiple={0} is allowed only once +signAllowedSignersNoIdentities=Line has no identity patterns +signAllowedSignersPublicKeyParsing=Cannot parse public key {0} +signAllowedSignersUnterminatedQuote=Unterminated double quote signCertAlgorithmMismatch=Certificate of type {0} with CA key {1} uses an incompatible signature algorithm {2} signCertAlgorithmUnknown=Certificate with CA key {0} is signed with an unknown algorithm {1} signCertificateExpired=Expired certificate with CA key {0} signCertificateInvalid=Certificate signature does not match on certificate with CA key {0} +signCertificateNotForName=Certificate with CA key {0} does not apply for name ''{1}'' +signCertificateRevoked=Certificate with CA key {0} was revoked signCertificateTooEarly=Certificate with CA key {0} was not valid yet +signCertificateWithoutPrincipals=Certificate with CA key {0} has no principals; identities from gpg.ssh.allowedSignersFile: {1} signDefaultKeyEmpty=git.ssh.defaultKeyCommand {0} returned no key signDefaultKeyFailed=git.ssh.defaultKeyCommand {0} failed with exit code {1}\n{2} signDefaultKeyInterrupted=git.ssh.defaultKeyCommand {0} was interrupted +signGarbageAtEnd=SSH signature has extra bytes at the end +signInvalidAlgorithm=SSH signature has invalid signature algorithm {0} signInvalidKeyDSA=SSH signatures with DSA keys or certificates are not supported; use a different signing key. +signInvalidMagic=SSH signature does not start with "SSHSIG" +signInvalidNamespace=Namespace of SSH signature should be ''git'' but is ''{0}'' +signInvalidSignature=SSH signature is invalid: {0} +signInvalidVersion=Cannot verify signature with version {0} +signKeyExpired=Expired key used for SSH signature +signKeyRevoked=Key used for the SSH signature was revoked +signKeyTooEarly=Key used for the SSH signature was not valid yet +signKrlBlobLeftover=gpg.ssh.revocationFile has invalid blob section {0} with {1} leftover bytes +signKrlBlobLengthInvalid=gpg.ssh.revocationFile has invalid blob length {1} in section {0} +signKrlBlobLengthInvalidExpected=gpg.ssh.revocationFile has invalid blob length {1} (expected {2}) in section {0} +signKrlCaKeyLengthInvalid=gpg.ssh.revocationFile has invalid CA key length {0} in certificates section +signKrlCertificateLeftover=gpg.ssh.revocationFile has invalid certificates section with {0} leftover bytes +signKrlCertificateSubsectionLeftover=gpg.ssh.revocationFile has invalid certificates subsection with {0} leftover bytes +signKrlCertificateSubsectionLength=gpg.ssh.revocationFile has invalid certificates subsection length {0} +signKrlEmptyRange=gpg.ssh.revocationFile has an empty range of certificate serial numbers +signKrlInvalidBitSetLength=gpg.ssh.revocationFile has invalid certificate serial number bit set length {0} +signKrlInvalidKeyIdLength=gpg.ssh.revocationFile has invalid certificate key ID length {0} +signKrlInvalidMagic=gpg.ssh.revocationFile is not a binary OpenSSH key revocation list +signKrlInvalidReservedLength=gpg.ssh.revocationFile has an invalid reserved string length {0} +signKrlInvalidVersion=gpg.ssh.revocationFile: cannot read KRLs with FORMAT_VERSION {0} +signKrlNoCertificateSubsection=gpg.ssh.revocationFile has certificate section without subsections +signKrlSerialZero=gpg.ssh.revocationFile: certificate serial number zero cannot be revoked +signKrlShortRange=gpg.ssh.revocationFile: short certificate serial number range, need at least 8 more bytes, got only {0} +signKrlUnknownSection=gpg.ssh.revocationFile has an unknown section type {0} +signKrlUnknownSubsection=gpg.ssh.revocationFile has an unknown certificates subsection type {0} signLogFailure=SSH signature verification failed +signMismatchedSignatureAlgorithm=SSH signature made with an ''{0}'' key has incompatible signature algorithm ''{1}'' signNoAgent=No connector for ssh-agent found; maybe include org.eclipse.jgit.ssh.apache.agent in the application. +signNoPrincipalMatched=No principal matched in gpg.ssh.allowedSignersFile signNoPublicKey=No public key found with signing key {0} signNoSigningKey=Git config user.signingKey or gpg.ssh.defaultKeyCommand must be set for SSH signing. signNotUserCertificate=Certificate with CA key {0} used for the SSH signature is not a user certificate. @@ -147,4 +189,5 @@ signTooManyPrivateKeys=Private key file {0} must contain exactly one private key signTooManyPublicKeys=Public key file {0} must contain exactly one public key signUnknownHashAlgorithm=SSH Signature has an unknown hash algorithm {0} signUnknownSignatureAlgorithm=SSH Signature has an unknown signature algorithm {0} +signWrongNamespace=Key may not be used in namespace "{0}". unknownProxyProtocol=Ignoring unknown proxy protocol {0}
\ No newline at end of file diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/AllowedSigners.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/AllowedSigners.java new file mode 100644 index 0000000000..92cf1faec9 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/AllowedSigners.java @@ -0,0 +1,535 @@ +/* + * 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 java.io.BufferedReader; +import java.io.IOException; +import java.io.StreamCorruptedException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.security.PublicKey; +import java.text.MessageFormat; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.temporal.ChronoField; +import java.time.temporal.TemporalAccessor; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.TimeZone; +import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import org.apache.sshd.common.config.keys.KeyUtils; +import org.apache.sshd.common.config.keys.OpenSshCertificate; +import org.apache.sshd.common.config.keys.PublicKeyEntry; +import org.apache.sshd.common.util.io.ModifiableFileWatcher; +import org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile; +import org.eclipse.jgit.internal.transport.sshd.SshdText; +import org.eclipse.jgit.signing.ssh.VerificationException; +import org.eclipse.jgit.util.StringUtils; +import org.eclipse.jgit.util.SystemReader; + +/** + * Encapsulates the allowed signers handling. + */ +final class AllowedSigners extends ModifiableFileWatcher { + + private static final String CERT_AUTHORITY = "cert-authority"; //$NON-NLS-1$ + + private static final String NAMESPACES = "namespaces="; //$NON-NLS-1$ + + private static final String VALID_AFTER = "valid-after="; //$NON-NLS-1$ + + private static final String VALID_BEFORE = "valid-before="; //$NON-NLS-1$ + + private static final String SSH_KEY_PREFIX = "ssh-"; //$NON-NLS-1$ + + private static final DateTimeFormatter SSH_DATE_FORMAT = new DateTimeFormatterBuilder() + .appendValue(ChronoField.YEAR, 4) + .appendValue(ChronoField.MONTH_OF_YEAR, 2) + .appendValue(ChronoField.DAY_OF_MONTH, 2) + .optionalStart() + .appendValue(ChronoField.HOUR_OF_DAY, 2) + .appendValue(ChronoField.MINUTE_OF_HOUR, 2) + .optionalStart() + .appendValue(ChronoField.SECOND_OF_MINUTE, 2) + .toFormatter(Locale.ROOT); + + private static final Predicate<AllowedEntry> CERTIFICATES = AllowedEntry::isCA; + + private static final Predicate<AllowedEntry> PLAIN_KEYS = Predicate + .not(CERTIFICATES); + + static record AllowedEntry(String[] identities, boolean isCA, + String[] namespaces, Instant validAfter, Instant validBefore, + String key) { + // Empty + + @Override + public final boolean equals(Object any) { + if (this == any) { + return true; + } + if (any == null || !(any instanceof AllowedEntry)) { + return false; + } + AllowedEntry other = (AllowedEntry) any; + return isCA == other.isCA + && Arrays.equals(identities, other.identities) + && Arrays.equals(namespaces, other.namespaces) + && Objects.equals(validAfter, other.validAfter) + && Objects.equals(validBefore, other.validBefore) + && Objects.equals(key, other.key); + } + + @Override + public final int hashCode() { + int hash = Boolean.hashCode(isCA); + hash = hash * 31 + Arrays.hashCode(identities); + hash = hash * 31 + Arrays.hashCode(namespaces); + return hash * 31 + Objects.hash(validAfter, validBefore, key); + } + } + + private static record State(Map<String, List<AllowedEntry>> entries) { + // Empty + } + + private State state; + + public AllowedSigners(Path path) { + super(path); + state = new State(new HashMap<>()); + } + + public String isAllowed(PublicKey key, String namespace, String name, + Instant time) throws IOException, VerificationException { + State currentState = refresh(); + PublicKey keyToCheck = key; + if (key instanceof OpenSshCertificate certificate) { + AllowedEntry entry = find(currentState, certificate.getCaPubKey(), + namespace, name, time, CERTIFICATES); + if (entry != null) { + Collection<String> principals = certificate.getPrincipals(); + if (principals.isEmpty()) { + // According to the OpenSSH documentation, a certificate + // without principals is valid for anyone. + // + // See https://man.openbsd.org/ssh-keygen.1#CERTIFICATES . + // + // However, the same documentation also says that a name + // must match both the entry's patterns and be listed in the + // certificate's principals. + // + // See https://man.openbsd.org/ssh-keygen.1#ALLOWED_SIGNERS + // + // git/OpenSSH considers signatures made by such + // certificates untrustworthy. + String identities; + if (!StringUtils.isEmptyOrNull(name)) { + // The name must have matched entry.identities. + identities = name; + } else { + identities = Arrays.stream(entry.identities()) + .collect(Collectors.joining(",")); //$NON-NLS-1$ + } + throw new VerificationException(false, MessageFormat.format( + SshdText.get().signCertificateWithoutPrincipals, + KeyUtils.getFingerPrint(certificate.getCaPubKey()), + identities)); + } + if (!StringUtils.isEmptyOrNull(name)) { + if (!principals.contains(name)) { + throw new VerificationException(false, + MessageFormat.format(SshdText + .get().signCertificateNotForName, + KeyUtils.getFingerPrint( + certificate.getCaPubKey()), + name)); + } + return name; + } + // Filter the principals listed in the certificate by + // the patterns defined in the file. + Set<String> filtered = new LinkedHashSet<>(); + List<String> patterns = Arrays.asList(entry.identities()); + for (String principal : principals) { + if (OpenSshConfigFile.patternMatch(patterns, principal)) { + filtered.add(principal); + } + } + return filtered.stream().collect(Collectors.joining(",")); //$NON-NLS-1$ + } + // Certificate not found. git/OpenSSH considers this untrustworthy, + // even if the certified key itself might be listed. + return null; + // Alternative: go check for the certified key itself: + // keyToCheck = certificate.getCertPubKey(); + } + AllowedEntry entry = find(currentState, keyToCheck, namespace, name, + time, PLAIN_KEYS); + if (entry != null) { + if (!StringUtils.isEmptyOrNull(name)) { + // The name must have matched entry.identities. + return name; + } + // No name given, but we consider the key valid: report the + // identities. + return Arrays.stream(entry.identities()) + .collect(Collectors.joining(",")); //$NON-NLS-1$ + } + return null; + } + + private AllowedEntry find(State current, PublicKey key, + String namespace, String name, Instant time, + Predicate<AllowedEntry> filter) + throws VerificationException { + String k = PublicKeyEntry.toString(key); + VerificationException v = null; + List<AllowedEntry> candidates = current.entries().get(k); + if (candidates == null) { + return null; + } + for (AllowedEntry entry : candidates) { + if (!filter.test(entry)) { + continue; + } + if (name != null && !OpenSshConfigFile + .patternMatch(Arrays.asList(entry.identities()), name)) { + continue; + } + if (entry.namespaces() != null) { + if (!OpenSshConfigFile.patternMatch( + Arrays.asList(entry.namespaces()), + namespace)) { + if (v == null) { + v = new VerificationException(false, + MessageFormat.format( + SshdText.get().signWrongNamespace, + KeyUtils.getFingerPrint(key), + namespace)); + } + continue; + } + } + if (time != null) { + if (entry.validAfter() != null + && time.isBefore(entry.validAfter())) { + if (v == null) { + v = new VerificationException(true, + MessageFormat.format( + SshdText.get().signKeyTooEarly, + KeyUtils.getFingerPrint(key))); + } + continue; + } else if (entry.validBefore() != null + && time.isAfter(entry.validBefore())) { + if (v == null) { + v = new VerificationException(true, + MessageFormat.format( + SshdText.get().signKeyTooEarly, + KeyUtils.getFingerPrint(key))); + } + continue; + } + } + return entry; + } + if (v != null) { + throw v; + } + return null; + } + + private synchronized State refresh() throws IOException { + if (checkReloadRequired()) { + updateReloadAttributes(); + try { + state = reload(getPath()); + } catch (NoSuchFileException e) { + // File disappeared + resetReloadAttributes(); + state = new State(new HashMap<>()); + } + } + return state; + } + + private static State reload(Path path) throws IOException { + Map<String, List<AllowedEntry>> entries = new HashMap<>(); + try (BufferedReader r = Files.newBufferedReader(path, + StandardCharsets.UTF_8)) { + String line; + for (int lineNumber = 1;; lineNumber++) { + line = r.readLine(); + if (line == null) { + break; + } + line = line.strip(); + try { + AllowedEntry entry = parseLine(line); + if (entry != null) { + entries.computeIfAbsent(entry.key(), + k -> new ArrayList<>()).add(entry); + } + } catch (IOException | RuntimeException e) { + throw new IOException(MessageFormat.format( + SshdText.get().signAllowedSignersFormatError, path, + Integer.toString(lineNumber), line), e); + } + } + } + return new State(entries); + } + + private static boolean matches(String src, String other, int offset) { + return src.regionMatches(true, offset, other, 0, other.length()); + } + + // Things below have package visibility for testing. + + static AllowedEntry parseLine(String line) + throws IOException { + if (StringUtils.isEmptyOrNull(line) || line.charAt(0) == '#') { + return null; + } + int length = line.length(); + if ((matches(line, CERT_AUTHORITY, 0) + && CERT_AUTHORITY.length() < length + && Character.isWhitespace(line.charAt(CERT_AUTHORITY.length()))) + || matches(line, NAMESPACES, 0) + || matches(line, VALID_AFTER, 0) + || matches(line, VALID_BEFORE, 0) + || matches(line, SSH_KEY_PREFIX, 0)) { + throw new StreamCorruptedException( + SshdText.get().signAllowedSignersNoIdentities); + } + int i = 0; + while (i < length && !Character.isWhitespace(line.charAt(i))) { + i++; + } + if (i >= length) { + throw new StreamCorruptedException(SshdText.get().signAllowedSignersLineFormat); + } + String[] identities = line.substring(0, i).split(","); //$NON-NLS-1$ + if (Arrays.stream(identities).anyMatch(String::isEmpty)) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signAllowedSignersEmptyIdentity, + line.substring(0, i))); + } + // Parse the options + i++; + boolean isCA = false; + List<String> namespaces = null; + Instant validAfter = null; + Instant validBefore = null; + while (i < length) { + // Skip whitespace + if (Character.isSpaceChar(line.charAt(i))) { + i++; + continue; + } + if (matches(line, CERT_AUTHORITY, i)) { + i += CERT_AUTHORITY.length(); + isCA = true; + if (!Character.isWhitespace(line.charAt(i))) { + throw new StreamCorruptedException(SshdText.get().signAllowedSignersCertAuthorityError); + } + i++; + } else if (matches(line, NAMESPACES, i)) { + if (namespaces != null) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signAllowedSignersMultiple, + NAMESPACES)); + } + i += NAMESPACES.length(); + Dequoted parsed = dequote(line, i); + i = parsed.after(); + String ns = parsed.value(); + String[] items = ns.split(","); //$NON-NLS-1$ + namespaces = new ArrayList<>(items.length); + for (int j = 0; j < items.length; j++) { + String n = items[j].strip(); + if (!n.isEmpty()) { + namespaces.add(n); + } + } + if (namespaces.isEmpty()) { + throw new StreamCorruptedException( + SshdText.get().signAllowedSignersEmptyNamespaces); + } + } else if (matches(line, VALID_AFTER, i)) { + if (validAfter != null) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signAllowedSignersMultiple, + VALID_AFTER)); + } + i += VALID_AFTER.length(); + Dequoted parsed = dequote(line, i); + i = parsed.after(); + validAfter = parseDate(parsed.value()); + } else if (matches(line, VALID_BEFORE, i)) { + if (validBefore != null) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signAllowedSignersMultiple, + VALID_BEFORE)); + } + i += VALID_BEFORE.length(); + Dequoted parsed = dequote(line, i); + i = parsed.after(); + validBefore = parseDate(parsed.value()); + } else { + break; + } + } + // Now we should be at the key + String key = parsePublicKey(line, i); + return new AllowedEntry(identities, isCA, + namespaces == null ? null : namespaces.toArray(new String[0]), + validAfter, validBefore, key); + } + + static String parsePublicKey(String s, int from) + throws StreamCorruptedException { + int i = from; + int length = s.length(); + while (i < length && Character.isWhitespace(s.charAt(i))) { + i++; + } + if (i >= length) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signAllowedSignersPublicKeyParsing, + s.substring(from))); + } + int start = i; + while (i < length && !Character.isWhitespace(s.charAt(i))) { + i++; + } + if (i >= length) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signAllowedSignersPublicKeyParsing, + s.substring(start))); + } + int endOfKeyType = i; + i = endOfKeyType + 1; + while (i < length && Character.isWhitespace(s.charAt(i))) { + i++; + } + int startOfKey = i; + while (i < length && !Character.isWhitespace(s.charAt(i))) { + i++; + } + if (i == startOfKey) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signAllowedSignersPublicKeyParsing, + s.substring(start))); + } + String keyType = s.substring(start, endOfKeyType); + if (!keyType.startsWith(SSH_KEY_PREFIX)) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signAllowedSignersPublicKeyParsing, + s.substring(start))); + } + return keyType + ' ' + s.substring(startOfKey, i); + } + + static Instant parseDate(String input) { + // Allowed formats are YYYYMMDD[Z] or YYYYMMDDHHMM[SS][Z]. If 'Z', it's + // UTC, otherwise local time. + String timeSpec = input; + int length = input.length(); + if (length < 8) { + throw new IllegalArgumentException(MessageFormat.format( + SshdText.get().signAllowedSignersInvalidDate, input)); + } + boolean isUTC = false; + if (timeSpec.charAt(length - 1) == 'Z') { + isUTC = true; + timeSpec = timeSpec.substring(0, length - 1); + } + LocalDateTime time; + TemporalAccessor temporalAccessor = SSH_DATE_FORMAT.parseBest(timeSpec, + LocalDateTime::from, LocalDate::from); + if (temporalAccessor instanceof LocalDateTime) { + time = (LocalDateTime) temporalAccessor; + } else { + time = ((LocalDate) temporalAccessor).atStartOfDay(); + } + if (isUTC) { + return time.atOffset(ZoneOffset.UTC).toInstant(); + } + TimeZone tz = SystemReader.getInstance().getTimeZone(); + // Since there are a few TimeZone IDs that are not recognized by ZoneId, + // use offsets. + return time.atOffset(ZoneOffset.ofTotalSeconds( + (int) TimeUnit.MILLISECONDS.toSeconds(tz.getRawOffset()))) + .toInstant(); + } + + // OpenSSH uses the backslash *only* to quote the double-quote. + static Dequoted dequote(String line, int from) { + int length = line.length(); + int i = from; + if (line.charAt(i) == '"') { + boolean quoted = false; + i++; + StringBuilder b = new StringBuilder(); + while (i < length) { + char ch = line.charAt(i); + if (ch == '"') { + if (quoted) { + b.append(ch); + quoted = false; + } else { + break; + } + } else if (ch == '\\') { + quoted = true; + } else { + if (quoted) { + b.append('\\'); + } + b.append(ch); + quoted = false; + } + i++; + } + if (i >= length) { + throw new IllegalArgumentException( + SshdText.get().signAllowedSignersUnterminatedQuote); + } + return new Dequoted(b.toString(), i + 1); + } + while (i < length && !Character.isWhitespace(line.charAt(i))) { + i++; + } + return new Dequoted(line.substring(from, i), i); + } + + static record Dequoted(String value, int after) { + // Empty + } +} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/OpenSshBinaryKrl.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/OpenSshBinaryKrl.java new file mode 100644 index 0000000000..46518d8c84 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/OpenSshBinaryKrl.java @@ -0,0 +1,490 @@ +/* + * 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 java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.StreamCorruptedException; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.sshd.common.config.keys.OpenSshCertificate; +import org.apache.sshd.common.util.buffer.BufferUtils; +import org.apache.sshd.common.util.buffer.ByteArrayBuffer; +import org.eclipse.jgit.annotations.NonNull; +import org.eclipse.jgit.api.errors.JGitInternalException; +import org.eclipse.jgit.internal.transport.sshd.SshdText; +import org.eclipse.jgit.util.IO; +import org.eclipse.jgit.util.StringUtils; + +/** + * An implementation of OpenSSH binary format key revocation lists (KRLs). + * + * @see <a href= + * "https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.krl">PROTOCOL.krl</a> + */ +class OpenSshBinaryKrl { + + /** + * The "magic" bytes at the start of an OpenSSH binary KRL. + */ + static final byte[] MAGIC = { 'S', 'S', 'H', 'K', 'R', 'L', '\n', 0 }; + + private static final int FORMAT_VERSION = 1; + + private static final int SECTION_CERTIFICATES = 1; + + private static final int SECTION_KEY = 2; + + private static final int SECTION_SHA1 = 3; + + private static final int SECTION_SIGNATURE = 4; // Skipped + + private static final int SECTION_SHA256 = 5; + + private static final int SECTION_EXTENSION = 255; // Skipped + + // Certificates + + private static final int CERT_SERIAL_LIST = 0x20; + + private static final int CERT_SERIAL_RANGES = 0x21; + + private static final int CERT_SERIAL_BITS = 0x22; + + private static final int CERT_KEY_IDS = 0x23; + + private static final int CERT_EXTENSIONS = 0x39; // Skipped + + private final Map<Blob, CertificateRevocation> certificates = new HashMap<>(); + + private static class CertificateRevocation { + + final SerialRangeSet ranges = new SerialRangeSet(); + + final Set<String> keyIds = new HashSet<>(); + } + + // Plain keys + + /** + * A byte array that can be used as a key in a {@link Map} or {@link Set}. + * {@link #equals(Object)} and {@link #hashCode()} are based on the content. + * + * @param blob + * the array to wrap + */ + private static record Blob(byte[] blob) { + + @Override + public final boolean equals(Object any) { + if (this == any) { + return true; + } + if (any == null || !(any instanceof Blob)) { + return false; + } + Blob other = (Blob) any; + return Arrays.equals(blob, other.blob); + } + + @Override + public final int hashCode() { + return Arrays.hashCode(blob); + } + } + + private final Set<Blob> blobs = new HashSet<>(); + + private final Set<Blob> sha1 = new HashSet<>(); + + private final Set<Blob> sha256 = new HashSet<>(); + + private OpenSshBinaryKrl() { + // No public instantiation, use load(InputStream, boolean) instead. + } + + /** + * Tells whether the given key has been revoked. + * + * @param key + * {@link PublicKey} to check + * @return {@code true} if the key was revoked, {@code false} otherwise + */ + boolean isRevoked(PublicKey key) { + if (key instanceof OpenSshCertificate certificate) { + if (certificates.isEmpty()) { + return false; + } + // These apply to all certificates + if (isRevoked(certificate, certificates.get(null))) { + return true; + } + if (isRevoked(certificate, + certificates.get(blob(certificate.getCaPubKey())))) { + return true; + } + // Keys themselves are checked in OpenSshKrl. + return false; + } + if (!blobs.isEmpty() && blobs.contains(blob(key))) { + return true; + } + if (!sha256.isEmpty() && sha256.contains(hash("SHA256", key))) { //$NON-NLS-1$ + return true; + } + if (!sha1.isEmpty() && sha1.contains(hash("SHA1", key))) { //$NON-NLS-1$ + return true; + } + return false; + } + + private boolean isRevoked(OpenSshCertificate certificate, + CertificateRevocation revocations) { + if (revocations == null) { + return false; + } + String id = certificate.getId(); + if (!StringUtils.isEmptyOrNull(id) && revocations.keyIds.contains(id)) { + return true; + } + long serial = certificate.getSerial(); + if (serial != 0 && revocations.ranges.contains(serial)) { + return true; + } + return false; + } + + private Blob blob(PublicKey key) { + ByteArrayBuffer buf = new ByteArrayBuffer(); + buf.putRawPublicKey(key); + return new Blob(buf.getCompactData()); + } + + private Blob hash(String algorithm, PublicKey key) { + ByteArrayBuffer buf = new ByteArrayBuffer(); + buf.putRawPublicKey(key); + try { + return new Blob(MessageDigest.getInstance(algorithm) + .digest(buf.getCompactData())); + } catch (NoSuchAlgorithmException e) { + throw new JGitInternalException(e.getMessage(), e); + } + } + + /** + * Loads a binary KRL from the given stream. + * + * @param in + * {@link InputStream} to read from + * @param magicSkipped + * whether the {@link #MAGIC} bytes at the beginning have already + * been skipped + * @return a new {@link OpenSshBinaryKrl}. + * @throws IOException + * if the stream cannot be read as an OpenSSH binary KRL + */ + @NonNull + static OpenSshBinaryKrl load(InputStream in, boolean magicSkipped) + throws IOException { + if (!magicSkipped) { + byte[] magic = new byte[MAGIC.length]; + IO.readFully(in, magic); + if (!Arrays.equals(magic, MAGIC)) { + throw new StreamCorruptedException( + SshdText.get().signKrlInvalidMagic); + } + } + skipHeader(in); + return load(in); + } + + private static long getUInt(InputStream in) throws IOException { + byte[] buf = new byte[Integer.BYTES]; + IO.readFully(in, buf); + return BufferUtils.getUInt(buf); + } + + private static long getLong(InputStream in) throws IOException { + byte[] buf = new byte[Long.BYTES]; + IO.readFully(in, buf); + return BufferUtils.getLong(buf, 0, Long.BYTES); + } + + private static void skipHeader(InputStream in) throws IOException { + long version = getUInt(in); + if (version != FORMAT_VERSION) { + throw new StreamCorruptedException( + MessageFormat.format(SshdText.get().signKrlInvalidVersion, + Long.valueOf(version))); + } + // krl_version, generated_date, flags (none defined in version 1) + in.skip(24); + in.skip(getUInt(in)); // reserved + in.skip(getUInt(in)); // comment + } + + private static OpenSshBinaryKrl load(InputStream in) throws IOException { + OpenSshBinaryKrl krl = new OpenSshBinaryKrl(); + for (;;) { + int sectionType = in.read(); + if (sectionType < 0) { + break; // EOF + } + switch (sectionType) { + case SECTION_CERTIFICATES: + readCertificates(krl.certificates, in, getUInt(in)); + break; + case SECTION_KEY: + readBlobs("explicit_keys", krl.blobs, in, getUInt(in), 0); //$NON-NLS-1$ + break; + case SECTION_SHA1: + readBlobs("fingerprint_sha1", krl.sha1, in, getUInt(in), 20); //$NON-NLS-1$ + break; + case SECTION_SIGNATURE: + // Unsupported as of OpenSSH 9.4. It even refuses to load such + // KRLs. Just skip it. + in.skip(getUInt(in)); + break; + case SECTION_SHA256: + readBlobs("fingerprint_sha256", krl.sha256, in, getUInt(in), //$NON-NLS-1$ + 32); + break; + case SECTION_EXTENSION: + // No extensions are defined for version 1 KRLs. + in.skip(getUInt(in)); + break; + default: + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signKrlUnknownSection, + Integer.valueOf(sectionType))); + } + } + return krl; + } + + private static void readBlobs(String sectionName, Set<Blob> blobs, + InputStream in, long sectionLength, long expectedBlobLength) + throws IOException { + while (sectionLength >= Integer.BYTES) { + // Read blobs. + long blobLength = getUInt(in); + sectionLength -= Integer.BYTES; + if (blobLength > sectionLength) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signKrlBlobLengthInvalid, sectionName, + Long.valueOf(blobLength))); + } + if (expectedBlobLength != 0 && blobLength != expectedBlobLength) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signKrlBlobLengthInvalidExpected, + sectionName, Long.valueOf(blobLength), + Long.valueOf(expectedBlobLength))); + } + byte[] blob = new byte[(int) blobLength]; + IO.readFully(in, blob); + sectionLength -= blobLength; + blobs.add(new Blob(blob)); + } + if (sectionLength != 0) { + throw new StreamCorruptedException( + MessageFormat.format(SshdText.get().signKrlBlobLeftover, + sectionName, Long.valueOf(sectionLength))); + } + } + + private static void readCertificates(Map<Blob, CertificateRevocation> certs, + InputStream in, long sectionLength) throws IOException { + long keyLength = getUInt(in); + sectionLength -= Integer.BYTES; + if (keyLength > sectionLength) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signKrlCaKeyLengthInvalid, + Long.valueOf(keyLength))); + } + Blob key = null; + if (keyLength > 0) { + byte[] blob = new byte[(int) keyLength]; + IO.readFully(in, blob); + key = new Blob(blob); + sectionLength -= keyLength; + } + CertificateRevocation rev = certs.computeIfAbsent(key, + k -> new CertificateRevocation()); + long reservedLength = getUInt(in); + sectionLength -= Integer.BYTES; + if (reservedLength > sectionLength) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signKrlCaKeyLengthInvalid, + Long.valueOf(reservedLength))); + } + in.skip(reservedLength); + sectionLength -= reservedLength; + if (sectionLength == 0) { + throw new StreamCorruptedException( + SshdText.get().signKrlNoCertificateSubsection); + } + while (sectionLength > 0) { + int subSection = in.read(); + if (subSection < 0) { + throw new EOFException(); + } + sectionLength--; + if (sectionLength < Integer.BYTES) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signKrlCertificateLeftover, + Long.valueOf(sectionLength))); + } + long subLength = getUInt(in); + sectionLength -= Integer.BYTES; + if (subLength > sectionLength) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signKrlCertificateSubsectionLength, + Long.valueOf(subLength))); + } + if (subLength > 0) { + switch (subSection) { + case CERT_SERIAL_LIST: + readSerials(rev.ranges, in, subLength, false); + break; + case CERT_SERIAL_RANGES: + readSerials(rev.ranges, in, subLength, true); + break; + case CERT_SERIAL_BITS: + readSerialBitSet(rev.ranges, in, subLength); + break; + case CERT_KEY_IDS: + readIds(rev.keyIds, in, subLength); + break; + case CERT_EXTENSIONS: + in.skip(subLength); + break; + default: + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signKrlUnknownSubsection, + Long.valueOf(subSection))); + } + } + sectionLength -= subLength; + } + } + + private static void readSerials(SerialRangeSet set, InputStream in, + long length, boolean ranges) throws IOException { + while (length >= Long.BYTES) { + long a = getLong(in); + length -= Long.BYTES; + if (a == 0) { + throw new StreamCorruptedException( + SshdText.get().signKrlSerialZero); + } + if (!ranges) { + set.add(a); + continue; + } + if (length < Long.BYTES) { + throw new StreamCorruptedException( + MessageFormat.format(SshdText.get().signKrlShortRange, + Long.valueOf(length))); + } + long b = getLong(in); + length -= Long.BYTES; + if (Long.compareUnsigned(a, b) > 0) { + throw new StreamCorruptedException( + SshdText.get().signKrlEmptyRange); + } + set.add(a, b); + } + if (length != 0) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signKrlCertificateSubsectionLeftover, + Long.valueOf(length))); + } + } + + private static void readSerialBitSet(SerialRangeSet set, InputStream in, + long subLength) throws IOException { + while (subLength > 0) { + if (subLength < Long.BYTES) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signKrlCertificateSubsectionLeftover, + Long.valueOf(subLength))); + } + long base = getLong(in); + subLength -= Long.BYTES; + if (subLength < Integer.BYTES) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signKrlCertificateSubsectionLeftover, + Long.valueOf(subLength))); + } + long setLength = getUInt(in); + subLength -= Integer.BYTES; + if (setLength == 0 || setLength > subLength) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signKrlInvalidBitSetLength, + Long.valueOf(setLength))); + } + // Now process the bits. Note that the mpint is stored MSB first. + // + // We set individual serial numbers (one for each set bit) and let + // the SerialRangeSet take care of coalescing for successive runs + // of set bits. + int n = (int) setLength; + for (int i = n - 1; i >= 0; i--) { + int b = in.read(); + if (b < 0) { + throw new EOFException(); + } else if (b == 0) { + // Stored as an mpint: may have leading zero bytes (actually + // at most one; if the high bit of the first byte is set). + continue; + } + for (int bit = 0, + mask = 1; bit < Byte.SIZE; bit++, mask <<= 1) { + if ((b & mask) != 0) { + set.add(base + (i * Byte.SIZE) + bit); + } + } + } + subLength -= setLength; + } + } + + private static void readIds(Set<String> ids, InputStream in, long subLength) + throws IOException { + while (subLength >= Integer.BYTES) { + long length = getUInt(in); + subLength -= Integer.BYTES; + if (length > subLength) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signKrlInvalidKeyIdLength, + Long.valueOf(length))); + } + byte[] bytes = new byte[(int) length]; + IO.readFully(in, bytes); + ids.add(new String(bytes, StandardCharsets.UTF_8)); + subLength -= length; + } + if (subLength != 0) { + throw new StreamCorruptedException(MessageFormat.format( + SshdText.get().signKrlCertificateSubsectionLeftover, + Long.valueOf(subLength))); + } + } +} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/OpenSshKrl.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/OpenSshKrl.java new file mode 100644 index 0000000000..7993def90c --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/OpenSshKrl.java @@ -0,0 +1,120 @@ +/* + * 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 java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.security.PublicKey; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.apache.sshd.common.config.keys.OpenSshCertificate; +import org.apache.sshd.common.config.keys.PublicKeyEntry; +import org.apache.sshd.common.util.io.ModifiableFileWatcher; +import org.eclipse.jgit.util.IO; + +/** + * An implementation of an OpenSSH key revocation list (KRL), either a binary + * KRL or a simple list of public keys. + */ +class OpenSshKrl extends ModifiableFileWatcher { + + private static record State(Set<String> keys, OpenSshBinaryKrl krl) { + // Empty + } + + private State state; + + public OpenSshKrl(Path path) { + super(path); + state = new State(Set.of(), null); + } + + public boolean isRevoked(PublicKey key) throws IOException { + State current = refresh(); + return isRevoked(current, key); + } + + private boolean isRevoked(State current, PublicKey key) { + if (key instanceof OpenSshCertificate cert) { + OpenSshBinaryKrl krl = current.krl(); + if (krl != null && krl.isRevoked(cert)) { + return true; + } + if (isRevoked(current, cert.getCaPubKey()) + || isRevoked(current, cert.getCertPubKey())) { + return true; + } + return false; + } + OpenSshBinaryKrl krl = current.krl(); + if (krl != null) { + return krl.isRevoked(key); + } + return current.keys().contains(PublicKeyEntry.toString(key)); + } + + private synchronized State refresh() throws IOException { + if (checkReloadRequired()) { + updateReloadAttributes(); + try { + state = reload(getPath()); + } catch (NoSuchFileException e) { + // File disappeared + resetReloadAttributes(); + state = new State(Set.of(), null); + } + } + return state; + } + + private static State reload(Path path) throws IOException { + try (BufferedInputStream in = new BufferedInputStream( + Files.newInputStream(path))) { + byte[] magic = new byte[OpenSshBinaryKrl.MAGIC.length]; + in.mark(magic.length); + IO.readFully(in, magic); + if (Arrays.equals(magic, OpenSshBinaryKrl.MAGIC)) { + return new State(null, OpenSshBinaryKrl.load(in, true)); + } + // Otherwise try reading it textually + in.reset(); + return loadTextKrl(in); + } + } + + private static State loadTextKrl(InputStream in) throws IOException { + Set<String> keys = new HashSet<>(); + try (BufferedReader r = new BufferedReader( + new InputStreamReader(in, StandardCharsets.UTF_8))) { + String line; + for (;;) { + line = r.readLine(); + if (line == null) { + break; + } + line = line.strip(); + if (line.isEmpty() || line.charAt(0) == '#') { + continue; + } + keys.add(AllowedSigners.parsePublicKey(line, 0)); + } + } + return new State(keys, null); + } +} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/OpenSshSigningKeyDatabase.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/OpenSshSigningKeyDatabase.java new file mode 100644 index 0000000000..aa26886839 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/OpenSshSigningKeyDatabase.java @@ -0,0 +1,161 @@ +/* + * 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 java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.security.PublicKey; +import java.time.Instant; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +import org.eclipse.jgit.annotations.NonNull; +import org.eclipse.jgit.lib.GpgConfig; +import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.signing.ssh.CachingSigningKeyDatabase; +import org.eclipse.jgit.signing.ssh.VerificationException; +import org.eclipse.jgit.util.FS; +import org.eclipse.jgit.util.StringUtils; + +/** + * A {@link CachingSigningKeyDatabase} using the OpenSSH allowed signers file + * and the OpenSSH key revocation list. + */ +public class OpenSshSigningKeyDatabase implements CachingSigningKeyDatabase { + + // Keep caches of allowed signers and KRLs. Cache by canonical path. + + private static final int DEFAULT_CACHE_SIZE = 5; + + private AtomicInteger cacheSize = new AtomicInteger(DEFAULT_CACHE_SIZE); + + private class LRU<K, V> extends LinkedHashMap<K, V> { + + private static final long serialVersionUID = 1L; + + LRU() { + super(DEFAULT_CACHE_SIZE, 0.75f, true); + } + + @Override + protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) { + return size() > cacheSize.get(); + } + } + + private final HashMap<Path, AllowedSigners> allowedSigners = new LRU<>(); + + private final HashMap<Path, OpenSshKrl> revocations = new LRU<>(); + + @Override + public boolean isRevoked(Repository repository, GpgConfig config, + PublicKey key) throws IOException { + String fileName = config.getSshRevocationFile(); + if (StringUtils.isEmptyOrNull(fileName)) { + return false; + } + File file = getFile(repository, fileName); + OpenSshKrl revocationList; + synchronized (revocations) { + revocationList = revocations.computeIfAbsent(file.toPath(), + OpenSshKrl::new); + } + return revocationList.isRevoked(key); + } + + @Override + public String isAllowed(Repository repository, GpgConfig config, + PublicKey key, String namespace, PersonIdent ident) + throws IOException, VerificationException { + String fileName = config.getSshAllowedSignersFile(); + if (StringUtils.isEmptyOrNull(fileName)) { + // No file configured. Git would error out. + return null; + } + File file = getFile(repository, fileName); + AllowedSigners allowed; + synchronized (allowedSigners) { + allowed = allowedSigners.computeIfAbsent(file.toPath(), + AllowedSigners::new); + } + Instant gitTime = null; + if (ident != null) { + gitTime = ident.getWhenAsInstant(); + } + return allowed.isAllowed(key, namespace, null, gitTime); + } + + private File getFile(@NonNull Repository repository, String fileName) + throws IOException { + File file; + if (fileName.startsWith("~/") //$NON-NLS-1$ + || fileName.startsWith('~' + File.separator)) { + file = FS.DETECTED.resolve(FS.DETECTED.userHome(), + fileName.substring(2)); + } else { + file = new File(fileName); + if (!file.isAbsolute()) { + file = new File(repository.getWorkTree(), fileName); + } + } + return file.getCanonicalFile(); + } + + @Override + public int getCacheSize() { + return cacheSize.get(); + } + + @Override + public void setCacheSize(int size) { + if (size > 0) { + cacheSize.set(size); + pruneCache(size); + } + } + + private void pruneCache(int size) { + prune(allowedSigners, size); + prune(revocations, size); + } + + private void prune(HashMap<?, ?> map, int size) { + synchronized (map) { + if (map.size() <= size) { + return; + } + Iterator<?> iter = map.entrySet().iterator(); + int i = 0; + while (iter.hasNext() && i < size) { + iter.next(); + i++; + } + while (iter.hasNext()) { + iter.next(); + iter.remove(); + } + } + } + + @Override + public void clearCache() { + synchronized (allowedSigners) { + allowedSigners.clear(); + } + synchronized (revocations) { + revocations.clear(); + } + } + +} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SerialRangeSet.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SerialRangeSet.java new file mode 100644 index 0000000000..6a0cec8821 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SerialRangeSet.java @@ -0,0 +1,138 @@ +/* + * 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 java.util.SortedMap; +import java.util.TreeMap; + +import org.eclipse.jgit.internal.transport.sshd.SshdText; + +/** + * Encapsulates the storage for revoked certificate serial numbers. + */ +class SerialRangeSet { + + /** + * A range of certificate serial numbers [from..to], i.e., with both range + * limits included. + */ + private interface SerialRange { + + long from(); + + long to(); + } + + private static record Singleton(long from) implements SerialRange { + + @Override + public long to() { + return from; + } + } + + private static record Range(long from, long to) implements SerialRange { + + public Range(long from, long to) { + if (Long.compareUnsigned(from, to) > 0) { + throw new IllegalArgumentException( + SshdText.get().signKrlEmptyRange); + } + this.from = from; + this.to = to; + } + } + + // We use the same data structure as OpenSSH,; basically a + // TreeSet<SerialRange> of mutable elements. To get "mutability", the set is + // implemented as a TreeMap with the same elements as keys and values. + // + // get(x) will return null if none of the serial numbers in the range x is + // in the set, and some range (partially) overlapping with x otherwise. + // + // containsKey will return true if there is any (partially) overlapping + // range in the TreeMap. + private final TreeMap<SerialRange, SerialRange> ranges = new TreeMap<>( + SerialRangeSet::compare); + + private static int compare(SerialRange a, SerialRange b) { + // Return == if they overlap + if (Long.compareUnsigned(a.to(), b.from()) >= 0 + && Long.compareUnsigned(a.from(), b.to()) <= 0) { + return 0; + } + return Long.compareUnsigned(a.from(), b.from()); + } + + void add(long serial) { + add(ranges, new Singleton(serial)); + } + + void add(long from, long to) { + add(ranges, new Range(from, to)); + } + + boolean contains(long serial) { + return ranges.containsKey(new Singleton(serial)); + } + + int size() { + return ranges.size(); + } + + boolean isEmpty() { + return ranges.isEmpty(); + } + + private static void add(TreeMap<SerialRange, SerialRange> ranges, + SerialRange newRange) { + for (;;) { + SerialRange existing = ranges.get(newRange); + if (existing == null) { + break; + } + if (Long.compareUnsigned(existing.from(), newRange.from()) <= 0 + && Long.compareUnsigned(existing.to(), + newRange.to()) >= 0) { + // newRange completely contained in existing + return; + } + ranges.remove(existing); + long newFrom = newRange.from(); + if (Long.compareUnsigned(existing.from(), newFrom) < 0) { + newFrom = existing.from(); + } + long newTo = newRange.to(); + if (Long.compareUnsigned(existing.to(), newTo) > 0) { + newTo = existing.to(); + } + newRange = new Range(newFrom, newTo); + } + // No overlapping range exists: check for coalescing with the + // previous/next range + SortedMap<SerialRange, SerialRange> head = ranges.headMap(newRange); + if (!head.isEmpty()) { + SerialRange prev = head.lastKey(); + if (newRange.from() - prev.to() == 1) { + ranges.remove(prev); + newRange = new Range(prev.from(), newRange.to()); + } + } + SortedMap<SerialRange, SerialRange> tail = ranges.tailMap(newRange); + if (!tail.isEmpty()) { + SerialRange next = tail.firstKey(); + if (next.from() - newRange.to() == 1) { + ranges.remove(next); + newRange = new Range(newRange.from(), next.to()); + } + } + ranges.put(newRange, newRange); + } +} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SigningDatabase.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SigningDatabase.java new file mode 100644 index 0000000000..e2e1a36840 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SigningDatabase.java @@ -0,0 +1,59 @@ +/* + * 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 org.eclipse.jgit.signing.ssh.CachingSigningKeyDatabase; +import org.eclipse.jgit.signing.ssh.SigningKeyDatabase; + +/** + * A global {@link SigningKeyDatabase} instance. + */ +public final class SigningDatabase { + + private static SigningKeyDatabase INSTANCE = new OpenSshSigningKeyDatabase(); + + private SigningDatabase() { + // No instantiation + } + + /** + * Obtains the current instance. + * + * @return the global {@link SigningKeyDatabase} + */ + public static synchronized SigningKeyDatabase getInstance() { + return INSTANCE; + } + + /** + * Sets the global {@link SigningKeyDatabase}. + * + * @param database + * to set; if {@code null} a default database using the OpenSSH + * allowed signers file and the OpenSSH revocation list mechanism + * is used. + * @return the previously set {@link SigningKeyDatabase} + */ + public static synchronized SigningKeyDatabase setInstance( + SigningKeyDatabase database) { + SigningKeyDatabase previous = INSTANCE; + if (database != INSTANCE) { + if (INSTANCE instanceof CachingSigningKeyDatabase caching) { + caching.clearCache(); + } + if (database == null) { + INSTANCE = new OpenSshSigningKeyDatabase(); + } else { + INSTANCE = database; + } + } + return previous; + } +} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SshSignatureVerifier.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SshSignatureVerifier.java new file mode 100644 index 0000000000..76be340bc7 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SshSignatureVerifier.java @@ -0,0 +1,319 @@ +/* + * 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 java.io.IOException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.text.MessageFormat; +import java.time.Instant; +import java.util.Date; +import java.util.Locale; + +import org.apache.sshd.common.config.keys.KeyUtils; +import org.apache.sshd.common.config.keys.OpenSshCertificate; +import org.apache.sshd.common.keyprovider.KeyPairProvider; +import org.apache.sshd.common.signature.BuiltinSignatures; +import org.apache.sshd.common.signature.Signature; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.buffer.ByteArrayBuffer; +import org.eclipse.jgit.internal.transport.sshd.SshdText; +import org.eclipse.jgit.lib.GpgConfig; +import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.SignatureVerifier; +import org.eclipse.jgit.signing.ssh.CachingSigningKeyDatabase; +import org.eclipse.jgit.signing.ssh.SigningKeyDatabase; +import org.eclipse.jgit.signing.ssh.VerificationException; +import org.eclipse.jgit.util.Base64; +import org.eclipse.jgit.util.RawParseUtils; +import org.eclipse.jgit.util.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A {@link SignatureVerifier} for SSH signatures. + */ +public class SshSignatureVerifier implements SignatureVerifier { + + private static final Logger LOG = LoggerFactory + .getLogger(SshSignatureVerifier.class); + + private static final byte[] OBJECT = { 'o', 'b', 'j', 'e', 'c', 't', ' ' }; + + private static final byte[] TREE = { 't', 'r', 'e', 'e', ' ' }; + + private static final byte[] TYPE = { 't', 'y', 'p', 'e', ' ' }; + + @Override + public String getName() { + return "ssh"; //$NON-NLS-1$ + } + + @Override + public SignatureVerification verify(Repository repository, GpgConfig config, + byte[] data, byte[] signatureData) throws IOException { + // This is a bit stupid. SSH signatures do not store a signer, nor a + // time the signature was created. So we must use the committer's or + // tagger's PersonIdent, but here we have neither. But... if we see + // that the data is a commit or tag, then we can parse the PersonIdent + // from the data. + // + // Note: we cannot assume that absent a principal recorded in the + // allowedSignersFile or on a certificate that the key used to sign the + // commit belonged to the committer. + PersonIdent gitIdentity = getGitIdentity(data); + Date signatureDate = null; + Instant signatureInstant = null; + if (gitIdentity != null) { + signatureDate = gitIdentity.getWhen(); + signatureInstant = gitIdentity.getWhenAsInstant(); + } + + TrustLevel trust = TrustLevel.NEVER; + byte[] decodedSignature; + try { + decodedSignature = dearmor(signatureData); + } catch (IllegalArgumentException e) { + return new SignatureVerification(getName(), signatureDate, null, + null, null, false, false, trust, + MessageFormat.format(SshdText.get().signInvalidSignature, + e.getLocalizedMessage())); + } + int start = RawParseUtils.match(decodedSignature, 0, + SshSignatureConstants.MAGIC); + if (start < 0) { + return new SignatureVerification(getName(), signatureDate, null, + null, null, false, false, trust, + SshdText.get().signInvalidMagic); + } + ByteArrayBuffer signature = new ByteArrayBuffer(decodedSignature, start, + decodedSignature.length - start); + + long version = signature.getUInt(); + if (version != SshSignatureConstants.VERSION) { + return new SignatureVerification(getName(), signatureDate, null, + null, null, false, false, trust, + MessageFormat.format(SshdText.get().signInvalidVersion, + Long.toString(version))); + } + + PublicKey key = signature.getPublicKey(); + String fingerprint; + if (key instanceof OpenSshCertificate cert) { + fingerprint = KeyUtils.getFingerPrint(cert.getCertPubKey()); + String message = SshCertificateUtils.verify(cert, signatureInstant); + if (message != null) { + return new SignatureVerification(getName(), signatureDate, null, + fingerprint, null, false, false, trust, message); + } + } else { + fingerprint = KeyUtils.getFingerPrint(key); + } + + String namespace = signature.getString(); + if (!SshSignatureConstants.NAMESPACE.equals(namespace)) { + return new SignatureVerification(getName(), signatureDate, null, + fingerprint, null, false, false, trust, + MessageFormat.format(SshdText.get().signInvalidNamespace, + namespace)); + } + + signature.getString(); // Skip the reserved field + String hashAlgorithm = signature.getString(); + byte[] hash; + try { + hash = MessageDigest + .getInstance(hashAlgorithm.toUpperCase(Locale.ROOT)) + .digest(data); + } catch (NoSuchAlgorithmException e) { + return new SignatureVerification(getName(), signatureDate, null, + fingerprint, null, false, false, trust, + MessageFormat.format( + SshdText.get().signUnknownHashAlgorithm, + hashAlgorithm)); + } + ByteArrayBuffer rawSignature = new ByteArrayBuffer( + signature.getBytes()); + if (signature.available() > 0) { + return new SignatureVerification(getName(), signatureDate, null, + fingerprint, null, false, false, trust, + SshdText.get().signGarbageAtEnd); + } + + String signatureAlgorithm = rawSignature.getString(); + switch (signatureAlgorithm) { + case KeyPairProvider.SSH_DSS: + case KeyPairProvider.SSH_DSS_CERT: + case KeyPairProvider.SSH_RSA: + case KeyPairProvider.SSH_RSA_CERT: + return new SignatureVerification(getName(), signatureDate, null, + fingerprint, null, false, false, trust, + MessageFormat.format(SshdText.get().signInvalidAlgorithm, + signatureAlgorithm)); + } + + String keyType = KeyUtils + .getSignatureAlgorithm(KeyUtils.getKeyType(key), key); + if (!KeyUtils.getCanonicalKeyType(keyType) + .equals(KeyUtils.getCanonicalKeyType(signatureAlgorithm))) { + return new SignatureVerification(getName(), signatureDate, null, + fingerprint, null, false, false, trust, + MessageFormat.format( + SshdText.get().signMismatchedSignatureAlgorithm, + keyType, signatureAlgorithm)); + } + + BuiltinSignatures factory = BuiltinSignatures + .fromFactoryName(signatureAlgorithm); + if (factory == null || !factory.isSupported()) { + return new SignatureVerification(getName(), signatureDate, null, + fingerprint, null, false, false, trust, + MessageFormat.format( + SshdText.get().signUnknownSignatureAlgorithm, + signatureAlgorithm)); + } + + boolean valid; + String message = null; + try { + Signature verifier = factory.create(); + verifier.initVerifier(null, + key instanceof OpenSshCertificate cert + ? cert.getCertPubKey() + : key); + // Feed it the data + Buffer toSign = new ByteArrayBuffer(); + toSign.putRawBytes(SshSignatureConstants.MAGIC); + toSign.putString(SshSignatureConstants.NAMESPACE); + toSign.putUInt(0); // reserved: zero-length string + toSign.putString(hashAlgorithm); + toSign.putBytes(hash); + verifier.update(null, toSign.getCompactData()); + valid = verifier.verify(null, rawSignature.getBytes()); + } catch (Exception e) { + LOG.warn("{}", SshdText.get().signLogFailure, e); //$NON-NLS-1$ + valid = false; + message = SshdText.get().signSeeLog; + } + boolean expired = false; + String principal = null; + if (valid) { + if (rawSignature.available() > 0) { + valid = false; + message = SshdText.get().signGarbageAtEnd; + } else { + SigningKeyDatabase database = SigningKeyDatabase.getInstance(); + if (database.isRevoked(repository, config, key)) { + valid = false; + if (key instanceof OpenSshCertificate certificate) { + message = MessageFormat.format( + SshdText.get().signCertificateRevoked, + KeyUtils.getFingerPrint( + certificate.getCaPubKey())); + } else { + message = SshdText.get().signKeyRevoked; + } + } else { + // This may turn a positive verification into a failed one. + try { + principal = database.isAllowed(repository, config, key, + SshSignatureConstants.NAMESPACE, gitIdentity); + if (!StringUtils.isEmptyOrNull(principal)) { + trust = TrustLevel.FULL; + } else { + valid = false; + message = SshdText.get().signNoPrincipalMatched; + trust = TrustLevel.UNKNOWN; + } + } catch (VerificationException e) { + valid = false; + message = e.getMessage(); + expired = e.isExpired(); + } catch (IOException e) { + LOG.warn("{}", SshdText.get().signLogFailure, e); //$NON-NLS-1$ + valid = false; + message = SshdText.get().signSeeLog; + } + } + } + } + return new SignatureVerification(getName(), signatureDate, null, + fingerprint, principal, valid, expired, trust, message); + } + + private static PersonIdent getGitIdentity(byte[] rawObject) { + // Data from a commit will start with "tree ID\n". + int i = RawParseUtils.match(rawObject, 0, TREE); + if (i > 0) { + i = RawParseUtils.committer(rawObject, 0); + if (i < 0) { + return null; + } + return RawParseUtils.parsePersonIdent(rawObject, i); + } + // Data from a tag will start with "object ID\ntype ". + i = RawParseUtils.match(rawObject, 0, OBJECT); + if (i > 0) { + i = RawParseUtils.nextLF(rawObject, i); + i = RawParseUtils.match(rawObject, i, TYPE); + if (i > 0) { + i = RawParseUtils.tagger(rawObject, 0); + if (i < 0) { + return null; + } + return RawParseUtils.parsePersonIdent(rawObject, i); + } + } + return null; + } + + private static byte[] dearmor(byte[] data) { + int start = RawParseUtils.match(data, 0, + SshSignatureConstants.ARMOR_HEAD); + if (start > 0) { + if (data[start] == '\r') { + start++; + } + if (data[start] == '\n') { + start++; + } + } + int end = data.length; + if (end > start + 1 && data[end - 1] == '\n') { + end--; + if (end > start + 1 && data[end - 1] == '\r') { + end--; + } + } + end = end - SshSignatureConstants.ARMOR_END.length; + if (end >= 0 && end >= start + && RawParseUtils.match(data, end, + SshSignatureConstants.ARMOR_END) >= 0) { + // end is fine: on the first the character of the end marker + } else { + // No end marker. + end = data.length; + } + if (start < 0) { + start = 0; + } + return Base64.decode(data, start, end - start); + } + + @Override + public void clear() { + SigningKeyDatabase database = SigningKeyDatabase.getInstance(); + if (database instanceof CachingSigningKeyDatabase caching) { + caching.clearCache(); + } + } +} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java index 6f7a4e9ef4..0533b651e0 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018, 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others + * Copyright (C) 2018, 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 @@ -147,17 +147,59 @@ public final class SshdText extends TranslationBundle { /***/ public String sshCommandTimeout; /***/ public String sshProcessStillRunning; /***/ public String sshProxySessionCloseFailed; + /***/ public String signAllowedSignersCertAuthorityError; + /***/ public String signAllowedSignersEmptyIdentity; + /***/ public String signAllowedSignersEmptyNamespaces; + /***/ public String signAllowedSignersFormatError; + /***/ public String signAllowedSignersInvalidDate; + /***/ public String signAllowedSignersLineFormat; + /***/ public String signAllowedSignersMultiple; + /***/ public String signAllowedSignersNoIdentities; + /***/ public String signAllowedSignersPublicKeyParsing; + /***/ public String signAllowedSignersUnterminatedQuote; /***/ public String signCertAlgorithmMismatch; /***/ public String signCertAlgorithmUnknown; /***/ public String signCertificateExpired; /***/ public String signCertificateInvalid; + /***/ public String signCertificateNotForName; + /***/ public String signCertificateRevoked; /***/ public String signCertificateTooEarly; + /***/ public String signCertificateWithoutPrincipals; /***/ public String signDefaultKeyEmpty; /***/ public String signDefaultKeyFailed; /***/ public String signDefaultKeyInterrupted; + /***/ public String signGarbageAtEnd; + /***/ public String signInvalidAlgorithm; /***/ public String signInvalidKeyDSA; + /***/ public String signInvalidMagic; + /***/ public String signInvalidNamespace; + /***/ public String signInvalidSignature; + /***/ public String signInvalidVersion; + /***/ public String signKeyExpired; + /***/ public String signKeyRevoked; + /***/ public String signKeyTooEarly; + /***/ public String signKrlBlobLeftover; + /***/ public String signKrlBlobLengthInvalid; + /***/ public String signKrlBlobLengthInvalidExpected; + /***/ public String signKrlCaKeyLengthInvalid; + /***/ public String signKrlCertificateLeftover; + /***/ public String signKrlCertificateSubsectionLeftover; + /***/ public String signKrlCertificateSubsectionLength; + /***/ public String signKrlEmptyRange; + /***/ public String signKrlInvalidBitSetLength; + /***/ public String signKrlInvalidKeyIdLength; + /***/ public String signKrlInvalidMagic; + /***/ public String signKrlInvalidReservedLength; + /***/ public String signKrlInvalidVersion; + /***/ public String signKrlNoCertificateSubsection; + /***/ public String signKrlSerialZero; + /***/ public String signKrlShortRange; + /***/ public String signKrlUnknownSection; + /***/ public String signKrlUnknownSubsection; /***/ public String signLogFailure; + /***/ public String signMismatchedSignatureAlgorithm; /***/ public String signNoAgent; + /***/ public String signNoPrincipalMatched; /***/ public String signNoPublicKey; /***/ public String signNoSigningKey; /***/ public String signNotUserCertificate; @@ -169,6 +211,7 @@ public final class SshdText extends TranslationBundle { /***/ public String signTooManyPublicKeys; /***/ public String signUnknownHashAlgorithm; /***/ public String signUnknownSignatureAlgorithm; + /***/ public String signWrongNamespace; /***/ public String unknownProxyProtocol; } diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/signing/ssh/CachingSigningKeyDatabase.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/signing/ssh/CachingSigningKeyDatabase.java new file mode 100644 index 0000000000..4d2d8b6797 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/signing/ssh/CachingSigningKeyDatabase.java @@ -0,0 +1,49 @@ +/* + * 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.signing.ssh; + +/** + * A {@link SigningKeyDatabase} that caches data. + * <p> + * A signing key database may be used to check keys frequently; it may thus need + * to cache some data and it may need to cache data per repository. If an + * implementation does cache data, it is responsible itself for refreshing that + * cache at appropriate times. Clients can control the cache size somewhat via + * {@link #setCacheSize(int)}, although the meaning of the cache size (i.e., its + * unit) is left undefined here. + * </p> + * + * @since 7.1 + */ +public interface CachingSigningKeyDatabase extends SigningKeyDatabase { + + /** + * Retrieves the current cache size. + * + * @return the cache size, or -1 if this database has no cache. + */ + int getCacheSize(); + + /** + * Sets the cache size to use. + * + * @param size + * the cache size, ignored if this database does not have a + * cache. + * @throws IllegalArgumentException + * if {@code size < 0} + */ + void setCacheSize(int size); + + /** + * Discards any cached data. A no-op if the database has no cache. + */ + void clearCache(); +} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/signing/ssh/SigningKeyDatabase.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/signing/ssh/SigningKeyDatabase.java new file mode 100644 index 0000000000..eec64c3abd --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/signing/ssh/SigningKeyDatabase.java @@ -0,0 +1,94 @@ +/* + * 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.signing.ssh; + +import java.io.IOException; +import java.security.PublicKey; + +import org.eclipse.jgit.annotations.NonNull; +import org.eclipse.jgit.internal.signing.ssh.SigningDatabase; +import org.eclipse.jgit.lib.GpgConfig; +import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.lib.Repository; + +/** + * A database storing meta-information about signing keys and certificates. + * + * @since 7.1 + */ +public interface SigningKeyDatabase { + + /** + * Obtains the current global instance. + * + * @return the global {@link SigningKeyDatabase} + */ + static SigningKeyDatabase getInstance() { + return SigningDatabase.getInstance(); + } + + /** + * Sets the global {@link SigningKeyDatabase}. + * + * @param database + * to set; if {@code null} a default database using the OpenSSH + * allowed signers file and the OpenSSH revocation list mechanism + * is used. + * @return the previously set {@link SigningKeyDatabase} + */ + static SigningKeyDatabase setInstance(SigningKeyDatabase database) { + return SigningDatabase.setInstance(database); + } + + /** + * Determines whether the gives key has been revoked. + * + * @param repository + * {@link Repository} the key is being used in + * @param config + * {@link GpgConfig} to use + * @param key + * {@link PublicKey} to check + * @return {@code true} if the key has been revoked, {@code false} otherwise + * @throws IOException + * if an I/O problem occurred + */ + boolean isRevoked(@NonNull Repository repository, @NonNull GpgConfig config, + @NonNull PublicKey key) throws IOException; + + /** + * Checks whether the given key is allowed to be used for signing, and if + * allowed returns the principal. + * + * @param repository + * {@link Repository} the key is being used in + * @param config + * {@link GpgConfig} to use + * @param key + * {@link PublicKey} to check + * @param namespace + * of the signature + * @param ident + * optional {@link PersonIdent} giving a signer's e-mail address + * and a signature time + * @return {@code null} if the database does not contain any information + * about the given key; the principal if it does and all checks + * passed + * @throws IOException + * if an I/O problem occurred + * @throws VerificationException + * if the database contains information about the key and the + * checks determined that the key is not allowed to be used for + * signing + */ + String isAllowed(@NonNull Repository repository, @NonNull GpgConfig config, + @NonNull PublicKey key, @NonNull String namespace, + PersonIdent ident) throws IOException, VerificationException; +} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/signing/ssh/SshSignatureVerifierFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/signing/ssh/SshSignatureVerifierFactory.java new file mode 100644 index 0000000000..c315428c33 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/signing/ssh/SshSignatureVerifierFactory.java @@ -0,0 +1,34 @@ +/* + * 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.signing.ssh; + +import org.eclipse.jgit.lib.GpgConfig.GpgFormat; +import org.eclipse.jgit.lib.SignatureVerifier; +import org.eclipse.jgit.internal.signing.ssh.SshSignatureVerifier; +import org.eclipse.jgit.lib.SignatureVerifierFactory; + +/** + * Factory creating {@link SshSignatureVerifier}s. + * + * @since 7.1 + */ +public final class SshSignatureVerifierFactory + implements SignatureVerifierFactory { + + @Override + public GpgFormat getType() { + return GpgFormat.SSH; + } + + @Override + public SignatureVerifier create() { + return new SshSignatureVerifier(); + } +} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/signing/ssh/VerificationException.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/signing/ssh/VerificationException.java new file mode 100644 index 0000000000..cd77111813 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/signing/ssh/VerificationException.java @@ -0,0 +1,63 @@ +/* + * 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.signing.ssh; + +/** + * An exception giving details about a failed + * {@link SigningKeyDatabase#isAllowed(org.eclipse.jgit.lib.Repository, org.eclipse.jgit.lib.GpgConfig, java.security.PublicKey, String, org.eclipse.jgit.lib.PersonIdent)} + * validation. + * + * @since 7.1 + */ +public class VerificationException extends Exception { + + private static final long serialVersionUID = 313760495170326160L; + + private final boolean expired; + + private final String reason; + + /** + * Creates a new instance. + * + * @param expired + * whether the checked public key or certificate was expired + * @param reason + * describing the check failure + */ + public VerificationException(boolean expired, String reason) { + this.expired = expired; + this.reason = reason; + } + + @Override + public String getMessage() { + return reason; + } + + /** + * Tells whether the check failed because the public key was expired. + * + * @return {@code true} if the check failed because the public key was + * expired, {@code false} otherwise + */ + public boolean isExpired() { + return expired; + } + + /** + * Retrieves the check failure reason. + * + * @return the reason description + */ + public String getReason() { + return reason; + } +} |