diff options
Diffstat (limited to 'crypto/src/asn1/Asn1OutputStream.cs')
-rw-r--r-- | crypto/src/asn1/Asn1OutputStream.cs | 130 |
1 files changed, 123 insertions, 7 deletions
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); } } } |