Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / infocard / Service / managed / Microsoft / InfoCards / RequestSecurityTokenResponse.cs / 1 / RequestSecurityTokenResponse.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- // // Presharp uses the c# pragma mechanism to supress its warnings. // These are not recognised by the base compiler so we need to explictly // disable the following warnings. See http://winweb/cse/Tools/PREsharp/userguide/default.asp // for details. // #pragma warning disable 1634, 1691 // unknown message, unknown pragma namespace Microsoft.InfoCards { using System; using System.IO; using System.Xml; using System.Collections.Generic; using System.Security.Cryptography; using System.IdentityModel.Tokens; using System.IdentityModel.Selectors; using System.IdentityModel.Policy; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Security; using System.ServiceModel.Security.Tokens; using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace; static class RequestSecurityTokenResponseHelper { // Proof token is required for GenericXmlSecurityToken, and // eliminating GenericXmlSecurityToken would cause a lot of // code churn and risk at this point. This username token // should be harmless. private static SecurityToken s_noProofToken = new UserNameSecurityToken( "noproof", "noproof", "noproof" ); class RequestSecurityTokenResponse { // // Set it to default here. // int m_keySize; bool m_keySizeSpecified; DateTime m_created = DateTime.UtcNow; DateTime m_expires = DateTime.UtcNow.AddHours( 1 ); // // Required non-normative // string m_requestType; // // Can be null // SecurityKeyIdentifierClause m_requestedAttachedReference; SecurityKeyIdentifierClause m_requestedUnattachedReference; SecurityToken m_entropyToken; string m_computedKeyAlgorithm; DisplayToken m_displayToken; SecurityKeyTypeInternal? m_keyType; // // We are not really using this property usefully. // Would have been good if GerericXmlToken accepted this // as one of the args. // string m_tokenType; // // We'll validate // XmlElement m_issuedTokenElement; SecurityToken m_proofToken; public int KeySize { set { m_keySize = value; m_keySizeSpecified = true; } } public int GetIntelligentKeySize( bool symmetric, int rstKeySize ) { if( symmetric ) { if( !m_keySizeSpecified ) { // // Just use the same keySize we sent (becuase the IP/STS did not override keySize) // return rstKeySize; } else { return m_keySize; } } else { // // Should not access this property otherwise // throw IDT.ThrowHelperError( new InvalidOperationException() ); } } public SecurityKeyTypeInternal? KeyType { get { return m_keyType; } set { m_keyType = value; } } public DateTime Created { get { return m_created; } set { m_created = value; } } public DateTime Expires { get { return m_expires; } set { m_expires = value; } } public SecurityKeyIdentifierClause RequestedAttachedReference { get { return m_requestedAttachedReference; } set { m_requestedAttachedReference = value; } } public SecurityKeyIdentifierClause RequestedUnattachedReference { get { return m_requestedUnattachedReference; } set { m_requestedUnattachedReference = value; } } public string TokenType { set { m_tokenType = value; } } public SecurityToken EntropyToken { get { return m_entropyToken; } set { m_entropyToken = value; } } public string ComputedKeyAlgorithm { get { return m_computedKeyAlgorithm; } set { m_computedKeyAlgorithm = value; } } public DisplayToken DisplayToken { get { return m_displayToken; } set { m_displayToken = value; } } public XmlElement IssuedTokenElement { get { return m_issuedTokenElement; } set { m_issuedTokenElement = value; } } public SecurityToken ProofToken { get { return m_proofToken; } set { m_proofToken = value; } } public string RequestType { get { return m_requestType; } set { m_requestType = value; } } // // We could parse wst:SignatureAlgorithm, wst:EncryptionAlgorithm, // wst:CanonicalizationAlgorithm, as well - in case the IP/STS did not honor what // was requested or did not use the defaults. However this is of no use to us. // The token is considered opaque to the Infocard subsystem. // public static byte[] ComputeCombinedKey( byte[] requestorEntropy, byte[] issuerEntropy, int keySize ) { if( requestorEntropy == null ) { throw IDT.ThrowHelperArgumentNull( "requestorEntropy" ); } if( issuerEntropy == null ) { throw IDT.ThrowHelperArgumentNull( "issuerEntropy" ); } IDT.Assert( keySize > 0, "Keysize must be > 0" ); Psha1DerivedKeyGenerator generator = new Psha1DerivedKeyGenerator( requestorEntropy ); return generator.GenerateDerivedKey( new byte[] { }, issuerEntropy, keySize, 0 ); } public void ValidateRstrContents( SecurityKeyTypeInternal keyTypeExpected ) { if( null == IssuedTokenElement ) { throw IDT.ThrowHelperError( new InvalidOperationException( SR.GetString( SR.NoIssuedTokenXml ) ) ); } if( KeyType != null && keyTypeExpected != KeyType ) { throw IDT.ThrowHelperError( new InvalidOperationException( SR.GetString( SR.ProofKeyTypeMismatch ) ) ); } if( SecurityKeyTypeInternal.SymmetricKey == keyTypeExpected ) { } else if( SecurityKeyTypeInternal.AsymmetricKey == keyTypeExpected ) { // // enforce that there is no proof token in the RSTR // if( null != ProofToken ) { throw IDT.ThrowHelperError( new InvalidOperationException( SR.GetString( SR.ProofTokenXmlUnexpectedInRstr ) ) ); } } else { IDT.Assert( SecurityKeyTypeInternal.NoKey == keyTypeExpected, "Bad enum member for SecurityKeyTypeInternal" ); // // enforce that there is no proof token in the RSTR // if( null != ProofToken ) { throw IDT.ThrowHelperError( new InvalidOperationException( SR.GetString( SR.ProofTokenXmlUnexpectedInRstr ) ) ); } } } } // // Summary // Retrieve data from the RSTR // // Parameters // reader - the reader positioned at// tokenSerializer - the token serializer to deserialize proof and entropy tokens in RSTR // tokenResolver - optional token resolver needed by the token serializer while deserializing tokens // static RequestSecurityTokenResponse ReadRequestSecurityTokenResponse( XmlDictionaryReader reader, SecurityTokenSerializer tokenSerializer, SecurityTokenResolver resolver, ProtocolProfile profile ) { IDT.Assert( null != reader, "null reader" ); IDT.Assert( null != tokenSerializer, "null tokenSerializer" ); RequestSecurityTokenResponse rstr = new RequestSecurityTokenResponse(); // // If the protocol version we are using is Oasis 2007, we need to read the opening element of // the RequestSecurityTokenResponseCollection first. // if( XmlNames.WSSpecificationVersion.WSTrustOasis2007 == profile.WSTrust.Version ) { reader.ReadFullStartElement( profile.WSTrust.RequestSecurityTokenResponseCollection, profile.WSTrust.Namespace ); } // // Retrieve the protected token from the xml // IDT.TraceDebug( "IPSTSCLIENT: Retrieving the security token from the RSTR xml" ); reader.ReadFullStartElement( profile.WSTrust.RequestSecurityTokenResponse, profile.WSTrust.Namespace ); bool readTokenType = false; bool readKeyType = false; bool readKeySize = false; bool readAttachedReference = false; bool readUnattachedReference = false; bool readLifetime = false; bool readIssuedToken = false; bool readProofToken = false; bool readDisplayToken = false; bool readEntropy = false; bool readRequestType = false; rstr.Created = DateTime.UtcNow; rstr.Expires = new DateTime( ( DateTime.MaxValue.Ticks - TimeSpan.FromDays( 2 ).Ticks ), DateTimeKind.Utc ); if( !reader.IsStartElement() ) { // // If the content is not an xml node, then we are dealing with invalid xml. // throw IDT.ThrowHelperError( new XmlException( SR.GetString( SR.ServiceSTSCommunicationFailed ) ) ); } while( reader.IsStartElement() ) { if( reader.IsStartElement( profile.WSTrust.TokenType, profile.WSTrust.Namespace ) ) { if( readTokenType ) { throw IDT.ThrowHelperError( new XmlException( SR.GetString( SR.MultipleTokenTypeElementsFound ) ) ); } rstr.TokenType = reader.ReadElementString(); readTokenType = true; } else if( reader.IsStartElement( profile.WSTrust.KeySize, profile.WSTrust.Namespace ) ) { if( readKeySize ) { throw IDT.ThrowHelperError( new XmlException( SR.GetString( SR.MultipleKeySizeElementsFound ) ) ); } int theKeySize = reader.ReadElementContentAsInt(); if( theKeySize <= 0 ) { throw IDT.ThrowHelperError( new InvalidOperationException( SR.GetString( SR.KeySizeMustBeGreaterThanZero ) ) ); } rstr.KeySize = theKeySize; readKeySize = true; } else if( reader.IsStartElement( profile.WSTrust.KeyType, profile.WSTrust.Namespace ) ) { if( readKeyType ) { throw IDT.ThrowHelperError( new XmlException( SR.GetString( SR.MultipleKeySizeElementsFound ) ) ); } string theKeyType = reader.ReadElementContentAsString(); Uri keyTypeUri = new Uri( theKeyType ); if( profile.WSTrust.KeyTypeSymmetric.Equals( keyTypeUri ) ) { rstr.KeyType = SecurityKeyTypeInternal.SymmetricKey; } else if( profile.WSTrust.KeyTypeAsymmetric.Equals( keyTypeUri ) ) { rstr.KeyType = SecurityKeyTypeInternal.AsymmetricKey; } else if( profile.WSTrust.KeyTypeBearer.Equals( keyTypeUri ) ) { rstr.KeyType = SecurityKeyTypeInternal.NoKey; } else { throw IDT.ThrowHelperError( new XmlException( SR.GetString( SR.KeyTypeNotRecognized, theKeyType ) ) ); } readKeyType = true; } else if( reader.IsStartElement( profile.WSTrust.Lifetime, profile.WSTrust.Namespace ) ) { if( readLifetime ) { throw IDT.ThrowHelperError( new XmlException( SR.GetString( SR.MultipleLifetimeElementsFound ) ) ); } reader.ReadStartElement(); if( reader.IsStartElement( XmlNames.WSSecurityUtility.Created, XmlNames.WSSecurityUtility.Namespace ) ) { rstr.Created = reader.ReadElementContentAsDateTime().ToUniversalTime(); } if( reader.IsStartElement( XmlNames.WSSecurityUtility.Expires, XmlNames.WSSecurityUtility.Namespace ) ) { rstr.Expires = reader.ReadElementContentAsDateTime().ToUniversalTime(); } reader.ReadEndElement(); // wst:Lifetime readLifetime = true; } else if( reader.IsStartElement( profile.WSTrust.RequestedSecurityToken, profile.WSTrust.Namespace ) ) { if( readIssuedToken ) { throw IDT.ThrowHelperError( new XmlException( SR.GetString( SR.MultipleRequestedSecurityTokenElementsFound ) ) ); } reader.ReadStartElement(); reader.MoveToElement(); XmlDocument document = new XmlDocument(); rstr.IssuedTokenElement = document.ReadNode( reader ) as XmlElement; reader.ReadEndElement(); // wst:RequestedSecurityToken readIssuedToken = true; } else if( reader.IsStartElement( profile.WSTrust.RequestedProofToken, profile.WSTrust.Namespace ) ) { if( readProofToken ) { throw IDT.ThrowHelperError( new XmlException( SR.GetString( SR.MultipleRequestedProofTokenElementsFound ) ) ); } reader.ReadStartElement(); if( reader.IsStartElement( profile.WSTrust.ComputedKey, profile.WSTrust.Namespace ) ) { rstr.ComputedKeyAlgorithm = reader.ReadElementString(); if( profile.WSTrust.ComputedKeyAlgorithm != rstr.ComputedKeyAlgorithm ) { throw IDT.ThrowHelperError( new NotImplementedException ( SR.GetString( SR.OnlyPSha1SupportedCurrently, rstr.ComputedKeyAlgorithm ) ) ); } } else { rstr.ProofToken = tokenSerializer.ReadToken( reader, resolver ); } reader.ReadEndElement(); // wst:RequestedProofToken readProofToken = true; } else if( reader.IsStartElement( profile.WSTrust.Entropy, profile.WSTrust.Namespace ) ) { if( readEntropy ) { throw IDT.ThrowHelperError( new XmlException( SR.GetString( SR.MultipleEntropyElementsFound ) ) ); } reader.ReadStartElement(); rstr.EntropyToken = tokenSerializer.ReadToken( reader, resolver ); reader.ReadEndElement(); readEntropy = true; } else if( reader.IsStartElement( XmlNames.WSIdentity.RequestedDisplayTokenElement, XmlNames.WSIdentity.Namespace ) ) { if( readDisplayToken ) { throw IDT.ThrowHelperError( new XmlException( SR.GetString( SR.MultipleRequestedDisplayTokenElementsFound ) ) ); } rstr.DisplayToken = CreateDisplayToken( reader ); readDisplayToken = true; } else if( reader.IsStartElement( profile.WSTrust.RequestedAttachedReference, profile.WSTrust.Namespace ) ) { if( readAttachedReference ) { throw IDT.ThrowHelperError( new XmlException( SR.GetString( SR.MultipleRequestedAttachedReferenceElementsFound ) ) ); } reader.ReadStartElement(); rstr.RequestedAttachedReference = tokenSerializer.ReadKeyIdentifierClause( reader ); reader.ReadEndElement(); // wst:RequestedAttachedReference readAttachedReference = true; } else if( reader.IsStartElement( profile.WSTrust.RequestedUnattachedReference, profile.WSTrust.Namespace ) ) { if( readUnattachedReference ) { throw IDT.ThrowHelperError( new XmlException( SR.GetString( SR.MultipleRequestedUnattachedReferenceElementsFound ) ) ); } reader.ReadStartElement(); rstr.RequestedUnattachedReference = tokenSerializer.ReadKeyIdentifierClause( reader ); reader.ReadEndElement(); // wst:RequestedUnattachedReference readUnattachedReference = true; } else if( reader.IsStartElement( profile.WSTrust.RequestType, profile.WSTrust.Namespace ) ) { if( readRequestType ) { throw IDT.ThrowHelperError( new XmlException( SR.GetString( SR.MultipleRequestTypeElementsFound ) ) ); } rstr.RequestType = reader.ReadElementContentAsString(); // // We only support this currently // if( profile.WSTrust.IssueRequestType != rstr.RequestType ) { throw IDT.ThrowHelperError( new InvalidOperationException( SR.GetString( SR.OnlyIssueRequestTypeSupported, rstr.RequestType, profile.WSTrust.IssueRequestType ) ) ); } readRequestType = true; } else { reader.Skip(); } } // // RequestSecurityTokenResponse // reader.ReadEndElement(); // // If we are using the Oasis 2007 version of WSTrust, // read the element closing tag for ResquestSecurityTokenResponseCollection. // Since we do not support multiple RSTRs, we assert here if we fail to read // the closing element of the RSTR Collection. // if( XmlNames.WSSpecificationVersion.WSTrustOasis2007 == profile.WSTrust.Version ) { if( !( ( profile.WSTrust.RequestSecurityTokenResponseCollection == reader.LocalName ) && ( profile.WSTrust.Namespace == reader.NamespaceURI ) && ( reader.NodeType == XmlNodeType.EndElement ) ) ) { // // throw IDT.ThrowHelperError( new XmlException( SR.GetString( SR.ServiceSTSCommunicationFailed ) ) ); } reader.ReadEndElement(); } return rstr; } // // Summary // Retrieve bearer issued token from the RSTR // // Parameters // reader - the reader positioned at // tokenSerializer - the token serializer to deserialize proof and entropy tokens in RSTR // tokenResolver - optional token resolver needed by the token serializer while deserializing tokens // displayToken (out) - display token if present in the RSTR // public static GenericXmlSecurityToken ProcessBearerTokenData( XmlDictionaryReader reader, SecurityTokenSerializer tokenSerializer, SecurityTokenResolver resolver, ProtocolProfile profile, out DisplayToken displayToken ) { RequestSecurityTokenResponse rstr = ReadRequestSecurityTokenResponse( reader, tokenSerializer, resolver, profile ); displayToken = rstr.DisplayToken ?? new DisplayToken(); rstr.ValidateRstrContents( SecurityKeyTypeInternal.NoKey ); SecurityToken proofToken = s_noProofToken; return new GenericXmlSecurityToken( rstr.IssuedTokenElement, proofToken, rstr.Created, rstr.Expires, rstr.RequestedAttachedReference, rstr.RequestedUnattachedReference, null ); } // // Summary // Retrieve symmetric issued token from the RSTR // // Parameters // reader - the reader positioned at // tokenSerializer - the token serializer to deserialize proof and entropy tokens in RSTR // tokenResolver - optional token resolver needed by the token serializer while deserializing tokens // displayToken (out) - display token if present in the RSTR // public static GenericXmlSecurityToken ProcessSymmetricTokenData( XmlDictionaryReader reader, SecurityTokenSerializer tokenSerializer, SecurityTokenResolver resolver, byte[] clientEntropyForSymmetric, ProtocolProfile profile , out DisplayToken displayToken ) { RequestSecurityTokenResponse rstr = ReadRequestSecurityTokenResponse( reader, tokenSerializer, resolver, profile ); displayToken = rstr.DisplayToken ?? new DisplayToken(); rstr.ValidateRstrContents( SecurityKeyTypeInternal.SymmetricKey ); // // Handle no proof key, issuer entropy ONLY, recipient entropy, combined entropy // if( rstr.EntropyToken != null ) { IDT.Assert( profile.WSTrust.ComputedKeyAlgorithm == rstr.ComputedKeyAlgorithm, "We already made sure it is PSHA1 while processing RSTR" ); // // the wst:Entropy element allows for wst:BinarySecret or xenc:EncryptedKey // and if it is not decrypted by this point, the entropy information is not supported. // BinarySecretSecurityToken binToken = rstr.EntropyToken as BinarySecretSecurityToken; if( null != binToken ) { int rstKeySize = clientEntropyForSymmetric.Length * 8; int keySizeToUse = rstr.GetIntelligentKeySize( true, rstKeySize ); if( keySizeToUse != rstKeySize ) { throw IDT.ThrowHelperError( new InvalidOperationException( SR.SymmetricProofKeyLengthMismatch ) ); } byte[] symmetricProofKeyBytes = RequestSecurityTokenResponse.ComputeCombinedKey( clientEntropyForSymmetric, binToken.GetKeyBytes(), rstKeySize ); rstr.ProofToken = new BinarySecretSecurityToken( symmetricProofKeyBytes ); } else { // // The IP/STS probably sent an xenc:encryptedkey element in wst:rstr/wst:entropy // There is no apriori key esp. in the symmetric key case for us to be able to // decrypt this information, hence not supported. // throw IDT.ThrowHelperError( new TrustExchangeException( SR.GetString( SR.InvalidEntropyContents ) ) ); } } else if( rstr.ProofToken != null ) { // // Issuer ignored our entropy, nothing to do // } else { // // STS used our entropy // byte[] symmetricProofKeyBytes = clientEntropyForSymmetric; rstr.ProofToken = new BinarySecretSecurityToken( symmetricProofKeyBytes ); } return new GenericXmlSecurityToken( rstr.IssuedTokenElement, rstr.ProofToken, rstr.Created, rstr.Expires, rstr.RequestedAttachedReference, rstr.RequestedUnattachedReference, null ); } // // Summary // Retrieve asymmetric issued token from the RSTR // // Parameters // reader - the reader positioned at // tokenSerializer - the token serializer to deserialize proof and entropy tokens in RSTR // tokenResolver - optional token resolver needed by the token serializer while deserializing tokens // public static GenericXmlSecurityToken ProcessAsymmetricTokenData( XmlDictionaryReader reader, RSA rsa, SecurityTokenSerializer tokenSerializer, SecurityTokenResolver resolver, ProtocolProfile profile, out DisplayToken displayToken ) { IDT.Assert( null != rsa, "null rsa" ); RequestSecurityTokenResponse rstr = ReadRequestSecurityTokenResponse( reader, tokenSerializer, resolver, profile ); displayToken = rstr.DisplayToken ?? new DisplayToken(); rstr.ValidateRstrContents( SecurityKeyTypeInternal.AsymmetricKey ); SecurityToken proofToken = new RsaSecurityToken( rsa ); return new GenericXmlSecurityToken( rstr.IssuedTokenElement, proofToken, rstr.Created, rstr.Expires, rstr.RequestedAttachedReference, rstr.RequestedUnattachedReference, null ); } // // Summary // Construct the display token using information from the RSTR // // Parameters // reader - The reader positioned at the RequestSecurityTokenResponse/RequestedDisplayToken // // Returns // The display token // static DisplayToken CreateDisplayToken( XmlDictionaryReader reader ) { IDT.Assert( null != reader, "null reader" ); IDT.TraceDebug( "IPSTSCLIENT: Retrieving the display token from the RSTR xml" ); DisplayToken token = new DisplayToken(); XmlReader validatingReader = InfoCardSchemas.CreateReader( reader.ReadOuterXml() ); try { validatingReader.ReadStartElement( XmlNames.WSIdentity.RequestedDisplayTokenElement, XmlNames.WSIdentity.Namespace ); validatingReader.ReadStartElement( XmlNames.WSIdentity.DisplayTokenElement, XmlNames.WSIdentity.Namespace ); while( validatingReader.IsStartElement() ) { if( validatingReader.IsStartElement( XmlNames.WSIdentity.DisplayClaimElement, XmlNames.WSIdentity.Namespace ) ) { IDT.TraceDebug( "IPSTSCLIENT: Reading claims list from display token" ); List claims = new List (); while( validatingReader.IsStartElement() ) { if( validatingReader.IsStartElement( XmlNames.WSIdentity.DisplayClaimElement, XmlNames.WSIdentity.Namespace ) ) { DisplayClaim clm = ReadDisplayClaim( validatingReader ); if( null != clm ) { claims.Add( clm ); } } else { validatingReader.Skip(); } } token = new DisplayToken( claims ); } else if( validatingReader.IsStartElement( XmlNames.WSIdentity.DisplayTokenTextElement, XmlNames.WSIdentity.Namespace ) ) { IDT.TraceDebug( "IPSTSCLIENT: Reading claims text string from display token" ); string mimeType = validatingReader.GetAttribute( XmlNames.WSIdentity.MimeTypeAttribute ); string text = validatingReader.ReadElementContentAsString(); if( !String.IsNullOrEmpty( text ) && !String.IsNullOrEmpty( mimeType ) ) { token = new DisplayToken( text, mimeType ); } } else { validatingReader.Skip(); } } validatingReader.ReadEndElement(); // wsi:DisplayTokenElement validatingReader.ReadEndElement(); // wsi:RequestedDisplayTokenElement } catch( Exception e ) { token = null; if( IDT.IsFatal( e ) ) { throw; } } return token; } // // Summary // Read a display claim // // Parameters // Reader from which data is being read. // // Return // Display Claim // static DisplayClaim ReadDisplayClaim( XmlReader reader ) { // // read each display claim // if( !reader.IsStartElement( XmlNames.WSIdentity.DisplayClaimElement, XmlNames.WSIdentity.Namespace ) ) { throw IDT.ThrowHelperError( new XmlException( SR.GetString( SR.UnexpectedElement ) ) ); } string name = String.Empty; List values = new List (); string description = String.Empty; string uri = String.Empty; // // Look for the qualified name. // uri = reader.GetAttribute( XmlNames.WSIdentity.UriAttribute, XmlNames.WSIdentity.Namespace ); // // Look for the unqualified name. // if( String.IsNullOrEmpty( uri ) ) { uri = reader.GetAttribute( XmlNames.WSIdentity.UriAttribute ); } bool isEmptyElement = reader.IsEmptyElement; reader.ReadStartElement(); if( !isEmptyElement ) { while( reader.IsStartElement() ) { if( reader.IsStartElement( XmlNames.WSIdentity.DisplayTagElement, XmlNames.WSIdentity.Namespace ) ) { name = reader.ReadElementContentAsString(); } else if( reader.IsStartElement( XmlNames.WSIdentity.DisplayValueElement, XmlNames.WSIdentity.Namespace ) ) { values.Add( reader.ReadElementContentAsString() ); } else if( reader.IsStartElement( XmlNames.WSIdentity.DescriptionElement, XmlNames.WSIdentity.Namespace ) ) { description = reader.ReadElementContentAsString(); } else { reader.Skip(); } } reader.ReadEndElement(); } return new DisplayClaim( name, values, description, uri ); } } } // 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
- WebServiceHandler.cs
- DataGridColumn.cs
- TimeSpanMinutesConverter.cs
- StringPropertyBuilder.cs
- ObjectStateEntry.cs
- StandardOleMarshalObject.cs
- ExtenderProviderService.cs
- MeasureData.cs
- SmiXetterAccessMap.cs
- HitTestDrawingContextWalker.cs
- LinqDataSourceDeleteEventArgs.cs
- FontEmbeddingManager.cs
- ScrollPatternIdentifiers.cs
- TextDecorationCollection.cs
- Subtree.cs
- ScriptIgnoreAttribute.cs
- SystemGatewayIPAddressInformation.cs
- DefaultProxySection.cs
- CompoundFileReference.cs
- CheckPair.cs
- OdbcConnectionPoolProviderInfo.cs
- BorderGapMaskConverter.cs
- UnauthorizedAccessException.cs
- DirectoryInfo.cs
- ExtractedStateEntry.cs
- StreamReader.cs
- CharConverter.cs
- SafeSecurityHandles.cs
- ReaderOutput.cs
- ListViewPagedDataSource.cs
- Int16Animation.cs
- MetadataWorkspace.cs
- HtmlTernaryTree.cs
- ServiceEndpoint.cs
- Fonts.cs
- WorkflowDesignerMessageFilter.cs
- EntityObject.cs
- MediaScriptCommandRoutedEventArgs.cs
- SQLUtility.cs
- SoapExtensionImporter.cs
- DivideByZeroException.cs
- VisualBasicSettingsConverter.cs
- CompareValidator.cs
- XslException.cs
- SystemUnicastIPAddressInformation.cs
- DefaultHttpHandler.cs
- ServiceErrorHandler.cs
- odbcmetadatafactory.cs
- ConditionCollection.cs
- WebPermission.cs
- KeyInstance.cs
- DataGridColumn.cs
- QilGeneratorEnv.cs
- XamlTypeMapper.cs
- FixedDocumentSequencePaginator.cs
- MSAAEventDispatcher.cs
- UrlMapping.cs
- FilterEventArgs.cs
- ProfileProvider.cs
- IdnElement.cs
- DataBindingHandlerAttribute.cs
- SiteMapPath.cs
- _SecureChannel.cs
- AssemblyNameProxy.cs
- OpacityConverter.cs
- HttpDebugHandler.cs
- BitmapScalingModeValidation.cs
- PathGeometry.cs
- DataListItemCollection.cs
- DataGridView.cs
- SafeNativeMethods.cs
- ProcessInfo.cs
- DesignerOptionService.cs
- WeakReadOnlyCollection.cs
- _NetRes.cs
- WebPartManager.cs
- ValidatorCompatibilityHelper.cs
- Activity.cs
- UriParserTemplates.cs
- IntellisenseTextBox.cs
- SqlVisitor.cs
- HtmlUtf8RawTextWriter.cs
- CatalogZone.cs
- XPathArrayIterator.cs
- CodeTypeDeclaration.cs
- AssemblyLoader.cs
- CompositeCollectionView.cs
- SelectionGlyph.cs
- ArrayListCollectionBase.cs
- XmlRawWriter.cs
- X509CertificateClaimSet.cs
- OleDbPropertySetGuid.cs
- UnsafeNativeMethodsCLR.cs
- processwaithandle.cs
- ParameterCollectionEditor.cs
- GPRECT.cs
- ContainerCodeDomSerializer.cs
- MarshalByRefObject.cs
- ProcessStartInfo.cs
- Group.cs