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