Move and implement key-capable MergeCallbacks

This commit is contained in:
Paul Schaub 2022-08-12 15:43:22 +02:00
parent 7a02ec865b
commit 7b6162682e
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
5 changed files with 65 additions and 14 deletions

View file

@ -10,7 +10,7 @@ import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pgp.cert_d.cli.MergeCallbacks; import org.pgpainless.certificate_store.MergeCallbacks;
import pgp.cert_d.cli.PGPCertDCli; import pgp.cert_d.cli.PGPCertDCli;
import pgp.certificate_store.certificate.Certificate; import pgp.certificate_store.certificate.Certificate;
import pgp.certificate_store.exception.BadDataException; import pgp.certificate_store.exception.BadDataException;

View file

@ -6,7 +6,7 @@ package pgp.cert_d.cli.commands;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pgp.cert_d.cli.MergeCallbacks; import org.pgpainless.certificate_store.MergeCallbacks;
import pgp.cert_d.cli.PGPCertDCli; import pgp.cert_d.cli.PGPCertDCli;
import pgp.certificate_store.certificate.Certificate; import pgp.certificate_store.certificate.Certificate;
import pgp.certificate_store.exception.BadDataException; import pgp.certificate_store.exception.BadDataException;

View file

@ -15,7 +15,7 @@ import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
import org.pgpainless.util.Passphrase; import org.pgpainless.util.Passphrase;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pgp.cert_d.cli.MergeCallbacks; import org.pgpainless.certificate_store.MergeCallbacks;
import pgp.cert_d.cli.PGPCertDCli; import pgp.cert_d.cli.PGPCertDCli;
import pgp.certificate_store.exception.BadDataException; import pgp.certificate_store.exception.BadDataException;
import picocli.CommandLine; import picocli.CommandLine;

View file

@ -2,18 +2,21 @@
// //
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package pgp.cert_d.cli; package org.pgpainless.certificate_store;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPKeyRing;
import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.certificate_store.CertificateFactory;
import org.pgpainless.key.OpenPgpFingerprint; import org.pgpainless.key.OpenPgpFingerprint;
import pgp.certificate_store.certificate.KeyMaterial; import pgp.certificate_store.certificate.KeyMaterial;
import pgp.certificate_store.certificate.KeyMaterialMerger; import pgp.certificate_store.certificate.KeyMaterialMerger;
import pgp.certificate_store.exception.BadDataException;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
public class MergeCallbacks { public class MergeCallbacks {
@ -29,20 +32,66 @@ public class MergeCallbacks {
@Override @Override
public KeyMaterial merge(KeyMaterial data, KeyMaterial existing) throws IOException { public KeyMaterial merge(KeyMaterial data, KeyMaterial existing) throws IOException {
if (data == null) {
return existing;
}
if (existing == null) {
return data;
}
try { try {
PGPPublicKeyRing existingCert = PGPainless.readKeyRing().publicKeyRing(existing.getInputStream()); PGPKeyRing existingKeyRing = PGPainless.readKeyRing().keyRing(existing.getInputStream());
PGPPublicKeyRing updatedCert = PGPainless.readKeyRing().publicKeyRing(data.getInputStream()); PGPKeyRing updatedKeyRing = PGPainless.readKeyRing().keyRing(data.getInputStream());
PGPKeyRing mergedKeyRing;
if (existingKeyRing instanceof PGPPublicKeyRing) {
PGPPublicKeyRing existingCert = (PGPPublicKeyRing) existingKeyRing;
if (updatedKeyRing instanceof PGPPublicKeyRing) {
mergedKeyRing = PGPPublicKeyRing.join(existingCert, (PGPPublicKeyRing) updatedKeyRing);
} else if (updatedKeyRing instanceof PGPSecretKeyRing) {
PGPPublicKeyRing updatedPublicKeys = PGPainless.extractCertificate((PGPSecretKeyRing) updatedKeyRing);
PGPPublicKeyRing mergedPublicKeys = PGPPublicKeyRing.join(existingCert, updatedPublicKeys);
updatedKeyRing = PGPSecretKeyRing.replacePublicKeys((PGPSecretKeyRing) updatedKeyRing, mergedPublicKeys);
mergedKeyRing = updatedKeyRing;
} else {
throw new IOException(new BadDataException());
}
} else if (existingKeyRing instanceof PGPSecretKeyRing) {
PGPSecretKeyRing existingKey = (PGPSecretKeyRing) existingKeyRing;
PGPPublicKeyRing existingCert = PGPainless.extractCertificate(existingKey);
if (updatedKeyRing instanceof PGPPublicKeyRing) {
PGPPublicKeyRing updatedCert = (PGPPublicKeyRing) updatedKeyRing;
PGPPublicKeyRing mergedCert = PGPPublicKeyRing.join(existingCert, updatedCert); PGPPublicKeyRing mergedCert = PGPPublicKeyRing.join(existingCert, updatedCert);
mergedKeyRing = PGPSecretKeyRing.replacePublicKeys(existingKey, mergedCert);
} else if (updatedKeyRing instanceof PGPSecretKeyRing) {
PGPSecretKeyRing updatedKey = (PGPSecretKeyRing) updatedKeyRing;
if (!Arrays.equals(existingKey.getEncoded(), updatedKey.getEncoded())) {
// Merging secret keys is not supported.
return existing;
}
mergedKeyRing = existingKeyRing;
} else {
throw new IOException(new BadDataException());
}
} else {
throw new IOException(new BadDataException());
}
printOutDifferences(existingCert, mergedCert); printOutDifferences(existingKeyRing, mergedKeyRing);
if (mergedKeyRing instanceof PGPPublicKeyRing) {
return CertificateFactory.certificateFromPublicKeyRing((PGPPublicKeyRing) mergedKeyRing);
} else {
return KeyFactory.keyFromSecretKeyRing((PGPSecretKeyRing) mergedKeyRing);
}
return CertificateFactory.certificateFromPublicKeyRing(mergedCert);
} catch (PGPException e) { } catch (PGPException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
private void printOutDifferences(PGPPublicKeyRing existingCert, PGPPublicKeyRing mergedCert) { private void printOutDifferences(PGPKeyRing existingCert, PGPKeyRing mergedCert) {
int numSigsBefore = countSigs(existingCert); int numSigsBefore = countSigs(existingCert);
int numSigsAfter = countSigs(mergedCert); int numSigsAfter = countSigs(mergedCert);
int newSigs = numSigsAfter - numSigsBefore; int newSigs = numSigsAfter - numSigsBefore;
@ -74,9 +123,11 @@ public class MergeCallbacks {
} }
} }
private int countSigs(PGPPublicKeyRing keys) { private int countSigs(PGPKeyRing keys) {
int numSigs = 0; int numSigs = 0;
for (PGPPublicKey key : keys) { Iterator<PGPPublicKey> iterator = keys.getPublicKeys();
while (iterator.hasNext()) {
PGPPublicKey key = iterator.next();
numSigs += count(key.getSignatures()); numSigs += count(key.getSignatures());
} }
return numSigs; return numSigs;

View file

@ -12,7 +12,7 @@ allprojects {
logbackVersion = '1.2.11' logbackVersion = '1.2.11'
junitVersion = '5.8.2' junitVersion = '5.8.2'
mockitoVersion = '4.5.1' mockitoVersion = '4.5.1'
pgpainlessVersion = '1.3.5-SNAPSHOT' pgpainlessVersion = '1.3.5'
pgpCertDJavaVersion = '0.1.2-SNAPSHOT' pgpCertDJavaVersion = '0.1.2-SNAPSHOT'
picocliVersion = '4.6.3' picocliVersion = '4.6.3'
} }