]> pd.if.org Git - zpackage/blob - libtomcrypt/src/pk/asn1/der/set/der_encode_set.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / pk / asn1 / der / set / der_encode_set.c
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  */
9 #include "tomcrypt.h"
10
11 /**
12   @file der_encode_set.c
13   ASN.1 DER, Encode a SET, Tom St Denis
14 */
15
16 #ifdef LTC_DER
17
18 /* LTC define to ASN.1 TAG */
19 static int _ltc_to_asn1(ltc_asn1_type v)
20 {
21    switch (v) {
22       case LTC_ASN1_BOOLEAN:                 return 0x01;
23       case LTC_ASN1_INTEGER:
24       case LTC_ASN1_SHORT_INTEGER:           return 0x02;
25       case LTC_ASN1_RAW_BIT_STRING:
26       case LTC_ASN1_BIT_STRING:              return 0x03;
27       case LTC_ASN1_OCTET_STRING:            return 0x04;
28       case LTC_ASN1_NULL:                    return 0x05;
29       case LTC_ASN1_OBJECT_IDENTIFIER:       return 0x06;
30       case LTC_ASN1_UTF8_STRING:             return 0x0C;
31       case LTC_ASN1_PRINTABLE_STRING:        return 0x13;
32       case LTC_ASN1_TELETEX_STRING:          return 0x14;
33       case LTC_ASN1_IA5_STRING:              return 0x16;
34       case LTC_ASN1_UTCTIME:                 return 0x17;
35       case LTC_ASN1_GENERALIZEDTIME:         return 0x18;
36       case LTC_ASN1_SEQUENCE:                return 0x30;
37       case LTC_ASN1_SET:
38       case LTC_ASN1_SETOF:                   return 0x31;
39       case LTC_ASN1_CHOICE:
40       case LTC_ASN1_CONSTRUCTED:
41       case LTC_ASN1_CONTEXT_SPECIFIC:
42       case LTC_ASN1_EOL:                     return -1;
43    }
44    return -1;
45 }
46
47
48 static int _qsort_helper(const void *a, const void *b)
49 {
50    ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b;
51    int            r;
52
53    r = _ltc_to_asn1(A->type) - _ltc_to_asn1(B->type);
54
55    /* for QSORT the order is UNDEFINED if they are "equal" which means it is NOT DETERMINISTIC.  So we force it to be :-) */
56    if (r == 0) {
57       /* their order in the original list now determines the position */
58       return A->used - B->used;
59    } else {
60       return r;
61    }
62 }
63
64 /*
65    Encode a SET type
66    @param list      The list of items to encode
67    @param inlen     The number of items in the list
68    @param out       [out] The destination
69    @param outlen    [in/out] The size of the output
70    @return CRYPT_OK on success
71 */
72 int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
73                    unsigned char *out,  unsigned long *outlen)
74 {
75    ltc_asn1_list  *copy;
76    unsigned long   x;
77    int             err;
78
79    /* make copy of list */
80    copy = XCALLOC(inlen, sizeof(*copy));
81    if (copy == NULL) {
82       return CRYPT_MEM;
83    }
84
85    /* fill in used member with index so we can fully sort it */
86    for (x = 0; x < inlen; x++) {
87        copy[x]      = list[x];
88        copy[x].used = x;
89    }
90
91    /* sort it by the "type" field */
92    XQSORT(copy, inlen, sizeof(*copy), &_qsort_helper);
93
94    /* call der_encode_sequence_ex() */
95    err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET);
96
97    /* free list */
98    XFREE(copy);
99
100    return err;
101 }
102
103
104 #endif
105
106 /* ref:         $Format:%D$ */
107 /* git commit:  $Format:%H$ */
108 /* commit time: $Format:%ai$ */