if ((decoder = OPENSSL_zalloc(sizeof(*decoder))) == NULL)
return NULL;
if (!CRYPTO_NEW_REF(&decoder->base.refcnt, 1)) {
- OSSL_DECODER_free(decoder);
+ ossl_decoder_free(decoder);
return NULL;
}
int OSSL_DECODER_up_ref(OSSL_DECODER *decoder)
{
-#ifdef OSSL_DECODER_fetch
+#ifdef OPENSSL_NO_CACHED_FETCH
return ossl_decoder_up_ref(decoder);
#else
+ /*
+ * DECODERS do something weird. They manually build methods rather than
+ * attempt to fetch them from the method store or construct them through
+ * the ossl_generic_fetch mechanism. As such they don't make use of the refcounting
+ * that we rely on in the method store, and so we always need to refcount them here
+ * We can identify them based on the fact that they never have a registered nid (i.e.
+ * its always zero)
+ */
if (decoder->base.id == 0)
return ossl_decoder_up_ref(decoder);
return 1;
void OSSL_DECODER_free(OSSL_DECODER *decoder)
{
-#ifdef OSSL_DECODER_fetch
+#ifdef OPENSSL_NO_CACHED_FETCH
ossl_decoder_free(decoder);
#else
if (decoder != NULL && decoder->base.id == 0)
return NULL;
decoder->base.id = id;
if ((decoder->base.name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
- OSSL_DECODER_free(decoder);
+ ossl_decoder_free(decoder);
return NULL;
}
decoder->base.algodef = algodef;
if ((decoder->base.parsed_propdef
= ossl_parse_property(libctx, algodef->property_definition))
== NULL) {
- OSSL_DECODER_free(decoder);
+ ossl_decoder_free(decoder);
return NULL;
}
if (!((decoder->newctx == NULL && decoder->freectx == NULL)
|| (decoder->newctx != NULL && decoder->freectx != NULL))
|| decoder->decode == NULL) {
- OSSL_DECODER_free(decoder);
+ ossl_decoder_free(decoder);
ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROVIDER_FUNCTIONS);
return NULL;
}
if (prov != NULL && !ossl_provider_up_ref(prov)) {
- OSSL_DECODER_free(decoder);
+ ossl_decoder_free(decoder);
return NULL;
}
/* Intermediary function to avoid ugly casts, used below */
static void destruct_decoder(void *method, void *data)
{
- OSSL_DECODER_free(method);
-}
-
-static int up_ref_decoder(void *method)
-{
- return OSSL_DECODER_up_ref(method);
-}
-
-static void free_decoder(void *method)
-{
- OSSL_DECODER_free(method);
+ ossl_decoder_free(method);
}
/* Fetching support. Can fetch by numeric identity or by name */
id = ossl_namemap_name2num(namemap, name);
if (id != 0)
ossl_method_store_cache_set(store, prov, id, propq, method,
- up_ref_decoder, free_decoder);
+ ossl_decoder_up_ref, ossl_decoder_free);
}
/*
static void ossl_encoder_free(void *data)
{
- OSSL_ENCODER_free(data);
+ OSSL_ENCODER *encoder = (OSSL_ENCODER *)data;
+ int ref = 0;
+
+ if (encoder == NULL)
+ return;
+
+ CRYPTO_DOWN_REF(&encoder->base.refcnt, &ref);
+ if (ref > 0)
+ return;
+ OPENSSL_free(encoder->base.name);
+ ossl_property_free(encoder->base.parsed_propdef);
+ ossl_provider_free(encoder->base.prov);
+ CRYPTO_FREE_REF(&encoder->base.refcnt);
+ OPENSSL_free(encoder);
}
static int ossl_encoder_up_ref(void *data)
{
- return OSSL_ENCODER_up_ref(data);
+ OSSL_ENCODER *encoder = (OSSL_ENCODER *)data;
+ int ref = 0;
+
+ CRYPTO_UP_REF(&encoder->base.refcnt, &ref);
+ return 1;
}
/* Simple method structure constructor and destructor */
return ossl_encoder_up_ref(encoder);
#else
return 1;
+#endif
}
void OSSL_ENCODER_free(OSSL_ENCODER *encoder)
return NULL;
encoder->base.id = id;
if ((encoder->base.name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
- OSSL_ENCODER_free(encoder);
+ ossl_encoder_free(encoder);
return NULL;
}
encoder->base.algodef = algodef;
if ((encoder->base.parsed_propdef
= ossl_parse_property(libctx, algodef->property_definition))
== NULL) {
- OSSL_ENCODER_free(encoder);
+ ossl_encoder_free(encoder);
return NULL;
}
|| (encoder->import_object != NULL && encoder->free_object != NULL)
|| (encoder->import_object == NULL && encoder->free_object == NULL))
|| encoder->encode == NULL) {
- OSSL_ENCODER_free(encoder);
+ ossl_encoder_free(encoder);
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INVALID_PROVIDER_FUNCTIONS);
return NULL;
}
if (prov != NULL && !ossl_provider_up_ref(prov)) {
- OSSL_ENCODER_free(encoder);
+ ossl_encoder_free(encoder);
return NULL;
}
/* Intermediary function to avoid ugly casts, used below */
static void destruct_encoder(void *method, void *data)
{
- OSSL_ENCODER_free(method);
-}
-
-static int up_ref_encoder(void *method)
-{
- return OSSL_ENCODER_up_ref(method);
-}
-
-static void free_encoder(void *method)
-{
- OSSL_ENCODER_free(method);
+ ossl_encoder_free(method);
}
/* Fetching support. Can fetch by numeric identity or by name */
if (id == 0)
id = ossl_namemap_name2num(namemap, name);
ossl_method_store_cache_set(store, prov, id, propq, method,
- up_ref_encoder, free_encoder);
+ ossl_encoder_up_ref, ossl_encoder_free);
}
/*