version 0.3.33
[fms.git] / libs / libtomcrypt / 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   * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
10  */
11 #include "tomcrypt.h"
12
13 /**
14   @file der_encode_set.c
15   ASN.1 DER, Encode a SET, Tom St Denis
16 */
17
18 #ifdef LTC_DER
19
20 /* LTC define to ASN.1 TAG */
21 static int ltc_to_asn1(int v)
22 {
23    switch (v) {
24       case LTC_ASN1_BOOLEAN:                 return 0x01;
25       case LTC_ASN1_INTEGER:
26       case LTC_ASN1_SHORT_INTEGER:           return 0x02;
27       case LTC_ASN1_BIT_STRING:              return 0x03;
28       case LTC_ASN1_OCTET_STRING:            return 0x04;
29       case LTC_ASN1_NULL:                    return 0x05;
30       case LTC_ASN1_OBJECT_IDENTIFIER:       return 0x06;
31       case LTC_ASN1_UTF8_STRING:             return 0x0C;
32       case LTC_ASN1_PRINTABLE_STRING:        return 0x13;
33       case LTC_ASN1_IA5_STRING:              return 0x16;
34       case LTC_ASN1_UTCTIME:                 return 0x17;
35       case LTC_ASN1_SEQUENCE:                return 0x30;
36       case LTC_ASN1_SET:
37       case LTC_ASN1_SETOF:                   return 0x31;
38       default: return -1;
39    }
40 }         
41       
42
43 static int qsort_helper(const void *a, const void *b)
44 {
45    ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b;
46    int            r;
47    
48    r = ltc_to_asn1(A->type) - ltc_to_asn1(B->type);
49    
50    /* for QSORT the order is UNDEFINED if they are "equal" which means it is NOT DETERMINISTIC.  So we force it to be :-) */
51    if (r == 0) {
52       /* their order in the original list now determines the position */
53       return A->used - B->used;
54    } else {
55       return r;
56    }
57 }   
58
59 /*
60    Encode a SET type
61    @param list      The list of items to encode
62    @param inlen     The number of items in the list
63    @param out       [out] The destination 
64    @param outlen    [in/out] The size of the output
65    @return CRYPT_OK on success
66 */
67 int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
68                    unsigned char *out,  unsigned long *outlen)
69 {
70    ltc_asn1_list  *copy;
71    unsigned long   x;
72    int             err;
73    
74    /* make copy of list */
75    copy = XCALLOC(inlen, sizeof(*copy));
76    if (copy == NULL) {
77       return CRYPT_MEM;
78    }      
79    
80    /* fill in used member with index so we can fully sort it */
81    for (x = 0; x < inlen; x++) {
82        copy[x]      = list[x];
83        copy[x].used = x;
84    }       
85    
86    /* sort it by the "type" field */
87    XQSORT(copy, inlen, sizeof(*copy), &qsort_helper);   
88    
89    /* call der_encode_sequence_ex() */
90    err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET);   
91    
92    /* free list */
93    XFREE(copy);
94    
95    return err;
96 }                   
97
98
99 #endif
100
101 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/set/der_encode_set.c,v $ */
102 /* $Revision: 1.11 $ */
103 /* $Date: 2006/11/26 02:27:37 $ */