aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.gpg.bc.test
diff options
context:
space:
mode:
authorThomas Wolf <thomas.wolf@paranor.ch>2021-01-17 16:21:28 +0100
committerMatthias Sohn <matthias.sohn@sap.com>2021-02-16 00:37:01 +0100
commit64cbea8a9794047fe576d03ab8a46e4eaf7eabee (patch)
tree4dc95a2278643c1d8faa70875043301de94ebc6a /org.eclipse.jgit.gpg.bc.test
parent3774fcc848da7526ffa74211cbb2781df5731125 (diff)
downloadjgit-64cbea8a9794047fe576d03ab8a46e4eaf7eabee.tar.gz
jgit-64cbea8a9794047fe576d03ab8a46e4eaf7eabee.zip
GPG: compute the keygrip to find a secret key
The gpg-agent stores secret keys in individual files in the secret key directory private-keys-v1.d. The files have the key's keygrip (in upper case) as name and extension ".key". A keygrip is a SHA1 hash over the parameters of the public key. By computing this keygrip, we can pre-compute the expected file name and then check only that one file instead of having to iterate over all keys stored in that directory. This file naming scheme is actually an implementation detail of gpg-agent. It is unlikely to change, though. The keygrip itself is computed via libgcrypt and will remain stable according to the GPG main author.[1] Add an implementation for calculating the keygrip and include tests. Do not iterate over files in BouncyCastleGpgKeyLocator but only check the single file identified by the keygrip. Ideally upstream BouncyCastle would provide such a getKeyGrip() method. But as it re-builds GPG and libgcrypt internals, it's doubtful it would be included there, and since BouncyCastle even lacks a number of curve OIDs for ed25519/curve25519 and uses the short-Weierstrass parameters instead of the more common Montgomery parameters, including it there might be quite a bit of work. [1] http://gnupg.10057.n7.nabble.com/GnuPG-2-1-x-and-2-2-x-keyring-formats-tp54146p54154.html Bug: 547536 Change-Id: I30022a0e7b33b1bf35aec1222f84591f0c30ddfd Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.jgit.gpg.bc.test')
-rw-r--r--org.eclipse.jgit.gpg.bc.test/.classpath9
-rw-r--r--org.eclipse.jgit.gpg.bc.test/.gitignore1
-rw-r--r--org.eclipse.jgit.gpg.bc.test/BUILD20
-rw-r--r--org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF12
-rw-r--r--org.eclipse.jgit.gpg.bc.test/build.properties2
-rw-r--r--org.eclipse.jgit.gpg.bc.test/pom.xml6
-rw-r--r--org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/brainpool256.asc14
-rw-r--r--org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/brainpool384.asc17
-rw-r--r--org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/brainpool512.asc19
-rw-r--r--org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/dsa-elgamal.asc44
-rw-r--r--org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/ed25519.asc9
-rw-r--r--org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/nistp256.asc14
-rw-r--r--org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/nistp384.asc16
-rw-r--r--org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/nistp521.asc19
-rw-r--r--org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/rsa.asc40
-rw-r--r--org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/secp256k1.asc14
-rw-r--r--org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/x25519.asc13
-rw-r--r--org.eclipse.jgit.gpg.bc.test/tst/org/eclipse/jgit/gpg/bc/internal/keys/KeyGrip25519Test.java61
-rw-r--r--org.eclipse.jgit.gpg.bc.test/tst/org/eclipse/jgit/gpg/bc/internal/keys/KeyGripTest.java143
19 files changed, 468 insertions, 5 deletions
diff --git a/org.eclipse.jgit.gpg.bc.test/.classpath b/org.eclipse.jgit.gpg.bc.test/.classpath
index f08af0a4e9..0acccbaaec 100644
--- a/org.eclipse.jgit.gpg.bc.test/.classpath
+++ b/org.eclipse.jgit.gpg.bc.test/.classpath
@@ -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>
diff --git a/org.eclipse.jgit.gpg.bc.test/.gitignore b/org.eclipse.jgit.gpg.bc.test/.gitignore
index 934e0e06ff..8b6760c93c 100644
--- a/org.eclipse.jgit.gpg.bc.test/.gitignore
+++ b/org.eclipse.jgit.gpg.bc.test/.gitignore
@@ -1,2 +1,3 @@
/bin
+/bin-tst
/target
diff --git a/org.eclipse.jgit.gpg.bc.test/BUILD b/org.eclipse.jgit.gpg.bc.test/BUILD
index 1e3677d929..59859b2837 100644
--- a/org.eclipse.jgit.gpg.bc.test/BUILD
+++ b/org.eclipse.jgit.gpg.bc.test/BUILD
@@ -1,4 +1,9 @@
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,22 @@ junit_tests(
srcs = glob(["tst/**/*.java"]),
tags = ["bc"],
deps = [
+ "//lib:bcpg",
+ "//lib:bcprov",
"//lib:junit",
"//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 .",
+)
diff --git a/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
index 35a418c5a2..39ece1fcf0 100644
--- a/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
@@ -7,8 +7,16 @@ 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)"
+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.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
Require-Bundle: org.hamcrest.core;bundle-version="[1.1.0,2.0.0)",
org.hamcrest.library;bundle-version="[1.1.0,2.0.0)"
diff --git a/org.eclipse.jgit.gpg.bc.test/build.properties b/org.eclipse.jgit.gpg.bc.test/build.properties
index 9ffa0caf78..e36d6667ee 100644
--- a/org.eclipse.jgit.gpg.bc.test/build.properties
+++ b/org.eclipse.jgit.gpg.bc.test/build.properties
@@ -1,5 +1,5 @@
source.. = tst/
-output.. = bin/
+output.. = bin-tst/
bin.includes = META-INF/,\
.,\
plugin.properties
diff --git a/org.eclipse.jgit.gpg.bc.test/pom.xml b/org.eclipse.jgit.gpg.bc.test/pom.xml
index f244fb4769..cac7e151e9 100644
--- a/org.eclipse.jgit.gpg.bc.test/pom.xml
+++ b/org.eclipse.jgit.gpg.bc.test/pom.xml
@@ -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>
diff --git a/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/brainpool256.asc b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/brainpool256.asc
new file mode 100644
index 0000000000..8427cfcc05
--- /dev/null
+++ b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/brainpool256.asc
@@ -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-----
diff --git a/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/brainpool384.asc b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/brainpool384.asc
new file mode 100644
index 0000000000..bdb20fe939
--- /dev/null
+++ b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/brainpool384.asc
@@ -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-----
diff --git a/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/brainpool512.asc b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/brainpool512.asc
new file mode 100644
index 0000000000..5b4bca2c67
--- /dev/null
+++ b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/brainpool512.asc
@@ -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-----
diff --git a/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/dsa-elgamal.asc b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/dsa-elgamal.asc
new file mode 100644
index 0000000000..db067325cb
--- /dev/null
+++ b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/dsa-elgamal.asc
@@ -0,0 +1,44 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+v5BhpoOOm+jM
+=PnGk
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/ed25519.asc b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/ed25519.asc
new file mode 100644
index 0000000000..636a5a95f3
--- /dev/null
+++ b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/ed25519.asc
@@ -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-----
diff --git a/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/nistp256.asc b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/nistp256.asc
new file mode 100644
index 0000000000..fd1509e9ba
--- /dev/null
+++ b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/nistp256.asc
@@ -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-----
diff --git a/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/nistp384.asc b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/nistp384.asc
new file mode 100644
index 0000000000..b2b59959e6
--- /dev/null
+++ b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/nistp384.asc
@@ -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-----
diff --git a/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/nistp521.asc b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/nistp521.asc
new file mode 100644
index 0000000000..db18f81a29
--- /dev/null
+++ b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/nistp521.asc
@@ -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-----
diff --git a/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/rsa.asc b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/rsa.asc
new file mode 100644
index 0000000000..e74df7a2a9
--- /dev/null
+++ b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/rsa.asc
@@ -0,0 +1,40 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+=aibx
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/secp256k1.asc b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/secp256k1.asc
new file mode 100644
index 0000000000..837f8a867e
--- /dev/null
+++ b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/secp256k1.asc
@@ -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-----
diff --git a/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/x25519.asc b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/x25519.asc
new file mode 100644
index 0000000000..d531d7a8ba
--- /dev/null
+++ b/org.eclipse.jgit.gpg.bc.test/tst-rsrc/org/eclipse/jgit/gpg/bc/internal/keys/x25519.asc
@@ -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-----
diff --git a/org.eclipse.jgit.gpg.bc.test/tst/org/eclipse/jgit/gpg/bc/internal/keys/KeyGrip25519Test.java b/org.eclipse.jgit.gpg.bc.test/tst/org/eclipse/jgit/gpg/bc/internal/keys/KeyGrip25519Test.java
new file mode 100644
index 0000000000..e30080258f
--- /dev/null
+++ b/org.eclipse.jgit.gpg.bc.test/tst/org/eclipse/jgit/gpg/bc/internal/keys/KeyGrip25519Test.java
@@ -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);
+ }
+}
diff --git a/org.eclipse.jgit.gpg.bc.test/tst/org/eclipse/jgit/gpg/bc/internal/keys/KeyGripTest.java b/org.eclipse.jgit.gpg.bc.test/tst/org/eclipse/jgit/gpg/bc/internal/keys/KeyGripTest.java
new file mode 100644
index 0000000000..a4aaf40d9b
--- /dev/null
+++ b/org.eclipse.jgit.gpg.bc.test/tst/org/eclipse/jgit/gpg/bc/internal/keys/KeyGripTest.java
@@ -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]);
+ }
+ }
+}