Example #1
0
        /// <summary>
        /// Writes the contents of a <see cref="Signature"/> as XML conforming to https://www.w3.org/TR/2001/PR-xmldsig-core-20010820/#sec-Signature.
        /// </summary>
        /// <param name="writer">the <see cref="XmlWriter"/> to use.</param>
        /// <param name="signature">the <see cref="Signature"/>to write.</param>
        /// <remarks>Assumes the &lt;SignatureValue> has been calculated, no canonicalization or signature calculation is performed.</remarks>
        /// <exception cref="ArgumentNullException">if <paramref name="writer"/> is null.</exception>
        /// <exception cref="ArgumentNullException">if <paramref name="signature"/> is null.</exception>
        /// <exception cref="XmlWriteException">if <see cref="Signature.SignatureValue"/> is null or empty.</exception>
        /// <exception cref="XmlWriteException">if <see cref="Signature.SignedInfo"/> is null.</exception>
        /// <exception cref="XmlWriteException">if one of the values in <see cref="Reference.Transforms"/> is null or empty.</exception>
        public virtual void WriteSignature(XmlWriter writer, Signature signature)
        {
            if (writer == null)
            {
                throw LogArgumentNullException(nameof(writer));
            }

            if (signature == null)
            {
                throw LogArgumentNullException(nameof(signature));
            }

            if (string.IsNullOrEmpty(signature.SignatureValue))
            {
                throw XmlUtil.LogWriteException(LogMessages.IDX30401, XmlSignatureConstants.Elements.Signature, XmlSignatureConstants.Elements.SignatureValue);
            }

            if (signature.SignedInfo == null)
            {
                throw XmlUtil.LogWriteException(LogMessages.IDX30404);
            }

            // <Signature>
            writer.WriteStartElement(Prefix, XmlSignatureConstants.Elements.Signature, XmlSignatureConstants.Namespace);
            if (signature.Id != null)
            {
                writer.WriteAttributeString(XmlSignatureConstants.Attributes.Id, null, signature.Id);
            }

            // <SignedInfo>
            WriteSignedInfo(writer, signature.SignedInfo);

            // <SignatureValue>
            writer.WriteStartElement(Prefix, XmlSignatureConstants.Elements.SignatureValue, XmlSignatureConstants.Namespace);

            // TODO - need signature value id
            // @Id
            if (!string.IsNullOrEmpty(signature.Id))
            {
                writer.WriteAttributeString(XmlSignatureConstants.Attributes.Id, null, signature.Id);
            }

            writer.WriteString(signature.SignatureValue);

            // </ SignatureValue>
            writer.WriteEndElement();

            // <KeyInfo>
            if (signature.KeyInfo != null)
            {
                WriteKeyInfo(writer, signature.KeyInfo);
            }

            // </ Signature>
            writer.WriteEndElement();
        }
Example #2
0
        /// <summary>
        /// Writes the contents of a <see cref="SignedInfo"/> as XML conforming to https://www.w3.org/TR/2001/PR-xmldsig-core-20010820/#sec-SignedInfo.
        /// </summary>
        /// <param name="writer">the <see cref="XmlWriter"/> to use.</param>
        /// <param name="signedInfo">the <see cref="SignedInfo"/>to write.</param>
        /// <remarks>Assumes the &lt;Reference> digest has been calculated, no canonicalization or digest calculation is performed.</remarks>
        /// <exception cref="ArgumentNullException">if <paramref name="writer"/> is null.</exception>
        /// <exception cref="ArgumentNullException">if <paramref name="signedInfo"/> is null.</exception>
        /// <exception cref="XmlWriteException">if <see cref="SignedInfo.CanonicalizationMethod"/> is null or empty.</exception>
        /// <exception cref="XmlWriteException">if <see cref="SignedInfo.References"/> is null.</exception>
        /// <exception cref="NotSupportedException">if <see cref="SignedInfo.References" />.Count > 1.</exception>
        /// <exception cref="XmlWriteException">if <see cref="SignedInfo.SignatureMethod"/> is null or empty.</exception>
        public virtual void WriteSignedInfo(XmlWriter writer, SignedInfo signedInfo)
        {
            if (writer == null)
            {
                throw LogArgumentNullException(nameof(writer));
            }

            if (signedInfo == null)
            {
                throw LogArgumentNullException(nameof(signedInfo));
            }

            if (string.IsNullOrEmpty(signedInfo.CanonicalizationMethod))
            {
                throw XmlUtil.LogWriteException(LogMessages.IDX30401, XmlSignatureConstants.Elements.SignedInfo, XmlSignatureConstants.Elements.CanonicalizationMethod);
            }

            if (string.IsNullOrEmpty(signedInfo.SignatureMethod))
            {
                throw XmlUtil.LogWriteException(LogMessages.IDX30401, XmlSignatureConstants.Elements.SignedInfo, XmlSignatureConstants.Elements.SignatureMethod);
            }

            if (signedInfo.References == null)
            {
                throw XmlUtil.LogWriteException(LogMessages.IDX30405);
            }

            // <SignedInfo>
            writer.WriteStartElement(Prefix, XmlSignatureConstants.Elements.SignedInfo, XmlSignatureConstants.Namespace);

            // @Id
            if (signedInfo.Id != null)
            {
                writer.WriteAttributeString(XmlSignatureConstants.Attributes.Id, null, signedInfo.Id);
            }

            // <CanonicalizationMethod>
            writer.WriteStartElement(Prefix, XmlSignatureConstants.Elements.CanonicalizationMethod, XmlSignatureConstants.Namespace);

            //@Algorithm
            writer.WriteAttributeString(XmlSignatureConstants.Attributes.Algorithm, null, signedInfo.CanonicalizationMethod);
            writer.WriteEndElement();

            // <SignatureMethod>
            writer.WriteStartElement(Prefix, XmlSignatureConstants.Elements.SignatureMethod, XmlSignatureConstants.Namespace);

            // @Algorithm
            writer.WriteAttributeString(XmlSignatureConstants.Attributes.Algorithm, null, signedInfo.SignatureMethod);

            // </SignatureMethod>
            writer.WriteEndElement();

            // <Reference>
            foreach (var reference in signedInfo.References)
            {
                WriteReference(writer, reference);
            }

            // </SignedInfo>
            writer.WriteEndElement();
        }
Example #3
0
        /// <summary>
        /// Writes the contents of a <see cref="Reference"/> as XML conforming to https://www.w3.org/TR/2001/PR-xmldsig-core-20010820/#sec-Reference.
        /// </summary>
        /// <param name="writer">the <see cref="XmlWriter"/> to use.</param>
        /// <param name="reference">the <see cref="Reference"/>to write.</param>
        /// <remarks>Assumes the &lt;DigestValue> has been calculated, no canonicalization or digest calculation is performed.</remarks>
        /// <exception cref="ArgumentNullException">if <paramref name="writer"/> is null.</exception>
        /// <exception cref="ArgumentNullException">if <paramref name="reference"/> is null.</exception>
        /// <exception cref="XmlWriteException">if <see cref="Reference.DigestMethod"/> is null or empty.</exception>
        /// <exception cref="XmlWriteException">if <see cref="Reference.DigestValue"/> is null or empty.</exception>
        /// <exception cref="XmlWriteException">if one of the values in <see cref="Reference.Transforms"/> is null or empty.</exception>
        public virtual void WriteReference(XmlWriter writer, Reference reference)
        {
            if (writer == null)
            {
                throw LogArgumentNullException(nameof(writer));
            }

            if (reference == null)
            {
                throw LogArgumentNullException(nameof(reference));
            }

            if (string.IsNullOrEmpty(reference.DigestMethod))
            {
                throw XmlUtil.LogWriteException(LogMessages.IDX30401, XmlSignatureConstants.Elements.Reference, XmlSignatureConstants.Elements.DigestMethod);
            }

            if (string.IsNullOrEmpty(reference.DigestValue))
            {
                throw XmlUtil.LogWriteException(LogMessages.IDX30401, XmlSignatureConstants.Elements.Reference, XmlSignatureConstants.Elements.DigestValue);
            }

            // <Reference>
            writer.WriteStartElement(Prefix, XmlSignatureConstants.Elements.Reference, XmlSignatureConstants.Namespace);

            // @Id
            if (reference.Id != null)
            {
                writer.WriteAttributeString(XmlSignatureConstants.Attributes.Id, null, reference.Id);
            }

            // @Uri
            if (reference.Uri != null)
            {
                if (reference.Uri.StartsWith("#", StringComparison.Ordinal))
                {
                    writer.WriteAttributeString(XmlSignatureConstants.Attributes.URI, null, reference.Uri);
                }
                else
                {
                    writer.WriteAttributeString(XmlSignatureConstants.Attributes.URI, null, "#" + reference.Uri);
                }
            }

            // @Type
            if (reference.Type != null)
            {
                writer.WriteAttributeString(XmlSignatureConstants.Attributes.Type, null, reference.Type);
            }

            // <Transforms>
            writer.WriteStartElement(Prefix, XmlSignatureConstants.Elements.Transforms, XmlSignatureConstants.Namespace);

            // <Transform>
            foreach (var transform in reference.Transforms)
            {
                if (transform == null)
                {
                    throw XmlUtil.LogWriteException(LogMessages.IDX30403);
                }

                // <Transform>
                writer.WriteStartElement(Prefix, XmlSignatureConstants.Elements.Transform, XmlSignatureConstants.Namespace);

                // @Algorithm
                writer.WriteAttributeString(XmlSignatureConstants.Attributes.Algorithm, transform.Algorithm);

                // </Transform>
                writer.WriteEndElement();
            }

            // Write Canonicalizing transform
            if (reference.CanonicalizingTransfrom != null)
            {
                // <Transform>
                writer.WriteStartElement(Prefix, XmlSignatureConstants.Elements.Transform, XmlSignatureConstants.Namespace);

                // @Algorithm
                writer.WriteAttributeString(XmlSignatureConstants.Attributes.Algorithm, reference.CanonicalizingTransfrom.Algorithm);

                // <InclusiveNamespaces>
                if (!string.IsNullOrEmpty(reference.CanonicalizingTransfrom.InclusiveNamespacesPrefixList))
                {
                    // @PrefixList
                    writer.WriteStartElement(XmlSignatureConstants.ExclusiveC14nPrefix, XmlSignatureConstants.Elements.InclusiveNamespaces, XmlSignatureConstants.ExclusiveC14nNamespace);
                    writer.WriteAttributeString(XmlSignatureConstants.Attributes.PrefixList, reference.CanonicalizingTransfrom.InclusiveNamespacesPrefixList);
                    writer.WriteEndElement();
                }

                // </Transform>
                writer.WriteEndElement();
            }

            // </Transforms>
            writer.WriteEndElement();

            // <DigestMethod>
            writer.WriteStartElement(Prefix, XmlSignatureConstants.Elements.DigestMethod, XmlSignatureConstants.Namespace);

            // @Algorithm
            writer.WriteAttributeString(XmlSignatureConstants.Attributes.Algorithm, null, reference.DigestMethod);

            // </DigestMethod>
            writer.WriteEndElement();

            // <DigestValue />
            writer.WriteElementString(Prefix, XmlSignatureConstants.Elements.DigestValue, XmlSignatureConstants.Namespace, reference.DigestValue);

            // </Reference>
            writer.WriteEndElement();
        }