/*
 *  © Darren McDonald 2010
 *
 *  This file is part of athena-ssl-cipher-check.
 *
 *  athena-ssl-cipher-check is free software: you can redistribute it
 *  and/or modify it under the terms of the GNU General Public License as
 *  published by the Free Software Foundation, either version 3 of the License,
 *  or (at your option) any later version.
 *
 *  athena-ssl-cipher-check is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with athena-ssl-cipher-check. If not, see
 *  <http://www.gnu.org/licenses/>.
 *
 */

package athenasslciphercheck;

import java.io.*;
import java.util.*;

public class CipherListWrapper {
    private ArrayList<Cipher> cipherDescList;

    public CipherListWrapper()
    {
        cipherDescList = new ArrayList<Cipher>();
    }

    public Cipher lookUpCipher( byte[] tmp )
    {
        Cipher rtn;
        for( int i = 0; i < cipherDescList.size(); i++ )
        {
            if( cipherDescList.get(i).getId()[0] == tmp[0] &&
                cipherDescList.get(i).getId()[1] == tmp[1] )
                return cipherDescList.get(i);
        }
        return null;
    }

    public void loadCiphers()
    {
        //ffs, There has got be a better way of doing this...
        String path = "";
        if( System.getProperty("java.class.path").contains( System.getProperty("file.separator") ) )
                path += System.getProperty("java.class.path").substring(0, 1+System.getProperty("java.class.path").lastIndexOf(System.getProperty("file.separator")));
        //</ffs>
        try {
            BufferedReader fileIn = new BufferedReader(new FileReader(path+"tlsciphers.txt"));
            String line;

            int count = 0; //line number counter
            while( (line = fileIn.readLine()) != null )
            {
                count++; //inc line number
                if( line.charAt(0) == '#' ) //if comment, ignore
                    continue;

                if( line.split(" ").length != 4 )
                {
                    System.out.println("Error in configuration file on line "+count+", 4 words expected.");
                    continue;
                }

                String cipherCode = line.split(" ")[0];
                if( cipherCode.length() != 4 ||
                    !this.isHexidec( cipherCode ) )
                {
                    System.out.println("Error in configuration file on line "+count
                                       +", codes must in the form of a four digit hexidecimal number");
                    continue;
                }

                Cipher tmpCipher = new Cipher(  line.split(" ")[1],
                                                hexStringToByte( cipherCode ),
                                                Integer.parseInt( line.split(" ")[2] ),
                                                Integer.parseInt( line.split(" ")[3] ) );
                cipherDescList.add(tmpCipher);
            }

            fileIn.close();
        }
        catch ( Exception ex) {
            System.out.println( ex.getMessage() );
            System.out.println("configuration file '"+path+"tlsciphers.txt' not found");
        }


    }

    public boolean isHexidec( String s )
    {
        for( int i = 0; i < s.length(); i ++ )
        {
            char c = s.charAt(i);
            if( (c >= '0' && c <= '9') )
                continue;
            if( (c >= 'a' && c <= 'f') )
                continue;
            if( (c >= 'A' && c <= 'F') )
                continue;

            return false;
        }
        return true;
    }

    /*
     * Number of hexidecimal digits %2 must equal 0
     * i.e. an even number of characters
     */
    public byte[] hexStringToByte( String s )
    {
        byte[] array = new byte[s.length()/2];

        for( int i = 0; i < s.length(); i += 2 )
        {
            int tmp = 0;
            tmp = (hexValue( s.charAt(i) )*16) + hexValue( s.charAt(i+1) );
            array[i/2] = (byte) tmp;
        }

        return array;
    }

    public int hexValue(char c)
    {
        switch( c )
        {
            case '0':
                return 0;
            case '1':
                return 1;
            case '2':
                return 2;
            case '3':
                return 3;
            case '4':
                return 4;
            case '5':
                return 5;
            case '6':
                return 6;
            case '7':
                return 7;
            case '8':
                return 8;
            case '9':
                return 9;

            case 'A':
            case 'a':
                return 10;

            case 'B':
            case 'b':
                return 11;

            case 'C':
            case 'c':
                return 12;

            case 'D':
            case 'd':
                return 13;

            case 'E':
            case 'e':
                return 14;

            case 'F':
            case 'f':
                return 15;

            default:
                return -1;
        }
    }

}
