001package org.apache.commons.ssl.org.bouncycastle.asn1.cms;
002
003import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
004import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Set;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject;
009import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
010import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject;
011
012/**
013 * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.1">RFC 5652</a>: OriginatorInfo object.
014 * <pre>
015 * RFC 3369:
016 *
017 * OriginatorInfo ::= SEQUENCE {
018 *     certs [0] IMPLICIT CertificateSet OPTIONAL,
019 *     crls  [1] IMPLICIT CertificateRevocationLists OPTIONAL 
020 * }
021 * CertificateRevocationLists ::= SET OF CertificateList (from X.509)
022 *
023 * RFC 3582 / 5652:
024 *
025 * OriginatorInfo ::= SEQUENCE {
026 *     certs [0] IMPLICIT CertificateSet OPTIONAL,
027 *     crls  [1] IMPLICIT RevocationInfoChoices OPTIONAL
028 * }
029 * RevocationInfoChoices ::= SET OF RevocationInfoChoice
030 * RevocationInfoChoice ::= CHOICE {
031 *     crl CertificateList,
032 *     other [1] IMPLICIT OtherRevocationInfoFormat }
033 *
034 * OtherRevocationInfoFormat ::= SEQUENCE {
035 *     otherRevInfoFormat OBJECT IDENTIFIER,
036 *     otherRevInfo ANY DEFINED BY otherRevInfoFormat }
037 * </pre>
038 * <p>
039 * TODO: RevocationInfoChoices / RevocationInfoChoice.
040 *       Constructor using CertificateSet, CertificationInfoChoices
041 */
042public class OriginatorInfo
043    extends ASN1Object
044{
045    private ASN1Set certs;
046    private ASN1Set crls;
047    
048    public OriginatorInfo(
049        ASN1Set certs,
050        ASN1Set crls)
051    {
052        this.certs = certs;
053        this.crls = crls;
054    }
055    
056    private OriginatorInfo(
057        ASN1Sequence seq)
058    {
059        switch (seq.size())
060        {
061        case 0:     // empty
062            break;
063        case 1:
064            ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(0);
065            switch (o.getTagNo())
066            {
067            case 0 :
068                certs = ASN1Set.getInstance(o, false);
069                break;
070            case 1 :
071                crls = ASN1Set.getInstance(o, false);
072                break;
073            default:
074                throw new IllegalArgumentException("Bad tag in OriginatorInfo: " + o.getTagNo());
075            }
076            break;
077        case 2:
078            certs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(0), false);
079            crls  = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(1), false);
080            break;
081        default:
082            throw new IllegalArgumentException("OriginatorInfo too big");
083        }
084    }
085    
086    /**
087     * Return an OriginatorInfo object from a tagged object.
088     *
089     * @param obj the tagged object holding the object we want.
090     * @param explicit true if the object is meant to be explicitly
091     *              tagged false otherwise.
092     * @exception IllegalArgumentException if the object held by the
093     *          tagged object cannot be converted.
094     */
095    public static OriginatorInfo getInstance(
096        ASN1TaggedObject    obj,
097        boolean             explicit)
098    {
099        return getInstance(ASN1Sequence.getInstance(obj, explicit));
100    }
101    
102    /**
103     * Return an OriginatorInfo object from the given object.
104     * <p>
105     * Accepted inputs:
106     * <ul>
107     * <li> null &rarr; null
108     * <li> {@link OriginatorInfo} object
109     * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with OriginatorInfo structure inside
110     * </ul>
111     *
112     * @param obj the object we want converted.
113     * @exception IllegalArgumentException if the object cannot be converted.
114     */
115    public static OriginatorInfo getInstance(
116        Object obj)
117    {
118        if (obj instanceof OriginatorInfo)
119        {
120            return (OriginatorInfo)obj;
121        }
122        else if (obj != null)
123        {
124            return new OriginatorInfo(ASN1Sequence.getInstance(obj));
125        }
126
127        return null;
128    }
129    
130    public ASN1Set getCertificates()
131    {
132        return certs;
133    }
134
135    public ASN1Set getCRLs()
136    {
137        return crls;
138    }
139
140    /** 
141     * Produce an object suitable for an ASN1OutputStream.
142     */
143    public ASN1Primitive toASN1Primitive()
144    {
145        ASN1EncodableVector  v = new ASN1EncodableVector();
146
147        if (certs != null)
148        {
149            v.add(new DERTaggedObject(false, 0, certs));
150        }
151        
152        if (crls != null)
153        {
154            v.add(new DERTaggedObject(false, 1, crls));
155        }
156        
157        return new DERSequence(v);
158    }
159}