Sat, 07 Nov 2020 10:05:20 +0800
Merge
1.1 --- a/.hgtags Sun Oct 25 03:07:23 2020 +0800 1.2 +++ b/.hgtags Sat Nov 07 10:05:20 2020 +0800 1.3 @@ -1084,4 +1084,7 @@ 1.4 d8bd882cfd2ae393e7dbffed7fbd455449c32d88 jdk8u272-b07 1.5 ab2e99db67029a5505934895831561bb39a8ca31 jdk8u272-b08 1.6 77b682e2d679a13ed7fbb8343f5b2ac1ddee1300 jdk8u272-b09 1.7 +badfd40f15ac56deecb250cc14735974c3e41611 jdk8u272-b10 1.8 +badfd40f15ac56deecb250cc14735974c3e41611 jdk8u272-ga 1.9 5a272e10d7e7994152dfd0b88f0ffd8b0c0dac68 mips-jdk8u272-b10 1.10 +badfd40f15ac56deecb250cc14735974c3e41611 jdk8u275-b00
2.1 --- a/src/share/classes/com/sun/jndi/ldap/ext/StartTlsResponseImpl.java Sun Oct 25 03:07:23 2020 +0800 2.2 +++ b/src/share/classes/com/sun/jndi/ldap/ext/StartTlsResponseImpl.java Sat Nov 07 10:05:20 2020 +0800 2.3 @@ -288,7 +288,8 @@ 2.4 */ 2.5 public void setConnection(Connection ldapConnection, String hostname) { 2.6 this.ldapConnection = ldapConnection; 2.7 - this.hostname = (hostname != null) ? hostname : ldapConnection.host; 2.8 + this.hostname = (hostname == null || hostname.isEmpty()) 2.9 + ? ldapConnection.host : hostname; 2.10 originalInputStream = ldapConnection.inStream; 2.11 originalOutputStream = ldapConnection.outStream; 2.12 }
3.1 --- a/src/share/classes/sun/security/pkcs11/P11AEADCipher.java Sun Oct 25 03:07:23 2020 +0800 3.2 +++ b/src/share/classes/sun/security/pkcs11/P11AEADCipher.java Sat Nov 07 10:05:20 2020 +0800 3.3 @@ -1,4 +1,5 @@ 3.4 -/* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3.5 +/* 3.6 + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -331,25 +332,25 @@ 3.11 } 3.12 3.13 private void cancelOperation() { 3.14 + // cancel operation by finishing it; avoid killSession as some 3.15 + // hardware vendors may require re-login 3.16 + int bufLen = doFinalLength(0); 3.17 + byte[] buffer = new byte[bufLen]; 3.18 + byte[] in = dataBuffer.toByteArray(); 3.19 + int inLen = in.length; 3.20 try { 3.21 - if (session.hasObjects() == false) { 3.22 - session = token.killSession(session); 3.23 - return; 3.24 + if (encrypt) { 3.25 + token.p11.C_Encrypt(session.id(), 0, in, 0, inLen, 3.26 + 0, buffer, 0, bufLen); 3.27 } else { 3.28 - // cancel operation by finishing it 3.29 - int bufLen = doFinalLength(0); 3.30 - byte[] buffer = new byte[bufLen]; 3.31 - 3.32 - if (encrypt) { 3.33 - token.p11.C_Encrypt(session.id(), 0, buffer, 0, bufLen, 3.34 - 0, buffer, 0, bufLen); 3.35 - } else { 3.36 - token.p11.C_Decrypt(session.id(), 0, buffer, 0, bufLen, 3.37 - 0, buffer, 0, bufLen); 3.38 - } 3.39 + token.p11.C_Decrypt(session.id(), 0, in, 0, inLen, 3.40 + 0, buffer, 0, bufLen); 3.41 } 3.42 } catch (PKCS11Exception e) { 3.43 - throw new ProviderException("Cancel failed", e); 3.44 + if (encrypt) { 3.45 + throw new ProviderException("Cancel failed", e); 3.46 + } 3.47 + // ignore failure for decryption 3.48 } 3.49 } 3.50 3.51 @@ -432,18 +433,21 @@ 3.52 if (!initialized) { 3.53 return; 3.54 } 3.55 + initialized = false; 3.56 + 3.57 try { 3.58 if (session == null) { 3.59 return; 3.60 } 3.61 + 3.62 if (doCancel && token.explicitCancel) { 3.63 cancelOperation(); 3.64 } 3.65 } finally { 3.66 p11Key.releaseKeyID(); 3.67 session = token.releaseSession(session); 3.68 + dataBuffer.reset(); 3.69 } 3.70 - initialized = false; 3.71 } 3.72 3.73 // see JCE spec
4.1 --- a/src/share/classes/sun/security/pkcs11/P11Cipher.java Sun Oct 25 03:07:23 2020 +0800 4.2 +++ b/src/share/classes/sun/security/pkcs11/P11Cipher.java Sat Nov 07 10:05:20 2020 +0800 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -409,10 +409,12 @@ 4.11 return; 4.12 } 4.13 initialized = false; 4.14 + 4.15 try { 4.16 if (session == null) { 4.17 return; 4.18 } 4.19 + 4.20 if (doCancel && token.explicitCancel) { 4.21 cancelOperation(); 4.22 } 4.23 @@ -426,22 +428,21 @@ 4.24 4.25 private void cancelOperation() { 4.26 token.ensureValid(); 4.27 - if (session.hasObjects() == false) { 4.28 - session = token.killSession(session); 4.29 - return; 4.30 - } else { 4.31 - try { 4.32 - // cancel operation by finishing it 4.33 - int bufLen = doFinalLength(0); 4.34 - byte[] buffer = new byte[bufLen]; 4.35 - if (encrypt) { 4.36 - token.p11.C_EncryptFinal(session.id(), 0, buffer, 0, bufLen); 4.37 - } else { 4.38 - token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen); 4.39 - } 4.40 - } catch (PKCS11Exception e) { 4.41 + // cancel operation by finishing it; avoid killSession as some 4.42 + // hardware vendors may require re-login 4.43 + try { 4.44 + int bufLen = doFinalLength(0); 4.45 + byte[] buffer = new byte[bufLen]; 4.46 + if (encrypt) { 4.47 + token.p11.C_EncryptFinal(session.id(), 0, buffer, 0, bufLen); 4.48 + } else { 4.49 + token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen); 4.50 + } 4.51 + } catch (PKCS11Exception e) { 4.52 + if (encrypt) { 4.53 throw new ProviderException("Cancel failed", e); 4.54 } 4.55 + // ignore failure for decryption 4.56 } 4.57 } 4.58
5.1 --- a/src/share/classes/sun/security/pkcs11/P11Mac.java Sun Oct 25 03:07:23 2020 +0800 5.2 +++ b/src/share/classes/sun/security/pkcs11/P11Mac.java Sat Nov 07 10:05:20 2020 +0800 5.3 @@ -1,5 +1,5 @@ 5.4 /* 5.5 - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. 5.6 + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. 5.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.8 * 5.9 * This code is free software; you can redistribute it and/or modify it 5.10 @@ -122,10 +122,12 @@ 5.11 return; 5.12 } 5.13 initialized = false; 5.14 + 5.15 try { 5.16 if (session == null) { 5.17 return; 5.18 } 5.19 + 5.20 if (doCancel && token.explicitCancel) { 5.21 cancelOperation(); 5.22 } 5.23 @@ -137,15 +139,12 @@ 5.24 5.25 private void cancelOperation() { 5.26 token.ensureValid(); 5.27 - if (session.hasObjects() == false) { 5.28 - session = token.killSession(session); 5.29 - return; 5.30 - } else { 5.31 - try { 5.32 - token.p11.C_SignFinal(session.id(), 0); 5.33 - } catch (PKCS11Exception e) { 5.34 - throw new ProviderException("Cancel failed", e); 5.35 - } 5.36 + // cancel operation by finishing it; avoid killSession as some 5.37 + // hardware vendors may require re-login 5.38 + try { 5.39 + token.p11.C_SignFinal(session.id(), 0); 5.40 + } catch (PKCS11Exception e) { 5.41 + throw new ProviderException("Cancel failed", e); 5.42 } 5.43 } 5.44 5.45 @@ -207,7 +206,6 @@ 5.46 ensureInitialized(); 5.47 return token.p11.C_SignFinal(session.id(), 0); 5.48 } catch (PKCS11Exception e) { 5.49 - reset(true); 5.50 throw new ProviderException("doFinal() failed", e); 5.51 } finally { 5.52 reset(false);
6.1 --- a/src/share/classes/sun/security/pkcs11/P11PSSSignature.java Sun Oct 25 03:07:23 2020 +0800 6.2 +++ b/src/share/classes/sun/security/pkcs11/P11PSSSignature.java Sat Nov 07 10:05:20 2020 +0800 6.3 @@ -1,5 +1,5 @@ 6.4 /* 6.5 - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 6.6 + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. 6.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 * 6.9 * This code is free software; you can redistribute it and/or modify it 6.10 @@ -223,10 +223,12 @@ 6.11 return; 6.12 } 6.13 initialized = false; 6.14 + 6.15 try { 6.16 if (session == null) { 6.17 return; 6.18 } 6.19 + 6.20 if (doCancel && token.explicitCancel) { 6.21 cancelOperation(); 6.22 } 6.23 @@ -242,14 +244,10 @@ 6.24 token.ensureValid(); 6.25 if (DEBUG) System.out.print("Cancelling operation"); 6.26 6.27 - if (session.hasObjects() == false) { 6.28 - if (DEBUG) System.out.println(" by killing session"); 6.29 - session = token.killSession(session); 6.30 - return; 6.31 - } 6.32 - // "cancel" operation by finishing it 6.33 - if (mode == M_SIGN) { 6.34 - try { 6.35 + // cancel operation by finishing it; avoid killSession as some 6.36 + // hardware vendors may require re-login 6.37 + try { 6.38 + if (mode == M_SIGN) { 6.39 if (type == T_UPDATE) { 6.40 if (DEBUG) System.out.println(" by C_SignFinal"); 6.41 token.p11.C_SignFinal(session.id(), 0); 6.42 @@ -259,11 +257,7 @@ 6.43 if (DEBUG) System.out.println(" by C_Sign"); 6.44 token.p11.C_Sign(session.id(), digest); 6.45 } 6.46 - } catch (PKCS11Exception e) { 6.47 - throw new ProviderException("cancel failed", e); 6.48 - } 6.49 - } else { // M_VERIFY 6.50 - try { 6.51 + } else { // M_VERIFY 6.52 byte[] signature = 6.53 new byte[(p11Key.length() + 7) >> 3]; 6.54 if (type == T_UPDATE) { 6.55 @@ -275,10 +269,12 @@ 6.56 if (DEBUG) System.out.println(" by C_Verify"); 6.57 token.p11.C_Verify(session.id(), digest, signature); 6.58 } 6.59 - } catch (PKCS11Exception e) { 6.60 - // will fail since the signature is incorrect 6.61 - // XXX check error code 6.62 } 6.63 + } catch (PKCS11Exception e) { 6.64 + if (mode == M_SIGN) { 6.65 + throw new ProviderException("cancel failed", e); 6.66 + } 6.67 + // ignore failure for verification 6.68 } 6.69 } 6.70
7.1 --- a/src/share/classes/sun/security/pkcs11/P11RSACipher.java Sun Oct 25 03:07:23 2020 +0800 7.2 +++ b/src/share/classes/sun/security/pkcs11/P11RSACipher.java Sat Nov 07 10:05:20 2020 +0800 7.3 @@ -1,5 +1,5 @@ 7.4 /* 7.5 - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. 7.6 + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. 7.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 * 7.9 * This code is free software; you can redistribute it and/or modify it 7.10 @@ -246,10 +246,12 @@ 7.11 return; 7.12 } 7.13 initialized = false; 7.14 + 7.15 try { 7.16 if (session == null) { 7.17 return; 7.18 } 7.19 + 7.20 if (doCancel && token.explicitCancel) { 7.21 cancelOperation(); 7.22 } 7.23 @@ -263,36 +265,33 @@ 7.24 // state variables such as "initialized" 7.25 private void cancelOperation() { 7.26 token.ensureValid(); 7.27 - if (session.hasObjects() == false) { 7.28 - session = token.killSession(session); 7.29 - return; 7.30 - } else { 7.31 - try { 7.32 - PKCS11 p11 = token.p11; 7.33 - int inLen = maxInputSize; 7.34 - int outLen = buffer.length; 7.35 - long sessId = session.id(); 7.36 - switch (mode) { 7.37 - case MODE_ENCRYPT: 7.38 - p11.C_Encrypt(sessId, 0, buffer, 0, inLen, 0, buffer, 0, outLen); 7.39 - break; 7.40 - case MODE_DECRYPT: 7.41 - p11.C_Decrypt(sessId, 0, buffer, 0, inLen, 0, buffer, 0, outLen); 7.42 - break; 7.43 - case MODE_SIGN: 7.44 - byte[] tmpBuffer = new byte[maxInputSize]; 7.45 - p11.C_Sign(sessId, tmpBuffer); 7.46 - break; 7.47 - case MODE_VERIFY: 7.48 - p11.C_VerifyRecover(sessId, buffer, 0, inLen, buffer, 7.49 - 0, outLen); 7.50 - break; 7.51 - default: 7.52 - throw new ProviderException("internal error"); 7.53 - } 7.54 - } catch (PKCS11Exception e) { 7.55 - // XXX ensure this always works, ignore error 7.56 + // cancel operation by finishing it; avoid killSession as some 7.57 + // hardware vendors may require re-login 7.58 + try { 7.59 + PKCS11 p11 = token.p11; 7.60 + int inLen = maxInputSize; 7.61 + int outLen = buffer.length; 7.62 + long sessId = session.id(); 7.63 + switch (mode) { 7.64 + case MODE_ENCRYPT: 7.65 + p11.C_Encrypt(sessId, 0, buffer, 0, inLen, 0, buffer, 0, outLen); 7.66 + break; 7.67 + case MODE_DECRYPT: 7.68 + p11.C_Decrypt(sessId, 0, buffer, 0, inLen, 0, buffer, 0, outLen); 7.69 + break; 7.70 + case MODE_SIGN: 7.71 + byte[] tmpBuffer = new byte[maxInputSize]; 7.72 + p11.C_Sign(sessId, tmpBuffer); 7.73 + break; 7.74 + case MODE_VERIFY: 7.75 + p11.C_VerifyRecover(sessId, buffer, 0, inLen, buffer, 7.76 + 0, outLen); 7.77 + break; 7.78 + default: 7.79 + throw new ProviderException("internal error"); 7.80 } 7.81 + } catch (PKCS11Exception e) { 7.82 + // XXX ensure this always works, ignore error 7.83 } 7.84 } 7.85 7.86 @@ -361,6 +360,7 @@ 7.87 private int implDoFinal(byte[] out, int outOfs, int outLen) 7.88 throws BadPaddingException, IllegalBlockSizeException { 7.89 if (bufOfs > maxInputSize) { 7.90 + reset(true); 7.91 throw new IllegalBlockSizeException("Data must not be longer " 7.92 + "than " + maxInputSize + " bytes"); 7.93 }
8.1 --- a/src/share/classes/sun/security/pkcs11/P11Signature.java Sun Oct 25 03:07:23 2020 +0800 8.2 +++ b/src/share/classes/sun/security/pkcs11/P11Signature.java Sat Nov 07 10:05:20 2020 +0800 8.3 @@ -245,10 +245,12 @@ 8.4 return; 8.5 } 8.6 initialized = false; 8.7 + 8.8 try { 8.9 if (session == null) { 8.10 return; 8.11 } 8.12 + 8.13 if (doCancel && token.explicitCancel) { 8.14 cancelOperation(); 8.15 } 8.16 @@ -259,59 +261,51 @@ 8.17 } 8.18 8.19 private void cancelOperation() { 8.20 - 8.21 token.ensureValid(); 8.22 - if (session.hasObjects() == false) { 8.23 - session = token.killSession(session); 8.24 - return; 8.25 - } else { 8.26 - // "cancel" operation by finishing it 8.27 - // XXX make sure all this always works correctly 8.28 + // cancel operation by finishing it; avoid killSession as some 8.29 + // hardware vendors may require re-login 8.30 + try { 8.31 if (mode == M_SIGN) { 8.32 - try { 8.33 - if (type == T_UPDATE) { 8.34 - token.p11.C_SignFinal(session.id(), 0); 8.35 - } else { 8.36 - byte[] digest; 8.37 - if (type == T_DIGEST) { 8.38 - digest = md.digest(); 8.39 - } else { // T_RAW 8.40 - digest = buffer; 8.41 - } 8.42 - token.p11.C_Sign(session.id(), digest); 8.43 + if (type == T_UPDATE) { 8.44 + token.p11.C_SignFinal(session.id(), 0); 8.45 + } else { 8.46 + byte[] digest; 8.47 + if (type == T_DIGEST) { 8.48 + digest = md.digest(); 8.49 + } else { // T_RAW 8.50 + digest = buffer; 8.51 } 8.52 - } catch (PKCS11Exception e) { 8.53 - throw new ProviderException("cancel failed", e); 8.54 + token.p11.C_Sign(session.id(), digest); 8.55 } 8.56 } else { // M_VERIFY 8.57 byte[] signature; 8.58 - try { 8.59 - if (keyAlgorithm.equals("DSA")) { 8.60 - signature = new byte[40]; 8.61 - } else { 8.62 - signature = new byte[(p11Key.length() + 7) >> 3]; 8.63 + if (keyAlgorithm.equals("DSA")) { 8.64 + signature = new byte[40]; 8.65 + } else { 8.66 + signature = new byte[(p11Key.length() + 7) >> 3]; 8.67 + } 8.68 + if (type == T_UPDATE) { 8.69 + token.p11.C_VerifyFinal(session.id(), signature); 8.70 + } else { 8.71 + byte[] digest; 8.72 + if (type == T_DIGEST) { 8.73 + digest = md.digest(); 8.74 + } else { // T_RAW 8.75 + digest = buffer; 8.76 } 8.77 - if (type == T_UPDATE) { 8.78 - token.p11.C_VerifyFinal(session.id(), signature); 8.79 - } else { 8.80 - byte[] digest; 8.81 - if (type == T_DIGEST) { 8.82 - digest = md.digest(); 8.83 - } else { // T_RAW 8.84 - digest = buffer; 8.85 - } 8.86 - token.p11.C_Verify(session.id(), digest, signature); 8.87 - } 8.88 - } catch (PKCS11Exception e) { 8.89 - long errorCode = e.getErrorCode(); 8.90 - if ((errorCode == CKR_SIGNATURE_INVALID) || 8.91 - (errorCode == CKR_SIGNATURE_LEN_RANGE)) { 8.92 - // expected since signature is incorrect 8.93 - return; 8.94 - } 8.95 - throw new ProviderException("cancel failed", e); 8.96 + token.p11.C_Verify(session.id(), digest, signature); 8.97 } 8.98 } 8.99 + } catch (PKCS11Exception e) { 8.100 + if (mode == M_VERIFY) { 8.101 + long errorCode = e.getErrorCode(); 8.102 + if ((errorCode == CKR_SIGNATURE_INVALID) || 8.103 + (errorCode == CKR_SIGNATURE_LEN_RANGE)) { 8.104 + // expected since signature is incorrect 8.105 + return; 8.106 + } 8.107 + } 8.108 + throw new ProviderException("cancel failed", e); 8.109 } 8.110 } 8.111
9.1 --- a/src/share/classes/sun/security/ssl/CertificateVerify.java Sun Oct 25 03:07:23 2020 +0800 9.2 +++ b/src/share/classes/sun/security/ssl/CertificateVerify.java Sat Nov 07 10:05:20 2020 +0800 9.3 @@ -31,6 +31,7 @@ 9.4 import java.text.MessageFormat; 9.5 import java.util.Arrays; 9.6 import java.util.Locale; 9.7 +import java.util.Map; 9.8 import sun.security.ssl.SSLHandshake.HandshakeMessage; 9.9 import sun.security.ssl.X509Authentication.X509Credentials; 9.10 import sun.security.ssl.X509Authentication.X509Possession; 9.11 @@ -585,30 +586,27 @@ 9.12 9.13 // This happens in client side only. 9.14 ClientHandshakeContext chc = (ClientHandshakeContext)context; 9.15 - this.signatureScheme = SignatureScheme.getPreferableAlgorithm( 9.16 + Map.Entry<SignatureScheme, Signature> schemeAndSigner = 9.17 + SignatureScheme.getSignerOfPreferableAlgorithm( 9.18 chc.peerRequestedSignatureSchemes, 9.19 x509Possession, 9.20 chc.negotiatedProtocol); 9.21 - if (signatureScheme == null) { 9.22 + if (schemeAndSigner == null) { 9.23 // Unlikely, the credentials generator should have 9.24 // selected the preferable signature algorithm properly. 9.25 throw chc.conContext.fatal(Alert.INTERNAL_ERROR, 9.26 - "No preferred signature algorithm for CertificateVerify"); 9.27 + "No supported CertificateVerify signature algorithm for " + 9.28 + x509Possession.popPrivateKey.getAlgorithm() + 9.29 + " key"); 9.30 } 9.31 9.32 + this.signatureScheme = schemeAndSigner.getKey(); 9.33 byte[] temproary = null; 9.34 try { 9.35 - Signature signer = 9.36 - signatureScheme.getSignature(x509Possession.popPrivateKey); 9.37 + Signature signer = schemeAndSigner.getValue(); 9.38 signer.update(chc.handshakeHash.archived()); 9.39 temproary = signer.sign(); 9.40 - } catch (NoSuchAlgorithmException | 9.41 - InvalidAlgorithmParameterException nsae) { 9.42 - throw chc.conContext.fatal(Alert.INTERNAL_ERROR, 9.43 - "Unsupported signature algorithm (" + 9.44 - signatureScheme.name + 9.45 - ") used in CertificateVerify handshake message", nsae); 9.46 - } catch (InvalidKeyException | SignatureException ikse) { 9.47 + } catch (SignatureException ikse) { 9.48 throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE, 9.49 "Cannot produce CertificateVerify signature", ikse); 9.50 } 9.51 @@ -668,7 +666,7 @@ 9.52 this.signature = Record.getBytes16(m); 9.53 try { 9.54 Signature signer = 9.55 - signatureScheme.getSignature(x509Credentials.popPublicKey); 9.56 + signatureScheme.getVerifier(x509Credentials.popPublicKey); 9.57 signer.update(shc.handshakeHash.archived()); 9.58 if (!signer.verify(signature)) { 9.59 throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE, 9.60 @@ -897,17 +895,22 @@ 9.61 X509Possession x509Possession) throws IOException { 9.62 super(context); 9.63 9.64 - this.signatureScheme = SignatureScheme.getPreferableAlgorithm( 9.65 - context.peerRequestedSignatureSchemes, 9.66 - x509Possession, 9.67 - context.negotiatedProtocol); 9.68 - if (signatureScheme == null) { 9.69 + Map.Entry<SignatureScheme, Signature> schemeAndSigner = 9.70 + SignatureScheme.getSignerOfPreferableAlgorithm( 9.71 + context.peerRequestedSignatureSchemes, 9.72 + x509Possession, 9.73 + context.negotiatedProtocol); 9.74 + if (schemeAndSigner == null) { 9.75 // Unlikely, the credentials generator should have 9.76 // selected the preferable signature algorithm properly. 9.77 throw context.conContext.fatal(Alert.INTERNAL_ERROR, 9.78 - "No preferred signature algorithm for CertificateVerify"); 9.79 + "No supported CertificateVerify signature algorithm for " + 9.80 + x509Possession.popPrivateKey.getAlgorithm() + 9.81 + " key"); 9.82 } 9.83 9.84 + this.signatureScheme = schemeAndSigner.getKey(); 9.85 + 9.86 byte[] hashValue = context.handshakeHash.digest(); 9.87 byte[] contentCovered; 9.88 if (context.sslConfig.isClientMode) { 9.89 @@ -924,17 +927,10 @@ 9.90 9.91 byte[] temproary = null; 9.92 try { 9.93 - Signature signer = 9.94 - signatureScheme.getSignature(x509Possession.popPrivateKey); 9.95 + Signature signer = schemeAndSigner.getValue(); 9.96 signer.update(contentCovered); 9.97 temproary = signer.sign(); 9.98 - } catch (NoSuchAlgorithmException | 9.99 - InvalidAlgorithmParameterException nsae) { 9.100 - throw context.conContext.fatal(Alert.INTERNAL_ERROR, 9.101 - "Unsupported signature algorithm (" + 9.102 - signatureScheme.name + 9.103 - ") used in CertificateVerify handshake message", nsae); 9.104 - } catch (InvalidKeyException | SignatureException ikse) { 9.105 + } catch (SignatureException ikse) { 9.106 throw context.conContext.fatal(Alert.HANDSHAKE_FAILURE, 9.107 "Cannot produce CertificateVerify signature", ikse); 9.108 } 9.109 @@ -1005,7 +1001,7 @@ 9.110 9.111 try { 9.112 Signature signer = 9.113 - signatureScheme.getSignature(x509Credentials.popPublicKey); 9.114 + signatureScheme.getVerifier(x509Credentials.popPublicKey); 9.115 signer.update(contentCovered); 9.116 if (!signer.verify(signature)) { 9.117 throw context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
10.1 --- a/src/share/classes/sun/security/ssl/DHServerKeyExchange.java Sun Oct 25 03:07:23 2020 +0800 10.2 +++ b/src/share/classes/sun/security/ssl/DHServerKeyExchange.java Sat Nov 07 10:05:20 2020 +0800 10.3 @@ -42,6 +42,7 @@ 10.4 import java.text.MessageFormat; 10.5 import java.util.EnumSet; 10.6 import java.util.Locale; 10.7 +import java.util.Map; 10.8 import javax.crypto.interfaces.DHPublicKey; 10.9 import javax.crypto.spec.DHParameterSpec; 10.10 import javax.crypto.spec.DHPublicKeySpec; 10.11 @@ -125,24 +126,21 @@ 10.12 shc.negotiatedProtocol.useTLS12PlusSpec(); 10.13 Signature signer = null; 10.14 if (useExplicitSigAlgorithm) { 10.15 - signatureScheme = SignatureScheme.getPreferableAlgorithm( 10.16 - shc.peerRequestedSignatureSchemes, 10.17 - x509Possession, 10.18 - shc.negotiatedProtocol); 10.19 - if (signatureScheme == null) { 10.20 + Map.Entry<SignatureScheme, Signature> schemeAndSigner = 10.21 + SignatureScheme.getSignerOfPreferableAlgorithm( 10.22 + shc.peerRequestedSignatureSchemes, 10.23 + x509Possession, 10.24 + shc.negotiatedProtocol); 10.25 + if (schemeAndSigner == null) { 10.26 // Unlikely, the credentials generator should have 10.27 // selected the preferable signature algorithm properly. 10.28 throw shc.conContext.fatal(Alert.INTERNAL_ERROR, 10.29 - "No preferred signature algorithm"); 10.30 - } 10.31 - try { 10.32 - signer = signatureScheme.getSignature( 10.33 - x509Possession.popPrivateKey); 10.34 - } catch (NoSuchAlgorithmException | InvalidKeyException | 10.35 - InvalidAlgorithmParameterException nsae) { 10.36 - throw shc.conContext.fatal(Alert.INTERNAL_ERROR, 10.37 - "Unsupported signature algorithm: " + 10.38 - signatureScheme.name, nsae); 10.39 + "No supported signature algorithm for " + 10.40 + x509Possession.popPrivateKey.getAlgorithm() + 10.41 + " key"); 10.42 + } else { 10.43 + signatureScheme = schemeAndSigner.getKey(); 10.44 + signer = schemeAndSigner.getValue(); 10.45 } 10.46 } else { 10.47 signatureScheme = null; 10.48 @@ -241,7 +239,7 @@ 10.49 Signature signer; 10.50 if (useExplicitSigAlgorithm) { 10.51 try { 10.52 - signer = signatureScheme.getSignature( 10.53 + signer = signatureScheme.getVerifier( 10.54 x509Credentials.popPublicKey); 10.55 } catch (NoSuchAlgorithmException | InvalidKeyException | 10.56 InvalidAlgorithmParameterException nsae) {
11.1 --- a/src/share/classes/sun/security/ssl/ECDHServerKeyExchange.java Sun Oct 25 03:07:23 2020 +0800 11.2 +++ b/src/share/classes/sun/security/ssl/ECDHServerKeyExchange.java Sat Nov 07 10:05:20 2020 +0800 11.3 @@ -45,6 +45,7 @@ 11.4 import java.text.MessageFormat; 11.5 import java.util.EnumSet; 11.6 import java.util.Locale; 11.7 +import java.util.Map; 11.8 import sun.security.ssl.ECDHKeyExchange.ECDHECredentials; 11.9 import sun.security.ssl.ECDHKeyExchange.ECDHEPossession; 11.10 import sun.security.ssl.SSLHandshake.HandshakeMessage; 11.11 @@ -139,26 +140,21 @@ 11.12 shc.negotiatedProtocol.useTLS12PlusSpec(); 11.13 Signature signer = null; 11.14 if (useExplicitSigAlgorithm) { 11.15 - signatureScheme = SignatureScheme.getPreferableAlgorithm( 11.16 - shc.peerRequestedSignatureSchemes, 11.17 - x509Possession, 11.18 - shc.negotiatedProtocol); 11.19 - if (signatureScheme == null) { 11.20 + Map.Entry<SignatureScheme, Signature> schemeAndSigner = 11.21 + SignatureScheme.getSignerOfPreferableAlgorithm( 11.22 + shc.peerRequestedSignatureSchemes, 11.23 + x509Possession, 11.24 + shc.negotiatedProtocol); 11.25 + if (schemeAndSigner == null) { 11.26 // Unlikely, the credentials generator should have 11.27 // selected the preferable signature algorithm properly. 11.28 throw shc.conContext.fatal(Alert.INTERNAL_ERROR, 11.29 - "No preferred signature algorithm for " + 11.30 + "No supported signature algorithm for " + 11.31 x509Possession.popPrivateKey.getAlgorithm() + 11.32 " key"); 11.33 - } 11.34 - try { 11.35 - signer = signatureScheme.getSignature( 11.36 - x509Possession.popPrivateKey); 11.37 - } catch (NoSuchAlgorithmException | InvalidKeyException | 11.38 - InvalidAlgorithmParameterException nsae) { 11.39 - throw shc.conContext.fatal(Alert.INTERNAL_ERROR, 11.40 - "Unsupported signature algorithm: " + 11.41 - signatureScheme.name, nsae); 11.42 + } else { 11.43 + signatureScheme = schemeAndSigner.getKey(); 11.44 + signer = schemeAndSigner.getValue(); 11.45 } 11.46 } else { 11.47 signatureScheme = null; 11.48 @@ -295,7 +291,7 @@ 11.49 Signature signer; 11.50 if (useExplicitSigAlgorithm) { 11.51 try { 11.52 - signer = signatureScheme.getSignature( 11.53 + signer = signatureScheme.getVerifier( 11.54 x509Credentials.popPublicKey); 11.55 } catch (NoSuchAlgorithmException | InvalidKeyException | 11.56 InvalidAlgorithmParameterException nsae) {
12.1 --- a/src/share/classes/sun/security/ssl/SignatureScheme.java Sun Oct 25 03:07:23 2020 +0800 12.2 +++ b/src/share/classes/sun/security/ssl/SignatureScheme.java Sat Nov 07 10:05:20 2020 +0800 12.3 @@ -31,6 +31,7 @@ 12.4 import java.security.spec.ECParameterSpec; 12.5 import java.security.spec.MGF1ParameterSpec; 12.6 import java.security.spec.PSSParameterSpec; 12.7 +import java.util.AbstractMap.SimpleImmutableEntry; 12.8 import java.util.ArrayList; 12.9 import java.util.Arrays; 12.10 import java.util.Collection; 12.11 @@ -38,6 +39,7 @@ 12.12 import java.util.EnumSet; 12.13 import java.util.LinkedList; 12.14 import java.util.List; 12.15 +import java.util.Map; 12.16 import java.util.Set; 12.17 import sun.security.ssl.SupportedGroupsExtension.NamedGroup; 12.18 import sun.security.ssl.SupportedGroupsExtension.NamedGroupType; 12.19 @@ -427,7 +429,7 @@ 12.20 return null; 12.21 } 12.22 12.23 - static SignatureScheme getPreferableAlgorithm( 12.24 + static Map.Entry<SignatureScheme, Signature> getSignerOfPreferableAlgorithm( 12.25 List<SignatureScheme> schemes, 12.26 X509Possession x509Possession, 12.27 ProtocolVersion version) { 12.28 @@ -452,7 +454,10 @@ 12.29 x509Possession.getECParameterSpec(); 12.30 if (params != null && 12.31 ss.namedGroup == NamedGroup.valueOf(params)) { 12.32 - return ss; 12.33 + Signature signer = ss.getSigner(signingKey); 12.34 + if (signer != null) { 12.35 + return new SimpleImmutableEntry<>(ss, signer); 12.36 + } 12.37 } 12.38 12.39 if (SSLLogger.isOn && 12.40 @@ -477,7 +482,10 @@ 12.41 NamedGroup keyGroup = NamedGroup.valueOf(params); 12.42 if (keyGroup != null && 12.43 SupportedGroups.isSupported(keyGroup)) { 12.44 - return ss; 12.45 + Signature signer = ss.getSigner(signingKey); 12.46 + if (signer != null) { 12.47 + return new SimpleImmutableEntry<>(ss, signer); 12.48 + } 12.49 } 12.50 } 12.51 12.52 @@ -488,7 +496,10 @@ 12.53 "), unsupported EC parameter spec: " + params); 12.54 } 12.55 } else { 12.56 - return ss; 12.57 + Signature signer = ss.getSigner(signingKey); 12.58 + if (signer != null) { 12.59 + return new SimpleImmutableEntry<>(ss, signer); 12.60 + } 12.61 } 12.62 } 12.63 } 12.64 @@ -509,21 +520,48 @@ 12.65 return new String[0]; 12.66 } 12.67 12.68 - Signature getSignature(Key key) throws NoSuchAlgorithmException, 12.69 + // This method is used to get the signature instance of this signature 12.70 + // scheme for the specific public key. Unlike getSigner(), the exception 12.71 + // is bubbled up. If the public key does not support this signature 12.72 + // scheme, it normally means the TLS handshaking cannot continue and 12.73 + // the connection should be terminated. 12.74 + Signature getVerifier(PublicKey publicKey) throws NoSuchAlgorithmException, 12.75 InvalidAlgorithmParameterException, InvalidKeyException { 12.76 if (!isAvailable) { 12.77 return null; 12.78 } 12.79 12.80 - Signature signer = JsseJce.getSignature(algorithm); 12.81 - if (key instanceof PublicKey) { 12.82 - SignatureUtil.initVerifyWithParam(signer, (PublicKey)key, 12.83 - signAlgParameter); 12.84 - } else { 12.85 - SignatureUtil.initSignWithParam(signer, (PrivateKey)key, 12.86 - signAlgParameter, null); 12.87 + Signature verifier = Signature.getInstance(algorithm); 12.88 + SignatureUtil.initVerifyWithParam(verifier, publicKey, signAlgParameter); 12.89 + 12.90 + return verifier; 12.91 + } 12.92 + 12.93 + // This method is also used to choose preferable signature scheme for the 12.94 + // specific private key. If the private key does not support the signature 12.95 + // scheme, {@code null} is returned, and the caller may fail back to next 12.96 + // available signature scheme. 12.97 + private Signature getSigner(PrivateKey privateKey) { 12.98 + if (!isAvailable) { 12.99 + return null; 12.100 } 12.101 12.102 - return signer; 12.103 + try { 12.104 + Signature signer = Signature.getInstance(algorithm); 12.105 + SignatureUtil.initSignWithParam(signer, privateKey, 12.106 + signAlgParameter, 12.107 + null); 12.108 + return signer; 12.109 + } catch (NoSuchAlgorithmException | InvalidKeyException | 12.110 + InvalidAlgorithmParameterException nsae) { 12.111 + if (SSLLogger.isOn && 12.112 + SSLLogger.isOn("ssl,handshake,verbose")) { 12.113 + SSLLogger.finest( 12.114 + "Ignore unsupported signature algorithm (" + 12.115 + this.name + ")", nsae); 12.116 + } 12.117 + } 12.118 + 12.119 + return null; 12.120 } 12.121 }