001 // Copyright (C) 2002 IAIK
002 // https://jce.iaik.tugraz.at
003 //
004 // Copyright (C) 2003 - 2025 Stiftung Secure Information and
005 // Communication Technologies SIC
006 // https://sic.tech
007 //
008 // All rights reserved.
009 //
010 // Redistribution and use in source and binary forms, with or without
011 // modification, are permitted provided that the following conditions
012 // are met:
013 // 1. Redistributions of source code must retain the above copyright
014 // notice, this list of conditions and the following disclaimer.
015 // 2. Redistributions in binary form must reproduce the above copyright
016 // notice, this list of conditions and the following disclaimer in the
017 // documentation and/or other materials provided with the distribution.
018 //
019 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
020 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
021 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022 // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
023 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
024 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
025 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
026 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
027 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
028 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
029 // SUCH DAMAGE.
030
031 // Copyright (C) 2002 IAIK
032 // https://sic.tech/
033 //
034 // Copyright (C) 2003 - 2025 Stiftung Secure Information and
035 // Communication Technologies SIC
036 // https://sic.tech/
037 //
038 // All rights reserved.
039 //
040 // This source is provided for inspection purposes and recompilation only,
041 // unless specified differently in a contract with IAIK. This source has to
042 // be kept in strict confidence and must not be disclosed to any third party
043 // under any circumstances. Redistribution in source and binary forms, with
044 // or without modification, are <not> permitted in any case!
045 //
046 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
047 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
048 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
049 // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
050 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
051 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
052 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
053 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
054 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
055 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
056 // SUCH DAMAGE.
057 //
058 // $Header: /IAIK-CMS/current/src/demo/cms/pkcs11/IaikPkcs11SecurityProvider.java 11 12.02.25 17:58 Dbratko $
059 //
060
061 package demo.cms.pkcs11;
062
063 import java.security.InvalidAlgorithmParameterException;
064 import java.security.InvalidKeyException;
065 import java.security.Key;
066 import java.security.NoSuchAlgorithmException;
067 import java.security.NoSuchProviderException;
068 import java.security.PrivateKey;
069 import java.security.PublicKey;
070 import java.security.SecureRandom;
071 import java.security.Signature;
072 import java.security.SignatureException;
073 import java.security.spec.AlgorithmParameterSpec;
074
075 import javax.crypto.BadPaddingException;
076 import javax.crypto.Cipher;
077 import javax.crypto.IllegalBlockSizeException;
078 import javax.crypto.NoSuchPaddingException;
079 import javax.crypto.SecretKey;
080
081 import iaik.asn1.structures.AlgorithmID;
082 import iaik.cms.CMSAlgorithmID;
083 import iaik.cms.DigestInfo;
084 import iaik.cms.IaikProvider;
085 import iaik.pkcs.pkcs1.RSAPssParameterSpec;
086 import iaik.pkcs.pkcs11.Mechanism;
087 import iaik.pkcs.pkcs11.parameters.RSAPkcsParameters;
088 import iaik.pkcs.pkcs11.parameters.RSAPkcsPssParameters;
089 import iaik.pkcs.pkcs11.provider.IAIKPkcs11;
090 import iaik.pkcs.pkcs11.provider.keys.IAIKPKCS11Key;
091 import iaik.pkcs.pkcs11.provider.keys.IAIKPKCS11PrivateKey;
092 import iaik.pkcs.pkcs11.provider.signatures.PKCS11SignatureParameterSpec;
093 import iaik.pkcs.pkcs11.wrapper.PKCS11Constants;
094
095
096
097 /**
098 * This class implements a <code>SecurityProvider</code> for the IAIK-CMS
099 * toolkit. This <code>SecurityProvider</code> can handle
100 * <code>IAIKPKCS11Key</code> objects and is thus suitable for use with the
101 * PKCS#11 provider. The demos in this package use this class to get the
102 * IAIK-CMS library to use a PKCS#11 module instead of pure software crypto.
103 * <p>
104 * To install this security provider call:
105 * <pre>
106 * IAIKPkcs11 iaikPkcs11Provider = ...;
107 * IaikPkcs11SecurityProvider pkcs11CmsSecurityProvider = new IaikPkcs11SecurityProvider(iaikPkcs11Provider);
108 * SecurityProvider.setSecurityProvider(pkcs11CmsSecurityProvider);
109 * </pre>
110 */
111 public class IaikPkcs11SecurityProvider extends IaikProvider {
112
113 /**
114 * Switch on/off debug output.
115 */
116 private final static boolean DEBUG = true;
117
118 /**
119 * The name of the security provider.
120 */
121 private final static String PROVIDER_NAME = "IAIK PKCS#11 Security Provider";
122
123 /**
124 * Reference to the installed PKCS#11 provider instance.
125 */
126 protected IAIKPkcs11 iaikPkcs11Provider_;
127
128 /**
129 * The given PKCS#11 provider instance must already be installed in the JCA
130 * framework.
131 *
132 * @param iaikPkcs11Provider The PKCS#11 provider instance to use in this CMS
133 * security provider.
134 */
135 public IaikPkcs11SecurityProvider(IAIKPkcs11 iaikPkcs11Provider) {
136 super();
137 // providerName_ = PROVIDER_NAME;
138 iaikPkcs11Provider_ = iaikPkcs11Provider;
139 }
140
141 /**
142 * Calculates the signature value for a CMS SignerInfo over the given digest
143 * value with the given algorithm using the supplied private key.
144 * <p>
145 * Each {@link iaik.cms.SignerInfo SignerInfo} included in a CMS SignedData
146 * object may calculate the signature value differently depending on the
147 * presence of signed attributes:
148 * <p>
149 * <ul>
150 * <li>If signed attributes are present the signature is calculated over
151 * the DER encoding of the signed attributes.
152 * <li>If signed attributes are NOT present, the signature is calculated
153 * over the content data itsself.
154 * </ul>
155 * This method is called by class {@link iaik.cms.SignerInfo SignerInfo} for
156 * calculating the signature when no signed attributes are present. Since
157 * the data to be signed may be of arbitrary size this method expects the
158 * already hashed data to only calculate the signature value on it (for
159 * instance, by doing the digest encrypting when using RSA for signing).
160 * <p>
161 * For that reason, when writing your own SecurityProvider and overriding
162 * this method, you will need some kind of <i>RAW</i> signature (respectively
163 * digest encryption) mechanism only expecting the already hashed data (e.g.
164 * a "RawDSA" signature engine when using DSA repectively a Cipher engine
165 * when using RSA).
166 * <p>
167 * If you want to override this method for use with smartcards, please be sure
168 * that your smartcard is able to do the signature (respectively digest
169 * encryption) operation only. However, if your smartcard requires to supply
170 * the whole data for doing the hash calcualtion itself, you may ensure that
171 * your {@link iaik.cms.SignerInfo SignerInfo} contains signed attributes
172 * and override method {@link #calculateSignatureFromSignedAttributes
173 * calculateSignatureFromSignedAttributes} for calculating the signature over
174 * the DER encoding of the signed attributes (thereby doing the hash
175 * computation, too).
176 *
177 * @param signatureAlgorithm signatureAlgorithm the signature algorithm to be
178 * used, e.g. rsaEncryption, DSA
179 * @param digestAlgorithm the digest algorithm used for hash computation (e.g.
180 * SHA-1 or MD5); may be necessary for some signature schemes (e.g.
181 * to be included as a DigestInfo in a PKCS#1 RSA signature)
182 * @param privateKey the private key of the signer (i.e. the one supplied when
183 * creating a {@link iaik.cms.SignerInfo SignerInfo} object; may be
184 * some kind of "dummy" key when used for smartcards
185 * @param digest the digest value over which the signature shall be calculated
186 *
187 * @return the signature value calculated from the given digest value
188 *
189 * @throws NoSuchAlgorithmException if any of the required algorithms is not supported
190 * @throws InvalidKeyException if the key is not valid
191 * @throws SignatureException if signature verification fails because of some crypto related error
192 */
193 public byte[] calculateSignatureFromHash(AlgorithmID signatureAlgorithm,
194 AlgorithmID digestAlgorithm, PrivateKey privateKey, byte[] digest)
195 throws NoSuchAlgorithmException, InvalidKeyException, SignatureException
196 {
197 byte[] signatureValue;
198
199 // we handle PKCS#11 keys in a special way, but we forward other keys to the default implementation
200 if (privateKey instanceof IAIKPKCS11PrivateKey) {
201 IAIKPkcs11 iaikPkcs11KeyProvider = ((IAIKPKCS11PrivateKey) privateKey).getTokenManager().getProvider();
202
203 String algorithmName = privateKey.getAlgorithm();
204
205 Signature signatureEngine;
206 byte[] dataToBeSigned = digest;
207 try {
208 if (algorithmName.equals("RSA")) {
209 if (signatureAlgorithm.equals(CMSAlgorithmID.rsassaPss)) {
210 signatureEngine = Signature.getInstance("RawRSA/PSS", iaikPkcs11KeyProvider.getName());
211 PKCS11SignatureParameterSpec params = generateRSAPssParameters(digestAlgorithm, signatureAlgorithm);
212 try {
213 signatureEngine.setParameter(params);
214 } catch (InvalidAlgorithmParameterException e) {
215 throw new SignatureException("Error setting RSA-PSS algorithm parameters: " + e.toString());
216 }
217 } else {
218 DigestInfo digestInfo = new DigestInfo(digestAlgorithm, digest);
219 dataToBeSigned = digestInfo.toByteArray();
220 signatureEngine = Signature.getInstance("RawRSA/PKCS1", iaikPkcs11KeyProvider.getName());
221 }
222 } else if (algorithmName.equals("DSA")) {
223 signatureEngine = Signature.getInstance("RawDSA", iaikPkcs11KeyProvider.getName());
224 } else if ((algorithmName.equals("EC")) || (algorithmName.equals("ECDSA"))) {
225 signatureEngine = Signature.getInstance("RawECDSA", iaikPkcs11KeyProvider.getName());
226 } else {
227 throw new NoSuchAlgorithmException(
228 "Unable to calculate signature with signature algorithm: " + signatureAlgorithm);
229 }
230
231 } catch (NoSuchProviderException ex) {
232 throw new NoSuchAlgorithmException("The PKCS#11 provider has not been installed corerctly: " + ex);
233 }
234 signatureEngine.initSign(privateKey);
235 signatureEngine.update(dataToBeSigned);
236 signatureValue = signatureEngine.sign();
237 } else {
238 signatureValue = super.calculateSignatureFromHash(signatureAlgorithm, digestAlgorithm, privateKey, digest);
239 }
240
241 return signatureValue ;
242 }
243
244 /**
245 * Calculates the signature value for a CMS SignerInfo over the given signed
246 * attributes with the given algorithm using the supplied private key.
247 * <p>
248 * Each {@link iaik.cms.SignerInfo SignerInfo} included in a CMS SignedData
249 * object may calculate the signature value differently depending on the
250 * presence of signed attributes:
251 * <p>
252 * <ul>
253 * <li>If signed attributes are present the signature is calculated over
254 * the DER encoding of the signed attributes.
255 * <li>If signed attributes are NOT present, the signature is calculated
256 * over the content data itsself.
257 * </ul>
258 * This method is called by class {@link iaik.cms.SignerInfo SignerInfo} for
259 * calculating the signature when signed attributes are present.
260 * <p>
261 * When writing your own SecurityProvider and overriding
262 * this method, be aware that only the -- yet NOT hashed -- DER encoding of
263 * the signed attributes is supplied to this method. For that reason this
264 * method can be overriden for use with smartcards requiring to do the
265 * digest calculation theirselves: ensure that your {@link iaik.cms.SignerInfo
266 * SignerInfo} contains signed attributes and override this method in a way
267 * to pass the given DER encoding of the signed attributes to your smartcard
268 * for doing the signature (and digest) calculation.
269 * <p>
270 * Since this method requires to calculate the digest value over the DER encoded
271 * signed attributes as part of the signature calculation, it uses a
272 * ordinary JCA Signature engine.
273 *
274 * @param signatureAlgorithm signatureAlgorithm the signature algorithm to be
275 * used, e.g. rsaEncryption, DSA
276 * @param digestAlgorithm the digest algorithm to be used for hash computation (e.g.
277 * SHA-1,..., SHA-512); may be necessary for some signature schemes (e.g.
278 * to be included as a DigestInfo in a PKCS#1 RSA signature)
279 * @param privateKey the private key of the signer (i.e. the one supplied when
280 * creating a {@link iaik.cms.SignerInfo SignerInfo} object; may be
281 * some kind of "dummy" key when used for smartcards
282 * @param signedAttributes the DER encoding of the signed attributes over which
283 * the signature shall be calculated
284 *
285 * @return the signature value calculated from the given DER encoded signed
286 * attributes
287 *
288 * @throws NoSuchAlgorithmException if no Signature engine is available for the requested algorithm
289 * @throws InvalidKeyException if the key is not valid
290 * @throws SignatureException if signature calculation fails
291 */
292 public byte[] calculateSignatureFromSignedAttributes(AlgorithmID signatureAlgorithm,
293 AlgorithmID digestAlgorithm, PrivateKey privateKey, byte[] signedAttributes)
294 throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
295
296 byte[] digest = getHash(digestAlgorithm, signedAttributes);
297 return calculateSignatureFromHash(signatureAlgorithm, digestAlgorithm, privateKey, digest);
298
299 }
300
301 /**
302 * This method returns the desired Signature object which uses the PKCS#11
303 * provider if the key is a PKCS#11 key.
304 *
305 * If the mode parameter is <CODE>SIGNATURE_SIGN</CODE> or
306 * <CODE>SIGNATURE_VERIFY</CODE> the signature object has to be
307 * initialized with the provided key in the respective mode.
308 *
309 * @param algorithm the name of the Signature algorithm
310 * @param mode the mode indicating if the engine has to be initialized
311 * @param key the key for initializing the Signature engine
312 *
313 * @return the (if requested initialized) Signature engine
314 *
315 * @throws InvalidKeyException if the key is not valid
316 * @throws NoSuchAlgorithmException if no Signature engine is
317 * available for the requested algorithm
318 */
319 public Signature getSignature(String algorithm, int mode, Key key)
320 throws InvalidKeyException, NoSuchAlgorithmException {
321
322 Signature signature;
323
324 // for PKCS#11 keys we use the PKCS#11 provider, for other keys we use the default implementation
325 if (key instanceof IAIKPKCS11Key) {
326 try {
327 signature = Signature.getInstance(algorithm, iaikPkcs11Provider_.getName());
328 } catch (NoSuchProviderException e) {
329 throw new NoSuchAlgorithmException("PKCS#11 Provider has not been installed correctly " + e.toString());
330 }
331 if (mode == SIGNATURE_SIGN) {
332 signature.initSign((PrivateKey)key);
333 } else if (mode == SIGNATURE_VERIFY) {
334 signature.initVerify((PublicKey)key);
335 } // do nothing for SIGNATURE_NONE
336 } else {
337 signature = super.getSignature(algorithm, mode, key);
338 }
339
340 return signature ;
341 }
342
343 /**
344 * This method returns the desired Signature object.
345 *
346 * If the mode parameter is <CODE>SIGNATURE_SIGN</CODE> or
347 * <CODE>SIGNATURE_VERIFY</CODE> the signature object is to be
348 * initialized with the provided key in the respective mode.
349 * If algorithm parameters are specified they are set for the
350 * Signature engine.
351 *
352 * @param algorithm the AlgorithmID of the Signature algorithm
353 * @param mode the mode indicating if the engine has to be initialized
354 * @param key the key for initializing the Signature engine
355 * @param paramSpec any parameters to be set for the Signature engine, if not <code>null</code>
356 *
357 * @return the (if requested initialized) Signature engine
358 *
359 * @throws InvalidKeyException if the key is not valid
360 * @throws NoSuchAlgorithmException if no Signature engine is
361 * available for the requested algorithm
362 */
363 public Signature getSignature(AlgorithmID algorithm,
364 int mode,
365 Key key,
366 AlgorithmParameterSpec paramSpec)
367 throws InvalidKeyException, NoSuchAlgorithmException {
368
369 Signature signature;
370
371 // for PKCS#11 keys we use the PKCS#11 provider, for other keys we use the default implementation
372 if (key instanceof IAIKPKCS11Key) {
373
374 signature = algorithm.getSignatureInstance(iaikPkcs11Provider_.getName());
375
376 if (mode == SIGNATURE_SIGN) {
377 signature.initSign((PrivateKey)key);
378 } else if (mode == SIGNATURE_VERIFY) {
379 signature.initVerify((PublicKey)key);
380 } // do nothing for SIGNATURE_NONE
381 } else {
382 signature = super.getSignature(algorithm, mode, key, paramSpec);
383 }
384 if (paramSpec != null) {
385 setSignatureParameters(signature, paramSpec);
386 }
387 return signature ;
388
389 }
390
391 /**
392 * Calculates RSA-PSS parameters for the given digest algorithm
393 *
394 * @param digestAlgorithm the digest algorithm
395 * @param signatureAlgorithm the signature algorithm
396 *
397 * @return the generated parameters
398 *
399 * @throws NoSuchAlgorithmException if no parameters for the given digest algorithms are available
400 */
401 private static PKCS11SignatureParameterSpec generateRSAPssParameters(
402 AlgorithmID digestAlgorithm, AlgorithmID signatureAlgorithm)
403 throws NoSuchAlgorithmException {
404
405
406 Mechanism hashAlgorithm;
407 long messageGenerationFunctionType;
408 int saltLength;
409 if (digestAlgorithm.equals(AlgorithmID.sha1)) {
410 hashAlgorithm = Mechanism.get(PKCS11Constants.CKM_SHA_1);
411 messageGenerationFunctionType = RSAPkcsParameters.MessageGenerationFunctionType.SHA1;
412 saltLength = 20;
413 } else if (digestAlgorithm.equals(AlgorithmID.sha256)) {
414 hashAlgorithm = Mechanism.get(PKCS11Constants.CKM_SHA256);
415 messageGenerationFunctionType = RSAPkcsParameters.MessageGenerationFunctionType.SHA256;
416 saltLength = 32;
417 } else if (digestAlgorithm.equals(AlgorithmID.sha384)) {
418 hashAlgorithm = Mechanism.get(PKCS11Constants.CKM_SHA384);
419 messageGenerationFunctionType = RSAPkcsParameters.MessageGenerationFunctionType.SHA384;
420 saltLength = 48;
421 } else if (digestAlgorithm.equals(AlgorithmID.sha512)) {
422 hashAlgorithm = Mechanism.get(PKCS11Constants.CKM_SHA512);
423 messageGenerationFunctionType = RSAPkcsParameters.MessageGenerationFunctionType.SHA512;
424 saltLength = 64;
425 } else {
426 throw new NoSuchAlgorithmException(
427 "Cannot create RSA-PSS parameters for " + digestAlgorithm.getName()
428 + " digest algorithm!");
429 }
430 RSAPkcsPssParameters parameters = new RSAPkcsPssParameters(
431 hashAlgorithm, messageGenerationFunctionType, saltLength);
432 PKCS11SignatureParameterSpec params = new PKCS11SignatureParameterSpec(
433 parameters);
434
435 // set signature algorithm parameters
436 AlgorithmID mgf1 = (AlgorithmID)AlgorithmID.mgf1.clone();
437 mgf1.setParameter(digestAlgorithm.toASN1Object());
438 RSAPssParameterSpec pssParamSpec = new RSAPssParameterSpec(digestAlgorithm,
439 mgf1, saltLength);
440 try {
441 signatureAlgorithm.setAlgorithmParameterSpec(pssParamSpec);
442 } catch (InvalidAlgorithmParameterException e) {
443 throw new NoSuchAlgorithmException(e.toString());
444 }
445 return params;
446 }
447
448 /**
449 * Decrypts the given encrypted content encryption key for a {@link
450 * iaik.cms.KeyTransRecipientInfo KeyTransRecipientInfo}.
451 * <p>
452 * CMS <code>EnvelopedData</code> uses the {@link
453 * iaik.cms.KeyTransRecipientInfo KeyTransRecipientInfo} type for
454 * encrypting the secret content encryption key with the public key of
455 * the recipient. Currently in general RSA PKCS#1v1.5 is used for key
456 * transport. If rsaEncryption is requested as key encryption algorithm
457 * this method uses a RSA Cipher ("RSA/ECB/PKCS1Padding/Encrypt") for
458 * decrypting the encrypted content encryption key with the supplied
459 * private key of the recipient. If another algorithm than RSA is requested,
460 * this method throws a NoSuchAlgorithmException. An application wishing to
461 * support another algorithm may override this method.
462 *
463 * @param encryptedKey the encrypted content encryption key to be decrypted
464 * @param kea the key encryption alglorithm to be used, e.g. rsaEncryption
465 * @param recipientKey the private key of the recipient to be used for decrypting
466 * the encrypted content encryption key
467 * @param cekAlgorithmName the name of the content encryption key (e.g. "DES") to be set for the
468 * SecretKey object created by this method
469 *
470 * @return the decrypted content encryption key
471 *
472 * @throws NoSuchAlgorithmException if the requested algorithm is not available
473 * @throws InvalidKeyException if the decryption key is not valid
474 * @throws NoSuchPaddingException if the required padding scheme is not supported
475 * @throws BadPaddingException if an padding error occurs
476 */
477 public SecretKey decryptKey(byte[] encryptedKey, AlgorithmID kea, PrivateKey recipientKey, String cekAlgorithmName)
478 throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, BadPaddingException
479 {
480 SecretKey decryptedSymmetricKey;
481
482 // we handle PKCS#11 keys in a special way, but we forward other keys to the default implementation
483 if (recipientKey instanceof IAIKPKCS11PrivateKey) {
484 IAIKPkcs11 iaikPkcs11KeyProvider = ((IAIKPKCS11PrivateKey) recipientKey).getTokenManager().getProvider();
485 String algorithmImplementationName = kea.getImplementationName();
486
487 try {
488 Cipher cipher = Cipher.getInstance(algorithmImplementationName, iaikPkcs11KeyProvider.getName());
489 cipher.init(Cipher.DECRYPT_MODE, recipientKey, (AlgorithmParameterSpec) null, (SecureRandom) null);
490 byte[] cek = cipher.doFinal(encryptedKey);
491 decryptedSymmetricKey = new iaik.security.cipher.SecretKey(cek, cekAlgorithmName);
492
493 } catch (NoSuchProviderException ex) {
494 throw new NoSuchAlgorithmException("The PKCS#11 provider has not been installed corerctly: " + ex);
495 } catch (InvalidAlgorithmParameterException ex) {
496 throw new NoSuchAlgorithmException("Error initializing the cipher: " + ex);
497 } catch (IllegalBlockSizeException ex) {
498 throw new NoSuchAlgorithmException("Error during cipher operation: " + ex);
499 }
500 } else {
501 decryptedSymmetricKey = super.decryptKey(encryptedKey, kea, recipientKey, cekAlgorithmName);
502 }
503
504 return decryptedSymmetricKey ;
505 }
506
507 /**
508 * Decrypts the given encrypted content encryption key for a {@link
509 * iaik.cms.KeyTransRecipientInfo KeyTransRecipientInfo}.
510 * <p>
511 * CMS <code>EnvelopedData</code> uses the {@link
512 * iaik.cms.KeyTransRecipientInfo KeyTransRecipientInfo} type for
513 * encrypting the secret content encryption key with the public key of
514 * the recipient. Currently in general RSA PKCS#1v1.5 is used for key
515 * transport. If rsaEncryption is requested as key encryption algorithm
516 * this method uses a RSA Cipher ("RSA/ECB/PKCS1Padding/Encrypt") for
517 * decrypting the encrypted content encryption key with the supplied
518 * private key of the recipient. If another algorithm than RSA is requested,
519 * this method throws a NoSuchAlgorithmException. An application wishing to
520 * support another algorithm may override this method.
521 *
522 * @param encryptedKey the encrypted content encryption key to be decrypted
523 * @param kea the key encryption alglorithm to be used, e.g. rsaEncryption
524 * @param recipientKey the private key of the recipient to be used for decrypting
525 * the encrypted content encryption key
526 *
527 * @return the decrypted content encryption key, the algorithm name will be set to "RAW"
528 *
529 * @throws NoSuchAlgorithmException if the requested algorithm is not available
530 * @throws InvalidKeyException if the decryption key is not valid
531 * @throws NoSuchPaddingException if the required padding scheme is not supported
532 * @throws BadPaddingException if an padding error occurs
533 */
534 // only needed for old CMS versions
535 // public SecretKey decryptKey(byte[] encryptedKey, AlgorithmID kea, PrivateKey recipientKey)
536 // throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, BadPaddingException
537 // {
538 // return decryptKey(encryptedKey, kea, recipientKey, "RAW");
539 // }
540
541 }