Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / infocard / Service / managed / Microsoft / InfoCards / InfoCardXmlSerializer.cs / 2 / InfoCardXmlSerializer.cs
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace Microsoft.InfoCards
{
using System;
using System.Xml;
using System.Xml.Schema;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Collections.Generic;
using System.Collections;
using System.ServiceModel;
using System.IO;
using System.Reflection;
using System.Globalization;
using System.Security.Cryptography;
using Microsoft.InfoCards.Diagnostics;
using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace;
using System.IdentityModel.Tokens;
//
// This class manages the deserialization of an infocard
// as an XML file as specified by WS-Identity
//
internal class InfoCardXmlSerializer
{
InfoCard m_card = null;
X509Certificate2 m_issuer = null;
X509Certificate2Collection m_additionalIssuerCerts = null;
bool m_isIssuerChainTrusted = false;
bool m_checkSignature = false;
bool m_isDeserialized = false;
StoreConnection m_connection;
public InfoCardXmlSerializer( StoreConnection connection )
{
m_connection = connection;
}
public InfoCard Card
{
get
{
if( m_isDeserialized )
{
return m_card;
}
else
{
return null;
}
}
}
public X509Certificate2 Issuer
{
get
{
if( m_isDeserialized )
{
return m_issuer;
}
else
{
return null;
}
}
}
public X509Certificate2Collection AdditionalIssuerCerts
{
get
{
return m_additionalIssuerCerts;
}
}
public bool IsIssuerChainTrusted
{
get
{
//
// This function should only be called after deserialization
//
IDT.Assert( m_isDeserialized, "Card should be deserialized before checking this value" );
return m_isIssuerChainTrusted;
}
}
public bool CheckSignature
{
set { m_checkSignature = value; }
}
//
// Summary
// Deserialize a managed infocard xml file
//
// Parameters
// filename - name of the managed card file
//
//
public void Deserialize( string filename )
{
try
{
m_card = new InfoCard();
m_card.HashSalt = InfoCard.GenerateSalt();
CreateCardFromXml( filename );
m_card.IssuerIdentifierAsBytes =
Convert.FromBase64String(
Recipient.CertGetRecipientOrganizationPPIDSeedHash(
m_issuer, m_additionalIssuerCerts, m_isIssuerChainTrusted ) );
m_isDeserialized = true;
}
catch( Exception e )
{
if( IDT.IsFatal( e ) )
{
throw;
}
throw IDT.ThrowHelperError(
new ImportException( SR.GetString( SR.InvalidImportFile ), e ) );
}
}
//
// Summary
// Populate the infocard by parsing a managed card file
//
// Parameter
// reader - The XmlReader to read from
//
private void CreateCardFromXml( string filename )
{
try
{
//
// File.OpenRead( filename )is equivalent to
// FileStream(String, FileMode.Open, FileAccess.Read, FileShare.Read).
// So the file is locked.
//
using( FileStream file = File.OpenRead( filename ) )
{
//
// Use a stream that validates the xml against internally stored schemas.
//
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreWhitespace = false;
settings.IgnoreProcessingInstructions = false;
settings.IgnoreComments = true;
using( XmlReader reader = InfoCardSchemas.CreateReader( file, settings ) )
{
RetrieveIssuerAndCheckSign( reader );
file.Seek( 0, SeekOrigin.Begin );
settings = InfoCardSchemas.CreateDefaultReaderSettings();
settings.IgnoreWhitespace = false;
using( XmlReader inner = InfoCardSchemas.CreateReader( file, settings ) )
{
while( inner.Read() )
{
if( inner.LocalName == XmlNames.WSIdentity.InfoCardElement )
{
m_card.ReadXml( inner );
break;
}
}
//
// Make sure that there is only one card per file and we have reached the end signature element
//
inner.Read();
if( XmlNames.XmlDSig.Signature != inner.LocalName || XmlNodeType.EndElement != inner.NodeType )
{
throw IDT.ThrowHelperError(
new ImportException( SR.GetString( SR.InvalidImportFile ) ) );
}
}
}
}
}
catch( XmlSchemaValidationException e )
{
throw IDT.ThrowHelperError(
new ImportException( SR.GetString( SR.InvalidImportFile ), e ) );
}
catch( CryptographicException e )
{
throw IDT.ThrowHelperError(
new ImportException( SR.GetString( SR.InvalidImportFile ), e ) );
}
catch( UnauthorizedAccessException e )
{
throw IDT.ThrowHelperError(
new ImportException( SR.GetString( SR.ImportInaccesibleFile ), e ) );
}
catch( FileNotFoundException e )
{
throw IDT.ThrowHelperError(
new ImportException( SR.GetString( SR.ImportFileNotFound ), e ) );
}
catch( IOException e )
{
throw IDT.ThrowHelperError(
new ImportException( SR.GetString( SR.InvalidImportFile ), e ) );
}
}
//
// Summary
// Retrive the issuer of the infocard. this function also checks the signature
//
// Parameters
// The filename to read data from
//
private void RetrieveIssuerAndCheckSign( XmlReader reader )
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.PreserveWhitespace = true;
xmlDocument.Load( reader );
XmlNamespaceManager mgr = XmlNames.CreateNamespaceManager( xmlDocument.NameTable );
if( XmlNames.XmlDSig.Signature != xmlDocument.DocumentElement.LocalName
&& XmlNames.XmlDSig.Namespace == xmlDocument.DocumentElement.NamespaceURI )
{
throw IDT.ThrowHelperError( new IdentityValidationException(
SR.GetString( SR.SignatureNotVerified ) ) );
}
//
// Check the signature
//
SignedXml signedXml = new SignedXml( xmlDocument );
signedXml.LoadXml( xmlDocument.DocumentElement );
//
// check if appropriate transforms and algorithms are used
//
if( null == signedXml.Signature ||
null == signedXml.Signature.ObjectList ||
null == signedXml.Signature.SignedInfo ||
null == signedXml.Signature.SignedInfo.References ||
null == ( (Reference)signedXml.Signature.SignedInfo.References[ 0 ] ).TransformChain )
{
throw IDT.ThrowHelperError( new IdentityValidationException( SR.GetString( SR.SignatureNotVerified ) ) );
}
//
// verify there is a single object, a single reference and a single transform specified
//
if( signedXml.Signature.ObjectList.Count != 1 ||
signedXml.Signature.SignedInfo.References.Count != 1 ||
( (Reference)signedXml.Signature.SignedInfo.References[ 0 ] ).TransformChain.Count != 1 )
{
throw IDT.ThrowHelperError( new IdentityValidationException( SR.GetString( SR.SignatureNotVerified ) ) );
}
//
// verify the algorithms
//
string transformAlg = ( (Reference)signedXml.Signature.SignedInfo.References[ 0 ] ).TransformChain[ 0 ].Algorithm;
if( signedXml.Signature.SignedInfo.SignatureMethod != SignedXml.XmlDsigRSASHA1Url ||
( SignedXml.XmlDsigExcC14NTransformUrl != transformAlg &&
SignedXml.XmlDsigExcC14NWithCommentsTransformUrl != transformAlg ) ||
SignedXml.XmlDsigExcC14NTransformUrl != signedXml.Signature.SignedInfo.CanonicalizationMethodObject.Algorithm ||
SignedXml.XmlDsigSHA1Url != ( (Reference)signedXml.Signature.SignedInfo.References[ 0 ] ).DigestMethod )
{
throw IDT.ThrowHelperError( new IdentityValidationException( SR.GetString( SR.SignatureNotVerified ) ) );
}
if( null == signedXml.KeyInfo )
{
throw IDT.ThrowHelperError( new IdentityValidationException( SR.GetString( SR.SignatureNotVerified ) ) );
}
//
// Retrieve the certificate from the signature
// We need to ensure that there is a valid X509Data element
//
XmlNodeList nodeList = signedXml.KeyInfo.GetXml().ChildNodes;
KeyInfoX509Data data = new KeyInfoX509Data();
//
// Iterate through all the elements in Keyinfo to find X509Data
//
foreach( XmlNode node in nodeList )
{
if( XmlNames.XmlDSig.Namespace == node.NamespaceURI && XmlNames.XmlDSig.X509DataElement == node.Name )
{
data.LoadXml( (XmlElement)node );
break;
}
}
ArrayList list = data.Certificates;
if( null != list && list.Count > 0 )
{
m_issuer = (X509Certificate2)list[ 0 ];
m_additionalIssuerCerts = new X509Certificate2Collection();
for( int i = 1; i < list.Count; i++ )
{
m_additionalIssuerCerts.Add( ( X509Certificate2 ) list[ i ] );
}
}
else
{
throw IDT.ThrowHelperError( new IdentityValidationException( SR.GetString( SR.NoCertificateFoundInSignature ) ) );
}
//
// Verify chain or peer trusted. Either machine or user roots are ok.
//
try
{
InfoCardX509Validator.ValidateChainOrPeer( m_issuer, m_additionalIssuerCerts, out m_isIssuerChainTrusted );
}
catch( SecurityTokenValidationException validationE )
{
throw IDT.ThrowHelperError(
new IdentityValidationException( validationE.Message ) );
}
//
// verify the signature
//
if( m_checkSignature )
{
if( !signedXml.CheckSignature( m_issuer, true ) )
{
throw IDT.ThrowHelperError( new IdentityValidationException( SR.GetString( SR.SignatureNotVerified ) ) );
}
}
}
}
}
// 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
- EncodingInfo.cs
- ReflectionTypeLoadException.cs
- ContentWrapperAttribute.cs
- TextUtf8RawTextWriter.cs
- NativeStructs.cs
- IOException.cs
- ResXResourceWriter.cs
- PrivacyNoticeBindingElement.cs
- CustomDictionarySources.cs
- ReflectionPermission.cs
- EncodingDataItem.cs
- CornerRadiusConverter.cs
- VisualBrush.cs
- CqlLexerHelpers.cs
- ActivityExecutionContext.cs
- ApplicationSettingsBase.cs
- AttributeAction.cs
- CheckBoxList.cs
- OrderablePartitioner.cs
- WindowInteractionStateTracker.cs
- EdmComplexPropertyAttribute.cs
- BinaryMethodMessage.cs
- BidPrivateBase.cs
- BitmapEffect.cs
- SignedInfo.cs
- DescriptionCreator.cs
- RepeatInfo.cs
- ResourceSet.cs
- BrushValueSerializer.cs
- ClientApiGenerator.cs
- SchemaNames.cs
- MsmqInputSessionChannelListener.cs
- iisPickupDirectory.cs
- BoundField.cs
- GridViewCancelEditEventArgs.cs
- ExpressionPrinter.cs
- ZoneButton.cs
- RuleSettings.cs
- parserscommon.cs
- TextElementEnumerator.cs
- MenuAutomationPeer.cs
- BadImageFormatException.cs
- Claim.cs
- CopyNamespacesAction.cs
- HwndSubclass.cs
- IISUnsafeMethods.cs
- ParameterCollection.cs
- EntityDataSourceDataSelection.cs
- SerialStream.cs
- CompressEmulationStream.cs
- XmlWrappingReader.cs
- ToolStripOverflow.cs
- CommandPlan.cs
- ComponentChangedEvent.cs
- ListCollectionView.cs
- ArrayWithOffset.cs
- SiteMapProvider.cs
- SaveFileDialog.cs
- WorkflowEventArgs.cs
- OleDbParameterCollection.cs
- WorkflowQueue.cs
- TypeConstant.cs
- PhoneCall.cs
- DocumentSequenceHighlightLayer.cs
- ObjectConverter.cs
- SimpleApplicationHost.cs
- RectAnimation.cs
- ViewManager.cs
- KoreanCalendar.cs
- BrushValueSerializer.cs
- ResXFileRef.cs
- DataControlFieldCell.cs
- TextContainer.cs
- DbDeleteCommandTree.cs
- InkCanvas.cs
- PersonalizableTypeEntry.cs
- ContextQuery.cs
- ContentType.cs
- ApplicationDirectoryMembershipCondition.cs
- FormatterConverter.cs
- IDReferencePropertyAttribute.cs
- PKCS1MaskGenerationMethod.cs
- DragSelectionMessageFilter.cs
- WebServiceEnumData.cs
- SelectionService.cs
- CqlWriter.cs
- ExpressionLink.cs
- SoapWriter.cs
- NamespaceInfo.cs
- BindingBase.cs
- DataServiceQueryOfT.cs
- BridgeDataReader.cs
- COM2Enum.cs
- PropertyDescriptorComparer.cs
- XPathEmptyIterator.cs
- ScalarRestriction.cs
- CanonicalXml.cs
- XmlNodeChangedEventManager.cs
- DriveInfo.cs
- URLString.cs