<?php

/**
 * Class irenHmac
 * 
 * <h5>Questa classe implementa l'autenticazione attraverso 
 * il protocollo HMAC (Hash - based message authentication)</h5>
 * 
 * <b>Descrizione dell'Algoritmo:</b>
 * <ol>
 * <li>Rimozione del protocollo, nome del server e porta dalla URL Chiamata</li>
 * <li>Decodifica dei parametri di GET</li>
 * <li>Ordinamento alfabetico degli stessi</li> 
 * <li>Costruzione della queryString</li>
 * <li>Costruzione della stringa da criptare (path dello script + queryString)</li>
 * <li>Hash SHA256 della chiave</li>
 * <li>HMAC con SHA256 con la chiave generata al passo precedente</li>
 * <li>base64 della hash ottenuta</li>
 * </ol>
 * 
 * @author Marco Carbone <marco.carbone@gisweb.it>
 * 
 */

class irenHmac{

    /**
     * @var string Chiave condivisa per criptare il messaggio definita ne file config.php
     */
    static $secret = MYSECRET;
    /**
     * @var string Nome del parametro di GET per Autenticazione
     */
    static $authParam = "hmac";
    /**
     * @var string[] Parametri di GET da non considerare nel criptare 
     *               il messaggio
     */
    static $inValidParams = Array("hmac");
    /**
     * @var string URL di redirect alla quale rimandare in caso di mancanza 
     *             di Autenticazione
     */
    static $noAuthPage = "noauth.html";
    /**
     * @var string URL di redirect alla quale rimandare in caso di 
     *             Autenticazione fallita
     */
    static $noValidPage = "novalid.html";
    
    /**
     * Metodo per la preparazione della Stringa da Criptare
     * 
     * @param $path Path della pagina chiamata da autenticare
     * @param $data Parametri da considerare (generalmente i parametri di GET)
     *              per creare la stringa da criptare
     * @return string Stringa da criptare secondo i criteri 
     *                dell'HMAC Authentication
     */
    static function prepareHMacString($path,$data){
        foreach(self::$inValidParams as $prm) unset($data[$prm]);
        ksort($data); 
        $res = sprintf("%s?%s",$path,http_build_query($data));
        return $res;

    }

    /**
     * Metodo che genera il messaggio criptato
     * 
     * @param $message Messaggio da criptare
     * @return string Messaggio criptato
     */
    static function createHash($message){
        $s = hash_hmac('sha256', $message, hash('sha256',self::$secret),true);
        return base64_encode($s);
    }

    /**
     * Metodo che verifica se la hash passata è corrispondente con i 
     * parametri della chiamata
     * 
     * @param $hmac string Stringa da verificare
     * @param $path string Path dello Script
     * @param $data string[] Parametri per la costruzione della hash
     * @return bool
     */
    static function verifyHMac($hmac,$path,$data){
        $string = self::prepareHMacString($path,$data);
        $hash = self::createHash($string);
        if ($hash===$hmac){
            return True;
        }
        else{
            return False;
        }
    }
    
    /**
     * Metodo che reindirizza alla pagina di Nessuna Autenticazione passata
     * 
     * @return void
     */
    
    static function noAuth(){
        header($_SERVER['SERVER_PROTOCOL'] . ' 401 Unauthorized', true, 401);
        header("location: ".irenHmac::$noAuthPage);
        exit;
    }
    
    /**
    * Metodo che reindirizza alla pagina di Autenticazione Fallita
    * 
    * @return void
    */
    
    static function noValid(){
        header($_SERVER['SERVER_PROTOCOL'] . ' 401 Unauthorized', true, 401);
        header("location: ".irenHmac::$noValidPage);
        exit;
    }
}

?>
