## OpenCA - CA Command
## (c) 1998-2001 by Massimiliano Pala and OpenCA Group
##
##   File Name: bpRevokeCertificate
##     Version: $Revision: 1.7.2.2 $
##       Brief: Revoke Certificates
## Description: 
##  Parameters: operator, role, passwd

sub cmdBpRevokeCertificate {

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

my $tempDir  = getRequired ("TempDir");
my $chainDir = getRequired ( 'ChainDir' );

my ($request, $crr_cert, $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_RevokeCertificateSheet'));
	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 ("Revoke Certificate Batch Processor"));

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

print addLogSection (gettext ("Revoked certificate's role ... "));
print addLogLine    ($role);
print closeLogSection ();

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

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

	$key = $request->getSerial();

	## load the affected certificate
	$crr_cert = $db->getItem (DATATYPE => "CERTIFICATE",
				KEY => $request->getParsed()->{REVOKE_CERTIFICATE_SERIAL});
	if (not $crr_cert) {
		print addPreLogLine ("<FONT COLOR=#FF0000>".
				i18nGettext (
                  "CRR __CRR_SERIAL__ ingored because cannot load the affected certificate __CERT_SERIAL__",
                  "__CRR_SERIAL__", $request->getSerial(),
				  "__CERT_SERIAL__", $request->getParsed()->{REVOKE_CERTIFICATE_SERIAL}).
				"</FONT>");
		next;
	}

	## check the role of the affected certificate
	if ($crr_cert->getParsed()->{HEADER}->{ROLE} !~ /^$role$/) {
		print addPreLogLine (
                i18nGettext (
                  "CRR __CRR_SERIAL__ ingored because the requested role is __ROLE__.",
                  "__CRR_SERIAL__", $request->getSerial(),
				  "__ROLE__", $request->getParsed()->{HEADER}->{ROLE}));
		next;
	}

	## verify role of affected certificate
	if (not $tools->saveFile( FILENAME => "${tempDir}/${$}.role",
				DATA       => $role )) {
		unlink ("${tempDir}/${$}.role");
		print addPreLogLine ("<FONT COLOR=#FF0000>".
                i18nGettext (
				  "CRR __CRR_SERIAL__ ingored because temporary file with the affected certificates's role cannot be written.",
                  "__CRR_SERIAL__", $request->getSerial()).
				"</FONT>");
		next;
	}
	if (not $tools->saveFile( FILENAME => "${tempDir}/${$}.sig",
				DATA       => $crr_cert->getParsed()->{HEADER}->{ROLE_SIGNATURE} )) {
		unlink ("${tempDir}/${$}.role");
		unlink ("${tempDir}/${$}.sig");
		print addPreLogLine ("<FONT COLOR=#FF0000>".
                i18nGettext (
				  "CRR __CRR_SERIAL__ ingored because temporary file with the signature of the affected certificate's role cannot be written.",
                  "__CRR_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 (
				  "CRR __CRR_SERIAL__ ingored because the verification of the affected certificate's role failed.",
                  "__CRR_SERIAL__", $request->getSerial()).
				"</FONT>");
		next;
	}

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

	## check the signature
	if (not libCheckSignature (OBJECT => $request, SIGNATURE => $signature)) {
		print addPreLogLine ("<FONT COLOR=#FF0000>".
                i18nGettext (
				  "CRR __CRR_SERIAL__ ingored because the verification of the signature fails.",
                  "__CRR_SERIAL__", $request->getSerial()).
				"</FONT>");
		next;
        }

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

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

	## verify role of signer
	if (not $tools->saveFile( FILENAME => "${tempDir}/${$}.role",
				DATA       => $operator )) {
		unlink ("${tempDir}/${$}.role");
		print addPreLogLine ("<FONT COLOR=#FF0000>".
                i18nGettext (
				  "CRR __CRR_SERIAL__ ingored because temporary file with the signer's role cannot be written.",
                  "__CRR_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 (
				  "CRR __CRR_SERIAL__ ingored because temporary file with the signature of the signer's role cannot be written.",
                  "__CRR_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 (
				  "CRR __CRR_SERIAL__ ingored because the verification of the signer's role failed.",
                  "__CRR_SERIAL__", $request->getSerial()).
				"</FONT>");
		next;
	}

	## issue certificate
	$cert = libRevokeCertificate (KEY => $request->getSerial(),
				PASSWD    => $passwd);
	if (not $cert) {
		print addPreLogLine ("<FONT COLOR=#FF0000>".
				i18nGettext ("CRR __CRR_SERIAL__ failed.", "__CRR_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__ revoked from certificate revocation request __CRR_SERIAL__",
                  "__CERT_SERIAL__", $cert->getSerial(),
				  "__CRR_SERIAL__", $request->getSerial()).
				"</FONT>");
	}
}

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

print closePage();

}

1;
