1package org.bouncycastle.jce.provider;
2
3import java.io.IOException;
4import java.io.InputStream;
5import java.security.InvalidKeyException;
6import java.security.Key;
7import java.security.KeyFactorySpi;
8import java.security.PrivateKey;
9import java.security.PublicKey;
10import java.security.interfaces.DSAPrivateKey;
11import java.security.interfaces.DSAPublicKey;
12import java.security.interfaces.RSAPrivateCrtKey;
13import java.security.interfaces.RSAPrivateKey;
14import java.security.interfaces.RSAPublicKey;
15import java.security.spec.DSAPrivateKeySpec;
16import java.security.spec.DSAPublicKeySpec;
17import java.security.spec.InvalidKeySpecException;
18import java.security.spec.KeySpec;
19import java.security.spec.PKCS8EncodedKeySpec;
20import java.security.spec.RSAPrivateCrtKeySpec;
21import java.security.spec.RSAPrivateKeySpec;
22import java.security.spec.RSAPublicKeySpec;
23import java.security.spec.X509EncodedKeySpec;
24
25import javax.crypto.interfaces.DHPrivateKey;
26import javax.crypto.interfaces.DHPublicKey;
27import javax.crypto.spec.DHPrivateKeySpec;
28import javax.crypto.spec.DHPublicKeySpec;
29
30import org.bouncycastle.asn1.ASN1InputStream;
31import org.bouncycastle.asn1.ASN1Sequence;
32import org.bouncycastle.asn1.DERObjectIdentifier;
33import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
34import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
35import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
36import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
37import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;
38import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
39import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
40// BEGIN android-removed
41// import org.bouncycastle.jce.interfaces.ElGamalPrivateKey;
42// import org.bouncycastle.jce.interfaces.ElGamalPublicKey;
43// import org.bouncycastle.jce.spec.ECPrivateKeySpec;
44// import org.bouncycastle.jce.spec.ECPublicKeySpec;
45// import org.bouncycastle.jce.spec.ElGamalPrivateKeySpec;
46// import org.bouncycastle.jce.spec.ElGamalPublicKeySpec;
47// import org.bouncycastle.jce.spec.GOST3410PrivateKeySpec;
48// import org.bouncycastle.jce.spec.GOST3410PublicKeySpec;
49// END android-removed
50
51public abstract class JDKKeyFactory
52    extends KeyFactorySpi
53{
54    protected boolean elGamalFactory = false;
55
56    public JDKKeyFactory()
57    {
58    }
59
60    protected KeySpec engineGetKeySpec(
61        Key    key,
62        Class    spec)
63    throws InvalidKeySpecException
64    {
65       if (spec.isAssignableFrom(PKCS8EncodedKeySpec.class) && key.getFormat().equals("PKCS#8"))
66       {
67               return new PKCS8EncodedKeySpec(key.getEncoded());
68       }
69       else if (spec.isAssignableFrom(X509EncodedKeySpec.class) && key.getFormat().equals("X.509"))
70       {
71               return new X509EncodedKeySpec(key.getEncoded());
72       }
73       else if (spec.isAssignableFrom(RSAPublicKeySpec.class) && key instanceof RSAPublicKey)
74       {
75            RSAPublicKey    k = (RSAPublicKey)key;
76
77            return new RSAPublicKeySpec(k.getModulus(), k.getPublicExponent());
78       }
79       else if (spec.isAssignableFrom(RSAPrivateKeySpec.class) && key instanceof RSAPrivateKey)
80       {
81            RSAPrivateKey    k = (RSAPrivateKey)key;
82
83            return new RSAPrivateKeySpec(k.getModulus(), k.getPrivateExponent());
84       }
85       else if (spec.isAssignableFrom(RSAPrivateCrtKeySpec.class) && key instanceof RSAPrivateCrtKey)
86       {
87            RSAPrivateCrtKey    k = (RSAPrivateCrtKey)key;
88
89            return new RSAPrivateCrtKeySpec(
90                            k.getModulus(), k.getPublicExponent(),
91                            k.getPrivateExponent(),
92                            k.getPrimeP(), k.getPrimeQ(),
93                            k.getPrimeExponentP(), k.getPrimeExponentQ(),
94                            k.getCrtCoefficient());
95       }
96       else if (spec.isAssignableFrom(DHPrivateKeySpec.class) && key instanceof DHPrivateKey)
97       {
98           DHPrivateKey k = (DHPrivateKey)key;
99
100           return new DHPrivateKeySpec(k.getX(), k.getParams().getP(), k.getParams().getG());
101       }
102       else if (spec.isAssignableFrom(DHPublicKeySpec.class) && key instanceof DHPublicKey)
103       {
104           DHPublicKey k = (DHPublicKey)key;
105
106           return new DHPublicKeySpec(k.getY(), k.getParams().getP(), k.getParams().getG());
107       }
108
109        throw new RuntimeException("not implemented yet " + key + " " + spec);
110    }
111
112    protected Key engineTranslateKey(
113        Key    key)
114        throws InvalidKeyException
115    {
116        if (key instanceof RSAPublicKey)
117        {
118            return new JCERSAPublicKey((RSAPublicKey)key);
119        }
120        else if (key instanceof RSAPrivateCrtKey)
121        {
122            return new JCERSAPrivateCrtKey((RSAPrivateCrtKey)key);
123        }
124        else if (key instanceof RSAPrivateKey)
125        {
126            return new JCERSAPrivateKey((RSAPrivateKey)key);
127        }
128        else if (key instanceof DHPublicKey)
129        {
130            // BEGIN android-removed
131            // if (elGamalFactory)
132            // {
133            //     return new JCEElGamalPublicKey((DHPublicKey)key);
134            // }
135            // else
136            // {
137            // END android-removed
138                return new JCEDHPublicKey((DHPublicKey)key);
139            // BEGIN android-removed
140            // }
141            // END android-removed
142        }
143        else if (key instanceof DHPrivateKey)
144        {
145            // BEGIN android-removed
146            // if (elGamalFactory)
147            // {
148            //     return new JCEElGamalPrivateKey((DHPrivateKey)key);
149            // }
150            // else
151            // {
152            // END android-removed
153                return new JCEDHPrivateKey((DHPrivateKey)key);
154            // BEGIN android-removed
155            // }
156            // END android-removed
157        }
158        else if (key instanceof DSAPublicKey)
159        {
160            return new JDKDSAPublicKey((DSAPublicKey)key);
161        }
162        else if (key instanceof DSAPrivateKey)
163        {
164            return new JDKDSAPrivateKey((DSAPrivateKey)key);
165        }
166        // BEGIN android-removed
167        // else if (key instanceof ElGamalPublicKey)
168        // {
169        //     return new JCEElGamalPublicKey((ElGamalPublicKey)key);
170        // }
171        // else if (key instanceof ElGamalPrivateKey)
172        // {
173        //    return new JCEElGamalPrivateKey((ElGamalPrivateKey)key);
174        // }
175        // END android-removed
176
177        throw new InvalidKeyException("key type unknown");
178    }
179
180    /**
181     * create a public key from the given DER encoded input stream.
182     */
183    static PublicKey createPublicKeyFromDERStream(
184        byte[]         in)
185        throws IOException
186    {
187        return createPublicKeyFromPublicKeyInfo(
188                new SubjectPublicKeyInfo((ASN1Sequence)(new ASN1InputStream(in).readObject())));
189    }
190
191    /**
192     * create a public key from the given public key info object.
193     */
194    static PublicKey createPublicKeyFromPublicKeyInfo(
195        SubjectPublicKeyInfo         info)
196    {
197        DERObjectIdentifier     algOid = info.getAlgorithmId().getObjectId();
198
199        if (RSAUtil.isRsaOid(algOid))
200        {
201            return new JCERSAPublicKey(info);
202        }
203        else if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement))
204        {
205            return new JCEDHPublicKey(info);
206        }
207        else if (algOid.equals(X9ObjectIdentifiers.dhpublicnumber))
208        {
209            return new JCEDHPublicKey(info);
210        }
211        // BEGIN android-removed
212        // else if (algOid.equals(OIWObjectIdentifiers.elGamalAlgorithm))
213        // {
214        //     return new JCEElGamalPublicKey(info);
215        // }
216        // END android-removed
217        else if (algOid.equals(X9ObjectIdentifiers.id_dsa))
218        {
219            return new JDKDSAPublicKey(info);
220        }
221        else if (algOid.equals(OIWObjectIdentifiers.dsaWithSHA1))
222        {
223            return new JDKDSAPublicKey(info);
224        }
225        // BEGIN android-removed
226        // else if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey))
227        // {
228        //     return new JCEECPublicKey(info);
229        // }
230        // else if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_94))
231        // {
232        //     return new JDKGOST3410PublicKey(info);
233        // }
234        // else if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_2001))
235        // {
236        //     return new JCEECPublicKey(info);
237        // }
238        else
239        {
240            throw new RuntimeException("algorithm identifier " + algOid + " in key not recognised");
241        }
242    }
243
244    /**
245     * create a private key from the given DER encoded input stream.
246     */
247    static PrivateKey createPrivateKeyFromDERStream(
248        byte[]         in)
249        throws IOException
250    {
251        return createPrivateKeyFromPrivateKeyInfo(
252                new PrivateKeyInfo((ASN1Sequence)(new ASN1InputStream(in).readObject())));
253    }
254
255    /**
256     * create a private key from the given public key info object.
257     */
258    static PrivateKey createPrivateKeyFromPrivateKeyInfo(
259        PrivateKeyInfo      info)
260    {
261        DERObjectIdentifier     algOid = info.getAlgorithmId().getObjectId();
262
263        if (RSAUtil.isRsaOid(algOid))
264        {
265              return new JCERSAPrivateCrtKey(info);
266        }
267        else if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement))
268        {
269              return new JCEDHPrivateKey(info);
270        }
271        // BEGIN android-removed
272        // else if (algOid.equals(OIWObjectIdentifiers.elGamalAlgorithm))
273        // {
274        //       return new JCEElGamalPrivateKey(info);
275        // }
276        // END android-removed
277        else if (algOid.equals(X9ObjectIdentifiers.id_dsa))
278        {
279              return new JDKDSAPrivateKey(info);
280        }
281        // BEGIN android-removed
282        // else if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey))
283        // {
284        //       return new JCEECPrivateKey(info);
285        // }
286        // else if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_94))
287        // {
288        //       return new JDKGOST3410PrivateKey(info);
289        // }
290        // else if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_2001))
291        // {
292        //       return new JCEECPrivateKey(info);
293        // }
294        // END android-removed
295        else
296        {
297            throw new RuntimeException("algorithm identifier " + algOid + " in key not recognised");
298        }
299    }
300
301    public static class RSA
302        extends JDKKeyFactory
303    {
304        public RSA()
305        {
306        }
307
308        protected PrivateKey engineGeneratePrivate(
309            KeySpec    keySpec)
310            throws InvalidKeySpecException
311        {
312            if (keySpec instanceof PKCS8EncodedKeySpec)
313            {
314                try
315                {
316                    return JDKKeyFactory.createPrivateKeyFromDERStream(
317                                ((PKCS8EncodedKeySpec)keySpec).getEncoded());
318                }
319                catch (Exception e)
320                {
321                    //
322                    // in case it's just a RSAPrivateKey object...
323                    //
324                    try
325                    {
326                        return new JCERSAPrivateCrtKey(
327                            new RSAPrivateKeyStructure(
328                                (ASN1Sequence)new ASN1InputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded()).readObject()));
329                    }
330                    catch (Exception ex)
331                    {
332                        throw new InvalidKeySpecException(ex.toString());
333                    }
334                }
335            }
336            else if (keySpec instanceof RSAPrivateCrtKeySpec)
337            {
338                return new JCERSAPrivateCrtKey((RSAPrivateCrtKeySpec)keySpec);
339            }
340            else if (keySpec instanceof RSAPrivateKeySpec)
341            {
342                return new JCERSAPrivateKey((RSAPrivateKeySpec)keySpec);
343            }
344
345            throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
346        }
347
348        protected PublicKey engineGeneratePublic(
349            KeySpec    keySpec)
350            throws InvalidKeySpecException
351        {
352            if (keySpec instanceof X509EncodedKeySpec)
353            {
354                try
355                {
356                    return JDKKeyFactory.createPublicKeyFromDERStream(
357                                ((X509EncodedKeySpec)keySpec).getEncoded());
358                }
359                catch (Exception e)
360                {
361                    throw new InvalidKeySpecException(e.toString());
362                }
363            }
364            else if (keySpec instanceof RSAPublicKeySpec)
365            {
366                return new JCERSAPublicKey((RSAPublicKeySpec)keySpec);
367            }
368
369            throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
370        }
371    }
372
373    public static class DH
374        extends JDKKeyFactory
375    {
376        public DH()
377        {
378        }
379
380        protected PrivateKey engineGeneratePrivate(
381            KeySpec    keySpec)
382            throws InvalidKeySpecException
383        {
384            if (keySpec instanceof PKCS8EncodedKeySpec)
385            {
386                try
387                {
388                    return JDKKeyFactory.createPrivateKeyFromDERStream(
389                                ((PKCS8EncodedKeySpec)keySpec).getEncoded());
390                }
391                catch (Exception e)
392                {
393                    throw new InvalidKeySpecException(e.toString());
394                }
395            }
396            else if (keySpec instanceof DHPrivateKeySpec)
397            {
398                return new JCEDHPrivateKey((DHPrivateKeySpec)keySpec);
399            }
400
401            throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
402        }
403
404        protected PublicKey engineGeneratePublic(
405            KeySpec    keySpec)
406            throws InvalidKeySpecException
407        {
408            if (keySpec instanceof X509EncodedKeySpec)
409            {
410                try
411                {
412                    return JDKKeyFactory.createPublicKeyFromDERStream(
413                                ((X509EncodedKeySpec)keySpec).getEncoded());
414                }
415                catch (Exception e)
416                {
417                    throw new InvalidKeySpecException(e.toString());
418                }
419            }
420            else if (keySpec instanceof DHPublicKeySpec)
421            {
422                return new JCEDHPublicKey((DHPublicKeySpec)keySpec);
423            }
424
425            throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
426        }
427    }
428
429    public static class DSA
430        extends JDKKeyFactory
431    {
432        public DSA()
433        {
434        }
435
436        protected PrivateKey engineGeneratePrivate(
437            KeySpec    keySpec)
438            throws InvalidKeySpecException
439        {
440            if (keySpec instanceof PKCS8EncodedKeySpec)
441            {
442                try
443                {
444                    return JDKKeyFactory.createPrivateKeyFromDERStream(
445                                ((PKCS8EncodedKeySpec)keySpec).getEncoded());
446                }
447                catch (Exception e)
448                {
449                    throw new InvalidKeySpecException(e.toString());
450                }
451            }
452            else if (keySpec instanceof DSAPrivateKeySpec)
453            {
454                return new JDKDSAPrivateKey((DSAPrivateKeySpec)keySpec);
455            }
456
457            throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
458        }
459
460        protected PublicKey engineGeneratePublic(
461            KeySpec    keySpec)
462            throws InvalidKeySpecException
463        {
464            if (keySpec instanceof X509EncodedKeySpec)
465            {
466                try
467                {
468                    return JDKKeyFactory.createPublicKeyFromDERStream(
469                                ((X509EncodedKeySpec)keySpec).getEncoded());
470                }
471                catch (Exception e)
472                {
473                    throw new InvalidKeySpecException(e.toString());
474                }
475            }
476            else if (keySpec instanceof DSAPublicKeySpec)
477            {
478                return new JDKDSAPublicKey((DSAPublicKeySpec)keySpec);
479            }
480
481            throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
482        }
483    }
484
485    public static class GOST3410
486        extends JDKKeyFactory
487    {
488        public GOST3410()
489        {
490        }
491
492        protected PrivateKey engineGeneratePrivate(
493                KeySpec    keySpec)
494        throws InvalidKeySpecException
495        {
496            if (keySpec instanceof PKCS8EncodedKeySpec)
497            {
498                try
499                {
500                    return JDKKeyFactory.createPrivateKeyFromDERStream(
501                            ((PKCS8EncodedKeySpec)keySpec).getEncoded());
502                }
503                catch (Exception e)
504                {
505                    throw new InvalidKeySpecException(e.toString());
506                }
507            }
508            // BEGIN android-removed
509            // else if (keySpec instanceof GOST3410PrivateKeySpec)
510            // {
511            //     return new JDKGOST3410PrivateKey((GOST3410PrivateKeySpec)keySpec);
512            // }
513            // END android-removed
514
515            throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
516        }
517
518        protected PublicKey engineGeneratePublic(
519                KeySpec    keySpec)
520        throws InvalidKeySpecException
521        {
522            if (keySpec instanceof X509EncodedKeySpec)
523            {
524                try
525                {
526                    return JDKKeyFactory.createPublicKeyFromDERStream(
527                            ((X509EncodedKeySpec)keySpec).getEncoded());
528                }
529                catch (Exception e)
530                {
531                    throw new InvalidKeySpecException(e.toString());
532                }
533            }
534            // BEGIN android-removed
535            // else if (keySpec instanceof GOST3410PublicKeySpec)
536            // {
537            //     return new JDKGOST3410PublicKey((GOST3410PublicKeySpec)keySpec);
538            // }
539            // END android-removed
540
541            throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
542        }
543    }
544
545    public static class ElGamal
546        extends JDKKeyFactory
547    {
548        public ElGamal()
549        {
550            elGamalFactory = true;
551        }
552
553        protected PrivateKey engineGeneratePrivate(
554            KeySpec    keySpec)
555            throws InvalidKeySpecException
556        {
557            if (keySpec instanceof PKCS8EncodedKeySpec)
558            {
559                try
560                {
561                    return JDKKeyFactory.createPrivateKeyFromDERStream(
562                                ((PKCS8EncodedKeySpec)keySpec).getEncoded());
563                }
564                catch (Exception e)
565                {
566                    throw new InvalidKeySpecException(e.toString());
567                }
568            }
569            // BEGIN android-removed
570            // else if (keySpec instanceof ElGamalPrivateKeySpec)
571            // {
572            //     return new JCEElGamalPrivateKey((ElGamalPrivateKeySpec)keySpec);
573            // }
574            // else if (keySpec instanceof DHPrivateKeySpec)
575            // {
576            //     return new JCEElGamalPrivateKey((DHPrivateKeySpec)keySpec);
577            // }
578            // END android-removed
579
580            throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
581        }
582
583        protected PublicKey engineGeneratePublic(
584            KeySpec    keySpec)
585            throws InvalidKeySpecException
586        {
587            if (keySpec instanceof X509EncodedKeySpec)
588            {
589                try
590                {
591                    return JDKKeyFactory.createPublicKeyFromDERStream(
592                                ((X509EncodedKeySpec)keySpec).getEncoded());
593                }
594                catch (Exception e)
595                {
596                    throw new InvalidKeySpecException(e.toString());
597                }
598            }
599            // BEGIN android-removed
600            // else if (keySpec instanceof ElGamalPublicKeySpec)
601            // {
602            //     return new JCEElGamalPublicKey((ElGamalPublicKeySpec)keySpec);
603            // }
604            // else if (keySpec instanceof DHPublicKeySpec)
605            // {
606            //     return new JCEElGamalPublicKey((DHPublicKeySpec)keySpec);
607            // }
608            // END android-removed
609
610            throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
611        }
612    }
613
614
615    /**
616     * This isn't really correct, however the class path project API seems to think such
617     * a key factory will exist.
618     */
619    public static class X509
620        extends JDKKeyFactory
621    {
622        public X509()
623        {
624        }
625
626        protected PrivateKey engineGeneratePrivate(
627            KeySpec    keySpec)
628            throws InvalidKeySpecException
629        {
630            if (keySpec instanceof PKCS8EncodedKeySpec)
631            {
632                try
633                {
634                    return JDKKeyFactory.createPrivateKeyFromDERStream(
635                                ((PKCS8EncodedKeySpec)keySpec).getEncoded());
636                }
637                catch (Exception e)
638                {
639                    throw new InvalidKeySpecException(e.toString());
640                }
641            }
642
643            throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
644        }
645
646        protected PublicKey engineGeneratePublic(
647            KeySpec    keySpec)
648            throws InvalidKeySpecException
649        {
650            if (keySpec instanceof X509EncodedKeySpec)
651            {
652                try
653                {
654                    return JDKKeyFactory.createPublicKeyFromDERStream(
655                                ((X509EncodedKeySpec)keySpec).getEncoded());
656                }
657                catch (Exception e)
658                {
659                    throw new InvalidKeySpecException(e.toString());
660                }
661            }
662
663            throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
664        }
665    }
666
667    public static class EC
668        extends JDKKeyFactory
669    {
670        String  algorithm;
671
672        public EC()
673        {
674            this("EC");
675        }
676
677        public EC(
678            String  algorithm)
679        {
680            this.algorithm = algorithm;
681        }
682
683        protected PrivateKey engineGeneratePrivate(
684            KeySpec    keySpec)
685            throws InvalidKeySpecException
686        {
687            if (keySpec instanceof PKCS8EncodedKeySpec)
688            {
689                try
690                {
691                    return JDKKeyFactory.createPrivateKeyFromDERStream(
692                                ((PKCS8EncodedKeySpec)keySpec).getEncoded());
693                }
694                catch (Exception e)
695                {
696                    throw new InvalidKeySpecException(e.toString());
697                }
698            }
699            // BEGIN android-removed
700            // else if (keySpec instanceof ECPrivateKeySpec)
701            // {
702            //     return new JCEECPrivateKey(algorithm, (ECPrivateKeySpec)keySpec);
703            // }
704            // else if (keySpec instanceof java.security.spec.ECPrivateKeySpec)
705            // {
706            //     return new JCEECPrivateKey(algorithm, (java.security.spec.ECPrivateKeySpec)keySpec);
707            // }
708            // END android-removed
709
710            throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
711        }
712
713        protected PublicKey engineGeneratePublic(
714            KeySpec    keySpec)
715            throws InvalidKeySpecException
716        {
717            if (keySpec instanceof X509EncodedKeySpec)
718            {
719                try
720                {
721                    return JDKKeyFactory.createPublicKeyFromDERStream(
722                                ((X509EncodedKeySpec)keySpec).getEncoded());
723                }
724                catch (Exception e)
725                {
726                    throw new InvalidKeySpecException(e.toString());
727                }
728            }
729            // BEGIN android-removed
730            // else if (keySpec instanceof ECPublicKeySpec)
731            // {
732            //     return new JCEECPublicKey(algorithm, (ECPublicKeySpec)keySpec);
733            // }
734            // else if (keySpec instanceof java.security.spec.ECPublicKeySpec)
735            // {
736            //     return new JCEECPublicKey(algorithm, (java.security.spec.ECPublicKeySpec)keySpec);
737            // }
738            // END android-removed
739
740            throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
741        }
742    }
743
744    public static class ECDSA
745        extends EC
746    {
747        public ECDSA()
748        {
749            super("ECDSA");
750        }
751    }
752
753    public static class ECGOST3410
754        extends EC
755    {
756        public ECGOST3410()
757        {
758            super("ECGOST3410");
759        }
760    }
761
762    public static class ECDH
763        extends EC
764    {
765        public ECDH()
766        {
767            super("ECDH");
768        }
769    }
770
771    public static class ECDHC
772        extends EC
773    {
774        public ECDHC()
775        {
776            super("ECDHC");
777        }
778    }
779}
780