/// <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 <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(); }
/// <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 <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(); }
/// <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 <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(); }