Perl XS中的OpenSSL和Threads

时间:2016-08-24 23:06:59

标签: c perl openssl pthreads xs

我在Perl-XS-Module中使用OpenSSL。我有一个调用OpenSSL-API函数的C函数。它非常简单,用于测试目的(init openssl,读取密钥,生成RSA对象并使用它,没有参数)。不需要大检查,地址和内存都可以。

XS是-lssl-lcryptoMakefile的标准h2x。

void _foo (void)
{
    unsigned char key [3000];
    memset (key, 0, 3000);
    printf ("\ninit=%d", SSL_library_init ());   // init
    FILE *f = fopen ("key.key","r");
    printf ("\nf=%d", f);
    int keysize = fread (key, 1, 3000, f);   // readin
    printf ("\nn=%d",keysize);
    fclose (f);
    printf ("\nkey=%s", key);

    BIO *bio = BIO_new_mem_buf (key, keysize);
    printf ("\nbio=%ld", bio);
    RSA *pk = (RSA *) PEM_read_bio_RSAPrivateKey (bio, NULL, NULL, NULL);
    printf ("\npk=%ld", pk);

    printf ("\nsz=%d" ,RSA_size(pk));  // ***** crash here if in a perl-thread
    printf ("\n\n");
}

如果我使用纯C / C ++,这是有效的。如果我在XS-Module中使用它并在线程外部的Perl中使用它也可以。但是如果我在Perl和一个线程中使用它会崩溃。

现在我想说那是因为我没有thread-handling。但是,如果我查看其他Perl-Modules(例如Crypt :: OpenSSL :: RSA),我也找不到特殊的线程处理。

我对XS很新,也许我想念一些东西。也许有人可以给我一个提示,谢谢!

2 个答案:

答案 0 :(得分:1)

printf ("\ninit=%d", SSL_library_init ());   // init

来自SSL_library_init的文档:

  

必须在执行任何其他操作之前调用SSL_library_init()。 SSL_library_init()不可重入。

这意味着你应该在线程启动前更好地调用SSL_library_init一次,或者至少确保你有正确的锁定,并且多次调用此函数,包括不从你可能使用的其他模块调用。像Net::SSLeay这样的模块实际上会处理这个as can be seen in the source code

答案 1 :(得分:0)

我找到了答案。我不确定它,我不喜欢它,但似乎是合法的。

我的xs中有很多openssl-includes。但我没有包括ssl.h。

#include <openssl/ssl.h>

没有编译错误,没有链接器错误。如果我在线程中使用它只会出现分段错误。甚至可以在线外工作。

如果我包含h文件,它可以正常工作。即使没有添加openssl-mutex-thread-handling。

在我尝试制作样品后发现了#34;漂亮&#34;把它贴在这里。这有点奇怪......我更喜欢编译错误......

但它解释了为什么其他模块正在运作。

感谢您的帮助!!