## OpenCA - CA Command
## (c) 1998-2001 by Massimiliano Pala and OpenCA Group
##
##   File Name: issueCertificate
##     Version: $Revision: 1.6.2.1 $
##       Brief: Issue a Certificate
## Description: Issue a new Certificate
##  Parameters: key, dataType, passwd

sub cmdBpIssueCertificate {

## get the parameters
## Get the parameters
my $operator = $query->param('operator');
my $role     = $query->param('role');
my $passwd   = $query->param('passwd');
my $chainDir = getRequired('ChainDir');

my ($request, $operator_cert, $operator_serial, $signature, $role_sig, $cert);

if (not $operator or not $role or not $passwd) {
	## must be the startpage

	## load page
	my $page = $tools->getFile( getRequired ('BP_IssueCertificateSheet'));
	configError (gettext ("Cannot load the form for the batch processor for issuing certificate"))
		if (not $page);

        ## set values
	my $html_role = $query->newInput (
					-regx=>'LETTERS',
					-intype=>'popup_menu',
					-name=>'operator',
					-values=>[loadRoles()],
					-default=>$operator);
	$page = $query->subVar($page,'@OPERATOR@', $html_role);
	$html_role = $query->newInput (
					-regx=>'LETTERS',
					-intype=>'popup_menu',
					-name=>'role',
					-values=>[loadRoles()],
					-default=>$role);
	$page = $query->subVar($page,'@ROLE@', $html_role);

	## display
	print $page;

	return 1;
}

print startLogPage (gettext ("Issue Certificate Batch Processor"));

print addLogSection (gettext ("Operator's role ... "));
print addLogLine    ($operator);
print closeLogSection ();

print addLogSection (gettext ("Requested role ... "));
print addLogLine    ($role);
print closeLogSection ();

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

my $tempDir = getRequired ('TempDir');

## loop
## there can never be a request 0
my $key = 0;
while ($request = $db->getNextItem(DATATYPE => "APPROVED_REQUEST", KEY => $key)) {

	$key = $request->getSerial();

	## check the requsted role
	if ($request->getParsed()->{HEADER}->{ROLE} !~ /^$role$/) {
		print addPreLogLine (
                i18nGettext (
                  "CSR __CSR_SERIAL__ ignored because the requested role is __ROLE__.",
                  "__CSR_SERIAL__", $request->getSerial(),
				  "__ROLE__", $request->getParsed()->{HEADER}->{ROLE}));
		next;
	}

	## is there a signature?
	$signature = libGetSignatureObject (OBJECT => $request);
	if (not $signature) {
		print addPreLogLine ("<FONT COLOR=#FF0000>".
				i18nGettext (
                  "CSR __CSR_SERIAL__ ignored because there is no signature.",
                  "__CSR_SERIAL__", $request->getSerial()).
				"</FONT>");
		next;
	}

	## check the signature
	if (not libCheckSignature (OBJECT => $request, SIGNATURE => $signature)) {
		print addPreLogLine ("<FONT COLOR=#FF0000>".
				i18nGettext (
                  "CSR __CSR_SERIAL__ ignored because the verification of the signature fails. Error: __ERRNO__.",
                  "__ERRNO__", $errno,
                  "__CSR_SERIAL__", $request->getSerial()).
				"<br>\n$errval".
				"</FONT>");
		next;
	}

	##// load the signer's cert
	$operator_cert = libGetSignerCertificateDB (SIGNATURE => $signature);
	if (not $operator_cert) {
		print addPreLogLine ("<FONT COLOR=#FF0000>".
				i18nGettext (
				  "CSR __CSR_SERIAL__ ignored because the signer's certificate is not loadable.",
                  "__CSR_SERIAL__", $request->getSerial()).
				"</FONT>");
		next;
	}

	## check role of signer
	if ($operator_cert->getParsed()->{HEADER}->{ROLE} !~ /^$operator$/) {
		print addPreLogLine ("<FONT COLOR=#FF0000>".
				i18nGettext (
				  "CSR __CSR_SERIAL__ ignored because the signer's role is __ROLE__.",
                  "__CSR_SERIAL__", $request->getSerial(),
				  "__ROLE__", $operator_cert->getParsed()->{HEADER}->{ROLE}).
				"</FONT>");
		next;
	}

	## this brings nothing because database and cert are on the same machine
	## 
	## verify role of signer
	if (not $tools->saveFile( FILENAME => "${tempDir}/${$}.role",
				DATA       => $operator )) {
		unlink ("${tempDir}/${$}.role");
		print addPreLogLine ("<FONT COLOR=#FF0000>".
				i18nGettext (
				  "CSR __CSR_SERIAL__ ignored because temporary file with the signer's role cannot be written.",
                  "__CSR_SERIAL__", $request->getSerial()).
				"</FONT>");
		next;
	}
	if (not $tools->saveFile( FILENAME => "${tempDir}/${$}.sig",
				DATA       => $operator_cert->getParsed()->{HEADER}->{ROLE_SIGNATURE} )) {
		unlink ("${tempDir}/${$}.role");
		unlink ("${tempDir}/${$}.sig");
		print addPreLogLine ("<FONT COLOR=#FF0000>".
				i18nGettext (
				  "CSR __CSR_SERIAL__ ignored because temporary file with the signature of the signer's role cannot be written.",
                  "__CSR_SERIAL__", $request->getSerial()).
				"</FONT>");
		next;
	}
	$role_sig = new OpenCA::PKCS7(
				SHELL    => $cryptoShell,
				INFILE   => "${tempDir}/${$}.sig",
				DATAFILE => "${tempDir}/${$}.role",
				CA_DIR   => "${chainDir}",
				NOCHAIN  => "1" );
	unlink ("${tempDir}/${$}.role");
	unlink ("${tempDir}/${$}.sig");
	if (not $role_sig or ($role_sig->status() != 0)) {
		print addPreLogLine ("<FONT COLOR=#FF0000>".
				i18nGettext (
                  "CSR __CSR_SERIAL__ ignored because the verification of the signer's role failed. Error: __ERRNO__.",
                  "__CSR_SERIAL__", $request->getSerial(),
				  "__ERRNO__", $OpenCA::PKCS7::errno).
                "<br>\n".$OpenCA::PKCS7::errval.
				"</FONT>");
		next;
	}

	## issue certificate
	$cert = libIssueCertificate (KEY      => $request->getSerial(),
					DATATYPE => "APPROVED_REQUEST",
					PASSWD   => $passwd);
	if (not $cert) {
		print addPreLogLine ("<FONT COLOR=#FF0000>".
                i18nGettext ("CSR __CSR_SERIAL__ failed.", "__CSR_SERIAL__", $request->getSerial()).
				"<br>\n".
                i18nGettext ("Errorcode: __ERRNO__.", "__ERRNO__", $errno).
				"<br>\n".
                i18nGettext ("Errormessage: __ERRVAL__.", "__ERRVAL__", $errval).
				"</FONT>");
	} else {
		print addPreLogLine ("<FONT COLOR=#00FF00>".
                i18nGettext (
				  "Certificate __CERT_SERIAL__ issued from request __CSR_SERIAL__.",
                  "__CERT_SERIAL__", $cert->getSerial(),
				  "__CSR_SERIAL__", $request->getSerial()).
				"</FONT>");
	}

}

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

print closePage();

}

1;
