22fb8b505282c8c34974ef47c336b90df0c1e7ba
[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         //
45         // Signature operations
46         //
47
48         // ECDsa does not encode the algorithm identifier into the signature blob, therefore SignHash and VerifyHash
49         // do not need the HashAlgorithmName value, only SignData and VerifyData do.
50         public abstract byte[] SignHash(byte[] hash);
51         public abstract bool VerifyHash(byte[] hash, byte[] signature);
52
53         protected virtual byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) {
54             throw DerivedClassMustOverride();
55         }
56
57         protected virtual byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) {
58             throw DerivedClassMustOverride();
59         }
60
61         public virtual byte[] SignData(byte[] data, HashAlgorithmName hashAlgorithm) {
62             if (data == null) {
63                 throw new ArgumentNullException("data");
64             }
65             return SignData(data, 0, data.Length, hashAlgorithm);
66         }
67
68         public virtual byte[] SignData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) {
69             if (data == null) { throw new ArgumentNullException("data"); }
70             if (offset < 0 || offset > data.Length) { throw new ArgumentOutOfRangeException("offset"); }
71             if (count < 0 || count > data.Length - offset) { throw new ArgumentOutOfRangeException("count"); }
72             if (String.IsNullOrEmpty(hashAlgorithm.Name)) { throw HashAlgorithmNameNullOrEmpty(); }
73
74             byte[] hash = HashData(data, offset, count, hashAlgorithm);
75             return SignHash(hash);
76         }
77
78         public virtual byte[] SignData(Stream data, HashAlgorithmName hashAlgorithm) {
79             if (data == null) {
80                 throw new ArgumentNullException("data");
81             }
82             if (String.IsNullOrEmpty(hashAlgorithm.Name)) {
83                 throw HashAlgorithmNameNullOrEmpty();
84             }
85
86             byte[] hash = HashData(data, hashAlgorithm);
87             return SignHash(hash);
88         }
89
90         public bool VerifyData(byte[] data, byte[] signature, HashAlgorithmName hashAlgorithm) {
91             if (data == null) {
92                 throw new ArgumentNullException("data");
93             }
94             return VerifyData(data, 0, data.Length, signature, hashAlgorithm);
95         }
96
97         public virtual bool VerifyData(byte[] data, int offset, int count, byte[] signature, HashAlgorithmName hashAlgorithm) {
98             if (data == null) {
99                 throw new ArgumentNullException("data");
100             }
101             if (offset < 0 || offset > data.Length) {
102                 throw new ArgumentOutOfRangeException("offset");
103             }
104             if (count < 0 || count > data.Length - offset) {
105                 throw new ArgumentOutOfRangeException("count");
106             }
107             if (signature == null) {
108                 throw new ArgumentNullException("signature");
109             }
110             if (String.IsNullOrEmpty(hashAlgorithm.Name)) {
111                 throw HashAlgorithmNameNullOrEmpty();
112             }
113
114             byte[] hash = HashData(data, offset, count, hashAlgorithm);
115             return VerifyHash(hash, signature);
116         }
117
118         public bool VerifyData(Stream data, byte[] signature, HashAlgorithmName hashAlgorithm) {
119             if (data == null) {
120                 throw new ArgumentNullException("data");
121             }
122             if (signature == null) {
123                 throw new ArgumentNullException("signature");
124             }
125             if (String.IsNullOrEmpty(hashAlgorithm.Name)) {
126                 throw HashAlgorithmNameNullOrEmpty();
127             }
128
129             byte[] hash = HashData(data, hashAlgorithm);
130             return VerifyHash(hash, signature);
131         }
132
133         private static Exception DerivedClassMustOverride() {
134             return new NotImplementedException(SR.GetString(SR.NotSupported_SubclassOverride));
135         }
136
137         internal static Exception HashAlgorithmNameNullOrEmpty() {
138             return new ArgumentException(SR.GetString(SR.Cryptography_HashAlgorithmNameNullOrEmpty), "hashAlgorithm");
139         }
140     }
141 }