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