SetaPDF Demos

There seems to be a problem loading the components. Please check your PHP error logs for details!

Common issues could be that you missed to install the trial license or that you are using a trial version on an unsupported PHP version.

openssl-dgst + RSASSA-PSS

This demo uses the openssl-dgst command from OpenSSL with the RSASSA-PSS signature algorithm to create the signature value.

PHP
<?php

// load and register the autoload function
require_once __DIR__ . '/../../../../../../bootstrap.php';

// you need to adjust these paths to yours
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
    $opensslPath = 'C:\\OpenSSL\\Win64-1.1.1i\\bin\\';
} else {
    $opensslPath = '/usr/bin/';
}

// the file to sign
$fileToSign = $assetsDirectory . '/pdfs/tektown/Laboratory-Report.pdf';
// create a temporary path
$tempFile = \SetaPDF_Core_Writer_TempFile::createTempPath();

// create a writer instance
$writer = new \SetaPDF_Core_Writer_Http('signed-with-dgst.pdf');
// create the document instance
$document = \SetaPDF_Core_Document::loadByFilename($fileToSign, $writer);

// create the signer instance
$signer = new \SetaPDF_Signer($document);

// let's use the PAdES modul and configure it
$module = new \SetaPDF_Signer_Signature_Module_Pades();
$module->setDigest(\SetaPDF_Signer_Digest::SHA_256);
$module->setCertificate('file://' . $assetsDirectory . '/certificates/setapdf-no-pw.pem');

// create a temporary version which represents the data which should get signed
$tmpDocument = $signer->preSign(new \SetaPDF_Core_Writer_File($tempFile), $module);

// for PSS we need to update the SignatureAlgorithmIdentifier as defined here:
// https://tools.ietf.org/html/rfc4055#section-3.1
$cms = $module->getCms();

$saltLength = 256 / 8;
switch ($module->getDigest()) {
    case \SetaPDF_Signer_Digest::SHA_384:
        $saltLength = 384 / 8;
        break;
    case \SetaPDF_Signer_Digest::SHA_512:
        $saltLength = 512 / 8;
        break;
}

$signatureAlgorithmIdentifier = \SetaPDF_Signer_Asn1_Element::findByPath('1/0/4/0/4', $cms);
$signatureAlgorithmIdentifier->getChild(0)->setValue(\SetaPDF_Signer_Asn1_Oid::encode("1.2.840.113549.1.1.10"));
$signatureAlgorithmIdentifier->removeChild($signatureAlgorithmIdentifier->getChild(1));
$signatureAlgorithmIdentifier->addChild(new \SetaPDF_Signer_Asn1_Element(
    \SetaPDF_Signer_Asn1_Element::SEQUENCE | \SetaPDF_Signer_Asn1_Element::IS_CONSTRUCTED, '',
    [
        new \SetaPDF_Signer_Asn1_Element(
            \SetaPDF_Signer_Asn1_Element::TAG_CLASS_CONTEXT_SPECIFIC | \SetaPDF_Signer_Asn1_Element::IS_CONSTRUCTED, '',
            [
                new \SetaPDF_Signer_Asn1_Element(
                    \SetaPDF_Signer_Asn1_Element::SEQUENCE | \SetaPDF_Signer_Asn1_Element::IS_CONSTRUCTED, '',
                    [
                        new \SetaPDF_Signer_Asn1_Element(
                            \SetaPDF_Signer_Asn1_Element::OBJECT_IDENTIFIER,
                            \SetaPDF_Signer_Asn1_Oid::encode(\SetaPDF_Signer_Digest::getOid($module->getDigest()))
                        ),
                        new \SetaPDF_Signer_Asn1_Element(\SetaPDF_Signer_Asn1_Element::NULL)
                    ]
                )
            ]
        ),
        new \SetaPDF_Signer_Asn1_Element(
            \SetaPDF_Signer_Asn1_Element::TAG_CLASS_CONTEXT_SPECIFIC | \SetaPDF_Signer_Asn1_Element::IS_CONSTRUCTED | "\x01", '',
            [
                new \SetaPDF_Signer_Asn1_Element(
                    \SetaPDF_Signer_Asn1_Element::SEQUENCE | \SetaPDF_Signer_Asn1_Element::IS_CONSTRUCTED, '',
                    [
                        new \SetaPDF_Signer_Asn1_Element(
                            \SetaPDF_Signer_Asn1_Element::OBJECT_IDENTIFIER,
                            \SetaPDF_Signer_Asn1_Oid::encode('1.2.840.113549.1.1.8')
                        ),
                        new \SetaPDF_Signer_Asn1_Element(
                            \SetaPDF_Signer_Asn1_Element::SEQUENCE | \SetaPDF_Signer_Asn1_Element::IS_CONSTRUCTED, '',
                            [
                                new \SetaPDF_Signer_Asn1_Element(
                                    \SetaPDF_Signer_Asn1_Element::OBJECT_IDENTIFIER,
                                    \SetaPDF_Signer_Asn1_Oid::encode(\SetaPDF_Signer_Digest::getOid($module->getDigest()))
                                ),
                                new \SetaPDF_Signer_Asn1_Element(\SetaPDF_Signer_Asn1_Element::NULL)
                            ]
                        )
                    ]
                )
            ]
        ),
        new \SetaPDF_Signer_Asn1_Element(
            \SetaPDF_Signer_Asn1_Element::TAG_CLASS_CONTEXT_SPECIFIC | \SetaPDF_Signer_Asn1_Element::IS_CONSTRUCTED | "\x02",
            '',
            [
                new \SetaPDF_Signer_Asn1_Element(\SetaPDF_Signer_Asn1_Element::INTEGER, \chr($saltLength))
            ]
        )
    ]
));

// get the hash data from the module
$hashData = $module->getDataToSign($tmpDocument->getHashFile());

// define some variables related to the private key
$privateKey = realpath($assetsDirectory . '/certificates/setapdf-no-pw.pem');
$privateKeyPass = '';

// create a temporary file with the data to sign
$tmpFileIn = \SetaPDF_Core_Writer_TempFile::createTempFile($hashData);
// prepare a temporary file for the final signature
$tmpFileOut = \SetaPDF_Core_Writer_TempFile::createTempPath();

// build the command
$cmd = $opensslPath . 'openssl dgst '
    . '-' . $module->getDigest() . ' '
    . '-sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:' . escapeshellarg($saltLength) . ' '
    . '-binary '
    . "-sign " . escapeshellarg($privateKey) . ' '
    . '-passin pass:' . escapeshellarg($privateKeyPass) . ' '
    . '-out ' . escapeshellarg($tmpFileOut) . ' '
    . escapeshellarg($tmpFileIn);

// execute it
exec($cmd, $out, $retValue);

if ($retValue !== 0) {
    throw new \SetaPDF_Signer_Exception(
        sprintf('An error occurs while calling OpenSSL through CLI (exit code %s).', $retValue)
    );
}

// get the signature data
$signatureValue = file_get_contents($tmpFileOut);

// pass it to the module
$module->setSignatureValue($signatureValue);

// get the final cms container
$cms = $module->getCms();
// and pass it to the main signer instance
$signer->saveSignature($tmpDocument, $cms);