diff --git a/tools/itscertgen/checker/certinfo.c b/tools/itscertgen/checker/certinfo.c index 281c0fdb882b18df9a279244f1228335f6f56170..ad1fb8de29fb97cb999da770c5c7fc2f20771e3c 100644 --- a/tools/itscertgen/checker/certinfo.c +++ b/tools/itscertgen/checker/certinfo.c @@ -49,7 +49,8 @@ typedef enum { si_digest, si_certificate, si_certificate_chain, - si_digest_with_other_algorithm + si_digest_with_other_algorithm, + si_other } SignerInfoType; typedef enum { @@ -117,7 +118,8 @@ static const char * _signer_types[] = { "self", "digest", "certificate", - "chain", + "certificate_chain", + "other_digest", "other", }; @@ -252,19 +254,34 @@ int main(int argc, char ** argv) cxml_handler_add_default_entities(NULL); - if (*p > 1){ - fprintf(stderr, "Unsupported signer type: %s\n", ENUMSTRING(*p, _signer_types)); - return -1; - } fprintf(stdout, "\t\n"); + } + else{ + fprintf(stdout, ">\n"); + if (*p == si_certificate_chain || *p >= si_other){ + const char * b = ++p; + length = (uint32_t)cintx_read(&p, e, NULL); + print_x(stdout, b, length); + p += length; + } + else{ + fprintf(stderr, "Unsupported signer type: %d\n", ENUMSTRING(*p, _signer_types)); + return -1; + } + fprintf(stdout, "\t\n"); } - fprintf(stdout, "/>\n"); - p++; + const SubjectInfo * si = (const SubjectInfo *)p; if (si->subject_type > crl_signer){ fprintf(stderr, "Unsupported subject type: %d\n", si->subject_type); @@ -736,6 +753,15 @@ static int print_validity(const char ** pp, const char * e) } } break; + default: + { + fprintf(stdout, "\t\t\t\n", rtype); + int size = (int)cintx_read(&p, e, &rc); + print_x(stdout, p, size); p += size; + + fprintf(stdout, "\n\t\t\t\n"); + } + break; } } fprintf(stdout, "\t\t\n"); diff --git a/tools/itscertgen/checker/itscertverify.vcxproj b/tools/itscertgen/checker/itscertverify.vcxproj index 96b2d8a9bbc4ce61fc71223b2c3327e5ca8d7347..b9d248dd876c5b558792c2e1134938e8e4ba3d09 100644 --- a/tools/itscertgen/checker/itscertverify.vcxproj +++ b/tools/itscertgen/checker/itscertverify.vcxproj @@ -36,14 +36,14 @@ Application true v120 - Unicode + MultiByte Application false v120 true - Unicode + MultiByte @@ -72,12 +72,12 @@ Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - C:\OpenSSL-Win32\include;.. + C:\OpenSSL\Win32\include;.. Console true - C:\OpenSSL-Win32\lib\VC\static + C:\OpenSSL\Win32\lib\VC\static libeay32MDd.lib;ssleay32MDd.lib;%(AdditionalDependencies) @@ -90,14 +90,14 @@ true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - C:\OpenSSL-Win32\include;.. + C:\OpenSSL\Win32\include;.. Console true true true - C:\OpenSSL-Win32\lib\VC\static + C:\OpenSSL\Win32\lib\VC\static diff --git a/tools/itscertgen/checker/mkgmtime.c b/tools/itscertgen/checker/mkgmtime.c new file mode 100644 index 0000000000000000000000000000000000000000..d72c43ea8635f357c6b4f0800ea9b7a2d4471b2a --- /dev/null +++ b/tools/itscertgen/checker/mkgmtime.c @@ -0,0 +1,360 @@ +// Found in DeSmuME +// Alexis modified it a tad bit so it would compile as C (opposed to C++) + +/* lib/mkgmtime.c + + Copyright (C) 2010 DeSmuME team + + This file is part of DeSmuME + + DeSmuME is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DeSmuME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DeSmuME; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +//Taken from newlib 1.18.0 which is licensed under GPL 2 and modified for desmume + +/* + * mktime.c + * Original Author: G. Haley + * + * Converts the broken-down time, expressed as local time, in the structure + * pointed to by tim_p into a calendar time value. The original values of the + * tm_wday and tm_yday fields of the structure are ignored, and the original + * values of the other fields have no restrictions. On successful completion + * the fields of the structure are set to represent the specified calendar + * time. Returns the specified calendar time. If the calendar time can not be + * represented, returns the value (time_t) -1. + * + * Modifications: Fixed tm_isdst usage - 27 August 2008 Craig Howland. + */ + +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include +#include "mkgmtime.h" + +#define _SEC_IN_MINUTE 60L +#define _SEC_IN_HOUR 3600L +#define _SEC_IN_DAY 86400L + +static const int DAYS_IN_MONTH[12] = +{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +#define _DAYS_IN_MONTH(x) ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x]) + +static const int _DAYS_BEFORE_MONTH[12] = +{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + +#define _ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || (((y)+1900) % 400) == 0)) +#define _DAYS_IN_YEAR(year) (_ISLEAP(year) ? 366 : 365) + +static void validate_structure(struct tm *tim_p) +{ + div_t res; + int days_in_feb = 28; + + /* calculate time & date to account for out of range values */ + if (tim_p->tm_sec < 0 || tim_p->tm_sec > 59) + { + res = div (tim_p->tm_sec, 60); + tim_p->tm_min += res.quot; + if ((tim_p->tm_sec = res.rem) < 0) + { + tim_p->tm_sec += 60; + --tim_p->tm_min; + } + } + + if (tim_p->tm_min < 0 || tim_p->tm_min > 59) + { + res = div (tim_p->tm_min, 60); + tim_p->tm_hour += res.quot; + if ((tim_p->tm_min = res.rem) < 0) + { + tim_p->tm_min += 60; + --tim_p->tm_hour; + } + } + + if (tim_p->tm_hour < 0 || tim_p->tm_hour > 23) + { + res = div (tim_p->tm_hour, 24); + tim_p->tm_mday += res.quot; + if ((tim_p->tm_hour = res.rem) < 0) + { + tim_p->tm_hour += 24; + --tim_p->tm_mday; + } + } + + if (tim_p->tm_mon > 11) + { + res = div (tim_p->tm_mon, 12); + tim_p->tm_year += res.quot; + if ((tim_p->tm_mon = res.rem) < 0) + { + tim_p->tm_mon += 12; + --tim_p->tm_year; + } + } + + if (_DAYS_IN_YEAR (tim_p->tm_year) == 366) + days_in_feb = 29; + + if (tim_p->tm_mday <= 0) + { + while (tim_p->tm_mday <= 0) + { + if (--tim_p->tm_mon == -1) + { + tim_p->tm_year--; + tim_p->tm_mon = 11; + days_in_feb = + ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? + 29 : 28); + } + tim_p->tm_mday += _DAYS_IN_MONTH (tim_p->tm_mon); + } + } + else + { + while (tim_p->tm_mday > _DAYS_IN_MONTH (tim_p->tm_mon)) + { + tim_p->tm_mday -= _DAYS_IN_MONTH (tim_p->tm_mon); + if (++tim_p->tm_mon == 12) + { + tim_p->tm_year++; + tim_p->tm_mon = 0; + days_in_feb = + ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? + 29 : 28); + } + } + } +} + + +static const unsigned long _leap_moments[] = { + 1136073600, + 1230768000, + 1341100800, + 1435708800, +}; + +time_t addleapseconds(time_t t) +{ + int i; + for (i = 0; i < sizeof(_leap_moments) / sizeof(_leap_moments[0]); i++){ + if (t < _leap_moments[i]) break; + } + return t + i; +} + +time_t removeleapseconds(time_t t) +{ + int i; + for (i = 0; i < sizeof(_leap_moments) / sizeof(_leap_moments[0]); i++){ + if (t < _leap_moments[i]) break; + t--; + } + return t; +} + +#define ITS_UTC_EPOCH 1072915200 + +unsigned long mkitstime32(struct tm *tim_p) +{ + time_t ret = mktaitime(tim_p); + if (ret > 0){ + ret -= ITS_UTC_EPOCH; + } + return (unsigned long)ret; +} + +unsigned long long mkitstime64(struct tm *tim_p) +{ + unsigned long long ret = mktaitime64(tim_p); + if (ret > 0){ + ret -= ((unsigned long long)ITS_UTC_EPOCH) * 1000; + } + return ret; +} + +time_t mktaitime(struct tm *tim_p) +{ + time_t t = mkgmtime(tim_p); + if (t >= 0){ + t = addleapseconds(t); + } + return t; +} + +unsigned long long mktaitime64(struct tm *tim_p) +{ + time_t t = mkgmtime(tim_p); + if (t >= 0){ + t = addleapseconds(t); + } + return ((unsigned long long)t)*1000; +} + +unsigned long unix2itstime32(time_t t) +{ + return ((unsigned long) addleapseconds(t)) - ITS_UTC_EPOCH; +} + +unsigned long long unix2itstime64(time_t t) +{ + return (((unsigned long long) addleapseconds(t)) - ITS_UTC_EPOCH) * 1000; +} + +static char _datebuf[8][16]; +static int _datebufidx = 0; +const char * strgmtdate(time_t t) +{ + struct tm * tm; + char * b = _datebuf[_datebufidx]; + _datebufidx = (_datebufidx + 1) & 7; + + tm = gmtime(&t); + sprintf(b, "%u-%02u-%02u", 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday); + return b; +} + +const char * strtaidate(time_t t) +{ + return strgmtdate(removeleapseconds(t)); +} + +const char * stritsdate32(time_t t) +{ + return strtaidate(t + ITS_UTC_EPOCH); +} + +time_t mkgmtime(struct tm *tim_p) +{ + time_t tim = 0; + long days = 0; + int year, isdst, tm_isdst; + + /* validate structure */ + validate_structure (tim_p); + + /* compute hours, minutes, seconds */ + tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) + + (tim_p->tm_hour * _SEC_IN_HOUR); + + /* compute days in year */ + days += tim_p->tm_mday - 1; + days += _DAYS_BEFORE_MONTH[tim_p->tm_mon]; + if (tim_p->tm_mon > 1 && _DAYS_IN_YEAR (tim_p->tm_year) == 366) + days++; + + /* compute day of the year */ + tim_p->tm_yday = days; + + if (tim_p->tm_year > 10000 + || tim_p->tm_year < -10000) + { + return (time_t) -1; + } + + /* compute days in other years */ + if (tim_p->tm_year > 70) + { + for (year = 70; year < tim_p->tm_year; year++) + days += _DAYS_IN_YEAR (year); + } + else if (tim_p->tm_year < 70) + { + for (year = 69; year > tim_p->tm_year; year--) + days -= _DAYS_IN_YEAR (year); + days -= _DAYS_IN_YEAR (year); + } + + /* compute day of the week */ + if ((tim_p->tm_wday = (days + 4) % 7) < 0) + tim_p->tm_wday += 7; + + /* compute total seconds */ + tim += (days * _SEC_IN_DAY); + + /* Convert user positive into 1 */ + tm_isdst = tim_p->tm_isdst > 0 ? 1 : tim_p->tm_isdst; + isdst = tm_isdst; + + //screw this! + + // if (_daylight) + // { + // int y = tim_p->tm_year + YEAR_BASE; + // if (y == tz->__tzyear || __tzcalc_limits (y)) + //{ + // /* calculate start of dst in dst local time and + // start of std in both std local time and dst local time */ + // time_t startdst_dst = tz->__tzrule[0].change + // - (time_t) tz->__tzrule[1].offset; + // time_t startstd_dst = tz->__tzrule[1].change + // - (time_t) tz->__tzrule[1].offset; + // time_t startstd_std = tz->__tzrule[1].change + // - (time_t) tz->__tzrule[0].offset; + // /* if the time is in the overlap between dst and std local times */ + // if (tim >= startstd_std && tim < startstd_dst) + // ; /* we let user decide or leave as -1 */ + // else + // { + // isdst = (tz->__tznorth + // ? (tim >= startdst_dst && tim < startstd_std) + // : (tim >= startdst_dst || tim < startstd_std)); + // /* if user committed and was wrong, perform correction, but not + // * if the user has given a negative value (which + // * asks mktime() to determine if DST is in effect or not) */ + // if (tm_isdst >= 0 && (isdst ^ tm_isdst) == 1) + // { + // /* we either subtract or add the difference between + // time zone offsets, depending on which way the user got it + // wrong. The diff is typically one hour, or 3600 seconds, + // and should fit in a 16-bit int, even though offset + // is a long to accomodate 12 hours. */ + // int diff = (int) (tz->__tzrule[0].offset + // - tz->__tzrule[1].offset); + // if (!isdst) + // diff = -diff; + // tim_p->tm_sec += diff; + // validate_structure (tim_p); + // tim += diff; /* we also need to correct our current time calculation */ + // } + // } + //} + // } + + //screw this also + /* add appropriate offset to put time in gmt format */ + //if (isdst == 1) + // tim += (time_t) tz->__tzrule[1].offset; + //else /* otherwise assume std time */ + // tim += (time_t) tz->__tzrule[0].offset; + + //and screw this too + /* reset isdst flag to what we have calculated */ + tim_p->tm_isdst = isdst; + + return tim; +} + +// vim: ts=2 sw=2 et diff --git a/tools/itscertgen/checker/mkgmtime.h b/tools/itscertgen/checker/mkgmtime.h new file mode 100644 index 0000000000000000000000000000000000000000..f17d981968f005780d26bf27bea4e2702243264f --- /dev/null +++ b/tools/itscertgen/checker/mkgmtime.h @@ -0,0 +1,51 @@ +/* lib/mkgmtime.h + + Copyright (C) 2010 DeSmuME team + + This file is part of DeSmuME + + DeSmuME is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DeSmuME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DeSmuME; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef _MKGMTIME_H_ +#define _MKGMTIME_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + extern time_t mkgmtime(struct tm *tim_p); + extern time_t mktaitime(struct tm *tim_p); + extern time_t addleapseconds(time_t t); + + #define mktaitime32(X) ((unsigned long)mktaitime(X)) + extern unsigned long mkitstime32(struct tm *tim_p); + extern unsigned long unix2itstime32(time_t t); + + extern unsigned long long mktaitime64(struct tm *tim_p); + extern unsigned long long mkitstime64(struct tm *tim_p); + extern unsigned long long unix2itstime64(time_t t); + + extern const char * stritsdate32(time_t t); + extern const char * strtaidate(time_t t); + extern const char * strgmtdate(time_t t); + +#ifdef __cplusplus +} +#endif + +#endif +//_MKGMTIME_H_ diff --git a/tools/itscertgen/cshared/cstr.c b/tools/itscertgen/cshared/cstr.c index 024822cdb9eb41e0684abb497d1caa07207723ac..81fcde7835ce8f9596be6e631ef9d7b1bf8923b3 100644 --- a/tools/itscertgen/cshared/cstr.c +++ b/tools/itscertgen/cshared/cstr.c @@ -35,6 +35,22 @@ int cstrequal(const char * s1, const char * s2) return (s1 == s2) || (s1 && s2 && 0 == strcmp(s1, s2)); } +char* cstrisprefix(const char * str, const char * prefix) +{ + int len; + if (str == prefix){ + return (char*)(str ? str + strlen(str) : NULL); + } + if (str == NULL || prefix == NULL || 0 == *prefix){ + return (char*)str; + } + len = strlen(prefix); + if (0 == memcmp(str, prefix, len)){ + return ((char*)str) + len; + } + return NULL; +} + char * cstrcpy(char * dst, const char * src) { if(!dst) return (char*)0; @@ -52,22 +68,37 @@ char * cstrcpy(char * dst, const char * src) /* copy up to maxsize characters from src to dst and return pointer to the next byte after the end */ char * cstrncpy(char * dst, int maxsize, const char * src) { - if(!dst) return (char*)0; + if (!dst) return (char*)0; unsigned int ms = maxsize; unsigned int len = 0; - if(src && ms > 0){ + if (src && ms > 0){ len = strlen(src); if (len > ms){ len = ms; } - if(len){ + if (len){ memcpy(dst, src, len); } } - dst[len]=0; + dst[len] = 0; return dst + len; } +char * cmemcpy(char * dst, const char * src, int length) +{ + if (!dst) return (char*)0; + if (length){ + if (src){ + memcpy(dst, src, length); + } + else{ + memset(dst, 0, length); + } + } + dst[length] = 0; + return dst + length; +} + /* copy up to maxsize characters from src to dst and return pointer to the next byte after the end */ char * cvstrncpy(char * dst, int maxsize, const char * ptr, ...) { diff --git a/tools/itscertgen/cshared/cstr.h b/tools/itscertgen/cshared/cstr.h index adf58b6926d6fc1bc8ec141cd7b33774d118b2a4..430858ec04797919c161af4be1a510bb7b088f1d 100644 --- a/tools/itscertgen/cshared/cstr.h +++ b/tools/itscertgen/cshared/cstr.h @@ -17,9 +17,11 @@ extern "C" { #define cisspace(X) isspace((int)(X)) #define cisdigit(X) isdigit((int)(X)) +#define cisalnum(X) isalnum((int)(X)) int cstrlen(const char * str); int cstrnlen(const char * str, int maxsize); +/* return pointer to the end of line*/ char* cstrend(const char * str); /* copy src to dst and return pointer to the next byte after the end */ char * cstrcpy(char * dst, const char * src); @@ -27,10 +29,15 @@ char * cstrcpy(char * dst, const char * src); /* copy up to maxsize characters from src to dst and return pointer to the next byte after the end */ char * cstrncpy(char * dst, int maxsize, const char * src); +/* copy length characters from src to dst or fill dst by zero if src is null and return pointer to the next byte after the end*/ +char * cmemcpy(char * dst, const char * src, int length); + /* copy up to maxsize characters from parameters to dst and return pointer to the next byte after the end */ char * cvstrncpy(char * dst, int maxsize, const char * ptr, ...); +/* return nonzero if strings are equals*/ int cstrequal(const char * s1, const char * s2); +char* cstrisprefix(const char * str, const char * prefix); /* allocate copy of the str */ char * cstralloc(int size); diff --git a/tools/itscertgen/cxml/cxml.vcxproj b/tools/itscertgen/cxml/cxml.vcxproj index 061a55db92101eab185a92130bb9e09b1a26dc2a..abddf8fd3834bae470b278d98b32546176d607d6 100644 --- a/tools/itscertgen/cxml/cxml.vcxproj +++ b/tools/itscertgen/cxml/cxml.vcxproj @@ -31,14 +31,14 @@ StaticLibrary true v120 - Unicode + MultiByte StaticLibrary false v120 true - Unicode + MultiByte diff --git a/tools/itscertgen/generator/certgen.c b/tools/itscertgen/generator/certgen.c index 7297e6062f41d92a034fd8976e7618d0ddc11785..5f811f4d5aec4d5ed2c83b525b9d16f9d2976436 100644 --- a/tools/itscertgen/generator/certgen.c +++ b/tools/itscertgen/generator/certgen.c @@ -40,12 +40,22 @@ struct bookmark_t { char * ptr; }; +typedef enum { + si_self, + si_digest, + si_certificate, + si_certificate_chain, + si_digest_with_other_algorithm, + si_other +} SignerInfoType; + typedef struct cert_cxml_handler_t { cxml_handler_t h; unsigned int subject_type; int signer_type; const char * signer; + const char * signer_digest; int vr_type; int sa_type; void * verificationKey; @@ -152,13 +162,16 @@ static int region_none_tag (cxml_handler_t* const h, cxml_tag_t * const tag); static int region_circle_tag (cxml_handler_t* const h, cxml_tag_t * const tag); static int region_rectangle_tag (cxml_handler_t* const h, cxml_tag_t * const tag); static int region_polygon_tag (cxml_handler_t* const h, cxml_tag_t * const tag); -static int region_id_tag (cxml_handler_t* const h, cxml_tag_t * const tag); +static int region_id_tag(cxml_handler_t* const h, cxml_tag_t * const tag); +static int region_region_tag(cxml_handler_t* const h, cxml_tag_t * const tag); +static int region_region_text(cxml_handler_t* const h, char * const text, int length); static const cxml_taghandler_t h_restriction[] = { - {"none", region_none_tag, NULL, NULL }, - {"circle", region_circle_tag, NULL, NULL }, - {"rectangle", region_rectangle_tag, NULL, h_location_list }, - {"polygon", region_polygon_tag, NULL, h_location_list }, - {"id", region_id_tag, NULL, NULL }, + {"region", region_region_tag, region_region_text, NULL }, + {"none", region_none_tag, NULL, NULL }, + {"circle", region_circle_tag, NULL, NULL }, + {"rectangle", region_rectangle_tag, NULL, h_location_list }, + {"polygon", region_polygon_tag, NULL, h_location_list }, + {"id", region_id_tag, NULL, NULL }, {NULL} }; @@ -277,7 +290,7 @@ static int _refPoint_option(const copt_t * opt, const char * option, const copt_ char * e; long double lat, lon; lat = strtold(value->v_str, &e); - if (*e == ':'){ + if (*e == ':' || *e == ','){ lon = strtold(e + 1, &e); if (*e == 0){ if (lat <= 90.0 && lat >= -90.0) lat *= 10000000.0; // degree @@ -393,6 +406,9 @@ static int root_certificate_tag (cxml_handler_t* const _h, cxml_tag_t * const ta if(_certName == NULL){ _certName = _profileName; } + else if (!cstrequal(_certName, _profileName)){ + fprintf(stderr, "WARNING: %s.xml: profile name differs from certificate name '%s'\n", _profileName, _certName); + } } h->ptr = h->buf = malloc(4096); h->end = h->buf + 4096; @@ -480,7 +496,8 @@ static const char * _signer_types [] = { "self", "digest", "certificate", - "chain", + "certificate_chain", + "other_digest", "other", }; @@ -520,83 +537,159 @@ static size_t load_certificate(const char * path, char * ptr, const char * e) return size; } +static const char * _pk_algorithms[] = { + [0] = "ecdsa_nistp256_with_sha256", + [1] = "ecies_nistp256", +}; + +static const char * _sym_algorithms[] = { + [0] = "aes_128_ccm", +}; +static const char * _point_types[] = { + [0] = "x_coordinate_only", + [1] = "compressed", + [2] = "compressed_y0", + [3] = "compressed_y1", + [4] = "uncompressed" +}; + static int certificate_signer_tag (cxml_handler_t* const _h, cxml_tag_t * const tag) { int rc = 0; + const char * v; // write signer info cert_cxml_handler_t * h = (cert_cxml_handler_t *)_h; if (cxml_tag_is_open(tag)){ - h->signer_type = 1; // digest by default - const char * v = cxml_tag_attr_value(tag, "type"); + h->signer_type = si_digest; // digest by default + v = cxml_tag_attr_value(tag, "type"); if(v){ h->signer_type = STR2ENUM(_signer_types, v); - if(h->signer_type <0){ + if (h->signer_type <0){ fprintf(stderr, "%s: Unknown signer type\n", v); return -1; } } cint8_write(h->signer_type, &h->ptr, h->end, &rc); - if (h->signer_type > 0){ + if (h->signer_type > si_self){ if (_signerName){ h->signer = _signerName; } else{ - v = cxml_tag_attr_value(tag, "name"); - if (v == NULL){ - fprintf(stderr, "%s: Signer name shall be provided\n", v); - return -1; + if (h->signer_type == si_digest || h->signer_type == si_digest_with_other_algorithm){ + h->signer_digest = cxml_tag_attr_value(tag, "digest"); + if (h->signer_type == si_digest_with_other_algorithm){ + int alg; + v = cxml_tag_attr_value(tag, "algorithm"); + if (v == NULL) { + fprintf(stderr, "Signing algorithm shall be provided\n"); + return -1; + } + alg = STR2ENUM(_pk_algorithms, v); + if (alg < 0){ + fprintf(stderr, "%s: Unknown public key algorithm\n", v); + return -1; + } + cint8_write(alg, &h->ptr, h->end, &rc); + } + } + if (h->signer_digest == NULL){ + v = cxml_tag_attr_value(tag, "name"); + if (v == NULL){ + fprintf(stderr, "%s: Signer name or digest shall be provided\n", v); + return -1; + } + h->signer = v; } - h->signer = v; + } + if (h->signer_type == si_certificate_chain || + h->signer_type >= si_other){ + bookmark_position(h, tag); } } }else{ // write signer info - if (h->signer_type > 0){ - if (h->signer_type > 2){ - fprintf(stderr, "%d: signer method unsupported\n", h->signer_type); - rc = -1; - } - else{ - // load signer certificate - int plen = strlen(_searchPath) + strlen(h->signer); - char * path = malloc(plen + 16); - cvstrncpy(path, plen + 16, _searchPath, "/", h->signer, ".crt", NULL); - size_t size = load_certificate(path, h->ptr, h->end); - if (size < 0){ - fprintf(stderr, "%s: signer certificate not found or error\n", h->signer); - rc = -1; + if (h->signer_type > si_self){ + if (h->signer_type < si_other) { + if (h->signer_digest){ + int len = strlen(h->signer_digest); + v = cstr_hex2bin(h->ptr, h->end - h->ptr, h->signer_digest, len); + if (v == NULL){ + fprintf(stderr, "%s: no more space to write digest of size %d bytes\n", v, len); + return -1; + } } else{ - if (h->signer_type == 1){ // digest - char hash[sha256_hash_size]; - // change eccpoint type of the signature to x_coordinate_only(0) - // to follow canonical encoding - h->ptr[size-65] = 0; - sha256_calculate(hash, h->ptr, size); + char * path, *cname; + int plen; + cname = (char*)h->signer; + while (*cname){ + char * se = strchr(cname, ' '); + if (se){ + *se = 0; + while (cisspace(*se))se++; + } + else se = cstrend(cname); + h->signer = cname; + + // load signer certificate + plen = strlen(_searchPath) + (se - cname); + path = malloc(plen + 16); + cvstrncpy(path, plen + 16, _searchPath, "/", cname, ".crt", NULL); + size_t size = load_certificate(path, h->ptr, h->end); + if (size < 0){ + fprintf(stderr, "%s: signer certificate not found or error\n", h->signer); + rc = -1; + } + else{ + // digests + if (h->signer_type == si_digest || h->signer_type == si_digest_with_other_algorithm){ + char hash[sha256_hash_size]; + // change eccpoint type of the signature to x_coordinate_only(0) + // to follow canonical encoding + h->ptr[size - 65] = 0; + sha256_calculate(hash, h->ptr, size); #ifdef DEBUG_DATA - fprintf(stderr, "HASH (%s): ", h->signer); - print_x(stderr, hash, sha256_hash_size); - fprintf(stderr, "\n"); - fprintf(stderr, "DIGEST (%s): ", h->signer); - print_x(stderr, &hash[sha256_hash_size - 8], 8); - fprintf(stderr, "\n"); + fprintf(stderr, "HASH (%s): ", h->signer); + print_x(stderr, hash, sha256_hash_size); + fprintf(stderr, "\n"); + fprintf(stderr, "DIGEST (%s): ", h->signer); + print_x(stderr, &hash[sha256_hash_size - 8], 8); + fprintf(stderr, "\n"); #endif - cbuf_write(hash + sha256_hash_size - 8, 8, &h->ptr, h->end, &rc); - } - else {// certificate - h->ptr += size; + cbuf_write(hash + sha256_hash_size - 8, 8, &h->ptr, h->end, &rc); + } + else {// certificate or chain + h->ptr += size; + if (h->signer_type == si_certificate_chain){ + cname = se; + continue; + } + } + } + // continue only if certificate chain + break; } + free(path); } - free(path); + } + if (h->signer_type == si_certificate_chain || h->signer_type >= si_other) { + apply_bookmark_size(h, tag); } } } return rc; } -static int certificate_signer_text(cxml_handler_t* const h, char * const text, int length) -{ return 0;} +static int certificate_signer_text(cxml_handler_t* const _h, char * const text, int length) +{ + int rc = 0; + cert_cxml_handler_t * h = (cert_cxml_handler_t *)_h; + if (h->signer_type >= si_other) { + cbuf_write(text, length, &h->ptr, h->end, &rc); + } + return rc; +} static const char * _subject_type [] = { "EC", "AT", "AA", "EA", "ROOT", "CRL" @@ -715,22 +808,6 @@ static int subject_attribute_tag (cxml_handler_t* const _h, cxml_tag_t * const t return rc; } -static const char * _pk_algorithms[] = { - [0] = "ecdsa_nistp256_with_sha256", - [1] = "ecies_nistp256", -}; - -static const char * _sym_algorithms[] = { - [0] = "aes_128_ccm", -}; -static const char * _point_types [] = { - [0] = "x_coordinate_only", - [1] = "compressed", - [2] = "compressed_y0", - [3] = "compressed_y1", - [4] = "uncompressed" -}; - static int attribute_public_key_tag(cxml_handler_t* const _h, cxml_tag_t * const tag) { int rc = 0; @@ -973,67 +1050,119 @@ static int certificate_validity_tag (cxml_handler_t* const _h, cxml_tag_t * cons return rc; } -static unsigned int _convert_time(const char * v) +static unsigned int _convert_diff_time(const char * v) +{ + unsigned int ret = 0; + const char * p = v; + char * e; + int mult = 1; + switch (*p){ + case '-': + mult = -1; + case '+': + p++; + } + + for (;;){ + unsigned int n; + n = strtoul(p, &e, 10); + if (n == ULONG_MAX) break; + if (cisalnum(*e)){ + switch (*e){ + case 'd': n *= 24; + case 'h': n *= 60; + case 'm': n *= 60; + case 's': e++; break; + default: + fprintf(stderr, "%s: Unknown time modificator: '%c'\n", p, *e); + return INT32_MIN; + } + } + else{ + // consider n as days + n *= 24 * 3600; + } + ret += n; + if (cisdigit(*e)){ + p = e; + continue; + } + break; + } + return ret * mult; +} + +static unsigned int _convert_time2(const char * v, unsigned int baseTime) { unsigned int ret; char * e; struct tm tm; // can be a difference from the base time point - if(*v == '-' || *v == '+'){ - const char * p; - if(_defaultTime == 0){ + if (*v == '-' || *v == '+'){ + if (baseTime == 0){ fprintf(stderr, "Default time must be set\n"); return 0; } - p = v+1; - ret = 0; - for(;;){ - unsigned int n; - n = strtoul(p, &e, 10); - if(n == ULONG_MAX) break; - switch(*e){ - case 'd': n *= 24; - case 'h': n *= 60; - case 'm': n *= 60; - case 's': e++; - } - ret += n; - if(cisdigit(*e)){ - p = e; - continue; - } - break; - } - if(*v == '-'){ - ret = _defaultTime - ret; - }else{ - ret = _defaultTime + ret; - } + ret = _convert_diff_time(v); + if (ret == INT32_MIN) + return 0; + ret = baseTime + ret; } else{ // next try load as integer seconds since epoch ret = strtoul(v, &e, 0); if (ret == ULONG_MAX || *e){ ret = 0; - //next try to convert ISO text representation memset(&tm, 0, sizeof(tm)); - if (3 == sscanf(v, "%d-%d-%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday)){ + // check predefined values + if ((e = cstrisprefix(v, "today"))){ + time_t t; + struct tm * ptm; + time(&t); ptm = gmtime(&t); + tm.tm_year = ptm->tm_year; tm.tm_mon = ptm->tm_mon; tm.tm_mday = ptm->tm_mday; + } + else if ((e = cstrisprefix(v, "ybegin"))){ + time_t t; + struct tm * ptm; + time(&t); ptm = gmtime(&t); + tm.tm_year = ptm->tm_year; tm.tm_mon = 0; tm.tm_mday = 1; + } + else if ((e = cstrisprefix(v, "yend"))){ + time_t t; + struct tm * ptm; + time(&t); ptm = gmtime(&t); + tm.tm_year = ptm->tm_year+1; tm.tm_mon = 0; tm.tm_mday = 1; + } + //next try to convert ISO text representation + else if (3 == sscanf(v, "%d-%d-%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday)){ tm.tm_mon--; // STARTED FROM 0 - if (tm.tm_year > 500){ + if (tm.tm_year > 500) tm.tm_year -= 1900; - } - ret = mkitstime32(&tm); - if (ret == (time_t)-1) { - fprintf(stderr, "%s: Date format specification error. Use YYY-MM-DD\n", v); - ret = 0; - } + e = (char*)v; // to prevent next check for '-/+' + } + else{ + fprintf(stderr, "%s: Date format specification error. Use YYY-MM-DD or today+/-NNNd\n", v); + return 0; + } + ret = mkitstime32(&tm); + if (ret == (time_t)-1) { + fprintf(stderr, "%s: Date format specification error. Use YYY-MM-DD or today+/-NNNd\n", v); + ret = 0; + } + if (*e == '-' || *e == '+'){ + ret = _convert_time2(e, ret); } } } return ret; } +static unsigned int _convert_time(const char * v) +{ + return _convert_time2(v, _defaultTime); +} + static int validity_restriction_tag (cxml_handler_t* const _h, cxml_tag_t * const tag) { int rc = 0; @@ -1084,7 +1213,7 @@ static int validity_restriction_tag (cxml_handler_t* const _h, cxml_tag_t * cons case 2: /* time_start_and_duration */ nTime = _convert_time(start); cint32_write(nTime, &h->ptr, h->end, &rc); - nTime = _convert_time(duration); + nTime = _convert_diff_time(duration); cint32_write(nTime, &h->ptr, h->end, &rc); break; case 3: /* region */ @@ -1177,13 +1306,18 @@ static int location_tag (cxml_handler_t* const _h, cxml_tag_t * const tag) { int rc = 0; if (cxml_tag_is_open(tag)){ - int32_t lat, lon; + int32_t lat, lon, absolute = 0; long double d; char * e; cert_cxml_handler_t * h = (cert_cxml_handler_t *)_h; - const char * v = cxml_tag_attr_value(tag, "latitude"); + + const char * v = cxml_tag_attr_value(tag, "mode"); + absolute = cstrequal(v, "absolute"); + + v = cxml_tag_attr_value(tag, "latitude"); + int relative = 1; if(v == NULL){ - fprintf(stderr, "ERROR: Latitude shall be specified for location.\n"); + fprintf(stderr, "ERROR: Latitude must be specified for location.\n"); return -1; } e = NULL; d = strtold(v, &e); @@ -1193,7 +1327,8 @@ static int location_tag (cxml_handler_t* const _h, cxml_tag_t * const tag) }else{ if (d <= 90.0 && d >= -90.0) d *= 10000000.0; // degree } - lat = (int32_t)floorl(d+_refLat); + if (!absolute) d += _refLat; + lat = (int32_t)floorl(d); v = cxml_tag_attr_value(tag, "longitude"); if(v == NULL){ @@ -1208,7 +1343,8 @@ static int location_tag (cxml_handler_t* const _h, cxml_tag_t * const tag) }else{ if (d <= 180.0 && d >= -180.0) d *= 10000000.0; // degree } - lon = (int32_t)floorl(d + _refLon); + if (!absolute) d += _refLon; + lon = (int32_t)floorl(d); cint32_write(lat, &h->ptr, h->end, &rc); cint32_write(lon, &h->ptr, h->end, &rc); @@ -1278,6 +1414,67 @@ static int region_id_tag (cxml_handler_t* const _h, cxml_tag_t * const tag) return rc; } +static const char * _region_types[] = { + [0] = "none", + [1] = "circle", + [2] = "rectangle", + [3] = "polygon", + [4] = "id" +}; +static cxml_tag_f* _region_type_handlers[] = { + [0] = region_none_tag, + [1] = region_circle_tag, + [2] = region_rectangle_tag, + [3] = region_polygon_tag, + [4] = region_id_tag +}; + +static int region_region_tag(cxml_handler_t* const _h, cxml_tag_t * const tag) +{ + int rc = 0; + cert_cxml_handler_t * h = (cert_cxml_handler_t *)_h; + if (cxml_tag_is_open(tag)){ + const char * v; + v = cxml_tag_attr_value(tag, "type"); + h->nTmpValue = STR2ENUM(_region_types, v); + if (h->nTmpValue < 0){ + fprintf(stderr, "ERROR: unknown region type: %s\n", v); + return -1; + } + } + if (h->nTmpValue < sizeof(_region_type_handlers) / sizeof(_region_type_handlers[0])){ + return _region_type_handlers[h->nTmpValue](_h, tag); + } + + if (cxml_tag_is_open(tag)){ + // region type + rc = cint8_write(h->nTmpValue, &h->ptr, h->end, NULL); + bookmark_position(h, tag); + } else{ + apply_bookmark_size(h, tag); + } + return rc; +} + +static int region_region_text(cxml_handler_t* const _h, char * const text, int length) +{ + cert_cxml_handler_t * h = (cert_cxml_handler_t *)_h; + char * end; + // try to treat it as hex + end = cstr_hex2bin(h->ptr, h->end - h->ptr, text, length); + if (end){ + h->ptr = end; + } + else{ + if (length > (h->end - h->ptr)){ + fprintf(stderr, "ERROR: region definition is tooooo big: %d bytes\n", length); + return -1; + } + h->ptr = cmemcpy(h->ptr, text, length); + } + return 0; +} + static const char * _signature_algorithms[] = { "ecdsa_nistp256_with_sha256", }; diff --git a/tools/itscertgen/generator/itscertgen.vcxproj b/tools/itscertgen/generator/itscertgen.vcxproj index 09a02f816206196abebebf92fb661e3b722c510d..0bf44d0e10e7982232acf08c4cc1a244cea2ebde 100644 --- a/tools/itscertgen/generator/itscertgen.vcxproj +++ b/tools/itscertgen/generator/itscertgen.vcxproj @@ -40,14 +40,14 @@ Application true v120 - Unicode + MultiByte Application false v120 true - Unicode + MultiByte @@ -74,12 +74,12 @@ Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - C:\OpenSSL-Win32\include;.. + C:\OpenSSL\Win32\include;.. Console true - C:\OpenSSL-Win32\lib\VC\static + C:\OpenSSL\Win32\lib\VC\static libeay32MDd.lib;ssleay32MDd.lib;%(AdditionalDependencies) @@ -92,12 +92,15 @@ true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + C:\OpenSSL\Win32\include;.. Console true true true + libeay32MDd.lib;ssleay32MDd.lib;%(AdditionalDependencies) + C:\OpenSSL\Win32\lib\VC\static diff --git a/tools/itscertgen/msgcheck/msgcheck.vcxproj b/tools/itscertgen/msgcheck/msgcheck.vcxproj index 430079db8774814b65cd5b61f7886c1f4d66c4ec..9a3baf803a9039efa3d4aa8cc5e640c4c4cab5fd 100644 --- a/tools/itscertgen/msgcheck/msgcheck.vcxproj +++ b/tools/itscertgen/msgcheck/msgcheck.vcxproj @@ -28,14 +28,14 @@ Application true v120 - Unicode + MultiByte Application false v120 true - Unicode + MultiByte