summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crypto/asn1/asn1t.h7
-rw-r--r--crypto/asn1/tasn_new.c86
-rw-r--r--crypto/asn1/tasn_utl.c13
-rw-r--r--crypto/asn1/x_bignum.c1
-rw-r--r--crypto/asn1/x_long.c1
-rw-r--r--crypto/asn1/x_name.c1
6 files changed, 82 insertions, 27 deletions
diff --git a/crypto/asn1/asn1t.h b/crypto/asn1/asn1t.h
index 3ff1b7ae8..3ed21d474 100644
--- a/crypto/asn1/asn1t.h
+++ b/crypto/asn1/asn1t.h
@@ -544,6 +544,7 @@ typedef struct ASN1_EXTERN_FUNCS_st {
void *app_data;
ASN1_ex_new_func *asn1_ex_new;
ASN1_ex_free_func *asn1_ex_free;
+ ASN1_ex_free_func *asn1_ex_clear;
ASN1_ex_d2i *asn1_ex_d2i;
ASN1_ex_i2d *asn1_ex_i2d;
} ASN1_EXTERN_FUNCS;
@@ -553,6 +554,7 @@ typedef struct ASN1_PRIMITIVE_FUNCS_st {
unsigned long flags;
ASN1_ex_new_func *prim_new;
ASN1_ex_free_func *prim_free;
+ ASN1_ex_free_func *prim_clear;
ASN1_primitive_c2i *prim_c2i;
ASN1_primitive_i2c *prim_i2c;
} ASN1_PRIMITIVE_FUNCS;
@@ -712,10 +714,11 @@ int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char
int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it);
+
ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+
const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr);
-int asn1_template_is_bool(const ASN1_TEMPLATE *tt);
-int asn1_item_is_bool(const ASN1_ITEM *it);
+
int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c
index 17c8de5ab..d6f115592 100644
--- a/crypto/asn1/tasn_new.c
+++ b/crypto/asn1/tasn_new.c
@@ -64,6 +64,9 @@
#include <openssl/asn1t.h>
static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine);
+static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
{
@@ -173,23 +176,53 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int
ASN1err(ASN1_F_ASN1_ITEM_NEW, ASN1_R_AUX_ERROR);
ASN1_item_ex_free(pval, it);
return 0;
-
+
+}
+
+static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ const ASN1_EXTERN_FUNCS *ef;
+
+ switch(it->itype) {
+
+ case ASN1_ITYPE_EXTERN:
+ ef = it->funcs;
+ if(ef && ef->asn1_ex_clear)
+ ef->asn1_ex_clear(pval, it);
+ else *pval = NULL;
+ break;
+
+
+ case ASN1_ITYPE_PRIMITIVE:
+ if(it->templates)
+ asn1_template_clear(pval, it->templates);
+ else
+ asn1_primitive_clear(pval, it);
+ break;
+
+ case ASN1_ITYPE_MSTRING:
+ asn1_primitive_clear(pval, it);
+ break;
+
+ case ASN1_ITYPE_COMPAT:
+ case ASN1_ITYPE_CHOICE:
+ case ASN1_ITYPE_SEQUENCE:
+ *pval = NULL;
+ break;
+ }
}
+
int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
{
const ASN1_ITEM *it = tt->item;
- /* Special BOOLEAN handling */
- if(asn1_template_is_bool(tt))
- return ASN1_item_ex_new(pval, it);
-
- /* If OPTIONAL or ANY DEFINED BY nothing to do */
-
- /* FIXME: OPTIONAL shouldn't really do this in general
- * because it needs to set the type to its "undefined"
- * state which may not be NULL.
- */
- if(tt->flags & (ASN1_TFLG_OPTIONAL|ASN1_TFLG_ADB_MASK)) {
+ if(tt->flags & ASN1_TFLG_OPTIONAL) {
+ asn1_template_clear(pval, tt);
+ return 1;
+ }
+ /* If ANY DEFINED BY nothing to do */
+
+ if(tt->flags & ASN1_TFLG_ADB_MASK) {
*pval = NULL;
return 1;
}
@@ -208,6 +241,16 @@ int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
return asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
}
+void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+ /* If ADB or STACK just NULL the field */
+ if(tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK))
+ *pval = NULL;
+ else
+ asn1_item_clear(pval, tt->item);
+}
+
+
/* NB: could probably combine most of the real XXX_new() behaviour and junk all the old
* functions.
*/
@@ -249,3 +292,22 @@ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
if(*pval) return 1;
return 0;
}
+
+void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ int utype;
+ const ASN1_PRIMITIVE_FUNCS *pf;
+ pf = it->funcs;
+ if(pf) {
+ if(pf->prim_clear)
+ pf->prim_clear(pval, it);
+ else
+ *pval = NULL;
+ return;
+ }
+ if(!it || (it->itype == ASN1_ITYPE_MSTRING)) utype = -1;
+ else utype = it->utype;
+ if(utype == V_ASN1_BOOLEAN)
+ *(ASN1_BOOLEAN *)pval = it->size;
+ else *pval = NULL;
+}
diff --git a/crypto/asn1/tasn_utl.c b/crypto/asn1/tasn_utl.c
index c3319f248..16b2c1478 100644
--- a/crypto/asn1/tasn_utl.c
+++ b/crypto/asn1/tasn_utl.c
@@ -250,16 +250,3 @@ const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int
if(nullerr) ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
return NULL;
}
-
-int asn1_template_is_bool(const ASN1_TEMPLATE *tt)
-{
- if(tt->flags & ASN1_TFLG_SK_MASK) return 0;
- else return asn1_item_is_bool(tt->item);
-}
-
-int asn1_item_is_bool(const ASN1_ITEM *it)
-{
- if((it->utype == V_ASN1_BOOLEAN) &&
- (it->itype == ASN1_ITYPE_PRIMITIVE)) return 1;
- return 0;
-}
diff --git a/crypto/asn1/x_bignum.c b/crypto/asn1/x_bignum.c
index 8f84f9412..6d59f5c8b 100644
--- a/crypto/asn1/x_bignum.c
+++ b/crypto/asn1/x_bignum.c
@@ -78,6 +78,7 @@ static ASN1_PRIMITIVE_FUNCS bignum_pf = {
NULL, 0,
bn_new,
bn_free,
+ 0,
bn_c2i,
bn_i2c
};
diff --git a/crypto/asn1/x_long.c b/crypto/asn1/x_long.c
index 46c67fdcf..845bc2df0 100644
--- a/crypto/asn1/x_long.c
+++ b/crypto/asn1/x_long.c
@@ -75,6 +75,7 @@ static ASN1_PRIMITIVE_FUNCS long_pf = {
NULL, 0,
long_new,
long_free,
+ long_free, /* Clear should set to initial value */
long_c2i,
long_i2c
};
diff --git a/crypto/asn1/x_name.c b/crypto/asn1/x_name.c
index 84abedc9e..5da066949 100644
--- a/crypto/asn1/x_name.c
+++ b/crypto/asn1/x_name.c
@@ -99,6 +99,7 @@ const ASN1_EXTERN_FUNCS x509_name_ff = {
NULL,
x509_name_ex_new,
x509_name_ex_free,
+ 0, /* Default clear behaviour is OK */
x509_name_ex_d2i,
x509_name_ex_i2d
};