KeyFactorySpi.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
1package org.bouncycastle.jcajce.provider.asymmetric.ec;
2
3import java.io.IOException;
4import java.security.InvalidKeyException;
5import java.security.Key;
6import java.security.PrivateKey;
7import java.security.PublicKey;
8import java.security.interfaces.ECPrivateKey;
9import java.security.interfaces.ECPublicKey;
10import java.security.spec.InvalidKeySpecException;
11import java.security.spec.KeySpec;
12
13import org.bouncycastle.asn1.ASN1ObjectIdentifier;
14import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
15import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
16import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
17import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi;
18import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
19import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
20import org.bouncycastle.jce.provider.BouncyCastleProvider;
21import org.bouncycastle.jce.spec.ECParameterSpec;
22import org.bouncycastle.jce.spec.ECPrivateKeySpec;
23import org.bouncycastle.jce.spec.ECPublicKeySpec;
24
25public class KeyFactorySpi
26    extends BaseKeyFactorySpi
27    implements AsymmetricKeyInfoConverter
28{
29    String algorithm;
30    ProviderConfiguration configuration;
31
32    KeyFactorySpi(
33        String algorithm,
34        ProviderConfiguration configuration)
35    {
36        this.algorithm = algorithm;
37        this.configuration = configuration;
38    }
39
40    protected Key engineTranslateKey(
41        Key    key)
42        throws InvalidKeyException
43    {
44        if (key instanceof ECPublicKey)
45        {
46            return new BCECPublicKey((ECPublicKey)key, configuration);
47        }
48        else if (key instanceof ECPrivateKey)
49        {
50            return new BCECPrivateKey((ECPrivateKey)key, configuration);
51        }
52
53        throw new InvalidKeyException("key type unknown");
54    }
55
56    protected KeySpec engineGetKeySpec(
57        Key    key,
58        Class    spec)
59    throws InvalidKeySpecException
60    {
61       if (spec.isAssignableFrom(java.security.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey)
62       {
63           ECPublicKey k = (ECPublicKey)key;
64           if (k.getParams() != null)
65           {
66               return new java.security.spec.ECPublicKeySpec(k.getW(), k.getParams());
67           }
68           else
69           {
70               ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
71
72               return new java.security.spec.ECPublicKeySpec(k.getW(), EC5Util.convertSpec(EC5Util.convertCurve(implicitSpec.getCurve(), implicitSpec.getSeed()), implicitSpec));
73           }
74       }
75       else if (spec.isAssignableFrom(java.security.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey)
76       {
77           ECPrivateKey k = (ECPrivateKey)key;
78
79           if (k.getParams() != null)
80           {
81               return new java.security.spec.ECPrivateKeySpec(k.getS(), k.getParams());
82           }
83           else
84           {
85               ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
86
87               return new java.security.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(EC5Util.convertCurve(implicitSpec.getCurve(), implicitSpec.getSeed()), implicitSpec));
88           }
89       }
90       else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey)
91       {
92           ECPublicKey k = (ECPublicKey)key;
93           if (k.getParams() != null)
94           {
95               return new org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW(), false), EC5Util.convertSpec(k.getParams(), false));
96           }
97           else
98           {
99               ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
100
101               return new org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW(), false), implicitSpec);
102           }
103       }
104       else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey)
105       {
106           ECPrivateKey k = (ECPrivateKey)key;
107
108           if (k.getParams() != null)
109           {
110               return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(k.getParams(), false));
111           }
112           else
113           {
114               ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
115
116               return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), implicitSpec);
117           }
118       }
119
120       return super.engineGetKeySpec(key, spec);
121    }
122
123    protected PrivateKey engineGeneratePrivate(
124        KeySpec keySpec)
125        throws InvalidKeySpecException
126    {
127        if (keySpec instanceof ECPrivateKeySpec)
128        {
129            return new BCECPrivateKey(algorithm, (ECPrivateKeySpec)keySpec, configuration);
130        }
131        else if (keySpec instanceof java.security.spec.ECPrivateKeySpec)
132        {
133            return new BCECPrivateKey(algorithm, (java.security.spec.ECPrivateKeySpec)keySpec, configuration);
134        }
135
136        return super.engineGeneratePrivate(keySpec);
137    }
138
139    protected PublicKey engineGeneratePublic(
140        KeySpec keySpec)
141        throws InvalidKeySpecException
142    {
143        if (keySpec instanceof ECPublicKeySpec)
144        {
145            return new BCECPublicKey(algorithm, (ECPublicKeySpec)keySpec, configuration);
146        }
147        else if (keySpec instanceof java.security.spec.ECPublicKeySpec)
148        {
149            return new BCECPublicKey(algorithm, (java.security.spec.ECPublicKeySpec)keySpec, configuration);
150        }
151
152        return super.engineGeneratePublic(keySpec);
153    }
154
155    public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
156        throws IOException
157    {
158        ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm();
159
160        if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey))
161        {
162            return new BCECPrivateKey(algorithm, keyInfo, configuration);
163        }
164        else
165        {
166            throw new IOException("algorithm identifier " + algOid + " in key not recognised");
167        }
168    }
169
170    public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
171        throws IOException
172    {
173        ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm();
174
175        if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey))
176        {
177            return new BCECPublicKey(algorithm, keyInfo, configuration);
178        }
179        else
180        {
181            throw new IOException("algorithm identifier " + algOid + " in key not recognised");
182        }
183    }
184
185    public static class EC
186        extends KeyFactorySpi
187    {
188        public EC()
189        {
190            super("EC", BouncyCastleProvider.CONFIGURATION);
191        }
192    }
193
194    public static class ECDSA
195        extends KeyFactorySpi
196    {
197        public ECDSA()
198        {
199            super("ECDSA", BouncyCastleProvider.CONFIGURATION);
200        }
201    }
202
203    // BEGIN android-removed
204    // public static class ECGOST3410
205    //     extends KeyFactorySpi
206    // {
207    //     public ECGOST3410()
208    //     {
209    //         super("ECGOST3410", BouncyCastleProvider.CONFIGURATION);
210    //     }
211    // }
212    // END android-removed
213
214    public static class ECDH
215        extends KeyFactorySpi
216    {
217        public ECDH()
218        {
219            super("ECDH", BouncyCastleProvider.CONFIGURATION);
220        }
221    }
222
223    public static class ECDHC
224        extends KeyFactorySpi
225    {
226        public ECDHC()
227        {
228            super("ECDHC", BouncyCastleProvider.CONFIGURATION);
229        }
230    }
231
232    public static class ECMQV
233        extends KeyFactorySpi
234    {
235        public ECMQV()
236        {
237            super("ECMQV", BouncyCastleProvider.CONFIGURATION);
238        }
239    }
240}