diff options
-rw-r--r-- | crypto/asn1/asn1t.h | 7 | ||||
-rw-r--r-- | crypto/asn1/tasn_new.c | 86 | ||||
-rw-r--r-- | crypto/asn1/tasn_utl.c | 13 | ||||
-rw-r--r-- | crypto/asn1/x_bignum.c | 1 | ||||
-rw-r--r-- | crypto/asn1/x_long.c | 1 | ||||
-rw-r--r-- | crypto/asn1/x_name.c | 1 |
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 }; |