SignerInfo.java revision 5db505e1f6a68c8d5dfdb0fed0b8607dea7bed96
1package org.bouncycastle.asn1.cms;
2
3import java.util.Enumeration;
4
5import org.bouncycastle.asn1.ASN1EncodableVector;
6import org.bouncycastle.asn1.ASN1Integer;
7import org.bouncycastle.asn1.ASN1Object;
8import org.bouncycastle.asn1.ASN1OctetString;
9import org.bouncycastle.asn1.ASN1Primitive;
10import org.bouncycastle.asn1.ASN1Sequence;
11import org.bouncycastle.asn1.ASN1Set;
12import org.bouncycastle.asn1.ASN1TaggedObject;
13import org.bouncycastle.asn1.DEROctetString;
14import org.bouncycastle.asn1.DERSequence;
15import org.bouncycastle.asn1.DERTaggedObject;
16import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
17
18/**
19 * <a href="http://tools.ietf.org/html/rfc5652#section-5.3">RFC 5652</a>:
20 * Signature container per Signer, see {@link SignerIdentifier}.
21 * <pre>
22 * PKCS#7:
23 *
24 * SignerInfo ::= SEQUENCE {
25 *     version                   Version,
26 *     sid                       SignerIdentifier,
27 *     digestAlgorithm           DigestAlgorithmIdentifier,
28 *     authenticatedAttributes   [0] IMPLICIT Attributes OPTIONAL,
29 *     digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
30 *     encryptedDigest           EncryptedDigest,
31 *     unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL
32 * }
33 *
34 * EncryptedDigest ::= OCTET STRING
35 *
36 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
37 *
38 * DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
39 *
40 * -----------------------------------------
41 *
42 * RFC 5256:
43 *
44 * SignerInfo ::= SEQUENCE {
45 *     version            CMSVersion,
46 *     sid                SignerIdentifier,
47 *     digestAlgorithm    DigestAlgorithmIdentifier,
48 *     signedAttrs        [0] IMPLICIT SignedAttributes OPTIONAL,
49 *     signatureAlgorithm SignatureAlgorithmIdentifier,
50 *     signature          SignatureValue,
51 *     unsignedAttrs      [1] IMPLICIT UnsignedAttributes OPTIONAL
52 * }
53 *
54 * -- {@link SignerIdentifier} referenced certificates are at containing
55 * -- {@link SignedData} certificates element.
56 *
57 * SignerIdentifier ::= CHOICE {
58 *     issuerAndSerialNumber {@link IssuerAndSerialNumber},
59 *     subjectKeyIdentifier  [0] SubjectKeyIdentifier }
60 *
61 * -- See {@link Attributes} for generalized SET OF {@link Attribute}
62 *
63 * SignedAttributes   ::= SET SIZE (1..MAX) OF Attribute
64 * UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute
65 *
66 * {@link Attribute} ::= SEQUENCE {
67 *     attrType   OBJECT IDENTIFIER,
68 *     attrValues SET OF AttributeValue }
69 *
70 * AttributeValue ::= ANY
71 *
72 * SignatureValue ::= OCTET STRING
73 * </pre>
74 */
75public class SignerInfo
76    extends ASN1Object
77{
78    private ASN1Integer              version;
79    private SignerIdentifier        sid;
80    private AlgorithmIdentifier     digAlgorithm;
81    private ASN1Set                 authenticatedAttributes;
82    private AlgorithmIdentifier     digEncryptionAlgorithm;
83    private ASN1OctetString         encryptedDigest;
84    private ASN1Set                 unauthenticatedAttributes;
85
86    /**
87     * Return a SignerInfo object from the given input
88     * <p>
89     * Accepted inputs:
90     * <ul>
91     * <li> null &rarr; null
92     * <li> {@link SignerInfo} object
93     * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with SignerInfo structure inside
94     * </ul>
95     *
96     * @param o the object we want converted.
97     * @exception IllegalArgumentException if the object cannot be converted.
98     */
99    public static SignerInfo getInstance(
100        Object  o)
101        throws IllegalArgumentException
102    {
103        if (o instanceof SignerInfo)
104        {
105            return (SignerInfo)o;
106        }
107        else if (o != null)
108        {
109            return new SignerInfo(ASN1Sequence.getInstance(o));
110        }
111
112        return null;
113    }
114
115    /**
116     *
117     * @param sid
118     * @param digAlgorithm            CMS knows as 'digestAlgorithm'
119     * @param authenticatedAttributes CMS knows as 'signedAttrs'
120     * @param digEncryptionAlgorithm  CMS knows as 'signatureAlgorithm'
121     * @param encryptedDigest         CMS knows as 'signature'
122     * @param unauthenticatedAttributes CMS knows as 'unsignedAttrs'
123     */
124    public SignerInfo(
125        SignerIdentifier        sid,
126        AlgorithmIdentifier     digAlgorithm,
127        ASN1Set                 authenticatedAttributes,
128        AlgorithmIdentifier     digEncryptionAlgorithm,
129        ASN1OctetString         encryptedDigest,
130        ASN1Set                 unauthenticatedAttributes)
131    {
132        if (sid.isTagged())
133        {
134            this.version = new ASN1Integer(3);
135        }
136        else
137        {
138            this.version = new ASN1Integer(1);
139        }
140
141        this.sid = sid;
142        this.digAlgorithm = digAlgorithm;
143        this.authenticatedAttributes = authenticatedAttributes;
144        this.digEncryptionAlgorithm = digEncryptionAlgorithm;
145        this.encryptedDigest = encryptedDigest;
146        this.unauthenticatedAttributes = unauthenticatedAttributes;
147    }
148
149    /**
150     *
151     * @param sid
152     * @param digAlgorithm            CMS knows as 'digestAlgorithm'
153     * @param authenticatedAttributes CMS knows as 'signedAttrs'
154     * @param digEncryptionAlgorithm  CMS knows as 'signatureAlgorithm'
155     * @param encryptedDigest         CMS knows as 'signature'
156     * @param unauthenticatedAttributes CMS knows as 'unsignedAttrs'
157     */
158    public SignerInfo(
159        SignerIdentifier        sid,
160        AlgorithmIdentifier     digAlgorithm,
161        Attributes              authenticatedAttributes,
162        AlgorithmIdentifier     digEncryptionAlgorithm,
163        ASN1OctetString         encryptedDigest,
164        Attributes              unauthenticatedAttributes)
165    {
166        if (sid.isTagged())
167        {
168            this.version = new ASN1Integer(3);
169        }
170        else
171        {
172            this.version = new ASN1Integer(1);
173        }
174
175        this.sid = sid;
176        this.digAlgorithm = digAlgorithm;
177        this.authenticatedAttributes = ASN1Set.getInstance(authenticatedAttributes);
178        this.digEncryptionAlgorithm = digEncryptionAlgorithm;
179        this.encryptedDigest = encryptedDigest;
180        this.unauthenticatedAttributes = ASN1Set.getInstance(unauthenticatedAttributes);
181    }
182
183    /**
184     * @deprecated use getInstance() method.
185     */
186    public SignerInfo(
187        ASN1Sequence seq)
188    {
189        Enumeration     e = seq.getObjects();
190
191        version = (ASN1Integer)e.nextElement();
192        sid = SignerIdentifier.getInstance(e.nextElement());
193        digAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement());
194
195        Object obj = e.nextElement();
196
197        if (obj instanceof ASN1TaggedObject)
198        {
199            authenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)obj, false);
200
201            digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement());
202        }
203        else
204        {
205            authenticatedAttributes = null;
206            digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(obj);
207        }
208
209        encryptedDigest = DEROctetString.getInstance(e.nextElement());
210
211        if (e.hasMoreElements())
212        {
213            unauthenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)e.nextElement(), false);
214        }
215        else
216        {
217            unauthenticatedAttributes = null;
218        }
219    }
220
221    public ASN1Integer getVersion()
222    {
223        return version;
224    }
225
226    public SignerIdentifier getSID()
227    {
228        return sid;
229    }
230
231    public ASN1Set getAuthenticatedAttributes()
232    {
233        return authenticatedAttributes;
234    }
235
236    public AlgorithmIdentifier getDigestAlgorithm()
237    {
238        return digAlgorithm;
239    }
240
241    public ASN1OctetString getEncryptedDigest()
242    {
243        return encryptedDigest;
244    }
245
246    public AlgorithmIdentifier getDigestEncryptionAlgorithm()
247    {
248        return digEncryptionAlgorithm;
249    }
250
251    public ASN1Set getUnauthenticatedAttributes()
252    {
253        return unauthenticatedAttributes;
254    }
255
256    /**
257     * Produce an object suitable for an ASN1OutputStream.
258     */
259    public ASN1Primitive toASN1Primitive()
260    {
261        ASN1EncodableVector v = new ASN1EncodableVector();
262
263        v.add(version);
264        v.add(sid);
265        v.add(digAlgorithm);
266
267        if (authenticatedAttributes != null)
268        {
269            v.add(new DERTaggedObject(false, 0, authenticatedAttributes));
270        }
271
272        v.add(digEncryptionAlgorithm);
273        v.add(encryptedDigest);
274
275        if (unauthenticatedAttributes != null)
276        {
277            v.add(new DERTaggedObject(false, 1, unauthenticatedAttributes));
278        }
279
280        return new DERSequence(v);
281    }
282}
283