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