diff options
author | Vincent Breitmoser <valodim@mugenguild.com> | 2015-09-29 20:20:26 +0200 |
---|---|---|
committer | Vincent Breitmoser <valodim@mugenguild.com> | 2015-09-30 14:41:09 +0200 |
commit | f461d6b1d83604d6752ac97128403ff2a34ddec4 (patch) | |
tree | 896252aea18b684a92438da72ff8f662a842fb32 | |
parent | 5b6c04cbfb08b021864c70478a25b13543e86206 (diff) | |
download | open-keychain-f461d6b1d83604d6752ac97128403ff2a34ddec4.tar.gz open-keychain-f461d6b1d83604d6752ac97128403ff2a34ddec4.tar.bz2 open-keychain-f461d6b1d83604d6752ac97128403ff2a34ddec4.zip |
decryptverify: add trivial detection of pgp ascii-armored data
2 files changed, 36 insertions, 2 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java index 36b4f5e1e..055f84b4d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java @@ -535,14 +535,14 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp if (!"".equals(originalFilename)) { log.add(LogType.MSG_DC_CLEAR_META_FILE, indent + 1, originalFilename); } - log.add(LogType.MSG_DC_CLEAR_META_MIME, indent + 1, - mimeType); log.add(LogType.MSG_DC_CLEAR_META_TIME, indent + 1, new Date(literalData.getModificationTime().getTime()).toString()); // return here if we want to decrypt the metadata only if (input.isDecryptMetadataOnly()) { + log.add(LogType.MSG_DC_CLEAR_META_MIME, indent + 1, mimeType); + // this operation skips the entire stream to find the data length! Long originalSize = literalData.findDataLength(); @@ -584,6 +584,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp long wholeSize = 0; // TODO inputData.getSize() - inputData.getStreamPosition(); int length; byte[] buffer = new byte[1 << 16]; + byte[] firstBytes = new byte[48]; while ((length = dataIn.read(buffer)) > 0) { // Log.d(Constants.TAG, "read bytes: " + length); if (out != null) { @@ -595,7 +596,13 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp signature.update(buffer, 0, length); } + // note down first couple of bytes for "magic bytes" file type detection + if (alreadyWritten == 0) { + System.arraycopy(buffer, 0, firstBytes, 0, length > firstBytes.length ? firstBytes.length : length); + } + alreadyWritten += length; + if (wholeSize > 0) { long progress = 100 * alreadyWritten / wholeSize; // stop at 100% for wrong file sizes... @@ -607,6 +614,17 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp // TODO: slow annealing to fake a progress? } + // special treatment to detect pgp mime types + if (matchesPrefix(firstBytes, "-----BEGIN PGP PUBLIC KEY BLOCK-----") + || matchesPrefix(firstBytes, "-----BEGIN PGP PRIVATE KEY BLOCK-----")) { + mimeType = "application/pgp-keys"; + } else if (matchesPrefix(firstBytes, "-----BEGIN PGP MESSAGE-----")) { + // this is NOT pgp/encrypted, see RFC 3156! + mimeType = "application/pgp-message"; + } + + log.add(LogType.MSG_DC_CLEAR_META_MIME, indent + 1, mimeType); + metadata = new OpenPgpMetadata( originalFilename, mimeType, literalData.getModificationTime().getTime(), alreadyWritten, charset); @@ -1291,4 +1309,17 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp String nl = System.getProperty("line.separator"); return nl.getBytes(); } + + /// Convenience method - Trivially checks if a byte array matches the bytes of a plain text string + // Assumes data.length >= needle.length() + static boolean matchesPrefix(byte[] data, String needle) { + byte[] needleBytes = needle.getBytes(); + for (int i = 0; i < needle.length(); i++) { + if (data[i] != needleBytes[i]) { + return false; + } + } + return true; + } + } diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java index 4d4915e8d..e88dc95fc 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java @@ -354,6 +354,9 @@ public class ExportTest { "backup_" + KeyFormattingUtils.convertKeyIdToHex(mStaticRing1.getMasterKeyId()) + ".pub.asc", result.getDecryptionMetadata().getFilename()); + assertEquals("mime type for pgp keys must be correctly detected", + "application/pgp-keys", result.getDecryptionMetadata().getMimeType()); + TestingUtils.assertArrayEqualsPrefix("exported data must start with ascii armor header", "-----BEGIN PGP PUBLIC KEY BLOCK-----\n".getBytes(), result.getOutputBytes()); TestingUtils.assertArrayEqualsSuffix("exported data must end with ascii armor header", |