1package org.bouncycastle.jce.provider;
2
3import org.bouncycastle.asn1.ASN1Encodable;
4import org.bouncycastle.asn1.ASN1EncodableVector;
5import org.bouncycastle.asn1.ASN1Object;
6import org.bouncycastle.asn1.ASN1OctetString;
7import org.bouncycastle.asn1.ASN1Sequence;
8import org.bouncycastle.asn1.DERInteger;
9import org.bouncycastle.asn1.DERNull;
10import org.bouncycastle.asn1.DERObjectIdentifier;
11import org.bouncycastle.asn1.DEROctetString;
12import org.bouncycastle.asn1.DERSequence;
13// BEGIN android-removed
14// import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters;
15// import org.bouncycastle.asn1.oiw.ElGamalParameter;
16// END android-removed
17import org.bouncycastle.asn1.pkcs.DHParameter;
18import org.bouncycastle.asn1.pkcs.PKCS12PBEParams;
19import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
20// BEGIN android-removed
21// import org.bouncycastle.asn1.pkcs.RC2CBCParameter;
22// END android-removed
23import org.bouncycastle.asn1.pkcs.RSAESOAEPparams;
24import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
25import org.bouncycastle.asn1.pkcs.PBKDF2Params;
26import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
27import org.bouncycastle.asn1.x509.DSAParameter;
28// BEGIN android-removed
29// import org.bouncycastle.jce.spec.ElGamalParameterSpec;
30// import org.bouncycastle.jce.spec.GOST3410ParameterSpec;
31// import org.bouncycastle.jce.spec.GOST3410PublicKeyParameterSetSpec;
32// import org.bouncycastle.jce.spec.IESParameterSpec;
33// END android-removed
34import org.bouncycastle.util.Arrays;
35
36import javax.crypto.spec.DHParameterSpec;
37import javax.crypto.spec.IvParameterSpec;
38import javax.crypto.spec.OAEPParameterSpec;
39import javax.crypto.spec.PBEParameterSpec;
40import javax.crypto.spec.PSource;
41// BEGIN android-removed
42// import javax.crypto.spec.RC2ParameterSpec;
43// END android-removed
44import java.io.IOException;
45import java.security.AlgorithmParametersSpi;
46import java.security.spec.AlgorithmParameterSpec;
47import java.security.spec.DSAParameterSpec;
48import java.security.spec.InvalidParameterSpecException;
49import java.security.spec.MGF1ParameterSpec;
50import java.security.spec.PSSParameterSpec;
51
52public abstract class JDKAlgorithmParameters
53    extends AlgorithmParametersSpi
54{
55    protected boolean isASN1FormatString(String format)
56    {
57        return format == null || format.equals("ASN.1");
58    }
59
60    protected AlgorithmParameterSpec engineGetParameterSpec(
61        Class paramSpec)
62        throws InvalidParameterSpecException
63    {
64        if (paramSpec == null)
65        {
66            throw new NullPointerException("argument to getParameterSpec must not be null");
67        }
68
69        return localEngineGetParameterSpec(paramSpec);
70    }
71
72    protected abstract AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec)
73        throws InvalidParameterSpecException;
74
75    public static class IVAlgorithmParameters
76        extends JDKAlgorithmParameters
77    {
78        private byte[]  iv;
79
80        protected byte[] engineGetEncoded()
81            throws IOException
82        {
83            return engineGetEncoded("ASN.1");
84        }
85
86        protected byte[] engineGetEncoded(
87            String format)
88            throws IOException
89        {
90            if (isASN1FormatString(format))
91            {
92                 return new DEROctetString(engineGetEncoded("RAW")).getEncoded();
93            }
94
95            if (format.equals("RAW"))
96            {
97                return Arrays.clone(iv);
98            }
99
100            return null;
101        }
102
103        protected AlgorithmParameterSpec localEngineGetParameterSpec(
104            Class paramSpec)
105            throws InvalidParameterSpecException
106        {
107            if (paramSpec == IvParameterSpec.class)
108            {
109                return new IvParameterSpec(iv);
110            }
111
112            throw new InvalidParameterSpecException("unknown parameter spec passed to IV parameters object.");
113        }
114
115        protected void engineInit(
116            AlgorithmParameterSpec paramSpec)
117            throws InvalidParameterSpecException
118        {
119            if (!(paramSpec instanceof IvParameterSpec))
120            {
121                throw new InvalidParameterSpecException("IvParameterSpec required to initialise a IV parameters algorithm parameters object");
122            }
123
124            this.iv = ((IvParameterSpec)paramSpec).getIV();
125        }
126
127        protected void engineInit(
128            byte[] params)
129            throws IOException
130        {
131            //
132            // check that we don't have a DER encoded octet string
133            //
134            if ((params.length % 8) != 0
135                    && params[0] == 0x04 && params[1] == params.length - 2)
136            {
137                ASN1OctetString oct = (ASN1OctetString)ASN1Object.fromByteArray(params);
138
139                params = oct.getOctets();
140            }
141
142            this.iv = Arrays.clone(params);
143        }
144
145        protected void engineInit(
146            byte[] params,
147            String format)
148            throws IOException
149        {
150            if (isASN1FormatString(format))
151            {
152                try
153                {
154                    ASN1OctetString oct = (ASN1OctetString)ASN1Object.fromByteArray(params);
155
156                    engineInit(oct.getOctets());
157                }
158                catch (Exception e)
159                {
160                    throw new IOException("Exception decoding: " + e);
161                }
162
163                return;
164            }
165
166            if (format.equals("RAW"))
167            {
168                engineInit(params);
169                return;
170            }
171
172            throw new IOException("Unknown parameters format in IV parameters object");
173        }
174
175        protected String engineToString()
176        {
177            return "IV Parameters";
178        }
179    }
180
181    // BEGIN android-removed
182    // public static class RC2AlgorithmParameters
183    //     extends JDKAlgorithmParameters
184    // {
185    //     private static final short[] table = {
186    //        0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0,
187    //        0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a,
188    //        0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36,
189    //        0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c,
190    //        0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60,
191    //        0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa,
192    //        0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e,
193    //        0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf,
194    //        0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6,
195    //        0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3,
196    //        0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c,
197    //        0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2,
198    //        0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5,
199    //        0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5,
200    //        0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f,
201    //        0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab
202    //     };
203    //
204    //     private static final short[] ekb = {
205    //        0x5d, 0xbe, 0x9b, 0x8b, 0x11, 0x99, 0x6e, 0x4d, 0x59, 0xf3, 0x85, 0xa6, 0x3f, 0xb7, 0x83, 0xc5,
206    //        0xe4, 0x73, 0x6b, 0x3a, 0x68, 0x5a, 0xc0, 0x47, 0xa0, 0x64, 0x34, 0x0c, 0xf1, 0xd0, 0x52, 0xa5,
207    //        0xb9, 0x1e, 0x96, 0x43, 0x41, 0xd8, 0xd4, 0x2c, 0xdb, 0xf8, 0x07, 0x77, 0x2a, 0xca, 0xeb, 0xef,
208    //        0x10, 0x1c, 0x16, 0x0d, 0x38, 0x72, 0x2f, 0x89, 0xc1, 0xf9, 0x80, 0xc4, 0x6d, 0xae, 0x30, 0x3d,
209    //        0xce, 0x20, 0x63, 0xfe, 0xe6, 0x1a, 0xc7, 0xb8, 0x50, 0xe8, 0x24, 0x17, 0xfc, 0x25, 0x6f, 0xbb,
210    //        0x6a, 0xa3, 0x44, 0x53, 0xd9, 0xa2, 0x01, 0xab, 0xbc, 0xb6, 0x1f, 0x98, 0xee, 0x9a, 0xa7, 0x2d,
211    //        0x4f, 0x9e, 0x8e, 0xac, 0xe0, 0xc6, 0x49, 0x46, 0x29, 0xf4, 0x94, 0x8a, 0xaf, 0xe1, 0x5b, 0xc3,
212    //        0xb3, 0x7b, 0x57, 0xd1, 0x7c, 0x9c, 0xed, 0x87, 0x40, 0x8c, 0xe2, 0xcb, 0x93, 0x14, 0xc9, 0x61,
213    //        0x2e, 0xe5, 0xcc, 0xf6, 0x5e, 0xa8, 0x5c, 0xd6, 0x75, 0x8d, 0x62, 0x95, 0x58, 0x69, 0x76, 0xa1,
214    //        0x4a, 0xb5, 0x55, 0x09, 0x78, 0x33, 0x82, 0xd7, 0xdd, 0x79, 0xf5, 0x1b, 0x0b, 0xde, 0x26, 0x21,
215    //        0x28, 0x74, 0x04, 0x97, 0x56, 0xdf, 0x3c, 0xf0, 0x37, 0x39, 0xdc, 0xff, 0x06, 0xa4, 0xea, 0x42,
216    //        0x08, 0xda, 0xb4, 0x71, 0xb0, 0xcf, 0x12, 0x7a, 0x4e, 0xfa, 0x6c, 0x1d, 0x84, 0x00, 0xc8, 0x7f,
217    //        0x91, 0x45, 0xaa, 0x2b, 0xc2, 0xb1, 0x8f, 0xd5, 0xba, 0xf2, 0xad, 0x19, 0xb2, 0x67, 0x36, 0xf7,
218    //        0x0f, 0x0a, 0x92, 0x7d, 0xe3, 0x9d, 0xe9, 0x90, 0x3e, 0x23, 0x27, 0x66, 0x13, 0xec, 0x81, 0x15,
219    //        0xbd, 0x22, 0xbf, 0x9f, 0x7e, 0xa9, 0x51, 0x4b, 0x4c, 0xfb, 0x02, 0xd3, 0x70, 0x86, 0x31, 0xe7,
220    //        0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18, 0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd
221    //     };
222    //
223    //     private byte[]  iv;
224    //     private int     parameterVersion = 58;
225    //
226    //     protected byte[] engineGetEncoded()
227    //     {
228    //         return Arrays.clone(iv);
229    //     }
230    //
231    //     protected byte[] engineGetEncoded(
232    //         String format)
233    //         throws IOException
234    //     {
235    //         if (isASN1FormatString(format))
236    //         {
237    //             if (parameterVersion == -1)
238    //             {
239    //                 return new RC2CBCParameter(engineGetEncoded()).getEncoded();
240    //             }
241    //             else
242    //             {
243    //                 return new RC2CBCParameter(parameterVersion, engineGetEncoded()).getEncoded();
244    //             }
245    //         }
246    //
247    //         if (format.equals("RAW"))
248    //         {
249    //             return engineGetEncoded();
250    //         }
251    //
252    //         return null;
253    //     }
254    //
255    //     protected AlgorithmParameterSpec localEngineGetParameterSpec(
256    //         Class paramSpec)
257    //         throws InvalidParameterSpecException
258    //     {
259    //         if (paramSpec == RC2ParameterSpec.class)
260    //         {
261    //             if (parameterVersion != -1)
262    //             {
263    //                 if (parameterVersion < 256)
264    //                 {
265    //                     return new RC2ParameterSpec(ekb[parameterVersion], iv);
266    //                 }
267    //                 else
268    //                 {
269    //                     return new RC2ParameterSpec(parameterVersion, iv);
270    //                 }
271    //             }
272    //         }
273    //
274    //         if (paramSpec == IvParameterSpec.class)
275    //         {
276    //             return new IvParameterSpec(iv);
277    //         }
278    //
279    //         throw new InvalidParameterSpecException("unknown parameter spec passed to RC2 parameters object.");
280    //     }
281    //
282    //     protected void engineInit(
283    //         AlgorithmParameterSpec paramSpec)
284    //         throws InvalidParameterSpecException
285    //     {
286    //         if (paramSpec instanceof IvParameterSpec)
287    //         {
288    //             this.iv = ((IvParameterSpec)paramSpec).getIV();
289    //         }
290    //         else if (paramSpec instanceof RC2ParameterSpec)
291    //         {
292    //             int effKeyBits = ((RC2ParameterSpec)paramSpec).getEffectiveKeyBits();
293    //             if (effKeyBits != -1)
294    //             {
295    //                 if (effKeyBits < 256)
296    //                 {
297    //                     parameterVersion = table[effKeyBits];
298    //                 }
299    //                 else
300    //                 {
301    //                     parameterVersion = effKeyBits;
302    //                 }
303    //             }
304    //
305    //             this.iv = ((RC2ParameterSpec)paramSpec).getIV();
306    //         }
307    //         else
308    //         {
309    //             throw new InvalidParameterSpecException("IvParameterSpec or RC2ParameterSpec required to initialise a RC2 parameters algorithm parameters object");
310    //         }
311    //     }
312    //
313    //     protected void engineInit(
314    //         byte[] params)
315    //         throws IOException
316    //     {
317    //         this.iv = Arrays.clone(params);
318    //     }
319    //
320    //     protected void engineInit(
321    //         byte[] params,
322    //         String format)
323    //         throws IOException
324    //     {
325    //         if (isASN1FormatString(format))
326    //         {
327    //             RC2CBCParameter p = RC2CBCParameter.getInstance(ASN1Object.fromByteArray(params));
328    //
329    //             if (p.getRC2ParameterVersion() != null)
330    //             {
331    //                 parameterVersion = p.getRC2ParameterVersion().intValue();
332    //             }
333    //
334    //             iv = p.getIV();
335    //
336    //             return;
337    //         }
338    //
339    //         if (format.equals("RAW"))
340    //         {
341    //             engineInit(params);
342    //             return;
343    //         }
344    //
345    //         throw new IOException("Unknown parameters format in IV parameters object");
346    //     }
347    //
348    //     protected String engineToString()
349    //     {
350    //         return "RC2 Parameters";
351    //     }
352    // }
353    // END android-removed
354
355    public static class PBKDF2
356        extends JDKAlgorithmParameters
357    {
358        PBKDF2Params params;
359
360        protected byte[] engineGetEncoded()
361        {
362            try
363            {
364                return params.getEncoded(ASN1Encodable.DER);
365            }
366            catch (IOException e)
367            {
368                throw new RuntimeException("Oooops! " + e.toString());
369            }
370        }
371
372        protected byte[] engineGetEncoded(
373            String format)
374        {
375            if (isASN1FormatString(format))
376            {
377                return engineGetEncoded();
378            }
379
380            return null;
381        }
382
383        protected AlgorithmParameterSpec localEngineGetParameterSpec(
384            Class paramSpec)
385            throws InvalidParameterSpecException
386        {
387            if (paramSpec == PBEParameterSpec.class)
388            {
389                return new PBEParameterSpec(params.getSalt(),
390                                params.getIterationCount().intValue());
391            }
392
393            throw new InvalidParameterSpecException("unknown parameter spec passed to PKCS12 PBE parameters object.");
394        }
395
396        protected void engineInit(
397            AlgorithmParameterSpec paramSpec)
398            throws InvalidParameterSpecException
399        {
400            if (!(paramSpec instanceof PBEParameterSpec))
401            {
402                throw new InvalidParameterSpecException("PBEParameterSpec required to initialise a PKCS12 PBE parameters algorithm parameters object");
403            }
404
405            PBEParameterSpec    pbeSpec = (PBEParameterSpec)paramSpec;
406
407            this.params = new PBKDF2Params(pbeSpec.getSalt(),
408                                pbeSpec.getIterationCount());
409        }
410
411        protected void engineInit(
412            byte[] params)
413            throws IOException
414        {
415            this.params = PBKDF2Params.getInstance(ASN1Object.fromByteArray(params));
416        }
417
418        protected void engineInit(
419            byte[] params,
420            String format)
421            throws IOException
422        {
423            if (isASN1FormatString(format))
424            {
425                engineInit(params);
426                return;
427            }
428
429            throw new IOException("Unknown parameters format in PWRIKEK parameters object");
430        }
431
432        protected String engineToString()
433        {
434            return "PBKDF2 Parameters";
435        }
436    }
437
438    public static class PKCS12PBE
439        extends JDKAlgorithmParameters
440    {
441        PKCS12PBEParams params;
442
443        protected byte[] engineGetEncoded()
444        {
445            try
446            {
447                return params.getEncoded(ASN1Encodable.DER);
448            }
449            catch (IOException e)
450            {
451                throw new RuntimeException("Oooops! " + e.toString());
452            }
453        }
454
455        protected byte[] engineGetEncoded(
456            String format)
457        {
458            if (isASN1FormatString(format))
459            {
460                return engineGetEncoded();
461            }
462
463            return null;
464        }
465
466        protected AlgorithmParameterSpec localEngineGetParameterSpec(
467            Class paramSpec)
468            throws InvalidParameterSpecException
469        {
470            if (paramSpec == PBEParameterSpec.class)
471            {
472                return new PBEParameterSpec(params.getIV(),
473                                params.getIterations().intValue());
474            }
475
476            throw new InvalidParameterSpecException("unknown parameter spec passed to PKCS12 PBE parameters object.");
477        }
478
479        protected void engineInit(
480            AlgorithmParameterSpec paramSpec)
481            throws InvalidParameterSpecException
482        {
483            if (!(paramSpec instanceof PBEParameterSpec))
484            {
485                throw new InvalidParameterSpecException("PBEParameterSpec required to initialise a PKCS12 PBE parameters algorithm parameters object");
486            }
487
488            PBEParameterSpec    pbeSpec = (PBEParameterSpec)paramSpec;
489
490            this.params = new PKCS12PBEParams(pbeSpec.getSalt(),
491                                pbeSpec.getIterationCount());
492        }
493
494        protected void engineInit(
495            byte[] params)
496            throws IOException
497        {
498            this.params = PKCS12PBEParams.getInstance(ASN1Object.fromByteArray(params));
499        }
500
501        protected void engineInit(
502            byte[] params,
503            String format)
504            throws IOException
505        {
506            if (isASN1FormatString(format))
507            {
508                engineInit(params);
509                return;
510            }
511
512            throw new IOException("Unknown parameters format in PKCS12 PBE parameters object");
513        }
514
515        protected String engineToString()
516        {
517            return "PKCS12 PBE Parameters";
518        }
519    }
520
521    public static class DH
522        extends JDKAlgorithmParameters
523    {
524        DHParameterSpec     currentSpec;
525
526        /**
527         * Return the PKCS#3 ASN.1 structure DHParameter.
528         * <p>
529         * <pre>
530         *  DHParameter ::= SEQUENCE {
531         *                   prime INTEGER, -- p
532         *                   base INTEGER, -- g
533         *                   privateValueLength INTEGER OPTIONAL}
534         * </pre>
535         */
536        protected byte[] engineGetEncoded()
537        {
538            DHParameter dhP = new DHParameter(currentSpec.getP(), currentSpec.getG(), currentSpec.getL());
539
540            try
541            {
542                return dhP.getEncoded(ASN1Encodable.DER);
543            }
544            catch (IOException e)
545            {
546                throw new RuntimeException("Error encoding DHParameters");
547            }
548        }
549
550        protected byte[] engineGetEncoded(
551            String format)
552        {
553            if (isASN1FormatString(format))
554            {
555                return engineGetEncoded();
556            }
557
558            return null;
559        }
560
561        protected AlgorithmParameterSpec localEngineGetParameterSpec(
562            Class paramSpec)
563            throws InvalidParameterSpecException
564        {
565            if (paramSpec == DHParameterSpec.class)
566            {
567                return currentSpec;
568            }
569
570            throw new InvalidParameterSpecException("unknown parameter spec passed to DH parameters object.");
571        }
572
573        protected void engineInit(
574            AlgorithmParameterSpec paramSpec)
575            throws InvalidParameterSpecException
576        {
577            if (!(paramSpec instanceof DHParameterSpec))
578            {
579                throw new InvalidParameterSpecException("DHParameterSpec required to initialise a Diffie-Hellman algorithm parameters object");
580            }
581
582            this.currentSpec = (DHParameterSpec)paramSpec;
583        }
584
585        protected void engineInit(
586            byte[] params)
587            throws IOException
588        {
589            try
590            {
591                DHParameter dhP = new DHParameter((ASN1Sequence)ASN1Object.fromByteArray(params));
592
593                if (dhP.getL() != null)
594                {
595                    currentSpec = new DHParameterSpec(dhP.getP(), dhP.getG(), dhP.getL().intValue());
596                }
597                else
598                {
599                    currentSpec = new DHParameterSpec(dhP.getP(), dhP.getG());
600                }
601            }
602            catch (ClassCastException e)
603            {
604                throw new IOException("Not a valid DH Parameter encoding.");
605            }
606            catch (ArrayIndexOutOfBoundsException e)
607            {
608                throw new IOException("Not a valid DH Parameter encoding.");
609            }
610        }
611
612        protected void engineInit(
613            byte[] params,
614            String format)
615            throws IOException
616        {
617            if (isASN1FormatString(format))
618            {
619                engineInit(params);
620            }
621            else
622            {
623                throw new IOException("Unknown parameter format " + format);
624            }
625        }
626
627        protected String engineToString()
628        {
629            return "Diffie-Hellman Parameters";
630        }
631    }
632
633    public static class DSA
634        extends JDKAlgorithmParameters
635    {
636        DSAParameterSpec     currentSpec;
637
638        /**
639         * Return the X.509 ASN.1 structure DSAParameter.
640         * <p>
641         * <pre>
642         *  DSAParameter ::= SEQUENCE {
643         *                   prime INTEGER, -- p
644         *                   subprime INTEGER, -- q
645         *                   base INTEGER, -- g}
646         * </pre>
647         */
648        protected byte[] engineGetEncoded()
649        {
650            DSAParameter dsaP = new DSAParameter(currentSpec.getP(), currentSpec.getQ(), currentSpec.getG());
651
652            try
653            {
654                return dsaP.getEncoded(ASN1Encodable.DER);
655            }
656            catch (IOException e)
657            {
658                throw new RuntimeException("Error encoding DSAParameters");
659            }
660        }
661
662        protected byte[] engineGetEncoded(
663            String format)
664        {
665            if (isASN1FormatString(format))
666            {
667                return engineGetEncoded();
668            }
669
670            return null;
671        }
672
673        protected AlgorithmParameterSpec localEngineGetParameterSpec(
674            Class paramSpec)
675            throws InvalidParameterSpecException
676        {
677            if (paramSpec == DSAParameterSpec.class)
678            {
679                return currentSpec;
680            }
681
682            throw new InvalidParameterSpecException("unknown parameter spec passed to DSA parameters object.");
683        }
684
685        protected void engineInit(
686            AlgorithmParameterSpec paramSpec)
687            throws InvalidParameterSpecException
688        {
689            if (!(paramSpec instanceof DSAParameterSpec))
690            {
691                throw new InvalidParameterSpecException("DSAParameterSpec required to initialise a DSA algorithm parameters object");
692            }
693
694            this.currentSpec = (DSAParameterSpec)paramSpec;
695        }
696
697        protected void engineInit(
698            byte[] params)
699            throws IOException
700        {
701            try
702            {
703                DSAParameter dsaP = new DSAParameter((ASN1Sequence)ASN1Object.fromByteArray(params));
704
705                currentSpec = new DSAParameterSpec(dsaP.getP(), dsaP.getQ(), dsaP.getG());
706            }
707            catch (ClassCastException e)
708            {
709                throw new IOException("Not a valid DSA Parameter encoding.");
710            }
711            catch (ArrayIndexOutOfBoundsException e)
712            {
713                throw new IOException("Not a valid DSA Parameter encoding.");
714            }
715        }
716
717        protected void engineInit(
718            byte[] params,
719            String format)
720            throws IOException
721        {
722            if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509"))
723            {
724                engineInit(params);
725            }
726            else
727            {
728                throw new IOException("Unknown parameter format " + format);
729            }
730        }
731
732        protected String engineToString()
733        {
734            return "DSA Parameters";
735        }
736    }
737
738    // BEGIN android-removed
739    // public static class GOST3410
740    //     extends JDKAlgorithmParameters
741    // {
742    //     GOST3410ParameterSpec     currentSpec;
743    //
744    //     /**
745    //      * Return the X.509 ASN.1 structure GOST3410Parameter.
746    //      * <p>
747    //      * <pre>
748    //      *  GOST3410Parameter ::= SEQUENCE {
749    //      *                   prime INTEGER, -- p
750    //      *                   subprime INTEGER, -- q
751    //      *                   base INTEGER, -- a}
752    //      * </pre>
753    //      */
754    //     protected byte[] engineGetEncoded()
755    //     {
756    //         GOST3410PublicKeyAlgParameters gost3410P = new GOST3410PublicKeyAlgParameters(new DERObjectIdentifier(currentSpec.getPublicKeyParamSetOID()), new DERObjectIdentifier(currentSpec.getDigestParamSetOID()), new DERObjectIdentifier(currentSpec.getEncryptionParamSetOID()));
757    //
758    //         try
759    //         {
760    //             return gost3410P.getEncoded(ASN1Encodable.DER);
761    //         }
762    //         catch (IOException e)
763    //         {
764    //             throw new RuntimeException("Error encoding GOST3410Parameters");
765    //         }
766    //     }
767    //
768    //     protected byte[] engineGetEncoded(
769    //             String format)
770    //     {
771    //         if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509"))
772    //         {
773    //             return engineGetEncoded();
774    //         }
775    //
776    //         return null;
777    //     }
778    //
779    //     protected AlgorithmParameterSpec localEngineGetParameterSpec(
780    //             Class paramSpec)
781    //     throws InvalidParameterSpecException
782    //     {
783    //         if (paramSpec == GOST3410PublicKeyParameterSetSpec.class)
784    //         {
785    //             return currentSpec;
786    //         }
787    //
788    //         throw new InvalidParameterSpecException("unknown parameter spec passed to GOST3410 parameters object.");
789    //     }
790    //
791    //     protected void engineInit(
792    //             AlgorithmParameterSpec paramSpec)
793    //     throws InvalidParameterSpecException
794    //     {
795    //         if (!(paramSpec instanceof GOST3410ParameterSpec))
796    //         {
797    //             throw new InvalidParameterSpecException("GOST3410ParameterSpec required to initialise a GOST3410 algorithm parameters object");
798    //         }
799    //
800    //         this.currentSpec = (GOST3410ParameterSpec)paramSpec;
801    //     }
802    //
803    //     protected void engineInit(
804    //             byte[] params)
805    //     throws IOException
806    //     {
807    //         try
808    //         {
809    //             ASN1Sequence seq = (ASN1Sequence) ASN1Object.fromByteArray(params);
810    //
811    //             this.currentSpec = GOST3410ParameterSpec.fromPublicKeyAlg(
812    //                 new GOST3410PublicKeyAlgParameters(seq));
813    //         }
814    //         catch (ClassCastException e)
815    //         {
816    //             throw new IOException("Not a valid GOST3410 Parameter encoding.");
817    //         }
818    //         catch (ArrayIndexOutOfBoundsException e)
819    //         {
820    //             throw new IOException("Not a valid GOST3410 Parameter encoding.");
821    //         }
822    //     }
823    //
824    //     protected void engineInit(
825    //             byte[] params,
826    //             String format)
827    //     throws IOException
828    //     {
829    //         if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509"))
830    //         {
831    //             engineInit(params);
832    //         }
833    //         else
834    //         {
835    //             throw new IOException("Unknown parameter format " + format);
836    //         }
837    //     }
838    //
839    //     protected String engineToString()
840    //     {
841    //         return "GOST3410 Parameters";
842    //     }
843    // }
844
845    // public static class ElGamal
846    //     extends JDKAlgorithmParameters
847    // {
848    //     ElGamalParameterSpec     currentSpec;
849    //
850    //     /**
851    //      * Return the X.509 ASN.1 structure ElGamalParameter.
852    //      * <p>
853    //      * <pre>
854    //      *  ElGamalParameter ::= SEQUENCE {
855    //      *                   prime INTEGER, -- p
856    //      *                   base INTEGER, -- g}
857    //      * </pre>
858    //      */
859    //     protected byte[] engineGetEncoded()
860    //     {
861    //         ElGamalParameter elP = new ElGamalParameter(currentSpec.getP(), currentSpec.getG());
862    //
863    //         try
864    //         {
865    //             return elP.getEncoded(ASN1Encodable.DER);
866    //         }
867    //         catch (IOException e)
868    //         {
869    //             throw new RuntimeException("Error encoding ElGamalParameters");
870    //         }
871    //     }
872    //
873    //     protected byte[] engineGetEncoded(
874    //         String format)
875    //     {
876    //         if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509"))
877    //         {
878    //             return engineGetEncoded();
879    //         }
880    //
881    //         return null;
882    //     }
883    //
884    //     protected AlgorithmParameterSpec localEngineGetParameterSpec(
885    //         Class paramSpec)
886    //         throws InvalidParameterSpecException
887    //     {
888    //         if (paramSpec == ElGamalParameterSpec.class)
889    //         {
890    //             return currentSpec;
891    //         }
892    //         else if (paramSpec == DHParameterSpec.class)
893    //         {
894    //             return new DHParameterSpec(currentSpec.getP(), currentSpec.getG());
895    //         }
896    //
897    //         throw new InvalidParameterSpecException("unknown parameter spec passed to ElGamal parameters object.");
898    //     }
899    //
900    //     protected void engineInit(
901    //         AlgorithmParameterSpec paramSpec)
902    //         throws InvalidParameterSpecException
903    //     {
904    //         if (!(paramSpec instanceof ElGamalParameterSpec) && !(paramSpec instanceof DHParameterSpec))
905    //         {
906    //             throw new InvalidParameterSpecException("DHParameterSpec required to initialise a ElGamal algorithm parameters object");
907    //         }
908    //
909    //         if (paramSpec instanceof ElGamalParameterSpec)
910    //         {
911    //             this.currentSpec = (ElGamalParameterSpec)paramSpec;
912    //         }
913    //         else
914    //         {
915    //             DHParameterSpec s = (DHParameterSpec)paramSpec;
916    //
917    //             this.currentSpec = new ElGamalParameterSpec(s.getP(), s.getG());
918    //         }
919    //     }
920    //
921    //     protected void engineInit(
922    //         byte[] params)
923    //         throws IOException
924    //     {
925    //         try
926    //         {
927    //             ElGamalParameter elP = new ElGamalParameter((ASN1Sequence)ASN1Object.fromByteArray(params));
928    //
929    //             currentSpec = new ElGamalParameterSpec(elP.getP(), elP.getG());
930    //         }
931    //         catch (ClassCastException e)
932    //         {
933    //             throw new IOException("Not a valid ElGamal Parameter encoding.");
934    //         }
935    //         catch (ArrayIndexOutOfBoundsException e)
936    //         {
937    //             throw new IOException("Not a valid ElGamal Parameter encoding.");
938    //         }
939    //     }
940    //
941    //     protected void engineInit(
942    //         byte[] params,
943    //         String format)
944    //         throws IOException
945    //     {
946    //         if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509"))
947    //         {
948    //             engineInit(params);
949    //         }
950    //         else
951    //         {
952    //             throw new IOException("Unknown parameter format " + format);
953    //         }
954    //     }
955    //
956    //     protected String engineToString()
957    //     {
958    //         return "ElGamal Parameters";
959    //     }
960    // }
961    //
962    // public static class IES
963    //     extends JDKAlgorithmParameters
964    // {
965    //     IESParameterSpec     currentSpec;
966    //
967    //     /**
968    //      * in the absence of a standard way of doing it this will do for
969    //      * now...
970    //      */
971    //     protected byte[] engineGetEncoded()
972    //     {
973    //         try
974    //         {
975    //             ASN1EncodableVector v = new ASN1EncodableVector();
976    //
977    //             v.add(new DEROctetString(currentSpec.getDerivationV()));
978    //             v.add(new DEROctetString(currentSpec.getEncodingV()));
979    //             v.add(new DERInteger(currentSpec.getMacKeySize()));
980    //
981    //             return new DERSequence(v).getEncoded(ASN1Encodable.DER);
982    //         }
983    //         catch (IOException e)
984    //         {
985    //             throw new RuntimeException("Error encoding IESParameters");
986    //         }
987    //     }
988    //
989    //     protected byte[] engineGetEncoded(
990    //         String format)
991    //     {
992    //         if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509"))
993    //         {
994    //             return engineGetEncoded();
995    //         }
996    //
997    //         return null;
998    //     }
999    //
1000    //     protected AlgorithmParameterSpec localEngineGetParameterSpec(
1001    //         Class paramSpec)
1002    //         throws InvalidParameterSpecException
1003    //     {
1004    //         if (paramSpec == IESParameterSpec.class)
1005    //         {
1006    //             return currentSpec;
1007    //         }
1008    //
1009    //         throw new InvalidParameterSpecException("unknown parameter spec passed to ElGamal parameters object.");
1010    //     }
1011    //
1012    //     protected void engineInit(
1013    //         AlgorithmParameterSpec paramSpec)
1014    //         throws InvalidParameterSpecException
1015    //     {
1016    //         if (!(paramSpec instanceof IESParameterSpec))
1017    //         {
1018    //             throw new InvalidParameterSpecException("IESParameterSpec required to initialise a IES algorithm parameters object");
1019    //         }
1020    //
1021    //         this.currentSpec = (IESParameterSpec)paramSpec;
1022    //     }
1023    //
1024    //     protected void engineInit(
1025    //         byte[] params)
1026    //         throws IOException
1027    //     {
1028    //         try
1029    //         {
1030    //             ASN1Sequence s = (ASN1Sequence)ASN1Object.fromByteArray(params);
1031    //
1032    //             this.currentSpec = new IESParameterSpec(
1033    //                                     ((ASN1OctetString)s.getObjectAt(0)).getOctets(),
1034    //                                     ((ASN1OctetString)s.getObjectAt(0)).getOctets(),
1035    //                                     ((DERInteger)s.getObjectAt(0)).getValue().intValue());
1036    //         }
1037    //         catch (ClassCastException e)
1038    //         {
1039    //             throw new IOException("Not a valid IES Parameter encoding.");
1040    //         }
1041    //         catch (ArrayIndexOutOfBoundsException e)
1042    //         {
1043    //             throw new IOException("Not a valid IES Parameter encoding.");
1044    //         }
1045    //     }
1046    //
1047    //     protected void engineInit(
1048    //         byte[] params,
1049    //         String format)
1050    //         throws IOException
1051    //     {
1052    //         if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509"))
1053    //         {
1054    //             engineInit(params);
1055    //         }
1056    //         else
1057    //         {
1058    //             throw new IOException("Unknown parameter format " + format);
1059    //         }
1060    //     }
1061    //
1062    //     protected String engineToString()
1063    //     {
1064    //         return "IES Parameters";
1065    //     }
1066    // }
1067    // END android-removed
1068
1069    public static class OAEP
1070        extends JDKAlgorithmParameters
1071    {
1072        OAEPParameterSpec     currentSpec;
1073
1074        /**
1075         * Return the PKCS#1 ASN.1 structure RSAES-OAEP-params.
1076         */
1077        protected byte[] engineGetEncoded()
1078        {
1079            AlgorithmIdentifier     hashAlgorithm = new AlgorithmIdentifier(
1080                                                            JCEDigestUtil.getOID(currentSpec.getDigestAlgorithm()),
1081                                                            // BEGIN android-changed
1082                                                            DERNull.INSTANCE);
1083                                                            // END android-changed
1084            MGF1ParameterSpec       mgfSpec = (MGF1ParameterSpec)currentSpec.getMGFParameters();
1085            AlgorithmIdentifier     maskGenAlgorithm = new AlgorithmIdentifier(
1086                                                            PKCSObjectIdentifiers.id_mgf1,
1087                                                            // BEGIN android-changed
1088                                                            new AlgorithmIdentifier(JCEDigestUtil.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE));
1089                                                            // END android-changed
1090            PSource.PSpecified      pSource = (PSource.PSpecified)currentSpec.getPSource();
1091            AlgorithmIdentifier     pSourceAlgorithm = new AlgorithmIdentifier(
1092                                                            PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(pSource.getValue()));
1093            RSAESOAEPparams         oaepP = new RSAESOAEPparams(hashAlgorithm, maskGenAlgorithm, pSourceAlgorithm);
1094
1095            try
1096            {
1097                return oaepP.getEncoded(ASN1Encodable.DER);
1098            }
1099            catch (IOException e)
1100            {
1101                throw new RuntimeException("Error encoding OAEPParameters");
1102            }
1103        }
1104
1105        protected byte[] engineGetEncoded(
1106            String format)
1107        {
1108            if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509"))
1109            {
1110                return engineGetEncoded();
1111            }
1112
1113            return null;
1114        }
1115
1116        protected AlgorithmParameterSpec localEngineGetParameterSpec(
1117            Class paramSpec)
1118            throws InvalidParameterSpecException
1119        {
1120            if (paramSpec == OAEPParameterSpec.class && currentSpec != null)
1121            {
1122                return currentSpec;
1123            }
1124
1125            throw new InvalidParameterSpecException("unknown parameter spec passed to OAEP parameters object.");
1126        }
1127
1128        protected void engineInit(
1129            AlgorithmParameterSpec paramSpec)
1130            throws InvalidParameterSpecException
1131        {
1132            if (!(paramSpec instanceof OAEPParameterSpec))
1133            {
1134                throw new InvalidParameterSpecException("OAEPParameterSpec required to initialise an OAEP algorithm parameters object");
1135            }
1136
1137            this.currentSpec = (OAEPParameterSpec)paramSpec;
1138        }
1139
1140        protected void engineInit(
1141            byte[] params)
1142            throws IOException
1143        {
1144            try
1145            {
1146                RSAESOAEPparams oaepP = new RSAESOAEPparams((ASN1Sequence)ASN1Object.fromByteArray(params));
1147
1148                currentSpec = new OAEPParameterSpec(
1149                                       oaepP.getHashAlgorithm().getObjectId().getId(),
1150                                       oaepP.getMaskGenAlgorithm().getObjectId().getId(),
1151                                       new MGF1ParameterSpec(AlgorithmIdentifier.getInstance(oaepP.getMaskGenAlgorithm().getParameters()).getObjectId().getId()),
1152                                       new PSource.PSpecified(ASN1OctetString.getInstance(oaepP.getPSourceAlgorithm().getParameters()).getOctets()));
1153            }
1154            catch (ClassCastException e)
1155            {
1156                throw new IOException("Not a valid OAEP Parameter encoding.");
1157            }
1158            catch (ArrayIndexOutOfBoundsException e)
1159            {
1160                throw new IOException("Not a valid OAEP Parameter encoding.");
1161            }
1162        }
1163
1164        protected void engineInit(
1165            byte[] params,
1166            String format)
1167            throws IOException
1168        {
1169            if (format.equalsIgnoreCase("X.509")
1170                    || format.equalsIgnoreCase("ASN.1"))
1171            {
1172                engineInit(params);
1173            }
1174            else
1175            {
1176                throw new IOException("Unknown parameter format " + format);
1177            }
1178        }
1179
1180        protected String engineToString()
1181        {
1182            return "OAEP Parameters";
1183        }
1184    }
1185
1186    // BEGIN android-removed
1187    // public static class PSS
1188    //     extends JDKAlgorithmParameters
1189    // {
1190    //     PSSParameterSpec     currentSpec;
1191    //
1192    //     /**
1193    //      * Return the PKCS#1 ASN.1 structure RSASSA-PSS-params.
1194    //      */
1195    //     protected byte[] engineGetEncoded()
1196    //         throws IOException
1197    //     {
1198    //         PSSParameterSpec    pssSpec = currentSpec;
1199    //         AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(
1200    //                                             JCEDigestUtil.getOID(pssSpec.getDigestAlgorithm()),
1201    //                                             // BEGIN android-changed
1202    //                                             DERNull.INSTANCE);
1203    //                                             // END android-changed
1204    //         MGF1ParameterSpec   mgfSpec = (MGF1ParameterSpec)pssSpec.getMGFParameters();
1205    //         AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
1206    //                                             PKCSObjectIdentifiers.id_mgf1,
1207    //                                             // BEGIN android-changed
1208    //                                             new AlgorithmIdentifier(JCEDigestUtil.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE));
1209    //                                             // END android-changed
1210    //         RSASSAPSSparams     pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new DERInteger(pssSpec.getSaltLength()), new DERInteger(pssSpec.getTrailerField()));
1211    //
1212    //         return pssP.getEncoded("DER");
1213    //     }
1214    //
1215    //     protected byte[] engineGetEncoded(
1216    //         String format)
1217    //         throws IOException
1218    //     {
1219    //         if (format.equalsIgnoreCase("X.509")
1220    //                 || format.equalsIgnoreCase("ASN.1"))
1221    //         {
1222    //             return engineGetEncoded();
1223    //         }
1224    //
1225    //         return null;
1226    //     }
1227    //
1228    //     protected AlgorithmParameterSpec localEngineGetParameterSpec(
1229    //         Class paramSpec)
1230    //         throws InvalidParameterSpecException
1231    //     {
1232    //         if (paramSpec == PSSParameterSpec.class && currentSpec != null)
1233    //         {
1234    //             return currentSpec;
1235    //         }
1236    //
1237    //         throw new InvalidParameterSpecException("unknown parameter spec passed to PSS parameters object.");
1238    //     }
1239    //
1240    //     protected void engineInit(
1241    //         AlgorithmParameterSpec paramSpec)
1242    //         throws InvalidParameterSpecException
1243    //     {
1244    //         if (!(paramSpec instanceof PSSParameterSpec))
1245    //         {
1246    //             throw new InvalidParameterSpecException("PSSParameterSpec required to initialise an PSS algorithm parameters object");
1247    //         }
1248    //
1249    //         this.currentSpec = (PSSParameterSpec)paramSpec;
1250    //     }
1251    //
1252    //     protected void engineInit(
1253    //         byte[] params)
1254    //         throws IOException
1255    //     {
1256    //         try
1257    //         {
1258    //             RSASSAPSSparams pssP = new RSASSAPSSparams((ASN1Sequence)ASN1Object.fromByteArray(params));
1259    //
1260    //             currentSpec = new PSSParameterSpec(
1261    //                                    pssP.getHashAlgorithm().getObjectId().getId(),
1262    //                                    pssP.getMaskGenAlgorithm().getObjectId().getId(),
1263    //                                    new MGF1ParameterSpec(AlgorithmIdentifier.getInstance(pssP.getMaskGenAlgorithm().getParameters()).getObjectId().getId()),
1264    //                                    pssP.getSaltLength().getValue().intValue(),
1265    //                                    pssP.getTrailerField().getValue().intValue());
1266    //         }
1267    //         catch (ClassCastException e)
1268    //         {
1269    //             throw new IOException("Not a valid PSS Parameter encoding.");
1270    //         }
1271    //         catch (ArrayIndexOutOfBoundsException e)
1272    //         {
1273    //             throw new IOException("Not a valid PSS Parameter encoding.");
1274    //         }
1275    //     }
1276    //
1277    //     protected void engineInit(
1278    //         byte[] params,
1279    //         String format)
1280    //         throws IOException
1281    //     {
1282    //         if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509"))
1283    //         {
1284    //             engineInit(params);
1285    //         }
1286    //         else
1287    //         {
1288    //             throw new IOException("Unknown parameter format " + format);
1289    //         }
1290    //     }
1291    //
1292    //     protected String engineToString()
1293    //     {
1294    //         return "PSS Parameters";
1295    //     }
1296    // }
1297    // END android-removed
1298}
1299