mirror of
https://codeberg.org/PGPainless/cert-d-pgpainless.git
synced 2024-12-22 13:17:58 +01:00
Use PGPPublicKeyRing.join(first, second) for proper MergeCallback
This commit is contained in:
parent
adf9e534c4
commit
32f2bbede7
3 changed files with 90 additions and 25 deletions
|
@ -0,0 +1,85 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package pgp.cert_d.cli.commands;
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
|
import org.pgpainless.PGPainless;
|
||||||
|
import org.pgpainless.certificate_store.CertificateFactory;
|
||||||
|
import org.pgpainless.key.OpenPgpFingerprint;
|
||||||
|
import pgp.certificate_store.Certificate;
|
||||||
|
import pgp.certificate_store.MergeCallback;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
public class DefaultMergeCallback implements MergeCallback {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Certificate merge(Certificate data, Certificate existing) throws IOException {
|
||||||
|
try {
|
||||||
|
PGPPublicKeyRing existingCert = PGPainless.readKeyRing().publicKeyRing(existing.getInputStream());
|
||||||
|
PGPPublicKeyRing updatedCert = PGPainless.readKeyRing().publicKeyRing(data.getInputStream());
|
||||||
|
PGPPublicKeyRing mergedCert = PGPPublicKeyRing.join(existingCert, updatedCert);
|
||||||
|
|
||||||
|
printOutDifferences(existingCert, mergedCert);
|
||||||
|
|
||||||
|
return CertificateFactory.certificateFromPublicKeyRing(mergedCert);
|
||||||
|
} catch (PGPException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printOutDifferences(PGPPublicKeyRing existingCert, PGPPublicKeyRing mergedCert) {
|
||||||
|
int numSigsBefore = countSigs(existingCert);
|
||||||
|
int numSigsAfter = countSigs(mergedCert);
|
||||||
|
int newSigs = numSigsAfter - numSigsBefore;
|
||||||
|
int numUidsBefore = count(existingCert.getPublicKey().getUserIDs());
|
||||||
|
int numUidsAfter = count(mergedCert.getPublicKey().getUserIDs());
|
||||||
|
int newUids = numUidsAfter - numUidsBefore;
|
||||||
|
|
||||||
|
if (!existingCert.equals(mergedCert)) {
|
||||||
|
OpenPgpFingerprint fingerprint = OpenPgpFingerprint.of(mergedCert);
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(String.format("Certificate %s has", fingerprint));
|
||||||
|
if (newSigs != 0) {
|
||||||
|
sb.append(String.format(" %d new signatures", newSigs));
|
||||||
|
}
|
||||||
|
if (newUids != 0) {
|
||||||
|
if (newSigs != 0) {
|
||||||
|
sb.append(" and");
|
||||||
|
}
|
||||||
|
sb.append(String.format(" %d new UIDs", newUids));
|
||||||
|
}
|
||||||
|
if (newSigs == 0 && newUids == 0) {
|
||||||
|
sb.append(" changed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// In this case it is okay to print to stdout, since we are a CLI app
|
||||||
|
// CHECKSTYLE:OFF
|
||||||
|
System.out.println(sb);
|
||||||
|
// CHECKSTYLE:ON
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int countSigs(PGPPublicKeyRing keys) {
|
||||||
|
int numSigs = 0;
|
||||||
|
for (PGPPublicKey key : keys) {
|
||||||
|
numSigs += count(key.getSignatures());
|
||||||
|
}
|
||||||
|
return numSigs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Use CollectionUtils.count() once available
|
||||||
|
private static int count(Iterator<?> iterator) {
|
||||||
|
int num = 0;
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
iterator.next();
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,8 +4,6 @@
|
||||||
|
|
||||||
package pgp.cert_d.cli.commands;
|
package pgp.cert_d.cli.commands;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import pgp.cert_d.cli.PGPCertDCli;
|
import pgp.cert_d.cli.PGPCertDCli;
|
||||||
|
@ -14,27 +12,19 @@ import pgp.certificate_store.MergeCallback;
|
||||||
import pgp.certificate_store.exception.BadDataException;
|
import pgp.certificate_store.exception.BadDataException;
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
@CommandLine.Command(name = "import",
|
@CommandLine.Command(name = "import",
|
||||||
description = "Import or update a certificate")
|
description = "Import or update a certificate")
|
||||||
public class Import implements Runnable {
|
public class Import implements Runnable {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(Import.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(Import.class);
|
||||||
|
private final MergeCallback mergeCallback = new DefaultMergeCallback();
|
||||||
// TODO: Replace with proper merge callback
|
|
||||||
private final MergeCallback dummyMerge = new MergeCallback() {
|
|
||||||
@Override
|
|
||||||
public Certificate merge(Certificate data, Certificate existing) throws IOException {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Certificate certificate = PGPCertDCli.getCertificateDirectory().insertCertificate(System.in, dummyMerge);
|
Certificate certificate = PGPCertDCli.getCertificateDirectory().insertCertificate(System.in, mergeCallback);
|
||||||
// CHECKSTYLE:OFF
|
|
||||||
System.out.println(certificate.getFingerprint());
|
|
||||||
// CHECKSTYLE:ON
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOGGER.error("IO-Error.", e);
|
LOGGER.error("IO-Error.", e);
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
|
|
|
@ -24,14 +24,7 @@ import java.io.IOException;
|
||||||
public class MultiImport implements Runnable {
|
public class MultiImport implements Runnable {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(MultiImport.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(MultiImport.class);
|
||||||
|
private final MergeCallback dummyMerge = new DefaultMergeCallback();
|
||||||
// TODO: Replace with proper merge callback
|
|
||||||
private final MergeCallback dummyMerge = new MergeCallback() {
|
|
||||||
@Override
|
|
||||||
public Certificate merge(Certificate data, Certificate existing) throws IOException {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -41,9 +34,6 @@ public class MultiImport implements Runnable {
|
||||||
ByteArrayInputStream certIn = new ByteArrayInputStream(cert.getEncoded());
|
ByteArrayInputStream certIn = new ByteArrayInputStream(cert.getEncoded());
|
||||||
Certificate certificate = PGPCertDCli.getCertificateDirectory()
|
Certificate certificate = PGPCertDCli.getCertificateDirectory()
|
||||||
.insertCertificate(certIn, dummyMerge);
|
.insertCertificate(certIn, dummyMerge);
|
||||||
// CHECKSTYLE:OFF
|
|
||||||
System.out.println(certificate.getFingerprint());
|
|
||||||
// CHECKSTYLE:ON
|
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOGGER.error("IO-Error.", e);
|
LOGGER.error("IO-Error.", e);
|
||||||
|
|
Loading…
Reference in a new issue