Subject: | Android support |
Howdy!
Sicne Perl 5.20 now has Android support, I've been working on getting most of CPAN to work on the platform. For Net::SSLeay, this required two changes:
lib/Net/SSLeay.pm:
open_tcp_connection uses getprotobyname(), which Android doesn't have -- instead, it generates an "Unsupported socket function" exception at runtime. Thankfully, the fix is pretty simple; instead of using scalar-context getprotobyname('tcp'), you can instead look at the constant provided by Socket.pm:
use Socket;
my $proto = Socket::IPPROTO_TCP;
SSLeay.xs:
This one's a bit tougher. The libssl.so's that can be acquired for Android come without deprecated interfaces, which breaks the module since there is no RSA_generate_key() in the library.
The non-trivial solution is to use RSA_generate_key_ex() instead; I managed to make it work (& have all of the tests pass) by tweaking the function so that it looks like this:
RSA *
RSA_generate_key(bits,ee,perl_cb=&PL_sv_undef,perl_data=&PL_sv_undef)
int bits
unsigned long ee
SV* perl_cb
SV* perl_data
PREINIT:
simple_cb_data_t* cb_data = NULL;
CODE:
int rc;
RSA * ret;
BIGNUM *e;
e = BN_new();
BN_set_word(e, ee);
cb_data = simple_cb_data_new(perl_cb, perl_data);
BN_GENCB new_cb;
BN_GENCB_set_old(&new_cb, ssleay_RSA_generate_key_cb_invoke, cb_data);
ret = RSA_new();
rc = RSA_generate_key_ex(ret, bits, e, &new_cb);
if (rc == -1 || ret == NULL)
croak("Couldn't generate RSA key");
simple_cb_data_free(cb_data);
BN_free(e);
e = NULL;
RETVAL = ret;
OUTPUT:
RETVAL
..but that will break for old openssl's, where the _ex function isn't available, so that should probably be wrapped in an #ifdef OPENSSL_VERSION_NUMBER >= (er, no clue 0.9.8 I think) or even an #ifdef __ANDROID__