Replaced system SQLite with SQLCipher to support encrypted database
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
|
||||
/**
|
||||
@file der_decode_sequence_ex.c
|
||||
ASN.1 DER, decode a SEQUENCE, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Decode a SEQUENCE
|
||||
@param in The DER encoded input
|
||||
@param inlen The size of the input
|
||||
@param list The list of items to decode
|
||||
@param outlen The number of items in the list
|
||||
@param flags c.f. enum ltc_der_seq
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
||||
ltc_asn1_list *list, unsigned long outlen, unsigned int flags)
|
||||
{
|
||||
return der_decode_custom_type_ex(in, inlen, NULL, list, outlen, flags);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,546 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
/**
|
||||
@file der_decode_sequence_flexi.c
|
||||
ASN.1 DER, decode an array of ASN.1 types with a flexi parser, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
static int s_new_element(ltc_asn1_list **l)
|
||||
{
|
||||
/* alloc new link */
|
||||
if (*l == NULL) {
|
||||
*l = XCALLOC(1, sizeof(ltc_asn1_list));
|
||||
if (*l == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
} else {
|
||||
(*l)->next = XCALLOC(1, sizeof(ltc_asn1_list));
|
||||
if ((*l)->next == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
(*l)->next->prev = *l;
|
||||
*l = (*l)->next;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements.
|
||||
@param in The input buffer
|
||||
@param inlen [in/out] The length of the input buffer and on output the amount of decoded data
|
||||
@param out [out] A pointer to the linked list
|
||||
@param depth The depth/level of decoding recursion we've already reached
|
||||
@return CRYPT_OK on success.
|
||||
*/
|
||||
static int s_der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out, unsigned long depth)
|
||||
{
|
||||
ltc_asn1_list *l;
|
||||
unsigned long err, identifier, len, totlen, data_offset, id_len, len_len;
|
||||
void *realloc_tmp;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(inlen != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
|
||||
l = NULL;
|
||||
totlen = 0;
|
||||
|
||||
if (*inlen == 0) {
|
||||
/* alloc new link */
|
||||
if ((err = s_new_element(&l)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* scan the input and and get lengths and what not */
|
||||
while (*inlen) {
|
||||
/* alloc new link */
|
||||
if ((err = s_new_element(&l)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
id_len = *inlen;
|
||||
if ((err = der_decode_asn1_identifier(in, &id_len, l)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
/* read the type byte */
|
||||
identifier = *in;
|
||||
|
||||
if (l->type != LTC_ASN1_EOL) {
|
||||
/* fetch length */
|
||||
len_len = *inlen - id_len;
|
||||
#if defined(LTC_TEST_DBG)
|
||||
data_offset = 666;
|
||||
len = 0;
|
||||
#endif
|
||||
if ((err = der_decode_asn1_length(&in[id_len], &len_len, &len)) != CRYPT_OK) {
|
||||
#if defined(LTC_TEST_DBG)
|
||||
fprintf(stderr, "E1 %02lx: hl=%4lu l=%4lu - %s (%s)\n", identifier, data_offset, len, der_asn1_tag_to_string_map[l->tag], error_to_string(err));
|
||||
#endif
|
||||
goto error;
|
||||
} else if (len > (*inlen - id_len - len_len)) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
#if defined(LTC_TEST_DBG)
|
||||
fprintf(stderr, "E2 %02lx: hl=%4lu l=%4lu - %s (%s)\n", identifier, data_offset, len, der_asn1_tag_to_string_map[l->tag], error_to_string(err));
|
||||
#endif
|
||||
goto error;
|
||||
}
|
||||
data_offset = id_len + len_len;
|
||||
#if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 1
|
||||
if (l->type == LTC_ASN1_CUSTOM_TYPE && l->klass == LTC_ASN1_CL_CONTEXT_SPECIFIC) {
|
||||
fprintf(stderr, "OK %02lx: hl=%4lu l=%4lu - Context Specific[%s %llu]\n", identifier, data_offset, len, der_asn1_pc_to_string_map[l->pc], l->tag);
|
||||
} else {
|
||||
fprintf(stderr, "OK %02lx: hl=%4lu l=%4lu - %s\n", identifier, data_offset, len, der_asn1_tag_to_string_map[l->tag]);
|
||||
}
|
||||
#endif
|
||||
len += data_offset;
|
||||
|
||||
if (l->type == LTC_ASN1_CUSTOM_TYPE) {
|
||||
/* Custom type, use the 'used' field to store the original identifier */
|
||||
l->used = identifier;
|
||||
if (l->pc == LTC_ASN1_PC_CONSTRUCTED) {
|
||||
/* treat constructed elements like SEQUENCEs */
|
||||
identifier = 0x20;
|
||||
} else {
|
||||
/* primitive elements are treated as opaque data */
|
||||
identifier = 0x80;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Init this so gcc won't complain,
|
||||
* as this case will only be hit when we
|
||||
* can't decode the identifier so the
|
||||
* switch-case should go to default anyway...
|
||||
*/
|
||||
data_offset = 0;
|
||||
len = 0;
|
||||
}
|
||||
|
||||
/* now switch on type */
|
||||
switch (identifier) {
|
||||
case 0x01: /* BOOLEAN */
|
||||
if (l->type != LTC_ASN1_BOOLEAN) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
l->size = 1;
|
||||
l->data = XCALLOC(1, sizeof(int));
|
||||
|
||||
if ((err = der_decode_boolean(in, *inlen, l->data)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_boolean(&len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x02: /* INTEGER */
|
||||
if (l->type != LTC_ASN1_INTEGER) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
l->size = 1;
|
||||
if ((err = ltc_mp_init(&l->data)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* decode field */
|
||||
if ((err = der_decode_integer(in, *inlen, l->data)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* calc length of object */
|
||||
if ((err = der_length_integer(l->data, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x03: /* BIT */
|
||||
if (l->type != LTC_ASN1_BIT_STRING) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char. */
|
||||
|
||||
if ((l->data = XCALLOC(1, l->size)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_decode_bit_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_bit_string(l->size, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x04: /* OCTET */
|
||||
if (l->type != LTC_ASN1_OCTET_STRING) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
l->size = len;
|
||||
|
||||
if ((l->data = XCALLOC(1, l->size)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_decode_octet_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_octet_string(l->size, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x05: /* NULL */
|
||||
if (l->type != LTC_ASN1_NULL) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* valid NULL is 0x05 0x00 */
|
||||
if (in[0] != 0x05 || in[1] != 0x00) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* simple to store ;-) */
|
||||
l->data = NULL;
|
||||
l->size = 0;
|
||||
len = 2;
|
||||
|
||||
break;
|
||||
|
||||
case 0x06: /* OID */
|
||||
if (l->type != LTC_ASN1_OBJECT_IDENTIFIER) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
l->size = len;
|
||||
|
||||
if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_decode_object_identifier(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_object_identifier(l->data, l->size, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* resize it to save a bunch of mem */
|
||||
if ((realloc_tmp = XREALLOC(l->data, l->size * sizeof(unsigned long))) == NULL) {
|
||||
/* out of heap but this is not an error */
|
||||
break;
|
||||
}
|
||||
l->data = realloc_tmp;
|
||||
break;
|
||||
|
||||
case 0x0C: /* UTF8 */
|
||||
|
||||
/* init field */
|
||||
if (l->type != LTC_ASN1_UTF8_STRING) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
l->size = len;
|
||||
|
||||
if ((l->data = XCALLOC(l->size, sizeof(wchar_t))) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_decode_utf8_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_utf8_string(l->data, l->size, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x13: /* PRINTABLE */
|
||||
if (l->type != LTC_ASN1_PRINTABLE_STRING) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
l->size = len;
|
||||
|
||||
if ((l->data = XCALLOC(1, l->size)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_decode_printable_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_printable_string(l->data, l->size, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x14: /* TELETEXT */
|
||||
if (l->type != LTC_ASN1_TELETEX_STRING) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
l->size = len;
|
||||
|
||||
if ((l->data = XCALLOC(1, l->size)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_decode_teletex_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_teletex_string(l->data, l->size, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x16: /* IA5 */
|
||||
if (l->type != LTC_ASN1_IA5_STRING) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
l->size = len;
|
||||
|
||||
if ((l->data = XCALLOC(1, l->size)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_decode_ia5_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_ia5_string(l->data, l->size, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x17: /* UTC TIME */
|
||||
if (l->type != LTC_ASN1_UTCTIME) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
l->size = 1;
|
||||
|
||||
if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
len = *inlen;
|
||||
if ((err = der_decode_utctime(in, &len, l->data)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_utctime(l->data, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
if (l->type != LTC_ASN1_GENERALIZEDTIME) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
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 */
|
||||
|
||||
/* init field */
|
||||
if (identifier == 0x20) {
|
||||
if (l->type != LTC_ASN1_CUSTOM_TYPE) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (identifier == 0x30) {
|
||||
if (l->type != LTC_ASN1_SEQUENCE) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (l->type != LTC_ASN1_SET) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* check that we don't go over the recursion limit */
|
||||
if (depth > LTC_DER_MAX_RECURSION) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((l->data = XMALLOC(len)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
XMEMCPY(l->data, in, len);
|
||||
l->size = len;
|
||||
|
||||
|
||||
/* jump to the start of the data */
|
||||
in += data_offset;
|
||||
*inlen -= data_offset;
|
||||
len -= data_offset;
|
||||
|
||||
/* save the decoded ASN.1 len */
|
||||
len_len = len;
|
||||
|
||||
/* Sequence elements go as child */
|
||||
if ((err = s_der_decode_sequence_flexi(in, &len, &(l->child), depth+1)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
if (len_len != len) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* len update */
|
||||
totlen += data_offset;
|
||||
|
||||
/* the flexi decoder can also do nothing, so make sure a child has been allocated */
|
||||
if (l->child) {
|
||||
/* link them up y0 */
|
||||
l->child->parent = l;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x80: /* Context-specific */
|
||||
if (l->type != LTC_ASN1_CUSTOM_TYPE) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((l->data = XCALLOC(1, len - data_offset)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
XMEMCPY(l->data, in + data_offset, len - data_offset);
|
||||
l->size = len - data_offset;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
/* invalid byte ... this is a soft error */
|
||||
/* remove link */
|
||||
if (l->prev) {
|
||||
l = l->prev;
|
||||
XFREE(l->next);
|
||||
l->next = NULL;
|
||||
}
|
||||
goto outside;
|
||||
}
|
||||
|
||||
/* advance pointers */
|
||||
totlen += len;
|
||||
in += len;
|
||||
*inlen -= len;
|
||||
}
|
||||
|
||||
outside:
|
||||
|
||||
/* in case we processed anything */
|
||||
if (totlen) {
|
||||
/* rewind l please */
|
||||
while (l->prev != NULL || l->parent != NULL) {
|
||||
if (l->parent != NULL) {
|
||||
l = l->parent;
|
||||
} else {
|
||||
l = l->prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* return */
|
||||
*out = l;
|
||||
*inlen = totlen;
|
||||
return CRYPT_OK;
|
||||
|
||||
error:
|
||||
/* free list */
|
||||
der_sequence_free(l);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements.
|
||||
@param in The input buffer
|
||||
@param inlen [in/out] The length of the input buffer and on output the amount of decoded data
|
||||
@param out [out] A pointer to the linked list
|
||||
@return CRYPT_OK on success.
|
||||
*/
|
||||
int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out)
|
||||
{
|
||||
return s_der_decode_sequence_flexi(in, inlen, out, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
@@ -0,0 +1,184 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
/**
|
||||
@file der_decode_sequence_multi.c
|
||||
ASN.1 DER, decode a SEQUENCE, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Decode a SEQUENCE type using a VA list
|
||||
@param in Input buffer
|
||||
@param inlen Length of input in octets
|
||||
@param a1 Initialized argument list #1
|
||||
@param a2 Initialized argument list #2 (copy of #1)
|
||||
@param flags c.f. enum ltc_der_seq
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
static int s_der_decode_sequence_va(const unsigned char *in, unsigned long inlen, va_list a1, va_list a2, unsigned int flags)
|
||||
{
|
||||
int err;
|
||||
ltc_asn1_type type;
|
||||
unsigned long size, x;
|
||||
void *data;
|
||||
ltc_asn1_list *list;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
|
||||
/* get size of output that will be required */
|
||||
x = 0;
|
||||
for (;;) {
|
||||
type = (ltc_asn1_type)va_arg(a1, int);
|
||||
|
||||
if (type == LTC_ASN1_EOL) {
|
||||
break;
|
||||
}
|
||||
|
||||
size = va_arg(a1, unsigned long);
|
||||
data = va_arg(a1, void*);
|
||||
LTC_UNUSED_PARAM(size);
|
||||
LTC_UNUSED_PARAM(data);
|
||||
|
||||
switch (type) {
|
||||
case LTC_ASN1_BOOLEAN:
|
||||
case LTC_ASN1_INTEGER:
|
||||
case LTC_ASN1_SHORT_INTEGER:
|
||||
case LTC_ASN1_BIT_STRING:
|
||||
case LTC_ASN1_OCTET_STRING:
|
||||
case LTC_ASN1_NULL:
|
||||
case LTC_ASN1_OBJECT_IDENTIFIER:
|
||||
case LTC_ASN1_IA5_STRING:
|
||||
case LTC_ASN1_PRINTABLE_STRING:
|
||||
case LTC_ASN1_UTF8_STRING:
|
||||
case LTC_ASN1_UTCTIME:
|
||||
case LTC_ASN1_SET:
|
||||
case LTC_ASN1_SETOF:
|
||||
case LTC_ASN1_SEQUENCE:
|
||||
case LTC_ASN1_CHOICE:
|
||||
case LTC_ASN1_RAW_BIT_STRING:
|
||||
case LTC_ASN1_TELETEX_STRING:
|
||||
case LTC_ASN1_GENERALIZEDTIME:
|
||||
++x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_EOL:
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate structure for x elements */
|
||||
if (x == 0) {
|
||||
return CRYPT_NOP;
|
||||
}
|
||||
|
||||
list = XCALLOC(x, sizeof(*list));
|
||||
if (list == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* fill in the structure */
|
||||
x = 0;
|
||||
for (;;) {
|
||||
type = (ltc_asn1_type)va_arg(a2, int);
|
||||
size = va_arg(a2, unsigned long);
|
||||
data = va_arg(a2, void*);
|
||||
|
||||
if (type == LTC_ASN1_EOL) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case LTC_ASN1_BOOLEAN:
|
||||
case LTC_ASN1_INTEGER:
|
||||
case LTC_ASN1_SHORT_INTEGER:
|
||||
case LTC_ASN1_BIT_STRING:
|
||||
case LTC_ASN1_OCTET_STRING:
|
||||
case LTC_ASN1_NULL:
|
||||
case LTC_ASN1_OBJECT_IDENTIFIER:
|
||||
case LTC_ASN1_IA5_STRING:
|
||||
case LTC_ASN1_PRINTABLE_STRING:
|
||||
case LTC_ASN1_UTF8_STRING:
|
||||
case LTC_ASN1_UTCTIME:
|
||||
case LTC_ASN1_SEQUENCE:
|
||||
case LTC_ASN1_SET:
|
||||
case LTC_ASN1_SETOF:
|
||||
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] */
|
||||
case LTC_ASN1_EOL:
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
err = der_decode_sequence_ex(in, inlen, list, x, flags);
|
||||
XFREE(list);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Decode a SEQUENCE type using a VA list
|
||||
@param in Input buffer
|
||||
@param inlen Length of input in octets
|
||||
@remark <...> is of the form <type, size, data> (int, unsigned long, void*)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
|
||||
{
|
||||
va_list a1, a2;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
|
||||
va_start(a1, inlen);
|
||||
va_start(a2, inlen);
|
||||
|
||||
err = s_der_decode_sequence_va(in, inlen, a1, a2, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_RELAXED);
|
||||
|
||||
va_end(a2);
|
||||
va_end(a1);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Decode a SEQUENCE type using a VA list
|
||||
@param in Input buffer
|
||||
@param inlen Length of input in octets
|
||||
@param flags c.f. enum ltc_der_seq
|
||||
@remark <...> is of the form <type, size, data> (int, unsigned long, void*)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int der_decode_sequence_multi_ex(const unsigned char *in, unsigned long inlen, unsigned int flags, ...)
|
||||
{
|
||||
va_list a1, a2;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
|
||||
va_start(a1, flags);
|
||||
va_start(a2, flags);
|
||||
|
||||
err = s_der_decode_sequence_va(in, inlen, a1, a2, flags);
|
||||
|
||||
va_end(a2);
|
||||
va_end(a1);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
@@ -0,0 +1,202 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
|
||||
/**
|
||||
@file der_encode_sequence_ex.c
|
||||
ASN.1 DER, encode a SEQUENCE, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Encode a SEQUENCE
|
||||
@param list The list of items to encode
|
||||
@param inlen The number of items in the list
|
||||
@param out [out] The destination
|
||||
@param outlen [in/out] The size of the output
|
||||
@param type_of LTC_ASN1_SEQUENCE or LTC_ASN1_SET/LTC_ASN1_SETOF
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int der_encode_sequence_ex(const ltc_asn1_list *list, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen, int type_of)
|
||||
{
|
||||
int err;
|
||||
ltc_asn1_type type;
|
||||
unsigned long size, x, y, z, i;
|
||||
void *data;
|
||||
|
||||
LTC_ARGCHK(list != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
/* get size of output that will be required */
|
||||
y = 0; z = 0;
|
||||
if (der_length_sequence_ex(list, inlen, &y, &z) != CRYPT_OK) return CRYPT_INVALID_ARG;
|
||||
|
||||
/* too big ? */
|
||||
if (*outlen < y) {
|
||||
*outlen = y;
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* store header */
|
||||
x = 0;
|
||||
out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31;
|
||||
|
||||
y = *outlen - x;
|
||||
if ((err = der_encode_asn1_length(z, &out[x], &y)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
x += y;
|
||||
|
||||
/* store data */
|
||||
*outlen -= x;
|
||||
for (i = 0; i < inlen; i++) {
|
||||
type = list[i].type;
|
||||
size = list[i].size;
|
||||
data = list[i].data;
|
||||
|
||||
if (type == LTC_ASN1_EOL) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case LTC_ASN1_BOOLEAN:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_INTEGER:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_SHORT_INTEGER:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_BIT_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_RAW_BIT_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_raw_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_OCTET_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_NULL:
|
||||
out[x] = 0x05;
|
||||
out[x+1] = 0x00;
|
||||
z = 2;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_OBJECT_IDENTIFIER:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_IA5_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_PRINTABLE_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_UTF8_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_UTCTIME:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_GENERALIZEDTIME:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_generalizedtime(data, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_SET:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_SETOF:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_SEQUENCE:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_custom_type(&list[i], out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_CHOICE:
|
||||
case LTC_ASN1_EOL:
|
||||
case LTC_ASN1_TELETEX_STRING:
|
||||
err = CRYPT_INVALID_ARG;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
x += z;
|
||||
*outlen -= z;
|
||||
}
|
||||
*outlen = x;
|
||||
err = CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,142 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
/**
|
||||
@file der_encode_sequence_multi.c
|
||||
ASN.1 DER, encode a SEQUENCE, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Encode a SEQUENCE type using a VA list
|
||||
@param out [out] Destination for data
|
||||
@param outlen [in/out] Length of buffer and resulting length of output
|
||||
@remark <...> is of the form <type, size, data> (int, unsigned long, void*)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
|
||||
{
|
||||
int err;
|
||||
ltc_asn1_type type;
|
||||
unsigned long size, x;
|
||||
void *data;
|
||||
va_list args;
|
||||
ltc_asn1_list *list;
|
||||
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
/* get size of output that will be required */
|
||||
va_start(args, outlen);
|
||||
x = 0;
|
||||
for (;;) {
|
||||
type = (ltc_asn1_type)va_arg(args, int);
|
||||
|
||||
if (type == LTC_ASN1_EOL) {
|
||||
break;
|
||||
}
|
||||
|
||||
size = va_arg(args, unsigned long);
|
||||
data = va_arg(args, void*);
|
||||
LTC_UNUSED_PARAM(size);
|
||||
LTC_UNUSED_PARAM(data);
|
||||
|
||||
switch (type) {
|
||||
case LTC_ASN1_BOOLEAN:
|
||||
case LTC_ASN1_INTEGER:
|
||||
case LTC_ASN1_SHORT_INTEGER:
|
||||
case LTC_ASN1_BIT_STRING:
|
||||
case LTC_ASN1_OCTET_STRING:
|
||||
case LTC_ASN1_NULL:
|
||||
case LTC_ASN1_OBJECT_IDENTIFIER:
|
||||
case LTC_ASN1_IA5_STRING:
|
||||
case LTC_ASN1_PRINTABLE_STRING:
|
||||
case LTC_ASN1_UTF8_STRING:
|
||||
case LTC_ASN1_UTCTIME:
|
||||
case LTC_ASN1_SEQUENCE:
|
||||
case LTC_ASN1_SET:
|
||||
case LTC_ASN1_SETOF:
|
||||
case LTC_ASN1_RAW_BIT_STRING:
|
||||
case LTC_ASN1_GENERALIZEDTIME:
|
||||
++x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_CHOICE:
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
case LTC_ASN1_EOL:
|
||||
case LTC_ASN1_TELETEX_STRING:
|
||||
va_end(args);
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
/* allocate structure for x elements */
|
||||
if (x == 0) {
|
||||
return CRYPT_NOP;
|
||||
}
|
||||
|
||||
list = XCALLOC(x, sizeof(*list));
|
||||
if (list == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* fill in the structure */
|
||||
va_start(args, outlen);
|
||||
x = 0;
|
||||
for (;;) {
|
||||
type = (ltc_asn1_type)va_arg(args, int);
|
||||
|
||||
if (type == LTC_ASN1_EOL) {
|
||||
break;
|
||||
}
|
||||
|
||||
size = va_arg(args, unsigned long);
|
||||
data = va_arg(args, void*);
|
||||
|
||||
switch (type) {
|
||||
case LTC_ASN1_BOOLEAN:
|
||||
case LTC_ASN1_INTEGER:
|
||||
case LTC_ASN1_SHORT_INTEGER:
|
||||
case LTC_ASN1_BIT_STRING:
|
||||
case LTC_ASN1_OCTET_STRING:
|
||||
case LTC_ASN1_NULL:
|
||||
case LTC_ASN1_OBJECT_IDENTIFIER:
|
||||
case LTC_ASN1_IA5_STRING:
|
||||
case LTC_ASN1_PRINTABLE_STRING:
|
||||
case LTC_ASN1_UTF8_STRING:
|
||||
case LTC_ASN1_UTCTIME:
|
||||
case LTC_ASN1_SEQUENCE:
|
||||
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;
|
||||
|
||||
case LTC_ASN1_CHOICE:
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
case LTC_ASN1_EOL:
|
||||
case LTC_ASN1_TELETEX_STRING:
|
||||
va_end(args);
|
||||
err = CRYPT_INVALID_ARG;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
err = der_encode_sequence(list, x, out, outlen);
|
||||
LBL_ERR:
|
||||
XFREE(list);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
@@ -0,0 +1,38 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_length_sequence.c
|
||||
ASN.1 DER, length a SEQUENCE, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Get the length of a DER sequence
|
||||
@param list The sequences of items in the SEQUENCE
|
||||
@param inlen The number of items
|
||||
@param outlen [out] The length required in octets to store it
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
|
||||
int der_flexi_sequence_cmp(const ltc_asn1_list *flexi, der_flexi_check *check)
|
||||
{
|
||||
ltc_asn1_list *cur;
|
||||
if (flexi->type != LTC_ASN1_SEQUENCE) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
cur = flexi->child;
|
||||
while(check->t != LTC_ASN1_EOL) {
|
||||
if (!LTC_ASN1_IS_TYPE(cur, check->t)) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
if (check->pp != NULL) *check->pp = cur;
|
||||
cur = cur->next;
|
||||
check++;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,179 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_length_sequence.c
|
||||
ASN.1 DER, length a SEQUENCE, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Get the length of a DER sequence
|
||||
@param list The sequences of items in the SEQUENCE
|
||||
@param inlen The number of items
|
||||
@param outlen [out] The length required in octets to store it
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int der_length_sequence(const ltc_asn1_list *list, unsigned long inlen,
|
||||
unsigned long *outlen)
|
||||
{
|
||||
return der_length_sequence_ex(list, inlen, outlen, NULL);
|
||||
}
|
||||
|
||||
int der_length_sequence_ex(const ltc_asn1_list *list, unsigned long inlen,
|
||||
unsigned long *outlen, unsigned long *payloadlen)
|
||||
{
|
||||
int err;
|
||||
ltc_asn1_type type;
|
||||
unsigned long size, x, y, i;
|
||||
void *data;
|
||||
|
||||
LTC_ARGCHK(list != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
/* get size of output that will be required */
|
||||
y = 0;
|
||||
for (i = 0; i < inlen; i++) {
|
||||
type = list[i].type;
|
||||
size = list[i].size;
|
||||
data = list[i].data;
|
||||
|
||||
if (type == LTC_ASN1_EOL) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* some items may be optional during import */
|
||||
if (!list[i].used && list[i].optional) continue;
|
||||
|
||||
switch (type) {
|
||||
case LTC_ASN1_BOOLEAN:
|
||||
if ((err = der_length_boolean(&x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
y += x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_INTEGER:
|
||||
if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
y += x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_SHORT_INTEGER:
|
||||
if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
y += x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_BIT_STRING:
|
||||
case LTC_ASN1_RAW_BIT_STRING:
|
||||
if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
y += x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_OCTET_STRING:
|
||||
if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
y += x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_NULL:
|
||||
y += 2;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_OBJECT_IDENTIFIER:
|
||||
if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
y += x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_IA5_STRING:
|
||||
if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
y += x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_TELETEX_STRING:
|
||||
if ((err = der_length_teletex_string(data, size, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
y += x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_PRINTABLE_STRING:
|
||||
if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
y += x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_UTCTIME:
|
||||
if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
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;
|
||||
}
|
||||
y += x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
if ((err = der_length_custom_type(&list[i], &x, NULL)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
y += x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_SET:
|
||||
case LTC_ASN1_SETOF:
|
||||
case LTC_ASN1_SEQUENCE:
|
||||
if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
y += x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_CHOICE:
|
||||
case LTC_ASN1_EOL:
|
||||
err = CRYPT_INVALID_ARG;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if ((err = der_length_asn1_length(y, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
if (payloadlen != NULL) {
|
||||
*payloadlen = y;
|
||||
}
|
||||
|
||||
/* store size */
|
||||
*outlen = y + x + 1;
|
||||
err = CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_sequence_free.c
|
||||
ASN.1 DER, free's a structure allocated by der_decode_sequence_flexi(), Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Free memory allocated by der_decode_sequence_flexi()
|
||||
@param in The list to free
|
||||
*/
|
||||
void der_sequence_free(ltc_asn1_list *in)
|
||||
{
|
||||
ltc_asn1_list *l;
|
||||
|
||||
if (!in) return;
|
||||
|
||||
/* walk to the start of the chain */
|
||||
while (in->prev != NULL || in->parent != NULL) {
|
||||
if (in->parent != NULL) {
|
||||
in = in->parent;
|
||||
} else {
|
||||
in = in->prev;
|
||||
}
|
||||
}
|
||||
|
||||
/* now walk the list and free stuff */
|
||||
while (in != NULL) {
|
||||
/* is there a child? */
|
||||
if (in->child) {
|
||||
/* disconnect */
|
||||
in->child->parent = NULL;
|
||||
der_sequence_free(in->child);
|
||||
}
|
||||
|
||||
switch (in->type) {
|
||||
case LTC_ASN1_SETOF: break;
|
||||
case LTC_ASN1_INTEGER : if (in->data != NULL) { ltc_mp_clear(in->data); } break;
|
||||
default : if (in->data != NULL) { XFREE(in->data); }
|
||||
}
|
||||
|
||||
/* move to next and free current */
|
||||
l = in->next;
|
||||
XFREE(in);
|
||||
in = l;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_sequence_shrink.c
|
||||
Free memory allocated for CONSTRUCTED, SET or SEQUENCE elements by der_decode_sequence_flexi(), Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Free memory allocated for CONSTRUCTED,
|
||||
SET or SEQUENCE elements by der_decode_sequence_flexi()
|
||||
@param in The list to shrink
|
||||
*/
|
||||
void der_sequence_shrink(ltc_asn1_list *in)
|
||||
{
|
||||
if (!in) return;
|
||||
|
||||
/* now walk the list and free stuff */
|
||||
while (in != NULL) {
|
||||
/* is there a child? */
|
||||
if (in->child) {
|
||||
der_sequence_shrink(in->child);
|
||||
}
|
||||
|
||||
switch (in->type) {
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
case LTC_ASN1_SET:
|
||||
case LTC_ASN1_SEQUENCE : if (in->data != NULL) { XFREE(in->data); in->data = NULL; } break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
/* move to next and free current */
|
||||
in = in->next;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user