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.util.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 }