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);
//
XmlElement 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 for 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 more tags but there were none that
//defined the id attribute and target attribute and 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
//, ,
int 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);
// must be one of or
// 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 -
// 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 than or 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));
}
///
/// 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 the tag 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
- IntSecurity.cs
- HashCodeCombiner.cs
- WebPartManager.cs
- DecimalStorage.cs
- Html32TextWriter.cs
- wmiprovider.cs
- COM2EnumConverter.cs
- safex509handles.cs
- SqlRemoveConstantOrderBy.cs
- MarginsConverter.cs
- ObjectToIdCache.cs
- SqlNodeAnnotation.cs
- MissingFieldException.cs
- QuaternionKeyFrameCollection.cs
- QueryContinueDragEventArgs.cs
- DragEvent.cs
- WinEventTracker.cs
- XmlKeywords.cs
- SecureStringHasher.cs
- MetadataItemSerializer.cs
- StorageMappingItemCollection.cs
- UnhandledExceptionEventArgs.cs
- ChannelToken.cs
- MostlySingletonList.cs
- ExpressionContext.cs
- UIElementIsland.cs
- UserControlCodeDomTreeGenerator.cs
- ReadOnlyDataSource.cs
- TraceSection.cs
- KeyboardDevice.cs
- DLinqDataModelProvider.cs
- XPathSelectionIterator.cs
- EntityProviderServices.cs
- DataGridViewRowCancelEventArgs.cs
- NetSectionGroup.cs
- ExceptionNotification.cs
- SqlStream.cs
- SmtpSection.cs
- SimpleTypeResolver.cs
- SqlMultiplexer.cs
- PointIndependentAnimationStorage.cs
- MatrixTransform3D.cs
- DBDataPermissionAttribute.cs
- DataSysAttribute.cs
- RepeatInfo.cs
- EncodedStreamFactory.cs
- FixedDocumentSequencePaginator.cs
- DrawingDrawingContext.cs
- FeatureAttribute.cs
- ContentValidator.cs
- SocketElement.cs
- AddDataControlFieldDialog.cs
- XamlPoint3DCollectionSerializer.cs
- ByteFacetDescriptionElement.cs
- DbCommandDefinition.cs
- OleDbEnumerator.cs
- ConstraintCollection.cs
- RepeatInfo.cs
- DetailsViewRowCollection.cs
- NotifyParentPropertyAttribute.cs
- Base64Decoder.cs
- ListViewItemSelectionChangedEvent.cs
- DataBindingCollection.cs
- PersistenceProviderElement.cs
- EmptyCollection.cs
- SkinIDTypeConverter.cs
- BitmapEffectInputConnector.cs
- WebPartAuthorizationEventArgs.cs
- ApplicationProxyInternal.cs
- RIPEMD160.cs
- FilterableData.cs
- ReturnValue.cs
- Error.cs
- Process.cs
- QilFunction.cs
- AdapterDictionary.cs
- Point.cs
- ObjectDataSourceFilteringEventArgs.cs
- LifetimeMonitor.cs
- ByteStream.cs
- XmlAttributeOverrides.cs
- InternalConfigHost.cs
- DesignerDataStoredProcedure.cs
- OleCmdHelper.cs
- Event.cs
- TextEmbeddedObject.cs
- EUCJPEncoding.cs
- BitmapMetadata.cs
- ObjectNavigationPropertyMapping.cs
- TableItemStyle.cs
- EntityDataSourceEntitySetNameItem.cs
- SafeCoTaskMem.cs
- EventLog.cs
- NativeMethodsCLR.cs
- Symbol.cs
- DataGridViewDataErrorEventArgs.cs
- GenericFlowSwitchHelper.cs
- EnumType.cs
- SafeHandles.cs
- IteratorAsyncResult.cs