2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / Mono.Security / Mono.Security.Protocol.Tls.Handshake.Client / TlsClientKeyExchange.cs
1 // Transport Security Layer (TLS)
2 // Copyright (c) 2003-2004 Carlos Guzman Alvarez
3
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining
6 // a copy of this software and associated documentation files (the
7 // "Software"), to deal in the Software without restriction, including
8 // without limitation the rights to use, copy, modify, merge, publish,
9 // distribute, sublicense, and/or sell copies of the Software, and to
10 // permit persons to whom the Software is furnished to do so, subject to
11 // the following conditions:
12 // 
13 // The above copyright notice and this permission notice shall be
14 // included in all copies or substantial portions of the Software.
15 // 
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 //\r
24 \r
25 using System;
26 using System.IO;
27 using System.Security.Cryptography;
28
29 using Mono.Security.Cryptography;
30
31 namespace Mono.Security.Protocol.Tls.Handshake.Client
32 {
33         internal class TlsClientKeyExchange : HandshakeMessage
34         {
35                 #region Constructors
36
37                 public TlsClientKeyExchange (Context context) : 
38                         base(context, HandshakeType.ClientKeyExchange)
39                 {
40                 }
41
42                 #endregion
43
44                 #region Protected Methods
45
46                 protected override void ProcessAsSsl3()
47                 {
48                         // Compute pre master secret
49                         byte[] preMasterSecret = this.Context.Cipher.CreatePremasterSecret();
50
51                         // Create a new RSA key
52                         RSA rsa = null;
53                         if (this.Context.ServerSettings.ServerKeyExchange) 
54                         {
55                                 // this is the case for "exportable" ciphers
56                                 rsa = new RSAManaged ();
57                                 rsa.ImportParameters (this.Context.ServerSettings.RsaParameters);
58                         }
59                         else 
60                         {
61                                 rsa = this.Context.ServerSettings.CertificateRSA;
62                         }
63                         
64                         // Encrypt premaster_sercret
65                         RSAPKCS1KeyExchangeFormatter formatter = new RSAPKCS1KeyExchangeFormatter(rsa);
66
67                         // Write the preMasterSecret encrypted
68                         byte[] buffer = formatter.CreateKeyExchange(preMasterSecret);
69                         this.Write(buffer);
70
71                         // Create master secret
72                         this.Context.Cipher.ComputeMasterSecret(preMasterSecret);
73
74                         // Create keys
75                         this.Context.Cipher.ComputeKeys();
76
77                         // Clear resources
78                         rsa.Clear();
79                 }
80
81                 protected override void ProcessAsTls1()
82                 {
83                         // Compute pre master secret
84                         byte[] preMasterSecret = this.Context.Cipher.CreatePremasterSecret();
85
86                         // Create a new RSA key
87                         RSA rsa = null;
88                         if (this.Context.ServerSettings.ServerKeyExchange) 
89                         {
90                                 // this is the case for "exportable" ciphers
91                                 rsa = new RSAManaged ();
92                                 rsa.ImportParameters (this.Context.ServerSettings.RsaParameters);
93                         }
94                         else 
95                         {
96                                 rsa = this.Context.ServerSettings.CertificateRSA;
97                         }
98                         
99                         // Encrypt premaster_sercret
100                         RSAPKCS1KeyExchangeFormatter formatter = new RSAPKCS1KeyExchangeFormatter(rsa);
101
102                         // Write the preMasterSecret encrypted
103                         byte[] buffer = formatter.CreateKeyExchange(preMasterSecret);
104                         this.Write((short)buffer.Length);
105                         this.Write(buffer);
106
107                         // Create master secret
108                         this.Context.Cipher.ComputeMasterSecret(preMasterSecret);
109
110                         // Create keys
111                         this.Context.Cipher.ComputeKeys();
112
113                         // Clear resources
114                         rsa.Clear();
115                 }
116
117                 #endregion
118         }
119 }