#include <stddef.h>
+#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
int skcontlen, sklen;
ASN1_VALUE *skitem;
if(!*pval) return 0;
- isset = flags & ASN1_TFLG_SET_OF;
+ if(flags & ASN1_TFLG_SET_OF) {
+ isset = 1;
+ /* 2 means we reorder */
+ if(flags & ASN1_TFLG_SEQUENCE_OF) isset = 2;
+ } else isset = 0;
/* First work out inner tag value */
if(flags & ASN1_TFLG_IMPTAG) {
sktag = tt->tag;
skcontlen = 0;
for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
skitem = sk_ASN1_VALUE_value(sk, i);
- skcontlen += ASN1_item_ex_i2d(&skitem, NULL, tt->item, -1, 0);
+ skcontlen += ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), -1, 0);
}
sklen = ASN1_object_size(1, skcontlen, sktag);
/* If EXPLICIT need length of surrounding tag */
/* SET or SEQUENCE and IMPLICIT tag */
ASN1_put_object(out, 1, skcontlen, sktag, skaclass);
/* And finally the stuff itself */
- asn1_set_seq_out(sk, out, skcontlen, tt->item, isset);
+ asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), isset);
return ret;
}
if(flags & ASN1_TFLG_EXPTAG) {
/* EXPLICIT tagging */
/* Find length of tagged item */
- i = ASN1_item_ex_i2d(pval, NULL, tt->item, -1, 0);
+ i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, 0);
if(!i) return 0;
/* Find length of EXPLICIT tag */
ret = ASN1_object_size(1, i, tt->tag);
if(out) {
/* Output tag and item */
ASN1_put_object(out, 1, i, tt->tag, aclass);
- ASN1_item_ex_i2d(pval, out, tt->item, -1, 0);
+ ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, 0);
}
return ret;
}
if(flags & ASN1_TFLG_IMPTAG) {
/* IMPLICIT tagging */
- return ASN1_item_ex_i2d(pval, out, tt->item, tt->tag, aclass);
+ return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), tt->tag, aclass);
}
/* Nothing special: treat as normal */
- return ASN1_item_ex_i2d(pval, out, tt->item, -1, 0);
+ return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, 0);
}
/* Temporary structure used to hold DER encoding of items for SET OF */
typedef struct {
unsigned char *data;
int length;
+ ASN1_VALUE *field;
} DER_ENC;
static int der_cmp(const void *a, const void *b)
{
int i;
ASN1_VALUE *skitem;
- unsigned char *tmpdat, *p;
- DER_ENC *derlst, *tder;
+ unsigned char *tmpdat = NULL, *p = NULL;
+ DER_ENC *derlst = NULL, *tder;
if(do_sort) {
/* Don't need to sort less than 2 items */
if(sk_ASN1_VALUE_num(sk) < 2) do_sort = 0;
skitem = sk_ASN1_VALUE_value(sk, i);
tder->data = p;
tder->length = ASN1_item_i2d(skitem, &p, item);
+ tder->field = skitem;
}
/* Now sort them */
qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
p += tder->length;
}
*out = p;
+ /* If do_sort is 2 then reorder the STACK */
+ if(do_sort == 2) {
+ for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
+ sk_ASN1_VALUE_set(sk, i, tder->field);
+ }
OPENSSL_free(derlst);
OPENSSL_free(tmpdat);
return 1;