"Fossies" - the Fresh Open Source Software Archive

Member "openssl-1.0.2q/crypto/asn1/a_gentm.c" (20 Nov 2018, 10128 Bytes) of package /linux/misc/openssl-1.0.2q.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "a_gentm.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.1.0g_vs_1.1.1-pre2.

    1 /* crypto/asn1/a_gentm.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 /*
   60  * GENERALIZEDTIME implementation, written by Steve Henson. Based on UTCTIME
   61  */
   62 
   63 #include <stdio.h>
   64 #include <time.h>
   65 #include "cryptlib.h"
   66 #include "o_time.h"
   67 #include <openssl/asn1.h>
   68 #include "asn1_locl.h"
   69 
   70 #if 0
   71 
   72 int i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a, unsigned char **pp)
   73 {
   74 # ifdef CHARSET_EBCDIC
   75     /* KLUDGE! We convert to ascii before writing DER */
   76     int len;
   77     char tmp[24];
   78     ASN1_STRING tmpstr = *(ASN1_STRING *)a;
   79 
   80     len = tmpstr.length;
   81     ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof(tmp)) ? sizeof(tmp) : len);
   82     tmpstr.data = tmp;
   83 
   84     a = (ASN1_GENERALIZEDTIME *)&tmpstr;
   85 # endif
   86     return (i2d_ASN1_bytes((ASN1_STRING *)a, pp,
   87                            V_ASN1_GENERALIZEDTIME, V_ASN1_UNIVERSAL));
   88 }
   89 
   90 ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a,
   91                                                unsigned char **pp,
   92                                                long length)
   93 {
   94     ASN1_GENERALIZEDTIME *ret = NULL;
   95 
   96     ret =
   97         (ASN1_GENERALIZEDTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length,
   98                                                V_ASN1_GENERALIZEDTIME,
   99                                                V_ASN1_UNIVERSAL);
  100     if (ret == NULL) {
  101         ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME, ERR_R_NESTED_ASN1_ERROR);
  102         return (NULL);
  103     }
  104 # ifdef CHARSET_EBCDIC
  105     ascii2ebcdic(ret->data, ret->data, ret->length);
  106 # endif
  107     if (!ASN1_GENERALIZEDTIME_check(ret)) {
  108         ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME, ASN1_R_INVALID_TIME_FORMAT);
  109         goto err;
  110     }
  111 
  112     return (ret);
  113  err:
  114     if ((ret != NULL) && ((a == NULL) || (*a != ret)))
  115         M_ASN1_GENERALIZEDTIME_free(ret);
  116     return (NULL);
  117 }
  118 
  119 #endif
  120 
  121 int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d)
  122 {
  123     static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
  124     static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
  125     char *a;
  126     int n, i, l, o;
  127 
  128     if (d->type != V_ASN1_GENERALIZEDTIME)
  129         return (0);
  130     l = d->length;
  131     a = (char *)d->data;
  132     o = 0;
  133     /*
  134      * GENERALIZEDTIME is similar to UTCTIME except the year is represented
  135      * as YYYY. This stuff treats everything as a two digit field so make
  136      * first two fields 00 to 99
  137      */
  138     if (l < 13)
  139         goto err;
  140     for (i = 0; i < 7; i++) {
  141         if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
  142             i++;
  143             if (tm)
  144                 tm->tm_sec = 0;
  145             break;
  146         }
  147         if ((a[o] < '0') || (a[o] > '9'))
  148             goto err;
  149         n = a[o] - '0';
  150         if (++o > l)
  151             goto err;
  152 
  153         if ((a[o] < '0') || (a[o] > '9'))
  154             goto err;
  155         n = (n * 10) + a[o] - '0';
  156         if (++o > l)
  157             goto err;
  158 
  159         if ((n < min[i]) || (n > max[i]))
  160             goto err;
  161         if (tm) {
  162             switch (i) {
  163             case 0:
  164                 tm->tm_year = n * 100 - 1900;
  165                 break;
  166             case 1:
  167                 tm->tm_year += n;
  168                 break;
  169             case 2:
  170                 tm->tm_mon = n - 1;
  171                 break;
  172             case 3:
  173                 tm->tm_mday = n;
  174                 break;
  175             case 4:
  176                 tm->tm_hour = n;
  177                 break;
  178             case 5:
  179                 tm->tm_min = n;
  180                 break;
  181             case 6:
  182                 tm->tm_sec = n;
  183                 break;
  184             }
  185         }
  186     }
  187     /*
  188      * Optional fractional seconds: decimal point followed by one or more
  189      * digits.
  190      */
  191     if (a[o] == '.') {
  192         if (++o > l)
  193             goto err;
  194         i = o;
  195         while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
  196             o++;
  197         /* Must have at least one digit after decimal point */
  198         if (i == o)
  199             goto err;
  200     }
  201 
  202     if (a[o] == 'Z')
  203         o++;
  204     else if ((a[o] == '+') || (a[o] == '-')) {
  205         int offsign = a[o] == '-' ? 1 : -1, offset = 0;
  206         o++;
  207         if (o + 4 > l)
  208             goto err;
  209         for (i = 7; i < 9; i++) {
  210             if ((a[o] < '0') || (a[o] > '9'))
  211                 goto err;
  212             n = a[o] - '0';
  213             o++;
  214             if ((a[o] < '0') || (a[o] > '9'))
  215                 goto err;
  216             n = (n * 10) + a[o] - '0';
  217             if ((n < min[i]) || (n > max[i]))
  218                 goto err;
  219             if (tm) {
  220                 if (i == 7)
  221                     offset = n * 3600;
  222                 else if (i == 8)
  223                     offset += n * 60;
  224             }
  225             o++;
  226         }
  227         if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
  228             return 0;
  229     } else if (a[o]) {
  230         /* Missing time zone information. */
  231         goto err;
  232     }
  233     return (o == l);
  234  err:
  235     return (0);
  236 }
  237 
  238 int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d)
  239 {
  240     return asn1_generalizedtime_to_tm(NULL, d);
  241 }
  242 
  243 int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
  244 {
  245     ASN1_GENERALIZEDTIME t;
  246 
  247     t.type = V_ASN1_GENERALIZEDTIME;
  248     t.length = strlen(str);
  249     t.data = (unsigned char *)str;
  250     if (ASN1_GENERALIZEDTIME_check(&t)) {
  251         if (s != NULL) {
  252             if (!ASN1_STRING_set((ASN1_STRING *)s,
  253                                  (unsigned char *)str, t.length))
  254                 return 0;
  255             s->type = V_ASN1_GENERALIZEDTIME;
  256         }
  257         return (1);
  258     } else
  259         return (0);
  260 }
  261 
  262 ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
  263                                                time_t t)
  264 {
  265     return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
  266 }
  267 
  268 ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
  269                                                time_t t, int offset_day,
  270                                                long offset_sec)
  271 {
  272     char *p;
  273     struct tm *ts;
  274     struct tm data;
  275     size_t len = 20;
  276 
  277     if (s == NULL)
  278         s = M_ASN1_GENERALIZEDTIME_new();
  279     if (s == NULL)
  280         return (NULL);
  281 
  282     ts = OPENSSL_gmtime(&t, &data);
  283     if (ts == NULL)
  284         return (NULL);
  285 
  286     if (offset_day || offset_sec) {
  287         if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
  288             return NULL;
  289     }
  290 
  291     p = (char *)s->data;
  292     if ((p == NULL) || ((size_t)s->length < len)) {
  293         p = OPENSSL_malloc(len);
  294         if (p == NULL) {
  295             ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, ERR_R_MALLOC_FAILURE);
  296             return (NULL);
  297         }
  298         if (s->data != NULL)
  299             OPENSSL_free(s->data);
  300         s->data = (unsigned char *)p;
  301     }
  302 
  303     BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900,
  304                  ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
  305                  ts->tm_sec);
  306     s->length = strlen(p);
  307     s->type = V_ASN1_GENERALIZEDTIME;
  308 #ifdef CHARSET_EBCDIC_not
  309     ebcdic2ascii(s->data, s->data, s->length);
  310 #endif
  311     return (s);
  312 }