blob: f99a43cf5118b8fe6759df9a8caa0b045447a26a [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package javax.crypto;
27
28import java.util.*;
29import java.util.regex.*;
30
31import static java.util.Locale.ENGLISH;
32
33import java.security.*;
34import java.security.Provider.Service;
35import java.security.spec.AlgorithmParameterSpec;
36import java.security.spec.InvalidParameterSpecException;
37import java.security.cert.Certificate;
38import java.security.cert.X509Certificate;
39
40import javax.crypto.spec.*;
41
42import java.nio.ByteBuffer;
43import java.nio.ReadOnlyBufferException;
44
45import sun.security.util.Debug;
46import sun.security.jca.*;
47import sun.security.jca.GetInstance.Instance;
48
49/**
50 * This class provides the functionality of a cryptographic cipher for
51 * encryption and decryption. It forms the core of the Java Cryptographic
52 * Extension (JCE) framework.
53 *
54 * <p>In order to create a Cipher object, the application calls the
55 * Cipher's <code>getInstance</code> method, and passes the name of the
56 * requested <i>transformation</i> to it. Optionally, the name of a provider
57 * may be specified.
58 *
59 * <p>A <i>transformation</i> is a string that describes the operation (or
60 * set of operations) to be performed on the given input, to produce some
61 * output. A transformation always includes the name of a cryptographic
62 * algorithm (e.g., <i>DES</i>), and may be followed by a feedback mode and
63 * padding scheme.
64 *
65 * <p> A transformation is of the form:<p>
66 *
67 * <ul>
68 * <li>"<i>algorithm/mode/padding</i>" or
69 * <p>
70 * <li>"<i>algorithm</i>"
71 * </ul>
72 *
73 * <P> (in the latter case,
74 * provider-specific default values for the mode and padding scheme are used).
75 * For example, the following is a valid transformation:<p>
76 *
77 * <pre>
78 * Cipher c = Cipher.getInstance("<i>DES/CBC/PKCS5Padding</i>");
79 * </pre>
80 *
81 * Using modes such as <code>CFB</code> and <code>OFB<code>, block
82 * ciphers can encrypt data in units smaller than the cipher's actual
83 * block size. When requesting such a mode, you may optionally specify
84 * the number of bits to be processed at a time by appending this number
85 * to the mode name as shown in the "<code>DES/CFB8/NoPadding</code>" and
86 * "<code>DES/OFB32/PKCS5Padding</code>" transformations. If no such
87 * number is specified, a provider-specific default is used. (For
88 * example, the SunJCE provider uses a default of 64 bits for DES.)
89 * Thus, block ciphers can be turned into byte-oriented stream ciphers by
90 * using an 8 bit mode such as CFB8 or OFB8.
91 *
92 * @author Jan Luehe
93 * @see KeyGenerator
94 * @see SecretKey
95 * @since 1.4
96 */
97
98public class Cipher {
99
100 private static final Debug debug =
101 Debug.getInstance("jca", "Cipher");
102
103 /**
104 * Constant used to initialize cipher to encryption mode.
105 */
106 public static final int ENCRYPT_MODE = 1;
107
108 /**
109 * Constant used to initialize cipher to decryption mode.
110 */
111 public static final int DECRYPT_MODE = 2;
112
113 /**
114 * Constant used to initialize cipher to key-wrapping mode.
115 */
116 public static final int WRAP_MODE = 3;
117
118 /**
119 * Constant used to initialize cipher to key-unwrapping mode.
120 */
121 public static final int UNWRAP_MODE = 4;
122
123 /**
124 * Constant used to indicate the to-be-unwrapped key is a "public key".
125 */
126 public static final int PUBLIC_KEY = 1;
127
128 /**
129 * Constant used to indicate the to-be-unwrapped key is a "private key".
130 */
131 public static final int PRIVATE_KEY = 2;
132
133 /**
134 * Constant used to indicate the to-be-unwrapped key is a "secret key".
135 */
136 public static final int SECRET_KEY = 3;
137
138 // The provider
139 private Provider provider;
140
141 // The provider implementation (delegate)
142 private CipherSpi spi;
143
144 // The transformation
145 private String transformation;
146
147 // Crypto permission representing the maximum allowable cryptographic
148 // strength that this Cipher object can be used for. (The cryptographic
149 // strength is a function of the keysize and algorithm parameters encoded
150 // in the crypto permission.)
151 private CryptoPermission cryptoPerm;
152
153 // The exemption mechanism that needs to be enforced
154 private ExemptionMechanism exmech;
155
156 // Flag which indicates whether or not this cipher has been initialized
157 private boolean initialized = false;
158
159 // The operation mode - store the operation mode after the
160 // cipher has been initialized.
161 private int opmode = 0;
162
163 // The OID for the KeyUsage extension in an X.509 v3 certificate
164 private static final String KEY_USAGE_EXTENSION_OID = "2.5.29.15";
165
166 // next SPI to try in provider selection
167 // null once provider is selected
168 private CipherSpi firstSpi;
169
170 // next service to try in provider selection
171 // null once provider is selected
172 private Service firstService;
173
174 // remaining services to try in provider selection
175 // null once provider is selected
176 private Iterator serviceIterator;
177
178 // list of transform Strings to lookup in the provider
179 private List transforms;
180
181 private final Object lock;
182
183 /**
184 * Creates a Cipher object.
185 *
186 * @param cipherSpi the delegate
187 * @param provider the provider
188 * @param transformation the transformation
189 */
190 protected Cipher(CipherSpi cipherSpi,
191 Provider provider,
192 String transformation) {
193 // See bug 4341369 & 4334690 for more info.
194 // If the caller is trusted, then okey.
195 // Otherwise throw a NullPointerException.
196 if (!JceSecurityManager.INSTANCE.isCallerTrusted()) {
197 throw new NullPointerException();
198 }
199 this.spi = cipherSpi;
200 this.provider = provider;
201 this.transformation = transformation;
202 this.cryptoPerm = CryptoAllPermission.INSTANCE;
203 this.lock = null;
204 }
205
206 /**
207 * Creates a Cipher object. Called internally and by NullCipher.
208 *
209 * @param cipherSpi the delegate
210 * @param transformation the transformation
211 */
212 Cipher(CipherSpi cipherSpi, String transformation) {
213 this.spi = cipherSpi;
214 this.transformation = transformation;
215 this.cryptoPerm = CryptoAllPermission.INSTANCE;
216 this.lock = null;
217 }
218
219 private Cipher(CipherSpi firstSpi, Service firstService,
220 Iterator serviceIterator, String transformation, List transforms) {
221 this.firstSpi = firstSpi;
222 this.firstService = firstService;
223 this.serviceIterator = serviceIterator;
224 this.transforms = transforms;
225 this.transformation = transformation;
226 this.lock = new Object();
227 }
228
229 private static String[] tokenizeTransformation(String transformation)
230 throws NoSuchAlgorithmException {
231 if (transformation == null) {
232 throw new NoSuchAlgorithmException("No transformation given");
233 }
234 /*
235 * array containing the components of a Cipher transformation:
236 *
237 * index 0: algorithm component (e.g., DES)
238 * index 1: feedback component (e.g., CFB)
239 * index 2: padding component (e.g., PKCS5Padding)
240 */
241 String[] parts = new String[3];
242 int count = 0;
243 StringTokenizer parser = new StringTokenizer(transformation, "/");
244 try {
245 while (parser.hasMoreTokens() && count < 3) {
246 parts[count++] = parser.nextToken().trim();
247 }
248 if (count == 0 || count == 2 || parser.hasMoreTokens()) {
249 throw new NoSuchAlgorithmException("Invalid transformation"
250 + " format:" +
251 transformation);
252 }
253 } catch (NoSuchElementException e) {
254 throw new NoSuchAlgorithmException("Invalid transformation " +
255 "format:" + transformation);
256 }
257 if ((parts[0] == null) || (parts[0].length() == 0)) {
258 throw new NoSuchAlgorithmException("Invalid transformation:" +
259 "algorithm not specified-"
260 + transformation);
261 }
262 return parts;
263 }
264
265 // Provider attribute name for supported chaining mode
266 private final static String ATTR_MODE = "SupportedModes";
267 // Provider attribute name for supported padding names
268 private final static String ATTR_PAD = "SupportedPaddings";
269
270 // constants indicating whether the provider supports
271 // a given mode or padding
272 private final static int S_NO = 0; // does not support
273 private final static int S_MAYBE = 1; // unable to determine
274 private final static int S_YES = 2; // does support
275
276 /**
277 * Nested class to deal with modes and paddings.
278 */
279 private static class Transform {
280 // transform string to lookup in the provider
281 final String transform;
282 // the mode/padding suffix in upper case. for example, if the algorithm
283 // to lookup is "DES/CBC/PKCS5Padding" suffix is "/CBC/PKCS5PADDING"
284 // if loopup is "DES", suffix is the empty string
285 // needed because aliases prevent straight transform.equals()
286 final String suffix;
287 // value to pass to setMode() or null if no such call required
288 final String mode;
289 // value to pass to setPadding() or null if no such call required
290 final String pad;
291 Transform(String alg, String suffix, String mode, String pad) {
292 this.transform = alg + suffix;
293 this.suffix = suffix.toUpperCase(Locale.ENGLISH);
294 this.mode = mode;
295 this.pad = pad;
296 }
297 // set mode and padding for the given SPI
298 void setModePadding(CipherSpi spi) throws NoSuchAlgorithmException,
299 NoSuchPaddingException {
300 if (mode != null) {
301 spi.engineSetMode(mode);
302 }
303 if (pad != null) {
304 spi.engineSetPadding(pad);
305 }
306 }
307 // check whether the given services supports the mode and
308 // padding described by this Transform
309 int supportsModePadding(Service s) {
310 int smode = supportsMode(s);
311 if (smode == S_NO) {
312 return smode;
313 }
314 int spad = supportsPadding(s);
315 // our constants are defined so that Math.min() is a tri-valued AND
316 return Math.min(smode, spad);
317 }
318
319 // separate methods for mode and padding
320 // called directly by Cipher only to throw the correct exception
321 int supportsMode(Service s) {
322 return supports(s, ATTR_MODE, mode);
323 }
324 int supportsPadding(Service s) {
325 return supports(s, ATTR_PAD, pad);
326 }
327
328 private static int supports(Service s, String attrName, String value) {
329 if (value == null) {
330 return S_YES;
331 }
332 String regexp = s.getAttribute(attrName);
333 if (regexp == null) {
334 return S_MAYBE;
335 }
336 return matches(regexp, value) ? S_YES : S_NO;
337 }
338
339 // Map<String,Pattern> for previously compiled patterns
340 // XXX use ConcurrentHashMap once available
341 private final static Map patternCache =
342 Collections.synchronizedMap(new HashMap());
343
344 private static boolean matches(String regexp, String str) {
345 Pattern pattern = (Pattern)patternCache.get(regexp);
346 if (pattern == null) {
347 pattern = Pattern.compile(regexp);
348 patternCache.put(regexp, pattern);
349 }
350 return pattern.matcher(str.toUpperCase(Locale.ENGLISH)).matches();
351 }
352
353 }
354
355 private static List getTransforms(String transformation)
356 throws NoSuchAlgorithmException {
357 String[] parts = tokenizeTransformation(transformation);
358
359 String alg = parts[0];
360 String mode = parts[1];
361 String pad = parts[2];
362 if ((mode != null) && (mode.length() == 0)) {
363 mode = null;
364 }
365 if ((pad != null) && (pad.length() == 0)) {
366 pad = null;
367 }
368
369 if ((mode == null) && (pad == null)) {
370 // DES
371 Transform tr = new Transform(alg, "", null, null);
372 return Collections.singletonList(tr);
373 } else { // if ((mode != null) && (pad != null)) {
374 // DES/CBC/PKCS5Padding
375 List list = new ArrayList(4);
376 list.add(new Transform(alg, "/" + mode + "/" + pad, null, null));
377 list.add(new Transform(alg, "/" + mode, null, pad));
378 list.add(new Transform(alg, "//" + pad, mode, null));
379 list.add(new Transform(alg, "", mode, pad));
380 return list;
381 }
382 }
383
384 // get the transform matching the specified service
385 private static Transform getTransform(Service s, List transforms) {
386 String alg = s.getAlgorithm().toUpperCase(Locale.ENGLISH);
387 for (Iterator t = transforms.iterator(); t.hasNext(); ) {
388 Transform tr = (Transform)t.next();
389 if (alg.endsWith(tr.suffix)) {
390 return tr;
391 }
392 }
393 return null;
394 }
395
396 /**
397 * Returns a <code>Cipher</code> object that implements the specified
398 * transformation.
399 *
400 * <p> This method traverses the list of registered security Providers,
401 * starting with the most preferred Provider.
402 * A new Cipher object encapsulating the
403 * CipherSpi implementation from the first
404 * Provider that supports the specified algorithm is returned.
405 *
406 * <p> Note that the list of registered providers may be retrieved via
407 * the {@link Security#getProviders() Security.getProviders()} method.
408 *
409 * @param transformation the name of the transformation, e.g.,
410 * <i>DES/CBC/PKCS5Padding</i>.
411 * See Appendix A in the
412 * <a href=
413 * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
414 * Java Cryptography Architecture Reference Guide</a>
415 * for information about standard transformation names.
416 *
417 * @return a cipher that implements the requested transformation.
418 *
419 * @exception NoSuchAlgorithmException if <code>transformation</code>
420 * is null, empty, in an invalid format,
421 * or if no Provider supports a CipherSpi implementation for the
422 * specified algorithm.
423 *
424 * @exception NoSuchPaddingException if <code>transformation</code>
425 * contains a padding scheme that is not available.
426 *
427 * @see java.security.Provider
428 */
429 public static final Cipher getInstance(String transformation)
430 throws NoSuchAlgorithmException, NoSuchPaddingException
431 {
432 List transforms = getTransforms(transformation);
433 List cipherServices = new ArrayList(transforms.size());
434 for (Iterator t = transforms.iterator(); t.hasNext(); ) {
435 Transform transform = (Transform)t.next();
436 cipherServices.add(new ServiceId("Cipher", transform.transform));
437 }
438 List services = GetInstance.getServices(cipherServices);
439 // make sure there is at least one service from a signed provider
440 // and that it can use the specified mode and padding
441 Iterator t = services.iterator();
442 Exception failure = null;
443 while (t.hasNext()) {
444 Service s = (Service)t.next();
445 if (JceSecurity.canUseProvider(s.getProvider()) == false) {
446 continue;
447 }
448 Transform tr = getTransform(s, transforms);
449 if (tr == null) {
450 // should never happen
451 continue;
452 }
453 int canuse = tr.supportsModePadding(s);
454 if (canuse == S_NO) {
455 // does not support mode or padding we need, ignore
456 continue;
457 }
458 if (canuse == S_YES) {
459 return new Cipher(null, s, t, transformation, transforms);
460 } else { // S_MAYBE, try out if it works
461 try {
462 CipherSpi spi = (CipherSpi)s.newInstance(null);
463 tr.setModePadding(spi);
464 return new Cipher(spi, s, t, transformation, transforms);
465 } catch (Exception e) {
466 failure = e;
467 }
468 }
469 }
470 throw new NoSuchAlgorithmException
471 ("Cannot find any provider supporting " + transformation, failure);
472 }
473
474 /**
475 * Returns a <code>Cipher</code> object that implements the specified
476 * transformation.
477 *
478 * <p> A new Cipher object encapsulating the
479 * CipherSpi implementation from the specified provider
480 * is returned. The specified provider must be registered
481 * in the security provider list.
482 *
483 * <p> Note that the list of registered providers may be retrieved via
484 * the {@link Security#getProviders() Security.getProviders()} method.
485 *
486 * @param transformation the name of the transformation,
487 * e.g., <i>DES/CBC/PKCS5Padding</i>.
488 * See Appendix A in the
489 * <a href=
490 * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
491 * Java Cryptography Architecture Reference Guide</a>
492 * for information about standard transformation names.
493 *
494 * @param provider the name of the provider.
495 *
496 * @return a cipher that implements the requested transformation.
497 *
498 * @exception NoSuchAlgorithmException if <code>transformation</code>
499 * is null, empty, in an invalid format,
500 * or if a CipherSpi implementation for the specified algorithm
501 * is not available from the specified provider.
502 *
503 * @exception NoSuchProviderException if the specified provider is not
504 * registered in the security provider list.
505 *
506 * @exception NoSuchPaddingException if <code>transformation</code>
507 * contains a padding scheme that is not available.
508 *
509 * @exception IllegalArgumentException if the <code>provider</code>
510 * is null or empty.
511 *
512 * @see java.security.Provider
513 */
514 public static final Cipher getInstance(String transformation,
515 String provider)
516 throws NoSuchAlgorithmException, NoSuchProviderException,
517 NoSuchPaddingException
518 {
519 if ((provider == null) || (provider.length() == 0)) {
520 throw new IllegalArgumentException("Missing provider");
521 }
522 Provider p = Security.getProvider(provider);
523 if (p == null) {
524 throw new NoSuchProviderException("No such provider: " +
525 provider);
526 }
527 return getInstance(transformation, p);
528 }
529
530 /**
531 * Returns a <code>Cipher</code> object that implements the specified
532 * transformation.
533 *
534 * <p> A new Cipher object encapsulating the
535 * CipherSpi implementation from the specified Provider
536 * object is returned. Note that the specified Provider object
537 * does not have to be registered in the provider list.
538 *
539 * @param transformation the name of the transformation,
540 * e.g., <i>DES/CBC/PKCS5Padding</i>.
541 * See Appendix A in the
542 * <a href=
543 * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
544 * Java Cryptography Architecture Reference Guide</a>
545 * for information about standard transformation names.
546 *
547 * @param provider the provider.
548 *
549 * @return a cipher that implements the requested transformation.
550 *
551 * @exception NoSuchAlgorithmException if <code>transformation</code>
552 * is null, empty, in an invalid format,
553 * or if a CipherSpi implementation for the specified algorithm
554 * is not available from the specified Provider object.
555 *
556 * @exception NoSuchPaddingException if <code>transformation</code>
557 * contains a padding scheme that is not available.
558 *
559 * @exception IllegalArgumentException if the <code>provider</code>
560 * is null.
561 *
562 * @see java.security.Provider
563 */
564 public static final Cipher getInstance(String transformation,
565 Provider provider)
566 throws NoSuchAlgorithmException, NoSuchPaddingException
567 {
568 if (provider == null) {
569 throw new IllegalArgumentException("Missing provider");
570 }
571 Exception failure = null;
572 List transforms = getTransforms(transformation);
573 boolean providerChecked = false;
574 String paddingError = null;
575 for (Iterator t = transforms.iterator(); t.hasNext();) {
576 Transform tr = (Transform)t.next();
577 Service s = provider.getService("Cipher", tr.transform);
578 if (s == null) {
579 continue;
580 }
581 if (providerChecked == false) {
582 // for compatibility, first do the lookup and then verify
583 // the provider. this makes the difference between a NSAE
584 // and a SecurityException if the
585 // provider does not support the algorithm.
586 Exception ve = JceSecurity.getVerificationResult(provider);
587 if (ve != null) {
588 String msg = "JCE cannot authenticate the provider "
589 + provider.getName();
590 throw new SecurityException(msg, ve);
591 }
592 providerChecked = true;
593 }
594 if (tr.supportsMode(s) == S_NO) {
595 continue;
596 }
597 if (tr.supportsPadding(s) == S_NO) {
598 paddingError = tr.pad;
599 continue;
600 }
601 try {
602 CipherSpi spi = (CipherSpi)s.newInstance(null);
603 tr.setModePadding(spi);
604 Cipher cipher = new Cipher(spi, transformation);
605 cipher.provider = s.getProvider();
606 cipher.initCryptoPermission();
607 return cipher;
608 } catch (Exception e) {
609 failure = e;
610 }
611 }
612
613 // throw NoSuchPaddingException if the problem is with padding
614 if (failure instanceof NoSuchPaddingException) {
615 throw (NoSuchPaddingException)failure;
616 }
617 if (paddingError != null) {
618 throw new NoSuchPaddingException
619 ("Padding not supported: " + paddingError);
620 }
621 throw new NoSuchAlgorithmException
622 ("No such algorithm: " + transformation, failure);
623 }
624
625 // If the requested crypto service is export-controlled,
626 // determine the maximum allowable keysize.
627 private void initCryptoPermission() throws NoSuchAlgorithmException {
628 if (JceSecurity.isRestricted() == false) {
629 cryptoPerm = CryptoAllPermission.INSTANCE;
630 exmech = null;
631 return;
632 }
633 cryptoPerm = getConfiguredPermission(transformation);
634 // Instantiate the exemption mechanism (if required)
635 String exmechName = cryptoPerm.getExemptionMechanism();
636 if (exmechName != null) {
637 exmech = ExemptionMechanism.getInstance(exmechName);
638 }
639 }
640
641 // max number of debug warnings to print from chooseFirstProvider()
642 private static int warnCount = 10;
643
644 /**
645 * Choose the Spi from the first provider available. Used if
646 * delayed provider selection is not possible because init()
647 * is not the first method called.
648 */
649 void chooseFirstProvider() {
650 if (spi != null) {
651 return;
652 }
653 synchronized (lock) {
654 if (spi != null) {
655 return;
656 }
657 if (debug != null) {
658 int w = --warnCount;
659 if (w >= 0) {
660 debug.println("Cipher.init() not first method "
661 + "called, disabling delayed provider selection");
662 if (w == 0) {
663 debug.println("Further warnings of this type will "
664 + "be suppressed");
665 }
666 new Exception("Call trace").printStackTrace();
667 }
668 }
669 Exception lastException = null;
670 while ((firstService != null) || serviceIterator.hasNext()) {
671 Service s;
672 CipherSpi thisSpi;
673 if (firstService != null) {
674 s = firstService;
675 thisSpi = firstSpi;
676 firstService = null;
677 firstSpi = null;
678 } else {
679 s = (Service)serviceIterator.next();
680 thisSpi = null;
681 }
682 if (JceSecurity.canUseProvider(s.getProvider()) == false) {
683 continue;
684 }
685 Transform tr = getTransform(s, transforms);
686 if (tr == null) {
687 // should never happen
688 continue;
689 }
690 if (tr.supportsModePadding(s) == S_NO) {
691 continue;
692 }
693 try {
694 if (thisSpi == null) {
695 Object obj = s.newInstance(null);
696 if (obj instanceof CipherSpi == false) {
697 continue;
698 }
699 thisSpi = (CipherSpi)obj;
700 }
701 tr.setModePadding(thisSpi);
702 initCryptoPermission();
703 spi = thisSpi;
704 provider = s.getProvider();
705 // not needed any more
706 firstService = null;
707 serviceIterator = null;
708 transforms = null;
709 return;
710 } catch (Exception e) {
711 lastException = e;
712 }
713 }
714 ProviderException e = new ProviderException
715 ("Could not construct CipherSpi instance");
716 if (lastException != null) {
717 e.initCause(lastException);
718 }
719 throw e;
720 }
721 }
722
723 private final static int I_KEY = 1;
724 private final static int I_PARAMSPEC = 2;
725 private final static int I_PARAMS = 3;
726 private final static int I_CERT = 4;
727
728 private void implInit(CipherSpi thisSpi, int type, int opmode, Key key,
729 AlgorithmParameterSpec paramSpec, AlgorithmParameters params,
730 SecureRandom random) throws InvalidKeyException,
731 InvalidAlgorithmParameterException {
732 switch (type) {
733 case I_KEY:
734 checkCryptoPerm(thisSpi, key);
735 thisSpi.engineInit(opmode, key, random);
736 break;
737 case I_PARAMSPEC:
738 checkCryptoPerm(thisSpi, key, paramSpec);
739 thisSpi.engineInit(opmode, key, paramSpec, random);
740 break;
741 case I_PARAMS:
742 checkCryptoPerm(thisSpi, key, params);
743 thisSpi.engineInit(opmode, key, params, random);
744 break;
745 case I_CERT:
746 checkCryptoPerm(thisSpi, key);
747 thisSpi.engineInit(opmode, key, random);
748 break;
749 default:
750 throw new AssertionError("Internal Cipher error: " + type);
751 }
752 }
753
754 private void chooseProvider(int initType, int opmode, Key key,
755 AlgorithmParameterSpec paramSpec,
756 AlgorithmParameters params, SecureRandom random)
757 throws InvalidKeyException, InvalidAlgorithmParameterException {
758 synchronized (lock) {
759 if (spi != null) {
760 implInit(spi, initType, opmode, key, paramSpec, params, random);
761 return;
762 }
763 Exception lastException = null;
764 while ((firstService != null) || serviceIterator.hasNext()) {
765 Service s;
766 CipherSpi thisSpi;
767 if (firstService != null) {
768 s = firstService;
769 thisSpi = firstSpi;
770 firstService = null;
771 firstSpi = null;
772 } else {
773 s = (Service)serviceIterator.next();
774 thisSpi = null;
775 }
776 // if provider says it does not support this key, ignore it
777 if (s.supportsParameter(key) == false) {
778 continue;
779 }
780 if (JceSecurity.canUseProvider(s.getProvider()) == false) {
781 continue;
782 }
783 Transform tr = getTransform(s, transforms);
784 if (tr == null) {
785 // should never happen
786 continue;
787 }
788 if (tr.supportsModePadding(s) == S_NO) {
789 continue;
790 }
791 try {
792 if (thisSpi == null) {
793 thisSpi = (CipherSpi)s.newInstance(null);
794 }
795 tr.setModePadding(thisSpi);
796 initCryptoPermission();
797 implInit(thisSpi, initType, opmode, key, paramSpec,
798 params, random);
799 provider = s.getProvider();
800 this.spi = thisSpi;
801 firstService = null;
802 serviceIterator = null;
803 transforms = null;
804 return;
805 } catch (Exception e) {
806 // NoSuchAlgorithmException from newInstance()
807 // InvalidKeyException from init()
808 // RuntimeException (ProviderException) from init()
809 // SecurityException from crypto permission check
810 if (lastException == null) {
811 lastException = e;
812 }
813 }
814 }
815 // no working provider found, fail
816 if (lastException instanceof InvalidKeyException) {
817 throw (InvalidKeyException)lastException;
818 }
819 if (lastException instanceof InvalidAlgorithmParameterException) {
820 throw (InvalidAlgorithmParameterException)lastException;
821 }
822 if (lastException instanceof RuntimeException) {
823 throw (RuntimeException)lastException;
824 }
825 String kName = (key != null) ? key.getClass().getName() : "(null)";
826 throw new InvalidKeyException
827 ("No installed provider supports this key: "
828 + kName, lastException);
829 }
830 }
831
832 /**
833 * Returns the provider of this <code>Cipher</code> object.
834 *
835 * @return the provider of this <code>Cipher</code> object
836 */
837 public final Provider getProvider() {
838 chooseFirstProvider();
839 return this.provider;
840 }
841
842 /**
843 * Returns the algorithm name of this <code>Cipher</code> object.
844 *
845 * <p>This is the same name that was specified in one of the
846 * <code>getInstance</code> calls that created this <code>Cipher</code>
847 * object..
848 *
849 * @return the algorithm name of this <code>Cipher</code> object.
850 */
851 public final String getAlgorithm() {
852 return this.transformation;
853 }
854
855 /**
856 * Returns the block size (in bytes).
857 *
858 * @return the block size (in bytes), or 0 if the underlying algorithm is
859 * not a block cipher
860 */
861 public final int getBlockSize() {
862 chooseFirstProvider();
863 return spi.engineGetBlockSize();
864 }
865
866 /**
867 * Returns the length in bytes that an output buffer would need to be in
868 * order to hold the result of the next <code>update</code> or
869 * <code>doFinal</code> operation, given the input length
870 * <code>inputLen</code> (in bytes).
871 *
872 * <p>This call takes into account any unprocessed (buffered) data from a
873 * previous <code>update</code> call, and padding.
874 *
875 * <p>The actual output length of the next <code>update</code> or
876 * <code>doFinal</code> call may be smaller than the length returned by
877 * this method.
878 *
879 * @param inputLen the input length (in bytes)
880 *
881 * @return the required output buffer size (in bytes)
882 *
883 * @exception IllegalStateException if this cipher is in a wrong state
884 * (e.g., has not yet been initialized)
885 */
886 public final int getOutputSize(int inputLen) {
887
888 if (!initialized && !(this instanceof NullCipher)) {
889 throw new IllegalStateException("Cipher not initialized");
890 }
891 if (inputLen < 0) {
892 throw new IllegalArgumentException("Input size must be equal " +
893 "to or greater than zero");
894 }
895 chooseFirstProvider();
896 return spi.engineGetOutputSize(inputLen);
897 }
898
899 /**
900 * Returns the initialization vector (IV) in a new buffer.
901 *
902 * <p>This is useful in the case where a random IV was created,
903 * or in the context of password-based encryption or
904 * decryption, where the IV is derived from a user-supplied password.
905 *
906 * @return the initialization vector in a new buffer, or null if the
907 * underlying algorithm does not use an IV, or if the IV has not yet
908 * been set.
909 */
910 public final byte[] getIV() {
911 chooseFirstProvider();
912 return spi.engineGetIV();
913 }
914
915 /**
916 * Returns the parameters used with this cipher.
917 *
918 * <p>The returned parameters may be the same that were used to initialize
919 * this cipher, or may contain a combination of default and random
920 * parameter values used by the underlying cipher implementation if this
921 * cipher requires algorithm parameters but was not initialized with any.
922 *
923 * @return the parameters used with this cipher, or null if this cipher
924 * does not use any parameters.
925 */
926 public final AlgorithmParameters getParameters() {
927 chooseFirstProvider();
928 return spi.engineGetParameters();
929 }
930
931 /**
932 * Returns the exemption mechanism object used with this cipher.
933 *
934 * @return the exemption mechanism object used with this cipher, or
935 * null if this cipher does not use any exemption mechanism.
936 */
937 public final ExemptionMechanism getExemptionMechanism() {
938 chooseFirstProvider();
939 return exmech;
940 }
941
942 //
943 // Crypto permission check code below
944 //
945 private void checkCryptoPerm(CipherSpi checkSpi, Key key)
946 throws InvalidKeyException {
947 if (cryptoPerm == CryptoAllPermission.INSTANCE) {
948 return;
949 }
950 // Check if key size and default parameters are within legal limits
951 AlgorithmParameterSpec params;
952 try {
953 params = getAlgorithmParameterSpec(checkSpi.engineGetParameters());
954 } catch (InvalidParameterSpecException ipse) {
955 throw new InvalidKeyException
956 ("Unsupported default algorithm parameters");
957 }
958 if (!passCryptoPermCheck(checkSpi, key, params)) {
959 throw new InvalidKeyException(
960 "Illegal key size or default parameters");
961 }
962 }
963
964 private void checkCryptoPerm(CipherSpi checkSpi, Key key,
965 AlgorithmParameterSpec params) throws InvalidKeyException,
966 InvalidAlgorithmParameterException {
967 if (cryptoPerm == CryptoAllPermission.INSTANCE) {
968 return;
969 }
970 // Determine keysize and check if it is within legal limits
971 if (!passCryptoPermCheck(checkSpi, key, null)) {
972 throw new InvalidKeyException("Illegal key size");
973 }
974 if ((params != null) && (!passCryptoPermCheck(checkSpi, key, params))) {
975 throw new InvalidAlgorithmParameterException("Illegal parameters");
976 }
977 }
978
979 private void checkCryptoPerm(CipherSpi checkSpi, Key key,
980 AlgorithmParameters params)
981 throws InvalidKeyException, InvalidAlgorithmParameterException {
982 if (cryptoPerm == CryptoAllPermission.INSTANCE) {
983 return;
984 }
985 // Convert the specified parameters into specs and then delegate.
986 AlgorithmParameterSpec pSpec;
987 try {
988 pSpec = getAlgorithmParameterSpec(params);
989 } catch (InvalidParameterSpecException ipse) {
990 throw new InvalidAlgorithmParameterException
991 ("Failed to retrieve algorithm parameter specification");
992 }
993 checkCryptoPerm(checkSpi, key, pSpec);
994 }
995
996 private boolean passCryptoPermCheck(CipherSpi checkSpi, Key key,
997 AlgorithmParameterSpec params)
998 throws InvalidKeyException {
999 String em = cryptoPerm.getExemptionMechanism();
1000 int keySize = checkSpi.engineGetKeySize(key);
1001 // Use the "algorithm" component of the cipher
1002 // transformation so that the perm check would
1003 // work when the key has the "aliased" algo.
1004 String algComponent;
1005 int index = transformation.indexOf('/');
1006 if (index != -1) {
1007 algComponent = transformation.substring(0, index);
1008 } else {
1009 algComponent = transformation;
1010 }
1011 CryptoPermission checkPerm =
1012 new CryptoPermission(algComponent, keySize, params, em);
1013
1014 if (!cryptoPerm.implies(checkPerm)) {
1015 if (debug != null) {
1016 debug.println("Crypto Permission check failed");
1017 debug.println("granted: " + cryptoPerm);
1018 debug.println("requesting: " + checkPerm);
1019 }
1020 return false;
1021 }
1022 if (exmech == null) {
1023 return true;
1024 }
1025 try {
1026 if (!exmech.isCryptoAllowed(key)) {
1027 if (debug != null) {
1028 debug.println(exmech.getName() + " isn't enforced");
1029 }
1030 return false;
1031 }
1032 } catch (ExemptionMechanismException eme) {
1033 if (debug != null) {
1034 debug.println("Cannot determine whether "+
1035 exmech.getName() + " has been enforced");
1036 eme.printStackTrace();
1037 }
1038 return false;
1039 }
1040 return true;
1041 }
1042
1043 // check if opmode is one of the defined constants
1044 // throw InvalidParameterExeption if not
1045 private static void checkOpmode(int opmode) {
1046 if ((opmode < ENCRYPT_MODE) || (opmode > UNWRAP_MODE)) {
1047 throw new InvalidParameterException("Invalid operation mode");
1048 }
1049 }
1050
1051 /**
1052 * Initializes this cipher with a key.
1053 *
1054 * <p>The cipher is initialized for one of the following four operations:
1055 * encryption, decryption, key wrapping or key unwrapping, depending
1056 * on the value of <code>opmode</code>.
1057 *
1058 * <p>If this cipher requires any algorithm parameters that cannot be
1059 * derived from the given <code>key</code>, the underlying cipher
1060 * implementation is supposed to generate the required parameters itself
1061 * (using provider-specific default or random values) if it is being
1062 * initialized for encryption or key wrapping, and raise an
1063 * <code>InvalidKeyException</code> if it is being
1064 * initialized for decryption or key unwrapping.
1065 * The generated parameters can be retrieved using
1066 * {@link #getParameters() getParameters} or
1067 * {@link #getIV() getIV} (if the parameter is an IV).
1068 *
1069 * <p>If this cipher (including its underlying feedback or padding scheme)
1070 * requires any random bytes (e.g., for parameter generation), it will get
1071 * them using the {@link SecureRandom <code>SecureRandom</code>}
1072 * implementation of the highest-priority
1073 * installed provider as the source of randomness.
1074 * (If none of the installed providers supply an implementation of
1075 * SecureRandom, a system-provided source of randomness will be used.)
1076 *
1077 * <p>Note that when a Cipher object is initialized, it loses all
1078 * previously-acquired state. In other words, initializing a Cipher is
1079 * equivalent to creating a new instance of that Cipher and initializing
1080 * it.
1081 *
1082 * @param opmode the operation mode of this cipher (this is one of
1083 * the following:
1084 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
1085 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
1086 * @param key the key
1087 *
1088 * @exception InvalidKeyException if the given key is inappropriate for
1089 * initializing this cipher, or if this cipher is being initialized for
1090 * decryption and requires algorithm parameters that cannot be
1091 * determined from the given key, or if the given key has a keysize that
1092 * exceeds the maximum allowable keysize (as determined from the
1093 * configured jurisdiction policy files).
1094 */
1095 public final void init(int opmode, Key key) throws InvalidKeyException {
1096 init(opmode, key, JceSecurity.RANDOM);
1097 }
1098
1099 /**
1100 * Initializes this cipher with a key and a source of randomness.
1101 *
1102 * <p>The cipher is initialized for one of the following four operations:
1103 * encryption, decryption, key wrapping or key unwrapping, depending
1104 * on the value of <code>opmode</code>.
1105 *
1106 * <p>If this cipher requires any algorithm parameters that cannot be
1107 * derived from the given <code>key</code>, the underlying cipher
1108 * implementation is supposed to generate the required parameters itself
1109 * (using provider-specific default or random values) if it is being
1110 * initialized for encryption or key wrapping, and raise an
1111 * <code>InvalidKeyException</code> if it is being
1112 * initialized for decryption or key unwrapping.
1113 * The generated parameters can be retrieved using
1114 * {@link #getParameters() getParameters} or
1115 * {@link #getIV() getIV} (if the parameter is an IV).
1116 *
1117 * <p>If this cipher (including its underlying feedback or padding scheme)
1118 * requires any random bytes (e.g., for parameter generation), it will get
1119 * them from <code>random</code>.
1120 *
1121 * <p>Note that when a Cipher object is initialized, it loses all
1122 * previously-acquired state. In other words, initializing a Cipher is
1123 * equivalent to creating a new instance of that Cipher and initializing
1124 * it.
1125 *
1126 * @param opmode the operation mode of this cipher (this is one of the
1127 * following:
1128 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
1129 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
1130 * @param key the encryption key
1131 * @param random the source of randomness
1132 *
1133 * @exception InvalidKeyException if the given key is inappropriate for
1134 * initializing this cipher, or if this cipher is being initialized for
1135 * decryption and requires algorithm parameters that cannot be
1136 * determined from the given key, or if the given key has a keysize that
1137 * exceeds the maximum allowable keysize (as determined from the
1138 * configured jurisdiction policy files).
1139 */
1140 public final void init(int opmode, Key key, SecureRandom random)
1141 throws InvalidKeyException
1142 {
1143 initialized = false;
1144 checkOpmode(opmode);
1145
1146 if (spi != null) {
1147 checkCryptoPerm(spi, key);
1148 spi.engineInit(opmode, key, random);
1149 } else {
1150 try {
1151 chooseProvider(I_KEY, opmode, key, null, null, random);
1152 } catch (InvalidAlgorithmParameterException e) {
1153 // should never occur
1154 throw new InvalidKeyException(e);
1155 }
1156 }
1157
1158 initialized = true;
1159 this.opmode = opmode;
1160 }
1161
1162 /**
1163 * Initializes this cipher with a key and a set of algorithm
1164 * parameters.
1165 *
1166 * <p>The cipher is initialized for one of the following four operations:
1167 * encryption, decryption, key wrapping or key unwrapping, depending
1168 * on the value of <code>opmode</code>.
1169 *
1170 * <p>If this cipher requires any algorithm parameters and
1171 * <code>params</code> is null, the underlying cipher implementation is
1172 * supposed to generate the required parameters itself (using
1173 * provider-specific default or random values) if it is being
1174 * initialized for encryption or key wrapping, and raise an
1175 * <code>InvalidAlgorithmParameterException</code> if it is being
1176 * initialized for decryption or key unwrapping.
1177 * The generated parameters can be retrieved using
1178 * {@link #getParameters() getParameters} or
1179 * {@link #getIV() getIV} (if the parameter is an IV).
1180 *
1181 * <p>If this cipher (including its underlying feedback or padding scheme)
1182 * requires any random bytes (e.g., for parameter generation), it will get
1183 * them using the {@link SecureRandom <code>SecureRandom</code>}
1184 * implementation of the highest-priority
1185 * installed provider as the source of randomness.
1186 * (If none of the installed providers supply an implementation of
1187 * SecureRandom, a system-provided source of randomness will be used.)
1188 *
1189 * <p>Note that when a Cipher object is initialized, it loses all
1190 * previously-acquired state. In other words, initializing a Cipher is
1191 * equivalent to creating a new instance of that Cipher and initializing
1192 * it.
1193 *
1194 * @param opmode the operation mode of this cipher (this is one of the
1195 * following:
1196 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
1197 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
1198 * @param key the encryption key
1199 * @param params the algorithm parameters
1200 *
1201 * @exception InvalidKeyException if the given key is inappropriate for
1202 * initializing this cipher, or its keysize exceeds the maximum allowable
1203 * keysize (as determined from the configured jurisdiction policy files).
1204 * @exception InvalidAlgorithmParameterException if the given algorithm
1205 * parameters are inappropriate for this cipher,
1206 * or this cipher is being initialized for decryption and requires
1207 * algorithm parameters and <code>params</code> is null, or the given
1208 * algorithm parameters imply a cryptographic strength that would exceed
1209 * the legal limits (as determined from the configured jurisdiction
1210 * policy files).
1211 */
1212 public final void init(int opmode, Key key, AlgorithmParameterSpec params)
1213 throws InvalidKeyException, InvalidAlgorithmParameterException
1214 {
1215 init(opmode, key, params, JceSecurity.RANDOM);
1216 }
1217
1218 /**
1219 * Initializes this cipher with a key, a set of algorithm
1220 * parameters, and a source of randomness.
1221 *
1222 * <p>The cipher is initialized for one of the following four operations:
1223 * encryption, decryption, key wrapping or key unwrapping, depending
1224 * on the value of <code>opmode</code>.
1225 *
1226 * <p>If this cipher requires any algorithm parameters and
1227 * <code>params</code> is null, the underlying cipher implementation is
1228 * supposed to generate the required parameters itself (using
1229 * provider-specific default or random values) if it is being
1230 * initialized for encryption or key wrapping, and raise an
1231 * <code>InvalidAlgorithmParameterException</code> if it is being
1232 * initialized for decryption or key unwrapping.
1233 * The generated parameters can be retrieved using
1234 * {@link #getParameters() getParameters} or
1235 * {@link #getIV() getIV} (if the parameter is an IV).
1236 *
1237 * <p>If this cipher (including its underlying feedback or padding scheme)
1238 * requires any random bytes (e.g., for parameter generation), it will get
1239 * them from <code>random</code>.
1240 *
1241 * <p>Note that when a Cipher object is initialized, it loses all
1242 * previously-acquired state. In other words, initializing a Cipher is
1243 * equivalent to creating a new instance of that Cipher and initializing
1244 * it.
1245 *
1246 * @param opmode the operation mode of this cipher (this is one of the
1247 * following:
1248 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
1249 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
1250 * @param key the encryption key
1251 * @param params the algorithm parameters
1252 * @param random the source of randomness
1253 *
1254 * @exception InvalidKeyException if the given key is inappropriate for
1255 * initializing this cipher, or its keysize exceeds the maximum allowable
1256 * keysize (as determined from the configured jurisdiction policy files).
1257 * @exception InvalidAlgorithmParameterException if the given algorithm
1258 * parameters are inappropriate for this cipher,
1259 * or this cipher is being initialized for decryption and requires
1260 * algorithm parameters and <code>params</code> is null, or the given
1261 * algorithm parameters imply a cryptographic strength that would exceed
1262 * the legal limits (as determined from the configured jurisdiction
1263 * policy files).
1264 */
1265 public final void init(int opmode, Key key, AlgorithmParameterSpec params,
1266 SecureRandom random)
1267 throws InvalidKeyException, InvalidAlgorithmParameterException
1268 {
1269 initialized = false;
1270 checkOpmode(opmode);
1271
1272 if (spi != null) {
1273 checkCryptoPerm(spi, key, params);
1274 spi.engineInit(opmode, key, params, random);
1275 } else {
1276 chooseProvider(I_PARAMSPEC, opmode, key, params, null, random);
1277 }
1278
1279 initialized = true;
1280 this.opmode = opmode;
1281 }
1282
1283 /**
1284 * Initializes this cipher with a key and a set of algorithm
1285 * parameters.
1286 *
1287 * <p>The cipher is initialized for one of the following four operations:
1288 * encryption, decryption, key wrapping or key unwrapping, depending
1289 * on the value of <code>opmode</code>.
1290 *
1291 * <p>If this cipher requires any algorithm parameters and
1292 * <code>params</code> is null, the underlying cipher implementation is
1293 * supposed to generate the required parameters itself (using
1294 * provider-specific default or random values) if it is being
1295 * initialized for encryption or key wrapping, and raise an
1296 * <code>InvalidAlgorithmParameterException</code> if it is being
1297 * initialized for decryption or key unwrapping.
1298 * The generated parameters can be retrieved using
1299 * {@link #getParameters() getParameters} or
1300 * {@link #getIV() getIV} (if the parameter is an IV).
1301 *
1302 * <p>If this cipher (including its underlying feedback or padding scheme)
1303 * requires any random bytes (e.g., for parameter generation), it will get
1304 * them using the {@link SecureRandom <code>SecureRandom</code>}
1305 * implementation of the highest-priority
1306 * installed provider as the source of randomness.
1307 * (If none of the installed providers supply an implementation of
1308 * SecureRandom, a system-provided source of randomness will be used.)
1309 *
1310 * <p>Note that when a Cipher object is initialized, it loses all
1311 * previously-acquired state. In other words, initializing a Cipher is
1312 * equivalent to creating a new instance of that Cipher and initializing
1313 * it.
1314 *
1315 * @param opmode the operation mode of this cipher (this is one of the
1316 * following: <code>ENCRYPT_MODE</code>,
1317 * <code>DECRYPT_MODE</code>, <code>WRAP_MODE</code>
1318 * or <code>UNWRAP_MODE</code>)
1319 * @param key the encryption key
1320 * @param params the algorithm parameters
1321 *
1322 * @exception InvalidKeyException if the given key is inappropriate for
1323 * initializing this cipher, or its keysize exceeds the maximum allowable
1324 * keysize (as determined from the configured jurisdiction policy files).
1325 * @exception InvalidAlgorithmParameterException if the given algorithm
1326 * parameters are inappropriate for this cipher,
1327 * or this cipher is being initialized for decryption and requires
1328 * algorithm parameters and <code>params</code> is null, or the given
1329 * algorithm parameters imply a cryptographic strength that would exceed
1330 * the legal limits (as determined from the configured jurisdiction
1331 * policy files).
1332 */
1333 public final void init(int opmode, Key key, AlgorithmParameters params)
1334 throws InvalidKeyException, InvalidAlgorithmParameterException
1335 {
1336 init(opmode, key, params, JceSecurity.RANDOM);
1337 }
1338
1339 /**
1340 * Initializes this cipher with a key, a set of algorithm
1341 * parameters, and a source of randomness.
1342 *
1343 * <p>The cipher is initialized for one of the following four operations:
1344 * encryption, decryption, key wrapping or key unwrapping, depending
1345 * on the value of <code>opmode</code>.
1346 *
1347 * <p>If this cipher requires any algorithm parameters and
1348 * <code>params</code> is null, the underlying cipher implementation is
1349 * supposed to generate the required parameters itself (using
1350 * provider-specific default or random values) if it is being
1351 * initialized for encryption or key wrapping, and raise an
1352 * <code>InvalidAlgorithmParameterException</code> if it is being
1353 * initialized for decryption or key unwrapping.
1354 * The generated parameters can be retrieved using
1355 * {@link #getParameters() getParameters} or
1356 * {@link #getIV() getIV} (if the parameter is an IV).
1357 *
1358 * <p>If this cipher (including its underlying feedback or padding scheme)
1359 * requires any random bytes (e.g., for parameter generation), it will get
1360 * them from <code>random</code>.
1361 *
1362 * <p>Note that when a Cipher object is initialized, it loses all
1363 * previously-acquired state. In other words, initializing a Cipher is
1364 * equivalent to creating a new instance of that Cipher and initializing
1365 * it.
1366 *
1367 * @param opmode the operation mode of this cipher (this is one of the
1368 * following: <code>ENCRYPT_MODE</code>,
1369 * <code>DECRYPT_MODE</code>, <code>WRAP_MODE</code>
1370 * or <code>UNWRAP_MODE</code>)
1371 * @param key the encryption key
1372 * @param params the algorithm parameters
1373 * @param random the source of randomness
1374 *
1375 * @exception InvalidKeyException if the given key is inappropriate for
1376 * initializing this cipher, or its keysize exceeds the maximum allowable
1377 * keysize (as determined from the configured jurisdiction policy files).
1378 * @exception InvalidAlgorithmParameterException if the given algorithm
1379 * parameters are inappropriate for this cipher,
1380 * or this cipher is being initialized for decryption and requires
1381 * algorithm parameters and <code>params</code> is null, or the given
1382 * algorithm parameters imply a cryptographic strength that would exceed
1383 * the legal limits (as determined from the configured jurisdiction
1384 * policy files).
1385 */
1386 public final void init(int opmode, Key key, AlgorithmParameters params,
1387 SecureRandom random)
1388 throws InvalidKeyException, InvalidAlgorithmParameterException
1389 {
1390 initialized = false;
1391 checkOpmode(opmode);
1392
1393 if (spi != null) {
1394 checkCryptoPerm(spi, key, params);
1395 spi.engineInit(opmode, key, params, random);
1396 } else {
1397 chooseProvider(I_PARAMS, opmode, key, null, params, random);
1398 }
1399
1400 initialized = true;
1401 this.opmode = opmode;
1402 }
1403
1404 /**
1405 * Initializes this cipher with the public key from the given certificate.
1406 * <p> The cipher is initialized for one of the following four operations:
1407 * encryption, decryption, key wrapping or key unwrapping, depending
1408 * on the value of <code>opmode</code>.
1409 *
1410 * <p>If the certificate is of type X.509 and has a <i>key usage</i>
1411 * extension field marked as critical, and the value of the <i>key usage</i>
1412 * extension field implies that the public key in
1413 * the certificate and its corresponding private key are not
1414 * supposed to be used for the operation represented by the value
1415 * of <code>opmode</code>,
1416 * an <code>InvalidKeyException</code>
1417 * is thrown.
1418 *
1419 * <p> If this cipher requires any algorithm parameters that cannot be
1420 * derived from the public key in the given certificate, the underlying
1421 * cipher
1422 * implementation is supposed to generate the required parameters itself
1423 * (using provider-specific default or ramdom values) if it is being
1424 * initialized for encryption or key wrapping, and raise an <code>
1425 * InvalidKeyException</code> if it is being initialized for decryption or
1426 * key unwrapping.
1427 * The generated parameters can be retrieved using
1428 * {@link #getParameters() getParameters} or
1429 * {@link #getIV() getIV} (if the parameter is an IV).
1430 *
1431 * <p>If this cipher (including its underlying feedback or padding scheme)
1432 * requires any random bytes (e.g., for parameter generation), it will get
1433 * them using the
1434 * <code>SecureRandom</code>
1435 * implementation of the highest-priority
1436 * installed provider as the source of randomness.
1437 * (If none of the installed providers supply an implementation of
1438 * SecureRandom, a system-provided source of randomness will be used.)
1439 *
1440 * <p>Note that when a Cipher object is initialized, it loses all
1441 * previously-acquired state. In other words, initializing a Cipher is
1442 * equivalent to creating a new instance of that Cipher and initializing
1443 * it.
1444 *
1445 * @param opmode the operation mode of this cipher (this is one of the
1446 * following:
1447 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
1448 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
1449 * @param certificate the certificate
1450 *
1451 * @exception InvalidKeyException if the public key in the given
1452 * certificate is inappropriate for initializing this cipher, or this
1453 * cipher is being initialized for decryption or unwrapping keys and
1454 * requires algorithm parameters that cannot be determined from the
1455 * public key in the given certificate, or the keysize of the public key
1456 * in the given certificate has a keysize that exceeds the maximum
1457 * allowable keysize (as determined by the configured jurisdiction policy
1458 * files).
1459 */
1460 public final void init(int opmode, Certificate certificate)
1461 throws InvalidKeyException
1462 {
1463 init(opmode, certificate, JceSecurity.RANDOM);
1464 }
1465
1466 /**
1467 * Initializes this cipher with the public key from the given certificate
1468 * and
1469 * a source of randomness.
1470 *
1471 * <p>The cipher is initialized for one of the following four operations:
1472 * encryption, decryption, key wrapping
1473 * or key unwrapping, depending on
1474 * the value of <code>opmode</code>.
1475 *
1476 * <p>If the certificate is of type X.509 and has a <i>key usage</i>
1477 * extension field marked as critical, and the value of the <i>key usage</i>
1478 * extension field implies that the public key in
1479 * the certificate and its corresponding private key are not
1480 * supposed to be used for the operation represented by the value of
1481 * <code>opmode</code>,
1482 * an <code>InvalidKeyException</code>
1483 * is thrown.
1484 *
1485 * <p>If this cipher requires any algorithm parameters that cannot be
1486 * derived from the public key in the given <code>certificate</code>,
1487 * the underlying cipher
1488 * implementation is supposed to generate the required parameters itself
1489 * (using provider-specific default or random values) if it is being
1490 * initialized for encryption or key wrapping, and raise an
1491 * <code>InvalidKeyException</code> if it is being
1492 * initialized for decryption or key unwrapping.
1493 * The generated parameters can be retrieved using
1494 * {@link #getParameters() getParameters} or
1495 * {@link #getIV() getIV} (if the parameter is an IV).
1496 *
1497 * <p>If this cipher (including its underlying feedback or padding scheme)
1498 * requires any random bytes (e.g., for parameter generation), it will get
1499 * them from <code>random</code>.
1500 *
1501 * <p>Note that when a Cipher object is initialized, it loses all
1502 * previously-acquired state. In other words, initializing a Cipher is
1503 * equivalent to creating a new instance of that Cipher and initializing
1504 * it.
1505 *
1506 * @param opmode the operation mode of this cipher (this is one of the
1507 * following:
1508 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
1509 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
1510 * @param certificate the certificate
1511 * @param random the source of randomness
1512 *
1513 * @exception InvalidKeyException if the public key in the given
1514 * certificate is inappropriate for initializing this cipher, or this
1515 * cipher is being initialized for decryption or unwrapping keys and
1516 * requires algorithm parameters that cannot be determined from the
1517 * public key in the given certificate, or the keysize of the public key
1518 * in the given certificate has a keysize that exceeds the maximum
1519 * allowable keysize (as determined by the configured jurisdiction policy
1520 * files).
1521 */
1522 public final void init(int opmode, Certificate certificate,
1523 SecureRandom random)
1524 throws InvalidKeyException
1525 {
1526 initialized = false;
1527 checkOpmode(opmode);
1528
1529 // Check key usage if the certificate is of
1530 // type X.509.
1531 if (certificate instanceof java.security.cert.X509Certificate) {
1532 // Check whether the cert has a key usage extension
1533 // marked as a critical extension.
1534 X509Certificate cert = (X509Certificate)certificate;
1535 Set critSet = cert.getCriticalExtensionOIDs();
1536
1537 if (critSet != null && !critSet.isEmpty()
1538 && critSet.contains(KEY_USAGE_EXTENSION_OID)) {
1539 boolean[] keyUsageInfo = cert.getKeyUsage();
1540 // keyUsageInfo[2] is for keyEncipherment;
1541 // keyUsageInfo[3] is for dataEncipherment.
1542 if ((keyUsageInfo != null) &&
1543 (((opmode == Cipher.ENCRYPT_MODE) &&
1544 (keyUsageInfo.length > 3) &&
1545 (keyUsageInfo[3] == false)) ||
1546 ((opmode == Cipher.WRAP_MODE) &&
1547 (keyUsageInfo.length > 2) &&
1548 (keyUsageInfo[2] == false)))) {
1549 throw new InvalidKeyException("Wrong key usage");
1550 }
1551 }
1552 }
1553
1554 PublicKey publicKey =
1555 (certificate==null? null:certificate.getPublicKey());
1556
1557 if (spi != null) {
1558 checkCryptoPerm(spi, publicKey);
1559 spi.engineInit(opmode, publicKey, random);
1560 } else {
1561 try {
1562 chooseProvider(I_CERT, opmode, publicKey, null, null, random);
1563 } catch (InvalidAlgorithmParameterException e) {
1564 // should never occur
1565 throw new InvalidKeyException(e);
1566 }
1567 }
1568
1569 initialized = true;
1570 this.opmode = opmode;
1571 }
1572
1573 /**
1574 * Ensures that Cipher is in a valid state for update() and doFinal()
1575 * calls - should be initialized and in ENCRYPT_MODE or DECRYPT_MODE.
1576 * @throws IllegalStateException if Cipher object is not in valid state.
1577 */
1578 private void checkCipherState() {
1579 if (!(this instanceof NullCipher)) {
1580 if (!initialized) {
1581 throw new IllegalStateException("Cipher not initialized");
1582 }
1583 if ((opmode != Cipher.ENCRYPT_MODE) &&
1584 (opmode != Cipher.DECRYPT_MODE)) {
1585 throw new IllegalStateException("Cipher not initialized " +
1586 "for encryption/decryption");
1587 }
1588 }
1589 }
1590
1591 /**
1592 * Continues a multiple-part encryption or decryption operation
1593 * (depending on how this cipher was initialized), processing another data
1594 * part.
1595 *
1596 * <p>The bytes in the <code>input</code> buffer are processed, and the
1597 * result is stored in a new buffer.
1598 *
1599 * <p>If <code>input</code> has a length of zero, this method returns
1600 * <code>null</code>.
1601 *
1602 * @param input the input buffer
1603 *
1604 * @return the new buffer with the result, or null if the underlying
1605 * cipher is a block cipher and the input data is too short to result in a
1606 * new block.
1607 *
1608 * @exception IllegalStateException if this cipher is in a wrong state
1609 * (e.g., has not been initialized)
1610 */
1611 public final byte[] update(byte[] input) {
1612 checkCipherState();
1613
1614 // Input sanity check
1615 if (input == null) {
1616 throw new IllegalArgumentException("Null input buffer");
1617 }
1618
1619 chooseFirstProvider();
1620 if (input.length == 0) {
1621 return null;
1622 }
1623 return spi.engineUpdate(input, 0, input.length);
1624 }
1625
1626 /**
1627 * Continues a multiple-part encryption or decryption operation
1628 * (depending on how this cipher was initialized), processing another data
1629 * part.
1630 *
1631 * <p>The first <code>inputLen</code> bytes in the <code>input</code>
1632 * buffer, starting at <code>inputOffset</code> inclusive, are processed,
1633 * and the result is stored in a new buffer.
1634 *
1635 * <p>If <code>inputLen</code> is zero, this method returns
1636 * <code>null</code>.
1637 *
1638 * @param input the input buffer
1639 * @param inputOffset the offset in <code>input</code> where the input
1640 * starts
1641 * @param inputLen the input length
1642 *
1643 * @return the new buffer with the result, or null if the underlying
1644 * cipher is a block cipher and the input data is too short to result in a
1645 * new block.
1646 *
1647 * @exception IllegalStateException if this cipher is in a wrong state
1648 * (e.g., has not been initialized)
1649 */
1650 public final byte[] update(byte[] input, int inputOffset, int inputLen) {
1651 checkCipherState();
1652
1653 // Input sanity check
1654 if (input == null || inputOffset < 0
1655 || inputLen > (input.length - inputOffset) || inputLen < 0) {
1656 throw new IllegalArgumentException("Bad arguments");
1657 }
1658
1659 chooseFirstProvider();
1660 if (inputLen == 0) {
1661 return null;
1662 }
1663 return spi.engineUpdate(input, inputOffset, inputLen);
1664 }
1665
1666 /**
1667 * Continues a multiple-part encryption or decryption operation
1668 * (depending on how this cipher was initialized), processing another data
1669 * part.
1670 *
1671 * <p>The first <code>inputLen</code> bytes in the <code>input</code>
1672 * buffer, starting at <code>inputOffset</code> inclusive, are processed,
1673 * and the result is stored in the <code>output</code> buffer.
1674 *
1675 * <p>If the <code>output</code> buffer is too small to hold the result,
1676 * a <code>ShortBufferException</code> is thrown. In this case, repeat this
1677 * call with a larger output buffer. Use
1678 * {@link #getOutputSize(int) getOutputSize} to determine how big
1679 * the output buffer should be.
1680 *
1681 * <p>If <code>inputLen</code> is zero, this method returns
1682 * a length of zero.
1683 *
1684 * <p>Note: this method should be copy-safe, which means the
1685 * <code>input</code> and <code>output</code> buffers can reference
1686 * the same byte array and no unprocessed input data is overwritten
1687 * when the result is copied into the output buffer.
1688 *
1689 * @param input the input buffer
1690 * @param inputOffset the offset in <code>input</code> where the input
1691 * starts
1692 * @param inputLen the input length
1693 * @param output the buffer for the result
1694 *
1695 * @return the number of bytes stored in <code>output</code>
1696 *
1697 * @exception IllegalStateException if this cipher is in a wrong state
1698 * (e.g., has not been initialized)
1699 * @exception ShortBufferException if the given output buffer is too small
1700 * to hold the result
1701 */
1702 public final int update(byte[] input, int inputOffset, int inputLen,
1703 byte[] output)
1704 throws ShortBufferException {
1705 checkCipherState();
1706
1707 // Input sanity check
1708 if (input == null || inputOffset < 0
1709 || inputLen > (input.length - inputOffset) || inputLen < 0) {
1710 throw new IllegalArgumentException("Bad arguments");
1711 }
1712
1713 chooseFirstProvider();
1714 if (inputLen == 0) {
1715 return 0;
1716 }
1717 return spi.engineUpdate(input, inputOffset, inputLen,
1718 output, 0);
1719 }
1720
1721 /**
1722 * Continues a multiple-part encryption or decryption operation
1723 * (depending on how this cipher was initialized), processing another data
1724 * part.
1725 *
1726 * <p>The first <code>inputLen</code> bytes in the <code>input</code>
1727 * buffer, starting at <code>inputOffset</code> inclusive, are processed,
1728 * and the result is stored in the <code>output</code> buffer, starting at
1729 * <code>outputOffset</code> inclusive.
1730 *
1731 * <p>If the <code>output</code> buffer is too small to hold the result,
1732 * a <code>ShortBufferException</code> is thrown. In this case, repeat this
1733 * call with a larger output buffer. Use
1734 * {@link #getOutputSize(int) getOutputSize} to determine how big
1735 * the output buffer should be.
1736 *
1737 * <p>If <code>inputLen</code> is zero, this method returns
1738 * a length of zero.
1739 *
1740 * <p>Note: this method should be copy-safe, which means the
1741 * <code>input</code> and <code>output</code> buffers can reference
1742 * the same byte array and no unprocessed input data is overwritten
1743 * when the result is copied into the output buffer.
1744 *
1745 * @param input the input buffer
1746 * @param inputOffset the offset in <code>input</code> where the input
1747 * starts
1748 * @param inputLen the input length
1749 * @param output the buffer for the result
1750 * @param outputOffset the offset in <code>output</code> where the result
1751 * is stored
1752 *
1753 * @return the number of bytes stored in <code>output</code>
1754 *
1755 * @exception IllegalStateException if this cipher is in a wrong state
1756 * (e.g., has not been initialized)
1757 * @exception ShortBufferException if the given output buffer is too small
1758 * to hold the result
1759 */
1760 public final int update(byte[] input, int inputOffset, int inputLen,
1761 byte[] output, int outputOffset)
1762 throws ShortBufferException {
1763 checkCipherState();
1764
1765 // Input sanity check
1766 if (input == null || inputOffset < 0
1767 || inputLen > (input.length - inputOffset) || inputLen < 0
1768 || outputOffset < 0) {
1769 throw new IllegalArgumentException("Bad arguments");
1770 }
1771
1772 chooseFirstProvider();
1773 if (inputLen == 0) {
1774 return 0;
1775 }
1776 return spi.engineUpdate(input, inputOffset, inputLen,
1777 output, outputOffset);
1778 }
1779
1780 /**
1781 * Continues a multiple-part encryption or decryption operation
1782 * (depending on how this cipher was initialized), processing another data
1783 * part.
1784 *
1785 * <p>All <code>input.remaining()</code> bytes starting at
1786 * <code>input.position()</code> are processed. The result is stored
1787 * in the output buffer.
1788 * Upon return, the input buffer's position will be equal
1789 * to its limit; its limit will not have changed. The output buffer's
1790 * position will have advanced by n, where n is the value returned
1791 * by this method; the output buffer's limit will not have changed.
1792 *
1793 * <p>If <code>output.remaining()</code> bytes are insufficient to
1794 * hold the result, a <code>ShortBufferException</code> is thrown.
1795 * In this case, repeat this call with a larger output buffer. Use
1796 * {@link #getOutputSize(int) getOutputSize} to determine how big
1797 * the output buffer should be.
1798 *
1799 * <p>Note: this method should be copy-safe, which means the
1800 * <code>input</code> and <code>output</code> buffers can reference
1801 * the same block of memory and no unprocessed input data is overwritten
1802 * when the result is copied into the output buffer.
1803 *
1804 * @param input the input ByteBuffer
1805 * @param output the output ByteByffer
1806 *
1807 * @return the number of bytes stored in <code>output</code>
1808 *
1809 * @exception IllegalStateException if this cipher is in a wrong state
1810 * (e.g., has not been initialized)
1811 * @exception IllegalArgumentException if input and output are the
1812 * same object
1813 * @exception ReadOnlyBufferException if the output buffer is read-only
1814 * @exception ShortBufferException if there is insufficient space in the
1815 * output buffer
1816 * @since 1.5
1817 */
1818 public final int update(ByteBuffer input, ByteBuffer output)
1819 throws ShortBufferException {
1820 checkCipherState();
1821
1822 if ((input == null) || (output == null)) {
1823 throw new IllegalArgumentException("Buffers must not be null");
1824 }
1825 if (input == output) {
1826 throw new IllegalArgumentException("Input and output buffers must "
1827 + "not be the same object, consider using buffer.duplicate()");
1828 }
1829 if (output.isReadOnly()) {
1830 throw new ReadOnlyBufferException();
1831 }
1832
1833 chooseFirstProvider();
1834 return spi.engineUpdate(input, output);
1835 }
1836
1837 /**
1838 * Finishes a multiple-part encryption or decryption operation, depending
1839 * on how this cipher was initialized.
1840 *
1841 * <p>Input data that may have been buffered during a previous
1842 * <code>update</code> operation is processed, with padding (if requested)
1843 * being applied.
1844 * The result is stored in a new buffer.
1845 *
1846 * <p>Upon finishing, this method resets this cipher object to the state
1847 * it was in when previously initialized via a call to <code>init</code>.
1848 * That is, the object is reset and available to encrypt or decrypt
1849 * (depending on the operation mode that was specified in the call to
1850 * <code>init</code>) more data.
1851 *
1852 * <p>Note: if any exception is thrown, this cipher object may need to
1853 * be reset before it can be used again.
1854 *
1855 * @return the new buffer with the result
1856 *
1857 * @exception IllegalStateException if this cipher is in a wrong state
1858 * (e.g., has not been initialized)
1859 * @exception IllegalBlockSizeException if this cipher is a block cipher,
1860 * no padding has been requested (only in encryption mode), and the total
1861 * input length of the data processed by this cipher is not a multiple of
1862 * block size; or if this encryption algorithm is unable to
1863 * process the input data provided.
1864 * @exception BadPaddingException if this cipher is in decryption mode,
1865 * and (un)padding has been requested, but the decrypted data is not
1866 * bounded by the appropriate padding bytes
1867 */
1868 public final byte[] doFinal()
1869 throws IllegalBlockSizeException, BadPaddingException {
1870 checkCipherState();
1871
1872 chooseFirstProvider();
1873 return spi.engineDoFinal(null, 0, 0);
1874 }
1875
1876 /**
1877 * Finishes a multiple-part encryption or decryption operation, depending
1878 * on how this cipher was initialized.
1879 *
1880 * <p>Input data that may have been buffered during a previous
1881 * <code>update</code> operation is processed, with padding (if requested)
1882 * being applied.
1883 * The result is stored in the <code>output</code> buffer, starting at
1884 * <code>outputOffset</code> inclusive.
1885 *
1886 * <p>If the <code>output</code> buffer is too small to hold the result,
1887 * a <code>ShortBufferException</code> is thrown. In this case, repeat this
1888 * call with a larger output buffer. Use
1889 * {@link #getOutputSize(int) getOutputSize} to determine how big
1890 * the output buffer should be.
1891 *
1892 * <p>Upon finishing, this method resets this cipher object to the state
1893 * it was in when previously initialized via a call to <code>init</code>.
1894 * That is, the object is reset and available to encrypt or decrypt
1895 * (depending on the operation mode that was specified in the call to
1896 * <code>init</code>) more data.
1897 *
1898 * <p>Note: if any exception is thrown, this cipher object may need to
1899 * be reset before it can be used again.
1900 *
1901 * @param output the buffer for the result
1902 * @param outputOffset the offset in <code>output</code> where the result
1903 * is stored
1904 *
1905 * @return the number of bytes stored in <code>output</code>
1906 *
1907 * @exception IllegalStateException if this cipher is in a wrong state
1908 * (e.g., has not been initialized)
1909 * @exception IllegalBlockSizeException if this cipher is a block cipher,
1910 * no padding has been requested (only in encryption mode), and the total
1911 * input length of the data processed by this cipher is not a multiple of
1912 * block size; or if this encryption algorithm is unable to
1913 * process the input data provided.
1914 * @exception ShortBufferException if the given output buffer is too small
1915 * to hold the result
1916 * @exception BadPaddingException if this cipher is in decryption mode,
1917 * and (un)padding has been requested, but the decrypted data is not
1918 * bounded by the appropriate padding bytes
1919 */
1920 public final int doFinal(byte[] output, int outputOffset)
1921 throws IllegalBlockSizeException, ShortBufferException,
1922 BadPaddingException {
1923 checkCipherState();
1924
1925 // Input sanity check
1926 if ((output == null) || (outputOffset < 0)) {
1927 throw new IllegalArgumentException("Bad arguments");
1928 }
1929
1930 chooseFirstProvider();
1931 return spi.engineDoFinal(null, 0, 0, output, outputOffset);
1932 }
1933
1934 /**
1935 * Encrypts or decrypts data in a single-part operation, or finishes a
1936 * multiple-part operation. The data is encrypted or decrypted,
1937 * depending on how this cipher was initialized.
1938 *
1939 * <p>The bytes in the <code>input</code> buffer, and any input bytes that
1940 * may have been buffered during a previous <code>update</code> operation,
1941 * are processed, with padding (if requested) being applied.
1942 * The result is stored in a new buffer.
1943 *
1944 * <p>Upon finishing, this method resets this cipher object to the state
1945 * it was in when previously initialized via a call to <code>init</code>.
1946 * That is, the object is reset and available to encrypt or decrypt
1947 * (depending on the operation mode that was specified in the call to
1948 * <code>init</code>) more data.
1949 *
1950 * <p>Note: if any exception is thrown, this cipher object may need to
1951 * be reset before it can be used again.
1952 *
1953 * @param input the input buffer
1954 *
1955 * @return the new buffer with the result
1956 *
1957 * @exception IllegalStateException if this cipher is in a wrong state
1958 * (e.g., has not been initialized)
1959 * @exception IllegalBlockSizeException if this cipher is a block cipher,
1960 * no padding has been requested (only in encryption mode), and the total
1961 * input length of the data processed by this cipher is not a multiple of
1962 * block size; or if this encryption algorithm is unable to
1963 * process the input data provided.
1964 * @exception BadPaddingException if this cipher is in decryption mode,
1965 * and (un)padding has been requested, but the decrypted data is not
1966 * bounded by the appropriate padding bytes
1967 */
1968 public final byte[] doFinal(byte[] input)
1969 throws IllegalBlockSizeException, BadPaddingException {
1970 checkCipherState();
1971
1972 // Input sanity check
1973 if (input == null) {
1974 throw new IllegalArgumentException("Null input buffer");
1975 }
1976
1977 chooseFirstProvider();
1978 return spi.engineDoFinal(input, 0, input.length);
1979 }
1980
1981 /**
1982 * Encrypts or decrypts data in a single-part operation, or finishes a
1983 * multiple-part operation. The data is encrypted or decrypted,
1984 * depending on how this cipher was initialized.
1985 *
1986 * <p>The first <code>inputLen</code> bytes in the <code>input</code>
1987 * buffer, starting at <code>inputOffset</code> inclusive, and any input
1988 * bytes that may have been buffered during a previous <code>update</code>
1989 * operation, are processed, with padding (if requested) being applied.
1990 * The result is stored in a new buffer.
1991 *
1992 * <p>Upon finishing, this method resets this cipher object to the state
1993 * it was in when previously initialized via a call to <code>init</code>.
1994 * That is, the object is reset and available to encrypt or decrypt
1995 * (depending on the operation mode that was specified in the call to
1996 * <code>init</code>) more data.
1997 *
1998 * <p>Note: if any exception is thrown, this cipher object may need to
1999 * be reset before it can be used again.
2000 *
2001 * @param input the input buffer
2002 * @param inputOffset the offset in <code>input</code> where the input
2003 * starts
2004 * @param inputLen the input length
2005 *
2006 * @return the new buffer with the result
2007 *
2008 * @exception IllegalStateException if this cipher is in a wrong state
2009 * (e.g., has not been initialized)
2010 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2011 * no padding has been requested (only in encryption mode), and the total
2012 * input length of the data processed by this cipher is not a multiple of
2013 * block size; or if this encryption algorithm is unable to
2014 * process the input data provided.
2015 * @exception BadPaddingException if this cipher is in decryption mode,
2016 * and (un)padding has been requested, but the decrypted data is not
2017 * bounded by the appropriate padding bytes
2018 */
2019 public final byte[] doFinal(byte[] input, int inputOffset, int inputLen)
2020 throws IllegalBlockSizeException, BadPaddingException {
2021 checkCipherState();
2022
2023 // Input sanity check
2024 if (input == null || inputOffset < 0
2025 || inputLen > (input.length - inputOffset) || inputLen < 0) {
2026 throw new IllegalArgumentException("Bad arguments");
2027 }
2028
2029 chooseFirstProvider();
2030 return spi.engineDoFinal(input, inputOffset, inputLen);
2031 }
2032
2033 /**
2034 * Encrypts or decrypts data in a single-part operation, or finishes a
2035 * multiple-part operation. The data is encrypted or decrypted,
2036 * depending on how this cipher was initialized.
2037 *
2038 * <p>The first <code>inputLen</code> bytes in the <code>input</code>
2039 * buffer, starting at <code>inputOffset</code> inclusive, and any input
2040 * bytes that may have been buffered during a previous <code>update</code>
2041 * operation, are processed, with padding (if requested) being applied.
2042 * The result is stored in the <code>output</code> buffer.
2043 *
2044 * <p>If the <code>output</code> buffer is too small to hold the result,
2045 * a <code>ShortBufferException</code> is thrown. In this case, repeat this
2046 * call with a larger output buffer. Use
2047 * {@link #getOutputSize(int) getOutputSize} to determine how big
2048 * the output buffer should be.
2049 *
2050 * <p>Upon finishing, this method resets this cipher object to the state
2051 * it was in when previously initialized via a call to <code>init</code>.
2052 * That is, the object is reset and available to encrypt or decrypt
2053 * (depending on the operation mode that was specified in the call to
2054 * <code>init</code>) more data.
2055 *
2056 * <p>Note: if any exception is thrown, this cipher object may need to
2057 * be reset before it can be used again.
2058 *
2059 * <p>Note: this method should be copy-safe, which means the
2060 * <code>input</code> and <code>output</code> buffers can reference
2061 * the same byte array and no unprocessed input data is overwritten
2062 * when the result is copied into the output buffer.
2063 *
2064 * @param input the input buffer
2065 * @param inputOffset the offset in <code>input</code> where the input
2066 * starts
2067 * @param inputLen the input length
2068 * @param output the buffer for the result
2069 *
2070 * @return the number of bytes stored in <code>output</code>
2071 *
2072 * @exception IllegalStateException if this cipher is in a wrong state
2073 * (e.g., has not been initialized)
2074 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2075 * no padding has been requested (only in encryption mode), and the total
2076 * input length of the data processed by this cipher is not a multiple of
2077 * block size; or if this encryption algorithm is unable to
2078 * process the input data provided.
2079 * @exception ShortBufferException if the given output buffer is too small
2080 * to hold the result
2081 * @exception BadPaddingException if this cipher is in decryption mode,
2082 * and (un)padding has been requested, but the decrypted data is not
2083 * bounded by the appropriate padding bytes
2084 */
2085 public final int doFinal(byte[] input, int inputOffset, int inputLen,
2086 byte[] output)
2087 throws ShortBufferException, IllegalBlockSizeException,
2088 BadPaddingException {
2089 checkCipherState();
2090
2091 // Input sanity check
2092 if (input == null || inputOffset < 0
2093 || inputLen > (input.length - inputOffset) || inputLen < 0) {
2094 throw new IllegalArgumentException("Bad arguments");
2095 }
2096
2097 chooseFirstProvider();
2098 return spi.engineDoFinal(input, inputOffset, inputLen,
2099 output, 0);
2100 }
2101
2102 /**
2103 * Encrypts or decrypts data in a single-part operation, or finishes a
2104 * multiple-part operation. The data is encrypted or decrypted,
2105 * depending on how this cipher was initialized.
2106 *
2107 * <p>The first <code>inputLen</code> bytes in the <code>input</code>
2108 * buffer, starting at <code>inputOffset</code> inclusive, and any input
2109 * bytes that may have been buffered during a previous
2110 * <code>update</code> operation, are processed, with padding
2111 * (if requested) being applied.
2112 * The result is stored in the <code>output</code> buffer, starting at
2113 * <code>outputOffset</code> inclusive.
2114 *
2115 * <p>If the <code>output</code> buffer is too small to hold the result,
2116 * a <code>ShortBufferException</code> is thrown. In this case, repeat this
2117 * call with a larger output buffer. Use
2118 * {@link #getOutputSize(int) getOutputSize} to determine how big
2119 * the output buffer should be.
2120 *
2121 * <p>Upon finishing, this method resets this cipher object to the state
2122 * it was in when previously initialized via a call to <code>init</code>.
2123 * That is, the object is reset and available to encrypt or decrypt
2124 * (depending on the operation mode that was specified in the call to
2125 * <code>init</code>) more data.
2126 *
2127 * <p>Note: if any exception is thrown, this cipher object may need to
2128 * be reset before it can be used again.
2129 *
2130 * <p>Note: this method should be copy-safe, which means the
2131 * <code>input</code> and <code>output</code> buffers can reference
2132 * the same byte array and no unprocessed input data is overwritten
2133 * when the result is copied into the output buffer.
2134 *
2135 * @param input the input buffer
2136 * @param inputOffset the offset in <code>input</code> where the input
2137 * starts
2138 * @param inputLen the input length
2139 * @param output the buffer for the result
2140 * @param outputOffset the offset in <code>output</code> where the result
2141 * is stored
2142 *
2143 * @return the number of bytes stored in <code>output</code>
2144 *
2145 * @exception IllegalStateException if this cipher is in a wrong state
2146 * (e.g., has not been initialized)
2147 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2148 * no padding has been requested (only in encryption mode), and the total
2149 * input length of the data processed by this cipher is not a multiple of
2150 * block size; or if this encryption algorithm is unable to
2151 * process the input data provided.
2152 * @exception ShortBufferException if the given output buffer is too small
2153 * to hold the result
2154 * @exception BadPaddingException if this cipher is in decryption mode,
2155 * and (un)padding has been requested, but the decrypted data is not
2156 * bounded by the appropriate padding bytes
2157 */
2158 public final int doFinal(byte[] input, int inputOffset, int inputLen,
2159 byte[] output, int outputOffset)
2160 throws ShortBufferException, IllegalBlockSizeException,
2161 BadPaddingException {
2162 checkCipherState();
2163
2164 // Input sanity check
2165 if (input == null || inputOffset < 0
2166 || inputLen > (input.length - inputOffset) || inputLen < 0
2167 || outputOffset < 0) {
2168 throw new IllegalArgumentException("Bad arguments");
2169 }
2170
2171 chooseFirstProvider();
2172 return spi.engineDoFinal(input, inputOffset, inputLen,
2173 output, outputOffset);
2174 }
2175
2176 /**
2177 * Encrypts or decrypts data in a single-part operation, or finishes a
2178 * multiple-part operation. The data is encrypted or decrypted,
2179 * depending on how this cipher was initialized.
2180 *
2181 * <p>All <code>input.remaining()</code> bytes starting at
2182 * <code>input.position()</code> are processed. The result is stored
2183 * in the output buffer.
2184 * Upon return, the input buffer's position will be equal
2185 * to its limit; its limit will not have changed. The output buffer's
2186 * position will have advanced by n, where n is the value returned
2187 * by this method; the output buffer's limit will not have changed.
2188 *
2189 * <p>If <code>output.remaining()</code> bytes are insufficient to
2190 * hold the result, a <code>ShortBufferException</code> is thrown.
2191 * In this case, repeat this call with a larger output buffer. Use
2192 * {@link #getOutputSize(int) getOutputSize} to determine how big
2193 * the output buffer should be.
2194 *
2195 * <p>Upon finishing, this method resets this cipher object to the state
2196 * it was in when previously initialized via a call to <code>init</code>.
2197 * That is, the object is reset and available to encrypt or decrypt
2198 * (depending on the operation mode that was specified in the call to
2199 * <code>init</code>) more data.
2200 *
2201 * <p>Note: if any exception is thrown, this cipher object may need to
2202 * be reset before it can be used again.
2203 *
2204 * <p>Note: this method should be copy-safe, which means the
2205 * <code>input</code> and <code>output</code> buffers can reference
2206 * the same byte array and no unprocessed input data is overwritten
2207 * when the result is copied into the output buffer.
2208 *
2209 * @param input the input ByteBuffer
2210 * @param output the output ByteBuffer
2211 *
2212 * @return the number of bytes stored in <code>output</code>
2213 *
2214 * @exception IllegalStateException if this cipher is in a wrong state
2215 * (e.g., has not been initialized)
2216 * @exception IllegalArgumentException if input and output are the
2217 * same object
2218 * @exception ReadOnlyBufferException if the output buffer is read-only
2219 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2220 * no padding has been requested (only in encryption mode), and the total
2221 * input length of the data processed by this cipher is not a multiple of
2222 * block size; or if this encryption algorithm is unable to
2223 * process the input data provided.
2224 * @exception ShortBufferException if there is insufficient space in the
2225 * output buffer
2226 * @exception BadPaddingException if this cipher is in decryption mode,
2227 * and (un)padding has been requested, but the decrypted data is not
2228 * bounded by the appropriate padding bytes
2229 * @since 1.5
2230 */
2231 public final int doFinal(ByteBuffer input, ByteBuffer output)
2232 throws ShortBufferException, IllegalBlockSizeException,
2233 BadPaddingException {
2234 checkCipherState();
2235
2236 if ((input == null) || (output == null)) {
2237 throw new IllegalArgumentException("Buffers must not be null");
2238 }
2239 if (input == output) {
2240 throw new IllegalArgumentException("Input and output buffers must "
2241 + "not be the same object, consider using buffer.duplicate()");
2242 }
2243 if (output.isReadOnly()) {
2244 throw new ReadOnlyBufferException();
2245 }
2246
2247 chooseFirstProvider();
2248 return spi.engineDoFinal(input, output);
2249 }
2250
2251 /**
2252 * Wrap a key.
2253 *
2254 * @param key the key to be wrapped.
2255 *
2256 * @return the wrapped key.
2257 *
2258 * @exception IllegalStateException if this cipher is in a wrong
2259 * state (e.g., has not been initialized).
2260 *
2261 * @exception IllegalBlockSizeException if this cipher is a block
2262 * cipher, no padding has been requested, and the length of the
2263 * encoding of the key to be wrapped is not a
2264 * multiple of the block size.
2265 *
2266 * @exception InvalidKeyException if it is impossible or unsafe to
2267 * wrap the key with this cipher (e.g., a hardware protected key is
2268 * being passed to a software-only cipher).
2269 */
2270 public final byte[] wrap(Key key)
2271 throws IllegalBlockSizeException, InvalidKeyException {
2272 if (!(this instanceof NullCipher)) {
2273 if (!initialized) {
2274 throw new IllegalStateException("Cipher not initialized");
2275 }
2276 if (opmode != Cipher.WRAP_MODE) {
2277 throw new IllegalStateException("Cipher not initialized " +
2278 "for wrapping keys");
2279 }
2280 }
2281
2282 chooseFirstProvider();
2283 return spi.engineWrap(key);
2284 }
2285
2286 /**
2287 * Unwrap a previously wrapped key.
2288 *
2289 * @param wrappedKey the key to be unwrapped.
2290 *
2291 * @param wrappedKeyAlgorithm the algorithm associated with the wrapped
2292 * key.
2293 *
2294 * @param wrappedKeyType the type of the wrapped key. This must be one of
2295 * <code>SECRET_KEY</code>, <code>PRIVATE_KEY</code>, or
2296 * <code>PUBLIC_KEY</code>.
2297 *
2298 * @return the unwrapped key.
2299 *
2300 * @exception IllegalStateException if this cipher is in a wrong state
2301 * (e.g., has not been initialized).
2302 *
2303 * @exception NoSuchAlgorithmException if no installed providers
2304 * can create keys of type <code>wrappedKeyType</code> for the
2305 * <code>wrappedKeyAlgorithm</code>.
2306 *
2307 * @exception InvalidKeyException if <code>wrappedKey</code> does not
2308 * represent a wrapped key of type <code>wrappedKeyType</code> for
2309 * the <code>wrappedKeyAlgorithm</code>.
2310 */
2311 public final Key unwrap(byte[] wrappedKey,
2312 String wrappedKeyAlgorithm,
2313 int wrappedKeyType)
2314 throws InvalidKeyException, NoSuchAlgorithmException {
2315
2316 if (!(this instanceof NullCipher)) {
2317 if (!initialized) {
2318 throw new IllegalStateException("Cipher not initialized");
2319 }
2320 if (opmode != Cipher.UNWRAP_MODE) {
2321 throw new IllegalStateException("Cipher not initialized " +
2322 "for unwrapping keys");
2323 }
2324 }
2325 if ((wrappedKeyType != SECRET_KEY) &&
2326 (wrappedKeyType != PRIVATE_KEY) &&
2327 (wrappedKeyType != PUBLIC_KEY)) {
2328 throw new InvalidParameterException("Invalid key type");
2329 }
2330
2331 chooseFirstProvider();
2332 return spi.engineUnwrap(wrappedKey,
2333 wrappedKeyAlgorithm,
2334 wrappedKeyType);
2335 }
2336
2337 private AlgorithmParameterSpec getAlgorithmParameterSpec(
2338 AlgorithmParameters params)
2339 throws InvalidParameterSpecException {
2340 if (params == null) {
2341 return null;
2342 }
2343
2344 String alg = params.getAlgorithm().toUpperCase(Locale.ENGLISH);
2345
2346 if (alg.equalsIgnoreCase("RC2")) {
2347 return params.getParameterSpec(RC2ParameterSpec.class);
2348 }
2349
2350 if (alg.equalsIgnoreCase("RC5")) {
2351 return params.getParameterSpec(RC5ParameterSpec.class);
2352 }
2353
2354 if (alg.startsWith("PBE")) {
2355 return params.getParameterSpec(PBEParameterSpec.class);
2356 }
2357
2358 if (alg.startsWith("DES")) {
2359 return params.getParameterSpec(IvParameterSpec.class);
2360 }
2361 return null;
2362 }
2363
2364 private static CryptoPermission getConfiguredPermission(
2365 String transformation) throws NullPointerException,
2366 NoSuchAlgorithmException {
2367 if (transformation == null) throw new NullPointerException();
2368 String[] parts = tokenizeTransformation(transformation);
2369 return JceSecurityManager.INSTANCE.getCryptoPermission(parts[0]);
2370 }
2371
2372 /**
2373 * Returns the maximum key length for the specified transformation
2374 * according to the installed JCE jurisdiction policy files. If
2375 * JCE unlimited strength jurisdiction policy files are installed,
2376 * Integer.MAX_VALUE will be returned.
2377 * For more information on default key size in JCE jurisdiction
2378 * policy files, please see Appendix E in the
2379 * <a href=
2380 * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppE">
2381 * Java Cryptography Architecture Reference Guide</a>.
2382 *
2383 * @param transformation the cipher transformation.
2384 * @return the maximum key length in bits or Integer.MAX_VALUE.
2385 * @exception NullPointerException if <code>transformation</code> is null.
2386 * @exception NoSuchAlgorithmException if <code>transformation</code>
2387 * is not a valid transformation, i.e. in the form of "algorithm" or
2388 * "algorithm/mode/padding".
2389 * @since 1.5
2390 */
2391 public static final int getMaxAllowedKeyLength(String transformation)
2392 throws NoSuchAlgorithmException {
2393 CryptoPermission cp = getConfiguredPermission(transformation);
2394 return cp.getMaxKeySize();
2395 }
2396
2397 /**
2398 * Returns an AlgorithmParameterSpec object which contains
2399 * the maximum cipher parameter value according to the
2400 * jurisdiction policy file. If JCE unlimited strength jurisdiction
2401 * policy files are installed or there is no maximum limit on the
2402 * parameters for the specified transformation in the policy file,
2403 * null will be returned.
2404 *
2405 * @param transformation the cipher transformation.
2406 * @return an AlgorithmParameterSpec which holds the maximum
2407 * value or null.
2408 * @exception NullPointerException if <code>transformation</code>
2409 * is null.
2410 * @exception NoSuchAlgorithmException if <code>transformation</code>
2411 * is not a valid transformation, i.e. in the form of "algorithm" or
2412 * "algorithm/mode/padding".
2413 * @since 1.5
2414 */
2415 public static final AlgorithmParameterSpec getMaxAllowedParameterSpec(
2416 String transformation) throws NoSuchAlgorithmException {
2417 CryptoPermission cp = getConfiguredPermission(transformation);
2418 return cp.getAlgorithmParameterSpec();
2419 }
2420}