14c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompackage org.bouncycastle.jcajce.provider.asymmetric.dsa;
24c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
34c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.IOException;
44c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.ObjectInputStream;
54c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.ObjectOutputStream;
64c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.math.BigInteger;
74c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.interfaces.DSAParams;
84c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.interfaces.DSAPrivateKey;
94c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.spec.DSAParameterSpec;
104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.spec.DSAPrivateKeySpec;
114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.util.Enumeration;
124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Encodable;
144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Integer;
154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1ObjectIdentifier;
164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x509.AlgorithmIdentifier;
184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x509.DSAParameter;
194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompublic class BCDSAPrivateKey
264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    implements DSAPrivateKey, PKCS12BagAttributeCarrier
274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom{
284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private static final long serialVersionUID = -4677259546958385734L;
294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private BigInteger          x;
314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private transient DSAParams dsaSpec;
324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected BCDSAPrivateKey()
364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    BCDSAPrivateKey(
404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        DSAPrivateKey key)
414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.x = key.getX();
434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.dsaSpec = key.getParams();
444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    BCDSAPrivateKey(
474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        DSAPrivateKeySpec spec)
484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.x = spec.getX();
504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG());
514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public BCDSAPrivateKey(
544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        PrivateKeyInfo info)
554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws IOException
564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        DSAParameter    params = DSAParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters());
584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Integer      derX = (ASN1Integer)info.parsePrivateKey();
594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.x = derX.getValue();
614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG());
624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    BCDSAPrivateKey(
654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        DSAPrivateKeyParameters params)
664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.x = params.getX();
684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG());
694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public String getAlgorithm()
724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return "DSA";
744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * return the encoding format we produce in getEncoded().
784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     *
794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * @return the string "PKCS#8"
804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public String getFormat()
824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return "PKCS#8";
844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * Return a PKCS8 representation of the key. The sequence returned
884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * represents a full PrivateKeyInfo object.
894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     *
904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * @return a PKCS8 representation of the key.
914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public byte[] getEncoded()
934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG()).toASN1Primitive()), new ASN1Integer(getX()));
954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public DSAParams getParams()
984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return dsaSpec;
1004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public BigInteger getX()
1034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return x;
1054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public boolean equals(
1084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        Object o)
1094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (!(o instanceof DSAPrivateKey))
1114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return false;
1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        DSAPrivateKey other = (DSAPrivateKey)o;
1164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return this.getX().equals(other.getX())
1184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            && this.getParams().getG().equals(other.getParams().getG())
1194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            && this.getParams().getP().equals(other.getParams().getP())
1204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            && this.getParams().getQ().equals(other.getParams().getQ());
1214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public int hashCode()
1244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return this.getX().hashCode() ^ this.getParams().getG().hashCode()
1264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                ^ this.getParams().getP().hashCode() ^ this.getParams().getQ().hashCode();
1274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public void setBagAttribute(
1304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1ObjectIdentifier oid,
1314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable attribute)
1324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        attrCarrier.setBagAttribute(oid, attribute);
1344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Encodable getBagAttribute(
13770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom        ASN1ObjectIdentifier oid)
1384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return attrCarrier.getBagAttribute(oid);
1404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public Enumeration getBagAttributeKeys()
1434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return attrCarrier.getBagAttributeKeys();
1454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private void readObject(
1484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ObjectInputStream in)
1494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws IOException, ClassNotFoundException
1504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        in.defaultReadObject();
1524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.dsaSpec = new DSAParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), (BigInteger)in.readObject());
1544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
1554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private void writeObject(
1584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ObjectOutputStream out)
1594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws IOException
1604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        out.defaultWriteObject();
1624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        out.writeObject(dsaSpec.getP());
1644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        out.writeObject(dsaSpec.getQ());
1654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        out.writeObject(dsaSpec.getG());
1664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom}
168