Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / infocard / Service / managed / Microsoft / InfoCards / X509LogoTypeExtension.cs / 1 / X509LogoTypeExtension.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace Microsoft.InfoCards { using System; using System.IO; using System.Text; using System.Diagnostics; using System.Collections.Generic; using System.Security.Cryptography; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; using System.Globalization; using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace; // // Summary: // Extension supporting the encoding and decoding of the X509 // logotype extension (1.3.6.1.5.5.7.1.12) specified by RFC 3709. // { iso(1) identified-organization(3) dod(6) internet(1) // security(5) mechanisms(5) pkix(7) id-pe(1) 12 } // internal sealed class X509LogoTypeExtension : X509Extension { Listm_logos = new List (); bool m_decodePathComplete; const string szOID_LOGO_TYPES = "1.3.6.1.5.5.7.1.12"; const byte OctetStringTag = 0x04; const byte ObjectIdentifierTag = 0x06; const byte StringTag = 0x16; const byte SequenceTag = 0x30; const byte DirectTag = 0xa0; const byte IndirectTag = 0xa1; const byte AudioLogoTypeDataTag = 0xa1; public List Logos { get { IDT.DebugAssert( m_decodePathComplete, "Extension must be decoded before accessing this property" ); return m_logos; } } public void TryDecodeExtension() { try { DecodeExtension(); } #pragma warning disable 56500 // do not catch non-recoverable exceptions catch ( Exception e ) { if( IDT.IsFatal( e ) ) { InfoCardService.Crash( e ); } // // All other exceptions, including LogoValidationExceptions should be recoverable // IDT.TraceDebug( "X509LogoClient: Error found decoding extension:\n{0}", e.Message ); IDT.TraceAndLogException( e ); } #pragma warning restore 56500 // do not catch non-recoverable exceptions // // Indicates that we've at least tried decoding the extension. // After this is set, the Logos property can be safely accessed. // m_decodePathComplete = true; } // // Summary: // Constructs the extension using the rawdata from the certificate // public X509LogoTypeExtension( byte[] rawData ) : base( szOID_LOGO_TYPES, rawData, false ) {} public static X509LogoTypeExtension FromCertificate( X509Certificate2 certificate ) { if( null == certificate.Extensions || null == certificate.Extensions[ szOID_LOGO_TYPES ] ) { return null; } return new X509LogoTypeExtension( certificate.Extensions[ szOID_LOGO_TYPES ].RawData ); } // // Summary: // Gets the byte information from an AsnEncodedData object. // and resets the decoded flag. // // Parameters: // asnEncodedData - raw ASN.1 data. // public override void CopyFrom( AsnEncodedData asnEncodedData ) { base.CopyFrom( asnEncodedData ); // // This is not a critical extension // base.Critical = false; // // We've not decoded this yet, so cannot access the Logos property. // Set a flag for this. // m_decodePathComplete = false; } // // Summary: // Builds a string containing human readable and hexadecimal representations // of the extension information. // // Returns: // A string with the following shape // X509 Logotype Extension( 1.3.6.1.5.5.7.1.12 ) // 30 81 be a1 5d a0 5b 30 0..�]�[0 // 59 30 57 30 55 16 09 69 Y0W0U..i // 6d 61 67 65 2f 67 69 66 mage/gif // 30 21 30 1f 30 07 06 05 0!0.0... // 2b 0e 03 02 1a 04 14 8f ........ // e5 d3 1a 86 ac 8d 8e 6b �O.....k // ... // d3 1a 86 ac 8d 8e 6b c3 O.....kA // cf 80 6a d4 48 18 2c 7b I.jOH.,{ // 19 2e 30 25 16 23 68 74 ..0%.#ht // 74 70 3a 2f 2f 6c 6f 67 tp://log // 6f 2e 76 65 72 69 73 69 o.verisi // 67 6e 2e 63 6f 6d 2f 76 gn.com/v // 73 6c 6f 67 6f 2e 67 69 slogo.gi // 66 f // // LogoType: Issuer // MediaType: image/gif // Location(s): http://logo.verisign.com/vslogo.gif // // Hash(es) // // Name: sha1 // Oid: 1.3.14.3.2.26 // Bytes: // 8f e5 d3 1a 86 ac 8d 8e .�O..... // 6b c3 cf 80 6a d4 48 18 kAI.jOH. // 2c 7b 19 2e ,{.. // public override string ToString() { #if DEBUG StringBuilder sb = new StringBuilder(); sb.AppendFormat( "X509 Logotype Extension( {0} )\n", szOID_LOGO_TYPES ); sb.Append( Asn1Utilities.ToHexDump( RawData ) ); sb.Append( '\n' ); foreach( X509Logo logo in Logos ) { sb.Append( logo.ToString() ); sb.Append( "\n" ); } return sb.ToString(); #else return base.ToString(); #endif } // // Summary: // Takes the populated members and writes them out to the RawData member. // private void DecodeExtension() { BinaryReader br = new InfoCardBinaryReader( new MemoryStream( RawData ) ); ASCIIEncoding ascii = new ASCIIEncoding(); // // Read LogoTypeExtn sequence tag // // LogotypeExtn ::= SEQUENCE { // communityLogos [0] EXPLICIT SEQUENCE OF LogotypeInfo OPTIONAL, // issuerLogo [1] EXPLICIT LogotypeInfo OPTIONAL, // subjectLogo [2] EXPLICIT LogotypeInfo OPTIONAL, // otherLogos [3] EXPLICIT SEQUENCE OF OtherLogotypeInfo OPTIONAL } // VerifyByte( br.ReadByte(), SequenceTag ); ReadAsnByteLength( br ); while( !ReachedEndPosition( br.BaseStream.Position, br.BaseStream.Length ) ) { bool isImage; string mediaType; Dictionary hashes = new Dictionary (); List fileLocations = new List (); bool isDirect; // // Read Logo Type // X509LogoType logoType = (X509LogoType) br.ReadByte(); long logoTypeStartPosition = br.BaseStream.Position; long logoTypeLength = ReadAsnByteLength( br ); long logoTypeEndPosition = br.BaseStream.Position + logoTypeLength; IDT.TraceDebug( "X509LogoClient: Logo parsing details: start={0},length={1},end={2}", logoTypeStartPosition, logoTypeLength, logoTypeEndPosition ); if( X509LogoType.Subject != logoType && X509LogoType.Issuer != logoType ) { // // See 39977, need to process logo extensions that have Other/Community logos // Current code simply throws. // throw IDT.ThrowHelperError( new LogoValidationException( SR.GetString( SR.LogoUnsupportedType ) ) ); // OtherLogotypeInfo ::= SEQUENCE { // logotypeType OBJECT IDENTIFIER, // info LogotypeInfo } // // otherLogoOid = ReadObjectIdentifier( br ); } // // Read Direct/Indirect // // LogotypeInfo ::= CHOICE { // direct [0] LogotypeData, // indirect [1] LogotypeReference } // byte b = br.ReadByte(); VerifyByte( b, new byte[] { DirectTag, IndirectTag } ); isDirect = ( DirectTag == b ); ReadAsnByteLength( br ); if( IndirectTag == b ) { // // See 39977, process logo extensions that use an indirect references to logos. // Current code simply throws. // throw IDT.ThrowHelperError( new LogoValidationException( SR.GetString( SR.LogoUnsupportedIndirectReferences ) ) ); // Process InDirect to get a LogoTypeData structure // // LogotypeReference ::= SEQUENCE { // refStructHash SEQUENCE SIZE (1..MAX) OF HashAlgAndValue, // refStructURI SEQUENCE SIZE (1..MAX) OF IA5String } // // // Replace the existing byte[], stream and BinaryReader with // new LogotypeData structure for further processing // } // // Read LogotypeData Sequence Tag // // LogotypeData ::= SEQUENCE { // image SEQUENCE OF LogotypeImage OPTIONAL, // audio [1] SEQUENCE OF LogotypeAudio OPTIONAL } // VerifyByte( br.ReadByte(), SequenceTag ); ReadAsnByteLength( br ); // // Read LogoType Image/Audio Sequence Tag // The only difference between audio and image // is that AudioLogoTypeDataTag (which is 0xa1) is stuck in before the sequence tag (0x30) // b = br.ReadByte(); if( AudioLogoTypeDataTag == b ) { isImage = false; IDT.TraceAndLogException( new LogoValidationException( SR.GetString( SR.LogoUnsupportedAudio ) ) ); // // A [1] indicates audio context // Process LogoTypeAudio Sequence Tag // VerifyByte( br.ReadByte(), SequenceTag ); } else { isImage = true; VerifyByte( b, SequenceTag ); } ReadAsnByteLength( br ); // // Process the content LogotypeDetails (imageDetails or audioDetails) // // LogotypeImage ::= SEQUENCE { // imageDetails LogotypeDetails, // imageInfo LogotypeImageInfo OPTIONAL } // // LogotypeAudio ::= SEQUENCE { // audioDetails LogotypeDetails, // audioInfo LogotypeAudioInfo OPTIONAL } // VerifyByte( br.ReadByte(), SequenceTag ); ReadAsnByteLength( br ); // // LogotypeDetails ::= SEQUENCE { // mediaType IA5String, -- MIME media type name and optional // -- parameters // logotypeHash SEQUENCE SIZE (1..MAX) OF HashAlgAndValue, // logotypeURI SEQUENCE SIZE (1..MAX) OF IA5String } // VerifyByte( br.ReadByte(), StringTag ); Int32 length = ReadAsnByteLength( br ); // // Read the media type using the ASCII encoding // mediaType = ascii.GetString( br.ReadBytes( (int) length ) ); // // Read the Hash Algorithm and Value // // HashAlgAndValue ::= SEQUENCE { // hashAlg AlgorithmIdentifier, // hashValue OCTET STRING } // // // Read the sequence for logotypeHash field // VerifyByte( br.ReadByte(), SequenceTag ); // // Length of LogoTypeHash // length = ReadAsnByteLength( br ); // // Make sure to take the stream position after processing the length // long logoTypeHashEnd = br.BaseStream.Position + length; while( !ReachedEndPosition( br.BaseStream.Position, logoTypeHashEnd ) ) { // // Read the sequence for each item in the collection of HashAlgAndValue(s) // VerifyByte( br.ReadByte(), SequenceTag ); // // Length of HashAlgAndValue: // length = ReadAsnByteLength( br ); // // Read the sequence for the Algorithm // // // AlgorithmIdentifier ::= SEQUENCE { // algorithm OBJECT IDENTIFIER, // parameters ANY DEFINED BY algorithm OPTIONAL } // VerifyByte( br.ReadByte(), SequenceTag ); // // Length of AlgorithmIdentifier // length = ReadAsnByteLength( br ); long algorithmIdentifierEnd = br.BaseStream.Position + length; Oid oid = ReadObjectIdentifier( br ); // // If there are parameters, ignore them. // br.BaseStream.Position = algorithmIdentifierEnd; // // Read the Hash Value // VerifyByte( br.ReadByte(), OctetStringTag ); length = ReadAsnByteLength( br ); byte[] hashvalue = br.ReadBytes( length ); // // Add the hash algorithm and value to the collection // hashes[ oid ] = hashvalue; } // // Read the collection logoTypeUri (image/audio file locations) // // logotypeURI SEQUENCE SIZE (1..MAX) OF IA5String } // VerifyByte( br.ReadByte(), SequenceTag ); length = ReadAsnByteLength( br ); long logoTypeUriEnd = br.BaseStream.Position + length; while( !ReachedEndPosition( br.BaseStream.Position, logoTypeUriEnd ) ) { VerifyByte( br.ReadByte(), StringTag ); length = ReadAsnByteLength( br ); // // Read the Uri using the ASCII encoding // fileLocations.Add( ascii.GetString( br.ReadBytes( (int) length ) ) ); } // // There may be a LogotypeImageInfo structure. This data is not used so skip over it. // if( br.BaseStream.Position != logoTypeEndPosition ) { IDT.TraceDebug( "X509LogoClient: Found LogotypeImageInfo at position {0}. This information is not parsed. Moving to next logo in the extension", br.BaseStream.Position ); br.BaseStream.Position = logoTypeEndPosition; } // if( isImage ) // { // // If the LogotypeImageInfo // // LogotypeImageInfo ::= SEQUENCE { // type [0] LogotypeImageType DEFAULT color, // fileSize INTEGER, -- In octets // xSize INTEGER, -- Horizontal size in pixels // ySize INTEGER, -- Vertical size in pixels // resolution LogotypeImageResolution OPTIONAL, // language [4] IA5String OPTIONAL } -- RFC 3066 Language Tag // // // LogotypeImageType ::= INTEGER { grayScale(0), color(1) } // // // LogotypeImageResolution ::= CHOICE { // numBits [1] INTEGER, -- Resolution in bits // tableSize [2] INTEGER } -- Number of colors or grey tones // // } // else // { // // LogotypeAudioInfo ::= SEQUENCE { // fileSize INTEGER, -- In octets // playTime INTEGER, -- In milliseconds // channels INTEGER, -- 1=mono, 2=stereo, 4=quad // sampleRate [3] INTEGER OPTIONAL, -- Samples per second // language [4] IA5String OPTIONAL } -- RFC 3066 Language Tag // // } if( isImage ) { m_logos.Add( new X509ImageLogo( logoType, mediaType, hashes, fileLocations ) ); } // else // { // m_logos.Add( new X509AudioLogo( logoType, mediaType, hashes, fileLocations ) ); // } } } // // Summary: // Simple method to validate the specified byte is one in a list. // If not it throws an exception. // // Parameters: // input - byte to be evaluated. // expected - list to check against // private void VerifyByte( byte input, byte[] expected ) { foreach( byte b in expected ) { if( b == input ) { return; } } throw IDT.ThrowHelperError( new LogoValidationException( SR.GetString( SR.LogoInvalidLogoType ) ) ); } // // Summary: // Simple method to validate the specified byte is the value expected. If not it throws // an exception. // // Parameters: // input - byte to be evaluated. // expected - byte to check against // private void VerifyByte( byte input, byte expected ) { if( input != expected ) { throw IDT.ThrowHelperError( new LogoValidationException( SR.GetString( SR.LogoInvalidLogoType ) ) ); } } // // Summary: // Checks to see if the stream position has reached the end of a section. // // Parameters: // currentPosition - position in the stream // endPosition - end of the section // // Remarks: // Throws an LogoValidationException if the current is beyond the end. // private bool ReachedEndPosition( long currentPosition, long endPosition ) { if( currentPosition > endPosition ) { throw IDT.ThrowHelperError( new LogoValidationException( SR.GetString( SR.LogoInvalidCertificateLength ) ) ); } return ( currentPosition == endPosition ); } // // Summary: // An ASN.1 length is a single byte union. The most-significant bit // indicates which format the length takes on: // // Parameters: // br - BinaryReader to be used to consume the length from // // Remarks: // MSB == 0 --> Then the length is the binary value of the lower 7 bits // of that byte e.g. [7f] --> 127 // // MSG == 1 --> Then the lower 7 bits of the byte contain the number of bytes that follow this byte // whose binary value comprise the length // e.g. [81 9f] --> 159 // private Int32 ReadAsnByteLength( BinaryReader br ) { byte firstByte = br.ReadByte(); if( 0x00 == ( firstByte & 0x80 ) ) { return (Int32) firstByte; } int numberOfBytesInLength = firstByte & 0x7f; if( numberOfBytesInLength < 1 || numberOfBytesInLength > 4 ) { throw IDT.ThrowHelperError( new LogoValidationException( SR.GetString( SR.LogoInvalidAsnLength ) ) ); } // // The lower 7-bits hold the number of bytes that form the length // byte[] bytes = br.ReadBytes( firstByte & 0x7f ); Int32 totalLength = 0; foreach( byte b in bytes ) { totalLength = b + ( totalLength << 8 ); } return totalLength; } // // Summary: // Constructs an Oid from the an ASN.1 encoded byte stream. // // Parameters: // br - BinaryReader to be used to consume the Oid from // // Remarks: // Hierarchical Object Identifier: The first two levels are // encoded into one byte, since the root level has only 3 nodes // (40*x + y). However if x = joint-iso-itu-t(2) then y may be // > 39, so we have to add special-case handling for this. // Oid ReadObjectIdentifier( BinaryReader br ) { VerifyByte( br.ReadByte(), ObjectIdentifierTag ); Int32 length = ReadAsnByteLength( br ); byte[] oidbytes = br.ReadBytes( length ); // // Construct the object identifer as a string in the form 1 3 14 3 2 26 // StringBuilder sb = new StringBuilder(); sb.AppendFormat( "{0}.{1}.", oidbytes[ 0 ] / 40, oidbytes[ 0 ] % 40 ); for( int n=1; n
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RenderingEventArgs.cs
- TableCellAutomationPeer.cs
- SubMenuStyleCollectionEditor.cs
- SymLanguageType.cs
- MailWebEventProvider.cs
- InfoCardX509Validator.cs
- HitTestDrawingContextWalker.cs
- DataGridPageChangedEventArgs.cs
- ShaderEffect.cs
- HandlerBase.cs
- WaitHandleCannotBeOpenedException.cs
- HttpCachePolicy.cs
- JsonGlobals.cs
- InstanceData.cs
- ColorPalette.cs
- DataSourceCollectionBase.cs
- DbProviderFactoriesConfigurationHandler.cs
- SortedDictionary.cs
- EndPoint.cs
- WebPartDisplayModeCollection.cs
- DispatcherSynchronizationContext.cs
- CodeStatement.cs
- FilteredAttributeCollection.cs
- DurationConverter.cs
- InputBinding.cs
- ProviderConnectionPointCollection.cs
- DesignTimeTemplateParser.cs
- HttpClientCredentialType.cs
- WindowCollection.cs
- XhtmlBasicCalendarAdapter.cs
- SignatureToken.cs
- TrackBar.cs
- MiniMapControl.xaml.cs
- SHA256Managed.cs
- AlternateView.cs
- SessionSwitchEventArgs.cs
- XmlUtil.cs
- ProxyWebPart.cs
- Shape.cs
- ProgressiveCrcCalculatingStream.cs
- DragCompletedEventArgs.cs
- ServerType.cs
- HtmlGenericControl.cs
- SaveFileDialog.cs
- StoryFragments.cs
- SecurityUtils.cs
- Viewport3DAutomationPeer.cs
- Queue.cs
- Zone.cs
- HotCommands.cs
- DataGridColumnsPage.cs
- StrokeNodeOperations.cs
- DelegateSerializationHolder.cs
- EncryptedType.cs
- EffectiveValueEntry.cs
- PropertyInformation.cs
- Column.cs
- VSWCFServiceContractGenerator.cs
- AssemblyInfo.cs
- QueryConverter.cs
- HeaderedContentControl.cs
- SymbolTable.cs
- ImageInfo.cs
- ResourceDescriptionAttribute.cs
- WindowsPen.cs
- LinqDataSourceContextEventArgs.cs
- ConfigXmlSignificantWhitespace.cs
- StringFunctions.cs
- FieldNameLookup.cs
- MachineKeySection.cs
- ProtectedConfiguration.cs
- FormsIdentity.cs
- BuiltInExpr.cs
- GroupBoxRenderer.cs
- OdbcConnectionString.cs
- LinearKeyFrames.cs
- CalendarDataBindingHandler.cs
- Html32TextWriter.cs
- EventWaitHandle.cs
- SrgsElementFactoryCompiler.cs
- GridViewAutoFormat.cs
- CurrencyManager.cs
- ColorEditor.cs
- PointConverter.cs
- CreateRefExpr.cs
- ProtocolsConfiguration.cs
- Bidi.cs
- Dispatcher.cs
- DesignSurfaceEvent.cs
- ValueProviderWrapper.cs
- OptimalTextSource.cs
- ControlPropertyNameConverter.cs
- MimeXmlReflector.cs
- RSAPKCS1SignatureDeformatter.cs
- Message.cs
- HtmlShim.cs
- CircleHotSpot.cs
- XmlSchemaIdentityConstraint.cs
- MissingSatelliteAssemblyException.cs
- MenuRenderer.cs