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