Skip to content

Commit

Permalink
Add support for custom constructed ASN.1 types
Browse files Browse the repository at this point in the history
This fixes #622

Signed-off-by: Steffen Jaeckel <[email protected]>
  • Loading branch information
sjaeckel committed Jun 21, 2023
1 parent aacafad commit 05a51bd
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 4 deletions.
8 changes: 8 additions & 0 deletions src/headers/tomcrypt_pk.h
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,14 @@ typedef struct ltc_asn1_list_ {
LTC_MACRO_list[LTC_TMPVAR(LTC_SAI)].tag = (Tag); \
} while (0)

#define LTC_SET_ASN1_CUSTOM(list, index, Class, Structure, Tag, Type, Data, Size) \
do { \
int LTC_TMPVAR(LTC_SAC) = (index); \
LTC_SET_ASN1(list, LTC_TMPVAR(LTC_SAC), LTC_ASN1_CUSTOM_TYPE, Data, Size); \
LTC_SET_ASN1_IDENTIFIER(list, LTC_TMPVAR(LTC_SAC), Class, Structure, Tag); \
list[LTC_TMPVAR(LTC_SAC)].used = (int)(Type); \
} while (0)

#define LTC_SET_ASN1_CUSTOM_CONSTRUCTED(list, index, Class, Tag, Data) \
do { \
int LTC_TMPVAR(LTC_SACC) = (index); \
Expand Down
9 changes: 5 additions & 4 deletions src/pk/asn1/der/custom_type/der_encode_custom_type.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
int der_encode_custom_type(const ltc_asn1_list *root,
unsigned char *out, unsigned long *outlen)
{
int err;
int err, use_root;
ltc_asn1_type type;
const ltc_asn1_list *list;
unsigned long size, x, y, z, i, inlen, id_len;
Expand All @@ -49,8 +49,9 @@ int der_encode_custom_type(const ltc_asn1_list *root,
if (der_length_asn1_identifier(root, &id_len) != CRYPT_OK) return CRYPT_INVALID_ARG;
x = id_len;


if (root->pc == LTC_ASN1_PC_PRIMITIVE) {
use_root = root->pc == LTC_ASN1_PC_PRIMITIVE ||
(root->used >= LTC_ASN1_SEQUENCE && root->used <= LTC_ASN1_SETOF);
if (use_root) {
list = root;
inlen = 1;
/* In case it's a PRIMITIVE type we encode directly to the output
Expand All @@ -72,7 +73,7 @@ int der_encode_custom_type(const ltc_asn1_list *root,
/* store data */
*outlen -= x;
for (i = 0; i < inlen; i++) {
if (root->pc == LTC_ASN1_PC_PRIMITIVE) {
if (use_root) {
type = (ltc_asn1_type)list[i].used;
} else {
type = list[i].type;
Expand Down
45 changes: 45 additions & 0 deletions tests/der_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1422,6 +1422,49 @@ static void s_der_regression_test(void)
SHOULD_FAIL(der_decode_sequence_flexi(issue_507, &len, &l));
}

static void s_der_custom_setof(void)
{
/*
* C.f. https://github.com/libtom/libtomcrypt/issues/622
*
Toy ::= SEQUENCE {
hello UTF8String,
numbers [0] IMPLICIT SET OF Number }
Number ::= INTEGER { zero(0), one(1) }
30 0F
0C 02 68 69
A0 09
02 01 00
02 01 00
02 01 01
*
*/

ltc_asn1_list setof[3];
ltc_asn1_list seq[2];
const unsigned long zero = 0;
const unsigned long one = 1;
const wchar_t *hello = L"hi";
unsigned char buf[32];
unsigned long buflen = sizeof(buf);
ltc_asn1_list *flexi;

LTC_SET_ASN1(setof, 0, LTC_ASN1_SHORT_INTEGER, &one, 1);
LTC_SET_ASN1(setof, 1, LTC_ASN1_SHORT_INTEGER, &zero, 1);
LTC_SET_ASN1(setof, 2, LTC_ASN1_SHORT_INTEGER, &zero, 1);

LTC_SET_ASN1(seq, 0, LTC_ASN1_UTF8_STRING, hello, wcslen(hello));
LTC_SET_ASN1_CUSTOM(seq, 1, LTC_ASN1_CL_CONTEXT_SPECIFIC, LTC_ASN1_PC_CONSTRUCTED, 0, LTC_ASN1_SETOF, setof, 3);
DO(der_encode_sequence(seq, 2, buf, &buflen));

DO(der_decode_sequence_flexi(buf, &buflen, &flexi));
s_der_tests_print_flexi(flexi);
der_free_sequence_flexi(flexi);
}

static void der_toolong_test(void)
{
int n, err, failed = 0;
Expand Down Expand Up @@ -1652,6 +1695,8 @@ int der_test(void)

if (ltc_mp.name == NULL) return CRYPT_NOP;

s_der_custom_setof();

s_der_recursion_limit();

der_Xcode_test();
Expand Down

0 comments on commit 05a51bd

Please sign in to comment.