• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.jcajce.provider.asymmetric.util;
2 
3 import java.security.InvalidKeyException;
4 import java.security.PrivateKey;
5 import java.security.PublicKey;
6 
7 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
8 // BEGIN android-removed
9 // import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
10 // END android-removed
11 import org.bouncycastle.asn1.nist.NISTNamedCurves;
12 import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
13 import org.bouncycastle.asn1.sec.SECNamedCurves;
14 // BEGIN android-removed
15 // import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
16 // END android-removed
17 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
18 import org.bouncycastle.asn1.x9.X962NamedCurves;
19 import org.bouncycastle.asn1.x9.X9ECParameters;
20 import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
21 import org.bouncycastle.crypto.params.ECDomainParameters;
22 import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
23 import org.bouncycastle.crypto.params.ECPublicKeyParameters;
24 import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
25 import org.bouncycastle.jce.interfaces.ECPrivateKey;
26 import org.bouncycastle.jce.interfaces.ECPublicKey;
27 import org.bouncycastle.jce.provider.BouncyCastleProvider;
28 import org.bouncycastle.jce.spec.ECParameterSpec;
29 
30 /**
31  * utility class for converting jce/jca ECDSA, ECDH, and ECDHC
32  * objects into their org.bouncycastle.crypto counterparts.
33  */
34 public class ECUtil
35 {
36     /**
37      * Returns a sorted array of middle terms of the reduction polynomial.
38      * @param k The unsorted array of middle terms of the reduction polynomial
39      * of length 1 or 3.
40      * @return the sorted array of middle terms of the reduction polynomial.
41      * This array always has length 3.
42      */
convertMidTerms( int[] k)43     static int[] convertMidTerms(
44         int[] k)
45     {
46         int[] res = new int[3];
47 
48         if (k.length == 1)
49         {
50             res[0] = k[0];
51         }
52         else
53         {
54             if (k.length != 3)
55             {
56                 throw new IllegalArgumentException("Only Trinomials and pentanomials supported");
57             }
58 
59             if (k[0] < k[1] && k[0] < k[2])
60             {
61                 res[0] = k[0];
62                 if (k[1] < k[2])
63                 {
64                     res[1] = k[1];
65                     res[2] = k[2];
66                 }
67                 else
68                 {
69                     res[1] = k[2];
70                     res[2] = k[1];
71                 }
72             }
73             else if (k[1] < k[2])
74             {
75                 res[0] = k[1];
76                 if (k[0] < k[2])
77                 {
78                     res[1] = k[0];
79                     res[2] = k[2];
80                 }
81                 else
82                 {
83                     res[1] = k[2];
84                     res[2] = k[0];
85                 }
86             }
87             else
88             {
89                 res[0] = k[2];
90                 if (k[0] < k[1])
91                 {
92                     res[1] = k[0];
93                     res[2] = k[1];
94                 }
95                 else
96                 {
97                     res[1] = k[1];
98                     res[2] = k[0];
99                 }
100             }
101         }
102 
103         return res;
104     }
105 
generatePublicKeyParameter( PublicKey key)106     public static AsymmetricKeyParameter generatePublicKeyParameter(
107         PublicKey    key)
108         throws InvalidKeyException
109     {
110         if (key instanceof ECPublicKey)
111         {
112             ECPublicKey    k = (ECPublicKey)key;
113             ECParameterSpec s = k.getParameters();
114 
115             if (s == null)
116             {
117                 s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
118 
119                 return new ECPublicKeyParameters(
120                             ((BCECPublicKey)k).engineGetQ(),
121                             new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
122             }
123             else
124             {
125                 return new ECPublicKeyParameters(
126                             k.getQ(),
127                             new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
128             }
129         }
130         else if (key instanceof java.security.interfaces.ECPublicKey)
131         {
132             java.security.interfaces.ECPublicKey pubKey = (java.security.interfaces.ECPublicKey)key;
133             ECParameterSpec s = EC5Util.convertSpec(pubKey.getParams(), false);
134             return new ECPublicKeyParameters(
135                 EC5Util.convertPoint(pubKey.getParams(), pubKey.getW(), false),
136                             new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
137         }
138         else
139         {
140             // see if we can build a key from key.getEncoded()
141             try
142             {
143                 byte[] bytes = key.getEncoded();
144 
145                 if (bytes == null)
146                 {
147                     throw new InvalidKeyException("no encoding for EC public key");
148                 }
149 
150                 PublicKey publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes));
151 
152                 if (publicKey instanceof java.security.interfaces.ECPublicKey)
153                 {
154                     return ECUtil.generatePublicKeyParameter(publicKey);
155                 }
156             }
157             catch (Exception e)
158             {
159                 throw new InvalidKeyException("cannot identify EC public key: " + e.toString());
160             }
161         }
162 
163         throw new InvalidKeyException("cannot identify EC public key.");
164     }
165 
generatePrivateKeyParameter( PrivateKey key)166     public static AsymmetricKeyParameter generatePrivateKeyParameter(
167         PrivateKey    key)
168         throws InvalidKeyException
169     {
170         if (key instanceof ECPrivateKey)
171         {
172             ECPrivateKey  k = (ECPrivateKey)key;
173             ECParameterSpec s = k.getParameters();
174 
175             if (s == null)
176             {
177                 s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
178             }
179 
180             return new ECPrivateKeyParameters(
181                             k.getD(),
182                             new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
183         }
184         else if (key instanceof java.security.interfaces.ECPrivateKey)
185         {
186             java.security.interfaces.ECPrivateKey privKey = (java.security.interfaces.ECPrivateKey)key;
187             ECParameterSpec s = EC5Util.convertSpec(privKey.getParams(), false);
188             return new ECPrivateKeyParameters(
189                             privKey.getS(),
190                             new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
191         }
192         else
193         {
194             // see if we can build a key from key.getEncoded()
195             try
196             {
197                 byte[] bytes = key.getEncoded();
198 
199                 if (bytes == null)
200                 {
201                     throw new InvalidKeyException("no encoding for EC private key");
202                 }
203 
204                 PrivateKey privateKey = BouncyCastleProvider.getPrivateKey(PrivateKeyInfo.getInstance(bytes));
205 
206                 if (privateKey instanceof java.security.interfaces.ECPrivateKey)
207                 {
208                     return ECUtil.generatePrivateKeyParameter(privateKey);
209                 }
210             }
211             catch (Exception e)
212             {
213                 throw new InvalidKeyException("cannot identify EC private key: " + e.toString());
214             }
215         }
216 
217         throw new InvalidKeyException("can't identify EC private key.");
218     }
219 
getNamedCurveOid( String name)220     public static ASN1ObjectIdentifier getNamedCurveOid(
221         String name)
222     {
223         ASN1ObjectIdentifier oid = X962NamedCurves.getOID(name);
224 
225         if (oid == null)
226         {
227             oid = SECNamedCurves.getOID(name);
228             if (oid == null)
229             {
230                 oid = NISTNamedCurves.getOID(name);
231             }
232             // BEGIN android-removed
233             // if (oid == null)
234             // {
235             //     oid = TeleTrusTNamedCurves.getOID(name);
236             // }
237             // if (oid == null)
238             // {
239             //     oid = ECGOST3410NamedCurves.getOID(name);
240             // }
241             // END android-removed
242         }
243 
244         return oid;
245     }
246 
getNamedCurveByOid( ASN1ObjectIdentifier oid)247     public static X9ECParameters getNamedCurveByOid(
248         ASN1ObjectIdentifier oid)
249     {
250         X9ECParameters params = X962NamedCurves.getByOID(oid);
251 
252         if (params == null)
253         {
254             params = SECNamedCurves.getByOID(oid);
255             if (params == null)
256             {
257                 params = NISTNamedCurves.getByOID(oid);
258             }
259             // BEGIN android-removed
260             // if (params == null)
261             // {
262             //     params = TeleTrusTNamedCurves.getByOID(oid);
263             // }
264             // END android-removed
265         }
266 
267         return params;
268     }
269 
getCurveName( ASN1ObjectIdentifier oid)270     public static String getCurveName(
271         ASN1ObjectIdentifier oid)
272     {
273         String name = X962NamedCurves.getName(oid);
274 
275         if (name == null)
276         {
277             name = SECNamedCurves.getName(oid);
278             if (name == null)
279             {
280                 name = NISTNamedCurves.getName(oid);
281             }
282             // BEGIN android-removed
283             // if (name == null)
284             // {
285             //     name = TeleTrusTNamedCurves.getName(oid);
286             // }
287             // if (name == null)
288             // {
289             //     name = ECGOST3410NamedCurves.getName(oid);
290             // }
291             // END android-removed
292         }
293 
294         return name;
295     }
296 }
297