Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/rsa/RSASignature.java
38830 views
/*1* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.rsa;2627import java.io.IOException;28import java.nio.ByteBuffer;2930import java.security.*;31import java.security.interfaces.*;32import java.security.spec.AlgorithmParameterSpec;3334import sun.security.rsa.RSAUtil.KeyType;35import sun.security.util.*;36import sun.security.x509.AlgorithmId;3738/**39* PKCS#1 v1.5 RSA signatures with the various message digest algorithms.40* This file contains an abstract base class with all the logic plus41* a nested static class for each of the message digest algorithms42* (see end of the file). We support MD2, MD5, SHA-1, SHA-224, SHA-256,43* SHA-384, SHA-512, SHA-512/224, and SHA-512/256.44*45* @since 1.546* @author Andreas Sterbenz47*/48public abstract class RSASignature extends SignatureSpi {4950// we sign an ASN.1 SEQUENCE of AlgorithmId and digest51// it has the form 30:xx:30:xx:[digestOID]:05:00:04:xx:[digest]52// this means the encoded length is (8 + digestOID.length + digest.length)53private static final int baseLength = 8;5455// object identifier for the message digest algorithm used56private final ObjectIdentifier digestOID;5758// length of the encoded signature blob59private final int encodedLength;6061// message digest implementation we use62private final MessageDigest md;63// flag indicating whether the digest is reset64private boolean digestReset;6566// private key, if initialized for signing67private RSAPrivateKey privateKey;68// public key, if initialized for verifying69private RSAPublicKey publicKey;7071// padding to use, set when the initSign/initVerify is called72private RSAPadding padding;7374/**75* Construct a new RSASignature. Used by subclasses.76*/77RSASignature(String algorithm, ObjectIdentifier digestOID, int oidLength) {78this.digestOID = digestOID;79try {80md = MessageDigest.getInstance(algorithm);81} catch (NoSuchAlgorithmException e) {82throw new ProviderException(e);83}84digestReset = true;85encodedLength = baseLength + oidLength + md.getDigestLength();86}8788// initialize for verification. See JCA doc89@Override90protected void engineInitVerify(PublicKey publicKey)91throws InvalidKeyException {92RSAPublicKey rsaKey = (RSAPublicKey)RSAKeyFactory.toRSAKey(publicKey);93this.privateKey = null;94this.publicKey = rsaKey;95initCommon(rsaKey, null);96}9798// initialize for signing. See JCA doc99@Override100protected void engineInitSign(PrivateKey privateKey)101throws InvalidKeyException {102engineInitSign(privateKey, null);103}104105// initialize for signing. See JCA doc106@Override107protected void engineInitSign(PrivateKey privateKey, SecureRandom random)108throws InvalidKeyException {109RSAPrivateKey rsaKey =110(RSAPrivateKey)RSAKeyFactory.toRSAKey(privateKey);111this.privateKey = rsaKey;112this.publicKey = null;113initCommon(rsaKey, random);114}115116/**117* Init code common to sign and verify.118*/119private void initCommon(RSAKey rsaKey, SecureRandom random)120throws InvalidKeyException {121try {122RSAUtil.checkParamsAgainstType(KeyType.RSA, rsaKey.getParams());123} catch (ProviderException e) {124throw new InvalidKeyException("Invalid key for RSA signatures", e);125}126resetDigest();127int keySize = RSACore.getByteLength(rsaKey);128try {129padding = RSAPadding.getInstance130(RSAPadding.PAD_BLOCKTYPE_1, keySize, random);131} catch (InvalidAlgorithmParameterException iape) {132throw new InvalidKeyException(iape.getMessage());133}134int maxDataSize = padding.getMaxDataSize();135if (encodedLength > maxDataSize) {136throw new InvalidKeyException137("Key is too short for this signature algorithm");138}139}140141/**142* Reset the message digest if it is not already reset.143*/144private void resetDigest() {145if (digestReset == false) {146md.reset();147digestReset = true;148}149}150151/**152* Return the message digest value.153*/154private byte[] getDigestValue() {155digestReset = true;156return md.digest();157}158159// update the signature with the plaintext data. See JCA doc160@Override161protected void engineUpdate(byte b) throws SignatureException {162md.update(b);163digestReset = false;164}165166// update the signature with the plaintext data. See JCA doc167@Override168protected void engineUpdate(byte[] b, int off, int len)169throws SignatureException {170md.update(b, off, len);171digestReset = false;172}173174// update the signature with the plaintext data. See JCA doc175@Override176protected void engineUpdate(ByteBuffer b) {177md.update(b);178digestReset = false;179}180181// sign the data and return the signature. See JCA doc182@Override183protected byte[] engineSign() throws SignatureException {184if (privateKey == null) {185throw new SignatureException("Missing private key");186}187byte[] digest = getDigestValue();188try {189byte[] encoded = encodeSignature(digestOID, digest);190byte[] padded = padding.pad(encoded);191byte[] encrypted = RSACore.rsa(padded, privateKey, true);192return encrypted;193} catch (GeneralSecurityException e) {194throw new SignatureException("Could not sign data", e);195} catch (IOException e) {196throw new SignatureException("Could not encode data", e);197}198}199200// verify the data and return the result. See JCA doc201@Override202protected boolean engineVerify(byte[] sigBytes) throws SignatureException {203if (publicKey == null) {204throw new SignatureException("Missing public key");205}206207if (sigBytes.length != RSACore.getByteLength(publicKey)) {208throw new SignatureException("Signature length not correct: got " +209sigBytes.length + " but was expecting " +210RSACore.getByteLength(publicKey));211}212byte[] digest = getDigestValue();213try {214byte[] decrypted = RSACore.rsa(sigBytes, publicKey);215byte[] unpadded = padding.unpad(decrypted);216byte[] decodedDigest = decodeSignature(digestOID, unpadded);217return MessageDigest.isEqual(digest, decodedDigest);218} catch (javax.crypto.BadPaddingException e) {219// occurs if the app has used the wrong RSA public key220// or if sigBytes is invalid221// return false rather than propagating the exception for222// compatibility/ease of use223return false;224} catch (IOException e) {225throw new SignatureException("Signature encoding error", e);226}227}228229/**230* Encode the digest, return the to-be-signed data.231* Also used by the PKCS#11 provider.232*/233public static byte[] encodeSignature(ObjectIdentifier oid, byte[] digest)234throws IOException {235DerOutputStream out = new DerOutputStream();236new AlgorithmId(oid).encode(out);237out.putOctetString(digest);238DerValue result =239new DerValue(DerValue.tag_Sequence, out.toByteArray());240return result.toByteArray();241}242243/**244* Decode the signature data. Verify that the object identifier matches245* and return the message digest.246*/247public static byte[] decodeSignature(ObjectIdentifier oid, byte[] sig)248throws IOException {249// Enforce strict DER checking for signatures250DerInputStream in = new DerInputStream(sig, 0, sig.length, false);251DerValue[] values = in.getSequence(2);252if ((values.length != 2) || (in.available() != 0)) {253throw new IOException("SEQUENCE length error");254}255AlgorithmId algId = AlgorithmId.parse(values[0]);256if (algId.getOID().equals((Object)oid) == false) {257throw new IOException("ObjectIdentifier mismatch: "258+ algId.getOID());259}260if (algId.getEncodedParams() != null) {261throw new IOException("Unexpected AlgorithmId parameters");262}263byte[] digest = values[1].getOctetString();264return digest;265}266267// set parameter, not supported. See JCA doc268@Deprecated269@Override270protected void engineSetParameter(String param, Object value)271throws InvalidParameterException {272throw new UnsupportedOperationException("setParameter() not supported");273}274275// See JCA doc276@Override277protected void engineSetParameter(AlgorithmParameterSpec params)278throws InvalidAlgorithmParameterException {279if (params != null) {280throw new InvalidAlgorithmParameterException("No parameters accepted");281}282}283284// get parameter, not supported. See JCA doc285@Deprecated286@Override287protected Object engineGetParameter(String param)288throws InvalidParameterException {289throw new UnsupportedOperationException("getParameter() not supported");290}291292// See JCA doc293@Override294protected AlgorithmParameters engineGetParameters() {295return null;296}297298// Nested class for MD2withRSA signatures299public static final class MD2withRSA extends RSASignature {300public MD2withRSA() {301super("MD2", AlgorithmId.MD2_oid, 10);302}303}304305// Nested class for MD5withRSA signatures306public static final class MD5withRSA extends RSASignature {307public MD5withRSA() {308super("MD5", AlgorithmId.MD5_oid, 10);309}310}311312// Nested class for SHA1withRSA signatures313public static final class SHA1withRSA extends RSASignature {314public SHA1withRSA() {315super("SHA-1", AlgorithmId.SHA_oid, 7);316}317}318319// Nested class for SHA224withRSA signatures320public static final class SHA224withRSA extends RSASignature {321public SHA224withRSA() {322super("SHA-224", AlgorithmId.SHA224_oid, 11);323}324}325326// Nested class for SHA256withRSA signatures327public static final class SHA256withRSA extends RSASignature {328public SHA256withRSA() {329super("SHA-256", AlgorithmId.SHA256_oid, 11);330}331}332333// Nested class for SHA384withRSA signatures334public static final class SHA384withRSA extends RSASignature {335public SHA384withRSA() {336super("SHA-384", AlgorithmId.SHA384_oid, 11);337}338}339340// Nested class for SHA512withRSA signatures341public static final class SHA512withRSA extends RSASignature {342public SHA512withRSA() {343super("SHA-512", AlgorithmId.SHA512_oid, 11);344}345}346347// Nested class for SHA512/224withRSA signatures348public static final class SHA512_224withRSA extends RSASignature {349public SHA512_224withRSA() {350super("SHA-512/224", AlgorithmId.SHA512_224_oid, 11);351}352}353354// Nested class for SHA512/256withRSA signatures355public static final class SHA512_256withRSA extends RSASignature {356public SHA512_256withRSA() {357super("SHA-512/256", AlgorithmId.SHA512_256_oid, 11);358}359}360}361362363