001package org.apache.commons.ssl.org.bouncycastle.asn1.crmf;
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.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.DERBitString;
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.x509.AlgorithmIdentifier;
012
013public class POPOSigningKey
014    extends ASN1Object
015{
016    private POPOSigningKeyInput poposkInput;
017    private AlgorithmIdentifier algorithmIdentifier;
018    private DERBitString signature;
019
020    private POPOSigningKey(ASN1Sequence seq)
021    {
022        int index = 0;
023
024        if (seq.getObjectAt(index) instanceof ASN1TaggedObject)
025        {
026            ASN1TaggedObject tagObj
027                = (ASN1TaggedObject)seq.getObjectAt(index++);
028            if (tagObj.getTagNo() != 0)
029            {
030                throw new IllegalArgumentException(
031                    "Unknown POPOSigningKeyInput tag: " + tagObj.getTagNo());
032            }
033            poposkInput = POPOSigningKeyInput.getInstance(tagObj.getObject());
034        }
035        algorithmIdentifier = AlgorithmIdentifier.getInstance(seq.getObjectAt(index++));
036        signature = DERBitString.getInstance(seq.getObjectAt(index));
037    }
038
039    public static POPOSigningKey getInstance(Object o)
040    {
041        if (o instanceof POPOSigningKey)
042        {
043            return (POPOSigningKey)o;
044        }
045
046        if (o != null)
047        {
048            return new POPOSigningKey(ASN1Sequence.getInstance(o));
049        }
050
051        return null;
052    }
053
054    public static POPOSigningKey getInstance(ASN1TaggedObject obj, boolean explicit)
055    {
056        return getInstance(ASN1Sequence.getInstance(obj, explicit));
057    }
058
059    /**
060     * Creates a new Proof of Possession object for a signing key.
061     *
062     * @param poposkIn  the POPOSigningKeyInput structure, or null if the
063     *                  CertTemplate includes both subject and publicKey values.
064     * @param aid       the AlgorithmIdentifier used to sign the proof of possession.
065     * @param signature a signature over the DER-encoded value of poposkIn,
066     *                  or the DER-encoded value of certReq if poposkIn is null.
067     */
068    public POPOSigningKey(
069        POPOSigningKeyInput poposkIn,
070        AlgorithmIdentifier aid,
071        DERBitString signature)
072    {
073        this.poposkInput = poposkIn;
074        this.algorithmIdentifier = aid;
075        this.signature = signature;
076    }
077
078    public POPOSigningKeyInput getPoposkInput()
079    {
080        return poposkInput;
081    }
082
083    public AlgorithmIdentifier getAlgorithmIdentifier()
084    {
085        return algorithmIdentifier;
086    }
087
088    public DERBitString getSignature()
089    {
090        return signature;
091    }
092
093    /**
094     * <pre>
095     * POPOSigningKey ::= SEQUENCE {
096     *                      poposkInput           [0] POPOSigningKeyInput OPTIONAL,
097     *                      algorithmIdentifier   AlgorithmIdentifier,
098     *                      signature             BIT STRING }
099     *  -- The signature (using "algorithmIdentifier") is on the
100     *  -- DER-encoded value of poposkInput.  NOTE: If the CertReqMsg
101     *  -- certReq CertTemplate contains the subject and publicKey values,
102     *  -- then poposkInput MUST be omitted and the signature MUST be
103     *  -- computed on the DER-encoded value of CertReqMsg certReq.  If
104     *  -- the CertReqMsg certReq CertTemplate does not contain the public
105     *  -- key and subject values, then poposkInput MUST be present and
106     *  -- MUST be signed.  This strategy ensures that the public key is
107     *  -- not present in both the poposkInput and CertReqMsg certReq
108     *  -- CertTemplate fields.
109     * </pre>
110     *
111     * @return a basic ASN.1 object representation.
112     */
113    public ASN1Primitive toASN1Primitive()
114    {
115        ASN1EncodableVector v = new ASN1EncodableVector();
116
117        if (poposkInput != null)
118        {
119            v.add(new DERTaggedObject(false, 0, poposkInput));
120        }
121
122        v.add(algorithmIdentifier);
123        v.add(signature);
124
125        return new DERSequence(v);
126    }
127}