1package org.bouncycastle.jcajce.provider.asymmetric.dsa; 2 3import java.io.IOException; 4import java.io.ObjectInputStream; 5import java.io.ObjectOutputStream; 6import java.math.BigInteger; 7import java.security.interfaces.DSAParams; 8import java.security.interfaces.DSAPrivateKey; 9import java.security.spec.DSAParameterSpec; 10import java.security.spec.DSAPrivateKeySpec; 11import java.util.Enumeration; 12 13import org.bouncycastle.asn1.ASN1Encodable; 14import org.bouncycastle.asn1.ASN1Integer; 15import org.bouncycastle.asn1.ASN1ObjectIdentifier; 16import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 17import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 18import org.bouncycastle.asn1.x509.DSAParameter; 19import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; 20import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; 21import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; 22import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; 23import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; 24 25public class BCDSAPrivateKey 26 implements DSAPrivateKey, PKCS12BagAttributeCarrier 27{ 28 private static final long serialVersionUID = -4677259546958385734L; 29 30 private BigInteger x; 31 private transient DSAParams dsaSpec; 32 33 private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); 34 35 protected BCDSAPrivateKey() 36 { 37 } 38 39 BCDSAPrivateKey( 40 DSAPrivateKey key) 41 { 42 this.x = key.getX(); 43 this.dsaSpec = key.getParams(); 44 } 45 46 BCDSAPrivateKey( 47 DSAPrivateKeySpec spec) 48 { 49 this.x = spec.getX(); 50 this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG()); 51 } 52 53 public BCDSAPrivateKey( 54 PrivateKeyInfo info) 55 throws IOException 56 { 57 DSAParameter params = DSAParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters()); 58 ASN1Integer derX = (ASN1Integer)info.parsePrivateKey(); 59 60 this.x = derX.getValue(); 61 this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG()); 62 } 63 64 BCDSAPrivateKey( 65 DSAPrivateKeyParameters params) 66 { 67 this.x = params.getX(); 68 this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG()); 69 } 70 71 public String getAlgorithm() 72 { 73 return "DSA"; 74 } 75 76 /** 77 * return the encoding format we produce in getEncoded(). 78 * 79 * @return the string "PKCS#8" 80 */ 81 public String getFormat() 82 { 83 return "PKCS#8"; 84 } 85 86 /** 87 * Return a PKCS8 representation of the key. The sequence returned 88 * represents a full PrivateKeyInfo object. 89 * 90 * @return a PKCS8 representation of the key. 91 */ 92 public byte[] getEncoded() 93 { 94 return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG()).toASN1Primitive()), new ASN1Integer(getX())); 95 } 96 97 public DSAParams getParams() 98 { 99 return dsaSpec; 100 } 101 102 public BigInteger getX() 103 { 104 return x; 105 } 106 107 public boolean equals( 108 Object o) 109 { 110 if (!(o instanceof DSAPrivateKey)) 111 { 112 return false; 113 } 114 115 DSAPrivateKey other = (DSAPrivateKey)o; 116 117 return this.getX().equals(other.getX()) 118 && this.getParams().getG().equals(other.getParams().getG()) 119 && this.getParams().getP().equals(other.getParams().getP()) 120 && this.getParams().getQ().equals(other.getParams().getQ()); 121 } 122 123 public int hashCode() 124 { 125 return this.getX().hashCode() ^ this.getParams().getG().hashCode() 126 ^ this.getParams().getP().hashCode() ^ this.getParams().getQ().hashCode(); 127 } 128 129 public void setBagAttribute( 130 ASN1ObjectIdentifier oid, 131 ASN1Encodable attribute) 132 { 133 attrCarrier.setBagAttribute(oid, attribute); 134 } 135 136 public ASN1Encodable getBagAttribute( 137 ASN1ObjectIdentifier oid) 138 { 139 return attrCarrier.getBagAttribute(oid); 140 } 141 142 public Enumeration getBagAttributeKeys() 143 { 144 return attrCarrier.getBagAttributeKeys(); 145 } 146 147 private void readObject( 148 ObjectInputStream in) 149 throws IOException, ClassNotFoundException 150 { 151 in.defaultReadObject(); 152 153 this.dsaSpec = new DSAParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), (BigInteger)in.readObject()); 154 this.attrCarrier = new PKCS12BagAttributeCarrierImpl(); 155 } 156 157 private void writeObject( 158 ObjectOutputStream out) 159 throws IOException 160 { 161 out.defaultWriteObject(); 162 163 out.writeObject(dsaSpec.getP()); 164 out.writeObject(dsaSpec.getQ()); 165 out.writeObject(dsaSpec.getG()); 166 } 167} 168