diff --git a/crypto/src/asn1/BerOctetString.cs b/crypto/src/asn1/BerOctetString.cs
index b092d8fb2..4855e31d1 100644
--- a/crypto/src/asn1/BerOctetString.cs
+++ b/crypto/src/asn1/BerOctetString.cs
@@ -9,7 +9,7 @@ namespace Org.BouncyCastle.Asn1
public class BerOctetString
: DerOctetString, IEnumerable
{
- private static readonly int DefaultChunkSize = 1000;
+ private static readonly int DefaultSegmentLimit = 1000;
public static BerOctetString FromSequence(Asn1Sequence seq)
{
@@ -17,7 +17,7 @@ namespace Org.BouncyCastle.Asn1
Asn1OctetString[] v = new Asn1OctetString[count];
for (int i = 0; i < count; ++i)
{
- v[i] = Asn1OctetString.GetInstance(seq[i]);
+ v[i] = GetInstance(seq[i]);
}
return new BerOctetString(v);
}
@@ -62,13 +62,13 @@ namespace Org.BouncyCastle.Asn1
Asn1OctetString[] v = new Asn1OctetString[count];
for (int i = 0; i < count; ++i)
{
- v[i] = Asn1OctetString.GetInstance(list[i]);
+ v[i] = GetInstance(list[i]);
}
return v;
}
- private readonly int chunkSize;
- private readonly Asn1OctetString[] octs;
+ private readonly int segmentLimit;
+ private readonly Asn1OctetString[] elements;
[Obsolete("Will be removed")]
public BerOctetString(IEnumerable e)
@@ -77,30 +77,30 @@ namespace Org.BouncyCastle.Asn1
}
public BerOctetString(byte[] str)
- : this(str, DefaultChunkSize)
+ : this(str, DefaultSegmentLimit)
{
}
- public BerOctetString(Asn1OctetString[] octs)
- : this(octs, DefaultChunkSize)
+ public BerOctetString(Asn1OctetString[] elements)
+ : this(elements, DefaultSegmentLimit)
{
}
- public BerOctetString(byte[] str, int chunkSize)
- : this(str, null, chunkSize)
+ public BerOctetString(byte[] str, int segmentLimit)
+ : this(str, null, segmentLimit)
{
}
- public BerOctetString(Asn1OctetString[] octs, int chunkSize)
- : this(FlattenOctetStrings(octs), octs, chunkSize)
+ public BerOctetString(Asn1OctetString[] elements, int segmentLimit)
+ : this(FlattenOctetStrings(elements), elements, segmentLimit)
{
}
- private BerOctetString(byte[] str, Asn1OctetString[] octs, int chunkSize)
- : base(str)
+ private BerOctetString(byte[] octets, Asn1OctetString[] elements, int segmentLimit)
+ : base(octets)
{
- this.octs = octs;
- this.chunkSize = chunkSize;
+ this.elements = elements;
+ this.segmentLimit = segmentLimit;
}
/**
@@ -108,10 +108,10 @@ namespace Org.BouncyCastle.Asn1
*/
public IEnumerator GetEnumerator()
{
- if (octs == null)
- return new ChunkEnumerator(str, chunkSize);
+ if (elements == null)
+ return new ChunkEnumerator(str, segmentLimit);
- return octs.GetEnumerator();
+ return elements.GetEnumerator();
}
[Obsolete("Use GetEnumerator() instead")]
@@ -120,82 +120,119 @@ namespace Org.BouncyCastle.Asn1
return GetEnumerator();
}
+ private bool IsConstructed
+ {
+ get { return null != elements || str.Length > segmentLimit; }
+ }
+
internal override int EncodedLength(bool withID)
{
throw Platform.CreateNotImplementedException("BerOctetString.EncodedLength");
+
+ // TODO This depends on knowing it's not DER
+ //if (!IsConstructed)
+ // return EncodedLength(withID, str.Length);
+
+ //int totalLength = withID ? 4 : 3;
+
+ //if (null != elements)
+ //{
+ // for (int i = 0; i < elements.Length; ++i)
+ // {
+ // totalLength += elements[i].EncodedLength(true);
+ // }
+ //}
+ //else
+ //{
+ // int fullSegments = str.Length / segmentLimit;
+ // totalLength += fullSegments * EncodedLength(true, segmentLimit);
+
+ // int lastSegmentLength = str.Length - (fullSegments * segmentLimit);
+ // if (lastSegmentLength > 0)
+ // {
+ // totalLength += EncodedLength(true, lastSegmentLength);
+ // }
+ //}
+
+ //return totalLength;
}
internal override void Encode(Asn1OutputStream asn1Out, bool withID)
{
- if (asn1Out.IsBer)
+ if (!asn1Out.IsBer || !IsConstructed)
{
- if (withID)
- {
- asn1Out.WriteByte(Asn1Tags.Constructed | Asn1Tags.OctetString);
- }
+ base.Encode(asn1Out, withID);
+ return;
+ }
- asn1Out.WriteByte(0x80);
+ asn1Out.WriteIdentifier(withID, Asn1Tags.Constructed | Asn1Tags.OctetString);
+ asn1Out.WriteByte(0x80);
- foreach (Asn1OctetString oct in this)
- {
- oct.Encode(asn1Out, true);
- }
-
- asn1Out.WriteByte(0x00);
- asn1Out.WriteByte(0x00);
+ if (null != elements)
+ {
+ asn1Out.WritePrimitives(elements);
}
else
{
- base.Encode(asn1Out, withID);
+ int pos = 0;
+ while (pos < str.Length)
+ {
+ int segmentLength = System.Math.Min(str.Length - pos, segmentLimit);
+ Encode(asn1Out, true, str, pos, segmentLength);
+ pos += segmentLength;
+ }
}
+
+ asn1Out.WriteByte(0x00);
+ asn1Out.WriteByte(0x00);
}
private class ChunkEnumerator
: IEnumerator
{
private readonly byte[] octets;
- private readonly int chunkSize;
+ private readonly int segmentLimit;
- private DerOctetString currentChunk = null;
- private int nextChunkPos = 0;
+ private DerOctetString currentSegment = null;
+ private int nextSegmentPos = 0;
- internal ChunkEnumerator(byte[] octets, int chunkSize)
+ internal ChunkEnumerator(byte[] octets, int segmentLimit)
{
this.octets = octets;
- this.chunkSize = chunkSize;
+ this.segmentLimit = segmentLimit;
}
public object Current
{
get
{
- if (null == currentChunk)
+ if (null == currentSegment)
throw new InvalidOperationException();
- return currentChunk;
+ return currentSegment;
}
}
public bool MoveNext()
{
- if (nextChunkPos >= octets.Length)
+ if (nextSegmentPos >= octets.Length)
{
- this.currentChunk = null;
+ this.currentSegment = null;
return false;
}
- int length = System.Math.Min(octets.Length - nextChunkPos, chunkSize);
- byte[] chunk = new byte[length];
- Array.Copy(octets, nextChunkPos, chunk, 0, length);
- this.currentChunk = new DerOctetString(chunk);
- this.nextChunkPos += length;
+ int length = System.Math.Min(octets.Length - nextSegmentPos, segmentLimit);
+ byte[] segment = new byte[length];
+ Array.Copy(octets, nextSegmentPos, segment, 0, length);
+ this.currentSegment = new DerOctetString(segment);
+ this.nextSegmentPos += length;
return true;
}
public void Reset()
{
- this.currentChunk = null;
- this.nextChunkPos = 0;
+ this.currentSegment = null;
+ this.nextSegmentPos = 0;
}
}
}
diff --git a/crypto/src/asn1/DerOctetString.cs b/crypto/src/asn1/DerOctetString.cs
index bdabb8221..bcd4e7333 100644
--- a/crypto/src/asn1/DerOctetString.cs
+++ b/crypto/src/asn1/DerOctetString.cs
@@ -36,5 +36,10 @@ namespace Org.BouncyCastle.Asn1
{
asn1Out.WriteEncodingDL(withID, Asn1Tags.OctetString, buf, off, len);
}
- }
+
+ internal static int EncodedLength(bool withID, int contentsLength)
+ {
+ return Asn1OutputStream.GetLengthOfEncodingDL(withID, contentsLength);
+ }
+ }
}
diff --git a/crypto/test/src/asn1/test/CMSTest.cs b/crypto/test/src/asn1/test/CMSTest.cs
index 1afb363af..9930830f1 100644
--- a/crypto/test/src/asn1/test/CMSTest.cs
+++ b/crypto/test/src/asn1/test/CMSTest.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Asn1.Tests
//
// compressed data object
//
- private static readonly byte[] compData = Base64.Decode(
+ private static readonly byte[] OrigCompData = Base64.Decode(
"MIAGCyqGSIb3DQEJEAEJoIAwgAIBADANBgsqhkiG9w0BCRADCDCABgkqhkiG9w0BBwGggCSABIIC"
+ "Hnic7ZRdb9owFIbvK/k/5PqVYPFXGK12YYyboVFASSp1vQtZGiLRACZE49/XHoUW7S/0tXP8Efux"
+ "fU5ivWnasml72XFb3gb5druui7ytN803M570nii7C5r8tfwR281hy/p/KSM3+jzH5s3+pbQ90xSb"
@@ -72,7 +72,7 @@ namespace Org.BouncyCastle.Asn1.Tests
//
// signed data
//
- private static readonly byte[] signedData = Base64.Decode(
+ private static readonly byte[] OrigSignedData = Base64.Decode(
"MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA"
+ "JIAEDEhlbGxvIFdvcmxkIQAAAAAAAKCCBGIwggINMIIBdqADAgECAgEBMA0GCSqG"
+ "SIb3DQEBBAUAMCUxFjAUBgNVBAoTDUJvdW5jeSBDYXN0bGUxCzAJBgNVBAYTAkFV"
@@ -114,14 +114,10 @@ namespace Org.BouncyCastle.Asn1.Tests
{
try
{
- ContentInfo info = ContentInfo.GetInstance(
- Asn1Object.FromByteArray(compData));
- CompressedData data = CompressedData.GetInstance(info.Content);
-
- data = new CompressedData(data.CompressionAlgorithmIdentifier, data.EncapContentInfo);
- info = new ContentInfo(CmsObjectIdentifiers.CompressedData, data);
+ byte[] compData1 = ImplCompressionTest(OrigCompData);
+ byte[] compData2 = ImplCompressionTest(compData1);
- if (!Arrays.AreEqual(info.GetEncoded(), compData))
+ if (!Arrays.AreEqual(compData1, compData2))
{
return new SimpleTestResult(false, Name + ": CMS compression failed to re-encode");
}
@@ -134,7 +130,16 @@ namespace Org.BouncyCastle.Asn1.Tests
}
}
- private ITestResult EnvelopedTest()
+ private byte[] ImplCompressionTest(byte[] compData)
+ {
+ ContentInfo info = ContentInfo.GetInstance(Asn1Object.FromByteArray(compData));
+ CompressedData data = CompressedData.GetInstance(info.Content);
+ data = new CompressedData(data.CompressionAlgorithmIdentifier, data.EncapContentInfo);
+ info = new ContentInfo(CmsObjectIdentifiers.CompressedData, data);
+ return info.GetEncoded();
+ }
+
+ private ITestResult EnvelopedTest()
{
try
{
@@ -243,14 +248,10 @@ namespace Org.BouncyCastle.Asn1.Tests
{
try
{
- ContentInfo info = ContentInfo.GetInstance(
- Asn1Object.FromByteArray(signedData));
- SignedData sData = SignedData.GetInstance(info.Content);
-
- sData = new SignedData(sData.DigestAlgorithms, sData.EncapContentInfo, sData.Certificates, sData.CRLs, sData.SignerInfos);
- info = new ContentInfo(CmsObjectIdentifiers.SignedData, sData);
+ byte[] signedData1 = ImplSignedTest(OrigSignedData);
+ byte[] signedData2 = ImplSignedTest(signedData1);
- if (!Arrays.AreEqual(info.GetEncoded(), signedData))
+ if (!Arrays.AreEqual(signedData1, signedData2))
{
return new SimpleTestResult(false, Name + ": CMS signed failed to re-encode");
}
@@ -263,7 +264,16 @@ namespace Org.BouncyCastle.Asn1.Tests
}
}
- public ITestResult Perform()
+ private byte[] ImplSignedTest(byte[] signedData)
+ {
+ ContentInfo info = ContentInfo.GetInstance(Asn1Object.FromByteArray(signedData));
+ SignedData sData = SignedData.GetInstance(info.Content);
+ sData = new SignedData(sData.DigestAlgorithms, sData.EncapContentInfo, sData.Certificates, sData.CRLs, sData.SignerInfos);
+ info = new ContentInfo(CmsObjectIdentifiers.SignedData, sData);
+ return info.GetEncoded();
+ }
+
+ public ITestResult Perform()
{
ITestResult res = CompressionTest();
diff --git a/crypto/test/src/asn1/test/PKCS12Test.cs b/crypto/test/src/asn1/test/PKCS12Test.cs
index 5e4748728..eae61de46 100644
--- a/crypto/test/src/asn1/test/PKCS12Test.cs
+++ b/crypto/test/src/asn1/test/PKCS12Test.cs
@@ -113,6 +113,20 @@ namespace Org.BouncyCastle.Asn1.Tests
+ "AgFkAAA=");
public override void PerformTest()
+ {
+ byte[] pfxEncoding1 = ImplTest(pkcs12);
+ byte[] pfxEncoding2 = ImplTest(pfxEncoding1);
+
+ //
+ // comparison test
+ //
+ if (!Arrays.AreEqual(pfxEncoding1, pfxEncoding2))
+ {
+ Fail("failed comparison test");
+ }
+ }
+
+ private byte[] ImplTest(byte[] pkcs12)
{
Pfx bag = Pfx.GetInstance(pkcs12);
ContentInfo info = bag.AuthSafe;
@@ -178,14 +192,7 @@ namespace Org.BouncyCastle.Asn1.Tests
bag = new Pfx(info, mData);
- //
- // comparison test
- //
- byte[] pfxEncoding = bag.GetEncoded();
- if (!Arrays.AreEqual(pfxEncoding, pkcs12))
- {
- Fail("Failed comparison test");
- }
+ return bag.GetEncoded();
}
public override string Name
|