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 }