1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException; 4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.text.ParseException; 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.text.SimpleDateFormat; 6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Date; 7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.SimpleTimeZone; 8c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.util.TimeZone; 9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/** 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Generalized time object. 12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class DERGeneralizedTime 14c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom extends ASN1Object 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String time; 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return a generalized time from the passed in object 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @exception IllegalArgumentException if the object cannot be converted. 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public static DERGeneralizedTime getInstance( 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Object obj) 25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (obj == null || obj instanceof DERGeneralizedTime) 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (DERGeneralizedTime)obj; 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return a Generalized Time object from a tagged object. 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param obj the tagged object holding the object we want 38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param explicit true if the object is meant to be explicitly 39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * tagged false otherwise. 40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @exception IllegalArgumentException if the tagged object cannot 41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * be converted. 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public static DERGeneralizedTime getInstance( 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1TaggedObject obj, 45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean explicit) 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 476e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom DERObject o = obj.getObject(); 486e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 496e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (explicit || o instanceof DERGeneralizedTime) 506e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 516e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return getInstance(o); 526e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 536e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom else 546e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 556e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return new DERGeneralizedTime(((ASN1OctetString)o).getOctets()); 566e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 60c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * for local time, or Z+-HHMM on the end, for difference between local 62c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * time and UTC time. The fractional second amount f must consist of at 63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * least one number with trailing zeroes removed. 64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param time the time string. 66c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @exception IllegalArgumentException if String is an illegal format. 67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public DERGeneralizedTime( 69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String time) 70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.time = time; 72c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom try 73c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 74c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom this.getDate(); 75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom catch (ParseException e) 77c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 78c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IllegalArgumentException("invalid date string: " + e.getMessage()); 79c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * base constructer from a java.util.date object 84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public DERGeneralizedTime( 86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Date time) 87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'"); 89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam dateF.setTimeZone(new SimpleTimeZone(0,"Z")); 91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.time = dateF.format(time); 93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam DERGeneralizedTime( 96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] bytes) 97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // explicitly convert to characters 100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam char[] dateC = new char[bytes.length]; 102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i != dateC.length; i++) 104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam dateC[i] = (char)(bytes[i] & 0xff); 106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.time = new String(dateC); 109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 112c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * Return the time. 113c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @return The time string as it appeared in the encoded object. 114c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom */ 115c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public String getTimeString() 116c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 117c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return time; 118c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 119c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 120c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom /** 121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return the time - always in the form of 122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm). 123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * <p> 124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Normally in a certificate we would expect "Z" rather than "GMT", 125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * however adding the "GMT" means we can just use: 126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * <pre> 127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * dateF = new SimpleDateFormat("yyyyMMddHHmmssz"); 128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * </pre> 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * To read in the time and get a date which is compatible with our local 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * time zone. 131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public String getTime() 133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // standardise the format. 136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (time.charAt(time.length() - 1) == 'Z') 138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return time.substring(0, time.length() - 1) + "GMT+00:00"; 140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int signPos = time.length() - 5; 144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam char sign = time.charAt(signPos); 145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (sign == '-' || sign == '+') 146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return time.substring(0, signPos) 148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam + "GMT" 149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam + time.substring(signPos, signPos + 3) 150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam + ":" 151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam + time.substring(signPos + 3); 152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam signPos = time.length() - 3; 156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sign = time.charAt(signPos); 157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (sign == '-' || sign == '+') 158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return time.substring(0, signPos) 160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam + "GMT" 161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam + time.substring(signPos) 162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam + ":00"; 163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 166c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return time + calculateGMTOffset(); 167c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 169c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private String calculateGMTOffset() 170c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 171c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom String sign = "+"; 172c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom TimeZone timeZone = TimeZone.getDefault(); 173c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int offset = timeZone.getRawOffset(); 174c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (offset < 0) 175c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 176c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom sign = "-"; 177c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom offset = -offset; 178c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 179c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int hours = offset / (60 * 60 * 1000); 180c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int minutes = (offset - (hours * 60 * 60 * 1000)) / (60 * 1000); 181c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 182c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom try 183c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 184c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (timeZone.useDaylightTime() && timeZone.inDaylightTime(this.getDate())) 185c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 186c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom hours += sign.equals("+") ? 1 : -1; 187c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 188c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 189c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom catch (ParseException e) 190c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 191c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // we'll do our best and ignore daylight savings 192c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 193c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 194c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return "GMT" + sign + convert(hours) + ":" + convert(minutes); 195c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 196c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 197c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private String convert(int time) 198c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 199c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (time < 10) 200c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 201c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return "0" + time; 202c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 203c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 204c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return Integer.toString(time); 205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 207c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public Date getDate() 208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws ParseException 209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SimpleDateFormat dateF; 211c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom String d = time; 212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 213c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (time.endsWith("Z")) 214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 215c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (hasFractionalSeconds()) 216c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 217c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'"); 218c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 219c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom else 220c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 221c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'"); 222c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 223c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 224c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom dateF.setTimeZone(new SimpleTimeZone(0, "Z")); 225c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 226c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom else if (time.indexOf('-') > 0 || time.indexOf('+') > 0) 227c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 228c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom d = this.getTime(); 229c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (hasFractionalSeconds()) 2306e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 231c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSSz"); 232c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 233c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom else 234c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 235c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom dateF = new SimpleDateFormat("yyyyMMddHHmmssz"); 236c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 237c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 238c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom dateF.setTimeZone(new SimpleTimeZone(0, "Z")); 239b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 240b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 242c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (hasFractionalSeconds()) 243c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 244c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS"); 245c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 246c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom else 247c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 248c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom dateF = new SimpleDateFormat("yyyyMMddHHmmss"); 249c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 250c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 251c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom dateF.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID())); 252c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 253c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 254c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (hasFractionalSeconds()) 255c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 256c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // java misinterprets extra digits as being milliseconds... 257c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom String frac = d.substring(14); 258c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int index; 259c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom for (index = 1; index < frac.length(); index++) 260c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 261c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom char ch = frac.charAt(index); 262c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (!('0' <= ch && ch <= '9')) 263c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 264c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom break; 265c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 266c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 2676e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 268c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (index - 1 > 3) 269c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 270c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom frac = frac.substring(0, 4) + frac.substring(index); 271c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom d = d.substring(0, 14) + frac; 272c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 2736e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom else if (index - 1 == 1) 2746e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 2756e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom frac = frac.substring(0, index) + "00" + frac.substring(index); 2766e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom d = d.substring(0, 14) + frac; 2776e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 2786e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom else if (index - 1 == 2) 2796e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 2806e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom frac = frac.substring(0, index) + "0" + frac.substring(index); 2816e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom d = d.substring(0, 14) + frac; 2826e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 283b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 284c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 285c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return dateF.parse(d); 286b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 287c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 288c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private boolean hasFractionalSeconds() 289c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 290c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return time.indexOf('.') == 14; 291c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 292c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 293b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private byte[] getOctets() 294b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 295b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam char[] cs = time.toCharArray(); 296b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] bs = new byte[cs.length]; 297b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 298b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i != cs.length; i++) 299b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 300b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bs[i] = (byte)cs[i]; 301b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 302b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 303b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return bs; 304b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 305b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 306b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 307b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam void encode( 308b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam DEROutputStream out) 309b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 310b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 311b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam out.writeEncoded(GENERALIZED_TIME, this.getOctets()); 312b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 313b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 314c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom boolean asn1Equals( 315c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom DERObject o) 316b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 317c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (!(o instanceof DERGeneralizedTime)) 318b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 319b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return false; 320b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 321b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 322b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return time.equals(((DERGeneralizedTime)o).time); 323b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 324b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 325b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public int hashCode() 326b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 327b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return time.hashCode(); 328b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 329b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 330