1 package org.bouncycastle.jcajce.provider.asymmetric.elgamal;
2 
3 import java.io.IOException;
4 import java.io.ObjectInputStream;
5 import java.io.ObjectOutputStream;
6 import java.math.BigInteger;
7 import java.util.Enumeration;
8 
9 import javax.crypto.interfaces.DHPrivateKey;
10 import javax.crypto.spec.DHParameterSpec;
11 import javax.crypto.spec.DHPrivateKeySpec;
12 
13 import org.bouncycastle.asn1.ASN1Encodable;
14 import org.bouncycastle.asn1.ASN1Encoding;
15 import org.bouncycastle.asn1.ASN1Integer;
16 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
17 import org.bouncycastle.asn1.oiw.ElGamalParameter;
18 import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
19 import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
20 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
21 import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters;
22 import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
23 import org.bouncycastle.jce.interfaces.ElGamalPrivateKey;
24 import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
25 import org.bouncycastle.jce.spec.ElGamalParameterSpec;
26 import org.bouncycastle.jce.spec.ElGamalPrivateKeySpec;
27 
28 public class BCElGamalPrivateKey
29     implements ElGamalPrivateKey, DHPrivateKey, PKCS12BagAttributeCarrier
30 {
31     static final long serialVersionUID = 4819350091141529678L;
32 
33     private BigInteger      x;
34 
35     private transient ElGamalParameterSpec   elSpec;
36     private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
37 
BCElGamalPrivateKey()38     protected BCElGamalPrivateKey()
39     {
40     }
41 
BCElGamalPrivateKey( ElGamalPrivateKey key)42     BCElGamalPrivateKey(
43         ElGamalPrivateKey key)
44     {
45         this.x = key.getX();
46         this.elSpec = key.getParameters();
47     }
48 
BCElGamalPrivateKey( DHPrivateKey key)49     BCElGamalPrivateKey(
50         DHPrivateKey key)
51     {
52         this.x = key.getX();
53         this.elSpec = new ElGamalParameterSpec(key.getParams().getP(), key.getParams().getG());
54     }
55 
BCElGamalPrivateKey( ElGamalPrivateKeySpec spec)56     BCElGamalPrivateKey(
57         ElGamalPrivateKeySpec spec)
58     {
59         this.x = spec.getX();
60         this.elSpec = new ElGamalParameterSpec(spec.getParams().getP(), spec.getParams().getG());
61     }
62 
BCElGamalPrivateKey( DHPrivateKeySpec spec)63     BCElGamalPrivateKey(
64         DHPrivateKeySpec spec)
65     {
66         this.x = spec.getX();
67         this.elSpec = new ElGamalParameterSpec(spec.getP(), spec.getG());
68     }
69 
BCElGamalPrivateKey( PrivateKeyInfo info)70     BCElGamalPrivateKey(
71         PrivateKeyInfo info)
72         throws IOException
73     {
74         ElGamalParameter     params = ElGamalParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters());
75         ASN1Integer      derX = ASN1Integer.getInstance(info.parsePrivateKey());
76 
77         this.x = derX.getValue();
78         this.elSpec = new ElGamalParameterSpec(params.getP(), params.getG());
79     }
80 
BCElGamalPrivateKey( ElGamalPrivateKeyParameters params)81     BCElGamalPrivateKey(
82         ElGamalPrivateKeyParameters params)
83     {
84         this.x = params.getX();
85         this.elSpec = new ElGamalParameterSpec(params.getParameters().getP(), params.getParameters().getG());
86     }
87 
getAlgorithm()88     public String getAlgorithm()
89     {
90         return "ElGamal";
91     }
92 
93     /**
94      * return the encoding format we produce in getEncoded().
95      *
96      * @return the string "PKCS#8"
97      */
getFormat()98     public String getFormat()
99     {
100         return "PKCS#8";
101     }
102 
103     /**
104      * Return a PKCS8 representation of the key. The sequence returned
105      * represents a full PrivateKeyInfo object.
106      *
107      * @return a PKCS8 representation of the key.
108      */
getEncoded()109     public byte[] getEncoded()
110     {
111         try
112         {
113             PrivateKeyInfo          info = new PrivateKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(elSpec.getP(), elSpec.getG())), new ASN1Integer(getX()));
114 
115             return info.getEncoded(ASN1Encoding.DER);
116         }
117         catch (IOException e)
118         {
119             return null;
120         }
121     }
122 
getParameters()123     public ElGamalParameterSpec getParameters()
124     {
125         return elSpec;
126     }
127 
getParams()128     public DHParameterSpec getParams()
129     {
130         return new DHParameterSpec(elSpec.getP(), elSpec.getG());
131     }
132 
getX()133     public BigInteger getX()
134     {
135         return x;
136     }
137 
equals( Object o)138     public boolean equals(
139         Object o)
140     {
141         if (!(o instanceof DHPrivateKey))
142         {
143             return false;
144         }
145 
146         DHPrivateKey other = (DHPrivateKey)o;
147 
148         return this.getX().equals(other.getX())
149             && this.getParams().getG().equals(other.getParams().getG())
150             && this.getParams().getP().equals(other.getParams().getP())
151             && this.getParams().getL() == other.getParams().getL();
152     }
153 
hashCode()154     public int hashCode()
155     {
156         return this.getX().hashCode() ^ this.getParams().getG().hashCode()
157                 ^ this.getParams().getP().hashCode() ^ this.getParams().getL();
158     }
159 
readObject( ObjectInputStream in)160     private void readObject(
161         ObjectInputStream   in)
162         throws IOException, ClassNotFoundException
163     {
164         in.defaultReadObject();
165 
166         this.elSpec = new ElGamalParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject());
167         this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
168     }
169 
writeObject( ObjectOutputStream out)170     private void writeObject(
171         ObjectOutputStream  out)
172         throws IOException
173     {
174         out.defaultWriteObject();
175 
176         out.writeObject(elSpec.getP());
177         out.writeObject(elSpec.getG());
178     }
179 
setBagAttribute( ASN1ObjectIdentifier oid, ASN1Encodable attribute)180     public void setBagAttribute(
181         ASN1ObjectIdentifier oid,
182         ASN1Encodable attribute)
183     {
184         attrCarrier.setBagAttribute(oid, attribute);
185     }
186 
getBagAttribute( ASN1ObjectIdentifier oid)187     public ASN1Encodable getBagAttribute(
188         ASN1ObjectIdentifier oid)
189     {
190         return attrCarrier.getBagAttribute(oid);
191     }
192 
getBagAttributeKeys()193     public Enumeration getBagAttributeKeys()
194     {
195         return attrCarrier.getBagAttributeKeys();
196     }
197 }
198