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
- MDIWindowDialog.cs
- TextFindEngine.cs
- SecurityVerifiedMessage.cs
- GridViewColumnCollection.cs
- ColorKeyFrameCollection.cs
- SoapTransportImporter.cs
- LinkConverter.cs
- ProcessHostFactoryHelper.cs
- PassportAuthenticationModule.cs
- DataGridViewUtilities.cs
- Publisher.cs
- OperationAbortedException.cs
- ValidatingCollection.cs
- ClientWindowsAuthenticationMembershipProvider.cs
- FormViewInsertEventArgs.cs
- TextEffectCollection.cs
- Activator.cs
- DbParameterCollection.cs
- IPAddress.cs
- ArraySegment.cs
- Int16Converter.cs
- ScriptingProfileServiceSection.cs
- StandardMenuStripVerb.cs
- DataBinder.cs
- TimeSpanSecondsOrInfiniteConverter.cs
- StyleSelector.cs
- Math.cs
- OperatingSystem.cs
- SqlUdtInfo.cs
- ExtenderProvidedPropertyAttribute.cs
- X509CertificateStore.cs
- GPRECTF.cs
- Normalization.cs
- ToolStripItemTextRenderEventArgs.cs
- CodeEntryPointMethod.cs
- WebServiceData.cs
- PrintDocument.cs
- Button.cs
- DrawingState.cs
- BindingSourceDesigner.cs
- SerialReceived.cs
- ObjectStateManager.cs
- documentsequencetextpointer.cs
- InputManager.cs
- FaultReason.cs
- DockPattern.cs
- Soap12ServerProtocol.cs
- RegistryDataKey.cs
- BinaryParser.cs
- KeyMatchBuilder.cs
- RoutingExtensionElement.cs
- FormViewDeletedEventArgs.cs
- OleDbPermission.cs
- ComAdminInterfaces.cs
- OleDbConnectionPoolGroupProviderInfo.cs
- ScaleTransform3D.cs
- ThreadExceptionEvent.cs
- SortDescription.cs
- OrderablePartitioner.cs
- COM2ExtendedUITypeEditor.cs
- EntityProviderServices.cs
- Annotation.cs
- CustomWebEventKey.cs
- VersionedStream.cs
- SerialPort.cs
- TrustManagerMoreInformation.cs
- ContentPlaceHolderDesigner.cs
- SqlDataSourceCache.cs
- ExtensionSimplifierMarkupObject.cs
- XPathNode.cs
- EntityType.cs
- SqlTrackingService.cs
- CreateRefExpr.cs
- DateTimeUtil.cs
- ModelTreeEnumerator.cs
- ChildTable.cs
- StorageAssociationSetMapping.cs
- CodeBinaryOperatorExpression.cs
- WebPartRestoreVerb.cs
- SpAudioStreamWrapper.cs
- InlineUIContainer.cs
- PropertyMetadata.cs
- ViewStateModeByIdAttribute.cs
- LayoutUtils.cs
- GridSplitter.cs
- InnerItemCollectionView.cs
- RoutedEventArgs.cs
- XmlSchemaAnyAttribute.cs
- WebPartConnectionsCancelEventArgs.cs
- SqlNodeAnnotation.cs
- RadioButtonAutomationPeer.cs
- DateTimeFormatInfoScanner.cs
- SafeHandles.cs
- NamespaceEmitter.cs
- HttpHandlerAction.cs
- VSWCFServiceContractGenerator.cs
- FontResourceCache.cs
- TdsParserHelperClasses.cs
- PauseStoryboard.cs
- AttachmentCollection.cs