2002-11-17 Sebastien Pouliot <spouliot@videotron.ca>
[mono.git] / mcs / class / corlib / System.Security.Cryptography / RSA.cs
1 //
2 // System.Security.Cryptography.RSA.cs
3 //
4 // Authors:
5 //   Dan Lewis (dihlewis@yahoo.co.uk)
6 //   Sebastien Pouliot (spouliot@motus.com)
7 //
8 // (C) 2002
9 // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
10 //
11
12 using System;
13 using System.Text;
14
15 namespace System.Security.Cryptography 
16 {
17         internal class RSAHandler : MiniParser.IHandler {
18
19                 private RSAParameters rsa;
20                 private bool unknown;
21                 private byte[] temp;
22
23                 public RSAHandler () 
24                 {
25                         rsa = new RSAParameters();
26                 }
27
28                 public RSAParameters GetParams () {
29                         return rsa;
30                 }
31
32                 public void OnStartParsing (MiniParser parser) {}
33
34                 public void OnStartElement (string name, MiniParser.IAttrList attrs) {}
35
36                 public void OnEndElement (string name) {
37                         switch (name) {
38                                 case "P":
39                                         rsa.P = temp;
40                                         break;
41                                 case "Q":
42                                         rsa.Q = temp;
43                                         break;
44                                 case "D":
45                                         rsa.D = temp;
46                                         break;
47                                 case "DP":
48                                         rsa.DP = temp;
49                                         break;
50                                 case "DQ":
51                                         rsa.DQ = temp;
52                                         break;
53                                 case "Exponent":
54                                         rsa.Exponent = temp;
55                                         break;
56                                 case "InverseQ":
57                                         rsa.InverseQ = temp;
58                                         break;
59                                 case "Modulus":
60                                         rsa.Modulus = temp;
61                                         break;
62                                 default:
63                                         // unknown tag in parameters
64                                         break;
65                         }
66                 }
67
68                 public void OnChars (string ch) 
69                 {
70                         temp = Convert.FromBase64String (ch);
71                 }
72
73                 public void OnEndParsing (MiniParser parser) {}
74         }
75
76         public abstract class RSA : AsymmetricAlgorithm 
77         {
78                 public static new RSA Create () 
79                 {
80                         return Create ("System.Security.Cryptography.RSA");
81                 }
82
83                 public static new RSA Create (string algName)
84                 {
85                         return (RSA) CryptoConfig.CreateFromName (algName);
86                 }
87         
88                 public RSA () { }
89
90                 public abstract byte[] EncryptValue (byte[] rgb);
91                 public abstract byte[] DecryptValue (byte[] rgb);
92
93                 public abstract RSAParameters ExportParameters (bool include);
94                 public abstract void ImportParameters (RSAParameters parameters);
95
96                 protected void ZeroizePrivateKey (RSAParameters parameters)
97                 {
98                         if (parameters.P != null)
99                                 Array.Clear(parameters.P, 0, parameters.P.Length);
100                         if (parameters.Q != null)
101                                 Array.Clear(parameters.Q, 0, parameters.Q.Length);
102                         if (parameters.DP != null)
103                                 Array.Clear(parameters.DP, 0, parameters.DP.Length);
104                         if (parameters.DQ != null)
105                                 Array.Clear(parameters.DQ, 0, parameters.DQ.Length);
106                         if (parameters.InverseQ != null)
107                                 Array.Clear(parameters.InverseQ, 0, parameters.InverseQ.Length);
108                         if (parameters.D != null)
109                                 Array.Clear(parameters.D, 0, parameters.D.Length);
110                 }
111
112                 public override void FromXmlString (string xmlString) 
113                 {
114                         if (xmlString == null)
115                                 throw new ArgumentNullException ();
116
117                         RSAParameters rsaParams = new RSAParameters ();
118                         try {
119                                 MiniParser parser = new MiniParser ();
120                                 AsymmetricParameters reader = new AsymmetricParameters (xmlString);
121                                 RSAHandler handler = new RSAHandler ();
122                                 parser.Parse(reader, handler);
123                                 ImportParameters (handler.GetParams ());
124                         }
125                         catch {
126                                 ZeroizePrivateKey (rsaParams);
127                                 throw new CryptographicException ();
128                         }
129                         finally {
130                                 ZeroizePrivateKey (rsaParams);
131                         }
132                 }
133
134                 public override string ToXmlString (bool includePrivateParameters) 
135                 {
136                         StringBuilder sb = new StringBuilder ();
137                         RSAParameters rsaParams = ExportParameters (includePrivateParameters);
138                         try {
139                                 sb.Append ("<RSAKeyValue>");
140                                 
141                                 sb.Append ("<Modulus>");
142                                 sb.Append (Convert.ToBase64String (rsaParams.Modulus));
143                                 sb.Append ("</Modulus>");
144
145                                 sb.Append ("<Exponent>");
146                                 sb.Append (Convert.ToBase64String (rsaParams.Exponent));
147                                 sb.Append ("</Exponent>");
148
149                                 if (includePrivateParameters)
150                                 {
151                                         sb.Append ("<P>");
152                                         sb.Append (Convert.ToBase64String (rsaParams.P));
153                                         sb.Append ("</P>");
154
155                                         sb.Append ("<Q>");
156                                         sb.Append (Convert.ToBase64String (rsaParams.Q));
157                                         sb.Append ("</Q>");
158
159                                         sb.Append ("<DP>");
160                                         sb.Append (Convert.ToBase64String (rsaParams.DP));
161                                         sb.Append ("</DP>");
162
163                                         sb.Append ("<DQ>");
164                                         sb.Append (Convert.ToBase64String (rsaParams.DQ));
165                                         sb.Append ("</DQ>");
166
167                                         sb.Append ("<InverseQ>");
168                                         sb.Append (Convert.ToBase64String (rsaParams.InverseQ));
169                                         sb.Append ("</InverseQ>");
170
171                                         sb.Append ("<D>");
172                                         sb.Append (Convert.ToBase64String (rsaParams.D));
173                                         sb.Append ("</D>");
174                                 }
175                                 
176                                 sb.Append ("</RSAKeyValue>");
177                         }
178                         catch {
179                                 ZeroizePrivateKey (rsaParams);
180                                 throw;
181                         }
182                         
183                         return sb.ToString ();
184                 }
185         }
186 }