Discussion:
Help in loading EC_KEY
jeetendra gangele
2012-12-13 09:04:28 UTC
Permalink
HI,

I am trying to sign the data using EC-DSA algorithm.
i have the private key to sign the data and I could load using
EC_KEY_set_private_key.
But when check the loaded key its failing with the error code below.
error:100B1043:lib(16):func(177):reason(67)
EC_KEY_check_key failed:

That means key not proper.
I am trying to use the curve NID_secp224r1.

Below is my code please help me in this.

14 static int loadkey_ecdsa()
15 {
16
17 EC_POINT *pub_key = NULL;
18 EC_GROUP *group = NULL;
19 BIGNUM start;
20 BIGNUM *res;
21 EC_KEY *pkey=EC_KEY_new_by_curve_name(NID_secp224r1);
22 BN_CTX *ctx;
23 int ret =0;
24
25 BN_init(&start);
26 ctx = BN_CTX_new();
27
28 res = &start;
29 char b1[] =
"24163241384221333188237658810894854793008347803969558128365682755047";
30 BN_dec2bn(&res,b1);
31 if(NULL == pkey)
32 printf("pkey failed");
33 group = EC_KEY_get0_group(pkey);
34 if(NULL == group)
35 printf("group failed");
36 pub_key = EC_POINT_new(group);
37 if(NULL == pub_key)
38 printf("pub failed");
39
40 if (!EC_KEY_check_key(pkey)) {
41 printf("EC_KEY_check_key failed:\n");
42 printf("%s\n",ERR_error_string(ERR_get_error(),NULL));
43 } else {
44 printf("Public key verified OK\n");
45 }
46 if(!EC_KEY_set_private_key(pkey, res))
47 printf("private key set failed\n");
48 //EC_KEY_set_public_key_affine_coordinates(pkey,x,y);
49
50 if (!EC_KEY_check_key(pkey)) {
51 printf("EC_KEY_check_key failed:\n");
52 printf("%s\n",ERR_error_string(ERR_get_error(),NULL));
53 } else {
54 printf("Public key verified OK\n");
55 }
56
57 BN_free(res);
58
59 BN_CTX_free(ctx);
60 }



Thanks
jeetendra
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List openssl-***@openssl.org
Automated List Manager ***@openssl.org
redpath
2012-12-13 15:00:07 UTC
Permalink
Well here is one I can answer. First I generate the ECDSA keys
This list of commands will help you

Show the type of curves:

openssl ecparam -list_curves

Use the secp224r1 curve

openssl ecparam -out ec_key.pem -name secp224r1 -genkey

Generate the certificate x509
Your certificate will be in ecdsapublic.x509 and
the corresponding private key will be in ecdsapriv.pem.

openssl req -newkey ec:ec_key.pem -x509 -nodes -days 365 -keyout
ecdsapriv.pem -out ecdsapublic.x509


addition commands
openssl req -new -key ecdsapriv.pem -inform pem -x509 -days 3650 -out
ecdsapriv.x509
openssl x509 -in ecdsapriv.x509 -noout -text


Then I have code to sign something reading a file also the compile command
is below.

Platform: Mac OSX 10.7

cc -o signECDSA -Wno-deprecated-declarations signECDSA.c -lcrypto

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/pem.h>





/***
* Get the data form a file and return a malloced buffer and size.
**/
unsigned char *getdata(char *filename, int *length){
FILE *fp =fopen(filename, "rb");
long avail;

*length=0;
if (fp==(FILE *)0){
printf("Get Data JPG %s File error %d\n",filename,errno);
return NULL;
}

fseek(fp, 0L, SEEK_END);
avail = ftell(fp);
fseek(fp, 0L, SEEK_SET);
unsigned char *b= (unsigned char *) malloc(avail+1);
if (fread (b,1,avail,fp)!=avail){
printf("INPUT JPG fail %s read error %d\n",filename, errno);
return NULL;
}
b[avail]=0; // added one byte for debug if you use a text file
*length=(int)avail; // but length returned is true length of data
fclose(fp);
return b;
}




/**
* Simple help
*/
void help(){
printf("\n");
printf("Usage <signfile> <private PEM key>\n");
printf("eg:\n");
printf("signECDSA myfile.doc ecdsapriv.pem\n\n");
}

unsigned char *sha256(char *data, int length)
{
static unsigned char hash[SHA256_DIGEST_LENGTH];

printf("******SHA2 digest follows length=%d:\n",length);
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, data, length);
SHA256_Final(hash, &sha256);
int i = 0;
for(i = 0; i < SHA256_DIGEST_LENGTH; i++)
printf("%02x", hash[i]);
printf("\n");
return hash;
}


int main(int argc, char **args){
char buffer[256];
long avail;
int len;
unsigned char *b,*m;
FILE *fp;
int ret;
EC_KEY *peckey; //I want to load private

int curvetype= NID_secp224r1; //FYI redpath
char *curvename= "NID_secp224r1";

if (argc<3){
help();
return 0;
}


printf("\n");
if ( (m= getdata(args[1],&len))==NULL)
return 1;
printf("\nUSING CURVENAME: %s\n",curvename);
printf("INPUT file %s length %d \n",args[1],len);

/***
Make a digest from Data
****/

unsigned char *result=sha256((char *)m,len);
if (result==NULL){
printf("SHA1 failed to create message digest\n");
return 1;
}



//private area
fp =fopen(args[2], "rb");
EVP_PKEY *pevpkey= PEM_read_PrivateKey(fp, &pevpkey, NULL, NULL);
if (pevpkey==NULL){
printf("PEM for read private failed\n");
return 1;
}
else
printf("PEM for read private SUCCESS\n");

peckey= EVP_PKEY_get1_EC_KEY(pevpkey);
if (peckey==NULL){
printf("ECKEY private failed\n");
return 1;
}
else
printf("got EC_KEY private success\n");
ret= EC_KEY_set_group(peckey,EC_GROUP_new_by_curve_name(curvetype) );
if (!ret){
printf("error set group\n");
return 1;
}
printf("set group ret = %d \n",ret);

unsigned int siglen = ECDSA_size(peckey);
printf("Max signature length is %d \n",siglen);
siglen = ECDSA_size(peckey);
unsigned char *ptr = OPENSSL_malloc(siglen);
unsigned char *save= ptr;
ECDSA_SIG *sig;
ret= ECDSA_sign(0 ,result, SHA256_DIGEST_LENGTH, ptr, &siglen, peckey);
//Do sign it dude
if (!ret){
printf("ERROR signing null\n");
return 1;
}
printf(" Signature success \n");
printf("Signature length is %d \n",siglen);

/**
* Write out Digital Signature File
*
***/
strcpy(buffer,args[1]);
strcat(buffer,".ecdsa");
fp = fopen(buffer,"wb");
fwrite(save, 1, siglen, fp);
fclose(fp);

printf("OUTPUT signature file is %s\n\n",buffer);

return 0;

}



Then I have code to verify the file against the original that was signed

Platform: Mac OSX 10.7

cc -o verifyECDSA -Wno-deprecated-declarations verifyECDSA.c -lcrypto


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/pem.h>





/***
* Get the data form a file and return a malloced buffer and size.
**/
unsigned char *getdata(char *filename, int *length){
FILE *fp =fopen(filename, "rb");
long avail;

*length=0;
if (fp==(FILE *)0){
printf("Get Data JPG %s File error %d\n",filename,errno);
return NULL;
}

fseek(fp, 0L, SEEK_END);
avail = ftell(fp);
fseek(fp, 0L, SEEK_SET);
unsigned char *b= (unsigned char *) malloc(avail+1);
if (fread (b,1,avail,fp)!=avail){
printf("INPUT JPG fail %s read error %d\n",filename, errno);
return NULL;
}
b[avail]=0; // added one byte for debug if you use a text file
*length=(int)avail; // but length returned is true length of data
fclose(fp);
return b;
}




/**
* Simple help
*/
void help(){
printf("\n");
printf("Usage <filename> <signature> <X509 ECkey certificate>\n");
printf("eg:\n");
printf("verifyECDSA myfile.doc myfile.doc.signed ecdsapublic.x509 \n\n");
}

unsigned char *sha256(char *data, int length)
{
static unsigned char hash[SHA256_DIGEST_LENGTH];

printf("******SHA2 digest follows length=%d:\n",length);
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, data, length);
SHA256_Final(hash, &sha256);
int i = 0;
for(i = 0; i < SHA256_DIGEST_LENGTH; i++)
printf("%02x", hash[i]);
printf("\n");
return hash;
}


int main(int argc, char **args){
char buffer[256];
long avail;
int len,siglen;
unsigned char *m;
unsigned char *sig;
FILE *fp;
int ret;
EC_KEY *pubeckey; //I want to load private
int curvetype= NID_secp224r1; //FYI redpath
char *curvename= "NID_secp224r1";

if (argc<4){
help();
return 0;
}

printf("\nUSING CURVENAME: %s\n",curvename);
printf("\n");
if ( (m= getdata(args[1],&len))==NULL)
return 1;
printf("INPUT file %s length %d \n",args[1],len);

/***
Make a digest from Data
****/

unsigned char *result=sha256((char *)m,len);
if (result==NULL){
printf("SHA1 failed to create message digest\n");
return 1;
}

printf("open signature file %s \n",args[2]);
if ( (sig= getdata(args[2],&siglen))==NULL)
return 1;

//Get X509
printf("open X509 file [%s]\n",args[3]);
fp =fopen(args[3], "rb");
if (fp==NULL){
printf("null file open %s\n",args[3]);
exit(1);
}
X509 *x509= PEM_read_X509(fp,&x509, NULL, NULL); //its public there is no
password
if (x509==NULL){
printf("X509 is null \n");
}else
printf("open X509 success\n");
fclose(fp);
EVP_PKEY *evpkey = X509_get_pubkey(x509);
pubeckey= EVP_PKEY_get1_EC_KEY(evpkey);

if (pubeckey==NULL)
printf("ECKEY is null\n");
else
printf("got EC_KEY PUBLIC\n");

ret= EC_KEY_set_group(pubeckey,EC_GROUP_new_by_curve_name(curvetype) );
if (!ret){
printf("error set group\n");
return 1;
}
printf("set group ret = %d \n",ret);


printf("attempt to verify\n");
ret = ECDSA_verify(0, result,SHA256_DIGEST_LENGTH, sig, siglen, pubeckey);
printf("verify %d \n",ret);

if (ret == -1){
printf("signature error in verify\n");
}
else if (ret == 0){
printf(" incorrect signature \n");
}
else /* ret == 1 */{
printf("signature ok \n");
}

return 0;

}


Nothing like real code to work with.
I never did get my How to package a signature in a PKCS7 file,
I abstracted code but yet not real code answer that worked.




--
View this message in context: http://openssl.6102.n7.nabble.com/Help-in-loading-EC-KEY-tp42700p42706.html
Sent from the OpenSSL - Dev mailing list archive at Nabble.com.
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List openssl-***@openssl.org
Automated List Manager ***@openssl.org
Dave Thompson
2012-12-14 00:21:44 UTC
Permalink
Sent: Thursday, 13 December, 2012 10:00
This list of commands will help you
openssl ecparam -out ec_key.pem -name secp224r1 -genkey
Generate the certificate x509
Your certificate will be in ecdsapublic.x509 and
the corresponding private key will be in ecdsapriv.pem.
openssl req -newkey ec:ec_key.pem -x509 -nodes -days 365 -keyout
ecdsapriv.pem -out ecdsapublic.x509
This is redundant. ecparam -genkey already generated a key.
Either use that key, maybe renamed, as in the form just below,
or omit -genkey from the ecparam.
addition commands
openssl req -new -key ecdsapriv.pem -inform pem -x509
-days 3650 -out ecdsapriv.x509
There is no significant difference between a cert created for
a new key with -newkey -x509 or one created for an existing key
with -new -x509, so naming it "priv" instead of "public" is
confusing and misleading. Since the cert is really the content
not the format -- certs can be either pem or der -- I would
instead name it ecdsa_cert.pem or ecdsa_x509.pem .
Platform: Mac OSX 10.7
cc -o signECDSA -Wno-deprecated-declarations signECDSA.c -lcrypto
<snip: read file, compute sha256>
fp =fopen(args[2], "rb");
EVP_PKEY *pevpkey= PEM_read_PrivateKey(fp, &pevpkey, NULL, NULL);
if (pevpkey==NULL){
<snip>
peckey= EVP_PKEY_get1_EC_KEY(pevpkey);
if (peckey==NULL){
<snip>
ret= EC_KEY_set_group(peckey,EC_GROUP_new_by_curve_name(curvetype) );
The key already identifies (or contains, if explicit) the group.
Setting it again to the correct value is a waste of time,
and setting it to a wrong value would screw it up totally.
If for some reason you want to ensure a key uses a particular
(named) group, *get* the "name" (really NID) and compare it.

<snip>
cc -o verifyECDSA -Wno-deprecated-declarations
verifyECDSA.c -lcrypto
<snip similar except publickey from cert>
unsigned char *b= (unsigned char *) malloc(avail+1);
if (fread (b,1,avail,fp)!=avail){
You don't need to cast the return of malloc in correct C
but you should check for failure (null) before using it.


______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List openssl-***@openssl.org
Automated List Manager ***@openssl.org
Jeffrey Walton
2012-12-13 21:39:29 UTC
Permalink
Post by jeetendra gangele
HI,
I am trying to sign the data using EC-DSA algorithm.
i have the private key to sign the data and I could load using
EC_KEY_set_private_key.
But when check the loaded key its failing with the error code below.
error:100B1043:lib(16):func(177):reason(67)
That means key not proper.
I am trying to use the curve NID_secp224r1.
...
Post by jeetendra gangele
37 if(NULL == pub_key)
38 printf("pub failed");
39
40 if (!EC_KEY_check_key(pkey)) {
41 printf("EC_KEY_check_key failed:\n");
42 printf("%s\n",ERR_error_string(ERR_get_error(),NULL));
43 }
Is it pub_key or pkey?

Jeff
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Continue reading on narkive:
Loading...