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