Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SafeWaitHandle.cs
- SmiRecordBuffer.cs
- ParserExtension.cs
- SemaphoreFullException.cs
- XmlSchemaAny.cs
- XmlBaseWriter.cs
- LoginDesignerUtil.cs
- Rights.cs
- LongValidator.cs
- UnsafeNativeMethods.cs
- XmlWrappingWriter.cs
- ServerReliableChannelBinder.cs
- SemanticKeyElement.cs
- Util.cs
- CharEnumerator.cs
- GeneralTransform3DCollection.cs
- _Rfc2616CacheValidators.cs
- Utils.cs
- SystemKeyConverter.cs
- VisualStateGroup.cs
- CompositeControl.cs
- AsnEncodedData.cs
- URLIdentityPermission.cs
- UnknownWrapper.cs
- SchemaImporterExtensionElement.cs
- DataGridViewLinkCell.cs
- DataConnectionHelper.cs
- EntityDataReader.cs
- ManifestResourceInfo.cs
- RelationshipManager.cs
- Convert.cs
- Rect3D.cs
- KnownBoxes.cs
- MemberDomainMap.cs
- BrowsableAttribute.cs
- XmlSchemaCollection.cs
- FileDialog.cs
- QueryGenerator.cs
- PartialArray.cs
- DispatcherObject.cs
- FormsAuthenticationConfiguration.cs
- TagNameToTypeMapper.cs
- XmlMtomWriter.cs
- ReaderWriterLockWrapper.cs
- KnownTypes.cs
- DataBindingCollection.cs
- XmlDataSourceView.cs
- DecoderReplacementFallback.cs
- ColorDialog.cs
- DataObjectMethodAttribute.cs
- ItemCheckEvent.cs
- OdbcInfoMessageEvent.cs
- Attributes.cs
- BaseTemplateBuildProvider.cs
- MetadataItemEmitter.cs
- serverconfig.cs
- RequestDescription.cs
- OdbcConnectionStringbuilder.cs
- TimeSpan.cs
- PopupControlService.cs
- Vector3D.cs
- QueryOptionExpression.cs
- XPathSelfQuery.cs
- ContainerActivationHelper.cs
- WebRequestModuleElementCollection.cs
- DateTimeSerializationSection.cs
- HttpProtocolImporter.cs
- ImageField.cs
- PropertyValueChangedEvent.cs
- KeyToListMap.cs
- ThemeInfoAttribute.cs
- ContractCodeDomInfo.cs
- WorkflowMessageEventHandler.cs
- PeerNameRecordCollection.cs
- InheritanceRules.cs
- UnsafeNetInfoNativeMethods.cs
- LiteralDesigner.cs
- BuildProvider.cs
- LinqDataSource.cs
- RegexStringValidator.cs
- ProcessThreadCollection.cs
- Exceptions.cs
- WpfPayload.cs
- AuthorizationRule.cs
- ToolStripCustomTypeDescriptor.cs
- GZipDecoder.cs
- Utils.cs
- CustomSignedXml.cs
- GridViewRowCollection.cs
- HtmlContainerControl.cs
- EntityConnectionStringBuilder.cs
- CrossAppDomainChannel.cs
- SystemGatewayIPAddressInformation.cs
- DocumentSequenceHighlightLayer.cs
- SystemIPInterfaceProperties.cs
- ServiceMemoryGates.cs
- GACMembershipCondition.cs
- Bidi.cs
- TranslateTransform.cs
- PathHelper.cs