summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2021-10-12 17:27:28 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2021-10-12 17:27:28 +0700
commitc5065a21286ce0755cee38118b1e288898456f7e (patch)
treee641ffbe5f561c130c39231dd5ee7f4351e03d35
parentcompleted copy constructor in SignerInformation, fixed mutable issue for SET ... (diff)
downloadBouncyCastle.NET-ed25519-c5065a21286ce0755cee38118b1e288898456f7e.tar.xz
Marker packet skipping
-rw-r--r--crypto/crypto.csproj5
-rw-r--r--crypto/src/bcpg/BcpgInputStream.cs13
-rw-r--r--crypto/src/openpgp/PGPKeyRing.cs54
-rw-r--r--crypto/src/openpgp/PgpPublicKeyRing.cs2
-rw-r--r--crypto/src/openpgp/PgpPublicKeyRingBundle.cs7
-rw-r--r--crypto/src/openpgp/PgpSecretKeyRing.cs2
-rw-r--r--crypto/src/openpgp/PgpSecretKeyRingBundle.cs7
-rw-r--r--crypto/test/UnitTests.csproj1
-rw-r--r--crypto/test/src/openpgp/test/IgnoreMarkerPacketInCertificatesTest.cs119
-rw-r--r--crypto/test/src/openpgp/test/RegressionTest.cs1
10 files changed, 176 insertions, 35 deletions
diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj
index f562cf91d..e95ee2f82 100644
--- a/crypto/crypto.csproj
+++ b/crypto/crypto.csproj
@@ -14894,6 +14894,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "test\src\openpgp\test\IgnoreMarkerPacketInCertificatesTest.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "test\src\openpgp\test\PGPArmoredTest.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
diff --git a/crypto/src/bcpg/BcpgInputStream.cs b/crypto/src/bcpg/BcpgInputStream.cs
index f9627fde0..3dba953ea 100644
--- a/crypto/src/bcpg/BcpgInputStream.cs
+++ b/crypto/src/bcpg/BcpgInputStream.cs
@@ -247,6 +247,17 @@ namespace Org.BouncyCastle.Bcpg
             }
         }
 
+        public PacketTag SkipMarkerPackets()
+        {
+            PacketTag tag;
+            while ((tag = NextPacketTag()) == PacketTag.Marker)
+            {
+                ReadPacket();
+            }
+
+            return tag;
+        }
+
 #if PORTABLE
         protected override void Dispose(bool disposing)
         {
@@ -257,7 +268,7 @@ namespace Org.BouncyCastle.Bcpg
             base.Dispose(disposing);
         }
 #else
-		public override void Close()
+        public override void Close()
 		{
             Platform.Dispose(m_in);
 			base.Close();
diff --git a/crypto/src/openpgp/PGPKeyRing.cs b/crypto/src/openpgp/PGPKeyRing.cs
index 425eaca56..9d9454f54 100644
--- a/crypto/src/openpgp/PGPKeyRing.cs
+++ b/crypto/src/openpgp/PGPKeyRing.cs
@@ -12,25 +12,23 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
 		{
 		}
 
-		internal static TrustPacket ReadOptionalTrustPacket(
-			BcpgInputStream bcpgInput)
+        internal static TrustPacket ReadOptionalTrustPacket(BcpgInputStream pIn)
 		{
-			return (bcpgInput.NextPacketTag() == PacketTag.Trust)
-				?	(TrustPacket)bcpgInput.ReadPacket()
-				:	null;
+            PacketTag tag = pIn.SkipMarkerPackets();
+
+            return tag == PacketTag.Trust ? (TrustPacket)pIn.ReadPacket() : null;
 		}
 
-		internal static IList ReadSignaturesAndTrust(
-			BcpgInputStream	bcpgInput)
+		internal static IList ReadSignaturesAndTrust(BcpgInputStream pIn)
 		{
-			try
-			{
+            try
+            {
 				IList sigList = Platform.CreateArrayList();
 
-				while (bcpgInput.NextPacketTag() == PacketTag.Signature)
+				while (pIn.SkipMarkerPackets() == PacketTag.Signature)
 				{
-					SignaturePacket signaturePacket = (SignaturePacket) bcpgInput.ReadPacket();
-					TrustPacket trustPacket = ReadOptionalTrustPacket(bcpgInput);
+					SignaturePacket signaturePacket = (SignaturePacket)pIn.ReadPacket();
+					TrustPacket trustPacket = ReadOptionalTrustPacket(pIn);
 
 					sigList.Add(new PgpSignature(signaturePacket, trustPacket));
 				}
@@ -43,20 +41,15 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
 			}
 		}
 
-		internal static void ReadUserIDs(
-			BcpgInputStream	bcpgInput,
-			out IList       ids,
-			out IList       idTrusts,
-			out IList       idSigs)
+		internal static void ReadUserIDs(BcpgInputStream pIn, out IList ids, out IList idTrusts, out IList idSigs)
 		{
 			ids = Platform.CreateArrayList();
             idTrusts = Platform.CreateArrayList();
             idSigs = Platform.CreateArrayList();
 
-			while (bcpgInput.NextPacketTag() == PacketTag.UserId
-				|| bcpgInput.NextPacketTag() == PacketTag.UserAttribute)
+            while (IsUserTag(pIn.SkipMarkerPackets()))
 			{
-				Packet obj = bcpgInput.ReadPacket();
+				Packet obj = pIn.ReadPacket();
 				if (obj is UserIdPacket)
 				{
 					UserIdPacket id = (UserIdPacket)obj;
@@ -64,16 +57,25 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
 				}
 				else
 				{
-					UserAttributePacket user = (UserAttributePacket) obj;
+					UserAttributePacket user = (UserAttributePacket)obj;
 					ids.Add(new PgpUserAttributeSubpacketVector(user.GetSubpackets()));
 				}
 
-				idTrusts.Add(
-					ReadOptionalTrustPacket(bcpgInput));
-
-				idSigs.Add(
-					ReadSignaturesAndTrust(bcpgInput));
+				idTrusts.Add(ReadOptionalTrustPacket(pIn));
+				idSigs.Add(ReadSignaturesAndTrust(pIn));
 			}
 		}
+
+        private static bool IsUserTag(PacketTag tag)
+        {
+            switch (tag)
+            {
+                case PacketTag.UserAttribute:
+                case PacketTag.UserId:
+                    return true;
+                default:
+                    return false;
+            }
+        }
 	}
 }
diff --git a/crypto/src/openpgp/PgpPublicKeyRing.cs b/crypto/src/openpgp/PgpPublicKeyRing.cs
index c214623b4..b35e0147b 100644
--- a/crypto/src/openpgp/PgpPublicKeyRing.cs
+++ b/crypto/src/openpgp/PgpPublicKeyRing.cs
@@ -38,7 +38,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
 
             BcpgInputStream bcpgInput = BcpgInputStream.Wrap(inputStream);
 
-            PacketTag initialTag = bcpgInput.NextPacketTag();
+            PacketTag initialTag = bcpgInput.SkipMarkerPackets();
             if (initialTag != PacketTag.PublicKey && initialTag != PacketTag.PublicSubkey)
             {
                 throw new IOException("public key ring doesn't start with public key tag: "
diff --git a/crypto/src/openpgp/PgpPublicKeyRingBundle.cs b/crypto/src/openpgp/PgpPublicKeyRingBundle.cs
index 91113e904..08d0aa0a1 100644
--- a/crypto/src/openpgp/PgpPublicKeyRingBundle.cs
+++ b/crypto/src/openpgp/PgpPublicKeyRingBundle.cs
@@ -48,12 +48,13 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
 
 			foreach (object obj in e)
             {
-				PgpPublicKeyRing pgpPub = obj as PgpPublicKeyRing;
+                // Marker packets must be ignored
+                if (obj is PgpMarker)
+                    continue;
 
+                PgpPublicKeyRing pgpPub = obj as PgpPublicKeyRing;
 				if (pgpPub == null)
-				{
 					throw new PgpException(Platform.GetTypeName(obj) + " found where PgpPublicKeyRing expected");
-				}
 
 				long key = pgpPub.GetPublicKey().KeyId;
                 pubRings.Add(key, pgpPub);
diff --git a/crypto/src/openpgp/PgpSecretKeyRing.cs b/crypto/src/openpgp/PgpSecretKeyRing.cs
index 70cd7217c..06ad4d374 100644
--- a/crypto/src/openpgp/PgpSecretKeyRing.cs
+++ b/crypto/src/openpgp/PgpSecretKeyRing.cs
@@ -49,7 +49,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
 
             BcpgInputStream bcpgInput = BcpgInputStream.Wrap(inputStream);
 
-            PacketTag initialTag = bcpgInput.NextPacketTag();
+            PacketTag initialTag = bcpgInput.SkipMarkerPackets();
             if (initialTag != PacketTag.SecretKey && initialTag != PacketTag.SecretSubkey)
             {
                 throw new IOException("secret key ring doesn't start with secret key tag: "
diff --git a/crypto/src/openpgp/PgpSecretKeyRingBundle.cs b/crypto/src/openpgp/PgpSecretKeyRingBundle.cs
index c9f4d3959..26be9c10b 100644
--- a/crypto/src/openpgp/PgpSecretKeyRingBundle.cs
+++ b/crypto/src/openpgp/PgpSecretKeyRingBundle.cs
@@ -48,12 +48,13 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
 
 			foreach (object obj in e)
 			{
-				PgpSecretKeyRing pgpSecret = obj as PgpSecretKeyRing;
+                // Marker packets must be ignored
+                if (obj is PgpMarker)
+                    continue;
 
+                PgpSecretKeyRing pgpSecret = obj as PgpSecretKeyRing;
 				if (pgpSecret == null)
-				{
 					throw new PgpException(Platform.GetTypeName(obj) + " found where PgpSecretKeyRing expected");
-				}
 
 				long key = pgpSecret.GetPublicKey().KeyId;
 				secretRings.Add(key, pgpSecret);
diff --git a/crypto/test/UnitTests.csproj b/crypto/test/UnitTests.csproj
index 1cacbd43f..398135599 100644
--- a/crypto/test/UnitTests.csproj
+++ b/crypto/test/UnitTests.csproj
@@ -383,6 +383,7 @@
     <Compile Include="src\openpgp\examples\SignedFileProcessor.cs" />
     <Compile Include="src\openpgp\examples\test\AllTests.cs" />
     <Compile Include="src\openpgp\test\DSA2Test.cs" />
+    <Compile Include="src\openpgp\test\IgnoreMarkerPacketInCertificatesTest.cs" />
     <Compile Include="src\openpgp\test\PGPArmoredTest.cs" />
     <Compile Include="src\openpgp\test\PGPClearSignedSignatureTest.cs" />
     <Compile Include="src\openpgp\test\PGPCompressionTest.cs" />
diff --git a/crypto/test/src/openpgp/test/IgnoreMarkerPacketInCertificatesTest.cs b/crypto/test/src/openpgp/test/IgnoreMarkerPacketInCertificatesTest.cs
new file mode 100644
index 000000000..8196577df
--- /dev/null
+++ b/crypto/test/src/openpgp/test/IgnoreMarkerPacketInCertificatesTest.cs
@@ -0,0 +1,119 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+    [TestFixture]
+    public class IgnoreMarkerPacketInCertificatesTest
+        : SimpleTest
+    {
+        // [PUBLIC KEY, MARKER, USER-ID, SIGNATURE, SUBKEY, SIGNATURE]
+        private static readonly string CERT_WITH_MARKER = "" +
+            "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
+            "\n" +
+            "xsDNBF2lnPIBDAC5cL9PQoQLTMuhjbYvb4Ncuuo0bfmgPRFywX53jPhoFf4Zg6mv\n" +
+            "/seOXpgecTdOcVttfzC8ycIKrt3aQTiwOG/ctaR4Bk/t6ayNFfdUNxHWk4WCKzdz\n" +
+            "/56fW2O0F23qIRd8UUJp5IIlN4RDdRCtdhVQIAuzvp2oVy/LaS2kxQoKvph/5pQ/\n" +
+            "5whqsyroEWDJoSV0yOb25B/iwk/pLUFoyhDG9bj0kIzDxrEqW+7Ba8nocQlecMF3\n" +
+            "X5KMN5kp2zraLv9dlBBpWW43XktjcCZgMy20SouraVma8Je/ECwUWYUiAZxLIlMv\n" +
+            "9CurEOtxUw6N3RdOtLmYZS9uEnn5y1UkF88o8Nku890uk6BrewFzJyLAx5wRZ4F0\n" +
+            "qV/yq36UWQ0JB/AUGhHVPdFf6pl6eaxBwT5GXvbBUibtf8YI2og5RsgTWtXfU7eb\n" +
+            "SGXrl5ZMpbA6mbfhd0R8aPxWfmDWiIOhBufhMCvUHh1sApMKVZnvIff9/0Dca3wb\n" +
+            "vLIwa3T4CyshfT0AEQEAAcoDUEdQzSFCb2IgQmFiYmFnZSA8Ym9iQG9wZW5wZ3Au\n" +
+            "ZXhhbXBsZT7CwQ4EEwEKADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTR\n" +
+            "pm4aI7GCyZgPeIz7/MgqAV5zMAUCXaWe+gAKCRD7/MgqAV5zMG9sC/9U2T3RrqEb\n" +
+            "w533FPNfEflhEVRIZ8gDXKM8hU6cqqEzCmzZT6xYTe6sv4y+PJBGXJFXyhj0g6FD\n" +
+            "kSyboM5litOcTupURObVqMgA/Y4UKERznm4fzzH9qek85c4ljtLyNufedoL2pp3v\n" +
+            "kGtn7eD0QFRaLLmnxPKQ/TlZKdLE1G3u8Uot8QHicaR6GnAdc5UXQJE3BiV7jZuD\n" +
+            "yWmZ1cUNwJkKL6oRtp+ZNDOQCrLNLecKHcgCqrpjSQG5oouba1I1Q6VlsP44dhA1\n" +
+            "nkmLHtxlTOzpeHj4jnk1FaXmyasurrrI5CgU/L2Oi39DGKTH/A/cywDN4ZplIQ9z\n" +
+            "R8enkbXquUZvFDe+Xz+6xRXtb5MwQyWODB3nHw85HocLwRoIN9WdQEI+L8a/56Au\n" +
+            "Owhs8llkSuiITjR7r9SgKJC2WlAHl7E8lhJ3VDW3ELC56KH308d6mwOGZRAqIAKz\n" +
+            "M1T5FGjMBhq7ZV0eqdEntBh3EcOIfj2M8rg1MzJv+0mHZOIjByawikbOwM0EXaWc\n" +
+            "8gEMANYwv1xsYyunXYK0X1vY/rP1NNPvhLyLIE7NpK90YNBj+xS1ldGDbUdZqZee\n" +
+            "f2xJe8gMQg05DoD1DF3GipZ0Ies65beh+d5hegb7N4pzh0LzrBrVNHar29b5ExdI\n" +
+            "7i4iYD5TO6Vr/qTUOiAN/byqELEzAb+L+b2DVz/RoCm4PIp1DU9ewcc2WB38Ofqu\n" +
+            "t3nLYA5tqJ9XvAiEQme+qAVcM3ZFcaMt4I4dXhDZZNg+D9LiTWcxdUPBleu8iwDR\n" +
+            "jAgyAhPzpFp+nWoqWA81uIiULWD1Fj+IVoY3ZvgivoYOiEFBJ9lbb4teg9m5UT/A\n" +
+            "aVDTWuHzbspVlbiVe+qyB77C2daWzNyx6UYBPLOo4r0t0c91kbNE5lgjZ7xz6los\n" +
+            "0N1U8vq91EFSeQJoSQ62XWavYmlCLmdNT6BNfgh4icLsT7Vr1QMX9jznJtTPxdXy\n" +
+            "tSdHvpSpULsqJ016l0dtmONcK3z9mj5N5z0k1tg1AH970TGYOe2aUcSxIRDMXDOP\n" +
+            "yzEfjwARAQABwsD2BBgBCgAgFiEE0aZuGiOxgsmYD3iM+/zIKgFeczAFAl2lnPIC\n" +
+            "GwwACgkQ+/zIKgFeczDp/wv/boLfh2SMF99PMyPkF3Obwy0Xrs5id4nhNAzDv7jU\n" +
+            "gvitVxIqEiGT/dR3mSdpG0/Z5/X7kXrqH39E9A4nn628HCEEBxRZK6kqdSt1VplB\n" +
+            "qdia1LFxVXY8v35ASI03e3OW6FpY7/+sALEn4r9ldCUjPBBVOk2F8bMBoxVX3Ol/\n" +
+            "e7STXiK1y/pqUpjz6stm87XAgh5FkuZTS1kMPke1YO9RXusgUjVa6gtv4pmBtifc\n" +
+            "5aMI8dV1Ot1nYKqdlsbdJfDprAf1vNEtX0ReRuEgx7PR14JV16j7AUWSWHz/lUrZ\n" +
+            "vS+T/7CownF+lrWUe8kuhvM4/1++uzCyv3YwDb6T3TVZ4hJHuoTNwjQV2DwDIUAT\n" +
+            "FoQrpXKM/tJcYvC9+KzDfg7G5mveqbHVK5+7i2gfdesHtAk3xfKqpuwbFQIGpaJ/\n" +
+            "1FIrjGPNFN7nqI96JIkk4hyIw/2LaV0j4qAvJzJ4O8agGPQcIs7eBVoF7i5tWuPk\n" +
+            "qOFfY9U0Ql3ddlHNpdkTZoAx\n" +
+            "=6mfA\n" +
+            "-----END PGP PUBLIC KEY BLOCK-----";
+
+		public override string Name
+		{
+			get { return "IgnoreMarkerPacketInCertificatesTest"; }
+		}
+
+        public override void PerformTest()
+        {
+            ArmoredInputStream armorIn = new ArmoredInputStream(
+                new MemoryStream(Encoding.UTF8.GetBytes(CERT_WITH_MARKER)));
+            PgpObjectFactory objectFactory = new PgpObjectFactory(armorIn);
+
+            PgpPublicKeyRing certificate = (PgpPublicKeyRing)objectFactory.NextPgpObject();
+            IsEquals("Bob Babbage <bob@openpgp.example>", First(certificate.GetPublicKey().GetUserIds()));
+            IEnumerable publicKeys = certificate.GetPublicKeys();
+            IEnumerator publicKeyEnum = publicKeys.GetEnumerator();
+            IsTrue(publicKeyEnum.MoveNext());
+            PgpPublicKey primaryKey = (PgpPublicKey)publicKeyEnum.Current;
+            IsEquals(new BigInteger("FBFCC82A015E7330", 16).LongValue, primaryKey.KeyId);
+            IEnumerable signatures = primaryKey.GetSignatures();
+            IsEquals(1, Count(signatures));
+
+            IsTrue(publicKeyEnum.MoveNext());
+            PgpPublicKey subkey = (PgpPublicKey)publicKeyEnum.Current;
+            IsEquals(new BigInteger("7C2FAA4DF93C37B2", 16).LongValue, subkey.KeyId);
+            signatures = subkey.GetSignatures();
+            IsEquals(1, Count(signatures));
+        }
+
+		public static void Main(string[] args)
+		{
+			RunTest(new PgpArmoredTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+
+        private int Count(IEnumerable e)
+        {
+            int count = 0;
+            foreach (object o in e)
+            {
+                ++count;
+            }
+            return count;
+        }
+
+        private object First(IEnumerable e)
+        {
+            IEnumerator enumerator = e.GetEnumerator();
+            IsTrue(enumerator.MoveNext());
+            return enumerator.Current;
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/test/RegressionTest.cs b/crypto/test/src/openpgp/test/RegressionTest.cs
index 5e978f0ea..a65173989 100644
--- a/crypto/test/src/openpgp/test/RegressionTest.cs
+++ b/crypto/test/src/openpgp/test/RegressionTest.cs
@@ -25,6 +25,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
             new PgpECMessageTest(),
             new PgpParsingTest(),
             new PgpFeaturesTest(),
+            new IgnoreMarkerPacketInCertificatesTest(),
         };
 
         public static void Main(string[] args)