libcrypto:RSA_check_key中的段错误-> BN_is_prime_fasttest_ex-> BN_num_bits

时间:2018-06-25 17:14:13

标签: openssl libcrypto

在一切正常安装的情况下,我在RHEL 6.9上遇到了带有lib crypto的段错误。我将其简化为以下测试程序:

extern "C" {
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <string.h>
}

int main ( int , char const** )
{
   char const* publicKey = "-----BEGIN PUBLIC KEY-----\n"
      "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAs/6Nf24RG1cXBbww6MlM\n"
      "7anHA4dvqjHyYDC3SENEqWtmW/yRXh9sJs3dfsBWIW610huTMvYRzqZ9c95t6h5W\n"
      "EicsNC/396KNBLbDP3urDtKVq5z5djTPWQGpi3Jdx7OISszW4eOWQzArjGCYAwM8\n"
      "XpmXm92JA3lFPQkCDW/yp8UyG/VKWV/t25YKqmkUhp6bvpVZpifAAQlDDZ6t60tq\n"
      "dxMuDkYC+HyZS+Z63SCMErFqbXwwNSQS+5fgr7B7fgJb8c+8od+n8Fza2jEG9Qc5\n"
      "jpGjrttT52DmVpIJvDQaqwFfswgMrnAE4KNIwZvmiQXCUVgbHz4b8Ftjotwqt7QX\n"
      "ZyC5VGsW8pksVtV4Iqo5QTxi0ZVyFKLFX35VjwUrxiZCRx/44RXdveX2wbf3My+5\n"
      "vS9fW1VGipxdfcebOqosvP7Q1aegx4MBqAUt71XqtOIWRHWQJaVHji+ohjqRp/gQ\n"
      "XXqSvBLzTXAW530fSTC8Qjcdyd0IOwclCH4ZKYcTf74G70kdCo9tSkPUTvw3kqCz\n"
      "2bev5BcVf4FUR1m1XF868vj+pQCBfGkm5AKvhJyXMuCGnTKAMMysJj9iCp73q5z0\n"
      "jIYDKgWpfF3mBZJBHhqUL8/3s3ZmboeRrO1nWB0MVXBYIAUUy9YquQitMMjOhoZ1\n"
      "+heBhiVxr2R10QvOg+yL68UCAwEAAQ==\n"
      "-----END PUBLIC KEY-----" ;

   FILE * f = fopen("out.pem","wb") ;
   fwrite ( publicKey , 1 , strlen(publicKey) , f ) ;
   fclose ( f ) ;

   size_t bufferLen = strlen(publicKey) ;
   char* buffer = (char*)malloc(bufferLen+1) ;
   memcpy ( (void*)buffer , (void const*)publicKey , size_t(bufferLen+1) ) ;
   BIO * keybio = BIO_new_mem_buf(buffer,bufferLen) ;

   RSA* rsa (0) ;
   PEM_read_bio_RSA_PUBKEY(keybio, &rsa,NULL, NULL);

   RSA_check_key ( rsa ) ;

   return 0 ;
}

我可以使用由此编写的out.pem文件使用openssl成功加密内容,因此密钥是有效的。 (此外,此密钥是使用openssl命令行实用程序生成的。)

我用它来编译和调试该测试程序:

g++ -g -lcrypto rsa_test.cpp && gdb ./a.out

where是:

#0  0x0000003caeea70b1 in BN_num_bits () from /usr/lib64/libcrypto.so.10
#1  0x0000003caeeadf0a in BN_is_prime_fasttest_ex () from /usr/lib64/libcrypto.so.10
#2  0x0000003caeec927a in RSA_check_key () from /usr/lib64/libcrypto.so.10
#3  0x00000000004009d7 in main () at rsa_test.cpp:37

info break是:

(gdb) info shared
From                To                  Syms Read   Shared Object Library
0x0000003ca6600b30  0x0000003ca661a26b  Yes (*)     /lib64/ld-linux-x86-64.so.2
0x0000003caee69d80  0x0000003caef5ef98  Yes (*)     /usr/lib64/libcrypto.so.10
0x0000003cada563f0  0x0000003cadac33a6  Yes (*)     /usr/lib64/libstdc++.so.6
0x0000003ca7603e60  0x0000003ca76443d8  Yes (*)     /lib64/libm.so.6
0x0000003caaa02910  0x0000003caaa12f78  Yes (*)     /lib64/libgcc_s.so.1
0x0000003ca6a1ea60  0x0000003ca6b4032c  Yes (*)     /lib64/libc.so.6
0x0000003ca7200de0  0x0000003ca7201998  Yes (*)     /lib64/libdl.so.2
0x0000003ca7a02120  0x0000003ca7a0d3a8  Yes (*)     /lib64/libz.so.1
(*): Shared library is missing debugging information.

当我在反汇编中四处查看时,似乎将null传递给BN_is_prime_fasttest_ex,因此将BNNUM位数传递给BIGNUM指针。

(gdb) frame 3
#3  0x00000000004009d7 in main () at rsa_test.cpp:37
37      RSA_check_key ( rsa ) ;
(gdb) print *keybio
$1 = {method = 0x3caf1d8c60, callback = 0, cb_arg = 0x0, init = 1, shutdown = 1, flags = 512, retry_reason = 0, num = 0, ptr = 0x6025b0, next_bio = 0x0, prev_bio = 0x0, 
  references = 1, num_read = 0, num_write = 0, ex_data = {sk = 0x0, dummy = 0}}
(gdb) print *rsa
$2 = {pad = 0, version = 0, meth = 0x3caf1d6ce0, engine = 0x0, n = 0x602d80, e = 0x602fb0, d = 0x0, p = 0x0, q = 0x0, dmp1 = 0x0, dmq1 = 0x0, iqmp = 0x0, ex_data = {sk = 0x0, 
    dummy = 0}, references = 1, flags = 1030, _method_mod_n = 0x0, _method_mod_p = 0x0, _method_mod_q = 0x0, bignum_data = 0x0, blinding = 0x0, mt_blinding = 0x0}

此代码已在其他RHEL系统上运行,所以我不知道为什么突然在这里不起作用。我最初在调用memcpy之后拥有BIO_new_mem_buf(当它在其他RHEL 5系统上工作时),但是在调试过程中将其移至较早版本,以防万一。

以下是分段故障本身的反汇编:

(gdb) disas
Dump of assembler code for function BN_num_bits:
   0x0000003caeea70b0 <+0>: push   %rbx
=> 0x0000003caeea70b1 <+1>: mov    0x8(%rdi),%ebx
   0x0000003caeea70b4 <+4>: xor    %eax,%eax
   0x0000003caeea70b6 <+6>: test   %ebx,%ebx
   0x0000003caeea70b8 <+8>: jne    0x3caeea70c0 <BN_num_bits+16>
   0x0000003caeea70ba <+10>:    pop    %rbx
   0x0000003caeea70bb <+11>:    retq   
   0x0000003caeea70bc <+12>:    nopl   0x0(%rax)
   0x0000003caeea70c0 <+16>:    mov    (%rdi),%rax
   0x0000003caeea70c3 <+19>:    sub    $0x1,%ebx
   0x0000003caeea70c6 <+22>:    movslq %ebx,%rdx
   0x0000003caeea70c9 <+25>:    shl    $0x6,%ebx
   0x0000003caeea70cc <+28>:    mov    (%rax,%rdx,8),%rdi
   0x0000003caeea70d0 <+32>:    callq  0x3caeea6f80 <BN_num_bits_word>
   0x0000003caeea70d5 <+37>:    add    %ebx,%eax
   0x0000003caeea70d7 <+39>:    pop    %rbx
   0x0000003caeea70d8 <+40>:    retq   
End of assembler dump.

还有info reg

rax            0x1  1
rbx            0x2  2
rcx            0x0  0
rdx            0x0  0
rsi            0x3caf1c3c30 260635900976
rdi            0x0  0
rbp            0x0  0x0
rsp            0x7fffffffdbb0   0x7fffffffdbb0
r8             0x0  0
r9             0x0  0
r10            0x40 64
r11            0x3caeec91d0 260632777168
r12            0x0  0
r13            0x0  0
r14            0x0  0
r15            0x602990 6302096
rip            0x3caeea70b1 0x3caeea70b1 <BN_num_bits+1>
eflags         0x10246  [ PF ZF IF RF ]
cs             0x33 51
ss             0x2b 43
ds             0x0  0
es             0x0  0
fs             0x0  0
gs             0x0  0

所以...。为什么会发生段错误?

0 个答案:

没有答案