c - Segmentation fault when signing a message using OpenSSL, SWIG, and Perl -


we using swig make c cryptographic utility library available perl. able generate keys, create digests, signing code causes segmentation fault, believe may in openssl code it's difficult sure.

this problem comes when running code swig, native c code works.

in perl, call this:

$signature = key_utils::mysignmessagewithpem($pem, $message); 

which calls code in .i file:

%newobject mysignmessagewithpem;                                                                                                                                                                                                                                                                                                %inline %{                                                                                                                                                                                                                                                                                                                       char *mysignmessagewithpem(char *pem, char *message) {                                                                                                                                                                                                                                                                           char *ret = malloc(145);                                                                                                                                                                                                                                                                                                       char *err = malloc(5);                                                                                                                                                                                                                                                                                                         int errorcode;                                                                                                                                                                                                                                                                                                                  memcpy(err, "error", 5);                                                                                                                                                                                                                                                                                                        errorcode = signmessagewithpem(pem, message, &ret);                                                                                                                                                                                                                                                                            char *signature = ret;                                                                                                                                                                                                                                                                                                          if (errorcode == noerror) {                                                                                                                                                                                                                                                                                                      return signature;                                                                                                                                                                                                                                                                                                            } else {                                                                                                                                                                                                                                                                                                                         return err;                                                                                                                                                                                                                                                                                                                  }                                                                                                                                                                                                                                                                                                                             }                                                                                                                                                                                                                                                                                                                            %}                      

which calls c code:

int signmessagewithpem(char *message, char *pem, char **signature) {                                                                                                                                                                                                                                                            unsigned int meslen = strlen(message);                                                                                                                                                                                                                                                                                     unsigned char *messagebytes = calloc(meslen, sizeof(unsigned char));                                                                                                                                                                                                                                                       ecdsa_sig *sig = null;                                                                                                                                                                                                                                                                                                     memcpy(messagebytes, message, meslen);                                                                                                                                                                                                                                                                                      ec_key *key = null;                                                                                                                                                                                                                                                                                                        bio *in = null;                                                                                                                                                                                                                                                                                                            unsigned char *buffer = null;                                                                                                                                                                                                                                                                                               char *sha256ofmsg = calloc(sha256_hex_string, sizeof(char));                                                                                                                                                                                                                                                               unsigned char *outbytesofsha256ofmsg = calloc(sha256_string, sizeof(unsigned char));                                                                                                                                                                                                                                        digestofbytes(messagebytes, &sha256ofmsg, "sha256", meslen);                                                                                                                                                                                                                                                               sha256ofmsg[64] = '\0';                                                                                                                                                                                                                                                                                                    createdatawithhexstring(sha256ofmsg, &outbytesofsha256ofmsg);                                                                                                                                                                                                                                                               in = bio_new(bio_s_mem());                                                                                                                                                                                                                                                                                                 bio_puts(in, pem);                                                                                                                                                                                                                                                                                                         pem_read_bio_ecprivatekey(in, &key, null, null);                                                                                                                                                                                                                                                                            sig = ecdsa_do_sign((const unsigned char*)outbytesofsha256ofmsg, sha256_digest_length, key);                                                                                                                                                                                                                               int verify = ecdsa_do_verify((const unsigned char*)outbytesofsha256ofmsg, sha256_digest_length, sig, key);                                                                                                                                                                                                                  if(verify != 1) {                                                                                                                                                                                                                                                                                                              return error;                                                                                                                                                                                                                                                                                                          }                                                                                                                                                                                                                                                                                                                           int buflen = ecdsa_size(key);                                                                                                                                                                                                                                                                                              buffer = openssl_malloc(buflen);                                                                                                                                                                                                                                                                                            int dersiglen = i2d_ecdsa_sig(sig, &buffer);                                                                                                                                                                                                                                                                                char *hexdata = calloc(dersiglen, sizeof(char));                                                                                                                                                                                                                                                                           memcpy(hexdata, buffer-dersiglen, dersiglen);                                                                                                                                                                                                                                                                               char *hexstring = calloc(dersiglen*2+1, sizeof(char));                                                                                                                                                                                                                                                                      hexstring[dersiglen * 2] = '\0';                                                                                                                                                                                                                                                                                           tohexstring(hexdata, dersiglen, hexstring);                                                                                                                                                                                                                                                                                 memcpy(*signature, hexstring, dersiglen*2);                                                                                                                                                                                                                                                                                signature[dersiglen * 2] = '\0';                                                                                                                                                                                                                                                                                            ec_key_free(key);                                                                                                                                                                                                                                                                                                           bio_free_all(in);                                                                                                                                                                                                                                                                                                          free(sha256ofmsg);                                                                                                                                                                                                                                                                                                         free(outbytesofsha256ofmsg);                                                                                                                                                                                                                                                                                               free(hexdata);                                                                                                                                                                                                                                                                                                             free(hexstring);                                                                                                                                                                                                                                                                                                            return noerror; }                   

and returns segmentation fault. informative error have gotten perl crashed sigsegv in ec_key_get_key_method_data()

the full code here: https://github.com/aleitner/bitpay-perl/tree/stack-overflow-question

is bug ssl, or doing wrong?

the answer question is: calling arguments in wrong order.

seriously. line:

$signature = key_utils::mysignmessagewithpem($pem, $message);

needed be:

$signature = key_utils::mysignmessagewithpem($message, $pem);

we in fact doing wrong. tempted remove question, maybe answer can serve cautionary tale or something.


Comments

Popular posts from this blog

IF statement in MySQL trigger -

c++ - What does MSC in "// appease MSC" comments mean? -

javascript - Blogger related post gadget image Resize s72-c [ Need Expert Help ] -