using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using Kz.GammaTech.X509;
using Kz.GammaTech.Utilities.Encoders;
using Kz.GammaTech.Asn1.X509;
using System.IO;
using Kz.GammaTech.Crypto;
using Kz.GammaTech.Pkcs;
using Kz.GammaTech.Math;
using System.DirectoryServices.Protocols;
//  Пример использования класса X509Crl и получения CRL по ldap


namespace ExampleCRL
{
    class Program
    {
        static void Main(string[] args)
        {

            byte[] cert11 = Base64.Decode("MIICYTCCAgqgAwIBAgIgFAxsAx70WlYXzJJJ2qCYho/tE7bzDNDOHb6Vd1FGxVQw"
                                        + "DgYKKwYBBAG1EQECAgUAMFgxCzAJBgNVBAYTAktaMQ8wDQYDVQQIEwZBTE1BVFkx"
                                        + "DjAMBgNVBAoTBUdBTU1BMQ0wCwYDVQQLEwRURVNUMRkwFwYDVQQDDBDQmtCe0KDQ"
                                        + "ndCV0JLQntCZMCIYDzIwMDgwMjI4MTEwMjQ4WhgPMjAxMzAyMjgxMTAyNDhaMC0x"
                                        + "DjAMBgNVBAMTBUtvbHlhMQ4wDAYDVQQKEwVHQU1NQTELMAkGA1UEBhMCS1owYzAO"
                                        + "BgorBgEEAbURAQICBQADUQAGAgAAOqoAAABFQzEAAgAApSRb0FHBh0v0FVJUPQaN"
                                        + "WriI+dhr0TvGAxfY2QqWLDEkEpX7MZzJm1+G0Tt4vsrVr7QtQdTR6BpWHnT+7j2H"
                                        + "kaOBvjCBuzBVBgNVHSMETjBMgCB+3q+PryXXE6FCBDKuC3jwhkIGoOUtbH5Hh+pW"
                                        + "mM9jG6EGhwR/AAABgiB+3q+PryXXE6FCBDKuC3jwhkIGoOUtbH5Hh+pWmM9jGzAp"
                                        + "BgNVHQ4EIgQgFAxsAx70WlYXzJJJ2qCYho/tE7bzDNDOHb6Vd1FGxVQwDgYDVR0P"
                                        + "AQH/BAQDAgEGMAwGA1UdEwQFMAMCAQAwGQYDVR0fBBIwEDAOoAigBocEfwAAAYEC"
                                        + "AWYwDgYKKwYBBAG1EQECAgUAA0EA/8+ze6MMyC9HyTXeBIAAriCFGyoFv9Dm/4kJ"
                                        + "Rm6ymb1fQW9eM5FP6s5lL9aI18HJP+YjpITWf/TnQolWd+0KtQ==");

          byte[] cert12 = Base64.Decode("MIIDCTCCArKgAwIBAgIg9cQ9aKqVgQzJ+SAxZDIfh7mrz6X/blKg7difgQI/wtww"
                                        + "DgYKKwYBBAG1EQECAgUAMC0xCzAJBgNVBAMTAkNBMREwDwYDVQQKEwhERUNFTUJF"
                                        + "UjELMAkGA1UEBhMCS1owIhgPMjAwOTAxMDgxMTI1MzBaGA8yMDEwMDEwODExMjUz"
                                        + "MFowKjEMMAoGA1UEAxMDMTI4MQ0wCwYDVQQKEwRMRU5BMQswCQYDVQQGEwJLWjBj"
                                        + "MA4GCisGAQQBtREBBQgFAANRAAYCAAA6qgAAAEVDMQACAABZYQwWwBPerAqztrms"
                                        + "XKnpkCF6NXhPJgzqvZOo+isHcuOvIkUOvsi1VdhIENUm2yAgT7l6Z5ZBTku92JwV"
                                        + "+Ov5o4IBkzCCAY8wCwYDVR0PBAQDAgbAMBMGA1UdJQQMMAoGCCsGAQUFBwMEMEEG"
                                        + "CCsGAQUFBwEBBDUwMzAxBggrBgEFBQcwAYYlaHR0cDovLzE5Mi4xNjguNy40Mzo2"
                                        + "MjI4MC9jZ2kvc3RhdHVzADApBgNVHQ4EIgQg9cQ9aKqVgQzJ+SAxZDIfh7mrz6X/"
                                        + "blKg7difgQI/wtwwgYAGA1UdIwR5MHeAIC/wr3HUOhoNvruGyzL2+Xc4KX8mhA/X"
                                        + "Zg7M3qxCLJqnoTGkLzAtMQswCQYDVQQDEwJDQTERMA8GA1UEChMIREVDRU1CRVIx"
                                        + "CzAJBgNVBAYTAktagiAv8K9x1DoaDb67hssy9vl3OCl/JoQP12YOzN6sQiyapzB6"
                                        + "BgNVHSAEczBxMG8GCisGAQQBtRELAQUwYTAfBggrBgEFBQcCARYTaHR0cDovL3d3"
                                        + "dy5nYW1tYS5rejA+BggrBgEFBQcCAjAyMBIWC1Rlc3QgUG9saWN5MAMCAQEaHENl"
                                        + "cnRpZmljYXRlIFBvbGljZXMgU3RhdG1lbnQwDgYKKwYBBAG1EQECAgUAA0EAQPjC"
                                        + "a20Hh2+q7aMceuoW2spEJA9kURP568MWTNliejAGRwcOOgYfnpCj9yU5dZhtMU8c"
                                        + "x22Kozxii4w95RUBXw==");

            

         // формирование CRL
           X509Certificate cert = new X509CertificateParser().ReadCertificate(cert11);          
            X509Certificate cert2 = new X509CertificateParser().ReadCertificate(cert12);
            
            X509V2CrlGenerator generator = new X509V2CrlGenerator();
            
            // ключи для подписи CRL, хранятся в PKCS12
            FileInfo f = new FileInfo(@"1.p12");
            FileStream file = f.OpenRead();
            byte[] fpkcs12 = new byte[file.Length];
            file.Read(fpkcs12, 0, (int)file.Length);
            file.Close();                              
            string pwd = "123456789"; // пароль  для PKCS12
            char[] pass = pwd.ToCharArray();
            MemoryStream stream = new MemoryStream(fpkcs12, false);
        // создание "хранилища" PKCS12 
            Pkcs12Store store = new Pkcs12Store(stream, pass);
            string pName = null;
        // поиск ключей 
            foreach (string n in store.Aliases)
            {
                if (store.IsKeyEntry(n))
                {
                    pName = n;
                }

            }
        // получение ключа 
            AsymmetricKeyEntry key = store.GetKey(pName);
            AsymmetricKeyParameter privKey = key.Key; // закрытый ключ
            X509CertificateEntry[] ch = store.GetCertificateChain(pName);
            X509Certificate cert_root = ch[0].Certificate; // сертификаты           
            // добавляем отозваный сертификат в CRL 
            generator.AddCrlEntry(cert.SerialNumber, DateTime.Now, 2);
            // добавляем еще один
            generator.AddCrlEntry(cert2.SerialNumber, DateTime.Now, 3);
            // устанавливаем имя издателя CRL
            generator.SetIssuerDN(cert_root.IssuerDN);
            // устанавливаем алгоритм 
            generator.SetSignatureAlgorithm("1.3.6.1.4.1.6801.1.5.8");
            //устанавливаем дату выпуска
            generator.SetThisUpdate(DateTime.Now);
            
            // подписываем CRL
            X509Crl crl = generator.Generate(privKey);

            // проверка подписи CRL
            crl.Verify(cert_root.GetPublicKey());
            
            // получаем его в виде массива байт
            byte[] crl_b = crl.GetEncoded();
            // сохраняем в файл
            FileInfo f1 = new FileInfo(@"c:\crl.crl");
            FileStream file1 = f1.Create();
            file1.Write(crl_b, 0, crl_b.Length);
            file1.Close();

            // открываем файл с CRL
            FileInfo f2 = new FileInfo("c:\\crl.crl");
            FileStream file2 = f2.OpenRead();
            byte[] crl_b2 = new byte[file2.Length];
            int r = file2.Read(crl_b2,0,(int)file2.Length);
            file2.Close();
            
            // созданем объект X509Crl                                          
            X509Crl crl2 = new X509CrlParser().ReadCrl(crl_b2);
            // просматриваем содержание CRL
			foreach (X509CrlEntry crlEntry in crl2.GetRevokedCertificates())
			{                
                if (crlEntry.SerialNumber.ToString() == cert.SerialNumber.ToString())
                {                    
                    Console.WriteLine("Certificate with serial number " + cert.SerialNumber.ToString(16) + "is revoked");
                }                
			}
           



            // получение CRL по LDAP
            LdapDirectoryIdentifier dir_id = new LdapDirectoryIdentifier("127.0.0.1", 62222); // указать адрес хранилища
            
            System.Net.NetworkCredential cred = new System.Net.NetworkCredential();
            cred.UserName = "t=R";            // таким образом указывается, что необходимо получить CRL
            LdapConnection ldap_connect = new LdapConnection(dir_id);
            ldap_connect.Credential = cred;
            ldap_connect.AuthType = AuthType.Basic;            
            ldap_connect.Bind();
            SearchRequest req = new SearchRequest();
            req.DistinguishedName = "C=KZ;O=GAMMA;CN=ROOT;";// указать имя УЦ
               
           
            SearchResponse ldap_resp2 = (SearchResponse)ldap_connect.SendRequest(req);


            // разбираем ответ
            foreach (SearchResultEntry d in ldap_resp2.Entries)
            {
              
                foreach (System.Collections.DictionaryEntry k in d.Attributes)
                {
                    string k1 = (string)k.Key;
                    if ((k1 == "certificaterevocationlist") || (k1 == "certificateRevocationList"))
                    {
                        System.DirectoryServices.Protocols.DirectoryAttribute attr = (System.DirectoryServices.Protocols.DirectoryAttribute)k.Value;


                        int c = attr.Count;
                        System.Collections.IEnumerator en;
                        en = attr.GetEnumerator();

                        en.Reset();

                        for (int i22 = 0; i22 < c; i22++)
                        {
                            int p = 0;
                            while (en.MoveNext() == true)
                            {
                                p++;
                                byte[] g = (byte[])en.Current;
                                X509Crl crl_new = new X509CrlParser().ReadCrl(g); // создаем объект X509CRL. В дальнейшем его можно просмотреть так как приведено выше
                            }
                        }
                    }
                }
            }

           
           
                                                                  
        }
    }
}
