/*
   CopyRight (C) 1998-2005 CyberPlat.Com. All Rights Reserved.
   e-mail: support@cyberplat.com
*/

using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Resources;
using System.Linq;
using System.Web;
using System.Web.Security;

namespace org.CyberPlat
{
    public class IPrivException : System.Exception
    {
        private int _code;
        public IPrivException(int c)
        {
            _code = c;
        }
        public override string ToString()
        {
            switch (_code)
            {
                case -1: return "Argument error";
                case -2: return "memory allocation error";
                case -3: return "Bad document format";
                case -4: return "Partial document read";
                case -5: return "Document internal error";
                case -6: return "Unknown cipher";
                case -7: return "Wrong key length";
                case -8: return "Bad code phrase";
                case -9: return "Wrong document type";
                case -10: return "Base64 encoding error";
                case -11: return "Base64 decoding error";
                case -12: return "Uknown crypto provider";
                case -13: return "Crypto provider not ready";
                case -14: return "Unsupported call";
                case -15: return "File not found";
                case -16: return "File read error";
                case -17: return "Key can not be used";
                case -18: return "Signature format error";
                case -19: return "Can not find public key";
                case -20: return "Wrong signature";
                case -21: return "File creation error";
                case -22: return "File write error";
                case -23: return "Bad key card format";
                case -24: return "Key generation error";
            }
            return "General fault";
        }
        public int code
        {
            get { return _code; }
        }
    };

    public class IPrivKey
    {
        private byte[] pkey;

        public IPrivKey()
        {
            pkey = new byte[36];
        }
        public string signText(string src)
        {
            return IPriv.signText(src, this);
        }
        public string verifyText(string src)
        {
            return IPriv.verifyText(src, this);
        }
        public void closeKey()
        {
            IPriv.closeKey(this);
        }
        public byte[] getKey()
        {
            return pkey;
        }
    };

    public class IPriv
    {
        [DllImport("libipriv.dll")]//correct
        //[DllImport("C:\\inetpub\\vhosts\\egenlearning.com\\egenservices.com\\Bin\\libipriv.dll")]//correct

        internal static extern int Crypt_Initialize();

        [DllImport("libipriv.dll")]//correct
        //[DllImport("C:\\inetpub\\vhosts\\egenlearning.com\\egenservices.com\\Bin\\libipriv.dll")]//correct
                    
 
        internal static extern int Crypt_Done();

        //[DllImport("libipriv.dll")]
        [DllImport("libipriv.dll")]//correct
        //[DllImport("C:\\inetpub\\vhosts\\egenlearning.com\\egenservices.com\\Bin\\libipriv.dll")]//correct

        ////[DllImport("E:\\Egen Work\\work\\websites\\egenservicesNew10May2012\\Bin\\libipriv.dll")]//testing
        internal static extern int Crypt_OpenSecretKeyFromFile(int eng,
            [MarshalAs(UnmanagedType.LPStr)]string path,
            [MarshalAs(UnmanagedType.LPStr)]string passwd,
            [MarshalAs(UnmanagedType.LPArray)]byte[] pkey);

        [DllImport("libipriv.dll")]//correct
        //[DllImport("C:\\inetpub\\vhosts\\egenlearning.com\\egenservices.com\\Bin\\libipriv.dll")]//correct
        //[DllImport("E:\\Egen Work\\work\\websites\\egenservicesNew10May2012\\Bin\\libipriv.dll")]//testing

        internal static extern int Crypt_OpenPublicKeyFromFile(int eng,
            [MarshalAs(UnmanagedType.LPStr)]string path,
            uint keyserial,
            [MarshalAs(UnmanagedType.LPArray)]byte[] pkey,
            [MarshalAs(UnmanagedType.LPArray)]byte[] ñakey);

        [DllImport("libipriv.dll")]//correct
        //[DllImport("C:\\inetpub\\vhosts\\egenlearning.com\\egenservices.com\\Bin\\libipriv.dll")]//correct
        ////[DllImport("E:\\Egen Work\\work\\websites\\egenservicesNew10May2012\\Bin\\libipriv.dll")]//testing

        internal static extern int Crypt_Sign([MarshalAs(UnmanagedType.LPStr)]string src,
            int nsrc, [MarshalAs(UnmanagedType.LPStr)]StringBuilder dst,
             int ndst,
             [MarshalAs(UnmanagedType.LPArray)]byte[] pkey);

        //[DllImport("libipriv.dll")]

        [DllImport("libipriv.dll")]//correct
        //[DllImport("C:\\inetpub\\vhosts\\egenlearning.com\\egenservices.com\\Bin\\libipriv.dll")]//correct
                    

        internal static extern int Crypt_Verify([MarshalAs(UnmanagedType.LPStr)]string src,
            int nsrc, [MarshalAs(UnmanagedType.LPArray)]byte[] pdst,
             [MarshalAs(UnmanagedType.LPArray)]byte[] pndst, [MarshalAs(UnmanagedType.LPArray)]byte[] pkey);

        //[DllImport("libipriv.dll")]
                      
        [DllImport("libipriv.dll")]//correct

        //[DllImport("C:\\inetpub\\vhosts\\egenlearning.com\\egenservices.com\\Bin\\libipriv.dll")]//correct
        
        internal static extern int Crypt_CloseKey([MarshalAs(UnmanagedType.LPArray)]byte[] pkey);


        //public static void Initialize()
        //{
        //    Crypt_Initialize();
        //}
        public static void Done()
        {
            Crypt_Done();
        }
        public static IPrivKey openSecretKey(string path, string passwd)
        {
            IPrivKey k = new IPrivKey();
            int rc = Crypt_OpenSecretKeyFromFile(0, path, passwd, k.getKey());
            if (rc != 0)
                throw (new IPrivException(rc));
            return k;
        }
        public static IPrivKey openPublicKey(string path, uint keyserial)
        {
            IPrivKey k = new IPrivKey();
            int rc = Crypt_OpenPublicKeyFromFile(0, path, keyserial, k.getKey(), null);
            if (rc != 0)
                throw (new IPrivException(rc));
            return k;
        }
        public static string signText(string src, IPrivKey key)
        {
            string dst;
            StringBuilder tmp = new StringBuilder(2048);
            int rc = Crypt_Sign(src, src.Length, tmp, tmp.Capacity, key.getKey());
            if (rc < 0)
                throw (new IPrivException(rc));
            dst = tmp.ToString(0, rc);
            return dst;
        }
        public static string verifyText(string src, IPrivKey key)
        {
            int rc = Crypt_Verify(src, -1, null, null, key.getKey());
            if (rc != 0)
                throw (new IPrivException(rc));
            return "";
        }
        public static void closeKey(IPrivKey key)
        {
            Crypt_CloseKey(key.getKey());
        }
    };

}
