- static auto nid(OBJ_create("1.2.840.113635.100.9.1", "", ""));
- _assert(PKCS7_add_signed_attribute(info, nid, V_ASN1_OCTET_STRING, string));
- } catch (...) {
- ASN1_OCTET_STRING_free(string);
- throw;
+ for (Algorithm *pointer : GetAlgorithms()) {
+ Algorithm &algorithm(*pointer);
+ APPLE_CDHASH *cdhash(APPLE_CDHASH_new());
+ _assert(cdhash != NULL);
+ _assert(sk_push((_STACK *) cdattr->cdhashes, cdhash) != 0);
+ cdhash->algorithm = OBJ_nid2obj(algorithm.nid_);
+ Octet string(algorithm[hash], algorithm.size_);
+ cdhash->value = string;
+ string.release();
+ }
+
+ // in e20b57270dece66ce2c68aeb5d14dd6d9f3c5d68 OpenSSL removed a "hack"
+ // in the process, they introduced a useful bug in X509_ATTRIBUTE_set1_data
+ // however, I don't want to rely on that or detect the bypass before it
+ // so, instead, I create my own compatible attribute and re-serialize it :/
+
+ ASN1_STRING *seq(ASN1_STRING_new());
+ _assert(seq != NULL);
+ _scope({ ASN1_STRING_free(seq); });
+ seq->length = ASN1_item_i2d((ASN1_VALUE *) cdattr, &seq->data, ASN1_ITEM_rptr(APPLE_CDATTR));
+
+ X509_ATTRIBUTE *attribute(NULL);
+ const unsigned char *data(seq->data);
+ _assert(d2i_X509_ATTRIBUTE(&attribute, &data, seq->length) != 0);
+ _assert(attribute != NULL);
+ _assert(sk_X509_ATTRIBUTE_push(attributes, attribute) != 0);
+ }
+
+ {
+ // XXX: move the "cdhashes" plist code to here and remove xml argument
+
+ Octet string(xml);
+ static auto nid(OBJ_create("1.2.840.113635.100.9.1", "apple-1", "Apple 1"));
+ auto attribute(X509_ATTRIBUTE_create(nid, V_ASN1_OCTET_STRING, string));
+ _assert(attribute != NULL);
+ string.release();
+ _assert(sk_X509_ATTRIBUTE_push(attributes, attribute) != 0);