Commit dc46e3dd authored by Matt Caswell's avatar Matt Caswell
Browse files

Use the right NID when putting a method in the store



When we attempt to fetch a method with a given NID we will ask the
providers for it if we don't already know about it. During that process
we may be told about other methods with a different NID. We need to
make sure we don't confuse the two.

Reviewed-by: default avatarRichard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8541)
parent 68ca1737
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -35,7 +35,8 @@ static int ossl_method_construct_this(OSSL_PROVIDER *provider, void *cbdata)
        const OSSL_ALGORITHM *thismap = map++;
        void *method = NULL;

        if ((method = data->mcm->construct(thismap->implementation, provider,
        if ((method = data->mcm->construct(thismap->algorithm_name,
                                           thismap->implementation, provider,
                                           data->mcm_data)) == NULL)
            continue;

+8 −1
Original line number Diff line number Diff line
@@ -585,10 +585,17 @@ static void evp_md_free(void *md)
    EVP_MD_meth_free(md);
}

static int evp_md_nid(void *vmd)
{
    EVP_MD *md = vmd;

    return md->type;
}

EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm,
                     const char *properties)
{
    return evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties,
                             evp_md_from_dispatch, evp_md_upref,
                             evp_md_free);
                             evp_md_free, evp_md_nid);
}
+18 −9
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ struct method_data_st {
                                  OSSL_PROVIDER *);
    int (*refcnt_up_method)(void *method);
    void (*destruct_method)(void *method);
    int (*nid_method)(void *method);
};

/*
@@ -106,29 +107,35 @@ static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
}

static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
                               const char *propdef, void *method,
                               void *data)
                               const char *propdef,
                               void *method, void *data)
{
    struct method_data_st *methdata = data;
    int nid = methdata->nid_method(method);

    if (nid == NID_undef)
        return 0;

    if (store == NULL
        && (store = get_default_method_store(libctx)) == NULL)
        return 0;

    if (methdata->refcnt_up_method(method)
        && ossl_method_store_add(store, methdata->nid, propdef, method,
        && ossl_method_store_add(store, nid, propdef, method,
                                 methdata->destruct_method))
        return 1;
    return 0;
}

static void *construct_method(const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov,
static void *construct_method(const char *algorithm_name,
                              const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov,
                              void *data)
{
    struct method_data_st *methdata = data;
    void *method = NULL;
    int nid = OBJ_sn2nid(algorithm_name);

    if (methdata->nid == NID_undef) {
    if (nid == NID_undef) {
        /* Create a new NID for that name on the fly */
        ASN1_OBJECT tmpobj;

@@ -139,13 +146,13 @@ static void *construct_method(const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov,
        tmpobj.length = 0;
        tmpobj.data = NULL;

        methdata->nid = OBJ_add_object(&tmpobj);
        nid = OBJ_add_object(&tmpobj);
    }

    if (methdata->nid == NID_undef)
    if (nid == NID_undef)
        return NULL;

    method = methdata->method_from_dispatch(methdata->nid, fns, prov);
    method = methdata->method_from_dispatch(nid, fns, prov);
    if (method == NULL)
        return NULL;
    return method;
@@ -163,7 +170,8 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
                        void *(*new_method)(int nid, const OSSL_DISPATCH *fns,
                                            OSSL_PROVIDER *prov),
                        int (*upref_method)(void *),
                        void (*free_method)(void *))
                        void (*free_method)(void *),
                        int (*nid_method)(void *))
{
    int nid = OBJ_sn2nid(algorithm);
    void *method = NULL;
@@ -186,6 +194,7 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
        mcmdata.destruct_method = free_method;
        mcmdata.refcnt_up_method = upref_method;
        mcmdata.destruct_method = free_method;
        mcmdata.nid_method = nid_method;
        method = ossl_method_construct(libctx, operation_id, algorithm,
                                       properties, 0 /* !force_cache */,
                                       &mcm, &mcmdata);
+2 −1
Original line number Diff line number Diff line
@@ -90,4 +90,5 @@ void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id,
                        void *(*new_method)(int nid, const OSSL_DISPATCH *fns,
                                            OSSL_PROVIDER *prov),
                        int (*upref_method)(void *),
                        void (*free_method)(void *));
                        void (*free_method)(void *),
                        int (*nid_method)(void *));
+6 −1
Original line number Diff line number Diff line
@@ -14,7 +14,8 @@ evp_generic_fetch - generic algorithm fetcher and method creator for EVP
                         void *(*new_method)(int nid, const OSSL_DISPATCH *fns,
                                             OSSL_PROVIDER *prov),
                         int (*upref_method)(void *),
                         void (*free_method)(void *));
                         void (*free_method)(void *),
                         int (*nid_method)(void *));

=head1 DESCRIPTION

@@ -41,6 +42,10 @@ one.

frees the given method.

=item nid_method()

returns the nid associated with the given method.

=back

=head1 RETURN VALUES
Loading