Merge changes from topic 'signed-push-cleanup'
* changes: Move REFS_GPG_KEYS to PublicKeyStore config-gerrit.txt: Organize "receive" section PushCertificateChecker: Don't throw exceptions PushCertificateChecker: Tweak some error messages
This commit is contained in:
@@ -2863,28 +2863,16 @@ Default is 5 seconds. Negative values will be converted to 0.
|
|||||||
[[receive]]
|
[[receive]]
|
||||||
=== Section receive
|
=== Section receive
|
||||||
|
|
||||||
This section is used to set who can execute the 'receive-pack' and
|
This section is used to configure behavior of the 'receive-pack'
|
||||||
to limit the maximum Git object size that 'receive-pack' will accept.
|
handler, which responds to 'git push' requests.
|
||||||
'receive-pack' is what runs on the server during a user's push or
|
|
||||||
repo upload command. It also contains some advanced options for tuning the
|
|
||||||
behavior of Gerrit's 'receive-pack' mechanism.
|
|
||||||
|
|
||||||
----
|
[[receive.allowGroup]]receive.allowGroup::
|
||||||
[receive]
|
|
||||||
allowGroup = GROUP_ALLOWED_TO_EXECUTE
|
|
||||||
allowGroup = YET_ANOTHER_GROUP_ALLOWED_TO_EXECUTE
|
|
||||||
maxObjectSizeLimit = 40 m
|
|
||||||
----
|
|
||||||
|
|
||||||
[[receive.enableSignedPush]]receive.enableSignedPush::
|
|
||||||
+
|
+
|
||||||
If true, server-side signed push validation is enabled.
|
Name of the groups of users that are allowed to execute
|
||||||
|
'receive-pack' on the server. One or more groups can be set.
|
||||||
+
|
+
|
||||||
When a client pushes with `git push --signed`, this ensures that the
|
If no groups are added, any user will be allowed to execute
|
||||||
push certificate is valid and signed with a valid public key stored in
|
'receive-pack' on the server.
|
||||||
the `refs/gpg-keys` branch of `All-Users`.
|
|
||||||
+
|
|
||||||
Defaults to false.
|
|
||||||
|
|
||||||
[[receive.certNonceSeed]]receive.certNonceSeed::
|
[[receive.certNonceSeed]]receive.certNonceSeed::
|
||||||
+
|
+
|
||||||
@@ -2910,6 +2898,18 @@ the client.
|
|||||||
+
|
+
|
||||||
Default is 5 minutes.
|
Default is 5 minutes.
|
||||||
|
|
||||||
|
[[receive.changeUpdateThreads]]receive.changeUpdateThreads::
|
||||||
|
+
|
||||||
|
Number of threads to perform change creation or patch set updates
|
||||||
|
concurrently. Each thread uses its own database connection from
|
||||||
|
the database connection pool, and if all threads are busy then
|
||||||
|
main receive thread will also perform a change creation or patch
|
||||||
|
set update.
|
||||||
|
+
|
||||||
|
Defaults to 1, using only the main receive thread. This feature is for
|
||||||
|
databases with very high latency that can benefit from concurrent
|
||||||
|
operations when multiple changes are impacted at once.
|
||||||
|
|
||||||
[[receive.checkMagicRefs]]receive.checkMagicRefs::
|
[[receive.checkMagicRefs]]receive.checkMagicRefs::
|
||||||
+
|
+
|
||||||
If true, Gerrit will verify the destination repository has
|
If true, Gerrit will verify the destination repository has
|
||||||
@@ -2938,13 +2938,30 @@ references to access commits intended to be hidden from the user.
|
|||||||
+
|
+
|
||||||
Default is true.
|
Default is true.
|
||||||
|
|
||||||
[[receive.allowGroup]]receive.allowGroup::
|
[[receive.enableSignedPush]]receive.enableSignedPush::
|
||||||
+
|
+
|
||||||
Name of the groups of users that are allowed to execute
|
If true, server-side signed push validation is enabled.
|
||||||
'receive-pack' on the server. One or more groups can be set.
|
|
||||||
+
|
+
|
||||||
If no groups are added, any user will be allowed to execute
|
When a client pushes with `git push --signed`, this ensures that the
|
||||||
'receive-pack' on the server.
|
push certificate is valid and signed with a valid public key stored in
|
||||||
|
the `refs/gpg-keys` branch of `All-Users`.
|
||||||
|
+
|
||||||
|
Defaults to false.
|
||||||
|
|
||||||
|
[[receive.maxBatchChanges]]receive.maxBatchChanges::
|
||||||
|
+
|
||||||
|
The maximum number of changes that Gerrit allows to be pushed
|
||||||
|
in a batch for review. When this number is exceeded Gerrit rejects
|
||||||
|
the push with an error message.
|
||||||
|
+
|
||||||
|
May be overridden for certain groups by specifying a limit in the
|
||||||
|
link:access-control.html#capability_batchChangesLimit['Batch Changes Limit']
|
||||||
|
global capability.
|
||||||
|
+
|
||||||
|
This setting can be used to prevent users from uploading large
|
||||||
|
number of changes for review by mistake.
|
||||||
|
+
|
||||||
|
Default is zero, no limit.
|
||||||
|
|
||||||
[[receive.maxObjectSizeLimit]]receive.maxObjectSizeLimit::
|
[[receive.maxObjectSizeLimit]]receive.maxObjectSizeLimit::
|
||||||
+
|
+
|
||||||
@@ -2965,21 +2982,6 @@ Default is zero.
|
|||||||
+
|
+
|
||||||
Common unit suffixes of 'k', 'm', or 'g' are supported.
|
Common unit suffixes of 'k', 'm', or 'g' are supported.
|
||||||
|
|
||||||
[[receive.maxBatchChanges]]receive.maxBatchChanges::
|
|
||||||
+
|
|
||||||
The maximum number of changes that Gerrit allows to be pushed
|
|
||||||
in a batch for review. When this number is exceeded Gerrit rejects
|
|
||||||
the push with an error message.
|
|
||||||
+
|
|
||||||
May be overridden for certain groups by specifying a limit in the
|
|
||||||
link:access-control.html#capability_batchChangesLimit['Batch Changes Limit']
|
|
||||||
global capability.
|
|
||||||
+
|
|
||||||
This setting can be used to prevent users from uploading large
|
|
||||||
number of changes for review by mistake.
|
|
||||||
+
|
|
||||||
Default is zero, no limit.
|
|
||||||
|
|
||||||
[[receive.threadPoolSize]]receive.threadPoolSize::
|
[[receive.threadPoolSize]]receive.threadPoolSize::
|
||||||
+
|
+
|
||||||
Maximum size of the thread pool in which the change data in received packs is
|
Maximum size of the thread pool in which the change data in received packs is
|
||||||
@@ -2987,18 +2989,6 @@ processed.
|
|||||||
+
|
+
|
||||||
Defaults to the number of available CPUs according to the Java runtime.
|
Defaults to the number of available CPUs according to the Java runtime.
|
||||||
|
|
||||||
[[receive.changeUpdateThreads]]receive.changeUpdateThreads::
|
|
||||||
+
|
|
||||||
Number of threads to perform change creation or patch set updates
|
|
||||||
concurrently. Each thread uses its own database connection from
|
|
||||||
the database connection pool, and if all threads are busy then
|
|
||||||
main receive thread will also perform a change creation or patch
|
|
||||||
set update.
|
|
||||||
+
|
|
||||||
Defaults to 1, using only the main receive thread. This feature is for
|
|
||||||
databases with very high latency that can benefit from concurrent
|
|
||||||
operations when multiple changes are impacted at once.
|
|
||||||
|
|
||||||
[[receive.timeout]]receive.timeout::
|
[[receive.timeout]]receive.timeout::
|
||||||
+
|
+
|
||||||
Overall timeout on the time taken to process the change data in
|
Overall timeout on the time taken to process the change data in
|
||||||
|
@@ -17,6 +17,7 @@ package com.google.gerrit.acceptance.api.accounts;
|
|||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static com.google.common.truth.Truth.assert_;
|
import static com.google.common.truth.Truth.assert_;
|
||||||
|
import static com.google.gerrit.gpg.PublicKeyStore.REFS_GPG_KEYS;
|
||||||
import static com.google.gerrit.gpg.PublicKeyStore.keyToString;
|
import static com.google.gerrit.gpg.PublicKeyStore.keyToString;
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
@@ -39,7 +40,6 @@ import com.google.gerrit.gpg.server.GpgKeys;
|
|||||||
import com.google.gerrit.gpg.testutil.TestKey;
|
import com.google.gerrit.gpg.testutil.TestKey;
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
||||||
import com.google.gerrit.reviewdb.client.RefNames;
|
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.config.AllUsersName;
|
import com.google.gerrit.server.config.AllUsersName;
|
||||||
import com.google.gerrit.testutil.ConfigSuite;
|
import com.google.gerrit.testutil.ConfigSuite;
|
||||||
@@ -99,9 +99,9 @@ public class AccountIT extends AbstractDaemonTest {
|
|||||||
@After
|
@After
|
||||||
public void clearPublicKeyStore() throws Exception {
|
public void clearPublicKeyStore() throws Exception {
|
||||||
try (Repository repo = repoManager.openRepository(allUsers)) {
|
try (Repository repo = repoManager.openRepository(allUsers)) {
|
||||||
Ref ref = repo.getRef(RefNames.REFS_GPG_KEYS);
|
Ref ref = repo.getRef(REFS_GPG_KEYS);
|
||||||
if (ref != null) {
|
if (ref != null) {
|
||||||
RefUpdate ru = repo.updateRef(RefNames.REFS_GPG_KEYS);
|
RefUpdate ru = repo.updateRef(REFS_GPG_KEYS);
|
||||||
ru.setForceUpdate(true);
|
ru.setForceUpdate(true);
|
||||||
assertThat(ru.delete()).isEqualTo(RefUpdate.Result.FORCED);
|
assertThat(ru.delete()).isEqualTo(RefUpdate.Result.FORCED);
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ public class AccountIT extends AbstractDaemonTest {
|
|||||||
|
|
||||||
@After
|
@After
|
||||||
public void deleteGpgKeys() throws Exception {
|
public void deleteGpgKeys() throws Exception {
|
||||||
String ref = RefNames.REFS_GPG_KEYS;
|
String ref = REFS_GPG_KEYS;
|
||||||
try (Repository repo = repoManager.openRepository(allUsers)) {
|
try (Repository repo = repoManager.openRepository(allUsers)) {
|
||||||
if (repo.getRefDatabase().exactRef(ref) != null) {
|
if (repo.getRefDatabase().exactRef(ref) != null) {
|
||||||
RefUpdate ru = repo.updateRef(ref);
|
RefUpdate ru = repo.updateRef(ref);
|
||||||
|
@@ -17,8 +17,6 @@ package com.google.gerrit.gpg;
|
|||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
|
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
|
||||||
|
|
||||||
import com.google.gerrit.reviewdb.client.RefNames;
|
|
||||||
|
|
||||||
import org.bouncycastle.bcpg.ArmoredInputStream;
|
import org.bouncycastle.bcpg.ArmoredInputStream;
|
||||||
import org.bouncycastle.bcpg.ArmoredOutputStream;
|
import org.bouncycastle.bcpg.ArmoredOutputStream;
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
@@ -73,6 +71,9 @@ public class PublicKeyStore implements AutoCloseable {
|
|||||||
private static final ObjectId EMPTY_TREE =
|
private static final ObjectId EMPTY_TREE =
|
||||||
ObjectId.fromString("4b825dc642cb6eb9a060e54bf8d69288fbee4904");
|
ObjectId.fromString("4b825dc642cb6eb9a060e54bf8d69288fbee4904");
|
||||||
|
|
||||||
|
/** Ref where GPG public keys are stored. */
|
||||||
|
public static final String REFS_GPG_KEYS = "refs/meta/gpg-keys";
|
||||||
|
|
||||||
private final Repository repo;
|
private final Repository repo;
|
||||||
private ObjectReader reader;
|
private ObjectReader reader;
|
||||||
private RevCommit tip;
|
private RevCommit tip;
|
||||||
@@ -104,7 +105,7 @@ public class PublicKeyStore implements AutoCloseable {
|
|||||||
reset();
|
reset();
|
||||||
reader = repo.newObjectReader();
|
reader = repo.newObjectReader();
|
||||||
|
|
||||||
Ref ref = repo.getRefDatabase().exactRef(RefNames.REFS_GPG_KEYS);
|
Ref ref = repo.getRefDatabase().exactRef(REFS_GPG_KEYS);
|
||||||
if (ref == null) {
|
if (ref == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -249,7 +250,7 @@ public class PublicKeyStore implements AutoCloseable {
|
|||||||
ins.flush();
|
ins.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
RefUpdate ru = repo.updateRef(RefNames.REFS_GPG_KEYS);
|
RefUpdate ru = repo.updateRef(PublicKeyStore.REFS_GPG_KEYS);
|
||||||
ru.setExpectedOldObjectId(tip);
|
ru.setExpectedOldObjectId(tip);
|
||||||
ru.setNewObjectId(newTip);
|
ru.setNewObjectId(newTip);
|
||||||
ru.setRefLogIdent(cb.getCommitter());
|
ru.setRefLogIdent(cb.getCommitter());
|
||||||
|
@@ -31,6 +31,8 @@ import org.eclipse.jgit.lib.Constants;
|
|||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.transport.PushCertificate;
|
import org.eclipse.jgit.transport.PushCertificate;
|
||||||
import org.eclipse.jgit.transport.PushCertificate.NonceStatus;
|
import org.eclipse.jgit.transport.PushCertificate.NonceStatus;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -39,6 +41,9 @@ import java.util.List;
|
|||||||
|
|
||||||
/** Checker for push certificates. */
|
/** Checker for push certificates. */
|
||||||
public abstract class PushCertificateChecker {
|
public abstract class PushCertificateChecker {
|
||||||
|
private static final Logger log =
|
||||||
|
LoggerFactory.getLogger(PushCertificateChecker.class);
|
||||||
|
|
||||||
private final PublicKeyChecker publicKeyChecker;
|
private final PublicKeyChecker publicKeyChecker;
|
||||||
|
|
||||||
protected PushCertificateChecker(PublicKeyChecker publicKeyChecker) {
|
protected PushCertificateChecker(PublicKeyChecker publicKeyChecker) {
|
||||||
@@ -49,28 +54,34 @@ public abstract class PushCertificateChecker {
|
|||||||
* Check a push certificate.
|
* Check a push certificate.
|
||||||
*
|
*
|
||||||
* @return result of the check.
|
* @return result of the check.
|
||||||
* @throws PGPException if an error occurred during GPG checks.
|
|
||||||
* @throws IOException if an error occurred reading from the repository.
|
|
||||||
*/
|
*/
|
||||||
public final CheckResult check(PushCertificate cert) throws PGPException, IOException {
|
public final CheckResult check(PushCertificate cert) {
|
||||||
if (cert.getNonceStatus() != NonceStatus.OK) {
|
if (cert.getNonceStatus() != NonceStatus.OK) {
|
||||||
return new CheckResult("Invalid nonce");
|
return new CheckResult("Invalid nonce");
|
||||||
}
|
}
|
||||||
PGPSignature sig = readSignature(cert);
|
|
||||||
if (sig == null) {
|
|
||||||
return new CheckResult("Invalid signature format");
|
|
||||||
}
|
|
||||||
Repository repo = getRepository();
|
|
||||||
List<String> problems = new ArrayList<>();
|
List<String> problems = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
PGPSignature sig = readSignature(cert);
|
||||||
|
if (sig != null) {
|
||||||
|
@SuppressWarnings("resource")
|
||||||
|
Repository repo = getRepository();
|
||||||
try (PublicKeyStore store = new PublicKeyStore(repo)) {
|
try (PublicKeyStore store = new PublicKeyStore(repo)) {
|
||||||
checkSignature(sig, cert, store.get(sig.getKeyID()), problems);
|
checkSignature(sig, cert, store.get(sig.getKeyID()), problems);
|
||||||
checkCustom(repo, problems);
|
checkCustom(repo, problems);
|
||||||
return new CheckResult(problems);
|
|
||||||
} finally {
|
} finally {
|
||||||
if (shouldClose(repo)) {
|
if (shouldClose(repo)) {
|
||||||
repo.close();
|
repo.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
problems.add("Invalid signature format");
|
||||||
|
}
|
||||||
|
} catch (PGPException | IOException e) {
|
||||||
|
String msg = "Internal error checking push certificate";
|
||||||
|
log.error(msg, e);
|
||||||
|
problems.add(msg);
|
||||||
|
}
|
||||||
|
return new CheckResult(problems);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,9 +151,9 @@ public abstract class PushCertificateChecker {
|
|||||||
if (result.isOk()) {
|
if (result.isOk()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StringBuilder err = new StringBuilder("Invalid public key (")
|
StringBuilder err = new StringBuilder("Invalid public key ")
|
||||||
.append(keyToString(k))
|
.append(keyToString(k))
|
||||||
.append("):");
|
.append(":");
|
||||||
for (int i = 0; i < result.getProblems().size(); i++) {
|
for (int i = 0; i < result.getProblems().size(); i++) {
|
||||||
err.append('\n').append(" ").append(result.getProblems().get(i));
|
err.append('\n').append(" ").append(result.getProblems().get(i));
|
||||||
}
|
}
|
||||||
@@ -150,13 +161,13 @@ public abstract class PushCertificateChecker {
|
|||||||
return;
|
return;
|
||||||
} catch (PGPException e) {
|
} catch (PGPException e) {
|
||||||
deferredProblems.add(
|
deferredProblems.add(
|
||||||
"Error checking signature with public key (" + keyToString(k)
|
"Error checking signature with public key " + keyToString(k)
|
||||||
+ ": " + e.getMessage());
|
+ ": " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!anyKeys) {
|
if (!anyKeys) {
|
||||||
problems.add(
|
problems.add(
|
||||||
"No public keys found for Key ID " + keyIdToString(sig.getKeyID()));
|
"No public keys found for key ID " + keyIdToString(sig.getKeyID()));
|
||||||
} else {
|
} else {
|
||||||
problems.addAll(deferredProblems);
|
problems.addAll(deferredProblems);
|
||||||
}
|
}
|
||||||
|
@@ -19,14 +19,11 @@ import com.google.gerrit.server.git.GitRepositoryManager;
|
|||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.transport.PreReceiveHook;
|
import org.eclipse.jgit.transport.PreReceiveHook;
|
||||||
import org.eclipse.jgit.transport.PushCertificate;
|
import org.eclipse.jgit.transport.PushCertificate;
|
||||||
import org.eclipse.jgit.transport.ReceiveCommand;
|
import org.eclipse.jgit.transport.ReceiveCommand;
|
||||||
import org.eclipse.jgit.transport.ReceivePack;
|
import org.eclipse.jgit.transport.ReceivePack;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -40,9 +37,6 @@ import java.util.Collection;
|
|||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class SignedPushPreReceiveHook implements PreReceiveHook {
|
public class SignedPushPreReceiveHook implements PreReceiveHook {
|
||||||
private static final Logger log =
|
|
||||||
LoggerFactory.getLogger(SignedPushPreReceiveHook.class);
|
|
||||||
|
|
||||||
private final GitRepositoryManager repoManager;
|
private final GitRepositoryManager repoManager;
|
||||||
private final AllUsersName allUsers;
|
private final AllUsersName allUsers;
|
||||||
private final PublicKeyChecker keyChecker;
|
private final PublicKeyChecker keyChecker;
|
||||||
@@ -60,7 +54,6 @@ public class SignedPushPreReceiveHook implements PreReceiveHook {
|
|||||||
@Override
|
@Override
|
||||||
public void onPreReceive(ReceivePack rp,
|
public void onPreReceive(ReceivePack rp,
|
||||||
Collection<ReceiveCommand> commands) {
|
Collection<ReceiveCommand> commands) {
|
||||||
try {
|
|
||||||
PushCertificate cert = rp.getPushCertificate();
|
PushCertificate cert = rp.getPushCertificate();
|
||||||
if (cert == null) {
|
if (cert == null) {
|
||||||
return;
|
return;
|
||||||
@@ -83,10 +76,6 @@ public class SignedPushPreReceiveHook implements PreReceiveHook {
|
|||||||
}
|
}
|
||||||
reject(commands, "invalid push cert");
|
reject(commands, "invalid push cert");
|
||||||
}
|
}
|
||||||
} catch (PGPException | IOException e) {
|
|
||||||
log.error("Error checking push certificate", e);
|
|
||||||
reject(commands, "push cert error");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void reject(Collection<ReceiveCommand> commands,
|
private static void reject(Collection<ReceiveCommand> commands,
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
package com.google.gerrit.gpg;
|
package com.google.gerrit.gpg;
|
||||||
|
|
||||||
|
import static com.google.gerrit.gpg.PublicKeyStore.REFS_GPG_KEYS;
|
||||||
import static com.google.gerrit.gpg.PublicKeyStore.keyIdToString;
|
import static com.google.gerrit.gpg.PublicKeyStore.keyIdToString;
|
||||||
import static com.google.gerrit.gpg.PublicKeyStore.keyObjectId;
|
import static com.google.gerrit.gpg.PublicKeyStore.keyObjectId;
|
||||||
import static com.google.gerrit.gpg.PublicKeyStore.keyToString;
|
import static com.google.gerrit.gpg.PublicKeyStore.keyToString;
|
||||||
@@ -23,7 +24,6 @@ import static org.junit.Assert.assertFalse;
|
|||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import com.google.gerrit.gpg.testutil.TestKey;
|
import com.google.gerrit.gpg.testutil.TestKey;
|
||||||
import com.google.gerrit.reviewdb.client.RefNames;
|
|
||||||
|
|
||||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
@@ -84,13 +84,13 @@ public class PublicKeyStoreTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testGet() throws Exception {
|
public void testGet() throws Exception {
|
||||||
TestKey key1 = TestKey.key1();
|
TestKey key1 = TestKey.key1();
|
||||||
tr.branch(RefNames.REFS_GPG_KEYS)
|
tr.branch(REFS_GPG_KEYS)
|
||||||
.commit()
|
.commit()
|
||||||
.add(keyObjectId(key1.getKeyId()).name(),
|
.add(keyObjectId(key1.getKeyId()).name(),
|
||||||
key1.getPublicKeyArmored())
|
key1.getPublicKeyArmored())
|
||||||
.create();
|
.create();
|
||||||
TestKey key2 = TestKey.key2();
|
TestKey key2 = TestKey.key2();
|
||||||
tr.branch(RefNames.REFS_GPG_KEYS)
|
tr.branch(REFS_GPG_KEYS)
|
||||||
.commit()
|
.commit()
|
||||||
.add(keyObjectId(key2.getKeyId()).name(),
|
.add(keyObjectId(key2.getKeyId()).name(),
|
||||||
key2.getPublicKeyArmored())
|
key2.getPublicKeyArmored())
|
||||||
@@ -104,7 +104,7 @@ public class PublicKeyStoreTest {
|
|||||||
public void testGetMultiple() throws Exception {
|
public void testGetMultiple() throws Exception {
|
||||||
TestKey key1 = TestKey.key1();
|
TestKey key1 = TestKey.key1();
|
||||||
TestKey key2 = TestKey.key2();
|
TestKey key2 = TestKey.key2();
|
||||||
tr.branch(RefNames.REFS_GPG_KEYS)
|
tr.branch(REFS_GPG_KEYS)
|
||||||
.commit()
|
.commit()
|
||||||
.add(keyObjectId(key1.getKeyId()).name(),
|
.add(keyObjectId(key1.getKeyId()).name(),
|
||||||
key1.getPublicKeyArmored()
|
key1.getPublicKeyArmored()
|
||||||
@@ -131,7 +131,7 @@ public class PublicKeyStoreTest {
|
|||||||
public void saveAppendsToExistingList() throws Exception {
|
public void saveAppendsToExistingList() throws Exception {
|
||||||
TestKey key1 = TestKey.key1();
|
TestKey key1 = TestKey.key1();
|
||||||
TestKey key2 = TestKey.key2();
|
TestKey key2 = TestKey.key2();
|
||||||
tr.branch(RefNames.REFS_GPG_KEYS)
|
tr.branch(REFS_GPG_KEYS)
|
||||||
.commit()
|
.commit()
|
||||||
// Mismatched for this key ID, but we can still read it out.
|
// Mismatched for this key ID, but we can still read it out.
|
||||||
.add(keyObjectId(key1.getKeyId()).name(), key2.getPublicKeyArmored())
|
.add(keyObjectId(key1.getKeyId()).name(), key2.getPublicKeyArmored())
|
||||||
@@ -146,7 +146,7 @@ public class PublicKeyStoreTest {
|
|||||||
RevWalk rw = new RevWalk(reader)) {
|
RevWalk rw = new RevWalk(reader)) {
|
||||||
NoteMap notes = NoteMap.read(
|
NoteMap notes = NoteMap.read(
|
||||||
reader, tr.getRevWalk().parseCommit(
|
reader, tr.getRevWalk().parseCommit(
|
||||||
tr.getRepository().getRef(RefNames.REFS_GPG_KEYS).getObjectId()));
|
tr.getRepository().getRef(REFS_GPG_KEYS).getObjectId()));
|
||||||
String contents = new String(
|
String contents = new String(
|
||||||
reader.open(notes.get(keyObjectId(key1.getKeyId()))).getBytes(),
|
reader.open(notes.get(keyObjectId(key1.getKeyId()))).getBytes(),
|
||||||
UTF_8);
|
UTF_8);
|
||||||
|
@@ -14,13 +14,13 @@
|
|||||||
|
|
||||||
package com.google.gerrit.gpg;
|
package com.google.gerrit.gpg;
|
||||||
|
|
||||||
|
import static com.google.gerrit.gpg.PublicKeyStore.REFS_GPG_KEYS;
|
||||||
import static com.google.gerrit.gpg.PublicKeyStore.keyIdToString;
|
import static com.google.gerrit.gpg.PublicKeyStore.keyIdToString;
|
||||||
import static com.google.gerrit.gpg.PublicKeyStore.keyToString;
|
import static com.google.gerrit.gpg.PublicKeyStore.keyToString;
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
import com.google.gerrit.gpg.testutil.TestKey;
|
import com.google.gerrit.gpg.testutil.TestKey;
|
||||||
import com.google.gerrit.reviewdb.client.RefNames;
|
|
||||||
|
|
||||||
import org.bouncycastle.bcpg.ArmoredOutputStream;
|
import org.bouncycastle.bcpg.ArmoredOutputStream;
|
||||||
import org.bouncycastle.bcpg.BCPGOutputStream;
|
import org.bouncycastle.bcpg.BCPGOutputStream;
|
||||||
@@ -56,7 +56,7 @@ public class PushCertificateCheckerTest {
|
|||||||
TestKey key3 = TestKey.key3();
|
TestKey key3 = TestKey.key3();
|
||||||
tr = new TestRepository<>(new InMemoryRepository(
|
tr = new TestRepository<>(new InMemoryRepository(
|
||||||
new DfsRepositoryDescription("repo")));
|
new DfsRepositoryDescription("repo")));
|
||||||
tr.branch(RefNames.REFS_GPG_KEYS).commit()
|
tr.branch(REFS_GPG_KEYS).commit()
|
||||||
.add(PublicKeyStore.keyObjectId(key1.getPublicKey().getKeyID()).name(),
|
.add(PublicKeyStore.keyObjectId(key1.getPublicKey().getKeyID()).name(),
|
||||||
key1.getPublicKeyArmored())
|
key1.getPublicKeyArmored())
|
||||||
.add(PublicKeyStore.keyObjectId(key3.getPublicKey().getKeyID()).name(),
|
.add(PublicKeyStore.keyObjectId(key3.getPublicKey().getKeyID()).name(),
|
||||||
@@ -96,7 +96,7 @@ public class PushCertificateCheckerTest {
|
|||||||
TestKey key2 = TestKey.key2();
|
TestKey key2 = TestKey.key2();
|
||||||
PushCertificate cert = newSignedCert(validNonce(), key2);
|
PushCertificate cert = newSignedCert(validNonce(), key2);
|
||||||
assertProblems(cert,
|
assertProblems(cert,
|
||||||
"No public keys found for Key ID " + keyIdToString(key2.getKeyId()));
|
"No public keys found for key ID " + keyIdToString(key2.getKeyId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -104,8 +104,8 @@ public class PushCertificateCheckerTest {
|
|||||||
TestKey key3 = TestKey.key3();
|
TestKey key3 = TestKey.key3();
|
||||||
PushCertificate cert = newSignedCert(validNonce(), key3);
|
PushCertificate cert = newSignedCert(validNonce(), key3);
|
||||||
assertProblems(cert,
|
assertProblems(cert,
|
||||||
"Invalid public key (" + keyToString(key3.getPublicKey())
|
"Invalid public key " + keyToString(key3.getPublicKey())
|
||||||
+ "):\n Key is expired");
|
+ ":\n Key is expired");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String validNonce() {
|
private String validNonce() {
|
||||||
|
@@ -57,12 +57,6 @@ public class RefNames {
|
|||||||
|
|
||||||
public static final String EDIT_PREFIX = "edit-";
|
public static final String EDIT_PREFIX = "edit-";
|
||||||
|
|
||||||
/**
|
|
||||||
* Special ref for GPG public keys used by {@link
|
|
||||||
* com.google.gerrit.gpg.SignedPushPreReceiveHook}.
|
|
||||||
*/
|
|
||||||
public static final String REFS_GPG_KEYS = "refs/meta/gpg-keys";
|
|
||||||
|
|
||||||
public static String fullName(String ref) {
|
public static String fullName(String ref) {
|
||||||
return ref.startsWith(REFS) ? ref : REFS_HEADS + ref;
|
return ref.startsWith(REFS) ? ref : REFS_HEADS + ref;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user