--- old/make/lib/SecurityLibraries.gmk 2020-02-04 15:14:11.302689705 -0800 +++ new/make/lib/SecurityLibraries.gmk 2020-02-04 15:14:10.914689705 -0800 @@ -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 @@ -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" \ --- old/src/share/classes/com/sun/crypto/provider/OAEPParameters.java 2020-02-04 15:14:13.131689705 -0800 +++ new/src/share/classes/com/sun/crypto/provider/OAEPParameters.java 2020-02-04 15:14:12.755689705 -0800 @@ -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 @@ 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"); --- old/src/share/classes/com/sun/crypto/provider/RSACipher.java 2020-02-04 15:14:14.994689705 -0800 +++ new/src/share/classes/com/sun/crypto/provider/RSACipher.java 2020-02-04 15:14:14.604689705 -0800 @@ -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 @@ /** * 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 @@ 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 --- old/src/share/classes/com/sun/crypto/provider/SunJCE.java 2020-02-04 15:14:16.917689705 -0800 +++ new/src/share/classes/com/sun/crypto/provider/SunJCE.java 2020-02-04 15:14:16.528689705 -0800 @@ -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 @@ + "|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"); --- old/src/share/classes/java/security/Signature.java 2020-02-04 15:14:18.811689705 -0800 +++ new/src/share/classes/java/security/Signature.java 2020-02-04 15:14:18.424689705 -0800 @@ -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.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 @@ 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 @@ 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); } @@ -467,6 +498,53 @@ } /** + * 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. *

If the certificate is of type X.509 and has a key usage @@ -486,27 +564,40 @@ */ 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) { @@ -560,6 +651,31 @@ } /** + * 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 * signature scheme. @@ -680,7 +796,7 @@ * 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 @@ /** * 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 @@ * * @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 @@ } } - 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 @@ 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 @@ } 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 @@ 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 @@ } } - 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 @@ 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 @@ 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 @@ 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 @@ 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) --- old/src/share/classes/java/security/SignatureSpi.java 2020-02-04 15:14:20.656689705 -0800 +++ new/src/share/classes/java/security/SignatureSpi.java 2020-02-04 15:14:20.254689705 -0800 @@ -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 @@ -71,6 +71,33 @@ /** * 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. * * @param privateKey the private key of the identity whose signature @@ -97,10 +124,41 @@ * 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 @@ * 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 @@ * @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 @@ * 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 @@ * @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 @@ */ @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 @@ * 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. - * - *

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. + *

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

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 @@ * * @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 --- old/src/share/classes/java/security/cert/X509CRL.java 2020-02-04 15:14:22.489689705 -0800 +++ new/src/share/classes/java/security/cert/X509CRL.java 2020-02-04 15:14:22.091689705 -0800 @@ -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.Arrays; import sun.security.x509.X509CRLImpl; +import sun.security.util.SignatureUtil; /** *

@@ -241,7 +238,27 @@ 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."); + } } /** --- old/src/share/classes/java/security/cert/X509Certificate.java 2020-02-04 15:14:24.349689705 -0800 +++ new/src/share/classes/java/security/cert/X509Certificate.java 2020-02-04 15:14:23.919689705 -0800 @@ -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 @@ 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 @@ 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 @@ 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."); + } } } --- old/src/share/classes/java/security/interfaces/RSAKey.java 2020-02-04 15:14:26.205689705 -0800 +++ new/src/share/classes/java/security/interfaces/RSAKey.java 2020-02-04 15:14:25.832689705 -0800 @@ -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 @@ * @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; + } } --- old/src/share/classes/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java 2020-02-04 15:14:27.988689705 -0800 +++ new/src/share/classes/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java 2020-02-04 15:14:27.599689705 -0800 @@ -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 @@ /** * 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 * --- old/src/share/classes/java/security/interfaces/RSAPrivateCrtKey.java 2020-02-04 15:14:29.834689705 -0800 +++ new/src/share/classes/java/security/interfaces/RSAPrivateCrtKey.java 2020-02-04 15:14:29.446689705 -0800 @@ -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 @@ 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 --- old/src/share/classes/java/security/interfaces/package-info.java 2020-02-04 15:14:31.640689705 -0800 +++ new/src/share/classes/java/security/interfaces/package-info.java 2020-02-04 15:14:31.244689705 -0800 @@ -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

* * --- old/src/share/classes/java/security/spec/MGF1ParameterSpec.java 2020-02-04 15:14:33.476689705 -0800 +++ new/src/share/classes/java/security/spec/MGF1ParameterSpec.java 2020-02-04 15:14:33.047689705 -0800 @@ -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 @@ /** * 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 @@ 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; /** --- old/src/share/classes/java/security/spec/PSSParameterSpec.java 2020-02-04 15:14:35.319689705 -0800 +++ new/src/share/classes/java/security/spec/PSSParameterSpec.java 2020-02-04 15:14:34.926689705 -0800 @@ -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 @@ 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 @@ * 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 @@ /** * 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 @@ /** * 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 @@ } /** - * 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(); + } } --- old/src/share/classes/java/security/spec/RSAKeyGenParameterSpec.java 2020-02-04 15:14:37.231689705 -0800 +++ new/src/share/classes/java/security/spec/RSAKeyGenParameterSpec.java 2020-02-04 15:14:36.832689705 -0800 @@ -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 @@ private int keysize; private BigInteger publicExponent; + private AlgorithmParameterSpec keyParams; /** * The public-exponent value F0 = 3. @@ -55,15 +56,30 @@ 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 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; + } } --- old/src/share/classes/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java 2020-02-04 15:14:39.116689705 -0800 +++ new/src/share/classes/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java 2020-02-04 15:14:38.684689705 -0800 @@ -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 @@ 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 @@ 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 @@ * 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; --- old/src/share/classes/java/security/spec/RSAOtherPrimeInfo.java 2020-02-04 15:14:40.909689705 -0800 +++ new/src/share/classes/java/security/spec/RSAOtherPrimeInfo.java 2020-02-04 15:14:40.534689705 -0800 @@ -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 @@ /** * 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
+ * }
  *
  * 
* --- old/src/share/classes/java/security/spec/RSAPrivateCrtKeySpec.java 2020-02-04 15:14:42.734689705 -0800 +++ new/src/share/classes/java/security/spec/RSAPrivateCrtKeySpec.java 2020-02-04 15:14:42.325689705 -0800 @@ -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 @@ 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 @@ 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 @@ 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; --- old/src/share/classes/java/security/spec/RSAPrivateKeySpec.java 2020-02-04 15:14:44.611689705 -0800 +++ new/src/share/classes/java/security/spec/RSAPrivateKeySpec.java 2020-02-04 15:14:44.174689705 -0800 @@ -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 @@ 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 @@ * @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 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; + } } --- old/src/share/classes/java/security/spec/RSAPublicKeySpec.java 2020-02-04 15:14:46.418689705 -0800 +++ new/src/share/classes/java/security/spec/RSAPublicKeySpec.java 2020-02-04 15:14:46.026689705 -0800 @@ -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 @@ 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 @@ * @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 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; + } + } --- old/src/share/classes/java/security/spec/package-info.java 2020-02-04 15:14:48.283689705 -0800 +++ new/src/share/classes/java/security/spec/package-info.java 2020-02-04 15:14:47.839689705 -0800 @@ -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

* *