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

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -