1package org.bouncycastle.jce.provider; 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.DSAPublicKey; 9import java.security.spec.DSAParameterSpec; 10import java.security.spec.DSAPublicKeySpec; 11 12import org.bouncycastle.asn1.ASN1Encodable; 13import org.bouncycastle.asn1.ASN1Encoding; 14import org.bouncycastle.asn1.ASN1Integer; 15import org.bouncycastle.asn1.DERNull; 16import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 17import org.bouncycastle.asn1.x509.DSAParameter; 18import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 19import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; 20import org.bouncycastle.crypto.params.DSAPublicKeyParameters; 21 22public class JDKDSAPublicKey 23 implements DSAPublicKey 24{ 25 private static final long serialVersionUID = 1752452449903495175L; 26 27 private BigInteger y; 28 private DSAParams dsaSpec; 29 30 JDKDSAPublicKey( 31 DSAPublicKeySpec spec) 32 { 33 this.y = spec.getY(); 34 this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG()); 35 } 36 37 JDKDSAPublicKey( 38 DSAPublicKey key) 39 { 40 this.y = key.getY(); 41 this.dsaSpec = key.getParams(); 42 } 43 44 JDKDSAPublicKey( 45 DSAPublicKeyParameters params) 46 { 47 this.y = params.getY(); 48 this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG()); 49 } 50 51 JDKDSAPublicKey( 52 BigInteger y, 53 DSAParameterSpec dsaSpec) 54 { 55 this.y = y; 56 this.dsaSpec = dsaSpec; 57 } 58 59 JDKDSAPublicKey( 60 SubjectPublicKeyInfo info) 61 { 62 63 ASN1Integer derY; 64 65 try 66 { 67 derY = (ASN1Integer)info.parsePublicKey(); 68 } 69 catch (IOException e) 70 { 71 throw new IllegalArgumentException("invalid info structure in DSA public key"); 72 } 73 74 this.y = derY.getValue(); 75 76 if (isNotNull(info.getAlgorithm().getParameters())) 77 { 78 DSAParameter params = DSAParameter.getInstance(info.getAlgorithm().getParameters()); 79 80 this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG()); 81 } 82 } 83 84 private boolean isNotNull(ASN1Encodable parameters) 85 { 86 return parameters != null && !DERNull.INSTANCE.equals(parameters); 87 } 88 89 public String getAlgorithm() 90 { 91 return "DSA"; 92 } 93 94 public String getFormat() 95 { 96 return "X.509"; 97 } 98 99 public byte[] getEncoded() 100 { 101 try 102 { 103 if (dsaSpec == null) 104 { 105 return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa), new ASN1Integer(y)).getEncoded(ASN1Encoding.DER); 106 } 107 108 return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG())), new ASN1Integer(y)).getEncoded(ASN1Encoding.DER); 109 } 110 catch (IOException e) 111 { 112 return null; 113 } 114 } 115 116 public DSAParams getParams() 117 { 118 return dsaSpec; 119 } 120 121 public BigInteger getY() 122 { 123 return y; 124 } 125 126 public String toString() 127 { 128 StringBuffer buf = new StringBuffer(); 129 String nl = System.getProperty("line.separator"); 130 131 buf.append("DSA Public Key").append(nl); 132 buf.append(" y: ").append(this.getY().toString(16)).append(nl); 133 134 return buf.toString(); 135 } 136 137 public int hashCode() 138 { 139 return this.getY().hashCode() ^ this.getParams().getG().hashCode() 140 ^ this.getParams().getP().hashCode() ^ this.getParams().getQ().hashCode(); 141 } 142 143 public boolean equals( 144 Object o) 145 { 146 if (!(o instanceof DSAPublicKey)) 147 { 148 return false; 149 } 150 151 DSAPublicKey other = (DSAPublicKey)o; 152 153 return this.getY().equals(other.getY()) 154 && this.getParams().getG().equals(other.getParams().getG()) 155 && this.getParams().getP().equals(other.getParams().getP()) 156 && this.getParams().getQ().equals(other.getParams().getQ()); 157 } 158 159 private void readObject( 160 ObjectInputStream in) 161 throws IOException, ClassNotFoundException 162 { 163 this.y = (BigInteger)in.readObject(); 164 this.dsaSpec = new DSAParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), (BigInteger)in.readObject()); 165 } 166 167 private void writeObject( 168 ObjectOutputStream out) 169 throws IOException 170 { 171 out.writeObject(y); 172 out.writeObject(dsaSpec.getP()); 173 out.writeObject(dsaSpec.getQ()); 174 out.writeObject(dsaSpec.getG()); 175 } 176} 177