From d3243e3efcf34e720426f8a87e37276c9a601038 Mon Sep 17 00:00:00 2001 From: wetmore Date: Thu, 13 Feb 2020 15:47:52 -0800 Subject: [PATCH] 8230978: Add support for RSASSA-PSS Signature algorithm (Java SE 8) 8175029: StackOverflowError in X509CRL and X509Certificate.verify(PublicKey, Provider) 8146293: Add support for RSASSA-PSS Signature algorithm 8205445: Add RSASSA-PSS Signature support to SunMSCAPI 8205720: KeyFactory#getKeySpec and translateKey throws NullPointerException with Invalid key 8206171: Signature#getParameters for RSASSA-PSS throws ProviderException when not initialized 8213009: Refactoring existing SunMSCAPI classes 8213010: Supporting keys created with certmgr.exe 8214096: sun.security.util.SignatureUtil passes null parameter, so JCE validation fails 8215694: keytool cannot generate RSASSA-PSS certificates 8221407: Windows 32bit build error in libsunmscapi/security.cpp 8216039: TLS with BC and RSASSA-PSS breaks ECDHServerKeyExchange 8223003: SunMSCAPI keys are not cleaned up 8223063: Support CNG RSA keys 8225745: NoSuchAlgorithmException exception for SHA256withECDSA with RSASSA-PSS support 8225180: SignedObject with invalid Key not throwing the InvalidKeyException in Windows 8236470: Deal with ECDSA using ecdsa-with-SHA2 plus hash algorithm as AlgorithmId 8238502: sunmscapi.dll causing EXCEPTION_ACCESS_VIOLATION Summary: Contains elements of JDK-8051408 (see comments on JDK-8230978) Reviewed-by: valeriep, weijun, coffeys, pkoppula, andrew --HG-- rename : src/windows/classes/sun/security/mscapi/Key.java => src/windows/classes/sun/security/mscapi/CKey.java rename : src/windows/classes/sun/security/mscapi/RSAKeyPair.java => src/windows/classes/sun/security/mscapi/CKeyPair.java rename : src/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java => src/windows/classes/sun/security/mscapi/CKeyPairGenerator.java rename : src/windows/classes/sun/security/mscapi/KeyStore.java => src/windows/classes/sun/security/mscapi/CKeyStore.java rename : src/windows/classes/sun/security/mscapi/RSAPrivateKey.java => src/windows/classes/sun/security/mscapi/CPrivateKey.java rename : src/windows/classes/sun/security/mscapi/RSAPublicKey.java => src/windows/classes/sun/security/mscapi/CPublicKey.java rename : src/windows/classes/sun/security/mscapi/RSACipher.java => src/windows/classes/sun/security/mscapi/CRSACipher.java rename : src/windows/classes/sun/security/mscapi/RSASignature.java => src/windows/classes/sun/security/mscapi/CSignature.java --- make/lib/SecurityLibraries.gmk | 4 +- .../sun/crypto/provider/OAEPParameters.java | 6 +- .../com/sun/crypto/provider/RSACipher.java | 14 +- .../com/sun/crypto/provider/SunJCE.java | 6 +- .../classes/java/security/Signature.java | 266 +++- .../classes/java/security/SignatureSpi.java | 104 +- .../classes/java/security/cert/X509CRL.java | 35 +- .../java/security/cert/X509Certificate.java | 27 +- .../java/security/interfaces/RSAKey.java | 23 +- .../RSAMultiPrimePrivateCrtKey.java | 6 +- .../security/interfaces/RSAPrivateCrtKey.java | 5 +- .../security/interfaces/package-info.java | 4 +- .../java/security/spec/MGF1ParameterSpec.java | 54 +- .../java/security/spec/PSSParameterSpec.java | 144 ++- .../security/spec/RSAKeyGenParameterSpec.java | 33 +- .../spec/RSAMultiPrimePrivateCrtKeySpec.java | 152 ++- .../java/security/spec/RSAOtherPrimeInfo.java | 13 +- .../security/spec/RSAPrivateCrtKeySpec.java | 46 +- .../java/security/spec/RSAPrivateKeySpec.java | 32 +- .../java/security/spec/RSAPublicKeySpec.java | 34 +- .../java/security/spec/package-info.java | 4 +- src/share/classes/javax/crypto/Cipher.java | 8 +- .../javax/crypto/spec/OAEPParameterSpec.java | 37 +- .../classes/javax/crypto/spec/PSource.java | 14 +- .../classes/javax/crypto/spec/package.html | 3 +- .../sun/misc/JavaSecuritySignatureAccess.java | 43 + src/share/classes/sun/misc/SharedSecrets.java | 15 +- .../classes/sun/security/ec/CurveDB.java | 21 +- .../sun/security/ec/ECDSASignature.java | 125 +- .../classes/sun/security/pkcs/SignerInfo.java | 33 +- .../classes/sun/security/pkcs10/PKCS10.java | 30 +- .../classes/sun/security/pkcs11/P11Key.java | 15 +- .../sun/security/pkcs11/P11RSAKeyFactory.java | 7 +- .../sun/security/pkcs11/P11Signature.java | 29 +- .../classes/sun/security/provider/DSA.java | 18 +- .../classes/sun/security/provider/SHA5.java | 38 +- .../sun/security/provider/SunEntries.java | 11 +- src/share/classes/sun/security/rsa/MGF1.java | 94 ++ .../sun/security/rsa/PSSParameters.java | 274 ++++ .../sun/security/rsa/RSAKeyFactory.java | 200 ++- .../sun/security/rsa/RSAKeyPairGenerator.java | 56 +- .../sun/security/rsa/RSAPSSSignature.java | 619 +++++++++ .../classes/sun/security/rsa/RSAPadding.java | 73 +- .../security/rsa/RSAPrivateCrtKeyImpl.java | 97 +- .../sun/security/rsa/RSAPrivateKeyImpl.java | 45 +- .../sun/security/rsa/RSAPublicKeyImpl.java | 90 +- .../sun/security/rsa/RSASignature.java | 58 +- .../classes/sun/security/rsa/RSAUtil.java | 162 +++ .../sun/security/rsa/SunRsaSignEntries.java | 40 +- .../sun/security/ssl/RSASignature.java | 15 +- .../classes/sun/security/ssl/SunJSSE.java | 6 +- .../security/tools/keytool/CertAndKeyGen.java | 17 +- .../sun/security/tools/keytool/Main.java | 33 +- .../classes/sun/security/util/ECUtil.java | 77 +- .../util/SecurityProviderConstants.java | 7 +- .../sun/security/util/SignatureUtil.java | 171 +++ .../sun/security/x509/AlgorithmId.java | 169 ++- .../sun/security/x509/X509CRLImpl.java | 56 +- .../sun/security/x509/X509CertImpl.java | 115 +- .../classes/sun/security/mscapi/CKey.java | 155 +++ .../mscapi/{RSAKeyPair.java => CKeyPair.java} | 23 +- .../security/mscapi/CKeyPairGenerator.java | 133 ++ .../mscapi/{KeyStore.java => CKeyStore.java} | 203 ++- .../{RSAPrivateKey.java => CPrivateKey.java} | 67 +- .../sun/security/mscapi/CPublicKey.java | 227 ++++ .../{RSACipher.java => CRSACipher.java} | 30 +- .../sun/security/mscapi/CSignature.java | 954 ++++++++++++++ .../classes/sun/security/mscapi/Key.java | 165 --- .../security/mscapi/RSAKeyPairGenerator.java | 124 -- .../sun/security/mscapi/RSAPublicKey.java | 199 --- .../sun/security/mscapi/RSASignature.java | 524 -------- .../sun/security/mscapi/SunMSCAPI.java | 83 +- .../native/sun/security/mscapi/security.cpp | 1144 +++++++++++------ .../crypto/provider/Cipher/RSA/TestOAEP.java | 50 +- .../provider/Cipher/RSA/TestOAEPPadding.java | 16 +- .../Cipher/RSA/TestOAEPParameterSpec.java | 6 +- .../Cipher/RSA/TestOAEPWithParams.java | 8 +- .../KeyPairGenerator/FinalizeHalf.java | 4 +- test/java/security/Signature/Offsets.java | 25 +- .../Signature/SignatureGetInstance.java | 238 ++++ test/java/security/SignedObject/Chain.java | 73 +- .../security/cert/X509CRL/VerifyDefault.java | 133 ++ .../cert/X509Certificate/VerifyDefault.java | 139 ++ test/java/security/testlibrary/CertUtils.java | 103 +- test/lib/jdk/test/lib/SigTestUtil.java | 150 +++ .../jdk/testlibrary/security/DerUtils.java | 117 ++ test/sun/security/ec/SignedObjectChain.java | 5 +- .../mscapi/InteropWithSunRsaSign.java | 171 +++ test/sun/security/mscapi/KeyAlgorithms.java | 79 ++ test/sun/security/mscapi/NullKey.java | 55 + .../security/mscapi/SignedObjectChain.java | 5 +- test/sun/security/mscapi/VeryLongAlias.java | 134 ++ .../provider/MessageDigest/SHA512.java | 70 + test/sun/security/rsa/SigGen15_186-3.txt | 341 +++++ .../rsa/SigGen15_186-3_TruncatedSHAs.txt | 233 ++++ test/sun/security/rsa/SigRecord.java | 198 +++ test/sun/security/rsa/SignatureOffsets.java | 8 +- test/sun/security/rsa/SignatureTest.java | 95 +- test/sun/security/rsa/SignedObjectChain.java | 10 +- .../security/rsa/TestKeyPairGenerator.java | 45 +- test/sun/security/rsa/TestSigGen15.java | 125 ++ test/sun/security/rsa/TestSignatures.java | 56 +- test/sun/security/rsa/pss/InitAgain.java | 69 + .../security/rsa/pss/PSSParametersTest.java | 123 ++ test/sun/security/rsa/pss/SigGenPSS_186-3.txt | 420 ++++++ .../rsa/pss/SigGenPSS_186-3_TruncatedSHAs.txt | 257 ++++ test/sun/security/rsa/pss/SigRecord.java | 210 +++ test/sun/security/rsa/pss/SignatureTest2.java | 200 +++ .../security/rsa/pss/SignatureTestPSS.java | 193 +++ .../security/rsa/pss/TestPSSKeySupport.java | 152 +++ test/sun/security/rsa/pss/TestSigGenPSS.java | 155 +++ .../security/ssl/rsa/SignedObjectChain.java | 7 +- test/sun/security/tools/keytool/PSS.java | 104 ++ .../security/util/misc/SetNullSigParams.java | 77 ++ .../ECSigParamsVerifyWithCert.java | 91 ++ 115 files changed, 10194 insertions(+), 2520 deletions(-) create mode 100644 src/share/classes/sun/misc/JavaSecuritySignatureAccess.java create mode 100644 src/share/classes/sun/security/rsa/MGF1.java create mode 100644 src/share/classes/sun/security/rsa/PSSParameters.java create mode 100644 src/share/classes/sun/security/rsa/RSAPSSSignature.java create mode 100644 src/share/classes/sun/security/rsa/RSAUtil.java create mode 100644 src/share/classes/sun/security/util/SignatureUtil.java create mode 100644 src/windows/classes/sun/security/mscapi/CKey.java rename src/windows/classes/sun/security/mscapi/{RSAKeyPair.java => CKeyPair.java} (70%) create mode 100644 src/windows/classes/sun/security/mscapi/CKeyPairGenerator.java rename src/windows/classes/sun/security/mscapi/{KeyStore.java => CKeyStore.java} (86%) rename src/windows/classes/sun/security/mscapi/{RSAPrivateKey.java => CPrivateKey.java} (54%) create mode 100644 src/windows/classes/sun/security/mscapi/CPublicKey.java rename src/windows/classes/sun/security/mscapi/{RSACipher.java => CRSACipher.java} (95%) create mode 100644 src/windows/classes/sun/security/mscapi/CSignature.java delete mode 100644 src/windows/classes/sun/security/mscapi/Key.java delete mode 100644 src/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java delete mode 100644 src/windows/classes/sun/security/mscapi/RSAPublicKey.java delete mode 100644 src/windows/classes/sun/security/mscapi/RSASignature.java create mode 100644 test/java/security/Signature/SignatureGetInstance.java create mode 100644 test/java/security/cert/X509CRL/VerifyDefault.java create mode 100644 test/java/security/cert/X509Certificate/VerifyDefault.java create mode 100644 test/lib/jdk/test/lib/SigTestUtil.java create mode 100644 test/lib/testlibrary/jdk/testlibrary/security/DerUtils.java create mode 100644 test/sun/security/mscapi/InteropWithSunRsaSign.java create mode 100644 test/sun/security/mscapi/KeyAlgorithms.java create mode 100644 test/sun/security/mscapi/NullKey.java create mode 100644 test/sun/security/mscapi/VeryLongAlias.java create mode 100644 test/sun/security/provider/MessageDigest/SHA512.java create mode 100644 test/sun/security/rsa/SigGen15_186-3.txt create mode 100644 test/sun/security/rsa/SigGen15_186-3_TruncatedSHAs.txt create mode 100644 test/sun/security/rsa/SigRecord.java create mode 100644 test/sun/security/rsa/TestSigGen15.java create mode 100644 test/sun/security/rsa/pss/InitAgain.java create mode 100644 test/sun/security/rsa/pss/PSSParametersTest.java create mode 100644 test/sun/security/rsa/pss/SigGenPSS_186-3.txt create mode 100644 test/sun/security/rsa/pss/SigGenPSS_186-3_TruncatedSHAs.txt create mode 100644 test/sun/security/rsa/pss/SigRecord.java create mode 100644 test/sun/security/rsa/pss/SignatureTest2.java create mode 100644 test/sun/security/rsa/pss/SignatureTestPSS.java create mode 100644 test/sun/security/rsa/pss/TestPSSKeySupport.java create mode 100644 test/sun/security/rsa/pss/TestSigGenPSS.java create mode 100644 test/sun/security/tools/keytool/PSS.java create mode 100644 test/sun/security/util/misc/SetNullSigParams.java create mode 100644 test/sun/security/x509/X509CertImpl/ECSigParamsVerifyWithCert.java diff --git a/make/lib/SecurityLibraries.gmk b/make/lib/SecurityLibraries.gmk index 2a1721bc1..a8eeceb3c 100644 --- a/make/lib/SecurityLibraries.gmk +++ b/make/lib/SecurityLibraries.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -171,7 +171,7 @@ ifeq ($(OPENJDK_TARGET_OS), windows) -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/mscapi, \ LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := Crypt32.Lib advapi32.lib, \ + LDFLAGS_SUFFIX := Crypt32.Lib advapi32.lib ncrypt.lib, \ VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ RC_FLAGS := $(RC_FLAGS) \ -D "JDK_FNAME=sunmscapi.dll" \ diff --git a/src/share/classes/com/sun/crypto/provider/OAEPParameters.java b/src/share/classes/com/sun/crypto/provider/OAEPParameters.java index 74b3cc408..d3cbae6f5 100644 --- a/src/share/classes/com/sun/crypto/provider/OAEPParameters.java +++ b/src/share/classes/com/sun/crypto/provider/OAEPParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -137,6 +137,10 @@ public final class OAEPParameters extends AlgorithmParametersSpi { mgfSpec = MGF1ParameterSpec.SHA384; } else if (mgfDigestName.equals("SHA-512")) { mgfSpec = MGF1ParameterSpec.SHA512; + } else if (mgfDigestName.equals("SHA-512/224")) { + mgfSpec = MGF1ParameterSpec.SHA512_224; + } else if (mgfDigestName.equals("SHA-512/256")) { + mgfSpec = MGF1ParameterSpec.SHA512_256; } else { throw new IOException( "Unrecognized message digest algorithm"); diff --git a/src/share/classes/com/sun/crypto/provider/RSACipher.java b/src/share/classes/com/sun/crypto/provider/RSACipher.java index 5faefb6bd..1d7baca3f 100644 --- a/src/share/classes/com/sun/crypto/provider/RSACipher.java +++ b/src/share/classes/com/sun/crypto/provider/RSACipher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,13 +44,15 @@ import sun.security.util.KeyUtil; /** * RSA cipher implementation. Supports RSA en/decryption and signing/verifying - * using PKCS#1 v1.5 padding and without padding (raw RSA). Note that raw RSA - * is supported mostly for completeness and should only be used in rare cases. + * using both PKCS#1 v1.5 and OAEP (v2.2) paddings and without padding (raw RSA). + * Note that raw RSA is supported mostly for completeness and should only be + * used in rare cases. * * Objects should be instantiated by calling Cipher.getInstance() using the * following algorithm names: - * . "RSA/ECB/PKCS1Padding" (or "RSA") for PKCS#1 padding. The mode (blocktype) - * is selected based on the en/decryption mode and public/private key used + * . "RSA/ECB/PKCS1Padding" (or "RSA") for PKCS#1 v1.5 padding. + * . "RSA/ECB/OAEPwithandMGF1Padding" (or "RSA/ECB/OAEPPadding") for + * PKCS#1 v2.2 padding. * . "RSA/ECB/NoPadding" for rsa RSA. * * We only do one RSA operation per doFinal() call. If the application passes @@ -81,7 +83,7 @@ public final class RSACipher extends CipherSpi { private final static String PAD_NONE = "NoPadding"; // constant for PKCS#1 v1.5 RSA private final static String PAD_PKCS1 = "PKCS1Padding"; - // constant for PKCS#2 v2.0 OAEP with MGF1 + // constant for PKCS#2 v2.2 OAEP with MGF1 private final static String PAD_OAEP_MGF1 = "OAEP"; // current mode, one of MODE_* above. Set when init() is called diff --git a/src/share/classes/com/sun/crypto/provider/SunJCE.java b/src/share/classes/com/sun/crypto/provider/SunJCE.java index 55c55e2de..efe8031fe 100644 --- a/src/share/classes/com/sun/crypto/provider/SunJCE.java +++ b/src/share/classes/com/sun/crypto/provider/SunJCE.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -131,7 +131,9 @@ public final class SunJCE extends Provider { + "|OAEPWITHSHA-224ANDMGF1PADDING" + "|OAEPWITHSHA-256ANDMGF1PADDING" + "|OAEPWITHSHA-384ANDMGF1PADDING" - + "|OAEPWITHSHA-512ANDMGF1PADDING"); + + "|OAEPWITHSHA-512ANDMGF1PADDING" + + "|OAEPWITHSHA-512/224ANDMGF1PADDING" + + "|OAEPWITHSHA-512/256ANDMGF1PADDING"); put("Cipher.RSA SupportedKeyClasses", "java.security.interfaces.RSAPublicKey" + "|java.security.interfaces.RSAPrivateKey"); diff --git a/src/share/classes/java/security/Signature.java b/src/share/classes/java/security/Signature.java index 5232b9c46..8d8408c49 100644 --- a/src/share/classes/java/security/Signature.java +++ b/src/share/classes/java/security/Signature.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,8 @@ import javax.crypto.CipherSpi; import javax.crypto.IllegalBlockSizeException; import javax.crypto.BadPaddingException; import javax.crypto.NoSuchPaddingException; +import sun.misc.JavaSecuritySignatureAccess; +import sun.misc.SharedSecrets; import sun.security.util.Debug; import sun.security.jca.*; @@ -117,6 +119,34 @@ import sun.security.jca.GetInstance.Instance; public abstract class Signature extends SignatureSpi { + static { + SharedSecrets.setJavaSecuritySignatureAccess( + new JavaSecuritySignatureAccess() { + @Override + public void initVerify(Signature s, PublicKey publicKey, + AlgorithmParameterSpec params) + throws InvalidKeyException, + InvalidAlgorithmParameterException { + s.initVerify(publicKey, params); + } + @Override + public void initVerify(Signature s, + java.security.cert.Certificate certificate, + AlgorithmParameterSpec params) + throws InvalidKeyException, + InvalidAlgorithmParameterException { + s.initVerify(certificate, params); + } + @Override + public void initSign(Signature s, PrivateKey privateKey, + AlgorithmParameterSpec params, SecureRandom random) + throws InvalidKeyException, + InvalidAlgorithmParameterException { + s.initSign(privateKey, params, random); + } + }); + } + private static final Debug debug = Debug.getInstance("jca", "Signature"); @@ -275,6 +305,7 @@ public abstract class Signature extends SignatureSpi { signatureInfo.put("sun.security.rsa.RSASignature$SHA256withRSA", TRUE); signatureInfo.put("sun.security.rsa.RSASignature$SHA384withRSA", TRUE); signatureInfo.put("sun.security.rsa.RSASignature$SHA512withRSA", TRUE); + signatureInfo.put("sun.security.rsa.RSAPSSSignature", TRUE); signatureInfo.put("com.sun.net.ssl.internal.ssl.RSASignature", TRUE); signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE); } @@ -466,6 +497,53 @@ public abstract class Signature extends SignatureSpi { } } + /** + * Initialize this object for verification. If this method is called + * again with different arguments, it negates the effect + * of this call. + * + * @param publicKey the public key of the identity whose signature is + * going to be verified. + * @param params the parameters used for verifying this signature. + * + * @exception InvalidKeyException if the key is invalid. + * @exception InvalidAlgorithmParameterException if the params is invalid. + */ + final void initVerify(PublicKey publicKey, AlgorithmParameterSpec params) + throws InvalidKeyException, InvalidAlgorithmParameterException { + engineInitVerify(publicKey, params); + state = VERIFY; + + if (!skipDebug && pdebug != null) { + pdebug.println("Signature." + algorithm + + " verification algorithm from: " + getProviderName()); + } + } + + private static PublicKey getPublicKeyFromCert(Certificate cert) + throws InvalidKeyException { + // If the certificate is of type X509Certificate, + // we should check whether it has a Key Usage + // extension marked as critical. + //if (cert instanceof java.security.cert.X509Certificate) { + if (cert instanceof X509Certificate) { + // Check whether the cert has a key usage extension + // marked as a critical extension. + // The OID for KeyUsage extension is 2.5.29.15. + X509Certificate c = (X509Certificate)cert; + Set critSet = c.getCriticalExtensionOIDs(); + + if (critSet != null && !critSet.isEmpty() + && critSet.contains("2.5.29.15")) { + boolean[] keyUsageInfo = c.getKeyUsage(); + // keyUsageInfo[0] is for digitalSignature. + if ((keyUsageInfo != null) && (keyUsageInfo[0] == false)) + throw new InvalidKeyException("Wrong key usage"); + } + } + return cert.getPublicKey(); + } + /** * Initializes this object for verification, using the public key from * the given certificate. @@ -486,27 +564,40 @@ public abstract class Signature extends SignatureSpi { */ public final void initVerify(Certificate certificate) throws InvalidKeyException { - // If the certificate is of type X509Certificate, - // we should check whether it has a Key Usage - // extension marked as critical. - if (certificate instanceof java.security.cert.X509Certificate) { - // Check whether the cert has a key usage extension - // marked as a critical extension. - // The OID for KeyUsage extension is 2.5.29.15. - X509Certificate cert = (X509Certificate)certificate; - Set critSet = cert.getCriticalExtensionOIDs(); + engineInitVerify(getPublicKeyFromCert(certificate)); + state = VERIFY; - if (critSet != null && !critSet.isEmpty() - && critSet.contains("2.5.29.15")) { - boolean[] keyUsageInfo = cert.getKeyUsage(); - // keyUsageInfo[0] is for digitalSignature. - if ((keyUsageInfo != null) && (keyUsageInfo[0] == false)) - throw new InvalidKeyException("Wrong key usage"); - } + if (!skipDebug && pdebug != null) { + pdebug.println("Signature." + algorithm + + " verification algorithm from: " + getProviderName()); } + } - PublicKey publicKey = certificate.getPublicKey(); - engineInitVerify(publicKey); + /** + * Initializes this object for verification, using the public key from + * the given certificate. + *

If the certificate is of type X.509 and has a key usage + * extension field marked as critical, and the value of the key usage + * extension field implies that the public key in + * the certificate and its corresponding private key are not + * supposed to be used for digital signatures, an + * {@code InvalidKeyException} is thrown. + * + * @param certificate the certificate of the identity whose signature is + * going to be verified. + * @param params the parameters used for verifying this signature. + * + * @exception InvalidKeyException if the public key in the certificate + * is not encoded properly or does not include required parameter + * information or cannot be used for digital signature purposes. + * @exception InvalidAlgorithmParameterException if the params is invalid. + * + * @since 8 + */ + final void initVerify(Certificate certificate, + AlgorithmParameterSpec params) + throws InvalidKeyException, InvalidAlgorithmParameterException { + engineInitVerify(getPublicKeyFromCert(certificate), params); state = VERIFY; if (!skipDebug && pdebug != null) { @@ -559,6 +650,31 @@ public abstract class Signature extends SignatureSpi { } } + /** + * Initialize this object for signing. If this method is called + * again with different arguments, it negates the effect + * of this call. + * + * @param privateKey the private key of the identity whose signature + * is going to be generated. + * @param params the parameters used for generating signature. + * @param random the source of randomness for this signature. + * + * @exception InvalidKeyException if the key is invalid. + * @exception InvalidAlgorithmParameterException if the params is invalid + */ + final void initSign(PrivateKey privateKey, + AlgorithmParameterSpec params, SecureRandom random) + throws InvalidKeyException, InvalidAlgorithmParameterException { + engineInitSign(privateKey, params, random); + state = SIGN; + + if (!skipDebug && pdebug != null) { + pdebug.println("Signature." + algorithm + + " signing algorithm from: " + getProviderName()); + } + } + /** * Returns the signature bytes of all the data updated. * The format of the signature depends on the underlying @@ -680,7 +796,7 @@ public abstract class Signature extends SignatureSpi { * encoded or of the wrong type, if this signature algorithm is unable to * process the input data provided, etc. * @exception IllegalArgumentException if the {@code signature} - * byte array is null, or the {@code offset} or {@code length} + * byte array is {@code null}, or the {@code offset} or {@code length} * is less than 0, or the sum of the {@code offset} and * {@code length} is greater than the length of the * {@code signature} byte array. @@ -873,14 +989,15 @@ public abstract class Signature extends SignatureSpi { /** * Returns the parameters used with this signature object. * - *

The returned parameters may be the same that were used to initialize - * this signature, or may contain a combination of default and randomly - * generated parameter values used by the underlying signature - * implementation if this signature requires algorithm parameters but - * was not initialized with any. + *

If this signature has been previously initialized with parameters + * (by calling the {@code setParameter} method), this method returns + * the same parameters. If this signature has not been initialized with + * parameters, this method may return a combination of default and + * randomly generated parameter values if the underlying + * signature implementation supports it and can successfully generate + * them. Otherwise, {@code null} is returned. * - * @return the parameters used with this signature, or null if this - * signature does not use any parameters. + * @return the parameters used with this signature, or {@code null} * * @see #setParameter(AlgorithmParameterSpec) * @since 1.4 @@ -901,7 +1018,7 @@ public abstract class Signature extends SignatureSpi { * * @param param the string name of the parameter. * - * @return the object that represents the parameter value, or null if + * @return the object that represents the parameter value, or {@code null} if * there is none. * * @exception InvalidParameterException if {@code param} is an invalid @@ -1086,11 +1203,13 @@ public abstract class Signature extends SignatureSpi { } } - private void chooseProvider(int type, Key key, SecureRandom random) - throws InvalidKeyException { + // Used by engineSetParameter/engineInitSign/engineInitVerify() to + // find the right provider with the supplied key, parameters, random source + private void chooseProvider(int type, Key key, + AlgorithmParameterSpec params, SecureRandom random) + throws InvalidKeyException, InvalidAlgorithmParameterException { synchronized (lock) { if (sigSpi != null) { - init(sigSpi, type, key, random); return; } Exception lastException = null; @@ -1103,7 +1222,7 @@ public abstract class Signature extends SignatureSpi { s = serviceIterator.next(); } // if provider says it does not support this key, ignore it - if (s.supportsParameter(key) == false) { + if (key != null && s.supportsParameter(key) == false) { continue; } // if instance is not a SignatureSpi, ignore it @@ -1112,7 +1231,7 @@ public abstract class Signature extends SignatureSpi { } try { SignatureSpi spi = newInstance(s); - init(spi, type, key, random); + tryOperation(spi, type, key, params, random); provider = s.getProvider(); sigSpi = spi; firstService = null; @@ -1134,6 +1253,10 @@ public abstract class Signature extends SignatureSpi { if (lastException instanceof RuntimeException) { throw (RuntimeException)lastException; } + if (lastException instanceof InvalidAlgorithmParameterException) { + throw (InvalidAlgorithmParameterException)lastException; + } + String k = (key != null) ? key.getClass().getName() : "(null)"; throw new InvalidKeyException ("No installed provider supports this key: " @@ -1141,22 +1264,36 @@ public abstract class Signature extends SignatureSpi { } } - private final static int I_PUB = 1; - private final static int I_PRIV = 2; - private final static int I_PRIV_SR = 3; + private static final int I_PUB = 1; + private static final int I_PRIV = 2; + private static final int I_PRIV_SR = 3; + private static final int I_PUB_PARAM = 4; + private static final int I_PRIV_PARAM_SR = 5; + private static final int S_PARAM = 6; + + private void tryOperation(SignatureSpi spi, int type, Key key, + AlgorithmParameterSpec params, SecureRandom random) + throws InvalidKeyException, InvalidAlgorithmParameterException { - private void init(SignatureSpi spi, int type, Key key, - SecureRandom random) throws InvalidKeyException { switch (type) { case I_PUB: spi.engineInitVerify((PublicKey)key); break; + case I_PUB_PARAM: + spi.engineInitVerify((PublicKey)key, params); + break; case I_PRIV: spi.engineInitSign((PrivateKey)key); break; case I_PRIV_SR: spi.engineInitSign((PrivateKey)key, random); break; + case I_PRIV_PARAM_SR: + spi.engineInitSign((PrivateKey)key, params, random); + break; + case S_PARAM: + spi.engineSetParameter(params); + break; default: throw new AssertionError("Internal error: " + type); } @@ -1167,7 +1304,22 @@ public abstract class Signature extends SignatureSpi { if (sigSpi != null) { sigSpi.engineInitVerify(publicKey); } else { - chooseProvider(I_PUB, publicKey, null); + try { + chooseProvider(I_PUB, publicKey, null, null); + } catch (InvalidAlgorithmParameterException iape) { + // should not happen, re-throw as IKE just in case + throw new InvalidKeyException(iape); + } + } + } + + void engineInitVerify(PublicKey publicKey, + AlgorithmParameterSpec params) + throws InvalidKeyException, InvalidAlgorithmParameterException { + if (sigSpi != null) { + sigSpi.engineInitVerify(publicKey, params); + } else { + chooseProvider(I_PUB_PARAM, publicKey, params, null); } } @@ -1176,7 +1328,12 @@ public abstract class Signature extends SignatureSpi { if (sigSpi != null) { sigSpi.engineInitSign(privateKey); } else { - chooseProvider(I_PRIV, privateKey, null); + try { + chooseProvider(I_PRIV, privateKey, null, null); + } catch (InvalidAlgorithmParameterException iape) { + // should not happen, re-throw as IKE just in case + throw new InvalidKeyException(iape); + } } } @@ -1185,7 +1342,22 @@ public abstract class Signature extends SignatureSpi { if (sigSpi != null) { sigSpi.engineInitSign(privateKey, sr); } else { - chooseProvider(I_PRIV_SR, privateKey, sr); + try { + chooseProvider(I_PRIV_SR, privateKey, null, sr); + } catch (InvalidAlgorithmParameterException iape) { + // should not happen, re-throw as IKE just in case + throw new InvalidKeyException(iape); + } + } + } + + void engineInitSign(PrivateKey privateKey, + AlgorithmParameterSpec params, SecureRandom sr) + throws InvalidKeyException, InvalidAlgorithmParameterException { + if (sigSpi != null) { + sigSpi.engineInitSign(privateKey, params, sr); + } else { + chooseProvider(I_PRIV_PARAM_SR, privateKey, params, sr); } } @@ -1236,8 +1408,16 @@ public abstract class Signature extends SignatureSpi { protected void engineSetParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { - chooseFirstProvider(); - sigSpi.engineSetParameter(params); + if (sigSpi != null) { + sigSpi.engineSetParameter(params); + } else { + try { + chooseProvider(S_PARAM, null, params, null); + } catch (InvalidKeyException ike) { + // should never happen, rethrow just in case + throw new InvalidAlgorithmParameterException(ike); + } + } } protected Object engineGetParameter(String param) diff --git a/src/share/classes/java/security/SignatureSpi.java b/src/share/classes/java/security/SignatureSpi.java index d6d2bc39b..87df4bbaf 100644 --- a/src/share/classes/java/security/SignatureSpi.java +++ b/src/share/classes/java/security/SignatureSpi.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,6 +69,33 @@ public abstract class SignatureSpi { protected abstract void engineInitVerify(PublicKey publicKey) throws InvalidKeyException; + /** + * Initializes this signature object with the specified + * public key for verification operations. + * + * @param publicKey the public key of the identity whose signature is + * going to be verified. + * @param params the parameters for generating this signature + * + * @exception InvalidKeyException if the key is improperly + * encoded, does not work with the given parameters, and so on. + * @exception InvalidAlgorithmParameterException if the given parameters + * is invalid. + */ + void engineInitVerify(PublicKey publicKey, + AlgorithmParameterSpec params) + throws InvalidKeyException, InvalidAlgorithmParameterException { + if (params != null) { + try { + engineSetParameter(params); + } catch (UnsupportedOperationException usoe) { + // error out if not overrridden + throw new InvalidAlgorithmParameterException(usoe); + } + } + engineInitVerify(publicKey); + } + /** * Initializes this signature object with the specified * private key for signing operations. @@ -97,10 +124,41 @@ public abstract class SignatureSpi { * encoded, parameters are missing, and so on. */ protected void engineInitSign(PrivateKey privateKey, - SecureRandom random) - throws InvalidKeyException { - this.appRandom = random; - engineInitSign(privateKey); + SecureRandom random) + throws InvalidKeyException { + this.appRandom = random; + engineInitSign(privateKey); + } + + /** + * Initializes this signature object with the specified + * private key and source of randomness for signing operations. + * + *

This concrete method has been added to this previously-defined + * abstract class. (For backwards compatibility, it cannot be abstract.) + * + * @param privateKey the private key of the identity whose signature + * will be generated. + * @param params the parameters for generating this signature + * @param random the source of randomness + * + * @exception InvalidKeyException if the key is improperly + * encoded, parameters are missing, and so on. + * @exception InvalidAlgorithmParameterException if the parameters is + * invalid. + */ + void engineInitSign(PrivateKey privateKey, + AlgorithmParameterSpec params, SecureRandom random) + throws InvalidKeyException, InvalidAlgorithmParameterException { + if (params != null) { + try { + engineSetParameter(params); + } catch (UnsupportedOperationException usoe) { + // error out if not overrridden + throw new InvalidAlgorithmParameterException(usoe); + } + } + engineInitSign(privateKey, random); } /** @@ -126,7 +184,7 @@ public abstract class SignatureSpi { * properly */ protected abstract void engineUpdate(byte[] b, int off, int len) - throws SignatureException; + throws SignatureException; /** * Updates the data to be signed or verified using the specified @@ -222,7 +280,7 @@ public abstract class SignatureSpi { * @since 1.2 */ protected int engineSign(byte[] outbuf, int offset, int len) - throws SignatureException { + throws SignatureException { byte[] sig = engineSign(); if (len < sig.length) { throw new SignatureException @@ -250,7 +308,7 @@ public abstract class SignatureSpi { * process the input data provided, etc. */ protected abstract boolean engineVerify(byte[] sigBytes) - throws SignatureException; + throws SignatureException; /** * Verifies the passed-in signature in the specified array @@ -272,7 +330,7 @@ public abstract class SignatureSpi { * @since 1.4 */ protected boolean engineVerify(byte[] sigBytes, int offset, int length) - throws SignatureException { + throws SignatureException { byte[] sigBytesCopy = new byte[length]; System.arraycopy(sigBytes, offset, sigBytesCopy, 0, length); return engineVerify(sigBytesCopy); @@ -304,7 +362,7 @@ public abstract class SignatureSpi { */ @Deprecated protected abstract void engineSetParameter(String param, Object value) - throws InvalidParameterException; + throws InvalidParameterException; /** *

This method is overridden by providers to initialize @@ -320,23 +378,23 @@ public abstract class SignatureSpi { * are inappropriate for this signature engine */ protected void engineSetParameter(AlgorithmParameterSpec params) - throws InvalidAlgorithmParameterException { - throw new UnsupportedOperationException(); + throws InvalidAlgorithmParameterException { + throw new UnsupportedOperationException(); } /** - *

This method is overridden by providers to return the - * parameters used with this signature engine, or null - * if this signature engine does not use any parameters. + *

This method is overridden by providers to return the parameters + * used with this signature engine. * - *

The returned parameters may be the same that were used to initialize - * this signature engine, or may contain a combination of default and - * randomly generated parameter values used by the underlying signature - * implementation if this signature engine requires algorithm parameters - * but was not initialized with any. + *

If this signature engine has been previously initialized with + * parameters (by calling the {@code engineSetParameter} method), this + * method returns the same parameters. If this signature engine has not been + * initialized with parameters, this method may return a combination of + * default and randomly generated parameter values if the underlying + * signature implementation supports it and can successfully generate + * them. Otherwise, {@code null} is returned. * - * @return the parameters used with this signature engine, or null if this - * signature engine does not use any parameters + * @return the parameters used with this signature engine, or {@code null} * * @exception UnsupportedOperationException if this method is * not overridden by a provider @@ -359,7 +417,7 @@ public abstract class SignatureSpi { * * @param param the string name of the parameter. * - * @return the object that represents the parameter value, or null if + * @return the object that represents the parameter value, or {@code null} if * there is none. * * @exception InvalidParameterException if {@code param} is an diff --git a/src/share/classes/java/security/cert/X509CRL.java b/src/share/classes/java/security/cert/X509CRL.java index 5ce84847f..0a40f4545 100644 --- a/src/share/classes/java/security/cert/X509CRL.java +++ b/src/share/classes/java/security/cert/X509CRL.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,9 @@ package java.security.cert; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.InvalidKeyException; -import java.security.SignatureException; -import java.security.Principal; -import java.security.Provider; -import java.security.PublicKey; +import java.security.*; +import java.security.spec.*; + import javax.security.auth.x500.X500Principal; import java.math.BigInteger; @@ -40,6 +36,7 @@ import java.util.Set; import java.util.Arrays; import sun.security.x509.X509CRLImpl; +import sun.security.util.SignatureUtil; /** *

@@ -241,7 +238,27 @@ public abstract class X509CRL extends CRL implements X509Extension { public void verify(PublicKey key, Provider sigProvider) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, SignatureException { - X509CRLImpl.verify(this, key, sigProvider); + String sigAlgName = getSigAlgName(); + Signature sig = (sigProvider == null) + ? Signature.getInstance(sigAlgName) + : Signature.getInstance(sigAlgName, sigProvider); + + try { + byte[] paramBytes = getSigAlgParams(); + SignatureUtil.initVerifyWithParam(sig, key, + SignatureUtil.getParamSpec(sigAlgName, paramBytes)); + } catch (ProviderException e) { + throw new CRLException(e.getMessage(), e.getCause()); + } catch (InvalidAlgorithmParameterException e) { + throw new CRLException(e); + } + + byte[] tbsCRL = getTBSCertList(); + sig.update(tbsCRL, 0, tbsCRL.length); + + if (sig.verify(getSignature()) == false) { + throw new SignatureException("Signature does not match."); + } } /** diff --git a/src/share/classes/java/security/cert/X509Certificate.java b/src/share/classes/java/security/cert/X509Certificate.java index 0aba5da60..68afe1ada 100644 --- a/src/share/classes/java/security/cert/X509Certificate.java +++ b/src/share/classes/java/security/cert/X509Certificate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,12 +27,14 @@ package java.security.cert; import java.math.BigInteger; import java.security.*; +import java.security.spec.*; import java.util.Collection; import java.util.Date; import java.util.List; import javax.security.auth.x500.X500Principal; import sun.security.x509.X509CertImpl; +import sun.security.util.SignatureUtil; /** *

@@ -647,7 +649,7 @@ implements X509Extension { return X509CertImpl.getIssuerAlternativeNames(this); } - /** + /** * Verifies that this certificate was signed using the * private key that corresponds to the specified public key. * This method uses the signature verification engine @@ -673,6 +675,25 @@ implements X509Extension { public void verify(PublicKey key, Provider sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, SignatureException { - X509CertImpl.verify(this, key, sigProvider); + String sigName = getSigAlgName(); + Signature sig = (sigProvider == null) + ? Signature.getInstance(sigName) + : Signature.getInstance(sigName, sigProvider); + + try { + SignatureUtil.initVerifyWithParam(sig, key, + SignatureUtil.getParamSpec(sigName, getSigAlgParams())); + } catch (ProviderException e) { + throw new CertificateException(e.getMessage(), e.getCause()); + } catch (InvalidAlgorithmParameterException e) { + throw new CertificateException(e); + } + + byte[] tbsCert = getTBSCertificate(); + sig.update(tbsCert, 0, tbsCert.length); + + if (sig.verify(getSignature()) == false) { + throw new SignatureException("Signature does not match."); + } } } diff --git a/src/share/classes/java/security/interfaces/RSAKey.java b/src/share/classes/java/security/interfaces/RSAKey.java index 67fbe2bf8..5703d669d 100644 --- a/src/share/classes/java/security/interfaces/RSAKey.java +++ b/src/share/classes/java/security/interfaces/RSAKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,9 +26,12 @@ package java.security.interfaces; import java.math.BigInteger; +import java.security.spec.AlgorithmParameterSpec; /** - * The interface to an RSA public or private key. + * The interface to a public or private key in + * PKCS#1 v2.2 standard, + * such as those for RSA, or RSASSA-PSS algorithms. * * @author Jan Luehe * @@ -46,4 +49,20 @@ public interface RSAKey { * @return the modulus */ public BigInteger getModulus(); + + /** + * Returns the parameters associated with this key. + * The parameters are optional and may be either + * explicitly specified or implicitly created during + * key pair generation. + * + * @implSpec + * The default implementation returns {@code null}. + * + * @return the associated parameters, may be null + * @since 8 + */ + default AlgorithmParameterSpec getParams() { + return null; + } } diff --git a/src/share/classes/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java b/src/share/classes/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java index f85d96a76..e9afe9cc9 100644 --- a/src/share/classes/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java +++ b/src/share/classes/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,8 +30,8 @@ import java.security.spec.RSAOtherPrimeInfo; /** * The interface to an RSA multi-prime private key, as defined in the - * PKCS#1 v2.1, using the Chinese Remainder Theorem - * (CRT) information values. + * PKCS#1 v2.2 standard, + * using the Chinese Remainder Theorem (CRT) information values. * * @author Valerie Peng * diff --git a/src/share/classes/java/security/interfaces/RSAPrivateCrtKey.java b/src/share/classes/java/security/interfaces/RSAPrivateCrtKey.java index 0408feabb..4b391c088 100644 --- a/src/share/classes/java/security/interfaces/RSAPrivateCrtKey.java +++ b/src/share/classes/java/security/interfaces/RSAPrivateCrtKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,8 @@ package java.security.interfaces; import java.math.BigInteger; /** - * The interface to an RSA private key, as defined in the PKCS#1 standard, + * The interface to an RSA private key, as defined in the + * PKCS#1 v2.2 standard, * using the Chinese Remainder Theorem (CRT) information values. * * @author Jan Luehe diff --git a/src/share/classes/java/security/interfaces/package-info.java b/src/share/classes/java/security/interfaces/package-info.java index 54c9397e6..808224395 100644 --- a/src/share/classes/java/security/interfaces/package-info.java +++ b/src/share/classes/java/security/interfaces/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ *

Package Specification

* *
    - *
  • PKCS #1: RSA Encryption Standard, Version 1.5, November 1993
  • + *
  • PKCS #1: RSA Cryptography Specifications, Version 2.2 (RFC 8017)
  • *
  • Federal Information Processing Standards Publication (FIPS PUB) 186: * Digital Signature Standard (DSS)
  • *
diff --git a/src/share/classes/java/security/spec/MGF1ParameterSpec.java b/src/share/classes/java/security/spec/MGF1ParameterSpec.java index 1be267f0c..3821b84b5 100644 --- a/src/share/classes/java/security/spec/MGF1ParameterSpec.java +++ b/src/share/classes/java/security/spec/MGF1ParameterSpec.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,23 +29,31 @@ import java.security.spec.AlgorithmParameterSpec; /** * This class specifies the set of parameters used with mask generation - * function MGF1 in OAEP Padding and RSA-PSS signature scheme, as + * function MGF1 in OAEP Padding and RSASSA-PSS signature scheme, as * defined in the - * PKCS #1 v2.1 - * standard. + * PKCS#1 v2.2 standard. * *

Its ASN.1 definition in PKCS#1 standard is described below: *

- * MGF1Parameters ::= OAEP-PSSDigestAlgorthms
+ * PKCS1MGFAlgorithms    ALGORITHM-IDENTIFIER ::= {
+ *   { OID id-mgf1 PARAMETERS HashAlgorithm },
+ *   ...  -- Allows for future expansion --
+ * }
  * 
* where *
+ * HashAlgorithm ::= AlgorithmIdentifier {
+ *   {OAEP-PSSDigestAlgorithms}
+ * }
+ *
  * OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
- *   { OID id-sha1 PARAMETERS NULL   }|
- *   { OID id-sha224 PARAMETERS NULL   }|
- *   { OID id-sha256 PARAMETERS NULL }|
- *   { OID id-sha384 PARAMETERS NULL }|
- *   { OID id-sha512 PARAMETERS NULL },
+ *   { OID id-sha1       PARAMETERS NULL }|
+ *   { OID id-sha224     PARAMETERS NULL }|
+ *   { OID id-sha256     PARAMETERS NULL }|
+ *   { OID id-sha384     PARAMETERS NULL }|
+ *   { OID id-sha512     PARAMETERS NULL }|
+ *   { OID id-sha512-224 PARAMETERS NULL }|
+ *   { OID id-sha512-256 PARAMETERS NULL },
  *   ...  -- Allows for future expansion --
  * }
  * 
@@ -59,31 +67,47 @@ import java.security.spec.AlgorithmParameterSpec; public class MGF1ParameterSpec implements AlgorithmParameterSpec { /** - * The MGF1ParameterSpec which uses "SHA-1" message digest. + * The MGF1ParameterSpec which uses "SHA-1" message digest */ public static final MGF1ParameterSpec SHA1 = new MGF1ParameterSpec("SHA-1"); + /** - * The MGF1ParameterSpec which uses "SHA-224" message digest. + * The MGF1ParameterSpec which uses "SHA-224" message digest */ public static final MGF1ParameterSpec SHA224 = new MGF1ParameterSpec("SHA-224"); + /** - * The MGF1ParameterSpec which uses "SHA-256" message digest. + * The MGF1ParameterSpec which uses "SHA-256" message digest */ public static final MGF1ParameterSpec SHA256 = new MGF1ParameterSpec("SHA-256"); + /** - * The MGF1ParameterSpec which uses "SHA-384" message digest. + * The MGF1ParameterSpec which uses "SHA-384" message digest */ public static final MGF1ParameterSpec SHA384 = new MGF1ParameterSpec("SHA-384"); + /** - * The MGF1ParameterSpec which uses SHA-512 message digest. + * The MGF1ParameterSpec which uses SHA-512 message digest */ public static final MGF1ParameterSpec SHA512 = new MGF1ParameterSpec("SHA-512"); + /** + * The MGF1ParameterSpec which uses SHA-512/224 message digest + */ + public static final MGF1ParameterSpec SHA512_224 = + new MGF1ParameterSpec("SHA-512/224"); + + /** + * The MGF1ParameterSpec which uses SHA-512/256 message digest + */ + public static final MGF1ParameterSpec SHA512_256 = + new MGF1ParameterSpec("SHA-512/256"); + private String mdName; /** diff --git a/src/share/classes/java/security/spec/PSSParameterSpec.java b/src/share/classes/java/security/spec/PSSParameterSpec.java index a9b82d8e4..7e725d759 100644 --- a/src/share/classes/java/security/spec/PSSParameterSpec.java +++ b/src/share/classes/java/security/spec/PSSParameterSpec.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,37 +25,42 @@ package java.security.spec; -import java.math.BigInteger; -import java.security.spec.MGF1ParameterSpec; +import java.util.Objects; /** - * This class specifies a parameter spec for RSA-PSS signature scheme, + * This class specifies a parameter spec for RSASSA-PSS signature scheme, * as defined in the - * PKCS#1 v2.1 - * standard. + * PKCS#1 v2.2 standard. * *

Its ASN.1 definition in PKCS#1 standard is described below: *

  * RSASSA-PSS-params ::= SEQUENCE {
- *   hashAlgorithm      [0] OAEP-PSSDigestAlgorithms  DEFAULT sha1,
- *   maskGenAlgorithm   [1] PKCS1MGFAlgorithms  DEFAULT mgf1SHA1,
- *   saltLength         [2] INTEGER  DEFAULT 20,
- *   trailerField       [3] INTEGER  DEFAULT 1
+ *   hashAlgorithm      [0] HashAlgorithm      DEFAULT sha1,
+ *   maskGenAlgorithm   [1] MaskGenAlgorithm   DEFAULT mgf1SHA1,
+ *   saltLength         [2] INTEGER            DEFAULT 20,
+ *   trailerField       [3] TrailerField       DEFAULT trailerFieldBC(1)
  * }
  * 
* where *
+ * HashAlgorithm ::= AlgorithmIdentifier {
+ *   {OAEP-PSSDigestAlgorithms}
+ * }
+ * MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} }
+ * TrailerField ::= INTEGER { trailerFieldBC(1) }
+ *
  * OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
- *   { OID id-sha1 PARAMETERS NULL   }|
- *   { OID id-sha224 PARAMETERS NULL   }|
- *   { OID id-sha256 PARAMETERS NULL }|
- *   { OID id-sha384 PARAMETERS NULL }|
- *   { OID id-sha512 PARAMETERS NULL },
+ *   { OID id-sha1       PARAMETERS NULL }|
+ *   { OID id-sha224     PARAMETERS NULL }|
+ *   { OID id-sha256     PARAMETERS NULL }|
+ *   { OID id-sha384     PARAMETERS NULL }|
+ *   { OID id-sha512     PARAMETERS NULL }|
+ *   { OID id-sha512-224 PARAMETERS NULL }|
+ *   { OID id-sha512-256 PARAMETERS NULL },
  *   ...  -- Allows for future expansion --
  * }
- *
  * PKCS1MGFAlgorithms    ALGORITHM-IDENTIFIER ::= {
- *   { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
+ *   { OID id-mgf1 PARAMETERS HashAlgorithm },
  *   ...  -- Allows for future expansion --
  * }
  * 
@@ -78,55 +83,62 @@ import java.security.spec.MGF1ParameterSpec; public class PSSParameterSpec implements AlgorithmParameterSpec { - private String mdName = "SHA-1"; - private String mgfName = "MGF1"; - private AlgorithmParameterSpec mgfSpec = MGF1ParameterSpec.SHA1; - private int saltLen = 20; - private int trailerField = 1; + private final String mdName; + + private final String mgfName; + + private final AlgorithmParameterSpec mgfSpec; + + private final int saltLen; + + private final int trailerField; /** - * The PSS parameter set with all default values. - * @since 1.5 + * The {@code TrailerFieldBC} constant as defined in PKCS#1 + * + * @since 8 */ - public static final PSSParameterSpec DEFAULT = new PSSParameterSpec(); + public static final int TRAILER_FIELD_BC = 1; /** - * Constructs a new {@code PSSParameterSpec} as defined in - * the PKCS #1 standard using the default values. + * The PSS parameter set with all default values + * + * @since 1.5 */ + public static final PSSParameterSpec DEFAULT = new PSSParameterSpec + ("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 20, TRAILER_FIELD_BC); + + + // disallowed private PSSParameterSpec() { + throw new RuntimeException("default constructor not allowed"); } + /** * Creates a new {@code PSSParameterSpec} as defined in * the PKCS #1 standard using the specified message digest, * mask generation function, parameters for mask generation * function, salt length, and trailer field values. * - * @param mdName the algorithm name of the hash function. - * @param mgfName the algorithm name of the mask generation - * function. - * @param mgfSpec the parameters for the mask generation - * function. If null is specified, null will be returned by - * getMGFParameters(). - * @param saltLen the length of salt. - * @param trailerField the value of the trailer field. - * @exception NullPointerException if {@code mdName}, - * or {@code mgfName} is null. - * @exception IllegalArgumentException if {@code saltLen} - * or {@code trailerField} is less than 0. + * @param mdName the algorithm name of the hash function + * @param mgfName the algorithm name of the mask generation function + * @param mgfSpec the parameters for the mask generation function. + * If null is specified, null will be returned by + * getMGFParameters(). + * @param saltLen the length of salt + * @param trailerField the value of the trailer field + * @exception NullPointerException if {@code mdName}, or {@code mgfName} + * is null + * @exception IllegalArgumentException if {@code saltLen} or + * {@code trailerField} is less than 0 * @since 1.5 */ public PSSParameterSpec(String mdName, String mgfName, - AlgorithmParameterSpec mgfSpec, - int saltLen, int trailerField) { - if (mdName == null) { - throw new NullPointerException("digest algorithm is null"); - } - if (mgfName == null) { - throw new NullPointerException("mask generation function " + - "algorithm is null"); - } + AlgorithmParameterSpec mgfSpec, int saltLen, int trailerField) { + Objects.requireNonNull(mdName, "digest algorithm is null"); + Objects.requireNonNull(mgfName, + "mask generation function algorithm is null"); if (saltLen < 0) { throw new IllegalArgumentException("negative saltLen value: " + saltLen); @@ -147,23 +159,19 @@ public class PSSParameterSpec implements AlgorithmParameterSpec { * using the specified salt length and other default values as * defined in PKCS#1. * - * @param saltLen the length of salt in bits to be used in PKCS#1 - * PSS encoding. + * @param saltLen the length of salt in bytes to be used in PKCS#1 + * PSS encoding * @exception IllegalArgumentException if {@code saltLen} is - * less than 0. + * less than 0 */ public PSSParameterSpec(int saltLen) { - if (saltLen < 0) { - throw new IllegalArgumentException("negative saltLen value: " + - saltLen); - } - this.saltLen = saltLen; + this("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, saltLen, TRAILER_FIELD_BC); } /** * Returns the message digest algorithm name. * - * @return the message digest algorithm name. + * @return the message digest algorithm name * @since 1.5 */ public String getDigestAlgorithm() { @@ -173,7 +181,7 @@ public class PSSParameterSpec implements AlgorithmParameterSpec { /** * Returns the mask generation function algorithm name. * - * @return the mask generation function algorithm name. + * @return the mask generation function algorithm name * * @since 1.5 */ @@ -184,7 +192,7 @@ public class PSSParameterSpec implements AlgorithmParameterSpec { /** * Returns the parameters for the mask generation function. * - * @return the parameters for the mask generation function. + * @return the parameters for the mask generation function * @since 1.5 */ public AlgorithmParameterSpec getMGFParameters() { @@ -192,21 +200,31 @@ public class PSSParameterSpec implements AlgorithmParameterSpec { } /** - * Returns the salt length in bits. + * Returns the salt length in bytes. * - * @return the salt length. + * @return the salt length */ public int getSaltLength() { return saltLen; } /** - * Returns the value for the trailer field, i.e. bc in PKCS#1 v2.1. + * Returns the value for the trailer field. * - * @return the value for the trailer field, i.e. bc in PKCS#1 v2.1. + * @return the value for the trailer field * @since 1.5 */ public int getTrailerField() { return trailerField; } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("MD: " + mdName + "\n") + .append("MGF: " + mgfSpec + "\n") + .append("SaltLength: " + saltLen + "\n") + .append("TrailerField: " + trailerField + "\n"); + return sb.toString(); + } } diff --git a/src/share/classes/java/security/spec/RSAKeyGenParameterSpec.java b/src/share/classes/java/security/spec/RSAKeyGenParameterSpec.java index a73c6cd46..014af6fe3 100644 --- a/src/share/classes/java/security/spec/RSAKeyGenParameterSpec.java +++ b/src/share/classes/java/security/spec/RSAKeyGenParameterSpec.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,7 @@ public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec { private int keysize; private BigInteger publicExponent; + private AlgorithmParameterSpec keyParams; /** * The public-exponent value F0 = 3. @@ -55,15 +56,30 @@ public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec { public static final BigInteger F4 = BigInteger.valueOf(65537); /** - * Constructs a new {@code RSAParameterSpec} object from the - * given keysize and public-exponent value. + * Constructs a new {@code RSAKeyGenParameterSpec} object from the + * given keysize, public-exponent value, and null key parameters. * * @param keysize the modulus size (specified in number of bits) * @param publicExponent the public exponent */ public RSAKeyGenParameterSpec(int keysize, BigInteger publicExponent) { + this(keysize, publicExponent, null); + } + + /** + * Constructs a new {@code RSAKeyGenParameterSpec} object from the + * given keysize, public-exponent value, and key parameters. + * + * @param keysize the modulus size (specified in number of bits) + * @param publicExponent the public exponent + * @param keyParams the key parameters, may be null + * @since 8 + */ + public RSAKeyGenParameterSpec(int keysize, BigInteger publicExponent, + AlgorithmParameterSpec keyParams) { this.keysize = keysize; this.publicExponent = publicExponent; + this.keyParams = keyParams; } /** @@ -83,4 +99,15 @@ public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec { public BigInteger getPublicExponent() { return publicExponent; } + + /** + * Returns the parameters to be associated with key. + * + * @return the associated parameters, may be null if + * not present + * @since 8 + */ + public AlgorithmParameterSpec getKeyParams() { + return keyParams; + } } diff --git a/src/share/classes/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java b/src/share/classes/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java index a198e43a2..f7bd8832a 100644 --- a/src/share/classes/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java +++ b/src/share/classes/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,11 +26,13 @@ package java.security.spec; import java.math.BigInteger; +import java.util.Objects; /** * This class specifies an RSA multi-prime private key, as defined in the - * PKCS#1 v2.1, using the Chinese Remainder Theorem (CRT) information - * values for efficiency. + * PKCS#1 v2.2 standard + * using the Chinese Remainder Theorem (CRT) information values + * for efficiency. * * @author Valerie Peng * @@ -57,34 +59,28 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec { private final RSAOtherPrimeInfo otherPrimeInfo[]; /** - * Creates a new {@code RSAMultiPrimePrivateCrtKeySpec} - * given the modulus, publicExponent, privateExponent, - * primeP, primeQ, primeExponentP, primeExponentQ, - * crtCoefficient, and otherPrimeInfo as defined in PKCS#1 v2.1. + * Creates a new {@code RSAMultiPrimePrivateCrtKeySpec}. * *

Note that the contents of {@code otherPrimeInfo} * are copied to protect against subsequent modification when * constructing this object. * - * @param modulus the modulus n. - * @param publicExponent the public exponent e. - * @param privateExponent the private exponent d. - * @param primeP the prime factor p of n. - * @param primeQ the prime factor q of n. - * @param primeExponentP this is d mod (p-1). - * @param primeExponentQ this is d mod (q-1). - * @param crtCoefficient the Chinese Remainder Theorem - * coefficient q-1 mod p. - * @param otherPrimeInfo triplets of the rest of primes, null can be - * specified if there are only two prime factors (p and q). - * @exception NullPointerException if any of the parameters, i.e. - * {@code modulus}, - * {@code publicExponent}, {@code privateExponent}, - * {@code primeP}, {@code primeQ}, - * {@code primeExponentP}, {@code primeExponentQ}, - * {@code crtCoefficient}, is null. - * @exception IllegalArgumentException if an empty, i.e. 0-length, - * {@code otherPrimeInfo} is specified. + * @param modulus the modulus n + * @param publicExponent the public exponent e + * @param privateExponent the private exponent d + * @param primeP the prime factor p of n + * @param primeQ the prime factor q of n + * @param primeExponentP this is d mod (p-1) + * @param primeExponentQ this is d mod (q-1) + * @param crtCoefficient the Chinese Remainder Theorem + * coefficient q-1 mod p + * @param otherPrimeInfo triplets of the rest of primes, null can be + * specified if there are only two prime factors + * (p and q) + * @throws NullPointerException if any of the specified parameters + * with the exception of {@code otherPrimeInfo} is null + * @throws IllegalArgumentException if an empty, i.e. 0-length, + * {@code otherPrimeInfo} is specified */ public RSAMultiPrimePrivateCrtKeySpec(BigInteger modulus, BigInteger publicExponent, @@ -95,45 +91,67 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec { BigInteger primeExponentQ, BigInteger crtCoefficient, RSAOtherPrimeInfo[] otherPrimeInfo) { - super(modulus, privateExponent); - if (modulus == null) { - throw new NullPointerException("the modulus parameter must be " + - "non-null"); - } - if (publicExponent == null) { - throw new NullPointerException("the publicExponent parameter " + - "must be non-null"); - } - if (privateExponent == null) { - throw new NullPointerException("the privateExponent parameter " + - "must be non-null"); - } - if (primeP == null) { - throw new NullPointerException("the primeP parameter " + - "must be non-null"); - } - if (primeQ == null) { - throw new NullPointerException("the primeQ parameter " + - "must be non-null"); - } - if (primeExponentP == null) { - throw new NullPointerException("the primeExponentP parameter " + - "must be non-null"); - } - if (primeExponentQ == null) { - throw new NullPointerException("the primeExponentQ parameter " + - "must be non-null"); - } - if (crtCoefficient == null) { - throw new NullPointerException("the crtCoefficient parameter " + - "must be non-null"); - } - this.publicExponent = publicExponent; - this.primeP = primeP; - this.primeQ = primeQ; - this.primeExponentP = primeExponentP; - this.primeExponentQ = primeExponentQ; - this.crtCoefficient = crtCoefficient; + this(modulus, publicExponent, privateExponent, primeP, primeQ, + primeExponentP, primeExponentQ, crtCoefficient, otherPrimeInfo, + null); + } + + /** + * Creates a new {@code RSAMultiPrimePrivateCrtKeySpec} with additional + * key parameters. + * + *

Note that the contents of {@code otherPrimeInfo} + * are copied to protect against subsequent modification when + * constructing this object. + * + * @param modulus the modulus n + * @param publicExponent the public exponent e + * @param privateExponent the private exponent d + * @param primeP the prime factor p of n + * @param primeQ the prime factor q of n + * @param primeExponentP this is d mod (p-1) + * @param primeExponentQ this is d mod (q-1) + * @param crtCoefficient the Chinese Remainder Theorem coefficient + * q-1 mod p + * @param otherPrimeInfo triplets of the rest of primes, null can be + * specified if there are only two prime factors + * (p and q) + * @param keyParams the parameters associated with key + * @throws NullPointerException if any of the specified parameters + * with the exception of {@code otherPrimeInfo} and {@code keyParams} + * is null + * @throws IllegalArgumentException if an empty, i.e. 0-length, + * {@code otherPrimeInfo} is specified + * @since 8 + */ + public RSAMultiPrimePrivateCrtKeySpec(BigInteger modulus, + BigInteger publicExponent, + BigInteger privateExponent, + BigInteger primeP, + BigInteger primeQ, + BigInteger primeExponentP, + BigInteger primeExponentQ, + BigInteger crtCoefficient, + RSAOtherPrimeInfo[] otherPrimeInfo, + AlgorithmParameterSpec keyParams) { + super(modulus, privateExponent, keyParams); + Objects.requireNonNull(modulus, + "the modulus parameter must be non-null"); + Objects.requireNonNull(privateExponent, + "the privateExponent parameter must be non-null"); + this.publicExponent = Objects.requireNonNull(publicExponent, + "the publicExponent parameter must be non-null"); + this.primeP = Objects.requireNonNull(primeP, + "the primeP parameter must be non-null"); + this.primeQ = Objects.requireNonNull(primeQ, + "the primeQ parameter must be non-null"); + this.primeExponentP = Objects.requireNonNull(primeExponentP, + "the primeExponentP parameter must be non-null"); + this.primeExponentQ = Objects.requireNonNull(primeExponentQ, + "the primeExponentQ parameter must be non-null"); + this.crtCoefficient = Objects.requireNonNull(crtCoefficient, + "the crtCoefficient parameter must be non-null"); + if (otherPrimeInfo == null) { this.otherPrimeInfo = null; } else if (otherPrimeInfo.length == 0) { @@ -202,8 +220,8 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec { * Returns a copy of the otherPrimeInfo or null if there are * only two prime factors (p and q). * - * @return the otherPrimeInfo. Returns a new array each - * time this method is called. + * @return the otherPrimeInfo. Returns a new array each time this method + * is called. */ public RSAOtherPrimeInfo[] getOtherPrimeInfo() { if (otherPrimeInfo == null) return null; diff --git a/src/share/classes/java/security/spec/RSAOtherPrimeInfo.java b/src/share/classes/java/security/spec/RSAOtherPrimeInfo.java index 10d847176..99b83a885 100644 --- a/src/share/classes/java/security/spec/RSAOtherPrimeInfo.java +++ b/src/share/classes/java/security/spec/RSAOtherPrimeInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,15 +29,16 @@ import java.math.BigInteger; /** * This class represents the triplet (prime, exponent, and coefficient) - * inside RSA's OtherPrimeInfo structure, as defined in the PKCS#1 v2.1. + * inside RSA's OtherPrimeInfo structure, as defined in the + * PKCS#1 v2.2 standard. * The ASN.1 syntax of RSA's OtherPrimeInfo is as follows: * *

  * OtherPrimeInfo ::= SEQUENCE {
- *   prime INTEGER,
- *   exponent INTEGER,
- *   coefficient INTEGER
- *   }
+ *   prime        INTEGER,
+ *   exponent     INTEGER,
+ *   coefficient  INTEGER
+ * }
  *
  * 
* diff --git a/src/share/classes/java/security/spec/RSAPrivateCrtKeySpec.java b/src/share/classes/java/security/spec/RSAPrivateCrtKeySpec.java index d0ba70be4..f4d618b38 100644 --- a/src/share/classes/java/security/spec/RSAPrivateCrtKeySpec.java +++ b/src/share/classes/java/security/spec/RSAPrivateCrtKeySpec.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,9 +28,9 @@ package java.security.spec; import java.math.BigInteger; /** - * This class specifies an RSA private key, as defined in the PKCS#1 - * standard, using the Chinese Remainder Theorem (CRT) information values for - * efficiency. + * This class specifies an RSA private key, as defined in the + * PKCS#1 v2.2 standard, + * using the Chinese Remainder Theorem (CRT) information values for efficiency. * * @author Jan Luehe * @@ -52,13 +52,8 @@ public class RSAPrivateCrtKeySpec extends RSAPrivateKeySpec { private final BigInteger primeExponentQ; private final BigInteger crtCoefficient; - - /** - * Creates a new {@code RSAPrivateCrtKeySpec} - * given the modulus, publicExponent, privateExponent, - * primeP, primeQ, primeExponentP, primeExponentQ, and - * crtCoefficient as defined in PKCS#1. + * Creates a new {@code RSAPrivateCrtKeySpec}. * * @param modulus the modulus n * @param publicExponent the public exponent e @@ -78,7 +73,36 @@ public class RSAPrivateCrtKeySpec extends RSAPrivateKeySpec { BigInteger primeExponentP, BigInteger primeExponentQ, BigInteger crtCoefficient) { - super(modulus, privateExponent); + this(modulus, publicExponent, privateExponent, primeP, primeQ, + primeExponentP, primeExponentQ, crtCoefficient, null); + } + + /** + * Creates a new {@code RSAPrivateCrtKeySpec} with additional + * key parameters. + * + * @param modulus the modulus n + * @param publicExponent the public exponent e + * @param privateExponent the private exponent d + * @param primeP the prime factor p of n + * @param primeQ the prime factor q of n + * @param primeExponentP this is d mod (p-1) + * @param primeExponentQ this is d mod (q-1) + * @param crtCoefficient the Chinese Remainder Theorem + * coefficient q-1 mod p + * @param keyParams the parameters associated with key + * @since 8 + */ + public RSAPrivateCrtKeySpec(BigInteger modulus, + BigInteger publicExponent, + BigInteger privateExponent, + BigInteger primeP, + BigInteger primeQ, + BigInteger primeExponentP, + BigInteger primeExponentQ, + BigInteger crtCoefficient, + AlgorithmParameterSpec keyParams) { + super(modulus, privateExponent, keyParams); this.publicExponent = publicExponent; this.primeP = primeP; this.primeQ = primeQ; diff --git a/src/share/classes/java/security/spec/RSAPrivateKeySpec.java b/src/share/classes/java/security/spec/RSAPrivateKeySpec.java index e74914616..2bb06c586 100644 --- a/src/share/classes/java/security/spec/RSAPrivateKeySpec.java +++ b/src/share/classes/java/security/spec/RSAPrivateKeySpec.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,8 +43,9 @@ import java.math.BigInteger; public class RSAPrivateKeySpec implements KeySpec { - private BigInteger modulus; - private BigInteger privateExponent; + private final BigInteger modulus; + private final BigInteger privateExponent; + private final AlgorithmParameterSpec params; /** * Creates a new RSAPrivateKeySpec. @@ -53,8 +54,22 @@ public class RSAPrivateKeySpec implements KeySpec { * @param privateExponent the private exponent */ public RSAPrivateKeySpec(BigInteger modulus, BigInteger privateExponent) { + this(modulus, privateExponent, null); + } + + /** + * Creates a new RSAPrivateKeySpec with additional key parameters. + * + * @param modulus the modulus + * @param privateExponent the private exponent + * @param params the parameters associated with this key, may be null + * @since 8 + */ + public RSAPrivateKeySpec(BigInteger modulus, BigInteger privateExponent, + AlgorithmParameterSpec params) { this.modulus = modulus; this.privateExponent = privateExponent; + this.params = params; } /** @@ -74,4 +89,15 @@ public class RSAPrivateKeySpec implements KeySpec { public BigInteger getPrivateExponent() { return this.privateExponent; } + + /** + * Returns the parameters associated with this key, may be null if not + * present. + * + * @return the parameters associated with this key + * @since 8 + */ + public AlgorithmParameterSpec getParams() { + return this.params; + } } diff --git a/src/share/classes/java/security/spec/RSAPublicKeySpec.java b/src/share/classes/java/security/spec/RSAPublicKeySpec.java index 9a944f962..b9ab22462 100644 --- a/src/share/classes/java/security/spec/RSAPublicKeySpec.java +++ b/src/share/classes/java/security/spec/RSAPublicKeySpec.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,8 +43,9 @@ import java.math.BigInteger; public class RSAPublicKeySpec implements KeySpec { - private BigInteger modulus; - private BigInteger publicExponent; + private final BigInteger modulus; + private final BigInteger publicExponent; + private final AlgorithmParameterSpec params; /** * Creates a new RSAPublicKeySpec. @@ -53,10 +54,25 @@ public class RSAPublicKeySpec implements KeySpec { * @param publicExponent the public exponent */ public RSAPublicKeySpec(BigInteger modulus, BigInteger publicExponent) { + this(modulus, publicExponent, null); + } + + /** + * Creates a new RSAPublicKeySpec with additional key parameters. + * + * @param modulus the modulus + * @param publicExponent the public exponent + * @param params the parameters associated with this key, may be null + * @since 8 + */ + public RSAPublicKeySpec(BigInteger modulus, BigInteger publicExponent, + AlgorithmParameterSpec params) { this.modulus = modulus; this.publicExponent = publicExponent; + this.params = params; } + /** * Returns the modulus. * @@ -74,4 +90,16 @@ public class RSAPublicKeySpec implements KeySpec { public BigInteger getPublicExponent() { return this.publicExponent; } + + /** + * Returns the parameters associated with this key, may be null if not + * present. + * + * @return the parameters associated with this key + * @since 8 + */ + public AlgorithmParameterSpec getParams() { + return this.params; + } + } diff --git a/src/share/classes/java/security/spec/package-info.java b/src/share/classes/java/security/spec/package-info.java index cb393088e..ed99a20d4 100644 --- a/src/share/classes/java/security/spec/package-info.java +++ b/src/share/classes/java/security/spec/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ *

Package Specification

* *
    - *
  • PKCS #1: RSA Encryption Standard, Version 1.5, November 1993
  • + *
  • PKCS #1: RSA Cryptography Specifications, Version 2.2 (RFC 8017)
  • *
  • PKCS #8: Private-Key Information Syntax Standard, * Version 1.2, November 1993
  • *
  • Federal Information Processing Standards Publication (FIPS PUB) 186: diff --git a/src/share/classes/javax/crypto/Cipher.java b/src/share/classes/javax/crypto/Cipher.java index b18ce92c4..d3d09d7e2 100644 --- a/src/share/classes/javax/crypto/Cipher.java +++ b/src/share/classes/javax/crypto/Cipher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -317,11 +317,15 @@ public class Cipher { while (parser.hasMoreTokens() && count < 3) { parts[count++] = parser.nextToken().trim(); } - if (count == 0 || count == 2 || parser.hasMoreTokens()) { + if (count == 0 || count == 2) { throw new NoSuchAlgorithmException("Invalid transformation" + " format:" + transformation); } + // treats all subsequent tokens as part of padding + if (count == 3 && parser.hasMoreTokens()) { + parts[2] = parts[2] + parser.nextToken("\r\n"); + } } catch (NoSuchElementException e) { throw new NoSuchAlgorithmException("Invalid transformation " + "format:" + transformation); diff --git a/src/share/classes/javax/crypto/spec/OAEPParameterSpec.java b/src/share/classes/javax/crypto/spec/OAEPParameterSpec.java index fcdc018cb..0b90452e6 100644 --- a/src/share/classes/javax/crypto/spec/OAEPParameterSpec.java +++ b/src/share/classes/javax/crypto/spec/OAEPParameterSpec.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,40 +32,53 @@ import java.security.spec.MGF1ParameterSpec; /** * This class specifies the set of parameters used with OAEP Padding, * as defined in the - * PKCS #1 - * standard. + * PKCS#1 v2.2 standard. * * Its ASN.1 definition in PKCS#1 standard is described below: *
      * RSAES-OAEP-params ::= SEQUENCE {
    - *   hashAlgorithm      [0] OAEP-PSSDigestAlgorithms     DEFAULT sha1,
    - *   maskGenAlgorithm   [1] PKCS1MGFAlgorithms  DEFAULT mgf1SHA1,
    - *   pSourceAlgorithm   [2] PKCS1PSourceAlgorithms  DEFAULT pSpecifiedEmpty
    + *   hashAlgorithm      [0] HashAlgorithm     DEFAULT sha1,
    + *   maskGenAlgorithm   [1] MaskGenAlgorithm  DEFAULT mgf1SHA1,
    + *   pSourceAlgorithm   [2] PSourceAlgorithm  DEFAULT pSpecifiedEmpty
      * }
      * 
    * where *
    + * HashAlgorithm ::= AlgorithmIdentifier {
    + *   {OAEP-PSSDigestAlgorithms}
    + * }
    + * MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} }
    + * PSourceAlgorithm ::= AlgorithmIdentifier {
    + *   {PKCS1PSourceAlgorithms}
    + * }
    + *
      * OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
    - *   { OID id-sha1 PARAMETERS NULL   }|
    - *   { OID id-sha256 PARAMETERS NULL }|
    - *   { OID id-sha384 PARAMETERS NULL }|
    - *   { OID id-sha512 PARAMETERS NULL },
    + *   { OID id-sha1       PARAMETERS NULL }|
    + *   { OID id-sha224     PARAMETERS NULL }|
    + *   { OID id-sha256     PARAMETERS NULL }|
    + *   { OID id-sha384     PARAMETERS NULL }|
    + *   { OID id-sha512     PARAMETERS NULL }|
    + *   { OID id-sha512-224 PARAMETERS NULL }|
    + *   { OID id-sha512-256 PARAMETERS NULL },
      *   ...  -- Allows for future expansion --
      * }
      * PKCS1MGFAlgorithms    ALGORITHM-IDENTIFIER ::= {
    - *   { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
    + *   { OID id-mgf1 PARAMETERS HashAlgorithm },
      *   ...  -- Allows for future expansion --
      * }
      * PKCS1PSourceAlgorithms    ALGORITHM-IDENTIFIER ::= {
    - *   { OID id-pSpecified PARAMETERS OCTET STRING },
    + *   { OID id-pSpecified PARAMETERS EncodingParameters },
      *   ...  -- Allows for future expansion --
      * }
    + * EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
      * 
    *

    Note: the OAEPParameterSpec.DEFAULT uses the following: + *

      *     message digest  -- "SHA-1"
      *     mask generation function (mgf) -- "MGF1"
      *     parameters for mgf -- MGF1ParameterSpec.SHA1
      *     source of encoding input -- PSource.PSpecified.DEFAULT
    + * 
    * * @see java.security.spec.MGF1ParameterSpec * @see PSource diff --git a/src/share/classes/javax/crypto/spec/PSource.java b/src/share/classes/javax/crypto/spec/PSource.java index a3d2efe89..0e5a6c88a 100644 --- a/src/share/classes/javax/crypto/spec/PSource.java +++ b/src/share/classes/javax/crypto/spec/PSource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,13 +28,19 @@ package javax.crypto.spec; /** * This class specifies the source for encoding input P in OAEP Padding, * as defined in the - * PKCS #1 - * standard. + * PKCS#1 v2.2 standard. + *
    + * PSourceAlgorithm ::= AlgorithmIdentifier {
    + *   {PKCS1PSourceAlgorithms}
    + * }
    + * 
    + * where *
      * PKCS1PSourceAlgorithms    ALGORITHM-IDENTIFIER ::= {
    - *   { OID id-pSpecified PARAMETERS OCTET STRING },
    + *   { OID id-pSpecified PARAMETERS EncodingParameters },
      *   ...  -- Allows for future expansion --
      * }
    + * EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
      * 
    * @author Valerie Peng * diff --git a/src/share/classes/javax/crypto/spec/package.html b/src/share/classes/javax/crypto/spec/package.html index b8fd80724..fd4bac4b1 100644 --- a/src/share/classes/javax/crypto/spec/package.html +++ b/src/share/classes/javax/crypto/spec/package.html @@ -1,5 +1,5 @@