1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 package java.security; 28 29 import java.security.spec.AlgorithmParameterSpec; 30 import java.util.*; 31 import java.io.*; 32 33 import java.nio.ByteBuffer; 34 35 import sun.security.jca.JCAUtil; 36 37 /** 38 * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) 39 * for the {@code Signature} class, which is used to provide the 40 * functionality of a digital signature algorithm. Digital signatures are used 41 * for authentication and integrity assurance of digital data. 42 *. 43 * <p> All the abstract methods in this class must be implemented by each 44 * cryptographic service provider who wishes to supply the implementation 45 * of a particular signature algorithm. 46 * 47 * @author Benjamin Renaud 48 * 49 * 50 * @see Signature 51 */ 52 53 public abstract class SignatureSpi { 54 55 /** 56 * Application-specified source of randomness. 57 */ 58 protected SecureRandom appRandom = null; 59 60 /** 61 * Initializes this signature object with the specified 62 * public key for verification operations. 63 * 64 * @param publicKey the public key of the identity whose signature is 65 * going to be verified. 66 * 67 * @exception InvalidKeyException if the key is improperly 68 * encoded, parameters are missing, and so on. 69 */ engineInitVerify(PublicKey publicKey)70 protected abstract void engineInitVerify(PublicKey publicKey) 71 throws InvalidKeyException; 72 73 /** 74 * Initializes this signature object with the specified 75 * private key for signing operations. 76 * 77 * @param privateKey the private key of the identity whose signature 78 * will be generated. 79 * 80 * @exception InvalidKeyException if the key is improperly 81 * encoded, parameters are missing, and so on. 82 */ engineInitSign(PrivateKey privateKey)83 protected abstract void engineInitSign(PrivateKey privateKey) 84 throws InvalidKeyException; 85 86 /** 87 * Initializes this signature object with the specified 88 * private key and source of randomness for signing operations. 89 * 90 * <p>This concrete method has been added to this previously-defined 91 * abstract class. (For backwards compatibility, it cannot be abstract.) 92 * 93 * @param privateKey the private key of the identity whose signature 94 * will be generated. 95 * @param random the source of randomness 96 * 97 * @exception InvalidKeyException if the key is improperly 98 * encoded, parameters are missing, and so on. 99 */ engineInitSign(PrivateKey privateKey, SecureRandom random)100 protected void engineInitSign(PrivateKey privateKey, 101 SecureRandom random) 102 throws InvalidKeyException { 103 this.appRandom = random; 104 engineInitSign(privateKey); 105 } 106 107 /** 108 * Updates the data to be signed or verified 109 * using the specified byte. 110 * 111 * @param b the byte to use for the update. 112 * 113 * @exception SignatureException if the engine is not initialized 114 * properly. 115 */ engineUpdate(byte b)116 protected abstract void engineUpdate(byte b) throws SignatureException; 117 118 /** 119 * Updates the data to be signed or verified, using the 120 * specified array of bytes, starting at the specified offset. 121 * 122 * @param b the array of bytes 123 * @param off the offset to start from in the array of bytes 124 * @param len the number of bytes to use, starting at offset 125 * 126 * @exception SignatureException if the engine is not initialized 127 * properly 128 */ engineUpdate(byte[] b, int off, int len)129 protected abstract void engineUpdate(byte[] b, int off, int len) 130 throws SignatureException; 131 132 /** 133 * Updates the data to be signed or verified using the specified 134 * ByteBuffer. Processes the {@code data.remaining()} bytes 135 * starting at at {@code data.position()}. 136 * Upon return, the buffer's position will be equal to its limit; 137 * its limit will not have changed. 138 * 139 * @param input the ByteBuffer 140 * @since 1.5 141 */ engineUpdate(ByteBuffer input)142 protected void engineUpdate(ByteBuffer input) { 143 if (input.hasRemaining() == false) { 144 return; 145 } 146 try { 147 if (input.hasArray()) { 148 byte[] b = input.array(); 149 int ofs = input.arrayOffset(); 150 int pos = input.position(); 151 int lim = input.limit(); 152 engineUpdate(b, ofs + pos, lim - pos); 153 input.position(lim); 154 } else { 155 int len = input.remaining(); 156 byte[] b = new byte[JCAUtil.getTempArraySize(len)]; 157 while (len > 0) { 158 int chunk = Math.min(len, b.length); 159 input.get(b, 0, chunk); 160 engineUpdate(b, 0, chunk); 161 len -= chunk; 162 } 163 } 164 } catch (SignatureException e) { 165 // is specified to only occur when the engine is not initialized 166 // this case should never occur as it is caught in Signature.java 167 throw new ProviderException("update() failed", e); 168 } 169 } 170 171 /** 172 * Returns the signature bytes of all the data 173 * updated so far. 174 * The format of the signature depends on the underlying 175 * signature scheme. 176 * 177 * @return the signature bytes of the signing operation's result. 178 * 179 * @exception SignatureException if the engine is not 180 * initialized properly or if this signature algorithm is unable to 181 * process the input data provided. 182 */ engineSign()183 protected abstract byte[] engineSign() throws SignatureException; 184 185 /** 186 * Finishes this signature operation and stores the resulting signature 187 * bytes in the provided buffer {@code outbuf}, starting at 188 * {@code offset}. 189 * The format of the signature depends on the underlying 190 * signature scheme. 191 * 192 * <p>The signature implementation is reset to its initial state 193 * (the state it was in after a call to one of the 194 * {@code engineInitSign} methods) 195 * and can be reused to generate further signatures with the same private 196 * key. 197 * 198 * This method should be abstract, but we leave it concrete for 199 * binary compatibility. Knowledgeable providers should override this 200 * method. 201 * 202 * @param outbuf buffer for the signature result. 203 * 204 * @param offset offset into {@code outbuf} where the signature is 205 * stored. 206 * 207 * @param len number of bytes within {@code outbuf} allotted for the 208 * signature. 209 * Both this default implementation and the SUN provider do not 210 * return partial digests. If the value of this parameter is less 211 * than the actual signature length, this method will throw a 212 * SignatureException. 213 * This parameter is ignored if its value is greater than or equal to 214 * the actual signature length. 215 * 216 * @return the number of bytes placed into {@code outbuf} 217 * 218 * @exception SignatureException if the engine is not 219 * initialized properly, if this signature algorithm is unable to 220 * process the input data provided, or if {@code len} is less 221 * than the actual signature length. 222 * 223 * @since 1.2 224 */ engineSign(byte[] outbuf, int offset, int len)225 protected int engineSign(byte[] outbuf, int offset, int len) 226 throws SignatureException { 227 byte[] sig = engineSign(); 228 if (len < sig.length) { 229 throw new SignatureException 230 ("partial signatures not returned"); 231 } 232 if (outbuf.length - offset < sig.length) { 233 throw new SignatureException 234 ("insufficient space in the output buffer to store the " 235 + "signature"); 236 } 237 System.arraycopy(sig, 0, outbuf, offset, sig.length); 238 return sig.length; 239 } 240 241 /** 242 * Verifies the passed-in signature. 243 * 244 * @param sigBytes the signature bytes to be verified. 245 * 246 * @return true if the signature was verified, false if not. 247 * 248 * @exception SignatureException if the engine is not 249 * initialized properly, the passed-in signature is improperly 250 * encoded or of the wrong type, if this signature algorithm is unable to 251 * process the input data provided, etc. 252 */ engineVerify(byte[] sigBytes)253 protected abstract boolean engineVerify(byte[] sigBytes) 254 throws SignatureException; 255 256 /** 257 * Verifies the passed-in signature in the specified array 258 * of bytes, starting at the specified offset. 259 * 260 * <p> Note: Subclasses should overwrite the default implementation. 261 * 262 * 263 * @param sigBytes the signature bytes to be verified. 264 * @param offset the offset to start from in the array of bytes. 265 * @param length the number of bytes to use, starting at offset. 266 * 267 * @return true if the signature was verified, false if not. 268 * 269 * @exception SignatureException if the engine is not 270 * initialized properly, the passed-in signature is improperly 271 * encoded or of the wrong type, if this signature algorithm is unable to 272 * process the input data provided, etc. 273 * @since 1.4 274 */ engineVerify(byte[] sigBytes, int offset, int length)275 protected boolean engineVerify(byte[] sigBytes, int offset, int length) 276 throws SignatureException { 277 byte[] sigBytesCopy = new byte[length]; 278 System.arraycopy(sigBytes, offset, sigBytesCopy, 0, length); 279 return engineVerify(sigBytesCopy); 280 } 281 282 /** 283 * Sets the specified algorithm parameter to the specified 284 * value. This method supplies a general-purpose mechanism through 285 * which it is possible to set the various parameters of this object. 286 * A parameter may be any settable parameter for the algorithm, such as 287 * a parameter size, or a source of random bits for signature generation 288 * (if appropriate), or an indication of whether or not to perform 289 * a specific but optional computation. A uniform algorithm-specific 290 * naming scheme for each parameter is desirable but left unspecified 291 * at this time. 292 * 293 * @param param the string identifier of the parameter. 294 * 295 * @param value the parameter value. 296 * 297 * @exception InvalidParameterException if {@code param} is an 298 * invalid parameter for this signature algorithm engine, 299 * the parameter is already set 300 * and cannot be set again, a security exception occurs, and so on. 301 * 302 * @deprecated Replaced by {@link 303 * #engineSetParameter(java.security.spec.AlgorithmParameterSpec) 304 * engineSetParameter}. 305 */ 306 @Deprecated engineSetParameter(String param, Object value)307 protected abstract void engineSetParameter(String param, Object value) 308 throws InvalidParameterException; 309 310 /** 311 * <p>This method is overridden by providers to initialize 312 * this signature engine with the specified parameter set. 313 * 314 * @param params the parameters 315 * 316 * @exception UnsupportedOperationException if this method is not 317 * overridden by a provider 318 * 319 * @exception InvalidAlgorithmParameterException if this method is 320 * overridden by a provider and the given parameters 321 * are inappropriate for this signature engine 322 */ engineSetParameter(AlgorithmParameterSpec params)323 protected void engineSetParameter(AlgorithmParameterSpec params) 324 throws InvalidAlgorithmParameterException { 325 throw new UnsupportedOperationException(); 326 } 327 328 /** 329 * <p>This method is overridden by providers to return the 330 * parameters used with this signature engine, or null 331 * if this signature engine does not use any parameters. 332 * 333 * <p>The returned parameters may be the same that were used to initialize 334 * this signature engine, or may contain a combination of default and 335 * randomly generated parameter values used by the underlying signature 336 * implementation if this signature engine requires algorithm parameters 337 * but was not initialized with any. 338 * 339 * @return the parameters used with this signature engine, or null if this 340 * signature engine does not use any parameters 341 * 342 * @exception UnsupportedOperationException if this method is 343 * not overridden by a provider 344 * @since 1.4 345 */ engineGetParameters()346 protected AlgorithmParameters engineGetParameters() { 347 throw new UnsupportedOperationException(); 348 } 349 350 /** 351 * Gets the value of the specified algorithm parameter. 352 * This method supplies a general-purpose mechanism through which it 353 * is possible to get the various parameters of this object. A parameter 354 * may be any settable parameter for the algorithm, such as a parameter 355 * size, or a source of random bits for signature generation (if 356 * appropriate), or an indication of whether or not to perform a 357 * specific but optional computation. A uniform algorithm-specific 358 * naming scheme for each parameter is desirable but left unspecified 359 * at this time. 360 * 361 * @param param the string name of the parameter. 362 * 363 * @return the object that represents the parameter value, or null if 364 * there is none. 365 * 366 * @exception InvalidParameterException if {@code param} is an 367 * invalid parameter for this engine, or another exception occurs while 368 * trying to get this parameter. 369 * 370 * @deprecated Deprecated. 371 */ 372 @Deprecated 373 // Android-changed add "Deprecated." engineGetParameter(String param)374 protected abstract Object engineGetParameter(String param) 375 throws InvalidParameterException; 376 377 /** 378 * Returns a clone if the implementation is cloneable. 379 * 380 * @return a clone if the implementation is cloneable. 381 * 382 * @exception CloneNotSupportedException if this is called 383 * on an implementation that does not support {@code Cloneable}. 384 */ clone()385 public Object clone() throws CloneNotSupportedException { 386 if (this instanceof Cloneable) { 387 return super.clone(); 388 } else { 389 throw new CloneNotSupportedException(); 390 } 391 } 392 } 393