LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/asn1 - a_utctm.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 14 97 14.4 %
Date: 2015-10-10 Functions: 1 6 16.7 %

          Line data    Source code
       1             : /* crypto/asn1/a_utctm.c */
       2             : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       3             :  * All rights reserved.
       4             :  *
       5             :  * This package is an SSL implementation written
       6             :  * by Eric Young (eay@cryptsoft.com).
       7             :  * The implementation was written so as to conform with Netscapes SSL.
       8             :  *
       9             :  * This library is free for commercial and non-commercial use as long as
      10             :  * the following conditions are aheared to.  The following conditions
      11             :  * apply to all code found in this distribution, be it the RC4, RSA,
      12             :  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
      13             :  * included with this distribution is covered by the same copyright terms
      14             :  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
      15             :  *
      16             :  * Copyright remains Eric Young's, and as such any Copyright notices in
      17             :  * the code are not to be removed.
      18             :  * If this package is used in a product, Eric Young should be given attribution
      19             :  * as the author of the parts of the library used.
      20             :  * This can be in the form of a textual message at program startup or
      21             :  * in documentation (online or textual) provided with the package.
      22             :  *
      23             :  * Redistribution and use in source and binary forms, with or without
      24             :  * modification, are permitted provided that the following conditions
      25             :  * are met:
      26             :  * 1. Redistributions of source code must retain the copyright
      27             :  *    notice, this list of conditions and the following disclaimer.
      28             :  * 2. Redistributions in binary form must reproduce the above copyright
      29             :  *    notice, this list of conditions and the following disclaimer in the
      30             :  *    documentation and/or other materials provided with the distribution.
      31             :  * 3. All advertising materials mentioning features or use of this software
      32             :  *    must display the following acknowledgement:
      33             :  *    "This product includes cryptographic software written by
      34             :  *     Eric Young (eay@cryptsoft.com)"
      35             :  *    The word 'cryptographic' can be left out if the rouines from the library
      36             :  *    being used are not cryptographic related :-).
      37             :  * 4. If you include any Windows specific code (or a derivative thereof) from
      38             :  *    the apps directory (application code) you must include an acknowledgement:
      39             :  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
      40             :  *
      41             :  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
      42             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      43             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      44             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      45             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      46             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      47             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      49             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      50             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      51             :  * SUCH DAMAGE.
      52             :  *
      53             :  * The licence and distribution terms for any publically available version or
      54             :  * derivative of this code cannot be changed.  i.e. this code cannot simply be
      55             :  * copied and put under another distribution licence
      56             :  * [including the GNU Public Licence.]
      57             :  */
      58             : 
      59             : #include <stdio.h>
      60             : #include <time.h>
      61             : #include "cryptlib.h"
      62             : #include "o_time.h"
      63             : #include <openssl/asn1.h>
      64             : #include "asn1_locl.h"
      65             : 
      66             : #if 0
      67             : int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp)
      68             : {
      69             : # ifndef CHARSET_EBCDIC
      70             :     return (i2d_ASN1_bytes((ASN1_STRING *)a, pp,
      71             :                            V_ASN1_UTCTIME, V_ASN1_UNIVERSAL));
      72             : # else
      73             :     /* KLUDGE! We convert to ascii before writing DER */
      74             :     int len;
      75             :     char tmp[24];
      76             :     ASN1_STRING x = *(ASN1_STRING *)a;
      77             : 
      78             :     len = x.length;
      79             :     ebcdic2ascii(tmp, x.data, (len >= sizeof tmp) ? sizeof tmp : len);
      80             :     x.data = tmp;
      81             :     return i2d_ASN1_bytes(&x, pp, V_ASN1_UTCTIME, V_ASN1_UNIVERSAL);
      82             : # endif
      83             : }
      84             : 
      85             : ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
      86             :                                long length)
      87             : {
      88             :     ASN1_UTCTIME *ret = NULL;
      89             : 
      90             :     ret = (ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length,
      91             :                                          V_ASN1_UTCTIME, V_ASN1_UNIVERSAL);
      92             :     if (ret == NULL) {
      93             :         ASN1err(ASN1_F_D2I_ASN1_UTCTIME, ERR_R_NESTED_ASN1_ERROR);
      94             :         return (NULL);
      95             :     }
      96             : # ifdef CHARSET_EBCDIC
      97             :     ascii2ebcdic(ret->data, ret->data, ret->length);
      98             : # endif
      99             :     if (!ASN1_UTCTIME_check(ret)) {
     100             :         ASN1err(ASN1_F_D2I_ASN1_UTCTIME, ASN1_R_INVALID_TIME_FORMAT);
     101             :         goto err;
     102             :     }
     103             : 
     104             :     return (ret);
     105             :  err:
     106             :     if ((ret != NULL) && ((a == NULL) || (*a != ret)))
     107             :         M_ASN1_UTCTIME_free(ret);
     108             :     return (NULL);
     109             : }
     110             : 
     111             : #endif
     112             : 
     113           0 : int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
     114             : {
     115             :     static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };
     116             :     static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 };
     117             :     char *a;
     118             :     int n, i, l, o;
     119             : 
     120           0 :     if (d->type != V_ASN1_UTCTIME)
     121             :         return (0);
     122           0 :     l = d->length;
     123           0 :     a = (char *)d->data;
     124             :     o = 0;
     125             : 
     126           0 :     if (l < 11)
     127             :         goto err;
     128           0 :     for (i = 0; i < 6; i++) {
     129           0 :         if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
     130             :             i++;
     131           0 :             if (tm)
     132           0 :                 tm->tm_sec = 0;
     133             :             break;
     134             :         }
     135           0 :         if ((a[o] < '0') || (a[o] > '9'))
     136             :             goto err;
     137           0 :         n = a[o] - '0';
     138           0 :         if (++o > l)
     139             :             goto err;
     140             : 
     141           0 :         if ((a[o] < '0') || (a[o] > '9'))
     142             :             goto err;
     143           0 :         n = (n * 10) + a[o] - '0';
     144           0 :         if (++o > l)
     145             :             goto err;
     146             : 
     147           0 :         if ((n < min[i]) || (n > max[i]))
     148             :             goto err;
     149           0 :         if (tm) {
     150           0 :             switch (i) {
     151             :             case 0:
     152           0 :                 tm->tm_year = n < 50 ? n + 100 : n;
     153           0 :                 break;
     154             :             case 1:
     155           0 :                 tm->tm_mon = n - 1;
     156           0 :                 break;
     157             :             case 2:
     158           0 :                 tm->tm_mday = n;
     159           0 :                 break;
     160             :             case 3:
     161           0 :                 tm->tm_hour = n;
     162           0 :                 break;
     163             :             case 4:
     164           0 :                 tm->tm_min = n;
     165           0 :                 break;
     166             :             case 5:
     167           0 :                 tm->tm_sec = n;
     168           0 :                 break;
     169             :             }
     170             :         }
     171             :     }
     172           0 :     if (a[o] == 'Z')
     173           0 :         o++;
     174           0 :     else if ((a[o] == '+') || (a[o] == '-')) {
     175           0 :         int offsign = a[o] == '-' ? -1 : 1, offset = 0;
     176           0 :         o++;
     177           0 :         if (o + 4 > l)
     178             :             goto err;
     179           0 :         for (i = 6; i < 8; i++) {
     180           0 :             if ((a[o] < '0') || (a[o] > '9'))
     181             :                 goto err;
     182           0 :             n = a[o] - '0';
     183           0 :             o++;
     184           0 :             if ((a[o] < '0') || (a[o] > '9'))
     185             :                 goto err;
     186           0 :             n = (n * 10) + a[o] - '0';
     187           0 :             if ((n < min[i]) || (n > max[i]))
     188             :                 goto err;
     189           0 :             if (tm) {
     190           0 :                 if (i == 6)
     191           0 :                     offset = n * 3600;
     192           0 :                 else if (i == 7)
     193           0 :                     offset += n * 60;
     194             :             }
     195           0 :             o++;
     196             :         }
     197           0 :         if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
     198             :             return 0;
     199             :     }
     200           0 :     return o == l;
     201             :  err:
     202             :     return 0;
     203             : }
     204             : 
     205           0 : int ASN1_UTCTIME_check(const ASN1_UTCTIME *d)
     206             : {
     207           0 :     return asn1_utctime_to_tm(NULL, d);
     208             : }
     209             : 
     210           0 : int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
     211             : {
     212             :     ASN1_UTCTIME t;
     213             : 
     214           0 :     t.type = V_ASN1_UTCTIME;
     215           0 :     t.length = strlen(str);
     216           0 :     t.data = (unsigned char *)str;
     217           0 :     if (ASN1_UTCTIME_check(&t)) {
     218           0 :         if (s != NULL) {
     219           0 :             if (!ASN1_STRING_set((ASN1_STRING *)s,
     220             :                                  (unsigned char *)str, t.length))
     221             :                 return 0;
     222           0 :             s->type = V_ASN1_UTCTIME;
     223             :         }
     224             :         return (1);
     225             :     } else
     226             :         return (0);
     227             : }
     228             : 
     229           0 : ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
     230             : {
     231           0 :     return ASN1_UTCTIME_adj(s, t, 0, 0);
     232             : }
     233             : 
     234        1480 : ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
     235             :                                int offset_day, long offset_sec)
     236             : {
     237             :     char *p;
     238             :     struct tm *ts;
     239             :     struct tm data;
     240             :     size_t len = 20;
     241             :     int free_s = 0;
     242             : 
     243        1480 :     if (s == NULL) {
     244             :         free_s = 1;
     245           0 :         s = M_ASN1_UTCTIME_new();
     246             :     }
     247        1480 :     if (s == NULL)
     248             :         goto err;
     249             : 
     250        1480 :     ts = OPENSSL_gmtime(&t, &data);
     251        1480 :     if (ts == NULL)
     252             :         goto err;
     253             : 
     254        1480 :     if (offset_day || offset_sec) {
     255           0 :         if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
     256             :             goto err;
     257             :     }
     258             : 
     259        1480 :     if ((ts->tm_year < 50) || (ts->tm_year >= 150))
     260             :         goto err;
     261             : 
     262        1480 :     p = (char *)s->data;
     263        1480 :     if ((p == NULL) || ((size_t)s->length < len)) {
     264           0 :         p = OPENSSL_malloc(len);
     265           0 :         if (p == NULL) {
     266           0 :             ASN1err(ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE);
     267           0 :             goto err;
     268             :         }
     269           0 :         if (s->data != NULL)
     270           0 :             OPENSSL_free(s->data);
     271           0 :         s->data = (unsigned char *)p;
     272             :     }
     273             : 
     274        2960 :     BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100,
     275        1480 :                  ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
     276             :                  ts->tm_sec);
     277        1480 :     s->length = strlen(p);
     278        1480 :     s->type = V_ASN1_UTCTIME;
     279             : #ifdef CHARSET_EBCDIC_not
     280             :     ebcdic2ascii(s->data, s->data, s->length);
     281             : #endif
     282        1480 :     return (s);
     283             :  err:
     284           0 :     if (free_s && s)
     285           0 :         M_ASN1_UTCTIME_free(s);
     286             :     return NULL;
     287             : }
     288             : 
     289           0 : int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
     290             : {
     291             :     struct tm stm, ttm;
     292             :     int day, sec;
     293             : 
     294           0 :     if (!asn1_utctime_to_tm(&stm, s))
     295             :         return -2;
     296             : 
     297           0 :     if (!OPENSSL_gmtime(&t, &ttm))
     298             :         return -2;
     299             : 
     300           0 :     if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
     301             :         return -2;
     302             : 
     303           0 :     if (day > 0)
     304             :         return 1;
     305           0 :     if (day < 0)
     306             :         return -1;
     307           0 :     if (sec > 0)
     308             :         return 1;
     309           0 :     if (sec < 0)
     310             :         return -1;
     311           0 :     return 0;
     312             : }
     313             : 
     314             : #if 0
     315             : time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s)
     316             : {
     317             :     struct tm tm;
     318             :     int offset;
     319             : 
     320             :     memset(&tm, '\0', sizeof tm);
     321             : 
     322             : # define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
     323             :     tm.tm_year = g2(s->data);
     324             :     if (tm.tm_year < 50)
     325             :         tm.tm_year += 100;
     326             :     tm.tm_mon = g2(s->data + 2) - 1;
     327             :     tm.tm_mday = g2(s->data + 4);
     328             :     tm.tm_hour = g2(s->data + 6);
     329             :     tm.tm_min = g2(s->data + 8);
     330             :     tm.tm_sec = g2(s->data + 10);
     331             :     if (s->data[12] == 'Z')
     332             :         offset = 0;
     333             :     else {
     334             :         offset = g2(s->data + 13) * 60 + g2(s->data + 15);
     335             :         if (s->data[12] == '-')
     336             :             offset = -offset;
     337             :     }
     338             : # undef g2
     339             : 
     340             :     /*
     341             :      * FIXME: mktime assumes the current timezone
     342             :      * instead of UTC, and unless we rewrite OpenSSL
     343             :      * in Lisp we cannot locally change the timezone
     344             :      * without possibly interfering with other parts
     345             :      * of the program. timegm, which uses UTC, is
     346             :      * non-standard.
     347             :      * Also time_t is inappropriate for general
     348             :      * UTC times because it may a 32 bit type.
     349             :      */
     350             :     return mktime(&tm) - offset * 60;
     351             : }
     352             : #endif

Generated by: LCOV version 1.10