package mixconfig.tools.dataretention;

/*
 * RetentionDlg.java
 *
 * Created on Dec 11, 2008, 9:09:06 PM
 */

/**
 *
 * @author Petr Svenda
 */

import java.security.*;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.File;

import anon.crypto.MyRSAPrivateKey;
import anon.crypto.PKCS12;

public class RetentionDlg extends javax.swing.JFrame {
    static DataRetentionSmartCard    anonLog = new DataRetentionSmartCard();

    private static byte  testLogKey[] = {(byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x31};
    PublicKey           m_publicKey = null;
    byte[]              m_logKeyBlock = null;

    private final static byte FOOTER_LENGTH = 20;


    /** Creates new form RetentionDlg */
    public RetentionDlg() {
        initComponents();

        try {
            m_logs.append("Connecting to ANON card... ");
            if (anonLog.connectToSmartCard()) {
                m_logs.append("OK\n");

                m_logs.append("Retriving public key... ");
                try {
                    if ((m_publicKey = anonLog.retrievePublicKey()) != null) {
                        m_logs.append("OK\n");
                        m_logs.append(m_publicKey.toString() + "\n");
                    }
                    else {
                        m_logs.append("FAIL\n");
                    }
                }
                catch (Exception ex) {
                    m_logs.append("FAIL\n");
                    System.out.println("Exception : " + ex);
                }
            }
            else {
                throw new Exception();
            }
        }
        catch (Exception ex) {
            m_logs.append("FAIL\n");
            System.out.println("Exception : " + ex);
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jButton1 = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();
        m_currentDate = new javax.swing.JTextField();
        SetCurrentDate = new javax.swing.JButton();
        m_adminPIN = new javax.swing.JPasswordField();
        jPanel2 = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        authenticateUser = new javax.swing.JButton();
        retrieveLogs = new javax.swing.JButton();
        m_logsPeriod = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        m_userPIN = new javax.swing.JPasswordField();
        jScrollPane1 = new javax.swing.JScrollPane();
        m_logs = new javax.swing.JTextArea();
        jPanel3 = new javax.swing.JPanel();
        m_testLogsPeriod = new javax.swing.JTextField();
        createTestLogs = new javax.swing.JButton();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("ANON Log access console");

        jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        jLabel1.setText("Admin PIN");

        jButton1.setText("Authenticate admin");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jLabel2.setText("Current date (ddmmyyy)");

        m_currentDate.setText("14122008");

        SetCurrentDate.setText("Set current date");
        SetCurrentDate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SetCurrentDateActionPerformed(evt);
            }
        });

        m_adminPIN.setText("12345678");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(m_currentDate)
                    .addComponent(jLabel2)
                    .addComponent(jLabel1)
                    .addComponent(m_adminPIN, javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(SetCurrentDate, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap(13, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(m_adminPIN, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButton1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(m_currentDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(SetCurrentDate))
                .addContainerGap())
        );

        jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        jLabel3.setText("User PIN");

        authenticateUser.setText("Authenticate user");
        authenticateUser.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                authenticateUserActionPerformed(evt);
            }
        });

        retrieveLogs.setText("Retrieve logs");
        retrieveLogs.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                retrieveLogsActionPerformed(evt);
            }
        });

        m_logsPeriod.setText("31122008");

        jLabel4.setText("Logs date  (ddmmyyy)");

        m_userPIN.setText("1234");

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(m_logsPeriod, javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel4)
                    .addComponent(jLabel3)
                    .addComponent(m_userPIN, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(retrieveLogs, javax.swing.GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE)
                    .addComponent(authenticateUser, javax.swing.GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel3)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(m_userPIN, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(authenticateUser))
                .addGap(10, 10, 10)
                .addComponent(jLabel4)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(m_logsPeriod, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(retrieveLogs))
                .addContainerGap(16, Short.MAX_VALUE))
        );

        m_logs.setColumns(20);
        m_logs.setRows(5);
        jScrollPane1.setViewportView(m_logs);

        jPanel3.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        m_testLogsPeriod.setText("11102008");

        createTestLogs.setText("Generate test logs");
        createTestLogs.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
              //  createTestLogsActionPerformed(evt);
            }
        });

        jLabel5.setText(".: Development test functions :.");

        jLabel6.setText("Logs date  (ddmmyyy)");

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, 279, Short.MAX_VALUE)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanel3Layout.createSequentialGroup()
                                .addComponent(jLabel6)
                                .addGap(158, 158, 158))
                            .addGroup(jPanel3Layout.createSequentialGroup()
                                .addComponent(m_testLogsPeriod, javax.swing.GroupLayout.PREFERRED_SIZE, 132, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(createTestLogs, javax.swing.GroupLayout.DEFAULT_SIZE, 127, Short.MAX_VALUE)))
                        .addContainerGap())))
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGap(5, 5, 5)
                .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jLabel6)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(m_testLogsPeriod, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(createTestLogs))
                .addContainerGap(12, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(jPanel3, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(18, 18, 18)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 623, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(38, 38, 38))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        m_logs.append("\n");
        // LOG ADMIN
        m_logs.append("Authenticating admin by PIN... ");
        try {
            if (anonLog.Admin_Authenticate(m_adminPIN.getText().getBytes())) {
                m_logs.append("OK\n");
            }
            else m_logs.append("FAIL\n");
        }
        catch (Exception ex) {
            m_logs.append("FAIL\n");
            System.out.println("Exception : " + ex);
        }
    }//GEN-LAST:event_jButton1ActionPerformed

    private void SetCurrentDateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SetCurrentDateActionPerformed
        m_logs.append("\n");
        try {
            byte day = (byte) Integer.parseInt(m_currentDate.getText(0, 2));
            byte month = (byte) Integer.parseInt(m_currentDate.getText(2, 2));
            short year = (short) Integer.parseInt(m_currentDate.getText(4, 4));
            m_logs.append("Setting current date '" + Integer.toString(day) + "." + Integer.toString(month) + "." + Integer.toString(year) + "' .... ");
            if (anonLog.Admin_SetCurrentDate(day, month, year)) {
                m_logs.append("OK\n");
            }
            else m_logs.append("FAIL (Are you authenticated as admin?)\n");
        }
        catch (Exception ex) {
            m_logs.append("FAIL (Are you authenticated as admin?)\n");
            System.out.println("Exception : " + ex);
        }
    }//GEN-LAST:event_SetCurrentDateActionPerformed

    private void authenticateUserActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_authenticateUserActionPerformed
        m_logs.append("\n");
        // LOG USER
        m_logs.append("Authenticating user by PIN... ");
        try {
            if (anonLog.authenticateUser(m_userPIN.getText().getBytes())) {
                m_logs.append("OK\n");
            }
            else m_logs.append("FAIL\n");
        }
        catch (Exception ex) {
            m_logs.append("FAIL\n");
            System.out.println("Exception : " + ex);
        }
    }//GEN-LAST:event_authenticateUserActionPerformed

    private void retrieveLogsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_retrieveLogsActionPerformed
        m_logs.append("\n");
        try {
            byte logDay = (byte) Integer.parseInt(m_logsPeriod.getText(0, 2));
            byte logMonth = (byte) Integer.parseInt(m_logsPeriod.getText(2, 2));
            short logYear = (short) Integer.parseInt(m_logsPeriod.getText(4, 4));
            // TRY TO RETRIEVE KEY
            m_logs.append("Retrieving logs for period '" + Integer.toString(logDay) + "." + Integer.toString(logMonth) + "." + Integer.toString(logYear) + "'\n");

            String dateString = Integer.toString(logDay) + Integer.toString(logMonth) + Integer.toString(logYear);
            String fileName = "c:\\ANONlog_" + dateString + ".txt";
            String fileNameOut = "c:\\ANONlog_" + dateString + ".txt.ret";
            FileInputStream in = new FileInputStream(fileName);
            FileOutputStream out = new FileOutputStream(fileNameOut);
            m_logs.append("Processing file '" + fileName + "'\n");
            m_logs.append("Writing into file '" + fileNameOut + "'\n");

            // READ AND PARSE HEADER
            DataRetentionLogFileHeader   header = new DataRetentionLogFileHeader();
            m_logs.append("Parsing header... ");
            header.parseFromFile(in);
            m_logs.append("OK\n");
            header.writeToFile(out);

            // TAKE FIRST KEY AND TRY TO DECRYPT
            // TODO: solve probelm with multiple keys
            byte[] decrLogKey = null;
            m_logs.append("Retrieving log key... ");
            PKCS12 pkcs12=PKCS12.getInstance(new FileInputStream("c:/dataretentiontest.pfx"),"");
            MyRSAPrivateKey privKey=(MyRSAPrivateKey)pkcs12.getPrivateKey();
            if ((decrLogKey = anonLog.decrpytSymmetricKey(header.getEncryptedKey(0))) != null) {
                m_logs.append("OK\n");
                m_logs.append("Log key: " + anonLog.bytesToHex(decrLogKey) + "\n");
            }
            else {
                m_logs.append("FAIL (Are you authenticated as user?)\n");
                throw new Exception();
            }

            // COMPUTE EXPECTED ENCRYPTED LENGTH OF LOG LINE
            int encrLogLineLength = header.getSizeOfLogLine();//
            //anonLog.GetExpectedLogLineLength(header.nr_of_log_entries_per_encrypted_log_line * ANONSCLog.entity_entry_lengths[header.logging_entity]);
            m_logs.append("Expected length of single log line: " + encrLogLineLength + "\n");

            // ESTIMATE NUMBER ENCRYPTED LOG LINES
            File file = new File(fileName);
            long fileLength = file.length();
            int numLogLinesEntries = (int) ((fileLength - header.getLength() - FOOTER_LENGTH) / encrLogLineLength);
            m_logs.append("Expected number of log entries: " + numLogLinesEntries + "\n");
            byte[] encrLogLine = new byte[encrLogLineLength];
            byte[] decrData = null;
            byte[] iv = null;
            int counter = 0;
            for (int i = 0; i < numLogLinesEntries; i++) {
                //READ LINE
                in.read(encrLogLine);
                iv = anonLog.CreateIV(counter);
                decrData = anonLog.DecryptLogLineKey(decrLogKey, encrLogLine, iv);
                m_logs.append(" Log line " + counter + " : " + anonLog.bytesToHex(decrData) + "\n");

                out.write(decrData);
                counter++;
            }
            int extraEntries=0;
            if(numLogLinesEntries*encrLogLineLength< (fileLength - header.getLength() - FOOTER_LENGTH))
            		{ //some remaining entries
            			byte tmpBuff[]=new byte[(int)((fileLength - header.getLength() - FOOTER_LENGTH)-numLogLinesEntries*encrLogLineLength)];
            			in.read(tmpBuff);
                        iv = anonLog.CreateIV(counter);
                        decrData = anonLog.DecryptLogLineKey(decrLogKey, tmpBuff, iv);
                        m_logs.append(" Log line " + counter + " : " + anonLog.bytesToHex(decrData) + "\n");
                        extraEntries=tmpBuff.length/header.getSizeOfLogEntry();//
                        //ANONSCLog.entity_entry_lengths[header.logging_entity];
            		}
            

            // DECRYPT FOOTER, VERIFY NUMBER OF BLOCKS
            byte[] footer = new byte[FOOTER_LENGTH];
            in.read(footer);
            m_logs.append("Verifying footer... ");
            int footerNumLogLines = anonLog.VerifyFooter(decrLogKey, footer, counter);
            m_logs.append("OK\n");
            m_logs.append("Number of log entries from footer: " + footerNumLogLines + "\n");

            if (numLogLinesEntries*header.getNrOfLogEntriesPerLogLine() +extraEntries!= footerNumLogLines) {
                m_logs.append("ERROR: Number of log entries from footer differ from observed logs");
                throw new Exception();
            }
            
            out.write(footer);

            in.close();
            out.close();

            m_logs.append("\nDecrypted logs were succesfully written into file '" + fileNameOut + "'\n");
        }
        catch (Exception ex) {
            m_logs.append("FAIL\n");
        }
    }//GEN-LAST:event_retrieveLogsActionPerformed
/*
    private void createTestLogsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_createTestLogsActionPerformed
        m_logs.append("\n");
        // TEST CREATION OF ENCRYPTED LOG KEY BLOCK
        try {
            // TEST LOG DATE
            byte logDay = (byte) Integer.parseInt(m_testLogsPeriod.getText(0, 2));
            byte logMonth = (byte) Integer.parseInt(m_testLogsPeriod.getText(2, 2));
            short logYear = (short) Integer.parseInt(m_testLogsPeriod.getText(4, 4));

            // OPEN OUTPUT FILE
            String dateString = Integer.toString(logDay) + Integer.toString(logMonth) + Integer.toString(logYear);
            String fileName = "c:\\ANONlog_" + dateString + ".txt";
            FileOutputStream out = new FileOutputStream(fileName);
            m_logs.append("Writing into '" + fileName + "'\n");

            // USE FIXED KEY OR GENERATE NEW ONE

            //
            // LOG HEADER
            //
            DataRetentionLogFileHeader   header = new DataRetentionLogFileHeader();
            header.version = 0;
            header.day = logDay;
            header.month = logMonth;
            header.year = logYear;
            header.logging_entity = 1;
            header.logged_fields = 0;
            header.nr_of_log_entries_per_encrypted_log_line = 2; // = k (below)
            header.nr_of_keys = 1;

            // CREATE ENCRYPTED KEY BLOCK
            if ((m_logKeyBlock = anonLog.EncryptLogKey(testLogKey, logDay, logMonth, logYear, m_publicKey)) != null) {
                (header.keys[0]).encryptedKeyBlock = m_logKeyBlock;
                m_logs.append("Encrypted log key: " + anonLog.bytesToHex(m_logKeyBlock) + "\n");
            }
            else {
                m_logs.append("Fail to encrypt key\n");
                throw new Exception();
            }

            m_logs.append("Writting header\n");
            header.writeToFile(out);

            //
            // LOG BODY
            //

            // INSERT SEVERAL LINES INTO LOG
            byte[] iv = null;
            int counter = 0;
            iv = anonLog.CreateIV(counter);
            byte[] plainData = new byte[header.nr_of_log_entries_per_encrypted_log_line * ANONSCLog.entity_entry_lengths[header.logging_entity]];
            for (int j = 0; j < header.nr_of_log_entries_per_encrypted_log_line; j++) {
                for (int i = 0; i < ANONSCLog.entity_entry_lengths[header.logging_entity]; i++) plainData[i + j * ANONSCLog.entity_entry_lengths[header.logging_entity]] = 0x31;
            }
            byte[] encrData = anonLog.EncryptLogLine(testLogKey, plainData, iv);
            // WRITE TO FILE
            m_logs.append("Writing log line " + counter + " with length " + encrData.length + " bytes\n");
            out.write(encrData);

            counter++;
            iv = anonLog.CreateIV(counter);
            for (int j = 0; j < header.nr_of_log_entries_per_encrypted_log_line; j++) {
                for (int i = 0; i < ANONSCLog.entity_entry_lengths[header.logging_entity]; i++) plainData[i + j * ANONSCLog.entity_entry_lengths[header.logging_entity]] = 0x32;
            }
            encrData = anonLog.EncryptLogLine(testLogKey, plainData, iv);
            // WRITE TO FILE
            m_logs.append("Writing log line " + counter + " with length " + encrData.length + " bytes\n");
            out.write(encrData);

            counter++;
            iv = anonLog.CreateIV(counter);
            for (int j = 0; j < header.nr_of_log_entries_per_encrypted_log_line; j++) {
                for (int i = 0; i < ANONSCLog.entity_entry_lengths[header.logging_entity]; i++) plainData[i + j * ANONSCLog.entity_entry_lengths[header.logging_entity]] = 0x33;
            }
            encrData = anonLog.EncryptLogLine(testLogKey, plainData, iv);
            // WRITE TO FILE
            m_logs.append("Writing log line " + counter + " with length " + encrData.length + " bytes\n");
            out.write(encrData);

            //
            // LOG FOOTER
            //
            byte[] footer = anonLog.CreateFooter(testLogKey, counter);
            out.write(footer);
            m_logs.append("Writing footer with length " + footer.length + " bytes\n");


            out.close();
        }
        catch (Exception ex) {
            m_logs.append("FAIL\n");
        }
    }//GEN-LAST:event_createTestLogsActionPerformed
*/
    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new RetentionDlg().setVisible(true);
            }
    });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton SetCurrentDate;
    private javax.swing.JButton authenticateUser;
    private javax.swing.JButton createTestLogs;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JPasswordField m_adminPIN;
    private javax.swing.JTextField m_currentDate;
    private javax.swing.JTextArea m_logs;
    private javax.swing.JTextField m_logsPeriod;
    private javax.swing.JTextField m_testLogsPeriod;
    private javax.swing.JPasswordField m_userPIN;
    private javax.swing.JButton retrieveLogs;
    // End of variables declaration//GEN-END:variables

}
