org.bouncycastle.cms.RecipientInformation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bcmail Show documentation
Show all versions of bcmail Show documentation
A patched bouncycastle-mail
The newest version!
package org.bouncycastle.cms;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import org.bouncycastle.asn1.DEREncodable;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.util.io.Streams;
public abstract class RecipientInformation
{
protected RecipientId rid;
protected AlgorithmIdentifier keyEncAlg;
protected AlgorithmIdentifier messageAlgorithm;
private CMSSecureReadable secureReadable;
private AuthAttributesProvider additionalData;
private byte[] resultMac;
private RecipientOperator operator;
RecipientInformation(
AlgorithmIdentifier keyEncAlg,
AlgorithmIdentifier messageAlgorithm,
CMSSecureReadable secureReadable,
AuthAttributesProvider additionalData)
{
this.keyEncAlg = keyEncAlg;
this.messageAlgorithm = messageAlgorithm;
this.secureReadable = secureReadable;
this.additionalData = additionalData;
}
String getContentAlgorithmName()
{
AlgorithmIdentifier algorithm = secureReadable.getAlgorithm();
return CMSEnvelopedHelper.INSTANCE.getSymmetricCipherName(algorithm.getObjectId().getId());
}
public RecipientId getRID()
{
return rid;
}
private byte[] encodeObj(
DEREncodable obj)
throws IOException
{
if (obj != null)
{
return obj.getDERObject().getEncoded();
}
return null;
}
/**
* return the object identifier for the key encryption algorithm.
*
* @return OID for key encryption algorithm.
*/
public String getKeyEncryptionAlgOID()
{
return keyEncAlg.getObjectId().getId();
}
/**
* return the ASN.1 encoded key encryption algorithm parameters, or null if
* there aren't any.
*
* @return ASN.1 encoding of key encryption algorithm parameters.
*/
public byte[] getKeyEncryptionAlgParams()
{
try
{
return encodeObj(keyEncAlg.getParameters());
}
catch (Exception e)
{
throw new RuntimeException("exception getting encryption parameters " + e);
}
}
/**
* Return an AlgorithmParameters object giving the encryption parameters
* used to encrypt the key this recipient holds.
*
* @param provider the provider to generate the parameters for.
* @return the parameters object, null if there is not one.
* @throws CMSException if the algorithm cannot be found, or the parameters can't be parsed.
* @throws NoSuchProviderException if the provider cannot be found.
*/
public AlgorithmParameters getKeyEncryptionAlgorithmParameters(
String provider)
throws CMSException, NoSuchProviderException
{
return getKeyEncryptionAlgorithmParameters(CMSUtils.getProvider(provider));
}
/**
* Return an AlgorithmParameters object giving the encryption parameters
* used to encrypt the key this recipient holds.
*
* @param provider the provider to generate the parameters for.
* @return the parameters object, null if there is not one.
* @throws CMSException if the algorithm cannot be found, or the parameters can't be parsed.
*/
public AlgorithmParameters getKeyEncryptionAlgorithmParameters(
Provider provider)
throws CMSException
{
try
{
byte[] enc = this.encodeObj(keyEncAlg.getParameters());
if (enc == null)
{
return null;
}
AlgorithmParameters params = CMSEnvelopedHelper.INSTANCE.createAlgorithmParameters(getKeyEncryptionAlgOID(), provider);
params.init(enc, "ASN.1");
return params;
}
catch (NoSuchAlgorithmException e)
{
throw new CMSException("can't find parameters for algorithm", e);
}
catch (IOException e)
{
throw new CMSException("can't find parse parameters", e);
}
}
protected CMSTypedStream getContentFromSessionKey(
Key sKey,
Provider provider)
throws CMSException
{
CMSReadable readable = secureReadable.getReadable((SecretKey)sKey, provider);
try
{
return new CMSTypedStream(readable.getInputStream());
}
catch (IOException e)
{
throw new CMSException("error getting .", e);
}
}
/**
* @deprecated use getContent(Recipient)
*/
public byte[] getContent(
Key key,
String provider)
throws CMSException, NoSuchProviderException
{
return getContent(key, CMSUtils.getProvider(provider));
}
/**
* @deprecated use getContent(Recipient)
*/
public byte[] getContent(
Key key,
Provider provider)
throws CMSException
{
try
{
return CMSUtils.streamToByteArray(getContentStream(key, provider).getContentStream());
}
catch (IOException e)
{
throw new RuntimeException("unable to parse internal stream: " + e);
}
}
/**
* Return the content digest calculated during the read of the content if one has been generated. This will
* only happen if we are dealing with authenticated data and authenticated attributes are present.
*
* @return byte array containing the digest.
*/
public byte[] getContentDigest()
{
if (secureReadable instanceof CMSEnvelopedHelper.CMSDigestAuthenticatedSecureReadable)
{
return ((CMSEnvelopedHelper.CMSDigestAuthenticatedSecureReadable)secureReadable).getDigest();
}
return null;
}
/**
* Return the MAC calculated for the recipient. Note: this call is only meaningful once all
* the content has been read.
*
* @return byte array containing the mac.
*/
public byte[] getMac()
{
if (resultMac == null)
{
if (operator != null)
{
if (operator.isMacBased())
{
if (additionalData != null)
{
try
{
Streams.drain(operator.getInputStream(new ByteArrayInputStream(additionalData.getAuthAttributes().getDEREncoded())));
}
catch (IOException e)
{
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
resultMac = operator.getMac();
}
}
else
{
Object cryptoObject = secureReadable.getCryptoObject();
if (cryptoObject instanceof Mac)
{
resultMac = ((Mac)cryptoObject).doFinal();
}
}
}
return resultMac;
}
/**
* Return the decrypted/encapsulated content in the EnvelopedData after recovering the content
* encryption/MAC key using the passed in Recipient.
*
* @param recipient recipient object to use to recover content encryption key
* @return the content inside the EnvelopedData this RecipientInformation is associated with.
* @throws CMSException if the content-encryption/MAC key cannot be recovered.
*/
public byte[] getContent(
Recipient recipient)
throws CMSException
{
try
{
return CMSUtils.streamToByteArray(getContentStream(recipient).getContentStream());
}
catch (IOException e)
{
throw new CMSException("unable to parse internal stream: " + e.getMessage(), e);
}
}
/**
* decrypt the content and return it
* @deprecated use getContentStream(Recipient) method
*/
public CMSTypedStream getContentStream(Key key, String provider)
throws CMSException, NoSuchProviderException
{
return getContentStream(key, CMSUtils.getProvider(provider));
}
/**
* decrypt the content and return it
* @deprecated use getContentStream(Recipient) method
*/
public abstract CMSTypedStream getContentStream(Key key, Provider provider)
throws CMSException;
/**
* Return a CMSTypedStream representing the content in the EnvelopedData after recovering the content
* encryption/MAC key using the passed in Recipient.
*
* @param recipient recipient object to use to recover content encryption key
* @return the content inside the EnvelopedData this RecipientInformation is associated with.
* @throws CMSException if the content-encryption/MAC key cannot be recovered.
*/
public CMSTypedStream getContentStream(Recipient recipient)
throws CMSException, IOException
{
operator = getRecipientOperator(recipient);
if (additionalData != null)
{
return new CMSTypedStream(secureReadable.getInputStream());
}
return new CMSTypedStream(operator.getInputStream(secureReadable.getInputStream()));
}
protected abstract RecipientOperator getRecipientOperator(Recipient recipient)
throws CMSException, IOException;
}