Example #1
0
 /// <summary>
 /// Метод подписи данных
 /// </summary>
 /// <param name="data"></param>
 /// <param name="thumbprint"></param>
 /// <returns></returns>
 public byte[] Sign(byte[] data, string thumbprint)
 {
     if (SignServiceUtils.IsUnix)
     {
         var unixService = new SignServiceUnix(loggerFactory);
         return(unixService.Sign(data, thumbprint));
     }
     else
     {
         var winService = new SignServiceWin(loggerFactory);
         return(winService.Sign(data, thumbprint));
     }
 }
Example #2
0
        /// <summary>
        /// Метод подписания вложений подписью органа власти
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="certificate"></param>
        /// <returns></returns>
        private XmlDocument SignAttachmentsOv(XmlDocument doc, IntPtr certificate)
        {
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);

            string prefix = FindPrefix(doc.DocumentElement, true);

            nsmgr.AddNamespace(prefix, NamespaceUri.Smev3TypesBasic);

            log.LogDebug($"Пытаемся найти тэг заголовка вложений.");
            string     findHeaderString     = string.Format("//{0}:AttachmentHeaderList", prefix);
            XmlElement attachmentHeaderList = doc.SelectSingleNode(findHeaderString, nsmgr) as XmlElement;

            log.LogDebug($"Пытаемся найти тэг с контентом вложений.");
            string     findContentString     = string.Format("//{0}:AttachmentContentList", prefix);
            XmlElement attachmentContentList = doc.SelectSingleNode(findContentString, nsmgr) as XmlElement;

            if (attachmentHeaderList != null && attachmentContentList != null)
            {
                log.LogDebug("Список заголовков и контента с вложениями был успешно получен.");

                bool changed = false;
                AttachmentHeaderList headerList = null;

                try
                {
                    log.LogDebug("Пытаемся получить объект AttachmentHeaderList.");
                    headerList = DeserializeXml <AttachmentHeaderList>(attachmentHeaderList, NamespaceUri.Smev3TypesBasic);
                    log.LogDebug("Объект AttachmentHeaderList успешно получен.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при получении объекта AttachmentHeaderList. {ex.Message}.");
                }

                // Если нет информации о вложениях
                if (headerList == null || headerList.AttachmentHeader == null || headerList.AttachmentHeader.Length <= 0)
                {
                    log.LogDebug("Вложения для подписи не найдены.");
                    return(doc);
                }

                // Проверим есть ли вложения для которых необходима подпись
                log.LogDebug("Проверим есть ли вложения для которых необходима подпись.");

                var needSigned = false;
                foreach (var header in headerList.AttachmentHeader)
                {
                    if (header.SignaturePKCS7 == null || header.SignaturePKCS7.Length <= 0)
                    {
                        log.LogDebug($"Вложение {header.contentId} нуждается в подписи.");
                        needSigned = true;
                        break;
                    }
                }

                // Если все вложения уже подписаны, выходим
                if (!needSigned)
                {
                    log.LogDebug("Все вложения являются подписанными.");
                    return(doc);
                }

                // Пытаемся получить список контента вложений. Обрабатывает только вложения указанные в XML в виде base64 строки, для случаев с
                // расположением вложения на FTP или в случае если данный XML является частью МТОМ запроса предполагается что вложения были подписаны отдельно, заранее
                AttachmentContentList contentList = null;

                try
                {
                    contentList = DeserializeXml <AttachmentContentList>(attachmentContentList, NamespaceUri.Smev3TypesBasic);
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при десериализации контента вложений. " +
                                        $"Убедитесь, что для вложений, которые находятся на FTP, или будут расположены в МТОМ запросе подпись была получена отдельно. " +
                                        $"Содержимое ошибки {ex.Message}.");
                }

                if (contentList != null && contentList.AttachmentContent != null && contentList.AttachmentContent.Length > 0)
                {
                    foreach (AttachmentHeaderType header in headerList.AttachmentHeader)
                    {
                        if (header.SignaturePKCS7 == null || header.SignaturePKCS7.Length == 0)
                        {
                            log.LogDebug($"В заголовке вложения отсутствует подпись. Пытаемся подписать.");
                            AttachmentContentType content = contentList.AttachmentContent.FirstOrDefault(cnt => cnt.Id == header.contentId);

                            if (content != null && content.Content != null && content.Content.Length > 0)
                            {
                                byte[] signature = null;

                                try
                                {
                                    if (SignServiceUtils.IsUnix)
                                    {
                                        log.LogDebug($"Выполняем подпись под Unix платформой.");
                                        signature = SignServiceUnix.Sign(content.Content, certificate);
                                    }
                                    else
                                    {
                                        log.LogDebug($"Выполняем подпись под Windows платформой.");
                                        signature = SignServiceWin.Sign(content.Content, certificate);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    throw new Exception($"Ошибка при вычислении подписи для вложения. {ex.Message}.");
                                }

                                header.SignaturePKCS7 = signature;
                                changed = true;
                            }
                        }
                    }

                    if (changed)
                    {
                        string prefixForSerialize = FindPrefix(doc.DocumentElement, false);

                        try
                        {
                            log.LogDebug($"Пытаемся обновить список вложений.");

                            XmlElement attachmentHeaderListNew = this.SerializeToXmlElement(headerList, NamespaceUri.Smev3TypesBasic, prefixForSerialize);
                            attachmentHeaderListNew = doc.ImportNode(attachmentHeaderListNew, true) as XmlElement;
                            attachmentHeaderList.ParentNode.ReplaceChild(attachmentHeaderListNew, attachmentHeaderList);

                            log.LogDebug("Список вложений успешно обновлен.");
                        }
                        catch (Exception ex)
                        {
                            throw new Exception($"Ошибка при попытке обновить подписанные вложения. {ex.Message}.");
                        }
                    }
                }
            }

            return(doc);
        }