package org.bouncycastle.cms.jcajce;

import java.io.OutputStream;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.Provider;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.operator.DefaultSecretKeySizeProvider;
import org.bouncycastle.operator.GenericKey;
import org.bouncycastle.operator.OutputEncryptor;
import org.bouncycastle.operator.SecretKeySizeProvider;
import org.bouncycastle.operator.jcajce.JceGenericKey;

Builder for the content encryptor in EnvelopedData - used to encrypt the actual transmitted content.
/** * Builder for the content encryptor in EnvelopedData - used to encrypt the actual transmitted content. */
public class JceCMSContentEncryptorBuilder { private static final SecretKeySizeProvider KEY_SIZE_PROVIDER = DefaultSecretKeySizeProvider.INSTANCE; private final ASN1ObjectIdentifier encryptionOID; private final int keySize; private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper()); private SecureRandom random; private AlgorithmParameters algorithmParameters; public JceCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID) { this(encryptionOID, KEY_SIZE_PROVIDER.getKeySize(encryptionOID)); } public JceCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID, int keySize) { this.encryptionOID = encryptionOID; int fixedSize = KEY_SIZE_PROVIDER.getKeySize(encryptionOID); if (encryptionOID.equals(PKCSObjectIdentifiers.des_EDE3_CBC)) { if (keySize != 168 && keySize != fixedSize) { throw new IllegalArgumentException("incorrect keySize for encryptionOID passed to builder."); } this.keySize = 168; } else if (encryptionOID.equals(OIWObjectIdentifiers.desCBC)) { if (keySize != 56 && keySize != fixedSize) { throw new IllegalArgumentException("incorrect keySize for encryptionOID passed to builder."); } this.keySize = 56; } else { if (fixedSize > 0 && fixedSize != keySize) { throw new IllegalArgumentException("incorrect keySize for encryptionOID passed to builder."); } this.keySize = keySize; } }
Set the provider to use for content encryption.
Params:
  • provider – the provider object to use for cipher and default parameters creation.
Returns:the current builder instance.
/** * Set the provider to use for content encryption. * * @param provider the provider object to use for cipher and default parameters creation. * @return the current builder instance. */
public JceCMSContentEncryptorBuilder setProvider(Provider provider) { this.helper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider)); return this; }
Set the provider to use for content encryption (by name)
Params:
  • providerName – the name of the provider to use for cipher and default parameters creation.
Returns:the current builder instance.
/** * Set the provider to use for content encryption (by name) * * @param providerName the name of the provider to use for cipher and default parameters creation. * @return the current builder instance. */
public JceCMSContentEncryptorBuilder setProvider(String providerName) { this.helper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName)); return this; }
Provide a specified source of randomness to be used for session key and IV/nonce generation.
Params:
  • random – the secure random to use.
Returns:the current builder instance.
/** * Provide a specified source of randomness to be used for session key and IV/nonce generation. * * @param random the secure random to use. * @return the current builder instance. */
public JceCMSContentEncryptorBuilder setSecureRandom(SecureRandom random) { this.random = random; return this; }
Provide a set of algorithm parameters for the content encryption cipher to use.
Params:
  • algorithmParameters – algorithmParameters for content encryption.
Returns:the current builder instance.
/** * Provide a set of algorithm parameters for the content encryption cipher to use. * * @param algorithmParameters algorithmParameters for content encryption. * @return the current builder instance. */
public JceCMSContentEncryptorBuilder setAlgorithmParameters(AlgorithmParameters algorithmParameters) { this.algorithmParameters = algorithmParameters; return this; } public OutputEncryptor build() throws CMSException { return new CMSOutputEncryptor(encryptionOID, keySize, algorithmParameters, random); } private class CMSOutputEncryptor implements OutputEncryptor { private SecretKey encKey; private AlgorithmIdentifier algorithmIdentifier; private Cipher cipher; CMSOutputEncryptor(ASN1ObjectIdentifier encryptionOID, int keySize, AlgorithmParameters params, SecureRandom random) throws CMSException { KeyGenerator keyGen = helper.createKeyGenerator(encryptionOID); if (random == null) { random = new SecureRandom(); } if (keySize < 0) { keyGen.init(random); } else { keyGen.init(keySize, random); } cipher = helper.createCipher(encryptionOID); encKey = keyGen.generateKey(); if (params == null) { params = helper.generateParameters(encryptionOID, encKey, random); } try { cipher.init(Cipher.ENCRYPT_MODE, encKey, params, random); } catch (GeneralSecurityException e) { throw new CMSException("unable to initialize cipher: " + e.getMessage(), e); } // // If params are null we try and second guess on them as some providers don't provide // algorithm parameter generation explicity but instead generate them under the hood. // if (params == null) { params = cipher.getParameters(); } algorithmIdentifier = helper.getAlgorithmIdentifier(encryptionOID, params); } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } public OutputStream getOutputStream(OutputStream dOut) { return new CipherOutputStream(dOut, cipher); } public GenericKey getKey() { return new JceGenericKey(algorithmIdentifier, encKey); } } }