Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.bouncycastle.asn1;
  
A parser for ASN.1 streams which also returns, where possible, parsers for the objects it encounters.
  
 public class ASN1StreamParser
 {
     private final InputStream _in;
     private final int         _limit;
     private final byte[][] tmpBuffers;
 
     public ASN1StreamParser(
         InputStream in)
     {
         this(in, StreamUtil.findLimit(in));
     }
 
     public ASN1StreamParser(
         InputStream in,
         int         limit)
     {
         this. = in;
         this. = limit;
 
         this. = new byte[11][];
     }
 
     public ASN1StreamParser(
         byte[] encoding)
     {
         this(new ByteArrayInputStream(encoding), encoding.length);
     }
 
     ASN1Encodable readIndef(int tagValuethrows IOException
     {
         // Note: INDEF => CONSTRUCTED
 
         // TODO There are other tags that may be constructed (e.g. BIT_STRING)
         switch (tagValue)
         {
             case .:
                 return new DERExternalParser(this);
             case .:
                 return new BEROctetStringParser(this);
             case .:
                 return new BERSequenceParser(this);
             case .:
                 return new BERSetParser(this);
             default:
                 throw new ASN1Exception("unknown BER object encountered: 0x" + Integer.toHexString(tagValue));
         }
     }
 
     ASN1Encodable readImplicit(boolean constructedint tagthrows IOException
     {
         if ( instanceof IndefiniteLengthInputStream)
         {
             if (!constructed)
             {
                 throw new IOException("indefinite length primitive encoding encountered");
             }
             
             return readIndef(tag);
         }
 
         if (constructed)
         {
             switch (tag)
             {
                 case .:
                     return new DERSetParser(this);
                 case .:
                     return new DERSequenceParser(this);
                 case .:
                     return new BEROctetStringParser(this);
             }
         }
         else
         {
             switch (tag)
             {
                 case .:
                     throw new ASN1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)");
                 case .:
                     throw new ASN1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)");
                 case .:
                     return new DEROctetStringParser((DefiniteLengthInputStream));
             }
         }
 
         // TODO ASN1Exception
         throw new RuntimeException("implicit tagging not implemented");
     }
 
     ASN1Primitive readTaggedObject(boolean constructedint tagthrows IOException
    {
        if (!constructed)
        {
            // Note: !CONSTRUCTED => IMPLICIT
            DefiniteLengthInputStream defIn = (DefiniteLengthInputStream);
            return new DERTaggedObject(falsetagnew DEROctetString(defIn.toByteArray()));
        }
        ASN1EncodableVector v = readVector();
        if ( instanceof IndefiniteLengthInputStream)
        {
            return v.size() == 1
                ?   new BERTaggedObject(truetagv.get(0))
                :   new BERTaggedObject(falsetag, BERFactory.createSequence(v));
        }
        return v.size() == 1
            ?   new DERTaggedObject(truetagv.get(0))
            :   new DERTaggedObject(falsetag, DERFactory.createSequence(v));
    }
    public ASN1Encodable readObject()
        throws IOException
    {
        int tag = .read();
        if (tag == -1)
        {
            return null;
        }
        //
        // turn of looking for "00" while we resolve the tag
        //
        set00Check(false);
        //
        // calculate tag number
        //
        int tagNo = ASN1InputStream.readTagNumber(tag);
        boolean isConstructed = (tag & .) != 0;
        //
        // calculate length
        //
        int length = ASN1InputStream.readLength();
        if (length < 0) // indefinite length method
        {
            if (!isConstructed)
            {
                throw new IOException("indefinite length primitive encoding encountered");
            }
            IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream();
            ASN1StreamParser sp = new ASN1StreamParser(indIn);
            if ((tag & .) != 0)
            {
                return new BERApplicationSpecificParser(tagNosp);
            }
            if ((tag & .) != 0)
            {
                return new BERTaggedObjectParser(truetagNosp);
            }
            return sp.readIndef(tagNo);
        }
        else
        {
            DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(length);
            if ((tag & .) != 0)
            {
                return new DERApplicationSpecific(isConstructedtagNodefIn.toByteArray());
            }
            if ((tag & .) != 0)
            {
                return new BERTaggedObjectParser(isConstructedtagNonew ASN1StreamParser(defIn));
            }
            if (isConstructed)
            {
                // TODO There are other tags that may be constructed (e.g. BIT_STRING)
                switch (tagNo)
                {
                    case .:
                        //
                        // yes, people actually do this...
                        //
                        return new BEROctetStringParser(new ASN1StreamParser(defIn));
                    case .:
                        return new DERSequenceParser(new ASN1StreamParser(defIn));
                    case .:
                        return new DERSetParser(new ASN1StreamParser(defIn));
                    case .:
                        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 .:
                    return new DEROctetStringParser(defIn);
            }
            try
            {
                return ASN1InputStream.createPrimitiveDERObject(tagNodefIn);
            }
            catch (IllegalArgumentException e)
            {
                throw new ASN1Exception("corrupted stream detected"e);
            }
        }
    }
    private void set00Check(boolean enabled)
    {
        if ( instanceof IndefiniteLengthInputStream)
        {
            ((IndefiniteLengthInputStream)).setEofOn00(enabled);
        }
    }
    {
        ASN1EncodableVector v = new ASN1EncodableVector();
        ASN1Encodable obj;
        while ((obj = readObject()) != null)
        {
            if (obj instanceof InMemoryRepresentable)
            {
                v.add(((InMemoryRepresentable)obj).getLoadedObject());
            }
            else
            {
                v.add(obj.toASN1Primitive());
            }
        }
        return v;
    }
New to GrepCode? Check out our FAQ X