Search code examples
perlopenssl

Perl Crypt::OpenSSL::RSA fails when loading private key, with baffling error message


I'm trying to use Crypt::OpenSSL::RSA to encrypt a file using a public key and then decrypt it using the corresponding private key (which currently I enter at a prompt). My encryption program works fine; but I'm getting a baffling error when I try the decrypt. Can someone help me diagnose this and work out what I'm doing wrong? The documentation is a bit sketchy and the only example I found on the web fails totally in a different way.

Here is the test program ("pub_decrypt")

#! /usr/bin/perl
use strict;
use warnings;
use 5.026;

use Crypt::OpenSSL::RSA;

my $private_key_file = 'private.pem';

my $input_file = shift or exit;
die "Input file '$input_file' not found\n" unless -e $input_file;

print "Enter passphrase for '$private_key_file': ";
my $passphrase = <>;
chomp $passphrase;
exit unless $passphrase;

my $priv_key = Crypt::OpenSSL::RSA->new_private_key( $private_key_file, $passphrase )
    or die "Failed to get private key";
my $decrypted = $priv_key->decrypt( $input_file )
    or die "Decryption failed";
print "Decrypted text:\n$decrypted\n";

When I run it this happens:

./pub_decrypt encrypted_text
Enter passphrase for 'private.pem': blahblah
Usage: Crypt::OpenSSL::RSA::new_private_key(proto, key_string_SV) at ./pub_decrypt line 18, <> line 1.

I like it when a library tells you what you've done wrong when calling it, but in this case the suggested usage isn't anything like the module documentation. What is "proto", and what format of key string is "_SV" suggesting I should use?


Solution

  • Upgrade Crypt::OpenSSL::RSA. Your version doesn't accept a passphrase.

    0.33 (2022, latest on CPAN at this time):

    SV*
    new_private_key(proto, key_string_SV, passphase_SV=&PL_sv_undef)
        SV* proto;
        SV* key_string_SV;
        SV* passphase_SV;
      CODE:
        RETVAL = make_rsa_obj(
            proto, _load_rsa_key(key_string_SV, PEM_read_bio_RSAPrivateKey, passphase_SV));
      OUTPUT:
        RETVAL
    

    0.28 (2011, second latest on CPAN at this time):

    SV*
    new_private_key(proto, key_string_SV)
        SV* proto;
        SV* key_string_SV;
      CODE:
        RETVAL = make_rsa_obj(
            proto, _load_rsa_key(key_string_SV, PEM_read_bio_RSAPrivateKey));
      OUTPUT:
        RETVAL
    

    The usage message is automatically generated from the prototype by the program that generates C from this XS code. For functions with only SV* parameters such as these, I believe it's simply an argument count check.