org.bouncycastle.cms.KeyTransIntRecipientInfoGenerator 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.IOException;
import java.security.GeneralSecurityException;
import java.security.Provider;
import java.security.ProviderException;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
import org.bouncycastle.asn1.cms.KeyTransRecipientInfo;
import org.bouncycastle.asn1.cms.RecipientIdentifier;
import org.bouncycastle.asn1.cms.RecipientInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.TBSCertificateStructure;
class KeyTransIntRecipientInfoGenerator
implements IntRecipientInfoGenerator
{
// TODO Pass recipId, keyEncAlg instead?
private TBSCertificateStructure recipientTBSCert;
private PublicKey recipientPublicKey;
private ASN1OctetString subjectKeyIdentifier;
// Derived fields
private SubjectPublicKeyInfo info;
KeyTransIntRecipientInfoGenerator()
{
}
void setRecipientCert(X509Certificate recipientCert)
{
this.recipientTBSCert = CMSUtils.getTBSCertificateStructure(recipientCert);
this.recipientPublicKey = recipientCert.getPublicKey();
this.info = recipientTBSCert.getSubjectPublicKeyInfo();
}
void setRecipientPublicKey(PublicKey recipientPublicKey)
{
this.recipientPublicKey = recipientPublicKey;
try
{
info = SubjectPublicKeyInfo.getInstance(
ASN1Object.fromByteArray(recipientPublicKey.getEncoded()));
}
catch (IOException e)
{
throw new IllegalArgumentException(
"can't extract key algorithm from this key");
}
}
void setSubjectKeyIdentifier(ASN1OctetString subjectKeyIdentifier)
{
this.subjectKeyIdentifier = subjectKeyIdentifier;
}
public RecipientInfo generate(SecretKey contentEncryptionKey, SecureRandom random,
Provider prov) throws GeneralSecurityException
{
AlgorithmIdentifier keyEncryptionAlgorithm = info.getAlgorithmId();
byte[] encryptedKeyBytes = null;
Cipher keyEncryptionCipher = CMSEnvelopedHelper.INSTANCE.createAsymmetricCipher(
keyEncryptionAlgorithm.getObjectId().getId(), prov);
try
{
keyEncryptionCipher.init(Cipher.WRAP_MODE, recipientPublicKey, random);
encryptedKeyBytes = keyEncryptionCipher.wrap(contentEncryptionKey);
}
catch (GeneralSecurityException e)
{
}
catch (IllegalStateException e)
{
}
catch (UnsupportedOperationException e)
{
}
catch (ProviderException e)
{
}
// some providers do not support WRAP (this appears to be only for asymmetric algorithms)
if (encryptedKeyBytes == null)
{
keyEncryptionCipher.init(Cipher.ENCRYPT_MODE, recipientPublicKey, random);
encryptedKeyBytes = keyEncryptionCipher.doFinal(contentEncryptionKey.getEncoded());
}
RecipientIdentifier recipId;
if (recipientTBSCert != null)
{
IssuerAndSerialNumber issuerAndSerial = new IssuerAndSerialNumber(
recipientTBSCert.getIssuer(), recipientTBSCert.getSerialNumber().getValue());
recipId = new RecipientIdentifier(issuerAndSerial);
}
else
{
recipId = new RecipientIdentifier(subjectKeyIdentifier);
}
return new RecipientInfo(new KeyTransRecipientInfo(recipId, keyEncryptionAlgorithm,
new DEROctetString(encryptedKeyBytes)));
}
}