mirror of
https://github.com/tips-of-mine/gestion-certificats2.git
synced 2025-06-28 09:18:42 +02:00
feat: Permettre la révocation des certificats intermédiaires
Implémente la fonctionnalité de révocation pour les certificats de type 'intermédiaire'. Modifications principales : - CertificateController.php : - Suppression de l'interdiction de révoquer les certificats intermédiaires. - Ajout d'une logique spécifique pour révoquer un certificat intermédiaire en utilisant la configuration et la CRL du CA Racine. - Les certificats 'simple' continuent d'être révoqués via le script revoke_cert.sh. - app/src/Views/certificates/index.php : - Le bouton 'Révoquer' est maintenant affiché pour les certificats intermédiaires non révoqués. - app/src/Lang/fr.json : - Ajout de nouvelles clés de traduction pour les messages relatifs à la révocation des certificats intermédiaires. - Modification de la clé 'cert_revoke_error_ca_revocation' pour indiquer que seuls les certificats ROOT ne peuvent être révoqués via l'interface. Ces modifications permettent une gestion plus complète des certificats intermédiaires directement depuis l'interface utilisateur.
This commit is contained in:
@ -238,16 +238,14 @@ class CertificateController
|
||||
exit();
|
||||
}
|
||||
|
||||
// Empêcher la révocation des certificats Root ou Intermédiaires via l'interface
|
||||
if ($cert['type'] === 'root' || $cert['type'] === 'intermediate') {
|
||||
$_SESSION['error'] = $this->langService->__('cert_revoke_error_ca_revocation');
|
||||
// Empêcher la révocation des certificats Root via l'interface
|
||||
if ($cert['type'] === 'root') {
|
||||
$_SESSION['error'] = $this->langService->__('cert_revoke_error_ca_revocation'); // Peut-être une clé dédiée pour root si le message doit être différent
|
||||
header('Location: /certificates');
|
||||
exit();
|
||||
}
|
||||
|
||||
// Préparer le nom de base du certificat pour le script (sans l'extension .pem)
|
||||
$certBaseName = str_replace('.cert.pem', '.cert', $cert['name']);
|
||||
$functionalPerimeterName = $cert['perimeter_name'];
|
||||
$functionalPerimeterName = $cert['perimeter_name']; // Déjà récupéré plus haut, mais utile ici aussi
|
||||
|
||||
// Vérifier si le certificat n'est pas déjà révoqué dans la DB
|
||||
if ($cert['is_revoked']) {
|
||||
@ -256,29 +254,79 @@ class CertificateController
|
||||
exit();
|
||||
}
|
||||
|
||||
// Appeler le script shell de révocation
|
||||
$command = escapeshellcmd(SCRIPTS_PATH . '/revoke_cert.sh') . ' ' .
|
||||
escapeshellarg($certBaseName) . ' ' .
|
||||
escapeshellarg($functionalPerimeterName);
|
||||
if ($cert['type'] === 'intermediate') {
|
||||
// Logique de révocation pour les certificats intermédiaires
|
||||
$intermediateCertPath = "/opt/tls/intermediate/" . $functionalPerimeterName . "/certs/" . $cert['name'];
|
||||
$rootCaConfigPath = "/opt/tls/root/openssl.cnf"; // Chemin vers la configuration OpenSSL du CA Racine
|
||||
$rootCaCrlPath = "/opt/tls/root/crl/crl.pem"; // Chemin vers la CRL du CA Racine
|
||||
|
||||
$this->logService->log('info', "Tentative de révocation du certificat '{$cert['name']}' pour le périmètre '$functionalPerimeterName'. Commande: '$command'", $userId, $ipAddress);
|
||||
// Commande pour révoquer le certificat intermédiaire avec le CA Racine
|
||||
$revokeCmd = sprintf(
|
||||
"openssl ca -batch -config %s -revoke %s",
|
||||
escapeshellarg($rootCaConfigPath),
|
||||
escapeshellarg($intermediateCertPath)
|
||||
);
|
||||
|
||||
$output = shell_exec($command . ' 2>&1');
|
||||
$this->logService->log('info', "Tentative de révocation du certificat intermédiaire '{$cert['name']}' pour le périmètre '$functionalPerimeterName'. Commande: '$revokeCmd'", $userId, $ipAddress);
|
||||
$outputRevoke = shell_exec($revokeCmd . ' 2>&1');
|
||||
|
||||
if (strpos($output, "Certificat '$certBaseName' révoqué avec succès.") !== false) {
|
||||
// Mettre à jour le statut du certificat dans la base de données
|
||||
$stmt = $this->db->prepare("UPDATE certificates SET is_revoked = TRUE, revoked_at = NOW() WHERE id = ?");
|
||||
$stmt->execute([$certificateId]);
|
||||
if (strpos($outputRevoke, "Data Base Updated") !== false || strpos($outputRevoke, "Successfully revoked certificate") !== false) {
|
||||
// Commande pour régénérer la CRL du CA Racine
|
||||
$generateCrlCmd = sprintf(
|
||||
"openssl ca -batch -config %s -gencrl -out %s",
|
||||
escapeshellarg($rootCaConfigPath),
|
||||
escapeshellarg($rootCaCrlPath)
|
||||
);
|
||||
|
||||
$this->logService->log('info', "Révocation réussie. Tentative de mise à jour de la CRL du CA Racine. Commande: '$generateCrlCmd'", $userId, $ipAddress);
|
||||
$outputCrl = shell_exec($generateCrlCmd . ' 2>&1');
|
||||
|
||||
// Vérifier si la CRL a été générée et si le fichier existe
|
||||
if ((strpos($outputCrl, "CRL Generated") !== false || strpos($outputCrl, "CRL generated") !== false) && file_exists($rootCaCrlPath)) {
|
||||
// Mettre à jour le statut du certificat dans la base de données
|
||||
$stmt_update = $this->db->prepare("UPDATE certificates SET is_revoked = TRUE, revoked_at = NOW() WHERE id = ?");
|
||||
$stmt_update->execute([$certificateId]);
|
||||
|
||||
$this->logService->log('info', "Certificat intermédiaire '{$cert['name']}' révoqué et CRL du CA Racine mise à jour.", $userId, $ipAddress);
|
||||
$_SESSION['success'] = $this->langService->__('cert_revoke_success_intermediate', ['name' => $cert['name']]);
|
||||
} else {
|
||||
$this->logService->log('error', "Échec de la mise à jour de la CRL du CA Racine pour le cert intermédiaire '{$cert['name']}'. Output CRL: $outputCrl. Output Revoke: $outputRevoke", $userId, $ipAddress);
|
||||
$_SESSION['error'] = $this->langService->__('cert_revoke_warn_crl_update_failed_intermediate', ['name' => $cert['name']]);
|
||||
}
|
||||
} else {
|
||||
$_SESSION['error'] = $this->langService->__('cert_revoke_error_intermediate', ['name' => $cert['name'], 'output' => htmlspecialchars($outputRevoke)]);
|
||||
$this->logService->log('error', "Échec de la révocation du certificat intermédiaire '{$cert['name']}'. Output: $outputRevoke", $userId, $ipAddress);
|
||||
}
|
||||
header('Location: /certificates');
|
||||
exit();
|
||||
|
||||
$this->logService->log('info', "Certificat '{$cert['name']}' révoqué et enregistré en DB.", $userId, $ipAddress);
|
||||
$_SESSION['success'] = $this->langService->__('cert_revoke_success');
|
||||
} else {
|
||||
$_SESSION['error'] = $this->langService->__('cert_revoke_error', ['output' => htmlspecialchars($output)]);
|
||||
$this->logService->log('error', "Échec révocation certificat '{$cert['name']}': $output", $userId, $ipAddress);
|
||||
}
|
||||
// Logique existante pour les certificats 'simple'
|
||||
$certBaseName = str_replace('.cert.pem', '.cert', $cert['name']);
|
||||
|
||||
header('Location: /certificates');
|
||||
exit();
|
||||
// Appeler le script shell de révocation
|
||||
$command = escapeshellcmd(SCRIPTS_PATH . '/revoke_cert.sh') . ' ' .
|
||||
escapeshellarg($certBaseName) . ' ' .
|
||||
escapeshellarg($functionalPerimeterName);
|
||||
|
||||
$this->logService->log('info', "Tentative de révocation du certificat simple '{$cert['name']}' pour le périmètre '$functionalPerimeterName'. Commande: '$command'", $userId, $ipAddress);
|
||||
|
||||
$output = shell_exec($command . ' 2>&1');
|
||||
|
||||
if (strpos($output, "Certificat '$certBaseName' révoqué avec succès.") !== false) {
|
||||
// Mettre à jour le statut du certificat dans la base de données
|
||||
$stmt_update = $this->db->prepare("UPDATE certificates SET is_revoked = TRUE, revoked_at = NOW() WHERE id = ?");
|
||||
$stmt_update->execute([$certificateId]);
|
||||
|
||||
$this->logService->log('info', "Certificat simple '{$cert['name']}' révoqué et enregistré en DB.", $userId, $ipAddress);
|
||||
$_SESSION['success'] = $this->langService->__('cert_revoke_success');
|
||||
} else {
|
||||
$_SESSION['error'] = $this->langService->__('cert_revoke_error', ['output' => htmlspecialchars($output)]);
|
||||
$this->logService->log('error', "Échec révocation certificat simple '{$cert['name']}': $output", $userId, $ipAddress);
|
||||
}
|
||||
header('Location: /certificates');
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,7 +61,7 @@
|
||||
"cert_create_error": "Erreur lors de la création du certificat: {output}",
|
||||
"cert_revoke_error_id_missing": "ID du certificat manquant pour la révocation.",
|
||||
"cert_revoke_error_not_found": "Certificat introuvable pour la révocation.",
|
||||
"cert_revoke_error_ca_revocation": "Les certificats ROOT et INTERMÉDIAIRES ne peuvent pas être révoqués via l'interface pour des raisons de sécurité PKI.",
|
||||
"cert_revoke_error_ca_revocation": "Les certificats ROOT ne peuvent pas être révoqués via l'interface pour des raisons de sécurité PKI.",
|
||||
"cert_revoke_error_already_revoked": "Ce certificat est déjà révoqué.",
|
||||
"cert_revoke_success": "Certificat révoqué avec succès.",
|
||||
"cert_revoke_error": "Erreur lors de la révocation du certificat: {output}",
|
||||
@ -80,5 +80,8 @@
|
||||
"user_delete_success": "Utilisateur '{username}' supprimé avec succès.",
|
||||
"user_delete_error_not_found": "Utilisateur introuvable pour la suppression.",
|
||||
"user_delete_error_db": "Erreur lors de la suppression de l'utilisateur dans la base de données.",
|
||||
"self_delete_not_allowed": "Vous ne pouvez pas vous supprimer vous-même."
|
||||
"self_delete_not_allowed": "Vous ne pouvez pas vous supprimer vous-même.",
|
||||
"cert_revoke_success_intermediate": "Le certificat intermédiaire '{name}' a été révoqué avec succès et la CRL du CA Racine a été mise à jour.",
|
||||
"cert_revoke_warn_crl_update_failed_intermediate": "Le certificat intermédiaire '{name}' a été révoqué, mais la mise à jour de la CRL du CA Racine a rencontré un problème. Veuillez contacter un administrateur.",
|
||||
"cert_revoke_error_intermediate": "Erreur lors de la révocation du certificat intermédiaire '{name}': {output}"
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ require_once APP_ROOT_DIR . '/src/Views/shared/header.php';
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
// Seuls les certificats 'simple' et non révoqués peuvent être révoqués via l'interface
|
||||
if (!$cert['is_revoked'] && $cert['type'] === 'simple'): ?>
|
||||
// Les certificats 'simple' ou 'intermediate' non révoqués peuvent être révoqués
|
||||
if (!$cert['is_revoked'] && ($cert['type'] === 'simple' || $cert['type'] === 'intermediate')): ?>
|
||||
<form action="/certificates/revoke" method="post" class="inline-form" onsubmit="return confirm('<?= htmlspecialchars($translations['confirm_revoke']) ?>');">
|
||||
<input type="hidden" name="certificate_id" value="<?= htmlspecialchars($cert['id']) ?>">
|
||||
<button type="submit" class="button danger-button"><?= htmlspecialchars($translations['revoke_certificate']) ?></button>
|
||||
|
Reference in New Issue
Block a user