From c3a6083bace63a12515b08b30e4ffa42fc74a0a0 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Thu, 14 Oct 2021 18:46:47 +0700 Subject: More ASN.1 updates from bc-java --- crypto/src/asn1/DerOutputStream.cs | 182 ++++++++++++++++++------------------- 1 file changed, 88 insertions(+), 94 deletions(-) (limited to 'crypto/src/asn1/DerOutputStream.cs') 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); + } } } -- cgit 1.4.1