org.bouncycastle.cms.CMSSignedGenerator Maven / Gradle / Ivy
Show all versions of bcmail Show documentation
package org.bouncycastle.cms;
import java.io.IOException;
import java.security.AlgorithmParameters;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.cert.CertStore;
import java.security.cert.CertStoreException;
import java.security.cert.X509Certificate;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.RSAPrivateKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERObjectIdentifier;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.cms.AttributeTable;
import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
import org.bouncycastle.asn1.cms.SignerIdentifier;
import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.AttributeCertificate;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.jce.interfaces.GOST3410PrivateKey;
import org.bouncycastle.util.Store;
import org.bouncycastle.x509.X509AttributeCertificate;
import org.bouncycastle.x509.X509Store;
public class CMSSignedGenerator
{
/**
* Default type for the signed data.
*/
public static final String DATA = CMSObjectIdentifiers.data.getId();
public static final String DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1.getId();
public static final String DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224.getId();
public static final String DIGEST_SHA256 = NISTObjectIdentifiers.id_sha256.getId();
public static final String DIGEST_SHA384 = NISTObjectIdentifiers.id_sha384.getId();
public static final String DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512.getId();
public static final String DIGEST_MD5 = PKCSObjectIdentifiers.md5.getId();
public static final String DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId();
public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId();
public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId();
public static final String DIGEST_RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256.getId();
public static final String ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption.getId();
public static final String ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1.getId();
public static final String ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1.getId();
public static final String ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS.getId();
public static final String ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94.getId();
public static final String ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001.getId();
private static final String ENCRYPTION_ECDSA_WITH_SHA1 = X9ObjectIdentifiers.ecdsa_with_SHA1.getId();
private static final String ENCRYPTION_ECDSA_WITH_SHA224 = X9ObjectIdentifiers.ecdsa_with_SHA224.getId();
private static final String ENCRYPTION_ECDSA_WITH_SHA256 = X9ObjectIdentifiers.ecdsa_with_SHA256.getId();
private static final String ENCRYPTION_ECDSA_WITH_SHA384 = X9ObjectIdentifiers.ecdsa_with_SHA384.getId();
private static final String ENCRYPTION_ECDSA_WITH_SHA512 = X9ObjectIdentifiers.ecdsa_with_SHA512.getId();
private static final Set NO_PARAMS = new HashSet();
private static final Map EC_ALGORITHMS = new HashMap();
static
{
NO_PARAMS.add(ENCRYPTION_DSA);
NO_PARAMS.add(ENCRYPTION_ECDSA);
NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA1);
NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA224);
NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA256);
NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA384);
NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA512);
EC_ALGORITHMS.put(DIGEST_SHA1, ENCRYPTION_ECDSA_WITH_SHA1);
EC_ALGORITHMS.put(DIGEST_SHA224, ENCRYPTION_ECDSA_WITH_SHA224);
EC_ALGORITHMS.put(DIGEST_SHA256, ENCRYPTION_ECDSA_WITH_SHA256);
EC_ALGORITHMS.put(DIGEST_SHA384, ENCRYPTION_ECDSA_WITH_SHA384);
EC_ALGORITHMS.put(DIGEST_SHA512, ENCRYPTION_ECDSA_WITH_SHA512);
}
protected List certs = new ArrayList();
protected List crls = new ArrayList();
protected List _signers = new ArrayList();
protected List signerGens = new ArrayList();
protected Map digests = new HashMap();
protected final SecureRandom rand;
/**
* base constructor
*/
protected CMSSignedGenerator()
{
this(new SecureRandom());
}
/**
* constructor allowing specific source of randomness
* @param rand instance of SecureRandom to use
*/
protected CMSSignedGenerator(
SecureRandom rand)
{
this.rand = rand;
}
protected String getEncOID(
PrivateKey key,
String digestOID)
{
String encOID = null;
if (key instanceof RSAPrivateKey || "RSA".equalsIgnoreCase(key.getAlgorithm()))
{
encOID = ENCRYPTION_RSA;
}
else if (key instanceof DSAPrivateKey || "DSA".equalsIgnoreCase(key.getAlgorithm()))
{
encOID = ENCRYPTION_DSA;
if (!digestOID.equals(DIGEST_SHA1))
{
throw new IllegalArgumentException("can't mix DSA with anything but SHA1");
}
}
else if ("ECDSA".equalsIgnoreCase(key.getAlgorithm()) || "EC".equalsIgnoreCase(key.getAlgorithm()))
{
encOID = (String)EC_ALGORITHMS.get(digestOID);
if (encOID == null)
{
throw new IllegalArgumentException("can't mix ECDSA with anything but SHA family digests");
}
}
else if (key instanceof GOST3410PrivateKey || "GOST3410".equalsIgnoreCase(key.getAlgorithm()))
{
encOID = ENCRYPTION_GOST3410;
}
else if ("ECGOST3410".equalsIgnoreCase(key.getAlgorithm()))
{
encOID = ENCRYPTION_ECGOST3410;
}
return encOID;
}
protected AlgorithmIdentifier getEncAlgorithmIdentifier(String encOid, Signature sig)
throws IOException
{
if (NO_PARAMS.contains(encOid))
{
return new AlgorithmIdentifier(
new DERObjectIdentifier(encOid));
}
else
{
if (encOid.equals(CMSSignedGenerator.ENCRYPTION_RSA_PSS))
{
AlgorithmParameters sigParams = sig.getParameters();
return new AlgorithmIdentifier(
new DERObjectIdentifier(encOid), ASN1Object.fromByteArray(sigParams.getEncoded()));
}
else
{
return new AlgorithmIdentifier(
new DERObjectIdentifier(encOid), new DERNull());
}
}
}
protected Map getBaseParameters(DERObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash)
{
Map param = new HashMap();
param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType);
param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId);
param.put(CMSAttributeTableGenerator.DIGEST, hash.clone());
return param;
}
protected ASN1Set getAttributeSet(
AttributeTable attr)
{
if (attr != null)
{
return new DERSet(attr.toASN1EncodableVector());
}
return null;
}
/**
* add the certificates and CRLs contained in the given CertStore
* to the pool that will be included in the encoded signature block.
*
* Note: this assumes the CertStore will support null in the get
* methods.
* @param certStore CertStore containing the public key certificates and CRLs
* @throws java.security.cert.CertStoreException if an issue occurs processing the CertStore
* @throws CMSException if an issue occurse transforming data from the CertStore into the message
* @deprecated use addCertificates and addCRLs
*/
public void addCertificatesAndCRLs(
CertStore certStore)
throws CertStoreException, CMSException
{
certs.addAll(CMSUtils.getCertificatesFromStore(certStore));
crls.addAll(CMSUtils.getCRLsFromStore(certStore));
}
public void addCertificates(
Store certStore)
throws CMSException
{
certs.addAll(CMSUtils.getCertificatesFromStore(certStore));
}
public void addCRLs(
Store crlStore)
throws CMSException
{
crls.addAll(CMSUtils.getCRLsFromStore(crlStore));
}
public void addAttributeCertificates(
Store attrStore)
throws CMSException
{
certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrStore));
}
/**
* Add the attribute certificates contained in the passed in store to the
* generator.
*
* @param store a store of Version 2 attribute certificates
* @throws CMSException if an error occurse processing the store.
* @deprecated use basic Store method
*/
public void addAttributeCertificates(
X509Store store)
throws CMSException
{
try
{
for (Iterator it = store.getMatches(null).iterator(); it.hasNext();)
{
X509AttributeCertificate attrCert = (X509AttributeCertificate)it.next();
certs.add(new DERTaggedObject(false, 2,
AttributeCertificate.getInstance(ASN1Object.fromByteArray(attrCert.getEncoded()))));
}
}
catch (IllegalArgumentException e)
{
throw new CMSException("error processing attribute certs", e);
}
catch (IOException e)
{
throw new CMSException("error processing attribute certs", e);
}
}
/**
* Add a store of precalculated signers to the generator.
*
* @param signerStore store of signers
*/
public void addSigners(
SignerInformationStore signerStore)
{
Iterator it = signerStore.getSigners().iterator();
while (it.hasNext())
{
_signers.add(it.next());
}
}
public void addSignerInfoGenerator(SignerInfoGenerator infoGen)
{
signerGens.add(infoGen);
}
/**
* Return a map of oids and byte arrays representing the digests calculated on the content during
* the last generate.
*
* @return a map of oids (as String objects) and byte[] representing digests.
*/
public Map getGeneratedDigests()
{
return new HashMap(digests);
}
static SignerIdentifier getSignerIdentifier(X509Certificate cert)
{
return new SignerIdentifier(CMSUtils.getIssuerAndSerialNumber(cert));
}
static SignerIdentifier getSignerIdentifier(byte[] subjectKeyIdentifier)
{
return new SignerIdentifier(new DEROctetString(subjectKeyIdentifier));
}
}