Пример #1
0
        /// <summary>
        /// Метод нахождения префикса
        /// </summary>
        /// <param name="element"></param>
        /// <param name="isTypeBasic"></param>
        /// <returns></returns>
        private string FindPrefix(XmlElement element, bool isTypeBasic)
        {
            try
            {
                log.LogDebug("Пытаемся получить значение префикса.");

                string prefix = SoapDSigUtil.FindPrefix(element, NamespaceUri.Smev3Types);
                if (!isTypeBasic)
                {
                    prefix = (string.Compare(prefix, "xmlns", StringComparison.InvariantCultureIgnoreCase) == 0) ? string.Empty : prefix;
                }
                else
                {
                    prefix = (string.IsNullOrEmpty(prefix) || string.Compare(prefix, "xmlns", true) == 0) ? "typesBasic" : prefix;
                }

                log.LogDebug($"Значение префикса успешно получено: {prefix}.");

                return(prefix);
            }
            catch (Exception ex)
            {
                throw new Exception($"Ошибка при попытке получить значение префикса. {ex.Message}.");
            }
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="document"></param>
        /// <param name="idValue"></param>
        /// <returns></returns>
        public override XmlElement GetIdElement(XmlDocument document, string idValue)
        {
            XmlNamespaceManager nsmgr   = new XmlNamespaceManager(document.NameTable);
            XmlElement          element = null;

            if (string.IsNullOrEmpty(idValue) == false)
            {
                string prefix = SoapDSigUtil.FindPrefix(document.DocumentElement, this.NamespaceForReference);

                if (string.IsNullOrEmpty(prefix))
                {
                    prefix = "wsu";
                }

                nsmgr.AddNamespace(prefix, this.NamespaceForReference);

                string findString = string.Format("//*[(@Id='{0}' and namespace-uri()='{1}') or (@{2}:Id='{0}')]", idValue, this.NamespaceForReference, prefix);
                element = document.SelectSingleNode(findString, nsmgr) as XmlElement;
            }
            else if (document.DocumentElement != null)
            {
                element = document.DocumentElement;
            }

            return(element);
        }
Пример #3
0
        /// <summary>
        /// Метод подписи XML подписью органа власти
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="certificate"></param>
        /// <returns></returns>
        private XmlDocument SignMessage2XX(XmlDocument xml, IntPtr certificate)
        {
            try
            {
                // Удаляем тэг Actor
                string message = string.Empty;

                try
                {
                    log.LogDebug("Пытаемся удалить атрибут 'Actor'.");
                    message = SoapDSigUtil.RemoveActor(xml);
                    log.LogDebug("Атрибут 'Actor' успешно удален.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке удалить атрибут 'Actor'. {ex.Message}.");
                }

                XmlDocument doc = new XmlDocument()
                {
                    PreserveWhitespace = true
                };

                try
                {
                    doc.LoadXml(message);
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при формировании XML после удаления атрибута 'Actor'. {ex.Message}.");
                }

                try
                {
                    log.LogDebug("Получаем значение тэга для подписи.");
                    this.tagForSign = this.FindSmevTagForSign(doc);
                    log.LogDebug($"Значение тэга для подписи получено. {tagForSign}.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке получить тэг с элементом для подписи. {ex.Message}.");
                }

                SmevSignedXml signedXml = new SmevSignedXml(doc);

                try
                {
                    log.LogDebug($"Выполняем добавление элемента Reference в XML.");

                    signedXml = (SmevSignedXml)SmevXmlHelper.AddReference(doc, signedXml, certificate,
                                                                          SignWithId,
                                                                          mrVersion,
                                                                          ElemForSign,
                                                                          ref idCounter,
                                                                          tagForSign,
                                                                          tagForSignNamespaceUri,
                                                                          namespaceIdAttr: NamespaceUri.OasisWSSecurityUtility
                                                                          );

                    log.LogDebug($"Добавление элемента Reference в XML выполнено успешно.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке добавить элемент Reference. {ex.Message}.");
                }

                signedXml.NamespaceForReference             = NamespaceUri.OasisWSSecurityUtility;
                signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;

                try
                {
                    log.LogDebug($"Пытаемся получить значение SignatureMethod.");
                    signedXml.SignedInfo.SignatureMethod = SignServiceUtils.GetSignatureMethod(SignServiceUtils.GetAlgId(certificate));
                    log.LogDebug($"Значение SignatureMethod успешно получено: {signedXml.SignedInfo.SignatureMethod}.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке получить значение метода подписи. {ex.Message}.");
                }

                XmlElement keyInfoElem        = doc.CreateElement("KeyInfo", NamespaceUri.WSXmlDSig);
                XmlElement binaryTokenElem    = doc.CreateElement("wsse", "BinarySecurityToken", NamespaceUri.OasisWSSecuritySecext);
                XmlElement tokenReferenceElem = doc.CreateElement("wsse", "SecurityTokenReference", NamespaceUri.OasisWSSecuritySecext);

                XmlElement referenceElem = doc.CreateElement("wsse", "Reference", NamespaceUri.OasisWSSecuritySecext);

                string       certId                = "uuid-" + Guid.NewGuid().ToString();
                XmlAttribute idAttr                = doc.CreateAttribute("u", "Id", NamespaceUri.OasisWSSecurityUtility);
                XmlAttribute valueTypeTokenAttr    = doc.CreateAttribute("ValueType");
                XmlAttribute encodingTypeTokenAttr = doc.CreateAttribute("EncodingType");

                idAttr.Value                = certId;
                valueTypeTokenAttr.Value    = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";
                encodingTypeTokenAttr.Value = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary";

                binaryTokenElem.Attributes.Append((XmlAttribute)doc.ImportNode(idAttr, true));
                binaryTokenElem.Attributes.Append((XmlAttribute)doc.ImportNode(valueTypeTokenAttr, true));
                binaryTokenElem.Attributes.Append((XmlAttribute)doc.ImportNode(encodingTypeTokenAttr, true));

                X509Certificate2 cert = SignServiceUtils.GetX509Certificate2(certificate);
                binaryTokenElem.InnerText = Convert.ToBase64String(cert.RawData);

                XmlAttribute valueTypeAttr = doc.CreateAttribute("ValueType");
                valueTypeAttr.Value = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";
                referenceElem.Attributes.Append((XmlAttribute)doc.ImportNode(valueTypeAttr, true));

                XmlAttribute uriAttr = doc.CreateAttribute("URI");
                uriAttr.Value = "#" + certId;

                referenceElem.Attributes.Append((XmlAttribute)doc.ImportNode(uriAttr, true));
                tokenReferenceElem.PrependChild(doc.ImportNode(referenceElem, true));
                keyInfoElem.PrependChild(doc.ImportNode(tokenReferenceElem, true));

                try
                {
                    KeyInfoNode keyNode = new KeyInfoNode(tokenReferenceElem);
                    KeyInfo     keyInfo = new KeyInfo();
                    keyInfo.AddClause(keyNode);
                    signedXml.KeyInfo = keyInfo;
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при формировании элемента KeyInfo. {ex.Message}.");
                }

                try
                {
                    log.LogDebug($"Пытаемся вычислить подпись.");
                    signedXml.ComputeSignatureWithoutPrivateKey(xmldsigPrefix, certificate);
                    log.LogDebug($"Вычисление подписи выполнено успешно.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке вычислить подпись для XML. {ex.Message}.");
                }

                XmlElement signatureElem = null;

                try
                {
                    log.LogDebug("Пытаемся получить элемент с подписью.");
                    signatureElem = signedXml.GetXml(xmldsigPrefix);
                    log.LogDebug("Элемент с подписью успешно получен.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке получить элемент содержащий подпись. {ex.Message}.");
                }

                try
                {
                    log.LogDebug("Пытаемся добавить подпись в XML содержимое.");
                    FillSignatureElement(doc, signatureElem, certificate, binaryTokenElem);
                    log.LogDebug("Подпись успешно добавлена.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке заполнить XML информацией о подписи. {ex.Message}.");
                }

                try
                {
                    log.LogDebug("Пытаемся добавить атрибут 'Actor'.");
                    SoapDSigUtil.AddActor(doc);
                    log.LogDebug("Атрибут 'Actor' успешно добавлен.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке добавить атрибут 'Actor'. {ex.Message}.");
                }

                return(doc);
            }
            catch (Exception ex)
            {
                log.LogError($"Ошибка при попытке подписать XML. {ex.Message}.");
                throw new CryptographicException($"Ошибка при попытке подписать XML для версии {mrText[mrVersion]}. {ex.Message}.");
            }
            finally
            {
                SignServiceUtils.FreeHandleCertificate(certificate);
            }
        }