/* v3_conf.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type, X509V3_CTX *ctx);
static char *conf_lhash_get_string(void *db, char *section, char *value);
static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section);
-static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid,
- int crit, void *ext_struc);
+static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
+ int crit, void *ext_struc);
static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len);
/* CONF *conf: Config file */
/* char *name: Name */
/* char *value: Value */
X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
- char *value)
+ char *value)
{
int crit;
int ext_type;
ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
if (!ret)
{
- X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_ERROR_IN_EXTENSION);
+ X509V3err(X509V3_F_X509V3_EXT_NCONF,X509V3_R_ERROR_IN_EXTENSION);
ERR_add_error_data(4,"name=", name, ", value=", value);
}
return ret;
/* CONF *conf: Config file */
/* char *value: Value */
X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
- char *value)
+ char *value)
{
int crit;
int ext_type;
/* CONF *conf: Config file */
/* char *value: Value */
static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
- int crit, char *value)
+ int crit, char *value)
{
- X509V3_EXT_METHOD *method;
+ 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_CONF,X509V3_R_UNKNOWN_EXTENSION_NAME);
+ 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_CONF,X509V3_R_UNKNOWN_EXTENSION);
+ X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_UNKNOWN_EXTENSION);
return NULL;
}
/* Now get internal extension representation based on type */
{
if(*value == '@') nval = NCONF_get_section(conf, value + 1);
else nval = X509V3_parse_list(value);
- if(!nval)
+ if(sk_CONF_VALUE_num(nval) <= 0)
{
- X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_INVALID_EXTENSION_STRING);
+ 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;
}
}
else if(method->r2i)
{
- if(!ctx->db)
+ if(!ctx->db || !ctx->db_meth)
{
- X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_NO_CONFIG_DATABASE);
+ 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_X509V3_EXT_CONF,X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
+ X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
return NULL;
}
}
-static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid,
- int crit, void *ext_struc)
+static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
+ int crit, void *ext_struc)
{
unsigned char *ext_der;
int ext_len;
X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
{
- X509V3_EXT_METHOD *method;
+ const X509V3_EXT_METHOD *method;
if (!(method = X509V3_EXT_get_nid(ext_nid))) {
X509V3err(X509V3_F_X509V3_EXT_I2D,X509V3_R_UNKNOWN_EXTENSION);
return NULL;
{
int gen_type = 0;
char *p = *value;
- if ((strlen(p) >= 4) && !strncmp(p, "DER:,", 4))
+ if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4))
{
p+=4;
gen_type = 1;
}
- if ((strlen(p) >= 5) && !strncmp(p, "ASN1:,", 5))
+ else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5))
{
p+=5;
gen_type = 2;
/* Create a generic extension: for now just handle DER type */
static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
- int crit, int gen_type, X509V3_CTX *ctx)
+ int crit, int gen_type,
+ X509V3_CTX *ctx)
{
unsigned char *ext_der=NULL;
long ext_len;
return ext_der;
}
+static void delete_ext(STACK_OF(X509_EXTENSION) *sk, X509_EXTENSION *dext)
+ {
+ int idx;
+ ASN1_OBJECT *obj;
+ obj = X509_EXTENSION_get_object(dext);
+ while ((idx = X509v3_get_ext_by_OBJ(sk, obj, -1)) >= 0)
+ {
+ X509_EXTENSION *tmpext = X509v3_get_ext(sk, idx);
+ X509v3_delete_ext(sk, idx);
+ X509_EXTENSION_free(tmpext);
+ }
+ }
+
/* This is the main function: add a bunch of extensions based on a config file
* section to an extension STACK.
*/
int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
- STACK_OF(X509_EXTENSION) **sk)
+ STACK_OF(X509_EXTENSION) **sk)
{
X509_EXTENSION *ext;
STACK_OF(CONF_VALUE) *nval;
val = sk_CONF_VALUE_value(nval, i);
if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
return 0;
+ if (ctx->flags == X509V3_CTX_REPLACE)
+ delete_ext(*sk, ext);
if (sk) X509v3_add_ext(sk, ext, -1);
X509_EXTENSION_free(ext);
}
/* Convenience functions to add extensions to a certificate, CRL and request */
int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
- X509 *cert)
+ X509 *cert)
{
STACK_OF(X509_EXTENSION) **sk = NULL;
if (cert)
/* Same as above but for a CRL */
int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
- X509_CRL *crl)
+ X509_CRL *crl)
{
STACK_OF(X509_EXTENSION) **sk = NULL;
if (crl)
char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section)
{
+ if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string)
+ {
+ X509V3err(X509V3_F_X509V3_GET_STRING,X509V3_R_OPERATION_NOT_DEFINED);
+ return NULL;
+ }
if (ctx->db_meth->get_string)
return ctx->db_meth->get_string(ctx->db, name, section);
return NULL;
STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section)
{
+ if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section)
+ {
+ X509V3err(X509V3_F_X509V3_GET_SECTION,X509V3_R_OPERATION_NOT_DEFINED);
+ return NULL;
+ }
if (ctx->db_meth->get_section)
return ctx->db_meth->get_section(ctx->db, section);
return NULL;
}
void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
- X509_CRL *crl, int flags)
+ X509_CRL *crl, int flags)
{
ctx->issuer_cert = issuer;
ctx->subject_cert = subj;
/* Old conf compatibility functions */
-X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name,
- char *value)
+X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+ char *name, char *value)
{
CONF ctmp;
CONF_set_nconf(&ctmp, conf);
/* LHASH *conf: Config file */
/* char *value: Value */
-X509_EXTENSION *X509V3_EXT_conf_nid(LHASH *conf, X509V3_CTX *ctx, int ext_nid,
- char *value)
+X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+ int ext_nid, char *value)
{
CONF ctmp;
CONF_set_nconf(&ctmp, conf);
NULL
};
-void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash)
+void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash)
{
ctx->db_meth = &conf_lhash_method;
ctx->db = lhash;
}
-int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
- X509 *cert)
+int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+ char *section, X509 *cert)
{
CONF ctmp;
CONF_set_nconf(&ctmp, conf);
/* Same as above but for a CRL */
-int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
- X509_CRL *crl)
+int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+ char *section, X509_CRL *crl)
{
CONF ctmp;
CONF_set_nconf(&ctmp, conf);
/* Add extensions to certificate request */
-int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
- X509_REQ *req)
+int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+ char *section, X509_REQ *req)
{
CONF ctmp;
CONF_set_nconf(&ctmp, conf);