## OpenCA - Command
## (c) 1998-2001 by Massimiliano Pala and OpenCA Group
## (c) Copyright 2002-2004 The OpenCA Project
##
##   File Name: viewSignature
##       Brief: View Signature
##// Description: Display given object's signature and its validity
##  Parameters: dataType, key

use strict;

# 2004-12-17 Martin Bartosch; FIXME: is this really needed? (globally? at all?)
our (@cols);

sub cmdViewSignature {

## Get the Configuration parameters ...
my ( $parsed, $lnk, $serLink, $sigInfo, $sigStatus, $signer, $signature);
my ( $baseDoc, $info, $sigCertStatus, $def, $dbStatus, $dbMessage);
my ( $myCN, $myEmail, $mySerial, $tmpCert, $pCert );

my $dataType 	= $query->param('dataType' );
my $key      	= $query->param('key');
my $tempDir  	= getRequired('tempDir');
my ( $sigMessage, $decSerLink );

## Check passed parameters
configError( gettext ("Error, needed dB key!") ) if ( not $key );
configError ( i18nGettext ("Invalid or missing dataType (__DATATYPE__)!", "__DATATYPE__", $dataType)) if ( not $dataType);

## Retrieve item from the DB
my $item = $db->getItem( DATATYPE=>$dataType, KEY=>$key );

configError (gettext ("Object not present in DB!") ) if ( not $item );
configError (gettext ("Object not Signed!")) if ( not $item->getParsed()->{SIGNATURE} );

## Get the parsed Object
my $parsed = $item->getParsed();

@cols = ( gettext ("Variable"), gettext ("Value") );

## Get Signature
if( not $signature = libGetSignatureObject( OBJECT=>$item )) {
    generalError( i18nGettext ("Signature Object not returned, check the openca-verify command. __ERRVAL__",
                               "__ERRVAL__", $errval), 560);
}

## Get Signer
$signer = $signature->getSigner();

$lnk = new CGI({cmd=>"search", dataType=>"CERTIFICATE",
		name=>"CN", value=>$signer->{DN_HASH}->{CN}[0]} );
$myCN = $lnk->a({-href=>"?".$lnk->query_string()}, $signer->{DN_HASH}->{CN}[0]);

$lnk = new CGI({cmd=>"search", dataType=>"CERTIFICATE",
		name=>"EMAIL", value=>$signer->{DN_HASH}->{EMAILADDRESS}[0]} );
$myEmail = $lnk->a({-href=>"?".$lnk->query_string()}, $signer->{DN_HASH}->{EMAILADDRESS}[0]);

## Check Signature Status
if( not libCheckSignature( SIGNATURE=>$signature ) ) {
	$sigStatus = "<FONT COLOR=\"Red\">".gettext("Error")."</FONT>";
	$sigMessage = gettext ("Signature Verification Error!");

	$sigInfo = $query->img({-src=>getRequired ('SigErrorImage'),
				-align=>"MIDDLE"});
	if( $errno > 400 ) {
		$dbMessage = $errval;
		$dbStatus = $errno;
		$sigStatus = "<FONT COLOR=\"Red\">".gettext ("Unknown")."</FONT>";

		if( $signer->{SERIAL} ) {
			$serLink = $signer->{SERIAL};
		} else {
			$serLink = gettext("Unknown");
		}
	} else {
		##// FIXME: what's that!? 
		## FIXME: libCheckSignature fails and we state "Signature correctly verified"
		## $sigMessage = gettext ("Signature correctly verified");
	}
} else {
	$sigStatus = gettext ("Valid");
	$sigMessage = gettext ("Signature correctly verified");
	$sigInfo = $query->img({src=>getRequired ('ValidSigImage'),
			border=>"0", align=>"MIDDLE"});
}

$tmpCert = libGetSignerCertificateDB( SIGNATURE=>$signature );
if( $errno < 400 ) {
	if( $tmpCert->{DATATYPE} =~ /VALID/ ) {
		$sigCertStatus = gettext ("Valid");
	} elsif ( $tmpCert->{DATATYPE} =~ /EXPIRED/ ) {
		$sigCertStatus = gettext ("Expired");
	} elsif ( $tmpCert->{DATATYPE} =~ /REVOKED/ ) {
		$sigCertStatus = "<FONT COLOR=\"RED\">".gettext("Revoked")."</FONT>";
	}
	$dbStatus = "0";
	$dbMessage = gettext ("Certificate present in dB");

	$lnk = new CGI({ cmd=>"viewCert",
		 dataType=>$tmpCert->{DATATYPE},
		 key=>$tmpCert->getSerial()});

	$serLink = $lnk->a({-href=>"?".$lnk->query_string()},
			$tmpCert->getSerial() );

 	$decSerLink = "( " . hex( $tmpCert->getSerial() ) . " )";

    $lnk = new CGI({cmd      => "search",
                    dataType => "CERTIFICATE",
                    name     => "EMAIL",
                    value    => $tmpCert->getParsed()->{EMAILADDRESS}} );
    $myEmail = $lnk->a({-href=>"?".$lnk->query_string()}, $tmpCert->getParsed()->{EMAILADDRESS});
}

$pCert = $tmpCert->getParsed();

my $info_list = undef;
$info_list->{HEAD}->[0] = gettext ("Variable");
$info_list->{HEAD}->[1] = gettext ("Value");

$info_list->{BODY}->[0]->[0] = gettext ("Signer Common Name");
$info_list->{BODY}->[0]->[1] = ($myCN or gettext ("n/a") );
$info_list->{BODY}->[1]->[0] = gettext ("Signer E-Mail");
$info_list->{BODY}->[1]->[1] = ($myEmail or gettext ("n/a") );
$info_list->{BODY}->[2]->[0] = gettext ("Signer Certificate's Serial");
$info_list->{BODY}->[2]->[1] = $serLink.$decSerLink;
$info_list->{BODY}->[3]->[0] = gettext ("Certificate Valid From");
$info_list->{BODY}->[3]->[1] = ($pCert->{NOTBEFORE} or gettext ("n/a"));
$info_list->{BODY}->[4]->[0] = gettext ("Certificate Valid To");
$info_list->{BODY}->[4]->[1] = ($pCert->{NOTAFTER} or gettext ("n/a") );
$info_list->{BODY}->[5]->[0] = gettext ("Signature Infos");
$info_list->{BODY}->[6]->[0] = gettext ("Signature Status");
$info_list->{BODY}->[6]->[1] = $sigStatus;
$info_list->{BODY}->[7]->[0] = gettext ("Status Message");
$info_list->{BODY}->[7]->[1] = $sigMessage;
$info_list->{BODY}->[8]->[0] = gettext ("DB Status");
$info_list->{BODY}->[8]->[1] = $dbMessage."(".$dbStatus.")";
$info_list->{BODY}->[9]->[0] = gettext ("Signature");
$info_list->{BODY}->[9]->[1] = "<pre>".$parsed->{SIGNATURE}."</pre>";

return libSendReply (
                     "NAME"        => gettext ("Signature Infos"),
                     "EXPLANATION" => gettext ("Signer Informations"),
                     "TIMESTAMP"   => 1,
                     "INFO_LIST"   => $info_list,
                     "SIGINFO"     => $sigInfo
                    );
}

1;

