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
- XmlReaderSettings.cs
- infer.cs
- SqlBulkCopyColumnMapping.cs
- IISUnsafeMethods.cs
- DataMisalignedException.cs
- ReadOnlyDataSourceView.cs
- RequestBringIntoViewEventArgs.cs
- RequestCachingSection.cs
- NotFiniteNumberException.cs
- GlyphRunDrawing.cs
- StreamUpdate.cs
- CompilerGlobalScopeAttribute.cs
- SafeRegistryKey.cs
- DelegatingTypeDescriptionProvider.cs
- DataColumnMappingCollection.cs
- PipelineComponent.cs
- ShapingWorkspace.cs
- BevelBitmapEffect.cs
- UniqueContractNameValidationBehavior.cs
- GeneratedCodeAttribute.cs
- InternalConfigHost.cs
- Color.cs
- BindingNavigator.cs
- DataGridViewCellCollection.cs
- EndpointDiscoveryBehavior.cs
- TextBlockAutomationPeer.cs
- XmlExtensionFunction.cs
- ToolboxBitmapAttribute.cs
- CheckBoxField.cs
- CommonProperties.cs
- DependencyPropertyHelper.cs
- ISAPIRuntime.cs
- PopOutPanel.cs
- QueryParameter.cs
- DocumentViewerAutomationPeer.cs
- Pens.cs
- WebPartConnectionCollection.cs
- LabelExpression.cs
- FileUtil.cs
- RuntimeConfig.cs
- InkCanvas.cs
- FontStyleConverter.cs
- MemberRelationshipService.cs
- HierarchicalDataSourceIDConverter.cs
- DbInsertCommandTree.cs
- ArrayConverter.cs
- DriveNotFoundException.cs
- MethodBuilder.cs
- QuotedPrintableStream.cs
- UIElement.cs
- WindowsAuthenticationModule.cs
- PageParser.cs
- EntityDataSourceWrapper.cs
- ToolStripProfessionalLowResolutionRenderer.cs
- TextCharacters.cs
- SingleConverter.cs
- Column.cs
- DebuggerAttributes.cs
- GenerateTemporaryTargetAssembly.cs
- SecurityElement.cs
- ContainerControl.cs
- TimersDescriptionAttribute.cs
- Scheduling.cs
- NegatedCellConstant.cs
- WeakReferenceList.cs
- HyperLinkColumn.cs
- GeometryGroup.cs
- WorkflowServiceNamespace.cs
- GiveFeedbackEventArgs.cs
- EventEntry.cs
- ValidationHelpers.cs
- Message.cs
- CombinedGeometry.cs
- EncodingNLS.cs
- TypeToken.cs
- DependencyObjectValidator.cs
- DispatcherHooks.cs
- InputChannelAcceptor.cs
- ViewgenGatekeeper.cs
- OciHandle.cs
- MasterPageBuildProvider.cs
- safePerfProviderHandle.cs
- SQLDoubleStorage.cs
- TextContainerChangeEventArgs.cs
- LinqTreeNodeEvaluator.cs
- SerializationSectionGroup.cs
- ServiceHostFactory.cs
- SecurityContextTokenCache.cs
- DependencyPropertyDescriptor.cs
- ListDesigner.cs
- StringComparer.cs
- XmlSchemaChoice.cs
- ReaderOutput.cs
- XmlQualifiedName.cs
- FaultReasonText.cs
- BinaryParser.cs
- oledbmetadatacolumnnames.cs
- OptimizerPatterns.cs
- ResourceAssociationSetEnd.cs
- CompiledQuery.cs