History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/rsa/RSAKeyFactory.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/rsa/RSAKeyFactory.java+401−0
@@ -0,0 +1,401 @@
1+/*
2+ * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.security.rsa;
27+
28+import java.math.BigInteger;
29+
30+import java.security.*;
31+import java.security.interfaces.*;
32+import java.security.spec.*;
33+
34+import sun.security.action.GetPropertyAction;
35+
36+/**
37+ * KeyFactory for RSA keys. Keys must be instances of PublicKey or PrivateKey
38+ * and getAlgorithm() must return "RSA". For such keys, it supports conversion
39+ * between the following:
40+ *
41+ * For public keys:
42+ * . PublicKey with an X.509 encoding
43+ * . RSAPublicKey
44+ * . RSAPublicKeySpec
45+ * . X509EncodedKeySpec
46+ *
47+ * For private keys:
48+ * . PrivateKey with a PKCS#8 encoding
49+ * . RSAPrivateKey
50+ * . RSAPrivateCrtKey
51+ * . RSAPrivateKeySpec
52+ * . RSAPrivateCrtKeySpec
53+ * . PKCS8EncodedKeySpec
54+ * (of course, CRT variants only for CRT keys)
55+ *
56+ * Note: as always, RSA keys should be at least 512 bits long
57+ *
58+ * @since 1.5
59+ * @author Andreas Sterbenz
60+ */
61+public final class RSAKeyFactory extends KeyFactorySpi {
62+
63+ private final static Class<?> rsaPublicKeySpecClass =
64+ RSAPublicKeySpec.class;
65+ private final static Class<?> rsaPrivateKeySpecClass =
66+ RSAPrivateKeySpec.class;
67+ private final static Class<?> rsaPrivateCrtKeySpecClass =
68+ RSAPrivateCrtKeySpec.class;
69+
70+ private final static Class<?> x509KeySpecClass = X509EncodedKeySpec.class;
71+ private final static Class<?> pkcs8KeySpecClass = PKCS8EncodedKeySpec.class;
72+
73+ public final static int MIN_MODLEN = 512;
74+ public final static int MAX_MODLEN = 16384;
75+
76+ /*
77+ * If the modulus length is above this value, restrict the size of
78+ * the exponent to something that can be reasonably computed. We
79+ * could simply hardcode the exp len to something like 64 bits, but
80+ * this approach allows flexibility in case impls would like to use
81+ * larger module and exponent values.
82+ */
83+ public final static int MAX_MODLEN_RESTRICT_EXP = 3072;
84+ public final static int MAX_RESTRICTED_EXPLEN = 64;
85+
86+ private static final boolean restrictExpLen =
87+ "true".equalsIgnoreCase(AccessController.doPrivileged(
88+ new GetPropertyAction(
89+ "sun.security.rsa.restrictRSAExponent", "true")));
90+
91+ // instance used for static translateKey();
92+ private final static RSAKeyFactory INSTANCE = new RSAKeyFactory();
93+
94+ public RSAKeyFactory() {
95+ // empty
96+ }
97+
98+ /**
99+ * Static method to convert Key into an instance of RSAPublicKeyImpl
100+ * or RSAPrivate(Crt)KeyImpl. If the key is not an RSA key or cannot be
101+ * used, throw an InvalidKeyException.
102+ *
103+ * Used by RSASignature and RSACipher.
104+ */
105+ public static RSAKey toRSAKey(Key key) throws InvalidKeyException {
106+ if ((key instanceof RSAPrivateKeyImpl) ||
107+ (key instanceof RSAPrivateCrtKeyImpl) ||
108+ (key instanceof RSAPublicKeyImpl)) {
109+ return (RSAKey)key;
110+ } else {
111+ return (RSAKey)INSTANCE.engineTranslateKey(key);
112+ }
113+ }
114+
115+ /*
116+ * Single test entry point for all of the mechanisms in the SunRsaSign
117+ * provider (RSA*KeyImpls). All of the tests are the same.
118+ *
119+ * For compatibility, we round up to the nearest byte here:
120+ * some Key impls might pass in a value within a byte of the
121+ * real value.
122+ */
123+ static void checkRSAProviderKeyLengths(int modulusLen, BigInteger exponent)
124+ throws InvalidKeyException {
125+ checkKeyLengths(((modulusLen + 7) & ~7), exponent,
126+ RSAKeyFactory.MIN_MODLEN, Integer.MAX_VALUE);
127+ }
128+
129+ /**
130+ * Check the length of an RSA key modulus/exponent to make sure it
131+ * is not too short or long. Some impls have their own min and
132+ * max key sizes that may or may not match with a system defined value.
133+ *
134+ * @param modulusLen the bit length of the RSA modulus.
135+ * @param exponent the RSA exponent
136+ * @param minModulusLen if > 0, check to see if modulusLen is at
137+ * least this long, otherwise unused.
138+ * @param maxModulusLen caller will allow this max number of bits.
139+ * Allow the smaller of the system-defined maximum and this param.
140+ *
141+ * @throws InvalidKeyException if any of the values are unacceptable.
142+ */
143+ public static void checkKeyLengths(int modulusLen, BigInteger exponent,
144+ int minModulusLen, int maxModulusLen) throws InvalidKeyException {
145+
146+ if ((minModulusLen > 0) && (modulusLen < (minModulusLen))) {
147+ throw new InvalidKeyException( "RSA keys must be at least " +
148+ minModulusLen + " bits long");
149+ }
150+
151+ // Even though our policy file may allow this, we don't want
152+ // either value (mod/exp) to be too big.
153+
154+ int maxLen = Math.min(maxModulusLen, MAX_MODLEN);
155+
156+ // If a RSAPrivateKey/RSAPublicKey, make sure the
157+ // modulus len isn't too big.
158+ if (modulusLen > maxLen) {
159+ throw new InvalidKeyException(
160+ "RSA keys must be no longer than " + maxLen + " bits");
161+ }
162+
163+ // If a RSAPublicKey, make sure the exponent isn't too big.
164+ if (restrictExpLen && (exponent != null) &&
165+ (modulusLen > MAX_MODLEN_RESTRICT_EXP) &&
166+ (exponent.bitLength() > MAX_RESTRICTED_EXPLEN)) {
167+ throw new InvalidKeyException(
168+ "RSA exponents can be no longer than " +
169+ MAX_RESTRICTED_EXPLEN + " bits " +
170+ " if modulus is greater than " +
171+ MAX_MODLEN_RESTRICT_EXP + " bits");
172+ }
173+ }
174+
175+ /**
176+ * Translate an RSA key into a SunRsaSign RSA key. If conversion is
177+ * not possible, throw an InvalidKeyException.
178+ * See also JCA doc.
179+ */
180+ protected Key engineTranslateKey(Key key) throws InvalidKeyException {
181+ if (key == null) {
182+ throw new InvalidKeyException("Key must not be null");
183+ }
184+ String keyAlg = key.getAlgorithm();
185+ if (keyAlg.equals("RSA") == false) {
186+ throw new InvalidKeyException("Not an RSA key: " + keyAlg);
187+ }
188+ if (key instanceof PublicKey) {
189+ return translatePublicKey((PublicKey)key);
190+ } else if (key instanceof PrivateKey) {
191+ return translatePrivateKey((PrivateKey)key);
192+ } else {
193+ throw new InvalidKeyException("Neither a public nor a private key");
194+ }
195+ }
196+
197+ // see JCA doc
198+ protected PublicKey engineGeneratePublic(KeySpec keySpec)
199+ throws InvalidKeySpecException {
200+ try {
201+ return generatePublic(keySpec);
202+ } catch (InvalidKeySpecException e) {
203+ throw e;
204+ } catch (GeneralSecurityException e) {
205+ throw new InvalidKeySpecException(e);
206+ }
207+ }
208+
209+ // see JCA doc
210+ protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
211+ throws InvalidKeySpecException {
212+ try {
213+ return generatePrivate(keySpec);
214+ } catch (InvalidKeySpecException e) {
215+ throw e;
216+ } catch (GeneralSecurityException e) {
217+ throw new InvalidKeySpecException(e);
218+ }
219+ }
220+
221+ // internal implementation of translateKey() for public keys. See JCA doc
222+ private PublicKey translatePublicKey(PublicKey key)
223+ throws InvalidKeyException {
224+ if (key instanceof RSAPublicKey) {
225+ if (key instanceof RSAPublicKeyImpl) {
226+ return key;
227+ }
228+ RSAPublicKey rsaKey = (RSAPublicKey)key;
229+ try {
230+ return new RSAPublicKeyImpl(
231+ rsaKey.getModulus(),
232+ rsaKey.getPublicExponent()
233+ );
234+ } catch (RuntimeException e) {
235+ // catch providers that incorrectly implement RSAPublicKey
236+ throw new InvalidKeyException("Invalid key", e);
237+ }
238+ } else if ("X.509".equals(key.getFormat())) {
239+ byte[] encoded = key.getEncoded();
240+ return new RSAPublicKeyImpl(encoded);
241+ } else {
242+ throw new InvalidKeyException("Public keys must be instance "
243+ + "of RSAPublicKey or have X.509 encoding");
244+ }
245+ }
246+
247+ // internal implementation of translateKey() for private keys. See JCA doc
248+ private PrivateKey translatePrivateKey(PrivateKey key)
249+ throws InvalidKeyException {
250+ if (key instanceof RSAPrivateCrtKey) {
251+ if (key instanceof RSAPrivateCrtKeyImpl) {
252+ return key;
253+ }
254+ RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
255+ try {
256+ return new RSAPrivateCrtKeyImpl(
257+ rsaKey.getModulus(),
258+ rsaKey.getPublicExponent(),
259+ rsaKey.getPrivateExponent(),
260+ rsaKey.getPrimeP(),
261+ rsaKey.getPrimeQ(),
262+ rsaKey.getPrimeExponentP(),
263+ rsaKey.getPrimeExponentQ(),
264+ rsaKey.getCrtCoefficient()
265+ );
266+ } catch (RuntimeException e) {
267+ // catch providers that incorrectly implement RSAPrivateCrtKey
268+ throw new InvalidKeyException("Invalid key", e);
269+ }
270+ } else if (key instanceof RSAPrivateKey) {
271+ if (key instanceof RSAPrivateKeyImpl) {
272+ return key;
273+ }
274+ RSAPrivateKey rsaKey = (RSAPrivateKey)key;
275+ try {
276+ return new RSAPrivateKeyImpl(
277+ rsaKey.getModulus(),
278+ rsaKey.getPrivateExponent()
279+ );
280+ } catch (RuntimeException e) {
281+ // catch providers that incorrectly implement RSAPrivateKey
282+ throw new InvalidKeyException("Invalid key", e);
283+ }
284+ } else if ("PKCS#8".equals(key.getFormat())) {
285+ byte[] encoded = key.getEncoded();
286+ return RSAPrivateCrtKeyImpl.newKey(encoded);
287+ } else {
288+ throw new InvalidKeyException("Private keys must be instance "
289+ + "of RSAPrivate(Crt)Key or have PKCS#8 encoding");
290+ }
291+ }
292+
293+ // internal implementation of generatePublic. See JCA doc
294+ private PublicKey generatePublic(KeySpec keySpec)
295+ throws GeneralSecurityException {
296+ if (keySpec instanceof X509EncodedKeySpec) {
297+ X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec;
298+ return new RSAPublicKeyImpl(x509Spec.getEncoded());
299+ } else if (keySpec instanceof RSAPublicKeySpec) {
300+ RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec;
301+ return new RSAPublicKeyImpl(
302+ rsaSpec.getModulus(),
303+ rsaSpec.getPublicExponent()
304+ );
305+ } else {
306+ throw new InvalidKeySpecException("Only RSAPublicKeySpec "
307+ + "and X509EncodedKeySpec supported for RSA public keys");
308+ }
309+ }
310+
311+ // internal implementation of generatePrivate. See JCA doc
312+ private PrivateKey generatePrivate(KeySpec keySpec)
313+ throws GeneralSecurityException {
314+ if (keySpec instanceof PKCS8EncodedKeySpec) {
315+ PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec;
316+ return RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded());
317+ } else if (keySpec instanceof RSAPrivateCrtKeySpec) {
318+ RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec;
319+ return new RSAPrivateCrtKeyImpl(
320+ rsaSpec.getModulus(),
321+ rsaSpec.getPublicExponent(),
322+ rsaSpec.getPrivateExponent(),
323+ rsaSpec.getPrimeP(),
324+ rsaSpec.getPrimeQ(),
325+ rsaSpec.getPrimeExponentP(),
326+ rsaSpec.getPrimeExponentQ(),
327+ rsaSpec.getCrtCoefficient()
328+ );
329+ } else if (keySpec instanceof RSAPrivateKeySpec) {
330+ RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec;
331+ return new RSAPrivateKeyImpl(
332+ rsaSpec.getModulus(),
333+ rsaSpec.getPrivateExponent()
334+ );
335+ } else {
336+ throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec "
337+ + "and PKCS8EncodedKeySpec supported for RSA private keys");
338+ }
339+ }
340+
341+ protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
342+ throws InvalidKeySpecException {
343+ try {
344+ // convert key to one of our keys
345+ // this also verifies that the key is a valid RSA key and ensures
346+ // that the encoding is X.509/PKCS#8 for public/private keys
347+ key = engineTranslateKey(key);
348+ } catch (InvalidKeyException e) {
349+ throw new InvalidKeySpecException(e);
350+ }
351+ if (key instanceof RSAPublicKey) {
352+ RSAPublicKey rsaKey = (RSAPublicKey)key;
353+ if (rsaPublicKeySpecClass.isAssignableFrom(keySpec)) {
354+ return (T) new RSAPublicKeySpec(
355+ rsaKey.getModulus(),
356+ rsaKey.getPublicExponent()
357+ );
358+ } else if (x509KeySpecClass.isAssignableFrom(keySpec)) {
359+ return (T) new X509EncodedKeySpec(key.getEncoded());
360+ } else {
361+ throw new InvalidKeySpecException
362+ ("KeySpec must be RSAPublicKeySpec or "
363+ + "X509EncodedKeySpec for RSA public keys");
364+ }
365+ } else if (key instanceof RSAPrivateKey) {
366+ if (pkcs8KeySpecClass.isAssignableFrom(keySpec)) {
367+ return (T) new PKCS8EncodedKeySpec(key.getEncoded());
368+ } else if (rsaPrivateCrtKeySpecClass.isAssignableFrom(keySpec)) {
369+ if (key instanceof RSAPrivateCrtKey) {
370+ RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey)key;
371+ return (T) new RSAPrivateCrtKeySpec(
372+ crtKey.getModulus(),
373+ crtKey.getPublicExponent(),
374+ crtKey.getPrivateExponent(),
375+ crtKey.getPrimeP(),
376+ crtKey.getPrimeQ(),
377+ crtKey.getPrimeExponentP(),
378+ crtKey.getPrimeExponentQ(),
379+ crtKey.getCrtCoefficient()
380+ );
381+ } else {
382+ throw new InvalidKeySpecException
383+ ("RSAPrivateCrtKeySpec can only be used with CRT keys");
384+ }
385+ } else if (rsaPrivateKeySpecClass.isAssignableFrom(keySpec)) {
386+ RSAPrivateKey rsaKey = (RSAPrivateKey)key;
387+ return (T) new RSAPrivateKeySpec(
388+ rsaKey.getModulus(),
389+ rsaKey.getPrivateExponent()
390+ );
391+ } else {
392+ throw new InvalidKeySpecException
393+ ("KeySpec must be RSAPrivate(Crt)KeySpec or "
394+ + "PKCS8EncodedKeySpec for RSA private keys");
395+ }
396+ } else {
397+ // should not occur, caught in engineTranslateKey()
398+ throw new InvalidKeySpecException("Neither public nor private key");
399+ }
400+ }
401+}