1package org.bouncycastle.jcajce.provider.asymmetric.ec; 2 3import java.io.IOException; 4import java.math.BigInteger; 5import java.security.InvalidKeyException; 6import java.security.PrivateKey; 7import java.security.PublicKey; 8 9import org.bouncycastle.asn1.ASN1EncodableVector; 10import org.bouncycastle.asn1.ASN1Encoding; 11import org.bouncycastle.asn1.ASN1Integer; 12import org.bouncycastle.asn1.ASN1Primitive; 13import org.bouncycastle.asn1.ASN1Sequence; 14import org.bouncycastle.asn1.DERSequence; 15import org.bouncycastle.crypto.CipherParameters; 16import org.bouncycastle.crypto.DSA; 17import org.bouncycastle.crypto.Digest; 18import org.bouncycastle.crypto.digests.NullDigest; 19// BEGIN android-added 20import org.bouncycastle.crypto.digests.AndroidDigestFactory; 21// END android-added 22// BEGIN android-removed 23// import org.bouncycastle.crypto.digests.RIPEMD160Digest; 24// import org.bouncycastle.crypto.digests.SHA1Digest; 25// import org.bouncycastle.crypto.digests.SHA224Digest; 26// import org.bouncycastle.crypto.digests.SHA256Digest; 27// import org.bouncycastle.crypto.digests.SHA384Digest; 28// import org.bouncycastle.crypto.digests.SHA512Digest; 29// END android-removed 30import org.bouncycastle.crypto.params.ParametersWithRandom; 31import org.bouncycastle.crypto.signers.ECDSASigner; 32// BEGIN android-removed 33// import org.bouncycastle.crypto.signers.ECNRSigner; 34// import org.bouncycastle.crypto.signers.HMacDSAKCalculator; 35// END android-removed 36import org.bouncycastle.jcajce.provider.asymmetric.util.DSABase; 37import org.bouncycastle.jcajce.provider.asymmetric.util.DSAEncoder; 38import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; 39 40public class SignatureSpi 41 extends DSABase 42{ 43 SignatureSpi(Digest digest, DSA signer, DSAEncoder encoder) 44 { 45 super(digest, signer, encoder); 46 } 47 48 protected void engineInitVerify(PublicKey publicKey) 49 throws InvalidKeyException 50 { 51 CipherParameters param = ECUtil.generatePublicKeyParameter(publicKey); 52 53 digest.reset(); 54 signer.init(false, param); 55 } 56 57 protected void engineInitSign( 58 PrivateKey privateKey) 59 throws InvalidKeyException 60 { 61 CipherParameters param = ECUtil.generatePrivateKeyParameter(privateKey); 62 63 digest.reset(); 64 65 if (appRandom != null) 66 { 67 signer.init(true, new ParametersWithRandom(param, appRandom)); 68 } 69 else 70 { 71 signer.init(true, param); 72 } 73 } 74 75 static public class ecDSA 76 extends SignatureSpi 77 { 78 public ecDSA() 79 { 80 // BEGIN android-changed 81 super(AndroidDigestFactory.getSHA1(), new ECDSASigner(), new StdDSAEncoder()); 82 // END android-changed 83 } 84 } 85 86 // BEGIN android-removed 87 // static public class ecDetDSA 88 // extends SignatureSpi 89 // { 90 // public ecDetDSA() 91 // { 92 // super(new SHA1Digest(), new ECDSASigner(new HMacDSAKCalculator(new SHA1Digest())), new StdDSAEncoder()); 93 // } 94 // } 95 // END android-removed 96 97 static public class ecDSAnone 98 extends SignatureSpi 99 { 100 public ecDSAnone() 101 { 102 super(new NullDigest(), new ECDSASigner(), new StdDSAEncoder()); 103 } 104 } 105 106 static public class ecDSA224 107 extends SignatureSpi 108 { 109 public ecDSA224() 110 { 111 // BEGIN android-changed 112 super(AndroidDigestFactory.getSHA224(), new ECDSASigner(), new StdDSAEncoder()); 113 // END android-changed 114 } 115 } 116 117 // BEGIN android-removed 118 // static public class ecDetDSA224 119 // extends SignatureSpi 120 // { 121 // public ecDetDSA224() 122 // { 123 // super(new SHA224Digest(), new ECDSASigner(new HMacDSAKCalculator(new SHA224Digest())), new StdDSAEncoder()); 124 // } 125 // } 126 // END android-removed 127 128 static public class ecDSA256 129 extends SignatureSpi 130 { 131 public ecDSA256() 132 { 133 // BEGIN android-changed 134 super(AndroidDigestFactory.getSHA256(), new ECDSASigner(), new StdDSAEncoder()); 135 // END android-changed 136 } 137 } 138 139 // BEGIN android-removed 140 // static public class ecDetDSA256 141 // extends SignatureSpi 142 // { 143 // public ecDetDSA256() 144 // { 145 // super(new SHA256Digest(), new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest())), new StdDSAEncoder()); 146 // } 147 // } 148 // END android-removed 149 150 static public class ecDSA384 151 extends SignatureSpi 152 { 153 public ecDSA384() 154 { 155 // BEGIN android-changed 156 super(AndroidDigestFactory.getSHA384(), new ECDSASigner(), new StdDSAEncoder()); 157 // END android-changed 158 } 159 } 160 161 // BEGIN android-removed 162 // static public class ecDetDSA384 163 // extends SignatureSpi 164 // { 165 // public ecDetDSA384() 166 // { 167 // super(new SHA384Digest(), new ECDSASigner(new HMacDSAKCalculator(new SHA384Digest())), new StdDSAEncoder()); 168 // } 169 // } 170 // END android-removed 171 172 static public class ecDSA512 173 extends SignatureSpi 174 { 175 public ecDSA512() 176 { 177 // BEGIN android-changed 178 super(AndroidDigestFactory.getSHA512(), new ECDSASigner(), new StdDSAEncoder()); 179 // END android-changed 180 } 181 } 182 183 // BEGIN android-removed 184 // static public class ecDetDSA512 185 // extends SignatureSpi 186 // { 187 // public ecDetDSA512() 188 // { 189 // super(new SHA512Digest(), new ECDSASigner(new HMacDSAKCalculator(new SHA512Digest())), new StdDSAEncoder()); 190 // } 191 // } 192 // 193 // static public class ecDSARipeMD160 194 // extends SignatureSpi 195 // { 196 // public ecDSARipeMD160() 197 // { 198 // super(new RIPEMD160Digest(), new ECDSASigner(), new StdDSAEncoder()); 199 // } 200 // } 201 // 202 // static public class ecNR 203 // extends SignatureSpi 204 // { 205 // public ecNR() 206 // { 207 // super(new SHA1Digest(), new ECNRSigner(), new StdDSAEncoder()); 208 // } 209 // } 210 // 211 // static public class ecNR224 212 // extends SignatureSpi 213 // { 214 // public ecNR224() 215 // { 216 // super(new SHA224Digest(), new ECNRSigner(), new StdDSAEncoder()); 217 // } 218 // } 219 // 220 // static public class ecNR256 221 // extends SignatureSpi 222 // { 223 // public ecNR256() 224 // { 225 // super(new SHA256Digest(), new ECNRSigner(), new StdDSAEncoder()); 226 // } 227 // } 228 // 229 // static public class ecNR384 230 // extends SignatureSpi 231 // { 232 // public ecNR384() 233 // { 234 // super(new SHA384Digest(), new ECNRSigner(), new StdDSAEncoder()); 235 // } 236 // } 237 // 238 // static public class ecNR512 239 // extends SignatureSpi 240 // { 241 // public ecNR512() 242 // { 243 // super(new SHA512Digest(), new ECNRSigner(), new StdDSAEncoder()); 244 // } 245 // } 246 // 247 // static public class ecCVCDSA 248 // extends SignatureSpi 249 // { 250 // public ecCVCDSA() 251 // { 252 // super(new SHA1Digest(), new ECDSASigner(), new CVCDSAEncoder()); 253 // } 254 // } 255 // 256 // static public class ecCVCDSA224 257 // extends SignatureSpi 258 // { 259 // public ecCVCDSA224() 260 // { 261 // super(new SHA224Digest(), new ECDSASigner(), new CVCDSAEncoder()); 262 // } 263 // } 264 // 265 // static public class ecCVCDSA256 266 // extends SignatureSpi 267 // { 268 // public ecCVCDSA256() 269 // { 270 // super(new SHA256Digest(), new ECDSASigner(), new CVCDSAEncoder()); 271 // } 272 // } 273 // 274 // static public class ecCVCDSA384 275 // extends SignatureSpi 276 // { 277 // public ecCVCDSA384() 278 // { 279 // super(new SHA384Digest(), new ECDSASigner(), new CVCDSAEncoder()); 280 // } 281 // } 282 // 283 // static public class ecCVCDSA512 284 // extends SignatureSpi 285 // { 286 // public ecCVCDSA512() 287 // { 288 // super(new SHA512Digest(), new ECDSASigner(), new CVCDSAEncoder()); 289 // } 290 // } 291 // END android-removed 292 293 private static class StdDSAEncoder 294 implements DSAEncoder 295 { 296 public byte[] encode( 297 BigInteger r, 298 BigInteger s) 299 throws IOException 300 { 301 ASN1EncodableVector v = new ASN1EncodableVector(); 302 303 v.add(new ASN1Integer(r)); 304 v.add(new ASN1Integer(s)); 305 306 return new DERSequence(v).getEncoded(ASN1Encoding.DER); 307 } 308 309 public BigInteger[] decode( 310 byte[] encoding) 311 throws IOException 312 { 313 ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding); 314 BigInteger[] sig = new BigInteger[2]; 315 316 sig[0] = ASN1Integer.getInstance(s.getObjectAt(0)).getValue(); 317 sig[1] = ASN1Integer.getInstance(s.getObjectAt(1)).getValue(); 318 319 return sig; 320 } 321 } 322 323 private static class CVCDSAEncoder 324 implements DSAEncoder 325 { 326 public byte[] encode( 327 BigInteger r, 328 BigInteger s) 329 throws IOException 330 { 331 byte[] first = makeUnsigned(r); 332 byte[] second = makeUnsigned(s); 333 byte[] res; 334 335 if (first.length > second.length) 336 { 337 res = new byte[first.length * 2]; 338 } 339 else 340 { 341 res = new byte[second.length * 2]; 342 } 343 344 System.arraycopy(first, 0, res, res.length / 2 - first.length, first.length); 345 System.arraycopy(second, 0, res, res.length - second.length, second.length); 346 347 return res; 348 } 349 350 351 private byte[] makeUnsigned(BigInteger val) 352 { 353 byte[] res = val.toByteArray(); 354 355 if (res[0] == 0) 356 { 357 byte[] tmp = new byte[res.length - 1]; 358 359 System.arraycopy(res, 1, tmp, 0, tmp.length); 360 361 return tmp; 362 } 363 364 return res; 365 } 366 367 public BigInteger[] decode( 368 byte[] encoding) 369 throws IOException 370 { 371 BigInteger[] sig = new BigInteger[2]; 372 373 byte[] first = new byte[encoding.length / 2]; 374 byte[] second = new byte[encoding.length / 2]; 375 376 System.arraycopy(encoding, 0, first, 0, first.length); 377 System.arraycopy(encoding, first.length, second, 0, second.length); 378 379 sig[0] = new BigInteger(1, first); 380 sig[1] = new BigInteger(1, second); 381 382 return sig; 383 } 384 } 385} 386