diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/DecryptImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/DecryptImpl.java index f18ed732..11b20f82 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/DecryptImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/DecryptImpl.java @@ -52,22 +52,9 @@ public class DecryptImpl implements Decrypt { @Override public DecryptImpl verifyWithCert(InputStream certIn) throws SOPGPException.BadData, IOException { - try { - PGPPublicKeyRingCollection certs = PGPainless.readKeyRing().keyRingCollection(certIn, false) - .getPgpPublicKeyRingCollection(); - if (certs.size() == 0) { - throw new SOPGPException.BadData(new PGPException("No certificates provided.")); - } - + PGPPublicKeyRingCollection certs = KeyReader.readPublicKeys(certIn, true); + if (certs != null) { consumerOptions.addVerificationCerts(certs); - - } catch (IOException e) { - if (e.getMessage() != null && e.getMessage().startsWith("unknown object in stream:")) { - throw new SOPGPException.BadData(e); - } - throw e; - } catch (PGPException e) { - throw new SOPGPException.BadData(e); } return this; } @@ -102,23 +89,11 @@ public class DecryptImpl implements Decrypt { @Override public DecryptImpl withKey(InputStream keyIn) throws SOPGPException.BadData, IOException, SOPGPException.UnsupportedAsymmetricAlgo { - try { - PGPSecretKeyRingCollection secretKeyCollection = PGPainless.readKeyRing() - .secretKeyRingCollection(keyIn); - if (secretKeyCollection.size() == 0) { - throw new SOPGPException.BadData("No key data found."); - } - for (PGPSecretKeyRing key : secretKeyCollection) { - protector.addSecretKey(key); - consumerOptions.addDecryptionKey(key, protector); - } - } catch (IOException e) { - if (e.getMessage() != null && e.getMessage().startsWith("unknown object in stream:")) { - throw new SOPGPException.BadData(e); - } - throw e; - } catch (PGPException e) { - throw new SOPGPException.BadData(e); + PGPSecretKeyRingCollection secretKeyCollection = KeyReader.readSecretKeys(keyIn, true); + + for (PGPSecretKeyRing key : secretKeyCollection) { + protector.addSecretKey(key); + consumerOptions.addDecryptionKey(key, protector); } return this; } diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/DetachedVerifyImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/DetachedVerifyImpl.java index 1f9aa32b..3065addf 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/DetachedVerifyImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/DetachedVerifyImpl.java @@ -39,13 +39,8 @@ public class DetachedVerifyImpl implements DetachedVerify { } @Override - public DetachedVerify cert(InputStream cert) throws SOPGPException.BadData { - PGPPublicKeyRingCollection certificates; - try { - certificates = PGPainless.readKeyRing().publicKeyRingCollection(cert); - } catch (IOException | PGPException e) { - throw new SOPGPException.BadData(e); - } + public DetachedVerify cert(InputStream cert) throws SOPGPException.BadData, IOException { + PGPPublicKeyRingCollection certificates = KeyReader.readPublicKeys(cert, true); options.addVerificationCerts(certificates); return this; } diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/EncryptImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/EncryptImpl.java index 9658bd17..61a46731 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/EncryptImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/EncryptImpl.java @@ -58,28 +58,23 @@ public class EncryptImpl implements Encrypt { @Override public Encrypt signWith(InputStream keyIn) - throws SOPGPException.KeyCannotSign, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData { + throws SOPGPException.KeyCannotSign, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData, IOException { if (signingOptions == null) { signingOptions = SigningOptions.get(); } - - try { - PGPSecretKeyRingCollection keys = PGPainless.readKeyRing().secretKeyRingCollection(keyIn); - if (keys.size() != 1) { - throw new SOPGPException.BadData(new AssertionError("Exactly one secret key at a time expected. Got " + keys.size())); - } - PGPSecretKeyRing signingKey = keys.iterator().next(); - - KeyRingInfo info = PGPainless.inspectKeyRing(signingKey); - if (info.getSigningSubkeys().isEmpty()) { - throw new SOPGPException.KeyCannotSign("Key " + OpenPgpFingerprint.of(signingKey) + " cannot sign."); - } - - protector.addSecretKey(signingKey); - signingKeys.add(signingKey); - } catch (IOException | PGPException e) { - throw new SOPGPException.BadData(e); + PGPSecretKeyRingCollection keys = KeyReader.readSecretKeys(keyIn, true); + if (keys.size() != 1) { + throw new SOPGPException.BadData(new AssertionError("Exactly one secret key at a time expected. Got " + keys.size())); } + PGPSecretKeyRing signingKey = keys.iterator().next(); + + KeyRingInfo info = PGPainless.inspectKeyRing(signingKey); + if (info.getSigningSubkeys().isEmpty()) { + throw new SOPGPException.KeyCannotSign("Key " + OpenPgpFingerprint.of(signingKey) + " cannot sign."); + } + + protector.addSecretKey(signingKey); + signingKeys.add(signingKey); return this; } diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/ExtractCertImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/ExtractCertImpl.java index 16848383..5be3ad31 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/ExtractCertImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/ExtractCertImpl.java @@ -10,7 +10,6 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.List; -import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; @@ -32,21 +31,7 @@ public class ExtractCertImpl implements ExtractCert { @Override public Ready key(InputStream keyInputStream) throws IOException, SOPGPException.BadData { - PGPSecretKeyRingCollection keys; - try { - keys = PGPainless.readKeyRing().secretKeyRingCollection(keyInputStream); - } catch (IOException e) { - if (e.getMessage() != null && e.getMessage().startsWith("unknown object in stream:")) { - throw new SOPGPException.BadData(e); - } - throw e; - } catch (PGPException e) { - throw new IOException("Cannot read keys.", e); - } - - if (keys == null || keys.size() == 0) { - throw new SOPGPException.BadData(new PGPException("No key data found.")); - } + PGPSecretKeyRingCollection keys = KeyReader.readSecretKeys(keyInputStream, true); List certs = new ArrayList<>(); for (PGPSecretKeyRing key : keys) { diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineSignImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineSignImpl.java index 3bdc8fc3..c0bd29f4 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineSignImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineSignImpl.java @@ -51,19 +51,14 @@ public class InlineSignImpl implements InlineSign { @Override public InlineSign key(InputStream keyIn) throws SOPGPException.KeyCannotSign, SOPGPException.BadData, IOException { - try { - PGPSecretKeyRingCollection keys = PGPainless.readKeyRing().secretKeyRingCollection(keyIn); - - for (PGPSecretKeyRing key : keys) { - KeyRingInfo info = PGPainless.inspectKeyRing(key); - if (!info.isUsableForSigning()) { - throw new SOPGPException.KeyCannotSign("Key " + info.getFingerprint() + " does not have valid, signing capable subkeys."); - } - protector.addSecretKey(key); - signingKeys.add(key); + PGPSecretKeyRingCollection keys = KeyReader.readSecretKeys(keyIn, true); + for (PGPSecretKeyRing key : keys) { + KeyRingInfo info = PGPainless.inspectKeyRing(key); + if (!info.isUsableForSigning()) { + throw new SOPGPException.KeyCannotSign("Key " + info.getFingerprint() + " does not have valid, signing capable subkeys."); } - } catch (PGPException | KeyException e) { - throw new SOPGPException.BadData(e); + protector.addSecretKey(key); + signingKeys.add(key); } return this; } diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineVerifyImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineVerifyImpl.java index e9994f38..4af53685 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineVerifyImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineVerifyImpl.java @@ -42,13 +42,8 @@ public class InlineVerifyImpl implements InlineVerify { } @Override - public InlineVerify cert(InputStream cert) throws SOPGPException.BadData { - PGPPublicKeyRingCollection certificates; - try { - certificates = PGPainless.readKeyRing().publicKeyRingCollection(cert); - } catch (IOException | PGPException e) { - throw new SOPGPException.BadData(e); - } + public InlineVerify cert(InputStream cert) throws SOPGPException.BadData, IOException { + PGPPublicKeyRingCollection certificates = KeyReader.readPublicKeys(cert, true); options.addVerificationCerts(certificates); return this; } diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/KeyReader.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/KeyReader.java new file mode 100644 index 00000000..064a5e39 --- /dev/null +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/KeyReader.java @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: 2022 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.sop; + +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; +import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; +import org.pgpainless.PGPainless; +import sop.exception.SOPGPException; + +import java.io.IOException; +import java.io.InputStream; + +class KeyReader { + + static PGPSecretKeyRingCollection readSecretKeys(InputStream keyInputStream, boolean requireContent) + throws IOException, SOPGPException.BadData { + PGPSecretKeyRingCollection keys; + try { + keys = PGPainless.readKeyRing().secretKeyRingCollection(keyInputStream); + } catch (IOException e) { + String message = e.getMessage(); + if (message == null) { + throw e; + } + if (message.startsWith("unknown object in stream:") || + message.startsWith("invalid header encountered")) { + throw new SOPGPException.BadData(e); + } + throw e; + } catch (PGPException e) { + throw new IOException("Cannot read keys.", e); + } + + if (requireContent && (keys == null || keys.size() == 0)) { + throw new SOPGPException.BadData(new PGPException("No key data found.")); + } + + return keys; + } + + static PGPPublicKeyRingCollection readPublicKeys(InputStream certIn, boolean requireContent) throws IOException { + PGPPublicKeyRingCollection certs; + try { + certs = PGPainless.readKeyRing().publicKeyRingCollection(certIn); + } catch (IOException e) { + if (e.getMessage() != null && e.getMessage().startsWith("unknown object in stream:")) { + throw new SOPGPException.BadData(e); + } + throw e; + } catch (PGPException e) { + throw new SOPGPException.BadData(e); + } + if (requireContent && (certs == null || certs.size() == 0)) { + throw new SOPGPException.BadData(new PGPException("No cert data found.")); + } + return certs; + } +}