1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.bouncycastle.asn1; 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException; 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.text.SimpleDateFormat; 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Date; 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.SimpleTimeZone; 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * UTC time object. 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class DERUTCTime 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project extends DERObject 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String time; 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return an UTC Time from the passed in object. 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @exception IllegalArgumentException if the object cannot be converted. 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static DERUTCTime getInstance( 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object obj) 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj == null || obj instanceof DERUTCTime) 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (DERUTCTime)obj; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj instanceof ASN1OctetString) 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new DERUTCTime(((ASN1OctetString)obj).getOctets()); 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return an UTC Time from a tagged object. 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param obj the tagged object holding the object we want 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param explicit true if the object is meant to be explicitly 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * tagged false otherwise. 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @exception IllegalArgumentException if the tagged object cannot 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * be converted. 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static DERUTCTime getInstance( 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ASN1TaggedObject obj, 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean explicit) 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return getInstance(obj.getObject()); 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * never encoded. When you're creating one of these objects from scratch, that's 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * what you want to use, otherwise we'll try to deal with whatever gets read from 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the input stream... (this is why the input format is different from the getTime() 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method output). 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param time the time string. 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public DERUTCTime( 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String time) 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.time = time; 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * base constructer from a java.util.date object 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public DERUTCTime( 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Date time) 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'"); 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dateF.setTimeZone(new SimpleTimeZone(0,"Z")); 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.time = dateF.format(time); 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DERUTCTime( 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] bytes) 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // explicitly convert to characters 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char[] dateC = new char[bytes.length]; 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i != dateC.length; i++) 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dateC[i] = (char)(bytes[i] & 0xff); 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.time = new String(dateC); 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return the time - always in the form of 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * YYMMDDhhmmssGMT(+hh:mm|-hh:mm). 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Normally in a certificate we would expect "Z" rather than "GMT", 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * however adding the "GMT" means we can just use: 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <pre> 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dateF = new SimpleDateFormat("yyMMddHHmmssz"); 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </pre> 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * To read in the time and get a date which is compatible with our local 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * time zone. 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <b>Note:</b> In some cases, due to the local date processing, this 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * may lead to unexpected results. If you want to stick the normal 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * convention of 1950 to 2049 use the getAdjustedTime() method. 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String getTime() 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // standardise the format. 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (time.length() == 11) 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return time.substring(0, 10) + "00GMT+00:00"; 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else if (time.length() == 13) 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return time.substring(0, 12) + "GMT+00:00"; 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else if (time.length() == 17) 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return time.substring(0, 12) + "GMT" + time.substring(12, 15) + ":" + time.substring(15, 17); 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return time; 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return the time as an adjusted date with a 4 digit year. This goes 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in the range of 1950 - 2049. 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String getAdjustedTime() 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String d = this.getTime(); 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (d.charAt(0) < '5') 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return "20" + d; 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return "19" + d; 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private byte[] getOctets() 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char[] cs = time.toCharArray(); 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] bs = new byte[cs.length]; 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i != cs.length; i++) 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bs[i] = (byte)cs[i]; 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return bs; 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void encode( 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DEROutputStream out) 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeEncoded(UTC_TIME, this.getOctets()); 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean equals( 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object o) 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((o == null) || !(o instanceof DERUTCTime)) 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return time.equals(((DERUTCTime)o).time); 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int hashCode() 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return time.hashCode(); 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toString() 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return time; 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 194