#!/usr/bin/perl -w
use strict;
my $config_file = "/tmp/openssl.cnf.$$";	# Where to write the config file
my $keyname;			# Generally, the primary FQDN
my $org_unit;			# Organisational unit for csr, ie Web Services
my @altnames;			# Alternate dns names for csr, ie www1.example.com, www1.example.net etc
my $altname;			# Alternate dns names for csr, ie www1.example.com, www1.example.net etc
my $altcount = 1;		# Can only have 16 or less alts (when submitting to Verisign)
my $altflag = 1;		# flag for my while loop
my @config_out;			# Populate with all info for the config file.
my $email_address;		# email address to be tagged on the certificate
my $proc_base_name;		# basename of the process, simply for naming conventions
my $mutual_tls = "y";	# flag for mutual tls for client app stuff
my $home = $ENV{'HOME'};# Get user's home directory to store files in.
my $self_signed = 1;	# self-sign key
chomp $home;
my $random_file = "$home/.rnd";	 #openssl for hpux needs a .rnd file to work

#  If config file exists, exit and alert user
unlink $config_file if -e $config_file;

if (!-e $random_file) {
	`dd bs=512 count=4 if=/dev/null of=$random_file`
	##die ("Random file couldn't be found at $random_file\n");
}
#  Open config file to write ssl stuff out to
open (CONFIG, ">$config_file")||die "Can't open $config_file for writing\n";
# Start getting info from user
print ("Generate SSL Cert stuff for SAPI\n");
print ("FQDN/Keyname for Cert \(ie www.example.com\)\t\t:");
if ( @ARGV ) {
	$keyname = shift @ARGV;
	print "$keyname\n";
	@altnames = map { "DNS:$_" } @ARGV;
	$altflag=0;
} else {
	chomp ($keyname=<STDIN>);
	while ($altflag) {
		print ("Alt Names (ie www1.example.com or <return> for none)\t\t\t:");
		chomp($altname=<STDIN>);
		if ($altcount < 16) {
			if ($altname eq $keyname) {
				print (" ****** Alternate name can not equal main keyname ******\n");
			} elsif ($altname ne "") {
				push (@altnames, "DNS:$altname");
				$altcount++;
			} else {
				$altflag=0;
			}
		} else {
			$altflag=0;
		}
	}
}

#print ("Host short name (ie imap big_srv etc)\t\t\t\t:");
#chomp ($proc_base_name=<STDIN>);
$proc_base_name = $keyname;

# Start building the config file
push (@config_out, "# -------------- BEGIN custom openssl.cnf -----\n");
push (@config_out, "HOME		    = $home\n");
push (@config_out, "RANDFILE		= $random_file\n");
push (@config_out, "oid_section	     = new_oids\n");
push (@config_out, "[ new_oids ]\n");
push (@config_out, "[ req ]\n");
push (@config_out, "default_bits	    = 2048\n");
push (@config_out, "default_days    = 730		   # how long to certify for\n");
#push (@config_out, "default_keyfile	 = $home/${proc_base_name}_privatekey.pem\n");
push (@config_out, "distinguished_name      = req_distinguished_name\n");
push (@config_out, "encrypt_key	     = no\n");
push (@config_out, "string_mask = nombstr\n");
push (@config_out, "req_extensions = v3_req # Extensions to add to certificate request\n");
push (@config_out, "[ req_distinguished_name ]\n");
push (@config_out, "commonName		      = Common Name (eg, YOUR name)\n");
push (@config_out, "commonName_default	      = $keyname\n");
push (@config_out, "commonName_max		  = 64\n");
push (@config_out, "[ v3_req ]\n");
	if ($altnames[0] ne "") {
		$altname=join(',', @altnames);
		push (@config_out, "subjectAltName=$altname\n");
	}
push (@config_out, "# -------------- END OpsSec-provided openssl.cnf -----\n");
#  Write shit to file
print (CONFIG "@config_out");
warn @config_out;
close CONFIG;
#  Generate ssl stuff
print ("\nAttempting openssl...\n");
if ( $self_signed ) {
	my $out = "$home/${proc_base_name}.pem";
	system "openssl req -new -x509 -days 365 -nodes -config $config_file -out $out -keyout $out";
	print "Generated self-signed certificate $out\n";
} else {
	system ("openssl req -batch -config $config_file -newkey rsa:2048 -out $home/${proc_base_name}_csr.pem");
	print ("\nwriting csr to $home/${proc_base_name}_csr.pem...\n\n");
	print ("Take the contents of $home/${proc_base_name}_csr.pem and go submit them to receive an SSL ID.  When you receive your public key back, you 'should' name it something like '${proc_base_name}_server.pem'.  ");
}
`rm $config_file`;
