Home | History | Annotate | Download | only in set
      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 (at) 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 $ */
    104