1 package org.bouncycastle.asn1; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 import java.util.Enumeration; 6 import java.util.Vector; 7 8 public class BERConstructedOctetString 9 extends DEROctetString 10 { 11 /** 12 * convert a vector of octet strings into a single byte string 13 */ 14 static private byte[] toBytes( 15 Vector octs) 16 { 17 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 18 19 for (int i = 0; i != octs.size(); i++) 20 { 21 try 22 { 23 DEROctetString o = (DEROctetString)octs.elementAt(i); 24 25 bOut.write(o.getOctets()); 26 } 27 catch (ClassCastException e) 28 { 29 throw new IllegalArgumentException(octs.elementAt(i).getClass().getName() + " found in input should only contain DEROctetString"); 30 } 31 catch (IOException e) 32 { 33 throw new IllegalArgumentException("exception converting octets " + e.toString()); 34 } 35 } 36 37 return bOut.toByteArray(); 38 } 39 40 private Vector octs; 41 42 /** 43 * @param string the octets making up the octet string. 44 */ 45 public BERConstructedOctetString( 46 byte[] string) 47 { 48 super(string); 49 } 50 51 public BERConstructedOctetString( 52 Vector octs) 53 { 54 super(toBytes(octs)); 55 56 this.octs = octs; 57 } 58 59 public BERConstructedOctetString( 60 DERObject obj) 61 { 62 super(obj); 63 } 64 65 public BERConstructedOctetString( 66 DEREncodable obj) 67 { 68 super(obj.getDERObject()); 69 } 70 71 public byte[] getOctets() 72 { 73 return string; 74 } 75 76 /** 77 * return the DER octets that make up this string. 78 */ 79 public Enumeration getObjects() 80 { 81 if (octs == null) 82 { 83 return generateOcts().elements(); 84 } 85 86 return octs.elements(); 87 } 88 89 private Vector generateOcts() 90 { 91 int start = 0; 92 int end = 0; 93 Vector vec = new Vector(); 94 95 while ((end + 1) < string.length) 96 { 97 if (string[end] == 0 && string[end + 1] == 0) 98 { 99 byte[] nStr = new byte[end - start + 1]; 100 101 System.arraycopy(string, start, nStr, 0, nStr.length); 102 103 vec.addElement(new DEROctetString(nStr)); 104 start = end + 1; 105 } 106 end++; 107 } 108 109 byte[] nStr = new byte[string.length - start]; 110 111 System.arraycopy(string, start, nStr, 0, nStr.length); 112 113 vec.addElement(new DEROctetString(nStr)); 114 115 return vec; 116 } 117 118 public void encode( 119 DEROutputStream out) 120 throws IOException 121 { 122 if (out instanceof ASN1OutputStream || out instanceof BEROutputStream) 123 { 124 out.write(CONSTRUCTED | OCTET_STRING); 125 126 out.write(0x80); 127 128 // 129 // write out the octet array 130 // 131 if (octs != null) 132 { 133 for (int i = 0; i != octs.size(); i++) 134 { 135 out.writeObject(octs.elementAt(i)); 136 } 137 } 138 else 139 { 140 int start = 0; 141 int end = 0; 142 143 while ((end + 1) < string.length) 144 { 145 if (string[end] == 0 && string[end + 1] == 0) 146 { 147 byte[] nStr = new byte[end - start + 1]; 148 149 System.arraycopy(string, start, nStr, 0, nStr.length); 150 151 out.writeObject(new DEROctetString(nStr)); 152 start = end + 1; 153 } 154 end++; 155 } 156 157 byte[] nStr = new byte[string.length - start]; 158 159 System.arraycopy(string, start, nStr, 0, nStr.length); 160 161 out.writeObject(new DEROctetString(nStr)); 162 } 163 164 out.write(0x00); 165 out.write(0x00); 166 } 167 else 168 { 169 super.encode(out); 170 } 171 } 172 } 173