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