1package org.bouncycastle.jcajce.provider.asymmetric.ec;
2
3import java.io.IOException;
4import java.math.BigInteger;
5import java.security.InvalidKeyException;
6import java.security.PrivateKey;
7import java.security.PublicKey;
8
9import org.bouncycastle.asn1.ASN1EncodableVector;
10import org.bouncycastle.asn1.ASN1Encoding;
11import org.bouncycastle.asn1.ASN1Integer;
12import org.bouncycastle.asn1.ASN1Primitive;
13import org.bouncycastle.asn1.ASN1Sequence;
14import org.bouncycastle.asn1.DERSequence;
15import org.bouncycastle.crypto.CipherParameters;
16import org.bouncycastle.crypto.DSA;
17import org.bouncycastle.crypto.Digest;
18import org.bouncycastle.crypto.digests.NullDigest;
19// BEGIN android-added
20import org.bouncycastle.crypto.digests.AndroidDigestFactory;
21// END android-added
22// BEGIN android-removed
23// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
24// import org.bouncycastle.crypto.digests.SHA1Digest;
25// import org.bouncycastle.crypto.digests.SHA224Digest;
26// import org.bouncycastle.crypto.digests.SHA256Digest;
27// import org.bouncycastle.crypto.digests.SHA384Digest;
28// import org.bouncycastle.crypto.digests.SHA512Digest;
29// END android-removed
30import org.bouncycastle.crypto.params.ParametersWithRandom;
31import org.bouncycastle.crypto.signers.ECDSASigner;
32// BEGIN android-removed
33// import org.bouncycastle.crypto.signers.ECNRSigner;
34// import org.bouncycastle.crypto.signers.HMacDSAKCalculator;
35// END android-removed
36import org.bouncycastle.jcajce.provider.asymmetric.util.DSABase;
37import org.bouncycastle.jcajce.provider.asymmetric.util.DSAEncoder;
38import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
39
40public class SignatureSpi
41    extends DSABase
42{
43    SignatureSpi(Digest digest, DSA signer, DSAEncoder encoder)
44    {
45        super(digest, signer, encoder);
46    }
47
48    protected void engineInitVerify(PublicKey publicKey)
49        throws InvalidKeyException
50    {
51        CipherParameters param = ECUtil.generatePublicKeyParameter(publicKey);
52
53        digest.reset();
54        signer.init(false, param);
55    }
56
57    protected void engineInitSign(
58        PrivateKey privateKey)
59        throws InvalidKeyException
60    {
61        CipherParameters param = ECUtil.generatePrivateKeyParameter(privateKey);
62
63        digest.reset();
64
65        if (appRandom != null)
66        {
67            signer.init(true, new ParametersWithRandom(param, appRandom));
68        }
69        else
70        {
71            signer.init(true, param);
72        }
73    }
74
75    static public class ecDSA
76        extends SignatureSpi
77    {
78        public ecDSA()
79        {
80            // BEGIN android-changed
81            super(AndroidDigestFactory.getSHA1(), new ECDSASigner(), new StdDSAEncoder());
82            // END android-changed
83        }
84    }
85
86    // BEGIN android-removed
87    // static public class ecDetDSA
88    //     extends SignatureSpi
89    // {
90    //     public ecDetDSA()
91    //     {
92    //         super(new SHA1Digest(), new ECDSASigner(new HMacDSAKCalculator(new SHA1Digest())), new StdDSAEncoder());
93    //     }
94    // }
95    // END android-removed
96
97    static public class ecDSAnone
98        extends SignatureSpi
99    {
100        public ecDSAnone()
101        {
102            super(new NullDigest(), new ECDSASigner(), new StdDSAEncoder());
103        }
104    }
105
106    static public class ecDSA224
107        extends SignatureSpi
108    {
109        public ecDSA224()
110        {
111            // BEGIN android-changed
112            super(AndroidDigestFactory.getSHA224(), new ECDSASigner(), new StdDSAEncoder());
113            // END android-changed
114        }
115    }
116
117    // BEGIN android-removed
118    // static public class ecDetDSA224
119    //     extends SignatureSpi
120    // {
121    //     public ecDetDSA224()
122    //     {
123    //         super(new SHA224Digest(), new ECDSASigner(new HMacDSAKCalculator(new SHA224Digest())), new StdDSAEncoder());
124    //     }
125    // }
126    // END android-removed
127
128    static public class ecDSA256
129        extends SignatureSpi
130    {
131        public ecDSA256()
132        {
133            // BEGIN android-changed
134            super(AndroidDigestFactory.getSHA256(), new ECDSASigner(), new StdDSAEncoder());
135            // END android-changed
136        }
137    }
138
139    // BEGIN android-removed
140    // static public class ecDetDSA256
141    //     extends SignatureSpi
142    // {
143    //     public ecDetDSA256()
144    //     {
145    //         super(new SHA256Digest(), new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest())), new StdDSAEncoder());
146    //     }
147    // }
148    // END android-removed
149
150    static public class ecDSA384
151        extends SignatureSpi
152    {
153        public ecDSA384()
154        {
155            // BEGIN android-changed
156            super(AndroidDigestFactory.getSHA384(), new ECDSASigner(), new StdDSAEncoder());
157            // END android-changed
158        }
159    }
160
161    // BEGIN android-removed
162    // static public class ecDetDSA384
163    //     extends SignatureSpi
164    // {
165    //     public ecDetDSA384()
166    //     {
167    //         super(new SHA384Digest(), new ECDSASigner(new HMacDSAKCalculator(new SHA384Digest())), new StdDSAEncoder());
168    //     }
169    // }
170    // END android-removed
171
172    static public class ecDSA512
173        extends SignatureSpi
174    {
175        public ecDSA512()
176        {
177            // BEGIN android-changed
178            super(AndroidDigestFactory.getSHA512(), new ECDSASigner(), new StdDSAEncoder());
179            // END android-changed
180        }
181    }
182
183    // BEGIN android-removed
184    // static public class ecDetDSA512
185    //     extends SignatureSpi
186    // {
187    //     public ecDetDSA512()
188    //     {
189    //         super(new SHA512Digest(), new ECDSASigner(new HMacDSAKCalculator(new SHA512Digest())), new StdDSAEncoder());
190    //     }
191    // }
192    //
193    // static public class ecDSARipeMD160
194    //     extends SignatureSpi
195    // {
196    //     public ecDSARipeMD160()
197    //     {
198    //         super(new RIPEMD160Digest(), new ECDSASigner(), new StdDSAEncoder());
199    //     }
200    // }
201    //
202    // static public class ecNR
203    //     extends SignatureSpi
204    // {
205    //     public ecNR()
206    //     {
207    //         super(new SHA1Digest(), new ECNRSigner(), new StdDSAEncoder());
208    //     }
209    // }
210    //
211    // static public class ecNR224
212    //     extends SignatureSpi
213    // {
214    //     public ecNR224()
215    //     {
216    //         super(new SHA224Digest(), new ECNRSigner(), new StdDSAEncoder());
217    //     }
218    // }
219    //
220    // static public class ecNR256
221    //     extends SignatureSpi
222    // {
223    //     public ecNR256()
224    //     {
225    //         super(new SHA256Digest(), new ECNRSigner(), new StdDSAEncoder());
226    //     }
227    // }
228    //
229    // static public class ecNR384
230    //     extends SignatureSpi
231    // {
232    //     public ecNR384()
233    //     {
234    //         super(new SHA384Digest(), new ECNRSigner(), new StdDSAEncoder());
235    //     }
236    // }
237    //
238    // static public class ecNR512
239    //     extends SignatureSpi
240    // {
241    //     public ecNR512()
242    //     {
243    //         super(new SHA512Digest(), new ECNRSigner(), new StdDSAEncoder());
244    //     }
245    // }
246    //
247    // static public class ecCVCDSA
248    //     extends SignatureSpi
249    // {
250    //     public ecCVCDSA()
251    //     {
252    //         super(new SHA1Digest(), new ECDSASigner(), new PlainDSAEncoder());
253    //     }
254    // }
255    //
256    // static public class ecCVCDSA224
257    //     extends SignatureSpi
258    // {
259    //     public ecCVCDSA224()
260    //     {
261    //         super(new SHA224Digest(), new ECDSASigner(), new PlainDSAEncoder());
262    //     }
263    // }
264    //
265    // static public class ecCVCDSA256
266    //     extends SignatureSpi
267    // {
268    //     public ecCVCDSA256()
269    //     {
270    //         super(new SHA256Digest(), new ECDSASigner(), new PlainDSAEncoder());
271    //     }
272    // }
273    //
274    // static public class ecCVCDSA384
275    //     extends SignatureSpi
276    // {
277    //     public ecCVCDSA384()
278    //     {
279    //         super(new SHA384Digest(), new ECDSASigner(), new PlainDSAEncoder());
280    //     }
281    // }
282    //
283    // static public class ecCVCDSA512
284    //     extends SignatureSpi
285    // {
286    //     public ecCVCDSA512()
287    //     {
288    //         super(new SHA512Digest(), new ECDSASigner(), new PlainDSAEncoder());
289    //     }
290    // }
291    //
292    // static public class ecPlainDSARP160
293    //     extends SignatureSpi
294    // {
295    //     public ecPlainDSARP160()
296    //     {
297    //         super(new RIPEMD160Digest(), new ECDSASigner(), new PlainDSAEncoder());
298    //     }
299    // }
300    // END android-removed
301
302    private static class StdDSAEncoder
303        implements DSAEncoder
304    {
305        public byte[] encode(
306            BigInteger r,
307            BigInteger s)
308            throws IOException
309        {
310            ASN1EncodableVector v = new ASN1EncodableVector();
311
312            v.add(new ASN1Integer(r));
313            v.add(new ASN1Integer(s));
314
315            return new DERSequence(v).getEncoded(ASN1Encoding.DER);
316        }
317
318        public BigInteger[] decode(
319            byte[] encoding)
320            throws IOException
321        {
322            ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding);
323            BigInteger[] sig = new BigInteger[2];
324
325            sig[0] = ASN1Integer.getInstance(s.getObjectAt(0)).getValue();
326            sig[1] = ASN1Integer.getInstance(s.getObjectAt(1)).getValue();
327
328            return sig;
329        }
330    }
331
332    // BEGIN android-removed
333    // private static class PlainDSAEncoder
334    //     implements DSAEncoder
335    // {
336    //     public byte[] encode(
337    //         BigInteger r,
338    //         BigInteger s)
339    //         throws IOException
340    //     {
341    //         byte[] first = makeUnsigned(r);
342    //         byte[] second = makeUnsigned(s);
343    //         byte[] res;
344    //
345    //         if (first.length > second.length)
346    //         {
347    //             res = new byte[first.length * 2];
348    //         }
349    //         else
350    //         {
351    //             res = new byte[second.length * 2];
352    //         }
353    //
354    //         System.arraycopy(first, 0, res, res.length / 2 - first.length, first.length);
355    //         System.arraycopy(second, 0, res, res.length - second.length, second.length);
356    //
357    //         return res;
358    //     }
359    //
360    //
361    //     private byte[] makeUnsigned(BigInteger val)
362    //     {
363    //         byte[] res = val.toByteArray();
364    //
365    //         if (res[0] == 0)
366    //         {
367    //             byte[] tmp = new byte[res.length - 1];
368    //
369    //             System.arraycopy(res, 1, tmp, 0, tmp.length);
370    //
371    //             return tmp;
372    //         }
373    //
374    //         return res;
375    //     }
376    //
377    //     public BigInteger[] decode(
378    //         byte[] encoding)
379    //         throws IOException
380    //     {
381    //         BigInteger[] sig = new BigInteger[2];
382    //
383    //         byte[] first = new byte[encoding.length / 2];
384    //         byte[] second = new byte[encoding.length / 2];
385    //
386    //         System.arraycopy(encoding, 0, first, 0, first.length);
387    //         System.arraycopy(encoding, first.length, second, 0, second.length);
388    //
389    //         sig[0] = new BigInteger(1, first);
390    //         sig[1] = new BigInteger(1, second);
391    //
392    //         return sig;
393    //     }
394    // }
395    // END android-removed
396}
397