diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2021-10-14 18:46:47 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2021-10-14 18:46:47 +0700 |
commit | c3a6083bace63a12515b08b30e4ffa42fc74a0a0 (patch) | |
tree | 694e96380bbf30b597462be7dcefe0dc4ceb7406 | |
parent | Add WriteElements method (diff) | |
download | BouncyCastle.NET-ed25519-c3a6083bace63a12515b08b30e4ffa42fc74a0a0.tar.xz |
More ASN.1 updates from bc-java
-rw-r--r-- | crypto/src/asn1/Asn1Object.cs | 18 | ||||
-rw-r--r-- | crypto/src/asn1/Asn1OutputStream.cs | 44 | ||||
-rw-r--r-- | crypto/src/asn1/BEROctetStringGenerator.cs | 6 | ||||
-rw-r--r-- | crypto/src/asn1/BerTaggedObject.cs | 6 | ||||
-rw-r--r-- | crypto/src/asn1/DerOutputStream.cs | 182 | ||||
-rw-r--r-- | crypto/src/asn1/DerTaggedObject.cs | 2 |
6 files changed, 126 insertions, 132 deletions
diff --git a/crypto/src/asn1/Asn1Object.cs b/crypto/src/asn1/Asn1Object.cs index 1abf0e0bd..d60a85348 100644 --- a/crypto/src/asn1/Asn1Object.cs +++ b/crypto/src/asn1/Asn1Object.cs @@ -13,23 +13,7 @@ namespace Org.BouncyCastle.Asn1 public override void EncodeTo(Stream output, string encoding) { - Asn1OutputStream asn1Out = Asn1OutputStream.Create(output, encoding); - Asn1Object asn1Object = this; - - if (Der.Equals(encoding)) - { - Asn1Set asn1Set = asn1Object as Asn1Set; - if (null != asn1Set) - { - /* - * NOTE: Even a DerSet isn't necessarily already in sorted order (particularly from DerSetParser), - * so all sets have to be converted here. - */ - asn1Object = new DerSet(asn1Set.elements); - } - } - - asn1Out.WriteObject(asn1Object); + Asn1OutputStream.Create(output, encoding).WriteObject(this); } /// <summary>Create a base ASN.1 object from a byte array.</summary> diff --git a/crypto/src/asn1/Asn1OutputStream.cs b/crypto/src/asn1/Asn1OutputStream.cs index 5746d1c59..e6eec563e 100644 --- a/crypto/src/asn1/Asn1OutputStream.cs +++ b/crypto/src/asn1/Asn1OutputStream.cs @@ -29,6 +29,29 @@ namespace Org.BouncyCastle.Asn1 { } + public override void WriteObject(Asn1Encodable encodable) + { + if (null == encodable) + throw new IOException("null object detected"); + + WritePrimitive(encodable.ToAsn1Object()); + FlushInternal(); + } + + public override void WriteObject(Asn1Object primitive) + { + if (null == primitive) + throw new IOException("null object detected"); + + WritePrimitive(primitive); + FlushInternal(); + } + + internal void FlushInternal() + { + // Placeholder to support future internal buffering + } + internal override bool IsBer { get { return true; } @@ -42,27 +65,16 @@ namespace Org.BouncyCastle.Asn1 } } - public override void WriteObject(Asn1Encodable obj) + internal virtual void WritePrimitive(Asn1Object primitive) { - if (obj == null) - { - WriteNull(); - } - else - { - obj.ToAsn1Object().Encode(this); - } + primitive.Encode(this); } - public override void WriteObject(Asn1Object obj) + internal virtual void WritePrimitives(Asn1Object[] primitives) { - if (obj == null) - { - WriteNull(); - } - else + for (int i = 0, count = primitives.Length; i < count; ++i) { - obj.Encode(this); + WritePrimitive(primitives[i]); } } } diff --git a/crypto/src/asn1/BEROctetStringGenerator.cs b/crypto/src/asn1/BEROctetStringGenerator.cs index de039014b..4a7f1e8e5 100644 --- a/crypto/src/asn1/BEROctetStringGenerator.cs +++ b/crypto/src/asn1/BEROctetStringGenerator.cs @@ -112,6 +112,8 @@ namespace Org.BouncyCastle.Asn1 DerOctetString.Encode(_derOut, _buf, 0, _off); } + _derOut.FlushInternal(); + _gen.WriteBerEnd(); } base.Dispose(disposing); @@ -124,7 +126,9 @@ namespace Org.BouncyCastle.Asn1 DerOctetString.Encode(_derOut, _buf, 0, _off); } - _gen.WriteBerEnd(); + _derOut.FlushInternal(); + + _gen.WriteBerEnd(); base.Close(); } #endif diff --git a/crypto/src/asn1/BerTaggedObject.cs b/crypto/src/asn1/BerTaggedObject.cs index 9dadc24ba..097f77610 100644 --- a/crypto/src/asn1/BerTaggedObject.cs +++ b/crypto/src/asn1/BerTaggedObject.cs @@ -51,7 +51,7 @@ namespace Org.BouncyCastle.Asn1 { if (asn1Out.IsBer) { - asn1Out.WriteTag(Asn1Tags.Constructed | Asn1Tags.Tagged, tagNo); + asn1Out.WriteIdentifier(true, Asn1Tags.Constructed | Asn1Tags.Tagged, tagNo); asn1Out.WriteByte(0x80); if (!IsEmpty()) @@ -86,12 +86,12 @@ namespace Org.BouncyCastle.Asn1 foreach (Asn1Encodable o in eObj) { - asn1Out.WriteObject(o); + asn1Out.WritePrimitive(o.ToAsn1Object()); } } else { - asn1Out.WriteObject(obj); + asn1Out.WritePrimitive(obj.ToAsn1Object()); } } diff --git a/crypto/src/asn1/DerOutputStream.cs b/crypto/src/asn1/DerOutputStream.cs index 3ecdcd11f..84d1af44b 100644 --- a/crypto/src/asn1/DerOutputStream.cs +++ b/crypto/src/asn1/DerOutputStream.cs @@ -15,43 +15,52 @@ namespace Org.BouncyCastle.Asn1 { } + public virtual void WriteObject(Asn1Encodable encodable) + { + new DerOutputStreamNew(s).WriteObject(encodable); + } + + public virtual void WriteObject(Asn1Object primitive) + { + new DerOutputStreamNew(s).WriteObject(primitive); + } + internal virtual bool IsBer { get { return false; } } - private void WriteLength( - int length) + internal void WriteDL(int length) { - if (length > 127) - { - int size = 1; - uint val = (uint)length; - - while ((val >>= 8) != 0) - { - size++; - } - - WriteByte((byte)(size | 0x80)); - - for (int i = (size - 1) * 8; i >= 0; i -= 8) - { - WriteByte((byte)(length >> i)); - } - } - else - { - WriteByte((byte)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( + internal void WriteEncoded( int tag, byte[] bytes) { WriteByte((byte)tag); - WriteLength(bytes.Length); + WriteDL(bytes.Length); Write(bytes, 0, bytes.Length); } @@ -61,7 +70,7 @@ namespace Org.BouncyCastle.Asn1 byte[] bytes) { WriteByte((byte)tag); - WriteLength(bytes.Length + 1); + WriteDL(bytes.Length + 1); WriteByte(first); Write(bytes, 0, bytes.Length); } @@ -73,85 +82,55 @@ namespace Org.BouncyCastle.Asn1 int length) { WriteByte((byte)tag); - WriteLength(length); + WriteDL(length); Write(bytes, offset, length); } - internal void WriteTag( - int flags, - int tagNo) - { - if (tagNo < 31) - { - WriteByte((byte)(flags | tagNo)); - } - else - { - WriteByte((byte)(flags | 0x1f)); - if (tagNo < 128) - { - WriteByte((byte)tagNo); - } - else - { - byte[] stack = new byte[5]; - int pos = stack.Length; - - stack[--pos] = (byte)(tagNo & 0x7F); - - do - { - tagNo >>= 7; - stack[--pos] = (byte)(tagNo & 0x7F | 0x80); - } - while (tagNo > 127); - - Write(stack, pos, stack.Length - pos); - } - } - } - internal void WriteEncoded( int flags, int tagNo, byte[] bytes) { - WriteTag(flags, tagNo); - WriteLength(bytes.Length); + WriteIdentifier(true, flags, tagNo); + WriteDL(bytes.Length); Write(bytes, 0, bytes.Length); } - protected void WriteNull() - { - WriteByte(Asn1Tags.Null); - WriteByte(0x00); - } - - public virtual void WriteObject( - Asn1Encodable obj) - { - if (obj == null) - { - WriteNull(); - } - else - { - obj.ToAsn1Object().Encode(new DerOutputStreamNew(s)); - } - } + internal void WriteIdentifier(bool withID, int identifier) + { + if (withID) + { + WriteByte((byte)identifier); + } + } - public virtual void WriteObject( - Asn1Object obj) - { - if (obj == null) - { - WriteNull(); - } - else - { - obj.Encode(new DerOutputStreamNew(s)); - } - } + 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 class DerOutputStreamNew @@ -166,5 +145,20 @@ namespace Org.BouncyCastle.Asn1 { get { return false; } } + + internal override void WritePrimitive(Asn1Object primitive) + { + Asn1Set asn1Set = primitive as Asn1Set; + if (null != asn1Set) + { + /* + * NOTE: Even a DerSet isn't necessarily already in sorted order (particularly from DerSetParser), + * so all sets have to be converted here. + */ + primitive = new DerSet(asn1Set.elements); + } + + primitive.Encode(this); + } } } diff --git a/crypto/src/asn1/DerTaggedObject.cs b/crypto/src/asn1/DerTaggedObject.cs index 182d5ee47..40776ace3 100644 --- a/crypto/src/asn1/DerTaggedObject.cs +++ b/crypto/src/asn1/DerTaggedObject.cs @@ -58,7 +58,7 @@ namespace Org.BouncyCastle.Asn1 // need to mark constructed types... (preserve Constructed tag) // int flags = (bytes[0] & Asn1Tags.Constructed) | Asn1Tags.Tagged; - asn1Out.WriteTag(flags, tagNo); + asn1Out.WriteIdentifier(true, flags, tagNo); asn1Out.Write(bytes, 1, bytes.Length - 1); } } |