Search in sources :

Example 6 with PGPPublicKey

use of org.bouncycastle.openpgp.PGPPublicKey in project gerrit by GerritCodeReview.

the class PostGpgKeys method toJson.

private Map<String, GpgKeyInfo> toJson(Collection<PGPPublicKeyRing> keys, Set<Fingerprint> deleted, PublicKeyStore store, IdentifiedUser user) throws IOException {
    // Unlike when storing keys, include web-of-trust checks when producing
    // result JSON, so the user at least knows of any issues.
    PublicKeyChecker checker = checkerFactory.create(user, store);
    Map<String, GpgKeyInfo> infos = Maps.newHashMapWithExpectedSize(keys.size() + deleted.size());
    for (PGPPublicKeyRing keyRing : keys) {
        PGPPublicKey key = keyRing.getPublicKey();
        CheckResult result = checker.check(key);
        GpgKeyInfo info = GpgKeys.toJson(key, result);
        infos.put(info.id, info);
        info.id = null;
    }
    for (Fingerprint fp : deleted) {
        infos.put(keyIdToString(fp.getId()), new GpgKeyInfo());
    }
    return infos;
}
Also used : PGPPublicKeyRing(org.bouncycastle.openpgp.PGPPublicKeyRing) Fingerprint(com.google.gerrit.gpg.Fingerprint) CheckResult(com.google.gerrit.gpg.CheckResult) PGPPublicKey(org.bouncycastle.openpgp.PGPPublicKey) PublicKeyStore.keyToString(com.google.gerrit.gpg.PublicKeyStore.keyToString) PublicKeyStore.keyIdToString(com.google.gerrit.gpg.PublicKeyStore.keyIdToString) GerritPublicKeyChecker(com.google.gerrit.gpg.GerritPublicKeyChecker) PublicKeyChecker(com.google.gerrit.gpg.PublicKeyChecker) GpgKeyInfo(com.google.gerrit.extensions.common.GpgKeyInfo)

Example 7 with PGPPublicKey

use of org.bouncycastle.openpgp.PGPPublicKey in project gerrit by GerritCodeReview.

the class GerritPublicKeyCheckerTest method keyLaterInTrustChainMissingUserId.

@Test
public void keyLaterInTrustChainMissingUserId() throws Exception {
    // A---Bx
    //  \
    //   \---C
    //
    // The server ultimately trusts B.
    // C signed A's key but is not in the store.
    TestKey keyA = add(keyA(), user);
    PGPPublicKeyRing keyRingB = keyB().getPublicKeyRing();
    PGPPublicKey keyB = keyRingB.getPublicKey();
    keyB = PGPPublicKey.removeCertification(keyB, (String) keyB.getUserIDs().next());
    keyRingB = PGPPublicKeyRing.insertPublicKey(keyRingB, keyB);
    add(keyRingB, addUser("userB"));
    PublicKeyChecker checkerA = checkerFactory.create(user, store);
    assertProblems(checkerA.check(keyA.getPublicKey()), Status.OK, "No path to a trusted key", "Certification by " + keyToString(keyB) + " is valid, but key is not trusted", "Key D24FE467 used for certification is not in store");
}
Also used : PGPPublicKeyRing(org.bouncycastle.openpgp.PGPPublicKeyRing) TestKey(com.google.gerrit.gpg.testutil.TestKey) PGPPublicKey(org.bouncycastle.openpgp.PGPPublicKey) PublicKeyStore.keyToString(com.google.gerrit.gpg.PublicKeyStore.keyToString) Test(org.junit.Test)

Example 8 with PGPPublicKey

use of org.bouncycastle.openpgp.PGPPublicKey in project gerrit by GerritCodeReview.

the class PublicKeyStore method add.

/**
   * Add a public key to the store.
   *
   * <p>Multiple calls may be made to buffer keys in memory, and they are not saved until {@link
   * #save(CommitBuilder)} is called.
   *
   * @param keyRing a key ring containing exactly one public master key.
   */
public void add(PGPPublicKeyRing keyRing) {
    int numMaster = 0;
    for (PGPPublicKey key : keyRing) {
        if (key.isMasterKey()) {
            numMaster++;
        }
    }
    // here. The alternative is insane but harmless.
    if (numMaster != 1) {
        throw new IllegalArgumentException("Exactly 1 master key is required, found " + numMaster);
    }
    Fingerprint fp = new Fingerprint(keyRing.getPublicKey().getFingerprint());
    toAdd.put(fp, keyRing);
    toRemove.remove(fp);
}
Also used : PGPPublicKey(org.bouncycastle.openpgp.PGPPublicKey)

Example 9 with PGPPublicKey

use of org.bouncycastle.openpgp.PGPPublicKey in project gerrit by GerritCodeReview.

the class PushCertificateChecker method combine.

private static Result combine(Result sigResult, List<CheckResult> results) {
    // Combine results:
    //  - If any input result is BAD, the final result is bad.
    //  - If sigResult is TRUSTED and no other result is BAD, the final result
    //    is TRUSTED.
    //  - Otherwise, the result is OK.
    List<String> problems = new ArrayList<>();
    boolean bad = false;
    for (CheckResult result : results) {
        problems.addAll(result.getProblems());
        bad |= result.getStatus() == BAD;
    }
    Status status = bad ? BAD : OK;
    PGPPublicKey key;
    if (sigResult != null) {
        key = sigResult.getPublicKey();
        CheckResult cr = sigResult.getCheckResult();
        problems.addAll(cr.getProblems());
        if (cr.getStatus() == BAD) {
            status = BAD;
        } else if (!bad && cr.getStatus() == TRUSTED) {
            status = TRUSTED;
        }
    } else {
        key = null;
    }
    return new Result(key, CheckResult.create(status, problems));
}
Also used : Status(com.google.gerrit.extensions.common.GpgKeyInfo.Status) NonceStatus(org.eclipse.jgit.transport.PushCertificate.NonceStatus) ArrayList(java.util.ArrayList) PGPPublicKey(org.bouncycastle.openpgp.PGPPublicKey) PublicKeyStore.keyToString(com.google.gerrit.gpg.PublicKeyStore.keyToString) PublicKeyStore.keyIdToString(com.google.gerrit.gpg.PublicKeyStore.keyIdToString)

Example 10 with PGPPublicKey

use of org.bouncycastle.openpgp.PGPPublicKey in project gerrit by GerritCodeReview.

the class PublicKeyChecker method checkWebOfTrust.

private CheckResult checkWebOfTrust(PGPPublicKey key, PublicKeyStore store, int depth, Set<Fingerprint> seen) {
    if (trusted == null) {
        // Trust checking not configured, server trusts all OK keys.
        return CheckResult.trusted();
    }
    Fingerprint fp = new Fingerprint(key.getFingerprint());
    if (seen.contains(fp)) {
        return CheckResult.ok("Key is trusted in a cycle");
    }
    seen.add(fp);
    Fingerprint trustedFp = trusted.get(key.getKeyID());
    if (trustedFp != null && trustedFp.equals(fp)) {
        // Directly trusted.
        return CheckResult.trusted();
    } else if (depth >= maxTrustDepth) {
        return CheckResult.ok("No path of depth <= " + maxTrustDepth + " to a trusted key");
    }
    List<CheckResult> signerResults = new ArrayList<>();
    @SuppressWarnings("unchecked") Iterator<String> userIds = key.getUserIDs();
    while (userIds.hasNext()) {
        String userId = userIds.next();
        // Don't check the timestamp of these certifications. This allows admins
        // to correct untrusted keys by signing them with a trusted key, such that
        // older signatures created by those keys retroactively appear valid.
        Iterator<PGPSignature> sigs = key.getSignaturesForID(userId);
        while (sigs.hasNext()) {
            PGPSignature sig = sigs.next();
            // TODO(dborowitz): Handle CERTIFICATION_REVOCATION.
            if (sig.getSignatureType() != PGPSignature.DEFAULT_CERTIFICATION && sig.getSignatureType() != PGPSignature.POSITIVE_CERTIFICATION) {
                // Not a certification.
                continue;
            }
            PGPPublicKey signer = getSigner(store, sig, userId, key, signerResults);
            // TODO(dborowitz): Require self certification.
            if (signer == null || Arrays.equals(signer.getFingerprint(), key.getFingerprint())) {
                continue;
            }
            String subpacketProblem = checkTrustSubpacket(sig, depth);
            if (subpacketProblem == null) {
                CheckResult signerResult = check(signer, depth + 1, false, seen);
                if (signerResult.isTrusted()) {
                    return CheckResult.trusted();
                }
            }
            signerResults.add(CheckResult.ok("Certification by " + keyToString(signer) + " is valid, but key is not trusted"));
        }
    }
    List<String> problems = new ArrayList<>();
    problems.add("No path to a trusted key");
    for (CheckResult signerResult : signerResults) {
        problems.addAll(signerResult.getProblems());
    }
    return CheckResult.create(OK, problems);
}
Also used : ArrayList(java.util.ArrayList) PGPPublicKey(org.bouncycastle.openpgp.PGPPublicKey) PublicKeyStore.keyToString(com.google.gerrit.gpg.PublicKeyStore.keyToString) PublicKeyStore.keyIdToString(com.google.gerrit.gpg.PublicKeyStore.keyIdToString) PGPSignature(org.bouncycastle.openpgp.PGPSignature)

Aggregations

PGPPublicKey (org.bouncycastle.openpgp.PGPPublicKey)26 PGPPublicKeyRing (org.bouncycastle.openpgp.PGPPublicKeyRing)12 PublicKeyStore.keyToString (com.google.gerrit.gpg.PublicKeyStore.keyToString)8 PublicKeyStore.keyIdToString (com.google.gerrit.gpg.PublicKeyStore.keyIdToString)6 Test (org.junit.Test)6 ArrayList (java.util.ArrayList)5 PublicKeyStore (com.google.gerrit.gpg.PublicKeyStore)4 ByteArrayInputStream (java.io.ByteArrayInputStream)4 InputStream (java.io.InputStream)4 PGPException (org.bouncycastle.openpgp.PGPException)4 GpgKeyInfo (com.google.gerrit.extensions.common.GpgKeyInfo)3 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)3 CheckResult (com.google.gerrit.gpg.CheckResult)3 Fingerprint (com.google.gerrit.gpg.Fingerprint)3 TestKey (com.google.gerrit.gpg.testutil.TestKey)3 GerritPersonIdent (com.google.gerrit.server.GerritPersonIdent)3 IOException (java.io.IOException)3 PGPPublicKeyRingCollection (org.bouncycastle.openpgp.PGPPublicKeyRingCollection)3 BcPGPContentVerifierBuilderProvider (org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider)3 CommitBuilder (org.eclipse.jgit.lib.CommitBuilder)3