From 366d13f1e455a905f7c88f907be0852f0d55b13a Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Thu, 3 Feb 2022 15:24:12 +0100 Subject: [PATCH] Add DefaultMergeCallback --- .../DefaultMergeCallback.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 pgpainless-core/src/main/java/org/pgpainless/certificate_store/DefaultMergeCallback.java diff --git a/pgpainless-core/src/main/java/org/pgpainless/certificate_store/DefaultMergeCallback.java b/pgpainless-core/src/main/java/org/pgpainless/certificate_store/DefaultMergeCallback.java new file mode 100644 index 00000000..df4fe805 --- /dev/null +++ b/pgpainless-core/src/main/java/org/pgpainless/certificate_store/DefaultMergeCallback.java @@ -0,0 +1,63 @@ +// SPDX-FileCopyrightText: 2022 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.certificate_store; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPPublicKeyRing; +import org.pgpainless.PGPainless; +import pgp.certificate_store.Certificate; +import pgp.certificate_store.MergeCallback; + +public class DefaultMergeCallback implements MergeCallback { + + @Override + public Certificate merge(Certificate data, Certificate existing) throws IOException { + // no existing certificate + if (existing == null) { + return data; + } + + if (!data.getFingerprint().equals(existing.getFingerprint())) { + throw new IllegalArgumentException("Certificate mismatch! " + + "Existing certificate: " + existing.getFingerprint() + ", New certificate: " + data.getFingerprint()); + } + + // existing and new certificates are equal + if (existing.getTag().equals(data.getTag())) { + return existing; + } + + PGPPublicKeyRing existingCertificate = PGPainless.readKeyRing().publicKeyRing(existing.getInputStream()); + PGPPublicKeyRing updatedCertificate = PGPainless.readKeyRing().publicKeyRing(data.getInputStream()); + + List mergedKeys = new ArrayList<>(); + + for (PGPPublicKey key : existingCertificate) { + PGPPublicKey kay = updatedCertificate.getPublicKey(key.getKeyID()); + if (kay != null) { + // TODO: get https://github.com/bcgit/bc-java/pull/1102 merged + PGPPublicKey mkay = PGPPublicKey.join(key, kay); + mergedKeys.add(mkay); + } else { + mergedKeys.add(key); + } + } + + for (PGPPublicKey key : updatedCertificate) { + PGPPublicKey kay = existingCertificate.getPublicKey(key.getKeyID()); + if (kay == null) { + mergedKeys.add(key); + } + } + + PGPPublicKeyRing merged = new PGPPublicKeyRing(mergedKeys); + return CertificateFactory.certificateFromPublicKeyRing(merged); + } + +}