diff options
Diffstat (limited to 'crypto/src/asn1/PrimitiveDerEncodingSuffixed.cs')
-rw-r--r-- | crypto/src/asn1/PrimitiveDerEncodingSuffixed.cs | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/crypto/src/asn1/PrimitiveDerEncodingSuffixed.cs b/crypto/src/asn1/PrimitiveDerEncodingSuffixed.cs new file mode 100644 index 000000000..7f9f38d99 --- /dev/null +++ b/crypto/src/asn1/PrimitiveDerEncodingSuffixed.cs @@ -0,0 +1,83 @@ +using System; +using System.Diagnostics; + +namespace Org.BouncyCastle.Asn1 +{ + internal class PrimitiveDerEncodingSuffixed + : DerEncoding + { + private readonly byte[] m_contentsOctets; + private readonly byte m_contentsSuffix; + + internal PrimitiveDerEncodingSuffixed(int tagClass, int tagNo, byte[] contentsOctets, byte contentsSuffix) + : base(tagClass, tagNo) + { + Debug.Assert(contentsOctets != null); + Debug.Assert(contentsOctets.Length > 0); + m_contentsOctets = contentsOctets; + m_contentsSuffix = contentsSuffix; + } + + protected internal override int CompareLengthAndContents(DerEncoding other) + { + if (other is PrimitiveDerEncodingSuffixed suff) + { + return CompareSuffixed(this.m_contentsOctets, this.m_contentsSuffix, + suff.m_contentsOctets, suff.m_contentsSuffix); + } + else if (other is PrimitiveDerEncoding that) + { + int length = that.m_contentsOctets.Length; + if (length == 0) + return this.m_contentsOctets.Length; + + return CompareSuffixed(this.m_contentsOctets, this.m_contentsSuffix, + that.m_contentsOctets, that.m_contentsOctets[length - 1]); + } + else + { + throw new InvalidOperationException(); + } + } + + public override void Encode(Asn1OutputStream asn1Out) + { + asn1Out.WriteIdentifier(m_tagClass, m_tagNo); + asn1Out.WriteDL(m_contentsOctets.Length); + asn1Out.Write(m_contentsOctets, 0, m_contentsOctets.Length - 1); + asn1Out.WriteByte(m_contentsSuffix); + } + + public override int GetLength() + { + return Asn1OutputStream.GetLengthOfEncodingDL(m_tagNo, m_contentsOctets.Length); + } + + private static int CompareSuffixed(byte[] octetsA, byte suffixA, byte[] octetsB, byte suffixB) + { + Debug.Assert(octetsA.Length > 0); + Debug.Assert(octetsB.Length > 0); + + int length = octetsA.Length; + if (length != octetsB.Length) + return length - octetsB.Length; + + int last = length - 1; +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + int c = octetsA.AsSpan(0, last).SequenceCompareTo( + octetsB.AsSpan(0, last)); + if (c != 0) + return c; +#else + for (int i = 0; i < last; i++) + { + byte ai = octetsA[i], bi = octetsB[i]; + if (ai != bi) + return ai - bi; + } +#endif + + return suffixA - suffixB; + } + } +} |