ASN1InputStream.java
上传用户:lior1029
上传日期:2013-05-07
资源大小:209k
文件大小:11k
源码类别:

CA认证

开发平台:

Java

  1. package org.bouncycastle.asn1;
  2. import java.math.BigInteger;
  3. import java.io.*;
  4. import java.util.*;
  5. /**
  6.  * a general purpose ASN.1 decoder - note: this class differs from the
  7.  * others in that it returns null after it has read the last object in
  8.  * the stream. If an ASN.1 NULL is encountered a DER/BER Null object is
  9.  * returned.
  10.  */
  11. public class ASN1InputStream
  12.     extends DERInputStream
  13. {
  14. private DERObject END_OF_STREAM = new DERObject() {
  15. void encode(
  16. DEROutputStream out)
  17. throws IOException
  18. {
  19. throw new IOException("Eeek!");
  20. }
  21. };
  22.     boolean eofFound = false;
  23.     public ASN1InputStream(
  24.         InputStream is)
  25.     {
  26.         super(is);
  27.     }
  28.     protected int readLength()
  29.         throws IOException
  30.     {
  31.         int length = read();
  32.         if (length < 0)
  33.         {
  34.             throw new IOException("EOF found when length expected");
  35.         }
  36.         if (length == 0x80)
  37.         {
  38.             return -1;      // indefinite-length encoding
  39.         }
  40.         if (length > 127)
  41.         {
  42.             int size = length & 0x7f;
  43.             length = 0;
  44.             for (int i = 0; i < size; i++)
  45.             {
  46.                 int next = read();
  47.                 if (next < 0)
  48.                 {
  49.                     throw new IOException("EOF found reading length");
  50.                 }
  51.                 length = (length << 8) + next;
  52.             }
  53.         }
  54.         return length;
  55.     }
  56.     protected void readFully(
  57.         byte[]  bytes)
  58.         throws IOException
  59.     {
  60.         int     left = bytes.length;
  61.         int     len;
  62.         if (left == 0)
  63.         {
  64.             return;
  65.         }
  66.         while ((len = read(bytes, bytes.length - left, left)) > 0)
  67.         {
  68.             if ((left -= len) == 0)
  69.             {
  70.                 return;
  71.             }
  72.         }
  73.         if (left != 0)
  74.         {
  75.             return;
  76.             //throw new IOException("EOF encountered in middle of object");
  77.         }
  78.     }
  79. /**
  80.  * build an object given its tag and a byte stream to construct it
  81.  * from.
  82.  */
  83.     protected DERObject buildObject(
  84. int     tag,
  85. byte[] bytes)
  86. throws IOException
  87. {
  88. switch (tag)
  89.         {
  90.         case NULL:
  91.             return new DERNull();   
  92.         case SEQUENCE | CONSTRUCTED:
  93.             ByteArrayInputStream    bIn = new ByteArrayInputStream(bytes);
  94.             ASN1InputStream         aIn = new ASN1InputStream(bIn);
  95.             ASN1EncodableVector     v = new ASN1EncodableVector();
  96.             DERObject   obj = aIn.readObject();
  97.             while (obj != null)
  98.             {
  99.                 v.add(obj);
  100.                 obj = aIn.readObject();
  101.             }
  102.             return new DERSequence(v);
  103.         case SET | CONSTRUCTED:
  104.             bIn = new ByteArrayInputStream(bytes);
  105.             aIn = new ASN1InputStream(bIn);
  106.             v = new ASN1EncodableVector();
  107.             obj = aIn.readObject();
  108.             while (obj != null)
  109.             {
  110.                 v.add(obj);
  111.                 obj = aIn.readObject();
  112.             }
  113.             return new DERSet(v);
  114.         case BOOLEAN:
  115.             return new DERBoolean(bytes);
  116.         case INTEGER:
  117.             return new DERInteger(bytes);
  118.         case ENUMERATED:
  119.             return new DEREnumerated(bytes);
  120.         case OBJECT_IDENTIFIER:
  121.             return new DERObjectIdentifier(bytes);
  122.         case BIT_STRING:
  123.             int     padBits = bytes[0];
  124.             byte[]  data = new byte[bytes.length - 1];
  125.             System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
  126.             return new DERBitString(data, padBits);
  127.         case UTF8_STRING:
  128.             return new DERUTF8String(bytes);
  129.         case PRINTABLE_STRING:
  130.             return new DERPrintableString(bytes);
  131.         case IA5_STRING:
  132.             return new DERIA5String(bytes);
  133.         case T61_STRING:
  134.             return new DERT61String(bytes);
  135.         case VISIBLE_STRING:
  136.             return new DERVisibleString(bytes);
  137.         case UNIVERSAL_STRING:
  138.             return new DERUniversalString(bytes);
  139.         case BMP_STRING:
  140.             return new DERBMPString(bytes);
  141.         case OCTET_STRING:
  142.             return new DEROctetString(bytes);
  143.         case UTC_TIME:
  144.             return new DERUTCTime(bytes);
  145.         case GENERALIZED_TIME:
  146.             return new DERGeneralizedTime(bytes);
  147.         default:
  148.             //
  149.             // with tagged object tag number is bottom 5 bits
  150.             //
  151.             if ((tag & TAGGED) != 0)  
  152.             {
  153.                 int tagNo = tag & 0x1f;
  154.                 if (tagNo == 0x1f)
  155.                 {
  156.                     int idx = 0;
  157.                     tagNo = 0;
  158.                     while ((bytes[idx] & 0x80) != 0)
  159.                     {
  160.                         tagNo |= (bytes[idx++] & 0x7f);
  161.                         tagNo <<= 7;
  162.                     }
  163.                     tagNo |= (bytes[idx] & 0x7f);
  164.                     byte[]  tmp = bytes;
  165.                     bytes = new byte[tmp.length - (idx + 1)];
  166.                     System.arraycopy(tmp, idx + 1, bytes, 0, bytes.length);
  167.                 }
  168.                 if (bytes.length == 0)        // empty tag!
  169.                 {
  170.                     return new DERTaggedObject(tagNo);
  171.                 }
  172.                 //
  173.                 // simple type - implicit... return an octet string
  174.                 //
  175.                 if ((tag & CONSTRUCTED) == 0)
  176.                 {
  177.                     return new DERTaggedObject(false, tagNo, new DEROctetString(bytes));
  178.                 }
  179.                 bIn = new ByteArrayInputStream(bytes);
  180.                 aIn = new ASN1InputStream(bIn);
  181.                 DEREncodable dObj = aIn.readObject();
  182.                 //
  183.                 // explicitly tagged (probably!) - if it isn't we'd have to
  184.                 // tell from the context
  185.                 //
  186.                 if (aIn.available() == 0)
  187.                 {
  188.                     return new DERTaggedObject(tagNo, dObj);
  189.                 }
  190.                 //
  191.                 // another implicit object, we'll create a sequence...
  192.                 //
  193.                 v = new ASN1EncodableVector();
  194.                 while (dObj != null)
  195.                 {
  196.                     v.add(dObj);
  197.                     dObj = aIn.readObject();
  198.                 }
  199.                 return new DERTaggedObject(false, tagNo, new DERSequence(v));
  200.             }
  201.             return new DERUnknownTag(tag, bytes);
  202.         }
  203. }
  204.     /**
  205.      * read a string of bytes representing an indefinite length object.
  206.      */
  207.     private byte[] readIndefiniteLengthFully()
  208.         throws IOException
  209.     {
  210.         ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
  211.         int                     b, b1;
  212.         b1 = read();
  213.         while ((b = read()) >= 0)
  214.         {
  215. if (b1 == 0 && b == 0)
  216. {
  217. break;
  218. }
  219.             bOut.write(b1);
  220.             b1 = b;
  221.         }
  222.         return bOut.toByteArray();
  223.     }
  224. private BERConstructedOctetString buildConstructedOctetString()
  225. throws IOException
  226. {
  227.         Vector                  octs = new Vector();
  228. for (;;)
  229. {
  230. DERObject o = readObject();
  231. if (o == END_OF_STREAM)
  232. {
  233. break;
  234. }
  235.             octs.addElement(o);
  236. }
  237. return new BERConstructedOctetString(octs);
  238. }
  239.     public DERObject readObject()
  240.         throws IOException
  241.     {
  242.         int tag = read();
  243.         if (tag == -1)
  244.         {
  245.             if (eofFound)
  246.             {
  247.                 throw new EOFException("attempt to read past end of file.");
  248.             }
  249.             eofFound = true;
  250.             return null;
  251.         }
  252.     
  253.         int     length = readLength();
  254.         if (length < 0)    // indefinite length method
  255.         {
  256.             switch (tag)
  257.             {
  258.             case NULL:
  259.                 return new BERNull();
  260.             case SEQUENCE | CONSTRUCTED:
  261.                 ASN1EncodableVector  v = new ASN1EncodableVector();
  262.     
  263. for (;;)
  264. {
  265. DERObject   obj = readObject();
  266. if (obj == END_OF_STREAM)
  267. {
  268. break;
  269. }
  270. v.add(obj);
  271. }
  272. return new BERSequence(v);
  273.             case SET | CONSTRUCTED:
  274.                 v = new ASN1EncodableVector();
  275.     
  276. for (;;)
  277. {
  278. DERObject   obj = readObject();
  279. if (obj == END_OF_STREAM)
  280. {
  281. break;
  282. }
  283. v.add(obj);
  284. }
  285. return new BERSet(v);
  286.             case OCTET_STRING | CONSTRUCTED:
  287. return buildConstructedOctetString();
  288.             default:
  289.                 //
  290.                 // with tagged object tag number is bottom 5 bits
  291.                 //
  292.                 if ((tag & TAGGED) != 0)  
  293.                 {
  294.                     int tagNo = tag & 0x1f;
  295.                     if (tagNo == 0x1f)
  296.                     {
  297.                         int b = read();
  298.                         tagNo = 0;
  299.                         while ((b >= 0) && ((b & 0x80) != 0))
  300.                         {
  301.                             tagNo |= (b & 0x7f);
  302.                             tagNo <<= 7;
  303.                             b = read();
  304.                         }
  305.                         tagNo |= (b & 0x7f);
  306.                     }
  307.                     //
  308.                     // simple type - implicit... return an octet string
  309.                     //
  310.                     if ((tag & CONSTRUCTED) == 0)
  311.                     {
  312.                         byte[]  bytes = readIndefiniteLengthFully();
  313.                         return new BERTaggedObject(false, tagNo, new DEROctetString(bytes));
  314.                     }
  315.                     //
  316.                     // either constructed or explicitly tagged
  317.                     //
  318. DERObject dObj = readObject();
  319. if (dObj == END_OF_STREAM)     // empty tag!
  320.                     {
  321.                         return new DERTaggedObject(tagNo);
  322.                     }
  323.                     DERObject       next = readObject();
  324.                     //
  325.                     // explicitly tagged (probably!) - if it isn't we'd have to
  326.                     // tell from the context
  327.                     //
  328.                     if (next == END_OF_STREAM)
  329.                     {
  330.                         return new BERTaggedObject(tagNo, dObj);
  331.                     }
  332.                     //
  333.                     // another implicit object, we'll create a sequence...
  334.                     //
  335.                     v = new ASN1EncodableVector();
  336.                     v.add(dObj);
  337.                     do
  338.                     {
  339.                         v.add(next);
  340.                         next = readObject();
  341.                     }
  342.                     while (next != END_OF_STREAM);
  343.                     return new BERTaggedObject(false, tagNo, new BERSequence(v));
  344.                 }
  345.                 throw new IOException("unknown BER object encountered");
  346.             }
  347.         }
  348.         else
  349.         {
  350.             if (tag == 0 && length == 0)    // end of contents marker.
  351.             {
  352.                 return END_OF_STREAM;
  353.             }
  354.             byte[]  bytes = new byte[length];
  355.     
  356.             readFully(bytes);
  357.     
  358. return buildObject(tag, bytes);
  359.         }
  360.     }
  361. }