Search code examples
c++opensslecdsa

ECDSA parameters/public key


I am not able to verify an ECDSA signature with openssl: I have the signature, the SHA256 hash of the data, the EC curve name , and an element that the documentation calls public key.

If I check this public key with openssl I think I have a ecparams structure:

unsigned char parameters[] = { 0x03, 0x5d, 0x30, 0x6b, 0x47, 0x48,... (I copied those data to file param)

$ openssl ecparam -check -name secp256r1 -in parameters
using curve name prime256v1 instead of secp256r1
checking elliptic curve parameters: ok
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----

So I think this is a compressed ecparameters structure.

I'm trying to verify the signature starting from those data, but while I am able to acquire the signature data I am not able to generate a key starting from the parameters

unsigned char parameters[] = { 0x03, 0x5d, 0x30, 0x6b, 0x47, 0x48...
unsigned char signature[] = { 0x30, 0x45, 0x02, 0x20, 0x77, 0x30...

ECDSA_SIG* derSignature = d2i_ECDSA_SIG(&derSignature, &signaturePtr, sizeof(signature));
EC_KEY*    key1 = d2i_EC_PUBKEY(NULL, &parametersPtr, sizeof(parameters));
EC_KEY*    key2 = d2i_ECParameters(NULL, &parametersPtr, sizeof(parameters));

While derSignature is a valid pointer, key1 and key2 are null. I have not found a good documentation about this, but I know that you also need the name of the curve to reconstruct the key, so I first created a key structure associated with the curve, and then I tried to populate the structure using the parameters, but it's still not working.

key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);

key = d2i_EC_PUBKEY(&key, &parametersPtr, sizeof(parameters));

(I also tried this, same result)
key = d2i_EC_PUBKEY(&key, &parametersPtr, sizeof(parameters));


Solution

  • I found out the right way to import the "key": I need to create a new key object, setting the right curve id. Then import the data as "octect" (not sure why I need to import this way, if someone can explain It would help)

    EC_KEY* key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
    key = o2i_ECPublicKey(&key,&parametersPtr, sizeof(parameters));
    

    PS: that's not a full public key, but contains all the information to do a signature verification.