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