1package org.bouncycastle.asn1.cms;
2
3import org.bouncycastle.asn1.ASN1Encodable;
4import org.bouncycastle.asn1.ASN1EncodableVector;
5import org.bouncycastle.asn1.ASN1OctetString;
6import org.bouncycastle.asn1.ASN1Sequence;
7import org.bouncycastle.asn1.ASN1TaggedObject;
8import org.bouncycastle.asn1.DERGeneralizedTime;
9import org.bouncycastle.asn1.DERObject;
10import org.bouncycastle.asn1.DERSequence;
11
12public class RecipientKeyIdentifier
13    extends ASN1Encodable
14{
15    private ASN1OctetString      subjectKeyIdentifier;
16    private DERGeneralizedTime   date;
17    private OtherKeyAttribute    other;
18
19    public RecipientKeyIdentifier(
20        ASN1OctetString         subjectKeyIdentifier,
21        DERGeneralizedTime      date,
22        OtherKeyAttribute       other)
23    {
24        this.subjectKeyIdentifier = subjectKeyIdentifier;
25        this.date = date;
26        this.other = other;
27    }
28
29    public RecipientKeyIdentifier(
30        ASN1Sequence seq)
31    {
32        subjectKeyIdentifier = ASN1OctetString.getInstance(
33                                                    seq.getObjectAt(0));
34
35        switch(seq.size())
36        {
37        case 1:
38            break;
39        case 2:
40            if (seq.getObjectAt(1) instanceof DERGeneralizedTime)
41            {
42                date = (DERGeneralizedTime)seq.getObjectAt(1);
43            }
44            else
45            {
46                other = OtherKeyAttribute.getInstance(seq.getObjectAt(2));
47            }
48            break;
49        case 3:
50            date  = (DERGeneralizedTime)seq.getObjectAt(1);
51            other = OtherKeyAttribute.getInstance(seq.getObjectAt(2));
52            break;
53        default:
54            throw new IllegalArgumentException("Invalid KEKIdentifier");
55        }
56    }
57
58    /**
59     * return a RecipientKeyIdentifier object from a tagged object.
60     *
61     * @param _ato the tagged object holding the object we want.
62     * @param _explicit true if the object is meant to be explicitly
63     *              tagged false otherwise.
64     * @exception IllegalArgumentException if the object held by the
65     *          tagged object cannot be converted.
66     */
67    public static RecipientKeyIdentifier getInstance(ASN1TaggedObject _ato, boolean _explicit)
68    {
69        return getInstance(ASN1Sequence.getInstance(_ato, _explicit));
70    }
71
72    /**
73     * return a RecipientKeyIdentifier object from the given object.
74     *
75     * @param _obj the object we want converted.
76     * @exception IllegalArgumentException if the object cannot be converted.
77     */
78    public static RecipientKeyIdentifier getInstance(Object _obj)
79    {
80        if(_obj == null || _obj instanceof RecipientKeyIdentifier)
81        {
82            return (RecipientKeyIdentifier)_obj;
83        }
84
85        if(_obj instanceof ASN1Sequence)
86        {
87            return new RecipientKeyIdentifier((ASN1Sequence)_obj);
88        }
89
90        throw new IllegalArgumentException("Invalid RecipientKeyIdentifier: " + _obj.getClass().getName());
91    }
92
93    public ASN1OctetString getSubjectKeyIdentifier()
94    {
95        return subjectKeyIdentifier;
96    }
97
98    public DERGeneralizedTime getDate()
99    {
100        return date;
101    }
102
103    public OtherKeyAttribute getOtherKeyAttribute()
104    {
105        return other;
106    }
107
108
109    /**
110     * Produce an object suitable for an ASN1OutputStream.
111     * <pre>
112     * RecipientKeyIdentifier ::= SEQUENCE {
113     *     subjectKeyIdentifier SubjectKeyIdentifier,
114     *     date GeneralizedTime OPTIONAL,
115     *     other OtherKeyAttribute OPTIONAL
116     * }
117     *
118     * SubjectKeyIdentifier ::= OCTET STRING
119     * </pre>
120     */
121    public DERObject toASN1Object()
122    {
123        ASN1EncodableVector  v = new ASN1EncodableVector();
124
125        v.add(subjectKeyIdentifier);
126
127        if (date != null)
128        {
129            v.add(date);
130        }
131
132        if (other != null)
133        {
134            v.add(other);
135        }
136
137        return new DERSequence(v);
138    }
139}
140