import java.io.*;
import java.security.*;
import java.security.cert.*;
import java.security.interfaces.*;

/** Program wykorzystuje klucz publiczny z certyfikatu (czyli plik z 
 *  oryginalnymi danymi oraz dwa pliki wygenerowane przez program SignData)
 *  do porównania podpisu cyfrowego z plikiem.
 */

public class VerifyData
{
    public static void main(String[] args)
    {
        try
        {
            if (args.length < 3)
            {
                System.out.println(
                    "Proszę podać plik z danymi, plik podpisu "+
                    "oraz plik certyfikatu.");
                System.exit(1);
            }

            FileInputStream certFile = new FileInputStream(args[2]);

// Tworzenie konstruktora certyfikatu, odczytującego certyfikat X.509.
            CertificateFactory certFact = CertificateFactory.
                getInstance("X.509");

// Wczytanie certyfikatu z odpowiedniego pliku.
            java.security.cert.Certificate cert =
                certFact.generateCertificate(certFile);

            certFile.close();

// Ekstrakcja klucza publicznego z certyfikatu (przy założeniu, że jest to klucz RSA).
            RSAPublicKey pubKey = (RSAPublicKey) cert.getPublicKey();

// Tworzenie i inicjalizacja obiektuvSignature dla MD5 i RSA.
            Signature sigVerifier = Signature.getInstance("MD5withRSA");
            sigVerifier.initVerify(pubKey);

// Otwarcie pliku z danymi.
            FileInputStream dataFile = new FileInputStream(args[0]);

// Utworzenie bufora do odczytu pliku.
            byte[] buffer = new byte[4096];

            int len;

// Odczyt bloku bajtów z pliku i dołączenie go do podpisu.
            while ((len = dataFile.read(buffer)) > 0)
            {
                sigVerifier.update(buffer, 0, len);
            }

            dataFile.close();

// Tworzenie bufora dla oryginalnego podpisu.
            File sigFile = new File(args[1]);
            byte sigBytes[] = new byte[(int) sigFile.length()];

// Odczyt podpisu z pliku.
            FileInputStream sigIn = new FileInputStream(sigFile);
            sigIn.read(sigBytes);
            sigIn.close();

// Porównanie podpisu z pliku z plikiem danych
// i kluczem publicznym z certyfikatu.
            if (sigVerifier.verify(sigBytes))
            {
                System.out.println("Podpis pasuje.");
            }
            else
            {
                System.out.println(
                    "Podpis nie pasuje.");
            }
        }
        catch (Exception exc)
        {
            exc.printStackTrace();
        }
    }
}
