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