38d8e84702210c9bfbf047a95677d98a7f9c6a61
[mono.git] / mcs / class / Mono.Security / Mono.Security.Cryptography / MD5SHA1.cs
1 /* Transport Security Layer (TLS)
2  * Copyright (c) 2003-2004 Carlos Guzman Alvarez
3  * 
4  * Permission is hereby granted, free of charge, to any person 
5  * obtaining a copy of this software and associated documentation 
6  * files (the "Software"), to deal in the Software without restriction, 
7  * including without limitation the rights to use, copy, modify, merge, 
8  * publish, distribute, sublicense, and/or sell copies of the Software, 
9  * and to permit persons to whom the Software is furnished to do so, 
10  * subject to the following conditions:
11  * 
12  * The above copyright notice and this permission notice shall be included 
13  * in all copies or substantial portions of the Software.
14  * 
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
17  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
19  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
20  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
22  * DEALINGS IN THE SOFTWARE.
23  */
24
25 using System;
26 using System.Security.Cryptography;
27
28 using Mono.Security.Protocol.Tls;
29
30 namespace Mono.Security.Cryptography
31 {
32         internal class MD5SHA1 : HashAlgorithm
33         {
34                 #region Fields
35
36                 private HashAlgorithm   md5;
37                 private HashAlgorithm   sha;
38                 private bool                    hashing;
39
40                 #endregion
41
42                 #region Constructors
43
44                 public MD5SHA1() : base()
45                 {
46                         this.md5 = MD5.Create();
47                         this.sha = SHA1.Create();
48
49                         // Set HashSizeValue
50                         this.HashSizeValue = this.md5.HashSize + this.sha.HashSize;
51                 }
52
53                 #endregion
54
55                 #region Methods
56
57                 public override void Initialize()
58                 {
59                         this.md5.Initialize();
60                         this.sha.Initialize();
61                         this.hashing = false;
62                 }
63
64                 protected override byte[] HashFinal()
65                 {
66                         if (!hashing)
67                         {
68                                 this.hashing = true;
69                         }
70                         // Finalize the original hash
71                         this.md5.TransformFinalBlock(new byte[0], 0, 0);
72                         this.sha.TransformFinalBlock(new byte[0], 0, 0);
73
74                         byte[] hash = new byte[36];
75
76                         Buffer.BlockCopy(this.md5.Hash, 0, hash, 0, 16);
77                         Buffer.BlockCopy(this.sha.Hash, 0, hash, 16, 20);
78
79                         return hash;
80                 }
81
82                 protected override void HashCore(
83                         byte[] array,
84                         int ibStart,
85                         int cbSize)
86                 {
87                         if (!hashing)
88                         {
89                                 hashing = true;
90                         }
91                         this.md5.TransformBlock(array, ibStart, cbSize, array, ibStart);
92                         this.sha.TransformBlock(array, ibStart, cbSize, array, ibStart);
93                 }
94
95                 public byte[] CreateSignature(RSA rsa) 
96                 {
97                         if (rsa == null)
98                         {
99                                 throw new CryptographicUnexpectedOperationException ("missing key");
100                         }
101
102                         RSASslSignatureFormatter f = new RSASslSignatureFormatter(rsa);
103                         f.SetHashAlgorithm("MD5SHA1");
104
105                         return f.CreateSignature(this.Hash);
106                 }
107
108                 public bool VerifySignature(RSA rsa, byte[] rgbSignature) 
109                 {
110                         if (rsa == null)
111                         {
112                                 throw new CryptographicUnexpectedOperationException ("missing key");
113                         }
114                         if (rgbSignature == null)
115                         {
116                                 throw new ArgumentNullException ("rgbSignature");
117                         }
118
119                         RSASslSignatureDeformatter d = new RSASslSignatureDeformatter(rsa);
120                         d.SetHashAlgorithm("MD5SHA1");
121
122                         return d.VerifySignature(this.Hash, rgbSignature);
123                 }
124
125                 #endregion
126         }
127 }