Welcome to mirror list, hosted at ThFree Co, Russian Federation.

dsa.cs « cryptography « security « system « mscorlib « referencesource « class « mcs - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 51f9a9ae4cc12961e7f4424fab286906191e63b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// ==++==
// 
//   Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// ==--==
// <OWNER>[....]</OWNER>
// 

//
// DSA.cs
//

namespace System.Security.Cryptography {
    using System.Text;
    using System.Runtime.Serialization;
    using System.Security.Util;
    using System.Globalization;
    using System.Diagnostics.Contracts;

    // DSAParameters is serializable so that one could pass the public parameters
    // across a remote call, but we explicitly make the private key X non-serializable
    // so you cannot accidently send it along with the public parameters.
    [Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
    public struct DSAParameters {
        public byte[]      P;
        public byte[]      Q;
        public byte[]      G;
        public byte[]      Y;
        public byte[]      J;
        [NonSerialized] public byte[]      X;
        public byte[]      Seed;
        public int         Counter;
    }

[System.Runtime.InteropServices.ComVisible(true)]
    public abstract class DSA : AsymmetricAlgorithm
    {
        //
        //  Extending this class allows us to know that you are really implementing
        //  an DSA key.  This is required for anybody providing a new DSA key value
        //  implemention.
        //
        //  The class provides no methods, fields or anything else.  Its only purpose is
        //  as a heirarchy member for identification of the algorithm.
        //

        protected DSA() { }

        //
        // public methods
        //

        new static public DSA Create() {
#if FULL_AOT_RUNTIME
            return new System.Security.Cryptography.DSACryptoServiceProvider ();
#else
            return Create("System.Security.Cryptography.DSA");
#endif
        }

        new static public DSA Create(String algName) {
            return (DSA) CryptoConfig.CreateFromName(algName);
        }

        abstract public byte[] CreateSignature(byte[] rgbHash);

        abstract public bool VerifySignature(byte[] rgbHash, byte[] rgbSignature); 

        // We can provide a default implementation of FromXmlString because we require 
        // every DSA implementation to implement ImportParameters
        // All we have to do here is parse the XML.

        public override void FromXmlString(String xmlString) {
            if (xmlString == null) throw new ArgumentNullException("xmlString");
            Contract.EndContractBlock();
            DSAParameters dsaParams = new DSAParameters();
            Parser p = new Parser(xmlString);
            SecurityElement topElement = p.GetTopElement();

            // P is always present
            String pString = topElement.SearchForTextOfLocalName("P");
            if (pString == null) {
                throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidFromXmlString","DSA","P"));
            }
            dsaParams.P = Convert.FromBase64String(Utils.DiscardWhiteSpaces(pString));

            // Q is always present
            String qString = topElement.SearchForTextOfLocalName("Q");
            if (qString == null) {
                throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidFromXmlString","DSA","Q"));
            }
            dsaParams.Q = Convert.FromBase64String(Utils.DiscardWhiteSpaces(qString));

            // G is always present
            String gString = topElement.SearchForTextOfLocalName("G");
            if (gString == null) {
                throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidFromXmlString","DSA","G"));
            }
            dsaParams.G = Convert.FromBase64String(Utils.DiscardWhiteSpaces(gString));

            // Y is always present
            String yString = topElement.SearchForTextOfLocalName("Y");
            if (yString == null) {
                throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidFromXmlString","DSA","Y"));
            }
            dsaParams.Y = Convert.FromBase64String(Utils.DiscardWhiteSpaces(yString));

            // J is optional
            String jString = topElement.SearchForTextOfLocalName("J");
            if (jString != null) dsaParams.J = Convert.FromBase64String(Utils.DiscardWhiteSpaces(jString));

            // X is optional -- private key if present
            String xString = topElement.SearchForTextOfLocalName("X");
            if (xString != null) dsaParams.X = Convert.FromBase64String(Utils.DiscardWhiteSpaces(xString));

            // Seed and PgenCounter are optional as a unit -- both present or both absent
            String seedString = topElement.SearchForTextOfLocalName("Seed");
            String pgenCounterString = topElement.SearchForTextOfLocalName("PgenCounter");
            if ((seedString != null) && (pgenCounterString != null)) {
                dsaParams.Seed = Convert.FromBase64String(Utils.DiscardWhiteSpaces(seedString));
                dsaParams.Counter = Utils.ConvertByteArrayToInt(Convert.FromBase64String(Utils.DiscardWhiteSpaces(pgenCounterString)));
            } else if ((seedString != null) || (pgenCounterString != null)) {
                if (seedString == null) {
                    throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidFromXmlString","DSA","Seed"));
                } else {
                    throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidFromXmlString","DSA","PgenCounter"));
                }
            }

            ImportParameters(dsaParams);
        }

        // We can provide a default implementation of ToXmlString because we require 
        // every DSA implementation to implement ImportParameters
        // If includePrivateParameters is false, this is just an XMLDSIG DSAKeyValue
        // clause.  If includePrivateParameters is true, then we extend DSAKeyValue with 
        // the other (private) elements.

        public override String ToXmlString(bool includePrivateParameters) {
            // From the XMLDSIG spec, RFC 3075, Section 6.4.1, a DSAKeyValue looks like this:
            /* 
               <element name="DSAKeyValue"> 
                 <complexType> 
                   <sequence>
                     <sequence>
                       <element name="P" type="ds:CryptoBinary"/> 
                       <element name="Q" type="ds:CryptoBinary"/> 
                       <element name="G" type="ds:CryptoBinary"/> 
                       <element name="Y" type="ds:CryptoBinary"/> 
                       <element name="J" type="ds:CryptoBinary" minOccurs="0"/> 
                     </sequence>
                     <sequence minOccurs="0">
                       <element name="Seed" type="ds:CryptoBinary"/> 
                       <element name="PgenCounter" type="ds:CryptoBinary"/> 
                     </sequence>
                   </sequence>
                 </complexType>
               </element>
            */
            // we extend appropriately for private component X
            DSAParameters dsaParams = this.ExportParameters(includePrivateParameters);
            StringBuilder sb = new StringBuilder();
            sb.Append("<DSAKeyValue>");
            // Add P, Q, G and Y
            sb.Append("<P>"+Convert.ToBase64String(dsaParams.P)+"</P>");
            sb.Append("<Q>"+Convert.ToBase64String(dsaParams.Q)+"</Q>");
            sb.Append("<G>"+Convert.ToBase64String(dsaParams.G)+"</G>");
            sb.Append("<Y>"+Convert.ToBase64String(dsaParams.Y)+"</Y>");
            // Add optional components if present
            if (dsaParams.J != null) {
                sb.Append("<J>"+Convert.ToBase64String(dsaParams.J)+"</J>");
            }
            if ((dsaParams.Seed != null)) {  // note we assume counter is correct if Seed is present
                sb.Append("<Seed>"+Convert.ToBase64String(dsaParams.Seed)+"</Seed>");
                sb.Append("<PgenCounter>"+Convert.ToBase64String(Utils.ConvertIntToByteArray(dsaParams.Counter))+"</PgenCounter>");
            }

            if (includePrivateParameters) {
                // Add the private component
                sb.Append("<X>"+Convert.ToBase64String(dsaParams.X)+"</X>");
            } 
            sb.Append("</DSAKeyValue>");
            return(sb.ToString());
        }

        abstract public DSAParameters ExportParameters(bool includePrivateParameters);

        abstract public void ImportParameters(DSAParameters parameters);
    }
}