/* v3_crld.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.
*/
/* ====================================================================
- * Copyright (c) 1999, 2005 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include <openssl/asn1t.h>
#include <openssl/x509v3.h>
-static void *v2i_crld(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
-static int i2r_crldp(X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
- int indent);
+static void *v2i_crld(const X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
+ int indent);
-X509V3_EXT_METHOD v3_crld =
+const X509V3_EXT_METHOD v3_crld =
{
NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
0,0,0,0,
NULL
};
+const X509V3_EXT_METHOD v3_freshest_crl =
+ {
+ NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
+ 0,0,0,0,
+ 0,0,
+ 0,
+ v2i_crld,
+ i2r_crldp,0,
+ NULL
+ };
+
static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect)
{
STACK_OF(CONF_VALUE) *gnsect;
return gens;
}
-static int get_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
+static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
CONF_VALUE *cnf)
{
STACK_OF(GENERAL_NAME) *fnm = NULL;
dnsect = X509V3_get_section(ctx, cnf->value);
if (!dnsect)
{
- X509V3err(X509V3_F_GET_DIST_POINT_NAME,
+ X509V3err(X509V3_F_SET_DIST_POINT_NAME,
X509V3_R_SECTION_NOT_FOUND);
return -1;
}
if (sk_X509_NAME_ENTRY_value(rnm,
sk_X509_NAME_ENTRY_num(rnm) - 1)->set)
{
- X509V3err(X509V3_F_GET_DIST_POINT_NAME,
- X509V3_R_INVAID_MULTIPLE_RDNS);
+ X509V3err(X509V3_F_SET_DIST_POINT_NAME,
+ X509V3_R_INVALID_MULTIPLE_RDNS);
goto err;
}
}
if (*pdp)
{
- X509V3err(X509V3_F_GET_DIST_POINT_NAME,
+ X509V3err(X509V3_F_SET_DIST_POINT_NAME,
X509V3_R_DISTPOINT_ALREADY_SET);
goto err;
}
return -1;
}
-
static const BIT_STRING_BITNAME reason_flags[] = {
+{0, "Unused", "unused"},
{1, "Key Compromise", "keyCompromise"},
{2, "CA Compromise", "CACompromise"},
{3, "Affiliation Changed", "affiliationChanged"},
{
int ret;
cnf = sk_CONF_VALUE_value(nval, i);
- ret = get_dist_point_name(&point->distpoint, ctx, cnf);
+ ret = set_dist_point_name(&point->distpoint, ctx, cnf);
if (ret > 0)
continue;
if (ret < 0)
return NULL;
}
-static void *v2i_crld(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+static void *v2i_crld(const X509V3_EXT_METHOD *method,
+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
{
STACK_OF(DIST_POINT) *crld = NULL;
GENERAL_NAMES *gens = NULL;
IMPLEMENT_STACK_OF(DIST_POINT)
IMPLEMENT_ASN1_SET_OF(DIST_POINT)
+static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
+ {
+ DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
+
+ switch(operation)
+ {
+ case ASN1_OP_NEW_POST:
+ dpn->dpname = NULL;
+ break;
+
+ case ASN1_OP_FREE_POST:
+ if (dpn->dpname)
+ X509_NAME_free(dpn->dpname);
+ break;
+ }
+ return 1;
+ }
+
-ASN1_CHOICE(DIST_POINT_NAME) = {
+ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = {
ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
-} ASN1_CHOICE_END(DIST_POINT_NAME)
+} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type)
+
IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME)
ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5)
} ASN1_SEQUENCE_END(ISSUING_DIST_POINT)
-static int i2r_idp(X509V3_EXT_METHOD *method,
- void *pidp, BIO *out, int indent);
+IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
+
+static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
+ int indent);
+static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval);
-X509V3_EXT_METHOD v3_idp =
+const X509V3_EXT_METHOD v3_idp =
{
NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
ASN1_ITEM_ref(ISSUING_DIST_POINT),
0,0,0,0,
0,0,
- 0,0,
+ 0,
+ v2i_idp,
i2r_idp,0,
NULL
};
+static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+ STACK_OF(CONF_VALUE) *nval)
+ {
+ ISSUING_DIST_POINT *idp = NULL;
+ CONF_VALUE *cnf;
+ char *name, *val;
+ int i, ret;
+ idp = ISSUING_DIST_POINT_new();
+ if (!idp)
+ goto merr;
+ for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
+ {
+ cnf = sk_CONF_VALUE_value(nval, i);
+ name = cnf->name;
+ val = cnf->value;
+ ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
+ if (ret > 0)
+ continue;
+ if (ret < 0)
+ goto err;
+ if (!strcmp(name, "onlyuser"))
+ {
+ if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
+ goto err;
+ }
+ else if (!strcmp(name, "onlyCA"))
+ {
+ if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
+ goto err;
+ }
+ else if (!strcmp(name, "onlyAA"))
+ {
+ if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
+ goto err;
+ }
+ else if (!strcmp(name, "indirectCRL"))
+ {
+ if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
+ goto err;
+ }
+ else if (!strcmp(name, "onlysomereasons"))
+ {
+ if (!set_reasons(&idp->onlysomereasons, val))
+ goto err;
+ }
+ else
+ {
+ X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME);
+ X509V3_conf_err(cnf);
+ goto err;
+ }
+ }
+ return idp;
+
+ merr:
+ X509V3err(X509V3_F_V2I_IDP,ERR_R_MALLOC_FAILURE);
+ err:
+ ISSUING_DIST_POINT_free(idp);
+ return NULL;
+ }
+
static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
{
int i;
return 1;
}
-static int i2r_idp(X509V3_EXT_METHOD *method, void *pidp, BIO *out, int indent)
+static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
+ int indent)
{
ISSUING_DIST_POINT *idp = pidp;
if (idp->distpoint)
return 1;
}
-static int i2r_crldp(X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
- int indent)
+static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
+ int indent)
{
STACK_OF(DIST_POINT) *crld = pcrldp;
DIST_POINT *point;
}
return 1;
}
+
+int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname)
+ {
+ int i;
+ STACK_OF(X509_NAME_ENTRY) *frag;
+ X509_NAME_ENTRY *ne;
+ if (!dpn || (dpn->type != 1))
+ return 1;
+ frag = dpn->name.relativename;
+ dpn->dpname = X509_NAME_dup(iname);
+ if (!dpn->dpname)
+ return 0;
+ for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++)
+ {
+ ne = sk_X509_NAME_ENTRY_value(frag, i);
+ if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1))
+ {
+ X509_NAME_free(dpn->dpname);
+ dpn->dpname = NULL;
+ return 0;
+ }
+ }
+ /* generate cached encoding of name */
+ if (i2d_X509_NAME(dpn->dpname, NULL) < 0)
+ {
+ X509_NAME_free(dpn->dpname);
+ dpn->dpname = NULL;
+ return 0;
+ }
+ return 1;
+ }