// Note: Recursive protected void Decode(byte[] asn1, ref int anPos, int anLength) { byte[] aTag; int nTagLength = 0; int nLength; byte[] aValue; // Check for multi byte tags if ((asn1[anPos + nTagLength++] & 0x1f) == 0x1f) { // Tag number is encoded in the following bytes as a sequence of seven bit bytes // The high bit of these bytes is used as a flag to indicate whether there's more tag available while ((asn1[anPos + nTagLength++] & 0x80) == 0x80) { } } aTag = new byte[nTagLength]; Buffer.BlockCopy(asn1, anPos, aTag, 0, nTagLength); // Minimum is 2 bytes (tag + length of 0) while (anPos < anLength - 1) { DecodeTLV(asn1, ref anPos, out aTag, out nLength, out aValue); // Sometimes we get trailing 0 if (aTag[0] == 0) { continue; } ASN1 elm = Add(new ASN1(aTag, aValue)); if ((aTag[0] & 0x20) == 0x20) { int nConstructedPos = anPos; elm.Decode(asn1, ref nConstructedPos, nConstructedPos + nLength); } anPos += nLength; // Value length } }