c - Creating a DER formatted ECDSA signature from raw r and s -
i have raw ecdsa signature, r , s values. need der-encoded version of signature. there straightforward way in openssl using c interface?
my current attempt use i2d_ecdsa_sig(const ecdsa_sig *sig, unsigned char **pp)
populate ecdsa_sig*
. call returns non-zero target buffer doesn't seem changed.
i'm intiailly filling ecdsa_sig wtih r
, s
values. don't see errors. man page says r , s should allocated when call ecdsa_sig_new
ecdsa_sig* ec_sig = ecdsa_sig_new(); if (null == bn_bin2bn(sig, 32, (ec_sig->r))) { dumpopensslerrors(); } dbg("post r :%s\n", bn_bn2hex(ec_sig->r)); if (null == bn_bin2bn(sig + 32, 32, (ec_sig->s))) { dumpopensslerrors(); } dbg("post s :%s\n", bn_bn2hex(ec_sig->s));
s , r set:
post r :397116930c282d1fcb71166a2d06728120cf2ee5cf6ccd4e2d822e8e0ae24a30
post s :9e997d4718a7603942834fbdd22a4b856fc4083704ede62033cf1a77cb9822a9
now make encoded signature.
int sig_size = i2d_ecdsa_sig(ec_sig, null); if (sig_size > 255) { dbg("signature large wants %d\n", sig_size); } dbg("post i2d:%s\n", bn_bn2hex(ec_sig->s));
s hasn't changed:
post i2d:9e997d4718a7603942834fbdd22a4b856fc4083704ede62033cf1a77cb9822a9
at point have more enough bytes ready , set target 6s it's easy see changes.
unsigned char* sig_bytes = new unsigned char[256]; memset(sig_bytes, 6, 256); sig_size = i2d_ecdsa_sig(ec_sig, (&sig_bytes)); dbg("new size %d\n", sig_size); dbg("post i2d:%s\n", bn_bn2hex(ec_sig->s)); hexdump("sig ", (const byte*)sig_bytes, sig_size);
the new size 71 new size 71
, s iis stiill same:
`post i2d:9e997d4718a7603942834fbdd22a4b856fc4083704ede62033cf1a77cb9822a9`
the hex dump 6s.
--sig -- 0x06: 0x06: 0x06: 0x06: 0x06: 0x06: 0x06: 0x06: 0x06: ...
the dump still 6s though call didn't return 0. missing tying der encode raw signature?
i2d_ecdsa_sig
modifies second argument, increasing size of signature. ecdsa.h:
/** der encode content of ecdsa_sig object (note: function modifies *pp * (*pp += length of der encoded signature)). * \param sig pointer ecdsa_sig object * \param pp pointer unsigned char pointer output or null * \return length of der encoded ecdsa_sig object or 0 */ int i2d_ecdsa_sig(const ecdsa_sig *sig, unsigned char **pp);
so need keep track of original value of sig_bytes
when call i2d_ecdsa_sig
:
int sig_size = i2d_ecdsa_sig(ec_sig, null); unsigned char *sig_bytes = malloc(sig_size); unsigned char *p; memset(sig_bytes, 6, sig_size); p = sig_bytes; new_sig_size = i2d_ecdsa_sig(_sig, &p); // value of p sig_bytes + sig_size, , signature resides @ sig_bytes
output:
30 45 02 20 39 71 16 93 0c 28 2d 1f cb 71 16 6a 2d 06 72 81 20 cf 2e e5 cf 6c cd 4e 2d 82 2e 8e 0a e2 4a 30 02 21 00 9e 99 7d 47 18 a7 60 39 42 83 4f bd d2 2a 4b 85 6f c4 08 37 04 ed e6 20 33 cf 1a 77 cb 98 22 a9
Comments
Post a Comment