14c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompackage org.bouncycastle.asn1;
24c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
34c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.ByteArrayInputStream;
44c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.FileInputStream;
54c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.IOException;
64c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.InputStream;
7a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstromimport java.nio.channels.FileChannel;
84c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
94c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromclass StreamUtil
104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom{
11ebe7111e889aaa6efd076e1205f2dd669d6df690Kenny Root    // BEGIN android-removed
12ebe7111e889aaa6efd076e1205f2dd669d6df690Kenny Root    // private static final long  MAX_MEMORY = Runtime.getRuntime().maxMemory();
13ebe7111e889aaa6efd076e1205f2dd669d6df690Kenny Root    // END android-removed
144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * Find out possible longest length...
174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     *
184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * @param in input stream of interest
194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * @return length calculation or MAX_VALUE.
204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    static int findLimit(InputStream in)
224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (in instanceof LimitedInputStream)
244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return ((LimitedInputStream)in).getRemaining();
264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (in instanceof ASN1InputStream)
284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return ((ASN1InputStream)in).getLimit();
304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (in instanceof ByteArrayInputStream)
324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return ((ByteArrayInputStream)in).available();
344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (in instanceof FileInputStream)
364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            try
384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
39a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom                FileChannel channel = ((FileInputStream)in).getChannel();
40a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom                long  size = (channel != null) ? channel.size() : Integer.MAX_VALUE;
414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                if (size < Integer.MAX_VALUE)
434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                {
444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    return (int)size;
454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                }
464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            catch (IOException e)
484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                // ignore - they'll find out soon enough!
504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
53ebe7111e889aaa6efd076e1205f2dd669d6df690Kenny Root        // BEGIN android-changed
54ebe7111e889aaa6efd076e1205f2dd669d6df690Kenny Root        long maxMemory = Runtime.getRuntime().maxMemory();
55ebe7111e889aaa6efd076e1205f2dd669d6df690Kenny Root        if (maxMemory > Integer.MAX_VALUE)
564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return Integer.MAX_VALUE;
584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
60ebe7111e889aaa6efd076e1205f2dd669d6df690Kenny Root        return (int) maxMemory;
61ebe7111e889aaa6efd076e1205f2dd669d6df690Kenny Root        // END android-changed
624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    static int calculateBodyLength(
654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int length)
664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int count = 1;
684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (length > 127)
704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            int size = 1;
724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            int val = length;
734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            while ((val >>>= 8) != 0)
754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                size++;
774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            for (int i = (size - 1) * 8; i >= 0; i -= 8)
804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                count++;
824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return count;
864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    static int calculateTagLength(int tagNo)
894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws IOException
904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int length = 1;
924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (tagNo >= 31)
944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (tagNo < 128)
964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                length++;
984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            else
1004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
1014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                byte[] stack = new byte[5];
1024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                int pos = stack.length;
1034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                stack[--pos] = (byte)(tagNo & 0x7F);
1054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                do
1074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                {
1084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    tagNo >>= 7;
1094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
1104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                }
1114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                while (tagNo > 127);
1124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                length += stack.length - pos;
1144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
1154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return length;
1184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom}
120