mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-23 03:17:58 +01:00
Add option to force handling of data as non-openpgp
This commit is contained in:
parent
8172aa1083
commit
230725f6ff
3 changed files with 38 additions and 37 deletions
|
@ -36,6 +36,7 @@ public class ConsumerOptions {
|
|||
|
||||
|
||||
private boolean ignoreMDCErrors = false;
|
||||
private boolean forceNonOpenPgpData = false;
|
||||
|
||||
private Date verifyNotBefore = null;
|
||||
private Date verifyNotAfter = new Date();
|
||||
|
@ -296,6 +297,21 @@ public class ConsumerOptions {
|
|||
return ignoreMDCErrors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force PGPainless to handle the data provided by the {@link InputStream} as non-OpenPGP data.
|
||||
* This workaround might come in handy if PGPainless accidentally mistakes the data for binary OpenPGP data.
|
||||
*
|
||||
* @return options
|
||||
*/
|
||||
public ConsumerOptions forceNonOpenPgpData() {
|
||||
this.forceNonOpenPgpData = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
boolean isForceNonOpenPgpData() {
|
||||
return forceNonOpenPgpData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the {@link MissingKeyPassphraseStrategy}.
|
||||
* This strategy defines, how missing passphrases for unlocking secret keys are handled.
|
||||
|
|
|
@ -134,7 +134,7 @@ public final class DecryptionStreamFactory {
|
|||
PGPObjectFactory objectFactory;
|
||||
|
||||
// Non-OpenPGP data. We are probably verifying detached signatures
|
||||
if (openPgpIn.isNonOpenPgp()) {
|
||||
if (openPgpIn.isNonOpenPgp() || options.isForceNonOpenPgpData()) {
|
||||
outerDecodingStream = openPgpIn;
|
||||
pgpInStream = wrapInVerifySignatureStream(outerDecodingStream, null);
|
||||
return new DecryptionStream(pgpInStream, resultBuilder, integrityProtectedEncryptedInputStream, null);
|
||||
|
|
|
@ -18,7 +18,7 @@ public class OpenPgpInputStream extends BufferedInputStream {
|
|||
private static final byte[] ARMOR_HEADER = "-----BEGIN PGP ".getBytes(Charset.forName("UTF8"));
|
||||
|
||||
// Buffer beginning bytes of the data
|
||||
public static final int MAX_BUFFER_SIZE = 8192;
|
||||
public static final int MAX_BUFFER_SIZE = 8192 * 2;
|
||||
|
||||
private final byte[] buffer;
|
||||
private final int bufferLen;
|
||||
|
@ -53,6 +53,14 @@ public class OpenPgpInputStream extends BufferedInputStream {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is still brittle.
|
||||
* Basically we try to parse OpenPGP packets from the buffer.
|
||||
* If we run into exceptions, then we know that the data is non-OpenPGP'ish.
|
||||
*
|
||||
* This breaks down though if we read plausible garbage where the data accidentally makes sense,
|
||||
* or valid, yet incomplete packets (remember, we are still only working on a portion of the data).
|
||||
*/
|
||||
private void determineIsBinaryOpenPgp() {
|
||||
if (bufferLen == -1) {
|
||||
// Empty data
|
||||
|
@ -62,47 +70,24 @@ public class OpenPgpInputStream extends BufferedInputStream {
|
|||
try {
|
||||
ByteArrayInputStream bufferIn = new ByteArrayInputStream(buffer, 0, bufferLen);
|
||||
PGPObjectFactory objectFactory = ImplementationFactory.getInstance().getPGPObjectFactory(bufferIn);
|
||||
|
||||
boolean containsPackets = false;
|
||||
while (objectFactory.nextObject() != null) {
|
||||
// read all packets in buffer
|
||||
containsPackets = true;
|
||||
// read all packets in buffer - hope to confirm invalid data via thrown IOExceptions
|
||||
}
|
||||
containsOpenPgpPackets = true;
|
||||
containsOpenPgpPackets = containsPackets;
|
||||
|
||||
} catch (IOException e) {
|
||||
if (e.getMessage().contains("premature end of stream in PartialInputStream")) {
|
||||
// We *probably* hit valid, but large OpenPGP data
|
||||
// This is not an optimal way of determining the nature of data, but probably the best
|
||||
// we can get from BC.
|
||||
containsOpenPgpPackets = true;
|
||||
}
|
||||
// else: seemingly random, non-OpenPGP data
|
||||
}
|
||||
}
|
||||
String msg = e.getMessage();
|
||||
|
||||
private boolean startsWith(byte[] bytes, byte[] subsequence, int bufferLen) {
|
||||
return indexOfSubsequence(bytes, subsequence, bufferLen) == 0;
|
||||
}
|
||||
// If true, we *probably* hit valid, but large OpenPGP data (not sure though) :/
|
||||
// Otherwise we hit garbage and can be sure that this is no OpenPGP data \o/
|
||||
containsOpenPgpPackets = (msg != null && msg.contains("premature end of stream in PartialInputStream"));
|
||||
|
||||
private int indexOfSubsequence(byte[] bytes, byte[] subsequence, int bufferLen) {
|
||||
if (bufferLen == -1) {
|
||||
return -1;
|
||||
// This is not an optimal way of determining the nature of data, but probably the best
|
||||
// we can do :/
|
||||
}
|
||||
// Naive implementation
|
||||
// TODO: Could be improved by using e.g. Knuth-Morris-Pratt algorithm.
|
||||
for (int i = 0; i < bufferLen; i++) {
|
||||
if ((i + subsequence.length) <= bytes.length) {
|
||||
boolean found = true;
|
||||
for (int j = 0; j < subsequence.length; j++) {
|
||||
if (bytes[i + j] != subsequence[j]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private boolean startsWithIgnoringWhitespace(byte[] bytes, byte[] subsequence, int bufferLen) {
|
||||
|
|
Loading…
Reference in a new issue