use of org.bouncycastle.openpgp.PGPPublicKey in project gerrit by GerritCodeReview.
the class AccountIT method reAddExistingGpgKey.
@Test
public void reAddExistingGpgKey() throws Exception {
addExternalIdEmail(admin, "test5@example.com");
TestKey key = validKeyWithSecondUserId();
String id = key.getKeyIdString();
PGPPublicKey pk = key.getPublicKey();
GpgKeyInfo info = addGpgKey(armor(pk)).get(id);
assertThat(info.userIds).hasSize(2);
assertIteratorSize(2, getOnlyKeyFromStore(key).getUserIDs());
pk = PGPPublicKey.removeCertification(pk, "foo:myId");
info = addGpgKey(armor(pk)).get(id);
assertThat(info.userIds).hasSize(1);
assertIteratorSize(1, getOnlyKeyFromStore(key).getUserIDs());
}
use of org.bouncycastle.openpgp.PGPPublicKey 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());
}
}
use of org.bouncycastle.openpgp.PGPPublicKey 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);
}
}
}
use of org.bouncycastle.openpgp.PGPPublicKey in project gerrit by GerritCodeReview.
the class PublicKeyStore method getSigner.
/**
* Choose the public key that produced a signature.
*
* <p>
*
* @param keyRings candidate keys.
* @param sig signature object.
* @param data signed payload.
* @return the key chosen from {@code keyRings} that was able to verify the signature, or {@code
* null} if none was found.
* @throws PGPException if an error occurred verifying the signature.
*/
public static PGPPublicKey getSigner(Iterable<PGPPublicKeyRing> keyRings, PGPSignature sig, byte[] data) throws PGPException {
for (PGPPublicKeyRing kr : keyRings) {
PGPPublicKey k = kr.getPublicKey();
sig.init(new BcPGPContentVerifierBuilderProvider(), k);
sig.update(data);
if (sig.verify()) {
return k;
}
}
return null;
}
use of org.bouncycastle.openpgp.PGPPublicKey in project gerrit by GerritCodeReview.
the class PushCertificateChecker method checkSignature.
private Result checkSignature(PGPSignature sig, PushCertificate cert, PublicKeyStore store) throws PGPException, IOException {
PGPPublicKeyRingCollection keys = store.get(sig.getKeyID());
if (!keys.getKeyRings().hasNext()) {
return new Result(null, CheckResult.bad("No public keys found for key ID " + keyIdToString(sig.getKeyID())));
}
PGPPublicKey signer = PublicKeyStore.getSigner(keys, sig, Constants.encode(cert.toText()));
if (signer == null) {
return new Result(null, CheckResult.bad("Signature by " + keyIdToString(sig.getKeyID()) + " is not valid"));
}
CheckResult result = publicKeyChecker.setStore(store).setEffectiveTime(sig.getCreationTime()).check(signer);
if (!result.getProblems().isEmpty()) {
StringBuilder err = new StringBuilder("Invalid public key ").append(keyToString(signer)).append(":\n ").append(Joiner.on("\n ").join(result.getProblems()));
return new Result(signer, CheckResult.create(result.getStatus(), err.toString()));
}
return new Result(signer, result);
}
Aggregations