Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Base / MS / Internal / IO / Packaging / XmlSignatureProperties.cs / 1305600 / XmlSignatureProperties.cs
//------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // Helper for XmlDigitalSignatureProcessor. // Generates and consumes Metro-compliant SignatureProperties element within an // XmlDSig signature. // // History: // 01/25/2004: BruceMac: First iteration // 12/02/2005: BruceMac: Security Mitigations and support short form for UTC dates "Z" // //----------------------------------------------------------------------------- using System; using System.Collections; using System.Globalization; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Security.Cryptography; using System.Security.Cryptography.Xml; using System.Security.Cryptography.X509Certificates; using System.Security.Permissions; using System.Xml; using System.IO; using System.Windows; using System.IO.Packaging; using System.Diagnostics; using MS.Internal.WindowsBase; namespace MS.Internal.IO.Packaging { ////// Signature Handler implementation that follows the Feb 12, 2002 W3C DigSig Recommendation /// ///See: http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/ for details static internal class XmlSignatureProperties { //----------------------------------------------------------------------------- // // Internal Properties // //----------------------------------------------------------------------------- ////// Signature Time Format - default to most descriptive form - in Xml syntax /// internal static String DefaultDateTimeFormat { get { return _dateTimePatternMap[0].Format; } } //------------------------------------------------------------------------------ // // Internal Methods // //----------------------------------------------------------------------------- ////// Verify the given string is a legal Xml format /// /// xml format to verify ///true if legal internal static bool LegalFormat(String candidateFormat) { if (candidateFormat == null) throw new ArgumentNullException("candidateFormat"); return (GetIndex(candidateFormat) != -1); } ////// Obtain a W3C formatted SigningTime (equivalent to TimeStamp) /// /// xml document we are building /// time to persist /// id of new signature /// format to use - must be Xml date format legal syntax ///given writer with SignatureProperties xml added to it ///format matches that described in http://www.w3.org/TR/NOTE-datetime ////// /// internal static XmlElement AssembleSignatureProperties( XmlDocument xDoc, DateTime dateTime, String xmlDateTimeFormat, String signatureId) { Invariant.Assert(xDoc != null); Invariant.Assert(signatureId != null); // check for null format - use default if null if (xmlDateTimeFormat == null) { xmlDateTimeFormat = DefaultDateTimeFormat; } string[] dateTimeFormats = ConvertXmlFormatStringToDateTimeFormatString(xmlDateTimeFormat); //XmlElement signatureProperties = xDoc.CreateElement(XTable.Get(XTable.ID.SignaturePropertiesTagName), SignedXml.XmlDsigNamespaceUrl); // then we can stop parsing if ((String.CompareOrdinal(signaturePropertiesTag, reader.LocalName) == 0 && (reader.NodeType == XmlNodeType.EndElement))) break; else throw new XmlException(SR.Get(SRID.RequiredTagNotFound, signaturePropertyTag)); } //We did find one or moreXmlElement signatureProperty = xDoc.CreateElement(XTable.Get(XTable.ID.SignaturePropertyTagName), SignedXml.XmlDsigNamespaceUrl); signatureProperties.AppendChild(signatureProperty); XmlAttribute idAttr = xDoc.CreateAttribute(XTable.Get(XTable.ID.SignaturePropertyIdAttrName)); idAttr.Value = XTable.Get(XTable.ID.SignaturePropertyIdAttrValue); signatureProperty.Attributes.Append(idAttr); XmlAttribute targetAttr = xDoc.CreateAttribute(XTable.Get(XTable.ID.TargetAttrName)); targetAttr.Value = "#" + signatureId; signatureProperty.Attributes.Append(targetAttr); // XmlElement signatureTime = xDoc.CreateElement(XTable.Get(XTable.ID.SignatureTimeTagName), XTable.Get(XTable.ID.OpcSignatureNamespace)); XmlElement signatureTimeFormat = xDoc.CreateElement(XTable.Get(XTable.ID.SignatureTimeFormatTagName), XTable.Get(XTable.ID.OpcSignatureNamespace)); XmlElement signatureTimeValue = xDoc.CreateElement(XTable.Get(XTable.ID.SignatureTimeValueTagName), XTable.Get(XTable.ID.OpcSignatureNamespace)); signatureTimeFormat.AppendChild(xDoc.CreateTextNode(xmlDateTimeFormat)); signatureTimeValue.AppendChild(xDoc.CreateTextNode(DateTimeToXmlFormattedTime(dateTime, dateTimeFormats[0]))); signatureTime.AppendChild(signatureTimeFormat); signatureTime.AppendChild(signatureTimeValue); signatureProperty.AppendChild(signatureTime); return signatureProperties; } /// /// Parse the xml and determine the signing time /// /// NodeReader positioned at the SignatureProperties tag /// value of the Id attribute on the Signature tag /// format found ///illegal format ///signing time internal static DateTime ParseSigningTime(XmlReader reader, string signatureId, out String timeFormat) { if (reader == null) throw new ArgumentNullException("reader"); bool signatureTimePropertyFound = false; bool signatureTimeIdFound = false; string w3cSignatureNameSpace = SignedXml.XmlDsigNamespaceUrl; //tag string signaturePropertyTag = XTable.Get(XTable.ID.SignaturePropertyTagName); string signaturePropertiesTag = XTable.Get(XTable.ID.SignaturePropertiesTagName); //initializing to a dummy value DateTime signingTime = DateTime.Now; timeFormat = null; while (reader.Read()) { //Looking for tag if (reader.MoveToContent() == XmlNodeType.Element && (String.CompareOrdinal(reader.NamespaceURI, w3cSignatureNameSpace) == 0) && (String.CompareOrdinal(reader.LocalName, signaturePropertyTag) == 0) && reader.Depth == 2) { //Verify Attributes //Look for well-defined Id attribute and if it is present if (VerifyIdAttribute(reader)) { //If we encounter more than one tag with the expected //id, then its an error. if (signatureTimeIdFound) throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); else signatureTimeIdFound = true; //VerifyTargetAttribute will return false, if the Target attribute is missing //or contains an incorrect value. if(VerifyTargetAttribute(reader, signatureId)) { signingTime = ParseSignatureTimeTag(reader, out timeFormat); signatureTimePropertyFound = true; } } } else //Expected tag not found. //Look for end tag corresponding to or //if these are other custom defined properties, then anything with //depth greater than 2 should be ignored as these can be nested elements. if (((String.CompareOrdinal(signaturePropertyTag, reader.LocalName) == 0 && (reader.NodeType == XmlNodeType.EndElement))) || reader.Depth > 2) continue; else //If we find the end tag fortags but there were none that //defined the id attribute and target attribute and tag at this point, //else it could be that there are more SignatureTime or //other tags nested here and that is an error. if (reader.Read() && reader.MoveToContent() == XmlNodeType.EndElement && String.CompareOrdinal(signaturePropertyTag, reader.LocalName) == 0) break; else throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); } else // if we do not find the nested elements as expected throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); } } else throw new XmlException(SR.Get(SRID.RequiredTagNotFound, signatureTimeTag)); // generate an equivalent DateTime object if (timeValue != null && timeFormat != null) return XmlFormattedTimeToDateTime(timeValue, timeFormat); else throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); } ///element tag correctly. if(!signatureTimePropertyFound) throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); return signingTime; } //------------------------------------------------------------------------------ // // Private Methods // //------------------------------------------------------------------------------ /// /// Parse the SignatureTime tag /// /// NodeReader positioned at the SignatureProperty tag /// format found ///illegal format ///signing time private static DateTime ParseSignatureTimeTag(XmlReader reader, out String timeFormat) { //There are no attributes on all the three tags that we parse in this method //, , // Note: ReadContentAsString will return String.Empty but never null timeFormat = reader.ReadContentAsString(); Debug.Assert(reader.NodeType == XmlNodeType.EndElement); } else //This would happen if we found more than one Format tags or if there //are other nested elements of if they are of a different XmlNodeType type throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); } else //If we encounter any tag other thanint expectedAttributeCount = 0; string opcSignatureNameSpace = XTable.Get(XTable.ID.OpcSignatureNamespace); string signaturePropertyTag = XTable.Get(XTable.ID.SignaturePropertyTagName); string signatureTimeTag = XTable.Get(XTable.ID.SignatureTimeTagName); string timeValueTagName = XTable.Get(XTable.ID.SignatureTimeValueTagName); string timeFormatTagName = XTable.Get(XTable.ID.SignatureTimeFormatTagName); // // Note: ReadContentAsString will return String.Empty but never null timeValue = reader.ReadContentAsString(); Debug.Assert(reader.NodeType == XmlNodeType.EndElement); } else //This would happen if we found more than one Value tags or if there //are other nested elements of if they are of a different XmlNodeType type throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); } else if ((String.CompareOrdinal(reader.LocalName, timeFormatTagName) == 0) && PackagingUtilities.GetNonXmlnsAttributeCount(reader) == expectedAttributeCount) { if (timeFormat == null && reader.Read() && reader.MoveToContent() == XmlNodeType.Text && reader.Depth == 5) { //After reading the content, the reader progresses to the next element. //So after this method is called, the reader is positioned at the //EndElement corresponding to Format tag -must be one of or or /// DateTime to XML Format /// /// date time to convert /// format to use - specified in DateTime syntax ///opc-legal string suitable for embedding in XML digital signatures private static String DateTimeToXmlFormattedTime(DateTime dt, string format) { DateTimeFormatInfo formatter = new DateTimeFormatInfo(); formatter.FullDateTimePattern = format; return dt.ToString(format, formatter); } ////// XML Format time string to DateTime /// /// string to parse /// format to use - specified in Xml Signature date syntax ///Format does not match the given string ///DateTime private static DateTime XmlFormattedTimeToDateTime(String s, String format) { // convert Xml syntax to equivalent DateTime syntax string[] legalFormats = ConvertXmlFormatStringToDateTimeFormatString(format); // the default formatter is culture-invariant (which is what we want) DateTimeFormatInfo formatter = new DateTimeFormatInfo(); formatter.FullDateTimePattern = format; return DateTime.ParseExact(s, legalFormats, formatter, DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite); } ////// Get index of the row that matches the given format /// /// format to lookup ///-1 if not found private static int GetIndex(String format) { for (int i = 0; i < _dateTimePatternMap.GetLength(0); i++) { if (String.CompareOrdinal(_dateTimePatternMap[i].Format, format) == 0) { return i; } } return -1; } ////// Convert Xml format syntax to DateTime format syntax /// /// ///private static string[] ConvertXmlFormatStringToDateTimeFormatString(String format) { return _dateTimePatternMap[GetIndex(format)].Patterns; } /// /// Verify if the SignatureProperty tag has a valid Id attribute /// /// NodeReader positioned at the SignatureProperty tag ///true, if Id attribute is present and has the correct value, else false private static bool VerifyIdAttribute(XmlReader reader) { string idAttrValue = reader.GetAttribute(XTable.Get(XTable.ID.SignaturePropertyIdAttrName)); if(idAttrValue!=null && (String.CompareOrdinal(idAttrValue,XTable.Get(XTable.ID.SignaturePropertyIdAttrValue)) == 0)) return true; else return false; } ////// Verify if the mandatory Target attribute exists on the SignatureProperty tag /// /// NodeReader positioned at the SignatureProperty tag /// value of the Id attribute on the Signature tag ///true, if Target attribute is present and has the correct value, else false private static bool VerifyTargetAttribute(XmlReader reader, string signatureId) { string idTargetValue = reader.GetAttribute(XTable.Get(XTable.ID.TargetAttrName)); if (idTargetValue != null) { //whether there is an Id attribute on thetag or no, //an empty Target attribute on tag, is allowed. //Empty string means current document if (String.CompareOrdinal(idTargetValue, String.Empty) == 0) return true; else { //If the Target attribute has a non-empty string then //it must match the tag Id attribute value if (signatureId != null && String.CompareOrdinal(idTargetValue, "#" + signatureId) == 0) return true; else return false; } } else return false; } //----------------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------------------ // This is a mapping between time formats allowed by Opc spec (taken from // http://www.w3.org/TR/NOTE-datetime) and the equivalent formatting string // expected by the DateTimeFormatInfo class. private struct TimeFormatMapEntry { public TimeFormatMapEntry(string xmlFormatString, string[] dateTimePatterns) { _xmlFormatString = xmlFormatString; _dateTimePatterns = dateTimePatterns; } public string Format { get { return _xmlFormatString; }} public string[] Patterns { get { return _dateTimePatterns; }} private string _xmlFormatString; private string[] _dateTimePatterns; }; private static readonly TimeFormatMapEntry[] _dateTimePatternMap = { // Opc Spec value Equivalent DateTimePattern(s) new TimeFormatMapEntry("YYYY-MM-DDThh:mm:ss.sTZD", new string[] {"yyyy-MM-ddTHH:mm:ss.fzzz", "yyyy-MM-ddTHH:mm:ss.fZ"}), new TimeFormatMapEntry("YYYY-MM-DDThh:mm:ssTZD", new string[] {"yyyy-MM-ddTHH:mm:sszzz", "yyyy-MM-ddTHH:mm:ssZ"}), new TimeFormatMapEntry("YYYY-MM-DDThh:mmTZD", new string[] {"yyyy-MM-ddTHH:mmzzz", "yyyy-MM-ddTHH:mmZ"}), new TimeFormatMapEntry("YYYY-MM-DD", new string[] {"yyyy-MM-dd"}), new TimeFormatMapEntry("YYYY-MM", new string[] {"yyyy-MM"}), new TimeFormatMapEntry("YYYY", new string[] {"yyyy"}), }; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ // // // Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // Helper for XmlDigitalSignatureProcessor. // Generates and consumes Metro-compliant SignatureProperties element within an // XmlDSig signature. // // History: // 01/25/2004: BruceMac: First iteration // 12/02/2005: BruceMac: Security Mitigations and support short form for UTC dates "Z" // //----------------------------------------------------------------------------- using System; using System.Collections; using System.Globalization; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Security.Cryptography; using System.Security.Cryptography.Xml; using System.Security.Cryptography.X509Certificates; using System.Security.Permissions; using System.Xml; using System.IO; using System.Windows; using System.IO.Packaging; using System.Diagnostics; using MS.Internal.WindowsBase; namespace MS.Internal.IO.Packaging { ////// Signature Handler implementation that follows the Feb 12, 2002 W3C DigSig Recommendation /// ///See: http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/ for details static internal class XmlSignatureProperties { //----------------------------------------------------------------------------- // // Internal Properties // //----------------------------------------------------------------------------- ////// Signature Time Format - default to most descriptive form - in Xml syntax /// internal static String DefaultDateTimeFormat { get { return _dateTimePatternMap[0].Format; } } //------------------------------------------------------------------------------ // // Internal Methods // //----------------------------------------------------------------------------- ////// Verify the given string is a legal Xml format /// /// xml format to verify ///true if legal internal static bool LegalFormat(String candidateFormat) { if (candidateFormat == null) throw new ArgumentNullException("candidateFormat"); return (GetIndex(candidateFormat) != -1); } ////// Obtain a W3C formatted SigningTime (equivalent to TimeStamp) /// /// xml document we are building /// time to persist /// id of new signature /// format to use - must be Xml date format legal syntax ///given writer with SignatureProperties xml added to it ///format matches that described in http://www.w3.org/TR/NOTE-datetime ////// /// internal static XmlElement AssembleSignatureProperties( XmlDocument xDoc, DateTime dateTime, String xmlDateTimeFormat, String signatureId) { Invariant.Assert(xDoc != null); Invariant.Assert(signatureId != null); // check for null format - use default if null if (xmlDateTimeFormat == null) { xmlDateTimeFormat = DefaultDateTimeFormat; } string[] dateTimeFormats = ConvertXmlFormatStringToDateTimeFormatString(xmlDateTimeFormat); //XmlElement signatureProperties = xDoc.CreateElement(XTable.Get(XTable.ID.SignaturePropertiesTagName), SignedXml.XmlDsigNamespaceUrl); // then we can stop parsing if ((String.CompareOrdinal(signaturePropertiesTag, reader.LocalName) == 0 && (reader.NodeType == XmlNodeType.EndElement))) break; else throw new XmlException(SR.Get(SRID.RequiredTagNotFound, signaturePropertyTag)); } //We did find one or moreXmlElement signatureProperty = xDoc.CreateElement(XTable.Get(XTable.ID.SignaturePropertyTagName), SignedXml.XmlDsigNamespaceUrl); signatureProperties.AppendChild(signatureProperty); XmlAttribute idAttr = xDoc.CreateAttribute(XTable.Get(XTable.ID.SignaturePropertyIdAttrName)); idAttr.Value = XTable.Get(XTable.ID.SignaturePropertyIdAttrValue); signatureProperty.Attributes.Append(idAttr); XmlAttribute targetAttr = xDoc.CreateAttribute(XTable.Get(XTable.ID.TargetAttrName)); targetAttr.Value = "#" + signatureId; signatureProperty.Attributes.Append(targetAttr); // XmlElement signatureTime = xDoc.CreateElement(XTable.Get(XTable.ID.SignatureTimeTagName), XTable.Get(XTable.ID.OpcSignatureNamespace)); XmlElement signatureTimeFormat = xDoc.CreateElement(XTable.Get(XTable.ID.SignatureTimeFormatTagName), XTable.Get(XTable.ID.OpcSignatureNamespace)); XmlElement signatureTimeValue = xDoc.CreateElement(XTable.Get(XTable.ID.SignatureTimeValueTagName), XTable.Get(XTable.ID.OpcSignatureNamespace)); signatureTimeFormat.AppendChild(xDoc.CreateTextNode(xmlDateTimeFormat)); signatureTimeValue.AppendChild(xDoc.CreateTextNode(DateTimeToXmlFormattedTime(dateTime, dateTimeFormats[0]))); signatureTime.AppendChild(signatureTimeFormat); signatureTime.AppendChild(signatureTimeValue); signatureProperty.AppendChild(signatureTime); return signatureProperties; } /// /// Parse the xml and determine the signing time /// /// NodeReader positioned at the SignatureProperties tag /// value of the Id attribute on the Signature tag /// format found ///illegal format ///signing time internal static DateTime ParseSigningTime(XmlReader reader, string signatureId, out String timeFormat) { if (reader == null) throw new ArgumentNullException("reader"); bool signatureTimePropertyFound = false; bool signatureTimeIdFound = false; string w3cSignatureNameSpace = SignedXml.XmlDsigNamespaceUrl; //tag string signaturePropertyTag = XTable.Get(XTable.ID.SignaturePropertyTagName); string signaturePropertiesTag = XTable.Get(XTable.ID.SignaturePropertiesTagName); //initializing to a dummy value DateTime signingTime = DateTime.Now; timeFormat = null; while (reader.Read()) { //Looking for tag if (reader.MoveToContent() == XmlNodeType.Element && (String.CompareOrdinal(reader.NamespaceURI, w3cSignatureNameSpace) == 0) && (String.CompareOrdinal(reader.LocalName, signaturePropertyTag) == 0) && reader.Depth == 2) { //Verify Attributes //Look for well-defined Id attribute and if it is present if (VerifyIdAttribute(reader)) { //If we encounter more than one tag with the expected //id, then its an error. if (signatureTimeIdFound) throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); else signatureTimeIdFound = true; //VerifyTargetAttribute will return false, if the Target attribute is missing //or contains an incorrect value. if(VerifyTargetAttribute(reader, signatureId)) { signingTime = ParseSignatureTimeTag(reader, out timeFormat); signatureTimePropertyFound = true; } } } else //Expected tag not found. //Look for end tag corresponding to or //if these are other custom defined properties, then anything with //depth greater than 2 should be ignored as these can be nested elements. if (((String.CompareOrdinal(signaturePropertyTag, reader.LocalName) == 0 && (reader.NodeType == XmlNodeType.EndElement))) || reader.Depth > 2) continue; else //If we find the end tag fortags but there were none that //defined the id attribute and target attribute and tag at this point, //else it could be that there are more SignatureTime or //other tags nested here and that is an error. if (reader.Read() && reader.MoveToContent() == XmlNodeType.EndElement && String.CompareOrdinal(signaturePropertyTag, reader.LocalName) == 0) break; else throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); } else // if we do not find the nested elements as expected throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); } } else throw new XmlException(SR.Get(SRID.RequiredTagNotFound, signatureTimeTag)); // generate an equivalent DateTime object if (timeValue != null && timeFormat != null) return XmlFormattedTimeToDateTime(timeValue, timeFormat); else throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); } ///element tag correctly. if(!signatureTimePropertyFound) throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); return signingTime; } //------------------------------------------------------------------------------ // // Private Methods // //------------------------------------------------------------------------------ /// /// Parse the SignatureTime tag /// /// NodeReader positioned at the SignatureProperty tag /// format found ///illegal format ///signing time private static DateTime ParseSignatureTimeTag(XmlReader reader, out String timeFormat) { //There are no attributes on all the three tags that we parse in this method //, , // Note: ReadContentAsString will return String.Empty but never null timeFormat = reader.ReadContentAsString(); Debug.Assert(reader.NodeType == XmlNodeType.EndElement); } else //This would happen if we found more than one Format tags or if there //are other nested elements of if they are of a different XmlNodeType type throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); } else //If we encounter any tag other thanint expectedAttributeCount = 0; string opcSignatureNameSpace = XTable.Get(XTable.ID.OpcSignatureNamespace); string signaturePropertyTag = XTable.Get(XTable.ID.SignaturePropertyTagName); string signatureTimeTag = XTable.Get(XTable.ID.SignatureTimeTagName); string timeValueTagName = XTable.Get(XTable.ID.SignatureTimeValueTagName); string timeFormatTagName = XTable.Get(XTable.ID.SignatureTimeFormatTagName); // // Note: ReadContentAsString will return String.Empty but never null timeValue = reader.ReadContentAsString(); Debug.Assert(reader.NodeType == XmlNodeType.EndElement); } else //This would happen if we found more than one Value tags or if there //are other nested elements of if they are of a different XmlNodeType type throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); } else if ((String.CompareOrdinal(reader.LocalName, timeFormatTagName) == 0) && PackagingUtilities.GetNonXmlnsAttributeCount(reader) == expectedAttributeCount) { if (timeFormat == null && reader.Read() && reader.MoveToContent() == XmlNodeType.Text && reader.Depth == 5) { //After reading the content, the reader progresses to the next element. //So after this method is called, the reader is positioned at the //EndElement corresponding to Format tag -must be one of or or /// DateTime to XML Format /// /// date time to convert /// format to use - specified in DateTime syntax ///opc-legal string suitable for embedding in XML digital signatures private static String DateTimeToXmlFormattedTime(DateTime dt, string format) { DateTimeFormatInfo formatter = new DateTimeFormatInfo(); formatter.FullDateTimePattern = format; return dt.ToString(format, formatter); } ////// XML Format time string to DateTime /// /// string to parse /// format to use - specified in Xml Signature date syntax ///Format does not match the given string ///DateTime private static DateTime XmlFormattedTimeToDateTime(String s, String format) { // convert Xml syntax to equivalent DateTime syntax string[] legalFormats = ConvertXmlFormatStringToDateTimeFormatString(format); // the default formatter is culture-invariant (which is what we want) DateTimeFormatInfo formatter = new DateTimeFormatInfo(); formatter.FullDateTimePattern = format; return DateTime.ParseExact(s, legalFormats, formatter, DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite); } ////// Get index of the row that matches the given format /// /// format to lookup ///-1 if not found private static int GetIndex(String format) { for (int i = 0; i < _dateTimePatternMap.GetLength(0); i++) { if (String.CompareOrdinal(_dateTimePatternMap[i].Format, format) == 0) { return i; } } return -1; } ////// Convert Xml format syntax to DateTime format syntax /// /// ///private static string[] ConvertXmlFormatStringToDateTimeFormatString(String format) { return _dateTimePatternMap[GetIndex(format)].Patterns; } /// /// Verify if the SignatureProperty tag has a valid Id attribute /// /// NodeReader positioned at the SignatureProperty tag ///true, if Id attribute is present and has the correct value, else false private static bool VerifyIdAttribute(XmlReader reader) { string idAttrValue = reader.GetAttribute(XTable.Get(XTable.ID.SignaturePropertyIdAttrName)); if(idAttrValue!=null && (String.CompareOrdinal(idAttrValue,XTable.Get(XTable.ID.SignaturePropertyIdAttrValue)) == 0)) return true; else return false; } ////// Verify if the mandatory Target attribute exists on the SignatureProperty tag /// /// NodeReader positioned at the SignatureProperty tag /// value of the Id attribute on the Signature tag ///true, if Target attribute is present and has the correct value, else false private static bool VerifyTargetAttribute(XmlReader reader, string signatureId) { string idTargetValue = reader.GetAttribute(XTable.Get(XTable.ID.TargetAttrName)); if (idTargetValue != null) { //whether there is an Id attribute on thetag or no, //an empty Target attribute on tag, is allowed. //Empty string means current document if (String.CompareOrdinal(idTargetValue, String.Empty) == 0) return true; else { //If the Target attribute has a non-empty string then //it must match the tag Id attribute value if (signatureId != null && String.CompareOrdinal(idTargetValue, "#" + signatureId) == 0) return true; else return false; } } else return false; } //----------------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------------------ // This is a mapping between time formats allowed by Opc spec (taken from // http://www.w3.org/TR/NOTE-datetime) and the equivalent formatting string // expected by the DateTimeFormatInfo class. private struct TimeFormatMapEntry { public TimeFormatMapEntry(string xmlFormatString, string[] dateTimePatterns) { _xmlFormatString = xmlFormatString; _dateTimePatterns = dateTimePatterns; } public string Format { get { return _xmlFormatString; }} public string[] Patterns { get { return _dateTimePatterns; }} private string _xmlFormatString; private string[] _dateTimePatterns; }; private static readonly TimeFormatMapEntry[] _dateTimePatternMap = { // Opc Spec value Equivalent DateTimePattern(s) new TimeFormatMapEntry("YYYY-MM-DDThh:mm:ss.sTZD", new string[] {"yyyy-MM-ddTHH:mm:ss.fzzz", "yyyy-MM-ddTHH:mm:ss.fZ"}), new TimeFormatMapEntry("YYYY-MM-DDThh:mm:ssTZD", new string[] {"yyyy-MM-ddTHH:mm:sszzz", "yyyy-MM-ddTHH:mm:ssZ"}), new TimeFormatMapEntry("YYYY-MM-DDThh:mmTZD", new string[] {"yyyy-MM-ddTHH:mmzzz", "yyyy-MM-ddTHH:mmZ"}), new TimeFormatMapEntry("YYYY-MM-DD", new string[] {"yyyy-MM-dd"}), new TimeFormatMapEntry("YYYY-MM", new string[] {"yyyy-MM"}), new TimeFormatMapEntry("YYYY", new string[] {"yyyy"}), }; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RawStylusSystemGestureInputReport.cs
- PropertyPathConverter.cs
- PrintController.cs
- HttpCookiesSection.cs
- BufferedReceiveElement.cs
- X509ChainPolicy.cs
- Delegate.cs
- RightsController.cs
- BatchStream.cs
- UnicodeEncoding.cs
- ContextQuery.cs
- TrustSection.cs
- NativeMethods.cs
- DataGridViewRowEventArgs.cs
- RecordManager.cs
- IUnknownConstantAttribute.cs
- GridViewEditEventArgs.cs
- HttpProcessUtility.cs
- x509utils.cs
- IERequestCache.cs
- XmlSerializationWriter.cs
- IIS7WorkerRequest.cs
- SqlDataSourceQueryConverter.cs
- EnumerableCollectionView.cs
- JsonDeserializer.cs
- InteropBitmapSource.cs
- FilteredXmlReader.cs
- Utilities.cs
- RoleManagerEventArgs.cs
- ArrayWithOffset.cs
- Cursors.cs
- PassportAuthenticationModule.cs
- MessageSecurityOverMsmq.cs
- ZipFileInfo.cs
- diagnosticsswitches.cs
- ModuleConfigurationInfo.cs
- AddInSegmentDirectoryNotFoundException.cs
- IntPtr.cs
- OletxResourceManager.cs
- PDBReader.cs
- ExpandCollapseProviderWrapper.cs
- ResourcesGenerator.cs
- MetadataArtifactLoaderComposite.cs
- SessionPageStateSection.cs
- MatrixAnimationUsingPath.cs
- RichTextBoxAutomationPeer.cs
- WSFederationHttpBindingElement.cs
- VirtualPathData.cs
- PrintDialog.cs
- ACE.cs
- ArgumentsParser.cs
- PropertyAccessVisitor.cs
- MouseGestureConverter.cs
- DelegateHelpers.cs
- QilBinary.cs
- NameValueCache.cs
- Ipv6Element.cs
- DefaultMemberAttribute.cs
- WebBaseEventKeyComparer.cs
- DocumentSequence.cs
- UserNameSecurityTokenAuthenticator.cs
- StylusCollection.cs
- TouchEventArgs.cs
- ConfigurationValidatorAttribute.cs
- TransformDescriptor.cs
- ZoneLinkButton.cs
- SRDisplayNameAttribute.cs
- CanonicalizationDriver.cs
- CookieParameter.cs
- Soap.cs
- Vector3DIndependentAnimationStorage.cs
- ArgIterator.cs
- MessageSmuggler.cs
- DockProviderWrapper.cs
- httpstaticobjectscollection.cs
- DbConnectionStringCommon.cs
- XmlDataSource.cs
- InputLanguage.cs
- OleDbDataAdapter.cs
- FloaterBaseParagraph.cs
- SqlCaseSimplifier.cs
- DesignerVerb.cs
- LineVisual.cs
- EncoderExceptionFallback.cs
- MsmqQueue.cs
- UIHelper.cs
- NativeMethods.cs
- SafeEventLogWriteHandle.cs
- CancelEventArgs.cs
- DataTableMappingCollection.cs
- Control.cs
- TextSelection.cs
- DesignerOptionService.cs
- ADConnectionHelper.cs
- SinglePageViewer.cs
- HealthMonitoringSectionHelper.cs
- MergePropertyDescriptor.cs
- GPRECT.cs
- Track.cs
- PackagePartCollection.cs