001: package org.bouncycastle.asn1;
002:
003: import java.io.ByteArrayOutputStream;
004: import java.io.IOException;
005: import java.util.Enumeration;
006: import java.util.Vector;
007:
008: public class BERConstructedOctetString extends DEROctetString {
009: private static final int MAX_LENGTH = 1000;
010:
011: /**
012: * convert a vector of octet strings into a single byte string
013: */
014: static private byte[] toBytes(Vector octs) {
015: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
016:
017: for (int i = 0; i != octs.size(); i++) {
018: try {
019: DEROctetString o = (DEROctetString) octs.elementAt(i);
020:
021: bOut.write(o.getOctets());
022: } catch (ClassCastException e) {
023: throw new IllegalArgumentException(
024: octs.elementAt(i).getClass().getName()
025: + " found in input should only contain DEROctetString");
026: } catch (IOException e) {
027: throw new IllegalArgumentException(
028: "exception converting octets " + e.toString());
029: }
030: }
031:
032: return bOut.toByteArray();
033: }
034:
035: private Vector octs;
036:
037: /**
038: * @param string the octets making up the octet string.
039: */
040: public BERConstructedOctetString(byte[] string) {
041: super (string);
042: }
043:
044: public BERConstructedOctetString(Vector octs) {
045: super (toBytes(octs));
046:
047: this .octs = octs;
048: }
049:
050: public BERConstructedOctetString(DERObject obj) {
051: super (obj);
052: }
053:
054: public BERConstructedOctetString(DEREncodable obj) {
055: super (obj.getDERObject());
056: }
057:
058: public byte[] getOctets() {
059: return string;
060: }
061:
062: /**
063: * return the DER octets that make up this string.
064: */
065: public Enumeration getObjects() {
066: if (octs == null) {
067: return generateOcts().elements();
068: }
069:
070: return octs.elements();
071: }
072:
073: private Vector generateOcts() {
074: int start = 0;
075: int end = 0;
076: Vector vec = new Vector();
077:
078: while ((end + 1) < string.length) {
079: if (string[end] == 0 && string[end + 1] == 0) {
080: byte[] nStr = new byte[end - start + 1];
081:
082: System.arraycopy(string, start, nStr, 0, nStr.length);
083:
084: vec.addElement(new DEROctetString(nStr));
085: start = end + 1;
086: }
087: end++;
088: }
089:
090: byte[] nStr = new byte[string.length - start];
091:
092: System.arraycopy(string, start, nStr, 0, nStr.length);
093:
094: vec.addElement(new DEROctetString(nStr));
095:
096: return vec;
097: }
098:
099: public void encode(DEROutputStream out) throws IOException {
100: if (out instanceof ASN1OutputStream
101: || out instanceof BEROutputStream) {
102: out.write(CONSTRUCTED | OCTET_STRING);
103:
104: out.write(0x80);
105:
106: //
107: // write out the octet array
108: //
109: if (octs != null) {
110: for (int i = 0; i != octs.size(); i++) {
111: out.writeObject(octs.elementAt(i));
112: }
113: } else {
114: for (int i = 0; i < string.length; i += MAX_LENGTH) {
115: int end;
116:
117: if (i + MAX_LENGTH > string.length) {
118: end = string.length;
119: } else {
120: end = i + MAX_LENGTH;
121: }
122:
123: byte[] nStr = new byte[end - i];
124:
125: System.arraycopy(string, i, nStr, 0, nStr.length);
126:
127: out.writeObject(new DEROctetString(nStr));
128: }
129: }
130:
131: out.write(0x00);
132: out.write(0x00);
133: } else {
134: super.encode(out);
135: }
136: }
137: }
|