<commit_before>package org.bouncycastle.cms;

import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.BERConstructedOctetString;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERObjectIdentifier;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.cms.AttributeTable;
import org.bouncycastle.asn1.cms.CMSAttributes;
import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
import org.bouncycastle.asn1.cms.ContentInfo;
import org.bouncycastle.asn1.cms.SignedData;
import org.bouncycastle.asn1.cms.SignerIdentifier;
import org.bouncycastle.asn1.cms.SignerInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
import java.security.Provider;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * general class for generating a pkcs7-signature message.
 * <p>
 * A simple example of usage.
 *
 * <pre>
 *      CertStore               certs...
 *      CMSSignedDataGenerator    gen = new CMSSignedDataGenerator();
 *
 *      gen.addSigner(privKey, cert, CMSSignedGenerator.DIGEST_SHA1);
 *      gen.addCertificatesAndCRLs(certs);
 *
 *      CMSSignedData           data = gen.generate(content, "BC");
 * </pre>
 */
public class CMSSignedDataGenerator
    extends CMSSignedGenerator
{
    List                        signerInfs = new ArrayList();

    private class SignerInf
    {
        private final PrivateKey                  key;
        private final SignerIdentifier            signerIdentifier;
        private final String                      digestOID;
        private final String                      encOID;
        private final CMSAttributeTableGenerator  sAttr;
        private final CMSAttributeTableGenerator  unsAttr;
        private final AttributeTable              baseSignedTable;

        SignerInf(
            PrivateKey                 key,
            SignerIdentifier           signerIdentifier,
            String                     digestOID,
            String                     encOID,
            CMSAttributeTableGenerator sAttr,
            CMSAttributeTableGenerator unsAttr,
            AttributeTable             baseSignedTable)
        {
            this.key = key;
            this.signerIdentifier = signerIdentifier;
            this.digestOID = digestOID;
            this.encOID = encOID;
            this.sAttr = sAttr;
            this.unsAttr = unsAttr;
            this.baseSignedTable = baseSignedTable;
        }

        AlgorithmIdentifier getDigestAlgorithmID()
        {
            return new AlgorithmIdentifier(new DERObjectIdentifier(digestOID), new DERNull());
        }

        SignerInfo toSignerInfo(
            DERObjectIdentifier contentType,
            CMSProcessable      content,
            SecureRandom        random,
            Provider            sigProvider,
            boolean             addDefaultAttributes,
            boolean             isCounterSignature)
            throws IOException, SignatureException, InvalidKeyException, NoSuchAlgorithmException, CertificateEncodingException, CMSException
        {
            AlgorithmIdentifier digAlgId = getDigestAlgorithmID();
            String              digestName = CMSSignedHelper.INSTANCE.getDigestAlgName(digestOID);
            String              signatureName = digestName + "with" + CMSSignedHelper.INSTANCE.getEncryptionAlgName(encOID);
            Signature           sig = CMSSignedHelper.INSTANCE.getSignatureInstance(signatureName, sigProvider);
            MessageDigest       dig = CMSSignedHelper.INSTANCE.getDigestInstance(digestName, sigProvider);               
            AlgorithmIdentifier encAlgId = getEncAlgorithmIdentifier(encOID, sig);

            byte[]      hash = null;

            if (content != null)
            {
                content.write(new DigOutputStream(dig));

                hash = dig.digest();

                _digests.put(digestOID, hash.clone());
            }

            ASN1Set signedAttr = null;
            byte[] tmp;
            if (sAttr != null)
            {
                AttributeTable signed;
                if (addDefaultAttributes)
                {
                    Map parameters = getBaseParameters(contentType, digAlgId, hash);
                    signed = sAttr.getAttributes(Collections.unmodifiableMap(parameters));
                }
                else
                {
                    signed = baseSignedTable;
                }

                if (isCounterSignature)
                {
                    Hashtable ats = signed.toHashtable();

                    ats.remove(CMSAttributes.contentType);

                    signed = new AttributeTable(ats);
                }

                signedAttr = getAttributeSet(signed);

                // sig must be composed from the DER encoding.
                tmp = signedAttr.getEncoded(ASN1Encodable.DER);
            }
            else
            {
                ByteArrayOutputStream bOut = new ByteArrayOutputStream();
                content.write(bOut);
                tmp = bOut.toByteArray();
            }

            sig.initSign(key, random);
            sig.update(tmp);
            byte[] sigBytes = sig.sign();

            ASN1Set unsignedAttr = null;
            if (unsAttr != null)
            {
                Map parameters = getBaseParameters(contentType, digAlgId, hash);
                parameters.put(CMSAttributeTableGenerator.SIGNATURE, sigBytes.clone());

                AttributeTable unsigned = unsAttr.getAttributes(Collections.unmodifiableMap(parameters));

                unsignedAttr = getAttributeSet(unsigned);
            }

            return new SignerInfo(signerIdentifier, digAlgId,
                signedAttr, encAlgId, new DEROctetString(sigBytes), unsignedAttr);
        }
    }
    <commit_msg>rolled back refactoring of attribute processing - fails no attribute test<commit_after>package org.bouncycastle.cms;

import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.BERConstructedOctetString;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERObjectIdentifier;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.cms.AttributeTable;
import org.bouncycastle.asn1.cms.CMSAttributes;
import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
import org.bouncycastle.asn1.cms.ContentInfo;
import org.bouncycastle.asn1.cms.SignedData;
import org.bouncycastle.asn1.cms.SignerIdentifier;
import org.bouncycastle.asn1.cms.SignerInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
import java.security.Provider;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * general class for generating a pkcs7-signature message.
 * <p>
 * A simple example of usage.
 *
 * <pre>
 *      CertStore               certs...
 *      CMSSignedDataGenerator    gen = new CMSSignedDataGenerator();
 *
 *      gen.addSigner(privKey, cert, CMSSignedGenerator.DIGEST_SHA1);
 *      gen.addCertificatesAndCRLs(certs);
 *
 *      CMSSignedData           data = gen.generate(content, "BC");
 * </pre>
 */
public class CMSSignedDataGenerator
    extends CMSSignedGenerator
{
    List                        signerInfs = new ArrayList();

    private class SignerInf
    {
        private final PrivateKey                  key;
        private final SignerIdentifier            signerIdentifier;
        private final String                      digestOID;
        private final String                      encOID;
        private final CMSAttributeTableGenerator  sAttr;
        private final CMSAttributeTableGenerator  unsAttr;
        private final AttributeTable              baseSignedTable;

        SignerInf(
            PrivateKey                 key,
            SignerIdentifier           signerIdentifier,
            String                     digestOID,
            String                     encOID,
            CMSAttributeTableGenerator sAttr,
            CMSAttributeTableGenerator unsAttr,
            AttributeTable             baseSignedTable)
        {
            this.key = key;
            this.signerIdentifier = signerIdentifier;
            this.digestOID = digestOID;
            this.encOID = encOID;
            this.sAttr = sAttr;
            this.unsAttr = unsAttr;
            this.baseSignedTable = baseSignedTable;
        }

        AlgorithmIdentifier getDigestAlgorithmID()
        {
            return new AlgorithmIdentifier(new DERObjectIdentifier(digestOID), new DERNull());
        }

        SignerInfo toSignerInfo(
            DERObjectIdentifier contentType,
            CMSProcessable      content,
            SecureRandom        random,
            Provider            sigProvider,
            boolean             addDefaultAttributes,
            boolean             isCounterSignature)
            throws IOException, SignatureException, InvalidKeyException, NoSuchAlgorithmException, CertificateEncodingException, CMSException
        {
            AlgorithmIdentifier digAlgId = getDigestAlgorithmID();
            String              digestName = CMSSignedHelper.INSTANCE.getDigestAlgName(digestOID);
            String              signatureName = digestName + "with" + CMSSignedHelper.INSTANCE.getEncryptionAlgName(encOID);
            Signature           sig = CMSSignedHelper.INSTANCE.getSignatureInstance(signatureName, sigProvider);
            MessageDigest       dig = CMSSignedHelper.INSTANCE.getDigestInstance(digestName, sigProvider);               
            AlgorithmIdentifier encAlgId = getEncAlgorithmIdentifier(encOID, sig);

            byte[]      hash = null;

            if (content != null)
            {
                content.write(new DigOutputStream(dig));

                hash = dig.digest();

                _digests.put(digestOID, hash.clone());
            }

            AttributeTable signed;

            if (addDefaultAttributes)
            {
                Map parameters = getBaseParameters(contentType, digAlgId, hash);
                signed = (sAttr != null) ? sAttr.getAttributes(Collections.unmodifiableMap(parameters)) : null;
            }
            else
            {
                signed = baseSignedTable;
            }

            if (isCounterSignature)
            {
                Hashtable ats = signed.toHashtable();

                ats.remove(CMSAttributes.contentType);

                signed = new AttributeTable(ats);
            }

            ASN1Set signedAttr = getAttributeSet(signed);

            //
            // sig must be composed from the DER encoding.
            //
            byte[] tmp;
            if (signedAttr != null)
            {
                tmp = signedAttr.getEncoded(ASN1Encodable.DER);
            }
            else
            {
                ByteArrayOutputStream bOut = new ByteArrayOutputStream();
                content.write(bOut);
                tmp = bOut.toByteArray();
            }

            sig.initSign(key, random);
            sig.update(tmp);
            byte[] sigBytes = sig.sign();

            ASN1Set unsignedAttr = null;
            if (unsAttr != null)
            {
                Map parameters = getBaseParameters(contentType, digAlgId, hash);
                parameters.put(CMSAttributeTableGenerator.SIGNATURE, sigBytes.clone());

                AttributeTable unsigned = unsAttr.getAttributes(Collections.unmodifiableMap(parameters));

                unsignedAttr = getAttributeSet(unsigned);
            }

            return new SignerInfo(signerIdentifier, digAlgId,
                signedAttr, encAlgId, new DEROctetString(sigBytes), unsignedAttr);
        }
    }
    
{'fraction_non_alphanumeric': 0.07301659814222629, 'fraction_numerical': 0.004872849093954621, 'mean_word_length': 2.060344827586207, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2975872', 'n_tokens_mistral': 3517, 'n_tokens_neox': 3323, 'n_words': 650}