001package org.apache.commons.ssl.org.bouncycastle.asn1.pkcs;
002
003import java.util.Enumeration;
004
005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Integer;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Set;
011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject;
012import org.apache.commons.ssl.org.bouncycastle.asn1.BERSequence;
013import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject;
014
015/**
016 * a PKCS#7 signed data object.
017 */
018public class SignedData
019    extends ASN1Object
020    implements PKCSObjectIdentifiers
021{
022    private ASN1Integer              version;
023    private ASN1Set                 digestAlgorithms;
024    private ContentInfo             contentInfo;
025    private ASN1Set                 certificates;
026    private ASN1Set                 crls;
027    private ASN1Set                 signerInfos;
028
029    public static SignedData getInstance(
030        Object  o)
031    {
032        if (o instanceof SignedData)
033        {
034            return (SignedData)o;
035        }
036        else if (o != null)
037        {
038            return new SignedData(ASN1Sequence.getInstance(o));
039        }
040
041        return null;
042    }
043
044    public SignedData(
045        ASN1Integer        _version,
046        ASN1Set           _digestAlgorithms,
047        ContentInfo       _contentInfo,
048        ASN1Set           _certificates,
049        ASN1Set           _crls,
050        ASN1Set           _signerInfos)
051    {
052        version          = _version;
053        digestAlgorithms = _digestAlgorithms;
054        contentInfo      = _contentInfo;
055        certificates     = _certificates;
056        crls             = _crls;
057        signerInfos      = _signerInfos;
058    }
059
060    public SignedData(
061        ASN1Sequence seq)
062    {
063        Enumeration     e = seq.getObjects();
064
065        version = (ASN1Integer)e.nextElement();
066        digestAlgorithms = ((ASN1Set)e.nextElement());
067        contentInfo = ContentInfo.getInstance(e.nextElement());
068
069        while (e.hasMoreElements())
070        {
071            ASN1Primitive o = (ASN1Primitive)e.nextElement();
072
073            //
074            // an interesting feature of SignedData is that there appear to be varying implementations...
075            // for the moment we ignore anything which doesn't fit.
076            //
077            if (o instanceof ASN1TaggedObject)
078            {
079                ASN1TaggedObject tagged = (ASN1TaggedObject)o;
080
081                switch (tagged.getTagNo())
082                {
083                case 0:
084                    certificates = ASN1Set.getInstance(tagged, false);
085                    break;
086                case 1:
087                    crls = ASN1Set.getInstance(tagged, false);
088                    break;
089                default:
090                    throw new IllegalArgumentException("unknown tag value " + tagged.getTagNo());
091                }
092            }
093            else
094            {
095                signerInfos = (ASN1Set)o;
096            }
097        }
098    }
099
100    public ASN1Integer getVersion()
101    {
102        return version;
103    }
104
105    public ASN1Set getDigestAlgorithms()
106    {
107        return digestAlgorithms;
108    }
109
110    public ContentInfo getContentInfo()
111    {
112        return contentInfo;
113    }
114
115    public ASN1Set getCertificates()
116    {
117        return certificates;
118    }
119
120    public ASN1Set getCRLs()
121    {
122        return crls;
123    }
124
125    public ASN1Set getSignerInfos()
126    {
127        return signerInfos;
128    }
129
130    /**
131     * Produce an object suitable for an ASN1OutputStream.
132     * <pre>
133     *  SignedData ::= SEQUENCE {
134     *      version Version,
135     *      digestAlgorithms DigestAlgorithmIdentifiers,
136     *      contentInfo ContentInfo,
137     *      certificates
138     *          [0] IMPLICIT ExtendedCertificatesAndCertificates
139     *                   OPTIONAL,
140     *      crls
141     *          [1] IMPLICIT CertificateRevocationLists OPTIONAL,
142     *      signerInfos SignerInfos }
143     * </pre>
144     */
145    public ASN1Primitive toASN1Primitive()
146    {
147        ASN1EncodableVector v = new ASN1EncodableVector();
148
149        v.add(version);
150        v.add(digestAlgorithms);
151        v.add(contentInfo);
152
153        if (certificates != null)
154        {
155            v.add(new DERTaggedObject(false, 0, certificates));
156        }
157
158        if (crls != null)
159        {
160            v.add(new DERTaggedObject(false, 1, crls));
161        }
162
163        v.add(signerInfos);
164
165        return new BERSequence(v);
166    }
167}