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