1e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrompackage org.bouncycastle.cms;
2e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
3e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.io.IOException;
4e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.io.OutputStream;
5e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.util.Collections;
6e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.util.HashMap;
7e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.util.Map;
8e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
9e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.ASN1Encoding;
10e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.ASN1ObjectIdentifier;
11e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.ASN1Set;
12e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.DEROctetString;
13e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.DERSet;
14e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.cms.AttributeTable;
15e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.cms.SignerIdentifier;
16e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.cms.SignerInfo;
17e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.x509.AlgorithmIdentifier;
18e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.cert.X509CertificateHolder;
19e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.ContentSigner;
20e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
21e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
22e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.DigestCalculator;
23e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.DigestCalculatorProvider;
24e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.OperatorCreationException;
255db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Rootimport org.bouncycastle.util.Arrays;
26e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.util.io.TeeOutputStream;
27e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
28e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrompublic class SignerInfoGenerator
29e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom{
30e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    private final SignerIdentifier signerIdentifier;
31e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    private final CMSAttributeTableGenerator sAttrGen;
32e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    private final CMSAttributeTableGenerator unsAttrGen;
33e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    private final ContentSigner signer;
34e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    private final DigestCalculator digester;
35e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    private final DigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
36e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    private final CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder;
37e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
38e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    private byte[] calculatedDigest = null;
39e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    private X509CertificateHolder certHolder;
40e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
41e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    SignerInfoGenerator(
42e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        SignerIdentifier signerIdentifier,
43e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        ContentSigner signer,
44e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        DigestCalculatorProvider digesterProvider,
45e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder)
46e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        throws OperatorCreationException
47e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
48e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this(signerIdentifier, signer, digesterProvider, sigEncAlgFinder, false);
49e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
50e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
51e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    SignerInfoGenerator(
52e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        SignerIdentifier signerIdentifier,
53e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        ContentSigner signer,
54e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        DigestCalculatorProvider digesterProvider,
55e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder,
56e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        boolean isDirectSignature)
57e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        throws OperatorCreationException
58e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
59e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.signerIdentifier = signerIdentifier;
60e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.signer = signer;
61e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
62e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        if (digesterProvider != null)
63e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
64e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            this.digester = digesterProvider.get(digAlgFinder.find(signer.getAlgorithmIdentifier()));
65e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
66e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        else
67e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
68e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            this.digester = null;
69e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
70e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
71e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        if (isDirectSignature)
72e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
73e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            this.sAttrGen = null;
74e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            this.unsAttrGen = null;
75e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
76e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        else
77e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
78e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            this.sAttrGen = new DefaultSignedAttributeTableGenerator();
79e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            this.unsAttrGen = null;
80e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
81e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
82e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.sigEncAlgFinder = sigEncAlgFinder;
83e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
84e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
85e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    public SignerInfoGenerator(
86e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        SignerInfoGenerator original,
87e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        CMSAttributeTableGenerator sAttrGen,
88e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        CMSAttributeTableGenerator unsAttrGen)
89e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
90e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.signerIdentifier = original.signerIdentifier;
91e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.signer = original.signer;
92e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.digester = original.digester;
93e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.sigEncAlgFinder = original.sigEncAlgFinder;
94e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.sAttrGen = sAttrGen;
95e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.unsAttrGen = unsAttrGen;
96e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
97e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
98e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    SignerInfoGenerator(
99e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        SignerIdentifier signerIdentifier,
100e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        ContentSigner signer,
101e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        DigestCalculatorProvider digesterProvider,
102e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder,
103e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        CMSAttributeTableGenerator sAttrGen,
104e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        CMSAttributeTableGenerator unsAttrGen)
105e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        throws OperatorCreationException
106e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
107e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.signerIdentifier = signerIdentifier;
108e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.signer = signer;
109e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
110e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        if (digesterProvider != null)
111e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
112e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            this.digester = digesterProvider.get(digAlgFinder.find(signer.getAlgorithmIdentifier()));
113e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
114e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        else
115e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
116e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            this.digester = null;
117e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
118e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
119e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.sAttrGen = sAttrGen;
120e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.unsAttrGen = unsAttrGen;
121e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.sigEncAlgFinder = sigEncAlgFinder;
122e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
123e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
124e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom    public SignerIdentifier getSID()
125e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom    {
126a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        return signerIdentifier;
127e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom    }
128e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom
1295db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root    public int getGeneratedVersion()
130e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom    {
1315db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root        return signerIdentifier.isTagged() ? 3 : 1;
132e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom    }
133e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom
134e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    public boolean hasAssociatedCertificate()
135e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
136e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        return certHolder != null;
137e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
138e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
139e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    public X509CertificateHolder getAssociatedCertificate()
140e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
141e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        return certHolder;
142e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
143e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
144e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    public AlgorithmIdentifier getDigestAlgorithm()
145e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
146e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        if (digester != null)
147e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
148e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            return digester.getAlgorithmIdentifier();
149e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
150e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
151e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        return digAlgFinder.find(signer.getAlgorithmIdentifier());
152e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
153e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
154e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    public OutputStream getCalculatingOutputStream()
155e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
156e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        if (digester != null)
157e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
158e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            if (sAttrGen == null)
159e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            {
160e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                return new TeeOutputStream(digester.getOutputStream(), signer.getOutputStream());
161e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            }
162e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            return digester.getOutputStream();
163e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
164e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        else
165e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
166e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            return signer.getOutputStream();
167e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
168e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
169e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
170e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    public SignerInfo generate(ASN1ObjectIdentifier contentType)
171e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        throws CMSException
172e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
173e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        try
174e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
175e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            /* RFC 3852 5.4
176e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom             * The result of the message digest calculation process depends on
177e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom             * whether the signedAttrs field is present.  When the field is absent,
178e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom             * the result is just the message digest of the content as described
179e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom             *
180e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom             * above.  When the field is present, however, the result is the message
181e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom             * digest of the complete DER encoding of the SignedAttrs value
182e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom             * contained in the signedAttrs field.
183e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom             */
184e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            ASN1Set signedAttr = null;
185e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
186e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            AlgorithmIdentifier digestAlg = null;
187e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
188e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            if (sAttrGen != null)
189e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            {
190e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                digestAlg = digester.getAlgorithmIdentifier();
191e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                calculatedDigest = digester.getDigest();
192e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                Map parameters = getBaseParameters(contentType, digester.getAlgorithmIdentifier(), calculatedDigest);
193e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                AttributeTable signed = sAttrGen.getAttributes(Collections.unmodifiableMap(parameters));
194e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
195e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                signedAttr = getAttributeSet(signed);
196e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
197e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                // sig must be composed from the DER encoding.
198e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                OutputStream sOut = signer.getOutputStream();
199e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
200e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                sOut.write(signedAttr.getEncoded(ASN1Encoding.DER));
201e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
202e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                sOut.close();
203e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            }
204e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            else
205e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            {
206e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                if (digester != null)
207e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                {
208e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                    digestAlg = digester.getAlgorithmIdentifier();
209e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                    calculatedDigest = digester.getDigest();
210e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                }
211e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                else
212e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                {
213e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                    digestAlg = digAlgFinder.find(signer.getAlgorithmIdentifier());
214e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                    calculatedDigest = null;
215e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                }
216e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            }
217e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
218e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            byte[] sigBytes = signer.getSignature();
219e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
220e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            ASN1Set unsignedAttr = null;
221e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            if (unsAttrGen != null)
222e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            {
223e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                Map parameters = getBaseParameters(contentType, digestAlg, calculatedDigest);
2245db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root                parameters.put(CMSAttributeTableGenerator.SIGNATURE, Arrays.clone(sigBytes));
225e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
226e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                AttributeTable unsigned = unsAttrGen.getAttributes(Collections.unmodifiableMap(parameters));
227e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
228e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                unsignedAttr = getAttributeSet(unsigned);
229e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            }
230e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
231e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            AlgorithmIdentifier digestEncryptionAlgorithm = sigEncAlgFinder.findEncryptionAlgorithm(signer.getAlgorithmIdentifier());
232e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
233e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            return new SignerInfo(signerIdentifier, digestAlg,
234e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                signedAttr, digestEncryptionAlgorithm, new DEROctetString(sigBytes), unsignedAttr);
235e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
236e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        catch (IOException e)
237e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
238e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            throw new CMSException("encoding error.", e);
239e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
240e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
241e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
242e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    void setAssociatedCertificate(X509CertificateHolder certHolder)
243e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
244e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.certHolder = certHolder;
245e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
246e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
247e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    private ASN1Set getAttributeSet(
248e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        AttributeTable attr)
249e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
250e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        if (attr != null)
251e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
252e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            return new DERSet(attr.toASN1EncodableVector());
253e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
254e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
255e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        return null;
256e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
257e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
258e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom    private Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash)
259e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
260e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        Map param = new HashMap();
261e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
262e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        if (contentType != null)
263e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
264e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType);
265e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
266e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
267e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId);
2685db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root        param.put(CMSAttributeTableGenerator.DIGEST,  Arrays.clone(hash));
269e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        return param;
270e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
271e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
272e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    public byte[] getCalculatedDigest()
273e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
274e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        if (calculatedDigest != null)
275e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
2765db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root            return Arrays.clone(calculatedDigest);
277e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
278e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
279e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        return null;
280e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
281e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
282e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    public CMSAttributeTableGenerator getSignedAttributeTableGenerator()
283e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
284e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        return sAttrGen;
285e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
286e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
287e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    public CMSAttributeTableGenerator getUnsignedAttributeTableGenerator()
288e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
289e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        return unsAttrGen;
290e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
291e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom}
292