9bfd8c40810d001e710099e7261896fca137c21d
[mono.git] / mcs / class / corlib / System.Security.Cryptography / DSA.cs
1 //
2 // System.Security.Cryptography.DSA.cs class implementation
3 //
4 // Authors:
5 //   Thomas Neidhart (tome@sbox.tugraz.at)
6 //   Sebastien Pouliot (spouliot@motus.com)
7 //
8 // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
9 //
10
11 using System;
12 using System.Text;
13 using System.Xml;
14
15 // References:
16 // a.   FIPS PUB 186-2: Digital Signature Standard (DSS) 
17 //      http://csrc.nist.gov/publications/fips/fips186-2/fips186-2-change1.pdf
18
19 namespace System.Security.Cryptography
20 {
21         /// <summary>
22         /// Abstract base class for all implementations of the DSA algorithm
23         /// </summary>
24         public abstract class DSA : AsymmetricAlgorithm
25         {
26                 internal DSA () {}
27         
28                 public static new DSA Create ()
29                 {
30                         return Create ("System.Security.Cryptography.DSA");
31                 }
32
33                 public static new DSA Create (string algName) 
34                 {
35                         return (DSA) CryptoConfig.CreateFromName (algName);
36                 }
37                 
38                 public abstract byte[] CreateSignature (byte[] rgbHash);
39                 
40                 public abstract DSAParameters ExportParameters (bool includePrivateParameters);
41
42                 protected void ZeroizePrivateKey (DSAParameters parameters)
43                 {
44                         if (parameters.X != null)
45                                 Array.Clear (parameters.X, 0, parameters.X.Length);
46                 }
47
48                 public override void FromXmlString (string xmlString) 
49                 {
50                         if (xmlString == null)
51                                 throw new ArgumentNullException ();
52                         
53                         DSAParameters dsaParams = new DSAParameters ();
54                         try {
55                                 XmlDocument xml = new XmlDocument ();
56                                 xml.LoadXml (xmlString);
57                                 dsaParams.P = GetElement (xml, "P");
58                                 dsaParams.Q = GetElement (xml, "Q");
59                                 dsaParams.G = GetElement (xml, "G");
60                                 dsaParams.Y = GetElement (xml, "Y");
61                                 dsaParams.J = GetElement (xml, "J");
62                                 dsaParams.Seed = GetElement (xml, "Seed");
63                                 byte[] counter = GetElement (xml, "PgenCounter");
64                                 // else we may have an exception
65                                 byte[] counter4b = new byte[4];
66                                 Array.Copy (counter, 0, counter4b, 0, counter.Length);
67                                 dsaParams.Counter = BitConverter.ToInt32 (counter4b, 0);
68                                 dsaParams.X = GetElement (xml, "X");
69                                 ImportParameters (dsaParams);
70                         }
71                         catch {
72                                 ZeroizePrivateKey (dsaParams);
73                                 throw;
74                         }
75                         finally {
76                                 ZeroizePrivateKey (dsaParams);
77                         }
78                 }
79                 
80                 public abstract void ImportParameters (DSAParameters parameters);
81
82                 public override string ToXmlString (bool includePrivateParameters)
83                 {
84                         StringBuilder sb = new StringBuilder ();
85                         DSAParameters dsaParams = ExportParameters (includePrivateParameters);
86                         try {
87                                 sb.Append ("<DSAKeyValue>");
88                                 
89                                 sb.Append ("<P>");
90                                 sb.Append (Convert.ToBase64String (dsaParams.P));
91                                 sb.Append ("</P>");
92                                 
93                                 sb.Append ("<Q>");
94                                 sb.Append (Convert.ToBase64String (dsaParams.Q));
95                                 sb.Append ("</Q>");
96
97                                 sb.Append ("<G>");
98                                 sb.Append (Convert.ToBase64String (dsaParams.G));
99                                 sb.Append ("</G>");
100
101                                 sb.Append ("<Y>");
102                                 sb.Append (Convert.ToBase64String( dsaParams.Y));
103                                 sb.Append( "</Y>");
104
105                                 sb.Append ("<J>");
106                                 sb.Append (Convert.ToBase64String (dsaParams.J));
107                                 sb.Append ("</J>");
108                                 
109                                 sb.Append ("<Seed>");
110                                 sb.Append (Convert.ToBase64String (dsaParams.Seed));
111                                 sb.Append ("</Seed>");
112                                 
113                                 sb.Append ("<PgenCounter>");
114                                 // the number of bytes is important (no matter == 0x00)
115                                 byte[] inArr = BitConverter.GetBytes (dsaParams.Counter);
116                                 int l = inArr.Length;
117                                 while (inArr[l-1] == 0x00)
118                                         l--;
119                                 byte[] c = new byte[l];
120                                 Array.Copy (inArr, 0, c, 0, l);
121                                 sb.Append (Convert.ToBase64String (c));
122                                 sb.Append ("</PgenCounter>");
123
124                                 if (dsaParams.X != null) {
125                                         sb.Append ("<X>");
126                                         sb.Append (Convert.ToBase64String (dsaParams.X));
127                                         sb.Append ("</X>");
128                                 }
129                                 else if (includePrivateParameters)
130                                         throw new CryptographicException();
131
132                                 sb.Append ("</DSAKeyValue>");
133                         }
134                         catch {
135                                 ZeroizePrivateKey (dsaParams);
136                                 throw;
137                         }
138                         finally {
139                                 ZeroizePrivateKey (dsaParams);
140                         }
141                                                 
142                         return sb.ToString ();
143                 }
144                 
145                 public abstract bool VerifySignature (byte[] rgbHash, byte[] rgbSignature);
146                 
147         } // DSA
148         
149 } // System.Security.Cryptography