1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package java.security; 19 20 import java.nio.ByteBuffer; 21 import java.security.spec.AlgorithmParameterSpec; 22 23 /** 24 * {@code SignatureSpi} is the <i>Service Provider Interface</i> (<b>SPI</b>) 25 * definition for {@link Signature}. 26 * 27 * @see Signature 28 */ 29 public abstract class SignatureSpi { 30 31 /** 32 * Implementation specific source of randomness. 33 */ 34 protected SecureRandom appRandom; 35 36 /** 37 * Initializes this {@code SignatureSpi} instance for signature 38 * verification, using the public key of the identity whose signature is 39 * going to be verified. 40 * 41 * @param publicKey 42 * the public key. 43 * @throws InvalidKeyException 44 * if {@code publicKey} is not valid. 45 */ engineInitVerify(PublicKey publicKey)46 protected abstract void engineInitVerify(PublicKey publicKey) 47 throws InvalidKeyException; 48 49 /** 50 * Initializes this {@code SignatureSpi} instance for signing, using the 51 * private key of the identity whose signature is going to be generated. 52 * 53 * @param privateKey 54 * the private key. 55 * @throws InvalidKeyException 56 * if {@code privateKey} is not valid. 57 */ engineInitSign(PrivateKey privateKey)58 protected abstract void engineInitSign(PrivateKey privateKey) 59 throws InvalidKeyException; 60 61 /** 62 * Initializes this {@code SignatureSpi} instance for signing, using the 63 * private key of the identity whose signature is going to be generated and 64 * the specified source of randomness. 65 * 66 * @param privateKey 67 * the private key. 68 * @param random 69 * the {@code SecureRandom} to use. 70 * @throws InvalidKeyException 71 * if {@code privateKey} is not valid. 72 */ engineInitSign(PrivateKey privateKey, SecureRandom random)73 protected void engineInitSign(PrivateKey privateKey, SecureRandom random) 74 throws InvalidKeyException { 75 appRandom = random; 76 engineInitSign(privateKey); 77 } 78 79 /** 80 * Updates the data to be verified or to be signed, using the specified 81 * {@code byte}. 82 * 83 * @param b 84 * the byte to update with. 85 * @throws SignatureException 86 * if this {@code SignatureSpi} instance is not initialized 87 * properly. 88 */ engineUpdate(byte b)89 protected abstract void engineUpdate(byte b) throws SignatureException; 90 91 /** 92 * Updates the data to be verified or to be signed, using the given {@code 93 * byte[]}, starting form the specified index for the specified length. 94 * 95 * @param b 96 * the byte array to update with. 97 * @param off 98 * the start index in {@code b} of the data. 99 * @param len 100 * the number of bytes to use. 101 * @throws SignatureException 102 * if this {@code SignatureSpi} instance is not initialized 103 * properly. 104 */ engineUpdate(byte[] b, int off, int len)105 protected abstract void engineUpdate(byte[] b, int off, int len) 106 throws SignatureException; 107 108 /** 109 * Updates the data to be verified or to be signed, using the specified 110 * {@code ByteBuffer}. 111 * 112 * @param input 113 * the {@code ByteBuffer} to update with. 114 * @throws RuntimeException 115 * since {@code SignatureException} is not specified for this 116 * method it throws a {@code RuntimeException} if underlying 117 * {@link #engineUpdate(byte[], int, int)} throws {@code 118 * SignatureException}. 119 */ engineUpdate(ByteBuffer input)120 protected void engineUpdate(ByteBuffer input) { 121 if (!input.hasRemaining()) { 122 return; 123 } 124 byte[] tmp; 125 if (input.hasArray()) { 126 tmp = input.array(); 127 int offset = input.arrayOffset(); 128 int position = input.position(); 129 int limit = input.limit(); 130 try { 131 engineUpdate(tmp, offset + position, limit - position); 132 } catch (SignatureException e) { 133 throw new RuntimeException(e); //Wrap SignatureException 134 } 135 input.position(limit); 136 } else { 137 tmp = new byte[input.limit() - input.position()]; 138 input.get(tmp); 139 try { 140 engineUpdate(tmp, 0, tmp.length); 141 } catch (SignatureException e) { 142 throw new RuntimeException(e); //Wrap SignatureException 143 } 144 } 145 } 146 147 /** 148 * Generates and returns the signature of all updated data. 149 * <p> 150 * This {@code SignatureSpi} instance is reset to the state of its last 151 * initialization for signing and thus can be used for another signature 152 * from the same identity. 153 * 154 * @return the signature of all updated data. 155 * @throws SignatureException 156 * if this {@code SignatureSpi} instance is not initialized 157 * properly. 158 */ engineSign()159 protected abstract byte[] engineSign() throws SignatureException; 160 161 /** 162 * Generates and stores the signature of all updated data in the provided 163 * {@code byte[]} at the specified position with the specified length. 164 * <p> 165 * This {@code SignatureSpi} instance is reset to the state of its last 166 * initialization for signing and thus can be used for another signature 167 * from the same identity. 168 * 169 * @param outbuf 170 * the buffer to store the signature. 171 * @param offset 172 * the index of the first byte in {@code outbuf} to store. 173 * @param len 174 * the number of bytes allocated for the signature. 175 * @return the number of bytes stored in {@code outbuf}. 176 * @throws SignatureException 177 * if this {@code SignatureSpi} instance is not initialized 178 * properly. 179 * @throws IllegalArgumentException 180 * if {@code offset} or {@code len} are not valid in respect to 181 * {@code outbuf}. 182 */ engineSign(byte[] outbuf, int offset, int len)183 protected int engineSign(byte[] outbuf, int offset, int len) throws SignatureException { 184 byte[] tmp = engineSign(); 185 if (tmp == null) { 186 return 0; 187 } 188 if (len < tmp.length) { 189 throw new SignatureException("The value of len parameter is less than the actual signature length"); 190 } 191 if (offset < 0) { 192 throw new SignatureException("offset < 0"); 193 } 194 if (offset + len > outbuf.length) { 195 throw new SignatureException("offset + len > outbuf.length"); 196 } 197 System.arraycopy(tmp, 0, outbuf, offset, tmp.length); 198 return tmp.length; 199 } 200 201 /** 202 * Indicates whether the given {@code sigBytes} can be verified using the 203 * public key or a certificate of the signer. 204 * <p> 205 * This {@code SignatureSpi} instance is reset to the state of its last 206 * initialization for verifying and thus can be used to verify another 207 * signature of the same signer. 208 * 209 * @param sigBytes 210 * the signature to verify. 211 * @return {@code true} if the signature was verified, {@code false} 212 * otherwise. 213 * @throws SignatureException 214 * if this {@code SignatureSpi} instance is not initialized 215 * properly. 216 */ engineVerify(byte[] sigBytes)217 protected abstract boolean engineVerify(byte[] sigBytes) 218 throws SignatureException; 219 220 /** 221 * Indicates whether the given {@code sigBytes} starting at index {@code 222 * offset} with {@code length} bytes can be verified using the public key or 223 * a certificate of the signer. 224 * <p> 225 * This {@code SignatureSpi} instance is reset to the state of its last 226 * initialization for verifying and thus can be used to verify another 227 * signature of the same signer. 228 * 229 * @param sigBytes 230 * the {@code byte[]} containing the signature to verify. 231 * @param offset 232 * the start index in {@code sigBytes} of the signature 233 * @param length 234 * the number of bytes allocated for the signature. 235 * @return {@code true} if the signature was verified, {@code false} 236 * otherwise. 237 * @throws SignatureException 238 * if this {@code SignatureSpi} instance is not initialized 239 * properly. 240 * @throws IllegalArgumentException 241 * if {@code offset} or {@code length} are not valid in respect 242 * to {@code sigBytes}. 243 */ engineVerify(byte[] sigBytes, int offset, int length)244 protected boolean engineVerify(byte[] sigBytes, int offset, int length) 245 throws SignatureException { 246 byte[] tmp = new byte[length]; 247 System.arraycopy(sigBytes, offset, tmp, 0, length); 248 return engineVerify(tmp); 249 } 250 251 /** 252 * Sets the specified parameter to the given value. 253 * 254 * @param param 255 * the name of the parameter. 256 * @param value 257 * the parameter value. 258 * @throws InvalidParameterException 259 * if the parameter is invalid, already set or is not allowed to 260 * be changed. 261 * @deprecated Use {@link #engineSetParameter(AlgorithmParameterSpec)} 262 */ 263 @Deprecated engineSetParameter(String param, Object value)264 protected abstract void engineSetParameter(String param, Object value) 265 throws InvalidParameterException; 266 267 /** 268 * Sets the specified {@code AlgorithmParameterSpec}. 269 * 270 * @param params 271 * the parameter to set. 272 * @throws InvalidAlgorithmParameterException 273 * if the parameter is invalid, already set or is not allowed to 274 * be changed. 275 */ engineSetParameter(AlgorithmParameterSpec params)276 protected void engineSetParameter(AlgorithmParameterSpec params) 277 throws InvalidAlgorithmParameterException { 278 throw new UnsupportedOperationException(); 279 } 280 281 /** 282 * Returns the {@code AlgorithmParameters} of this {@link SignatureSpi} 283 * instance. 284 * 285 * @return the {@code AlgorithmParameters} of this {@link SignatureSpi} 286 * instance, maybe {@code null}. 287 */ engineGetParameters()288 protected AlgorithmParameters engineGetParameters() { 289 throw new UnsupportedOperationException(); 290 } 291 292 /** 293 * Returns the value of the parameter with the specified name. 294 * 295 * @param param 296 * the name of the requested parameter value. 297 * @return the value of the parameter with the specified name, maybe {@code 298 * null}. 299 * @throws InvalidParameterException 300 * if {@code param} is not a valid parameter for this {@code 301 * SignatureSpi} or an other error occurs. 302 * @deprecated There is no generally accepted parameter naming convention. 303 */ 304 @Deprecated engineGetParameter(String param)305 protected abstract Object engineGetParameter(String param) 306 throws InvalidParameterException; 307 308 @Override clone()309 public Object clone() throws CloneNotSupportedException { 310 return super.clone(); 311 } 312 } 313