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