noxxi / p5-io-socket-ssl

IO::Socket::SSL Perl Module
36 stars 60 forks source link

Segmentation fault while using IO::Socket::SSL::Utils::PEM_cert2file with CERT_create #29

Closed Robertof closed 9 years ago

Robertof commented 9 years ago

Hello,

I discovered something wrong with (probably?) IO::Socket::SSL and the certificate creation utility in IO::Socket::SSL::Utils. First, while I was writing a script using the CERT_create function, along with the PEM_cert2file sub to write it to a file, my script crashed with a SIGSEGV. So I thought that it was my fault, and inspected the arguments over and over. I also checked the source of IO::Socket::SSL::Utils. However, I discovered that the problem is there even with the default values!

Take a look at this example:

$ perl -MIO::Socket::SSL::Utils -e 'my $crt = CERT_create(); PEM_cert2file($crt, "test_file.pem")'
Segmentation fault (core dumped)

Using this this with IO::Socket::SSL version 2.010, Net::SSLeay version 1.68 and OpenSSL version 1.0.2a produces a segmentation fault on two systems of mine. The interesting thing is that if the result of CERT_create is not assigned to a variable, but instead given directly to PEM_cert2file, everything works (however, the cert is saved to a randomly numbered file instead of test_file.pem).

Can you help me? I have been struggling with this for a while, and it may still be my fault! Let me know if you need any more details. Thanks!

noxxi commented 9 years ago

CERT_create returns (cert,key) and this is also documented. If you use in in scalar context you will end up with the last entry of the return list, i.e. key - this is how Perl works. Trying to use the key within PEM_cert2file will result in a segmentation fault, because the key is in effect a OpenSSL EV_PKEY* and using it as an OpenSSL X509* will crash OpenSSL. While this is not the optimal behavior there is not much I can do about it, since IO::Socket::SSL::Utils just wraps around Net::SSLeay which simply wraps objects around pointers to OpenSSL structures and you have to make sure yourself that you use the right kind of handle at the right place or OpenSSL will crash.

When using it directly inside PEM_cert2file it will be called in array context, so that the first argument will be the certificate. But the second argument will not be the file name but instead the key, and thus you will end up with the certificate written to a file name with some number (i.e. the value of EV_PKEY*) and not the name you've intended.

Robertof commented 9 years ago

Well, it looks like I'm an idiot then! I shouldn't write code and report issues after being awake for 19 hours... The segmentation fault really had me thinking about a problem in the library.

One suggestion I could give is to use wantarray to return an arrayref in scalar context (and maybe automatically dereference - if necessary - in the subroutines using certificates), to make the errors more explicit. But really, that shouldn't be necessary with someone who carefully reads the documentation.

Sorry for wasting your time, and keep up the good work. Have a good day!