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