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.SimpleDateFormat;
023 import java.util.Date;
024 import java.util.SimpleTimeZone;
025
026 /**
027 * UTC time object.
028 */
029 public class DERUTCTime
030 extends DERObject
031 {
032 String time;
033
034 /**
035 * return an UTC Time from the passed in object.
036 *
037 * @exception IllegalArgumentException if the object cannot be converted.
038 */
039 public static DERUTCTime getInstance(
040 Object obj)
041 {
042 if (obj == null || obj instanceof DERUTCTime)
043 {
044 return (DERUTCTime)obj;
045 }
046
047 if (obj instanceof ASN1OctetString)
048 {
049 return new DERUTCTime(((ASN1OctetString)obj).getOctets());
050 }
051
052 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
053 }
054
055 /**
056 * return an UTC Time 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 DERUTCTime getInstance(
065 ASN1TaggedObject obj,
066 boolean explicit)
067 {
068 return getInstance(obj.getObject());
069 }
070
071 /**
072 * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
073 * never encoded. When you're creating one of these objects from scratch, that's
074 * what you want to use, otherwise we'll try to deal with whatever gets read from
075 * the input stream... (this is why the input format is different from the getTime()
076 * method output).
077 * <p>
078 *
079 * @param time the time string.
080 */
081 public DERUTCTime(
082 String time)
083 {
084 this.time = time;
085 }
086
087 /**
088 * base constructer from a java.util.date object
089 */
090 public DERUTCTime(
091 Date time)
092 {
093 SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'");
094
095 dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
096
097 this.time = dateF.format(time);
098 }
099
100 DERUTCTime(
101 byte[] bytes)
102 {
103 //
104 // explicitly convert to characters
105 //
106 char[] dateC = new char[bytes.length];
107
108 for (int i = 0; i != dateC.length; i++)
109 {
110 dateC[i] = (char)(bytes[i] & 0xff);
111 }
112
113 this.time = new String(dateC);
114 }
115
116 /**
117 * return the time - always in the form of
118 * YYMMDDhhmmssGMT(+hh:mm|-hh:mm).
119 * <p>
120 * Normally in a certificate we would expect "Z" rather than "GMT",
121 * however adding the "GMT" means we can just use:
122 * <pre>
123 * dateF = new SimpleDateFormat("yyMMddHHmmssz");
124 * </pre>
125 * To read in the time and get a date which is compatible with our local
126 * time zone.
127 * <p>
128 * <b>Note:</b> In some cases, due to the local date processing, this
129 * may lead to unexpected results. If you want to stick the normal
130 * convention of 1950 to 2049 use the getAdjustedTime() method.
131 */
132 public String getTime()
133 {
134 //
135 // standardise the format.
136 //
137 if (time.length() == 11)
138 {
139 return time.substring(0, 10) + "00GMT+00:00";
140 }
141 else if (time.length() == 13)
142 {
143 return time.substring(0, 12) + "GMT+00:00";
144 }
145 else if (time.length() == 17)
146 {
147 return time.substring(0, 12) + "GMT" + time.substring(12, 15) + ":" + time.substring(15, 17);
148 }
149
150 return time;
151 }
152
153 /**
154 * return the time as an adjusted date with a 4 digit year. This goes
155 * in the range of 1950 - 2049.
156 */
157 public String getAdjustedTime()
158 {
159 String d = this.getTime();
160
161 if (d.charAt(0) < '5')
162 {
163 return "20" + d;
164 }
165 else
166 {
167 return "19" + d;
168 }
169 }
170
171 private byte[] getOctets()
172 {
173 char[] cs = time.toCharArray();
174 byte[] bs = new byte[cs.length];
175
176 for (int i = 0; i != cs.length; i++)
177 {
178 bs[i] = (byte)cs[i];
179 }
180
181 return bs;
182 }
183
184 void encode(
185 DEROutputStream out)
186 throws IOException
187 {
188 out.writeEncoded(UTC_TIME, this.getOctets());
189 }
190
191 public boolean equals(
192 Object o)
193 {
194 if ((o == null) || !(o instanceof DERUTCTime))
195 {
196 return false;
197 }
198
199 return time.equals(((DERUTCTime)o).time);
200 }
201
202 public int hashCode()
203 {
204 return time.hashCode();
205 }
206 }