in reply to Issue with LWP loading client certificate

For authentication you need a keyfile in addition to a certfile.

Greetings,
-jo

$gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
  • Comment on Re: Issue with LWP loading client certificate

Replies are listed 'Best First'.
Re^2: Issue with LWP loading client certificate
by haj (Vicar) on Jun 18, 2021 at 15:06 UTC

    That's true for DER files, but not for all certificate formats (PEM and PKCS#12 can have both key and certificate rolled into one file). But if that was the problem, then IO::Socket::SSL would complain loudly and the handshake wouldn't complete. So I rather guess that the server didn't request a client certificate.

Re^2: Issue with LWP loading client certificate
by ffrost (Acolyte) on Jun 18, 2021 at 13:49 UTC

    A keyfile? Something like ...

    $ua->ssl_opts(SSL_key_file => 'privatekey.pem');

    So, would this load the cert/keyfile then?

    $ua->ssl_opts(SSL_key_file => 'privatekey.pem'); $ua->ssl_opts(SSL_cert_file => 'cert.pem');

    And, they have to be .pem formatted files?

      And, they have to be .pem formatted files?

      Not necessarily. The documentation says:

      Supported file formats are PEM, DER and PKCS#12, where PEM and PKCS#12 can contain the certificate and the chain to use, while DER can only contain a single certificate.

      🦛

      Yes, this should work with a privatekey in PEM format. It needs to be unencrypted, though.

      UPDATE:
      You may as well put the cert and the privkey in PEM format into the certfile or you may use a PKCS#12 as certfile. And you may give a callback sub to provide the passphrase for the private key via SSL_password_cb. See IO::Socket::SSL.

      Greetings,
      -jo

      $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$

        Further down the rabbit hole we go. Open one door and another presents itself.

        We cannot have unencrypted .pfx files for the private key on the server. But, there's notation stating the password for the private key can get passed into the IO::Socket with a subroutine. This part doesn't make sense to me. From what I've found this is how it's put together, but it's still failing.

        use LWP::UserAgent; use Data::Dumper; use IO::Socket::SSL qw(debug4); IO::Socket::SSL::set_defaults(passwd_cb => sub { "passwordvaluehere" } +); $endpoint = 'https://omit/commotest'; $ua = LWP::UserAgent->new; $ua->ssl_opts(SSL_cert_file => 'der.cer'); $ua->ssl_opts(SSL_key_file => 'privatekey.pfx'); $ua->ssl_opts(SSL_use_cert => '1'); $response = $ua->get($endpoint); if ($response->is_success) { print Dumper $response; } else { print "Error: " . $response->status_line, "\n"; }

        But now I'm getting the following response ... We're using a simple passphrase for now to test with, no symbols. Research online showed other users had issues with complex passphrases and the decryption.

        DEBUG: .../IO/Socket/SSL.pm:2411: Failed to load key from file (no PEM + or DER) SSL error: 4824: 1 - error:0606F076:digital envelope routines:EVP_PKCS +82PKEY:unsupported private key algorithm SSL error: 4824: 2 - error:140B000D:SSL routines:SSL_CTX_use_PrivateKe +y_file:ASN1 lib
Re^2: Issue with LWP loading client certificate
by ffrost (Acolyte) on Jun 20, 2021 at 13:10 UTC

    Further down the rabbit hole we go. Open one door and another presents itself.

    We cannot have unencrypted .pfx files for the private key on the server. But, there's notation stating the password for the private key can get passed into the IO::Socket with a subroutine. This part doesn't make sense to me. From what I've found this is how it's put together, but it's still failing.

    use LWP::UserAgent; use Data::Dumper; use IO::Socket::SSL qw(debug4); $endpoint = ‘https://omit/commotest'; $ua = LWP::UserAgent->new; $ua->ssl_opts(SSL_cert_file => 'der.cer'); $ua->ssl_opts(SSL_key_file => 'privatekey.pfx'); $ua->ssl_opts(SSL_passwd_cb => sub { return "passwordvaluehere"; } ); $ua->ssl_opts(SSL_use_cert => '1'); $response = $ua->get($endpoint); if ($response->is_success) { print Dumper $response; } else { print "Error: " . $response->status_line, "\n"; }

    But now I'm getting the following response ... We're using a simple passphrase for now to test with, no symbols. Research online showed other users had issues with complex passphrases and the decryption.

    DEBUG: .../IO/Socket/SSL.pm:2411: Failed to load key from file (no PEM + or DER) SSL error: 4824: 1 - error:0606F076:digital envelope routines:EVP_PKC +S82PKEY:unsupported private key algorithm SSL error: 4824: 2 - error:140B000D:SSL routines:SSL_CTX_use_PrivateK +ey_file:ASN1 lib

      I would guess that your privatekey.pfx is all you need. That extension is used for PKCS#12 files, which are containers usually having the certificate and the private key embedded.

      An extra SSL_key_file must be PEM or DER (that's what the message says) but you should make progress by providing the .pfx file as SSL_cert_file and drop the SSL_key_file:

      $ua = LWP::UserAgent->new; $ua->ssl_opts(SSL_cert_file => 'privatekey.pfx'); $ua->ssl_opts(SSL_passwd_cb => sub { return "passwordvaluehere"; } ); $ua->ssl_opts(SSL_use_cert => '1');

        That worked. It's finally working!