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