## 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 $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');

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=>$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,
                                     GETTEXT  => \&i18nGettext,
				     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 $crin) {
		## crin-mismatch
		## should I sent here a general error?
                my ($info_list, $hidden_list, $cmd_panel) = (undef, undef, undef);

                $info_list->{BODY}->[0]->[0] = gettext ("Certificate Serial Number");
                $info_list->{BODY}->[0]->[1] = '<Input type="text" name="serial" value="'.$serial.'">';
                $info_list->{BODY}->[1]->[0] = gettext ("Reason [ Reason for revocating the certificate ]");
                $info_list->{BODY}->[1]->[1] = '<textarea cols="35" rows="5" name="reason" wrap="virtual">'.$reason.'</textarea>';
                $info_list->{BODY}->[2]->[0] = gettext ("Please enter the CRIN which the owner of the private keys received during the process of issuing the certificate.");
                $info_list->{BODY}->[3]->[0] = gettext ("CRIN code [ revocation pin ]");
                $info_list->{BODY}->[3]->[1] = '<Input type="password" name="crin">';
                $info_list->{BODY}->[3]->[0] = gettext ("Retype CRIN code [ retype revocation pin ]");
                $info_list->{BODY}->[3]->[1] = '<Input type="password" name="crin2">';

                $hidden_list->{"cmd"} = "submit_revreq";
                $cmd_panel->[0]   = '<input type="submit" name="Submit" value="'.gettext ("Continue").'">';

		print STDERR "SECURITY ALERT BY PKI: attempt to revoke a certificate with a wrong pin (certificate: $serial)\n";
		libSendReply (
                              "NAME"        => gettext ("Certificate Revocation Request"),
                              "EXPLANATION" => gettext ("Certificate Data:\nIf you don't know the certificate's serial number please use the lists."),
                              "HIDDEN_LIST" => $hidden_list,
                              "INFO_LIST"   => $info_list,
                              "CMD_PANEL"   => $cmd_panel
                             );
                              
		return undef;
	}
}

if ( not $db->storeItem( OBJECT=>$req, DATATYPE=>"NEW_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->updateStatus ( DATATYPE=>"VALID_CERTIFICATE", OBJECT => $cert, NEWTYPE=>"SUSPENDED_CERTIFICATE") ) {
	print STDERR "SECURITY ALERT BY PKI: database failed during an update of the certificate state for a correct CRR which follows\n".
		$req_txt."\n";
	configError( gettext("Failed to change the certificate's state."));
}

return libSendReply (
                     "NAME"        => gettext ("Revocation Request Accepted"),
                     "EXPLANATION" => i18nGettext ("Your revocation request has been accepted and is now waiting to be processed. Once your certificate is revoqued, you will be notified by e-mail.\n\nIf you want to check out if your request has been correctly received, you can see the __BEGIN_LINK__Revocation Requests List__END_LINK__.\n\nIf you want to cancel the revocation request (you issued it by error), you have to go to the nearest Registration Authority.",
                                                   "__BEGIN_LINK__", '<A HREF="?cmd=lists&action=newCrrs">',
                                                   "__END_LINK__", "</a>")
                    );
}

1;

