From 61605407b72d584c94daeafe4ea4c2b1cad3914e Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Thu, 14 Oct 2021 20:33:18 +0700 Subject: Add withID to Encode method - refactor Asn1OutputStream utility methods --- crypto/src/asn1/Asn1Object.cs | 4 +- crypto/src/asn1/Asn1OutputStream.cs | 130 +++++++++++++++++++++++++++-- crypto/src/asn1/BERBitString.cs | 6 +- crypto/src/asn1/BEROctetStringGenerator.cs | 10 +-- crypto/src/asn1/BerOctetString.cs | 14 ++-- crypto/src/asn1/BerOutputStream.cs | 9 +- crypto/src/asn1/BerSequence.cs | 14 +--- crypto/src/asn1/BerSet.cs | 12 +-- crypto/src/asn1/BerTaggedObject.cs | 16 ++-- crypto/src/asn1/DERExternal.cs | 4 +- crypto/src/asn1/DerApplicationSpecific.cs | 8 +- crypto/src/asn1/DerBMPString.cs | 4 +- crypto/src/asn1/DerBitString.cs | 6 +- crypto/src/asn1/DerBoolean.cs | 4 +- crypto/src/asn1/DerEnumerated.cs | 4 +- crypto/src/asn1/DerGeneralString.cs | 4 +- crypto/src/asn1/DerGeneralizedTime.cs | 4 +- crypto/src/asn1/DerGraphicString.cs | 4 +- crypto/src/asn1/DerIA5String.cs | 4 +- crypto/src/asn1/DerInteger.cs | 4 +- crypto/src/asn1/DerNull.cs | 8 +- crypto/src/asn1/DerNumericString.cs | 4 +- crypto/src/asn1/DerObjectIdentifier.cs | 4 +- crypto/src/asn1/DerOctetString.cs | 8 +- crypto/src/asn1/DerOutputStream.cs | 115 +------------------------ crypto/src/asn1/DerPrintableString.cs | 4 +- crypto/src/asn1/DerSequence.cs | 6 +- crypto/src/asn1/DerSet.cs | 8 +- crypto/src/asn1/DerT61String.cs | 4 +- crypto/src/asn1/DerTaggedObject.cs | 17 ++-- crypto/src/asn1/DerUTCTime.cs | 4 +- crypto/src/asn1/DerUTF8String.cs | 4 +- crypto/src/asn1/DerUniversalString.cs | 4 +- crypto/src/asn1/DerVideotexString.cs | 4 +- crypto/src/asn1/DerVisibleString.cs | 4 +- crypto/src/asn1/LazyDERSequence.cs | 6 +- crypto/src/asn1/LazyDERSet.cs | 6 +- 37 files changed, 243 insertions(+), 232 deletions(-) diff --git a/crypto/src/asn1/Asn1Object.cs b/crypto/src/asn1/Asn1Object.cs index d60a85348..7c7f87704 100644 --- a/crypto/src/asn1/Asn1Object.cs +++ b/crypto/src/asn1/Asn1Object.cs @@ -62,9 +62,9 @@ namespace Org.BouncyCastle.Asn1 return this; } - internal abstract void Encode(Asn1OutputStream asn1Out); + internal abstract void Encode(Asn1OutputStream asn1Out, bool withID); - protected abstract bool Asn1Equals(Asn1Object asn1Object); + protected abstract bool Asn1Equals(Asn1Object asn1Object); protected abstract int Asn1GetHashCode(); internal bool CallAsn1Equals(Asn1Object obj) diff --git a/crypto/src/asn1/Asn1OutputStream.cs b/crypto/src/asn1/Asn1OutputStream.cs index e6eec563e..1b253419a 100644 --- a/crypto/src/asn1/Asn1OutputStream.cs +++ b/crypto/src/asn1/Asn1OutputStream.cs @@ -34,7 +34,7 @@ namespace Org.BouncyCastle.Asn1 if (null == encodable) throw new IOException("null object detected"); - WritePrimitive(encodable.ToAsn1Object()); + WritePrimitive(encodable.ToAsn1Object(), true); FlushInternal(); } @@ -43,7 +43,7 @@ namespace Org.BouncyCastle.Asn1 if (null == primitive) throw new IOException("null object detected"); - WritePrimitive(primitive); + WritePrimitive(primitive, true); FlushInternal(); } @@ -52,29 +52,145 @@ namespace Org.BouncyCastle.Asn1 // Placeholder to support future internal buffering } - internal override bool IsBer + internal virtual bool IsBer { get { return true; } } + internal void WriteDL(int length) + { + if (length < 128) + { + WriteByte((byte)length); + } + else + { + byte[] stack = new byte[5]; + int pos = stack.Length; + + do + { + stack[--pos] = (byte)length; + length >>= 8; + } + while (length > 0); + + int count = stack.Length - pos; + stack[--pos] = (byte)(0x80 | count); + + Write(stack, pos, count + 1); + } + } + internal virtual void WriteElements(Asn1Encodable[] elements) { for (int i = 0, count = elements.Length; i < count; ++i) { - elements[i].ToAsn1Object().Encode(this); + elements[i].ToAsn1Object().Encode(this, true); + } + } + + internal void WriteEncodingDL(bool withID, int identifier, byte contents) + { + WriteIdentifier(withID, identifier); + WriteDL(1); + WriteByte(contents); + } + + internal void WriteEncodingDL(bool withID, int identifier, byte[] contents) + { + WriteIdentifier(withID, identifier); + WriteDL(contents.Length); + Write(contents, 0, contents.Length); + } + + internal void WriteEncodingDL(bool withID, int identifier, byte[] contents, int contentsOff, int contentsLen) + { + WriteIdentifier(withID, identifier); + WriteDL(contentsLen); + Write(contents, contentsOff, contentsLen); + } + + internal void WriteEncodingDL(bool withID, int identifier, byte contentsPrefix, byte[] contents, + int contentsOff, int contentsLen) + { + WriteIdentifier(withID, identifier); + WriteDL(1 + contentsLen); + WriteByte(contentsPrefix); + Write(contents, contentsOff, contentsLen); + } + + internal void WriteEncodingDL(bool withID, int identifier, byte[] contents, int contentsOff, int contentsLen, + byte contentsSuffix) + { + WriteIdentifier(withID, identifier); + WriteDL(contentsLen + 1); + Write(contents, contentsOff, contentsLen); + WriteByte(contentsSuffix); + } + + internal void WriteEncodingDL(bool withID, int flags, int tag, byte[] contents) + { + WriteIdentifier(withID, flags, tag); + WriteDL(contents.Length); + Write(contents, 0, contents.Length); + } + + internal void WriteEncodingIL(bool withID, int identifier, Asn1Encodable[] elements) + { + WriteIdentifier(withID, identifier); + WriteByte(0x80); + WriteElements(elements); + WriteByte(0x00); + WriteByte(0x00); + } + + internal void WriteIdentifier(bool withID, int identifier) + { + if (withID) + { + WriteByte((byte)identifier); + } + } + + internal void WriteIdentifier(bool withID, int flags, int tag) + { + if (!withID) + { + // Don't write the identifier + } + else if (tag < 31) + { + WriteByte((byte)(flags | tag)); + } + else + { + byte[] stack = new byte[6]; + int pos = stack.Length; + + stack[--pos] = (byte)(tag & 0x7F); + while (tag > 127) + { + tag >>= 7; + stack[--pos] = (byte)(tag & 0x7F | 0x80); + } + + stack[--pos] = (byte)(flags | 0x1F); + + Write(stack, pos, stack.Length - pos); } } - internal virtual void WritePrimitive(Asn1Object primitive) + internal virtual void WritePrimitive(Asn1Object primitive, bool withID) { - primitive.Encode(this); + primitive.Encode(this, withID); } internal virtual void WritePrimitives(Asn1Object[] primitives) { for (int i = 0, count = primitives.Length; i < count; ++i) { - WritePrimitive(primitives[i]); + WritePrimitive(primitives[i], true); } } } diff --git a/crypto/src/asn1/BERBitString.cs b/crypto/src/asn1/BERBitString.cs index 0db973a07..a738a75e6 100644 --- a/crypto/src/asn1/BERBitString.cs +++ b/crypto/src/asn1/BERBitString.cs @@ -27,15 +27,15 @@ namespace Org.BouncyCastle.Asn1 { } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { if (asn1Out.IsBer) { - asn1Out.WriteEncoded(Asn1Tags.BitString, (byte)mPadBits, mData); + asn1Out.WriteEncodingDL(withID, Asn1Tags.BitString, (byte)mPadBits, mData, 0, mData.Length); } else { - base.Encode(asn1Out); + base.Encode(asn1Out, withID); } } } diff --git a/crypto/src/asn1/BEROctetStringGenerator.cs b/crypto/src/asn1/BEROctetStringGenerator.cs index 4a7f1e8e5..37e46bea5 100644 --- a/crypto/src/asn1/BEROctetStringGenerator.cs +++ b/crypto/src/asn1/BEROctetStringGenerator.cs @@ -67,7 +67,7 @@ namespace Org.BouncyCastle.Asn1 if (_off == _buf.Length) { - DerOctetString.Encode(_derOut, _buf, 0, _off); + DerOctetString.Encode(_derOut, true, _buf, 0, _off); _off = 0; } } @@ -88,13 +88,13 @@ namespace Org.BouncyCastle.Asn1 { Array.Copy(b, off, _buf, _off, available); count += available; - DerOctetString.Encode(_derOut, _buf, 0, bufLen); + DerOctetString.Encode(_derOut, true, _buf, 0, bufLen); } int remaining; while ((remaining = len - count) >= bufLen) { - DerOctetString.Encode(_derOut, b, off + count, bufLen); + DerOctetString.Encode(_derOut, true, b, off + count, bufLen); count += bufLen; } @@ -109,7 +109,7 @@ namespace Org.BouncyCastle.Asn1 { if (_off != 0) { - DerOctetString.Encode(_derOut, _buf, 0, _off); + DerOctetString.Encode(_derOut, true, _buf, 0, _off); } _derOut.FlushInternal(); @@ -123,7 +123,7 @@ namespace Org.BouncyCastle.Asn1 { if (_off != 0) { - DerOctetString.Encode(_derOut, _buf, 0, _off); + DerOctetString.Encode(_derOut, true, _buf, 0, _off); } _derOut.FlushInternal(); diff --git a/crypto/src/asn1/BerOctetString.cs b/crypto/src/asn1/BerOctetString.cs index 2140faef1..1a8f761a4 100644 --- a/crypto/src/asn1/BerOctetString.cs +++ b/crypto/src/asn1/BerOctetString.cs @@ -121,20 +121,20 @@ namespace Org.BouncyCastle.Asn1 return GetEnumerator(); } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { if (asn1Out.IsBer) { - asn1Out.WriteByte(Asn1Tags.Constructed | Asn1Tags.OctetString); + if (withID) + { + asn1Out.WriteByte(Asn1Tags.Constructed | Asn1Tags.OctetString); + } asn1Out.WriteByte(0x80); - // - // write out the octet array - // foreach (Asn1OctetString oct in this) { - oct.Encode(asn1Out); + oct.Encode(asn1Out, true); } asn1Out.WriteByte(0x00); @@ -142,7 +142,7 @@ namespace Org.BouncyCastle.Asn1 } else { - base.Encode(asn1Out); + base.Encode(asn1Out, withID); } } diff --git a/crypto/src/asn1/BerOutputStream.cs b/crypto/src/asn1/BerOutputStream.cs index 54b72cf06..1486368e0 100644 --- a/crypto/src/asn1/BerOutputStream.cs +++ b/crypto/src/asn1/BerOutputStream.cs @@ -13,9 +13,14 @@ namespace Org.BouncyCastle.Asn1 { } - internal override bool IsBer + public override void WriteObject(Asn1Encodable encodable) { - get { return true; } + Asn1OutputStream.Create(s).WriteObject(encodable); + } + + public override void WriteObject(Asn1Object primitive) + { + Asn1OutputStream.Create(s).WriteObject(primitive); } } } diff --git a/crypto/src/asn1/BerSequence.cs b/crypto/src/asn1/BerSequence.cs index b8ef12dd0..341090c7a 100644 --- a/crypto/src/asn1/BerSequence.cs +++ b/crypto/src/asn1/BerSequence.cs @@ -39,21 +39,15 @@ namespace Org.BouncyCastle.Asn1 { } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { if (asn1Out.IsBer) - { - asn1Out.WriteByte(Asn1Tags.Sequence | Asn1Tags.Constructed); - asn1Out.WriteByte(0x80); - - asn1Out.WriteElements(elements); - - asn1Out.WriteByte(0x00); - asn1Out.WriteByte(0x00); + { + asn1Out.WriteEncodingIL(withID, Asn1Tags.Constructed | Asn1Tags.Sequence, elements); } else { - base.Encode(asn1Out); + base.Encode(asn1Out, withID); } } } diff --git a/crypto/src/asn1/BerSet.cs b/crypto/src/asn1/BerSet.cs index a3868dfa6..3a1163fcb 100644 --- a/crypto/src/asn1/BerSet.cs +++ b/crypto/src/asn1/BerSet.cs @@ -44,21 +44,15 @@ namespace Org.BouncyCastle.Asn1 { } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { if (asn1Out.IsBer) { - asn1Out.WriteByte(Asn1Tags.Set | Asn1Tags.Constructed); - asn1Out.WriteByte(0x80); - - asn1Out.WriteElements(elements); - - asn1Out.WriteByte(0x00); - asn1Out.WriteByte(0x00); + asn1Out.WriteEncodingIL(withID, Asn1Tags.Constructed | Asn1Tags.Set, elements); } else { - base.Encode(asn1Out); + base.Encode(asn1Out, withID); } } } diff --git a/crypto/src/asn1/BerTaggedObject.cs b/crypto/src/asn1/BerTaggedObject.cs index 097f77610..631d34420 100644 --- a/crypto/src/asn1/BerTaggedObject.cs +++ b/crypto/src/asn1/BerTaggedObject.cs @@ -47,12 +47,16 @@ namespace Org.BouncyCastle.Asn1 { } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { if (asn1Out.IsBer) { - asn1Out.WriteIdentifier(true, Asn1Tags.Constructed | Asn1Tags.Tagged, tagNo); - asn1Out.WriteByte(0x80); + if (withID) + { + asn1Out.WriteIdentifier(true, Asn1Tags.Constructed | Asn1Tags.Tagged, tagNo); + } + + asn1Out.WriteByte(0x80); if (!IsEmpty()) { @@ -86,12 +90,12 @@ namespace Org.BouncyCastle.Asn1 foreach (Asn1Encodable o in eObj) { - asn1Out.WritePrimitive(o.ToAsn1Object()); + asn1Out.WritePrimitive(o.ToAsn1Object(), true); } } else { - asn1Out.WritePrimitive(obj.ToAsn1Object()); + asn1Out.WritePrimitive(obj.ToAsn1Object(), true); } } @@ -100,7 +104,7 @@ namespace Org.BouncyCastle.Asn1 } else { - base.Encode(asn1Out); + base.Encode(asn1Out, withID); } } } diff --git a/crypto/src/asn1/DERExternal.cs b/crypto/src/asn1/DERExternal.cs index 1e5a42f77..4f3c6ed6c 100644 --- a/crypto/src/asn1/DERExternal.cs +++ b/crypto/src/asn1/DERExternal.cs @@ -89,7 +89,7 @@ namespace Org.BouncyCastle.Asn1 ExternalContent = externalData.ToAsn1Object(); } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { MemoryStream ms = new MemoryStream(); WriteEncodable(ms, directReference); @@ -97,7 +97,7 @@ namespace Org.BouncyCastle.Asn1 WriteEncodable(ms, dataValueDescriptor); WriteEncodable(ms, new DerTaggedObject(Asn1Tags.External, externalContent)); - asn1Out.WriteEncoded(Asn1Tags.Constructed, Asn1Tags.External, ms.ToArray()); + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.External, ms.ToArray()); } protected override int Asn1GetHashCode() diff --git a/crypto/src/asn1/DerApplicationSpecific.cs b/crypto/src/asn1/DerApplicationSpecific.cs index 7bba8c5a9..0d60a3e38 100644 --- a/crypto/src/asn1/DerApplicationSpecific.cs +++ b/crypto/src/asn1/DerApplicationSpecific.cs @@ -163,15 +163,15 @@ namespace Org.BouncyCastle.Asn1 return FromByteArray(tmp); } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - int classBits = Asn1Tags.Application; + int flags = Asn1Tags.Application; if (isConstructed) { - classBits |= Asn1Tags.Constructed; + flags |= Asn1Tags.Constructed; } - asn1Out.WriteEncoded(classBits, tag, octets); + asn1Out.WriteEncodingDL(withID, flags, tag, octets); } protected override bool Asn1Equals( diff --git a/crypto/src/asn1/DerBMPString.cs b/crypto/src/asn1/DerBMPString.cs index eb9606096..3a75604ae 100644 --- a/crypto/src/asn1/DerBMPString.cs +++ b/crypto/src/asn1/DerBMPString.cs @@ -111,7 +111,7 @@ namespace Org.BouncyCastle.Asn1 return this.str.Equals(other.str); } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { char[] c = str.ToCharArray(); byte[] b = new byte[c.Length * 2]; @@ -122,7 +122,7 @@ namespace Org.BouncyCastle.Asn1 b[2 * i + 1] = (byte)c[i]; } - asn1Out.WriteEncoded(Asn1Tags.BmpString, b); + asn1Out.WriteEncodingDL(withID, Asn1Tags.BmpString, b); } } } diff --git a/crypto/src/asn1/DerBitString.cs b/crypto/src/asn1/DerBitString.cs index 282e97929..624da6763 100644 --- a/crypto/src/asn1/DerBitString.cs +++ b/crypto/src/asn1/DerBitString.cs @@ -191,7 +191,7 @@ namespace Org.BouncyCastle.Asn1 } } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { if (mPadBits > 0) { @@ -208,12 +208,12 @@ namespace Org.BouncyCastle.Asn1 */ contents[contents.Length - 1] = (byte)(last ^ unusedBits); - asn1Out.WriteEncoded(Asn1Tags.BitString, contents); + asn1Out.WriteEncodingDL(withID, Asn1Tags.BitString, contents); return; } } - asn1Out.WriteEncoded(Asn1Tags.BitString, (byte)mPadBits, mData); + asn1Out.WriteEncodingDL(withID, Asn1Tags.BitString, (byte)mPadBits, mData, 0, mData.Length); } protected override int Asn1GetHashCode() diff --git a/crypto/src/asn1/DerBoolean.cs b/crypto/src/asn1/DerBoolean.cs index 3052c6e0d..7458b18ea 100644 --- a/crypto/src/asn1/DerBoolean.cs +++ b/crypto/src/asn1/DerBoolean.cs @@ -81,10 +81,10 @@ namespace Org.BouncyCastle.Asn1 get { return value != 0; } } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { // TODO Should we make sure the byte value is one of '0' or '0xff' here? - asn1Out.WriteEncoded(Asn1Tags.Boolean, new byte[]{ value }); + asn1Out.WriteEncodingDL(withID, Asn1Tags.Boolean, value); } protected override bool Asn1Equals( diff --git a/crypto/src/asn1/DerEnumerated.cs b/crypto/src/asn1/DerEnumerated.cs index f00eab05e..6e3a16054 100644 --- a/crypto/src/asn1/DerEnumerated.cs +++ b/crypto/src/asn1/DerEnumerated.cs @@ -119,9 +119,9 @@ namespace Org.BouncyCastle.Asn1 } } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.Enumerated, bytes); + asn1Out.WriteEncodingDL(withID, Asn1Tags.Enumerated, bytes); } protected override bool Asn1Equals(Asn1Object asn1Object) diff --git a/crypto/src/asn1/DerGeneralString.cs b/crypto/src/asn1/DerGeneralString.cs index f6e800e73..f7446dc27 100644 --- a/crypto/src/asn1/DerGeneralString.cs +++ b/crypto/src/asn1/DerGeneralString.cs @@ -61,9 +61,9 @@ namespace Org.BouncyCastle.Asn1 return Strings.ToAsciiByteArray(str); } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.GeneralString, GetOctets()); + asn1Out.WriteEncodingDL(withID, Asn1Tags.GeneralString, GetOctets()); } protected override bool Asn1Equals( diff --git a/crypto/src/asn1/DerGeneralizedTime.cs b/crypto/src/asn1/DerGeneralizedTime.cs index 0b603d65d..d1505d9b0 100644 --- a/crypto/src/asn1/DerGeneralizedTime.cs +++ b/crypto/src/asn1/DerGeneralizedTime.cs @@ -295,9 +295,9 @@ namespace Org.BouncyCastle.Asn1 return Strings.ToAsciiByteArray(time); } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.GeneralizedTime, GetOctets()); + asn1Out.WriteEncodingDL(withID, Asn1Tags.GeneralizedTime, GetOctets()); } protected override bool Asn1Equals( diff --git a/crypto/src/asn1/DerGraphicString.cs b/crypto/src/asn1/DerGraphicString.cs index 879a2f658..e2901118d 100644 --- a/crypto/src/asn1/DerGraphicString.cs +++ b/crypto/src/asn1/DerGraphicString.cs @@ -79,9 +79,9 @@ namespace Org.BouncyCastle.Asn1 return Arrays.Clone(mString); } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.GraphicString, mString); + asn1Out.WriteEncodingDL(withID, Asn1Tags.GraphicString, mString); } protected override int Asn1GetHashCode() diff --git a/crypto/src/asn1/DerIA5String.cs b/crypto/src/asn1/DerIA5String.cs index 22311fdb8..14fefa941 100644 --- a/crypto/src/asn1/DerIA5String.cs +++ b/crypto/src/asn1/DerIA5String.cs @@ -100,9 +100,9 @@ namespace Org.BouncyCastle.Asn1 return Strings.ToAsciiByteArray(str); } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.IA5String, GetOctets()); + asn1Out.WriteEncodingDL(withID, Asn1Tags.IA5String, GetOctets()); } protected override int Asn1GetHashCode() diff --git a/crypto/src/asn1/DerInteger.cs b/crypto/src/asn1/DerInteger.cs index 43e991b36..c71f4685d 100644 --- a/crypto/src/asn1/DerInteger.cs +++ b/crypto/src/asn1/DerInteger.cs @@ -169,9 +169,9 @@ namespace Org.BouncyCastle.Asn1 } } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.Integer, bytes); + asn1Out.WriteEncodingDL(withID, Asn1Tags.Integer, bytes); } protected override int Asn1GetHashCode() diff --git a/crypto/src/asn1/DerNull.cs b/crypto/src/asn1/DerNull.cs index 60f040b40..01a2e3c72 100644 --- a/crypto/src/asn1/DerNull.cs +++ b/crypto/src/asn1/DerNull.cs @@ -16,12 +16,12 @@ namespace Org.BouncyCastle.Asn1 { } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.Null, ZeroBytes); - } + asn1Out.WriteEncodingDL(withID, Asn1Tags.Null, ZeroBytes); + } - protected override bool Asn1Equals(Asn1Object asn1Object) + protected override bool Asn1Equals(Asn1Object asn1Object) { return asn1Object is DerNull; } diff --git a/crypto/src/asn1/DerNumericString.cs b/crypto/src/asn1/DerNumericString.cs index 1163d71f4..7839b04ff 100644 --- a/crypto/src/asn1/DerNumericString.cs +++ b/crypto/src/asn1/DerNumericString.cs @@ -100,9 +100,9 @@ namespace Org.BouncyCastle.Asn1 return Strings.ToAsciiByteArray(str); } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.NumericString, GetOctets()); + asn1Out.WriteEncodingDL(withID, Asn1Tags.NumericString, GetOctets()); } protected override bool Asn1Equals( diff --git a/crypto/src/asn1/DerObjectIdentifier.cs b/crypto/src/asn1/DerObjectIdentifier.cs index aa40c4c06..9a4e80ac2 100644 --- a/crypto/src/asn1/DerObjectIdentifier.cs +++ b/crypto/src/asn1/DerObjectIdentifier.cs @@ -197,9 +197,9 @@ namespace Org.BouncyCastle.Asn1 } } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.ObjectIdentifier, GetContents()); + asn1Out.WriteEncodingDL(withID, Asn1Tags.ObjectIdentifier, GetContents()); } protected override int Asn1GetHashCode() diff --git a/crypto/src/asn1/DerOctetString.cs b/crypto/src/asn1/DerOctetString.cs index 4dc5bff2c..f865abff8 100644 --- a/crypto/src/asn1/DerOctetString.cs +++ b/crypto/src/asn1/DerOctetString.cs @@ -22,14 +22,14 @@ namespace Org.BouncyCastle.Asn1 { } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.OctetString, str); + asn1Out.WriteEncodingDL(withID, Asn1Tags.OctetString, str); } - internal static void Encode(Asn1OutputStream asn1Out, byte[] bytes, int offset, int length) + internal static void Encode(Asn1OutputStream asn1Out, bool withID, byte[] buf, int off, int len) { - asn1Out.WriteEncoded(Asn1Tags.OctetString, bytes, offset, length); + asn1Out.WriteEncodingDL(withID, Asn1Tags.OctetString, buf, off, len); } } } diff --git a/crypto/src/asn1/DerOutputStream.cs b/crypto/src/asn1/DerOutputStream.cs index 84d1af44b..b8cbe9ee2 100644 --- a/crypto/src/asn1/DerOutputStream.cs +++ b/crypto/src/asn1/DerOutputStream.cs @@ -17,119 +17,12 @@ namespace Org.BouncyCastle.Asn1 public virtual void WriteObject(Asn1Encodable encodable) { - new DerOutputStreamNew(s).WriteObject(encodable); + Asn1OutputStream.Create(s, Asn1Encodable.Der).WriteObject(encodable); } public virtual void WriteObject(Asn1Object primitive) { - new DerOutputStreamNew(s).WriteObject(primitive); - } - - internal virtual bool IsBer - { - get { return false; } - } - - internal void WriteDL(int length) - { - if (length < 128) - { - WriteByte((byte)length); - } - else - { - byte[] stack = new byte[5]; - int pos = stack.Length; - - do - { - stack[--pos] = (byte)length; - length >>= 8; - } - while (length > 0); - - int count = stack.Length - pos; - stack[--pos] = (byte)(0x80 | count); - - Write(stack, pos, count + 1); - } - } - - internal void WriteEncoded( - int tag, - byte[] bytes) - { - WriteByte((byte)tag); - WriteDL(bytes.Length); - Write(bytes, 0, bytes.Length); - } - - internal void WriteEncoded( - int tag, - byte first, - byte[] bytes) - { - WriteByte((byte)tag); - WriteDL(bytes.Length + 1); - WriteByte(first); - Write(bytes, 0, bytes.Length); - } - - internal void WriteEncoded( - int tag, - byte[] bytes, - int offset, - int length) - { - WriteByte((byte)tag); - WriteDL(length); - Write(bytes, offset, length); - } - - internal void WriteEncoded( - int flags, - int tagNo, - byte[] bytes) - { - WriteIdentifier(true, flags, tagNo); - WriteDL(bytes.Length); - Write(bytes, 0, bytes.Length); - } - - internal void WriteIdentifier(bool withID, int identifier) - { - if (withID) - { - WriteByte((byte)identifier); - } - } - - internal void WriteIdentifier(bool withID, int flags, int tag) - { - if (!withID) - { - // Don't write the identifier - } - else if (tag < 31) - { - WriteByte((byte)(flags | tag)); - } - else - { - byte[] stack = new byte[6]; - int pos = stack.Length; - - stack[--pos] = (byte)(tag & 0x7F); - while (tag > 127) - { - tag >>= 7; - stack[--pos] = (byte)(tag & 0x7F | 0x80); - } - - stack[--pos] = (byte)(flags | 0x1F); - - Write(stack, pos, stack.Length - pos); - } + Asn1OutputStream.Create(s, Asn1Encodable.Der).WriteObject(primitive); } } @@ -146,7 +39,7 @@ namespace Org.BouncyCastle.Asn1 get { return false; } } - internal override void WritePrimitive(Asn1Object primitive) + internal override void WritePrimitive(Asn1Object primitive, bool withID) { Asn1Set asn1Set = primitive as Asn1Set; if (null != asn1Set) @@ -158,7 +51,7 @@ namespace Org.BouncyCastle.Asn1 primitive = new DerSet(asn1Set.elements); } - primitive.Encode(this); + primitive.Encode(this, withID); } } } diff --git a/crypto/src/asn1/DerPrintableString.cs b/crypto/src/asn1/DerPrintableString.cs index 5198dc30c..5df1de547 100644 --- a/crypto/src/asn1/DerPrintableString.cs +++ b/crypto/src/asn1/DerPrintableString.cs @@ -100,9 +100,9 @@ namespace Org.BouncyCastle.Asn1 return Strings.ToAsciiByteArray(str); } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.PrintableString, GetOctets()); + asn1Out.WriteEncodingDL(withID, Asn1Tags.PrintableString, GetOctets()); } protected override bool Asn1Equals( diff --git a/crypto/src/asn1/DerSequence.cs b/crypto/src/asn1/DerSequence.cs index 05b6f4533..b5ab20b9e 100644 --- a/crypto/src/asn1/DerSequence.cs +++ b/crypto/src/asn1/DerSequence.cs @@ -53,11 +53,11 @@ namespace Org.BouncyCastle.Asn1 * ASN.1 descriptions given. Rather than just outputing Sequence, * we also have to specify Constructed, and the objects length. */ - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { if (Count < 1) { - asn1Out.WriteEncoded(Asn1Tags.Sequence | Asn1Tags.Constructed, Asn1OctetString.EmptyOctets); + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Sequence, Asn1OctetString.EmptyOctets); return; } @@ -75,7 +75,7 @@ namespace Org.BouncyCastle.Asn1 int length = (int)bOut.Position; #endif - asn1Out.WriteEncoded(Asn1Tags.Sequence | Asn1Tags.Constructed, bytes, 0, length); + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Sequence, bytes, 0, length); Platform.Dispose(dOut); } diff --git a/crypto/src/asn1/DerSet.cs b/crypto/src/asn1/DerSet.cs index 62d8873b8..517d83b5f 100644 --- a/crypto/src/asn1/DerSet.cs +++ b/crypto/src/asn1/DerSet.cs @@ -70,17 +70,17 @@ namespace Org.BouncyCastle.Asn1 * ASN.1 descriptions given. Rather than just outputing Set, * we also have to specify Constructed, and the objects length. */ - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { if (Count < 1) { - asn1Out.WriteEncoded(Asn1Tags.Set | Asn1Tags.Constructed, Asn1OctetString.EmptyOctets); + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Set, Asn1OctetString.EmptyOctets); return; } // TODO Intermediate buffer could be avoided if we could calculate expected length MemoryStream bOut = new MemoryStream(); - Asn1OutputStream dOut = Asn1OutputStream.Create(bOut, Asn1Encodable.Der); + Asn1OutputStream dOut = Asn1OutputStream.Create(bOut, Der); dOut.WriteElements(elements); dOut.Flush(); @@ -92,7 +92,7 @@ namespace Org.BouncyCastle.Asn1 int length = (int)bOut.Position; #endif - asn1Out.WriteEncoded(Asn1Tags.Set | Asn1Tags.Constructed, bytes, 0, length); + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Set, bytes, 0, length); Platform.Dispose(dOut); } diff --git a/crypto/src/asn1/DerT61String.cs b/crypto/src/asn1/DerT61String.cs index 40906f3c1..e4f84b10a 100644 --- a/crypto/src/asn1/DerT61String.cs +++ b/crypto/src/asn1/DerT61String.cs @@ -77,9 +77,9 @@ namespace Org.BouncyCastle.Asn1 return str; } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.T61String, GetOctets()); + asn1Out.WriteEncodingDL(withID, Asn1Tags.T61String, GetOctets()); } public byte[] GetOctets() diff --git a/crypto/src/asn1/DerTaggedObject.cs b/crypto/src/asn1/DerTaggedObject.cs index 40776ace3..7f1541c15 100644 --- a/crypto/src/asn1/DerTaggedObject.cs +++ b/crypto/src/asn1/DerTaggedObject.cs @@ -42,7 +42,7 @@ namespace Org.BouncyCastle.Asn1 { } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { if (!IsEmpty()) { @@ -50,21 +50,26 @@ namespace Org.BouncyCastle.Asn1 if (explicitly) { - asn1Out.WriteEncoded(Asn1Tags.Constructed | Asn1Tags.Tagged, tagNo, bytes); + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Tagged, tagNo, bytes); } else { // // need to mark constructed types... (preserve Constructed tag) // - int flags = (bytes[0] & Asn1Tags.Constructed) | Asn1Tags.Tagged; - asn1Out.WriteIdentifier(true, flags, tagNo); - asn1Out.Write(bytes, 1, bytes.Length - 1); + if (withID) + { + int flags = (bytes[0] & Asn1Tags.Constructed) | Asn1Tags.Tagged; + asn1Out.WriteIdentifier(true, flags, tagNo); + } + + asn1Out.Write(bytes, 1, bytes.Length - 1); } } else { - asn1Out.WriteEncoded(Asn1Tags.Constructed | Asn1Tags.Tagged, tagNo, new byte[0]); + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Tagged, tagNo, + Asn1OctetString.EmptyOctets); } } } diff --git a/crypto/src/asn1/DerUTCTime.cs b/crypto/src/asn1/DerUTCTime.cs index 7c8330874..55a1ac5c2 100644 --- a/crypto/src/asn1/DerUTCTime.cs +++ b/crypto/src/asn1/DerUTCTime.cs @@ -237,9 +237,9 @@ namespace Org.BouncyCastle.Asn1 return Strings.ToAsciiByteArray(time); } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.UtcTime, GetOctets()); + asn1Out.WriteEncodingDL(withID, Asn1Tags.UtcTime, GetOctets()); } protected override bool Asn1Equals( diff --git a/crypto/src/asn1/DerUTF8String.cs b/crypto/src/asn1/DerUTF8String.cs index 72e882afe..b9f389fce 100644 --- a/crypto/src/asn1/DerUTF8String.cs +++ b/crypto/src/asn1/DerUTF8String.cs @@ -89,9 +89,9 @@ namespace Org.BouncyCastle.Asn1 return this.str.Equals(other.str); } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.Utf8String, Encoding.UTF8.GetBytes(str)); + asn1Out.WriteEncodingDL(withID, Asn1Tags.Utf8String, Encoding.UTF8.GetBytes(str)); } } } diff --git a/crypto/src/asn1/DerUniversalString.cs b/crypto/src/asn1/DerUniversalString.cs index e7367dc38..29dbbce95 100644 --- a/crypto/src/asn1/DerUniversalString.cs +++ b/crypto/src/asn1/DerUniversalString.cs @@ -86,9 +86,9 @@ namespace Org.BouncyCastle.Asn1 return (byte[]) str.Clone(); } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.UniversalString, this.str); + asn1Out.WriteEncodingDL(withID, Asn1Tags.UniversalString, this.str); } protected override bool Asn1Equals( diff --git a/crypto/src/asn1/DerVideotexString.cs b/crypto/src/asn1/DerVideotexString.cs index c52987368..0e063b4fc 100644 --- a/crypto/src/asn1/DerVideotexString.cs +++ b/crypto/src/asn1/DerVideotexString.cs @@ -79,9 +79,9 @@ namespace Org.BouncyCastle.Asn1 return Arrays.Clone(mString); } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.VideotexString, mString); + asn1Out.WriteEncodingDL(withID, Asn1Tags.VideotexString, mString); } protected override int Asn1GetHashCode() diff --git a/crypto/src/asn1/DerVisibleString.cs b/crypto/src/asn1/DerVisibleString.cs index 3d25e788e..db6d7f818 100644 --- a/crypto/src/asn1/DerVisibleString.cs +++ b/crypto/src/asn1/DerVisibleString.cs @@ -86,9 +86,9 @@ namespace Org.BouncyCastle.Asn1 return Strings.ToAsciiByteArray(str); } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncoded(Asn1Tags.VisibleString, GetOctets()); + asn1Out.WriteEncodingDL(withID, Asn1Tags.VisibleString, GetOctets()); } protected override bool Asn1Equals( diff --git a/crypto/src/asn1/LazyDERSequence.cs b/crypto/src/asn1/LazyDERSequence.cs index bd14b6578..83997aa98 100644 --- a/crypto/src/asn1/LazyDERSequence.cs +++ b/crypto/src/asn1/LazyDERSequence.cs @@ -59,17 +59,17 @@ namespace Org.BouncyCastle.Asn1 } } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { lock (this) { if (encoded == null) { - base.Encode(asn1Out); + base.Encode(asn1Out, withID); } else { - asn1Out.WriteEncoded(Asn1Tags.Sequence | Asn1Tags.Constructed, encoded); + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Sequence, encoded); } } } diff --git a/crypto/src/asn1/LazyDERSet.cs b/crypto/src/asn1/LazyDERSet.cs index f8271f330..ae56f5e50 100644 --- a/crypto/src/asn1/LazyDERSet.cs +++ b/crypto/src/asn1/LazyDERSet.cs @@ -59,17 +59,17 @@ namespace Org.BouncyCastle.Asn1 } } - internal override void Encode(Asn1OutputStream asn1Out) + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { lock (this) { if (encoded == null) { - base.Encode(asn1Out); + base.Encode(asn1Out, withID); } else { - asn1Out.WriteEncoded(Asn1Tags.Set | Asn1Tags.Constructed, encoded); + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Set, encoded); } } } -- cgit 1.4.1