Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用OpenSSL、SWIG和Perl对消息签名时出现分段错误_C_Perl_Openssl_Swig_Ecdsa - Fatal编程技术网

C 使用OpenSSL、SWIG和Perl对消息签名时出现分段错误

C 使用OpenSSL、SWIG和Perl对消息签名时出现分段错误,c,perl,openssl,swig,ecdsa,C,Perl,Openssl,Swig,Ecdsa,我们使用SWIG使C加密实用程序库可供Perl使用。我们可以生成密钥、创建摘要,但签名代码会导致分段错误,我们认为这可能在OpenSSL代码中,但很难确定 这个问题只有在使用SWIG运行代码时才会出现,因为本机C代码是有效的 在Perl中,我们称之为: $signature = key_utils::mysignMessageWithPem($pem, $message); 在.i文件中调用此代码: %newobject mysignMessageWithPem;

我们使用SWIG使C加密实用程序库可供Perl使用。我们可以生成密钥、创建摘要,但签名代码会导致分段错误,我们认为这可能在OpenSSL代码中,但很难确定

这个问题只有在使用SWIG运行代码时才会出现,因为本机C代码是有效的

在Perl中,我们称之为:

$signature = key_utils::mysignMessageWithPem($pem, $message);
在.i文件中调用此代码:

%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;                                                                                                                                                                                                                                                                                                             
    }                                                                                                                                                                                                                                                                                                                         

  }                                                                                                                                                                                                                                                                                                                           
%}                     
调用此C代码:

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;
}                  
并返回
分段错误
。我们得到的信息最丰富的错误是
perl在EC\u KEY\u get\u KEY\u method\u data()中与SIGSEGV崩溃。

完整代码如下:


这是SSL的错误,还是我们做错了?

这个问题的答案是:我们以错误的顺序调用参数

真的。该行:

$signature=key\u utils::mysignMessageWithPem($pem,$message)

需要:

$signature=key\u utils::mysignMessageWithPem($message,$pem)


事实上,我们做错了什么。我很想删除这个问题,但也许答案可以作为一个警示故事或其他东西。

不要删除它,迟早会有人使用它的