提交 d3243e3e 编写于 作者: W wetmore

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
上级 317005f1
# #
# 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. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -171,7 +171,7 @@ ifeq ($(OPENJDK_TARGET_OS), windows) ...@@ -171,7 +171,7 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
-I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/mscapi, \ -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/mscapi, \
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \ LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
$(call SET_SHARED_LIBRARY_ORIGIN), \ $(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, \ VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \
RC_FLAGS := $(RC_FLAGS) \ RC_FLAGS := $(RC_FLAGS) \
-D "JDK_FNAME=sunmscapi.dll" \ -D "JDK_FNAME=sunmscapi.dll" \
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -137,6 +137,10 @@ public final class OAEPParameters extends AlgorithmParametersSpi { ...@@ -137,6 +137,10 @@ public final class OAEPParameters extends AlgorithmParametersSpi {
mgfSpec = MGF1ParameterSpec.SHA384; mgfSpec = MGF1ParameterSpec.SHA384;
} else if (mgfDigestName.equals("SHA-512")) { } else if (mgfDigestName.equals("SHA-512")) {
mgfSpec = MGF1ParameterSpec.SHA512; 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 { } else {
throw new IOException( throw new IOException(
"Unrecognized message digest algorithm"); "Unrecognized message digest algorithm");
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -44,13 +44,15 @@ import sun.security.util.KeyUtil; ...@@ -44,13 +44,15 @@ import sun.security.util.KeyUtil;
/** /**
* RSA cipher implementation. Supports RSA en/decryption and signing/verifying * 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 * using both PKCS#1 v1.5 and OAEP (v2.2) paddings and without padding (raw RSA).
* is supported mostly for completeness and should only be used in rare cases. * 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 * Objects should be instantiated by calling Cipher.getInstance() using the
* following algorithm names: * following algorithm names:
* . "RSA/ECB/PKCS1Padding" (or "RSA") for PKCS#1 padding. The mode (blocktype) * . "RSA/ECB/PKCS1Padding" (or "RSA") for PKCS#1 v1.5 padding.
* is selected based on the en/decryption mode and public/private key used * . "RSA/ECB/OAEPwith<hash>andMGF1Padding" (or "RSA/ECB/OAEPPadding") for
* PKCS#1 v2.2 padding.
* . "RSA/ECB/NoPadding" for rsa RSA. * . "RSA/ECB/NoPadding" for rsa RSA.
* *
* We only do one RSA operation per doFinal() call. If the application passes * We only do one RSA operation per doFinal() call. If the application passes
...@@ -81,7 +83,7 @@ public final class RSACipher extends CipherSpi { ...@@ -81,7 +83,7 @@ public final class RSACipher extends CipherSpi {
private final static String PAD_NONE = "NoPadding"; private final static String PAD_NONE = "NoPadding";
// constant for PKCS#1 v1.5 RSA // constant for PKCS#1 v1.5 RSA
private final static String PAD_PKCS1 = "PKCS1Padding"; 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"; private final static String PAD_OAEP_MGF1 = "OAEP";
// current mode, one of MODE_* above. Set when init() is called // current mode, one of MODE_* above. Set when init() is called
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -131,7 +131,9 @@ public final class SunJCE extends Provider { ...@@ -131,7 +131,9 @@ public final class SunJCE extends Provider {
+ "|OAEPWITHSHA-224ANDMGF1PADDING" + "|OAEPWITHSHA-224ANDMGF1PADDING"
+ "|OAEPWITHSHA-256ANDMGF1PADDING" + "|OAEPWITHSHA-256ANDMGF1PADDING"
+ "|OAEPWITHSHA-384ANDMGF1PADDING" + "|OAEPWITHSHA-384ANDMGF1PADDING"
+ "|OAEPWITHSHA-512ANDMGF1PADDING"); + "|OAEPWITHSHA-512ANDMGF1PADDING"
+ "|OAEPWITHSHA-512/224ANDMGF1PADDING"
+ "|OAEPWITHSHA-512/256ANDMGF1PADDING");
put("Cipher.RSA SupportedKeyClasses", put("Cipher.RSA SupportedKeyClasses",
"java.security.interfaces.RSAPublicKey" + "java.security.interfaces.RSAPublicKey" +
"|java.security.interfaces.RSAPrivateKey"); "|java.security.interfaces.RSAPrivateKey");
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -41,6 +41,8 @@ import javax.crypto.CipherSpi; ...@@ -41,6 +41,8 @@ import javax.crypto.CipherSpi;
import javax.crypto.IllegalBlockSizeException; import javax.crypto.IllegalBlockSizeException;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;
import javax.crypto.NoSuchPaddingException; import javax.crypto.NoSuchPaddingException;
import sun.misc.JavaSecuritySignatureAccess;
import sun.misc.SharedSecrets;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.jca.*; import sun.security.jca.*;
...@@ -117,6 +119,34 @@ import sun.security.jca.GetInstance.Instance; ...@@ -117,6 +119,34 @@ import sun.security.jca.GetInstance.Instance;
public abstract class Signature extends SignatureSpi { 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 = private static final Debug debug =
Debug.getInstance("jca", "Signature"); Debug.getInstance("jca", "Signature");
...@@ -275,6 +305,7 @@ public abstract class Signature extends SignatureSpi { ...@@ -275,6 +305,7 @@ public abstract class Signature extends SignatureSpi {
signatureInfo.put("sun.security.rsa.RSASignature$SHA256withRSA", TRUE); signatureInfo.put("sun.security.rsa.RSASignature$SHA256withRSA", TRUE);
signatureInfo.put("sun.security.rsa.RSASignature$SHA384withRSA", TRUE); signatureInfo.put("sun.security.rsa.RSASignature$SHA384withRSA", TRUE);
signatureInfo.put("sun.security.rsa.RSASignature$SHA512withRSA", 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("com.sun.net.ssl.internal.ssl.RSASignature", TRUE);
signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE); signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE);
} }
...@@ -466,6 +497,53 @@ public abstract class Signature extends SignatureSpi { ...@@ -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<String> 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 * Initializes this object for verification, using the public key from
* the given certificate. * the given certificate.
...@@ -486,27 +564,40 @@ public abstract class Signature extends SignatureSpi { ...@@ -486,27 +564,40 @@ public abstract class Signature extends SignatureSpi {
*/ */
public final void initVerify(Certificate certificate) public final void initVerify(Certificate certificate)
throws InvalidKeyException { throws InvalidKeyException {
// If the certificate is of type X509Certificate, engineInitVerify(getPublicKeyFromCert(certificate));
// we should check whether it has a Key Usage state = VERIFY;
// 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<String> critSet = cert.getCriticalExtensionOIDs();
if (critSet != null && !critSet.isEmpty() if (!skipDebug && pdebug != null) {
&& critSet.contains("2.5.29.15")) { pdebug.println("Signature." + algorithm +
boolean[] keyUsageInfo = cert.getKeyUsage(); " verification algorithm from: " + getProviderName());
// keyUsageInfo[0] is for digitalSignature.
if ((keyUsageInfo != null) && (keyUsageInfo[0] == false))
throw new InvalidKeyException("Wrong key usage");
} }
} }
PublicKey publicKey = certificate.getPublicKey(); /**
engineInitVerify(publicKey); * Initializes this object for verification, using the public key from
* the given certificate.
* <p>If the certificate is of type X.509 and has a <i>key usage</i>
* extension field marked as critical, and the value of the <i>key usage</i>
* 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; state = VERIFY;
if (!skipDebug && pdebug != null) { if (!skipDebug && pdebug != null) {
...@@ -559,6 +650,31 @@ public abstract class Signature extends SignatureSpi { ...@@ -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. * Returns the signature bytes of all the data updated.
* The format of the signature depends on the underlying * The format of the signature depends on the underlying
...@@ -680,7 +796,7 @@ public abstract class Signature extends SignatureSpi { ...@@ -680,7 +796,7 @@ public abstract class Signature extends SignatureSpi {
* encoded or of the wrong type, if this signature algorithm is unable to * encoded or of the wrong type, if this signature algorithm is unable to
* process the input data provided, etc. * process the input data provided, etc.
* @exception IllegalArgumentException if the {@code signature} * @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 * is less than 0, or the sum of the {@code offset} and
* {@code length} is greater than the length of the * {@code length} is greater than the length of the
* {@code signature} byte array. * {@code signature} byte array.
...@@ -873,14 +989,15 @@ public abstract class Signature extends SignatureSpi { ...@@ -873,14 +989,15 @@ public abstract class Signature extends SignatureSpi {
/** /**
* Returns the parameters used with this signature object. * Returns the parameters used with this signature object.
* *
* <p>The returned parameters may be the same that were used to initialize * <p> If this signature has been previously initialized with parameters
* this signature, or may contain a combination of default and randomly * (by calling the {@code setParameter} method), this method returns
* generated parameter values used by the underlying signature * the same parameters. If this signature has not been initialized with
* implementation if this signature requires algorithm parameters but * parameters, this method may return a combination of default and
* was not initialized with any. * 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 * @return the parameters used with this signature, or {@code null}
* signature does not use any parameters.
* *
* @see #setParameter(AlgorithmParameterSpec) * @see #setParameter(AlgorithmParameterSpec)
* @since 1.4 * @since 1.4
...@@ -901,7 +1018,7 @@ public abstract class Signature extends SignatureSpi { ...@@ -901,7 +1018,7 @@ public abstract class Signature extends SignatureSpi {
* *
* @param param the string name of the parameter. * @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. * there is none.
* *
* @exception InvalidParameterException if {@code param} is an invalid * @exception InvalidParameterException if {@code param} is an invalid
...@@ -1086,11 +1203,13 @@ public abstract class Signature extends SignatureSpi { ...@@ -1086,11 +1203,13 @@ public abstract class Signature extends SignatureSpi {
} }
} }
private void chooseProvider(int type, Key key, SecureRandom random) // Used by engineSetParameter/engineInitSign/engineInitVerify() to
throws InvalidKeyException { // 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) { synchronized (lock) {
if (sigSpi != null) { if (sigSpi != null) {
init(sigSpi, type, key, random);
return; return;
} }
Exception lastException = null; Exception lastException = null;
...@@ -1103,7 +1222,7 @@ public abstract class Signature extends SignatureSpi { ...@@ -1103,7 +1222,7 @@ public abstract class Signature extends SignatureSpi {
s = serviceIterator.next(); s = serviceIterator.next();
} }
// if provider says it does not support this key, ignore it // if provider says it does not support this key, ignore it
if (s.supportsParameter(key) == false) { if (key != null && s.supportsParameter(key) == false) {
continue; continue;
} }
// if instance is not a SignatureSpi, ignore it // if instance is not a SignatureSpi, ignore it
...@@ -1112,7 +1231,7 @@ public abstract class Signature extends SignatureSpi { ...@@ -1112,7 +1231,7 @@ public abstract class Signature extends SignatureSpi {
} }
try { try {
SignatureSpi spi = newInstance(s); SignatureSpi spi = newInstance(s);
init(spi, type, key, random); tryOperation(spi, type, key, params, random);
provider = s.getProvider(); provider = s.getProvider();
sigSpi = spi; sigSpi = spi;
firstService = null; firstService = null;
...@@ -1134,6 +1253,10 @@ public abstract class Signature extends SignatureSpi { ...@@ -1134,6 +1253,10 @@ public abstract class Signature extends SignatureSpi {
if (lastException instanceof RuntimeException) { if (lastException instanceof RuntimeException) {
throw (RuntimeException)lastException; throw (RuntimeException)lastException;
} }
if (lastException instanceof InvalidAlgorithmParameterException) {
throw (InvalidAlgorithmParameterException)lastException;
}
String k = (key != null) ? key.getClass().getName() : "(null)"; String k = (key != null) ? key.getClass().getName() : "(null)";
throw new InvalidKeyException throw new InvalidKeyException
("No installed provider supports this key: " ("No installed provider supports this key: "
...@@ -1141,22 +1264,36 @@ public abstract class Signature extends SignatureSpi { ...@@ -1141,22 +1264,36 @@ public abstract class Signature extends SignatureSpi {
} }
} }
private final static int I_PUB = 1; private static final int I_PUB = 1;
private final static int I_PRIV = 2; private static final int I_PRIV = 2;
private final static int I_PRIV_SR = 3; 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) { switch (type) {
case I_PUB: case I_PUB:
spi.engineInitVerify((PublicKey)key); spi.engineInitVerify((PublicKey)key);
break; break;
case I_PUB_PARAM:
spi.engineInitVerify((PublicKey)key, params);
break;
case I_PRIV: case I_PRIV:
spi.engineInitSign((PrivateKey)key); spi.engineInitSign((PrivateKey)key);
break; break;
case I_PRIV_SR: case I_PRIV_SR:
spi.engineInitSign((PrivateKey)key, random); spi.engineInitSign((PrivateKey)key, random);
break; break;
case I_PRIV_PARAM_SR:
spi.engineInitSign((PrivateKey)key, params, random);
break;
case S_PARAM:
spi.engineSetParameter(params);
break;
default: default:
throw new AssertionError("Internal error: " + type); throw new AssertionError("Internal error: " + type);
} }
...@@ -1167,7 +1304,22 @@ public abstract class Signature extends SignatureSpi { ...@@ -1167,7 +1304,22 @@ public abstract class Signature extends SignatureSpi {
if (sigSpi != null) { if (sigSpi != null) {
sigSpi.engineInitVerify(publicKey); sigSpi.engineInitVerify(publicKey);
} else { } 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 { ...@@ -1176,7 +1328,12 @@ public abstract class Signature extends SignatureSpi {
if (sigSpi != null) { if (sigSpi != null) {
sigSpi.engineInitSign(privateKey); sigSpi.engineInitSign(privateKey);
} else { } 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 { ...@@ -1185,7 +1342,22 @@ public abstract class Signature extends SignatureSpi {
if (sigSpi != null) { if (sigSpi != null) {
sigSpi.engineInitSign(privateKey, sr); sigSpi.engineInitSign(privateKey, sr);
} else { } 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 { ...@@ -1236,8 +1408,16 @@ public abstract class Signature extends SignatureSpi {
protected void engineSetParameter(AlgorithmParameterSpec params) protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException { throws InvalidAlgorithmParameterException {
chooseFirstProvider(); if (sigSpi != null) {
sigSpi.engineSetParameter(params); 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) protected Object engineGetParameter(String param)
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -69,6 +69,33 @@ public abstract class SignatureSpi { ...@@ -69,6 +69,33 @@ public abstract class SignatureSpi {
protected abstract void engineInitVerify(PublicKey publicKey) protected abstract void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException; 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 * Initializes this signature object with the specified
* private key for signing operations. * private key for signing operations.
...@@ -103,6 +130,37 @@ public abstract class SignatureSpi { ...@@ -103,6 +130,37 @@ public abstract class SignatureSpi {
engineInitSign(privateKey); engineInitSign(privateKey);
} }
/**
* Initializes this signature object with the specified
* private key and source of randomness for signing operations.
*
* <p>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);
}
/** /**
* Updates the data to be signed or verified * Updates the data to be signed or verified
* using the specified byte. * using the specified byte.
...@@ -325,18 +383,18 @@ public abstract class SignatureSpi { ...@@ -325,18 +383,18 @@ public abstract class SignatureSpi {
} }
/** /**
* <p>This method is overridden by providers to return the * <p>This method is overridden by providers to return the parameters
* parameters used with this signature engine, or null * used with this signature engine.
* if this signature engine does not use any parameters.
* *
* <p>The returned parameters may be the same that were used to initialize * <p> If this signature engine has been previously initialized with
* this signature engine, or may contain a combination of default and * parameters (by calling the {@code engineSetParameter} method), this
* randomly generated parameter values used by the underlying signature * method returns the same parameters. If this signature engine has not been
* implementation if this signature engine requires algorithm parameters * initialized with parameters, this method may return a combination of
* but was not initialized with any. * 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 * @return the parameters used with this signature engine, or {@code null}
* signature engine does not use any parameters
* *
* @exception UnsupportedOperationException if this method is * @exception UnsupportedOperationException if this method is
* not overridden by a provider * not overridden by a provider
...@@ -359,7 +417,7 @@ public abstract class SignatureSpi { ...@@ -359,7 +417,7 @@ public abstract class SignatureSpi {
* *
* @param param the string name of the parameter. * @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. * there is none.
* *
* @exception InvalidParameterException if {@code param} is an * @exception InvalidParameterException if {@code param} is an
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,13 +25,9 @@ ...@@ -25,13 +25,9 @@
package java.security.cert; package java.security.cert;
import java.security.NoSuchAlgorithmException; import java.security.*;
import java.security.NoSuchProviderException; import java.security.spec.*;
import java.security.InvalidKeyException;
import java.security.SignatureException;
import java.security.Principal;
import java.security.Provider;
import java.security.PublicKey;
import javax.security.auth.x500.X500Principal; import javax.security.auth.x500.X500Principal;
import java.math.BigInteger; import java.math.BigInteger;
...@@ -40,6 +36,7 @@ import java.util.Set; ...@@ -40,6 +36,7 @@ import java.util.Set;
import java.util.Arrays; import java.util.Arrays;
import sun.security.x509.X509CRLImpl; import sun.security.x509.X509CRLImpl;
import sun.security.util.SignatureUtil;
/** /**
* <p> * <p>
...@@ -241,7 +238,27 @@ public abstract class X509CRL extends CRL implements X509Extension { ...@@ -241,7 +238,27 @@ public abstract class X509CRL extends CRL implements X509Extension {
public void verify(PublicKey key, Provider sigProvider) public void verify(PublicKey key, Provider sigProvider)
throws CRLException, NoSuchAlgorithmException, throws CRLException, NoSuchAlgorithmException,
InvalidKeyException, SignatureException { 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.");
}
} }
/** /**
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,12 +27,14 @@ package java.security.cert; ...@@ -27,12 +27,14 @@ package java.security.cert;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.*; import java.security.*;
import java.security.spec.*;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import javax.security.auth.x500.X500Principal; import javax.security.auth.x500.X500Principal;
import sun.security.x509.X509CertImpl; import sun.security.x509.X509CertImpl;
import sun.security.util.SignatureUtil;
/** /**
* <p> * <p>
...@@ -673,6 +675,25 @@ implements X509Extension { ...@@ -673,6 +675,25 @@ implements X509Extension {
public void verify(PublicKey key, Provider sigProvider) public void verify(PublicKey key, Provider sigProvider)
throws CertificateException, NoSuchAlgorithmException, throws CertificateException, NoSuchAlgorithmException,
InvalidKeyException, SignatureException { 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.");
}
} }
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,9 +26,12 @@ ...@@ -26,9 +26,12 @@
package java.security.interfaces; package java.security.interfaces;
import java.math.BigInteger; 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
* <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard,
* such as those for RSA, or RSASSA-PSS algorithms.
* *
* @author Jan Luehe * @author Jan Luehe
* *
...@@ -46,4 +49,20 @@ public interface RSAKey { ...@@ -46,4 +49,20 @@ public interface RSAKey {
* @return the modulus * @return the modulus
*/ */
public BigInteger getModulus(); 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;
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -30,8 +30,8 @@ import java.security.spec.RSAOtherPrimeInfo; ...@@ -30,8 +30,8 @@ import java.security.spec.RSAOtherPrimeInfo;
/** /**
* The interface to an RSA multi-prime private key, as defined in the * The interface to an RSA multi-prime private key, as defined in the
* PKCS#1 v2.1, using the <i>Chinese Remainder Theorem</i> * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard,
* (CRT) information values. * using the <i>Chinese Remainder Theorem</i> (CRT) information values.
* *
* @author Valerie Peng * @author Valerie Peng
* *
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,7 +28,8 @@ package java.security.interfaces; ...@@ -28,7 +28,8 @@ package java.security.interfaces;
import java.math.BigInteger; 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
* <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard,
* using the <i>Chinese Remainder Theorem</i> (CRT) information values. * using the <i>Chinese Remainder Theorem</i> (CRT) information values.
* *
* @author Jan Luehe * @author Jan Luehe
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
* <h2>Package Specification</h2> * <h2>Package Specification</h2>
* *
* <ul> * <ul>
* <li>PKCS #1: RSA Encryption Standard, Version 1.5, November 1993 </li> * <li>PKCS #1: RSA Cryptography Specifications, Version 2.2 (RFC 8017)</li>
* <li>Federal Information Processing Standards Publication (FIPS PUB) 186: * <li>Federal Information Processing Standards Publication (FIPS PUB) 186:
* Digital Signature Standard (DSS) </li> * Digital Signature Standard (DSS) </li>
* </ul> * </ul>
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,23 +29,31 @@ import java.security.spec.AlgorithmParameterSpec; ...@@ -29,23 +29,31 @@ import java.security.spec.AlgorithmParameterSpec;
/** /**
* This class specifies the set of parameters used with mask generation * 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 * defined in the
* <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS #1 v2.1</a> * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
* standard.
* *
* <p>Its ASN.1 definition in PKCS#1 standard is described below: * <p>Its ASN.1 definition in PKCS#1 standard is described below:
* <pre> * <pre>
* MGF1Parameters ::= OAEP-PSSDigestAlgorthms * PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-mgf1 PARAMETERS HashAlgorithm },
* ... -- Allows for future expansion --
* }
* </pre> * </pre>
* where * where
* <pre> * <pre>
* HashAlgorithm ::= AlgorithmIdentifier {
* {OAEP-PSSDigestAlgorithms}
* }
*
* OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= { * OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-sha1 PARAMETERS NULL }| * { OID id-sha1 PARAMETERS NULL }|
* { OID id-sha224 PARAMETERS NULL }| * { OID id-sha224 PARAMETERS NULL }|
* { OID id-sha256 PARAMETERS NULL }| * { OID id-sha256 PARAMETERS NULL }|
* { OID id-sha384 PARAMETERS NULL }| * { OID id-sha384 PARAMETERS NULL }|
* { OID id-sha512 PARAMETERS NULL }, * { OID id-sha512 PARAMETERS NULL }|
* { OID id-sha512-224 PARAMETERS NULL }|
* { OID id-sha512-256 PARAMETERS NULL },
* ... -- Allows for future expansion -- * ... -- Allows for future expansion --
* } * }
* </pre> * </pre>
...@@ -59,31 +67,47 @@ import java.security.spec.AlgorithmParameterSpec; ...@@ -59,31 +67,47 @@ import java.security.spec.AlgorithmParameterSpec;
public class MGF1ParameterSpec implements 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 = public static final MGF1ParameterSpec SHA1 =
new MGF1ParameterSpec("SHA-1"); 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 = public static final MGF1ParameterSpec SHA224 =
new MGF1ParameterSpec("SHA-224"); 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 = public static final MGF1ParameterSpec SHA256 =
new MGF1ParameterSpec("SHA-256"); 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 = public static final MGF1ParameterSpec SHA384 =
new MGF1ParameterSpec("SHA-384"); 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 = public static final MGF1ParameterSpec SHA512 =
new MGF1ParameterSpec("SHA-512"); 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; private String mdName;
/** /**
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,37 +25,42 @@ ...@@ -25,37 +25,42 @@
package java.security.spec; package java.security.spec;
import java.math.BigInteger; import java.util.Objects;
import java.security.spec.MGF1ParameterSpec;
/** /**
* 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 * as defined in the
* <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS#1 v2.1</a> * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
* standard.
* *
* <p>Its ASN.1 definition in PKCS#1 standard is described below: * <p>Its ASN.1 definition in PKCS#1 standard is described below:
* <pre> * <pre>
* RSASSA-PSS-params ::= SEQUENCE { * RSASSA-PSS-params ::= SEQUENCE {
* hashAlgorithm [0] OAEP-PSSDigestAlgorithms DEFAULT sha1, * hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
* maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1, * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
* saltLength [2] INTEGER DEFAULT 20, * saltLength [2] INTEGER DEFAULT 20,
* trailerField [3] INTEGER DEFAULT 1 * trailerField [3] TrailerField DEFAULT trailerFieldBC(1)
* } * }
* </pre> * </pre>
* where * where
* <pre> * <pre>
* HashAlgorithm ::= AlgorithmIdentifier {
* {OAEP-PSSDigestAlgorithms}
* }
* MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} }
* TrailerField ::= INTEGER { trailerFieldBC(1) }
*
* OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= { * OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-sha1 PARAMETERS NULL }| * { OID id-sha1 PARAMETERS NULL }|
* { OID id-sha224 PARAMETERS NULL }| * { OID id-sha224 PARAMETERS NULL }|
* { OID id-sha256 PARAMETERS NULL }| * { OID id-sha256 PARAMETERS NULL }|
* { OID id-sha384 PARAMETERS NULL }| * { OID id-sha384 PARAMETERS NULL }|
* { OID id-sha512 PARAMETERS NULL }, * { OID id-sha512 PARAMETERS NULL }|
* { OID id-sha512-224 PARAMETERS NULL }|
* { OID id-sha512-256 PARAMETERS NULL },
* ... -- Allows for future expansion -- * ... -- Allows for future expansion --
* } * }
*
* PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= { * PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms }, * { OID id-mgf1 PARAMETERS HashAlgorithm },
* ... -- Allows for future expansion -- * ... -- Allows for future expansion --
* } * }
* </pre> * </pre>
...@@ -78,55 +83,62 @@ import java.security.spec.MGF1ParameterSpec; ...@@ -78,55 +83,62 @@ import java.security.spec.MGF1ParameterSpec;
public class PSSParameterSpec implements AlgorithmParameterSpec { public class PSSParameterSpec implements AlgorithmParameterSpec {
private String mdName = "SHA-1"; private final String mdName;
private String mgfName = "MGF1";
private AlgorithmParameterSpec mgfSpec = MGF1ParameterSpec.SHA1; private final String mgfName;
private int saltLen = 20;
private int trailerField = 1; private final AlgorithmParameterSpec mgfSpec;
private final int saltLen;
private final int trailerField;
/** /**
* The PSS parameter set with all default values. * The {@code TrailerFieldBC} constant as defined in PKCS#1
* @since 1.5 *
* @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 PSS parameter set with all default values
* the PKCS #1 standard using the default values. *
* @since 1.5
*/ */
public static final PSSParameterSpec DEFAULT = new PSSParameterSpec
("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 20, TRAILER_FIELD_BC);
// disallowed
private PSSParameterSpec() { private PSSParameterSpec() {
throw new RuntimeException("default constructor not allowed");
} }
/** /**
* Creates a new {@code PSSParameterSpec} as defined in * Creates a new {@code PSSParameterSpec} as defined in
* the PKCS #1 standard using the specified message digest, * the PKCS #1 standard using the specified message digest,
* mask generation function, parameters for mask generation * mask generation function, parameters for mask generation
* function, salt length, and trailer field values. * function, salt length, and trailer field values.
* *
* @param mdName the algorithm name of the hash function. * @param mdName the algorithm name of the hash function
* @param mgfName the algorithm name of the mask generation * @param mgfName the algorithm name of the mask generation function
* function. * @param mgfSpec the parameters for the mask generation function.
* @param mgfSpec the parameters for the mask generation * If null is specified, null will be returned by
* function. If null is specified, null will be returned by
* getMGFParameters(). * getMGFParameters().
* @param saltLen the length of salt. * @param saltLen the length of salt
* @param trailerField the value of the trailer field. * @param trailerField the value of the trailer field
* @exception NullPointerException if {@code mdName}, * @exception NullPointerException if {@code mdName}, or {@code mgfName}
* or {@code mgfName} is null. * is null
* @exception IllegalArgumentException if {@code saltLen} * @exception IllegalArgumentException if {@code saltLen} or
* or {@code trailerField} is less than 0. * {@code trailerField} is less than 0
* @since 1.5 * @since 1.5
*/ */
public PSSParameterSpec(String mdName, String mgfName, public PSSParameterSpec(String mdName, String mgfName,
AlgorithmParameterSpec mgfSpec, AlgorithmParameterSpec mgfSpec, int saltLen, int trailerField) {
int saltLen, int trailerField) { Objects.requireNonNull(mdName, "digest algorithm is null");
if (mdName == null) { Objects.requireNonNull(mgfName,
throw new NullPointerException("digest algorithm is null"); "mask generation function algorithm is null");
}
if (mgfName == null) {
throw new NullPointerException("mask generation function " +
"algorithm is null");
}
if (saltLen < 0) { if (saltLen < 0) {
throw new IllegalArgumentException("negative saltLen value: " + throw new IllegalArgumentException("negative saltLen value: " +
saltLen); saltLen);
...@@ -147,23 +159,19 @@ public class PSSParameterSpec implements AlgorithmParameterSpec { ...@@ -147,23 +159,19 @@ public class PSSParameterSpec implements AlgorithmParameterSpec {
* using the specified salt length and other default values as * using the specified salt length and other default values as
* defined in PKCS#1. * defined in PKCS#1.
* *
* @param saltLen the length of salt in bits to be used in PKCS#1 * @param saltLen the length of salt in bytes to be used in PKCS#1
* PSS encoding. * PSS encoding
* @exception IllegalArgumentException if {@code saltLen} is * @exception IllegalArgumentException if {@code saltLen} is
* less than 0. * less than 0
*/ */
public PSSParameterSpec(int saltLen) { public PSSParameterSpec(int saltLen) {
if (saltLen < 0) { this("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, saltLen, TRAILER_FIELD_BC);
throw new IllegalArgumentException("negative saltLen value: " +
saltLen);
}
this.saltLen = saltLen;
} }
/** /**
* Returns the message digest algorithm name. * Returns the message digest algorithm name.
* *
* @return the message digest algorithm name. * @return the message digest algorithm name
* @since 1.5 * @since 1.5
*/ */
public String getDigestAlgorithm() { public String getDigestAlgorithm() {
...@@ -173,7 +181,7 @@ public class PSSParameterSpec implements AlgorithmParameterSpec { ...@@ -173,7 +181,7 @@ public class PSSParameterSpec implements AlgorithmParameterSpec {
/** /**
* Returns the mask generation function algorithm name. * Returns the mask generation function algorithm name.
* *
* @return the mask generation function algorithm name. * @return the mask generation function algorithm name
* *
* @since 1.5 * @since 1.5
*/ */
...@@ -184,7 +192,7 @@ public class PSSParameterSpec implements AlgorithmParameterSpec { ...@@ -184,7 +192,7 @@ public class PSSParameterSpec implements AlgorithmParameterSpec {
/** /**
* Returns the parameters for the mask generation function. * 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 * @since 1.5
*/ */
public AlgorithmParameterSpec getMGFParameters() { public AlgorithmParameterSpec getMGFParameters() {
...@@ -192,21 +200,31 @@ public class PSSParameterSpec implements AlgorithmParameterSpec { ...@@ -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() { public int getSaltLength() {
return saltLen; 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 * @since 1.5
*/ */
public int getTrailerField() { public int getTrailerField() {
return trailerField; 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();
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -43,6 +43,7 @@ public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec { ...@@ -43,6 +43,7 @@ public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec {
private int keysize; private int keysize;
private BigInteger publicExponent; private BigInteger publicExponent;
private AlgorithmParameterSpec keyParams;
/** /**
* The public-exponent value F0 = 3. * The public-exponent value F0 = 3.
...@@ -55,15 +56,30 @@ public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec { ...@@ -55,15 +56,30 @@ public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec {
public static final BigInteger F4 = BigInteger.valueOf(65537); public static final BigInteger F4 = BigInteger.valueOf(65537);
/** /**
* Constructs a new {@code RSAParameterSpec} object from the * Constructs a new {@code RSAKeyGenParameterSpec} object from the
* given keysize and public-exponent value. * given keysize, public-exponent value, and null key parameters.
* *
* @param keysize the modulus size (specified in number of bits) * @param keysize the modulus size (specified in number of bits)
* @param publicExponent the public exponent * @param publicExponent the public exponent
*/ */
public RSAKeyGenParameterSpec(int keysize, BigInteger publicExponent) { 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.keysize = keysize;
this.publicExponent = publicExponent; this.publicExponent = publicExponent;
this.keyParams = keyParams;
} }
/** /**
...@@ -83,4 +99,15 @@ public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec { ...@@ -83,4 +99,15 @@ public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec {
public BigInteger getPublicExponent() { public BigInteger getPublicExponent() {
return publicExponent; 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;
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,11 +26,13 @@ ...@@ -26,11 +26,13 @@
package java.security.spec; package java.security.spec;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Objects;
/** /**
* This class specifies an RSA multi-prime private key, as defined in the * This class specifies an RSA multi-prime private key, as defined in the
* PKCS#1 v2.1, using the Chinese Remainder Theorem (CRT) information * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard
* values for efficiency. * using the Chinese Remainder Theorem (CRT) information values
* for efficiency.
* *
* @author Valerie Peng * @author Valerie Peng
* *
...@@ -57,34 +59,28 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec { ...@@ -57,34 +59,28 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec {
private final RSAOtherPrimeInfo otherPrimeInfo[]; private final RSAOtherPrimeInfo otherPrimeInfo[];
/** /**
* Creates a new {@code RSAMultiPrimePrivateCrtKeySpec} * Creates a new {@code RSAMultiPrimePrivateCrtKeySpec}.
* given the modulus, publicExponent, privateExponent,
* primeP, primeQ, primeExponentP, primeExponentQ,
* crtCoefficient, and otherPrimeInfo as defined in PKCS#1 v2.1.
* *
* <p>Note that the contents of {@code otherPrimeInfo} * <p>Note that the contents of {@code otherPrimeInfo}
* are copied to protect against subsequent modification when * are copied to protect against subsequent modification when
* constructing this object. * constructing this object.
* *
* @param modulus the modulus n. * @param modulus the modulus n
* @param publicExponent the public exponent e. * @param publicExponent the public exponent e
* @param privateExponent the private exponent d. * @param privateExponent the private exponent d
* @param primeP the prime factor p of n. * @param primeP the prime factor p of n
* @param primeQ the prime factor q of n. * @param primeQ the prime factor q of n
* @param primeExponentP this is d mod (p-1). * @param primeExponentP this is d mod (p-1)
* @param primeExponentQ this is d mod (q-1). * @param primeExponentQ this is d mod (q-1)
* @param crtCoefficient the Chinese Remainder Theorem * @param crtCoefficient the Chinese Remainder Theorem
* coefficient q-1 mod p. * coefficient q-1 mod p
* @param otherPrimeInfo triplets of the rest of primes, null can be * @param otherPrimeInfo triplets of the rest of primes, null can be
* specified if there are only two prime factors (p and q). * specified if there are only two prime factors
* @exception NullPointerException if any of the parameters, i.e. * (p and q)
* {@code modulus}, * @throws NullPointerException if any of the specified parameters
* {@code publicExponent}, {@code privateExponent}, * with the exception of {@code otherPrimeInfo} is null
* {@code primeP}, {@code primeQ}, * @throws IllegalArgumentException if an empty, i.e. 0-length,
* {@code primeExponentP}, {@code primeExponentQ}, * {@code otherPrimeInfo} is specified
* {@code crtCoefficient}, is null.
* @exception IllegalArgumentException if an empty, i.e. 0-length,
* {@code otherPrimeInfo} is specified.
*/ */
public RSAMultiPrimePrivateCrtKeySpec(BigInteger modulus, public RSAMultiPrimePrivateCrtKeySpec(BigInteger modulus,
BigInteger publicExponent, BigInteger publicExponent,
...@@ -95,45 +91,67 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec { ...@@ -95,45 +91,67 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec {
BigInteger primeExponentQ, BigInteger primeExponentQ,
BigInteger crtCoefficient, BigInteger crtCoefficient,
RSAOtherPrimeInfo[] otherPrimeInfo) { RSAOtherPrimeInfo[] otherPrimeInfo) {
super(modulus, privateExponent); this(modulus, publicExponent, privateExponent, primeP, primeQ,
if (modulus == null) { primeExponentP, primeExponentQ, crtCoefficient, otherPrimeInfo,
throw new NullPointerException("the modulus parameter must be " + null);
"non-null");
} }
if (publicExponent == null) {
throw new NullPointerException("the publicExponent parameter " + /**
"must be non-null"); * Creates a new {@code RSAMultiPrimePrivateCrtKeySpec} with additional
} * key parameters.
if (privateExponent == null) { *
throw new NullPointerException("the privateExponent parameter " + * <p>Note that the contents of {@code otherPrimeInfo}
"must be non-null"); * are copied to protect against subsequent modification when
} * constructing this object.
if (primeP == null) { *
throw new NullPointerException("the primeP parameter " + * @param modulus the modulus n
"must be non-null"); * @param publicExponent the public exponent e
} * @param privateExponent the private exponent d
if (primeQ == null) { * @param primeP the prime factor p of n
throw new NullPointerException("the primeQ parameter " + * @param primeQ the prime factor q of n
"must be non-null"); * @param primeExponentP this is d mod (p-1)
} * @param primeExponentQ this is d mod (q-1)
if (primeExponentP == null) { * @param crtCoefficient the Chinese Remainder Theorem coefficient
throw new NullPointerException("the primeExponentP parameter " + * q-1 mod p
"must be non-null"); * @param otherPrimeInfo triplets of the rest of primes, null can be
} * specified if there are only two prime factors
if (primeExponentQ == null) { * (p and q)
throw new NullPointerException("the primeExponentQ parameter " + * @param keyParams the parameters associated with key
"must be non-null"); * @throws NullPointerException if any of the specified parameters
} * with the exception of {@code otherPrimeInfo} and {@code keyParams}
if (crtCoefficient == null) { * is null
throw new NullPointerException("the crtCoefficient parameter " + * @throws IllegalArgumentException if an empty, i.e. 0-length,
"must be non-null"); * {@code otherPrimeInfo} is specified
} * @since 8
this.publicExponent = publicExponent; */
this.primeP = primeP; public RSAMultiPrimePrivateCrtKeySpec(BigInteger modulus,
this.primeQ = primeQ; BigInteger publicExponent,
this.primeExponentP = primeExponentP; BigInteger privateExponent,
this.primeExponentQ = primeExponentQ; BigInteger primeP,
this.crtCoefficient = crtCoefficient; 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) { if (otherPrimeInfo == null) {
this.otherPrimeInfo = null; this.otherPrimeInfo = null;
} else if (otherPrimeInfo.length == 0) { } else if (otherPrimeInfo.length == 0) {
...@@ -202,8 +220,8 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec { ...@@ -202,8 +220,8 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec {
* Returns a copy of the otherPrimeInfo or null if there are * Returns a copy of the otherPrimeInfo or null if there are
* only two prime factors (p and q). * only two prime factors (p and q).
* *
* @return the otherPrimeInfo. Returns a new array each * @return the otherPrimeInfo. Returns a new array each time this method
* time this method is called. * is called.
*/ */
public RSAOtherPrimeInfo[] getOtherPrimeInfo() { public RSAOtherPrimeInfo[] getOtherPrimeInfo() {
if (otherPrimeInfo == null) return null; if (otherPrimeInfo == null) return null;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,7 +29,8 @@ import java.math.BigInteger; ...@@ -29,7 +29,8 @@ import java.math.BigInteger;
/** /**
* This class represents the triplet (prime, exponent, and coefficient) * 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
* <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
* The ASN.1 syntax of RSA's OtherPrimeInfo is as follows: * The ASN.1 syntax of RSA's OtherPrimeInfo is as follows:
* *
* <pre> * <pre>
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,9 +28,9 @@ package java.security.spec; ...@@ -28,9 +28,9 @@ package java.security.spec;
import java.math.BigInteger; import java.math.BigInteger;
/** /**
* This class specifies an RSA private key, as defined in the PKCS#1 * This class specifies an RSA private key, as defined in the
* standard, using the Chinese Remainder Theorem (CRT) information values for * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard,
* efficiency. * using the Chinese Remainder Theorem (CRT) information values for efficiency.
* *
* @author Jan Luehe * @author Jan Luehe
* *
...@@ -52,13 +52,8 @@ public class RSAPrivateCrtKeySpec extends RSAPrivateKeySpec { ...@@ -52,13 +52,8 @@ public class RSAPrivateCrtKeySpec extends RSAPrivateKeySpec {
private final BigInteger primeExponentQ; private final BigInteger primeExponentQ;
private final BigInteger crtCoefficient; private final BigInteger crtCoefficient;
/** /**
* Creates a new {@code RSAPrivateCrtKeySpec} * Creates a new {@code RSAPrivateCrtKeySpec}.
* given the modulus, publicExponent, privateExponent,
* primeP, primeQ, primeExponentP, primeExponentQ, and
* crtCoefficient as defined in PKCS#1.
* *
* @param modulus the modulus n * @param modulus the modulus n
* @param publicExponent the public exponent e * @param publicExponent the public exponent e
...@@ -78,7 +73,36 @@ public class RSAPrivateCrtKeySpec extends RSAPrivateKeySpec { ...@@ -78,7 +73,36 @@ public class RSAPrivateCrtKeySpec extends RSAPrivateKeySpec {
BigInteger primeExponentP, BigInteger primeExponentP,
BigInteger primeExponentQ, BigInteger primeExponentQ,
BigInteger crtCoefficient) { 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.publicExponent = publicExponent;
this.primeP = primeP; this.primeP = primeP;
this.primeQ = primeQ; this.primeQ = primeQ;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -43,8 +43,9 @@ import java.math.BigInteger; ...@@ -43,8 +43,9 @@ import java.math.BigInteger;
public class RSAPrivateKeySpec implements KeySpec { public class RSAPrivateKeySpec implements KeySpec {
private BigInteger modulus; private final BigInteger modulus;
private BigInteger privateExponent; private final BigInteger privateExponent;
private final AlgorithmParameterSpec params;
/** /**
* Creates a new RSAPrivateKeySpec. * Creates a new RSAPrivateKeySpec.
...@@ -53,8 +54,22 @@ public class RSAPrivateKeySpec implements KeySpec { ...@@ -53,8 +54,22 @@ public class RSAPrivateKeySpec implements KeySpec {
* @param privateExponent the private exponent * @param privateExponent the private exponent
*/ */
public RSAPrivateKeySpec(BigInteger modulus, BigInteger privateExponent) { 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.modulus = modulus;
this.privateExponent = privateExponent; this.privateExponent = privateExponent;
this.params = params;
} }
/** /**
...@@ -74,4 +89,15 @@ public class RSAPrivateKeySpec implements KeySpec { ...@@ -74,4 +89,15 @@ public class RSAPrivateKeySpec implements KeySpec {
public BigInteger getPrivateExponent() { public BigInteger getPrivateExponent() {
return this.privateExponent; 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;
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -43,8 +43,9 @@ import java.math.BigInteger; ...@@ -43,8 +43,9 @@ import java.math.BigInteger;
public class RSAPublicKeySpec implements KeySpec { public class RSAPublicKeySpec implements KeySpec {
private BigInteger modulus; private final BigInteger modulus;
private BigInteger publicExponent; private final BigInteger publicExponent;
private final AlgorithmParameterSpec params;
/** /**
* Creates a new RSAPublicKeySpec. * Creates a new RSAPublicKeySpec.
...@@ -53,10 +54,25 @@ public class RSAPublicKeySpec implements KeySpec { ...@@ -53,10 +54,25 @@ public class RSAPublicKeySpec implements KeySpec {
* @param publicExponent the public exponent * @param publicExponent the public exponent
*/ */
public RSAPublicKeySpec(BigInteger modulus, BigInteger publicExponent) { 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.modulus = modulus;
this.publicExponent = publicExponent; this.publicExponent = publicExponent;
this.params = params;
} }
/** /**
* Returns the modulus. * Returns the modulus.
* *
...@@ -74,4 +90,16 @@ public class RSAPublicKeySpec implements KeySpec { ...@@ -74,4 +90,16 @@ public class RSAPublicKeySpec implements KeySpec {
public BigInteger getPublicExponent() { public BigInteger getPublicExponent() {
return this.publicExponent; 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;
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
* <h2>Package Specification</h2> * <h2>Package Specification</h2>
* *
* <ul> * <ul>
* <li>PKCS #1: RSA Encryption Standard, Version 1.5, November 1993</li> * <li>PKCS #1: RSA Cryptography Specifications, Version 2.2 (RFC 8017)</li>
* <li>PKCS #8: Private-Key Information Syntax Standard, * <li>PKCS #8: Private-Key Information Syntax Standard,
* Version 1.2, November 1993</li> * Version 1.2, November 1993</li>
* <li>Federal Information Processing Standards Publication (FIPS PUB) 186: * <li>Federal Information Processing Standards Publication (FIPS PUB) 186:
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -317,11 +317,15 @@ public class Cipher { ...@@ -317,11 +317,15 @@ public class Cipher {
while (parser.hasMoreTokens() && count < 3) { while (parser.hasMoreTokens() && count < 3) {
parts[count++] = parser.nextToken().trim(); parts[count++] = parser.nextToken().trim();
} }
if (count == 0 || count == 2 || parser.hasMoreTokens()) { if (count == 0 || count == 2) {
throw new NoSuchAlgorithmException("Invalid transformation" throw new NoSuchAlgorithmException("Invalid transformation"
+ " format:" + + " format:" +
transformation); 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) { } catch (NoSuchElementException e) {
throw new NoSuchAlgorithmException("Invalid transformation " + throw new NoSuchAlgorithmException("Invalid transformation " +
"format:" + transformation); "format:" + transformation);
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -32,40 +32,53 @@ import java.security.spec.MGF1ParameterSpec; ...@@ -32,40 +32,53 @@ import java.security.spec.MGF1ParameterSpec;
/** /**
* This class specifies the set of parameters used with OAEP Padding, * This class specifies the set of parameters used with OAEP Padding,
* as defined in the * as defined in the
* <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS #1</a> * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
* standard.
* *
* Its ASN.1 definition in PKCS#1 standard is described below: * Its ASN.1 definition in PKCS#1 standard is described below:
* <pre> * <pre>
* RSAES-OAEP-params ::= SEQUENCE { * RSAES-OAEP-params ::= SEQUENCE {
* hashAlgorithm [0] OAEP-PSSDigestAlgorithms DEFAULT sha1, * hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
* maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1, * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
* pSourceAlgorithm [2] PKCS1PSourceAlgorithms DEFAULT pSpecifiedEmpty * pSourceAlgorithm [2] PSourceAlgorithm DEFAULT pSpecifiedEmpty
* } * }
* </pre> * </pre>
* where * where
* <pre> * <pre>
* HashAlgorithm ::= AlgorithmIdentifier {
* {OAEP-PSSDigestAlgorithms}
* }
* MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} }
* PSourceAlgorithm ::= AlgorithmIdentifier {
* {PKCS1PSourceAlgorithms}
* }
*
* OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= { * OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-sha1 PARAMETERS NULL }| * { OID id-sha1 PARAMETERS NULL }|
* { OID id-sha224 PARAMETERS NULL }|
* { OID id-sha256 PARAMETERS NULL }| * { OID id-sha256 PARAMETERS NULL }|
* { OID id-sha384 PARAMETERS NULL }| * { OID id-sha384 PARAMETERS NULL }|
* { OID id-sha512 PARAMETERS NULL }, * { OID id-sha512 PARAMETERS NULL }|
* { OID id-sha512-224 PARAMETERS NULL }|
* { OID id-sha512-256 PARAMETERS NULL },
* ... -- Allows for future expansion -- * ... -- Allows for future expansion --
* } * }
* PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= { * PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms }, * { OID id-mgf1 PARAMETERS HashAlgorithm },
* ... -- Allows for future expansion -- * ... -- Allows for future expansion --
* } * }
* PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= { * PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-pSpecified PARAMETERS OCTET STRING }, * { OID id-pSpecified PARAMETERS EncodingParameters },
* ... -- Allows for future expansion -- * ... -- Allows for future expansion --
* } * }
* EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
* </pre> * </pre>
* <p>Note: the OAEPParameterSpec.DEFAULT uses the following: * <p>Note: the OAEPParameterSpec.DEFAULT uses the following:
* <pre>
* message digest -- "SHA-1" * message digest -- "SHA-1"
* mask generation function (mgf) -- "MGF1" * mask generation function (mgf) -- "MGF1"
* parameters for mgf -- MGF1ParameterSpec.SHA1 * parameters for mgf -- MGF1ParameterSpec.SHA1
* source of encoding input -- PSource.PSpecified.DEFAULT * source of encoding input -- PSource.PSpecified.DEFAULT
* </pre>
* *
* @see java.security.spec.MGF1ParameterSpec * @see java.security.spec.MGF1ParameterSpec
* @see PSource * @see PSource
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,13 +28,19 @@ package javax.crypto.spec; ...@@ -28,13 +28,19 @@ package javax.crypto.spec;
/** /**
* This class specifies the source for encoding input P in OAEP Padding, * This class specifies the source for encoding input P in OAEP Padding,
* as defined in the * as defined in the
* <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS #1</a> * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
* standard. * <pre>
* PSourceAlgorithm ::= AlgorithmIdentifier {
* {PKCS1PSourceAlgorithms}
* }
* </pre>
* where
* <pre> * <pre>
* PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= { * PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-pSpecified PARAMETERS OCTET STRING }, * { OID id-pSpecified PARAMETERS EncodingParameters },
* ... -- Allows for future expansion -- * ... -- Allows for future expansion --
* } * }
* EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
* </pre> * </pre>
* @author Valerie Peng * @author Valerie Peng
* *
......
<!-- <!--
Copyright (c) 1999, 2007, 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. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it This code is free software; you can redistribute it and/or modify it
...@@ -46,6 +46,7 @@ Diffie-Hellman, DES, Triple DES, PBE, RC2 and RC5 algorithms. ...@@ -46,6 +46,7 @@ Diffie-Hellman, DES, Triple DES, PBE, RC2 and RC5 algorithms.
<h2>Package Specification</h2> <h2>Package Specification</h2>
<ul> <ul>
<li>PKCS #1: RSA Cryptography Specifications, Version 2.2 (RFC 8017)</li>
<li>PKCS #3: Diffie-Hellman Key-Agreement Standard, Version 1.4, <li>PKCS #3: Diffie-Hellman Key-Agreement Standard, Version 1.4,
November 1993.</li> November 1993.</li>
<li>PKCS #5: Password-Based Encryption Standard, Version 1.5, <li>PKCS #5: Password-Based Encryption Standard, Version 1.5,
......
/*
* Copyright (c) 2019, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
public interface JavaSecuritySignatureAccess {
void initVerify(Signature s, PublicKey publicKey, AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException;
void initVerify(Signature s, java.security.cert.Certificate certificate,
AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException;
void initSign(Signature s, PrivateKey privateKey,
AlgorithmParameterSpec params, SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException;
}
/* /*
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -31,6 +31,7 @@ import java.io.Console; ...@@ -31,6 +31,7 @@ import java.io.Console;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
import java.security.Signature;
import java.security.AccessController; import java.security.AccessController;
...@@ -60,6 +61,7 @@ public class SharedSecrets { ...@@ -60,6 +61,7 @@ public class SharedSecrets {
private static JavaOISAccess javaOISAccess; private static JavaOISAccess javaOISAccess;
private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess; private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess;
private static JavaObjectInputStreamAccess javaObjectInputStreamAccess; private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
private static JavaSecuritySignatureAccess javaSecuritySignatureAccess;
public static JavaUtilJarAccess javaUtilJarAccess() { public static JavaUtilJarAccess javaUtilJarAccess() {
if (javaUtilJarAccess == null) { if (javaUtilJarAccess == null) {
...@@ -214,6 +216,17 @@ public class SharedSecrets { ...@@ -214,6 +216,17 @@ public class SharedSecrets {
javaObjectInputStreamAccess = access; javaObjectInputStreamAccess = access;
} }
public static void setJavaSecuritySignatureAccess(JavaSecuritySignatureAccess jssa) {
javaSecuritySignatureAccess = jssa;
}
public static JavaSecuritySignatureAccess getJavaSecuritySignatureAccess() {
if (javaSecuritySignatureAccess == null) {
unsafe.ensureClassInitialized(Signature.class);
}
return javaSecuritySignatureAccess;
}
public static void setJavaxCryptoSealedObjectAccess(JavaxCryptoSealedObjectAccess jcsoa) { public static void setJavaxCryptoSealedObjectAccess(JavaxCryptoSealedObjectAccess jcsoa) {
javaxCryptoSealedObjectAccess = jcsoa; javaxCryptoSealedObjectAccess = jcsoa;
} }
......
/* /*
* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -32,6 +32,8 @@ import java.security.spec.*; ...@@ -32,6 +32,8 @@ import java.security.spec.*;
import java.util.*; import java.util.*;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import sun.security.util.ECUtil;
/** /**
* Repository for well-known Elliptic Curve parameters. It is used by both * Repository for well-known Elliptic Curve parameters. It is used by both
* the SunPKCS11 and SunJSSE code. * the SunPKCS11 and SunJSSE code.
...@@ -104,22 +106,11 @@ public class CurveDB { ...@@ -104,22 +106,11 @@ public class CurveDB {
if (namedCurve.getCurve().getField().getFieldSize() != fieldSize) { if (namedCurve.getCurve().getField().getFieldSize() != fieldSize) {
continue; continue;
} }
if (namedCurve.getCurve().equals(params.getCurve()) == false) { if (ECUtil.equals(namedCurve, params)) {
continue;
}
if (namedCurve.getGenerator().equals(params.getGenerator()) ==
false) {
continue;
}
if (namedCurve.getOrder().equals(params.getOrder()) == false) {
continue;
}
if (namedCurve.getCofactor() != params.getCofactor()) {
continue;
}
// everything matches our named curve, return it // everything matches our named curve, return it
return namedCurve; return namedCurve;
} }
}
// no match found // no match found
return null; return null;
} }
......
/* /*
* Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,9 +25,7 @@ ...@@ -25,9 +25,7 @@
package sun.security.ec; package sun.security.ec;
import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.math.BigInteger;
import java.security.*; import java.security.*;
import java.security.interfaces.*; import java.security.interfaces.*;
...@@ -68,6 +66,9 @@ abstract class ECDSASignature extends SignatureSpi { ...@@ -68,6 +66,9 @@ abstract class ECDSASignature extends SignatureSpi {
// public key, if initialized for verifying // public key, if initialized for verifying
private ECPublicKey publicKey; private ECPublicKey publicKey;
// signature parameters
private ECParameterSpec sigParams = null;
/** /**
* Constructs a new ECDSASignature. Used by Raw subclass. * Constructs a new ECDSASignature. Used by Raw subclass.
* *
...@@ -198,10 +199,14 @@ abstract class ECDSASignature extends SignatureSpi { ...@@ -198,10 +199,14 @@ abstract class ECDSASignature extends SignatureSpi {
@Override @Override
protected void engineInitVerify(PublicKey publicKey) protected void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException { throws InvalidKeyException {
this.publicKey = (ECPublicKey) ECKeyFactory.toECKey(publicKey); ECPublicKey key = (ECPublicKey) ECKeyFactory.toECKey(publicKey);
if (!isCompatible(this.sigParams, key.getParams())) {
throw new InvalidKeyException("Key params does not match signature params");
}
// Should check that the supplied key is appropriate for signature // Should check that the supplied key is appropriate for signature
// algorithm (e.g. P-256 for SHA256withECDSA) // algorithm (e.g. P-256 for SHA256withECDSA)
this.publicKey = key;
this.privateKey = null; this.privateKey = null;
resetDigest(); resetDigest();
} }
...@@ -217,10 +222,14 @@ abstract class ECDSASignature extends SignatureSpi { ...@@ -217,10 +222,14 @@ abstract class ECDSASignature extends SignatureSpi {
@Override @Override
protected void engineInitSign(PrivateKey privateKey, SecureRandom random) protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException { throws InvalidKeyException {
this.privateKey = (ECPrivateKey) ECKeyFactory.toECKey(privateKey); ECPrivateKey key = (ECPrivateKey) ECKeyFactory.toECKey(privateKey);
if (!isCompatible(this.sigParams, key.getParams())) {
throw new InvalidKeyException("Key params does not match signature params");
}
// Should check that the supplied key is appropriate for signature // Should check that the supplied key is appropriate for signature
// algorithm (e.g. P-256 for SHA256withECDSA) // algorithm (e.g. P-256 for SHA256withECDSA)
this.privateKey = key;
this.publicKey = null; this.publicKey = null;
this.random = random; this.random = random;
resetDigest(); resetDigest();
...@@ -273,6 +282,16 @@ abstract class ECDSASignature extends SignatureSpi { ...@@ -273,6 +282,16 @@ abstract class ECDSASignature extends SignatureSpi {
needsReset = true; needsReset = true;
} }
private static boolean isCompatible(ECParameterSpec sigParams,
ECParameterSpec keyParams) {
if (sigParams == null) {
// no restriction on key param
return true;
}
return ECUtil.equals(sigParams, keyParams);
}
private byte[] signDigestImpl(ECDSAOperations ops, int seedBits, private byte[] signDigestImpl(ECDSAOperations ops, int seedBits,
byte[] digest, ECPrivateKeyImpl privImpl, SecureRandom random) byte[] digest, ECPrivateKeyImpl privImpl, SecureRandom random)
throws SignatureException { throws SignatureException {
...@@ -366,7 +385,7 @@ abstract class ECDSASignature extends SignatureSpi { ...@@ -366,7 +385,7 @@ abstract class ECDSASignature extends SignatureSpi {
sig = signDigestNative(privateKey, digest, random); sig = signDigestNative(privateKey, digest, random);
} }
return encodeSignature(sig); return ECUtil.encodeSignature(sig);
} }
// verify the data and return the result. See JCA doc // verify the data and return the result. See JCA doc
...@@ -387,7 +406,8 @@ abstract class ECDSASignature extends SignatureSpi { ...@@ -387,7 +406,8 @@ abstract class ECDSASignature extends SignatureSpi {
try { try {
return verifySignedDigest( return verifySignedDigest(
decodeSignature(signature), getDigestValue(), w, encodedParams); ECUtil.decodeSignature(signature), getDigestValue(),
w, encodedParams);
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {
throw new SignatureException("Could not verify signature", e); throw new SignatureException("Could not verify signature", e);
...@@ -402,6 +422,21 @@ abstract class ECDSASignature extends SignatureSpi { ...@@ -402,6 +422,21 @@ abstract class ECDSASignature extends SignatureSpi {
throw new UnsupportedOperationException("setParameter() not supported"); throw new UnsupportedOperationException("setParameter() not supported");
} }
@Override
protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
if (params != null && !(params instanceof ECParameterSpec)) {
throw new InvalidAlgorithmParameterException("No parameter accepted");
}
ECKey key = (this.privateKey == null? this.publicKey : this.privateKey);
if ((key != null) && !isCompatible((ECParameterSpec)params, key.getParams())) {
throw new InvalidAlgorithmParameterException
("Signature params does not match key params");
}
sigParams = (ECParameterSpec) params;
}
// get parameter, not supported. See JCA doc // get parameter, not supported. See JCA doc
@Override @Override
@Deprecated @Deprecated
...@@ -410,77 +445,19 @@ abstract class ECDSASignature extends SignatureSpi { ...@@ -410,77 +445,19 @@ abstract class ECDSASignature extends SignatureSpi {
throw new UnsupportedOperationException("getParameter() not supported"); throw new UnsupportedOperationException("getParameter() not supported");
} }
// Convert the concatenation of R and S into their DER encoding @Override
private byte[] encodeSignature(byte[] signature) throws SignatureException { protected AlgorithmParameters engineGetParameters() {
if (sigParams == null) {
try { return null;
int n = signature.length >> 1;
byte[] bytes = new byte[n];
System.arraycopy(signature, 0, bytes, 0, n);
BigInteger r = new BigInteger(1, bytes);
System.arraycopy(signature, n, bytes, 0, n);
BigInteger s = new BigInteger(1, bytes);
DerOutputStream out = new DerOutputStream(signature.length + 10);
out.putInteger(r);
out.putInteger(s);
DerValue result =
new DerValue(DerValue.tag_Sequence, out.toByteArray());
return result.toByteArray();
} catch (Exception e) {
throw new SignatureException("Could not encode signature", e);
}
} }
// Convert the DER encoding of R and S into a concatenation of R and S
private byte[] decodeSignature(byte[] sig) throws SignatureException {
try { try {
// Enforce strict DER checking for signatures AlgorithmParameters ap = AlgorithmParameters.getInstance("EC");
DerInputStream in = new DerInputStream(sig, 0, sig.length, false); ap.init(sigParams);
DerValue[] values = in.getSequence(2); return ap;
// check number of components in the read sequence
// and trailing data
if ((values.length != 2) || (in.available() != 0)) {
throw new IOException("Invalid encoding for signature");
}
BigInteger r = values[0].getPositiveBigInteger();
BigInteger s = values[1].getPositiveBigInteger();
// trim leading zeroes
byte[] rBytes = trimZeroes(r.toByteArray());
byte[] sBytes = trimZeroes(s.toByteArray());
int k = Math.max(rBytes.length, sBytes.length);
// r and s each occupy half the array
byte[] result = new byte[k << 1];
System.arraycopy(rBytes, 0, result, k - rBytes.length,
rBytes.length);
System.arraycopy(sBytes, 0, result, result.length - sBytes.length,
sBytes.length);
return result;
} catch (Exception e) { } catch (Exception e) {
throw new SignatureException("Invalid encoding for signature", e); // should never happen
} throw new ProviderException("Error retrieving EC parameters", e);
}
// trim leading (most significant) zeroes from the result
private static byte[] trimZeroes(byte[] b) {
int i = 0;
while ((i < b.length - 1) && (b[i] == 0)) {
i++;
}
if (i == 0) {
return b;
} }
byte[] t = new byte[b.length - i];
System.arraycopy(b, i, t, 0, t.length);
return t;
} }
/** /**
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,20 +28,12 @@ package sun.security.pkcs; ...@@ -28,20 +28,12 @@ package sun.security.pkcs;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.IOException; import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.CryptoPrimitive;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.Timestamp;
import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.security.cert.CertPath; import java.security.cert.CertPath;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.security.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
...@@ -62,6 +54,7 @@ import sun.security.util.ObjectIdentifier; ...@@ -62,6 +54,7 @@ import sun.security.util.ObjectIdentifier;
import sun.security.x509.AlgorithmId; import sun.security.x509.AlgorithmId;
import sun.security.x509.X500Name; import sun.security.x509.X500Name;
import sun.security.x509.KeyUsageExtension; import sun.security.x509.KeyUsageExtension;
import sun.security.util.SignatureUtil;
/** /**
* A SignerInfo, as defined in PKCS#7's signedData type. * A SignerInfo, as defined in PKCS#7's signedData type.
...@@ -453,19 +446,24 @@ public class SignerInfo implements DerEncoder { ...@@ -453,19 +446,24 @@ public class SignerInfo implements DerEncoder {
} }
Signature sig = Signature.getInstance(algname); Signature sig = Signature.getInstance(algname);
sig.initVerify(key);
AlgorithmParameters ap =
digestEncryptionAlgorithmId.getParameters();
try {
SignatureUtil.initVerifyWithParam(sig, key,
SignatureUtil.getParamSpec(algname, ap));
} catch (ProviderException | InvalidAlgorithmParameterException |
InvalidKeyException e) {
throw new SignatureException(e.getMessage(), e);
}
sig.update(dataSigned); sig.update(dataSigned);
if (sig.verify(encryptedDigest)) { if (sig.verify(encryptedDigest)) {
return this; return this;
} }
} catch (IOException e) { } catch (IOException e) {
throw new SignatureException("IO error verifying signature:\n" + throw new SignatureException("IO error verifying signature:\n" +
e.getMessage()); e.getMessage());
} catch (InvalidKeyException e) {
throw new SignatureException("InvalidKey: " + e.getMessage());
} }
return null; return null;
} }
...@@ -476,7 +474,6 @@ public class SignerInfo implements DerEncoder { ...@@ -476,7 +474,6 @@ public class SignerInfo implements DerEncoder {
return verify(block, null); return verify(block, null);
} }
public BigInteger getVersion() { public BigInteger getVersion() {
return version; return version;
} }
......
/* /*
* Copyright (c) 1996, 2013, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -31,11 +31,7 @@ import java.io.IOException; ...@@ -31,11 +31,7 @@ import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.NoSuchAlgorithmException; import java.security.*;
import java.security.InvalidKeyException;
import java.security.Signature;
import java.security.SignatureException;
import java.security.PublicKey;
import java.util.Base64; import java.util.Base64;
...@@ -43,6 +39,8 @@ import sun.security.util.*; ...@@ -43,6 +39,8 @@ import sun.security.util.*;
import sun.security.x509.AlgorithmId; import sun.security.x509.AlgorithmId;
import sun.security.x509.X509Key; import sun.security.x509.X509Key;
import sun.security.x509.X500Name; import sun.security.x509.X500Name;
import sun.security.util.SignatureUtil;
/** /**
* A PKCS #10 certificate request is created and sent to a Certificate * A PKCS #10 certificate request is created and sent to a Certificate
...@@ -169,12 +167,20 @@ public class PKCS10 { ...@@ -169,12 +167,20 @@ public class PKCS10 {
try { try {
sigAlg = id.getName(); sigAlg = id.getName();
sig = Signature.getInstance(sigAlg); sig = Signature.getInstance(sigAlg);
sig.initVerify(subjectPublicKeyInfo); SignatureUtil.initVerifyWithParam(sig, subjectPublicKeyInfo,
SignatureUtil.getParamSpec(sigAlg, id.getParameters()));
sig.update(data); sig.update(data);
if (!sig.verify(sigData)) if (!sig.verify(sigData)) {
throw new SignatureException("Invalid PKCS #10 signature"); throw new SignatureException("Invalid PKCS #10 signature");
}
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {
throw new SignatureException("invalid key"); throw new SignatureException("Invalid key");
} catch (InvalidAlgorithmParameterException e) {
throw new SignatureException("Invalid signature parameters", e);
} catch (ProviderException e) {
throw new SignatureException("Error parsing signature parameters",
e.getCause());
} }
} }
...@@ -226,10 +232,14 @@ public class PKCS10 { ...@@ -226,10 +232,14 @@ public class PKCS10 {
*/ */
AlgorithmId algId = null; AlgorithmId algId = null;
try { try {
algId = AlgorithmId.get(signature.getAlgorithm()); AlgorithmParameters params = signature.getParameters();
algId = params == null
? AlgorithmId.get(signature.getAlgorithm())
: AlgorithmId.get(params);
} catch (NoSuchAlgorithmException nsae) { } catch (NoSuchAlgorithmException nsae) {
throw new SignatureException(nsae); throw new SignatureException(nsae);
} }
algId.encode(scratch); // sig algorithm algId.encode(scratch); // sig algorithm
scratch.putBitString(sig); // sig scratch.putBitString(sig); // sig
......
/* /*
* Copyright (c) 2003, 2019, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -37,7 +37,9 @@ import javax.crypto.*; ...@@ -37,7 +37,9 @@ import javax.crypto.*;
import javax.crypto.interfaces.*; import javax.crypto.interfaces.*;
import javax.crypto.spec.*; import javax.crypto.spec.*;
import sun.security.rsa.RSAUtil.KeyType;
import sun.security.rsa.RSAPublicKeyImpl; import sun.security.rsa.RSAPublicKeyImpl;
import sun.security.rsa.RSAPrivateCrtKeyImpl;
import sun.security.internal.interfaces.TlsMasterSecret; import sun.security.internal.interfaces.TlsMasterSecret;
...@@ -543,11 +545,8 @@ abstract class P11Key implements Key, Length { ...@@ -543,11 +545,8 @@ abstract class P11Key implements Key, Length {
if (encoded == null) { if (encoded == null) {
fetchValues(); fetchValues();
try { try {
// XXX make constructor in SunRsaSign provider public Key newKey = RSAPrivateCrtKeyImpl.newKey
// and call it directly (KeyType.RSA, null, n, e, d, p, q, pe, qe, coeff);
KeyFactory factory = KeyFactory.getInstance
("RSA", P11Util.getSunRsaSignProvider());
Key newKey = factory.translateKey(this);
encoded = newKey.getEncoded(); encoded = newKey.getEncoded();
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {
throw new ProviderException(e); throw new ProviderException(e);
...@@ -647,7 +646,6 @@ abstract class P11Key implements Key, Length { ...@@ -647,7 +646,6 @@ abstract class P11Key implements Key, Length {
private static final class P11RSAPublicKey extends P11Key private static final class P11RSAPublicKey extends P11Key
implements RSAPublicKey { implements RSAPublicKey {
private static final long serialVersionUID = -826726289023854455L; private static final long serialVersionUID = -826726289023854455L;
private BigInteger n, e; private BigInteger n, e;
private byte[] encoded; private byte[] encoded;
P11RSAPublicKey(Session session, long keyID, String algorithm, P11RSAPublicKey(Session session, long keyID, String algorithm,
...@@ -676,7 +674,8 @@ abstract class P11Key implements Key, Length { ...@@ -676,7 +674,8 @@ abstract class P11Key implements Key, Length {
if (encoded == null) { if (encoded == null) {
fetchValues(); fetchValues();
try { try {
encoded = new RSAPublicKeyImpl(n, e).getEncoded(); encoded = RSAPublicKeyImpl.newKey
(KeyType.RSA, null, n, e).getEncoded();
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {
throw new ProviderException(e); throw new ProviderException(e);
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -31,6 +31,7 @@ import java.security.*; ...@@ -31,6 +31,7 @@ import java.security.*;
import java.security.interfaces.*; import java.security.interfaces.*;
import java.security.spec.*; import java.security.spec.*;
import sun.security.rsa.RSAPublicKeyImpl;
import static sun.security.pkcs11.TemplateManager.*; import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*; import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
...@@ -60,7 +61,7 @@ final class P11RSAKeyFactory extends P11KeyFactory { ...@@ -60,7 +61,7 @@ final class P11RSAKeyFactory extends P11KeyFactory {
} else if ("X.509".equals(key.getFormat())) { } else if ("X.509".equals(key.getFormat())) {
// let SunRsaSign provider parse for us, then recurse // let SunRsaSign provider parse for us, then recurse
byte[] encoded = key.getEncoded(); byte[] encoded = key.getEncoded();
key = new sun.security.rsa.RSAPublicKeyImpl(encoded); key = RSAPublicKeyImpl.newKey(encoded);
return implTranslatePublicKey(key); return implTranslatePublicKey(key);
} else { } else {
throw new InvalidKeyException("PublicKey must be instance " throw new InvalidKeyException("PublicKey must be instance "
...@@ -113,7 +114,7 @@ final class P11RSAKeyFactory extends P11KeyFactory { ...@@ -113,7 +114,7 @@ final class P11RSAKeyFactory extends P11KeyFactory {
if (keySpec instanceof X509EncodedKeySpec) { if (keySpec instanceof X509EncodedKeySpec) {
try { try {
byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded(); byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();
PublicKey key = new sun.security.rsa.RSAPublicKeyImpl(encoded); PublicKey key = RSAPublicKeyImpl.newKey(encoded);
return implTranslatePublicKey(key); return implTranslatePublicKey(key);
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {
throw new InvalidKeySpecException throw new InvalidKeySpecException
......
/* /*
* Copyright (c) 2003, 2019, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -31,6 +31,7 @@ import java.nio.ByteBuffer; ...@@ -31,6 +31,7 @@ import java.nio.ByteBuffer;
import java.security.*; import java.security.*;
import java.security.interfaces.*; import java.security.interfaces.*;
import java.security.spec.AlgorithmParameterSpec;
import sun.nio.ch.DirectBuffer; import sun.nio.ch.DirectBuffer;
import sun.security.util.*; import sun.security.util.*;
...@@ -434,9 +435,9 @@ final class P11Signature extends SignatureSpi { ...@@ -434,9 +435,9 @@ final class P11Signature extends SignatureSpi {
} }
// see JCA spec // see JCA spec
@Override
protected void engineInitVerify(PublicKey publicKey) protected void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException { throws InvalidKeyException {
if (publicKey == null) { if (publicKey == null) {
throw new InvalidKeyException("Key must not be null"); throw new InvalidKeyException("Key must not be null");
} }
...@@ -451,9 +452,9 @@ final class P11Signature extends SignatureSpi { ...@@ -451,9 +452,9 @@ final class P11Signature extends SignatureSpi {
} }
// see JCA spec // see JCA spec
@Override
protected void engineInitSign(PrivateKey privateKey) protected void engineInitSign(PrivateKey privateKey)
throws InvalidKeyException { throws InvalidKeyException {
if (privateKey == null) { if (privateKey == null) {
throw new InvalidKeyException("Key must not be null"); throw new InvalidKeyException("Key must not be null");
} }
...@@ -468,6 +469,7 @@ final class P11Signature extends SignatureSpi { ...@@ -468,6 +469,7 @@ final class P11Signature extends SignatureSpi {
} }
// see JCA spec // see JCA spec
@Override
protected void engineUpdate(byte b) throws SignatureException { protected void engineUpdate(byte b) throws SignatureException {
ensureInitialized(); ensureInitialized();
switch (type) { switch (type) {
...@@ -492,6 +494,7 @@ final class P11Signature extends SignatureSpi { ...@@ -492,6 +494,7 @@ final class P11Signature extends SignatureSpi {
} }
// see JCA spec // see JCA spec
@Override
protected void engineUpdate(byte[] b, int ofs, int len) protected void engineUpdate(byte[] b, int ofs, int len)
throws SignatureException { throws SignatureException {
...@@ -535,6 +538,7 @@ final class P11Signature extends SignatureSpi { ...@@ -535,6 +538,7 @@ final class P11Signature extends SignatureSpi {
} }
// see JCA spec // see JCA spec
@Override
protected void engineUpdate(ByteBuffer byteBuffer) { protected void engineUpdate(ByteBuffer byteBuffer) {
ensureInitialized(); ensureInitialized();
...@@ -585,6 +589,7 @@ final class P11Signature extends SignatureSpi { ...@@ -585,6 +589,7 @@ final class P11Signature extends SignatureSpi {
} }
// see JCA spec // see JCA spec
@Override
protected byte[] engineSign() throws SignatureException { protected byte[] engineSign() throws SignatureException {
ensureInitialized(); ensureInitialized();
...@@ -641,6 +646,7 @@ final class P11Signature extends SignatureSpi { ...@@ -641,6 +646,7 @@ final class P11Signature extends SignatureSpi {
} }
// see JCA spec // see JCA spec
@Override
protected boolean engineVerify(byte[] signature) throws SignatureException { protected boolean engineVerify(byte[] signature) throws SignatureException {
ensureInitialized(); ensureInitialized();
boolean doCancel = true; boolean doCancel = true;
...@@ -828,14 +834,31 @@ final class P11Signature extends SignatureSpi { ...@@ -828,14 +834,31 @@ final class P11Signature extends SignatureSpi {
} }
// see JCA spec // see JCA spec
@Override
protected void engineSetParameter(String param, Object value) protected void engineSetParameter(String param, Object value)
throws InvalidParameterException { throws InvalidParameterException {
throw new UnsupportedOperationException("setParameter() not supported"); throw new UnsupportedOperationException("setParameter() not supported");
} }
// see JCA spec // see JCA spec
@Override
protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
if (params != null) {
throw new InvalidAlgorithmParameterException("No parameter accepted");
}
}
// see JCA spec
@Override
protected Object engineGetParameter(String param) protected Object engineGetParameter(String param)
throws InvalidParameterException { throws InvalidParameterException {
throw new UnsupportedOperationException("getParameter() not supported"); throw new UnsupportedOperationException("getParameter() not supported");
} }
// see JCA spec
@Override
protected AlgorithmParameters engineGetParameters() {
return null;
}
} }
/* /*
* Copyright (c) 1996, 2018, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -33,8 +33,7 @@ import java.nio.ByteBuffer; ...@@ -33,8 +33,7 @@ import java.nio.ByteBuffer;
import java.security.*; import java.security.*;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.interfaces.*; import java.security.interfaces.*;
import java.security.spec.DSAParameterSpec; import java.security.spec.*;
import java.security.spec.InvalidParameterSpecException;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.util.DerValue; import sun.security.util.DerValue;
...@@ -314,11 +313,24 @@ abstract class DSA extends SignatureSpi { ...@@ -314,11 +313,24 @@ abstract class DSA extends SignatureSpi {
throw new InvalidParameterException("No parameter accepted"); throw new InvalidParameterException("No parameter accepted");
} }
@Override
protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
if (params != null) {
throw new InvalidAlgorithmParameterException("No parameter accepted");
}
}
@Deprecated @Deprecated
protected Object engineGetParameter(String key) { protected Object engineGetParameter(String key) {
return null; return null;
} }
@Override
protected AlgorithmParameters engineGetParameters() {
return null;
}
private BigInteger generateR(BigInteger p, BigInteger q, BigInteger g, private BigInteger generateR(BigInteger p, BigInteger q, BigInteger g,
BigInteger k) { BigInteger k) {
......
/* /*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -121,7 +121,14 @@ abstract class SHA5 extends DigestBase { ...@@ -121,7 +121,14 @@ abstract class SHA5 extends DigestBase {
i2bBig4((int)bitsProcessed, buffer, 124); i2bBig4((int)bitsProcessed, buffer, 124);
implCompress(buffer, 0); implCompress(buffer, 0);
l2bBig(state, 0, out, ofs, engineGetDigestLength()); int len = engineGetDigestLength();
if (len == 28) {
// Special case for SHA-512/224
l2bBig(state, 0, out, ofs, 24);
i2bBig4((int)(state[3] >> 32), out, ofs + 24);
} else {
l2bBig(state, 0, out, ofs, len);
}
} }
/** /**
...@@ -308,4 +315,31 @@ abstract class SHA5 extends DigestBase { ...@@ -308,4 +315,31 @@ abstract class SHA5 extends DigestBase {
super("SHA-384", 48, INITIAL_HASHES); super("SHA-384", 48, INITIAL_HASHES);
} }
} }
public static final class SHA512_224 extends SHA5 {
private static final long[] INITIAL_HASHES = {
0x8C3D37C819544DA2L, 0x73E1996689DCD4D6L,
0x1DFAB7AE32FF9C82L, 0x679DD514582F9FCFL,
0x0F6D2B697BD44DA8L, 0x77E36F7304C48942L,
0x3F9D85A86A1D36C8L, 0x1112E6AD91D692A1L
};
public SHA512_224() {
super("SHA-512/224", 28, INITIAL_HASHES);
}
}
public static final class SHA512_256 extends SHA5 {
private static final long[] INITIAL_HASHES = {
0x22312194FC2BF72CL, 0x9F555FA3C84C64C2L,
0x2393B86B6F53B151L, 0x963877195940EABDL,
0x96283EE2A88EFFE3L, 0xBE5E1E2553863992L,
0x2B0199FC2C85B8AAL, 0x0EB72DDC81C52CA2L
};
public SHA512_256() {
super("SHA-512/256", 32, INITIAL_HASHES);
}
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -106,6 +106,7 @@ final class SunEntries { ...@@ -106,6 +106,7 @@ final class SunEntries {
map.put("SecureRandom.NativePRNG", map.put("SecureRandom.NativePRNG",
"sun.security.provider.NativePRNG"); "sun.security.provider.NativePRNG");
} }
map.put("SecureRandom.SHA1PRNG", map.put("SecureRandom.SHA1PRNG",
"sun.security.provider.SecureRandom"); "sun.security.provider.SecureRandom");
if (nativeAvailable && !useNativePRNG) { if (nativeAvailable && !useNativePRNG) {
...@@ -200,6 +201,14 @@ final class SunEntries { ...@@ -200,6 +201,14 @@ final class SunEntries {
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.3", "SHA-512"); map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.3", "SHA-512");
map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.3", map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.3",
"SHA-512"); "SHA-512");
map.put("MessageDigest.SHA-512/224", "sun.security.provider.SHA5$SHA512_224");
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.5", "SHA-512/224");
map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.5",
"SHA-512/224");
map.put("MessageDigest.SHA-512/256", "sun.security.provider.SHA5$SHA512_256");
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.6", "SHA-512/256");
map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.6",
"SHA-512/256");
/* /*
* Algorithm Parameter Generator engines * Algorithm Parameter Generator engines
......
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.rsa;
import java.security.*;
/**
* This class implements the MGF1 mask generation function defined in PKCS#1
* v2.2 B.2.1 (https://tools.ietf.org/html/rfc8017#appendix-B.2.1). A mask
* generation function takes an octet string of variable length and a
* desired output length as input and outputs an octet string of the
* desired length. MGF1 is a mask generation function based on a hash
* function, i.e. message digest algorithm.
*
* @since 8
*/
public final class MGF1 {
private final MessageDigest md;
/**
* Construct an instance of MGF1 based on the specified digest algorithm.
*/
MGF1(String mdAlgo) throws NoSuchAlgorithmException {
this.md = MessageDigest.getInstance(mdAlgo);
}
/**
* Using the specified seed bytes, generate the mask, xor the mask
* with the specified output buffer and store the result into the
* output buffer (essentially replaced in place).
*
* @param seed the buffer holding the seed bytes
* @param seedOfs the index of the seed bytes
* @param seedLen the length of the seed bytes to be used by MGF1
* @param maskLen the intended length of the generated mask
* @param out the output buffer holding the mask
* @param outOfs the index of the output buffer for the mask
*/
void generateAndXor(byte[] seed, int seedOfs, int seedLen, int maskLen,
byte[] out, int outOfs) throws RuntimeException {
byte[] C = new byte[4]; // 32 bit counter
byte[] digest = new byte[md.getDigestLength()];
while (maskLen > 0) {
md.update(seed, seedOfs, seedLen);
md.update(C);
try {
md.digest(digest, 0, digest.length);
} catch (DigestException e) {
// should never happen
throw new RuntimeException(e.toString());
}
for (int i = 0; (i < digest.length) && (maskLen > 0); maskLen--) {
out[outOfs++] ^= digest[i++];
}
if (maskLen > 0) {
// increment counter
for (int i = C.length - 1; (++C[i] == 0) && (i > 0); i--) {
// empty
}
}
}
}
/**
* Returns the name of this MGF1 instance, i.e. "MGF1" followed by the
* digest algorithm it based on.
*/
String getName() {
return "MGF1" + md.getAlgorithm();
}
}
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.rsa;
import java.io.*;
import sun.security.util.*;
import sun.security.x509.*;
import java.security.AlgorithmParametersSpi;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.PSSParameterSpec;
import static java.security.spec.PSSParameterSpec.DEFAULT;
/**
* This class implements the PSS parameters used with the RSA
* signatures in PSS padding. Here is its ASN.1 definition:
* RSASSA-PSS-params ::= SEQUENCE {
* hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
* maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
* saltLength [2] INTEGER DEFAULT 20
* trailerField [3] TrailerField DEFAULT trailerFieldBC
* }
*
* @author Valerie Peng
*
*/
public final class PSSParameters extends AlgorithmParametersSpi {
private PSSParameterSpec spec;
public PSSParameters() {
}
@Override
protected void engineInit(AlgorithmParameterSpec paramSpec)
throws InvalidParameterSpecException {
if (!(paramSpec instanceof PSSParameterSpec)) {
throw new InvalidParameterSpecException
("Inappropriate parameter specification");
}
PSSParameterSpec spec = (PSSParameterSpec) paramSpec;
String mgfName = spec.getMGFAlgorithm();
if (!spec.getMGFAlgorithm().equalsIgnoreCase("MGF1")) {
throw new InvalidParameterSpecException("Unsupported mgf " +
mgfName + "; MGF1 only");
}
AlgorithmParameterSpec mgfSpec = spec.getMGFParameters();
if (!(mgfSpec instanceof MGF1ParameterSpec)) {
throw new InvalidParameterSpecException("Inappropriate mgf " +
"parameters; non-null MGF1ParameterSpec only");
}
this.spec = spec;
}
@Override
protected void engineInit(byte[] encoded) throws IOException {
// first initialize with the DEFAULT values before
// retrieving from the encoding bytes
String mdName = DEFAULT.getDigestAlgorithm();
MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec) DEFAULT.getMGFParameters();
int saltLength = DEFAULT.getSaltLength();
int trailerField = DEFAULT.getTrailerField();
DerInputStream der = new DerInputStream(encoded);
DerValue[] datum = der.getSequence(4);
for (DerValue d : datum) {
if (d.isContextSpecific((byte) 0x00)) {
// hash algid
mdName = AlgorithmId.parse
(d.data.getDerValue()).getName();
} else if (d.isContextSpecific((byte) 0x01)) {
// mgf algid
AlgorithmId val = AlgorithmId.parse(d.data.getDerValue());
if (!val.getOID().equals(AlgorithmId.mgf1_oid)) {
throw new IOException("Only MGF1 mgf is supported");
}
AlgorithmId params = AlgorithmId.parse(
new DerValue(val.getEncodedParams()));
String mgfDigestName = params.getName();
switch (mgfDigestName) {
case "SHA-1":
mgfSpec = MGF1ParameterSpec.SHA1;
break;
case "SHA-224":
mgfSpec = MGF1ParameterSpec.SHA224;
break;
case "SHA-256":
mgfSpec = MGF1ParameterSpec.SHA256;
break;
case "SHA-384":
mgfSpec = MGF1ParameterSpec.SHA384;
break;
case "SHA-512":
mgfSpec = MGF1ParameterSpec.SHA512;
break;
case "SHA-512/224":
mgfSpec = MGF1ParameterSpec.SHA512_224;
break;
case "SHA-512/256":
mgfSpec = MGF1ParameterSpec.SHA512_256;
break;
default:
throw new IOException
("Unrecognized message digest algorithm " +
mgfDigestName);
}
} else if (d.isContextSpecific((byte) 0x02)) {
// salt length
saltLength = d.data.getDerValue().getInteger();
if (saltLength < 0) {
throw new IOException("Negative value for saltLength");
}
} else if (d.isContextSpecific((byte) 0x03)) {
// trailer field
trailerField = d.data.getDerValue().getInteger();
if (trailerField != 1) {
throw new IOException("Unsupported trailerField value " +
trailerField);
}
} else {
throw new IOException("Invalid encoded PSSParameters");
}
}
this.spec = new PSSParameterSpec(mdName, "MGF1", mgfSpec,
saltLength, trailerField);
}
@Override
protected void engineInit(byte[] encoded, String decodingMethod)
throws IOException {
if ((decodingMethod != null) &&
(!decodingMethod.equalsIgnoreCase("ASN.1"))) {
throw new IllegalArgumentException("Only support ASN.1 format");
}
engineInit(encoded);
}
@Override
protected <T extends AlgorithmParameterSpec>
T engineGetParameterSpec(Class<T> paramSpec)
throws InvalidParameterSpecException {
if (PSSParameterSpec.class.isAssignableFrom(paramSpec)) {
return paramSpec.cast(spec);
} else {
throw new InvalidParameterSpecException
("Inappropriate parameter specification");
}
}
@Override
protected byte[] engineGetEncoded() throws IOException {
return getEncoded(spec);
}
@Override
protected byte[] engineGetEncoded(String encMethod) throws IOException {
if ((encMethod != null) &&
(!encMethod.equalsIgnoreCase("ASN.1"))) {
throw new IllegalArgumentException("Only support ASN.1 format");
}
return engineGetEncoded();
}
@Override
protected String engineToString() {
return spec.toString();
}
/**
* Returns the encoding of a {@link PSSParameterSpec} object. This method
* is used in this class and {@link AlgorithmId}.
*
* @param spec a {@code PSSParameterSpec} object
* @return its DER encoding
* @throws IOException if the name of a MessageDigest or MaskGenAlgorithm
* is unsupported
*/
public static byte[] getEncoded(PSSParameterSpec spec) throws IOException {
AlgorithmParameterSpec mgfSpec = spec.getMGFParameters();
if (!(mgfSpec instanceof MGF1ParameterSpec)) {
throw new IOException("Cannot encode " + mgfSpec);
}
MGF1ParameterSpec mgf1Spec = (MGF1ParameterSpec)mgfSpec;
DerOutputStream tmp = new DerOutputStream();
DerOutputStream tmp2, tmp3;
// MD
AlgorithmId mdAlgId;
try {
mdAlgId = AlgorithmId.get(spec.getDigestAlgorithm());
} catch (NoSuchAlgorithmException nsae) {
throw new IOException("AlgorithmId " + spec.getDigestAlgorithm() +
" impl not found");
}
if (!mdAlgId.getOID().equals(AlgorithmId.SHA_oid)) {
tmp2 = new DerOutputStream();
mdAlgId.derEncode(tmp2);
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0),
tmp2);
}
// MGF
AlgorithmId mgfDigestId;
try {
mgfDigestId = AlgorithmId.get(mgf1Spec.getDigestAlgorithm());
} catch (NoSuchAlgorithmException nase) {
throw new IOException("AlgorithmId " +
mgf1Spec.getDigestAlgorithm() + " impl not found");
}
if (!mgfDigestId.getOID().equals(AlgorithmId.SHA_oid)) {
tmp2 = new DerOutputStream();
tmp2.putOID(AlgorithmId.mgf1_oid);
mgfDigestId.encode(tmp2);
tmp3 = new DerOutputStream();
tmp3.write(DerValue.tag_Sequence, tmp2);
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 1),
tmp3);
}
// SaltLength
if (spec.getSaltLength() != 20) {
tmp2 = new DerOutputStream();
tmp2.putInteger(spec.getSaltLength());
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 2),
tmp2);
}
// TrailerField
if (spec.getTrailerField() != PSSParameterSpec.TRAILER_FIELD_BC) {
tmp2 = new DerOutputStream();
tmp2.putInteger(spec.getTrailerField());
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 3),
tmp2);
}
// Put all together under a SEQUENCE tag
DerOutputStream out = new DerOutputStream();
out.write(DerValue.tag_Sequence, tmp);
return out.toByteArray();
}
}
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -32,10 +32,15 @@ import java.security.interfaces.*; ...@@ -32,10 +32,15 @@ import java.security.interfaces.*;
import java.security.spec.*; import java.security.spec.*;
import sun.security.action.GetPropertyAction; import sun.security.action.GetPropertyAction;
import sun.security.x509.AlgorithmId;
import static sun.security.rsa.RSAUtil.KeyType;
/** /**
* KeyFactory for RSA keys. Keys must be instances of PublicKey or PrivateKey * KeyFactory for RSA keys, e.g. "RSA", "RSASSA-PSS".
* and getAlgorithm() must return "RSA". For such keys, it supports conversion * Keys must be instances of PublicKey or PrivateKey
* and getAlgorithm() must return a value which matches the type which are
* specified during construction time of the KeyFactory object.
* For such keys, it supports conversion
* between the following: * between the following:
* *
* For public keys: * For public keys:
...@@ -58,21 +63,21 @@ import sun.security.action.GetPropertyAction; ...@@ -58,21 +63,21 @@ import sun.security.action.GetPropertyAction;
* @since 1.5 * @since 1.5
* @author Andreas Sterbenz * @author Andreas Sterbenz
*/ */
public final class RSAKeyFactory extends KeyFactorySpi { public class RSAKeyFactory extends KeyFactorySpi {
private final static Class<?> rsaPublicKeySpecClass = private static final Class<?> RSA_PUB_KEYSPEC_CLS = RSAPublicKeySpec.class;
RSAPublicKeySpec.class; private static final Class<?> RSA_PRIV_KEYSPEC_CLS =
private final static Class<?> rsaPrivateKeySpecClass =
RSAPrivateKeySpec.class; RSAPrivateKeySpec.class;
private final static Class<?> rsaPrivateCrtKeySpecClass = private static final Class<?> RSA_PRIVCRT_KEYSPEC_CLS =
RSAPrivateCrtKeySpec.class; RSAPrivateCrtKeySpec.class;
private static final Class<?> X509_KEYSPEC_CLS = X509EncodedKeySpec.class;
private final static Class<?> x509KeySpecClass = X509EncodedKeySpec.class; private static final Class<?> PKCS8_KEYSPEC_CLS = PKCS8EncodedKeySpec.class;
private final static Class<?> pkcs8KeySpecClass = PKCS8EncodedKeySpec.class;
public final static int MIN_MODLEN = 512; public final static int MIN_MODLEN = 512;
public final static int MAX_MODLEN = 16384; public final static int MAX_MODLEN = 16384;
private final KeyType type;
/* /*
* If the modulus length is above this value, restrict the size of * If the modulus length is above this value, restrict the size of
* the exponent to something that can be reasonably computed. We * the exponent to something that can be reasonably computed. We
...@@ -88,11 +93,18 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -88,11 +93,18 @@ public final class RSAKeyFactory extends KeyFactorySpi {
new GetPropertyAction( new GetPropertyAction(
"sun.security.rsa.restrictRSAExponent", "true"))); "sun.security.rsa.restrictRSAExponent", "true")));
// instance used for static translateKey(); static RSAKeyFactory getInstance(KeyType type) {
private final static RSAKeyFactory INSTANCE = new RSAKeyFactory(); return new RSAKeyFactory(type);
}
public RSAKeyFactory() { // Internal utility method for checking key algorithm
// empty private static void checkKeyAlgo(Key key, String expectedAlg)
throws InvalidKeyException {
String keyAlg = key.getAlgorithm();
if (keyAlg == null || !(keyAlg.equalsIgnoreCase(expectedAlg))) {
throw new InvalidKeyException("Expected a " + expectedAlg
+ " key, but got " + keyAlg);
}
} }
/** /**
...@@ -108,7 +120,13 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -108,7 +120,13 @@ public final class RSAKeyFactory extends KeyFactorySpi {
(key instanceof RSAPublicKeyImpl)) { (key instanceof RSAPublicKeyImpl)) {
return (RSAKey)key; return (RSAKey)key;
} else { } else {
return (RSAKey)INSTANCE.engineTranslateKey(key); try {
KeyType type = KeyType.lookup(key.getAlgorithm());
RSAKeyFactory kf = RSAKeyFactory.getInstance(type);
return (RSAKey) kf.engineTranslateKey(key);
} catch (ProviderException e) {
throw new InvalidKeyException(e);
}
} }
} }
...@@ -172,6 +190,15 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -172,6 +190,15 @@ public final class RSAKeyFactory extends KeyFactorySpi {
} }
} }
// disallowed as KeyType is required
private RSAKeyFactory() {
this.type = KeyType.RSA;
}
public RSAKeyFactory(KeyType type) {
this.type = type;
}
/** /**
* Translate an RSA key into a SunRsaSign RSA key. If conversion is * Translate an RSA key into a SunRsaSign RSA key. If conversion is
* not possible, throw an InvalidKeyException. * not possible, throw an InvalidKeyException.
...@@ -181,9 +208,14 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -181,9 +208,14 @@ public final class RSAKeyFactory extends KeyFactorySpi {
if (key == null) { if (key == null) {
throw new InvalidKeyException("Key must not be null"); throw new InvalidKeyException("Key must not be null");
} }
String keyAlg = key.getAlgorithm(); // ensure the key algorithm matches the current KeyFactory instance
if (keyAlg.equals("RSA") == false) { checkKeyAlgo(key, type.keyAlgo());
throw new InvalidKeyException("Not an RSA key: " + keyAlg);
// no translation needed if the key is already our own impl
if ((key instanceof RSAPrivateKeyImpl) ||
(key instanceof RSAPrivateCrtKeyImpl) ||
(key instanceof RSAPublicKeyImpl)) {
return key;
} }
if (key instanceof PublicKey) { if (key instanceof PublicKey) {
return translatePublicKey((PublicKey)key); return translatePublicKey((PublicKey)key);
...@@ -222,22 +254,21 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -222,22 +254,21 @@ public final class RSAKeyFactory extends KeyFactorySpi {
private PublicKey translatePublicKey(PublicKey key) private PublicKey translatePublicKey(PublicKey key)
throws InvalidKeyException { throws InvalidKeyException {
if (key instanceof RSAPublicKey) { if (key instanceof RSAPublicKey) {
if (key instanceof RSAPublicKeyImpl) {
return key;
}
RSAPublicKey rsaKey = (RSAPublicKey)key; RSAPublicKey rsaKey = (RSAPublicKey)key;
try { try {
return new RSAPublicKeyImpl( return new RSAPublicKeyImpl(
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
rsaKey.getModulus(), rsaKey.getModulus(),
rsaKey.getPublicExponent() rsaKey.getPublicExponent());
); } catch (ProviderException e) {
} catch (RuntimeException e) {
// catch providers that incorrectly implement RSAPublicKey // catch providers that incorrectly implement RSAPublicKey
throw new InvalidKeyException("Invalid key", e); throw new InvalidKeyException("Invalid key", e);
} }
} else if ("X.509".equals(key.getFormat())) { } else if ("X.509".equals(key.getFormat())) {
byte[] encoded = key.getEncoded(); RSAPublicKey translated = new RSAPublicKeyImpl(key.getEncoded());
return new RSAPublicKeyImpl(encoded); // ensure the key algorithm matches the current KeyFactory instance
checkKeyAlgo(translated, type.keyAlgo());
return translated;
} else { } else {
throw new InvalidKeyException("Public keys must be instance " throw new InvalidKeyException("Public keys must be instance "
+ "of RSAPublicKey or have X.509 encoding"); + "of RSAPublicKey or have X.509 encoding");
...@@ -248,12 +279,10 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -248,12 +279,10 @@ public final class RSAKeyFactory extends KeyFactorySpi {
private PrivateKey translatePrivateKey(PrivateKey key) private PrivateKey translatePrivateKey(PrivateKey key)
throws InvalidKeyException { throws InvalidKeyException {
if (key instanceof RSAPrivateCrtKey) { if (key instanceof RSAPrivateCrtKey) {
if (key instanceof RSAPrivateCrtKeyImpl) {
return key;
}
RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key; RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
try { try {
return new RSAPrivateCrtKeyImpl( return new RSAPrivateCrtKeyImpl(
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
rsaKey.getModulus(), rsaKey.getModulus(),
rsaKey.getPublicExponent(), rsaKey.getPublicExponent(),
rsaKey.getPrivateExponent(), rsaKey.getPrivateExponent(),
...@@ -263,27 +292,28 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -263,27 +292,28 @@ public final class RSAKeyFactory extends KeyFactorySpi {
rsaKey.getPrimeExponentQ(), rsaKey.getPrimeExponentQ(),
rsaKey.getCrtCoefficient() rsaKey.getCrtCoefficient()
); );
} catch (RuntimeException e) { } catch (ProviderException e) {
// catch providers that incorrectly implement RSAPrivateCrtKey // catch providers that incorrectly implement RSAPrivateCrtKey
throw new InvalidKeyException("Invalid key", e); throw new InvalidKeyException("Invalid key", e);
} }
} else if (key instanceof RSAPrivateKey) { } else if (key instanceof RSAPrivateKey) {
if (key instanceof RSAPrivateKeyImpl) {
return key;
}
RSAPrivateKey rsaKey = (RSAPrivateKey)key; RSAPrivateKey rsaKey = (RSAPrivateKey)key;
try { try {
return new RSAPrivateKeyImpl( return new RSAPrivateKeyImpl(
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
rsaKey.getModulus(), rsaKey.getModulus(),
rsaKey.getPrivateExponent() rsaKey.getPrivateExponent()
); );
} catch (RuntimeException e) { } catch (ProviderException e) {
// catch providers that incorrectly implement RSAPrivateKey // catch providers that incorrectly implement RSAPrivateKey
throw new InvalidKeyException("Invalid key", e); throw new InvalidKeyException("Invalid key", e);
} }
} else if ("PKCS#8".equals(key.getFormat())) { } else if ("PKCS#8".equals(key.getFormat())) {
byte[] encoded = key.getEncoded(); RSAPrivateKey translated =
return RSAPrivateCrtKeyImpl.newKey(encoded); RSAPrivateCrtKeyImpl.newKey(key.getEncoded());
// ensure the key algorithm matches the current KeyFactory instance
checkKeyAlgo(translated, type.keyAlgo());
return translated;
} else { } else {
throw new InvalidKeyException("Private keys must be instance " throw new InvalidKeyException("Private keys must be instance "
+ "of RSAPrivate(Crt)Key or have PKCS#8 encoding"); + "of RSAPrivate(Crt)Key or have PKCS#8 encoding");
...@@ -295,13 +325,21 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -295,13 +325,21 @@ public final class RSAKeyFactory extends KeyFactorySpi {
throws GeneralSecurityException { throws GeneralSecurityException {
if (keySpec instanceof X509EncodedKeySpec) { if (keySpec instanceof X509EncodedKeySpec) {
X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec; X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec;
return new RSAPublicKeyImpl(x509Spec.getEncoded()); RSAPublicKey generated = new RSAPublicKeyImpl(x509Spec.getEncoded());
// ensure the key algorithm matches the current KeyFactory instance
checkKeyAlgo(generated, type.keyAlgo());
return generated;
} else if (keySpec instanceof RSAPublicKeySpec) { } else if (keySpec instanceof RSAPublicKeySpec) {
RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec; RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec;
try {
return new RSAPublicKeyImpl( return new RSAPublicKeyImpl(
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
rsaSpec.getModulus(), rsaSpec.getModulus(),
rsaSpec.getPublicExponent() rsaSpec.getPublicExponent()
); );
} catch (ProviderException e) {
throw new InvalidKeySpecException(e);
}
} else { } else {
throw new InvalidKeySpecException("Only RSAPublicKeySpec " throw new InvalidKeySpecException("Only RSAPublicKeySpec "
+ "and X509EncodedKeySpec supported for RSA public keys"); + "and X509EncodedKeySpec supported for RSA public keys");
...@@ -313,10 +351,15 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -313,10 +351,15 @@ public final class RSAKeyFactory extends KeyFactorySpi {
throws GeneralSecurityException { throws GeneralSecurityException {
if (keySpec instanceof PKCS8EncodedKeySpec) { if (keySpec instanceof PKCS8EncodedKeySpec) {
PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec; PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec;
return RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded()); RSAPrivateKey generated = RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded());
// ensure the key algorithm matches the current KeyFactory instance
checkKeyAlgo(generated, type.keyAlgo());
return generated;
} else if (keySpec instanceof RSAPrivateCrtKeySpec) { } else if (keySpec instanceof RSAPrivateCrtKeySpec) {
RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec; RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec;
try {
return new RSAPrivateCrtKeyImpl( return new RSAPrivateCrtKeyImpl(
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
rsaSpec.getModulus(), rsaSpec.getModulus(),
rsaSpec.getPublicExponent(), rsaSpec.getPublicExponent(),
rsaSpec.getPrivateExponent(), rsaSpec.getPrivateExponent(),
...@@ -326,12 +369,20 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -326,12 +369,20 @@ public final class RSAKeyFactory extends KeyFactorySpi {
rsaSpec.getPrimeExponentQ(), rsaSpec.getPrimeExponentQ(),
rsaSpec.getCrtCoefficient() rsaSpec.getCrtCoefficient()
); );
} catch (ProviderException e) {
throw new InvalidKeySpecException(e);
}
} else if (keySpec instanceof RSAPrivateKeySpec) { } else if (keySpec instanceof RSAPrivateKeySpec) {
RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec; RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec;
try {
return new RSAPrivateKeyImpl( return new RSAPrivateKeyImpl(
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
rsaSpec.getModulus(), rsaSpec.getModulus(),
rsaSpec.getPrivateExponent() rsaSpec.getPrivateExponent()
); );
} catch (ProviderException e) {
throw new InvalidKeySpecException(e);
}
} else { } else {
throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec " throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec "
+ "and PKCS8EncodedKeySpec supported for RSA private keys"); + "and PKCS8EncodedKeySpec supported for RSA private keys");
...@@ -350,12 +401,13 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -350,12 +401,13 @@ public final class RSAKeyFactory extends KeyFactorySpi {
} }
if (key instanceof RSAPublicKey) { if (key instanceof RSAPublicKey) {
RSAPublicKey rsaKey = (RSAPublicKey)key; RSAPublicKey rsaKey = (RSAPublicKey)key;
if (rsaPublicKeySpecClass.isAssignableFrom(keySpec)) { if (RSA_PUB_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
return keySpec.cast(new RSAPublicKeySpec( return keySpec.cast(new RSAPublicKeySpec(
rsaKey.getModulus(), rsaKey.getModulus(),
rsaKey.getPublicExponent() rsaKey.getPublicExponent(),
rsaKey.getParams()
)); ));
} else if (x509KeySpecClass.isAssignableFrom(keySpec)) { } else if (X509_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
return keySpec.cast(new X509EncodedKeySpec(key.getEncoded())); return keySpec.cast(new X509EncodedKeySpec(key.getEncoded()));
} else { } else {
throw new InvalidKeySpecException throw new InvalidKeySpecException
...@@ -363,9 +415,9 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -363,9 +415,9 @@ public final class RSAKeyFactory extends KeyFactorySpi {
+ "X509EncodedKeySpec for RSA public keys"); + "X509EncodedKeySpec for RSA public keys");
} }
} else if (key instanceof RSAPrivateKey) { } else if (key instanceof RSAPrivateKey) {
if (pkcs8KeySpecClass.isAssignableFrom(keySpec)) { if (PKCS8_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
return keySpec.cast(new PKCS8EncodedKeySpec(key.getEncoded())); return keySpec.cast(new PKCS8EncodedKeySpec(key.getEncoded()));
} else if (rsaPrivateCrtKeySpecClass.isAssignableFrom(keySpec)) { } else if (RSA_PRIVCRT_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
if (key instanceof RSAPrivateCrtKey) { if (key instanceof RSAPrivateCrtKey) {
RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey)key; RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey)key;
return keySpec.cast(new RSAPrivateCrtKeySpec( return keySpec.cast(new RSAPrivateCrtKeySpec(
...@@ -376,17 +428,19 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -376,17 +428,19 @@ public final class RSAKeyFactory extends KeyFactorySpi {
crtKey.getPrimeQ(), crtKey.getPrimeQ(),
crtKey.getPrimeExponentP(), crtKey.getPrimeExponentP(),
crtKey.getPrimeExponentQ(), crtKey.getPrimeExponentQ(),
crtKey.getCrtCoefficient() crtKey.getCrtCoefficient(),
crtKey.getParams()
)); ));
} else { } else {
throw new InvalidKeySpecException throw new InvalidKeySpecException
("RSAPrivateCrtKeySpec can only be used with CRT keys"); ("RSAPrivateCrtKeySpec can only be used with CRT keys");
} }
} else if (rsaPrivateKeySpecClass.isAssignableFrom(keySpec)) { } else if (RSA_PRIV_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
RSAPrivateKey rsaKey = (RSAPrivateKey)key; RSAPrivateKey rsaKey = (RSAPrivateKey)key;
return keySpec.cast(new RSAPrivateKeySpec( return keySpec.cast(new RSAPrivateKeySpec(
rsaKey.getModulus(), rsaKey.getModulus(),
rsaKey.getPrivateExponent() rsaKey.getPrivateExponent(),
rsaKey.getParams()
)); ));
} else { } else {
throw new InvalidKeySpecException throw new InvalidKeySpecException
...@@ -398,4 +452,16 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -398,4 +452,16 @@ public final class RSAKeyFactory extends KeyFactorySpi {
throw new InvalidKeySpecException("Neither public nor private key"); throw new InvalidKeySpecException("Neither public nor private key");
} }
} }
public static final class Legacy extends RSAKeyFactory {
public Legacy() {
super(KeyType.RSA);
}
}
public static final class PSS extends RSAKeyFactory {
public PSS() {
super(KeyType.PSS);
}
}
} }
/* /*
* Copyright (c) 2003, 2017, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -33,6 +33,9 @@ import java.security.spec.RSAKeyGenParameterSpec; ...@@ -33,6 +33,9 @@ import java.security.spec.RSAKeyGenParameterSpec;
import sun.security.jca.JCAUtil; import sun.security.jca.JCAUtil;
import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE; import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
import static sun.security.util.SecurityProviderConstants.DEF_RSASSA_PSS_KEY_SIZE;
import sun.security.x509.AlgorithmId;
import static sun.security.rsa.RSAUtil.KeyType;
/** /**
* RSA keypair generation. Standard algorithm, minimum key length 512 bit. * RSA keypair generation. Standard algorithm, minimum key length 512 bit.
...@@ -43,7 +46,7 @@ import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE; ...@@ -43,7 +46,7 @@ import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
* @since 1.5 * @since 1.5
* @author Andreas Sterbenz * @author Andreas Sterbenz
*/ */
public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi { public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
// public exponent to use // public exponent to use
private BigInteger publicExponent; private BigInteger publicExponent;
...@@ -51,35 +54,31 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -51,35 +54,31 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
// size of the key to generate, >= RSAKeyFactory.MIN_MODLEN // size of the key to generate, >= RSAKeyFactory.MIN_MODLEN
private int keySize; private int keySize;
private final KeyType type;
private AlgorithmId rsaId;
// PRNG to use // PRNG to use
private SecureRandom random; private SecureRandom random;
public RSAKeyPairGenerator() { RSAKeyPairGenerator(KeyType type, int defKeySize) {
this.type = type;
// initialize to default in case the app does not call initialize() // initialize to default in case the app does not call initialize()
initialize(DEF_RSA_KEY_SIZE, null); initialize(defKeySize, null);
} }
// initialize the generator. See JCA doc // initialize the generator. See JCA doc
public void initialize(int keySize, SecureRandom random) { public void initialize(int keySize, SecureRandom random) {
// do not allow unreasonably small or large key sizes,
// probably user error
try { try {
RSAKeyFactory.checkKeyLengths(keySize, RSAKeyGenParameterSpec.F4, initialize(new RSAKeyGenParameterSpec(keySize,
512, 64 * 1024); RSAKeyGenParameterSpec.F4), null);
} catch (InvalidKeyException e) { } catch (InvalidAlgorithmParameterException iape) {
throw new InvalidParameterException(e.getMessage()); throw new InvalidParameterException(iape.getMessage());
} }
this.keySize = keySize;
this.random = random;
this.publicExponent = RSAKeyGenParameterSpec.F4;
} }
// second initialize method. See JCA doc. // second initialize method. See JCA doc.
public void initialize(AlgorithmParameterSpec params, SecureRandom random) public void initialize(AlgorithmParameterSpec params, SecureRandom random)
throws InvalidAlgorithmParameterException { throws InvalidAlgorithmParameterException {
if (params instanceof RSAKeyGenParameterSpec == false) { if (params instanceof RSAKeyGenParameterSpec == false) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("Params must be instance of RSAKeyGenParameterSpec"); ("Params must be instance of RSAKeyGenParameterSpec");
...@@ -88,6 +87,7 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -88,6 +87,7 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params; RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params;
int tmpKeySize = rsaSpec.getKeysize(); int tmpKeySize = rsaSpec.getKeysize();
BigInteger tmpPublicExponent = rsaSpec.getPublicExponent(); BigInteger tmpPublicExponent = rsaSpec.getPublicExponent();
AlgorithmParameterSpec tmpParams = rsaSpec.getKeyParams();
if (tmpPublicExponent == null) { if (tmpPublicExponent == null) {
tmpPublicExponent = RSAKeyGenParameterSpec.F4; tmpPublicExponent = RSAKeyGenParameterSpec.F4;
...@@ -111,6 +111,13 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -111,6 +111,13 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
"Invalid key sizes", e); "Invalid key sizes", e);
} }
try {
this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams);
} catch (ProviderException e) {
throw new InvalidAlgorithmParameterException(
"Invalid key parameters", e);
}
this.keySize = tmpKeySize; this.keySize = tmpKeySize;
this.publicExponent = tmpPublicExponent; this.publicExponent = tmpPublicExponent;
this.random = random; this.random = random;
...@@ -166,9 +173,9 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -166,9 +173,9 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
BigInteger coeff = q.modInverse(p); BigInteger coeff = q.modInverse(p);
try { try {
PublicKey publicKey = new RSAPublicKeyImpl(n, e); PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e);
PrivateKey privateKey = PrivateKey privateKey = new RSAPrivateCrtKeyImpl(
new RSAPrivateCrtKeyImpl(n, e, d, p, q, pe, qe, coeff); rsaId, n, e, d, p, q, pe, qe, coeff);
return new KeyPair(publicKey, privateKey); return new KeyPair(publicKey, privateKey);
} catch (InvalidKeyException exc) { } catch (InvalidKeyException exc) {
// invalid key exception only thrown for keys < 512 bit, // invalid key exception only thrown for keys < 512 bit,
...@@ -178,4 +185,15 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -178,4 +185,15 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
} }
} }
public static final class Legacy extends RSAKeyPairGenerator {
public Legacy() {
super(KeyType.RSA, DEF_RSA_KEY_SIZE);
}
}
public static final class PSS extends RSAKeyPairGenerator {
public PSS() {
super(KeyType.PSS, DEF_RSASSA_PSS_KEY_SIZE);
}
}
} }
此差异已折叠。
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -39,16 +39,13 @@ import sun.security.jca.JCAUtil; ...@@ -39,16 +39,13 @@ import sun.security.jca.JCAUtil;
/** /**
* RSA padding and unpadding. * RSA padding and unpadding.
* *
* The various PKCS#1 versions can be found in the EMC/RSA Labs * The various PKCS#1 versions can be found in the IETF RFCs
* web site, which is currently: * tracking the corresponding PKCS#1 standards.
* *
* http://www.emc.com/emc-plus/rsa-labs/index.htm * RFC 2313: PKCS#1 v1.5
* * RFC 2437: PKCS#1 v2.0
* or in the IETF RFCs derived from the above PKCS#1 standards. * RFC 3447: PKCS#1 v2.1
* * RFC 8017: PKCS#1 v2.2
* RFC 2313: v1.5
* RFC 2437: v2.0
* RFC 3447: v2.1
* *
* The format of PKCS#1 v1.5 padding is: * The format of PKCS#1 v1.5 padding is:
* *
...@@ -105,11 +102,11 @@ public final class RSAPadding { ...@@ -105,11 +102,11 @@ public final class RSAPadding {
// maximum size of the data // maximum size of the data
private final int maxDataSize; private final int maxDataSize;
// OAEP: main messagedigest // OAEP: main message digest
private MessageDigest md; private MessageDigest md;
// OAEP: message digest for MGF1 // OAEP: MGF1
private MessageDigest mgfMd; private MGF1 mgf;
// OAEP: value of digest of data (user-supplied or zero-length) using md // OAEP: value of digest of data (user-supplied or zero-length) using md
private byte[] lHash; private byte[] lHash;
...@@ -164,7 +161,7 @@ public final class RSAPadding { ...@@ -164,7 +161,7 @@ public final class RSAPadding {
break; break;
case PAD_OAEP_MGF1: case PAD_OAEP_MGF1:
String mdName = "SHA-1"; String mdName = "SHA-1";
String mgfMdName = "SHA-1"; String mgfMdName = mdName;
byte[] digestInput = null; byte[] digestInput = null;
try { try {
if (spec != null) { if (spec != null) {
...@@ -185,10 +182,9 @@ public final class RSAPadding { ...@@ -185,10 +182,9 @@ public final class RSAPadding {
digestInput = ((PSource.PSpecified) pSrc).getValue(); digestInput = ((PSource.PSpecified) pSrc).getValue();
} }
md = MessageDigest.getInstance(mdName); md = MessageDigest.getInstance(mdName);
mgfMd = MessageDigest.getInstance(mgfMdName); mgf = new MGF1(mgfMdName);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
throw new InvalidKeyException throw new InvalidKeyException("Digest not available", e);
("Digest " + mdName + " not available", e);
} }
lHash = getInitialHash(md, digestInput); lHash = getInitialHash(md, digestInput);
int digestLen = lHash.length; int digestLen = lHash.length;
...@@ -196,7 +192,7 @@ public final class RSAPadding { ...@@ -196,7 +192,7 @@ public final class RSAPadding {
if (maxDataSize <= 0) { if (maxDataSize <= 0) {
throw new InvalidKeyException throw new InvalidKeyException
("Key is too short for encryption using OAEPPadding" + ("Key is too short for encryption using OAEPPadding" +
" with " + mdName + " and MGF1" + mgfMdName); " with " + mdName + " and " + mgf.getName());
} }
break; break;
default: default:
...@@ -432,10 +428,10 @@ public final class RSAPadding { ...@@ -432,10 +428,10 @@ public final class RSAPadding {
System.arraycopy(M, 0, EM, mStart, M.length); System.arraycopy(M, 0, EM, mStart, M.length);
// produce maskedDB // produce maskedDB
mgf1(EM, seedStart, seedLen, EM, dbStart, dbLen); mgf.generateAndXor(EM, seedStart, seedLen, dbLen, EM, dbStart);
// produce maskSeed // produce maskSeed
mgf1(EM, dbStart, dbLen, EM, seedStart, seedLen); mgf.generateAndXor(EM, dbStart, dbLen, seedLen, EM, seedStart);
return EM; return EM;
} }
...@@ -458,8 +454,8 @@ public final class RSAPadding { ...@@ -458,8 +454,8 @@ public final class RSAPadding {
int dbStart = hLen + 1; int dbStart = hLen + 1;
int dbLen = EM.length - dbStart; int dbLen = EM.length - dbStart;
mgf1(EM, dbStart, dbLen, EM, seedStart, seedLen); mgf.generateAndXor(EM, dbStart, dbLen, seedLen, EM, seedStart);
mgf1(EM, seedStart, seedLen, EM, dbStart, dbLen); mgf.generateAndXor(EM, seedStart, seedLen, dbLen, EM, dbStart);
// verify lHash == lHash' // verify lHash == lHash'
for (int i = 0; i < hLen; i++) { for (int i = 0; i < hLen; i++) {
...@@ -507,37 +503,4 @@ public final class RSAPadding { ...@@ -507,37 +503,4 @@ public final class RSAPadding {
return m; return m;
} }
} }
/**
* Compute MGF1 using mgfMD as the message digest.
* Note that we combine MGF1 with the XOR operation to reduce data
* copying.
*
* We generate maskLen bytes of MGF1 from the seed and XOR it into
* out[] starting at outOfs;
*/
private void mgf1(byte[] seed, int seedOfs, int seedLen,
byte[] out, int outOfs, int maskLen) throws BadPaddingException {
byte[] C = new byte[4]; // 32 bit counter
byte[] digest = new byte[mgfMd.getDigestLength()];
while (maskLen > 0) {
mgfMd.update(seed, seedOfs, seedLen);
mgfMd.update(C);
try {
mgfMd.digest(digest, 0, digest.length);
} catch (DigestException e) {
// should never happen
throw new BadPaddingException(e.toString());
}
for (int i = 0; (i < digest.length) && (maskLen > 0); maskLen--) {
out[outOfs++] ^= digest[i++];
}
if (maskLen > 0) {
// increment counter
for (int i = C.length - 1; (++C[i] == 0) && (i > 0); i--) {
// empty
}
}
}
}
} }
/* /*
* Copyright (c) 2003, 2017, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,16 +29,20 @@ import java.io.IOException; ...@@ -29,16 +29,20 @@ import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.*; import java.security.*;
import java.security.spec.*;
import java.security.interfaces.*; import java.security.interfaces.*;
import sun.security.util.*; import sun.security.util.*;
import sun.security.x509.AlgorithmId; import sun.security.x509.AlgorithmId;
import sun.security.pkcs.PKCS8Key; import sun.security.pkcs.PKCS8Key;
import static sun.security.rsa.RSAUtil.KeyType;
/** /**
* Key implementation for RSA private keys, CRT form. For non-CRT private * RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in CRT form.
* keys, see RSAPrivateKeyImpl. We need separate classes to ensure * For non-CRT private keys, see RSAPrivateKeyImpl. We need separate classes
* correct behavior in instanceof checks, etc. * to ensure correct behavior in instanceof checks, etc.
* *
* Note: RSA keys must be at least 512 bits long * Note: RSA keys must be at least 512 bits long
* *
...@@ -62,9 +66,10 @@ public final class RSAPrivateCrtKeyImpl ...@@ -62,9 +66,10 @@ public final class RSAPrivateCrtKeyImpl
private BigInteger qe; // prime exponent q private BigInteger qe; // prime exponent q
private BigInteger coeff; // CRT coeffcient private BigInteger coeff; // CRT coeffcient
// algorithmId used to identify RSA keys // Optional parameters associated with this RSA key
final static AlgorithmId rsaId = // specified in the encoding of its AlgorithmId.
new AlgorithmId(AlgorithmId.RSAEncryption_oid); // Must be null for "RSA" keys.
private AlgorithmParameterSpec keyParams;
/** /**
* Generate a new key from its encoding. Returns a CRT key if possible * Generate a new key from its encoding. Returns a CRT key if possible
...@@ -73,9 +78,16 @@ public final class RSAPrivateCrtKeyImpl ...@@ -73,9 +78,16 @@ public final class RSAPrivateCrtKeyImpl
public static RSAPrivateKey newKey(byte[] encoded) public static RSAPrivateKey newKey(byte[] encoded)
throws InvalidKeyException { throws InvalidKeyException {
RSAPrivateCrtKeyImpl key = new RSAPrivateCrtKeyImpl(encoded); RSAPrivateCrtKeyImpl key = new RSAPrivateCrtKeyImpl(encoded);
if (key.getPublicExponent().signum() == 0) { // check all CRT-specific components are available, if any one
// public exponent is missing, return a non-CRT key // missing, return a non-CRT key instead
if ((key.getPublicExponent().signum() == 0) ||
(key.getPrimeExponentP().signum() == 0) ||
(key.getPrimeExponentQ().signum() == 0) ||
(key.getPrimeP().signum() == 0) ||
(key.getPrimeQ().signum() == 0) ||
(key.getCrtCoefficient().signum() == 0)) {
return new RSAPrivateKeyImpl( return new RSAPrivateKeyImpl(
key.algid,
key.getModulus(), key.getModulus(),
key.getPrivateExponent() key.getPrivateExponent()
); );
...@@ -84,21 +96,57 @@ public final class RSAPrivateCrtKeyImpl ...@@ -84,21 +96,57 @@ public final class RSAPrivateCrtKeyImpl
} }
} }
/**
* Generate a new key from the specified type and components.
* Returns a CRT key if possible and a non-CRT key otherwise.
* Used by SunPKCS11 provider.
*/
public static RSAPrivateKey newKey(KeyType type,
AlgorithmParameterSpec params,
BigInteger n, BigInteger e, BigInteger d,
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
BigInteger coeff) throws InvalidKeyException {
RSAPrivateKey key;
AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params);
if ((e.signum() == 0) || (p.signum() == 0) ||
(q.signum() == 0) || (pe.signum() == 0) ||
(qe.signum() == 0) || (coeff.signum() == 0)) {
// if any component is missing, return a non-CRT key
return new RSAPrivateKeyImpl(rsaId, n, d);
} else {
return new RSAPrivateCrtKeyImpl(rsaId, n, e, d,
p, q, pe, qe, coeff);
}
}
/** /**
* Construct a key from its encoding. Called from newKey above. * Construct a key from its encoding. Called from newKey above.
*/ */
RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException { RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException {
if (encoded == null || encoded.length == 0) {
throw new InvalidKeyException("Missing key encoding");
}
decode(encoded); decode(encoded);
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e); RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
try {
// this will check the validity of params
this.keyParams = RSAUtil.getParamSpec(algid);
} catch (ProviderException e) {
throw new InvalidKeyException(e);
}
} }
/** /**
* Construct a key from its components. Used by the * Construct a RSA key from its components. Used by the
* RSAKeyFactory and the RSAKeyPairGenerator. * RSAKeyFactory and the RSAKeyPairGenerator.
*/ */
RSAPrivateCrtKeyImpl(BigInteger n, BigInteger e, BigInteger d, RSAPrivateCrtKeyImpl(AlgorithmId rsaId,
BigInteger n, BigInteger e, BigInteger d,
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe, BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
BigInteger coeff) throws InvalidKeyException { BigInteger coeff) throws InvalidKeyException {
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
this.n = n; this.n = n;
this.e = e; this.e = e;
this.d = d; this.d = d;
...@@ -107,7 +155,7 @@ public final class RSAPrivateCrtKeyImpl ...@@ -107,7 +155,7 @@ public final class RSAPrivateCrtKeyImpl
this.pe = pe; this.pe = pe;
this.qe = qe; this.qe = qe;
this.coeff = coeff; this.coeff = coeff;
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e); this.keyParams = RSAUtil.getParamSpec(rsaId);
// generate the encoding // generate the encoding
algid = rsaId; algid = rsaId;
...@@ -132,50 +180,73 @@ public final class RSAPrivateCrtKeyImpl ...@@ -132,50 +180,73 @@ public final class RSAPrivateCrtKeyImpl
} }
// see JCA doc // see JCA doc
@Override
public String getAlgorithm() { public String getAlgorithm() {
return "RSA"; return algid.getName();
} }
// see JCA doc // see JCA doc
@Override
public BigInteger getModulus() { public BigInteger getModulus() {
return n; return n;
} }
// see JCA doc // see JCA doc
@Override
public BigInteger getPublicExponent() { public BigInteger getPublicExponent() {
return e; return e;
} }
// see JCA doc // see JCA doc
@Override
public BigInteger getPrivateExponent() { public BigInteger getPrivateExponent() {
return d; return d;
} }
// see JCA doc // see JCA doc
@Override
public BigInteger getPrimeP() { public BigInteger getPrimeP() {
return p; return p;
} }
// see JCA doc // see JCA doc
@Override
public BigInteger getPrimeQ() { public BigInteger getPrimeQ() {
return q; return q;
} }
// see JCA doc // see JCA doc
@Override
public BigInteger getPrimeExponentP() { public BigInteger getPrimeExponentP() {
return pe; return pe;
} }
// see JCA doc // see JCA doc
@Override
public BigInteger getPrimeExponentQ() { public BigInteger getPrimeExponentQ() {
return qe; return qe;
} }
// see JCA doc // see JCA doc
@Override
public BigInteger getCrtCoefficient() { public BigInteger getCrtCoefficient() {
return coeff; return coeff;
} }
// see JCA doc
@Override
public AlgorithmParameterSpec getParams() {
return keyParams;
}
// return a string representation of this key for debugging
@Override
public String toString() {
return "SunRsaSign " + getAlgorithm() + " private CRT key, " + n.bitLength()
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
+ "\n private exponent: " + d;
}
/** /**
* Parse the key. Called by PKCS8Key. * Parse the key. Called by PKCS8Key.
*/ */
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,15 +29,18 @@ import java.io.IOException; ...@@ -29,15 +29,18 @@ import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.*; import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import java.security.interfaces.*; import java.security.interfaces.*;
import sun.security.util.*; import sun.security.util.*;
import sun.security.x509.AlgorithmId;
import sun.security.pkcs.PKCS8Key; import sun.security.pkcs.PKCS8Key;
/** /**
* Key implementation for RSA private keys, non-CRT form (modulus, private * RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in non-CRT
* exponent only). For CRT private keys, see RSAPrivateCrtKeyImpl. We need * form (modulus, private exponent only). For CRT private keys, see
* separate classes to ensure correct behavior in instanceof checks, etc. * RSAPrivateCrtKeyImpl. We need separate classes to ensure correct behavior
* in instanceof checks, etc.
* *
* Note: RSA keys must be at least 512 bits long * Note: RSA keys must be at least 512 bits long
* *
...@@ -54,16 +57,25 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey { ...@@ -54,16 +57,25 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
private final BigInteger n; // modulus private final BigInteger n; // modulus
private final BigInteger d; // private exponent private final BigInteger d; // private exponent
// optional parameters associated with this RSA key
// specified in the encoding of its AlgorithmId.
// must be null for "RSA" keys.
private final AlgorithmParameterSpec keyParams;
/** /**
* Construct a key from its components. Used by the * Construct a key from its components. Used by the
* RSAKeyFactory and the RSAKeyPairGenerator. * RSAKeyFactory and the RSAKeyPairGenerator.
*/ */
RSAPrivateKeyImpl(BigInteger n, BigInteger d) throws InvalidKeyException { RSAPrivateKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger d)
throws InvalidKeyException {
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null);
this.n = n; this.n = n;
this.d = d; this.d = d;
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null); this.keyParams = RSAUtil.getParamSpec(rsaId);
// generate the encoding // generate the encoding
algid = RSAPrivateCrtKeyImpl.rsaId; algid = rsaId;
try { try {
DerOutputStream out = new DerOutputStream(); DerOutputStream out = new DerOutputStream();
out.putInteger(0); // version must be 0 out.putInteger(0); // version must be 0
...@@ -85,17 +97,34 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey { ...@@ -85,17 +97,34 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
} }
// see JCA doc // see JCA doc
@Override
public String getAlgorithm() { public String getAlgorithm() {
return "RSA"; return algid.getName();
} }
// see JCA doc // see JCA doc
@Override
public BigInteger getModulus() { public BigInteger getModulus() {
return n; return n;
} }
// see JCA doc // see JCA doc
@Override
public BigInteger getPrivateExponent() { public BigInteger getPrivateExponent() {
return d; return d;
} }
// see JCA doc
@Override
public AlgorithmParameterSpec getParams() {
return keyParams;
}
// return a string representation of this key for debugging
@Override
public String toString() {
return "Sun " + getAlgorithm() + " private key, " + n.bitLength()
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
+ "\n private exponent: " + d;
}
} }
/* /*
* Copyright (c) 2003, 2017, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,17 +29,22 @@ import java.io.IOException; ...@@ -29,17 +29,22 @@ import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.*; import java.security.*;
import java.security.spec.*;
import java.security.interfaces.*; import java.security.interfaces.*;
import sun.security.util.*; import sun.security.util.*;
import sun.security.x509.X509Key; import sun.security.x509.X509Key;
import sun.security.x509.AlgorithmId;
import static sun.security.rsa.RSAUtil.KeyType;
/** /**
* Key implementation for RSA public keys. * RSA public key implementation for "RSA", "RSASSA-PSS" algorithms.
* *
* Note: RSA keys must be at least 512 bits long * Note: RSA keys must be at least 512 bits long
* *
* @see RSAPrivateCrtKeyImpl * @see RSAPrivateCrtKeyImpl
* @see RSAPrivateKeyImpl
* @see RSAKeyFactory * @see RSAKeyFactory
* *
* @since 1.5 * @since 1.5
...@@ -53,18 +58,46 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey { ...@@ -53,18 +58,46 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
private BigInteger n; // modulus private BigInteger n; // modulus
private BigInteger e; // public exponent private BigInteger e; // public exponent
// optional parameters associated with this RSA key
// specified in the encoding of its AlgorithmId
// must be null for "RSA" keys.
private AlgorithmParameterSpec keyParams;
/**
* Generate a new RSAPublicKey from the specified encoding.
* Used by SunPKCS11 provider.
*/
public static RSAPublicKey newKey(byte[] encoded)
throws InvalidKeyException {
return new RSAPublicKeyImpl(encoded);
}
/**
* Generate a new RSAPublicKey from the specified type and components.
* Used by SunPKCS11 provider.
*/
public static RSAPublicKey newKey(KeyType type,
AlgorithmParameterSpec params, BigInteger n, BigInteger e)
throws InvalidKeyException {
AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params);
return new RSAPublicKeyImpl(rsaId, n, e);
}
/** /**
* Construct a key from its components. Used by the * Construct a RSA key from AlgorithmId and its components. Used by
* RSAKeyFactory and the RSAKeyPairGenerator. * RSAKeyFactory and RSAKeyPairGenerator.
*/ */
public RSAPublicKeyImpl(BigInteger n, BigInteger e) RSAPublicKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger e)
throws InvalidKeyException { throws InvalidKeyException {
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
checkExponentRange(n, e);
this.n = n; this.n = n;
this.e = e; this.e = e;
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e); this.keyParams = RSAUtil.getParamSpec(rsaId);
checkExponentRange();
// generate the encoding // generate the encoding
algid = RSAPrivateCrtKeyImpl.rsaId; algid = rsaId;
try { try {
DerOutputStream out = new DerOutputStream(); DerOutputStream out = new DerOutputStream();
out.putInteger(n); out.putInteger(n);
...@@ -82,39 +115,60 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey { ...@@ -82,39 +115,60 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
/** /**
* Construct a key from its encoding. Used by RSAKeyFactory. * Construct a key from its encoding. Used by RSAKeyFactory.
*/ */
public RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException { RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException {
decode(encoded); if (encoded == null || encoded.length == 0) {
throw new InvalidKeyException("Missing key encoding");
}
decode(encoded); // this sets n and e value
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e); RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
checkExponentRange(); checkExponentRange(n, e);
try {
// this will check the validity of params
this.keyParams = RSAUtil.getParamSpec(algid);
} catch (ProviderException e) {
throw new InvalidKeyException(e);
}
} }
private void checkExponentRange() throws InvalidKeyException { // pkg private utility method for checking RSA modulus and public exponent
static void checkExponentRange(BigInteger mod, BigInteger exp)
throws InvalidKeyException {
// the exponent should be smaller than the modulus // the exponent should be smaller than the modulus
if (e.compareTo(n) >= 0) { if (exp.compareTo(mod) >= 0) {
throw new InvalidKeyException("exponent is larger than modulus"); throw new InvalidKeyException("exponent is larger than modulus");
} }
// the exponent should be at least 3 // the exponent should be at least 3
if (e.compareTo(THREE) < 0) { if (exp.compareTo(THREE) < 0) {
throw new InvalidKeyException("exponent is smaller than 3"); throw new InvalidKeyException("exponent is smaller than 3");
} }
} }
// see JCA doc // see JCA doc
@Override
public String getAlgorithm() { public String getAlgorithm() {
return "RSA"; return algid.getName();
} }
// see JCA doc // see JCA doc
@Override
public BigInteger getModulus() { public BigInteger getModulus() {
return n; return n;
} }
// see JCA doc // see JCA doc
@Override
public BigInteger getPublicExponent() { public BigInteger getPublicExponent() {
return e; return e;
} }
// see JCA doc
@Override
public AlgorithmParameterSpec getParams() {
return keyParams;
}
/** /**
* Parse the key. Called by X509Key. * Parse the key. Called by X509Key.
*/ */
...@@ -137,9 +191,11 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey { ...@@ -137,9 +191,11 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
} }
// return a string representation of this key for debugging // return a string representation of this key for debugging
@Override
public String toString() { public String toString() {
return "Sun RSA public key, " + n.bitLength() + " bits\n modulus: " return "Sun " + getAlgorithm() + " public key, " + n.bitLength()
+ n + "\n public exponent: " + e; + " bits" + "\n params: " + keyParams + "\n modulus: " + n
+ "\n public exponent: " + e;
} }
protected Object writeReplace() throws java.io.ObjectStreamException { protected Object writeReplace() throws java.io.ObjectStreamException {
......
/* /*
* Copyright (c) 2003, 2015, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -30,16 +30,18 @@ import java.nio.ByteBuffer; ...@@ -30,16 +30,18 @@ import java.nio.ByteBuffer;
import java.security.*; import java.security.*;
import java.security.interfaces.*; import java.security.interfaces.*;
import java.security.spec.AlgorithmParameterSpec;
import sun.security.rsa.RSAUtil.KeyType;
import sun.security.util.*; import sun.security.util.*;
import sun.security.x509.AlgorithmId; import sun.security.x509.AlgorithmId;
/** /**
* PKCS#1 RSA signatures with the various message digest algorithms. * PKCS#1 v1.5 RSA signatures with the various message digest algorithms.
* This file contains an abstract base class with all the logic plus * This file contains an abstract base class with all the logic plus
* a nested static class for each of the message digest algorithms * a nested static class for each of the message digest algorithms
* (see end of the file). We support MD2, MD5, SHA-1, SHA-224, SHA-256, * (see end of the file). We support MD2, MD5, SHA-1, SHA-224, SHA-256,
* SHA-384, and SHA-512. * SHA-384, SHA-512, SHA-512/224, and SHA-512/256.
* *
* @since 1.5 * @since 1.5
* @author Andreas Sterbenz * @author Andreas Sterbenz
...@@ -85,6 +87,7 @@ public abstract class RSASignature extends SignatureSpi { ...@@ -85,6 +87,7 @@ public abstract class RSASignature extends SignatureSpi {
} }
// initialize for verification. See JCA doc // initialize for verification. See JCA doc
@Override
protected void engineInitVerify(PublicKey publicKey) protected void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException { throws InvalidKeyException {
RSAPublicKey rsaKey = (RSAPublicKey)RSAKeyFactory.toRSAKey(publicKey); RSAPublicKey rsaKey = (RSAPublicKey)RSAKeyFactory.toRSAKey(publicKey);
...@@ -94,12 +97,14 @@ public abstract class RSASignature extends SignatureSpi { ...@@ -94,12 +97,14 @@ public abstract class RSASignature extends SignatureSpi {
} }
// initialize for signing. See JCA doc // initialize for signing. See JCA doc
@Override
protected void engineInitSign(PrivateKey privateKey) protected void engineInitSign(PrivateKey privateKey)
throws InvalidKeyException { throws InvalidKeyException {
engineInitSign(privateKey, null); engineInitSign(privateKey, null);
} }
// initialize for signing. See JCA doc // initialize for signing. See JCA doc
@Override
protected void engineInitSign(PrivateKey privateKey, SecureRandom random) protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException { throws InvalidKeyException {
RSAPrivateKey rsaKey = RSAPrivateKey rsaKey =
...@@ -114,6 +119,11 @@ public abstract class RSASignature extends SignatureSpi { ...@@ -114,6 +119,11 @@ public abstract class RSASignature extends SignatureSpi {
*/ */
private void initCommon(RSAKey rsaKey, SecureRandom random) private void initCommon(RSAKey rsaKey, SecureRandom random)
throws InvalidKeyException { throws InvalidKeyException {
try {
RSAUtil.checkParamsAgainstType(KeyType.RSA, rsaKey.getParams());
} catch (ProviderException e) {
throw new InvalidKeyException("Invalid key for RSA signatures", e);
}
resetDigest(); resetDigest();
int keySize = RSACore.getByteLength(rsaKey); int keySize = RSACore.getByteLength(rsaKey);
try { try {
...@@ -148,12 +158,14 @@ public abstract class RSASignature extends SignatureSpi { ...@@ -148,12 +158,14 @@ public abstract class RSASignature extends SignatureSpi {
} }
// update the signature with the plaintext data. See JCA doc // update the signature with the plaintext data. See JCA doc
@Override
protected void engineUpdate(byte b) throws SignatureException { protected void engineUpdate(byte b) throws SignatureException {
md.update(b); md.update(b);
digestReset = false; digestReset = false;
} }
// update the signature with the plaintext data. See JCA doc // update the signature with the plaintext data. See JCA doc
@Override
protected void engineUpdate(byte[] b, int off, int len) protected void engineUpdate(byte[] b, int off, int len)
throws SignatureException { throws SignatureException {
md.update(b, off, len); md.update(b, off, len);
...@@ -161,13 +173,18 @@ public abstract class RSASignature extends SignatureSpi { ...@@ -161,13 +173,18 @@ public abstract class RSASignature extends SignatureSpi {
} }
// update the signature with the plaintext data. See JCA doc // update the signature with the plaintext data. See JCA doc
@Override
protected void engineUpdate(ByteBuffer b) { protected void engineUpdate(ByteBuffer b) {
md.update(b); md.update(b);
digestReset = false; digestReset = false;
} }
// sign the data and return the signature. See JCA doc // sign the data and return the signature. See JCA doc
@Override
protected byte[] engineSign() throws SignatureException { protected byte[] engineSign() throws SignatureException {
if (privateKey == null) {
throw new SignatureException("Missing private key");
}
byte[] digest = getDigestValue(); byte[] digest = getDigestValue();
try { try {
byte[] encoded = encodeSignature(digestOID, digest); byte[] encoded = encodeSignature(digestOID, digest);
...@@ -182,7 +199,12 @@ public abstract class RSASignature extends SignatureSpi { ...@@ -182,7 +199,12 @@ public abstract class RSASignature extends SignatureSpi {
} }
// verify the data and return the result. See JCA doc // verify the data and return the result. See JCA doc
@Override
protected boolean engineVerify(byte[] sigBytes) throws SignatureException { protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
if (publicKey == null) {
throw new SignatureException("Missing public key");
}
if (sigBytes.length != RSACore.getByteLength(publicKey)) { if (sigBytes.length != RSACore.getByteLength(publicKey)) {
throw new SignatureException("Signature length not correct: got " + throw new SignatureException("Signature length not correct: got " +
sigBytes.length + " but was expecting " + sigBytes.length + " but was expecting " +
...@@ -245,18 +267,35 @@ public abstract class RSASignature extends SignatureSpi { ...@@ -245,18 +267,35 @@ public abstract class RSASignature extends SignatureSpi {
// set parameter, not supported. See JCA doc // set parameter, not supported. See JCA doc
@Deprecated @Deprecated
@Override
protected void engineSetParameter(String param, Object value) protected void engineSetParameter(String param, Object value)
throws InvalidParameterException { throws InvalidParameterException {
throw new UnsupportedOperationException("setParameter() not supported"); throw new UnsupportedOperationException("setParameter() not supported");
} }
// See JCA doc
@Override
protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
if (params != null) {
throw new InvalidAlgorithmParameterException("No parameters accepted");
}
}
// get parameter, not supported. See JCA doc // get parameter, not supported. See JCA doc
@Deprecated @Deprecated
@Override
protected Object engineGetParameter(String param) protected Object engineGetParameter(String param)
throws InvalidParameterException { throws InvalidParameterException {
throw new UnsupportedOperationException("getParameter() not supported"); throw new UnsupportedOperationException("getParameter() not supported");
} }
// See JCA doc
@Override
protected AlgorithmParameters engineGetParameters() {
return null;
}
// Nested class for MD2withRSA signatures // Nested class for MD2withRSA signatures
public static final class MD2withRSA extends RSASignature { public static final class MD2withRSA extends RSASignature {
public MD2withRSA() { public MD2withRSA() {
...@@ -306,4 +345,17 @@ public abstract class RSASignature extends SignatureSpi { ...@@ -306,4 +345,17 @@ public abstract class RSASignature extends SignatureSpi {
} }
} }
// Nested class for SHA512/224withRSA signatures
public static final class SHA512_224withRSA extends RSASignature {
public SHA512_224withRSA() {
super("SHA-512/224", AlgorithmId.SHA512_224_oid, 11);
}
}
// Nested class for SHA512/256withRSA signatures
public static final class SHA512_256withRSA extends RSASignature {
public SHA512_256withRSA() {
super("SHA-512/256", AlgorithmId.SHA512_256_oid, 11);
}
}
} }
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.rsa;
import java.io.IOException;
import java.security.*;
import java.security.spec.*;
import sun.security.util.ObjectIdentifier;
import sun.security.x509.AlgorithmId;
/**
* Utility class for SunRsaSign provider.
* Currently used by RSAKeyPairGenerator and RSAKeyFactory.
*
* @since 8
*/
public class RSAUtil {
public enum KeyType {
RSA ("RSA"),
PSS ("RSASSA-PSS")
;
private final String algo;
KeyType(String keyAlgo) {
this.algo = keyAlgo;
}
public String keyAlgo() {
return algo;
}
public static KeyType lookup(String name)
throws InvalidKeyException, ProviderException {
if (name == null) {
throw new InvalidKeyException("Null key algorithm");
}
for (KeyType kt : KeyType.values()) {
if (kt.keyAlgo().equalsIgnoreCase(name)) {
return kt;
}
}
// no match
throw new ProviderException("Unsupported algorithm " + name);
}
}
public static void checkParamsAgainstType(KeyType type,
AlgorithmParameterSpec paramSpec) throws ProviderException {
switch (type) {
case RSA:
if (paramSpec != null) {
throw new ProviderException("null params expected for " +
type.keyAlgo());
}
break;
case PSS:
if ((paramSpec != null) &&
!(paramSpec instanceof PSSParameterSpec)) {
throw new ProviderException
("PSSParmeterSpec expected for " + type.keyAlgo());
}
break;
default:
throw new ProviderException
("Unsupported RSA algorithm " + type);
}
}
public static AlgorithmId createAlgorithmId(KeyType type,
AlgorithmParameterSpec paramSpec) throws ProviderException {
checkParamsAgainstType(type, paramSpec);
ObjectIdentifier oid = null;
AlgorithmParameters params = null;
try {
switch (type) {
case RSA:
oid = AlgorithmId.RSAEncryption_oid;
break;
case PSS:
if (paramSpec != null) {
params = AlgorithmParameters.getInstance(type.keyAlgo());
params.init(paramSpec);
}
oid = AlgorithmId.RSASSA_PSS_oid;
break;
default:
throw new ProviderException
("Unsupported RSA algorithm " + type);
}
AlgorithmId result;
if (params == null) {
result = new AlgorithmId(oid);
} else {
result = new AlgorithmId(oid, params);
}
return result;
} catch (NoSuchAlgorithmException | InvalidParameterSpecException e) {
// should not happen
throw new ProviderException(e);
}
}
public static AlgorithmParameterSpec getParamSpec(AlgorithmId algid)
throws ProviderException {
if (algid == null) {
throw new ProviderException("AlgorithmId should not be null");
}
return getParamSpec(algid.getParameters());
}
public static AlgorithmParameterSpec getParamSpec(AlgorithmParameters params)
throws ProviderException {
if (params == null) return null;
try {
String algName = params.getAlgorithm();
KeyType type = KeyType.lookup(algName);
Class<? extends AlgorithmParameterSpec> specCls;
switch (type) {
case RSA:
throw new ProviderException("No params accepted for " +
type.keyAlgo());
case PSS:
specCls = PSSParameterSpec.class;
break;
default:
throw new ProviderException("Unsupported RSA algorithm: " + algName);
}
return params.getParameterSpec(specCls);
} catch (ProviderException pe) {
// pass it up
throw pe;
} catch (Exception e) {
throw new ProviderException(e);
}
}
}
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -41,11 +41,10 @@ public final class SunRsaSignEntries { ...@@ -41,11 +41,10 @@ public final class SunRsaSignEntries {
public static void putEntries(Map<Object, Object> map) { public static void putEntries(Map<Object, Object> map) {
// main algorithms // main algorithms
map.put("KeyFactory.RSA", map.put("KeyFactory.RSA",
"sun.security.rsa.RSAKeyFactory"); "sun.security.rsa.RSAKeyFactory$Legacy");
map.put("KeyPairGenerator.RSA", map.put("KeyPairGenerator.RSA",
"sun.security.rsa.RSAKeyPairGenerator"); "sun.security.rsa.RSAKeyPairGenerator$Legacy");
map.put("Signature.MD2withRSA", map.put("Signature.MD2withRSA",
"sun.security.rsa.RSASignature$MD2withRSA"); "sun.security.rsa.RSASignature$MD2withRSA");
map.put("Signature.MD5withRSA", map.put("Signature.MD5withRSA",
...@@ -60,9 +59,21 @@ public final class SunRsaSignEntries { ...@@ -60,9 +59,21 @@ public final class SunRsaSignEntries {
"sun.security.rsa.RSASignature$SHA384withRSA"); "sun.security.rsa.RSASignature$SHA384withRSA");
map.put("Signature.SHA512withRSA", map.put("Signature.SHA512withRSA",
"sun.security.rsa.RSASignature$SHA512withRSA"); "sun.security.rsa.RSASignature$SHA512withRSA");
map.put("Signature.SHA512/224withRSA",
"sun.security.rsa.RSASignature$SHA512_224withRSA");
map.put("Signature.SHA512/256withRSA",
"sun.security.rsa.RSASignature$SHA512_256withRSA");
map.put("KeyFactory.RSASSA-PSS",
"sun.security.rsa.RSAKeyFactory$PSS");
map.put("KeyPairGenerator.RSASSA-PSS",
"sun.security.rsa.RSAKeyPairGenerator$PSS");
map.put("Signature.RSASSA-PSS",
"sun.security.rsa.RSAPSSSignature");
map.put("AlgorithmParameters.RSASSA-PSS",
"sun.security.rsa.PSSParameters");
// attributes for supported key classes // attributes for supported key classes
String rsaKeyClasses = "java.security.interfaces.RSAPublicKey" + String rsaKeyClasses = "java.security.interfaces.RSAPublicKey" +
"|java.security.interfaces.RSAPrivateKey"; "|java.security.interfaces.RSAPrivateKey";
map.put("Signature.MD2withRSA SupportedKeyClasses", rsaKeyClasses); map.put("Signature.MD2withRSA SupportedKeyClasses", rsaKeyClasses);
...@@ -72,9 +83,11 @@ public final class SunRsaSignEntries { ...@@ -72,9 +83,11 @@ public final class SunRsaSignEntries {
map.put("Signature.SHA256withRSA SupportedKeyClasses", rsaKeyClasses); map.put("Signature.SHA256withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA384withRSA SupportedKeyClasses", rsaKeyClasses); map.put("Signature.SHA384withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA512withRSA SupportedKeyClasses", rsaKeyClasses); map.put("Signature.SHA512withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA512/224withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA512/256withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.RSASSA-PSS SupportedKeyClasses", rsaKeyClasses);
// aliases // aliases
map.put("Alg.Alias.KeyFactory.1.2.840.113549.1.1", "RSA"); map.put("Alg.Alias.KeyFactory.1.2.840.113549.1.1", "RSA");
map.put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1", "RSA"); map.put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1", "RSA");
...@@ -102,6 +115,21 @@ public final class SunRsaSignEntries { ...@@ -102,6 +115,21 @@ public final class SunRsaSignEntries {
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512withRSA"); map.put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.13", "SHA512withRSA"); map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.13", "SHA512withRSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.15", "SHA512/224withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.15", "SHA512/224withRSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.16", "SHA512/256withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.16", "SHA512/256withRSA");
map.put("Alg.Alias.KeyFactory.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.AlgorithmParameters.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
} }
} }
/* /*
* Copyright (c) 1996, 2013, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
package sun.security.ssl; package sun.security.ssl;
import java.security.*; import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
/** /**
* Signature implementation for the SSL/TLS RSA Signature variant with both * Signature implementation for the SSL/TLS RSA Signature variant with both
...@@ -198,10 +199,22 @@ public final class RSASignature extends SignatureSpi { ...@@ -198,10 +199,22 @@ public final class RSASignature extends SignatureSpi {
sha = digests[1]; sha = digests[1];
} }
@Override
protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
if (params != null) {
throw new InvalidAlgorithmParameterException("No parameters accepted");
}
}
@Override @Override
protected Object engineGetParameter(String param) protected Object engineGetParameter(String param)
throws InvalidParameterException { throws InvalidParameterException {
throw new InvalidParameterException("Parameters not supported"); throw new InvalidParameterException("Parameters not supported");
} }
@Override
protected AlgorithmParameters engineGetParameters() {
return null;
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -160,12 +160,12 @@ public abstract class SunJSSE extends java.security.Provider { ...@@ -160,12 +160,12 @@ public abstract class SunJSSE extends java.security.Provider {
private void doRegister(boolean isfips) { private void doRegister(boolean isfips) {
if (isfips == false) { if (isfips == false) {
put("KeyFactory.RSA", put("KeyFactory.RSA",
"sun.security.rsa.RSAKeyFactory"); "sun.security.rsa.RSAKeyFactory$Legacy");
put("Alg.Alias.KeyFactory.1.2.840.113549.1.1", "RSA"); put("Alg.Alias.KeyFactory.1.2.840.113549.1.1", "RSA");
put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1", "RSA"); put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1", "RSA");
put("KeyPairGenerator.RSA", put("KeyPairGenerator.RSA",
"sun.security.rsa.RSAKeyPairGenerator"); "sun.security.rsa.RSAKeyPairGenerator$Legacy");
put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1", "RSA"); put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1", "RSA");
put("Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1", "RSA"); put("Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1", "RSA");
......
/* /*
* Copyright (c) 1996, 2012, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -30,12 +30,12 @@ import java.security.cert.X509Certificate; ...@@ -30,12 +30,12 @@ import java.security.cert.X509Certificate;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateEncodingException;
import java.security.*; import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Date; import java.util.Date;
import sun.security.pkcs10.PKCS10; import sun.security.pkcs10.PKCS10;
import sun.security.x509.*; import sun.security.x509.*;
/** /**
* Generate a pair of keys, and provide access to them. This class is * Generate a pair of keys, and provide access to them. This class is
* provided primarily for ease of use. * provided primarily for ease of use.
...@@ -250,12 +250,14 @@ public final class CertAndKeyGen { ...@@ -250,12 +250,14 @@ public final class CertAndKeyGen {
new CertificateValidity(firstDate,lastDate); new CertificateValidity(firstDate,lastDate);
X509CertInfo info = new X509CertInfo(); X509CertInfo info = new X509CertInfo();
AlgorithmParameterSpec params = AlgorithmId
.getDefaultAlgorithmParameterSpec(sigAlg, privateKey);
// Add all mandatory attributes // Add all mandatory attributes
info.set(X509CertInfo.VERSION, info.set(X509CertInfo.VERSION,
new CertificateVersion(CertificateVersion.V3)); new CertificateVersion(CertificateVersion.V3));
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber( info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(
new java.util.Random().nextInt() & 0x7fffffff)); new java.util.Random().nextInt() & 0x7fffffff));
AlgorithmId algID = AlgorithmId.get(sigAlg); AlgorithmId algID = AlgorithmId.getWithParameterSpec(sigAlg, params);
info.set(X509CertInfo.ALGORITHM_ID, info.set(X509CertInfo.ALGORITHM_ID,
new CertificateAlgorithmId(algID)); new CertificateAlgorithmId(algID));
info.set(X509CertInfo.SUBJECT, myname); info.set(X509CertInfo.SUBJECT, myname);
...@@ -265,13 +267,19 @@ public final class CertAndKeyGen { ...@@ -265,13 +267,19 @@ public final class CertAndKeyGen {
if (ext != null) info.set(X509CertInfo.EXTENSIONS, ext); if (ext != null) info.set(X509CertInfo.EXTENSIONS, ext);
cert = new X509CertImpl(info); cert = new X509CertImpl(info);
cert.sign(privateKey, this.sigAlg); cert.sign(privateKey,
params,
sigAlg,
null);
return (X509Certificate)cert; return (X509Certificate)cert;
} catch (IOException e) { } catch (IOException e) {
throw new CertificateEncodingException("getSelfCert: " + throw new CertificateEncodingException("getSelfCert: " +
e.getMessage()); e.getMessage());
} catch (InvalidAlgorithmParameterException e2) {
throw new SignatureException(
"Unsupported PSSParameterSpec: " + e2.getMessage());
} }
} }
...@@ -297,6 +305,7 @@ public final class CertAndKeyGen { ...@@ -297,6 +305,7 @@ public final class CertAndKeyGen {
* @exception InvalidKeyException on key handling errors. * @exception InvalidKeyException on key handling errors.
* @exception SignatureException on signature handling errors. * @exception SignatureException on signature handling errors.
*/ */
// This method is not used inside JDK. Will not update it.
public PKCS10 getCertRequest (X500Name myname) public PKCS10 getCertRequest (X500Name myname)
throws InvalidKeyException, SignatureException throws InvalidKeyException, SignatureException
{ {
......
/* /*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -56,6 +56,7 @@ public final class SecurityProviderConstants { ...@@ -56,6 +56,7 @@ public final class SecurityProviderConstants {
public static final int DEF_DSA_KEY_SIZE; public static final int DEF_DSA_KEY_SIZE;
public static final int DEF_RSA_KEY_SIZE; public static final int DEF_RSA_KEY_SIZE;
public static final int DEF_RSASSA_PSS_KEY_SIZE;
public static final int DEF_DH_KEY_SIZE; public static final int DEF_DH_KEY_SIZE;
public static final int DEF_EC_KEY_SIZE; public static final int DEF_EC_KEY_SIZE;
...@@ -66,6 +67,7 @@ public final class SecurityProviderConstants { ...@@ -66,6 +67,7 @@ public final class SecurityProviderConstants {
(KEY_LENGTH_PROP); (KEY_LENGTH_PROP);
int dsaKeySize = 2048; int dsaKeySize = 2048;
int rsaKeySize = 2048; int rsaKeySize = 2048;
int rsaSsaPssKeySize = rsaKeySize; // default to same value as RSA
int dhKeySize = 2048; int dhKeySize = 2048;
int ecKeySize = 256; int ecKeySize = 256;
...@@ -98,6 +100,8 @@ public final class SecurityProviderConstants { ...@@ -98,6 +100,8 @@ public final class SecurityProviderConstants {
dsaKeySize = value; dsaKeySize = value;
} else if (algoName.equals("RSA")) { } else if (algoName.equals("RSA")) {
rsaKeySize = value; rsaKeySize = value;
} else if (algoName.equals("RSASSA-PSS")) {
rsaSsaPssKeySize = value;
} else if (algoName.equals("DH")) { } else if (algoName.equals("DH")) {
dhKeySize = value; dhKeySize = value;
} else if (algoName.equals("EC")) { } else if (algoName.equals("EC")) {
...@@ -125,6 +129,7 @@ public final class SecurityProviderConstants { ...@@ -125,6 +129,7 @@ public final class SecurityProviderConstants {
} }
DEF_DSA_KEY_SIZE = dsaKeySize; DEF_DSA_KEY_SIZE = dsaKeySize;
DEF_RSA_KEY_SIZE = rsaKeySize; DEF_RSA_KEY_SIZE = rsaKeySize;
DEF_RSASSA_PSS_KEY_SIZE = rsaSsaPssKeySize;
DEF_DH_KEY_SIZE = dhKeySize; DEF_DH_KEY_SIZE = dhKeySize;
DEF_EC_KEY_SIZE = ecKeySize; DEF_EC_KEY_SIZE = ecKeySize;
} }
......
此差异已折叠。
此差异已折叠。
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -130,6 +130,16 @@ public class TestOAEPPadding { ...@@ -130,6 +130,16 @@ public class TestOAEPPadding {
MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT));
test(new OAEPParameterSpec("SHA-512", "MGF1", test(new OAEPParameterSpec("SHA-512", "MGF1",
MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT));
// SHA-512/224 and SHA-512/256
test(new OAEPParameterSpec("SHA-512/224", "MGF1",
MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT));
test(new OAEPParameterSpec("SHA-512/224", "MGF1",
MGF1ParameterSpec.SHA512_224, PSource.PSpecified.DEFAULT));
test(new OAEPParameterSpec("SHA-512/256", "MGF1",
MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT));
test(new OAEPParameterSpec("SHA-512/256", "MGF1",
MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT));
if (failed) { if (failed) {
throw new Exception("Test failed"); throw new Exception("Test failed");
} }
...@@ -154,9 +164,9 @@ public class TestOAEPPadding { ...@@ -154,9 +164,9 @@ public class TestOAEPPadding {
dlen = 16; dlen = 16;
} else if (algo.equals("SHA1")) { } else if (algo.equals("SHA1")) {
dlen = 20; dlen = 20;
} else if (algo.equals("SHA-224")) { } else if (algo.equals("SHA-224") || algo.equals("SHA-512/224")) {
dlen = 28; dlen = 28;
} else if (algo.equals("SHA-256")) { } else if (algo.equals("SHA-256") || algo.equals("SHA-512/256")) {
dlen = 32; dlen = 32;
} else if (algo.equals("SHA-384")) { } else if (algo.equals("SHA-384")) {
dlen = 48; dlen = 48;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册