On 06/13/2011 10:08 PM, Scott Schaefer wrote:
On 06/13/2011 06:10 AM, Kurt Roeckx wrote:
On Fri, May 06, 2011 at 08:35:57AM -0400, Scott Schaefer wrote:
See attached. Prints "completion" message only on successful return.
Also fixes bug which prevents executing -newreq-nodes option, and
includes newer options in usage message.
Can you also check the CA.sh script for the same problems?
Kurt
I will be glad to submit patch for CA.sh, since, on quick review, it
indeed has same two problems as CA.pl; i.e.
1) It prints "success" messages, even on failure of underlying SSL
command(s), and
2) The usage message in lacking the newer, added valid arguments,
This will probably require 24-48 hours, since I have travel commitment
tomorrow.
OTOH, my assertion that my original patch for CA.pl 'fixes bug which
prevents executing -newreq-nodes option' is WRONG. I badly misread
that code in order to conclude what I did; i.e. the original code does
execute both -newreq and -newreq-nodes options correctly.
Note the patch still correctly executes both options, and both did
incorrectly print "success" message even on failure of underlying SSL
command. For this reason, I would prefer to leave the patch intact,
and simply change the second part of the description to only "Also
includes newer options in usage message". If you prefer, I can submit
revised patch file that does not re-order the testing of command-args
vs patterns /^-newreq$/ and/^-newreq-nodes$/.
Attached are two patches. The first is a replacement for the original
and applies to CA.pl. The second is new, and applies to CA.sh.
Please note that both of these are less-than-thoroughly tested. I have
verified most of the functionality, but not all of the boundary cases
which I would normally test before releasing as production code. In
addition, the original(s) had some inconsistencies and unclear design
choices which I am not certain I understand the rationale for.
However, I am starting my first vacation of more than three days in over
six years tomorrow morning, and will be unable to test any more until my
return.
diff --git a/apps/CA.pl b/apps/CA.pl
--- a/apps/CA.pl
+++ b/apps/CA.pl
@@ -44,6 +44,26 @@
$ENV{OPENSSL} = $openssl;
}
+sub system_command() {
+ my $cmd = shift;
+ my $ret = 2;
+ if ($cmd) {
+ system($cmd);
+ if ($? == -1) {
+ print "ERROR: Failed to execute: $cmd\n";
+ exit 1;
+ }
+ elsif ($? & 127) {
+ printf "ERROR: Process died with signal %d, %s coredump\n",($? & 127),(($? & 128) ? 'with' : 'without');
+ exit 1;
+ }
+ else {
+ $ret = $? >> 8;
+ }
+ }
+ $ret;
+}
+
$SSLEAY_CONFIG=$ENV{"SSLEAY_CONFIG"};
$DAYS="-days 365"; # 1 year
$CADAYS="-days 1095"; # 3 years
@@ -62,25 +82,39 @@
$RET = 0;
+$USAGE = <<"_USAGE_";
+usage: $0 -newcert | -newreq | -newreq-nodes | -newca |
+ -sign | -signreq | -signCA | -signcert | -xsign | pkcs12 | -verify
+_USAGE_
+$HELP_USAGE = <<"_HELP_USAGE_";
+usage: $0 option
+ Valid options
+ -newca : Create local CA directory structure
+ -newcert : Create certficate
+ -newreq|-newreq-nodes : Create certficate request
+ -sign|-signreq|-signCA|-signcert|-xsign : Sign cert/request
+ -pkcs12 name (default='My Certificate') : Create PKCS-12 certificate
+ -verify [file [file]]: Verifiy certificate(s); newcert.pem if no file(s)
+_HELP_USAGE_
+
+
foreach (@ARGV) {
+ $result='';
if ( /^(-\?|-h|-help)$/ ) {
- print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n";
+ print STDERR $HELP_USAGE;
exit 0;
} elsif (/^-newcert$/) {
# create a certificate
- system ("$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS");
- $RET=$?;
- print "Certificate is in newcert.pem, private key is in newkey.pem\n"
+ $RET=&system_command("$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS");
+ $result="Certificate is in newcert.pem, private key is in newkey.pem";
} elsif (/^-newreq$/) {
# create a certificate request
- system ("$REQ -new -keyout newkey.pem -out newreq.pem $DAYS");
- $RET=$?;
- print "Request is in newreq.pem, private key is in newkey.pem\n";
+ $RET=&system_command("$REQ -new -keyout newkey.pem -out newreq.pem $DAYS");
+ $result="Request is in newreq.pem, private key is in newkey.pem";
} elsif (/^-newreq-nodes$/) {
# create a certificate request
- system ("$REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS");
- $RET=$?;
- print "Request is in newreq.pem, private key is in newkey.pem\n";
+ $RET=&system_command("$REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS");
+ $result="Request is in newreq.pem, private key is in newkey.pem";
} elsif (/^-newca$/) {
# if explicitly asked for or it doesn't exist then setup the
# directory structure that Eric likes to manage things
@@ -111,62 +145,60 @@
$RET=$?;
} else {
print "Making CA certificate ...\n";
- system ("$REQ -new -keyout " .
+ $RET=&system_command("$REQ -new -keyout " .
"${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ");
- system ("$CA -create_serial " .
- "-out ${CATOP}/$CACERT $CADAYS -batch " .
- "-keyfile ${CATOP}/private/$CAKEY -selfsign " .
- "-extensions v3_ca " .
- "-infiles ${CATOP}/$CAREQ ");
- $RET=$?;
+ if ($RET==0) {
+ $RET=&system_command("$CA -create_serial " .
+ "-out ${CATOP}/$CACERT $CADAYS -batch " .
+ "-keyfile ${CATOP}/private/$CAKEY -selfsign " .
+ "-extensions v3_ca " .
+ "-infiles ${CATOP}/$CAREQ ");
+ }
}
}
} elsif (/^-pkcs12$/) {
my $cname = $ARGV[1];
$cname = "My Certificate" unless defined $cname;
- system ("$PKCS12 -in newcert.pem -inkey newkey.pem " .
- "-certfile ${CATOP}/$CACERT -out newcert.p12 " .
- "-export -name \"$cname\"");
- $RET=$?;
- print "PKCS #12 file is in newcert.p12\n";
+ $RET=&system_command("$PKCS12 -in newcert.pem -inkey newkey.pem " .
+ "-certfile ${CATOP}/$CACERT -out newcert.p12 " .
+ "-export -name \"$cname\"");
+ print "PKCS #12 file is in newcert.p12\n" if ($RET==0);
exit $RET;
} elsif (/^-xsign$/) {
- system ("$CA -policy policy_anything -infiles newreq.pem");
- $RET=$?;
+ $RET=&system_command("$CA -policy policy_anything -infiles newreq.pem");
} elsif (/^(-sign|-signreq)$/) {
- system ("$CA -policy policy_anything -out newcert.pem " .
- "-infiles newreq.pem");
- $RET=$?;
- print "Signed certificate is in newcert.pem\n";
+ $RET=&system_command("$CA -policy policy_anything -out newcert.pem " .
+ "-infiles newreq.pem");
+ $result="Signed certificate is in newcert.pem";
} elsif (/^(-signCA)$/) {
- system ("$CA -policy policy_anything -out newcert.pem " .
+ $RET=&system_command("$CA -policy policy_anything -out newcert.pem " .
"-extensions v3_ca -infiles newreq.pem");
- $RET=$?;
- print "Signed CA certificate is in newcert.pem\n";
+ $result="Signed CA certificate is in newcert.pem";
} elsif (/^-signcert$/) {
- system ("$X509 -x509toreq -in newreq.pem -signkey newreq.pem " .
- "-out tmp.pem");
- system ("$CA -policy policy_anything -out newcert.pem " .
- "-infiles tmp.pem");
- $RET = $?;
- print "Signed certificate is in newcert.pem\n";
+ $RET=&system_command("$X509 -x509toreq -in newreq.pem -signkey newreq.pem " .
+ "-out tmp.pem");
+ if ($RET==0) {
+ $RET=&system_command("$CA -policy policy_anything -out newcert.pem " .
+ "-infiles tmp.pem");
+ }
+ $result="Signed certificate is in newcert.pem";
} elsif (/^-verify$/) {
+ shift;
if (shift) {
+ $RET = 0;
foreach $j (@ARGV) {
- system ("$VERIFY -CAfile $CATOP/$CACERT $j");
- $RET=$? if ($? != 0);
+ my $v_ret=&system_command("$VERIFY -CAfile $CATOP/$CACERT $j");
+ $RET=$v_ret if ($v_ret != 0);
}
- exit $RET;
} else {
- system ("$VERIFY -CAfile $CATOP/$CACERT newcert.pem");
- $RET=$?;
- exit 0;
+ $RET=&system_command("$VERIFY -CAfile $CATOP/$CACERT newcert.pem");
}
} else {
print STDERR "Unknown arg $_\n";
- print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n";
+ print STDERR $USAGE;
exit 1;
}
+ print "$result\n" if (($result) && ($RET==0));
}
exit $RET;
diff --git a/apps/CA.sh b/apps/CA.sh
--- a/apps/CA.sh
+++ b/apps/CA.sh
@@ -55,7 +55,18 @@
}
usage() {
- echo "usage: $0 -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify" >&2
+ echo "usage: $0 -newcert | -newreq | -newreq-nodes | -newca |" >&2
+ echo " -sign | -signreq | -signCA | -signcert | -xsign | pkcs12 | -verify" >&2
+}
+help_usage() {
+ echo "usage: $0 option" >&2
+ echo " Valid options" >&2
+ echo " -newca : Create local CA directory structure" >&2
+ echo " -newcert : Create certficate" >&2
+ echo " -newreq|-newreq-nodes : Create certficate request" >&2
+ echo " -sign|-signreq|-signCA|-signcert|-xsign : Sign cert/request" >&2
+ echo " -pkcs12 name (default='My Certificate') : Create PKCS#12 certificate" >&2
+ echo " -verify [file [file]]: Verifiy certificate(s); newcert.pem if no file(s)" >&2
}
if [ -z "$OPENSSL" ]; then OPENSSL=openssl; fi
@@ -78,26 +89,32 @@
while [ "$1" != "" ] ; do
case $1 in
-\?|-h|-help)
- usage
+ help_usage
exit 0
;;
-newcert)
# create a certificate
$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS
RET=$?
- echo "Certificate is in newcert.pem, private key is in newkey.pem"
+ if [ $RET -eq 0 ]; then
+ echo "Certificate is in newcert.pem, private key is in newkey.pem"
+ fi
;;
-newreq)
# create a certificate request
$REQ -new -keyout newkey.pem -out newreq.pem $DAYS
RET=$?
- echo "Request is in newreq.pem, private key is in newkey.pem"
+ if [ $RET -eq 0 ]; then
+ echo "Request is in newreq.pem, private key is in newkey.pem"
+ fi
;;
-newreq-nodes)
# create a certificate request
$REQ -new -nodes -keyout newreq.pem -out newreq.pem $DAYS
RET=$?
- echo "Request (and private key) is in newreq.pem"
+ if [ $RET -eq 0 ]; then
+ echo "Request (and private key) is in newreq.pem"
+ fi
;;
-newca)
# if explicitly asked for or it doesn't exist then setup the directory
@@ -150,18 +167,24 @@
$PKCS12 -in newcert.pem -inkey newreq.pem -certfile ${CATOP}/$CACERT \
-out newcert.p12 -export -name "$CNAME"
RET=$?
- exit $RET
+ if [ $RET -eq 0 ]; then
+ echo "PKCS#12 file is in newcert.p12"
+ fi
;;
-sign|-signreq)
$CA -policy policy_anything -out newcert.pem -infiles newreq.pem
RET=$?
cat newcert.pem
- echo "Signed certificate is in newcert.pem"
+ if [ $RET -eq 0 ]; then
+ echo "Signed certificate is in newcert.pem"
+ fi
;;
-signCA)
$CA -policy policy_anything -out newcert.pem -extensions v3_ca -infiles newreq.pem
RET=$?
- echo "Signed CA certificate is in newcert.pem"
+ if [ $RET -eq 0 ]; then
+ echo "Signed CA certificate is in newcert.pem"
+ fi
;;
-signcert)
echo "Cert passphrase will be requested twice - bug?"
@@ -169,7 +192,9 @@
$CA -policy policy_anything -out newcert.pem -infiles tmp.pem
RET=$?
cat newcert.pem
- echo "Signed certificate is in newcert.pem"
+ if [ $RET -eq 0 ]; then
+ echo "Signed certificate is in newcert.pem"
+ fi
;;
-verify)
shift
@@ -177,6 +202,7 @@
$VERIFY -CAfile $CATOP/$CACERT newcert.pem
RET=$?
else
+ RET=0
for j
do
$VERIFY -CAfile $CATOP/$CACERT $j
@@ -188,7 +214,7 @@
exit $RET
;;
*)
- echo "Unknown arg $i" >&2
+ echo "Unknown arg $1" >&2
usage
exit 1
;;