示例#1
0
/*
   Encode a SET type
   @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_set(ltc_asn1_list *list, unsigned long inlen,
                   unsigned char *out,  unsigned long *outlen)
{
   ltc_asn1_list  *copy;
   unsigned long   x;
   int             err;

   /* make copy of list */
   copy = XCALLOC(inlen, sizeof(*copy));
   if (copy == NULL) {
      return CRYPT_MEM;
   }

   /* fill in used member with index so we can fully sort it */
   for (x = 0; x < inlen; x++) {
       copy[x]      = list[x];
       copy[x].used = x;
   }

   /* sort it by the "type" field */
   XQSORT(copy, inlen, sizeof(*copy), &qsort_helper);

   /* call der_encode_sequence_ex() */
   err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET);

   /* free list */
   XFREE(copy);

   return err;
}
示例#2
0
/**
   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;
}