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.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.ASN1TaggedObject;
008import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject;
009
010/**
011 * <a href="http://tools.ietf.org/html/rfc5652#section-6.2.2">RFC 5652</a>:
012 * Content encryption key delivery mechanisms.
013 * <p>
014 * <pre>
015 * KeyAgreeRecipientIdentifier ::= CHOICE {
016 *     issuerAndSerialNumber IssuerAndSerialNumber,
017 *     rKeyId [0] IMPLICIT RecipientKeyIdentifier }
018 * </pre>
019 */
020public class KeyAgreeRecipientIdentifier
021    extends ASN1Object
022    implements ASN1Choice
023{
024    private IssuerAndSerialNumber issuerSerial;
025    private RecipientKeyIdentifier rKeyID;
026
027    /**
028     * Return an KeyAgreeRecipientIdentifier object from a tagged object.
029     *
030     * @param obj the tagged object holding the object we want.
031     * @param explicit true if the object is meant to be explicitly
032     *              tagged false otherwise.
033     * @exception IllegalArgumentException if the object held by the
034     *          tagged object cannot be converted.
035     */
036    public static KeyAgreeRecipientIdentifier getInstance(
037        ASN1TaggedObject    obj,
038        boolean             explicit)
039    {
040        return getInstance(ASN1Sequence.getInstance(obj, explicit));
041    }
042    
043    /**
044     * Return an KeyAgreeRecipientIdentifier object from the given object.
045     * <p>
046     * Accepted inputs:
047     * <ul>
048     * <li> {@link KeyAgreeRecipientIdentifier} object
049     * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with IssuerAndSerialNumber structure inside
050     * <li> {@link org.bouncycastle.asn1.ASN1TaggedObject#getInstance(java.lang.Object) ASN1TaggedObject} with tag value 0: a KeyAgreeRecipientIdentifier data structure
051     * </ul>
052     * <p>
053     * Note: no byte[] input!
054     *
055     * @param obj the object we want converted.
056     * @exception IllegalArgumentException if the object cannot be converted.
057     */
058    public static KeyAgreeRecipientIdentifier getInstance(
059        Object obj)
060    {
061        if (obj == null || obj instanceof KeyAgreeRecipientIdentifier)
062        {
063            return (KeyAgreeRecipientIdentifier)obj;
064        }
065        
066        if (obj instanceof ASN1Sequence)
067        {
068            return new KeyAgreeRecipientIdentifier(IssuerAndSerialNumber.getInstance(obj));
069        }
070        
071        if (obj instanceof ASN1TaggedObject && ((ASN1TaggedObject)obj).getTagNo() == 0)
072        {
073            return new KeyAgreeRecipientIdentifier(RecipientKeyIdentifier.getInstance(
074                (ASN1TaggedObject)obj, false));
075        }
076        
077        throw new IllegalArgumentException("Invalid KeyAgreeRecipientIdentifier: " + obj.getClass().getName());
078    } 
079
080    public KeyAgreeRecipientIdentifier(
081        IssuerAndSerialNumber issuerSerial)
082    {
083        this.issuerSerial = issuerSerial;
084        this.rKeyID = null;
085    }
086
087    public KeyAgreeRecipientIdentifier(
088         RecipientKeyIdentifier rKeyID)
089    {
090        this.issuerSerial = null;
091        this.rKeyID = rKeyID;
092    }
093
094    public IssuerAndSerialNumber getIssuerAndSerialNumber()
095    {
096        return issuerSerial;
097    }
098
099    public RecipientKeyIdentifier getRKeyID()
100    {
101        return rKeyID;
102    }
103
104    /** 
105     * Produce an object suitable for an ASN1OutputStream.
106     */
107    public ASN1Primitive toASN1Primitive()
108    {
109        if (issuerSerial != null)
110        {
111            return issuerSerial.toASN1Primitive();
112        }
113
114        return new DERTaggedObject(false, 0, rKeyID);
115    }
116}