diff --git a/crypto/src/bcpg/ECPublicBCPGKey.cs b/crypto/src/bcpg/ECPublicBCPGKey.cs
index c473139e7..df19caac3 100644
--- a/crypto/src/bcpg/ECPublicBCPGKey.cs
+++ b/crypto/src/bcpg/ECPublicBCPGKey.cs
@@ -81,10 +81,10 @@ namespace Org.BouncyCastle.Bcpg
BcpgInputStream bcpgIn)
{
int length = bcpgIn.ReadByte();
+ if (length < 0)
+ throw new EndOfStreamException();
if (length == 0 || length == 0xFF)
- {
- throw new IOException("future extensions not yet implemented.");
- }
+ throw new IOException("future extensions not yet implemented");
byte[] buffer = new byte[length + 2];
bcpgIn.ReadFully(buffer, 2, buffer.Length - 2);
diff --git a/crypto/src/bcpg/SignatureSubpacketsReader.cs b/crypto/src/bcpg/SignatureSubpacketsReader.cs
index 80bedb07c..45dc96885 100644
--- a/crypto/src/bcpg/SignatureSubpacketsReader.cs
+++ b/crypto/src/bcpg/SignatureSubpacketsReader.cs
@@ -52,6 +52,9 @@ namespace Org.BouncyCastle.Bcpg
if (tag < 0)
throw new EndOfStreamException("unexpected EOF reading signature sub packet");
+ if (bodyLen <= 0)
+ throw new EndOfStreamException("out of range data found in signature sub packet");
+
byte[] data = new byte[bodyLen - 1];
//
diff --git a/crypto/src/openpgp/PGPKeyRing.cs b/crypto/src/openpgp/PGPKeyRing.cs
index 6426f3f25..425eaca56 100644
--- a/crypto/src/openpgp/PGPKeyRing.cs
+++ b/crypto/src/openpgp/PGPKeyRing.cs
@@ -16,7 +16,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
BcpgInputStream bcpgInput)
{
return (bcpgInput.NextPacketTag() == PacketTag.Trust)
- ? (TrustPacket) bcpgInput.ReadPacket()
+ ? (TrustPacket)bcpgInput.ReadPacket()
: null;
}
diff --git a/crypto/src/openpgp/PgpCompressedData.cs b/crypto/src/openpgp/PgpCompressedData.cs
index e64a17c9c..c841b7474 100644
--- a/crypto/src/openpgp/PgpCompressedData.cs
+++ b/crypto/src/openpgp/PgpCompressedData.cs
@@ -14,7 +14,11 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
public PgpCompressedData(
BcpgInputStream bcpgInput)
{
- data = (CompressedDataPacket) bcpgInput.ReadPacket();
+ Packet packet = bcpgInput.ReadPacket();
+ if (!(packet is CompressedDataPacket))
+ throw new IOException("unexpected packet in stream: " + packet);
+
+ this.data = (CompressedDataPacket)packet;
}
/// <summary>The algorithm used for compression</summary>
diff --git a/crypto/src/openpgp/PgpEncryptedDataList.cs b/crypto/src/openpgp/PgpEncryptedDataList.cs
index 8dded7c05..1f605dab5 100644
--- a/crypto/src/openpgp/PgpEncryptedDataList.cs
+++ b/crypto/src/openpgp/PgpEncryptedDataList.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections;
+using System.IO;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
@@ -10,10 +11,10 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
public class PgpEncryptedDataList
: PgpObject
{
- private IList list = Platform.CreateArrayList();
- private InputStreamPacket data;
+ private readonly IList list = Platform.CreateArrayList();
+ private readonly InputStreamPacket data;
- public PgpEncryptedDataList(
+ public PgpEncryptedDataList(
BcpgInputStream bcpgInput)
{
while (bcpgInput.NextPacketTag() == PacketTag.PublicKeyEncryptedSession
@@ -22,9 +23,13 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
list.Add(bcpgInput.ReadPacket());
}
- data = (InputStreamPacket)bcpgInput.ReadPacket();
+ Packet packet = bcpgInput.ReadPacket();
+ if (!(packet is InputStreamPacket))
+ throw new IOException("unexpected packet in stream: " + packet);
- for (int i = 0; i != list.Count; i++)
+ this.data = (InputStreamPacket)packet;
+
+ for (int i = 0; i != list.Count; i++)
{
if (list[i] is SymmetricKeyEncSessionPacket)
{
diff --git a/crypto/src/openpgp/PgpLiteralData.cs b/crypto/src/openpgp/PgpLiteralData.cs
index 79bbc3984..d1b7b4a4d 100644
--- a/crypto/src/openpgp/PgpLiteralData.cs
+++ b/crypto/src/openpgp/PgpLiteralData.cs
@@ -16,12 +16,16 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
/// <summary>The special name indicating a "for your eyes only" packet.</summary>
public const string Console = "_CONSOLE";
- private LiteralDataPacket data;
+ private readonly LiteralDataPacket data;
public PgpLiteralData(
BcpgInputStream bcpgInput)
{
- data = (LiteralDataPacket) bcpgInput.ReadPacket();
+ Packet packet = bcpgInput.ReadPacket();
+ if (!(packet is LiteralDataPacket))
+ throw new IOException("unexpected packet in stream: " + packet);
+
+ this.data = (LiteralDataPacket)packet;
}
/// <summary>The format of the data stream - Binary or Text</summary>
diff --git a/crypto/src/openpgp/PgpMarker.cs b/crypto/src/openpgp/PgpMarker.cs
index 733e4e959..7257767ec 100644
--- a/crypto/src/openpgp/PgpMarker.cs
+++ b/crypto/src/openpgp/PgpMarker.cs
@@ -1,3 +1,6 @@
+using System;
+using System.IO;
+
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
/// <remarks>
@@ -7,12 +10,16 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
public class PgpMarker
: PgpObject
{
- private readonly MarkerPacket p;
+ private readonly MarkerPacket data;
public PgpMarker(
- BcpgInputStream bcpgIn)
+ BcpgInputStream bcpgInput)
{
- p = (MarkerPacket) bcpgIn.ReadPacket();
+ Packet packet = bcpgInput.ReadPacket();
+ if (!(packet is MarkerPacket))
+ throw new IOException("unexpected packet in stream: " + packet);
+
+ this.data = (MarkerPacket)packet;
}
}
}
diff --git a/crypto/src/openpgp/PgpOnePassSignature.cs b/crypto/src/openpgp/PgpOnePassSignature.cs
index 68fc5994d..2fab5137e 100644
--- a/crypto/src/openpgp/PgpOnePassSignature.cs
+++ b/crypto/src/openpgp/PgpOnePassSignature.cs
@@ -9,14 +9,22 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
/// <remarks>A one pass signature object.</remarks>
public class PgpOnePassSignature
{
- private OnePassSignaturePacket sigPack;
- private int signatureType;
+ private static OnePassSignaturePacket Cast(Packet packet)
+ {
+ if (!(packet is OnePassSignaturePacket))
+ throw new IOException("unexpected packet in stream: " + packet);
+
+ return (OnePassSignaturePacket)packet;
+ }
+
+ private readonly OnePassSignaturePacket sigPack;
+ private readonly int signatureType;
private ISigner sig;
private byte lastb;
internal PgpOnePassSignature(
BcpgInputStream bcpgInput)
- : this((OnePassSignaturePacket) bcpgInput.ReadPacket())
+ : this(Cast(bcpgInput.ReadPacket()))
{
}
diff --git a/crypto/src/openpgp/PgpPublicKeyEncryptedData.cs b/crypto/src/openpgp/PgpPublicKeyEncryptedData.cs
index c2a351182..78d4d575c 100644
--- a/crypto/src/openpgp/PgpPublicKeyEncryptedData.cs
+++ b/crypto/src/openpgp/PgpPublicKeyEncryptedData.cs
@@ -197,12 +197,17 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
byte[] enc = secKeyData[0];
int pLen = ((((enc[0] & 0xff) << 8) + (enc[1] & 0xff)) + 7) / 8;
- byte[] pEnc = new byte[pLen];
+ if ((2 + pLen + 1) > enc.Length)
+ throw new PgpException("encoded length out of range");
+ byte[] pEnc = new byte[pLen];
Array.Copy(enc, 2, pEnc, 0, pLen);
- byte[] keyEnc = new byte[enc[pLen + 2]];
+ int keyLen = enc[pLen + 2];
+ if ((2 + pLen + 1 + keyLen) > enc.length)
+ throw new PgpException("encoded length out of range");
+ byte[] keyEnc = new byte[keyLen];
Array.Copy(enc, 2 + pLen + 1, keyEnc, 0, keyEnc.Length);
ECPoint publicPoint = x9Params.Curve.DecodePoint(pEnc);
diff --git a/crypto/src/openpgp/PgpPublicKeyRing.cs b/crypto/src/openpgp/PgpPublicKeyRing.cs
index 92464d64f..c214623b4 100644
--- a/crypto/src/openpgp/PgpPublicKeyRing.cs
+++ b/crypto/src/openpgp/PgpPublicKeyRing.cs
@@ -45,7 +45,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
+ "tag 0x" + ((int)initialTag).ToString("X"));
}
- PublicKeyPacket pubPk = (PublicKeyPacket) bcpgInput.ReadPacket();
+ PublicKeyPacket pubPk = ReadPublicKeyPacket(bcpgInput);
TrustPacket trustPk = ReadOptionalTrustPacket(bcpgInput);
// direct signatures and revocations
@@ -186,9 +186,18 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
return found ? new PgpPublicKeyRing(keys) : null;
}
+ internal static PublicKeyPacket ReadPublicKeyPacket(BcpgInputStream bcpgInput)
+ {
+ Packet packet = bcpgInput.ReadPacket();
+ if (!(packet is PublicKeyPacket))
+ throw new IOException("unexpected packet in stream: " + packet);
+
+ return (PublicKeyPacket)packet;
+ }
+
internal static PgpPublicKey ReadSubkey(BcpgInputStream bcpgInput)
{
- PublicKeyPacket pk = (PublicKeyPacket) bcpgInput.ReadPacket();
+ PublicKeyPacket pk = ReadPublicKeyPacket(bcpgInput);
TrustPacket kTrust = ReadOptionalTrustPacket(bcpgInput);
// PGP 8 actually leaves out the signature.
diff --git a/crypto/src/openpgp/PgpSecretKey.cs b/crypto/src/openpgp/PgpSecretKey.cs
index b3986073d..01cceadbb 100644
--- a/crypto/src/openpgp/PgpSecretKey.cs
+++ b/crypto/src/openpgp/PgpSecretKey.cs
@@ -536,12 +536,15 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
for (int i = 0; i != 4; i++)
{
- int encLen = (((encData[pos] << 8) | (encData[pos + 1] & 0xff)) + 7) / 8;
+ int encLen = ((((encData[pos] & 0xff) << 8) | (encData[pos + 1] & 0xff)) + 7) / 8;
data[pos] = encData[pos];
data[pos + 1] = encData[pos + 1];
pos += 2;
+ if (encLen > (encData.Length - pos))
+ throw new PgpException("out of range encLen found in encData");
+
byte[] tmp = RecoverKeyData(encAlgorithm, "/CFB/NoPadding", key, iv, encData, pos, encLen);
Array.Copy(tmp, 0, data, pos, encLen);
pos += encLen;
@@ -984,11 +987,14 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
int pos = 0;
for (int i = 0; i != 4; i++)
{
- int encLen = (((rawKeyData[pos] << 8) | (rawKeyData[pos + 1] & 0xff)) + 7) / 8;
+ int encLen = ((((rawKeyData[pos] & 0xff) << 8) | (rawKeyData[pos + 1] & 0xff)) + 7) / 8;
keyData[pos] = rawKeyData[pos];
keyData[pos + 1] = rawKeyData[pos + 1];
+ if (encLen > (rawKeyData.Length - (pos + 2)))
+ throw new PgpException("out of range encLen found in rawKeyData");
+
byte[] tmp;
if (i == 0)
{
diff --git a/crypto/src/openpgp/PgpSignature.cs b/crypto/src/openpgp/PgpSignature.cs
index c8c541bef..fb6244725 100644
--- a/crypto/src/openpgp/PgpSignature.cs
+++ b/crypto/src/openpgp/PgpSignature.cs
@@ -12,6 +12,14 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
/// <remarks>A PGP signature object.</remarks>
public class PgpSignature
{
+ private static SignaturePacket Cast(Packet packet)
+ {
+ if (!(packet is SignaturePacket))
+ throw new IOException("unexpected packet in stream: " + packet);
+
+ return (SignaturePacket)packet;
+ }
+
public const int BinaryDocument = 0x00;
public const int CanonicalTextDocument = 0x01;
public const int StandAlone = 0x02;
@@ -38,7 +46,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
internal PgpSignature(
BcpgInputStream bcpgInput)
- : this((SignaturePacket)bcpgInput.ReadPacket())
+ : this(Cast(bcpgInput.ReadPacket()))
{
}
diff --git a/crypto/src/openpgp/PgpUtilities.cs b/crypto/src/openpgp/PgpUtilities.cs
index a3efd591f..fd5ab6232 100644
--- a/crypto/src/openpgp/PgpUtilities.cs
+++ b/crypto/src/openpgp/PgpUtilities.cs
@@ -27,17 +27,20 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
try
{
- Asn1Sequence s = (Asn1Sequence) Asn1Object.FromByteArray(encoding);
+ Asn1Sequence s = Asn1Sequence.GetInstance(encoding);
- i1 = (DerInteger) s[0];
- i2 = (DerInteger) s[1];
+ i1 = DerInteger.GetInstance(s[0]);
+ i2 = DerInteger.GetInstance(s[1]);
}
- catch (IOException e)
+ catch (Exception e)
{
throw new PgpException("exception encoding signature", e);
}
- return new MPInteger[]{ new MPInteger(i1.Value), new MPInteger(i2.Value) };
+ return new MPInteger[]{
+ new MPInteger(i1.Value),
+ new MPInteger(i2.Value)
+ };
}
public static MPInteger[] RsaSigToMpi(
|