1package org.bouncycastle.jce.provider; 2 3import java.io.ByteArrayOutputStream; 4import java.io.IOException; 5import java.io.ObjectInputStream; 6import java.io.ObjectOutputStream; 7import java.math.BigInteger; 8import java.util.Enumeration; 9import java.util.Hashtable; 10import java.util.Vector; 11 12import javax.crypto.interfaces.DHPrivateKey; 13import javax.crypto.spec.DHParameterSpec; 14import javax.crypto.spec.DHPrivateKeySpec; 15 16import org.bouncycastle.asn1.ASN1Sequence; 17import org.bouncycastle.asn1.DEREncodable; 18import org.bouncycastle.asn1.DERInteger; 19import org.bouncycastle.asn1.DERObjectIdentifier; 20import org.bouncycastle.asn1.DEROutputStream; 21import org.bouncycastle.asn1.pkcs.DHParameter; 22import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 23import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 24import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 25import org.bouncycastle.crypto.params.DHPrivateKeyParameters; 26import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; 27 28public class JCEDHPrivateKey 29 implements DHPrivateKey, PKCS12BagAttributeCarrier 30{ 31 BigInteger x; 32 33 DHParameterSpec dhSpec; 34 35 private Hashtable pkcs12Attributes = new Hashtable(); 36 private Vector pkcs12Ordering = new Vector(); 37 38 protected JCEDHPrivateKey() 39 { 40 } 41 42 JCEDHPrivateKey( 43 DHPrivateKey key) 44 { 45 this.x = key.getX(); 46 this.dhSpec = key.getParams(); 47 } 48 49 JCEDHPrivateKey( 50 DHPrivateKeySpec spec) 51 { 52 this.x = spec.getX(); 53 this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG()); 54 } 55 56 JCEDHPrivateKey( 57 PrivateKeyInfo info) 58 { 59 DHParameter params = new DHParameter((ASN1Sequence)info.getAlgorithmId().getParameters()); 60 DERInteger derX = (DERInteger)info.getPrivateKey(); 61 62 this.x = derX.getValue(); 63 if (params.getL() != null) 64 { 65 this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue()); 66 } 67 else 68 { 69 this.dhSpec = new DHParameterSpec(params.getP(), params.getG()); 70 } 71 } 72 73 JCEDHPrivateKey( 74 DHPrivateKeyParameters params) 75 { 76 this.x = params.getX(); 77 this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG()); 78 } 79 80 public String getAlgorithm() 81 { 82 return "DH"; 83 } 84 85 /** 86 * return the encoding format we produce in getEncoded(). 87 * 88 * @return the string "PKCS#8" 89 */ 90 public String getFormat() 91 { 92 return "PKCS#8"; 93 } 94 95 /** 96 * Return a PKCS8 representation of the key. The sequence returned 97 * represents a full PrivateKeyInfo object. 98 * 99 * @return a PKCS8 representation of the key. 100 */ 101 public byte[] getEncoded() 102 { 103 PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL()).getDERObject()), new DERInteger(getX())); 104 105 return info.getDEREncoded(); 106 } 107 108 public DHParameterSpec getParams() 109 { 110 return dhSpec; 111 } 112 113 public BigInteger getX() 114 { 115 return x; 116 } 117 118 private void readObject( 119 ObjectInputStream in) 120 throws IOException, ClassNotFoundException 121 { 122 x = (BigInteger)in.readObject(); 123 124 this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt()); 125 } 126 127 private void writeObject( 128 ObjectOutputStream out) 129 throws IOException 130 { 131 out.writeObject(this.getX()); 132 out.writeObject(dhSpec.getP()); 133 out.writeObject(dhSpec.getG()); 134 out.writeInt(dhSpec.getL()); 135 } 136 137 public void setBagAttribute( 138 DERObjectIdentifier oid, 139 DEREncodable attribute) 140 { 141 pkcs12Attributes.put(oid, attribute); 142 pkcs12Ordering.addElement(oid); 143 } 144 145 public DEREncodable getBagAttribute( 146 DERObjectIdentifier oid) 147 { 148 return (DEREncodable)pkcs12Attributes.get(oid); 149 } 150 151 public Enumeration getBagAttributeKeys() 152 { 153 return pkcs12Ordering.elements(); 154 } 155} 156