File: SymbolHelper.cs

package info (click to toggle)
mono 6.8.0.105%2Bdfsg-3.3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,284,512 kB
  • sloc: cs: 11,172,132; xml: 2,850,069; ansic: 671,653; cpp: 122,091; perl: 59,366; javascript: 30,841; asm: 22,168; makefile: 20,093; sh: 15,020; python: 4,827; pascal: 925; sql: 859; sed: 16; php: 1
file content (153 lines) | stat: -rw-r--r-- 5,307 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//-----------------------------------------------------------------------
// <copyright file="SymbolHelper.cs" company="Microsoft Corporation">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace System.Activities.Debugger.Symbol
{
    using System.Diagnostics.CodeAnalysis;
    using System.IO;
    using System.Linq;
    using System.Runtime;
    using System.Security;
    using System.Security.Cryptography;

    internal static class SymbolHelper
    {
        static readonly Guid Md5IdentifierGuid = new Guid("406ea660-64cf-4c82-b6f0-42d48172a799");
        static readonly Guid Sha1IdentifierGuid = new Guid("ff1816ec-aa5e-4d10-87f7-6f4963833460");

        public static Guid ChecksumProviderId
        {
            get
            {
                if (LocalAppContextSwitches.UseMD5ForWFDebugger)
                {
                    return Md5IdentifierGuid;
                }
                else
                {
                    return Sha1IdentifierGuid;
                }
            }
        }

        // This is the same Encode/Decode logic as the WCF FramingEncoder
        public static int ReadEncodedInt32(BinaryReader reader)
        {
            int value = 0;
            int bytesConsumed = 0;
            while (true)
            {
                int next = reader.ReadByte();
                value |= (next & 0x7F) << (bytesConsumed * 7);
                bytesConsumed++;
                if ((next & 0x80) == 0)
                {
                    break;
                }
            }

            return value;
        }

        // This is the same Encode/Decode logic as the WCF FramingEncoder
        public static void WriteEncodedInt32(BinaryWriter writer, int value)
        {
            Fx.Assert(value >= 0, "Must be non-negative");

            while ((value & 0xFFFFFF80) != 0)
            {
                writer.Write((byte)((value & 0x7F) | 0x80));
                value >>= 7;
            }

            writer.Write((byte)value);
        }

        public static int GetEncodedSize(int value)
        {
            Fx.Assert(value >= 0, "Must be non-negative");

            int count = 1;
            while ((value & 0xFFFFFF80) != 0)
            {
                count++;
                value >>= 7;
            }

            return count;
        }

        public static byte[] CalculateChecksum(string fileName)
        {
            Fx.Assert(!string.IsNullOrEmpty(fileName), "fileName should not be empty or null");
            byte[] checksum;
            try
            {
                using (StreamReader streamReader = new StreamReader(fileName))
                {
                    using (HashAlgorithm hashAlgorithm = CreateHashProvider())
                    {
                        checksum = hashAlgorithm.ComputeHash(streamReader.BaseStream);
                    }
                }
            }
            catch (IOException)
            {
                // DirectoryNotFoundException and FileNotFoundException are expected
                checksum = null;
            }
            catch (UnauthorizedAccessException)
            {
                // UnauthorizedAccessException is expected
                checksum = null;
            }
            catch (SecurityException)
            {
                // Must not have had enough permissions to access the file.
                checksum = null;
            }

            return checksum;
        }

        [Fx.Tag.SecurityNote(Critical = "Used to get a string from checksum that is provided by the user/from a file.",
            Safe = "We not exposing any critical data. Just converting the byte array to a hex string.")]
        [SecuritySafeCritical]
        public static string GetHexStringFromChecksum(byte[] checksum)
        {
            return checksum == null ? string.Empty : string.Join(string.Empty, checksum.Select(x => x.ToString("X2")).ToArray());
        }

        [Fx.Tag.SecurityNote(Critical = "Used to validate checksum that is provided by the user/from a file.",
            Safe = "We not exposing any critical data. Just validating that the provided checksum meets the format for the checksums we produce.")]
        [SecuritySafeCritical]
        internal static bool ValidateChecksum(byte[] checksumToValidate)
        {
            // We are using MD5.ComputeHash, which will return a 16 byte array.
            if (LocalAppContextSwitches.UseMD5ForWFDebugger)
            {
                return checksumToValidate.Length == 16;
            }
            else
            {
                return checksumToValidate.Length == 20;
            }
        }

        [SuppressMessage("Microsoft.Cryptographic.Standard", "CA5350:MD5CannotBeUsed",
            Justification = "Design has been approved.  We are not using MD5 for any security or cryptography purposes but rather as a hash.")]
        static HashAlgorithm CreateHashProvider()
        {
            if (LocalAppContextSwitches.UseMD5ForWFDebugger)
            {
                return new MD5CryptoServiceProvider();
            }
            else
            {
                return new SHA1CryptoServiceProvider();
            }
        }
    }
}