SignatureSpi.java revision e1142c149e244797ce73b0e7fad40816e447a817
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.ASN1Primitive;
12import org.bouncycastle.asn1.ASN1Sequence;
13import org.bouncycastle.asn1.DERInteger;
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// END android-removed
35import org.bouncycastle.jcajce.provider.asymmetric.util.DSABase;
36import org.bouncycastle.jcajce.provider.asymmetric.util.DSAEncoder;
37
38public class SignatureSpi
39    extends DSABase
40{
41    SignatureSpi(Digest digest, DSA signer, DSAEncoder encoder)
42    {
43        super(digest, signer, encoder);
44    }
45
46    protected void engineInitVerify(PublicKey publicKey)
47        throws InvalidKeyException
48    {
49        CipherParameters param = ECUtil.generatePublicKeyParameter(publicKey);
50
51        digest.reset();
52        signer.init(false, param);
53    }
54
55    protected void engineInitSign(
56        PrivateKey privateKey)
57        throws InvalidKeyException
58    {
59        CipherParameters param = ECUtil.generatePrivateKeyParameter(privateKey);
60
61        digest.reset();
62
63        if (appRandom != null)
64        {
65            signer.init(true, new ParametersWithRandom(param, appRandom));
66        }
67        else
68        {
69            signer.init(true, param);
70        }
71    }
72
73    static public class ecDSA
74        extends SignatureSpi
75    {
76        public ecDSA()
77        {
78            // BEGIN android-changed
79            super(AndroidDigestFactory.getSHA1(), new ECDSASigner(), new StdDSAEncoder());
80            // END android-changed
81        }
82    }
83
84    static public class ecDSAnone
85        extends SignatureSpi
86    {
87        public ecDSAnone()
88        {
89            super(new NullDigest(), new ECDSASigner(), new StdDSAEncoder());
90        }
91    }
92
93    // BEGIN android-removed
94    // static public class ecDSA224
95    //     extends SignatureSpi
96    // {
97    //     public ecDSA224()
98    //     {
99    //         super(new SHA224Digest(), new ECDSASigner(), new StdDSAEncoder());
100    //     }
101    // }
102    // END android-removed
103
104    static public class ecDSA256
105        extends SignatureSpi
106    {
107        public ecDSA256()
108        {
109            // BEGIN android-changed
110            super(AndroidDigestFactory.getSHA256(), new ECDSASigner(), new StdDSAEncoder());
111            // END android-changed
112        }
113    }
114
115    static public class ecDSA384
116        extends SignatureSpi
117    {
118        public ecDSA384()
119        {
120            // BEGIN android-changed
121            super(AndroidDigestFactory.getSHA384(), new ECDSASigner(), new StdDSAEncoder());
122            // END android-changed
123        }
124    }
125
126    static public class ecDSA512
127        extends SignatureSpi
128    {
129        public ecDSA512()
130        {
131            // BEGIN android-changed
132            super(AndroidDigestFactory.getSHA512(), new ECDSASigner(), new StdDSAEncoder());
133            // END android-changed
134        }
135    }
136
137    // BEGIN android-removed
138    // static public class ecDSARipeMD160
139    //     extends SignatureSpi
140    // {
141    //     public ecDSARipeMD160()
142    //     {
143    //         super(new RIPEMD160Digest(), new ECDSASigner(), new StdDSAEncoder());
144    //     }
145    // }
146    //
147    // static public class ecNR
148    //     extends SignatureSpi
149    // {
150    //     public ecNR()
151    //     {
152    //         super(new SHA1Digest(), new ECNRSigner(), new StdDSAEncoder());
153    //     }
154    // }
155    //
156    // static public class ecNR224
157    //     extends SignatureSpi
158    // {
159    //     public ecNR224()
160    //     {
161    //         super(new SHA224Digest(), new ECNRSigner(), new StdDSAEncoder());
162    //     }
163    // }
164    //
165    // static public class ecNR256
166    //     extends SignatureSpi
167    // {
168    //     public ecNR256()
169    //     {
170    //         super(new SHA256Digest(), new ECNRSigner(), new StdDSAEncoder());
171    //     }
172    // }
173    //
174    // static public class ecNR384
175    //     extends SignatureSpi
176    // {
177    //     public ecNR384()
178    //     {
179    //         super(new SHA384Digest(), new ECNRSigner(), new StdDSAEncoder());
180    //     }
181    // }
182    //
183    // static public class ecNR512
184    //     extends SignatureSpi
185    // {
186    //     public ecNR512()
187    //     {
188    //         super(new SHA512Digest(), new ECNRSigner(), new StdDSAEncoder());
189    //     }
190    // }
191    //
192    // static public class ecCVCDSA
193    //     extends SignatureSpi
194    // {
195    //     public ecCVCDSA()
196    //     {
197    //         super(new SHA1Digest(), new ECDSASigner(), new CVCDSAEncoder());
198    //     }
199    // }
200    //
201    // static public class ecCVCDSA224
202    //     extends SignatureSpi
203    // {
204    //     public ecCVCDSA224()
205    //     {
206    //         super(new SHA224Digest(), new ECDSASigner(), new CVCDSAEncoder());
207    //     }
208    // }
209    //
210    // static public class ecCVCDSA256
211    //     extends SignatureSpi
212    // {
213    //     public ecCVCDSA256()
214    //     {
215    //         super(new SHA256Digest(), new ECDSASigner(), new CVCDSAEncoder());
216    //     }
217    // }
218    // END android-removed
219
220    private static class StdDSAEncoder
221        implements DSAEncoder
222    {
223        public byte[] encode(
224            BigInteger r,
225            BigInteger s)
226            throws IOException
227        {
228            ASN1EncodableVector v = new ASN1EncodableVector();
229
230            v.add(new DERInteger(r));
231            v.add(new DERInteger(s));
232
233            return new DERSequence(v).getEncoded(ASN1Encoding.DER);
234        }
235
236        public BigInteger[] decode(
237            byte[] encoding)
238            throws IOException
239        {
240            ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding);
241            BigInteger[] sig = new BigInteger[2];
242
243            sig[0] = ((DERInteger)s.getObjectAt(0)).getValue();
244            sig[1] = ((DERInteger)s.getObjectAt(1)).getValue();
245
246            return sig;
247        }
248    }
249
250    private static class CVCDSAEncoder
251        implements DSAEncoder
252    {
253        public byte[] encode(
254            BigInteger r,
255            BigInteger s)
256            throws IOException
257        {
258            byte[] first = makeUnsigned(r);
259            byte[] second = makeUnsigned(s);
260            byte[] res;
261
262            if (first.length > second.length)
263            {
264                res = new byte[first.length * 2];
265            }
266            else
267            {
268                res = new byte[second.length * 2];
269            }
270
271            System.arraycopy(first, 0, res, res.length / 2 - first.length, first.length);
272            System.arraycopy(second, 0, res, res.length - second.length, second.length);
273
274            return res;
275        }
276
277
278        private byte[] makeUnsigned(BigInteger val)
279        {
280            byte[] res = val.toByteArray();
281
282            if (res[0] == 0)
283            {
284                byte[] tmp = new byte[res.length - 1];
285
286                System.arraycopy(res, 1, tmp, 0, tmp.length);
287
288                return tmp;
289            }
290
291            return res;
292        }
293
294        public BigInteger[] decode(
295            byte[] encoding)
296            throws IOException
297        {
298            BigInteger[] sig = new BigInteger[2];
299
300            byte[] first = new byte[encoding.length / 2];
301            byte[] second = new byte[encoding.length / 2];
302
303            System.arraycopy(encoding, 0, first, 0, first.length);
304            System.arraycopy(encoding, first.length, second, 0, second.length);
305
306            sig[0] = new BigInteger(1, first);
307            sig[1] = new BigInteger(1, second);
308
309            return sig;
310        }
311    }
312}
313