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
- DistinctQueryOperator.cs
- FontSourceCollection.cs
- SelectorItemAutomationPeer.cs
- TextEditorTables.cs
- Soap12ProtocolImporter.cs
- AbstractExpressions.cs
- CopyCodeAction.cs
- BaseParaClient.cs
- BuildDependencySet.cs
- Main.cs
- HttpModuleCollection.cs
- EntityConnection.cs
- HttpStaticObjectsCollectionBase.cs
- DynamicDocumentPaginator.cs
- PageStatePersister.cs
- DatagridviewDisplayedBandsData.cs
- AnnotationObservableCollection.cs
- Pts.cs
- SafeProcessHandle.cs
- AssertSection.cs
- Bold.cs
- UnicodeEncoding.cs
- storepermissionattribute.cs
- TrustManagerMoreInformation.cs
- LicenseManager.cs
- XPathMultyIterator.cs
- FontWeightConverter.cs
- XmlSchemaValidationException.cs
- OleDbTransaction.cs
- UnwrappedTypesXmlSerializerManager.cs
- FontWeights.cs
- AggregateNode.cs
- XsltSettings.cs
- LoginName.cs
- MessageAction.cs
- RowsCopiedEventArgs.cs
- Storyboard.cs
- UnauthorizedAccessException.cs
- PropertyGridEditorPart.cs
- COSERVERINFO.cs
- RectConverter.cs
- RijndaelManaged.cs
- UserMapPath.cs
- ReflectionTypeLoadException.cs
- DesignConnection.cs
- VolatileEnlistmentMultiplexing.cs
- ControlOperationInvoker.cs
- SupportingTokenListenerFactory.cs
- AssemblySettingAttributes.cs
- CodeCommentStatementCollection.cs
- NegatedConstant.cs
- ErrorProvider.cs
- RelationshipConverter.cs
- DrawingAttributeSerializer.cs
- SiteMapSection.cs
- SQLResource.cs
- Keyboard.cs
- NoClickablePointException.cs
- CombinedGeometry.cs
- XmlArrayAttribute.cs
- ControlIdConverter.cs
- WebPartVerbCollection.cs
- BitHelper.cs
- StringUtil.cs
- ReadOnlyHierarchicalDataSource.cs
- PerspectiveCamera.cs
- StyleSheet.cs
- DeferredReference.cs
- NetDataContractSerializer.cs
- XamlToRtfParser.cs
- TrackingRecord.cs
- DataBoundControlActionList.cs
- TextDocumentView.cs
- DoubleLinkList.cs
- SafeHandle.cs
- ThreadPoolTaskScheduler.cs
- DataContractSerializerOperationFormatter.cs
- ExtensionQuery.cs
- CodeArrayCreateExpression.cs
- IPCCacheManager.cs
- ActivityPreviewDesigner.cs
- DataGridItem.cs
- HostingEnvironmentSection.cs
- StateItem.cs
- PackagingUtilities.cs
- AutomationTextAttribute.cs
- RtfToken.cs
- EdmItemError.cs
- MissingSatelliteAssemblyException.cs
- bindurihelper.cs
- DiscardableAttribute.cs
- Control.cs
- HttpCapabilitiesBase.cs
- SystemSounds.cs
- x509utils.cs
- IdentityValidationException.cs
- XmlIlGenerator.cs
- StateMachineAction.cs
- FamilyTypeface.cs
- DesignerOptions.cs