Hello,
attached you can find some test code of mine utilizing ECDSA_do_sign and
ECDSA_do_verify. It simply signs "fnord" and verifys the signature.
The strange thing is: sig->r and sig->s are different from call to
call of the program. i2d_ECDSA_SIG also returns different length of the
DER encoded version of the signature at each call of the program, for
that matter.
Am I missing something or is this a bug in ecdsa?
regards,
Özgür Kesim
#include <openssl/objects.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/ec.h>
#include <openssl/pem.h>
#include <stdio.h>
#include <assert.h>
ECDSA_SIG* sig;
ECDSA_SIG* sig2;
/* Keys generated with:
*
* ecdsa.key:
* openssl ecparam -genkey -name wap-wsg-idm-ecid-wtls8 \
* -conv_form compressed > ecdsa.key
* ecdsa.pub:
* openssl ec -in ecdsa.key -pubout -out ecdsa.pub
*/
char privkey[]=
"-----BEGIN EC PARAMETERS-----\n"
"BgVnKw0ECA==\n"
"-----END EC PARAMETERS-----\n"
"-----BEGIN EC PRIVATE KEY-----\n"
"MD4CAQEEDthN31VEyito/izDlzDPoAcGBWcrDQQIoSADHgAE8qeUbBtKNIUgmHIl\n"
"goPQpt7McJZvBbz0/NF88Q==\n"
"-----END EC PRIVATE KEY-----\n";
char pubkey[]=
"-----BEGIN PUBLIC KEY-----\n"
"MDIwEAYHKoZIzj0CAQYFZysNBAgDHgAE8qeUbBtKNIUgmHIlgoPQpt7McJZvBbz0\n"
"/NF88Q==\n"
"-----END PUBLIC KEY-----\n";
int sign(const char* data,unsigned int len) {
BIO* in;
EC_KEY* pkey;
in=BIO_new_mem_buf(privkey,sizeof(privkey));
if (!in) return -1;
/* load private key */
pkey=PEM_read_bio_ECPrivateKey(in, NULL, NULL, NULL /* passphrase */);
if (!pkey) return -1;
/* sign data */
sig = ECDSA_do_sign(data, len, pkey);
if (!sig) return -1;
return 1;
}
int verify(const char* data,unsigned int len) {
int r;
BIO* in;
EC_KEY *pub_key;
in=BIO_new_mem_buf(pubkey,sizeof(pubkey));
if (!in) return -1;
/* load public key */
pub_key = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL);
if (!pub_key) return -1;
r = ECDSA_do_verify(data, len, sig2, pub_key);
if (r < 0) return -1;
else if (r == 0) return 0;
else return 1;
}
int main() {
unsigned char buf[1024];
unsigned char* x;
int r;
r=sign("fnord",5);
printf("sign returned %d\n",r);
x=buf;
printf("(sig->r, sig->s): (%s,%s)\n", BN_bn2hex(sig->r), BN_bn2hex(sig->s));
r=i2d_ECDSA_SIG(sig,&x);
printf("i2d_ECDSA_SIG returned %p, length %d\n",sig, r);
*x=0; x=buf;
sig2=d2i_ECDSA_SIG(&sig2,(const unsigned char**)&x,r);
printf("d2i_ECDSA_SIG returned %p\n",sig2);
r=verify("fnord",5);
printf("verify returned %d\n",r);
}