|
Packit |
aea12f |
/*
|
|
Packit |
aea12f |
* Copyright (C) 2003-2016 Free Software Foundation, Inc.
|
|
Packit |
aea12f |
* Copyright (C) 2016 Red Hat, Inc.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Author: Nikos Mavrogiannopoulos
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This file is part of GnuTLS.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* The GnuTLS is free software; you can redistribute it and/or
|
|
Packit |
aea12f |
* modify it under the terms of the GNU Lesser General Public License
|
|
Packit |
aea12f |
* as published by the Free Software Foundation; either version 2.1 of
|
|
Packit |
aea12f |
* the License, or (at your option) any later version.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This library is distributed in the hope that it will be useful, but
|
|
Packit |
aea12f |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
aea12f |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
aea12f |
* Lesser General Public License for more details.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* You should have received a copy of the GNU Lesser General Public License
|
|
Packit |
aea12f |
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
#include "gnutls_int.h"
|
|
Packit |
aea12f |
#include <libtasn1.h>
|
|
Packit |
aea12f |
#include <datum.h>
|
|
Packit |
aea12f |
#include <global.h>
|
|
Packit |
aea12f |
#include "errors.h"
|
|
Packit |
aea12f |
#include <str.h>
|
|
Packit |
aea12f |
#include <x509.h>
|
|
Packit |
aea12f |
#include <num.h>
|
|
Packit |
aea12f |
#include <x509_b64.h>
|
|
Packit |
aea12f |
#include "x509_int.h"
|
|
Packit |
aea12f |
#include "extras/hex.h"
|
|
Packit |
aea12f |
#include <common.h>
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
time_t _gnutls_utcTime2gtime(const char *ttime);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* TIME functions
|
|
Packit |
aea12f |
* Conversions between generalized or UTC time to time_t
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* This is an emulation of the struct tm.
|
|
Packit |
aea12f |
* Since we do not use libc's functions, we don't need to
|
|
Packit |
aea12f |
* depend on the libc structure.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
typedef struct fake_tm {
|
|
Packit |
aea12f |
int tm_mon;
|
|
Packit |
aea12f |
int tm_year; /* FULL year - ie 1971 */
|
|
Packit |
aea12f |
int tm_mday;
|
|
Packit |
aea12f |
int tm_hour;
|
|
Packit |
aea12f |
int tm_min;
|
|
Packit |
aea12f |
int tm_sec;
|
|
Packit |
aea12f |
} fake_tm;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* The mktime_utc function is due to Russ Allbery (rra@stanford.edu),
|
|
Packit |
aea12f |
* who placed it under public domain:
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* The number of days in each month.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
static const int MONTHDAYS[] = {
|
|
Packit |
aea12f |
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
|
Packit |
aea12f |
};
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Whether a given year is a leap year. */
|
|
Packit |
aea12f |
#define ISLEAP(year) \
|
|
Packit |
aea12f |
(((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0))
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/*
|
|
Packit |
aea12f |
** Given a struct tm representing a calendar time in UTC, convert it to
|
|
Packit |
aea12f |
** seconds since epoch. Returns (time_t) -1 if the time is not
|
|
Packit |
aea12f |
** convertible. Note that this function does not canonicalize the provided
|
|
Packit |
aea12f |
** struct tm, nor does it allow out of range values or years before 1970.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
static time_t mktime_utc(const struct fake_tm *tm)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
time_t result = 0;
|
|
Packit |
aea12f |
int i;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* We do allow some ill-formed dates, but we don't do anything special
|
|
Packit |
aea12f |
* with them and our callers really shouldn't pass them to us. Do
|
|
Packit |
aea12f |
* explicitly disallow the ones that would cause invalid array accesses
|
|
Packit |
aea12f |
* or other algorithm problems.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
if (tm->tm_mon < 0 || tm->tm_mon > 11 || tm->tm_year < 1970)
|
|
Packit |
aea12f |
return (time_t) - 1;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Check for "obvious" mistakes in dates */
|
|
Packit |
aea12f |
if (tm->tm_sec > 60 || tm->tm_min > 59 || tm->tm_mday > 31 || tm->tm_mday < 1 || tm->tm_hour > 23)
|
|
Packit |
aea12f |
return (time_t) - 1;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Convert to a time_t.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
for (i = 1970; i < tm->tm_year; i++)
|
|
Packit |
aea12f |
result += 365 + ISLEAP(i);
|
|
Packit |
aea12f |
for (i = 0; i < tm->tm_mon; i++)
|
|
Packit |
aea12f |
result += MONTHDAYS[i];
|
|
Packit |
aea12f |
if (tm->tm_mon > 1 && ISLEAP(tm->tm_year))
|
|
Packit |
aea12f |
result++;
|
|
Packit |
aea12f |
result = 24 * (result + tm->tm_mday - 1) + tm->tm_hour;
|
|
Packit |
aea12f |
result = 60 * result + tm->tm_min;
|
|
Packit |
aea12f |
result = 60 * result + tm->tm_sec;
|
|
Packit |
aea12f |
return result;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* this one will parse dates of the form:
|
|
Packit |
aea12f |
* month|day|hour|minute|sec* (2 chars each)
|
|
Packit |
aea12f |
* and year is given. Returns a time_t date.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
static time_t time2gtime(const char *ttime, int year)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
char xx[4];
|
|
Packit |
aea12f |
struct fake_tm etime;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (strlen(ttime) < 8) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return (time_t) - 1;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
etime.tm_year = year;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* In order to work with 32 bit
|
|
Packit |
aea12f |
* time_t.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
if (sizeof(time_t) <= 4 && etime.tm_year >= 2038)
|
|
Packit |
aea12f |
return (time_t) 2145914603; /* 2037-12-31 23:23:23 */
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (etime.tm_year < 1970)
|
|
Packit |
aea12f |
return (time_t) 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
xx[2] = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* get the month
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
memcpy(xx, ttime, 2); /* month */
|
|
Packit |
aea12f |
etime.tm_mon = atoi(xx) - 1;
|
|
Packit |
aea12f |
ttime += 2;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* get the day
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
memcpy(xx, ttime, 2); /* day */
|
|
Packit |
aea12f |
etime.tm_mday = atoi(xx);
|
|
Packit |
aea12f |
ttime += 2;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* get the hour
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
memcpy(xx, ttime, 2); /* hour */
|
|
Packit |
aea12f |
etime.tm_hour = atoi(xx);
|
|
Packit |
aea12f |
ttime += 2;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* get the minutes
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
memcpy(xx, ttime, 2); /* minutes */
|
|
Packit |
aea12f |
etime.tm_min = atoi(xx);
|
|
Packit |
aea12f |
ttime += 2;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (strlen(ttime) >= 2) {
|
|
Packit |
aea12f |
memcpy(xx, ttime, 2);
|
|
Packit |
aea12f |
etime.tm_sec = atoi(xx);
|
|
Packit |
aea12f |
} else
|
|
Packit |
aea12f |
etime.tm_sec = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return mktime_utc(&etime);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* returns a time_t value that contains the given time.
|
|
Packit |
aea12f |
* The given time is expressed as:
|
|
Packit |
aea12f |
* YEAR(2)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* (seconds are optional)
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
time_t _gnutls_utcTime2gtime(const char *ttime)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
char xx[3];
|
|
Packit |
aea12f |
int year;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (strlen(ttime) < 10) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return (time_t) - 1;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
xx[2] = 0;
|
|
Packit |
aea12f |
/* get the year
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
memcpy(xx, ttime, 2); /* year */
|
|
Packit |
aea12f |
year = atoi(xx);
|
|
Packit |
aea12f |
ttime += 2;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (year > 49)
|
|
Packit |
aea12f |
year += 1900;
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
year += 2000;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return time2gtime(ttime, year);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* returns a time_t value that contains the given time.
|
|
Packit |
aea12f |
* The given time is expressed as:
|
|
Packit |
aea12f |
* YEAR(4)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
time_t _gnutls_x509_generalTime2gtime(const char *ttime)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
char xx[5];
|
|
Packit |
aea12f |
int year;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (strlen(ttime) < 12) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return (time_t) - 1;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (strchr(ttime, 'Z') == 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
/* required to be in GMT */
|
|
Packit |
aea12f |
return (time_t) - 1;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (strchr(ttime, '.') != 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
/* no fractional seconds allowed */
|
|
Packit |
aea12f |
return (time_t) - 1;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
xx[4] = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* get the year
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
memcpy(xx, ttime, 4); /* year */
|
|
Packit |
aea12f |
year = atoi(xx);
|
|
Packit |
aea12f |
ttime += 4;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return time2gtime(ttime, year);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* tag will contain ASN1_TAG_UTCTime or ASN1_TAG_GENERALIZEDTime */
|
|
Packit |
aea12f |
static int
|
|
Packit |
aea12f |
gtime_to_suitable_time(time_t gtime, char *str_time, size_t str_time_size, unsigned *tag)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
size_t ret;
|
|
Packit |
aea12f |
struct tm _tm;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (gtime == (time_t)-1
|
|
Packit |
aea12f |
#if SIZEOF_LONG == 8
|
|
Packit |
aea12f |
|| gtime >= 253402210800
|
|
Packit |
aea12f |
#endif
|
|
Packit |
aea12f |
) {
|
|
Packit |
aea12f |
if (tag)
|
|
Packit |
aea12f |
*tag = ASN1_TAG_GENERALIZEDTime;
|
|
Packit |
aea12f |
snprintf(str_time, str_time_size, "99991231235959Z");
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!gmtime_r(>ime, &_tm)) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INTERNAL_ERROR;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (_tm.tm_year >= 150) {
|
|
Packit |
aea12f |
if (tag)
|
|
Packit |
aea12f |
*tag = ASN1_TAG_GENERALIZEDTime;
|
|
Packit |
aea12f |
ret = strftime(str_time, str_time_size, "%Y%m%d%H%M%SZ", &_tm);
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
if (tag)
|
|
Packit |
aea12f |
*tag = ASN1_TAG_UTCTime;
|
|
Packit |
aea12f |
ret = strftime(str_time, str_time_size, "%y%m%d%H%M%SZ", &_tm);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
if (!ret) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_SHORT_MEMORY_BUFFER;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
static int
|
|
Packit |
aea12f |
gtime_to_generalTime(time_t gtime, char *str_time, size_t str_time_size)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
size_t ret;
|
|
Packit |
aea12f |
struct tm _tm;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (gtime == (time_t)-1
|
|
Packit |
aea12f |
#if SIZEOF_LONG == 8
|
|
Packit |
aea12f |
|| gtime >= 253402210800
|
|
Packit |
aea12f |
#endif
|
|
Packit |
aea12f |
) {
|
|
Packit |
aea12f |
snprintf(str_time, str_time_size, "99991231235959Z");
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!gmtime_r(>ime, &_tm)) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INTERNAL_ERROR;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = strftime(str_time, str_time_size, "%Y%m%d%H%M%SZ", &_tm);
|
|
Packit |
aea12f |
if (!ret) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_SHORT_MEMORY_BUFFER;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Extracts the time in time_t from the ASN1_TYPE given. When should
|
|
Packit |
aea12f |
* be something like "tbsCertList.thisUpdate".
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
#define MAX_TIME 64
|
|
Packit |
aea12f |
time_t _gnutls_x509_get_time(ASN1_TYPE c2, const char *where, int force_general)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
char ttime[MAX_TIME];
|
|
Packit |
aea12f |
char name[128];
|
|
Packit |
aea12f |
time_t c_time = (time_t) - 1;
|
|
Packit |
aea12f |
int len, result;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
len = sizeof(ttime) - 1;
|
|
Packit |
aea12f |
result = asn1_read_value(c2, where, ttime, &len;;
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return (time_t) (-1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (force_general != 0) {
|
|
Packit |
aea12f |
c_time = _gnutls_x509_generalTime2gtime(ttime);
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
_gnutls_str_cpy(name, sizeof(name), where);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* choice */
|
|
Packit |
aea12f |
if (strcmp(ttime, "generalTime") == 0) {
|
|
Packit |
aea12f |
if (name[0] == 0)
|
|
Packit |
aea12f |
_gnutls_str_cpy(name, sizeof(name),
|
|
Packit |
aea12f |
"generalTime");
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
_gnutls_str_cat(name, sizeof(name),
|
|
Packit |
aea12f |
".generalTime");
|
|
Packit |
aea12f |
len = sizeof(ttime) - 1;
|
|
Packit |
aea12f |
result = asn1_read_value(c2, name, ttime, &len;;
|
|
Packit |
aea12f |
if (result == ASN1_SUCCESS)
|
|
Packit |
aea12f |
c_time =
|
|
Packit |
aea12f |
_gnutls_x509_generalTime2gtime(ttime);
|
|
Packit |
aea12f |
} else { /* UTCTIME */
|
|
Packit |
aea12f |
if (name[0] == 0)
|
|
Packit |
aea12f |
_gnutls_str_cpy(name, sizeof(name), "utcTime");
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
_gnutls_str_cat(name, sizeof(name), ".utcTime");
|
|
Packit |
aea12f |
len = sizeof(ttime) - 1;
|
|
Packit |
aea12f |
result = asn1_read_value(c2, name, ttime, &len;;
|
|
Packit |
aea12f |
if (result == ASN1_SUCCESS)
|
|
Packit |
aea12f |
c_time = _gnutls_utcTime2gtime(ttime);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* We cannot handle dates after 2031 in 32 bit machines.
|
|
Packit |
aea12f |
* a time_t of 64bits has to be used.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return (time_t) (-1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return c_time;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Sets the time in time_t in the ASN1_TYPE given. Where should
|
|
Packit |
aea12f |
* be something like "tbsCertList.thisUpdate".
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_x509_set_time(ASN1_TYPE c2, const char *where, time_t tim,
|
|
Packit |
aea12f |
int force_general)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
char str_time[MAX_TIME];
|
|
Packit |
aea12f |
char name[128];
|
|
Packit |
aea12f |
int result, len;
|
|
Packit |
aea12f |
unsigned tag;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (force_general != 0) {
|
|
Packit |
aea12f |
result =
|
|
Packit |
aea12f |
gtime_to_generalTime(tim, str_time, sizeof(str_time));
|
|
Packit |
aea12f |
if (result < 0)
|
|
Packit |
aea12f |
return gnutls_assert_val(result);
|
|
Packit |
aea12f |
len = strlen(str_time);
|
|
Packit |
aea12f |
result = asn1_write_value(c2, where, str_time, len);
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS)
|
|
Packit |
aea12f |
return gnutls_assert_val(_gnutls_asn2err(result));
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = gtime_to_suitable_time(tim, str_time, sizeof(str_time), &tag;;
|
|
Packit |
aea12f |
if (result < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return result;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_str_cpy(name, sizeof(name), where);
|
|
Packit |
aea12f |
if (tag == ASN1_TAG_UTCTime) {
|
|
Packit |
aea12f |
if ((result = asn1_write_value(c2, where, "utcTime", 1)) < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
_gnutls_str_cat(name, sizeof(name), ".utcTime");
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
if ((result = asn1_write_value(c2, where, "generalTime", 1)) < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
_gnutls_str_cat(name, sizeof(name), ".generalTime");
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
len = strlen(str_time);
|
|
Packit |
aea12f |
result = asn1_write_value(c2, name, str_time, len);
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* This will set a DER encoded Time element. To be used in fields
|
|
Packit |
aea12f |
* which are of the ANY.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_x509_set_raw_time(ASN1_TYPE c2, const char *where, time_t tim)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
char str_time[MAX_TIME];
|
|
Packit |
aea12f |
uint8_t buf[128];
|
|
Packit |
aea12f |
int result, len, der_len;
|
|
Packit |
aea12f |
unsigned tag;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result =
|
|
Packit |
aea12f |
gtime_to_suitable_time(tim, str_time, sizeof(str_time), &tag;;
|
|
Packit |
aea12f |
if (result < 0)
|
|
Packit |
aea12f |
return gnutls_assert_val(result);
|
|
Packit |
aea12f |
len = strlen(str_time);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
buf[0] = tag;
|
|
Packit |
aea12f |
asn1_length_der(len, buf+1, &der_len);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if ((unsigned)len > sizeof(buf)-der_len-1) {
|
|
Packit |
aea12f |
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
memcpy(buf+1+der_len, str_time, len);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = asn1_write_value(c2, where, buf, len+1+der_len);
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS)
|
|
Packit |
aea12f |
return gnutls_assert_val(_gnutls_asn2err(result));
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|