예제 #1
0
 /**
  * create a sequence containing a vector of objects.
  */
 public DERSequence(
     ASN1EncodableVector v)
 {
     for (int i = 0; i != v.size(); i++)
     {
         this.addObject(v.get(i));
     }
 }
예제 #2
0
        /**
         * Return an ASN1 set from a tagged object. There is a special
         * case here, if an object appears to have been explicitly tagged on
         * reading but we were expecting it to be implictly tagged in the
         * normal course of events it indicates that we lost the surrounding
         * set - so we need to add it back (this will happen if the tagged
         * object is a sequence that contains other sequences). If you are
         * dealing with implicitly tagged sets you really <b>should</b>
         * be using this method.
         *
         * @param obj the tagged object.
         * @param explicit true if the object is meant to be explicitly tagged
         *          false otherwise.
         * @exception IllegalArgumentException if the tagged object cannot
         *          be converted.
         */
        public static ASN1Set getInstance(
            ASN1TaggedObject obj,
            bool explicitly)
        {
            if (explicitly)
            {
                if (!obj.isExplicit())
                {
                    throw new ArgumentException("object implicit - explicit expected.");
                }

                return((ASN1Set)obj.getObject());
            }
            else
            {
                //
                // constructed object which appears to be explicitly tagged
                // and it's really implicit means we have to add the
                // surrounding sequence.
                //
                if (obj.isExplicit())
                {
                    ASN1Set set = new DERSet(obj.getObject());

                    return(set);
                }
                else
                {
                    if (obj.getObject() is ASN1Set)
                    {
                        return((ASN1Set)obj.getObject());
                    }

                    //
                    // in this case the parser returns a sequence, convert it
                    // into a set.
                    //
                    ASN1EncodableVector v = new ASN1EncodableVector();

                    if (obj.getObject() is ASN1Sequence)
                    {
                        ASN1Sequence s = (ASN1Sequence)obj.getObject();
                        IEnumerator  e = s.getObjects();

                        while (e.MoveNext())
                        {
                            v.add((ASN1Encodable)e.Current);
                        }

                        return(new DERSet(v));
                    }
                }
            }

            throw new ArgumentException(
                      "unknown object in getInstanceFromTagged");
        }
예제 #3
0
        internal DERSet(
            ASN1EncodableVector v,
            bool needsSorting)
        {
            for (int i = 0; i != v.size(); i++)
            {
                this.addObject(v.get(i));
            }

            if (needsSorting)
            {
                this.sort();
            }
        }
예제 #4
0
 /**
  * @param v - a vector of objects making up the set.
  */
 public DERSet(
     ASN1EncodableVector v) : this(v, true)
 {
 }
예제 #5
0
 /**
  * create a sequence containing a vector of objects.
  */
 public BERSequence(ASN1EncodableVector v) : base(v)
 {
 }
예제 #6
0
 internal BERSet(ASN1EncodableVector v, bool needsSorting) : base(v, needsSorting)
 {
 }
예제 #7
0
 /**
  * create a set containing a vector of objects.
  */
 public BERSet(ASN1EncodableVector v) : base(v)
 {
 }
예제 #8
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));
            }
        }
예제 #9
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));
            }
        }