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 10280304Sjkim * 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 56280304Sjkim/*- 57280304Sjkim * 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) 76280304Sjkim{ 77280304Sjkim# ifdef CHARSET_EBCDIC 78280304Sjkim /* KLUDGE! We convert to ascii before writing DER */ 79280304Sjkim char tmp[24]; 80280304Sjkim ASN1_STRING tmpstr; 8155714Skris 82280304Sjkim if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) { 83280304Sjkim int len; 8455714Skris 85280304Sjkim tmpstr = *(ASN1_STRING *)a; 86280304Sjkim len = tmpstr.length; 87280304Sjkim ebcdic2ascii(tmp, tmpstr.data, 88280304Sjkim (len >= sizeof tmp) ? sizeof tmp : len); 89280304Sjkim tmpstr.data = tmp; 90280304Sjkim a = (ASN1_GENERALIZEDTIME *)&tmpstr; 91280304Sjkim } 92280304Sjkim# endif 93280304Sjkim if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) 94280304Sjkim return (i2d_ASN1_bytes((ASN1_STRING *)a, pp, 95280304Sjkim a->type, V_ASN1_UNIVERSAL)); 96280304Sjkim ASN1err(ASN1_F_I2D_ASN1_TIME, ASN1_R_EXPECTING_A_TIME); 97280304Sjkim return -1; 98280304Sjkim} 9955714Skris#endif 10055714Skris 10155714SkrisASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t) 102280304Sjkim{ 103280304Sjkim return ASN1_TIME_adj(s, t, 0, 0); 104280304Sjkim} 105238405Sjkim 106238405SjkimASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, 107280304Sjkim int offset_day, long offset_sec) 108280304Sjkim{ 109280304Sjkim struct tm *ts; 110280304Sjkim struct tm data; 11155714Skris 112280304Sjkim ts = OPENSSL_gmtime(&t, &data); 113280304Sjkim if (ts == NULL) { 114280304Sjkim ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME); 115280304Sjkim return NULL; 116280304Sjkim } 117280304Sjkim if (offset_day || offset_sec) { 118280304Sjkim if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) 119280304Sjkim return NULL; 120280304Sjkim } 121280304Sjkim if ((ts->tm_year >= 50) && (ts->tm_year < 150)) 122280304Sjkim return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec); 123280304Sjkim return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec); 124280304Sjkim} 125109998Smarkm 126109998Smarkmint ASN1_TIME_check(ASN1_TIME *t) 127280304Sjkim{ 128280304Sjkim if (t->type == V_ASN1_GENERALIZEDTIME) 129280304Sjkim return ASN1_GENERALIZEDTIME_check(t); 130280304Sjkim else if (t->type == V_ASN1_UTCTIME) 131280304Sjkim return ASN1_UTCTIME_check(t); 132280304Sjkim return 0; 133280304Sjkim} 134109998Smarkm 135109998Smarkm/* Convert an ASN1_TIME structure to GeneralizedTime */ 136280304SjkimASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, 137280304Sjkim ASN1_GENERALIZEDTIME **out) 138280304Sjkim{ 139280304Sjkim ASN1_GENERALIZEDTIME *ret; 140280304Sjkim char *str; 141280304Sjkim int newlen; 142109998Smarkm 143280304Sjkim if (!ASN1_TIME_check(t)) 144280304Sjkim return NULL; 145109998Smarkm 146280304Sjkim if (!out || !*out) { 147280304Sjkim if (!(ret = ASN1_GENERALIZEDTIME_new())) 148280304Sjkim return NULL; 149280304Sjkim if (out) 150280304Sjkim *out = ret; 151280304Sjkim } else 152280304Sjkim ret = *out; 153109998Smarkm 154280304Sjkim /* If already GeneralizedTime just copy across */ 155280304Sjkim if (t->type == V_ASN1_GENERALIZEDTIME) { 156280304Sjkim if (!ASN1_STRING_set(ret, t->data, t->length)) 157280304Sjkim return NULL; 158280304Sjkim return ret; 159280304Sjkim } 160109998Smarkm 161280304Sjkim /* grow the string */ 162280304Sjkim if (!ASN1_STRING_set(ret, NULL, t->length + 2)) 163280304Sjkim return NULL; 164280304Sjkim /* ASN1_STRING_set() allocated 'len + 1' bytes. */ 165280304Sjkim newlen = t->length + 2 + 1; 166280304Sjkim str = (char *)ret->data; 167280304Sjkim /* Work out the century and prepend */ 168280304Sjkim if (t->data[0] >= '5') 169280304Sjkim BUF_strlcpy(str, "19", newlen); 170280304Sjkim else 171280304Sjkim BUF_strlcpy(str, "20", newlen); 172109998Smarkm 173280304Sjkim BUF_strlcat(str, (char *)t->data, newlen); 174109998Smarkm 175280304Sjkim return ret; 176280304Sjkim} 177238405Sjkim 178238405Sjkimint ASN1_TIME_set_string(ASN1_TIME *s, const char *str) 179280304Sjkim{ 180280304Sjkim ASN1_TIME t; 181238405Sjkim 182280304Sjkim t.length = strlen(str); 183280304Sjkim t.data = (unsigned char *)str; 184280304Sjkim t.flags = 0; 185238405Sjkim 186280304Sjkim t.type = V_ASN1_UTCTIME; 187238405Sjkim 188280304Sjkim if (!ASN1_TIME_check(&t)) { 189280304Sjkim t.type = V_ASN1_GENERALIZEDTIME; 190280304Sjkim if (!ASN1_TIME_check(&t)) 191280304Sjkim return 0; 192280304Sjkim } 193280304Sjkim 194280304Sjkim if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t)) 195280304Sjkim return 0; 196280304Sjkim 197280304Sjkim return 1; 198280304Sjkim} 199