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