- X509_EXTENSION *ext = NULL;
- X509V3_EXT_METHOD *method;
- STACK *nval;
- char *ext_struc;
- char *ext_der, *p;
- int ext_len;
- ASN1_OCTET_STRING *ext_oct;
- if(ext_nid == NID_undef) {
- X509V3err(X509V3_F_DO_EXT_CONF,X509V3_R_UNKNOWN_EXTENSION_NAME);
- return NULL;
- }
- if(!(method = X509V3_EXT_get_nid(ext_nid))) {
- X509V3err(X509V3_F_DO_EXT_CONF,X509V3_R_UNKNOWN_EXTENSION);
- return NULL;
- }
- /* Now get internal extension representation based on type */
- if(method->v2i) {
- if(*value == '@') nval = CONF_get_section(conf, value + 1);
- else nval = X509V3_parse_list(value);
- if(!nval) {
- X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_INVALID_EXTENSION_STRING);
- ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value);
- return NULL;
- }
- ext_struc = method->v2i(method, ctx, nval);
- if(*value != '@') sk_pop_free(nval, X509V3_conf_free);
- if(!ext_struc) return NULL;
- } else if(method->s2i) {
- if(!(ext_struc = method->s2i(method, ctx, value))) return NULL;
- } else if(method->r2i) {
- if(!ctx->db) {
- X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_NO_CONFIG_DATABASE);
- return NULL;
- }
- if(!(ext_struc = method->r2i(method, ctx, value))) return NULL;
- } else {
- X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
- ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
- return NULL;
- }
-
- /* We've now got the internal representation: convert to DER */
- ext_len = method->i2d(ext_struc, NULL);
- ext_der = Malloc(ext_len);
- p = ext_der;
- method->i2d(ext_struc, &p);
- method->ext_free(ext_struc);
- ext_oct = ASN1_OCTET_STRING_new();
- ext_oct->data = ext_der;
- ext_oct->length = ext_len;
-
- ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
- ASN1_OCTET_STRING_free(ext_oct);
-
- return ext;
+ const X509V3_EXT_METHOD *method;
+ X509_EXTENSION *ext;
+ STACK_OF(CONF_VALUE) *nval;
+ void *ext_struc;
+ if (ext_nid == NID_undef) {
+ X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION_NAME);
+ return NULL;
+ }
+ if (!(method = X509V3_EXT_get_nid(ext_nid))) {
+ X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION);
+ return NULL;
+ }
+ /* Now get internal extension representation based on type */
+ if (method->v2i) {
+ if (*value == '@')
+ nval = NCONF_get_section(conf, value + 1);
+ else
+ nval = X509V3_parse_list(value);
+ if (sk_CONF_VALUE_num(nval) <= 0) {
+ X509V3err(X509V3_F_DO_EXT_NCONF,
+ X509V3_R_INVALID_EXTENSION_STRING);
+ ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=",
+ value);
+ return NULL;
+ }
+ ext_struc = method->v2i(method, ctx, nval);
+ if (*value != '@')
+ sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
+ if (!ext_struc)
+ return NULL;
+ } else if (method->s2i) {
+ if (!(ext_struc = method->s2i(method, ctx, value)))
+ return NULL;
+ } else if (method->r2i) {
+ if (!ctx->db || !ctx->db_meth) {
+ X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_NO_CONFIG_DATABASE);
+ return NULL;
+ }
+ if (!(ext_struc = method->r2i(method, ctx, value)))
+ return NULL;
+ } else {
+ X509V3err(X509V3_F_DO_EXT_NCONF,
+ X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
+ ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
+ return NULL;
+ }
+
+ ext = do_ext_i2d(method, ext_nid, crit, ext_struc);
+ if (method->it)
+ ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
+ else
+ method->ext_free(ext_struc);
+ return ext;