internal void ValidateAndSkipDerValue() { byte tag = PeekTag(); // If the tag is in the UNIVERSAL class if ((tag & TagClassMask) == 0) { // Tag 0 is special ("reserved for use by the encoding rules"), but mainly is used // as the End-of-Contents marker for the indefinite length encodings, which DER prohibits. // // Tag 15 is reserved. // // So either of these are invalid. if (tag == 0 || tag == 15) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } // DER limits the constructed encoding to SEQUENCE and SET, as well as anything which gets // a defined encoding as being an IMPLICIT SEQUENCE. bool expectConstructed = false; switch (tag & TagNumberMask) { case 0x08: // External or Instance-Of case 0x0B: // EmbeddedPDV case (byte)DerTag.Sequence: case (byte)DerTag.Set: case 0x1D: // Unrestricted Character String expectConstructed = true; break; } bool isConstructed = (tag & ConstructedFlag) == ConstructedFlag; if (expectConstructed != isConstructed) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } } EatTag((DerTag)tag); int contentLength = EatLength(); if (contentLength > 0 && (tag & ConstructedFlag) == ConstructedFlag) { var childReader = new DerSequenceReader(true, _data, _position, _end - _position); while (childReader.HasData) { childReader.ValidateAndSkipDerValue(); } } _position += contentLength; }