/* sequence */ int i2d_X509_ATTRIBUTE(X509_ATTRIBUTE *a, unsigned char **pp) { int k=0; int r=0,ret=0; unsigned char **p=NULL; if (a == NULL) return(0); p=NULL; for (;;) { if (k) { r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); if (pp == NULL) return(r); p=pp; ASN1_put_object(p,1,ret,V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); } ret+=i2d_ASN1_OBJECT(a->object,p); if (a->set) ret+=i2d_ASN1_SET_OF_ASN1_TYPE(a->value.set,p,(i2d_func_t)i2d_ASN1_TYPE, V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET); else ret+=i2d_ASN1_TYPE(a->value.single,p); if (k++) return(r); } }
static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) { ASN1_TYPE *ret = NULL, *typ = NULL; STACK_OF(ASN1_TYPE) *sk = NULL; STACK_OF(CONF_VALUE) *sect = NULL; unsigned char *der = NULL, *p; int derlen; int i, is_set; sk = sk_ASN1_TYPE_new_null(); if (section) { if (!cnf) goto bad; sect = X509V3_get_section(cnf, (char *)section); if (!sect) goto bad; for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf); if (!typ) goto bad; sk_ASN1_TYPE_push(sk, typ); typ = NULL; } } /* Now we has a STACK of the components, convert to the correct form */ if (utype == V_ASN1_SET) is_set = 1; else is_set = 0; derlen = i2d_ASN1_SET_OF_ASN1_TYPE(sk, NULL, i2d_ASN1_TYPE, utype, V_ASN1_UNIVERSAL, is_set); der = OPENSSL_malloc(derlen); p = der; i2d_ASN1_SET_OF_ASN1_TYPE(sk, &p, i2d_ASN1_TYPE, utype, V_ASN1_UNIVERSAL, is_set); if (!(ret = ASN1_TYPE_new())) goto bad; if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) goto bad; ret->type = utype; ret->value.asn1_string->data = der; ret->value.asn1_string->length = derlen; der = NULL; bad: if (der) OPENSSL_free(der); if (sk) sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); if (typ) ASN1_TYPE_free(typ); if (sect) X509V3_section_free(cnf, sect); return ret; }