1

I am working with OpenSSL inside a Perl-XS-Module. I have a C-function that calls OpenSSL-API-functions. It is very simple for test-purposes (init openssl, read a key, make the RSA-object and use it, no arguments). No big checks needed and addresses and memory are ok.

XS is standard h2xs with -lssl and -lcrypto in the Makefile.

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");
}

That is working if I do pure C/C++. It is also ok if I have it in the XS-Module and use it in Perl outside a thread. But it crashes if I have it in Perl and inside a thread.

Now I would say that is because I do not have any thread-handling. But if I have a look into other Perl-Modules (e.g. Crypt::OpenSSL::RSA) I do not find and special thread-handling there too.

I am pretty new to XS and maybe I miss something. Maybe someone can give me a hint, thanks!

jww
  • 97,681
  • 90
  • 411
  • 885
chris01
  • 10,921
  • 9
  • 54
  • 93
  • What is "pure C/C++"? – too honest for this site Aug 25 '16 at 01:05
  • *"Now I would say that is because I do not have any thread-handling..."* - You would probably be right. *"If I have a look into other Perl-Modules (e.g. Crypt::OpenSSL::RSA) I do not find and special thread-handling there too..."* - You don't have to follow them over the cliff. – jww Aug 25 '16 at 01:40
  • Looked at C::O::RSA. If that works in threads, then yeah, yours should too. It does check if `bio` or `pk` are `NULL`, but I'm guessing you made sure that neither `bio` nor `pk` are `NULL`. – ikegami Aug 25 '16 at 02:49
  • I said addresses and pointers are ok. No problem with NULL or anything. – chris01 Aug 25 '16 at 07:13

2 Answers2

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

From the documentation of SSL_library_init:

SSL_library_init() must be called before any other action takes place. SSL_library_init() is not reentrant.

Which means that you should better call SSL_library_init once before the threads are started or at least make sure that you have proper locking and that this function is not called multiple times, including not called from other modules you might use. Modules like Net::SSLeay actually take care of this as can be seen in the source code.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • I now made sure the init is only called once and not inside the thread. But it did not make a difference. I was hoping I do not need the MUTEX-locking of OpenSSL-threads. Therefore I was comparing with that other module. – chris01 Aug 25 '16 at 07:29
  • @chris: with the code you've shown so far it is impossible to say what exactly is going on and what interactions might happen with Perl or other modules. To get better help please provide a fully working minimal example which makes it possible to reproduce your problem, see http://stackoverflow.com/help/mcve. – Steffen Ullrich Aug 25 '16 at 07:39
  • Yes, I agree. I addes mutex-locking to my code and it is still not working. Same problem. I will post a sample. Thanks! – chris01 Aug 25 '16 at 07:54
0

I found out the answer. I am not sure about it and I do not like it but it seems to be legit.

I have a lot of openssl-includes in my xs. But I did not include ssl.h.

#include <openssl/ssl.h>

No compile-error, no linker-error. Only a segmentation-fault if I use it in threads. Works even outside threads.

If I include the h-file it works all fine. Even without the added openssl-mutex-thread-handling.

Found out after I tried to make my sample "pretty" to post it here. That is a bit weird.... I would prefer an compiler-error...

But it explains why the other module is working.

Thanks for help!!

chris01
  • 10,921
  • 9
  • 54
  • 93
  • *"If I include the h-file it works all fine. Even without the added openssl-mutex-thread-handling..."* - that does not really make sense. – jww Aug 25 '16 at 22:12
  • My code did not work in threads. It was ok outside threads. OpenSSL provides functions to handle multithreading (https://www.openssl.org/docs/man1.0.2/crypto/threads.html). I thought the reason for the problem was that I did not use them. But it still did not work after I added the suggested handling. Hope it is clear now. – chris01 Aug 26 '16 at 09:04
  • You wrote in your question: "*That is working if I do pure C/C++.*" Did it work in your "pure C/C++" test without including the h-file? – dolmen Aug 30 '16 at 12:36
  • With pure C I ment the XS. It is in C and if I tried the C-code it was working. I did not try it in C with threads. But then as XS with perl-threads. – chris01 Aug 30 '16 at 12:41