001package org.apache.commons.ssl.org.bouncycastle.asn1.sec;
002
003import java.math.BigInteger;
004import java.util.Enumeration;
005
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Encodable;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Integer;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1OctetString;
011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
012import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
013import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject;
014import org.apache.commons.ssl.org.bouncycastle.asn1.DERBitString;
015import org.apache.commons.ssl.org.bouncycastle.asn1.DEROctetString;
016import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
017import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject;
018import org.bouncycastle.util.BigIntegers;
019
020/**
021 * the elliptic curve private key object from SEC 1
022 */
023public class ECPrivateKey
024    extends ASN1Object
025{
026    private ASN1Sequence seq;
027
028    private ECPrivateKey(
029        ASN1Sequence seq)
030    {
031        this.seq = seq;
032    }
033
034    public static ECPrivateKey getInstance(
035        Object obj)
036    {
037        if (obj instanceof ECPrivateKey)
038        {
039            return (ECPrivateKey)obj;
040        }
041
042        if (obj != null)
043        {
044            return new ECPrivateKey(ASN1Sequence.getInstance(obj));
045        }
046
047        return null;
048    }
049
050    /**
051     * @deprecated use constructor which takes orderBitLength to guarantee correct encoding.
052     */
053    public ECPrivateKey(
054        BigInteger key)
055    {
056        this(key.bitLength(), key);
057    }
058
059    /**
060     * Base constructor.
061     *
062     * @param orderBitLength the bitLength of the order of the curve.
063     * @param key the private key value.
064     */
065    public ECPrivateKey(
066        int        orderBitLength,
067        BigInteger key)
068    {
069        byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key);
070
071        ASN1EncodableVector v = new ASN1EncodableVector();
072
073        v.add(new ASN1Integer(1));
074        v.add(new DEROctetString(bytes));
075
076        seq = new DERSequence(v);
077    }
078
079    /**
080     * @deprecated use constructor which takes orderBitLength to guarantee correct encoding.
081     */
082    public ECPrivateKey(
083        BigInteger key,
084        ASN1Encodable parameters)
085    {
086        this(key, null, parameters);
087    }
088
089    /**
090     * @deprecated use constructor which takes orderBitLength to guarantee correct encoding.
091     */
092    public ECPrivateKey(
093        BigInteger key,
094        DERBitString publicKey,
095        ASN1Encodable parameters)
096    {
097        this(key.bitLength(), key, publicKey, parameters);
098    }
099
100    public ECPrivateKey(
101        int orderBitLength,
102        BigInteger key,
103        ASN1Encodable parameters)
104    {
105        this(orderBitLength, key, null, parameters);
106    }
107
108    public ECPrivateKey(
109        int orderBitLength,
110        BigInteger key,
111        DERBitString publicKey,
112        ASN1Encodable parameters)
113    {
114        byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key);
115
116        ASN1EncodableVector v = new ASN1EncodableVector();
117
118        v.add(new ASN1Integer(1));
119        v.add(new DEROctetString(bytes));
120
121        if (parameters != null)
122        {
123            v.add(new DERTaggedObject(true, 0, parameters));
124        }
125
126        if (publicKey != null)
127        {
128            v.add(new DERTaggedObject(true, 1, publicKey));
129        }
130
131        seq = new DERSequence(v);
132    }
133
134    public BigInteger getKey()
135    {
136        ASN1OctetString octs = (ASN1OctetString)seq.getObjectAt(1);
137
138        return new BigInteger(1, octs.getOctets());
139    }
140
141    public DERBitString getPublicKey()
142    {
143        return (DERBitString)getObjectInTag(1);
144    }
145
146    public ASN1Primitive getParameters()
147    {
148        return getObjectInTag(0);
149    }
150
151    private ASN1Primitive getObjectInTag(int tagNo)
152    {
153        Enumeration e = seq.getObjects();
154
155        while (e.hasMoreElements())
156        {
157            ASN1Encodable obj = (ASN1Encodable)e.nextElement();
158
159            if (obj instanceof ASN1TaggedObject)
160            {
161                ASN1TaggedObject tag = (ASN1TaggedObject)obj;
162                if (tag.getTagNo() == tagNo)
163                {
164                    return tag.getObject().toASN1Primitive();
165                }
166            }
167        }
168        return null;
169    }
170
171    /**
172     * ECPrivateKey ::= SEQUENCE {
173     *     version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
174     *     privateKey OCTET STRING,
175     *     parameters [0] Parameters OPTIONAL,
176     *     publicKey [1] BIT STRING OPTIONAL }
177     */
178    public ASN1Primitive toASN1Primitive()
179    {
180        return seq;
181    }
182}