Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pg/src/main/java/org/spongycastle/openpgp/PGPEncryptedData.java')
-rw-r--r--pg/src/main/java/org/spongycastle/openpgp/PGPEncryptedData.java165
1 files changed, 165 insertions, 0 deletions
diff --git a/pg/src/main/java/org/spongycastle/openpgp/PGPEncryptedData.java b/pg/src/main/java/org/spongycastle/openpgp/PGPEncryptedData.java
new file mode 100644
index 00000000..6f5f4043
--- /dev/null
+++ b/pg/src/main/java/org/spongycastle/openpgp/PGPEncryptedData.java
@@ -0,0 +1,165 @@
+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.PGPDataDecryptor;
+import org.spongycastle.openpgp.operator.PGPDataDecryptorFactory;
+import org.spongycastle.openpgp.operator.PGPDigestCalculator;
+import org.spongycastle.util.Arrays;
+
+/**
+ * A PGP encrypted data object.
+ * <p/>
+ * Encrypted data packets are decrypted using a {@link PGPDataDecryptor} obtained from a
+ * {@link PGPDataDecryptorFactory}.
+ */
+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.
+ * <p/>
+ * Note this stream is shared with all other encryption methods in the same
+ * {@link PGPEncryptedDataList} and with any decryption methods in sub-classes, so consuming
+ * this stream will affect decryption.
+ *
+ * @return the encrypted data in this packet.
+ */
+ public InputStream getInputStream()
+ {
+ return encData.getInputStream();
+ }
+
+ /**
+ * Checks whether the packet is integrity protected.
+ *
+ * @return <code>true</code> if there is a modification detection code package associated with
+ * this stream
+ */
+ public boolean isIntegrityProtected()
+ {
+ return (encData instanceof SymmetricEncIntegrityPacket);
+ }
+
+ /**
+ * Verifies the integrity of the packet against the modification detection code associated with
+ * it in the stream.
+ * <p/>
+ * Note: This can only be called after the message has been read.
+ *
+ * @return <code>true</code> if the message verifies, <code>false</code> otherwise.
+ * @throws PGPException if the message is not {@link #isIntegrityProtected() 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);
+ }
+}