001 /**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements. See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package org.apache.geronimo.util.asn1;
020
021 import java.io.ByteArrayOutputStream;
022 import java.io.IOException;
023 import java.util.Enumeration;
024 import java.util.Vector;
025
026 public class BERConstructedOctetString
027 extends DEROctetString
028 {
029 /**
030 * convert a vector of octet strings into a single byte string
031 */
032 static private byte[] toBytes(
033 Vector octs)
034 {
035 ByteArrayOutputStream bOut = new ByteArrayOutputStream();
036
037 for (int i = 0; i != octs.size(); i++)
038 {
039 try
040 {
041 DEROctetString o = (DEROctetString)octs.elementAt(i);
042
043 bOut.write(o.getOctets());
044 }
045 catch (ClassCastException e)
046 {
047 throw new IllegalArgumentException(octs.elementAt(i).getClass().getName() + " found in input should only contain DEROctetString");
048 }
049 catch (IOException e)
050 {
051 throw new IllegalArgumentException("exception converting octets " + e.toString());
052 }
053 }
054
055 return bOut.toByteArray();
056 }
057
058 private Vector octs;
059
060 /**
061 * @param string the octets making up the octet string.
062 */
063 public BERConstructedOctetString(
064 byte[] string)
065 {
066 super(string);
067 }
068
069 public BERConstructedOctetString(
070 Vector octs)
071 {
072 super(toBytes(octs));
073
074 this.octs = octs;
075 }
076
077 public BERConstructedOctetString(
078 DERObject obj)
079 {
080 super(obj);
081 }
082
083 public BERConstructedOctetString(
084 DEREncodable obj)
085 {
086 super(obj.getDERObject());
087 }
088
089 public byte[] getOctets()
090 {
091 return string;
092 }
093
094 /**
095 * return the DER octets that make up this string.
096 */
097 public Enumeration getObjects()
098 {
099 if (octs == null)
100 {
101 return generateOcts().elements();
102 }
103
104 return octs.elements();
105 }
106
107 private Vector generateOcts()
108 {
109 int start = 0;
110 int end = 0;
111 Vector vec = new Vector();
112
113 while ((end + 1) < string.length)
114 {
115 if (string[end] == 0 && string[end + 1] == 0)
116 {
117 byte[] nStr = new byte[end - start + 1];
118
119 System.arraycopy(string, start, nStr, 0, nStr.length);
120
121 vec.addElement(new DEROctetString(nStr));
122 start = end + 1;
123 }
124 end++;
125 }
126
127 byte[] nStr = new byte[string.length - start];
128
129 System.arraycopy(string, start, nStr, 0, nStr.length);
130
131 vec.addElement(new DEROctetString(nStr));
132
133 return vec;
134 }
135
136 public void encode(
137 DEROutputStream out)
138 throws IOException
139 {
140 if (out instanceof ASN1OutputStream || out instanceof BEROutputStream)
141 {
142 out.write(CONSTRUCTED | OCTET_STRING);
143
144 out.write(0x80);
145
146 //
147 // write out the octet array
148 //
149 if (octs != null)
150 {
151 for (int i = 0; i != octs.size(); i++)
152 {
153 out.writeObject(octs.elementAt(i));
154 }
155 }
156 else
157 {
158 int start = 0;
159 int end = 0;
160
161 while ((end + 1) < string.length)
162 {
163 if (string[end] == 0 && string[end + 1] == 0)
164 {
165 byte[] nStr = new byte[end - start + 1];
166
167 System.arraycopy(string, start, nStr, 0, nStr.length);
168
169 out.writeObject(new DEROctetString(nStr));
170 start = end + 1;
171 }
172 end++;
173 }
174
175 byte[] nStr = new byte[string.length - start];
176
177 System.arraycopy(string, start, nStr, 0, nStr.length);
178
179 out.writeObject(new DEROctetString(nStr));
180 }
181
182 out.write(0x00);
183 out.write(0x00);
184 }
185 else
186 {
187 super.encode(out);
188 }
189 }
190 }