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.IOException;
022 import java.text.ParseException;
023 import java.text.SimpleDateFormat;
024 import java.util.Date;
025 import java.util.SimpleTimeZone;
026
027 /**
028 * Generalized time object.
029 */
030 public class DERGeneralizedTime
031 extends DERObject
032 {
033 String time;
034
035 /**
036 * return a generalized time from the passed in object
037 *
038 * @exception IllegalArgumentException if the object cannot be converted.
039 */
040 public static DERGeneralizedTime getInstance(
041 Object obj)
042 {
043 if (obj == null || obj instanceof DERGeneralizedTime)
044 {
045 return (DERGeneralizedTime)obj;
046 }
047
048 if (obj instanceof ASN1OctetString)
049 {
050 return new DERGeneralizedTime(((ASN1OctetString)obj).getOctets());
051 }
052
053 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
054 }
055
056 /**
057 * return a Generalized Time object from a tagged object.
058 *
059 * @param obj the tagged object holding the object we want
060 * @param explicit true if the object is meant to be explicitly
061 * tagged false otherwise.
062 * @exception IllegalArgumentException if the tagged object cannot
063 * be converted.
064 */
065 public static DERGeneralizedTime getInstance(
066 ASN1TaggedObject obj,
067 boolean explicit)
068 {
069 return getInstance(obj.getObject());
070 }
071
072 /**
073 * The correct format for this is YYYYMMDDHHMMSSZ, or without the Z
074 * for local time, or Z+-HHMM on the end, for difference between local
075 * time and UTC time.
076 * <p>
077 *
078 * @param time the time string.
079 */
080 public DERGeneralizedTime(
081 String time)
082 {
083 this.time = time;
084 }
085
086 /**
087 * base constructer from a java.util.date object
088 */
089 public DERGeneralizedTime(
090 Date time)
091 {
092 SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
093
094 dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
095
096 this.time = dateF.format(time);
097 }
098
099 DERGeneralizedTime(
100 byte[] bytes)
101 {
102 //
103 // explicitly convert to characters
104 //
105 char[] dateC = new char[bytes.length];
106
107 for (int i = 0; i != dateC.length; i++)
108 {
109 dateC[i] = (char)(bytes[i] & 0xff);
110 }
111
112 this.time = new String(dateC);
113 }
114
115 /**
116 * return the time - always in the form of
117 * YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm).
118 * <p>
119 * Normally in a certificate we would expect "Z" rather than "GMT",
120 * however adding the "GMT" means we can just use:
121 * <pre>
122 * dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
123 * </pre>
124 * To read in the time and get a date which is compatible with our local
125 * time zone.
126 */
127 public String getTime()
128 {
129 //
130 // standardise the format.
131 //
132 if (time.charAt(time.length() - 1) == 'Z')
133 {
134 return time.substring(0, time.length() - 1) + "GMT+00:00";
135 }
136 else
137 {
138 int signPos = time.length() - 5;
139 char sign = time.charAt(signPos);
140 if (sign == '-' || sign == '+')
141 {
142 return time.substring(0, signPos)
143 + "GMT"
144 + time.substring(signPos, signPos + 3)
145 + ":"
146 + time.substring(signPos + 3);
147 }
148 else
149 {
150 signPos = time.length() - 3;
151 sign = time.charAt(signPos);
152 if (sign == '-' || sign == '+')
153 {
154 return time.substring(0, signPos)
155 + "GMT"
156 + time.substring(signPos)
157 + ":00";
158 }
159 }
160 }
161
162 return time;
163 }
164
165 public Date getDate()
166 throws ParseException
167 {
168 SimpleDateFormat dateF;
169
170 if (time.indexOf('.') == 14)
171 {
172 dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'");
173 }
174 else
175 {
176 dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
177 }
178
179 dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
180
181 return dateF.parse(time);
182 }
183
184 private byte[] getOctets()
185 {
186 char[] cs = time.toCharArray();
187 byte[] bs = new byte[cs.length];
188
189 for (int i = 0; i != cs.length; i++)
190 {
191 bs[i] = (byte)cs[i];
192 }
193
194 return bs;
195 }
196
197
198 void encode(
199 DEROutputStream out)
200 throws IOException
201 {
202 out.writeEncoded(GENERALIZED_TIME, this.getOctets());
203 }
204
205 public boolean equals(
206 Object o)
207 {
208 if ((o == null) || !(o instanceof DERGeneralizedTime))
209 {
210 return false;
211 }
212
213 return time.equals(((DERGeneralizedTime)o).time);
214 }
215
216 public int hashCode()
217 {
218 return time.hashCode();
219 }
220 }