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