1 /* 2 * Copyright (c) 2003, 2020, 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 sun.security.rsa; 27 28 import java.io.IOException; 29 import java.nio.ByteBuffer; 30 31 import java.security.*; 32 import java.security.interfaces.*; 33 import java.security.spec.AlgorithmParameterSpec; 34 35 import sun.security.rsa.RSAUtil.KeyType; 36 import sun.security.util.*; 37 import sun.security.x509.AlgorithmId; 38 39 /** 40 * PKCS#1 v1.5 RSA signatures with the various message digest algorithms. 41 * This file contains an abstract base class with all the logic plus 42 * a nested static class for each of the message digest algorithms 43 * (see end of the file). We support MD2, MD5, SHA-1, SHA2 family ( 44 * SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and SHA-512/256), 45 * and SHA3 family (SHA3-224, SHA3-256, SHA3-384, SHA3-512) of digests. 46 * 47 * @since 1.5 48 * @author Andreas Sterbenz 49 */ 50 public abstract class RSASignature extends SignatureSpi { 51 52 // we sign an ASN.1 SEQUENCE of AlgorithmId and digest 53 // it has the form 30:xx:30:xx:[digestOID]:05:00:04:xx:[digest] 54 // this means the encoded length is (8 + digestOID.length + digest.length) 55 private static final int baseLength = 8; 56 57 // object identifier for the message digest algorithm used 58 private final ObjectIdentifier digestOID; 59 60 // length of the encoded signature blob 61 private final int encodedLength; 62 63 // message digest implementation we use 64 private final MessageDigest md; 65 // flag indicating whether the digest is reset 66 private boolean digestReset; 67 68 // private key, if initialized for signing 69 private RSAPrivateKey privateKey; 70 // public key, if initialized for verifying 71 private RSAPublicKey publicKey; 72 73 // padding to use, set when the initSign/initVerify is called 74 private RSAPadding padding; 75 76 /** 77 * Construct a new RSASignature. Used by subclasses. 78 */ 79 RSASignature(String algorithm, ObjectIdentifier digestOID, int oidLength) { 80 this.digestOID = digestOID; 81 try { 82 md = MessageDigest.getInstance(algorithm); 83 } catch (NoSuchAlgorithmException e) { 84 throw new ProviderException(e); 85 } 86 digestReset = true; 87 encodedLength = baseLength + oidLength + md.getDigestLength(); 88 } 89 90 // initialize for verification. See JCA doc 91 @Override 92 protected void engineInitVerify(PublicKey publicKey) 93 throws InvalidKeyException { 94 RSAPublicKey rsaKey = (RSAPublicKey)RSAKeyFactory.toRSAKey(publicKey); 95 this.privateKey = null; 96 this.publicKey = rsaKey; 97 initCommon(rsaKey, null); 98 } 99 100 // initialize for signing. See JCA doc 101 @Override 102 protected void engineInitSign(PrivateKey privateKey) 103 throws InvalidKeyException { 104 engineInitSign(privateKey, null); 105 } 106 107 // initialize for signing. See JCA doc 108 @Override 109 protected void engineInitSign(PrivateKey privateKey, SecureRandom random) 110 throws InvalidKeyException { 111 RSAPrivateKey rsaKey = 112 (RSAPrivateKey)RSAKeyFactory.toRSAKey(privateKey); 113 this.privateKey = rsaKey; 114 this.publicKey = null; 115 initCommon(rsaKey, random); 116 } 117 118 /** 119 * Init code common to sign and verify. 120 */ 121 private void initCommon(RSAKey rsaKey, SecureRandom random) 122 throws InvalidKeyException { 123 try { 124 RSAUtil.checkParamsAgainstType(KeyType.RSA, rsaKey.getParams()); 125 } catch (ProviderException e) { 126 throw new InvalidKeyException("Invalid key for RSA signatures", e); 127 } 128 resetDigest(); 129 int keySize = RSACore.getByteLength(rsaKey); 130 try { 131 padding = RSAPadding.getInstance 132 (RSAPadding.PAD_BLOCKTYPE_1, keySize, random); 133 } catch (InvalidAlgorithmParameterException iape) { 134 throw new InvalidKeyException(iape.getMessage()); 135 } 136 int maxDataSize = padding.getMaxDataSize(); 137 if (encodedLength > maxDataSize) { 138 throw new InvalidKeyException 139 ("Key is too short for this signature algorithm"); 140 } 141 } 142 143 /** 144 * Reset the message digest if it is not already reset. 145 */ 146 private void resetDigest() { 147 if (digestReset == false) { 148 md.reset(); 149 digestReset = true; 150 } 151 } 152 153 /** 154 * Return the message digest value. 155 */ 156 private byte[] getDigestValue() { 157 digestReset = true; 158 return md.digest(); 159 } 160 161 // update the signature with the plaintext data. See JCA doc 162 @Override 163 protected void engineUpdate(byte b) throws SignatureException { 164 md.update(b); 165 digestReset = false; 166 } 167 168 // update the signature with the plaintext data. See JCA doc 169 @Override 170 protected void engineUpdate(byte[] b, int off, int len) 171 throws SignatureException { 172 md.update(b, off, len); 173 digestReset = false; 174 } 175 176 // update the signature with the plaintext data. See JCA doc 177 @Override 178 protected void engineUpdate(ByteBuffer b) { 179 md.update(b); 180 digestReset = false; 181 } 182 183 // sign the data and return the signature. See JCA doc 184 @Override 185 protected byte[] engineSign() throws SignatureException { 186 if (privateKey == null) { 187 throw new SignatureException("Missing private key"); 188 } 189 byte[] digest = getDigestValue(); 190 try { 191 byte[] encoded = encodeSignature(digestOID, digest); 192 byte[] padded = padding.pad(encoded); 193 byte[] encrypted = RSACore.rsa(padded, privateKey, true); 194 return encrypted; 195 } catch (GeneralSecurityException e) { 196 throw new SignatureException("Could not sign data", e); 197 } catch (IOException e) { 198 throw new SignatureException("Could not encode data", e); 199 } 200 } 201 202 // verify the data and return the result. See JCA doc 203 // should be reset to the state after engineInitVerify call. 204 @Override 205 protected boolean engineVerify(byte[] sigBytes) throws SignatureException { 206 if (publicKey == null) { 207 throw new SignatureException("Missing public key"); 208 } 209 try { 210 if (sigBytes.length != RSACore.getByteLength(publicKey)) { 211 throw new SignatureException("Signature length not correct: got " + 212 sigBytes.length + " but was expecting " + 213 RSACore.getByteLength(publicKey)); 214 } 215 byte[] digest = getDigestValue(); 216 byte[] decrypted = RSACore.rsa(sigBytes, publicKey); 217 byte[] unpadded = padding.unpad(decrypted); 218 byte[] decodedDigest = decodeSignature(digestOID, unpadded); 219 return MessageDigest.isEqual(digest, decodedDigest); 220 } catch (javax.crypto.BadPaddingException e) { 221 // occurs if the app has used the wrong RSA public key 222 // or if sigBytes is invalid 223 // return false rather than propagating the exception for 224 // compatibility/ease of use 225 return false; 226 } catch (IOException e) { 227 throw new SignatureException("Signature encoding error", e); 228 } finally { 229 resetDigest(); 230 } 231 } 232 233 /** 234 * Encode the digest, return the to-be-signed data. 235 * Also used by the PKCS#11 provider. 236 */ 237 public static byte[] encodeSignature(ObjectIdentifier oid, byte[] digest) 238 throws IOException { 239 DerOutputStream out = new DerOutputStream(); 240 new AlgorithmId(oid).encode(out); 241 out.putOctetString(digest); 242 DerValue result = 243 new DerValue(DerValue.tag_Sequence, out.toByteArray()); 244 return result.toByteArray(); 245 } 246 247 /** 248 * Decode the signature data. Verify that the object identifier matches 249 * and return the message digest. 250 */ 251 public static byte[] decodeSignature(ObjectIdentifier oid, byte[] sig) 252 throws IOException { 253 // Enforce strict DER checking for signatures 254 DerInputStream in = new DerInputStream(sig, 0, sig.length, false); 255 DerValue[] values = in.getSequence(2); 256 if ((values.length != 2) || (in.available() != 0)) { 257 throw new IOException("SEQUENCE length error"); 258 } 259 AlgorithmId algId = AlgorithmId.parse(values[0]); 260 if (algId.getOID().equals(oid) == false) { 261 throw new IOException("ObjectIdentifier mismatch: " 262 + algId.getOID()); 263 } 264 if (algId.getEncodedParams() != null) { 265 throw new IOException("Unexpected AlgorithmId parameters"); 266 } 267 byte[] digest = values[1].getOctetString(); 268 return digest; 269 } 270 271 // set parameter, not supported. See JCA doc 272 @Deprecated 273 @Override 274 protected void engineSetParameter(String param, Object value) 275 throws InvalidParameterException { 276 throw new UnsupportedOperationException("setParameter() not supported"); 277 } 278 279 // See JCA doc 280 @Override 281 protected void engineSetParameter(AlgorithmParameterSpec params) 282 throws InvalidAlgorithmParameterException { 283 if (params != null) { 284 throw new InvalidAlgorithmParameterException("No parameters accepted"); 285 } 286 } 287 288 // get parameter, not supported. See JCA doc 289 @Deprecated 290 @Override 291 protected Object engineGetParameter(String param) 292 throws InvalidParameterException { 293 throw new UnsupportedOperationException("getParameter() not supported"); 294 } 295 296 // See JCA doc 297 @Override 298 protected AlgorithmParameters engineGetParameters() { 299 return null; 300 } 301 302 // Nested class for MD2withRSA signatures 303 public static final class MD2withRSA extends RSASignature { 304 public MD2withRSA() { 305 super("MD2", AlgorithmId.MD2_oid, 10); 306 } 307 } 308 309 // Nested class for MD5withRSA signatures 310 public static final class MD5withRSA extends RSASignature { 311 public MD5withRSA() { 312 super("MD5", AlgorithmId.MD5_oid, 10); 313 } 314 } 315 316 // Nested class for SHA1withRSA signatures 317 public static final class SHA1withRSA extends RSASignature { 318 public SHA1withRSA() { 319 super("SHA-1", AlgorithmId.SHA_oid, 7); 320 } 321 } 322 323 // Nested class for SHA224withRSA signatures 324 public static final class SHA224withRSA extends RSASignature { 325 public SHA224withRSA() { 326 super("SHA-224", AlgorithmId.SHA224_oid, 11); 327 } 328 } 329 330 // Nested class for SHA256withRSA signatures 331 public static final class SHA256withRSA extends RSASignature { 332 public SHA256withRSA() { 333 super("SHA-256", AlgorithmId.SHA256_oid, 11); 334 } 335 } 336 337 // Nested class for SHA384withRSA signatures 338 public static final class SHA384withRSA extends RSASignature { 339 public SHA384withRSA() { 340 super("SHA-384", AlgorithmId.SHA384_oid, 11); 341 } 342 } 343 344 // Nested class for SHA512withRSA signatures 345 public static final class SHA512withRSA extends RSASignature { 346 public SHA512withRSA() { 347 super("SHA-512", AlgorithmId.SHA512_oid, 11); 348 } 349 } 350 351 // Nested class for SHA512/224withRSA signatures 352 public static final class SHA512_224withRSA extends RSASignature { 353 public SHA512_224withRSA() { 354 super("SHA-512/224", AlgorithmId.SHA512_224_oid, 11); 355 } 356 } 357 358 // Nested class for SHA512/256withRSA signatures 359 public static final class SHA512_256withRSA extends RSASignature { 360 public SHA512_256withRSA() { 361 super("SHA-512/256", AlgorithmId.SHA512_256_oid, 11); 362 } 363 } 364 365 // Nested class for SHA3-224withRSA signatures 366 public static final class SHA3_224withRSA extends RSASignature { 367 public SHA3_224withRSA() { 368 super("SHA3-224", AlgorithmId.SHA3_224_oid, 11); 369 } 370 } 371 372 // Nested class for SHA3-256withRSA signatures 373 public static final class SHA3_256withRSA extends RSASignature { 374 public SHA3_256withRSA() { 375 super("SHA3-256", AlgorithmId.SHA3_256_oid, 11); 376 } 377 } 378 379 // Nested class for SHA3-384withRSA signatures 380 public static final class SHA3_384withRSA extends RSASignature { 381 public SHA3_384withRSA() { 382 super("SHA3-384", AlgorithmId.SHA3_384_oid, 11); 383 } 384 } 385 386 // Nested class for SHA3-512withRSA signatures 387 public static final class SHA3_512withRSA extends RSASignature { 388 public SHA3_512withRSA() { 389 super("SHA3-512", AlgorithmId.SHA3_512_oid, 11); 390 } 391 } 392 }