aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/spongycastle/pg/src/main/java/org/spongycastle/openpgp/PGPEncryptedData.java
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/spongycastle/pg/src/main/java/org/spongycastle/openpgp/PGPEncryptedData.java')
-rw-r--r--libraries/spongycastle/pg/src/main/java/org/spongycastle/openpgp/PGPEncryptedData.java147
1 files changed, 147 insertions, 0 deletions
diff --git a/libraries/spongycastle/pg/src/main/java/org/spongycastle/openpgp/PGPEncryptedData.java b/libraries/spongycastle/pg/src/main/java/org/spongycastle/openpgp/PGPEncryptedData.java
new file mode 100644
index 000000000..7ff398101
--- /dev/null
+++ b/libraries/spongycastle/pg/src/main/java/org/spongycastle/openpgp/PGPEncryptedData.java
@@ -0,0 +1,147 @@
+package org.spongycastle.openpgp;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.spongycastle.bcpg.InputStreamPacket;
+import org.spongycastle.bcpg.SymmetricEncIntegrityPacket;
+import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
+import org.spongycastle.openpgp.operator.PGPDigestCalculator;
+import org.spongycastle.util.Arrays;
+
+public abstract class PGPEncryptedData
+ implements SymmetricKeyAlgorithmTags
+{
+ protected class TruncatedStream extends InputStream
+ {
+ int[] lookAhead = new int[22];
+ int bufPtr;
+ InputStream in;
+
+ TruncatedStream(
+ InputStream in)
+ throws IOException
+ {
+ for (int i = 0; i != lookAhead.length; i++)
+ {
+ if ((lookAhead[i] = in.read()) < 0)
+ {
+ throw new EOFException();
+ }
+ }
+
+ bufPtr = 0;
+ this.in = in;
+ }
+
+ public int read()
+ throws IOException
+ {
+ int ch = in.read();
+
+ if (ch >= 0)
+ {
+ int c = lookAhead[bufPtr];
+
+ lookAhead[bufPtr] = ch;
+ bufPtr = (bufPtr + 1) % lookAhead.length;
+
+ return c;
+ }
+
+ return -1;
+ }
+
+ int[] getLookAhead()
+ {
+ int[] tmp = new int[lookAhead.length];
+ int count = 0;
+
+ for (int i = bufPtr; i != lookAhead.length; i++)
+ {
+ tmp[count++] = lookAhead[i];
+ }
+ for (int i = 0; i != bufPtr; i++)
+ {
+ tmp[count++] = lookAhead[i];
+ }
+
+ return tmp;
+ }
+ }
+
+ InputStreamPacket encData;
+ InputStream encStream;
+ TruncatedStream truncStream;
+ PGPDigestCalculator integrityCalculator;
+
+ PGPEncryptedData(
+ InputStreamPacket encData)
+ {
+ this.encData = encData;
+ }
+
+ /**
+ * Return the raw input stream for the data stream.
+ *
+ * @return InputStream
+ */
+ public InputStream getInputStream()
+ {
+ return encData.getInputStream();
+ }
+
+ /**
+ * Return true if the message is integrity protected.
+ * @return true if there is a modification detection code package associated with this stream
+ */
+ public boolean isIntegrityProtected()
+ {
+ return (encData instanceof SymmetricEncIntegrityPacket);
+ }
+
+ /**
+ * Note: This can only be called after the message has been read.
+ *
+ * @return true if the message verifies, false otherwise.
+ * @throws PGPException if the message is not integrity protected.
+ */
+ public boolean verify()
+ throws PGPException, IOException
+ {
+ if (!this.isIntegrityProtected())
+ {
+ throw new PGPException("data not integrity protected.");
+ }
+
+ //
+ // make sure we are at the end.
+ //
+ while (encStream.read() >= 0)
+ {
+ // do nothing
+ }
+
+ //
+ // process the MDC packet
+ //
+ int[] lookAhead = truncStream.getLookAhead();
+
+ OutputStream dOut = integrityCalculator.getOutputStream();
+
+ dOut.write((byte)lookAhead[0]);
+ dOut.write((byte)lookAhead[1]);
+
+ byte[] digest = integrityCalculator.getDigest();
+ byte[] streamDigest = new byte[digest.length];
+
+ for (int i = 0; i != streamDigest.length; i++)
+ {
+ streamDigest[i] = (byte)lookAhead[i + 2];
+ }
+
+ return Arrays.constantTimeAreEqual(digest, streamDigest);
+ }
+}