Merge
This commit is contained in:
commit
f4f859b446
.hgtags
src
hotspot
cpu
share
classfile
code
gc/z
include
opto
prims
runtime
java.base
share
classes
java
sun/security
ssl
Alert.javaAlpnExtension.javaCertSignAlgsExtension.javaCertStatusExtension.javaCertificateMessage.javaCertificateRequest.javaCertificateStatus.javaCertificateVerify.javaChangeCipherSpec.javaClientHello.javaClientKeyExchange.javaCookieExtension.javaDHClientKeyExchange.javaDHKeyExchange.javaDHServerKeyExchange.javaECDHClientKeyExchange.javaECDHKeyExchange.javaECDHServerKeyExchange.javaECPointFormatsExtension.javaEncryptedExtensions.javaExtendedMasterSecretExtension.javaFinished.javaHandshakeContext.javaHelloRequest.javaHelloVerifyRequest.javaKeyShareExtension.javaKeyUpdate.javaMaxFragExtension.javaNewSessionTicket.javaPostHandshakeContext.javaPreSharedKeyExtension.javaPskKeyExchangeModesExtension.javaRSAClientKeyExchange.javaRSAKeyExchange.javaRSAServerKeyExchange.javaRenegoInfoExtension.javaSSLConfiguration.javaSSLEngineImpl.javaSSLExtensions.javaSSLSocketImpl.javaSSLSocketInputRecord.javaSSLTransport.javaServerHello.javaServerHelloDone.javaServerKeyExchange.javaServerNameExtension.javaSignatureAlgorithmsExtension.javaSupportedGroupsExtension.javaSupportedVersionsExtension.javaTransportContext.java
util
native/libjava
unix/native
java.smartcardio/share/classes/javax/smartcardio
jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc
jdk.jshell/share/classes/jdk/internal/jshell/tool/resources
test/hotspot/jtreg
compiler
aot/cli/jaotc
c2/cr6340864
TestByteVect.javaTestDoubleVect.javaTestFloatVect.javaTestIntVect.javaTestLongVect.javaTestShortVect.java
codegen
loopopts
serviceability/jvmti/HeapMonitor/MyPackage
1
.hgtags
1
.hgtags
@ -527,3 +527,4 @@ f8fb0c86f2b3d24294d39c5685a628e1beb14ba7 jdk-12+21
|
||||
732bec44c89e8b93a38296bf690f97b7230c5b6d jdk-12+22
|
||||
eef755718cb24813031a842bbfc716a6cea18e9a jdk-12+23
|
||||
cc4098b3bc10d1c390384289025fea7b0d4b9e93 jdk-13+0
|
||||
7d4397b43fa305806160785a4c7210600d59581a jdk-12+24
|
||||
|
@ -2133,7 +2133,12 @@ const uint Matcher::vector_ideal_reg(int len) {
|
||||
}
|
||||
|
||||
const uint Matcher::vector_shift_count_ideal_reg(int size) {
|
||||
return Op_VecX;
|
||||
switch(size) {
|
||||
case 8: return Op_VecD;
|
||||
case 16: return Op_VecX;
|
||||
}
|
||||
ShouldNotReachHere();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// AES support not yet implemented
|
||||
@ -16581,32 +16586,32 @@ instruct vxor16B(vecX dst, vecX src1, vecX src2)
|
||||
%}
|
||||
|
||||
// ------------------------------ Shift ---------------------------------------
|
||||
|
||||
instruct vshiftcntL(vecX dst, iRegIorL2I cnt) %{
|
||||
instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{
|
||||
predicate(n->as_Vector()->length_in_bytes() == 8);
|
||||
match(Set dst (LShiftCntV cnt));
|
||||
format %{ "dup $dst, $cnt\t# shift count (vecX)" %}
|
||||
ins_encode %{
|
||||
__ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg));
|
||||
%}
|
||||
ins_pipe(vdup_reg_reg128);
|
||||
%}
|
||||
|
||||
// Right shifts on aarch64 SIMD are implemented as left shift by -ve amount
|
||||
instruct vshiftcntR(vecX dst, iRegIorL2I cnt) %{
|
||||
match(Set dst (RShiftCntV cnt));
|
||||
format %{ "dup $dst, $cnt\t# shift count (vecX)\n\tneg $dst, $dst\t T16B" %}
|
||||
format %{ "dup $dst, $cnt\t# shift count vector (8B)" %}
|
||||
ins_encode %{
|
||||
__ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg));
|
||||
%}
|
||||
ins_pipe(vdup_reg_reg64);
|
||||
%}
|
||||
|
||||
instruct vshiftcnt16B(vecX dst, iRegIorL2I cnt) %{
|
||||
predicate(n->as_Vector()->length_in_bytes() == 16);
|
||||
match(Set dst (LShiftCntV cnt));
|
||||
match(Set dst (RShiftCntV cnt));
|
||||
format %{ "dup $dst, $cnt\t# shift count vector (16B)" %}
|
||||
ins_encode %{
|
||||
__ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg));
|
||||
__ negr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($dst$$reg));
|
||||
%}
|
||||
ins_pipe(vdup_reg_reg128);
|
||||
%}
|
||||
|
||||
instruct vsll8B(vecD dst, vecD src, vecX shift) %{
|
||||
instruct vsll8B(vecD dst, vecD src, vecD shift) %{
|
||||
predicate(n->as_Vector()->length() == 4 ||
|
||||
n->as_Vector()->length() == 8);
|
||||
match(Set dst (LShiftVB src shift));
|
||||
match(Set dst (RShiftVB src shift));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "sshl $dst,$src,$shift\t# vector (8B)" %}
|
||||
ins_encode %{
|
||||
@ -16620,7 +16625,6 @@ instruct vsll8B(vecD dst, vecD src, vecX shift) %{
|
||||
instruct vsll16B(vecX dst, vecX src, vecX shift) %{
|
||||
predicate(n->as_Vector()->length() == 16);
|
||||
match(Set dst (LShiftVB src shift));
|
||||
match(Set dst (RShiftVB src shift));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "sshl $dst,$src,$shift\t# vector (16B)" %}
|
||||
ins_encode %{
|
||||
@ -16631,29 +16635,93 @@ instruct vsll16B(vecX dst, vecX src, vecX shift) %{
|
||||
ins_pipe(vshift128);
|
||||
%}
|
||||
|
||||
instruct vsrl8B(vecD dst, vecD src, vecX shift) %{
|
||||
// Right shifts with vector shift count on aarch64 SIMD are implemented
|
||||
// as left shift by negative shift count.
|
||||
// There are two cases for vector shift count.
|
||||
//
|
||||
// Case 1: The vector shift count is from replication.
|
||||
// | |
|
||||
// LoadVector RShiftCntV
|
||||
// | /
|
||||
// RShiftVI
|
||||
// Note: In inner loop, multiple neg instructions are used, which can be
|
||||
// moved to outer loop and merge into one neg instruction.
|
||||
//
|
||||
// Case 2: The vector shift count is from loading.
|
||||
// This case isn't supported by middle-end now. But it's supported by
|
||||
// panama/vectorIntrinsics(JEP 338: Vector API).
|
||||
// | |
|
||||
// LoadVector LoadVector
|
||||
// | /
|
||||
// RShiftVI
|
||||
//
|
||||
|
||||
instruct vsra8B(vecD dst, vecD src, vecD shift, vecD tmp) %{
|
||||
predicate(n->as_Vector()->length() == 4 ||
|
||||
n->as_Vector()->length() == 8);
|
||||
match(Set dst (URShiftVB src shift));
|
||||
match(Set dst (RShiftVB src shift));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ushl $dst,$src,$shift\t# vector (8B)" %}
|
||||
effect(TEMP tmp);
|
||||
format %{ "negr $tmp,$shift\t"
|
||||
"sshl $dst,$src,$tmp\t# vector (8B)" %}
|
||||
ins_encode %{
|
||||
__ ushl(as_FloatRegister($dst$$reg), __ T8B,
|
||||
as_FloatRegister($src$$reg),
|
||||
__ negr(as_FloatRegister($tmp$$reg), __ T8B,
|
||||
as_FloatRegister($shift$$reg));
|
||||
__ sshl(as_FloatRegister($dst$$reg), __ T8B,
|
||||
as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(vshift64);
|
||||
%}
|
||||
|
||||
instruct vsrl16B(vecX dst, vecX src, vecX shift) %{
|
||||
instruct vsra16B(vecX dst, vecX src, vecX shift, vecX tmp) %{
|
||||
predicate(n->as_Vector()->length() == 16);
|
||||
match(Set dst (RShiftVB src shift));
|
||||
ins_cost(INSN_COST);
|
||||
effect(TEMP tmp);
|
||||
format %{ "negr $tmp,$shift\t"
|
||||
"sshl $dst,$src,$tmp\t# vector (16B)" %}
|
||||
ins_encode %{
|
||||
__ negr(as_FloatRegister($tmp$$reg), __ T16B,
|
||||
as_FloatRegister($shift$$reg));
|
||||
__ sshl(as_FloatRegister($dst$$reg), __ T16B,
|
||||
as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(vshift128);
|
||||
%}
|
||||
|
||||
instruct vsrl8B(vecD dst, vecD src, vecD shift, vecD tmp) %{
|
||||
predicate(n->as_Vector()->length() == 4 ||
|
||||
n->as_Vector()->length() == 8);
|
||||
match(Set dst (URShiftVB src shift));
|
||||
ins_cost(INSN_COST);
|
||||
effect(TEMP tmp);
|
||||
format %{ "negr $tmp,$shift\t"
|
||||
"ushl $dst,$src,$tmp\t# vector (8B)" %}
|
||||
ins_encode %{
|
||||
__ negr(as_FloatRegister($tmp$$reg), __ T8B,
|
||||
as_FloatRegister($shift$$reg));
|
||||
__ ushl(as_FloatRegister($dst$$reg), __ T8B,
|
||||
as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(vshift64);
|
||||
%}
|
||||
|
||||
instruct vsrl16B(vecX dst, vecX src, vecX shift, vecX tmp) %{
|
||||
predicate(n->as_Vector()->length() == 16);
|
||||
match(Set dst (URShiftVB src shift));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ushl $dst,$src,$shift\t# vector (16B)" %}
|
||||
effect(TEMP tmp);
|
||||
format %{ "negr $tmp,$shift\t"
|
||||
"ushl $dst,$src,$tmp\t# vector (16B)" %}
|
||||
ins_encode %{
|
||||
__ negr(as_FloatRegister($tmp$$reg), __ T16B,
|
||||
as_FloatRegister($shift$$reg));
|
||||
__ ushl(as_FloatRegister($dst$$reg), __ T16B,
|
||||
as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($shift$$reg));
|
||||
as_FloatRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(vshift128);
|
||||
%}
|
||||
@ -16765,11 +16833,10 @@ instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{
|
||||
ins_pipe(vshift128_imm);
|
||||
%}
|
||||
|
||||
instruct vsll4S(vecD dst, vecD src, vecX shift) %{
|
||||
instruct vsll4S(vecD dst, vecD src, vecD shift) %{
|
||||
predicate(n->as_Vector()->length() == 2 ||
|
||||
n->as_Vector()->length() == 4);
|
||||
match(Set dst (LShiftVS src shift));
|
||||
match(Set dst (RShiftVS src shift));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "sshl $dst,$src,$shift\t# vector (4H)" %}
|
||||
ins_encode %{
|
||||
@ -16783,7 +16850,6 @@ instruct vsll4S(vecD dst, vecD src, vecX shift) %{
|
||||
instruct vsll8S(vecX dst, vecX src, vecX shift) %{
|
||||
predicate(n->as_Vector()->length() == 8);
|
||||
match(Set dst (LShiftVS src shift));
|
||||
match(Set dst (RShiftVS src shift));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "sshl $dst,$src,$shift\t# vector (8H)" %}
|
||||
ins_encode %{
|
||||
@ -16794,29 +16860,72 @@ instruct vsll8S(vecX dst, vecX src, vecX shift) %{
|
||||
ins_pipe(vshift128);
|
||||
%}
|
||||
|
||||
instruct vsrl4S(vecD dst, vecD src, vecX shift) %{
|
||||
instruct vsra4S(vecD dst, vecD src, vecD shift, vecD tmp) %{
|
||||
predicate(n->as_Vector()->length() == 2 ||
|
||||
n->as_Vector()->length() == 4);
|
||||
match(Set dst (URShiftVS src shift));
|
||||
match(Set dst (RShiftVS src shift));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ushl $dst,$src,$shift\t# vector (4H)" %}
|
||||
effect(TEMP tmp);
|
||||
format %{ "negr $tmp,$shift\t"
|
||||
"sshl $dst,$src,$tmp\t# vector (4H)" %}
|
||||
ins_encode %{
|
||||
__ ushl(as_FloatRegister($dst$$reg), __ T4H,
|
||||
as_FloatRegister($src$$reg),
|
||||
__ negr(as_FloatRegister($tmp$$reg), __ T8B,
|
||||
as_FloatRegister($shift$$reg));
|
||||
__ sshl(as_FloatRegister($dst$$reg), __ T4H,
|
||||
as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(vshift64);
|
||||
%}
|
||||
|
||||
instruct vsrl8S(vecX dst, vecX src, vecX shift) %{
|
||||
instruct vsra8S(vecX dst, vecX src, vecX shift, vecX tmp) %{
|
||||
predicate(n->as_Vector()->length() == 8);
|
||||
match(Set dst (RShiftVS src shift));
|
||||
ins_cost(INSN_COST);
|
||||
effect(TEMP tmp);
|
||||
format %{ "negr $tmp,$shift\t"
|
||||
"sshl $dst,$src,$tmp\t# vector (8H)" %}
|
||||
ins_encode %{
|
||||
__ negr(as_FloatRegister($tmp$$reg), __ T16B,
|
||||
as_FloatRegister($shift$$reg));
|
||||
__ sshl(as_FloatRegister($dst$$reg), __ T8H,
|
||||
as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(vshift128);
|
||||
%}
|
||||
|
||||
instruct vsrl4S(vecD dst, vecD src, vecD shift, vecD tmp) %{
|
||||
predicate(n->as_Vector()->length() == 2 ||
|
||||
n->as_Vector()->length() == 4);
|
||||
match(Set dst (URShiftVS src shift));
|
||||
ins_cost(INSN_COST);
|
||||
effect(TEMP tmp);
|
||||
format %{ "negr $tmp,$shift\t"
|
||||
"ushl $dst,$src,$tmp\t# vector (4H)" %}
|
||||
ins_encode %{
|
||||
__ negr(as_FloatRegister($tmp$$reg), __ T8B,
|
||||
as_FloatRegister($shift$$reg));
|
||||
__ ushl(as_FloatRegister($dst$$reg), __ T4H,
|
||||
as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(vshift64);
|
||||
%}
|
||||
|
||||
instruct vsrl8S(vecX dst, vecX src, vecX shift, vecX tmp) %{
|
||||
predicate(n->as_Vector()->length() == 8);
|
||||
match(Set dst (URShiftVS src shift));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ushl $dst,$src,$shift\t# vector (8H)" %}
|
||||
effect(TEMP tmp);
|
||||
format %{ "negr $tmp,$shift\t"
|
||||
"ushl $dst,$src,$tmp\t# vector (8H)" %}
|
||||
ins_encode %{
|
||||
__ negr(as_FloatRegister($tmp$$reg), __ T16B,
|
||||
as_FloatRegister($shift$$reg));
|
||||
__ ushl(as_FloatRegister($dst$$reg), __ T8H,
|
||||
as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($shift$$reg));
|
||||
as_FloatRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(vshift128);
|
||||
%}
|
||||
@ -16928,10 +17037,9 @@ instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{
|
||||
ins_pipe(vshift128_imm);
|
||||
%}
|
||||
|
||||
instruct vsll2I(vecD dst, vecD src, vecX shift) %{
|
||||
instruct vsll2I(vecD dst, vecD src, vecD shift) %{
|
||||
predicate(n->as_Vector()->length() == 2);
|
||||
match(Set dst (LShiftVI src shift));
|
||||
match(Set dst (RShiftVI src shift));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "sshl $dst,$src,$shift\t# vector (2S)" %}
|
||||
ins_encode %{
|
||||
@ -16945,7 +17053,6 @@ instruct vsll2I(vecD dst, vecD src, vecX shift) %{
|
||||
instruct vsll4I(vecX dst, vecX src, vecX shift) %{
|
||||
predicate(n->as_Vector()->length() == 4);
|
||||
match(Set dst (LShiftVI src shift));
|
||||
match(Set dst (RShiftVI src shift));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "sshl $dst,$src,$shift\t# vector (4S)" %}
|
||||
ins_encode %{
|
||||
@ -16956,28 +17063,70 @@ instruct vsll4I(vecX dst, vecX src, vecX shift) %{
|
||||
ins_pipe(vshift128);
|
||||
%}
|
||||
|
||||
instruct vsrl2I(vecD dst, vecD src, vecX shift) %{
|
||||
instruct vsra2I(vecD dst, vecD src, vecD shift, vecD tmp) %{
|
||||
predicate(n->as_Vector()->length() == 2);
|
||||
match(Set dst (URShiftVI src shift));
|
||||
match(Set dst (RShiftVI src shift));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ushl $dst,$src,$shift\t# vector (2S)" %}
|
||||
effect(TEMP tmp);
|
||||
format %{ "negr $tmp,$shift\t"
|
||||
"sshl $dst,$src,$tmp\t# vector (2S)" %}
|
||||
ins_encode %{
|
||||
__ ushl(as_FloatRegister($dst$$reg), __ T2S,
|
||||
as_FloatRegister($src$$reg),
|
||||
__ negr(as_FloatRegister($tmp$$reg), __ T8B,
|
||||
as_FloatRegister($shift$$reg));
|
||||
__ sshl(as_FloatRegister($dst$$reg), __ T2S,
|
||||
as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(vshift64);
|
||||
%}
|
||||
|
||||
instruct vsrl4I(vecX dst, vecX src, vecX shift) %{
|
||||
instruct vsra4I(vecX dst, vecX src, vecX shift, vecX tmp) %{
|
||||
predicate(n->as_Vector()->length() == 4);
|
||||
match(Set dst (RShiftVI src shift));
|
||||
ins_cost(INSN_COST);
|
||||
effect(TEMP tmp);
|
||||
format %{ "negr $tmp,$shift\t"
|
||||
"sshl $dst,$src,$tmp\t# vector (4S)" %}
|
||||
ins_encode %{
|
||||
__ negr(as_FloatRegister($tmp$$reg), __ T16B,
|
||||
as_FloatRegister($shift$$reg));
|
||||
__ sshl(as_FloatRegister($dst$$reg), __ T4S,
|
||||
as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(vshift128);
|
||||
%}
|
||||
|
||||
instruct vsrl2I(vecD dst, vecD src, vecD shift, vecD tmp) %{
|
||||
predicate(n->as_Vector()->length() == 2);
|
||||
match(Set dst (URShiftVI src shift));
|
||||
ins_cost(INSN_COST);
|
||||
effect(TEMP tmp);
|
||||
format %{ "negr $tmp,$shift\t"
|
||||
"ushl $dst,$src,$tmp\t# vector (2S)" %}
|
||||
ins_encode %{
|
||||
__ negr(as_FloatRegister($tmp$$reg), __ T8B,
|
||||
as_FloatRegister($shift$$reg));
|
||||
__ ushl(as_FloatRegister($dst$$reg), __ T2S,
|
||||
as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(vshift64);
|
||||
%}
|
||||
|
||||
instruct vsrl4I(vecX dst, vecX src, vecX shift, vecX tmp) %{
|
||||
predicate(n->as_Vector()->length() == 4);
|
||||
match(Set dst (URShiftVI src shift));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ushl $dst,$src,$shift\t# vector (4S)" %}
|
||||
effect(TEMP tmp);
|
||||
format %{ "negr $tmp,$shift\t"
|
||||
"ushl $dst,$src,$tmp\t# vector (4S)" %}
|
||||
ins_encode %{
|
||||
__ negr(as_FloatRegister($tmp$$reg), __ T16B,
|
||||
as_FloatRegister($shift$$reg));
|
||||
__ ushl(as_FloatRegister($dst$$reg), __ T4S,
|
||||
as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($shift$$reg));
|
||||
as_FloatRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(vshift128);
|
||||
%}
|
||||
@ -17063,7 +17212,6 @@ instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{
|
||||
instruct vsll2L(vecX dst, vecX src, vecX shift) %{
|
||||
predicate(n->as_Vector()->length() == 2);
|
||||
match(Set dst (LShiftVL src shift));
|
||||
match(Set dst (RShiftVL src shift));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "sshl $dst,$src,$shift\t# vector (2D)" %}
|
||||
ins_encode %{
|
||||
@ -17074,15 +17222,36 @@ instruct vsll2L(vecX dst, vecX src, vecX shift) %{
|
||||
ins_pipe(vshift128);
|
||||
%}
|
||||
|
||||
instruct vsrl2L(vecX dst, vecX src, vecX shift) %{
|
||||
instruct vsra2L(vecX dst, vecX src, vecX shift, vecX tmp) %{
|
||||
predicate(n->as_Vector()->length() == 2);
|
||||
match(Set dst (RShiftVL src shift));
|
||||
ins_cost(INSN_COST);
|
||||
effect(TEMP tmp);
|
||||
format %{ "negr $tmp,$shift\t"
|
||||
"sshl $dst,$src,$tmp\t# vector (2D)" %}
|
||||
ins_encode %{
|
||||
__ negr(as_FloatRegister($tmp$$reg), __ T16B,
|
||||
as_FloatRegister($shift$$reg));
|
||||
__ sshl(as_FloatRegister($dst$$reg), __ T2D,
|
||||
as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(vshift128);
|
||||
%}
|
||||
|
||||
instruct vsrl2L(vecX dst, vecX src, vecX shift, vecX tmp) %{
|
||||
predicate(n->as_Vector()->length() == 2);
|
||||
match(Set dst (URShiftVL src shift));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ushl $dst,$src,$shift\t# vector (2D)" %}
|
||||
effect(TEMP tmp);
|
||||
format %{ "negr $tmp,$shift\t"
|
||||
"ushl $dst,$src,$tmp\t# vector (2D)" %}
|
||||
ins_encode %{
|
||||
__ negr(as_FloatRegister($tmp$$reg), __ T16B,
|
||||
as_FloatRegister($shift$$reg));
|
||||
__ ushl(as_FloatRegister($dst$$reg), __ T2D,
|
||||
as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($shift$$reg));
|
||||
as_FloatRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(vshift128);
|
||||
%}
|
||||
|
@ -8945,9 +8945,10 @@ instruct partialSubtypeCheck( R0RegP index, R1RegP sub, R2RegP super, flagsRegP
|
||||
instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch )
|
||||
%{
|
||||
match(Set pcc (FastLock object box));
|
||||
predicate(!(UseBiasedLocking && !UseOptoBiasInlining));
|
||||
|
||||
effect(TEMP scratch, TEMP scratch2);
|
||||
ins_cost(100);
|
||||
ins_cost(DEFAULT_COST*3);
|
||||
|
||||
format %{ "FASTLOCK $object, $box; KILL $scratch, $scratch2" %}
|
||||
ins_encode %{
|
||||
@ -8956,6 +8957,21 @@ instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRe
|
||||
ins_pipe(long_memory_op);
|
||||
%}
|
||||
|
||||
instruct cmpFastLock_noBiasInline(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2,
|
||||
iRegP scratch, iRegP scratch3) %{
|
||||
match(Set pcc (FastLock object box));
|
||||
predicate(UseBiasedLocking && !UseOptoBiasInlining);
|
||||
|
||||
effect(TEMP scratch, TEMP scratch2, TEMP scratch3);
|
||||
ins_cost(DEFAULT_COST*5);
|
||||
|
||||
format %{ "FASTLOCK $object, $box; KILL $scratch, $scratch2, $scratch3" %}
|
||||
ins_encode %{
|
||||
__ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register, $scratch3$$Register);
|
||||
%}
|
||||
ins_pipe(long_memory_op);
|
||||
%}
|
||||
|
||||
|
||||
instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch ) %{
|
||||
match(Set pcc (FastUnlock object box));
|
||||
|
@ -1971,7 +1971,7 @@ void MacroAssembler::resolve(DecoratorSet decorators, Register obj) {
|
||||
|
||||
|
||||
#ifdef COMPILER2
|
||||
void MacroAssembler::fast_lock(Register Roop, Register Rbox, Register Rscratch, Register Rscratch2)
|
||||
void MacroAssembler::fast_lock(Register Roop, Register Rbox, Register Rscratch, Register Rscratch2, Register scratch3)
|
||||
{
|
||||
assert(VM_Version::supports_ldrex(), "unsupported, yet?");
|
||||
|
||||
@ -1985,11 +1985,13 @@ void MacroAssembler::fast_lock(Register Roop, Register Rbox, Register Rscratch,
|
||||
Label fast_lock, done;
|
||||
|
||||
if (UseBiasedLocking && !UseOptoBiasInlining) {
|
||||
Label failed;
|
||||
biased_locking_enter(Roop, Rmark, Rscratch, false, noreg, done, failed);
|
||||
bind(failed);
|
||||
assert(scratch3 != noreg, "need extra temporary for -XX:-UseOptoBiasInlining");
|
||||
biased_locking_enter(Roop, Rmark, Rscratch, false, scratch3, done, done);
|
||||
// Fall through if lock not biased otherwise branch to done
|
||||
}
|
||||
|
||||
// Invariant: Rmark loaded below does not contain biased lock pattern
|
||||
|
||||
ldr(Rmark, Address(Roop, oopDesc::mark_offset_in_bytes()));
|
||||
tst(Rmark, markOopDesc::unlocked_value);
|
||||
b(fast_lock, ne);
|
||||
@ -2016,6 +2018,9 @@ void MacroAssembler::fast_lock(Register Roop, Register Rbox, Register Rscratch,
|
||||
|
||||
bind(done);
|
||||
|
||||
// At this point flags are set as follows:
|
||||
// EQ -> Success
|
||||
// NE -> Failure, branch to slow path
|
||||
}
|
||||
|
||||
void MacroAssembler::fast_unlock(Register Roop, Register Rbox, Register Rscratch, Register Rscratch2)
|
||||
|
@ -371,10 +371,10 @@ public:
|
||||
// lock_reg and obj_reg must be loaded up with the appropriate values.
|
||||
// swap_reg must be supplied.
|
||||
// tmp_reg must be supplied.
|
||||
// Optional slow case is for implementations (interpreter and C1) which branch to
|
||||
// slow case directly. If slow_case is NULL, then leaves condition
|
||||
// codes set (for C2's Fast_Lock node) and jumps to done label.
|
||||
// Falls through for the fast locking attempt.
|
||||
// Done label is branched to with condition code EQ set if the lock is
|
||||
// biased and we acquired it. Slow case label is branched to with
|
||||
// condition code NE set if the lock is biased but we failed to acquire
|
||||
// it. Otherwise fall through.
|
||||
// Returns offset of first potentially-faulting instruction for null
|
||||
// check info (currently consumed only by C1). If
|
||||
// swap_reg_contains_mark is true then returns -1 as it is assumed
|
||||
@ -1073,7 +1073,7 @@ public:
|
||||
void restore_default_fp_mode();
|
||||
|
||||
#ifdef COMPILER2
|
||||
void fast_lock(Register obj, Register box, Register scratch, Register scratch2);
|
||||
void fast_lock(Register obj, Register box, Register scratch, Register scratch2, Register scratch3 = noreg);
|
||||
void fast_unlock(Register obj, Register box, Register scratch, Register scratch2);
|
||||
#endif
|
||||
|
||||
|
@ -7760,9 +7760,9 @@ instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, eFlagsReg
|
||||
match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3)));
|
||||
effect(KILL cr, KILL src2);
|
||||
|
||||
expand %{ mulI_rReg(dst, src1, cr);
|
||||
mulI_rReg(src2, src3, cr);
|
||||
addI_rReg(dst, src2, cr); %}
|
||||
expand %{ mulI_eReg(dst, src1, cr);
|
||||
mulI_eReg(src2, src3, cr);
|
||||
addI_eReg(dst, src2, cr); %}
|
||||
%}
|
||||
|
||||
// Multiply Register Int to Long
|
||||
|
@ -173,7 +173,7 @@ class DictionaryEntry : public HashtableEntry<InstanceKlass*, mtClass> {
|
||||
for (ProtectionDomainEntry* current = pd_set(); // accessed at a safepoint
|
||||
current != NULL;
|
||||
current = current->_next) {
|
||||
guarantee(oopDesc::is_oop(current->_pd_cache->object_no_keepalive()), "Invalid oop");
|
||||
guarantee(oopDesc::is_oop_or_null(current->_pd_cache->object_no_keepalive()), "Invalid oop");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,9 +51,9 @@ ScopeDesc::ScopeDesc(const CompiledMethod* code, int decode_offset, bool reexecu
|
||||
}
|
||||
|
||||
|
||||
ScopeDesc::ScopeDesc(const ScopeDesc* parent) {
|
||||
void ScopeDesc::initialize(const ScopeDesc* parent, int decode_offset) {
|
||||
_code = parent->_code;
|
||||
_decode_offset = parent->_sender_decode_offset;
|
||||
_decode_offset = decode_offset;
|
||||
_objects = parent->_objects;
|
||||
_reexecute = false; //reexecute only applies to the first scope
|
||||
_rethrow_exception = false;
|
||||
@ -61,6 +61,14 @@ ScopeDesc::ScopeDesc(const ScopeDesc* parent) {
|
||||
decode_body();
|
||||
}
|
||||
|
||||
ScopeDesc::ScopeDesc(const ScopeDesc* parent) {
|
||||
initialize(parent, parent->_sender_decode_offset);
|
||||
}
|
||||
|
||||
ScopeDesc::ScopeDesc(const ScopeDesc* parent, int decode_offset) {
|
||||
initialize(parent, decode_offset);
|
||||
}
|
||||
|
||||
|
||||
void ScopeDesc::decode_body() {
|
||||
if (decode_offset() == DebugInformationRecorder::serialized_null) {
|
||||
|
@ -67,6 +67,9 @@ class ScopeDesc : public ResourceObj {
|
||||
// avoid a .hpp-.hpp dependency.)
|
||||
ScopeDesc(const CompiledMethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop);
|
||||
|
||||
// Direct access to scope
|
||||
ScopeDesc* at_offset(int decode_offset) { return new ScopeDesc(this, decode_offset); }
|
||||
|
||||
// JVM state
|
||||
Method* method() const { return _method; }
|
||||
int bci() const { return _bci; }
|
||||
@ -85,12 +88,16 @@ class ScopeDesc : public ResourceObj {
|
||||
// Returns where the scope was decoded
|
||||
int decode_offset() const { return _decode_offset; }
|
||||
|
||||
int sender_decode_offset() const { return _sender_decode_offset; }
|
||||
|
||||
// Tells whether sender() returns NULL
|
||||
bool is_top() const;
|
||||
|
||||
private:
|
||||
// Alternative constructor
|
||||
void initialize(const ScopeDesc* parent, int decode_offset);
|
||||
// Alternative constructors
|
||||
ScopeDesc(const ScopeDesc* parent);
|
||||
ScopeDesc(const ScopeDesc* parent, int decode_offset);
|
||||
|
||||
// JVM state
|
||||
Method* _method;
|
||||
|
@ -128,7 +128,8 @@ uintptr_t ZObjectAllocator::alloc_medium_object(size_t size, ZAllocationFlags fl
|
||||
}
|
||||
|
||||
uintptr_t ZObjectAllocator::alloc_small_object_from_nonworker(size_t size, ZAllocationFlags flags) {
|
||||
assert(ZThread::is_java() || ZThread::is_vm(), "Should be a Java or VM thread");
|
||||
assert(ZThread::is_java() || ZThread::is_vm() || ZThread::is_runtime_worker(),
|
||||
"Should be a Java, VM or Runtime worker thread");
|
||||
|
||||
// Non-worker small page allocation can never use the reserve
|
||||
flags.set_no_reserve();
|
||||
@ -193,7 +194,8 @@ uintptr_t ZObjectAllocator::alloc_object(size_t size) {
|
||||
}
|
||||
|
||||
uintptr_t ZObjectAllocator::alloc_object_for_relocation(size_t size) {
|
||||
assert(ZThread::is_java() || ZThread::is_worker() || ZThread::is_vm(), "Unknown thread");
|
||||
assert(ZThread::is_java() || ZThread::is_vm() || ZThread::is_worker() || ZThread::is_runtime_worker(),
|
||||
"Unknown thread");
|
||||
|
||||
ZAllocationFlags flags;
|
||||
flags.set_relocation();
|
||||
|
@ -22,7 +22,43 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "gc/shared/workgroup.hpp"
|
||||
#include "gc/z/zRuntimeWorkers.hpp"
|
||||
#include "gc/z/zThread.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
|
||||
class ZRuntimeWorkersInitializeTask : public AbstractGangTask {
|
||||
private:
|
||||
const uint _nworkers;
|
||||
uint _started;
|
||||
Monitor _monitor;
|
||||
|
||||
public:
|
||||
ZRuntimeWorkersInitializeTask(uint nworkers) :
|
||||
AbstractGangTask("ZRuntimeWorkersInitializeTask"),
|
||||
_nworkers(nworkers),
|
||||
_started(0),
|
||||
_monitor(Monitor::leaf,
|
||||
"ZRuntimeWorkersInitialize",
|
||||
false /* allow_vm_block */,
|
||||
Monitor::_safepoint_check_never) {}
|
||||
|
||||
virtual void work(uint worker_id) {
|
||||
// Register as runtime worker
|
||||
ZThread::set_runtime_worker();
|
||||
|
||||
// Wait for all threads to start
|
||||
MonitorLockerEx ml(&_monitor, Monitor::_no_safepoint_check_flag);
|
||||
if (++_started == _nworkers) {
|
||||
// All threads started
|
||||
ml.notify_all();
|
||||
} else {
|
||||
while (_started != _nworkers) {
|
||||
ml.wait(Monitor::_no_safepoint_check_flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ZRuntimeWorkers::ZRuntimeWorkers() :
|
||||
_workers("RuntimeWorker",
|
||||
@ -35,6 +71,15 @@ ZRuntimeWorkers::ZRuntimeWorkers() :
|
||||
// Initialize worker threads
|
||||
_workers.initialize_workers();
|
||||
_workers.update_active_workers(nworkers());
|
||||
if (_workers.active_workers() != nworkers()) {
|
||||
vm_exit_during_initialization("Failed to create ZRuntimeWorkers");
|
||||
}
|
||||
|
||||
// Execute task to register threads as runtime workers. This also
|
||||
// helps reduce latency in early safepoints, which otherwise would
|
||||
// have to take on any warmup costs.
|
||||
ZRuntimeWorkersInitializeTask task(nworkers());
|
||||
_workers.run_task(&task);
|
||||
}
|
||||
|
||||
uint ZRuntimeWorkers::nworkers() const {
|
||||
|
@ -31,6 +31,7 @@ __thread uintptr_t ZThread::_id;
|
||||
__thread bool ZThread::_is_vm;
|
||||
__thread bool ZThread::_is_java;
|
||||
__thread bool ZThread::_is_worker;
|
||||
__thread bool ZThread::_is_runtime_worker;
|
||||
__thread uint ZThread::_worker_id;
|
||||
|
||||
void ZThread::initialize() {
|
||||
@ -40,7 +41,8 @@ void ZThread::initialize() {
|
||||
_id = (uintptr_t)thread;
|
||||
_is_vm = thread->is_VM_thread();
|
||||
_is_java = thread->is_Java_thread();
|
||||
_is_worker = thread->is_Worker_thread();
|
||||
_is_worker = false;
|
||||
_is_runtime_worker = false;
|
||||
_worker_id = (uint)-1;
|
||||
}
|
||||
|
||||
@ -56,6 +58,16 @@ const char* ZThread::name() {
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
void ZThread::set_worker() {
|
||||
ensure_initialized();
|
||||
_is_worker = true;
|
||||
}
|
||||
|
||||
void ZThread::set_runtime_worker() {
|
||||
ensure_initialized();
|
||||
_is_runtime_worker = true;
|
||||
}
|
||||
|
||||
bool ZThread::has_worker_id() {
|
||||
return _initialized &&
|
||||
_is_worker &&
|
||||
|
@ -29,6 +29,8 @@
|
||||
|
||||
class ZThread : public AllStatic {
|
||||
friend class ZTask;
|
||||
friend class ZWorkersInitializeTask;
|
||||
friend class ZRuntimeWorkersInitializeTask;
|
||||
|
||||
private:
|
||||
static __thread bool _initialized;
|
||||
@ -36,6 +38,7 @@ private:
|
||||
static __thread bool _is_vm;
|
||||
static __thread bool _is_java;
|
||||
static __thread bool _is_worker;
|
||||
static __thread bool _is_runtime_worker;
|
||||
static __thread uint _worker_id;
|
||||
|
||||
static void initialize();
|
||||
@ -46,6 +49,9 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
static void set_worker();
|
||||
static void set_runtime_worker();
|
||||
|
||||
static bool has_worker_id();
|
||||
static void set_worker_id(uint worker_id);
|
||||
static void clear_worker_id();
|
||||
@ -73,6 +79,11 @@ public:
|
||||
return _is_worker;
|
||||
}
|
||||
|
||||
static bool is_runtime_worker() {
|
||||
ensure_initialized();
|
||||
return _is_runtime_worker;
|
||||
}
|
||||
|
||||
static uint worker_id() {
|
||||
assert(has_worker_id(), "Worker id not initialized");
|
||||
return _worker_id;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "gc/z/zGlobals.hpp"
|
||||
#include "gc/z/zTask.hpp"
|
||||
#include "gc/z/zThread.hpp"
|
||||
#include "gc/z/zWorkers.inline.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
@ -64,20 +65,26 @@ uint ZWorkers::calculate_nconcurrent() {
|
||||
return calculate_nworkers(12.5);
|
||||
}
|
||||
|
||||
class ZWorkersWarmupTask : public ZTask {
|
||||
class ZWorkersInitializeTask : public ZTask {
|
||||
private:
|
||||
const uint _nworkers;
|
||||
uint _started;
|
||||
Monitor _monitor;
|
||||
|
||||
public:
|
||||
ZWorkersWarmupTask(uint nworkers) :
|
||||
ZTask("ZWorkersWarmupTask"),
|
||||
ZWorkersInitializeTask(uint nworkers) :
|
||||
ZTask("ZWorkersInitializeTask"),
|
||||
_nworkers(nworkers),
|
||||
_started(0),
|
||||
_monitor(Monitor::leaf, "ZWorkersWarmup", false, Monitor::_safepoint_check_never) {}
|
||||
_monitor(Monitor::leaf,
|
||||
"ZWorkersInitialize",
|
||||
false /* allow_vm_block */,
|
||||
Monitor::_safepoint_check_never) {}
|
||||
|
||||
virtual void work() {
|
||||
// Register as worker
|
||||
ZThread::set_worker();
|
||||
|
||||
// Wait for all threads to start
|
||||
MonitorLockerEx ml(&_monitor, Monitor::_no_safepoint_check_flag);
|
||||
if (++_started == _nworkers) {
|
||||
@ -107,10 +114,10 @@ ZWorkers::ZWorkers() :
|
||||
vm_exit_during_initialization("Failed to create ZWorkers");
|
||||
}
|
||||
|
||||
// Warm up worker threads by having them execute a dummy task.
|
||||
// This helps reduce latency in early GC pauses, which otherwise
|
||||
// would have to take on any warmup costs.
|
||||
ZWorkersWarmupTask task(nworkers());
|
||||
// Execute task to register threads as workers. This also helps
|
||||
// reduce latency in early GC pauses, which otherwise would have
|
||||
// to take on any warmup costs.
|
||||
ZWorkersInitializeTask task(nworkers());
|
||||
run(&task, nworkers());
|
||||
}
|
||||
|
||||
|
@ -625,6 +625,15 @@ JVM_GetMethodParameters(JNIEnv *env, jobject method);
|
||||
JNIEXPORT jobject JNICALL
|
||||
JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls);
|
||||
|
||||
/*
|
||||
* Ensure that code doing a stackwalk and using javaVFrame::locals() to
|
||||
* get the value will see a materialized value and not a scalar-replaced
|
||||
* null value.
|
||||
*/
|
||||
#define JVM_EnsureMaterializedForStackWalk(env, value) \
|
||||
do {} while(0) // Nothing to do. The fact that the value escaped
|
||||
// through a native method is enough.
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls);
|
||||
|
||||
|
@ -3469,8 +3469,7 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f
|
||||
}
|
||||
case Op_CmpUL: {
|
||||
if (!Matcher::has_match_rule(Op_CmpUL)) {
|
||||
// We don't support unsigned long comparisons. Set 'max_idx_expr'
|
||||
// to max_julong if < 0 to make the signed comparison fail.
|
||||
// No support for unsigned long comparisons
|
||||
ConINode* sign_pos = new ConINode(TypeInt::make(BitsPerLong - 1));
|
||||
Node* sign_bit_mask = new RShiftLNode(n->in(1), sign_pos);
|
||||
Node* orl = new OrLNode(n->in(1), sign_bit_mask);
|
||||
|
@ -2289,9 +2289,9 @@ Node* PhaseIdealLoop::add_range_check_predicate(IdealLoopTree* loop, CountedLoop
|
||||
register_new_node(opaque_bol, predicate_proj);
|
||||
IfNode* new_iff = NULL;
|
||||
if (overflow) {
|
||||
new_iff = new IfNode(predicate_proj, bol, PROB_MAX, COUNT_UNKNOWN);
|
||||
new_iff = new IfNode(predicate_proj, opaque_bol, PROB_MAX, COUNT_UNKNOWN);
|
||||
} else {
|
||||
new_iff = new RangeCheckNode(predicate_proj, bol, PROB_MAX, COUNT_UNKNOWN);
|
||||
new_iff = new RangeCheckNode(predicate_proj, opaque_bol, PROB_MAX, COUNT_UNKNOWN);
|
||||
}
|
||||
register_control(new_iff, loop->_parent, predicate_proj);
|
||||
Node* iffalse = new IfFalseNode(new_iff);
|
||||
|
@ -302,7 +302,7 @@ public:
|
||||
void set_slp_max_unroll(int unroll_factor) { _slp_maximum_unroll_factor = unroll_factor; }
|
||||
int slp_max_unroll() const { return _slp_maximum_unroll_factor; }
|
||||
|
||||
virtual LoopNode* skip_strip_mined(int expect_opaq = 1);
|
||||
virtual LoopNode* skip_strip_mined(int expect_skeleton = 1);
|
||||
OuterStripMinedLoopNode* outer_loop() const;
|
||||
virtual IfTrueNode* outer_loop_tail() const;
|
||||
virtual OuterStripMinedLoopEndNode* outer_loop_end() const;
|
||||
|
@ -1367,7 +1367,7 @@ static void kill_dead_code( Node *dead, PhaseIterGVN *igvn ) {
|
||||
igvn->C->remove_range_check_cast(cast);
|
||||
}
|
||||
if (dead->Opcode() == Op_Opaque4) {
|
||||
igvn->C->remove_range_check_cast(dead);
|
||||
igvn->C->remove_opaque4_node(dead);
|
||||
}
|
||||
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
|
||||
bs->unregister_potential_barrier_node(dead);
|
||||
|
@ -823,9 +823,7 @@ JNI_QUICK_ENTRY(jboolean, jni_IsSameObject(JNIEnv *env, jobject r1, jobject r2))
|
||||
|
||||
HOTSPOT_JNI_ISSAMEOBJECT_ENTRY(env, r1, r2);
|
||||
|
||||
oop a = JNIHandles::resolve(r1);
|
||||
oop b = JNIHandles::resolve(r2);
|
||||
jboolean ret = oopDesc::equals(a, b) ? JNI_TRUE : JNI_FALSE;
|
||||
jboolean ret = JNIHandles::is_same_object(r1, r2) ? JNI_TRUE : JNI_FALSE;
|
||||
|
||||
HOTSPOT_JNI_ISSAMEOBJECT_RETURN(ret);
|
||||
return ret;
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/init.hpp"
|
||||
#include "runtime/interfaceSupport.inline.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/java.hpp"
|
||||
#include "runtime/javaCalls.hpp"
|
||||
#include "runtime/jfieldIDWorkaround.hpp"
|
||||
@ -1230,11 +1231,10 @@ JVM_ENTRY(jobject, JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls))
|
||||
oop protection_domain = NULL;
|
||||
|
||||
// Iterate through Java frames
|
||||
RegisterMap reg_map(thread);
|
||||
javaVFrame *vf = thread->last_java_vframe(®_map);
|
||||
for (; vf != NULL; vf = vf->java_sender()) {
|
||||
vframeStream vfst(thread);
|
||||
for(; !vfst.at_end(); vfst.next()) {
|
||||
// get method of frame
|
||||
Method* method = vf->method();
|
||||
Method* method = vfst.method();
|
||||
|
||||
// stop at the first privileged frame
|
||||
if (method->method_holder() == SystemDictionary::AccessController_klass() &&
|
||||
@ -1243,13 +1243,15 @@ JVM_ENTRY(jobject, JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls))
|
||||
// this frame is privileged
|
||||
is_privileged = true;
|
||||
|
||||
javaVFrame *priv = vf; // executePrivileged
|
||||
javaVFrame *caller_fr = priv->java_sender(); // doPrivileged
|
||||
caller_fr = caller_fr->java_sender(); // caller
|
||||
javaVFrame *priv = vfst.asJavaVFrame(); // executePrivileged
|
||||
|
||||
StackValueCollection* locals = priv->locals();
|
||||
privileged_context = locals->obj_at(1);
|
||||
Handle caller = locals->obj_at(2);
|
||||
StackValue* ctx_sv = locals->at(1); // AccessControlContext context
|
||||
StackValue* clr_sv = locals->at(2); // Class<?> caller
|
||||
assert(!ctx_sv->obj_is_scalar_replaced(), "found scalar-replaced object");
|
||||
assert(!clr_sv->obj_is_scalar_replaced(), "found scalar-replaced object");
|
||||
privileged_context = ctx_sv->get_obj();
|
||||
Handle caller = clr_sv->get_obj();
|
||||
|
||||
Klass *caller_klass = java_lang_Class::as_Klass(caller());
|
||||
protection_domain = caller_klass->protection_domain();
|
||||
|
@ -152,17 +152,11 @@ jobject JNIHandles::make_weak_global(Handle obj, AllocFailType alloc_failmode) {
|
||||
oop JNIHandles::resolve_external_guard(jobject handle) {
|
||||
oop result = NULL;
|
||||
if (handle != NULL) {
|
||||
result = resolve_impl<true /* external_guard */ >(handle);
|
||||
result = resolve_impl<0 /* decorators */, true /* external_guard */>(handle);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
oop JNIHandles::resolve_jweak(jweak handle) {
|
||||
assert(handle != NULL, "precondition");
|
||||
assert(is_jweak(handle), "precondition");
|
||||
return NativeAccess<ON_PHANTOM_OOP_REF>::oop_load(jweak_ptr(handle));
|
||||
}
|
||||
|
||||
bool JNIHandles::is_global_weak_cleared(jweak handle) {
|
||||
assert(handle != NULL, "precondition");
|
||||
assert(is_jweak(handle), "not a weak handle");
|
||||
@ -318,7 +312,7 @@ void JNIHandles::print_on(outputStream* st) {
|
||||
class VerifyJNIHandles: public OopClosure {
|
||||
public:
|
||||
virtual void do_oop(oop* root) {
|
||||
guarantee(oopDesc::is_oop(RawAccess<>::oop_load(root)), "Invalid oop");
|
||||
guarantee(oopDesc::is_oop_or_null(RawAccess<>::oop_load(root)), "Invalid oop");
|
||||
}
|
||||
virtual void do_oop(narrowOop* root) { ShouldNotReachHere(); }
|
||||
};
|
||||
|
@ -42,8 +42,10 @@ class JNIHandles : AllStatic {
|
||||
inline static oop* jobject_ptr(jobject handle); // NOT jweak!
|
||||
inline static oop* jweak_ptr(jobject handle);
|
||||
|
||||
template<bool external_guard> inline static oop resolve_impl(jobject handle);
|
||||
static oop resolve_jweak(jweak handle);
|
||||
template <DecoratorSet decorators, bool external_guard> inline static oop resolve_impl(jobject handle);
|
||||
|
||||
// Resolve handle into oop, without keeping the object alive
|
||||
inline static oop resolve_no_keepalive(jobject handle);
|
||||
|
||||
// This method is not inlined in order to avoid circular includes between
|
||||
// this header file and thread.hpp.
|
||||
@ -70,6 +72,9 @@ class JNIHandles : AllStatic {
|
||||
// Resolve externally provided handle into oop with some guards
|
||||
static oop resolve_external_guard(jobject handle);
|
||||
|
||||
// Check for equality without keeping objects alive
|
||||
static bool is_same_object(jobject handle1, jobject handle2);
|
||||
|
||||
// Local handles
|
||||
static jobject make_local(oop obj);
|
||||
static jobject make_local(JNIEnv* env, oop obj); // Fast version when env is known
|
||||
|
@ -49,15 +49,15 @@ inline oop* JNIHandles::jweak_ptr(jobject handle) {
|
||||
}
|
||||
|
||||
// external_guard is true if called from resolve_external_guard.
|
||||
template<bool external_guard>
|
||||
template <DecoratorSet decorators, bool external_guard>
|
||||
inline oop JNIHandles::resolve_impl(jobject handle) {
|
||||
assert(handle != NULL, "precondition");
|
||||
assert(!current_thread_in_native(), "must not be in native");
|
||||
oop result;
|
||||
if (is_jweak(handle)) { // Unlikely
|
||||
result = resolve_jweak(handle);
|
||||
result = NativeAccess<ON_PHANTOM_OOP_REF|decorators>::oop_load(jweak_ptr(handle));
|
||||
} else {
|
||||
result = NativeAccess<>::oop_load(jobject_ptr(handle));
|
||||
result = NativeAccess<decorators>::oop_load(jobject_ptr(handle));
|
||||
// Construction of jobjects canonicalize a null value into a null
|
||||
// jobject, so for non-jweak the pointee should never be null.
|
||||
assert(external_guard || result != NULL, "Invalid JNI handle");
|
||||
@ -68,14 +68,28 @@ inline oop JNIHandles::resolve_impl(jobject handle) {
|
||||
inline oop JNIHandles::resolve(jobject handle) {
|
||||
oop result = NULL;
|
||||
if (handle != NULL) {
|
||||
result = resolve_impl<false /* external_guard */ >(handle);
|
||||
result = resolve_impl<0 /* decorators */, false /* external_guard */>(handle);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline oop JNIHandles::resolve_no_keepalive(jobject handle) {
|
||||
oop result = NULL;
|
||||
if (handle != NULL) {
|
||||
result = resolve_impl<AS_NO_KEEPALIVE, false /* external_guard */>(handle);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline bool JNIHandles::is_same_object(jobject handle1, jobject handle2) {
|
||||
oop obj1 = resolve_no_keepalive(handle1);
|
||||
oop obj2 = resolve_no_keepalive(handle2);
|
||||
return oopDesc::equals(obj1, obj2);
|
||||
}
|
||||
|
||||
inline oop JNIHandles::resolve_non_null(jobject handle) {
|
||||
assert(handle != NULL, "JNI handle should not be null");
|
||||
oop result = resolve_impl<false /* external_guard */ >(handle);
|
||||
oop result = resolve_impl<0 /* decorators */, false /* external_guard */>(handle);
|
||||
assert(result != NULL, "NULL read from jni handle");
|
||||
return result;
|
||||
}
|
||||
|
@ -452,8 +452,10 @@ vframeStream::vframeStream(JavaThread* thread, frame top_frame,
|
||||
_stop_at_java_call_stub = stop_at_java_call_stub;
|
||||
|
||||
// skip top frame, as it may not be at safepoint
|
||||
_prev_frame = top_frame;
|
||||
_frame = top_frame.sender(&_reg_map);
|
||||
while (!fill_from_frame()) {
|
||||
_prev_frame = _frame;
|
||||
_frame = _frame.sender(&_reg_map);
|
||||
}
|
||||
}
|
||||
@ -534,6 +536,37 @@ void vframeStreamCommon::skip_reflection_related_frames() {
|
||||
}
|
||||
}
|
||||
|
||||
javaVFrame* vframeStreamCommon::asJavaVFrame() {
|
||||
javaVFrame* result = NULL;
|
||||
if (_mode == compiled_mode) {
|
||||
guarantee(_frame.is_compiled_frame(), "expected compiled Java frame");
|
||||
|
||||
// lazy update to register map
|
||||
bool update_map = true;
|
||||
RegisterMap map(_thread, update_map);
|
||||
frame f = _prev_frame.sender(&map);
|
||||
|
||||
guarantee(f.is_compiled_frame(), "expected compiled Java frame");
|
||||
|
||||
compiledVFrame* cvf = compiledVFrame::cast(vframe::new_vframe(&f, &map, _thread));
|
||||
|
||||
guarantee(cvf->cb() == cb(), "wrong code blob");
|
||||
|
||||
// get the same scope as this stream
|
||||
cvf = cvf->at_scope(_decode_offset, _vframe_id);
|
||||
|
||||
guarantee(cvf->scope()->decode_offset() == _decode_offset, "wrong scope");
|
||||
guarantee(cvf->scope()->sender_decode_offset() == _sender_decode_offset, "wrong scope");
|
||||
guarantee(cvf->vframe_id() == _vframe_id, "wrong vframe");
|
||||
|
||||
result = cvf;
|
||||
} else {
|
||||
result = javaVFrame::cast(vframe::new_vframe(&_frame, &_reg_map, _thread));
|
||||
}
|
||||
guarantee(result->method() == method(), "wrong method");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#ifndef PRODUCT
|
||||
void vframe::print() {
|
||||
|
@ -278,12 +278,16 @@ class MonitorInfo : public ResourceObj {
|
||||
class vframeStreamCommon : StackObj {
|
||||
protected:
|
||||
// common
|
||||
frame _prev_frame;
|
||||
frame _frame;
|
||||
JavaThread* _thread;
|
||||
RegisterMap _reg_map;
|
||||
enum { interpreted_mode, compiled_mode, at_end_mode } _mode;
|
||||
|
||||
// For compiled_mode
|
||||
int _decode_offset;
|
||||
int _sender_decode_offset;
|
||||
int _vframe_id;
|
||||
|
||||
// Cached information
|
||||
Method* _method;
|
||||
@ -320,6 +324,8 @@ class vframeStreamCommon : StackObj {
|
||||
return (CompiledMethod*) cb();
|
||||
}
|
||||
|
||||
javaVFrame* asJavaVFrame();
|
||||
|
||||
// Frame type
|
||||
inline bool is_interpreted_frame() const;
|
||||
inline bool is_entry_frame() const;
|
||||
|
@ -44,6 +44,7 @@ inline void vframeStreamCommon::next() {
|
||||
|
||||
// handle general case
|
||||
do {
|
||||
_prev_frame = _frame;
|
||||
_frame = _frame.sender(&_reg_map);
|
||||
} while (!fill_from_frame());
|
||||
}
|
||||
@ -59,6 +60,7 @@ inline vframeStream::vframeStream(JavaThread* thread, bool stop_at_java_call_stu
|
||||
|
||||
_frame = _thread->last_frame();
|
||||
while (!fill_from_frame()) {
|
||||
_prev_frame = _frame;
|
||||
_frame = _frame.sender(&_reg_map);
|
||||
}
|
||||
}
|
||||
@ -68,12 +70,14 @@ inline bool vframeStreamCommon::fill_in_compiled_inlined_sender() {
|
||||
return false;
|
||||
}
|
||||
fill_from_compiled_frame(_sender_decode_offset);
|
||||
++_vframe_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) {
|
||||
_mode = compiled_mode;
|
||||
_decode_offset = decode_offset;
|
||||
|
||||
// Range check to detect ridiculous offsets.
|
||||
if (decode_offset == DebugInformationRecorder::serialized_null ||
|
||||
@ -118,6 +122,8 @@ inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) {
|
||||
inline void vframeStreamCommon::fill_from_compiled_native_frame() {
|
||||
_mode = compiled_mode;
|
||||
_sender_decode_offset = DebugInformationRecorder::serialized_null;
|
||||
_decode_offset = DebugInformationRecorder::serialized_null;
|
||||
_vframe_id = 0;
|
||||
_method = nm()->method();
|
||||
_bci = 0;
|
||||
}
|
||||
@ -187,6 +193,7 @@ inline bool vframeStreamCommon::fill_from_frame() {
|
||||
decode_offset = pc_desc->scope_decode_offset();
|
||||
}
|
||||
fill_from_compiled_frame(decode_offset);
|
||||
_vframe_id = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -252,6 +252,14 @@ compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, Java
|
||||
guarantee(_scope != NULL, "scope must be present");
|
||||
}
|
||||
|
||||
compiledVFrame* compiledVFrame::at_scope(int decode_offset, int vframe_id) {
|
||||
if (scope()->decode_offset() != decode_offset) {
|
||||
ScopeDesc* scope = this->scope()->at_offset(decode_offset);
|
||||
return new compiledVFrame(frame_pointer(), register_map(), thread(), scope, vframe_id);
|
||||
}
|
||||
assert(_vframe_id == vframe_id, "wrong frame id");
|
||||
return this;
|
||||
}
|
||||
|
||||
bool compiledVFrame::is_top() const {
|
||||
// FIX IT: Remove this when new native stubs are in place
|
||||
|
@ -72,6 +72,9 @@ class compiledVFrame: public javaVFrame {
|
||||
// Returns the scopeDesc
|
||||
ScopeDesc* scope() const { return _scope; }
|
||||
|
||||
// Return the compiledVFrame for the desired scope
|
||||
compiledVFrame* at_scope(int decode_offset, int vframe_id);
|
||||
|
||||
// Returns SynchronizationEntryBCI or bci() (used for synchronization)
|
||||
int raw_bci() const;
|
||||
|
||||
|
@ -206,7 +206,7 @@ void VMOperationTimeoutTask::task() {
|
||||
if (is_armed()) {
|
||||
jlong delay = (os::javaTimeMillis() - _arm_time);
|
||||
if (delay > AbortVMOnVMOperationTimeoutDelay) {
|
||||
fatal("VM operation took too long: " SIZE_FORMAT " ms (timeout: " SIZE_FORMAT " ms)",
|
||||
fatal("VM operation took too long: " JLONG_FORMAT " ms (timeout: " INTX_FORMAT " ms)",
|
||||
delay, AbortVMOnVMOperationTimeoutDelay);
|
||||
}
|
||||
}
|
||||
|
@ -664,7 +664,7 @@ public final class String
|
||||
* object.
|
||||
*/
|
||||
public int length() {
|
||||
return isLatin1() ? value.length : value.length >> UTF16;
|
||||
return value.length >> coder();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -709,6 +709,13 @@ public final class AccessController {
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value needs to be physically located in the frame, so that it
|
||||
* can be found by a stack walk.
|
||||
*/
|
||||
@Hidden
|
||||
private static native void ensureMaterializedForStackWalk(Object o);
|
||||
|
||||
/**
|
||||
* Sanity check that the caller context is indeed privileged.
|
||||
*
|
||||
@ -734,6 +741,11 @@ public final class AccessController {
|
||||
AccessControlContext context,
|
||||
Class<?> caller)
|
||||
{
|
||||
// Ensure context has a physical value in the frame
|
||||
if (context != null) {
|
||||
ensureMaterializedForStackWalk(context);
|
||||
}
|
||||
|
||||
assert isPrivileged(); // sanity check invariant
|
||||
T result = action.run();
|
||||
assert isPrivileged(); // sanity check invariant
|
||||
@ -742,7 +754,6 @@ public final class AccessController {
|
||||
// retrieved by getStackAccessControlContext().
|
||||
Reference.reachabilityFence(context);
|
||||
Reference.reachabilityFence(caller);
|
||||
Reference.reachabilityFence(action);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -761,6 +772,11 @@ public final class AccessController {
|
||||
Class<?> caller)
|
||||
throws Exception
|
||||
{
|
||||
// Ensure context has a physical value in the frame
|
||||
if (context != null) {
|
||||
ensureMaterializedForStackWalk(context);
|
||||
}
|
||||
|
||||
assert isPrivileged(); // sanity check invariant
|
||||
T result = action.run();
|
||||
assert isPrivileged(); // sanity check invariant
|
||||
@ -769,7 +785,6 @@ public final class AccessController {
|
||||
// retrieved by getStackAccessControlContext().
|
||||
Reference.reachabilityFence(context);
|
||||
Reference.reachabilityFence(caller);
|
||||
Reference.reachabilityFence(action);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -122,11 +122,17 @@ enum Alert {
|
||||
reason = (cause != null) ? cause.getMessage() : "";
|
||||
}
|
||||
|
||||
SSLException ssle = (this == UNEXPECTED_MESSAGE) ?
|
||||
new SSLProtocolException(reason) :
|
||||
(handshakeOnly ?
|
||||
new SSLHandshakeException(reason) :
|
||||
new SSLException(reason));
|
||||
SSLException ssle;
|
||||
if ((cause != null) && (cause instanceof IOException)) {
|
||||
ssle = new SSLException(reason);
|
||||
} else if ((this == UNEXPECTED_MESSAGE)) {
|
||||
ssle = new SSLProtocolException(reason);
|
||||
} else if (handshakeOnly) {
|
||||
ssle = new SSLHandshakeException(reason);
|
||||
} else {
|
||||
ssle = new SSLException(reason);
|
||||
}
|
||||
|
||||
if (cause != null) {
|
||||
ssle.initCause(cause);
|
||||
}
|
||||
@ -187,7 +193,7 @@ enum Alert {
|
||||
// AlertDescription description;
|
||||
// } Alert;
|
||||
if (m.remaining() != 2) {
|
||||
context.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid Alert message: no sufficient data");
|
||||
}
|
||||
|
||||
@ -241,14 +247,14 @@ enum Alert {
|
||||
if (tc.peerUserCanceled) {
|
||||
tc.closeOutbound();
|
||||
} else if (tc.handshakeContext != null) {
|
||||
tc.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw tc.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Received close_notify during handshake");
|
||||
}
|
||||
} else if (alert == Alert.USER_CANCELED) {
|
||||
if (level == Level.WARNING) {
|
||||
tc.peerUserCanceled = true;
|
||||
} else {
|
||||
tc.fatal(alert,
|
||||
throw tc.fatal(alert,
|
||||
"Received fatal close_notify alert", true, null);
|
||||
}
|
||||
} else if ((level == Level.WARNING) && (alert != null)) {
|
||||
@ -263,7 +269,7 @@ enum Alert {
|
||||
alert != Alert.NO_CERTIFICATE ||
|
||||
(tc.sslConfig.clientAuthType !=
|
||||
ClientAuthType.CLIENT_AUTH_REQUESTED)) {
|
||||
tc.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw tc.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"received handshake warning: " + alert.description);
|
||||
} // Otherwise, ignore the warning
|
||||
} // Otherwise, ignore the warning.
|
||||
@ -276,7 +282,7 @@ enum Alert {
|
||||
diagnostic = "Received fatal alert: " + alert.description;
|
||||
}
|
||||
|
||||
tc.fatal(alert, diagnostic, true, null);
|
||||
throw tc.fatal(alert, diagnostic, true, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +174,8 @@ final class AlpnExtension {
|
||||
SSLLogger.severe(
|
||||
"Application protocol name cannot be empty");
|
||||
}
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Application protocol name cannot be empty");
|
||||
}
|
||||
|
||||
@ -189,7 +190,8 @@ final class AlpnExtension {
|
||||
") exceeds the size limit (" +
|
||||
MAX_AP_LENGTH + " bytes)");
|
||||
}
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Application protocol name (" + ap +
|
||||
") exceeds the size limit (" +
|
||||
MAX_AP_LENGTH + " bytes)");
|
||||
@ -204,7 +206,8 @@ final class AlpnExtension {
|
||||
") exceed the size limit (" +
|
||||
MAX_AP_LIST_LENGTH + " bytes)");
|
||||
}
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"The configured application protocols (" +
|
||||
Arrays.toString(laps) +
|
||||
") exceed the size limit (" +
|
||||
@ -283,8 +286,7 @@ final class AlpnExtension {
|
||||
try {
|
||||
spec = new AlpnSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// Update the context.
|
||||
@ -302,7 +304,7 @@ final class AlpnExtension {
|
||||
}
|
||||
|
||||
if (!matched) {
|
||||
shc.conContext.fatal(Alert.NO_APPLICATION_PROTOCOL,
|
||||
throw shc.conContext.fatal(Alert.NO_APPLICATION_PROTOCOL,
|
||||
"No matching application layer protocol values");
|
||||
}
|
||||
} // Otherwise, applicationProtocol will be set by the
|
||||
@ -379,7 +381,8 @@ final class AlpnExtension {
|
||||
if ((shc.applicationProtocol == null) ||
|
||||
(!shc.applicationProtocol.isEmpty() &&
|
||||
!alps.contains(shc.applicationProtocol))) {
|
||||
shc.conContext.fatal(Alert.NO_APPLICATION_PROTOCOL,
|
||||
throw shc.conContext.fatal(
|
||||
Alert.NO_APPLICATION_PROTOCOL,
|
||||
"No matching application layer protocol values");
|
||||
}
|
||||
}
|
||||
@ -391,7 +394,8 @@ final class AlpnExtension {
|
||||
if ((shc.applicationProtocol == null) ||
|
||||
(!shc.applicationProtocol.isEmpty() &&
|
||||
!alps.contains(shc.applicationProtocol))) {
|
||||
shc.conContext.fatal(Alert.NO_APPLICATION_PROTOCOL,
|
||||
throw shc.conContext.fatal(
|
||||
Alert.NO_APPLICATION_PROTOCOL,
|
||||
"No matching application layer protocol values");
|
||||
}
|
||||
}
|
||||
@ -454,7 +458,7 @@ final class AlpnExtension {
|
||||
if (requestedAlps == null ||
|
||||
requestedAlps.applicationProtocols == null ||
|
||||
requestedAlps.applicationProtocols.isEmpty()) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected " + SSLExtension.CH_ALPN.name + " extension");
|
||||
}
|
||||
|
||||
@ -463,13 +467,12 @@ final class AlpnExtension {
|
||||
try {
|
||||
spec = new AlpnSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// Only one application protocol is allowed.
|
||||
if (spec.applicationProtocols.size() != 1) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Invalid " + SSLExtension.CH_ALPN.name + " extension: " +
|
||||
"Only one application protocol name " +
|
||||
"is allowed in ServerHello message");
|
||||
@ -478,7 +481,7 @@ final class AlpnExtension {
|
||||
// The respond application protocol must be one of the requested.
|
||||
if (!requestedAlps.applicationProtocols.containsAll(
|
||||
spec.applicationProtocols)) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Invalid " + SSLExtension.CH_ALPN.name + " extension: " +
|
||||
"Only client specified application protocol " +
|
||||
"is allowed in ServerHello message");
|
||||
|
@ -153,8 +153,7 @@ final class CertSignAlgsExtension {
|
||||
try {
|
||||
spec = new SignatureSchemesSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// Update the context.
|
||||
@ -297,8 +296,7 @@ final class CertSignAlgsExtension {
|
||||
try {
|
||||
spec = new SignatureSchemesSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// Update the context.
|
||||
|
@ -606,8 +606,7 @@ final class CertStatusExtension {
|
||||
try {
|
||||
spec = new CertStatusRequestSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// Update the context.
|
||||
@ -711,13 +710,13 @@ final class CertStatusExtension {
|
||||
CertStatusRequestSpec requestedCsr = (CertStatusRequestSpec)
|
||||
chc.handshakeExtensions.get(CH_STATUS_REQUEST);
|
||||
if (requestedCsr == null) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected status_request extension in ServerHello");
|
||||
}
|
||||
|
||||
// Parse the extension.
|
||||
if (buffer.hasRemaining()) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Invalid status_request extension in ServerHello message: " +
|
||||
"the extension data must be empty");
|
||||
}
|
||||
@ -964,8 +963,7 @@ final class CertStatusExtension {
|
||||
try {
|
||||
spec = new CertStatusRequestV2Spec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// Update the context.
|
||||
@ -1067,13 +1065,13 @@ final class CertStatusExtension {
|
||||
CertStatusRequestV2Spec requestedCsr = (CertStatusRequestV2Spec)
|
||||
chc.handshakeExtensions.get(CH_STATUS_REQUEST_V2);
|
||||
if (requestedCsr == null) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected status_request_v2 extension in ServerHello");
|
||||
}
|
||||
|
||||
// Parse the extension.
|
||||
if (buffer.hasRemaining()) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Invalid status_request_v2 extension in ServerHello: " +
|
||||
"the extension data must be empty");
|
||||
}
|
||||
@ -1157,10 +1155,10 @@ final class CertStatusExtension {
|
||||
respBytes);
|
||||
producedData = certResp.toByteArray();
|
||||
} catch (CertificateException ce) {
|
||||
shc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
throw shc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
"Failed to parse server certificates", ce);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.BAD_CERT_STATUS_RESPONSE,
|
||||
throw shc.conContext.fatal(Alert.BAD_CERT_STATUS_RESPONSE,
|
||||
"Failed to parse certificate status response", ioe);
|
||||
}
|
||||
|
||||
@ -1188,8 +1186,7 @@ final class CertStatusExtension {
|
||||
try {
|
||||
spec = new CertStatusResponseSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.DECODE_ERROR, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw chc.conContext.fatal(Alert.DECODE_ERROR, ioe);
|
||||
}
|
||||
|
||||
if (chc.sslContext.isStaplingEnabled(true)) {
|
||||
|
@ -111,10 +111,10 @@ final class CertificateMessage {
|
||||
encodedCerts.add(cert.getEncoded());
|
||||
} catch (CertificateEncodingException cee) {
|
||||
// unlikely
|
||||
handshakeContext.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw handshakeContext.conContext.fatal(
|
||||
Alert.INTERNAL_ERROR,
|
||||
"Could not encode certificate (" +
|
||||
cert.getSubjectX500Principal() + ")", cee);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,7 +127,8 @@ final class CertificateMessage {
|
||||
|
||||
int listLen = Record.getInt24(m);
|
||||
if (listLen > m.remaining()) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw handshakeContext.conContext.fatal(
|
||||
Alert.ILLEGAL_PARAMETER,
|
||||
"Error parsing certificate message:no sufficient data");
|
||||
}
|
||||
if (listLen > 0) {
|
||||
@ -248,10 +249,8 @@ final class CertificateMessage {
|
||||
}
|
||||
|
||||
if (x509Possession == null) { // unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"No expected X.509 certificate for server authentication");
|
||||
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
|
||||
shc.handshakeSession.setLocalPrivateKey(
|
||||
@ -375,7 +374,7 @@ final class CertificateMessage {
|
||||
if (shc.sslConfig.clientAuthType !=
|
||||
ClientAuthType.CLIENT_AUTH_REQUESTED) {
|
||||
// unexpected or require client authentication
|
||||
shc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
throw shc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
"Empty server certificate chain");
|
||||
} else {
|
||||
return;
|
||||
@ -392,7 +391,7 @@ final class CertificateMessage {
|
||||
new ByteArrayInputStream(encodedCert));
|
||||
}
|
||||
} catch (CertificateException ce) {
|
||||
shc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
throw shc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
"Failed to parse server certificates", ce);
|
||||
}
|
||||
|
||||
@ -410,7 +409,7 @@ final class CertificateMessage {
|
||||
T12CertificateMessage certificateMessage) throws IOException {
|
||||
List<byte[]> encodedCerts = certificateMessage.encodedCertChain;
|
||||
if (encodedCerts == null || encodedCerts.isEmpty()) {
|
||||
chc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
throw chc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
"Empty server certificate chain");
|
||||
}
|
||||
|
||||
@ -424,7 +423,7 @@ final class CertificateMessage {
|
||||
new ByteArrayInputStream(encodedCert));
|
||||
}
|
||||
} catch (CertificateException ce) {
|
||||
chc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
throw chc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
"Failed to parse server certificates", ce);
|
||||
}
|
||||
|
||||
@ -443,7 +442,7 @@ final class CertificateMessage {
|
||||
if ((identityAlg == null || identityAlg.isEmpty()) &&
|
||||
!isIdentityEquivalent(x509Certs[0],
|
||||
chc.reservedServerCerts[0])) {
|
||||
chc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
throw chc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
"server certificate change is restricted " +
|
||||
"during renegotiation");
|
||||
}
|
||||
@ -639,7 +638,7 @@ final class CertificateMessage {
|
||||
// the certificate chain in the TLS session.
|
||||
chc.handshakeSession.setPeerCertificates(certs);
|
||||
} catch (CertificateException ce) {
|
||||
chc.conContext.fatal(getCertificateAlert(chc, ce), ce);
|
||||
throw chc.conContext.fatal(getCertificateAlert(chc, ce), ce);
|
||||
}
|
||||
}
|
||||
|
||||
@ -685,7 +684,7 @@ final class CertificateMessage {
|
||||
"Improper X509TrustManager implementation");
|
||||
}
|
||||
} catch (CertificateException ce) {
|
||||
shc.conContext.fatal(Alert.CERTIFICATE_UNKNOWN, ce);
|
||||
throw shc.conContext.fatal(Alert.CERTIFICATE_UNKNOWN, ce);
|
||||
}
|
||||
}
|
||||
|
||||
@ -942,22 +941,20 @@ final class CertificateMessage {
|
||||
|
||||
SSLPossession pos = choosePossession(shc, clientHello);
|
||||
if (pos == null) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No available authentication scheme");
|
||||
return null; // make the complier happy
|
||||
}
|
||||
|
||||
if (!(pos instanceof X509Possession)) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No X.509 certificate for server authentication");
|
||||
}
|
||||
|
||||
X509Possession x509Possession = (X509Possession)pos;
|
||||
X509Certificate[] localCerts = x509Possession.popCerts;
|
||||
if (localCerts == null || localCerts.length == 0) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No X.509 certificate for server authentication");
|
||||
return null; // make the complier happy
|
||||
}
|
||||
|
||||
// update the context
|
||||
@ -969,9 +966,8 @@ final class CertificateMessage {
|
||||
try {
|
||||
cm = new T13CertificateMessage(shc, (new byte[0]), localCerts);
|
||||
} catch (SSLException | CertificateException ce) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Failed to produce server Certificate message", ce);
|
||||
return null; // make the complier happy
|
||||
}
|
||||
|
||||
// Check the OCSP stapling extensions and attempt
|
||||
@ -1108,9 +1104,8 @@ final class CertificateMessage {
|
||||
cm = new T13CertificateMessage(
|
||||
chc, chc.certRequestContext, localCerts);
|
||||
} catch (SSLException | CertificateException ce) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Failed to produce client Certificate message", ce);
|
||||
return null;
|
||||
}
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine("Produced client Certificate message", cm);
|
||||
@ -1163,7 +1158,7 @@ final class CertificateMessage {
|
||||
if (certificateMessage.certEntries == null ||
|
||||
certificateMessage.certEntries.isEmpty()) {
|
||||
if (shc.sslConfig.clientAuthType == CLIENT_AUTH_REQUIRED) {
|
||||
shc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
throw shc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
"Empty client certificate chain");
|
||||
} else {
|
||||
// optional client authentication
|
||||
@ -1187,7 +1182,7 @@ final class CertificateMessage {
|
||||
T13CertificateMessage certificateMessage )throws IOException {
|
||||
if (certificateMessage.certEntries == null ||
|
||||
certificateMessage.certEntries.isEmpty()) {
|
||||
chc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
throw chc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
"Empty server certificate chain");
|
||||
}
|
||||
|
||||
@ -1224,7 +1219,7 @@ final class CertificateMessage {
|
||||
new ByteArrayInputStream(entry.encoded));
|
||||
}
|
||||
} catch (CertificateException ce) {
|
||||
shc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
throw shc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
"Failed to parse server certificates", ce);
|
||||
}
|
||||
|
||||
@ -1270,7 +1265,7 @@ final class CertificateMessage {
|
||||
// the certificate chain in the TLS session.
|
||||
shc.handshakeSession.setPeerCertificates(certs);
|
||||
} catch (CertificateException ce) {
|
||||
shc.conContext.fatal(Alert.CERTIFICATE_UNKNOWN, ce);
|
||||
throw shc.conContext.fatal(Alert.CERTIFICATE_UNKNOWN, ce);
|
||||
}
|
||||
|
||||
return certs;
|
||||
@ -1289,7 +1284,7 @@ final class CertificateMessage {
|
||||
new ByteArrayInputStream(entry.encoded));
|
||||
}
|
||||
} catch (CertificateException ce) {
|
||||
chc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
throw chc.conContext.fatal(Alert.BAD_CERTIFICATE,
|
||||
"Failed to parse server certificates", ce);
|
||||
}
|
||||
|
||||
@ -1326,7 +1321,7 @@ final class CertificateMessage {
|
||||
// the certificate chain in the TLS session.
|
||||
chc.handshakeSession.setPeerCertificates(certs);
|
||||
} catch (CertificateException ce) {
|
||||
chc.conContext.fatal(getCertificateAlert(chc, ce), ce);
|
||||
throw chc.conContext.fatal(getCertificateAlert(chc, ce), ce);
|
||||
}
|
||||
|
||||
return certs;
|
||||
|
@ -171,14 +171,14 @@ final class CertificateRequest {
|
||||
// DistinguishedName certificate_authorities<0..2^16-1>;
|
||||
// } CertificateRequest;
|
||||
if (m.remaining() < 4) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Incorrect CertificateRequest message: no sufficient data");
|
||||
}
|
||||
this.types = Record.getBytes8(m);
|
||||
|
||||
int listLen = Record.getInt16(m);
|
||||
if (listLen > m.remaining()) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Incorrect CertificateRequest message:no sufficient data");
|
||||
}
|
||||
|
||||
@ -407,7 +407,7 @@ final class CertificateRequest {
|
||||
this.types = ClientCertificateType.CERT_TYPES;
|
||||
|
||||
if (signatureSchemes == null || signatureSchemes.isEmpty()) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"No signature algorithms specified for " +
|
||||
"CertificateRequest hanshake message");
|
||||
}
|
||||
@ -437,7 +437,7 @@ final class CertificateRequest {
|
||||
|
||||
// certificate_authorities
|
||||
if (m.remaining() < 8) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid CertificateRequest handshake message: " +
|
||||
"no sufficient data");
|
||||
}
|
||||
@ -445,14 +445,14 @@ final class CertificateRequest {
|
||||
|
||||
// supported_signature_algorithms
|
||||
if (m.remaining() < 6) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid CertificateRequest handshake message: " +
|
||||
"no sufficient data");
|
||||
}
|
||||
|
||||
byte[] algs = Record.getBytes16(m);
|
||||
if (algs == null || algs.length == 0 || (algs.length & 0x01) != 0) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid CertificateRequest handshake message: " +
|
||||
"incomplete signature algorithms");
|
||||
}
|
||||
@ -466,14 +466,14 @@ final class CertificateRequest {
|
||||
|
||||
// certificate_authorities
|
||||
if (m.remaining() < 2) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid CertificateRequest handshake message: " +
|
||||
"no sufficient data");
|
||||
}
|
||||
|
||||
int listLen = Record.getInt16(m);
|
||||
if (listLen > m.remaining()) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid CertificateRequest message: no sufficient data");
|
||||
}
|
||||
|
||||
@ -597,7 +597,7 @@ final class CertificateRequest {
|
||||
|
||||
if (shc.localSupportedSignAlgs == null ||
|
||||
shc.localSupportedSignAlgs.isEmpty()) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No supported signature algorithm");
|
||||
}
|
||||
|
||||
@ -783,14 +783,14 @@ final class CertificateRequest {
|
||||
// Extension extensions<2..2^16-1>;
|
||||
// } CertificateRequest;
|
||||
if (m.remaining() < 5) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid CertificateRequest handshake message: " +
|
||||
"no sufficient data");
|
||||
}
|
||||
this.requestContext = Record.getBytes8(m);
|
||||
|
||||
if (m.remaining() < 4) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid CertificateRequest handshake message: " +
|
||||
"no sufficient extensions data");
|
||||
}
|
||||
|
@ -154,7 +154,8 @@ final class CertificateStatus {
|
||||
encodedResponses.add(respDER);
|
||||
encodedResponsesLen = 3 + respDER.length;
|
||||
} else {
|
||||
handshakeContext.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw handshakeContext.conContext.fatal(
|
||||
Alert.HANDSHAKE_FAILURE,
|
||||
"Zero-length OCSP Response");
|
||||
}
|
||||
} else if (statusType == CertStatusRequestType.OCSP_MULTI) {
|
||||
@ -172,11 +173,13 @@ final class CertificateStatus {
|
||||
}
|
||||
|
||||
if (respListLen != 0) {
|
||||
handshakeContext.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw handshakeContext.conContext.fatal(
|
||||
Alert.INTERNAL_ERROR,
|
||||
"Bad OCSP response list length");
|
||||
}
|
||||
} else {
|
||||
handshakeContext.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw handshakeContext.conContext.fatal(
|
||||
Alert.HANDSHAKE_FAILURE,
|
||||
"Unsupported StatusResponseType: " + statusType);
|
||||
}
|
||||
messageLength = messageLength();
|
||||
|
@ -83,11 +83,11 @@ final class CertificateVerify {
|
||||
signer.update(hashes);
|
||||
temproary = signer.sign();
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm (" + algorithm +
|
||||
") used in CertificateVerify handshake message", nsae);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Cannot produce CertificateVerify signature", gse);
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ final class CertificateVerify {
|
||||
// };
|
||||
// } Signature;
|
||||
if (m.remaining() < 2) {
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid CertificateVerify message: no sufficient data");
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ final class CertificateVerify {
|
||||
|
||||
if (x509Credentials == null ||
|
||||
x509Credentials.popPublicKey == null) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No X509 credentials negotiated for CertificateVerify");
|
||||
}
|
||||
|
||||
@ -140,15 +140,15 @@ final class CertificateVerify {
|
||||
shc.handshakeSession.getMasterSecret());
|
||||
signer.update(hashes);
|
||||
if (!signer.verify(signature)) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid CertificateVerify message: invalid signature");
|
||||
}
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm (" + algorithm +
|
||||
") used in CertificateVerify handshake message", nsae);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Cannot verify CertificateVerify signature", gse);
|
||||
}
|
||||
}
|
||||
@ -327,11 +327,11 @@ final class CertificateVerify {
|
||||
signer.update(hashes);
|
||||
temproary = signer.sign();
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm (" + algorithm +
|
||||
") used in CertificateVerify handshake message", nsae);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Cannot produce CertificateVerify signature", gse);
|
||||
}
|
||||
|
||||
@ -356,7 +356,7 @@ final class CertificateVerify {
|
||||
// };
|
||||
// } Signature;
|
||||
if (m.remaining() < 2) {
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid CertificateVerify message: no sufficient data");
|
||||
}
|
||||
|
||||
@ -372,7 +372,7 @@ final class CertificateVerify {
|
||||
|
||||
if (x509Credentials == null ||
|
||||
x509Credentials.popPublicKey == null) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No X509 credentials negotiated for CertificateVerify");
|
||||
}
|
||||
|
||||
@ -383,15 +383,15 @@ final class CertificateVerify {
|
||||
byte[] hashes = shc.handshakeHash.digest(algorithm);
|
||||
signer.update(hashes);
|
||||
if (!signer.verify(signature)) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid CertificateVerify message: invalid signature");
|
||||
}
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm (" + algorithm +
|
||||
") used in CertificateVerify handshake message", nsae);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Cannot verify CertificateVerify signature", gse);
|
||||
}
|
||||
}
|
||||
@ -570,7 +570,7 @@ final class CertificateVerify {
|
||||
if (signatureScheme == null) {
|
||||
// Unlikely, the credentials generator should have
|
||||
// selected the preferable signature algorithm properly.
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"No preferred signature algorithm for CertificateVerify");
|
||||
}
|
||||
|
||||
@ -582,12 +582,12 @@ final class CertificateVerify {
|
||||
temproary = signer.sign();
|
||||
} catch (NoSuchAlgorithmException |
|
||||
InvalidAlgorithmParameterException nsae) {
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm (" +
|
||||
signatureScheme.name +
|
||||
") used in CertificateVerify handshake message", nsae);
|
||||
} catch (InvalidKeyException | SignatureException ikse) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Cannot produce CertificateVerify signature", ikse);
|
||||
}
|
||||
|
||||
@ -607,7 +607,7 @@ final class CertificateVerify {
|
||||
// opaque signature<0..2^16-1>;
|
||||
// } DigitallySigned;
|
||||
if (m.remaining() < 4) {
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid CertificateVerify message: no sufficient data");
|
||||
}
|
||||
|
||||
@ -615,13 +615,13 @@ final class CertificateVerify {
|
||||
int ssid = Record.getInt16(m);
|
||||
this.signatureScheme = SignatureScheme.valueOf(ssid);
|
||||
if (signatureScheme == null) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid signature algorithm (" + ssid +
|
||||
") used in CertificateVerify handshake message");
|
||||
}
|
||||
|
||||
if (!shc.localSupportedSignAlgs.contains(signatureScheme)) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Unsupported signature algorithm (" +
|
||||
signatureScheme.name +
|
||||
") used in CertificateVerify handshake message");
|
||||
@ -638,7 +638,7 @@ final class CertificateVerify {
|
||||
|
||||
if (x509Credentials == null ||
|
||||
x509Credentials.popPublicKey == null) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No X509 credentials negotiated for CertificateVerify");
|
||||
}
|
||||
|
||||
@ -649,17 +649,17 @@ final class CertificateVerify {
|
||||
signatureScheme.getSignature(x509Credentials.popPublicKey);
|
||||
signer.update(shc.handshakeHash.archived());
|
||||
if (!signer.verify(signature)) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid CertificateVerify signature");
|
||||
}
|
||||
} catch (NoSuchAlgorithmException |
|
||||
InvalidAlgorithmParameterException nsae) {
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm (" +
|
||||
signatureScheme.name +
|
||||
") used in CertificateVerify handshake message", nsae);
|
||||
} catch (InvalidKeyException | SignatureException ikse) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Cannot verify CertificateVerify signature", ikse);
|
||||
}
|
||||
}
|
||||
@ -871,7 +871,7 @@ final class CertificateVerify {
|
||||
if (signatureScheme == null) {
|
||||
// Unlikely, the credentials generator should have
|
||||
// selected the preferable signature algorithm properly.
|
||||
context.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw context.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"No preferred signature algorithm for CertificateVerify");
|
||||
}
|
||||
|
||||
@ -897,12 +897,12 @@ final class CertificateVerify {
|
||||
temproary = signer.sign();
|
||||
} catch (NoSuchAlgorithmException |
|
||||
InvalidAlgorithmParameterException nsae) {
|
||||
context.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw context.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm (" +
|
||||
signatureScheme.name +
|
||||
") used in CertificateVerify handshake message", nsae);
|
||||
} catch (InvalidKeyException | SignatureException ikse) {
|
||||
context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Cannot produce CertificateVerify signature", ikse);
|
||||
}
|
||||
|
||||
@ -918,7 +918,7 @@ final class CertificateVerify {
|
||||
// opaque signature<0..2^16-1>;
|
||||
// } DigitallySigned;
|
||||
if (m.remaining() < 4) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid CertificateVerify message: no sufficient data");
|
||||
}
|
||||
|
||||
@ -926,13 +926,13 @@ final class CertificateVerify {
|
||||
int ssid = Record.getInt16(m);
|
||||
this.signatureScheme = SignatureScheme.valueOf(ssid);
|
||||
if (signatureScheme == null) {
|
||||
context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid signature algorithm (" + ssid +
|
||||
") used in CertificateVerify handshake message");
|
||||
}
|
||||
|
||||
if (!context.localSupportedSignAlgs.contains(signatureScheme)) {
|
||||
context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Unsupported signature algorithm (" +
|
||||
signatureScheme.name +
|
||||
") used in CertificateVerify handshake message");
|
||||
@ -949,7 +949,7 @@ final class CertificateVerify {
|
||||
|
||||
if (x509Credentials == null ||
|
||||
x509Credentials.popPublicKey == null) {
|
||||
context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No X509 credentials negotiated for CertificateVerify");
|
||||
}
|
||||
|
||||
@ -975,17 +975,17 @@ final class CertificateVerify {
|
||||
signatureScheme.getSignature(x509Credentials.popPublicKey);
|
||||
signer.update(contentCovered);
|
||||
if (!signer.verify(signature)) {
|
||||
context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid CertificateVerify signature");
|
||||
}
|
||||
} catch (NoSuchAlgorithmException |
|
||||
InvalidAlgorithmParameterException nsae) {
|
||||
context.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw context.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm (" +
|
||||
signatureScheme.name +
|
||||
") used in CertificateVerify handshake message", nsae);
|
||||
} catch (InvalidKeyException | SignatureException ikse) {
|
||||
context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Cannot verify CertificateVerify signature", ikse);
|
||||
}
|
||||
}
|
||||
|
@ -105,6 +105,12 @@ final class ChangeCipherSpec {
|
||||
throw new SSLException("Algorithm missing: ", gse);
|
||||
}
|
||||
|
||||
if (writeCipher == null) {
|
||||
throw hc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Illegal cipher suite (" + ncs +
|
||||
") and protocol version (" + hc.negotiatedProtocol + ")");
|
||||
}
|
||||
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine("Produced ChangeCipherSpec message");
|
||||
}
|
||||
@ -136,7 +142,7 @@ final class ChangeCipherSpec {
|
||||
|
||||
// parse
|
||||
if (message.remaining() != 1 || message.get() != 1) {
|
||||
tc.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw tc.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Malformed or unexpected ChangeCipherSpec message");
|
||||
}
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
@ -145,7 +151,7 @@ final class ChangeCipherSpec {
|
||||
|
||||
// validate
|
||||
if (tc.handshakeContext == null) {
|
||||
tc.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw tc.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Unexpected ChangeCipherSpec message");
|
||||
}
|
||||
|
||||
@ -153,7 +159,7 @@ final class ChangeCipherSpec {
|
||||
HandshakeContext hc = tc.handshakeContext;
|
||||
|
||||
if (hc.handshakeKeyDerivation == null) {
|
||||
tc.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw tc.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected ChangeCipherSpec message");
|
||||
}
|
||||
|
||||
@ -195,6 +201,14 @@ final class ChangeCipherSpec {
|
||||
// unlikely
|
||||
throw new SSLException("Algorithm missing: ", gse);
|
||||
}
|
||||
|
||||
if (readCipher == null) {
|
||||
throw hc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Illegal cipher suite (" + hc.negotiatedCipherSuite +
|
||||
") and protocol version (" + hc.negotiatedProtocol +
|
||||
")");
|
||||
}
|
||||
|
||||
tc.inputRecord.changeReadCiphers(readCipher);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Not supported.");
|
||||
@ -225,7 +239,7 @@ final class ChangeCipherSpec {
|
||||
|
||||
// parse
|
||||
if (message.remaining() != 1 || message.get() != 1) {
|
||||
tc.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw tc.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Malformed or unexpected ChangeCipherSpec message");
|
||||
}
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
|
@ -144,8 +144,8 @@ final class ClientHello {
|
||||
if (id == SSLExtension.CH_PRE_SHARED_KEY.id) {
|
||||
// ensure pre_shared_key is the last extension
|
||||
if (remaining > 0) {
|
||||
tc.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"pre_shared_key extension is not last");
|
||||
throw tc.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"pre_shared_key extension is not last");
|
||||
}
|
||||
// read only up to the IDs
|
||||
Record.getBytes16(m);
|
||||
@ -169,7 +169,8 @@ final class ClientHello {
|
||||
try {
|
||||
sessionId.checkLength(clientVersion);
|
||||
} catch (SSLProtocolException ex) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, ex);
|
||||
throw handshakeContext.conContext.fatal(
|
||||
Alert.ILLEGAL_PARAMETER, ex);
|
||||
}
|
||||
if (isDTLS) {
|
||||
this.cookie = Record.getBytes8(m);
|
||||
@ -179,8 +180,9 @@ final class ClientHello {
|
||||
|
||||
byte[] encodedIds = Record.getBytes16(m);
|
||||
if (encodedIds.length == 0 || (encodedIds.length & 0x01) != 0) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid ClientHello message");
|
||||
throw handshakeContext.conContext.fatal(
|
||||
Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid ClientHello message");
|
||||
}
|
||||
|
||||
this.cipherSuiteIds = new int[encodedIds.length >> 1];
|
||||
@ -702,7 +704,8 @@ final class ClientHello {
|
||||
try {
|
||||
chc.kickstart();
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE, ioe);
|
||||
throw chc.conContext.fatal(
|
||||
Alert.HANDSHAKE_FAILURE, ioe);
|
||||
}
|
||||
|
||||
// The handshake message has been delivered.
|
||||
@ -790,7 +793,7 @@ final class ClientHello {
|
||||
// clean up this consumer
|
||||
shc.handshakeConsumers.remove(SSLHandshake.CLIENT_HELLO.id);
|
||||
if (!shc.handshakeConsumers.isEmpty()) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"No more handshake message allowed " +
|
||||
"in a ClientHello flight");
|
||||
}
|
||||
@ -877,7 +880,7 @@ final class ClientHello {
|
||||
context.activeProtocols, chv);
|
||||
if (pv == null || pv == ProtocolVersion.NONE ||
|
||||
pv == ProtocolVersion.SSL20Hello) {
|
||||
context.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
throw context.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
"Client requested protocol " +
|
||||
ProtocolVersion.nameOf(clientHelloVersion) +
|
||||
" is not enabled or supported in server context");
|
||||
@ -910,13 +913,11 @@ final class ClientHello {
|
||||
}
|
||||
|
||||
// No protocol version can be negotiated.
|
||||
context.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
throw context.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
"The client supported protocol versions " + Arrays.toString(
|
||||
ProtocolVersion.toStringArray(clientSupportedVersions)) +
|
||||
" are not accepted by server preferences " +
|
||||
context.activeProtocols);
|
||||
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
}
|
||||
|
||||
@ -957,13 +958,13 @@ final class ClientHello {
|
||||
if (shc.conContext.isNegotiated) {
|
||||
if (!shc.conContext.secureRenegotiation &&
|
||||
!HandshakeContext.allowUnsafeRenegotiation) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Unsafe renegotiation is not allowed");
|
||||
}
|
||||
|
||||
if (ServerHandshakeContext.rejectClientInitiatedRenego &&
|
||||
!shc.kickstartMessageDelivered) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Client initiated renegotiation is not allowed");
|
||||
}
|
||||
}
|
||||
@ -1170,13 +1171,13 @@ final class ClientHello {
|
||||
handshakeProducer.produce(shc, clientHello);
|
||||
} else {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No HelloRetryRequest producer: " + shc.handshakeProducers);
|
||||
}
|
||||
|
||||
if (!shc.handshakeProducers.isEmpty()) {
|
||||
// unlikely, but please double check.
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"unknown handshake producers: " + shc.handshakeProducers);
|
||||
}
|
||||
}
|
||||
@ -1264,13 +1265,13 @@ final class ClientHello {
|
||||
if (shc.conContext.isNegotiated) {
|
||||
if (!shc.conContext.secureRenegotiation &&
|
||||
!HandshakeContext.allowUnsafeRenegotiation) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Unsafe renegotiation is not allowed");
|
||||
}
|
||||
|
||||
if (ServerHandshakeContext.rejectClientInitiatedRenego &&
|
||||
!shc.kickstartMessageDelivered) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Client initiated renegotiation is not allowed");
|
||||
}
|
||||
}
|
||||
|
@ -68,9 +68,8 @@ final class ClientKeyExchange {
|
||||
}
|
||||
|
||||
// not consumer defined.
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected ClientKeyExchange handshake message.");
|
||||
return null; // make the compiler happe
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,7 +104,7 @@ final class ClientKeyExchange {
|
||||
}
|
||||
|
||||
// not consumer defined.
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected ClientKeyExchange handshake message.");
|
||||
}
|
||||
}
|
||||
|
@ -163,8 +163,7 @@ public class CookieExtension {
|
||||
try {
|
||||
spec = new CookieSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
shc.handshakeExtensions.put(SSLExtension.CH_COOKIE, spec);
|
||||
@ -201,9 +200,8 @@ public class CookieExtension {
|
||||
HelloCookieManager hcm =
|
||||
shc.sslContext.getHelloCookieManager(shc.negotiatedProtocol);
|
||||
if (!hcm.isCookieValid(shc, clientHello, spec.cookie)) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"unrecognized cookie");
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -270,8 +268,7 @@ public class CookieExtension {
|
||||
try {
|
||||
spec = new CookieSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
chc.handshakeExtensions.put(SSLExtension.HRR_COOKIE, spec);
|
||||
|
@ -87,7 +87,7 @@ final class DHClientKeyExchange {
|
||||
|
||||
if (dhePossession == null) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No DHE credentials negotiated for client key exchange");
|
||||
}
|
||||
|
||||
@ -104,14 +104,14 @@ final class DHClientKeyExchange {
|
||||
(ServerHandshakeContext)handshakeContext;
|
||||
|
||||
if (m.remaining() < 3) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid DH ClientKeyExchange message: insufficient data");
|
||||
}
|
||||
|
||||
this.y = Record.getBytes16(m);
|
||||
|
||||
if (m.hasRemaining()) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid DH ClientKeyExchange message: unknown extra data");
|
||||
}
|
||||
}
|
||||
@ -177,7 +177,7 @@ final class DHClientKeyExchange {
|
||||
}
|
||||
|
||||
if (dheCredentials == null) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No DHE credentials negotiated for client key exchange");
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ final class DHClientKeyExchange {
|
||||
chc.negotiatedProtocol);
|
||||
if (ke == null) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key exchange type");
|
||||
} else {
|
||||
SSLKeyDerivation masterKD = ke.createKeyDerivation(chc);
|
||||
@ -214,7 +214,7 @@ final class DHClientKeyExchange {
|
||||
SSLTrafficKeyDerivation.valueOf(chc.negotiatedProtocol);
|
||||
if (kd == null) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " +
|
||||
chc.negotiatedProtocol);
|
||||
} else {
|
||||
@ -254,7 +254,7 @@ final class DHClientKeyExchange {
|
||||
|
||||
if (dhePossession == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No expected DHE possessions for client key exchange");
|
||||
}
|
||||
|
||||
@ -263,7 +263,7 @@ final class DHClientKeyExchange {
|
||||
shc.negotiatedProtocol);
|
||||
if (ke == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key exchange type");
|
||||
}
|
||||
|
||||
@ -310,7 +310,7 @@ final class DHClientKeyExchange {
|
||||
SSLTrafficKeyDerivation.valueOf(shc.negotiatedProtocol);
|
||||
if (kd == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " + shc.negotiatedProtocol);
|
||||
} else {
|
||||
shc.handshakeKeyDerivation =
|
||||
|
@ -438,7 +438,7 @@ final class DHKeyExchange {
|
||||
}
|
||||
|
||||
if (dhePossession == null || dheCredentials == null) {
|
||||
context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No sufficient DHE key agreement parameters negotiated");
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ final class DHServerKeyExchange {
|
||||
|
||||
if (dhePossession == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"No DHE credentials negotiated for server key exchange");
|
||||
}
|
||||
DHPublicKey publicKey = dhePossession.publicKey;
|
||||
@ -132,7 +132,7 @@ final class DHServerKeyExchange {
|
||||
if (signatureScheme == null) {
|
||||
// Unlikely, the credentials generator should have
|
||||
// selected the preferable signature algorithm properly.
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"No preferred signature algorithm");
|
||||
}
|
||||
try {
|
||||
@ -140,7 +140,7 @@ final class DHServerKeyExchange {
|
||||
x509Possession.popPrivateKey);
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException |
|
||||
InvalidAlgorithmParameterException nsae) {
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm: " +
|
||||
signatureScheme.name, nsae);
|
||||
}
|
||||
@ -151,7 +151,7 @@ final class DHServerKeyExchange {
|
||||
x509Possession.popPrivateKey.getAlgorithm(),
|
||||
x509Possession.popPrivateKey);
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm: " +
|
||||
x509Possession.popPrivateKey.getAlgorithm(), e);
|
||||
}
|
||||
@ -163,7 +163,7 @@ final class DHServerKeyExchange {
|
||||
shc.serverHelloRandom.randomBytes);
|
||||
signature = signer.sign();
|
||||
} catch (SignatureException ex) {
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Failed to sign dhe parameters: " +
|
||||
x509Possession.popPrivateKey.getAlgorithm(), ex);
|
||||
}
|
||||
@ -189,7 +189,7 @@ final class DHServerKeyExchange {
|
||||
new BigInteger(1, p),
|
||||
new BigInteger(1, p)));
|
||||
} catch (InvalidKeyException ike) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid DH ServerKeyExchange: invalid parameters", ike);
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ final class DHServerKeyExchange {
|
||||
if (x509Credentials == null) {
|
||||
// anonymous, no authentication, no signature
|
||||
if (m.hasRemaining()) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid DH ServerKeyExchange: unknown extra data");
|
||||
}
|
||||
|
||||
@ -221,13 +221,13 @@ final class DHServerKeyExchange {
|
||||
int ssid = Record.getInt16(m);
|
||||
signatureScheme = SignatureScheme.valueOf(ssid);
|
||||
if (signatureScheme == null) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid signature algorithm (" + ssid +
|
||||
") used in DH ServerKeyExchange handshake message");
|
||||
}
|
||||
|
||||
if (!chc.localSupportedSignAlgs.contains(signatureScheme)) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Unsupported signature algorithm (" +
|
||||
signatureScheme.name +
|
||||
") used in DH ServerKeyExchange handshake message");
|
||||
@ -245,11 +245,9 @@ final class DHServerKeyExchange {
|
||||
x509Credentials.popPublicKey);
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException |
|
||||
InvalidAlgorithmParameterException nsae) {
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm: " +
|
||||
signatureScheme.name, nsae);
|
||||
|
||||
return; // make the compiler happe
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
@ -257,11 +255,9 @@ final class DHServerKeyExchange {
|
||||
x509Credentials.popPublicKey.getAlgorithm(),
|
||||
x509Credentials.popPublicKey);
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm: " +
|
||||
x509Credentials.popPublicKey.getAlgorithm(), e);
|
||||
|
||||
return; // make the compiler happe
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,11 +267,11 @@ final class DHServerKeyExchange {
|
||||
chc.serverHelloRandom.randomBytes);
|
||||
|
||||
if (!signer.verify(paramsSignature)) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid signature on DH ServerKeyExchange message");
|
||||
}
|
||||
} catch (SignatureException ex) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Cannot verify DH ServerKeyExchange signature", ex);
|
||||
}
|
||||
}
|
||||
@ -535,15 +531,13 @@ final class DHServerKeyExchange {
|
||||
new BigInteger(1, skem.g));
|
||||
publicKey = (DHPublicKey)kf.generatePublic(spec);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
chc.conContext.fatal(Alert.INSUFFICIENT_SECURITY,
|
||||
throw chc.conContext.fatal(Alert.INSUFFICIENT_SECURITY,
|
||||
"Could not generate DHPublicKey", gse);
|
||||
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
if (!chc.algorithmConstraints.permits(
|
||||
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), publicKey)) {
|
||||
chc.conContext.fatal(Alert.INSUFFICIENT_SECURITY,
|
||||
throw chc.conContext.fatal(Alert.INSUFFICIENT_SECURITY,
|
||||
"DH ServerKeyExchange does not comply to " +
|
||||
"algorithm constraints");
|
||||
}
|
||||
|
@ -190,20 +190,20 @@ final class ECDHClientKeyExchange {
|
||||
}
|
||||
|
||||
if (x509Credentials == null) {
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"No server certificate for ECDH client key exchange");
|
||||
}
|
||||
|
||||
PublicKey publicKey = x509Credentials.popPublicKey;
|
||||
if (!publicKey.getAlgorithm().equals("EC")) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Not EC server certificate for ECDH client key exchange");
|
||||
}
|
||||
|
||||
ECParameterSpec params = ((ECPublicKey)publicKey).getParams();
|
||||
NamedGroup namedGroup = NamedGroup.valueOf(params);
|
||||
if (namedGroup == null) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Unsupported EC server cert for ECDH client key exchange");
|
||||
}
|
||||
|
||||
@ -228,7 +228,7 @@ final class ECDHClientKeyExchange {
|
||||
chc.negotiatedProtocol);
|
||||
if (ke == null) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key exchange type");
|
||||
} else {
|
||||
SSLKeyDerivation masterKD = ke.createKeyDerivation(chc);
|
||||
@ -240,7 +240,7 @@ final class ECDHClientKeyExchange {
|
||||
SSLTrafficKeyDerivation.valueOf(chc.negotiatedProtocol);
|
||||
if (kd == null) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " +
|
||||
chc.negotiatedProtocol);
|
||||
} else {
|
||||
@ -280,15 +280,14 @@ final class ECDHClientKeyExchange {
|
||||
|
||||
if (x509Possession == null) {
|
||||
// unlikely, have been checked during cipher suite negotiation.
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"No expected EC server cert for ECDH client key exchange");
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
PrivateKey privateKey = x509Possession.popPrivateKey;
|
||||
if (!privateKey.getAlgorithm().equals("EC")) {
|
||||
// unlikely, have been checked during cipher suite negotiation.
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Not EC server cert for ECDH client key exchange");
|
||||
}
|
||||
|
||||
@ -296,7 +295,7 @@ final class ECDHClientKeyExchange {
|
||||
NamedGroup namedGroup = NamedGroup.valueOf(params);
|
||||
if (namedGroup == null) {
|
||||
// unlikely, have been checked during cipher suite negotiation.
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Unsupported EC server cert for ECDH client key exchange");
|
||||
}
|
||||
|
||||
@ -305,9 +304,8 @@ final class ECDHClientKeyExchange {
|
||||
shc.negotiatedProtocol);
|
||||
if (ke == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key exchange type");
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
// parse the handshake message
|
||||
@ -353,7 +351,7 @@ final class ECDHClientKeyExchange {
|
||||
SSLTrafficKeyDerivation.valueOf(shc.negotiatedProtocol);
|
||||
if (kd == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " + shc.negotiatedProtocol);
|
||||
} else {
|
||||
shc.handshakeKeyDerivation =
|
||||
@ -387,7 +385,7 @@ final class ECDHClientKeyExchange {
|
||||
}
|
||||
|
||||
if (ecdheCredentials == null) {
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"No ECDHE credentials negotiated for client key exchange");
|
||||
}
|
||||
|
||||
@ -412,7 +410,7 @@ final class ECDHClientKeyExchange {
|
||||
chc.negotiatedProtocol);
|
||||
if (ke == null) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key exchange type");
|
||||
} else {
|
||||
SSLKeyDerivation masterKD = ke.createKeyDerivation(chc);
|
||||
@ -424,7 +422,7 @@ final class ECDHClientKeyExchange {
|
||||
SSLTrafficKeyDerivation.valueOf(chc.negotiatedProtocol);
|
||||
if (kd == null) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " +
|
||||
chc.negotiatedProtocol);
|
||||
} else {
|
||||
@ -463,16 +461,15 @@ final class ECDHClientKeyExchange {
|
||||
}
|
||||
if (ecdhePossession == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"No expected ECDHE possessions for client key exchange");
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
ECParameterSpec params = ecdhePossession.publicKey.getParams();
|
||||
NamedGroup namedGroup = NamedGroup.valueOf(params);
|
||||
if (namedGroup == null) {
|
||||
// unlikely, have been checked during cipher suite negotiation.
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Unsupported EC server cert for ECDHE client key exchange");
|
||||
}
|
||||
|
||||
@ -481,9 +478,8 @@ final class ECDHClientKeyExchange {
|
||||
shc.negotiatedProtocol);
|
||||
if (ke == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key exchange type");
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
// parse the handshake message
|
||||
@ -529,7 +525,7 @@ final class ECDHClientKeyExchange {
|
||||
SSLTrafficKeyDerivation.valueOf(shc.negotiatedProtocol);
|
||||
if (kd == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " + shc.negotiatedProtocol);
|
||||
} else {
|
||||
shc.handshakeKeyDerivation =
|
||||
|
@ -274,7 +274,7 @@ final class ECDHKeyExchange {
|
||||
NamedGroup ng = NamedGroup.valueOf(params);
|
||||
if (ng == null) {
|
||||
// unlikely, have been checked during cipher suite negotiation.
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Unsupported EC server cert for ECDH key exchange");
|
||||
}
|
||||
|
||||
@ -295,7 +295,7 @@ final class ECDHKeyExchange {
|
||||
}
|
||||
|
||||
if (x509Possession == null || ecdheCredentials == null) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No sufficient ECDHE key agreement parameters negotiated");
|
||||
}
|
||||
|
||||
@ -327,7 +327,7 @@ final class ECDHKeyExchange {
|
||||
NamedGroup namedGroup = NamedGroup.valueOf(params);
|
||||
if (namedGroup == null) {
|
||||
// unlikely, should have been checked previously
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Unsupported EC server cert for ECDH key exchange");
|
||||
}
|
||||
|
||||
@ -344,7 +344,7 @@ final class ECDHKeyExchange {
|
||||
}
|
||||
|
||||
if (ecdhePossession == null || x509Credentials == null) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No sufficient ECDH key agreement parameters negotiated");
|
||||
}
|
||||
|
||||
@ -388,7 +388,7 @@ final class ECDHKeyExchange {
|
||||
}
|
||||
|
||||
if (ecdhePossession == null || ecdheCredentials == null) {
|
||||
context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No sufficient ECDHE key agreement parameters negotiated");
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ final class ECDHServerKeyExchange {
|
||||
|
||||
if (ecdhePossession == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"No ECDHE credentials negotiated for server key exchange");
|
||||
}
|
||||
|
||||
@ -125,7 +125,7 @@ final class ECDHServerKeyExchange {
|
||||
this.namedGroup = NamedGroup.valueOf(params);
|
||||
if ((namedGroup == null) || (namedGroup.oid == null) ) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Unnamed EC parameter spec: " + params);
|
||||
}
|
||||
|
||||
@ -146,7 +146,7 @@ final class ECDHServerKeyExchange {
|
||||
if (signatureScheme == null) {
|
||||
// Unlikely, the credentials generator should have
|
||||
// selected the preferable signature algorithm properly.
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"No preferred signature algorithm for " +
|
||||
x509Possession.popPrivateKey.getAlgorithm() +
|
||||
" key");
|
||||
@ -156,7 +156,7 @@ final class ECDHServerKeyExchange {
|
||||
x509Possession.popPrivateKey);
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException |
|
||||
InvalidAlgorithmParameterException nsae) {
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm: " +
|
||||
signatureScheme.name, nsae);
|
||||
}
|
||||
@ -167,7 +167,7 @@ final class ECDHServerKeyExchange {
|
||||
x509Possession.popPrivateKey.getAlgorithm(),
|
||||
x509Possession.popPrivateKey);
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm: " +
|
||||
x509Possession.popPrivateKey.getAlgorithm(), e);
|
||||
}
|
||||
@ -180,7 +180,7 @@ final class ECDHServerKeyExchange {
|
||||
namedGroup.id, publicPoint);
|
||||
signature = signer.sign();
|
||||
} catch (SignatureException ex) {
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Failed to sign ecdhe parameters: " +
|
||||
x509Possession.popPrivateKey.getAlgorithm(), ex);
|
||||
}
|
||||
@ -199,37 +199,37 @@ final class ECDHServerKeyExchange {
|
||||
byte curveType = (byte)Record.getInt8(m);
|
||||
if (curveType != CURVE_NAMED_CURVE) {
|
||||
// Unlikely as only the named curves should be negotiated.
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Unsupported ECCurveType: " + curveType);
|
||||
}
|
||||
|
||||
int namedGroupId = Record.getInt16(m);
|
||||
this.namedGroup = NamedGroup.valueOf(namedGroupId);
|
||||
if (namedGroup == null) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Unknown named group ID: " + namedGroupId);
|
||||
}
|
||||
|
||||
if (!SupportedGroups.isSupported(namedGroup)) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Unsupported named group: " + namedGroup);
|
||||
}
|
||||
|
||||
if (namedGroup.oid == null) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Unknown named EC curve: " + namedGroup);
|
||||
}
|
||||
|
||||
ECParameterSpec parameters =
|
||||
JsseJce.getECParameterSpec(namedGroup.oid);
|
||||
if (parameters == null) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"No supported EC parameter: " + namedGroup);
|
||||
}
|
||||
|
||||
publicPoint = Record.getBytes8(m);
|
||||
if (publicPoint.length == 0) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Insufficient ECPoint data: " + namedGroup);
|
||||
}
|
||||
|
||||
@ -242,7 +242,7 @@ final class ECDHServerKeyExchange {
|
||||
new ECPublicKeySpec(point, parameters));
|
||||
} catch (NoSuchAlgorithmException |
|
||||
InvalidKeySpecException | IOException ex) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid ECPoint: " + namedGroup, ex);
|
||||
}
|
||||
|
||||
@ -259,7 +259,7 @@ final class ECDHServerKeyExchange {
|
||||
if (x509Credentials == null) {
|
||||
// anonymous, no authentication, no signature
|
||||
if (m.hasRemaining()) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid DH ServerKeyExchange: unknown extra data");
|
||||
}
|
||||
this.signatureScheme = null;
|
||||
@ -275,13 +275,13 @@ final class ECDHServerKeyExchange {
|
||||
int ssid = Record.getInt16(m);
|
||||
signatureScheme = SignatureScheme.valueOf(ssid);
|
||||
if (signatureScheme == null) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid signature algorithm (" + ssid +
|
||||
") used in ECDH ServerKeyExchange handshake message");
|
||||
}
|
||||
|
||||
if (!chc.localSupportedSignAlgs.contains(signatureScheme)) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Unsupported signature algorithm (" +
|
||||
signatureScheme.name +
|
||||
") used in ECDH ServerKeyExchange handshake message");
|
||||
@ -299,11 +299,9 @@ final class ECDHServerKeyExchange {
|
||||
x509Credentials.popPublicKey);
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException |
|
||||
InvalidAlgorithmParameterException nsae) {
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm: " +
|
||||
signatureScheme.name, nsae);
|
||||
|
||||
return; // make the compiler happe
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
@ -311,11 +309,9 @@ final class ECDHServerKeyExchange {
|
||||
x509Credentials.popPublicKey.getAlgorithm(),
|
||||
x509Credentials.popPublicKey);
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unsupported signature algorithm: " +
|
||||
x509Credentials.popPublicKey.getAlgorithm(), e);
|
||||
|
||||
return; // make the compiler happe
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,11 +322,11 @@ final class ECDHServerKeyExchange {
|
||||
namedGroup.id, publicPoint);
|
||||
|
||||
if (!signer.verify(paramsSignature)) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid ECDH ServerKeyExchange signature");
|
||||
}
|
||||
} catch (SignatureException ex) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Cannot verify ECDH ServerKeyExchange signature", ex);
|
||||
}
|
||||
}
|
||||
@ -546,7 +542,7 @@ final class ECDHServerKeyExchange {
|
||||
if (!chc.algorithmConstraints.permits(
|
||||
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
|
||||
skem.publicKey)) {
|
||||
chc.conContext.fatal(Alert.INSUFFICIENT_SECURITY,
|
||||
throw chc.conContext.fatal(Alert.INSUFFICIENT_SECURITY,
|
||||
"ECDH ServerKeyExchange does not comply " +
|
||||
"to algorithm constraints");
|
||||
}
|
||||
|
@ -231,13 +231,12 @@ final class ECPointFormatsExtension {
|
||||
try {
|
||||
spec = new ECPointFormatsSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// per RFC 4492, uncompressed points must always be supported.
|
||||
if (!spec.hasUncompressedFormat()) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Invalid ec_point_formats extension data: " +
|
||||
"peer does not support uncompressed points");
|
||||
}
|
||||
@ -272,7 +271,7 @@ final class ECPointFormatsExtension {
|
||||
ECPointFormatsSpec requestedSpec = (ECPointFormatsSpec)
|
||||
chc.handshakeExtensions.get(CH_EC_POINT_FORMATS);
|
||||
if (requestedSpec == null) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected ec_point_formats extension in ServerHello");
|
||||
}
|
||||
|
||||
@ -281,13 +280,12 @@ final class ECPointFormatsExtension {
|
||||
try {
|
||||
spec = new ECPointFormatsSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// per RFC 4492, uncompressed points must always be supported.
|
||||
if (!spec.hasUncompressedFormat()) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Invalid ec_point_formats extension data: " +
|
||||
"peer does not support uncompressed points");
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ final class EncryptedExtensions {
|
||||
// Extension extensions<0..2^16-1>;
|
||||
// } EncryptedExtensions;
|
||||
if (m.remaining() < 2) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid EncryptedExtensions handshake message: " +
|
||||
"no sufficient data");
|
||||
}
|
||||
|
@ -172,8 +172,7 @@ final class ExtendedMasterSecretExtension {
|
||||
try {
|
||||
spec = new ExtendedMasterSecretSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
if (shc.isResumption && shc.resumingSession != null &&
|
||||
@ -232,7 +231,7 @@ final class ExtendedMasterSecretExtension {
|
||||
//
|
||||
// As if extended master extension is required for full
|
||||
// handshake, it MUST be used in abbreviated handshake too.
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Extended Master Secret extension is required");
|
||||
}
|
||||
|
||||
@ -242,7 +241,7 @@ final class ExtendedMasterSecretExtension {
|
||||
// session used the "extended_master_secret" extension
|
||||
// but the new ClientHello does not contain it, the
|
||||
// server MUST abort the abbreviated handshake.
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Missing Extended Master Secret extension " +
|
||||
"on session resumption");
|
||||
} else {
|
||||
@ -250,7 +249,7 @@ final class ExtendedMasterSecretExtension {
|
||||
// original session nor the new ClientHello uses the
|
||||
// extension, the server SHOULD abort the handshake.
|
||||
if (!SSLConfiguration.allowLegacyResumption) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Missing Extended Master Secret extension " +
|
||||
"on session resumption");
|
||||
} else { // Otherwise, continue with a full handshake.
|
||||
@ -318,7 +317,7 @@ final class ExtendedMasterSecretExtension {
|
||||
ExtendedMasterSecretSpec requstedSpec = (ExtendedMasterSecretSpec)
|
||||
chc.handshakeExtensions.get(CH_EXTENDED_MASTER_SECRET);
|
||||
if (requstedSpec == null) {
|
||||
chc.conContext.fatal(Alert.UNSUPPORTED_EXTENSION,
|
||||
throw chc.conContext.fatal(Alert.UNSUPPORTED_EXTENSION,
|
||||
"Server sent the extended_master_secret " +
|
||||
"extension improperly");
|
||||
}
|
||||
@ -328,13 +327,12 @@ final class ExtendedMasterSecretExtension {
|
||||
try {
|
||||
spec = new ExtendedMasterSecretSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
if (chc.isResumption && chc.resumingSession != null &&
|
||||
!chc.resumingSession.useExtendedMasterSecret) {
|
||||
chc.conContext.fatal(Alert.UNSUPPORTED_EXTENSION,
|
||||
throw chc.conContext.fatal(Alert.UNSUPPORTED_EXTENSION,
|
||||
"Server sent an unexpected extended_master_secret " +
|
||||
"extension on session resumption");
|
||||
}
|
||||
@ -364,7 +362,7 @@ final class ExtendedMasterSecretExtension {
|
||||
// For full handshake, if a client receives a ServerHello
|
||||
// without the extension, it SHOULD abort the handshake if
|
||||
// it does not wish to interoperate with legacy servers.
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Extended Master Secret extension is required");
|
||||
}
|
||||
|
||||
@ -374,14 +372,14 @@ final class ExtendedMasterSecretExtension {
|
||||
// the "extended_master_secret" extension but the new
|
||||
// ServerHello does not contain the extension, the client
|
||||
// MUST abort the handshake.
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Missing Extended Master Secret extension " +
|
||||
"on session resumption");
|
||||
} else if (SSLConfiguration.useExtendedMasterSecret &&
|
||||
!SSLConfiguration.allowLegacyResumption &&
|
||||
chc.negotiatedProtocol.useTLS10PlusSpec()) {
|
||||
// Unlikely, abbreviated handshake should be discarded.
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Extended Master Secret extension is required");
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ final class Finished {
|
||||
try {
|
||||
vd = vds.createVerifyData(context, false);
|
||||
} catch (IOException ioe) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Failed to generate verify_data", ioe);
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ final class Finished {
|
||||
}
|
||||
|
||||
if (m.remaining() != verifyDataLen) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Inappropriate finished message: need " + verifyDataLen +
|
||||
" but remaining " + m.remaining() + " bytes verify_data");
|
||||
}
|
||||
@ -116,12 +116,11 @@ final class Finished {
|
||||
try {
|
||||
myVerifyData = vd.createVerifyData(context, true);
|
||||
} catch (IOException ioe) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Failed to generate verify_data", ioe);
|
||||
return; // make the compiler happy
|
||||
}
|
||||
if (!MessageDigest.isEqual(myVerifyData, verifyData)) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"The Finished message cannot be verified.");
|
||||
}
|
||||
}
|
||||
@ -518,7 +517,7 @@ final class Finished {
|
||||
// we have received ChangeCipherSpec
|
||||
if (hc.conContext.consumers.containsKey(
|
||||
ContentType.CHANGE_CIPHER_SPEC.id)) {
|
||||
hc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw hc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Missing ChangeCipherSpec message");
|
||||
}
|
||||
|
||||
@ -679,19 +678,17 @@ final class Finished {
|
||||
SSLKeyDerivation kd = chc.handshakeKeyDerivation;
|
||||
if (kd == null) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"no key derivation");
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
|
||||
SSLTrafficKeyDerivation kdg =
|
||||
SSLTrafficKeyDerivation.valueOf(chc.negotiatedProtocol);
|
||||
if (kdg == null) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " +
|
||||
chc.negotiatedProtocol);
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
|
||||
try {
|
||||
@ -713,22 +710,29 @@ final class Finished {
|
||||
chc.negotiatedProtocol, writeKey, writeIv,
|
||||
chc.sslContext.getSecureRandom());
|
||||
|
||||
if (writeCipher == null) {
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Illegal cipher suite (" + chc.negotiatedCipherSuite +
|
||||
") and protocol version (" + chc.negotiatedProtocol +
|
||||
")");
|
||||
}
|
||||
|
||||
chc.baseWriteSecret = writeSecret;
|
||||
chc.conContext.outputRecord.changeWriteCiphers(
|
||||
writeCipher, false);
|
||||
|
||||
} catch (GeneralSecurityException gse) {
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Failure to derive application secrets", gse);
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
|
||||
// The resumption master secret is stored in the session so
|
||||
// it can be used after the handshake is completed.
|
||||
SSLSecretDerivation sd = ((SSLSecretDerivation) kd).forContext(chc);
|
||||
SecretKey resumptionMasterSecret = sd.deriveKey(
|
||||
"TlsResumptionMasterSecret", null);
|
||||
chc.handshakeSession.setResumptionMasterSecret(resumptionMasterSecret);
|
||||
"TlsResumptionMasterSecret", null);
|
||||
chc.handshakeSession.setResumptionMasterSecret(
|
||||
resumptionMasterSecret);
|
||||
|
||||
chc.conContext.conSession = chc.handshakeSession.finish();
|
||||
chc.conContext.protocolVersion = chc.negotiatedProtocol;
|
||||
@ -762,19 +766,17 @@ final class Finished {
|
||||
SSLKeyDerivation kd = shc.handshakeKeyDerivation;
|
||||
if (kd == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"no key derivation");
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
|
||||
SSLTrafficKeyDerivation kdg =
|
||||
SSLTrafficKeyDerivation.valueOf(shc.negotiatedProtocol);
|
||||
if (kdg == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " +
|
||||
shc.negotiatedProtocol);
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
|
||||
// derive salt secret
|
||||
@ -810,6 +812,13 @@ final class Finished {
|
||||
shc.negotiatedProtocol, writeKey, writeIv,
|
||||
shc.sslContext.getSecureRandom());
|
||||
|
||||
if (writeCipher == null) {
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Illegal cipher suite (" + shc.negotiatedCipherSuite +
|
||||
") and protocol version (" + shc.negotiatedProtocol +
|
||||
")");
|
||||
}
|
||||
|
||||
shc.baseWriteSecret = writeSecret;
|
||||
shc.conContext.outputRecord.changeWriteCiphers(
|
||||
writeCipher, false);
|
||||
@ -817,9 +826,8 @@ final class Finished {
|
||||
// update the context for the following key derivation
|
||||
shc.handshakeKeyDerivation = secretKD;
|
||||
} catch (GeneralSecurityException gse) {
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Failure to derive application secrets", gse);
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
|
||||
/*
|
||||
@ -892,19 +900,17 @@ final class Finished {
|
||||
SSLKeyDerivation kd = chc.handshakeKeyDerivation;
|
||||
if (kd == null) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"no key derivation");
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
SSLTrafficKeyDerivation kdg =
|
||||
SSLTrafficKeyDerivation.valueOf(chc.negotiatedProtocol);
|
||||
if (kdg == null) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " +
|
||||
chc.negotiatedProtocol);
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
// save the session
|
||||
@ -947,15 +953,21 @@ final class Finished {
|
||||
chc.negotiatedProtocol, readKey, readIv,
|
||||
chc.sslContext.getSecureRandom());
|
||||
|
||||
if (readCipher == null) {
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Illegal cipher suite (" + chc.negotiatedCipherSuite +
|
||||
") and protocol version (" + chc.negotiatedProtocol +
|
||||
")");
|
||||
}
|
||||
|
||||
chc.baseReadSecret = readSecret;
|
||||
chc.conContext.inputRecord.changeReadCiphers(readCipher);
|
||||
|
||||
// update the context for the following key derivation
|
||||
chc.handshakeKeyDerivation = secretKD;
|
||||
} catch (GeneralSecurityException gse) {
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Failure to derive application secrets", gse);
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
//
|
||||
@ -1003,19 +1015,17 @@ final class Finished {
|
||||
SSLKeyDerivation kd = shc.handshakeKeyDerivation;
|
||||
if (kd == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"no key derivation");
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
SSLTrafficKeyDerivation kdg =
|
||||
SSLTrafficKeyDerivation.valueOf(shc.negotiatedProtocol);
|
||||
if (kdg == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " +
|
||||
shc.negotiatedProtocol);
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
// save the session
|
||||
@ -1044,20 +1054,28 @@ final class Finished {
|
||||
shc.negotiatedProtocol, readKey, readIv,
|
||||
shc.sslContext.getSecureRandom());
|
||||
|
||||
if (readCipher == null) {
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Illegal cipher suite (" + shc.negotiatedCipherSuite +
|
||||
") and protocol version (" + shc.negotiatedProtocol +
|
||||
")");
|
||||
}
|
||||
|
||||
shc.baseReadSecret = readSecret;
|
||||
shc.conContext.inputRecord.changeReadCiphers(readCipher);
|
||||
|
||||
// The resumption master secret is stored in the session so
|
||||
// it can be used after the handshake is completed.
|
||||
shc.handshakeHash.update();
|
||||
SSLSecretDerivation sd = ((SSLSecretDerivation)kd).forContext(shc);
|
||||
SSLSecretDerivation sd =
|
||||
((SSLSecretDerivation)kd).forContext(shc);
|
||||
SecretKey resumptionMasterSecret = sd.deriveKey(
|
||||
"TlsResumptionMasterSecret", null);
|
||||
shc.handshakeSession.setResumptionMasterSecret(resumptionMasterSecret);
|
||||
shc.handshakeSession.setResumptionMasterSecret(
|
||||
resumptionMasterSecret);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Failure to derive application secrets", gse);
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
// update connection context
|
||||
|
@ -365,26 +365,20 @@ abstract class HandshakeContext implements ConnectionContext {
|
||||
// } Handshake;
|
||||
|
||||
if (plaintext.contentType != ContentType.HANDSHAKE.id) {
|
||||
conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Unexpected operation for record: " + plaintext.contentType);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (plaintext.fragment == null || plaintext.fragment.remaining() < 4) {
|
||||
conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Invalid handshake message: insufficient data");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte handshakeType = (byte)Record.getInt8(plaintext.fragment);
|
||||
int handshakeLen = Record.getInt24(plaintext.fragment);
|
||||
if (handshakeLen != plaintext.fragment.remaining()) {
|
||||
conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Invalid handshake message: insufficient handshake body");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return handshakeType;
|
||||
@ -438,16 +432,15 @@ abstract class HandshakeContext implements ConnectionContext {
|
||||
}
|
||||
|
||||
if (consumer == null) {
|
||||
conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected handshake message: " +
|
||||
SSLHandshake.nameOf(handshakeType));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
consumer.consume(this, fragment);
|
||||
} catch (UnsupportedOperationException unsoe) {
|
||||
conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unsupported handshake message: " +
|
||||
SSLHandshake.nameOf(handshakeType), unsoe);
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ final class HelloRequest {
|
||||
ByteBuffer m) throws IOException {
|
||||
super(handshakeContext);
|
||||
if (m.hasRemaining()) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Error parsing HelloRequest message: not empty");
|
||||
}
|
||||
}
|
||||
@ -185,7 +185,7 @@ final class HelloRequest {
|
||||
if (!chc.kickstartMessageDelivered) {
|
||||
if (!chc.conContext.secureRenegotiation &&
|
||||
!HandshakeContext.allowUnsafeRenegotiation) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Unsafe renegotiation is not allowed");
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ final class HelloVerifyRequest {
|
||||
// opaque cookie<0..2^8-1>;
|
||||
// } HelloVerifyRequest;
|
||||
if (m.remaining() < 3) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid HelloVerifyRequest: no sufficient data");
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ final class HelloVerifyRequest {
|
||||
chc.handshakeConsumers.remove(SSLHandshake.SERVER_HELLO.id);
|
||||
}
|
||||
if (!chc.handshakeConsumers.isEmpty()) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"No more message expected before " +
|
||||
"HelloVerifyRequest is processed");
|
||||
}
|
||||
|
@ -337,8 +337,7 @@ final class KeyShareExtension {
|
||||
try {
|
||||
spec = new CHKeyShareSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
List<SSLCredentials> credentials = new LinkedList<>();
|
||||
@ -610,16 +609,14 @@ final class KeyShareExtension {
|
||||
if (chc.clientRequestedNamedGroups == null ||
|
||||
chc.clientRequestedNamedGroups.isEmpty()) {
|
||||
// No supported groups.
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected key_share extension in ServerHello");
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
}
|
||||
|
||||
// Is it a supported and enabled extension?
|
||||
if (!chc.sslConfig.isAvailable(SSLExtension.SH_KEY_SHARE)) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unsupported key_share extension in ServerHello");
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
}
|
||||
|
||||
// Parse the extension
|
||||
@ -627,25 +624,22 @@ final class KeyShareExtension {
|
||||
try {
|
||||
spec = new SHKeyShareSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
KeyShareEntry keyShare = spec.serverShare;
|
||||
NamedGroup ng = NamedGroup.valueOf(keyShare.namedGroupId);
|
||||
if (ng == null || !SupportedGroups.isActivatable(
|
||||
chc.sslConfig.algorithmConstraints, ng)) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unsupported named group: " +
|
||||
NamedGroup.nameOf(keyShare.namedGroupId));
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
}
|
||||
|
||||
SSLKeyExchange ke = SSLKeyExchange.valueOf(ng);
|
||||
if (ke == null) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"No key exchange for named group " + ng.name);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
}
|
||||
|
||||
SSLCredentials credentials = null;
|
||||
@ -657,7 +651,7 @@ final class KeyShareExtension {
|
||||
if (!chc.algorithmConstraints.permits(
|
||||
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
|
||||
ecdhec.popPublicKey)) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"ECDHE key share entry does not " +
|
||||
"comply to algorithm constraints");
|
||||
} else {
|
||||
@ -665,7 +659,7 @@ final class KeyShareExtension {
|
||||
}
|
||||
}
|
||||
} catch (IOException | GeneralSecurityException ex) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Cannot decode named group: " +
|
||||
NamedGroup.nameOf(keyShare.namedGroupId));
|
||||
}
|
||||
@ -677,7 +671,7 @@ final class KeyShareExtension {
|
||||
if (!chc.algorithmConstraints.permits(
|
||||
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
|
||||
dhec.popPublicKey)) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"DHE key share entry does not " +
|
||||
"comply to algorithm constraints");
|
||||
} else {
|
||||
@ -685,18 +679,18 @@ final class KeyShareExtension {
|
||||
}
|
||||
}
|
||||
} catch (IOException | GeneralSecurityException ex) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Cannot decode named group: " +
|
||||
NamedGroup.nameOf(keyShare.namedGroupId));
|
||||
}
|
||||
} else {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unsupported named group: " +
|
||||
NamedGroup.nameOf(keyShare.namedGroupId));
|
||||
}
|
||||
|
||||
if (credentials == null) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unsupported named group: " + ng.name);
|
||||
}
|
||||
|
||||
@ -794,17 +788,15 @@ final class KeyShareExtension {
|
||||
|
||||
// Is it a supported and enabled extension?
|
||||
if (!shc.sslConfig.isAvailable(SSLExtension.HRR_KEY_SHARE)) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unsupported key_share extension in HelloRetryRequest");
|
||||
return null; // make the compiler happy.
|
||||
}
|
||||
|
||||
if (shc.clientRequestedNamedGroups == null ||
|
||||
shc.clientRequestedNamedGroups.isEmpty()) {
|
||||
// No supported groups.
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected key_share extension in HelloRetryRequest");
|
||||
return null; // make the compiler happy.
|
||||
}
|
||||
|
||||
NamedGroup selectedGroup = null;
|
||||
@ -823,9 +815,8 @@ final class KeyShareExtension {
|
||||
}
|
||||
|
||||
if (selectedGroup == null) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
new IOException("No common named group"));
|
||||
return null; // make the complier happy
|
||||
throw shc.conContext.fatal(
|
||||
Alert.UNEXPECTED_MESSAGE, "No common named group");
|
||||
}
|
||||
|
||||
byte[] extdata = new byte[] {
|
||||
@ -861,9 +852,8 @@ final class KeyShareExtension {
|
||||
|
||||
// Is it a supported and enabled extension?
|
||||
if (!shc.sslConfig.isAvailable(SSLExtension.HRR_KEY_SHARE)) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unsupported key_share extension in HelloRetryRequest");
|
||||
return null; // make the compiler happy.
|
||||
}
|
||||
|
||||
CHKeyShareSpec spec = (CHKeyShareSpec)shc.handshakeExtensions.get(
|
||||
@ -903,17 +893,15 @@ final class KeyShareExtension {
|
||||
|
||||
// Is it a supported and enabled extension?
|
||||
if (!chc.sslConfig.isAvailable(SSLExtension.HRR_KEY_SHARE)) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unsupported key_share extension in HelloRetryRequest");
|
||||
return; // make the compiler happy.
|
||||
}
|
||||
|
||||
if (chc.clientRequestedNamedGroups == null ||
|
||||
chc.clientRequestedNamedGroups.isEmpty()) {
|
||||
// No supported groups.
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected key_share extension in HelloRetryRequest");
|
||||
return; // make the compiler happy.
|
||||
}
|
||||
|
||||
// Parse the extension
|
||||
@ -921,23 +909,20 @@ final class KeyShareExtension {
|
||||
try {
|
||||
spec = new HRRKeyShareSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
NamedGroup serverGroup = NamedGroup.valueOf(spec.selectedGroup);
|
||||
if (serverGroup == null) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unsupported HelloRetryRequest selected group: " +
|
||||
NamedGroup.nameOf(spec.selectedGroup));
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
}
|
||||
|
||||
if (!chc.clientRequestedNamedGroups.contains(serverGroup)) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected HelloRetryRequest selected group: " +
|
||||
serverGroup.name);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
}
|
||||
|
||||
// update the context
|
||||
|
@ -78,7 +78,7 @@ final class KeyUpdate {
|
||||
super(context);
|
||||
|
||||
if (m.remaining() != 1) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"KeyUpdate has an unexpected length of "+
|
||||
m.remaining());
|
||||
}
|
||||
@ -86,7 +86,7 @@ final class KeyUpdate {
|
||||
byte request = m.get();
|
||||
this.status = KeyUpdateRequest.valueOf(request);
|
||||
if (status == null) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid KeyUpdate message value: " +
|
||||
KeyUpdateRequest.nameOf(request));
|
||||
}
|
||||
@ -198,18 +198,17 @@ final class KeyUpdate {
|
||||
SSLTrafficKeyDerivation.valueOf(hc.conContext.protocolVersion);
|
||||
if (kdg == null) {
|
||||
// unlikely
|
||||
hc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw hc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " +
|
||||
hc.conContext.protocolVersion);
|
||||
return;
|
||||
}
|
||||
|
||||
SSLKeyDerivation skd = kdg.createKeyDerivation(hc,
|
||||
hc.conContext.inputRecord.readCipher.baseSecret);
|
||||
if (skd == null) {
|
||||
// unlikely
|
||||
hc.conContext.fatal(Alert.INTERNAL_ERROR, "no key derivation");
|
||||
return;
|
||||
throw hc.conContext.fatal(
|
||||
Alert.INTERNAL_ERROR, "no key derivation");
|
||||
}
|
||||
|
||||
SecretKey nplus1 = skd.deriveKey("TlsUpdateNplus1", null);
|
||||
@ -223,15 +222,22 @@ final class KeyUpdate {
|
||||
Authenticator.valueOf(hc.conContext.protocolVersion),
|
||||
hc.conContext.protocolVersion, key, ivSpec,
|
||||
hc.sslContext.getSecureRandom());
|
||||
|
||||
if (rc == null) {
|
||||
throw hc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Illegal cipher suite (" + hc.negotiatedCipherSuite +
|
||||
") and protocol version (" + hc.negotiatedProtocol +
|
||||
")");
|
||||
}
|
||||
|
||||
rc.baseSecret = nplus1;
|
||||
hc.conContext.inputRecord.changeReadCiphers(rc);
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
|
||||
SSLLogger.fine("KeyUpdate: read key updated");
|
||||
}
|
||||
} catch (GeneralSecurityException gse) {
|
||||
hc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw hc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Failure to derive read secrets", gse);
|
||||
return;
|
||||
}
|
||||
|
||||
if (km.status == KeyUpdateRequest.REQUESTED) {
|
||||
@ -271,18 +277,17 @@ final class KeyUpdate {
|
||||
SSLTrafficKeyDerivation.valueOf(hc.conContext.protocolVersion);
|
||||
if (kdg == null) {
|
||||
// unlikely
|
||||
hc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw hc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " +
|
||||
hc.conContext.protocolVersion);
|
||||
return null;
|
||||
}
|
||||
|
||||
SSLKeyDerivation skd = kdg.createKeyDerivation(hc,
|
||||
hc.conContext.outputRecord.writeCipher.baseSecret);
|
||||
if (skd == null) {
|
||||
// unlikely
|
||||
hc.conContext.fatal(Alert.INTERNAL_ERROR, "no key derivation");
|
||||
return null;
|
||||
throw hc.conContext.fatal(
|
||||
Alert.INTERNAL_ERROR, "no key derivation");
|
||||
}
|
||||
|
||||
SecretKey nplus1 = skd.deriveKey("TlsUpdateNplus1", null);
|
||||
@ -298,9 +303,14 @@ final class KeyUpdate {
|
||||
hc.conContext.protocolVersion, key, ivSpec,
|
||||
hc.sslContext.getSecureRandom());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
hc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw hc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Failure to derive write secrets", gse);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (wc == null) {
|
||||
throw hc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Illegal cipher suite (" + hc.negotiatedCipherSuite +
|
||||
") and protocol version (" + hc.negotiatedProtocol + ")");
|
||||
}
|
||||
|
||||
// Output the handshake message and change the write cipher.
|
||||
|
@ -253,13 +253,12 @@ final class MaxFragExtension {
|
||||
try {
|
||||
spec = new MaxFragLenSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
MaxFragLenEnum mfle = MaxFragLenEnum.valueOf(spec.id);
|
||||
if (mfle == null) {
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"the requested maximum fragment length is other " +
|
||||
"than the allowed values");
|
||||
}
|
||||
@ -359,7 +358,7 @@ final class MaxFragExtension {
|
||||
MaxFragLenSpec requestedSpec = (MaxFragLenSpec)
|
||||
chc.handshakeExtensions.get(CH_MAX_FRAGMENT_LENGTH);
|
||||
if (requestedSpec == null) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected max_fragment_length extension in ServerHello");
|
||||
}
|
||||
|
||||
@ -368,18 +367,17 @@ final class MaxFragExtension {
|
||||
try {
|
||||
spec = new MaxFragLenSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
if (spec.id != requestedSpec.id) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"The maximum fragment length response is not requested");
|
||||
}
|
||||
|
||||
MaxFragLenEnum mfle = MaxFragLenEnum.valueOf(spec.id);
|
||||
if (mfle == null) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"the requested maximum fragment length is other " +
|
||||
"than the allowed values");
|
||||
}
|
||||
@ -532,7 +530,7 @@ final class MaxFragExtension {
|
||||
MaxFragLenSpec requestedSpec = (MaxFragLenSpec)
|
||||
chc.handshakeExtensions.get(CH_MAX_FRAGMENT_LENGTH);
|
||||
if (requestedSpec == null) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected max_fragment_length extension in ServerHello");
|
||||
}
|
||||
|
||||
@ -541,18 +539,17 @@ final class MaxFragExtension {
|
||||
try {
|
||||
spec = new MaxFragLenSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
if (spec.id != requestedSpec.id) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"The maximum fragment length response is not requested");
|
||||
}
|
||||
|
||||
MaxFragLenEnum mfle = MaxFragLenEnum.valueOf(spec.id);
|
||||
if (mfle == null) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"the requested maximum fragment length is other " +
|
||||
"than the allowed values");
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ final class NewSessionTicket {
|
||||
// Extension extensions<0..2^16-2>;
|
||||
// } NewSessionTicket;
|
||||
if (m.remaining() < 14) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid NewSessionTicket message: no sufficient data");
|
||||
}
|
||||
|
||||
@ -95,18 +95,18 @@ final class NewSessionTicket {
|
||||
this.ticketNonce = Record.getBytes8(m);
|
||||
|
||||
if (m.remaining() < 5) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid NewSessionTicket message: no sufficient data");
|
||||
}
|
||||
|
||||
this.ticket = Record.getBytes16(m);
|
||||
if (ticket.length == 0) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"No ticket in the NewSessionTicket handshake message");
|
||||
}
|
||||
|
||||
if (m.remaining() < 2) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid NewSessionTicket message: no sufficient data");
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ final class PostHandshakeContext extends HandshakeContext {
|
||||
super(context);
|
||||
|
||||
if (!negotiatedProtocol.useTLS13PlusSpec()) {
|
||||
conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Post-handshake not supported in " + negotiatedProtocol.name);
|
||||
}
|
||||
|
||||
@ -63,16 +63,15 @@ final class PostHandshakeContext extends HandshakeContext {
|
||||
void dispatch(byte handshakeType, ByteBuffer fragment) throws IOException {
|
||||
SSLConsumer consumer = handshakeConsumers.get(handshakeType);
|
||||
if (consumer == null) {
|
||||
conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected post-handshake message: " +
|
||||
SSLHandshake.nameOf(handshakeType));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
consumer.consume(this, fragment);
|
||||
} catch (UnsupportedOperationException unsoe) {
|
||||
conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unsupported post-handshake message: " +
|
||||
SSLHandshake.nameOf(handshakeType), unsoe);
|
||||
}
|
||||
|
@ -111,14 +111,14 @@ final class PreSharedKeyExtension {
|
||||
// PskBinderEntry binders<33..2^16-1>;
|
||||
// } OfferedPsks;
|
||||
if (m.remaining() < 44) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient data (length=" + m.remaining() + ")");
|
||||
}
|
||||
|
||||
int idEncodedLength = Record.getInt16(m);
|
||||
if (idEncodedLength < 7) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient identities (length=" + idEncodedLength + ")");
|
||||
}
|
||||
@ -128,7 +128,7 @@ final class PreSharedKeyExtension {
|
||||
while (idReadLength < idEncodedLength) {
|
||||
byte[] id = Record.getBytes16(m);
|
||||
if (id.length < 1) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient identity (length=" + id.length + ")");
|
||||
}
|
||||
@ -140,7 +140,7 @@ final class PreSharedKeyExtension {
|
||||
}
|
||||
|
||||
if (m.remaining() < 35) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient binders data (length=" +
|
||||
m.remaining() + ")");
|
||||
@ -148,7 +148,7 @@ final class PreSharedKeyExtension {
|
||||
|
||||
int bindersEncodedLen = Record.getInt16(m);
|
||||
if (bindersEncodedLen < 33) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient binders (length=" +
|
||||
bindersEncodedLen + ")");
|
||||
@ -159,7 +159,7 @@ final class PreSharedKeyExtension {
|
||||
while (bindersReadLength < bindersEncodedLen) {
|
||||
byte[] binder = Record.getBytes8(m);
|
||||
if (binder.length < 32) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient binder entry (length=" +
|
||||
binder.length + ")");
|
||||
@ -171,7 +171,7 @@ final class PreSharedKeyExtension {
|
||||
|
||||
int getIdsEncodedLength() {
|
||||
int idEncodedLength = 0;
|
||||
for(PskIdentity curId : identities) {
|
||||
for (PskIdentity curId : identities) {
|
||||
idEncodedLength += curId.getEncodedLength();
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ final class PreSharedKeyExtension {
|
||||
byte[] buffer = new byte[encodedLength];
|
||||
ByteBuffer m = ByteBuffer.wrap(buffer);
|
||||
Record.putInt16(m, idsEncodedLength);
|
||||
for(PskIdentity curId : identities) {
|
||||
for (PskIdentity curId : identities) {
|
||||
curId.writeEncoded(m);
|
||||
}
|
||||
Record.putInt16(m, bindersEncodedLength);
|
||||
@ -271,7 +271,7 @@ final class PreSharedKeyExtension {
|
||||
SHPreSharedKeySpec(HandshakeContext context,
|
||||
ByteBuffer m) throws IOException {
|
||||
if (m.remaining() < 2) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient selected_identity (length=" +
|
||||
m.remaining() + ")");
|
||||
@ -348,21 +348,20 @@ final class PreSharedKeyExtension {
|
||||
try {
|
||||
pskSpec = new CHPreSharedKeySpec(shc, buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// The "psk_key_exchange_modes" extension should have been loaded.
|
||||
if (!shc.handshakeExtensions.containsKey(
|
||||
SSLExtension.PSK_KEY_EXCHANGE_MODES)) {
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Client sent PSK but not PSK modes, or the PSK " +
|
||||
"extension is not the last extension");
|
||||
}
|
||||
|
||||
// error if id and binder lists are not the same length
|
||||
if (pskSpec.identities.size() != pskSpec.binders.size()) {
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"PSK extension has incorrect number of binders");
|
||||
}
|
||||
|
||||
@ -506,7 +505,7 @@ final class PreSharedKeyExtension {
|
||||
SHPreSharedKeySpec shPsk = (SHPreSharedKeySpec)
|
||||
shc.handshakeExtensions.get(SSLExtension.SH_PRE_SHARED_KEY);
|
||||
if (chPsk == null || shPsk == null) {
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Required extensions are unavailable");
|
||||
}
|
||||
|
||||
@ -533,17 +532,17 @@ final class PreSharedKeyExtension {
|
||||
HandshakeHash pskBinderHash, byte[] binder) throws IOException {
|
||||
Optional<SecretKey> pskOpt = session.getPreSharedKey();
|
||||
if (!pskOpt.isPresent()) {
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Session has no PSK");
|
||||
}
|
||||
SecretKey psk = pskOpt.get();
|
||||
|
||||
SecretKey binderKey = deriveBinderKey(psk, session);
|
||||
SecretKey binderKey = deriveBinderKey(shc, psk, session);
|
||||
byte[] computedBinder =
|
||||
computeBinder(binderKey, session, pskBinderHash);
|
||||
computeBinder(shc, binderKey, session, pskBinderHash);
|
||||
if (!Arrays.equals(binder, computedBinder)) {
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Incorect PSK binder value");
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Incorect PSK binder value");
|
||||
}
|
||||
}
|
||||
|
||||
@ -687,13 +686,14 @@ final class PreSharedKeyExtension {
|
||||
ageMillis + chc.resumingSession.getTicketAgeAdd();
|
||||
identities.add(new PskIdentity(chc.pskIdentity, obfuscatedAge));
|
||||
|
||||
SecretKey binderKey = deriveBinderKey(psk, chc.resumingSession);
|
||||
SecretKey binderKey =
|
||||
deriveBinderKey(chc, psk, chc.resumingSession);
|
||||
ClientHelloMessage clientHello = (ClientHelloMessage)message;
|
||||
CHPreSharedKeySpec pskPrototype = createPskPrototype(
|
||||
chc.resumingSession.getSuite().hashAlg.hashLength, identities);
|
||||
HandshakeHash pskBinderHash = chc.handshakeHash.copy();
|
||||
|
||||
byte[] binder = computeBinder(binderKey, pskBinderHash,
|
||||
byte[] binder = computeBinder(chc, binderKey, pskBinderHash,
|
||||
chc.resumingSession, chc, clientHello, pskPrototype);
|
||||
|
||||
List<byte[]> binders = new ArrayList<>();
|
||||
@ -717,7 +717,8 @@ final class PreSharedKeyExtension {
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] computeBinder(SecretKey binderKey,
|
||||
private static byte[] computeBinder(
|
||||
HandshakeContext context, SecretKey binderKey,
|
||||
SSLSessionImpl session,
|
||||
HandshakeHash pskBinderHash) throws IOException {
|
||||
|
||||
@ -726,10 +727,11 @@ final class PreSharedKeyExtension {
|
||||
pskBinderHash.update();
|
||||
byte[] digest = pskBinderHash.digest();
|
||||
|
||||
return computeBinder(binderKey, session, digest);
|
||||
return computeBinder(context, binderKey, session, digest);
|
||||
}
|
||||
|
||||
private static byte[] computeBinder(SecretKey binderKey,
|
||||
private static byte[] computeBinder(
|
||||
HandshakeContext context, SecretKey binderKey,
|
||||
HandshakeHash hash, SSLSessionImpl session,
|
||||
HandshakeContext ctx, ClientHello.ClientHelloMessage hello,
|
||||
CHPreSharedKeySpec pskPrototype) throws IOException {
|
||||
@ -745,10 +747,11 @@ final class PreSharedKeyExtension {
|
||||
hash.update();
|
||||
byte[] digest = hash.digest();
|
||||
|
||||
return computeBinder(binderKey, session, digest);
|
||||
return computeBinder(context, binderKey, session, digest);
|
||||
}
|
||||
|
||||
private static byte[] computeBinder(SecretKey binderKey,
|
||||
private static byte[] computeBinder(HandshakeContext context,
|
||||
SecretKey binderKey,
|
||||
SSLSessionImpl session, byte[] digest) throws IOException {
|
||||
try {
|
||||
CipherSuite.HashAlg hashAlg = session.getSuite().hashAlg;
|
||||
@ -766,15 +769,15 @@ final class PreSharedKeyExtension {
|
||||
hmac.init(finishedKey);
|
||||
return hmac.doFinal(digest);
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException ex) {
|
||||
throw new IOException(ex);
|
||||
throw context.conContext.fatal(Alert.INTERNAL_ERROR, ex);
|
||||
}
|
||||
} catch (GeneralSecurityException ex) {
|
||||
throw new IOException(ex);
|
||||
throw context.conContext.fatal(Alert.INTERNAL_ERROR, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static SecretKey deriveBinderKey(SecretKey psk,
|
||||
SSLSessionImpl session) throws IOException {
|
||||
private static SecretKey deriveBinderKey(HandshakeContext context,
|
||||
SecretKey psk, SSLSessionImpl session) throws IOException {
|
||||
try {
|
||||
CipherSuite.HashAlg hashAlg = session.getSuite().hashAlg;
|
||||
HKDF hkdf = new HKDF(hashAlg.name);
|
||||
@ -788,7 +791,7 @@ final class PreSharedKeyExtension {
|
||||
return hkdf.expand(earlySecret,
|
||||
hkdfInfo, hashAlg.hashLength, "TlsBinderKey");
|
||||
} catch (GeneralSecurityException ex) {
|
||||
throw new IOException(ex);
|
||||
throw context.conContext.fatal(Alert.INTERNAL_ERROR, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -827,7 +830,7 @@ final class PreSharedKeyExtension {
|
||||
// Is it a response of the specific request?
|
||||
if (!chc.handshakeExtensions.containsKey(
|
||||
SSLExtension.CH_PRE_SHARED_KEY)) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Server sent unexpected pre_shared_key extension");
|
||||
}
|
||||
|
||||
@ -838,13 +841,13 @@ final class PreSharedKeyExtension {
|
||||
}
|
||||
|
||||
if (shPsk.selectedIdentity != 0) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Selected identity index is not in correct range.");
|
||||
}
|
||||
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine(
|
||||
"Resuming session: ", chc.resumingSession);
|
||||
"Resuming session: ", chc.resumingSession);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -201,8 +201,7 @@ final class PskKeyExchangeModesExtension {
|
||||
try {
|
||||
spec = new PskKeyExchangeModesSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// Update the context.
|
||||
@ -324,7 +323,7 @@ final class PskKeyExchangeModesExtension {
|
||||
SSLExtensionSpec spec =
|
||||
shc.handshakeExtensions.get(SSLExtension.CH_PRE_SHARED_KEY);
|
||||
if (spec != null) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"pre_shared_key key extension is offered " +
|
||||
"without a psk_key_exchange_modes extension");
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ final class RSAClientKeyExchange {
|
||||
super(context);
|
||||
|
||||
if (m.remaining() < 2) {
|
||||
context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid RSA ClientKeyExchange message: insufficient data");
|
||||
}
|
||||
|
||||
@ -167,14 +167,14 @@ final class RSAClientKeyExchange {
|
||||
}
|
||||
|
||||
if (rsaCredentials == null && x509Credentials == null) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"No RSA credentials negotiated for client key exchange");
|
||||
}
|
||||
|
||||
PublicKey publicKey = (rsaCredentials != null) ?
|
||||
rsaCredentials.popPublicKey : x509Credentials.popPublicKey;
|
||||
if (!publicKey.getAlgorithm().equals("RSA")) { // unlikely
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Not RSA public key for client key exchange");
|
||||
}
|
||||
|
||||
@ -186,10 +186,8 @@ final class RSAClientKeyExchange {
|
||||
ckem = new RSAClientKeyExchangeMessage(
|
||||
chc, premaster, publicKey);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Cannot generate RSA premaster secret", gse);
|
||||
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine(
|
||||
@ -205,7 +203,7 @@ final class RSAClientKeyExchange {
|
||||
chc.negotiatedCipherSuite.keyExchange,
|
||||
chc.negotiatedProtocol);
|
||||
if (ke == null) { // unlikely
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key exchange type");
|
||||
} else {
|
||||
SSLKeyDerivation masterKD = ke.createKeyDerivation(chc);
|
||||
@ -217,7 +215,7 @@ final class RSAClientKeyExchange {
|
||||
SSLTrafficKeyDerivation kd =
|
||||
SSLTrafficKeyDerivation.valueOf(chc.negotiatedProtocol);
|
||||
if (kd == null) { // unlikely
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " +
|
||||
chc.negotiatedProtocol);
|
||||
} else {
|
||||
@ -262,14 +260,14 @@ final class RSAClientKeyExchange {
|
||||
}
|
||||
|
||||
if (rsaPossession == null && x509Possession == null) { // unlikely
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"No RSA possessions negotiated for client key exchange");
|
||||
}
|
||||
|
||||
PrivateKey privateKey = (rsaPossession != null) ?
|
||||
rsaPossession.popPrivateKey : x509Possession.popPrivateKey;
|
||||
if (!privateKey.getAlgorithm().equals("RSA")) { // unlikely
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Not RSA private key for client key exchange");
|
||||
}
|
||||
|
||||
@ -287,7 +285,7 @@ final class RSAClientKeyExchange {
|
||||
RSAPremasterSecret.decode(shc, privateKey, ckem.encrypted);
|
||||
shc.handshakeCredentials.add(premaster);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Cannot decode RSA premaster secret", gse);
|
||||
}
|
||||
|
||||
@ -296,7 +294,7 @@ final class RSAClientKeyExchange {
|
||||
shc.negotiatedCipherSuite.keyExchange,
|
||||
shc.negotiatedProtocol);
|
||||
if (ke == null) { // unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key exchange type");
|
||||
} else {
|
||||
SSLKeyDerivation masterKD = ke.createKeyDerivation(shc);
|
||||
@ -308,7 +306,7 @@ final class RSAClientKeyExchange {
|
||||
SSLTrafficKeyDerivation kd =
|
||||
SSLTrafficKeyDerivation.valueOf(shc.negotiatedProtocol);
|
||||
if (kd == null) { // unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " +
|
||||
shc.negotiatedProtocol);
|
||||
} else {
|
||||
|
@ -274,7 +274,7 @@ final class RSAKeyExchange {
|
||||
}
|
||||
|
||||
if (premaster == null) {
|
||||
context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No sufficient RSA key agreement parameters negotiated");
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ final class RSAServerKeyExchange {
|
||||
signature = signer.sign();
|
||||
} catch (NoSuchAlgorithmException |
|
||||
InvalidKeyException | SignatureException ex) {
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Failed to sign ephemeral RSA parameters", ex);
|
||||
}
|
||||
|
||||
@ -122,7 +122,7 @@ final class RSAServerKeyExchange {
|
||||
}
|
||||
|
||||
if (x509Credentials == null) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"No RSA credentials negotiated for server key exchange");
|
||||
}
|
||||
|
||||
@ -133,12 +133,12 @@ final class RSAServerKeyExchange {
|
||||
chc.clientHelloRandom.randomBytes,
|
||||
chc.serverHelloRandom.randomBytes);
|
||||
if (!signer.verify(paramsSignature)) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid signature of RSA ServerKeyExchange message");
|
||||
}
|
||||
} catch (NoSuchAlgorithmException |
|
||||
InvalidKeyException | SignatureException ex) {
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Failed to sign ephemeral RSA parameters", ex);
|
||||
}
|
||||
}
|
||||
@ -250,12 +250,12 @@ final class RSAServerKeyExchange {
|
||||
return null;
|
||||
} else if (x509Possession == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"No RSA certificate negotiated for server key exchange");
|
||||
} else if (!"RSA".equals(
|
||||
x509Possession.popPrivateKey.getAlgorithm())) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"No X.509 possession can be used for " +
|
||||
"ephemeral RSA ServerKeyExchange");
|
||||
}
|
||||
@ -312,15 +312,13 @@ final class RSAServerKeyExchange {
|
||||
new BigInteger(1, skem.exponent));
|
||||
publicKey = (RSAPublicKey)kf.generatePublic(spec);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
chc.conContext.fatal(Alert.INSUFFICIENT_SECURITY,
|
||||
throw chc.conContext.fatal(Alert.INSUFFICIENT_SECURITY,
|
||||
"Could not generate RSAPublicKey", gse);
|
||||
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
if (!chc.algorithmConstraints.permits(
|
||||
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), publicKey)) {
|
||||
chc.conContext.fatal(Alert.INSUFFICIENT_SECURITY,
|
||||
throw chc.conContext.fatal(Alert.INSUFFICIENT_SECURITY,
|
||||
"RSA ServerKeyExchange does not comply to " +
|
||||
"algorithm constraints");
|
||||
}
|
||||
@ -328,7 +326,8 @@ final class RSAServerKeyExchange {
|
||||
//
|
||||
// update
|
||||
//
|
||||
chc.handshakeCredentials.add(new EphemeralRSACredentials(publicKey));
|
||||
chc.handshakeCredentials.add(
|
||||
new EphemeralRSACredentials(publicKey));
|
||||
|
||||
//
|
||||
// produce
|
||||
|
@ -185,12 +185,10 @@ final class RenegoInfoExtension {
|
||||
return null;
|
||||
} else {
|
||||
// terminate the session.
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"insecure renegotiation is not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,14 +224,13 @@ final class RenegoInfoExtension {
|
||||
try {
|
||||
spec = new RenegotiationInfoSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
if (!shc.conContext.isNegotiated) {
|
||||
// initial handshaking.
|
||||
if (spec.renegotiatedConnection.length != 0) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Invalid renegotiation_info extension data: not empty");
|
||||
}
|
||||
shc.conContext.secureRenegotiation = true;
|
||||
@ -241,14 +238,14 @@ final class RenegoInfoExtension {
|
||||
if (!shc.conContext.secureRenegotiation) {
|
||||
// Unexpected RI extension for insecure renegotiation,
|
||||
// abort the handshake with a fatal handshake_failure alert.
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"The renegotiation_info is present in a insecure " +
|
||||
"renegotiation");
|
||||
} else {
|
||||
// verify the client_verify_data value
|
||||
if (!Arrays.equals(shc.conContext.clientVerifyData,
|
||||
spec.renegotiatedConnection)) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Invalid renegotiation_info extension data: " +
|
||||
"incorrect verify data in ClientHello");
|
||||
}
|
||||
@ -295,7 +292,7 @@ final class RenegoInfoExtension {
|
||||
}
|
||||
|
||||
if (!HandshakeContext.allowLegacyHelloMessages) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Failed to negotiate the use of secure renegotiation");
|
||||
} // otherwise, allow legacy hello message
|
||||
|
||||
@ -307,7 +304,7 @@ final class RenegoInfoExtension {
|
||||
shc.conContext.secureRenegotiation = false;
|
||||
} else if (shc.conContext.secureRenegotiation) {
|
||||
// Require secure renegotiation, terminate the connection.
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Inconsistent secure renegotiation indication");
|
||||
} else { // renegotiation, not secure
|
||||
if (HandshakeContext.allowUnsafeRenegotiation) {
|
||||
@ -320,7 +317,7 @@ final class RenegoInfoExtension {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine("Terminate insecure renegotiation");
|
||||
}
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Unsafe renegotiation is not allowed");
|
||||
}
|
||||
}
|
||||
@ -430,7 +427,7 @@ final class RenegoInfoExtension {
|
||||
if (requestedSpec == null &&
|
||||
!chc.activeCipherSuites.contains(
|
||||
CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) {
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Missing renegotiation_info and SCSV detected in " +
|
||||
"ClientHello");
|
||||
}
|
||||
@ -440,8 +437,7 @@ final class RenegoInfoExtension {
|
||||
try {
|
||||
spec = new RenegotiationInfoSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
|
||||
@ -452,7 +448,7 @@ final class RenegoInfoExtension {
|
||||
// and if it is not, MUST abort the handshake (by sending
|
||||
// a fatal handshake_failure alert). [RFC 5746]
|
||||
if (spec.renegotiatedConnection.length != 0) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid renegotiation_info in ServerHello: " +
|
||||
"not empty renegotiated_connection");
|
||||
}
|
||||
@ -467,7 +463,7 @@ final class RenegoInfoExtension {
|
||||
int infoLen = chc.conContext.clientVerifyData.length +
|
||||
chc.conContext.serverVerifyData.length;
|
||||
if (spec.renegotiatedConnection.length != infoLen) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid renegotiation_info in ServerHello: " +
|
||||
"invalid renegotiated_connection length (" +
|
||||
spec.renegotiatedConnection.length + ")");
|
||||
@ -476,14 +472,14 @@ final class RenegoInfoExtension {
|
||||
byte[] cvd = chc.conContext.clientVerifyData;
|
||||
if (!Arrays.equals(spec.renegotiatedConnection,
|
||||
0, cvd.length, cvd, 0, cvd.length)) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid renegotiation_info in ServerHello: " +
|
||||
"unmatched client_verify_data value");
|
||||
}
|
||||
byte[] svd = chc.conContext.serverVerifyData;
|
||||
if (!Arrays.equals(spec.renegotiatedConnection,
|
||||
cvd.length, infoLen, svd, 0, svd.length)) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Invalid renegotiation_info in ServerHello: " +
|
||||
"unmatched server_verify_data value");
|
||||
}
|
||||
@ -516,7 +512,7 @@ final class RenegoInfoExtension {
|
||||
if (requestedSpec == null &&
|
||||
!chc.activeCipherSuites.contains(
|
||||
CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) {
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Missing renegotiation_info and SCSV detected in " +
|
||||
"ClientHello");
|
||||
}
|
||||
@ -524,7 +520,7 @@ final class RenegoInfoExtension {
|
||||
if (!chc.conContext.isNegotiated) {
|
||||
// initial handshaking.
|
||||
if (!HandshakeContext.allowLegacyHelloMessages) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Failed to negotiate the use of secure renegotiation");
|
||||
} // otherwise, allow legacy hello message
|
||||
|
||||
@ -536,7 +532,7 @@ final class RenegoInfoExtension {
|
||||
chc.conContext.secureRenegotiation = false;
|
||||
} else if (chc.conContext.secureRenegotiation) {
|
||||
// Require secure renegotiation, terminate the connection.
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Inconsistent secure renegotiation indication");
|
||||
} else { // renegotiation, not secure
|
||||
if (HandshakeContext.allowUnsafeRenegotiation) {
|
||||
@ -549,7 +545,7 @@ final class RenegoInfoExtension {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine("Terminate insecure renegotiation");
|
||||
}
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Unsafe renegotiation is not allowed");
|
||||
}
|
||||
}
|
||||
|
@ -29,8 +29,6 @@ import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.AlgorithmConstraints;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
@ -102,10 +102,10 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
|
||||
try {
|
||||
conContext.kickstart();
|
||||
} catch (IOException ioe) {
|
||||
conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Couldn't kickstart handshaking", ioe);
|
||||
} catch (Exception ex) { // including RuntimeException
|
||||
conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Fail to begin handshake", ex);
|
||||
}
|
||||
}
|
||||
@ -137,16 +137,14 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
|
||||
srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength);
|
||||
} catch (SSLProtocolException spe) {
|
||||
// may be an unexpected handshake message
|
||||
conContext.fatal(Alert.UNEXPECTED_MESSAGE, spe);
|
||||
throw conContext.fatal(Alert.UNEXPECTED_MESSAGE, spe);
|
||||
} catch (IOException ioe) {
|
||||
conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"problem wrapping app data", ioe);
|
||||
} catch (Exception ex) { // including RuntimeException
|
||||
conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Fail to wrap application data", ex);
|
||||
}
|
||||
|
||||
return null; // make compiler happy
|
||||
}
|
||||
|
||||
private SSLEngineResult writeRecord(
|
||||
@ -275,9 +273,9 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
|
||||
srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength);
|
||||
} catch (SSLHandshakeException she) {
|
||||
// may be record sequence number overflow
|
||||
conContext.fatal(Alert.HANDSHAKE_FAILURE, she);
|
||||
throw conContext.fatal(Alert.HANDSHAKE_FAILURE, she);
|
||||
} catch (IOException e) {
|
||||
conContext.fatal(Alert.UNEXPECTED_MESSAGE, e);
|
||||
throw conContext.fatal(Alert.UNEXPECTED_MESSAGE, e);
|
||||
}
|
||||
|
||||
if (ciphertext == null) {
|
||||
@ -444,7 +442,7 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
|
||||
srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength);
|
||||
} catch (SSLProtocolException spe) {
|
||||
// may be an unexpected handshake message
|
||||
conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
spe.getMessage(), spe);
|
||||
} catch (IOException ioe) {
|
||||
/*
|
||||
@ -453,14 +451,12 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
|
||||
* got us into this situation, so report that much back.
|
||||
* Our days of consuming are now over anyway.
|
||||
*/
|
||||
conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"problem unwrapping net record", ioe);
|
||||
} catch (Exception ex) { // including RuntimeException
|
||||
conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Fail to unwrap network record", ex);
|
||||
}
|
||||
|
||||
return null; // make compiler happy
|
||||
}
|
||||
|
||||
private SSLEngineResult readRecord(
|
||||
@ -721,7 +717,7 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
|
||||
if (!conContext.isInputCloseNotified &&
|
||||
(conContext.isNegotiated || conContext.handshakeContext != null)) {
|
||||
|
||||
conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"closing inbound before receiving peer's close_notify");
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,8 @@ final class SSLExtensions {
|
||||
int extId = Record.getInt16(m);
|
||||
int extLen = Record.getInt16(m);
|
||||
if (extLen > m.remaining()) {
|
||||
hm.handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw hm.handshakeContext.conContext.fatal(
|
||||
Alert.ILLEGAL_PARAMETER,
|
||||
"Error parsing extension (" + extId +
|
||||
"): no sufficient data");
|
||||
}
|
||||
@ -86,7 +87,7 @@ final class SSLExtensions {
|
||||
"in the ServerHello handshake message");
|
||||
}
|
||||
} else {
|
||||
hm.handshakeContext.conContext.fatal(
|
||||
throw hm.handshakeContext.conContext.fatal(
|
||||
Alert.UNSUPPORTED_EXTENSION,
|
||||
"extension (" + extId +
|
||||
") should not be presented in " + handshakeType.name);
|
||||
@ -102,7 +103,7 @@ final class SSLExtensions {
|
||||
}
|
||||
|
||||
if (extension.handshakeType != handshakeType) {
|
||||
hm.handshakeContext.conContext.fatal(
|
||||
throw hm.handshakeContext.conContext.fatal(
|
||||
Alert.UNSUPPORTED_EXTENSION,
|
||||
"extension (" + extId + ") should not be " +
|
||||
"presented in " + handshakeType.name);
|
||||
|
@ -402,7 +402,7 @@ public final class SSLSocketImpl
|
||||
readHandshakeRecord();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Couldn't kickstart handshaking", ioe);
|
||||
} catch (Exception oe) { // including RuntimeException
|
||||
handleException(oe);
|
||||
@ -608,7 +608,12 @@ public final class SSLSocketImpl
|
||||
}
|
||||
} else {
|
||||
if (!conContext.isInboundClosed()) {
|
||||
conContext.inputRecord.close();
|
||||
try (conContext.inputRecord) {
|
||||
// Try the best to use up the input records and close the
|
||||
// socket gracefully, without impact the performance too
|
||||
// much.
|
||||
appInput.deplete();
|
||||
}
|
||||
}
|
||||
|
||||
if ((autoClose || !isLayered()) && !super.isInputShutdown()) {
|
||||
@ -642,7 +647,7 @@ public final class SSLSocketImpl
|
||||
if (checkCloseNotify && !conContext.isInputCloseNotified &&
|
||||
(conContext.isNegotiated || conContext.handshakeContext != null)) {
|
||||
|
||||
conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"closing inbound before receiving peer's close_notify");
|
||||
}
|
||||
|
||||
@ -907,6 +912,30 @@ public final class SSLSocketImpl
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try the best to use up the input records so as to close the
|
||||
* socket gracefully, without impact the performance too much.
|
||||
*/
|
||||
private synchronized void deplete() {
|
||||
if (!conContext.isInboundClosed()) {
|
||||
if (!(conContext.inputRecord instanceof SSLSocketInputRecord)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SSLSocketInputRecord socketInputRecord =
|
||||
(SSLSocketInputRecord)conContext.inputRecord;
|
||||
try {
|
||||
socketInputRecord.deplete(
|
||||
conContext.isNegotiated && (getSoTimeout() > 0));
|
||||
} catch (IOException ioe) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
|
||||
SSLLogger.warning(
|
||||
"input stream close depletion failed", ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -982,9 +1011,9 @@ public final class SSLSocketImpl
|
||||
conContext.outputRecord.deliver(b, off, len);
|
||||
} catch (SSLHandshakeException she) {
|
||||
// may be record sequence number overflow
|
||||
conContext.fatal(Alert.HANDSHAKE_FAILURE, she);
|
||||
throw conContext.fatal(Alert.HANDSHAKE_FAILURE, she);
|
||||
} catch (IOException e) {
|
||||
conContext.fatal(Alert.UNEXPECTED_MESSAGE, e);
|
||||
throw conContext.fatal(Alert.UNEXPECTED_MESSAGE, e);
|
||||
}
|
||||
|
||||
// Is the sequence number is nearly overflow, or has the key usage
|
||||
@ -1309,7 +1338,8 @@ public final class SSLSocketImpl
|
||||
alert = Alert.INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
conContext.fatal(alert, cause);
|
||||
|
||||
throw conContext.fatal(alert, cause);
|
||||
}
|
||||
|
||||
private Plaintext handleEOF(EOFException eofe) throws IOException {
|
||||
|
@ -463,4 +463,17 @@ final class SSLSocketInputRecord extends InputRecord implements SSLRecord {
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
// Try to use up the input stream without impact the performance too much.
|
||||
void deplete(boolean tryToRead) throws IOException {
|
||||
int remaining = is.available();
|
||||
if (tryToRead && (remaining == 0)) {
|
||||
// try to wait and read one byte if no buffered input
|
||||
is.read();
|
||||
}
|
||||
|
||||
while ((remaining = is.available()) != 0) {
|
||||
is.skip(remaining);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ interface SSLTransport {
|
||||
}
|
||||
}
|
||||
|
||||
context.fatal(Alert.UNEXPECTED_MESSAGE, unsoe);
|
||||
throw context.fatal(Alert.UNEXPECTED_MESSAGE, unsoe);
|
||||
} catch (BadPaddingException bpe) {
|
||||
/*
|
||||
* The basic SSLv3 record protection involves (optional)
|
||||
@ -126,15 +126,15 @@ interface SSLTransport {
|
||||
Alert alert = (context.handshakeContext != null) ?
|
||||
Alert.HANDSHAKE_FAILURE :
|
||||
Alert.BAD_RECORD_MAC;
|
||||
context.fatal(alert, bpe);
|
||||
throw context.fatal(alert, bpe);
|
||||
} catch (SSLHandshakeException she) {
|
||||
// may be record sequence number overflow
|
||||
context.fatal(Alert.HANDSHAKE_FAILURE, she);
|
||||
throw context.fatal(Alert.HANDSHAKE_FAILURE, she);
|
||||
} catch (EOFException eofe) {
|
||||
// rethrow EOFException, the call will handle it if neede.
|
||||
throw eofe;
|
||||
} catch (IOException ioe) {
|
||||
context.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
throw context.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
if (plaintexts == null || plaintexts.length == 0) {
|
||||
@ -191,7 +191,7 @@ interface SSLTransport {
|
||||
}
|
||||
|
||||
if (remains > 0) {
|
||||
context.fatal(Alert.INTERNAL_ERROR,
|
||||
throw context.fatal(Alert.INTERNAL_ERROR,
|
||||
"no sufficient room in the destination buffers");
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ final class ServerHello {
|
||||
this.serverVersion = ProtocolVersion.valueOf(major, minor);
|
||||
if (this.serverVersion == null) {
|
||||
// The client should only request for known protocol versions.
|
||||
context.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
throw context.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
"Unsupported protocol version: " +
|
||||
ProtocolVersion.nameOf(major, minor));
|
||||
}
|
||||
@ -143,20 +143,21 @@ final class ServerHello {
|
||||
try {
|
||||
sessionId.checkLength(serverVersion.id);
|
||||
} catch (SSLProtocolException ex) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, ex);
|
||||
throw handshakeContext.conContext.fatal(
|
||||
Alert.ILLEGAL_PARAMETER, ex);
|
||||
}
|
||||
|
||||
int cipherSuiteId = Record.getInt16(m);
|
||||
this.cipherSuite = CipherSuite.valueOf(cipherSuiteId);
|
||||
if (cipherSuite == null || !context.isNegotiable(cipherSuite)) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Server selected improper ciphersuite " +
|
||||
CipherSuite.nameOf(cipherSuiteId));
|
||||
}
|
||||
|
||||
this.compressionMethod = m.get();
|
||||
if (compressionMethod != 0) {
|
||||
context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"compression type not supported, " + compressionMethod);
|
||||
}
|
||||
|
||||
@ -293,10 +294,8 @@ final class ServerHello {
|
||||
KeyExchangeProperties credentials =
|
||||
chooseCipherSuite(shc, clientHello);
|
||||
if (credentials == null) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"no cipher suites in common");
|
||||
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
shc.negotiatedCipherSuite = credentials.cipherSuite;
|
||||
shc.handshakeKeyExchange = credentials.keyExchange;
|
||||
@ -374,7 +373,7 @@ final class ServerHello {
|
||||
SSLTrafficKeyDerivation.valueOf(shc.negotiatedProtocol);
|
||||
if (kdg == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " +
|
||||
shc.negotiatedProtocol);
|
||||
} else {
|
||||
@ -458,10 +457,8 @@ final class ServerHello {
|
||||
}
|
||||
}
|
||||
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"no cipher suites in common");
|
||||
|
||||
return null; // make the compiler happy.
|
||||
}
|
||||
|
||||
private static final class KeyExchangeProperties {
|
||||
@ -524,9 +521,8 @@ final class ServerHello {
|
||||
// negotiate the cipher suite.
|
||||
CipherSuite cipherSuite = chooseCipherSuite(shc, clientHello);
|
||||
if (cipherSuite == null) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"no cipher suites in common");
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
shc.negotiatedCipherSuite = cipherSuite;
|
||||
shc.handshakeSession.setSuite(cipherSuite);
|
||||
@ -592,9 +588,8 @@ final class ServerHello {
|
||||
SSLKeyExchange ke = shc.handshakeKeyExchange;
|
||||
if (ke == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not negotiated key shares");
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
|
||||
SSLKeyDerivation handshakeKD = ke.createKeyDerivation(shc);
|
||||
@ -605,10 +600,9 @@ final class ServerHello {
|
||||
SSLTrafficKeyDerivation.valueOf(shc.negotiatedProtocol);
|
||||
if (kdg == null) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " +
|
||||
shc.negotiatedProtocol);
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
|
||||
SSLKeyDerivation kd =
|
||||
@ -634,9 +628,15 @@ final class ServerHello {
|
||||
shc.sslContext.getSecureRandom());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Missing cipher algorithm", gse);
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
|
||||
if (readCipher == null) {
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Illegal cipher suite (" + shc.negotiatedCipherSuite +
|
||||
") and protocol version (" + shc.negotiatedProtocol +
|
||||
")");
|
||||
}
|
||||
|
||||
shc.baseReadSecret = readSecret;
|
||||
@ -662,9 +662,15 @@ final class ServerHello {
|
||||
shc.sslContext.getSecureRandom());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
// unlikely
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Missing cipher algorithm", gse);
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
|
||||
if (writeCipher == null) {
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Illegal cipher suite (" + shc.negotiatedCipherSuite +
|
||||
") and protocol version (" + shc.negotiatedProtocol +
|
||||
")");
|
||||
}
|
||||
|
||||
shc.baseWriteSecret = writeSecret;
|
||||
@ -746,9 +752,8 @@ final class ServerHello {
|
||||
CipherSuite cipherSuite =
|
||||
T13ServerHelloProducer.chooseCipherSuite(shc, clientHello);
|
||||
if (cipherSuite == null) {
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"no cipher suites in common for hello retry request");
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
|
||||
ServerHelloMessage hhrm = new ServerHelloMessage(shc,
|
||||
@ -857,7 +862,7 @@ final class ServerHello {
|
||||
SSLHandshake.HELLO_VERIFY_REQUEST.id);
|
||||
}
|
||||
if (!chc.handshakeConsumers.isEmpty()) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"No more message expected before ServerHello is processed");
|
||||
}
|
||||
|
||||
@ -895,14 +900,14 @@ final class ServerHello {
|
||||
}
|
||||
|
||||
if (!chc.activeProtocols.contains(serverVersion)) {
|
||||
chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
throw chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
"The server selected protocol version " + serverVersion +
|
||||
" is not accepted by client preferences " +
|
||||
chc.activeProtocols);
|
||||
}
|
||||
|
||||
if (!serverVersion.useTLS13PlusSpec()) {
|
||||
chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
throw chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
"Unexpected HelloRetryRequest for " + serverVersion.name);
|
||||
}
|
||||
|
||||
@ -947,7 +952,7 @@ final class ServerHello {
|
||||
}
|
||||
|
||||
if (!chc.activeProtocols.contains(serverVersion)) {
|
||||
chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
throw chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
"The server selected protocol version " + serverVersion +
|
||||
" is not accepted by client preferences " +
|
||||
chc.activeProtocols);
|
||||
@ -964,7 +969,7 @@ final class ServerHello {
|
||||
}
|
||||
|
||||
if (serverHello.serverRandom.isVersionDowngrade(chc)) {
|
||||
chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"A potential protocol version downgrade attack");
|
||||
}
|
||||
|
||||
@ -1007,7 +1012,7 @@ final class ServerHello {
|
||||
ClientHandshakeContext chc = (ClientHandshakeContext)context;
|
||||
ServerHelloMessage serverHello = (ServerHelloMessage)message;
|
||||
if (!chc.isNegotiable(serverHello.serverVersion)) {
|
||||
chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
throw chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
"Server chose " + serverHello.serverVersion +
|
||||
", but that protocol version is not enabled or " +
|
||||
"not supported by the client.");
|
||||
@ -1019,7 +1024,7 @@ final class ServerHello {
|
||||
chc.negotiatedProtocol, chc.negotiatedCipherSuite);
|
||||
chc.serverHelloRandom = serverHello.serverRandom;
|
||||
if (chc.negotiatedCipherSuite.keyExchange == null) {
|
||||
chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
throw chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
"TLS 1.2 or prior version does not support the " +
|
||||
"server cipher suite: " + chc.negotiatedCipherSuite.name);
|
||||
}
|
||||
@ -1045,7 +1050,7 @@ final class ServerHello {
|
||||
// Verify that the session ciphers are unchanged.
|
||||
CipherSuite sessionSuite = chc.resumingSession.getSuite();
|
||||
if (chc.negotiatedCipherSuite != sessionSuite) {
|
||||
chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
throw chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
"Server returned wrong cipher suite for session");
|
||||
}
|
||||
|
||||
@ -1053,7 +1058,7 @@ final class ServerHello {
|
||||
ProtocolVersion sessionVersion =
|
||||
chc.resumingSession.getProtocolVersion();
|
||||
if (chc.negotiatedProtocol != sessionVersion) {
|
||||
chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
throw chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
"Server resumed with wrong protocol version");
|
||||
}
|
||||
|
||||
@ -1072,7 +1077,7 @@ final class ServerHello {
|
||||
}
|
||||
chc.isResumption = false;
|
||||
if (!chc.sslConfig.enableSessionCreation) {
|
||||
chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
throw chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
"New session creation is disabled");
|
||||
}
|
||||
}
|
||||
@ -1091,7 +1096,7 @@ final class ServerHello {
|
||||
}
|
||||
|
||||
if (!chc.sslConfig.enableSessionCreation) {
|
||||
chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
throw chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
"New session creation is disabled");
|
||||
}
|
||||
chc.handshakeSession = new SSLSessionImpl(chc,
|
||||
@ -1112,7 +1117,7 @@ final class ServerHello {
|
||||
SSLTrafficKeyDerivation.valueOf(chc.negotiatedProtocol);
|
||||
if (kdg == null) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " +
|
||||
chc.negotiatedProtocol);
|
||||
} else {
|
||||
@ -1183,7 +1188,7 @@ final class ServerHello {
|
||||
ClientHandshakeContext chc = (ClientHandshakeContext)context;
|
||||
ServerHelloMessage serverHello = (ServerHelloMessage)message;
|
||||
if (serverHello.serverVersion != ProtocolVersion.TLS12) {
|
||||
chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
throw chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
"The ServerHello.legacy_version field is not TLS 1.2");
|
||||
}
|
||||
|
||||
@ -1208,7 +1213,7 @@ final class ServerHello {
|
||||
}
|
||||
|
||||
if (!chc.sslConfig.enableSessionCreation) {
|
||||
chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
throw chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
"New session creation is disabled");
|
||||
}
|
||||
chc.handshakeSession = new SSLSessionImpl(chc,
|
||||
@ -1221,7 +1226,7 @@ final class ServerHello {
|
||||
Optional<SecretKey> psk =
|
||||
chc.resumingSession.consumePreSharedKey();
|
||||
if(!psk.isPresent()) {
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"No PSK available. Unable to resume.");
|
||||
}
|
||||
|
||||
@ -1242,9 +1247,8 @@ final class ServerHello {
|
||||
SSLKeyExchange ke = chc.handshakeKeyExchange;
|
||||
if (ke == null) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not negotiated key shares");
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
SSLKeyDerivation handshakeKD = ke.createKeyDerivation(chc);
|
||||
@ -1254,10 +1258,9 @@ final class ServerHello {
|
||||
SSLTrafficKeyDerivation.valueOf(chc.negotiatedProtocol);
|
||||
if (kdg == null) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
|
||||
"Not supported key derivation: " +
|
||||
chc.negotiatedProtocol);
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
SSLKeyDerivation secretKD =
|
||||
@ -1284,9 +1287,15 @@ final class ServerHello {
|
||||
chc.sslContext.getSecureRandom());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Missing cipher algorithm", gse);
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
if (readCipher == null) {
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Illegal cipher suite (" + chc.negotiatedCipherSuite +
|
||||
") and protocol version (" + chc.negotiatedProtocol +
|
||||
")");
|
||||
}
|
||||
|
||||
chc.baseReadSecret = readSecret;
|
||||
@ -1312,9 +1321,15 @@ final class ServerHello {
|
||||
chc.sslContext.getSecureRandom());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Missing cipher algorithm", gse);
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
if (writeCipher == null) {
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Illegal cipher suite (" + chc.negotiatedCipherSuite +
|
||||
") and protocol version (" + chc.negotiatedProtocol +
|
||||
")");
|
||||
}
|
||||
|
||||
chc.baseWriteSecret = writeSecret;
|
||||
@ -1376,7 +1391,7 @@ final class ServerHello {
|
||||
ClientHandshakeContext chc = (ClientHandshakeContext)context;
|
||||
ServerHelloMessage helloRetryRequest = (ServerHelloMessage)message;
|
||||
if (helloRetryRequest.serverVersion != ProtocolVersion.TLS12) {
|
||||
chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
throw chc.conContext.fatal(Alert.PROTOCOL_VERSION,
|
||||
"The HelloRetryRequest.legacy_version is not TLS 1.2");
|
||||
}
|
||||
|
||||
@ -1406,7 +1421,7 @@ final class ServerHello {
|
||||
chc.initialClientHelloMsg.write(hos);
|
||||
} catch (IOException ioe) {
|
||||
// unlikely
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Failed to construct message hash", ioe);
|
||||
}
|
||||
chc.handshakeHash.deliver(hos.toByteArray());
|
||||
|
@ -50,7 +50,7 @@ final class ServerHelloDone {
|
||||
ByteBuffer m) throws IOException {
|
||||
super(handshakeContext);
|
||||
if (m.hasRemaining()) {
|
||||
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Error parsing ServerHelloDone message: not empty");
|
||||
}
|
||||
}
|
||||
|
@ -68,9 +68,8 @@ final class ServerKeyExchange {
|
||||
}
|
||||
|
||||
// not producer defined.
|
||||
shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No ServerKeyExchange handshake message can be produced.");
|
||||
return null; // make the compiler happe
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,7 +106,7 @@ final class ServerKeyExchange {
|
||||
}
|
||||
|
||||
// no consumer defined.
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected ServerKeyExchange handshake message.");
|
||||
}
|
||||
}
|
||||
|
@ -295,8 +295,7 @@ final class ServerNameExtension {
|
||||
try {
|
||||
spec = new CHServerNamesSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// Update the context.
|
||||
@ -314,7 +313,7 @@ final class ServerNameExtension {
|
||||
}
|
||||
} else {
|
||||
// We do not reject client without SNI extension currently.
|
||||
shc.conContext.fatal(Alert.UNRECOGNIZED_NAME,
|
||||
throw shc.conContext.fatal(Alert.UNRECOGNIZED_NAME,
|
||||
"Unrecognized server name indication");
|
||||
}
|
||||
} else {
|
||||
@ -483,13 +482,13 @@ final class ServerNameExtension {
|
||||
CHServerNamesSpec spec = (CHServerNamesSpec)
|
||||
chc.handshakeExtensions.get(CH_SERVER_NAME);
|
||||
if (spec == null) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected ServerHello server_name extension");
|
||||
}
|
||||
|
||||
// Parse the extension.
|
||||
if (buffer.remaining() != 0) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Invalid ServerHello server_name extension");
|
||||
}
|
||||
|
||||
@ -570,13 +569,13 @@ final class ServerNameExtension {
|
||||
CHServerNamesSpec spec = (CHServerNamesSpec)
|
||||
chc.handshakeExtensions.get(CH_SERVER_NAME);
|
||||
if (spec == null) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected EncryptedExtensions server_name extension");
|
||||
}
|
||||
|
||||
// Parse the extension.
|
||||
if (buffer.remaining() != 0) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Invalid EncryptedExtensions server_name extension");
|
||||
}
|
||||
|
||||
|
@ -238,8 +238,7 @@ final class SignatureAlgorithmsExtension {
|
||||
try {
|
||||
spec = new SignatureSchemesSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// Update the context.
|
||||
@ -329,7 +328,7 @@ final class SignatureAlgorithmsExtension {
|
||||
// We may support the server authentication other than X.509
|
||||
// certificate later.
|
||||
if (shc.negotiatedProtocol.useTLS13PlusSpec()) {
|
||||
shc.conContext.fatal(Alert.MISSING_EXTENSION,
|
||||
throw shc.conContext.fatal(Alert.MISSING_EXTENSION,
|
||||
"No mandatory signature_algorithms extension in the " +
|
||||
"received CertificateRequest handshake message");
|
||||
}
|
||||
@ -403,10 +402,9 @@ final class SignatureAlgorithmsExtension {
|
||||
// handshake message in TLS 1.3.
|
||||
if (!shc.sslConfig.isAvailable(
|
||||
SSLExtension.CR_SIGNATURE_ALGORITHMS)) {
|
||||
shc.conContext.fatal(Alert.MISSING_EXTENSION,
|
||||
throw shc.conContext.fatal(Alert.MISSING_EXTENSION,
|
||||
"No available signature_algorithms extension " +
|
||||
"for client certificate authentication");
|
||||
return null; // make the compiler happy
|
||||
}
|
||||
|
||||
// Produce the extension.
|
||||
@ -454,10 +452,9 @@ final class SignatureAlgorithmsExtension {
|
||||
// handshake message in TLS 1.3.
|
||||
if (!chc.sslConfig.isAvailable(
|
||||
SSLExtension.CR_SIGNATURE_ALGORITHMS)) {
|
||||
chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"No available signature_algorithms extension " +
|
||||
"for client certificate authentication");
|
||||
return; // make the compiler happy
|
||||
}
|
||||
|
||||
// Parse the extension.
|
||||
@ -465,8 +462,7 @@ final class SignatureAlgorithmsExtension {
|
||||
try {
|
||||
spec = new SignatureSchemesSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
List<SignatureScheme> knownSignatureSchemes = new LinkedList<>();
|
||||
@ -545,7 +541,7 @@ final class SignatureAlgorithmsExtension {
|
||||
|
||||
// This is a mandatory extension for CertificateRequest handshake
|
||||
// message in TLS 1.3.
|
||||
chc.conContext.fatal(Alert.MISSING_EXTENSION,
|
||||
throw chc.conContext.fatal(Alert.MISSING_EXTENSION,
|
||||
"No mandatory signature_algorithms extension in the " +
|
||||
"received CertificateRequest handshake message");
|
||||
}
|
||||
|
@ -900,8 +900,7 @@ final class SupportedGroupsExtension {
|
||||
try {
|
||||
spec = new SupportedGroupsSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// Update the context.
|
||||
@ -1024,8 +1023,7 @@ final class SupportedGroupsExtension {
|
||||
try {
|
||||
spec = new SupportedGroupsSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// Update the context.
|
||||
|
@ -225,8 +225,7 @@ final class SupportedVersionsExtension {
|
||||
try {
|
||||
spec = new CHSupportedVersionsSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// Update the context.
|
||||
@ -368,8 +367,7 @@ final class SupportedVersionsExtension {
|
||||
try {
|
||||
spec = new SHSupportedVersionsSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// Update the context.
|
||||
@ -458,8 +456,7 @@ final class SupportedVersionsExtension {
|
||||
try {
|
||||
spec = new SHSupportedVersionsSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
return; // fatal() always throws, make the compiler happy.
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
// Update the context.
|
||||
|
@ -148,9 +148,8 @@ class TransportContext implements ConnectionContext {
|
||||
|
||||
ContentType ct = ContentType.valueOf(plaintext.contentType);
|
||||
if (ct == null) {
|
||||
fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unknown content type: " + plaintext.contentType);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ct) {
|
||||
@ -164,7 +163,7 @@ class TransportContext implements ConnectionContext {
|
||||
protocolVersion.useTLS13PlusSpec()) {
|
||||
handshakeContext = new PostHandshakeContext(this);
|
||||
} else {
|
||||
fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected post-handshake message: " +
|
||||
SSLHandshake.nameOf(type));
|
||||
}
|
||||
@ -185,7 +184,7 @@ class TransportContext implements ConnectionContext {
|
||||
if (consumer != null) {
|
||||
consumer.consume(this, plaintext.fragment);
|
||||
} else {
|
||||
fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
"Unexpected content: " + plaintext.contentType);
|
||||
}
|
||||
}
|
||||
@ -250,22 +249,22 @@ class TransportContext implements ConnectionContext {
|
||||
}
|
||||
}
|
||||
|
||||
void fatal(Alert alert,
|
||||
SSLException fatal(Alert alert,
|
||||
String diagnostic) throws SSLException {
|
||||
fatal(alert, diagnostic, null);
|
||||
return fatal(alert, diagnostic, null);
|
||||
}
|
||||
|
||||
void fatal(Alert alert, Throwable cause) throws SSLException {
|
||||
fatal(alert, null, cause);
|
||||
SSLException fatal(Alert alert, Throwable cause) throws SSLException {
|
||||
return fatal(alert, null, cause);
|
||||
}
|
||||
|
||||
void fatal(Alert alert,
|
||||
SSLException fatal(Alert alert,
|
||||
String diagnostic, Throwable cause) throws SSLException {
|
||||
fatal(alert, diagnostic, false, cause);
|
||||
return fatal(alert, diagnostic, false, cause);
|
||||
}
|
||||
|
||||
// Note: close_notify is not delivered via fatal() methods.
|
||||
void fatal(Alert alert, String diagnostic,
|
||||
SSLException fatal(Alert alert, String diagnostic,
|
||||
boolean recvFatalAlert, Throwable cause) throws SSLException {
|
||||
// If we've already shutdown because of an error, there is nothing we
|
||||
// can do except rethrow the exception.
|
||||
@ -328,6 +327,8 @@ class TransportContext implements ConnectionContext {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
|
||||
SSLLogger.warning("Fatal: input record closure failed", ioe);
|
||||
}
|
||||
|
||||
closeReason.addSuppressed(ioe);
|
||||
}
|
||||
|
||||
// invalidate the session
|
||||
@ -353,6 +354,8 @@ class TransportContext implements ConnectionContext {
|
||||
SSLLogger.warning(
|
||||
"Fatal: failed to send fatal alert " + alert, ioe);
|
||||
}
|
||||
|
||||
closeReason.addSuppressed(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,6 +366,8 @@ class TransportContext implements ConnectionContext {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
|
||||
SSLLogger.warning("Fatal: output record closure failed", ioe);
|
||||
}
|
||||
|
||||
closeReason.addSuppressed(ioe);
|
||||
}
|
||||
|
||||
// terminate the handshake context
|
||||
@ -377,6 +382,8 @@ class TransportContext implements ConnectionContext {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
|
||||
SSLLogger.warning("Fatal: transport closure failed", ioe);
|
||||
}
|
||||
|
||||
closeReason.addSuppressed(ioe);
|
||||
} finally {
|
||||
isBroken = true;
|
||||
}
|
||||
|
@ -28,8 +28,6 @@ package sun.security.util;
|
||||
import java.io.IOException;
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import sun.security.util.ObjectIdentifier;
|
||||
import sun.security.x509.AlgorithmId;
|
||||
import sun.security.rsa.RSAUtil;
|
||||
|
||||
/**
|
||||
@ -86,13 +84,12 @@ public class SignatureUtil {
|
||||
// specified Signature object as signature parameters.
|
||||
public static void specialSetParameter(Signature sig, byte[] paramBytes)
|
||||
throws InvalidAlgorithmParameterException, ProviderException {
|
||||
|
||||
AlgorithmParameters params = null;
|
||||
if (paramBytes != null) {
|
||||
String sigName = sig.getAlgorithm();
|
||||
params = createAlgorithmParameters(sigName, paramBytes);
|
||||
AlgorithmParameters params =
|
||||
createAlgorithmParameters(sigName, paramBytes);
|
||||
specialSetParameter(sig, params);
|
||||
}
|
||||
specialSetParameter(sig, params);
|
||||
}
|
||||
|
||||
// Special method for setting the specified AlgorithmParameter object
|
||||
@ -100,16 +97,9 @@ public class SignatureUtil {
|
||||
public static void specialSetParameter(Signature sig,
|
||||
AlgorithmParameters params)
|
||||
throws InvalidAlgorithmParameterException, ProviderException {
|
||||
|
||||
String sigName = sig.getAlgorithm();
|
||||
if (params != null) {
|
||||
String sigName = sig.getAlgorithm();
|
||||
sig.setParameter(getParamSpec(sigName, params));
|
||||
} else {
|
||||
try {
|
||||
sig.setParameter(null);
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// ignore for maintaining backward compatibility
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,3 +59,12 @@ Java_java_security_AccessController_getInheritedAccessControlContext(
|
||||
{
|
||||
return JVM_GetInheritedAccessControlContext(env, this);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_java_security_AccessController_ensureMaterializedForStackWalk(
|
||||
JNIEnv *env,
|
||||
jclass cls,
|
||||
jobject value)
|
||||
{
|
||||
JVM_EnsureMaterializedForStackWalk(env, value);
|
||||
}
|
||||
|
@ -5,7 +5,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
|
@ -803,12 +803,8 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
|
||||
|
||||
#ifdef __linux__
|
||||
/*
|
||||
* On Linux if we are connecting to a
|
||||
*
|
||||
* - link-local address
|
||||
* - multicast interface-local or link-local address
|
||||
*
|
||||
* we need to specify the interface in the scope_id.
|
||||
* On Linux if we are connecting to a link-local address
|
||||
* we need to specify the interface in the scope_id (2.4 kernel only)
|
||||
*
|
||||
* If the scope was cached then we use the cached value. If not cached but
|
||||
* specified in the Inet6Address we use that, but we first check if the
|
||||
@ -818,9 +814,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
|
||||
* we try to determine a value from the routing table. In all these
|
||||
* cases the used value is cached for further use.
|
||||
*/
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr)
|
||||
|| IN6_IS_ADDR_MC_NODELOCAL(&sa->sa6.sin6_addr)
|
||||
|| IN6_IS_ADDR_MC_LINKLOCAL(&sa->sa6.sin6_addr)) {
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr)) {
|
||||
unsigned int cached_scope_id = 0, scope_id = 0;
|
||||
|
||||
if (ia6_cachedscopeidID) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, 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
|
||||
@ -182,7 +182,7 @@ public final class TerminalFactory {
|
||||
* <p>It is determined as follows:
|
||||
*
|
||||
* when this class is initialized, the system property
|
||||
* <code>javax.smartcardio.TerminalFactory.DefaultType</code>
|
||||
* {@systemProperty javax.smartcardio.TerminalFactory.DefaultType}
|
||||
* is examined. If it is set, a TerminalFactory of this type is
|
||||
* instantiated by calling the {@linkplain #getInstance
|
||||
* getInstance(String,Object)} method passing
|
||||
|
@ -29,11 +29,18 @@ import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
|
||||
import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
|
||||
import static org.graalvm.compiler.hotspot.meta.HotSpotAOTProfilingPlugin.Options.TieredAOT;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.stream.Stream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
|
||||
import org.graalvm.compiler.api.runtime.GraalJVMCICompiler;
|
||||
@ -78,10 +85,33 @@ public final class Main {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Main t = new Main();
|
||||
final int exitCode = t.run(args);
|
||||
final int exitCode = t.run(parse(args));
|
||||
System.exit(exitCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands '@file' in command line arguments by replacing '@file' with the content of 'file'
|
||||
* parsed by StringTokenizer. '@' character can be quoted as '@@'.
|
||||
*/
|
||||
private static String[] parse(String[] args) throws IOException {
|
||||
List<String> result = new ArrayList<>();
|
||||
for (String arg : args) {
|
||||
if (arg.length() > 1 && arg.charAt(0) == '@') {
|
||||
String v = arg.substring(1);
|
||||
if (v.charAt(0) == '@') {
|
||||
result.add(v);
|
||||
} else {
|
||||
try (Stream<String> file = Files.lines(Paths.get(v))) {
|
||||
file.map(StringTokenizer::new).map(Collections::list).flatMap(l -> l.stream().map(o -> (String) o)).forEachOrdered(result::add);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result.add(arg);
|
||||
}
|
||||
}
|
||||
return result.toArray(String[]::new);
|
||||
}
|
||||
|
||||
private int run(String[] args) {
|
||||
log = new PrintWriter(System.out);
|
||||
printer = new LogPrinter(this, log);
|
||||
|
@ -187,12 +187,12 @@ jshell.console.create.method = Create method
|
||||
jshell.console.resolvable = \nThe identifier is resolvable in this context.
|
||||
jshell.console.no.candidate = \nNo candidate fully qualified names found to import.
|
||||
jshell.console.incomplete = \nResults may be incomplete; try again later for complete results.
|
||||
jshell.console.erroneous = \nIncomplete or erroneous. A single valid expression or statement must proceed Shift-<tab> m.
|
||||
jshell.console.exprstmt = \nA single valid expression or statement must proceed Shift-<tab> m.
|
||||
jshell.console.empty = \nEmpty entry. A single valid expression or statement must proceed Shift-<tab> m..
|
||||
jshell.console.erroneous = \nIncomplete or erroneous. A single valid expression or statement must precede Shift+Tab m.
|
||||
jshell.console.exprstmt = \nA single valid expression or statement must precede Shift+Tab m.
|
||||
jshell.console.empty = \nEmpty entry. A single valid expression or statement must precede Shift+Tab m.
|
||||
|
||||
jshell.fix.wrong.shortcut =\
|
||||
Unexpected character after Shift-Tab.\n\
|
||||
Unexpected character after Shift+Tab.\n\
|
||||
Use "i" for auto-import, "v" for variable creation, or "m" for method creation.\n\
|
||||
For more information see:\n\
|
||||
/help shortcuts
|
||||
@ -579,92 +579,92 @@ or prior commands/snippets can be retrieved from history, edited, and executed.\
|
||||
This support is similar to readline/editline with simple emacs-like bindings.\n\
|
||||
There are also jshell tool specific key sequences.\n\
|
||||
\n\
|
||||
--- Line and history navigation ---\n\
|
||||
\n\
|
||||
Return\n\t\
|
||||
Enters the current snippet\n\
|
||||
Left-arrow or Ctrl+B\n\t\
|
||||
Moves backward one character\n\
|
||||
Right-arrow or Ctrl+F\n\t\
|
||||
Moves forward one character\n\
|
||||
Up-arrow or Ctrl+P\n\t\
|
||||
Moves up one line, backward through history\n\
|
||||
Down arrow or Ctrl+N\n\t\
|
||||
Moves down one line, forward through history\n\
|
||||
Ctrl+A\n\t\
|
||||
Moves to the beginning of the line\n\
|
||||
Ctrl+E\n\t\
|
||||
Moves to the end of the line\n\
|
||||
Meta+B\n\t\
|
||||
Moves backward one word\n\
|
||||
Meta+F\n\t\
|
||||
Moves forward one word\n\
|
||||
Ctrl+R\n\t\
|
||||
Line and history navigation:\n\
|
||||
\n\t\
|
||||
Return\n\t\t\
|
||||
Enters the current snippet\n\t\
|
||||
Left-arrow or Ctrl+B\n\t\t\
|
||||
Moves backward one character\n\t\
|
||||
Right-arrow or Ctrl+F\n\t\t\
|
||||
Moves forward one character\n\t\
|
||||
Up-arrow or Ctrl+P\n\t\t\
|
||||
Moves up one line, backward through history\n\t\
|
||||
Down arrow or Ctrl+N\n\t\t\
|
||||
Moves down one line, forward through history\n\t\
|
||||
Ctrl+A\n\t\t\
|
||||
Moves to the beginning of the line\n\t\
|
||||
Ctrl+E\n\t\t\
|
||||
Moves to the end of the line\n\t\
|
||||
Meta+B\n\t\t\
|
||||
Moves backward one word\n\t\
|
||||
Meta+F\n\t\t\
|
||||
Moves forward one word\n\t\
|
||||
Ctrl+R\n\t\t\
|
||||
Search backward through history\n\
|
||||
\n\
|
||||
\n\
|
||||
--- Line and history basic editing ---\n\
|
||||
\n\
|
||||
Meta+Return or Ctrl+Return (depending on platform)\n\t\
|
||||
Insert a new line in snippet\n\
|
||||
Ctrl+_ (underscore may require shift key) or Ctrl+X then Ctrl+U\n\t\
|
||||
Undo edit - repeat to undo more edits\n\
|
||||
Delete\n\t\
|
||||
Deletes the character at or after the cursor, depending on the operating system\n\
|
||||
Backspace\n\t\
|
||||
Deletes the character before the cursor\n\
|
||||
Ctrl+K\n\t\
|
||||
Deletes the text from the cursor to the end of the line\n\
|
||||
Meta+D\n\t\
|
||||
Deletes the text from the cursor to the end of the word\n\
|
||||
Ctrl+W\n\t\
|
||||
Deletes the text from the cursor to the previous white space\n\
|
||||
Ctrl+Y\n\t\
|
||||
Pastes the most recently deleted text into the line\n\
|
||||
Meta+Y\n\t\
|
||||
After Ctrl+Y, Meta+Y cycles through previously deleted text\n\
|
||||
Ctrl+X then Ctrl+K\n\t\
|
||||
Line and history basic editing:\n\
|
||||
\n\t\
|
||||
Meta+Return or Ctrl+Return (depending on platform)\n\t\t\
|
||||
Insert a new line in snippet\n\t\
|
||||
Ctrl+_ (underscore may require the Shift key) or Ctrl+X then Ctrl+U\n\t\t\
|
||||
Undo edit - repeat to undo more edits\n\t\
|
||||
Delete\n\t\t\
|
||||
Deletes the character at or after the cursor, depending on the operating system\n\t\
|
||||
Backspace\n\t\t\
|
||||
Deletes the character before the cursor\n\t\
|
||||
Ctrl+K\n\t\t\
|
||||
Deletes the text from the cursor to the end of the line\n\t\
|
||||
Meta+D\n\t\t\
|
||||
Deletes the text from the cursor to the end of the word\n\t\
|
||||
Ctrl+W\n\t\t\
|
||||
Deletes the text from the cursor to the previous white space\n\t\
|
||||
Ctrl+Y\n\t\t\
|
||||
Pastes the most recently deleted text into the line\n\t\
|
||||
Meta+Y\n\t\t\
|
||||
After Ctrl+Y, Meta+Y cycles through previously deleted text\n\t\
|
||||
Ctrl+X then Ctrl+K\n\t\t\
|
||||
Delete whole snippet\n\
|
||||
\n\
|
||||
\n\
|
||||
--- Shortcuts for jshell tool ---\n\
|
||||
\n\
|
||||
Shortcuts for jshell tool:\n\
|
||||
\n\t\
|
||||
For details, see: /help shortcuts\n\
|
||||
\n\
|
||||
Tab\n\t\
|
||||
Complete Java identifier or jshell command\n\
|
||||
Shift+Tab then v\n\t\
|
||||
Convert expression to variable declaration\n\
|
||||
Shift+Tab then m\n\t\
|
||||
Convert statement to method declaration\n\
|
||||
Shift+Tab then i\n\t\
|
||||
Add imports for this identifier\n\
|
||||
\n\t\
|
||||
Tab\n\t\t\
|
||||
Complete Java identifier or jshell command\n\t\
|
||||
Shift+Tab then v\n\t\t\
|
||||
Convert expression to variable declaration\n\t\
|
||||
Shift+Tab then m\n\t\t\
|
||||
Convert statement to method declaration\n\t\
|
||||
Shift+Tab then i\n\t\t\
|
||||
Add imports for this identifier\n\t\
|
||||
\n\
|
||||
\n\
|
||||
--- More line and history editing ---\n\
|
||||
\n\
|
||||
Ctrl+L\n\t\
|
||||
Clear screen and reprint snippet\n\
|
||||
Ctrl+U\n\t\
|
||||
Kill whole line\n\
|
||||
Ctrl+T\n\t\
|
||||
Transpose characters\n\
|
||||
Ctrl+X then Ctrl+B\n\t\
|
||||
Navigate to matching bracket, parenthesis, ...\n\
|
||||
Ctrl+X then =\n\t\
|
||||
Enter show current character position mode\n\
|
||||
Ctrl+X then Ctrl+O\n\t\
|
||||
Toggle overwrite characters vs insert characters\n\
|
||||
Meta+C\n\t\
|
||||
Capitalize word\n\
|
||||
Meta+U\n\t\
|
||||
Convert word to uppercase\n\
|
||||
Meta+L\n\t\
|
||||
Convert word to lowercase\n\
|
||||
Meta+0 through Meta+9 then key\n\t\
|
||||
More line and history editing:\n\
|
||||
\n\t\
|
||||
Ctrl+L\n\t\t\
|
||||
Clear screen and reprint snippet\n\t\
|
||||
Ctrl+U\n\t\t\
|
||||
Kill whole line\n\t\
|
||||
Ctrl+T\n\t\t\
|
||||
Transpose characters\n\t\
|
||||
Ctrl+X then Ctrl+B\n\t\t\
|
||||
Navigate to matching bracket, parenthesis, ...\n\t\
|
||||
Ctrl+X then =\n\t\t\
|
||||
Enter show current character position mode\n\t\
|
||||
Ctrl+X then Ctrl+O\n\t\t\
|
||||
Toggle overwrite characters vs insert characters\n\t\
|
||||
Meta+C\n\t\t\
|
||||
Capitalize word\n\t\
|
||||
Meta+U\n\t\t\
|
||||
Convert word to uppercase\n\t\
|
||||
Meta+L\n\t\t\
|
||||
Convert word to lowercase\n\t\
|
||||
Meta+0 through Meta+9 then key\n\t\t\
|
||||
Repeat the specified number of times\n\
|
||||
\n\
|
||||
Where, for example, "Ctrl+A" means hold down the control key and press A.\n\
|
||||
Where, for example, "Ctrl+A" means hold down the Control key and press A.\n\
|
||||
Where "Meta" is "Alt" on many keyboards.\n\
|
||||
Line editing support is derived from JLine 3.
|
||||
|
||||
@ -672,26 +672,34 @@ help.shortcuts.summary = a description of keystrokes for snippet and command com
|
||||
information access, and automatic code generation
|
||||
help.shortcuts =\
|
||||
Supported shortcuts include:\n\
|
||||
\n\
|
||||
<tab>\n\t\t\
|
||||
\n\t\
|
||||
Tab\n\t\t\
|
||||
After entering the first few letters of a Java identifier,\n\t\t\
|
||||
a jshell tool command, or, in some cases, a jshell tool command argument,\n\t\t\
|
||||
press the <tab> key to complete the input.\n\t\t\
|
||||
If there is more than one completion, then possible completions will be shown.\n\t\t\
|
||||
Will show documentation if available and appropriate.\n\n\
|
||||
Shift-<tab> v\n\t\t\
|
||||
After a complete expression, hold down <shift> while pressing <tab>,\n\t\t\
|
||||
then release and press "v", the expression will be converted to\n\t\t\
|
||||
a variable declaration whose type is based on the type of the expression.\n\n\
|
||||
Shift-<tab> m\n\t\t\
|
||||
After a complete expression or statement, hold down <shift> while pressing <tab>,\n\t\t\
|
||||
then release and press "m", the expression or statement will be converted to\n\t\t\
|
||||
a method declaration. If an expression, the return type is based on the type\n\t\t\
|
||||
of the expression.\n\n\
|
||||
Shift-<tab> i\n\t\t\
|
||||
After an unresolvable identifier, hold down <shift> while pressing <tab>,\n\t\t\
|
||||
then release and press "i", and the jshell tool will propose possible imports\n\t\t\
|
||||
which will resolve the identifier based on the content of the specified classpath.
|
||||
a jshell tool command, or, in some cases, a jshell tool\n\t\t\
|
||||
command argument, press the Tab key to complete the input.\n\t\t\
|
||||
If there is more than one completion, then possible completions\n\t\t\
|
||||
will be shown.\n\t\t\
|
||||
Another Tab will show documentation if available and appropriate.\n\n\t\
|
||||
Shift+Tab then v\n\t\t\
|
||||
After a complete expression, hold down the Shift key while\n\t\t\
|
||||
pressing the Tab key, then release and press the "v" key,\n\t\t\
|
||||
the expression will be converted to a variable declaration \n\t\t\
|
||||
whose type is based on the type of the expression.\n\n\t\
|
||||
Shift+Tab then m\n\t\t\
|
||||
After a complete expression or statement, hold down the\n\t\t\
|
||||
Shift key while pressing the Tab key, then release and press\n\t\t\
|
||||
the "m" key, the expression or statement will be converted\n\t\t\
|
||||
to a method declaration. If it is an expression, the method\n\t\t\
|
||||
return type will be based on the type of the expression.\n\n\t\
|
||||
Shift+Tab then i\n\t\t\
|
||||
After an unresolvable identifier, hold down the Shift key\n\t\t\
|
||||
while pressing the Tab key, then release and press the "i" key,\n\t\t\
|
||||
and the jshell tool will propose possible imports which will\n\t\t\
|
||||
resolve the identifier based on the content of the specified\n\t\t\
|
||||
classpath. Enter the digit corresponding to the desired import,\n\t\t\
|
||||
or press the "0" key to add no imports.\n\
|
||||
\n\
|
||||
For information onother special keys see: /help keys
|
||||
|
||||
help.context.summary = a description of the evaluation context options for /env /reload and /reset
|
||||
help.context =\
|
||||
@ -789,7 +797,7 @@ Startup and error snippets maybe used, e.g.: s3-s9 or e1-e4\n\
|
||||
Any number of IDs or ID ranges may be used, e.g.: /3-7 s4 14-16 e2\n\
|
||||
See also '/help id'.\n\
|
||||
\n\
|
||||
Finally, you can search backwards through history by entering ctrl-R followed by the string to search for.
|
||||
Finally, you can search backwards through history by entering Ctrl+R followed by the string to search for.
|
||||
|
||||
help.set._retain = \
|
||||
The '-retain' option saves a setting so that it is used in future sessions.\n\
|
||||
|
60
test/hotspot/jtreg/compiler/aot/cli/jaotc/AtFileTest.java
Normal file
60
test/hotspot/jtreg/compiler/aot/cli/jaotc/AtFileTest.java
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary check at-file jaotc support
|
||||
* @comment based on CompileClassTest with arguments wrote in 'jaotc.cmd' file
|
||||
* @requires vm.aot
|
||||
* @bug 8215322
|
||||
* @library / /test/lib /testlibrary
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* @build compiler.aot.cli.jaotc.AtFileTest
|
||||
* @run driver ClassFileInstaller compiler.aot.cli.jaotc.data.HelloWorldOne
|
||||
* @run driver compiler.aot.cli.jaotc.AtFileTest
|
||||
*/
|
||||
|
||||
package compiler.aot.cli.jaotc;
|
||||
|
||||
import compiler.aot.cli.jaotc.data.HelloWorldOne;
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import jdk.test.lib.Asserts;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
public class AtFileTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
Path file = Paths.get("jatoc.cmd");
|
||||
Files.write(file, List.of("--class-name",
|
||||
JaotcTestHelper.getClassAotCompilationName(HelloWorldOne.class)));
|
||||
OutputAnalyzer oa = JaotcTestHelper.compileLibrary("@" + file.toString());
|
||||
oa.shouldHaveExitValue(0);
|
||||
File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH);
|
||||
Asserts.assertTrue(compiledLibrary.exists(), "Compiled library file missing");
|
||||
Asserts.assertGT(compiledLibrary.length(), 0L, "Unexpected compiled library size");
|
||||
JaotcTestHelper.checkLibraryUsage(HelloWorldOne.class.getName());
|
||||
}
|
||||
}
|
@ -27,6 +27,9 @@
|
||||
* @summary Implement vectorization optimizations in hotspot-server
|
||||
*
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m compiler.c2.cr6340864.TestByteVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=8 compiler.c2.cr6340864.TestByteVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=16 compiler.c2.cr6340864.TestByteVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=32 compiler.c2.cr6340864.TestByteVect
|
||||
*/
|
||||
|
||||
package compiler.c2.cr6340864;
|
||||
|
@ -27,6 +27,9 @@
|
||||
* @summary Implement vectorization optimizations in hotspot-server
|
||||
*
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m compiler.c2.cr6340864.TestDoubleVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=8 compiler.c2.cr6340864.TestDoubleVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=16 compiler.c2.cr6340864.TestDoubleVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=32 compiler.c2.cr6340864.TestDoubleVect
|
||||
*/
|
||||
|
||||
package compiler.c2.cr6340864;
|
||||
|
@ -27,6 +27,9 @@
|
||||
* @summary Implement vectorization optimizations in hotspot-server
|
||||
*
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m compiler.c2.cr6340864.TestFloatVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=8 compiler.c2.cr6340864.TestFloatVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=16 compiler.c2.cr6340864.TestFloatVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=32 compiler.c2.cr6340864.TestFloatVect
|
||||
*/
|
||||
|
||||
package compiler.c2.cr6340864;
|
||||
|
@ -27,6 +27,9 @@
|
||||
* @summary Implement vectorization optimizations in hotspot-server
|
||||
*
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m compiler.c2.cr6340864.TestIntVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=8 compiler.c2.cr6340864.TestIntVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=16 compiler.c2.cr6340864.TestIntVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=32 compiler.c2.cr6340864.TestIntVect
|
||||
*/
|
||||
|
||||
package compiler.c2.cr6340864;
|
||||
|
@ -27,6 +27,9 @@
|
||||
* @summary Implement vectorization optimizations in hotspot-server
|
||||
*
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m compiler.c2.cr6340864.TestLongVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=8 compiler.c2.cr6340864.TestLongVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=16 compiler.c2.cr6340864.TestLongVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=32 compiler.c2.cr6340864.TestLongVect
|
||||
*/
|
||||
|
||||
package compiler.c2.cr6340864;
|
||||
|
@ -27,6 +27,9 @@
|
||||
* @summary Implement vectorization optimizations in hotspot-server
|
||||
*
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m compiler.c2.cr6340864.TestShortVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=8 compiler.c2.cr6340864.TestShortVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=16 compiler.c2.cr6340864.TestShortVect
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=32 compiler.c2.cr6340864.TestShortVect
|
||||
*/
|
||||
|
||||
package compiler.c2.cr6340864;
|
||||
|
@ -27,6 +27,9 @@
|
||||
* @summary incorrect results of char vectors right shift operaiton
|
||||
*
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m compiler.codegen.TestCharVect2
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=8 compiler.codegen.TestCharVect2
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=16 compiler.codegen.TestCharVect2
|
||||
* @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=32 compiler.codegen.TestCharVect2
|
||||
*/
|
||||
|
||||
package compiler.codegen;
|
||||
|
57
test/hotspot/jtreg/compiler/loopopts/Test8211698.java
Normal file
57
test/hotspot/jtreg/compiler/loopopts/Test8211698.java
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8211698
|
||||
* @summary Crash in C2 compiled code during execution of double array heavy processing code
|
||||
*
|
||||
* @run main/othervm -XX:CompileOnly=Test8211698.test Test8211698
|
||||
*
|
||||
*/
|
||||
|
||||
public class Test8211698 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Test8211698 issue = new Test8211698();
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
issue.test();
|
||||
}
|
||||
}
|
||||
|
||||
public void test() {
|
||||
int[] iarr1 = new int[888];
|
||||
for (int i = 5; i > 0; i--) {
|
||||
for (int j = 0; j <= i - 1; j++) {
|
||||
int istep = 2 * j - i;
|
||||
int iadj = 0;
|
||||
if (istep < 0) {
|
||||
iadj = iarr1[-istep];
|
||||
} else {
|
||||
iadj = iarr1[istep];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
97
test/hotspot/jtreg/compiler/loopopts/TestSplitIfOpaque1.java
Normal file
97
test/hotspot/jtreg/compiler/loopopts/TestSplitIfOpaque1.java
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8214994
|
||||
* @summary The split-if optimization fails because an unexpected Opaque1 is encountered.
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseOnStackReplacement -XX:-BackgroundCompilation
|
||||
* compiler.loopopts.TestSplitIfOpaque1
|
||||
*/
|
||||
|
||||
package compiler.loopopts;
|
||||
|
||||
public class TestSplitIfOpaque1 {
|
||||
|
||||
static class MyClass {
|
||||
int f;
|
||||
MyClass(int f) {
|
||||
this.f = f;
|
||||
}
|
||||
}
|
||||
|
||||
// The inner loop is found to be a counted loop and a loop limit check
|
||||
// is added by updating the Opaque1 input of the predicate template.
|
||||
// This Opaque1 node is then pushed upwards to before the predicates of
|
||||
// the outer loop and ends up right after the second 'if (b)'.
|
||||
// The split-if optimization kicks in and splits the first predicate of
|
||||
// the outer loop (an "obj != NULL" check) through the 'if (b)' region.
|
||||
// We fail because the region contains an unexpected Opaque1 node.
|
||||
static int test1(boolean b, int limit, MyClass obj) {
|
||||
int res = 0;
|
||||
MyClass notNull = new MyClass(42);
|
||||
if (b) {
|
||||
limit = 100;
|
||||
}
|
||||
if (b) {
|
||||
obj = notNull;
|
||||
}
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
res += obj.f;
|
||||
for (int j = 0; j <= limit; ++j) {
|
||||
// Empty
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// Same as test1 but triggers slightly different failure mode
|
||||
static int test2(boolean b, int limit, MyClass obj, int[] array) {
|
||||
int res = 0;
|
||||
MyClass notNull = new MyClass(12);
|
||||
if (b) {
|
||||
limit = 100;
|
||||
}
|
||||
if (b) {
|
||||
obj = notNull;
|
||||
}
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
res += obj.f;
|
||||
for (int j = 0; j <= limit; ++j) {
|
||||
array[j] = j;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
MyClass obj = new MyClass(42);
|
||||
int[] array = new int[101];
|
||||
for (int i = 0; i < 20_000; i++) {
|
||||
test1(true, 50, obj);
|
||||
test1(false, 100, obj);
|
||||
test2(true, 50, obj, array);
|
||||
test2(false, 100, obj, array);
|
||||
}
|
||||
}
|
||||
}
|
@ -30,7 +30,6 @@ package MyPackage;
|
||||
* @summary Verifies the JVMTI Heap Monitor Thread information sanity.
|
||||
* @compile HeapMonitorThreadTest.java
|
||||
* @run main/othervm/native -Xmx512m -agentlib:HeapMonitorTest MyPackage.HeapMonitorThreadTest
|
||||
* @requires vm.gc != "Z"
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user