Changes between 0.9.6 and 0.9.7 [xx XXX 2000]
+ *) Add a special meaning when SET OF and SEQUENCE OF flags are both
+ set (this was treated exactly the same as SET OF previously). This
+ is used to reorder the STACK representing the structure to match the
+ encoding. This will be used to get round a problem where a PKCS7
+ structure which was signed could not be verified because the STACK
+ order did not reflect the encoded order.
+ [Steve Henson]
+
*) Reimplement the OCSP ASN1 module using the new code.
[Steve Henson]
/* Field is a SEQUENCE OF */
#define ASN1_TFLG_SEQUENCE_OF (0x2 << 1)
+/* Special case: this refers to a SET OF that
+ * will be sorted into DER order when encoded *and*
+ * the corresponding STACK will be modified to match
+ * the new order.
+ */
+#define ASN1_TFLG_SET_ORDER (0x3 << 1)
+
+/* Mask for SET OF or SEQUENCE OF */
#define ASN1_TFLG_SK_MASK (0x3 << 1)
/* These flags mean the tag should be taken from the
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;
typedef struct {
unsigned char *data;
int length;
+ ASN1_VALUE *field;
} DER_ENC;
static int der_cmp(const void *a, const void *b)
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;
ASN1_SIMPLE(PKCS7_SIGNER_INFO, version, ASN1_INTEGER),
ASN1_SIMPLE(PKCS7_SIGNER_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL),
ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_alg, X509_ALGOR),
- ASN1_IMP_SET_OF_OPT(PKCS7_SIGNER_INFO, auth_attr, X509_ATTRIBUTE, 0),
+ /* NB this should be a SET OF but we use a SEQUENCE OF so the original order
+ * is retained when the structure is reencoded.
+ */
+ ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNER_INFO, auth_attr, X509_ATTRIBUTE, 0),
ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_enc_alg, X509_ALGOR),
ASN1_SIMPLE(PKCS7_SIGNER_INFO, enc_digest, ASN1_OCTET_STRING),
ASN1_IMP_SET_OF_OPT(PKCS7_SIGNER_INFO, unauth_attr, X509_ATTRIBUTE, 1)