/* LibTomCrypt, modular cryptographic library -- Tom St Denis
 *
 * LibTomCrypt is a library that provides various cryptographic
 * algorithms in a highly modular and flexible manner.
 *
 * The library is free for all purposes without any express
 * guarantee it works.
 *
 * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
 */
#include "tomcrypt.h"

/**
  @file der_encode_setof.c
  ASN.1 DER, Encode SET OF, Tom St Denis
*/

#ifdef LTC_DER

struct edge {
   unsigned char *start;
   unsigned long  size;
};

static int qsort_helper(const void *a, const void *b)
{
   struct edge   *A = (struct edge *)a, *B = (struct edge *)b;
   int            r;
   unsigned long  x;
   
   /* compare min length */
   r = XMEMCMP(A->start, B->start, MIN(A->size, B->size));
   
   if (r == 0 && A->size != B->size) {
      if (A->size > B->size) {
         for (x = B->size; x < A->size; x++) {
            if (A->start[x]) {
               return 1;
            }
         }
      } else {
         for (x = A->size; x < B->size; x++) {
            if (B->start[x]) {
               return -1;
            }
         }
      }         
   }
   
   return r;      
}

/**
   Encode a SETOF stucture
   @param list      The list of items to encode
   @param inlen     The number of items in the list
   @param out       [out] The destination 
   @param outlen    [in/out] The size of the output
   @return CRYPT_OK on success
*/   
int der_encode_setof(ltc_asn1_list *list, unsigned long inlen,
                     unsigned char *out,  unsigned long *outlen)
{
   unsigned long  x, y, z, hdrlen;
   int            err;
   struct edge   *edges;
   unsigned char *ptr, *buf;
   
   /* check that they're all the same type */
   for (x = 1; x < inlen; x++) {
      if (list[x].type != list[x-1].type) {
         return CRYPT_INVALID_ARG;
      }
   }

   /* alloc buffer to store copy of output */
   buf = XCALLOC(1, *outlen);
   if (buf == NULL) {
      return CRYPT_MEM;
   }      
                  
   /* encode list */
   if ((err = der_encode_sequence_ex(list, inlen, buf, outlen, LTC_ASN1_SETOF)) != CRYPT_OK) {
       XFREE(buf);
       return err;
   }
   
   /* allocate edges */
   edges = XCALLOC(inlen, sizeof(*edges));
   if (edges == NULL) {
      XFREE(buf);
      return CRYPT_MEM;
   }      
   
   /* skip header */
      ptr = buf + 1;

      /* now skip length data */
      x = *ptr++;
      if (x >= 0x80) {
         ptr += (x & 0x7F);
      }
      
      /* get the size of the static header */
      hdrlen = ((unsigned long)ptr) - ((unsigned long)buf);
      
      
   /* scan for edges */
   x = 0;
   while (ptr < (buf + *outlen)) {
      /* store start */
      edges[x].start = ptr;
      
      /* skip type */
      z = 1;
      
      /* parse length */
      y = ptr[z++];
      if (y < 128) {
         edges[x].size = y;
      } else {
         y &= 0x7F;
         edges[x].size = 0;
         while (y--) {
            edges[x].size = (edges[x].size << 8) | ((unsigned long)ptr[z++]);
         }
      }
      
      /* skip content */
      edges[x].size += z;
      ptr           += edges[x].size;
      ++x;
   }      
      
   /* sort based on contents (using edges) */
   XQSORT(edges, inlen, sizeof(*edges), &qsort_helper);
   
   /* copy static header */
   XMEMCPY(out, buf, hdrlen);
   
   /* copy+sort using edges+indecies to output from buffer */
   for (y = hdrlen, x = 0; x < inlen; x++) {
      XMEMCPY(out+y, edges[x].start, edges[x].size);
      y += edges[x].size;
   }      
   
#ifdef LTC_CLEAN_STACK
   zeromem(buf, *outlen);
#endif      
   
   /* free buffers */
   XFREE(edges);
   XFREE(buf);
   
   return CRYPT_OK;
}

#endif

/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c,v $ */
/* $Revision: 1.11 $ */
/* $Date: 2006/03/31 14:15:35 $ */
