From f7cb199066dc45b96858f2923a82fab25e4aef25 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Wed, 29 Mar 2017 12:03:53 +0200 Subject: [PATCH 1/8] add test proposed by @karel-m --- testprof/rsa_test.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/testprof/rsa_test.c b/testprof/rsa_test.c index 8bc372f..55db842 100644 --- a/testprof/rsa_test.c +++ b/testprof/rsa_test.c @@ -46,6 +46,22 @@ static const unsigned char openssl_private_rsa[] = { 0x78, 0x18, 0x5a, 0x79, 0x3d, 0x2e, 0x8e, 0x7e, 0x86, 0x0a, 0xe6, 0xa8, 0x33, 0xc1, 0x04, 0x17, 0x4a, 0x9f, }; +static const unsigned char x509_public_rsa[] = + "MIICdTCCAd4CCQCYjCwz0l9JpjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJD\ + WjEPMA0GA1UECAwGTW9yYXZhMQ0wCwYDVQQHDARCcm5vMRAwDgYDVQQKDAdMVEMg\ + THRkMQ8wDQYDVQQLDAZDcnlwdG8xEjAQBgNVBAMMCVRlc3QgQ2VydDEYMBYGCSqG\ + SIb3DQEJARYJdGVzdEBjZXJ0MCAXDTE3MDMwOTIzNDMzOVoYDzIyOTAxMjIyMjM0\ + MzM5WjB+MQswCQYDVQQGEwJDWjEPMA0GA1UECAwGTW9yYXZhMQ0wCwYDVQQHDARC\ + cm5vMRAwDgYDVQQKDAdMVEMgTHRkMQ8wDQYDVQQLDAZDcnlwdG8xEjAQBgNVBAMM\ + CVRlc3QgQ2VydDEYMBYGCSqGSIb3DQEJARYJdGVzdEBjZXJ0MIGfMA0GCSqGSIb3\ + DQEBAQUAA4GNADCBiQKBgQDPmt5kitrIMyCp14MxGVSymoWnobd1M7aprIQks97b\ + fYUtlmXlP3KVJJ8oaMpP20QcPmASit0mpev/C17UiDhJKm5bvxI3R70Fa7zb8+7k\ + EY5BaHxhE9dCyIC+No/cCItPrKTidgzJY2xJWJPtzKrcJTsKYD+LVDrDTTHnlKRE\ + /QIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAApwWqupmmLGHeKOLFLcthQpAXXYep6T\ + 3S3e8X7fIG6TGhfvn5DHn+/V/C4184oOCwImI+VYRokdXdQ1AMGfVUomHJxsFPia\ + bv5Aw3hiKsIG3jigKHwmMScgkl3yn+8hLkx6thNbqQoa6Yyo20RqaEFBwlZ5G8lF\ + rZsdeO84SeCH"; + /* private keay - hexadecimal */ static char *hex_d = "C862B9EADE44531D5697D9979E1ACF301E0A8845862930A34D9F616573E0D6878FB6F306A382DC7CACFE9B289AAEFDFBFE2F0ED89704E3BB1FD1EC0DBAA3497F47AC8A44047E86B739423FAD1EB70EA551F440631EFDBDEA9F419FA8901D6F0A5A9513110D80AF5F64988A2C786865B02B8BA25387CAF16404ABF27BDB83C881"; static char *hex_dP = "6DEBC32D2EF05EA488310529008AD195299B83CF75DB31E37A27DE3A74300C764CD4502A402D39D99963A95D80AE53CA943F05231EF80504E1B835F217B3A089"; @@ -539,6 +555,19 @@ for (cnt = 0; cnt < len; ) { DOX(rsa_verify_hash_ex(p2, len2, p, 20, LTC_PKCS_1_V1_5, hash_idx, -1, &stat, &pubKey), "should succeed"); DOX(stat == 0?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, "should fail"); } + rsa_free(&key); + + /* try reading the public RSA key from a X509 certificate */ + len3 = sizeof(tmp); + DO(base64_decode(x509_public_rsa, sizeof(x509_public_rsa), tmp, &len3)); + DO(rsa_import_x509(tmp, len3, &key)); + len = sizeof(tmp); + DO(rsa_export(tmp, &len, PK_PUBLIC, &key)); + if (len != sizeof(openssl_public_rsa_stripped) || memcmp(tmp, openssl_public_rsa_stripped, len)) { + fprintf(stderr, "RSA public export failed to match rsa_import_x509\n"); + return 1; + } + rsa_free(&key); len3 = sizeof(tmp); DO(base64_decode(_der_tests_cacert_root_cert, _der_tests_cacert_root_cert_size, tmp, &len3)); From 2bd517307c13ce579d7d7388aab93febee8af0f4 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 30 Mar 2017 18:58:21 +0200 Subject: [PATCH 2/8] add GeneralizedTime DER en-/decode --- src/headers/tomcrypt.h | 2 +- src/headers/tomcrypt_pk.h | 21 +++ src/pk/asn1/der/choice/der_decode_choice.c | 9 ++ .../der_decode_generalizedtime.c | 131 ++++++++++++++++++ .../der_encode_generalizedtime.c | 103 ++++++++++++++ .../der_length_generalizedtime.c | 53 +++++++ .../der/sequence/der_decode_sequence_ex.c | 8 ++ .../der/sequence/der_decode_sequence_flexi.c | 19 +++ .../der/sequence/der_decode_sequence_multi.c | 2 + .../der/sequence/der_encode_sequence_ex.c | 16 +++ .../der/sequence/der_encode_sequence_multi.c | 2 + .../asn1/der/sequence/der_length_sequence.c | 7 + src/pk/asn1/der/set/der_encode_set.c | 1 + testprof/der_tests.c | 13 ++ 14 files changed, 386 insertions(+), 1 deletion(-) create mode 100644 src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c create mode 100644 src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c create mode 100644 src/pk/asn1/der/generalizedtime/der_length_generalizedtime.c diff --git a/src/headers/tomcrypt.h b/src/headers/tomcrypt.h index d38a7c7..6f661c7 100644 --- a/src/headers/tomcrypt.h +++ b/src/headers/tomcrypt.h @@ -55,7 +55,7 @@ enum { CRYPT_FILE_NOTFOUND, /* File Not Found */ CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */ - CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */ + CRYPT_OVERFLOW, /* An overflow of a value was prevented */ CRYPT_PK_DUP, /* Duplicate key already in key ring */ CRYPT_PK_NOT_FOUND, /* Key not found in keyring */ CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */ diff --git a/src/headers/tomcrypt_pk.h b/src/headers/tomcrypt_pk.h index be19bad..a39f5b8 100644 --- a/src/headers/tomcrypt_pk.h +++ b/src/headers/tomcrypt_pk.h @@ -475,6 +475,8 @@ typedef enum ltc_asn1_type_ { LTC_ASN1_TELETEX_STRING, LTC_ASN1_CONSTRUCTED, LTC_ASN1_CONTEXT_SPECIFIC, + /* 20 */ + LTC_ASN1_GENERALIZEDTIME, } ltc_asn1_type; /** A LTC ASN.1 list type */ @@ -662,6 +664,25 @@ int der_decode_utctime(const unsigned char *in, unsigned long *inlen, int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen); +/* GeneralizedTime */ +typedef struct { + unsigned YYYY, /* year */ + MM, /* month */ + DD, /* day */ + hh, /* hour */ + mm, /* minute */ + ss, /* second */ + fs; /* fractional seconds */ +} ltc_generalizedtime; + +int der_encode_generalizedtime(ltc_generalizedtime *gtime, + unsigned char *out, unsigned long *outlen); + +int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen, + ltc_generalizedtime *out); + +int der_length_generalizedtime(ltc_generalizedtime *gtime, unsigned long *outlen); + #endif diff --git a/src/pk/asn1/der/choice/der_decode_choice.c b/src/pk/asn1/der/choice/der_decode_choice.c index e90e67a..eb71513 100644 --- a/src/pk/asn1/der/choice/der_decode_choice.c +++ b/src/pk/asn1/der/choice/der_decode_choice.c @@ -186,6 +186,15 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen, } break; + case LTC_ASN1_GENERALIZEDTIME: + z = *inlen; + if (der_decode_generalizedtime(in, &z, data) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + break; + case LTC_ASN1_SET: case LTC_ASN1_SETOF: case LTC_ASN1_SEQUENCE: diff --git a/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c b/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c new file mode 100644 index 0000000..0fd5579 --- /dev/null +++ b/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c @@ -0,0 +1,131 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_generalizedtime.c + ASN.1 DER, decode a GeneralizedTime, Steffen Jaeckel + Based on der_decode_utctime.c +*/ + +#ifdef LTC_DER + +static int char_to_int(unsigned char x) +{ + switch (x) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + } + return 100; +} + +#define DECODE_V(y, max) do {\ + y = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \ + if (y >= max) return CRYPT_INVALID_PACKET; \ + x += 2; \ +} while(0) + +#define DECODE_V4(y, max) do {\ + y = char_to_int(buf[x])*1000 + char_to_int(buf[x+1])*100 + char_to_int(buf[x+2])*10 + char_to_int(buf[x+3]); \ + if (y >= max) return CRYPT_INVALID_PACKET; \ + x += 4; \ +} while(0) + +/** + Decodes a Generalized time structure in DER format (reads all 6 valid encoding formats) + @param in Input buffer + @param inlen Length of input buffer in octets + @param out [out] Destination of Generalized time structure + @return CRYPT_OK if successful +*/ +int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen, + ltc_generalizedtime *out) +{ + unsigned char buf[32]; + unsigned long x; + int y; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + LTC_ARGCHK(out != NULL); + + /* check header */ + if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* decode the string */ + for (x = 0; x < in[1]; x++) { + y = der_ia5_value_decode(in[x+2]); + if (y == -1) { + return CRYPT_INVALID_PACKET; + } + if (!((y >= '0' && y <= '9') || y == 'Z')) { + return CRYPT_INVALID_PACKET; + } + buf[x] = y; + } + *inlen = 2 + x; + + if (x < 15) { + return CRYPT_INVALID_PACKET; + } + + /* possible encodings are +YYYYMMDDhhmmssZ +YYYYMMDDhhmmss.[0-9]*Z + + So let's do a trivial decode upto [including] ss + */ + + x = 0; + DECODE_V4(out->YYYY, 10000); + DECODE_V(out->MM, 13); + DECODE_V(out->DD, 32); + DECODE_V(out->hh, 24); + DECODE_V(out->mm, 60); + DECODE_V(out->ss, 60); + + /* clear fractional seconds info */ + out->fs = 0; + + /* now is it Z or . */ + if (buf[x] == 'Z') { + return CRYPT_OK; + } else if (buf[x] == '.') { + x++; + while (buf[x] != 'Z') { + unsigned fs = out->fs; + if (x >= sizeof(buf)) return CRYPT_INVALID_PACKET; + out->fs *= 10; + out->fs += char_to_int(buf[x]); + if (fs < out->fs) return CRYPT_OVERFLOW; + x++; + } + return CRYPT_OK; + } else { + return CRYPT_INVALID_PACKET; + } +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c b/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c new file mode 100644 index 0000000..4852684 --- /dev/null +++ b/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c @@ -0,0 +1,103 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_utctime.c + ASN.1 DER, encode a GeneralizedTime, Steffen Jaeckel + Based on der_encode_utctime.c +*/ + +#ifdef LTC_DER + +static const char * const baseten = "0123456789"; + +#define STORE_V(y) do {\ + out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[y % 10]); \ +} while(0) + +#define STORE_V4(y) do {\ + out[x++] = der_ia5_char_encode(baseten[(y/1000) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[(y/100) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[y % 10]); \ +} while(0) + +/** + Encodes a Generalized time structure in DER format + @param utctime The UTC time structure to encode + @param out The destination of the DER encoding of the UTC time structure + @param outlen [in/out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_encode_generalizedtime(ltc_generalizedtime *gtime, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, tmplen; + int err; + + LTC_ARGCHK(gtime != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((err = der_length_generalizedtime(gtime, &tmplen)) != CRYPT_OK) { + return err; + } + if (tmplen > *outlen) { + *outlen = tmplen; + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header */ + out[0] = 0x18; + + /* store values */ + x = 2; + STORE_V4(gtime->YYYY); + STORE_V(gtime->MM); + STORE_V(gtime->DD); + STORE_V(gtime->hh); + STORE_V(gtime->mm); + STORE_V(gtime->ss); + + if (gtime->fs) { + unsigned long div; + unsigned fs = gtime->fs; + unsigned len = 0; + out[x++] = der_ia5_char_encode('.'); + div = 1; + do { + fs /= 10; + div *= 10; + len++; + } while(fs != 0); + while (len-- > 1) { + out[x++] = der_ia5_char_encode(baseten[(gtime->fs/div) % 10]); + div /= 10; + } + out[x++] = der_ia5_char_encode(baseten[gtime->fs % 10]); + } + out[x++] = der_ia5_char_encode('Z'); + + /* store length */ + out[1] = (unsigned char)(x - 2); + + /* all good let's return */ + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/generalizedtime/der_length_generalizedtime.c b/src/pk/asn1/der/generalizedtime/der_length_generalizedtime.c new file mode 100644 index 0000000..eff3948 --- /dev/null +++ b/src/pk/asn1/der/generalizedtime/der_length_generalizedtime.c @@ -0,0 +1,53 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_utctime.c + ASN.1 DER, get length of GeneralizedTime, Steffen Jaeckel + Based on der_length_utctime.c +*/ + +#ifdef LTC_DER + +/** + Gets length of DER encoding of GeneralizedTime + @param utctime The UTC time structure to get the size of + @param outlen [out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_length_generalizedtime(ltc_generalizedtime *gtime, unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(gtime != NULL); + + if (gtime->fs == 0) { + /* we encode as YYYYMMDDhhmmssZ */ + *outlen = 2 + 15; + } else { + /* we encode as YYYYMMDDhhmmss.fsZ */ + unsigned long len = 2 + 17; + unsigned fs = gtime->fs; + do { + fs /= 10; + len++; + } while(fs != 0); + *outlen = len; + } + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/sequence/der_decode_sequence_ex.c b/src/pk/asn1/der/sequence/der_decode_sequence_ex.c index 8a362b7..26e0e71 100644 --- a/src/pk/asn1/der/sequence/der_decode_sequence_ex.c +++ b/src/pk/asn1/der/sequence/der_decode_sequence_ex.c @@ -244,6 +244,14 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, } break; + case LTC_ASN1_GENERALIZEDTIME: + z = inlen; + if ((err = der_decode_generalizedtime(in + x, &z, data)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + break; + case LTC_ASN1_SET: z = inlen; if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) { diff --git a/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c b/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c index 5435381..d76f403 100644 --- a/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c +++ b/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c @@ -347,6 +347,25 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc } break; + case 0x18: + l->type = LTC_ASN1_GENERALIZEDTIME; + l->size = len; + + if ((l->data = XCALLOC(1, sizeof(ltc_generalizedtime))) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_generalizedtime(in, &len, l->data)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_generalizedtime(l->data, &len)) != CRYPT_OK) { + goto error; + } + + break; + case 0x20: /* Any CONSTRUCTED element that is neither SEQUENCE nor SET */ case 0x30: /* SEQUENCE */ case 0x31: /* SET */ diff --git a/src/pk/asn1/der/sequence/der_decode_sequence_multi.c b/src/pk/asn1/der/sequence/der_decode_sequence_multi.c index 8fa4ae0..ba23412 100644 --- a/src/pk/asn1/der/sequence/der_decode_sequence_multi.c +++ b/src/pk/asn1/der/sequence/der_decode_sequence_multi.c @@ -69,6 +69,7 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) case LTC_ASN1_CHOICE: case LTC_ASN1_RAW_BIT_STRING: case LTC_ASN1_TELETEX_STRING: + case LTC_ASN1_GENERALIZEDTIME: ++x; break; @@ -121,6 +122,7 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) case LTC_ASN1_CHOICE: case LTC_ASN1_RAW_BIT_STRING: case LTC_ASN1_TELETEX_STRING: + case LTC_ASN1_GENERALIZEDTIME: LTC_SET_ASN1(list, x++, type, data, size); break; /* coverity[dead_error_line] */ diff --git a/src/pk/asn1/der/sequence/der_encode_sequence_ex.c b/src/pk/asn1/der/sequence/der_encode_sequence_ex.c index 0f17118..e733207 100644 --- a/src/pk/asn1/der/sequence/der_encode_sequence_ex.c +++ b/src/pk/asn1/der/sequence/der_encode_sequence_ex.c @@ -126,6 +126,13 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, y += x; break; + case LTC_ASN1_GENERALIZEDTIME: + if ((err = der_length_generalizedtime(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + case LTC_ASN1_SET: case LTC_ASN1_SETOF: case LTC_ASN1_SEQUENCE: @@ -307,6 +314,15 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, *outlen -= z; break; + case LTC_ASN1_GENERALIZEDTIME: + z = *outlen; + if ((err = der_encode_generalizedtime(data, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + case LTC_ASN1_SET: z = *outlen; if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) { diff --git a/src/pk/asn1/der/sequence/der_encode_sequence_multi.c b/src/pk/asn1/der/sequence/der_encode_sequence_multi.c index cf17f7f..3bd76bf 100644 --- a/src/pk/asn1/der/sequence/der_encode_sequence_multi.c +++ b/src/pk/asn1/der/sequence/der_encode_sequence_multi.c @@ -68,6 +68,7 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) case LTC_ASN1_SET: case LTC_ASN1_SETOF: case LTC_ASN1_RAW_BIT_STRING: + case LTC_ASN1_GENERALIZEDTIME: ++x; break; @@ -120,6 +121,7 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) case LTC_ASN1_SET: case LTC_ASN1_SETOF: case LTC_ASN1_RAW_BIT_STRING: + case LTC_ASN1_GENERALIZEDTIME: LTC_SET_ASN1(list, x++, type, data, size); break; diff --git a/src/pk/asn1/der/sequence/der_length_sequence.c b/src/pk/asn1/der/sequence/der_length_sequence.c index c7fec54..99e427a 100644 --- a/src/pk/asn1/der/sequence/der_length_sequence.c +++ b/src/pk/asn1/der/sequence/der_length_sequence.c @@ -122,6 +122,13 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, y += x; break; + case LTC_ASN1_GENERALIZEDTIME: + if ((err = der_length_generalizedtime(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + case LTC_ASN1_UTF8_STRING: if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) { goto LBL_ERR; diff --git a/src/pk/asn1/der/set/der_encode_set.c b/src/pk/asn1/der/set/der_encode_set.c index ae87697..75de234 100644 --- a/src/pk/asn1/der/set/der_encode_set.c +++ b/src/pk/asn1/der/set/der_encode_set.c @@ -34,6 +34,7 @@ static int ltc_to_asn1(ltc_asn1_type v) case LTC_ASN1_TELETEX_STRING: return 0x14; case LTC_ASN1_IA5_STRING: return 0x16; case LTC_ASN1_UTCTIME: return 0x17; + case LTC_ASN1_GENERALIZEDTIME: return 0x18; case LTC_ASN1_SEQUENCE: return 0x30; case LTC_ASN1_SET: case LTC_ASN1_SETOF: return 0x31; diff --git a/testprof/der_tests.c b/testprof/der_tests.c index dcaf1b2..420ac00 100644 --- a/testprof/der_tests.c +++ b/testprof/der_tests.c @@ -335,6 +335,19 @@ static void _der_tests_print_flexi(ltc_asn1_list* l, unsigned int level) text = buf; } break; + case LTC_ASN1_GENERALIZEDTIME: + name = "GENERALIZED TIME"; + { + ltc_generalizedtime* gt = l->data; + if(gt->fs) + snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d.%02dZ", + gt->YYYY, gt->MM, gt->DD, gt->hh, gt->mm, gt->ss, gt->fs); + else + snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02dZ", + gt->YYYY, gt->MM, gt->DD, gt->hh, gt->mm, gt->ss); + text = buf; + } + break; case LTC_ASN1_CHOICE: name = "CHOICE"; break; From 59b4026fa7d19febe34e891d6e20f15affd35858 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 30 Mar 2017 18:58:28 +0200 Subject: [PATCH 3/8] Update makefiles --- libtomcrypt_VS2005.vcproj | 16 ++++++++++++++++ libtomcrypt_VS2008.vcproj | 16 ++++++++++++++++ makefile | 3 +++ makefile.icc | 3 +++ makefile.mingw | 3 +++ makefile.msvc | 3 +++ makefile.shared | 3 +++ makefile.unix | 3 +++ 8 files changed, 50 insertions(+) diff --git a/libtomcrypt_VS2005.vcproj b/libtomcrypt_VS2005.vcproj index ec61129..7658587 100644 --- a/libtomcrypt_VS2005.vcproj +++ b/libtomcrypt_VS2005.vcproj @@ -1456,6 +1456,22 @@ > + + + + + + + + diff --git a/libtomcrypt_VS2008.vcproj b/libtomcrypt_VS2008.vcproj index 26c0efb..24f12d1 100644 --- a/libtomcrypt_VS2008.vcproj +++ b/libtomcrypt_VS2008.vcproj @@ -1697,6 +1697,22 @@ > + + + + + + + + diff --git a/makefile b/makefile index 140ef2b..d3b80d5 100644 --- a/makefile +++ b/makefile @@ -122,6 +122,9 @@ src/pk/asn1/der/bit/der_decode_raw_bit_string.o src/pk/asn1/der/bit/der_encode_b src/pk/asn1/der/bit/der_encode_raw_bit_string.o src/pk/asn1/der/bit/der_length_bit_string.o \ src/pk/asn1/der/boolean/der_decode_boolean.o src/pk/asn1/der/boolean/der_encode_boolean.o \ src/pk/asn1/der/boolean/der_length_boolean.o src/pk/asn1/der/choice/der_decode_choice.o \ +src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.o \ +src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.o \ +src/pk/asn1/der/generalizedtime/der_length_generalizedtime.o \ src/pk/asn1/der/ia5/der_decode_ia5_string.o src/pk/asn1/der/ia5/der_encode_ia5_string.o \ src/pk/asn1/der/ia5/der_length_ia5_string.o src/pk/asn1/der/integer/der_decode_integer.o \ src/pk/asn1/der/integer/der_encode_integer.o src/pk/asn1/der/integer/der_length_integer.o \ diff --git a/makefile.icc b/makefile.icc index e16d71c..f7589e0 100644 --- a/makefile.icc +++ b/makefile.icc @@ -179,6 +179,9 @@ src/pk/asn1/der/bit/der_decode_raw_bit_string.o src/pk/asn1/der/bit/der_encode_b src/pk/asn1/der/bit/der_encode_raw_bit_string.o src/pk/asn1/der/bit/der_length_bit_string.o \ src/pk/asn1/der/boolean/der_decode_boolean.o src/pk/asn1/der/boolean/der_encode_boolean.o \ src/pk/asn1/der/boolean/der_length_boolean.o src/pk/asn1/der/choice/der_decode_choice.o \ +src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.o \ +src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.o \ +src/pk/asn1/der/generalizedtime/der_length_generalizedtime.o \ src/pk/asn1/der/ia5/der_decode_ia5_string.o src/pk/asn1/der/ia5/der_encode_ia5_string.o \ src/pk/asn1/der/ia5/der_length_ia5_string.o src/pk/asn1/der/integer/der_decode_integer.o \ src/pk/asn1/der/integer/der_encode_integer.o src/pk/asn1/der/integer/der_length_integer.o \ diff --git a/makefile.mingw b/makefile.mingw index 12d4de2..c18e362 100644 --- a/makefile.mingw +++ b/makefile.mingw @@ -115,6 +115,9 @@ src/pk/asn1/der/bit/der_decode_raw_bit_string.o src/pk/asn1/der/bit/der_encode_b src/pk/asn1/der/bit/der_encode_raw_bit_string.o src/pk/asn1/der/bit/der_length_bit_string.o \ src/pk/asn1/der/boolean/der_decode_boolean.o src/pk/asn1/der/boolean/der_encode_boolean.o \ src/pk/asn1/der/boolean/der_length_boolean.o src/pk/asn1/der/choice/der_decode_choice.o \ +src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.o \ +src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.o \ +src/pk/asn1/der/generalizedtime/der_length_generalizedtime.o \ src/pk/asn1/der/ia5/der_decode_ia5_string.o src/pk/asn1/der/ia5/der_encode_ia5_string.o \ src/pk/asn1/der/ia5/der_length_ia5_string.o src/pk/asn1/der/integer/der_decode_integer.o \ src/pk/asn1/der/integer/der_encode_integer.o src/pk/asn1/der/integer/der_length_integer.o \ diff --git a/makefile.msvc b/makefile.msvc index 80ac0cc..cb325b1 100644 --- a/makefile.msvc +++ b/makefile.msvc @@ -89,6 +89,9 @@ src/pk/asn1/der/bit/der_decode_raw_bit_string.obj src/pk/asn1/der/bit/der_encode src/pk/asn1/der/bit/der_encode_raw_bit_string.obj src/pk/asn1/der/bit/der_length_bit_string.obj \ src/pk/asn1/der/boolean/der_decode_boolean.obj src/pk/asn1/der/boolean/der_encode_boolean.obj \ src/pk/asn1/der/boolean/der_length_boolean.obj src/pk/asn1/der/choice/der_decode_choice.obj \ +src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.obj \ +src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.obj \ +src/pk/asn1/der/generalizedtime/der_length_generalizedtime.obj \ src/pk/asn1/der/ia5/der_decode_ia5_string.obj src/pk/asn1/der/ia5/der_encode_ia5_string.obj \ src/pk/asn1/der/ia5/der_length_ia5_string.obj src/pk/asn1/der/integer/der_decode_integer.obj \ src/pk/asn1/der/integer/der_encode_integer.obj src/pk/asn1/der/integer/der_length_integer.obj \ diff --git a/makefile.shared b/makefile.shared index 0393caa..d59c0dc 100644 --- a/makefile.shared +++ b/makefile.shared @@ -112,6 +112,9 @@ src/pk/asn1/der/bit/der_decode_raw_bit_string.o src/pk/asn1/der/bit/der_encode_b src/pk/asn1/der/bit/der_encode_raw_bit_string.o src/pk/asn1/der/bit/der_length_bit_string.o \ src/pk/asn1/der/boolean/der_decode_boolean.o src/pk/asn1/der/boolean/der_encode_boolean.o \ src/pk/asn1/der/boolean/der_length_boolean.o src/pk/asn1/der/choice/der_decode_choice.o \ +src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.o \ +src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.o \ +src/pk/asn1/der/generalizedtime/der_length_generalizedtime.o \ src/pk/asn1/der/ia5/der_decode_ia5_string.o src/pk/asn1/der/ia5/der_encode_ia5_string.o \ src/pk/asn1/der/ia5/der_length_ia5_string.o src/pk/asn1/der/integer/der_decode_integer.o \ src/pk/asn1/der/integer/der_encode_integer.o src/pk/asn1/der/integer/der_length_integer.o \ diff --git a/makefile.unix b/makefile.unix index 59a3481..310bb1c 100644 --- a/makefile.unix +++ b/makefile.unix @@ -120,6 +120,9 @@ src/pk/asn1/der/bit/der_decode_raw_bit_string.o src/pk/asn1/der/bit/der_encode_b src/pk/asn1/der/bit/der_encode_raw_bit_string.o src/pk/asn1/der/bit/der_length_bit_string.o \ src/pk/asn1/der/boolean/der_decode_boolean.o src/pk/asn1/der/boolean/der_encode_boolean.o \ src/pk/asn1/der/boolean/der_length_boolean.o src/pk/asn1/der/choice/der_decode_choice.o \ +src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.o \ +src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.o \ +src/pk/asn1/der/generalizedtime/der_length_generalizedtime.o \ src/pk/asn1/der/ia5/der_decode_ia5_string.o src/pk/asn1/der/ia5/der_encode_ia5_string.o \ src/pk/asn1/der/ia5/der_length_ia5_string.o src/pk/asn1/der/integer/der_decode_integer.o \ src/pk/asn1/der/integer/der_encode_integer.o src/pk/asn1/der/integer/der_length_integer.o \ From 83780d4764d1c04c748b8d0446617981cccd3a2b Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 30 Mar 2017 22:48:42 +0200 Subject: [PATCH 4/8] add timezone-offset support to GeneralizedTime this also fixes a bug in the length generation --- src/headers/tomcrypt_pk.h | 5 ++++- .../generalizedtime/der_decode_generalizedtime.c | 11 ++++++++++- .../generalizedtime/der_encode_generalizedtime.c | 9 ++++++++- .../generalizedtime/der_length_generalizedtime.c | 13 ++++++++++--- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/headers/tomcrypt_pk.h b/src/headers/tomcrypt_pk.h index a39f5b8..60a11a9 100644 --- a/src/headers/tomcrypt_pk.h +++ b/src/headers/tomcrypt_pk.h @@ -672,7 +672,10 @@ typedef struct { hh, /* hour */ mm, /* minute */ ss, /* second */ - fs; /* fractional seconds */ + fs, /* fractional seconds */ + off_dir, /* timezone offset direction 0 == +, 1 == - */ + off_hh, /* timezone offset hours */ + off_mm; /* timezone offset minutes */ } ltc_generalizedtime; int der_encode_generalizedtime(ltc_generalizedtime *gtime, diff --git a/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c b/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c index 0fd5579..1f0713e 100644 --- a/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c +++ b/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c @@ -110,7 +110,7 @@ YYYYMMDDhhmmss.[0-9]*Z return CRYPT_OK; } else if (buf[x] == '.') { x++; - while (buf[x] != 'Z') { + while (buf[x] >= '0' && buf[x] <= '9') { unsigned fs = out->fs; if (x >= sizeof(buf)) return CRYPT_INVALID_PACKET; out->fs *= 10; @@ -118,6 +118,15 @@ YYYYMMDDhhmmss.[0-9]*Z if (fs < out->fs) return CRYPT_OVERFLOW; x++; } + } + + /* now is it Z, +, - */ + if (buf[x] == 'Z') { + return CRYPT_OK; + } else if (buf[x] == '+' || buf[x] == '-') { + out->off_dir = (buf[x++] == '+') ? 0 : 1; + DECODE_V(out->off_hh, 24); + DECODE_V(out->off_mm, 60); return CRYPT_OK; } else { return CRYPT_INVALID_PACKET; diff --git a/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c b/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c index 4852684..afb26c8 100644 --- a/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c +++ b/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c @@ -86,7 +86,14 @@ int der_encode_generalizedtime(ltc_generalizedtime *gtime, } out[x++] = der_ia5_char_encode(baseten[gtime->fs % 10]); } - out[x++] = der_ia5_char_encode('Z'); + + if (gtime->off_mm || gtime->off_hh) { + out[x++] = der_ia5_char_encode(gtime->off_dir ? '-' : '+'); + STORE_V(gtime->off_hh); + STORE_V(gtime->off_mm); + } else { + out[x++] = der_ia5_char_encode('Z'); + } /* store length */ out[1] = (unsigned char)(x - 2); diff --git a/src/pk/asn1/der/generalizedtime/der_length_generalizedtime.c b/src/pk/asn1/der/generalizedtime/der_length_generalizedtime.c index eff3948..e5abf9f 100644 --- a/src/pk/asn1/der/generalizedtime/der_length_generalizedtime.c +++ b/src/pk/asn1/der/generalizedtime/der_length_generalizedtime.c @@ -31,15 +31,22 @@ int der_length_generalizedtime(ltc_generalizedtime *gtime, unsigned long *outlen if (gtime->fs == 0) { /* we encode as YYYYMMDDhhmmssZ */ - *outlen = 2 + 15; + *outlen = 2 + 14 + 1; } else { - /* we encode as YYYYMMDDhhmmss.fsZ */ - unsigned long len = 2 + 17; + unsigned long len = 2 + 14 + 1; unsigned fs = gtime->fs; do { fs /= 10; len++; } while(fs != 0); + if (gtime->off_hh == 0 && gtime->off_mm == 0) { + /* we encode as YYYYMMDDhhmmss.fsZ */ + len += 1; + } + else { + /* we encode as YYYYMMDDhhmmss.fs{+|-}hh'mm' */ + len += 5; + } *outlen = len; } From 1f0daf1eff8c8b5734d5299a5c1b683b8099e268 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Fri, 31 Mar 2017 00:57:22 +0200 Subject: [PATCH 5/8] fix compiler warning --- .../der/generalizedtime/der_encode_generalizedtime.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c b/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c index afb26c8..12b65e3 100644 --- a/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c +++ b/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c @@ -70,19 +70,19 @@ int der_encode_generalizedtime(ltc_generalizedtime *gtime, STORE_V(gtime->ss); if (gtime->fs) { - unsigned long div; + unsigned long divisor; unsigned fs = gtime->fs; unsigned len = 0; out[x++] = der_ia5_char_encode('.'); - div = 1; + divisor = 1; do { fs /= 10; - div *= 10; + divisor *= 10; len++; } while(fs != 0); while (len-- > 1) { - out[x++] = der_ia5_char_encode(baseten[(gtime->fs/div) % 10]); - div /= 10; + out[x++] = der_ia5_char_encode(baseten[(gtime->fs/divisor) % 10]); + divisor /= 10; } out[x++] = der_ia5_char_encode(baseten[gtime->fs % 10]); } From 08503a02f5612cfab79d415797e0418bc9ffaae9 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Fri, 31 Mar 2017 15:12:12 +0200 Subject: [PATCH 6/8] update error codes This closes #180 --- src/headers/tomcrypt.h | 9 ++++++--- src/misc/error_to_string.c | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/headers/tomcrypt.h b/src/headers/tomcrypt.h index 6f661c7..40584e7 100644 --- a/src/headers/tomcrypt.h +++ b/src/headers/tomcrypt.h @@ -55,9 +55,12 @@ enum { CRYPT_FILE_NOTFOUND, /* File Not Found */ CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */ - CRYPT_OVERFLOW, /* An overflow of a value was prevented */ - CRYPT_PK_DUP, /* Duplicate key already in key ring */ - CRYPT_PK_NOT_FOUND, /* Key not found in keyring */ + + CRYPT_OVERFLOW, /* An overflow of a value was detected/prevented */ + + CRYPT_UNUSED1, /* UNUSED1 */ + CRYPT_UNUSED2, /* UNUSED2 */ + CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */ CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */ diff --git a/src/misc/error_to_string.c b/src/misc/error_to_string.c index 2ca1492..c3d0872 100644 --- a/src/misc/error_to_string.c +++ b/src/misc/error_to_string.c @@ -45,9 +45,12 @@ static const char * const err_2_str[] = "File Not Found", "Invalid PK type.", - "Invalid PK system.", - "Duplicate PK key found on keyring.", - "Key not found in keyring.", + + "An overflow of a value was detected/prevented.", + + "UNUSED1.", + "UNUSED2.", + "Invalid sized parameter.", "Invalid size for prime.", From 2c52bf75f417e3f619da178ac0aa094d00e380b4 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Fri, 31 Mar 2017 15:12:38 +0200 Subject: [PATCH 7/8] bugfixing --- .../der/generalizedtime/der_decode_generalizedtime.c | 12 +++++++++--- .../der/generalizedtime/der_encode_generalizedtime.c | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c b/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c index 1f0713e..f8997ee 100644 --- a/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c +++ b/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c @@ -76,7 +76,9 @@ int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen, if (y == -1) { return CRYPT_INVALID_PACKET; } - if (!((y >= '0' && y <= '9') || y == 'Z')) { + if (!((y >= '0' && y <= '9') + || y == 'Z' || y == '.' + || y == '+' || y == '-')) { return CRYPT_INVALID_PACKET; } buf[x] = y; @@ -89,7 +91,11 @@ int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen, /* possible encodings are YYYYMMDDhhmmssZ -YYYYMMDDhhmmss.[0-9]*Z +YYYYMMDDhhmmss+hh'mm' +YYYYMMDDhhmmss-hh'mm' +YYYYMMDDhhmmss.fsZ +YYYYMMDDhhmmss.fs+hh'mm' +YYYYMMDDhhmmss.fs-hh'mm' So let's do a trivial decode upto [including] ss */ @@ -115,7 +121,7 @@ YYYYMMDDhhmmss.[0-9]*Z if (x >= sizeof(buf)) return CRYPT_INVALID_PACKET; out->fs *= 10; out->fs += char_to_int(buf[x]); - if (fs < out->fs) return CRYPT_OVERFLOW; + if (fs > out->fs) return CRYPT_OVERFLOW; x++; } } diff --git a/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c b/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c index 12b65e3..b2198d9 100644 --- a/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c +++ b/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c @@ -81,8 +81,8 @@ int der_encode_generalizedtime(ltc_generalizedtime *gtime, len++; } while(fs != 0); while (len-- > 1) { - out[x++] = der_ia5_char_encode(baseten[(gtime->fs/divisor) % 10]); divisor /= 10; + out[x++] = der_ia5_char_encode(baseten[(gtime->fs/divisor) % 10]); } out[x++] = der_ia5_char_encode(baseten[gtime->fs % 10]); } From 78a32430d4fd73bf825fd9f84614eb5691029b51 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Fri, 31 Mar 2017 18:21:13 +0200 Subject: [PATCH 8/8] more tests --- testprof/der_tests.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/testprof/der_tests.c b/testprof/der_tests.c index 420ac00..faa3b3b 100644 --- a/testprof/der_tests.c +++ b/testprof/der_tests.c @@ -671,6 +671,7 @@ static void der_set_test(void) SEQUENCE { INTEGER 12345678 UTCTIME { 91, 5, 6, 16, 45, 40, 1, 7, 0 } + GENERALIZEDTIME { 2017, 03, 21, 10, 21, 12, 4, 1, 2, 0 } SEQUENCE { OCTET STRING { 1, 2, 3, 4 } BIT STRING { 1, 0, 0, 1 } @@ -695,6 +696,7 @@ static void der_flexi_test(void) static const char ia5_str[] = "ia5"; static const unsigned long int_val = 12345678UL; static const ltc_utctime utctime = { 91, 5, 6, 16, 45, 40, 1, 7, 0 }; + static const ltc_generalizedtime gtime = { 2017, 03, 21, 10, 21, 12, 421, 1, 2, 0 }; static const unsigned char oct_str[] = { 1, 2, 3, 4 }; static const unsigned char bit_str[] = { 1, 0, 0, 1 }; static const unsigned long oid_str[] = { 1, 2, 840, 113549 }; @@ -702,16 +704,17 @@ static void der_flexi_test(void) unsigned char encode_buf[192]; unsigned long encode_buf_len, decode_len; - ltc_asn1_list static_list[5][3], *decoded_list, *l; + ltc_asn1_list static_list[5][4], *decoded_list, *l; /* build list */ LTC_SET_ASN1(static_list[0], 0, LTC_ASN1_PRINTABLE_STRING, (void *)printable_str, strlen(printable_str)); LTC_SET_ASN1(static_list[0], 1, LTC_ASN1_IA5_STRING, (void *)ia5_str, strlen(ia5_str)); - LTC_SET_ASN1(static_list[0], 2, LTC_ASN1_SEQUENCE, static_list[1], 3); + LTC_SET_ASN1(static_list[0], 2, LTC_ASN1_SEQUENCE, static_list[1], 4); LTC_SET_ASN1(static_list[1], 0, LTC_ASN1_SHORT_INTEGER, (void *)&int_val, 1); LTC_SET_ASN1(static_list[1], 1, LTC_ASN1_UTCTIME, (void *)&utctime, 1); - LTC_SET_ASN1(static_list[1], 2, LTC_ASN1_SEQUENCE, static_list[2], 3); + LTC_SET_ASN1(static_list[1], 2, LTC_ASN1_GENERALIZEDTIME, (void *)>ime, 1); + LTC_SET_ASN1(static_list[1], 3, LTC_ASN1_SEQUENCE, static_list[2], 3); LTC_SET_ASN1(static_list[2], 0, LTC_ASN1_OCTET_STRING, (void *)oct_str, 4); LTC_SET_ASN1(static_list[2], 1, LTC_ASN1_BIT_STRING, (void *)bit_str, 4); @@ -854,6 +857,26 @@ static void der_flexi_test(void) /* move to next */ l = l->next; + /* GeneralizedTime */ + + if (l->next == NULL || l->child != NULL) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (l->type != LTC_ASN1_GENERALIZEDTIME) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + if (memcmp(l->data, >ime, sizeof(gtime))) { + fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); + exit(EXIT_FAILURE); + } + + /* move to next */ + l = l->next; + /* expect child anve move down */ if (l->next != NULL || l->child == NULL) { @@ -1008,6 +1031,7 @@ static int der_choice_test(void) unsigned long integer, oidbuf[10], outlen, inlen, x, y; void *mpinteger; ltc_utctime utctime = { 91, 5, 6, 16, 45, 40, 1, 7, 0 }; + ltc_generalizedtime gtime = { 2038, 01, 19, 3, 14, 8, 0, 0, 0, 0 }; /* setup variables */ for (x = 0; x < sizeof(bitbuf); x++) { bitbuf[x] = x & 1; } @@ -1030,7 +1054,11 @@ static int der_choice_test(void) LTC_SET_ASN1(types, 4, LTC_ASN1_INTEGER, mpinteger, 1); } LTC_SET_ASN1(types, 5, LTC_ASN1_OBJECT_IDENTIFIER, oidbuf, sizeof(oidbuf)/sizeof(oidbuf[0])); - LTC_SET_ASN1(types, 6, LTC_ASN1_UTCTIME, &utctime, 1); + if (x > 7) { + LTC_SET_ASN1(types, 6, LTC_ASN1_UTCTIME, &utctime, 1); + } else { + LTC_SET_ASN1(types, 6, LTC_ASN1_GENERALIZEDTIME, >ime, 1); + } LTC_SET_ASN1(host, 0, LTC_ASN1_CHOICE, types, 7);