a_time.c revision 280297
155714Skris/* crypto/asn1/a_time.c */ 255714Skris/* ==================================================================== 355714Skris * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 455714Skris * 555714Skris * Redistribution and use in source and binary forms, with or without 655714Skris * modification, are permitted provided that the following conditions 755714Skris * are met: 855714Skris * 955714Skris * 1. Redistributions of source code must retain the above copyright 10280297Sjkim * notice, this list of conditions and the following disclaimer. 1155714Skris * 1255714Skris * 2. Redistributions in binary form must reproduce the above copyright 1355714Skris * notice, this list of conditions and the following disclaimer in 1455714Skris * the documentation and/or other materials provided with the 1555714Skris * distribution. 1655714Skris * 1755714Skris * 3. All advertising materials mentioning features or use of this 1855714Skris * software must display the following acknowledgment: 1955714Skris * "This product includes software developed by the OpenSSL Project 2055714Skris * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2155714Skris * 2255714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2355714Skris * endorse or promote products derived from this software without 2455714Skris * prior written permission. For written permission, please contact 2555714Skris * licensing@OpenSSL.org. 2655714Skris * 2755714Skris * 5. Products derived from this software may not be called "OpenSSL" 2855714Skris * nor may "OpenSSL" appear in their names without prior written 2955714Skris * permission of the OpenSSL Project. 3055714Skris * 3155714Skris * 6. Redistributions of any form whatsoever must retain the following 3255714Skris * acknowledgment: 3355714Skris * "This product includes software developed by the OpenSSL Project 3455714Skris * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3555714Skris * 3655714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 3755714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 3855714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 3955714Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4055714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4155714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4255714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4355714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4455714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4555714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4655714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 4755714Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 4855714Skris * ==================================================================== 4955714Skris * 5055714Skris * This product includes cryptographic software written by Eric Young 5155714Skris * (eay@cryptsoft.com). This product includes software written by Tim 5255714Skris * Hudson (tjh@cryptsoft.com). 5355714Skris * 5455714Skris */ 5555714Skris 56280297Sjkim/*- 57280297Sjkim * This is an implementation of the ASN1 Time structure which is: 5855714Skris * Time ::= CHOICE { 5955714Skris * utcTime UTCTime, 6055714Skris * generalTime GeneralizedTime } 6155714Skris * written by Steve Henson. 6255714Skris */ 6355714Skris 6455714Skris#include <stdio.h> 6555714Skris#include <time.h> 6655714Skris#include "cryptlib.h" 67109998Smarkm#include "o_time.h" 68109998Smarkm#include <openssl/asn1t.h> 6955714Skris 70109998SmarkmIMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME) 7159191Skris 72109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME) 7359191Skris 74109998Smarkm#if 0 7555714Skrisint i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp) 76280297Sjkim{ 77280297Sjkim# ifdef CHARSET_EBCDIC 78280297Sjkim /* KLUDGE! We convert to ascii before writing DER */ 79280297Sjkim char tmp[24]; 80280297Sjkim ASN1_STRING tmpstr; 8155714Skris 82280297Sjkim if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) { 83280297Sjkim int len; 8455714Skris 85280297Sjkim tmpstr = *(ASN1_STRING *)a; 86280297Sjkim len = tmpstr.length; 87280297Sjkim ebcdic2ascii(tmp, tmpstr.data, 88280297Sjkim (len >= sizeof tmp) ? sizeof tmp : len); 89280297Sjkim tmpstr.data = tmp; 90280297Sjkim a = (ASN1_GENERALIZEDTIME *)&tmpstr; 91280297Sjkim } 92280297Sjkim# endif 93280297Sjkim if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) 94280297Sjkim return (i2d_ASN1_bytes((ASN1_STRING *)a, pp, 95280297Sjkim a->type, V_ASN1_UNIVERSAL)); 96280297Sjkim ASN1err(ASN1_F_I2D_ASN1_TIME, ASN1_R_EXPECTING_A_TIME); 97280297Sjkim return -1; 98280297Sjkim} 9955714Skris#endif 10055714Skris 10155714SkrisASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t) 102280297Sjkim{ 103280297Sjkim return ASN1_TIME_adj(s, t, 0, 0); 104280297Sjkim} 105238405Sjkim 106238405SjkimASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, 107280297Sjkim int offset_day, long offset_sec) 108280297Sjkim{ 109280297Sjkim struct tm *ts; 110280297Sjkim struct tm data; 11155714Skris 112280297Sjkim ts = OPENSSL_gmtime(&t, &data); 113280297Sjkim if (ts == NULL) { 114280297Sjkim ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME); 115280297Sjkim return NULL; 116280297Sjkim } 117280297Sjkim if (offset_day || offset_sec) { 118280297Sjkim if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) 119280297Sjkim return NULL; 120280297Sjkim } 121280297Sjkim if ((ts->tm_year >= 50) && (ts->tm_year < 150)) 122280297Sjkim return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec); 123280297Sjkim return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec); 124280297Sjkim} 125109998Smarkm 126109998Smarkmint ASN1_TIME_check(ASN1_TIME *t) 127280297Sjkim{ 128280297Sjkim if (t->type == V_ASN1_GENERALIZEDTIME) 129280297Sjkim return ASN1_GENERALIZEDTIME_check(t); 130280297Sjkim else if (t->type == V_ASN1_UTCTIME) 131280297Sjkim return ASN1_UTCTIME_check(t); 132280297Sjkim return 0; 133280297Sjkim} 134109998Smarkm 135109998Smarkm/* Convert an ASN1_TIME structure to GeneralizedTime */ 136280297SjkimASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, 137280297Sjkim ASN1_GENERALIZEDTIME **out) 138280297Sjkim{ 139280297Sjkim ASN1_GENERALIZEDTIME *ret; 140280297Sjkim char *str; 141280297Sjkim int newlen; 142109998Smarkm 143280297Sjkim if (!ASN1_TIME_check(t)) 144280297Sjkim return NULL; 145109998Smarkm 146280297Sjkim if (!out || !*out) { 147280297Sjkim if (!(ret = ASN1_GENERALIZEDTIME_new())) 148280297Sjkim return NULL; 149280297Sjkim if (out) 150280297Sjkim *out = ret; 151280297Sjkim } else 152280297Sjkim ret = *out; 153109998Smarkm 154280297Sjkim /* If already GeneralizedTime just copy across */ 155280297Sjkim if (t->type == V_ASN1_GENERALIZEDTIME) { 156280297Sjkim if (!ASN1_STRING_set(ret, t->data, t->length)) 157280297Sjkim return NULL; 158280297Sjkim return ret; 159280297Sjkim } 160109998Smarkm 161280297Sjkim /* grow the string */ 162280297Sjkim if (!ASN1_STRING_set(ret, NULL, t->length + 2)) 163280297Sjkim return NULL; 164280297Sjkim /* ASN1_STRING_set() allocated 'len + 1' bytes. */ 165280297Sjkim newlen = t->length + 2 + 1; 166280297Sjkim str = (char *)ret->data; 167280297Sjkim /* Work out the century and prepend */ 168280297Sjkim if (t->data[0] >= '5') 169280297Sjkim BUF_strlcpy(str, "19", newlen); 170280297Sjkim else 171280297Sjkim BUF_strlcpy(str, "20", newlen); 172109998Smarkm 173280297Sjkim BUF_strlcat(str, (char *)t->data, newlen); 174109998Smarkm 175280297Sjkim return ret; 176280297Sjkim} 177238405Sjkim 178238405Sjkimint ASN1_TIME_set_string(ASN1_TIME *s, const char *str) 179280297Sjkim{ 180280297Sjkim ASN1_TIME t; 181238405Sjkim 182280297Sjkim t.length = strlen(str); 183280297Sjkim t.data = (unsigned char *)str; 184280297Sjkim t.flags = 0; 185238405Sjkim 186280297Sjkim t.type = V_ASN1_UTCTIME; 187238405Sjkim 188280297Sjkim if (!ASN1_TIME_check(&t)) { 189280297Sjkim t.type = V_ASN1_GENERALIZEDTIME; 190280297Sjkim if (!ASN1_TIME_check(&t)) 191280297Sjkim return 0; 192280297Sjkim } 193280297Sjkim 194280297Sjkim if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t)) 195280297Sjkim return 0; 196280297Sjkim 197280297Sjkim return 1; 198280297Sjkim} 199