Net::SSL does not use Net::SSLeay, but it uses Crypt::SSLeay. While Crypt::SSLeay does basic SSL stuff, it does not verification of the servers hostname, which makes man in the middle easy.

Current LWP version therefore use IO::Socket::SSL (which is based on Net::SSLeay, not Crypt::SSLeay) and enable strict certificate verification, including checking the hostname of the certificate against the hostname given in the URL.

I’ve checked client-side certificate handling and it works like advertised in LWP::UserAgent. But you will get an error, if the name in the servers certificate does not match the name in the URL. And using Net::SSL in this case only works because the underlying Crypt::SSLeay simply ignores this error. So it’s probably not a fault of LWP, but the fault of a certificate mismatch.

You can switch off checking the hostname with LWP too by setting verify_hostname to false in ssl_opts (as documented).

@Mark: Not yet – I haven’t had time to verify that it is indeed a bug, rather than me getting it wrong, and if a bug, which part of the toolchain it’s in (LWP::UserAgent, Net::SSL, Net::SSLeay, IO::Socket::SSL…)

@Steffen: Ahhh – that might be the case. I’ll have a look and see if setting verify_hostname solves it. Are you saying that there’ll be an error if the client certificate’s common name doesn’t match the server’s common name, or talking about normal server cert validation? (If it were the latter, I’d expect it to still give the same result, sine I didn’t disable checking, just passed details of the client cert in a different manner.)

As stated in another comment, LWP can use either
Net::SSL + Crypt::SSLeay (a single CPAN distribution), either IO::Socket::SSL + Net::SSLeay (two distinct CPAN distribution).

However, while https protocol support is indeed transparent, there is absolutly no abstraction over low-level features of those different SSL bindings for server certificat checking, in LWP 5.x, and just minimal ones in LWP 6.x. All you have is pure-perl based regexp checking on certificate subject. If you want fine-grained control, you have to:
– ensure which exact binding is used
– use binding-specific settings

To make the puzzle even more complex, those bindings have different capacities (Net::SSL can’t validate server hostname), LWP 6.x has different default settings, and Redhat backported 6.x features silently into 5.x…