Merge pull request #4381 from BrzVlad/feature-generational-hash
[mono.git] / mcs / class / referencesource / System.Core / System / Security / Cryptography / ECDsa.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6
7 using System;
8 using System.IO;
9
10 namespace System.Security.Cryptography {
11     /// <summary>
12     ///     Base class for implementations of elliptic curve DSA
13     /// </summary>
14     [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
15     public abstract class ECDsa : AsymmetricAlgorithm {
16         public override string KeyExchangeAlgorithm {
17             get { return null; }
18         }
19
20         public override string SignatureAlgorithm {
21             get { return "ECDsa"; }
22         }
23
24         //
25         // Creation factory methods
26         //
27
28         public static new ECDsa Create() {
29 #if MONO
30             throw new NotImplementedException ();
31 #else
32             return Create(typeof(ECDsaCng).FullName);
33 #endif
34         }
35
36         public static new ECDsa Create(string algorithm) {
37             if (algorithm == null) {
38                 throw new ArgumentNullException("algorithm");
39             }
40
41             return CryptoConfig.CreateFromName(algorithm) as ECDsa;
42         }
43
44         public static ECDsa Create (ECCurve curve)
45         {
46             throw new NotImplementedException ();
47         }
48
49         public static ECDsa Create (ECParameters parameters)
50         {
51             throw new NotImplementedException ();
52         }
53
54         public virtual ECParameters ExportExplicitParameters (bool includePrivateParameters)
55         {
56             throw new NotImplementedException ();
57         }
58
59         public virtual ECParameters ExportParameters (bool includePrivateParameters)
60         {
61             throw new NotImplementedException ();
62         }
63
64         public virtual void GenerateKey (ECCurve curve)
65         {
66             throw new NotImplementedException ();
67         }
68
69         public virtual void ImportParameters (ECParameters parameters)
70         {
71             throw new NotImplementedException ();
72         }
73
74         //
75         // Signature operations
76         //
77
78         // ECDsa does not encode the algorithm identifier into the signature blob, therefore SignHash and VerifyHash
79         // do not need the HashAlgorithmName value, only SignData and VerifyData do.
80         public abstract byte[] SignHash(byte[] hash);
81         public abstract bool VerifyHash(byte[] hash, byte[] signature);
82
83         protected virtual byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) {
84             throw DerivedClassMustOverride();
85         }
86
87         protected virtual byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) {
88             throw DerivedClassMustOverride();
89         }
90
91         public virtual byte[] SignData(byte[] data, HashAlgorithmName hashAlgorithm) {
92             if (data == null) {
93                 throw new ArgumentNullException("data");
94             }
95             return SignData(data, 0, data.Length, hashAlgorithm);
96         }
97
98         public virtual byte[] SignData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) {
99             if (data == null) { throw new ArgumentNullException("data"); }
100             if (offset < 0 || offset > data.Length) { throw new ArgumentOutOfRangeException("offset"); }
101             if (count < 0 || count > data.Length - offset) { throw new ArgumentOutOfRangeException("count"); }
102             if (String.IsNullOrEmpty(hashAlgorithm.Name)) { throw HashAlgorithmNameNullOrEmpty(); }
103
104             byte[] hash = HashData(data, offset, count, hashAlgorithm);
105             return SignHash(hash);
106         }
107
108         public virtual byte[] SignData(Stream data, HashAlgorithmName hashAlgorithm) {
109             if (data == null) {
110                 throw new ArgumentNullException("data");
111             }
112             if (String.IsNullOrEmpty(hashAlgorithm.Name)) {
113                 throw HashAlgorithmNameNullOrEmpty();
114             }
115
116             byte[] hash = HashData(data, hashAlgorithm);
117             return SignHash(hash);
118         }
119
120         public bool VerifyData(byte[] data, byte[] signature, HashAlgorithmName hashAlgorithm) {
121             if (data == null) {
122                 throw new ArgumentNullException("data");
123             }
124             return VerifyData(data, 0, data.Length, signature, hashAlgorithm);
125         }
126
127         public virtual bool VerifyData(byte[] data, int offset, int count, byte[] signature, HashAlgorithmName hashAlgorithm) {
128             if (data == null) {
129                 throw new ArgumentNullException("data");
130             }
131             if (offset < 0 || offset > data.Length) {
132                 throw new ArgumentOutOfRangeException("offset");
133             }
134             if (count < 0 || count > data.Length - offset) {
135                 throw new ArgumentOutOfRangeException("count");
136             }
137             if (signature == null) {
138                 throw new ArgumentNullException("signature");
139             }
140             if (String.IsNullOrEmpty(hashAlgorithm.Name)) {
141                 throw HashAlgorithmNameNullOrEmpty();
142             }
143
144             byte[] hash = HashData(data, offset, count, hashAlgorithm);
145             return VerifyHash(hash, signature);
146         }
147
148         public bool VerifyData(Stream data, byte[] signature, HashAlgorithmName hashAlgorithm) {
149             if (data == null) {
150                 throw new ArgumentNullException("data");
151             }
152             if (signature == null) {
153                 throw new ArgumentNullException("signature");
154             }
155             if (String.IsNullOrEmpty(hashAlgorithm.Name)) {
156                 throw HashAlgorithmNameNullOrEmpty();
157             }
158
159             byte[] hash = HashData(data, hashAlgorithm);
160             return VerifyHash(hash, signature);
161         }
162
163         private static Exception DerivedClassMustOverride() {
164             return new NotImplementedException(SR.GetString(SR.NotSupported_SubclassOverride));
165         }
166
167         internal static Exception HashAlgorithmNameNullOrEmpty() {
168             return new ArgumentException(SR.GetString(SR.Cryptography_HashAlgorithmNameNullOrEmpty), "hashAlgorithm");
169         }
170     }
171 }