SignedXmlDebugLog.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / ManagedLibraries / Security / System / Security / Cryptography / Xml / SignedXmlDebugLog.cs / 1305376 / SignedXmlDebugLog.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
// [....]
// 
 
using System;
using System.Diagnostics; 
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Security.Cryptography.X509Certificates; 
using System.Text;
using System.Xml; 
 
namespace System.Security.Cryptography.Xml {
    ///  
    ///     Trace support for debugging issues signing and verifying XML signatures.
    /// 
    internal static class SignedXmlDebugLog {
 
        //
        // In order to enable XML digital signature debug loggging, applications should setup their config 
        // file to be similar to the following: 
        //
        //  
        //   
        //     
        //        
        //         
        //            
        //          
        //       
        //      
        //     
        //       
        //     
        //      
        //        
        //     
        //      
        //       
        //         
        //       
        //      
        //   
        //  
        // 

        private const string NullString = "(null)"; 

        private static TraceSource s_traceSource = new TraceSource("System.Security.Cryptography.Xml.SignedXml");
        private static bool? s_verboseLogging;
        private static bool? s_informationLogging; 

        ///  
        ///     Types of events that are logged to the debug log 
        /// 
        internal enum SignedXmlDebugEvent { 
            /// 
            ///     Canonicalization of input XML has begun
            /// 
            BeginCanonicalization, 

            ///  
            ///     Verificaiton of the signature format itself is beginning 
            /// 
            BeginCheckSignatureFormat, 

            /// 
            ///     Verification of a signed info is beginning
            ///  
            BeginCheckSignedInfo,
 
            ///  
            ///     Signing is beginning
            ///  
            BeginSignatureComputation,

            /// 
            ///     Signature verification is beginning 
            /// 
            BeginSignatureVerification, 
 
            /// 
            ///     Input data has been transformed to its canonicalized form 
            /// 
            CanonicalizedData,

            ///  
            ///     The result of signature format validation
            ///  
            FormatValidationResult, 

            ///  
            ///     Namespaces are being propigated into the signature
            /// 
            NamespacePropagation,
 
            /// 
            ///     Output from a Reference 
            ///  
            ReferenceData,
 
            /// 
            ///     The result of a signature verification
            /// 
            SignatureVerificationResult, 

            ///  
            ///     Calculating the final signature 
            /// 
            Signing, 

            /// 
            ///     A reference is being hashed
            ///  
            SigningReference,
 
            ///  
            ///     A signature has failed to verify
            ///  
            VerificationFailure,

            /// 
            ///     Verify that a reference has the correct hash value 
            /// 
            VerifyReference, 
 
            /// 
            ///     Verification is processing the SignedInfo section of the signature 
            /// 
            VerifySignedInfo,

            ///  
            ///     Verification status on the x.509 certificate in use
            ///  
            X509Verification 
        }
 
        /// 
        ///     Check to see if logging should be done in this process
        /// 
        private static bool InformationLoggingEnabled { 
            get {
                if (!s_informationLogging.HasValue) { 
                    s_informationLogging = s_traceSource.Switch.ShouldTrace(TraceEventType.Information); 
                }
 
                return s_informationLogging.Value;
            }
        }
 
        /// 
        ///     Check to see if verbose log messages should be generated 
        ///  
        private static bool VerboseLoggingEnabled {
            get { 
                if (!s_verboseLogging.HasValue) {
                    s_verboseLogging = s_traceSource.Switch.ShouldTrace(TraceEventType.Verbose);
                }
 
                return s_verboseLogging.Value;
            } 
        } 

        ///  
        ///     Convert the byte array into a hex string
        /// 
        private static string FormatBytes(byte[] bytes) {
            if (bytes == null) 
                return NullString;
 
            StringBuilder builder = new StringBuilder(bytes.Length * 2); 
            foreach (byte b in bytes) {
                builder.Append(b.ToString("x2", CultureInfo.InvariantCulture)); 
            }

            return builder.ToString();
        } 

        ///  
        ///     Map a key to a string describing the key 
        /// 
        private static string GetKeyName(object key) { 
            Debug.Assert(key != null, "key != null");

            ICspAsymmetricAlgorithm cspKey = key as ICspAsymmetricAlgorithm;
            X509Certificate certificate = key as X509Certificate; 
            X509Certificate2 certificate2 = key as X509Certificate2;
 
            // 
            // Use the following sources for key names, if available:
            // 
            // * CAPI key         -> key container name
            // * X509Certificate2 -> subject simple name
            // * X509Certificate  -> subject name
            // * All others       -> hash code 
            //
 
            string keyName = null; 
            if (cspKey != null && cspKey.CspKeyContainerInfo.KeyContainerName != null) {
                keyName = String.Format(CultureInfo.InvariantCulture, 
                                        "\"{0}\"",
                                        cspKey.CspKeyContainerInfo.KeyContainerName);
            }
            else if (certificate2 != null) { 
                keyName = String.Format(CultureInfo.InvariantCulture,
                                        "\"{0}\"", 
                                        certificate2.GetNameInfo(X509NameType.SimpleName, false)); 
            }
            else if (certificate != null) { 
                keyName = String.Format(CultureInfo.InvariantCulture,
                                        "\"{0}\"",
                                        certificate.Subject);
            } 
            else {
                keyName = key.GetHashCode().ToString("x8", CultureInfo.InvariantCulture); 
            } 

            return String.Format(CultureInfo.InvariantCulture, "{0}#{1}", key.GetType().Name, keyName); 
        }

        /// 
        ///     Map an object to a string describing the object 
        /// 
        private static string GetObjectId(object o) { 
            Debug.Assert(o != null, "o != null"); 

            return String.Format(CultureInfo.InvariantCulture, 
                                 "{0}#{1}", o.GetType().Name,
                                 o.GetHashCode().ToString("x8", CultureInfo.InvariantCulture));
        }
 
        /// 
        ///     Map an OID to the friendliest name possible 
        ///  
        private static string GetOidName(Oid oid) {
            Debug.Assert(oid != null, "oid != null"); 

            string friendlyName = oid.FriendlyName;
            if (String.IsNullOrEmpty(friendlyName))
                friendlyName = oid.Value; 

            return friendlyName; 
        } 

        ///  
        ///     Log that canonicalization has begun on input data
        /// 
        /// SignedXml object doing the signing or verification
        /// transform canonicalizing the input 
        internal static void LogBeginCanonicalization(SignedXml signedXml, Transform canonicalizationTransform) {
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(canonicalizationTransform != null, "canonicalizationTransform != null"); 

            if (InformationLoggingEnabled) { 
                string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_BeginCanonicalization"),
                                                  canonicalizationTransform.Algorithm,
                                                  canonicalizationTransform.GetType().Name); 
                WriteLine(signedXml,
                          TraceEventType.Information, 
                          SignedXmlDebugEvent.BeginCanonicalization, 
                          logMessage);
            } 

            if (VerboseLoggingEnabled) {
                string canonicalizationSettings = String.Format(CultureInfo.InvariantCulture,
                                                                SecurityResources.GetResourceString("Log_CanonicalizationSettings"), 
                                                                canonicalizationTransform.Resolver.GetType(),
                                                                canonicalizationTransform.BaseURI); 
                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.BeginCanonicalization, 
                          canonicalizationSettings);
            }
        }
 
        /// 
        ///     Log that we're going to be validating the signature format itself 
        ///  
        /// SignedXml object doing the verification
        /// Callback delegate which is being used for format verification 
        internal static void LogBeginCheckSignatureFormat(SignedXml signedXml, Func formatValidator) {
            Debug.Assert(signedXml != null, "signedXml != null");
            Debug.Assert(formatValidator != null, "formatValidator != null");
 
            if (InformationLoggingEnabled) {
                MethodInfo validationMethod = formatValidator.Method; 
 
                string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_CheckSignatureFormat"), 
                                                  validationMethod.Module.Assembly.FullName,
                                                  validationMethod.DeclaringType.FullName,
                                                  validationMethod.Name);
                WriteLine(signedXml, TraceEventType.Information, SignedXmlDebugEvent.BeginCheckSignatureFormat, logMessage); 
            }
        } 
 
        /// 
        ///     Log that checking SignedInfo is beginning 
        /// 
        /// SignedXml object doing the verification
        /// SignedInfo object being verified
        internal static void LogBeginCheckSignedInfo(SignedXml signedXml, SignedInfo signedInfo) { 
            Debug.Assert(signedXml != null, "signedXml != null");
            Debug.Assert(signedInfo != null, " signedInfo != null"); 
 
            if (InformationLoggingEnabled) {
                string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                  SecurityResources.GetResourceString("Log_CheckSignedInfo"),
                                                  signedInfo.Id != null ? signedInfo.Id : NullString);
                WriteLine(signedXml, TraceEventType.Information, SignedXmlDebugEvent.BeginCheckSignedInfo, logMessage);
            } 
        }
 
        ///  
        ///     Log that signature computation is beginning
        ///  
        /// SignedXml object doing the signing
        /// Context of the signature
        internal static void LogBeginSignatureComputation(SignedXml signedXml, XmlElement context) {
            Debug.Assert(signedXml != null, "signedXml != null"); 

            if (InformationLoggingEnabled) { 
                WriteLine(signedXml, 
                          TraceEventType.Information,
                          SignedXmlDebugEvent.BeginSignatureComputation, 
                          SecurityResources.GetResourceString("Log_BeginSignatureComputation"));
            }

            if (VerboseLoggingEnabled) { 
                string contextData = String.Format(CultureInfo.InvariantCulture,
                                                   SecurityResources.GetResourceString("Log_XmlContext"), 
                                                   context != null ? context.OuterXml : NullString); 

                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.BeginSignatureComputation,
                          contextData);
            } 
        }
 
        ///  
        ///     Log that signature verification is beginning
        ///  
        /// SignedXml object doing the verification
        /// Context of the verification
        internal static void LogBeginSignatureVerification(SignedXml signedXml, XmlElement context) {
            Debug.Assert(signedXml != null, "signedXml != null"); 

            if (InformationLoggingEnabled) { 
                WriteLine(signedXml, 
                          TraceEventType.Information,
                          SignedXmlDebugEvent.BeginSignatureVerification, 
                          SecurityResources.GetResourceString("Log_BeginSignatureVerification"));
            }

            if (VerboseLoggingEnabled) { 
                string contextData = String.Format(CultureInfo.InvariantCulture,
                                                   SecurityResources.GetResourceString("Log_XmlContext"), 
                                                   context != null ? context.OuterXml : NullString); 

                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.BeginSignatureVerification,
                          contextData);
            } 
        }
 
        ///  
        ///     Log the canonicalized data
        ///  
        /// SignedXml object doing the signing or verification
        /// transform canonicalizing the input
        internal static void LogCanonicalizedOutput(SignedXml signedXml, Transform canonicalizationTransform) {
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(canonicalizationTransform != null, "canonicalizationTransform != null");
 
            if (VerboseLoggingEnabled) { 
                using (StreamReader reader = new StreamReader(canonicalizationTransform.GetOutput(typeof(Stream)) as Stream)) {
                    string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                      SecurityResources.GetResourceString("Log_CanonicalizedOutput"),
                                                      reader.ReadToEnd());
                    WriteLine(signedXml,
                              TraceEventType.Verbose, 
                              SignedXmlDebugEvent.CanonicalizedData,
                              logMessage); 
                } 
            }
        } 

        /// 
        ///     Log that the signature format callback has rejected the signature
        ///  
        /// SignedXml object doing the signature verification
        /// result of the signature format verification 
        internal static void LogFormatValidationResult(SignedXml signedXml, bool result) { 
            Debug.Assert(signedXml != null, "signedXml != null");
 
            if (InformationLoggingEnabled) {
                string logMessage = result ? SecurityResources.GetResourceString("Log_FormatValidationSuccessful") :
                                             SecurityResources.GetResourceString("Log_FormatValidationNotSuccessful");
                WriteLine(signedXml, TraceEventType.Information, SignedXmlDebugEvent.FormatValidationResult, logMessage); 
            }
        } 
 
        /// 
        ///     Log namespaces which are being propigated into the singature 
        /// 
        /// SignedXml doing the signing or verification
        /// namespaces being propigated
        internal static void LogNamespacePropagation(SignedXml signedXml, XmlNodeList namespaces) { 
            Debug.Assert(signedXml != null, "signedXml != null");
 
            if (InformationLoggingEnabled) { 
                if (namespaces != null) {
                    foreach (XmlAttribute propagatedNamespace in namespaces) { 
                        string propagationMessage = String.Format(CultureInfo.InvariantCulture,
                                                                  SecurityResources.GetResourceString("Log_PropagatingNamespace"),
                                                                  propagatedNamespace.Name,
                                                                  propagatedNamespace.Value); 

                        WriteLine(signedXml, 
                                  TraceEventType.Information, 
                                  SignedXmlDebugEvent.NamespacePropagation,
                                  propagationMessage); 
                    }
                }
                else {
                    WriteLine(signedXml, 
                              TraceEventType.Information,
                              SignedXmlDebugEvent.NamespacePropagation, 
                              SecurityResources.GetResourceString("Log_NoNamespacesPropagated")); 
                }
            } 
        }

        /// 
        ///     Log the output of a reference 
        /// 
        /// The reference being processed 
        /// Stream containing the output of the reference 
        /// Stream containing the output of the reference
        internal static Stream LogReferenceData(Reference reference, Stream data) { 
            if (VerboseLoggingEnabled) {
                //
                // Since the input data stream could be from the network or another source that does not
                // support rewinding, we will read the stream into a temporary MemoryStream that can be used 
                // to stringify the output and also return to the reference so that it can produce the hash
                // value. 
                // 

                MemoryStream ms = new MemoryStream(); 

                // First read the input stream into our temporary stream
                byte[] buffer = new byte[4096];
                int readBytes = 0; 
                do {
                    readBytes = data.Read(buffer, 0, buffer.Length); 
                    ms.Write(buffer, 0, readBytes); 
                } while (readBytes == buffer.Length);
 
                // Log out information about it
                string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_TransformedReferenceContents"),
                                                  Encoding.UTF8.GetString(ms.ToArray())); 
                WriteLine(reference,
                          TraceEventType.Verbose, 
                          SignedXmlDebugEvent.ReferenceData, 
                          logMessage);
 
                // Rewind to the beginning, so that the entire input stream is hashed
                ms.Seek(0, SeekOrigin.Begin);
                return ms;
            } 
            else {
                return data; 
            } 
        }
 
        /// 
        ///     Log the computation of a signature value when signing with an asymmetric algorithm
        /// 
        /// SignedXml object calculating the signature 
        /// key used for signing
        /// signature description being used to create the signature 
        /// hash algorithm used to digest the output 
        /// signature formatter used to do the signing
        internal static void LogSigning(SignedXml signedXml, 
                                        object key,
                                        SignatureDescription signatureDescription,
                                        HashAlgorithm hash,
                                        AsymmetricSignatureFormatter asymmetricSignatureFormatter) { 
            Debug.Assert(signedXml != null, "signedXml != null");
            Debug.Assert(signatureDescription != null, "signatureDescription != null"); 
            Debug.Assert(hash != null, "hash != null"); 
            Debug.Assert(asymmetricSignatureFormatter != null, "asymmetricSignatureFormatter != null");
 
            if (InformationLoggingEnabled) {
                string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_SigningAsymmetric"),
                                                  GetKeyName(key), 
                                                  signatureDescription.GetType().Name,
                                                  hash.GetType().Name, 
                                                  asymmetricSignatureFormatter.GetType().Name); 

                WriteLine(signedXml, 
                          TraceEventType.Information,
                          SignedXmlDebugEvent.Signing,
                          logMessage);
            } 
        }
 
        ///  
        ///     Log the computation of a signature value when signing with a keyed hash algorithm
        ///  
        /// SignedXml object calculating the signature
        /// key the signature is created with
        /// hash algorithm used to digest the output
        /// signature formatter used to do the signing 
        internal static void LogSigning(SignedXml signedXml, KeyedHashAlgorithm key) {
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(key != null, "key != null"); 

            if (InformationLoggingEnabled) { 
                string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_SigningHmac"),
                                                  key.GetType().Name);
 
                WriteLine(signedXml,
                          TraceEventType.Information, 
                          SignedXmlDebugEvent.Signing, 
                          logMessage);
            } 
        }

        /// 
        ///     Log the calculation of a hash value of a reference 
        /// 
        /// SignedXml object driving the signature 
        /// Reference being hashed 
        internal static void LogSigningReference(SignedXml signedXml, Reference reference) {
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(reference != null, "reference != null");

            if (VerboseLoggingEnabled) {
                string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                  SecurityResources.GetResourceString("Log_SigningReference"),
                                                  GetObjectId(reference), 
                                                  reference.Uri, 
                                                  reference.Id,
                                                  reference.Type, 
                                                  reference.DigestMethod,
                                                  CryptoConfig.CreateFromName(reference.DigestMethod).GetType().Name);

                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.SigningReference, 
                          logMessage); 
            }
        } 

        /// 
        ///     Log the specific point where a signature is determined to not be verifiable
        ///  
        /// SignedXml object doing the verification
        /// location that the signature was determined to be invalid 
        internal static void LogVerificationFailure(SignedXml signedXml, string failureLocation) { 
            if (InformationLoggingEnabled) {
                string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                  SecurityResources.GetResourceString("Log_VerificationFailed"),
                                                  failureLocation);

                WriteLine(signedXml, 
                          TraceEventType.Information,
                          SignedXmlDebugEvent.VerificationFailure, 
                          logMessage); 
            }
        } 

        /// 
        ///     Log the success or failure of a signature verification operation
        ///  
        /// SignedXml object doing the verification
        /// public key used to verify the signature 
        /// true if the signature verified, false otherwise 
        internal static void LogVerificationResult(SignedXml signedXml, object key, bool verified) {
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(key != null, "key != null");

            if (InformationLoggingEnabled) {
                string resource = verified ? SecurityResources.GetResourceString("Log_VerificationWithKeySuccessful") : 
                                             SecurityResources.GetResourceString("Log_VerificationWithKeyNotSuccessful");
                string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                  resource, 
                                                  GetKeyName(key));
 
                WriteLine(signedXml,
                          TraceEventType.Information,
                          SignedXmlDebugEvent.SignatureVerificationResult,
                          logMessage); 
            }
        } 
 
        /// 
        ///     Log the check for appropriate X509 key usage 
        /// 
        /// SignedXml doing the signature verification
        /// certificate having its key usages checked
        /// key usages being examined 
        internal static void LogVerifyKeyUsage(SignedXml signedXml, X509Certificate certificate, X509KeyUsageExtension keyUsages) {
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(certificate != null, "certificate != null"); 

            if (InformationLoggingEnabled) { 
                string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_KeyUsages"),
                                                  keyUsages.KeyUsages,
                                                  GetOidName(keyUsages.Oid), 
                                                  GetKeyName(certificate));
 
                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.X509Verification, 
                          logMessage);
            }
        }
 
        /// 
        ///     Log that we are verifying a reference 
        ///  
        /// SignedXMl object doing the verification
        /// reference being verified 
        internal static void LogVerifyReference(SignedXml signedXml, Reference reference) {
            Debug.Assert(signedXml != null, "signedXml != null");
            Debug.Assert(reference != null, "reference != null");
 
            if (InformationLoggingEnabled) {
                string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                  SecurityResources.GetResourceString("Log_VerifyReference"), 
                                                  GetObjectId(reference),
                                                  reference.Uri, 
                                                  reference.Id,
                                                  reference.Type);

                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.VerifyReference, 
                          logMessage); 
            }
        } 

        /// 
        ///     Log the hash comparison when verifying a reference
        ///  
        /// SignedXml object verifying the signature
        /// reference being verified 
        /// actual hash value of the reference 
        /// hash value the signature expected the reference to have
        internal static void LogVerifyReferenceHash(SignedXml signedXml, 
                                                    Reference reference,
                                                    byte[] actualHash,
                                                    byte[] expectedHash) {
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(reference != null, "reference != null");
            Debug.Assert(actualHash != null, "actualHash != null"); 
            Debug.Assert(expectedHash != null, "expectedHash != null"); 

            if (VerboseLoggingEnabled) { 
                string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_ReferenceHash"),
                                                  GetObjectId(reference),
                                                  reference.DigestMethod, 
                                                  CryptoConfig.CreateFromName(reference.DigestMethod).GetType().Name,
                                                  FormatBytes(actualHash), 
                                                  FormatBytes(expectedHash)); 

                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.VerifyReference,
                          logMessage);
            } 
        }
 
        ///  
        ///     Log the verification parameters when verifying the SignedInfo section of a signature using an
        ///     asymmetric key 
        /// 
        /// SignedXml object doing the verification
        /// key being used to verify the signed info
        /// type of signature description class used 
        /// type of hash algorithm used
        /// type of signature deformatter used 
        /// hash value of the signed info 
        /// raw signature value
        internal static void LogVerifySignedInfo(SignedXml signedXml, 
                                                 AsymmetricAlgorithm key,
                                                 SignatureDescription signatureDescription,
                                                 HashAlgorithm hashAlgorithm,
                                                 AsymmetricSignatureDeformatter asymmetricSignatureDeformatter, 
                                                 byte[] actualHashValue,
                                                 byte[] signatureValue) { 
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(signatureDescription != null, "signatureDescription != null");
            Debug.Assert(hashAlgorithm != null, "hashAlgorithm != null"); 
            Debug.Assert(asymmetricSignatureDeformatter != null, "asymmetricSignatureDeformatter != null");

            if (InformationLoggingEnabled) {
                string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                  SecurityResources.GetResourceString("Log_VerifySignedInfoAsymmetric"),
                                                  GetKeyName(key), 
                                                  signatureDescription.GetType().Name, 
                                                  hashAlgorithm.GetType().Name,
                                                  asymmetricSignatureDeformatter.GetType().Name); 
                WriteLine(signedXml,
                          TraceEventType.Information,
                          SignedXmlDebugEvent.VerifySignedInfo,
                          logMessage); 
            }
 
            if (VerboseLoggingEnabled) { 
                string hashLog = String.Format(CultureInfo.InvariantCulture,
                                               SecurityResources.GetResourceString("Log_ActualHashValue"), 
                                               FormatBytes(actualHashValue));
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.VerifySignedInfo, hashLog);

                string signatureLog = String.Format(CultureInfo.InvariantCulture, 
                                                    SecurityResources.GetResourceString("Log_RawSignatureValue"),
                                                    FormatBytes(signatureValue)); 
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.VerifySignedInfo, signatureLog); 
            }
        } 

        /// 
        ///     Log the verification parameters when verifying the SignedInfo section of a signature using a
        ///     keyed hash algorithm 
        /// 
        /// SignedXml object doing the verification 
        /// hash algoirthm doing the verification 
        /// hash value of the signed info
        /// raw signature value 
        internal static void LogVerifySignedInfo(SignedXml signedXml,
                                                 KeyedHashAlgorithm mac,
                                                 byte[] actualHashValue,
                                                 byte[] signatureValue) { 
            Debug.Assert(signedXml != null, "signedXml != null");
            Debug.Assert(mac != null, "mac != null"); 
 
            if (InformationLoggingEnabled) {
                string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                  SecurityResources.GetResourceString("Log_VerifySignedInfoHmac"),
                                                  mac.GetType().Name);
                WriteLine(signedXml,
                          TraceEventType.Information, 
                          SignedXmlDebugEvent.VerifySignedInfo,
                          logMessage); 
            } 

            if (VerboseLoggingEnabled) { 
                string hashLog = String.Format(CultureInfo.InvariantCulture,
                                               SecurityResources.GetResourceString("Log_ActualHashValue"),
                                               FormatBytes(actualHashValue));
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.VerifySignedInfo, hashLog); 

                string signatureLog = String.Format(CultureInfo.InvariantCulture, 
                                                    SecurityResources.GetResourceString("Log_RawSignatureValue"), 
                                                    FormatBytes(signatureValue));
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.VerifySignedInfo, signatureLog); 
            }
        }

        ///  
        ///     Log that an X509 chain is being built for a certificate
        ///  
        /// SignedXml object building the chain 
        /// chain built for the certificate
        /// certificate having the chain built for it 
        internal static void LogVerifyX509Chain(SignedXml signedXml, X509Chain chain, X509Certificate certificate) {
            Debug.Assert(signedXml != null, "signedXml != null");
            Debug.Assert(certificate != null, "certificate != null");
            Debug.Assert(chain != null, "chain != null"); 

            if (InformationLoggingEnabled) { 
                string buildMessage = String.Format(CultureInfo.InvariantCulture, 
                                                    SecurityResources.GetResourceString("Log_BuildX509Chain"),
                                                    GetKeyName(certificate)); 
                WriteLine(signedXml,
                          TraceEventType.Information,
                          SignedXmlDebugEvent.X509Verification,
                          buildMessage); 
            }
 
            if (VerboseLoggingEnabled) { 
                // Dump out the flags and other miscelanious information used for building
                string revocationMode = String.Format(CultureInfo.InvariantCulture, 
                                                      SecurityResources.GetResourceString("Log_RevocationMode"),
                                                      chain.ChainPolicy.RevocationFlag);
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, revocationMode);
 
                string revocationFlag = String.Format(CultureInfo.InvariantCulture,
                                                      SecurityResources.GetResourceString("Log_RevocationFlag"), 
                                                      chain.ChainPolicy.RevocationFlag); 
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, revocationFlag);
 
                string verificationFlags = String.Format(CultureInfo.InvariantCulture,
                                                         SecurityResources.GetResourceString("Log_VerificationFlag"),
                                                         chain.ChainPolicy.VerificationFlags);
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, verificationFlags); 

                string verificationTime = String.Format(CultureInfo.InvariantCulture, 
                                                        SecurityResources.GetResourceString("Log_VerificationTime"), 
                                                        chain.ChainPolicy.VerificationTime);
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, verificationTime); 

                string urlTimeout = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_UrlTimeout"),
                                                  chain.ChainPolicy.UrlRetrievalTimeout); 
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, urlTimeout);
            } 
 
            // If there were any errors in the chain, make sure to dump those out
            if (InformationLoggingEnabled) { 
                foreach (X509ChainStatus status in chain.ChainStatus) {
                    if (status.Status != X509ChainStatusFlags.NoError) {
                        string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                          SecurityResources.GetResourceString("Log_X509ChainError"), 
                                                          status.Status,
                                                          status.StatusInformation); 
 
                        WriteLine(signedXml,
                                  TraceEventType.Information, 
                                  SignedXmlDebugEvent.X509Verification,
                                  logMessage);
                    }
                } 
            }
 
            // Finally, dump out the chain itself 
            if (VerboseLoggingEnabled) {
                StringBuilder chainElements = new StringBuilder(); 
                chainElements.Append(SecurityResources.GetResourceString("Log_CertificateChain"));

                foreach (X509ChainElement element in chain.ChainElements) {
                    chainElements.AppendFormat(CultureInfo.InvariantCulture, " {0}", GetKeyName(element.Certificate)); 
                }
 
                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.X509Verification, 
                          chainElements.ToString());
            }
        }
 
        /// 
        ///     Write data to the log 
        ///  
        /// object doing the trace
        /// severity of the debug event 
        /// data being written
        /// type of event being traced
        private static void WriteLine(object source, TraceEventType eventType, SignedXmlDebugEvent eventId, string data) {
            Debug.Assert(source != null, "source != null"); 
            Debug.Assert(!String.IsNullOrEmpty(data), "!String.IsNullOrEmpty(data)");
            Debug.Assert(InformationLoggingEnabled, "InformationLoggingEnabled"); 
 
            s_traceSource.TraceEvent(eventType,
                                    (int)eventId, 
                                    "[{0}, {1}] {2}",
                                    GetObjectId(source),
                                    eventId,
                                    data); 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
// [....]
// 
 
using System;
using System.Diagnostics; 
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Security.Cryptography.X509Certificates; 
using System.Text;
using System.Xml; 
 
namespace System.Security.Cryptography.Xml {
    ///  
    ///     Trace support for debugging issues signing and verifying XML signatures.
    /// 
    internal static class SignedXmlDebugLog {
 
        //
        // In order to enable XML digital signature debug loggging, applications should setup their config 
        // file to be similar to the following: 
        //
        //  
        //   
        //     
        //        
        //         
        //            
        //          
        //       
        //      
        //     
        //       
        //     
        //      
        //        
        //     
        //      
        //       
        //         
        //       
        //      
        //   
        //  
        // 

        private const string NullString = "(null)"; 

        private static TraceSource s_traceSource = new TraceSource("System.Security.Cryptography.Xml.SignedXml");
        private static bool? s_verboseLogging;
        private static bool? s_informationLogging; 

        ///  
        ///     Types of events that are logged to the debug log 
        /// 
        internal enum SignedXmlDebugEvent { 
            /// 
            ///     Canonicalization of input XML has begun
            /// 
            BeginCanonicalization, 

            ///  
            ///     Verificaiton of the signature format itself is beginning 
            /// 
            BeginCheckSignatureFormat, 

            /// 
            ///     Verification of a signed info is beginning
            ///  
            BeginCheckSignedInfo,
 
            ///  
            ///     Signing is beginning
            ///  
            BeginSignatureComputation,

            /// 
            ///     Signature verification is beginning 
            /// 
            BeginSignatureVerification, 
 
            /// 
            ///     Input data has been transformed to its canonicalized form 
            /// 
            CanonicalizedData,

            ///  
            ///     The result of signature format validation
            ///  
            FormatValidationResult, 

            ///  
            ///     Namespaces are being propigated into the signature
            /// 
            NamespacePropagation,
 
            /// 
            ///     Output from a Reference 
            ///  
            ReferenceData,
 
            /// 
            ///     The result of a signature verification
            /// 
            SignatureVerificationResult, 

            ///  
            ///     Calculating the final signature 
            /// 
            Signing, 

            /// 
            ///     A reference is being hashed
            ///  
            SigningReference,
 
            ///  
            ///     A signature has failed to verify
            ///  
            VerificationFailure,

            /// 
            ///     Verify that a reference has the correct hash value 
            /// 
            VerifyReference, 
 
            /// 
            ///     Verification is processing the SignedInfo section of the signature 
            /// 
            VerifySignedInfo,

            ///  
            ///     Verification status on the x.509 certificate in use
            ///  
            X509Verification 
        }
 
        /// 
        ///     Check to see if logging should be done in this process
        /// 
        private static bool InformationLoggingEnabled { 
            get {
                if (!s_informationLogging.HasValue) { 
                    s_informationLogging = s_traceSource.Switch.ShouldTrace(TraceEventType.Information); 
                }
 
                return s_informationLogging.Value;
            }
        }
 
        /// 
        ///     Check to see if verbose log messages should be generated 
        ///  
        private static bool VerboseLoggingEnabled {
            get { 
                if (!s_verboseLogging.HasValue) {
                    s_verboseLogging = s_traceSource.Switch.ShouldTrace(TraceEventType.Verbose);
                }
 
                return s_verboseLogging.Value;
            } 
        } 

        ///  
        ///     Convert the byte array into a hex string
        /// 
        private static string FormatBytes(byte[] bytes) {
            if (bytes == null) 
                return NullString;
 
            StringBuilder builder = new StringBuilder(bytes.Length * 2); 
            foreach (byte b in bytes) {
                builder.Append(b.ToString("x2", CultureInfo.InvariantCulture)); 
            }

            return builder.ToString();
        } 

        ///  
        ///     Map a key to a string describing the key 
        /// 
        private static string GetKeyName(object key) { 
            Debug.Assert(key != null, "key != null");

            ICspAsymmetricAlgorithm cspKey = key as ICspAsymmetricAlgorithm;
            X509Certificate certificate = key as X509Certificate; 
            X509Certificate2 certificate2 = key as X509Certificate2;
 
            // 
            // Use the following sources for key names, if available:
            // 
            // * CAPI key         -> key container name
            // * X509Certificate2 -> subject simple name
            // * X509Certificate  -> subject name
            // * All others       -> hash code 
            //
 
            string keyName = null; 
            if (cspKey != null && cspKey.CspKeyContainerInfo.KeyContainerName != null) {
                keyName = String.Format(CultureInfo.InvariantCulture, 
                                        "\"{0}\"",
                                        cspKey.CspKeyContainerInfo.KeyContainerName);
            }
            else if (certificate2 != null) { 
                keyName = String.Format(CultureInfo.InvariantCulture,
                                        "\"{0}\"", 
                                        certificate2.GetNameInfo(X509NameType.SimpleName, false)); 
            }
            else if (certificate != null) { 
                keyName = String.Format(CultureInfo.InvariantCulture,
                                        "\"{0}\"",
                                        certificate.Subject);
            } 
            else {
                keyName = key.GetHashCode().ToString("x8", CultureInfo.InvariantCulture); 
            } 

            return String.Format(CultureInfo.InvariantCulture, "{0}#{1}", key.GetType().Name, keyName); 
        }

        /// 
        ///     Map an object to a string describing the object 
        /// 
        private static string GetObjectId(object o) { 
            Debug.Assert(o != null, "o != null"); 

            return String.Format(CultureInfo.InvariantCulture, 
                                 "{0}#{1}", o.GetType().Name,
                                 o.GetHashCode().ToString("x8", CultureInfo.InvariantCulture));
        }
 
        /// 
        ///     Map an OID to the friendliest name possible 
        ///  
        private static string GetOidName(Oid oid) {
            Debug.Assert(oid != null, "oid != null"); 

            string friendlyName = oid.FriendlyName;
            if (String.IsNullOrEmpty(friendlyName))
                friendlyName = oid.Value; 

            return friendlyName; 
        } 

        ///  
        ///     Log that canonicalization has begun on input data
        /// 
        /// SignedXml object doing the signing or verification
        /// transform canonicalizing the input 
        internal static void LogBeginCanonicalization(SignedXml signedXml, Transform canonicalizationTransform) {
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(canonicalizationTransform != null, "canonicalizationTransform != null"); 

            if (InformationLoggingEnabled) { 
                string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_BeginCanonicalization"),
                                                  canonicalizationTransform.Algorithm,
                                                  canonicalizationTransform.GetType().Name); 
                WriteLine(signedXml,
                          TraceEventType.Information, 
                          SignedXmlDebugEvent.BeginCanonicalization, 
                          logMessage);
            } 

            if (VerboseLoggingEnabled) {
                string canonicalizationSettings = String.Format(CultureInfo.InvariantCulture,
                                                                SecurityResources.GetResourceString("Log_CanonicalizationSettings"), 
                                                                canonicalizationTransform.Resolver.GetType(),
                                                                canonicalizationTransform.BaseURI); 
                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.BeginCanonicalization, 
                          canonicalizationSettings);
            }
        }
 
        /// 
        ///     Log that we're going to be validating the signature format itself 
        ///  
        /// SignedXml object doing the verification
        /// Callback delegate which is being used for format verification 
        internal static void LogBeginCheckSignatureFormat(SignedXml signedXml, Func formatValidator) {
            Debug.Assert(signedXml != null, "signedXml != null");
            Debug.Assert(formatValidator != null, "formatValidator != null");
 
            if (InformationLoggingEnabled) {
                MethodInfo validationMethod = formatValidator.Method; 
 
                string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_CheckSignatureFormat"), 
                                                  validationMethod.Module.Assembly.FullName,
                                                  validationMethod.DeclaringType.FullName,
                                                  validationMethod.Name);
                WriteLine(signedXml, TraceEventType.Information, SignedXmlDebugEvent.BeginCheckSignatureFormat, logMessage); 
            }
        } 
 
        /// 
        ///     Log that checking SignedInfo is beginning 
        /// 
        /// SignedXml object doing the verification
        /// SignedInfo object being verified
        internal static void LogBeginCheckSignedInfo(SignedXml signedXml, SignedInfo signedInfo) { 
            Debug.Assert(signedXml != null, "signedXml != null");
            Debug.Assert(signedInfo != null, " signedInfo != null"); 
 
            if (InformationLoggingEnabled) {
                string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                  SecurityResources.GetResourceString("Log_CheckSignedInfo"),
                                                  signedInfo.Id != null ? signedInfo.Id : NullString);
                WriteLine(signedXml, TraceEventType.Information, SignedXmlDebugEvent.BeginCheckSignedInfo, logMessage);
            } 
        }
 
        ///  
        ///     Log that signature computation is beginning
        ///  
        /// SignedXml object doing the signing
        /// Context of the signature
        internal static void LogBeginSignatureComputation(SignedXml signedXml, XmlElement context) {
            Debug.Assert(signedXml != null, "signedXml != null"); 

            if (InformationLoggingEnabled) { 
                WriteLine(signedXml, 
                          TraceEventType.Information,
                          SignedXmlDebugEvent.BeginSignatureComputation, 
                          SecurityResources.GetResourceString("Log_BeginSignatureComputation"));
            }

            if (VerboseLoggingEnabled) { 
                string contextData = String.Format(CultureInfo.InvariantCulture,
                                                   SecurityResources.GetResourceString("Log_XmlContext"), 
                                                   context != null ? context.OuterXml : NullString); 

                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.BeginSignatureComputation,
                          contextData);
            } 
        }
 
        ///  
        ///     Log that signature verification is beginning
        ///  
        /// SignedXml object doing the verification
        /// Context of the verification
        internal static void LogBeginSignatureVerification(SignedXml signedXml, XmlElement context) {
            Debug.Assert(signedXml != null, "signedXml != null"); 

            if (InformationLoggingEnabled) { 
                WriteLine(signedXml, 
                          TraceEventType.Information,
                          SignedXmlDebugEvent.BeginSignatureVerification, 
                          SecurityResources.GetResourceString("Log_BeginSignatureVerification"));
            }

            if (VerboseLoggingEnabled) { 
                string contextData = String.Format(CultureInfo.InvariantCulture,
                                                   SecurityResources.GetResourceString("Log_XmlContext"), 
                                                   context != null ? context.OuterXml : NullString); 

                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.BeginSignatureVerification,
                          contextData);
            } 
        }
 
        ///  
        ///     Log the canonicalized data
        ///  
        /// SignedXml object doing the signing or verification
        /// transform canonicalizing the input
        internal static void LogCanonicalizedOutput(SignedXml signedXml, Transform canonicalizationTransform) {
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(canonicalizationTransform != null, "canonicalizationTransform != null");
 
            if (VerboseLoggingEnabled) { 
                using (StreamReader reader = new StreamReader(canonicalizationTransform.GetOutput(typeof(Stream)) as Stream)) {
                    string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                      SecurityResources.GetResourceString("Log_CanonicalizedOutput"),
                                                      reader.ReadToEnd());
                    WriteLine(signedXml,
                              TraceEventType.Verbose, 
                              SignedXmlDebugEvent.CanonicalizedData,
                              logMessage); 
                } 
            }
        } 

        /// 
        ///     Log that the signature format callback has rejected the signature
        ///  
        /// SignedXml object doing the signature verification
        /// result of the signature format verification 
        internal static void LogFormatValidationResult(SignedXml signedXml, bool result) { 
            Debug.Assert(signedXml != null, "signedXml != null");
 
            if (InformationLoggingEnabled) {
                string logMessage = result ? SecurityResources.GetResourceString("Log_FormatValidationSuccessful") :
                                             SecurityResources.GetResourceString("Log_FormatValidationNotSuccessful");
                WriteLine(signedXml, TraceEventType.Information, SignedXmlDebugEvent.FormatValidationResult, logMessage); 
            }
        } 
 
        /// 
        ///     Log namespaces which are being propigated into the singature 
        /// 
        /// SignedXml doing the signing or verification
        /// namespaces being propigated
        internal static void LogNamespacePropagation(SignedXml signedXml, XmlNodeList namespaces) { 
            Debug.Assert(signedXml != null, "signedXml != null");
 
            if (InformationLoggingEnabled) { 
                if (namespaces != null) {
                    foreach (XmlAttribute propagatedNamespace in namespaces) { 
                        string propagationMessage = String.Format(CultureInfo.InvariantCulture,
                                                                  SecurityResources.GetResourceString("Log_PropagatingNamespace"),
                                                                  propagatedNamespace.Name,
                                                                  propagatedNamespace.Value); 

                        WriteLine(signedXml, 
                                  TraceEventType.Information, 
                                  SignedXmlDebugEvent.NamespacePropagation,
                                  propagationMessage); 
                    }
                }
                else {
                    WriteLine(signedXml, 
                              TraceEventType.Information,
                              SignedXmlDebugEvent.NamespacePropagation, 
                              SecurityResources.GetResourceString("Log_NoNamespacesPropagated")); 
                }
            } 
        }

        /// 
        ///     Log the output of a reference 
        /// 
        /// The reference being processed 
        /// Stream containing the output of the reference 
        /// Stream containing the output of the reference
        internal static Stream LogReferenceData(Reference reference, Stream data) { 
            if (VerboseLoggingEnabled) {
                //
                // Since the input data stream could be from the network or another source that does not
                // support rewinding, we will read the stream into a temporary MemoryStream that can be used 
                // to stringify the output and also return to the reference so that it can produce the hash
                // value. 
                // 

                MemoryStream ms = new MemoryStream(); 

                // First read the input stream into our temporary stream
                byte[] buffer = new byte[4096];
                int readBytes = 0; 
                do {
                    readBytes = data.Read(buffer, 0, buffer.Length); 
                    ms.Write(buffer, 0, readBytes); 
                } while (readBytes == buffer.Length);
 
                // Log out information about it
                string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_TransformedReferenceContents"),
                                                  Encoding.UTF8.GetString(ms.ToArray())); 
                WriteLine(reference,
                          TraceEventType.Verbose, 
                          SignedXmlDebugEvent.ReferenceData, 
                          logMessage);
 
                // Rewind to the beginning, so that the entire input stream is hashed
                ms.Seek(0, SeekOrigin.Begin);
                return ms;
            } 
            else {
                return data; 
            } 
        }
 
        /// 
        ///     Log the computation of a signature value when signing with an asymmetric algorithm
        /// 
        /// SignedXml object calculating the signature 
        /// key used for signing
        /// signature description being used to create the signature 
        /// hash algorithm used to digest the output 
        /// signature formatter used to do the signing
        internal static void LogSigning(SignedXml signedXml, 
                                        object key,
                                        SignatureDescription signatureDescription,
                                        HashAlgorithm hash,
                                        AsymmetricSignatureFormatter asymmetricSignatureFormatter) { 
            Debug.Assert(signedXml != null, "signedXml != null");
            Debug.Assert(signatureDescription != null, "signatureDescription != null"); 
            Debug.Assert(hash != null, "hash != null"); 
            Debug.Assert(asymmetricSignatureFormatter != null, "asymmetricSignatureFormatter != null");
 
            if (InformationLoggingEnabled) {
                string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_SigningAsymmetric"),
                                                  GetKeyName(key), 
                                                  signatureDescription.GetType().Name,
                                                  hash.GetType().Name, 
                                                  asymmetricSignatureFormatter.GetType().Name); 

                WriteLine(signedXml, 
                          TraceEventType.Information,
                          SignedXmlDebugEvent.Signing,
                          logMessage);
            } 
        }
 
        ///  
        ///     Log the computation of a signature value when signing with a keyed hash algorithm
        ///  
        /// SignedXml object calculating the signature
        /// key the signature is created with
        /// hash algorithm used to digest the output
        /// signature formatter used to do the signing 
        internal static void LogSigning(SignedXml signedXml, KeyedHashAlgorithm key) {
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(key != null, "key != null"); 

            if (InformationLoggingEnabled) { 
                string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_SigningHmac"),
                                                  key.GetType().Name);
 
                WriteLine(signedXml,
                          TraceEventType.Information, 
                          SignedXmlDebugEvent.Signing, 
                          logMessage);
            } 
        }

        /// 
        ///     Log the calculation of a hash value of a reference 
        /// 
        /// SignedXml object driving the signature 
        /// Reference being hashed 
        internal static void LogSigningReference(SignedXml signedXml, Reference reference) {
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(reference != null, "reference != null");

            if (VerboseLoggingEnabled) {
                string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                  SecurityResources.GetResourceString("Log_SigningReference"),
                                                  GetObjectId(reference), 
                                                  reference.Uri, 
                                                  reference.Id,
                                                  reference.Type, 
                                                  reference.DigestMethod,
                                                  CryptoConfig.CreateFromName(reference.DigestMethod).GetType().Name);

                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.SigningReference, 
                          logMessage); 
            }
        } 

        /// 
        ///     Log the specific point where a signature is determined to not be verifiable
        ///  
        /// SignedXml object doing the verification
        /// location that the signature was determined to be invalid 
        internal static void LogVerificationFailure(SignedXml signedXml, string failureLocation) { 
            if (InformationLoggingEnabled) {
                string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                  SecurityResources.GetResourceString("Log_VerificationFailed"),
                                                  failureLocation);

                WriteLine(signedXml, 
                          TraceEventType.Information,
                          SignedXmlDebugEvent.VerificationFailure, 
                          logMessage); 
            }
        } 

        /// 
        ///     Log the success or failure of a signature verification operation
        ///  
        /// SignedXml object doing the verification
        /// public key used to verify the signature 
        /// true if the signature verified, false otherwise 
        internal static void LogVerificationResult(SignedXml signedXml, object key, bool verified) {
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(key != null, "key != null");

            if (InformationLoggingEnabled) {
                string resource = verified ? SecurityResources.GetResourceString("Log_VerificationWithKeySuccessful") : 
                                             SecurityResources.GetResourceString("Log_VerificationWithKeyNotSuccessful");
                string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                  resource, 
                                                  GetKeyName(key));
 
                WriteLine(signedXml,
                          TraceEventType.Information,
                          SignedXmlDebugEvent.SignatureVerificationResult,
                          logMessage); 
            }
        } 
 
        /// 
        ///     Log the check for appropriate X509 key usage 
        /// 
        /// SignedXml doing the signature verification
        /// certificate having its key usages checked
        /// key usages being examined 
        internal static void LogVerifyKeyUsage(SignedXml signedXml, X509Certificate certificate, X509KeyUsageExtension keyUsages) {
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(certificate != null, "certificate != null"); 

            if (InformationLoggingEnabled) { 
                string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_KeyUsages"),
                                                  keyUsages.KeyUsages,
                                                  GetOidName(keyUsages.Oid), 
                                                  GetKeyName(certificate));
 
                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.X509Verification, 
                          logMessage);
            }
        }
 
        /// 
        ///     Log that we are verifying a reference 
        ///  
        /// SignedXMl object doing the verification
        /// reference being verified 
        internal static void LogVerifyReference(SignedXml signedXml, Reference reference) {
            Debug.Assert(signedXml != null, "signedXml != null");
            Debug.Assert(reference != null, "reference != null");
 
            if (InformationLoggingEnabled) {
                string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                  SecurityResources.GetResourceString("Log_VerifyReference"), 
                                                  GetObjectId(reference),
                                                  reference.Uri, 
                                                  reference.Id,
                                                  reference.Type);

                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.VerifyReference, 
                          logMessage); 
            }
        } 

        /// 
        ///     Log the hash comparison when verifying a reference
        ///  
        /// SignedXml object verifying the signature
        /// reference being verified 
        /// actual hash value of the reference 
        /// hash value the signature expected the reference to have
        internal static void LogVerifyReferenceHash(SignedXml signedXml, 
                                                    Reference reference,
                                                    byte[] actualHash,
                                                    byte[] expectedHash) {
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(reference != null, "reference != null");
            Debug.Assert(actualHash != null, "actualHash != null"); 
            Debug.Assert(expectedHash != null, "expectedHash != null"); 

            if (VerboseLoggingEnabled) { 
                string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_ReferenceHash"),
                                                  GetObjectId(reference),
                                                  reference.DigestMethod, 
                                                  CryptoConfig.CreateFromName(reference.DigestMethod).GetType().Name,
                                                  FormatBytes(actualHash), 
                                                  FormatBytes(expectedHash)); 

                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.VerifyReference,
                          logMessage);
            } 
        }
 
        ///  
        ///     Log the verification parameters when verifying the SignedInfo section of a signature using an
        ///     asymmetric key 
        /// 
        /// SignedXml object doing the verification
        /// key being used to verify the signed info
        /// type of signature description class used 
        /// type of hash algorithm used
        /// type of signature deformatter used 
        /// hash value of the signed info 
        /// raw signature value
        internal static void LogVerifySignedInfo(SignedXml signedXml, 
                                                 AsymmetricAlgorithm key,
                                                 SignatureDescription signatureDescription,
                                                 HashAlgorithm hashAlgorithm,
                                                 AsymmetricSignatureDeformatter asymmetricSignatureDeformatter, 
                                                 byte[] actualHashValue,
                                                 byte[] signatureValue) { 
            Debug.Assert(signedXml != null, "signedXml != null"); 
            Debug.Assert(signatureDescription != null, "signatureDescription != null");
            Debug.Assert(hashAlgorithm != null, "hashAlgorithm != null"); 
            Debug.Assert(asymmetricSignatureDeformatter != null, "asymmetricSignatureDeformatter != null");

            if (InformationLoggingEnabled) {
                string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                  SecurityResources.GetResourceString("Log_VerifySignedInfoAsymmetric"),
                                                  GetKeyName(key), 
                                                  signatureDescription.GetType().Name, 
                                                  hashAlgorithm.GetType().Name,
                                                  asymmetricSignatureDeformatter.GetType().Name); 
                WriteLine(signedXml,
                          TraceEventType.Information,
                          SignedXmlDebugEvent.VerifySignedInfo,
                          logMessage); 
            }
 
            if (VerboseLoggingEnabled) { 
                string hashLog = String.Format(CultureInfo.InvariantCulture,
                                               SecurityResources.GetResourceString("Log_ActualHashValue"), 
                                               FormatBytes(actualHashValue));
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.VerifySignedInfo, hashLog);

                string signatureLog = String.Format(CultureInfo.InvariantCulture, 
                                                    SecurityResources.GetResourceString("Log_RawSignatureValue"),
                                                    FormatBytes(signatureValue)); 
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.VerifySignedInfo, signatureLog); 
            }
        } 

        /// 
        ///     Log the verification parameters when verifying the SignedInfo section of a signature using a
        ///     keyed hash algorithm 
        /// 
        /// SignedXml object doing the verification 
        /// hash algoirthm doing the verification 
        /// hash value of the signed info
        /// raw signature value 
        internal static void LogVerifySignedInfo(SignedXml signedXml,
                                                 KeyedHashAlgorithm mac,
                                                 byte[] actualHashValue,
                                                 byte[] signatureValue) { 
            Debug.Assert(signedXml != null, "signedXml != null");
            Debug.Assert(mac != null, "mac != null"); 
 
            if (InformationLoggingEnabled) {
                string logMessage = String.Format(CultureInfo.InvariantCulture, 
                                                  SecurityResources.GetResourceString("Log_VerifySignedInfoHmac"),
                                                  mac.GetType().Name);
                WriteLine(signedXml,
                          TraceEventType.Information, 
                          SignedXmlDebugEvent.VerifySignedInfo,
                          logMessage); 
            } 

            if (VerboseLoggingEnabled) { 
                string hashLog = String.Format(CultureInfo.InvariantCulture,
                                               SecurityResources.GetResourceString("Log_ActualHashValue"),
                                               FormatBytes(actualHashValue));
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.VerifySignedInfo, hashLog); 

                string signatureLog = String.Format(CultureInfo.InvariantCulture, 
                                                    SecurityResources.GetResourceString("Log_RawSignatureValue"), 
                                                    FormatBytes(signatureValue));
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.VerifySignedInfo, signatureLog); 
            }
        }

        ///  
        ///     Log that an X509 chain is being built for a certificate
        ///  
        /// SignedXml object building the chain 
        /// chain built for the certificate
        /// certificate having the chain built for it 
        internal static void LogVerifyX509Chain(SignedXml signedXml, X509Chain chain, X509Certificate certificate) {
            Debug.Assert(signedXml != null, "signedXml != null");
            Debug.Assert(certificate != null, "certificate != null");
            Debug.Assert(chain != null, "chain != null"); 

            if (InformationLoggingEnabled) { 
                string buildMessage = String.Format(CultureInfo.InvariantCulture, 
                                                    SecurityResources.GetResourceString("Log_BuildX509Chain"),
                                                    GetKeyName(certificate)); 
                WriteLine(signedXml,
                          TraceEventType.Information,
                          SignedXmlDebugEvent.X509Verification,
                          buildMessage); 
            }
 
            if (VerboseLoggingEnabled) { 
                // Dump out the flags and other miscelanious information used for building
                string revocationMode = String.Format(CultureInfo.InvariantCulture, 
                                                      SecurityResources.GetResourceString("Log_RevocationMode"),
                                                      chain.ChainPolicy.RevocationFlag);
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, revocationMode);
 
                string revocationFlag = String.Format(CultureInfo.InvariantCulture,
                                                      SecurityResources.GetResourceString("Log_RevocationFlag"), 
                                                      chain.ChainPolicy.RevocationFlag); 
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, revocationFlag);
 
                string verificationFlags = String.Format(CultureInfo.InvariantCulture,
                                                         SecurityResources.GetResourceString("Log_VerificationFlag"),
                                                         chain.ChainPolicy.VerificationFlags);
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, verificationFlags); 

                string verificationTime = String.Format(CultureInfo.InvariantCulture, 
                                                        SecurityResources.GetResourceString("Log_VerificationTime"), 
                                                        chain.ChainPolicy.VerificationTime);
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, verificationTime); 

                string urlTimeout = String.Format(CultureInfo.InvariantCulture,
                                                  SecurityResources.GetResourceString("Log_UrlTimeout"),
                                                  chain.ChainPolicy.UrlRetrievalTimeout); 
                WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, urlTimeout);
            } 
 
            // If there were any errors in the chain, make sure to dump those out
            if (InformationLoggingEnabled) { 
                foreach (X509ChainStatus status in chain.ChainStatus) {
                    if (status.Status != X509ChainStatusFlags.NoError) {
                        string logMessage = String.Format(CultureInfo.InvariantCulture,
                                                          SecurityResources.GetResourceString("Log_X509ChainError"), 
                                                          status.Status,
                                                          status.StatusInformation); 
 
                        WriteLine(signedXml,
                                  TraceEventType.Information, 
                                  SignedXmlDebugEvent.X509Verification,
                                  logMessage);
                    }
                } 
            }
 
            // Finally, dump out the chain itself 
            if (VerboseLoggingEnabled) {
                StringBuilder chainElements = new StringBuilder(); 
                chainElements.Append(SecurityResources.GetResourceString("Log_CertificateChain"));

                foreach (X509ChainElement element in chain.ChainElements) {
                    chainElements.AppendFormat(CultureInfo.InvariantCulture, " {0}", GetKeyName(element.Certificate)); 
                }
 
                WriteLine(signedXml, 
                          TraceEventType.Verbose,
                          SignedXmlDebugEvent.X509Verification, 
                          chainElements.ToString());
            }
        }
 
        /// 
        ///     Write data to the log 
        ///  
        /// object doing the trace
        /// severity of the debug event 
        /// data being written
        /// type of event being traced
        private static void WriteLine(object source, TraceEventType eventType, SignedXmlDebugEvent eventId, string data) {
            Debug.Assert(source != null, "source != null"); 
            Debug.Assert(!String.IsNullOrEmpty(data), "!String.IsNullOrEmpty(data)");
            Debug.Assert(InformationLoggingEnabled, "InformationLoggingEnabled"); 
 
            s_traceSource.TraceEvent(eventType,
                                    (int)eventId, 
                                    "[{0}, {1}] {2}",
                                    GetObjectId(source),
                                    eventId,
                                    data); 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK