Example #1
0
        private static char[] GetBmpCharBuffer(DefiniteLengthInputStream defIn)
        {
            int remainingBytes = defIn.Remaining;

            if (0 != (remainingBytes & 1))
            {
                throw new IOException("malformed BMPString encoding encountered");
            }

            char[] str       = new char[remainingBytes / 2];
            int    stringPos = 0;

            byte[] buf = new byte[8];
            while (remainingBytes >= 8)
            {
                if (Streams.ReadFully(defIn, buf, 0, 8) != 8)
                {
                    throw new EndOfStreamException("EOF encountered in middle of BMPString");
                }

                str[stringPos]     = (char)((buf[0] << 8) | (buf[1] & 0xFF));
                str[stringPos + 1] = (char)((buf[2] << 8) | (buf[3] & 0xFF));
                str[stringPos + 2] = (char)((buf[4] << 8) | (buf[5] & 0xFF));
                str[stringPos + 3] = (char)((buf[6] << 8) | (buf[7] & 0xFF));
                stringPos         += 4;
                remainingBytes    -= 8;
            }
            if (remainingBytes > 0)
            {
                if (Streams.ReadFully(defIn, buf, 0, remainingBytes) != remainingBytes)
                {
                    throw new EndOfStreamException("EOF encountered in middle of BMPString");
                }

                int bufPos = 0;
                do
                {
                    int b1 = buf[bufPos++] << 8;
                    int b2 = buf[bufPos++] & 0xFF;
                    str[stringPos++] = (char)(b1 | b2);
                }while (bufPos < remainingBytes);
            }

            if (0 != defIn.Remaining || str.Length != stringPos)
            {
                throw new InvalidOperationException();
            }

            return(str);
        }
Example #2
0
        internal virtual Asn1EncodableVector ReadVector(DefiniteLengthInputStream dIn)
        {
            if (dIn.Remaining < 1)
            {
                return(new Asn1EncodableVector(0));
            }

            Asn1InputStream     subStream = new Asn1InputStream(dIn);
            Asn1EncodableVector v         = new Asn1EncodableVector();
            Asn1Object          o;

            while ((o = subStream.ReadObject()) != null)
            {
                v.Add(o);
            }

            return(v);
        }
Example #3
0
        private static byte[] GetBuffer(DefiniteLengthInputStream defIn, byte[][] tmpBuffers)
        {
            int len = defIn.Remaining;

            if (len >= tmpBuffers.Length)
            {
                return(defIn.ToArray());
            }

            byte[] buf = tmpBuffers[len];
            if (buf == null)
            {
                buf = tmpBuffers[len] = new byte[len];
            }

            defIn.ReadAllIntoByteArray(buf);

            return(buf);
        }
Example #4
0
        internal Asn1Object ReadTaggedObject(bool constructed, int tag)
        {
            if (!constructed)
            {
                // Note: !CONSTRUCTED => IMPLICIT
                DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in;
                return(new DerTaggedObject(false, tag, new DerOctetString(defIn.ToArray())));
            }

            Asn1EncodableVector v = ReadVector();

            if (_in is IndefiniteLengthInputStream)
            {
                return(v.Count == 1
                                        ? new BerTaggedObject(true, tag, v[0])
                                        : new BerTaggedObject(false, tag, BerSequence.FromVector(v)));
            }

            return(v.Count == 1
                                ? new DerTaggedObject(true, tag, v[0])
                                : new DerTaggedObject(false, tag, DerSequence.FromVector(v)));
        }
Example #5
0
        /**
         * build an object given its tag and the number of bytes to construct it from.
         */
        private Asn1Object BuildObject(
            int tag,
            int tagNo,
            int length)
        {
            bool isConstructed = (tag & Asn1Tags.Constructed) != 0;

            DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this.s, length, limit);

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

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

            if (isConstructed)
            {
                // TODO There are other tags that may be constructed (e.g. BitString)
                switch (tagNo)
                {
                case Asn1Tags.OctetString:
                {
                    //
                    // yes, people actually do this...
                    //
                    Asn1EncodableVector v       = ReadVector(defIn);
                    Asn1OctetString[]   strings = new Asn1OctetString[v.Count];

                    for (int i = 0; i != strings.Length; i++)
                    {
                        Asn1Encodable asn1Obj = v[i];
                        if (!(asn1Obj is Asn1OctetString))
                        {
                            throw new Asn1Exception("unknown object encountered in constructed OCTET STRING: "
                                                    + Platform.GetTypeName(asn1Obj));
                        }

                        strings[i] = (Asn1OctetString)asn1Obj;
                    }

                    return(new BerOctetString(strings));
                }

                case Asn1Tags.Sequence:
                    return(CreateDerSequence(defIn));

                case Asn1Tags.Set:
                    return(CreateDerSet(defIn));

                case Asn1Tags.External:
                    return(new DerExternal(ReadVector(defIn)));

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

            return(CreatePrimitiveDerObject(tagNo, defIn, tmpBuffers));
        }
Example #6
0
        internal static Asn1Object CreatePrimitiveDerObject(
            int tagNo,
            DefiniteLengthInputStream defIn,
            byte[][] tmpBuffers)
        {
            switch (tagNo)
            {
            case Asn1Tags.BmpString:
                return(new DerBmpString(GetBmpCharBuffer(defIn)));

            case Asn1Tags.Boolean:
                return(DerBoolean.FromOctetString(GetBuffer(defIn, tmpBuffers)));

            case Asn1Tags.Enumerated:
                return(DerEnumerated.FromOctetString(GetBuffer(defIn, tmpBuffers)));

            case Asn1Tags.ObjectIdentifier:
                return(DerObjectIdentifier.FromOctetString(GetBuffer(defIn, tmpBuffers)));
            }

            byte[] bytes = defIn.ToArray();

            switch (tagNo)
            {
            case Asn1Tags.BitString:
                return(DerBitString.FromAsn1Octets(bytes));

            case Asn1Tags.GeneralizedTime:
                return(new DerGeneralizedTime(bytes));

            case Asn1Tags.GeneralString:
                return(new DerGeneralString(bytes));

            case Asn1Tags.GraphicString:
                return(new DerGraphicString(bytes));

            case Asn1Tags.IA5String:
                return(new DerIA5String(bytes));

            case Asn1Tags.Integer:
                return(new DerInteger(bytes, false));

            case Asn1Tags.Null:
                return(DerNull.Instance);      // actual content is ignored (enforce 0 length?)

            case Asn1Tags.NumericString:
                return(new DerNumericString(bytes));

            case Asn1Tags.OctetString:
                return(new DerOctetString(bytes));

            case Asn1Tags.PrintableString:
                return(new DerPrintableString(bytes));

            case Asn1Tags.T61String:
                return(new DerT61String(bytes));

            case Asn1Tags.UniversalString:
                return(new DerUniversalString(bytes));

            case Asn1Tags.UtcTime:
                return(new DerUtcTime(bytes));

            case Asn1Tags.Utf8String:
                return(new DerUtf8String(bytes));

            case Asn1Tags.VideotexString:
                return(new DerVideotexString(bytes));

            case Asn1Tags.VisibleString:
                return(new DerVisibleString(bytes));

            default:
                throw new IOException("unknown tag " + tagNo + " encountered");
            }
        }
Example #7
0
 internal virtual DerSet CreateDerSet(
     DefiniteLengthInputStream dIn)
 {
     return(DerSet.FromVector(ReadVector(dIn), false));
 }
Example #8
0
 internal virtual DerSequence CreateDerSequence(
     DefiniteLengthInputStream dIn)
 {
     return(DerSequence.FromVector(ReadVector(dIn)));
 }
Example #9
0
 internal DerOctetStringParser(
     DefiniteLengthInputStream stream)
 {
     this.stream = stream;
 }
Example #10
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,
                                                    tagNo == Asn1Tags.OctetString || tagNo == Asn1Tags.Sequence || tagNo == Asn1Tags.Set || tagNo == Asn1Tags.External);

            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, _limit);

                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);
                }
            }
        }