summaryrefslogtreecommitdiffstats
path: root/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/GpgKeys.java
diff options
context:
space:
mode:
Diffstat (limited to 'gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/GpgKeys.java')
-rw-r--r--gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/GpgKeys.java252
1 files changed, 0 insertions, 252 deletions
diff --git a/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/GpgKeys.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/GpgKeys.java
deleted file mode 100644
index 6dd3c7ec3a..0000000000
--- a/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/GpgKeys.java
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.gpg.server;
-
-import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_GPGKEY;
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import com.google.common.base.CharMatcher;
-import com.google.common.collect.ImmutableList;
-import com.google.common.io.BaseEncoding;
-import com.google.gerrit.extensions.common.GpgKeyInfo;
-import com.google.gerrit.extensions.registration.DynamicMap;
-import com.google.gerrit.extensions.restapi.AuthException;
-import com.google.gerrit.extensions.restapi.ChildCollection;
-import com.google.gerrit.extensions.restapi.IdString;
-import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
-import com.google.gerrit.extensions.restapi.RestReadView;
-import com.google.gerrit.extensions.restapi.RestView;
-import com.google.gerrit.gpg.BouncyCastleUtil;
-import com.google.gerrit.gpg.CheckResult;
-import com.google.gerrit.gpg.Fingerprint;
-import com.google.gerrit.gpg.GerritPublicKeyChecker;
-import com.google.gerrit.gpg.PublicKeyChecker;
-import com.google.gerrit.gpg.PublicKeyStore;
-import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.account.AccountResource;
-import com.google.gerrit.server.account.externalids.ExternalId;
-import com.google.gerrit.server.account.externalids.ExternalIds;
-import com.google.gwtorm.server.OrmException;
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.google.inject.Singleton;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import org.bouncycastle.bcpg.ArmoredOutputStream;
-import org.bouncycastle.openpgp.PGPException;
-import org.bouncycastle.openpgp.PGPPublicKey;
-import org.bouncycastle.openpgp.PGPPublicKeyRing;
-import org.eclipse.jgit.util.NB;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Singleton
-public class GpgKeys implements ChildCollection<AccountResource, GpgKey> {
- private static final Logger log = LoggerFactory.getLogger(GpgKeys.class);
-
- public static final String MIME_TYPE = "application/pgp-keys";
-
- private final DynamicMap<RestView<GpgKey>> views;
- private final Provider<CurrentUser> self;
- private final Provider<PublicKeyStore> storeProvider;
- private final GerritPublicKeyChecker.Factory checkerFactory;
- private final ExternalIds externalIds;
-
- @Inject
- GpgKeys(
- DynamicMap<RestView<GpgKey>> views,
- Provider<CurrentUser> self,
- Provider<PublicKeyStore> storeProvider,
- GerritPublicKeyChecker.Factory checkerFactory,
- ExternalIds externalIds) {
- this.views = views;
- this.self = self;
- this.storeProvider = storeProvider;
- this.checkerFactory = checkerFactory;
- this.externalIds = externalIds;
- }
-
- @Override
- public ListGpgKeys list() throws ResourceNotFoundException, AuthException {
- return new ListGpgKeys();
- }
-
- @Override
- public GpgKey parse(AccountResource parent, IdString id)
- throws ResourceNotFoundException, PGPException, OrmException, IOException {
- checkVisible(self, parent);
- String str = CharMatcher.whitespace().removeFrom(id.get()).toUpperCase();
- if ((str.length() != 8 && str.length() != 40)
- || !CharMatcher.anyOf("0123456789ABCDEF").matchesAllOf(str)) {
- throw new ResourceNotFoundException(id);
- }
-
- byte[] fp = parseFingerprint(id.get(), getGpgExtIds(parent));
- try (PublicKeyStore store = storeProvider.get()) {
- long keyId = keyId(fp);
- for (PGPPublicKeyRing keyRing : store.get(keyId)) {
- PGPPublicKey key = keyRing.getPublicKey();
- if (Arrays.equals(key.getFingerprint(), fp)) {
- return new GpgKey(parent.getUser(), keyRing);
- }
- }
- }
-
- throw new ResourceNotFoundException(id);
- }
-
- static byte[] parseFingerprint(String str, Iterable<ExternalId> existingExtIds)
- throws ResourceNotFoundException {
- str = CharMatcher.whitespace().removeFrom(str).toUpperCase();
- if ((str.length() != 8 && str.length() != 40)
- || !CharMatcher.anyOf("0123456789ABCDEF").matchesAllOf(str)) {
- throw new ResourceNotFoundException(str);
- }
- byte[] fp = null;
- for (ExternalId extId : existingExtIds) {
- String fpStr = extId.key().id();
- if (!fpStr.endsWith(str)) {
- continue;
- } else if (fp != null) {
- throw new ResourceNotFoundException("Multiple keys found for " + str);
- }
- fp = BaseEncoding.base16().decode(fpStr);
- if (str.length() == 40) {
- break;
- }
- }
- if (fp == null) {
- throw new ResourceNotFoundException(str);
- }
- return fp;
- }
-
- @Override
- public DynamicMap<RestView<GpgKey>> views() {
- return views;
- }
-
- public class ListGpgKeys implements RestReadView<AccountResource> {
- @Override
- public Map<String, GpgKeyInfo> apply(AccountResource rsrc)
- throws OrmException, PGPException, IOException, ResourceNotFoundException {
- checkVisible(self, rsrc);
- Map<String, GpgKeyInfo> keys = new HashMap<>();
- try (PublicKeyStore store = storeProvider.get()) {
- for (ExternalId extId : getGpgExtIds(rsrc)) {
- String fpStr = extId.key().id();
- byte[] fp = BaseEncoding.base16().decode(fpStr);
- boolean found = false;
- for (PGPPublicKeyRing keyRing : store.get(keyId(fp))) {
- if (Arrays.equals(keyRing.getPublicKey().getFingerprint(), fp)) {
- found = true;
- GpgKeyInfo info =
- toJson(
- keyRing.getPublicKey(), checkerFactory.create(rsrc.getUser(), store), store);
- keys.put(info.id, info);
- info.id = null;
- break;
- }
- }
- if (!found) {
- log.warn("No public key stored for fingerprint {}", Fingerprint.toString(fp));
- }
- }
- }
- return keys;
- }
- }
-
- @Singleton
- public static class Get implements RestReadView<GpgKey> {
- private final Provider<PublicKeyStore> storeProvider;
- private final GerritPublicKeyChecker.Factory checkerFactory;
-
- @Inject
- Get(Provider<PublicKeyStore> storeProvider, GerritPublicKeyChecker.Factory checkerFactory) {
- this.storeProvider = storeProvider;
- this.checkerFactory = checkerFactory;
- }
-
- @Override
- public GpgKeyInfo apply(GpgKey rsrc) throws IOException {
- try (PublicKeyStore store = storeProvider.get()) {
- return toJson(
- rsrc.getKeyRing().getPublicKey(),
- checkerFactory.create().setExpectedUser(rsrc.getUser()),
- store);
- }
- }
- }
-
- private Iterable<ExternalId> getGpgExtIds(AccountResource rsrc) throws IOException {
- return externalIds.byAccount(rsrc.getUser().getAccountId(), SCHEME_GPGKEY);
- }
-
- private static long keyId(byte[] fp) {
- return NB.decodeInt64(fp, fp.length - 8);
- }
-
- static void checkVisible(Provider<CurrentUser> self, AccountResource rsrc)
- throws ResourceNotFoundException {
- if (!BouncyCastleUtil.havePGP()) {
- throw new ResourceNotFoundException("GPG not enabled");
- }
- if (!self.get().hasSameAccountId(rsrc.getUser())) {
- throw new ResourceNotFoundException();
- }
- }
-
- public static GpgKeyInfo toJson(PGPPublicKey key, CheckResult checkResult) throws IOException {
- GpgKeyInfo info = new GpgKeyInfo();
-
- if (key != null) {
- info.id = PublicKeyStore.keyIdToString(key.getKeyID());
- info.fingerprint = Fingerprint.toString(key.getFingerprint());
- Iterator<String> userIds = key.getUserIDs();
- info.userIds = ImmutableList.copyOf(userIds);
-
- try (ByteArrayOutputStream out = new ByteArrayOutputStream(4096)) {
- try (ArmoredOutputStream aout = new ArmoredOutputStream(out)) {
- // This is not exactly the key stored in the store, but is equivalent. In
- // particular, it will have a Bouncy Castle version string. The armored
- // stream reader in PublicKeyStore doesn't give us an easy way to extract
- // the original ASCII armor.
- key.encode(aout);
- }
- info.key = new String(out.toByteArray(), UTF_8);
- }
- }
-
- info.status = checkResult.getStatus();
- info.problems = checkResult.getProblems();
-
- return info;
- }
-
- static GpgKeyInfo toJson(PGPPublicKey key, PublicKeyChecker checker, PublicKeyStore store)
- throws IOException {
- return toJson(key, checker.setStore(store).check(key));
- }
-
- public static void toJson(GpgKeyInfo info, CheckResult checkResult) {
- info.status = checkResult.getStatus();
- info.problems = checkResult.getProblems();
- }
-}