## OpenCA Command
## (c) 1998-2001 by OpenCA Group
##
##   File Name: new_ask4rev
##       Brief: begin to revoke a certificate
## Description: get the certificate which should be revoked and prompt
##              the user to a second ok
##  Parameters: serial, crin, crin2, reason

sub cmdConfirm_revreq {

## Reserved variables
my ( $text, $cert, @search, $certTable );

## Get required configuration parametes
my $basedoc     = getRequired( "RevReqConfirmSheet" );
my $server	= getRequired( 'CgiServerType' );
my $chainDir    = getRequired( 'ChainDir');

## To aprove a Request, we need it signed by the RA operator
my $beginHeader = "-----BEGIN HEADER-----";
my $endHeader = "-----END HEADER-----";

## Get the parameters
my $serial      = $query->param('serial');
my $crin        = $query->param('crin');
my $crin2       = $query->param('crin2');
my $reason	= $query->param('reason');

my $cmdspanel = $tools->getFile ( getRequired ('RevReqIncSignature') );

## download the certificate
my $cert = $db->getItem ( DATATYPE => "CERTIFICATE", KEY => $serial );
if (not $cert) {
	##// it's not good to show the user the detailed problem
	configError (i18nGettext ("Error: Cannot find the certificate __CERT_SERIAL__ in the database.",
                              "__CERT_SERIAL__", $serial));
}
my $parsed = $cert->getParsed();

## Check for equal crin codes
if ( $crin ne $crin2 ) {
	configError (gettext ("CRIN codes are different, go back and check it."));
} elsif ($crin) {
	my $hashed_crin = $cryptoShell->getDigest ( DATA => $crin, ALGORITHM => "sha1" );

	## get the informations about the crin
	my $pin     = $cert->getParsed()->{HEADER}->{PIN};
	my $pin_sig = $cert->getParsed()->{HEADER}->{PIN_SIGNATURE};
	
	## check the signature of the PIN

	my $tempDir = getRequired ('TempDir');
	## pin -> file
	$tools->saveFile( FILENAME=>"${tempDir}/${$}.txt", DATA=>$cert->getSerial."\n".$pin );
	## pin_sig -> file
	$tools->saveFile( FILENAME=>"${tempDir}/${$}.sig", DATA=>$pin_sig );
	## verify signature
	## Build a new PKCS7 object
        my $sig = new OpenCA::PKCS7( SHELL=>$cryptoShell,
				     INFILE=>"${tempDir}/${$}.sig",
				     DATAFILE=>"${tempDir}/${$}.txt",
				     CA_DIR=>$chainDir );
	## remove files
	unlink ("${tempDir}/${$}.sig");
	unlink ("${tempDir}/${$}.txt");
	## if I have some time then I have to implement this
	if (not $sig) {
		##// it's not good to show the user the detailed problem
		## this is a security problem here !!!
		print STDERR "SECURITY ALERT BY PKI: the signature of the pin is corrupt (certificate: $serial)\n";
		configError (gettext ("The signature of the PIN is corrupt!"));
	}

	## check the crin
	if ($pin ne $hashed_crin) {
		## crin-mismatch
		## should I sent here a general error?
		my $basedoc = getRequired ('RevReqStartSheet');
		my $page    = $tools->getFile ( $basedoc );
		$page       = $query->subVar ($page, '@SERIAL@', $serial);
		$page       = $query->subVar ($page, '@REASON@', $reason);
		print $page;
		print STDERR "SECURITY ALERT BY PKI: attempt to revoke a certificate with a wrong pin (certificate: $serial)\n";
		return undef;
	}
	$cmdspanel .= $tools->getFile ( getRequired ('RevReqIncPIN') );
}

## Strip html and \n\r code from reason
$reason =~ s/<[^\>]*>/ /g;
$reason =~ s/(\n|\r)/ /g;
$reason =~ s/^\s+//g;
$reason =~ s/[\s]+/ /g;

## Load base page
my $page = $tools->getFile ( $basedoc );

## Get the certificate serial number of the submitter
my $sslCert  =($ENV{'SSL_CLIENT_CERT_SERIAL'} or $ENV{'SSL_CLIENT_M_SERIAL'});
my $sslDn    = $ENV{'SSL_CLIENT_S_DN'};
my $issuerDn = $ENV{'SSL_CLIENT_I_DN'};

$sslDn =~ s/^\///;
$sslDn =~ s/\/([^=]+)=/\, $1=/g;

$issuerDn =~ s/^\///;
$issuerDn =~ s/\/([^=]+)=/\, $1=/g;

if( $sslCert eq "" ) {
        $sslCert = "n/a";
} else {
        if ( length( $sslCert ) % 2 ) {
                $sslCert = "0" . $sslCert;
        }
}

my $last_crr = libDBGetLastItem ("CRR");
my $crr_serial = 0;
$crr_serial    = $last_crr->getSerial("CRR") if ($last_crr);
$crr_serial  >>= getRequired ("ModuleShift");
if (not $serial) {
	##// it's not good to show the user the detailed problem
	## this is a security problem here !!!
	print STDERR "SECURITY ALERT BY PKI: correct CRR cannot be stored because of DB-error (certificate: $serial)\n";
	configError (gettext ("A databaseerror occurs during counting the existing CRRs!"));
}
$crr_serial++;
$crr_serial = ($crr_serial << getRequired ("ModuleShift")) | getRequired ("ModuleID");

## Set Text to sign
$head  = "$beginHeader\n";
$head .= "TYPE = CRR\n";
$head .= "SERIAL = $crr_serial\n";
$head .= "SSL_CERT_SERIAL = $sslCert\n";
$head .= "SSL_CERT_DN = $sslDn\n";
$head .= "SSL_CERT_ISSUER = $issuerDn\n";
$head .= "$endHeader\n";

$text .= "SUBMIT_DATE = " . $tools->getDate() . "\n";
if ( $server =~ /^RA$/i ) {
	$text .= "APPROVED_DATE = " . $tools->getDate() . "\n";
}
$text .= "CRIN = $crin\n";
$text .= "REVOKE_REASON = $reason\n";
$text .= "REVOKE_CERTIFICATE_DN = " . $parsed->{DN} . "\n";
$text .= "REVOKE_CERTIFICATE_NOTBEFORE = " . $parsed->{NOTBEFORE} . "\n";
$text .= "REVOKE_CERTIFICATE_NOTAFTER = " . $parsed->{NOTAFTER} . "\n";
$text .= "REVOKE_CERTIFICATE_SERIAL = " . $cert->getSerial(). "\n";
$text .= "REVOKE_CERTIFICATE_ISSUER_DN = " . $parsed->{ISSUER} . "\n";
$text .= "REVOKE_CERTIFICATE_KEY_DIGEST = " . $parsed->{KEY_DIGEST} . "\n";

my $tmpIssuer = $parsed->{ISSUER};
my $tmpDN     = $parsed->{DN};
my $tmpStatus = $status;

$tmpIssuer =~ s/\,\s*/<BR>\n/g;
$tmpDN =~ s/\,\s*/<BR>\n/g;

$certTable .= $query->startTable( COLS=>[ @cols ], WIDTH=>"100%",
                                                   BGCOLOR=>"#EEEEF1",
                                                   TITLE_BGCOLOR=>"#DDCCFF" );

$certTable .=$query->addTableLine(DATA=>["<B>".gettext("Certificate Version:")."</B>",
                                ($parsed->{VERSION} or gettext("n/a")) ]);
$certTable .=$query->addTableLine(DATA=>[ "<B>".gettext("Serial Number:")."</B>",
                                ($cert->getSerial() or gettext("n/a")) ]);
$certTable .=$query->addTableLine(DATA=>[ "<B>".gettext("Distinguished Name:")."</B>",
                                ($tmpDN or gettext("n/a")) ]);
$certTable .=$query->addTableLine(DATA=>[ "<B>".gettext("Issued by:")."</B>",
                                ($tmpIssuer or gettext("n/a")) ]);
$certTable .=$query->addTableLine(DATA=>[ "<B>".gettext("Valid From:")."</B>",
                                ($parsed->{NOTBEFORE} or gettext("n/a")) ]);
$certTable .=$query->addTableLine(DATA=>[ "<B>".gettext("Expiration on:")."</B>",
                                ($parsed->{NOTAFTER} or gettext("n/a")) ]);
$certTable .=$query->addTableLine(DATA=>[ "<B>".gettext("Revoke Reason:")."</B>",
                                ($reason or gettext("n/a")) ]);
$certTable .= $query->endTable();

## Substitute the Variables in the $page
$page = $query->subVar( $page, '@TEXT@',      $text);
$page = $query->subVar( $page, '@HEADER@',    $head);
$page = $query->subVar( $page, '@CRIN@',      $crin);
$page = $query->subVar( $page, '@TABLE@',     $certTable);
$page = $query->subVar ($page, '@CMDSPANEL@', $cmdspanel);
$page = $query->subVar ($page, '@SERIAL@',    $cert->getSerial());
$page = $query->subVar ($page, '@REASON@',    $reason);

print "$page";

}

1;
