Merge pull request #4431 from vkargov/vk-leaking-points
[mono.git] / mcs / class / referencesource / System.Core / System / Security / Cryptography / CngAlgorithm.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6
7 using System;
8 using System.Diagnostics.Contracts;
9
10 namespace System.Security.Cryptography {
11     /// <summary>
12     ///     Utility class to strongly type algorithms used with CNG. Since all CNG APIs which require an
13     ///     algorithm name take the name as a string, we use this string wrapper class to specifically mark
14     ///     which parameters are expected to be algorithms.  We also provide a list of well known algorithm
15     ///     names, which helps Intellisense users find a set of good algorithm names to use.
16     /// </summary>
17     [Serializable]
18     [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
19     public sealed class CngAlgorithm : IEquatable<CngAlgorithm> {
20         private static volatile CngAlgorithm s_ecdhp256;
21         private static volatile CngAlgorithm s_ecdhp384;
22         private static volatile CngAlgorithm s_ecdhp521;
23         private static volatile CngAlgorithm s_ecdsap256;
24         private static volatile CngAlgorithm s_ecdsap384;
25         private static volatile CngAlgorithm s_ecdsap521;
26         private static volatile CngAlgorithm s_md5;
27         private static volatile CngAlgorithm s_sha1;
28         private static volatile CngAlgorithm s_sha256;
29         private static volatile CngAlgorithm s_sha384;
30         private static volatile CngAlgorithm s_sha512;
31         private static volatile CngAlgorithm s_rsa;
32
33         private string m_algorithm;
34
35         public CngAlgorithm(string algorithm) {
36             Contract.Ensures(!String.IsNullOrEmpty(m_algorithm));
37
38             if (algorithm == null) {
39                 throw new ArgumentNullException("algorithm");
40             }
41             if (algorithm.Length == 0) {
42                 throw new ArgumentException(SR.GetString(SR.Cryptography_InvalidAlgorithmName, algorithm), "algorithm");
43             }
44
45             m_algorithm = algorithm;
46         }
47
48         /// <summary>
49         ///     Name of the algorithm
50         /// </summary>
51         public string Algorithm {
52             get {
53                 Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()));
54                 return m_algorithm;
55             }
56         }
57
58         public static bool operator==(CngAlgorithm left, CngAlgorithm right) {
59             if (Object.ReferenceEquals(left, null)) {
60                 return Object.ReferenceEquals(right, null);
61             }
62
63             return left.Equals(right);
64         }
65
66         [Pure]
67         public static bool operator !=(CngAlgorithm left, CngAlgorithm right) {
68             if (Object.ReferenceEquals(left, null)) {
69                 return !Object.ReferenceEquals(right, null);
70             }
71
72             return !left.Equals(right);
73         }
74
75         public override bool Equals(object obj) {
76             Contract.Assert(m_algorithm != null);
77
78             return Equals(obj as CngAlgorithm);
79         }
80
81         public bool Equals(CngAlgorithm other) {
82             if (Object.ReferenceEquals(other, null)) {
83                 return false;
84             }
85
86             return m_algorithm.Equals(other.Algorithm);
87         }
88
89         public override int GetHashCode() {
90             Contract.Assert(m_algorithm != null);
91             return m_algorithm.GetHashCode();
92         }
93
94         public override string ToString() {
95             Contract.Assert(m_algorithm != null);
96             return m_algorithm;
97         }
98
99         //
100         // Well known algorithms
101         //
102
103         public static CngAlgorithm Rsa {
104             get {
105                 Contract.Ensures(Contract.Result<CngAlgorithm>() != null);
106                 if (s_rsa == null) {
107                     s_rsa = new CngAlgorithm(BCryptNative.AlgorithmName.Rsa);
108                 }
109                 return s_rsa;
110             }
111         }
112
113         public static CngAlgorithm ECDiffieHellmanP256 {
114             get {
115                 Contract.Ensures(Contract.Result<CngAlgorithm>() != null);
116
117                 if (s_ecdhp256 == null) {
118                     s_ecdhp256 = new CngAlgorithm(BCryptNative.AlgorithmName.ECDHP256);
119                 }
120
121                 return s_ecdhp256;
122             }
123         }
124
125         public static CngAlgorithm ECDiffieHellmanP384 {
126             get {
127                 Contract.Ensures(Contract.Result<CngAlgorithm>() != null);
128
129                 if (s_ecdhp384 == null) {
130                     s_ecdhp384 = new CngAlgorithm(BCryptNative.AlgorithmName.ECDHP384);
131                 }
132
133                 return s_ecdhp384;
134             }
135         }
136
137         public static CngAlgorithm ECDiffieHellmanP521 {
138             get {
139                 Contract.Ensures(Contract.Result<CngAlgorithm>() != null);
140
141                 if (s_ecdhp521 == null) {
142                     s_ecdhp521 = new CngAlgorithm(BCryptNative.AlgorithmName.ECDHP521);
143                 }
144
145                 return s_ecdhp521;
146             }
147         }
148
149         public static CngAlgorithm ECDsaP256 {
150             get {
151                 Contract.Ensures(Contract.Result<CngAlgorithm>() != null);
152
153                 if (s_ecdsap256 == null) {
154                     s_ecdsap256 = new CngAlgorithm(BCryptNative.AlgorithmName.ECDsaP256);
155                 }
156
157                 return s_ecdsap256;
158             }
159         }
160
161         public static CngAlgorithm ECDsaP384 {
162             get {
163                 Contract.Ensures(Contract.Result<CngAlgorithm>() != null);
164
165                 if (s_ecdsap384 == null) {
166                     s_ecdsap384 = new CngAlgorithm(BCryptNative.AlgorithmName.ECDsaP384);
167                 }
168
169                 return s_ecdsap384;
170             }
171         }
172
173         public static CngAlgorithm ECDsaP521 {
174             get {
175                 Contract.Ensures(Contract.Result<CngAlgorithm>() != null);
176
177                 if (s_ecdsap521 == null) {
178                     s_ecdsap521 = new CngAlgorithm(BCryptNative.AlgorithmName.ECDsaP521);
179                 }
180
181                 return s_ecdsap521;
182             }
183         }
184
185         public static CngAlgorithm MD5 {
186             get {
187                 Contract.Ensures(Contract.Result<CngAlgorithm>() != null);
188
189                 if (s_md5 == null) {
190                     s_md5 = new CngAlgorithm(BCryptNative.AlgorithmName.MD5);
191                 }
192
193                 return s_md5;
194             }
195         }
196
197         public static CngAlgorithm Sha1 {
198             get {
199                 Contract.Ensures(Contract.Result<CngAlgorithm>() != null);
200
201                 if (s_sha1 == null) {
202                     s_sha1 = new CngAlgorithm(BCryptNative.AlgorithmName.Sha1);
203                 }
204
205                 return s_sha1;
206             }
207         }
208
209         public static CngAlgorithm Sha256 {
210             get {
211                 Contract.Ensures(Contract.Result<CngAlgorithm>() != null);
212
213                 if (s_sha256 == null) {
214                     s_sha256 = new CngAlgorithm(BCryptNative.AlgorithmName.Sha256);
215                 }
216
217                 return s_sha256;
218             }
219         }
220
221         public static CngAlgorithm Sha384 {
222             get {
223                 Contract.Ensures(Contract.Result<CngAlgorithm>() != null);
224
225                 if (s_sha384 == null) {
226                     s_sha384 = new CngAlgorithm(BCryptNative.AlgorithmName.Sha384);
227                 }
228
229                 return s_sha384;
230             }
231         }
232
233         public static CngAlgorithm Sha512 {
234             get {
235                 Contract.Ensures(Contract.Result<CngAlgorithm>() != null);
236
237                 if (s_sha512 == null) {
238                     s_sha512 = new CngAlgorithm(BCryptNative.AlgorithmName.Sha512);
239                 }
240
241                 return s_sha512;
242             }
243         }
244
245         public static CngAlgorithm ECDiffieHellman {
246             get {
247                 throw new NotImplementedException ();
248             }
249         }
250
251         public static CngAlgorithm ECDsa {
252             get {
253                 throw new NotImplementedException ();
254             }
255         }
256     }
257 }