001package org.apache.commons.ssl.org.bouncycastle.asn1.cms;
002
003import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Choice;
004import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Encodable;
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.ASN1TaggedObject;
009import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject;
010import org.apache.commons.ssl.org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
011
012/**
013 * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.2">RFC 5652</a>:
014 * Content encryption key delivery mechanisms.
015 * <pre>
016 * OriginatorIdentifierOrKey ::= CHOICE {
017 *     issuerAndSerialNumber IssuerAndSerialNumber,
018 *     subjectKeyIdentifier [0] SubjectKeyIdentifier,
019 *     originatorKey [1] OriginatorPublicKey 
020 * }
021 *
022 * SubjectKeyIdentifier ::= OCTET STRING
023 * </pre>
024 */
025public class OriginatorIdentifierOrKey
026    extends ASN1Object
027    implements ASN1Choice
028{
029    private ASN1Encodable id;
030
031    public OriginatorIdentifierOrKey(
032        IssuerAndSerialNumber id)
033    {
034        this.id = id;
035    }
036
037    /**
038     * @deprecated use version taking a SubjectKeyIdentifier
039     */
040    public OriginatorIdentifierOrKey(
041        ASN1OctetString id)
042    {
043        this(new SubjectKeyIdentifier(id.getOctets()));
044    }
045
046    public OriginatorIdentifierOrKey(
047        SubjectKeyIdentifier id)
048    {
049        this.id = new DERTaggedObject(false, 0, id);
050    }
051
052    public OriginatorIdentifierOrKey(
053        OriginatorPublicKey id)
054    {
055        this.id = new DERTaggedObject(false, 1, id);
056    }
057
058    /**
059     * @deprecated use more specific version
060     */
061    public OriginatorIdentifierOrKey(
062        ASN1Primitive id)
063    {
064        this.id = id;
065    }
066
067    /**
068     * Return an OriginatorIdentifierOrKey object from a tagged object.
069     *
070     * @param o the tagged object holding the object we want.
071     * @param explicit true if the object is meant to be explicitly
072     *              tagged false otherwise.
073     * @exception IllegalArgumentException if the object held by the
074     *          tagged object cannot be converted.
075     */
076    public static OriginatorIdentifierOrKey getInstance(
077        ASN1TaggedObject    o,
078        boolean             explicit)
079    {
080        if (!explicit)
081        {
082            throw new IllegalArgumentException(
083                    "Can't implicitly tag OriginatorIdentifierOrKey");
084        }
085
086        return getInstance(o.getObject());
087    }
088    
089    /**
090     * Return an OriginatorIdentifierOrKey object from the given object.
091     * <p>
092     * Accepted inputs:
093     * <ul>
094     * <li> null &rarr; null
095     * <li> {@link OriginatorIdentifierOrKey} object
096     * <li> {@link IssuerAndSerialNumber} object
097     * <li> {@link SubjectKeyIdentifier} object
098     * <li> {@link OriginatorPublicKey} object
099     * <li> {@link org.bouncycastle.asn1.ASN1TaggedObject#getInstance(java.lang.Object) ASN1TaggedObject} input formats with IssuerAndSerialNumber structure inside
100     * </ul>
101     *
102     * @param o the object we want converted.
103     * @exception IllegalArgumentException if the object cannot be converted.
104     */
105    public static OriginatorIdentifierOrKey getInstance(
106        Object o)
107    {
108        if (o == null || o instanceof OriginatorIdentifierOrKey)
109        {
110            return (OriginatorIdentifierOrKey)o;
111        }
112
113        if (o instanceof IssuerAndSerialNumber)
114        {
115            return new OriginatorIdentifierOrKey((IssuerAndSerialNumber)o);
116        }
117
118        if (o instanceof SubjectKeyIdentifier)
119        {
120            return new OriginatorIdentifierOrKey((SubjectKeyIdentifier)o);
121        }
122
123        if (o instanceof OriginatorPublicKey)
124        {
125            return new OriginatorIdentifierOrKey((OriginatorPublicKey)o);
126        }
127
128        if (o instanceof ASN1TaggedObject)
129        {
130            // TODO Add validation
131            return new OriginatorIdentifierOrKey((ASN1TaggedObject)o);
132        }
133
134        throw new IllegalArgumentException("Invalid OriginatorIdentifierOrKey: " + o.getClass().getName());
135    }
136
137    public ASN1Encodable getId()
138    {
139        return id;
140    }
141
142    public IssuerAndSerialNumber getIssuerAndSerialNumber()
143    {
144        if (id instanceof IssuerAndSerialNumber)
145        {
146            return (IssuerAndSerialNumber)id;
147        }
148
149        return null;
150    }
151
152    public SubjectKeyIdentifier getSubjectKeyIdentifier()
153    {
154        if (id instanceof ASN1TaggedObject && ((ASN1TaggedObject)id).getTagNo() == 0)
155        {
156            return SubjectKeyIdentifier.getInstance((ASN1TaggedObject)id, false);
157        }
158
159        return null;
160    }
161
162    public OriginatorPublicKey getOriginatorKey()
163    {
164        if (id instanceof ASN1TaggedObject && ((ASN1TaggedObject)id).getTagNo() == 1)
165        {
166            return OriginatorPublicKey.getInstance((ASN1TaggedObject)id, false);
167        }
168
169        return null;
170    }
171
172    /**
173     * Produce an object suitable for an ASN1OutputStream.
174     */
175    public ASN1Primitive toASN1Primitive()
176    {
177        return id.toASN1Primitive();
178    }
179}