safeLoad();
$basePath = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/');
// ── HTTP Basic Auth ──
$authUser = $_ENV['AUTH_USERNAME'] ?? '';
$authPass = $_ENV['AUTH_PASSWORD'] ?? '';
if ($authUser !== '' || $authPass !== '') {
if (!isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])) {
$authHeader = $_SERVER['HTTP_AUTHORIZATION']
?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION']
?? '';
if (preg_match('/Basic\s+(.+)/i', $authHeader, $m)) {
$decoded = base64_decode($m[1], true);
if ($decoded !== false && str_contains($decoded, ':')) {
[$_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']]
= explode(':', $decoded, 2);
}
}
}
$valid = ($_SERVER['PHP_AUTH_USER'] ?? '') === $authUser
&& ($_SERVER['PHP_AUTH_PW'] ?? '') === $authPass;
if (!$valid) {
header('WWW-Authenticate: Basic realm="DropSign"');
http_response_code(401);
echo json_encode(['error' => 'Authentication required']);
exit;
}
}
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()]);
}