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.ASN1GeneralizedTime;
005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1OctetString;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject;
010import org.apache.commons.ssl.org.bouncycastle.asn1.DEROctetString;
011import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
012
013/**
014 * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.2">RFC 5652</a>:
015 * Content encryption key delivery mechanisms.
016 * <p>
017 * <pre>
018 * RecipientKeyIdentifier ::= SEQUENCE {
019 *     subjectKeyIdentifier SubjectKeyIdentifier,
020 *     date GeneralizedTime OPTIONAL,
021 *     other OtherKeyAttribute OPTIONAL 
022 * }
023 *
024 * SubjectKeyIdentifier ::= OCTET STRING
025 * </pre>
026 */
027public class RecipientKeyIdentifier
028    extends ASN1Object
029{
030    private ASN1OctetString      subjectKeyIdentifier;
031    private ASN1GeneralizedTime  date;
032    private OtherKeyAttribute    other;
033
034    public RecipientKeyIdentifier(
035        ASN1OctetString         subjectKeyIdentifier,
036        ASN1GeneralizedTime     date,
037        OtherKeyAttribute       other)
038    {
039        this.subjectKeyIdentifier = subjectKeyIdentifier;
040        this.date = date;
041        this.other = other;
042    }
043
044    public RecipientKeyIdentifier(
045        byte[]                  subjectKeyIdentifier,
046        ASN1GeneralizedTime     date,
047        OtherKeyAttribute       other)
048    {
049        this.subjectKeyIdentifier = new DEROctetString(subjectKeyIdentifier);
050        this.date = date;
051        this.other = other;
052    }
053
054    public RecipientKeyIdentifier(
055        byte[]         subjectKeyIdentifier)
056    {
057        this(subjectKeyIdentifier, null, null);
058    }
059
060    /**
061     * @deprecated use getInstance()
062     */
063    public RecipientKeyIdentifier(
064        ASN1Sequence seq)
065    {
066        subjectKeyIdentifier = ASN1OctetString.getInstance(
067                                                    seq.getObjectAt(0));
068        
069        switch(seq.size())
070        {
071        case 1:
072            break;
073        case 2:
074            if (seq.getObjectAt(1) instanceof ASN1GeneralizedTime)
075            {
076                date = ASN1GeneralizedTime.getInstance(seq.getObjectAt(1));
077            }
078            else
079            {
080                other = OtherKeyAttribute.getInstance(seq.getObjectAt(2));
081            }
082            break;
083        case 3:
084            date  = ASN1GeneralizedTime.getInstance(seq.getObjectAt(1));
085            other = OtherKeyAttribute.getInstance(seq.getObjectAt(2));
086            break;
087        default:
088            throw new IllegalArgumentException("Invalid RecipientKeyIdentifier");
089        }
090    }
091
092    /**
093     * Return a RecipientKeyIdentifier object from a tagged object.
094     *
095     * @param ato the tagged object holding the object we want.
096     * @param isExplicit true if the object is meant to be explicitly
097     *              tagged false otherwise.
098     * @exception IllegalArgumentException if the object held by the
099     *          tagged object cannot be converted.
100     */
101    public static RecipientKeyIdentifier getInstance(ASN1TaggedObject ato, boolean isExplicit)
102    {
103        return getInstance(ASN1Sequence.getInstance(ato, isExplicit));
104    }
105    
106    /**
107     * Return a RecipientKeyIdentifier object from the given object.
108     * <p>
109     * Accepted inputs:
110     * <ul>
111     * <li> null &rarr; null
112     * <li> {@link RecipientKeyIdentifier} object
113     * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with RecipientKeyIdentifier structure inside
114     * </ul>
115     *
116     * @param obj the object we want converted.
117     * @exception IllegalArgumentException if the object cannot be converted.
118     */
119    public static RecipientKeyIdentifier getInstance(Object obj)
120    {
121        if (obj instanceof RecipientKeyIdentifier)
122        {
123            return (RecipientKeyIdentifier)obj;
124        }
125        
126        if(obj != null)
127        {
128            return new RecipientKeyIdentifier(ASN1Sequence.getInstance(obj));
129        }
130        
131        return null;
132    } 
133
134    public ASN1OctetString getSubjectKeyIdentifier()
135    {
136        return subjectKeyIdentifier;
137    }
138
139    public ASN1GeneralizedTime getDate()
140    {
141        return date;
142    }
143
144    public OtherKeyAttribute getOtherKeyAttribute()
145    {
146        return other;
147    }
148
149
150    /** 
151     * Produce an object suitable for an ASN1OutputStream.
152     */
153    public ASN1Primitive toASN1Primitive()
154    {
155        ASN1EncodableVector  v = new ASN1EncodableVector();
156
157        v.add(subjectKeyIdentifier);
158        
159        if (date != null)
160        {
161            v.add(date);
162        }
163
164        if (other != null)
165        {
166            v.add(other);
167        }
168        
169        return new DERSequence(v);
170    }
171}