Commit f152102d authored by Yannick Perret's avatar Yannick Perret
Browse files

Initial commit

parents
<?php
/*
Auteur : Yannick Perret (yannick.perret@liris.cnrs.fr) pour le LIRIS (https://liris.cnrs.fr)
Licence : GPL.
Réutilisation libre, à vos risque. Merci de m'en informer.
*/
// pour error() et entete()
require "tools.php";
// le répertoire est protégé par une authentification (LDAP dans notre cas)
// seuls les membres ont accès à l'API (en pratique le login n'est utilisé que pour nommer
// le fichier p12 résultant (cf vp12.php)
$login = $_SERVER['PHP_AUTH_USER'];
if (empty($login)) {
error("échec de récupération de votre login. Contactez XXXXXXX");
}
head("Convertir une clé privée et un certificat");
// du texte explicatif, et surtout une FORM permettant de saisir le mot de passe associé
// à la clé privée (note : le même mot de passe est utilisé pour l'export du P12), d'uploader
// la clé privée ainsi que le certificat
echo <<<_EOT_
<p>Cette application permet de <u>convertir une clé privée et un certificat</u> (format .pem ou .crt)
<u>en fichier P12</u> (utilisé pour import dans un navigateur ou un gestionnaire de mail).</p>
<form action='vp12.php' method='POST'>
<p>Veillez saisir le mot de passe (min. 8 caractères) associé à votre clé privée (le mot de passe que vous avez utilisé lors de la demande de certificat).<br/>
Mot de passe (min. 8 caractères) :
<input type='password' name='password' minlength='8' required></p>
<p>Veillez copier ou télécharger (préférable) dans cette zone le contenu (texte) votre clé privée
(celle que vous avez téléchargé lors de votre demande de certificat) :</p>
<textarea id='textarea-key' name='takey' rows='5' cols='70'>
</textarea>
<input type='file' id='input-file-key'>
<p>Veillez copier ou télécharger (préférable) dans cette zone le contenu (texte) votre certificat
(fichier prenom.nom.crt ou login.crt que vous avez reçu par mail, dans un fichier ZIP) :</p>
<textarea id='textarea-crt' name='tacrt' rows='5' cols='70'>
</textarea>
<input type='file' id='input-file-crt'>
<input type='hidden' name='taca' value=''>
<br/>
<input type='submit' value='Convertir'>
</form>
<br/><p>Note : en validant vous obtiendrez un certificat au format P12 (PKC12) que vous
pourrez télécharger.</p>
<p>Note bis : bien sûr ces informations (mots de passe, certificat…) sont traitées
à la volée et ne sont pas sauvegardées. Votre certificat vous reste personnel.
Si vous ne souhaitez pas passer par cette application pour la conversion,
vous référer à la <a href='https://INSEREZ.VOTRE.DOC'>documentation</a> pour effectuer cette opération vous-même.</p>
_EOT_;
/* Désactivé : ça perturbe trop les gens (pour l'insertion du CA dans le P12 résultant)
echo "<p>Veillez copier ou télécharger (préférable) dans cette zone le contenu (texte) du CA associé (fichier DigiCertCA.crt que vous avez reçu par mail, dans un fichier ZIP). Ceci est optionnel, le certificat personnel semble très bien fonctionner sans le CA, mais dans le doute…</p>\n";
echo "<textarea id='textarea-ca' name='taca' rows='5' cols='70'>\n";
echo "</textarea>\n";
echo "<input type='file' id='input-file-ca'>\n";
*/
// script pour l'upload des données (plus sûr qu'un copier-coller)
echo <<<EOT
<script>
document.getElementById('input-file-key')
.addEventListener('change', () => { getFile(event, 'textarea-key'); } )
document.getElementById('input-file-crt')
.addEventListener('change', () => { getFile(event, 'textarea-crt'); } )
document.getElementById('input-file-ca')
.addEventListener('change', () => { getFile(event, 'textarea-ca'); } )
function getFile(event, target) {
const input = event.target
if ('files' in input && input.files.length > 0) {
placeFileContent(
document.getElementById(target),
input.files[0])
}
}
function placeFileContent(target, file) {
readFileContent(file).then(content => {
target.value = content
}).catch(error => console.log(error))
}
function readFileContent(file) {
const reader = new FileReader()
return new Promise((resolve, reject) => {
reader.onload = event => resolve(event.target.result)
reader.onerror = error => reject(error)
reader.readAsText(file)
})
}
</script>
EOT;
echo "</body>\n</html>\n";
die();
<?php
// génère un document "en erreur"
function error($text) {
echo <<<_EOT_
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Erreur</title>
<meta name="Description" content="Erreur">
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="icon" type="type/ico" href="HAL_favicon.ico" />
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<p>Erreur : $text.</p>
</body>
</html>
_EOT_;
die(1);
}
// génère l'entête HTML
function head($title) {
echo <<<_EOT_
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>$title</title>
<meta name="Description" content="Résultat">
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="icon" type="type/ico" href="HAL_favicon.ico" />
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
_EOT_;
}
<?php
/*
Auteur : Yannick Perret (yannick.perret@liris.cnrs.fr) pour le LIRIS (https://liris.cnrs.fr)
Licence : GPL.
Réutilisation libre, à vos risque. Merci de m'en informer.
*/
// pour error() et entete()
require "tools.php";
// le répertoire est protégé par une authentification (LDAP dans notre cas)
$login = $_SERVER['PHP_AUTH_USER'];
if (empty($login)) {
error("échec de récupération de votre login. Contactez XXXXX");
}
// on récupère les infos ($password2 est le mot de passe d'export : on utilise le même)
$password = $_POST['password'];
$password2 = $password;
$key = $_POST['takey'];
$cert = $_POST['tacrt'];
$ca = $_POST['taca'];
// vérification des données
if (empty($password) || empty($password2) || empty($key) ||
empty($cert)) {
error("il manque une information requise (clé privée, certificat ou mot de passe)");
}
// on charge la clé
$skey = openssl_pkey_get_private($key, $password);
if ($skey === FALSE) {
error("échec de lecture de la clé (mauvais fichier ? mauvais mot de passe ?)");
}
// on fait la conversion du certificat
$ret = openssl_pkcs12_export($cert, $cres, $skey, $password2);
if ($ret === FALSE) {
error("échec de convertion du certificat (mauvais fichier ?)");
}
// ok. zone pour récupérer (sauvegarder) le fichier P12 (qui est binaire, d'où le passage
// par du BASE64 en intermédiaire)
// le fichier est nommé par défaut selon le login de l'utilisateur
head("Conversion de certificat");
echo <<<_EOT_
<p>La conversion a fonctionné. Récupérez le certificat au format P12
en utilisant le bouton « Télécharger » ci-dessous.</p>
<p>Veuillez à ne pas oublier le mot de passe associé, il vous sera nécessaire pour
importer votre certificat dans un outil (navigateur…).</p>
<p>Vous référer à la documentation pour l'import d'un certificat :
<a href='https://INSEREZ.VOTRE.DOC'>https://INSEREZ.VOTRE.DOC</a></p>
<a id='a' class='btn' download='$login.p12' type='application/octet-stream'>Télécharger le certificat format P12</a>
<script>
_EOT_;
// partie pour encoder le contenu ($cres) en base64 (on ne peut pas mettre du binaire directement
// dans le code HTML) puis inversement, et permet le téléchargement
echo <<<EOF
/**
* Convert a base64 string to an ArrayBuffer
*/
function base64ToArrayBuffer( base64 ) {
var raw = window.atob( base64 );
var rawLength = raw.length;
var array = new Uint8Array( new ArrayBuffer(rawLength) );
for( i = 0; i < rawLength; i++ ) {
array[ i ] = raw.charCodeAt( i );
}
return( array.buffer );
}
EOF;
echo "var a = document.getElementById('a'); var cont = base64ToArrayBuffer('";
echo base64_encode($cres);
echo "'); var bcont = new Blob([cont]); a.href = URL.createObjectURL(bcont);</script>\n";
echo "</body>\n</html>\n";
die();
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment