Compare commits

...

20 Commits

Author SHA1 Message Date
Stuart Marks
5bcea92eaa 8338140: (str) Add notes to String.trim and String.isEmpty pointing to newer APIs
Reviewed-by: naoto, bpb, liach
Backport-of: 06d804a0f0
2025-06-17 20:45:27 +00:00
Damon Fenacci
cc4e9716ac 8358129: compiler/startup/StartupOutput.java runs into out of memory on Windows after JDK-8347406
Reviewed-by: shade
Backport-of: 534a8605e5
2025-06-17 13:10:06 +00:00
Roland Westrelin
46cfc1e194 8358334: C2/Shenandoah: incorrect execution with Unsafe
Reviewed-by: thartmann
Backport-of: 1fcede053c
2025-06-17 08:06:58 +00:00
Rajan Halade
ae71782e77 8359170: Add 2 TLS and 2 CS Sectigo roots
Reviewed-by: mullan
Backport-of: 9586817cea
2025-06-17 06:10:35 +00:00
Ioi Lam
753700182d 8355556: JVM crash because archived method handle intrinsics are not restored
Reviewed-by: shade
Backport-of: 366650a438
2025-06-17 04:36:41 +00:00
SendaoYan
eb727dcb51 8359272: Several vmTestbase/compact tests timed out on large memory machine
Reviewed-by: ayang
Backport-of: a0fb35c837
2025-06-17 00:43:52 +00:00
Johannes Bechberger
b6cacfcbc8 8359135: New test TestCPUTimeSampleThrottling fails intermittently
Reviewed-by: mdoerr
Backport-of: 3f0fef2c9c
2025-06-16 16:20:54 +00:00
Hamlin Li
d870a48880 8358892: RISC-V: jvm crash when running dacapo sunflow after JDK-8352504
8359045: RISC-V: construct test to verify invocation of C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge/gt

Reviewed-by: fyang
Backport-of: 9d060574e5
2025-06-16 11:18:32 +00:00
Fernando Guallini
2ea2f74f92 8358171: Additional code coverage for PEM API
Reviewed-by: rhalade, ascarpino
Backport-of: b2e7cda6a0
2025-06-16 09:54:18 +00:00
Alan Bateman
077ce2edc7 8358764: (sc) SocketChannel.close when thread blocked in read causes connection to be reset (win)
Reviewed-by: iris, jpai
Backport-of: e5196fc24d
2025-06-16 09:19:56 +00:00
Tobias Hartmann
2a3294571a 8359327: Incorrect AVX3Threshold results into code buffer overflows on APX targets
Reviewed-by: chagedorn
Backport-of: e7f63ba310
2025-06-16 08:48:49 +00:00
SendaoYan
3877746eb9 8359181: Error messages generated by configure --help after 8301197
Reviewed-by: ihse
Backport-of: 7b7136b4ec
2025-06-15 12:25:17 +00:00
Tobias Hartmann
3bd80fe3ba 8357782: JVM JIT Causes Static Initialization Order Issue
Reviewed-by: shade
Backport-of: e8ef93ae9d
2025-06-15 09:05:56 +00:00
Tobias Hartmann
03232d4a5d 8359200: Memory corruption in MStack::push
Reviewed-by: epeter, shade
Backport-of: ed39e17e34
2025-06-15 09:04:55 +00:00
Daniel Fuchs
4111730845 8359364: java/net/URL/EarlyOrDelayedParsing test fails intermittently
Reviewed-by: alanb
Backport-of: 57cabc6d74
2025-06-13 16:54:40 +00:00
Kevin Walls
74ea38e406 8358701: Remove misleading javax.management.remote API doc wording about JMX spec, and historic link to JMXMP
Reviewed-by: alanb
Backport-of: 66535fe26d
2025-06-13 14:28:14 +00:00
Tobias Hartmann
839a91e14b 8357982: Fix several failing BMI tests with -XX:+UseAPX
Reviewed-by: chagedorn
Backport-of: c98dffa186
2025-06-12 11:11:41 +00:00
Daniel Fuchs
aa4f79eaec 8358617: java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java fails with 403 due to system proxies
Reviewed-by: jpai
Backport-of: a377773fa7
2025-06-11 16:22:34 +00:00
Stuart Marks
c7df72ff0f 8358809: Improve link to stdin.encoding from java.lang.IO
Reviewed-by: naoto
Backport-of: d024f58e61
2025-06-07 00:56:45 +00:00
Rajan Halade
80e066e733 8345414: Google CAInterop test failures
Reviewed-by: weijun
Backport-of: 8e9ba788ae
2025-06-06 21:31:33 +00:00
66 changed files with 2829 additions and 247 deletions

View File

@@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2012, 2025, 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
@@ -366,7 +366,7 @@ EOT
# Print additional help, e.g. a list of toolchains and JVM features.
# This must be done by the autoconf script.
( CONFIGURE_PRINT_ADDITIONAL_HELP=true . $generated_script PRINTF=printf )
( CONFIGURE_PRINT_ADDITIONAL_HELP=true . $generated_script PRINTF=printf ECHO=echo )
cat <<EOT

View File

@@ -2170,15 +2170,13 @@ void C2_MacroAssembler::enc_cmove_cmp_fp(int cmpFlag, FloatRegister op1, FloatRe
cmov_cmp_fp_le(op1, op2, dst, src, is_single);
break;
case BoolTest::ge:
assert(false, "Should go to BoolTest::le case");
ShouldNotReachHere();
cmov_cmp_fp_ge(op1, op2, dst, src, is_single);
break;
case BoolTest::lt:
cmov_cmp_fp_lt(op1, op2, dst, src, is_single);
break;
case BoolTest::gt:
assert(false, "Should go to BoolTest::lt case");
ShouldNotReachHere();
cmov_cmp_fp_gt(op1, op2, dst, src, is_single);
break;
default:
assert(false, "unsupported compare condition");

View File

@@ -1268,12 +1268,19 @@ void MacroAssembler::cmov_gtu(Register cmp1, Register cmp2, Register dst, Regist
}
// ----------- cmove, compare float -----------
//
// For CmpF/D + CMoveI/L, ordered ones are quite straight and simple,
// so, just list behaviour of unordered ones as follow.
//
// Set dst (CMoveI (Binary cop (CmpF/D op1 op2)) (Binary dst src))
// (If one or both inputs to the compare are NaN, then)
// 1. (op1 lt op2) => true => CMove: dst = src
// 2. (op1 le op2) => true => CMove: dst = src
// 3. (op1 gt op2) => false => CMove: dst = dst
// 4. (op1 ge op2) => false => CMove: dst = dst
// 5. (op1 eq op2) => false => CMove: dst = dst
// 6. (op1 ne op2) => true => CMove: dst = src
// Move src to dst only if cmp1 == cmp2,
// otherwise leave dst unchanged, including the case where one of them is NaN.
// Clarification:
// java code : cmp1 != cmp2 ? dst : src
// transformed to : CMove dst, (cmp1 eq cmp2), dst, src
void MacroAssembler::cmov_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
if (UseZicond) {
if (is_single) {
@@ -1289,7 +1296,7 @@ void MacroAssembler::cmov_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Regi
Label no_set;
if (is_single) {
// jump if cmp1 != cmp2, including the case of NaN
// not jump (i.e. move src to dst) if cmp1 == cmp2
// fallthrough (i.e. move src to dst) if cmp1 == cmp2
float_bne(cmp1, cmp2, no_set);
} else {
double_bne(cmp1, cmp2, no_set);
@@ -1298,11 +1305,6 @@ void MacroAssembler::cmov_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Regi
bind(no_set);
}
// Keep dst unchanged only if cmp1 == cmp2,
// otherwise move src to dst, including the case where one of them is NaN.
// Clarification:
// java code : cmp1 == cmp2 ? dst : src
// transformed to : CMove dst, (cmp1 ne cmp2), dst, src
void MacroAssembler::cmov_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
if (UseZicond) {
if (is_single) {
@@ -1318,7 +1320,7 @@ void MacroAssembler::cmov_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, Regi
Label no_set;
if (is_single) {
// jump if cmp1 == cmp2
// not jump (i.e. move src to dst) if cmp1 != cmp2, including the case of NaN
// fallthrough (i.e. move src to dst) if cmp1 != cmp2, including the case of NaN
float_beq(cmp1, cmp2, no_set);
} else {
double_beq(cmp1, cmp2, no_set);
@@ -1327,14 +1329,6 @@ void MacroAssembler::cmov_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, Regi
bind(no_set);
}
// When cmp1 <= cmp2 or any of them is NaN then dst = src, otherwise, dst = dst
// Clarification
// scenario 1:
// java code : cmp2 < cmp1 ? dst : src
// transformed to : CMove dst, (cmp1 le cmp2), dst, src
// scenario 2:
// java code : cmp1 > cmp2 ? dst : src
// transformed to : CMove dst, (cmp1 le cmp2), dst, src
void MacroAssembler::cmov_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
if (UseZicond) {
if (is_single) {
@@ -1350,7 +1344,7 @@ void MacroAssembler::cmov_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, Regi
Label no_set;
if (is_single) {
// jump if cmp1 > cmp2
// not jump (i.e. move src to dst) if cmp1 <= cmp2 or either is NaN
// fallthrough (i.e. move src to dst) if cmp1 <= cmp2 or either is NaN
float_bgt(cmp1, cmp2, no_set);
} else {
double_bgt(cmp1, cmp2, no_set);
@@ -1359,14 +1353,30 @@ void MacroAssembler::cmov_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, Regi
bind(no_set);
}
// When cmp1 < cmp2 or any of them is NaN then dst = src, otherwise, dst = dst
// Clarification
// scenario 1:
// java code : cmp2 <= cmp1 ? dst : src
// transformed to : CMove dst, (cmp1 lt cmp2), dst, src
// scenario 2:
// java code : cmp1 >= cmp2 ? dst : src
// transformed to : CMove dst, (cmp1 lt cmp2), dst, src
void MacroAssembler::cmov_cmp_fp_ge(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
if (UseZicond) {
if (is_single) {
fle_s(t0, cmp2, cmp1);
} else {
fle_d(t0, cmp2, cmp1);
}
czero_nez(dst, dst, t0);
czero_eqz(t0 , src, t0);
orr(dst, dst, t0);
return;
}
Label no_set;
if (is_single) {
// jump if cmp1 < cmp2 or either is NaN
// fallthrough (i.e. move src to dst) if cmp1 >= cmp2
float_blt(cmp1, cmp2, no_set, false, true);
} else {
double_blt(cmp1, cmp2, no_set, false, true);
}
mv(dst, src);
bind(no_set);
}
void MacroAssembler::cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
if (UseZicond) {
if (is_single) {
@@ -1382,7 +1392,7 @@ void MacroAssembler::cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Regi
Label no_set;
if (is_single) {
// jump if cmp1 >= cmp2
// not jump (i.e. move src to dst) if cmp1 < cmp2 or either is NaN
// fallthrough (i.e. move src to dst) if cmp1 < cmp2 or either is NaN
float_bge(cmp1, cmp2, no_set);
} else {
double_bge(cmp1, cmp2, no_set);
@@ -1391,6 +1401,30 @@ void MacroAssembler::cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Regi
bind(no_set);
}
void MacroAssembler::cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
if (UseZicond) {
if (is_single) {
flt_s(t0, cmp2, cmp1);
} else {
flt_d(t0, cmp2, cmp1);
}
czero_nez(dst, dst, t0);
czero_eqz(t0 , src, t0);
orr(dst, dst, t0);
return;
}
Label no_set;
if (is_single) {
// jump if cmp1 <= cmp2 or either is NaN
// fallthrough (i.e. move src to dst) if cmp1 > cmp2
float_ble(cmp1, cmp2, no_set, false, true);
} else {
double_ble(cmp1, cmp2, no_set, false, true);
}
mv(dst, src);
bind(no_set);
}
// Float compare branch instructions
#define INSN(NAME, FLOATCMP, BRANCH) \

View File

@@ -660,7 +660,9 @@ class MacroAssembler: public Assembler {
void cmov_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
void cmov_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
void cmov_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
void cmov_cmp_fp_ge(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
void cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
void cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
public:
// We try to follow risc-v asm menomics.

View File

@@ -239,7 +239,7 @@
do_arch_blob, \
do_arch_entry, \
do_arch_entry_init) \
do_arch_blob(final, 31000 \
do_arch_blob(final, 33000 \
WINDOWS_ONLY(+22000) ZGC_ONLY(+20000)) \
#endif // CPU_X86_STUBDECLARATIONS_HPP

View File

@@ -2111,7 +2111,7 @@ bool VM_Version::is_intel_cascade_lake() {
// has improved implementation of 64-byte load/stores and so the default
// threshold is set to 0 for these platforms.
int VM_Version::avx3_threshold() {
return (is_intel_family_core() &&
return (is_intel_server_family() &&
supports_serialize() &&
FLAG_IS_DEFAULT(AVX3Threshold)) ? 0 : AVX3Threshold;
}

View File

@@ -10527,7 +10527,8 @@ instruct xorI_rReg_im1_ndd(rRegI dst, rRegI src, immI_M1 imm)
// Xor Register with Immediate
instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
%{
predicate(!UseAPX);
// Strict predicate check to make selection of xorI_rReg_im1 cost agnostic if immI src is -1.
predicate(!UseAPX && n->in(2)->bottom_type()->is_int()->get_con() != -1);
match(Set dst (XorI dst src));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
@@ -10541,7 +10542,8 @@ instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
instruct xorI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
%{
predicate(UseAPX);
// Strict predicate check to make selection of xorI_rReg_im1_ndd cost agnostic if immI src2 is -1.
predicate(UseAPX && n->in(2)->bottom_type()->is_int()->get_con() != -1);
match(Set dst (XorI src1 src2));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
@@ -10559,6 +10561,7 @@ instruct xorI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr)
predicate(UseAPX);
match(Set dst (XorI (LoadI src1) src2));
effect(KILL cr);
ins_cost(150);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
format %{ "exorl $dst, $src1, $src2\t# int ndd" %}
@@ -11201,7 +11204,8 @@ instruct xorL_rReg_im1_ndd(rRegL dst,rRegL src, immL_M1 imm)
// Xor Register with Immediate
instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
%{
predicate(!UseAPX);
// Strict predicate check to make selection of xorL_rReg_im1 cost agnostic if immL32 src is -1.
predicate(!UseAPX && n->in(2)->bottom_type()->is_long()->get_con() != -1L);
match(Set dst (XorL dst src));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
@@ -11215,7 +11219,8 @@ instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
instruct xorL_rReg_rReg_imm(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr)
%{
predicate(UseAPX);
// Strict predicate check to make selection of xorL_rReg_im1_ndd cost agnostic if immL32 src2 is -1.
predicate(UseAPX && n->in(2)->bottom_type()->is_long()->get_con() != -1L);
match(Set dst (XorL src1 src2));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
@@ -11234,6 +11239,7 @@ instruct xorL_rReg_mem_imm(rRegL dst, memory src1, immL32 src2, rFlagsReg cr)
match(Set dst (XorL (LoadL src1) src2));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
ins_cost(150);
format %{ "exorq $dst, $src1, $src2\t# long ndd" %}
ins_encode %{

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2025, 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
@@ -187,7 +187,13 @@ class ValueNumberingVisitor: public InstructionVisitor {
void do_Convert (Convert* x) { /* nothing to do */ }
void do_NullCheck (NullCheck* x) { /* nothing to do */ }
void do_TypeCast (TypeCast* x) { /* nothing to do */ }
void do_NewInstance (NewInstance* x) { /* nothing to do */ }
void do_NewInstance (NewInstance* x) {
ciInstanceKlass* c = x->klass();
if (c != nullptr && !c->is_initialized() &&
(!c->is_loaded() || c->has_class_initializer())) {
kill_memory();
}
}
void do_NewTypeArray (NewTypeArray* x) { /* nothing to do */ }
void do_NewObjectArray (NewObjectArray* x) { /* nothing to do */ }
void do_NewMultiArray (NewMultiArray* x) { /* nothing to do */ }

View File

@@ -549,6 +549,11 @@ bool ciInstanceKlass::compute_has_trusted_loader() {
return java_lang_ClassLoader::is_trusted_loader(loader_oop);
}
bool ciInstanceKlass::has_class_initializer() {
VM_ENTRY_MARK;
return get_instanceKlass()->class_initializer() != nullptr;
}
// ------------------------------------------------------------------
// ciInstanceKlass::find_method
//

View File

@@ -231,6 +231,8 @@ public:
ciInstanceKlass* unique_concrete_subklass();
bool has_finalizable_subclass();
bool has_class_initializer();
bool contains_field_offset(int offset);
// Get the instance of java.lang.Class corresponding to

View File

@@ -625,6 +625,34 @@ void ShenandoahBarrierC2Support::verify(RootNode* root) {
}
#endif
bool ShenandoahBarrierC2Support::is_anti_dependent_load_at_control(PhaseIdealLoop* phase, Node* maybe_load, Node* store,
Node* control) {
return maybe_load->is_Load() && phase->C->can_alias(store->adr_type(), phase->C->get_alias_index(maybe_load->adr_type())) &&
phase->ctrl_or_self(maybe_load) == control;
}
void ShenandoahBarrierC2Support::maybe_push_anti_dependent_loads(PhaseIdealLoop* phase, Node* maybe_store, Node* control, Unique_Node_List &wq) {
if (!maybe_store->is_Store() && !maybe_store->is_LoadStore()) {
return;
}
Node* mem = maybe_store->in(MemNode::Memory);
for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
Node* u = mem->fast_out(i);
if (is_anti_dependent_load_at_control(phase, u, maybe_store, control)) {
wq.push(u);
}
}
}
void ShenandoahBarrierC2Support::push_data_inputs_at_control(PhaseIdealLoop* phase, Node* n, Node* ctrl, Unique_Node_List &wq) {
for (uint i = 0; i < n->req(); i++) {
Node* in = n->in(i);
if (in != nullptr && phase->has_ctrl(in) && phase->get_ctrl(in) == ctrl) {
wq.push(in);
}
}
}
bool ShenandoahBarrierC2Support::is_dominator_same_ctrl(Node* c, Node* d, Node* n, PhaseIdealLoop* phase) {
// That both nodes have the same control is not sufficient to prove
// domination, verify that there's no path from d to n
@@ -639,22 +667,9 @@ bool ShenandoahBarrierC2Support::is_dominator_same_ctrl(Node* c, Node* d, Node*
if (m->is_Phi() && m->in(0)->is_Loop()) {
assert(phase->ctrl_or_self(m->in(LoopNode::EntryControl)) != c, "following loop entry should lead to new control");
} else {
if (m->is_Store() || m->is_LoadStore()) {
// Take anti-dependencies into account
Node* mem = m->in(MemNode::Memory);
for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
Node* u = mem->fast_out(i);
if (u->is_Load() && phase->C->can_alias(m->adr_type(), phase->C->get_alias_index(u->adr_type())) &&
phase->ctrl_or_self(u) == c) {
wq.push(u);
}
}
}
for (uint i = 0; i < m->req(); i++) {
if (m->in(i) != nullptr && phase->ctrl_or_self(m->in(i)) == c) {
wq.push(m->in(i));
}
}
// Take anti-dependencies into account
maybe_push_anti_dependent_loads(phase, m, c, wq);
push_data_inputs_at_control(phase, m, c, wq);
}
}
return true;
@@ -1006,7 +1021,20 @@ void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node* lo
phase->register_new_node(val, ctrl);
}
void ShenandoahBarrierC2Support::fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase) {
void ShenandoahBarrierC2Support::collect_nodes_above_barrier(Unique_Node_List &nodes_above_barrier, PhaseIdealLoop* phase, Node* ctrl, Node* init_raw_mem) {
nodes_above_barrier.clear();
if (phase->has_ctrl(init_raw_mem) && phase->get_ctrl(init_raw_mem) == ctrl && !init_raw_mem->is_Phi()) {
nodes_above_barrier.push(init_raw_mem);
}
for (uint next = 0; next < nodes_above_barrier.size(); next++) {
Node* n = nodes_above_barrier.at(next);
// Take anti-dependencies into account
maybe_push_anti_dependent_loads(phase, n, ctrl, nodes_above_barrier);
push_data_inputs_at_control(phase, n, ctrl, nodes_above_barrier);
}
}
void ShenandoahBarrierC2Support::fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& nodes_above_barrier, uint last, PhaseIdealLoop* phase) {
Node* ctrl = phase->get_ctrl(barrier);
Node* init_raw_mem = fixer.find_mem(ctrl, barrier);
@@ -1017,30 +1045,17 @@ void ShenandoahBarrierC2Support::fix_ctrl(Node* barrier, Node* region, const Mem
// control will be after the expanded barrier. The raw memory (if
// its memory is control dependent on the barrier's input control)
// must stay above the barrier.
uses_to_ignore.clear();
if (phase->has_ctrl(init_raw_mem) && phase->get_ctrl(init_raw_mem) == ctrl && !init_raw_mem->is_Phi()) {
uses_to_ignore.push(init_raw_mem);
}
for (uint next = 0; next < uses_to_ignore.size(); next++) {
Node *n = uses_to_ignore.at(next);
for (uint i = 0; i < n->req(); i++) {
Node* in = n->in(i);
if (in != nullptr && phase->has_ctrl(in) && phase->get_ctrl(in) == ctrl) {
uses_to_ignore.push(in);
}
}
}
collect_nodes_above_barrier(nodes_above_barrier, phase, ctrl, init_raw_mem);
for (DUIterator_Fast imax, i = ctrl->fast_outs(imax); i < imax; i++) {
Node* u = ctrl->fast_out(i);
if (u->_idx < last &&
u != barrier &&
!u->depends_only_on_test() && // preserve dependency on test
!uses_to_ignore.member(u) &&
!nodes_above_barrier.member(u) &&
(u->in(0) != ctrl || (!u->is_Region() && !u->is_Phi())) &&
(ctrl->Opcode() != Op_CatchProj || u->Opcode() != Op_CreateEx)) {
Node* old_c = phase->ctrl_or_self(u);
Node* c = old_c;
if (c != ctrl ||
if (old_c != ctrl ||
is_dominator_same_ctrl(old_c, barrier, u, phase) ||
ShenandoahBarrierSetC2::is_shenandoah_state_load(u)) {
phase->igvn().rehash_node_delayed(u);
@@ -1315,7 +1330,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
// Expand load-reference-barriers
MemoryGraphFixer fixer(Compile::AliasIdxRaw, true, phase);
Unique_Node_List uses_to_ignore;
Unique_Node_List nodes_above_barriers;
for (int i = state->load_reference_barriers_count() - 1; i >= 0; i--) {
ShenandoahLoadReferenceBarrierNode* lrb = state->load_reference_barrier(i);
uint last = phase->C->unique();
@@ -1410,7 +1425,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
Node* out_val = val_phi;
phase->register_new_node(val_phi, region);
fix_ctrl(lrb, region, fixer, uses, uses_to_ignore, last, phase);
fix_ctrl(lrb, region, fixer, uses, nodes_above_barriers, last, phase);
ctrl = orig_ctrl;

View File

@@ -62,8 +62,12 @@ private:
PhaseIdealLoop* phase, int flags);
static void call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr,
DecoratorSet decorators, PhaseIdealLoop* phase);
static void collect_nodes_above_barrier(Unique_Node_List &nodes_above_barrier, PhaseIdealLoop* phase, Node* ctrl,
Node* init_raw_mem);
static void test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase);
static void fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase);
static void fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& nodes_above_barrier, uint last, PhaseIdealLoop* phase);
static Node* get_load_addr(PhaseIdealLoop* phase, VectorSet& visited, Node* lrb);
public:
@@ -76,6 +80,11 @@ public:
static bool expand(Compile* C, PhaseIterGVN& igvn);
static void pin_and_expand(PhaseIdealLoop* phase);
static void push_data_inputs_at_control(PhaseIdealLoop* phase, Node* n, Node* ctrl,
Unique_Node_List &wq);
static bool is_anti_dependent_load_at_control(PhaseIdealLoop* phase, Node* maybe_load, Node* store, Node* control);
static void maybe_push_anti_dependent_loads(PhaseIdealLoop* phase, Node* maybe_store, Node* control, Unique_Node_List &wq);
#ifdef ASSERT
static void verify(RootNode* root);
#endif

View File

@@ -47,7 +47,6 @@ void VectorSet::init(Arena* arena) {
// Expand the existing set to a bigger size
void VectorSet::grow(uint new_word_capacity) {
_nesting.check(_set_arena); // Check if a potential reallocation in the arena is safe
assert(new_word_capacity >= _size, "Should have been checked before, use maybe_grow?");
assert(new_word_capacity < (1U << 30), "");
uint x = next_power_of_2(new_word_capacity);

View File

@@ -52,6 +52,7 @@ private:
// Grow vector to required word capacity
void maybe_grow(uint new_word_capacity) {
_nesting.check(_set_arena); // Check if a potential reallocation in the arena is safe
if (new_word_capacity >= _size) {
grow(new_word_capacity);
}

View File

@@ -37,11 +37,8 @@
#include "utilities/copy.hpp"
#include "utilities/powerOfTwo.hpp"
void Block_Array::grow( uint i ) {
_nesting.check(_arena); // Check if a potential reallocation in the arena is safe
if (i < Max()) {
return; // No need to grow
}
void Block_Array::grow(uint i) {
assert(i >= Max(), "Should have been checked before, use maybe_grow?");
DEBUG_ONLY(_limit = i+1);
if( i < _size ) return;
if( !_size ) {

View File

@@ -53,7 +53,13 @@ class Block_Array : public ArenaObj {
ReallocMark _nesting; // Safety checks for arena reallocation
protected:
Block **_blocks;
void grow( uint i ); // Grow array node to fit
void maybe_grow(uint i) {
_nesting.check(_arena); // Check if a potential reallocation in the arena is safe
if (i >= Max()) {
grow(i);
}
}
void grow(uint i); // Grow array node to fit
public:
Block_Array(Arena *a) : _size(OptoBlockListSize), _arena(a) {
@@ -68,7 +74,7 @@ public:
Block *operator[] ( uint i ) const // Lookup, or assert for not mapped
{ assert( i < Max(), "oob" ); return _blocks[i]; }
// Extend the mapping: index i maps to Block *n.
void map( uint i, Block *n ) { grow(i); _blocks[i] = n; }
void map( uint i, Block *n ) { maybe_grow(i); _blocks[i] = n; }
uint Max() const { DEBUG_ONLY(return _limit); return _size; }
};

View File

@@ -65,13 +65,8 @@ public:
Node_Stack::push(n, (uint)ns);
}
void push(Node *n, Node_State ns, Node *parent, int indx) {
++_inode_top;
if ((_inode_top + 1) >= _inode_max) grow();
_inode_top->node = parent;
_inode_top->indx = (uint)indx;
++_inode_top;
_inode_top->node = n;
_inode_top->indx = (uint)ns;
Node_Stack::push(parent, (uint)indx);
Node_Stack::push(n, (uint)ns);
}
Node *parent() {
pop();

View File

@@ -2798,7 +2798,6 @@ const RegMask &Node::in_RegMask(uint) const {
}
void Node_Array::grow(uint i) {
_nesting.check(_a); // Check if a potential reallocation in the arena is safe
assert(i >= _max, "Should have been checked before, use maybe_grow?");
assert(_max > 0, "invariant");
uint old = _max;
@@ -3038,10 +3037,6 @@ void Unique_Node_List::remove_useless_nodes(VectorSet &useful) {
//=============================================================================
void Node_Stack::grow() {
_nesting.check(_a); // Check if a potential reallocation in the arena is safe
if (_inode_top < _inode_max) {
return; // No need to grow
}
size_t old_top = pointer_delta(_inode_top,_inodes,sizeof(INode)); // save _top
size_t old_max = pointer_delta(_inode_max,_inodes,sizeof(INode));
size_t max = old_max << 1; // max * 2

View File

@@ -1633,6 +1633,7 @@ protected:
// Grow array to required capacity
void maybe_grow(uint i) {
_nesting.check(_a); // Check if a potential reallocation in the arena is safe
if (i >= _max) {
grow(i);
}
@@ -1884,7 +1885,15 @@ protected:
INode *_inodes; // Array storage for the stack
Arena *_a; // Arena to allocate in
ReallocMark _nesting; // Safety checks for arena reallocation
void maybe_grow() {
_nesting.check(_a); // Check if a potential reallocation in the arena is safe
if (_inode_top >= _inode_max) {
grow();
}
}
void grow();
public:
Node_Stack(int size) {
size_t max = (size > OptoNodeListSize) ? size : OptoNodeListSize;
@@ -1907,7 +1916,7 @@ public:
}
void push(Node *n, uint i) {
++_inode_top;
grow();
maybe_grow();
INode *top = _inode_top; // optimization
top->node = n;
top->indx = i;

View File

@@ -771,8 +771,8 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
#endif
if (CDSConfig::is_using_aot_linked_classes()) {
AOTLinkedClassBulkLoader::finish_loading_javabase_classes(CHECK_JNI_ERR);
SystemDictionary::restore_archived_method_handle_intrinsics();
AOTLinkedClassBulkLoader::finish_loading_javabase_classes(CHECK_JNI_ERR);
}
// Start string deduplication thread if requested.

View File

@@ -38,7 +38,7 @@ import java.nio.charset.StandardCharsets;
* <p>
* The {@link #readln()} and {@link #readln(String)} methods decode bytes read from
* {@code System.in} into characters. The charset used for decoding is specified by the
* {@link System#getProperties stdin.encoding} property. If this property is not present,
* {@link System##stdin.encoding stdin.encoding} property. If this property is not present,
* or if the charset it names cannot be loaded, then UTF-8 is used instead. Decoding
* always replaces malformed and unmappable byte sequences with the charset's default
* replacement string.

View File

@@ -1589,6 +1589,11 @@ public final class String
* @return {@code true} if {@link #length()} is {@code 0}, otherwise
* {@code false}
*
* @apiNote
* To determine whether a string contains only
* {@linkplain Character#isWhitespace(int) white space}, use
* {@link #isBlank() isBlank}.
*
* @since 1.6
*/
@Override
@@ -3827,9 +3832,13 @@ public final class String
* begins with the character at index <i>k</i> and ends with the
* character at index <i>m</i>-that is, the result of
* {@code this.substring(k, m + 1)}.
* <p>
* This method may be used to trim space (as defined above) from
* the beginning and end of a string.
*
* @apiNote
* This method removes leading and trailing space characters and ASCII control
* characters from the string. To remove characters using a Unicode-based definition of
* {@linkplain Character#isWhitespace(int) white space}, use {@link #strip() strip},
* {@link #stripIndent() stripIndent}, {@link #stripLeading() stripLeading}, or
* {@link #stripTrailing() stripTrailing}.
*
* @return a string whose value is this string, with all leading
* and trailing space removed, or this string if it
@@ -3934,13 +3943,9 @@ public final class String
}
/**
* Returns {@code true} if the string is empty or contains only
* {@linkplain Character#isWhitespace(int) white space} codepoints,
* otherwise {@code false}.
*
* @return {@code true} if the string is empty or contains only
* {@linkplain Character#isWhitespace(int) white space} codepoints,
* otherwise {@code false}
* {@return {@code true} if the string is {@linkplain #isEmpty empty} or contains
* only {@linkplain Character#isWhitespace(int) white space} codepoints,
* otherwise {@code false}}
*
* @see Character#isWhitespace(int)
*

View File

@@ -94,6 +94,15 @@ public class Net {
return EXCLUSIVE_BIND;
}
private static final StableValue<Boolean> SHUTDOWN_WRITE_BEFORE_CLOSE = StableValue.of();
/**
* Tells whether a TCP connection should be shutdown for writing before closing.
*/
static boolean shouldShutdownWriteBeforeClose() {
return SHUTDOWN_WRITE_BEFORE_CLOSE.orElseSet(Net::shouldShutdownWriteBeforeClose0);
}
/**
* Tells whether both IPV6_XXX and IP_XXX socket options should be set on
* IPv6 sockets. On some kernels, both IPV6_XXX and IP_XXX socket options
@@ -462,6 +471,8 @@ public class Net {
*/
private static native int isExclusiveBindAvailable();
private static native boolean shouldShutdownWriteBeforeClose0();
private static native boolean shouldSetBothIPv4AndIPv6Options0();
private static native boolean canIPv6SocketJoinIPv4Group0();

View File

@@ -846,7 +846,7 @@ class SocketChannelImpl
/**
* Marks the beginning of a connect operation that might block.
* @param blocking true if configured blocking
* @param isa the remote address
* @param sa the remote socket address
* @throws ClosedChannelException if the channel is closed
* @throws AlreadyConnectedException if already connected
* @throws ConnectionPendingException is a connection is pending
@@ -1070,8 +1070,8 @@ class SocketChannelImpl
}
/**
* Closes the socket if there are no I/O operations in progress and the
* channel is not registered with a Selector.
* Closes the socket if there are no I/O operations in progress (or no I/O
* operations tracked), and the channel is not registered with a Selector.
*/
private boolean tryClose() throws IOException {
assert Thread.holdsLock(stateLock) && state == ST_CLOSING;
@@ -1096,11 +1096,21 @@ class SocketChannelImpl
}
/**
* Closes this channel when configured in blocking mode.
* Closes this channel when configured in blocking mode. If there are no I/O
* operations in progress (or tracked), then the channel's socket is closed. If
* there are I/O operations in progress then the behavior is platform specific.
*
* If there is an I/O operation in progress then the socket is pre-closed
* and the I/O threads signalled, in which case the final close is deferred
* until all I/O operations complete.
* On Unix systems, the channel's socket is pre-closed. This unparks any virtual
* threads that are blocked in I/O operations on this channel. If there are
* platform threads blocked on the channel's socket then the socket is dup'ed
* and the platform threads signalled. The final close is deferred until all I/O
* operations complete.
*
* On Windows, the channel's socket is pre-closed. This unparks any virtual
* threads that are blocked in I/O operations on this channel. If there are no
* virtual threads blocked in I/O operations on this channel then the channel's
* socket is closed. If there are virtual threads in I/O then the final close is
* deferred until all I/O operations on virtual threads complete.
*
* Note that a channel configured blocking may be registered with a Selector
* This arises when a key is canceled and the channel configured to blocking
@@ -1112,17 +1122,17 @@ class SocketChannelImpl
boolean connected = (state == ST_CONNECTED);
state = ST_CLOSING;
if (!tryClose()) {
if (connected && Net.shouldShutdownWriteBeforeClose()) {
// shutdown output when linger interval not set to 0
if (connected) {
try {
var SO_LINGER = StandardSocketOptions.SO_LINGER;
if ((int) Net.getSocketOption(fd, SO_LINGER) != 0) {
Net.shutdown(fd, Net.SHUT_WR);
}
} catch (IOException ignore) { }
}
try {
var SO_LINGER = StandardSocketOptions.SO_LINGER;
if ((int) Net.getSocketOption(fd, SO_LINGER) != 0) {
Net.shutdown(fd, Net.SHUT_WR);
}
} catch (IOException ignore) { }
}
if (!tryClose()) {
// prepare file descriptor for closing
nd.preClose(fd, readerThread, writerThread);
}

View File

@@ -0,0 +1,21 @@
Owner: CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB
Issuer: CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB
Serial number: 50249ba2ef8ea6bf6c2c1f1a6385d4c3
Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046
Signature algorithm name: SHA384withECDSA
Subject Public Key Algorithm: 384-bit EC (secp384r1) key
Version: 3
-----BEGIN CERTIFICATE-----
MIICKDCCAa+gAwIBAgIQUCSbou+Opr9sLB8aY4XUwzAKBggqhkjOPQQDAzBWMQsw
CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRT
ZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBFNDYwHhcNMjEwMzIyMDAw
MDAwWhcNNDYwMzIxMjM1OTU5WjBWMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2Vj
dGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25p
bmcgUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQIMoEDH487om+BR4zl
e7m6wWmyW0nAKLkUWG8kM85Qm3PZO8FoOZx6Yc5c0iJHRKuAhanllayqrmZYhlan
uIODzLTRDqlR+EtnOX+MubY5aDSPGUq6jiHrQrisVp0J3AejQjBAMB0GA1UdDgQW
BBTPfSygkHqYHd22XoXC4NoVcdLlXjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/
BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjACd++zAerlV83j8HflRwwwlLmgchbs
aGX/4g44dv/oG8KfzCVTRg6sZHMobtK0IqYCMGk5W6+oBFyZMtOebrSwXs8lGjll
/zHz43Zy8DMXO+iiqzSEwWGneZ6KupkGGqfVKw==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,39 @@
Owner: CN=Sectigo Public Code Signing Root R46, O=Sectigo Limited, C=GB
Issuer: CN=Sectigo Public Code Signing Root R46, O=Sectigo Limited, C=GB
Serial number: 4b2c3b01018bad2abc8c7b5b3eed9057
Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046
Signature algorithm name: SHA384withRSA
Subject Public Key Algorithm: 4096-bit RSA key
Version: 3
-----BEGIN CERTIFICATE-----
MIIFeDCCA2CgAwIBAgIQSyw7AQGLrSq8jHtbPu2QVzANBgkqhkiG9w0BAQwFADBW
MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQD
EyRTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwHhcNMjEwMzIy
MDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBWMQswCQYDVQQGEwJHQjEYMBYGA1UEChMP
U2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdvIFB1YmxpYyBDb2RlIFNp
Z25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCN
55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+shJHjUoq14pbe0IdjJImK
/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCDJ9qaDStQ6Utbs7hkNqR+
Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7P2bSlDFp+m2zNKzBenjc
klDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extmeme/G3h+pDHazJyCh1rr9
gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUzT2MuuC3hv2WnBGsY2HH6
zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6qRT5uWl+PoVvLnTCGMOgD
s0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mczmrYI4IAFSEDu9oJkRqj1
c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEcQNYWFyn8XJwYK+pF9e+9
1WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2TOglmmVhcKaO5DKYwODzQ
RjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/AZwQsRb8zG4Y3G9i/qZQ
p7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QIDAQABo0IwQDAdBgNVHQ4E
FgQUMuuSmv81lkgvKEBCcCA2kVwXheYwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB
/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAHZlwuPXIkrXHYle/2lexhQCTXOm
zc0oyrA36r+nySGqql/av/aDbNCA0QpcAKTL88w5D55BcYjVPOiKe4wXI/fKNHSR
bAauUD8AWbImPDwXg1cDPi3RGj3UzwdUskMLUnKoiPXEF/Jv0Vil0WjkPZgIGO42
9EhImvpUcPCI1HAWMEJJ0Nk/dUtFcdiuorthDoiFUFe5uhErNikfjyBynlyeidGC
2kWNapnahHFrM6UQu3nwl/Z0gaA/V8eGjDCMDjiVrgHGHqvcqB9vL9f/dh6uF3Nt
5bl1s2EGqJUzwk5vsjfylb6FVBK5yL1iQnb3Kvz1NzEDJlf+0ebb8BYCcoOMCLOE
rKnkB/ihiMQTWlBHVEKm7dBBNCyYsT6iNKEMXb2s9395p79tDFYyhRtLl7jhrOSk
PHHxo+FOY9b0Rrr1CwjhYzztolkvCtQsayOinqFN7tESzRgzUO1Bbst/PUFgC2ML
ePV170MVtzYLEK/cXBipmNk22R3YhLMGioLjexskp0LO7g8+VlwyfexL3lYrOzu6
+XpY0FG2bNb2WKJSJHpEhqEcYD9J0/z6+YQcBcI0v+Lm8RkqmS9WVzWctfUHw0Yv
3jg9GQ37o/HfE57nqXJYMa+96trX1m13MzOO9Kz9wb9Jh9JwBWd0Bqb2eEAtFgSR
Dx/TFsS4ehcNJMmy
-----END CERTIFICATE-----

View File

@@ -0,0 +1,21 @@
Owner: CN=Sectigo Public Server Authentication Root E46, O=Sectigo Limited, C=GB
Issuer: CN=Sectigo Public Server Authentication Root E46, O=Sectigo Limited, C=GB
Serial number: 42f2ccda1b6937445f15fe752810b8f4
Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046
Signature algorithm name: SHA384withECDSA
Subject Public Key Algorithm: 384-bit EC (secp384r1) key
Version: 3
-----BEGIN CERTIFICATE-----
MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw
CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T
ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN
MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG
A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT
ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA
IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC
WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+
6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B
Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa
qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q
4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,39 @@
Owner: CN=Sectigo Public Server Authentication Root R46, O=Sectigo Limited, C=GB
Issuer: CN=Sectigo Public Server Authentication Root R46, O=Sectigo Limited, C=GB
Serial number: 758dfd8bae7c0700faa925a7e1c7ad14
Valid from: Mon Mar 22 00:00:00 GMT 2021 until: Wed Mar 21 23:59:59 GMT 2046
Signature algorithm name: SHA384withRSA
Subject Public Key Algorithm: 4096-bit RSA key
Version: 3
-----BEGIN CERTIFICATE-----
MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf
MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD
Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw
HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY
MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp
YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa
ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz
SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf
iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X
ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3
IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS
VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE
SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu
+Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt
8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L
HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt
zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P
AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c
mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ
YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52
gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA
Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB
JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX
DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui
TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5
dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65
LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp
0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY
QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL
-----END CERTIFICATE-----

View File

@@ -205,6 +205,11 @@ Java_sun_nio_ch_Net_isExclusiveBindAvailable(JNIEnv *env, jclass clazz) {
return -1;
}
JNIEXPORT jboolean JNICALL
Java_sun_nio_ch_Net_shouldShutdownWriteBeforeClose0(JNIEnv *env, jclass clazz) {
return JNI_FALSE;
}
JNIEXPORT jboolean JNICALL
Java_sun_nio_ch_Net_shouldSetBothIPv4AndIPv6Options0(JNIEnv* env, jclass cl)
{

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2025, 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
@@ -117,6 +117,11 @@ Java_sun_nio_ch_Net_isExclusiveBindAvailable(JNIEnv *env, jclass clazz) {
return 1;
}
JNIEXPORT jboolean JNICALL
Java_sun_nio_ch_Net_shouldShutdownWriteBeforeClose0(JNIEnv *env, jclass clazz) {
return JNI_TRUE;
}
JNIEXPORT jboolean JNICALL
Java_sun_nio_ch_Net_shouldSetBothIPv4AndIPv6Options0(JNIEnv* env, jclass cl)
{

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,12 +27,9 @@
* <p>Interfaces for remote access to
* JMX MBean servers.
* This package defines the essential interfaces for making a JMX
* MBean server manageable remotely. The specification of this
* functionality is completed by Part III of the
* <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
* JMX Specification, version 1.4</a></p>
* MBean server manageable remotely.</p>
*
* <p>The JMX specification defines the notion of <b>connectors</b>.
* <p>JMX defines the notion of <b>connectors</b>.
* A connector is attached to a JMX API MBean server and makes it
* accessible to remote Java clients. The client end of a
* connector exports essentially the same interface as the MBean
@@ -41,32 +38,17 @@
* interface.</p>
*
* <p>A connector makes an MBean server remotely accessible through
* a given protocol. The JMX Remote API allows the use of different
* type of connectors:
* a given protocol.
*
* <ul>
* <ul>
* <li>The JMX Remote API defines a standard connector,
* the <b>RMI Connector</b>, which provides remote access to an
* MBeanServer through RMI.
* MBeanServer through RMI.
*
* <li>The JMX Remote API also defines an optional connector called
* <b>JMXMP Connector</b> implementing the JMX Message Protocol
* (JMXMP). As it is optional, it is not part of this bundle (see
* note below).
*
* <li>User-defined connector protocols are also possible using the
* <li>Other connector protocols are also possible using the
* {@link javax.management.remote.JMXConnectorFactory
* JMXConnectorFactory} and, optionally, the Generic Connector
* (not part of this bundle, see note below).
* </ul>
*
* <p><u>Note</u>: the optional packages implementing
* the optional part of the <em>JMX Remote API</em>
* are not included in the <em>Java SE Platform</em>
* but are available from the <em>JMX Remote API
* <a href="https://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html">
* Reference Implementation</a></em>.</p>
*
* JMXConnectorFactory}.
* </ul>
*
* <h2>Connector addresses</h2>
*

View File

@@ -79,8 +79,6 @@ compiler/ciReplay/TestIncrementalInlining.java 8349191 generic-all
compiler/c2/TestVerifyConstraintCasts.java 8355574 generic-all
compiler/startup/StartupOutput.java 8358129 windows-all
#############################################################################
# :hotspot_gc

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2025, 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
* @library /test/lib /
* @bug 8359200
* @key randomness
* @requires vm.flagless & vm.compiler2.enabled & vm.debug == true
* @summary Test that -XX:OptoNodeListSize does not crash the VM.
* @run driver compiler.arguments.TestOptoNodeListSize
*/
package compiler.arguments;
import java.io.IOException;
import java.util.Random;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.Utils;
public class TestOptoNodeListSize {
private static final Random RANDOM = Utils.getRandomInstance();
public static void main(String[] args) throws IOException {
if (args.length == 0) {
int size = RANDOM.nextInt(1000) + 1;
ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:OptoNodeListSize=" + size,
"-Xcomp", "-XX:-TieredCompilation", "compiler.arguments.TestOptoNodeListSize", "run");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
} else {
System.out.println("Test passed.");
}
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2025, 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 Test that C1 respects that static initializers can have memory side effects.
* @bug 8357782
* @requires vm.compiler1.enabled
* @comment Since static initializers only execute in the first execution of the class initializer, we need -Xcomp.
* @run main/othervm -Xcomp -XX:TieredStopAtLevel=1 -XX:CompileCommand=compileonly,compiler/c1/A$B.test compiler.c1.TestStaticInitializerSideEffect
*/
package compiler.c1;
public class TestStaticInitializerSideEffect {
public static void main(String[] args) {
A.B.test();
}
}
class A {
static class B {
static String field;
static void test() {
// This unused variable triggers local value numbering to remove
// the field load in the constructor below if it is not killed
// before.
String tmp = field;
// The class initializer of C should kill the LVN effect of tmp due
// to the memory side effects of the static initializer.
new C(field);
}
}
static class C {
// When executing the class initializer, this has a side effect.
static {
B.field = "Hello";
}
C(String val) {
// If C1 does not respect that side effect, we crash here.
if (val == null) {
throw new RuntimeException("Should not reach here");
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2025, 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
@@ -57,6 +57,19 @@ public class AndnTestI extends BmiIntrinsicBase.BmiTestCase {
(byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
(byte) 0x00,
(byte) 0xF2};
// from intel apx specifications EVEX.128.NP.0F38.W0 F2 /r
instrMaskAPX = new byte[]{
(byte) 0xFF,
(byte) 0x07,
(byte) 0x00,
(byte) 0x00,
(byte) 0xFF};
instrPatternAPX = new byte[]{
(byte) 0x62, // fixed prefix byte 0x62 for extended EVEX instruction
(byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
(byte) 0x00,
(byte) 0x00,
(byte) 0xF2};
}
public static void main(String[] args) throws Exception {

View File

@@ -59,6 +59,23 @@ public class BlsiTestI extends BmiIntrinsicBase.BmiTestCase {
(byte) 0x00,
(byte) 0xF3,
(byte) 0b0001_1000}; // bits 543 == 011 (3)
// from intel apx specifications EVEX.128.NP.0F38.W0 F3 /3(opcode extension)
instrMaskAPX = new byte[]{
(byte) 0xFF,
(byte) 0x07,
(byte) 0x00,
(byte) 0x00,
(byte) 0xFF,
(byte) 0x38};
instrPatternAPX = new byte[]{
(byte) 0x62, // fixed prefix byte 0x62 for extended EVEX instruction
(byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
(byte) 0x00,
(byte) 0x00,
(byte) 0xF3,
(byte) 0b0001_1000}; // bits 543 == 011 (3)
}
public static void main(String[] args) throws Exception {

View File

@@ -57,7 +57,24 @@ public class BlsmskTestI extends BmiIntrinsicBase.BmiTestCase {
(byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
(byte) 0x00,
(byte) 0xF3,
(byte) 0b0001_0000}; // bits 543 == 011 (3)
(byte) 0b0001_0000}; // bits 543 == 010 (2)
// from intel apx specifications EVEX.128.NP.0F38.W1 F3 /2(opcode extension part of ModRM.REG)
instrMaskAPX = new byte[]{
(byte) 0xFF,
(byte) 0x07,
(byte) 0x00,
(byte) 0x00,
(byte) 0xFF,
(byte) 0x38};
instrPatternAPX = new byte[]{
(byte) 0x62, // fixed prefix byte 0x62 for extended EVEX instruction
(byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
(byte) 0x00,
(byte) 0x00,
(byte) 0xF3,
(byte) 0b0001_0000}; // bits 543 == 010 (2)
}
public static void main(String[] args) throws Exception {

View File

@@ -58,7 +58,25 @@ public class BlsrTestI extends BmiIntrinsicBase.BmiTestCase {
(byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
(byte) 0x00,
(byte) 0xF3,
(byte) 0b0000_1000}; // bits 543 == 011 (3)
(byte) 0b0000_1000}; // bits 543 == 001 (1)
// from intel apx specifications EVEX.128.NP.0F38.W1 F3 /1(opcode extension part of ModRM.REG)
instrMaskAPX = new byte[]{
(byte) 0xFF,
(byte) 0x07,
(byte) 0x00,
(byte) 0x00,
(byte) 0xFF,
(byte) 0x38};
instrPatternAPX = new byte[]{
(byte) 0x62, // fixed prefix byte 0x62 for extended EVEX instruction
(byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
(byte) 0x00,
(byte) 0x00,
(byte) 0xF3,
(byte) 0b0000_1000}; // bits 543 == 001 (1)
}
public static void main(String[] args) throws Exception {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2025, 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
@@ -111,7 +111,8 @@ public class BmiIntrinsicBase extends CompilerWhiteBoxTest {
protected void checkEmittedCode(Executable executable) {
final byte[] nativeCode = NMethod.get(executable, false).insts;
final byte[] matchInstrPattern = (((BmiTestCase) testCase).getTestCaseX64() && Platform.isX64()) ? ((BmiTestCase_x64) testCase).getInstrPattern_x64() : ((BmiTestCase) testCase).getInstrPattern();
if (!((BmiTestCase) testCase).verifyPositive(nativeCode)) {
boolean use_apx = CPUInfo.hasFeature("apx_f");
if (!((BmiTestCase) testCase).verifyPositive(nativeCode, use_apx)) {
throw new AssertionError(testCase.name() + " " + "CPU instructions expected not found in nativeCode: " + Utils.toHexString(nativeCode) + " ---- Expected instrPattern: " +
Utils.toHexString(matchInstrPattern));
} else {
@@ -124,6 +125,8 @@ public class BmiIntrinsicBase extends CompilerWhiteBoxTest {
private final Method method;
protected byte[] instrMask;
protected byte[] instrPattern;
protected byte[] instrMaskAPX;
protected byte[] instrPatternAPX;
protected boolean isLongOperation;
protected String cpuFlag = "bmi1";
protected String vmFlag = "UseBMI1Instructions";
@@ -160,6 +163,13 @@ public class BmiIntrinsicBase extends CompilerWhiteBoxTest {
return countCpuInstructions(nativeCode, instrMask, instrPattern);
}
protected int countCpuInstructionsAPX(byte[] nativeCode) {
if (instrMaskAPX == null || instrPatternAPX == null) {
return 0;
}
return countCpuInstructions(nativeCode, instrMaskAPX, instrPatternAPX);
}
public static int countCpuInstructions(byte[] nativeCode, byte[] instrMask, byte[] instrPattern) {
int count = 0;
int patternSize = Math.min(instrMask.length, instrPattern.length);
@@ -181,8 +191,12 @@ public class BmiIntrinsicBase extends CompilerWhiteBoxTest {
return count;
}
public boolean verifyPositive(byte[] nativeCode) {
final int cnt = countCpuInstructions(nativeCode);
public boolean verifyPositive(byte[] nativeCode, boolean use_apx) {
int cnt = countCpuInstructions(nativeCode);
if (use_apx) {
System.out.println("CHECKING APX INST PATTERNS");
cnt += countCpuInstructionsAPX(nativeCode);
}
if (Platform.isX86()) {
return cnt >= (isLongOperation ? 2 : 1);
} else {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2025, 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
@@ -73,6 +73,21 @@ public class BzhiTestI2L extends BmiIntrinsicBase.BmiTestCase_x64 {
(byte) 0x62, // 00010 implied 0F 38 leading opcode bytes
(byte) 0xA8,
(byte) 0xF5};
// from intel apx specifications EVEX.128.NP.0F38.W0 F5 /r
instrMaskAPX = new byte[]{
(byte) 0xFF,
(byte) 0x07,
(byte) 0x00,
(byte) 0x00,
(byte) 0xFF};
instrPatternAPX = new byte[]{
(byte) 0x62, // fixed prefix byte 0x62 for extended EVEX instruction
(byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
(byte) 0x00,
(byte) 0x00,
(byte) 0xF5};
}
public static void main(String[] args) throws Exception {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2025, 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
@@ -51,6 +51,10 @@ public class LZcntTestI extends BmiIntrinsicBase.BmiTestCase_x64 {
instrMask_x64 = new byte[]{(byte) 0xFF, (byte) 0x00, (byte) 0xFF, (byte) 0xFF};
instrPattern_x64 = new byte[]{(byte) 0xF3, (byte) 0x00, (byte) 0x0F, (byte) 0xBD};
// REX2 variant
instrMaskAPX = new byte[]{(byte) 0xFF, (byte) 0xFF, (byte)0x80, (byte) 0xFF};
instrPatternAPX = new byte[]{(byte) 0xF3, (byte) 0xD5, (byte) 0x80, (byte) 0xBD};
}
public static void main(String[] args) throws Exception {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2025, 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
@@ -50,6 +50,10 @@ public class TZcntTestI extends BmiIntrinsicBase.BmiTestCase_x64 {
instrMask_x64 = new byte[]{(byte) 0xFF, (byte) 0x00, (byte) 0xFF, (byte) 0xFF};
instrPattern_x64 = new byte[]{(byte) 0xF3, (byte) 0x00, (byte) 0x0F, (byte) 0xBC};
// REX2 variant
instrMaskAPX = new byte[]{(byte) 0xFF, (byte) 0xFF, (byte)0x80, (byte) 0xFF};
instrPatternAPX = new byte[]{(byte) 0xF3, (byte) 0xD5, (byte) 0x80, (byte) 0xBC};
}
public static void main(String[] args) throws Exception {

View File

@@ -60,21 +60,17 @@ public class StartupOutput {
throw new Exception("VM crashed with exit code " + exitCode);
}
Process[] pr = new Process[200];
for (int i = 0; i < 200; i++) {
int initialCodeCacheSizeInKb = 800 + rand.nextInt(400);
int reservedCodeCacheSizeInKb = initialCodeCacheSizeInKb + rand.nextInt(200);
pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:InitialCodeCacheSize=" + initialCodeCacheSizeInKb + "K", "-XX:ReservedCodeCacheSize=" + reservedCodeCacheSizeInKb + "k", "-version");
pr[i] = pb.start();
}
for (int i = 0; i < 200; i++) {
out = new OutputAnalyzer(pr[i]);
// The VM should not crash but will probably fail with a "CodeCache is full. Compiler has been disabled." message
out.stdoutShouldNotContain("# A fatal error");
out = new OutputAnalyzer(pb.start());
exitCode = out.getExitValue();
if (exitCode != 1 && exitCode != 0) {
throw new Exception("VM crashed with exit code " + exitCode);
}
// The VM should not crash but will probably fail with a "CodeCache is full. Compiler has been disabled." message
out.stdoutShouldNotContain("# A fatal error");
}
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 2025, Red Hat, Inc. 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 8358334
* @summary C2/Shenandoah: incorrect execution with Unsafe
* @requires vm.gc.Shenandoah
* @modules java.base/jdk.internal.misc:+open
*
* @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:-TieredCompilation -XX:+UseShenandoahGC
* TestLostAntiDependencyAtExpansion
*
*
*/
import jdk.internal.misc.Unsafe;
public class TestLostAntiDependencyAtExpansion {
static final jdk.internal.misc.Unsafe UNSAFE = Unsafe.getUnsafe();
public static void main(String[] args) {
long addr = UNSAFE.allocateMemory(8);
for (int i = 0; i < 20_000; i++) {
UNSAFE.putLong(addr, 42L);
long res = test1(addr);
if (res != 42L) {
throw new RuntimeException("Incorrect result: " + res);
}
}
}
static class A {
long field;
}
static A a = new A();
private static long test1(long addr) {
long tmp = UNSAFE.getLong(addr);
UNSAFE.putLong(addr, 0L);
return tmp + a.field;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2025, 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
@@ -34,9 +34,11 @@
* This testcase uses interned strings for both first and second phases
* and multiple threads.
*
* @requires os.maxMemory > 3G
* @library /vmTestbase
* /test/lib
* @run main/othervm
* -Xmx2G
* -XX:-UseGCOverheadLimit
* vm.gc.compact.Compact
* -gp interned(randomString)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2025, 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
@@ -34,9 +34,11 @@
* This testcase uses interned strings for first phase,
* random arrays for second phases and multiple threads.
*
* @requires os.maxMemory > 3G
* @library /vmTestbase
* /test/lib
* @run main/othervm
* -Xmx2G
* -XX:-UseGCOverheadLimit
* vm.gc.compact.Compact
* -gp interned(randomString)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2025, 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
@@ -34,9 +34,11 @@
* This testcase uses random strings for first phase, array of
* random strings for second phase and multiple threads.
*
* @requires os.maxMemory > 3G
* @library /vmTestbase
* /test/lib
* @run main/othervm
* -Xmx2G
* -XX:-UseGCOverheadLimit
* vm.gc.compact.Compact
* -gp randomString

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2025, 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
@@ -34,9 +34,11 @@
* This testcase uses interned strings for both first and second phases
* and multiple threads.
*
* @requires os.maxMemory > 3G
* @library /vmTestbase
* /test/lib
* @run main/othervm
* -Xmx2G
* -XX:-UseGCOverheadLimit
* vm.gc.compact.Compact
* -gp interned(randomString)

View File

@@ -429,7 +429,7 @@ public class HttpURLConnectionExpectContinueTest {
.port(control.serverSocket.getLocalPort())
.toURL();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
HttpURLConnection connection = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
connection.setDoOutput(true);
connection.setReadTimeout(5000);
connection.setUseCaches(false);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2025, 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
@@ -38,6 +38,10 @@
import java.io.IOException;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
@@ -57,6 +61,19 @@ public class EarlyOrDelayedParsing {
{
String value = System.getProperty("jdk.net.url.delayParsing", "false");
EARLY_PARSING = !value.isEmpty() && !Boolean.parseBoolean(value);
if (!EARLY_PARSING) {
// we will open the connection in that case.
// make sure no proxy is selected
ProxySelector.setDefault(new ProxySelector() {
@Override
public List<Proxy> select(URI uri) {
return List.of(Proxy.NO_PROXY);
}
@Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
}
});
}
}
// Some characters that when included at the wrong place

View File

@@ -0,0 +1,195 @@
/*
* Copyright (c) 2025, 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 8358764
* @summary Test closing a socket while a thread is blocked in read. The connection
* should be closed gracefuly so that the peer reads EOF.
* @run junit PeerReadsAfterAsyncClose
*/
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.*;
class PeerReadsAfterAsyncClose {
static Stream<ThreadFactory> factories() {
return Stream.of(Thread.ofPlatform().factory(), Thread.ofVirtual().factory());
}
/**
* Close SocketChannel while a thread is blocked reading from the channel's socket.
*/
@ParameterizedTest
@MethodSource("factories")
void testCloseDuringSocketChannelRead(ThreadFactory factory) throws Exception {
var loopback = InetAddress.getLoopbackAddress();
try (var listener = new ServerSocket()) {
listener.bind(new InetSocketAddress(loopback, 0));
try (SocketChannel sc = SocketChannel.open(listener.getLocalSocketAddress());
Socket peer = listener.accept()) {
// start thread to read from channel
var cceThrown = new AtomicBoolean();
Thread thread = factory.newThread(() -> {
try {
sc.read(ByteBuffer.allocate(1));
fail();
} catch (ClosedChannelException e) {
cceThrown.set(true);
} catch (Throwable e) {
e.printStackTrace();
}
});
thread.start();
try {
// close SocketChannel when thread sampled in implRead
onReach(thread, "sun.nio.ch.SocketChannelImpl.implRead", () -> {
try {
sc.close();
} catch (IOException ignore) { }
});
// peer should read EOF
int n = peer.getInputStream().read();
assertEquals(-1, n);
} finally {
thread.join();
}
assertEquals(true, cceThrown.get(), "ClosedChannelException not thrown");
}
}
}
/**
* Close Socket while a thread is blocked reading from the socket.
*/
@ParameterizedTest
@MethodSource("factories")
void testCloseDuringSocketUntimedRead(ThreadFactory factory) throws Exception {
testCloseDuringSocketRead(factory, 0);
}
/**
* Close Socket while a thread is blocked reading from the socket with a timeout.
*/
@ParameterizedTest
@MethodSource("factories")
void testCloseDuringSockeTimedRead(ThreadFactory factory) throws Exception {
testCloseDuringSocketRead(factory, 60_000);
}
private void testCloseDuringSocketRead(ThreadFactory factory, int timeout) throws Exception {
var loopback = InetAddress.getLoopbackAddress();
try (var listener = new ServerSocket()) {
listener.bind(new InetSocketAddress(loopback, 0));
try (Socket s = new Socket(loopback, listener.getLocalPort());
Socket peer = listener.accept()) {
// start thread to read from socket
var seThrown = new AtomicBoolean();
Thread thread = factory.newThread(() -> {
try {
s.setSoTimeout(timeout);
s.getInputStream().read();
fail();
} catch (SocketException e) {
seThrown.set(true);
} catch (Throwable e) {
e.printStackTrace();
}
});
thread.start();
try {
// close Socket when thread sampled in implRead
onReach(thread, "sun.nio.ch.NioSocketImpl.implRead", () -> {
try {
s.close();
} catch (IOException ignore) { }
});
// peer should read EOF
int n = peer.getInputStream().read();
assertEquals(-1, n);
} finally {
thread.join();
}
assertEquals(true, seThrown.get(), "SocketException not thrown");
}
}
}
/**
* Runs the given action when the given target thread is sampled at the given
* location. The location takes the form "{@code c.m}" where
* {@code c} is the fully qualified class name and {@code m} is the method name.
*/
private void onReach(Thread target, String location, Runnable action) {
int index = location.lastIndexOf('.');
String className = location.substring(0, index);
String methodName = location.substring(index + 1);
Thread.ofPlatform().daemon(true).start(() -> {
try {
boolean found = false;
while (!found) {
found = contains(target.getStackTrace(), className, methodName);
if (!found) {
Thread.sleep(20);
}
}
action.run();
} catch (Exception e) {
e.printStackTrace();
}
});
}
/**
* Returns true if the given stack trace contains an element for the given class
* and method name.
*/
private boolean contains(StackTraceElement[] stack, String className, String methodName) {
return Arrays.stream(stack)
.anyMatch(e -> className.equals(e.getClassName())
&& methodName.equals(e.getMethodName()));
}
}

View File

@@ -27,6 +27,7 @@ import javax.crypto.EncryptedPrivateKeyInfo;
import java.security.DEREncodable;
import java.security.KeyPair;
import java.security.PEMRecord;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.security.interfaces.*;
import java.util.ArrayList;
@@ -45,7 +46,7 @@ class PEMData {
KwDdi3cNwu7YYD/QtJ+9+AEBdoqhRANCAASL+REY4vvAI9M3gonaml5K3lRgHq5w
+OO4oO0VNduC44gUN1nrk7/wdNSpL+xXNEX52Dsff+2RD/fop224ANvB
-----END PRIVATE KEY-----
""", KeyPair.class);
""", KeyPair.class, "SunEC");
public static final Entry rsapriv = new Entry("rsapriv",
"""
@@ -65,7 +66,68 @@ class PEMData {
6onPAs4hkm+63dfzCojvEkALevO8J3OVX7YS5q9J1r75wDn60Ob0Zh+iiorpx8Ob
WqcWcoJqfdLEyBT+
-----END PRIVATE KEY-----
""", RSAPrivateKey.class);
""", RSAPrivateKey.class, "SunRsaSign");
public static final Entry rsaCrtCoefZeroPriv = new Entry("rsaCrtCoefZeroPriv",
"""
-----BEGIN RSA PRIVATE KEY-----
MIIEIwIBAAKCAQEAuZAPiPMlA5R0oOIbxbq+gOmBRcvptIT+0pmG6rZ6H//r7A/Z
MRwen0iO2GuhlyUgOk9Fja/TMBrNX99boVDEZtL4oxRTJibdLNjfQqPeFhs3NNvv
CJJEGD91Dq/fGbWv1TMZcEywqqYSdERDEA7yluw87I7YZc9kXVBwRw5AedvoXOL/
z5yPjK8W7FTCLHSVKiD/X3P3ZX9TmFjTIbRH15Do5sRxsPdrZczYjWdXFXNQEUuF
sVFGHFbB/AJiZlGYqMU+hEIErE35sHrKpZYkj9YovYQe0SBJyuROPl8wmz0Cd69s
rhg142Qf23RPhclBuCNAQQOkefeCppg4IFFh7QIDAQABAoIBADlKHlm4Q7m2uElB
dbSWwqEXNnefjJBUrT3E84/8dXjysNppTDNqzJN9uchcdn+tESWfeshTO97yr2yF
j4se3fwm72ed60vwnMFvVYKECBmIHoO90S8yxT49PT0jFDyiSN6IT7bJnpOZAUKP
HqtTCheJaQfZ1DqejIx4vKlbX5GfShwPQV0Q7KeKnfxhryhAbM5Y5UT8grQGBQU7
aQUZuasQV10APVRaz39VU8/hzBc081LR3O0tjnZcrMAQ7ANsP9Gu3My04cnQ5WBo
P8uCCaSPSkrzCvjd9YYkdnwXMbVCfALOa+MxBddMi4IQG0qI28Bpw6dkKziPxage
KcAQnAsCgYEA0/CwzUlyrG6f+FF3uAvPVn/jEhWatJb7Me7lkhO3suV92brb1pQo
1W1jHdx0OqMuCVfIJ4bXkTwKuvLQGcWJzNWUVh4Tij/ZAV0Ssw2cKbBSCQGNIFsx
Ux0V9tDSYJsEdk+Y5grloDNJokYYCCpF5bz/6QYmX+t3yzjyVSvcNeMCgYEA4COU
ezUXKLSWD+jJZXpS5yopB7oXAg7mmonlc1DRuaIxspwBrbXPLQ/neN8Sefpz9Nxn
4ksPxGbLnJh0wGCnxSu0Qfn4eNVSsulag4IQmbCO2UBsdXNCJB5KlDpRlVhvvviH
Zpz2Dkdx+itLf1EV841MCtPAHZJwrs6i6JntEe8CgYEAgJYdjs+rJXcQ04YKDr4L
k72PtR8qd7rKuObqnhAcegvGqV03mB7YD3WIl0tzsUfj3INHysOC8njtQbOkEp7J
Fl/W2dDxpgVK0gr4F26AesKhYxlv2Fu7t2OEOfVETpx+vpFYgOnHm8TCPhQs7HdJ
ZTOgSG8UxUmFquToEkjEGGUCgYB6AMP8wKxHeuzH4iVl+EySCa/lxdRqSWQasH7V
4yMVkYTNvP9o57LKy4Jql7n97Wca3LIrSkJd3LpuFcpPQQ1xVNW8p+0pEK0AN+cN
+ElC7wkCln+y+rcA5AAiaRApY8cHw04oe72vjhIrY0+oEKILPVkr95D2R9TQQigI
xmh1vwIBAA==
-----END RSA PRIVATE KEY-----
""", RSAPrivateKey.class, "SunRsaSign");
public static final Entry rsapsspriv = new Entry("rsapsspriv",
"""
-----BEGIN PRIVATE KEY-----
MIIEugIBADALBgkqhkiG9w0BAQoEggSmMIIEogIBAAKCAQEAn3qFQtvj9JVqVPRh
mMMRyT17GiUY+NWOwUHx5bHqfhlHJoCllctSU/YXzrH4Da1w7sSeaMmAKYMW4X5k
rn9hnKOhgHnm2nkZBaVNQeyrseuDnfwWtLXjnj8rEKpgf9UPRUeXGRSoAb1qpwBf
epFtLSKZrzswZY2u2UEUGJERABi6Qp+cIZ8uXzBkIsMgrhb50xsdysZ9+qq95z0i
N1vh/V+Yi2fYpSYVDE8aMWdpvs0oWGvoLQjRgElJx/SknndAfLD42HPYZyyXevyJ
RgUf+NP0V7c+UtE7m7pgMs1hhxHSmUNdfH9GnOSg9m3+L3WqhaNNWB4aKMqFyhlM
EsAuawIDAQABAoIBAAMJ9yXIgeYEaN54j67fsg7nJIQ228HLc/5xGWvFQaYofidu
K87twm0GKKWlf4gR24U5QEQtPst2YNu9fav+PRJv4yEgcYqNOdxWg4veN4Fa7wr2
JZ/zmARJHjLMRFgl67YSwKmCMBdkZXa24PA5et6cJQM7+gFIELe5b+lt7j3VsxQ7
JpTJyp3I73lXcJrzcb/OCTxobFPLtkVSgKUNwae26xlNqXX4fQfLp99LHGnkmG3k
Wlzjs6dUi4fl4yLAJYMxEwxQbSbmY66ZKnM4SkT/YHx67gyJw2CMRp4FQDg94Sor
0IDDKiSMGzcjuCuUl27/qTuv+iMgCqNB7CSPXtECgYEAvqN8ZuZXeUKz4tn6wxJk
k1utCl3pSM5PLMF4J43uvX49HF1i3svXrwxzJqug6kPXvB7cuB6U2DFIM3lh2jNE
u2w0U/5zVz2yEI9EaRjnOXePLsSWjOiC+5MGTafJWy5vZ8+zaWL9tjtUH5hsg1cB
ZMlXtWrI+AmAUAv6FFDZaHECgYEA1igXzRMGgXAT+YX0wdZQcRMy9jD5WIYIiCex
6/WRE2LDM855ZBwTU5gyqZC2MWC3yn1ASDraxKdH1m3872Q0NVJfsOaLvBk1HuPk
dlSHRKO2GeO9m5/YzrZm9jpGs0IH6DKOah/t0aCd2CFxt6qef2wOUmXTCK6tyCXN
EiUmEpsCgYAMue85E1Ftl+VYVILn+Ndb+ve/RGupX5RrgXLa+R+h6MZ9mUJbazI3
zlX1k+mHGgZR2aGUbP40vH18ajL9FQUWme+YV9ktTsIPVvETLwVokbGuRpNiTrdH
whXeoz/O5Xesb3Ijq+cR/j3sagl8bxd5ufMv+jP2UvQM4+/K4WbSEQKBgGuZeVvw
UzR1u5ODWpaJt6EYpGJN+PohXegLCbokh9/Vn35IH3XNJWi677mCnAfzMGTsyX+B
Eqn74nw6hvtAvXqNCMc5DrxTbf03Q3KwxcYW+0fGxV2L0sMJonHUlfE7G/3uaN+p
azQIH0aYhypg74HWKNv9jSqvmWEWnRKg16BBAoGAGLAqCRCP8wxqRVZZjhUJ+5JN
b6PrykDxCKhlA6JqZKuCYzvXhLABq/7miNDg0CmRREl+yKXlkEoFl4g9LtP7wfjX
n4us/WNmh+GPZYxlCJSNRTjgk7pm5TjVH5YWURDEnjIHZ7yxbAFlvNUhI1mF5g97
KVcB4fjBitP1h8P+MoY=
-----END PRIVATE KEY-----
""", RSAPrivateKey.class, "SunRsaSign");
public static final Entry rsaprivbc = new Entry("rsaprivbc",
"""
@@ -85,14 +147,14 @@ class PEMData {
6onPAs4hkm+63dfzCojvEkALevO8J3OVX7YS5q9J1r75wDn60Ob0Zh+iiorpx8Ob
WqcWcoJqfdLEyBT+
-----END PRIVATE KEY-----
""", RSAPrivateKey.class);
""", RSAPrivateKey.class, "SunRsaSign");
public static final Entry ec25519priv = new Entry("ed25519priv",
"""
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIFFZsmD+OKk67Cigc84/2fWtlKsvXWLSoMJ0MHh4jI4I
-----END PRIVATE KEY-----
""", EdECPrivateKey.class);
""", EdECPrivateKey.class, "SunEC");
public static final Entry rsapub = new Entry("rsapub",
"""
@@ -102,7 +164,20 @@ class PEMData {
MtJpIPIXynEqRy2mIw2GrKTtu3dqrW+ndarbD6D4yRY1hWHluiuOtzhxuueCuf9h
XCYEHZS1cqd8wokFPwIDAQAB
-----END PUBLIC KEY-----
""", RSAPublicKey.class);
""", RSAPublicKey.class, "SunRsaSign");
public static final Entry rsapsspub = new Entry("rsapsspub",
"""
-----BEGIN PUBLIC KEY-----
MIIBIDALBgkqhkiG9w0BAQoDggEPADCCAQoCggEBAJ96hULb4/SValT0YZjDEck9
exolGPjVjsFB8eWx6n4ZRyaApZXLUlP2F86x+A2tcO7EnmjJgCmDFuF+ZK5/YZyj
oYB55tp5GQWlTUHsq7Hrg538FrS1454/KxCqYH/VD0VHlxkUqAG9aqcAX3qRbS0i
ma87MGWNrtlBFBiREQAYukKfnCGfLl8wZCLDIK4W+dMbHcrGffqqvec9Ijdb4f1f
mItn2KUmFQxPGjFnab7NKFhr6C0I0YBJScf0pJ53QHyw+Nhz2Gcsl3r8iUYFH/jT
9Fe3PlLRO5u6YDLNYYcR0plDXXx/RpzkoPZt/i91qoWjTVgeGijKhcoZTBLALmsC
AwEAAQ==
-----END PUBLIC KEY-----
""", RSAPublicKey.class, "SunRsaSign");
public static final Entry rsapubbc = new Entry("rsapubbc",
"""
@@ -112,14 +187,14 @@ class PEMData {
MtJpIPIXynEqRy2mIw2GrKTtu3dqrW+ndarbD6D4yRY1hWHluiuOtzhxuueCuf9h
XCYEHZS1cqd8wokFPwIDAQAB
-----END PUBLIC KEY-----
""", RSAPublicKey.class);
""", RSAPublicKey.class, "SunRsaSign");
public static final Entry ecsecp256pub = new Entry("ecsecp256pub", """
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEi/kRGOL7wCPTN4KJ2ppeSt5UYB6u
cPjjuKDtFTXbguOIFDdZ65O/8HTUqS/sVzRF+dg7H3/tkQ/36KdtuADbwQ==
-----END PUBLIC KEY-----
""", ECPublicKey.class);
""", ECPublicKey.class, "SunEC");
// EC key with explicit parameters -- Not currently supported by SunEC
public static final String pubec_explicit = """
@@ -152,7 +227,7 @@ class PEMData {
P4c4mySRy5N3plFQUp3pIB7wqshi1t6hkdg7gRGjMtJpIPIXynEqRy2mIw2GrKTtu3dqrW+ndarb
D6D4yRY1hWHluiuOtzhxuueCuf9hXCYEHZS1cqd8wokFPwIDAQAB
-----END PRIVATE KEY-----
""", KeyPair.class);
""", KeyPair.class, "SunRsaSign");
public static final Entry oasrfc8410 = new Entry("oasrfc8410",
"""
@@ -161,7 +236,24 @@ class PEMData {
oB8wHQYKKoZIhvcNAQkJFDEPDA1DdXJkbGUgQ2hhaXJzgSEAGb9ECWmEzf6FQbrB
Z9w7lshQhqowtrbLDFw4rXAxZuE=
-----END PRIVATE KEY-----
""", KeyPair.class);
""", KeyPair.class, "SunEC");
public static final Entry oasxdh = new Entry("oasxdh",
"""
-----BEGIN PRIVATE KEY-----
MFECAQEwBQYDK2VuBCIEIIrMS7w5YxuBTyPFiaFvp6ILiGET7wY9ybk7Qqhe3hSq
gSEAB7ODPxRePrPnJMaj3f47blVx6c5bfxcllQzLp4bW5x4=
-----END PRIVATE KEY-----
""", KeyPair.class, "SunEC");
public static final Entry oasec = new Entry("oasec",
"""
-----BEGIN PRIVATE KEY-----
MIGFAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBCcwJQIBAQQgkGEVbZE1yAiO11Ya
eepcrBQL+HpVE4fy0V6jbpJcmkiBQgAERCqYYmN9uNT9Z1O2Z2VC3Zag9eUAhz7G
p8DqC21VrIgpqVQ4BrcWsieNg9fSd4N2hgfMpk9PCQwJQ8ifCMiBVQ==
-----END PRIVATE KEY-----
""", KeyPair.class, "SunEC");
public static final Entry rsaOpenSSL = new Entry("rsaOpenSSL",
"""
@@ -192,7 +284,7 @@ class PEMData {
EcgIOtkvoTrJ9Cquvuj+O7/d2yNoH0SZQ4IYJKq47/Z4kKhwXzJnBCCCBKgkjfub
RTQSNnSEgTaBD29l7FrhNRHX9lIKFZ23caCTBS6o3q3+KgPbq7ao
-----END RSA PRIVATE KEY-----
""", RSAPrivateKey.class);
""", RSAPrivateKey.class, "SunRsaSign");
static final Entry ed25519ep8 = new Entry("ed25519ep8",
"""
@@ -202,11 +294,11 @@ class PEMData {
vdMyi46+Dw7cOjwEQLtx5ME0NOOo7vlCGm3H/4j+Tf5UXrMb1UrkPjqc8OiLbC0n
IycFtI70ciPjgwDSjtCcPxR8fSxJPrm2yOJsRVo=
-----END ENCRYPTED PRIVATE KEY-----
""", EdECPrivateKey.class, "fish".toCharArray());
""", EdECPrivateKey.class, "SunEC", "fish".toCharArray());
// This is not meant to be decrypted and to stay as an EKPI
static final Entry ed25519ekpi = new Entry("ed25519ekpi",
ed25519ep8.pem(), EncryptedPrivateKeyInfo.class, null);
ed25519ep8.pem(), EncryptedPrivateKeyInfo.class, "SunEC", null);
static final Entry rsaCert = new Entry("rsaCert",
"""
@@ -237,7 +329,7 @@ class PEMData {
8gOYV33zkPhziWJt4uFMFIi7N2DLEk5UVZv1KTLZlfPl55DRs7j/Sb4vKHpB17AO
meVknxVvifDVY0TIz57t28Accsk6ClBCxNPluPU/8YLGAZJYsdDXjGcndQ13s5G7
-----END CERTIFICATE-----
""", X509Certificate.class);
""", X509Certificate.class, "SUN");
static final Entry ecCert = new Entry("ecCert",
"""
@@ -249,7 +341,68 @@ class PEMData {
lU3G9QAwCgYIKoZIzj0EAwIDSAAwRQIgMwYld7aBzkcRt9mn27YOed5+n0xN1y8Q
VEcFjLI/tBYCIQDU3szDZ/PK2mUZwtgQxLqHdh+f1JY0UwQS6M8QUvoDHw==
-----END CERTIFICATE-----
""", X509Certificate.class);
""", X509Certificate.class, "SUN");
private static final Entry rsaCrl = new Entry("rsaCrl",
"""
-----BEGIN X509 CRL-----
MIIBRTCBrwIBATANBgkqhkiG9w0BAQUFADBMMQswCQYDVQQGEwJVUzEaMBgGA1UE
ChMRVGVzdCBDZXJ0aWZpY2F0ZXMxITAfBgNVBAMTGEJhc2ljIEhUVFAgVVJJIFBl
ZXIgMSBDQRcNMDUwNjAzMjE0NTQ3WhcNMTUwNjAxMjE0NTQ3WqAvMC0wHwYDVR0j
BBgwFoAUa+bxcvx1zVdUhvIEd9hcfbmFdw4wCgYDVR0UBAMCAQEwDQYJKoZIhvcN
AQEFBQADgYEAZ+21yt1pJn2FU6vBwpFtAKVeBCCCqJVFiRxT84XbUw0BpLrCFvlk
FOo6tC95aoV7vPGwOEyUNbKJJOCzLliIwV1PPfgZQV20xohSIPISHdUjmlyttglv
AuEvltGnbP7ENxw18HxvM20XmHz+akuFu6npI6MkBjfoxvlq1bcdTrI=
-----END X509 CRL-----
""", X509CRL.class, "SUN");
// Few random manipulated Base64 characters in PEM content
private static final Entry invalidDer = new Entry("invalidDER", """
-----BEGIN PRIVATE KEY-----
MIICeAIBADANBhkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOtjMnCzPy4jCeZb
OdOvmvU3jl7+cvPFgL5MfqDCM5a8yI0yImg/hzibJJHLk3emUVBSnekgHvCqyGLW
3qGR2DuBEaMy0mkg8hfKcSpHLaYjDYaspO27d2qtb6d1qtsPoPjJFjWFYeW6K463
OHG654K5/2FcJgQdlLVyp3zCiQU/AgMBAAECgYEAwNkDkTv5rlX8nWLuLJV5kh/T
H9a93SRZxw8qy5Bv7bZ7ZNfHP7uUkHbi7iPojKWRhwo43692SdzR0dCSk7LGgN9q
CYvndsYR6gifVGBi0WF+St4+NdtcQ3VlNdsojy2BdIx0oC+r7i3bn+zc968O/kI+
EgdgrMcjjFqyx6tMHpECQQD8TYPKGHyN7Jdy28llCoUX/sL/yZ2vIi5mnDAFE5ae
KZQSkNAXG+8i9Qbs/Wdd5S3oZDqu+6DBn9gib80pYY05AkEA7tY59Oy8ka7nBlGP
g6Wo1usF2bKqk8vjko9ioZQay7f86aB10QFcAjCr+cCUm16Lc9DwzWl02nNggRZa
Jz8eNwJBAO+1zfLjFOPb14F/JHdlaVKE8EwKCFDuztsapd0M4Vtf8Zk6ERsDpU63
Ml9T2zOwnM9g+whpdjDAZ59ATdJ1JrECQQDReJQ2SxeL0lGPCiOLu9RcQp7L81aF
79G1bgp8WlAyEjlAkloiqEWRKiz7DDuKFR7Lwhognng9S+n87aS+PS57AkBh75t8
6onPAs4hkm+63dfzCojvEkALevO8J3OVX7YS5q9J1r75wDn60Ob0Zh+iiorpx8Ob
WqcWcoJqfdLEyBT+
-----END PRIVATE KEY-----
""", DEREncodable.class, null);
private static final Entry invalidPEM = new Entry("invalidPEM", """
-----BEGIN INVALID PEM-----
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBVS52ZSKZ0oES7twD2
GGwRIVu3uHlGIwlu0xzFe7sgIPntca2bHfYMhgGxrlCm0q+hZANiAAQNWgwWfLX8
8pYVjvwbfvDF9f+Oa9w6JjrfpWwFAUI6b1OPgrNUh+yXtUXnQNXnfUcIu0Os53bM
""", DEREncodable.class, null);
private static final Entry invalidHeader = new Entry("invalidHeader", """
---BEGIN PRIVATE KEY---
MC4CAQAwBQYDK2VwBCIEIFFZsmD+OKk67Cigc84/2fWtlKsvXWLSoMJ0MHh4jI4I
-----END PRIVATE KEY-----
""", DEREncodable.class, null);
private static final Entry invalidFooter = new Entry("invalidFooter", """
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIFFZsmD+OKk67Cigc84/2fWtlKsvXWLSoMJ0MHh4jI4I
---END PRIVATE KEY---
""", DEREncodable.class, null);
private static final Entry incorrectFooter = new Entry("incorrectFooter", """
-----BEGIN PRIVATE KEY-----
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBVS52ZSKZ0oES7twD2
GGwRIVu3uHlGIwlu0xzFe7sgIPntca2bHfYMhgGxrlCm0q+hZANiAAQNWgwWfLX8
8pYVjvwbfvDF9f+Oa9w6JjrfpWwFAUI6b1OPgrNUh+yXtUXnQNXnfUcIu0Os53bM
8fTqPkQl6RyWEDHeXqJK8zTBHMeBq9nLfDPSbzQgLDyC64Orn0D8exM=
-----END PUBLIC KEY-----
""", DEREncodable.class, null);
// EC cert with explicit parameters -- Not currently supported by SunEC
static final String ecCertEX = """
@@ -280,7 +433,7 @@ class PEMData {
8pYVjvwbfvDF9f+Oa9w6JjrfpWwFAUI6b1OPgrNUh+yXtUXnQNXnfUcIu0Os53bM
8fTqPkQl6RyWEDHeXqJK8zTBHMeBq9nLfDPSbzQgLDyC64Orn0D8exM=
-----END PRIVATE KEY-----
""", KeyPair.class);
""", KeyPair.class, "SunEC");
public static final Entry ecCSR = new Entry("ecCSR",
"""
@@ -297,7 +450,7 @@ class PEMData {
MQYMBGZpc2gwCgYIKoZIzj0EAwIDRwAwRAIgUBTdrMDE4BqruYRh1rRyKQBf48WR
kIX8R4dBK9h1VRcCIEBR2Mzvku/huTbWTwKVlXBZeEmwIlxKwpRepPtViXcW
-----END CERTIFICATE REQUEST-----
""", PEMRecord.class);
""", PEMRecord.class, "SunEC");
public static final String preData = "TEXT BLAH TEXT BLAH" +
System.lineSeparator();
@@ -318,39 +471,41 @@ class PEMData {
MQYMBGZpc2gwCgYIKoZIzj0EAwIDRwAwRAIgUBTdrMDE4BqruYRh1rRyKQBf48WR
kIX8R4dBK9h1VRcCIEBR2Mzvku/huTbWTwKVlXBZeEmwIlxKwpRepPtViXcW
-----END CERTIFICATE REQUEST-----
""" + postData, PEMRecord.class);
""" + postData, PEMRecord.class, "SunEC");
final static Pattern CR = Pattern.compile("\r");
final static Pattern LF = Pattern.compile("\n");
final static Pattern LSDEFAULT = Pattern.compile(System.lineSeparator());
public record Entry(String name, String pem, Class clazz, char[] password,
public record Entry(String name, String pem, Class clazz, String provider, char[] password,
byte[] der) {
public Entry(String name, String pem, Class clazz, char[] password,
public Entry(String name, String pem, Class clazz, String provider, char[] password,
byte[] der) {
this.name = name;
this.pem = pem;
this.clazz = clazz;
this.provider = provider;
this.password = password;
if (pem != null && pem.length() > 0) {
if (pem != null && pem.length() > 0 &&
!name.contains("incorrect") && !name.contains("invalid")) {
String[] pemtext = pem.split("-----");
this.der = Base64.getMimeDecoder().decode(pemtext[2]);
} else {
this.der = null;
}
}
Entry(String name, String pem, Class clazz, char[] password) {
this(name, pem, clazz, password, null);
Entry(String name, String pem, Class clazz, String provider, char[] password) {
this(name, pem, clazz, provider, password, null);
}
Entry(String name, String pem, Class clazz) {
this(name, pem, clazz, null, null);
Entry(String name, String pem, Class clazz, String provider) {
this(name, pem, clazz, provider, null, null);
}
public Entry newClass(String name, Class c) {
return new Entry(name, pem, c, password);
return new Entry(name, pem, c, provider, password);
}
public Entry newClass(Class c) {
@@ -360,20 +515,20 @@ class PEMData {
Entry makeCRLF(String name) {
return new Entry(name,
Pattern.compile(System.lineSeparator()).matcher(pem).replaceAll("\r\n"),
clazz, password());
clazz, provider, password());
}
Entry makeCR(String name) {
return new Entry(name,
Pattern.compile(System.lineSeparator()).matcher(pem).replaceAll("\r"),
clazz, password());
clazz, provider, password());
}
Entry makeNoCRLF(String name) {
return new Entry(name,
LF.matcher(CR.matcher(pem).replaceAll("")).
replaceAll(""),
clazz, password());
clazz, provider, password());
}
}
@@ -401,10 +556,12 @@ class PEMData {
static {
pubList.add(rsapub);
pubList.add(rsapsspub);
pubList.add(rsapubbc);
pubList.add(ecsecp256pub.makeCR("ecsecp256pub-r"));
pubList.add(ecsecp256pub.makeCRLF("ecsecp256pub-rn"));
privList.add(rsapriv);
privList.add(rsapsspriv);
privList.add(rsaprivbc);
privList.add(ecsecp256);
privList.add(ecsecp384);
@@ -413,9 +570,12 @@ class PEMData {
privList.add(rsaOpenSSL);
oasList.add(oasrfc8410);
oasList.add(oasbcpem);
oasList.add(oasec);
oasList.add(oasxdh);
certList.add(rsaCert);
certList.add(ecCert);
certList.add(rsaCrl);
entryList.addAll(pubList);
entryList.addAll(privList);
@@ -429,6 +589,11 @@ class PEMData {
failureEntryList.add(new Entry("emptyPEM", "", DEREncodable.class, null));
failureEntryList.add(new Entry("nullPEM", null, DEREncodable.class, null));
failureEntryList.add(incorrectFooter);
failureEntryList.add(invalidPEM);
failureEntryList.add(invalidDer);
failureEntryList.add(invalidHeader);
failureEntryList.add(invalidFooter);
}
static void checkResults(PEMData.Entry entry, String result) {

View File

@@ -26,6 +26,7 @@
/*
* @test
* @bug 8298420
* @library /test/lib
* @modules java.base/sun.security.pkcs
* java.base/sun.security.util
* @summary Testing basic PEM API decoding
@@ -37,23 +38,27 @@ import java.io.*;
import java.lang.Class;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.security.interfaces.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.security.spec.*;
import java.util.*;
import java.util.Arrays;
import jdk.test.lib.Asserts;
import sun.security.pkcs.PKCS8Key;
import sun.security.util.Pem;
public class PEMDecoderTest {
static HexFormat hex = HexFormat.of();
public static void main(String[] args) throws IOException {
public static void main(String[] args) throws Exception {
System.out.println("Decoder test:");
PEMData.entryList.forEach(PEMDecoderTest::test);
PEMData.entryList.forEach(entry -> test(entry, false));
System.out.println("Decoder test withFactory:");
PEMData.entryList.forEach(entry -> test(entry, true));
System.out.println("Decoder test returning DEREncodable class:");
PEMData.entryList.forEach(entry -> test(entry, DEREncodable.class));
System.out.println("Decoder test with encrypted PEM:");
@@ -95,7 +100,11 @@ public class PEMDecoderTest {
System.out.println("Check a Signature/Verify op is successful:");
PEMData.privList.forEach(PEMDecoderTest::testSignature);
PEMData.oasList.forEach(PEMDecoderTest::testSignature);
PEMData.oasList.stream().filter(e -> !e.name().endsWith("xdh"))
.forEach(PEMDecoderTest::testSignature);
System.out.println("Checking if decode() returns a PKCS8Key and can generate a pub");
PEMData.oasList.forEach(PEMDecoderTest::testPKCS8Key);
System.out.println("Checking if ecCSR:");
test(PEMData.ecCSR);
@@ -182,6 +191,10 @@ public class PEMDecoderTest {
} catch (Exception e) {
throw new AssertionError("error getting key", e);
}
testCertTypeConverter(PEMData.ecCert);
System.out.println("Decoder test testCoefZero:");
testCoefZero(PEMData.rsaCrtCoefZeroPriv);
}
static void testInputStream() throws IOException {
@@ -231,6 +244,24 @@ public class PEMDecoderTest {
throw new AssertionError("Failed");
}
// test that X509 CERTIFICATE is converted to CERTIFICATE in PEM
static void testCertTypeConverter(PEMData.Entry entry) throws CertificateEncodingException {
String certPem = entry.pem().replace("CERTIFICATE", "X509 CERTIFICATE");
Asserts.assertEqualsByteArray(entry.der(),
PEMDecoder.of().decode(certPem, X509Certificate.class).getEncoded());
certPem = entry.pem().replace("CERTIFICATE", "X.509 CERTIFICATE");
Asserts.assertEqualsByteArray(entry.der(),
PEMDecoder.of().decode(certPem, X509Certificate.class).getEncoded());
}
// test that when the crtCoeff is zero, the key is decoded but only the modulus and private
// exponent are used resulting in a different der
static void testCoefZero(PEMData.Entry entry) {
RSAPrivateKey decoded = PEMDecoder.of().decode(entry.pem(), RSAPrivateKey.class);
Asserts.assertNotEqualsByteArray(decoded.getEncoded(), entry.der());
}
static void testPEMRecord(PEMData.Entry entry) {
PEMRecord r = PEMDecoder.of().decode(entry.pem(), PEMRecord.class);
String expected = entry.pem().split("-----")[2].replace(System.lineSeparator(), "");
@@ -333,13 +364,26 @@ public class PEMDecoderTest {
// Change the Entry to use the given class as the expected class returned
static DEREncodable test(PEMData.Entry entry, Class c) {
return test(entry.newClass(c));
return test(entry.newClass(c), false);
}
// Run test with a given Entry
static DEREncodable test(PEMData.Entry entry) {
return test(entry, false);
}
// Run test with a given Entry
static DEREncodable test(PEMData.Entry entry, boolean withFactory) {
System.out.printf("Testing %s %s%n", entry.name(), entry.provider());
try {
DEREncodable r = test(entry.pem(), entry.clazz(), PEMDecoder.of());
PEMDecoder pemDecoder;
if (withFactory) {
Provider provider = Security.getProvider(entry.provider());
pemDecoder = PEMDecoder.of().withFactory(provider);
} else {
pemDecoder = PEMDecoder.of();
}
DEREncodable r = test(entry.pem(), entry.clazz(), pemDecoder);
System.out.println("PASS (" + entry.name() + ")");
return r;
} catch (Exception | AssertionError e) {
@@ -412,6 +456,19 @@ public class PEMDecoderTest {
}
}
private static void testPKCS8Key(PEMData.Entry entry) {
try {
PKCS8Key key = PEMDecoder.of().decode(entry.pem(), PKCS8Key.class);
PKCS8EncodedKeySpec spec =
new PKCS8EncodedKeySpec(key.getEncoded());
KeyFactory kf = KeyFactory.getInstance(key.getAlgorithm());
kf.generatePublic(spec);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
static void testClass(PEMData.Entry entry, Class clazz) throws IOException {
var pk = PEMDecoder.of().decode(entry.pem(), clazz);
}
@@ -472,9 +529,15 @@ public class PEMDecoderTest {
"should not be null");
}
AlgorithmParameterSpec spec = null;
String algorithm = switch(privateKey.getAlgorithm()) {
case "EC" -> "SHA256withECDSA";
case "EdDSA" -> "EdDSA";
case "RSASSA-PSS" -> {
spec = new PSSParameterSpec(
"SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1);
yield "RSASSA-PSS";
}
case null -> {
System.out.println("Algorithm is null " +
entry.name());
@@ -487,6 +550,9 @@ public class PEMDecoderTest {
try {
if (d instanceof PrivateKey) {
s = Signature.getInstance(algorithm);
if (spec != null) {
s.setParameter(spec);
}
s.initSign(privateKey);
s.update(data);
s.sign();

View File

@@ -26,9 +26,15 @@
/*
* @test
* @bug 8298420
* @library /test/lib
* @summary Testing basic PEM API encoding
* @enablePreview
* @modules java.base/sun.security.util
* @run main PEMEncoderTest PBEWithHmacSHA256AndAES_128
* @run main/othervm -Djava.security.properties=${test.src}/java.security-anotherAlgo
* PEMEncoderTest PBEWithHmacSHA512AndAES_256
* @run main/othervm -Djava.security.properties=${test.src}/java.security-emptyAlgo
* PEMEncoderTest PBEWithHmacSHA256AndAES_128
*/
import sun.security.util.Pem;
@@ -39,13 +45,22 @@ import javax.crypto.spec.PBEParameterSpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;
import jdk.test.lib.security.SecurityUtils;
import static jdk.test.lib.Asserts.assertEquals;
import static jdk.test.lib.Asserts.assertThrows;
public class PEMEncoderTest {
static Map<String, DEREncodable> keymap;
static String pkcs8DefaultAlgExpect;
public static void main(String[] args) throws Exception {
pkcs8DefaultAlgExpect = args[0];
PEMEncoder encoder = PEMEncoder.of();
// These entries are removed
@@ -63,7 +78,12 @@ public class PEMEncoderTest {
System.out.println("New instance re-encode testToString:");
keymap.keySet().stream().forEach(key -> testToString(key,
PEMEncoder.of()));
System.out.println("Same instance Encoder testEncodedKeySpec:");
testEncodedKeySpec(encoder);
System.out.println("New instance Encoder testEncodedKeySpec:");
testEncodedKeySpec(PEMEncoder.of());
System.out.println("Same instance Encoder testEmptyKey:");
testEmptyAndNullKey(encoder);
keymap = generateObjKeyMap(PEMData.encryptedList);
System.out.println("Same instance Encoder match test:");
keymap.keySet().stream().forEach(key -> testEncryptedMatch(key, encoder));
@@ -86,6 +106,13 @@ public class PEMEncoderTest {
PEMRecord pemRecord =
d.decode(PEMData.ed25519ep8.pem(), PEMRecord.class);
PEMData.checkResults(PEMData.ed25519ep8, pemRecord.toString());
// test PemRecord is encapsulated with PEM header and footer on encoding
String[] pemLines = PEMData.ed25519ep8.pem().split("\n");
String[] pemNoHeaderFooter = Arrays.copyOfRange(pemLines, 1, pemLines.length - 1);
PEMRecord pemR = new PEMRecord("ENCRYPTED PRIVATE KEY", String.join("\n",
pemNoHeaderFooter));
PEMData.checkResults(PEMData.ed25519ep8.pem(), encoder.encodeToString(pemR));
}
static Map generateObjKeyMap(List<PEMData.Entry> list) {
@@ -145,10 +172,12 @@ public class PEMEncoderTest {
static void testEncrypted(String key, PEMEncoder encoder) {
PEMData.Entry entry = PEMData.getEntry(key);
try {
encoder.withEncryption(
String pem = encoder.withEncryption(
(entry.password() != null ? entry.password() :
"fish".toCharArray()))
.encodeToString(keymap.get(key));
verifyEncriptionAlg(pem);
} catch (RuntimeException e) {
throw new AssertionError("Encrypted encoder failed with " +
entry.name(), e);
@@ -157,6 +186,11 @@ public class PEMEncoderTest {
System.out.println("PASS: " + entry.name());
}
private static void verifyEncriptionAlg(String pem) {
var epki = PEMDecoder.of().decode(pem, EncryptedPrivateKeyInfo.class);
assertEquals(epki.getAlgName(), pkcs8DefaultAlgExpect);
}
/*
Test cannot verify PEM was the same as known PEM because we have no
public access to the AlgoritmID.params and PBES2Parameters.
@@ -195,5 +229,42 @@ public class PEMEncoderTest {
PEMData.checkResults(entry, result);
System.out.println("PASS: " + entry.name());
}
}
static void testEncodedKeySpec(PEMEncoder encoder) throws NoSuchAlgorithmException {
KeyPair kp = getKeyPair();
encoder.encodeToString(new X509EncodedKeySpec(kp.getPublic().getEncoded()));
encoder.encodeToString(new PKCS8EncodedKeySpec(kp.getPrivate().getEncoded()));
System.out.println("PASS: testEncodedKeySpec");
}
private static void testEmptyAndNullKey(PEMEncoder encoder) throws NoSuchAlgorithmException {
KeyPair kp = getKeyPair();
assertThrows(IllegalArgumentException.class, () -> encoder.encode(
new KeyPair(kp.getPublic(), new EmptyKey())));
assertThrows(IllegalArgumentException.class, () -> encoder.encode(
new KeyPair(kp.getPublic(), null)));
assertThrows(IllegalArgumentException.class, () -> encoder.encode(
new KeyPair(new EmptyKey(), kp.getPrivate())));
assertThrows(IllegalArgumentException.class, () -> encoder.encode(
new KeyPair(null, kp.getPrivate())));
System.out.println("PASS: testEmptyKey");
}
private static KeyPair getKeyPair() throws NoSuchAlgorithmException {
Provider provider = Security.getProvider("SunRsaSign");
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", provider);
kpg.initialize(SecurityUtils.getTestKeySize("RSA"));
return kpg.generateKeyPair();
}
private static class EmptyKey implements PublicKey, PrivateKey {
@Override
public String getAlgorithm() { return "Test"; }
@Override
public String getFormat() { return "Test"; }
@Override
public byte[] getEncoded() { return new byte[0]; }
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8298420
* @library /test/lib
* @summary Testing PEM API is thread safe
* @enablePreview
* @modules java.base/sun.security.util
*/
import java.security.*;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import jdk.test.lib.security.SecurityUtils;
public class PEMMultiThreadTest {
static final int THREAD_COUNT = 5;
static final int KEYS_COUNT = 50;
public static void main(String[] args) throws Exception {
PEMEncoder encoder = PEMEncoder.of();
try (ExecutorService ex = Executors.newFixedThreadPool(THREAD_COUNT)) {
Map<Integer, PublicKey> keys = new HashMap<>();
Map<Integer, String> encoded = Collections.synchronizedMap(new HashMap<>());
Map<Integer, String> decoded = Collections.synchronizedMap(new HashMap<>());
final CountDownLatch encodingComplete = new CountDownLatch(KEYS_COUNT);
final CountDownLatch decodingComplete = new CountDownLatch(KEYS_COUNT);
// Generate keys and encode them in parallel
for (int i = 0; i < KEYS_COUNT; i++) {
final int finalI = i;
KeyPair kp = getKeyPair();
keys.put(finalI, kp.getPublic());
ex.submit(() -> {
encoded.put(finalI, encoder.encodeToString(kp.getPublic()));
encodingComplete.countDown();
});
}
encodingComplete.await();
// Decode keys in parallel
PEMDecoder decoder = PEMDecoder.of();
for (Map.Entry<Integer, String> entry : encoded.entrySet()) {
ex.submit(() -> {
decoded.put(entry.getKey(), decoder.decode(entry.getValue(), PublicKey.class)
.toString());
decodingComplete.countDown();
});
}
decodingComplete.await();
// verify all keys were properly encoded and decoded comparing with the original key map
for (Map.Entry<Integer, PublicKey> kp : keys.entrySet()) {
if (!decoded.get(kp.getKey()).equals(kp.getValue().toString())) {
throw new RuntimeException("a key was not properly encoded and decoded: " + decoded);
}
}
}
System.out.println("PASS: testThreadSafety");
}
private static KeyPair getKeyPair() throws NoSuchAlgorithmException {
String alg = "EC";
KeyPairGenerator kpg = KeyPairGenerator.getInstance(alg);
kpg.initialize(SecurityUtils.getTestKeySize(alg));
return kpg.generateKeyPair();
}
}

View File

@@ -0,0 +1 @@
jdk.epkcs8.defaultAlgorithm=PBEWithHmacSHA512AndAES_256

View File

@@ -0,0 +1 @@
jdk.epkcs8.defaultAlgorithm=

View File

@@ -25,11 +25,15 @@
/**
* @test
* @library /test/lib
* @modules java.base/sun.security.util
* @bug 8298420
* @summary Testing encryptKey
* @enablePreview
*/
import sun.security.util.Pem;
import javax.crypto.EncryptedPrivateKeyInfo;
import javax.crypto.SecretKey;
import javax.crypto.spec.PBEParameterSpec;
@@ -37,8 +41,13 @@ import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.PEMDecoder;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Arrays;
import static jdk.test.lib.Asserts.assertEquals;
public class EncryptKey {
private static final String encEdECKey =
@@ -56,6 +65,8 @@ public class EncryptKey {
passwdText.getBytes(), "PBE");
public static void main(String[] args) throws Exception {
Provider p = Security.getProvider(System.getProperty("test.provider.name", "SunJCE"));
EncryptedPrivateKeyInfo ekpi = PEMDecoder.of().decode(encEdECKey,
EncryptedPrivateKeyInfo.class);
PrivateKey priKey = PEMDecoder.of().withDecryption(password).
@@ -71,6 +82,19 @@ public class EncryptKey {
" with expected.");
}
// Test encryptKey(PrivateKey, char[], String, ...) with provider
e = EncryptedPrivateKeyInfo.encryptKey(priKey, password, ekpi.getAlgName(),
ap.getParameterSpec(PBEParameterSpec.class), p);
if (!Arrays.equals(ekpi.getEncryptedData(), e.getEncryptedData())) {
throw new AssertionError("encryptKey() didn't match" +
" with expected.");
}
// Test encryptKey(PrivateKey, char[], String, ...) with provider and null algorithm
e = EncryptedPrivateKeyInfo.encryptKey(priKey, password, null, null,
p);
assertEquals(e.getAlgName(), Pem.DEFAULT_ALGO);
// Test encryptKey(PrivateKey, Key, String, ...)
e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, ekpi.getAlgName(),
ap.getParameterSpec(PBEParameterSpec.class),null, null);
@@ -78,5 +102,26 @@ public class EncryptKey {
throw new AssertionError("encryptKey() didn't match" +
" with expected.");
}
// Test encryptKey(PrivateKey, Key, String, ...) with provider and null random
e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, ekpi.getAlgName(),
ap.getParameterSpec(PBEParameterSpec.class), p, null);
if (!Arrays.equals(ekpi.getEncryptedData(), e.getEncryptedData())) {
throw new AssertionError("encryptKey() didn't match" +
" with expected.");
}
// Test encryptKey(PrivateKey, Key, String, ...) with provider and SecureRandom
e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, ekpi.getAlgName(),
ap.getParameterSpec(PBEParameterSpec.class), p, new SecureRandom());
if (!Arrays.equals(ekpi.getEncryptedData(), e.getEncryptedData())) {
throw new AssertionError("encryptKey() didn't match" +
" with expected.");
}
// Test encryptKey(PrivateKey, Key, String, ...) with provider and null algorithm
e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, null, null,
p, new SecureRandom());
assertEquals(e.getAlgName(), Pem.DEFAULT_ALGO);
}
}

View File

@@ -35,6 +35,8 @@ import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.PEMDecoder;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.Security;
import java.util.Arrays;
public class GetKey {
@@ -48,12 +50,29 @@ public class GetKey {
IycFtI70ciPjgwDSjtCcPxR8fSxJPrm2yOJsRVo=
-----END ENCRYPTED PRIVATE KEY-----
""";
private static final String encDHECKey =
"""
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIBvDBmBgkqhkiG9w0BBQ0wWTA4BgkqhkiG9w0BBQwwKwQUN8pkErJx7aqH0fJF
BcOadPKiuRoCAhAAAgEQMAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAECBBAT1Vwd
gU4rTd6zy7lKr4wmBIIBUMe+2+O0AG6t4CMSHcDVceRg2jvbs5PmPjW4Ka5mDich
hVEsjSpJLbUyJdbji6UaiUpuWgvYSMLZ10pfhOFw/ssXwCw+JrlXUqDpQGLaW8ZR
zSL3CoozTI2Y6EBdWt53KbySwtZMoTpW/W3vPi98bJXtR635msf6gYXmSUP7DyoJ
79dxz3pRYsnOuBe0yZ2wTq9iMgTMudzLJAFX2qyi+3KOb1g5Va9DYAqJmzCYOd74
+I+0gGNFtSc1vGQYr3cAfcKT8AZ1RHE4IkpnpgFD5HsZ8f4hy0yK8juk9NE9Gzuy
B929LBXk6V3L0MKzIABS3QvAlhWETM6XtGBDugzAgsooo9lEHLwYRldvOlL+QYyE
CtqDmXOrgEMWvxWGEFCTKYhKkqMKjU3y3GiozEEdb9j2okW1s30yHQjIoj0OR4nB
D8GeP0QnY73NfbOw7z81TA==
-----END ENCRYPTED PRIVATE KEY-----
""";
private static final String passwdText = "fish";
private static final char[] password = passwdText.toCharArray();
private static final SecretKey key = new SecretKeySpec(
passwdText.getBytes(), "PBE");
public static void main(String[] args) throws Exception {
Provider p = Security.getProvider(System.getProperty("test.provider.name", "SunJCE"));
EncryptedPrivateKeyInfo ekpi = PEMDecoder.of().decode(encEdECKey,
EncryptedPrivateKeyInfo.class);
PrivateKey priKey = PEMDecoder.of().withDecryption(password).
@@ -66,11 +85,23 @@ public class GetKey {
+ "match with expected.");
}
// Test getKey(key, provider)
// Test getKey(key, provider) provider null
if (!Arrays.equals(priKey.getEncoded(),
ekpi.getKey(key, null).getEncoded())) {
throw new AssertionError("getKey(key, provider) " +
"didn't match with expected.");
}
// Test getKey(key, provider) with provider
EncryptedPrivateKeyInfo ekpiDH = PEMDecoder.of().decode(encDHECKey,
EncryptedPrivateKeyInfo.class);
PrivateKey priKeyDH = PEMDecoder.of().withDecryption(password).
decode(encDHECKey, PrivateKey.class);
if (!Arrays.equals(priKeyDH.getEncoded(),
ekpiDH.getKey(key, p).getEncoded())) {
throw new AssertionError("getKey(key, provider) " +
"didn't match with expected.");
}
}
}

View File

@@ -61,19 +61,27 @@ public class TestCPUTimeSampleThrottling {
private static void testThrottleSettingsPeriod() throws Exception {
float rate = countEvents(1000, "10ms").rate();
Asserts.assertTrue(rate > 90 && rate < 110, "Expected around 100 events per second, got " + rate);
Asserts.assertTrue(rate > 75 && rate < 110, "Expected around 100 events per second, got " + rate);
}
private record EventCount(long count, float time) {
private record EventCount(long count, float cpuTime) {
float rate() {
return count / time;
return count / cpuTime;
}
}
private static EventCount countEvents(int timeMs, String rate) throws Exception {
try(Recording recording = new Recording()) {
/**
* Counting the events that are emitted for a given throttle in a given time.
* <p>
* The result is wall-clock independent; it only records the CPU-time and the number of
* emitted events. The result, therefore, does not depend on the load of the machine.
* And because failed events are counted too, the result is not affected by the thread
* doing other in-JVM work (like garbage collection).
*/
private static EventCount countEvents(int timeMs, String throttle) throws Exception {
try (Recording recording = new Recording()) {
recording.enable(EventNames.CPUTimeSample)
.with("throttle", rate);
.with("throttle", throttle);
var bean = ManagementFactory.getThreadMXBean();
@@ -92,8 +100,6 @@ public class TestCPUTimeSampleThrottling {
.equals(Thread.currentThread().getName()))
.count();
System.out.println("Event count: " + eventCount + ", CPU time: " + spendCPUTime / 1_000_000_000f + "s");
return new EventCount(eventCount, spendCPUTime / 1_000_000_000f);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2025, 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
@@ -557,6 +557,36 @@
* @run main/othervm/manual -Djava.security.debug=certpath CAInterop ssltlsrootrsa2022 CRL
*/
/*
* @test id=sectigotlsrootr46
* @bug 8359170
* @summary Interoperability tests with Sectigo Public Server Authentication
* Root R46
* @library /test/lib
* @build jtreg.SkippedException ValidatePathWithURL CAInterop
* @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop
* sectigotlsrootr46 OCSP
* @run main/othervm/manual -Djava.security.debug=certpath,ocsp
* -Dcom.sun.security.ocsp.useget=false CAInterop sectigotlsrootr46 OCSP
* @run main/othervm/manual -Djava.security.debug=certpath CAInterop
* sectigotlsrootr46 CRL
*/
/*
* @test id=sectigotlsroote46
* @bug 8359170
* @summary Interoperability tests with Sectigo Public Server Authentication
* Root E46
* @library /test/lib
* @build jtreg.SkippedException ValidatePathWithURL CAInterop
* @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop
* sectigotlsroote46 OCSP
* @run main/othervm/manual -Djava.security.debug=certpath,ocsp
* -Dcom.sun.security.ocsp.useget=false CAInterop sectigotlsroote46 OCSP
* @run main/othervm/manual -Djava.security.debug=certpath CAInterop
* sectigotlsroote46 CRL
*/
/**
* Collection of certificate validation tests for interoperability with external CAs.
* These tests are marked as manual as they depend on external infrastructure and may fail
@@ -635,20 +665,20 @@ public class CAInterop {
"https://revoked.sfig2.catest.starfieldtech.com");
case "globalsigneccrootcar4" ->
new CATestURLs("https://good.gsr4.demo.pki.goog",
"https://revoked.gsr4.demo.pki.goog");
new CATestURLs("https://good.gsr4.demosite.pki.goog",
"https://revoked.gsr4.demosite.pki.goog");
case "gtsrootcar1" ->
new CATestURLs("https://good.gtsr1.demo.pki.goog",
"https://revoked.gtsr1.demo.pki.goog");
new CATestURLs("https://good.gtsr1.demosite.pki.goog",
"https://revoked.gtsr1.demosite.pki.goog");
case "gtsrootcar2" ->
new CATestURLs("https://good.gtsr2.demo.pki.goog",
"https://revoked.gtsr2.demo.pki.goog");
new CATestURLs("https://good.gtsr2.demosite.pki.goog",
"https://revoked.gtsr2.demosite.pki.goog");
case "gtsrootecccar3" ->
new CATestURLs("https://good.gtsr3.demo.pki.goog",
"https://revoked.gtsr3.demo.pki.goog");
new CATestURLs("https://good.gtsr3.demosite.pki.goog",
"https://revoked.gtsr3.demosite.pki.goog");
case "gtsrootecccar4" ->
new CATestURLs("https://good.gtsr4.demo.pki.goog",
"https://revoked.gtsr4.demo.pki.goog");
new CATestURLs("https://good.gtsr4.demosite.pki.goog",
"https://revoked.gtsr4.demosite.pki.goog");
case "microsoftecc2017" ->
new CATestURLs("https://acteccroot2017.pki.microsoft.com",
@@ -742,6 +772,13 @@ public class CAInterop {
new CATestURLs("https://test-root-2022-rsa.ssl.com",
"https://revoked-root-2022-rsa.ssl.com");
case "sectigotlsrootr46" ->
new CATestURLs("https://sectigopublicserverauthenticationrootr46-ev.sectigo.com",
"https://sectigopublicserverauthenticationrootr46-ev.sectigo.com:444");
case "sectigotlsroote46" ->
new CATestURLs("https://sectigopublicserverauthenticationroote46-ev.sectigo.com",
"https://sectigopublicserverauthenticationroote46-ev.sectigo.com:444");
default -> throw new RuntimeException("No test setup found for: " + alias);
};
}

View File

@@ -0,0 +1,310 @@
/*
* Copyright (c) 2025, 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 8359170
* @summary Interoperability tests with Sectigo Public Code Signing Root CAs
* @build ValidatePathWithParams
* @run main/othervm/manual -Djava.security.debug=ocsp,certpath SectigoCSRootCAs OCSP
* @run main/othervm/manual -Djava.security.debug=certpath SectigoCSRootCAs CRL
*/
public class SectigoCSRootCAs {
public static void main(String[] args) throws Exception {
ValidatePathWithParams pathValidator = new ValidatePathWithParams(null);
if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) {
pathValidator.enableCRLCheck();
} else {
// OCSP check by default
pathValidator.enableOCSPCheck();
}
new SectigoCSRootCA_R46().runTest(pathValidator);
new SectigoCSRootCA_E46().runTest(pathValidator);
}
}
class SectigoCSRootCA_R46 {
// Owner: CN=Sectigo Public Code Signing CA R36, O=Sectigo Limited, C=GB
// Issuer: CN=Sectigo Public Code Signing Root R46, O=Sectigo Limited, C=GB
// Serial number: 621d6d0c52019e3b9079152089211c0a
// Valid from: Sun Mar 21 17:00:00 PDT 2021 until: Fri Mar 21 16:59:59
// PDT 2036
private static final String INT = "-----BEGIN CERTIFICATE-----\n" +
"MIIGGjCCBAKgAwIBAgIQYh1tDFIBnjuQeRUgiSEcCjANBgkqhkiG9w0BAQwFADBW\n" +
"MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQD\n" +
"EyRTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwHhcNMjEwMzIy\n" +
"MDAwMDAwWhcNMzYwMzIxMjM1OTU5WjBUMQswCQYDVQQGEwJHQjEYMBYGA1UEChMP\n" +
"U2VjdGlnbyBMaW1pdGVkMSswKQYDVQQDEyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNp\n" +
"Z25pbmcgQ0EgUjM2MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAmyud\n" +
"U/o1P45gBkNqwM/1f/bIU1MYyM7TbH78WAeVF3llMwsRHgBGRmxDeEDIArCS2VCo\n" +
"Vk4Y/8j6stIkmYV5Gej4NgNjVQ4BYoDjGMwdjioXan1hlaGFt4Wk9vT0k2oWJMJj\n" +
"L9G//N523hAm4jF4UjrW2pvv9+hdPX8tbbAfI3v0VdJiJPFy/7XwiunD7mBxNtec\n" +
"M6ytIdUlh08T2z7mJEXZD9OWcJkZk5wDuf2q52PN43jc4T9OkoXZ0arWZVeffvMr\n" +
"/iiIROSCzKoDmWABDRzV/UiQ5vqsaeFaqQdzFf4ed8peNWh1OaZXnYvZQgWx/SXi\n" +
"JDRSAolRzZEZquE6cbcH747FHncs/Kzcn0Ccv2jrOW+LPmnOyB+tAfiWu01TPhCr\n" +
"9VrkxsHC5qFNxaThTG5j4/Kc+ODD2dX/fmBECELcvzUHf9shoFvrn35XGf2RPaNT\n" +
"O2uSZ6n9otv7jElspkfK9qEATHZcodp+R4q2OIypxR//YEb3fkDn3UayWW9bAgMB\n" +
"AAGjggFkMIIBYDAfBgNVHSMEGDAWgBQy65Ka/zWWSC8oQEJwIDaRXBeF5jAdBgNV\n" +
"HQ4EFgQUDyrLIIcouOxvSK4rVKYpqhekzQwwDgYDVR0PAQH/BAQDAgGGMBIGA1Ud\n" +
"EwEB/wQIMAYBAf8CAQAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwGwYDVR0gBBQwEjAG\n" +
"BgRVHSAAMAgGBmeBDAEEATBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsLnNl\n" +
"Y3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ1Jvb3RSNDYuY3JsMHsG\n" +
"CCsGAQUFBwEBBG8wbTBGBggrBgEFBQcwAoY6aHR0cDovL2NydC5zZWN0aWdvLmNv\n" +
"bS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdSb290UjQ2LnA3YzAjBggrBgEFBQcw\n" +
"AYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wDQYJKoZIhvcNAQEMBQADggIBAAb/\n" +
"guF3YzZue6EVIJsT/wT+mHVEYcNWlXHRkT+FoetAQLHI1uBy/YXKZDk8+Y1LoNqH\n" +
"rp22AKMGxQtgCivnDHFyAQ9GXTmlk7MjcgQbDCx6mn7yIawsppWkvfPkKaAQsiqa\n" +
"T9DnMWBHVNIabGqgQSGTrQWo43MOfsPynhbz2Hyxf5XWKZpRvr3dMapandPfYgoZ\n" +
"8iDL2OR3sYztgJrbG6VZ9DoTXFm1g0Rf97Aaen1l4c+w3DC+IkwFkvjFV3jS49ZS\n" +
"c4lShKK6BrPTJYs4NG1DGzmpToTnwoqZ8fAmi2XlZnuchC4NPSZaPATHvNIzt+z1\n" +
"PHo35D/f7j2pO1S8BCysQDHCbM5Mnomnq5aYcKCsdbh0czchOm8bkinLrYrKpii+\n" +
"Tk7pwL7TjRKLXkomm5D1Umds++pip8wH2cQpf93at3VDcOK4N7EwoIJB0kak6pSz\n" +
"Eu4I64U6gZs7tS/dGNSljf2OSSnRr7KWzq03zl8l75jy+hOds9TWSenLbjBQUGR9\n" +
"6cFr6lEUfAIEHVC1L68Y1GGxx4/eRI82ut83axHMViw1+sVpbPxg51Tbnio1lB93\n" +
"079WPFnYaOvfGAA0e0zcfF/M9gXr+korwQTh2Prqooq2bYNMvUoUKD85gnJ+t0sm\n" +
"rWrb8dee2CvYZXD5laGtaAxOfy/VKNmwuWuAh9kc\n" +
"-----END CERTIFICATE-----";
// Owner: CN=Sectigo Limited, O=Sectigo Limited, ST=West Yorkshire, C=GB
// Issuer: CN=Sectigo Public Code Signing CA R36, O=Sectigo Limited, C=GB
// Serial number: c1de046377578f1605414f3fa91bf5f6
// Valid from: Wed Jun 04 17:00:00 PDT 2025 until: Fri Jun 05 16:59:59
// PDT 2026
private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
"MIIGRDCCBKygAwIBAgIRAMHeBGN3V48WBUFPP6kb9fYwDQYJKoZIhvcNAQEMBQAw\n" +
"VDELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDErMCkGA1UE\n" +
"AxMiU2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIFIzNjAeFw0yNTA2MDUw\n" +
"MDAwMDBaFw0yNjA2MDUyMzU5NTlaMFoxCzAJBgNVBAYTAkdCMRcwFQYDVQQIDA5X\n" +
"ZXN0IFlvcmtzaGlyZTEYMBYGA1UECgwPU2VjdGlnbyBMaW1pdGVkMRgwFgYDVQQD\n" +
"DA9TZWN0aWdvIExpbWl0ZWQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC\n" +
"AQDCYjakgsoYkqVpENW0MuN5hBZDdIM60WJgBXU7zTAXORntSu/Grn/SQywwTg4o\n" +
"ltRcKuCp0Cd5zLAIjtgpVDDACWHgxKUtxerjjBZeGp0+viR+biLL0mVNPXgZZ5bQ\n" +
"AnDYVKJaGnPsXQD8l+Bn/R2c4cw7mXjBYp2KrTuqOBkPzk4LmdgpKXjxiw1yYb+n\n" +
"WKZ+3BMLIU6/k+LB9+WB6Odrl4Lff1jB4C6XhQELGjZAbpkFB2+Qr0ajIA3ZFXqU\n" +
"IMh0j5oD5juuXxryOvCgSBkEwxPHnlXxZBNd3DmrZ9NGClBIGE2f9FOjzo5Rl7lV\n" +
"KlzFdFmcH8LaLtWjniF+iT+YZw3Ld1O9VMK7RaHePsS4JYfbjeapoCEgudecmIz4\n" +
"5Q2tTjCdR5s/SxiVbynfEw+cAGeiv4sRXNSg0uhZ2eGMHh6mPley2pUoRMR8Qx1U\n" +
"0Uzg2NtPsHAo0DIH3jKEWU2zP5UPwCfqKYGaZLNLeGh07NZHBCp3TGp9kPVen5Ib\n" +
"tnJssu+pab7fixvbpDM4/r9MkKU6C1IsE6lffyON0PA6LaywwecYTJGpieXqoz03\n" +
"5UmQXvAzkb9omIAcQ6yWMZNrqwwG9XRKQEhvG3v7sbFkck1KZOz4r/KHkLx9sIxm\n" +
"vngdD/qLFebxPIvPT0GKnvSzuGcdQXVTdkZBBBrunv+XpQIDAQABo4IBiTCCAYUw\n" +
"HwYDVR0jBBgwFoAUDyrLIIcouOxvSK4rVKYpqhekzQwwHQYDVR0OBBYEFGMpbbJO\n" +
"xiuD6t+HEyA3hjp4devXMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBMG\n" +
"A1UdJQQMMAoGCCsGAQUFBwMDMEoGA1UdIARDMEEwNQYMKwYBBAGyMQECAQMCMCUw\n" +
"IwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAgGBmeBDAEEATBJ\n" +
"BgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLnNlY3RpZ28uY29tL1NlY3RpZ29Q\n" +
"dWJsaWNDb2RlU2lnbmluZ0NBUjM2LmNybDB5BggrBgEFBQcBAQRtMGswRAYIKwYB\n" +
"BQUHMAKGOGh0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0NvZGVT\n" +
"aWduaW5nQ0FSMzYuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdv\n" +
"LmNvbTANBgkqhkiG9w0BAQwFAAOCAYEAP2OCzJ+0hrg4XK3w+Ypoe0G5hKfzZ9RH\n" +
"nDcgY8BjgWYVOlN9ad2bU70RfgkZzylkaSt02KHOpkXmYpgfjZsovmyUchvlZ4fU\n" +
"RmivZleuO3G/ZvDFX373S40QFDd+lC1LYYUolRVz7/ZU2Vzql4FxsM1psRaW17xj\n" +
"jf9qaAvDlOH45eEEkfRUbIDdn1UYqDxdCN+90jtD1vRWkYINvE1T6mq3rHpEVoTS\n" +
"dIOgmcSL3MAKMB0LxWUPfoVdhnoUuoIxIAcV1SuR6zej4wHjClEaR8ReT/C23Jr3\n" +
"hQ4VDbfGu3gvlZG8/+lNmT+t4WaNPECxbFP0BgbD70FP594mSVH3fgptYiiRN7ez\n" +
"iUfOSBeCZpSMm7Z5P0KkxkagyFIR3vzgvqbJS/iaomvd9ZIkd9AwMEhugJpITeZj\n" +
"lKSXs+2q2UHQdLTPGVoOjmqyPhDGKAeVVF+jLIUWwtAaAoJm6ooXSp8sAeLA+e+K\n" +
"6RUFETVxhCefCjkbWq64OYLXriDb0l+W\n" +
"-----END CERTIFICATE-----";
// Owner: CN=Sectigo Limited, O=Sectigo Limited, ST=West Yorkshire, C=GB
// Issuer: CN=Sectigo Public Code Signing CA R36, O=Sectigo Limited, C=GB
// Serial number: 5ca6fb60da04db99dedbbc0c37131ec
// Valid from: Wed Jun 04 17:00:00 PDT 2025 until: Sun Jun 04 16:59:59
// PDT 2028
private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
"MIIGQzCCBKugAwIBAgIQBcpvtg2gTbmd7bvAw3Ex7DANBgkqhkiG9w0BAQwFADBU\n" +
"MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSswKQYDVQQD\n" +
"EyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2MB4XDTI1MDYwNTAw\n" +
"MDAwMFoXDTI4MDYwNDIzNTk1OVowWjELMAkGA1UEBhMCR0IxFzAVBgNVBAgMDldl\n" +
"c3QgWW9ya3NoaXJlMRgwFgYDVQQKDA9TZWN0aWdvIExpbWl0ZWQxGDAWBgNVBAMM\n" +
"D1NlY3RpZ28gTGltaXRlZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB\n" +
"ALDjoFCMN16zlrcv/saieSYT7FXEhTVDPLNzGAbNdBEX09FoL5EIkiN3biVIbDki\n" +
"bIocCFpo/yTrjARG/zz82AjdWHyomdtDjL35CQmgiUX7V8tu64xUfUAgadqm+0PL\n" +
"by1LRddKE7chpdJu+EDEmeYDPqcRGM+u8suPgosFf6XfVNFy/FZJiD1c7q6JNZ8i\n" +
"5NrvTs0zA9HckKE3uvPO9rw56EyF3SfUz9+zHKHwSElv8nCYpREudUf4yCzPNisK\n" +
"MVovzeCo36nzJFEdWTnDOr4mtvfCEGvJOU3mgzpECK7QF+yFifr90SG4lvrwzkig\n" +
"wYQymukXmB2gxN1tGOvgLig3Q/b4vljBiEeRPEba/L8YQnaXpR/BnPze8yb2t39l\n" +
"bzmnghkWkGA0PAB2vrzpi7pq12fGOD0+ErtAzAl/TAD/UFWwXDQLWX9LXRRKi5E+\n" +
"ScTlqLl9U1q9HsWYfM6CvLbc32TByaQ8yBytvsSRB0C0blp7CtP5MAc8j9xJdwAs\n" +
"Mj2bvSOfA+NJ0Kdg/tqdHHU6hex2HnGzDiEhovm6u/oAfDp/i2bBKLgARglMfGaC\n" +
"hFWeHLL6GAyBezMv+AQNCDCTYDMlqAihVMRUAfYgoHcVCfvTSETTTGdRUDFzIdCA\n" +
"wNwSVfykpadsev43I2IF+F3aNgJYuXnpxSCLPngemcgxAgMBAAGjggGJMIIBhTAf\n" +
"BgNVHSMEGDAWgBQPKssghyi47G9IritUpimqF6TNDDAdBgNVHQ4EFgQUlff/C/GC\n" +
"faJ+Y7ua3hKsCsrW9y4wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwEwYD\n" +
"VR0lBAwwCgYIKwYBBQUHAwMwSgYDVR0gBEMwQTA1BgwrBgEEAbIxAQIBAwIwJTAj\n" +
"BggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYGZ4EMAQQBMEkG\n" +
"A1UdHwRCMEAwPqA8oDqGOGh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1\n" +
"YmxpY0NvZGVTaWduaW5nQ0FSMzYuY3JsMHkGCCsGAQUFBwEBBG0wazBEBggrBgEF\n" +
"BQcwAoY4aHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29kZVNp\n" +
"Z25pbmdDQVIzNi5jcnQwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3RpZ28u\n" +
"Y29tMA0GCSqGSIb3DQEBDAUAA4IBgQAfVq3mY7ggMcTJeWKKrGxs9RUiuAY0p4Xv\n" +
"CHNQViM/tHAn0t/nkPp+d2Ji3Zr6PefN+1F6zmsxsbZHse52JNHWYUwCb/Dx4Vw6\n" +
"3Wnc1zhXtZnvUTUfgrivuIsMjUG8yzTdEt/taMKEO0KqlKPsBPgFKveDVVaq9UZa\n" +
"FfxTWqgrnvkvP/Lag/YeKKj4cJG+a/MJZJm7kvyaBNKXVAamr/bumoxKDzpD67ds\n" +
"n9qwBi2Mv0rRXvZ2SHQXzsJ/zjNKWUhpPVrpypaER7EUxjNuSgC4L8AmfvHiO67v\n" +
"9EVIEud+beP3FtCXl/cSHhVeDxiC0KBXXBl9zLBaYvCH+8iABnZLStLgBDtfdkfk\n" +
"TZEAGbrNOXJDMnKRxr8y377Zq+KHwfiTnyizACHyMMTi+CCwg1ZFGcLOHa5shByc\n" +
"Ln9lYysM1/5vrEjt3ZUw11+pDqbPCGS++xgAwcftKfJ0TZrW/g6NZ9URg+11H9ad\n" +
"WalBv2VkhJAFJam9P2Y+pi9luk85sGo=\n" +
"-----END CERTIFICATE-----";
public void runTest(ValidatePathWithParams pathValidator) throws Exception {
// Validate valid
pathValidator.validate(new String[]{VALID, INT},
ValidatePathWithParams.Status.GOOD, null, System.out);
// Validate Revoked
pathValidator.validate(new String[]{REVOKED, INT},
ValidatePathWithParams.Status.REVOKED,
"Thu Jun 05 10:27:45 PDT 2025", System.out);
}
}
class SectigoCSRootCA_E46 {
// Owner: CN=Sectigo Public Code Signing CA EV E36, O=Sectigo Limited, C=GB
// Issuer: CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB
// Serial number: 3774434f9eb40e221f9236ca1f2f2717
// Valid from: Sun Mar 21 17:00:00 PDT 2021 until: Fri Mar 21 16:59:59
// PDT 2036
private static final String INT_VALID = "-----BEGIN CERTIFICATE-----\n" +
"MIIDMDCCAragAwIBAgIQN3RDT560DiIfkjbKHy8nFzAKBggqhkjOPQQDAzBWMQsw\n" +
"CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRT\n" +
"ZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBFNDYwHhcNMjEwMzIyMDAw\n" +
"MDAwWhcNMzYwMzIxMjM1OTU5WjBXMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2Vj\n" +
"dGlnbyBMaW1pdGVkMS4wLAYDVQQDEyVTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25p\n" +
"bmcgQ0EgRVYgRTM2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3mMV9nNViYoH\n" +
"4aSrPwFjpbbeXHw2pMbqezwDGb45uEZQr3qI9Hgt0k4R26o5upfXzJt03F8efu0r\n" +
"RNEs4yDDz6OCAWMwggFfMB8GA1UdIwQYMBaAFM99LKCQepgd3bZehcLg2hVx0uVe\n" +
"MB0GA1UdDgQWBBQadKQ417m2DrNb+txerj+28HM9iDAOBgNVHQ8BAf8EBAMCAYYw\n" +
"EgYDVR0TAQH/BAgwBgEB/wIBADATBgNVHSUEDDAKBggrBgEFBQcDAzAaBgNVHSAE\n" +
"EzARMAYGBFUdIAAwBwYFZ4EMAQMwSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2Ny\n" +
"bC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdSb290RTQ2LmNy\n" +
"bDB7BggrBgEFBQcBAQRvMG0wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jcnQuc2VjdGln\n" +
"by5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nUm9vdEU0Ni5wN2MwIwYIKwYB\n" +
"BQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3RpZ28uY29tMAoGCCqGSM49BAMDA2gAMGUC\n" +
"MQCger3L4CYx2W7HyHzvLaAnNee9QVqOwOrBYZyyqXERLtZg1DscsdoYZ2gszEW3\n" +
"zaUCMAaLtcwdoV35ADpru29wChS7kFgXt599Ex27wmL++uJCJth6xYr3nyF2b2YJ\n" +
"DAatOw==\n" +
"-----END CERTIFICATE-----";
// Owner: CN=Sectigo Public Code Signing CA E36, O=Sectigo Limited, C=GB
// Issuer: CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB
// Serial number: 3602617636e7034b9cc1fc5ffeac2d54
// Valid from: Sun Mar 21 17:00:00 PDT 2021 until: Fri Mar 21 16:59:59
// PDT 2036
private static final String INT_REVOKED = "-----BEGIN CERTIFICATE-----\n" +
"MIIDLjCCArSgAwIBAgIQNgJhdjbnA0ucwfxf/qwtVDAKBggqhkjOPQQDAzBWMQsw\n" +
"CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRT\n" +
"ZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBFNDYwHhcNMjEwMzIyMDAw\n" +
"MDAwWhcNMzYwMzIxMjM1OTU5WjBUMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2Vj\n" +
"dGlnbyBMaW1pdGVkMSswKQYDVQQDEyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25p\n" +
"bmcgQ0EgRTM2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAElDe1m6jawDhrwMxJ\n" +
"yFPhKYf8EGu+lBw3bF5CzmfaH1I7Zi+WAmkeEwS3tiNxzPh8GbBBLtdaRuqGuyWc\n" +
"W6ERmaOCAWQwggFgMB8GA1UdIwQYMBaAFM99LKCQepgd3bZehcLg2hVx0uVeMB0G\n" +
"A1UdDgQWBBQlDZtt2Bh3t4rDOFFW5cfytf+DajAOBgNVHQ8BAf8EBAMCAYYwEgYD\n" +
"VR0TAQH/BAgwBgEB/wIBADATBgNVHSUEDDAKBggrBgEFBQcDAzAbBgNVHSAEFDAS\n" +
"MAYGBFUdIAAwCAYGZ4EMAQQBMEsGA1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwu\n" +
"c2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nUm9vdEU0Ni5jcmww\n" +
"ewYIKwYBBQUHAQEEbzBtMEYGCCsGAQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28u\n" +
"Y29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ1Jvb3RFNDYucDdjMCMGCCsGAQUF\n" +
"BzABhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTAKBggqhkjOPQQDAwNoADBlAjBM\n" +
"ykNTSVvegC1m17yIi87qgx6QIGbw1Mw2bQ4gtOWBVb/C8ALByC1YK7yQJNLJFTkC\n" +
"MQCNBv3fe1eLrGELS5KQD0cEFbXGlzQ5r1mnOHePMqlK5d+rmMxff58/t6bo3QEb\n" +
"8SQ=\n" +
"-----END CERTIFICATE-----";
// Owner: CN=Sectigo Limited, O=Sectigo Limited, ST=West Yorkshire, C=GB,
// OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB,
// SERIALNUMBER=04058690
// Issuer: CN=Sectigo Public Code Signing CA EV E36, O=Sectigo Limited, C=GB
// Serial number: fa2aa131f36b337717ac73f606a6ec49
// Valid from: Tue Feb 13 16:00:00 PST 2024 until: Sat Feb 13 15:59:59
// PST 2027
private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
"MIIDrjCCA1SgAwIBAgIRAPoqoTHzazN3F6xz9gam7EkwCgYIKoZIzj0EAwIwVzEL\n" +
"MAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEuMCwGA1UEAxMl\n" +
"U2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIEVWIEUzNjAeFw0yNDAyMTQw\n" +
"MDAwMDBaFw0yNzAyMTMyMzU5NTlaMIGhMREwDwYDVQQFEwgwNDA1ODY5MDETMBEG\n" +
"CysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24x\n" +
"CzAJBgNVBAYTAkdCMRcwFQYDVQQIDA5XZXN0IFlvcmtzaGlyZTEYMBYGA1UECgwP\n" +
"U2VjdGlnbyBMaW1pdGVkMRgwFgYDVQQDDA9TZWN0aWdvIExpbWl0ZWQwWTATBgcq\n" +
"hkjOPQIBBggqhkjOPQMBBwNCAASwXGEU01WkW/hWNYza08ZT7i0ZeZ9M1s93JYEB\n" +
"rZ/f1Ho1YzxtToqgIK2o+32afablPFYWlE6wGyuL/TYggBpKo4IBtDCCAbAwHwYD\n" +
"VR0jBBgwFoAUGnSkONe5tg6zW/rcXq4/tvBzPYgwHQYDVR0OBBYEFHEcsJgcYuDO\n" +
"dv1raL6h83a6j9C/MA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBMGA1Ud\n" +
"JQQMMAoGCCsGAQUFBwMDMEkGA1UdIARCMEAwNQYMKwYBBAGyMQECAQYBMCUwIwYI\n" +
"KwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAcGBWeBDAEDMEsGA1Ud\n" +
"HwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1Ymxp\n" +
"Y0NvZGVTaWduaW5nQ0FFVkUzNi5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsGAQUF\n" +
"BzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2ln\n" +
"bmluZ0NBRVZFMzYuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdv\n" +
"LmNvbTAmBgNVHREEHzAdoBsGCCsGAQUFBwgDoA8wDQwLR0ItMDQwNTg2OTAwCgYI\n" +
"KoZIzj0EAwIDSAAwRQIgQVp7IIkEZNmC7GfmT1MSEhDebIjjzd75ZVEEbPP/4ocC\n" +
"IQDSyfPDKNMbKNOKrweDLwSE2GZV6nDWbiLz6ZmSZHob8w==\n" +
"-----END CERTIFICATE-----";
// Owner: CN=Sectigo Limited, O=Sectigo Limited, ST=West Yorkshire, C=GB
// Issuer: CN=Sectigo Public Code Signing CA E36, O=Sectigo Limited, C=GB
// Serial number: a1f601514271f24ca0a31c0d7b856705
// Valid from: Wed Jun 04 17:00:00 PDT 2025 until: Sun Jun 04 16:59:59
// PDT 2028
private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
"MIIDOTCCAt6gAwIBAgIRAKH2AVFCcfJMoKMcDXuFZwUwCgYIKoZIzj0EAwIwVDEL\n" +
"MAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDErMCkGA1UEAxMi\n" +
"U2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIEUzNjAeFw0yNTA2MDUwMDAw\n" +
"MDBaFw0yODA2MDQyMzU5NTlaMFoxCzAJBgNVBAYTAkdCMRcwFQYDVQQIDA5XZXN0\n" +
"IFlvcmtzaGlyZTEYMBYGA1UECgwPU2VjdGlnbyBMaW1pdGVkMRgwFgYDVQQDDA9T\n" +
"ZWN0aWdvIExpbWl0ZWQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASwXGEU01Wk\n" +
"W/hWNYza08ZT7i0ZeZ9M1s93JYEBrZ/f1Ho1YzxtToqgIK2o+32afablPFYWlE6w\n" +
"GyuL/TYggBpKo4IBiTCCAYUwHwYDVR0jBBgwFoAUJQ2bbdgYd7eKwzhRVuXH8rX/\n" +
"g2owHQYDVR0OBBYEFHEcsJgcYuDOdv1raL6h83a6j9C/MA4GA1UdDwEB/wQEAwIH\n" +
"gDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMEoGA1UdIARDMEEw\n" +
"NQYMKwYBBAGyMQECAQMCMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5j\n" +
"b20vQ1BTMAgGBmeBDAEEATBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLnNl\n" +
"Y3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ0NBRTM2LmNybDB5Bggr\n" +
"BgEFBQcBAQRtMGswRAYIKwYBBQUHMAKGOGh0dHA6Ly9jcnQuc2VjdGlnby5jb20v\n" +
"U2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nQ0FFMzYuY3J0MCMGCCsGAQUFBzABhhdo\n" +
"dHRwOi8vb2NzcC5zZWN0aWdvLmNvbTAKBggqhkjOPQQDAgNJADBGAiEAlEkiISLz\n" +
"PdJsFmVzJ2VZ8hnnVsOBXKbqISFQvIdguJoCIQCH4T0vwxn6uVkJpMvtxiMG/rYg\n" +
"jRFhfbxDcVee6likOw==\n" +
"-----END CERTIFICATE-----";
public void runTest(ValidatePathWithParams pathValidator) throws Exception {
// Validate valid
pathValidator.validate(new String[]{VALID, INT_VALID},
ValidatePathWithParams.Status.GOOD, null, System.out);
// Validate Revoked
pathValidator.validate(new String[]{REVOKED, INT_REVOKED},
ValidatePathWithParams.Status.REVOKED,
"Thu Jun 05 10:27:19 PDT 2025", System.out);
}
}

View File

@@ -28,7 +28,7 @@
* 8223499 8225392 8232019 8234245 8233223 8225068 8225069 8243321 8243320
* 8243559 8225072 8258630 8259312 8256421 8225081 8225082 8225083 8245654
* 8305975 8304760 8307134 8295894 8314960 8317373 8317374 8318759 8319187
* 8321408 8316138 8341057 8303770 8350498
* 8321408 8316138 8341057 8303770 8350498 8359170
* @summary Check root CA entries in cacerts file
*/
import java.io.ByteArrayInputStream;
@@ -47,12 +47,12 @@ public class VerifyCACerts {
+ File.separator + "security" + File.separator + "cacerts";
// The numbers of certs now.
private static final int COUNT = 109;
private static final int COUNT = 113;
// SHA-256 of cacerts, can be generated with
// shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95
private static final String CHECKSUM
= "BD:6B:AB:BB:17:87:0D:D5:8D:53:D3:63:A5:DD:70:57:0F:4E:D3:57:4F:E5:FB:05:41:1C:A9:6E:B0:BF:79:38";
= "18:36:49:15:B6:71:85:FF:F1:8E:C0:10:BE:0A:41:52:5B:DC:F7:B3:1F:51:7A:45:7D:7A:14:10:3A:59:42:4C";
// Hex formatter to upper case with ":" delimiter
private static final HexFormat HEX = HexFormat.ofDelimiter(":").withUpperCase();
@@ -279,6 +279,14 @@ public class VerifyCACerts {
"C3:2F:FD:9F:46:F9:36:D1:6C:36:73:99:09:59:43:4B:9A:D6:0A:AF:BB:9E:7C:F3:36:54:F1:44:CC:1B:A1:43");
put("ssltlsrootrsa2022 [jdk]",
"8F:AF:7D:2E:2C:B4:70:9B:B8:E0:B3:36:66:BF:75:A5:DD:45:B5:DE:48:0F:8E:A8:D4:BF:E6:BE:BC:17:F2:ED");
put("sectigotlsrootr46 [jdk]",
"7B:B6:47:A6:2A:EE:AC:88:BF:25:7A:A5:22:D0:1F:FE:A3:95:E0:AB:45:C7:3F:93:F6:56:54:EC:38:F2:5A:06");
put("sectigotlsroote46 [jdk]",
"C9:0F:26:F0:FB:1B:40:18:B2:22:27:51:9B:5C:A2:B5:3E:2C:A5:B3:BE:5C:F1:8E:FE:1B:EF:47:38:0C:53:83");
put("sectigocodesignrootr46 [jdk]",
"7E:76:26:0A:E6:9A:55:D3:F0:60:B0:FD:18:B2:A8:C0:14:43:C8:7B:60:79:10:30:C9:FA:0B:05:85:10:1A:38");
put("sectigocodesignroote46 [jdk]",
"8F:63:71:D8:CC:5A:A7:CA:14:96:67:A9:8B:54:96:39:89:51:E4:31:9F:7A:FB:CC:6A:66:0D:67:3E:43:8D:0B");
}
};

View File

@@ -31,10 +31,13 @@
* java.base/sun.security.provider
* java.base/sun.security.x509
* @run main PKCS8Test
* @run main/othervm -Dtest.provider.name=SunJCE PKCS8Test
*/
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.Provider;
import java.security.Security;
import java.util.Arrays;
import java.util.HexFormat;
@@ -45,6 +48,7 @@ import sun.security.provider.DSAPrivateKey;
public class PKCS8Test {
static Provider provider;
static final String FORMAT = "PKCS#8";
static final String EXPECTED_ALG_ID_CHRS = "DSA, \n" +
"\tp: 02\n\tq: 03\n\tg: 04\n";
@@ -59,7 +63,7 @@ public class PKCS8Test {
"0403020101"); // PrivateKey OCTET int x = 1
public static void main(String[] args) throws Exception {
provider = Security.getProvider(System.getProperty("test.provider.name"));
byte[] encodedKey = new DSAPrivateKey(
BigInteger.valueOf(1),
BigInteger.valueOf(2),
@@ -73,7 +77,8 @@ public class PKCS8Test {
.toString(encodedKey));
}
PKCS8Key decodedKey = (PKCS8Key)PKCS8Key.parseKey(encodedKey);
PKCS8Key decodedKey = provider == null ? (PKCS8Key)PKCS8Key.parseKey(encodedKey) :
(PKCS8Key)PKCS8Key.parseKey(encodedKey, provider);
assert(ALGORITHM.equalsIgnoreCase(decodedKey.getAlgorithm()));
assert(FORMAT.equalsIgnoreCase(decodedKey.getFormat()));
@@ -126,7 +131,11 @@ public class PKCS8Test {
original[1] = (byte) (length - 2); // the length field inside DER
original[4] = (byte) newVersion; // the version inside DER
try {
PKCS8Key.parseKey(original);
if (provider == null) {
PKCS8Key.parseKey(original);
} else {
PKCS8Key.parseKey(original, provider);
}
} catch (InvalidKeyException e) {
throw new RuntimeException(e);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, 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
@@ -45,6 +45,8 @@ public final class SecurityUtils {
private enum KeySize{
RSA(2048),
DSA(2048),
Ed25519(256),
EC(256),
DH(2048);
private final int keySize;
@@ -145,6 +147,8 @@ public final class SecurityUtils {
return switch (algo) {
case "RSA" -> KeySize.RSA.keySize;
case "DSA" -> KeySize.DSA.keySize;
case "Ed25519" -> KeySize.Ed25519.keySize;
case "EC" -> KeySize.EC.keySize;
case "DH", "DiffieHellman" -> KeySize.DH.keySize;
default -> throw new RuntimeException("Test key size not defined for " + algo);
};