DSASigner.java revision 5db505e1f6a68c8d5dfdb0fed0b8607dea7bed96
1package org.bouncycastle.jcajce.provider.asymmetric.dsa; 2 3import java.io.IOException; 4import java.math.BigInteger; 5import java.security.InvalidKeyException; 6import java.security.PrivateKey; 7import java.security.PublicKey; 8import java.security.SecureRandom; 9import java.security.SignatureException; 10import java.security.SignatureSpi; 11import java.security.interfaces.DSAKey; 12import java.security.spec.AlgorithmParameterSpec; 13 14import org.bouncycastle.asn1.ASN1Encoding; 15import org.bouncycastle.asn1.ASN1Integer; 16import org.bouncycastle.asn1.ASN1Primitive; 17import org.bouncycastle.asn1.ASN1Sequence; 18import org.bouncycastle.asn1.DERSequence; 19import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 20import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 21import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; 22import org.bouncycastle.crypto.CipherParameters; 23import org.bouncycastle.crypto.DSA; 24import org.bouncycastle.crypto.Digest; 25import org.bouncycastle.crypto.digests.NullDigest; 26// BEGIN android-added 27import org.bouncycastle.crypto.digests.AndroidDigestFactory; 28// END android-added 29// BEGIN android-removed 30// import org.bouncycastle.crypto.digests.SHA1Digest; 31// import org.bouncycastle.crypto.digests.SHA224Digest; 32// import org.bouncycastle.crypto.digests.SHA256Digest; 33// import org.bouncycastle.crypto.digests.SHA384Digest; 34// import org.bouncycastle.crypto.digests.SHA512Digest; 35// END android-removed 36import org.bouncycastle.crypto.params.ParametersWithRandom; 37// BEGIN android-removed 38// import org.bouncycastle.crypto.signers.HMacDSAKCalculator; 39// END android-removed 40 41public class DSASigner 42 extends SignatureSpi 43 implements PKCSObjectIdentifiers, X509ObjectIdentifiers 44{ 45 private Digest digest; 46 private DSA signer; 47 private SecureRandom random; 48 49 protected DSASigner( 50 Digest digest, 51 DSA signer) 52 { 53 this.digest = digest; 54 this.signer = signer; 55 } 56 57 protected void engineInitVerify( 58 PublicKey publicKey) 59 throws InvalidKeyException 60 { 61 CipherParameters param; 62 63 if (publicKey instanceof DSAKey) 64 { 65 param = DSAUtil.generatePublicKeyParameter(publicKey); 66 } 67 else 68 { 69 try 70 { 71 byte[] bytes = publicKey.getEncoded(); 72 73 publicKey = new BCDSAPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); 74 75 if (publicKey instanceof DSAKey) 76 { 77 param = DSAUtil.generatePublicKeyParameter(publicKey); 78 } 79 else 80 { 81 throw new InvalidKeyException("can't recognise key type in DSA based signer"); 82 } 83 } 84 catch (Exception e) 85 { 86 throw new InvalidKeyException("can't recognise key type in DSA based signer"); 87 } 88 } 89 90 digest.reset(); 91 signer.init(false, param); 92 } 93 94 protected void engineInitSign( 95 PrivateKey privateKey, 96 SecureRandom random) 97 throws InvalidKeyException 98 { 99 this.random = random; 100 engineInitSign(privateKey); 101 } 102 103 protected void engineInitSign( 104 PrivateKey privateKey) 105 throws InvalidKeyException 106 { 107 CipherParameters param; 108 109 param = DSAUtil.generatePrivateKeyParameter(privateKey); 110 111 if (random != null) 112 { 113 param = new ParametersWithRandom(param, random); 114 } 115 116 digest.reset(); 117 signer.init(true, param); 118 } 119 120 protected void engineUpdate( 121 byte b) 122 throws SignatureException 123 { 124 digest.update(b); 125 } 126 127 protected void engineUpdate( 128 byte[] b, 129 int off, 130 int len) 131 throws SignatureException 132 { 133 digest.update(b, off, len); 134 } 135 136 protected byte[] engineSign() 137 throws SignatureException 138 { 139 byte[] hash = new byte[digest.getDigestSize()]; 140 141 digest.doFinal(hash, 0); 142 143 try 144 { 145 BigInteger[] sig = signer.generateSignature(hash); 146 147 return derEncode(sig[0], sig[1]); 148 } 149 catch (Exception e) 150 { 151 throw new SignatureException(e.toString()); 152 } 153 } 154 155 protected boolean engineVerify( 156 byte[] sigBytes) 157 throws SignatureException 158 { 159 byte[] hash = new byte[digest.getDigestSize()]; 160 161 digest.doFinal(hash, 0); 162 163 BigInteger[] sig; 164 165 try 166 { 167 sig = derDecode(sigBytes); 168 } 169 catch (Exception e) 170 { 171 throw new SignatureException("error decoding signature bytes."); 172 } 173 174 return signer.verifySignature(hash, sig[0], sig[1]); 175 } 176 177 protected void engineSetParameter( 178 AlgorithmParameterSpec params) 179 { 180 throw new UnsupportedOperationException("engineSetParameter unsupported"); 181 } 182 183 /** 184 * @deprecated replaced with <a href = "#engineSetParameter(java.security.spec.AlgorithmParameterSpec)"> 185 */ 186 protected void engineSetParameter( 187 String param, 188 Object value) 189 { 190 throw new UnsupportedOperationException("engineSetParameter unsupported"); 191 } 192 193 /** 194 * @deprecated 195 */ 196 protected Object engineGetParameter( 197 String param) 198 { 199 throw new UnsupportedOperationException("engineSetParameter unsupported"); 200 } 201 202 private byte[] derEncode( 203 BigInteger r, 204 BigInteger s) 205 throws IOException 206 { 207 ASN1Integer[] rs = new ASN1Integer[]{ new ASN1Integer(r), new ASN1Integer(s) }; 208 return new DERSequence(rs).getEncoded(ASN1Encoding.DER); 209 } 210 211 private BigInteger[] derDecode( 212 byte[] encoding) 213 throws IOException 214 { 215 ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding); 216 return new BigInteger[]{ 217 ((ASN1Integer)s.getObjectAt(0)).getValue(), 218 ((ASN1Integer)s.getObjectAt(1)).getValue() 219 }; 220 } 221 222 static public class stdDSA 223 extends DSASigner 224 { 225 public stdDSA() 226 { 227 // BEGIN android-changed 228 super(AndroidDigestFactory.getSHA1(), new org.bouncycastle.crypto.signers.DSASigner()); 229 // END android-changed 230 } 231 } 232 233 // BEGIN android-removed 234 // static public class detDSA 235 // extends DSASigner 236 // { 237 // public detDSA() 238 // { 239 // super(new SHA1Digest(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(new SHA1Digest()))); 240 // } 241 // } 242 // END android-removed 243 244 static public class dsa224 245 extends DSASigner 246 { 247 public dsa224() 248 { 249 // BEGIN android-changed 250 super(AndroidDigestFactory.getSHA224(), new org.bouncycastle.crypto.signers.DSASigner()); 251 // END android-changed 252 } 253 } 254 255 // BEGIN android-removed 256 // static public class detDSA224 257 // extends DSASigner 258 // { 259 // public detDSA224() 260 // { 261 // super(new SHA224Digest(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(new SHA224Digest()))); 262 // } 263 // } 264 // END android-removed 265 266 static public class dsa256 267 extends DSASigner 268 { 269 public dsa256() 270 { 271 // BEGIN android-changed 272 super(AndroidDigestFactory.getSHA256(), new org.bouncycastle.crypto.signers.DSASigner()); 273 // END android-changed 274 } 275 } 276 277 // BEGIN android-removed 278 // static public class detDSA256 279 // extends DSASigner 280 // { 281 // public detDSA256() 282 // { 283 // super(new SHA256Digest(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(new SHA256Digest()))); 284 // } 285 // } 286 // 287 // static public class dsa384 288 // extends DSASigner 289 // { 290 // public dsa384() 291 // { 292 // super(new SHA384Digest(), new org.bouncycastle.crypto.signers.DSASigner()); 293 // } 294 // } 295 // 296 // static public class detDSA384 297 // extends DSASigner 298 // { 299 // public detDSA384() 300 // { 301 // super(new SHA384Digest(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(new SHA384Digest()))); 302 // } 303 // } 304 // 305 // static public class dsa512 306 // extends DSASigner 307 // { 308 // public dsa512() 309 // { 310 // super(new SHA512Digest(), new org.bouncycastle.crypto.signers.DSASigner()); 311 // } 312 // } 313 // 314 // static public class detDSA512 315 // extends DSASigner 316 // { 317 // public detDSA512() 318 // { 319 // super(new SHA512Digest(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(new SHA512Digest()))); 320 // } 321 // } 322 // END android-removed 323 324 static public class noneDSA 325 extends DSASigner 326 { 327 public noneDSA() 328 { 329 super(new NullDigest(), new org.bouncycastle.crypto.signers.DSASigner()); 330 } 331 } 332} 333