org.spongycastle.cert.crmf.EncryptedValueBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pkix Show documentation
Show all versions of pkix Show documentation
Spongy Castle is a package-rename (org.bouncycastle.* to org.spongycastle.*) of Bouncy Castle
intended for the Android platform. Android unfortunately ships with a stripped-down version of
Bouncy Castle, which prevents easy upgrades - Spongy Castle overcomes this and provides a full,
up-to-date version of the Bouncy Castle cryptographic libs.
package org.spongycastle.cert.crmf;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.spongycastle.asn1.ASN1OctetString;
import org.spongycastle.asn1.DERBitString;
import org.spongycastle.asn1.crmf.EncryptedValue;
import org.spongycastle.asn1.x509.AlgorithmIdentifier;
import org.spongycastle.cert.X509CertificateHolder;
import org.spongycastle.operator.KeyWrapper;
import org.spongycastle.operator.OperatorException;
import org.spongycastle.operator.OutputEncryptor;
import org.spongycastle.util.Strings;
/**
* Builder for EncryptedValue structures.
*/
public class EncryptedValueBuilder
{
private KeyWrapper wrapper;
private OutputEncryptor encryptor;
private EncryptedValuePadder padder;
/**
* Create a builder that makes EncryptedValue structures.
*
* @param wrapper a wrapper for key used to encrypt the actual data contained in the EncryptedValue.
* @param encryptor an output encryptor to encrypt the actual data contained in the EncryptedValue.
*/
public EncryptedValueBuilder(KeyWrapper wrapper, OutputEncryptor encryptor)
{
this(wrapper, encryptor, null);
}
/**
* Create a builder that makes EncryptedValue structures with fixed length blocks padded using the passed in padder.
*
* @param wrapper a wrapper for key used to encrypt the actual data contained in the EncryptedValue.
* @param encryptor an output encryptor to encrypt the actual data contained in the EncryptedValue.
* @param padder a padder to ensure that the EncryptedValue created will always be a constant length.
*/
public EncryptedValueBuilder(KeyWrapper wrapper, OutputEncryptor encryptor, EncryptedValuePadder padder)
{
this.wrapper = wrapper;
this.encryptor = encryptor;
this.padder = padder;
}
/**
* Build an EncryptedValue structure containing the passed in pass phrase.
*
* @param revocationPassphrase a revocation pass phrase.
* @return an EncryptedValue containing the encrypted pass phrase.
* @throws CRMFException on a failure to encrypt the data, or wrap the symmetric key for this value.
*/
public EncryptedValue build(char[] revocationPassphrase)
throws CRMFException
{
return encryptData(padData(Strings.toUTF8ByteArray(revocationPassphrase)));
}
/**
* Build an EncryptedValue structure containing the certificate contained in
* the passed in holder.
*
* @param holder a holder containing a certificate.
* @return an EncryptedValue containing the encrypted certificate.
* @throws CRMFException on a failure to encrypt the data, or wrap the symmetric key for this value.
*/
public EncryptedValue build(X509CertificateHolder holder)
throws CRMFException
{
try
{
return encryptData(padData(holder.getEncoded()));
}
catch (IOException e)
{
throw new CRMFException("cannot encode certificate: " + e.getMessage(), e);
}
}
private EncryptedValue encryptData(byte[] data)
throws CRMFException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
OutputStream eOut = encryptor.getOutputStream(bOut);
try
{
eOut.write(data);
eOut.close();
}
catch (IOException e)
{
throw new CRMFException("cannot process data: " + e.getMessage(), e);
}
AlgorithmIdentifier intendedAlg = null;
AlgorithmIdentifier symmAlg = encryptor.getAlgorithmIdentifier();
DERBitString encSymmKey;
try
{
wrapper.generateWrappedKey(encryptor.getKey());
encSymmKey = new DERBitString(wrapper.generateWrappedKey(encryptor.getKey()));
}
catch (OperatorException e)
{
throw new CRMFException("cannot wrap key: " + e.getMessage(), e);
}
AlgorithmIdentifier keyAlg = wrapper.getAlgorithmIdentifier();
ASN1OctetString valueHint = null;
DERBitString encValue = new DERBitString(bOut.toByteArray());
return new EncryptedValue(intendedAlg, symmAlg, encSymmKey, keyAlg, valueHint, encValue);
}
private byte[] padData(byte[] data)
{
if (padder != null)
{
return padder.getPaddedData(data);
}
return data;
}
}