1 /**
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one or more
4 * contributor license agreements. See the NOTICE file distributed with
5 * this work for additional information regarding copyright ownership.
6 * The ASF licenses this file to You under the Apache License, Version 2.0
7 * (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 package org.apache.geronimo.util.asn1;
20
21 import java.io.IOException;
22 import java.text.SimpleDateFormat;
23 import java.util.Date;
24 import java.util.SimpleTimeZone;
25
26 /**
27 * UTC time object.
28 */
29 public class DERUTCTime
30 extends DERObject
31 {
32 String time;
33
34 /**
35 * return an UTC Time from the passed in object.
36 *
37 * @exception IllegalArgumentException if the object cannot be converted.
38 */
39 public static DERUTCTime getInstance(
40 Object obj)
41 {
42 if (obj == null || obj instanceof DERUTCTime)
43 {
44 return (DERUTCTime)obj;
45 }
46
47 if (obj instanceof ASN1OctetString)
48 {
49 return new DERUTCTime(((ASN1OctetString)obj).getOctets());
50 }
51
52 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
53 }
54
55 /**
56 * return an UTC Time from a tagged object.
57 *
58 * @param obj the tagged object holding the object we want
59 * @param explicit true if the object is meant to be explicitly
60 * tagged false otherwise.
61 * @exception IllegalArgumentException if the tagged object cannot
62 * be converted.
63 */
64 public static DERUTCTime getInstance(
65 ASN1TaggedObject obj,
66 boolean explicit)
67 {
68 return getInstance(obj.getObject());
69 }
70
71 /**
72 * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
73 * never encoded. When you're creating one of these objects from scratch, that's
74 * what you want to use, otherwise we'll try to deal with whatever gets read from
75 * the input stream... (this is why the input format is different from the getTime()
76 * method output).
77 * <p>
78 *
79 * @param time the time string.
80 */
81 public DERUTCTime(
82 String time)
83 {
84 this.time = time;
85 }
86
87 /**
88 * base constructer from a java.util.date object
89 */
90 public DERUTCTime(
91 Date time)
92 {
93 SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'");
94
95 dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
96
97 this.time = dateF.format(time);
98 }
99
100 DERUTCTime(
101 byte[] bytes)
102 {
103
104
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
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 }