1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 /**
6 @file der_encode_set.c
7 ASN.1 DER, Encode a SET, Tom St Denis
8 */
9
10 #ifdef LTC_DER
11
12 /* LTC define to ASN.1 TAG */
s_ltc_to_asn1(ltc_asn1_type v)13 static int s_ltc_to_asn1(ltc_asn1_type v)
14 {
15 return der_asn1_type_to_identifier_map[v];
16 }
17
18
s_qsort_helper(const void * a,const void * b)19 static int s_qsort_helper(const void *a, const void *b)
20 {
21 ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b;
22 int r;
23
24 r = s_ltc_to_asn1(A->type) - s_ltc_to_asn1(B->type);
25
26 /* for QSORT the order is UNDEFINED if they are "equal" which means it is NOT DETERMINISTIC. So we force it to be :-) */
27 if (r == 0) {
28 /* their order in the original list now determines the position */
29 return A->used - B->used;
30 }
31 return r;
32 }
33
34 /*
35 Encode a SET type
36 @param list The list of items to encode
37 @param inlen The number of items in the list
38 @param out [out] The destination
39 @param outlen [in/out] The size of the output
40 @return CRYPT_OK on success
41 */
der_encode_set(const ltc_asn1_list * list,unsigned long inlen,unsigned char * out,unsigned long * outlen)42 int der_encode_set(const ltc_asn1_list *list, unsigned long inlen,
43 unsigned char *out, unsigned long *outlen)
44 {
45 ltc_asn1_list *copy;
46 unsigned long x;
47 int err;
48
49 /* make copy of list */
50 copy = XCALLOC(inlen, sizeof(*copy));
51 if (copy == NULL) {
52 return CRYPT_MEM;
53 }
54
55 /* fill in used member with index so we can fully sort it */
56 for (x = 0; x < inlen; x++) {
57 copy[x] = list[x];
58 copy[x].used = x;
59 }
60
61 /* sort it by the "type" field */
62 XQSORT(copy, inlen, sizeof(*copy), &s_qsort_helper);
63
64 /* call der_encode_sequence_ex() */
65 err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET);
66
67 /* free list */
68 XFREE(copy);
69
70 return err;
71 }
72
73
74 #endif
75