All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.asn1.ASN1UTCTime Maven / Gradle / Ivy

There is a newer version: 1.70_1
Show newest version
package org.bouncycastle.asn1;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.SimpleTimeZone;

import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Strings;

/**
- * UTC time object.
 * Internal facade of {@link ASN1UTCTime}.
 * 

* This datatype is valid only from 1950-01-01 00:00:00 UTC until 2049-12-31 23:59:59 UTC. *

*
*

X.690

*

11: Restrictions on BER employed by both CER and DER

*

11.8 UTCTime

* 11.8.1 The encoding shall terminate with "Z", * as described in the ITU-T X.680 | ISO/IEC 8824-1 clause on UTCTime. *

* 11.8.2 The seconds element shall always be present. *

* 11.8.3 Midnight (GMT) shall be represented in the form: *

* "YYMMDD000000Z" *
* where "YYMMDD" represents the day following the midnight in question. */ public class ASN1UTCTime extends ASN1Primitive { private byte[] time; /** * Return an UTC Time from the passed in object. * * @param obj an ASN1UTCTime or an object that can be converted into one. * @exception IllegalArgumentException if the object cannot be converted. * @return an ASN1UTCTime instance, or null. */ public static ASN1UTCTime getInstance( Object obj) { if (obj == null || obj instanceof ASN1UTCTime) { return (ASN1UTCTime)obj; } if (obj instanceof byte[]) { try { return (ASN1UTCTime)fromByteArray((byte[])obj); } catch (Exception e) { throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); } } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); } /** * Return an UTC Time from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. * @return an ASN1UTCTime instance, or null. */ public static ASN1UTCTime getInstance( ASN1TaggedObject obj, boolean explicit) { ASN1Object o = obj.getObject(); if (explicit || o instanceof ASN1UTCTime) { return getInstance(o); } else { return new ASN1UTCTime(ASN1OctetString.getInstance(o).getOctets()); } } /** * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were * never encoded. When you're creating one of these objects from scratch, that's * what you want to use, otherwise we'll try to deal with whatever gets read from * the input stream... (this is why the input format is different from the getTime() * method output). *

* * @param time the time string. */ public ASN1UTCTime( String time) { this.time = Strings.toByteArray(time); try { this.getDate(); } catch (ParseException e) { throw new IllegalArgumentException("invalid date string: " + e.getMessage()); } } /** * Base constructor from a java.util.date object * @param time the Date to build the time from. */ public ASN1UTCTime( Date time) { SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'", DateUtil.EN_Locale); dateF.setTimeZone(new SimpleTimeZone(0,"Z")); this.time = Strings.toByteArray(dateF.format(time)); } /** * Base constructor from a java.util.date and Locale - you may need to use this if the default locale * doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible with other ASN.1 implementations. * * @param time a date object representing the time of interest. * @param locale an appropriate Locale for producing an ASN.1 UTCTime value. */ public ASN1UTCTime( Date time, Locale locale) { SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'", locale); dateF.setTimeZone(new SimpleTimeZone(0,"Z")); this.time = Strings.toByteArray(dateF.format(time)); } ASN1UTCTime( byte[] time) { if (time.length < 2) { throw new IllegalArgumentException("UTCTime string too short"); } this.time = time; if (!(isDigit(0) && isDigit(1))) { throw new IllegalArgumentException("illegal characters in UTCTime string"); } } /** * Return the time as a date based on whatever a 2 digit year will return. For * standardised processing use getAdjustedDate(). * * @return the resulting date * @exception ParseException if the date string cannot be parsed. */ public Date getDate() throws ParseException { SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz"); return DateUtil.epochAdjust(dateF.parse(getTime())); } /** * Return the time as an adjusted date * in the range of 1950 - 2049. * * @return a date in the range of 1950 to 2049. * @exception ParseException if the date string cannot be parsed. */ public Date getAdjustedDate() throws ParseException { SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz"); dateF.setTimeZone(new SimpleTimeZone(0,"Z")); return DateUtil.epochAdjust(dateF.parse(getAdjustedTime())); } /** * Return the time - always in the form of * YYMMDDhhmmssGMT(+hh:mm|-hh:mm). *

* Normally in a certificate we would expect "Z" rather than "GMT", * however adding the "GMT" means we can just use: *

     *     dateF = new SimpleDateFormat("yyMMddHHmmssz");
     * 
* To read in the time and get a date which is compatible with our local * time zone. *

* Note: In some cases, due to the local date processing, this * may lead to unexpected results. If you want to stick the normal * convention of 1950 to 2049 use the getAdjustedTime() method. */ public String getTime() { String stime = Strings.fromByteArray(time); // // standardise the format. // if (stime.indexOf('-') < 0 && stime.indexOf('+') < 0) { if (stime.length() == 11) { return stime.substring(0, 10) + "00GMT+00:00"; } else { return stime.substring(0, 12) + "GMT+00:00"; } } else { int index = stime.indexOf('-'); if (index < 0) { index = stime.indexOf('+'); } String d = stime; if (index == stime.length() - 3) { d += "00"; } if (index == 10) { return d.substring(0, 10) + "00GMT" + d.substring(10, 13) + ":" + d.substring(13, 15); } else { return d.substring(0, 12) + "GMT" + d.substring(12, 15) + ":" + d.substring(15, 17); } } } /** * Return a time string as an adjusted date with a 4 digit year. This goes * in the range of 1950 - 2049. */ public String getAdjustedTime() { String d = this.getTime(); if (d.charAt(0) < '5') { return "20" + d; } else { return "19" + d; } } private boolean isDigit(int pos) { return time.length > pos && time[pos] >= '0' && time[pos] <= '9'; } boolean isConstructed() { return false; } int encodedLength() { int length = time.length; return 1 + StreamUtil.calculateBodyLength(length) + length; } void encode(ASN1OutputStream out, boolean withTag) throws IOException { out.writeEncoded(withTag, BERTags.UTC_TIME, time); } boolean asn1Equals( ASN1Primitive o) { if (!(o instanceof ASN1UTCTime)) { return false; } return Arrays.areEqual(time, ((ASN1UTCTime)o).time); } public int hashCode() { return Arrays.hashCode(time); } public String toString() { return Strings.fromByteArray(time); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy