## OpenCA - CA Command
## (c) 1998-2001 by Massimiliano Pala and OpenCA Group
##
##   File Name: bpCreateKey
##     Version: $Revision: 1.7 $
##       Brief: create Keypairs for new users
## Description: 
##  Parameters:

sub cmdBpCreateKey {

	print startLogPage (gettext ("Create Keypair Batch Processor"));

	## datadirectory for the batchprocessor
	my $batch_dir  = getRequired ("BP_DIR");

	print addLogSection (gettext ("Running batch processor ..."));

	bpScanDir ($batch_dir, "bpCreateKey");

	print addPreLogLine ("");
	print addLogLine (gettext ("Batch processor finished"));
	print closeLogSection ();

	print closePage();

}

sub bpCreateKey {
	my $dir = $_[0];

	## check for ID
	if ( (-f $dir."/ID") and
	     (-f $dir."/acl/newKey") and
	     (not -f $dir."/private/privateKey") ) {

		## get new key
		my $pin;
		my $key_length, key_alg;

		## determine keylength
		if (-f $dir."/data/KEY_LENGTH") {
			$key_length = $tools->getFile ($dir."/data/KEY_LENGTH");
		} else {
			$key_length = getRequired ("BP_DEFAULT_KEY_LENGTH");
		}

		## check length
		if (not $key_length) {
			print addPreLogLine ("<FONT COLOR=#FF0000>".
				    i18nGettext (
                      "Cannot determine the keylength - ID __ID__ ignored.",
                      "__ID__", $tools->getFile ($dir."/ID")).
				    "</FONT>");
			return;
		}
		if ($key_length < getRequired ("BP_MINIMUM_KEY_LENGTH")) {
			print addPreLogLine ("<FONT COLOR=#FF0000>".
				    i18nGettext (
                      "Used keylength to small (__KEYLENGTH__ &lt; __MIN_KEYLENGTH__) - ID __ID__ ignored.",
                      "__KEYLENGTH__", $key_length,
                      "__MIN_KEYLENGTH__", getRequired ("BP_MINIMUM_KEY_LENGTH"),
				      "__ID__", $tools->getFile ($dir."/ID")).
				    "</FONT>");
			return;
		}

		## determine keyalgorithm
		if (-f $dir."/data/KEY_ALGORITHM") {
			$key_alg = $tools->getFile ($dir."/data/KEY_ALGORITHM");
		} else {
			$key_alg = getRequired ("BP_DEFAULT_KEY_ALGORITHM");
		}

		## check keyalgorithm
		if (not $key_alg) {
			print addPreLogLine ("<FONT COLOR=#FF0000>".
				    i18nGettext (
                      "Cannot determine the keyalgorithm - ID __ID__ ignored.",
                      "__ID__", $tools->getFile ($dir."/ID")).
				    "</FONT>");
			return;
		}
		if ($key_alg !~ /^(rsa|dsa)$/i) {
			print addPreLogLine ("<FONT COLOR=#FF0000>".
				    i18nGettext (
                      "Used keyalgorithm is not supported (use rsa or dsa and not __KEY_ALG__) - ID __ID__ ignored.",
                      "__KEY_ALG__", $key_alg,
				      "__ID__", $tools->getFile ($dir."/ID")).
				    "</FONT>");
			return;
		}

		## load the PIN
		if (not -f $dir."/private/purePIN") {
			print addPreLogLine ("<FONT COLOR=#FF0000>".
				    i18nGettext (
                      "There is no PIN available to encrypt the new private key - ID __ID__ ignored.",
                      "__ID__", $tools->getFile ($dir."/ID")).
				    "</FONT>");
			return;
		}
		$pin = $cryptoShell->getSMIME (
		                                  DECRYPT    => 1,
		                                  CERT       => getRequired ("BP_CERTIFICATE"),
		                                  KEY        => getRequired ("BP_KEY"),
		                                  USE_ENGINE => 1,
		                                  PASSWD     => $query->param ('passwd'),
		                                  INFILE     => $dir."/private/purePIN",
		                                  );
		( $pin ) = ( $pin =~ /-----BEGIN PIN-----[\n\r]*([^\n\r]*)[\n\r]*-----END PIN-----/i);
		if (not $pin) {
			print addPreLogLine (
			          "<FONT COLOR=#FF0000>".
			          i18nGettext (
				      "Cannot load the PIN to encrypt the new private key because the decryption of the PIN failed - ID __ID__ ignored.",
			              "__ID__", $tools->getFile ($dir."/ID")).
			          "</FONT>");
			return;
		}

		## generate key
		if( not $cryptoShell->genKey(
					BITS    => $key_length,
					OUTFILE => $dir."/private/privateKey",
					TYPE    => $key_alg,
					PASSWD  => $pin) ) {
			print addPreLogLine ("<FONT COLOR=#FF0000>".
				    i18nGettext (
                      "Cannot generate a new key - ID __ID__ ignored.",
                      "__ID__", $tools->getFile ($dir."/ID"))."<br>".
				    i18nGettext (
				      "OpenSSL fails with errorcode __ERRNO__.",
                      "__ERRNO__", $OpenCA::OpenSSL::errno)."<br>".
				    $OpenCA::OpenSSL::errval.
				    "</FONT>");
			return;
		}

		## remove permission to generate this new key
		if (not unlink $dir."/acl/newKey") {
			print addPreLogLine ("<FONT COLOR=#FF0000>".
				    i18nGettext (
                      "Cannot remove permission to create a new key but the new key was already generated - ID __ID__.",
                      "__ID__", $tools->getFile ($dir."/ID")).
				    "</FONT>");
			return;
		}

		print addPreLogLine (i18nGettext ("Generated a new key for ID __ID__.", "__ID__", $tools->getFile ($dir."/ID")));

	}
}

1;
