BEROctetString.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
13c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypackage org.bouncycastle.asn1;
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyryimport java.io.ByteArrayOutputStream;
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyryimport java.io.IOException;
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyryimport java.util.Enumeration;
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyryimport java.util.Vector;
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic class BEROctetString
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    extends ASN1OctetString
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    private static final int MAX_LENGTH = 1000;
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    private ASN1OctetString[] octs;
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /**
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry     * convert a vector of octet strings into a single byte string
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry     */
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    static private byte[] toBytes(
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        ASN1OctetString[]  octs)
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    {
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        for (int i = 0; i != octs.length; i++)
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        {
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            try
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            {
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                DEROctetString o = (DEROctetString)octs[i];
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                bOut.write(o.getOctets());
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            }
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            catch (ClassCastException e)
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            {
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                throw new IllegalArgumentException(octs[i].getClass().getName() + " found in input should only contain DEROctetString");
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            }
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            catch (IOException e)
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            {
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                throw new IllegalArgumentException("exception converting octets " + e.toString());
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            }
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        }
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        return bOut.toByteArray();
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /**
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry     * @param string the octets making up the octet string.
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry     */
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    public BEROctetString(
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        byte[] string)
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    {
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        super(string);
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    public BEROctetString(
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        ASN1OctetString[] octs)
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    {
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        super(toBytes(octs));
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        this.octs = octs;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    public byte[] getOctets()
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    {
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        return string;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /**
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry     * return the DER octets that make up this string.
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry     */
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    public Enumeration getObjects()
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    {
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        if (octs == null)
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        {
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            return generateOcts().elements();
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        }
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        return new Enumeration()
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        {
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            int counter = 0;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            public boolean hasMoreElements()
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            {
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                return counter < octs.length;
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            }
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            public Object nextElement()
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            {
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                return octs[counter++];
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            }
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        };
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    private Vector generateOcts()
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    {
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        Vector vec = new Vector();
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        for (int i = 0; i < string.length; i += MAX_LENGTH)
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        {
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            int end;
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            if (i + MAX_LENGTH > string.length)
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            {
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                end = string.length;
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            }
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            else
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            {
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                end = i + MAX_LENGTH;
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            }
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            byte[] nStr = new byte[end - i];
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            System.arraycopy(string, i, nStr, 0, nStr.length);
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            vec.addElement(new DEROctetString(nStr));
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry         }
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry         return vec;
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    boolean isConstructed()
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    {
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        return true;
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int encodedLength()
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        throws IOException
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    {
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        int length = 0;
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        for (Enumeration e = getObjects(); e.hasMoreElements();)
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        {
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        }
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        return 2 + length + 2;
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    public void encode(
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        ASN1OutputStream out)
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        throws IOException
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    {
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        out.write(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        out.write(0x80);
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        //
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        // write out the octet array
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        //
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        for (Enumeration e = getObjects(); e.hasMoreElements();)
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        {
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            out.writeObject((ASN1Encodable)e.nextElement());
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        }
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        out.write(0x00);
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        out.write(0x00);
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    static BEROctetString fromSequence(ASN1Sequence seq)
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    {
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        ASN1OctetString[]     v = new ASN1OctetString[seq.size()];
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        Enumeration e = seq.getObjects();
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        int                   index = 0;
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        while (e.hasMoreElements())
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        {
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            v[index++] = (ASN1OctetString)e.nextElement();
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        }
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        return new BEROctetString(v);
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry