Search in sources :

Example 1 with PublicKeyStore

use of com.google.gerrit.gpg.PublicKeyStore in project gerrit by GerritCodeReview.

the class PostGpgKeys method tryStoreKeys.

private Void tryStoreKeys(AccountResource rsrc, List<PGPPublicKeyRing> keyRings, Collection<Fingerprint> toRemove) throws RestApiException, PGPException, IOException {
    try (PublicKeyStore store = storeProvider.get()) {
        List<String> addedKeys = new ArrayList<>();
        IdentifiedUser user = rsrc.getUser();
        for (PGPPublicKeyRing keyRing : keyRings) {
            PGPPublicKey key = keyRing.getPublicKey();
            // Don't check web of trust; admins can fill in certifications later.
            CheckResult result = checkerFactory.create(user, store).disableTrust().check(key);
            if (!result.isOk()) {
                throw new BadRequestException(String.format("Problems with public key %s:\n%s", keyToString(key), Joiner.on('\n').join(result.getProblems())));
            }
            addedKeys.add(PublicKeyStore.keyToString(key));
            store.add(keyRing);
        }
        for (Fingerprint fp : toRemove) {
            store.remove(fp.get());
        }
        CommitBuilder cb = new CommitBuilder();
        PersonIdent committer = serverIdent.get();
        cb.setAuthor(user.newCommitterIdent(committer));
        cb.setCommitter(committer);
        RefUpdate.Result saveResult = store.save(cb);
        switch(saveResult) {
            case NEW:
            case FAST_FORWARD:
            case FORCED:
                if (!addedKeys.isEmpty()) {
                    try {
                        addKeySenderFactory.create(user, addedKeys).send();
                    } catch (EmailException e) {
                        logger.atSevere().withCause(e).log("Cannot send GPG key added message to %s", rsrc.getUser().getAccount().preferredEmail());
                    }
                }
                if (!toRemove.isEmpty()) {
                    try {
                        deleteKeySenderFactory.create(user, toRemove.stream().map(Fingerprint::toString).collect(toList())).send();
                    } catch (EmailException e) {
                        logger.atSevere().withCause(e).log("Cannot send GPG key deleted message to %s", user.getAccount().preferredEmail());
                    }
                }
                break;
            case NO_CHANGE:
                break;
            case LOCK_FAILURE:
            case IO_FAILURE:
            case NOT_ATTEMPTED:
            case REJECTED:
            case REJECTED_CURRENT_BRANCH:
            case RENAMED:
            case REJECTED_MISSING_OBJECT:
            case REJECTED_OTHER_REASON:
            default:
                throw new StorageException(String.format("Failed to save public keys: %s", saveResult));
        }
    }
    return null;
}
Also used : PGPPublicKeyRing(org.bouncycastle.openpgp.PGPPublicKeyRing) Fingerprint(com.google.gerrit.gpg.Fingerprint) ArrayList(java.util.ArrayList) PGPPublicKey(org.bouncycastle.openpgp.PGPPublicKey) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) PublicKeyStore.keyToString(com.google.gerrit.gpg.PublicKeyStore.keyToString) PublicKeyStore.keyIdToString(com.google.gerrit.gpg.PublicKeyStore.keyIdToString) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) CheckResult(com.google.gerrit.gpg.CheckResult) PublicKeyStore(com.google.gerrit.gpg.PublicKeyStore) EmailException(com.google.gerrit.exceptions.EmailException) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) StorageException(com.google.gerrit.exceptions.StorageException) RefUpdate(org.eclipse.jgit.lib.RefUpdate)

Example 2 with PublicKeyStore

use of com.google.gerrit.gpg.PublicKeyStore in project gerrit by GerritCodeReview.

the class GpgKeys method parse.

@Override
public GpgKey parse(AccountResource parent, IdString id) throws ResourceNotFoundException, PGPException, IOException {
    checkVisible(self, parent);
    ExternalId gpgKeyExtId = findGpgKey(id.get(), getGpgExtIds(parent));
    byte[] fp = parseFingerprint(gpgKeyExtId);
    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);
}
Also used : PGPPublicKeyRing(org.bouncycastle.openpgp.PGPPublicKeyRing) ExternalId(com.google.gerrit.server.account.externalids.ExternalId) PublicKeyStore(com.google.gerrit.gpg.PublicKeyStore) PGPPublicKey(org.bouncycastle.openpgp.PGPPublicKey) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException)

Example 3 with PublicKeyStore

use of com.google.gerrit.gpg.PublicKeyStore in project gerrit by GerritCodeReview.

the class AccountIT method getOnlyKeyFromStore.

private PGPPublicKey getOnlyKeyFromStore(TestKey key) throws Exception {
    try (PublicKeyStore store = publicKeyStoreProvider.get()) {
        Iterable<PGPPublicKeyRing> keys = store.get(key.getKeyId());
        assertThat(keys).hasSize(1);
        return keys.iterator().next().getPublicKey();
    }
}
Also used : PGPPublicKeyRing(org.bouncycastle.openpgp.PGPPublicKeyRing) PublicKeyStore(com.google.gerrit.gpg.PublicKeyStore)

Example 4 with PublicKeyStore

use of com.google.gerrit.gpg.PublicKeyStore in project gerrit by GerritCodeReview.

the class PostGpgKeys method apply.

@Override
public Map<String, GpgKeyInfo> apply(AccountResource rsrc, Input input) throws ResourceNotFoundException, BadRequestException, ResourceConflictException, PGPException, OrmException, IOException, ConfigInvalidException {
    GpgKeys.checkVisible(self, rsrc);
    Collection<ExternalId> existingExtIds = externalIds.byAccount(rsrc.getUser().getAccountId(), SCHEME_GPGKEY);
    try (PublicKeyStore store = storeProvider.get()) {
        Set<Fingerprint> toRemove = readKeysToRemove(input, existingExtIds);
        List<PGPPublicKeyRing> newKeys = readKeysToAdd(input, toRemove);
        List<ExternalId> newExtIds = new ArrayList<>(existingExtIds.size());
        for (PGPPublicKeyRing keyRing : newKeys) {
            PGPPublicKey key = keyRing.getPublicKey();
            ExternalId.Key extIdKey = toExtIdKey(key.getFingerprint());
            Account account = getAccountByExternalId(extIdKey);
            if (account != null) {
                if (!account.getId().equals(rsrc.getUser().getAccountId())) {
                    throw new ResourceConflictException("GPG key already associated with another account");
                }
            } else {
                newExtIds.add(ExternalId.create(extIdKey, rsrc.getUser().getAccountId()));
            }
        }
        storeKeys(rsrc, newKeys, toRemove);
        List<ExternalId.Key> extIdKeysToRemove = toRemove.stream().map(fp -> toExtIdKey(fp.get())).collect(toList());
        externalIdsUpdateFactory.create().replace(rsrc.getUser().getAccountId(), extIdKeysToRemove, newExtIds);
        accountCache.evict(rsrc.getUser().getAccountId());
        return toJson(newKeys, toRemove, store, rsrc.getUser());
    }
}
Also used : ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) OrmException(com.google.gwtorm.server.OrmException) PublicKeyStore.keyToString(com.google.gerrit.gpg.PublicKeyStore.keyToString) Inject(com.google.inject.Inject) LoggerFactory(org.slf4j.LoggerFactory) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) RestModifyView(com.google.gerrit.extensions.restapi.RestModifyView) ByteArrayInputStream(java.io.ByteArrayInputStream) GpgKeyInfo(com.google.gerrit.extensions.common.GpgKeyInfo) Map(java.util.Map) PGPPublicKeyRing(org.bouncycastle.openpgp.PGPPublicKeyRing) PGPException(org.bouncycastle.openpgp.PGPException) ImmutableSet(com.google.common.collect.ImmutableSet) Collection(java.util.Collection) Set(java.util.Set) RefUpdate(org.eclipse.jgit.lib.RefUpdate) PGPPublicKey(org.bouncycastle.openpgp.PGPPublicKey) SCHEME_GPGKEY(com.google.gerrit.server.account.externalids.ExternalId.SCHEME_GPGKEY) Sets(com.google.common.collect.Sets) ExternalIds(com.google.gerrit.server.account.externalids.ExternalIds) PersonIdent(org.eclipse.jgit.lib.PersonIdent) List(java.util.List) ExternalIdsUpdate(com.google.gerrit.server.account.externalids.ExternalIdsUpdate) Joiner(com.google.common.base.Joiner) Singleton(com.google.inject.Singleton) AccountCache(com.google.gerrit.server.account.AccountCache) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) PublicKeyStore(com.google.gerrit.gpg.PublicKeyStore) InternalAccountQuery(com.google.gerrit.server.query.account.InternalAccountQuery) GerritPublicKeyChecker(com.google.gerrit.gpg.GerritPublicKeyChecker) Fingerprint(com.google.gerrit.gpg.Fingerprint) ArrayList(java.util.ArrayList) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) Account(com.google.gerrit.reviewdb.client.Account) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) ArmoredInputStream(org.bouncycastle.bcpg.ArmoredInputStream) CheckResult(com.google.gerrit.gpg.CheckResult) Input(com.google.gerrit.gpg.server.PostGpgKeys.Input) CurrentUser(com.google.gerrit.server.CurrentUser) Logger(org.slf4j.Logger) BaseEncoding(com.google.common.io.BaseEncoding) UTF_8(java.nio.charset.StandardCharsets.UTF_8) AccountResource(com.google.gerrit.server.account.AccountResource) EmailException(com.google.gerrit.common.errors.EmailException) PublicKeyChecker(com.google.gerrit.gpg.PublicKeyChecker) IOException(java.io.IOException) Maps(com.google.common.collect.Maps) PublicKeyStore.keyIdToString(com.google.gerrit.gpg.PublicKeyStore.keyIdToString) Collectors.toList(java.util.stream.Collectors.toList) Provider(com.google.inject.Provider) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) AddKeySender(com.google.gerrit.server.mail.send.AddKeySender) ExternalId(com.google.gerrit.server.account.externalids.ExternalId) AccountState(com.google.gerrit.server.account.AccountState) BcPGPObjectFactory(org.bouncycastle.openpgp.bc.BcPGPObjectFactory) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) InputStream(java.io.InputStream) PGPPublicKeyRing(org.bouncycastle.openpgp.PGPPublicKeyRing) Account(com.google.gerrit.reviewdb.client.Account) Fingerprint(com.google.gerrit.gpg.Fingerprint) ExternalId(com.google.gerrit.server.account.externalids.ExternalId) ArrayList(java.util.ArrayList) PGPPublicKey(org.bouncycastle.openpgp.PGPPublicKey) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) PublicKeyStore(com.google.gerrit.gpg.PublicKeyStore) PGPPublicKey(org.bouncycastle.openpgp.PGPPublicKey)

Example 5 with PublicKeyStore

use of com.google.gerrit.gpg.PublicKeyStore in project gerrit by GerritCodeReview.

the class PostGpgKeys method storeKeys.

private void storeKeys(AccountResource rsrc, List<PGPPublicKeyRing> keyRings, Set<Fingerprint> toRemove) throws BadRequestException, ResourceConflictException, PGPException, IOException {
    try (PublicKeyStore store = storeProvider.get()) {
        List<String> addedKeys = new ArrayList<>();
        for (PGPPublicKeyRing keyRing : keyRings) {
            PGPPublicKey key = keyRing.getPublicKey();
            // Don't check web of trust; admins can fill in certifications later.
            CheckResult result = checkerFactory.create(rsrc.getUser(), store).disableTrust().check(key);
            if (!result.isOk()) {
                throw new BadRequestException(String.format("Problems with public key %s:\n%s", keyToString(key), Joiner.on('\n').join(result.getProblems())));
            }
            addedKeys.add(PublicKeyStore.keyToString(key));
            store.add(keyRing);
        }
        for (Fingerprint fp : toRemove) {
            store.remove(fp.get());
        }
        CommitBuilder cb = new CommitBuilder();
        PersonIdent committer = serverIdent.get();
        cb.setAuthor(rsrc.getUser().newCommitterIdent(committer.getWhen(), committer.getTimeZone()));
        cb.setCommitter(committer);
        RefUpdate.Result saveResult = store.save(cb);
        switch(saveResult) {
            case NEW:
            case FAST_FORWARD:
            case FORCED:
                try {
                    addKeyFactory.create(rsrc.getUser(), addedKeys).send();
                } catch (EmailException e) {
                    log.error("Cannot send GPG key added message to " + rsrc.getUser().getAccount().getPreferredEmail(), e);
                }
                break;
            case NO_CHANGE:
                break;
            case IO_FAILURE:
            case LOCK_FAILURE:
            case NOT_ATTEMPTED:
            case REJECTED:
            case REJECTED_CURRENT_BRANCH:
            case RENAMED:
            default:
                // TODO(dborowitz): Backoff and retry on LOCK_FAILURE.
                throw new ResourceConflictException("Failed to save public keys: " + saveResult);
        }
    }
}
Also used : PGPPublicKeyRing(org.bouncycastle.openpgp.PGPPublicKeyRing) Fingerprint(com.google.gerrit.gpg.Fingerprint) ArrayList(java.util.ArrayList) PGPPublicKey(org.bouncycastle.openpgp.PGPPublicKey) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) PublicKeyStore.keyToString(com.google.gerrit.gpg.PublicKeyStore.keyToString) PublicKeyStore.keyIdToString(com.google.gerrit.gpg.PublicKeyStore.keyIdToString) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) CheckResult(com.google.gerrit.gpg.CheckResult) PublicKeyStore(com.google.gerrit.gpg.PublicKeyStore) EmailException(com.google.gerrit.common.errors.EmailException) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) RefUpdate(org.eclipse.jgit.lib.RefUpdate)

Aggregations

PublicKeyStore (com.google.gerrit.gpg.PublicKeyStore)7 PGPPublicKey (org.bouncycastle.openpgp.PGPPublicKey)6 PGPPublicKeyRing (org.bouncycastle.openpgp.PGPPublicKeyRing)6 Fingerprint (com.google.gerrit.gpg.Fingerprint)4 PublicKeyStore.keyIdToString (com.google.gerrit.gpg.PublicKeyStore.keyIdToString)4 GerritPersonIdent (com.google.gerrit.server.GerritPersonIdent)4 ExternalId (com.google.gerrit.server.account.externalids.ExternalId)4 ArrayList (java.util.ArrayList)4 CommitBuilder (org.eclipse.jgit.lib.CommitBuilder)4 PersonIdent (org.eclipse.jgit.lib.PersonIdent)4 RefUpdate (org.eclipse.jgit.lib.RefUpdate)4 BadRequestException (com.google.gerrit.extensions.restapi.BadRequestException)3 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)3 ResourceNotFoundException (com.google.gerrit.extensions.restapi.ResourceNotFoundException)3 CheckResult (com.google.gerrit.gpg.CheckResult)3 PublicKeyStore.keyToString (com.google.gerrit.gpg.PublicKeyStore.keyToString)3 EmailException (com.google.gerrit.common.errors.EmailException)2 EmailException (com.google.gerrit.exceptions.EmailException)2 StorageException (com.google.gerrit.exceptions.StorageException)2 IdentifiedUser (com.google.gerrit.server.IdentifiedUser)2