NBitcoin.BouncyCastle.Asn1.Asn1InputStream.ReadLength C# (CSharp) Method

ReadLength() public static method

public static ReadLength ( Stream s, int limit ) : int
s Stream
limit int
return int
		public static int ReadLength(
			Stream s,
			int limit)
		{
			int length = s.ReadByte();
			if(length < 0)
				throw new EndOfStreamException("EOF found when length expected");

			if(length == 0x80)
				return -1;      // indefinite-length encoding

			if(length > 127)
			{
				int size = length & 0x7f;

				// Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
				if(size > 4)
					throw new IOException("DER length more than 4 bytes: " + size);

				length = 0;
				for(int i = 0; i < size; i++)
				{
					int next = s.ReadByte();

					if(next < 0)
						throw new EndOfStreamException("EOF found reading length");

					length = (length << 8) + next;
				}

				if(length < 0)
					throw new IOException("Corrupted stream - negative length found");

				if(length >= limit)   // after all we must have read at least 1 byte
					throw new IOException("Corrupted stream - out of bounds length found");
			}

			return length;
		}

Usage Example

示例#1
0
        public virtual IAsn1Convertible ReadObject()
        {
            int tag = _in.ReadByte();

            if (tag == -1)
            {
                return(null);
            }

            // turn of looking for "00" while we resolve the tag
            Set00Check(false);

            //
            // calculate tag number
            //
            int tagNo = Asn1InputStream.ReadTagNumber(_in, tag);

            bool isConstructed = (tag & Asn1Tags.Constructed) != 0;

            //
            // calculate length
            //
            int length = Asn1InputStream.ReadLength(_in, _limit);

            if (length < 0)             // indefinite length method
            {
                if (!isConstructed)
                {
                    throw new IOException("indefinite length primitive encoding encountered");
                }

                IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit);
                Asn1StreamParser            sp    = new Asn1StreamParser(indIn, _limit);

                if ((tag & Asn1Tags.Application) != 0)
                {
                    return(new BerApplicationSpecificParser(tagNo, sp));
                }

                if ((tag & Asn1Tags.Tagged) != 0)
                {
                    return(new BerTaggedObjectParser(true, tagNo, sp));
                }

                return(sp.ReadIndef(tagNo));
            }
            else
            {
                DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length);

                if ((tag & Asn1Tags.Application) != 0)
                {
                    return(new DerApplicationSpecific(isConstructed, tagNo, defIn.ToArray()));
                }

                if ((tag & Asn1Tags.Tagged) != 0)
                {
                    return(new BerTaggedObjectParser(isConstructed, tagNo, new Asn1StreamParser(defIn)));
                }

                if (isConstructed)
                {
                    // TODO There are other tags that may be constructed (e.g. BitString)
                    switch (tagNo)
                    {
                    case Asn1Tags.OctetString:
                        //
                        // yes, people actually do this...
                        //
                        return(new BerOctetStringParser(new Asn1StreamParser(defIn)));

                    case Asn1Tags.Sequence:
                        return(new DerSequenceParser(new Asn1StreamParser(defIn)));

                    case Asn1Tags.Set:
                        return(new DerSetParser(new Asn1StreamParser(defIn)));

                    case Asn1Tags.External:
                        return(new DerExternalParser(new Asn1StreamParser(defIn)));

                    default:
                        throw new IOException("unknown tag " + tagNo + " encountered");
                    }
                }

                // Some primitive encodings can be handled by parsers too...
                switch (tagNo)
                {
                case Asn1Tags.OctetString:
                    return(new DerOctetStringParser(defIn));
                }

                try
                {
                    return(Asn1InputStream.CreatePrimitiveDerObject(tagNo, defIn, tmpBuffers));
                }
                catch (ArgumentException e)
                {
                    throw new Asn1Exception("corrupted stream detected", e);
                }
            }
        }