## OpenCA - CA Command
## (c) 1998-2001 by Massimiliano Pala and OpenCA Group
## (c) Copyright 2002-2004 The OpenCA Project
##
##   File Name: genCACert
##       Brief: Generate CA Certificate
##// Description: Generate the CA's Certificate (self-signed) from the
##              request file (careq.pem).
##  Parameters: bits, days, passwd

use strict;

sub cmdGenCACert {

    our ($journal, $query, $tools, $crypto_layer, $cryptoShell, $db);

    ## This command is executed to generate a new cacert.pem
    ## in the $opencaDir directory. Use the already generated
    ## careq.pem

    my $makeCmd   = getRequired( 'MakePath');

    ## Get the parameters
    my $bits	= $query->param('bits');
    my $days	= $query->param('days');
    my $pwd		= $query->param('passwd');

    ## Other reserved variables
    my $careqFile 	= getRequired ( 'ReqDir' )."/careq.pem";
    my $cacertFile 	= getRequired ( 'CACertificate' );
    my $cacertDER	= getRequired ( 'CACertificateDER' );
    my $cacertCRT	= getRequired ( 'CACertificateCRT' );
    my $cacertTXT	= getRequired ( 'CACertificateTXT' );
    my $chainDir 	= getRequired ( 'ChainDir' );

    my ( $page, $crt );
    my $msg = "";

    configError(i18nGettext ("Cannot find file __FILE__!", "__FILE__", $careqFile))
        unless ( -e "$careqFile" );
    $journal->{message} .= "The CA request is present.\n";

    ## If there is already a cacertfile, than we should move it to .old
    if ( -e "$cacertFile" ) {
        $journal->{message} .= "Detected an already generated certificate.\n";
        generalError (
            i18nGettext ("There is already a CA certificate present in this OpenCA installation (__FILE__).",
                         "__FILE__", $cacertFile));
    }

    my $ca_token = $crypto_layer->getToken ('CA');
    if (not ($ca_token->keyOnline || $ca_token->login))
    {
	my $msg = gettext ("Initializing CA token ... ").
	         "<FONT color=#ff0000>".gettext ("FAILED")."</FONT><br>\n".
	         i18nGettext ("Token's errormessage: __ERRVAL__", "__ERRVAL__", $ca_token->errval);
        generalError ($msg, $ca_token->errno);
    }
    $journal->{message} .= "Token is ready for use.\n";

    ## Remove the old careq file, it is not important to keep a
    unlink( "$cacertDER" ) if ( -e "$cacertDER" );

    ## it is to dangerous to support OUTFILE via OpenCA::OpenSSL
    $ca_token->genCert( REQFILE => $careqFile,
                    OUTFILE => $cacertFile,
                    DAYS    => $days );

    configError(gettext ("Error (1) while issuing certificate!"))
        if( $? != 0 );
    $journal->{message} .= "CA certificate was generated.\n";

    $cryptoShell->dataConvert( DATATYPE=>"CERTIFICATE",
			   INFILE=>"$cacertFile",
			   OUTFILE=>"$cacertDER",
			   OUTFORM=>"DER" );

    configError(gettext ("Error (2) while convertig certificate!"))
        if( $? != 0 );
    $journal->{message} .= "CA certificate was generated.\n";

    $cryptoShell->dataConvert( DATATYPE=>"CERTIFICATE",
			   INFILE=>"$cacertFile",
			   OUTFILE=>"$cacertTXT",
			   OUTFORM=>"TXT" );

    configError(gettext ("Error (3) while convertig certificate!"))
        if( $? != 0 );
    $journal->{message} .= "CA certificate stored as TXT file.\n";

    $crt = new OpenCA::X509( SHELL   => $cryptoShell,
                         GETTEXT => \&i18nGettext,
                         INFILE  => "$cacertFile" );
    configError(i18nGettext ("Error while loading CA certificate (__FILE__).",
                             "__FILE__", $cacertFile))
        if( not $crt );
    $journal->{message} .= "CA certificate cannot be loaded.\n";

    ##// Let's link to the chain dir
    $tools->copyFiles ( SRC=>"$cacertFile",
			    DEST=>"$cacertCRT");

    ##// Let's make the links for chain verification
    my $ret = `cd ${chainDir}; $makeCmd`;

    if ( not $db->storeItem( DATATYPE => "VALID_CA_CERTIFICATE",
				 OBJECT   => $crt,
				 MODE     => "INSERT")) {
	configError (gettext ("Error while storing CA cert to dB!"));
    }
    $journal->{message} .= "CA certificate stored in database.\n";

    my $info_list = undef;
    $info_list->{BODY}->[0]->[0] = '';
    $info_list->{BODY}->[0]->[1] = "<pre>".$crt->getTXT()."</pre>";

    return libSendReply (
                     "NAME"        => gettext ("Self Signed CA Certificate"),
                     "EXPLANATION" => gettext ("Following you can find the result of the generation process.").
                                      $msg,
                     "INFO_LIST"   => $info_list
                    );
}

sub getParamsGenCACert
{

    my $result = "";

    if (not $_[0]) ## 0 or empty
    {
        my $message = gettext ("This option lets you create a new self signed certificate for your CA. You should have generated the private key and the CSR already. You can abort the process by using the back button of your browser. Are you sure you want continue?");

        $result = "<table>\n";
        $result .= "  <tr><td colspan=2>".$message."</td></tr>\n";

        ## different items

        $result .= "  <tr>\n".
                   "    <td>".gettext ("CA certificate Validity (in days from now)")."</td>\n".
                   '    <td><input type="text" name="days" value="730"></td>'.
                   "\n  </tr>\n";

        $result .= "</table>\n";
    }
    return $result;
}

1;
