function getVisualRepresentationPosition($sampleNumber) { switch ($sampleNumber) { case 1: // Example #1: automatic positioning on footnote. This will insert the signature, and future signatures, // ordered as a footnote of the last page of the document return PadesVisualPositioningPresets::getFootnote(getRestPkiClient()); case 2: // Example #2: get the footnote positioning preset and customize it $visualPosition = PadesVisualPositioningPresets::getFootnote(getRestPkiClient()); $visualPosition->auto->container->left = 2.54; $visualPosition->auto->container->bottom = 2.54; $visualPosition->auto->container->right = 2.54; return $visualPosition; case 3: // Example #3: automatic positioning on new page. This will insert the signature, and future signatures, // in a new page appended to the end of the document. return PadesVisualPositioningPresets::getNewPage(getRestPkiClient()); case 4: // Example #4: get the "new page" positioning preset and customize it $visualPosition = PadesVisualPositioningPresets::getNewPage(getRestPkiClient()); $visualPosition->auto->container->left = 2.54; $visualPosition->auto->container->top = 2.54; $visualPosition->auto->container->right = 2.54; $visualPosition->auto->signatureRectangleSize->width = 5; $visualPosition->auto->signatureRectangleSize->height = 3; return $visualPosition; case 5: // Example #5: manual positioning return ['pageNumber' => 0, 'measurementUnits' => 'Centimeters', 'manual' => ['left' => 2.54, 'bottom' => 2.54, 'width' => 5, 'height' => 3]]; case 6: // Example #6: custom auto positioning return ['pageNumber' => -1, 'measurementUnits' => 'Centimeters', 'auto' => ['container' => ['left' => 2.54, 'right' => 2.54, 'bottom' => 2.54, 'height' => 12.31], 'signatureRectangleSize' => ['width' => 5, 'height' => 3], 'rowSpacing' => 1]]; default: return null; } }
/* * This file receives the form submission from pades-signature.php. We'll call REST PKI to complete the signature. */ // The file RestPkiLegacy.php contains the helper classes to call the REST PKI API for PHP 5.3+. Notice: if you're using // PHP version 5.5 or greater, please use one of the other samples, which make better use of the extended capabilities // of the newer versions of PHP - https://github.com/LacunaSoftware/RestPkiSamples/tree/master/PHP require_once 'RestPkiLegacy.php'; // The file util.php contains the function getRestPkiClient(), which gives us an instance of the RestPkiClient class // initialized with the API access token require_once 'util.php'; use Lacuna\PadesSignatureFinisher; // Get the token for this signature (rendered in a hidden input field, see pades-signature.php) $token = $_POST['token']; // Instantiate the PadesSignatureFinisher class, responsible for completing the signature process $signatureFinisher = new PadesSignatureFinisher(getRestPkiClient()); // Set the token $signatureFinisher->setToken($token); // Call the finish() method, which finalizes the signature process and returns the signed PDF $signedPdf = $signatureFinisher->finish(); // Get information about the certificate used by the user to sign the file. This method must only be called after // calling the finish() method. $signerCert = $signatureFinisher->getCertificate(); // At this point, you'd typically store the signed PDF on your database. For demonstration purposes, we'll // store the PDF on a temporary folder publicly accessible and render a link to it. $id = uniqid(); $appDataPath = "app-data"; if (!file_exists($appDataPath)) { mkdir($appDataPath); } file_put_contents("{$appDataPath}/{$id}.pdf", $signedPdf);
<?php /* * This file receives the form submission from xml-element-signature.php. We'll call REST PKI to complete the signature. */ // The file RestPkiLegacy.php contains the helper classes to call the REST PKI API require_once 'RestPkiLegacy.php'; // The file util.php contains the function getRestPkiClient(), which gives us an instance of the RestPkiClient class // initialized with the API access token require_once 'util.php'; use Lacuna\XmlSignatureFinisher; // Get the token for this signature (rendered in a hidden input field, see xml-element-signature.php) $token = $_POST['token']; // Instantiate the XmlSignatureFinisher class, responsible for completing the signature process $signatureFinisher = new XmlSignatureFinisher(getRestPkiClient()); // Set the token $signatureFinisher->setToken($token); // Call the finish() method, which finalizes the signature process and returns the signed XML $signedXml = $signatureFinisher->finish(); // Get information about the certificate used by the user to sign the file. This method must only be called after // calling the finish() method. $signerCert = $signatureFinisher->getCertificate(); // At this point, you'd typically store the signed XML on your database. For demonstration purposes, we'll // store the PDF on a temporary folder publicly accessible and render a link to it. $filename = uniqid() . ".xml"; createAppData(); // make sure the "app-data" folder exists (util.php) file_put_contents("app-data/{$filename}", $signedXml); ?> <!DOCTYPE html> <html>
/* * This file initiates a XML signature of an element of the XML using REST PKI and renders the signature page. The form * is posted to another file, xml-element-signature-action.php, which calls REST PKI again to complete the signature. */ // The file RestPkiLegacy.php contains the helper classes to call the REST PKI API require_once 'RestPkiLegacy.php'; // The file util.php contains the function getRestPkiClient(), which gives us an instance of the RestPkiClient class // initialized with the API access token require_once 'util.php'; use Lacuna\XmlElementSignatureStarter; use Lacuna\StandardSecurityContexts; use Lacuna\StandardSignaturePolicies; // Instantiate the XmlElementSignatureStarter class, responsible for receiving the signature elements and start the // signature process $signatureStarter = new XmlElementSignatureStarter(getRestPkiClient()); // Set the XML to be signed, a sample Brazilian fiscal invoice pre-generated $signatureStarter->setXmlToSignPath('content/SampleNFe.xml'); // Set the ID of the element to be signed $signatureStarter->setToSignElementId('NFe35141214314050000662550010001084271182362300'); // Set the signature policy $signatureStarter->setSignaturePolicy(StandardSignaturePolicies::XML_ICPBR_NFE_PADRAO_NACIONAL); // Optionally, set a SecurityContext to be used to determine trust in the certificate chain. Since we're using the // XML_ICPBR_NFE_PADRAO_NACIONAL policy, the security context will default to PKI Brazil (ICP-Brasil) //$signatureStarter->setSecurityContext(StandardSecurityContexts::PKI_BRAZIL); // Note: By changing the SecurityContext above you can accept only certificates from a custom PKI for tests. // Call the startWithWebPki() method, which initiates the signature. This yields the token, a 43-character // case-sensitive URL-safe string, which identifies this signature process. We'll use this value to call the // signWithRestPki() method on the Web PKI component (see javascript below) and also to complete the signature after // the form is submitted (see file xml-element-signature-action.php). This should not be mistaken with the API access token. $token = $signatureStarter->startWithWebPki();
<?php /* * This file receives the form submission from authentication.php. We'll call REST PKI to validate the authentication. */ // The file RestPki.php contains the helper classes to call the REST PKI API require_once 'RestPki.php'; // The file util.php contains the function getRestPkiClient(), which gives us an instance of the RestPkiClient class // initialized with the API access token require_once 'util.php'; // Get the token for this authentication (rendered in a hidden input field, see authentication.php) $token = $_POST['token']; // Get an instance of the Authentication class $auth = getRestPkiClient()->getAuthentication(); // Call the completeWithWebPki() method with the token, which finalizes the authentication process. The call yields a // ValidationResults which denotes whether the authentication was successful or not (we'll use it to render the page // accordingly, see below). $vr = $auth->completeWithWebPki($token); if ($vr->isValid()) { $userCert = $auth->getCertificate(); // At this point, you have assurance that the certificate is valid according to the SecurityContext specified on the // file authentication.php and that the user is indeed the certificate's subject. Now, you'd typically query your // database for a user that matches one of the certificate's fields, such as $userCert->emailAddress or // $userCert->pkiBrazil->cpf (the actual field to be used as key depends on your application's business logic) and // set the user as authenticated with whatever web security framework your application uses. For demonstration // purposes, we'll just render the user's certificate information. } ?> <!DOCTYPE html> <html> <head>
* 3. Co-signature of a previously signed CMS : "cmsfile" filled */ // The file RestPkiLegacy.php contains the helper classes to call the REST PKI API for PHP 5.3+. Notice: if you're using // PHP version 5.5 or greater, please use one of the other samples, which make better use of the extended capabilities // of the newer versions of PHP - https://github.com/LacunaSoftware/RestPkiSamples/tree/master/PHP require_once 'RestPkiLegacy.php'; // The file util.php contains the function getRestPkiClient(), which gives us an instance of the RestPkiClient class // initialized with the API access token require_once 'util.php'; use Lacuna\CadesSignatureStarter; use Lacuna\StandardSignaturePolicies; $userfile = isset($_GET['userfile']) ? $_GET['userfile'] : null; $cmsfile = isset($_GET['cmsfile']) ? $_GET['cmsfile'] : null; // Instantiate the CadesSignatureStarter class, responsible for receiving the signature elements and start the signature // process $signatureStarter = new CadesSignatureStarter(getRestPkiClient()); if (!empty($userfile)) { // If the URL argument "userfile" is filled, it means the user was redirected here by the file upload.php (signature // with file uploaded by user). We'll set the path of the file to be signed, which was saved in the "app-data" folder // by upload.php $signatureStarter->setFileToSign("app-data/{$userfile}"); } else { if (!empty($cmsfile)) { /* * If the URL argument "cmsfile" is filled, the user has asked to co-sign a previously signed CMS. We'll set the * path to the CMS to be co-signed, which was previously saved in the "app-data" folder by the file * cades-signature-action.php. Note two important things: * * 1. The CMS to be co-signed must be set using the method "setCmsToSign" or "setCmsFileToSign", not the method * "setContentToSign" nor "setFileToSign". *
/* * This file initiates a XML signature of the entire XML using REST PKI and renders the signature page. The form * is posted to another file, xml-full-signature-action.php, which calls REST PKI again to complete the signature. */ // The file RestPki.php contains the helper classes to call the REST PKI API require_once 'RestPki.php'; // The file util.php contains the function getRestPkiClient(), which gives us an instance of the RestPkiClient class // initialized with the API access token require_once 'util.php'; use Lacuna\FullXmlSignatureStarter; use Lacuna\StandardSecurityContexts; use Lacuna\StandardSignaturePolicies; // Instantiate the FullXmlSignatureStarter class, responsible for receiving the signature elements and start the // signature process $signatureStarter = new FullXmlSignatureStarter(getRestPkiClient()); // Set the XML to be signed, a sample Brazilian fiscal invoice pre-generated $signatureStarter->setXmlToSignPath('content/SampleDocument.xml'); // Set the location on which to insert the signature node. If the location is not specified, the signature will appended // to the root element (which is most usual with enveloped signatures). $signatureStarter->setSignatureElementLocation('//ls:signaturePlaceholder', \Lacuna\XmlInsertionOptions::APPEND_CHILD, array('ls' => 'http://www.lacunasoftware.com/sample')); // Set the signature policy $signatureStarter->setSignaturePolicy(StandardSignaturePolicies::XML_XADES_BES); // Set a SecurityContext to be used to determine trust in the certificate chain $signatureStarter->setSecurityContext(StandardSecurityContexts::PKI_BRAZIL); // Note: By changing the SecurityContext above you can accept only certificates from a certain PKI, for instance, // ICP-Brasil (\Lacuna\StandardSecurityContexts::PKI_BRAZIL). // Call the startWithWebPki() method, which initiates the signature. This yields the token, a 43-character // case-sensitive URL-safe string, which identifies this signature process. We'll use this value to call the // signWithRestPki() method on the Web PKI component (see javascript below) and also to complete the signature after // the form is submitted (see file xml-full-signature-action.php). This should not be mistaken with the API access token.