EldoS | Feel safer!

Software components for data protection, secure storage and transfer

CADES-BES with PHP and USB Key

Also by EldoS: RawDisk
Access locked and protected files in Windows, read and write disks and partitions and more.
#35459
Posted: 01/08/2016 08:11:44
by Andrew Gill (Basic support level)
Joined: 12/04/2015
Posts: 3

I am trying to sign a document using a USB key card certificate in CADES-BES format.

Using the library's sample file "CAdES_Sign.php" I have replaced the lines

Code
$cert = new TElX509Certificate(NULL);
$r = $cert->LoadFromFileAuto($certfile, $password);


with

Code
$certStorage = new TElPKCS11CertStorage(null);
$certStorage->DLLName = "C:\\Windows\\System32\\bit4ipki.dll";
$certStorage->Open();
$session = $certStorage->OpenSession(0, true);
$session->Login(1, $pin);
$cert = $certStorage->get_Certificates(0);


This code appears to load the certificate file. However, the script does not generate any error messages and produces an empty file.

Please can you advise what I need to change in order to produce a CADES-BES signed document from a USB key card?
#35460
Posted: 01/08/2016 08:16:09
by Vsevolod Ievgiienko (EldoS Corp.)

Thank you for contacting us.

Please check if $cert->get_PrivateKeyExists() returns 'true' after certificate is loaded from a token.

I’ve noticed there is no Support Access Ticket linked to your user account on EldoS site. Technical Support is provided to customers with the linked Support Access Ticket. You will find your Support Access Ticket together with all the details about how to use it in the registration e-mail that we’ve sent to you upon the purchase.

If you are evaluating the product and don't have a license yet, please let us know and then you can have support according to Basic support level. Basic support level includes answering basic technical questions that appear during product evaluation period. We also offer Premium support for a purchase from https://www.eldos.com/support/calc.php . You can use Premium Support to get higher level of assistance during your evaluation of our products.
#35467
Posted: 01/08/2016 12:35:34
by Andrew Gill (Basic support level)
Joined: 12/04/2015
Posts: 3

$cert->get_PrivateKeyExists() returns boolean true.

I am currently evaluating the product, and trying to generate all of the different types of signatures that we require, with all of the different certificates we need to use.
#35468
Posted: 01/08/2016 12:41:21
by Eugene Mayevski (EldoS Corp.)

Thank you for the clarification.

You mention the empty file, but your code (the one you posted) contains no calls to do anything or to save anything. Could you please elaborate on what you are actually doing and where's the file involved that you expect to be filled?


Sincerely yours
Eugene Mayevski
#35469
Posted: 01/08/2016 12:55:14
by Dmytro Bogatskyy (EldoS Corp.)

Hi,

Quote
This code appears to load the certificate file. However, the script does not generate any error messages and produces an empty file.

At first, does your code is wrapped in try..catch block and there is no exception is thrown by Sign() method?
Then, is your code for loading certificate is placed in the function? If so, then possible $cert variable become invalid because it is owned by $certStorage variable, but $certStorage is freed at the end of block/function before certificate is used. Please, try to make $certStorage variable as global.
#35490
Posted: 01/11/2016 06:58:28
by Andrew Gill (Basic support level)
Joined: 12/04/2015
Posts: 3

Hi,

Sorry perhaps it was not clear I was using the sample CAdes_sign.php that comes with the SBB download and just replacing the certificate section.

Below is the full code (with the $pin removed for security reasons). When it processes it generates an empty file in the temp folder.

Code
<?php
    date_default_timezone_set("UTC");
    $log = new TStringList();

    function CertValidityToStr($V)
    {
        switch ($V) {
            case TSBCertificateValidity::cvOk : Return 'OK'; break;
            case TSBCertificateValidity::cvSelfSigned : Return 'Self-signed'; break;
            case TSBCertificateValidity::cvInvalid : Return 'Invalid'; break;
            case TSBCertificateValidity::cvStorageError : Return 'Storage error'; break;
            case TSBCertificateValidity::cvChainUnvalidated : Return 'Chain unvalidated'; break;
            default: Return 'Unknown';
        }
    }

    function DoBeforeCertificateValidation($Sender, $Certificate)
    {
        global $log;
        $log->Add("Validating certificate: " . $Certificate->SubjectName->CommonName);
    }

    function DoAfterCertificateValidation($Sender, $Certificate, $CACertificate, &$Validity, &$Reason, &$DoContinue)
    {
        global $log;
        $log->Add("Validation done for " . $Certificate->SubjectName->CommonName . ": validity: " . CertValidityToStr($Validity));
    }

    function DoCertValidatorPrepared($Sender, &$CertValidator, $Cert)
    {
        global $log;
        $log->Add("Certificate validator prepared for validation of " . $Cert->SubjectRDN->SaveToDSString());
        $CertValidator->OnBeforeCertificateValidation = 'DoBeforeCertificateValidation';
        $CertValidator->OnAfterCertificateValidation = 'DoAfterCertificateValidation';
        $CertValidator->set_MandatoryCRLCheck(false);
        $CertValidator->set_MandatoryOCSPCheck(false);
        $CertValidator->set_MandatoryRevocationCheck(true);
    }

    function DoCertValidatorFinished($Sender, $CertValidator, $Cert, $Validity, $Reason)
    {
        global $log;
        $log->Add("Certificate validator finished validating " . $Certificate->SubjectRDN->SaveToDNString() . ": validity: " . CertValidityToStr($Validity));
    }

    if (isset($_POST["sign"]))
    {
        if (!extension_loaded("sbb") && !function_exists('SBUtils\SetLicenseKey'))
        {
            print "SecureBlackbox extension is not available, please check that you've set it up correctly";
            die;
        }

        $inputfile = $_FILES["inputfile"]["tmp_name"];
        $filename = $_FILES["inputfile"]["name"];
        $certfile = $_FILES["certfile"]["tmp_name"];
        $password = $_POST["password"];
        $slevel = $_POST["slevel"];
        $usev2 = (isset($_POST['usev2']) && $_POST['usev2'] == 'yes');
        $ignore = (isset($_POST['ignore']) && $_POST['ignore'] == 'yes');
        $tserver = $_POST["tserver"];

        if ((strlen($inputfile) > 0) )
        {
            $yourfile = basename($filename) . ".tmp";
            $tempname = tempnam(sys_get_temp_dir(), $yourfile);

            try
            {
                /*
                $cert = new TElX509Certificate(NULL);
                $r = $cert->LoadFromFileAuto($certfile, $password);
                if ($r != 0)
                {
                    print 'Failed to load certificate, error ' . $r;
                    return;
                }
                */

                $driver = "C:\\Windows\\System32\\bit4ipki.dll";
                
                
                $certStorage = new TElPKCS11CertStorage(null);
            
                $certStorage->DLLName = $driver;
                $certStorage->Open();
                $session = $certStorage->OpenSession(0, true);
                $session->Login(1, $pin);
                $cert = $certStorage->get_Certificates(0);
        
                $in = new TMemoryStream;
                $in->LoadFromFile($inputfile);

                $cms = new TElSignedCMSMessage(NULL);
                $cms->CreateNew($in, 0, $in->Size);

                $sig = $cms->get_Signatures($cms->AddSignature());
                $procesor = new TElCAdESSignatureProcessor();
                $procesor->OnCertValidatorPrepared = 'DoCertValidatorPrepared';
                $procesor->OnCertValidatorFinished = 'DoCertValidatorFinished';
                $procesor->set_Signature($sig);
                $procesor->set_ForceSigningCertificateV2($usev2);
                $procesor->set_IgnoreChainValidationErrors($ignore);

                $http = new TElHTTPSClient(NULL);
                $tsp = new TElHTTPTSPClient(NULL);
                if ($slevel >= 1)
                {
                    $tsp->set_HTTPClient($http);
                    $tsp->set_URL($tserver);
                }

                $log->Clear();

                switch ($slevel) {
                    case 0 : $procesor->CreateBES($cert); break;
                    case 1 : $procesor->CreateT($cert, $tsp); break;
                    case 2 : $procesor->CreateC($cert, $tsp); break;
                    case 3 : $procesor->CreateXType1($cert, $tsp, $tsp); break;
                    case 4 : $procesor->CreateXType2($cert, $tsp, $tsp); break;
                    case 5 : $procesor->CreateXLType1($cert, $tsp, $tsp); break;
                    case 6 : $procesor->CreateXLType2($cert, $tsp, $tsp); break;
                    case 7 : print "Creation of A signatures is not supported. Please create T/C/XL signature " .
                                   "and then upgrade it to A"; break;
                }

                $out = new TMemoryStream;
                $cms->Save($out);

                $out->SaveToFile($tempname);

                if (ob_get_level())
                {
                    ob_end_clean();
                }

                header('Content-Description: File Transfer');
                header('Content-Type: application/octet-stream');
                header("Content-Disposition: attachment; filename=$filename");
                header('Content-Transfer-Encoding: binary');
                header('Expires: 0');
                header('Cache-Control: must-revalidate');
                header('Pragma: public');
                header('Content-Length: ' . filesize($tempname));
                readfile($tempname);

                unlink($tempname);

                return;
            }
            catch(SBException $e)
            {
                print "Failed to sign the file. Error: " . $e->getMessage() ." <br/> <br/>";
                print "Log: " . $e->getMessage() ." <br/>";
                for ($i = 0; $i <= $logf->Count - 1; $i++)
                {
                    print $logf->get_Strings($i) . "<br/>";
                }
            }
        }
        else
        {
            $error_details = "";

            if (strlen($inputfile) == 0)
            {
                $error_details = $error_details . "File to sign is not provided<br/>";
            }


            print "Parameters missing: <br/><br/>" . $error_details;
        }
    }
?>

<html>
<head>
  <title>EldoS CAdES demo</title>
  <style type="text/css">
  .textheader {
    font-family: Arial;
    font-size: 16;
    font-weight: bold;
  }
  .textnormal {
    font-family: Arial;
    font-size: 12;
  }
  </style>
</head>
<body>
  <div align="center">
  <table border="0" cellspacing="0" cellpadding="0" width="600" height="100%">
    <tr height="*"></tr>
    <tr height="400">
      <td width="600" valign="top">
        <table border="0" cellspacing="0" cellpadding="10" width="100%" height="100%" style="border: 1px solid #bbbbbb;" bgcolor="#f6f6f6">
          <tr height="50">
            <td width="100%" valign="center" bgcolor="#e6e6e6">
              <div align="center" class="textheader">EldoS SecureBlackbox CAdES demo</div>
            </td>
          </tr>
          <tr height="70">
            <td width="100%" height="*" align="center" valign="center" class="textnormal">
              <div align="center"> This sample illustrates the use of SecureBlackbox CAdES components for signing files. <br/>
              Please provide your certificate file and the file to sign, choose signature level and click the 'Create signature' button to sign the file. </div>
            </td>
          </tr>
          <tr height="*">
            <td width="100%" height="*">            
              <form action="" method="post" enctype="multipart/form-data">
                <table border="0" cellspacing="0" cellpadding="0" width="100%" height="100%" class="textnormal">
                  <tr height="30">
                    <td width="30%" align="right"> File to sign: </td>
                    <td width="10"></td>
                    <td width="*" align="left"> <input type="file" name="inputfile" value="" size="30" /> <td>
                  </tr>
                  <tr height="30">
                    <td width="30%" align="right"> Signing certificate: </td>
                    <td width="10"></td>
                    <td width="*" align="left"> <input type="file" name="certfile" value="" size="30" /> </td>
                  </tr>
                  <tr height="30">
                    <td width="30%" align="right"> Certificate password: </td>
                    <td width="10"></td>
                    <td width="*" align="left"> <input type="password" name="password" value="" size="20" /> </td>
                  </tr>
                  <tr height="40" valign="bottom">
                    <td width="40%" align="right"> Signature level: </td>
                    <td width="10"></td>
                    <td width="*" align="left">
                      <select name="slevel" size="1">
                        <option value=0 selected>CAdES-BES</option>
                        <option value=1>CAdES-T</option>
                        <option value=2>CAdES-C</option>
                        <option value=3>CAdES-X (type 1)</option>
                        <option value=4>CAdES-X (type 2)</option>
                        <option value=5>CAdES-XL (type 1)</option>
                        <option value=6>CAdES-XL (type 2)</option>
                        <option value=7>CAdES-A</option>
                      </select>
                    </td>
                  </tr>
                  <tr height="30">
                    <td width="30%" align="right"> </td>
                    <td width="10"></td>
                    <td width="*" align="left"> <label><input type="checkbox" name="usev2" value="yes" checked="checked"/> Use SigningCertificateV2 attribute</label> </td>
                 </tr>
                  <tr height="30">
                    <td width="30%" align="right"> </td>
                    <td width="10"></td>
                    <td width="*" align="left"> <label><input type="checkbox" name="ignore" value="yes" checked="checked"/> Ignore chain validation errors</label> </td>
                 </tr>
                  <tr height="30">
                    <td width="30%" align="right"> Timestamping server (TSA) URL: </td>
                    <td width="10"></td>
                    <td width="*" align="left"> <input type="text" name="tserver" value="http://" size="40" /> <td>
                  </tr>
                  <tr height="45" valign="center">
                    <td colspan="3" align="center"> <input type="submit" name="sign" value="Create signature"/> </td>
                  </tr>
                  <tr height="30" valign="bottom">
                    <td colspan="3" align="center"> Please inspect the source code of this script for more details. </td>
                  </tr>
                </table>
              </form>
            </td>
          </tr>
          <tr height="20">
            <td width="100%" valign="center" bgcolor="#e6e6e6">
              <div align="center" class="textnormal">Copyright &copy; EldoS Corporation <a href="http://www.eldos.com/">www.eldos.com</a></div>
            </td>
          </tr>
        </table>
      </td>
    </tr>
    <tr height="*"></tr>
  </table>
  </div>  
</body>
</html>
#35494
Posted: 01/11/2016 07:30:07
by Vsevolod Ievgiienko (EldoS Corp.)

I welcome you to continue the conversation in the Helpdesk ( https://www.eldos.com/helpdesk/ ).

Helpdesk is our easy-to-use individual support system that allows communicating and exchanging sample data with our support personnel privately. You will also get e-mail notifications about updates of your support request.
Also by EldoS: CallbackProcess
A component to control process creation and termination in Windows and .NET applications.

Reply

Statistics

Topic viewed 2733 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!