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.util.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 }