001package org.apache.commons.ssl.org.bouncycastle.asn1; 002 003import java.io.ByteArrayOutputStream; 004import java.io.IOException; 005import java.util.Enumeration; 006import java.util.Vector; 007 008public class BEROctetString 009 extends ASN1OctetString 010{ 011 private static final int MAX_LENGTH = 1000; 012 013 private ASN1OctetString[] octs; 014 015 /** 016 * convert a vector of octet strings into a single byte string 017 */ 018 static private byte[] toBytes( 019 ASN1OctetString[] octs) 020 { 021 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 022 023 for (int i = 0; i != octs.length; i++) 024 { 025 try 026 { 027 DEROctetString o = (DEROctetString)octs[i]; 028 029 bOut.write(o.getOctets()); 030 } 031 catch (ClassCastException e) 032 { 033 throw new IllegalArgumentException(octs[i].getClass().getName() + " found in input should only contain DEROctetString"); 034 } 035 catch (IOException e) 036 { 037 throw new IllegalArgumentException("exception converting octets " + e.toString()); 038 } 039 } 040 041 return bOut.toByteArray(); 042 } 043 044 /** 045 * @param string the octets making up the octet string. 046 */ 047 public BEROctetString( 048 byte[] string) 049 { 050 super(string); 051 } 052 053 public BEROctetString( 054 ASN1OctetString[] octs) 055 { 056 super(toBytes(octs)); 057 058 this.octs = octs; 059 } 060 061 public byte[] getOctets() 062 { 063 return string; 064 } 065 066 /** 067 * return the DER octets that make up this string. 068 */ 069 public Enumeration getObjects() 070 { 071 if (octs == null) 072 { 073 return generateOcts().elements(); 074 } 075 076 return new Enumeration() 077 { 078 int counter = 0; 079 080 public boolean hasMoreElements() 081 { 082 return counter < octs.length; 083 } 084 085 public Object nextElement() 086 { 087 return octs[counter++]; 088 } 089 }; 090 } 091 092 private Vector generateOcts() 093 { 094 Vector vec = new Vector(); 095 for (int i = 0; i < string.length; i += MAX_LENGTH) 096 { 097 int end; 098 099 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}