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: */package org.apache.geronimo.crypto.asn1;
017:
018: import java.io.IOException;
019: import java.util.Enumeration;
020: import java.util.Vector;
021:
022: public abstract class ASN1Sequence extends DERObject {
023: private Vector seq = new Vector();
024:
025: /**
026: * return an ASN1Sequence from the given object.
027: *
028: * @param obj the object we want converted.
029: * @exception IllegalArgumentException if the object cannot be converted.
030: */
031: public static ASN1Sequence getInstance(Object obj) {
032: if (obj == null || obj instanceof ASN1Sequence) {
033: return (ASN1Sequence) obj;
034: }
035:
036: throw new IllegalArgumentException(
037: "unknown object in getInstance");
038: }
039:
040: /**
041: * Return an ASN1 sequence from a tagged object. There is a special
042: * case here, if an object appears to have been explicitly tagged on
043: * reading but we were expecting it to be implictly tagged in the
044: * normal course of events it indicates that we lost the surrounding
045: * sequence - so we need to add it back (this will happen if the tagged
046: * object is a sequence that contains other sequences). If you are
047: * dealing with implicitly tagged sequences you really <b>should</b>
048: * be using this method.
049: *
050: * @param obj the tagged object.
051: * @param explicit true if the object is meant to be explicitly tagged,
052: * false otherwise.
053: * @exception IllegalArgumentException if the tagged object cannot
054: * be converted.
055: */
056: public static ASN1Sequence getInstance(ASN1TaggedObject obj,
057: boolean explicit) {
058: if (explicit) {
059: if (!obj.isExplicit()) {
060: throw new IllegalArgumentException(
061: "object implicit - explicit expected.");
062: }
063:
064: return (ASN1Sequence) obj.getObject();
065: } else {
066: //
067: // constructed object which appears to be explicitly tagged
068: // when it should be implicit means we have to add the
069: // surrounding sequence.
070: //
071: if (obj.isExplicit()) {
072: if (obj instanceof BERTaggedObject) {
073: return new BERSequence(obj.getObject());
074: } else {
075: return new DERSequence(obj.getObject());
076: }
077: } else {
078: if (obj.getObject() instanceof ASN1Sequence) {
079: return (ASN1Sequence) obj.getObject();
080: }
081: }
082: }
083:
084: throw new IllegalArgumentException(
085: "unknown object in getInstanceFromTagged");
086: }
087:
088: public Enumeration getObjects() {
089: return seq.elements();
090: }
091:
092: /**
093: * return the object at the sequence postion indicated by index.
094: *
095: * @param index the sequence number (starting at zero) of the object
096: * @return the object at the sequence postion indicated by index.
097: */
098: public DEREncodable getObjectAt(int index) {
099: return (DEREncodable) seq.elementAt(index);
100: }
101:
102: /**
103: * return the number of objects in this sequence.
104: *
105: * @return the number of objects in this sequence.
106: */
107: public int size() {
108: return seq.size();
109: }
110:
111: public int hashCode() {
112: Enumeration e = this .getObjects();
113: int hashCode = 0;
114:
115: while (e.hasMoreElements()) {
116: Object o = e.nextElement();
117:
118: if (o != null) {
119: hashCode ^= o.hashCode();
120: }
121: }
122:
123: return hashCode;
124: }
125:
126: public boolean equals(Object o) {
127: if (o == null || !(o instanceof ASN1Sequence)) {
128: return false;
129: }
130:
131: ASN1Sequence other = (ASN1Sequence) o;
132:
133: if (this .size() != other.size()) {
134: return false;
135: }
136:
137: Enumeration s1 = this .getObjects();
138: Enumeration s2 = other.getObjects();
139:
140: while (s1.hasMoreElements()) {
141: Object o1 = s1.nextElement();
142: Object o2 = s2.nextElement();
143:
144: if (o1 != null && o2 != null) {
145: if (!o1.equals(o2)) {
146: return false;
147: }
148: } else if (o1 == null && o2 == null) {
149: continue;
150: } else {
151: return false;
152: }
153: }
154:
155: return true;
156: }
157:
158: protected void addObject(DEREncodable obj) {
159: seq.addElement(obj);
160: }
161:
162: abstract void encode(DEROutputStream out) throws IOException;
163: }
|