From fb5f9fef55e8d2caf1faa5efdb9f18c36349e5d6 Mon Sep 17 00:00:00 2001 From: "florian.azizian" <florian.azizian@maarch.org> Date: Wed, 9 Dec 2020 18:15:24 +0100 Subject: [PATCH] FIX #14565 TIME 0:00 Sign document with certificate --- .../CertificateSignatureController.php | 91 +++++++++++++++++++ .../controllers/DocumentController.php | 12 ++- 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/src/app/document/controllers/CertificateSignatureController.php b/src/app/document/controllers/CertificateSignatureController.php index dc9d44f2c5..e44ee5ae9d 100755 --- a/src/app/document/controllers/CertificateSignatureController.php +++ b/src/app/document/controllers/CertificateSignatureController.php @@ -14,12 +14,18 @@ namespace Document\controllers; +use Docserver\models\AdrModel; +use Docserver\models\DocserverModel; +use SrcCore\models\CoreConfigModel; + class CertificateSignatureController { public static $signatureLength = 30000; public static function getHashedCertificate(array $args) { + $libDir = CoreConfigModel::getLibrariesDirectory(); + require_once($libDir . 'SetaPDF-Signer/library/SetaPDF/Autoload.php'); $document = \SetaPDF_Core_Document::loadByString($args['document']); $signer = new \SetaPDF_Signer($document); @@ -69,4 +75,89 @@ class CertificateSignatureController 'signatureContentLength' => $signatureContentLength ]; } + + public static function signDocument($args = []) + { + $libDir = CoreConfigModel::getLibrariesDirectory(); + require_once($libDir . 'SetaPDF-Signer/library/SetaPDF/Autoload.php'); + $certificateSignature = \SetaPDF_Core_Type_HexString::hex2str($args['hashSignature']); + $signatureContentLength = $args['signatureContentLength']; + $certificate = $args['certificate']; + + $adr = AdrModel::getDocumentsAdr([ + 'select' => ['path', 'filename'], + 'where' => ['main_document_id = ?', 'type = ?'], + 'data' => [$args['id'], 'ESIGN'] + ]); + $docserver = DocserverModel::getByType(['type' => 'ESIGN', 'select' => ['path']]); + $pathToDocument = $docserver['path'] . $adr[0]['path'] . $adr[0]['filename']; + $tmpPath = CoreConfigModel::getTmpPath(); + $signedDocumentPath = $tmpPath . $GLOBALS['id'] . '_' . rand() . '_signedDocument.pdf'; + $writer = new \SetaPDF_Core_Writer_File($signedDocumentPath); + $document = \SetaPDF_Core_Document::loadByFilename($pathToDocument, $writer); + $signer = new \SetaPDF_Signer($document); + + // create a module instance + $module = new \SetaPDF_Signer_Signature_Module_Pades(); + // create a certificate instance + $certificate = new \SetaPDF_Signer_X509_Certificate($certificate); + // pass the user certificate to the module + $module->setCertificate($certificate); + // setup information resolver manager + $informationResolverManager = new \SetaPDF_Signer_InformationResolver_Manager(); + $informationResolverManager->addResolver(new \SetaPDF_Signer_InformationResolver_HttpCurlResolver()); + $extraCerts = new \SetaPDF_Signer_X509_Collection(); + + $certificates = [$certificate]; + while (count($certificates) > 0) { + $currentCertificate = array_pop($certificates); + $aia = $currentCertificate->getExtensions()->get(\SetaPDF_Signer_X509_Extension_AuthorityInformationAccess::OID); + if ($aia instanceof \SetaPDF_Signer_X509_Extension_AuthorityInformationAccess) { + foreach ($aia->fetchIssuers($informationResolverManager)->getAll() as $issuer) { + $extraCerts->add($issuer); + $certificates[] = $issuer; + } + } + } + + $module->setExtraCertificates($extraCerts); + + foreach ($extraCerts->getAll() as $extraCert) { + $signatureContentLength += (strlen($extraCert->get(\SetaPDF_Signer_X509_Format::DER)) * 2); + } + $signer->setSignatureContentLength($signatureContentLength); + + // pass the signature to the signature module + $module->setSignatureValue($certificateSignature); + // get the CMS structur from the signature module + $cms = (string)$module->getCms(); + + $ts = $certificate->getExtensions()->get(\SetaPDF_Signer_X509_Extension_TimeStamp::OID); + if ($ts && $ts->getVersion() === 1 && $ts->requiresAuth() === false) { + $tsLocation = $ts->getLocation(); + } + + if (isset($tsLocation)) { + $tsModule = new \SetaPDF_Signer_Timestamp_Module_Rfc3161_Curl($tsLocation); + $signer->setTimestampModule($tsModule); + $cms = $signer->addTimeStamp($cms, $tmpDocument); + } + + $tempPath = \SetaPDF_Core_Writer_TempFile::createTempPath(); + $tmpDocument = $signer->preSign( + new \SetaPDF_Core_Writer_File($tempPath), + $module + ); + + // save the signature to the temporary document + $signer->saveSignature($tmpDocument, $cms); + try { + $signer->saveSignature($tmpDocument, $cms); + unlink($tmpDocument->getWriter()->getPath()); + } catch (\SetaPDF_Signer_Exception_ContentLength $e) { + unlink($tmpDocument->getWriter()->getPath()); + $signatureContentLength = $signatureContentLength + 1000; + return ['errors' => 'Not enought space for signature', 'newSignatureLength' => $signatureContentLength]; + } + } } diff --git a/src/app/document/controllers/DocumentController.php b/src/app/document/controllers/DocumentController.php index 44611742e7..0e9fb6f990 100755 --- a/src/app/document/controllers/DocumentController.php +++ b/src/app/document/controllers/DocumentController.php @@ -659,7 +659,7 @@ class DocumentController exec("php src/app/convert/scripts/ThumbnailScript.php '{$configPath}' {$args['id']} 'document' '{$GLOBALS['id']}' {$page} > /dev/null &"); } - if ($workflow['signature_mode'] == 'rgs_2stars' ) { + if ($workflow['signature_mode'] == 'rgs_2stars') { $hashInformations = CertificateSignatureController::getHashedCertificate(['document' => $fileContent, 'certificate' => $body['certificate']]); return $response->withJson($hashInformations); } @@ -767,6 +767,16 @@ class DocumentController } elseif (DocumentController::ACTIONS[$args['actionId']] == 'REF' && $workflow['mode'] == 'sign') { DigitalSignatureController::abort(['signatureId' => $workflow['digital_signature_id'], 'documentId' => $args['id']]); } + } elseif ($workflow['signature_mode'] == 'rgs_2stars') { + $return = CertificateSignatureController::signDocument([ + 'id' => $args['id'], + 'certificate' => $args['certificate'], + 'signatureContentLength' => $args['signatureContentLength'], + 'hashSignature' => $args['hashSignature'] + ]); + if (!empty($return['errors'])) { + return $response->withStatus(400)->withJson($return); + } } $set = ['process_date' => 'CURRENT_TIMESTAMP', 'status' => DocumentController::ACTIONS[$args['actionId']]]; -- GitLab