using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Kz.GammaTech.Cms;
using Kz.GammaTech.CPWrapper;
using Kz.GammaTech.Crypto;
using Kz.GammaTech.X509;
using System.Security.Cryptography.X509Certificates;
using Kz.GammaTech.Asn1.Cms;
using Kz.GammaTech.Asn1;

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

           // attach pkcs7 без атрибутов
            GostCMS cms = new GostCMS();
          
            cms.input = System.Text.Encoding.ASCII.GetBytes("12345678");
            X509Store store = new X509Store("MY");
            // выбираем сертификат для подписи (если на профайле нет пароля)
            X509Certificate2 cert = null;
            try
            {
                store.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection certCollection = store.Certificates;
                X509Certificate2Collection signingCert = certCollection.Find(X509FindType.FindBySubjectName, "E_BABAK", false);
                cert = signingCert[0];
            }
            finally
            {
                store.Close();
            }
            //TumarProfile profile = new TumarProfile("profile://12345","123"); // если профайл запаролен, то ключ для подписи необходимо указать так
            TumarProfile profile = new TumarProfile(cert);
            Kz.GammaTech.X509.X509Certificate cert_ver = null;
            for (int i = 0; i < profile.key_count; i++)
            {
                if (profile.keys[i].keySpec == CpTumar.AT_SIGNATURE)
                {
                    cms.privateKey = profile.keys[i].Private;
                    cms.certificate = new X509CertificateParser().ReadCertificate(profile.keys[i].user_certificate);
                    cert_ver = new X509CertificateParser().ReadCertificate(profile.keys[i].user_certificate);
                    break;
                }
            }          
            cms.GenerateCMS();
            byte[] pkcs7 = cms.output;

            FileStream f = new FileStream("pkcs7_attach_without_attr.bin", FileMode.Create);
            f.Write(pkcs7, 0, pkcs7.Length);
            f.Close();
            // проверяем pkcs7, указав сертификат для проверки
            GostCMS cms_ver = new GostCMS();
            cms_ver.input = pkcs7;
            cms_ver.certificate = cert_ver;
            if (cms_ver.VerifyCMS())
            {
                Console.WriteLine("Verify pkcs7 attach without attr OK");
            }
            else
            {
                Console.WriteLine("Verify pkcs7 attach without attr fail");
            }

            // добавляем атрибуты

            Asn1EncodableVector unsignedAttributesVector = new Asn1EncodableVector();
            // метка времени
            unsignedAttributesVector.Add(new Kz.GammaTech.Asn1.Cms.Attribute(CmsAttributes.SigningTime, new DerSet(new DerUtcTime(DateTime.Now))));
            AttributeTable unsignedAttributes = new AttributeTable(unsignedAttributesVector);            
            cms_ver.ReplaceUnsignedAttribute(unsignedAttributes);

            FileStream f2 = new FileStream("pkcs7_attach_with_unsign_attr.bin", FileMode.Create);
            f2.Write(cms_ver.output, 0, cms_ver.output.Length);
            f2.Close();

            // проверяем pkcs7 attach с добавленными неподписываемыми атрибутами

            cms_ver.certificate = cert_ver;
            if (cms_ver.VerifyCMS())
            {
                Console.WriteLine("Verify pkcs7 attach with attr OK");
            }
            else
            {
                Console.WriteLine("Verify pkcs7 attach with attr fail");
            }


            // формируем pkcs7 detach без атрибутов
            GostCMSDetached cms_detach = new GostCMSDetached();
            cms_detach.input = System.Text.Encoding.ASCII.GetBytes("12345678");
            store = new X509Store("MY");
            // выбираем сертификат для подписи (если на профайле нет пароля)
            cert = null;
            try
            {
                store.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection certCollection = store.Certificates;
                X509Certificate2Collection signingCert = certCollection.Find(X509FindType.FindBySubjectName, "E_BABAK", false);
                cert = signingCert[0];
            }
            finally
            {
                store.Close();
            }
            //TumarProfile profile = new TumarProfile("profile://12345","123"); // если профайл запаролен, то ключ для подписи необходимо указать так
            profile = new TumarProfile(cert);
            cert_ver = null;
            for (int i = 0; i < profile.key_count; i++)
            {
                if (profile.keys[i].keySpec == CpTumar.AT_SIGNATURE)
                {
                    cms_detach.privateKey = profile.keys[i].Private;
                    cms_detach.SignerCertificate = new X509CertificateParser().ReadCertificate(profile.keys[i].user_certificate);
                    cert_ver = new X509CertificateParser().ReadCertificate(profile.keys[i].user_certificate);
                    break;
                }
            }

           cms_detach.GenerateCMS();

            f = new FileStream("pkcs7_detach_without_attr.bin", FileMode.Create);
            f.Write(cms_detach.output, 0, cms_detach.output.Length);
            f.Close();

            GostCMSDetached cms_detach_ver = new GostCMSDetached();
            cms_detach_ver.SignerCertificate = cert_ver;
            cms_detach_ver.input = cms_detach.output;
            cms_detach_ver.content = System.Text.Encoding.ASCII.GetBytes("12345678");
            if (cms_detach_ver.VerifyCMS())
            {
                Console.WriteLine("Verify pkcs7 detach without attr OK");
            }
            else
            {
                Console.WriteLine("Verify pkcs7 detach without attr fail");
            }

            // добавляем атрибуты
            Asn1EncodableVector unsignedAttributesVector2 = new Asn1EncodableVector();
            // метка времени
            unsignedAttributesVector2.Add(new Kz.GammaTech.Asn1.Cms.Attribute(CmsAttributes.SigningTime, new DerSet(new DerUtcTime(DateTime.Now))));
            AttributeTable unsignedAttributes2 = new AttributeTable(unsignedAttributesVector2);
            cms_detach_ver.ReplaceUnsignedAttribute(unsignedAttributes2);

            f = new FileStream("pkcs7_detach_with_attr.bin", FileMode.Create);
            f.Write(cms_detach_ver.output, 0, cms_detach_ver.output.Length);
            f.Close();
            // проверяем detach pkcs7 с добавленными неподписываемыми атрибутами
            GostCMSDetached cms_detach_attr_ver = new GostCMSDetached();
            cms_detach_attr_ver.input = cms_detach_ver.output;
            cms_detach_attr_ver.SignerCertificate = cert_ver;
            cms_detach_attr_ver.content = System.Text.Encoding.ASCII.GetBytes("12345678");

            if (cms_detach_attr_ver.VerifyCMS())
            {
                Console.WriteLine("Verify pkcs7 detach with attr OK");
            }
            else
            {
                Console.WriteLine("Verify pkcs7 detach with attr fail");
            }

            Console.ReadKey();

        }
    }
}
