## OpenCA - RA Server Command
## (c) 1998-2001 by Massimiliano Pala and OpenCA Group
## (c) Copyright 2001-2004 The OpenCA Project
##
## File Name: approveCSR
## Brief: approve Request
## Version: $Revision: 1.3 $
## Description: Adds a confirmed request into the APPROVED_REQUEST dB
## Parameters: key, dataType, text, signature
use strict;
sub cmdApproveCSR {
our ($query, $db, $errno, $errval, $cryptoShell);
## Get the parameters
my $key = $query->param( 'key' );
my $dataType = $query->param( 'dataType' );
my $text = $query->param( 'text' );
my $head = $query->param( 'head' );
my $signature = $query->param( 'signature' );
my $inform = "PEM";
## Get Conf Parameters
my $tempDir = getRequired('tempDir');
my ( $req, $item, $sig, $sigStatus, $signer );
$signature =~ s/\n*$//;
$text = "$head" . "$text\n";
if ($signature !~ /^\s*$/) {
$text .= "-----BEGIN PKCS7-----\n";
$text .= "$signature\n";
$text .= "-----END PKCS7-----\n";
}
print STDERR $text;
if( not $req = $db->getItem( DATATYPE=>$dataType, KEY=>$key) ) {
generalError( i18nGettext ("Cannot find __DATATYPE__ REQ in DB!", "__DATATYPE__", $dataType));
}
$text .= $req->getParsed()->{KEY};
## FIXME: should we check the subject here if it is not dynamic via serials?
if ($dataType !~ /RENEW/i and not $req->getParsed()->{HEADER}->{RENEW}) {
# check the public key
## Check if there are certificates with the same keys
my @certList = $db->searchItems( DATATYPE=> "CERTIFICATE",
PUBKEY => $req->getParsed()->{PUBKEY});
my $errorString = gettext ("A Certificate with the same public key exists!")."
\n".
gettext ("This is a keycompromise of the certificates with the serial:")."\n".
"
\n";
foreach my $h (@certList) {
$errorString .= "- ".$h->getSerial()."
\n";
}
$errorString .= gettext ("Please revoke the certificates and delete the request.")."\n";
generalError( $errorString ) if($#certList > -1);
}
if( $req->getParsed()->{HEADER}->{TYPE} =~ /(PKCS#10|IE)/i ) {
$inform = "PEM";
} else {
$inform = $req->getParsed()->{HEADER}->{TYPE};
}
if( not $item = new OpenCA::REQ ( SHELL => $cryptoShell,
GETTEXT => \&i18nGettext,
INFORM => $inform,
DATA => $text )) {
generalError( i18nGettext ("Cannot create a new REQ object (__KEY__)!", "__KEY__", $key).
"
\n".$OpenCA::REQ::errval, $OpenCA::REQ::errno );
}
$signer = libGetSignatureObject( OBJECT=>$item );
if ( not $signer ) {
generalError ($errval, $errno);
}
libCheckSignature (OBJECT=>$item);
$sigStatus = $errval;
## check signaturestate - explaination:
## $errno gets only set by libCheckSignature in case of real error
## $errval gets always set, also in success by libCheckSignature!
generalError ( $errval ) if $errno;
## get signer certificate
my $tmpCert = libGetSignerCertificateDB( SIGNATURE=>$signer );
if( not $tmpCert ) {
generalError ($errval, $errno);
}
## check validity of signer certificate
if ($tmpCert->getStatus() =~ /revoked/ || $tmpCert->getStatus() =~ /suspended/
|| $tmpCert->getStatus() =~ /expired/ ) {
generalError ( i18nGettext ("Cannot approve request! Invalid Operator-Certificate detected!").
"
\n".$errval, $errno);
}
if (not crypto_check_lifetime ($item, $req->getParsed()->{HEADER}->{ROLE}))
{
generalError ($errval, $errval);
}
if ( not $db->updateStatus ( DATATYPE=>$dataType,
OBJECT => $item, NEWTYPE=>"APPROVED_REQUEST")) {
generalError( i18nGettext ("Error while updating the status of the request (__KEY__)!", "__KEY__", $key).
"
\n".$OpenCA::DB::errval, $OpenCA::REQ::errno);
}
return libSendReply (
"TIMESTAMP" => 1,
"NAME" => gettext ("Certificate Signing Request Approved"),
"EXPLANATION" => gettext ("Certificate Request Successfully approved.")."\n".
i18nGettext ("Signature: __SIGSTATUS__",
"__SIGSTATUS__", $sigStatus)
);
}
1;