001package org.apache.commons.ssl.org.bouncycastle.asn1.cms.ecc;
002
003import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
004import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1OctetString;
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject;
009import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
010import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject;
011import org.apache.commons.ssl.org.bouncycastle.asn1.cms.OriginatorPublicKey;
012
013/**
014 * <a href="http://tools.ietf.org/html/rfc5753">RFC 5753/3278</a>: MQVuserKeyingMaterial object.
015 * <pre>
016 * MQVuserKeyingMaterial ::= SEQUENCE {
017 *   ephemeralPublicKey OriginatorPublicKey,
018 *   addedukm [0] EXPLICIT UserKeyingMaterial OPTIONAL  }
019 * </pre>
020 */
021public class MQVuserKeyingMaterial
022    extends ASN1Object
023{
024    private OriginatorPublicKey ephemeralPublicKey;
025    private ASN1OctetString addedukm;
026
027    public MQVuserKeyingMaterial(
028        OriginatorPublicKey ephemeralPublicKey,
029        ASN1OctetString addedukm)
030    {
031        // TODO Check ephemeralPublicKey not null
032        
033        this.ephemeralPublicKey = ephemeralPublicKey;
034        this.addedukm = addedukm;
035    }
036
037    private MQVuserKeyingMaterial(
038        ASN1Sequence seq)
039    {
040        // TODO Check seq has either 1 or 2 elements
041
042        this.ephemeralPublicKey = OriginatorPublicKey.getInstance(
043            seq.getObjectAt(0));
044
045        if (seq.size() > 1)
046        {
047            this.addedukm = ASN1OctetString.getInstance(
048                (ASN1TaggedObject)seq.getObjectAt(1), true);
049        }
050    }
051
052    /**
053     * Return an MQVuserKeyingMaterial object from a tagged object.
054     *
055     * @param obj      the tagged object holding the object we want.
056     * @param explicit true if the object is meant to be explicitly
057     *                 tagged false otherwise.
058     * @throws IllegalArgumentException if the object held by the
059     *                                  tagged object cannot be converted.
060     */
061    public static MQVuserKeyingMaterial getInstance(
062        ASN1TaggedObject obj,
063        boolean explicit)
064    {
065        return getInstance(ASN1Sequence.getInstance(obj, explicit));
066    }
067
068    /**
069     * Return an MQVuserKeyingMaterial object from the given object.
070     * <p>
071     * Accepted inputs:
072     * <ul>
073     * <li> null &rarr; null
074     * <li> {@link MQVuserKeyingMaterial} object
075     * <li> {@link org.bouncycastle.asn1.ASN1Sequence ASN1Sequence} with MQVuserKeyingMaterial inside it.
076     * </ul>
077     *
078     * @param obj the object we want converted.
079     * @throws IllegalArgumentException if the object cannot be converted.
080     */
081    public static MQVuserKeyingMaterial getInstance(
082        Object obj)
083    {
084        if (obj == null || obj instanceof MQVuserKeyingMaterial)
085        {
086            return (MQVuserKeyingMaterial)obj;
087        }
088
089        if (obj instanceof ASN1Sequence)
090        {
091            return new MQVuserKeyingMaterial((ASN1Sequence)obj);
092        }
093
094        throw new IllegalArgumentException("Invalid MQVuserKeyingMaterial: " + obj.getClass().getName());
095    }
096
097    public OriginatorPublicKey getEphemeralPublicKey()
098    {
099        return ephemeralPublicKey;
100    }
101
102    public ASN1OctetString getAddedukm()
103    {
104        return addedukm;
105    }
106
107    /**
108     * Produce an object suitable for an ASN1OutputStream.
109     */
110    public ASN1Primitive toASN1Primitive()
111    {
112        ASN1EncodableVector v = new ASN1EncodableVector();
113        v.add(ephemeralPublicKey);
114
115        if (addedukm != null)
116        {
117            v.add(new DERTaggedObject(true, 0, addedukm));
118        }
119
120        return new DERSequence(v);
121    }
122}