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 }