## OpenCA - Public Web-Gateway Command
## (c) 1998-2001 by OpenCA Group
##
##   File Name: submit_revreq
##       Brief: store the revreq to the DB
## Description: store the revreq to the DB for RA Operator approval
##  Parameters: head, text, signature

sub cmdSubmit_revreq {

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

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

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

## Get the parameters
my $head        = $query->param('head');
my $body        = $query->param('text');
my $signature   = $query->param('signature');
my $serial	= $query->param('serial');
my $reason	= $query->param('reason');

## Load base page
my $page = $query->getFile ( $basedoc );
if ( not $page ) {
	configError (i18nGettext("Cannot load file __FILE__!", "__FILE__", $page));
}

my $req_txt = $head . $body;

if ( $signature ne "" ) {
	$req_txt .= $beginSig . "\n" . $signature . 
		    "\n" . $endSig . "\n";
}

## Try to build the REQ object
my $req = new OpenCA::REQ ( SHELL=>$cryptoShell, DATA=>$req_txt );

if( not $req ) {
	configError( gettext("Error while creating the request."));
}

## download the certificate
my $cert = $db->getItem ( DATATYPE => "CERTIFICATE", KEY => $req->getParsed()->{REVOKE_CERTIFICATE_SERIAL} );
if (not $cert) {
	##// it's not good to show the user the detailed problem
	my $basedoc = getRequired ('db_error');
	print $tools->getFile ( $basedoc );
	return undef;
}

## check the pin/crin again
if ($req->getParsed()->{CRIN} or not $signature) {
	my $crin = $cryptoShell->getDigest ( DATA => $req->getParsed()->{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=>$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 !!!
		my $basedoc = getRequired ('db_error');
		print $tools->getFile ( $basedoc );
		print STDERR "SECURITY ALERT BY PKI: the signature of the pin is corrupt (certificate: $serial)\n";
		return undef;
	}

	## check the crin
	if ($pin ne $crin) {
		## crin-mismatch
		## should I sent here a general error?
		my $basedoc = getRequired ('RevReqStartSheet');
		my $page    = $query->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;
	}
}

if ( not $db->storeItem( OBJECT=>$req, DATATYPE=>"PENDING_CRR", MODE => "INSERT" )) {
	configError( gettext("Error while storing the request."));
	print STDERR "SECURITY ALERT BY PKI: database failed during storing a correct CRR which follows\n".
		$req_txt."\n";
	return undef;
}

if ( not $db->storeItem ( OBJECT => $cert, DATATYPE => "SUSPENDED_CERTIFICATE", MODE => "UPDATE")) {
	print STDERR "SECURITY ALERT BY PKI: database failed during storing a correct CRR which follows\n".
		$req_txt."\n";
	configError( gettext("Failed to change the certificate's state."));
}

print "$page";

return 1;

}

1;

