* master: (35 commits) [releng] japicmp: update last release version IgnoreNode: include path to file for invalid .gitignore patterns FastIgnoreRule: include bad pattern in log message init: add config option to set default for the initial branch name init: allow specifying the initial branch name for the new repository Fail clone if initial branch doesn't exist in remote repository GPG: fix reading unprotected old-format secret keys Update Orbit to S20210216215844 Add missing bazel dependency for o.e.j.gpg.bc.test GPG: handle extended private key format dfs: handle short copies [GPG] Provide a factory for the BouncyCastleGpgSigner Fix boxing warnings GPG: compute the keygrip to find a secret key GPG signature verification via BouncyCastle Post commit hook failure should not cause commit failure Allow to define additional Hook classes outside JGit GitHook: use default charset for output and error streams GitHook: use generic OutputStream instead of PrintStream Update jetty to 9.4.36.v20210114 ... Change-Id: I1cf5ab262c67b986e82422c48dfc103e335d28cctags/v5.11.0.202102240950-m3
@@ -1 +1 @@ | |||
4.0.0rc2 | |||
4.0.0 |
@@ -13,6 +13,8 @@ genrule( | |||
"//org.eclipse.jgit.lfs:jgit-lfs", | |||
"//org.eclipse.jgit.lfs.server:jgit-lfs-server", | |||
"//org.eclipse.jgit.junit:junit", | |||
"//org.eclipse.jgit.ssh.apache:ssh-apache", | |||
"//org.eclipse.jgit.ssh.jsch:ssh-jsch", | |||
], | |||
outs = ["all.zip"], | |||
cmd = " && ".join([ |
@@ -111,26 +111,26 @@ maven_jar( | |||
maven_jar( | |||
name = "httpclient", | |||
artifact = "org.apache.httpcomponents:httpclient:4.5.10", | |||
sha1 = "7ca2e4276f4ef95e4db725a8cd4a1d1e7585b9e5", | |||
artifact = "org.apache.httpcomponents:httpclient:4.5.13", | |||
sha1 = "e5f6cae5ca7ecaac1ec2827a9e2d65ae2869cada", | |||
) | |||
maven_jar( | |||
name = "httpcore", | |||
artifact = "org.apache.httpcomponents:httpcore:4.4.12", | |||
sha1 = "21ebaf6d532bc350ba95bd81938fa5f0e511c132", | |||
artifact = "org.apache.httpcomponents:httpcore:4.4.14", | |||
sha1 = "9dd1a631c082d92ecd4bd8fd4cf55026c720a8c1", | |||
) | |||
maven_jar( | |||
name = "sshd-osgi", | |||
artifact = "org.apache.sshd:sshd-osgi:2.4.0", | |||
sha1 = "fc4551c1eeda35e4671b263297d37d2bca81c4d4", | |||
artifact = "org.apache.sshd:sshd-osgi:2.6.0", | |||
sha1 = "40e365bb799e1bff3d31dc858b1e59a93c123f29", | |||
) | |||
maven_jar( | |||
name = "sshd-sftp", | |||
artifact = "org.apache.sshd:sshd-sftp:2.4.0", | |||
sha1 = "92e1b7d1e19c715efb4a8871d34145da8f87cdb2", | |||
artifact = "org.apache.sshd:sshd-sftp:2.6.0", | |||
sha1 = "6eddfe8fdf59a3d9a49151e4177f8c1bebeb30c9", | |||
) | |||
maven_jar( | |||
@@ -237,55 +237,55 @@ maven_jar( | |||
sha1 = "9180733b7df8542621dc12e21e87557e8c99b8cb", | |||
) | |||
JETTY_VER = "9.4.35.v20201120" | |||
JETTY_VER = "9.4.36.v20210114" | |||
maven_jar( | |||
name = "jetty-servlet", | |||
artifact = "org.eclipse.jetty:jetty-servlet:" + JETTY_VER, | |||
sha1 = "3e61bcb471e1bfc545ce866cbbe33c3aedeec9b1", | |||
src_sha1 = "e237af9dd6556756736fcdc7da00194fa00d3c2b", | |||
sha1 = "b189e52a5ee55ae172e4e99e29c5c314f5daf4b9", | |||
src_sha1 = "3a0fa449772ab0d76625f6afb81f60c32a490613", | |||
) | |||
maven_jar( | |||
name = "jetty-security", | |||
artifact = "org.eclipse.jetty:jetty-security:" + JETTY_VER, | |||
sha1 = "80dc2f422789c78315de76d289b7a5b36c3232d5", | |||
src_sha1 = "3c0d03191fdffd9cf1e46fa206d79eeb9e3adb90", | |||
sha1 = "42030d6ed7dfc0f75818cde0adcf738efc477574", | |||
src_sha1 = "612220a97d45fad3983ccc56b0cb9a271f3fd003", | |||
) | |||
maven_jar( | |||
name = "jetty-server", | |||
artifact = "org.eclipse.jetty:jetty-server:" + JETTY_VER, | |||
sha1 = "513502352fd689d4730b2935421b990ada8cc818", | |||
src_sha1 = "760d3574ebc7f9b9b1ba51242b9c1dda6fe5505b", | |||
sha1 = "88a7d342974aadca658e7386e8d0fcc5c0788f41", | |||
src_sha1 = "4552c0c6db2948e8557db477b6b48d291006e481", | |||
) | |||
maven_jar( | |||
name = "jetty-http", | |||
artifact = "org.eclipse.jetty:jetty-http:" + JETTY_VER, | |||
sha1 = "45d35131a35a1e76991682174421e8cdf765fb9f", | |||
src_sha1 = "491cd5b8abe8fe6f3db0086907a3f12440188e73", | |||
sha1 = "1eee89a55e04ff94df0f85d95200fc48acb43d86", | |||
src_sha1 = "552a784ec789c7ba581c5341ae6d8b6353ed5ace", | |||
) | |||
maven_jar( | |||
name = "jetty-io", | |||
artifact = "org.eclipse.jetty:jetty-io:" + JETTY_VER, | |||
sha1 = "eb9460700b99b71ecd82a53697f5ff99f69b9e1c", | |||
src_sha1 = "fed96a4559a49e7173dbe2d9d8e100d72aee2a10", | |||
sha1 = "84a8faf9031eb45a5a2ddb7681e22c483d81ab3a", | |||
src_sha1 = "72d5fc6d909e28f8720394b25babda80805a46b9", | |||
) | |||
maven_jar( | |||
name = "jetty-util", | |||
artifact = "org.eclipse.jetty:jetty-util:" + JETTY_VER, | |||
sha1 = "ef61b83f9715c3b5355b633d9f01d2834f908ece", | |||
src_sha1 = "8f178bebeb34c8365a06d854daa9b22da1b301d7", | |||
sha1 = "925257fbcca6b501a25252c7447dbedb021f7404", | |||
src_sha1 = "532e8b66044f4e58ca5da3aec19f02a2f3c16ddd", | |||
) | |||
maven_jar( | |||
name = "jetty-util-ajax", | |||
artifact = "org.eclipse.jetty:jetty-util-ajax:" + JETTY_VER, | |||
sha1 = "ebbb43912c6423bedb3458e44aee28eeb4d66f27", | |||
src_sha1 = "b3acea974a17493afb125a9dfbe783870ce1d2f9", | |||
sha1 = "2f478130c21787073facb64d7242e06f94980c60", | |||
src_sha1 = "7153d7ca38878d971fd90992c303bb7719ba7a21", | |||
) | |||
BOUNCYCASTLE_VER = "1.65" |
@@ -162,6 +162,7 @@ java_library( | |||
"//org.eclipse.jgit:__pkg__", | |||
"//org.eclipse.jgit.gpg.bc:__pkg__", | |||
"//org.eclipse.jgit.test:__pkg__", | |||
"//org.eclipse.jgit.gpg.bc.test:__pkg__", | |||
], | |||
exports = ["@bcpg//jar"], | |||
) | |||
@@ -172,6 +173,7 @@ java_library( | |||
"//org.eclipse.jgit:__pkg__", | |||
"//org.eclipse.jgit.gpg.bc:__pkg__", | |||
"//org.eclipse.jgit.test:__pkg__", | |||
"//org.eclipse.jgit.gpg.bc.test:__pkg__", | |||
], | |||
exports = ["@bcprov//jar"], | |||
) |
@@ -2,10 +2,15 @@ | |||
<classpath> | |||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> | |||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> | |||
<classpathentry kind="src" path="tst"> | |||
<classpathentry kind="src" output="bin-tst" path="tst"> | |||
<attributes> | |||
<attribute name="test" value="true"/> | |||
</attributes> | |||
</classpathentry> | |||
<classpathentry kind="output" path="bin"/> | |||
<classpathentry kind="src" output="bin-tst" path="tst-rsrc"> | |||
<attributes> | |||
<attribute name="test" value="true"/> | |||
</attributes> | |||
</classpathentry> | |||
<classpathentry kind="output" path="bin-tst"/> | |||
</classpath> |
@@ -1,2 +1,3 @@ | |||
/bin | |||
/bin-tst | |||
/target |
@@ -1,3 +1,8 @@ | |||
load( | |||
"@com_googlesource_gerrit_bazlets//tools:genrule2.bzl", | |||
"genrule2", | |||
) | |||
load("@rules_java//java:defs.bzl", "java_import") | |||
load( | |||
"@com_googlesource_gerrit_bazlets//tools:junit.bzl", | |||
"junit_tests", | |||
@@ -8,7 +13,23 @@ junit_tests( | |||
srcs = glob(["tst/**/*.java"]), | |||
tags = ["bc"], | |||
deps = [ | |||
"//lib:bcpg", | |||
"//lib:bcprov", | |||
"//lib:junit", | |||
"//org.eclipse.jgit:jgit", | |||
"//org.eclipse.jgit.gpg.bc:gpg-bc", | |||
"//org.eclipse.jgit.gpg.bc.test:tst_rsrc", | |||
], | |||
) | |||
java_import( | |||
name = "tst_rsrc", | |||
jars = [":tst_rsrc_jar"], | |||
) | |||
genrule2( | |||
name = "tst_rsrc_jar", | |||
srcs = glob(["tst-rsrc/**"]), | |||
outs = ["tst_rsrc.jar"], | |||
cmd = "o=$$PWD/$@ && tar cf - $(SRCS) | tar -C $$TMP --strip-components=2 -xf - && cd $$TMP && zip -qr $$o .", | |||
) |
@@ -7,8 +7,18 @@ Bundle-Version: 5.11.0.qualifier | |||
Bundle-Vendor: %Bundle-Vendor | |||
Bundle-Localization: plugin | |||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | |||
Import-Package: org.eclipse.jgit.gpg.bc.internal;version="[5.11.0,5.12.0)", | |||
org.junit;version="[4.13,5.0.0)" | |||
Export-Package: org.eclipse.jgit.gpg.bc.internal;x-internal:=true | |||
Import-Package: org.bouncycastle.jce.provider;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.openpgp;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.openpgp.operator;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.openpgp.operator.jcajce;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.util.encoders;version="[1.65.0,2.0.0)", | |||
org.eclipse.jgit.gpg.bc.internal;version="[5.11.0,5.12.0)", | |||
org.eclipse.jgit.gpg.bc.internal.keys;version="[5.11.0,5.12.0)", | |||
org.eclipse.jgit.util.sha1;version="[5.11.0,5.12.0)", | |||
org.junit;version="[4.13,5.0.0)", | |||
org.junit.runner;version="[4.13,5.0.0)", | |||
org.junit.runners;version="[4.13,5.0.0)" | |||
Export-Package: org.eclipse.jgit.gpg.bc.internal;x-internal:=true, | |||
org.eclipse.jgit.gpg.bc.internal.keys;x-internal:=true | |||
Require-Bundle: org.hamcrest.core;bundle-version="[1.1.0,2.0.0)", | |||
org.hamcrest.library;bundle-version="[1.1.0,2.0.0)" |
@@ -1,5 +1,5 @@ | |||
source.. = tst/ | |||
output.. = bin/ | |||
output.. = bin-tst/ | |||
bin.includes = META-INF/,\ | |||
.,\ | |||
plugin.properties |
@@ -85,6 +85,12 @@ | |||
<sourceDirectory>src/</sourceDirectory> | |||
<testSourceDirectory>tst/</testSourceDirectory> | |||
<testResources> | |||
<testResource> | |||
<directory>tst-rsrc/</directory> | |||
</testResource> | |||
</testResources> | |||
<plugins> | |||
<plugin> | |||
<groupId>org.apache.maven.plugins</groupId> |
@@ -0,0 +1,41 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
mQGNBGAHBLQBDACsS1vFqE3qgKD2R5X9n90Gz8bucwwvJWIqaHDsVoAtF6IcKIDo | |||
1hQC9YksTQYl/L7BsMDdmjyEbWRfzW4ory5596d342Hl6g7ZB5jJR5kJJdhy2MCJ | |||
BUiMy/724Fr/Dz8PNPcEoULz9ZH7HEaPRKqWWEQDUCq5ak0MfLKXtWVUBgsY5Mry | |||
29d/GLJvnxZ5v16PK+P4oqZ7vh7FWJPlqPK2TCZ6s1rYfWlu9XbHOzwXwozVg7IX | |||
tfFq4Rij4c0sg0S0GY8hGAlnOpRc/6J2S41Y8p3WqND6r1LPDQUFnNCKXVoHUGeK | |||
X9U5iAP7pxZSuonsFCqr3CDGxr+kKUpbfZeLrqTA4lBUK7T6w6Wq0qHosCYUU7YC | |||
GZjlEeCZBRWNfeq45LKlhdNUxHWWgaBsgWaaDmpFWaivblmQGOvmSv1nJMNmedRs | |||
DSF51nsJnkQceprsvThSa6qJwEYi7pj6L9HO2UGgJLCb3dL5VTQih2gdhghckUSB | |||
okUkvqBvvdiP2nEAEQEAAbQdVGVzdGVyMiA8dGVzdGVyMkBleGFtcGxlLm9yZz6J | |||
Ac4EEwEKADgWIQRPCAvglun3I2Bs1iITM2XBzCpwbgUCYAcEtAIbAwULCQgHAwUV | |||
CgkICwUWAgMBAAIeAQIXgAAKCRATM2XBzCpwboiBC/493+ruANV2eiro8MY8wZ3Y | |||
gdjp3pHBSg9RK74SIh95J+MW5qzPwkU+vHd8l0+aj9e1sDQb5BFcFk/Z1ioI3TDW | |||
B4vYWoMkdN932fJ/LcIlhOGjWwSNFZphbYmJzrAwUTA499yx3jt9Dg+vSU88S+8S | |||
FzYe6CBNt+PqDCbk6Gm+ZcVpR+elq/QJeyhdDzCCrrfNXwPwsVGAM61Z8SvdvNKE | |||
DA5gHXRsOKf8fu8lqW2Ay0MCvgsZLMIGOMDPCyBUd1bhlU0p18V6D6wdatfzu9gR | |||
X/k36HJyqB2cHh89/F2KdBSonRVRJOvHc/88zEeRFkiV5pUyrXv40l099+5dvA+2 | |||
h4ODftY7ZbR22k4iX5rqj2BRow3H+N5lTIWgiADPUl+H8z4ZY5G+LWk9Xms3o1G9 | |||
DmEepM3ma1pg4sZbxf0iStikch7aPvL/HgGRPJnDxA/W4KJxqmSw9TTMH/6XHq3D | |||
ah5Z1lbcylChgrFLFVJi+shnLTZSYttTeKOIqTPi0765AY0EYAcEtAEMANS23tqF | |||
Dr69wz0AaT7tjoccT/WlSO/gxd80ShMr4vbr21PZp8qGklFmlcrSrMDRwfXY04x2 | |||
qxHR/Kf+hCD5gNvg8kh/yH2lQRcvekzQ4/rLmSXBfGOFg+LioQQ3CZJ1MZyIHzu5 | |||
YVZ2pqALfJwJSw9P5Z340y8sq8AOPaJ+cpIC0rYBp9BUAmz9IeLVT7fUc6CjaWBo | |||
++E8H+9FyZC71RIPNcCvY+24Qky8ms7nw4hA47Dlht1pqL8dzOggCnohuSYMCXs2 | |||
YPLvDGdZMg7GgQ3AyZawDmjTxFWt51VU5hunGfGiC5Aock8rVHSYsQzUFjVBSR+Y | |||
Zy+c4noxZD1eRfb8KdFnrewyVqGKFtc/JwA61qhhyYFe5AWMAFtudjGYG0WiTP82 | |||
CmFFc1Qsvyls9G2yMkLuay5wsdIJMnRW9XwBzwxm0mdZI6D3nSbWjPUUfRcGBY8C | |||
Hqpc736G+UzMevZtorwy/5Q6D8v+Obrk02DIDKa6CJ7g7dTwK0I/fleJlwARAQAB | |||
iQG2BBgBCgAgFiEETwgL4Jbp9yNgbNYiEzNlwcwqcG4FAmAHBLQCGwwACgkQEzNl | |||
wcwqcG6mYQv8CFIVGj7/Qnr+wmviMzm8+B4WwQIUHGryqv9hnfp9hLOXMFmNuEDl | |||
QYkHVChWO7ehrR3fpvpebhcieV19skf/WO8xm0pGSXyjV2/0/bVhXq01xesXHH9r | |||
4aFxsCu0E8M9fZVAHP7NBr4A67knQ4EHRF6Rwml2ba6Zt2oP15IHvsAq/2B3f8ar | |||
5sUau4zM1cItG3tg49rbYr6V71HdgkWA22+EkbXL/Qq3haY/er2dIGc73lu8t7oQ | |||
msGK4LSAGc2661wMvJ6w6feCagkXAtrqyxodhSLoWgF3i0QVQnMbgmYWKEK2B6YA | |||
g669CZCCXJF+9Ebq+PP/d3Cy/k9iUmWDh72C7iL136kYZt+71b+yOmlDRT9l6DvU | |||
FP3bhRZWomOt3F3aP5mAdbwrP1NbvlxTYUAf++nUPdpr0Jrvgi67/VHVjaUtVh/K | |||
gVQ2C+4Cp/fllxXXKQMPcC8dD1x/AL6ytDzPu099ETMULntgbt7A5Lsd/fFScnF3 | |||
ZNx6wjRReIvT | |||
=8E/K | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,42 @@ | |||
Key: (private-key (rsa (n #00AC4B5BC5A84DEA80A0F64795FD9FDD06CFC6EE730C | |||
2F25622A6870EC56802D17A21C2880E8D61402F5892C4D0625FCBEC1B0C0DD9A3C846D | |||
645FCD6E28AF2E79F7A777E361E5EA0ED90798C947990925D872D8C08905488CCBFEF6 | |||
E05AFF0F3F0F34F704A142F3F591FB1C468F44AA96584403502AB96A4D0C7CB297B565 | |||
54060B18E4CAF2DBD77F18B26F9F1679BF5E8F2BE3F8A2A67BBE1EC55893E5A8F2B64C | |||
267AB35AD87D696EF576C73B3C17C28CD583B217B5F16AE118A3E1CD2C8344B4198F21 | |||
1809673A945CFFA2764B8D58F29DD6A8D0FAAF52CF0D05059CD08A5D5A0750678A5FD5 | |||
398803FBA71652BA89EC142AABDC20C6C6BFA4294A5B7D978BAEA4C0E250542BB4FAC3 | |||
A5AAD2A1E8B0261453B6021998E511E09905158D7DEAB8E4B2A585D354C4759681A06C | |||
81669A0E6A4559A8AF6E599018EBE64AFD6724C36679D46C0D2179D67B099E441C7A9A | |||
ECBD38526BAA89C04622EE98FA2FD1CED941A024B09BDDD2F955342287681D86085C91 | |||
4481A24524BEA06FBDD88FDA71#)(e #010001#)(d | |||
#208024A31FF0F6B3E5E91F2ED58572F1A67F1D9AD9290991BF732D1DFFE134E058E5 | |||
9BE459478CC5D42058997CF7EC79E55A9CBF10A9AAC761E04A85A5AA0A07DAE61DD0E8 | |||
36311534EE606D5392B42D8DEB7824B594280FDB2950D39886B58F0D24CE15F2FF88BA | |||
819B8F4566202B57A9F5C6743862FA80E7429C83CEA57B189ABE4AE657B28DAF7D6EA7 | |||
6CA89635B9B6232EE14779452D636B919E707B92B13DA3229133A953DAF021E0928B83 | |||
75EDEE98163C2189E22CE9A236C3D0EABD2608DAEF09211B2C77FFE9158A95F8EF2750 | |||
221C5ADEDAED0446DC0E4CD8D38AD897D44FA3915934B6CF03F489DFAA6D939AB9F8EF | |||
1C2A0CDCFC3F2207D63A9EB55B09A0A45323D5F59AE4A9D48E819E98E53D04F022905A | |||
9C4D137F32CB33A974F202B0D3AD4AC64CFBA2A4C18650B671AB753D1D3BD7C4FCC8D2 | |||
0F85D1876D89A3D94C77423778C08BDF8FBA23A8501D766FC1B4D51F2D4BB4C27B8491 | |||
CC2595FF54034F4F192D668C1934D292752A4E44C95135D29449B75928BAF1A2389ED9 | |||
#)(p #00CCD74AC0DC1CC46052F784DB19545A09FF904846247BAD1AFA5E00CE84A4DA | |||
BFCD3BCA175508C068553226DBA49EDAFBCC33CF2A914F9006326FCB62C0473B1E93F6 | |||
DCF89A24006B090834E5686464A8C216B70AD797732E671ED78CD3E922161069E46BA7 | |||
489F2A79CE46BDC4E6F5FCE97C3C9DC59399212235C53246609F8B7FDBF2AD191B3FB4 | |||
4CC59760BA6D2029541811D1E9B72DC2ADC98513589A9715C82EE88ADF9000A41512C9 | |||
6D491D2A30269FBFCD9CF5D2F275A1DBFFEEB72BE5#)(q | |||
#00D7532ABA5F442A994ED8290AA71EAAB6F8137FE3F01488298637084157972D31EA | |||
E9F495B4360A6E92ABA7C2418A5960DF29B8C8146CC7D1DF1201C17509D7315B6ECF86 | |||
F0A73C9F5B48D96F2108DD323FAE6BF897A8CB773EDCF5C82E203813945405F414E3F2 | |||
99EEDE43EE6259FDED1C01B47C20F67AC488209585FE6FB7D958AF5EF567737E1ACCB4 | |||
E293724BE8AB6159CD5A6603FFEFC2DBC30FB6EAF647DBE7D9664ED0BBA1C4A2268AE3 | |||
DE0850572E145BA811EB2087E1E26490F9439D#)(u | |||
#00A8026DB6685170EC05DA3574451678718501489843227BCEB772FDB86B20AB2F2A | |||
00B790A2373FD5DF7AD2CAA2E3896C4C9CBA08581F3644DF67743FA4BE1153421F8FB2 | |||
47F0EFB64C566CB7E361BAB21CCAF029B43B7172232D11D14912BC035E17FB8BC663CA | |||
6766E6D2531F87AF378896A2AC7D98824AA8F51C5D6C11B7DC266209BCD3B23597F02B | |||
A317CCAACC979402F84E47F3D143187F9739FE9A6C71829CC94E4003D70CFFA33AC0FA | |||
A12776EFAFFB8261ABE664C6A6FAE623D3678F#))) | |||
Created: 20210119T161132 |
@@ -0,0 +1,42 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
mQGNBGAHBAUBDADAzIW1FhCcQmP/NDhzXoeRQ+DNACqTed7eEhqm3rowkW4wKi56 | |||
v1UxFR0ZoA3LoT1oQQjiL3IS2l4/qpBR3JQhMFH3pl7yBsCIrN7JvZfAvxq2Ud4e | |||
YbdonY8mv/yCLq+nkTWlHkWGCppKMm6DupEUw5CFUCiptPXIxikU0uQYB7VRtXhh | |||
Q1RGdsv6mcOwMIh7hj9flTrX025x0vRypjqgDR05RuM3hMMpJDGMAuf51w/lbRl9 | |||
dAsJzFzg2cf+8qv92Gx3RuP3a3yl6pEuKnkpddC47lj2pvuhWZBf2sXZMyPvMIvA | |||
Dve4GIVj6k+wXE3DMp0xMy0Fvaxw5OORPxUAKNBR/BgjoRbkbjm+rJZzviu/XVPR | |||
42+78isvsa+lnEAmTeoTqiz9nlTTPN+6JjwJXYn2LuiFM8XzNPJwNmd/86lW1qbP | |||
DxZHhD9jjeXZNHUBUCKTIj2Rs2uFa0xrALdhhhGEao9JlVcUqz/Tw85qC+DlzSa3 | |||
3re5C6wGe2pnW3sAEQEAAbRGVGVzdGVyICjDhG5kZXJ1bmdlbiBpbiBHUEcga8O2 | |||
bm5lbiBGb2xnZW4gaGFiZW4hKSA8dGVzdGVyQGV4YW1wbGUub3JnPokBzgQTAQoA | |||
OBYhBPidC43dWzUvOqsRbzx6+72u3pDoBQJgBwQFAhsDBQsJCAcDBRUKCQgLBRYC | |||
AwEAAh4BAheAAAoJEDx6+72u3pDogeAL/iNn1aKxA7pKmucyuzcbzvUjtcbbqFL8 | |||
lOLdRxkrQNCDMb+wHgGY1UqJ6wsDruhV+TdPLzUXHpCl731MeLxZyIENr4wnjTBf | |||
Cr4SU8eFUkusVf3aWK3rlk54W50EkfBjMvDVavRKNkVbCWAAwXZ7mTRf3UlWxg+F | |||
9Sq4j2P/hEZIznKV3y7zXLDYg0OpMZLgbo3si0CD19/1T/8Z9C680qSwyAiPtjRo | |||
vfJYqZFQc+ZH7j1Hmvg68d2Qwrkg/WMfOGoTLZq/6PQcM5leQBAodcS1t7C8o1JQ | |||
6D+f2gLHpMfFdUKh9TkmvnKYI20TWUVm9XQLqyAHsOn2vRMUhydcZ8OP103TKmP4 | |||
mbpgiyp4i4S/7XofHSeFBrbdqt73ebubESuZVXNjTuuSUjH8Jq5nHq22ZrmotSd0 | |||
FNwc9qQmwPG/gmOGq3rUdT/KzUVntc66QN/+hMhFDYMRJsjJhhyszvGuuBp6vBzI | |||
lMZqx5jqOaI9ON0m0o8CKC50sKdJ25G3wLkBjQRgBwQFAQwAqMXwgfSaIM+eSQWs | |||
xb4Sf2aCr/RZi5wzZz89lSomMcblqtCpuHv9/C1PSd+N/D1yJKzPChbDjHh6B6gc | |||
4OUvuDKHmxK+oAiURpvR+yJEdbSEYwiBhfAUD6u2q3IfY5PpyyZT3NjZ9EY8FpOX | |||
wpgdSOdSiZVZfZt0xUPsGbW/xP1yVR1NHYLuZX5P5oTCvyNJyP8zQQmToamJsvzR | |||
v9r+2sa5di9roe53kZwq24VjIvTDOOE4xoYEXk5UD83u1LA++9Nfdisxxts1bxgj | |||
w1ThO/IRTyY5y5bKSQPskYFD3eVz+azjVurqhbj6ep69mR2X2gjLCetz6G1l4PU2 | |||
R6wcqVG6gR6XpGFPsN+M2JRtbgKrtMElA8egJIMMpH4hdXYqIqmpe/31zXhClHkO | |||
99EbBpk6OawZC+MnreQFN4NIK5uO2aLi+3KL1FFnNlFCXkh/8afbt4+6rHcWC6En | |||
q5W0ZkLZnpjdFOF5NPTinAdei+14gnf2QhIlFLeMHvqiVEXvABEBAAGJAbYEGAEK | |||
ACAWIQT4nQuN3Vs1LzqrEW88evu9rt6Q6AUCYAcEBQIbDAAKCRA8evu9rt6Q6DcX | |||
C/4orMX1YBZNJK5hLLdjfk45EsQDfCnhf8H991xd0Rq4VPJP6bvzikSdOn9bTUEz | |||
AAhA4JnFu9AMTh8ioOA7ZtViIccplFBivsxi3rAVrQvmCfoP2AdHfG/jB6D9uWGs | |||
MV5/o1p93Hr0ReO73HK6G4Q3FbJOG3fg6wTcMYyyEQrD5g4IQhKiIhudUlSkKUkA | |||
9hWKlXSLw3Yx/S2Nq5Ye+Pqr4CU7UFOTCsBIH4Ky+6gLTmP6esPx0k8vXLcOjaCk | |||
ENcLi0OaL/AgfATH/InN3wzrx2AFfU6eQdEG7HS+402eHl0fmWwMGV+SCsLl+2hx | |||
AguLFwjetuVrroc/d+XeZdTcpr/2vojsr4UgbkH8Pa2KrGIpK7V85nSOeVbpDUru | |||
tuimIRSxIQ6GDF2c7Ih5yBy+JPV47gppSV/GgHPgrOlebeqy4sytshRiEYw/nJzZ | |||
LKBaG6gykN+6MeV6+A7c1BlCYpyi2vcyvouU+l3/Z9gR7vY+Oj1eAaxrqeTFf++3 | |||
qnA= | |||
=03Wd | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,45 @@ | |||
Key: (protected-private-key (rsa (n #00C0CC85B516109C4263FF3438735E8791 | |||
43E0CD002A9379DEDE121AA6DEBA30916E302A2E7ABF5531151D19A00DCBA13D684108 | |||
E22F7212DA5E3FAA9051DC94213051F7A65EF206C088ACDEC9BD97C0BF1AB651DE1E61 | |||
B7689D8F26BFFC822EAFA79135A51E45860A9A4A326E83BA9114C390855028A9B4F5C8 | |||
C62914D2E41807B551B5786143544676CBFA99C3B030887B863F5F953AD7D36E71D2F4 | |||
72A63AA00D1D3946E33784C32924318C02E7F9D70FE56D197D740B09CC5CE0D9C7FEF2 | |||
ABFDD86C7746E3F76B7CA5EA912E2A792975D0B8EE58F6A6FBA159905FDAC5D93323EF | |||
308BC00EF7B8188563EA4FB05C4DC3329D31332D05BDAC70E4E3913F150028D051FC18 | |||
23A116E46E39BEAC9673BE2BBF5D53D1E36FBBF22B2FB1AFA59C40264DEA13AA2CFD9E | |||
54D33CDFBA263C095D89F62EE88533C5F334F27036677FF3A956D6A6CF0F1647843F63 | |||
8DE5D9347501502293223D91B36B856B4C6B00B7618611846A8F49955714AB3FD3C3CE | |||
6A0BE0E5CD26B7DEB7B90BAC067B6A675B7B#)(e #010001#)(protected | |||
openpgp-s2k3-ocb-aes ((sha1 #84A4A8051974D94E# | |||
"26420224")#914E6847983627126D1CDF93#)#DEB66FA3201F91591F688F5D2B1B79 | |||
39FD75F58A962C227BC739C6F2F814ADE5115BD85B2E55427153CEC82612F0C5BBE8B9 | |||
71A0E5A6B796111B6B1A03C4C926825F03B871CBFE0F64BD0F0CC65EA34E718BA823BD | |||
136D78C9E88CA1733DFC8D6A38830274322A589BC522A2A824FCEAF453523CDD9BC391 | |||
EEF1355470C110E9A92681DA0C61563465D5238CECCA2D6CFA78FFDFBDDA17A308D6E1 | |||
3B1858890EF25A7655F22FE6305AA0129DE5A353B657065E608A616A23C6AF561C4472 | |||
5AA705E55343E9C728641BB63C64F804F76A4C5008CE5FFBC09F03B632B42180425D28 | |||
9DC1201D91B1989627EE5930E6EF2F6606108B2F048934A9D79DB4834DD950C4A2013C | |||
A40B50EE54FA9E3CCB20C210244BFACA795494A1FCFF35856ACF63214A0498ED894BAB | |||
FE80CC24D8A478AD08D0BE8CDC8F357FB7F28A30B87540B9B4970D6EA0AEEF46A2549F | |||
BA43A98FAD75B4228108DB50D1C3654422E24B4C7754673A66281BB283CD6A1EA8E64B | |||
97DC9083C62034BF7FBCD193830F8FEC3589673B864E50EF7AF4DEE046BD26041E2925 | |||
170EB7B6DC6060E78309CC8A136AE9CE44D3B4EBDEE4479482464D0D23C13529184021 | |||
795557323D353A70CC710EC2A79C66E860095C082E40724867A9ABBFD3407B2F92CB2A | |||
D0D95CC8DAC2FB2C0187B3BB09AEDF869AF1969BA641027D4D5DAA31B1DA5822D40A5A | |||
7FAD1C054C02CF8F8F692B1C45C879299C0E9D5E5A165F6C22DEEBB8C16FFB91F381C4 | |||
8FCB209657A7BF9268BD34808D0A9D3D6F50F7026BC297FD3A08790B8EB5CC0291246B | |||
16E4B50A7E9630B33F59B5EA24EEA396F07AEFD0C262BE9915CB32D5F03673CBD3D20A | |||
831FDF55B5BA3D03440A8E1A331147A8AE0760EC593EDC881F5F0A04F4FCBC80C1531A | |||
4DE71D014E3612C2C679BEF3AED59F358ABA5731FF80FA15EAD2CB95AC548F6AB0FD7B | |||
BBBB2CB63DFFE9E672605B7F54EEA4B4C046C4CC8036F2F76260CF068D232A40F492FF | |||
9648CC7459F0F46FEABA3D62B9F421B0F8A1BF914E41702540213848345498AA13F989 | |||
49EFC2888D3720DC34D20634472FC3A194F1403C1609C38A020F7E47F3205CA5C0CB50 | |||
26270083ED153BF97375407514BA15D92808A8C10F8160880F6981BE53294292E4EEE8 | |||
D215E7854FC79016B64984BBBAD2E99EED8D66B25575183C279E4DAFCB63F1067FA2B0 | |||
0888A9C226D4846376520720FC1E947A93A1D32444F78B2F4EB836A6F8C685C1D82958 | |||
E31560C3FC861D2B68B889E1B5EE0476B914DFE316411F750D252F24076E53557AD5F0 | |||
4050E5E839B33E5B8AF16FDD9FE033B39796A52DE8AF65375966D4DB137C85C800B5B9 | |||
0E29434E4B215DE35E60C85391DFDFA572C6F9747A0EA0964236FBB3B04394D9DF0694 | |||
6E4CC9CBCE352382908148D265293C6EADE7C2AED6F5AE#)(protected-at | |||
"20210119T160858"))) | |||
Created: 20210119T160837 |
@@ -0,0 +1,30 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
mQENBF7EL8wBCADO46xh7nXn7vZ5ow2Zdrp7WTh9BlT2wtaHNKpnKvSoYHjJbbGz | |||
yF8Jf/qVPuXNbjx2df1lT7zT7x3evcjQoNy80deftCw8ApZB9RMOo3uUIqS2VpO+ | |||
cS9rjTgBRFL6xDv3g4++CE9s+5dKE9gKkwleZ5/tVqUIoHPAIUEjpcPHngi5m2bi | |||
tSmQUYWLGcliR1E79sJMSzPt1neksqHFMJ1KTEJLAABZ0t3PiBzmycIQWThX3uU/ | |||
lcgnZmmhWCJIqV0yRZqxl61ejUfq+zK0T7MzhAAugqe7D6BM1FRwZRNCHwDQXIvt | |||
/t3fczTe+x9oTy4qX4MfaP8lHM0223MwGR13ABEBAAG0H0EgVSBUaG9yIDxhLnUu | |||
dGhvckBleGFtcGxlLm9yZz6JAU4EEwEKADgWIQQILQAv4wNQfEJ6I/NEWemKCmiQ | |||
+wUCXsQvzAIbAwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRBEWemKCmiQ+xev | |||
CACZSWh4xjTgafwGMP9RnReOhubVmfHS+XGlidDQzJDtshDQddPZ3oQwyTe3OgkW | |||
ZgOrzjrHGsZp3WZmGUZejrKt2Brqp+h+VRujFVcKk4N9A52BkM6OeT9lzBabOpuA | |||
UaDsNMSFsMcGTTYpB16+sDcyui8LW1jGi1y+8aQa+u1lIk/vVycq8o4htn2Af8xZ | |||
rAT8peapsjoNjETEs8OQ0al3Q0UX9amW6Rq1zZZ0XtoXDCPTI01EfczDMN+AZoFk | |||
UYHwSREDFLSh+c+q1HhYp4TqP+2a5Rayna//n7zci1PmSX7zD3iWzV1jEQ3Jm8U3 | |||
DY+P/WLezQdSJIBVCFpCualquQENBF7EL8wBCAC+ef+vNvfu1jl9BXpu6K9PG0I5 | |||
DQfrNtcdPq90O32ipvsYvqGOJX9MHoTyxBPLew+e5UsYb3ex62JyJqdAaqSwYXEN | |||
MBESZx7yBqBMUvildfh8dowbJeblxCf5KsE4C9uNfg4ApWGD7PjVsUCh47V8VcfG | |||
ymCxxq80r+4GfFtt/HC+l9fPUnDLuXpAWEM2GPUzcauUoEXxZK6nhstYCRlKlQcK | |||
Tn+LtCC7SGpYlqvwWBzAnOYP9+eZfSJ897g0AiTEhK0JsBlDAb3UAWHYHkAkVa1+ | |||
oU/UedhPC4j2Q7RzPQFMun6aGkaDrntCxvT7IFiMplPG7iy0JDd6ubrWSzivABEB | |||
AAGJATYEGAEKACAWIQQILQAv4wNQfEJ6I/NEWemKCmiQ+wUCXsQvzAIbDAAKCRBE | |||
WemKCmiQ+xoBB/9BAmlHQUmVl/bkwszAcyXkR5HsyA4htMJt+6GKlqftuhLP0SGK | |||
Il+7GeK6NqNdQXxXG5Wj6dn7ZqWalQRA0evEa6VLH+74zrn0llWfzTPIcP1bHW7l | |||
uYaOzZ1z/q4FoEGNJxp/jdToZ4970OXLzqY/G/QlMJIlXWCC0EXNYbKCEpOE9uvW | |||
h4kWe5xeGOmhZylYbzurTDzqEtKy+LZ9f2xNYn6ElcWtwxsxwSY7L9B3eNcCYE46 | |||
Np6uqzPffB9s7PHW46yEL1lQs6ME+9hBGyjeVop+Wg9qkh3YCrp+KY5Vkmdndwkn | |||
Th4FnTpcCiS06fCVHHC5kelh+H6TgRA+XQ/V | |||
=WGUq | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,30 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
mQENBGAHViwBCADaE67a5U8oqNjqg//SmlNLd+MrFIccHsg+pkSDhF6ipjZEXdFu | |||
oRQ116tH/qY1SzsHw/TMLujYeTBW0KwQ5E2+TWagckL8pJpDt7ZC08CTK6u0Xvjy | |||
BSqy/t29NPTuQxxxqRx5gq91mtuo8v00fQmqkbFUgkVfEOKOv4qe2tlaR5pTvpmV | |||
VboXOls87RPgP/X665kamHjsywrsDpZ5FbvPS8E2kKdYXqeHaiEU4i0Bizjx3diK | |||
ilPEIxxl8zgDsROXyKagCy0KOOajBqhFhStQH1soIzvk8aG/9eItKmTa2v1BD2mV | |||
UlZNQ9ZfsnXx3QIBLmA3jugH69rkcekHRCWPABEBAAG0HVRlc3RlcjQgPHRlc3Rl | |||
cjRAZXhhbXBsZS5vcmc+iQFOBBMBCgA4FiEEJJx/+EvV3v35cJ+Jx5r/T8UxegwF | |||
AmAHViwCGwMFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQx5r/T8Uxegx+hQgA | |||
pIy+E58aWh9FIHW/POqLB/y3v/GbYdIbzk9ro0FAXQ2tQsoGQbsuLckJVIlyja7n | |||
oQX23OmWTOc2tj/Kpy9lZ2ButW43FaMSiLh1G/VtM5pqJ9yHFdb1z7Q+LHMhhB7w | |||
RKOoNSEgkwtxv4LAkKz5t/BrDU0hvDPxWPqCSRvSAEE6qIY0fa3mLf9ijy3gLlCd | |||
hBayUC53W0tL7gLHgprTM/fX7b1pDab8beorroPHs5XzcYUBleaCGmEYbtV2eXPQ | |||
5irOXOC/D/E8vOfOZwhOhFOZk9b4UnhFK4OCfpKIzIooc6tlboVPhdx7jb5DkXQo | |||
rozfavEvAPx8INi9KNmdBrkBDQRgB1YsAQgA6q/O6mAPB0kj3pnpuIdJC8EumgKm | |||
7W8rv+ZfRGePg+IEEm5DeFKtfWl70YH33nGmwnWB95wO5412JCNC174z5LKDBbz5 | |||
PWT/yTNnmjooxj6G4p/YVwXYJkvfaDP+kQnYgJAybpeqTa30tES0eqvI0J9aQo1h | |||
GSMRCkE6QMV45IMj6gH9rptQv9e8U6gbnwBPxWPG2FH5rsGIGQGzIEmGxmKRyxXm | |||
YDU4f7oWPHSg1ikQqCzAxxCBxeCOaid3acLK8//TOwF/Do8GPJbcupEDqsgbFNGM | |||
BDWtmkmxjrLntlU+dvIPcsBxdBUrrADiJ/k7EfFv3kHfLfdAonSdKZL85wARAQAB | |||
iQE2BBgBCgAgFiEEJJx/+EvV3v35cJ+Jx5r/T8UxegwFAmAHViwCGwwACgkQx5r/ | |||
T8Uxegy4+AgA1bzFKpsqkwrjZKDCCT759xeuUbxnYE9kBJgFSVuhn7fUbB4MoHx4 | |||
shBptx7iBOdxxT7yC0oaDPhbiIkttb/c5W0f6JuLr08JpjkFfkrWF+dMcVrtXwPx | |||
i/30ccV98qWJDCBunyeCwBNie1Ck+qXMxm3FYy4qIbftMQ7mG6KKN6eFlbxu8B6M | |||
p93DFUvycGH9CWz0yJcho7KT0NSSyoLZhJz2uxRe1BwGMV20O9AG9yicsU0/uJxY | |||
a2Hble8NkH54XDuZkrsBaAb/o8UsWP7AJdYYsb904UZDIZNRfjWapOmODnlnK8Ta | |||
Q8pyYRGS5of1SapatMfpQZF6hdsamnTH6A== | |||
=guSE | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,32 @@ | |||
Key: (protected-private-key (rsa (n #00DA13AEDAE54F28A8D8EA83FFD29A534B | |||
77E32B14871C1EC83EA64483845EA2A636445DD16EA11435D7AB47FEA6354B3B07C3F4 | |||
CC2EE8D8793056D0AC10E44DBE4D66A07242FCA49A43B7B642D3C0932BABB45EF8F205 | |||
2AB2FEDDBD34F4EE431C71A91C7982AF759ADBA8F2FD347D09AA91B15482455F10E28E | |||
BF8A9EDAD95A479A53BE999555BA173A5B3CED13E03FF5FAEB991A9878ECCB0AEC0E96 | |||
7915BBCF4BC13690A7585EA7876A2114E22D018B38F1DDD88A8A53C4231C65F33803B1 | |||
1397C8A6A00B2D0A38E6A306A845852B501F5B28233BE4F1A1BFF5E22D2A64DADAFD41 | |||
0F699552564D43D65FB275F1DD02012E60378EE807EBDAE471E90744258F#)(e | |||
#010001#)(protected openpgp-s2k3-ocb-aes ((sha1 #3E87FF0806B054D6# | |||
"26420224")#7E8282B83522F91C53D76805#)#70B1997D514FF5800155A90FD785E7 | |||
7DC2D782C48FC9BE44D0192C0AD56804468C910A202191EAD077B5542C95FE72BCC450 | |||
0C2A8E8313C0CBD6C881236AC13E0BE893663946B5AABBDA57FFE4BA49973D547FA5DD | |||
1236DEF9FA5A9CE52F7AF1947F42A6C3502A47E8EF7E8CEFDDD44D0BFE090EA3220C2B | |||
52E11776DE36DD6C72D3B39A56F5D7295D26A69DB8CDAD1ABDBE1B21C1B754C9184E65 | |||
2CAE169E2F492FA0EE5908AC5CB3BE5F4C7F6CD9F41314D1BD9B1DE713A4E6C7DFB11D | |||
2E64000ECFBBC89326B1322A8A227ECE7B919408C9187B5C9D53FC3985833E76D72164 | |||
40B7386569E4DE270C3616ABD2A91A657AC58AA872704CB3DD4DF08C77D03D8E3CEDB5 | |||
0D83BC3837FFE45D64B457AFE9A6ABF680637C51F80CB54691233BC4DE640026ACDAAC | |||
3FC0749FA8353F6EAD5D362A63C1CF25ACA73A9CF3290B54C18DB3214AF078D918682E | |||
513C434EFA06D9045571B1734CAE42990A1BE962D6E2A45846169EAAF2CDBD520813C2 | |||
D4DE97FFFABE582A02CA893F91EAF0EBCDCEB70B35850FDDF56EEA60C845A7E5C052C4 | |||
33344776E7A4C787690CC0E13F32373EE425CA10520C251D045C0AE73EE7A0CA83C858 | |||
E2E528CDBD117BC022ED3F5DDE40CED0128B761E29B11F422C8E7C4281BF94F6F75D07 | |||
0EE58426137548ABA38019A34DF1A66F700C29EF5545AC88BED75B5036801F0D8D4DB9 | |||
C6CCEA83D9DE3D626A04A80F218EFE9C74C173412A8A86786AB4A85403E8F8292CFED5 | |||
B8BA72FB5CE1BDD094AD9D633FD482F8FDBFA540DD2224149786ADA8DB6310A7C0C6E5 | |||
9167815B2CEF34E7C458C41B5C56A79414BA57073E9B06D28CA08C56ED5E685EEA2BA5 | |||
DD112F87B253A0D02AC7CF93EDE93F48A80B2DB57B254937EA80E9AC1CEBD36FD297EB | |||
C8A3B42CBC3D2CA732891B49457F3F15AA3F9BF93553968A07CB1A834B392F27B2D152 | |||
47D93E46A6338694EA53CA0F5968109B4FAC9A#)(protected-at | |||
"20210119T215925"))) | |||
Created: 20210119T215908 |
@@ -0,0 +1,14 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
mFMEWsODvRMJKyQDAwIIAQEHAgMEQLOxiiHZ/V6v3kvrhbnRtTp+oOPVpuvDKOiy | |||
gJOCZ7EWMVAwTr4syaSh8W8hdRgZ85Evv/1PYNFovYb6vzgVr7QJZWNjLWJwMjU2 | |||
iJQEExMIADwCGwMFCwkIBwIDIgIBBhUKCQgLAgQWAgMBAh4DAheAFiEEBjPF9yoZ | |||
j1HmUOSr0Mij2vngY0oFAlxVsKIACgkQ0Mij2vngY0pARAD/RozGDidH/0aFlxeU | |||
VWNJKjPiax6vdHqur5dqBS/RhhIA/1sPUnyAIvAXXID1uhK6oIBRKi7WJ5rI7vSy | |||
rBR5MlNJuFcEWsODvRIJKyQDAwIIAQEHAgMEE9Vd8dIjHJkmRs/8MLz4Krfwz5BK | |||
hunq1T0xnp65OEZJd00VxA+VUXdEUHfaDehtSv7izCpq4lbXGCkEGFN7QwMBCAeI | |||
eAQYEwgAIAIbDBYhBAYzxfcqGY9R5lDkq9DIo9r54GNKBQJcVbCpAAoJENDIo9r5 | |||
4GNK0MYA/2p5cq5smjSvKD/EGkosQwfcqkeygsQuEpDDLeEdsv8vAP9j+RHKX2tl | |||
W08zbayxGB0E+aCHuKCF8iLPeI4eroi/fw== | |||
=vsa4 | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,17 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
mHMEWsOEUBMJKyQDAwIIAQELAwMEivcvlPJsPmivhJcrfHx+ORxyum57GtRhWM49 | |||
Yr8fJ48gyFqj9cLYOBdhEVvcfceyBPXmyt0TozWtjkGzgbF4LIvN1EB0DW0Rlsdn | |||
p72/hf0gnXvWZdD8euArX4RaAYuQtAllY2MtYnAzODSItAQTEwkAPAIbAwULCQgH | |||
AgMiAgEGFQoJCAsCBBYCAwECHgMCF4AWIQRbiiVMgjztmN7NEO1s8tzoVZmtogUC | |||
XFWwugAKCRBs8tzoVZmtoj1yAX9P1UV7FYpGUIP13aPP0d5Bx8HdQDAoexdXz3WW | |||
WPL/7OhSjPde23Q8TfgWyO21M2wBf1oWjOsDSjO5mDLCr7ypAFF6IJAgx76tSUe9 | |||
Qmy7sL94OWDQ4+1Dccnc9GGiHLtRI7h3BFrDhFASCSskAwMCCAEBCwMDBETUkqGr | |||
7p8kX2dm38jzzxXRh1+OL7nmY168Zeo9yfwDbnyx8BoihP9ZgPWjGXmefT78GSfw | |||
ZDaYgC2NFQOcI/b8agh3PcjrXgZaFCZbUR9v2DnLUpCF8ZbxDJwEqweNTAMBCQmI | |||
mAQYEwkAIAIbDBYhBFuKJUyCPO2Y3s0Q7Wzy3OhVma2iBQJcVbDCAAoJEGzy3OhV | |||
ma2ig1IBfifduIiwdAlD45MOolSpHMX0AT7KoJHpt9ZFvWnjQkq9ZGEA/RA9vx7Z | |||
sLb7IsG1GgF/Sn+gtf/JIteXaZMnOhEOZ2oFUufij6o8gII8/9s8mkIjkrIICy// | |||
0n3q82ndFg0c | |||
=fcpz | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,19 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
mJMEWsOEhxMJKyQDAwIIAQENBAMEA28ylDnn3LR7t6EQow5DszCpmUA+yup03LsT | |||
9o0Tw4/asi8nAz+1tlRY5HD49j53PziOlsGzKYa/jxGWjhVESgqLrJp/Eo65zK9v | |||
yDhX+iCkSYQ15WGKr3QaRUmBOUbX9PqE6dY+DDGQ1kewI93QIGCB1gn+OSmyKPm3 | |||
YaVIbo60CWVjYy1icDUxMojUBBMTCgA8AhsDBQsJCAcCAyICAQYVCgkICwIEFgID | |||
AQIeAwIXgBYhBExZq5JyqmofYLhb0KpcWNFPe49IBQJcVbDYAAoJEKpcWNFPe49I | |||
F8UB/i8DwypbNusdbAqTbu1Twpn/QFMaVKHn8Ysgzqpimv+6hRq7uzekCvEOPOjl | |||
Oke5yLp8bpTTMPRKyfjNatQhdn8B/2+54qtXJuQd9oTSz7f2eFYvA8ZsMQgApYNl | |||
ksvKSw6dhSNX/DXK7JYIlgZXx7UGTkP4h3FQSiyCUJhVpClVVGa4lwRaw4SHEgkr | |||
JAMDAggBAQ0EAwRCtEqQkEgzQDxNGCj0duj0aGvnH+DHKlP4V6p9LJVIL0TuF1uZ | |||
BzP04efRvZT2vzCTcvvdE/G6G/txEZsR/989OchbkVWOPM/oCVktkaA02rBMcefh | |||
k9wKD+O9E3oHEN+tBt3yhmsv0MIR9IfPwi1GCsu55p4WUI//+ysB2T0YaQMBCgmI | |||
uAQYEwoAIAIbDBYhBExZq5JyqmofYLhb0KpcWNFPe49IBQJcVbDgAAoJEKpcWNFP | |||
e49IZQUB/R4U4aWBMimZSL8kyaK+/Y8NcInIGqRzrm5zPnTSHrgQeH55SVKahzsq | |||
j57D1Ec1HnUd4ctISVocOxpUfnJq5NAB/1fzbh+1RN2ZyNW6tAJlA/Irkwzzbil9 | |||
6fAIvRolwwaGsUZNMEiCF3rTcFaenJg9UhQvX6BoqXCdwawqTZCRN6E= | |||
=h+On | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,44 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
mQMuBFrDf8YRCACHbPXT8jG3RNWdNms9xvdaiLrY+Iui1Gq2WGLSajPEZVASEWN+ | |||
JuuX8k9d05rb+F2VAqLnW3CQreDW6unVNeRf52tdM8J4eXmeu/Bkk8y1Qx/HbGca | |||
sAGSIEKg34TuV5Ly5m4Z07bs3HPYUUQbmu0uclGfnX/ArZ+4Jp+uypC9bErdiXM0 | |||
cM7d52tb9IvOlXNu23rzHDbgVP6qF/AxLSRD8SQPvshu3/5b0bvdBkHVk+dHoLO0 | |||
fC5j476ibHGGZcnPMrTwqEIAxUCy5wQ3Lb/2/G31kuV55bAZ41tUNEvfzbiRN1L5 | |||
1uiO+XX96bRqLN13t0Coaba9fq1aN5Zr6piXAQCuNzvj8aaLXAOEXVRej6a2k+/C | |||
Jny91MgjSM701twUDQf/RMWHwQuFPe6zSDQs4pWlxkHwXJw3AVidkoWg/DCwv2pJ | |||
5VYQxBXRwND2OhcZvmeDT94UzPws0dFbprWyymtA49ZXitPGzFARAFWHWxk/IsOf | |||
Idc6w5eHXDMHxLhiPFqfjKeNpibzO2P7LXP2bUKzwybkKZarz1N6pfanDXAtC4DU | |||
SC3qWNqywYlfINAGCdwsPu5qFUNSnkjTYxe/MiHb4kL1p/z8qFNWrvg6GryXygp5 | |||
cLdqckjPaUHlR+B9wQZIVRzVdlFAbMDJ0EERLFG7FbIuY8dzy5x7n+oBOgRxee2I | |||
ytUpGVMLIJuecARLXNKsMXviCMYVE7Tj5hiSoM0TIgf8CwLLFsSa0EDm/wlXYZMj | |||
2gg3Z8iCz6ycxvFD9PXNt+8jyELO8CwS2pWu7ptBgaugkinqd40EQslQoP76CcHq | |||
bGQEohm4SnmfGsV8dicuziMVVKkVrYgbGvZ5cQ/ONGTTnSJuiTPN19oztwh8JOEc | |||
Jd4l+wFuVSm8OS1mj5eexeX1Tz3NfWQMT4deKh+jiTLe9Sw/57sSjxiw/8IczqhN | |||
Fu3YIy40d3Bv+OF6i8I+94WLbJPiX1ban1wqcA0bMaps1aYVtTRZ+mP0b3M9W7qa | |||
383/SLCBjUzQ7zm6PX/7uAXFyZOQfcyLaJ8Hc34yOE0git1DWmRS7U16Zv54v1Uh | |||
HbQGZHNhLWVniJQEExEIADwCGwMFCwkIBwIDIgIBBhUKCQgLAgQWAgMBAh4DAheA | |||
FiEECRxEzpz7w/9+x6ZNyKEKfXgnPhAFAlxVr2sACgkQyKEKfXgnPhABkgD7BfEd | |||
jhB+ApC9icNLs893i2jiHbAxZGSOQMRhCaJ7AzoBAIipcSIsBa3LJ4eTec1esiCY | |||
a8xzxquCTA+oANNoX7p6uQMNBFrDf8YQDADMPZ6+/YAIjXMLfQKX80jz6FZ4Kdfx | |||
Dc60m4O+ZElMv7eXtQJC2L/xOh4Th1fZUQIhSdtFiwaCSkCD8occfJwyt+lH3Dj0 | |||
Qrh3mIycAfPrjj0Rgxz8nRQbBLDbLF1QGPimt0zP69ByJ3opLujVVi5ixwgwza9S | |||
eGffKwGdyb9uFcB9MVnC997zfLvx/uNV44BwLnCH6Tp68Lynf+FpuvSX+Rsj4li3 | |||
UiLoVxEIbBZ/5Bn3ygc7aW4fM4bR4hKjWwJR0Hh1y/kt6A7dEAypVKBfSqAtAu2A | |||
zYAq3USsbtq1X1FaGEsmvcJY8IGa+aLTArq7dkhXzcv7K3EVdqOawS1zS/ARuG+B | |||
k6kct3zzyj1EitiTvdMAkGOoyk16qKVzUcbFRVC1HsZtxYj6OxU4Eazvh0LjvZ0A | |||
+eft/XO/ZmN6vyRaF1/10z+uHPfj1FLMpS8Zn4SN6x7Qtsx3iLL1n9cKBDFRXCqD | |||
HDaxLVC3N4zAI2hMMmZid+fbTuhsqYbSX2cAAwUL/j/H4/9Ml7PUUCXoozX2V4K+ | |||
gi6WEYmY+pXN/we9NuFulW4aURo7jK4wRYBu0BS3K9e8f8WUMAV5V6ShPWHXcobt | |||
iuSjLYJwdBJkgHbnKFWPZUozJ3Ftyp0Lh1M5bN7/ECofAxLHbRpCVrcOP2LC7vAU | |||
AeMgdiFDqEiLCnr/aGvqUOxbGO6Isi4jvaM/ZUfGjGe/Z6yVoqm6wEsNM7+9cFGQ | |||
QR1lRPeCPKcLeasCdbM5EIt1aLFNijZigWuDRLIgG5PuzA8Kpdk/u/UuCUeUFwJN | |||
ym8MEv2JJDiWHmb8IcgFMp40VenUs0fte0LWwrMjWVPpLsHKmkraRjQ1UtarRhT0 | |||
ANYilGjZWCnCb11xGKhlM7r5IkLGY/L/Eh4vjLgg9T5rGwOF8p1jSgx9mA8SpHV0 | |||
O0BoKNX1ApWEHayTLcyayCnTYbY/e4axnSKodixAI/NghOnJHqGr4LeZeKk/Q0mm | |||
GlljzFv3EAdoru4DVowWGFBmrwBy7o+GLgHs6K/+yIh4BBgRCAAgAhsMFiEECRxE | |||
zpz7w/9+x6ZNyKEKfXgnPhAFAlxVr64ACgkQyKEKfXgnPhCETQEApruWUqCwfibQ | |||
vyI/OZohPzljlvIoioj3rFjYNpufQD8A/RTaYtnPiEvsPynEZCj9zTV/SuHiKbHS | |||
v5BhpoOOm+jM | |||
=PnGk | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,9 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
mDMEWsN6MBYJKwYBBAHaRw8BAQdAAS+nkv9BdVi0JX7g6d+O201bdKhdowbielOo | |||
ugCpCfi0CWVjYy0yNTUxOYiUBBMWCAA8AhsDBQsJCAcCAyICAQYVCgkICwIEFgID | |||
AQIeAwIXgBYhBCH8aCdKrjtd45pCd8x4YniYGwcoBQJcVa/NAAoJEMx4YniYGwco | |||
lFAA/jMt3RUUb5xt63JW6HFcrYq0RrDAcYMsXAY73iZpPsEcAQDmKbH21LkwoClU | |||
9RrUJSYZnMla/pQdgOxd7/PjRCpbCg== | |||
=miZp | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,23 @@ | |||
Meta-Description: Example from GPG file 'keyformat.txt'. | |||
Description: Key to sign all GnuPG released tarballs. | |||
The key is actually stored on a smart card. | |||
Use-for-ssh: yes | |||
OpenSSH-cert: long base64 encoded string wrapped so that this | |||
key file can be easily edited with a standard editor. | |||
Token: D2760001240102000005000011730000 OPENPGP.1 | |||
Token: FF020001008A77C1 PIV.9C | |||
Key: (shadowed-private-key | |||
(rsa | |||
(n #00AA1AD2A55FD8C8FDE9E1941772D9CC903FA43B268CB1B5A1BAFDC900 | |||
2961D8AEA153424DC851EF13B83AC64FBE365C59DC1BD3E83017C90D4365B4 | |||
83E02859FC13DB5842A00E969480DB96CE6F7D1C03600392B8E08EF0C01FC7 | |||
19F9F9086B25AD39B4F1C2A2DF3E2BE317110CFFF21D4A11455508FE407997 | |||
601260816C8422297C0637BB291C3A079B9CB38A92CE9E551F80AA0EBF4F0E | |||
72C3F250461E4D31F23A7087857FC8438324A013634563D34EFDDCBF2EA80D | |||
F9662C9CCD4BEF2522D8BDFED24CEF78DC6B309317407EAC576D889F88ADA0 | |||
8C4FFB480981FB68C5C6CA27503381D41018E6CDC52AAAE46B166BDC10637A | |||
E186A02BA2497FDC5D1221#) | |||
(e #00010001#) | |||
(shadowed t1-v1 | |||
(#D2760001240102000005000011730000# OPENPGP.1) | |||
))) |
@@ -0,0 +1,14 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
mFIEWsOCNRMIKoZIzj0DAQcCAwQS5G6mn5dhamZ6678SXE1azavqf8BItWO9Qv8V | |||
dS1vEEoD14urr5OQKTLuHhDRjvSQdaxRtkf0sI51T7230sT3tAhlY2MtcDI1NoiU | |||
BBMTCAA8AhsDBQsJCAcCAyICAQYVCgkICwIEFgIDAQIeAwIXgBYhBLVP3ru2c0I6 | |||
XQqlRCNnTyGyRBUnBQJcVa/nAAoJECNnTyGyRBUn1ycA+wVg9sEfHDBaGtLqlUSB | |||
WdGKURrHN7CJe2UTz1/7oQCBAQDDi4RQyLHs+TfOrBNSbLEswCu1oEh8VmHt/SN7 | |||
+mqNLbhWBFrDgjUSCCqGSM49AwEHAgMELDOArLIG85ABQu1IwgQMpiIuUwj+N7ib | |||
gGenTRck5dkBpX48eK3lbjovXn4YkBneA7z14iez3+Sdg6UFAMFV2QMBCAeIeAQY | |||
EwgAIAIbDBYhBLVP3ru2c0I6XQqlRCNnTyGyRBUnBQJcVa/vAAoJECNnTyGyRBUn | |||
ZKoBAJ64gv3w27nFBERvIsRqufvR6xcimqS7Gif+WehBU+P5AQC5bqoISh0oSQid | |||
adI84f60RuOaozpjvR3B1bPZiR6u7w== | |||
=H2xn | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,16 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
mG8EWsOCnBMFK4EEACIDAwTRTCLBHlq6SUTiXZfWR0vbUh/0VAlrePaqHVIE4LEK | |||
0UBhPCIQOGuGL4JIufc8UzBWhiMLJ0z7KRjBWufsMZR2+rqj+unOK2lLu7sc9or8 | |||
X6B74hhP3Ili24PgGFAeAG+0CGVjYy1wMzg0iLQEExMJADwCGwMFCwkIBwIDIgIB | |||
BhUKCQgLAgQWAgMBAh4DAheAFiEEqyXLoELdkkw6zD7TJCo6peqF9EoFAlxVsBEA | |||
CgkQJCo6peqF9EooJQF7BPZelriXwZ/kJzaamImHBddkLFc7d2WbuSfDxEZQ+Mfw | |||
BAP3+QYUaFtfeqApjY69AX4w6LhTUgI2kl4O0Vc7ZOlqZBlwAc8CMV08TTfOEio2 | |||
b51SItvhLdDrFRJ2K4jiO+a4cwRaw4KcEgUrgQQAIgMDBORWqhYflSrYzF04SK8q | |||
8Om+DYTvwRtUlr3Aoq44+gm5yBcmJmgT3TKrp/bx5Jg/zwzIASFn0agbxkqKpQqH | |||
sHeelWsSBROQzy98HXdCp3nVmghI2aDk8zdD6AV4m7c2ewMBCQmImAQYEwkAIAIb | |||
DBYhBKsly6BC3ZJMOsw+0yQqOqXqhfRKBQJcVbAZAAoJECQqOqXqhfRKgAIBf3Wk | |||
TsqUA1JXkPGetA9sjHglIICN+DZY5k+PwTJUxaW2zrkiPJ3BYEnKbmmBLzA7BgGA | |||
4RYatyl2WOUYh/poRLgu7JpE4oRqdmNA+QOpCILMId1AeXfj4W01RKFWaKeH+3Yy | |||
=2H/0 | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,19 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
mJMEWsODGxMFK4EEACMEIwQA8OZCJ8Iv4Qr2oRr0kqez0nPSW/vNxYBZRpCJ9ab8 | |||
kVaRhW7+5vEsecm5XugZSePbAmERmk3oEiSgu35r6aovowcAGrOBfBm9fyIVqaoX | |||
veTS3yRHH6NEf044+pC+uBaaFukkrDmVTecdRvYr3Yrdc5ifyOve053znlpQ6a4n | |||
9bh4GGy0CGVjYy1wNTIxiNYEExMKADwCGwMFCwkIBwIDIgIBBhUKCQgLAgQWAgMB | |||
Ah4DAheAFiEET7Of9vpIV6S9fvW0IJLKgyQmO2oFAlxVsCkACgkQIJLKgyQmO2oK | |||
DwIGO72zo6otVkbHfeI9hWx/8FAOXh4MT4YtDicF/sj8QbHzdbEBHcLCByLYAnph | |||
8VVoCxpPcBLmNSHbNyreoksjEE0CB10P5kPrd/bYkdNx/HTu+1i8f7a448+Nr2rF | |||
PwdI9tOsghkT41qobZavjjnBlT/xv5DqXldJkEfaeiJxPHOKvMhWuJcEWsODGxIF | |||
K4EEACMEIwQBAY7ZCAjks1MWWxibg/EVaz5t6iEKJTwu8mGGKWdPZAQRKKNtNpf0 | |||
pZAMV3I8ue/WQMsYKRYv5AGq1PnjV19DmLsA0aGw4MDM260coctkcn/2MAJQMC9+ | |||
3Z+BJS3hqzwDuZ+LS13r0RLpgnt3ks+3ucG4II38ZZ1lTwKoIc+w/OuhsOIDAQoJ | |||
iLsEGBMKACACGwwWIQRPs5/2+khXpL1+9bQgksqDJCY7agUCXFWwLgAKCRAgksqD | |||
JCY7ahqbAgkBiXYtiBlp5dmSYnbc4JoIYWcxTBQ+/dGHyU6ZEfC5VQz2mrdJetK1 | |||
bIID0rFSsd24/8IzAqM3L+nY9h9bULWroroCBjTohh0j2EbW+hFOrRqL01osnlY+ | |||
1/G8e44blB5JqsPI9FqOZOUj6IzsUuV1N9gJbm1RHu/hSpm52d6rX4nOTbqt | |||
=3jnl | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,40 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
mQGNBFrDgZ4BDACxg83nNkYvIAz6Nk4Np4BscWDrrL3tyiiQSz1yfCotxO8zUtVl | |||
JorSlqRurNdAYU2XJLakMqpQHE7VVIMI/WdXCC8CrQbULOBxIf/LGiQf0VDo8ukg | |||
iFFd5vUeMRRILWKnMc/GCmFkFOUHd1Y60h96oe5f/d286fRZQnCO8PGS8CgB1mDJ | |||
GBY8U1DCCkt6g9O6bfFkfcwetr1+kB2cBIY7uDzN1Sm8dz2VrkqPqtqt/F02giRN | |||
hD2GxX9HVYCkCKEE9DFsB+MDKR9z5lXrI3SAsL/3htXK/ukWgBe4DIFjTXbrzgP+ | |||
nuWb4s1NxwSD7yjlnqVD7mZTGAwMsQbCjhwIeY4t5onsCJ4/40zm1jIZ5TJsfQ/b | |||
5gA7iu9kMKzxO0bPI2loJEB/K9aH7qsyQHgtt7G3+G8JrixLBUobtreY9V2QvhtC | |||
Q4OAHRO5nIKYIazDuKv9bxautZ0WuLOk/qmWMMoqFAn5bzQeVTTBD6kvr6l8/+MZ | |||
zaij9YPeUbeKJuMAEQEAAbQHcnNhLXJzYYkB0gQTAQIAPAIbAwULCQgHAgMiAgEG | |||
FQoJCAsCBBYCAwECHgMCF4AWIQRrwEpaPds1dmuaQNgvuReRGImOiwUCXFWwhwAK | |||
CRAvuReRGImOi1NiC/0RPjbQTWMw4/GxIMkRb9kmmsSUe7kCgqBCqZTxcI7rxZdn | |||
JFDbP5c6DAS/11bRQJ9OsoUjbDx0d81UuBlXB/mNsb9nCcXOrqAUHRqgWoNSDk4g | |||
9Oa1Kx77OM9BvRJbJGch2YW5Wcch5vcqQNu+6x3VGt7ipljYEJSQ6Dre+dgxYjXK | |||
60x63/ulFk2XImPQYjQ8VHbW/HDg/+DLf++phjVy9l58U1sUKSSdO8uuYoW6dBv2 | |||
xRg18Sn3DWOU+mrkV8Ld95+NRRE1cSHTQv5hu4ELqrV+YdGNmv9DgQAMJOl3xy8i | |||
vOz4cpKaOBasm423wr5Y56nOTzLFN+dxnYR8tbqswLkCldRY6fvL1NsS77rj0yZp | |||
pecCyi0E6RAcmSiZJqpnOpcuI76AkZuWSDEP3Y3x5QBf5fu2uiQQsPXYN8ie6xcC | |||
zeYtXsHyNxF0oBh2c26po8fo4E4T70RSO8Oqs1XzXnjIIle8pKU9M5U5ISbWS3Hj | |||
vtOn5ZrLC5KYnVRna3G5AY0EWsOBngEMALmXpJoPC1m4THYrfHibtt2/OwAlDm20 | |||
3xn+Klw69bkeXdc71wsLOAHVL3+7gXpip+IYmN7CBIyqlOCtsluu+gwP3MczPJZX | |||
vk1uXMMfLKiXl9Kodx/Fqq0Y26Tqse5PPMlagPStIvKyT0WTa3RCD28uVklapLuy | |||
1w1k4G5hIDPt6uKyxXq/HzneRSGWafmqoCWOmXQZzfOMG249bMXNOcPMJhOejPRS | |||
jREnnntbpvZ8DU/38+JFtqCUkPwuqYQkvGCKReSBifMiG3XAhHWOGzXPzdW1XdAi | |||
aA+NQP/kMUs45jS3hDdp4EObllYRBsQwtFpKPMNmwaVuOmVlbrXTP0YsDYGndkE6 | |||
5nJ46/2xPhl8+nIgDLg3SBBzQdOiPOGtHYjs0bRKdwXTeAq4fDq0vCQXMJF2fwAQ | |||
LEYWs7kabKhcPpWzTtoCG78WzR3TgldEPhPjE0offvVQO56x1XDqMBctoiDWkWkS | |||
bdi03GhbFdK5A7uYBTJYEoo61Yp/2/MjyQARAQABiQG2BBgBAgAgAhsMFiEEa8BK | |||
Wj3bNXZrmkDYL7kXkRiJjosFAlxVsI8ACgkQL7kXkRiJjoumjwv/c6a9G1bi3sh7 | |||
wRFhpsrFUoFfEBDI4eyI/haWhCIfI8n7p3lCSIy8lmf9yvUs75d5M3EQW08NQjIs | |||
/o8FcFoUBnKQv2whWSHTpx/BkuhcNVY+NIwyBKomU0WkFSm3+80ix0uh97KSlRlW | |||
Q5nMVExNxZ4mRFAhDQrJ2/pZ2DaddeO+4uZ7Twquaix+PMxpNKvkj2+757L23YjF | |||
QmHdk6E8burofpSCfBTB84eUSDvzs6Eb/34/KlbBZhKMYdffMDCSAZIMfIav6YVJ | |||
UDzT40kmS0vRW6bDIetSbpBM+GD1cSq0wKdlt+Giur9ZiaiyHIEqbPgr6WgdND25 | |||
Vx/i23Ik2o8wMb0Ub8cKD9wjdGAk+Rt2r7d2RzyO/R3ThKbUOGkQX6acAAZAjhPs | |||
UGxt1dDojmQ3nF4l2hZ9PcsyD3pz226wUUPT4JA1eE6tdoVjzY2J7EhfNaVcQQlb | |||
bQJQ+BQcO4oP1mPRCx1GiSmB+jRNQ4npxVJxLO/j7T27CrSZbhT7 | |||
=aibx | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,14 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
mE8EWsOE8xMFK4EEAAoCAwQVHqFZWqedXUIkNFs82PsQB3bsCDhrL/73xZca3+vo | |||
kB4T7jHcACThuMZYuUqUo9NzNTJioluOvZG+UdYXPdfdtAplY2MtcDI1NmsxiJQE | |||
ExMIADwCGwMFCwkIBwIDIgIBBhUKCQgLAgQWAgMBAh4DAheAFiEEgfdytX1Ov+cA | |||
CmYjPqW7b5aSwaAFAlxVsQ0ACgkQPqW7b5aSwaD2tQD/R4d15NBuSJ6IB1brH0E9 | |||
nEWkqo892PaAY5akdCO/i9EBAMsjE5NPxBnCs03c+VHFU200k27ixdrWpUa+HZEI | |||
A5wSuFMEWsOE8xIFK4EEAAoCAwSUWwe7CaaOYRANiKet2evLiOumefIHuvRpyOSK | |||
hyRdclIWpBUCAWEnmalkEL/8cEM5fjtILtCOKXqCOBsPv45HAwEIB4h4BBgTCAAg | |||
AhsMFiEEgfdytX1Ov+cACmYjPqW7b5aSwaAFAlxVsRUACgkQPqW7b5aSwaCETgD/ | |||
YXzCMYMbPGAU2oTitjAno8hDWmgTeaFWeCmqf6l9mP8BAKvpewWeFGZfWGAQcWPi | |||
E+jv7vadvEt1yMA8rmT041F5 | |||
=mDCI | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,13 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
mDMEW8SVGhYJKwYBBAHaRw8BAQdA9SMZ2uw0YugMFcl5TpEZeBRAGniEk9a42XNs | |||
7QA4Tky0DGVkZHNhLXgyNTUxOYiQBBMWCAA4FiEETJc4pvK+Thp5bJt7lBgioPwb | |||
MKUFAlvElRoCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQlBgioPwbMKUi | |||
1wEAgMq3X7o17OJBPfY3He/exDR6LhWwAAXrVQR/WdRiHkEBALd1Mj0BlZZLoKTr | |||
uJ4MD5CYZLicXTRwOv6e52F/DHwJuDgEW8SVGhIKKwYBBAGXVQEFAQEHQA0Lh2mG | |||
lB1O4xDYgztm/aX7+8AdHEGaMsCF1RQ6wVUeAwEIB4h4BBgWCAAgFiEETJc4pvK+ | |||
Thp5bJt7lBgioPwbMKUFAlvElRoCGwwACgkQlBgioPwbMKXmlQD+KxVg2dGL8lRW | |||
rQajwzmuwMrJX1lvJylg5Ozk6SGrBeABANZrdt8bmArEqeRVxFO2F4P7btyIpf1w | |||
5aNpqqtvkRcB | |||
=EYfV | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,61 @@ | |||
/* | |||
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> 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.gpg.bc.internal.keys; | |||
import static org.junit.Assert.assertEquals; | |||
import java.math.BigInteger; | |||
import java.util.Locale; | |||
import org.bouncycastle.openpgp.PGPException; | |||
import org.bouncycastle.util.encoders.Hex; | |||
import org.eclipse.jgit.util.sha1.SHA1; | |||
import org.junit.Test; | |||
public class KeyGrip25519Test { | |||
interface Hash { | |||
byte[] hash(SHA1 sha, BigInteger q) throws PGPException; | |||
} | |||
private void assertKeyGrip(String key, String expectedKeyGrip, Hash hash) | |||
throws Exception { | |||
SHA1 grip = SHA1.newInstance(); | |||
grip.setDetectCollision(false); | |||
BigInteger pk = new BigInteger(key, 16); | |||
byte[] keyGrip = hash.hash(grip, pk); | |||
assertEquals("Keygrip should match", expectedKeyGrip, | |||
Hex.toHexString(keyGrip).toUpperCase(Locale.ROOT)); | |||
} | |||
@Test | |||
public void testCompressed() throws Exception { | |||
assertKeyGrip("40" | |||
+ "773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB", | |||
"9DB6C64A38830F4960701789475520BE8C821F47", | |||
KeyGrip::hashEd25519); | |||
} | |||
@Test | |||
public void testCompressedNoPrefix() throws Exception { | |||
assertKeyGrip( | |||
"773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB", | |||
"9DB6C64A38830F4960701789475520BE8C821F47", | |||
KeyGrip::hashEd25519); | |||
} | |||
@Test | |||
public void testCurve25519() throws Exception { | |||
assertKeyGrip("40" | |||
+ "918C1733127F6BF2646FAE3D081A18AE77111C903B906310B077505EFFF12740", | |||
"0F89A565D3EA187CE839332398F5D480677DF49C", | |||
KeyGrip::hashCurve25519); | |||
} | |||
} |
@@ -0,0 +1,143 @@ | |||
/* | |||
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> 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.gpg.bc.internal.keys; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertTrue; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.security.Security; | |||
import java.util.Iterator; | |||
import java.util.Locale; | |||
import java.util.function.Consumer; | |||
import org.bouncycastle.jce.provider.BouncyCastleProvider; | |||
import org.bouncycastle.openpgp.PGPException; | |||
import org.bouncycastle.openpgp.PGPPublicKey; | |||
import org.bouncycastle.openpgp.PGPPublicKeyRing; | |||
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; | |||
import org.bouncycastle.openpgp.PGPUtil; | |||
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; | |||
import org.bouncycastle.util.encoders.Hex; | |||
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; | |||
@RunWith(Parameterized.class) | |||
public class KeyGripTest { | |||
@BeforeClass | |||
public static void ensureBC() { | |||
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { | |||
Security.addProvider(new BouncyCastleProvider()); | |||
} | |||
} | |||
protected static class TestData { | |||
String filename; | |||
String[] expectedKeyGrips; | |||
TestData(String filename, String... keyGrips) { | |||
this.filename = filename; | |||
this.expectedKeyGrips = keyGrips; | |||
} | |||
@Override | |||
public String toString() { | |||
return filename; | |||
} | |||
} | |||
@Parameters(name = "{0}") | |||
public static TestData[] initTestData() { | |||
return new TestData[] { | |||
new TestData("rsa.asc", | |||
"D148210FAF36468055B83D0F5A6DEB83FBC8E864", | |||
"A5E4CD2CBBE44A16E4D6EC05C2E3C3A599DC763C"), | |||
new TestData("dsa-elgamal.asc", | |||
"552286BEB2999F0A9E26A50385B90D9724001187", | |||
"CED7034A8EB5F4CE90DF99147EC33D86FCD3296C"), | |||
new TestData("brainpool256.asc", | |||
"A01BAA22A72F09A0FF0A1D4CBCE70844DD52DDD7", | |||
"C1678B7DE5F144C93B89468D5F9764ACE182ED36"), | |||
new TestData("brainpool384.asc", | |||
"2F25DB025DEBF3EA2715350209B985829B04F50A", | |||
"B6BD8B81F75AF914163D97DF8DE8F6FC64C283F8"), | |||
new TestData("brainpool512.asc", | |||
"5A484F56AB4B8B6583B6365034999F6543FAE1AE", | |||
"9133E4A7E8FC8515518DF444C3F2F247EEBBADEC"), | |||
new TestData("nistp256.asc", | |||
"FC81AECE90BCE6E54D0D637D266109783AC8DAC0", | |||
"A56DC8DB8355747A809037459B4258B8A743EAB5"), | |||
new TestData("nistp384.asc", | |||
"A1338230AED1C9C125663518470B49056C9D1733", | |||
"797A83FE041FFE06A7F4B1D32C6F4AE0F6D87ADF"), | |||
new TestData("nistp521.asc", | |||
"D91B789603EC9138AA20342A2B6DC86C81B70F5D", | |||
"FD048B2CA1919CB241DC8A2C7FA3E742EF343DCA"), | |||
new TestData("secp256k1.asc", | |||
"498B89C485489BA16B40755C0EBA580166393074", | |||
"48FFED40D018747363BDEFFDD404D1F4870F8064"), | |||
new TestData("ed25519.asc", | |||
"940D97D75C306D737A59A98EAFF1272832CEDC0B"), | |||
new TestData("x25519.asc", | |||
"A77DC8173DA6BEE126F5BD6F5A14E01200B52FCE", | |||
"636C983EDB558527BA82780B52CB5DAE011BE46B") | |||
}; | |||
} | |||
// Injected by JUnit | |||
@Parameter | |||
public TestData data; | |||
private void readAsc(InputStream in, Consumer<PGPPublicKey> process) | |||
throws IOException, PGPException { | |||
PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection( | |||
PGPUtil.getDecoderStream(in), new JcaKeyFingerprintCalculator()); | |||
Iterator<PGPPublicKeyRing> keyRings = pgpPub.getKeyRings(); | |||
while (keyRings.hasNext()) { | |||
PGPPublicKeyRing keyRing = keyRings.next(); | |||
Iterator<PGPPublicKey> keys = keyRing.getPublicKeys(); | |||
while (keys.hasNext()) { | |||
process.accept(keys.next()); | |||
} | |||
} | |||
} | |||
@Test | |||
public void testGrip() throws Exception { | |||
try (InputStream in = this.getClass() | |||
.getResourceAsStream(data.filename)) { | |||
int index[] = { 0 }; | |||
readAsc(in, key -> { | |||
byte[] keyGrip = null; | |||
try { | |||
keyGrip = KeyGrip.getKeyGrip(key); | |||
} catch (PGPException e) { | |||
throw new RuntimeException(e); | |||
} | |||
assertTrue("More keys than expected", | |||
index[0] < data.expectedKeyGrips.length); | |||
assertEquals("Wrong keygrip", data.expectedKeyGrips[index[0]++], | |||
Hex.toHexString(keyGrip).toUpperCase(Locale.ROOT)); | |||
}); | |||
assertEquals("Missing keys", data.expectedKeyGrips.length, | |||
index[0]); | |||
} | |||
} | |||
} |
@@ -0,0 +1,163 @@ | |||
/* | |||
* Copyright (C) 2021 Thomas Wolf <thomas.wolf@paranor.ch> 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.gpg.bc.internal.keys; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertFalse; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertTrue; | |||
import java.io.BufferedInputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.security.Security; | |||
import java.util.Iterator; | |||
import javax.crypto.Cipher; | |||
import org.bouncycastle.jce.provider.BouncyCastleProvider; | |||
import org.bouncycastle.openpgp.PGPException; | |||
import org.bouncycastle.openpgp.PGPPublicKey; | |||
import org.bouncycastle.openpgp.PGPPublicKeyRing; | |||
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; | |||
import org.bouncycastle.openpgp.PGPSecretKey; | |||
import org.bouncycastle.openpgp.PGPUtil; | |||
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; | |||
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; | |||
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; | |||
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; | |||
@RunWith(Parameterized.class) | |||
public class SecretKeysTest { | |||
@BeforeClass | |||
public static void ensureBC() { | |||
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { | |||
Security.addProvider(new BouncyCastleProvider()); | |||
} | |||
} | |||
private static volatile Boolean haveOCB; | |||
private static boolean ocbAvailable() { | |||
Boolean haveIt = haveOCB; | |||
if (haveIt != null) { | |||
return haveIt.booleanValue(); | |||
} | |||
try { | |||
Cipher c = Cipher.getInstance("AES/OCB/NoPadding"); //$NON-NLS-1$ | |||
if (c == null) { | |||
haveOCB = Boolean.FALSE; | |||
return false; | |||
} | |||
} catch (NoClassDefFoundError | Exception e) { | |||
haveOCB = Boolean.FALSE; | |||
return false; | |||
} | |||
haveOCB = Boolean.TRUE; | |||
return true; | |||
} | |||
private static class TestData { | |||
final String name; | |||
final boolean encrypted; | |||
final boolean keyValue; | |||
TestData(String name, boolean encrypted, boolean keyValue) { | |||
this.name = name; | |||
this.encrypted = encrypted; | |||
this.keyValue = keyValue; | |||
} | |||
@Override | |||
public String toString() { | |||
return name; | |||
} | |||
} | |||
@Parameters(name = "{0}") | |||
public static TestData[] initTestData() { | |||
return new TestData[] { | |||
new TestData("AFDA8EA10E185ACF8C0D0F8885A0EF61A72ECB11", false, false), | |||
new TestData("2FB05DBB70FC07CB84C13431F640CA6CEA1DBF8A", false, true), | |||
new TestData("66CCECEC2AB46A9735B10FEC54EDF9FD0F77BAF9", true, true), | |||
new TestData("F727FAB884DA3BD402B6E0F5472E108D21033124", true, true), | |||
new TestData("faked", false, true) }; | |||
} | |||
private static byte[] readTestKey(String filename) throws Exception { | |||
try (InputStream in = new BufferedInputStream( | |||
SecretKeysTest.class.getResourceAsStream(filename))) { | |||
return SecretKeys.keyFromNameValueFormat(in); | |||
} | |||
} | |||
private static PGPPublicKey readAsc(InputStream in) | |||
throws IOException, PGPException { | |||
PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection( | |||
PGPUtil.getDecoderStream(in), new JcaKeyFingerprintCalculator()); | |||
Iterator<PGPPublicKeyRing> keyRings = pgpPub.getKeyRings(); | |||
while (keyRings.hasNext()) { | |||
PGPPublicKeyRing keyRing = keyRings.next(); | |||
Iterator<PGPPublicKey> keys = keyRing.getPublicKeys(); | |||
if (keys.hasNext()) { | |||
return keys.next(); | |||
} | |||
} | |||
return null; | |||
} | |||
// Injected by JUnit | |||
@Parameter | |||
public TestData data; | |||
@Test | |||
public void testKeyRead() throws Exception { | |||
if (data.keyValue) { | |||
byte[] bytes = readTestKey(data.name + ".key"); | |||
assertEquals('(', bytes[0]); | |||
assertEquals(')', bytes[bytes.length - 1]); | |||
} | |||
try (InputStream pubIn = this.getClass() | |||
.getResourceAsStream(data.name + ".asc")) { | |||
if (pubIn != null) { | |||
PGPPublicKey publicKey = readAsc(pubIn); | |||
// Do a full test trying to load the secret key. | |||
PGPDigestCalculatorProvider calculatorProvider = new JcaPGPDigestCalculatorProviderBuilder() | |||
.build(); | |||
try (InputStream in = new BufferedInputStream(this.getClass() | |||
.getResourceAsStream(data.name + ".key"))) { | |||
PGPSecretKey secretKey = SecretKeys.readSecretKey(in, | |||
calculatorProvider, | |||
data.encrypted ? () -> "nonsense".toCharArray() | |||
: null, | |||
publicKey); | |||
assertNotNull(secretKey); | |||
} catch (PGPException e) { | |||
// Currently we may not be able to load OCB-encrypted keys. | |||
assertTrue(e.getMessage().contains("OCB")); | |||
assertTrue(data.encrypted); | |||
assertFalse(ocbAvailable()); | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -8,22 +8,30 @@ Bundle-Vendor: %Bundle-Vendor | |||
Bundle-Localization: plugin | |||
Bundle-Version: 5.11.0.qualifier | |||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | |||
Import-Package: org.bouncycastle.bcpg;version="[1.65.0,2.0.0)", | |||
Import-Package: org.bouncycastle.asn1;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.asn1.cryptlib;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.asn1.x9;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.bcpg;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.bcpg.sig;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.crypto.ec;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.gpg;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.gpg.keybox;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.gpg.keybox.jcajce;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.jcajce.interfaces;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.jcajce.util;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.jce.provider;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.math.ec;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.math.field;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.openpgp;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.openpgp.jcajce;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.openpgp.operator;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.openpgp.operator.jcajce;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.util;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.util.encoders;version="[1.65.0,2.0.0)", | |||
org.bouncycastle.util.io;version="[1.65.0,2.0.0)", | |||
org.eclipse.jgit.annotations;version="[5.11.0,5.12.0)", | |||
org.eclipse.jgit.api.errors;version="[5.11.0,5.12.0)", | |||
org.eclipse.jgit.errors;version="[5.11.0,5.12.0)", | |||
org.eclipse.jgit.lib;version="[5.11.0,5.12.0)", | |||
org.eclipse.jgit.nls;version="[5.11.0,5.12.0)", | |||
org.eclipse.jgit.transport;version="[5.11.0,5.12.0)", | |||
org.eclipse.jgit.util;version="[5.11.0,5.12.0)", | |||
org.slf4j;version="[1.7.0,2.0.0)" | |||
Export-Package: org.eclipse.jgit.gpg.bc.internal;version="5.11.0"; | |||
x-friends:="org.eclipse.jgit.gpg.bc.test" | |||
Export-Package: org.eclipse.jgit.gpg.bc;version="5.11.0", | |||
org.eclipse.jgit.gpg.bc.internal;version="5.11.0";x-friends:="org.eclipse.jgit.gpg.bc.test", | |||
org.eclipse.jgit.gpg.bc.internal.keys;version="5.11.0";x-friends:="org.eclipse.jgit.gpg.bc.test" |
@@ -11,7 +11,7 @@ | |||
margin: 0.25in 0.5in 0.25in 0.5in; | |||
tab-interval: 0.5in; | |||
} | |||
p { | |||
p { | |||
margin-left: auto; | |||
margin-top: 0.5em; | |||
margin-bottom: 0.5em; | |||
@@ -36,60 +36,53 @@ | |||
<p>Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors. </p> | |||
<p>All rights reserved.</p> | |||
<p>Redistribution and use in source and binary forms, with or without modification, | |||
<p>Redistribution and use in source and binary forms, with or without modification, | |||
are permitted provided that the following conditions are met: | |||
<ul><li>Redistributions of source code must retain the above copyright notice, | |||
<ul><li>Redistributions of source code must retain the above copyright notice, | |||
this list of conditions and the following disclaimer. </li> | |||
<li>Redistributions in binary form must reproduce the above copyright notice, | |||
this list of conditions and the following disclaimer in the documentation | |||
<li>Redistributions in binary form must reproduce the above copyright notice, | |||
this list of conditions and the following disclaimer in the documentation | |||
and/or other materials provided with the distribution. </li> | |||
<li>Neither the name of the Eclipse Foundation, Inc. nor the names of its | |||
contributors may be used to endorse or promote products derived from | |||
<li>Neither the name of the Eclipse Foundation, Inc. nor the names of its | |||
contributors may be used to endorse or promote products derived from | |||
this software without specific prior written permission. </li></ul> | |||
</p> | |||
<p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |||
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, | |||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
<p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |||
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, | |||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE.</p> | |||
<hr> | |||
<p><b>SHA-1 UbcCheck - MIT</b></p> | |||
<p><b>org.eclipse.jgit.gpg.bc.internal.keys.SExprParser - MIT</b></p> | |||
<p>Copyright (c) 2017:</p> | |||
<div class="ubc-name"> | |||
Marc Stevens | |||
Cryptology Group | |||
Centrum Wiskunde & Informatica | |||
P.O. Box 94079, 1090 GB Amsterdam, Netherlands | |||
marc@marc-stevens.nl | |||
</div> | |||
<div class="ubc-name"> | |||
Dan Shumow | |||
Microsoft Research | |||
danshu@microsoft.com | |||
</div> | |||
<p>Permission is hereby granted, free of charge, to any person obtaining a copy | |||
of this software and associated documentation files (the "Software"), to deal | |||
in the Software without restriction, including without limitation the rights | |||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
copies of the Software, and to permit persons to whom the Software is | |||
furnished to do so, subject to the following conditions: | |||
<p>Copyright (c) 2000-2021 The Legion of the Bouncy Castle Inc. | |||
(<a href="https://www.bouncycastle.org">https://www.bouncycastle.org</a>)</p> | |||
<p> | |||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software | |||
and associated documentation files (the "Software"), to deal in the Software without restriction, | |||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, | |||
subject to the following conditions: | |||
</p> | |||
<p> | |||
The above copyright notice and this permission notice shall be included in all copies or substantial | |||
portions of the Software. | |||
</p> | |||
<p> | |||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | |||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
DEALINGS IN THE SOFTWARE. | |||
</p> | |||
<ul><li>The above copyright notice and this permission notice shall be included | |||
in all copies or substantial portions of the Software.</li></ul> | |||
<p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
SOFTWARE.</p> | |||
</body> | |||
@@ -0,0 +1 @@ | |||
org.eclipse.jgit.gpg.bc.internal.BouncyCastleGpgSignatureVerifierFactory |
@@ -1,11 +1,36 @@ | |||
corrupt25519Key=Ed25519/Curve25519 public key has wrong length: {0} | |||
credentialPassphrase=Passphrase | |||
gpgFailedToParseSecretKey=Failed to parse secret key file in directory: {0}. Is the entered passphrase correct? | |||
cryptCipherError=Cannot create cipher to decrypt: {0} | |||
cryptWrongDecryptedLength=Decrypted key has wrong length; expected {0} bytes, got only {1} bytes | |||
gpgFailedToParseSecretKey=Failed to parse secret key file {0}. Is the entered passphrase correct? | |||
gpgNoCredentialsProvider=missing credentials provider | |||
gpgNoKeygrip=Cannot find key {0}: cannot determine key grip | |||
gpgNoKeyring=neither pubring.kbx nor secring.gpg files found | |||
gpgNoKeyInLegacySecring=no matching secret key found in legacy secring.gpg for key or user id: {0} | |||
gpgNoPublicKeyFound=Unable to find a public-key with key or user id: {0} | |||
gpgNoSecretKeyForPublicKey=unable to find associated secret key for public key: {0} | |||
gpgNoSuchAlgorithm=Cannot decrypt encrypted secret key: encryption algorithm {0} is not available | |||
gpgNotASigningKey=Secret key ({0}) is not suitable for signing | |||
gpgKeyInfo=GPG Key (fingerprint {0}) | |||
gpgSigningCancelled=Signing was cancelled | |||
nonSignatureError=Signature does not decode into a signature object | |||
secretKeyTooShort=Secret key file corrupt; only {0} bytes read | |||
sexprHexNotClosed=Hex number in s-expression not closed | |||
sexprHexOdd=Hex number in s-expression has an odd number of digits | |||
sexprStringInvalidEscape=Invalid escape {0} in s-expression | |||
sexprStringInvalidEscapeAtEnd=Invalid s-expression: quoted string ends with escape character | |||
sexprStringInvalidHexEscape=Invalid hex escape in s-expression | |||
sexprStringInvalidOctalEscape=Invalid octal escape in s-expression | |||
sexprStringNotClosed=String in s-expression not closed | |||
sexprUnhandled=Unhandled token {0} in s-expression | |||
signatureInconsistent=Inconsistent signature; key ID {0} does not match issuer fingerprint {1} | |||
signatureKeyLookupError=Error occurred while looking for public key | |||
signatureNoKeyInfo=No way to determine a public key from the signature | |||
signatureNoPublicKey=No public key found to verify the signature | |||
signatureParseError=Signature cannot be parsed | |||
signatureVerificationError=Signature verification failed | |||
unableToSignCommitNoSecretKey=Unable to sign commit. Signing key not available. | |||
uncompressed25519Key=Cannot handle ed25519 public key with uncompressed data: {0} | |||
unknownCurve=Unknown curve {0} | |||
unknownCurveParameters=Curve {0} does not have a prime field | |||
unknownKeyType=Unknown key type {0} |
@@ -0,0 +1,34 @@ | |||
/* | |||
* Copyright (C) 2021 Thomas Wolf <thomas.wolf@paranor.ch> 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.gpg.bc; | |||
import org.eclipse.jgit.gpg.bc.internal.BouncyCastleGpgSigner; | |||
import org.eclipse.jgit.lib.GpgSigner; | |||
/** | |||
* Factory for creating a {@link GpgSigner} based on Bouncy Castle. | |||
* | |||
* @since 5.11 | |||
*/ | |||
public final class BouncyCastleGpgSignerFactory { | |||
private BouncyCastleGpgSignerFactory() { | |||
// No instantiation | |||
} | |||
/** | |||
* Creates a new {@link GpgSigner}. | |||
* | |||
* @return the {@link GpgSigner} | |||
*/ | |||
public static GpgSigner create() { | |||
return new BouncyCastleGpgSigner(); | |||
} | |||
} |
@@ -1,3 +1,12 @@ | |||
/* | |||
* Copyright (C) 2018, 2021 Salesforce 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.gpg.bc.internal; | |||
import org.eclipse.jgit.nls.NLS; | |||
@@ -18,16 +27,41 @@ public final class BCText extends TranslationBundle { | |||
} | |||
// @formatter:off | |||
/***/ public String corrupt25519Key; | |||
/***/ public String credentialPassphrase; | |||
/***/ public String cryptCipherError; | |||
/***/ public String cryptWrongDecryptedLength; | |||
/***/ public String gpgFailedToParseSecretKey; | |||
/***/ public String gpgNoCredentialsProvider; | |||
/***/ public String gpgNoKeygrip; | |||
/***/ public String gpgNoKeyring; | |||
/***/ public String gpgNoKeyInLegacySecring; | |||
/***/ public String gpgNoPublicKeyFound; | |||
/***/ public String gpgNoSecretKeyForPublicKey; | |||
/***/ public String gpgNoSuchAlgorithm; | |||
/***/ public String gpgNotASigningKey; | |||
/***/ public String gpgKeyInfo; | |||
/***/ public String gpgSigningCancelled; | |||
/***/ public String nonSignatureError; | |||
/***/ public String secretKeyTooShort; | |||
/***/ public String sexprHexNotClosed; | |||
/***/ public String sexprHexOdd; | |||
/***/ public String sexprStringInvalidEscape; | |||
/***/ public String sexprStringInvalidEscapeAtEnd; | |||
/***/ public String sexprStringInvalidHexEscape; | |||
/***/ public String sexprStringInvalidOctalEscape; | |||
/***/ public String sexprStringNotClosed; | |||
/***/ public String sexprUnhandled; | |||
/***/ public String signatureInconsistent; | |||
/***/ public String signatureKeyLookupError; | |||
/***/ public String signatureNoKeyInfo; | |||
/***/ public String signatureNoPublicKey; | |||
/***/ public String signatureParseError; | |||
/***/ public String signatureVerificationError; | |||
/***/ public String unableToSignCommitNoSecretKey; | |||
/***/ public String uncompressed25519Key; | |||
/***/ public String unknownCurve; | |||
/***/ public String unknownCurveParameters; | |||
/***/ public String unknownKeyType; | |||
} |
@@ -1,5 +1,5 @@ | |||
/* | |||
* Copyright (C) 2018, 2020 Salesforce and others | |||
* Copyright (C) 2018, 2021 Salesforce 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 | |||
@@ -14,25 +14,22 @@ import static java.nio.file.Files.newInputStream; | |||
import java.io.BufferedInputStream; | |||
import java.io.File; | |||
import java.io.FileNotFoundException; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.net.URISyntaxException; | |||
import java.nio.file.DirectoryStream; | |||
import java.nio.file.Files; | |||
import java.nio.file.InvalidPathException; | |||
import java.nio.file.NoSuchFileException; | |||
import java.nio.file.Path; | |||
import java.nio.file.Paths; | |||
import java.security.NoSuchAlgorithmException; | |||
import java.security.NoSuchProviderException; | |||
import java.text.MessageFormat; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.Locale; | |||
import java.util.stream.Collectors; | |||
import java.util.stream.Stream; | |||
import org.bouncycastle.gpg.SExprParser; | |||
import org.bouncycastle.gpg.keybox.BlobType; | |||
import org.bouncycastle.gpg.keybox.KeyBlob; | |||
import org.bouncycastle.gpg.keybox.KeyBox; | |||
@@ -50,15 +47,15 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing; | |||
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; | |||
import org.bouncycastle.openpgp.PGPSignature; | |||
import org.bouncycastle.openpgp.PGPUtil; | |||
import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory; | |||
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; | |||
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; | |||
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; | |||
import org.bouncycastle.openpgp.operator.jcajce.JcePBEProtectionRemoverFactory; | |||
import org.bouncycastle.util.encoders.Hex; | |||
import org.eclipse.jgit.annotations.NonNull; | |||
import org.eclipse.jgit.api.errors.CanceledException; | |||
import org.eclipse.jgit.errors.UnsupportedCredentialItem; | |||
import org.eclipse.jgit.gpg.bc.internal.keys.KeyGrip; | |||
import org.eclipse.jgit.gpg.bc.internal.keys.SecretKeys; | |||
import org.eclipse.jgit.util.FS; | |||
import org.eclipse.jgit.util.StringUtils; | |||
import org.eclipse.jgit.util.SystemReader; | |||
@@ -78,17 +75,10 @@ public class BouncyCastleGpgKeyLocator { | |||
} | |||
/** Thrown if we try to read an encrypted private key without password. */ | |||
private static class EncryptedPgpKeyException extends RuntimeException { | |||
private static final long serialVersionUID = 1L; | |||
} | |||
private static final Logger log = LoggerFactory | |||
.getLogger(BouncyCastleGpgKeyLocator.class); | |||
private static final Path GPG_DIRECTORY = findGpgDirectory(); | |||
static final Path GPG_DIRECTORY = findGpgDirectory(); | |||
private static final Path USER_KEYBOX_PATH = GPG_DIRECTORY | |||
.resolve("pubring.kbx"); //$NON-NLS-1$ | |||
@@ -155,16 +145,13 @@ public class BouncyCastleGpgKeyLocator { | |||
private PGPSecretKey attemptParseSecretKey(Path keyFile, | |||
PGPDigestCalculatorProvider calculatorProvider, | |||
PBEProtectionRemoverFactory passphraseProvider, | |||
PGPPublicKey publicKey) { | |||
SecretKeys.PassphraseSupplier passphraseSupplier, | |||
PGPPublicKey publicKey) | |||
throws IOException, PGPException, CanceledException, | |||
UnsupportedCredentialItem, URISyntaxException { | |||
try (InputStream in = newInputStream(keyFile)) { | |||
return new SExprParser(calculatorProvider).parseSecretKey( | |||
new BufferedInputStream(in), passphraseProvider, publicKey); | |||
} catch (IOException | PGPException | ClassCastException e) { | |||
if (log.isDebugEnabled()) | |||
log.debug("Ignoring unreadable file '{}': {}", keyFile, //$NON-NLS-1$ | |||
e.getMessage(), e); | |||
return null; | |||
return SecretKeys.readSecretKey(in, calculatorProvider, | |||
passphraseSupplier, publicKey); | |||
} | |||
} | |||
@@ -247,16 +234,32 @@ public class BouncyCastleGpgKeyLocator { | |||
return false; | |||
} | |||
private String toFingerprint(String keyId) { | |||
private static String toFingerprint(String keyId) { | |||
if (keyId.startsWith("0x")) { //$NON-NLS-1$ | |||
return keyId.substring(2); | |||
} | |||
return keyId; | |||
} | |||
private PGPPublicKey findPublicKeyByKeyId(KeyBlob keyBlob) | |||
static PGPPublicKey findPublicKey(String fingerprint, String keySpec) | |||
throws IOException, PGPException { | |||
PGPPublicKey result = findPublicKeyInPubring(USER_PGP_PUBRING_FILE, | |||
fingerprint, keySpec); | |||
if (result == null && exists(USER_KEYBOX_PATH)) { | |||
try { | |||
result = findPublicKeyInKeyBox(USER_KEYBOX_PATH, fingerprint, | |||
keySpec); | |||
} catch (NoSuchAlgorithmException | NoSuchProviderException | |||
| IOException | NoOpenPgpKeyException e) { | |||
log.error(e.getMessage(), e); | |||
} | |||
} | |||
return result; | |||
} | |||
private static PGPPublicKey findPublicKeyByKeyId(KeyBlob keyBlob, | |||
String keyId) | |||
throws IOException { | |||
String keyId = toFingerprint(signingKey).toLowerCase(Locale.ROOT); | |||
if (keyId.isEmpty()) { | |||
return null; | |||
} | |||
@@ -270,10 +273,11 @@ public class BouncyCastleGpgKeyLocator { | |||
return null; | |||
} | |||
private PGPPublicKey findPublicKeyByUserId(KeyBlob keyBlob) | |||
private static PGPPublicKey findPublicKeyByUserId(KeyBlob keyBlob, | |||
String keySpec) | |||
throws IOException { | |||
for (UserID userID : keyBlob.getUserIds()) { | |||
if (containsSigningKey(userID.getUserIDAsString(), signingKey)) { | |||
if (containsSigningKey(userID.getUserIDAsString(), keySpec)) { | |||
return getSigningPublicKey(keyBlob); | |||
} | |||
} | |||
@@ -285,6 +289,10 @@ public class BouncyCastleGpgKeyLocator { | |||
* | |||
* @param keyboxFile | |||
* the KeyBox file | |||
* @param keyId | |||
* to look for, may be null | |||
* @param keySpec | |||
* to look for | |||
* @return publicKey the public key (maybe <code>null</code>) | |||
* @throws IOException | |||
* in case of problems reading the file | |||
@@ -293,19 +301,22 @@ public class BouncyCastleGpgKeyLocator { | |||
* @throws NoOpenPgpKeyException | |||
* if the file does not contain any OpenPGP key | |||
*/ | |||
private PGPPublicKey findPublicKeyInKeyBox(Path keyboxFile) | |||
private static PGPPublicKey findPublicKeyInKeyBox(Path keyboxFile, | |||
String keyId, String keySpec) | |||
throws IOException, NoSuchAlgorithmException, | |||
NoSuchProviderException, NoOpenPgpKeyException { | |||
KeyBox keyBox = readKeyBoxFile(keyboxFile); | |||
String id = keyId != null ? keyId | |||
: toFingerprint(keySpec).toLowerCase(Locale.ROOT); | |||
boolean hasOpenPgpKey = false; | |||
for (KeyBlob keyBlob : keyBox.getKeyBlobs()) { | |||
if (keyBlob.getType() == BlobType.OPEN_PGP_BLOB) { | |||
hasOpenPgpKey = true; | |||
PGPPublicKey key = findPublicKeyByKeyId(keyBlob); | |||
PGPPublicKey key = findPublicKeyByKeyId(keyBlob, id); | |||
if (key != null) { | |||
return key; | |||
} | |||
key = findPublicKeyByUserId(keyBlob); | |||
key = findPublicKeyByUserId(keyBlob, keySpec); | |||
if (key != null) { | |||
return key; | |||
} | |||
@@ -349,7 +360,8 @@ public class BouncyCastleGpgKeyLocator { | |||
// pubring.gpg also try secring.gpg to find the secret key. | |||
if (exists(USER_KEYBOX_PATH)) { | |||
try { | |||
publicKey = findPublicKeyInKeyBox(USER_KEYBOX_PATH); | |||
publicKey = findPublicKeyInKeyBox(USER_KEYBOX_PATH, null, | |||
signingKey); | |||
if (publicKey != null) { | |||
key = findSecretKeyForKeyBoxPublicKey(publicKey, | |||
USER_KEYBOX_PATH); | |||
@@ -372,7 +384,8 @@ public class BouncyCastleGpgKeyLocator { | |||
} | |||
} | |||
if (exists(USER_PGP_PUBRING_FILE)) { | |||
publicKey = findPublicKeyInPubring(USER_PGP_PUBRING_FILE); | |||
publicKey = findPublicKeyInPubring(USER_PGP_PUBRING_FILE, null, | |||
signingKey); | |||
if (publicKey != null) { | |||
// GPG < 2.1 may have both; the agent using the directory | |||
// and gpg using secring.gpg. GPG >= 2.1 delegates all | |||
@@ -444,67 +457,59 @@ public class BouncyCastleGpgKeyLocator { | |||
PGPPublicKey publicKey, Path userKeyboxPath) | |||
throws PGPException, CanceledException, UnsupportedCredentialItem, | |||
URISyntaxException { | |||
/* | |||
* this is somewhat brute-force but there doesn't seem to be another | |||
* way; we have to walk all private key files we find and try to open | |||
* them | |||
*/ | |||
PGPDigestCalculatorProvider calculatorProvider = new JcaPGPDigestCalculatorProviderBuilder() | |||
.build(); | |||
try (Stream<Path> keyFiles = Files.walk(USER_SECRET_KEY_DIR)) { | |||
List<Path> allPaths = keyFiles.filter(Files::isRegularFile) | |||
.collect(Collectors.toCollection(ArrayList::new)); | |||
if (allPaths.isEmpty()) { | |||
return null; | |||
byte[] keyGrip = null; | |||
try { | |||
keyGrip = KeyGrip.getKeyGrip(publicKey); | |||
} catch (PGPException e) { | |||
throw new PGPException( | |||
MessageFormat.format(BCText.get().gpgNoKeygrip, | |||
Hex.toHexString(publicKey.getFingerprint())), | |||
e); | |||
} | |||
String filename = Hex.toHexString(keyGrip).toUpperCase(Locale.ROOT) | |||
+ ".key"; //$NON-NLS-1$ | |||
Path keyFile = USER_SECRET_KEY_DIR.resolve(filename); | |||
if (!Files.exists(keyFile)) { | |||
return null; | |||
} | |||
boolean clearPrompt = false; | |||
try { | |||
PGPDigestCalculatorProvider calculatorProvider = new JcaPGPDigestCalculatorProviderBuilder() | |||
.build(); | |||
clearPrompt = true; | |||
PGPSecretKey secretKey = null; | |||
try { | |||
secretKey = attemptParseSecretKey(keyFile, calculatorProvider, | |||
() -> passphrasePrompt.getPassphrase( | |||
publicKey.getFingerprint(), userKeyboxPath), | |||
publicKey); | |||
} catch (PGPException e) { | |||
throw new PGPException(MessageFormat.format( | |||
BCText.get().gpgFailedToParseSecretKey, | |||
keyFile.toAbsolutePath()), e); | |||
} | |||
PBEProtectionRemoverFactory passphraseProvider = p -> { | |||
throw new EncryptedPgpKeyException(); | |||
}; | |||
for (int attempts = 0; attempts < 2; attempts++) { | |||
// Second pass will traverse only the encrypted keys with a real | |||
// passphrase provider. | |||
Iterator<Path> pathIterator = allPaths.iterator(); | |||
while (pathIterator.hasNext()) { | |||
Path keyFile = pathIterator.next(); | |||
try { | |||
PGPSecretKey secretKey = attemptParseSecretKey(keyFile, | |||
calculatorProvider, passphraseProvider, | |||
publicKey); | |||
pathIterator.remove(); | |||
if (secretKey != null) { | |||
if (!secretKey.isSigningKey()) { | |||
throw new PGPException(MessageFormat.format( | |||
BCText.get().gpgNotASigningKey, | |||
signingKey)); | |||
} | |||
return new BouncyCastleGpgKey(secretKey, | |||
userKeyboxPath); | |||
} | |||
} catch (EncryptedPgpKeyException e) { | |||
// Ignore; we'll try again. | |||
} | |||
} | |||
if (attempts > 0 || allPaths.isEmpty()) { | |||
break; | |||
if (secretKey != null) { | |||
if (!secretKey.isSigningKey()) { | |||
throw new PGPException(MessageFormat.format( | |||
BCText.get().gpgNotASigningKey, signingKey)); | |||
} | |||
// allPaths contains only the encrypted keys now. | |||
passphraseProvider = new JcePBEProtectionRemoverFactory( | |||
passphrasePrompt.getPassphrase( | |||
publicKey.getFingerprint(), userKeyboxPath)); | |||
clearPrompt = false; | |||
return new BouncyCastleGpgKey(secretKey, userKeyboxPath); | |||
} | |||
passphrasePrompt.clear(); | |||
return null; | |||
} catch (RuntimeException e) { | |||
passphrasePrompt.clear(); | |||
throw e; | |||
} catch (FileNotFoundException | NoSuchFileException e) { | |||
clearPrompt = false; | |||
return null; | |||
} catch (IOException e) { | |||
passphrasePrompt.clear(); | |||
throw new PGPException(MessageFormat.format( | |||
BCText.get().gpgFailedToParseSecretKey, | |||
USER_SECRET_KEY_DIR.toAbsolutePath()), e); | |||
keyFile.toAbsolutePath()), e); | |||
} finally { | |||
if (clearPrompt) { | |||
passphrasePrompt.clear(); | |||
} | |||
} | |||
} | |||
@@ -562,6 +567,11 @@ public class BouncyCastleGpgKeyLocator { | |||
* Return the first public key matching the key id ({@link #signingKey}. | |||
* | |||
* @param pubringFile | |||
* to search | |||
* @param keyId | |||
* to look for, may be null | |||
* @param keySpec | |||
* to look for | |||
* | |||
* @return the PGP public key, or {@code null} if none found | |||
* @throws IOException | |||
@@ -569,14 +579,16 @@ public class BouncyCastleGpgKeyLocator { | |||
* @throws PGPException | |||
* on BouncyCastle errors | |||
*/ | |||
private PGPPublicKey findPublicKeyInPubring(Path pubringFile) | |||
private static PGPPublicKey findPublicKeyInPubring(Path pubringFile, | |||
String keyId, String keySpec) | |||
throws IOException, PGPException { | |||
try (InputStream in = newInputStream(pubringFile)) { | |||
PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection( | |||
new BufferedInputStream(in), | |||
new JcaKeyFingerprintCalculator()); | |||
String keyId = toFingerprint(signingKey).toLowerCase(Locale.ROOT); | |||
String id = keyId != null ? keyId | |||
: toFingerprint(keySpec).toLowerCase(Locale.ROOT); | |||
Iterator<PGPPublicKeyRing> keyrings = pgpPub.getKeyRings(); | |||
while (keyrings.hasNext()) { | |||
PGPPublicKeyRing keyRing = keyrings.next(); | |||
@@ -586,30 +598,33 @@ public class BouncyCastleGpgKeyLocator { | |||
// try key id | |||
String fingerprint = Hex.toHexString(key.getFingerprint()) | |||
.toLowerCase(Locale.ROOT); | |||
if (fingerprint.endsWith(keyId)) { | |||
if (fingerprint.endsWith(id)) { | |||
return key; | |||
} | |||
// try user id | |||
Iterator<String> userIDs = key.getUserIDs(); | |||
while (userIDs.hasNext()) { | |||
String userId = userIDs.next(); | |||
if (containsSigningKey(userId, signingKey)) { | |||
if (containsSigningKey(userId, keySpec)) { | |||
return key; | |||
} | |||
} | |||
} | |||
} | |||
} catch (FileNotFoundException | NoSuchFileException e) { | |||
// Ignore and return null | |||
} | |||
return null; | |||
} | |||
private PGPPublicKey getPublicKey(KeyBlob blob, byte[] fingerprint) | |||
private static PGPPublicKey getPublicKey(KeyBlob blob, byte[] fingerprint) | |||
throws IOException { | |||
return ((PublicKeyRingBlob) blob).getPGPPublicKeyRing() | |||
.getPublicKey(fingerprint); | |||
} | |||
private PGPPublicKey getSigningPublicKey(KeyBlob blob) throws IOException { | |||
private static PGPPublicKey getSigningPublicKey(KeyBlob blob) | |||
throws IOException { | |||
PGPPublicKey masterKey = null; | |||
Iterator<PGPPublicKey> keys = ((PublicKeyRingBlob) blob) | |||
.getPGPPublicKeyRing().getPublicKeys(); | |||
@@ -629,7 +644,7 @@ public class BouncyCastleGpgKeyLocator { | |||
return masterKey; | |||
} | |||
private boolean isSigningKey(PGPPublicKey key) { | |||
private static boolean isSigningKey(PGPPublicKey key) { | |||
Iterator signatures = key.getSignatures(); | |||
while (signatures.hasNext()) { | |||
PGPSignature sig = (PGPSignature) signatures.next(); | |||
@@ -641,7 +656,7 @@ public class BouncyCastleGpgKeyLocator { | |||
return false; | |||
} | |||
private KeyBox readKeyBoxFile(Path keyboxFile) throws IOException, | |||
private static KeyBox readKeyBoxFile(Path keyboxFile) throws IOException, | |||
NoSuchAlgorithmException, NoSuchProviderException, | |||
NoOpenPgpKeyException { | |||
if (keyboxFile.toFile().length() == 0) { |
@@ -17,8 +17,8 @@ import org.bouncycastle.openpgp.PGPException; | |||
import org.bouncycastle.util.encoders.Hex; | |||
import org.eclipse.jgit.api.errors.CanceledException; | |||
import org.eclipse.jgit.errors.UnsupportedCredentialItem; | |||
import org.eclipse.jgit.transport.CredentialItem.CharArrayType; | |||
import org.eclipse.jgit.transport.CredentialItem.InformationalMessage; | |||
import org.eclipse.jgit.transport.CredentialItem.Password; | |||
import org.eclipse.jgit.transport.CredentialsProvider; | |||
import org.eclipse.jgit.transport.URIish; | |||
@@ -31,7 +31,7 @@ import org.eclipse.jgit.transport.URIish; | |||
*/ | |||
class BouncyCastleGpgKeyPassphrasePrompt implements AutoCloseable { | |||
private CharArrayType passphrase; | |||
private Password passphrase; | |||
private CredentialsProvider credentialsProvider; | |||
@@ -78,8 +78,7 @@ class BouncyCastleGpgKeyPassphrasePrompt implements AutoCloseable { | |||
throws PGPException, CanceledException, UnsupportedCredentialItem, | |||
URISyntaxException { | |||
if (passphrase == null) { | |||
passphrase = new CharArrayType(BCText.get().credentialPassphrase, | |||
true); | |||
passphrase = new Password(BCText.get().credentialPassphrase); | |||
} | |||
if (credentialsProvider == null) { |
@@ -0,0 +1,388 @@ | |||
/* | |||
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> 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.gpg.bc.internal; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.security.Security; | |||
import java.text.MessageFormat; | |||
import java.time.Instant; | |||
import java.util.Arrays; | |||
import java.util.Date; | |||
import java.util.Iterator; | |||
import java.util.Locale; | |||
import org.bouncycastle.bcpg.sig.IssuerFingerprint; | |||
import org.bouncycastle.jce.provider.BouncyCastleProvider; | |||
import org.bouncycastle.openpgp.PGPCompressedData; | |||
import org.bouncycastle.openpgp.PGPException; | |||
import org.bouncycastle.openpgp.PGPPublicKey; | |||
import org.bouncycastle.openpgp.PGPSignature; | |||
import org.bouncycastle.openpgp.PGPSignatureList; | |||
import org.bouncycastle.openpgp.PGPSignatureSubpacketVector; | |||
import org.bouncycastle.openpgp.PGPUtil; | |||
import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory; | |||
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; | |||
import org.bouncycastle.util.encoders.Hex; | |||
import org.eclipse.jgit.annotations.NonNull; | |||
import org.eclipse.jgit.annotations.Nullable; | |||
import org.eclipse.jgit.api.errors.JGitInternalException; | |||
import org.eclipse.jgit.lib.GpgConfig; | |||
import org.eclipse.jgit.lib.GpgSignatureVerifier; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.revwalk.RevObject; | |||
import org.eclipse.jgit.revwalk.RevTag; | |||
import org.eclipse.jgit.util.LRUMap; | |||
import org.eclipse.jgit.util.RawParseUtils; | |||
import org.eclipse.jgit.util.StringUtils; | |||
/** | |||
* A {@link GpgSignatureVerifier} to verify GPG signatures using BouncyCastle. | |||
*/ | |||
public class BouncyCastleGpgSignatureVerifier implements GpgSignatureVerifier { | |||
private static void registerBouncyCastleProviderIfNecessary() { | |||
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { | |||
Security.addProvider(new BouncyCastleProvider()); | |||
} | |||
} | |||
/** | |||
* Creates a new instance and registers the BouncyCastle security provider | |||
* if needed. | |||
*/ | |||
public BouncyCastleGpgSignatureVerifier() { | |||
registerBouncyCastleProviderIfNecessary(); | |||
} | |||
// To support more efficient signature verification of multiple objects we | |||
// cache public keys once found in a LRU cache. | |||
private static final Object NO_KEY = new Object(); | |||
private LRUMap<String, Object> byFingerprint = new LRUMap<>(16, 200); | |||
private LRUMap<String, Object> bySigner = new LRUMap<>(16, 200); | |||
@Override | |||
public String getName() { | |||
return "bc"; //$NON-NLS-1$ | |||
} | |||
@Override | |||
@Nullable | |||
public SignatureVerification verifySignature(@NonNull RevObject object, | |||
@NonNull GpgConfig config) throws IOException { | |||
if (object instanceof RevCommit) { | |||
RevCommit commit = (RevCommit) object; | |||
byte[] signatureData = commit.getRawGpgSignature(); | |||
if (signatureData == null) { | |||
return null; | |||
} | |||
byte[] raw = commit.getRawBuffer(); | |||
// Now remove the GPG signature | |||
byte[] header = { 'g', 'p', 'g', 's', 'i', 'g' }; | |||
int start = RawParseUtils.headerStart(header, raw, 0); | |||
if (start < 0) { | |||
return null; | |||
} | |||
int end = RawParseUtils.headerEnd(raw, start); | |||
// start is at the beginning of the header's content | |||
start -= header.length + 1; | |||
// end is on the terminating LF; we need to skip that, too | |||
if (end < raw.length) { | |||
end++; | |||
} | |||
byte[] data = new byte[raw.length - (end - start)]; | |||
System.arraycopy(raw, 0, data, 0, start); | |||
System.arraycopy(raw, end, data, start, raw.length - end); | |||
return verify(data, signatureData); | |||
} else if (object instanceof RevTag) { | |||
RevTag tag = (RevTag) object; | |||
byte[] signatureData = tag.getRawGpgSignature(); | |||
if (signatureData == null) { | |||
return null; | |||
} | |||
byte[] raw = tag.getRawBuffer(); | |||
// The signature is just tacked onto the end of the message, which | |||
// is last in the buffer. | |||
byte[] data = Arrays.copyOfRange(raw, 0, | |||
raw.length - signatureData.length); | |||
return verify(data, signatureData); | |||
} | |||
return null; | |||
} | |||
static PGPSignature parseSignature(InputStream in) | |||
throws IOException, PGPException { | |||
try (InputStream sigIn = PGPUtil.getDecoderStream(in)) { | |||
JcaPGPObjectFactory pgpFactory = new JcaPGPObjectFactory(sigIn); | |||
Object obj = pgpFactory.nextObject(); | |||
if (obj instanceof PGPCompressedData) { | |||
obj = new JcaPGPObjectFactory( | |||
((PGPCompressedData) obj).getDataStream()).nextObject(); | |||
} | |||
if (obj instanceof PGPSignatureList) { | |||
return ((PGPSignatureList) obj).get(0); | |||
} | |||
return null; | |||
} | |||
} | |||
@Override | |||
public SignatureVerification verify(byte[] data, byte[] signatureData) | |||
throws IOException { | |||
PGPSignature signature = null; | |||
String fingerprint = null; | |||
String signer = null; | |||
String keyId = null; | |||
try (InputStream sigIn = new ByteArrayInputStream(signatureData)) { | |||
signature = parseSignature(sigIn); | |||
if (signature != null) { | |||
// Try to figure out something to find the public key with. | |||
if (signature.hasSubpackets()) { | |||
PGPSignatureSubpacketVector packets = signature | |||
.getHashedSubPackets(); | |||
IssuerFingerprint fingerprintPacket = packets | |||
.getIssuerFingerprint(); | |||
if (fingerprintPacket != null) { | |||
fingerprint = Hex | |||
.toHexString(fingerprintPacket.getFingerprint()) | |||
.toLowerCase(Locale.ROOT); | |||
} | |||
signer = packets.getSignerUserID(); | |||
if (signer != null) { | |||
signer = BouncyCastleGpgSigner.extractSignerId(signer); | |||
} | |||
} | |||
keyId = Long.toUnsignedString(signature.getKeyID(), 16) | |||
.toLowerCase(Locale.ROOT); | |||
} else { | |||
throw new JGitInternalException(BCText.get().nonSignatureError); | |||
} | |||
} catch (PGPException e) { | |||
throw new JGitInternalException(BCText.get().signatureParseError, | |||
e); | |||
} | |||
Date signatureCreatedAt = signature.getCreationTime(); | |||
if (fingerprint == null && signer == null && keyId == null) { | |||
return new VerificationResult(signatureCreatedAt, null, null, null, | |||
false, false, TrustLevel.UNKNOWN, | |||
BCText.get().signatureNoKeyInfo); | |||
} | |||
if (fingerprint != null && keyId != null | |||
&& !fingerprint.endsWith(keyId)) { | |||
return new VerificationResult(signatureCreatedAt, signer, fingerprint, | |||
null, false, false, TrustLevel.UNKNOWN, | |||
MessageFormat.format(BCText.get().signatureInconsistent, | |||
keyId, fingerprint)); | |||
} | |||
if (fingerprint == null && keyId != null) { | |||
fingerprint = keyId; | |||
} | |||
// Try to find the public key | |||
String keySpec = '<' + signer + '>'; | |||
Object cached = null; | |||
PGPPublicKey publicKey = null; | |||
try { | |||
cached = byFingerprint.get(fingerprint); | |||
if (cached != null) { | |||
if (cached instanceof PGPPublicKey) { | |||
publicKey = (PGPPublicKey) cached; | |||
} | |||
} else if (!StringUtils.isEmptyOrNull(signer)) { | |||
cached = bySigner.get(signer); | |||
if (cached != null) { | |||
if (cached instanceof PGPPublicKey) { | |||
publicKey = (PGPPublicKey) cached; | |||
} | |||
} | |||
} | |||
if (cached == null) { | |||
publicKey = BouncyCastleGpgKeyLocator.findPublicKey(fingerprint, | |||
keySpec); | |||
} | |||
} catch (IOException | PGPException e) { | |||
throw new JGitInternalException( | |||
BCText.get().signatureKeyLookupError, e); | |||
} | |||
if (publicKey == null) { | |||
if (cached == null) { | |||
byFingerprint.put(fingerprint, NO_KEY); | |||
byFingerprint.put(keyId, NO_KEY); | |||
if (signer != null) { | |||
bySigner.put(signer, NO_KEY); | |||
} | |||
} | |||
return new VerificationResult(signatureCreatedAt, signer, | |||
fingerprint, null, false, false, TrustLevel.UNKNOWN, | |||
BCText.get().signatureNoPublicKey); | |||
} | |||
if (cached == null) { | |||
byFingerprint.put(fingerprint, publicKey); | |||
byFingerprint.put(keyId, publicKey); | |||
if (signer != null) { | |||
bySigner.put(signer, publicKey); | |||
} | |||
} | |||
String user = null; | |||
Iterator<String> userIds = publicKey.getUserIDs(); | |||
if (!StringUtils.isEmptyOrNull(signer)) { | |||
while (userIds.hasNext()) { | |||
String userId = userIds.next(); | |||
if (BouncyCastleGpgKeyLocator.containsSigningKey(userId, | |||
keySpec)) { | |||
user = userId; | |||
break; | |||
} | |||
} | |||
} | |||
if (user == null) { | |||
userIds = publicKey.getUserIDs(); | |||
if (userIds.hasNext()) { | |||
user = userIds.next(); | |||
} | |||
} | |||
boolean expired = false; | |||
long validFor = publicKey.getValidSeconds(); | |||
if (validFor > 0 && signatureCreatedAt != null) { | |||
Instant expiredAt = publicKey.getCreationTime().toInstant() | |||
.plusSeconds(validFor); | |||
expired = expiredAt.isBefore(signatureCreatedAt.toInstant()); | |||
} | |||
// Trust data is not defined in OpenPGP; the format is implementation | |||
// specific. We don't use the GPG trustdb but simply the trust packet | |||
// on the public key, if present. Even if present, it may or may not | |||
// be set. | |||
byte[] trustData = publicKey.getTrustData(); | |||
TrustLevel trust = parseGpgTrustPacket(trustData); | |||
boolean verified = false; | |||
try { | |||
signature.init( | |||
new JcaPGPContentVerifierBuilderProvider() | |||
.setProvider(BouncyCastleProvider.PROVIDER_NAME), | |||
publicKey); | |||
signature.update(data); | |||
verified = signature.verify(); | |||
} catch (PGPException e) { | |||
throw new JGitInternalException( | |||
BCText.get().signatureVerificationError, e); | |||
} | |||
return new VerificationResult(signatureCreatedAt, signer, fingerprint, user, | |||
verified, expired, trust, null); | |||
} | |||
private TrustLevel parseGpgTrustPacket(byte[] packet) { | |||
if (packet == null || packet.length < 6) { | |||
// A GPG trust packet has at least 6 bytes. | |||
return TrustLevel.UNKNOWN; | |||
} | |||
if (packet[2] != 'g' || packet[3] != 'p' || packet[4] != 'g') { | |||
// Not a GPG trust packet | |||
return TrustLevel.UNKNOWN; | |||
} | |||
int trust = packet[0] & 0x0F; | |||
switch (trust) { | |||
case 0: // No determined/set | |||
case 1: // Trust expired; i.e., calculation outdated or key expired | |||
case 2: // Undefined: not enough information to set | |||
return TrustLevel.UNKNOWN; | |||
case 3: | |||
return TrustLevel.NEVER; | |||
case 4: | |||
return TrustLevel.MARGINAL; | |||
case 5: | |||
return TrustLevel.FULL; | |||
case 6: | |||
return TrustLevel.ULTIMATE; | |||
default: | |||
return TrustLevel.UNKNOWN; | |||
} | |||
} | |||
@Override | |||
public void clear() { | |||
byFingerprint.clear(); | |||
bySigner.clear(); | |||
} | |||
private static class VerificationResult implements SignatureVerification { | |||
private final Date creationDate; | |||
private final String signer; | |||
private final String keyUser; | |||
private final String fingerprint; | |||
private final boolean verified; | |||
private final boolean expired; | |||
private final @NonNull TrustLevel trustLevel; | |||
private final String message; | |||
public VerificationResult(Date creationDate, String signer, | |||
String fingerprint, String user, boolean verified, | |||
boolean expired, @NonNull TrustLevel trust, String message) { | |||
this.creationDate = creationDate; | |||
this.signer = signer; | |||
this.fingerprint = fingerprint; | |||
this.keyUser = user; | |||
this.verified = verified; | |||
this.expired = expired; | |||
this.trustLevel = trust; | |||
this.message = message; | |||
} | |||
@Override | |||
public Date getCreationDate() { | |||
return creationDate; | |||
} | |||
@Override | |||
public String getSigner() { | |||
return signer; | |||
} | |||
@Override | |||
public String getKeyUser() { | |||
return keyUser; | |||
} | |||
@Override | |||
public String getKeyFingerprint() { | |||
return fingerprint; | |||
} | |||
@Override | |||
public boolean isExpired() { | |||
return expired; | |||
} | |||
@Override | |||
public TrustLevel getTrustLevel() { | |||
return trustLevel; | |||
} | |||
@Override | |||
public String getMessage() { | |||
return message; | |||
} | |||
@Override | |||
public boolean getVerified() { | |||
return verified; | |||
} | |||
} | |||
} |
@@ -0,0 +1,28 @@ | |||
/* | |||
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> 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.gpg.bc.internal; | |||
import org.eclipse.jgit.lib.GpgSignatureVerifier; | |||
import org.eclipse.jgit.lib.GpgSignatureVerifierFactory; | |||
/** | |||
* A {@link GpgSignatureVerifierFactory} that creates | |||
* {@link GpgSignatureVerifier} instances that verify GPG signatures using | |||
* BouncyCastle and that do cache public keys. | |||
*/ | |||
public final class BouncyCastleGpgSignatureVerifierFactory | |||
extends GpgSignatureVerifierFactory { | |||
@Override | |||
public GpgSignatureVerifier getVerifier() { | |||
return new BouncyCastleGpgSignatureVerifier(); | |||
} | |||
} |
@@ -1,5 +1,5 @@ | |||
/* | |||
* Copyright (C) 2018, 2020, Salesforce and others | |||
* Copyright (C) 2018, 2021, Salesforce 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 | |||
@@ -34,18 +34,22 @@ import org.eclipse.jgit.annotations.NonNull; | |||
import org.eclipse.jgit.annotations.Nullable; | |||
import org.eclipse.jgit.api.errors.CanceledException; | |||
import org.eclipse.jgit.api.errors.JGitInternalException; | |||
import org.eclipse.jgit.api.errors.UnsupportedSigningFormatException; | |||
import org.eclipse.jgit.errors.UnsupportedCredentialItem; | |||
import org.eclipse.jgit.internal.JGitText; | |||
import org.eclipse.jgit.lib.CommitBuilder; | |||
import org.eclipse.jgit.lib.GpgConfig; | |||
import org.eclipse.jgit.lib.GpgObjectSigner; | |||
import org.eclipse.jgit.lib.GpgSignature; | |||
import org.eclipse.jgit.lib.GpgSigner; | |||
import org.eclipse.jgit.lib.GpgObjectSigner; | |||
import org.eclipse.jgit.lib.ObjectBuilder; | |||
import org.eclipse.jgit.lib.PersonIdent; | |||
import org.eclipse.jgit.lib.GpgConfig.GpgFormat; | |||
import org.eclipse.jgit.transport.CredentialsProvider; | |||
import org.eclipse.jgit.util.StringUtils; | |||
/** | |||
* GPG Signer using BouncyCastle library | |||
* GPG Signer using the BouncyCastle library. | |||
*/ | |||
public class BouncyCastleGpgSigner extends GpgSigner | |||
implements GpgObjectSigner { | |||
@@ -70,13 +74,32 @@ public class BouncyCastleGpgSigner extends GpgSigner | |||
public boolean canLocateSigningKey(@Nullable String gpgSigningKey, | |||
PersonIdent committer, CredentialsProvider credentialsProvider) | |||
throws CanceledException { | |||
try { | |||
return canLocateSigningKey(gpgSigningKey, committer, | |||
credentialsProvider, null); | |||
} catch (UnsupportedSigningFormatException e) { | |||
// Cannot occur with a null config | |||
return false; | |||
} | |||
} | |||
@Override | |||
public boolean canLocateSigningKey(@Nullable String gpgSigningKey, | |||
PersonIdent committer, CredentialsProvider credentialsProvider, | |||
GpgConfig config) | |||
throws CanceledException, UnsupportedSigningFormatException { | |||
if (config != null && config.getKeyFormat() != GpgFormat.OPENPGP) { | |||
throw new UnsupportedSigningFormatException( | |||
JGitText.get().onlyOpenPgpSupportedForSigning); | |||
} | |||
try (BouncyCastleGpgKeyPassphrasePrompt passphrasePrompt = new BouncyCastleGpgKeyPassphrasePrompt( | |||
credentialsProvider)) { | |||
BouncyCastleGpgKey gpgKey = locateSigningKey(gpgSigningKey, | |||
committer, passphrasePrompt); | |||
return gpgKey != null; | |||
} catch (PGPException | IOException | NoSuchAlgorithmException | |||
| NoSuchProviderException | URISyntaxException e) { | |||
} catch (CanceledException e) { | |||
throw e; | |||
} catch (Exception e) { | |||
return false; | |||
} | |||
} | |||
@@ -101,17 +124,28 @@ public class BouncyCastleGpgSigner extends GpgSigner | |||
public void sign(@NonNull CommitBuilder commit, | |||
@Nullable String gpgSigningKey, @NonNull PersonIdent committer, | |||
CredentialsProvider credentialsProvider) throws CanceledException { | |||
signObject(commit, gpgSigningKey, committer, credentialsProvider); | |||
try { | |||
signObject(commit, gpgSigningKey, committer, credentialsProvider, | |||
null); | |||
} catch (UnsupportedSigningFormatException e) { | |||
// Cannot occur with a null config | |||
} | |||
} | |||
@Override | |||
public void signObject(@NonNull ObjectBuilder object, | |||
@Nullable String gpgSigningKey, @NonNull PersonIdent committer, | |||
CredentialsProvider credentialsProvider) throws CanceledException { | |||
CredentialsProvider credentialsProvider, GpgConfig config) | |||
throws CanceledException, UnsupportedSigningFormatException { | |||
if (config != null && config.getKeyFormat() != GpgFormat.OPENPGP) { | |||
throw new UnsupportedSigningFormatException( | |||
JGitText.get().onlyOpenPgpSupportedForSigning); | |||
} | |||
try (BouncyCastleGpgKeyPassphrasePrompt passphrasePrompt = new BouncyCastleGpgKeyPassphrasePrompt( | |||
credentialsProvider)) { | |||
BouncyCastleGpgKey gpgKey = locateSigningKey(gpgSigningKey, | |||
committer, passphrasePrompt); | |||
committer, | |||
passphrasePrompt); | |||
PGPSecretKey secretKey = gpgKey.getSecretKey(); | |||
if (secretKey == null) { | |||
throw new JGitInternalException( | |||
@@ -178,7 +212,7 @@ public class BouncyCastleGpgSigner extends GpgSigner | |||
} | |||
} | |||
private String extractSignerId(String pgpUserId) { | |||
static String extractSignerId(String pgpUserId) { | |||
int from = pgpUserId.indexOf('<'); | |||
if (from >= 0) { | |||
int to = pgpUserId.indexOf('>', from + 1); |
@@ -0,0 +1,322 @@ | |||
/* | |||
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> 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.gpg.bc.internal.keys; | |||
import java.math.BigInteger; | |||
import java.nio.charset.StandardCharsets; | |||
import java.text.MessageFormat; | |||
import java.util.Arrays; | |||
import org.bouncycastle.asn1.ASN1ObjectIdentifier; | |||
import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers; | |||
import org.bouncycastle.asn1.x9.ECNamedCurveTable; | |||
import org.bouncycastle.asn1.x9.X9ECParameters; | |||
import org.bouncycastle.bcpg.DSAPublicBCPGKey; | |||
import org.bouncycastle.bcpg.ECPublicBCPGKey; | |||
import org.bouncycastle.bcpg.ElGamalPublicBCPGKey; | |||
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; | |||
import org.bouncycastle.bcpg.RSAPublicBCPGKey; | |||
import org.bouncycastle.crypto.ec.CustomNamedCurves; | |||
import org.bouncycastle.math.ec.ECAlgorithms; | |||
import org.bouncycastle.math.field.FiniteField; | |||
import org.bouncycastle.openpgp.PGPException; | |||
import org.bouncycastle.openpgp.PGPPublicKey; | |||
import org.bouncycastle.util.encoders.Hex; | |||
import org.eclipse.jgit.annotations.NonNull; | |||
import org.eclipse.jgit.gpg.bc.internal.BCText; | |||
import org.eclipse.jgit.util.sha1.SHA1; | |||
/** | |||
* Utilities to compute the <em>keygrip</em> of a key. A keygrip is a SHA1 hash | |||
* over the public key parameters and is used internally by the gpg-agent to | |||
* find the secret key belonging to a public key: the secret key is stored in a | |||
* file under ~/.gnupg/private-keys-v1.d/ with a name "<keygrip>.key". While | |||
* this storage organization is an implementation detail of GPG, the way | |||
* keygrips are computed is not; they are computed by libgcrypt and their | |||
* definition is stable. | |||
*/ | |||
public final class KeyGrip { | |||
// Some OIDs apparently unknown to BouncyCastle. | |||
private static String OID_OPENPGP_ED25519 = "1.3.6.1.4.1.11591.15.1"; //$NON-NLS-1$ | |||
private static String OID_RFC8410_CURVE25519 = "1.3.101.110"; //$NON-NLS-1$ | |||
private static String OID_RFC8410_ED25519 = "1.3.101.112"; //$NON-NLS-1$ | |||
private KeyGrip() { | |||
// No instantiation | |||
} | |||
/** | |||
* Computes the keygrip for a {@link PGPPublicKey}. | |||
* | |||
* @param publicKey | |||
* to get the keygrip of | |||
* @return the keygrip | |||
* @throws PGPException | |||
* if an unknown key type is encountered. | |||
*/ | |||
@NonNull | |||
public static byte[] getKeyGrip(PGPPublicKey publicKey) | |||
throws PGPException { | |||
SHA1 grip = SHA1.newInstance(); | |||
grip.setDetectCollision(false); | |||
switch (publicKey.getAlgorithm()) { | |||
case PublicKeyAlgorithmTags.RSA_GENERAL: | |||
case PublicKeyAlgorithmTags.RSA_ENCRYPT: | |||
case PublicKeyAlgorithmTags.RSA_SIGN: | |||
BigInteger modulus = ((RSAPublicBCPGKey) publicKey | |||
.getPublicKeyPacket().getKey()).getModulus(); | |||
hash(grip, modulus.toByteArray()); | |||
break; | |||
case PublicKeyAlgorithmTags.DSA: | |||
DSAPublicBCPGKey dsa = (DSAPublicBCPGKey) publicKey | |||
.getPublicKeyPacket().getKey(); | |||
hash(grip, dsa.getP().toByteArray(), 'p', true); | |||
hash(grip, dsa.getQ().toByteArray(), 'q', true); | |||
hash(grip, dsa.getG().toByteArray(), 'g', true); | |||
hash(grip, dsa.getY().toByteArray(), 'y', true); | |||
break; | |||
case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: | |||
case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: | |||
ElGamalPublicBCPGKey eg = (ElGamalPublicBCPGKey) publicKey | |||
.getPublicKeyPacket().getKey(); | |||
hash(grip, eg.getP().toByteArray(), 'p', true); | |||
hash(grip, eg.getG().toByteArray(), 'g', true); | |||
hash(grip, eg.getY().toByteArray(), 'y', true); | |||
break; | |||
case PublicKeyAlgorithmTags.ECDH: | |||
case PublicKeyAlgorithmTags.ECDSA: | |||
case PublicKeyAlgorithmTags.EDDSA: | |||
ECPublicBCPGKey ec = (ECPublicBCPGKey) publicKey | |||
.getPublicKeyPacket().getKey(); | |||
ASN1ObjectIdentifier curveOID = ec.getCurveOID(); | |||
// BC doesn't know these OIDs. | |||
if (OID_OPENPGP_ED25519.equals(curveOID.getId()) | |||
|| OID_RFC8410_ED25519.equals(curveOID.getId())) { | |||
return hashEd25519(grip, ec.getEncodedPoint()); | |||
} else if (CryptlibObjectIdentifiers.curvey25519.equals(curveOID) | |||
|| OID_RFC8410_CURVE25519.equals(curveOID.getId())) { | |||
// curvey25519 actually is the OpenPGP OID for Curve25519 and is | |||
// known to BC, but the parameters are for the short Weierstrass | |||
// form. See https://github.com/bcgit/bc-java/issues/399 . | |||
// libgcrypt uses Montgomery form. | |||
return hashCurve25519(grip, ec.getEncodedPoint()); | |||
} | |||
X9ECParameters params = getX9Parameters(curveOID); | |||
if (params == null) { | |||
throw new PGPException(MessageFormat | |||
.format(BCText.get().unknownCurve, curveOID.getId())); | |||
} | |||
// Need to write p, a, b, g, n, q | |||
BigInteger q = ec.getEncodedPoint(); | |||
byte[] g = params.getG().getEncoded(false); | |||
BigInteger a = params.getCurve().getA().toBigInteger(); | |||
BigInteger b = params.getCurve().getB().toBigInteger(); | |||
BigInteger n = params.getN(); | |||
BigInteger p = null; | |||
FiniteField field = params.getCurve().getField(); | |||
if (ECAlgorithms.isFpField(field)) { | |||
p = field.getCharacteristic(); | |||
} | |||
if (p == null) { | |||
// Don't know... | |||
throw new PGPException(MessageFormat.format( | |||
BCText.get().unknownCurveParameters, curveOID.getId())); | |||
} | |||
hash(grip, p.toByteArray(), 'p', false); | |||
hash(grip, a.toByteArray(), 'a', false); | |||
hash(grip, b.toByteArray(), 'b', false); | |||
hash(grip, g, 'g', false); | |||
hash(grip, n.toByteArray(), 'n', false); | |||
if (publicKey.getAlgorithm() == PublicKeyAlgorithmTags.EDDSA) { | |||
hashQ25519(grip, q); | |||
} else { | |||
hash(grip, q.toByteArray(), 'q', false); | |||
} | |||
break; | |||
default: | |||
throw new PGPException( | |||
MessageFormat.format(BCText.get().unknownKeyType, | |||
Integer.toString(publicKey.getAlgorithm()))); | |||
} | |||
return grip.digest(); | |||
} | |||
private static void hash(SHA1 grip, byte[] data) { | |||
// Need to skip leading zero bytes | |||
int i = 0; | |||
while (i < data.length && data[i] == 0) { | |||
i++; | |||
} | |||
int length = data.length - i; | |||
if (i < data.length) { | |||
if ((data[i] & 0x80) != 0) { | |||
grip.update((byte) 0); | |||
} | |||
grip.update(data, i, length); | |||
} | |||
} | |||
private static void hash(SHA1 grip, byte[] data, char id, boolean zeroPad) { | |||
// Need to skip leading zero bytes | |||
int i = 0; | |||
while (i < data.length && data[i] == 0) { | |||
i++; | |||
} | |||
int length = data.length - i; | |||
boolean addZero = false; | |||
if (i < data.length && zeroPad && (data[i] & 0x80) != 0) { | |||
addZero = true; | |||
} | |||
// libgcrypt includes an SExp in the hash | |||
String prefix = "(1:" + id + (addZero ? length + 1 : length) + ':'; //$NON-NLS-1$ | |||
grip.update(prefix.getBytes(StandardCharsets.US_ASCII)); | |||
// For some items, gcrypt prepends a zero byte if the high bit is set | |||
if (addZero) { | |||
grip.update((byte) 0); | |||
} | |||
if (i < data.length) { | |||
grip.update(data, i, length); | |||
} | |||
grip.update((byte) ')'); | |||
} | |||
private static void hashQ25519(SHA1 grip, BigInteger q) | |||
throws PGPException { | |||
byte[] data = q.toByteArray(); | |||
switch (data[0]) { | |||
case 0x04: | |||
if (data.length != 65) { | |||
throw new PGPException(MessageFormat.format( | |||
BCText.get().corrupt25519Key, Hex.toHexString(data))); | |||
} | |||
// Uncompressed: should not occur with ed25519 or curve25519 | |||
throw new PGPException(MessageFormat.format( | |||
BCText.get().uncompressed25519Key, Hex.toHexString(data))); | |||
case 0x40: | |||
if (data.length != 33) { | |||
throw new PGPException(MessageFormat.format( | |||
BCText.get().corrupt25519Key, Hex.toHexString(data))); | |||
} | |||
// Compressed; normal case. Skip prefix. | |||
hash(grip, Arrays.copyOfRange(data, 1, data.length), 'q', false); | |||
break; | |||
default: | |||
if (data.length != 32) { | |||
throw new PGPException(MessageFormat.format( | |||
BCText.get().corrupt25519Key, Hex.toHexString(data))); | |||
} | |||
// Compressed format without prefix. Should not occur? | |||
hash(grip, data, 'q', false); | |||
break; | |||
} | |||
} | |||
/** | |||
* Computes the keygrip for an ed25519 public key. | |||
* <p> | |||
* Package-visible for tests only. | |||
* </p> | |||
* | |||
* @param grip | |||
* initialized {@link SHA1} | |||
* @param q | |||
* the public key's EC point | |||
* @return the keygrip | |||
* @throws PGPException | |||
* if q indicates uncompressed format | |||
*/ | |||
@SuppressWarnings("nls") | |||
static byte[] hashEd25519(SHA1 grip, BigInteger q) throws PGPException { | |||
// For the values, see RFC 7748: https://tools.ietf.org/html/rfc7748 | |||
// p = 2^255 - 19 | |||
hash(grip, Hex.decodeStrict( | |||
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED"), | |||
'p', false); | |||
// Field: a = 1 | |||
hash(grip, new byte[] { 0x01 }, 'a', false); | |||
// Field: b = 121665/121666 (mod p) | |||
// See Berstein et.al., "Twisted Edwards Curves", | |||
// https://doi.org/10.1007/978-3-540-68164-9_26 | |||
hash(grip, Hex.decodeStrict( | |||
"2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A"), | |||
'b', false); | |||
// Generator point with affine X,Y | |||
// @formatter:off | |||
// X(P) = 15112221349535400772501151409588531511454012693041857206046113283949847762202 | |||
// Y(P) = 46316835694926478169428394003475163141307993866256225615783033603165251855960 | |||
// the "04" signifies uncompressed format. | |||
// @formatter:on | |||
hash(grip, Hex.decodeStrict("04" | |||
+ "216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A" | |||
+ "6666666666666666666666666666666666666666666666666666666666666658"), | |||
'g', false); | |||
// order = 2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed | |||
hash(grip, Hex.decodeStrict( | |||
"1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED"), | |||
'n', false); | |||
hashQ25519(grip, q); | |||
return grip.digest(); | |||
} | |||
/** | |||
* Computes the keygrip for a curve25519 public key. | |||
* <p> | |||
* Package-visible for tests only. | |||
* </p> | |||
* | |||
* @param grip | |||
* initialized {@link SHA1} | |||
* @param q | |||
* the public key's EC point | |||
* @return the keygrip | |||
* @throws PGPException | |||
* if q indicates uncompressed format | |||
*/ | |||
@SuppressWarnings("nls") | |||
static byte[] hashCurve25519(SHA1 grip, BigInteger q) throws PGPException { | |||
hash(grip, Hex.decodeStrict( | |||
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED"), | |||
'p', false); | |||
// Unclear: RFC 7748 says A = 486662. This value here is (A-2)/4 = | |||
// 121665. Compare ecc-curves.c in libgcrypt: | |||
// https://github.com/gpg/libgcrypt/blob/361a058/cipher/ecc-curves.c#L146 | |||
hash(grip, new byte[] { 0x01, (byte) 0xDB, 0x41 }, 'a', false); | |||
hash(grip, new byte[] { 0x01 }, 'b', false); | |||
// libgcrypt uses the old g.y value before the erratum to RFC 7748 for | |||
// the keygrip. The new value would be | |||
// 5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14. See | |||
// https://www.rfc-editor.org/errata/eid4730 and | |||
// https://github.com/gpg/libgcrypt/commit/f67b6492e0b0 | |||
hash(grip, Hex.decodeStrict("04" | |||
+ "0000000000000000000000000000000000000000000000000000000000000009" | |||
+ "20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9"), | |||
'g', false); | |||
hash(grip, Hex.decodeStrict( | |||
"1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED"), | |||
'n', false); | |||
hashQ25519(grip, q); | |||
return grip.digest(); | |||
} | |||
private static X9ECParameters getX9Parameters( | |||
ASN1ObjectIdentifier curveOID) { | |||
X9ECParameters params = CustomNamedCurves.getByOID(curveOID); | |||
if (params == null) { | |||
params = ECNamedCurveTable.getByOID(curveOID); | |||
} | |||
return params; | |||
} | |||
} |
@@ -0,0 +1,121 @@ | |||
/* | |||
* Copyright (C) 2021 Thomas Wolf <thomas.wolf@paranor.ch> 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.gpg.bc.internal.keys; | |||
import java.security.NoSuchAlgorithmException; | |||
import java.text.MessageFormat; | |||
import javax.crypto.Cipher; | |||
import javax.crypto.SecretKey; | |||
import javax.crypto.spec.IvParameterSpec; | |||
import javax.crypto.spec.SecretKeySpec; | |||
import org.bouncycastle.openpgp.PGPException; | |||
import org.bouncycastle.openpgp.PGPUtil; | |||
import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory; | |||
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; | |||
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; | |||
import org.bouncycastle.util.Arrays; | |||
import org.eclipse.jgit.gpg.bc.internal.BCText; | |||
/** | |||
* A {@link PBEProtectionRemoverFactory} using AES/OCB/NoPadding for decryption. | |||
* It accepts an AAD in the factory's constructor, so the factory can be used to | |||
* create a {@link PBESecretKeyDecryptor} only for a particular input. | |||
* <p> | |||
* For JGit's needs, this is sufficient, but for a general upstream | |||
* implementation that limitation might not be acceptable. | |||
* </p> | |||
*/ | |||
class OCBPBEProtectionRemoverFactory | |||
implements PBEProtectionRemoverFactory { | |||
private final PGPDigestCalculatorProvider calculatorProvider; | |||
private final char[] passphrase; | |||
private final byte[] aad; | |||
/** | |||
* Creates a new factory instance with the given parameters. | |||
* <p> | |||
* Because the AAD is given at factory level, the {@link PBESecretKeyDecryptor}s | |||
* created by the factory can be used to decrypt only a particular input | |||
* matching this AAD. | |||
* </p> | |||
* | |||
* @param passphrase to use for secret key derivation | |||
* @param calculatorProvider for computing digests | |||
* @param aad for the OCB decryption | |||
*/ | |||
OCBPBEProtectionRemoverFactory(char[] passphrase, | |||
PGPDigestCalculatorProvider calculatorProvider, byte[] aad) { | |||
this.calculatorProvider = calculatorProvider; | |||
this.passphrase = passphrase; | |||
this.aad = aad; | |||
} | |||
@Override | |||
public PBESecretKeyDecryptor createDecryptor(String protection) | |||
throws PGPException { | |||
return new PBESecretKeyDecryptor(passphrase, calculatorProvider) { | |||
@Override | |||
public byte[] recoverKeyData(int encAlgorithm, byte[] key, | |||
byte[] iv, byte[] encrypted, int encryptedOffset, | |||
int encryptedLength) throws PGPException { | |||
String algorithmName = PGPUtil | |||
.getSymmetricCipherName(encAlgorithm); | |||
byte[] decrypted = null; | |||
try { | |||
Cipher c = Cipher | |||
.getInstance(algorithmName + "/OCB/NoPadding"); //$NON-NLS-1$ | |||
SecretKey secretKey = new SecretKeySpec(key, algorithmName); | |||
c.init(Cipher.DECRYPT_MODE, secretKey, | |||
new IvParameterSpec(iv)); | |||
c.updateAAD(aad); | |||
decrypted = new byte[c.getOutputSize(encryptedLength)]; | |||
int decryptedLength = c.update(encrypted, encryptedOffset, | |||
encryptedLength, decrypted); | |||
// doFinal() for OCB will check the MAC and throw an | |||
// exception if it doesn't match | |||
decryptedLength += c.doFinal(decrypted, decryptedLength); | |||
if (decryptedLength != decrypted.length) { | |||
throw new PGPException(MessageFormat.format( | |||
BCText.get().cryptWrongDecryptedLength, | |||
Integer.valueOf(decryptedLength), | |||
Integer.valueOf(decrypted.length))); | |||
} | |||
byte[] result = decrypted; | |||
decrypted = null; // Don't clear in finally | |||
return result; | |||
} catch (NoClassDefFoundError e) { | |||
String msg = MessageFormat.format( | |||
BCText.get().gpgNoSuchAlgorithm, | |||
algorithmName + "/OCB"); //$NON-NLS-1$ | |||
throw new PGPException(msg, | |||
new NoSuchAlgorithmException(msg, e)); | |||
} catch (PGPException e) { | |||
throw e; | |||
} catch (Exception e) { | |||
throw new PGPException( | |||
MessageFormat.format(BCText.get().cryptCipherError, | |||
e.getLocalizedMessage()), | |||
e); | |||
} finally { | |||
if (decrypted != null) { | |||
// Prevent halfway decrypted data leaking. | |||
Arrays.fill(decrypted, (byte) 0); | |||
} | |||
} | |||
} | |||
}; | |||
} | |||
} |
@@ -0,0 +1,826 @@ | |||
/* | |||
* Copyright (c) 2000-2021 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org) | |||
* <p> | |||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software | |||
* and associated documentation files (the "Software"), to deal in the Software without restriction, | |||
*including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, | |||
* subject to the following conditions: | |||
* </p> | |||
* <p> | |||
* The above copyright notice and this permission notice shall be included in all copies or substantial | |||
* portions of the Software. | |||
* </p> | |||
* <p> | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | |||
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
* DEALINGS IN THE SOFTWARE. | |||
* </p> | |||
*/ | |||
package org.eclipse.jgit.gpg.bc.internal.keys; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.OutputStream; | |||
import java.math.BigInteger; | |||
import java.util.Date; | |||
import org.bouncycastle.asn1.x9.ECNamedCurveTable; | |||
import org.bouncycastle.bcpg.DSAPublicBCPGKey; | |||
import org.bouncycastle.bcpg.DSASecretBCPGKey; | |||
import org.bouncycastle.bcpg.ECDSAPublicBCPGKey; | |||
import org.bouncycastle.bcpg.ECPublicBCPGKey; | |||
import org.bouncycastle.bcpg.ECSecretBCPGKey; | |||
import org.bouncycastle.bcpg.ElGamalPublicBCPGKey; | |||
import org.bouncycastle.bcpg.ElGamalSecretBCPGKey; | |||
import org.bouncycastle.bcpg.HashAlgorithmTags; | |||
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; | |||
import org.bouncycastle.bcpg.PublicKeyPacket; | |||
import org.bouncycastle.bcpg.RSAPublicBCPGKey; | |||
import org.bouncycastle.bcpg.RSASecretBCPGKey; | |||
import org.bouncycastle.bcpg.S2K; | |||
import org.bouncycastle.bcpg.SecretKeyPacket; | |||
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; | |||
import org.bouncycastle.openpgp.PGPException; | |||
import org.bouncycastle.openpgp.PGPPublicKey; | |||
import org.bouncycastle.openpgp.PGPSecretKey; | |||
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; | |||
import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory; | |||
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; | |||
import org.bouncycastle.openpgp.operator.PGPDigestCalculator; | |||
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; | |||
import org.bouncycastle.util.Arrays; | |||
import org.bouncycastle.util.Strings; | |||
/** | |||
* A parser for secret keys stored in s-expressions. Original BouncyCastle code | |||
* modified by the JGit team to: | |||
* <ul> | |||
* <li>handle unencrypted DSA, EC, and ElGamal keys (upstream only handles | |||
* unencrypted RSA), and</li> | |||
* <li>handle secret keys using AES/OCB as encryption (those don't have a | |||
* hash).</li> | |||
* </ul> | |||
*/ | |||
@SuppressWarnings("nls") | |||
public class SExprParser { | |||
private final PGPDigestCalculatorProvider digestProvider; | |||
/** | |||
* Base constructor. | |||
* | |||
* @param digestProvider | |||
* a provider for digest calculations. Used to confirm key | |||
* protection hashes. | |||
*/ | |||
public SExprParser(PGPDigestCalculatorProvider digestProvider) { | |||
this.digestProvider = digestProvider; | |||
} | |||
/** | |||
* Parse a secret key from one of the GPG S expression keys associating it | |||
* with the passed in public key. | |||
* | |||
* @param inputStream | |||
* to read from | |||
* @param keyProtectionRemoverFactory | |||
* for decrypting encrypted keys | |||
* @param pubKey | |||
* the private key should belong to | |||
* | |||
* @return a secret key object. | |||
* @throws IOException | |||
* @throws PGPException | |||
*/ | |||
public PGPSecretKey parseSecretKey(InputStream inputStream, | |||
PBEProtectionRemoverFactory keyProtectionRemoverFactory, | |||
PGPPublicKey pubKey) throws IOException, PGPException { | |||
SXprUtils.skipOpenParenthesis(inputStream); | |||
String type; | |||
type = SXprUtils.readString(inputStream, inputStream.read()); | |||
if (type.equals("protected-private-key") | |||
|| type.equals("private-key")) { | |||
SXprUtils.skipOpenParenthesis(inputStream); | |||
String keyType = SXprUtils.readString(inputStream, | |||
inputStream.read()); | |||
if (keyType.equals("ecc")) { | |||
SXprUtils.skipOpenParenthesis(inputStream); | |||
String curveID = SXprUtils.readString(inputStream, | |||
inputStream.read()); | |||
String curveName = SXprUtils.readString(inputStream, | |||
inputStream.read()); | |||
SXprUtils.skipCloseParenthesis(inputStream); | |||
byte[] qVal; | |||
SXprUtils.skipOpenParenthesis(inputStream); | |||
type = SXprUtils.readString(inputStream, inputStream.read()); | |||
if (type.equals("q")) { | |||
qVal = SXprUtils.readBytes(inputStream, inputStream.read()); | |||
} else { | |||
throw new PGPException("no q value found"); | |||
} | |||
SXprUtils.skipCloseParenthesis(inputStream); | |||
BigInteger d = processECSecretKey(inputStream, curveID, | |||
curveName, qVal, keyProtectionRemoverFactory); | |||
if (curveName.startsWith("NIST ")) { | |||
curveName = curveName.substring("NIST ".length()); | |||
} | |||
ECPublicBCPGKey basePubKey = new ECDSAPublicBCPGKey( | |||
ECNamedCurveTable.getOID(curveName), | |||
new BigInteger(1, qVal)); | |||
ECPublicBCPGKey assocPubKey = (ECPublicBCPGKey) pubKey | |||
.getPublicKeyPacket().getKey(); | |||
if (!basePubKey.getCurveOID().equals(assocPubKey.getCurveOID()) | |||
|| !basePubKey.getEncodedPoint() | |||
.equals(assocPubKey.getEncodedPoint())) { | |||
throw new PGPException( | |||
"passed in public key does not match secret key"); | |||
} | |||
return new PGPSecretKey( | |||
new SecretKeyPacket(pubKey.getPublicKeyPacket(), | |||
SymmetricKeyAlgorithmTags.NULL, null, null, | |||
new ECSecretBCPGKey(d).getEncoded()), | |||
pubKey); | |||
} else if (keyType.equals("dsa")) { | |||
BigInteger p = readBigInteger("p", inputStream); | |||
BigInteger q = readBigInteger("q", inputStream); | |||
BigInteger g = readBigInteger("g", inputStream); | |||
BigInteger y = readBigInteger("y", inputStream); | |||
BigInteger x = processDSASecretKey(inputStream, p, q, g, y, | |||
keyProtectionRemoverFactory); | |||
DSAPublicBCPGKey basePubKey = new DSAPublicBCPGKey(p, q, g, y); | |||
DSAPublicBCPGKey assocPubKey = (DSAPublicBCPGKey) pubKey | |||
.getPublicKeyPacket().getKey(); | |||
if (!basePubKey.getP().equals(assocPubKey.getP()) | |||
|| !basePubKey.getQ().equals(assocPubKey.getQ()) | |||
|| !basePubKey.getG().equals(assocPubKey.getG()) | |||
|| !basePubKey.getY().equals(assocPubKey.getY())) { | |||
throw new PGPException( | |||
"passed in public key does not match secret key"); | |||
} | |||
return new PGPSecretKey( | |||
new SecretKeyPacket(pubKey.getPublicKeyPacket(), | |||
SymmetricKeyAlgorithmTags.NULL, null, null, | |||
new DSASecretBCPGKey(x).getEncoded()), | |||
pubKey); | |||
} else if (keyType.equals("elg")) { | |||
BigInteger p = readBigInteger("p", inputStream); | |||
BigInteger g = readBigInteger("g", inputStream); | |||
BigInteger y = readBigInteger("y", inputStream); | |||
BigInteger x = processElGamalSecretKey(inputStream, p, g, y, | |||
keyProtectionRemoverFactory); | |||
ElGamalPublicBCPGKey basePubKey = new ElGamalPublicBCPGKey(p, g, | |||
y); | |||
ElGamalPublicBCPGKey assocPubKey = (ElGamalPublicBCPGKey) pubKey | |||
.getPublicKeyPacket().getKey(); | |||
if (!basePubKey.getP().equals(assocPubKey.getP()) | |||
|| !basePubKey.getG().equals(assocPubKey.getG()) | |||
|| !basePubKey.getY().equals(assocPubKey.getY())) { | |||
throw new PGPException( | |||
"passed in public key does not match secret key"); | |||
} | |||
return new PGPSecretKey( | |||
new SecretKeyPacket(pubKey.getPublicKeyPacket(), | |||
SymmetricKeyAlgorithmTags.NULL, null, null, | |||
new ElGamalSecretBCPGKey(x).getEncoded()), | |||
pubKey); | |||
} else if (keyType.equals("rsa")) { | |||
BigInteger n = readBigInteger("n", inputStream); | |||
BigInteger e = readBigInteger("e", inputStream); | |||
BigInteger[] values = processRSASecretKey(inputStream, n, e, | |||
keyProtectionRemoverFactory); | |||
// TODO: type of RSA key? | |||
RSAPublicBCPGKey basePubKey = new RSAPublicBCPGKey(n, e); | |||
RSAPublicBCPGKey assocPubKey = (RSAPublicBCPGKey) pubKey | |||
.getPublicKeyPacket().getKey(); | |||
if (!basePubKey.getModulus().equals(assocPubKey.getModulus()) | |||
|| !basePubKey.getPublicExponent() | |||
.equals(assocPubKey.getPublicExponent())) { | |||
throw new PGPException( | |||
"passed in public key does not match secret key"); | |||
} | |||
return new PGPSecretKey(new SecretKeyPacket( | |||
pubKey.getPublicKeyPacket(), | |||
SymmetricKeyAlgorithmTags.NULL, null, null, | |||
new RSASecretBCPGKey(values[0], values[1], values[2]) | |||
.getEncoded()), | |||
pubKey); | |||
} else { | |||
throw new PGPException("unknown key type: " + keyType); | |||
} | |||
} | |||
throw new PGPException("unknown key type found"); | |||
} | |||
/** | |||
* Parse a secret key from one of the GPG S expression keys. | |||
* | |||
* @param inputStream | |||
* to read from | |||
* @param keyProtectionRemoverFactory | |||
* for decrypting encrypted keys | |||
* @param fingerPrintCalculator | |||
* for calculating key fingerprints | |||
* | |||
* @return a secret key object. | |||
* @throws IOException | |||
* @throws PGPException | |||
*/ | |||
public PGPSecretKey parseSecretKey(InputStream inputStream, | |||
PBEProtectionRemoverFactory keyProtectionRemoverFactory, | |||
KeyFingerPrintCalculator fingerPrintCalculator) | |||
throws IOException, PGPException { | |||
SXprUtils.skipOpenParenthesis(inputStream); | |||
String type; | |||
type = SXprUtils.readString(inputStream, inputStream.read()); | |||
if (type.equals("protected-private-key") | |||
|| type.equals("private-key")) { | |||
SXprUtils.skipOpenParenthesis(inputStream); | |||
String keyType = SXprUtils.readString(inputStream, | |||
inputStream.read()); | |||
if (keyType.equals("ecc")) { | |||
SXprUtils.skipOpenParenthesis(inputStream); | |||
String curveID = SXprUtils.readString(inputStream, | |||
inputStream.read()); | |||
String curveName = SXprUtils.readString(inputStream, | |||
inputStream.read()); | |||
if (curveName.startsWith("NIST ")) { | |||
curveName = curveName.substring("NIST ".length()); | |||
} | |||
SXprUtils.skipCloseParenthesis(inputStream); | |||
byte[] qVal; | |||
SXprUtils.skipOpenParenthesis(inputStream); | |||
type = SXprUtils.readString(inputStream, inputStream.read()); | |||
if (type.equals("q")) { | |||
qVal = SXprUtils.readBytes(inputStream, inputStream.read()); | |||
} else { | |||
throw new PGPException("no q value found"); | |||
} | |||
PublicKeyPacket pubPacket = new PublicKeyPacket( | |||
PublicKeyAlgorithmTags.ECDSA, new Date(), | |||
new ECDSAPublicBCPGKey( | |||
ECNamedCurveTable.getOID(curveName), | |||
new BigInteger(1, qVal))); | |||
SXprUtils.skipCloseParenthesis(inputStream); | |||
BigInteger d = processECSecretKey(inputStream, curveID, | |||
curveName, qVal, keyProtectionRemoverFactory); | |||
return new PGPSecretKey( | |||
new SecretKeyPacket(pubPacket, | |||
SymmetricKeyAlgorithmTags.NULL, null, null, | |||
new ECSecretBCPGKey(d).getEncoded()), | |||
new PGPPublicKey(pubPacket, fingerPrintCalculator)); | |||
} else if (keyType.equals("dsa")) { | |||
BigInteger p = readBigInteger("p", inputStream); | |||
BigInteger q = readBigInteger("q", inputStream); | |||
BigInteger g = readBigInteger("g", inputStream); | |||
BigInteger y = readBigInteger("y", inputStream); | |||
BigInteger x = processDSASecretKey(inputStream, p, q, g, y, | |||
keyProtectionRemoverFactory); | |||
PublicKeyPacket pubPacket = new PublicKeyPacket( | |||
PublicKeyAlgorithmTags.DSA, new Date(), | |||
new DSAPublicBCPGKey(p, q, g, y)); | |||
return new PGPSecretKey( | |||
new SecretKeyPacket(pubPacket, | |||
SymmetricKeyAlgorithmTags.NULL, null, null, | |||
new DSASecretBCPGKey(x).getEncoded()), | |||
new PGPPublicKey(pubPacket, fingerPrintCalculator)); | |||
} else if (keyType.equals("elg")) { | |||
BigInteger p = readBigInteger("p", inputStream); | |||
BigInteger g = readBigInteger("g", inputStream); | |||
BigInteger y = readBigInteger("y", inputStream); | |||
BigInteger x = processElGamalSecretKey(inputStream, p, g, y, | |||
keyProtectionRemoverFactory); | |||
PublicKeyPacket pubPacket = new PublicKeyPacket( | |||
PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT, new Date(), | |||
new ElGamalPublicBCPGKey(p, g, y)); | |||
return new PGPSecretKey( | |||
new SecretKeyPacket(pubPacket, | |||
SymmetricKeyAlgorithmTags.NULL, null, null, | |||
new ElGamalSecretBCPGKey(x).getEncoded()), | |||
new PGPPublicKey(pubPacket, fingerPrintCalculator)); | |||
} else if (keyType.equals("rsa")) { | |||
BigInteger n = readBigInteger("n", inputStream); | |||
BigInteger e = readBigInteger("e", inputStream); | |||
BigInteger[] values = processRSASecretKey(inputStream, n, e, | |||
keyProtectionRemoverFactory); | |||
// TODO: type of RSA key? | |||
PublicKeyPacket pubPacket = new PublicKeyPacket( | |||
PublicKeyAlgorithmTags.RSA_GENERAL, new Date(), | |||
new RSAPublicBCPGKey(n, e)); | |||
return new PGPSecretKey( | |||
new SecretKeyPacket(pubPacket, | |||
SymmetricKeyAlgorithmTags.NULL, null, null, | |||
new RSASecretBCPGKey(values[0], values[1], | |||
values[2]).getEncoded()), | |||
new PGPPublicKey(pubPacket, fingerPrintCalculator)); | |||
} else { | |||
throw new PGPException("unknown key type: " + keyType); | |||
} | |||
} | |||
throw new PGPException("unknown key type found"); | |||
} | |||
private BigInteger readBigInteger(String expectedType, | |||
InputStream inputStream) throws IOException, PGPException { | |||
SXprUtils.skipOpenParenthesis(inputStream); | |||
String type = SXprUtils.readString(inputStream, inputStream.read()); | |||
if (!type.equals(expectedType)) { | |||
throw new PGPException(expectedType + " value expected"); | |||
} | |||
byte[] nBytes = SXprUtils.readBytes(inputStream, inputStream.read()); | |||
BigInteger v = new BigInteger(1, nBytes); | |||
SXprUtils.skipCloseParenthesis(inputStream); | |||
return v; | |||
} | |||
private static byte[][] extractData(InputStream inputStream, | |||
PBEProtectionRemoverFactory keyProtectionRemoverFactory) | |||
throws PGPException, IOException { | |||
byte[] data; | |||
byte[] protectedAt = null; | |||
SXprUtils.skipOpenParenthesis(inputStream); | |||
String type = SXprUtils.readString(inputStream, inputStream.read()); | |||
if (type.equals("protected")) { | |||
String protection = SXprUtils.readString(inputStream, | |||
inputStream.read()); | |||
SXprUtils.skipOpenParenthesis(inputStream); | |||
S2K s2k = SXprUtils.parseS2K(inputStream); | |||
byte[] iv = SXprUtils.readBytes(inputStream, inputStream.read()); | |||
SXprUtils.skipCloseParenthesis(inputStream); | |||
byte[] secKeyData = SXprUtils.readBytes(inputStream, | |||
inputStream.read()); | |||
SXprUtils.skipCloseParenthesis(inputStream); | |||
PBESecretKeyDecryptor keyDecryptor = keyProtectionRemoverFactory | |||
.createDecryptor(protection); | |||
// TODO: recognise other algorithms | |||
byte[] key = keyDecryptor.makeKeyFromPassPhrase( | |||
SymmetricKeyAlgorithmTags.AES_128, s2k); | |||
data = keyDecryptor.recoverKeyData( | |||
SymmetricKeyAlgorithmTags.AES_128, key, iv, secKeyData, 0, | |||
secKeyData.length); | |||
// check if protected at is present | |||
if (inputStream.read() == '(') { | |||
ByteArrayOutputStream bOut = new ByteArrayOutputStream(); | |||
bOut.write('('); | |||
int ch; | |||
while ((ch = inputStream.read()) >= 0 && ch != ')') { | |||
bOut.write(ch); | |||
} | |||
if (ch != ')') { | |||
throw new IOException("unexpected end to SExpr"); | |||
} | |||
bOut.write(')'); | |||
protectedAt = bOut.toByteArray(); | |||
} | |||
SXprUtils.skipCloseParenthesis(inputStream); | |||
SXprUtils.skipCloseParenthesis(inputStream); | |||
} else if (type.equals("d") || type.equals("x")) { | |||
// JGit modification: unencrypted DSA or ECC keys can have an "x" | |||
// here | |||
return null; | |||
} else { | |||
throw new PGPException("protected block not found"); | |||
} | |||
return new byte[][] { data, protectedAt }; | |||
} | |||
private BigInteger processDSASecretKey(InputStream inputStream, | |||
BigInteger p, BigInteger q, BigInteger g, BigInteger y, | |||
PBEProtectionRemoverFactory keyProtectionRemoverFactory) | |||
throws IOException, PGPException { | |||
String type; | |||
byte[][] basicData = extractData(inputStream, | |||
keyProtectionRemoverFactory); | |||
// JGit modification: handle unencrypted DSA keys | |||
if (basicData == null) { | |||
byte[] nBytes = SXprUtils.readBytes(inputStream, | |||
inputStream.read()); | |||
BigInteger x = new BigInteger(1, nBytes); | |||
SXprUtils.skipCloseParenthesis(inputStream); | |||
return x; | |||
} | |||
byte[] keyData = basicData[0]; | |||
byte[] protectedAt = basicData[1]; | |||
// | |||
// parse the secret key S-expr | |||
// | |||
InputStream keyIn = new ByteArrayInputStream(keyData); | |||
SXprUtils.skipOpenParenthesis(keyIn); | |||
SXprUtils.skipOpenParenthesis(keyIn); | |||
BigInteger x = readBigInteger("x", keyIn); | |||
SXprUtils.skipCloseParenthesis(keyIn); | |||
// JGit modification: OCB-encrypted keys don't have and don't need a | |||
// hash | |||
if (keyProtectionRemoverFactory instanceof OCBPBEProtectionRemoverFactory) { | |||
return x; | |||
} | |||
SXprUtils.skipOpenParenthesis(keyIn); | |||
type = SXprUtils.readString(keyIn, keyIn.read()); | |||
if (!type.equals("hash")) { | |||
throw new PGPException("hash keyword expected"); | |||
} | |||
type = SXprUtils.readString(keyIn, keyIn.read()); | |||
if (!type.equals("sha1")) { | |||
throw new PGPException("hash keyword expected"); | |||
} | |||
byte[] hashBytes = SXprUtils.readBytes(keyIn, keyIn.read()); | |||
SXprUtils.skipCloseParenthesis(keyIn); | |||
if (digestProvider != null) { | |||
PGPDigestCalculator digestCalculator = digestProvider | |||
.get(HashAlgorithmTags.SHA1); | |||
OutputStream dOut = digestCalculator.getOutputStream(); | |||
dOut.write(Strings.toByteArray("(3:dsa")); | |||
writeCanonical(dOut, "p", p); | |||
writeCanonical(dOut, "q", q); | |||
writeCanonical(dOut, "g", g); | |||
writeCanonical(dOut, "y", y); | |||
writeCanonical(dOut, "x", x); | |||
// check protected-at | |||
if (protectedAt != null) { | |||
dOut.write(protectedAt); | |||
} | |||
dOut.write(Strings.toByteArray(")")); | |||
byte[] check = digestCalculator.getDigest(); | |||
if (!Arrays.constantTimeAreEqual(check, hashBytes)) { | |||
throw new PGPException( | |||
"checksum on protected data failed in SExpr"); | |||
} | |||
} | |||
return x; | |||
} | |||
private BigInteger processElGamalSecretKey(InputStream inputStream, | |||
BigInteger p, BigInteger g, BigInteger y, | |||
PBEProtectionRemoverFactory keyProtectionRemoverFactory) | |||
throws IOException, PGPException { | |||
String type; | |||
byte[][] basicData = extractData(inputStream, | |||
keyProtectionRemoverFactory); | |||
// JGit modification: handle unencrypted EC keys | |||
if (basicData == null) { | |||
byte[] nBytes = SXprUtils.readBytes(inputStream, | |||
inputStream.read()); | |||
BigInteger x = new BigInteger(1, nBytes); | |||
SXprUtils.skipCloseParenthesis(inputStream); | |||
return x; | |||
} | |||
byte[] keyData = basicData[0]; | |||
byte[] protectedAt = basicData[1]; | |||
// | |||
// parse the secret key S-expr | |||
// | |||
InputStream keyIn = new ByteArrayInputStream(keyData); | |||
SXprUtils.skipOpenParenthesis(keyIn); | |||
SXprUtils.skipOpenParenthesis(keyIn); | |||
BigInteger x = readBigInteger("x", keyIn); | |||
SXprUtils.skipCloseParenthesis(keyIn); | |||
// JGit modification: OCB-encrypted keys don't have and don't need a | |||
// hash | |||
if (keyProtectionRemoverFactory instanceof OCBPBEProtectionRemoverFactory) { | |||
return x; | |||
} | |||
SXprUtils.skipOpenParenthesis(keyIn); | |||
type = SXprUtils.readString(keyIn, keyIn.read()); | |||
if (!type.equals("hash")) { | |||
throw new PGPException("hash keyword expected"); | |||
} | |||
type = SXprUtils.readString(keyIn, keyIn.read()); | |||
if (!type.equals("sha1")) { | |||
throw new PGPException("hash keyword expected"); | |||
} | |||
byte[] hashBytes = SXprUtils.readBytes(keyIn, keyIn.read()); | |||
SXprUtils.skipCloseParenthesis(keyIn); | |||
if (digestProvider != null) { | |||
PGPDigestCalculator digestCalculator = digestProvider | |||
.get(HashAlgorithmTags.SHA1); | |||
OutputStream dOut = digestCalculator.getOutputStream(); | |||
dOut.write(Strings.toByteArray("(3:elg")); | |||
writeCanonical(dOut, "p", p); | |||
writeCanonical(dOut, "g", g); | |||
writeCanonical(dOut, "y", y); | |||
writeCanonical(dOut, "x", x); | |||
// check protected-at | |||
if (protectedAt != null) { | |||
dOut.write(protectedAt); | |||
} | |||
dOut.write(Strings.toByteArray(")")); | |||
byte[] check = digestCalculator.getDigest(); | |||
if (!Arrays.constantTimeAreEqual(check, hashBytes)) { | |||
throw new PGPException( | |||
"checksum on protected data failed in SExpr"); | |||
} | |||
} | |||
return x; | |||
} | |||
private BigInteger processECSecretKey(InputStream inputStream, | |||
String curveID, String curveName, byte[] qVal, | |||
PBEProtectionRemoverFactory keyProtectionRemoverFactory) | |||
throws IOException, PGPException { | |||
String type; | |||
byte[][] basicData = extractData(inputStream, | |||
keyProtectionRemoverFactory); | |||
// JGit modification: handle unencrypted EC keys | |||
if (basicData == null) { | |||
byte[] nBytes = SXprUtils.readBytes(inputStream, | |||
inputStream.read()); | |||
BigInteger d = new BigInteger(1, nBytes); | |||
SXprUtils.skipCloseParenthesis(inputStream); | |||
return d; | |||
} | |||
byte[] keyData = basicData[0]; | |||
byte[] protectedAt = basicData[1]; | |||
// | |||
// parse the secret key S-expr | |||
// | |||
InputStream keyIn = new ByteArrayInputStream(keyData); | |||
SXprUtils.skipOpenParenthesis(keyIn); | |||
SXprUtils.skipOpenParenthesis(keyIn); | |||
BigInteger d = readBigInteger("d", keyIn); | |||
SXprUtils.skipCloseParenthesis(keyIn); | |||
// JGit modification: OCB-encrypted keys don't have and don't need a | |||
// hash | |||
if (keyProtectionRemoverFactory instanceof OCBPBEProtectionRemoverFactory) { | |||
return d; | |||
} | |||
SXprUtils.skipOpenParenthesis(keyIn); | |||
type = SXprUtils.readString(keyIn, keyIn.read()); | |||
if (!type.equals("hash")) { | |||
throw new PGPException("hash keyword expected"); | |||
} | |||
type = SXprUtils.readString(keyIn, keyIn.read()); | |||
if (!type.equals("sha1")) { | |||
throw new PGPException("hash keyword expected"); | |||
} | |||
byte[] hashBytes = SXprUtils.readBytes(keyIn, keyIn.read()); | |||
SXprUtils.skipCloseParenthesis(keyIn); | |||
if (digestProvider != null) { | |||
PGPDigestCalculator digestCalculator = digestProvider | |||
.get(HashAlgorithmTags.SHA1); | |||
OutputStream dOut = digestCalculator.getOutputStream(); | |||
dOut.write(Strings.toByteArray("(3:ecc")); | |||
dOut.write(Strings.toByteArray("(" + curveID.length() + ":" | |||
+ curveID + curveName.length() + ":" + curveName + ")")); | |||
writeCanonical(dOut, "q", qVal); | |||
writeCanonical(dOut, "d", d); | |||
// check protected-at | |||
if (protectedAt != null) { | |||
dOut.write(protectedAt); | |||
} | |||
dOut.write(Strings.toByteArray(")")); | |||
byte[] check = digestCalculator.getDigest(); | |||
if (!Arrays.constantTimeAreEqual(check, hashBytes)) { | |||
throw new PGPException( | |||
"checksum on protected data failed in SExpr"); | |||
} | |||
} | |||
return d; | |||
} | |||
private BigInteger[] processRSASecretKey(InputStream inputStream, | |||
BigInteger n, BigInteger e, | |||
PBEProtectionRemoverFactory keyProtectionRemoverFactory) | |||
throws IOException, PGPException { | |||
String type; | |||
byte[][] basicData = extractData(inputStream, | |||
keyProtectionRemoverFactory); | |||
byte[] keyData; | |||
byte[] protectedAt = null; | |||
InputStream keyIn; | |||
BigInteger d; | |||
if (basicData == null) { | |||
keyIn = inputStream; | |||
byte[] nBytes = SXprUtils.readBytes(inputStream, | |||
inputStream.read()); | |||
d = new BigInteger(1, nBytes); | |||
SXprUtils.skipCloseParenthesis(inputStream); | |||
} else { | |||
keyData = basicData[0]; | |||
protectedAt = basicData[1]; | |||
keyIn = new ByteArrayInputStream(keyData); | |||
SXprUtils.skipOpenParenthesis(keyIn); | |||
SXprUtils.skipOpenParenthesis(keyIn); | |||
d = readBigInteger("d", keyIn); | |||
} | |||
// | |||
// parse the secret key S-expr | |||
// | |||
BigInteger p = readBigInteger("p", keyIn); | |||
BigInteger q = readBigInteger("q", keyIn); | |||
BigInteger u = readBigInteger("u", keyIn); | |||
// JGit modification: OCB-encrypted keys don't have and don't need a | |||
// hash | |||
if (basicData == null | |||
|| keyProtectionRemoverFactory instanceof OCBPBEProtectionRemoverFactory) { | |||
return new BigInteger[] { d, p, q, u }; | |||
} | |||
SXprUtils.skipCloseParenthesis(keyIn); | |||
SXprUtils.skipOpenParenthesis(keyIn); | |||
type = SXprUtils.readString(keyIn, keyIn.read()); | |||
if (!type.equals("hash")) { | |||
throw new PGPException("hash keyword expected"); | |||
} | |||
type = SXprUtils.readString(keyIn, keyIn.read()); | |||
if (!type.equals("sha1")) { | |||
throw new PGPException("hash keyword expected"); | |||
} | |||
byte[] hashBytes = SXprUtils.readBytes(keyIn, keyIn.read()); | |||
SXprUtils.skipCloseParenthesis(keyIn); | |||
if (digestProvider != null) { | |||
PGPDigestCalculator digestCalculator = digestProvider | |||
.get(HashAlgorithmTags.SHA1); | |||
OutputStream dOut = digestCalculator.getOutputStream(); | |||
dOut.write(Strings.toByteArray("(3:rsa")); | |||
writeCanonical(dOut, "n", n); | |||
writeCanonical(dOut, "e", e); | |||
writeCanonical(dOut, "d", d); | |||
writeCanonical(dOut, "p", p); | |||
writeCanonical(dOut, "q", q); | |||
writeCanonical(dOut, "u", u); | |||
// check protected-at | |||
if (protectedAt != null) { | |||
dOut.write(protectedAt); | |||
} | |||
dOut.write(Strings.toByteArray(")")); | |||
byte[] check = digestCalculator.getDigest(); | |||
if (!Arrays.constantTimeAreEqual(check, hashBytes)) { | |||
throw new PGPException( | |||
"checksum on protected data failed in SExpr"); | |||
} | |||
} | |||
return new BigInteger[] { d, p, q, u }; | |||
} | |||
private void writeCanonical(OutputStream dOut, String label, BigInteger i) | |||
throws IOException { | |||
writeCanonical(dOut, label, i.toByteArray()); | |||
} | |||
private void writeCanonical(OutputStream dOut, String label, byte[] data) | |||
throws IOException { | |||
dOut.write(Strings.toByteArray( | |||
"(" + label.length() + ":" + label + data.length + ":")); | |||
dOut.write(data); | |||
dOut.write(Strings.toByteArray(")")); | |||
} | |||
} |
@@ -0,0 +1,110 @@ | |||
/* | |||
* Copyright (c) 2000-2021 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org) | |||
* <p> | |||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software | |||
* and associated documentation files (the "Software"), to deal in the Software without restriction, | |||
*including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, | |||
* subject to the following conditions: | |||
* </p> | |||
* <p> | |||
* The above copyright notice and this permission notice shall be included in all copies or substantial | |||
* portions of the Software. | |||
* </p> | |||
* <p> | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | |||
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
* DEALINGS IN THE SOFTWARE. | |||
* </p> | |||
*/ | |||
package org.eclipse.jgit.gpg.bc.internal.keys; | |||
// This class is an unmodified copy from Bouncy Castle; needed because it's package-visible only and used by SExprParser. | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import org.bouncycastle.bcpg.HashAlgorithmTags; | |||
import org.bouncycastle.bcpg.S2K; | |||
import org.bouncycastle.util.io.Streams; | |||
/** | |||
* Utility functions for looking a S-expression keys. This class will move when | |||
* it finds a better home! | |||
* <p> | |||
* Format documented here: | |||
* http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=agent/keyformat.txt;h=42c4b1f06faf1bbe71ffadc2fee0fad6bec91a97;hb=refs/heads/master | |||
* </p> | |||
*/ | |||
class SXprUtils { | |||
private static int readLength(InputStream in, int ch) throws IOException { | |||
int len = ch - '0'; | |||
while ((ch = in.read()) >= 0 && ch != ':') { | |||
len = len * 10 + ch - '0'; | |||
} | |||
return len; | |||
} | |||
static String readString(InputStream in, int ch) throws IOException { | |||
int len = readLength(in, ch); | |||
char[] chars = new char[len]; | |||
for (int i = 0; i != chars.length; i++) { | |||
chars[i] = (char) in.read(); | |||
} | |||
return new String(chars); | |||
} | |||
static byte[] readBytes(InputStream in, int ch) throws IOException { | |||
int len = readLength(in, ch); | |||
byte[] data = new byte[len]; | |||
Streams.readFully(in, data); | |||
return data; | |||
} | |||
static S2K parseS2K(InputStream in) throws IOException { | |||
skipOpenParenthesis(in); | |||
// Algorithm is hard-coded to SHA1 below anyway. | |||
readString(in, in.read()); | |||
byte[] iv = readBytes(in, in.read()); | |||
final long iterationCount = Long.parseLong(readString(in, in.read())); | |||
skipCloseParenthesis(in); | |||
// we have to return the actual iteration count provided. | |||
S2K s2k = new S2K(HashAlgorithmTags.SHA1, iv, (int) iterationCount) { | |||
@Override | |||
public long getIterationCount() { | |||
return iterationCount; | |||
} | |||
}; | |||
return s2k; | |||
} | |||
static void skipOpenParenthesis(InputStream in) throws IOException { | |||
int ch = in.read(); | |||
if (ch != '(') { | |||
throw new IOException( | |||
"unknown character encountered: " + (char) ch); //$NON-NLS-1$ | |||
} | |||
} | |||
static void skipCloseParenthesis(InputStream in) throws IOException { | |||
int ch = in.read(); | |||
if (ch != ')') { | |||
throw new IOException("unknown character encountered"); //$NON-NLS-1$ | |||
} | |||
} | |||
} |
@@ -0,0 +1,597 @@ | |||
/* | |||
* Copyright (C) 2021 Thomas Wolf <thomas.wolf@paranor.ch> 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.gpg.bc.internal.keys; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.EOFException; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.StreamCorruptedException; | |||
import java.net.URISyntaxException; | |||
import java.nio.charset.StandardCharsets; | |||
import java.text.MessageFormat; | |||
import java.util.Arrays; | |||
import org.bouncycastle.openpgp.PGPException; | |||
import org.bouncycastle.openpgp.PGPPublicKey; | |||
import org.bouncycastle.openpgp.PGPSecretKey; | |||
import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory; | |||
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; | |||
import org.bouncycastle.openpgp.operator.jcajce.JcePBEProtectionRemoverFactory; | |||
import org.bouncycastle.util.io.Streams; | |||
import org.eclipse.jgit.api.errors.CanceledException; | |||
import org.eclipse.jgit.errors.UnsupportedCredentialItem; | |||
import org.eclipse.jgit.gpg.bc.internal.BCText; | |||
import org.eclipse.jgit.util.RawParseUtils; | |||
/** | |||
* Utilities for reading GPG secret keys from a gpg-agent key file. | |||
*/ | |||
public final class SecretKeys { | |||
private SecretKeys() { | |||
// No instantiation. | |||
} | |||
/** | |||
* Something that can supply a passphrase to decrypt an encrypted secret | |||
* key. | |||
*/ | |||
public interface PassphraseSupplier { | |||
/** | |||
* Supplies a passphrase. | |||
* | |||
* @return the passphrase | |||
* @throws PGPException | |||
* if no passphrase can be obtained | |||
* @throws CanceledException | |||
* if the user canceled passphrase entry | |||
* @throws UnsupportedCredentialItem | |||
* if an internal error occurred | |||
* @throws URISyntaxException | |||
* if an internal error occurred | |||
*/ | |||
char[] getPassphrase() throws PGPException, CanceledException, | |||
UnsupportedCredentialItem, URISyntaxException; | |||
} | |||
private static final byte[] PROTECTED_KEY = "protected-private-key" //$NON-NLS-1$ | |||
.getBytes(StandardCharsets.US_ASCII); | |||
private static final byte[] OCB_PROTECTED = "openpgp-s2k3-ocb-aes" //$NON-NLS-1$ | |||
.getBytes(StandardCharsets.US_ASCII); | |||
/** | |||
* Reads a GPG secret key from the given stream. | |||
* | |||
* @param in | |||
* {@link InputStream} to read from, doesn't need to be buffered | |||
* @param calculatorProvider | |||
* for checking digests | |||
* @param passphraseSupplier | |||
* for decrypting encrypted keys | |||
* @param publicKey | |||
* the secret key should be for | |||
* @return the secret key | |||
* @throws IOException | |||
* if the stream cannot be parsed | |||
* @throws PGPException | |||
* if thrown by the underlying S-Expression parser, for instance | |||
* when the passphrase is wrong | |||
* @throws CanceledException | |||
* if thrown by the {@code passphraseSupplier} | |||
* @throws UnsupportedCredentialItem | |||
* if thrown by the {@code passphraseSupplier} | |||
* @throws URISyntaxException | |||
* if thrown by the {@code passphraseSupplier} | |||
*/ | |||
public static PGPSecretKey readSecretKey(InputStream in, | |||
PGPDigestCalculatorProvider calculatorProvider, | |||
PassphraseSupplier passphraseSupplier, PGPPublicKey publicKey) | |||
throws IOException, PGPException, CanceledException, | |||
UnsupportedCredentialItem, URISyntaxException { | |||
byte[] data = Streams.readAll(in); | |||
if (data.length == 0) { | |||
throw new EOFException(); | |||
} else if (data.length < 4 + PROTECTED_KEY.length) { | |||
// +4 for "(21:" for a binary protected key | |||
throw new IOException( | |||
MessageFormat.format(BCText.get().secretKeyTooShort, | |||
Integer.toUnsignedString(data.length))); | |||
} | |||
SExprParser parser = new SExprParser(calculatorProvider); | |||
byte firstChar = data[0]; | |||
try { | |||
if (firstChar == '(') { | |||
// Binary format. | |||
PBEProtectionRemoverFactory decryptor = null; | |||
if (matches(data, 4, PROTECTED_KEY)) { | |||
// AES/CBC encrypted. | |||
decryptor = new JcePBEProtectionRemoverFactory( | |||
passphraseSupplier.getPassphrase(), | |||
calculatorProvider); | |||
} | |||
try (InputStream sIn = new ByteArrayInputStream(data)) { | |||
return parser.parseSecretKey(sIn, decryptor, publicKey); | |||
} | |||
} | |||
// Assume it's the new key-value format. | |||
try (ByteArrayInputStream keyIn = new ByteArrayInputStream(data)) { | |||
byte[] rawData = keyFromNameValueFormat(keyIn); | |||
if (!matches(rawData, 1, PROTECTED_KEY)) { | |||
// Not encrypted human-readable format. | |||
try (InputStream sIn = new ByteArrayInputStream( | |||
convertSexpression(rawData))) { | |||
return parser.parseSecretKey(sIn, null, publicKey); | |||
} | |||
} | |||
// An encrypted key from a key-value file. Most likely AES/OCB | |||
// encrypted. | |||
boolean isOCB[] = { false }; | |||
byte[] sExp = convertSexpression(rawData, isOCB); | |||
PBEProtectionRemoverFactory decryptor; | |||
if (isOCB[0]) { | |||
decryptor = new OCBPBEProtectionRemoverFactory( | |||
passphraseSupplier.getPassphrase(), | |||
calculatorProvider, getAad(sExp)); | |||
} else { | |||
decryptor = new JcePBEProtectionRemoverFactory( | |||
passphraseSupplier.getPassphrase(), | |||
calculatorProvider); | |||
} | |||
try (InputStream sIn = new ByteArrayInputStream(sExp)) { | |||
return parser.parseSecretKey(sIn, decryptor, publicKey); | |||
} | |||
} | |||
} catch (IOException e) { | |||
throw new PGPException(e.getLocalizedMessage(), e); | |||
} | |||
} | |||
/** | |||
* Extract the AAD for the OCB decryption from an s-expression. | |||
* | |||
* @param sExp | |||
* buffer containing a valid binary s-expression | |||
* @return the AAD | |||
*/ | |||
private static byte[] getAad(byte[] sExp) { | |||
// Given a key | |||
// @formatter:off | |||
// (protected-private-key (rsa ... (protected openpgp-s2k3-ocb-aes ... )(protected-at ...))) | |||
// A B C D | |||
// The AAD is [A..B)[C..D). (From the binary serialized form.) | |||
// @formatter:on | |||
int i = 1; // Skip initial '(' | |||
while (sExp[i] != '(') { | |||
i++; | |||
} | |||
int aadStart = i++; | |||
int aadEnd = skip(sExp, aadStart); | |||
byte[] protectedPrefix = "(9:protected" //$NON-NLS-1$ | |||
.getBytes(StandardCharsets.US_ASCII); | |||
while (!matches(sExp, i, protectedPrefix)) { | |||
i++; | |||
} | |||
int protectedStart = i; | |||
int protectedEnd = skip(sExp, protectedStart); | |||
byte[] aadData = new byte[aadEnd - aadStart | |||
- (protectedEnd - protectedStart)]; | |||
System.arraycopy(sExp, aadStart, aadData, 0, protectedStart - aadStart); | |||
System.arraycopy(sExp, protectedEnd, aadData, protectedStart - aadStart, | |||
aadEnd - protectedEnd); | |||
return aadData; | |||
} | |||
/** | |||
* Skips a list including nested lists. | |||
* | |||
* @param sExp | |||
* buffer containing valid binary s-expression data | |||
* @param start | |||
* index of the opening '(' of the list to skip | |||
* @return the index after the closing ')' of the skipped list | |||
*/ | |||
private static int skip(byte[] sExp, int start) { | |||
int i = start + 1; | |||
int depth = 1; | |||
while (depth > 0) { | |||
switch (sExp[i]) { | |||
case '(': | |||
depth++; | |||
break; | |||
case ')': | |||
depth--; | |||
break; | |||
default: | |||
// We must be on a length | |||
int j = i; | |||
while (sExp[j] >= '0' && sExp[j] <= '9') { | |||
j++; | |||
} | |||
// j is on the colon | |||
int length = Integer.parseInt( | |||
new String(sExp, i, j - i, StandardCharsets.US_ASCII)); | |||
i = j + length; | |||
} | |||
i++; | |||
} | |||
return i; | |||
} | |||
/** | |||
* Checks whether the {@code needle} matches {@code src} at offset | |||
* {@code from}. | |||
* | |||
* @param src | |||
* to match against {@code needle} | |||
* @param from | |||
* position in {@code src} to start matching | |||
* @param needle | |||
* to match against | |||
* @return {@code true} if {@code src} contains {@code needle} at position | |||
* {@code from}, {@code false} otherwise | |||
*/ | |||
private static boolean matches(byte[] src, int from, byte[] needle) { | |||
if (from < 0 || from + needle.length > src.length) { | |||
return false; | |||
} | |||
return org.bouncycastle.util.Arrays.constantTimeAreEqual(needle.length, | |||
src, from, needle, 0); | |||
} | |||
/** | |||
* Converts a human-readable serialized s-expression into a binary | |||
* serialized s-expression. | |||
* | |||
* @param humanForm | |||
* to convert | |||
* @return the converted s-expression | |||
* @throws IOException | |||
* if the conversion fails | |||
*/ | |||
private static byte[] convertSexpression(byte[] humanForm) | |||
throws IOException { | |||
boolean[] isOCB = { false }; | |||
return convertSexpression(humanForm, isOCB); | |||
} | |||
/** | |||
* Converts a human-readable serialized s-expression into a binary | |||
* serialized s-expression. | |||
* | |||
* @param humanForm | |||
* to convert | |||
* @param isOCB | |||
* returns whether the s-expression specified AES/OCB encryption | |||
* @return the converted s-expression | |||
* @throws IOException | |||
* if the conversion fails | |||
*/ | |||
private static byte[] convertSexpression(byte[] humanForm, boolean[] isOCB) | |||
throws IOException { | |||
int pos = 0; | |||
try (ByteArrayOutputStream out = new ByteArrayOutputStream( | |||
humanForm.length)) { | |||
while (pos < humanForm.length) { | |||
byte b = humanForm[pos]; | |||
if (b == '(' || b == ')') { | |||
out.write(b); | |||
pos++; | |||
} else if (isGpgSpace(b)) { | |||
pos++; | |||
} else if (b == '#') { | |||
// Hex value follows up to the next # | |||
int i = ++pos; | |||
while (i < humanForm.length && isHex(humanForm[i])) { | |||
i++; | |||
} | |||
if (i == pos || humanForm[i] != '#') { | |||
throw new StreamCorruptedException( | |||
BCText.get().sexprHexNotClosed); | |||
} | |||
if ((i - pos) % 2 != 0) { | |||
throw new StreamCorruptedException( | |||
BCText.get().sexprHexOdd); | |||
} | |||
int l = (i - pos) / 2; | |||
out.write(Integer.toString(l) | |||
.getBytes(StandardCharsets.US_ASCII)); | |||
out.write(':'); | |||
while (pos < i) { | |||
int x = (nibble(humanForm[pos]) << 4) | |||
| nibble(humanForm[pos + 1]); | |||
pos += 2; | |||
out.write(x); | |||
} | |||
pos = i + 1; | |||
} else if (isTokenChar(b)) { | |||
// Scan the token | |||
int start = pos++; | |||
while (pos < humanForm.length | |||
&& isTokenChar(humanForm[pos])) { | |||
pos++; | |||
} | |||
int l = pos - start; | |||
if (pos - start == OCB_PROTECTED.length | |||
&& matches(humanForm, start, OCB_PROTECTED)) { | |||
isOCB[0] = true; | |||
} | |||
out.write(Integer.toString(l) | |||
.getBytes(StandardCharsets.US_ASCII)); | |||
out.write(':'); | |||
out.write(humanForm, start, pos - start); | |||
} else if (b == '"') { | |||
// Potentially quoted string. | |||
int start = ++pos; | |||
boolean escaped = false; | |||
while (pos < humanForm.length | |||
&& (escaped || humanForm[pos] != '"')) { | |||
int ch = humanForm[pos++]; | |||
escaped = !escaped && ch == '\\'; | |||
} | |||
if (pos >= humanForm.length) { | |||
throw new StreamCorruptedException( | |||
BCText.get().sexprStringNotClosed); | |||
} | |||
// start is on the first character of the string, pos on the | |||
// closing quote. | |||
byte[] dq = dequote(humanForm, start, pos); | |||
out.write(Integer.toString(dq.length) | |||
.getBytes(StandardCharsets.US_ASCII)); | |||
out.write(':'); | |||
out.write(dq); | |||
pos++; | |||
} else { | |||
throw new StreamCorruptedException( | |||
MessageFormat.format(BCText.get().sexprUnhandled, | |||
Integer.toHexString(b & 0xFF))); | |||
} | |||
} | |||
return out.toByteArray(); | |||
} | |||
} | |||
/** | |||
* GPG-style string de-quoting, which is basically C-style, with some | |||
* literal CR/LF escaping. | |||
* | |||
* @param in | |||
* buffer containing the quoted string | |||
* @param from | |||
* index after the opening quote in {@code in} | |||
* @param to | |||
* index of the closing quote in {@code in} | |||
* @return the dequoted raw string value | |||
* @throws StreamCorruptedException | |||
*/ | |||
private static byte[] dequote(byte[] in, int from, int to) | |||
throws StreamCorruptedException { | |||
// Result must be shorter or have the same length | |||
byte[] out = new byte[to - from]; | |||
int j = 0; | |||
int i = from; | |||
while (i < to) { | |||
byte b = in[i++]; | |||
if (b != '\\') { | |||
out[j++] = b; | |||
continue; | |||
} | |||
if (i == to) { | |||
throw new StreamCorruptedException( | |||
BCText.get().sexprStringInvalidEscapeAtEnd); | |||
} | |||
b = in[i++]; | |||
switch (b) { | |||
case 'b': | |||
out[j++] = '\b'; | |||
break; | |||
case 'f': | |||
out[j++] = '\f'; | |||
break; | |||
case 'n': | |||
out[j++] = '\n'; | |||
break; | |||
case 'r': | |||
out[j++] = '\r'; | |||
break; | |||
case 't': | |||
out[j++] = '\t'; | |||
break; | |||
case 'v': | |||
out[j++] = 0x0B; | |||
break; | |||
case '"': | |||
case '\'': | |||
case '\\': | |||
out[j++] = b; | |||
break; | |||
case '\r': | |||
// Escaped literal line end. If an LF is following, skip that, | |||
// too. | |||
if (i < to && in[i] == '\n') { | |||
i++; | |||
} | |||
break; | |||
case '\n': | |||
// Same for LF possibly followed by CR. | |||
if (i < to && in[i] == '\r') { | |||
i++; | |||
} | |||
break; | |||
case 'x': | |||
if (i + 1 >= to || !isHex(in[i]) || !isHex(in[i + 1])) { | |||
throw new StreamCorruptedException( | |||
BCText.get().sexprStringInvalidHexEscape); | |||
} | |||
out[j++] = (byte) ((nibble(in[i]) << 4) | nibble(in[i + 1])); | |||
i += 2; | |||
break; | |||
case '0': | |||
case '1': | |||
case '2': | |||
case '3': | |||
if (i + 2 >= to || !isOctal(in[i]) || !isOctal(in[i + 1]) | |||
|| !isOctal(in[i + 2])) { | |||
throw new StreamCorruptedException( | |||
BCText.get().sexprStringInvalidOctalEscape); | |||
} | |||
out[j++] = (byte) (((((in[i] - '0') << 3) | |||
| (in[i + 1] - '0')) << 3) | (in[i + 2] - '0')); | |||
i += 3; | |||
break; | |||
default: | |||
throw new StreamCorruptedException(MessageFormat.format( | |||
BCText.get().sexprStringInvalidEscape, | |||
Integer.toHexString(b & 0xFF))); | |||
} | |||
} | |||
return Arrays.copyOf(out, j); | |||
} | |||
/** | |||
* Extracts the key from a GPG name-value-pair key file. | |||
* <p> | |||
* Package-visible for tests only. | |||
* </p> | |||
* | |||
* @param in | |||
* {@link InputStream} to read from; should be buffered | |||
* @return the raw key data as extracted from the file | |||
* @throws IOException | |||
* if the {@code in} stream cannot be read or does not contain a | |||
* key | |||
*/ | |||
static byte[] keyFromNameValueFormat(InputStream in) throws IOException { | |||
// It would be nice if we could use RawParseUtils here, but GPG compares | |||
// names case-insensitively. We're only interested in the "Key:" | |||
// name-value pair. | |||
int[] nameLow = { 'k', 'e', 'y', ':' }; | |||
int[] nameCap = { 'K', 'E', 'Y', ':' }; | |||
int nameIdx = 0; | |||
for (;;) { | |||
int next = in.read(); | |||
if (next < 0) { | |||
throw new EOFException(); | |||
} | |||
if (next == '\n') { | |||
nameIdx = 0; | |||
} else if (nameIdx >= 0) { | |||
if (nameLow[nameIdx] == next || nameCap[nameIdx] == next) { | |||
nameIdx++; | |||
if (nameIdx == nameLow.length) { | |||
break; | |||
} | |||
} else { | |||
nameIdx = -1; | |||
} | |||
} | |||
} | |||
// We're after "Key:". Read the value as continuation lines. | |||
int last = ':'; | |||
byte[] rawData; | |||
try (ByteArrayOutputStream out = new ByteArrayOutputStream(8192)) { | |||
for (;;) { | |||
int next = in.read(); | |||
if (next < 0) { | |||
break; | |||
} | |||
if (last == '\n') { | |||
if (next == ' ' || next == '\t') { | |||
// Continuation line; skip this whitespace | |||
last = next; | |||
continue; | |||
} | |||
break; // Not a continuation line | |||
} | |||
out.write(next); | |||
last = next; | |||
} | |||
rawData = out.toByteArray(); | |||
} | |||
// GPG trims off trailing whitespace, and a line having only whitespace | |||
// is a single LF. | |||
try (ByteArrayOutputStream out = new ByteArrayOutputStream( | |||
rawData.length)) { | |||
int lineStart = 0; | |||
boolean trimLeading = true; | |||
while (lineStart < rawData.length) { | |||
int nextLineStart = RawParseUtils.nextLF(rawData, lineStart); | |||
if (trimLeading) { | |||
while (lineStart < nextLineStart | |||
&& isGpgSpace(rawData[lineStart])) { | |||
lineStart++; | |||
} | |||
} | |||
// Trim trailing | |||
int i = nextLineStart - 1; | |||
while (lineStart < i && isGpgSpace(rawData[i])) { | |||
i--; | |||
} | |||
if (i <= lineStart) { | |||
// Empty line signifies LF | |||
out.write('\n'); | |||
trimLeading = true; | |||
} else { | |||
out.write(rawData, lineStart, i - lineStart + 1); | |||
trimLeading = false; | |||
} | |||
lineStart = nextLineStart; | |||
} | |||
return out.toByteArray(); | |||
} | |||
} | |||
private static boolean isGpgSpace(int ch) { | |||
return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'; | |||
} | |||
private static boolean isTokenChar(int ch) { | |||
switch (ch) { | |||
case '-': | |||
case '.': | |||
case '/': | |||
case '_': | |||
case ':': | |||
case '*': | |||
case '+': | |||
case '=': | |||
return true; | |||
default: | |||
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') | |||
|| (ch >= '0' && ch <= '9')) { | |||
return true; | |||
} | |||
return false; | |||
} | |||
} | |||
private static boolean isHex(int ch) { | |||
return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') | |||
|| (ch >= 'a' && ch <= 'f'); | |||
} | |||
private static boolean isOctal(int ch) { | |||
return (ch >= '0' && ch <= '7'); | |||
} | |||
private static int nibble(int ch) { | |||
if (ch >= '0' && ch <= '9') { | |||
return ch - '0'; | |||
} else if (ch >= 'A' && ch <= 'F') { | |||
return ch - 'A' + 10; | |||
} else if (ch >= 'a' && ch <= 'f') { | |||
return ch - 'a' + 10; | |||
} | |||
return -1; | |||
} | |||
} |
@@ -20,7 +20,7 @@ import javax.servlet.http.HttpServletRequest; | |||
import javax.servlet.http.HttpServletResponse; | |||
import org.eclipse.jgit.internal.storage.file.ObjectDirectory; | |||
import org.eclipse.jgit.internal.storage.file.PackFile; | |||
import org.eclipse.jgit.internal.storage.file.Pack; | |||
import org.eclipse.jgit.lib.ObjectDatabase; | |||
/** Sends the current list of pack files, sorted most recent first. */ | |||
@@ -38,7 +38,7 @@ class InfoPacksServlet extends HttpServlet { | |||
final StringBuilder out = new StringBuilder(); | |||
final ObjectDatabase db = getRepository(req).getObjectDatabase(); | |||
if (db instanceof ObjectDirectory) { | |||
for (PackFile pack : ((ObjectDirectory) db).getPacks()) { | |||
for (Pack pack : ((ObjectDirectory) db).getPacks()) { | |||
out.append("P "); | |||
out.append(pack.getPackFile().getName()); | |||
out.append('\n'); |
@@ -8,28 +8,31 @@ Bundle-Localization: plugin | |||
Bundle-Vendor: %Bundle-Vendor | |||
Bundle-ActivationPolicy: lazy | |||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | |||
Import-Package: org.apache.sshd.common;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.config.keys;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.file.virtualfs;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.helpers;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.io;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.kex;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.keyprovider;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.session;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.util.buffer;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.util.logging;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.util.security;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.util.threads;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.server;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.server.auth;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.server.auth.gss;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.server.auth.keyboard;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.server.auth.password;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.server.command;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.server.session;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.server.shell;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.server.subsystem;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.server.subsystem.sftp;version="[2.4.0,2.5.0)", | |||
Import-Package: org.apache.sshd.common;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.config.keys;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.file.virtualfs;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.helpers;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.io;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.kex;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.keyprovider;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.session;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.signature;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.util.buffer;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.util.logging;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.util.security;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.util.threads;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.core;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.server;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.server.auth;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.server.auth.gss;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.server.auth.keyboard;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.server.auth.password;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.server.command;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.server.session;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.server.shell;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.server.subsystem;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.sftp;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.sftp.server;version="[2.6.0,2.7.0)", | |||
org.eclipse.jgit.annotations;version="[5.11.0,5.12.0)", | |||
org.eclipse.jgit.api;version="[5.11.0,5.12.0)", | |||
org.eclipse.jgit.api.errors;version="[5.11.0,5.12.0)", |
@@ -9,6 +9,9 @@ | |||
*/ | |||
package org.eclipse.jgit.junit.ssh; | |||
import static org.apache.sshd.core.CoreModuleProperties.SERVER_EXTRA_IDENTIFICATION_LINES; | |||
import static org.apache.sshd.core.CoreModuleProperties.SERVER_EXTRA_IDENT_LINES_SEPARATOR; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
@@ -21,26 +24,28 @@ import java.security.KeyPair; | |||
import java.security.PublicKey; | |||
import java.text.MessageFormat; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import java.util.Locale; | |||
import java.util.concurrent.TimeUnit; | |||
import org.apache.sshd.common.NamedFactory; | |||
import org.apache.sshd.common.NamedResource; | |||
import org.apache.sshd.common.PropertyResolver; | |||
import org.apache.sshd.common.PropertyResolverUtils; | |||
import org.apache.sshd.common.SshConstants; | |||
import org.apache.sshd.common.config.keys.AuthorizedKeyEntry; | |||
import org.apache.sshd.common.config.keys.KeyUtils; | |||
import org.apache.sshd.common.config.keys.PublicKeyEntryResolver; | |||
import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory; | |||
import org.apache.sshd.common.session.Session; | |||
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.security.SecurityUtils; | |||
import org.apache.sshd.common.util.threads.CloseableExecutorService; | |||
import org.apache.sshd.common.util.threads.ThreadUtils; | |||
import org.apache.sshd.server.ServerAuthenticationManager; | |||
import org.apache.sshd.server.ServerFactoryManager; | |||
import org.apache.sshd.server.ServerBuilder; | |||
import org.apache.sshd.server.SshServer; | |||
import org.apache.sshd.server.auth.UserAuth; | |||
import org.apache.sshd.server.auth.UserAuthFactory; | |||
@@ -52,7 +57,7 @@ import org.apache.sshd.server.command.AbstractCommandSupport; | |||
import org.apache.sshd.server.session.ServerSession; | |||
import org.apache.sshd.server.shell.UnknownCommand; | |||
import org.apache.sshd.server.subsystem.SubsystemFactory; | |||
import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory; | |||
import org.apache.sshd.sftp.server.SftpSubsystemFactory; | |||
import org.eclipse.jgit.annotations.NonNull; | |||
import org.eclipse.jgit.annotations.Nullable; | |||
import org.eclipse.jgit.lib.Repository; | |||
@@ -162,7 +167,9 @@ public class SshTestGitServer { | |||
this.testUser = testUser; | |||
setTestUserPublicKey(testKey); | |||
this.repository = repository; | |||
server = SshServer.setUpDefaultServer(); | |||
ServerBuilder builder = ServerBuilder.builder() | |||
.signatureFactories(getSignatureFactories()); | |||
server = builder.build(); | |||
hostKeys.add(hostKey); | |||
server.setKeyPairProvider((session) -> hostKeys); | |||
@@ -187,6 +194,37 @@ public class SshTestGitServer { | |||
}); | |||
} | |||
/** | |||
* Apache MINA sshd 2.6.0 has removed DSA, DSA_CERT and RSA_CERT. We have to | |||
* set it up explicitly to still allow users to connect with DSA keys. | |||
* | |||
* @return a list of supported signature factories | |||
*/ | |||
@SuppressWarnings("deprecation") | |||
private static List<NamedFactory<Signature>> getSignatureFactories() { | |||
// @formatter:off | |||
return Arrays.asList( | |||
BuiltinSignatures.nistp256_cert, | |||
BuiltinSignatures.nistp384_cert, | |||
BuiltinSignatures.nistp521_cert, | |||
BuiltinSignatures.ed25519_cert, | |||
BuiltinSignatures.rsaSHA512_cert, | |||
BuiltinSignatures.rsaSHA256_cert, | |||
BuiltinSignatures.rsa_cert, | |||
BuiltinSignatures.nistp256, | |||
BuiltinSignatures.nistp384, | |||
BuiltinSignatures.nistp521, | |||
BuiltinSignatures.ed25519, | |||
BuiltinSignatures.sk_ecdsa_sha2_nistp256, | |||
BuiltinSignatures.sk_ssh_ed25519, | |||
BuiltinSignatures.rsaSHA512, | |||
BuiltinSignatures.rsaSHA256, | |||
BuiltinSignatures.rsa, | |||
BuiltinSignatures.dsa_cert, | |||
BuiltinSignatures.dsa); | |||
// @formatter:on | |||
} | |||
private static PublicKey readPublicKey(Path key) | |||
throws IOException, GeneralSecurityException { | |||
return AuthorizedKeyEntry.readAuthorizedKeys(key).get(0) | |||
@@ -278,14 +316,8 @@ public class SshTestGitServer { | |||
@NonNull | |||
protected List<SubsystemFactory> configureSubsystems() { | |||
// SFTP. | |||
server.setFileSystemFactory(new VirtualFileSystemFactory() { | |||
@Override | |||
protected Path computeRootDir(Session session) throws IOException { | |||
return SshTestGitServer.this.repository.getDirectory() | |||
.getParentFile().getAbsoluteFile().toPath(); | |||
} | |||
}); | |||
server.setFileSystemFactory(new VirtualFileSystemFactory(repository | |||
.getDirectory().getParentFile().getAbsoluteFile().toPath())); | |||
return Collections | |||
.singletonList((new SftpSubsystemFactory.Builder()).build()); | |||
} | |||
@@ -434,9 +466,8 @@ public class SshTestGitServer { | |||
*/ | |||
public void setPreamble(String... lines) { | |||
if (lines != null && lines.length > 0) { | |||
PropertyResolverUtils.updateProperty(this.server, | |||
ServerFactoryManager.SERVER_EXTRA_IDENTIFICATION_LINES, | |||
String.join("|", lines)); | |||
SERVER_EXTRA_IDENTIFICATION_LINES.set(server, String.join( | |||
String.valueOf(SERVER_EXTRA_IDENT_LINES_SEPARATOR), lines)); | |||
} | |||
} | |||
@@ -9,10 +9,10 @@ | |||
*/ | |||
package org.eclipse.jgit.junit; | |||
import static java.lang.ClassLoader.getSystemClassLoader; | |||
import java.net.MalformedURLException; | |||
import java.net.URL; | |||
import java.net.URLClassLoader; | |||
import java.nio.file.Paths; | |||
import org.junit.runners.BlockJUnit4ClassRunner; | |||
import org.junit.runners.model.InitializationError; | |||
@@ -40,7 +40,13 @@ public class SeparateClassloaderTestRunner extends BlockJUnit4ClassRunner { | |||
private static Class<?> loadNewClass(Class<?> klass) | |||
throws InitializationError { | |||
try { | |||
URL[] urls = ((URLClassLoader) getSystemClassLoader()).getURLs(); | |||
String pathSeparator = System.getProperty("path.separator"); | |||
String[] classPathEntries = System.getProperty("java.class.path") | |||
.split(pathSeparator); | |||
URL[] urls = new URL[classPathEntries.length]; | |||
for (int i = 0; i < classPathEntries.length; i++) { | |||
urls[i] = Paths.get(classPathEntries[i]).toUri().toURL(); | |||
} | |||
ClassLoader testClassLoader = new URLClassLoader(urls) { | |||
@Override | |||
@@ -54,7 +60,7 @@ public class SeparateClassloaderTestRunner extends BlockJUnit4ClassRunner { | |||
} | |||
}; | |||
return Class.forName(klass.getName(), true, testClassLoader); | |||
} catch (ClassNotFoundException e) { | |||
} catch (ClassNotFoundException | MalformedURLException e) { | |||
throw new InitializationError(e); | |||
} | |||
} |
@@ -43,7 +43,7 @@ import org.eclipse.jgit.errors.ObjectWritingException; | |||
import org.eclipse.jgit.internal.storage.file.FileRepository; | |||
import org.eclipse.jgit.internal.storage.file.LockFile; | |||
import org.eclipse.jgit.internal.storage.file.ObjectDirectory; | |||
import org.eclipse.jgit.internal.storage.file.PackFile; | |||
import org.eclipse.jgit.internal.storage.file.Pack; | |||
import org.eclipse.jgit.internal.storage.file.PackIndex.MutableEntry; | |||
import org.eclipse.jgit.internal.storage.pack.PackWriter; | |||
import org.eclipse.jgit.lib.AnyObjectId; | |||
@@ -773,7 +773,7 @@ public class TestRepository<R extends Repository> implements AutoCloseable { | |||
rw.writeInfoRefs(); | |||
final StringBuilder w = new StringBuilder(); | |||
for (PackFile p : fr.getObjectDatabase().getPacks()) { | |||
for (Pack p : fr.getObjectDatabase().getPacks()) { | |||
w.append("P "); | |||
w.append(p.getPackFile().getName()); | |||
w.append('\n'); | |||
@@ -954,7 +954,7 @@ public class TestRepository<R extends Repository> implements AutoCloseable { | |||
} | |||
private static void prunePacked(ObjectDirectory odb) throws IOException { | |||
for (PackFile p : odb.getPacks()) { | |||
for (Pack p : odb.getPacks()) { | |||
for (MutableEntry e : p) | |||
FileUtils.delete(odb.fileFor(e.toObjectId())); | |||
} |
@@ -241,6 +241,7 @@ public class LFSPointerTest { | |||
} | |||
@Test | |||
@SuppressWarnings("SelfComparison") | |||
public void testCompareToSame() throws Exception { | |||
AnyLongObjectId id = LongObjectId.fromString(TEST_SHA256); | |||
LfsPointer lfs = new LfsPointer(id, 4); |
@@ -1,28 +1,28 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<?pde?> | |||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | |||
<target name="jgit-4.10" sequenceNumber="1610487371"> | |||
<target name="jgit-4.10" sequenceNumber="1613861945"> | |||
<locations> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/> | |||
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/> | |||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> | |||
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/> | |||
@@ -49,16 +49,16 @@ | |||
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/> | |||
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.assertj" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/> | |||
@@ -86,7 +86,7 @@ | |||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | |||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | |||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.osgi" version="0.0.0"/> |
@@ -1,7 +1,7 @@ | |||
target "jgit-4.10" with source configurePhase | |||
include "projects/jetty-9.4.x.tpd" | |||
include "orbit/S20210105214148.tpd" | |||
include "orbit/S20210216215844.tpd" | |||
location "https://download.eclipse.org/releases/2018-12/" { | |||
org.eclipse.osgi lazy |
@@ -1,28 +1,28 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<?pde?> | |||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | |||
<target name="jgit-4.11" sequenceNumber="1610487371"> | |||
<target name="jgit-4.11" sequenceNumber="1613862033"> | |||
<locations> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/> | |||
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/> | |||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> | |||
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/> | |||
@@ -49,16 +49,16 @@ | |||
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/> | |||
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.assertj" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/> | |||
@@ -86,7 +86,7 @@ | |||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | |||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | |||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.osgi" version="0.0.0"/> |
@@ -1,7 +1,7 @@ | |||
target "jgit-4.11" with source configurePhase | |||
include "projects/jetty-9.4.x.tpd" | |||
include "orbit/S20210105214148.tpd" | |||
include "orbit/S20210216215844.tpd" | |||
location "https://download.eclipse.org/releases/2019-03/" { | |||
org.eclipse.osgi lazy |
@@ -1,28 +1,28 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<?pde?> | |||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | |||
<target name="jgit-4.12" sequenceNumber="1610487371"> | |||
<target name="jgit-4.12" sequenceNumber="1613862033"> | |||
<locations> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/> | |||
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/> | |||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> | |||
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/> | |||
@@ -49,16 +49,16 @@ | |||
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/> | |||
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.assertj" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/> | |||
@@ -86,7 +86,7 @@ | |||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | |||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | |||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.osgi" version="0.0.0"/> |
@@ -1,7 +1,7 @@ | |||
target "jgit-4.12" with source configurePhase | |||
include "projects/jetty-9.4.x.tpd" | |||
include "orbit/S20210105214148.tpd" | |||
include "orbit/S20210216215844.tpd" | |||
location "https://download.eclipse.org/releases/2019-06/" { | |||
org.eclipse.osgi lazy |
@@ -1,28 +1,28 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<?pde?> | |||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | |||
<target name="jgit-4.13" sequenceNumber="1610487371"> | |||
<target name="jgit-4.13" sequenceNumber="1613862034"> | |||
<locations> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/> | |||
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/> | |||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> | |||
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/> | |||
@@ -49,16 +49,16 @@ | |||
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/> | |||
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.assertj" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/> | |||
@@ -86,7 +86,7 @@ | |||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | |||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | |||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.osgi" version="0.0.0"/> |
@@ -1,7 +1,7 @@ | |||
target "jgit-4.13" with source configurePhase | |||
include "projects/jetty-9.4.x.tpd" | |||
include "orbit/S20210105214148.tpd" | |||
include "orbit/S20210216215844.tpd" | |||
location "https://download.eclipse.org/releases/2019-09/" { | |||
org.eclipse.osgi lazy |
@@ -1,28 +1,28 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<?pde?> | |||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | |||
<target name="jgit-4.14" sequenceNumber="1610487371"> | |||
<target name="jgit-4.14" sequenceNumber="1613862030"> | |||
<locations> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/> | |||
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/> | |||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> | |||
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/> | |||
@@ -49,16 +49,16 @@ | |||
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/> | |||
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.assertj" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/> | |||
@@ -86,7 +86,7 @@ | |||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | |||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | |||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.osgi" version="0.0.0"/> |
@@ -1,7 +1,7 @@ | |||
target "jgit-4.14" with source configurePhase | |||
include "projects/jetty-9.4.x.tpd" | |||
include "orbit/S20210105214148.tpd" | |||
include "orbit/S20210216215844.tpd" | |||
location "https://download.eclipse.org/releases/2019-12/201912181000/" { | |||
org.eclipse.osgi lazy |
@@ -1,28 +1,28 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<?pde?> | |||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | |||
<target name="jgit-4.15" sequenceNumber="1610487371"> | |||
<target name="jgit-4.15" sequenceNumber="1613862030"> | |||
<locations> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/> | |||
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/> | |||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> | |||
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/> | |||
@@ -49,16 +49,16 @@ | |||
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/> | |||
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.assertj" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/> | |||
@@ -86,7 +86,7 @@ | |||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | |||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | |||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.osgi" version="0.0.0"/> |
@@ -1,7 +1,7 @@ | |||
target "jgit-4.15" with source configurePhase | |||
include "projects/jetty-9.4.x.tpd" | |||
include "orbit/S20210105214148.tpd" | |||
include "orbit/S20210216215844.tpd" | |||
location "https://download.eclipse.org/releases/2020-03/202003181000/" { | |||
org.eclipse.osgi lazy |
@@ -1,28 +1,28 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<?pde?> | |||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | |||
<target name="jgit-4.16" sequenceNumber="1610487371"> | |||
<target name="jgit-4.16" sequenceNumber="1613862033"> | |||
<locations> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/> | |||
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/> | |||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> | |||
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/> | |||
@@ -49,16 +49,16 @@ | |||
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/> | |||
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.assertj" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/> | |||
@@ -86,7 +86,7 @@ | |||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | |||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | |||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.osgi" version="0.0.0"/> |
@@ -1,7 +1,7 @@ | |||
target "jgit-4.16" with source configurePhase | |||
include "projects/jetty-9.4.x.tpd" | |||
include "orbit/S20210105214148.tpd" | |||
include "orbit/S20210216215844.tpd" | |||
location "https://download.eclipse.org/releases/2020-06/" { | |||
org.eclipse.osgi lazy |
@@ -1,28 +1,28 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<?pde?> | |||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | |||
<target name="jgit-4.17" sequenceNumber="1610487371"> | |||
<target name="jgit-4.17" sequenceNumber="1613862034"> | |||
<locations> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/> | |||
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/> | |||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> | |||
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/> | |||
@@ -49,16 +49,16 @@ | |||
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/> | |||
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.assertj" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/> | |||
@@ -86,7 +86,7 @@ | |||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | |||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | |||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.osgi" version="0.0.0"/> |
@@ -1,7 +1,7 @@ | |||
target "jgit-4.17" with source configurePhase | |||
include "projects/jetty-9.4.x.tpd" | |||
include "orbit/S20210105214148.tpd" | |||
include "orbit/S20210216215844.tpd" | |||
location "https://download.eclipse.org/releases/2020-09/" { | |||
org.eclipse.osgi lazy |
@@ -1,28 +1,28 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<?pde?> | |||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | |||
<target name="jgit-4.18" sequenceNumber="1610487371"> | |||
<target name="jgit-4.18" sequenceNumber="1613862034"> | |||
<locations> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/> | |||
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/> | |||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> | |||
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/> | |||
@@ -49,16 +49,16 @@ | |||
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/> | |||
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.assertj" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/> | |||
@@ -86,7 +86,7 @@ | |||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | |||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | |||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.osgi" version="0.0.0"/> |
@@ -1,7 +1,7 @@ | |||
target "jgit-4.18" with source configurePhase | |||
include "projects/jetty-9.4.x.tpd" | |||
include "orbit/S20210105214148.tpd" | |||
include "orbit/S20210216215844.tpd" | |||
location "https://download.eclipse.org/releases/2020-12/" { | |||
org.eclipse.osgi lazy |
@@ -1,28 +1,28 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<?pde?> | |||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | |||
<target name="jgit-4.19-staging" sequenceNumber="1610487085"> | |||
<target name="jgit-4.19-staging" sequenceNumber="1613862034"> | |||
<locations> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/> | |||
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/> | |||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> | |||
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/> | |||
@@ -49,16 +49,16 @@ | |||
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/> | |||
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.assertj" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/> | |||
@@ -86,7 +86,7 @@ | |||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | |||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | |||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.osgi" version="0.0.0"/> |
@@ -1,7 +1,7 @@ | |||
target "jgit-4.19-staging" with source configurePhase | |||
include "projects/jetty-9.4.x.tpd" | |||
include "orbit/S20210105214148.tpd" | |||
include "orbit/S20210216215844.tpd" | |||
location "https://download.eclipse.org/staging/2021-03/" { | |||
org.eclipse.osgi lazy |
@@ -1,28 +1,28 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<?pde?> | |||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | |||
<target name="jgit-4.6" sequenceNumber="1610487371"> | |||
<target name="jgit-4.6" sequenceNumber="1613862049"> | |||
<locations> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/> | |||
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/> | |||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> | |||
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/> | |||
@@ -49,16 +49,16 @@ | |||
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/> | |||
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.assertj" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/> | |||
@@ -86,7 +86,7 @@ | |||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | |||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | |||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.osgi" version="0.0.0"/> |
@@ -1,7 +1,7 @@ | |||
target "jgit-4.6" with source configurePhase | |||
include "projects/jetty-9.4.x.tpd" | |||
include "orbit/S20210105214148.tpd" | |||
include "orbit/S20210216215844.tpd" | |||
location "https://download.eclipse.org/releases/neon/" { | |||
org.eclipse.osgi lazy |
@@ -1,28 +1,28 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<?pde?> | |||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | |||
<target name="jgit-4.7" sequenceNumber="1610487371"> | |||
<target name="jgit-4.7" sequenceNumber="1613862039"> | |||
<locations> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/> | |||
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/> | |||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> | |||
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/> | |||
@@ -49,16 +49,16 @@ | |||
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/> | |||
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.assertj" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/> | |||
@@ -86,7 +86,7 @@ | |||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | |||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | |||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.osgi" version="0.0.0"/> |
@@ -1,7 +1,7 @@ | |||
target "jgit-4.7" with source configurePhase | |||
include "projects/jetty-9.4.x.tpd" | |||
include "orbit/S20210105214148.tpd" | |||
include "orbit/S20210216215844.tpd" | |||
location "https://download.eclipse.org/releases/oxygen/" { | |||
org.eclipse.osgi lazy |
@@ -1,28 +1,28 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<?pde?> | |||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | |||
<target name="jgit-4.8" sequenceNumber="1610487371"> | |||
<target name="jgit-4.8" sequenceNumber="1613862034"> | |||
<locations> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/> | |||
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/> | |||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> | |||
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/> | |||
@@ -49,16 +49,16 @@ | |||
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/> | |||
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.assertj" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/> | |||
@@ -86,7 +86,7 @@ | |||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | |||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | |||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.osgi" version="0.0.0"/> |
@@ -1,7 +1,7 @@ | |||
target "jgit-4.8" with source configurePhase | |||
include "projects/jetty-9.4.x.tpd" | |||
include "orbit/S20210105214148.tpd" | |||
include "orbit/S20210216215844.tpd" | |||
location "https://download.eclipse.org/releases/photon/" { | |||
org.eclipse.osgi lazy |
@@ -1,28 +1,28 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<?pde?> | |||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | |||
<target name="jgit-4.9" sequenceNumber="1610487371"> | |||
<target name="jgit-4.9" sequenceNumber="1613862033"> | |||
<locations> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/> | |||
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/> | |||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> | |||
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> | |||
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/> | |||
@@ -49,16 +49,16 @@ | |||
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/> | |||
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/> | |||
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/> | |||
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> | |||
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/> | |||
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/> | |||
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/> | |||
<unit id="org.assertj" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/> | |||
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/> | |||
@@ -86,7 +86,7 @@ | |||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | |||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | |||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/> | |||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||
</location> | |||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | |||
<unit id="org.eclipse.osgi" version="0.0.0"/> |
@@ -1,7 +1,7 @@ | |||
target "jgit-4.9" with source configurePhase | |||
include "projects/jetty-9.4.x.tpd" | |||
include "orbit/S20210105214148.tpd" | |||
include "orbit/S20210216215844.tpd" | |||
location "https://download.eclipse.org/releases/2018-09/" { | |||
org.eclipse.osgi lazy |
@@ -1,7 +1,7 @@ | |||
target "S20210105214148" with source configurePhase | |||
target "S20210216215844" with source configurePhase | |||
// see https://download.eclipse.org/tools/orbit/downloads/ | |||
location "https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository" { | |||
location "https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository" { | |||
com.google.gson [2.8.6.v20201231-1626,2.8.6.v20201231-1626] | |||
com.google.gson.source [2.8.6.v20201231-1626,2.8.6.v20201231-1626] | |||
com.jcraft.jsch [0.1.55.v20190404-1902,0.1.55.v20190404-1902] | |||
@@ -26,16 +26,16 @@ location "https://download.eclipse.org/tools/orbit/downloads/drops/S202101052141 | |||
org.apache.commons.compress.source [1.19.0.v20200106-2343,1.19.0.v20200106-2343] | |||
org.apache.commons.logging [1.2.0.v20180409-1502,1.2.0.v20180409-1502] | |||
org.apache.commons.logging.source [1.2.0.v20180409-1502,1.2.0.v20180409-1502] | |||
org.apache.httpcomponents.httpclient [4.5.10.v20200830-2311,4.5.10.v20200830-2311] | |||
org.apache.httpcomponents.httpclient.source [4.5.10.v20200830-2311,4.5.10.v20200830-2311] | |||
org.apache.httpcomponents.httpcore [4.4.12.v20200108-1212,4.4.12.v20200108-1212] | |||
org.apache.httpcomponents.httpcore.source [4.4.12.v20200108-1212,4.4.12.v20200108-1212] | |||
org.apache.httpcomponents.httpclient [4.5.13.v20210128-2225,4.5.13.v20210128-2225] | |||
org.apache.httpcomponents.httpclient.source [4.5.13.v20210128-2225,4.5.13.v20210128-2225] | |||
org.apache.httpcomponents.httpcore [4.4.14.v20210128-2225,4.4.14.v20210128-2225] | |||
org.apache.httpcomponents.httpcore.source [4.4.14.v20210128-2225,4.4.14.v20210128-2225] | |||
org.apache.log4j [1.2.15.v201012070815,1.2.15.v201012070815] | |||
org.apache.log4j.source [1.2.15.v201012070815,1.2.15.v201012070815] | |||
org.apache.sshd.osgi [2.4.0.v20200318-1614,2.4.0.v20200318-1614] | |||
org.apache.sshd.osgi.source [2.4.0.v20200318-1614,2.4.0.v20200318-1614] | |||
org.apache.sshd.sftp [2.4.0.v20200319-1547,2.4.0.v20200319-1547] | |||
org.apache.sshd.sftp.source [2.4.0.v20200319-1547,2.4.0.v20200319-1547] | |||
org.apache.sshd.osgi [2.6.0.v20210201-2003,2.6.0.v20210201-2003] | |||
org.apache.sshd.osgi.source [2.6.0.v20210201-2003,2.6.0.v20210201-2003] | |||
org.apache.sshd.sftp [2.6.0.v20210201-2003,2.6.0.v20210201-2003] | |||
org.apache.sshd.sftp.source [2.6.0.v20210201-2003,2.6.0.v20210201-2003] | |||
org.assertj [3.14.0.v20200120-1926,3.14.0.v20200120-1926] | |||
org.assertj.source [3.14.0.v20200120-1926,3.14.0.v20200120-1926] | |||
org.bouncycastle.bcpg [1.65.0.v20200527-1955,1.65.0.v20200527-1955] |
@@ -1,22 +1,22 @@ | |||
target "jetty-9.4.x" with source configurePhase | |||
location jetty-9.4.30 "https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/" { | |||
org.eclipse.jetty.client [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.client.source [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.continuation [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.continuation.source [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.http [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.http.source [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.io [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.io.source [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.security [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.security.source [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.server [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.server.source [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.servlet [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.servlet.source [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.util [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.util.source [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.util.ajax [9.4.35.v20201120,9.4.35.v20201120] | |||
org.eclipse.jetty.util.ajax.source [9.4.35.v20201120,9.4.35.v20201120] | |||
location jetty-9.4.36 "https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/" { | |||
org.eclipse.jetty.client [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.client.source [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.continuation [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.continuation.source [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.http [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.http.source [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.io [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.io.source [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.security [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.security.source [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.server [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.server.source [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.servlet [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.servlet.source [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.util [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.util.source [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.util.ajax [9.4.36.v20210114,9.4.36.v20210114] | |||
org.eclipse.jetty.util.ajax.source [9.4.36.v20210114,9.4.36.v20210114] | |||
} |
@@ -11,7 +11,9 @@ package org.eclipse.jgit.pgm; | |||
import static org.junit.Assert.assertArrayEquals; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertNotEquals; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertThrows; | |||
import static org.junit.Assert.assertTrue; | |||
import java.io.File; | |||
@@ -25,6 +27,7 @@ import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.ObjectId; | |||
import org.eclipse.jgit.lib.Ref; | |||
import org.eclipse.jgit.lib.RefUpdate; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.lib.StoredConfig; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.transport.RefSpec; | |||
@@ -64,6 +67,45 @@ public class CloneTest extends CLIRepositoryTestCase { | |||
assertEquals("expected 1 branch", 1, branches.size()); | |||
} | |||
@Test | |||
public void testCloneInitialBranch() throws Exception { | |||
createInitialCommit(); | |||
File gitDir = db.getDirectory(); | |||
String sourceURI = gitDir.toURI().toString(); | |||
File target = createTempDirectory("target"); | |||
String cmd = "git clone --branch master " + sourceURI + " " | |||
+ shellQuote(target.getPath()); | |||
String[] result = execute(cmd); | |||
assertArrayEquals(new String[] { | |||
"Cloning into '" + target.getPath() + "'...", "", "" }, result); | |||
Git git2 = Git.open(target); | |||
List<Ref> branches = git2.branchList().call(); | |||
assertEquals("expected 1 branch", 1, branches.size()); | |||
Repository db2 = git2.getRepository(); | |||
ObjectId head = db2.resolve("HEAD"); | |||
assertNotNull(head); | |||
assertNotEquals(ObjectId.zeroId(), head); | |||
ObjectId master = db2.resolve("master"); | |||
assertEquals(head, master); | |||
} | |||
@Test | |||
public void testCloneInitialBranchMissing() throws Exception { | |||
createInitialCommit(); | |||
File gitDir = db.getDirectory(); | |||
String sourceURI = gitDir.toURI().toString(); | |||
File target = createTempDirectory("target"); | |||
String cmd = "git clone --branch foo " + sourceURI + " " | |||
+ shellQuote(target.getPath()); | |||
Die e = assertThrows(Die.class, () -> execute(cmd)); | |||
assertEquals("Remote branch 'foo' not found in upstream origin", | |||
e.getMessage()); | |||
} | |||
private RevCommit createInitialCommit() throws Exception { | |||
JGitTestUtil.writeTrashFile(db, "hello.txt", "world"); | |||
git.add().addFilepattern("hello.txt").call(); |
@@ -11,11 +11,14 @@ | |||
package org.eclipse.jgit.pgm; | |||
import static org.junit.Assert.assertArrayEquals; | |||
import static org.junit.Assert.assertEquals; | |||
import java.io.File; | |||
import org.eclipse.jgit.internal.storage.file.FileRepository; | |||
import org.eclipse.jgit.lib.CLIRepositoryTestCase; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
@@ -54,4 +57,22 @@ public class InitTest extends CLIRepositoryTestCase { | |||
assertArrayEquals(expecteds, result); | |||
} | |||
@Test | |||
public void testInitDirectoryInitialBranch() throws Exception { | |||
File workDirectory = tempFolder.getRoot(); | |||
File gitDirectory = new File(workDirectory, Constants.DOT_GIT); | |||
String[] result = execute( | |||
"git init -b main '" + workDirectory.getCanonicalPath() + "'"); | |||
String[] expecteds = new String[] { | |||
"Initialized empty Git repository in " | |||
+ gitDirectory.getCanonicalPath(), | |||
"" }; | |||
assertArrayEquals(expecteds, result); | |||
try (Repository repo = new FileRepository(gitDirectory)) { | |||
assertEquals("refs/heads/main", repo.getFullBranch()); | |||
} | |||
} | |||
} |
@@ -77,14 +77,15 @@ invalidHttpProxyOnlyHttpSupported=Invalid http_proxy: {0}: Only http supported. | |||
invalidRecurseSubmodulesMode=Invalid recurse submodules mode: {0} | |||
invalidUntrackedFilesMode=Invalid untracked files mode ''{0}'' | |||
jgitVersion=jgit version {0} | |||
lineFormat={0} | |||
listeningOn=Listening on {0} | |||
lfsNoAccessKey=No accessKey in {0} | |||
lfsNoSecretKey=No secretKey in {0} | |||
lfsProtocolUrl=LFS protocol URL: {0} | |||
lfsStoreDirectory=LFS objects stored in: {0} | |||
lfsStoreUrl=LFS store URL: {0} | |||
lfsUnknownStoreType="Unknown LFS store type: {0}" | |||
lineFormat={0} | |||
listeningOn=Listening on {0} | |||
logNoSignatureVerifier="No signature verifier available" | |||
mergeConflict=CONFLICT(content): Merge conflict in {0} | |||
mergeCheckoutConflict=error: Your local changes to the following files would be overwritten by merge: | |||
mergeFailed=Automatic merge failed; fix conflicts and then commit the result | |||
@@ -411,6 +412,7 @@ usage_show=Display one commit | |||
usage_showRefNamesMatchingCommits=Show ref names matching commits | |||
usage_showPatch=display patch | |||
usage_showNotes=Add this ref to the list of note branches from which notes are displayed | |||
usage_showSignature=Verify signatures of signed commits in the log | |||
usage_showTimeInMilliseconds=Show mtime in milliseconds | |||
usage_squash=Squash commits as if a real merge happened, but do not make a commit or move the HEAD. | |||
usage_srcPrefix=show the source prefix instead of "a/" | |||
@@ -424,11 +426,13 @@ usage_tagLocalUser=create a signed annotated tag using the specified GPG key ID | |||
usage_tagMessage=create an annotated tag with the given message, unsigned unless -s or -u are given, or config tag.gpgSign is true, or tar.forceSignAnnotated is true and -a is not given | |||
usage_tagSign=create a signed annotated tag | |||
usage_tagNoSign=suppress signing the tag | |||
usage_tagVerify=Verify the GPG signature | |||
usage_untrackedFilesMode=show untracked files | |||
usage_updateRef=reference to update | |||
usage_updateRemoteRefsFromAnotherRepository=Update remote refs from another repository | |||
usage_useNameInsteadOfOriginToTrackUpstream=use <name> instead of 'origin' to track upstream | |||
usage_checkoutBranchAfterClone=check out named branch instead of remote's HEAD | |||
usage_initialBranch=initial branch of the newly created repository (default 'master', can be configured via config option init.defaultBranch) | |||
usage_viewCommitHistory=View commit history | |||
usage_orphan=Create a new orphan branch. The first commit made on this new branch will have no parents and it will be the root of a new history totally disconnected from other branches and commits. | |||
usernameFor=Username for {0}: |
@@ -18,6 +18,7 @@ import java.util.Collection; | |||
import org.eclipse.jgit.api.CloneCommand; | |||
import org.eclipse.jgit.api.Git; | |||
import org.eclipse.jgit.api.errors.InvalidRemoteException; | |||
import org.eclipse.jgit.api.errors.TransportException; | |||
import org.eclipse.jgit.lib.AnyObjectId; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.TextProgressMonitor; | |||
@@ -110,6 +111,8 @@ class Clone extends AbstractFetchCommand implements CloneCommand.Callback { | |||
db = command.call().getRepository(); | |||
if (msgs && db.resolve(Constants.HEAD) == null) | |||
outw.println(CLIText.get().clonedEmptyRepository); | |||
} catch (TransportException e) { | |||
throw die(e.getMessage(), e); | |||
} catch (InvalidRemoteException e) { | |||
throw die(MessageFormat.format(CLIText.get().doesNotExist, | |||
sourceUri), e); |
@@ -24,6 +24,7 @@ import org.eclipse.jgit.api.InitCommand; | |||
import org.eclipse.jgit.api.errors.GitAPIException; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.pgm.internal.CLIText; | |||
import org.eclipse.jgit.util.StringUtils; | |||
import org.kohsuke.args4j.Argument; | |||
import org.kohsuke.args4j.Option; | |||
@@ -32,6 +33,10 @@ class Init extends TextBuiltin { | |||
@Option(name = "--bare", usage = "usage_CreateABareRepository") | |||
private boolean bare; | |||
@Option(name = "--initial-branch", aliases = { "-b" }, | |||
metaVar = "metaVar_branchName", usage = "usage_initialBranch") | |||
private String branch; | |||
@Argument(index = 0, metaVar = "metaVar_directory") | |||
private String directory; | |||
@@ -54,6 +59,9 @@ class Init extends TextBuiltin { | |||
} | |||
Repository repository; | |||
try { | |||
if (!StringUtils.isEmptyOrNull(branch)) { | |||
command.setInitialBranch(branch); | |||
} | |||
repository = command.call().getRepository(); | |||
outw.println(MessageFormat.format( | |||
CLIText.get().initializedEmptyGitRepositoryIn, |
@@ -1,7 +1,7 @@ | |||
/* | |||
* Copyright (C) 2010, Google Inc. | |||
* Copyright (C) 2006-2008, Robin Rosenberg <robin.rosenberg@dewire.com> | |||
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others | |||
* Copyright (C) 2006, 2008, Robin Rosenberg <robin.rosenberg@dewire.com> | |||
* Copyright (C) 2008, 2021, Shawn O. Pearce <spearce@spearce.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 | |||
@@ -31,12 +31,17 @@ import org.eclipse.jgit.diff.RenameDetector; | |||
import org.eclipse.jgit.errors.LargeObjectException; | |||
import org.eclipse.jgit.lib.AnyObjectId; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.GpgConfig; | |||
import org.eclipse.jgit.lib.GpgSignatureVerifier; | |||
import org.eclipse.jgit.lib.GpgSignatureVerifier.SignatureVerification; | |||
import org.eclipse.jgit.lib.GpgSignatureVerifierFactory; | |||
import org.eclipse.jgit.lib.ObjectId; | |||
import org.eclipse.jgit.lib.PersonIdent; | |||
import org.eclipse.jgit.lib.Ref; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.notes.NoteMap; | |||
import org.eclipse.jgit.pgm.internal.CLIText; | |||
import org.eclipse.jgit.pgm.internal.VerificationUtils; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.revwalk.RevTree; | |||
import org.eclipse.jgit.util.GitDateFormatter; | |||
@@ -68,6 +73,9 @@ class Log extends RevWalkTextBuiltin { | |||
additionalNoteRefs.add(notesRef); | |||
} | |||
@Option(name = "--show-signature", usage = "usage_showSignature") | |||
private boolean showSignature; | |||
@Option(name = "--date", usage = "usage_date") | |||
void dateFormat(String date) { | |||
if (date.toLowerCase(Locale.ROOT).equals(date)) | |||
@@ -147,6 +155,10 @@ class Log extends RevWalkTextBuiltin { | |||
// END -- Options shared with Diff | |||
private GpgSignatureVerifier verifier; | |||
private GpgConfig config; | |||
Log() { | |||
dateFormatter = new GitDateFormatter(Format.DEFAULT); | |||
} | |||
@@ -161,6 +173,7 @@ class Log extends RevWalkTextBuiltin { | |||
/** {@inheritDoc} */ | |||
@Override | |||
protected void run() { | |||
config = new GpgConfig(db.getConfig()); | |||
diffFmt.setRepository(db); | |||
try { | |||
diffFmt.setPathFilter(pathFilter); | |||
@@ -197,6 +210,9 @@ class Log extends RevWalkTextBuiltin { | |||
throw die(e.getMessage(), e); | |||
} finally { | |||
diffFmt.close(); | |||
if (verifier != null) { | |||
verifier.clear(); | |||
} | |||
} | |||
} | |||
@@ -229,6 +245,9 @@ class Log extends RevWalkTextBuiltin { | |||
} | |||
outw.println(); | |||
if (showSignature) { | |||
showSignature(c); | |||
} | |||
final PersonIdent author = c.getAuthorIdent(); | |||
outw.println(MessageFormat.format(CLIText.get().authorInfo, author.getName(), author.getEmailAddress())); | |||
outw.println(MessageFormat.format(CLIText.get().dateInfo, | |||
@@ -252,6 +271,27 @@ class Log extends RevWalkTextBuiltin { | |||
outw.flush(); | |||
} | |||
private void showSignature(RevCommit c) throws IOException { | |||
if (c.getRawGpgSignature() == null) { | |||
return; | |||
} | |||
if (verifier == null) { | |||
GpgSignatureVerifierFactory factory = GpgSignatureVerifierFactory | |||
.getDefault(); | |||
if (factory == null) { | |||
throw die(CLIText.get().logNoSignatureVerifier, null); | |||
} | |||
verifier = factory.getVerifier(); | |||
} | |||
SignatureVerification verification = verifier.verifySignature(c, | |||
config); | |||
if (verification == null) { | |||
return; | |||
} | |||
VerificationUtils.writeVerification(outw, verification, | |||
verifier.getName(), c.getCommitterIdent()); | |||
} | |||
/** | |||
* @param c | |||
* @return <code>true</code> if at least one note was printed, |
@@ -29,10 +29,15 @@ import org.eclipse.jgit.errors.MissingObjectException; | |||
import org.eclipse.jgit.errors.RevisionSyntaxException; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.FileMode; | |||
import org.eclipse.jgit.lib.GpgConfig; | |||
import org.eclipse.jgit.lib.GpgSignatureVerifier; | |||
import org.eclipse.jgit.lib.GpgSignatureVerifierFactory; | |||
import org.eclipse.jgit.lib.ObjectId; | |||
import org.eclipse.jgit.lib.PersonIdent; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.lib.GpgSignatureVerifier.SignatureVerification; | |||
import org.eclipse.jgit.pgm.internal.CLIText; | |||
import org.eclipse.jgit.pgm.internal.VerificationUtils; | |||
import org.eclipse.jgit.pgm.opt.PathTreeFilterHandler; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.revwalk.RevObject; | |||
@@ -59,6 +64,9 @@ class Show extends TextBuiltin { | |||
@Option(name = "--", metaVar = "metaVar_path", handler = PathTreeFilterHandler.class) | |||
protected TreeFilter pathFilter = TreeFilter.ALL; | |||
@Option(name = "--show-signature", usage = "usage_showSignature") | |||
private boolean showSignature; | |||
// BEGIN -- Options shared with Diff | |||
@Option(name = "-p", usage = "usage_showPatch") | |||
boolean showPatch; | |||
@@ -220,13 +228,16 @@ class Show extends TextBuiltin { | |||
} | |||
outw.println(); | |||
String[] lines = tag.getFullMessage().split("\n"); //$NON-NLS-1$ | |||
for (String s : lines) { | |||
outw.println(s); | |||
String fullMessage = tag.getFullMessage(); | |||
if (!fullMessage.isEmpty()) { | |||
String[] lines = tag.getFullMessage().split("\n"); //$NON-NLS-1$ | |||
for (String s : lines) { | |||
outw.println(s); | |||
} | |||
} | |||
byte[] rawSignature = tag.getRawGpgSignature(); | |||
if (rawSignature != null) { | |||
lines = RawParseUtils.decode(rawSignature).split("\n"); //$NON-NLS-1$ | |||
String[] lines = RawParseUtils.decode(rawSignature).split("\n"); //$NON-NLS-1$ | |||
for (String s : lines) { | |||
outw.println(s); | |||
} | |||
@@ -258,6 +269,10 @@ class Show extends TextBuiltin { | |||
c.getId().copyTo(outbuffer, outw); | |||
outw.println(); | |||
if (showSignature) { | |||
showSignature(c); | |||
} | |||
final PersonIdent author = c.getAuthorIdent(); | |||
outw.println(MessageFormat.format(CLIText.get().authorInfo, | |||
author.getName(), author.getEmailAddress())); | |||
@@ -296,4 +311,28 @@ class Show extends TextBuiltin { | |||
} | |||
outw.println(); | |||
} | |||
private void showSignature(RevCommit c) throws IOException { | |||
if (c.getRawGpgSignature() == null) { | |||
return; | |||
} | |||
GpgSignatureVerifierFactory factory = GpgSignatureVerifierFactory | |||
.getDefault(); | |||
if (factory == null) { | |||
throw die(CLIText.get().logNoSignatureVerifier, null); | |||
} | |||
GpgSignatureVerifier verifier = factory.getVerifier(); | |||
GpgConfig config = new GpgConfig(db.getConfig()); | |||
try { | |||
SignatureVerification verification = verifier.verifySignature(c, | |||
config); | |||
if (verification == null) { | |||
return; | |||
} | |||
VerificationUtils.writeVerification(outw, verification, | |||
verifier.getName(), c.getCommitterIdent()); | |||
} finally { | |||
verifier.clear(); | |||
} | |||
} | |||
} |
@@ -4,7 +4,7 @@ | |||
* Copyright (C) 2008, Charles O'Farrell <charleso@charleso.org> | |||
* Copyright (C) 2008, Robin Rosenberg <robin.rosenberg.lists@dewire.com> | |||
* Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com> | |||
* Copyright (C) 2008, 2020 Shawn O. Pearce <spearce@spearce.org> and others | |||
* Copyright (C) 2008, 2021 Shawn O. Pearce <spearce@spearce.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 | |||
@@ -22,43 +22,60 @@ import java.util.List; | |||
import org.eclipse.jgit.api.Git; | |||
import org.eclipse.jgit.api.ListTagCommand; | |||
import org.eclipse.jgit.api.TagCommand; | |||
import org.eclipse.jgit.api.VerificationResult; | |||
import org.eclipse.jgit.api.VerifySignatureCommand; | |||
import org.eclipse.jgit.api.errors.GitAPIException; | |||
import org.eclipse.jgit.api.errors.RefAlreadyExistsException; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.GpgSignatureVerifier.SignatureVerification; | |||
import org.eclipse.jgit.lib.ObjectId; | |||
import org.eclipse.jgit.lib.Ref; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.pgm.internal.CLIText; | |||
import org.eclipse.jgit.pgm.internal.VerificationUtils; | |||
import org.eclipse.jgit.revwalk.RevTag; | |||
import org.eclipse.jgit.revwalk.RevWalk; | |||
import org.kohsuke.args4j.Argument; | |||
import org.kohsuke.args4j.Option; | |||
@Command(common = true, usage = "usage_CreateATag") | |||
class Tag extends TextBuiltin { | |||
@Option(name = "-f", usage = "usage_forceReplacingAnExistingTag") | |||
@Option(name = "--force", aliases = { "-f" }, forbids = { "--delete", | |||
"--verify" }, usage = "usage_forceReplacingAnExistingTag") | |||
private boolean force; | |||
@Option(name = "-d", usage = "usage_tagDelete") | |||
@Option(name = "--delete", aliases = { "-d" }, forbids = { | |||
"--verify" }, usage = "usage_tagDelete") | |||
private boolean delete; | |||
@Option(name = "--annotate", aliases = { | |||
"-a" }, usage = "usage_tagAnnotated") | |||
"-a" }, forbids = { "--delete", | |||
"--verify" }, usage = "usage_tagAnnotated") | |||
private boolean annotated; | |||
@Option(name = "-m", metaVar = "metaVar_message", usage = "usage_tagMessage") | |||
@Option(name = "-m", forbids = { "--delete", | |||
"--verify" }, metaVar = "metaVar_message", usage = "usage_tagMessage") | |||
private String message; | |||
@Option(name = "--sign", aliases = { "-s" }, forbids = { | |||
"--no-sign" }, usage = "usage_tagSign") | |||
"--no-sign", "--delete", "--verify" }, usage = "usage_tagSign") | |||
private boolean sign; | |||
@Option(name = "--no-sign", usage = "usage_tagNoSign", forbids = { | |||
"--sign" }) | |||
"--sign", "--delete", "--verify" }) | |||
private boolean noSign; | |||
@Option(name = "--local-user", aliases = { | |||
"-u" }, metaVar = "metaVar_tagLocalUser", usage = "usage_tagLocalUser") | |||
"-u" }, forbids = { "--delete", | |||
"--verify" }, metaVar = "metaVar_tagLocalUser", usage = "usage_tagLocalUser") | |||
private String gpgKeyId; | |||
@Option(name = "--verify", aliases = { "-v" }, forbids = { "--delete", | |||
"--force", "--annotate", "-m", "--sign", "--no-sign", | |||
"--local-user" }, usage = "usage_tagVerify") | |||
private boolean verify; | |||
@Argument(index = 0, metaVar = "metaVar_name") | |||
private String tagName; | |||
@@ -70,7 +87,25 @@ class Tag extends TextBuiltin { | |||
protected void run() { | |||
try (Git git = new Git(db)) { | |||
if (tagName != null) { | |||
if (delete) { | |||
if (verify) { | |||
VerifySignatureCommand verifySig = git.verifySignature() | |||
.setMode(VerifySignatureCommand.VerifyMode.TAGS) | |||
.addName(tagName); | |||
VerificationResult verification = verifySig.call() | |||
.get(tagName); | |||
if (verification == null) { | |||
showUnsigned(git, tagName); | |||
} else { | |||
Throwable error = verification.getException(); | |||
if (error != null) { | |||
throw die(error.getMessage(), error); | |||
} | |||
writeVerification(verifySig.getVerifier().getName(), | |||
(RevTag) verification.getObject(), | |||
verification.getVerification()); | |||
} | |||
} else if (delete) { | |||
List<String> deletedTags = git.tagDelete().setTags(tagName) | |||
.call(); | |||
if (deletedTags.isEmpty()) { | |||
@@ -116,4 +151,36 @@ class Tag extends TextBuiltin { | |||
throw die(e.getMessage(), e); | |||
} | |||
} | |||
private void showUnsigned(Git git, String wantedTag) throws IOException { | |||
ObjectId id = git.getRepository().resolve(wantedTag); | |||
if (id != null && !ObjectId.zeroId().equals(id)) { | |||
try (RevWalk walk = new RevWalk(git.getRepository())) { | |||
showTag(walk.parseTag(id)); | |||
} | |||
} else { | |||
throw die( | |||
MessageFormat.format(CLIText.get().tagNotFound, wantedTag)); | |||
} | |||
} | |||
private void showTag(RevTag tag) throws IOException { | |||
outw.println("object " + tag.getObject().name()); //$NON-NLS-1$ | |||
outw.println("type " + Constants.typeString(tag.getObject().getType())); //$NON-NLS-1$ | |||
outw.println("tag " + tag.getTagName()); //$NON-NLS-1$ | |||
outw.println("tagger " + tag.getTaggerIdent().toExternalString()); //$NON-NLS-1$ | |||
outw.println(); | |||
outw.print(tag.getFullMessage()); | |||
} | |||
private void writeVerification(String name, RevTag tag, | |||
SignatureVerification verification) throws IOException { | |||
showTag(tag); | |||
if (verification == null) { | |||
outw.println(); | |||
return; | |||
} | |||
VerificationUtils.writeVerification(outw, verification, name, | |||
tag.getTaggerIdent()); | |||
} | |||
} |
@@ -1,6 +1,6 @@ | |||
/* | |||
* Copyright (C) 2010, 2013 Sasa Zivkov <sasa.zivkov@sap.com> | |||
* Copyright (C) 2013, Obeo and others | |||
* Copyright (C) 2013, 2021 Obeo 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 | |||
@@ -163,6 +163,7 @@ public class CLIText extends TranslationBundle { | |||
/***/ public String lfsUnknownStoreType; | |||
/***/ public String lineFormat; | |||
/***/ public String listeningOn; | |||
/***/ public String logNoSignatureVerifier; | |||
/***/ public String mergeCheckoutConflict; | |||
/***/ public String mergeConflict; | |||
/***/ public String mergeFailed; |
@@ -0,0 +1,56 @@ | |||
/* | |||
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> 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.pgm.internal; | |||
import java.io.IOException; | |||
import org.eclipse.jgit.lib.GpgSignatureVerifier.SignatureVerification; | |||
import org.eclipse.jgit.lib.PersonIdent; | |||
import org.eclipse.jgit.util.GitDateFormatter; | |||
import org.eclipse.jgit.util.SignatureUtils; | |||
import org.eclipse.jgit.util.io.ThrowingPrintWriter; | |||
/** | |||
* Utilities for signature verification. | |||
*/ | |||
public final class VerificationUtils { | |||
private VerificationUtils() { | |||
// No instantiation | |||
} | |||
/** | |||
* Writes information about a signature verification to the given writer. | |||
* | |||
* @param out | |||
* to write to | |||
* @param verification | |||
* to show | |||
* @param name | |||
* of the verifier used | |||
* @param creator | |||
* of the object verified; used for time zone information | |||
* @throws IOException | |||
* if writing fails | |||
*/ | |||
public static void writeVerification(ThrowingPrintWriter out, | |||
SignatureVerification verification, String name, | |||
PersonIdent creator) throws IOException { | |||
String[] text = SignatureUtils | |||
.toString(verification, creator, | |||
new GitDateFormatter(GitDateFormatter.Format.LOCALE)) | |||
.split("\n"); //$NON-NLS-1$ | |||
for (String line : text) { | |||
out.print(name); | |||
out.print(": "); //$NON-NLS-1$ | |||
out.println(line); | |||
} | |||
} | |||
} |
@@ -7,17 +7,18 @@ Bundle-Version: 5.11.0.qualifier | |||
Bundle-Vendor: %Bundle-Vendor | |||
Bundle-Localization: plugin | |||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | |||
Import-Package: org.apache.sshd.client.config.hosts;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.auth;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.config.keys;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.helpers;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.keyprovider;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.session;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.util.net;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.util.security;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.server;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.server.forward;version="[2.4.0,2.5.0)", | |||
Import-Package: org.apache.sshd.client.config.hosts;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.auth;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.config.keys;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.helpers;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.keyprovider;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.session;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.util.net;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.util.security;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.core;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.server;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.server.forward;version="[2.6.0,2.7.0)", | |||
org.eclipse.jgit.api;version="[5.11.0,5.12.0)", | |||
org.eclipse.jgit.api.errors;version="[5.11.0,5.12.0)", | |||
org.eclipse.jgit.internal.transport.sshd.proxy;version="[5.11.0,5.12.0)", |
@@ -9,6 +9,7 @@ | |||
*/ | |||
package org.eclipse.jgit.transport.sshd; | |||
import static org.apache.sshd.core.CoreModuleProperties.MAX_CONCURRENT_SESSIONS; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertFalse; | |||
import static org.junit.Assert.assertNotNull; | |||
@@ -33,7 +34,6 @@ import java.util.stream.Collectors; | |||
import org.apache.sshd.client.config.hosts.KnownHostEntry; | |||
import org.apache.sshd.client.config.hosts.KnownHostHashValue; | |||
import org.apache.sshd.common.PropertyResolverUtils; | |||
import org.apache.sshd.common.config.keys.AuthorizedKeyEntry; | |||
import org.apache.sshd.common.config.keys.KeyUtils; | |||
import org.apache.sshd.common.config.keys.PublicKeyEntry; | |||
@@ -41,7 +41,6 @@ import org.apache.sshd.common.config.keys.PublicKeyEntryResolver; | |||
import org.apache.sshd.common.session.Session; | |||
import org.apache.sshd.common.util.net.SshdSocketAddress; | |||
import org.apache.sshd.server.ServerAuthenticationManager; | |||
import org.apache.sshd.server.ServerFactoryManager; | |||
import org.apache.sshd.server.SshServer; | |||
import org.apache.sshd.server.forward.StaticDecisionForwardingFilter; | |||
import org.eclipse.jgit.api.Git; | |||
@@ -216,8 +215,8 @@ public class ApacheSshTest extends SshTestBase { | |||
*/ | |||
@Test | |||
public void testCloneAndFetchWithSessionLimit() throws Exception { | |||
PropertyResolverUtils.updateProperty(server.getPropertyResolver(), | |||
ServerFactoryManager.MAX_CONCURRENT_SESSIONS, 2); | |||
MAX_CONCURRENT_SESSIONS | |||
.set(server.getPropertyResolver(), Integer.valueOf(2)); | |||
File localClone = cloneWith("ssh://localhost/doesntmatter", | |||
defaultCloneDir, null, // | |||
"Host localhost", // |
@@ -33,49 +33,51 @@ Export-Package: org.eclipse.jgit.internal.transport.sshd;version="5.11.0";x-inte | |||
org.apache.sshd.client.session, | |||
org.apache.sshd.client.keyverifier" | |||
Import-Package: net.i2p.crypto.eddsa;version="[0.3.0,0.4.0)", | |||
org.apache.sshd.agent;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.client;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.client.auth;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.client.auth.keyboard;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.client.auth.password;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.client.auth.pubkey;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.client.channel;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.client.config.hosts;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.client.config.keys;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.client.future;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.client.keyverifier;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.client.session;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.client.session.forward;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.client.subsystem.sftp;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.auth;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.channel;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.compression;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.config.keys;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.config.keys.loader;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.config.keys.loader.openssh.kdf;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.digest;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.forward;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.future;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.helpers;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.io;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.kex;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.keyprovider;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.mac;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.random;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.session;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.session.helpers;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.signature;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.subsystem.sftp;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.util;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.util.buffer;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.util.closeable;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.util.io;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.util.io.resource;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.util.logging;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.util.net;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.common.util.security;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.server.auth;version="[2.4.0,2.5.0)", | |||
org.apache.sshd.agent;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.client;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.client.auth;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.client.auth.keyboard;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.client.auth.password;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.client.auth.pubkey;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.client.channel;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.client.config.hosts;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.client.config.keys;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.client.future;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.client.keyverifier;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.client.session;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.client.session.forward;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.auth;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.channel;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.compression;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.config.keys;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.config.keys.loader;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.config.keys.loader.openssh.kdf;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.digest;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.forward;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.future;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.helpers;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.io;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.kex;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.keyprovider;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.mac;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.random;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.session;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.session.helpers;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.signature;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.util;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.util.buffer;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.util.closeable;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.util.io;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.util.io.resource;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.util.logging;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.util.net;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.common.util.security;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.core;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.server.auth;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.sftp;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.sftp.client;version="[2.6.0,2.7.0)", | |||
org.apache.sshd.sftp.common;version="[2.6.0,2.7.0)", | |||
org.eclipse.jgit.annotations;version="[5.11.0,5.12.0)", | |||
org.eclipse.jgit.errors;version="[5.11.0,5.12.0)", | |||
org.eclipse.jgit.fnmatch;version="[5.11.0,5.12.0)", |
@@ -10,6 +10,7 @@ | |||
package org.eclipse.jgit.internal.transport.sshd; | |||
import static java.text.MessageFormat.format; | |||
import static org.apache.sshd.core.CoreModuleProperties.MAX_IDENTIFICATION_SIZE; | |||
import java.io.IOException; | |||
import java.io.StreamCorruptedException; | |||
@@ -29,19 +30,14 @@ import java.util.Set; | |||
import org.apache.sshd.client.ClientFactoryManager; | |||
import org.apache.sshd.client.config.hosts.HostConfigEntry; | |||
import org.apache.sshd.client.future.AuthFuture; | |||
import org.apache.sshd.client.keyverifier.ServerKeyVerifier; | |||
import org.apache.sshd.client.session.ClientSessionImpl; | |||
import org.apache.sshd.client.session.ClientUserAuthService; | |||
import org.apache.sshd.common.AttributeRepository; | |||
import org.apache.sshd.common.FactoryManager; | |||
import org.apache.sshd.common.PropertyResolver; | |||
import org.apache.sshd.common.PropertyResolverUtils; | |||
import org.apache.sshd.common.SshException; | |||
import org.apache.sshd.common.config.keys.KeyUtils; | |||
import org.apache.sshd.common.io.IoSession; | |||
import org.apache.sshd.common.io.IoWriteFuture; | |||
import org.apache.sshd.common.kex.KexState; | |||
import org.apache.sshd.common.util.Readable; | |||
import org.apache.sshd.common.util.buffer.Buffer; | |||
import org.eclipse.jgit.errors.InvalidPatternException; | |||
@@ -66,7 +62,8 @@ public class JGitClientSession extends ClientSessionImpl { | |||
* protocol version exchange. 64kb is what OpenSSH < 8.0 read; OpenSSH 8.0 | |||
* changed it to 8Mb, but that seems excessive for the purpose stated in RFC | |||
* 4253. The Apache MINA sshd default in | |||
* {@link FactoryManager#DEFAULT_MAX_IDENTIFICATION_SIZE} is 16kb. | |||
* {@link org.apache.sshd.core.CoreModuleProperties#MAX_IDENTIFICATION_SIZE} | |||
* is 16kb. | |||
*/ | |||
private static final int DEFAULT_MAX_IDENTIFICATION_SIZE = 64 * 1024; | |||
@@ -76,17 +73,6 @@ public class JGitClientSession extends ClientSessionImpl { | |||
private volatile StatefulProxyConnector proxyHandler; | |||
/** | |||
* Work-around for bug 565394 / SSHD-1050; remove when using sshd 2.6.0. | |||
*/ | |||
private volatile AuthFuture authFuture; | |||
/** Records exceptions before there is an authFuture. */ | |||
private List<Throwable> earlyErrors = new ArrayList<>(); | |||
/** Guards setting an earlyError and the authFuture together. */ | |||
private final Object errorLock = new Object(); | |||
/** | |||
* @param manager | |||
* @param session | |||
@@ -97,125 +83,6 @@ public class JGitClientSession extends ClientSessionImpl { | |||
super(manager, session); | |||
} | |||
// BEGIN Work-around for bug 565394 / SSHD-1050 | |||
// Remove when using sshd 2.6.0. | |||
@Override | |||
public AuthFuture auth() throws IOException { | |||
if (getUsername() == null) { | |||
throw new IllegalStateException( | |||
SshdText.get().sessionWithoutUsername); | |||
} | |||
ClientUserAuthService authService = getUserAuthService(); | |||
String serviceName = nextServiceName(); | |||
List<Throwable> errors = null; | |||
AuthFuture future; | |||
// Guard both getting early errors and setting authFuture | |||
synchronized (errorLock) { | |||
future = authService.auth(serviceName); | |||
if (future == null) { | |||
// Internal error; no translation. | |||
throw new IllegalStateException( | |||
"No auth future generated by service '" //$NON-NLS-1$ | |||
+ serviceName + '\''); | |||
} | |||
errors = earlyErrors; | |||
earlyErrors = null; | |||
authFuture = future; | |||
} | |||
if (errors != null && !errors.isEmpty()) { | |||
Iterator<Throwable> iter = errors.iterator(); | |||
Throwable first = iter.next(); | |||
iter.forEachRemaining(t -> { | |||
if (t != first && t != null) { | |||
first.addSuppressed(t); | |||
} | |||
}); | |||
// Mark the future as having had an exception; just to be on the | |||
// safe side. Actually, there shouldn't be anyone waiting on this | |||
// future yet. | |||
future.setException(first); | |||
if (log.isDebugEnabled()) { | |||
log.debug("auth({}) early exception type={}: {}", //$NON-NLS-1$ | |||
this, first.getClass().getSimpleName(), | |||
first.getMessage()); | |||
} | |||
if (first instanceof SshException) { | |||
throw new SshException( | |||
((SshException) first).getDisconnectCode(), | |||
first.getMessage(), first); | |||
} | |||
throw new IOException(first.getMessage(), first); | |||
} | |||
return future; | |||
} | |||
@Override | |||
protected void signalAuthFailure(AuthFuture future, Throwable t) { | |||
signalAuthFailure(t); | |||
} | |||
private void signalAuthFailure(Throwable t) { | |||
AuthFuture future = authFuture; | |||
if (future == null) { | |||
synchronized (errorLock) { | |||
if (earlyErrors != null) { | |||
earlyErrors.add(t); | |||
} | |||
future = authFuture; | |||
} | |||
} | |||
if (future != null) { | |||
future.setException(t); | |||
} | |||
if (log.isDebugEnabled()) { | |||
boolean signalled = future != null && t == future.getException(); | |||
log.debug("signalAuthFailure({}) type={}, signalled={}: {}", this, //$NON-NLS-1$ | |||
t.getClass().getSimpleName(), Boolean.valueOf(signalled), | |||
t.getMessage()); | |||
} | |||
} | |||
@Override | |||
public void exceptionCaught(Throwable t) { | |||
signalAuthFailure(t); | |||
super.exceptionCaught(t); | |||
} | |||
@Override | |||
protected void preClose() { | |||
signalAuthFailure( | |||
new SshException(SshdText.get().authenticationOnClosedSession)); | |||
super.preClose(); | |||
} | |||
@Override | |||
protected void handleDisconnect(int code, String msg, String lang, | |||
Buffer buffer) throws Exception { | |||
signalAuthFailure(new SshException(code, msg)); | |||
super.handleDisconnect(code, msg, lang, buffer); | |||
} | |||
@Override | |||
protected <C extends Collection<ClientSessionEvent>> C updateCurrentSessionState( | |||
C newState) { | |||
if (closeFuture.isClosed()) { | |||
newState.add(ClientSessionEvent.CLOSED); | |||
} | |||
if (isAuthenticated()) { // authFuture.isSuccess() | |||
newState.add(ClientSessionEvent.AUTHED); | |||
} | |||
if (KexState.DONE.equals(getKexState())) { | |||
AuthFuture future = authFuture; | |||
if (future == null || future.isFailure()) { | |||
newState.add(ClientSessionEvent.WAIT_AUTH); | |||
} | |||
} | |||
return newState; | |||
} | |||
// END Work-around for bug 565394 / SSHD-1050 | |||
/** | |||
* Retrieves the {@link HostConfigEntry} this session was created for. | |||
* | |||
@@ -331,22 +198,6 @@ public class JGitClientSession extends ClientSessionImpl { | |||
} | |||
} | |||
@Override | |||
protected void checkKeys() throws SshException { | |||
ServerKeyVerifier serverKeyVerifier = getServerKeyVerifier(); | |||
// The super implementation always uses | |||
// getIoSession().getRemoteAddress(). In case of a proxy connection, | |||
// that would be the address of the proxy! | |||
SocketAddress remoteAddress = getConnectAddress(); | |||
PublicKey serverKey = getKex().getServerKey(); | |||
if (!serverKeyVerifier.verifyServerKey(this, remoteAddress, | |||
serverKey)) { | |||
throw new SshException( | |||
org.apache.sshd.common.SshConstants.SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE, | |||
SshdText.get().kexServerKeyInvalid); | |||
} | |||
} | |||
@Override | |||
protected String resolveAvailableSignaturesProposal( | |||
FactoryManager manager) { | |||
@@ -477,9 +328,15 @@ public class JGitClientSession extends ClientSessionImpl { | |||
throw new IllegalStateException( | |||
"doReadIdentification of client called with server=true"); //$NON-NLS-1$ | |||
} | |||
int maxIdentSize = PropertyResolverUtils.getIntProperty(this, | |||
FactoryManager.MAX_IDENTIFICATION_SIZE, | |||
DEFAULT_MAX_IDENTIFICATION_SIZE); | |||
Integer maxIdentLength = MAX_IDENTIFICATION_SIZE.get(this).orElse(null); | |||
int maxIdentSize; | |||
if (maxIdentLength == null || maxIdentLength | |||
.intValue() < DEFAULT_MAX_IDENTIFICATION_SIZE) { | |||
maxIdentSize = DEFAULT_MAX_IDENTIFICATION_SIZE; | |||
MAX_IDENTIFICATION_SIZE.set(this, Integer.valueOf(maxIdentSize)); | |||
} else { | |||
maxIdentSize = maxIdentLength.intValue(); | |||
} | |||
int current = buffer.rpos(); | |||
int end = current + buffer.available(); | |||
if (current >= end) { |