diff options
-rw-r--r-- | crypto/crypto.csproj | 5 | ||||
-rw-r--r-- | crypto/src/bcpg/BcpgInputStream.cs | 13 | ||||
-rw-r--r-- | crypto/src/openpgp/PGPKeyRing.cs | 54 | ||||
-rw-r--r-- | crypto/src/openpgp/PgpPublicKeyRing.cs | 2 | ||||
-rw-r--r-- | crypto/src/openpgp/PgpPublicKeyRingBundle.cs | 7 | ||||
-rw-r--r-- | crypto/src/openpgp/PgpSecretKeyRing.cs | 2 | ||||
-rw-r--r-- | crypto/src/openpgp/PgpSecretKeyRingBundle.cs | 7 | ||||
-rw-r--r-- | crypto/test/UnitTests.csproj | 1 | ||||
-rw-r--r-- | crypto/test/src/openpgp/test/IgnoreMarkerPacketInCertificatesTest.cs | 119 | ||||
-rw-r--r-- | crypto/test/src/openpgp/test/RegressionTest.cs | 1 |
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" + + "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\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) |