Access to ECDSA_METHOD do_verify function from engine

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Access to ECDSA_METHOD do_verify function from engine

Johannes Bauer-2
Hi list,

I'm having the *exact* same issue that Jacques had 2 years ago:
https://mta.openssl.org/pipermail/openssl-users/2015-June/001584.html

I.e., I'm writing an OpenSSL 1.0.2 engine that does ECDSA signing. In my
signing function, I want to verify the signature before leaving the
callback. For that I need to use the *default* verification function.

The problem is that ECDSA_METHOD is an opaque structure. It's only ever
passed through reference (and has been forward-declared), but it's
internal structure is defined in a localized crypto/ecdsa/ecs_locl.h
header file. So two questions:

When OpenSSL sees that the do_verify function in the callback has not
been set, why does it not default to the internal definition instead of
segfaulting?

How do I get the function pointer to the default method do_verify? I.e.,
how do I do something like:

ECDSA_METHOD_set_verify(ecdsa_method,
ECDSA_get_default_method()->ecdsa_do_verify);

Which currently (because of the opaque structure) results in:

usockeng.c: In function ‘bind_fn’:
usockeng.c:341:66: error: dereferencing pointer to incomplete type
‘ECDSA_METHOD {aka const struct ecdsa_method}’

There were two replies two years ago, both which don't help me:

Rémy suggests
(https://mta.openssl.org/pipermail/openssl-users/2015-June/001585.html)
to define the engine's ECDSA_METHOD structure explicitly, like so:

static ECDSA_METHOD my_own_openssl_ecdsa_meth = {
      "OpenSSL ECDSA method",
      my_own_ecdsa_do_sign_function,
      ecdsa_sign_setup_no_digest,
      ecdsa_do_verify,
...
}

This does not work (anymore?) because the stucture is opaque.

Dmitry suggests
(https://mta.openssl.org/pipermail/openssl-users/2015-June/001586.html)
to use ECDSA_METHOD_set_sign_setup/ECDSA_METHOD_set_sign -- I don't
understand this, since I did define set_sign (and it already works), but
I need *verification*.

Of course, the butt-ugly workaround would be to copy/paste the local
structure definition in my engine code, creating a horribly unportable
mess. But what's the *intended* way to solve this issue?

Best regards,
Johannes
--
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: Access to ECDSA_METHOD do_verify function from engine

Douglas E Engert
First of all the ECDSA_METHOD and ECDH_METHOD in 1.0.2 are combined
into EC_KEY_METHOD on 1.1.
Both versions have a *_new and *_set_verify.

"static ECDSA_METHOD my_own_openssl_ecdsa_meth"
will not work anymore.

Have a look at:

     https://github.com/OpenSC/libp11/blob/master/src/p11_ec.c

It uses either:
     ops = ECDSA_METHOD_new((ECDSA_METHOD *)ECDSA_OpenSSL());
or
     ops = EC_KEY_METHOD_new((EC_KEY_METHOD *)EC_KEY_OpenSSL());

which copy the default structure to the new opaque structure.
It then sets the routines it wants to change.



On 7/21/2017 4:41 AM, Johannes Bauer wrote:

> Hi list,
>
> I'm having the *exact* same issue that Jacques had 2 years ago:
> https://mta.openssl.org/pipermail/openssl-users/2015-June/001584.html
>
> I.e., I'm writing an OpenSSL 1.0.2 engine that does ECDSA signing. In my
> signing function, I want to verify the signature before leaving the
> callback. For that I need to use the *default* verification function.
>
> The problem is that ECDSA_METHOD is an opaque structure. It's only ever
> passed through reference (and has been forward-declared), but it's
> internal structure is defined in a localized crypto/ecdsa/ecs_locl.h
> header file. So two questions:
>
> When OpenSSL sees that the do_verify function in the callback has not
> been set, why does it not default to the internal definition instead of
> segfaulting?
>
> How do I get the function pointer to the default method do_verify? I.e.,
> how do I do something like:
>
> ECDSA_METHOD_set_verify(ecdsa_method,
> ECDSA_get_default_method()->ecdsa_do_verify);
>
> Which currently (because of the opaque structure) results in:
>
> usockeng.c: In function ‘bind_fn’:
> usockeng.c:341:66: error: dereferencing pointer to incomplete type
> ‘ECDSA_METHOD {aka const struct ecdsa_method}’
>
> There were two replies two years ago, both which don't help me:
>
> Rémy suggests
> (https://mta.openssl.org/pipermail/openssl-users/2015-June/001585.html)
> to define the engine's ECDSA_METHOD structure explicitly, like so:
>
> static ECDSA_METHOD my_own_openssl_ecdsa_meth = {
>        "OpenSSL ECDSA method",
>        my_own_ecdsa_do_sign_function,
>        ecdsa_sign_setup_no_digest,
>        ecdsa_do_verify,
> ...
> }
>
> This does not work (anymore?) because the stucture is opaque.
>
> Dmitry suggests
> (https://mta.openssl.org/pipermail/openssl-users/2015-June/001586.html)
> to use ECDSA_METHOD_set_sign_setup/ECDSA_METHOD_set_sign -- I don't
> understand this, since I did define set_sign (and it already works), but
> I need *verification*.
>
> Of course, the butt-ugly workaround would be to copy/paste the local
> structure definition in my engine code, creating a horribly unportable
> mess. But what's the *intended* way to solve this issue?
>
> Best regards,
> Johannes
>

--

  Douglas E. Engert  <[hidden email]>

--
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: Access to ECDSA_METHOD do_verify function from engine

Johannes Bauer-2
On 21.07.2017 14:00, Douglas E Engert wrote:

> It uses either:
>     ops = ECDSA_METHOD_new((ECDSA_METHOD *)ECDSA_OpenSSL());
> or
>     ops = EC_KEY_METHOD_new((EC_KEY_METHOD *)EC_KEY_OpenSSL());
>
> which copy the default structure to the new opaque structure.
> It then sets the routines it wants to change.

Ah, I missed this. Works perfectly, thank you very much for the tip.

I've also ported the engine to work on both OpenSSL 1.0 and 1.1 --
however the cast to a (mutable) EC_KEY_METHOD* isn't necessary for 1.1
(where the prototype accepts a const EC_KEY_METHOD*).

However, when I want to set the sign function for v1.1, I want to
override sig_sign, but use the OpenSSL default sign and sign_setup
functions. For this, I use EC_KEY_METHOD_get_sign. Unfortunately, for no
obvious reason, EC_KEY_METHOD_get_sign requires a EC_KEY_METHOD* instead
of a const EC_KEY_METHOD*. Do you happen to know why this is? Looking at
the code, there doesn't seem to be a reason for it. Gives an ugly
compile-time warning.

Cheers,
Johannes
--
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: Access to ECDSA_METHOD do_verify function from engine

Douglas E Engert


On 7/21/2017 7:19 AM, Johannes Bauer wrote:

> On 21.07.2017 14:00, Douglas E Engert wrote:
>
>> It uses either:
>>      ops = ECDSA_METHOD_new((ECDSA_METHOD *)ECDSA_OpenSSL());
>> or
>>      ops = EC_KEY_METHOD_new((EC_KEY_METHOD *)EC_KEY_OpenSSL());
>>
>> which copy the default structure to the new opaque structure.
>> It then sets the routines it wants to change.
>
> Ah, I missed this. Works perfectly, thank you very much for the tip.
>
> I've also ported the engine to work on both OpenSSL 1.0 and 1.1 --
> however the cast to a (mutable) EC_KEY_METHOD* isn't necessary for 1.1
> (where the prototype accepts a const EC_KEY_METHOD*).
>
> However, when I want to set the sign function for v1.1, I want to
> override sig_sign, but use the OpenSSL default sign and sign_setup
> functions. For this, I use EC_KEY_METHOD_get_sign. Unfortunately, for no
> obvious reason, EC_KEY_METHOD_get_sign requires a EC_KEY_METHOD* instead
> of a const EC_KEY_METHOD*. Do you happen to know why this is? Looking at
> the code, there doesn't seem to be a reason for it. Gives an ugly
> compile-time warning.

I don't see your problem with OpenSSL-1.1.0f. I don't recall seeing it with
earlier version either. p11_ec.c does:


647         static EC_KEY_METHOD *ops = NULL;
648         int (*orig_sign)(int, const unsigned char *, int, unsigned char *,
649                 unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL;

653                 ops = EC_KEY_METHOD_new((EC_KEY_METHOD *)EC_KEY_OpenSSL());
654                 EC_KEY_METHOD_get_sign(ops, &orig_sign, NULL, NULL);
655                 EC_KEY_METHOD_set_sign(ops, orig_sign, NULL, pkcs11_ecdsa_sign_sig);



>
> Cheers,
> Johannes
>

--

  Douglas E. Engert  <[hidden email]>

--
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: Access to ECDSA_METHOD do_verify function from engine

Johannes Bauer-2
On 21.07.2017 15:08, Douglas E Engert wrote:

> I don't see your problem with OpenSSL-1.1.0f. I don't recall seeing it with
> earlier version either. p11_ec.c does:
>
>
> 647         static EC_KEY_METHOD *ops = NULL;
> 648         int (*orig_sign)(int, const unsigned char *, int, unsigned
> char *,
> 649                 unsigned int *, const BIGNUM *, const BIGNUM *,
> EC_KEY *) = NULL;
>
> 653                 ops = EC_KEY_METHOD_new((EC_KEY_METHOD
> *)EC_KEY_OpenSSL());
> 654                 EC_KEY_METHOD_get_sign(ops, &orig_sign, NULL, NULL);
> 655                 EC_KEY_METHOD_set_sign(ops, orig_sign, NULL,
> pkcs11_ecdsa_sign_sig);

Ah, interesting! You call EC_KEY_METHOD_get_sign on the (inherited) copy
of the EC_KEY_METHOD. I didn't, but called it on the original source
(otherwise, very similar code):

int (*openssl_sign)(int type, const unsigned char *dgst, int dlen,
unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, const
BIGNUM *r, EC_KEY *eckey) = NULL;
int (*openssl_sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
BIGNUM **rp) = NULL;
EC_KEY_METHOD_get_sign((EC_KEY_METHOD*)EC_KEY_OpenSSL(), &openssl_sign,
&openssl_sign_setup, NULL);

The case of EC_KEY_OpenSSL() from const EC_KEY_METHOD* to EC_KEY_METHOD*
gives a -Wqual-cast diagnostic:

usockeng.c:245:25: warning: cast discards ‘const’ qualifier from pointer
target type [-Wcast-qual]
  EC_KEY_METHOD_get_sign((EC_KEY_METHOD*)EC_KEY_OpenSSL(),
&openssl_sign, &openssl_sign_setup, NULL);

I've changed my code now to also use the (mutable) new EC_KEY_METHOD*,
which doesn't give a diagnostic. Regardless, I believe that the first
parameter of EC_KEY_METHOD_get_sign should be const EC_KEY_METHOD*, not
EC_KEY_METHOD*.

Cheers,
Johannes

--
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: Access to ECDSA_METHOD do_verify function from engine

Tomas Mraz-2
On Fri, 2017-07-21 at 15:56 +0200, Johannes Bauer wrote:
> I've changed my code now to also use the (mutable) new
> EC_KEY_METHOD*,
> which doesn't give a diagnostic. Regardless, I believe that the first
> parameter of EC_KEY_METHOD_get_sign should be const EC_KEY_METHOD*,
> not
> EC_KEY_METHOD*.

Just open a github issue or better pull request with this change.

--
Tomáš Mráz
Red Hat

No matter how far down the wrong road you've gone, turn back.
                                              Turkish proverb
[You'll know whether the road is wrong if you carefully listen to your
conscience.]

 * Google and NSA associates, this message is none of your business.
 * Please leave it alone, and consider whether your actions are
 * authorized by the contract with Red Hat, or by the US constitution.
 * If you feel you're being encouraged to disregard the limits built
 * into them, remember Edward Snowden and Wikileaks.
--
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
Reply | Threaded
Open this post in threaded view
|

Re: Access to ECDSA_METHOD do_verify function from engine

Johannes Bauer-2
On 21.07.2017 16:10, Tomas Mraz wrote:
> On Fri, 2017-07-21 at 15:56 +0200, Johannes Bauer wrote:
>> I've changed my code now to also use the (mutable) new
>> EC_KEY_METHOD*,
>> which doesn't give a diagnostic. Regardless, I believe that the first
>> parameter of EC_KEY_METHOD_get_sign should be const EC_KEY_METHOD*,
>> not
>> EC_KEY_METHOD*.
>
> Just open a github issue or better pull request with this change.

Done.

https://github.com/openssl/openssl/pull/3985

Cheers,
Johannes
--
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev