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 */
21static 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
43static 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*/
67int 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 $ */
104