Home | History | Annotate | Download | only in cms
      1 package org.bouncycastle.asn1.cms;
      2 
      3 import java.util.Enumeration;
      4 
      5 import org.bouncycastle.asn1.ASN1EncodableVector;
      6 import org.bouncycastle.asn1.ASN1Integer;
      7 import org.bouncycastle.asn1.ASN1Object;
      8 import org.bouncycastle.asn1.ASN1OctetString;
      9 import org.bouncycastle.asn1.ASN1Primitive;
     10 import org.bouncycastle.asn1.ASN1Sequence;
     11 import org.bouncycastle.asn1.ASN1Set;
     12 import org.bouncycastle.asn1.ASN1TaggedObject;
     13 import org.bouncycastle.asn1.DEROctetString;
     14 import org.bouncycastle.asn1.DERSequence;
     15 import org.bouncycastle.asn1.DERTaggedObject;
     16 import 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 5652:
     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  */
     75 public 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