How and Where is OpenSSL called in this script?

时间:2016-10-20 19:07:42

标签: bash perl openssl centos6

centos-6.8 perl, v5.10.1 (*) built for x86_64-linux-thread-multi

I am attempting to update a Perl script called CSP. My experience with the script is limited to running it on rare occasions when we needed a new server certificate. I contacted the author of the original script, Leif Johansson, but I did not receive a response. The revised project that I am presently working on and refer to below can be found at https://github.com/byrnejb/rcsp/tree/csp040.

That is the background. My programming experience with Perl is negligible. Thus my questions here may be naive.

I have these code fragments in ./blib/lib/CSP.pm:

. . .
package CSP;

use strict;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);

require Exporter;
require AutoLoader;
use IO::File;
use Term::Prompt;
use POSIX qw(strftime);
use Date::Calc qw(Day_of_Week Gmtime Add_Delta_Days Add_Delta_DHMS);
use Sys::Hostname;

@ISA = qw(Exporter AutoLoader);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
@EXPORT = qw();
@EXPORT_OK = qw($_openssl);
$VERSION = '0.40';


# Preloaded methods go here.

# Autoload methods go after =cut, and are processed by the autosplit program.

$CSP::_openssl='openssl';

. . .

$CSP::_openssl='openssl';
. . .
sub genkey
  {
    my $self = shift;
    my $args = shift;

    $self->die("Required parameter keyfile missing")
      unless $args->{keyfile};

    $args->{keysize} = 4096 unless $args->{keysize} > 0;
    $args->{keypass} = "'" . $self->getPassword("Private key password",1) . "'"
      unless $args->{keypass};

    $self->warn("# Password argument: $args->{keypass}\n") if $ENV{CSPDEBUG};

    my $cmd = "-out $args->{keyfile} $args->{keysize}";
    $cmd = "-des3 -passout pass:$args->{keypass} ".$cmd if defined($args->{keypass});
    $self->{openssl}->cmd('genrsa',$cmd,$args);
  }

 ## Generate and optionally self-sign the request
  my $process;
  my $what;
  my $common_args = "-$args->{digest} -days $args->{days} ".
    " -key $cakey -passin pass:$args->{keypass}";
  if ($args->{csrfile})
    {
      $self->{openssl}->cmd('req',"-new $common_args -out $args->{csrfile}",$args);
      $what = "generated CA request for";
    }
  else
    {
      $self->{openssl}->cmd('req',"-x509 $common_args -new -out $cacert",$args);
      $what = "initialized self-signed";
    }

  $self->warn("Successfully $what CA $self->{name}")
    if $args->{verbose};
      }
  }

sub checkCA
  {
    my $self = shift;
    my $dir = $self->caDir();

    $self->die("Uninitialized CA: missing or unreadable ca certificate in $dir")
      unless -r "$dir/ca.crt";

    $self->die("Uninitialized CA: missing or unreadable ca private key in $dir")
      unless -r "$dir/private/ca.key";

    $dir;
  }
. . .

And towards the end of the script file this:

. . .
    $self->{csp} = $csp;

    $cmd = '' if $cmd eq 'dummy';

    my $engine = "-engine opensc" if $ENV{CSP_OPENSC};

    my $redirect = ($args->{verbose} == 0 && $rw ne 'r' ? ">/dev/null 2>&1" : "");
    warn "${lp}$self->{openssl} $cmd $cfgcmd $cmdline ${redirect}${rp}"
      if $ENV{CSPDEBUG};
    if ($rw eq 's')
      {
  $self->{rc} = system("$self->{openssl} $cmd $engine $cfgcmd $cmdline ${redirect}");
      }
    else
      {
  open $self->{fh},"${lp}$self->{openssl} $cmd $engine $cfgcmd $cmdline ${redirect}${rp}" or
    $self->{csp}->die("Unable to execute: $!");
      }

    $self;
  }
. . .

When I run this using the following command line with debugging on:

csp HLL_ROOT init \
  --keysize=4096 \
  --days=7318 \
  --url=ca.harte-lyne.ca \
  --email=certificates@harte-lyne.ca \
  --digest=sha512 \
  --verbose \
  "CN=HLL_ROOT,OU=Networked Data Services,O=Harte & Lyne Limited,L=Hamilton,ST=Ontario,C=CA,DC=harte-lyne,DC=ca"

Then I see this:

openssl genrsa  -des3 -passout pass:'a test' -out /home/byrnejb/Projects/Software/rcsp/ca_test_a/csp/HLL_ROOT/private/ca.key 4096

followed by:

openssl genrsa  -des3 -passout pass:'a test' -out /home/byrnejb/Projects/Software/rcsp/ca_test_a/csp/HLL_ROOT/private/ca.key 4096

and ending with:

[CSP][HLL_ROOT] Successfully initialized self-signed CA HLL_ROOT

However, the expected outputs of ca.key and ca.crt are not found in the directories shown as arguments in the commands above.

$ find /home/byrnejb/Projects/Software/rcsp/ca_test_a/csp/HLL_ROOT -name ca\.\*
$ 

Yet, if I copy and paste those exact commands into my bash session shell they work.

openssl genrsa  -des3 -passout pass:'a test' -out /home/byrnejb/Projects/Software/rcsp/ca_test_a/csp/HLL_ROOT/private/ca.key 4096
Generating RSA private key, 4096 bit long modulus
.....................................++
........................++
e is 65537 (0x10001)

and

openssl req  -config /home/byrnejb/Projects/Software/rcsp/ca_test_a/csp/HLL_ROOT/tmp/csp-8154.conf  -x509 -sha512 -days 7318  -key /home/byrnejb/Projects/Software/rcsp/ca_test_a/csp/HLL_ROOT/private/ca.key -passin pass:'a test' -new -out /home/byrnejb/Projects/Software/rcsp/ca_test_a/csp/HLL_ROOT/ca.crt

yields:

$ find /home/byrnejb/Projects/Software/rcsp/ca_test_a/csp/HLL_ROOT -name ca\.\*
/home/byrnejb/Projects/Software/rcsp/ca_test_a/csp/HLL_ROOT/private/ca.key
/home/byrnejb/Projects/Software/rcsp/ca_test_a/csp/HLL_ROOT/ca.crt

That seems to me that the commands are being created properly but that the openssl utility is not being called. As there is no branching code in the section where these commands are generated I conclude that the construct $self->{openssl}->cmd('req',"-x509 $common_args -new -out $cacert",$args); is the actual call to openssl but I do not know how this is meant to work.

How is this supposed to work? Why is it not working?

And should not the return code from openssl be checked?

2 个答案:

答案 0 :(得分:0)

Per @simbabque评论openssl调用的地方是:

1398    use IPC::Run qw( start pump finish timeout new_appender new_chunker);
        . . .
1418    sub cmd
1419      {
1420        my $self = shift;
1421        my $cmd = shift;
1422        my $cmdline = shift;
1423        my $args = shift;
1424        
1425        my $conf;
1426        my $cfgcmd;
        . . .
1448        $self->{_handle}->pump while length ${$self->{_in}};
        . . .

潜在的困难是在密码短语中使用嵌入式空格。编写代码时,代码将IPC:Run的参数作为连接字符串传递。对于作为字符串传递的参数IPC:Run使用white-space作为参数分隔符。处理此问题的正确方法是重构代码以使用数组来传递参数。

答案 1 :(得分:0)

我是该软件包的原始作者,很久以前我就放弃了它,原因显而易见。去看看https://github.com/leifj/ici可以更容易维护的东西(甚至基本上只是bash脚本)