2 // System.Security.Cryptography.DSA.cs class implementation
5 // Thomas Neidhart (tome@sbox.tugraz.at)
6 // Sebastien Pouliot (spouliot@motus.com)
8 // Portions (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
17 // a. FIPS PUB 186-2: Digital Signature Standard (DSS)
18 // http://csrc.nist.gov/publications/fips/fips186-2/fips186-2-change1.pdf
20 namespace System.Security.Cryptography {
23 /// Abstract base class for all implementations of the DSA algorithm
25 public abstract class DSA : AsymmetricAlgorithm {
27 // LAMESPEC: It says to derive new DSA implemenation from DSA class.
28 // Well it's aint gonna be easy this way.
29 // RSA constructor is public
32 public static new DSA Create ()
34 return Create ("System.Security.Cryptography.DSA");
37 public static new DSA Create (string algName)
39 return (DSA) CryptoConfig.CreateFromName (algName);
42 public abstract byte[] CreateSignature (byte[] rgbHash);
44 public abstract DSAParameters ExportParameters (bool includePrivateParameters);
46 internal void ZeroizePrivateKey (DSAParameters parameters)
48 if (parameters.X != null)
49 Array.Clear (parameters.X, 0, parameters.X.Length);
52 private byte[] GetNamedParam (SecurityElement se, string param)
54 SecurityElement sep = se.SearchForChildByTag (param);
57 return Convert.FromBase64String (sep.Text);
60 public override void FromXmlString (string xmlString)
62 if (xmlString == null)
63 throw new ArgumentNullException ("xmlString");
65 DSAParameters dsaParams = new DSAParameters ();
67 SecurityParser sp = new SecurityParser ();
68 sp.LoadXml (xmlString);
69 SecurityElement se = sp.ToXml ();
70 if (se.Tag != "DSAKeyValue")
71 throw new Exception ();
72 dsaParams.P = GetNamedParam (se, "P");
73 dsaParams.Q = GetNamedParam (se, "Q");
74 dsaParams.G = GetNamedParam (se, "G");
75 dsaParams.J = GetNamedParam (se, "J");
76 dsaParams.Y = GetNamedParam (se, "Y");
77 dsaParams.X = GetNamedParam (se, "X");
78 dsaParams.Seed = GetNamedParam (se, "Seed");
79 byte[] counter = GetNamedParam (se, "PgenCounter");
80 if (counter != null) {
81 byte[] counter4b = new byte [4]; // always 4 bytes
82 Array.Copy (counter, 0, counter4b, 0, counter.Length);
83 dsaParams.Counter = BitConverter.ToInt32 (counter4b, 0);
85 ImportParameters (dsaParams);
88 ZeroizePrivateKey (dsaParams);
92 ZeroizePrivateKey (dsaParams);
96 public abstract void ImportParameters (DSAParameters parameters);
98 // note: using SecurityElement.ToXml wouldn't generate the same string as the MS implementation
99 public override string ToXmlString (bool includePrivateParameters)
101 StringBuilder sb = new StringBuilder ();
102 DSAParameters dsaParams = ExportParameters (includePrivateParameters);
104 sb.Append ("<DSAKeyValue>");
107 sb.Append (Convert.ToBase64String (dsaParams.P));
111 sb.Append (Convert.ToBase64String (dsaParams.Q));
115 sb.Append (Convert.ToBase64String (dsaParams.G));
119 sb.Append (Convert.ToBase64String (dsaParams.Y));
123 sb.Append (Convert.ToBase64String (dsaParams.J));
126 if (dsaParams.Seed != null) {
127 sb.Append ("<Seed>");
128 sb.Append (Convert.ToBase64String (dsaParams.Seed));
129 sb.Append ("</Seed>");
131 sb.Append ("<PgenCounter>");
132 // the number of bytes is important (no matter == 0x00)
133 byte[] inArr = BitConverter.GetBytes (dsaParams.Counter);
134 int l = inArr.Length;
135 while (inArr[l-1] == 0x00)
137 byte[] c = new byte[l];
138 Array.Copy (inArr, 0, c, 0, l);
139 sb.Append (Convert.ToBase64String (c));
140 sb.Append ("</PgenCounter>");
143 if (dsaParams.X != null) {
145 sb.Append (Convert.ToBase64String (dsaParams.X));
148 else if (includePrivateParameters)
149 throw new CryptographicException();
151 sb.Append ("</DSAKeyValue>");
153 catch (NotImplementedException ex) {
154 ZeroizePrivateKey (dsaParams);
158 return sb.ToString ();
161 public abstract bool VerifySignature (byte[] rgbHash, byte[] rgbSignature);
165 } // System.Security.Cryptography