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
- ThumbAutomationPeer.cs
- TraceRecord.cs
- ExpressionBuilderCollection.cs
- DoubleIndependentAnimationStorage.cs
- ExtendedPropertyCollection.cs
- DeclaredTypeValidator.cs
- SystemResourceHost.cs
- StrokeRenderer.cs
- WindowPattern.cs
- Accessible.cs
- PromptStyle.cs
- UnknownBitmapDecoder.cs
- PrtTicket_Base.cs
- ScrollProviderWrapper.cs
- sqlinternaltransaction.cs
- StringFreezingAttribute.cs
- GiveFeedbackEventArgs.cs
- CacheDict.cs
- ProfileProvider.cs
- ImageDesigner.cs
- StringArrayConverter.cs
- ExtensionSimplifierMarkupObject.cs
- EntityClientCacheKey.cs
- RuleElement.cs
- ActivityExecutionContext.cs
- DataTableMappingCollection.cs
- ResourcePropertyMemberCodeDomSerializer.cs
- FreezableCollection.cs
- OptimizedTemplateContentHelper.cs
- Serializer.cs
- ConnectionManagementSection.cs
- RSAPKCS1SignatureDeformatter.cs
- ProtocolsConfigurationEntry.cs
- CqlGenerator.cs
- ISO2022Encoding.cs
- FloatUtil.cs
- Image.cs
- ExecutionContext.cs
- EncryptedData.cs
- DbConnectionStringCommon.cs
- PublisherIdentityPermission.cs
- MouseActionValueSerializer.cs
- ValueTypeFixupInfo.cs
- ToolboxItemSnapLineBehavior.cs
- Pair.cs
- UserControl.cs
- ConstraintConverter.cs
- FileRecordSequence.cs
- BatchStream.cs
- MimeMapping.cs
- PageTheme.cs
- Keywords.cs
- ScriptReferenceEventArgs.cs
- BamlCollectionHolder.cs
- controlskin.cs
- OrderPreservingPipeliningMergeHelper.cs
- DictionaryTraceRecord.cs
- WindowsSysHeader.cs
- Attachment.cs
- Type.cs
- AnonymousIdentificationSection.cs
- IdentityNotMappedException.cs
- ConnectionConsumerAttribute.cs
- ExtractedStateEntry.cs
- webproxy.cs
- HandlerFactoryWrapper.cs
- AdornerDecorator.cs
- Debug.cs
- TogglePattern.cs
- DesigntimeLicenseContext.cs
- AttachedPropertyMethodSelector.cs
- HMACSHA384.cs
- PreviousTrackingServiceAttribute.cs
- StateMachineTimers.cs
- ControlDesigner.cs
- OlePropertyStructs.cs
- CustomError.cs
- BaseCAMarshaler.cs
- Timer.cs
- WinInetCache.cs
- CDSsyncETWBCLProvider.cs
- RangeValuePattern.cs
- ScriptingAuthenticationServiceSection.cs
- LogicalTreeHelper.cs
- Visual3DCollection.cs
- StoreAnnotationsMap.cs
- CodeIdentifiers.cs
- SplitContainer.cs
- CollectionType.cs
- PropertyDescriptorGridEntry.cs
- SimpleTextLine.cs
- LinearGradientBrush.cs
- CompoundFileDeflateTransform.cs
- HttpRequest.cs
- DocumentScope.cs
- Hashtable.cs
- Primitive.cs
- AnnotationObservableCollection.cs
- TypeContext.cs
- dsa.cs