Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

3 Страницы<123>
Опции
К последнему сообщению К первому непрочитанному
Offline Максим Коллегин  
#11 Оставлено : 11 декабря 2014 г. 13:34:46(UTC)
Максим Коллегин

Статус: Сотрудник

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,374
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 32 раз
Поблагодарили: 703 раз в 612 постах
Ошибки в логе на клиенте или сервере? Контекст сертификат, используемый для установления ssl-соединения не стоит использовать в других сценариях - MS любит неожиданно закрывать открытый криптопровайдер.
Знания в базе знаний, поддержка в техподдержке
Offline sadgb  
#12 Оставлено : 11 декабря 2014 г. 15:11:46(UTC)
sadgb

Статус: Активный участник

Группы: Участники
Зарегистрирован: 19.11.2010(UTC)
Сообщений: 52
Откуда: Спб

Сказал(а) «Спасибо»: 4 раз
Ошибки на клиенте, на сервере везде тишина.

Вот наиболее стабильная на данный момент версия, но спустя 12 часов тоже выкинула такую ошибку и заглохла.
Тут клиент живет только пока мы его используем. Плюс обратите внимание на IgnoreAllErrors метод в котором ставятся параметры ServicePointManager

Код:
using System;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Runtime.InteropServices;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.Xml.Linq;
using ExceptionsLibrary;
using Log;

namespace CryptoLibrary.CertificateEnrollment
{
    class RaWorker
    {

        // only one service Soap client may exist at a time
        private static readonly object RaWorkerLock = new object();
        public string RaUrl { get; set; }
        public X509Certificate2 ClientCertificate { get; set; }

        public RaWorker(String raUrl, X509Certificate2 clientCertificate)
        {
            RaUrl = raUrl;
            ClientCertificate = clientCertificate;
        }

        // подписывает содержимое base64 строки и возвращает base64 строку
        public String SignString(String str)
        {
            var encode = SignHelper.SignMsg(Convert.FromBase64String(str), ClientCertificate, detached: false);
            return Convert.ToBase64String(encode);
        }

        public String ResignString(String str)
        {
            var buf = SignHelper.VerifyBuffer(Convert.FromBase64String(str)).Content.Content;
            return SignString(Convert.ToBase64String(buf));
        }

        public X509Certificate2 GetCertificateFromCertificateInfo(String certInfoXml)
        {
            var doc = XDocument.Parse(certInfoXml);
            XNamespace rs = "urn:schemas-microsoft-com:rowset";
            XNamespace z = "#RowsetSchema";
            var certBodyBase64 = doc.Descendants(rs + "data").Elements(z + "row").First().Attribute("PKCS").Value;
            return new X509Certificate2(Convert.FromBase64String(certBodyBase64));
        }


        public X509Certificate2 SubmitAcceptConfirmCertRequest(String requestStr)
        {
            lock (RaWorkerLock)
            {
                using (var client = CreateCertRequestClient())
                {
                    try
                    {
                        var requestId = client.SubmitRequest(requestStr,
                            "Автоматический запрос от сервера Аутентификации");
                        client.AcceptRequest(requestId, SignString(requestStr));

                        var certInfoXml = client.GetCertificateInfo(requestId);
                        var certificateUpdate = GetCertificateFromCertificateInfo(certInfoXml);

                        client.ConfirmRequest(requestId);
                        return certificateUpdate;
                    }
                    catch (Exception e)
                    {
                        throw new RaApiCallFailureException(e);
                    }
                }
            }
        }

        public X509Certificate2 SubmitAcceptConfirmFirstCertRequest(String regRequestId, String requestStr)
        {
            lock (RaWorkerLock)
            {
                using (var client = CreateCertRequestClient())
                {

                    try
                    {
                        bool unused = true;
                        string additionalInfo = null;
                        var requestId = client.SubmitFirstCertRequest(regRequestId, requestStr, ref unused,
                            ref additionalInfo);
                        client.AcceptFirstRequest(requestId, SignString(requestStr));

                        var certInfoXml = client.GetCertificateInfo(requestId);
                        var certificateUpdate = GetCertificateFromCertificateInfo(certInfoXml);

                        client.ConfirmRequest(requestId);
                        return certificateUpdate;
                    }
                    catch (Exception e)
                    {
                        throw new RaApiCallFailureException(e);
                    }
                }
            }
        }

        public RaService.CertRequestSoapPortClient CreateCertRequestClient()
        {
            IgnoreAllCertificateErrors();
            try
            {
                // Create the binding.
                var myBinding = new BasicHttpBinding
                {
                    Security =
                    {
                        Mode = BasicHttpSecurityMode.Transport,
                        Transport = { ClientCredentialType = HttpClientCredentialType.Certificate }
                    }
                };


                // Create the endpoint address. Note that the machine name 
                // must match the subject or DNS field of the X.509 certificate
                // used to authenticate the service. 
                var ea = new
                   EndpointAddress(RaUrl);


                var client = new RaService.CertRequestSoapPortClient(myBinding, ea);

                Debug.Assert(client.ClientCredentials != null, "client.ClientCredentials != null");

                client.ClientCredentials.ClientCertificate.Certificate = ClientCertificate;

                return client;
            }
            catch (Exception e)
            {
                throw new RaApiCallFailureException(e);
            }
        }
        private static bool _first = true;
        private static void IgnoreAllCertificateErrors()
        {
            try
            {
                if (!_first)
                    return;
                _first = false;

                LogHelper.Log("Ignore certificate errors");

                //Trust all certificates
                ServicePointManager.ServerCertificateValidationCallback =
                    ((sender, certificate, chain, sslPolicyErrors) => true);

                // trust sender
                ServicePointManager.ServerCertificateValidationCallback
                                = ((sender, cert, chain, errors) => true);

                // validate cert by calling a function
                ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, errors) => true;
                ServicePointManager.Expect100Continue = true;
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
                ServicePointManager.CheckCertificateRevocationList = false;
                ServicePointManager.DefaultConnectionLimit = 1000;
                ServicePointManager.MaxServicePointIdleTime = Int32.MaxValue;
                    

            }
            catch (Exception e)
            {
                LogHelper.Log("error ignoring " + e.Message);
            }
        }


        public X509Certificate2 CreateUserAndGetCertificate(string selfSignedCertRequestBase64)
        {
            lock (RaWorkerLock)
            {
                using (var registrationClient = CreateRegistrationClient())
                {
                    try
                    {
                        var requestId = registrationClient.CreateRequestByAdmin(selfSignedCertRequestBase64, "1", "2",
                            "Автоматическая регистрация пользователя ПЭК");
                        try
                        {
                            registrationClient.AcceptRequest(requestId);
                        }
                        catch (Exception)
                        {
                        }

                        return SubmitAcceptConfirmFirstCertRequest(requestId, selfSignedCertRequestBase64);

                    }
                    catch (Exception e)
                    {
                        throw new RaApiCallFailureException(e);
                    }
                }
            }
        }


        public RaService.RegistrationSoapPortClient CreateRegistrationClient()
        {
            IgnoreAllCertificateErrors();
            try
            {
                // Create the binding.
                var myBinding = new BasicHttpBinding
                {
                    Security =
                    {
                        Mode = BasicHttpSecurityMode.Transport,
                        Transport = { ClientCredentialType = HttpClientCredentialType.Certificate }
                    }
                };


                // Create the endpoint address. Note that the machine name 
                // must match the subject or DNS field of the X.509 certificate
                // used to authenticate the service. 
                var ea = new
                   EndpointAddress(RaUrl);


                var client = new RaService.RegistrationSoapPortClient(myBinding, ea);

                Debug.Assert(client.ClientCredentials != null, "client.ClientCredentials != null");

                client.ClientCredentials.ClientCertificate.Certificate = ClientCertificate;

                return client;
            }
            catch (Exception e)
            {
                throw new RaApiCallFailureException(e);
            }
        }

    }
}

Отредактировано пользователем 11 декабря 2014 г. 15:12:51(UTC)  | Причина: Не указана

Offline sadgb  
#13 Оставлено : 11 декабря 2014 г. 15:13:27(UTC)
sadgb

Статус: Активный участник

Группы: Участники
Зарегистрирован: 19.11.2010(UTC)
Сообщений: 52
Откуда: Спб

Сказал(а) «Спасибо»: 4 раз
Автор: maxdm Перейти к цитате
Ошибки в логе на клиенте или сервере? Контекст сертификат, используемый для установления ssl-соединения не стоит использовать в других сценариях - MS любит неожиданно закрывать открытый криптопровайдер.


поясните про контекст чуть более подробно, мне кажется я не до конца понимаю
Offline Максим Коллегин  
#14 Оставлено : 11 декабря 2014 г. 15:20:38(UTC)
Максим Коллегин

Статус: Сотрудник

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,374
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 32 раз
Поблагодарили: 703 раз в 612 постах
PCERT_CONTEXT - структура Windows для хранения сертификата и связанных объектов.
Потому и спрашиваю, используется ли конекст из свойства ssl-соеднинения, потому что код опущен:
Код:
 public RaWorker(String raUrl, X509Certificate2 clientCertificate)
        {
            RaUrl = raUrl;
            ClientCertificate = clientCertificate;
        }
 
        // подписывает содержимое base64 строки и возвращает base64 строку
        public String SignString(String str)
        {
            var encode = SignHelper.SignMsg(Convert.FromBase64String(str), ClientCertificate, detached: false);
            return Convert.ToBase64String(encode);
        }

И что в SignHelper?
Знания в базе знаний, поддержка в техподдержке
thanks 1 пользователь поблагодарил Максим Коллегин за этот пост.
sadgb оставлено 11.12.2014(UTC)
Offline sadgb  
#15 Оставлено : 11 декабря 2014 г. 16:12:25(UTC)
sadgb

Статус: Активный участник

Группы: Участники
Зарегистрирован: 19.11.2010(UTC)
Сообщений: 52
Откуда: Спб

Сказал(а) «Спасибо»: 4 раз
Автор: maxdm Перейти к цитате
PCERT_CONTEXT - структура Windows для хранения сертификата и связанных объектов.
Потому и спрашиваю, используется ли конекст из свойства ssl-соеднинения, потому что код опущен:
Код:
 public RaWorker(String raUrl, X509Certificate2 clientCertificate)
        {
            RaUrl = raUrl;
            ClientCertificate = clientCertificate;
        }
 
        // подписывает содержимое base64 строки и возвращает base64 строку
        public String SignString(String str)
        {
            var encode = SignHelper.SignMsg(Convert.FromBase64String(str), ClientCertificate, detached: false);
            return Convert.ToBase64String(encode);
        }

И что в SignHelper?


Понял куда вы клоните там действительно сертификат повторно используется еще и для подписи.
Код:
// Определяем подписывающего, объектом CmsSigner.
var cmsSigner = new CmsSigner(signerCert);


А есть идеи почему так печально становится с сервером что его аж перезапускать приходится ?

Потому что хочется быть максимально уверенным в том что именно это причина так как каждый деплой на счету

Отредактировано пользователем 11 декабря 2014 г. 16:13:26(UTC)  | Причина: Не указана

Offline Максим Коллегин  
#16 Оставлено : 11 декабря 2014 г. 17:17:44(UTC)
Максим Коллегин

Статус: Сотрудник

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,374
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 32 раз
Поблагодарили: 703 раз в 612 постах
Это точно странно. Т.е после первой ошибки даже нельзя соединиться с другого клиента (другой машины)?
Знания в базе знаний, поддержка в техподдержке
Offline sadgb  
#17 Оставлено : 11 декабря 2014 г. 18:50:09(UTC)
sadgb

Статус: Активный участник

Группы: Участники
Зарегистрирован: 19.11.2010(UTC)
Сообщений: 52
Откуда: Спб

Сказал(а) «Спасибо»: 4 раз
Автор: maxdm Перейти к цитате
Это точно странно. Т.е после первой ошибки даже нельзя соединиться с другого клиента (другой машины)?


я сервером называю свой сервер Asp.net mvc из которого идут запросы, а не УЦ/ЦР.
С других клиентов к УЦ отправлять можно. С этого нельзя.
Offline Максим Коллегин  
#18 Оставлено : 11 декабря 2014 г. 20:20:11(UTC)
Максим Коллегин

Статус: Сотрудник

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,374
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 32 раз
Поблагодарили: 703 раз в 612 постах
Идеи есть. подпись другим контекстом помогла?
Знания в базе знаний, поддержка в техподдержке
Offline sadgb  
#19 Оставлено : 12 декабря 2014 г. 10:59:35(UTC)
sadgb

Статус: Активный участник

Группы: Участники
Зарегистрирован: 19.11.2010(UTC)
Сообщений: 52
Откуда: Спб

Сказал(а) «Спасибо»: 4 раз
Это к сожалению так сразу не узнать, время между деплоем и результатом от 1 до 10 суток. Будем ждать. А можно все же идеи озвучить ? Ошибка плавающая, вдруг снова столкнемся, хоть будет понятно куда копать. Интересуют любые потенциальные догадки
Offline Максим Коллегин  
#20 Оставлено : 12 декабря 2014 г. 13:03:52(UTC)
Максим Коллегин

Статус: Сотрудник

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,374
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 32 раз
Поблагодарили: 703 раз в 612 постах
Идея - криптопровайдер контекста сертификата schannel закрывается одной из функций подписи из Framework. Для того, чтобы поймать, мне нужен простой воспроизводимый пример или хороший удаленный доступ на проблемную машину (предпочтительнее).
Знания в базе знаний, поддержка в техподдержке
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
3 Страницы<123>
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.