Пример #1
0
        private BEROctetString buildConstructedOctetString()
        {
            ArrayList octs = new ArrayList();

            for (;;)
            {
                ASN1Object o = readObject();

                if (o == END_OF_STREAM)
                {
                    break;
                }

                octs.Add(o);
            }

            return(new BEROctetString(octs));
        }
Пример #2
0
 public BEROctetString(ASN1Object obj) : base(obj)
 {
 }
Пример #3
0
        public ASN1Object readObject()
        {
            int tag = ReadByte();

            if (tag == -1)
            {
                if (eofFound)
                {
                    throw new EndOfStreamException("attempt to read past end of file.");
                }

                eofFound = true;

                return(null);
            }

            int length = readLength();

            if (length < 0)    // indefinite length method
            {
                switch (tag)
                {
                case ASN1Tags.NULL:
                    return(new BERNull());

                case ASN1Tags.SEQUENCE | ASN1Tags.CONSTRUCTED:
                    ASN1EncodableVector v = new ASN1EncodableVector();

                    for (;;)
                    {
                        ASN1Object obj = readObject();

                        if (obj == END_OF_STREAM)
                        {
                            break;
                        }

                        v.add(obj);
                    }
                    return(new BERSequence(v));

                case ASN1Tags.SET | ASN1Tags.CONSTRUCTED:
                    v = new ASN1EncodableVector();

                    for (;;)
                    {
                        ASN1Object obj = readObject();

                        if (obj == END_OF_STREAM)
                        {
                            break;
                        }

                        v.add(obj);
                    }
                    return(new BERSet(v, false));

                case ASN1Tags.OCTET_STRING | ASN1Tags.CONSTRUCTED:
                    return(buildConstructedOctetString());

                default:
                    //
                    // with tagged object tag number is bottom 5 bits
                    //
                    if ((tag & (int)ASN1Tags.TAGGED) != 0)
                    {
                        int tagNo = tag & 0x1f;

                        if (tagNo == 0x1f)
                        {
                            int b = ReadByte();

                            tagNo = 0;

                            while ((b >= 0) && ((b & 0x80) != 0))
                            {
                                tagNo  |= (b & 0x7f);
                                tagNo <<= 7;
                                b       = ReadByte();
                            }

                            tagNo |= (b & 0x7f);
                        }

                        //
                        // simple type - implicit... return an octet string
                        //
                        if ((tag & (int)ASN1Tags.CONSTRUCTED) == 0)
                        {
                            byte[] bytes = readIndefiniteLengthFully();

                            return(new BERTaggedObject(false, tagNo, new DEROctetString(bytes)));
                        }

                        //
                        // either constructed or explicitly tagged
                        //
                        ASN1Object dObj = readObject();

                        if (dObj == END_OF_STREAM)     // empty tag!
                        {
                            return(new DERTaggedObject(tagNo));
                        }

                        ASN1Object next = readObject();

                        //
                        // explicitly tagged (probably!) - if it isn't we'd have to
                        // tell from the context
                        //
                        if (next == END_OF_STREAM)
                        {
                            return(new BERTaggedObject(tagNo, dObj));
                        }

                        //
                        // another implicit object, we'll create a sequence...
                        //
                        v = new ASN1EncodableVector();

                        v.add(dObj);

                        do
                        {
                            v.add(next);
                            next = readObject();
                        }while (next != END_OF_STREAM);

                        return(new BERTaggedObject(false, tagNo, new BERSequence(v)));
                    }

                    throw new IOException("unknown BER object encountered");
                }
            }
            else
            {
                if (tag == 0 && length == 0)    // end of contents marker.
                {
                    return(END_OF_STREAM);
                }

                byte[] bytes = new byte[length];

                readFully(bytes);

                return(buildObject(tag, bytes));
            }
        }
Пример #4
0
        /**
         * build an object given its tag and a byte stream to construct it
         * from.
         */
        protected ASN1Object buildObject(
            int derTags,
            byte[]    bytes)
        {
            int tag = derTags;

            if ((tag & ASN1Tags.APPLICATION) != 0)
            {
                return(new DERApplicationSpecific(derTags, bytes));
            }

            switch (tag)
            {
            case ASN1Tags.NULL:
                return(new DERNull());

            case ASN1Tags.SEQUENCE | ASN1Tags.CONSTRUCTED:
                MemoryStream        bIn = new MemoryStream(bytes);
                ASN1InputStream     aIn = new ASN1InputStream(bIn);
                ASN1EncodableVector v   = new ASN1EncodableVector();

                ASN1Object obj = aIn.readObject();

                while (obj != null)
                {
                    v.add(obj);
                    obj = aIn.readObject();
                }

                return(new DERSequence(v));

            case ASN1Tags.SET | ASN1Tags.CONSTRUCTED:
                bIn = new MemoryStream(bytes);
                aIn = new ASN1InputStream(bIn);
                v   = new ASN1EncodableVector();

                obj = aIn.readObject();

                while (obj != null)
                {
                    v.add(obj);
                    obj = aIn.readObject();
                }

                return(new DERSet(v, false));

            case ASN1Tags.BOOLEAN:
                return(new DERBoolean(bytes));

            case ASN1Tags.INTEGER:
                return(new DERInteger(bytes));

            case ASN1Tags.ENUMERATED:
                return(new DEREnumerated(bytes));

            case ASN1Tags.OBJECT_IDENTIFIER:
                return(new DERObjectIdentifier(bytes));

            case ASN1Tags.BIT_STRING:
                int    padBits = bytes[0];
                byte[] data    = new byte[bytes.Length - 1];

                Array.Copy(bytes, 1, data, 0, bytes.Length - 1);

                return(new DERBitString(data, padBits));

            case ASN1Tags.NUMERIC_STRING:
                return(new DERNumericString(bytes));

            case ASN1Tags.UTF8_STRING:
                return(new DERUTF8String(bytes));

            case ASN1Tags.PRINTABLE_STRING:
                return(new DERPrintableString(bytes));

            case ASN1Tags.IA5_STRING:
                return(new DERIA5String(bytes));

            case ASN1Tags.T61_STRING:
                return(new DERT61String(bytes));

            case ASN1Tags.VISIBLE_STRING:
                return(new DERVisibleString(bytes));

            case ASN1Tags.GENERAL_STRING:
                return(new DERGeneralString(bytes));

            case ASN1Tags.UNIVERSAL_STRING:
                return(new DERUniversalString(bytes));

            case ASN1Tags.BMP_STRING:
                return(new DERBMPString(bytes));

            case ASN1Tags.OCTET_STRING:
                return(new DEROctetString(bytes));

            case ASN1Tags.UTC_TIME:
                return(new DERUTCTime(bytes));

            case ASN1Tags.GENERALIZED_TIME:
                return(new DERGeneralizedTime(bytes));

            default:
                //
                // with tagged object tag number is bottom 5 bits
                //
                if ((tag & (int)ASN1Tags.TAGGED) != 0)
                {
                    int tagNo = tag & 0x1f;

                    if (tagNo == 0x1f)
                    {
                        int idx = 0;

                        tagNo = 0;

                        while ((bytes[idx] & 0x80) != 0)
                        {
                            tagNo  |= (bytes[idx++] & 0x7f);
                            tagNo <<= 7;
                        }

                        tagNo |= (bytes[idx] & 0x7f);

                        byte[] tmp = bytes;

                        bytes = new byte[tmp.Length - (idx + 1)];
                        Array.Copy(tmp, idx + 1, bytes, 0, bytes.Length);
                    }

                    if (bytes.Length == 0)        // empty tag!
                    {
                        if ((tag & (int)ASN1Tags.CONSTRUCTED) == 0)
                        {
                            return(new DERTaggedObject(false, tagNo, new DERNull()));
                        }
                        else
                        {
                            return(new DERTaggedObject(false, tagNo, new DERSequence()));
                        }
                    }

                    //
                    // simple type - implicit... return an octet string
                    //
                    if ((tag & (int)ASN1Tags.CONSTRUCTED) == 0)
                    {
                        return(new DERTaggedObject(false, tagNo, new DEROctetString(bytes)));
                    }

                    bIn = new MemoryStream(bytes);
                    aIn = new ASN1InputStream(bIn);

                    ASN1Encodable dObj = aIn.readObject();

                    //
                    // explicitly tagged (probably!) - if it isn't we'd have to
                    // tell from the context
                    //

//                    if (aIn.available() == 0)
                    if (aIn.Position == bytes.Length) //FIXME?
                    {
                        return(new DERTaggedObject(tagNo, dObj));
                    }

                    //
                    // another implicit object, we'll create a sequence...
                    //
                    v = new ASN1EncodableVector();

                    while (dObj != null)
                    {
                        v.add(dObj);
                        dObj = aIn.readObject();
                    }

                    return(new DERTaggedObject(false, tagNo, new DERSequence(v)));
                }

                return(new DERUnknownTag(tag, bytes));
            }
        }