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; 74c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 84c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromclass StreamUtil 94c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom{ 104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private static final long MAX_MEMORY = Runtime.getRuntime().maxMemory(); 114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom /** 134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom * Find out possible longest length... 144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom * 154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom * @param in input stream of interest 164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom * @return length calculation or MAX_VALUE. 174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom */ 184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom static int findLimit(InputStream in) 194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (in instanceof LimitedInputStream) 214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return ((LimitedInputStream)in).getRemaining(); 234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else if (in instanceof ASN1InputStream) 254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return ((ASN1InputStream)in).getLimit(); 274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else if (in instanceof ByteArrayInputStream) 294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return ((ByteArrayInputStream)in).available(); 314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else if (in instanceof FileInputStream) 334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom try 354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom long size = ((FileInputStream)in).getChannel().size(); 374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (size < Integer.MAX_VALUE) 394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return (int)size; 414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom catch (IOException e) 444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // ignore - they'll find out soon enough! 464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (MAX_MEMORY > Integer.MAX_VALUE) 504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return Integer.MAX_VALUE; 524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return (int)MAX_MEMORY; 554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom static int calculateBodyLength( 584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int length) 594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int count = 1; 614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (length > 127) 634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int size = 1; 654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int val = length; 664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom while ((val >>>= 8) != 0) 684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom size++; 704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom for (int i = (size - 1) * 8; i >= 0; i -= 8) 734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom count++; 754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return count; 794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom static int calculateTagLength(int tagNo) 824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throws IOException 834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int length = 1; 854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (tagNo >= 31) 874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (tagNo < 128) 894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom length++; 914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom byte[] stack = new byte[5]; 954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int pos = stack.length; 964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom stack[--pos] = (byte)(tagNo & 0x7F); 984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom do 1004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom tagNo >>= 7; 1024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom stack[--pos] = (byte)(tagNo & 0x7F | 0x80); 1034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom while (tagNo > 127); 1054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom length += stack.length - pos; 1074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return length; 1114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom} 113