safeLoad(); $basePath = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/'); if ($_SERVER['REQUEST_METHOD'] === 'GET') { ?> DropSign

DropSign

Drop a PDF — get it cryptographically signed

🔐
Drag & drop a PDF here
or click to browse
Configure certificate in .env
'Upload failed']); exit; } $env = $_ENV; $certPem = $privKeyPem = $privKeyPass = ''; $certFile = $env['CERT_FILE'] ?? ''; $keyFile = $env['PRIVKEY_FILE'] ?? ''; if ($certFile && $keyFile) { $certPath = __DIR__ . '/' . $certFile; $keyPath = __DIR__ . '/' . $keyFile; $privKeyPass = $env['PRIVKEY_PASSWORD'] ?? ''; if (!file_exists($certPath)) { http_response_code(500); echo json_encode(['error' => 'Certificate not found: ' . $certFile]); exit; } if (!file_exists($keyPath)) { http_response_code(500); echo json_encode(['error' => 'Private key not found: ' . $keyFile]); exit; } $certPem = file_get_contents($certPath); $privKeyPem = file_get_contents($keyPath); } else { $p12Path = __DIR__ . '/' . ($env['PKCS12_FILE'] ?? 'certificate.p12'); $p12Pass = $env['PKCS12_PASSWORD'] ?? ''; if (!file_exists($p12Path)) { http_response_code(500); echo json_encode(['error' => 'Certificate file not found. Set CERT_FILE+PRIVKEY_FILE or PKCS12_FILE in .env']); exit; } $p12Content = file_get_contents($p12Path); if (!openssl_pkcs12_read($p12Content, $certs, $p12Pass)) { http_response_code(500); echo json_encode(['error' => 'Failed to read PKCS#12 certificate. Check password.']); exit; } $certPem = $certs['cert']; $privKeyPem = $certs['pkey']; $privKeyPass = $p12Pass; } try { $pdf = new Fpdi(); $pageCount = $pdf->setSourceFile($_FILES['pdf']['tmp_name']); for ($i = 1; $i <= $pageCount; $i++) { $tplId = $pdf->importPage($i); $size = $pdf->getTemplateSize($tplId); $orientation = ($size['width'] > $size['height']) ? 'L' : 'P'; $pdf->AddPage($orientation, [$size['width'], $size['height']]); $pdf->useTemplate($tplId); } $pdf->setSignature( $certPem, $privKeyPem, $privKeyPass, '', // extracerts (chain already in fullchain6.pem) 2, // cert_type (CMS) [ 'Name' => $env['SIGNATURE_NAME'] ?? '', 'Location' => $env['SIGNATURE_LOCATION'] ?? '', 'Reason' => $env['SIGNATURE_REASON'] ?? '', 'ContactInfo' => $env['SIGNATURE_CONTACT'] ?? '', ], '' // approval ); $outPath = tempnam(sys_get_temp_dir(), 'dropsign_') . '.pdf'; $pdf->Output($outPath, 'F'); header('Content-Type: application/pdf'); header('Content-Disposition: attachment; filename="signed_' . basename($_FILES['pdf']['name']) . '"'); header('Content-Length: ' . filesize($outPath)); readfile($outPath); unlink($outPath); } catch (\Exception $e) { http_response_code(500); echo json_encode(['error' => $e->getMessage()]); }