1 /* 2 * Copyright (c) 1997, 2013, 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 * 48 * 49 * @see Signature 50 */ 51 52 public abstract class SignatureSpi { 53 54 /** 55 * Application-specified source of randomness. 56 */ 57 protected SecureRandom appRandom = null; 58 59 /** 60 * Initializes this signature object with the specified 61 * public key for verification operations. 62 * 63 * @param publicKey the public key of the identity whose signature is 64 * going to be verified. 65 * 66 * @exception InvalidKeyException if the key is improperly 67 * encoded, parameters are missing, and so on. 68 */ 69 protected abstract void engineInitVerify(PublicKey publicKey) 70 throws InvalidKeyException; 71 72 /** 73 * Initializes this signature object with the specified 74 * private key for signing operations. 75 * 76 * @param privateKey the private key of the identity whose signature 77 * will be generated. 78 * 79 * @exception InvalidKeyException if the key is improperly 80 * encoded, parameters are missing, and so on. 81 */ 82 protected abstract void engineInitSign(PrivateKey privateKey) 83 throws InvalidKeyException; 84 85 /** 86 * Initializes this signature object with the specified 87 * private key and source of randomness for signing operations. 88 * 89 * <p>This concrete method has been added to this previously-defined 90 * abstract class. (For backwards compatibility, it cannot be abstract.) 91 * 92 * @param privateKey the private key of the identity whose signature 93 * will be generated. 94 * @param random the source of randomness 95 * 96 * @exception InvalidKeyException if the key is improperly 97 * encoded, parameters are missing, and so on. 98 */ 99 protected void engineInitSign(PrivateKey privateKey, 100 SecureRandom random) 101 throws InvalidKeyException { 102 this.appRandom = random; 103 engineInitSign(privateKey); 104 } 105 106 /** 107 * Updates the data to be signed or verified 108 * using the specified byte. 109 * 110 * @param b the byte to use for the update. 111 * 112 * @exception SignatureException if the engine is not initialized 113 * properly. 114 */ 115 protected abstract void engineUpdate(byte b) throws SignatureException; 116 117 /** 118 * Updates the data to be signed or verified, using the 119 * specified array of bytes, starting at the specified offset. 120 * 121 * @param b the array of bytes 122 * @param off the offset to start from in the array of bytes 123 * @param len the number of bytes to use, starting at offset 124 * 125 * @exception SignatureException if the engine is not initialized 126 * properly 127 */ 128 protected abstract void engineUpdate(byte[] b, int off, int len) 129 throws SignatureException; 130 131 /** 132 * Updates the data to be signed or verified using the specified 133 * ByteBuffer. Processes the {@code data.remaining()} bytes 134 * starting at at {@code data.position()}. 135 * Upon return, the buffer's position will be equal to its limit; 136 * its limit will not have changed. 137 * 138 * @param input the ByteBuffer 139 * @since 1.5 140 */ 141 protected void engineUpdate(ByteBuffer input) { 142 if (input.hasRemaining() == false) { 143 return; 144 } 145 try { 146 if (input.hasArray()) { 147 byte[] b = input.array(); 148 int ofs = input.arrayOffset(); 149 int pos = input.position(); 150 int lim = input.limit(); 151 engineUpdate(b, ofs + pos, lim - pos); 152 input.position(lim); 153 } else { 154 int len = input.remaining(); 155 byte[] b = new byte[JCAUtil.getTempArraySize(len)]; 156 while (len > 0) { 157 int chunk = Math.min(len, b.length); 158 input.get(b, 0, chunk); 159 engineUpdate(b, 0, chunk); 160 len -= chunk; 161 } 162 } 163 } catch (SignatureException e) { 164 // is specified to only occur when the engine is not initialized 165 // this case should never occur as it is caught in Signature.java 166 throw new ProviderException("update() failed", e); 167 } 168 } 169 170 /** 171 * Returns the signature bytes of all the data 172 * updated so far. 173 * The format of the signature depends on the underlying 174 * signature scheme. 175 * 176 * @return the signature bytes of the signing operation's result. 177 * 178 * @exception SignatureException if the engine is not 179 * initialized properly or if this signature algorithm is unable to 180 * process the input data provided. 181 */ 182 protected abstract byte[] engineSign() throws SignatureException; 183 184 /** 185 * Finishes this signature operation and stores the resulting signature 186 * bytes in the provided buffer {@code outbuf}, starting at 187 * {@code offset}. 188 * The format of the signature depends on the underlying 189 * signature scheme. 190 * 191 * <p>The signature implementation is reset to its initial state 192 * (the state it was in after a call to one of the 193 * {@code engineInitSign} methods) 194 * and can be reused to generate further signatures with the same private 195 * key. 196 * 197 * This method should be abstract, but we leave it concrete for 198 * binary compatibility. Knowledgeable providers should override this 199 * method. 200 * 201 * @param outbuf buffer for the signature result. 202 * 203 * @param offset offset into {@code outbuf} where the signature is 204 * stored. 205 * 206 * @param len number of bytes within {@code outbuf} allotted for the 207 * signature. 208 * Both this default implementation and the SUN provider do not 209 * return partial digests. If the value of this parameter is less 210 * than the actual signature length, this method will throw a 211 * SignatureException. 212 * This parameter is ignored if its value is greater than or equal to 213 * the actual signature length. 214 * 215 * @return the number of bytes placed into {@code outbuf} 216 * 217 * @exception SignatureException if the engine is not 218 * initialized properly, if this signature algorithm is unable to 219 * process the input data provided, or if {@code len} is less 220 * than the actual signature length. 221 * 222 * @since 1.2 223 */ 224 protected int engineSign(byte[] outbuf, int offset, int len) 225 throws SignatureException { 226 byte[] sig = engineSign(); 227 if (len < sig.length) { 228 throw new SignatureException 229 ("partial signatures not returned"); 230 } 231 if (outbuf.length - offset < sig.length) { 232 throw new SignatureException 233 ("insufficient space in the output buffer to store the " 234 + "signature"); 235 } 236 System.arraycopy(sig, 0, outbuf, offset, sig.length); 237 return sig.length; 238 } 239 240 /** 241 * Verifies the passed-in signature. 242 * 243 * @param sigBytes the signature bytes to be verified. 244 * 245 * @return true if the signature was verified, false if not. 246 * 247 * @exception SignatureException if the engine is not 248 * initialized properly, the passed-in signature is improperly 249 * encoded or of the wrong type, if this signature algorithm is unable to 250 * process the input data provided, etc. 251 */ 252 protected abstract boolean engineVerify(byte[] sigBytes) 253 throws SignatureException; 254 255 /** 256 * Verifies the passed-in signature in the specified array 257 * of bytes, starting at the specified offset. 258 * 259 * <p> Note: Subclasses should overwrite the default implementation. 260 * 261 * 262 * @param sigBytes the signature bytes to be verified. 263 * @param offset the offset to start from in the array of bytes. 264 * @param length the number of bytes to use, starting at offset. 265 * 266 * @return true if the signature was verified, false if not. 267 * 268 * @exception SignatureException if the engine is not 269 * initialized properly, the passed-in signature is improperly 270 * encoded or of the wrong type, if this signature algorithm is unable to 271 * process the input data provided, etc. 272 * @since 1.4 273 */ 274 protected boolean engineVerify(byte[] sigBytes, int offset, int length) 275 throws SignatureException { 276 byte[] sigBytesCopy = new byte[length]; 277 System.arraycopy(sigBytes, offset, sigBytesCopy, 0, length); 278 return engineVerify(sigBytesCopy); 279 } 280 281 /** 282 * Sets the specified algorithm parameter to the specified 283 * value. This method supplies a general-purpose mechanism through 284 * which it is possible to set the various parameters of this object. 285 * A parameter may be any settable parameter for the algorithm, such as 286 * a parameter size, or a source of random bits for signature generation 287 * (if appropriate), or an indication of whether or not to perform 288 * a specific but optional computation. A uniform algorithm-specific 289 * naming scheme for each parameter is desirable but left unspecified 290 * at this time. 291 * 292 * @param param the string identifier of the parameter. 293 * 294 * @param value the parameter value. 295 * 296 * @exception InvalidParameterException if {@code param} is an 297 * invalid parameter for this signature algorithm engine, 298 * the parameter is already set 299 * and cannot be set again, a security exception occurs, and so on. 300 * 301 * @deprecated Replaced by {@link 302 * #engineSetParameter(java.security.spec.AlgorithmParameterSpec) 303 * engineSetParameter}. 304 */ 305 @Deprecated 306 protected abstract void engineSetParameter(String param, Object value) 307 throws InvalidParameterException; 308 309 /** 310 * <p>This method is overridden by providers to initialize 311 * this signature engine with the specified parameter set. 312 * 313 * @param params the parameters 314 * 315 * @exception UnsupportedOperationException if this method is not 316 * overridden by a provider 317 * 318 * @exception InvalidAlgorithmParameterException if this method is 319 * overridden by a provider and the given parameters 320 * are inappropriate for this signature engine 321 */ 322 protected void engineSetParameter(AlgorithmParameterSpec params) 323 throws InvalidAlgorithmParameterException { 324 throw new UnsupportedOperationException(); 325 } 326 327 /** 328 * <p>This method is overridden by providers to return the 329 * parameters used with this signature engine, or null 330 * if this signature engine does not use any parameters. 331 * 332 * <p>The returned parameters may be the same that were used to initialize 333 * this signature engine, or may contain a combination of default and 334 * randomly generated parameter values used by the underlying signature 335 * implementation if this signature engine requires algorithm parameters 336 * but was not initialized with any. 337 * 338 * @return the parameters used with this signature engine, or null if this 339 * signature engine does not use any parameters 340 * 341 * @exception UnsupportedOperationException if this method is 342 * not overridden by a provider 343 * @since 1.4 344 */ 345 protected AlgorithmParameters engineGetParameters() { 346 throw new UnsupportedOperationException(); 347 } 348 349 /** 350 * Gets the value of the specified algorithm parameter. 351 * This method supplies a general-purpose mechanism through which it 352 * is possible to get the various parameters of this object. A parameter 353 * may be any settable parameter for the algorithm, such as a parameter 354 * size, or a source of random bits for signature generation (if 355 * appropriate), or an indication of whether or not to perform a 356 * specific but optional computation. A uniform algorithm-specific 357 * naming scheme for each parameter is desirable but left unspecified 358 * at this time. 359 * 360 * @param param the string name of the parameter. 361 * 362 * @return the object that represents the parameter value, or null if 363 * there is none. 364 * 365 * @exception InvalidParameterException if {@code param} is an 366 * invalid parameter for this engine, or another exception occurs while 367 * trying to get this parameter. 368 * 369 * @deprecated 370 */ 371 @Deprecated 372 protected abstract Object engineGetParameter(String param) 373 throws InvalidParameterException; 374 375 /** 376 * Returns a clone if the implementation is cloneable. 377 * 378 * @return a clone if the implementation is cloneable. 379 * 380 * @exception CloneNotSupportedException if this is called 381 * on an implementation that does not support {@code Cloneable}. 382 */ 383 public Object clone() throws CloneNotSupportedException { 384 if (this instanceof Cloneable) { 385 return super.clone(); 386 } else { 387 throw new CloneNotSupportedException(); 388 } 389 } 390 }