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 }