1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.geronimo.crypto.asn1; 19 20 import java.io.IOException; 21 import java.util.Enumeration; 22 import java.util.Vector; 23 24 public abstract class ASN1Sequence 25 extends DERObject 26 { 27 private Vector seq = new Vector(); 28 29 /** 30 * return an ASN1Sequence from the given object. 31 * 32 * @param obj the object we want converted. 33 * @exception IllegalArgumentException if the object cannot be converted. 34 */ 35 public static ASN1Sequence getInstance( 36 Object obj) 37 { 38 if (obj == null || obj instanceof ASN1Sequence) 39 { 40 return (ASN1Sequence)obj; 41 } 42 43 throw new IllegalArgumentException("unknown object in getInstance"); 44 } 45 46 /** 47 * Return an ASN1 sequence from a tagged object. There is a special 48 * case here, if an object appears to have been explicitly tagged on 49 * reading but we were expecting it to be implictly tagged in the 50 * normal course of events it indicates that we lost the surrounding 51 * sequence - so we need to add it back (this will happen if the tagged 52 * object is a sequence that contains other sequences). If you are 53 * dealing with implicitly tagged sequences you really <b>should</b> 54 * be using this method. 55 * 56 * @param obj the tagged object. 57 * @param explicit true if the object is meant to be explicitly tagged, 58 * false otherwise. 59 * @exception IllegalArgumentException if the tagged object cannot 60 * be converted. 61 */ 62 public static ASN1Sequence getInstance( 63 ASN1TaggedObject obj, 64 boolean explicit) 65 { 66 if (explicit) 67 { 68 if (!obj.isExplicit()) 69 { 70 throw new IllegalArgumentException("object implicit - explicit expected."); 71 } 72 73 return (ASN1Sequence)obj.getObject(); 74 } 75 else 76 { 77 // 78 // constructed object which appears to be explicitly tagged 79 // when it should be implicit means we have to add the 80 // surrounding sequence. 81 // 82 if (obj.isExplicit()) 83 { 84 if (obj instanceof BERTaggedObject) 85 { 86 return new BERSequence(obj.getObject()); 87 } 88 else 89 { 90 return new DERSequence(obj.getObject()); 91 } 92 } 93 else 94 { 95 if (obj.getObject() instanceof ASN1Sequence) 96 { 97 return (ASN1Sequence)obj.getObject(); 98 } 99 } 100 } 101 102 throw new IllegalArgumentException( 103 "unknown object in getInstanceFromTagged"); 104 } 105 106 public Enumeration getObjects() 107 { 108 return seq.elements(); 109 } 110 111 /** 112 * return the object at the sequence postion indicated by index. 113 * 114 * @param index the sequence number (starting at zero) of the object 115 * @return the object at the sequence postion indicated by index. 116 */ 117 public DEREncodable getObjectAt( 118 int index) 119 { 120 return (DEREncodable)seq.elementAt(index); 121 } 122 123 /** 124 * return the number of objects in this sequence. 125 * 126 * @return the number of objects in this sequence. 127 */ 128 public int size() 129 { 130 return seq.size(); 131 } 132 133 public int hashCode() 134 { 135 Enumeration e = this.getObjects(); 136 int hashCode = 0; 137 138 while (e.hasMoreElements()) 139 { 140 Object o = e.nextElement(); 141 142 if (o != null) 143 { 144 hashCode ^= o.hashCode(); 145 } 146 } 147 148 return hashCode; 149 } 150 151 public boolean equals( 152 Object o) 153 { 154 if (o == null || !(o instanceof ASN1Sequence)) 155 { 156 return false; 157 } 158 159 ASN1Sequence other = (ASN1Sequence)o; 160 161 if (this.size() != other.size()) 162 { 163 return false; 164 } 165 166 Enumeration s1 = this.getObjects(); 167 Enumeration s2 = other.getObjects(); 168 169 while (s1.hasMoreElements()) 170 { 171 Object o1 = s1.nextElement(); 172 Object o2 = s2.nextElement(); 173 174 if (o1 != null && o2 != null) 175 { 176 if (!o1.equals(o2)) 177 { 178 return false; 179 } 180 } 181 else if (o1 == null && o2 == null) 182 { 183 continue; 184 } 185 else 186 { 187 return false; 188 } 189 } 190 191 return true; 192 } 193 194 protected void addObject( 195 DEREncodable obj) 196 { 197 seq.addElement(obj); 198 } 199 200 abstract void encode(DEROutputStream out) 201 throws IOException; 202 }