Merge
diff --git a/.hgtags b/.hgtags
index 7546207..f33de09 100644
--- a/.hgtags
+++ b/.hgtags
@@ -1,3 +1,5 @@
+34d29c39a13809006bf5de695bd765a583630ba2 jdk8u252-b01
+5ef5ede200663d90d0cb0c894ebeafed103ad092 jdk8u252-b02
f8f941bef71f82a09525776c7a5f0dc8bee4b095 jdk8u222-b00
fde18ccd2b8ba928a5413a0356630d22af207734 jdk8u201-b26
580749ce10f6866981321ea49655ccfbd5a6d805 jdk8u201-b79
@@ -927,5 +929,10 @@
fba0e4232e85ed347926ea7090f5faf93a339bba jdk8u242-b01
7a085881d40076ac4ef57edc85ea17990bc42013 jdk8u242-b02
2a54d4e52e85ca2fea1d5e00ce045151dfab3129 jdk8u242-b03
-34d29c39a13809006bf5de695bd765a583630ba2 jdk8u252-b01
-5ef5ede200663d90d0cb0c894ebeafed103ad092 jdk8u252-b02
+a110a6eec144c031f13d047d0f8ba10ff1511dad jdk8u242-b04
+425cea04ffb14aa0459a24aabcffced907473425 jdk8u252-b00
+5cfa071a55c8963fd92289f1ed1bd1dc72df9243 jdk8u242-b05
+7d2ae150f615af3f5ea6ba809666b355297e3576 jdk8u242-b06
+1366079778f6e664c0ba38a29401bd0b00a3e47f jdk8u242-b07
+68d77753be949bfc1c095e71048ef71fb56ae87d jdk8u242-b08
+b542f28181f26bb051addf3db1d785c7859b57e4 jdk8u242-ga
diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index ff124a5..1a17bbe 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -983,5 +983,11 @@
d2079934980013fdd8e63e31897011edae1a1188 jdk8u242-b02
be3a6b2c79821f056a9ca1efde037555d829ccb8 jdk8u242-b03
813d61736302c853dd0ef1b1e92b8fd0ca0af123 jdk8u242-b04
+bb4532c15611d35d3136eeb287049da79ce01ebb jdk8u242-b05
+72443ad60b1e685bd50e7ec8f21adf66786863d1 jdk8u242-b06
+8ca5f59e3042b7353b64c131be6bb970ba489ce9 jdk8u242-b07
+5b17d1f49219624f122ea2b05ec1c9f1adff8c64 jdk8u242-b08
+5b17d1f49219624f122ea2b05ec1c9f1adff8c64 jdk8u242-ga
30768a181ad0f4ba3d37f00bf23d76c875cb043a jdk8u252-b00
5f55e79422a0246076db7d3f2a2c44cb36e0e271 jdk8u252-b01
+a013ce3462fc144cc83347be67109c4e4e4b26ff jdk8u252-b02
diff --git a/THIRD_PARTY_README b/THIRD_PARTY_README
index 3f18756..a9adb43 100644
--- a/THIRD_PARTY_README
+++ b/THIRD_PARTY_README
@@ -1334,11 +1334,13 @@
--------------------------------------------------------------------------------
-%% This notice is provided with respect to Joni v1.1.9, which may be
+%% This notice is provided with respect to Joni v2.1.16, which may be
included with JRE 8, JDK 8, and OpenJDK 8.
--- begin of LICENSE ---
+Copyright (c) 2017 JRuby Team
+
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
diff --git a/corba/.hgtags b/corba/.hgtags
index e382481..7a43a7b 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -1056,5 +1056,11 @@
b3fbd77f16f6744939621dd68c18cb310f9a6e8d jdk8u242-b02
89f67ddac3c9a8307156a7a1963d184ecd97efe0 jdk8u242-b03
1835a96a04a6cf83449507245f5c4b12395d0cf5 jdk8u242-b04
+69e526db7430472a95cb9c43d928a8eb00faaf27 jdk8u242-b05
+751146fda0429aeb6501620cdcfa021d469613f1 jdk8u242-b06
+72d4f7e239eec808290ee6e1ab99dfab88d66150 jdk8u242-b07
+bdd855313cfed15bb2d6bd567c0487313752bcb2 jdk8u242-b08
+bdd855313cfed15bb2d6bd567c0487313752bcb2 jdk8u242-ga
201757e54b483788b0925bd6e5fc010e6fe7ce2a jdk8u252-b00
f718ce62e7c8bf41eb3cbab2a5c0d0af94b7e03b jdk8u252-b01
+c43e6827a131c6b23a367f09146f911cf64251f1 jdk8u252-b02
diff --git a/corba/THIRD_PARTY_README b/corba/THIRD_PARTY_README
index 3f18756..a9adb43 100644
--- a/corba/THIRD_PARTY_README
+++ b/corba/THIRD_PARTY_README
@@ -1334,11 +1334,13 @@
--------------------------------------------------------------------------------
-%% This notice is provided with respect to Joni v1.1.9, which may be
+%% This notice is provided with respect to Joni v2.1.16, which may be
included with JRE 8, JDK 8, and OpenJDK 8.
--- begin of LICENSE ---
+Copyright (c) 2017 JRuby Team
+
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index 4c350a8..8425efb 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -1289,5 +1289,11 @@
775e2bf92114e41365cc6baf1480c818454256a4 jdk8u242-b02
ee19c358e3b8deeda2f64d660a0870df7b1abd49 jdk8u242-b03
20258ba5a788da55485c0648bcc073f8ad2c26ef jdk8u242-b04
+2c1e9fab6964647f4eeffe55fe5592da6399a3ce jdk8u242-b05
+81ddc1072b923330f84c0ace3124226f63877582 jdk8u242-b06
+8b80409d5840142a27e274d33948f483a6406a50 jdk8u242-b07
+7c9f6b5f8d119dc1ba3c5536595ce3ae7414599d jdk8u242-b08
+7c9f6b5f8d119dc1ba3c5536595ce3ae7414599d jdk8u242-ga
8c0733543544bbcd32c4404630d764d280299056 jdk8u252-b00
a67e9c6edcdd73cb860a16990f0905e102c282d7 jdk8u252-b01
+5bd3b8c0555292a967ea3b4c39a220d0c2cf40ad jdk8u252-b02
diff --git a/hotspot/THIRD_PARTY_README b/hotspot/THIRD_PARTY_README
index 3f18756..a9adb43 100644
--- a/hotspot/THIRD_PARTY_README
+++ b/hotspot/THIRD_PARTY_README
@@ -1334,11 +1334,13 @@
--------------------------------------------------------------------------------
-%% This notice is provided with respect to Joni v1.1.9, which may be
+%% This notice is provided with respect to Joni v2.1.16, which may be
included with JRE 8, JDK 8, and OpenJDK 8.
--- begin of LICENSE ---
+Copyright (c) 2017 JRuby Team
+
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
diff --git a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp
index 793dc18..d7240e8 100644
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp
@@ -286,35 +286,35 @@
// SPARC T4 and above should have support for AES instructions
if (has_aes()) {
- if (UseVIS > 2) { // AES intrinsics use MOVxTOd/MOVdTOx which are VIS3
- if (FLAG_IS_DEFAULT(UseAES)) {
- FLAG_SET_DEFAULT(UseAES, true);
+ if (FLAG_IS_DEFAULT(UseAES)) {
+ FLAG_SET_DEFAULT(UseAES, true);
+ }
+ if (!UseAES) {
+ if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {
+ warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled.");
}
- if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
- FLAG_SET_DEFAULT(UseAESIntrinsics, true);
- }
- // we disable both the AES flags if either of them is disabled on the command line
- if (!UseAES || !UseAESIntrinsics) {
- FLAG_SET_DEFAULT(UseAES, false);
+ FLAG_SET_DEFAULT(UseAESIntrinsics, false);
+ } else {
+ // The AES intrinsic stubs require AES instruction support (of course)
+ // but also require VIS3 mode or higher for instructions it use.
+ if (UseVIS > 2) {
+ if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
+ FLAG_SET_DEFAULT(UseAESIntrinsics, true);
+ }
+ } else {
+ if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {
+ warning("SPARC AES intrinsics require VIS3 instructions. Intrinsics will be disabled.");
+ }
FLAG_SET_DEFAULT(UseAESIntrinsics, false);
}
- } else {
- if (UseAES || UseAESIntrinsics) {
- warning("SPARC AES intrinsics require VIS3 instruction support. Intrinsics will be disabled.");
- if (UseAES) {
- FLAG_SET_DEFAULT(UseAES, false);
- }
- if (UseAESIntrinsics) {
- FLAG_SET_DEFAULT(UseAESIntrinsics, false);
- }
- }
}
} else if (UseAES || UseAESIntrinsics) {
- warning("AES instructions are not available on this CPU");
- if (UseAES) {
+ if (UseAES && !FLAG_IS_DEFAULT(UseAES)) {
+ warning("AES instructions are not available on this CPU");
FLAG_SET_DEFAULT(UseAES, false);
}
- if (UseAESIntrinsics) {
+ if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {
+ warning("AES intrinsics are not available on this CPU");
FLAG_SET_DEFAULT(UseAESIntrinsics, false);
}
}
diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
index 1f5ae75..3a4246c 100644
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
@@ -553,12 +553,36 @@
// Use AES instructions if available.
if (supports_aes()) {
if (FLAG_IS_DEFAULT(UseAES)) {
- UseAES = true;
+ FLAG_SET_DEFAULT(UseAES, true);
}
- } else if (UseAES) {
- if (!FLAG_IS_DEFAULT(UseAES))
+ if (!UseAES) {
+ if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {
+ warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled.");
+ }
+ FLAG_SET_DEFAULT(UseAESIntrinsics, false);
+ } else {
+ if (UseSSE > 2) {
+ if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
+ FLAG_SET_DEFAULT(UseAESIntrinsics, true);
+ }
+ } else {
+ // The AES intrinsic stubs require AES instruction support (of course)
+ // but also require sse3 mode or higher for instructions it use.
+ if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {
+ warning("X86 AES intrinsics require SSE3 instructions or higher. Intrinsics will be disabled.");
+ }
+ FLAG_SET_DEFAULT(UseAESIntrinsics, false);
+ }
+ }
+ } else if (UseAES || UseAESIntrinsics) {
+ if (UseAES && !FLAG_IS_DEFAULT(UseAES)) {
warning("AES instructions are not available on this CPU");
- FLAG_SET_DEFAULT(UseAES, false);
+ FLAG_SET_DEFAULT(UseAES, false);
+ }
+ if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {
+ warning("AES intrinsics are not available on this CPU");
+ FLAG_SET_DEFAULT(UseAESIntrinsics, false);
+ }
}
// Use CLMUL instructions if available.
@@ -582,18 +606,6 @@
FLAG_SET_DEFAULT(UseCRC32Intrinsics, false);
}
- // The AES intrinsic stubs require AES instruction support (of course)
- // but also require sse3 mode for instructions it use.
- if (UseAES && (UseSSE > 2)) {
- if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
- UseAESIntrinsics = true;
- }
- } else if (UseAESIntrinsics) {
- if (!FLAG_IS_DEFAULT(UseAESIntrinsics))
- warning("AES intrinsics are not available on this CPU");
- FLAG_SET_DEFAULT(UseAESIntrinsics, false);
- }
-
// GHASH/GCM intrinsics
if (UseCLMUL && (UseSSE > 2)) {
if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) {
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
index e5a3a11..2a2faa6 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
@@ -161,6 +161,8 @@
}
_dictionary->set_par_lock(&_parDictionaryAllocLock);
}
+
+ _used_stable = 0;
}
// Like CompactibleSpace forward() but always calls cross_threshold() to
@@ -377,6 +379,14 @@
return capacity() - free();
}
+size_t CompactibleFreeListSpace::used_stable() const {
+ return _used_stable;
+}
+
+void CompactibleFreeListSpace::recalculate_used_stable() {
+ _used_stable = used();
+}
+
size_t CompactibleFreeListSpace::free() const {
// "MT-safe, but not MT-precise"(TM), if you will: i.e.
// if you do this while the structures are in flux you
@@ -1218,6 +1228,13 @@
debug_only(fc->mangleAllocated(size));
}
+ // During GC we do not need to recalculate the stable used value for
+ // every allocation in old gen. It is done once at the end of GC instead
+ // for performance reasons.
+ if (!Universe::heap()->is_gc_active()) {
+ recalculate_used_stable();
+ }
+
return res;
}
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
index 7269068..121299d 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
@@ -148,6 +148,9 @@
// Used to keep track of limit of sweep for the space
HeapWord* _sweep_limit;
+ // Stable value of used().
+ size_t _used_stable;
+
// Support for compacting cms
HeapWord* cross_threshold(HeapWord* start, HeapWord* end);
HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top);
@@ -343,6 +346,17 @@
// which overestimates the region by returning the entire
// committed region (this is safe, but inefficient).
+ // Returns monotonically increasing stable used space bytes for CMS.
+ // This is required for jstat and other memory monitoring tools
+ // that might otherwise see inconsistent used space values during a garbage
+ // collection, promotion or allocation into compactibleFreeListSpace.
+ // The value returned by this function might be smaller than the
+ // actual value.
+ size_t used_stable() const;
+ // Recalculate and cache the current stable used() value. Only to be called
+ // in places where we can be sure that the result is stable.
+ void recalculate_used_stable();
+
// Returns a subregion of the space containing all the objects in
// the space.
MemRegion used_region() const {
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
index 1872e72..e7228d3 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
@@ -869,6 +869,10 @@
return _cmsSpace->max_alloc_in_words() * HeapWordSize;
}
+size_t ConcurrentMarkSweepGeneration::used_stable() const {
+ return cmsSpace()->used_stable();
+}
+
size_t ConcurrentMarkSweepGeneration::max_available() const {
return free() + _virtual_space.uncommitted_size();
}
@@ -1955,6 +1959,8 @@
FreelistLocker z(this);
MetaspaceGC::compute_new_size();
_cmsGen->compute_new_size_free_list();
+ // recalculate CMS used space after CMS collection
+ _cmsGen->cmsSpace()->recalculate_used_stable();
}
// A work method used by foreground collection to determine
@@ -2768,6 +2774,7 @@
_capacity_at_prologue = capacity();
_used_at_prologue = used();
+ _cmsSpace->recalculate_used_stable();
// Delegate to CMScollector which knows how to coordinate between
// this and any other CMS generations that it is responsible for
@@ -2837,6 +2844,7 @@
_eden_chunk_index = 0;
size_t cms_used = _cmsGen->cmsSpace()->used();
+ _cmsGen->cmsSpace()->recalculate_used_stable();
// update performance counters - this uses a special version of
// update_counters() that allows the utilization to be passed as a
@@ -3672,6 +3680,7 @@
_collectorState = Marking;
}
SpecializationStats::print();
+ _cmsGen->cmsSpace()->recalculate_used_stable();
}
void CMSCollector::checkpointRootsInitialWork(bool asynch) {
@@ -5066,10 +5075,12 @@
Mutex::_no_safepoint_check_flag);
assert(!init_mark_was_synchronous, "but that's impossible!");
checkpointRootsFinalWork(asynch, clear_all_soft_refs, false);
+ _cmsGen->cmsSpace()->recalculate_used_stable();
} else {
// already have all the locks
checkpointRootsFinalWork(asynch, clear_all_soft_refs,
init_mark_was_synchronous);
+ _cmsGen->cmsSpace()->recalculate_used_stable();
}
verify_work_stacks_empty();
verify_overflow_empty();
@@ -6368,6 +6379,10 @@
// Update heap occupancy information which is used as
// input to soft ref clearing policy at the next gc.
Universe::update_heap_info_at_gc();
+
+ // recalculate CMS used space after CMS collection
+ _cmsGen->cmsSpace()->recalculate_used_stable();
+
_collectorState = Resizing;
}
} else {
@@ -6467,6 +6482,7 @@
// Gather statistics on the young generation collection.
collector()->stats().record_gc0_end(used());
}
+ _cmsSpace->recalculate_used_stable();
}
CMSAdaptiveSizePolicy* ConcurrentMarkSweepGeneration::size_policy() {
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
index a6d06a5..a023b9f 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
@@ -1190,6 +1190,7 @@
double occupancy() const { return ((double)used())/((double)capacity()); }
size_t contiguous_available() const;
size_t unsafe_max_alloc_nogc() const;
+ size_t used_stable() const;
// over-rides
MemRegion used_region() const;
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp b/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp
index 7a5fdf9..b03430e 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp
@@ -63,7 +63,7 @@
}
inline void update_used() {
- _used->set_value(_gen->used());
+ _used->set_value(_gen->used_stable());
}
// special version of update_used() to allow the used value to be
@@ -107,7 +107,7 @@
GenerationUsedHelper(Generation* g) : _gen(g) { }
inline jlong take_sample() {
- return _gen->used();
+ return _gen->used_stable();
}
};
diff --git a/hotspot/src/share/vm/memory/generation.cpp b/hotspot/src/share/vm/memory/generation.cpp
index 3c45a91..dc4ac08 100644
--- a/hotspot/src/share/vm/memory/generation.cpp
+++ b/hotspot/src/share/vm/memory/generation.cpp
@@ -68,6 +68,12 @@
return gch->_gen_specs[level()];
}
+// This is for CMS. It returns stable monotonic used space size.
+// Remove this when CMS is removed.
+size_t Generation::used_stable() const {
+ return used();
+}
+
size_t Generation::max_capacity() const {
return reserved().byte_size();
}
diff --git a/hotspot/src/share/vm/memory/generation.hpp b/hotspot/src/share/vm/memory/generation.hpp
index 63dccb7..ca3fe94 100644
--- a/hotspot/src/share/vm/memory/generation.hpp
+++ b/hotspot/src/share/vm/memory/generation.hpp
@@ -168,6 +168,7 @@
virtual size_t capacity() const = 0; // The maximum number of object bytes the
// generation can currently hold.
virtual size_t used() const = 0; // The number of used bytes in the gen.
+ virtual size_t used_stable() const; // The number of used bytes for memory monitoring tools.
virtual size_t free() const = 0; // The number of free bytes in the gen.
// Support for java.lang.Runtime.maxMemory(); see CollectedHeap.
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index 0204188..4c973d3 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -294,6 +294,7 @@
set_has_unloaded_dependent(false);
set_init_state(InstanceKlass::allocated);
set_init_thread(NULL);
+ set_init_state(allocated);
set_reference_type(rt);
set_oop_map_cache(NULL);
set_jni_ids(NULL);
@@ -978,11 +979,13 @@
oop init_lock = this_oop->init_lock();
if (init_lock != NULL) {
ObjectLocker ol(init_lock, THREAD);
+ this_oop->set_init_thread(NULL); // reset _init_thread before changing _init_state
this_oop->set_init_state(state);
this_oop->fence_and_clear_init_lock();
ol.notify_all(CHECK);
} else {
assert(init_lock != NULL, "The initialization state should never be set twice");
+ this_oop->set_init_thread(NULL); // reset _init_thread before changing _init_state
this_oop->set_init_state(state);
}
}
@@ -3602,6 +3605,7 @@
bool good_state = is_shared() ? (_init_state <= state)
: (_init_state < state);
assert(good_state || state == allocated, "illegal state transition");
+ assert(_init_thread == NULL, "should be cleared before state change");
_init_state = (u1)state;
}
#endif
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
index 444eadd..49d5528 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
@@ -241,7 +241,7 @@
u2 _misc_flags;
u2 _minor_version; // minor version number of class file
u2 _major_version; // major version number of class file
- Thread* _init_thread; // Pointer to current thread doing initialization (to handle recusive initialization)
+ Thread* _init_thread; // Pointer to current thread doing initialization (to handle recursive initialization)
int _vtable_len; // length of Java vtable (in words)
int _itable_len; // length of Java itable (in words)
OopMapCache* volatile _oop_map_cache; // OopMapCache for all methods in the klass (allocated lazily)
diff --git a/hotspot/src/share/vm/oops/klassVtable.cpp b/hotspot/src/share/vm/oops/klassVtable.cpp
index 61dd4c2..b3f477c 100644
--- a/hotspot/src/share/vm/oops/klassVtable.cpp
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp
@@ -289,22 +289,25 @@
int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) {
InstanceKlass* superk = initialsuper;
while (superk != NULL && superk->super() != NULL) {
- InstanceKlass* supersuperklass = InstanceKlass::cast(superk->super());
- klassVtable* ssVtable = supersuperklass->vtable();
+ klassVtable* ssVtable = (superk->super())->vtable();
if (vtable_index < ssVtable->length()) {
Method* super_method = ssVtable->method_at(vtable_index);
+ // get the class holding the matching method
+ // make sure you use that class for is_override
+ InstanceKlass* supermethodholder = super_method->method_holder();
#ifndef PRODUCT
Symbol* name= target_method()->name();
Symbol* signature = target_method()->signature();
assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch");
#endif
- if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) {
+
+ if (supermethodholder->is_override(super_method, target_loader, target_classname, THREAD)) {
#ifndef PRODUCT
if (PrintVtables && Verbose) {
ResourceMark rm(THREAD);
char* sig = target_method()->name_and_sig_as_C_string();
tty->print("transitive overriding superclass %s with %s::%s index %d, original flags: ",
- supersuperklass->internal_name(),
+ supermethodholder->internal_name(),
_klass->internal_name(), sig, vtable_index);
super_method->access_flags().print_on(tty);
if (super_method->is_default_method()) {
@@ -656,7 +659,7 @@
// search through the super class hierarchy to see if we need
// a new entry
- ResourceMark rm;
+ ResourceMark rm(THREAD);
Symbol* name = target_method()->name();
Symbol* signature = target_method()->signature();
Klass* k = super;
diff --git a/hotspot/src/share/vm/services/memoryPool.hpp b/hotspot/src/share/vm/services/memoryPool.hpp
index 007366e..157b54e 100644
--- a/hotspot/src/share/vm/services/memoryPool.hpp
+++ b/hotspot/src/share/vm/services/memoryPool.hpp
@@ -198,7 +198,7 @@
bool support_usage_threshold);
MemoryUsage get_memory_usage();
- size_t used_in_bytes() { return _space->used(); }
+ size_t used_in_bytes() { return _space->used_stable(); }
};
#endif // INCLUDE_ALL_GCS
diff --git a/hotspot/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java b/hotspot/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java
index 6fbaf9c..9ff4549 100644
--- a/hotspot/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java
+++ b/hotspot/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java
@@ -22,9 +22,10 @@
*/
import sun.hotspot.WhiteBox;
-import sun.misc.Unsafe;
import sun.misc.IOUtils;
+import sun.misc.Unsafe;
+import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLConnection;
@@ -108,7 +109,13 @@
// (1) Load an anonymous version of this class using the corresponding Unsafe method
URL classUrl = TestAnonymousClassUnloading.class.getResource("TestAnonymousClassUnloading.class");
URLConnection connection = classUrl.openConnection();
- byte[] classBytes = IOUtils.readFully(connection.getInputStream(), connection.getContentLength(), true);
+
+ int length = connection.getContentLength();
+ byte[] classBytes = IOUtils.readAllBytes(connection.getInputStream());
+ if (length != -1 && classBytes.length != length) {
+ throw new IOException("Expected:" + length + ", actual: " + classBytes.length);
+ }
+
Class<?> anonymousClass = UNSAFE.defineAnonymousClass(TestAnonymousClassUnloading.class, classBytes, null);
// (2) Make sure all paths of doWork are profiled and compiled
diff --git a/hotspot/test/compiler/intrinsics/bmi/TestAndnI.java b/hotspot/test/compiler/intrinsics/bmi/TestAndnI.java
index e8cfaa2..1dbea7a 100644
--- a/hotspot/test/compiler/intrinsics/bmi/TestAndnI.java
+++ b/hotspot/test/compiler/intrinsics/bmi/TestAndnI.java
@@ -58,15 +58,27 @@
}
public int intExpr(int src1, Expr.MemI src2) {
- return ~src1 & src2.value;
+ if (src2 != null) {
+ return ~src1 & src2.value;
+ } else {
+ return 0;
+ }
}
public int intExpr(Expr.MemI src1, int src2) {
- return ~src1.value & src2;
+ if (src1 != null) {
+ return ~src1.value & src2;
+ } else {
+ return 0;
+ }
}
public int intExpr(Expr.MemI src1, Expr.MemI src2) {
- return ~src1.value & src2.value;
+ if (src1 != null && src2 != null) {
+ return ~src1.value & src2.value;
+ } else {
+ return 0;
+ }
}
}
@@ -77,15 +89,27 @@
}
public int intExpr(int src1, Expr.MemI src2) {
- return src1 & ~src2.value;
+ if (src2 != null) {
+ return src1 & ~src2.value;
+ } else {
+ return 0;
+ }
}
public int intExpr(Expr.MemI src1, int src2) {
- return src1.value & ~src2;
+ if (src1 != null) {
+ return src1.value & ~src2;
+ } else {
+ return 0;
+ }
}
public int intExpr(Expr.MemI src1, Expr.MemI src2) {
- return src1.value & ~src2.value;
+ if (src1 != null && src2 != null) {
+ return src1.value & ~src2.value;
+ } else {
+ return 0;
+ }
}
}
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/TestAndnL.java b/hotspot/test/compiler/intrinsics/bmi/TestAndnL.java
index 0dca7aa..2cc96c5 100644
--- a/hotspot/test/compiler/intrinsics/bmi/TestAndnL.java
+++ b/hotspot/test/compiler/intrinsics/bmi/TestAndnL.java
@@ -58,15 +58,27 @@
}
public long longExpr(long src1, Expr.MemL src2) {
- return ~src1 & src2.value;
+ if (src2 != null) {
+ return ~src1 & src2.value;
+ } else {
+ return 0;
+ }
}
public long longExpr(Expr.MemL src1, long src2) {
- return ~src1.value & src2;
+ if (src1 != null) {
+ return ~src1.value & src2;
+ } else {
+ return 0;
+ }
}
public long longExpr(Expr.MemL src1, Expr.MemL src2) {
- return ~src1.value & src2.value;
+ if (src1 != null && src2 != null) {
+ return ~src1.value & src2.value;
+ } else {
+ return 0;
+ }
}
@@ -79,15 +91,27 @@
}
public long longExpr(long src1, Expr.MemL src2) {
- return src1 & ~src2.value;
+ if (src2 != null) {
+ return src1 & ~src2.value;
+ } else {
+ return 0;
+ }
}
public long longExpr(Expr.MemL src1, long src2) {
- return src1.value & ~src2;
+ if (src1 != null) {
+ return src1.value & ~src2;
+ } else {
+ return 0;
+ }
}
public long longExpr(Expr.MemL src1, Expr.MemL src2) {
- return src1.value & ~src2.value;
+ if (src1 != null && src2 != null) {
+ return src1.value & ~src2.value;
+ } else {
+ return 0;
+ }
}
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestI.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestI.java
similarity index 84%
rename from hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestI.java
rename to hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestI.java
index 2a77347..7cc0232 100644
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestI.java
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestI.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,17 +25,17 @@
* @test
* @bug 8031321
* @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
- * @build AddnTestI
+ * @build AndnTestI
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
- * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions AddnTestI
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions AndnTestI
*/
import java.lang.reflect.Method;
-public class AddnTestI extends BmiIntrinsicBase.BmiTestCase {
+public class AndnTestI extends BmiIntrinsicBase.BmiTestCase {
- protected AddnTestI(Method method) {
+ protected AndnTestI(Method method) {
super(method);
// from intel manual VEX.NDS.LZ.0F38.W0 F2 /r, example c4e260f2c2
instrMask = new byte[]{
@@ -51,7 +51,7 @@
}
public static void main(String[] args) throws Exception {
- BmiIntrinsicBase.verifyTestCase(AddnTestI::new, TestAndnI.AndnIExpr.class.getDeclaredMethods());
- BmiIntrinsicBase.verifyTestCase(AddnTestI::new, TestAndnI.AndnICommutativeExpr.class.getDeclaredMethods());
+ BmiIntrinsicBase.verifyTestCase(AndnTestI::new, TestAndnI.AndnIExpr.class.getDeclaredMethods());
+ BmiIntrinsicBase.verifyTestCase(AndnTestI::new, TestAndnI.AndnICommutativeExpr.class.getDeclaredMethods());
}
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestL.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestL.java
similarity index 82%
rename from hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestL.java
rename to hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestL.java
index 72da9a0..e4493e2 100644
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestL.java
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestL.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,23 +25,23 @@
* @test
* @bug 8031321
* @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
- * @build AddnTestL
+ * @build AndnTestL
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
- * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions AddnTestL
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions AndnTestL
*/
import java.lang.reflect.Method;
-public class AddnTestL extends AddnTestI {
+public class AndnTestL extends AndnTestI {
- protected AddnTestL(Method method) {
+ protected AndnTestL(Method method) {
super(method);
isLongOperation = true;
}
public static void main(String[] args) throws Exception {
- BmiIntrinsicBase.verifyTestCase(AddnTestL::new, TestAndnL.AndnLExpr.class.getDeclaredMethods());
- BmiIntrinsicBase.verifyTestCase(AddnTestL::new, TestAndnL.AndnLCommutativeExpr.class.getDeclaredMethods());
+ BmiIntrinsicBase.verifyTestCase(AndnTestL::new, TestAndnL.AndnLExpr.class.getDeclaredMethods());
+ BmiIntrinsicBase.verifyTestCase(AndnTestL::new, TestAndnL.AndnLCommutativeExpr.class.getDeclaredMethods());
}
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java
index 0ba76e6..1f1b5da 100644
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java
@@ -44,6 +44,8 @@
public static void main(String[] args) throws Exception {
// j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods
System.out.println("class java.lang.Integer should be loaded. Proof: " + Integer.class);
+ // Avoid uncommon traps.
+ System.out.println("Num leading zeroes: " + new TestLzcntI.LzcntIExpr().intExpr(12341341));
BmiIntrinsicBase.verifyTestCase(LZcntTestI::new, TestLzcntI.LzcntIExpr.class.getDeclaredMethods());
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java
index 5ecfb96..9787bf8 100644
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java
@@ -49,6 +49,8 @@
public static void main(String[] args) throws Exception {
// j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods
System.out.println("classes java.lang.Long should be loaded. Proof: " + Long.class);
+ // Avoid uncommon traps.
+ System.out.println("Num leading zeroes: " + new TestLzcntL.LzcntLExpr().longExpr(12341341));
BmiIntrinsicBase.verifyTestCase(LZcntTestL::new, TestLzcntL.LzcntLExpr.class.getDeclaredMethods());
}
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java
index ad2af2c..3936c11 100644
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java
@@ -44,6 +44,8 @@
public static void main(String[] args) throws Exception {
// j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods
System.out.println("class java.lang.Integer should be loaded. Proof: " + Integer.class);
+ // Avoid uncommon traps.
+ System.out.println("Num trailing zeroes: " + new TestTzcntI.TzcntIExpr().intExpr(12341341));
BmiIntrinsicBase.verifyTestCase(TZcntTestI::new, TestTzcntI.TzcntIExpr.class.getDeclaredMethods());
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java
index 0a856df..5bd42b4 100644
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java
@@ -50,6 +50,8 @@
public static void main(String[] args) throws Exception {
// j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods
System.out.println("classes java.lang.Long should be loaded. Proof: " + Long.class);
+ // Avoid uncommon traps.
+ System.out.println("Num trailing zeroes: " + new TestTzcntL.TzcntLExpr().longExpr(12341341));
BmiIntrinsicBase.verifyTestCase(TZcntTestL::new, TestTzcntL.TzcntLExpr.class.getDeclaredMethods());
}
}
diff --git a/hotspot/test/runtime/8003720/VictimClassLoader.java b/hotspot/test/runtime/8003720/VictimClassLoader.java
index 3505f78..e219fd6 100644
--- a/hotspot/test/runtime/8003720/VictimClassLoader.java
+++ b/hotspot/test/runtime/8003720/VictimClassLoader.java
@@ -22,6 +22,8 @@
*
*/
+import sun.misc.IOUtils;
+
public class VictimClassLoader extends ClassLoader {
public static long counter = 0;
@@ -72,8 +74,10 @@
}
static byte[] readFully(java.io.InputStream in, int len) throws java.io.IOException {
- // Warning here:
- return sun.misc.IOUtils.readFully(in, len, true);
+ byte[] b = IOUtils.readAllBytes(in);
+ if (len != -1 && b.length != len)
+ throw new java.io.IOException("Expected:" + len + ", actual:" + b.length);
+ return b;
}
public void finalize() {
diff --git a/hotspot/test/runtime/RedefineTests/test8178870.sh b/hotspot/test/runtime/RedefineTests/test8178870.sh
deleted file mode 100644
index 4a90e26..0000000
--- a/hotspot/test/runtime/RedefineTests/test8178870.sh
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2019, Red Hat, Inc. All rights reserved.
-#
-# 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 test.sh
-## @bug 8178870
-## @summary test instrumentation.retransformClasses
-## @run shell test.sh
-
-if [ "${TESTSRC}" = "" ]
-then
- TESTSRC=${PWD}
- echo "TESTSRC not set. Using "${TESTSRC}" as default"
-fi
-echo "TESTSRC=${TESTSRC}"
-## Adding common setup Variables for running shell tests.
-. ${TESTSRC}/../../test_env.sh
-
-LIB_SRC=${TESTSRC}/../../testlibrary/
-
-# set platform-dependent variables
-OS=`uname -s`
-echo "Testing on " $OS
-case "$OS" in
- Linux)
- cc_cmd=`which gcc`
- if [ "x$cc_cmd" == "x" ]; then
- echo "WARNING: gcc not found. Cannot execute test." 2>&1
- exit 0;
- fi
- ;;
- Solaris)
- cc_cmd=`which cc`
- if [ "x$cc_cmd" == "x" ]; then
- echo "WARNING: cc not found. Cannot execute test." 2>&1
- exit 0;
- fi
- ;;
- *)
- echo "Test passed. Only on Linux and Solaris"
- exit 0;
- ;;
-esac
-
-THIS_DIR=.
-
-cp ${TESTSRC}/RedefineDoubleDelete.java ${THIS_DIR}
-mkdir -p ${THIS_DIR}/classes
-${TESTJAVA}/bin/javac -sourcepath ${LIB_SRC} -d ${THIS_DIR}/classes ${LIB_SRC}RedefineClassHelper.java
-${TESTJAVA}/bin/javac -cp .:${THIS_DIR}/classes:${TESTJAVA}/lib/tools.jar -d ${THIS_DIR} RedefineDoubleDelete.java
-
-$cc_cmd -fPIC -shared -o ${THIS_DIR}${FS}libRedefineDoubleDelete.so \
- -I${TESTJAVA}/include -I${TESTJAVA}/include/linux \
- ${TESTSRC}/libRedefineDoubleDelete.c
-
-LD_LIBRARY_PATH=${THIS_DIR}
-echo LD_LIBRARY_PATH = ${LD_LIBRARY_PATH}
-export LD_LIBRARY_PATH
-
-# Install redefineagent.jar
-${TESTJAVA}/bin${FS}java -cp ${THIS_DIR}/classes RedefineClassHelper
-
-echo
-echo ${TESTJAVA}/bin/java -agentlib:RedefineDoubleDelete RedefineDoubleDelete
-${TESTJAVA}/bin/java -cp .:${THIS_DIR}${FS}classes -javaagent:redefineagent.jar -agentlib:RedefineDoubleDelete RedefineDoubleDelete
-
diff --git a/jaxp/.hgtags b/jaxp/.hgtags
index b5c88c8..00c4e7c 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -1020,5 +1020,11 @@
91cff4cef2095bbc8af71dec6357d6eb5524e0ce jdk8u242-b02
616095b698d1c1c9a8c8a3517735be30be443207 jdk8u242-b03
2199192fb5ecf001bfd3f3ad2fd5ae09ef7e3073 jdk8u242-b04
+81838c6f30bc08546c3cc9941583da81ed6dadb1 jdk8u242-b05
+77787fb589bb938de5cdf1462dee166cd6cd2722 jdk8u242-b06
+8bddae4d0a3d727b1f254ec8932fb2e505fd01de jdk8u242-b07
+eac8e0f4e575f35d0266340575d79f1102ef0502 jdk8u242-b08
+eac8e0f4e575f35d0266340575d79f1102ef0502 jdk8u242-ga
41b0b125cb4a58be7e24f3b01901abc5fd589d62 jdk8u252-b00
c74e6ad60110a7d95568c96e1d375007531a2d3e jdk8u252-b01
+a8a94522990d0ccd5525ffbf12e9ca0074a9ae95 jdk8u252-b02
diff --git a/jaxp/THIRD_PARTY_README b/jaxp/THIRD_PARTY_README
index 3f18756..a9adb43 100644
--- a/jaxp/THIRD_PARTY_README
+++ b/jaxp/THIRD_PARTY_README
@@ -1334,11 +1334,13 @@
--------------------------------------------------------------------------------
-%% This notice is provided with respect to Joni v1.1.9, which may be
+%% This notice is provided with respect to Joni v2.1.16, which may be
included with JRE 8, JDK 8, and OpenJDK 8.
--- begin of LICENSE ---
+Copyright (c) 2017 JRuby Team
+
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
diff --git a/jaxws/.hgtags b/jaxws/.hgtags
index ce32cfa..0feeade 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -1014,5 +1014,11 @@
016be7bdaa27e14de8e40db8c67d0ab3997d5dc7 jdk8u242-b02
6f53efc6747b8be967b6919ce83426924ae6b79e jdk8u242-b03
b1722cc8c8d85ad8baac1469831a02b5c85f6c7a jdk8u242-b04
+c00877a0e915474c530fe45b68d8af8cbb245abf jdk8u242-b05
+a82b6ab00878ea389c4e03cbab0c01e7b2ffc257 jdk8u242-b06
+888c7a41a3ece3f502aa12b17fbd4625bc217c0f jdk8u242-b07
+b933b8903615c12824dc12ae493dc213e6f07c43 jdk8u242-b08
+b933b8903615c12824dc12ae493dc213e6f07c43 jdk8u242-ga
5c9d17a5ca582f05299659ad545788c1f754369d jdk8u252-b00
2c358ca051cb42b7b3326ad8e1375bb944208d1b jdk8u252-b01
+21725ddbd615ab02accd2d968ea556b239af8fd0 jdk8u252-b02
diff --git a/jaxws/THIRD_PARTY_README b/jaxws/THIRD_PARTY_README
index 3f18756..a9adb43 100644
--- a/jaxws/THIRD_PARTY_README
+++ b/jaxws/THIRD_PARTY_README
@@ -1334,11 +1334,13 @@
--------------------------------------------------------------------------------
-%% This notice is provided with respect to Joni v1.1.9, which may be
+%% This notice is provided with respect to Joni v2.1.16, which may be
included with JRE 8, JDK 8, and OpenJDK 8.
--- begin of LICENSE ---
+Copyright (c) 2017 JRuby Team
+
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
diff --git a/jdk/.hgtags b/jdk/.hgtags
index 356d740..0928f2c 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -1015,5 +1015,11 @@
2b292ab0ed9af9aa8aab27b1a80daa3509a050ba jdk8u242-b02
2f564a16517d678f31a3fa7352e16702e48c417d jdk8u242-b03
8163e59959ed5462891f2b1db7bc0fa2af1de0a6 jdk8u242-b04
+b2865f7f557fcaec84445b034b2de2b27456b6c5 jdk8u242-b05
+0d27e60569f7cf85cbdb0a83436e772e9256b5b0 jdk8u242-b06
+034a65a05bfbfb06e14d3d39efa0c9f27683573a jdk8u242-b07
+c63c2923e1f99c1f350bd24b42daf885023f18b7 jdk8u242-b08
+c63c2923e1f99c1f350bd24b42daf885023f18b7 jdk8u242-ga
44c4cee50aeb94c4629e642681ff099ad9dcac12 jdk8u252-b00
4dd113d7811ea6651c1c96f9c641b8bec8e31669 jdk8u252-b01
+8d39522b0f7573e69260eb3f7af360b72b27dfc3 jdk8u252-b02
diff --git a/jdk/THIRD_PARTY_README b/jdk/THIRD_PARTY_README
index 3f18756..a9adb43 100644
--- a/jdk/THIRD_PARTY_README
+++ b/jdk/THIRD_PARTY_README
@@ -1334,11 +1334,13 @@
--------------------------------------------------------------------------------
-%% This notice is provided with respect to Joni v1.1.9, which may be
+%% This notice is provided with respect to Joni v2.1.16, which may be
included with JRE 8, JDK 8, and OpenJDK 8.
--- begin of LICENSE ---
+Copyright (c) 2017 JRuby Team
+
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
diff --git a/jdk/jdk/test/lib/testlibrary/jdk/testlibrary/IOUtils.java b/jdk/jdk/test/lib/testlibrary/jdk/testlibrary/IOUtils.java
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/jdk/jdk/test/lib/testlibrary/jdk/testlibrary/IOUtils.java
diff --git a/jdk/make/data/cacerts/amazonrootca1 b/jdk/make/data/cacerts/amazonrootca1
new file mode 100644
index 0000000..9431a65
--- /dev/null
+++ b/jdk/make/data/cacerts/amazonrootca1
@@ -0,0 +1,27 @@
+Owner: CN=Amazon Root CA 1, O=Amazon, C=US
+Issuer: CN=Amazon Root CA 1, O=Amazon, C=US
+Serial number: 66c9fcf99bf8c0a39e2f0788a43e696365bca
+Valid from: Tue May 26 00:00:00 GMT 2015 until: Sun Jan 17 00:00:00 GMT 2038
+Signature algorithm name: SHA256withRSA
+Subject Public Key Algorithm: 2048-bit RSA key
+Version: 3
+-----BEGIN CERTIFICATE-----
+MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
+ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
+b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
+MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
+b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
+ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
+9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
+IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
+VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
+93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
+jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA
+A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI
+U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs
+N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
+o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
+5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
+rqXRfboQnoZsG4q5WTP468SQvvG5
+-----END CERTIFICATE-----
diff --git a/jdk/make/data/cacerts/amazonrootca2 b/jdk/make/data/cacerts/amazonrootca2
new file mode 100644
index 0000000..95e6f32
--- /dev/null
+++ b/jdk/make/data/cacerts/amazonrootca2
@@ -0,0 +1,38 @@
+Owner: CN=Amazon Root CA 2, O=Amazon, C=US
+Issuer: CN=Amazon Root CA 2, O=Amazon, C=US
+Serial number: 66c9fd29635869f0a0fe58678f85b26bb8a37
+Valid from: Tue May 26 00:00:00 GMT 2015 until: Sat May 26 00:00:00 GMT 2040
+Signature algorithm name: SHA384withRSA
+Subject Public Key Algorithm: 4096-bit RSA key
+Version: 3
+-----BEGIN CERTIFICATE-----
+MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
+ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
+b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
+MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
+b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK
+gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ
+W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg
+1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K
+8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r
+2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me
+z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR
+8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj
+mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz
+7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6
++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI
+0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
+Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm
+UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2
+LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS
+k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl
+7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm
+btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl
+urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+
+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63
+n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
+76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
+9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
+4PsJYGw=
+-----END CERTIFICATE-----
diff --git a/jdk/make/data/cacerts/amazonrootca3 b/jdk/make/data/cacerts/amazonrootca3
new file mode 100644
index 0000000..96a5c63
--- /dev/null
+++ b/jdk/make/data/cacerts/amazonrootca3
@@ -0,0 +1,19 @@
+Owner: CN=Amazon Root CA 3, O=Amazon, C=US
+Issuer: CN=Amazon Root CA 3, O=Amazon, C=US
+Serial number: 66c9fd5749736663f3b0b9ad9e89e7603f24a
+Valid from: Tue May 26 00:00:00 GMT 2015 until: Sat May 26 00:00:00 GMT 2040
+Signature algorithm name: SHA256withECDSA
+Subject Public Key Algorithm: 256-bit EC key
+Version: 3
+-----BEGIN CERTIFICATE-----
+MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5
+MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
+Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
+A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
+Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl
+ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr
+ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr
+BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM
+YyRIHN8wfdVoOw==
+-----END CERTIFICATE-----
diff --git a/jdk/make/data/cacerts/amazonrootca4 b/jdk/make/data/cacerts/amazonrootca4
new file mode 100644
index 0000000..9a59ca2
--- /dev/null
+++ b/jdk/make/data/cacerts/amazonrootca4
@@ -0,0 +1,20 @@
+Owner: CN=Amazon Root CA 4, O=Amazon, C=US
+Issuer: CN=Amazon Root CA 4, O=Amazon, C=US
+Serial number: 66c9fd7c1bb104c2943e5717b7b2cc81ac10e
+Valid from: Tue May 26 00:00:00 GMT 2015 until: Sat May 26 00:00:00 GMT 2040
+Signature algorithm name: SHA384withECDSA
+Subject Public Key Algorithm: 384-bit EC key
+Version: 3
+-----BEGIN CERTIFICATE-----
+MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5
+MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
+Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
+A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
+Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi
+9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk
+M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB
+/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB
+MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw
+CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
+1KyLa2tJElMzrdfkviT8tQp21KW8EA==
+-----END CERTIFICATE-----
diff --git a/jdk/make/data/cacerts/luxtrustglobalroot2ca b/jdk/make/data/cacerts/luxtrustglobalroot2ca
new file mode 100644
index 0000000..e04c399
--- /dev/null
+++ b/jdk/make/data/cacerts/luxtrustglobalroot2ca
@@ -0,0 +1,40 @@
+Owner: CN=LuxTrust Global Root 2, O=LuxTrust S.A., C=LU
+Issuer: CN=LuxTrust Global Root 2, O=LuxTrust S.A., C=LU
+Serial number: a7ea6df4b449eda6a24859ee6b815d3167fbbb1
+Valid from: Thu Mar 05 13:21:57 GMT 2015 until: Mon Mar 05 13:21:57 GMT 2035
+Signature algorithm name: SHA256withRSA
+Subject Public Key Algorithm: 4096-bit RSA key
+Version: 3
+-----BEGIN CERTIFICATE-----
+MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQEL
+BQAwRjELMAkGA1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNV
+BAMMFkx1eFRydXN0IEdsb2JhbCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUw
+MzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEWMBQGA1UECgwNTHV4VHJ1c3QgUy5B
+LjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wmKb3F
+ibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTem
+hfY7RBi2xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1
+EMShduxq3sVs35a0VkBCwGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsn
+Xpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4
+zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkmFRseTJIpgp7VkoGSQXAZ
+96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niFwpN6cj5m
+j5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4g
+DEa/a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+
+8kPREd8vZS9kzl8UubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2j
+X5t/Lax5Gw5CMZdjpPuKadUiDTSQMC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmH
+hFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB/zBCBgNVHSAEOzA5MDcGByuB
+KwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5Lmx1eHRydXN0
+Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT
++Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQEL
+BQADggIBAGoZFO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9
+BzZAcg4atmpZ1gDlaCDdLnINH2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTO
+jFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW7MM3LGVYvlcAGvI1+ut7MV3CwRI9
+loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIuZY+kt9J/Z93I055c
+qqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWAVWe+
+2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/
+JEAdemrRTxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKre
+zrnK+T+Tb/mjuuqlPpmt/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQf
+LSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+
+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31IiyBMz2TWuJdGsE7RKlY6
+oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr
+-----END CERTIFICATE-----
diff --git a/jdk/make/lib/SecurityLibraries.gmk b/jdk/make/lib/SecurityLibraries.gmk
index 2a1721b..a8eeceb 100644
--- a/jdk/make/lib/SecurityLibraries.gmk
+++ b/jdk/make/lib/SecurityLibraries.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -171,7 +171,7 @@
-I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/mscapi, \
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
- LDFLAGS_SUFFIX := Crypt32.Lib advapi32.lib, \
+ LDFLAGS_SUFFIX := Crypt32.Lib advapi32.lib ncrypt.lib, \
VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \
RC_FLAGS := $(RC_FLAGS) \
-D "JDK_FNAME=sunmscapi.dll" \
diff --git a/jdk/make/src/classes/build/tools/generatecacerts/GenerateCacerts.java b/jdk/make/src/classes/build/tools/generatecacerts/GenerateCacerts.java
index 3281794..f3a9fcd 100644
--- a/jdk/make/src/classes/build/tools/generatecacerts/GenerateCacerts.java
+++ b/jdk/make/src/classes/build/tools/generatecacerts/GenerateCacerts.java
@@ -25,14 +25,25 @@
package build.tools.generatecacerts;
+import java.io.DataOutputStream;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.security.KeyStore;
+import java.security.DigestOutputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.SortedSet;
+import java.util.TreeSet;
/**
* Generate cacerts
@@ -41,22 +52,102 @@
*/
public class GenerateCacerts {
public static void main(String[] args) throws Exception {
- KeyStore ks = KeyStore.getInstance("JKS");
- ks.load(null, null);
+ try (FileOutputStream fos = new FileOutputStream(args[1])) {
+ store(args[0], fos, "changeit".toCharArray());
+ }
+ }
+
+ // The following code is copied from JavaKeyStore.java.
+
+ private static final int MAGIC = 0xfeedfeed;
+ private static final int VERSION_2 = 0x02;
+
+ // This method is a simplified version of JavaKeyStore::engineStore.
+ // A new "dir" argument is added. All cert names in "dir" is collected into
+ // a sorted array. Each cert is stored with a creation date set to its
+ // notBefore value. Thus the output is determined as long as the certs
+ // are the same.
+ public static void store(String dir, OutputStream stream, char[] password)
+ throws IOException, NoSuchAlgorithmException, CertificateException
+ {
+ byte[] encoded; // the certificate encoding
CertificateFactory cf = CertificateFactory.getInstance("X509");
- try (DirectoryStream<Path> ds = Files.newDirectoryStream(Paths.get(args[0]))) {
+
+ MessageDigest md = getPreKeyedHash(password);
+ DataOutputStream dos
+ = new DataOutputStream(new DigestOutputStream(stream, md));
+
+ dos.writeInt(MAGIC);
+ // always write the latest version
+ dos.writeInt(VERSION_2);
+
+ // All file names in dir sorted.
+ // README is excluded. Name starting with "." excluded.
+ SortedSet<String> entries = new TreeSet<String>();
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(Paths.get(dir))) {
for (Path p : ds) {
String fName = p.getFileName().toString();
- if (!fName.equals("README")) {
- String alias = fName + " [jdk]";
- try (InputStream fis = Files.newInputStream(p)) {
- ks.setCertificateEntry(alias, cf.generateCertificate(fis));
- }
+ if (!fName.equals("README") && !fName.startsWith(".")) {
+ entries.add(fName);
}
}
}
- try (FileOutputStream fos = new FileOutputStream(args[1])) {
- ks.store(fos, "changeit".toCharArray());
+
+ dos.writeInt(entries.size());
+
+ for (String entry : entries) {
+
+ String alias = entry + " [jdk]";
+ X509Certificate cert;
+ try (InputStream fis = Files.newInputStream(Paths.get(dir, entry))) {
+ cert = (X509Certificate) cf.generateCertificate(fis);
+ }
+
+ dos.writeInt(2);
+
+ // Write the alias
+ dos.writeUTF(alias);
+
+ // Write the (entry creation) date, which is notBefore of the cert
+ dos.writeLong(cert.getNotBefore().getTime());
+
+ // Write the trusted certificate
+ encoded = cert.getEncoded();
+ dos.writeUTF(cert.getType());
+ dos.writeInt(encoded.length);
+ dos.write(encoded);
}
+
+ /*
+ * Write the keyed hash which is used to detect tampering with
+ * the keystore (such as deleting or modifying key or
+ * certificate entries).
+ */
+ byte[] digest = md.digest();
+
+ dos.write(digest);
+ dos.flush();
+ }
+
+ private static MessageDigest getPreKeyedHash(char[] password)
+ throws NoSuchAlgorithmException, UnsupportedEncodingException
+ {
+
+ MessageDigest md = MessageDigest.getInstance("SHA");
+ byte[] passwdBytes = convertToBytes(password);
+ md.update(passwdBytes);
+ Arrays.fill(passwdBytes, (byte) 0x00);
+ md.update("Mighty Aphrodite".getBytes("UTF8"));
+ return md;
+ }
+
+ private static byte[] convertToBytes(char[] password) {
+ int i, j;
+ byte[] passwdBytes = new byte[password.length * 2];
+ for (i=0, j=0; i<password.length; i++) {
+ passwdBytes[j++] = (byte)(password[i] >> 8);
+ passwdBytes[j++] = (byte)password[i];
+ }
+ return passwdBytes;
}
}
diff --git a/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m b/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m
index c04a6a3..870162e 100644
--- a/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m
+++ b/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -94,16 +94,18 @@
static CGDisplayModeRef getBestModeForParameters(CFArrayRef allModes, int w, int h, int bpp, int refrate) {
CGDisplayModeRef bestGuess = NULL;
CFIndex numModes = CFArrayGetCount(allModes), n;
- int thisBpp = 0;
+
for(n = 0; n < numModes; n++ ) {
CGDisplayModeRef cRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, n);
if(cRef == NULL) {
continue;
}
CFStringRef modeString = CGDisplayModeCopyPixelEncoding(cRef);
- thisBpp = getBPPFromModeString(modeString);
+ int thisBpp = getBPPFromModeString(modeString);
CFRelease(modeString);
- if (thisBpp != bpp || (int)CGDisplayModeGetHeight(cRef) != h || (int)CGDisplayModeGetWidth(cRef) != w) {
+ int thisH = (int)CGDisplayModeGetHeight(cRef);
+ int thisW = (int)CGDisplayModeGetWidth(cRef);
+ if (thisBpp != bpp || thisH != h || thisW != w) {
// One of the key parameters does not match
continue;
}
@@ -114,11 +116,12 @@
// Refresh rate might be 0 in display mode and we ask for specific display rate
// but if we do not find exact match then 0 refresh rate might be just Ok
- if (CGDisplayModeGetRefreshRate(cRef) == refrate) {
+ int thisRefrate = (int)CGDisplayModeGetRefreshRate(cRef);
+ if (thisRefrate == refrate) {
// Exact match
return cRef;
}
- if (CGDisplayModeGetRefreshRate(cRef) == 0) {
+ if (thisRefrate == 0) {
// Not exactly what was asked for, but may fit our needs if we don't find an exact match
bestGuess = cRef;
}
diff --git a/jdk/src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m b/jdk/src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m
index 5d5fb8f..bbf387e 100644
--- a/jdk/src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m
+++ b/jdk/src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m
@@ -220,7 +220,6 @@
AWT_ASSERT_APPKIT_THREAD;
jint displayID = (jint)[(NSNumber *)[argValue objectAtIndex: 0] intValue];
- jint pixfmt = (jint)[(NSNumber *)[argValue objectAtIndex: 1] intValue];
jint swapInterval = (jint)[(NSNumber *)[argValue objectAtIndex: 2] intValue];
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
[argValue removeAllObjects];
@@ -229,11 +228,7 @@
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- CGOpenGLDisplayMask glMask = (CGOpenGLDisplayMask)pixfmt;
if (sharedContext == NULL) {
- if (glMask == 0) {
- glMask = CGDisplayIDToOpenGLDisplayMask(displayID);
- }
NSOpenGLPixelFormatAttribute attrs[] = {
NSOpenGLPFAAllowOfflineRenderers,
@@ -244,16 +239,17 @@
NSOpenGLPFAColorSize, 32,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFADepthSize, 16,
- NSOpenGLPFAScreenMask, glMask,
0
};
sharedPixelFormat =
[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
if (sharedPixelFormat == nil) {
- J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: shared NSOpenGLPixelFormat is NULL");
- [argValue addObject: [NSNumber numberWithLong: 0L]];
- return;
+ J2dRlsTraceLn(J2D_TRACE_ERROR,
+ "CGLGraphicsConfig_getCGLConfigInfo: shared NSOpenGLPixelFormat is NULL");
+
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
}
sharedContext =
diff --git a/jdk/src/share/classes/com/sun/crypto/provider/JceKeyStore.java b/jdk/src/share/classes/com/sun/crypto/provider/JceKeyStore.java
index a3e9909..2800f24 100644
--- a/jdk/src/share/classes/com/sun/crypto/provider/JceKeyStore.java
+++ b/jdk/src/share/classes/com/sun/crypto/provider/JceKeyStore.java
@@ -45,6 +45,7 @@
import java.security.cert.CertificateException;
import javax.crypto.SealedObject;
+import sun.misc.IOUtils;
import sun.misc.ObjectInputFilter;
/**
@@ -73,7 +74,7 @@
private static final class PrivateKeyEntry {
Date date; // the creation date of this entry
byte[] protectedKey;
- Certificate chain[];
+ Certificate[] chain;
};
// Secret key
@@ -742,23 +743,11 @@
entry.date = new Date(dis.readLong());
// read the private key
- try {
- entry.protectedKey = new byte[dis.readInt()];
- } catch (OutOfMemoryError e) {
- throw new IOException("Keysize too big");
- }
- dis.readFully(entry.protectedKey);
+ entry.protectedKey = IOUtils.readExactlyNBytes(dis, dis.readInt());
// read the certificate chain
int numOfCerts = dis.readInt();
- try {
- if (numOfCerts > 0) {
- entry.chain = new Certificate[numOfCerts];
- }
- } catch (OutOfMemoryError e) {
- throw new IOException("Too many certificates in "
- + "chain");
- }
+ List<Certificate> tmpCerts = new ArrayList<>();
for (int j = 0; j < numOfCerts; j++) {
if (xVersion == 2) {
// read the certificate type, and instantiate a
@@ -766,27 +755,24 @@
// existing factory if possible)
String certType = dis.readUTF();
if (cfs.containsKey(certType)) {
- // reuse certificate factory
+ // reuse certificate factory
cf = cfs.get(certType);
} else {
- // create new certificate factory
+ // create new certificate factory
cf = CertificateFactory.getInstance(
certType);
- // store the certificate factory so we can
- // reuse it later
+ // store the certificate factory so we can
+ // reuse it later
cfs.put(certType, cf);
}
}
// instantiate the certificate
- try {
- encoded = new byte[dis.readInt()];
- } catch (OutOfMemoryError e) {
- throw new IOException("Certificate too big");
- }
- dis.readFully(encoded);
+ encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
bais = new ByteArrayInputStream(encoded);
- entry.chain[j] = cf.generateCertificate(bais);
+ tmpCerts.add(cf.generateCertificate(bais));
}
+ entry.chain = tmpCerts.toArray(
+ new Certificate[numOfCerts]);
// Add the entry to the list
entries.put(alias, entry);
@@ -818,12 +804,7 @@
cfs.put(certType, cf);
}
}
- try {
- encoded = new byte[dis.readInt()];
- } catch (OutOfMemoryError e) {
- throw new IOException("Certificate too big");
- }
- dis.readFully(encoded);
+ encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
bais = new ByteArrayInputStream(encoded);
entry.cert = cf.generateCertificate(bais);
@@ -882,18 +863,14 @@
* with
*/
if (password != null) {
- byte computed[], actual[];
- computed = md.digest();
- actual = new byte[computed.length];
- dis.readFully(actual);
- for (int i = 0; i < computed.length; i++) {
- if (computed[i] != actual[i]) {
- throw new IOException(
+ byte[] computed = md.digest();
+ byte[] actual = IOUtils.readExactlyNBytes(dis, computed.length);
+ if (!MessageDigest.isEqual(computed, actual)) {
+ throw new IOException(
"Keystore was tampered with, or "
+ "password was incorrect",
- new UnrecoverableKeyException(
- "Password verification failed"));
- }
+ new UnrecoverableKeyException(
+ "Password verification failed"));
}
}
} finally {
diff --git a/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java b/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java
index 74b3cc4..d3cbae6 100644
--- a/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java
+++ b/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -137,6 +137,10 @@
mgfSpec = MGF1ParameterSpec.SHA384;
} else if (mgfDigestName.equals("SHA-512")) {
mgfSpec = MGF1ParameterSpec.SHA512;
+ } else if (mgfDigestName.equals("SHA-512/224")) {
+ mgfSpec = MGF1ParameterSpec.SHA512_224;
+ } else if (mgfDigestName.equals("SHA-512/256")) {
+ mgfSpec = MGF1ParameterSpec.SHA512_256;
} else {
throw new IOException(
"Unrecognized message digest algorithm");
diff --git a/jdk/src/share/classes/com/sun/crypto/provider/RSACipher.java b/jdk/src/share/classes/com/sun/crypto/provider/RSACipher.java
index 5faefb6..1d7baca 100644
--- a/jdk/src/share/classes/com/sun/crypto/provider/RSACipher.java
+++ b/jdk/src/share/classes/com/sun/crypto/provider/RSACipher.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,13 +44,15 @@
/**
* RSA cipher implementation. Supports RSA en/decryption and signing/verifying
- * using PKCS#1 v1.5 padding and without padding (raw RSA). Note that raw RSA
- * is supported mostly for completeness and should only be used in rare cases.
+ * using both PKCS#1 v1.5 and OAEP (v2.2) paddings and without padding (raw RSA).
+ * Note that raw RSA is supported mostly for completeness and should only be
+ * used in rare cases.
*
* Objects should be instantiated by calling Cipher.getInstance() using the
* following algorithm names:
- * . "RSA/ECB/PKCS1Padding" (or "RSA") for PKCS#1 padding. The mode (blocktype)
- * is selected based on the en/decryption mode and public/private key used
+ * . "RSA/ECB/PKCS1Padding" (or "RSA") for PKCS#1 v1.5 padding.
+ * . "RSA/ECB/OAEPwith<hash>andMGF1Padding" (or "RSA/ECB/OAEPPadding") for
+ * PKCS#1 v2.2 padding.
* . "RSA/ECB/NoPadding" for rsa RSA.
*
* We only do one RSA operation per doFinal() call. If the application passes
@@ -81,7 +83,7 @@
private final static String PAD_NONE = "NoPadding";
// constant for PKCS#1 v1.5 RSA
private final static String PAD_PKCS1 = "PKCS1Padding";
- // constant for PKCS#2 v2.0 OAEP with MGF1
+ // constant for PKCS#2 v2.2 OAEP with MGF1
private final static String PAD_OAEP_MGF1 = "OAEP";
// current mode, one of MODE_* above. Set when init() is called
diff --git a/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java b/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java
index 55c55e2..efe8031 100644
--- a/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java
+++ b/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -131,7 +131,9 @@
+ "|OAEPWITHSHA-224ANDMGF1PADDING"
+ "|OAEPWITHSHA-256ANDMGF1PADDING"
+ "|OAEPWITHSHA-384ANDMGF1PADDING"
- + "|OAEPWITHSHA-512ANDMGF1PADDING");
+ + "|OAEPWITHSHA-512ANDMGF1PADDING"
+ + "|OAEPWITHSHA-512/224ANDMGF1PADDING"
+ + "|OAEPWITHSHA-512/256ANDMGF1PADDING");
put("Cipher.RSA SupportedKeyClasses",
"java.security.interfaces.RSAPublicKey" +
"|java.security.interfaces.RSAPrivateKey");
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java
index 3da159f..e86e60e 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java
@@ -123,6 +123,13 @@
return e;
}
+ private Entry checkValid(Entry e) {
+ if (e == INVALID_ENTRY) {
+ throw new IllegalStateException("Invalid constant pool reference");
+ }
+ return e;
+ }
+
/** Throw a ClassFormatException if the entry does not match the expected tag type. */
private Entry checkTag(Entry e, byte tag) throws ClassFormatException {
if (e == null || !e.tagMatches(tag)) {
@@ -225,6 +232,29 @@
return null; // OK
}
+ // use this identity for invalid references
+ private static final Entry INVALID_ENTRY = new Entry((byte) -1) {
+ @Override
+ public boolean equals(Object o) {
+ throw new IllegalStateException("Should not call this");
+ }
+
+ @Override
+ protected int computeValueHash() {
+ throw new IllegalStateException("Should not call this");
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ throw new IllegalStateException("Should not call this");
+ }
+
+ @Override
+ public String stringValue() {
+ throw new IllegalStateException("Should not call this");
+ }
+ };
+
void readConstantPool() throws IOException {
int length = in.readUnsignedShort();
//System.err.println("reading CP, length="+length);
@@ -233,7 +263,7 @@
int fptr = 0;
Entry[] cpMap = new Entry[length];
- cpMap[0] = null;
+ cpMap[0] = INVALID_ENTRY;
for (int i = 1; i < length; i++) {
//System.err.println("reading CP elt, i="+i);
int tag = in.readByte();
@@ -254,13 +284,13 @@
case CONSTANT_Long:
{
cpMap[i] = ConstantPool.getLiteralEntry(in.readLong());
- cpMap[++i] = null;
+ cpMap[++i] = INVALID_ENTRY;
}
break;
case CONSTANT_Double:
{
cpMap[i] = ConstantPool.getLiteralEntry(in.readDouble());
- cpMap[++i] = null;
+ cpMap[++i] = INVALID_ENTRY;
}
break;
@@ -315,7 +345,7 @@
int ref2 = fixups[fi++];
if (verbose > 3)
Utils.log.fine(" cp["+cpi+"] = "+ConstantPool.tagName(tag)+"{"+ref+","+ref2+"}");
- if (ref >= 0 && cpMap[ref] == null || ref2 >= 0 && cpMap[ref2] == null) {
+ if (ref >= 0 && checkValid(cpMap[ref]) == null || ref2 >= 0 && checkValid(cpMap[ref2]) == null) {
// Defer.
fixups[fptr++] = cpi;
fixups[fptr++] = tag;
@@ -364,7 +394,6 @@
cls.cpMap = cpMap;
}
-
private /*non-static*/
class UnresolvedEntry extends Entry {
final Object[] refsOrIndexes;
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java
index 43e83c1..e36670e 100644
--- a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java
@@ -47,8 +47,6 @@
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
-import sun.misc.IOUtils;
-
/**
* A thread that creates a connection to an LDAP server.
* After the connection, the thread reads from the connection.
@@ -886,7 +884,7 @@
}
// read in seqlen bytes
- byte[] left = IOUtils.readFully(in, seqlen, false);
+ byte[] left = readFully(in, seqlen);
inbuf = Arrays.copyOf(inbuf, offset + left.length);
System.arraycopy(left, 0, inbuf, offset, left.length);
offset += left.length;
@@ -981,6 +979,31 @@
}
}
+ private static byte[] readFully(InputStream is, int length)
+ throws IOException
+ {
+ byte[] buf = new byte[Math.min(length, 8192)];
+ int nread = 0;
+ while (nread < length) {
+ int bytesToRead;
+ if (nread >= buf.length) { // need to allocate a larger buffer
+ bytesToRead = Math.min(length - nread, buf.length + 8192);
+ if (buf.length < nread + bytesToRead) {
+ buf = Arrays.copyOf(buf, nread + bytesToRead);
+ }
+ } else {
+ bytesToRead = buf.length - nread;
+ }
+ int count = is.read(buf, nread, bytesToRead);
+ if (count < 0) {
+ if (buf.length != nread)
+ buf = Arrays.copyOf(buf, nread);
+ break;
+ }
+ nread += count;
+ }
+ return buf;
+ }
// This code must be uncommented to run the LdapAbandonTest.
/*public void sendSearchReqs(String dn, int numReqs) {
diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java
index db1f49e..741f3c1 100644
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java
@@ -376,14 +376,14 @@
return null;
}
- int lengthDataBits = binaryData.length * EIGHTBIT;
- if (lengthDataBits == 0) {
+ long lengthDataBits = ((long) binaryData.length) * ((long) EIGHTBIT);
+ if (lengthDataBits == 0L) {
return "";
}
- int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
- int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
- int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
+ long fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
+ int numberTriplets = (int) (lengthDataBits / TWENTYFOURBITGROUP);
+ int numberQuartet = fewerThan24bits != 0L ? numberTriplets + 1 : numberTriplets;
int quartesPerLine = length / 4;
int numberLines = (numberQuartet - 1) / quartesPerLine;
char encodedData[] = null;
diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IgnoreAllErrorHandler.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IgnoreAllErrorHandler.java
index d06a41f..4d0ab52 100644
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IgnoreAllErrorHandler.java
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IgnoreAllErrorHandler.java
@@ -35,19 +35,30 @@
public class IgnoreAllErrorHandler implements ErrorHandler {
/** {@link org.apache.commons.logging} logging facility */
- private static java.util.logging.Logger log =
+ private static final java.util.logging.Logger log =
java.util.logging.Logger.getLogger(IgnoreAllErrorHandler.class.getName());
/** Field throwExceptions */
- private static final boolean warnOnExceptions =
- System.getProperty("com.sun.org.apache.xml.internal.security.test.warn.on.exceptions", "false").equals("true");
+ private static final boolean warnOnExceptions = getProperty(
+ "com.sun.org.apache.xml.internal.security.test.warn.on.exceptions");
/** Field throwExceptions */
- private static final boolean throwExceptions =
- System.getProperty("com.sun.org.apache.xml.internal.security.test.throw.exceptions", "false").equals("true");
+ private static final boolean throwExceptions = getProperty(
+ "com.sun.org.apache.xml.internal.security.test.throw.exceptions");
+ private static boolean getProperty(String name) {
+ return java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Boolean>() {
+
+ @Override
+ public Boolean run() {
+ return Boolean.getBoolean(name);
+ }
+ });
+ }
/** @inheritDoc */
+ @Override
public void warning(SAXParseException ex) throws SAXException {
if (IgnoreAllErrorHandler.warnOnExceptions) {
log.log(java.util.logging.Level.WARNING, "", ex);
@@ -59,6 +70,7 @@
/** @inheritDoc */
+ @Override
public void error(SAXParseException ex) throws SAXException {
if (IgnoreAllErrorHandler.warnOnExceptions) {
log.log(java.util.logging.Level.SEVERE, "", ex);
@@ -70,6 +82,7 @@
/** @inheritDoc */
+ @Override
public void fatalError(SAXParseException ex) throws SAXException {
if (IgnoreAllErrorHandler.warnOnExceptions) {
log.log(java.util.logging.Level.WARNING, "", ex);
diff --git a/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java b/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
index 8547363..448764c 100644
--- a/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
+++ b/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
@@ -123,8 +123,9 @@
* must also be set to true; Otherwise a configuration error will
* be returned.</dd>
* <dt><b><code>renewTGT</code></b>:</dt>
- * <dd>Set this to true, if you want to renew
- * the TGT. If this is set, <code>useTicketCache</code> must also be
+ * <dd>Set this to true, if you want to renew the TGT when it's more than
+ * half-way expired (the time until expiration is less than the time
+ * since start time). If this is set, {@code useTicketCache} must also be
* set to true; otherwise a configuration error will be returned.</dd>
* <dt><b><code>doNotPrompt</code></b>:</dt>
* <dd>Set this to true if you do not want to be
@@ -665,22 +666,21 @@
(principal, ticketCacheName);
if (cred != null) {
- // check to renew credentials
- if (!isCurrent(cred)) {
- if (renewTGT) {
- Credentials newCred = renewCredentials(cred);
- if (newCred != null) {
- newCred.setProxy(cred.getProxy());
- }
+ if (renewTGT && isOld(cred)) {
+ // renew if ticket is old.
+ Credentials newCred = renewCredentials(cred);
+ if (newCred != null) {
+ newCred.setProxy(cred.getProxy());
cred = newCred;
- } else {
- // credentials have expired
- cred = null;
- if (debug)
- System.out.println("Credentials are" +
- " no longer valid");
}
}
+ if (!isCurrent(cred)) {
+ // credentials have expired
+ cred = null;
+ if (debug)
+ System.out.println("Credentials are" +
+ " no longer valid");
+ }
}
if (cred != null) {
@@ -988,7 +988,7 @@
}
}
- private boolean isCurrent(Credentials creds)
+ private static boolean isCurrent(Credentials creds)
{
Date endTime = creds.getEndTime();
if (endTime != null) {
@@ -997,6 +997,23 @@
return true;
}
+ private static boolean isOld(Credentials creds)
+ {
+ Date endTime = creds.getEndTime();
+ if (endTime != null) {
+ Date authTime = creds.getAuthTime();
+ long now = System.currentTimeMillis();
+ if (authTime != null) {
+ // pass the mid between auth and end
+ return now - authTime.getTime() > endTime.getTime() - now;
+ } else {
+ // will expire in less than 2 hours
+ return now <= endTime.getTime() - 1000*3600*2L;
+ }
+ }
+ return false;
+ }
+
private Credentials renewCredentials(Credentials creds)
{
Credentials lcreds;
@@ -1004,6 +1021,10 @@
if (!creds.isRenewable())
throw new RefreshFailedException("This ticket" +
" is not renewable");
+ if (creds.getRenewTill() == null) {
+ // Renewable ticket without renew-till. Illegal and ignored.
+ return creds;
+ }
if (System.currentTimeMillis() > cred.getRenewTill().getTime())
throw new RefreshFailedException("This ticket is past "
+ "its last renewal time.");
diff --git a/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java b/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java
index 30461e2..baa836e 100644
--- a/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java
+++ b/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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,8 +73,12 @@
}
try {
- MessageProp msgProp = new MessageProp(JGSS_QOP, privacy);
+ MessageProp msgProp = new MessageProp(JGSS_QOP, false);
byte[] answer = secCtx.unwrap(incoming, start, len, msgProp);
+ if (privacy && !msgProp.getPrivacy()) {
+ throw new SaslException("Privacy not protected");
+ }
+ checkMessageProp("", msgProp);
if (logger.isLoggable(Level.FINEST)) {
traceOutput(myClassName, "KRB501:Unwrap", "incoming: ",
incoming, start, len);
@@ -128,4 +132,20 @@
protected void finalize() throws Throwable {
dispose();
}
+
+ void checkMessageProp(String label, MessageProp msgProp)
+ throws SaslException {
+ if (msgProp.isDuplicateToken()) {
+ throw new SaslException(label + "Duplicate token");
+ }
+ if (msgProp.isGapToken()) {
+ throw new SaslException(label + "Gap token");
+ }
+ if (msgProp.isOldToken()) {
+ throw new SaslException(label + "Old token");
+ }
+ if (msgProp.isUnseqToken()) {
+ throw new SaslException(label + "Token not in sequence");
+ }
+ }
}
diff --git a/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java b/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java
index e8d9a4c..34a879a 100644
--- a/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java
+++ b/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -230,8 +230,10 @@
// Received S1 (security layer, server max recv size)
+ MessageProp msgProp = new MessageProp(false);
byte[] gssOutToken = secCtx.unwrap(challengeData, 0,
- challengeData.length, new MessageProp(0, false));
+ challengeData.length, msgProp);
+ checkMessageProp("Handshake failure: ", msgProp);
// First octet is a bit-mask specifying the protections
// supported by the server
diff --git a/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java b/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java
index 94ce39c..10c429a 100644
--- a/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java
+++ b/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -250,8 +250,10 @@
try {
// Expecting 4 octets from client selected protection
// and client's receive buffer size
+ MessageProp msgProp = new MessageProp(false);
byte[] gssOutToken = secCtx.unwrap(responseData, 0,
- responseData.length, new MessageProp(0, false));
+ responseData.length, msgProp);
+ checkMessageProp("Handshake failure: ", msgProp);
if (logger.isLoggable(Level.FINER)) {
traceOutput(MY_CLASS_NAME, "doHandshake2",
diff --git a/jdk/src/share/classes/java/awt/color/ICC_Profile.java b/jdk/src/share/classes/java/awt/color/ICC_Profile.java
index 89abeca..af1e5fc 100644
--- a/jdk/src/share/classes/java/awt/color/ICC_Profile.java
+++ b/jdk/src/share/classes/java/awt/color/ICC_Profile.java
@@ -43,7 +43,9 @@
import sun.java2d.cmm.ProfileDeferralMgr;
import sun.java2d.cmm.ProfileDeferralInfo;
import sun.java2d.cmm.ProfileActivator;
+import sun.misc.IOUtils;
+import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -1019,42 +1021,25 @@
static byte[] getProfileDataFromStream(InputStream s) throws IOException {
- byte profileData[];
- int profileSize;
- byte header[] = new byte[128];
- int bytestoread = 128;
- int bytesread = 0;
- int n;
+ BufferedInputStream bis = new BufferedInputStream(s);
+ bis.mark(128);
- while (bytestoread != 0) {
- if ((n = s.read(header, bytesread, bytestoread)) < 0) {
- return null;
- }
- bytesread += n;
- bytestoread -= n;
- }
+ byte[] header = IOUtils.readNBytes(bis, 128);
if (header[36] != 0x61 || header[37] != 0x63 ||
header[38] != 0x73 || header[39] != 0x70) {
return null; /* not a valid profile */
}
- profileSize = ((header[0] & 0xff) << 24) |
- ((header[1] & 0xff) << 16) |
- ((header[2] & 0xff) << 8) |
- (header[3] & 0xff);
- profileData = new byte[profileSize];
- System.arraycopy(header, 0, profileData, 0, 128);
- bytestoread = profileSize - 128;
- bytesread = 128;
- while (bytestoread != 0) {
- if ((n = s.read(profileData, bytesread, bytestoread)) < 0) {
- return null;
- }
- bytesread += n;
- bytestoread -= n;
+ int profileSize = ((header[0] & 0xff) << 24) |
+ ((header[1] & 0xff) << 16) |
+ ((header[2] & 0xff) << 8) |
+ (header[3] & 0xff);
+ bis.reset();
+ try {
+ return IOUtils.readNBytes(bis, profileSize);
+ } catch (OutOfMemoryError e) {
+ throw new IOException("Color profile is too big");
}
-
- return profileData;
}
diff --git a/jdk/src/share/classes/java/beans/beancontext/BeanContextSupport.java b/jdk/src/share/classes/java/beans/beancontext/BeanContextSupport.java
index 43dfcb0..9ce1658 100644
--- a/jdk/src/share/classes/java/beans/beancontext/BeanContextSupport.java
+++ b/jdk/src/share/classes/java/beans/beancontext/BeanContextSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -1024,18 +1024,8 @@
int count = serializable;
while (count-- > 0) {
- Object child = null;
- BeanContextSupport.BCSChild bscc = null;
-
- try {
- child = ois.readObject();
- bscc = (BeanContextSupport.BCSChild)ois.readObject();
- } catch (IOException ioe) {
- continue;
- } catch (ClassNotFoundException cnfe) {
- continue;
- }
-
+ Object child = ois.readObject();
+ BCSChild bscc = (BCSChild) ois.readObject();
synchronized(child) {
BeanContextChild bcc = null;
diff --git a/jdk/src/share/classes/java/io/FilePermission.java b/jdk/src/share/classes/java/io/FilePermission.java
index 3e0f7d8..ae4a919 100644
--- a/jdk/src/share/classes/java/io/FilePermission.java
+++ b/jdk/src/share/classes/java/io/FilePermission.java
@@ -46,8 +46,11 @@
* the file separator character, <code>File.separatorChar</code>) indicates
* all the files and directories contained in that directory. A pathname
* that ends with "/-" indicates (recursively) all files
- * and subdirectories contained in that directory. A pathname consisting of
- * the special token "<<ALL FILES>>" matches <b>any</b> file.
+ * and subdirectories contained in that directory. Such a pathname is called
+ * a wildcard pathname. Otherwise, it's a simple pathname.
+ * <P>
+ * A pathname consisting of the special token {@literal "<<ALL FILES>>"}
+ * matches <b>any</b> file.
* <P>
* Note: A pathname consisting of a single "*" indicates all the files
* in the current directory, while a pathname consisting of a single "-"
@@ -80,7 +83,7 @@
* <P>
* Be careful when granting FilePermissions. Think about the implications
* of granting read and especially write access to various files and
- * directories. The "<<ALL FILES>>" permission with write action is
+ * directories. The {@literal "<<ALL FILES>>"} permission with write action is
* especially dangerous. This grants permission to write to the entire
* file system. One thing this effectively allows is replacement of the
* system binary, including the JVM runtime environment.
@@ -156,6 +159,7 @@
private transient String cpath;
+ private transient boolean allFiles; // whether this is <<ALL FILES>>
private transient boolean invalid; // whether input path is invalid
// static Strings used by init(int mask)
@@ -207,6 +211,7 @@
this.mask = mask;
if (cpath.equals("<<ALL FILES>>")) {
+ allFiles = true;
directory = true;
recursive = true;
cpath = "";
@@ -335,6 +340,23 @@
* "/tmp/*" encompasses all files in the "/tmp" directory,
* including the one named "foo".
* </ul>
+ * <P>
+ * Precisely, a simple pathname implies another simple pathname
+ * if and only if they are equal. A simple pathname never implies
+ * a wildcard pathname. A wildcard pathname implies another wildcard
+ * pathname if and only if all simple pathnames implied by the latter
+ * are implied by the former. A wildcard pathname implies a simple
+ * pathname if and only if
+ * <ul>
+ * <li>if the wildcard flag is "*", the simple pathname's path
+ * must be right inside the wildcard pathname's path.
+ * <li>if the wildcard flag is "-", the simple pathname's path
+ * must be recursively inside the wildcard pathname's path.
+ * </ul>
+ * <P>
+ * {@literal "<<ALL FILES>>"} implies every other pathname. No pathname,
+ * except for {@literal "<<ALL FILES>>"} itself, implies
+ * {@literal "<<ALL FILES>>"}.
*
* @param p the permission to check against.
*
@@ -366,9 +388,15 @@
if (this == that) {
return true;
}
+ if (allFiles) {
+ return true;
+ }
if (this.invalid || that.invalid) {
return false;
}
+ if (that.allFiles) {
+ return false;
+ }
if (this.directory) {
if (this.recursive) {
// make sure that.path is longer then path so
@@ -415,6 +443,10 @@
* Checks two FilePermission objects for equality. Checks that <i>obj</i> is
* a FilePermission, and has the same pathname and actions as this object.
*
+ * @implNote More specifically, two pathnames are the same if and only if
+ * they have the same wildcard flag and their
+ * {@code npath} are equal. Or they are both {@literal "<<ALL FILES>>"}.
+ *
* @param obj the object we are testing for equality with this object.
* @return <code>true</code> if obj is a FilePermission, and has the same
* pathname and actions as this FilePermission object,
@@ -433,6 +465,7 @@
return false;
}
return (this.mask == that.mask) &&
+ (this.allFiles == that.allFiles) &&
this.cpath.equals(that.cpath) &&
(this.directory == that.directory) &&
(this.recursive == that.recursive);
diff --git a/jdk/src/share/classes/java/io/ObjectInputStream.java b/jdk/src/share/classes/java/io/ObjectInputStream.java
index 9d293c7..b16d53b 100644
--- a/jdk/src/share/classes/java/io/ObjectInputStream.java
+++ b/jdk/src/share/classes/java/io/ObjectInputStream.java
@@ -419,16 +419,50 @@
* @throws IOException Any of the usual Input/Output related exceptions.
*/
public final Object readObject()
+ throws IOException, ClassNotFoundException {
+ return readObject(Object.class);
+ }
+
+ /**
+ * Reads a String and only a string.
+ *
+ * @return the String read
+ * @throws EOFException If end of file is reached.
+ * @throws IOException If other I/O error has occurred.
+ */
+ private String readString() throws IOException {
+ try {
+ return (String) readObject(String.class);
+ } catch (ClassNotFoundException cnf) {
+ throw new IllegalStateException(cnf);
+ }
+ }
+
+ /**
+ * Internal method to read an object from the ObjectInputStream of the expected type.
+ * Called only from {@code readObject()} and {@code readString()}.
+ * Only {@code Object.class} and {@code String.class} are supported.
+ *
+ * @param type the type expected; either Object.class or String.class
+ * @return an object of the type
+ * @throws IOException Any of the usual Input/Output related exceptions.
+ * @throws ClassNotFoundException Class of a serialized object cannot be
+ * found.
+ */
+ private final Object readObject(Class<?> type)
throws IOException, ClassNotFoundException
{
if (enableOverride) {
return readObjectOverride();
}
+ if (! (type == Object.class || type == String.class))
+ throw new AssertionError("internal error");
+
// if nested read, passHandle contains handle of enclosing object
int outerHandle = passHandle;
try {
- Object obj = readObject0(false);
+ Object obj = readObject0(type, false);
handles.markDependency(outerHandle, passHandle);
ClassNotFoundException ex = handles.lookupException(passHandle);
if (ex != null) {
@@ -518,7 +552,7 @@
// if nested read, passHandle contains handle of enclosing object
int outerHandle = passHandle;
try {
- Object obj = readObject0(true);
+ Object obj = readObject0(Object.class, true);
handles.markDependency(outerHandle, passHandle);
ClassNotFoundException ex = handles.lookupException(passHandle);
if (ex != null) {
@@ -1517,8 +1551,10 @@
/**
* Underlying readObject implementation.
+ * @param type a type expected to be deserialized; non-null
+ * @param unshared true if the object can not be a reference to a shared object, otherwise false
*/
- private Object readObject0(boolean unshared) throws IOException {
+ private Object readObject0(Class<?> type, boolean unshared) throws IOException {
boolean oldMode = bin.getBlockDataMode();
if (oldMode) {
int remain = bin.currentBlockRemaining();
@@ -1550,13 +1586,20 @@
return readNull();
case TC_REFERENCE:
- return readHandle(unshared);
+ // check the type of the existing object
+ return type.cast(readHandle(unshared));
case TC_CLASS:
+ if (type == String.class) {
+ throw new ClassCastException("Cannot cast a class to java.lang.String");
+ }
return readClass(unshared);
case TC_CLASSDESC:
case TC_PROXYCLASSDESC:
+ if (type == String.class) {
+ throw new ClassCastException("Cannot cast a class to java.lang.String");
+ }
return readClassDesc(unshared);
case TC_STRING:
@@ -1564,15 +1607,27 @@
return checkResolve(readString(unshared));
case TC_ARRAY:
+ if (type == String.class) {
+ throw new ClassCastException("Cannot cast an array to java.lang.String");
+ }
return checkResolve(readArray(unshared));
case TC_ENUM:
+ if (type == String.class) {
+ throw new ClassCastException("Cannot cast an enum to java.lang.String");
+ }
return checkResolve(readEnum(unshared));
case TC_OBJECT:
+ if (type == String.class) {
+ throw new ClassCastException("Cannot cast an object to java.lang.String");
+ }
return checkResolve(readOrdinaryObject(unshared));
case TC_EXCEPTION:
+ if (type == String.class) {
+ throw new ClassCastException("Cannot cast an exception to java.lang.String");
+ }
IOException ex = readFatalException();
throw new WriteAbortedException("writing aborted", ex);
@@ -1947,7 +2002,7 @@
if (ccl == null) {
for (int i = 0; i < len; i++) {
- readObject0(false);
+ readObject0(Object.class, false);
}
} else if (ccl.isPrimitive()) {
if (ccl == Integer.TYPE) {
@@ -1972,7 +2027,7 @@
} else {
Object[] oa = (Object[]) array;
for (int i = 0; i < len; i++) {
- oa[i] = readObject0(false);
+ oa[i] = readObject0(Object.class, false);
handles.markDependency(arrayHandle, passHandle);
}
}
@@ -2250,7 +2305,7 @@
return;
default:
- readObject0(false);
+ readObject0(Object.class, false);
break;
}
}
@@ -2284,7 +2339,7 @@
int numPrimFields = fields.length - objVals.length;
for (int i = 0; i < objVals.length; i++) {
ObjectStreamField f = fields[numPrimFields + i];
- objVals[i] = readObject0(f.isUnshared());
+ objVals[i] = readObject0(Object.class, f.isUnshared());
if (f.getField() != null) {
handles.markDependency(objHandle, passHandle);
}
@@ -2305,7 +2360,7 @@
throw new InternalError();
}
clear();
- return (IOException) readObject0(false);
+ return (IOException) readObject0(Object.class, false);
}
/**
@@ -2449,7 +2504,7 @@
int numPrimFields = fields.length - objVals.length;
for (int i = 0; i < objVals.length; i++) {
objVals[i] =
- readObject0(fields[numPrimFields + i].isUnshared());
+ readObject0(Object.class, fields[numPrimFields + i].isUnshared());
objHandles[i] = passHandle;
}
passHandle = oldHandle;
@@ -3403,7 +3458,15 @@
* utflen bytes.
*/
private String readUTFBody(long utflen) throws IOException {
- StringBuilder sbuf = new StringBuilder();
+ StringBuilder sbuf;
+ if (utflen > 0 && utflen < Integer.MAX_VALUE) {
+ // a reasonable initial capacity based on the UTF length
+ int initialCapacity = Math.min((int)utflen, 0xFFFF);
+ sbuf = new StringBuilder(initialCapacity);
+ } else {
+ sbuf = new StringBuilder();
+ }
+
if (!blkmode) {
end = pos = 0;
}
@@ -3918,5 +3981,6 @@
}
static {
SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator);
+ SharedSecrets.setJavaObjectInputStreamReadString(ObjectInputStream::readString);
}
}
diff --git a/jdk/src/share/classes/java/lang/ClassLoader.java b/jdk/src/share/classes/java/lang/ClassLoader.java
index 2e98092..925fdac 100644
--- a/jdk/src/share/classes/java/lang/ClassLoader.java
+++ b/jdk/src/share/classes/java/lang/ClassLoader.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Azul Systems, 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
@@ -1467,6 +1468,17 @@
}
}
+ /*
+ * Initialize default paths for native libraries search.
+ * Must be done early as JDK may load libraries during bootstrap.
+ *
+ * @see java.lang.System#initPhase1
+ */
+ static void initLibraryPaths() {
+ usr_paths = initializePath("java.library.path");
+ sys_paths = initializePath("sun.boot.library.path");
+ }
+
// Returns true if the specified class loader can be found in this class
// loader's delegation chain.
boolean isAncestor(ClassLoader cl) {
@@ -1809,10 +1821,9 @@
boolean isAbsolute) {
ClassLoader loader =
(fromClass == null) ? null : fromClass.getClassLoader();
- if (sys_paths == null) {
- usr_paths = initializePath("java.library.path");
- sys_paths = initializePath("sun.boot.library.path");
- }
+ assert sys_paths != null : "should be initialized at this point";
+ assert usr_paths != null : "should be initialized at this point";
+
if (isAbsolute) {
if (loadLibrary0(fromClass, new File(name))) {
return;
@@ -1902,13 +1913,14 @@
name +
" already loaded in another classloader");
}
- /* If the library is being loaded (must be by the same thread,
- * because Runtime.load and Runtime.loadLibrary are
- * synchronous). The reason is can occur is that the JNI_OnLoad
- * function can cause another loadLibrary invocation.
+ /*
+ * When a library is being loaded, JNI_OnLoad function can cause
+ * another loadLibrary invocation that should succeed.
*
- * Thus we can use a static stack to hold the list of libraries
- * we are loading.
+ * We use a static stack to hold the list of libraries we are
+ * loading because this can happen only when called by the
+ * same thread because Runtime.load and Runtime.loadLibrary
+ * are synchronous.
*
* If there is a pending load operation for the library, we
* immediately return success; otherwise, we raise
diff --git a/jdk/src/share/classes/java/lang/Runtime.java b/jdk/src/share/classes/java/lang/Runtime.java
index 9e53dc9..5039059 100644
--- a/jdk/src/share/classes/java/lang/Runtime.java
+++ b/jdk/src/share/classes/java/lang/Runtime.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Azul Systems, 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
@@ -797,7 +798,7 @@
load0(Reflection.getCallerClass(), filename);
}
- synchronized void load0(Class<?> fromClass, String filename) {
+ void load0(Class<?> fromClass, String filename) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkLink(filename);
@@ -858,14 +859,14 @@
loadLibrary0(Reflection.getCallerClass(), libname);
}
- synchronized void loadLibrary0(Class<?> fromClass, String libname) {
+ void loadLibrary0(Class<?> fromClass, String libname) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkLink(libname);
}
if (libname.indexOf((int)File.separatorChar) != -1) {
throw new UnsatisfiedLinkError(
- "Directory separator should not appear in library name: " + libname);
+ "Directory separator should not appear in library name: " + libname);
}
ClassLoader.loadLibrary(fromClass, libname, false);
}
diff --git a/jdk/src/share/classes/java/lang/System.java b/jdk/src/share/classes/java/lang/System.java
index b2747fa..c568f02 100644
--- a/jdk/src/share/classes/java/lang/System.java
+++ b/jdk/src/share/classes/java/lang/System.java
@@ -43,6 +43,8 @@
import sun.security.util.SecurityConstants;
import sun.reflect.annotation.AnnotationType;
+import jdk.internal.util.StaticProperty;
+
/**
* The <code>System</code> class contains several useful class fields
* and methods. It cannot be instantiated.
@@ -1183,6 +1185,7 @@
lineSeparator = props.getProperty("line.separator");
+ StaticProperty.jdkSerialFilter(); // Load StaticProperty to cache the property values
sun.misc.Version.init();
FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
@@ -1192,6 +1195,8 @@
setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
+ ClassLoader.initLibraryPaths();
+
// Load the zip library now in order to keep java.util.zip.ZipFile
// from trying to use itself to load this library later.
loadLibrary("zip");
diff --git a/jdk/src/share/classes/java/net/URL.java b/jdk/src/share/classes/java/net/URL.java
index bbe87b6..820733c 100644
--- a/jdk/src/share/classes/java/net/URL.java
+++ b/jdk/src/share/classes/java/net/URL.java
@@ -33,6 +33,7 @@
import java.io.ObjectInputStream.GetField;
import java.util.Hashtable;
import java.util.StringTokenizer;
+import sun.misc.VM;
import sun.net.util.IPAddressUtil;
import sun.security.util.SecurityConstants;
@@ -1423,7 +1424,9 @@
}
boolean isBuiltinStreamHandler(URLStreamHandler handler) {
- return isBuiltinStreamHandler(handler.getClass().getName());
+ Class<?> handlerClass = handler.getClass();
+ return isBuiltinStreamHandler(handlerClass.getName())
+ || VM.isSystemDomainLoader(handlerClass.getClassLoader());
}
private boolean isBuiltinStreamHandler(String handlerClassName) {
diff --git a/jdk/src/share/classes/java/nio/channels/SelectableChannel.java b/jdk/src/share/classes/java/nio/channels/SelectableChannel.java
index 997d5c5..c7d7596 100644
--- a/jdk/src/share/classes/java/nio/channels/SelectableChannel.java
+++ b/jdk/src/share/classes/java/nio/channels/SelectableChannel.java
@@ -121,7 +121,7 @@
// keySet, may be empty but is never null, typ. a tiny array
// boolean isRegistered, protected by key set
// regLock, lock object to prevent duplicate registrations
- // boolean isBlocking, protected by regLock
+ // blocking mode, protected by regLock
/**
* Tells whether or not this channel is currently registered with any
diff --git a/jdk/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java b/jdk/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java
index 0de212d..d5b3ce8 100644
--- a/jdk/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java
+++ b/jdk/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,14 @@
package java.nio.channels.spi;
import java.io.IOException;
-import java.nio.channels.*;
+import java.nio.channels.CancelledKeyException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.ClosedSelectorException;
+import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.IllegalSelectorException;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
/**
@@ -67,8 +74,8 @@
// Lock for registration and configureBlocking operations
private final Object regLock = new Object();
- // Blocking mode, protected by regLock
- boolean blocking = true;
+ // True when non-blocking, need regLock to change;
+ private volatile boolean nonBlocking;
/**
* Initializes a new instance of this class.
@@ -197,7 +204,7 @@
throw new ClosedChannelException();
if ((ops & ~validOps()) != 0)
throw new IllegalArgumentException();
- if (blocking)
+ if (isBlocking())
throw new IllegalBlockingModeException();
SelectionKey k = findKey(sel);
if (k != null) {
@@ -264,9 +271,7 @@
// -- Blocking --
public final boolean isBlocking() {
- synchronized (regLock) {
- return blocking;
- }
+ return !nonBlocking;
}
public final Object blockingLock() {
@@ -287,12 +292,13 @@
synchronized (regLock) {
if (!isOpen())
throw new ClosedChannelException();
- if (blocking == block)
- return this;
- if (block && haveValidKeys())
- throw new IllegalBlockingModeException();
- implConfigureBlocking(block);
- blocking = block;
+ boolean blocking = !nonBlocking;
+ if (block != blocking) {
+ if (block && haveValidKeys())
+ throw new IllegalBlockingModeException();
+ implConfigureBlocking(block);
+ nonBlocking = !block;
+ }
}
return this;
}
diff --git a/jdk/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java b/jdk/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java
index c17eac6..3482b27 100644
--- a/jdk/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java
+++ b/jdk/src/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.rmi.Remote;
+import java.rmi.RemoteException;
import java.rmi.UnexpectedException;
import java.rmi.activation.Activatable;
import java.security.PrivilegedAction;
@@ -224,6 +225,13 @@
throw new IllegalArgumentException(
"proxy not Remote instance");
}
+
+ // Verify that the method is declared on an interface that extends Remote
+ Class<?> decl = method.getDeclaringClass();
+ if (!Remote.class.isAssignableFrom(decl)) {
+ throw new RemoteException("Method is not Remote: " + decl + "::" + method);
+ }
+
return ref.invoke((Remote) proxy, method, args,
getMethodHash(method));
} catch (Exception e) {
diff --git a/jdk/src/share/classes/java/security/CodeSource.java b/jdk/src/share/classes/java/security/CodeSource.java
index eb78c1d..e2ca471 100644
--- a/jdk/src/share/classes/java/security/CodeSource.java
+++ b/jdk/src/share/classes/java/security/CodeSource.java
@@ -570,7 +570,7 @@
cfs.put(certType, cf);
}
// parse the certificate
- byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
+ byte[] encoded = IOUtils.readExactlyNBytes(ois, ois.readInt());
ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
try {
certList.add(cf.generateCertificate(bais));
diff --git a/jdk/src/share/classes/java/security/Key.java b/jdk/src/share/classes/java/security/Key.java
index c0c63d7..09542e3 100644
--- a/jdk/src/share/classes/java/security/Key.java
+++ b/jdk/src/share/classes/java/security/Key.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2014, 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
@@ -63,7 +63,7 @@
* </pre>
*
* For more information, see
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
+ * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280:
* Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a>.
*
* <LI>A Format
diff --git a/jdk/src/share/classes/java/security/Signature.java b/jdk/src/share/classes/java/security/Signature.java
index 5232b9c..8d8408c 100644
--- a/jdk/src/share/classes/java/security/Signature.java
+++ b/jdk/src/share/classes/java/security/Signature.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,8 @@
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.BadPaddingException;
import javax.crypto.NoSuchPaddingException;
+import sun.misc.JavaSecuritySignatureAccess;
+import sun.misc.SharedSecrets;
import sun.security.util.Debug;
import sun.security.jca.*;
@@ -117,6 +119,34 @@
public abstract class Signature extends SignatureSpi {
+ static {
+ SharedSecrets.setJavaSecuritySignatureAccess(
+ new JavaSecuritySignatureAccess() {
+ @Override
+ public void initVerify(Signature s, PublicKey publicKey,
+ AlgorithmParameterSpec params)
+ throws InvalidKeyException,
+ InvalidAlgorithmParameterException {
+ s.initVerify(publicKey, params);
+ }
+ @Override
+ public void initVerify(Signature s,
+ java.security.cert.Certificate certificate,
+ AlgorithmParameterSpec params)
+ throws InvalidKeyException,
+ InvalidAlgorithmParameterException {
+ s.initVerify(certificate, params);
+ }
+ @Override
+ public void initSign(Signature s, PrivateKey privateKey,
+ AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidKeyException,
+ InvalidAlgorithmParameterException {
+ s.initSign(privateKey, params, random);
+ }
+ });
+ }
+
private static final Debug debug =
Debug.getInstance("jca", "Signature");
@@ -275,6 +305,7 @@
signatureInfo.put("sun.security.rsa.RSASignature$SHA256withRSA", TRUE);
signatureInfo.put("sun.security.rsa.RSASignature$SHA384withRSA", TRUE);
signatureInfo.put("sun.security.rsa.RSASignature$SHA512withRSA", TRUE);
+ signatureInfo.put("sun.security.rsa.RSAPSSSignature", TRUE);
signatureInfo.put("com.sun.net.ssl.internal.ssl.RSASignature", TRUE);
signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE);
}
@@ -467,6 +498,53 @@
}
/**
+ * Initialize this object for verification. If this method is called
+ * again with different arguments, it negates the effect
+ * of this call.
+ *
+ * @param publicKey the public key of the identity whose signature is
+ * going to be verified.
+ * @param params the parameters used for verifying this signature.
+ *
+ * @exception InvalidKeyException if the key is invalid.
+ * @exception InvalidAlgorithmParameterException if the params is invalid.
+ */
+ final void initVerify(PublicKey publicKey, AlgorithmParameterSpec params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ engineInitVerify(publicKey, params);
+ state = VERIFY;
+
+ if (!skipDebug && pdebug != null) {
+ pdebug.println("Signature." + algorithm +
+ " verification algorithm from: " + getProviderName());
+ }
+ }
+
+ private static PublicKey getPublicKeyFromCert(Certificate cert)
+ throws InvalidKeyException {
+ // If the certificate is of type X509Certificate,
+ // we should check whether it has a Key Usage
+ // extension marked as critical.
+ //if (cert instanceof java.security.cert.X509Certificate) {
+ if (cert instanceof X509Certificate) {
+ // Check whether the cert has a key usage extension
+ // marked as a critical extension.
+ // The OID for KeyUsage extension is 2.5.29.15.
+ X509Certificate c = (X509Certificate)cert;
+ Set<String> critSet = c.getCriticalExtensionOIDs();
+
+ if (critSet != null && !critSet.isEmpty()
+ && critSet.contains("2.5.29.15")) {
+ boolean[] keyUsageInfo = c.getKeyUsage();
+ // keyUsageInfo[0] is for digitalSignature.
+ if ((keyUsageInfo != null) && (keyUsageInfo[0] == false))
+ throw new InvalidKeyException("Wrong key usage");
+ }
+ }
+ return cert.getPublicKey();
+ }
+
+ /**
* Initializes this object for verification, using the public key from
* the given certificate.
* <p>If the certificate is of type X.509 and has a <i>key usage</i>
@@ -486,27 +564,40 @@
*/
public final void initVerify(Certificate certificate)
throws InvalidKeyException {
- // If the certificate is of type X509Certificate,
- // we should check whether it has a Key Usage
- // extension marked as critical.
- if (certificate instanceof java.security.cert.X509Certificate) {
- // Check whether the cert has a key usage extension
- // marked as a critical extension.
- // The OID for KeyUsage extension is 2.5.29.15.
- X509Certificate cert = (X509Certificate)certificate;
- Set<String> critSet = cert.getCriticalExtensionOIDs();
+ engineInitVerify(getPublicKeyFromCert(certificate));
+ state = VERIFY;
- if (critSet != null && !critSet.isEmpty()
- && critSet.contains("2.5.29.15")) {
- boolean[] keyUsageInfo = cert.getKeyUsage();
- // keyUsageInfo[0] is for digitalSignature.
- if ((keyUsageInfo != null) && (keyUsageInfo[0] == false))
- throw new InvalidKeyException("Wrong key usage");
- }
+ if (!skipDebug && pdebug != null) {
+ pdebug.println("Signature." + algorithm +
+ " verification algorithm from: " + getProviderName());
}
+ }
- PublicKey publicKey = certificate.getPublicKey();
- engineInitVerify(publicKey);
+ /**
+ * Initializes this object for verification, using the public key from
+ * the given certificate.
+ * <p>If the certificate is of type X.509 and has a <i>key usage</i>
+ * extension field marked as critical, and the value of the <i>key usage</i>
+ * extension field implies that the public key in
+ * the certificate and its corresponding private key are not
+ * supposed to be used for digital signatures, an
+ * {@code InvalidKeyException} is thrown.
+ *
+ * @param certificate the certificate of the identity whose signature is
+ * going to be verified.
+ * @param params the parameters used for verifying this signature.
+ *
+ * @exception InvalidKeyException if the public key in the certificate
+ * is not encoded properly or does not include required parameter
+ * information or cannot be used for digital signature purposes.
+ * @exception InvalidAlgorithmParameterException if the params is invalid.
+ *
+ * @since 8
+ */
+ final void initVerify(Certificate certificate,
+ AlgorithmParameterSpec params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ engineInitVerify(getPublicKeyFromCert(certificate), params);
state = VERIFY;
if (!skipDebug && pdebug != null) {
@@ -560,6 +651,31 @@
}
/**
+ * Initialize this object for signing. If this method is called
+ * again with different arguments, it negates the effect
+ * of this call.
+ *
+ * @param privateKey the private key of the identity whose signature
+ * is going to be generated.
+ * @param params the parameters used for generating signature.
+ * @param random the source of randomness for this signature.
+ *
+ * @exception InvalidKeyException if the key is invalid.
+ * @exception InvalidAlgorithmParameterException if the params is invalid
+ */
+ final void initSign(PrivateKey privateKey,
+ AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ engineInitSign(privateKey, params, random);
+ state = SIGN;
+
+ if (!skipDebug && pdebug != null) {
+ pdebug.println("Signature." + algorithm +
+ " signing algorithm from: " + getProviderName());
+ }
+ }
+
+ /**
* Returns the signature bytes of all the data updated.
* The format of the signature depends on the underlying
* signature scheme.
@@ -680,7 +796,7 @@
* encoded or of the wrong type, if this signature algorithm is unable to
* process the input data provided, etc.
* @exception IllegalArgumentException if the {@code signature}
- * byte array is null, or the {@code offset} or {@code length}
+ * byte array is {@code null}, or the {@code offset} or {@code length}
* is less than 0, or the sum of the {@code offset} and
* {@code length} is greater than the length of the
* {@code signature} byte array.
@@ -873,14 +989,15 @@
/**
* Returns the parameters used with this signature object.
*
- * <p>The returned parameters may be the same that were used to initialize
- * this signature, or may contain a combination of default and randomly
- * generated parameter values used by the underlying signature
- * implementation if this signature requires algorithm parameters but
- * was not initialized with any.
+ * <p> If this signature has been previously initialized with parameters
+ * (by calling the {@code setParameter} method), this method returns
+ * the same parameters. If this signature has not been initialized with
+ * parameters, this method may return a combination of default and
+ * randomly generated parameter values if the underlying
+ * signature implementation supports it and can successfully generate
+ * them. Otherwise, {@code null} is returned.
*
- * @return the parameters used with this signature, or null if this
- * signature does not use any parameters.
+ * @return the parameters used with this signature, or {@code null}
*
* @see #setParameter(AlgorithmParameterSpec)
* @since 1.4
@@ -901,7 +1018,7 @@
*
* @param param the string name of the parameter.
*
- * @return the object that represents the parameter value, or null if
+ * @return the object that represents the parameter value, or {@code null} if
* there is none.
*
* @exception InvalidParameterException if {@code param} is an invalid
@@ -1086,11 +1203,13 @@
}
}
- private void chooseProvider(int type, Key key, SecureRandom random)
- throws InvalidKeyException {
+ // Used by engineSetParameter/engineInitSign/engineInitVerify() to
+ // find the right provider with the supplied key, parameters, random source
+ private void chooseProvider(int type, Key key,
+ AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
synchronized (lock) {
if (sigSpi != null) {
- init(sigSpi, type, key, random);
return;
}
Exception lastException = null;
@@ -1103,7 +1222,7 @@
s = serviceIterator.next();
}
// if provider says it does not support this key, ignore it
- if (s.supportsParameter(key) == false) {
+ if (key != null && s.supportsParameter(key) == false) {
continue;
}
// if instance is not a SignatureSpi, ignore it
@@ -1112,7 +1231,7 @@
}
try {
SignatureSpi spi = newInstance(s);
- init(spi, type, key, random);
+ tryOperation(spi, type, key, params, random);
provider = s.getProvider();
sigSpi = spi;
firstService = null;
@@ -1134,6 +1253,10 @@
if (lastException instanceof RuntimeException) {
throw (RuntimeException)lastException;
}
+ if (lastException instanceof InvalidAlgorithmParameterException) {
+ throw (InvalidAlgorithmParameterException)lastException;
+ }
+
String k = (key != null) ? key.getClass().getName() : "(null)";
throw new InvalidKeyException
("No installed provider supports this key: "
@@ -1141,22 +1264,36 @@
}
}
- private final static int I_PUB = 1;
- private final static int I_PRIV = 2;
- private final static int I_PRIV_SR = 3;
+ private static final int I_PUB = 1;
+ private static final int I_PRIV = 2;
+ private static final int I_PRIV_SR = 3;
+ private static final int I_PUB_PARAM = 4;
+ private static final int I_PRIV_PARAM_SR = 5;
+ private static final int S_PARAM = 6;
- private void init(SignatureSpi spi, int type, Key key,
- SecureRandom random) throws InvalidKeyException {
+ private void tryOperation(SignatureSpi spi, int type, Key key,
+ AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+
switch (type) {
case I_PUB:
spi.engineInitVerify((PublicKey)key);
break;
+ case I_PUB_PARAM:
+ spi.engineInitVerify((PublicKey)key, params);
+ break;
case I_PRIV:
spi.engineInitSign((PrivateKey)key);
break;
case I_PRIV_SR:
spi.engineInitSign((PrivateKey)key, random);
break;
+ case I_PRIV_PARAM_SR:
+ spi.engineInitSign((PrivateKey)key, params, random);
+ break;
+ case S_PARAM:
+ spi.engineSetParameter(params);
+ break;
default:
throw new AssertionError("Internal error: " + type);
}
@@ -1167,7 +1304,22 @@
if (sigSpi != null) {
sigSpi.engineInitVerify(publicKey);
} else {
- chooseProvider(I_PUB, publicKey, null);
+ try {
+ chooseProvider(I_PUB, publicKey, null, null);
+ } catch (InvalidAlgorithmParameterException iape) {
+ // should not happen, re-throw as IKE just in case
+ throw new InvalidKeyException(iape);
+ }
+ }
+ }
+
+ void engineInitVerify(PublicKey publicKey,
+ AlgorithmParameterSpec params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ if (sigSpi != null) {
+ sigSpi.engineInitVerify(publicKey, params);
+ } else {
+ chooseProvider(I_PUB_PARAM, publicKey, params, null);
}
}
@@ -1176,7 +1328,12 @@
if (sigSpi != null) {
sigSpi.engineInitSign(privateKey);
} else {
- chooseProvider(I_PRIV, privateKey, null);
+ try {
+ chooseProvider(I_PRIV, privateKey, null, null);
+ } catch (InvalidAlgorithmParameterException iape) {
+ // should not happen, re-throw as IKE just in case
+ throw new InvalidKeyException(iape);
+ }
}
}
@@ -1185,7 +1342,22 @@
if (sigSpi != null) {
sigSpi.engineInitSign(privateKey, sr);
} else {
- chooseProvider(I_PRIV_SR, privateKey, sr);
+ try {
+ chooseProvider(I_PRIV_SR, privateKey, null, sr);
+ } catch (InvalidAlgorithmParameterException iape) {
+ // should not happen, re-throw as IKE just in case
+ throw new InvalidKeyException(iape);
+ }
+ }
+ }
+
+ void engineInitSign(PrivateKey privateKey,
+ AlgorithmParameterSpec params, SecureRandom sr)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ if (sigSpi != null) {
+ sigSpi.engineInitSign(privateKey, params, sr);
+ } else {
+ chooseProvider(I_PRIV_PARAM_SR, privateKey, params, sr);
}
}
@@ -1236,8 +1408,16 @@
protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
- chooseFirstProvider();
- sigSpi.engineSetParameter(params);
+ if (sigSpi != null) {
+ sigSpi.engineSetParameter(params);
+ } else {
+ try {
+ chooseProvider(S_PARAM, null, params, null);
+ } catch (InvalidKeyException ike) {
+ // should never happen, rethrow just in case
+ throw new InvalidAlgorithmParameterException(ike);
+ }
+ }
}
protected Object engineGetParameter(String param)
diff --git a/jdk/src/share/classes/java/security/SignatureSpi.java b/jdk/src/share/classes/java/security/SignatureSpi.java
index d6d2bc3..87df4bb 100644
--- a/jdk/src/share/classes/java/security/SignatureSpi.java
+++ b/jdk/src/share/classes/java/security/SignatureSpi.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -71,6 +71,33 @@
/**
* Initializes this signature object with the specified
+ * public key for verification operations.
+ *
+ * @param publicKey the public key of the identity whose signature is
+ * going to be verified.
+ * @param params the parameters for generating this signature
+ *
+ * @exception InvalidKeyException if the key is improperly
+ * encoded, does not work with the given parameters, and so on.
+ * @exception InvalidAlgorithmParameterException if the given parameters
+ * is invalid.
+ */
+ void engineInitVerify(PublicKey publicKey,
+ AlgorithmParameterSpec params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ if (params != null) {
+ try {
+ engineSetParameter(params);
+ } catch (UnsupportedOperationException usoe) {
+ // error out if not overrridden
+ throw new InvalidAlgorithmParameterException(usoe);
+ }
+ }
+ engineInitVerify(publicKey);
+ }
+
+ /**
+ * Initializes this signature object with the specified
* private key for signing operations.
*
* @param privateKey the private key of the identity whose signature
@@ -97,10 +124,41 @@
* encoded, parameters are missing, and so on.
*/
protected void engineInitSign(PrivateKey privateKey,
- SecureRandom random)
- throws InvalidKeyException {
- this.appRandom = random;
- engineInitSign(privateKey);
+ SecureRandom random)
+ throws InvalidKeyException {
+ this.appRandom = random;
+ engineInitSign(privateKey);
+ }
+
+ /**
+ * Initializes this signature object with the specified
+ * private key and source of randomness for signing operations.
+ *
+ * <p>This concrete method has been added to this previously-defined
+ * abstract class. (For backwards compatibility, it cannot be abstract.)
+ *
+ * @param privateKey the private key of the identity whose signature
+ * will be generated.
+ * @param params the parameters for generating this signature
+ * @param random the source of randomness
+ *
+ * @exception InvalidKeyException if the key is improperly
+ * encoded, parameters are missing, and so on.
+ * @exception InvalidAlgorithmParameterException if the parameters is
+ * invalid.
+ */
+ void engineInitSign(PrivateKey privateKey,
+ AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ if (params != null) {
+ try {
+ engineSetParameter(params);
+ } catch (UnsupportedOperationException usoe) {
+ // error out if not overrridden
+ throw new InvalidAlgorithmParameterException(usoe);
+ }
+ }
+ engineInitSign(privateKey, random);
}
/**
@@ -126,7 +184,7 @@
* properly
*/
protected abstract void engineUpdate(byte[] b, int off, int len)
- throws SignatureException;
+ throws SignatureException;
/**
* Updates the data to be signed or verified using the specified
@@ -222,7 +280,7 @@
* @since 1.2
*/
protected int engineSign(byte[] outbuf, int offset, int len)
- throws SignatureException {
+ throws SignatureException {
byte[] sig = engineSign();
if (len < sig.length) {
throw new SignatureException
@@ -250,7 +308,7 @@
* process the input data provided, etc.
*/
protected abstract boolean engineVerify(byte[] sigBytes)
- throws SignatureException;
+ throws SignatureException;
/**
* Verifies the passed-in signature in the specified array
@@ -272,7 +330,7 @@
* @since 1.4
*/
protected boolean engineVerify(byte[] sigBytes, int offset, int length)
- throws SignatureException {
+ throws SignatureException {
byte[] sigBytesCopy = new byte[length];
System.arraycopy(sigBytes, offset, sigBytesCopy, 0, length);
return engineVerify(sigBytesCopy);
@@ -304,7 +362,7 @@
*/
@Deprecated
protected abstract void engineSetParameter(String param, Object value)
- throws InvalidParameterException;
+ throws InvalidParameterException;
/**
* <p>This method is overridden by providers to initialize
@@ -320,23 +378,23 @@
* are inappropriate for this signature engine
*/
protected void engineSetParameter(AlgorithmParameterSpec params)
- throws InvalidAlgorithmParameterException {
- throw new UnsupportedOperationException();
+ throws InvalidAlgorithmParameterException {
+ throw new UnsupportedOperationException();
}
/**
- * <p>This method is overridden by providers to return the
- * parameters used with this signature engine, or null
- * if this signature engine does not use any parameters.
+ * <p>This method is overridden by providers to return the parameters
+ * used with this signature engine.
*
- * <p>The returned parameters may be the same that were used to initialize
- * this signature engine, or may contain a combination of default and
- * randomly generated parameter values used by the underlying signature
- * implementation if this signature engine requires algorithm parameters
- * but was not initialized with any.
+ * <p> If this signature engine has been previously initialized with
+ * parameters (by calling the {@code engineSetParameter} method), this
+ * method returns the same parameters. If this signature engine has not been
+ * initialized with parameters, this method may return a combination of
+ * default and randomly generated parameter values if the underlying
+ * signature implementation supports it and can successfully generate
+ * them. Otherwise, {@code null} is returned.
*
- * @return the parameters used with this signature engine, or null if this
- * signature engine does not use any parameters
+ * @return the parameters used with this signature engine, or {@code null}
*
* @exception UnsupportedOperationException if this method is
* not overridden by a provider
@@ -359,7 +417,7 @@
*
* @param param the string name of the parameter.
*
- * @return the object that represents the parameter value, or null if
+ * @return the object that represents the parameter value, or {@code null} if
* there is none.
*
* @exception InvalidParameterException if {@code param} is an
diff --git a/jdk/src/share/classes/java/security/UnresolvedPermission.java b/jdk/src/share/classes/java/security/UnresolvedPermission.java
index 2e8f5c7..c7eee55 100644
--- a/jdk/src/share/classes/java/security/UnresolvedPermission.java
+++ b/jdk/src/share/classes/java/security/UnresolvedPermission.java
@@ -590,7 +590,7 @@
cfs.put(certType, cf);
}
// parse the certificate
- byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
+ byte[] encoded = IOUtils.readExactlyNBytes(ois, ois.readInt());
ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
try {
certList.add(cf.generateCertificate(bais));
diff --git a/jdk/src/share/classes/java/security/cert/CRLReason.java b/jdk/src/share/classes/java/security/cert/CRLReason.java
index ac0b9e9..79d4729 100644
--- a/jdk/src/share/classes/java/security/cert/CRLReason.java
+++ b/jdk/src/share/classes/java/security/cert/CRLReason.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2014, 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,8 +27,8 @@
/**
* The CRLReason enumeration specifies the reason that a certificate
- * is revoked, as defined in <a href="http://www.ietf.org/rfc/rfc3280.txt">
- * RFC 3280: Internet X.509 Public Key Infrastructure Certificate and CRL
+ * is revoked, as defined in <a href="http://tools.ietf.org/html/rfc5280">
+ * RFC 5280: Internet X.509 Public Key Infrastructure Certificate and CRL
* Profile</a>.
*
* @author Sean Mullan
diff --git a/jdk/src/share/classes/java/security/cert/CertificateRevokedException.java b/jdk/src/share/classes/java/security/cert/CertificateRevokedException.java
index d478a79..98e4346 100644
--- a/jdk/src/share/classes/java/security/cert/CertificateRevokedException.java
+++ b/jdk/src/share/classes/java/security/cert/CertificateRevokedException.java
@@ -239,7 +239,7 @@
for (int i = 0; i < size; i++) {
String oid = (String) ois.readObject();
boolean critical = ois.readBoolean();
- byte[] extVal = IOUtils.readNBytes(ois, ois.readInt());
+ byte[] extVal = IOUtils.readExactlyNBytes(ois, ois.readInt());
Extension ext = sun.security.x509.Extension.newExtension
(new ObjectIdentifier(oid), critical, extVal);
extensions.put(oid, ext);
diff --git a/jdk/src/share/classes/java/security/cert/PKIXReason.java b/jdk/src/share/classes/java/security/cert/PKIXReason.java
index d58ded9..e9c4872 100644
--- a/jdk/src/share/classes/java/security/cert/PKIXReason.java
+++ b/jdk/src/share/classes/java/security/cert/PKIXReason.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
/**
* The {@code PKIXReason} enumerates the potential PKIX-specific reasons
* that an X.509 certification path may be invalid according to the PKIX
- * (RFC 3280) standard. These reasons are in addition to those of the
+ * (RFC 5280) standard. These reasons are in addition to those of the
* {@code CertPathValidatorException.BasicReason} enumeration.
*
* @since 1.7
diff --git a/jdk/src/share/classes/java/security/cert/TrustAnchor.java b/jdk/src/share/classes/java/security/cert/TrustAnchor.java
index c98bf81..e5be6a6 100644
--- a/jdk/src/share/classes/java/security/cert/TrustAnchor.java
+++ b/jdk/src/share/classes/java/security/cert/TrustAnchor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2014, 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
@@ -78,7 +78,7 @@
* The name constraints are specified as a byte array. This byte array
* should contain the DER encoded form of the name constraints, as they
* would appear in the NameConstraints structure defined in
- * <a href="http://www.ietf.org/rfc/rfc3280">RFC 3280</a>
+ * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280</a>
* and X.509. The ASN.1 definition of this structure appears below.
*
* <pre>{@code
@@ -140,7 +140,7 @@
* <p>
* The name constraints are specified as a byte array. This byte array
* contains the DER encoded form of the name constraints, as they
- * would appear in the NameConstraints structure defined in RFC 3280
+ * would appear in the NameConstraints structure defined in RFC 5280
* and X.509. The ASN.1 notation for this structure is supplied in the
* documentation for
* {@link #TrustAnchor(X509Certificate, byte[])
@@ -179,7 +179,7 @@
* <p>
* The name constraints are specified as a byte array. This byte array
* contains the DER encoded form of the name constraints, as they
- * would appear in the NameConstraints structure defined in RFC 3280
+ * would appear in the NameConstraints structure defined in RFC 5280
* and X.509. The ASN.1 notation for this structure is supplied in the
* documentation for
* {@link #TrustAnchor(X509Certificate, byte[])
@@ -294,7 +294,7 @@
* <p>
* The name constraints are returned as a byte array. This byte array
* contains the DER encoded form of the name constraints, as they
- * would appear in the NameConstraints structure defined in RFC 3280
+ * would appear in the NameConstraints structure defined in RFC 5280
* and X.509. The ASN.1 notation for this structure is supplied in the
* documentation for
* {@link #TrustAnchor(X509Certificate, byte[])
diff --git a/jdk/src/share/classes/java/security/cert/X509CRL.java b/jdk/src/share/classes/java/security/cert/X509CRL.java
index 5ce8484..2b48ceb 100644
--- a/jdk/src/share/classes/java/security/cert/X509CRL.java
+++ b/jdk/src/share/classes/java/security/cert/X509CRL.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,13 +25,9 @@
package java.security.cert;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.InvalidKeyException;
-import java.security.SignatureException;
-import java.security.Principal;
-import java.security.Provider;
-import java.security.PublicKey;
+import java.security.*;
+import java.security.spec.*;
+
import javax.security.auth.x500.X500Principal;
import java.math.BigInteger;
@@ -40,6 +36,7 @@
import java.util.Arrays;
import sun.security.x509.X509CRLImpl;
+import sun.security.util.SignatureUtil;
/**
* <p>
@@ -69,7 +66,7 @@
* </pre>
* <p>
* More information can be found in
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
+ * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280: Internet X.509
* Public Key Infrastructure Certificate and CRL Profile</a>.
* <p>
* The ASN.1 definition of {@code tbsCertList} is:
@@ -241,7 +238,27 @@
public void verify(PublicKey key, Provider sigProvider)
throws CRLException, NoSuchAlgorithmException,
InvalidKeyException, SignatureException {
- X509CRLImpl.verify(this, key, sigProvider);
+ String sigAlgName = getSigAlgName();
+ Signature sig = (sigProvider == null)
+ ? Signature.getInstance(sigAlgName)
+ : Signature.getInstance(sigAlgName, sigProvider);
+
+ try {
+ byte[] paramBytes = getSigAlgParams();
+ SignatureUtil.initVerifyWithParam(sig, key,
+ SignatureUtil.getParamSpec(sigAlgName, paramBytes));
+ } catch (ProviderException e) {
+ throw new CRLException(e.getMessage(), e.getCause());
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new CRLException(e);
+ }
+
+ byte[] tbsCRL = getTBSCertList();
+ sig.update(tbsCRL, 0, tbsCRL.length);
+
+ if (sig.verify(getSignature()) == false) {
+ throw new SignatureException("Signature does not match.");
+ }
}
/**
diff --git a/jdk/src/share/classes/java/security/cert/X509CRLSelector.java b/jdk/src/share/classes/java/security/cert/X509CRLSelector.java
index face5ff..cf2e6b4 100644
--- a/jdk/src/share/classes/java/security/cert/X509CRLSelector.java
+++ b/jdk/src/share/classes/java/security/cert/X509CRLSelector.java
@@ -52,7 +52,7 @@
* {@link CertStore#getCRLs CertStore.getCRLs} or some similar
* method.
* <p>
- * Please refer to <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
+ * Please refer to <a href="http://tools.ietf.org/html/rfc5280">RFC 5280:
* Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a>
* for definitions of the X.509 CRL fields and extensions mentioned below.
* <p>
diff --git a/jdk/src/share/classes/java/security/cert/X509CertSelector.java b/jdk/src/share/classes/java/security/cert/X509CertSelector.java
index 0fe97a6..905e454 100644
--- a/jdk/src/share/classes/java/security/cert/X509CertSelector.java
+++ b/jdk/src/share/classes/java/security/cert/X509CertSelector.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2014, 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
@@ -65,7 +65,7 @@
* number. Other unique combinations include the issuer, subject,
* subjectKeyIdentifier and/or the subjectPublicKey criteria.
* <p>
- * Please refer to <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
+ * Please refer to <a href="http://tools.ietf.org/html/rfc5280">RFC 5280:
* Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a> for
* definitions of the X.509 certificate extensions mentioned below.
* <p>
@@ -728,7 +728,7 @@
* The name is provided in string format.
* <a href="http://www.ietf.org/rfc/rfc822.txt">RFC 822</a>, DNS, and URI
* names use the well-established string formats for those types (subject to
- * the restrictions included in RFC 3280). IPv4 address names are
+ * the restrictions included in RFC 5280). IPv4 address names are
* supplied using dotted quad notation. OID address names are represented
* as a series of nonnegative integers separated by periods. And
* directory names (distinguished names) are supplied in RFC 2253 format.
@@ -746,7 +746,7 @@
* String form of some distinguished names.
*
* @param type the name type (0-8, as specified in
- * RFC 3280, section 4.2.1.7)
+ * RFC 5280, section 4.2.1.6)
* @param name the name in string form (not {@code null})
* @throws IOException if a parsing error occurs
*/
@@ -770,7 +770,7 @@
* <p>
* The name is provided as a byte array. This byte array should contain
* the DER encoded name, as it would appear in the GeneralName structure
- * defined in RFC 3280 and X.509. The encoded byte array should only contain
+ * defined in RFC 5280 and X.509. The encoded byte array should only contain
* the encoded value of the name, and should not include the tag associated
* with the name in the GeneralName structure. The ASN.1 definition of this
* structure appears below.
@@ -806,7 +806,7 @@
* must contain the specified subjectAlternativeName.
*
* @param type the name type (0-8, as specified in
- * RFC 3280, section 4.2.1.7)
+ * RFC 5280, section 4.2.1.6)
* @param name the name in string or byte array form
* @throws IOException if a parsing error occurs
*/
@@ -995,7 +995,7 @@
* <p>
* The name constraints are specified as a byte array. This byte array
* should contain the DER encoded form of the name constraints, as they
- * would appear in the NameConstraints structure defined in RFC 3280
+ * would appear in the NameConstraints structure defined in RFC 5280
* and X.509. The ASN.1 definition of this structure appears below.
*
* <pre>{@code
@@ -1197,7 +1197,7 @@
* <p>
* The name is provided in string format. RFC 822, DNS, and URI names
* use the well-established string formats for those types (subject to
- * the restrictions included in RFC 3280). IPv4 address names are
+ * the restrictions included in RFC 5280). IPv4 address names are
* supplied using dotted quad notation. OID address names are represented
* as a series of nonnegative integers separated by periods. And
* directory names (distinguished names) are supplied in RFC 2253 format.
@@ -1214,7 +1214,7 @@
* String form of some distinguished names.
*
* @param type the name type (0-8, as specified in
- * RFC 3280, section 4.2.1.7)
+ * RFC 5280, section 4.2.1.6)
* @param name the name in string form
* @throws IOException if a parsing error occurs
*/
@@ -1234,7 +1234,7 @@
* <p>
* The name is provided as a byte array. This byte array should contain
* the DER encoded name, as it would appear in the GeneralName structure
- * defined in RFC 3280 and X.509. The ASN.1 definition of this structure
+ * defined in RFC 5280 and X.509. The ASN.1 definition of this structure
* appears in the documentation for
* {@link #addSubjectAlternativeName(int type, byte [] name)
* addSubjectAlternativeName(int type, byte [] name)}.
@@ -1243,7 +1243,7 @@
* subsequent modifications.
*
* @param type the name type (0-8, as specified in
- * RFC 3280, section 4.2.1.7)
+ * RFC 5280, section 4.2.1.6)
* @param name a byte array containing the name in ASN.1 DER encoded form
* @throws IOException if a parsing error occurs
*/
@@ -1258,7 +1258,7 @@
* the specified pathToName.
*
* @param type the name type (0-8, as specified in
- * RFC 3280, section 4.2.1.7)
+ * RFC 5280, section 4.2.1.6)
* @param name the name in string or byte array form
* @throws IOException if an encoding error occurs (incorrect form for DN)
*/
@@ -1715,7 +1715,7 @@
* <p>
* The name constraints are returned as a byte array. This byte array
* contains the DER encoded form of the name constraints, as they
- * would appear in the NameConstraints structure defined in RFC 3280
+ * would appear in the NameConstraints structure defined in RFC 5280
* and X.509. The ASN.1 notation for this structure is supplied in the
* documentation for
* {@link #setNameConstraints(byte [] bytes) setNameConstraints(byte [] bytes)}.
diff --git a/jdk/src/share/classes/java/security/cert/X509Certificate.java b/jdk/src/share/classes/java/security/cert/X509Certificate.java
index 0aba5da..b13866a 100644
--- a/jdk/src/share/classes/java/security/cert/X509Certificate.java
+++ b/jdk/src/share/classes/java/security/cert/X509Certificate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,12 +27,14 @@
import java.math.BigInteger;
import java.security.*;
+import java.security.spec.*;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.security.auth.x500.X500Principal;
import sun.security.x509.X509CertImpl;
+import sun.security.util.SignatureUtil;
/**
* <p>
@@ -63,7 +65,7 @@
* CA such as a "root" CA.
* <p>
* More information can be found in
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
+ * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280: Internet X.509
* Public Key Infrastructure Certificate and CRL Profile</a>.
* <p>
* The ASN.1 definition of {@code tbsCertificate} is:
@@ -408,7 +410,7 @@
* Gets the {@code issuerUniqueID} value from the certificate.
* The issuer unique identifier is present in the certificate
* to handle the possibility of reuse of issuer names over time.
- * RFC 3280 recommends that names not be reused and that
+ * RFC 5280 recommends that names not be reused and that
* conforming certificates not make use of unique identifiers.
* Applications conforming to that profile should be capable of
* parsing unique identifiers and making comparisons.
@@ -459,7 +461,7 @@
* encipherOnly (7),
* decipherOnly (8) }
* </pre>
- * RFC 3280 recommends that when used, this be marked
+ * RFC 5280 recommends that when used, this be marked
* as a critical extension.
*
* @return the KeyUsage extension of this certificate, represented as
@@ -572,7 +574,7 @@
* <a href="http://www.ietf.org/rfc/rfc822.txt">RFC 822</a>, DNS, and URI
* names are returned as {@code String}s,
* using the well-established string formats for those types (subject to
- * the restrictions included in RFC 3280). IPv4 address names are
+ * the restrictions included in RFC 5280). IPv4 address names are
* returned using dotted quad notation. IPv6 address names are returned
* in the form "a1:a2:...:a8", where a1-a8 are hexadecimal values
* representing the eight 16-bit pieces of the address. OID names are
@@ -647,7 +649,7 @@
return X509CertImpl.getIssuerAlternativeNames(this);
}
- /**
+ /**
* Verifies that this certificate was signed using the
* private key that corresponds to the specified public key.
* This method uses the signature verification engine
@@ -673,6 +675,25 @@
public void verify(PublicKey key, Provider sigProvider)
throws CertificateException, NoSuchAlgorithmException,
InvalidKeyException, SignatureException {
- X509CertImpl.verify(this, key, sigProvider);
+ String sigName = getSigAlgName();
+ Signature sig = (sigProvider == null)
+ ? Signature.getInstance(sigName)
+ : Signature.getInstance(sigName, sigProvider);
+
+ try {
+ SignatureUtil.initVerifyWithParam(sig, key,
+ SignatureUtil.getParamSpec(sigName, getSigAlgParams()));
+ } catch (ProviderException e) {
+ throw new CertificateException(e.getMessage(), e.getCause());
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new CertificateException(e);
+ }
+
+ byte[] tbsCert = getTBSCertificate();
+ sig.update(tbsCert, 0, tbsCert.length);
+
+ if (sig.verify(getSignature()) == false) {
+ throw new SignatureException("Signature does not match.");
+ }
}
}
diff --git a/jdk/src/share/classes/java/security/interfaces/RSAKey.java b/jdk/src/share/classes/java/security/interfaces/RSAKey.java
index 67fbe2b..5703d66 100644
--- a/jdk/src/share/classes/java/security/interfaces/RSAKey.java
+++ b/jdk/src/share/classes/java/security/interfaces/RSAKey.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,12 @@
package java.security.interfaces;
import java.math.BigInteger;
+import java.security.spec.AlgorithmParameterSpec;
/**
- * The interface to an RSA public or private key.
+ * The interface to a public or private key in
+ * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard,
+ * such as those for RSA, or RSASSA-PSS algorithms.
*
* @author Jan Luehe
*
@@ -46,4 +49,20 @@
* @return the modulus
*/
public BigInteger getModulus();
+
+ /**
+ * Returns the parameters associated with this key.
+ * The parameters are optional and may be either
+ * explicitly specified or implicitly created during
+ * key pair generation.
+ *
+ * @implSpec
+ * The default implementation returns {@code null}.
+ *
+ * @return the associated parameters, may be null
+ * @since 8
+ */
+ default AlgorithmParameterSpec getParams() {
+ return null;
+ }
}
diff --git a/jdk/src/share/classes/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java b/jdk/src/share/classes/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java
index f85d96a..e9afe9c 100644
--- a/jdk/src/share/classes/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java
+++ b/jdk/src/share/classes/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,8 @@
/**
* The interface to an RSA multi-prime private key, as defined in the
- * PKCS#1 v2.1, using the <i>Chinese Remainder Theorem</i>
- * (CRT) information values.
+ * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard,
+ * using the <i>Chinese Remainder Theorem</i> (CRT) information values.
*
* @author Valerie Peng
*
diff --git a/jdk/src/share/classes/java/security/interfaces/RSAPrivateCrtKey.java b/jdk/src/share/classes/java/security/interfaces/RSAPrivateCrtKey.java
index 0408fea..4b391c0 100644
--- a/jdk/src/share/classes/java/security/interfaces/RSAPrivateCrtKey.java
+++ b/jdk/src/share/classes/java/security/interfaces/RSAPrivateCrtKey.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,8 @@
import java.math.BigInteger;
/**
- * The interface to an RSA private key, as defined in the PKCS#1 standard,
+ * The interface to an RSA private key, as defined in the
+ * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard,
* using the <i>Chinese Remainder Theorem</i> (CRT) information values.
*
* @author Jan Luehe
diff --git a/jdk/src/share/classes/java/security/interfaces/package-info.java b/jdk/src/share/classes/java/security/interfaces/package-info.java
index 54c9397..8082243 100644
--- a/jdk/src/share/classes/java/security/interfaces/package-info.java
+++ b/jdk/src/share/classes/java/security/interfaces/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,7 @@
* <h2>Package Specification</h2>
*
* <ul>
- * <li>PKCS #1: RSA Encryption Standard, Version 1.5, November 1993 </li>
+ * <li>PKCS #1: RSA Cryptography Specifications, Version 2.2 (RFC 8017)</li>
* <li>Federal Information Processing Standards Publication (FIPS PUB) 186:
* Digital Signature Standard (DSS) </li>
* </ul>
diff --git a/jdk/src/share/classes/java/security/spec/MGF1ParameterSpec.java b/jdk/src/share/classes/java/security/spec/MGF1ParameterSpec.java
index 1be267f..3821b84 100644
--- a/jdk/src/share/classes/java/security/spec/MGF1ParameterSpec.java
+++ b/jdk/src/share/classes/java/security/spec/MGF1ParameterSpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,23 +29,31 @@
/**
* This class specifies the set of parameters used with mask generation
- * function MGF1 in OAEP Padding and RSA-PSS signature scheme, as
+ * function MGF1 in OAEP Padding and RSASSA-PSS signature scheme, as
* defined in the
- * <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS #1 v2.1</a>
- * standard.
+ * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
*
* <p>Its ASN.1 definition in PKCS#1 standard is described below:
* <pre>
- * MGF1Parameters ::= OAEP-PSSDigestAlgorthms
+ * PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * { OID id-mgf1 PARAMETERS HashAlgorithm },
+ * ... -- Allows for future expansion --
+ * }
* </pre>
* where
* <pre>
+ * HashAlgorithm ::= AlgorithmIdentifier {
+ * {OAEP-PSSDigestAlgorithms}
+ * }
+ *
* OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
- * { OID id-sha1 PARAMETERS NULL }|
- * { OID id-sha224 PARAMETERS NULL }|
- * { OID id-sha256 PARAMETERS NULL }|
- * { OID id-sha384 PARAMETERS NULL }|
- * { OID id-sha512 PARAMETERS NULL },
+ * { OID id-sha1 PARAMETERS NULL }|
+ * { OID id-sha224 PARAMETERS NULL }|
+ * { OID id-sha256 PARAMETERS NULL }|
+ * { OID id-sha384 PARAMETERS NULL }|
+ * { OID id-sha512 PARAMETERS NULL }|
+ * { OID id-sha512-224 PARAMETERS NULL }|
+ * { OID id-sha512-256 PARAMETERS NULL },
* ... -- Allows for future expansion --
* }
* </pre>
@@ -59,31 +67,47 @@
public class MGF1ParameterSpec implements AlgorithmParameterSpec {
/**
- * The MGF1ParameterSpec which uses "SHA-1" message digest.
+ * The MGF1ParameterSpec which uses "SHA-1" message digest
*/
public static final MGF1ParameterSpec SHA1 =
new MGF1ParameterSpec("SHA-1");
+
/**
- * The MGF1ParameterSpec which uses "SHA-224" message digest.
+ * The MGF1ParameterSpec which uses "SHA-224" message digest
*/
public static final MGF1ParameterSpec SHA224 =
new MGF1ParameterSpec("SHA-224");
+
/**
- * The MGF1ParameterSpec which uses "SHA-256" message digest.
+ * The MGF1ParameterSpec which uses "SHA-256" message digest
*/
public static final MGF1ParameterSpec SHA256 =
new MGF1ParameterSpec("SHA-256");
+
/**
- * The MGF1ParameterSpec which uses "SHA-384" message digest.
+ * The MGF1ParameterSpec which uses "SHA-384" message digest
*/
public static final MGF1ParameterSpec SHA384 =
new MGF1ParameterSpec("SHA-384");
+
/**
- * The MGF1ParameterSpec which uses SHA-512 message digest.
+ * The MGF1ParameterSpec which uses SHA-512 message digest
*/
public static final MGF1ParameterSpec SHA512 =
new MGF1ParameterSpec("SHA-512");
+ /**
+ * The MGF1ParameterSpec which uses SHA-512/224 message digest
+ */
+ public static final MGF1ParameterSpec SHA512_224 =
+ new MGF1ParameterSpec("SHA-512/224");
+
+ /**
+ * The MGF1ParameterSpec which uses SHA-512/256 message digest
+ */
+ public static final MGF1ParameterSpec SHA512_256 =
+ new MGF1ParameterSpec("SHA-512/256");
+
private String mdName;
/**
diff --git a/jdk/src/share/classes/java/security/spec/PSSParameterSpec.java b/jdk/src/share/classes/java/security/spec/PSSParameterSpec.java
index a9b82d8..7e725d7 100644
--- a/jdk/src/share/classes/java/security/spec/PSSParameterSpec.java
+++ b/jdk/src/share/classes/java/security/spec/PSSParameterSpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,37 +25,42 @@
package java.security.spec;
-import java.math.BigInteger;
-import java.security.spec.MGF1ParameterSpec;
+import java.util.Objects;
/**
- * This class specifies a parameter spec for RSA-PSS signature scheme,
+ * This class specifies a parameter spec for RSASSA-PSS signature scheme,
* as defined in the
- * <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS#1 v2.1</a>
- * standard.
+ * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
*
* <p>Its ASN.1 definition in PKCS#1 standard is described below:
* <pre>
* RSASSA-PSS-params ::= SEQUENCE {
- * hashAlgorithm [0] OAEP-PSSDigestAlgorithms DEFAULT sha1,
- * maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1,
- * saltLength [2] INTEGER DEFAULT 20,
- * trailerField [3] INTEGER DEFAULT 1
+ * hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
+ * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
+ * saltLength [2] INTEGER DEFAULT 20,
+ * trailerField [3] TrailerField DEFAULT trailerFieldBC(1)
* }
* </pre>
* where
* <pre>
+ * HashAlgorithm ::= AlgorithmIdentifier {
+ * {OAEP-PSSDigestAlgorithms}
+ * }
+ * MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} }
+ * TrailerField ::= INTEGER { trailerFieldBC(1) }
+ *
* OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
- * { OID id-sha1 PARAMETERS NULL }|
- * { OID id-sha224 PARAMETERS NULL }|
- * { OID id-sha256 PARAMETERS NULL }|
- * { OID id-sha384 PARAMETERS NULL }|
- * { OID id-sha512 PARAMETERS NULL },
+ * { OID id-sha1 PARAMETERS NULL }|
+ * { OID id-sha224 PARAMETERS NULL }|
+ * { OID id-sha256 PARAMETERS NULL }|
+ * { OID id-sha384 PARAMETERS NULL }|
+ * { OID id-sha512 PARAMETERS NULL }|
+ * { OID id-sha512-224 PARAMETERS NULL }|
+ * { OID id-sha512-256 PARAMETERS NULL },
* ... -- Allows for future expansion --
* }
- *
* PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
- * { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
+ * { OID id-mgf1 PARAMETERS HashAlgorithm },
* ... -- Allows for future expansion --
* }
* </pre>
@@ -78,55 +83,62 @@
public class PSSParameterSpec implements AlgorithmParameterSpec {
- private String mdName = "SHA-1";
- private String mgfName = "MGF1";
- private AlgorithmParameterSpec mgfSpec = MGF1ParameterSpec.SHA1;
- private int saltLen = 20;
- private int trailerField = 1;
+ private final String mdName;
+
+ private final String mgfName;
+
+ private final AlgorithmParameterSpec mgfSpec;
+
+ private final int saltLen;
+
+ private final int trailerField;
/**
- * The PSS parameter set with all default values.
+ * The {@code TrailerFieldBC} constant as defined in PKCS#1
+ *
+ * @since 8
+ */
+ public static final int TRAILER_FIELD_BC = 1;
+
+ /**
+ * The PSS parameter set with all default values
+ *
* @since 1.5
*/
- public static final PSSParameterSpec DEFAULT = new PSSParameterSpec();
+ public static final PSSParameterSpec DEFAULT = new PSSParameterSpec
+ ("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 20, TRAILER_FIELD_BC);
- /**
- * Constructs a new {@code PSSParameterSpec} as defined in
- * the PKCS #1 standard using the default values.
- */
+
+ // disallowed
private PSSParameterSpec() {
+ throw new RuntimeException("default constructor not allowed");
}
+
/**
* Creates a new {@code PSSParameterSpec} as defined in
* the PKCS #1 standard using the specified message digest,
* mask generation function, parameters for mask generation
* function, salt length, and trailer field values.
*
- * @param mdName the algorithm name of the hash function.
- * @param mgfName the algorithm name of the mask generation
- * function.
- * @param mgfSpec the parameters for the mask generation
- * function. If null is specified, null will be returned by
- * getMGFParameters().
- * @param saltLen the length of salt.
- * @param trailerField the value of the trailer field.
- * @exception NullPointerException if {@code mdName},
- * or {@code mgfName} is null.
- * @exception IllegalArgumentException if {@code saltLen}
- * or {@code trailerField} is less than 0.
+ * @param mdName the algorithm name of the hash function
+ * @param mgfName the algorithm name of the mask generation function
+ * @param mgfSpec the parameters for the mask generation function.
+ * If null is specified, null will be returned by
+ * getMGFParameters().
+ * @param saltLen the length of salt
+ * @param trailerField the value of the trailer field
+ * @exception NullPointerException if {@code mdName}, or {@code mgfName}
+ * is null
+ * @exception IllegalArgumentException if {@code saltLen} or
+ * {@code trailerField} is less than 0
* @since 1.5
*/
public PSSParameterSpec(String mdName, String mgfName,
- AlgorithmParameterSpec mgfSpec,
- int saltLen, int trailerField) {
- if (mdName == null) {
- throw new NullPointerException("digest algorithm is null");
- }
- if (mgfName == null) {
- throw new NullPointerException("mask generation function " +
- "algorithm is null");
- }
+ AlgorithmParameterSpec mgfSpec, int saltLen, int trailerField) {
+ Objects.requireNonNull(mdName, "digest algorithm is null");
+ Objects.requireNonNull(mgfName,
+ "mask generation function algorithm is null");
if (saltLen < 0) {
throw new IllegalArgumentException("negative saltLen value: " +
saltLen);
@@ -147,23 +159,19 @@
* using the specified salt length and other default values as
* defined in PKCS#1.
*
- * @param saltLen the length of salt in bits to be used in PKCS#1
- * PSS encoding.
+ * @param saltLen the length of salt in bytes to be used in PKCS#1
+ * PSS encoding
* @exception IllegalArgumentException if {@code saltLen} is
- * less than 0.
+ * less than 0
*/
public PSSParameterSpec(int saltLen) {
- if (saltLen < 0) {
- throw new IllegalArgumentException("negative saltLen value: " +
- saltLen);
- }
- this.saltLen = saltLen;
+ this("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, saltLen, TRAILER_FIELD_BC);
}
/**
* Returns the message digest algorithm name.
*
- * @return the message digest algorithm name.
+ * @return the message digest algorithm name
* @since 1.5
*/
public String getDigestAlgorithm() {
@@ -173,7 +181,7 @@
/**
* Returns the mask generation function algorithm name.
*
- * @return the mask generation function algorithm name.
+ * @return the mask generation function algorithm name
*
* @since 1.5
*/
@@ -184,7 +192,7 @@
/**
* Returns the parameters for the mask generation function.
*
- * @return the parameters for the mask generation function.
+ * @return the parameters for the mask generation function
* @since 1.5
*/
public AlgorithmParameterSpec getMGFParameters() {
@@ -192,21 +200,31 @@
}
/**
- * Returns the salt length in bits.
+ * Returns the salt length in bytes.
*
- * @return the salt length.
+ * @return the salt length
*/
public int getSaltLength() {
return saltLen;
}
/**
- * Returns the value for the trailer field, i.e. bc in PKCS#1 v2.1.
+ * Returns the value for the trailer field.
*
- * @return the value for the trailer field, i.e. bc in PKCS#1 v2.1.
+ * @return the value for the trailer field
* @since 1.5
*/
public int getTrailerField() {
return trailerField;
}
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("MD: " + mdName + "\n")
+ .append("MGF: " + mgfSpec + "\n")
+ .append("SaltLength: " + saltLen + "\n")
+ .append("TrailerField: " + trailerField + "\n");
+ return sb.toString();
+ }
}
diff --git a/jdk/src/share/classes/java/security/spec/RSAKeyGenParameterSpec.java b/jdk/src/share/classes/java/security/spec/RSAKeyGenParameterSpec.java
index a73c6cd..014af6f 100644
--- a/jdk/src/share/classes/java/security/spec/RSAKeyGenParameterSpec.java
+++ b/jdk/src/share/classes/java/security/spec/RSAKeyGenParameterSpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,6 +43,7 @@
private int keysize;
private BigInteger publicExponent;
+ private AlgorithmParameterSpec keyParams;
/**
* The public-exponent value F0 = 3.
@@ -55,15 +56,30 @@
public static final BigInteger F4 = BigInteger.valueOf(65537);
/**
- * Constructs a new {@code RSAParameterSpec} object from the
- * given keysize and public-exponent value.
+ * Constructs a new {@code RSAKeyGenParameterSpec} object from the
+ * given keysize, public-exponent value, and null key parameters.
*
* @param keysize the modulus size (specified in number of bits)
* @param publicExponent the public exponent
*/
public RSAKeyGenParameterSpec(int keysize, BigInteger publicExponent) {
+ this(keysize, publicExponent, null);
+ }
+
+ /**
+ * Constructs a new {@code RSAKeyGenParameterSpec} object from the
+ * given keysize, public-exponent value, and key parameters.
+ *
+ * @param keysize the modulus size (specified in number of bits)
+ * @param publicExponent the public exponent
+ * @param keyParams the key parameters, may be null
+ * @since 8
+ */
+ public RSAKeyGenParameterSpec(int keysize, BigInteger publicExponent,
+ AlgorithmParameterSpec keyParams) {
this.keysize = keysize;
this.publicExponent = publicExponent;
+ this.keyParams = keyParams;
}
/**
@@ -83,4 +99,15 @@
public BigInteger getPublicExponent() {
return publicExponent;
}
+
+ /**
+ * Returns the parameters to be associated with key.
+ *
+ * @return the associated parameters, may be null if
+ * not present
+ * @since 8
+ */
+ public AlgorithmParameterSpec getKeyParams() {
+ return keyParams;
+ }
}
diff --git a/jdk/src/share/classes/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java b/jdk/src/share/classes/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java
index a198e43..f7bd883 100644
--- a/jdk/src/share/classes/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java
+++ b/jdk/src/share/classes/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,11 +26,13 @@
package java.security.spec;
import java.math.BigInteger;
+import java.util.Objects;
/**
* This class specifies an RSA multi-prime private key, as defined in the
- * PKCS#1 v2.1, using the Chinese Remainder Theorem (CRT) information
- * values for efficiency.
+ * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard
+ * using the Chinese Remainder Theorem (CRT) information values
+ * for efficiency.
*
* @author Valerie Peng
*
@@ -57,34 +59,28 @@
private final RSAOtherPrimeInfo otherPrimeInfo[];
/**
- * Creates a new {@code RSAMultiPrimePrivateCrtKeySpec}
- * given the modulus, publicExponent, privateExponent,
- * primeP, primeQ, primeExponentP, primeExponentQ,
- * crtCoefficient, and otherPrimeInfo as defined in PKCS#1 v2.1.
+ * Creates a new {@code RSAMultiPrimePrivateCrtKeySpec}.
*
* <p>Note that the contents of {@code otherPrimeInfo}
* are copied to protect against subsequent modification when
* constructing this object.
*
- * @param modulus the modulus n.
- * @param publicExponent the public exponent e.
- * @param privateExponent the private exponent d.
- * @param primeP the prime factor p of n.
- * @param primeQ the prime factor q of n.
- * @param primeExponentP this is d mod (p-1).
- * @param primeExponentQ this is d mod (q-1).
- * @param crtCoefficient the Chinese Remainder Theorem
- * coefficient q-1 mod p.
- * @param otherPrimeInfo triplets of the rest of primes, null can be
- * specified if there are only two prime factors (p and q).
- * @exception NullPointerException if any of the parameters, i.e.
- * {@code modulus},
- * {@code publicExponent}, {@code privateExponent},
- * {@code primeP}, {@code primeQ},
- * {@code primeExponentP}, {@code primeExponentQ},
- * {@code crtCoefficient}, is null.
- * @exception IllegalArgumentException if an empty, i.e. 0-length,
- * {@code otherPrimeInfo} is specified.
+ * @param modulus the modulus n
+ * @param publicExponent the public exponent e
+ * @param privateExponent the private exponent d
+ * @param primeP the prime factor p of n
+ * @param primeQ the prime factor q of n
+ * @param primeExponentP this is d mod (p-1)
+ * @param primeExponentQ this is d mod (q-1)
+ * @param crtCoefficient the Chinese Remainder Theorem
+ * coefficient q-1 mod p
+ * @param otherPrimeInfo triplets of the rest of primes, null can be
+ * specified if there are only two prime factors
+ * (p and q)
+ * @throws NullPointerException if any of the specified parameters
+ * with the exception of {@code otherPrimeInfo} is null
+ * @throws IllegalArgumentException if an empty, i.e. 0-length,
+ * {@code otherPrimeInfo} is specified
*/
public RSAMultiPrimePrivateCrtKeySpec(BigInteger modulus,
BigInteger publicExponent,
@@ -95,45 +91,67 @@
BigInteger primeExponentQ,
BigInteger crtCoefficient,
RSAOtherPrimeInfo[] otherPrimeInfo) {
- super(modulus, privateExponent);
- if (modulus == null) {
- throw new NullPointerException("the modulus parameter must be " +
- "non-null");
- }
- if (publicExponent == null) {
- throw new NullPointerException("the publicExponent parameter " +
- "must be non-null");
- }
- if (privateExponent == null) {
- throw new NullPointerException("the privateExponent parameter " +
- "must be non-null");
- }
- if (primeP == null) {
- throw new NullPointerException("the primeP parameter " +
- "must be non-null");
- }
- if (primeQ == null) {
- throw new NullPointerException("the primeQ parameter " +
- "must be non-null");
- }
- if (primeExponentP == null) {
- throw new NullPointerException("the primeExponentP parameter " +
- "must be non-null");
- }
- if (primeExponentQ == null) {
- throw new NullPointerException("the primeExponentQ parameter " +
- "must be non-null");
- }
- if (crtCoefficient == null) {
- throw new NullPointerException("the crtCoefficient parameter " +
- "must be non-null");
- }
- this.publicExponent = publicExponent;
- this.primeP = primeP;
- this.primeQ = primeQ;
- this.primeExponentP = primeExponentP;
- this.primeExponentQ = primeExponentQ;
- this.crtCoefficient = crtCoefficient;
+ this(modulus, publicExponent, privateExponent, primeP, primeQ,
+ primeExponentP, primeExponentQ, crtCoefficient, otherPrimeInfo,
+ null);
+ }
+
+ /**
+ * Creates a new {@code RSAMultiPrimePrivateCrtKeySpec} with additional
+ * key parameters.
+ *
+ * <p>Note that the contents of {@code otherPrimeInfo}
+ * are copied to protect against subsequent modification when
+ * constructing this object.
+ *
+ * @param modulus the modulus n
+ * @param publicExponent the public exponent e
+ * @param privateExponent the private exponent d
+ * @param primeP the prime factor p of n
+ * @param primeQ the prime factor q of n
+ * @param primeExponentP this is d mod (p-1)
+ * @param primeExponentQ this is d mod (q-1)
+ * @param crtCoefficient the Chinese Remainder Theorem coefficient
+ * q-1 mod p
+ * @param otherPrimeInfo triplets of the rest of primes, null can be
+ * specified if there are only two prime factors
+ * (p and q)
+ * @param keyParams the parameters associated with key
+ * @throws NullPointerException if any of the specified parameters
+ * with the exception of {@code otherPrimeInfo} and {@code keyParams}
+ * is null
+ * @throws IllegalArgumentException if an empty, i.e. 0-length,
+ * {@code otherPrimeInfo} is specified
+ * @since 8
+ */
+ public RSAMultiPrimePrivateCrtKeySpec(BigInteger modulus,
+ BigInteger publicExponent,
+ BigInteger privateExponent,
+ BigInteger primeP,
+ BigInteger primeQ,
+ BigInteger primeExponentP,
+ BigInteger primeExponentQ,
+ BigInteger crtCoefficient,
+ RSAOtherPrimeInfo[] otherPrimeInfo,
+ AlgorithmParameterSpec keyParams) {
+ super(modulus, privateExponent, keyParams);
+ Objects.requireNonNull(modulus,
+ "the modulus parameter must be non-null");
+ Objects.requireNonNull(privateExponent,
+ "the privateExponent parameter must be non-null");
+ this.publicExponent = Objects.requireNonNull(publicExponent,
+ "the publicExponent parameter must be non-null");
+ this.primeP = Objects.requireNonNull(primeP,
+ "the primeP parameter must be non-null");
+ this.primeQ = Objects.requireNonNull(primeQ,
+ "the primeQ parameter must be non-null");
+ this.primeExponentP = Objects.requireNonNull(primeExponentP,
+ "the primeExponentP parameter must be non-null");
+ this.primeExponentQ = Objects.requireNonNull(primeExponentQ,
+ "the primeExponentQ parameter must be non-null");
+ this.crtCoefficient = Objects.requireNonNull(crtCoefficient,
+ "the crtCoefficient parameter must be non-null");
+
if (otherPrimeInfo == null) {
this.otherPrimeInfo = null;
} else if (otherPrimeInfo.length == 0) {
@@ -202,8 +220,8 @@
* Returns a copy of the otherPrimeInfo or null if there are
* only two prime factors (p and q).
*
- * @return the otherPrimeInfo. Returns a new array each
- * time this method is called.
+ * @return the otherPrimeInfo. Returns a new array each time this method
+ * is called.
*/
public RSAOtherPrimeInfo[] getOtherPrimeInfo() {
if (otherPrimeInfo == null) return null;
diff --git a/jdk/src/share/classes/java/security/spec/RSAOtherPrimeInfo.java b/jdk/src/share/classes/java/security/spec/RSAOtherPrimeInfo.java
index 10d8471..99b83a8 100644
--- a/jdk/src/share/classes/java/security/spec/RSAOtherPrimeInfo.java
+++ b/jdk/src/share/classes/java/security/spec/RSAOtherPrimeInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,15 +29,16 @@
/**
* This class represents the triplet (prime, exponent, and coefficient)
- * inside RSA's OtherPrimeInfo structure, as defined in the PKCS#1 v2.1.
+ * inside RSA's OtherPrimeInfo structure, as defined in the
+ * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
* The ASN.1 syntax of RSA's OtherPrimeInfo is as follows:
*
* <pre>
* OtherPrimeInfo ::= SEQUENCE {
- * prime INTEGER,
- * exponent INTEGER,
- * coefficient INTEGER
- * }
+ * prime INTEGER,
+ * exponent INTEGER,
+ * coefficient INTEGER
+ * }
*
* </pre>
*
diff --git a/jdk/src/share/classes/java/security/spec/RSAPrivateCrtKeySpec.java b/jdk/src/share/classes/java/security/spec/RSAPrivateCrtKeySpec.java
index d0ba70b..f4d618b 100644
--- a/jdk/src/share/classes/java/security/spec/RSAPrivateCrtKeySpec.java
+++ b/jdk/src/share/classes/java/security/spec/RSAPrivateCrtKeySpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,9 +28,9 @@
import java.math.BigInteger;
/**
- * This class specifies an RSA private key, as defined in the PKCS#1
- * standard, using the Chinese Remainder Theorem (CRT) information values for
- * efficiency.
+ * This class specifies an RSA private key, as defined in the
+ * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard,
+ * using the Chinese Remainder Theorem (CRT) information values for efficiency.
*
* @author Jan Luehe
*
@@ -52,13 +52,8 @@
private final BigInteger primeExponentQ;
private final BigInteger crtCoefficient;
-
-
/**
- * Creates a new {@code RSAPrivateCrtKeySpec}
- * given the modulus, publicExponent, privateExponent,
- * primeP, primeQ, primeExponentP, primeExponentQ, and
- * crtCoefficient as defined in PKCS#1.
+ * Creates a new {@code RSAPrivateCrtKeySpec}.
*
* @param modulus the modulus n
* @param publicExponent the public exponent e
@@ -78,7 +73,36 @@
BigInteger primeExponentP,
BigInteger primeExponentQ,
BigInteger crtCoefficient) {
- super(modulus, privateExponent);
+ this(modulus, publicExponent, privateExponent, primeP, primeQ,
+ primeExponentP, primeExponentQ, crtCoefficient, null);
+ }
+
+ /**
+ * Creates a new {@code RSAPrivateCrtKeySpec} with additional
+ * key parameters.
+ *
+ * @param modulus the modulus n
+ * @param publicExponent the public exponent e
+ * @param privateExponent the private exponent d
+ * @param primeP the prime factor p of n
+ * @param primeQ the prime factor q of n
+ * @param primeExponentP this is d mod (p-1)
+ * @param primeExponentQ this is d mod (q-1)
+ * @param crtCoefficient the Chinese Remainder Theorem
+ * coefficient q-1 mod p
+ * @param keyParams the parameters associated with key
+ * @since 8
+ */
+ public RSAPrivateCrtKeySpec(BigInteger modulus,
+ BigInteger publicExponent,
+ BigInteger privateExponent,
+ BigInteger primeP,
+ BigInteger primeQ,
+ BigInteger primeExponentP,
+ BigInteger primeExponentQ,
+ BigInteger crtCoefficient,
+ AlgorithmParameterSpec keyParams) {
+ super(modulus, privateExponent, keyParams);
this.publicExponent = publicExponent;
this.primeP = primeP;
this.primeQ = primeQ;
diff --git a/jdk/src/share/classes/java/security/spec/RSAPrivateKeySpec.java b/jdk/src/share/classes/java/security/spec/RSAPrivateKeySpec.java
index e749146..2bb06c5 100644
--- a/jdk/src/share/classes/java/security/spec/RSAPrivateKeySpec.java
+++ b/jdk/src/share/classes/java/security/spec/RSAPrivateKeySpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,8 +43,9 @@
public class RSAPrivateKeySpec implements KeySpec {
- private BigInteger modulus;
- private BigInteger privateExponent;
+ private final BigInteger modulus;
+ private final BigInteger privateExponent;
+ private final AlgorithmParameterSpec params;
/**
* Creates a new RSAPrivateKeySpec.
@@ -53,8 +54,22 @@
* @param privateExponent the private exponent
*/
public RSAPrivateKeySpec(BigInteger modulus, BigInteger privateExponent) {
+ this(modulus, privateExponent, null);
+ }
+
+ /**
+ * Creates a new RSAPrivateKeySpec with additional key parameters.
+ *
+ * @param modulus the modulus
+ * @param privateExponent the private exponent
+ * @param params the parameters associated with this key, may be null
+ * @since 8
+ */
+ public RSAPrivateKeySpec(BigInteger modulus, BigInteger privateExponent,
+ AlgorithmParameterSpec params) {
this.modulus = modulus;
this.privateExponent = privateExponent;
+ this.params = params;
}
/**
@@ -74,4 +89,15 @@
public BigInteger getPrivateExponent() {
return this.privateExponent;
}
+
+ /**
+ * Returns the parameters associated with this key, may be null if not
+ * present.
+ *
+ * @return the parameters associated with this key
+ * @since 8
+ */
+ public AlgorithmParameterSpec getParams() {
+ return this.params;
+ }
}
diff --git a/jdk/src/share/classes/java/security/spec/RSAPublicKeySpec.java b/jdk/src/share/classes/java/security/spec/RSAPublicKeySpec.java
index 9a944f9..b9ab224 100644
--- a/jdk/src/share/classes/java/security/spec/RSAPublicKeySpec.java
+++ b/jdk/src/share/classes/java/security/spec/RSAPublicKeySpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,8 +43,9 @@
public class RSAPublicKeySpec implements KeySpec {
- private BigInteger modulus;
- private BigInteger publicExponent;
+ private final BigInteger modulus;
+ private final BigInteger publicExponent;
+ private final AlgorithmParameterSpec params;
/**
* Creates a new RSAPublicKeySpec.
@@ -53,10 +54,25 @@
* @param publicExponent the public exponent
*/
public RSAPublicKeySpec(BigInteger modulus, BigInteger publicExponent) {
+ this(modulus, publicExponent, null);
+ }
+
+ /**
+ * Creates a new RSAPublicKeySpec with additional key parameters.
+ *
+ * @param modulus the modulus
+ * @param publicExponent the public exponent
+ * @param params the parameters associated with this key, may be null
+ * @since 8
+ */
+ public RSAPublicKeySpec(BigInteger modulus, BigInteger publicExponent,
+ AlgorithmParameterSpec params) {
this.modulus = modulus;
this.publicExponent = publicExponent;
+ this.params = params;
}
+
/**
* Returns the modulus.
*
@@ -74,4 +90,16 @@
public BigInteger getPublicExponent() {
return this.publicExponent;
}
+
+ /**
+ * Returns the parameters associated with this key, may be null if not
+ * present.
+ *
+ * @return the parameters associated with this key
+ * @since 8
+ */
+ public AlgorithmParameterSpec getParams() {
+ return this.params;
+ }
+
}
diff --git a/jdk/src/share/classes/java/security/spec/package-info.java b/jdk/src/share/classes/java/security/spec/package-info.java
index cb39308..ed99a20 100644
--- a/jdk/src/share/classes/java/security/spec/package-info.java
+++ b/jdk/src/share/classes/java/security/spec/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,7 @@
* <h2>Package Specification</h2>
*
* <ul>
- * <li>PKCS #1: RSA Encryption Standard, Version 1.5, November 1993</li>
+ * <li>PKCS #1: RSA Cryptography Specifications, Version 2.2 (RFC 8017)</li>
* <li>PKCS #8: Private-Key Information Syntax Standard,
* Version 1.2, November 1993</li>
* <li>Federal Information Processing Standards Publication (FIPS PUB) 186:
diff --git a/jdk/src/share/classes/java/util/jar/JarFile.java b/jdk/src/share/classes/java/util/jar/JarFile.java
index 940dfb6..dd6d1a4 100644
--- a/jdk/src/share/classes/java/util/jar/JarFile.java
+++ b/jdk/src/share/classes/java/util/jar/JarFile.java
@@ -422,7 +422,12 @@
*/
private byte[] getBytes(ZipEntry ze) throws IOException {
try (InputStream is = super.getInputStream(ze)) {
- return IOUtils.readFully(is, (int)ze.getSize(), true);
+ int len = (int)ze.getSize();
+ byte[] b = IOUtils.readAllBytes(is);
+ if (len != -1 && b.length != len)
+ throw new EOFException("Expected:" + len + ", read:" + b.length);
+
+ return b;
}
}
diff --git a/jdk/src/share/classes/javax/crypto/Cipher.java b/jdk/src/share/classes/javax/crypto/Cipher.java
index b18ce92..d3d09d7 100644
--- a/jdk/src/share/classes/javax/crypto/Cipher.java
+++ b/jdk/src/share/classes/javax/crypto/Cipher.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -317,11 +317,15 @@
while (parser.hasMoreTokens() && count < 3) {
parts[count++] = parser.nextToken().trim();
}
- if (count == 0 || count == 2 || parser.hasMoreTokens()) {
+ if (count == 0 || count == 2) {
throw new NoSuchAlgorithmException("Invalid transformation"
+ " format:" +
transformation);
}
+ // treats all subsequent tokens as part of padding
+ if (count == 3 && parser.hasMoreTokens()) {
+ parts[2] = parts[2] + parser.nextToken("\r\n");
+ }
} catch (NoSuchElementException e) {
throw new NoSuchAlgorithmException("Invalid transformation " +
"format:" + transformation);
diff --git a/jdk/src/share/classes/javax/crypto/spec/OAEPParameterSpec.java b/jdk/src/share/classes/javax/crypto/spec/OAEPParameterSpec.java
index fcdc018..0b90452 100644
--- a/jdk/src/share/classes/javax/crypto/spec/OAEPParameterSpec.java
+++ b/jdk/src/share/classes/javax/crypto/spec/OAEPParameterSpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,40 +32,53 @@
/**
* This class specifies the set of parameters used with OAEP Padding,
* as defined in the
- * <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS #1</a>
- * standard.
+ * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
*
* Its ASN.1 definition in PKCS#1 standard is described below:
* <pre>
* RSAES-OAEP-params ::= SEQUENCE {
- * hashAlgorithm [0] OAEP-PSSDigestAlgorithms DEFAULT sha1,
- * maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1,
- * pSourceAlgorithm [2] PKCS1PSourceAlgorithms DEFAULT pSpecifiedEmpty
+ * hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
+ * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
+ * pSourceAlgorithm [2] PSourceAlgorithm DEFAULT pSpecifiedEmpty
* }
* </pre>
* where
* <pre>
+ * HashAlgorithm ::= AlgorithmIdentifier {
+ * {OAEP-PSSDigestAlgorithms}
+ * }
+ * MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} }
+ * PSourceAlgorithm ::= AlgorithmIdentifier {
+ * {PKCS1PSourceAlgorithms}
+ * }
+ *
* OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
- * { OID id-sha1 PARAMETERS NULL }|
- * { OID id-sha256 PARAMETERS NULL }|
- * { OID id-sha384 PARAMETERS NULL }|
- * { OID id-sha512 PARAMETERS NULL },
+ * { OID id-sha1 PARAMETERS NULL }|
+ * { OID id-sha224 PARAMETERS NULL }|
+ * { OID id-sha256 PARAMETERS NULL }|
+ * { OID id-sha384 PARAMETERS NULL }|
+ * { OID id-sha512 PARAMETERS NULL }|
+ * { OID id-sha512-224 PARAMETERS NULL }|
+ * { OID id-sha512-256 PARAMETERS NULL },
* ... -- Allows for future expansion --
* }
* PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
- * { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
+ * { OID id-mgf1 PARAMETERS HashAlgorithm },
* ... -- Allows for future expansion --
* }
* PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
- * { OID id-pSpecified PARAMETERS OCTET STRING },
+ * { OID id-pSpecified PARAMETERS EncodingParameters },
* ... -- Allows for future expansion --
* }
+ * EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
* </pre>
* <p>Note: the OAEPParameterSpec.DEFAULT uses the following:
+ * <pre>
* message digest -- "SHA-1"
* mask generation function (mgf) -- "MGF1"
* parameters for mgf -- MGF1ParameterSpec.SHA1
* source of encoding input -- PSource.PSpecified.DEFAULT
+ * </pre>
*
* @see java.security.spec.MGF1ParameterSpec
* @see PSource
diff --git a/jdk/src/share/classes/javax/crypto/spec/PSource.java b/jdk/src/share/classes/javax/crypto/spec/PSource.java
index a3d2efe..0e5a6c8 100644
--- a/jdk/src/share/classes/javax/crypto/spec/PSource.java
+++ b/jdk/src/share/classes/javax/crypto/spec/PSource.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,13 +28,19 @@
/**
* This class specifies the source for encoding input P in OAEP Padding,
* as defined in the
- * <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS #1</a>
- * standard.
+ * <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
+ * <pre>
+ * PSourceAlgorithm ::= AlgorithmIdentifier {
+ * {PKCS1PSourceAlgorithms}
+ * }
+ * </pre>
+ * where
* <pre>
* PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
- * { OID id-pSpecified PARAMETERS OCTET STRING },
+ * { OID id-pSpecified PARAMETERS EncodingParameters },
* ... -- Allows for future expansion --
* }
+ * EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
* </pre>
* @author Valerie Peng
*
diff --git a/jdk/src/share/classes/javax/crypto/spec/package.html b/jdk/src/share/classes/javax/crypto/spec/package.html
index b8fd807..fd4bac4 100644
--- a/jdk/src/share/classes/javax/crypto/spec/package.html
+++ b/jdk/src/share/classes/javax/crypto/spec/package.html
@@ -1,5 +1,5 @@
<!--
-Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,7 @@
<h2>Package Specification</h2>
<ul>
+ <li>PKCS #1: RSA Cryptography Specifications, Version 2.2 (RFC 8017)</li>
<li>PKCS #3: Diffie-Hellman Key-Agreement Standard, Version 1.4,
November 1993.</li>
<li>PKCS #5: Password-Based Encryption Standard, Version 1.5,
diff --git a/jdk/src/share/classes/javax/net/ssl/SSLEngine.java b/jdk/src/share/classes/javax/net/ssl/SSLEngine.java
index 6411088..c7ae043 100644
--- a/jdk/src/share/classes/javax/net/ssl/SSLEngine.java
+++ b/jdk/src/share/classes/javax/net/ssl/SSLEngine.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,8 @@
import java.nio.ByteBuffer;
import java.nio.ReadOnlyBufferException;
+import java.util.List;
+import java.util.function.BiFunction;
/**
@@ -1253,4 +1255,142 @@
}
}
+ /**
+ * Returns the most recent application protocol value negotiated for this
+ * connection.
+ * <p>
+ * If supported by the underlying SSL/TLS/DTLS implementation,
+ * application name negotiation mechanisms such as <a
+ * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 </a>, the
+ * Application-Layer Protocol Negotiation (ALPN), can negotiate
+ * application-level values between peers.
+ *
+ * @implSpec
+ * The implementation in this class throws
+ * {@code UnsupportedOperationException} and performs no other action.
+ *
+ * @return null if it has not yet been determined if application
+ * protocols might be used for this connection, an empty
+ * {@code String} if application protocols values will not
+ * be used, or a non-empty application protocol {@code String}
+ * if a value was successfully negotiated.
+ * @throws UnsupportedOperationException if the underlying provider
+ * does not implement the operation.
+ * @since 8
+ */
+ public String getApplicationProtocol() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the application protocol value negotiated on a SSL/TLS
+ * handshake currently in progress.
+ * <p>
+ * Like {@link #getHandshakeSession()},
+ * a connection may be in the middle of a handshake. The
+ * application protocol may or may not yet be available.
+ *
+ * @implSpec
+ * The implementation in this class throws
+ * {@code UnsupportedOperationException} and performs no other action.
+ *
+ * @return null if it has not yet been determined if application
+ * protocols might be used for this handshake, an empty
+ * {@code String} if application protocols values will not
+ * be used, or a non-empty application protocol {@code String}
+ * if a value was successfully negotiated.
+ * @throws UnsupportedOperationException if the underlying provider
+ * does not implement the operation.
+ * @since 8
+ */
+ public String getHandshakeApplicationProtocol() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Registers a callback function that selects an application protocol
+ * value for a SSL/TLS/DTLS handshake.
+ * The function overrides any values supplied using
+ * {@link SSLParameters#setApplicationProtocols
+ * SSLParameters.setApplicationProtocols} and it supports the following
+ * type parameters:
+ * <blockquote>
+ * <dl>
+ * <dt> {@code SSLEngine}
+ * <dd> The function's first argument allows the current {@code SSLEngine}
+ * to be inspected, including the handshake session and configuration
+ * settings.
+ * <dt> {@code List<String>}
+ * <dd> The function's second argument lists the application protocol names
+ * advertised by the TLS peer.
+ * <dt> {@code String}
+ * <dd> The function's result is an application protocol name, or null to
+ * indicate that none of the advertised names are acceptable.
+ * If the return value is an empty {@code String} then application
+ * protocol indications will not be used.
+ * If the return value is null (no value chosen) or is a value that
+ * was not advertised by the peer, the underlying protocol will
+ * determine what action to take. (For example, ALPN will send a
+ * "no_application_protocol" alert and terminate the connection.)
+ * </dl>
+ * </blockquote>
+ *
+ * For example, the following call registers a callback function that
+ * examines the TLS handshake parameters and selects an application protocol
+ * name:
+ * <pre>{@code
+ * serverEngine.setHandshakeApplicationProtocolSelector(
+ * (serverEngine, clientProtocols) -> {
+ * SSLSession session = serverEngine.getHandshakeSession();
+ * return chooseApplicationProtocol(
+ * serverEngine,
+ * clientProtocols,
+ * session.getProtocol(),
+ * session.getCipherSuite());
+ * });
+ * }</pre>
+ *
+ * @apiNote
+ * This method should be called by TLS server applications before the TLS
+ * handshake begins. Also, this {@code SSLEngine} should be configured with
+ * parameters that are compatible with the application protocol selected by
+ * the callback function. For example, enabling a poor choice of cipher
+ * suites could result in no suitable application protocol.
+ * See {@link SSLParameters}.
+ *
+ * @implSpec
+ * The implementation in this class throws
+ * {@code UnsupportedOperationException} and performs no other action.
+ *
+ * @param selector the callback function, or null to disable the callback
+ * functionality.
+ * @throws UnsupportedOperationException if the underlying provider
+ * does not implement the operation.
+ * @since 8
+ */
+ public void setHandshakeApplicationProtocolSelector(
+ BiFunction<SSLEngine, List<String>, String> selector) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Retrieves the callback function that selects an application protocol
+ * value during a SSL/TLS/DTLS handshake.
+ * See {@link #setHandshakeApplicationProtocolSelector
+ * setHandshakeApplicationProtocolSelector}
+ * for the function's type parameters.
+ *
+ * @implSpec
+ * The implementation in this class throws
+ * {@code UnsupportedOperationException} and performs no other action.
+ *
+ * @return the callback function, or null if none has been set.
+ * @throws UnsupportedOperationException if the underlying provider
+ * does not implement the operation.
+ * @since 8
+ */
+ public BiFunction<SSLEngine, List<String>, String>
+ getHandshakeApplicationProtocolSelector() {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/jdk/src/share/classes/javax/net/ssl/SSLParameters.java b/jdk/src/share/classes/javax/net/ssl/SSLParameters.java
index 5e0d403..c3244c1 100644
--- a/jdk/src/share/classes/javax/net/ssl/SSLParameters.java
+++ b/jdk/src/share/classes/javax/net/ssl/SSLParameters.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -56,6 +56,17 @@
* {@link SSLSocket#setSSLParameters SSLSocket.setSSLParameters()} and
* {@link SSLServerSocket#setSSLParameters SSLServerSocket.setSSLParameters()}
* and {@link SSLEngine#setSSLParameters SSLEngine.setSSLParameters()}.
+ * <p>
+ * For example:
+ *
+ * <blockquote><pre>
+ * SSLParameters p = sslSocket.getSSLParameters();
+ * p.setProtocols(new String[] { "TLSv1.2" });
+ * p.setCipherSuites(
+ * new String[] { "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", ... });
+ * p.setApplicationProtocols(new String[] {"h2", "http/1.1"});
+ * sslSocket.setSSLParameters(p);
+ * </pre></blockquote>*
*
* @see SSLSocket
* @see SSLEngine
@@ -74,6 +85,7 @@
private Map<Integer, SNIServerName> sniNames = null;
private Map<Integer, SNIMatcher> sniMatchers = null;
private boolean preferLocalCipherSuites;
+ private String[] applicationProtocols = new String[0];
/**
* Constructs SSLParameters.
@@ -464,5 +476,74 @@
public final boolean getUseCipherSuitesOrder() {
return preferLocalCipherSuites;
}
-}
+ /**
+ * Returns a prioritized array of application-layer protocol names that
+ * can be negotiated over the SSL/TLS/DTLS protocols.
+ * <p>
+ * The array could be empty (zero-length), in which case protocol
+ * indications will not be used.
+ * <p>
+ * This method will return a new array each time it is invoked.
+ *
+ * @return a non-null, possibly zero-length array of application protocol
+ * {@code String}s. The array is ordered based on protocol
+ * preference, with {@code protocols[0]} being the most preferred.
+ * @see #setApplicationProtocols
+ * @since 8
+ */
+ public String[] getApplicationProtocols() {
+ return applicationProtocols.clone();
+ }
+
+ /**
+ * Sets the prioritized array of application-layer protocol names that
+ * can be negotiated over the SSL/TLS/DTLS protocols.
+ * <p>
+ * If application-layer protocols are supported by the underlying
+ * SSL/TLS implementation, this method configures which values can
+ * be negotiated by protocols such as <a
+ * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 </a>, the
+ * Application Layer Protocol Negotiation (ALPN).
+ * <p>
+ * If this end of the connection is expected to offer application protocol
+ * values, all protocols configured by this method will be sent to the
+ * peer.
+ * <p>
+ * If this end of the connection is expected to select the application
+ * protocol value, the {@code protocols} configured by this method are
+ * compared with those sent by the peer. The first matched value becomes
+ * the negotiated value. If none of the {@code protocols} were actually
+ * requested by the peer, the underlying protocol will determine what
+ * action to take. (For example, ALPN will send a
+ * {@code "no_application_protocol"} alert and terminate the connection.)
+ *
+ * @implSpec
+ * This method will make a copy of the {@code protocols} array.
+ *
+ * @param protocols an ordered array of application protocols,
+ * with {@code protocols[0]} being the most preferred.
+ * If the array is empty (zero-length), protocol
+ * indications will not be used.
+ * @throws IllegalArgumentException if protocols is null, or if
+ * any element in a non-empty array is null or an
+ * empty (zero-length) string
+ * @see #getApplicationProtocols
+ * @since 8
+ */
+ public void setApplicationProtocols(String[] protocols) {
+ if (protocols == null) {
+ throw new IllegalArgumentException("protocols was null");
+ }
+
+ String[] tempProtocols = protocols.clone();
+
+ for (String p : tempProtocols) {
+ if (p == null || p.equals("")) {
+ throw new IllegalArgumentException(
+ "An element of protocols was null/empty");
+ }
+ }
+ applicationProtocols = tempProtocols;
+ }
+}
diff --git a/jdk/src/share/classes/javax/net/ssl/SSLSocket.java b/jdk/src/share/classes/javax/net/ssl/SSLSocket.java
index 948e20d..7de96c2 100644
--- a/jdk/src/share/classes/javax/net/ssl/SSLSocket.java
+++ b/jdk/src/share/classes/javax/net/ssl/SSLSocket.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,8 @@
import java.io.IOException;
import java.net.*;
+import java.util.List;
+import java.util.function.BiFunction;
/**
* This class extends <code>Socket</code>s and provides secure
@@ -662,4 +664,142 @@
}
}
+ /**
+ * Returns the most recent application protocol value negotiated for this
+ * connection.
+ * <p>
+ * If supported by the underlying SSL/TLS/DTLS implementation,
+ * application name negotiation mechanisms such as <a
+ * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 </a>, the
+ * Application-Layer Protocol Negotiation (ALPN), can negotiate
+ * application-level values between peers.
+ *
+ * @implSpec
+ * The implementation in this class throws
+ * {@code UnsupportedOperationException} and performs no other action.
+ *
+ * @return null if it has not yet been determined if application
+ * protocols might be used for this connection, an empty
+ * {@code String} if application protocols values will not
+ * be used, or a non-empty application protocol {@code String}
+ * if a value was successfully negotiated.
+ * @throws UnsupportedOperationException if the underlying provider
+ * does not implement the operation.
+ * @since 8
+ */
+ public String getApplicationProtocol() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the application protocol value negotiated on a SSL/TLS
+ * handshake currently in progress.
+ * <p>
+ * Like {@link #getHandshakeSession()},
+ * a connection may be in the middle of a handshake. The
+ * application protocol may or may not yet be available.
+ *
+ * @implSpec
+ * The implementation in this class throws
+ * {@code UnsupportedOperationException} and performs no other action.
+ *
+ * @return null if it has not yet been determined if application
+ * protocols might be used for this handshake, an empty
+ * {@code String} if application protocols values will not
+ * be used, or a non-empty application protocol {@code String}
+ * if a value was successfully negotiated.
+ * @throws UnsupportedOperationException if the underlying provider
+ * does not implement the operation.
+ * @since 8
+ */
+ public String getHandshakeApplicationProtocol() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ /**
+ * Registers a callback function that selects an application protocol
+ * value for a SSL/TLS/DTLS handshake.
+ * The function overrides any values supplied using
+ * {@link SSLParameters#setApplicationProtocols
+ * SSLParameters.setApplicationProtocols} and it supports the following
+ * type parameters:
+ * <blockquote>
+ * <dl>
+ * <dt> {@code SSLSocket}
+ * <dd> The function's first argument allows the current {@code SSLSocket}
+ * to be inspected, including the handshake session and configuration
+ * settings.
+ * <dt> {@code List<String>}
+ * <dd> The function's second argument lists the application protocol names
+ * advertised by the TLS peer.
+ * <dt> {@code String}
+ * <dd> The function's result is an application protocol name, or null to
+ * indicate that none of the advertised names are acceptable.
+ * If the return value is an empty {@code String} then application
+ * protocol indications will not be used.
+ * If the return value is null (no value chosen) or is a value that
+ * was not advertised by the peer, the underlying protocol will
+ * determine what action to take. (For example, ALPN will send a
+ * "no_application_protocol" alert and terminate the connection.)
+ * </dl>
+ * </blockquote>
+ *
+ * For example, the following call registers a callback function that
+ * examines the TLS handshake parameters and selects an application protocol
+ * name:
+ * <pre>{@code
+ * serverSocket.setHandshakeApplicationProtocolSelector(
+ * (serverSocket, clientProtocols) -> {
+ * SSLSession session = serverSocket.getHandshakeSession();
+ * return chooseApplicationProtocol(
+ * serverSocket,
+ * clientProtocols,
+ * session.getProtocol(),
+ * session.getCipherSuite());
+ * });
+ * }</pre>
+ *
+ * @apiNote
+ * This method should be called by TLS server applications before the TLS
+ * handshake begins. Also, this {@code SSLSocket} should be configured with
+ * parameters that are compatible with the application protocol selected by
+ * the callback function. For example, enabling a poor choice of cipher
+ * suites could result in no suitable application protocol.
+ * See {@link SSLParameters}.
+ *
+ * @implSpec
+ * The implementation in this class throws
+ * {@code UnsupportedOperationException} and performs no other action.
+ *
+ * @param selector the callback function, or null to de-register.
+ * @throws UnsupportedOperationException if the underlying provider
+ * does not implement the operation.
+ * @since 8
+ */
+ public void setHandshakeApplicationProtocolSelector(
+ BiFunction<SSLSocket, List<String>, String> selector) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Retrieves the callback function that selects an application protocol
+ * value during a SSL/TLS/DTLS handshake.
+ * See {@link #setHandshakeApplicationProtocolSelector
+ * setHandshakeApplicationProtocolSelector}
+ * for the function's type parameters.
+ *
+ * @implSpec
+ * The implementation in this class throws
+ * {@code UnsupportedOperationException} and performs no other action.
+ *
+ * @return the callback function, or null if none has been set.
+ * @throws UnsupportedOperationException if the underlying provider
+ * does not implement the operation.
+ * @since 8
+ */
+ public BiFunction<SSLSocket, List<String>, String>
+ getHandshakeApplicationProtocolSelector() {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java b/jdk/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java
index 71cc0aa..ff39983 100644
--- a/jdk/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java
@@ -33,6 +33,22 @@
KeyTab ktab) {
return ktab.takeSnapshot();
}
+
+ public KerberosPrincipal kerberosTicketGetClientAlias(KerberosTicket t) {
+ return t.clientAlias;
+ }
+
+ public void kerberosTicketSetClientAlias(KerberosTicket t, KerberosPrincipal a) {
+ t.clientAlias = a;
+ }
+
+ public KerberosPrincipal kerberosTicketGetServerAlias(KerberosTicket t) {
+ return t.serverAlias;
+ }
+
+ public void kerberosTicketSetServerAlias(KerberosTicket t, KerberosPrincipal a) {
+ t.serverAlias = a;
+ }
public KerberosTicket kerberosTicketGetProxy(KerberosTicket t) {
return t.proxy;
}
diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java
index 308b619..ef767f0 100644
--- a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -80,6 +80,11 @@
public static final int KRB_NT_UID = 5;
+ /**
+ * Enterprise name (alias)
+ */
+ static final int KRB_NT_ENTERPRISE = 10;
+
private transient String fullName;
private transient String realm;
diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java
index 0327f04..3f29d9b 100644
--- a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java
@@ -194,6 +194,10 @@
private InetAddress[] clientAddresses;
+ transient KerberosPrincipal clientAlias = null;
+
+ transient KerberosPrincipal serverAlias = null;
+
/**
* Evidence ticket if proxy_impersonator. This field can be accessed
* by KerberosSecrets. It's serialized.
@@ -308,11 +312,7 @@
} else
this.flags = new boolean[NUM_FLAGS];
- if (this.flags[RENEWABLE_TICKET_FLAG]) {
- if (renewTill == null)
- throw new IllegalArgumentException("The renewable period "
- + "end time cannot be null for renewable tickets.");
-
+ if (this.flags[RENEWABLE_TICKET_FLAG] && renewTill != null) {
this.renewTill = new Date(renewTill.getTime());
}
@@ -553,6 +553,11 @@
if (!isRenewable())
throw new RefreshFailedException("This ticket is not renewable");
+ if (getRenewTill() == null) {
+ // Renewable ticket without renew-till. Illegal and ignored.
+ return;
+ }
+
if (System.currentTimeMillis() > getRenewTill().getTime())
throw new RefreshFailedException("This ticket is past "
+ "its last renewal time.");
@@ -562,7 +567,11 @@
try {
krb5Creds = new sun.security.krb5.Credentials(asn1Encoding,
client.toString(),
+ (clientAlias != null ?
+ clientAlias.getName() : null),
server.toString(),
+ (serverAlias != null ?
+ serverAlias.getName() : null),
sessionKey.getEncoded(),
sessionKey.getKeyType(),
flags,
diff --git a/jdk/src/share/classes/javax/security/auth/x500/X500Principal.java b/jdk/src/share/classes/javax/security/auth/x500/X500Principal.java
index 77292b0..2236661 100644
--- a/jdk/src/share/classes/javax/security/auth/x500/X500Principal.java
+++ b/jdk/src/share/classes/javax/security/auth/x500/X500Principal.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,13 +41,13 @@
* of the distinguished name, or by using the ASN.1 DER encoded byte
* representation of the distinguished name. The current specification
* for the string representation of a distinguished name is defined in
- * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253: Lightweight
+ * <a href="http://tools.ietf.org/html/rfc2253">RFC 2253: Lightweight
* Directory Access Protocol (v3): UTF-8 String Representation of
* Distinguished Names</a>. This class, however, accepts string formats from
- * both RFC 2253 and <a href="http://www.ietf.org/rfc/rfc1779.txt">RFC 1779:
+ * both RFC 2253 and <a href="http://tools.ietf.org/html/rfc1779">RFC 1779:
* A String Representation of Distinguished Names</a>, and also recognizes
* attribute type keywords whose OIDs (Object Identifiers) are defined in
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
+ * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280: Internet X.509
* Public Key Infrastructure Certificate and CRL Profile</a>.
*
* <p> The string representation for this {@code X500Principal}
@@ -108,7 +108,7 @@
* (and listed in {@link #getName(String format) getName(String format)}),
* as well as the T, DNQ or DNQUALIFIER, SURNAME, GIVENNAME, INITIALS,
* GENERATION, EMAILADDRESS, and SERIALNUMBER keywords whose Object
- * Identifiers (OIDs) are defined in RFC 3280 and its successor.
+ * Identifiers (OIDs) are defined in RFC 5280.
* Any other attribute type must be specified as an OID.
*
* <p>This implementation enforces a more restrictive OID syntax than
@@ -456,7 +456,7 @@
* (obtained via the {@code getName(X500Principal.CANONICAL)} method)
* of this object and <i>o</i> are equal.
*
- * <p> This implementation is compliant with the requirements of RFC 3280.
+ * <p> This implementation is compliant with the requirements of RFC 5280.
*
* @param o Object to be compared for equality with this
* {@code X500Principal}
diff --git a/jdk/src/share/classes/javax/security/auth/x500/package-info.java b/jdk/src/share/classes/javax/security/auth/x500/package-info.java
index 12f8a53..1e9ca1a 100644
--- a/jdk/src/share/classes/javax/security/auth/x500/package-info.java
+++ b/jdk/src/share/classes/javax/security/auth/x500/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2014, 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
@@ -31,15 +31,15 @@
* <h2>Package Specification</h2>
*
* <ul>
- * <li><a href="http://www.ietf.org/rfc/rfc1779.txt">
+ * <li><a href="http://tools.ietf.org/html/rfc1779">
* RFC 1779: A String Representation of Distinguished Names</a></li>
- * <li><a href="http://www.ietf.org/rfc/rfc2253.txt">
+ * <li><a href="http://tools.ietf.org/html/rfc2253">
* RFC 2253: Lightweight Directory Access Protocol (v3):
* UTF-8 String Representation of Distinguished Names</a></li>
- * <li><a href="http://www.ietf.org/rfc/rfc3280.txt">
- * RFC 3280: Internet X.509 Public Key Infrastructure
+ * <li><a href="http://tools.ietf.org/html/rfc5280">
+ * RFC 5280: Internet X.509 Public Key Infrastructure
* Certificate and Certificate Revocation List (CRL) Profile</a></li>
- * <li><a href="http://www.ietf.org/rfc/rfc4512.txt">
+ * <li><a href="http://tools.ietf.org/html/rfc4512">
* RFC 4512: Lightweight Directory Access Protocol (LDAP):
* Directory Information Models</a></li>
* </ul>
diff --git a/jdk/src/share/classes/javax/security/sasl/Sasl.java b/jdk/src/share/classes/javax/security/sasl/Sasl.java
index 1ce36c7..7e0baf1 100644
--- a/jdk/src/share/classes/javax/security/sasl/Sasl.java
+++ b/jdk/src/share/classes/javax/security/sasl/Sasl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,15 +26,20 @@
package javax.security.sasl;
import javax.security.auth.callback.CallbackHandler;
-
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
import java.security.Provider;
import java.security.Security;
+import java.util.logging.Level;
+import java.util.logging.Logger;
/**
* A static class for creating SASL clients and servers.
@@ -62,6 +67,30 @@
* @author Rob Weltman
*/
public class Sasl {
+
+ private static List<String> disabledMechanisms = new ArrayList<>();
+
+ static {
+ String prop = AccessController.doPrivileged(
+ (PrivilegedAction<String>)
+ () -> Security.getProperty("jdk.sasl.disabledMechanisms"));
+
+ if (prop != null) {
+ for (String s : prop.split("\\s*,\\s*")) {
+ if (!s.isEmpty()) {
+ disabledMechanisms.add(s);
+ }
+ }
+ }
+ }
+
+ private static final String SASL_LOGGER_NAME = "javax.security.sasl";
+
+ /**
+ * Logger for debug messages
+ */
+ private static final Logger logger = Logger.getLogger(SASL_LOGGER_NAME);
+
// Cannot create one of these
private Sasl() {
}
@@ -306,6 +335,9 @@
* "Java Cryptography Architecture API Specification & Reference"
* for information about how to install and configure security service
* providers.
+ * <p>
+ * If a mechanism is listed in the {@code jdk.sasl.disabledMechanisms}
+ * security property, it will be ignored and won't be negotiated.
*
* @param mechanisms The non-null list of mechanism names to try. Each is the
* IANA-registered name of a SASL mechanism. (e.g. "GSSAPI", "CRAM-MD5").
@@ -369,6 +401,10 @@
"Mechanism name cannot be null");
} else if (mechName.length() == 0) {
continue;
+ } else if (isDisabled(mechName)) {
+ logger.log(Level.FINE,
+ "Disabled " + mechName + " mechanism ignored");
+ continue;
}
String mechFilter = "SaslClientFactory." + mechName;
Provider[] provs = Security.getProviders(mechFilter);
@@ -456,6 +492,9 @@
* "Java Cryptography Architecture API Specification & Reference"
* for information about how to install and configure security
* service providers.
+ * <p>
+ * If {@code mechanism} is listed in the {@code jdk.sasl.disabledMechanisms}
+ * security property, it will be ignored and this method returns {@code null}.
*
* @param mechanism The non-null mechanism name. It must be an
* IANA-registered name of a SASL mechanism. (e.g. "GSSAPI", "CRAM-MD5").
@@ -509,6 +548,10 @@
throw new NullPointerException("Mechanism name cannot be null");
} else if (mechanism.length() == 0) {
return null;
+ } else if (isDisabled(mechanism)) {
+ logger.log(Level.FINE,
+ "Disabled " + mechanism + " mechanism ignored");
+ return null;
}
String mechFilter = "SaslServerFactory." + mechanism;
@@ -618,4 +661,8 @@
}
return Collections.unmodifiableSet(result);
}
+
+ private static boolean isDisabled(String name) {
+ return disabledMechanisms.contains(name);
+ }
}
diff --git a/jdk/src/share/classes/jdk/internal/util/StaticProperty.java b/jdk/src/share/classes/jdk/internal/util/StaticProperty.java
new file mode 100644
index 0000000..1ac81df
--- /dev/null
+++ b/jdk/src/share/classes/jdk/internal/util/StaticProperty.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util;
+
+/**
+ * System Property access for internal use only.
+ * Read-only access to System property values initialized during Phase 1
+ * are cached. Setting, clearing, or modifying the value using
+ * {@link System#setProperty) or {@link System#getProperties()} is ignored.
+ * <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
+ * in these access methods. The caller of these methods should take care to ensure
+ * that the returned property is not made accessible to untrusted code.</strong>
+ */
+public final class StaticProperty {
+
+ // The class static initialization is triggered to initialize these final
+ // fields during init Phase 1 and before a security manager is set.
+ private static final String JDK_SERIAL_FILTER = System.getProperty("jdk.serialFilter");
+
+ private StaticProperty() {}
+
+ /**
+ *
+ * Return the {@code jdk.serialFilter} system property.
+ *
+ * <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
+ * in this method. The caller of this method should take care to ensure
+ * that the returned property is not made accessible to untrusted code.</strong>
+ *
+ * @return the {@code user.name} system property
+ */
+ public static String jdkSerialFilter() {
+ return JDK_SERIAL_FILTER;
+ }
+}
diff --git a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java
index 61aa8a6..08aee02 100644
--- a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java
+++ b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java
@@ -21,7 +21,7 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
*/
/*
* $Id: DOMKeyValue.java 1333415 2012-05-03 12:03:51Z coheigea $
@@ -33,21 +33,19 @@
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.keyinfo.KeyValue;
-// import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.security.AccessController;
+import java.io.IOException;
+import java.math.BigInteger;
import java.security.KeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
import java.security.PublicKey;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.DSAPublicKeySpec;
+import java.security.spec.ECField;
+import java.security.spec.ECFieldFp;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.ECPublicKeySpec;
@@ -55,6 +53,7 @@
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.RSAPublicKeySpec;
+import java.util.Arrays;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -326,55 +325,112 @@
private byte[] ecPublicKey;
private KeyFactory eckf;
private ECParameterSpec ecParams;
- private Method encodePoint, decodePoint, getCurveName,
- getECParameterSpec;
+
+ // The supported curve, secp256r1
+ private static final Curve SECP256R1;
+ static {
+ final String name, oid, sfield, a, b, x, y, n;
+ name = "secp256r1 [NIST P-256, X9.62 prime256v1]";
+ oid = "1.2.840.10045.3.1.7";
+ sfield =
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF";
+ a =
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC";
+ b =
+ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B";
+ x =
+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296";
+ y =
+ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5";
+ n =
+ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551";
+ final int h = 1;
+
+ BigInteger p = bigInt(sfield);
+ ECField field = new ECFieldFp(p);
+ EllipticCurve curve = new EllipticCurve(field, bigInt(a),
+ bigInt(b));
+ ECPoint g = new ECPoint(bigInt(x), bigInt(y));
+ SECP256R1 = new Curve(name, oid, curve, g, bigInt(n), h);
+ }
EC(PublicKey key) throws KeyException {
super(key);
ECPublicKey ecKey = (ECPublicKey)key;
ECPoint ecPoint = ecKey.getW();
ecParams = ecKey.getParams();
- try {
- AccessController.doPrivileged(
- new PrivilegedExceptionAction<Void>() {
- public Void run() throws
- ClassNotFoundException, NoSuchMethodException
- {
- getMethods();
- return null;
- }
- }
- );
- } catch (PrivilegedActionException pae) {
- throw new KeyException("ECKeyValue not supported",
- pae.getException());
- }
- Object[] args = new Object[] { ecPoint, ecParams.getCurve() };
- try {
- ecPublicKey = (byte[])encodePoint.invoke(null, args);
- } catch (IllegalAccessException iae) {
- throw new KeyException(iae);
- } catch (InvocationTargetException ite) {
- throw new KeyException(ite);
- }
+ ecPublicKey = encodePoint(ecPoint, ecParams.getCurve());
}
EC(Element dmElem) throws MarshalException {
super(dmElem);
}
- void getMethods() throws ClassNotFoundException, NoSuchMethodException {
- Class<?> c = Class.forName("sun.security.ec.ECParameters");
- Class<?>[] params = new Class<?>[] { ECPoint.class,
- EllipticCurve.class };
- encodePoint = c.getMethod("encodePoint", params);
- params = new Class<?>[] { ECParameterSpec.class };
- getCurveName = c.getMethod("getCurveName", params);
- params = new Class<?>[] { byte[].class, EllipticCurve.class };
- decodePoint = c.getMethod("decodePoint", params);
- c = Class.forName("sun.security.ec.NamedCurve");
- params = new Class<?>[] { String.class };
- getECParameterSpec = c.getMethod("getECParameterSpec", params);
+ private static ECPoint decodePoint(byte[] data, EllipticCurve curve)
+ throws IOException {
+ if ((data.length == 0) || (data[0] != 4)) {
+ throw new IOException("Only uncompressed point format " +
+ "supported");
+ }
+ // Per ANSI X9.62, an encoded point is a 1 byte type followed by
+ // ceiling(log base 2 field-size / 8) bytes of x and the same of y.
+ int n = (data.length - 1) / 2;
+ if (n != ((curve.getField().getFieldSize() + 7) >> 3)) {
+ throw new IOException("Point does not match field size");
+ }
+
+ byte[] xb = Arrays.copyOfRange(data, 1, 1 + n);
+ byte[] yb = Arrays.copyOfRange(data, n + 1, n + 1 + n);
+
+ return new ECPoint(new BigInteger(1, xb), new BigInteger(1, yb));
+ }
+
+ private static byte[] encodePoint(ECPoint point, EllipticCurve curve) {
+ // get field size in bytes (rounding up)
+ int n = (curve.getField().getFieldSize() + 7) >> 3;
+ byte[] xb = trimZeroes(point.getAffineX().toByteArray());
+ byte[] yb = trimZeroes(point.getAffineY().toByteArray());
+ if ((xb.length > n) || (yb.length > n)) {
+ throw new RuntimeException("Point coordinates do not " +
+ "match field size");
+ }
+ byte[] b = new byte[1 + (n << 1)];
+ b[0] = 4; // uncompressed
+ System.arraycopy(xb, 0, b, n - xb.length + 1, xb.length);
+ System.arraycopy(yb, 0, b, b.length - yb.length, yb.length);
+ return b;
+ }
+
+ private static byte[] trimZeroes(byte[] b) {
+ int i = 0;
+ while ((i < b.length - 1) && (b[i] == 0)) {
+ i++;
+ }
+ if (i == 0) {
+ return b;
+ }
+ return Arrays.copyOfRange(b, i, b.length);
+ }
+
+ private static String getCurveOid(ECParameterSpec params) {
+ // Check that the params represent the secp256r1 curve
+ // If so, return the object identifier of the curve
+ int fieldSize = params.getCurve().getField().getFieldSize();
+ if (SECP256R1.getCurve().getField().getFieldSize() == fieldSize
+ && SECP256R1.getCurve().equals(params.getCurve())
+ && SECP256R1.getGenerator().equals(params.getGenerator())
+ && SECP256R1.getOrder().equals(params.getOrder())
+ && SECP256R1.getCofactor() == params.getCofactor()) {
+ return SECP256R1.getObjectId();
+ }
+ return null;
+ }
+
+ private static ECParameterSpec getECParameterSpec(String oid) {
+ if (oid.equals(SECP256R1.getObjectId())) {
+ return SECP256R1;
+ }
+ return null;
}
void marshalPublicKey(Node parent, Document doc, String dsPrefix,
@@ -392,14 +448,11 @@
XMLDSIG_11_XMLNS,
prefix);
Object[] args = new Object[] { ecParams };
- try {
- String oid = (String) getCurveName.invoke(null, args);
- DOMUtils.setAttribute(namedCurveElem, "URI", "urn:oid:" + oid);
- } catch (IllegalAccessException iae) {
- throw new MarshalException(iae);
- } catch (InvocationTargetException ite) {
- throw new MarshalException(ite);
+ String oid = getCurveOid(ecParams);
+ if (oid == null) {
+ throw new MarshalException("Invalid ECParameterSpec");
}
+ DOMUtils.setAttribute(namedCurveElem, "URI", "urn:oid:" + oid);
String qname = (prefix == null || prefix.length() == 0)
? "xmlns" : "xmlns:" + prefix;
namedCurveElem.setAttributeNS("http://www.w3.org/2000/xmlns/",
@@ -423,21 +476,6 @@
("unable to create EC KeyFactory: " + e.getMessage());
}
}
- try {
- AccessController.doPrivileged(
- new PrivilegedExceptionAction<Void>() {
- public Void run() throws
- ClassNotFoundException, NoSuchMethodException
- {
- getMethods();
- return null;
- }
- }
- );
- } catch (PrivilegedActionException pae) {
- throw new MarshalException("ECKeyValue not supported",
- pae.getException());
- }
ECParameterSpec ecParams = null;
Element curElem = DOMUtils.getFirstChildElement(kvtElem);
if (curElem.getLocalName().equals("ECParameters")) {
@@ -448,14 +486,9 @@
// strip off "urn:oid"
if (uri.startsWith("urn:oid:")) {
String oid = uri.substring(8);
- try {
- Object[] args = new Object[] { oid };
- ecParams = (ECParameterSpec)
- getECParameterSpec.invoke(null, args);
- } catch (IllegalAccessException iae) {
- throw new MarshalException(iae);
- } catch (InvocationTargetException ite) {
- throw new MarshalException(ite);
+ ecParams = getECParameterSpec(oid);
+ if (ecParams == null) {
+ throw new MarshalException("Invalid curve OID");
}
} else {
throw new MarshalException("Invalid NamedCurve URI");
@@ -465,24 +498,43 @@
}
curElem = DOMUtils.getNextSiblingElement(curElem, "PublicKey");
ECPoint ecPoint = null;
+
try {
- Object[] args = new Object[] { Base64.decode(curElem),
- ecParams.getCurve() };
- ecPoint = (ECPoint)decodePoint.invoke(null, args);
+ ecPoint = decodePoint(Base64.decode(curElem),
+ ecParams.getCurve());
} catch (Base64DecodingException bde) {
throw new MarshalException("Invalid EC PublicKey", bde);
- } catch (IllegalAccessException iae) {
- throw new MarshalException(iae);
- } catch (InvocationTargetException ite) {
- throw new MarshalException(ite);
+ } catch (IOException ioe) {
+ throw new MarshalException("Invalid EC Point", ioe);
}
-/*
- ecPoint = sun.security.ec.ECParameters.decodePoint(
- Base64.decode(curElem), ecParams.getCurve());
-*/
+
ECPublicKeySpec spec = new ECPublicKeySpec(ecPoint, ecParams);
return generatePublicKey(eckf, spec);
}
+
+ static final class Curve extends ECParameterSpec {
+ private final String name;
+ private final String oid;
+
+ Curve(String name, String oid, EllipticCurve curve,
+ ECPoint g, BigInteger n, int h) {
+ super(curve, g, n, h);
+ this.name = name;
+ this.oid = oid;
+ }
+
+ private String getName() {
+ return name;
+ }
+
+ private String getObjectId() {
+ return oid;
+ }
+ }
+ }
+
+ private static BigInteger bigInt(String s) {
+ return new BigInteger(s, 16);
}
static final class Unknown extends DOMKeyValue {
diff --git a/jdk/src/share/classes/sun/applet/AppletClassLoader.java b/jdk/src/share/classes/sun/applet/AppletClassLoader.java
index f732ad2..1fcd158 100644
--- a/jdk/src/share/classes/sun/applet/AppletClassLoader.java
+++ b/jdk/src/share/classes/sun/applet/AppletClassLoader.java
@@ -33,6 +33,7 @@
import java.net.MalformedURLException;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.io.EOFException;
import java.io.File;
import java.io.FilePermission;
import java.io.IOException;
@@ -333,7 +334,9 @@
byte[] b;
try {
- b = IOUtils.readFully(in, len, true);
+ b = IOUtils.readAllBytes(in);
+ if (len != -1 && b.length != len)
+ throw new EOFException("Expected:" + len + ", read:" + b.length);
} finally {
in.close();
}
diff --git a/jdk/src/share/classes/sun/java2d/marlin/MarlinCache.java b/jdk/src/share/classes/sun/java2d/marlin/MarlinCache.java
index 78e566f..8574513 100644
--- a/jdk/src/share/classes/sun/java2d/marlin/MarlinCache.java
+++ b/jdk/src/share/classes/sun/java2d/marlin/MarlinCache.java
@@ -156,8 +156,6 @@
// rewritten to avoid division:
|| (width * heightSubPixel) >
((edgeSumDeltaY - heightSubPixel) << BLOCK_SIZE_LG);
-// ((edgeSumDeltaY - heightSubPixel) * RLE_THRESHOLD);
-// ((edgeSumDeltaY - heightSubPixel) << BLOCK_TH_LG);
if (doTrace && !useRLE) {
final float meanCrossings
@@ -293,8 +291,10 @@
// update row index to current position:
rowAAChunkIndex[row] = pos;
- // determine need array size (may overflow):
- final long needSize = pos + (px_bbox1 - px0);
+ // determine need array size:
+ // for RLE encoding, position must be aligned to 4 bytes (int):
+ // align - 1 = 3 so add +3 and round-off by mask ~3 = -4
+ final long needSize = pos + ((px_bbox1 - px0 + 3) & -4);
// update next position (bytes):
rowAAChunkPos = needSize;
@@ -401,8 +401,7 @@
// determine need array size:
// pessimistic: max needed size = deltaX x 4 (1 int)
- final int maxLen = (to - from);
- final long needSize = initialPos + (maxLen << 2);
+ final long needSize = initialPos + ((to - from) << 2);
// update row data:
OffHeapArray _rowAAChunk = rowAAChunk;
@@ -465,6 +464,13 @@
// note: last pixel exclusive (>= 0)
// note: it should check X is smaller than 23bits (overflow)!
+ // check address alignment to 4 bytes:
+ if (doCheckUnsafe) {
+ if ((addr_off & 3) != 0) {
+ MarlinUtils.logInfo("Misaligned Unsafe address: " + addr_off);
+ }
+ }
+
// special case to encode entries into a single int:
if (val == 0) {
_unsafe.putInt(addr_off,
@@ -521,6 +527,13 @@
// note: last pixel exclusive (>= 0)
// note: it should check X is smaller than 23bits (overflow)!
+ // check address alignment to 4 bytes:
+ if (doCheckUnsafe) {
+ if ((addr_off & 3) != 0) {
+ MarlinUtils.logInfo("Misaligned Unsafe address: " + addr_off);
+ }
+ }
+
// special case to encode entries into a single int:
if (val == 0) {
_unsafe.putInt(addr_off,
diff --git a/jdk/src/share/classes/sun/java2d/marlin/MarlinConst.java b/jdk/src/share/classes/sun/java2d/marlin/MarlinConst.java
index 6ff24a0..e799504 100644
--- a/jdk/src/share/classes/sun/java2d/marlin/MarlinConst.java
+++ b/jdk/src/share/classes/sun/java2d/marlin/MarlinConst.java
@@ -40,6 +40,8 @@
// log misc.Unsafe alloc/realloc/free
static final boolean logUnsafeMalloc = enableLogs
&& MarlinProperties.isLogUnsafeMalloc();
+ // do check unsafe alignment:
+ static final boolean doCheckUnsafe = false;
// do statistics
static final boolean doStats = enableLogs && MarlinProperties.isDoStats();
diff --git a/jdk/src/share/classes/sun/misc/IOUtils.java b/jdk/src/share/classes/sun/misc/IOUtils.java
index 67079b9..5e6c79c 100644
--- a/jdk/src/share/classes/sun/misc/IOUtils.java
+++ b/jdk/src/share/classes/sun/misc/IOUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, 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
@@ -32,67 +32,282 @@
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
+
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
public class IOUtils {
- /**
- * Read up to {@code length} of bytes from {@code in}
- * until EOF is detected.
- * @param is input stream, must not be null
- * @param length number of bytes to read, -1 or Integer.MAX_VALUE means
- * read as much as possible
- * @param readAll if true, an EOFException will be thrown if not enough
- * bytes are read. Ignored when length is -1 or Integer.MAX_VALUE
- * @return bytes read
- * @throws IOException Any IO error or a premature EOF is detected
- */
- public static byte[] readFully(InputStream is, int length, boolean readAll)
- throws IOException {
- byte[] output = {};
- if (length == -1) length = Integer.MAX_VALUE;
- int pos = 0;
- while (pos < length) {
- int bytesToRead;
- if (pos >= output.length) { // Only expand when there's no room
- bytesToRead = Math.min(length - pos, output.length + 1024);
- if (output.length < pos + bytesToRead) {
- output = Arrays.copyOf(output, pos + bytesToRead);
- }
- } else {
- bytesToRead = output.length - pos;
- }
- int cc = is.read(output, pos, bytesToRead);
- if (cc < 0) {
- if (readAll && length != Integer.MAX_VALUE) {
- throw new EOFException("Detect premature EOF");
- } else {
- if (output.length != pos) {
- output = Arrays.copyOf(output, pos);
- }
- break;
- }
- }
- pos += cc;
- }
- return output;
- }
+ private static final int DEFAULT_BUFFER_SIZE = 8192;
/**
- * Read {@code length} of bytes from {@code in}. An exception is
- * thrown if there are not enough bytes in the stream.
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
+ * Read exactly {@code length} of bytes from {@code in}.
+ *
+ * <p> Note that this method is safe to be called with unknown large
+ * {@code length} argument. The memory used is proportional to the
+ * actual bytes available. An exception is thrown if there are not
+ * enough bytes in the stream.
*
* @param is input stream, must not be null
- * @param length number of bytes to read, must not be negative
+ * @param length number of bytes to read
* @return bytes read
- * @throws IOException if any IO error or a premature EOF is detected, or
- * if {@code length} is negative since this length is usually also
- * read from {@code is}.
+ * @throws EOFException if there are not enough bytes in the stream
+ * @throws IOException if an I/O error occurs or {@code length} is negative
+ * @throws OutOfMemoryError if an array of the required size cannot be
+ * allocated.
*/
- public static byte[] readNBytes(InputStream is, int length) throws IOException {
+ public static byte[] readExactlyNBytes(InputStream is, int length)
+ throws IOException {
if (length < 0) {
throw new IOException("length cannot be negative: " + length);
}
- return readFully(is, length, true);
+ byte[] data = readNBytes(is, length);
+ if (data.length < length) {
+ throw new EOFException();
+ }
+ return data;
+ }
+
+ /**
+ * Reads all remaining bytes from the input stream. This method blocks until
+ * all remaining bytes have been read and end of stream is detected, or an
+ * exception is thrown. This method does not close the input stream.
+ *
+ * <p> When this stream reaches end of stream, further invocations of this
+ * method will return an empty byte array.
+ *
+ * <p> Note that this method is intended for simple cases where it is
+ * convenient to read all bytes into a byte array. It is not intended for
+ * reading input streams with large amounts of data.
+ *
+ * <p> The behavior for the case where the input stream is <i>asynchronously
+ * closed</i>, or the thread interrupted during the read, is highly input
+ * stream specific, and therefore not specified.
+ *
+ * <p> If an I/O error occurs reading from the input stream, then it may do
+ * so after some, but not all, bytes have been read. Consequently the input
+ * stream may not be at end of stream and may be in an inconsistent state.
+ * It is strongly recommended that the stream be promptly closed if an I/O
+ * error occurs.
+ *
+ * @implSpec
+ * This method invokes {@link #readNBytes(int)} with a length of
+ * {@link Integer#MAX_VALUE}.
+ *
+ * @param is input stream, must not be null
+ * @return a byte array containing the bytes read from this input stream
+ * @throws IOException if an I/O error occurs
+ * @throws OutOfMemoryError if an array of the required size cannot be
+ * allocated.
+ *
+ * @since 1.9
+ */
+ public static byte[] readAllBytes(InputStream is) throws IOException {
+ return readNBytes(is, Integer.MAX_VALUE);
+ }
+
+ /**
+ * Reads up to a specified number of bytes from the input stream. This
+ * method blocks until the requested number of bytes have been read, end
+ * of stream is detected, or an exception is thrown. This method does not
+ * close the input stream.
+ *
+ * <p> The length of the returned array equals the number of bytes read
+ * from the stream. If {@code len} is zero, then no bytes are read and
+ * an empty byte array is returned. Otherwise, up to {@code len} bytes
+ * are read from the stream. Fewer than {@code len} bytes may be read if
+ * end of stream is encountered.
+ *
+ * <p> When this stream reaches end of stream, further invocations of this
+ * method will return an empty byte array.
+ *
+ * <p> Note that this method is intended for simple cases where it is
+ * convenient to read the specified number of bytes into a byte array. The
+ * total amount of memory allocated by this method is proportional to the
+ * number of bytes read from the stream which is bounded by {@code len}.
+ * Therefore, the method may be safely called with very large values of
+ * {@code len} provided sufficient memory is available.
+ *
+ * <p> The behavior for the case where the input stream is <i>asynchronously
+ * closed</i>, or the thread interrupted during the read, is highly input
+ * stream specific, and therefore not specified.
+ *
+ * <p> If an I/O error occurs reading from the input stream, then it may do
+ * so after some, but not all, bytes have been read. Consequently the input
+ * stream may not be at end of stream and may be in an inconsistent state.
+ * It is strongly recommended that the stream be promptly closed if an I/O
+ * error occurs.
+ *
+ * @implNote
+ * The number of bytes allocated to read data from this stream and return
+ * the result is bounded by {@code 2*(long)len}, inclusive.
+ *
+ * @param is input stream, must not be null
+ * @param len the maximum number of bytes to read
+ * @return a byte array containing the bytes read from this input stream
+ * @throws IllegalArgumentException if {@code length} is negative
+ * @throws IOException if an I/O error occurs
+ * @throws OutOfMemoryError if an array of the required size cannot be
+ * allocated.
+ *
+ * @since 11
+ */
+ public static byte[] readNBytes(InputStream is, int len) throws IOException {
+ if (len < 0) {
+ throw new IllegalArgumentException("len < 0");
+ }
+
+ List<byte[]> bufs = null;
+ byte[] result = null;
+ int total = 0;
+ int remaining = len;
+ int n;
+ do {
+ byte[] buf = new byte[Math.min(remaining, DEFAULT_BUFFER_SIZE)];
+ int nread = 0;
+
+ // read to EOF which may read more or less than buffer size
+ while ((n = is.read(buf, nread,
+ Math.min(buf.length - nread, remaining))) > 0) {
+ nread += n;
+ remaining -= n;
+ }
+
+ if (nread > 0) {
+ if (MAX_BUFFER_SIZE - total < nread) {
+ throw new OutOfMemoryError("Required array size too large");
+ }
+ total += nread;
+ if (result == null) {
+ result = buf;
+ } else {
+ if (bufs == null) {
+ bufs = new ArrayList<>();
+ bufs.add(result);
+ }
+ bufs.add(buf);
+ }
+ }
+ // if the last call to read returned -1 or the number of bytes
+ // requested have been read then break
+ } while (n >= 0 && remaining > 0);
+
+ if (bufs == null) {
+ if (result == null) {
+ return new byte[0];
+ }
+ return result.length == total ?
+ result : Arrays.copyOf(result, total);
+ }
+
+ result = new byte[total];
+ int offset = 0;
+ remaining = total;
+ for (byte[] b : bufs) {
+ int count = Math.min(b.length, remaining);
+ System.arraycopy(b, 0, result, offset, count);
+ offset += count;
+ remaining -= count;
+ }
+
+ return result;
+ }
+
+ /**
+ * Reads the requested number of bytes from the input stream into the given
+ * byte array. This method blocks until {@code len} bytes of input data have
+ * been read, end of stream is detected, or an exception is thrown. The
+ * number of bytes actually read, possibly zero, is returned. This method
+ * does not close the input stream.
+ *
+ * <p> In the case where end of stream is reached before {@code len} bytes
+ * have been read, then the actual number of bytes read will be returned.
+ * When this stream reaches end of stream, further invocations of this
+ * method will return zero.
+ *
+ * <p> If {@code len} is zero, then no bytes are read and {@code 0} is
+ * returned; otherwise, there is an attempt to read up to {@code len} bytes.
+ *
+ * <p> The first byte read is stored into element {@code b[off]}, the next
+ * one in to {@code b[off+1]}, and so on. The number of bytes read is, at
+ * most, equal to {@code len}. Let <i>k</i> be the number of bytes actually
+ * read; these bytes will be stored in elements {@code b[off]} through
+ * {@code b[off+}<i>k</i>{@code -1]}, leaving elements {@code b[off+}<i>k</i>
+ * {@code ]} through {@code b[off+len-1]} unaffected.
+ *
+ * <p> The behavior for the case where the input stream is <i>asynchronously
+ * closed</i>, or the thread interrupted during the read, is highly input
+ * stream specific, and therefore not specified.
+ *
+ * <p> If an I/O error occurs reading from the input stream, then it may do
+ * so after some, but not all, bytes of {@code b} have been updated with
+ * data from the input stream. Consequently the input stream and {@code b}
+ * may be in an inconsistent state. It is strongly recommended that the
+ * stream be promptly closed if an I/O error occurs.
+ *
+ * @param is input stream, must not be null
+ * @param b the byte array into which the data is read
+ * @param off the start offset in {@code b} at which the data is written
+ * @param len the maximum number of bytes to read
+ * @return the actual number of bytes read into the buffer
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if {@code b} is {@code null}
+ * @throws IndexOutOfBoundsException If {@code off} is negative, {@code len}
+ * is negative, or {@code len} is greater than {@code b.length - off}
+ *
+ * @since 1.9
+ */
+ public static int readNBytes(InputStream is, byte[] b, int off, int len) throws IOException {
+ Objects.requireNonNull(b);
+ if (off < 0 || len < 0 || len > b.length - off)
+ throw new IndexOutOfBoundsException();
+ int n = 0;
+ while (n < len) {
+ int count = is.read(b, off + n, len - n);
+ if (count < 0)
+ break;
+ n += count;
+ }
+ return n;
+ }
+
+ /**
+ * Compatibility wrapper for third party users of
+ * {@code sun.misc.IOUtils.readFully} following its
+ * removal in JDK-8231139.
+ *
+ * Read up to {@code length} of bytes from {@code in}
+ * until EOF is detected.
+ *
+ * @param is input stream, must not be null
+ * @param length number of bytes to read
+ * @param readAll if true, an EOFException will be thrown if not enough
+ * bytes are read.
+ * @return bytes read
+ * @throws EOFException if there are not enough bytes in the stream
+ * @throws IOException if an I/O error occurs or {@code length} is negative
+ * @throws OutOfMemoryError if an array of the required size cannot be
+ * allocated.
+ */
+ public static byte[] readFully(InputStream is, int length, boolean readAll)
+ throws IOException {
+ if (length < 0) {
+ throw new IOException("length cannot be negative: " + length);
+ }
+ if (readAll) {
+ return readExactlyNBytes(is, length);
+ } else {
+ return readNBytes(is, length);
+ }
}
}
diff --git a/jdk/src/share/classes/sun/misc/JavaObjectInputStreamReadString.java b/jdk/src/share/classes/sun/misc/JavaObjectInputStreamReadString.java
new file mode 100644
index 0000000..ed7a6c3
--- /dev/null
+++ b/jdk/src/share/classes/sun/misc/JavaObjectInputStreamReadString.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+/**
+ * Interface to specify methods for accessing {@code ObjectInputStream}.
+ */
+@FunctionalInterface
+public interface JavaObjectInputStreamReadString {
+ String readString(ObjectInputStream ois) throws IOException;
+}
+
diff --git a/jdk/src/share/classes/sun/misc/JavaSecuritySignatureAccess.java b/jdk/src/share/classes/sun/misc/JavaSecuritySignatureAccess.java
new file mode 100644
index 0000000..382f814
--- /dev/null
+++ b/jdk/src/share/classes/sun/misc/JavaSecuritySignatureAccess.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+
+public interface JavaSecuritySignatureAccess {
+
+ void initVerify(Signature s, PublicKey publicKey, AlgorithmParameterSpec params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException;
+
+ void initVerify(Signature s, java.security.cert.Certificate certificate,
+ AlgorithmParameterSpec params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException;
+
+ void initSign(Signature s, PrivateKey privateKey,
+ AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException;
+}
diff --git a/jdk/src/share/classes/sun/misc/ObjectInputFilter.java b/jdk/src/share/classes/sun/misc/ObjectInputFilter.java
index 9b2c689..af21c74 100644
--- a/jdk/src/share/classes/sun/misc/ObjectInputFilter.java
+++ b/jdk/src/share/classes/sun/misc/ObjectInputFilter.java
@@ -37,6 +37,8 @@
import java.util.function.Function;
import sun.util.logging.PlatformLogger;
+import jdk.internal.util.StaticProperty;
+
/**
* Filter classes, array lengths, and graph metrics during deserialization.
* If set on an {@link ObjectInputStream}, the {@link #checkInput checkInput(FilterInfo)}
@@ -247,7 +249,7 @@
static {
configuredFilter = AccessController
.doPrivileged((PrivilegedAction<ObjectInputFilter>) () -> {
- String props = System.getProperty(SERIAL_FILTER_PROPNAME);
+ String props = StaticProperty.jdkSerialFilter();
if (props == null) {
props = Security.getProperty(SERIAL_FILTER_PROPNAME);
}
diff --git a/jdk/src/share/classes/sun/misc/SharedSecrets.java b/jdk/src/share/classes/sun/misc/SharedSecrets.java
index cc3fc64..f065a2c 100644
--- a/jdk/src/share/classes/sun/misc/SharedSecrets.java
+++ b/jdk/src/share/classes/sun/misc/SharedSecrets.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
import java.io.FileDescriptor;
import java.io.ObjectInputStream;
import java.security.ProtectionDomain;
+import java.security.Signature;
import java.security.AccessController;
@@ -59,7 +60,9 @@
private static JavaAWTAccess javaAWTAccess;
private static JavaOISAccess javaOISAccess;
private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess;
+ private static JavaObjectInputStreamReadString javaObjectInputStreamReadString;
private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
+ private static JavaSecuritySignatureAccess javaSecuritySignatureAccess;
public static JavaUtilJarAccess javaUtilJarAccess() {
if (javaUtilJarAccess == null) {
@@ -202,8 +205,18 @@
return javaAWTAccess;
}
+ public static JavaObjectInputStreamReadString getJavaObjectInputStreamReadString() {
+ if (javaObjectInputStreamReadString == null) {
+ unsafe.ensureClassInitialized(ObjectInputStream.class);
+ }
+ return javaObjectInputStreamReadString;
+ }
- public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
+ public static void setJavaObjectInputStreamReadString(JavaObjectInputStreamReadString access) {
+ javaObjectInputStreamReadString = access;
+ }
+
+ public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
if (javaObjectInputStreamAccess == null) {
unsafe.ensureClassInitialized(ObjectInputStream.class);
}
@@ -214,6 +227,17 @@
javaObjectInputStreamAccess = access;
}
+ public static void setJavaSecuritySignatureAccess(JavaSecuritySignatureAccess jssa) {
+ javaSecuritySignatureAccess = jssa;
+ }
+
+ public static JavaSecuritySignatureAccess getJavaSecuritySignatureAccess() {
+ if (javaSecuritySignatureAccess == null) {
+ unsafe.ensureClassInitialized(Signature.class);
+ }
+ return javaSecuritySignatureAccess;
+ }
+
public static void setJavaxCryptoSealedObjectAccess(JavaxCryptoSealedObjectAccess jcsoa) {
javaxCryptoSealedObjectAccess = jcsoa;
}
diff --git a/jdk/src/share/classes/sun/misc/URLClassPath.java b/jdk/src/share/classes/sun/misc/URLClassPath.java
index 6e03510..8d7593f 100644
--- a/jdk/src/share/classes/sun/misc/URLClassPath.java
+++ b/jdk/src/share/classes/sun/misc/URLClassPath.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -1229,10 +1229,15 @@
int i = 0;
while (st.hasMoreTokens()) {
String path = st.nextToken();
- URL url = DISABLE_CP_URL_CHECK ? new URL(base, path) : safeResolve(base, path);
+ URL url = DISABLE_CP_URL_CHECK ? new URL(base, path) : tryResolve(base, path);
if (url != null) {
urls[i] = url;
i++;
+ } else {
+ if (DEBUG_CP_URL_CHECK) {
+ System.err.println("Class-Path entry: \"" + path
+ + "\" ignored in JAR file " + base);
+ }
}
}
if (i == 0) {
@@ -1244,36 +1249,74 @@
return urls;
}
- /*
- * Return a URL for the given path resolved against the base URL, or
- * null if the resulting URL is invalid.
+ static URL tryResolve(URL base, String input) throws MalformedURLException {
+ if ("file".equalsIgnoreCase(base.getProtocol())) {
+ return tryResolveFile(base, input);
+ } else {
+ return tryResolveNonFile(base, input);
+ }
+ }
+
+ /**
+ * Attempt to return a file URL by resolving input against a base file
+ * URL. The input is an absolute or relative file URL that encodes a
+ * file path.
+ *
+ * @apiNote Nonsensical input such as a Windows file path with a drive
+ * letter cannot be disambiguated from an absolute URL so will be rejected
+ * (by returning null) by this method.
+ *
+ * @return the resolved URL or null if the input is an absolute URL with
+ * a scheme other than file (ignoring case)
+ * @throws MalformedURLException
*/
- static URL safeResolve(URL base, String path) {
- String child = path.replace(File.separatorChar, '/');
- try {
- if (!URI.create(child).isAbsolute()) {
- URL url = new URL(base, child);
- if (base.getProtocol().equalsIgnoreCase("file")) {
- return url;
- } else {
- String bp = base.getPath();
- String urlp = url.getPath();
- int pos = bp.lastIndexOf('/');
- if (pos == -1) {
- pos = bp.length() - 1;
- }
- if (urlp.regionMatches(0, bp, 0, pos + 1)
- && urlp.indexOf("..", pos) == -1) {
- return url;
- }
- }
+ static URL tryResolveFile(URL base, String input) throws MalformedURLException {
+ int index = input.indexOf(':');
+ boolean isFile;
+ if (index >= 0) {
+ String scheme = input.substring(0, index);
+ isFile = "file".equalsIgnoreCase(scheme);
+ } else {
+ isFile = true;
+ }
+ return (isFile) ? new URL(base, input) : null;
+ }
+
+ /**
+ * Attempt to return a URL by resolving input against a base URL. Returns
+ * null if the resolved URL is not contained by the base URL.
+ *
+ * @return the resolved URL or null
+ * @throws MalformedURLException
+ */
+ static URL tryResolveNonFile(URL base, String input) throws MalformedURLException {
+ String child = input.replace(File.separatorChar, '/');
+ if (isRelative(child)) {
+ URL url = new URL(base, child);
+ String bp = base.getPath();
+ String urlp = url.getPath();
+ int pos = bp.lastIndexOf('/');
+ if (pos == -1) {
+ pos = bp.length() - 1;
}
- } catch (MalformedURLException | IllegalArgumentException e) {}
- if (DEBUG_CP_URL_CHECK) {
- System.err.println("Class-Path entry: \"" + path + "\" ignored in JAR file " + base);
+ if (urlp.regionMatches(0, bp, 0, pos + 1)
+ && urlp.indexOf("..", pos) == -1) {
+ return url;
+ }
}
return null;
}
+
+ /**
+ * Returns true if the given input is a relative URI.
+ */
+ static boolean isRelative(String child) {
+ try {
+ return !URI.create(child).isAbsolute();
+ } catch (IllegalArgumentException e) {
+ return false;
+ }
+ }
}
/*
diff --git a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
index 53e84d4..b91093f 100644
--- a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
+++ b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
@@ -49,9 +49,6 @@
// Our file descriptor
private final FileDescriptor fd;
-
- // fd value needed for dev/poll. This value will remain valid
- // even after the value in the file descriptor object has been set to -1
private final int fdVal;
// The protocol family of the socket
@@ -103,7 +100,6 @@
// -- End of fields protected by stateLock
-
public DatagramChannelImpl(SelectorProvider sp)
throws IOException
{
@@ -138,16 +134,27 @@
throw new UnsupportedOperationException("IPv6 not available");
}
}
- this.family = family;
- this.fd = Net.socket(family, false);
- this.fdVal = IOUtil.fdVal(fd);
- this.state = ST_UNCONNECTED;
+
+ ResourceManager.beforeUdpCreate();
+ try {
+ this.family = family;
+ this.fd = Net.socket(family, false);
+ this.fdVal = IOUtil.fdVal(fd);
+ this.state = ST_UNCONNECTED;
+ } catch (IOException ioe) {
+ ResourceManager.afterUdpClose();
+ throw ioe;
+ }
}
public DatagramChannelImpl(SelectorProvider sp, FileDescriptor fd)
throws IOException
{
super(sp);
+
+ // increment UDP count to match decrement when closing
+ ResourceManager.beforeUdpCreate();
+
this.family = Net.isIPv6Available() ?
StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
this.fd = fd;
@@ -742,10 +749,9 @@
localAddress = Net.localAddress(fd);
// flush any packets already received.
- boolean blocking = false;
synchronized (blockingLock()) {
+ boolean blocking = isBlocking();
try {
- blocking = isBlocking();
// remainder of each packet thrown away
ByteBuffer tmpBuf = ByteBuffer.allocate(1);
if (blocking) {
diff --git a/jdk/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java b/jdk/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
index fe2ed23..838a02d 100644
--- a/jdk/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
+++ b/jdk/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,22 @@
package sun.nio.ch;
-import java.io.*;
-import java.net.*;
-import java.nio.*;
-import java.nio.channels.*;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.DatagramSocketImpl;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketOption;
+import java.net.SocketTimeoutException;
+import java.net.StandardSocketOptions;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.IllegalBlockingModeException;
// Make a datagram-socket channel look like a datagram socket.
@@ -178,7 +190,6 @@
dc.configureBlocking(false);
try {
- int n;
SocketAddress sender;
if ((sender = dc.receive(bb)) != null)
return sender;
@@ -188,19 +199,18 @@
throw new ClosedChannelException();
long st = System.currentTimeMillis();
int result = dc.poll(Net.POLLIN, to);
- if (result > 0 &&
- ((result & Net.POLLIN) != 0)) {
+ if (result > 0 && ((result & Net.POLLIN) != 0)) {
if ((sender = dc.receive(bb)) != null)
return sender;
}
to -= System.currentTimeMillis() - st;
if (to <= 0)
throw new SocketTimeoutException();
-
}
} finally {
- if (dc.isOpen())
+ try {
dc.configureBlocking(true);
+ } catch (ClosedChannelException e) { }
}
}
diff --git a/jdk/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java b/jdk/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java
index 4357ffc..63574ac 100644
--- a/jdk/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java
+++ b/jdk/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,20 @@
package sun.nio.ch;
-import java.io.*;
-import java.net.*;
-import java.nio.channels.*;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.net.StandardSocketOptions;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.NotYetBoundException;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
// Make a server-socket channel look like a server socket.
@@ -37,7 +48,7 @@
// class.
//
-public class ServerSocketAdaptor // package-private
+class ServerSocketAdaptor // package-private
extends ServerSocket
{
@@ -97,12 +108,16 @@
throw new IllegalBlockingModeException();
try {
if (timeout == 0) {
+ // for compatibility reasons: accept connection if available
+ // when configured non-blocking
SocketChannel sc = ssc.accept();
if (sc == null && !ssc.isBlocking())
throw new IllegalBlockingModeException();
return sc.socket();
}
+ if (!ssc.isBlocking())
+ throw new IllegalBlockingModeException();
ssc.configureBlocking(false);
try {
SocketChannel sc;
@@ -121,10 +136,10 @@
throw new SocketTimeoutException();
}
} finally {
- if (ssc.isOpen())
+ try {
ssc.configureBlocking(true);
+ } catch (ClosedChannelException e) { }
}
-
} catch (Exception x) {
Net.translateException(x);
assert false;
@@ -178,8 +193,7 @@
if (!isBound())
return "ServerSocket[unbound]";
return "ServerSocket[addr=" + getInetAddress() +
- // ",port=" + getPort() +
- ",localport=" + getLocalPort() + "]";
+ ",localport=" + getLocalPort() + "]";
}
public void setReceiveBufferSize(int size) throws SocketException {
diff --git a/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
index ee5ff76..563f948 100644
--- a/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
+++ b/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
@@ -48,10 +48,7 @@
// Our file descriptor
private final FileDescriptor fd;
-
- // fd value needed for dev/poll. This value will remain valid
- // even after the value in the file descriptor object has been set to -1
- private int fdVal;
+ private final int fdVal;
// ID of native thread currently blocked in this channel, for signalling
private volatile long thread = 0;
diff --git a/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java b/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java
index d115b7a..c128dc5 100644
--- a/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java
+++ b/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,23 @@
package sun.nio.ch;
-import java.io.*;
-import java.lang.ref.*;
-import java.net.*;
-import java.nio.*;
-import java.nio.channels.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+import java.net.SocketOption;
+import java.net.SocketTimeoutException;
+import java.net.StandardSocketOptions;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.SocketChannel;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.*;
@@ -47,7 +59,7 @@
// java.net.Socket so as to simplify tracking future changes to that class.
//
-public class SocketAdaptor
+class SocketAdaptor
extends Socket
{
@@ -91,7 +103,6 @@
throw new IllegalBlockingModeException();
try {
-
if (timeout == 0) {
sc.connect(remote);
return;
@@ -119,8 +130,9 @@
}
}
} finally {
- if (sc.isOpen())
+ try {
sc.configureBlocking(true);
+ } catch (ClosedChannelException e) { }
}
} catch (Exception x) {
@@ -188,10 +200,11 @@
synchronized (sc.blockingLock()) {
if (!sc.isBlocking())
throw new IllegalBlockingModeException();
+
if (timeout == 0)
return sc.read(bb);
- sc.configureBlocking(false);
+ sc.configureBlocking(false);
try {
int n;
if ((n = sc.read(bb)) != 0)
@@ -211,10 +224,10 @@
throw new SocketTimeoutException();
}
} finally {
- if (sc.isOpen())
+ try {
sc.configureBlocking(true);
+ } catch (ClosedChannelException e) { }
}
-
}
}
}
diff --git a/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java
index 7b694ef..164a165 100644
--- a/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java
+++ b/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java
@@ -50,9 +50,6 @@
// Our file descriptor object
private final FileDescriptor fd;
-
- // fd value needed for dev/poll. This value will remain valid
- // even after the value in the file descriptor object has been set to -1
private final int fdVal;
// IDs of native threads doing reads and writes, for signalling
diff --git a/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java b/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java
index ebe802b..e48ec1d 100644
--- a/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java
+++ b/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java
@@ -25,6 +25,7 @@
package sun.reflect.misc;
+import java.io.EOFException;
import java.security.AllPermission;
import java.security.AccessController;
import java.security.PermissionCollection;
@@ -42,8 +43,8 @@
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
-import sun.misc.IOUtils;
+import sun.misc.IOUtils;
class Trampoline {
static {
@@ -382,15 +383,12 @@
}
}
int len = uc.getContentLength();
- InputStream in = new BufferedInputStream(uc.getInputStream());
-
- byte[] b;
- try {
- b = IOUtils.readFully(in, len, true);
- } finally {
- in.close();
+ try (InputStream in = new BufferedInputStream(uc.getInputStream())) {
+ byte[] b = IOUtils.readAllBytes(in);
+ if (len != -1 && b.length != len)
+ throw new EOFException("Expected:" + len + ", read:" + b.length);
+ return b;
}
- return b;
}
diff --git a/jdk/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java b/jdk/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java
index c0a06f1..2d9102f 100644
--- a/jdk/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java
+++ b/jdk/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java
@@ -27,7 +27,9 @@
package sun.rmi.registry;
import java.io.IOException;
+import java.io.ObjectInputStream;
+import sun.misc.SharedSecrets;
import sun.rmi.transport.StreamRemoteCall;
/**
@@ -83,8 +85,9 @@
java.lang.String $param_String_1;
java.rmi.Remote $param_Remote_2;
try {
- java.io.ObjectInput in = call.getInputStream();
- $param_String_1 = (java.lang.String) in.readObject();
+ ObjectInputStream in = (ObjectInputStream)call.getInputStream();
+ $param_String_1 =
+ SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
$param_Remote_2 = (java.rmi.Remote) in.readObject();
} catch (ClassCastException | IOException | ClassNotFoundException e) {
call.discardPendingRefs();
@@ -118,9 +121,10 @@
{
java.lang.String $param_String_1;
try {
- java.io.ObjectInput in = call.getInputStream();
- $param_String_1 = (java.lang.String) in.readObject();
- } catch (ClassCastException | IOException | ClassNotFoundException e) {
+ ObjectInputStream in = (ObjectInputStream)call.getInputStream();
+ $param_String_1 =
+ SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
+ } catch (ClassCastException | IOException e) {
call.discardPendingRefs();
throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
} finally {
@@ -144,8 +148,9 @@
java.lang.String $param_String_1;
java.rmi.Remote $param_Remote_2;
try {
- java.io.ObjectInput in = call.getInputStream();
- $param_String_1 = (java.lang.String) in.readObject();
+ ObjectInputStream in = (ObjectInputStream)call.getInputStream();
+ $param_String_1 =
+ SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
$param_Remote_2 = (java.rmi.Remote) in.readObject();
} catch (ClassCastException | IOException | java.lang.ClassNotFoundException e) {
call.discardPendingRefs();
@@ -169,9 +174,10 @@
java.lang.String $param_String_1;
try {
- java.io.ObjectInput in = call.getInputStream();
- $param_String_1 = (java.lang.String) in.readObject();
- } catch (ClassCastException | IOException | ClassNotFoundException e) {
+ ObjectInputStream in = (ObjectInputStream)call.getInputStream();
+ $param_String_1 =
+ SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
+ } catch (ClassCastException | IOException e) {
call.discardPendingRefs();
throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
} finally {
diff --git a/jdk/src/share/classes/sun/rmi/server/UnicastRef.java b/jdk/src/share/classes/sun/rmi/server/UnicastRef.java
index 831c41b..b01a2b8 100644
--- a/jdk/src/share/classes/sun/rmi/server/UnicastRef.java
+++ b/jdk/src/share/classes/sun/rmi/server/UnicastRef.java
@@ -27,6 +27,7 @@
import java.io.IOException;
import java.io.ObjectInput;
+import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.lang.reflect.Method;
import java.rmi.MarshalException;
@@ -38,6 +39,8 @@
import java.rmi.server.RemoteObject;
import java.rmi.server.RemoteRef;
import java.security.AccessController;
+
+import sun.misc.SharedSecrets;
import sun.rmi.runtime.Log;
import sun.rmi.transport.Connection;
import sun.rmi.transport.LiveRef;
@@ -318,6 +321,8 @@
} else {
throw new Error("Unrecognized primitive type: " + type);
}
+ } else if (type == String.class && in instanceof ObjectInputStream) {
+ return SharedSecrets.getJavaObjectInputStreamReadString().readString((ObjectInputStream)in);
} else {
return in.readObject();
}
diff --git a/jdk/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java b/jdk/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java
index d733821..0d849ed 100644
--- a/jdk/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java
+++ b/jdk/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.lang.reflect.Proxy;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
@@ -553,6 +554,9 @@
host = in.readUTF();
port = in.readInt();
csf = (RMIClientSocketFactory) in.readObject();
+ if (Proxy.isProxyClass(csf.getClass())) {
+ throw new IOException("Invalid SocketFactory");
+ }
break;
default:
diff --git a/jdk/src/share/classes/sun/security/action/GetPropertyAction.java b/jdk/src/share/classes/sun/security/action/GetPropertyAction.java
index 24ecc91..59bf324 100644
--- a/jdk/src/share/classes/sun/security/action/GetPropertyAction.java
+++ b/jdk/src/share/classes/sun/security/action/GetPropertyAction.java
@@ -108,4 +108,27 @@
new GetPropertyAction(theProp));
}
}
+
+ /**
+ * Convenience method to get a property without going through doPrivileged
+ * if no security manager is present. This is unsafe for inclusion in a
+ * public API but allowable here since this class is now encapsulated.
+ *
+ * Note that this method performs a privileged action using caller-provided
+ * inputs. The caller of this method should take care to ensure that the
+ * inputs are not tainted and the returned property is not made accessible
+ * to untrusted code if it contains sensitive information.
+ *
+ * @param theProp the name of the system property.
+ * @param defaultVal the default value.
+ */
+ public static String privilegedGetProperty(String theProp,
+ String defaultVal) {
+ if (System.getSecurityManager() == null) {
+ return System.getProperty(theProp, defaultVal);
+ } else {
+ return AccessController.doPrivileged(
+ new GetPropertyAction(theProp, defaultVal));
+ }
+ }
}
diff --git a/jdk/src/share/classes/sun/security/ec/CurveDB.java b/jdk/src/share/classes/sun/security/ec/CurveDB.java
index 2bf70d3..cfe56eb 100644
--- a/jdk/src/share/classes/sun/security/ec/CurveDB.java
+++ b/jdk/src/share/classes/sun/security/ec/CurveDB.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,8 @@
import java.util.*;
import java.util.regex.Pattern;
+import sun.security.util.ECUtil;
+
/**
* Repository for well-known Elliptic Curve parameters. It is used by both
* the SunPKCS11 and SunJSSE code.
@@ -104,21 +106,10 @@
if (namedCurve.getCurve().getField().getFieldSize() != fieldSize) {
continue;
}
- if (namedCurve.getCurve().equals(params.getCurve()) == false) {
- continue;
+ if (ECUtil.equals(namedCurve, params)) {
+ // everything matches our named curve, return it
+ return namedCurve;
}
- if (namedCurve.getGenerator().equals(params.getGenerator()) ==
- false) {
- continue;
- }
- if (namedCurve.getOrder().equals(params.getOrder()) == false) {
- continue;
- }
- if (namedCurve.getCofactor() != params.getCofactor()) {
- continue;
- }
- // everything matches our named curve, return it
- return namedCurve;
}
// no match found
return null;
diff --git a/jdk/src/share/classes/sun/security/ec/ECDSASignature.java b/jdk/src/share/classes/sun/security/ec/ECDSASignature.java
index 03aceae..bb50e3a 100644
--- a/jdk/src/share/classes/sun/security/ec/ECDSASignature.java
+++ b/jdk/src/share/classes/sun/security/ec/ECDSASignature.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,7 @@
package sun.security.ec;
-import java.io.IOException;
import java.nio.ByteBuffer;
-import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.*;
@@ -68,6 +66,9 @@
// public key, if initialized for verifying
private ECPublicKey publicKey;
+ // signature parameters
+ private ECParameterSpec sigParams = null;
+
/**
* Constructs a new ECDSASignature. Used by Raw subclass.
*
@@ -198,10 +199,14 @@
@Override
protected void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException {
- this.publicKey = (ECPublicKey) ECKeyFactory.toECKey(publicKey);
+ ECPublicKey key = (ECPublicKey) ECKeyFactory.toECKey(publicKey);
+ if (!isCompatible(this.sigParams, key.getParams())) {
+ throw new InvalidKeyException("Key params does not match signature params");
+ }
// Should check that the supplied key is appropriate for signature
// algorithm (e.g. P-256 for SHA256withECDSA)
+ this.publicKey = key;
this.privateKey = null;
resetDigest();
}
@@ -217,10 +222,14 @@
@Override
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException {
- this.privateKey = (ECPrivateKey) ECKeyFactory.toECKey(privateKey);
+ ECPrivateKey key = (ECPrivateKey) ECKeyFactory.toECKey(privateKey);
+ if (!isCompatible(this.sigParams, key.getParams())) {
+ throw new InvalidKeyException("Key params does not match signature params");
+ }
// Should check that the supplied key is appropriate for signature
// algorithm (e.g. P-256 for SHA256withECDSA)
+ this.privateKey = key;
this.publicKey = null;
this.random = random;
resetDigest();
@@ -273,6 +282,16 @@
needsReset = true;
}
+ private static boolean isCompatible(ECParameterSpec sigParams,
+ ECParameterSpec keyParams) {
+ if (sigParams == null) {
+ // no restriction on key param
+ return true;
+ }
+ return ECUtil.equals(sigParams, keyParams);
+ }
+
+
private byte[] signDigestImpl(ECDSAOperations ops, int seedBits,
byte[] digest, ECPrivateKeyImpl privImpl, SecureRandom random)
throws SignatureException {
@@ -366,7 +385,7 @@
sig = signDigestNative(privateKey, digest, random);
}
- return encodeSignature(sig);
+ return ECUtil.encodeSignature(sig);
}
// verify the data and return the result. See JCA doc
@@ -387,7 +406,8 @@
try {
return verifySignedDigest(
- decodeSignature(signature), getDigestValue(), w, encodedParams);
+ ECUtil.decodeSignature(signature), getDigestValue(),
+ w, encodedParams);
} catch (GeneralSecurityException e) {
throw new SignatureException("Could not verify signature", e);
@@ -402,6 +422,21 @@
throw new UnsupportedOperationException("setParameter() not supported");
}
+ @Override
+ protected void engineSetParameter(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ if (params != null && !(params instanceof ECParameterSpec)) {
+ throw new InvalidAlgorithmParameterException("No parameter accepted");
+ }
+ ECKey key = (this.privateKey == null? this.publicKey : this.privateKey);
+ if ((key != null) && !isCompatible((ECParameterSpec)params, key.getParams())) {
+ throw new InvalidAlgorithmParameterException
+ ("Signature params does not match key params");
+ }
+
+ sigParams = (ECParameterSpec) params;
+ }
+
// get parameter, not supported. See JCA doc
@Override
@Deprecated
@@ -410,79 +445,21 @@
throw new UnsupportedOperationException("getParameter() not supported");
}
- // Convert the concatenation of R and S into their DER encoding
- private byte[] encodeSignature(byte[] signature) throws SignatureException {
-
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ if (sigParams == null) {
+ return null;
+ }
try {
-
- int n = signature.length >> 1;
- byte[] bytes = new byte[n];
- System.arraycopy(signature, 0, bytes, 0, n);
- BigInteger r = new BigInteger(1, bytes);
- System.arraycopy(signature, n, bytes, 0, n);
- BigInteger s = new BigInteger(1, bytes);
-
- DerOutputStream out = new DerOutputStream(signature.length + 10);
- out.putInteger(r);
- out.putInteger(s);
- DerValue result =
- new DerValue(DerValue.tag_Sequence, out.toByteArray());
-
- return result.toByteArray();
-
+ AlgorithmParameters ap = AlgorithmParameters.getInstance("EC");
+ ap.init(sigParams);
+ return ap;
} catch (Exception e) {
- throw new SignatureException("Could not encode signature", e);
+ // should never happen
+ throw new ProviderException("Error retrieving EC parameters", e);
}
}
- // Convert the DER encoding of R and S into a concatenation of R and S
- private byte[] decodeSignature(byte[] sig) throws SignatureException {
-
- try {
- // Enforce strict DER checking for signatures
- DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
- DerValue[] values = in.getSequence(2);
-
- // check number of components in the read sequence
- // and trailing data
- if ((values.length != 2) || (in.available() != 0)) {
- throw new IOException("Invalid encoding for signature");
- }
-
- BigInteger r = values[0].getPositiveBigInteger();
- BigInteger s = values[1].getPositiveBigInteger();
-
- // trim leading zeroes
- byte[] rBytes = trimZeroes(r.toByteArray());
- byte[] sBytes = trimZeroes(s.toByteArray());
- int k = Math.max(rBytes.length, sBytes.length);
- // r and s each occupy half the array
- byte[] result = new byte[k << 1];
- System.arraycopy(rBytes, 0, result, k - rBytes.length,
- rBytes.length);
- System.arraycopy(sBytes, 0, result, result.length - sBytes.length,
- sBytes.length);
- return result;
-
- } catch (Exception e) {
- throw new SignatureException("Invalid encoding for signature", e);
- }
- }
-
- // trim leading (most significant) zeroes from the result
- private static byte[] trimZeroes(byte[] b) {
- int i = 0;
- while ((i < b.length - 1) && (b[i] == 0)) {
- i++;
- }
- if (i == 0) {
- return b;
- }
- byte[] t = new byte[b.length - i];
- System.arraycopy(b, i, t, 0, t.length);
- return t;
- }
-
/**
* Signs the digest using the private key.
*
diff --git a/jdk/src/share/classes/sun/security/jgss/krb5/CipherHelper.java b/jdk/src/share/classes/sun/security/jgss/krb5/CipherHelper.java
index c637b01..0b8adfb 100644
--- a/jdk/src/share/classes/sun/security/jgss/krb5/CipherHelper.java
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/CipherHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,7 @@
import sun.security.krb5.internal.crypto.Aes128;
import sun.security.krb5.internal.crypto.Aes256;
import sun.security.krb5.internal.crypto.ArcFourHmac;
+import sun.security.krb5.internal.crypto.EType;
class CipherHelper {
@@ -77,10 +78,6 @@
private int sgnAlg, sealAlg;
private byte[] keybytes;
- // new token format from draft-ietf-krb-wg-gssapi-cfx-07
- // proto is used to determine new GSS token format for "newer" etypes
- private int proto = 0;
-
CipherHelper(EncryptionKey key) throws GSSException {
etype = key.getEType();
keybytes = key.getBytes();
@@ -106,7 +103,6 @@
case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96:
sgnAlg = -1;
sealAlg = -1;
- proto = 1;
break;
default:
@@ -123,8 +119,10 @@
return sealAlg;
}
+ // new token format from draft-ietf-krb-wg-gssapi-cfx-07
+ // proto is used to determine new GSS token format for "newer" etypes
int getProto() {
- return proto;
+ return EType.isNewer(etype) ? 1 : 0;
}
int getEType() {
diff --git a/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java b/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java
index 0077e7e..1688d5c 100644
--- a/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,8 @@
import org.ietf.jgss.*;
import java.io.InputStream;
import java.io.IOException;
+
+import sun.security.action.GetPropertyAction;
import sun.security.krb5.*;
import java.net.InetAddress;
import sun.security.krb5.internal.AuthorizationData;
@@ -36,6 +38,33 @@
class InitSecContextToken extends InitialToken {
+ // If non-mutual authentication is requested, there is no AP-REP message.
+ // The acceptor thus has no chance to send the seq-number field to the
+ // initiator. In this case, the initiator and acceptor should has an
+ // agreement to derive acceptor's initial seq-number if the acceptor wishes
+ // to send messages to the initiator.
+
+ // If this flag is true, it will the same as the initiator's initial
+ // seq-number (as MIT krb5 and Windows SSPI do). Otherwise, it will be zero
+ // (as Heimdal does). The default value is true.
+ private static final boolean ACCEPTOR_USE_INITIATOR_SEQNUM;
+
+ static {
+ // The ACCEPTOR_USE_INITIATOR_SEQNUM value is determined by the system
+ // property "sun.security.krb5.acceptor.sequence.number.nonmutual",
+ // which can be set to "initiator", "zero" or "0".
+ String propName = "sun.security.krb5.acceptor.sequence.number.nonmutual";
+ String s = GetPropertyAction.privilegedGetProperty(propName, "initiator");
+ if (s.equals("initiator")) {
+ ACCEPTOR_USE_INITIATOR_SEQNUM = true;
+ } else if (s.equals("zero") || s.equals("0")) {
+ ACCEPTOR_USE_INITIATOR_SEQNUM = false;
+ } else {
+ throw new AssertionError("Unrecognized value for " + propName
+ + ": " + s);
+ }
+ }
+
private KrbApReq apReq = null;
/**
@@ -79,7 +108,10 @@
context.setKey(Krb5Context.SESSION_KEY, serviceTicket.getSessionKey());
if (!mutualRequired)
- context.resetPeerSequenceNumber(0);
+ context.resetPeerSequenceNumber(
+ ACCEPTOR_USE_INITIATOR_SEQNUM
+ ? apReq.getSeqNumber().intValue()
+ : 0);
}
/**
@@ -144,10 +176,12 @@
apReqSeqNumber.intValue() :
0);
context.resetPeerSequenceNumber(peerSeqNumber);
- if (!context.getMutualAuthState())
- // Use the same sequence number as the peer
- // (Behaviour exhibited by the Windows SSPI server)
- context.resetMySequenceNumber(peerSeqNumber);
+ if (!context.getMutualAuthState()) {
+ context.resetMySequenceNumber(
+ ACCEPTOR_USE_INITIATOR_SEQNUM
+ ? peerSeqNumber
+ : 0);
+ }
context.setAuthTime(
new KerberosTime(apReq.getCreds().getAuthTime()).toString());
context.setTktFlags(apReq.getCreds().getFlags());
diff --git a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java
index a0658d0..e9ee13d 100644
--- a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java
@@ -713,14 +713,14 @@
if (subject != null &&
!subject.isReadOnly()) {
/*
- * Store the service credentials as
- * javax.security.auth.kerberos.KerberosTicket in
- * the Subject. We could wait till the context is
- * succesfully established; however it is easier
- * to do here and there is no harm indoing it here.
- */
+ * Store the service credentials as
+ * javax.security.auth.kerberos.KerberosTicket in
+ * the Subject. We could wait until the context is
+ * successfully established; however it is easier
+ * to do it here and there is no harm.
+ */
final KerberosTicket kt =
- Krb5Util.credsToTicket(serviceCreds);
+ Krb5Util.credsToTicket(serviceCreds);
AccessController.doPrivileged (
new java.security.PrivilegedAction<Void>() {
public Void run() {
diff --git a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java
index daefbbc..314cabb 100644
--- a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java
@@ -60,7 +60,9 @@
private Krb5InitCredential(Krb5NameElement name,
byte[] asn1Encoding,
KerberosPrincipal client,
+ KerberosPrincipal clientAlias,
KerberosPrincipal server,
+ KerberosPrincipal serverAlias,
byte[] sessionKey,
int keyType,
boolean[] flags,
@@ -81,14 +83,21 @@
endTime,
renewTill,
clientAddresses);
-
+ KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
+ .kerberosTicketSetClientAlias(this, clientAlias);
+ KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
+ .kerberosTicketSetServerAlias(this, serverAlias);
this.name = name;
try {
// Cache this for later use by the sun.security.krb5 package.
krb5Credentials = new Credentials(asn1Encoding,
client.getName(),
+ (clientAlias != null ?
+ clientAlias.getName() : null),
server.getName(),
+ (serverAlias != null ?
+ serverAlias.getName() : null),
sessionKey,
keyType,
flags,
@@ -111,7 +120,9 @@
Credentials delegatedCred,
byte[] asn1Encoding,
KerberosPrincipal client,
+ KerberosPrincipal clientAlias,
KerberosPrincipal server,
+ KerberosPrincipal serverAlias,
byte[] sessionKey,
int keyType,
boolean[] flags,
@@ -132,7 +143,10 @@
endTime,
renewTill,
clientAddresses);
-
+ KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
+ .kerberosTicketSetClientAlias(this, clientAlias);
+ KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
+ .kerberosTicketSetServerAlias(this, serverAlias);
this.name = name;
// A delegated cred does not have all fields set. So do not try to
// creat new Credentials out of the delegatedCred.
@@ -154,10 +168,18 @@
Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);
}
+ KerberosPrincipal clientAlias = KerberosSecrets
+ .getJavaxSecurityAuthKerberosAccess()
+ .kerberosTicketGetClientAlias(tgt);
+ KerberosPrincipal serverAlias = KerberosSecrets
+ .getJavaxSecurityAuthKerberosAccess()
+ .kerberosTicketGetServerAlias(tgt);
Krb5InitCredential result = new Krb5InitCredential(name,
tgt.getEncoded(),
tgt.getClient(),
+ clientAlias,
tgt.getServer(),
+ serverAlias,
tgt.getSessionKey().getEncoded(),
tgt.getSessionKeyType(),
tgt.getFlags(),
@@ -183,10 +205,14 @@
*/
PrincipalName cPrinc = delegatedCred.getClient();
+ PrincipalName cAPrinc = delegatedCred.getClientAlias();
PrincipalName sPrinc = delegatedCred.getServer();
+ PrincipalName sAPrinc = delegatedCred.getServerAlias();
KerberosPrincipal client = null;
+ KerberosPrincipal clientAlias = null;
KerberosPrincipal server = null;
+ KerberosPrincipal serverAlias = null;
Krb5NameElement credName = null;
@@ -197,6 +223,10 @@
client = new KerberosPrincipal(fullName);
}
+ if (cAPrinc != null) {
+ clientAlias = new KerberosPrincipal(cAPrinc.getName());
+ }
+
// XXX Compare name to credName
if (sPrinc != null) {
@@ -205,11 +235,17 @@
KerberosPrincipal.KRB_NT_SRV_INST);
}
+ if (sAPrinc != null) {
+ serverAlias = new KerberosPrincipal(sAPrinc.getName());
+ }
+
return new Krb5InitCredential(credName,
delegatedCred,
delegatedCred.getEncoded(),
client,
+ clientAlias,
server,
+ serverAlias,
sessionKey.getBytes(),
sessionKey.getEType(),
delegatedCred.getFlags(),
diff --git a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Util.java b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Util.java
index 8f79df1..387edd7 100644
--- a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Util.java
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Util.java
@@ -228,7 +228,7 @@
public static KerberosTicket credsToTicket(Credentials serviceCreds) {
EncryptionKey sessionKey = serviceCreds.getSessionKey();
- return new KerberosTicket(
+ KerberosTicket kt = new KerberosTicket(
serviceCreds.getEncoded(),
new KerberosPrincipal(serviceCreds.getClient().getName()),
new KerberosPrincipal(serviceCreds.getServer().getName(),
@@ -241,14 +241,35 @@
serviceCreds.getEndTime(),
serviceCreds.getRenewTill(),
serviceCreds.getClientAddresses());
+ PrincipalName clientAlias = serviceCreds.getClientAlias();
+ PrincipalName serverAlias = serviceCreds.getServerAlias();
+ if (clientAlias != null) {
+ KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
+ .kerberosTicketSetClientAlias(kt, new KerberosPrincipal(
+ clientAlias.getName(), clientAlias.getNameType()));
+ }
+ if (serverAlias != null) {
+ KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
+ .kerberosTicketSetServerAlias(kt, new KerberosPrincipal(
+ serverAlias.getName(), serverAlias.getNameType()));
+ }
+ return kt;
};
public static Credentials ticketToCreds(KerberosTicket kerbTicket)
throws KrbException, IOException {
+ KerberosPrincipal clientAlias = KerberosSecrets
+ .getJavaxSecurityAuthKerberosAccess()
+ .kerberosTicketGetClientAlias(kerbTicket);
+ KerberosPrincipal serverAlias = KerberosSecrets
+ .getJavaxSecurityAuthKerberosAccess()
+ .kerberosTicketGetServerAlias(kerbTicket);
return new Credentials(
kerbTicket.getEncoded(),
kerbTicket.getClient().getName(),
+ (clientAlias != null ? clientAlias.getName() : null),
kerbTicket.getServer().getName(),
+ (serverAlias != null ? serverAlias.getName() : null),
kerbTicket.getSessionKey().getEncoded(),
kerbTicket.getSessionKeyType(),
kerbTicket.getFlags(),
diff --git a/jdk/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java b/jdk/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java
index 7d293ce..808c201 100644
--- a/jdk/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -499,11 +499,11 @@
*/
class MessageTokenHeader {
- private int tokenId;
- private byte[] bytes = new byte[TOKEN_HEADER_SIZE];
+ private int tokenId;
+ private byte[] bytes = new byte[TOKEN_HEADER_SIZE];
- // Writes a new token header
- public MessageTokenHeader(int tokenId, boolean conf) throws GSSException {
+ // Writes a new token header
+ public MessageTokenHeader(int tokenId, boolean conf) throws GSSException {
this.tokenId = tokenId;
@@ -609,7 +609,7 @@
prop.setQOP(0);
// sequence number
- seqNumber = readBigEndian(bytes, 0, 8);
+ seqNumber = readBigEndian(bytes, 12, 4);
}
/**
diff --git a/jdk/src/share/classes/sun/security/jgss/krb5/SubjectComber.java b/jdk/src/share/classes/sun/security/jgss/krb5/SubjectComber.java
index a7100f0..1bc1bf7 100644
--- a/jdk/src/share/classes/sun/security/jgss/krb5/SubjectComber.java
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/SubjectComber.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
package sun.security.jgss.krb5;
+import sun.security.krb5.KerberosSecrets;
+
import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.kerberos.KerberosKey;
import javax.security.auth.Subject;
@@ -182,24 +184,45 @@
}
} else {
+ KerberosPrincipal serverAlias = KerberosSecrets
+ .getJavaxSecurityAuthKerberosAccess()
+ .kerberosTicketGetServerAlias(ticket);
if (serverPrincipal == null ||
- ticket.getServer().getName().equals(serverPrincipal)) {
-
+ ticket.getServer().getName().equals(serverPrincipal) ||
+ (serverAlias != null &&
+ serverPrincipal.equals(
+ serverAlias.getName()))) {
+ KerberosPrincipal clientAlias = KerberosSecrets
+ .getJavaxSecurityAuthKerberosAccess()
+ .kerberosTicketGetClientAlias(ticket);
if (clientPrincipal == null ||
clientPrincipal.equals(
- ticket.getClient().getName())) {
+ ticket.getClient().getName()) ||
+ (clientAlias != null &&
+ clientPrincipal.equals(
+ clientAlias.getName()))) {
if (oneOnly) {
return ticket;
} else {
// Record names so that tickets will
// all belong to same principals
if (clientPrincipal == null) {
- clientPrincipal =
- ticket.getClient().getName();
+ if (clientAlias == null) {
+ clientPrincipal =
+ ticket.getClient().getName();
+ } else {
+ clientPrincipal =
+ clientAlias.getName();
+ }
}
if (serverPrincipal == null) {
- serverPrincipal =
- ticket.getServer().getName();
+ if (serverAlias == null) {
+ serverPrincipal =
+ ticket.getServer().getName();
+ } else {
+ serverPrincipal =
+ serverAlias.getName();
+ }
}
answer.add(credClass.cast(ticket));
}
diff --git a/jdk/src/share/classes/sun/security/krb5/Checksum.java b/jdk/src/share/classes/sun/security/krb5/Checksum.java
index 6a7f491..92a5de8 100644
--- a/jdk/src/share/classes/sun/security/krb5/Checksum.java
+++ b/jdk/src/share/classes/sun/security/krb5/Checksum.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -69,6 +69,7 @@
// draft-brezak-win2k-krb-rc4-hmac-04.txt
public static final int CKSUMTYPE_HMAC_MD5_ARCFOUR = -138;
+ // default checksum type, -1 if not set
static int CKSUMTYPE_DEFAULT;
static int SAFECKSUMTYPE_DEFAULT;
@@ -83,26 +84,19 @@
try {
cfg = Config.getInstance();
temp = cfg.get("libdefaults", "default_checksum");
- if (temp != null)
- {
- CKSUMTYPE_DEFAULT = Config.getType(temp);
- } else {
- /*
- * If the default checksum is not
- * specified in the configuration we
- * set it to RSA_MD5. We follow the MIT and
- * SEAM implementation.
- */
- CKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5;
- }
+ if (temp != null) {
+ CKSUMTYPE_DEFAULT = Config.getType(temp);
+ } else {
+ CKSUMTYPE_DEFAULT = -1;
+ }
} catch (Exception exc) {
if (DEBUG) {
System.out.println("Exception in getting default checksum "+
- "value from the configuration " +
- "Setting default checksum to be RSA-MD5");
+ "value from the configuration. " +
+ "No default checksum set.");
exc.printStackTrace();
}
- CKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5;
+ CKSUMTYPE_DEFAULT = -1;
}
@@ -112,97 +106,100 @@
{
SAFECKSUMTYPE_DEFAULT = Config.getType(temp);
} else {
- SAFECKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5_DES;
+ SAFECKSUMTYPE_DEFAULT = -1;
}
} catch (Exception exc) {
if (DEBUG) {
System.out.println("Exception in getting safe default " +
"checksum value " +
- "from the configuration Setting " +
- "safe default checksum to be RSA-MD5");
+ "from the configuration Setting. " +
+ "No safe default checksum set.");
exc.printStackTrace();
}
- SAFECKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5_DES;
+ SAFECKSUMTYPE_DEFAULT = -1;
}
}
/**
* Constructs a new Checksum using the raw data and type.
+ *
+ * This constructor is only used by Authenticator Checksum
+ * {@link sun.security.jgss.krb5.InitialToken.OverloadedChecksum}
+ * where the checksum type must be 0x8003
+ * (see https://tools.ietf.org/html/rfc4121#section-4.1.1)
+ * and checksum field/value is used to convey service flags,
+ * channel bindings, and optional delegation information.
+ * This special type does NOT have a {@link CksumType} and has its
+ * own calculating and verification rules. It does has the same
+ * ASN.1 encoding though.
+ *
* @data the byte array of checksum.
* @new_cksumType the type of checksum.
- *
*/
- // used in InitialToken
public Checksum(byte[] data, int new_cksumType) {
cksumType = new_cksumType;
checksum = data;
}
/**
- * Constructs a new Checksum by calculating the checksum over the data
- * using specified checksum type.
- * @new_cksumType the type of checksum.
- * @data the data that needs to be performed a checksum calculation on.
+ * Constructs a new Checksum by calculating over the data using
+ * the specified checksum type. If the checksum is unkeyed, key
+ * and usage are ignored.
+ *
+ * @param new_cksumType the type of checksum. If set to -1, the
+ * {@linkplain EType#checksumType() mandatory checksum type}
+ * for the encryption type of {@code key} will be used
+ * @param data the data that needs to be performed a checksum calculation on
+ * @param key the key used by a keyed checksum
+ * @param usage the usage used by a keyed checksum
*/
- public Checksum(int new_cksumType, byte[] data)
- throws KdcErrException, KrbCryptoException {
-
- cksumType = new_cksumType;
- CksumType cksumEngine = CksumType.getInstance(cksumType);
- if (!cksumEngine.isSafe()) {
- checksum = cksumEngine.calculateChecksum(data, data.length);
- } else {
- throw new KdcErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
- }
- }
-
- /**
- * Constructs a new Checksum by calculating the keyed checksum
- * over the data using specified checksum type.
- * @new_cksumType the type of checksum.
- * @data the data that needs to be performed a checksum calculation on.
- */
- // KrbSafe, KrbTgsReq
public Checksum(int new_cksumType, byte[] data,
- EncryptionKey key, int usage)
- throws KdcErrException, KrbApErrException, KrbCryptoException {
- cksumType = new_cksumType;
- CksumType cksumEngine = CksumType.getInstance(cksumType);
- if (!cksumEngine.isSafe())
- throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
- checksum =
- cksumEngine.calculateKeyedChecksum(data,
- data.length,
- key.getBytes(),
- usage);
+ EncryptionKey key, int usage)
+ throws KdcErrException, KrbApErrException, KrbCryptoException {
+ if (new_cksumType == -1) {
+ cksumType = EType.getInstance(key.getEType()).checksumType();
+ } else {
+ cksumType = new_cksumType;
+ }
+ checksum = CksumType.getInstance(cksumType).calculateChecksum(
+ data, data.length, key.getBytes(), usage);
}
/**
* Verifies the keyed checksum over the data passed in.
*/
- public boolean verifyKeyedChecksum(byte[] data, EncryptionKey key,
- int usage)
- throws KdcErrException, KrbApErrException, KrbCryptoException {
+ public boolean verifyKeyedChecksum(byte[] data, EncryptionKey key, int usage)
+ throws KdcErrException, KrbApErrException, KrbCryptoException {
CksumType cksumEngine = CksumType.getInstance(cksumType);
- if (!cksumEngine.isSafe())
+ if (!cksumEngine.isKeyed()) {
throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
- return cksumEngine.verifyKeyedChecksum(data,
- data.length,
- key.getBytes(),
- checksum,
- usage);
+ } else {
+ return cksumEngine.verifyChecksum(
+ data, data.length, key.getBytes(), checksum, usage);
+ }
}
- /*
- public Checksum(byte[] data) throws KdcErrException, KrbCryptoException {
- this(Checksum.CKSUMTYPE_DEFAULT, data);
+
+ /**
+ * Verifies the checksum over the data passed in. The checksum might
+ * be a keyed or not.
+ *
+ * =============== ATTENTION! Use with care ==================
+ * According to https://tools.ietf.org/html/rfc3961#section-6.1,
+ * An unkeyed checksum should only be used "in limited circumstances
+ * where the lack of a key does not provide a window for an attack,
+ * preferably as part of an encrypted message".
+ */
+ public boolean verifyAnyChecksum(byte[] data, EncryptionKey key, int usage)
+ throws KdcErrException, KrbCryptoException {
+ return CksumType.getInstance(cksumType).verifyChecksum(
+ data, data.length, key.getBytes(), checksum, usage);
}
- */
boolean isEqual(Checksum cksum) throws KdcErrException {
- if (cksumType != cksum.cksumType)
+ if (cksumType != cksum.cksumType) {
return false;
- CksumType cksumEngine = CksumType.getInstance(cksumType);
+ }
return CksumType.isChecksumEqual(checksum, cksum.checksum);
}
@@ -214,7 +211,7 @@
* @exception IOException if an I/O error occurs while reading encoded data.
*
*/
- private Checksum(DerValue encoding) throws Asn1Exception, IOException {
+ public Checksum(DerValue encoding) throws Asn1Exception, IOException {
DerValue der;
if (encoding.getTag() != DerValue.tag_Sequence) {
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
diff --git a/jdk/src/share/classes/sun/security/krb5/Config.java b/jdk/src/share/classes/sun/security/krb5/Config.java
index 7ee9231..fe6565c 100644
--- a/jdk/src/share/classes/sun/security/krb5/Config.java
+++ b/jdk/src/share/classes/sun/security/krb5/Config.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,25 +30,24 @@
*/
package sun.security.krb5;
-import java.io.File;
-import java.io.FileInputStream;
-import java.util.Hashtable;
-import java.util.Vector;
-import java.util.ArrayList;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.io.IOException;
-import java.util.StringTokenizer;
+import java.io.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import sun.net.dns.ResolverConfiguration;
import sun.security.krb5.internal.crypto.EType;
import sun.security.krb5.internal.Krb5;
+import sun.security.util.SecurityProperties;
/**
* This class maintains key-value pairs of Kerberos configurable constants
@@ -57,6 +56,41 @@
public class Config {
+ /**
+ * {@systemProperty sun.security.krb5.disableReferrals} property
+ * indicating whether or not cross-realm referrals (RFC 6806) are
+ * enabled.
+ */
+ public static final boolean DISABLE_REFERRALS;
+
+ /**
+ * {@systemProperty sun.security.krb5.maxReferrals} property
+ * indicating the maximum number of cross-realm referral
+ * hops allowed.
+ */
+ public static final int MAX_REFERRALS;
+
+ static {
+ String disableReferralsProp =
+ SecurityProperties.privilegedGetOverridable(
+ "sun.security.krb5.disableReferrals");
+ if (disableReferralsProp != null) {
+ DISABLE_REFERRALS = "true".equalsIgnoreCase(disableReferralsProp);
+ } else {
+ DISABLE_REFERRALS = false;
+ }
+
+ int maxReferralsValue = 5;
+ String maxReferralsProp =
+ SecurityProperties.privilegedGetOverridable(
+ "sun.security.krb5.maxReferrals");
+ try {
+ maxReferralsValue = Integer.parseInt(maxReferralsProp);
+ } catch (NumberFormatException e) {
+ }
+ MAX_REFERRALS = maxReferralsValue;
+ }
+
/*
* Only allow a single instance of Config.
*/
@@ -257,7 +291,11 @@
}
/**
- * Gets all values for the specified keys.
+ * Gets all values (at least one) for the specified keys separated by
+ * a whitespace, or null if there is no such keys.
+ * The values can either be provided on a single line, or on multiple lines
+ * using the same key. When provided on a single line, the value can be
+ * comma or space separated.
* @throws IllegalArgumentException if any of the keys is illegal
* (See {@link #get})
*/
@@ -267,6 +305,7 @@
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String s: v) {
+ s = s.replaceAll("[\\s,]+", " ");
if (first) {
sb.append(s);
first = false;
@@ -314,6 +353,72 @@
}
/**
+ * Translates a duration value into seconds.
+ *
+ * The format can be one of "h:m[:s]", "NdNhNmNs", and "N". See
+ * http://web.mit.edu/kerberos/krb5-devel/doc/basic/date_format.html#duration
+ * for definitions.
+ *
+ * @param s the string duration
+ * @return time in seconds
+ * @throw KrbException if format is illegal
+ */
+ public static int duration(String s) throws KrbException {
+
+ if (s.isEmpty()) {
+ throw new KrbException("Duration cannot be empty");
+ }
+
+ // N
+ if (s.matches("\\d+")) {
+ return Integer.parseInt(s);
+ }
+
+ // h:m[:s]
+ Matcher m = Pattern.compile("(\\d+):(\\d+)(:(\\d+))?").matcher(s);
+ if (m.matches()) {
+ int hr = Integer.parseInt(m.group(1));
+ int min = Integer.parseInt(m.group(2));
+ if (min >= 60) {
+ throw new KrbException("Illegal duration format " + s);
+ }
+ int result = hr * 3600 + min * 60;
+ if (m.group(4) != null) {
+ int sec = Integer.parseInt(m.group(4));
+ if (sec >= 60) {
+ throw new KrbException("Illegal duration format " + s);
+ }
+ result += sec;
+ }
+ return result;
+ }
+
+ // NdNhNmNs
+ // 120m allowed. Maybe 1h120m is not good, but still allowed
+ m = Pattern.compile(
+ "((\\d+)d)?\\s*((\\d+)h)?\\s*((\\d+)m)?\\s*((\\d+)s)?",
+ Pattern.CASE_INSENSITIVE).matcher(s);
+ if (m.matches()) {
+ int result = 0;
+ if (m.group(2) != null) {
+ result += 86400 * Integer.parseInt(m.group(2));
+ }
+ if (m.group(4) != null) {
+ result += 3600 * Integer.parseInt(m.group(4));
+ }
+ if (m.group(6) != null) {
+ result += 60 * Integer.parseInt(m.group(6));
+ }
+ if (m.group(8) != null) {
+ result += Integer.parseInt(m.group(8));
+ }
+ return result;
+ }
+
+ throw new KrbException("Illegal duration format " + s);
+ }
+
+ /**
* Gets the int value for the specified keys.
* @param keys the keys
* @return the int value, Integer.MIN_VALUE is returned if it cannot be
diff --git a/jdk/src/share/classes/sun/security/krb5/Credentials.java b/jdk/src/share/classes/sun/security/krb5/Credentials.java
index 3fe2953..b364a62 100644
--- a/jdk/src/share/classes/sun/security/krb5/Credentials.java
+++ b/jdk/src/share/classes/sun/security/krb5/Credentials.java
@@ -48,7 +48,9 @@
Ticket ticket;
PrincipalName client;
+ PrincipalName clientAlias;
PrincipalName server;
+ PrincipalName serverAlias;
EncryptionKey key;
TicketFlags flags;
KerberosTime authTime;
@@ -78,7 +80,9 @@
public Credentials(Ticket new_ticket,
PrincipalName new_client,
+ PrincipalName new_client_alias,
PrincipalName new_server,
+ PrincipalName new_server_alias,
EncryptionKey new_key,
TicketFlags new_flags,
KerberosTime authTime,
@@ -87,14 +91,17 @@
KerberosTime renewTill,
HostAddresses cAddr,
AuthorizationData authzData) {
- this(new_ticket, new_client, new_server, new_key, new_flags,
- authTime, new_startTime, new_endTime, renewTill, cAddr);
+ this(new_ticket, new_client, new_client_alias, new_server,
+ new_server_alias, new_key, new_flags, authTime,
+ new_startTime, new_endTime, renewTill, cAddr);
this.authzData = authzData;
}
public Credentials(Ticket new_ticket,
PrincipalName new_client,
+ PrincipalName new_client_alias,
PrincipalName new_server,
+ PrincipalName new_server_alias,
EncryptionKey new_key,
TicketFlags new_flags,
KerberosTime authTime,
@@ -104,7 +111,9 @@
HostAddresses cAddr) {
ticket = new_ticket;
client = new_client;
+ clientAlias = new_client_alias;
server = new_server;
+ serverAlias = new_server_alias;
key = new_key;
flags = new_flags;
this.authTime = authTime;
@@ -116,7 +125,9 @@
public Credentials(byte[] encoding,
String client,
+ String clientAlias,
String server,
+ String serverAlias,
byte[] keyBytes,
int keyType,
boolean[] flags,
@@ -127,7 +138,11 @@
InetAddress[] cAddrs) throws KrbException, IOException {
this(new Ticket(encoding),
new PrincipalName(client, PrincipalName.KRB_NT_PRINCIPAL),
+ (clientAlias == null? null : new PrincipalName(clientAlias,
+ PrincipalName.KRB_NT_PRINCIPAL)),
new PrincipalName(server, PrincipalName.KRB_NT_SRV_INST),
+ (serverAlias == null? null : new PrincipalName(serverAlias,
+ PrincipalName.KRB_NT_SRV_INST)),
new EncryptionKey(keyType, keyBytes),
(flags == null? null: new TicketFlags(flags)),
(authTime == null? null: new KerberosTime(authTime)),
@@ -152,10 +167,18 @@
return client;
}
+ public final PrincipalName getClientAlias() {
+ return clientAlias;
+ }
+
public final PrincipalName getServer() {
return server;
}
+ public final PrincipalName getServerAlias() {
+ return serverAlias;
+ }
+
public final EncryptionKey getSessionKey() {
return key;
}
@@ -271,6 +294,7 @@
return new KrbTgsReq(options,
this,
server,
+ serverAlias,
null, // from
null, // till
null, // rtime
@@ -488,7 +512,11 @@
public static void printDebug(Credentials c) {
System.out.println(">>> DEBUG: ----Credentials----");
System.out.println("\tclient: " + c.client.toString());
+ if (c.clientAlias != null)
+ System.out.println("\tclient alias: " + c.clientAlias.toString());
System.out.println("\tserver: " + c.server.toString());
+ if (c.serverAlias != null)
+ System.out.println("\tserver alias: " + c.serverAlias.toString());
System.out.println("\tticket: sname: " + c.ticket.sname.toString());
if (c.startTime != null) {
System.out.println("\tstartTime: " + c.startTime.getTime());
@@ -516,7 +544,11 @@
public String toString() {
StringBuffer buffer = new StringBuffer("Credentials:");
buffer.append( "\n client=").append(client);
+ if (clientAlias != null)
+ buffer.append( "\n clientAlias=").append(clientAlias);
buffer.append( "\n server=").append(server);
+ if (serverAlias != null)
+ buffer.append( "\n serverAlias=").append(serverAlias);
if (authTime != null) {
buffer.append("\n authTime=").append(authTime);
}
@@ -531,4 +563,23 @@
return buffer.toString();
}
+ public sun.security.krb5.internal.ccache.Credentials toCCacheCreds() {
+ return new sun.security.krb5.internal.ccache.Credentials(
+ getClient(), getServer(),
+ getSessionKey(),
+ date2kt(getAuthTime()),
+ date2kt(getStartTime()),
+ date2kt(getEndTime()),
+ date2kt(getRenewTill()),
+ false,
+ flags,
+ new HostAddresses(getClientAddresses()),
+ getAuthzData(),
+ getTicket(),
+ null);
+ }
+
+ private static KerberosTime date2kt(Date d) {
+ return d == null ? null : new KerberosTime(d);
+ }
}
diff --git a/jdk/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java b/jdk/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java
index 84ca79b..7d1ebd4 100644
--- a/jdk/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java
+++ b/jdk/src/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java
@@ -25,6 +25,7 @@
package sun.security.krb5;
+import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.kerberos.KeyTab;
@@ -39,6 +40,14 @@
public sun.security.krb5.internal.ktab.KeyTab keyTabTakeSnapshot(
KeyTab ktab);
+ public KerberosPrincipal kerberosTicketGetClientAlias(KerberosTicket t);
+
+ public void kerberosTicketSetClientAlias(KerberosTicket t, KerberosPrincipal a);
+
+ public KerberosPrincipal kerberosTicketGetServerAlias(KerberosTicket t);
+
+ public void kerberosTicketSetServerAlias(KerberosTicket t, KerberosPrincipal a);
+
/**
* Returns the proxy for a KerberosTicket.
*/
diff --git a/jdk/src/share/classes/sun/security/krb5/KrbApReq.java b/jdk/src/share/classes/sun/security/krb5/KrbApReq.java
index fbd0557..e36aeac 100644
--- a/jdk/src/share/classes/sun/security/krb5/KrbApReq.java
+++ b/jdk/src/share/classes/sun/security/krb5/KrbApReq.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -361,7 +361,9 @@
creds = new Credentials(
apReqMessg.ticket,
authenticator.cname,
+ null,
apReqMessg.ticket.sname,
+ null,
enc_ticketPart.key,
enc_ticketPart.flags,
enc_ticketPart.authtime,
diff --git a/jdk/src/share/classes/sun/security/krb5/KrbAsRep.java b/jdk/src/share/classes/sun/security/krb5/KrbAsRep.java
index b03276f..202e86c 100644
--- a/jdk/src/share/classes/sun/security/krb5/KrbAsRep.java
+++ b/jdk/src/share/classes/sun/security/krb5/KrbAsRep.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -118,7 +118,7 @@
"Cannot find key for type/kvno to decrypt AS REP - " +
EType.toString(encPartKeyType) + "/" + encPartKvno);
}
- decrypt(dkey, asReq);
+ decrypt(dkey, asReq, cname);
}
/**
@@ -136,7 +136,7 @@
password,
encPartKeyType,
PAData.getSaltAndParams(encPartKeyType, rep.pAData));
- decrypt(dkey, asReq);
+ decrypt(dkey, asReq, cname);
}
/**
@@ -144,7 +144,8 @@
* @param dkey the decryption key to use
* @param asReq the original AS-REQ sent, used to validate AS-REP
*/
- private void decrypt(EncryptionKey dkey, KrbAsReq asReq)
+ private void decrypt(EncryptionKey dkey, KrbAsReq asReq,
+ PrincipalName cname)
throws KrbException, Asn1Exception, IOException {
byte[] enc_as_rep_bytes = rep.encPart.decrypt(dkey,
KeyUsage.KU_ENC_AS_REP_PART);
@@ -155,12 +156,18 @@
rep.encKDCRepPart = enc_part;
ASReq req = asReq.getMessage();
- check(true, req, rep);
+ check(true, req, rep, dkey);
+
+ PrincipalName clientAlias = cname;
+ if (clientAlias.equals(rep.cname))
+ clientAlias = null;
creds = new Credentials(
rep.ticket,
- req.reqBody.cname,
+ rep.cname,
+ clientAlias,
enc_part.sname,
+ null, // No server alias expected in a TGT
enc_part.key,
enc_part.flags,
enc_part.authtime,
diff --git a/jdk/src/share/classes/sun/security/krb5/KrbAsReq.java b/jdk/src/share/classes/sun/security/krb5/KrbAsReq.java
index 8de29b3..19e3ef6 100644
--- a/jdk/src/share/classes/sun/security/krb5/KrbAsReq.java
+++ b/jdk/src/share/classes/sun/security/krb5/KrbAsReq.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -35,6 +35,8 @@
import sun.security.krb5.internal.crypto.Nonce;
import sun.security.krb5.internal.crypto.KeyUsage;
import java.io.IOException;
+import java.time.Instant;
+import java.util.Arrays;
/**
* This class encapsulates the KRB-AS-REQ message that the client
@@ -57,14 +59,14 @@
KerberosTime till, // ok, will use
KerberosTime rtime, // ok
int[] eTypes, // NO
- HostAddresses addresses // ok
+ HostAddresses addresses, // ok
+ PAData[] extraPAs // ok
)
throws KrbException, IOException {
if (options == null) {
options = new KDCOptions();
}
-
// check if they are valid arguments. The optional fields should be
// consistent with settings in KDCOptions. Mar 17 2000
if (options.get(KDCOptions.FORWARDED) ||
@@ -82,12 +84,6 @@
} else {
if (from != null) from = null;
}
- if (options.get(KDCOptions.RENEWABLE)) {
- // if (rtime == null)
- // throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
- } else {
- if (rtime != null) rtime = null;
- }
PAData[] paData = null;
if (pakey != null) {
@@ -99,6 +95,15 @@
paData[0] = new PAData( Krb5.PA_ENC_TIMESTAMP,
encTs.asn1Encode());
}
+ if (extraPAs != null && extraPAs.length > 0) {
+ if (paData == null) {
+ paData = new PAData[extraPAs.length];
+ } else {
+ paData = Arrays.copyOf(paData, paData.length + extraPAs.length);
+ }
+ System.arraycopy(extraPAs, 0, paData,
+ paData.length - extraPAs.length, extraPAs.length);
+ }
if (cname.getRealm() == null) {
throw new RealmException(Krb5.REALM_NULL,
@@ -109,8 +114,10 @@
System.out.println(">>> KrbAsReq creating message");
}
+ Config cfg = Config.getInstance();
+
// check to use addresses in tickets
- if (addresses == null && Config.getInstance().useAddresses()) {
+ if (addresses == null && cfg.useAddresses()) {
addresses = HostAddresses.getLocalAddresses();
}
@@ -120,7 +127,26 @@
}
if (till == null) {
- till = new KerberosTime(0); // Choose KDC maximum allowed
+ String d = cfg.get("libdefaults", "ticket_lifetime");
+ if (d != null) {
+ till = new KerberosTime(Instant.now().plusSeconds(Config.duration(d)));
+ } else {
+ till = new KerberosTime(0); // Choose KDC maximum allowed
+ }
+ }
+
+ if (rtime == null) {
+ String d = cfg.get("libdefaults", "renew_lifetime");
+ if (d != null) {
+ rtime = new KerberosTime(Instant.now().plusSeconds(Config.duration(d)));
+ }
+ }
+
+ if (rtime != null) {
+ options.set(KDCOptions.RENEWABLE, true);
+ if (till.greaterThan(rtime)) {
+ rtime = till;
+ }
}
// enc-authorization-data and additional-tickets never in AS-REQ
diff --git a/jdk/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java b/jdk/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java
index 3c8fb90..445fa19 100644
--- a/jdk/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java
+++ b/jdk/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, 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
@@ -68,6 +68,7 @@
// Common data for AS-REQ fields
private KDCOptions options;
private PrincipalName cname;
+ private PrincipalName refCname; // May be changed by referrals
private PrincipalName sname;
private KerberosTime from;
private KerberosTime till;
@@ -100,6 +101,7 @@
private void init(PrincipalName cname)
throws KrbException {
this.cname = cname;
+ this.refCname = cname;
state = State.INIT;
}
@@ -224,6 +226,16 @@
this.options = options;
}
+ public void setTill(KerberosTime till) {
+ checkState(State.INIT, "Cannot specify till");
+ this.till = till;
+ }
+
+ public void setRTime(KerberosTime rtime) {
+ checkState(State.INIT, "Cannot specify rtime");
+ this.rtime = rtime;
+ }
+
/**
* Sets or clears target. If cleared, KrbAsReq might choose krbtgt
* for cname realm
@@ -252,7 +264,9 @@
* @throws KrbException
* @throws IOException
*/
- private KrbAsReq build(EncryptionKey key) throws KrbException, IOException {
+ private KrbAsReq build(EncryptionKey key, ReferralsState referralsState)
+ throws KrbException, IOException {
+ PAData[] extraPAs = null;
int[] eTypes;
if (password != null) {
eTypes = EType.getDefaults("default_tkt_enctypes");
@@ -262,15 +276,24 @@
ks);
for (EncryptionKey k: ks) k.destroy();
}
+ options = (options == null) ? new KDCOptions() : options;
+ if (referralsState.isEnabled()) {
+ options.set(KDCOptions.CANONICALIZE, true);
+ extraPAs = new PAData[]{ new PAData(Krb5.PA_REQ_ENC_PA_REP,
+ new byte[]{}) };
+ } else {
+ options.set(KDCOptions.CANONICALIZE, false);
+ }
return new KrbAsReq(key,
options,
- cname,
+ refCname,
sname,
from,
till,
rtime,
eTypes,
- addresses);
+ addresses,
+ extraPAs);
}
/**
@@ -308,11 +331,15 @@
*/
private KrbAsReqBuilder send() throws KrbException, IOException {
boolean preAuthFailedOnce = false;
- KdcComm comm = new KdcComm(cname.getRealmAsString());
+ KdcComm comm = null;
EncryptionKey pakey = null;
+ ReferralsState referralsState = new ReferralsState();
while (true) {
+ if (referralsState.refreshComm()) {
+ comm = new KdcComm(refCname.getRealmAsString());
+ }
try {
- req = build(pakey);
+ req = build(pakey, referralsState);
rep = new KrbAsRep(comm.send(req.encoding()));
return this;
} catch (KrbException ke) {
@@ -341,12 +368,71 @@
}
paList = kerr.getPA(); // Update current paList
} else {
+ if (referralsState.handleError(ke)) {
+ pakey = null;
+ preAuthFailedOnce = false;
+ continue;
+ }
throw ke;
}
}
}
}
+ private final class ReferralsState {
+ private boolean enabled;
+ private int count;
+ private boolean refreshComm;
+
+ ReferralsState() throws KrbException {
+ if (Config.DISABLE_REFERRALS) {
+ if (refCname.getNameType() == PrincipalName.KRB_NT_ENTERPRISE) {
+ throw new KrbException("NT-ENTERPRISE principals only allowed" +
+ " when referrals are enabled.");
+ }
+ enabled = false;
+ } else {
+ enabled = true;
+ }
+ refreshComm = true;
+ }
+
+ boolean handleError(KrbException ke) throws RealmException {
+ if (enabled) {
+ if (ke.returnCode() == Krb5.KRB_ERR_WRONG_REALM) {
+ Realm referredRealm = ke.getError().getClientRealm();
+ if (req.getMessage().reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) &&
+ referredRealm != null && referredRealm.toString().length() > 0 &&
+ count < Config.MAX_REFERRALS) {
+ refCname = new PrincipalName(refCname.getNameType(),
+ refCname.getNameStrings(), referredRealm);
+ refreshComm = true;
+ count++;
+ return true;
+ }
+ }
+ if (count < Config.MAX_REFERRALS &&
+ refCname.getNameType() != PrincipalName.KRB_NT_ENTERPRISE) {
+ // Server may raise an error if CANONICALIZE is true.
+ // Try CANONICALIZE false.
+ enabled = false;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean refreshComm() {
+ boolean retRefreshComm = refreshComm;
+ refreshComm = false;
+ return retRefreshComm;
+ }
+
+ boolean isEnabled() {
+ return enabled;
+ }
+ }
+
/**
* Performs AS-REQ send and AS-REP receive.
* Maybe a state is needed here, to divide prepare process and getCreds.
diff --git a/jdk/src/share/classes/sun/security/krb5/KrbCred.java b/jdk/src/share/classes/sun/security/krb5/KrbCred.java
index e6a4785..0ce26ef 100644
--- a/jdk/src/share/classes/sun/security/krb5/KrbCred.java
+++ b/jdk/src/share/classes/sun/security/krb5/KrbCred.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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,6 +34,7 @@
import sun.security.krb5.internal.*;
import sun.security.krb5.internal.crypto.KeyUsage;
import java.io.IOException;
+
import sun.security.util.DerValue;
/**
@@ -62,7 +63,6 @@
PrincipalName client = tgt.getClient();
PrincipalName tgService = tgt.getServer();
- PrincipalName server = serviceTicket.getServer();
if (!serviceTicket.getClient().equals(client))
throw new KrbException(Krb5.KRB_ERR_GENERIC,
"Client principal does not match");
@@ -75,14 +75,10 @@
options.set(KDCOptions.FORWARDED, true);
options.set(KDCOptions.FORWARDABLE, true);
- HostAddresses sAddrs = null;
- // XXX Also NT_GSS_KRB5_PRINCIPAL can be a host based principal
- // GSSName.NT_HOSTBASED_SERVICE should display with KRB_NT_SRV_HST
- if (server.getNameType() == PrincipalName.KRB_NT_SRV_HST)
- sAddrs= new HostAddresses(server);
-
KrbTgsReq tgsReq = new KrbTgsReq(options, tgt, tgService,
- null, null, null, null, sAddrs, null, null, null);
+ null, null, null, null, null,
+ null, // No easy way to get addresses right
+ null, null, null);
credMessg = createMessage(tgsReq.sendAndGetCreds(), key);
obuf = credMessg.asn1Encode();
@@ -94,7 +90,6 @@
EncryptionKey sessionKey
= delegatedCreds.getSessionKey();
PrincipalName princ = delegatedCreds.getClient();
- Realm realm = princ.getRealm();
PrincipalName tgService = delegatedCreds.getServer();
KrbCredInfo credInfo = new KrbCredInfo(sessionKey,
@@ -157,7 +152,7 @@
+ " endtime=" + endtime
+ "renewTill=" + renewTill);
}
- creds = new Credentials(ticket, pname, sname, credInfoKey,
+ creds = new Credentials(ticket, pname, null, sname, null, credInfoKey,
flags, authtime, starttime, endtime, renewTill, caddr);
}
diff --git a/jdk/src/share/classes/sun/security/krb5/KrbKdcRep.java b/jdk/src/share/classes/sun/security/krb5/KrbKdcRep.java
index 6d79afe..da4a8fa 100644
--- a/jdk/src/share/classes/sun/security/krb5/KrbKdcRep.java
+++ b/jdk/src/share/classes/sun/security/krb5/KrbKdcRep.java
@@ -31,23 +31,41 @@
package sun.security.krb5;
import sun.security.krb5.internal.*;
+import sun.security.krb5.internal.crypto.KeyUsage;
+import sun.security.util.DerInputStream;
abstract class KrbKdcRep {
static void check(
boolean isAsReq,
KDCReq req,
- KDCRep rep
+ KDCRep rep,
+ EncryptionKey replyKey
) throws KrbApErrException {
- if (isAsReq && !req.reqBody.cname.equals(rep.cname)) {
+ // cname change in AS-REP is allowed only if the client
+ // sent CANONICALIZE and the server supports RFC 6806 - Section 11
+ // FAST scheme (ENC-PA-REP flag).
+ if (isAsReq && !req.reqBody.cname.equals(rep.cname) &&
+ (!req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) ||
+ !rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP))) {
rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
}
+ // sname change in TGS-REP is allowed only if client
+ // sent CANONICALIZE and new sname is a referral of
+ // the form krbtgt/TO-REALM.COM@FROM-REALM.COM.
if (!req.reqBody.sname.equals(rep.encKDCRepPart.sname)) {
- rep.encKDCRepPart.key.destroy();
- throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
+ String[] snameStrings = rep.encKDCRepPart.sname.getNameStrings();
+ if (isAsReq || !req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) ||
+ snameStrings == null || snameStrings.length != 2 ||
+ !snameStrings[0].equals(PrincipalName.TGS_DEFAULT_SRV_NAME) ||
+ !rep.encKDCRepPart.sname.getRealmString().equals(
+ req.reqBody.sname.getRealmString())) {
+ rep.encKDCRepPart.key.destroy();
+ throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
+ }
}
if (req.reqBody.getNonce() != rep.encKDCRepPart.nonce) {
@@ -82,49 +100,84 @@
!rep.encKDCRepPart.flags.get(KDCOptions.RENEWABLE)) {
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
}
- if ((req.reqBody.from == null) || req.reqBody.from.isZero())
+
+ if ((req.reqBody.from == null) || req.reqBody.from.isZero()) {
// verify this is allowed
if ((rep.encKDCRepPart.starttime != null) &&
- !rep.encKDCRepPart.starttime.inClockSkew()) {
+ !rep.encKDCRepPart.starttime.inClockSkew()) {
rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW);
}
+ }
- if ((req.reqBody.from != null) && !req.reqBody.from.isZero())
+ if ((req.reqBody.from != null) && !req.reqBody.from.isZero()) {
// verify this is allowed
if ((rep.encKDCRepPart.starttime != null) &&
- !req.reqBody.from.equals(rep.encKDCRepPart.starttime)) {
+ !req.reqBody.from.equals(rep.encKDCRepPart.starttime)) {
rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
}
+ }
if (!req.reqBody.till.isZero() &&
- rep.encKDCRepPart.endtime.greaterThan(req.reqBody.till)) {
+ rep.encKDCRepPart.endtime.greaterThan(req.reqBody.till)) {
rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
}
- if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE))
- if (req.reqBody.rtime != null && !req.reqBody.rtime.isZero())
- // verify this is required
+ // RFC 6806 - Section 11 mechanism check
+ if (rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP) &&
+ req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE)) {
+ boolean reqPaReqEncPaRep = false;
+ boolean repPaReqEncPaRepValid = false;
+
+ // PA_REQ_ENC_PA_REP only required for AS requests
+ for (PAData pa : req.pAData) {
+ if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) {
+ reqPaReqEncPaRep = true;
+ break;
+ }
+ }
+
+ if (rep.encKDCRepPart.pAData != null) {
+ for (PAData pa : rep.encKDCRepPart.pAData) {
+ if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) {
+ try {
+ Checksum repCksum = new Checksum(
+ new DerInputStream(
+ pa.getValue()).getDerValue());
+ // The checksum is inside encKDCRepPart so we don't
+ // care if it's keyed or not.
+ repPaReqEncPaRepValid =
+ repCksum.verifyAnyChecksum(
+ req.asn1Encode(), replyKey,
+ KeyUsage.KU_AS_REQ);
+ } catch (Exception e) {
+ if (Krb5.DEBUG) {
+ e.printStackTrace();
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if (reqPaReqEncPaRep && !repPaReqEncPaRepValid) {
+ throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
+ }
+ }
+
+ if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE)) {
+ if (req.reqBody.rtime != null && !req.reqBody.rtime.isZero()) {
+ // verify this is required
if ((rep.encKDCRepPart.renewTill == null) ||
- rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.rtime)
- ) {
+ rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.rtime)
+ ) {
rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
}
- if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE_OK) &&
- rep.encKDCRepPart.flags.get(KDCOptions.RENEWABLE))
- if (!req.reqBody.till.isZero())
- // verify this is required
- if ((rep.encKDCRepPart.renewTill == null) ||
- rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.till)
- ) {
- rep.encKDCRepPart.key.destroy();
- throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
- }
+ }
+ }
}
-
-
}
diff --git a/jdk/src/share/classes/sun/security/krb5/KrbTgsRep.java b/jdk/src/share/classes/sun/security/krb5/KrbTgsRep.java
index 4f5c2d6..04f36ac 100644
--- a/jdk/src/share/classes/sun/security/krb5/KrbTgsRep.java
+++ b/jdk/src/share/classes/sun/security/krb5/KrbTgsRep.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -84,11 +84,29 @@
EncTGSRepPart enc_part = new EncTGSRepPart(ref);
rep.encKDCRepPart = enc_part;
- check(false, req, rep);
+ check(false, req, rep, tgsReq.tgsReqKey);
+
+ PrincipalName serverAlias = tgsReq.getServerAlias();
+ if (serverAlias != null) {
+ PrincipalName repSname = enc_part.sname;
+ if (serverAlias.equals(repSname) ||
+ isReferralSname(repSname)) {
+ serverAlias = null;
+ }
+ }
+
+ PrincipalName clientAlias = null;
+ if (rep.cname.equals(req.reqBody.cname)) {
+ // Only propagate the client alias if it is not an
+ // impersonation ticket (S4U2Self or S4U2Proxy).
+ clientAlias = tgsReq.getClientAlias();
+ }
this.creds = new Credentials(rep.ticket,
rep.cname,
+ clientAlias,
enc_part.sname,
+ serverAlias,
enc_part.key,
enc_part.flags,
enc_part.authtime,
@@ -111,4 +129,16 @@
sun.security.krb5.internal.ccache.Credentials setCredentials() {
return new sun.security.krb5.internal.ccache.Credentials(rep, secondTicket);
}
+
+ private static boolean isReferralSname(PrincipalName sname) {
+ if (sname != null) {
+ String[] snameStrings = sname.getNameStrings();
+ if (snameStrings.length == 2 &&
+ snameStrings[0].equals(
+ PrincipalName.TGS_DEFAULT_SRV_NAME)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/jdk/src/share/classes/sun/security/krb5/KrbTgsReq.java b/jdk/src/share/classes/sun/security/krb5/KrbTgsReq.java
index 85b7cb2..151f68b 100644
--- a/jdk/src/share/classes/sun/security/krb5/KrbTgsReq.java
+++ b/jdk/src/share/classes/sun/security/krb5/KrbTgsReq.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -35,6 +35,7 @@
import sun.security.krb5.internal.crypto.*;
import java.io.IOException;
import java.net.UnknownHostException;
+import java.time.Instant;
import java.util.Arrays;
/**
@@ -44,7 +45,9 @@
public class KrbTgsReq {
private PrincipalName princName;
+ private PrincipalName clientAlias;
private PrincipalName servName;
+ private PrincipalName serverAlias;
private TGSReq tgsReqMessg;
private KerberosTime ctime;
private Ticket secondTicket = null;
@@ -57,59 +60,26 @@
private byte[] ibuf;
// Used in CredentialsUtil
- public KrbTgsReq(Credentials asCreds,
- PrincipalName sname)
+ public KrbTgsReq(KDCOptions options, Credentials asCreds,
+ PrincipalName cname, PrincipalName clientAlias,
+ PrincipalName sname, PrincipalName serverAlias,
+ Ticket[] additionalTickets, PAData[] extraPAs)
throws KrbException, IOException {
- this(new KDCOptions(),
- asCreds,
- sname,
- null, // KerberosTime from
- null, // KerberosTime till
- null, // KerberosTime rtime
- null, // eTypes, // null, // int[] eTypes
- null, // HostAddresses addresses
- null, // AuthorizationData authorizationData
- null, // Ticket[] additionalTickets
- null); // EncryptionKey subSessionKey
- }
-
- // S4U2proxy
- public KrbTgsReq(Credentials asCreds,
- Ticket second,
- PrincipalName sname)
- throws KrbException, IOException {
- this(KDCOptions.with(KDCOptions.CNAME_IN_ADDL_TKT,
- KDCOptions.FORWARDABLE),
- asCreds,
- sname,
- null,
- null,
- null,
- null,
- null,
- null,
- new Ticket[] {second}, // the service ticket
- null);
- }
-
- // S4U2user
- public KrbTgsReq(Credentials asCreds,
- PrincipalName sname,
- PAData extraPA)
- throws KrbException, IOException {
- this(KDCOptions.with(KDCOptions.FORWARDABLE),
- asCreds,
- asCreds.getClient(),
- sname,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- extraPA); // the PA-FOR-USER
+ this(options,
+ asCreds,
+ cname,
+ clientAlias,
+ sname,
+ serverAlias,
+ null, // KerberosTime from
+ null, // KerberosTime till
+ null, // KerberosTime rtime
+ null, // int[] eTypes
+ null, // HostAddresses addresses
+ null, // AuthorizationData authorizationData
+ additionalTickets,
+ null, // EncryptionKey subKey
+ extraPAs);
}
// Called by Credentials, KrbCred
@@ -117,6 +87,7 @@
KDCOptions options,
Credentials asCreds,
PrincipalName sname,
+ PrincipalName serverAlias,
KerberosTime from,
KerberosTime till,
KerberosTime rtime,
@@ -125,16 +96,18 @@
AuthorizationData authorizationData,
Ticket[] additionalTickets,
EncryptionKey subKey) throws KrbException, IOException {
- this(options, asCreds, asCreds.getClient(), sname,
- from, till, rtime, eTypes, addresses,
- authorizationData, additionalTickets, subKey, null);
+ this(options, asCreds, asCreds.getClient(), asCreds.getClientAlias(),
+ sname, serverAlias, from, till, rtime, eTypes,
+ addresses, authorizationData, additionalTickets, subKey, null);
}
private KrbTgsReq(
KDCOptions options,
Credentials asCreds,
PrincipalName cname,
+ PrincipalName clientAlias,
PrincipalName sname,
+ PrincipalName serverAlias,
KerberosTime from,
KerberosTime till,
KerberosTime rtime,
@@ -143,10 +116,12 @@
AuthorizationData authorizationData,
Ticket[] additionalTickets,
EncryptionKey subKey,
- PAData extraPA) throws KrbException, IOException {
+ PAData[] extraPAs) throws KrbException, IOException {
princName = cname;
+ this.clientAlias = clientAlias;
servName = sname;
+ this.serverAlias = serverAlias;
ctime = KerberosTime.now();
// check if they are valid arguments. The optional fields
@@ -216,7 +191,7 @@
authorizationData,
additionalTickets,
subKey,
- extraPA);
+ extraPAs);
obuf = tgsReqMessg.asn1Encode();
// XXX We need to revisit this to see if can't move it
@@ -282,11 +257,16 @@
AuthorizationData authorizationData,
Ticket[] additionalTickets,
EncryptionKey subKey,
- PAData extraPA)
+ PAData[] extraPAs)
throws IOException, KrbException, UnknownHostException {
KerberosTime req_till = null;
if (till == null) {
- req_till = new KerberosTime(0);
+ String d = Config.getInstance().get("libdefaults", "ticket_lifetime");
+ if (d != null) {
+ req_till = new KerberosTime(Instant.now().plusSeconds(Config.duration(d)));
+ } else {
+ req_till = new KerberosTime(0); // Choose KDC maximum allowed
+ }
} else {
req_till = till;
}
@@ -340,26 +320,8 @@
byte[] temp = reqBody.asn1Encode(Krb5.KRB_TGS_REQ);
// if the checksum type is one of the keyed checksum types,
// use session key.
- Checksum cksum;
- switch (Checksum.CKSUMTYPE_DEFAULT) {
- case Checksum.CKSUMTYPE_RSA_MD4_DES:
- case Checksum.CKSUMTYPE_DES_MAC:
- case Checksum.CKSUMTYPE_DES_MAC_K:
- case Checksum.CKSUMTYPE_RSA_MD4_DES_K:
- case Checksum.CKSUMTYPE_RSA_MD5_DES:
- case Checksum.CKSUMTYPE_HMAC_SHA1_DES3_KD:
- case Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR:
- case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128:
- case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256:
- cksum = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp, key,
+ Checksum cksum = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp, key,
KeyUsage.KU_PA_TGS_REQ_CKSUM);
- break;
- case Checksum.CKSUMTYPE_CRC32:
- case Checksum.CKSUMTYPE_RSA_MD4:
- case Checksum.CKSUMTYPE_RSA_MD5:
- default:
- cksum = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp);
- }
// Usage will be KeyUsage.KU_PA_TGS_REQ_AUTHENTICATOR
@@ -375,11 +337,14 @@
null).getMessage();
PAData tgsPAData = new PAData(Krb5.PA_TGS_REQ, tgs_ap_req);
- return new TGSReq(
- extraPA != null ?
- new PAData[] {extraPA, tgsPAData } :
- new PAData[] {tgsPAData},
- reqBody);
+ PAData[] pa;
+ if (extraPAs != null) {
+ pa = Arrays.copyOf(extraPAs, extraPAs.length + 1);
+ pa[extraPAs.length] = tgsPAData;
+ } else {
+ pa = new PAData[] {tgsPAData};
+ }
+ return new TGSReq(pa, reqBody);
}
TGSReq getMessage() {
@@ -390,6 +355,14 @@
return secondTicket;
}
+ PrincipalName getClientAlias() {
+ return clientAlias;
+ }
+
+ PrincipalName getServerAlias() {
+ return serverAlias;
+ }
+
private static void debug(String message) {
// System.err.println(">>> KrbTgsReq: " + message);
}
diff --git a/jdk/src/share/classes/sun/security/krb5/PrincipalName.java b/jdk/src/share/classes/sun/security/krb5/PrincipalName.java
index 6d5ed3d..4a16eb3 100644
--- a/jdk/src/share/classes/sun/security/krb5/PrincipalName.java
+++ b/jdk/src/share/classes/sun/security/krb5/PrincipalName.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -91,6 +91,11 @@
public static final int KRB_NT_UID = 5;
/**
+ * Enterprise name (alias)
+ */
+ public static final int KRB_NT_ENTERPRISE = 10;
+
+ /**
* TGS Name
*/
public static final String TGS_DEFAULT_SRV_NAME = "krbtgt";
@@ -454,6 +459,7 @@
case KRB_NT_SRV_INST:
case KRB_NT_SRV_XHST:
case KRB_NT_UID:
+ case KRB_NT_ENTERPRISE:
nameStrings = nameParts;
nameType = type;
if (realm != null) {
@@ -547,7 +553,9 @@
for (int i = 0; i < nameStrings.length; i++) {
if (i > 0)
str.append("/");
- str.append(nameStrings[i]);
+ String n = nameStrings[i];
+ n = n.replace("@", "\\@");
+ str.append(n);
}
str.append("@");
str.append(nameRealm.toString());
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java b/jdk/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java
index 14620e9..0478b8a 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -32,7 +32,11 @@
package sun.security.krb5.internal;
import sun.security.krb5.*;
+import sun.security.util.DerValue;
+
import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
/**
* This class is a utility that contains much of the TGS-Exchange
@@ -43,6 +47,10 @@
private static boolean DEBUG = sun.security.krb5.internal.Krb5.DEBUG;
+ private static enum S4U2Type {
+ NONE, SELF, PROXY
+ }
+
/**
* Used by a middle server to acquire credentials on behalf of a
* client to itself using the S4U2self extension.
@@ -52,22 +60,44 @@
*/
public static Credentials acquireS4U2selfCreds(PrincipalName client,
Credentials ccreds) throws KrbException, IOException {
- String uRealm = client.getRealmString();
- String localRealm = ccreds.getClient().getRealmString();
- if (!uRealm.equals(localRealm)) {
- // TODO: we do not support kerberos referral now
- throw new KrbException("Cross realm impersonation not supported");
- }
if (!ccreds.isForwardable()) {
throw new KrbException("S4U2self needs a FORWARDABLE ticket");
}
- KrbTgsReq req = new KrbTgsReq(
- ccreds,
- ccreds.getClient(),
- new PAData(Krb5.PA_FOR_USER,
- new PAForUserEnc(client,
- ccreds.getSessionKey()).asn1Encode()));
- Credentials creds = req.sendAndGetCreds();
+ PrincipalName sname = ccreds.getClient();
+ String uRealm = client.getRealmString();
+ String localRealm = ccreds.getClient().getRealmString();
+ if (!uRealm.equals(localRealm)) {
+ // Referrals will be required because the middle service
+ // and the client impersonated are on different realms.
+ if (Config.DISABLE_REFERRALS) {
+ throw new KrbException("Cross-realm S4U2Self request not" +
+ " possible when referrals are disabled.");
+ }
+ if (ccreds.getClientAlias() != null) {
+ // If the name was canonicalized, the user pick
+ // has preference. This gives the possibility of
+ // using FQDNs that KDCs may use to return referrals.
+ // I.e.: a SVC/host.realm-2.com@REALM-1.COM name
+ // may be used by REALM-1.COM KDC to return a
+ // referral to REALM-2.COM.
+ sname = ccreds.getClientAlias();
+ }
+ sname = new PrincipalName(sname.getNameType(),
+ sname.getNameStrings(), new Realm(uRealm));
+ }
+ Credentials creds = serviceCreds(
+ KDCOptions.with(KDCOptions.FORWARDABLE),
+ ccreds, ccreds.getClient(), sname, null,
+ new PAData[] {
+ new PAData(Krb5.PA_FOR_USER,
+ new PAForUserEnc(client,
+ ccreds.getSessionKey()).asn1Encode()),
+ new PAData(Krb5.PA_PAC_OPTIONS,
+ new PaPacOptions()
+ .setResourceBasedConstrainedDelegation(true)
+ .setClaims(true)
+ .asn1Encode())
+ }, S4U2Type.SELF);
if (!creds.getClient().equals(client)) {
throw new KrbException("S4U2self request not honored by KDC");
}
@@ -89,11 +119,31 @@
String backend, Ticket second,
PrincipalName client, Credentials ccreds)
throws KrbException, IOException {
- KrbTgsReq req = new KrbTgsReq(
- ccreds,
- second,
- new PrincipalName(backend));
- Credentials creds = req.sendAndGetCreds();
+ PrincipalName backendPrincipal = new PrincipalName(backend);
+ String backendRealm = backendPrincipal.getRealmString();
+ String localRealm = ccreds.getClient().getRealmString();
+ if (!backendRealm.equals(localRealm)) {
+ // The middle service and the backend service are on
+ // different realms, so referrals will be required.
+ if (Config.DISABLE_REFERRALS) {
+ throw new KrbException("Cross-realm S4U2Proxy request not" +
+ " possible when referrals are disabled.");
+ }
+ backendPrincipal = new PrincipalName(
+ backendPrincipal.getNameType(),
+ backendPrincipal.getNameStrings(),
+ new Realm(localRealm));
+ }
+ Credentials creds = serviceCreds(KDCOptions.with(
+ KDCOptions.CNAME_IN_ADDL_TKT, KDCOptions.FORWARDABLE),
+ ccreds, ccreds.getClient(), backendPrincipal,
+ new Ticket[] {second}, new PAData[] {
+ new PAData(Krb5.PA_PAC_OPTIONS,
+ new PaPacOptions()
+ .setResourceBasedConstrainedDelegation(true)
+ .setClaims(true)
+ .asn1Encode())
+ }, S4U2Type.PROXY);
if (!creds.getClient().equals(client)) {
throw new KrbException("S4U2proxy request not honored by KDC");
}
@@ -114,53 +164,9 @@
public static Credentials acquireServiceCreds(
String service, Credentials ccreds)
throws KrbException, IOException {
- PrincipalName sname = new PrincipalName(service);
- String serviceRealm = sname.getRealmString();
- String localRealm = ccreds.getClient().getRealmString();
-
- if (localRealm.equals(serviceRealm)) {
- if (DEBUG) {
- System.out.println(
- ">>> Credentials acquireServiceCreds: same realm");
- }
- return serviceCreds(sname, ccreds);
- }
- Credentials theCreds = null;
-
- boolean[] okAsDelegate = new boolean[1];
- Credentials theTgt = getTGTforRealm(localRealm, serviceRealm,
- ccreds, okAsDelegate);
- if (theTgt != null) {
- if (DEBUG) {
- System.out.println(">>> Credentials acquireServiceCreds: "
- + "got right tgt");
- System.out.println(">>> Credentials acquireServiceCreds: "
- + "obtaining service creds for " + sname);
- }
-
- try {
- theCreds = serviceCreds(sname, theTgt);
- } catch (Exception exc) {
- if (DEBUG) {
- System.out.println(exc);
- }
- theCreds = null;
- }
- }
-
- if (theCreds != null) {
- if (DEBUG) {
- System.out.println(">>> Credentials acquireServiceCreds: "
- + "returning creds:");
- Credentials.printDebug(theCreds);
- }
- if (!okAsDelegate[0]) {
- theCreds.resetDelegate();
- }
- return theCreds;
- }
- throw new KrbApErrException(Krb5.KRB_AP_ERR_GEN_CRED,
- "No service creds");
+ PrincipalName sname = new PrincipalName(service,
+ PrincipalName.KRB_NT_SRV_HST);
+ return serviceCreds(sname, ccreds);
}
/**
@@ -305,6 +311,259 @@
private static Credentials serviceCreds(
PrincipalName service, Credentials ccreds)
throws KrbException, IOException {
- return new KrbTgsReq(ccreds, service).sendAndGetCreds();
+ return serviceCreds(new KDCOptions(), ccreds,
+ ccreds.getClient(), service, null, null,
+ S4U2Type.NONE);
+ }
+
+ /*
+ * Obtains credentials for a service (TGS).
+ * Cross-realm referrals are handled if enabled. A fallback scheme
+ * without cross-realm referrals supports is used in case of server
+ * error to maintain backward compatibility.
+ */
+ private static Credentials serviceCreds(
+ KDCOptions options, Credentials asCreds,
+ PrincipalName cname, PrincipalName sname,
+ Ticket[] additionalTickets, PAData[] extraPAs,
+ S4U2Type s4u2Type)
+ throws KrbException, IOException {
+ if (!Config.DISABLE_REFERRALS) {
+ try {
+ return serviceCredsReferrals(options, asCreds, cname, sname,
+ s4u2Type, additionalTickets, extraPAs);
+ } catch (KrbException e) {
+ // Server may raise an error if CANONICALIZE is true.
+ // Try CANONICALIZE false.
+ }
+ }
+ return serviceCredsSingle(options, asCreds, cname,
+ asCreds.getClientAlias(), sname, sname, s4u2Type,
+ additionalTickets, extraPAs);
+ }
+
+ /*
+ * Obtains credentials for a service (TGS).
+ * May handle and follow cross-realm referrals as defined by RFC 6806.
+ */
+ private static Credentials serviceCredsReferrals(
+ KDCOptions options, Credentials asCreds,
+ PrincipalName cname, PrincipalName sname,
+ S4U2Type s4u2Type, Ticket[] additionalTickets,
+ PAData[] extraPAs)
+ throws KrbException, IOException {
+ options = new KDCOptions(options.toBooleanArray());
+ options.set(KDCOptions.CANONICALIZE, true);
+ PrincipalName cSname = sname;
+ PrincipalName refSname = sname; // May change with referrals
+ Credentials creds = null;
+ boolean isReferral = false;
+ List<String> referrals = new LinkedList<>();
+ PrincipalName clientAlias = asCreds.getClientAlias();
+ while (referrals.size() <= Config.MAX_REFERRALS) {
+ ReferralsCache.ReferralCacheEntry ref =
+ ReferralsCache.get(cname, sname, refSname.getRealmString());
+ String toRealm = null;
+ if (ref == null) {
+ creds = serviceCredsSingle(options, asCreds, cname,
+ clientAlias, refSname, cSname, s4u2Type,
+ additionalTickets, extraPAs);
+ PrincipalName server = creds.getServer();
+ if (!refSname.equals(server)) {
+ String[] serverNameStrings = server.getNameStrings();
+ if (serverNameStrings.length == 2 &&
+ serverNameStrings[0].equals(
+ PrincipalName.TGS_DEFAULT_SRV_NAME) &&
+ !refSname.getRealmAsString().equals(
+ serverNameStrings[1])) {
+ // Server Name (sname) has the following format:
+ // krbtgt/TO-REALM.COM@FROM-REALM.COM
+ if (s4u2Type == S4U2Type.NONE) {
+ // Do not store S4U2Self or S4U2Proxy referral
+ // TGTs in the cache. Caching such tickets is not
+ // defined in MS-SFU and may cause unexpected
+ // results when using them in a different context.
+ ReferralsCache.put(cname, sname,
+ server.getRealmString(),
+ serverNameStrings[1], creds);
+ }
+ toRealm = serverNameStrings[1];
+ isReferral = true;
+ }
+ }
+ } else {
+ creds = ref.getCreds();
+ toRealm = ref.getToRealm();
+ isReferral = true;
+ }
+ if (isReferral) {
+ if (s4u2Type == S4U2Type.PROXY) {
+ Credentials[] credsInOut =
+ new Credentials[] {creds, null};
+ toRealm = handleS4U2ProxyReferral(asCreds,
+ credsInOut, sname);
+ creds = credsInOut[0];
+ if (additionalTickets == null ||
+ additionalTickets.length == 0 ||
+ credsInOut[1] == null) {
+ throw new KrbException("Additional tickets expected" +
+ " for S4U2Proxy.");
+ }
+ additionalTickets[0] = credsInOut[1].getTicket();
+ } else if (s4u2Type == S4U2Type.SELF) {
+ handleS4U2SelfReferral(extraPAs, asCreds, creds);
+ }
+ if (referrals.contains(toRealm)) {
+ // Referrals loop detected
+ return null;
+ }
+ asCreds = creds;
+ refSname = new PrincipalName(refSname.getNameString(),
+ refSname.getNameType(), toRealm);
+ referrals.add(toRealm);
+ isReferral = false;
+ continue;
+ }
+ break;
+ }
+ return creds;
+ }
+
+ /*
+ * Obtains credentials for a service (TGS).
+ * If the service realm is different than the one in the TGT, a new TGT for
+ * the service realm is obtained first (see getTGTforRealm call). This is
+ * not expected when following cross-realm referrals because the referral
+ * TGT realm matches the service realm.
+ */
+ private static Credentials serviceCredsSingle(
+ KDCOptions options, Credentials asCreds,
+ PrincipalName cname, PrincipalName clientAlias,
+ PrincipalName refSname, PrincipalName sname,
+ S4U2Type s4u2Type, Ticket[] additionalTickets,
+ PAData[] extraPAs)
+ throws KrbException, IOException {
+ Credentials theCreds = null;
+ boolean[] okAsDelegate = new boolean[]{true};
+ String[] serverAsCredsNames = asCreds.getServer().getNameStrings();
+ String tgtRealm = serverAsCredsNames[1];
+ String serviceRealm = refSname.getRealmString();
+ if (!serviceRealm.equals(tgtRealm)) {
+ // This is a cross-realm service request
+ if (DEBUG) {
+ System.out.println(">>> serviceCredsSingle:" +
+ " cross-realm authentication");
+ System.out.println(">>> serviceCredsSingle:" +
+ " obtaining credentials from " + tgtRealm +
+ " to " + serviceRealm);
+ }
+ Credentials newTgt = getTGTforRealm(tgtRealm, serviceRealm,
+ asCreds, okAsDelegate);
+ if (newTgt == null) {
+ throw new KrbApErrException(Krb5.KRB_AP_ERR_GEN_CRED,
+ "No service creds");
+ }
+ if (DEBUG) {
+ System.out.println(">>> Cross-realm TGT Credentials" +
+ " serviceCredsSingle: ");
+ Credentials.printDebug(newTgt);
+ }
+ if (s4u2Type == S4U2Type.SELF) {
+ handleS4U2SelfReferral(extraPAs, asCreds, newTgt);
+ }
+ asCreds = newTgt;
+ cname = asCreds.getClient();
+ } else if (DEBUG) {
+ System.out.println(">>> Credentials serviceCredsSingle:" +
+ " same realm");
+ }
+ KrbTgsReq req = new KrbTgsReq(options, asCreds, cname, clientAlias,
+ refSname, sname, additionalTickets, extraPAs);
+ theCreds = req.sendAndGetCreds();
+ if (theCreds != null) {
+ if (DEBUG) {
+ System.out.println(">>> TGS credentials serviceCredsSingle:");
+ Credentials.printDebug(theCreds);
+ }
+ if (!okAsDelegate[0]) {
+ theCreds.resetDelegate();
+ }
+ }
+ return theCreds;
+ }
+
+ /**
+ * PA-FOR-USER may need to be regenerated if credentials
+ * change. This may happen when obtaining a TGT for a
+ * different realm or when using a referral TGT.
+ */
+ private static void handleS4U2SelfReferral(PAData[] pas,
+ Credentials oldCeds, Credentials newCreds)
+ throws Asn1Exception, KrbException, IOException {
+ if (DEBUG) {
+ System.out.println(">>> Handling S4U2Self referral");
+ }
+ for (int i = 0; i < pas.length; i++) {
+ PAData pa = pas[i];
+ if (pa.getType() == Krb5.PA_FOR_USER) {
+ PAForUserEnc paForUser = new PAForUserEnc(
+ new DerValue(pa.getValue()),
+ oldCeds.getSessionKey());
+ pas[i] = new PAData(Krb5.PA_FOR_USER,
+ new PAForUserEnc(paForUser.getName(),
+ newCreds.getSessionKey()).asn1Encode());
+ break;
+ }
+ }
+ }
+
+ /**
+ * This method is called after receiving the first realm referral for
+ * a S4U2Proxy request. The credentials and tickets needed for the
+ * final S4U2Proxy request (in the referrals chain) are returned.
+ *
+ * Referrals are handled as described by MS-SFU (section 3.1.5.2.2
+ * Receives Referral).
+ *
+ * @param asCreds middle service credentials used for the first S4U2Proxy
+ * request
+ * @param credsInOut (in/out parameter):
+ * * input: first S4U2Proxy referral TGT received, null
+ * * output: referral TGT for final S4U2Proxy service request,
+ * client referral TGT for final S4U2Proxy service request
+ * (to be sent as additional-ticket)
+ * @param sname the backend service name
+ * @param additionalTickets (out parameter): the additional ticket for the
+ * last S4U2Proxy request is returned
+ * @return the backend realm for the last S4U2Proxy request
+ */
+ private static String handleS4U2ProxyReferral(Credentials asCreds,
+ Credentials[] credsInOut, PrincipalName sname)
+ throws KrbException, IOException {
+ if (DEBUG) {
+ System.out.println(">>> Handling S4U2Proxy referral");
+ }
+ Credentials refTGT = null;
+ // Get a credential for the middle service to the backend so we know
+ // the backend realm, as described in MS-SFU (section 3.1.5.2.2).
+ Credentials middleSvcCredsInBackendRealm =
+ serviceCreds(sname, asCreds);
+ String backendRealm =
+ middleSvcCredsInBackendRealm.getServer().getRealmString();
+ String toRealm = credsInOut[0].getServer().getNameStrings()[1];
+ if (!toRealm.equals(backendRealm)) {
+ // More than 1 hop. Follow the referrals chain and obtain a
+ // TGT for the backend realm.
+ refTGT = getTGTforRealm(toRealm, backendRealm, credsInOut[0],
+ new boolean[1]);
+ } else {
+ // There was only 1 hop. The referral TGT received is already
+ // for the backend realm.
+ refTGT = credsInOut[0];
+ }
+ credsInOut[0] = getTGTforRealm(asCreds.getClient().getRealmString(),
+ backendRealm, asCreds, new boolean[1]);
+ credsInOut[1] = refTGT;
+ return backendRealm;
}
}
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/EncASRepPart.java b/jdk/src/share/classes/sun/security/krb5/internal/EncASRepPart.java
index 7e5d037..ff9382e 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/EncASRepPart.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/EncASRepPart.java
@@ -47,7 +47,8 @@
KerberosTime new_endtime,
KerberosTime new_renewTill,
PrincipalName new_sname,
- HostAddresses new_caddr) {
+ HostAddresses new_caddr,
+ PAData[] new_pAData) {
super(
new_key,
new_lastReq,
@@ -60,6 +61,7 @@
new_renewTill,
new_sname,
new_caddr,
+ new_pAData,
Krb5.KRB_ENC_AS_REP_PART
);
//may need to use Krb5.KRB_ENC_TGS_REP_PART to mimic
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java b/jdk/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java
index 2dd4c84..5c60364 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java
@@ -31,7 +31,6 @@
package sun.security.krb5.internal;
import sun.security.krb5.*;
-import sun.security.krb5.EncryptionKey;
import sun.security.util.*;
import java.util.Vector;
import java.io.IOException;
@@ -41,19 +40,20 @@
* Implements the ASN.1 EncKDCRepPart type.
*
* <xmp>
- * EncKDCRepPart ::= SEQUENCE {
- * key [0] EncryptionKey,
- * last-req [1] LastReq,
- * nonce [2] UInt32,
- * key-expiration [3] KerberosTime OPTIONAL,
- * flags [4] TicketFlags,
- * authtime [5] KerberosTime,
- * starttime [6] KerberosTime OPTIONAL,
- * endtime [7] KerberosTime,
- * renew-till [8] KerberosTime OPTIONAL,
- * srealm [9] Realm,
- * sname [10] PrincipalName,
- * caddr [11] HostAddresses OPTIONAL
+ * EncKDCRepPart ::= SEQUENCE {
+ * key [0] EncryptionKey,
+ * last-req [1] LastReq,
+ * nonce [2] UInt32,
+ * key-expiration [3] KerberosTime OPTIONAL,
+ * flags [4] TicketFlags,
+ * authtime [5] KerberosTime,
+ * starttime [6] KerberosTime OPTIONAL,
+ * endtime [7] KerberosTime,
+ * renew-till [8] KerberosTime OPTIONAL,
+ * srealm [9] Realm,
+ * sname [10] PrincipalName,
+ * caddr [11] HostAddresses OPTIONAL,
+ * encrypted-pa-data [12] SEQUENCE OF PA-DATA OPTIONAL
* }
* </xmp>
*
@@ -76,6 +76,7 @@
public KerberosTime renewTill; //optional
public PrincipalName sname;
public HostAddresses caddr; //optional
+ public PAData[] pAData; //optional
public int msgType; //not included in sequence
public EncKDCRepPart(
@@ -90,6 +91,7 @@
KerberosTime new_renewTill,
PrincipalName new_sname,
HostAddresses new_caddr,
+ PAData[] new_pAData,
int new_msgType) {
key = new_key;
lastReq = new_lastReq;
@@ -102,6 +104,7 @@
renewTill = new_renewTill;
sname = new_sname;
caddr = new_caddr;
+ pAData = new_pAData;
msgType = new_msgType;
}
@@ -160,6 +163,9 @@
if (der.getData().available() > 0) {
caddr = HostAddresses.parse(der.getData(), (byte) 0x0B, true);
}
+ if (der.getData().available() > 0) {
+ pAData = PAData.parseSequence(der.getData(), (byte) 0x0C, true);
+ }
// We observe extra data from MSAD
/*if (der.getData().available() > 0) {
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
@@ -175,47 +181,58 @@
*/
public byte[] asn1Encode(int rep_type) throws Asn1Exception,
IOException {
+ DerOutputStream bytes;
DerOutputStream temp = new DerOutputStream();
- DerOutputStream bytes = new DerOutputStream();
- bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ DerOutputStream out = new DerOutputStream();
+ out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x00), key.asn1Encode());
- bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x01), lastReq.asn1Encode());
temp.putInteger(BigInteger.valueOf(nonce));
- bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x02), temp);
if (keyExpiration != null) {
- bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x03), keyExpiration.asn1Encode());
}
- bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x04), flags.asn1Encode());
- bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x05), authtime.asn1Encode());
if (starttime != null) {
- bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x06), starttime.asn1Encode());
}
- bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x07), endtime.asn1Encode());
if (renewTill != null) {
- bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x08), renewTill.asn1Encode());
}
- bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x09), sname.getRealm().asn1Encode());
- bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x0A), sname.asn1Encode());
if (caddr != null) {
- bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x0B), caddr.asn1Encode());
}
+ if (pAData != null && pAData.length > 0) {
+ temp = new DerOutputStream();
+ for (int i = 0; i < pAData.length; i++) {
+ temp.write(pAData[i].asn1Encode());
+ }
+ bytes = new DerOutputStream();
+ bytes.write(DerValue.tag_SequenceOf, temp);
+ out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+ true, (byte) 0x0C), bytes);
+ }
//should use the rep_type to build the encoding
//but other implementations do not; it is ignored and
//the cached msgType is used instead
temp = new DerOutputStream();
- temp.write(DerValue.tag_Sequence, bytes);
+ temp.write(DerValue.tag_Sequence, out);
bytes = new DerOutputStream();
bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION,
true, (byte) msgType), temp);
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java b/jdk/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java
index cdca881..b1f192e 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java
@@ -46,7 +46,8 @@
KerberosTime new_endtime,
KerberosTime new_renewTill,
PrincipalName new_sname,
- HostAddresses new_caddr) {
+ HostAddresses new_caddr,
+ PAData[] new_pAData) {
super(
new_key,
new_lastReq,
@@ -59,6 +60,7 @@
new_renewTill,
new_sname,
new_caddr,
+ new_pAData,
Krb5.KRB_ENC_TGS_REP_PART);
}
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/HostAddress.java b/jdk/src/share/classes/sun/security/krb5/internal/HostAddress.java
index f3d1d87..77e00a0 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/HostAddress.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/HostAddress.java
@@ -39,6 +39,7 @@
import java.net.Inet6Address;
import java.net.UnknownHostException;
import java.io.IOException;
+import java.util.Arrays;
/**
* Implements the ASN.1 HostAddress type.
@@ -295,4 +296,11 @@
}
}
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(Arrays.toString(address));
+ sb.append('(').append(addrType).append(')');
+ return sb.toString();
+ }
}
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/HostAddresses.java b/jdk/src/share/classes/sun/security/krb5/internal/HostAddresses.java
index 8dc9a28..38bb6a3 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/HostAddresses.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/HostAddresses.java
@@ -31,16 +31,14 @@
package sun.security.krb5.internal;
+import sun.security.krb5.Config;
import sun.security.krb5.PrincipalName;
import sun.security.krb5.KrbException;
import sun.security.krb5.Asn1Exception;
import sun.security.util.*;
-import java.util.Vector;
-import java.util.ArrayList;
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.UnknownHostException;
+
+import java.net.*;
+import java.util.*;
import java.io.IOException;
import sun.security.krb5.internal.ccache.CCacheOutputStream;
@@ -250,6 +248,10 @@
*/
public void writeAddrs(CCacheOutputStream cos) throws IOException {
+ if (addresses == null || addresses.length == 0) {
+ cos.write32(0);
+ return;
+ }
cos.write32(addresses.length);
for (int i = 0; i < addresses.length; i++) {
cos.write16(addresses[i].addrType);
@@ -289,34 +291,35 @@
*/
public static HostAddresses getLocalAddresses() throws IOException
{
- String hostname = null;
- InetAddress[] inetAddresses = null;
+ Set<InetAddress> all = new LinkedHashSet<>();
try {
- InetAddress localHost = InetAddress.getLocalHost();
- hostname = localHost.getHostName();
- inetAddresses = InetAddress.getAllByName(hostname);
- HostAddress[] hAddresses = new HostAddress[inetAddresses.length];
- for (int i = 0; i < inetAddresses.length; i++)
- {
- hAddresses[i] = new HostAddress(inetAddresses[i]);
- }
if (DEBUG) {
- System.out.println(">>> KrbKdcReq local addresses for "
- + hostname + " are: ");
-
- for (int i = 0; i < inetAddresses.length; i++) {
- System.out.println("\n\t" + inetAddresses[i]);
- if (inetAddresses[i] instanceof Inet4Address)
- System.out.println("IPv4 address");
- if (inetAddresses[i] instanceof Inet6Address)
- System.out.println("IPv6 address");
+ System.out.println(">>> KrbKdcReq local addresses are:");
+ }
+ String extra = Config.getInstance().getAll(
+ "libdefaults", "extra_addresses");
+ if (extra != null) {
+ for (String s: extra.split("\\s+")) {
+ all.add(InetAddress.getByName(s));
+ if (DEBUG) {
+ System.out.println(" extra_addresses: "
+ + InetAddress.getByName(s));
+ }
}
}
- return (new HostAddresses(hAddresses));
+ for (NetworkInterface ni:
+ Collections.list(NetworkInterface.getNetworkInterfaces())) {
+ if (DEBUG) {
+ System.out.println(" NetworkInterface " + ni + ":");
+ System.out.println(" "
+ + Collections.list(ni.getInetAddresses()));
+ }
+ all.addAll(Collections.list(ni.getInetAddresses()));
+ }
+ return new HostAddresses(all.toArray(new InetAddress[all.size()]));
} catch (Exception exc) {
throw new IOException(exc.toString());
}
-
}
/**
@@ -335,4 +338,9 @@
for (int i = 0; i < inetAddresses.length; i++)
addresses[i] = new HostAddress(inetAddresses[i]);
}
+
+ @Override
+ public String toString() {
+ return Arrays.toString(addresses);
+ }
}
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/KDCOptions.java b/jdk/src/share/classes/sun/security/krb5/internal/KDCOptions.java
index a3d9302..eb1b6f5 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/KDCOptions.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/KDCOptions.java
@@ -140,6 +140,7 @@
public static final int UNUSED10 = 10;
public static final int UNUSED11 = 11;
public static final int CNAME_IN_ADDL_TKT = 14;
+ public static final int CANONICALIZE = 15;
public static final int RENEWABLE_OK = 27;
public static final int ENC_TKT_IN_SKEY = 28;
public static final int RENEW = 30;
@@ -160,7 +161,8 @@
"UNUSED11", //11;
null,null,
"CNAME_IN_ADDL_TKT",//14;
- null,null,null,null,null,null,null,null,null,null,null,null,
+ "CANONICALIZE", //15;
+ null,null,null,null,null,null,null,null,null,null,null,
"RENEWABLE_OK", //27;
"ENC_TKT_IN_SKEY", //28;
null,
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/KDCReq.java b/jdk/src/share/classes/sun/security/krb5/internal/KDCReq.java
index 16591e8..12d4107 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/KDCReq.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/KDCReq.java
@@ -59,9 +59,9 @@
public class KDCReq {
public KDCReqBody reqBody;
+ public PAData[] pAData = null; //optional
private int pvno;
private int msgType;
- private PAData[] pAData = null; //optional
public KDCReq(PAData[] new_pAData, KDCReqBody new_reqBody,
int req_type) throws IOException {
@@ -144,23 +144,7 @@
} else {
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
}
- if ((der.getData().peekByte() & 0x1F) == 0x03) {
- subDer = der.getData().getDerValue();
- DerValue subsubDer = subDer.getData().getDerValue();
- if (subsubDer.getTag() != DerValue.tag_SequenceOf) {
- throw new Asn1Exception(Krb5.ASN1_BAD_ID);
- }
- Vector<PAData> v = new Vector<>();
- while (subsubDer.getData().available() > 0) {
- v.addElement(new PAData(subsubDer.getData().getDerValue()));
- }
- if (v.size() > 0) {
- pAData = new PAData[v.size()];
- v.copyInto(pAData);
- }
- } else {
- pAData = null;
- }
+ pAData = PAData.parseSequence(der.getData(), (byte) 0x03, true);
subDer = der.getData().getDerValue();
if ((subDer.getTag() & 0x01F) == 0x04) {
DerValue subsubDer = subDer.getData().getDerValue();
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/KRBError.java b/jdk/src/share/classes/sun/security/krb5/internal/KRBError.java
index 6569cbc..5b51706 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/KRBError.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/KRBError.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -90,6 +90,7 @@
private KerberosTime sTime;
private Integer suSec;
private int errorCode;
+ private Realm crealm; //optional
private PrincipalName cname; //optional
private PrincipalName sname;
private String eText; //optional
@@ -138,6 +139,7 @@
sTime = new_sTime;
suSec = new_suSec;
errorCode = new_errorCode;
+ crealm = new_cname != null ? new_cname.getRealm() : null;
cname = new_cname;
sname = new_sname;
eText = new_eText;
@@ -166,6 +168,7 @@
sTime = new_sTime;
suSec = new_suSec;
errorCode = new_errorCode;
+ crealm = new_cname != null ? new_cname.getRealm() : null;
cname = new_cname;
sname = new_sname;
eText = new_eText;
@@ -262,6 +265,10 @@
pa = paList.toArray(new PAData[paList.size()]);
}
+ public final Realm getClientRealm() {
+ return crealm;
+ }
+
public final KerberosTime getServerTime() {
return sTime;
}
@@ -349,7 +356,7 @@
errorCode = subDer.getData().getBigInteger().intValue();
}
else throw new Asn1Exception(Krb5.ASN1_BAD_ID);
- Realm crealm = Realm.parse(der.getData(), (byte)0x07, true);
+ crealm = Realm.parse(der.getData(), (byte)0x07, true);
cname = PrincipalName.parse(der.getData(), (byte)0x08, true, crealm);
Realm realm = Realm.parse(der.getData(), (byte)0x09, false);
sname = PrincipalName.parse(der.getData(), (byte)0x0A, false, realm);
@@ -393,6 +400,9 @@
System.out.println("\t suSec is " + suSec);
System.out.println("\t error code is " + errorCode);
System.out.println("\t error Message is " + Krb5.getErrorMessage(errorCode));
+ if (crealm != null) {
+ System.out.println("\t crealm is " + crealm.toString());
+ }
if (cname != null) {
System.out.println("\t cname is " + cname.toString());
}
@@ -442,8 +452,10 @@
temp.putInteger(BigInteger.valueOf(errorCode));
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), temp);
+ if (crealm != null) {
+ bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), crealm.asn1Encode());
+ }
if (cname != null) {
- bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), cname.getRealm().asn1Encode());
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), cname.asn1Encode());
}
@@ -488,6 +500,7 @@
isEqual(sTime, other.sTime) &&
isEqual(suSec, other.suSec) &&
errorCode == other.errorCode &&
+ isEqual(crealm, other.crealm) &&
isEqual(cname, other.cname) &&
isEqual(sname, other.sname) &&
isEqual(eText, other.eText) &&
@@ -508,6 +521,7 @@
if (sTime != null) result = 37 * result + sTime.hashCode();
if (suSec != null) result = 37 * result + suSec.hashCode();
result = 37 * result + errorCode;
+ if (crealm != null) result = 37 * result + crealm.hashCode();
if (cname != null) result = 37 * result + cname.hashCode();
if (sname != null) result = 37 * result + sname.hashCode();
if (eText != null) result = 37 * result + eText.hashCode();
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/KerberosTime.java b/jdk/src/share/classes/sun/security/krb5/internal/KerberosTime.java
index 3beaac8..64225c8 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/KerberosTime.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/KerberosTime.java
@@ -38,6 +38,7 @@
import sun.security.util.DerValue;
import java.io.IOException;
+import java.time.Instant;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
@@ -129,6 +130,14 @@
}
/**
+ * Creates a KerberosTime object from an Instant object
+ */
+ public KerberosTime(Instant instant) {
+ this(instant.getEpochSecond()*1000 + instant.getNano()/1000000L,
+ instant.getNano()/1000%1000);
+ }
+
+ /**
* Creates a KerberosTime object for now. It uses System.nanoTime()
* to get a more precise time than "new Date()".
*/
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/Krb5.java b/jdk/src/share/classes/sun/security/krb5/internal/Krb5.java
index 2be21dc..0df61a6 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/Krb5.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/Krb5.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -70,6 +70,7 @@
public static final int TKT_OPTS_PRE_AUTHENT = 10;
public static final int TKT_OPTS_HW_AUTHENT = 11;
public static final int TKT_OPTS_DELEGATE = 13;
+ public static final int TKT_OPTS_ENC_PA_REP = 15;
public static final int TKT_OPTS_MAX = 31;
// KDC Options
@@ -162,6 +163,10 @@
// S4U2user info
public static final int PA_FOR_USER = 129;
+ public static final int PA_PAC_OPTIONS = 167;
+
+ // FAST (RFC 6806)
+ public static final int PA_REQ_ENC_PA_REP = 149;
//-------------------------------+-------------
//authorization data type |ad-type value
@@ -265,6 +270,7 @@
public static final int KRB_ERR_RESPONSE_TOO_BIG = 52; //Response too big for UDP, retry with TCP
public static final int KRB_ERR_GENERIC = 60; //Generic error (description in e-text)
public static final int KRB_ERR_FIELD_TOOLONG = 61; //Field is too long for this implementation
+ public static final int KRB_ERR_WRONG_REALM = 68; //Wrong realm
public static final int KRB_CRYPTO_NOT_SUPPORT = 100; //Client does not support this crypto type
public static final int KRB_AP_ERR_NOREALM = 62;
public static final int KRB_AP_ERR_GEN_CRED = 63;
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/NetClient.java b/jdk/src/share/classes/sun/security/krb5/internal/NetClient.java
index 6224356..ab4fe40 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/NetClient.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/NetClient.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -103,7 +103,7 @@
}
try {
- return IOUtils.readFully(in, len, true);
+ return IOUtils.readExactlyNBytes(in, len);
} catch (IOException ioe) {
if (Krb5.DEBUG) {
System.out.println(
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/PAData.java b/jdk/src/share/classes/sun/security/krb5/internal/PAData.java
index f3fdb0b..fd1429a 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/PAData.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/PAData.java
@@ -1,4 +1,6 @@
/*
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,10 +32,12 @@
package sun.security.krb5.internal;
-import sun.security.krb5.KrbException;
+import sun.security.krb5.internal.crypto.EType;
import sun.security.util.*;
import sun.security.krb5.Asn1Exception;
import java.io.IOException;
+import java.util.Vector;
+
import sun.security.krb5.internal.util.KerberosString;
/**
@@ -139,6 +143,41 @@
}
/**
+ * Parse (unmarshal) a PAData from a DER input stream. This form
+ * parsing might be used when expanding a value which is part of
+ * a constructed sequence and uses explicitly tagged type.
+ *
+ * @exception Asn1Exception if an Asn1Exception occurs.
+ * @param data the Der input stream value, which contains one or more
+ * marshaled values.
+ * @param explicitTag tag number.
+ * @param optional indicates if this data field is optional.
+ * @return an array of PAData.
+ */
+ public static PAData[] parseSequence(DerInputStream data,
+ byte explicitTag, boolean optional)
+ throws Asn1Exception, IOException {
+ if ((optional) &&
+ (((byte)data.peekByte() & (byte)0x1F) != explicitTag))
+ return null;
+ DerValue subDer = data.getDerValue();
+ DerValue subsubDer = subDer.getData().getDerValue();
+ if (subsubDer.getTag() != DerValue.tag_SequenceOf) {
+ throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+ }
+ Vector<PAData> v = new Vector<>();
+ while (subsubDer.getData().available() > 0) {
+ v.addElement(new PAData(subsubDer.getData().getDerValue()));
+ }
+ if (v.size() > 0) {
+ PAData[] pas = new PAData[v.size()];
+ v.copyInto(pas);
+ return pas;
+ }
+ return null;
+ }
+
+ /**
* Gets the preferred etype from the PAData array.
* 1. ETYPE-INFO2-ENTRY with unknown s2kparams ignored
* 2. ETYPE-INFO2 preferred to ETYPE-INFO
@@ -169,8 +208,8 @@
while (d2.data.available() > 0) {
DerValue value = d2.data.getDerValue();
ETypeInfo2 tmp = new ETypeInfo2(value);
- if (tmp.getParams() == null) {
- // we don't support non-null s2kparams
+ if (EType.isNewer(tmp.getEType()) || tmp.getParams() == null) {
+ // we don't support non-null s2kparams for old etypes
return tmp.getEType();
}
}
@@ -236,8 +275,9 @@
while (d2.data.available() > 0) {
DerValue value = d2.data.getDerValue();
ETypeInfo2 tmp = new ETypeInfo2(value);
- if (tmp.getParams() == null && tmp.getEType() == eType) {
- // we don't support non-null s2kparams
+ if (tmp.getEType() == eType &&
+ (EType.isNewer(eType) || tmp.getParams() == null)) {
+ // we don't support non-null s2kparams for old etypes
return new SaltAndParams(tmp.getSalt(), tmp.getParams());
}
}
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/PAForUserEnc.java b/jdk/src/share/classes/sun/security/krb5/internal/PAForUserEnc.java
index 42c9caa..91e26a0 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/PAForUserEnc.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/PAForUserEnc.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -133,6 +133,7 @@
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), name.getRealm().asn1Encode());
try {
+ // MS-SFU 2.2.1: use hmac-md5 checksum regardless of key type
Checksum cks = new Checksum(
Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR,
getS4UByteArray(),
@@ -184,6 +185,10 @@
}
}
+ public PrincipalName getName() {
+ return name;
+ }
+
public String toString() {
return "PA-FOR-USER: " + name;
}
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/PaPacOptions.java b/jdk/src/share/classes/sun/security/krb5/internal/PaPacOptions.java
new file mode 100644
index 0000000..82fd12c
--- /dev/null
+++ b/jdk/src/share/classes/sun/security/krb5/internal/PaPacOptions.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.krb5.internal;
+
+import java.io.IOException;
+import sun.security.krb5.Asn1Exception;
+import sun.security.krb5.internal.util.KerberosFlags;
+import sun.security.util.DerOutputStream;
+import sun.security.util.DerValue;
+
+/**
+ * Implements the ASN.1 PA-PAC-OPTIONS type.
+ *
+ * <pre>{@code
+ * PA-PAC-OPTIONS ::= SEQUENCE {
+ * KerberosFlags
+ * -- Claims (0)
+ * -- Branch Aware (1)
+ * -- Forward to Full DC (2)
+ * }
+ * Note: KerberosFlags ::= BIT STRING (SIZE (32..MAX))
+ * -- minimum number of bits shall be sent, but no fewer than 32
+ *
+ * PA-PAC-OPTIONS ::= KerberosFlags
+ * -- resource-based constrained delegation (3)
+ * }</pre>
+ *
+ * This definition reflects MS-KILE (section 2.2.10)
+ * and MS-SFU (section 2.2.5).
+ */
+
+public class PaPacOptions {
+
+ private static final int CLAIMS = 0;
+ private static final int BRANCH_AWARE = 1;
+ private static final int FORWARD_TO_FULL_DC = 2;
+ private static final int RESOURCE_BASED_CONSTRAINED_DELEGATION = 3;
+
+ private KerberosFlags flags;
+
+ public PaPacOptions() {
+ this.flags = new KerberosFlags(Krb5.AP_OPTS_MAX + 1);
+ }
+
+ /**
+ * Constructs a PA-PAC-OPTIONS object from a DER encoding.
+ * @param encoding the ASN.1 encoded input
+ * @throws Asn1Exception if invalid DER
+ * @throws IOException if there is an error reading the DER value
+ */
+ public PaPacOptions(DerValue encoding) throws Asn1Exception, IOException {
+ if (encoding.getTag() != DerValue.tag_Sequence) {
+ throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+ }
+
+ DerValue der = encoding.getData().getDerValue();
+ if ((der.getTag() & 0x1F) == 0x00) {
+ flags = new KDCOptions(
+ der.getData().getDerValue());
+ } else {
+ throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+ }
+ }
+
+ /**
+ * Setter for the claims flag
+ * @param value whether the claims flag is set or not
+ * @return the same PaPacOptions instance
+ */
+ public PaPacOptions setClaims(boolean value) {
+ flags.set(CLAIMS, value);
+ return this;
+ }
+
+ /**
+ * Getter for the claims flag
+ * @return the claims flag value
+ */
+ public boolean getClaims() {
+ return flags.get(CLAIMS);
+ }
+
+ /**
+ * Setter for the branch-aware flag
+ * @param value whether the branch-aware flag is set or not
+ * @return the same PaPacOptions instance
+ */
+ public PaPacOptions setBranchAware(boolean value) {
+ flags.set(BRANCH_AWARE, value);
+ return this;
+ }
+
+ /**
+ * Getter for the branch-aware flag
+ * @return the branch-aware flag value
+ */
+ public boolean getBranchAware() {
+ return flags.get(BRANCH_AWARE);
+ }
+
+ /**
+ * Setter for the forward-to-full-DC flag
+ * @param value whether the forward-to-full-DC flag is set or not
+ * @return the same PaPacOptions instance
+ */
+ public PaPacOptions setForwardToFullDC(boolean value) {
+ flags.set(FORWARD_TO_FULL_DC, value);
+ return this;
+ }
+
+ /**
+ * Getter for the forward-to-full-DC flag
+ * @return the forward-to-full-DC flag value
+ */
+ public boolean getForwardToFullDC() {
+ return flags.get(FORWARD_TO_FULL_DC);
+ }
+
+ /**
+ * Setter for the resource-based-constrained-delegation flag
+ * @param value whether the resource-based-constrained-delegation
+ * is set or not
+ * @return the same PaPacOptions instance
+ */
+ public PaPacOptions setResourceBasedConstrainedDelegation(boolean value) {
+ flags.set(RESOURCE_BASED_CONSTRAINED_DELEGATION, value);
+ return this;
+ }
+
+ /**
+ * Getter for the resource-based-constrained-delegation flag
+ * @return the resource-based-constrained-delegation flag value
+ */
+ public boolean getResourceBasedConstrainedDelegation() {
+ return flags.get(RESOURCE_BASED_CONSTRAINED_DELEGATION);
+ }
+
+ /**
+ * Encodes this PaPacOptions instance.
+ * @return an ASN.1 encoded PaPacOptions byte array
+ * @throws IOException if an I/O error occurs while encoding this
+ * PaPacOptions instance
+ */
+ public byte[] asn1Encode() throws IOException {
+ byte[] bytes = null;
+ try(DerOutputStream temp = new DerOutputStream()) {
+ temp.write(
+ DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00),
+ flags.asn1Encode());
+ bytes = temp.toByteArray();
+ }
+ try(DerOutputStream temp = new DerOutputStream()) {
+ temp.write(DerValue.tag_Sequence, bytes);
+ return temp.toByteArray();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return flags.toString();
+ }
+}
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ReferralsCache.java b/jdk/src/share/classes/sun/security/krb5/internal/ReferralsCache.java
new file mode 100644
index 0000000..970d432
--- /dev/null
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ReferralsCache.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.krb5.internal;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import sun.security.krb5.Credentials;
+import sun.security.krb5.PrincipalName;
+
+/*
+ * ReferralsCache class implements a cache scheme for referral TGTs as
+ * described in RFC 6806 - 10. Caching Information. The goal is to optimize
+ * resources (such as network traffic) when a client requests credentials for a
+ * service principal to a given KDC. If a referral TGT was previously received,
+ * cached information is used instead of issuing a new query. Once a referral
+ * TGT expires, the corresponding referral entry in the cache is removed.
+ */
+final class ReferralsCache {
+
+ private static Map<ReferralCacheKey, Map<String, ReferralCacheEntry>>
+ referralsMap = new HashMap<>();
+
+ static private final class ReferralCacheKey {
+ private PrincipalName cname;
+ private PrincipalName sname;
+ ReferralCacheKey (PrincipalName cname, PrincipalName sname) {
+ this.cname = cname;
+ this.sname = sname;
+ }
+ public boolean equals(Object other) {
+ if (!(other instanceof ReferralCacheKey))
+ return false;
+ ReferralCacheKey that = (ReferralCacheKey)other;
+ return cname.equals(that.cname) &&
+ sname.equals(that.sname);
+ }
+ public int hashCode() {
+ return cname.hashCode() + sname.hashCode();
+ }
+ }
+
+ static final class ReferralCacheEntry {
+ private final Credentials creds;
+ private final String toRealm;
+ ReferralCacheEntry(Credentials creds, String toRealm) {
+ this.creds = creds;
+ this.toRealm = toRealm;
+ }
+ Credentials getCreds() {
+ return creds;
+ }
+ String getToRealm() {
+ return toRealm;
+ }
+ }
+
+ /*
+ * Add a new referral entry to the cache, including: client principal,
+ * service principal, source KDC realm, destination KDC realm and
+ * referral TGT.
+ *
+ * If a loop is generated when adding the new referral, the first hop is
+ * automatically removed. For example, let's assume that adding a
+ * REALM-3.COM -> REALM-1.COM referral generates the following loop:
+ * REALM-1.COM -> REALM-2.COM -> REALM-3.COM -> REALM-1.COM. Then,
+ * REALM-1.COM -> REALM-2.COM referral entry is removed from the cache.
+ */
+ static synchronized void put(PrincipalName cname, PrincipalName service,
+ String fromRealm, String toRealm, Credentials creds) {
+ ReferralCacheKey k = new ReferralCacheKey(cname, service);
+ pruneExpired(k);
+ if (creds.getEndTime().before(new Date())) {
+ return;
+ }
+ Map<String, ReferralCacheEntry> entries = referralsMap.get(k);
+ if (entries == null) {
+ entries = new HashMap<String, ReferralCacheEntry>();
+ referralsMap.put(k, entries);
+ }
+ entries.remove(fromRealm);
+ ReferralCacheEntry newEntry = new ReferralCacheEntry(creds, toRealm);
+ entries.put(fromRealm, newEntry);
+
+ // Remove loops within the cache
+ ReferralCacheEntry current = newEntry;
+ List<ReferralCacheEntry> seen = new LinkedList<>();
+ while (current != null) {
+ if (seen.contains(current)) {
+ // Loop found. Remove the first referral to cut the loop.
+ entries.remove(newEntry.getToRealm());
+ break;
+ }
+ seen.add(current);
+ current = entries.get(current.getToRealm());
+ }
+ }
+
+ /*
+ * Obtain a referral entry from the cache given a client principal,
+ * service principal and a source KDC realm.
+ */
+ static synchronized ReferralCacheEntry get(PrincipalName cname,
+ PrincipalName service, String fromRealm) {
+ ReferralCacheKey k = new ReferralCacheKey(cname, service);
+ pruneExpired(k);
+ Map<String, ReferralCacheEntry> entries = referralsMap.get(k);
+ if (entries != null) {
+ ReferralCacheEntry toRef = entries.get(fromRealm);
+ if (toRef != null) {
+ return toRef;
+ }
+ }
+ return null;
+ }
+
+ /*
+ * Remove referral entries from the cache when referral TGTs expire.
+ */
+ private static void pruneExpired(ReferralCacheKey k) {
+ Date now = new Date();
+ Map<String, ReferralCacheEntry> entries = referralsMap.get(k);
+ if (entries != null) {
+ for (Entry<String, ReferralCacheEntry> mapEntry :
+ entries.entrySet()) {
+ if (mapEntry.getValue().getCreds().getEndTime().before(now)) {
+ entries.remove(mapEntry.getKey());
+ }
+ }
+ }
+ }
+}
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/TicketFlags.java b/jdk/src/share/classes/sun/security/krb5/internal/TicketFlags.java
index 1f77e0f..1b3a182 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/TicketFlags.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/TicketFlags.java
@@ -51,7 +51,8 @@
* renewable(8),
* initial(9),
* pre-authent(10),
- * hw-authent(11)
+ * hw-authent(11),
+ * enc-pa-rep(15)
* }
*/
public class TicketFlags extends KerberosFlags {
@@ -178,6 +179,9 @@
case 11:
sb.append("HW-AUTHENT;");
break;
+ case 15:
+ sb.append("ENC-PA-REP;");
+ break;
}
}
}
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java b/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java
index c7d9d2a..a73af46 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java
@@ -128,7 +128,7 @@
length--;
for (int i = 0; i <= length; i++) {
namelength = readLength4();
- byte[] bytes = IOUtils.readFully(this, namelength, true);
+ byte[] bytes = IOUtils.readExactlyNBytes(this, namelength);
result.add(new String(bytes));
}
if (result.isEmpty()) {
@@ -186,7 +186,7 @@
if (version == KRB5_FCC_FVNO_3)
read(2); /* keytype recorded twice in fvno 3 */
keyLen = readLength4();
- byte[] bytes = IOUtils.readFully(this, keyLen, true);
+ byte[] bytes = IOUtils.readExactlyNBytes(this, keyLen);
return new EncryptionKey(bytes, keyType, new Integer(version));
}
@@ -239,7 +239,7 @@
for (int i = 0; i < num; i++) {
adtype = read(2);
adlength = readLength4();
- data = IOUtils.readFully(this, adlength, true);
+ data = IOUtils.readExactlyNBytes(this, adlength);
auData.add(new AuthorizationDataEntry(adtype, data));
}
return auData.toArray(new AuthorizationDataEntry[auData.size()]);
@@ -253,7 +253,7 @@
if (length == 0) {
return null;
} else {
- return IOUtils.readFully(this, length, true);
+ return IOUtils.readExactlyNBytes(this, length);
}
}
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java b/jdk/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java
index c62e629..ccb9b1c 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java
@@ -192,8 +192,9 @@
// is most likely to be the one in Authenticator in PA-TGS-REQ encoded
// in TGS-REQ, therefore only stored with a service ticket. Currently
// in Java, we only reads TGTs.
- return new sun.security.krb5.Credentials(ticket,
- cname, sname, key, flags, authtime, starttime, endtime, renewTill, caddr);
+ return new sun.security.krb5.Credentials(ticket, cname, null, sname,
+ null, key, flags, authtime, starttime, endtime, renewTill,
+ caddr);
}
public KerberosTime getStartTime() {
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java
index 8325692..b7b06a9 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -31,10 +31,7 @@
package sun.security.krb5.internal.crypto;
-import sun.security.krb5.Config;
import sun.security.krb5.Checksum;
-import sun.security.krb5.EncryptedData;
-import sun.security.krb5.KrbException;
import sun.security.krb5.KrbCryptoException;
import sun.security.krb5.internal.*;
@@ -81,6 +78,7 @@
cksumTypeName =
"sun.security.krb5.internal.crypto.HmacSha1Aes128CksumType";
break;
+
case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256:
cksumType = new HmacSha1Aes256CksumType();
cksumTypeName =
@@ -117,32 +115,11 @@
return cksumType;
}
-
- /**
- * Returns default checksum type.
- */
- public static CksumType getInstance() throws KdcErrException {
- // this method provided for Kerberos applications.
- int cksumType = Checksum.CKSUMTYPE_RSA_MD5; // default
- try {
- Config c = Config.getInstance();
- if ((cksumType = (Config.getType(c.get("libdefaults",
- "ap_req_checksum_type")))) == - 1) {
- if ((cksumType = Config.getType(c.get("libdefaults",
- "checksum_type"))) == -1) {
- cksumType = Checksum.CKSUMTYPE_RSA_MD5; // default
- }
- }
- } catch (KrbException e) {
- }
- return getInstance(cksumType);
- }
-
public abstract int confounderSize();
public abstract int cksumType();
- public abstract boolean isSafe();
+ public abstract boolean isKeyed();
public abstract int cksumSize();
@@ -150,13 +127,12 @@
public abstract int keySize();
- public abstract byte[] calculateChecksum(byte[] data, int size)
- throws KrbCryptoException;
-
- public abstract byte[] calculateKeyedChecksum(byte[] data, int size,
+ // Note: key and usage will be ignored for an unkeyed checksum.
+ public abstract byte[] calculateChecksum(byte[] data, int size,
byte[] key, int usage) throws KrbCryptoException;
- public abstract boolean verifyKeyedChecksum(byte[] data, int size,
+ // Note: key and usage will be ignored for an unkeyed checksum.
+ public abstract boolean verifyChecksum(byte[] data, int size,
byte[] key, byte[] checksum, int usage) throws KrbCryptoException;
public static boolean isChecksumEqual(byte[] cksum1, byte[] cksum2) {
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/Crc32CksumType.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/Crc32CksumType.java
index b1aa0ab..151e2da 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/Crc32CksumType.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/Crc32CksumType.java
@@ -32,7 +32,6 @@
import sun.security.krb5.*;
import sun.security.krb5.internal.*;
-import java.util.zip.CRC32;
public class Crc32CksumType extends CksumType {
@@ -47,7 +46,7 @@
return Checksum.CKSUMTYPE_CRC32;
}
- public boolean isSafe() {
+ public boolean isKeyed() {
return false;
}
@@ -63,18 +62,15 @@
return 0;
}
- public byte[] calculateChecksum(byte[] data, int size) {
+ public byte[] calculateChecksum(byte[] data, int size,
+ byte[] key, int usage) {
return crc32.byte2crc32sum_bytes(data, size);
}
- public byte[] calculateKeyedChecksum(byte[] data, int size,
- byte[] key, int usage) {
- return null;
- }
-
- public boolean verifyKeyedChecksum(byte[] data, int size,
- byte[] key, byte[] checksum, int usage) {
- return false;
+ public boolean verifyChecksum(byte[] data, int size,
+ byte[] key, byte[] checksum, int usage) {
+ return CksumType.isChecksumEqual(checksum,
+ crc32.byte2crc32sum_bytes(data));
}
public static byte[] int2quad(long input) {
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/DesCbcCrcEType.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/DesCbcCrcEType.java
index 08d9d55..e930d6a 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/DesCbcCrcEType.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/DesCbcCrcEType.java
@@ -53,7 +53,7 @@
}
public int checksumType() {
- return Checksum.CKSUMTYPE_CRC32;
+ return Checksum.CKSUMTYPE_RSA_MD5;
}
public int checksumSize() {
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/DesMacCksumType.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/DesMacCksumType.java
index 3c3842f..2e11a20 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/DesMacCksumType.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/DesMacCksumType.java
@@ -49,7 +49,7 @@
return Checksum.CKSUMTYPE_DES_MAC;
}
- public boolean isSafe() {
+ public boolean isKeyed() {
return true;
}
@@ -65,10 +65,6 @@
return 8;
}
- public byte[] calculateChecksum(byte[] data, int size) {
- return null;
- }
-
/**
* Calculates keyed checksum.
* @param data the data used to generate the checksum.
@@ -78,7 +74,7 @@
*
* @modified by Yanni Zhang, 12/08/99.
*/
- public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+ public byte[] calculateChecksum(byte[] data, int size, byte[] key,
int usage) throws KrbCryptoException {
byte[] new_data = new byte[size + confounderSize()];
byte[] conf = Confounder.bytes(confounderSize());
@@ -130,7 +126,7 @@
*
* @modified by Yanni Zhang, 12/08/99.
*/
- public boolean verifyKeyedChecksum(byte[] data, int size,
+ public boolean verifyChecksum(byte[] data, int size,
byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
byte[] cksum = decryptKeyedChecksum(checksum, key);
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/DesMacKCksumType.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/DesMacKCksumType.java
index 805f931..4f706fb 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/DesMacKCksumType.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/DesMacKCksumType.java
@@ -48,7 +48,7 @@
return Checksum.CKSUMTYPE_DES_MAC_K;
}
- public boolean isSafe() {
+ public boolean isKeyed() {
return true;
}
@@ -64,10 +64,6 @@
return 8;
}
- public byte[] calculateChecksum(byte[] data, int size) {
- return null;
- }
-
/**
* Calculates keyed checksum.
* @param data the data used to generate the checksum.
@@ -77,7 +73,7 @@
*
* @modified by Yanni Zhang, 12/08/99.
*/
- public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+ public byte[] calculateChecksum(byte[] data, int size, byte[] key,
int usage) throws KrbCryptoException {
//check for weak keys
try {
@@ -93,9 +89,9 @@
return cksum;
}
- public boolean verifyKeyedChecksum(byte[] data, int size,
+ public boolean verifyChecksum(byte[] data, int size,
byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
- byte[] new_cksum = calculateKeyedChecksum(data, data.length, key, usage);
+ byte[] new_cksum = calculateChecksum(data, data.length, key, usage);
return isChecksumEqual(checksum, new_cksum);
}
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/EType.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/EType.java
index feed5d8..ee59d21 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/EType.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/EType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -301,6 +301,26 @@
return isSupported(eTypeConst, enabledETypes);
}
+ /**
+ * https://tools.ietf.org/html/rfc4120#section-3.1.3:
+ *
+ * A "newer" enctype is any enctype first officially
+ * specified concurrently with or subsequent to the issue of this RFC.
+ * The enctypes DES, 3DES, or RC4 and any defined in [RFC1510] are not
+ * "newer" enctypes.
+ *
+ * @param eTypeConst the encryption type
+ * @return true if "newer"
+ */
+ public static boolean isNewer(int eTypeConst) {
+ return eTypeConst != EncryptedData.ETYPE_DES_CBC_CRC &&
+ eTypeConst != EncryptedData.ETYPE_DES_CBC_MD4 &&
+ eTypeConst != EncryptedData.ETYPE_DES_CBC_MD5 &&
+ eTypeConst != EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD &&
+ eTypeConst != EncryptedData.ETYPE_ARCFOUR_HMAC &&
+ eTypeConst != EncryptedData.ETYPE_ARCFOUR_HMAC_EXP;
+ }
+
public static String toString(int type) {
switch (type) {
case 0:
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacMd5ArcFourCksumType.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacMd5ArcFourCksumType.java
index 4a233dd..41388ec8 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacMd5ArcFourCksumType.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacMd5ArcFourCksumType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,8 +28,6 @@
import sun.security.krb5.Checksum;
import sun.security.krb5.KrbCryptoException;
import sun.security.krb5.internal.*;
-import javax.crypto.spec.DESKeySpec;
-import java.security.InvalidKeyException;
import java.security.GeneralSecurityException;
/**
@@ -51,7 +49,7 @@
return Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR;
}
- public boolean isSafe() {
+ public boolean isKeyed() {
return true;
}
@@ -67,10 +65,6 @@
return 16; // bytes
}
- public byte[] calculateChecksum(byte[] data, int size) {
- return null;
- }
-
/**
* Calculates keyed checksum.
* @param data the data used to generate the checksum.
@@ -78,7 +72,7 @@
* @param key the key used to encrypt the checksum.
* @return keyed checksum.
*/
- public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+ public byte[] calculateChecksum(byte[] data, int size, byte[] key,
int usage) throws KrbCryptoException {
try {
@@ -98,7 +92,7 @@
* @param checksum
* @return true if verification is successful.
*/
- public boolean verifyKeyedChecksum(byte[] data, int size,
+ public boolean verifyChecksum(byte[] data, int size,
byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
try {
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes128CksumType.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes128CksumType.java
index ba31b57..a16941c 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes128CksumType.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes128CksumType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,8 +28,6 @@
import sun.security.krb5.Checksum;
import sun.security.krb5.KrbCryptoException;
import sun.security.krb5.internal.*;
-import javax.crypto.spec.DESKeySpec;
-import java.security.InvalidKeyException;
import java.security.GeneralSecurityException;
/*
@@ -51,7 +49,7 @@
return Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128;
}
- public boolean isSafe() {
+ public boolean isKeyed() {
return true;
}
@@ -67,10 +65,6 @@
return 16; // bytes
}
- public byte[] calculateChecksum(byte[] data, int size) {
- return null;
- }
-
/**
* Calculates keyed checksum.
* @param data the data used to generate the checksum.
@@ -78,7 +72,7 @@
* @param key the key used to encrypt the checksum.
* @return keyed checksum.
*/
- public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+ public byte[] calculateChecksum(byte[] data, int size, byte[] key,
int usage) throws KrbCryptoException {
try {
@@ -98,7 +92,7 @@
* @param checksum
* @return true if verification is successful.
*/
- public boolean verifyKeyedChecksum(byte[] data, int size,
+ public boolean verifyChecksum(byte[] data, int size,
byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
try {
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes256CksumType.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes256CksumType.java
index d9f213b..9ce9347 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes256CksumType.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes256CksumType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,8 +28,6 @@
import sun.security.krb5.Checksum;
import sun.security.krb5.KrbCryptoException;
import sun.security.krb5.internal.*;
-import javax.crypto.spec.DESKeySpec;
-import java.security.InvalidKeyException;
import java.security.GeneralSecurityException;
/*
@@ -51,7 +49,7 @@
return Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256;
}
- public boolean isSafe() {
+ public boolean isKeyed() {
return true;
}
@@ -67,10 +65,6 @@
return 32; // bytes
}
- public byte[] calculateChecksum(byte[] data, int size) {
- return null;
- }
-
/**
* Calculates keyed checksum.
* @param data the data used to generate the checksum.
@@ -78,7 +72,7 @@
* @param key the key used to encrypt the checksum.
* @return keyed checksum.
*/
- public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+ public byte[] calculateChecksum(byte[] data, int size, byte[] key,
int usage) throws KrbCryptoException {
try {
@@ -98,7 +92,7 @@
* @param checksum
* @return true if verification is successful.
*/
- public boolean verifyKeyedChecksum(byte[] data, int size,
+ public boolean verifyChecksum(byte[] data, int size,
byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
try {
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Des3KdCksumType.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Des3KdCksumType.java
index 9547ea0..81e4420 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Des3KdCksumType.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/HmacSha1Des3KdCksumType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,8 +28,6 @@
import sun.security.krb5.Checksum;
import sun.security.krb5.KrbCryptoException;
import sun.security.krb5.internal.*;
-import javax.crypto.spec.DESKeySpec;
-import java.security.InvalidKeyException;
import java.security.GeneralSecurityException;
public class HmacSha1Des3KdCksumType extends CksumType {
@@ -45,7 +43,7 @@
return Checksum.CKSUMTYPE_HMAC_SHA1_DES3_KD;
}
- public boolean isSafe() {
+ public boolean isKeyed() {
return true;
}
@@ -61,10 +59,6 @@
return 24; // bytes
}
- public byte[] calculateChecksum(byte[] data, int size) {
- return null;
- }
-
/**
* Calculates keyed checksum.
* @param data the data used to generate the checksum.
@@ -72,7 +66,7 @@
* @param key the key used to encrypt the checksum.
* @return keyed checksum.
*/
- public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+ public byte[] calculateChecksum(byte[] data, int size, byte[] key,
int usage) throws KrbCryptoException {
try {
@@ -92,7 +86,7 @@
* @param checksum
* @return true if verification is successful.
*/
- public boolean verifyKeyedChecksum(byte[] data, int size,
+ public boolean verifyChecksum(byte[] data, int size,
byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
try {
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/KeyUsage.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/KeyUsage.java
index f9be46c..5179f52 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/KeyUsage.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/KeyUsage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, 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
@@ -56,6 +56,7 @@
public static final int KU_KRB_SAFE_CKSUM = 15; // KrbSafe
public static final int KU_PA_FOR_USER_ENC_CKSUM = 17; // S4U2user
public static final int KU_AD_KDC_ISSUED_CKSUM = 19;
+ public static final int KU_AS_REQ = 56;
public static final boolean isValid(int usage) {
return usage >= 0;
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java
index c475749..e0c4429 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java
@@ -33,8 +33,6 @@
import sun.security.krb5.KrbCryptoException;
import sun.security.krb5.internal.*;
import java.security.MessageDigest;
-import java.security.Provider;
-import java.security.Security;
public final class RsaMd5CksumType extends CksumType {
@@ -49,7 +47,7 @@
return Checksum.CKSUMTYPE_RSA_MD5;
}
- public boolean isSafe() {
+ public boolean isKeyed() {
return false;
}
@@ -74,7 +72,8 @@
* @modified by Yanni Zhang, 12/08/99.
*/
- public byte[] calculateChecksum(byte[] data, int size) throws KrbCryptoException{
+ public byte[] calculateChecksum(byte[] data, int size,
+ byte[] key, int usage) throws KrbCryptoException{
MessageDigest md5;
byte[] result = null;
try {
@@ -91,14 +90,15 @@
return result;
}
- public byte[] calculateKeyedChecksum(byte[] data, int size,
- byte[] key, int usage) throws KrbCryptoException {
- return null;
- }
-
- public boolean verifyKeyedChecksum(byte[] data, int size,
- byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
- return false;
+ @Override
+ public boolean verifyChecksum(byte[] data, int size,
+ byte[] key, byte[] checksum, int usage)
+ throws KrbCryptoException {
+ try {
+ byte[] calculated = MessageDigest.getInstance("MD5").digest(data);
+ return CksumType.isChecksumEqual(calculated, checksum);
+ } catch (Exception e) {
+ return false;
+ }
}
-
}
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5DesCksumType.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5DesCksumType.java
index c4c5383..0d55aed 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5DesCksumType.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5DesCksumType.java
@@ -33,12 +33,8 @@
import sun.security.krb5.Confounder;
import sun.security.krb5.KrbCryptoException;
import sun.security.krb5.internal.*;
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
import javax.crypto.spec.DESKeySpec;
import java.security.MessageDigest;
-import java.security.Provider;
-import java.security.Security;
import java.security.InvalidKeyException;
public final class RsaMd5DesCksumType extends CksumType {
@@ -54,7 +50,7 @@
return Checksum.CKSUMTYPE_RSA_MD5_DES;
}
- public boolean isSafe() {
+ public boolean isKeyed() {
return true;
}
@@ -79,7 +75,7 @@
*
* @modified by Yanni Zhang, 12/08/99.
*/
- public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+ public byte[] calculateChecksum(byte[] data, int size, byte[] key,
int usage) throws KrbCryptoException {
//prepend confounder
byte[] new_data = new byte[size + confounderSize()];
@@ -88,7 +84,7 @@
System.arraycopy(data, 0, new_data, confounderSize(), size);
//calculate md5 cksum
- byte[] mdc_cksum = calculateChecksum(new_data, new_data.length);
+ byte[] mdc_cksum = calculateRawChecksum(new_data, new_data.length);
byte[] cksum = new byte[cksumSize()];
System.arraycopy(conf, 0, cksum, 0, confounderSize());
System.arraycopy(mdc_cksum, 0, cksum, confounderSize(),
@@ -125,7 +121,7 @@
*
* @modified by Yanni Zhang, 12/08/99.
*/
- public boolean verifyKeyedChecksum(byte[] data, int size,
+ public boolean verifyChecksum(byte[] data, int size,
byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
//decrypt checksum
byte[] cksum = decryptKeyedChecksum(checksum, key);
@@ -135,7 +131,7 @@
System.arraycopy(cksum, 0, new_data, 0, confounderSize());
System.arraycopy(data, 0, new_data, confounderSize(), size);
- byte[] new_cksum = calculateChecksum(new_data, new_data.length);
+ byte[] new_cksum = calculateRawChecksum(new_data, new_data.length);
//extract original cksum value
byte[] orig_cksum = new byte[cksumSize() - confounderSize()];
System.arraycopy(cksum, confounderSize(), orig_cksum, 0,
@@ -181,7 +177,7 @@
*
* @modified by Yanni Zhang, 12/08/99.
*/
- public byte[] calculateChecksum(byte[] data, int size) throws KrbCryptoException{
+ private byte[] calculateRawChecksum(byte[] data, int size) throws KrbCryptoException{
MessageDigest md5;
byte[] result = null;
try {
@@ -197,5 +193,4 @@
}
return result;
}
-
}
diff --git a/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java b/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java
index 628d6d0..3053d34 100644
--- a/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java
+++ b/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,20 +28,12 @@
import java.io.OutputStream;
import java.io.IOException;
import java.math.BigInteger;
-import java.security.CryptoPrimitive;
-import java.security.InvalidKeyException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.Principal;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.Timestamp;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
+import java.security.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -62,6 +54,7 @@
import sun.security.x509.AlgorithmId;
import sun.security.x509.X500Name;
import sun.security.x509.KeyUsageExtension;
+import sun.security.util.SignatureUtil;
/**
* A SignerInfo, as defined in PKCS#7's signedData type.
@@ -453,30 +446,34 @@
}
Signature sig = Signature.getInstance(algname);
- sig.initVerify(key);
+
+ AlgorithmParameters ap =
+ digestEncryptionAlgorithmId.getParameters();
+ try {
+ SignatureUtil.initVerifyWithParam(sig, key,
+ SignatureUtil.getParamSpec(algname, ap));
+ } catch (ProviderException | InvalidAlgorithmParameterException |
+ InvalidKeyException e) {
+ throw new SignatureException(e.getMessage(), e);
+ }
+
sig.update(dataSigned);
if (sig.verify(encryptedDigest)) {
return this;
}
-
} catch (IOException e) {
throw new SignatureException("IO error verifying signature:\n" +
e.getMessage());
-
- } catch (InvalidKeyException e) {
- throw new SignatureException("InvalidKey: " + e.getMessage());
-
}
return null;
}
/* Verify the content of the pkcs7 block. */
SignerInfo verify(PKCS7 block)
- throws NoSuchAlgorithmException, SignatureException {
+ throws NoSuchAlgorithmException, SignatureException {
return verify(block, null);
}
-
public BigInteger getVersion() {
return version;
}
diff --git a/jdk/src/share/classes/sun/security/pkcs10/PKCS10.java b/jdk/src/share/classes/sun/security/pkcs10/PKCS10.java
index 9302580..9698c18 100644
--- a/jdk/src/share/classes/sun/security/pkcs10/PKCS10.java
+++ b/jdk/src/share/classes/sun/security/pkcs10/PKCS10.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,11 +31,7 @@
import java.math.BigInteger;
import java.security.cert.CertificateException;
-import java.security.NoSuchAlgorithmException;
-import java.security.InvalidKeyException;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.PublicKey;
+import java.security.*;
import java.util.Base64;
@@ -43,6 +39,8 @@
import sun.security.x509.AlgorithmId;
import sun.security.x509.X509Key;
import sun.security.x509.X500Name;
+import sun.security.util.SignatureUtil;
+
/**
* A PKCS #10 certificate request is created and sent to a Certificate
@@ -169,12 +167,20 @@
try {
sigAlg = id.getName();
sig = Signature.getInstance(sigAlg);
- sig.initVerify(subjectPublicKeyInfo);
+ SignatureUtil.initVerifyWithParam(sig, subjectPublicKeyInfo,
+ SignatureUtil.getParamSpec(sigAlg, id.getParameters()));
+
sig.update(data);
- if (!sig.verify(sigData))
+ if (!sig.verify(sigData)) {
throw new SignatureException("Invalid PKCS #10 signature");
+ }
} catch (InvalidKeyException e) {
- throw new SignatureException("invalid key");
+ throw new SignatureException("Invalid key");
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new SignatureException("Invalid signature parameters", e);
+ } catch (ProviderException e) {
+ throw new SignatureException("Error parsing signature parameters",
+ e.getCause());
}
}
@@ -226,10 +232,14 @@
*/
AlgorithmId algId = null;
try {
- algId = AlgorithmId.get(signature.getAlgorithm());
+ AlgorithmParameters params = signature.getParameters();
+ algId = params == null
+ ? AlgorithmId.get(signature.getAlgorithm())
+ : AlgorithmId.get(params);
} catch (NoSuchAlgorithmException nsae) {
throw new SignatureException(nsae);
}
+
algId.encode(scratch); // sig algorithm
scratch.putBitString(sig); // sig
diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11Key.java b/jdk/src/share/classes/sun/security/pkcs11/P11Key.java
index a07e208..bcffaf0 100644
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Key.java
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Key.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,9 @@
import javax.crypto.interfaces.*;
import javax.crypto.spec.*;
+import sun.security.rsa.RSAUtil.KeyType;
import sun.security.rsa.RSAPublicKeyImpl;
+import sun.security.rsa.RSAPrivateCrtKeyImpl;
import sun.security.internal.interfaces.TlsMasterSecret;
@@ -543,11 +545,8 @@
if (encoded == null) {
fetchValues();
try {
- // XXX make constructor in SunRsaSign provider public
- // and call it directly
- KeyFactory factory = KeyFactory.getInstance
- ("RSA", P11Util.getSunRsaSignProvider());
- Key newKey = factory.translateKey(this);
+ Key newKey = RSAPrivateCrtKeyImpl.newKey
+ (KeyType.RSA, null, n, e, d, p, q, pe, qe, coeff);
encoded = newKey.getEncoded();
} catch (GeneralSecurityException e) {
throw new ProviderException(e);
@@ -647,7 +646,6 @@
private static final class P11RSAPublicKey extends P11Key
implements RSAPublicKey {
private static final long serialVersionUID = -826726289023854455L;
-
private BigInteger n, e;
private byte[] encoded;
P11RSAPublicKey(Session session, long keyID, String algorithm,
@@ -676,7 +674,8 @@
if (encoded == null) {
fetchValues();
try {
- encoded = new RSAPublicKeyImpl(n, e).getEncoded();
+ encoded = RSAPublicKeyImpl.newKey
+ (KeyType.RSA, null, n, e).getEncoded();
} catch (InvalidKeyException e) {
throw new ProviderException(e);
}
diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11RSAKeyFactory.java b/jdk/src/share/classes/sun/security/pkcs11/P11RSAKeyFactory.java
index 0fc06a7..b3bfcc7 100644
--- a/jdk/src/share/classes/sun/security/pkcs11/P11RSAKeyFactory.java
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11RSAKeyFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
import java.security.interfaces.*;
import java.security.spec.*;
+import sun.security.rsa.RSAPublicKeyImpl;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
@@ -60,7 +61,7 @@
} else if ("X.509".equals(key.getFormat())) {
// let SunRsaSign provider parse for us, then recurse
byte[] encoded = key.getEncoded();
- key = new sun.security.rsa.RSAPublicKeyImpl(encoded);
+ key = RSAPublicKeyImpl.newKey(encoded);
return implTranslatePublicKey(key);
} else {
throw new InvalidKeyException("PublicKey must be instance "
@@ -113,7 +114,7 @@
if (keySpec instanceof X509EncodedKeySpec) {
try {
byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();
- PublicKey key = new sun.security.rsa.RSAPublicKeyImpl(encoded);
+ PublicKey key = RSAPublicKeyImpl.newKey(encoded);
return implTranslatePublicKey(key);
} catch (InvalidKeyException e) {
throw new InvalidKeySpecException
diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java b/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java
index af152d8..b09c7b3 100644
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
import java.security.*;
import java.security.interfaces.*;
+import java.security.spec.AlgorithmParameterSpec;
import sun.nio.ch.DirectBuffer;
import sun.security.util.*;
@@ -434,9 +435,9 @@
}
// see JCA spec
+ @Override
protected void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException {
-
if (publicKey == null) {
throw new InvalidKeyException("Key must not be null");
}
@@ -451,9 +452,9 @@
}
// see JCA spec
+ @Override
protected void engineInitSign(PrivateKey privateKey)
throws InvalidKeyException {
-
if (privateKey == null) {
throw new InvalidKeyException("Key must not be null");
}
@@ -468,6 +469,7 @@
}
// see JCA spec
+ @Override
protected void engineUpdate(byte b) throws SignatureException {
ensureInitialized();
switch (type) {
@@ -492,6 +494,7 @@
}
// see JCA spec
+ @Override
protected void engineUpdate(byte[] b, int ofs, int len)
throws SignatureException {
@@ -535,6 +538,7 @@
}
// see JCA spec
+ @Override
protected void engineUpdate(ByteBuffer byteBuffer) {
ensureInitialized();
@@ -585,6 +589,7 @@
}
// see JCA spec
+ @Override
protected byte[] engineSign() throws SignatureException {
ensureInitialized();
@@ -641,6 +646,7 @@
}
// see JCA spec
+ @Override
protected boolean engineVerify(byte[] signature) throws SignatureException {
ensureInitialized();
boolean doCancel = true;
@@ -828,14 +834,31 @@
}
// see JCA spec
+ @Override
protected void engineSetParameter(String param, Object value)
throws InvalidParameterException {
throw new UnsupportedOperationException("setParameter() not supported");
}
+ // see JCA spec
+ @Override
+ protected void engineSetParameter(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ if (params != null) {
+ throw new InvalidAlgorithmParameterException("No parameter accepted");
+ }
+ }
+
// see JCA spec
+ @Override
protected Object engineGetParameter(String param)
throws InvalidParameterException {
throw new UnsupportedOperationException("getParameter() not supported");
}
+
+ // see JCA spec
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ return null;
+ }
}
diff --git a/jdk/src/share/classes/sun/security/provider/DSA.java b/jdk/src/share/classes/sun/security/provider/DSA.java
index 6f08f90..cf3eade 100644
--- a/jdk/src/share/classes/sun/security/provider/DSA.java
+++ b/jdk/src/share/classes/sun/security/provider/DSA.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,8 +33,7 @@
import java.security.*;
import java.security.SecureRandom;
import java.security.interfaces.*;
-import java.security.spec.DSAParameterSpec;
-import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.*;
import sun.security.util.Debug;
import sun.security.util.DerValue;
@@ -314,11 +313,24 @@
throw new InvalidParameterException("No parameter accepted");
}
+ @Override
+ protected void engineSetParameter(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ if (params != null) {
+ throw new InvalidAlgorithmParameterException("No parameter accepted");
+ }
+ }
+
@Deprecated
protected Object engineGetParameter(String key) {
return null;
}
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ return null;
+ }
+
private BigInteger generateR(BigInteger p, BigInteger q, BigInteger g,
BigInteger k) {
diff --git a/jdk/src/share/classes/sun/security/provider/JavaKeyStore.java b/jdk/src/share/classes/sun/security/provider/JavaKeyStore.java
index e3776a4..0ed7fa1 100644
--- a/jdk/src/share/classes/sun/security/provider/JavaKeyStore.java
+++ b/jdk/src/share/classes/sun/security/provider/JavaKeyStore.java
@@ -694,7 +694,7 @@
// Read the private key
entry.protectedPrivKey =
- IOUtils.readFully(dis, dis.readInt(), true);
+ IOUtils.readExactlyNBytes(dis, dis.readInt());
// Read the certificate chain
int numOfCerts = dis.readInt();
@@ -719,7 +719,7 @@
}
}
// instantiate the certificate
- encoded = IOUtils.readFully(dis, dis.readInt(), true);
+ encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
bais = new ByteArrayInputStream(encoded);
certs.add(cf.generateCertificate(bais));
bais.close();
@@ -758,7 +758,7 @@
cfs.put(certType, cf);
}
}
- encoded = IOUtils.readFully(dis, dis.readInt(), true);
+ encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
bais = new ByteArrayInputStream(encoded);
entry.cert = cf.generateCertificate(bais);
bais.close();
@@ -785,16 +785,13 @@
if (password != null) {
byte computed[], actual[];
computed = md.digest();
- actual = new byte[computed.length];
- dis.readFully(actual);
- for (int i = 0; i < computed.length; i++) {
- if (computed[i] != actual[i]) {
- Throwable t = new UnrecoverableKeyException
+ actual = IOUtils.readExactlyNBytes(dis, computed.length);
+ if (!MessageDigest.isEqual(computed, actual)) {
+ Throwable t = new UnrecoverableKeyException
("Password verification failed");
- throw (IOException)new IOException
+ throw (IOException) new IOException
("Keystore was tampered with, or "
- + "password was incorrect").initCause(t);
- }
+ + "password was incorrect").initCause(t);
}
}
}
diff --git a/jdk/src/share/classes/sun/security/provider/SHA5.java b/jdk/src/share/classes/sun/security/provider/SHA5.java
index ceba1fc..f35006e 100644
--- a/jdk/src/share/classes/sun/security/provider/SHA5.java
+++ b/jdk/src/share/classes/sun/security/provider/SHA5.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -121,7 +121,14 @@
i2bBig4((int)bitsProcessed, buffer, 124);
implCompress(buffer, 0);
- l2bBig(state, 0, out, ofs, engineGetDigestLength());
+ int len = engineGetDigestLength();
+ if (len == 28) {
+ // Special case for SHA-512/224
+ l2bBig(state, 0, out, ofs, 24);
+ i2bBig4((int)(state[3] >> 32), out, ofs + 24);
+ } else {
+ l2bBig(state, 0, out, ofs, len);
+ }
}
/**
@@ -308,4 +315,31 @@
super("SHA-384", 48, INITIAL_HASHES);
}
}
+ public static final class SHA512_224 extends SHA5 {
+
+ private static final long[] INITIAL_HASHES = {
+ 0x8C3D37C819544DA2L, 0x73E1996689DCD4D6L,
+ 0x1DFAB7AE32FF9C82L, 0x679DD514582F9FCFL,
+ 0x0F6D2B697BD44DA8L, 0x77E36F7304C48942L,
+ 0x3F9D85A86A1D36C8L, 0x1112E6AD91D692A1L
+ };
+
+ public SHA512_224() {
+ super("SHA-512/224", 28, INITIAL_HASHES);
+ }
+ }
+
+ public static final class SHA512_256 extends SHA5 {
+
+ private static final long[] INITIAL_HASHES = {
+ 0x22312194FC2BF72CL, 0x9F555FA3C84C64C2L,
+ 0x2393B86B6F53B151L, 0x963877195940EABDL,
+ 0x96283EE2A88EFFE3L, 0xBE5E1E2553863992L,
+ 0x2B0199FC2C85B8AAL, 0x0EB72DDC81C52CA2L
+ };
+
+ public SHA512_256() {
+ super("SHA-512/256", 32, INITIAL_HASHES);
+ }
+ }
}
diff --git a/jdk/src/share/classes/sun/security/provider/SunEntries.java b/jdk/src/share/classes/sun/security/provider/SunEntries.java
index 008fea5..d856978 100644
--- a/jdk/src/share/classes/sun/security/provider/SunEntries.java
+++ b/jdk/src/share/classes/sun/security/provider/SunEntries.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -65,7 +65,7 @@
* and CRLs. Aliases for X.509 are X509.
*
* - PKIX is the certification path validation algorithm described
- * in RFC 3280. The ValidationAlgorithm attribute notes the
+ * in RFC 5280. The ValidationAlgorithm attribute notes the
* specification that this provider implements.
*
* - LDAP is the CertStore type for LDAP repositories. The
@@ -106,6 +106,7 @@
map.put("SecureRandom.NativePRNG",
"sun.security.provider.NativePRNG");
}
+
map.put("SecureRandom.SHA1PRNG",
"sun.security.provider.SecureRandom");
if (nativeAvailable && !useNativePRNG) {
@@ -200,6 +201,14 @@
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.3", "SHA-512");
map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.3",
"SHA-512");
+ map.put("MessageDigest.SHA-512/224", "sun.security.provider.SHA5$SHA512_224");
+ map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.5", "SHA-512/224");
+ map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.5",
+ "SHA-512/224");
+ map.put("MessageDigest.SHA-512/256", "sun.security.provider.SHA5$SHA512_256");
+ map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.6", "SHA-512/256");
+ map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.6",
+ "SHA-512/256");
/*
* Algorithm Parameter Generator engines
@@ -257,7 +266,7 @@
map.put("CertPathBuilder.PKIX",
"sun.security.provider.certpath.SunCertPathBuilder");
map.put("CertPathBuilder.PKIX ValidationAlgorithm",
- "RFC3280");
+ "RFC5280");
/*
* CertPathValidator
@@ -265,7 +274,7 @@
map.put("CertPathValidator.PKIX",
"sun.security.provider.certpath.PKIXCertPathValidator");
map.put("CertPathValidator.PKIX ValidationAlgorithm",
- "RFC3280");
+ "RFC5280");
/*
* CertStores
diff --git a/jdk/src/share/classes/sun/security/provider/certpath/PolicyChecker.java b/jdk/src/share/classes/sun/security/provider/certpath/PolicyChecker.java
index ab82820..dd030d3 100644
--- a/jdk/src/share/classes/sun/security/provider/certpath/PolicyChecker.java
+++ b/jdk/src/share/classes/sun/security/provider/certpath/PolicyChecker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2014, 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
@@ -578,7 +578,7 @@
}
/**
- * Rewrite leaf nodes at the end of validation as described in RFC 3280
+ * Rewrite leaf nodes at the end of validation as described in RFC 5280
* section 6.1.5: Step (g)(iii). Leaf nodes with anyPolicy are replaced
* by nodes explicitly representing initial policies not already
* represented by leaf nodes.
diff --git a/jdk/src/share/classes/sun/security/provider/certpath/PolicyNodeImpl.java b/jdk/src/share/classes/sun/security/provider/certpath/PolicyNodeImpl.java
index 02109d4..a42a1e8 100644
--- a/jdk/src/share/classes/sun/security/provider/certpath/PolicyNodeImpl.java
+++ b/jdk/src/share/classes/sun/security/provider/certpath/PolicyNodeImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2014, 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
@@ -56,7 +56,7 @@
private PolicyNodeImpl mParent;
private HashSet<PolicyNodeImpl> mChildren;
- // the 4 fields specified by RFC 3280
+ // the 4 fields specified by RFC 5280
private String mValidPolicy;
private HashSet<PolicyQualifierInfo> mQualifierSet;
private boolean mCriticalityIndicator;
diff --git a/jdk/src/share/classes/sun/security/rsa/MGF1.java b/jdk/src/share/classes/sun/security/rsa/MGF1.java
new file mode 100644
index 0000000..6bd2166
--- /dev/null
+++ b/jdk/src/share/classes/sun/security/rsa/MGF1.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.security.rsa;
+
+import java.security.*;
+
+/**
+ * This class implements the MGF1 mask generation function defined in PKCS#1
+ * v2.2 B.2.1 (https://tools.ietf.org/html/rfc8017#appendix-B.2.1). A mask
+ * generation function takes an octet string of variable length and a
+ * desired output length as input and outputs an octet string of the
+ * desired length. MGF1 is a mask generation function based on a hash
+ * function, i.e. message digest algorithm.
+ *
+ * @since 8
+ */
+public final class MGF1 {
+
+ private final MessageDigest md;
+
+ /**
+ * Construct an instance of MGF1 based on the specified digest algorithm.
+ */
+ MGF1(String mdAlgo) throws NoSuchAlgorithmException {
+ this.md = MessageDigest.getInstance(mdAlgo);
+ }
+
+ /**
+ * Using the specified seed bytes, generate the mask, xor the mask
+ * with the specified output buffer and store the result into the
+ * output buffer (essentially replaced in place).
+ *
+ * @param seed the buffer holding the seed bytes
+ * @param seedOfs the index of the seed bytes
+ * @param seedLen the length of the seed bytes to be used by MGF1
+ * @param maskLen the intended length of the generated mask
+ * @param out the output buffer holding the mask
+ * @param outOfs the index of the output buffer for the mask
+ */
+ void generateAndXor(byte[] seed, int seedOfs, int seedLen, int maskLen,
+ byte[] out, int outOfs) throws RuntimeException {
+ byte[] C = new byte[4]; // 32 bit counter
+ byte[] digest = new byte[md.getDigestLength()];
+ while (maskLen > 0) {
+ md.update(seed, seedOfs, seedLen);
+ md.update(C);
+ try {
+ md.digest(digest, 0, digest.length);
+ } catch (DigestException e) {
+ // should never happen
+ throw new RuntimeException(e.toString());
+ }
+ for (int i = 0; (i < digest.length) && (maskLen > 0); maskLen--) {
+ out[outOfs++] ^= digest[i++];
+ }
+ if (maskLen > 0) {
+ // increment counter
+ for (int i = C.length - 1; (++C[i] == 0) && (i > 0); i--) {
+ // empty
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the name of this MGF1 instance, i.e. "MGF1" followed by the
+ * digest algorithm it based on.
+ */
+ String getName() {
+ return "MGF1" + md.getAlgorithm();
+ }
+}
diff --git a/jdk/src/share/classes/sun/security/rsa/PSSParameters.java b/jdk/src/share/classes/sun/security/rsa/PSSParameters.java
new file mode 100644
index 0000000..6b7ff78
--- /dev/null
+++ b/jdk/src/share/classes/sun/security/rsa/PSSParameters.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.rsa;
+
+import java.io.*;
+import sun.security.util.*;
+import sun.security.x509.*;
+import java.security.AlgorithmParametersSpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
+import static java.security.spec.PSSParameterSpec.DEFAULT;
+
+/**
+ * This class implements the PSS parameters used with the RSA
+ * signatures in PSS padding. Here is its ASN.1 definition:
+ * RSASSA-PSS-params ::= SEQUENCE {
+ * hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
+ * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
+ * saltLength [2] INTEGER DEFAULT 20
+ * trailerField [3] TrailerField DEFAULT trailerFieldBC
+ * }
+ *
+ * @author Valerie Peng
+ *
+ */
+
+public final class PSSParameters extends AlgorithmParametersSpi {
+
+ private PSSParameterSpec spec;
+
+ public PSSParameters() {
+ }
+
+ @Override
+ protected void engineInit(AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException {
+ if (!(paramSpec instanceof PSSParameterSpec)) {
+ throw new InvalidParameterSpecException
+ ("Inappropriate parameter specification");
+ }
+ PSSParameterSpec spec = (PSSParameterSpec) paramSpec;
+
+ String mgfName = spec.getMGFAlgorithm();
+ if (!spec.getMGFAlgorithm().equalsIgnoreCase("MGF1")) {
+ throw new InvalidParameterSpecException("Unsupported mgf " +
+ mgfName + "; MGF1 only");
+ }
+ AlgorithmParameterSpec mgfSpec = spec.getMGFParameters();
+ if (!(mgfSpec instanceof MGF1ParameterSpec)) {
+ throw new InvalidParameterSpecException("Inappropriate mgf " +
+ "parameters; non-null MGF1ParameterSpec only");
+ }
+ this.spec = spec;
+ }
+
+ @Override
+ protected void engineInit(byte[] encoded) throws IOException {
+ // first initialize with the DEFAULT values before
+ // retrieving from the encoding bytes
+ String mdName = DEFAULT.getDigestAlgorithm();
+ MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec) DEFAULT.getMGFParameters();
+ int saltLength = DEFAULT.getSaltLength();
+ int trailerField = DEFAULT.getTrailerField();
+
+ DerInputStream der = new DerInputStream(encoded);
+ DerValue[] datum = der.getSequence(4);
+
+ for (DerValue d : datum) {
+ if (d.isContextSpecific((byte) 0x00)) {
+ // hash algid
+ mdName = AlgorithmId.parse
+ (d.data.getDerValue()).getName();
+ } else if (d.isContextSpecific((byte) 0x01)) {
+ // mgf algid
+ AlgorithmId val = AlgorithmId.parse(d.data.getDerValue());
+ if (!val.getOID().equals(AlgorithmId.mgf1_oid)) {
+ throw new IOException("Only MGF1 mgf is supported");
+ }
+ AlgorithmId params = AlgorithmId.parse(
+ new DerValue(val.getEncodedParams()));
+ String mgfDigestName = params.getName();
+ switch (mgfDigestName) {
+ case "SHA-1":
+ mgfSpec = MGF1ParameterSpec.SHA1;
+ break;
+ case "SHA-224":
+ mgfSpec = MGF1ParameterSpec.SHA224;
+ break;
+ case "SHA-256":
+ mgfSpec = MGF1ParameterSpec.SHA256;
+ break;
+ case "SHA-384":
+ mgfSpec = MGF1ParameterSpec.SHA384;
+ break;
+ case "SHA-512":
+ mgfSpec = MGF1ParameterSpec.SHA512;
+ break;
+ case "SHA-512/224":
+ mgfSpec = MGF1ParameterSpec.SHA512_224;
+ break;
+ case "SHA-512/256":
+ mgfSpec = MGF1ParameterSpec.SHA512_256;
+ break;
+ default:
+ throw new IOException
+ ("Unrecognized message digest algorithm " +
+ mgfDigestName);
+ }
+ } else if (d.isContextSpecific((byte) 0x02)) {
+ // salt length
+ saltLength = d.data.getDerValue().getInteger();
+ if (saltLength < 0) {
+ throw new IOException("Negative value for saltLength");
+ }
+ } else if (d.isContextSpecific((byte) 0x03)) {
+ // trailer field
+ trailerField = d.data.getDerValue().getInteger();
+ if (trailerField != 1) {
+ throw new IOException("Unsupported trailerField value " +
+ trailerField);
+ }
+ } else {
+ throw new IOException("Invalid encoded PSSParameters");
+ }
+ }
+
+ this.spec = new PSSParameterSpec(mdName, "MGF1", mgfSpec,
+ saltLength, trailerField);
+ }
+
+ @Override
+ protected void engineInit(byte[] encoded, String decodingMethod)
+ throws IOException {
+ if ((decodingMethod != null) &&
+ (!decodingMethod.equalsIgnoreCase("ASN.1"))) {
+ throw new IllegalArgumentException("Only support ASN.1 format");
+ }
+ engineInit(encoded);
+ }
+
+ @Override
+ protected <T extends AlgorithmParameterSpec>
+ T engineGetParameterSpec(Class<T> paramSpec)
+ throws InvalidParameterSpecException {
+ if (PSSParameterSpec.class.isAssignableFrom(paramSpec)) {
+ return paramSpec.cast(spec);
+ } else {
+ throw new InvalidParameterSpecException
+ ("Inappropriate parameter specification");
+ }
+ }
+
+ @Override
+ protected byte[] engineGetEncoded() throws IOException {
+ return getEncoded(spec);
+ }
+
+ @Override
+ protected byte[] engineGetEncoded(String encMethod) throws IOException {
+ if ((encMethod != null) &&
+ (!encMethod.equalsIgnoreCase("ASN.1"))) {
+ throw new IllegalArgumentException("Only support ASN.1 format");
+ }
+ return engineGetEncoded();
+ }
+
+ @Override
+ protected String engineToString() {
+ return spec.toString();
+ }
+
+ /**
+ * Returns the encoding of a {@link PSSParameterSpec} object. This method
+ * is used in this class and {@link AlgorithmId}.
+ *
+ * @param spec a {@code PSSParameterSpec} object
+ * @return its DER encoding
+ * @throws IOException if the name of a MessageDigest or MaskGenAlgorithm
+ * is unsupported
+ */
+ public static byte[] getEncoded(PSSParameterSpec spec) throws IOException {
+
+ AlgorithmParameterSpec mgfSpec = spec.getMGFParameters();
+ if (!(mgfSpec instanceof MGF1ParameterSpec)) {
+ throw new IOException("Cannot encode " + mgfSpec);
+ }
+
+ MGF1ParameterSpec mgf1Spec = (MGF1ParameterSpec)mgfSpec;
+
+ DerOutputStream tmp = new DerOutputStream();
+ DerOutputStream tmp2, tmp3;
+
+ // MD
+ AlgorithmId mdAlgId;
+ try {
+ mdAlgId = AlgorithmId.get(spec.getDigestAlgorithm());
+ } catch (NoSuchAlgorithmException nsae) {
+ throw new IOException("AlgorithmId " + spec.getDigestAlgorithm() +
+ " impl not found");
+ }
+ if (!mdAlgId.getOID().equals(AlgorithmId.SHA_oid)) {
+ tmp2 = new DerOutputStream();
+ mdAlgId.derEncode(tmp2);
+ tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0),
+ tmp2);
+ }
+
+ // MGF
+ AlgorithmId mgfDigestId;
+ try {
+ mgfDigestId = AlgorithmId.get(mgf1Spec.getDigestAlgorithm());
+ } catch (NoSuchAlgorithmException nase) {
+ throw new IOException("AlgorithmId " +
+ mgf1Spec.getDigestAlgorithm() + " impl not found");
+ }
+
+ if (!mgfDigestId.getOID().equals(AlgorithmId.SHA_oid)) {
+ tmp2 = new DerOutputStream();
+ tmp2.putOID(AlgorithmId.mgf1_oid);
+ mgfDigestId.encode(tmp2);
+ tmp3 = new DerOutputStream();
+ tmp3.write(DerValue.tag_Sequence, tmp2);
+ tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 1),
+ tmp3);
+ }
+
+ // SaltLength
+ if (spec.getSaltLength() != 20) {
+ tmp2 = new DerOutputStream();
+ tmp2.putInteger(spec.getSaltLength());
+ tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 2),
+ tmp2);
+ }
+
+ // TrailerField
+ if (spec.getTrailerField() != PSSParameterSpec.TRAILER_FIELD_BC) {
+ tmp2 = new DerOutputStream();
+ tmp2.putInteger(spec.getTrailerField());
+ tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 3),
+ tmp2);
+ }
+
+ // Put all together under a SEQUENCE tag
+ DerOutputStream out = new DerOutputStream();
+ out.write(DerValue.tag_Sequence, tmp);
+ return out.toByteArray();
+ }
+}
diff --git a/jdk/src/share/classes/sun/security/rsa/RSAKeyFactory.java b/jdk/src/share/classes/sun/security/rsa/RSAKeyFactory.java
index 54aa0d2..5445125 100644
--- a/jdk/src/share/classes/sun/security/rsa/RSAKeyFactory.java
+++ b/jdk/src/share/classes/sun/security/rsa/RSAKeyFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,10 +32,15 @@
import java.security.spec.*;
import sun.security.action.GetPropertyAction;
+import sun.security.x509.AlgorithmId;
+import static sun.security.rsa.RSAUtil.KeyType;
/**
- * KeyFactory for RSA keys. Keys must be instances of PublicKey or PrivateKey
- * and getAlgorithm() must return "RSA". For such keys, it supports conversion
+ * KeyFactory for RSA keys, e.g. "RSA", "RSASSA-PSS".
+ * Keys must be instances of PublicKey or PrivateKey
+ * and getAlgorithm() must return a value which matches the type which are
+ * specified during construction time of the KeyFactory object.
+ * For such keys, it supports conversion
* between the following:
*
* For public keys:
@@ -58,21 +63,21 @@
* @since 1.5
* @author Andreas Sterbenz
*/
-public final class RSAKeyFactory extends KeyFactorySpi {
+public class RSAKeyFactory extends KeyFactorySpi {
- private final static Class<?> rsaPublicKeySpecClass =
- RSAPublicKeySpec.class;
- private final static Class<?> rsaPrivateKeySpecClass =
- RSAPrivateKeySpec.class;
- private final static Class<?> rsaPrivateCrtKeySpecClass =
- RSAPrivateCrtKeySpec.class;
-
- private final static Class<?> x509KeySpecClass = X509EncodedKeySpec.class;
- private final static Class<?> pkcs8KeySpecClass = PKCS8EncodedKeySpec.class;
+ private static final Class<?> RSA_PUB_KEYSPEC_CLS = RSAPublicKeySpec.class;
+ private static final Class<?> RSA_PRIV_KEYSPEC_CLS =
+ RSAPrivateKeySpec.class;
+ private static final Class<?> RSA_PRIVCRT_KEYSPEC_CLS =
+ RSAPrivateCrtKeySpec.class;
+ private static final Class<?> X509_KEYSPEC_CLS = X509EncodedKeySpec.class;
+ private static final Class<?> PKCS8_KEYSPEC_CLS = PKCS8EncodedKeySpec.class;
public final static int MIN_MODLEN = 512;
public final static int MAX_MODLEN = 16384;
+ private final KeyType type;
+
/*
* If the modulus length is above this value, restrict the size of
* the exponent to something that can be reasonably computed. We
@@ -88,11 +93,18 @@
new GetPropertyAction(
"sun.security.rsa.restrictRSAExponent", "true")));
- // instance used for static translateKey();
- private final static RSAKeyFactory INSTANCE = new RSAKeyFactory();
+ static RSAKeyFactory getInstance(KeyType type) {
+ return new RSAKeyFactory(type);
+ }
- public RSAKeyFactory() {
- // empty
+ // Internal utility method for checking key algorithm
+ private static void checkKeyAlgo(Key key, String expectedAlg)
+ throws InvalidKeyException {
+ String keyAlg = key.getAlgorithm();
+ if (keyAlg == null || !(keyAlg.equalsIgnoreCase(expectedAlg))) {
+ throw new InvalidKeyException("Expected a " + expectedAlg
+ + " key, but got " + keyAlg);
+ }
}
/**
@@ -108,7 +120,13 @@
(key instanceof RSAPublicKeyImpl)) {
return (RSAKey)key;
} else {
- return (RSAKey)INSTANCE.engineTranslateKey(key);
+ try {
+ KeyType type = KeyType.lookup(key.getAlgorithm());
+ RSAKeyFactory kf = RSAKeyFactory.getInstance(type);
+ return (RSAKey) kf.engineTranslateKey(key);
+ } catch (ProviderException e) {
+ throw new InvalidKeyException(e);
+ }
}
}
@@ -172,6 +190,15 @@
}
}
+ // disallowed as KeyType is required
+ private RSAKeyFactory() {
+ this.type = KeyType.RSA;
+ }
+
+ public RSAKeyFactory(KeyType type) {
+ this.type = type;
+ }
+
/**
* Translate an RSA key into a SunRsaSign RSA key. If conversion is
* not possible, throw an InvalidKeyException.
@@ -181,9 +208,14 @@
if (key == null) {
throw new InvalidKeyException("Key must not be null");
}
- String keyAlg = key.getAlgorithm();
- if (keyAlg.equals("RSA") == false) {
- throw new InvalidKeyException("Not an RSA key: " + keyAlg);
+ // ensure the key algorithm matches the current KeyFactory instance
+ checkKeyAlgo(key, type.keyAlgo());
+
+ // no translation needed if the key is already our own impl
+ if ((key instanceof RSAPrivateKeyImpl) ||
+ (key instanceof RSAPrivateCrtKeyImpl) ||
+ (key instanceof RSAPublicKeyImpl)) {
+ return key;
}
if (key instanceof PublicKey) {
return translatePublicKey((PublicKey)key);
@@ -222,22 +254,21 @@
private PublicKey translatePublicKey(PublicKey key)
throws InvalidKeyException {
if (key instanceof RSAPublicKey) {
- if (key instanceof RSAPublicKeyImpl) {
- return key;
- }
RSAPublicKey rsaKey = (RSAPublicKey)key;
try {
return new RSAPublicKeyImpl(
+ RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
rsaKey.getModulus(),
- rsaKey.getPublicExponent()
- );
- } catch (RuntimeException e) {
+ rsaKey.getPublicExponent());
+ } catch (ProviderException e) {
// catch providers that incorrectly implement RSAPublicKey
throw new InvalidKeyException("Invalid key", e);
}
} else if ("X.509".equals(key.getFormat())) {
- byte[] encoded = key.getEncoded();
- return new RSAPublicKeyImpl(encoded);
+ RSAPublicKey translated = new RSAPublicKeyImpl(key.getEncoded());
+ // ensure the key algorithm matches the current KeyFactory instance
+ checkKeyAlgo(translated, type.keyAlgo());
+ return translated;
} else {
throw new InvalidKeyException("Public keys must be instance "
+ "of RSAPublicKey or have X.509 encoding");
@@ -248,12 +279,10 @@
private PrivateKey translatePrivateKey(PrivateKey key)
throws InvalidKeyException {
if (key instanceof RSAPrivateCrtKey) {
- if (key instanceof RSAPrivateCrtKeyImpl) {
- return key;
- }
RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
try {
return new RSAPrivateCrtKeyImpl(
+ RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
rsaKey.getModulus(),
rsaKey.getPublicExponent(),
rsaKey.getPrivateExponent(),
@@ -263,27 +292,28 @@
rsaKey.getPrimeExponentQ(),
rsaKey.getCrtCoefficient()
);
- } catch (RuntimeException e) {
+ } catch (ProviderException e) {
// catch providers that incorrectly implement RSAPrivateCrtKey
throw new InvalidKeyException("Invalid key", e);
}
} else if (key instanceof RSAPrivateKey) {
- if (key instanceof RSAPrivateKeyImpl) {
- return key;
- }
RSAPrivateKey rsaKey = (RSAPrivateKey)key;
try {
return new RSAPrivateKeyImpl(
+ RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
rsaKey.getModulus(),
rsaKey.getPrivateExponent()
);
- } catch (RuntimeException e) {
+ } catch (ProviderException e) {
// catch providers that incorrectly implement RSAPrivateKey
throw new InvalidKeyException("Invalid key", e);
}
} else if ("PKCS#8".equals(key.getFormat())) {
- byte[] encoded = key.getEncoded();
- return RSAPrivateCrtKeyImpl.newKey(encoded);
+ RSAPrivateKey translated =
+ RSAPrivateCrtKeyImpl.newKey(key.getEncoded());
+ // ensure the key algorithm matches the current KeyFactory instance
+ checkKeyAlgo(translated, type.keyAlgo());
+ return translated;
} else {
throw new InvalidKeyException("Private keys must be instance "
+ "of RSAPrivate(Crt)Key or have PKCS#8 encoding");
@@ -295,13 +325,21 @@
throws GeneralSecurityException {
if (keySpec instanceof X509EncodedKeySpec) {
X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec;
- return new RSAPublicKeyImpl(x509Spec.getEncoded());
+ RSAPublicKey generated = new RSAPublicKeyImpl(x509Spec.getEncoded());
+ // ensure the key algorithm matches the current KeyFactory instance
+ checkKeyAlgo(generated, type.keyAlgo());
+ return generated;
} else if (keySpec instanceof RSAPublicKeySpec) {
RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec;
- return new RSAPublicKeyImpl(
- rsaSpec.getModulus(),
- rsaSpec.getPublicExponent()
- );
+ try {
+ return new RSAPublicKeyImpl(
+ RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
+ rsaSpec.getModulus(),
+ rsaSpec.getPublicExponent()
+ );
+ } catch (ProviderException e) {
+ throw new InvalidKeySpecException(e);
+ }
} else {
throw new InvalidKeySpecException("Only RSAPublicKeySpec "
+ "and X509EncodedKeySpec supported for RSA public keys");
@@ -313,25 +351,38 @@
throws GeneralSecurityException {
if (keySpec instanceof PKCS8EncodedKeySpec) {
PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec;
- return RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded());
+ RSAPrivateKey generated = RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded());
+ // ensure the key algorithm matches the current KeyFactory instance
+ checkKeyAlgo(generated, type.keyAlgo());
+ return generated;
} else if (keySpec instanceof RSAPrivateCrtKeySpec) {
RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec;
- return new RSAPrivateCrtKeyImpl(
- rsaSpec.getModulus(),
- rsaSpec.getPublicExponent(),
- rsaSpec.getPrivateExponent(),
- rsaSpec.getPrimeP(),
- rsaSpec.getPrimeQ(),
- rsaSpec.getPrimeExponentP(),
- rsaSpec.getPrimeExponentQ(),
- rsaSpec.getCrtCoefficient()
- );
+ try {
+ return new RSAPrivateCrtKeyImpl(
+ RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
+ rsaSpec.getModulus(),
+ rsaSpec.getPublicExponent(),
+ rsaSpec.getPrivateExponent(),
+ rsaSpec.getPrimeP(),
+ rsaSpec.getPrimeQ(),
+ rsaSpec.getPrimeExponentP(),
+ rsaSpec.getPrimeExponentQ(),
+ rsaSpec.getCrtCoefficient()
+ );
+ } catch (ProviderException e) {
+ throw new InvalidKeySpecException(e);
+ }
} else if (keySpec instanceof RSAPrivateKeySpec) {
RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec;
- return new RSAPrivateKeyImpl(
- rsaSpec.getModulus(),
- rsaSpec.getPrivateExponent()
- );
+ try {
+ return new RSAPrivateKeyImpl(
+ RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
+ rsaSpec.getModulus(),
+ rsaSpec.getPrivateExponent()
+ );
+ } catch (ProviderException e) {
+ throw new InvalidKeySpecException(e);
+ }
} else {
throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec "
+ "and PKCS8EncodedKeySpec supported for RSA private keys");
@@ -350,12 +401,13 @@
}
if (key instanceof RSAPublicKey) {
RSAPublicKey rsaKey = (RSAPublicKey)key;
- if (rsaPublicKeySpecClass.isAssignableFrom(keySpec)) {
+ if (RSA_PUB_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
return keySpec.cast(new RSAPublicKeySpec(
rsaKey.getModulus(),
- rsaKey.getPublicExponent()
+ rsaKey.getPublicExponent(),
+ rsaKey.getParams()
));
- } else if (x509KeySpecClass.isAssignableFrom(keySpec)) {
+ } else if (X509_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
return keySpec.cast(new X509EncodedKeySpec(key.getEncoded()));
} else {
throw new InvalidKeySpecException
@@ -363,9 +415,9 @@
+ "X509EncodedKeySpec for RSA public keys");
}
} else if (key instanceof RSAPrivateKey) {
- if (pkcs8KeySpecClass.isAssignableFrom(keySpec)) {
+ if (PKCS8_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
return keySpec.cast(new PKCS8EncodedKeySpec(key.getEncoded()));
- } else if (rsaPrivateCrtKeySpecClass.isAssignableFrom(keySpec)) {
+ } else if (RSA_PRIVCRT_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
if (key instanceof RSAPrivateCrtKey) {
RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey)key;
return keySpec.cast(new RSAPrivateCrtKeySpec(
@@ -376,17 +428,19 @@
crtKey.getPrimeQ(),
crtKey.getPrimeExponentP(),
crtKey.getPrimeExponentQ(),
- crtKey.getCrtCoefficient()
+ crtKey.getCrtCoefficient(),
+ crtKey.getParams()
));
} else {
throw new InvalidKeySpecException
("RSAPrivateCrtKeySpec can only be used with CRT keys");
}
- } else if (rsaPrivateKeySpecClass.isAssignableFrom(keySpec)) {
+ } else if (RSA_PRIV_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
RSAPrivateKey rsaKey = (RSAPrivateKey)key;
return keySpec.cast(new RSAPrivateKeySpec(
rsaKey.getModulus(),
- rsaKey.getPrivateExponent()
+ rsaKey.getPrivateExponent(),
+ rsaKey.getParams()
));
} else {
throw new InvalidKeySpecException
@@ -398,4 +452,16 @@
throw new InvalidKeySpecException("Neither public nor private key");
}
}
+
+ public static final class Legacy extends RSAKeyFactory {
+ public Legacy() {
+ super(KeyType.RSA);
+ }
+ }
+
+ public static final class PSS extends RSAKeyFactory {
+ public PSS() {
+ super(KeyType.PSS);
+ }
+ }
}
diff --git a/jdk/src/share/classes/sun/security/rsa/RSAKeyPairGenerator.java b/jdk/src/share/classes/sun/security/rsa/RSAKeyPairGenerator.java
index 6ad77b5..dc1b062 100644
--- a/jdk/src/share/classes/sun/security/rsa/RSAKeyPairGenerator.java
+++ b/jdk/src/share/classes/sun/security/rsa/RSAKeyPairGenerator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,9 @@
import sun.security.jca.JCAUtil;
import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
+import static sun.security.util.SecurityProviderConstants.DEF_RSASSA_PSS_KEY_SIZE;
+import sun.security.x509.AlgorithmId;
+import static sun.security.rsa.RSAUtil.KeyType;
/**
* RSA keypair generation. Standard algorithm, minimum key length 512 bit.
@@ -43,7 +46,7 @@
* @since 1.5
* @author Andreas Sterbenz
*/
-public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
+public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
// public exponent to use
private BigInteger publicExponent;
@@ -51,35 +54,31 @@
// size of the key to generate, >= RSAKeyFactory.MIN_MODLEN
private int keySize;
+ private final KeyType type;
+ private AlgorithmId rsaId;
+
// PRNG to use
private SecureRandom random;
- public RSAKeyPairGenerator() {
+ RSAKeyPairGenerator(KeyType type, int defKeySize) {
+ this.type = type;
// initialize to default in case the app does not call initialize()
- initialize(DEF_RSA_KEY_SIZE, null);
+ initialize(defKeySize, null);
}
// initialize the generator. See JCA doc
public void initialize(int keySize, SecureRandom random) {
-
- // do not allow unreasonably small or large key sizes,
- // probably user error
try {
- RSAKeyFactory.checkKeyLengths(keySize, RSAKeyGenParameterSpec.F4,
- 512, 64 * 1024);
- } catch (InvalidKeyException e) {
- throw new InvalidParameterException(e.getMessage());
+ initialize(new RSAKeyGenParameterSpec(keySize,
+ RSAKeyGenParameterSpec.F4), null);
+ } catch (InvalidAlgorithmParameterException iape) {
+ throw new InvalidParameterException(iape.getMessage());
}
-
- this.keySize = keySize;
- this.random = random;
- this.publicExponent = RSAKeyGenParameterSpec.F4;
}
// second initialize method. See JCA doc.
public void initialize(AlgorithmParameterSpec params, SecureRandom random)
throws InvalidAlgorithmParameterException {
-
if (params instanceof RSAKeyGenParameterSpec == false) {
throw new InvalidAlgorithmParameterException
("Params must be instance of RSAKeyGenParameterSpec");
@@ -88,6 +87,7 @@
RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params;
int tmpKeySize = rsaSpec.getKeysize();
BigInteger tmpPublicExponent = rsaSpec.getPublicExponent();
+ AlgorithmParameterSpec tmpParams = rsaSpec.getKeyParams();
if (tmpPublicExponent == null) {
tmpPublicExponent = RSAKeyGenParameterSpec.F4;
@@ -111,6 +111,13 @@
"Invalid key sizes", e);
}
+ try {
+ this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams);
+ } catch (ProviderException e) {
+ throw new InvalidAlgorithmParameterException(
+ "Invalid key parameters", e);
+ }
+
this.keySize = tmpKeySize;
this.publicExponent = tmpPublicExponent;
this.random = random;
@@ -166,9 +173,9 @@
BigInteger coeff = q.modInverse(p);
try {
- PublicKey publicKey = new RSAPublicKeyImpl(n, e);
- PrivateKey privateKey =
- new RSAPrivateCrtKeyImpl(n, e, d, p, q, pe, qe, coeff);
+ PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e);
+ PrivateKey privateKey = new RSAPrivateCrtKeyImpl(
+ rsaId, n, e, d, p, q, pe, qe, coeff);
return new KeyPair(publicKey, privateKey);
} catch (InvalidKeyException exc) {
// invalid key exception only thrown for keys < 512 bit,
@@ -178,4 +185,15 @@
}
}
+ public static final class Legacy extends RSAKeyPairGenerator {
+ public Legacy() {
+ super(KeyType.RSA, DEF_RSA_KEY_SIZE);
+ }
+ }
+
+ public static final class PSS extends RSAKeyPairGenerator {
+ public PSS() {
+ super(KeyType.PSS, DEF_RSASSA_PSS_KEY_SIZE);
+ }
+ }
}
diff --git a/jdk/src/share/classes/sun/security/rsa/RSAPSSSignature.java b/jdk/src/share/classes/sun/security/rsa/RSAPSSSignature.java
new file mode 100644
index 0000000..dd29595
--- /dev/null
+++ b/jdk/src/share/classes/sun/security/rsa/RSAPSSSignature.java
@@ -0,0 +1,619 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.rsa;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.PSSParameterSpec;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.interfaces.*;
+
+import java.util.Arrays;
+import java.util.Hashtable;
+
+import sun.security.util.*;
+import sun.security.jca.JCAUtil;
+
+
+/**
+ * PKCS#1 v2.2 RSASSA-PSS signatures with various message digest algorithms.
+ * RSASSA-PSS implementation takes the message digest algorithm, MGF algorithm,
+ * and salt length values through the required signature PSS parameters.
+ * We support SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and
+ * SHA-512/256 message digest algorithms and MGF1 mask generation function.
+ *
+ * @since 8
+ */
+public class RSAPSSSignature extends SignatureSpi {
+
+ private static final boolean DEBUG = false;
+
+ // utility method for comparing digest algorithms
+ // NOTE that first argument is assumed to be standard digest name
+ private boolean isDigestEqual(String stdAlg, String givenAlg) {
+ if (stdAlg == null || givenAlg == null) return false;
+
+ if (givenAlg.indexOf("-") != -1) {
+ return stdAlg.equalsIgnoreCase(givenAlg);
+ } else {
+ if (stdAlg.equals("SHA-1")) {
+ return (givenAlg.equalsIgnoreCase("SHA")
+ || givenAlg.equalsIgnoreCase("SHA1"));
+ } else {
+ StringBuilder sb = new StringBuilder(givenAlg);
+ // case-insensitive check
+ if (givenAlg.regionMatches(true, 0, "SHA", 0, 3)) {
+ givenAlg = sb.insert(3, "-").toString();
+ return stdAlg.equalsIgnoreCase(givenAlg);
+ } else {
+ throw new ProviderException("Unsupported digest algorithm "
+ + givenAlg);
+ }
+ }
+ }
+ }
+
+ private static final byte[] EIGHT_BYTES_OF_ZEROS = new byte[8];
+
+ private static final Hashtable<String, Integer> DIGEST_LENGTHS =
+ new Hashtable<String, Integer>();
+ static {
+ DIGEST_LENGTHS.put("SHA-1", 20);
+ DIGEST_LENGTHS.put("SHA", 20);
+ DIGEST_LENGTHS.put("SHA1", 20);
+ DIGEST_LENGTHS.put("SHA-224", 28);
+ DIGEST_LENGTHS.put("SHA224", 28);
+ DIGEST_LENGTHS.put("SHA-256", 32);
+ DIGEST_LENGTHS.put("SHA256", 32);
+ DIGEST_LENGTHS.put("SHA-384", 48);
+ DIGEST_LENGTHS.put("SHA384", 48);
+ DIGEST_LENGTHS.put("SHA-512", 64);
+ DIGEST_LENGTHS.put("SHA512", 64);
+ DIGEST_LENGTHS.put("SHA-512/224", 28);
+ DIGEST_LENGTHS.put("SHA512/224", 28);
+ DIGEST_LENGTHS.put("SHA-512/256", 32);
+ DIGEST_LENGTHS.put("SHA512/256", 32);
+ }
+
+ // message digest implementation we use for hashing the data
+ private MessageDigest md;
+ // flag indicating whether the digest is reset
+ private boolean digestReset = true;
+
+ // private key, if initialized for signing
+ private RSAPrivateKey privKey = null;
+ // public key, if initialized for verifying
+ private RSAPublicKey pubKey = null;
+ // PSS parameters from signatures and keys respectively
+ private PSSParameterSpec sigParams = null; // required for PSS signatures
+
+ // PRNG used to generate salt bytes if none given
+ private SecureRandom random;
+
+ /**
+ * Construct a new RSAPSSSignatur with arbitrary digest algorithm
+ */
+ public RSAPSSSignature() {
+ this.md = null;
+ }
+
+ // initialize for verification. See JCA doc
+ @Override
+ protected void engineInitVerify(PublicKey publicKey)
+ throws InvalidKeyException {
+ if (!(publicKey instanceof RSAPublicKey)) {
+ throw new InvalidKeyException("key must be RSAPublicKey");
+ }
+ this.pubKey = (RSAPublicKey) isValid((RSAKey)publicKey);
+ this.privKey = null;
+ resetDigest();
+ }
+
+ // initialize for signing. See JCA doc
+ @Override
+ protected void engineInitSign(PrivateKey privateKey)
+ throws InvalidKeyException {
+ engineInitSign(privateKey, null);
+ }
+
+ // initialize for signing. See JCA doc
+ @Override
+ protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
+ throws InvalidKeyException {
+ if (!(privateKey instanceof RSAPrivateKey)) {
+ throw new InvalidKeyException("key must be RSAPrivateKey");
+ }
+ this.privKey = (RSAPrivateKey) isValid((RSAKey)privateKey);
+ this.pubKey = null;
+ this.random =
+ (random == null? JCAUtil.getSecureRandom() : random);
+ resetDigest();
+ }
+
+ /**
+ * Utility method for checking the key PSS parameters against signature
+ * PSS parameters.
+ * Returns false if any of the digest/MGF algorithms and trailerField
+ * values does not match or if the salt length in key parameters is
+ * larger than the value in signature parameters.
+ */
+ private static boolean isCompatible(AlgorithmParameterSpec keyParams,
+ PSSParameterSpec sigParams) {
+ if (keyParams == null) {
+ // key with null PSS parameters means no restriction
+ return true;
+ }
+ if (!(keyParams instanceof PSSParameterSpec)) {
+ return false;
+ }
+ // nothing to compare yet, defer the check to when sigParams is set
+ if (sigParams == null) {
+ return true;
+ }
+ PSSParameterSpec pssKeyParams = (PSSParameterSpec) keyParams;
+ // first check the salt length requirement
+ if (pssKeyParams.getSaltLength() > sigParams.getSaltLength()) {
+ return false;
+ }
+
+ // compare equality of the rest of fields based on DER encoding
+ PSSParameterSpec keyParams2 =
+ new PSSParameterSpec(pssKeyParams.getDigestAlgorithm(),
+ pssKeyParams.getMGFAlgorithm(),
+ pssKeyParams.getMGFParameters(),
+ sigParams.getSaltLength(),
+ pssKeyParams.getTrailerField());
+ PSSParameters ap = new PSSParameters();
+ // skip the JCA overhead
+ try {
+ ap.engineInit(keyParams2);
+ byte[] encoded = ap.engineGetEncoded();
+ ap.engineInit(sigParams);
+ byte[] encoded2 = ap.engineGetEncoded();
+ return Arrays.equals(encoded, encoded2);
+ } catch (Exception e) {
+ if (DEBUG) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Validate the specified RSAKey and its associated parameters against
+ * internal signature parameters.
+ */
+ private RSAKey isValid(RSAKey rsaKey) throws InvalidKeyException {
+ try {
+ AlgorithmParameterSpec keyParams = rsaKey.getParams();
+ // validate key parameters
+ if (!isCompatible(rsaKey.getParams(), this.sigParams)) {
+ throw new InvalidKeyException
+ ("Key contains incompatible PSS parameter values");
+ }
+ // validate key length
+ if (this.sigParams != null) {
+ Integer hLen =
+ DIGEST_LENGTHS.get(this.sigParams.getDigestAlgorithm());
+ if (hLen == null) {
+ throw new ProviderException("Unsupported digest algo: " +
+ this.sigParams.getDigestAlgorithm());
+ }
+ checkKeyLength(rsaKey, hLen, this.sigParams.getSaltLength());
+ }
+ return rsaKey;
+ } catch (SignatureException e) {
+ throw new InvalidKeyException(e);
+ }
+ }
+
+ /**
+ * Validate the specified Signature PSS parameters.
+ */
+ private PSSParameterSpec validateSigParams(AlgorithmParameterSpec p)
+ throws InvalidAlgorithmParameterException {
+ if (p == null) {
+ throw new InvalidAlgorithmParameterException
+ ("Parameters cannot be null");
+ }
+ if (!(p instanceof PSSParameterSpec)) {
+ throw new InvalidAlgorithmParameterException
+ ("parameters must be type PSSParameterSpec");
+ }
+ // no need to validate again if same as current signature parameters
+ PSSParameterSpec params = (PSSParameterSpec) p;
+ if (params == this.sigParams) return params;
+
+ RSAKey key = (this.privKey == null? this.pubKey : this.privKey);
+ // check against keyParams if set
+ if (key != null) {
+ if (!isCompatible(key.getParams(), params)) {
+ throw new InvalidAlgorithmParameterException
+ ("Signature parameters does not match key parameters");
+ }
+ }
+ // now sanity check the parameter values
+ if (!(params.getMGFAlgorithm().equalsIgnoreCase("MGF1"))) {
+ throw new InvalidAlgorithmParameterException("Only supports MGF1");
+
+ }
+ if (params.getTrailerField() != PSSParameterSpec.TRAILER_FIELD_BC) {
+ throw new InvalidAlgorithmParameterException
+ ("Only supports TrailerFieldBC(1)");
+
+ }
+ String digestAlgo = params.getDigestAlgorithm();
+ // check key length again
+ if (key != null) {
+ try {
+ int hLen = DIGEST_LENGTHS.get(digestAlgo);
+ checkKeyLength(key, hLen, params.getSaltLength());
+ } catch (SignatureException e) {
+ throw new InvalidAlgorithmParameterException(e);
+ }
+ }
+ return params;
+ }
+
+ /**
+ * Ensure the object is initialized with key and parameters and
+ * reset digest
+ */
+ private void ensureInit() throws SignatureException {
+ RSAKey key = (this.privKey == null? this.pubKey : this.privKey);
+ if (key == null) {
+ throw new SignatureException("Missing key");
+ }
+ if (this.sigParams == null) {
+ // Parameters are required for signature verification
+ throw new SignatureException
+ ("Parameters required for RSASSA-PSS signatures");
+ }
+ }
+
+ /**
+ * Utility method for checking key length against digest length and
+ * salt length
+ */
+ private static void checkKeyLength(RSAKey key, int digestLen,
+ int saltLen) throws SignatureException {
+ if (key != null) {
+ int keyLength = getKeyLengthInBits(key) >> 3;
+ int minLength = Math.addExact(Math.addExact(digestLen, saltLen), 2);
+ if (keyLength < minLength) {
+ throw new SignatureException
+ ("Key is too short, need min " + minLength);
+ }
+ }
+ }
+
+ /**
+ * Reset the message digest if it is not already reset.
+ */
+ private void resetDigest() {
+ if (digestReset == false) {
+ this.md.reset();
+ digestReset = true;
+ }
+ }
+
+ /**
+ * Return the message digest value.
+ */
+ private byte[] getDigestValue() {
+ digestReset = true;
+ return this.md.digest();
+ }
+
+ // update the signature with the plaintext data. See JCA doc
+ @Override
+ protected void engineUpdate(byte b) throws SignatureException {
+ ensureInit();
+ this.md.update(b);
+ digestReset = false;
+ }
+
+ // update the signature with the plaintext data. See JCA doc
+ @Override
+ protected void engineUpdate(byte[] b, int off, int len)
+ throws SignatureException {
+ ensureInit();
+ this.md.update(b, off, len);
+ digestReset = false;
+ }
+
+ // update the signature with the plaintext data. See JCA doc
+ @Override
+ protected void engineUpdate(ByteBuffer b) {
+ try {
+ ensureInit();
+ } catch (SignatureException se) {
+ // hack for working around API bug
+ throw new RuntimeException(se.getMessage());
+ }
+ this.md.update(b);
+ digestReset = false;
+ }
+
+ // sign the data and return the signature. See JCA doc
+ @Override
+ protected byte[] engineSign() throws SignatureException {
+ ensureInit();
+ byte[] mHash = getDigestValue();
+ try {
+ byte[] encoded = encodeSignature(mHash);
+ byte[] encrypted = RSACore.rsa(encoded, privKey, true);
+ return encrypted;
+ } catch (GeneralSecurityException e) {
+ throw new SignatureException("Could not sign data", e);
+ } catch (IOException e) {
+ throw new SignatureException("Could not encode data", e);
+ }
+ }
+
+ // verify the data and return the result. See JCA doc
+ // should be reset to the state after engineInitVerify call.
+ @Override
+ protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+ ensureInit();
+ try {
+ if (sigBytes.length != RSACore.getByteLength(this.pubKey)) {
+ throw new SignatureException
+ ("Signature length not correct: got "
+ + sigBytes.length + " but was expecting "
+ + RSACore.getByteLength(this.pubKey));
+ }
+ byte[] mHash = getDigestValue();
+ byte[] decrypted = RSACore.rsa(sigBytes, this.pubKey);
+ return decodeSignature(mHash, decrypted);
+ } catch (javax.crypto.BadPaddingException e) {
+ // occurs if the app has used the wrong RSA public key
+ // or if sigBytes is invalid
+ // return false rather than propagating the exception for
+ // compatibility/ease of use
+ return false;
+ } catch (IOException e) {
+ throw new SignatureException("Signature encoding error", e);
+ } finally {
+ resetDigest();
+ }
+ }
+
+ // return the modulus length in bits
+ private static int getKeyLengthInBits(RSAKey k) {
+ if (k != null) {
+ return k.getModulus().bitLength();
+ }
+ return -1;
+ }
+
+ /**
+ * Encode the digest 'mHash', return the to-be-signed data.
+ * Also used by the PKCS#11 provider.
+ */
+ private byte[] encodeSignature(byte[] mHash)
+ throws IOException, DigestException {
+ AlgorithmParameterSpec mgfParams = this.sigParams.getMGFParameters();
+ String mgfDigestAlgo;
+ if (mgfParams != null) {
+ mgfDigestAlgo =
+ ((MGF1ParameterSpec) mgfParams).getDigestAlgorithm();
+ } else {
+ mgfDigestAlgo = this.md.getAlgorithm();
+ }
+ try {
+ int emBits = getKeyLengthInBits(this.privKey) - 1;
+ int emLen =(emBits + 7) >> 3;
+ int hLen = this.md.getDigestLength();
+ int dbLen = emLen - hLen - 1;
+ int sLen = this.sigParams.getSaltLength();
+
+ // maps DB into the corresponding region of EM and
+ // stores its bytes directly into EM
+ byte[] em = new byte[emLen];
+
+ // step7 and some of step8
+ em[dbLen - sLen - 1] = (byte) 1; // set DB's padding2 into EM
+ em[em.length - 1] = (byte) 0xBC; // set trailer field of EM
+
+ if (!digestReset) {
+ throw new ProviderException("Digest should be reset");
+ }
+ // step5: generates M' using padding1, mHash, and salt
+ this.md.update(EIGHT_BYTES_OF_ZEROS);
+ digestReset = false; // mark digest as it now has data
+ this.md.update(mHash);
+ if (sLen != 0) {
+ // step4: generate random salt
+ byte[] salt = new byte[sLen];
+ this.random.nextBytes(salt);
+ this.md.update(salt);
+
+ // step8: set DB's salt into EM
+ System.arraycopy(salt, 0, em, dbLen - sLen, sLen);
+ }
+ // step6: generate H using M'
+ this.md.digest(em, dbLen, hLen); // set H field of EM
+ digestReset = true;
+
+ // step7 and 8 are already covered by the code which setting up
+ // EM as above
+
+ // step9 and 10: feed H into MGF and xor with DB in EM
+ MGF1 mgf1 = new MGF1(mgfDigestAlgo);
+ mgf1.generateAndXor(em, dbLen, hLen, dbLen, em, 0);
+
+ // step11: set the leftmost (8emLen - emBits) bits of the leftmost
+ // octet to 0
+ int numZeroBits = (emLen << 3) - emBits;
+ if (numZeroBits != 0) {
+ byte MASK = (byte) (0xff >>> numZeroBits);
+ em[0] = (byte) (em[0] & MASK);
+ }
+
+ // step12: em should now holds maskedDB || hash h || 0xBC
+ return em;
+ } catch (NoSuchAlgorithmException e) {
+ throw new IOException(e.toString());
+ }
+ }
+
+ /**
+ * Decode the signature data. Verify that the object identifier matches
+ * and return the message digest.
+ */
+ private boolean decodeSignature(byte[] mHash, byte[] em)
+ throws IOException {
+ int hLen = mHash.length;
+ int sLen = this.sigParams.getSaltLength();
+ int emLen = em.length;
+ int emBits = getKeyLengthInBits(this.pubKey) - 1;
+
+ // step3
+ if (emLen < (hLen + sLen + 2)) {
+ return false;
+ }
+
+ // step4
+ if (em[emLen - 1] != (byte) 0xBC) {
+ return false;
+ }
+
+ // step6: check if the leftmost (8emLen - emBits) bits of the leftmost
+ // octet are 0
+ int numZeroBits = (emLen << 3) - emBits;
+ if (numZeroBits != 0) {
+ byte MASK = (byte) (0xff << (8 - numZeroBits));
+ if ((em[0] & MASK) != 0) {
+ return false;
+ }
+ }
+ String mgfDigestAlgo;
+ AlgorithmParameterSpec mgfParams = this.sigParams.getMGFParameters();
+ if (mgfParams != null) {
+ mgfDigestAlgo =
+ ((MGF1ParameterSpec) mgfParams).getDigestAlgorithm();
+ } else {
+ mgfDigestAlgo = this.md.getAlgorithm();
+ }
+ // step 7 and 8
+ int dbLen = emLen - hLen - 1;
+ try {
+ MGF1 mgf1 = new MGF1(mgfDigestAlgo);
+ mgf1.generateAndXor(em, dbLen, hLen, dbLen, em, 0);
+ } catch (NoSuchAlgorithmException nsae) {
+ throw new IOException(nsae.toString());
+ }
+
+ // step9: set the leftmost (8emLen - emBits) bits of the leftmost
+ // octet to 0
+ if (numZeroBits != 0) {
+ byte MASK = (byte) (0xff >>> numZeroBits);
+ em[0] = (byte) (em[0] & MASK);
+ }
+
+ // step10
+ int i = 0;
+ for (; i < dbLen - sLen - 1; i++) {
+ if (em[i] != 0) {
+ return false;
+ }
+ }
+ if (em[i] != 0x01) {
+ return false;
+ }
+ // step12 and 13
+ this.md.update(EIGHT_BYTES_OF_ZEROS);
+ digestReset = false;
+ this.md.update(mHash);
+ if (sLen > 0) {
+ this.md.update(em, (dbLen - sLen), sLen);
+ }
+ byte[] digest2 = this.md.digest();
+ digestReset = true;
+
+ // step14
+ byte[] digestInEM = Arrays.copyOfRange(em, dbLen, emLen - 1);
+ return MessageDigest.isEqual(digest2, digestInEM);
+ }
+
+ // set parameter, not supported. See JCA doc
+ @Deprecated
+ @Override
+ protected void engineSetParameter(String param, Object value)
+ throws InvalidParameterException {
+ throw new UnsupportedOperationException("setParameter() not supported");
+ }
+
+ @Override
+ protected void engineSetParameter(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ this.sigParams = validateSigParams(params);
+ // disallow changing parameters when digest has been used
+ if (!digestReset) {
+ throw new ProviderException
+ ("Cannot set parameters during operations");
+ }
+ String newHashAlg = this.sigParams.getDigestAlgorithm();
+ // re-allocate md if not yet assigned or algorithm changed
+ if ((this.md == null) ||
+ !(this.md.getAlgorithm().equalsIgnoreCase(newHashAlg))) {
+ try {
+ this.md = MessageDigest.getInstance(newHashAlg);
+ } catch (NoSuchAlgorithmException nsae) {
+ // should not happen as we pick default digest algorithm
+ throw new InvalidAlgorithmParameterException
+ ("Unsupported digest algorithm " +
+ newHashAlg, nsae);
+ }
+ }
+ }
+
+ // get parameter, not supported. See JCA doc
+ @Deprecated
+ @Override
+ protected Object engineGetParameter(String param)
+ throws InvalidParameterException {
+ throw new UnsupportedOperationException("getParameter() not supported");
+ }
+
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ AlgorithmParameters ap = null;
+ if (this.sigParams != null) {
+ try {
+ ap = AlgorithmParameters.getInstance("RSASSA-PSS");
+ ap.init(this.sigParams);
+ } catch (GeneralSecurityException gse) {
+ throw new ProviderException(gse.getMessage());
+ }
+ }
+ return ap;
+ }
+}
diff --git a/jdk/src/share/classes/sun/security/rsa/RSAPadding.java b/jdk/src/share/classes/sun/security/rsa/RSAPadding.java
index 5c9e658..c0e3a56 100644
--- a/jdk/src/share/classes/sun/security/rsa/RSAPadding.java
+++ b/jdk/src/share/classes/sun/security/rsa/RSAPadding.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,16 +39,13 @@
/**
* RSA padding and unpadding.
*
- * The various PKCS#1 versions can be found in the EMC/RSA Labs
- * web site, which is currently:
+ * The various PKCS#1 versions can be found in the IETF RFCs
+ * tracking the corresponding PKCS#1 standards.
*
- * http://www.emc.com/emc-plus/rsa-labs/index.htm
- *
- * or in the IETF RFCs derived from the above PKCS#1 standards.
- *
- * RFC 2313: v1.5
- * RFC 2437: v2.0
- * RFC 3447: v2.1
+ * RFC 2313: PKCS#1 v1.5
+ * RFC 2437: PKCS#1 v2.0
+ * RFC 3447: PKCS#1 v2.1
+ * RFC 8017: PKCS#1 v2.2
*
* The format of PKCS#1 v1.5 padding is:
*
@@ -105,11 +102,11 @@
// maximum size of the data
private final int maxDataSize;
- // OAEP: main messagedigest
+ // OAEP: main message digest
private MessageDigest md;
- // OAEP: message digest for MGF1
- private MessageDigest mgfMd;
+ // OAEP: MGF1
+ private MGF1 mgf;
// OAEP: value of digest of data (user-supplied or zero-length) using md
private byte[] lHash;
@@ -164,7 +161,7 @@
break;
case PAD_OAEP_MGF1:
String mdName = "SHA-1";
- String mgfMdName = "SHA-1";
+ String mgfMdName = mdName;
byte[] digestInput = null;
try {
if (spec != null) {
@@ -185,10 +182,9 @@
digestInput = ((PSource.PSpecified) pSrc).getValue();
}
md = MessageDigest.getInstance(mdName);
- mgfMd = MessageDigest.getInstance(mgfMdName);
+ mgf = new MGF1(mgfMdName);
} catch (NoSuchAlgorithmException e) {
- throw new InvalidKeyException
- ("Digest " + mdName + " not available", e);
+ throw new InvalidKeyException("Digest not available", e);
}
lHash = getInitialHash(md, digestInput);
int digestLen = lHash.length;
@@ -196,7 +192,7 @@
if (maxDataSize <= 0) {
throw new InvalidKeyException
("Key is too short for encryption using OAEPPadding" +
- " with " + mdName + " and MGF1" + mgfMdName);
+ " with " + mdName + " and " + mgf.getName());
}
break;
default:
@@ -432,10 +428,10 @@
System.arraycopy(M, 0, EM, mStart, M.length);
// produce maskedDB
- mgf1(EM, seedStart, seedLen, EM, dbStart, dbLen);
+ mgf.generateAndXor(EM, seedStart, seedLen, dbLen, EM, dbStart);
// produce maskSeed
- mgf1(EM, dbStart, dbLen, EM, seedStart, seedLen);
+ mgf.generateAndXor(EM, dbStart, dbLen, seedLen, EM, seedStart);
return EM;
}
@@ -458,8 +454,8 @@
int dbStart = hLen + 1;
int dbLen = EM.length - dbStart;
- mgf1(EM, dbStart, dbLen, EM, seedStart, seedLen);
- mgf1(EM, seedStart, seedLen, EM, dbStart, dbLen);
+ mgf.generateAndXor(EM, dbStart, dbLen, seedLen, EM, seedStart);
+ mgf.generateAndXor(EM, seedStart, seedLen, dbLen, EM, dbStart);
// verify lHash == lHash'
for (int i = 0; i < hLen; i++) {
@@ -507,37 +503,4 @@
return m;
}
}
-
- /**
- * Compute MGF1 using mgfMD as the message digest.
- * Note that we combine MGF1 with the XOR operation to reduce data
- * copying.
- *
- * We generate maskLen bytes of MGF1 from the seed and XOR it into
- * out[] starting at outOfs;
- */
- private void mgf1(byte[] seed, int seedOfs, int seedLen,
- byte[] out, int outOfs, int maskLen) throws BadPaddingException {
- byte[] C = new byte[4]; // 32 bit counter
- byte[] digest = new byte[mgfMd.getDigestLength()];
- while (maskLen > 0) {
- mgfMd.update(seed, seedOfs, seedLen);
- mgfMd.update(C);
- try {
- mgfMd.digest(digest, 0, digest.length);
- } catch (DigestException e) {
- // should never happen
- throw new BadPaddingException(e.toString());
- }
- for (int i = 0; (i < digest.length) && (maskLen > 0); maskLen--) {
- out[outOfs++] ^= digest[i++];
- }
- if (maskLen > 0) {
- // increment counter
- for (int i = C.length - 1; (++C[i] == 0) && (i > 0); i--) {
- // empty
- }
- }
- }
- }
}
diff --git a/jdk/src/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java b/jdk/src/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java
index cb5e535..6b21993 100644
--- a/jdk/src/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java
+++ b/jdk/src/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,16 +29,20 @@
import java.math.BigInteger;
import java.security.*;
+import java.security.spec.*;
import java.security.interfaces.*;
import sun.security.util.*;
+
import sun.security.x509.AlgorithmId;
import sun.security.pkcs.PKCS8Key;
+import static sun.security.rsa.RSAUtil.KeyType;
+
/**
- * Key implementation for RSA private keys, CRT form. For non-CRT private
- * keys, see RSAPrivateKeyImpl. We need separate classes to ensure
- * correct behavior in instanceof checks, etc.
+ * RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in CRT form.
+ * For non-CRT private keys, see RSAPrivateKeyImpl. We need separate classes
+ * to ensure correct behavior in instanceof checks, etc.
*
* Note: RSA keys must be at least 512 bits long
*
@@ -62,9 +66,10 @@
private BigInteger qe; // prime exponent q
private BigInteger coeff; // CRT coeffcient
- // algorithmId used to identify RSA keys
- final static AlgorithmId rsaId =
- new AlgorithmId(AlgorithmId.RSAEncryption_oid);
+ // Optional parameters associated with this RSA key
+ // specified in the encoding of its AlgorithmId.
+ // Must be null for "RSA" keys.
+ private AlgorithmParameterSpec keyParams;
/**
* Generate a new key from its encoding. Returns a CRT key if possible
@@ -73,9 +78,16 @@
public static RSAPrivateKey newKey(byte[] encoded)
throws InvalidKeyException {
RSAPrivateCrtKeyImpl key = new RSAPrivateCrtKeyImpl(encoded);
- if (key.getPublicExponent().signum() == 0) {
- // public exponent is missing, return a non-CRT key
+ // check all CRT-specific components are available, if any one
+ // missing, return a non-CRT key instead
+ if ((key.getPublicExponent().signum() == 0) ||
+ (key.getPrimeExponentP().signum() == 0) ||
+ (key.getPrimeExponentQ().signum() == 0) ||
+ (key.getPrimeP().signum() == 0) ||
+ (key.getPrimeQ().signum() == 0) ||
+ (key.getCrtCoefficient().signum() == 0)) {
return new RSAPrivateKeyImpl(
+ key.algid,
key.getModulus(),
key.getPrivateExponent()
);
@@ -85,20 +97,56 @@
}
/**
- * Construct a key from its encoding. Called from newKey above.
+ * Generate a new key from the specified type and components.
+ * Returns a CRT key if possible and a non-CRT key otherwise.
+ * Used by SunPKCS11 provider.
*/
- RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException {
- decode(encoded);
- RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
+ public static RSAPrivateKey newKey(KeyType type,
+ AlgorithmParameterSpec params,
+ BigInteger n, BigInteger e, BigInteger d,
+ BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
+ BigInteger coeff) throws InvalidKeyException {
+ RSAPrivateKey key;
+ AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params);
+ if ((e.signum() == 0) || (p.signum() == 0) ||
+ (q.signum() == 0) || (pe.signum() == 0) ||
+ (qe.signum() == 0) || (coeff.signum() == 0)) {
+ // if any component is missing, return a non-CRT key
+ return new RSAPrivateKeyImpl(rsaId, n, d);
+ } else {
+ return new RSAPrivateCrtKeyImpl(rsaId, n, e, d,
+ p, q, pe, qe, coeff);
+ }
}
/**
- * Construct a key from its components. Used by the
+ * Construct a key from its encoding. Called from newKey above.
+ */
+ RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException {
+ if (encoded == null || encoded.length == 0) {
+ throw new InvalidKeyException("Missing key encoding");
+ }
+
+ decode(encoded);
+ RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
+ try {
+ // this will check the validity of params
+ this.keyParams = RSAUtil.getParamSpec(algid);
+ } catch (ProviderException e) {
+ throw new InvalidKeyException(e);
+ }
+ }
+
+ /**
+ * Construct a RSA key from its components. Used by the
* RSAKeyFactory and the RSAKeyPairGenerator.
*/
- RSAPrivateCrtKeyImpl(BigInteger n, BigInteger e, BigInteger d,
+ RSAPrivateCrtKeyImpl(AlgorithmId rsaId,
+ BigInteger n, BigInteger e, BigInteger d,
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
BigInteger coeff) throws InvalidKeyException {
+ RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
+
this.n = n;
this.e = e;
this.d = d;
@@ -107,7 +155,7 @@
this.pe = pe;
this.qe = qe;
this.coeff = coeff;
- RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
+ this.keyParams = RSAUtil.getParamSpec(rsaId);
// generate the encoding
algid = rsaId;
@@ -132,50 +180,73 @@
}
// see JCA doc
+ @Override
public String getAlgorithm() {
- return "RSA";
+ return algid.getName();
}
// see JCA doc
+ @Override
public BigInteger getModulus() {
return n;
}
// see JCA doc
+ @Override
public BigInteger getPublicExponent() {
return e;
}
// see JCA doc
+ @Override
public BigInteger getPrivateExponent() {
return d;
}
// see JCA doc
+ @Override
public BigInteger getPrimeP() {
return p;
}
// see JCA doc
+ @Override
public BigInteger getPrimeQ() {
return q;
}
// see JCA doc
+ @Override
public BigInteger getPrimeExponentP() {
return pe;
}
// see JCA doc
+ @Override
public BigInteger getPrimeExponentQ() {
return qe;
}
// see JCA doc
+ @Override
public BigInteger getCrtCoefficient() {
return coeff;
}
+ // see JCA doc
+ @Override
+ public AlgorithmParameterSpec getParams() {
+ return keyParams;
+ }
+
+ // return a string representation of this key for debugging
+ @Override
+ public String toString() {
+ return "SunRsaSign " + getAlgorithm() + " private CRT key, " + n.bitLength()
+ + " bits" + "\n params: " + keyParams + "\n modulus: " + n
+ + "\n private exponent: " + d;
+ }
+
/**
* Parse the key. Called by PKCS8Key.
*/
diff --git a/jdk/src/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java b/jdk/src/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java
index 1a7df13..df5abc1 100644
--- a/jdk/src/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java
+++ b/jdk/src/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,15 +29,18 @@
import java.math.BigInteger;
import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
import java.security.interfaces.*;
import sun.security.util.*;
+import sun.security.x509.AlgorithmId;
import sun.security.pkcs.PKCS8Key;
/**
- * Key implementation for RSA private keys, non-CRT form (modulus, private
- * exponent only). For CRT private keys, see RSAPrivateCrtKeyImpl. We need
- * separate classes to ensure correct behavior in instanceof checks, etc.
+ * RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in non-CRT
+ * form (modulus, private exponent only). For CRT private keys, see
+ * RSAPrivateCrtKeyImpl. We need separate classes to ensure correct behavior
+ * in instanceof checks, etc.
*
* Note: RSA keys must be at least 512 bits long
*
@@ -54,16 +57,25 @@
private final BigInteger n; // modulus
private final BigInteger d; // private exponent
+ // optional parameters associated with this RSA key
+ // specified in the encoding of its AlgorithmId.
+ // must be null for "RSA" keys.
+ private final AlgorithmParameterSpec keyParams;
+
/**
* Construct a key from its components. Used by the
* RSAKeyFactory and the RSAKeyPairGenerator.
*/
- RSAPrivateKeyImpl(BigInteger n, BigInteger d) throws InvalidKeyException {
+ RSAPrivateKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger d)
+ throws InvalidKeyException {
+ RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null);
+
this.n = n;
this.d = d;
- RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null);
+ this.keyParams = RSAUtil.getParamSpec(rsaId);
+
// generate the encoding
- algid = RSAPrivateCrtKeyImpl.rsaId;
+ algid = rsaId;
try {
DerOutputStream out = new DerOutputStream();
out.putInteger(0); // version must be 0
@@ -85,17 +97,34 @@
}
// see JCA doc
+ @Override
public String getAlgorithm() {
- return "RSA";
+ return algid.getName();
}
// see JCA doc
+ @Override
public BigInteger getModulus() {
return n;
}
// see JCA doc
+ @Override
public BigInteger getPrivateExponent() {
return d;
}
+
+ // see JCA doc
+ @Override
+ public AlgorithmParameterSpec getParams() {
+ return keyParams;
+ }
+
+ // return a string representation of this key for debugging
+ @Override
+ public String toString() {
+ return "Sun " + getAlgorithm() + " private key, " + n.bitLength()
+ + " bits" + "\n params: " + keyParams + "\n modulus: " + n
+ + "\n private exponent: " + d;
+ }
}
diff --git a/jdk/src/share/classes/sun/security/rsa/RSAPublicKeyImpl.java b/jdk/src/share/classes/sun/security/rsa/RSAPublicKeyImpl.java
index b273917..ebd035e 100644
--- a/jdk/src/share/classes/sun/security/rsa/RSAPublicKeyImpl.java
+++ b/jdk/src/share/classes/sun/security/rsa/RSAPublicKeyImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,17 +29,22 @@
import java.math.BigInteger;
import java.security.*;
+import java.security.spec.*;
import java.security.interfaces.*;
import sun.security.util.*;
import sun.security.x509.X509Key;
+import sun.security.x509.AlgorithmId;
+
+import static sun.security.rsa.RSAUtil.KeyType;
/**
- * Key implementation for RSA public keys.
+ * RSA public key implementation for "RSA", "RSASSA-PSS" algorithms.
*
* Note: RSA keys must be at least 512 bits long
*
* @see RSAPrivateCrtKeyImpl
+ * @see RSAPrivateKeyImpl
* @see RSAKeyFactory
*
* @since 1.5
@@ -53,18 +58,46 @@
private BigInteger n; // modulus
private BigInteger e; // public exponent
+ // optional parameters associated with this RSA key
+ // specified in the encoding of its AlgorithmId
+ // must be null for "RSA" keys.
+ private AlgorithmParameterSpec keyParams;
+
/**
- * Construct a key from its components. Used by the
- * RSAKeyFactory and the RSAKeyPairGenerator.
+ * Generate a new RSAPublicKey from the specified encoding.
+ * Used by SunPKCS11 provider.
*/
- public RSAPublicKeyImpl(BigInteger n, BigInteger e)
+ public static RSAPublicKey newKey(byte[] encoded)
throws InvalidKeyException {
+ return new RSAPublicKeyImpl(encoded);
+ }
+
+ /**
+ * Generate a new RSAPublicKey from the specified type and components.
+ * Used by SunPKCS11 provider.
+ */
+ public static RSAPublicKey newKey(KeyType type,
+ AlgorithmParameterSpec params, BigInteger n, BigInteger e)
+ throws InvalidKeyException {
+ AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params);
+ return new RSAPublicKeyImpl(rsaId, n, e);
+ }
+
+ /**
+ * Construct a RSA key from AlgorithmId and its components. Used by
+ * RSAKeyFactory and RSAKeyPairGenerator.
+ */
+ RSAPublicKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger e)
+ throws InvalidKeyException {
+ RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
+ checkExponentRange(n, e);
+
this.n = n;
this.e = e;
- RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
- checkExponentRange();
+ this.keyParams = RSAUtil.getParamSpec(rsaId);
+
// generate the encoding
- algid = RSAPrivateCrtKeyImpl.rsaId;
+ algid = rsaId;
try {
DerOutputStream out = new DerOutputStream();
out.putInteger(n);
@@ -82,39 +115,60 @@
/**
* Construct a key from its encoding. Used by RSAKeyFactory.
*/
- public RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException {
- decode(encoded);
+ RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException {
+ if (encoded == null || encoded.length == 0) {
+ throw new InvalidKeyException("Missing key encoding");
+ }
+ decode(encoded); // this sets n and e value
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
- checkExponentRange();
+ checkExponentRange(n, e);
+
+ try {
+ // this will check the validity of params
+ this.keyParams = RSAUtil.getParamSpec(algid);
+ } catch (ProviderException e) {
+ throw new InvalidKeyException(e);
+ }
}
- private void checkExponentRange() throws InvalidKeyException {
+ // pkg private utility method for checking RSA modulus and public exponent
+ static void checkExponentRange(BigInteger mod, BigInteger exp)
+ throws InvalidKeyException {
// the exponent should be smaller than the modulus
- if (e.compareTo(n) >= 0) {
+ if (exp.compareTo(mod) >= 0) {
throw new InvalidKeyException("exponent is larger than modulus");
}
// the exponent should be at least 3
- if (e.compareTo(THREE) < 0) {
+ if (exp.compareTo(THREE) < 0) {
throw new InvalidKeyException("exponent is smaller than 3");
}
}
// see JCA doc
+ @Override
public String getAlgorithm() {
- return "RSA";
+ return algid.getName();
}
// see JCA doc
+ @Override
public BigInteger getModulus() {
return n;
}
// see JCA doc
+ @Override
public BigInteger getPublicExponent() {
return e;
}
+ // see JCA doc
+ @Override
+ public AlgorithmParameterSpec getParams() {
+ return keyParams;
+ }
+
/**
* Parse the key. Called by X509Key.
*/
@@ -137,9 +191,11 @@
}
// return a string representation of this key for debugging
+ @Override
public String toString() {
- return "Sun RSA public key, " + n.bitLength() + " bits\n modulus: "
- + n + "\n public exponent: " + e;
+ return "Sun " + getAlgorithm() + " public key, " + n.bitLength()
+ + " bits" + "\n params: " + keyParams + "\n modulus: " + n
+ + "\n public exponent: " + e;
}
protected Object writeReplace() throws java.io.ObjectStreamException {
diff --git a/jdk/src/share/classes/sun/security/rsa/RSASignature.java b/jdk/src/share/classes/sun/security/rsa/RSASignature.java
index 379d401..0e719e8 100644
--- a/jdk/src/share/classes/sun/security/rsa/RSASignature.java
+++ b/jdk/src/share/classes/sun/security/rsa/RSASignature.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,16 +30,18 @@
import java.security.*;
import java.security.interfaces.*;
+import java.security.spec.AlgorithmParameterSpec;
+import sun.security.rsa.RSAUtil.KeyType;
import sun.security.util.*;
import sun.security.x509.AlgorithmId;
/**
- * PKCS#1 RSA signatures with the various message digest algorithms.
+ * PKCS#1 v1.5 RSA signatures with the various message digest algorithms.
* This file contains an abstract base class with all the logic plus
* a nested static class for each of the message digest algorithms
* (see end of the file). We support MD2, MD5, SHA-1, SHA-224, SHA-256,
- * SHA-384, and SHA-512.
+ * SHA-384, SHA-512, SHA-512/224, and SHA-512/256.
*
* @since 1.5
* @author Andreas Sterbenz
@@ -85,6 +87,7 @@
}
// initialize for verification. See JCA doc
+ @Override
protected void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException {
RSAPublicKey rsaKey = (RSAPublicKey)RSAKeyFactory.toRSAKey(publicKey);
@@ -94,12 +97,14 @@
}
// initialize for signing. See JCA doc
+ @Override
protected void engineInitSign(PrivateKey privateKey)
throws InvalidKeyException {
engineInitSign(privateKey, null);
}
// initialize for signing. See JCA doc
+ @Override
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException {
RSAPrivateKey rsaKey =
@@ -114,6 +119,11 @@
*/
private void initCommon(RSAKey rsaKey, SecureRandom random)
throws InvalidKeyException {
+ try {
+ RSAUtil.checkParamsAgainstType(KeyType.RSA, rsaKey.getParams());
+ } catch (ProviderException e) {
+ throw new InvalidKeyException("Invalid key for RSA signatures", e);
+ }
resetDigest();
int keySize = RSACore.getByteLength(rsaKey);
try {
@@ -148,12 +158,14 @@
}
// update the signature with the plaintext data. See JCA doc
+ @Override
protected void engineUpdate(byte b) throws SignatureException {
md.update(b);
digestReset = false;
}
// update the signature with the plaintext data. See JCA doc
+ @Override
protected void engineUpdate(byte[] b, int off, int len)
throws SignatureException {
md.update(b, off, len);
@@ -161,13 +173,18 @@
}
// update the signature with the plaintext data. See JCA doc
+ @Override
protected void engineUpdate(ByteBuffer b) {
md.update(b);
digestReset = false;
}
// sign the data and return the signature. See JCA doc
+ @Override
protected byte[] engineSign() throws SignatureException {
+ if (privateKey == null) {
+ throw new SignatureException("Missing private key");
+ }
byte[] digest = getDigestValue();
try {
byte[] encoded = encodeSignature(digestOID, digest);
@@ -182,7 +199,12 @@
}
// verify the data and return the result. See JCA doc
+ @Override
protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+ if (publicKey == null) {
+ throw new SignatureException("Missing public key");
+ }
+
if (sigBytes.length != RSACore.getByteLength(publicKey)) {
throw new SignatureException("Signature length not correct: got " +
sigBytes.length + " but was expecting " +
@@ -245,18 +267,35 @@
// set parameter, not supported. See JCA doc
@Deprecated
+ @Override
protected void engineSetParameter(String param, Object value)
throws InvalidParameterException {
throw new UnsupportedOperationException("setParameter() not supported");
}
+ // See JCA doc
+ @Override
+ protected void engineSetParameter(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ if (params != null) {
+ throw new InvalidAlgorithmParameterException("No parameters accepted");
+ }
+ }
+
// get parameter, not supported. See JCA doc
@Deprecated
+ @Override
protected Object engineGetParameter(String param)
throws InvalidParameterException {
throw new UnsupportedOperationException("getParameter() not supported");
}
+ // See JCA doc
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ return null;
+ }
+
// Nested class for MD2withRSA signatures
public static final class MD2withRSA extends RSASignature {
public MD2withRSA() {
@@ -306,4 +345,17 @@
}
}
+ // Nested class for SHA512/224withRSA signatures
+ public static final class SHA512_224withRSA extends RSASignature {
+ public SHA512_224withRSA() {
+ super("SHA-512/224", AlgorithmId.SHA512_224_oid, 11);
+ }
+ }
+
+ // Nested class for SHA512/256withRSA signatures
+ public static final class SHA512_256withRSA extends RSASignature {
+ public SHA512_256withRSA() {
+ super("SHA-512/256", AlgorithmId.SHA512_256_oid, 11);
+ }
+ }
}
diff --git a/jdk/src/share/classes/sun/security/rsa/RSAUtil.java b/jdk/src/share/classes/sun/security/rsa/RSAUtil.java
new file mode 100644
index 0000000..0889c03
--- /dev/null
+++ b/jdk/src/share/classes/sun/security/rsa/RSAUtil.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.rsa;
+
+import java.io.IOException;
+import java.security.*;
+import java.security.spec.*;
+import sun.security.util.ObjectIdentifier;
+import sun.security.x509.AlgorithmId;
+
+/**
+ * Utility class for SunRsaSign provider.
+ * Currently used by RSAKeyPairGenerator and RSAKeyFactory.
+ *
+ * @since 8
+ */
+public class RSAUtil {
+
+ public enum KeyType {
+ RSA ("RSA"),
+ PSS ("RSASSA-PSS")
+ ;
+
+ private final String algo;
+
+ KeyType(String keyAlgo) {
+ this.algo = keyAlgo;
+ }
+ public String keyAlgo() {
+ return algo;
+ }
+ public static KeyType lookup(String name)
+ throws InvalidKeyException, ProviderException {
+ if (name == null) {
+ throw new InvalidKeyException("Null key algorithm");
+ }
+ for (KeyType kt : KeyType.values()) {
+ if (kt.keyAlgo().equalsIgnoreCase(name)) {
+ return kt;
+ }
+ }
+ // no match
+ throw new ProviderException("Unsupported algorithm " + name);
+ }
+ }
+
+ public static void checkParamsAgainstType(KeyType type,
+ AlgorithmParameterSpec paramSpec) throws ProviderException {
+ switch (type) {
+ case RSA:
+ if (paramSpec != null) {
+ throw new ProviderException("null params expected for " +
+ type.keyAlgo());
+ }
+ break;
+ case PSS:
+ if ((paramSpec != null) &&
+ !(paramSpec instanceof PSSParameterSpec)) {
+ throw new ProviderException
+ ("PSSParmeterSpec expected for " + type.keyAlgo());
+ }
+ break;
+ default:
+ throw new ProviderException
+ ("Unsupported RSA algorithm " + type);
+ }
+ }
+
+ public static AlgorithmId createAlgorithmId(KeyType type,
+ AlgorithmParameterSpec paramSpec) throws ProviderException {
+
+ checkParamsAgainstType(type, paramSpec);
+
+ ObjectIdentifier oid = null;
+ AlgorithmParameters params = null;
+ try {
+ switch (type) {
+ case RSA:
+ oid = AlgorithmId.RSAEncryption_oid;
+ break;
+ case PSS:
+ if (paramSpec != null) {
+ params = AlgorithmParameters.getInstance(type.keyAlgo());
+ params.init(paramSpec);
+ }
+ oid = AlgorithmId.RSASSA_PSS_oid;
+ break;
+ default:
+ throw new ProviderException
+ ("Unsupported RSA algorithm " + type);
+ }
+ AlgorithmId result;
+ if (params == null) {
+ result = new AlgorithmId(oid);
+ } else {
+ result = new AlgorithmId(oid, params);
+ }
+ return result;
+ } catch (NoSuchAlgorithmException | InvalidParameterSpecException e) {
+ // should not happen
+ throw new ProviderException(e);
+ }
+ }
+
+ public static AlgorithmParameterSpec getParamSpec(AlgorithmId algid)
+ throws ProviderException {
+ if (algid == null) {
+ throw new ProviderException("AlgorithmId should not be null");
+ }
+ return getParamSpec(algid.getParameters());
+ }
+
+ public static AlgorithmParameterSpec getParamSpec(AlgorithmParameters params)
+ throws ProviderException {
+ if (params == null) return null;
+
+ try {
+ String algName = params.getAlgorithm();
+ KeyType type = KeyType.lookup(algName);
+ Class<? extends AlgorithmParameterSpec> specCls;
+ switch (type) {
+ case RSA:
+ throw new ProviderException("No params accepted for " +
+ type.keyAlgo());
+ case PSS:
+ specCls = PSSParameterSpec.class;
+ break;
+ default:
+ throw new ProviderException("Unsupported RSA algorithm: " + algName);
+ }
+ return params.getParameterSpec(specCls);
+ } catch (ProviderException pe) {
+ // pass it up
+ throw pe;
+ } catch (Exception e) {
+ throw new ProviderException(e);
+ }
+ }
+}
diff --git a/jdk/src/share/classes/sun/security/rsa/SunRsaSignEntries.java b/jdk/src/share/classes/sun/security/rsa/SunRsaSignEntries.java
index 836fc5f..6af5fdf 100644
--- a/jdk/src/share/classes/sun/security/rsa/SunRsaSignEntries.java
+++ b/jdk/src/share/classes/sun/security/rsa/SunRsaSignEntries.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,11 +41,10 @@
public static void putEntries(Map<Object, Object> map) {
// main algorithms
-
map.put("KeyFactory.RSA",
- "sun.security.rsa.RSAKeyFactory");
+ "sun.security.rsa.RSAKeyFactory$Legacy");
map.put("KeyPairGenerator.RSA",
- "sun.security.rsa.RSAKeyPairGenerator");
+ "sun.security.rsa.RSAKeyPairGenerator$Legacy");
map.put("Signature.MD2withRSA",
"sun.security.rsa.RSASignature$MD2withRSA");
map.put("Signature.MD5withRSA",
@@ -60,9 +59,21 @@
"sun.security.rsa.RSASignature$SHA384withRSA");
map.put("Signature.SHA512withRSA",
"sun.security.rsa.RSASignature$SHA512withRSA");
+ map.put("Signature.SHA512/224withRSA",
+ "sun.security.rsa.RSASignature$SHA512_224withRSA");
+ map.put("Signature.SHA512/256withRSA",
+ "sun.security.rsa.RSASignature$SHA512_256withRSA");
+
+ map.put("KeyFactory.RSASSA-PSS",
+ "sun.security.rsa.RSAKeyFactory$PSS");
+ map.put("KeyPairGenerator.RSASSA-PSS",
+ "sun.security.rsa.RSAKeyPairGenerator$PSS");
+ map.put("Signature.RSASSA-PSS",
+ "sun.security.rsa.RSAPSSSignature");
+ map.put("AlgorithmParameters.RSASSA-PSS",
+ "sun.security.rsa.PSSParameters");
// attributes for supported key classes
-
String rsaKeyClasses = "java.security.interfaces.RSAPublicKey" +
"|java.security.interfaces.RSAPrivateKey";
map.put("Signature.MD2withRSA SupportedKeyClasses", rsaKeyClasses);
@@ -72,9 +83,11 @@
map.put("Signature.SHA256withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA384withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA512withRSA SupportedKeyClasses", rsaKeyClasses);
+ map.put("Signature.SHA512/224withRSA SupportedKeyClasses", rsaKeyClasses);
+ map.put("Signature.SHA512/256withRSA SupportedKeyClasses", rsaKeyClasses);
+ map.put("Signature.RSASSA-PSS SupportedKeyClasses", rsaKeyClasses);
// aliases
-
map.put("Alg.Alias.KeyFactory.1.2.840.113549.1.1", "RSA");
map.put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1", "RSA");
@@ -102,6 +115,21 @@
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.13", "SHA512withRSA");
+ map.put("Alg.Alias.Signature.1.2.840.113549.1.1.15", "SHA512/224withRSA");
+ map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.15", "SHA512/224withRSA");
+ map.put("Alg.Alias.Signature.1.2.840.113549.1.1.16", "SHA512/256withRSA");
+ map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.16", "SHA512/256withRSA");
+ map.put("Alg.Alias.KeyFactory.1.2.840.113549.1.1.10", "RSASSA-PSS");
+ map.put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
+
+ map.put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1.10", "RSASSA-PSS");
+ map.put("Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
+
+ map.put("Alg.Alias.Signature.1.2.840.113549.1.1.10", "RSASSA-PSS");
+ map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
+
+ map.put("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.1.10", "RSASSA-PSS");
+ map.put("Alg.Alias.AlgorithmParameters.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
}
}
diff --git a/jdk/src/share/classes/sun/security/ssl/ALPNExtension.java b/jdk/src/share/classes/sun/security/ssl/ALPNExtension.java
new file mode 100644
index 0000000..f97f290
--- /dev/null
+++ b/jdk/src/share/classes/sun/security/ssl/ALPNExtension.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.ssl;
+
+import java.io.IOException;
+import java.nio.charset.*;
+import java.util.*;
+
+import javax.net.ssl.*;
+
+/*
+ * [RFC 7301]
+ * This TLS extension facilitates the negotiation of application-layer protocols
+ * within the TLS handshake. Clients MAY include an extension of type
+ * "application_layer_protocol_negotiation" in the (extended) ClientHello
+ * message. The "extension_data" field of this extension SHALL contain a
+ * "ProtocolNameList" value:
+ *
+ * enum {
+ * application_layer_protocol_negotiation(16), (65535)
+ * } ExtensionType;
+ *
+ * opaque ProtocolName<1..2^8-1>;
+ *
+ * struct {
+ * ProtocolName protocol_name_list<2..2^16-1>
+ * } ProtocolNameList;
+ */
+final class ALPNExtension extends HelloExtension {
+
+ final static int ALPN_HEADER_LENGTH = 1;
+ final static int MAX_APPLICATION_PROTOCOL_LENGTH = 255;
+ final static int MAX_APPLICATION_PROTOCOL_LIST_LENGTH = 65535;
+ private int listLength = 0; // ProtocolNameList length
+ private List<String> protocolNames = null;
+
+ // constructor for ServerHello
+ ALPNExtension(String protocolName) throws SSLException {
+ this(new String[]{ protocolName });
+ }
+
+ // constructor for ClientHello
+ ALPNExtension(String[] protocolNames) throws SSLException {
+ super(ExtensionType.EXT_ALPN);
+ if (protocolNames.length == 0) { // never null, never empty
+ throw new IllegalArgumentException(
+ "The list of application protocols cannot be empty");
+ }
+ this.protocolNames = Arrays.asList(protocolNames);
+ for (String p : protocolNames) {
+ int length = p.getBytes(StandardCharsets.UTF_8).length;
+ if (length == 0) {
+ throw new SSLProtocolException(
+ "Application protocol name is empty");
+ }
+ if (length <= MAX_APPLICATION_PROTOCOL_LENGTH) {
+ listLength += length + ALPN_HEADER_LENGTH;
+ } else {
+ throw new SSLProtocolException(
+ "Application protocol name is too long: " + p);
+ }
+ if (listLength > MAX_APPLICATION_PROTOCOL_LIST_LENGTH) {
+ throw new SSLProtocolException(
+ "Application protocol name list is too long");
+ }
+ }
+ }
+
+ // constructor for ServerHello for parsing ALPN extension
+ ALPNExtension(HandshakeInStream s, int len) throws IOException {
+ super(ExtensionType.EXT_ALPN);
+
+ if (len >= 2) {
+ listLength = s.getInt16(); // list length
+ if (listLength < 2 || listLength + 2 != len) {
+ throw new SSLProtocolException(
+ "Invalid " + type + " extension: incorrect list length " +
+ "(length=" + listLength + ")");
+ }
+ } else {
+ throw new SSLProtocolException(
+ "Invalid " + type + " extension: insufficient data " +
+ "(length=" + len + ")");
+ }
+
+ int remaining = listLength;
+ this.protocolNames = new ArrayList<>();
+ while (remaining > 0) {
+ // opaque ProtocolName<1..2^8-1>; // RFC 7301
+ byte[] bytes = s.getBytes8();
+ if (bytes.length == 0) {
+ throw new SSLProtocolException("Invalid " + type +
+ " extension: empty application protocol name");
+ }
+ String p =
+ new String(bytes, StandardCharsets.UTF_8); // app protocol
+ protocolNames.add(p);
+ remaining -= bytes.length + ALPN_HEADER_LENGTH;
+ }
+
+ if (remaining != 0) {
+ throw new SSLProtocolException(
+ "Invalid " + type + " extension: extra data " +
+ "(length=" + remaining + ")");
+ }
+ }
+
+ List<String> getPeerAPs() {
+ return protocolNames;
+ }
+
+ /*
+ * Return the length in bytes, including extension type and length fields.
+ */
+ @Override
+ int length() {
+ return 6 + listLength;
+ }
+
+ @Override
+ void send(HandshakeOutStream s) throws IOException {
+ s.putInt16(type.id);
+ s.putInt16(listLength + 2); // length of extension_data
+ s.putInt16(listLength); // length of ProtocolNameList
+
+ for (String p : protocolNames) {
+ s.putBytes8(p.getBytes(StandardCharsets.UTF_8));
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ if (protocolNames == null || protocolNames.isEmpty()) {
+ sb.append("<empty>");
+ } else {
+ for (String protocolName : protocolNames) {
+ sb.append("[" + protocolName + "]");
+ }
+ }
+
+ return "Extension " + type +
+ ", protocol names: " + sb;
+ }
+}
diff --git a/jdk/src/share/classes/sun/security/ssl/Alerts.java b/jdk/src/share/classes/sun/security/ssl/Alerts.java
index 672d9b7..bdfe577 100644
--- a/jdk/src/share/classes/sun/security/ssl/Alerts.java
+++ b/jdk/src/share/classes/sun/security/ssl/Alerts.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -83,6 +83,9 @@
static final byte alert_bad_certificate_status_response = 113;
static final byte alert_bad_certificate_hash_value = 114;
+ // from RFC 7301 (TLS ALPN Extension)
+ static final byte alert_no_application_protocol = 120;
+
static String alertDescription(byte code) {
switch (code) {
@@ -144,6 +147,8 @@
return "bad_certificate_status_response";
case alert_bad_certificate_hash_value:
return "bad_certificate_hash_value";
+ case alert_no_application_protocol:
+ return "no_application_protocol";
default:
return "<UNKNOWN ALERT: " + (code & 0x0ff) + ">";
@@ -189,6 +194,7 @@
case alert_unrecognized_name:
case alert_bad_certificate_status_response:
case alert_bad_certificate_hash_value:
+ case alert_no_application_protocol:
e = new SSLHandshakeException(reason);
break;
diff --git a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java
index 687eaee..5396c2a 100644
--- a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java
+++ b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -683,7 +683,7 @@
final boolean N = (SunJSSE.isFIPS() == false);
/*
- * TLS Cipher Suite Registry, as of August 2010.
+ * TLS Cipher Suite Registry, as of November 2015.
*
* http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
*
@@ -692,77 +692,77 @@
* 192-254 Specification Required Refers to value of first byte
* 255 Reserved for Private Use Refers to value of first byte
*
- * Value Description Reference
- * 0x00,0x00 TLS_NULL_WITH_NULL_NULL [RFC5246]
- * 0x00,0x01 TLS_RSA_WITH_NULL_MD5 [RFC5246]
- * 0x00,0x02 TLS_RSA_WITH_NULL_SHA [RFC5246]
- * 0x00,0x03 TLS_RSA_EXPORT_WITH_RC4_40_MD5 [RFC4346]
- * 0x00,0x04 TLS_RSA_WITH_RC4_128_MD5 [RFC5246]
- * 0x00,0x05 TLS_RSA_WITH_RC4_128_SHA [RFC5246]
- * 0x00,0x06 TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 [RFC4346]
- * 0x00,0x07 TLS_RSA_WITH_IDEA_CBC_SHA [RFC5469]
- * 0x00,0x08 TLS_RSA_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
- * 0x00,0x09 TLS_RSA_WITH_DES_CBC_SHA [RFC5469]
- * 0x00,0x0A TLS_RSA_WITH_3DES_EDE_CBC_SHA [RFC5246]
- * 0x00,0x0B TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
- * 0x00,0x0C TLS_DH_DSS_WITH_DES_CBC_SHA [RFC5469]
- * 0x00,0x0D TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA [RFC5246]
- * 0x00,0x0E TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
- * 0x00,0x0F TLS_DH_RSA_WITH_DES_CBC_SHA [RFC5469]
- * 0x00,0x10 TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA [RFC5246]
- * 0x00,0x11 TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
- * 0x00,0x12 TLS_DHE_DSS_WITH_DES_CBC_SHA [RFC5469]
- * 0x00,0x13 TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA [RFC5246]
- * 0x00,0x14 TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
- * 0x00,0x15 TLS_DHE_RSA_WITH_DES_CBC_SHA [RFC5469]
- * 0x00,0x16 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA [RFC5246]
- * 0x00,0x17 TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 [RFC4346]
- * 0x00,0x18 TLS_DH_anon_WITH_RC4_128_MD5 [RFC5246]
- * 0x00,0x19 TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
- * 0x00,0x1A TLS_DH_anon_WITH_DES_CBC_SHA [RFC5469]
- * 0x00,0x1B TLS_DH_anon_WITH_3DES_EDE_CBC_SHA [RFC5246]
- * 0x00,0x1C-1D Reserved to avoid conflicts with SSLv3 [RFC5246]
- * 0x00,0x1E TLS_KRB5_WITH_DES_CBC_SHA [RFC2712]
- * 0x00,0x1F TLS_KRB5_WITH_3DES_EDE_CBC_SHA [RFC2712]
- * 0x00,0x20 TLS_KRB5_WITH_RC4_128_SHA [RFC2712]
- * 0x00,0x21 TLS_KRB5_WITH_IDEA_CBC_SHA [RFC2712]
- * 0x00,0x22 TLS_KRB5_WITH_DES_CBC_MD5 [RFC2712]
- * 0x00,0x23 TLS_KRB5_WITH_3DES_EDE_CBC_MD5 [RFC2712]
- * 0x00,0x24 TLS_KRB5_WITH_RC4_128_MD5 [RFC2712]
- * 0x00,0x25 TLS_KRB5_WITH_IDEA_CBC_MD5 [RFC2712]
- * 0x00,0x26 TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA [RFC2712]
- * 0x00,0x27 TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA [RFC2712]
- * 0x00,0x28 TLS_KRB5_EXPORT_WITH_RC4_40_SHA [RFC2712]
- * 0x00,0x29 TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 [RFC2712]
- * 0x00,0x2A TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 [RFC2712]
- * 0x00,0x2B TLS_KRB5_EXPORT_WITH_RC4_40_MD5 [RFC2712]
- * 0x00,0x2C TLS_PSK_WITH_NULL_SHA [RFC4785]
- * 0x00,0x2D TLS_DHE_PSK_WITH_NULL_SHA [RFC4785]
- * 0x00,0x2E TLS_RSA_PSK_WITH_NULL_SHA [RFC4785]
- * 0x00,0x2F TLS_RSA_WITH_AES_128_CBC_SHA [RFC5246]
- * 0x00,0x30 TLS_DH_DSS_WITH_AES_128_CBC_SHA [RFC5246]
- * 0x00,0x31 TLS_DH_RSA_WITH_AES_128_CBC_SHA [RFC5246]
- * 0x00,0x32 TLS_DHE_DSS_WITH_AES_128_CBC_SHA [RFC5246]
- * 0x00,0x33 TLS_DHE_RSA_WITH_AES_128_CBC_SHA [RFC5246]
- * 0x00,0x34 TLS_DH_anon_WITH_AES_128_CBC_SHA [RFC5246]
- * 0x00,0x35 TLS_RSA_WITH_AES_256_CBC_SHA [RFC5246]
- * 0x00,0x36 TLS_DH_DSS_WITH_AES_256_CBC_SHA [RFC5246]
- * 0x00,0x37 TLS_DH_RSA_WITH_AES_256_CBC_SHA [RFC5246]
- * 0x00,0x38 TLS_DHE_DSS_WITH_AES_256_CBC_SHA [RFC5246]
- * 0x00,0x39 TLS_DHE_RSA_WITH_AES_256_CBC_SHA [RFC5246]
- * 0x00,0x3A TLS_DH_anon_WITH_AES_256_CBC_SHA [RFC5246]
- * 0x00,0x3B TLS_RSA_WITH_NULL_SHA256 [RFC5246]
- * 0x00,0x3C TLS_RSA_WITH_AES_128_CBC_SHA256 [RFC5246]
- * 0x00,0x3D TLS_RSA_WITH_AES_256_CBC_SHA256 [RFC5246]
- * 0x00,0x3E TLS_DH_DSS_WITH_AES_128_CBC_SHA256 [RFC5246]
- * 0x00,0x3F TLS_DH_RSA_WITH_AES_128_CBC_SHA256 [RFC5246]
- * 0x00,0x40 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 [RFC5246]
- * 0x00,0x41 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
- * 0x00,0x42 TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
- * 0x00,0x43 TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
- * 0x00,0x44 TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
- * 0x00,0x45 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
- * 0x00,0x46 TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * Value Description Reference
+ * 0x00,0x00 TLS_NULL_WITH_NULL_NULL [RFC5246]
+ * 0x00,0x01 TLS_RSA_WITH_NULL_MD5 [RFC5246]
+ * 0x00,0x02 TLS_RSA_WITH_NULL_SHA [RFC5246]
+ * 0x00,0x03 TLS_RSA_EXPORT_WITH_RC4_40_MD5 [RFC4346]
+ * 0x00,0x04 TLS_RSA_WITH_RC4_128_MD5 [RFC5246]
+ * 0x00,0x05 TLS_RSA_WITH_RC4_128_SHA [RFC5246]
+ * 0x00,0x06 TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 [RFC4346]
+ * 0x00,0x07 TLS_RSA_WITH_IDEA_CBC_SHA [RFC5469]
+ * 0x00,0x08 TLS_RSA_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x09 TLS_RSA_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x0A TLS_RSA_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x0B TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x0C TLS_DH_DSS_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x0D TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x0E TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x0F TLS_DH_RSA_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x10 TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x11 TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x12 TLS_DHE_DSS_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x13 TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x14 TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x15 TLS_DHE_RSA_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x16 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x17 TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 [RFC4346]
+ * 0x00,0x18 TLS_DH_anon_WITH_RC4_128_MD5 [RFC5246]
+ * 0x00,0x19 TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x1A TLS_DH_anon_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x1B TLS_DH_anon_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x1C-1D Reserved to avoid conflicts with SSLv3 [RFC5246]
+ * 0x00,0x1E TLS_KRB5_WITH_DES_CBC_SHA [RFC2712]
+ * 0x00,0x1F TLS_KRB5_WITH_3DES_EDE_CBC_SHA [RFC2712]
+ * 0x00,0x20 TLS_KRB5_WITH_RC4_128_SHA [RFC2712]
+ * 0x00,0x21 TLS_KRB5_WITH_IDEA_CBC_SHA [RFC2712]
+ * 0x00,0x22 TLS_KRB5_WITH_DES_CBC_MD5 [RFC2712]
+ * 0x00,0x23 TLS_KRB5_WITH_3DES_EDE_CBC_MD5 [RFC2712]
+ * 0x00,0x24 TLS_KRB5_WITH_RC4_128_MD5 [RFC2712]
+ * 0x00,0x25 TLS_KRB5_WITH_IDEA_CBC_MD5 [RFC2712]
+ * 0x00,0x26 TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA [RFC2712]
+ * 0x00,0x27 TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA [RFC2712]
+ * 0x00,0x28 TLS_KRB5_EXPORT_WITH_RC4_40_SHA [RFC2712]
+ * 0x00,0x29 TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 [RFC2712]
+ * 0x00,0x2A TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 [RFC2712]
+ * 0x00,0x2B TLS_KRB5_EXPORT_WITH_RC4_40_MD5 [RFC2712]
+ * 0x00,0x2C TLS_PSK_WITH_NULL_SHA [RFC4785]
+ * 0x00,0x2D TLS_DHE_PSK_WITH_NULL_SHA [RFC4785]
+ * 0x00,0x2E TLS_RSA_PSK_WITH_NULL_SHA [RFC4785]
+ * 0x00,0x2F TLS_RSA_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x30 TLS_DH_DSS_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x31 TLS_DH_RSA_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x32 TLS_DHE_DSS_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x33 TLS_DHE_RSA_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x34 TLS_DH_anon_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x35 TLS_RSA_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x36 TLS_DH_DSS_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x37 TLS_DH_RSA_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x38 TLS_DHE_DSS_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x39 TLS_DHE_RSA_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x3A TLS_DH_anon_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x3B TLS_RSA_WITH_NULL_SHA256 [RFC5246]
+ * 0x00,0x3C TLS_RSA_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x3D TLS_RSA_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x3E TLS_DH_DSS_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x3F TLS_DH_RSA_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x40 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x41 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x42 TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x43 TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x44 TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x45 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x46 TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
* 0x00,0x47-4F Reserved to avoid conflicts with
* deployed implementations [Pasi_Eronen]
* 0x00,0x50-58 Reserved to avoid conflicts [Pasi Eronen]
@@ -771,143 +771,261 @@
* 0x00,0x5D-5F Unassigned
* 0x00,0x60-66 Reserved to avoid conflicts with widely
* deployed implementations [Pasi_Eronen]
- * 0x00,0x67 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 [RFC5246]
- * 0x00,0x68 TLS_DH_DSS_WITH_AES_256_CBC_SHA256 [RFC5246]
- * 0x00,0x69 TLS_DH_RSA_WITH_AES_256_CBC_SHA256 [RFC5246]
- * 0x00,0x6A TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 [RFC5246]
- * 0x00,0x6B TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 [RFC5246]
- * 0x00,0x6C TLS_DH_anon_WITH_AES_128_CBC_SHA256 [RFC5246]
- * 0x00,0x6D TLS_DH_anon_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x67 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x68 TLS_DH_DSS_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x69 TLS_DH_RSA_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x6A TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x6B TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x6C TLS_DH_anon_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x6D TLS_DH_anon_WITH_AES_256_CBC_SHA256 [RFC5246]
* 0x00,0x6E-83 Unassigned
- * 0x00,0x84 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
- * 0x00,0x85 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
- * 0x00,0x86 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
- * 0x00,0x87 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
- * 0x00,0x88 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
- * 0x00,0x89 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
- * 0x00,0x8A TLS_PSK_WITH_RC4_128_SHA [RFC4279]
- * 0x00,0x8B TLS_PSK_WITH_3DES_EDE_CBC_SHA [RFC4279]
- * 0x00,0x8C TLS_PSK_WITH_AES_128_CBC_SHA [RFC4279]
- * 0x00,0x8D TLS_PSK_WITH_AES_256_CBC_SHA [RFC4279]
- * 0x00,0x8E TLS_DHE_PSK_WITH_RC4_128_SHA [RFC4279]
- * 0x00,0x8F TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA [RFC4279]
- * 0x00,0x90 TLS_DHE_PSK_WITH_AES_128_CBC_SHA [RFC4279]
- * 0x00,0x91 TLS_DHE_PSK_WITH_AES_256_CBC_SHA [RFC4279]
- * 0x00,0x92 TLS_RSA_PSK_WITH_RC4_128_SHA [RFC4279]
- * 0x00,0x93 TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA [RFC4279]
- * 0x00,0x94 TLS_RSA_PSK_WITH_AES_128_CBC_SHA [RFC4279]
- * 0x00,0x95 TLS_RSA_PSK_WITH_AES_256_CBC_SHA [RFC4279]
- * 0x00,0x96 TLS_RSA_WITH_SEED_CBC_SHA [RFC4162]
- * 0x00,0x97 TLS_DH_DSS_WITH_SEED_CBC_SHA [RFC4162]
- * 0x00,0x98 TLS_DH_RSA_WITH_SEED_CBC_SHA [RFC4162]
- * 0x00,0x99 TLS_DHE_DSS_WITH_SEED_CBC_SHA [RFC4162]
- * 0x00,0x9A TLS_DHE_RSA_WITH_SEED_CBC_SHA [RFC4162]
- * 0x00,0x9B TLS_DH_anon_WITH_SEED_CBC_SHA [RFC4162]
- * 0x00,0x9C TLS_RSA_WITH_AES_128_GCM_SHA256 [RFC5288]
- * 0x00,0x9D TLS_RSA_WITH_AES_256_GCM_SHA384 [RFC5288]
- * 0x00,0x9E TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 [RFC5288]
- * 0x00,0x9F TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 [RFC5288]
- * 0x00,0xA0 TLS_DH_RSA_WITH_AES_128_GCM_SHA256 [RFC5288]
- * 0x00,0xA1 TLS_DH_RSA_WITH_AES_256_GCM_SHA384 [RFC5288]
- * 0x00,0xA2 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 [RFC5288]
- * 0x00,0xA3 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 [RFC5288]
- * 0x00,0xA4 TLS_DH_DSS_WITH_AES_128_GCM_SHA256 [RFC5288]
- * 0x00,0xA5 TLS_DH_DSS_WITH_AES_256_GCM_SHA384 [RFC5288]
- * 0x00,0xA6 TLS_DH_anon_WITH_AES_128_GCM_SHA256 [RFC5288]
- * 0x00,0xA7 TLS_DH_anon_WITH_AES_256_GCM_SHA384 [RFC5288]
- * 0x00,0xA8 TLS_PSK_WITH_AES_128_GCM_SHA256 [RFC5487]
- * 0x00,0xA9 TLS_PSK_WITH_AES_256_GCM_SHA384 [RFC5487]
- * 0x00,0xAA TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 [RFC5487]
- * 0x00,0xAB TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 [RFC5487]
- * 0x00,0xAC TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 [RFC5487]
- * 0x00,0xAD TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 [RFC5487]
- * 0x00,0xAE TLS_PSK_WITH_AES_128_CBC_SHA256 [RFC5487]
- * 0x00,0xAF TLS_PSK_WITH_AES_256_CBC_SHA384 [RFC5487]
- * 0x00,0xB0 TLS_PSK_WITH_NULL_SHA256 [RFC5487]
- * 0x00,0xB1 TLS_PSK_WITH_NULL_SHA384 [RFC5487]
- * 0x00,0xB2 TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 [RFC5487]
- * 0x00,0xB3 TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 [RFC5487]
- * 0x00,0xB4 TLS_DHE_PSK_WITH_NULL_SHA256 [RFC5487]
- * 0x00,0xB5 TLS_DHE_PSK_WITH_NULL_SHA384 [RFC5487]
- * 0x00,0xB6 TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 [RFC5487]
- * 0x00,0xB7 TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 [RFC5487]
- * 0x00,0xB8 TLS_RSA_PSK_WITH_NULL_SHA256 [RFC5487]
- * 0x00,0xB9 TLS_RSA_PSK_WITH_NULL_SHA384 [RFC5487]
- * 0x00,0xBA TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
- * 0x00,0xBB TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
- * 0x00,0xBC TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
- * 0x00,0xBD TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
- * 0x00,0xBE TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
- * 0x00,0xBF TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
- * 0x00,0xC0 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
- * 0x00,0xC1 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
- * 0x00,0xC2 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
- * 0x00,0xC3 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
- * 0x00,0xC4 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
- * 0x00,0xC5 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0x84 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x85 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x86 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x87 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x88 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x89 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x8A TLS_PSK_WITH_RC4_128_SHA [RFC4279]
+ * 0x00,0x8B TLS_PSK_WITH_3DES_EDE_CBC_SHA [RFC4279]
+ * 0x00,0x8C TLS_PSK_WITH_AES_128_CBC_SHA [RFC4279]
+ * 0x00,0x8D TLS_PSK_WITH_AES_256_CBC_SHA [RFC4279]
+ * 0x00,0x8E TLS_DHE_PSK_WITH_RC4_128_SHA [RFC4279]
+ * 0x00,0x8F TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA [RFC4279]
+ * 0x00,0x90 TLS_DHE_PSK_WITH_AES_128_CBC_SHA [RFC4279]
+ * 0x00,0x91 TLS_DHE_PSK_WITH_AES_256_CBC_SHA [RFC4279]
+ * 0x00,0x92 TLS_RSA_PSK_WITH_RC4_128_SHA [RFC4279]
+ * 0x00,0x93 TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA [RFC4279]
+ * 0x00,0x94 TLS_RSA_PSK_WITH_AES_128_CBC_SHA [RFC4279]
+ * 0x00,0x95 TLS_RSA_PSK_WITH_AES_256_CBC_SHA [RFC4279]
+ * 0x00,0x96 TLS_RSA_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x97 TLS_DH_DSS_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x98 TLS_DH_RSA_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x99 TLS_DHE_DSS_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x9A TLS_DHE_RSA_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x9B TLS_DH_anon_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x9C TLS_RSA_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0x9D TLS_RSA_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0x9E TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0x9F TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0xA0 TLS_DH_RSA_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0xA1 TLS_DH_RSA_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0xA2 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0xA3 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0xA4 TLS_DH_DSS_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0xA5 TLS_DH_DSS_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0xA6 TLS_DH_anon_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0xA7 TLS_DH_anon_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0xA8 TLS_PSK_WITH_AES_128_GCM_SHA256 [RFC5487]
+ * 0x00,0xA9 TLS_PSK_WITH_AES_256_GCM_SHA384 [RFC5487]
+ * 0x00,0xAA TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 [RFC5487]
+ * 0x00,0xAB TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 [RFC5487]
+ * 0x00,0xAC TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 [RFC5487]
+ * 0x00,0xAD TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 [RFC5487]
+ * 0x00,0xAE TLS_PSK_WITH_AES_128_CBC_SHA256 [RFC5487]
+ * 0x00,0xAF TLS_PSK_WITH_AES_256_CBC_SHA384 [RFC5487]
+ * 0x00,0xB0 TLS_PSK_WITH_NULL_SHA256 [RFC5487]
+ * 0x00,0xB1 TLS_PSK_WITH_NULL_SHA384 [RFC5487]
+ * 0x00,0xB2 TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 [RFC5487]
+ * 0x00,0xB3 TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 [RFC5487]
+ * 0x00,0xB4 TLS_DHE_PSK_WITH_NULL_SHA256 [RFC5487]
+ * 0x00,0xB5 TLS_DHE_PSK_WITH_NULL_SHA384 [RFC5487]
+ * 0x00,0xB6 TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 [RFC5487]
+ * 0x00,0xB7 TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 [RFC5487]
+ * 0x00,0xB8 TLS_RSA_PSK_WITH_NULL_SHA256 [RFC5487]
+ * 0x00,0xB9 TLS_RSA_PSK_WITH_NULL_SHA384 [RFC5487]
+ * 0x00,0xBA TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xBB TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xBC TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xBD TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xBE TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xBF TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xC0 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC1 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC2 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC3 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC4 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC5 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
* 0x00,0xC6-FE Unassigned
- * 0x00,0xFF TLS_EMPTY_RENEGOTIATION_INFO_SCSV [RFC5746]
- * 0x01-BF,* Unassigned
- * 0xC0,0x01 TLS_ECDH_ECDSA_WITH_NULL_SHA [RFC4492]
- * 0xC0,0x02 TLS_ECDH_ECDSA_WITH_RC4_128_SHA [RFC4492]
- * 0xC0,0x03 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
- * 0xC0,0x04 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA [RFC4492]
- * 0xC0,0x05 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA [RFC4492]
- * 0xC0,0x06 TLS_ECDHE_ECDSA_WITH_NULL_SHA [RFC4492]
- * 0xC0,0x07 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA [RFC4492]
- * 0xC0,0x08 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
- * 0xC0,0x09 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA [RFC4492]
- * 0xC0,0x0A TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA [RFC4492]
- * 0xC0,0x0B TLS_ECDH_RSA_WITH_NULL_SHA [RFC4492]
- * 0xC0,0x0C TLS_ECDH_RSA_WITH_RC4_128_SHA [RFC4492]
- * 0xC0,0x0D TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
- * 0xC0,0x0E TLS_ECDH_RSA_WITH_AES_128_CBC_SHA [RFC4492]
- * 0xC0,0x0F TLS_ECDH_RSA_WITH_AES_256_CBC_SHA [RFC4492]
- * 0xC0,0x10 TLS_ECDHE_RSA_WITH_NULL_SHA [RFC4492]
- * 0xC0,0x11 TLS_ECDHE_RSA_WITH_RC4_128_SHA [RFC4492]
- * 0xC0,0x12 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
- * 0xC0,0x13 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA [RFC4492]
- * 0xC0,0x14 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA [RFC4492]
- * 0xC0,0x15 TLS_ECDH_anon_WITH_NULL_SHA [RFC4492]
- * 0xC0,0x16 TLS_ECDH_anon_WITH_RC4_128_SHA [RFC4492]
- * 0xC0,0x17 TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA [RFC4492]
- * 0xC0,0x18 TLS_ECDH_anon_WITH_AES_128_CBC_SHA [RFC4492]
- * 0xC0,0x19 TLS_ECDH_anon_WITH_AES_256_CBC_SHA [RFC4492]
- * 0xC0,0x1A TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA [RFC5054]
- * 0xC0,0x1B TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA [RFC5054]
- * 0xC0,0x1C TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA [RFC5054]
- * 0xC0,0x1D TLS_SRP_SHA_WITH_AES_128_CBC_SHA [RFC5054]
- * 0xC0,0x1E TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA [RFC5054]
- * 0xC0,0x1F TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA [RFC5054]
- * 0xC0,0x20 TLS_SRP_SHA_WITH_AES_256_CBC_SHA [RFC5054]
- * 0xC0,0x21 TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA [RFC5054]
- * 0xC0,0x22 TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA [RFC5054]
- * 0xC0,0x23 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 [RFC5289]
- * 0xC0,0x24 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 [RFC5289]
- * 0xC0,0x25 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 [RFC5289]
- * 0xC0,0x26 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 [RFC5289]
- * 0xC0,0x27 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 [RFC5289]
- * 0xC0,0x28 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 [RFC5289]
- * 0xC0,0x29 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 [RFC5289]
- * 0xC0,0x2A TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 [RFC5289]
- * 0xC0,0x2B TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 [RFC5289]
- * 0xC0,0x2C TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 [RFC5289]
- * 0xC0,0x2D TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 [RFC5289]
- * 0xC0,0x2E TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 [RFC5289]
- * 0xC0,0x2F TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [RFC5289]
- * 0xC0,0x30 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 [RFC5289]
- * 0xC0,0x31 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 [RFC5289]
- * 0xC0,0x32 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 [RFC5289]
- * 0xC0,0x33 TLS_ECDHE_PSK_WITH_RC4_128_SHA [RFC5489]
- * 0xC0,0x34 TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA [RFC5489]
- * 0xC0,0x35 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA [RFC5489]
- * 0xC0,0x36 TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA [RFC5489]
- * 0xC0,0x37 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 [RFC5489]
- * 0xC0,0x38 TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 [RFC5489]
- * 0xC0,0x39 TLS_ECDHE_PSK_WITH_NULL_SHA [RFC5489]
- * 0xC0,0x3A TLS_ECDHE_PSK_WITH_NULL_SHA256 [RFC5489]
- * 0xC0,0x3B TLS_ECDHE_PSK_WITH_NULL_SHA384 [RFC5489]
- * 0xC0,0x3C-FF Unassigned
+ * 0x00,0xFF TLS_EMPTY_RENEGOTIATION_INFO_SCSV [RFC5746]
+ * 0x01-55,* Unassigned
+ * 0x56,0x00 TLS_FALLBACK_SCSV [RFC7507]
+ * 0x56,0x01-0xC0,0x00 Unassigned
+ * 0xC0,0x01 TLS_ECDH_ECDSA_WITH_NULL_SHA [RFC4492]
+ * 0xC0,0x02 TLS_ECDH_ECDSA_WITH_RC4_128_SHA [RFC4492]
+ * 0xC0,0x03 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
+ * 0xC0,0x04 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA [RFC4492]
+ * 0xC0,0x05 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA [RFC4492]
+ * 0xC0,0x06 TLS_ECDHE_ECDSA_WITH_NULL_SHA [RFC4492]
+ * 0xC0,0x07 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA [RFC4492]
+ * 0xC0,0x08 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
+ * 0xC0,0x09 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA [RFC4492]
+ * 0xC0,0x0A TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA [RFC4492]
+ * 0xC0,0x0B TLS_ECDH_RSA_WITH_NULL_SHA [RFC4492]
+ * 0xC0,0x0C TLS_ECDH_RSA_WITH_RC4_128_SHA [RFC4492]
+ * 0xC0,0x0D TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
+ * 0xC0,0x0E TLS_ECDH_RSA_WITH_AES_128_CBC_SHA [RFC4492]
+ * 0xC0,0x0F TLS_ECDH_RSA_WITH_AES_256_CBC_SHA [RFC4492]
+ * 0xC0,0x10 TLS_ECDHE_RSA_WITH_NULL_SHA [RFC4492]
+ * 0xC0,0x11 TLS_ECDHE_RSA_WITH_RC4_128_SHA [RFC4492]
+ * 0xC0,0x12 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
+ * 0xC0,0x13 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA [RFC4492]
+ * 0xC0,0x14 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA [RFC4492]
+ * 0xC0,0x15 TLS_ECDH_anon_WITH_NULL_SHA [RFC4492]
+ * 0xC0,0x16 TLS_ECDH_anon_WITH_RC4_128_SHA [RFC4492]
+ * 0xC0,0x17 TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA [RFC4492]
+ * 0xC0,0x18 TLS_ECDH_anon_WITH_AES_128_CBC_SHA [RFC4492]
+ * 0xC0,0x19 TLS_ECDH_anon_WITH_AES_256_CBC_SHA [RFC4492]
+ * 0xC0,0x1A TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA [RFC5054]
+ * 0xC0,0x1B TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA [RFC5054]
+ * 0xC0,0x1C TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA [RFC5054]
+ * 0xC0,0x1D TLS_SRP_SHA_WITH_AES_128_CBC_SHA [RFC5054]
+ * 0xC0,0x1E TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA [RFC5054]
+ * 0xC0,0x1F TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA [RFC5054]
+ * 0xC0,0x20 TLS_SRP_SHA_WITH_AES_256_CBC_SHA [RFC5054]
+ * 0xC0,0x21 TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA [RFC5054]
+ * 0xC0,0x22 TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA [RFC5054]
+ * 0xC0,0x23 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 [RFC5289]
+ * 0xC0,0x24 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 [RFC5289]
+ * 0xC0,0x25 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 [RFC5289]
+ * 0xC0,0x26 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 [RFC5289]
+ * 0xC0,0x27 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 [RFC5289]
+ * 0xC0,0x28 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 [RFC5289]
+ * 0xC0,0x29 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 [RFC5289]
+ * 0xC0,0x2A TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 [RFC5289]
+ * 0xC0,0x2B TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 [RFC5289]
+ * 0xC0,0x2C TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 [RFC5289]
+ * 0xC0,0x2D TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 [RFC5289]
+ * 0xC0,0x2E TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 [RFC5289]
+ * 0xC0,0x2F TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [RFC5289]
+ * 0xC0,0x30 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 [RFC5289]
+ * 0xC0,0x31 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 [RFC5289]
+ * 0xC0,0x32 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 [RFC5289]
+ * 0xC0,0x33 TLS_ECDHE_PSK_WITH_RC4_128_SHA [RFC5489]
+ * 0xC0,0x34 TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA [RFC5489]
+ * 0xC0,0x35 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA [RFC5489]
+ * 0xC0,0x36 TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA [RFC5489]
+ * 0xC0,0x37 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 [RFC5489]
+ * 0xC0,0x38 TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 [RFC5489]
+ * 0xC0,0x39 TLS_ECDHE_PSK_WITH_NULL_SHA [RFC5489]
+ * 0xC0,0x3A TLS_ECDHE_PSK_WITH_NULL_SHA256 [RFC5489]
+ * 0xC0,0x3B TLS_ECDHE_PSK_WITH_NULL_SHA384 [RFC5489]
+ * 0xC0,0x3C TLS_RSA_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x3D TLS_RSA_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x3E TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x3F TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x40 TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x41 TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x42 TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x43 TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x44 TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x45 TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x46 TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x47 TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x48 TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x49 TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x4A TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x4B TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x4C TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x4D TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x4E TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x4F TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x50 TLS_RSA_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x51 TLS_RSA_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x52 TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x53 TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x54 TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x55 TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x56 TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x57 TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x58 TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x59 TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x5A TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x5B TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x5C TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x5D TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x5E TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x5F TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x60 TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x61 TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x62 TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x63 TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x64 TLS_PSK_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x65 TLS_PSK_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x66 TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x67 TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x68 TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x69 TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x6A TLS_PSK_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x6B TLS_PSK_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x6C TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x6D TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x6E TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x6F TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x70 TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x71 TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x72 TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x73 TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x74 TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x75 TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x76 TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x77 TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x78 TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x79 TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x7A TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x7B TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x7C TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x7D TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x7E TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x7F TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x80 TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x81 TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x82 TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x83 TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x84 TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x85 TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x86 TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x87 TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x88 TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x89 TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x8A TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x8B TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x8C TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x8D TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x8E TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x8F TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x90 TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x91 TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x92 TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x93 TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x94 TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x95 TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x96 TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x97 TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x98 TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x99 TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x9A TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x9B TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x9C TLS_RSA_WITH_AES_128_CCM [RFC6655]
+ * 0xC0,0x9D TLS_RSA_WITH_AES_256_CCM [RFC6655]
+ * 0xC0,0x9E TLS_DHE_RSA_WITH_AES_128_CCM [RFC6655]
+ * 0xC0,0x9F TLS_DHE_RSA_WITH_AES_256_CCM [RFC6655]
+ * 0xC0,0xA0 TLS_RSA_WITH_AES_128_CCM_8 [RFC6655]
+ * 0xC0,0xA1 TLS_RSA_WITH_AES_256_CCM_8 [RFC6655]
+ * 0xC0,0xA2 TLS_DHE_RSA_WITH_AES_128_CCM_8 [RFC6655]
+ * 0xC0,0xA3 TLS_DHE_RSA_WITH_AES_256_CCM_8 [RFC6655]
+ * 0xC0,0xA4 TLS_PSK_WITH_AES_128_CCM [RFC6655]
+ * 0xC0,0xA5 TLS_PSK_WITH_AES_256_CCM [RFC6655]
+ * 0xC0,0xA6 TLS_DHE_PSK_WITH_AES_128_CCM [RFC6655]
+ * 0xC0,0xA7 TLS_DHE_PSK_WITH_AES_256_CCM [RFC6655]
+ * 0xC0,0xA8 TLS_PSK_WITH_AES_128_CCM_8 [RFC6655]
+ * 0xC0,0xA9 TLS_PSK_WITH_AES_256_CCM_8 [RFC6655]
+ * 0xC0,0xAA TLS_PSK_DHE_WITH_AES_128_CCM_8 [RFC6655]
+ * 0xC0,0xAB TLS_PSK_DHE_WITH_AES_256_CCM_8 [RFC6655]
+ * 0xC0,0xAC TLS_ECDHE_ECDSA_WITH_AES_128_CCM [RFC7251]
+ * 0xC0,0xAD TLS_ECDHE_ECDSA_WITH_AES_256_CCM [RFC7251]
+ * 0xC0,0xAE TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 [RFC7251]
+ * 0xC0,0xAF TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 [RFC7251]
+ * 0xC0,0xB0-FF Unassigned
* 0xC1-FD,* Unassigned
* 0xFE,0x00-FD Unassigned
* 0xFE,0xFE-FF Reserved to avoid conflicts with widely
@@ -1220,149 +1338,276 @@
// the debug output.
// remaining unsupported ciphersuites defined in RFC2246.
- add("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", 0x0006);
- add("SSL_RSA_WITH_IDEA_CBC_SHA", 0x0007);
- add("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", 0x000b);
- add("SSL_DH_DSS_WITH_DES_CBC_SHA", 0x000c);
- add("SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA", 0x000d);
- add("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x000e);
- add("SSL_DH_RSA_WITH_DES_CBC_SHA", 0x000f);
- add("SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA", 0x0010);
+ add("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", 0x0006);
+ add("SSL_RSA_WITH_IDEA_CBC_SHA", 0x0007);
+ add("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", 0x000b);
+ add("SSL_DH_DSS_WITH_DES_CBC_SHA", 0x000c);
+ add("SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA", 0x000d);
+ add("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x000e);
+ add("SSL_DH_RSA_WITH_DES_CBC_SHA", 0x000f);
+ add("SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA", 0x0010);
// SSL 3.0 Fortezza ciphersuites
- add("SSL_FORTEZZA_DMS_WITH_NULL_SHA", 0x001c);
- add("SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA", 0x001d);
+ add("SSL_FORTEZZA_DMS_WITH_NULL_SHA", 0x001c);
+ add("SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA", 0x001d);
// 1024/56 bit exportable ciphersuites from expired internet draft
- add("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA", 0x0062);
- add("SSL_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA", 0x0063);
- add("SSL_RSA_EXPORT1024_WITH_RC4_56_SHA", 0x0064);
- add("SSL_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA", 0x0065);
- add("SSL_DHE_DSS_WITH_RC4_128_SHA", 0x0066);
+ add("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA", 0x0062);
+ add("SSL_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA", 0x0063);
+ add("SSL_RSA_EXPORT1024_WITH_RC4_56_SHA", 0x0064);
+ add("SSL_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA", 0x0065);
+ add("SSL_DHE_DSS_WITH_RC4_128_SHA", 0x0066);
// Netscape old and new SSL 3.0 FIPS ciphersuites
// see http://www.mozilla.org/projects/security/pki/nss/ssl/fips-ssl-ciphersuites.html
- add("NETSCAPE_RSA_FIPS_WITH_3DES_EDE_CBC_SHA", 0xffe0);
- add("NETSCAPE_RSA_FIPS_WITH_DES_CBC_SHA", 0xffe1);
- add("SSL_RSA_FIPS_WITH_DES_CBC_SHA", 0xfefe);
- add("SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA", 0xfeff);
+ add("NETSCAPE_RSA_FIPS_WITH_3DES_EDE_CBC_SHA", 0xffe0);
+ add("NETSCAPE_RSA_FIPS_WITH_DES_CBC_SHA", 0xffe1);
+ add("SSL_RSA_FIPS_WITH_DES_CBC_SHA", 0xfefe);
+ add("SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA", 0xfeff);
// Unsupported Kerberos cipher suites from RFC 2712
- add("TLS_KRB5_WITH_IDEA_CBC_SHA", 0x0021);
- add("TLS_KRB5_WITH_IDEA_CBC_MD5", 0x0025);
- add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", 0x0027);
- add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", 0x002a);
+ add("TLS_KRB5_WITH_IDEA_CBC_SHA", 0x0021);
+ add("TLS_KRB5_WITH_IDEA_CBC_MD5", 0x0025);
+ add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", 0x0027);
+ add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", 0x002a);
// Unsupported cipher suites from RFC 4162
- add("TLS_RSA_WITH_SEED_CBC_SHA", 0x0096);
- add("TLS_DH_DSS_WITH_SEED_CBC_SHA", 0x0097);
- add("TLS_DH_RSA_WITH_SEED_CBC_SHA", 0x0098);
- add("TLS_DHE_DSS_WITH_SEED_CBC_SHA", 0x0099);
- add("TLS_DHE_RSA_WITH_SEED_CBC_SHA", 0x009a);
- add("TLS_DH_anon_WITH_SEED_CBC_SHA", 0x009b);
+ add("TLS_RSA_WITH_SEED_CBC_SHA", 0x0096);
+ add("TLS_DH_DSS_WITH_SEED_CBC_SHA", 0x0097);
+ add("TLS_DH_RSA_WITH_SEED_CBC_SHA", 0x0098);
+ add("TLS_DHE_DSS_WITH_SEED_CBC_SHA", 0x0099);
+ add("TLS_DHE_RSA_WITH_SEED_CBC_SHA", 0x009a);
+ add("TLS_DH_anon_WITH_SEED_CBC_SHA", 0x009b);
// Unsupported cipher suites from RFC 4279
- add("TLS_PSK_WITH_RC4_128_SHA", 0x008a);
- add("TLS_PSK_WITH_3DES_EDE_CBC_SHA", 0x008b);
- add("TLS_PSK_WITH_AES_128_CBC_SHA", 0x008c);
- add("TLS_PSK_WITH_AES_256_CBC_SHA", 0x008d);
- add("TLS_DHE_PSK_WITH_RC4_128_SHA", 0x008e);
- add("TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA", 0x008f);
- add("TLS_DHE_PSK_WITH_AES_128_CBC_SHA", 0x0090);
- add("TLS_DHE_PSK_WITH_AES_256_CBC_SHA", 0x0091);
- add("TLS_RSA_PSK_WITH_RC4_128_SHA", 0x0092);
- add("TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA", 0x0093);
- add("TLS_RSA_PSK_WITH_AES_128_CBC_SHA", 0x0094);
- add("TLS_RSA_PSK_WITH_AES_256_CBC_SHA", 0x0095);
+ add("TLS_PSK_WITH_RC4_128_SHA", 0x008a);
+ add("TLS_PSK_WITH_3DES_EDE_CBC_SHA", 0x008b);
+ add("TLS_PSK_WITH_AES_128_CBC_SHA", 0x008c);
+ add("TLS_PSK_WITH_AES_256_CBC_SHA", 0x008d);
+ add("TLS_DHE_PSK_WITH_RC4_128_SHA", 0x008e);
+ add("TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA", 0x008f);
+ add("TLS_DHE_PSK_WITH_AES_128_CBC_SHA", 0x0090);
+ add("TLS_DHE_PSK_WITH_AES_256_CBC_SHA", 0x0091);
+ add("TLS_RSA_PSK_WITH_RC4_128_SHA", 0x0092);
+ add("TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA", 0x0093);
+ add("TLS_RSA_PSK_WITH_AES_128_CBC_SHA", 0x0094);
+ add("TLS_RSA_PSK_WITH_AES_256_CBC_SHA", 0x0095);
// Unsupported cipher suites from RFC 4785
- add("TLS_PSK_WITH_NULL_SHA", 0x002c);
- add("TLS_DHE_PSK_WITH_NULL_SHA", 0x002d);
- add("TLS_RSA_PSK_WITH_NULL_SHA", 0x002e);
+ add("TLS_PSK_WITH_NULL_SHA", 0x002c);
+ add("TLS_DHE_PSK_WITH_NULL_SHA", 0x002d);
+ add("TLS_RSA_PSK_WITH_NULL_SHA", 0x002e);
// Unsupported cipher suites from RFC 5246
- add("TLS_DH_DSS_WITH_AES_128_CBC_SHA", 0x0030);
- add("TLS_DH_RSA_WITH_AES_128_CBC_SHA", 0x0031);
- add("TLS_DH_DSS_WITH_AES_256_CBC_SHA", 0x0036);
- add("TLS_DH_RSA_WITH_AES_256_CBC_SHA", 0x0037);
- add("TLS_DH_DSS_WITH_AES_128_CBC_SHA256", 0x003e);
- add("TLS_DH_RSA_WITH_AES_128_CBC_SHA256", 0x003f);
- add("TLS_DH_DSS_WITH_AES_256_CBC_SHA256", 0x0068);
- add("TLS_DH_RSA_WITH_AES_256_CBC_SHA256", 0x0069);
+ add("TLS_DH_DSS_WITH_AES_128_CBC_SHA", 0x0030);
+ add("TLS_DH_RSA_WITH_AES_128_CBC_SHA", 0x0031);
+ add("TLS_DH_DSS_WITH_AES_256_CBC_SHA", 0x0036);
+ add("TLS_DH_RSA_WITH_AES_256_CBC_SHA", 0x0037);
+ add("TLS_DH_DSS_WITH_AES_128_CBC_SHA256", 0x003e);
+ add("TLS_DH_RSA_WITH_AES_128_CBC_SHA256", 0x003f);
+ add("TLS_DH_DSS_WITH_AES_256_CBC_SHA256", 0x0068);
+ add("TLS_DH_RSA_WITH_AES_256_CBC_SHA256", 0x0069);
// Unsupported cipher suites from RFC 5288
- add("TLS_DH_RSA_WITH_AES_128_GCM_SHA256", 0x00a0);
- add("TLS_DH_RSA_WITH_AES_256_GCM_SHA384", 0x00a1);
- add("TLS_DH_DSS_WITH_AES_128_GCM_SHA256", 0x00a4);
- add("TLS_DH_DSS_WITH_AES_256_GCM_SHA384", 0x00a5);
+ add("TLS_DH_RSA_WITH_AES_128_GCM_SHA256", 0x00a0);
+ add("TLS_DH_RSA_WITH_AES_256_GCM_SHA384", 0x00a1);
+ add("TLS_DH_DSS_WITH_AES_128_GCM_SHA256", 0x00a4);
+ add("TLS_DH_DSS_WITH_AES_256_GCM_SHA384", 0x00a5);
// Unsupported cipher suites from RFC 5487
- add("TLS_PSK_WITH_AES_128_GCM_SHA256", 0x00a8);
- add("TLS_PSK_WITH_AES_256_GCM_SHA384", 0x00a9);
- add("TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", 0x00aa);
- add("TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", 0x00ab);
- add("TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", 0x00ac);
- add("TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", 0x00ad);
- add("TLS_PSK_WITH_AES_128_CBC_SHA256", 0x00ae);
- add("TLS_PSK_WITH_AES_256_CBC_SHA384", 0x00af);
- add("TLS_PSK_WITH_NULL_SHA256", 0x00b0);
- add("TLS_PSK_WITH_NULL_SHA384", 0x00b1);
- add("TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", 0x00b2);
- add("TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", 0x00b3);
- add("TLS_DHE_PSK_WITH_NULL_SHA256", 0x00b4);
- add("TLS_DHE_PSK_WITH_NULL_SHA384", 0x00b5);
- add("TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", 0x00b6);
- add("TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", 0x00b7);
- add("TLS_RSA_PSK_WITH_NULL_SHA256", 0x00b8);
- add("TLS_RSA_PSK_WITH_NULL_SHA384", 0x00b9);
+ add("TLS_PSK_WITH_AES_128_GCM_SHA256", 0x00a8);
+ add("TLS_PSK_WITH_AES_256_GCM_SHA384", 0x00a9);
+ add("TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", 0x00aa);
+ add("TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", 0x00ab);
+ add("TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", 0x00ac);
+ add("TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", 0x00ad);
+ add("TLS_PSK_WITH_AES_128_CBC_SHA256", 0x00ae);
+ add("TLS_PSK_WITH_AES_256_CBC_SHA384", 0x00af);
+ add("TLS_PSK_WITH_NULL_SHA256", 0x00b0);
+ add("TLS_PSK_WITH_NULL_SHA384", 0x00b1);
+ add("TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", 0x00b2);
+ add("TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", 0x00b3);
+ add("TLS_DHE_PSK_WITH_NULL_SHA256", 0x00b4);
+ add("TLS_DHE_PSK_WITH_NULL_SHA384", 0x00b5);
+ add("TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", 0x00b6);
+ add("TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", 0x00b7);
+ add("TLS_RSA_PSK_WITH_NULL_SHA256", 0x00b8);
+ add("TLS_RSA_PSK_WITH_NULL_SHA384", 0x00b9);
// Unsupported cipher suites from RFC 5932
- add("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0041);
- add("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA", 0x0042);
- add("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0043);
- add("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", 0x0044);
- add("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0045);
- add("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA", 0x0046);
- add("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0084);
- add("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA", 0x0085);
- add("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0086);
- add("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", 0x0087);
- add("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0088);
- add("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA", 0x0089);
- add("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00ba);
- add("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256", 0x00bb);
- add("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00bc);
- add("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", 0x00bd);
- add("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00be);
- add("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256", 0x00bf);
- add("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c0);
- add("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256", 0x00c1);
- add("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c2);
- add("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", 0x00c3);
- add("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c4);
- add("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256", 0x00c5);
+ add("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0041);
+ add("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA", 0x0042);
+ add("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0043);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", 0x0044);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0045);
+ add("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA", 0x0046);
+ add("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0084);
+ add("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA", 0x0085);
+ add("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0086);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", 0x0087);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0088);
+ add("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA", 0x0089);
+ add("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00ba);
+ add("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256", 0x00bb);
+ add("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00bc);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", 0x00bd);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00be);
+ add("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256", 0x00bf);
+ add("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c0);
+ add("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256", 0x00c1);
+ add("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c2);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", 0x00c3);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c4);
+ add("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256", 0x00c5);
+
+ // TLS Fallback Signaling Cipher Suite Value (SCSV) RFC 7507
+ add("TLS_FALLBACK_SCSV", 0x5600);
// Unsupported cipher suites from RFC 5054
- add("TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", 0xc01a);
- add("TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", 0xc01b);
- add("TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", 0xc01c);
- add("TLS_SRP_SHA_WITH_AES_128_CBC_SHA", 0xc01d);
- add("TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", 0xc01e);
- add("TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", 0xc01f);
- add("TLS_SRP_SHA_WITH_AES_256_CBC_SHA", 0xc020);
- add("TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", 0xc021);
- add("TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", 0xc022);
+ add("TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", 0xc01a);
+ add("TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", 0xc01b);
+ add("TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", 0xc01c);
+ add("TLS_SRP_SHA_WITH_AES_128_CBC_SHA", 0xc01d);
+ add("TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", 0xc01e);
+ add("TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", 0xc01f);
+ add("TLS_SRP_SHA_WITH_AES_256_CBC_SHA", 0xc020);
+ add("TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", 0xc021);
+ add("TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", 0xc022);
// Unsupported cipher suites from RFC 5489
- add("TLS_ECDHE_PSK_WITH_RC4_128_SHA", 0xc033);
- add("TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", 0xc034);
- add("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", 0xc035);
- add("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", 0xc036);
- add("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", 0xc037);
- add("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", 0xc038);
- add("TLS_ECDHE_PSK_WITH_NULL_SHA", 0xc039);
- add("TLS_ECDHE_PSK_WITH_NULL_SHA256", 0xc03a);
- add("TLS_ECDHE_PSK_WITH_NULL_SHA384", 0xc03b);
+ add("TLS_ECDHE_PSK_WITH_RC4_128_SHA", 0xc033);
+ add("TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", 0xc034);
+ add("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", 0xc035);
+ add("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", 0xc036);
+ add("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", 0xc037);
+ add("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", 0xc038);
+ add("TLS_ECDHE_PSK_WITH_NULL_SHA", 0xc039);
+ add("TLS_ECDHE_PSK_WITH_NULL_SHA256", 0xc03a);
+ add("TLS_ECDHE_PSK_WITH_NULL_SHA384", 0xc03b);
+
+ // Unsupported cipher suites from RFC 6209
+ add("TLS_RSA_WITH_ARIA_128_CBC_SHA256", 0xc03c);
+ add("TLS_RSA_WITH_ARIA_256_CBC_SHA384", 0xc03d);
+ add("TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256", 0xc03e);
+ add("TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384", 0xc03f);
+ add("TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256", 0xc040);
+ add("TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384", 0xc041);
+ add("TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256", 0xc042);
+ add("TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384", 0xc043);
+ add("TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256", 0xc044);
+ add("TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384", 0xc045);
+ add("TLS_DH_anon_WITH_ARIA_128_CBC_SHA256", 0xc046);
+ add("TLS_DH_anon_WITH_ARIA_256_CBC_SHA384", 0xc047);
+ add("TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256", 0xc048);
+ add("TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384", 0xc049);
+ add("TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256", 0xc04a);
+ add("TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384", 0xc04b);
+ add("TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256", 0xc04c);
+ add("TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384", 0xc04d);
+ add("TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256", 0xc04e);
+ add("TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384", 0xc04f);
+ add("TLS_RSA_WITH_ARIA_128_GCM_SHA256", 0xc050);
+ add("TLS_RSA_WITH_ARIA_256_GCM_SHA384", 0xc051);
+ add("TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256", 0xc052);
+ add("TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384", 0xc053);
+ add("TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256", 0xc054);
+ add("TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384", 0xc055);
+ add("TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256", 0xc056);
+ add("TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384", 0xc057);
+ add("TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256", 0xc058);
+ add("TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384", 0xc059);
+ add("TLS_DH_anon_WITH_ARIA_128_GCM_SHA256", 0xc05a);
+ add("TLS_DH_anon_WITH_ARIA_256_GCM_SHA384", 0xc05b);
+ add("TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256", 0xc05c);
+ add("TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384", 0xc05d);
+ add("TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256", 0xc05e);
+ add("TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384", 0xc05f);
+ add("TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256", 0xc060);
+ add("TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384", 0xc061);
+ add("TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256", 0xc062);
+ add("TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384", 0xc063);
+ add("TLS_PSK_WITH_ARIA_128_CBC_SHA256", 0xc064);
+ add("TLS_PSK_WITH_ARIA_256_CBC_SHA384", 0xc065);
+ add("TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256", 0xc066);
+ add("TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384", 0xc067);
+ add("TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256", 0xc068);
+ add("TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384", 0xc069);
+ add("TLS_PSK_WITH_ARIA_128_GCM_SHA256", 0xc06a);
+ add("TLS_PSK_WITH_ARIA_256_GCM_SHA384", 0xc06b);
+ add("TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256", 0xc06c);
+ add("TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384", 0xc06d);
+ add("TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256", 0xc06e);
+ add("TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384", 0xc06f);
+ add("TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256", 0xc070);
+ add("TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384", 0xc071);
+
+ // Unsupported cipher suites from RFC 6367
+ add("TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", 0xc072);
+ add("TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", 0xc073);
+ add("TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", 0xc074);
+ add("TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", 0xc075);
+ add("TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0xc076);
+ add("TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", 0xc077);
+ add("TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0xc078);
+ add("TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384", 0xc079);
+ add("TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc07a);
+ add("TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc07b);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc07c);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc07d);
+ add("TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc07e);
+ add("TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc07f);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256", 0xc080);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384", 0xc081);
+ add("TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256", 0xc082);
+ add("TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384", 0xc083);
+ add("TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256", 0xc084);
+ add("TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384", 0xc085);
+ add("TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc086);
+ add("TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc087);
+ add("TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc088);
+ add("TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc089);
+ add("TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc08a);
+ add("TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc08b);
+ add("TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc08c);
+ add("TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc08d);
+ add("TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256", 0xc08e);
+ add("TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384", 0xc08f);
+ add("TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256", 0xc090);
+ add("TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384", 0xc091);
+ add("TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256", 0xc092);
+ add("TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384", 0xc093);
+ add("TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0xc094);
+ add("TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0xc095);
+ add("TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0xc096);
+ add("TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0xc097);
+ add("TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0xc098);
+ add("TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0xc099);
+ add("TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0xc09a);
+ add("TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0xc09b);
+
+ // Unsupported cipher suites from RFC 6655
+ add("TLS_RSA_WITH_AES_128_CCM", 0xc09c);
+ add("TLS_RSA_WITH_AES_256_CCM", 0xc09d);
+ add("TLS_DHE_RSA_WITH_AES_128_CCM", 0xc09e);
+ add("TLS_DHE_RSA_WITH_AES_256_CCM", 0xc09f);
+ add("TLS_RSA_WITH_AES_128_CCM_8", 0xc0A0);
+ add("TLS_RSA_WITH_AES_256_CCM_8", 0xc0A1);
+ add("TLS_DHE_RSA_WITH_AES_128_CCM_8", 0xc0A2);
+ add("TLS_DHE_RSA_WITH_AES_256_CCM_8", 0xc0A3);
+ add("TLS_PSK_WITH_AES_128_CCM", 0xc0A4);
+ add("TLS_PSK_WITH_AES_256_CCM", 0xc0A5);
+ add("TLS_DHE_PSK_WITH_AES_128_CCM", 0xc0A6);
+ add("TLS_DHE_PSK_WITH_AES_256_CCM", 0xc0A7);
+ add("TLS_PSK_WITH_AES_128_CCM_8", 0xc0A8);
+ add("TLS_PSK_WITH_AES_256_CCM_8", 0xc0A9);
+ add("TLS_PSK_DHE_WITH_AES_128_CCM_8", 0xc0Aa);
+ add("TLS_PSK_DHE_WITH_AES_256_CCM_8", 0xc0Ab);
+
+ // Unsupported cipher suites from RFC 7251
+ add("TLS_ECDHE_ECDSA_WITH_AES_128_CCM", 0xc0Ac);
+ add("TLS_ECDHE_ECDSA_WITH_AES_256_CCM", 0xc0Ad);
+ add("TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", 0xc0Ae);
+ add("TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8", 0xc0Af);
}
// ciphersuite SSL_NULL_WITH_NULL_NULL
diff --git a/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java b/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java
index f622645..aef11c5 100644
--- a/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java
+++ b/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -141,6 +141,9 @@
private final static boolean allowUnsafeServerCertChange =
Debug.getBooleanProperty("jdk.tls.allowUnsafeServerCertChange", false);
+ // Whether an ALPN extension was sent in the ClientHello
+ private boolean alpnActive = false;
+
private List<SNIServerName> requestedServerNames =
Collections.<SNIServerName>emptyList();
@@ -689,6 +692,45 @@
}
}
+ // check the ALPN extension
+ ALPNExtension serverHelloALPN =
+ (ALPNExtension) mesg.extensions.get(ExtensionType.EXT_ALPN);
+
+ if (serverHelloALPN != null) {
+ // Check whether an ALPN extension was sent in ClientHello message
+ if (!alpnActive) {
+ fatalSE(Alerts.alert_unsupported_extension,
+ "Server sent " + ExtensionType.EXT_ALPN +
+ " extension when not requested by client");
+ }
+
+ List<String> protocols = serverHelloALPN.getPeerAPs();
+ // Only one application protocol name should be present
+ String p;
+ if ((protocols.size() == 1) &&
+ !((p = protocols.get(0)).isEmpty())) {
+ int i;
+ for (i = 0; i < localApl.length; i++) {
+ if (localApl[i].equals(p)) {
+ break;
+ }
+ }
+ if (i == localApl.length) {
+ fatalSE(Alerts.alert_handshake_failure,
+ "Server has selected an application protocol name " +
+ "which was not offered by the client: " + p);
+
+ }
+ applicationProtocol = p;
+ } else {
+ fatalSE(Alerts.alert_handshake_failure,
+ "Incorrect data in ServerHello " + ExtensionType.EXT_ALPN +
+ " message");
+ }
+ } else {
+ applicationProtocol = "";
+ }
+
if (resumingSession && session != null) {
setHandshakeSessionSE(session);
// Reserve the handshake state if this is a session-resumption
@@ -708,6 +750,7 @@
} else if ((type != ExtensionType.EXT_ELLIPTIC_CURVES)
&& (type != ExtensionType.EXT_EC_POINT_FORMATS)
&& (type != ExtensionType.EXT_SERVER_NAME)
+ && (type != ExtensionType.EXT_ALPN)
&& (type != ExtensionType.EXT_RENEGOTIATION_INFO)
&& (type != ExtensionType.EXT_EXTENDED_MASTER_SECRET)){
fatalSE(Alerts.alert_unsupported_extension,
@@ -1537,6 +1580,12 @@
}
}
+ // Add ALPN extension
+ if (localApl != null && localApl.length > 0) {
+ clientHelloMessage.addALPNExtension(localApl);
+ alpnActive = true;
+ }
+
// reset the client random cookie
clnt_random = clientHelloMessage.clnt_random;
diff --git a/jdk/src/share/classes/sun/security/ssl/ExtensionType.java b/jdk/src/share/classes/sun/security/ssl/ExtensionType.java
index 4c5dcf2..21888ab 100644
--- a/jdk/src/share/classes/sun/security/ssl/ExtensionType.java
+++ b/jdk/src/share/classes/sun/security/ssl/ExtensionType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,8 @@
return name;
}
- static List<ExtensionType> knownExtensions = new ArrayList<ExtensionType>(14);
+ static List<ExtensionType> knownExtensions =
+ new ArrayList<ExtensionType>(15);
static ExtensionType get(int id) {
for (ExtensionType ext : knownExtensions) {
@@ -96,6 +97,11 @@
final static ExtensionType EXT_SIGNATURE_ALGORITHMS =
e(0x000D, "signature_algorithms"); // IANA registry value: 13
+ // extension defined in RFC 7301 (ALPN)
+ static final ExtensionType EXT_ALPN =
+ e(0x0010, "application_layer_protocol_negotiation");
+ // IANA registry value: 16
+
// extensions defined in RFC 7627
static final ExtensionType EXT_EXTENDED_MASTER_SECRET =
e(0x0017, "extended_master_secret"); // IANA registry value: 23
diff --git a/jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java b/jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java
index f453b65..b7bef38 100644
--- a/jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java
+++ b/jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -280,6 +280,11 @@
extensions.add(new ExtendedMasterSecretExtension());
}
+ // add application_layer_protocol_negotiation extension
+ void addALPNExtension(String[] applicationProtocols) throws SSLException {
+ extensions.add(new ALPNExtension(applicationProtocols));
+ }
+
@Override
int messageType() { return ht_client_hello; }
diff --git a/jdk/src/share/classes/sun/security/ssl/Handshaker.java b/jdk/src/share/classes/sun/security/ssl/Handshaker.java
index beee9fd..df082ae 100644
--- a/jdk/src/share/classes/sun/security/ssl/Handshaker.java
+++ b/jdk/src/share/classes/sun/security/ssl/Handshaker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
import java.io.*;
import java.util.*;
+import java.util.function.BiFunction;
import java.security.*;
import javax.crypto.*;
@@ -109,6 +110,20 @@
List<SNIServerName> serverNames = Collections.<SNIServerName>emptyList();
Collection<SNIMatcher> sniMatchers = Collections.<SNIMatcher>emptyList();
+ // List of local ApplicationProtocols
+ String[] localApl = null;
+
+ // Negotiated ALPN value
+ String applicationProtocol = null;
+
+ // Application protocol callback function (for SSLEngine)
+ BiFunction<SSLEngine,List<String>,String>
+ appProtocolSelectorSSLEngine = null;
+
+ // Application protocol callback function (for SSLSocket)
+ BiFunction<SSLSocket,List<String>,String>
+ appProtocolSelectorSSLSocket = null;
+
private boolean isClient;
private boolean needCertVerify;
@@ -489,6 +504,36 @@
}
/**
+ * Sets the Application Protocol list.
+ */
+ void setApplicationProtocols(String[] apl) {
+ this.localApl = apl;
+ }
+
+ /**
+ * Gets the "negotiated" ALPN value.
+ */
+ String getHandshakeApplicationProtocol() {
+ return applicationProtocol;
+ }
+
+ /**
+ * Sets the Application Protocol selector function for SSLEngine.
+ */
+ void setApplicationProtocolSelectorSSLEngine(
+ BiFunction<SSLEngine,List<String>,String> selector) {
+ this.appProtocolSelectorSSLEngine = selector;
+ }
+
+ /**
+ * Sets the Application Protocol selector function for SSLSocket.
+ */
+ void setApplicationProtocolSelectorSSLSocket(
+ BiFunction<SSLSocket,List<String>,String> selector) {
+ this.appProtocolSelectorSSLSocket = selector;
+ }
+
+ /**
* Sets the cipher suites preference.
*/
void setUseCipherSuitesOrder(boolean on) {
diff --git a/jdk/src/share/classes/sun/security/ssl/HelloExtensions.java b/jdk/src/share/classes/sun/security/ssl/HelloExtensions.java
index 4fd03aa..00db199 100644
--- a/jdk/src/share/classes/sun/security/ssl/HelloExtensions.java
+++ b/jdk/src/share/classes/sun/security/ssl/HelloExtensions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,8 +33,8 @@
/**
* This file contains all the classes relevant to TLS Extensions for the
* ClientHello and ServerHello messages. The extension mechanism and
- * several extensions are defined in RFC 3546. Additional extensions are
- * defined in the ECC RFC 4492.
+ * several extensions are defined in RFC 6066. Additional extensions are
+ * defined in the ECC RFC 4492 and the ALPN extension is defined in RFC 7301.
*
* Currently, only the two ECC extensions are fully supported.
*
@@ -52,6 +52,7 @@
* . EllipticCurvesExtension: the ECC supported curves extension.
* . EllipticPointFormatsExtension: the ECC supported point formats
* (compressed/uncompressed) extension.
+ * . ALPNExtension: the application_layer_protocol_negotiation extension.
*
* @since 1.6
* @author Andreas Sterbenz
@@ -86,6 +87,8 @@
extension = new RenegotiationInfoExtension(s, extlen);
} else if (extType == ExtensionType.EXT_EXTENDED_MASTER_SECRET) {
extension = new ExtendedMasterSecretExtension(s, extlen);
+ } else if (extType == ExtensionType.EXT_ALPN) {
+ extension = new ALPNExtension(s, extlen);
} else {
extension = new UnknownExtension(s, extlen, extType);
}
diff --git a/jdk/src/share/classes/sun/security/ssl/RSASignature.java b/jdk/src/share/classes/sun/security/ssl/RSASignature.java
index 94a1e8e..23a57ee 100644
--- a/jdk/src/share/classes/sun/security/ssl/RSASignature.java
+++ b/jdk/src/share/classes/sun/security/ssl/RSASignature.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
package sun.security.ssl;
import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
/**
* Signature implementation for the SSL/TLS RSA Signature variant with both
@@ -199,9 +200,21 @@
}
@Override
+ protected void engineSetParameter(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ if (params != null) {
+ throw new InvalidAlgorithmParameterException("No parameters accepted");
+ }
+ }
+
+ @Override
protected Object engineGetParameter(String param)
throws InvalidParameterException {
throw new InvalidParameterException("Parameters not supported");
}
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ return null;
+ }
}
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
index d4ce0e1..b423c12 100644
--- a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
+++ b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
import java.nio.*;
import java.util.*;
import java.security.*;
+import java.util.function.BiFunction;
import javax.crypto.BadPaddingException;
@@ -259,6 +260,19 @@
Collection<SNIMatcher> sniMatchers =
Collections.<SNIMatcher>emptyList();
+ // Configured application protocol values
+ String[] applicationProtocols = new String[0];
+
+ // Negotiated application protocol value.
+ //
+ // The value under negotiation will be obtained from handshaker.
+ String applicationProtocol = null;
+
+
+ // Callback function that selects the application protocol value during
+ // the SSL/TLS handshake.
+ BiFunction<SSLEngine, List<String>, String> applicationProtocolSelector;
+
// Have we been told whether we're client or server?
private boolean serverModeSet = false;
private boolean roleIsServer;
@@ -486,6 +500,9 @@
}
handshaker.setEnabledCipherSuites(enabledCipherSuites);
handshaker.setEnableSessionCreation(enableSessionCreation);
+ handshaker.setApplicationProtocols(applicationProtocols);
+ handshaker.setApplicationProtocolSelectorSSLEngine(
+ applicationProtocolSelector);
}
/*
@@ -1027,6 +1044,9 @@
handshaker.isSecureRenegotiation();
clientVerifyData = handshaker.getClientVerifyData();
serverVerifyData = handshaker.getServerVerifyData();
+ // set connection ALPN value
+ applicationProtocol =
+ handshaker.getHandshakeApplicationProtocol();
sess = handshaker.getSession();
handshakeSession = null;
@@ -2091,6 +2111,7 @@
params.setSNIMatchers(sniMatchers);
params.setServerNames(serverNames);
params.setUseCipherSuitesOrder(preferLocalCipherSuites);
+ params.setApplicationProtocols(applicationProtocols);
return params;
}
@@ -2116,10 +2137,12 @@
if (matchers != null) {
sniMatchers = matchers;
}
+ applicationProtocols = params.getApplicationProtocols();
if ((handshaker != null) && !handshaker.started()) {
handshaker.setIdentificationProtocol(identificationProtocol);
handshaker.setAlgorithmConstraints(algorithmConstraints);
+ applicationProtocols = params.getApplicationProtocols();
if (roleIsServer) {
handshaker.setSNIMatchers(sniMatchers);
handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
@@ -2129,6 +2152,34 @@
}
}
+ @Override
+ public synchronized String getApplicationProtocol() {
+ return applicationProtocol;
+ }
+
+ @Override
+ public synchronized String getHandshakeApplicationProtocol() {
+ if ((handshaker != null) && handshaker.started()) {
+ return handshaker.getHandshakeApplicationProtocol();
+ }
+ return null;
+ }
+
+ @Override
+ public synchronized void setHandshakeApplicationProtocolSelector(
+ BiFunction<SSLEngine, List<String>, String> selector) {
+ applicationProtocolSelector = selector;
+ if ((handshaker != null) && !handshaker.activated()) {
+ handshaker.setApplicationProtocolSelectorSSLEngine(selector);
+ }
+ }
+
+ @Override
+ public synchronized BiFunction<SSLEngine, List<String>, String>
+ getHandshakeApplicationProtocolSelector() {
+ return this.applicationProtocolSelector;
+ }
+
/**
* Returns a printable representation of this end of the connection.
*/
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java
index 464bab2..74d2bd7 100644
--- a/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java
+++ b/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -92,6 +92,9 @@
Collection<SNIMatcher> sniMatchers =
Collections.<SNIMatcher>emptyList();
+ // Configured application protocol values
+ String[] applicationProtocols = new String[0];
+
/*
* Whether local cipher suites preference in server side should be
* honored during handshaking?
@@ -311,7 +314,7 @@
params.setAlgorithmConstraints(algorithmConstraints);
params.setSNIMatchers(sniMatchers);
params.setUseCipherSuitesOrder(preferLocalCipherSuites);
-
+ params.setApplicationProtocols(applicationProtocols);
return params;
}
@@ -331,6 +334,7 @@
if (matchers != null) {
sniMatchers = params.getSNIMatchers();
}
+ applicationProtocols = params.getApplicationProtocols();
}
/**
@@ -343,7 +347,7 @@
SSLSocketImpl s = new SSLSocketImpl(sslContext, useServerMode,
enabledCipherSuites, doClientAuth, enableSessionCreation,
enabledProtocols, identificationProtocol, algorithmConstraints,
- sniMatchers, preferLocalCipherSuites);
+ sniMatchers, preferLocalCipherSuites, applicationProtocols);
implAccept(s);
s.doneConnect();
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
index d6171c3..4c745e3 100644
--- a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.BiFunction;
import javax.crypto.BadPaddingException;
import javax.net.ssl.*;
@@ -220,6 +221,18 @@
// Is the sniMatchers set to empty with SSLParameters.setSNIMatchers()?
private boolean noSniMatcher = false;
+ // Configured application protocol values
+ String[] applicationProtocols = new String[0];
+
+ // Negotiated application protocol value.
+ //
+ // The value under negotiation will be obtained from handshaker.
+ String applicationProtocol = null;
+
+ // Callback function that selects the application protocol value during
+ // the SSL/TLS handshake.
+ BiFunction<SSLSocket, List<String>, String> applicationProtocolSelector;
+
/*
* READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
* IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
@@ -506,7 +519,8 @@
String identificationProtocol,
AlgorithmConstraints algorithmConstraints,
Collection<SNIMatcher> sniMatchers,
- boolean preferLocalCipherSuites) throws IOException {
+ boolean preferLocalCipherSuites,
+ String[] applicationProtocols) throws IOException {
super();
doClientAuth = clientAuth;
@@ -515,6 +529,7 @@
this.algorithmConstraints = algorithmConstraints;
this.sniMatchers = sniMatchers;
this.preferLocalCipherSuites = preferLocalCipherSuites;
+ this.applicationProtocols = applicationProtocols;
init(context, serverMode);
/*
@@ -1078,6 +1093,9 @@
handshaker.isSecureRenegotiation();
clientVerifyData = handshaker.getClientVerifyData();
serverVerifyData = handshaker.getServerVerifyData();
+ // set connection ALPN value
+ applicationProtocol =
+ handshaker.getHandshakeApplicationProtocol();
sess = handshaker.getSession();
handshakeSession = null;
@@ -1329,6 +1347,9 @@
}
handshaker.setEnabledCipherSuites(enabledCipherSuites);
handshaker.setEnableSessionCreation(enableSessionCreation);
+ handshaker.setApplicationProtocols(applicationProtocols);
+ handshaker.setApplicationProtocolSelectorSSLSocket(
+ applicationProtocolSelector);
}
/**
@@ -2617,6 +2638,7 @@
}
params.setUseCipherSuitesOrder(preferLocalCipherSuites);
+ params.setApplicationProtocols(applicationProtocols);
return params;
}
@@ -2645,9 +2667,12 @@
sniMatchers = matchers;
}
+ applicationProtocols = params.getApplicationProtocols();
+
if ((handshaker != null) && !handshaker.started()) {
handshaker.setIdentificationProtocol(identificationProtocol);
handshaker.setAlgorithmConstraints(algorithmConstraints);
+ handshaker.setApplicationProtocols(applicationProtocols);
if (roleIsServer) {
handshaker.setSNIMatchers(sniMatchers);
handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
@@ -2657,6 +2682,34 @@
}
}
+ @Override
+ public synchronized String getApplicationProtocol() {
+ return applicationProtocol;
+ }
+
+ @Override
+ public synchronized String getHandshakeApplicationProtocol() {
+ if ((handshaker != null) && handshaker.started()) {
+ return handshaker.getHandshakeApplicationProtocol();
+ }
+ return null;
+ }
+
+ @Override
+ public synchronized void setHandshakeApplicationProtocolSelector(
+ BiFunction<SSLSocket, List<String>, String> selector) {
+ applicationProtocolSelector = selector;
+ if ((handshaker != null) && !handshaker.activated()) {
+ handshaker.setApplicationProtocolSelectorSSLSocket(selector);
+ }
+ }
+
+ @Override
+ public synchronized BiFunction<SSLSocket, List<String>, String>
+ getHandshakeApplicationProtocolSelector() {
+ return this.applicationProtocolSelector;
+ }
+
//
// We allocate a separate thread to deliver handshake completion
// events. This ensures that the notifications don't block the
diff --git a/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java b/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java
index daa66cf..acc2a78 100644
--- a/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java
+++ b/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
import java.security.interfaces.*;
import java.security.spec.ECParameterSpec;
import java.math.BigInteger;
+import java.util.function.BiFunction;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
@@ -508,6 +509,44 @@
}
}
+ // check the ALPN extension
+ ALPNExtension clientHelloALPN = (ALPNExtension)
+ mesg.extensions.get(ExtensionType.EXT_ALPN);
+
+ // Use the application protocol callback when provided.
+ // Otherwise use the local list of application protocols.
+ boolean hasAPCallback =
+ ((engine != null && appProtocolSelectorSSLEngine != null) ||
+ (conn != null && appProtocolSelectorSSLSocket != null));
+
+ if (!hasAPCallback) {
+ if ((clientHelloALPN != null) && (localApl.length > 0)) {
+
+ // Intersect the requested and the locally supported,
+ // and save for later.
+ String negotiatedValue = null;
+ List<String> protocols = clientHelloALPN.getPeerAPs();
+
+ // Use server preference order
+ for (String ap : localApl) {
+ if (protocols.contains(ap)) {
+ negotiatedValue = ap;
+ break;
+ }
+ }
+
+ if (negotiatedValue == null) {
+ fatalSE(Alerts.alert_no_application_protocol,
+ new SSLHandshakeException(
+ "No matching ALPN values"));
+ }
+ applicationProtocol = negotiatedValue;
+
+ } else {
+ applicationProtocol = "";
+ }
+ } // Otherwise, applicationProtocol will be set by the callback.
+
/*
* Always make sure this entire record has been digested before we
* start emitting output, to ensure correct digesting order.
@@ -858,6 +897,39 @@
m1.extensions.add(new ExtendedMasterSecretExtension());
}
+ // Prepare the ALPN response
+ if (clientHelloALPN != null) {
+ List<String> peerAPs = clientHelloALPN.getPeerAPs();
+
+ // check for a callback function
+ if (hasAPCallback) {
+ if (conn != null) {
+ applicationProtocol =
+ appProtocolSelectorSSLSocket.apply(conn, peerAPs);
+ } else {
+ applicationProtocol =
+ appProtocolSelectorSSLEngine.apply(engine, peerAPs);
+ }
+ }
+
+ // check for no-match and that the selected name was also proposed
+ // by the TLS peer
+ if (applicationProtocol == null ||
+ (!applicationProtocol.isEmpty() &&
+ !peerAPs.contains(applicationProtocol))) {
+
+ fatalSE(Alerts.alert_no_application_protocol,
+ new SSLHandshakeException(
+ "No matching ALPN values"));
+
+ } else if (!applicationProtocol.isEmpty()) {
+ m1.extensions.add(new ALPNExtension(applicationProtocol));
+ }
+ } else {
+ // Nothing was negotiated, returned at end of the handshake
+ applicationProtocol = "";
+ }
+
if (debug != null && Debug.isOn("handshake")) {
m1.print(System.out);
System.out.println("Cipher suite: " + session.getSuite());
diff --git a/jdk/src/share/classes/sun/security/ssl/SunJSSE.java b/jdk/src/share/classes/sun/security/ssl/SunJSSE.java
index 63119dd..11e2fcc 100644
--- a/jdk/src/share/classes/sun/security/ssl/SunJSSE.java
+++ b/jdk/src/share/classes/sun/security/ssl/SunJSSE.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -160,12 +160,12 @@
private void doRegister(boolean isfips) {
if (isfips == false) {
put("KeyFactory.RSA",
- "sun.security.rsa.RSAKeyFactory");
+ "sun.security.rsa.RSAKeyFactory$Legacy");
put("Alg.Alias.KeyFactory.1.2.840.113549.1.1", "RSA");
put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1", "RSA");
put("KeyPairGenerator.RSA",
- "sun.security.rsa.RSAKeyPairGenerator");
+ "sun.security.rsa.RSAKeyPairGenerator$Legacy");
put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1", "RSA");
put("Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1", "RSA");
diff --git a/jdk/src/share/classes/sun/security/timestamp/HttpTimestamper.java b/jdk/src/share/classes/sun/security/timestamp/HttpTimestamper.java
index 50cef6e..9b646f7 100644
--- a/jdk/src/share/classes/sun/security/timestamp/HttpTimestamper.java
+++ b/jdk/src/share/classes/sun/security/timestamp/HttpTimestamper.java
@@ -27,6 +27,7 @@
import java.io.BufferedInputStream;
import java.io.DataOutputStream;
+import java.io.EOFException;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
@@ -147,8 +148,11 @@
}
verifyMimeType(connection.getContentType());
- int contentLength = connection.getContentLength();
- replyBuffer = IOUtils.readFully(input, contentLength, false);
+ int clen = connection.getContentLength();
+ replyBuffer = IOUtils.readAllBytes(input);
+ if (clen != -1 && replyBuffer.length != clen)
+ throw new EOFException("Expected:" + clen +
+ ", read:" + replyBuffer.length);
if (debug != null) {
debug.println("received timestamp response (length=" +
diff --git a/jdk/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java b/jdk/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java
index 0b97cee..fa05a0d 100644
--- a/jdk/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java
+++ b/jdk/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java
@@ -144,7 +144,7 @@
/**
* Examine the certificate for a Subject Information Access extension
- * (<a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280</a>).
+ * (<a href="http://tools.ietf.org/html/rfc5280">RFC 5280</a>).
* The extension's {@code accessMethod} field should contain the object
* identifier defined for timestamping: 1.3.6.1.5.5.7.48.3 and its
* {@code accessLocation} field should contain an HTTP or HTTPS URL.
diff --git a/jdk/src/share/classes/sun/security/tools/keytool/CertAndKeyGen.java b/jdk/src/share/classes/sun/security/tools/keytool/CertAndKeyGen.java
index a8a748c..a218f63 100644
--- a/jdk/src/share/classes/sun/security/tools/keytool/CertAndKeyGen.java
+++ b/jdk/src/share/classes/sun/security/tools/keytool/CertAndKeyGen.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,12 +30,12 @@
import java.security.cert.CertificateException;
import java.security.cert.CertificateEncodingException;
import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
import java.util.Date;
import sun.security.pkcs10.PKCS10;
import sun.security.x509.*;
-
/**
* Generate a pair of keys, and provide access to them. This class is
* provided primarily for ease of use.
@@ -250,12 +250,14 @@
new CertificateValidity(firstDate,lastDate);
X509CertInfo info = new X509CertInfo();
+ AlgorithmParameterSpec params = AlgorithmId
+ .getDefaultAlgorithmParameterSpec(sigAlg, privateKey);
// Add all mandatory attributes
info.set(X509CertInfo.VERSION,
new CertificateVersion(CertificateVersion.V3));
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(
new java.util.Random().nextInt() & 0x7fffffff));
- AlgorithmId algID = AlgorithmId.get(sigAlg);
+ AlgorithmId algID = AlgorithmId.getWithParameterSpec(sigAlg, params);
info.set(X509CertInfo.ALGORITHM_ID,
new CertificateAlgorithmId(algID));
info.set(X509CertInfo.SUBJECT, myname);
@@ -265,13 +267,19 @@
if (ext != null) info.set(X509CertInfo.EXTENSIONS, ext);
cert = new X509CertImpl(info);
- cert.sign(privateKey, this.sigAlg);
+ cert.sign(privateKey,
+ params,
+ sigAlg,
+ null);
return (X509Certificate)cert;
} catch (IOException e) {
throw new CertificateEncodingException("getSelfCert: " +
e.getMessage());
+ } catch (InvalidAlgorithmParameterException e2) {
+ throw new SignatureException(
+ "Unsupported PSSParameterSpec: " + e2.getMessage());
}
}
@@ -297,6 +305,7 @@
* @exception InvalidKeyException on key handling errors.
* @exception SignatureException on signature handling errors.
*/
+ // This method is not used inside JDK. Will not update it.
public PKCS10 getCertRequest (X500Name myname)
throws InvalidKeyException, SignatureException
{
diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Main.java b/jdk/src/share/classes/sun/security/tools/keytool/Main.java
index 005a540..955c5b6f 100644
--- a/jdk/src/share/classes/sun/security/tools/keytool/Main.java
+++ b/jdk/src/share/classes/sun/security/tools/keytool/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,6 +50,7 @@
import java.security.cert.CRL;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
+import java.security.spec.AlgorithmParameterSpec;
import java.text.Collator;
import java.text.MessageFormat;
import java.util.*;
@@ -77,6 +78,7 @@
import sun.security.provider.certpath.CertStoreHelper;
import sun.security.util.Password;
import sun.security.util.SecurityProviderConstants;
+import sun.security.util.SignatureUtil;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
@@ -1293,17 +1295,20 @@
sigAlgName = getCompatibleSigAlgName(privateKey.getAlgorithm());
}
Signature signature = Signature.getInstance(sigAlgName);
- signature.initSign(privateKey);
+ AlgorithmParameterSpec params = AlgorithmId
+ .getDefaultAlgorithmParameterSpec(sigAlgName, privateKey);
+
+ SignatureUtil.initSignWithParam(signature, privateKey, params, null);
X509CertInfo info = new X509CertInfo();
+ AlgorithmId algID = AlgorithmId.getWithParameterSpec(sigAlgName, params);
info.set(X509CertInfo.VALIDITY, interval);
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(
new java.util.Random().nextInt() & 0x7fffffff));
info.set(X509CertInfo.VERSION,
new CertificateVersion(CertificateVersion.V3));
info.set(X509CertInfo.ALGORITHM_ID,
- new CertificateAlgorithmId(
- AlgorithmId.get(sigAlgName)));
+ new CertificateAlgorithmId(algID));
info.set(X509CertInfo.ISSUER, issuer);
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
@@ -1347,7 +1352,7 @@
signerCert.getPublicKey());
info.set(X509CertInfo.EXTENSIONS, ext);
X509CertImpl cert = new X509CertImpl(info);
- cert.sign(privateKey, sigAlgName);
+ cert.sign(privateKey, params, sigAlgName, null);
dumpCert(cert, out);
for (Certificate ca: keyStore.getCertificateChain(alias)) {
if (ca instanceof X509Certificate) {
@@ -1449,7 +1454,10 @@
}
Signature signature = Signature.getInstance(sigAlgName);
- signature.initSign(privKey);
+ AlgorithmParameterSpec params = AlgorithmId
+ .getDefaultAlgorithmParameterSpec(sigAlgName, privKey);
+ SignatureUtil.initSignWithParam(signature, privKey, params, null);
+
X500Name subject = dname == null?
new X500Name(((X509Certificate)cert).getSubjectDN().toString()):
new X500Name(dname);
@@ -1705,6 +1713,8 @@
keysize = SecurityProviderConstants.DEF_EC_KEY_SIZE;
} else if ("RSA".equalsIgnoreCase(keyAlgName)) {
keysize = SecurityProviderConstants.DEF_RSA_KEY_SIZE;
+ } else if ("RSASSA-PSS".equalsIgnoreCase(keyAlgName)) {
+ keysize = SecurityProviderConstants.DEF_RSASSA_PSS_KEY_SIZE;
} else if ("DSA".equalsIgnoreCase(keyAlgName)) {
keysize = SecurityProviderConstants.DEF_DSA_KEY_SIZE;
}
@@ -2236,9 +2246,9 @@
out.println(form.format(source));
out.println();
- for (Enumeration<String> e = keyStore.aliases();
- e.hasMoreElements(); ) {
- String alias = e.nextElement();
+ List<String> aliases = Collections.list(keyStore.aliases());
+ aliases.sort(String::compareTo);
+ for (String alias : aliases) {
doPrintEntry("<" + alias + ">", alias, out);
if (verbose || rfc) {
out.println(rb.getString("NEWLINE"));
@@ -2742,7 +2752,9 @@
// other solution: We first sign the cert, then retrieve the
// outer sigalg and use it to set the inner sigalg
X509CertImpl newCert = new X509CertImpl(certInfo);
- newCert.sign(privKey, sigAlgName);
+ AlgorithmParameterSpec params = AlgorithmId
+ .getDefaultAlgorithmParameterSpec(sigAlgName, privKey);
+ newCert.sign(privKey, params, sigAlgName, null);
AlgorithmId sigAlgid = (AlgorithmId)newCert.get(X509CertImpl.SIG_ALG);
certInfo.set(CertificateAlgorithmId.NAME + "." +
CertificateAlgorithmId.ALGORITHM, sigAlgid);
@@ -2759,7 +2771,7 @@
certInfo.set(X509CertInfo.EXTENSIONS, ext);
// Sign the new certificate
newCert = new X509CertImpl(certInfo);
- newCert.sign(privKey, sigAlgName);
+ newCert.sign(privKey, params, sigAlgName, null);
// Store the new certificate as a single-element certificate chain
keyStore.setKeyEntry(alias, privKey,
@@ -3331,6 +3343,11 @@
{
Key key = null;
+ if (KeyStoreUtil.isWindowsKeyStore(storetype)) {
+ key = keyStore.getKey(alias, null);
+ return Pair.of(key, null);
+ }
+
if (keyStore.containsAlias(alias) == false) {
MessageFormat form = new MessageFormat
(rb.getString("Alias.alias.does.not.exist"));
diff --git a/jdk/src/share/classes/sun/security/util/DerInputBuffer.java b/jdk/src/share/classes/sun/security/util/DerInputBuffer.java
index b09b7b3..54eade3 100644
--- a/jdk/src/share/classes/sun/security/util/DerInputBuffer.java
+++ b/jdk/src/share/classes/sun/security/util/DerInputBuffer.java
@@ -300,7 +300,7 @@
* YYMMDDhhmmss-hhmm
* UTC Time is broken in storing only two digits of year.
* If YY < 50, we assume 20YY;
- * if YY >= 50, we assume 19YY, as per RFC 3280.
+ * if YY >= 50, we assume 19YY, as per RFC 5280.
*
* Generalized time has a four-digit year and allows any
* precision specified in ISO 8601. However, for our purposes,
diff --git a/jdk/src/share/classes/sun/security/util/DerOutputStream.java b/jdk/src/share/classes/sun/security/util/DerOutputStream.java
index c517df8..05a7b63 100644
--- a/jdk/src/share/classes/sun/security/util/DerOutputStream.java
+++ b/jdk/src/share/classes/sun/security/util/DerOutputStream.java
@@ -461,7 +461,7 @@
* Marshals a DER UTC time/date value.
*
* <P>YYMMDDhhmmss{Z|+hhmm|-hhmm} ... emits only using Zulu time
- * and with seconds (even if seconds=0) as per RFC 3280.
+ * and with seconds (even if seconds=0) as per RFC 5280.
*/
public void putUTCTime(Date d) throws IOException {
putTime(d, DerValue.tag_UtcTime);
@@ -471,7 +471,7 @@
* Marshals a DER Generalized Time/date value.
*
* <P>YYYYMMDDhhmmss{Z|+hhmm|-hhmm} ... emits only using Zulu time
- * and with seconds (even if seconds=0) as per RFC 3280.
+ * and with seconds (even if seconds=0) as per RFC 5280.
*/
public void putGeneralizedTime(Date d) throws IOException {
putTime(d, DerValue.tag_GeneralizedTime);
diff --git a/jdk/src/share/classes/sun/security/util/DerValue.java b/jdk/src/share/classes/sun/security/util/DerValue.java
index 46dcbd3..9372537 100644
--- a/jdk/src/share/classes/sun/security/util/DerValue.java
+++ b/jdk/src/share/classes/sun/security/util/DerValue.java
@@ -45,8 +45,8 @@
* (such as PKCS #10 certificate requests, and some kinds of PKCS #7 data).
*
* A note with respect to T61/Teletex strings: From RFC 1617, section 4.1.3
- * and RFC 3280, section 4.1.2.4., we assume that this kind of string will
- * contain ISO-8859-1 characters only.
+ * and RFC 5280, section 8, we assume that this kind of string will contain
+ * ISO-8859-1 characters only.
*
*
* @author David Brownell
@@ -409,7 +409,7 @@
if (fullyBuffered && in.available() != length)
throw new IOException("extra data given to DerValue constructor");
- byte[] bytes = IOUtils.readFully(in, length, true);
+ byte[] bytes = IOUtils.readExactlyNBytes(in, length);
buffer = new DerInputBuffer(bytes, allowBER);
return new DerInputStream(buffer);
diff --git a/jdk/src/share/classes/sun/security/util/ECUtil.java b/jdk/src/share/classes/sun/security/util/ECUtil.java
index fac1034..fafb81c 100644
--- a/jdk/src/share/classes/sun/security/util/ECUtil.java
+++ b/jdk/src/share/classes/sun/security/util/ECUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,7 @@
import sun.security.x509.X509Key;
-public class ECUtil {
+public final class ECUtil {
// Used by SunPKCS11 and SunJSSE.
public static ECPoint decodePoint(byte[] data, EllipticCurve curve)
@@ -186,5 +186,78 @@
return nameSpec.getName();
}
+ public static boolean equals(ECParameterSpec spec1, ECParameterSpec spec2) {
+ if (spec1 == spec2) {
+ return true;
+ }
+
+ if (spec1 == null || spec2 == null) {
+ return false;
+ }
+ return (spec1.getCofactor() == spec2.getCofactor() &&
+ spec1.getOrder().equals(spec2.getOrder()) &&
+ spec1.getCurve().equals(spec2.getCurve()) &&
+ spec1.getGenerator().equals(spec2.getGenerator()));
+ }
+
+ // Convert the concatenation R and S in into their DER encoding
+ public static byte[] encodeSignature(byte[] signature) throws SignatureException {
+
+ try {
+
+ int n = signature.length >> 1;
+ byte[] bytes = new byte[n];
+ System.arraycopy(signature, 0, bytes, 0, n);
+ BigInteger r = new BigInteger(1, bytes);
+ System.arraycopy(signature, n, bytes, 0, n);
+ BigInteger s = new BigInteger(1, bytes);
+
+ DerOutputStream out = new DerOutputStream(signature.length + 10);
+ out.putInteger(r);
+ out.putInteger(s);
+ DerValue result =
+ new DerValue(DerValue.tag_Sequence, out.toByteArray());
+
+ return result.toByteArray();
+
+ } catch (Exception e) {
+ throw new SignatureException("Could not encode signature", e);
+ }
+ }
+
+ // Convert the DER encoding of R and S into a concatenation of R and S
+ public static byte[] decodeSignature(byte[] sig) throws SignatureException {
+
+ try {
+ // Enforce strict DER checking for signatures
+ DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
+ DerValue[] values = in.getSequence(2);
+
+ // check number of components in the read sequence
+ // and trailing data
+ if ((values.length != 2) || (in.available() != 0)) {
+ throw new IOException("Invalid encoding for signature");
+ }
+
+ BigInteger r = values[0].getPositiveBigInteger();
+ BigInteger s = values[1].getPositiveBigInteger();
+
+ // trim leading zeroes
+ byte[] rBytes = trimZeroes(r.toByteArray());
+ byte[] sBytes = trimZeroes(s.toByteArray());
+ int k = Math.max(rBytes.length, sBytes.length);
+ // r and s each occupy half the array
+ byte[] result = new byte[k << 1];
+ System.arraycopy(rBytes, 0, result, k - rBytes.length,
+ rBytes.length);
+ System.arraycopy(sBytes, 0, result, result.length - sBytes.length,
+ sBytes.length);
+ return result;
+
+ } catch (Exception e) {
+ throw new SignatureException("Invalid encoding for signature", e);
+ }
+ }
+
private ECUtil() {}
}
diff --git a/jdk/src/share/classes/sun/security/util/SecurityProviderConstants.java b/jdk/src/share/classes/sun/security/util/SecurityProviderConstants.java
index 2631558..b9d0d26 100644
--- a/jdk/src/share/classes/sun/security/util/SecurityProviderConstants.java
+++ b/jdk/src/share/classes/sun/security/util/SecurityProviderConstants.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -56,6 +56,7 @@
public static final int DEF_DSA_KEY_SIZE;
public static final int DEF_RSA_KEY_SIZE;
+ public static final int DEF_RSASSA_PSS_KEY_SIZE;
public static final int DEF_DH_KEY_SIZE;
public static final int DEF_EC_KEY_SIZE;
@@ -66,6 +67,7 @@
(KEY_LENGTH_PROP);
int dsaKeySize = 2048;
int rsaKeySize = 2048;
+ int rsaSsaPssKeySize = rsaKeySize; // default to same value as RSA
int dhKeySize = 2048;
int ecKeySize = 256;
@@ -98,6 +100,8 @@
dsaKeySize = value;
} else if (algoName.equals("RSA")) {
rsaKeySize = value;
+ } else if (algoName.equals("RSASSA-PSS")) {
+ rsaSsaPssKeySize = value;
} else if (algoName.equals("DH")) {
dhKeySize = value;
} else if (algoName.equals("EC")) {
@@ -125,6 +129,7 @@
}
DEF_DSA_KEY_SIZE = dsaKeySize;
DEF_RSA_KEY_SIZE = rsaKeySize;
+ DEF_RSASSA_PSS_KEY_SIZE = rsaSsaPssKeySize;
DEF_DH_KEY_SIZE = dhKeySize;
DEF_EC_KEY_SIZE = ecKeySize;
}
diff --git a/jdk/src/share/classes/sun/security/util/SignatureUtil.java b/jdk/src/share/classes/sun/security/util/SignatureUtil.java
new file mode 100644
index 0000000..9516a62
--- /dev/null
+++ b/jdk/src/share/classes/sun/security/util/SignatureUtil.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.io.IOException;
+import java.security.*;
+import java.security.spec.*;
+import java.util.Locale;
+import sun.security.rsa.RSAUtil;
+import sun.misc.SharedSecrets;
+
+/**
+ * Utility class for Signature related operations. Currently used by various
+ * internal PKI classes such as sun.security.x509.X509CertImpl,
+ * sun.security.pkcs.SignerInfo, for setting signature parameters.
+ *
+ * @since 8
+ */
+public class SignatureUtil {
+
+ private static String checkName(String algName) throws ProviderException {
+ if (algName.indexOf(".") == -1) {
+ return algName;
+ }
+ // convert oid to String
+ try {
+ return Signature.getInstance(algName).getAlgorithm();
+ } catch (Exception e) {
+ throw new ProviderException("Error mapping algorithm name", e);
+ }
+ }
+
+ // Utility method of creating an AlgorithmParameters object with
+ // the specified algorithm name and encoding
+ private static AlgorithmParameters createAlgorithmParameters(String algName,
+ byte[] paramBytes) throws ProviderException {
+
+ try {
+ algName = checkName(algName);
+ AlgorithmParameters result =
+ AlgorithmParameters.getInstance(algName);
+ result.init(paramBytes);
+ return result;
+ } catch (NoSuchAlgorithmException | IOException e) {
+ throw new ProviderException(e);
+ }
+ }
+
+ // Utility method for converting the specified AlgorithmParameters object
+ // into an AlgorithmParameterSpec object.
+ public static AlgorithmParameterSpec getParamSpec(String sigName,
+ AlgorithmParameters params)
+ throws ProviderException {
+
+ sigName = checkName(sigName).toUpperCase(Locale.ENGLISH);
+ AlgorithmParameterSpec paramSpec = null;
+ if (params != null) {
+ // AlgorithmParameters.getAlgorithm() may returns oid if it's
+ // created during DER decoding. Convert to use the standard name
+ // before passing it to RSAUtil
+ if (params.getAlgorithm().indexOf(".") != -1) {
+ try {
+ params = createAlgorithmParameters(sigName,
+ params.getEncoded());
+ } catch (IOException e) {
+ throw new ProviderException(e);
+ }
+ }
+
+ if (sigName.indexOf("RSA") != -1) {
+ paramSpec = RSAUtil.getParamSpec(params);
+ } else if (sigName.indexOf("ECDSA") != -1) {
+ try {
+ paramSpec = params.getParameterSpec(ECParameterSpec.class);
+ } catch (Exception e) {
+ throw new ProviderException("Error handling EC parameters", e);
+ }
+ } else {
+ throw new ProviderException
+ ("Unrecognized algorithm for signature parameters " +
+ sigName);
+ }
+ }
+ return paramSpec;
+ }
+
+ // Utility method for converting the specified parameter bytes into an
+ // AlgorithmParameterSpec object.
+ public static AlgorithmParameterSpec getParamSpec(String sigName,
+ byte[] paramBytes)
+ throws ProviderException {
+ sigName = checkName(sigName).toUpperCase(Locale.ENGLISH);
+ AlgorithmParameterSpec paramSpec = null;
+
+ if (paramBytes != null) {
+ if (sigName.indexOf("RSA") != -1) {
+ AlgorithmParameters params =
+ createAlgorithmParameters(sigName, paramBytes);
+ paramSpec = RSAUtil.getParamSpec(params);
+ } else if (sigName.indexOf("ECDSA") != -1) {
+ try {
+ Provider p = Signature.getInstance(sigName).getProvider();
+ paramSpec = ECUtil.getECParameterSpec(p, paramBytes);
+ } catch (Exception e) {
+ throw new ProviderException("Error handling EC parameters", e);
+ }
+ // ECUtil discards exception and returns null, so we need to check
+ // the returned value
+ if (paramSpec == null) {
+ throw new ProviderException("Error handling EC parameters");
+ }
+ } else {
+ throw new ProviderException
+ ("Unrecognized algorithm for signature parameters " +
+ sigName);
+ }
+ }
+ return paramSpec;
+ }
+
+ // Utility method for initializing the specified Signature object
+ // for verification with the specified key and params (may be null)
+ public static void initVerifyWithParam(Signature s, PublicKey key,
+ AlgorithmParameterSpec params)
+ throws ProviderException, InvalidAlgorithmParameterException,
+ InvalidKeyException {
+ SharedSecrets.getJavaSecuritySignatureAccess().initVerify(s, key, params);
+ }
+
+ // Utility method for initializing the specified Signature object
+ // for verification with the specified Certificate and params (may be null)
+ public static void initVerifyWithParam(Signature s,
+ java.security.cert.Certificate cert,
+ AlgorithmParameterSpec params)
+ throws ProviderException, InvalidAlgorithmParameterException,
+ InvalidKeyException {
+ SharedSecrets.getJavaSecuritySignatureAccess().initVerify(s, cert, params);
+ }
+
+ // Utility method for initializing the specified Signature object
+ // for signing with the specified key and params (may be null)
+ public static void initSignWithParam(Signature s, PrivateKey key,
+ AlgorithmParameterSpec params, SecureRandom sr)
+ throws ProviderException, InvalidAlgorithmParameterException,
+ InvalidKeyException {
+ SharedSecrets.getJavaSecuritySignatureAccess().initSign(s, key, params, sr);
+ }
+}
diff --git a/jdk/src/share/classes/sun/security/validator/PKIXValidator.java b/jdk/src/share/classes/sun/security/validator/PKIXValidator.java
index 9be5026..d6d973c 100644
--- a/jdk/src/share/classes/sun/security/validator/PKIXValidator.java
+++ b/jdk/src/share/classes/sun/security/validator/PKIXValidator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, 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
@@ -32,6 +32,7 @@
import javax.security.auth.x500.X500Principal;
import sun.security.action.GetBooleanAction;
+import sun.security.action.GetPropertyAction;
import sun.security.provider.certpath.AlgorithmChecker;
import sun.security.provider.certpath.PKIXExtendedParameters;
@@ -64,6 +65,18 @@
// enable use of the validator if possible
private final static boolean TRY_VALIDATOR = true;
+ /**
+ * System property that if set (or set to "true"), allows trust anchor
+ * certificates to be used if they do not have the proper CA extensions.
+ * Set to false if prop is not set, or set to any other value.
+ */
+ private static final boolean ALLOW_NON_CA_ANCHOR = allowNonCaAnchor();
+ private static boolean allowNonCaAnchor() {
+ String prop = GetPropertyAction
+ .privilegedGetProperty("jdk.security.allowNonCaAnchor");
+ return prop != null && (prop.isEmpty() || prop.equalsIgnoreCase("true"));
+ }
+
private final Set<X509Certificate> trustedCerts;
private final PKIXBuilderParameters parameterTemplate;
private int certPathLength = -1;
@@ -209,6 +222,7 @@
("null or zero-length certificate chain");
}
+
// Use PKIXExtendedParameters for timestamp and variant additions
PKIXBuilderParameters pkixParameters = null;
try {
@@ -234,29 +248,30 @@
for (int i = 0; i < chain.length; i++) {
X509Certificate cert = chain[i];
X500Principal dn = cert.getSubjectX500Principal();
- if (i != 0 &&
- !dn.equals(prevIssuer)) {
- // chain is not ordered correctly, call builder instead
- return doBuild(chain, otherCerts, pkixParameters);
- }
- // Check if chain[i] is already trusted. It may be inside
- // trustedCerts, or has the same dn and public key as a cert
- // inside trustedCerts. The latter happens when a CA has
- // updated its cert with a stronger signature algorithm in JRE
- // but the weak one is still in circulation.
-
- if (trustedCerts.contains(cert) || // trusted cert
- (trustedSubjects.containsKey(dn) && // replacing ...
- trustedSubjects.get(dn).contains( // ... weak cert
- cert.getPublicKey()))) {
- if (i == 0) {
+ if (i == 0) {
+ if (trustedCerts.contains(cert)) {
return new X509Certificate[] {chain[0]};
}
- // Remove and call validator on partial chain [0 .. i-1]
- X509Certificate[] newChain = new X509Certificate[i];
- System.arraycopy(chain, 0, newChain, 0, i);
- return doValidate(newChain, pkixParameters);
+ } else {
+ if (!dn.equals(prevIssuer)) {
+ // chain is not ordered correctly, call builder instead
+ return doBuild(chain, otherCerts, pkixParameters);
+ }
+ // Check if chain[i] is already trusted. It may be inside
+ // trustedCerts, or has the same dn and public key as a cert
+ // inside trustedCerts. The latter happens when a CA has
+ // updated its cert with a stronger signature algorithm in JRE
+ // but the weak one is still in circulation.
+ if (trustedCerts.contains(cert) || // trusted cert
+ (trustedSubjects.containsKey(dn) && // replacing ...
+ trustedSubjects.get(dn).contains( // ... weak cert
+ cert.getPublicKey()))) {
+ // Remove and call validator on partial chain [0 .. i-1]
+ X509Certificate[] newChain = new X509Certificate[i];
+ System.arraycopy(chain, 0, newChain, 0, i);
+ return doValidate(newChain, pkixParameters);
+ }
}
prevIssuer = cert.getIssuerX500Principal();
}
@@ -320,15 +335,18 @@
private static X509Certificate[] toArray(CertPath path, TrustAnchor anchor)
throws CertificateException {
- List<? extends java.security.cert.Certificate> list =
- path.getCertificates();
- X509Certificate[] chain = new X509Certificate[list.size() + 1];
- list.toArray(chain);
X509Certificate trustedCert = anchor.getTrustedCert();
if (trustedCert == null) {
throw new ValidatorException
("TrustAnchor must be specified as certificate");
}
+
+ verifyTrustAnchor(trustedCert);
+
+ List<? extends java.security.cert.Certificate> list =
+ path.getCertificates();
+ X509Certificate[] chain = new X509Certificate[list.size() + 1];
+ list.toArray(chain);
chain[chain.length - 1] = trustedCert;
return chain;
}
@@ -363,6 +381,41 @@
}
}
+ /**
+ * Verify that a trust anchor certificate is a CA certificate.
+ */
+ private static void verifyTrustAnchor(X509Certificate trustedCert)
+ throws ValidatorException {
+
+ // skip check if jdk.security.allowNonCAAnchor system property is set
+ if (ALLOW_NON_CA_ANCHOR) {
+ return;
+ }
+
+ // allow v1 trust anchor certificates
+ if (trustedCert.getVersion() < 3) {
+ return;
+ }
+
+ // check that the BasicConstraints cA field is not set to false
+ if (trustedCert.getBasicConstraints() == -1) {
+ throw new ValidatorException
+ ("TrustAnchor with subject \"" +
+ trustedCert.getSubjectX500Principal() +
+ "\" is not a CA certificate");
+ }
+
+ // check that the KeyUsage extension, if included, asserts the
+ // keyCertSign bit
+ boolean[] keyUsageBits = trustedCert.getKeyUsage();
+ if (keyUsageBits != null && !keyUsageBits[5]) {
+ throw new ValidatorException
+ ("TrustAnchor with subject \"" +
+ trustedCert.getSubjectX500Principal() +
+ "\" does not have keyCertSign bit set in KeyUsage extension");
+ }
+ }
+
private X509Certificate[] doBuild(X509Certificate[] chain,
Collection<X509Certificate> otherCerts,
PKIXBuilderParameters params) throws CertificateException {
diff --git a/jdk/src/share/classes/sun/security/x509/AVA.java b/jdk/src/share/classes/sun/security/x509/AVA.java
index b07e565..8665745 100644
--- a/jdk/src/share/classes/sun/security/x509/AVA.java
+++ b/jdk/src/share/classes/sun/security/x509/AVA.java
@@ -599,7 +599,7 @@
if (derval.tag != DerValue.tag_Sequence) {
throw new IOException("AVA not a sequence");
}
- oid = X500Name.intern(derval.data.getOID());
+ oid = derval.data.getOID();
value = derval.data.getDerValue();
if (derval.data.available() != 0) {
diff --git a/jdk/src/share/classes/sun/security/x509/AlgorithmId.java b/jdk/src/share/classes/sun/security/x509/AlgorithmId.java
index 44eda75..339b909 100644
--- a/jdk/src/share/classes/sun/security/x509/AlgorithmId.java
+++ b/jdk/src/share/classes/sun/security/x509/AlgorithmId.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,14 @@
package sun.security.x509;
import java.io.*;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
import java.util.*;
import java.security.*;
+import sun.security.rsa.PSSParameters;
import sun.security.util.*;
@@ -182,13 +187,20 @@
algid.equals((Object)SHA256_oid) ||
algid.equals((Object)SHA384_oid) ||
algid.equals((Object)SHA512_oid) ||
+ algid.equals((Object)SHA512_224_oid) ||
+ algid.equals((Object)SHA512_256_oid) ||
algid.equals((Object)DSA_oid) ||
algid.equals((Object)sha1WithDSA_oid)) {
; // no parameter part encoded
} else {
bytes.putNull();
}*/
- bytes.putNull();
+ if (algid.equals(RSASSA_PSS_oid)) {
+ // RFC 4055 3.3: when an RSASSA-PSS key does not require
+ // parameter validation, field is absent.
+ } else {
+ bytes.putNull();
+ }
} else {
bytes.putDerValue(params);
}
@@ -224,6 +236,9 @@
* return a name such as "MD5withRSA" for a signature algorithm on
* some systems. It also returns names like "OID.1.2.3.4", when
* no particular name for the algorithm is known.
+ *
+ * Note: for ecdsa-with-SHA2 plus hash algorithm (Ex: SHA-256), this method
+ * returns the "full" signature algorithm (Ex: SHA256withECDSA) directly.
*/
public String getName() {
String algName = nameTable.get(algid);
@@ -233,7 +248,7 @@
if ((params != null) && algid.equals((Object)specifiedWithECDSA_oid)) {
try {
AlgorithmId paramsId =
- AlgorithmId.parse(new DerValue(getEncodedParams()));
+ AlgorithmId.parse(new DerValue(params.toByteArray()));
String paramsName = paramsId.getName();
algName = makeSigAlg(paramsName, "EC");
} catch (IOException e) {
@@ -249,12 +264,18 @@
/**
* Returns the DER encoded parameter, which can then be
- * used to initialize java.security.AlgorithmParamters.
+ * used to initialize java.security.AlgorithmParameters.
+ *
+ * Note: for ecdsa-with-SHA2 plus hash algorithm (Ex: SHA-256), this method
+ * returns null because {@link #getName()} has already returned the "full"
+ * signature algorithm (Ex: SHA256withECDSA).
*
* @return DER encoded parameters, or null not present.
*/
public byte[] getEncodedParams() throws IOException {
- return (params == null) ? null : params.toByteArray();
+ return (params == null || algid.equals(specifiedWithECDSA_oid))
+ ? null
+ : params.toByteArray();
}
/**
@@ -483,11 +504,24 @@
name.equalsIgnoreCase("SHA224")) {
return AlgorithmId.SHA224_oid;
}
-
+ if (name.equalsIgnoreCase("SHA-512/224") ||
+ name.equalsIgnoreCase("SHA512/224")) {
+ return AlgorithmId.SHA512_224_oid;
+ }
+ if (name.equalsIgnoreCase("SHA-512/256") ||
+ name.equalsIgnoreCase("SHA512/256")) {
+ return AlgorithmId.SHA512_256_oid;
+ }
// Various public key algorithms
if (name.equalsIgnoreCase("RSA")) {
return AlgorithmId.RSAEncryption_oid;
}
+ if (name.equalsIgnoreCase("RSASSA-PSS")) {
+ return AlgorithmId.RSASSA_PSS_oid;
+ }
+ if (name.equalsIgnoreCase("RSAES-OAEP")) {
+ return AlgorithmId.RSAES_OAEP_oid;
+ }
if (name.equalsIgnoreCase("Diffie-Hellman")
|| name.equalsIgnoreCase("DH")) {
return AlgorithmId.DH_oid;
@@ -645,6 +679,12 @@
public static final ObjectIdentifier SHA512_oid =
ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 3});
+ public static final ObjectIdentifier SHA512_224_oid =
+ ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 5});
+
+ public static final ObjectIdentifier SHA512_256_oid =
+ ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 6});
+
/*
* COMMON PUBLIC KEY TYPES
*/
@@ -653,8 +693,6 @@
private static final int DSA_OIW_data[] = { 1, 3, 14, 3, 2, 12 };
private static final int DSA_PKIX_data[] = { 1, 2, 840, 10040, 4, 1 };
private static final int RSA_data[] = { 2, 5, 8, 1, 1 };
- private static final int RSAEncryption_data[] =
- { 1, 2, 840, 113549, 1, 1, 1 };
public static final ObjectIdentifier DH_oid;
public static final ObjectIdentifier DH_PKIX_oid;
@@ -663,7 +701,14 @@
public static final ObjectIdentifier EC_oid = oid(1, 2, 840, 10045, 2, 1);
public static final ObjectIdentifier ECDH_oid = oid(1, 3, 132, 1, 12);
public static final ObjectIdentifier RSA_oid;
- public static final ObjectIdentifier RSAEncryption_oid;
+ public static final ObjectIdentifier RSAEncryption_oid =
+ oid(1, 2, 840, 113549, 1, 1, 1);
+ public static final ObjectIdentifier RSAES_OAEP_oid =
+ oid(1, 2, 840, 113549, 1, 1, 7);
+ public static final ObjectIdentifier mgf1_oid =
+ oid(1, 2, 840, 113549, 1, 1, 8);
+ public static final ObjectIdentifier RSASSA_PSS_oid =
+ oid(1, 2, 840, 113549, 1, 1, 10);
/*
* COMMON SECRET KEY TYPES
@@ -690,6 +735,7 @@
{ 1, 2, 840, 113549, 1, 1, 12 };
private static final int sha512WithRSAEncryption_data[] =
{ 1, 2, 840, 113549, 1, 1, 13 };
+
private static final int shaWithDSA_OIW_data[] =
{ 1, 3, 14, 3, 2, 13 };
private static final int sha1WithDSA_OIW_data[] =
@@ -705,6 +751,11 @@
public static final ObjectIdentifier sha256WithRSAEncryption_oid;
public static final ObjectIdentifier sha384WithRSAEncryption_oid;
public static final ObjectIdentifier sha512WithRSAEncryption_oid;
+ public static final ObjectIdentifier sha512_224WithRSAEncryption_oid =
+ oid(1, 2, 840, 113549, 1, 1, 15);
+ public static final ObjectIdentifier sha512_256WithRSAEncryption_oid =
+ oid(1, 2, 840, 113549, 1, 1, 16);;
+
public static final ObjectIdentifier shaWithDSA_OIW_oid;
public static final ObjectIdentifier sha1WithDSA_OIW_oid;
public static final ObjectIdentifier sha1WithDSA_oid;
@@ -794,13 +845,6 @@
RSA_oid = ObjectIdentifier.newInternal(RSA_data);
/**
- * Algorithm ID for RSA keys used with RSA encryption, as defined
- * in PKCS #1. There are no parameters associated with this algorithm.
- * OID = 1.2.840.113549.1.1.1
- */
- RSAEncryption_oid = ObjectIdentifier.newInternal(RSAEncryption_data);
-
- /**
* Identifies a signing algorithm where an MD2 digest is encrypted
* using an RSA private key; defined in PKCS #1. Use of this
* signing algorithm is discouraged due to MD2 vulnerabilities.
@@ -895,6 +939,8 @@
nameTable.put(SHA256_oid, "SHA-256");
nameTable.put(SHA384_oid, "SHA-384");
nameTable.put(SHA512_oid, "SHA-512");
+ nameTable.put(SHA512_224_oid, "SHA-512/224");
+ nameTable.put(SHA512_256_oid, "SHA-512/256");
nameTable.put(RSAEncryption_oid, "RSA");
nameTable.put(RSA_oid, "RSA");
nameTable.put(DH_oid, "Diffie-Hellman");
@@ -924,6 +970,11 @@
nameTable.put(sha256WithRSAEncryption_oid, "SHA256withRSA");
nameTable.put(sha384WithRSAEncryption_oid, "SHA384withRSA");
nameTable.put(sha512WithRSAEncryption_oid, "SHA512withRSA");
+ nameTable.put(sha512_224WithRSAEncryption_oid, "SHA512/224withRSA");
+ nameTable.put(sha512_256WithRSAEncryption_oid, "SHA512/256withRSA");
+ nameTable.put(RSASSA_PSS_oid, "RSASSA-PSS");
+ nameTable.put(RSAES_OAEP_oid, "RSAES-OAEP");
+
nameTable.put(pbeWithMD5AndDES_oid, "PBEWithMD5AndDES");
nameTable.put(pbeWithMD5AndRC2_oid, "PBEWithMD5AndRC2");
nameTable.put(pbeWithSHA1AndDES_oid, "PBEWithSHA1AndDES");
@@ -977,4 +1028,90 @@
}
return null;
}
+
+ // Most commonly used PSSParameterSpec and AlgorithmId
+ private static class PSSParamsHolder {
+
+ final static PSSParameterSpec PSS_256_SPEC = new PSSParameterSpec(
+ "SHA-256", "MGF1",
+ new MGF1ParameterSpec("SHA-256"),
+ 32, PSSParameterSpec.TRAILER_FIELD_BC);
+ final static PSSParameterSpec PSS_384_SPEC = new PSSParameterSpec(
+ "SHA-384", "MGF1",
+ new MGF1ParameterSpec("SHA-384"),
+ 48, PSSParameterSpec.TRAILER_FIELD_BC);
+ final static PSSParameterSpec PSS_512_SPEC = new PSSParameterSpec(
+ "SHA-512", "MGF1",
+ new MGF1ParameterSpec("SHA-512"),
+ 64, PSSParameterSpec.TRAILER_FIELD_BC);
+
+ final static AlgorithmId PSS_256_ID;
+ final static AlgorithmId PSS_384_ID;
+ final static AlgorithmId PSS_512_ID;
+
+ static {
+ try {
+ PSS_256_ID = new AlgorithmId(RSASSA_PSS_oid,
+ new DerValue(PSSParameters.getEncoded(PSS_256_SPEC)));
+ PSS_384_ID = new AlgorithmId(RSASSA_PSS_oid,
+ new DerValue(PSSParameters.getEncoded(PSS_384_SPEC)));
+ PSS_512_ID = new AlgorithmId(RSASSA_PSS_oid,
+ new DerValue(PSSParameters.getEncoded(PSS_512_SPEC)));
+ } catch (IOException e) {
+ throw new AssertionError("Should not happen", e);
+ }
+ }
+ }
+
+ public static AlgorithmId getWithParameterSpec(String algName,
+ AlgorithmParameterSpec spec) throws NoSuchAlgorithmException {
+
+ if (spec == null) {
+ return AlgorithmId.get(algName);
+ } else if (spec == PSSParamsHolder.PSS_256_SPEC) {
+ return PSSParamsHolder.PSS_256_ID;
+ } else if (spec == PSSParamsHolder.PSS_384_SPEC) {
+ return PSSParamsHolder.PSS_384_ID;
+ } else if (spec == PSSParamsHolder.PSS_512_SPEC) {
+ return PSSParamsHolder.PSS_512_ID;
+ } else {
+ try {
+ AlgorithmParameters result =
+ AlgorithmParameters.getInstance(algName);
+ result.init(spec);
+ return get(result);
+ } catch (InvalidParameterSpecException | NoSuchAlgorithmException e) {
+ throw new ProviderException(e);
+ }
+ }
+ }
+
+ public static PSSParameterSpec getDefaultAlgorithmParameterSpec(
+ String sigAlg, PrivateKey k) {
+ if (sigAlg.equalsIgnoreCase("RSASSA-PSS")) {
+ switch (ifcFfcStrength(KeyUtil.getKeySize(k))) {
+ case "SHA256":
+ return PSSParamsHolder.PSS_256_SPEC;
+ case "SHA384":
+ return PSSParamsHolder.PSS_384_SPEC;
+ case "SHA512":
+ return PSSParamsHolder.PSS_512_SPEC;
+ default:
+ throw new AssertionError("Should not happen");
+ }
+ } else {
+ return null;
+ }
+ }
+
+ // Same values for RSA and DSA (from 8056174)
+ private static String ifcFfcStrength(int bitLength) {
+ if (bitLength > 7680) { // 256 bits
+ return "SHA512";
+ } else if (bitLength > 3072) { // 192 bits
+ return "SHA384";
+ } else { // 128 bits and less
+ return "SHA256";
+ }
+ }
}
diff --git a/jdk/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java b/jdk/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java
index 725c753..afc642d 100644
--- a/jdk/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java
+++ b/jdk/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
* certificate that identifies the specific OCSP Responder to use when
* performing on-line validation of that certificate.
* <p>
- * This extension is defined in <a href="http://www.ietf.org/rfc/rfc3280.txt">
+ * This extension is defined in <a href="http://tools.ietf.org/html/rfc5280">
* Internet X.509 PKI Certificate and Certificate Revocation List
* (CRL) Profile</a>. The profile permits
* the extension to be included in end-entity or CA certificates,
diff --git a/jdk/src/share/classes/sun/security/x509/CertificateIssuerExtension.java b/jdk/src/share/classes/sun/security/x509/CertificateIssuerExtension.java
index b773970..0dd8f39 100644
--- a/jdk/src/share/classes/sun/security/x509/CertificateIssuerExtension.java
+++ b/jdk/src/share/classes/sun/security/x509/CertificateIssuerExtension.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,7 +44,7 @@
* <p>
* If used by conforming CRL issuers, this extension is always
* critical. If an implementation ignored this extension it could not
- * correctly attribute CRL entries to certificates. PKIX (RFC 3280)
+ * correctly attribute CRL entries to certificates. PKIX (RFC 5280)
* RECOMMENDS that implementations recognize this extension.
* <p>
* The ASN.1 definition for this is:
diff --git a/jdk/src/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java b/jdk/src/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java
index 69be145..4b03223 100644
--- a/jdk/src/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java
+++ b/jdk/src/share/classes/sun/security/x509/DeltaCRLIndicatorExtension.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, 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,7 +45,7 @@
*
* <p>
* The extension is defined in Section 5.2.4 of
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">Internet X.509 PKI Certific
+ * <a href="http://tools.ietf.org/html/rfc5280">Internet X.509 PKI Certific
ate and Certificate Revocation List (CRL) Profile</a>.
*
* <p>
diff --git a/jdk/src/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java b/jdk/src/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java
index 68084602..dc82077 100644
--- a/jdk/src/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java
+++ b/jdk/src/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2014, 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
@@ -94,7 +94,7 @@
public static final String NAME = "ExtendedKeyUsage";
public static final String USAGES = "usages";
- // OID defined in RFC 3280 Sections 4.2.1.13
+ // OID defined in RFC 5280 Sections 4.2.1.12
// more from http://www.alvestrand.no/objectid/1.3.6.1.5.5.7.3.html
private static final Map <ObjectIdentifier, String> map =
new HashMap <ObjectIdentifier, String> ();
diff --git a/jdk/src/share/classes/sun/security/x509/FreshestCRLExtension.java b/jdk/src/share/classes/sun/security/x509/FreshestCRLExtension.java
index 775e2ac..3d0723d 100644
--- a/jdk/src/share/classes/sun/security/x509/FreshestCRLExtension.java
+++ b/jdk/src/share/classes/sun/security/x509/FreshestCRLExtension.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,7 @@
*
* <p>
* The extension is defined in Section 5.2.6 of
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">Internet X.509 PKI Certific
+ * <a href="http://tools.ietf.org/html/rfc5280">Internet X.509 PKI Certific
ate and Certificate Revocation List (CRL) Profile</a>.
*
* <p>
diff --git a/jdk/src/share/classes/sun/security/x509/InvalidityDateExtension.java b/jdk/src/share/classes/sun/security/x509/InvalidityDateExtension.java
index eda0216..7fac65f 100644
--- a/jdk/src/share/classes/sun/security/x509/InvalidityDateExtension.java
+++ b/jdk/src/share/classes/sun/security/x509/InvalidityDateExtension.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2014, 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
@@ -33,7 +33,7 @@
import sun.security.util.*;
/**
- * From RFC 3280:
+ * From RFC 5280:
* <p>
* The invalidity date is a non-critical CRL entry extension that
* provides the date on which it is known or suspected that the private
diff --git a/jdk/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java b/jdk/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java
index 6fe8eb3..6866af0 100644
--- a/jdk/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java
+++ b/jdk/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, 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
@@ -46,7 +46,7 @@
*
* <p>
* The extension is defined in Section 5.2.5 of
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">Internet X.509 PKI Certific
+ * <a href="http://tools.ietf.org/html/rfc5280">Internet X.509 PKI Certific
ate and Certificate Revocation List (CRL) Profile</a>.
*
* <p>
diff --git a/jdk/src/share/classes/sun/security/x509/RDN.java b/jdk/src/share/classes/sun/security/x509/RDN.java
index e60e2e8..9eb6068 100644
--- a/jdk/src/share/classes/sun/security/x509/RDN.java
+++ b/jdk/src/share/classes/sun/security/x509/RDN.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2014, 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
@@ -343,7 +343,7 @@
/*
* Returns a printable form of this RDN, using RFC 1779 style catenation
* of attribute/value assertions, and emitting attribute type keywords
- * from RFCs 1779, 2253, and 3280.
+ * from RFCs 1779, 2253, and 5280.
*/
public String toString() {
if (assertion.length == 1) {
diff --git a/jdk/src/share/classes/sun/security/x509/README b/jdk/src/share/classes/sun/security/x509/README
index 31a1291..f18a373 100644
--- a/jdk/src/share/classes/sun/security/x509/README
+++ b/jdk/src/share/classes/sun/security/x509/README
@@ -34,7 +34,7 @@
Protocol (LDAP) that many organizations are expecting will help
address online certificate distribution over the Internet.
- RFC 3280, which describes the Internet X.509 Public Key
+ RFC 5280, which describes the Internet X.509 Public Key
Infrastructure Certificate and CRL Profile.
RSA DSI has a bunch of "Public Key Cryptography Standards" (PKCS) which
diff --git a/jdk/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java b/jdk/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java
index e1a0bc2..29d60ef 100644
--- a/jdk/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java
+++ b/jdk/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, 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
@@ -48,7 +48,7 @@
* included in end entity or CA certificates. Conforming CAs MUST mark
* this extension as non-critical.
* <p>
- * This extension is defined in <a href="http://www.ietf.org/rfc/rfc3280.txt">
+ * This extension is defined in <a href="http://tools.ietf.org/html/rfc5280">
* Internet X.509 PKI Certificate and Certificate Revocation List
* (CRL) Profile</a>. The profile permits
* the extension to be included in end-entity or CA certificates,
diff --git a/jdk/src/share/classes/sun/security/x509/URIName.java b/jdk/src/share/classes/sun/security/x509/URIName.java
index 3c5b523..2d2cafd 100644
--- a/jdk/src/share/classes/sun/security/x509/URIName.java
+++ b/jdk/src/share/classes/sun/security/x509/URIName.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -35,15 +35,15 @@
* This class implements the URIName as required by the GeneralNames
* ASN.1 object.
* <p>
- * [RFC3280] When the subjectAltName extension contains a URI, the name MUST be
+ * [RFC5280] When the subjectAltName extension contains a URI, the name MUST be
* stored in the uniformResourceIdentifier (an IA5String). The name MUST
* be a non-relative URL, and MUST follow the URL syntax and encoding
- * rules specified in [RFC 1738]. The name must include both a scheme
+ * rules specified in [RFC 3986]. The name must include both a scheme
* (e.g., "http" or "ftp") and a scheme-specific-part. The scheme-
* specific-part must include a fully qualified domain name or IP
* address as the host.
* <p>
- * As specified in [RFC 1738], the scheme name is not case-sensitive
+ * As specified in [RFC 3986], the scheme name is not case-sensitive
* (e.g., "http" is equivalent to "HTTP"). The host part is also not
* case-sensitive, but other components of the scheme-specific-part may
* be case-sensitive. When comparing URIs, conforming implementations
@@ -113,7 +113,7 @@
}
host = uri.getHost();
- // RFC 3280 says that the host should be non-null, but we allow it to
+ // RFC 5280 says that the host should be non-null, but we allow it to
// be null because some widely deployed certificates contain CDP
// extensions with URIs that have no hostname (see bugs 4802236 and
// 5107944).
@@ -148,7 +148,7 @@
/**
* Create the URIName object with the specified name constraint. URI
* name constraints syntax is different than SubjectAltNames, etc. See
- * 4.2.1.11 of RFC 3280.
+ * 4.2.1.10 of RFC 5280.
*
* @param value the URI name constraint
* @throws IOException if name is not a proper URI name constraint
@@ -300,7 +300,7 @@
* These results are used in checking NameConstraints during
* certification path verification.
* <p>
- * RFC3280: For URIs, the constraint applies to the host part of the name.
+ * RFC5280: For URIs, the constraint applies to the host part of the name.
* The constraint may specify a host or a domain. Examples would be
* "foo.bar.com"; and ".xyz.com". When the the constraint begins with
* a period, it may be expanded with one or more subdomains. That is,
diff --git a/jdk/src/share/classes/sun/security/x509/X500Name.java b/jdk/src/share/classes/sun/security/x509/X500Name.java
index 447395c..f70c00f 100644
--- a/jdk/src/share/classes/sun/security/x509/X500Name.java
+++ b/jdk/src/share/classes/sun/security/x509/X500Name.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, 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
@@ -604,7 +604,7 @@
* Returns a string form of the X.500 distinguished name.
* The format of the string is from RFC 1779. The returned string
* may contain non-standardised keywords for more readability
- * (keywords from RFCs 1779, 2253, and 3280).
+ * (keywords from RFCs 1779, 2253, and 5280).
*/
public String toString() {
if (dn == null) {
@@ -865,7 +865,7 @@
* O="Sue, Grabbit and Runn" or
* O=Sue\, Grabbit and Runn
*
- * This method can parse RFC 1779, 2253 or 4514 DNs and non-standard 3280
+ * This method can parse RFC 1779, 2253 or 4514 DNs and non-standard 5280
* keywords. Additional keywords can be specified in the keyword/OID map.
*/
private void parseDN(String input, Map<String, String> keywordMap)
@@ -1104,20 +1104,8 @@
/****************************************************************/
/*
- * Maybe return a preallocated OID, to reduce storage costs
- * and speed recognition of common X.500 attributes.
- */
- static ObjectIdentifier intern(ObjectIdentifier oid) {
- ObjectIdentifier interned = internedOIDs.putIfAbsent(oid, oid);
- return (interned == null) ? oid : interned;
- }
-
- private static final Map<ObjectIdentifier,ObjectIdentifier> internedOIDs
- = new HashMap<ObjectIdentifier,ObjectIdentifier>();
-
- /*
* Selected OIDs from X.520
- * Includes all those specified in RFC 3280 as MUST or SHOULD
+ * Includes all those specified in RFC 5280 as MUST or SHOULD
* be recognized
*/
private static final int commonName_data[] = { 2, 5, 4, 3 };
@@ -1142,92 +1130,82 @@
{ 0, 9, 2342, 19200300, 100, 1, 1 };
- public static final ObjectIdentifier commonName_oid;
- public static final ObjectIdentifier countryName_oid;
- public static final ObjectIdentifier localityName_oid;
- public static final ObjectIdentifier orgName_oid;
- public static final ObjectIdentifier orgUnitName_oid;
- public static final ObjectIdentifier stateName_oid;
- public static final ObjectIdentifier streetAddress_oid;
- public static final ObjectIdentifier title_oid;
- public static final ObjectIdentifier DNQUALIFIER_OID;
- public static final ObjectIdentifier SURNAME_OID;
- public static final ObjectIdentifier GIVENNAME_OID;
- public static final ObjectIdentifier INITIALS_OID;
- public static final ObjectIdentifier GENERATIONQUALIFIER_OID;
- public static final ObjectIdentifier ipAddress_oid;
- public static final ObjectIdentifier DOMAIN_COMPONENT_OID;
- public static final ObjectIdentifier userid_oid;
- public static final ObjectIdentifier SERIALNUMBER_OID;
+ // OID for the "CN=" attribute, denoting a person's common name.
+ public static final ObjectIdentifier commonName_oid =
+ ObjectIdentifier.newInternal(commonName_data);
- static {
- /** OID for the "CN=" attribute, denoting a person's common name. */
- commonName_oid = intern(ObjectIdentifier.newInternal(commonName_data));
+ // OID for the "SERIALNUMBER=" attribute, denoting a serial number for.
+ // a name. Do not confuse with PKCS#9 issuerAndSerialNumber or the
+ // certificate serial number.
+ public static final ObjectIdentifier SERIALNUMBER_OID =
+ ObjectIdentifier.newInternal(SERIALNUMBER_DATA);
- /** OID for the "SERIALNUMBER=" attribute, denoting a serial number for.
- a name. Do not confuse with PKCS#9 issuerAndSerialNumber or the
- certificate serial number. */
- SERIALNUMBER_OID = intern(ObjectIdentifier.newInternal(SERIALNUMBER_DATA));
+ // OID for the "C=" attribute, denoting a country.
+ public static final ObjectIdentifier countryName_oid =
+ ObjectIdentifier.newInternal(countryName_data);
- /** OID for the "C=" attribute, denoting a country. */
- countryName_oid = intern(ObjectIdentifier.newInternal(countryName_data));
+ // OID for the "L=" attribute, denoting a locality (such as a city).
+ public static final ObjectIdentifier localityName_oid =
+ ObjectIdentifier.newInternal(localityName_data);
- /** OID for the "L=" attribute, denoting a locality (such as a city) */
- localityName_oid = intern(ObjectIdentifier.newInternal(localityName_data));
+ // OID for the "O=" attribute, denoting an organization name.
+ public static final ObjectIdentifier orgName_oid =
+ ObjectIdentifier.newInternal(orgName_data);
- /** OID for the "O=" attribute, denoting an organization name */
- orgName_oid = intern(ObjectIdentifier.newInternal(orgName_data));
+ // OID for the "OU=" attribute, denoting an organizational unit name.
+ public static final ObjectIdentifier orgUnitName_oid =
+ ObjectIdentifier.newInternal(orgUnitName_data);
- /** OID for the "OU=" attribute, denoting an organizational unit name */
- orgUnitName_oid = intern(ObjectIdentifier.newInternal(orgUnitName_data));
+ // OID for the "S=" attribute, denoting a state (such as Delaware).
+ public static final ObjectIdentifier stateName_oid =
+ ObjectIdentifier.newInternal(stateName_data);
- /** OID for the "S=" attribute, denoting a state (such as Delaware) */
- stateName_oid = intern(ObjectIdentifier.newInternal(stateName_data));
+ // OID for the "STREET=" attribute, denoting a street address.
+ public static final ObjectIdentifier streetAddress_oid =
+ ObjectIdentifier.newInternal(streetAddress_data);
- /** OID for the "STREET=" attribute, denoting a street address. */
- streetAddress_oid = intern(ObjectIdentifier.newInternal(streetAddress_data));
+ // OID for the "T=" attribute, denoting a person's title.
+ public static final ObjectIdentifier title_oid =
+ ObjectIdentifier.newInternal(title_data);
- /** OID for the "T=" attribute, denoting a person's title. */
- title_oid = intern(ObjectIdentifier.newInternal(title_data));
+ // OID for the "DNQUALIFIER=" or "DNQ=" attribute, denoting DN
+ // disambiguating information.
+ public static final ObjectIdentifier DNQUALIFIER_OID =
+ ObjectIdentifier.newInternal(DNQUALIFIER_DATA);
- /** OID for the "DNQUALIFIER=" or "DNQ=" attribute, denoting DN
- disambiguating information.*/
- DNQUALIFIER_OID = intern(ObjectIdentifier.newInternal(DNQUALIFIER_DATA));
+ // OID for the "SURNAME=" attribute, denoting a person's surname.
+ public static final ObjectIdentifier SURNAME_OID =
+ ObjectIdentifier.newInternal(SURNAME_DATA);
- /** OID for the "SURNAME=" attribute, denoting a person's surname.*/
- SURNAME_OID = intern(ObjectIdentifier.newInternal(SURNAME_DATA));
+ // OID for the "GIVENNAME=" attribute, denoting a person's given name.
+ public static final ObjectIdentifier GIVENNAME_OID =
+ ObjectIdentifier.newInternal(GIVENNAME_DATA);
- /** OID for the "GIVENNAME=" attribute, denoting a person's given name.*/
- GIVENNAME_OID = intern(ObjectIdentifier.newInternal(GIVENNAME_DATA));
+ // OID for the "INITIALS=" attribute, denoting a person's initials.
+ public static final ObjectIdentifier INITIALS_OID =
+ ObjectIdentifier.newInternal(INITIALS_DATA);
- /** OID for the "INITIALS=" attribute, denoting a person's initials.*/
- INITIALS_OID = intern(ObjectIdentifier.newInternal(INITIALS_DATA));
+ // OID for the "GENERATION=" attribute, denoting Jr., II, etc.
+ public static final ObjectIdentifier GENERATIONQUALIFIER_OID =
+ ObjectIdentifier.newInternal(GENERATIONQUALIFIER_DATA);
- /** OID for the "GENERATION=" attribute, denoting Jr., II, etc.*/
- GENERATIONQUALIFIER_OID =
- intern(ObjectIdentifier.newInternal(GENERATIONQUALIFIER_DATA));
+ // OIDs from other sources which show up in X.500 names we
+ // expect to deal with often.
+ //
+ // OID for "IP=" IP address attributes, used with SKIP.
+ public static final ObjectIdentifier ipAddress_oid =
+ ObjectIdentifier.newInternal(ipAddress_data);
- /*
- * OIDs from other sources which show up in X.500 names we
- * expect to deal with often
- */
- /** OID for "IP=" IP address attributes, used with SKIP. */
- ipAddress_oid = intern(ObjectIdentifier.newInternal(ipAddress_data));
+ // Domain component OID from RFC 1274, RFC 2247, RFC 5280.
+ //
+ // OID for "DC=" domain component attributes, used with DNSNames in DN
+ // format.
+ public static final ObjectIdentifier DOMAIN_COMPONENT_OID =
+ ObjectIdentifier.newInternal(DOMAIN_COMPONENT_DATA);
- /*
- * Domain component OID from RFC 1274, RFC 2247, RFC 3280
- */
-
- /*
- * OID for "DC=" domain component attributes, used with DNSNames in DN
- * format
- */
- DOMAIN_COMPONENT_OID =
- intern(ObjectIdentifier.newInternal(DOMAIN_COMPONENT_DATA));
-
- /** OID for "UID=" denoting a user id, defined in RFCs 1274 & 2798. */
- userid_oid = intern(ObjectIdentifier.newInternal(userid_data));
- }
+ // OID for "UID=" denoting a user id, defined in RFCs 1274 & 2798.
+ public static final ObjectIdentifier userid_oid =
+ ObjectIdentifier.newInternal(userid_data);
/**
* Return constraint type:<ul>
diff --git a/jdk/src/share/classes/sun/security/x509/X509CRLImpl.java b/jdk/src/share/classes/sun/security/x509/X509CRLImpl.java
index 84403b3..abc6d72 100644
--- a/jdk/src/share/classes/sun/security/x509/X509CRLImpl.java
+++ b/jdk/src/share/classes/sun/security/x509/X509CRLImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,20 +29,12 @@
import java.io.OutputStream;
import java.io.IOException;
import java.math.BigInteger;
-import java.security.Principal;
-import java.security.PublicKey;
-import java.security.PrivateKey;
-import java.security.Provider;
-import java.security.Signature;
-import java.security.NoSuchAlgorithmException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchProviderException;
-import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.security.cert.X509CRLEntry;
import java.security.cert.CRLException;
+import java.security.*;
import java.util.*;
import javax.security.auth.x500.X500Principal;
@@ -63,7 +55,7 @@
* signature BIT STRING }
* </pre>
* More information can be found in
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
+ * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280: Internet X.509
* Public Key Infrastructure Certificate and CRL Profile</a>.
* <p>
* The ASN.1 definition of <code>tbsCertList</code> is:
@@ -379,12 +371,21 @@
throw new CRLException("Uninitialized CRL");
}
Signature sigVerf = null;
+ String sigName = sigAlgId.getName();
if (sigProvider.length() == 0) {
- sigVerf = Signature.getInstance(sigAlgId.getName());
+ sigVerf = Signature.getInstance(sigName);
} else {
- sigVerf = Signature.getInstance(sigAlgId.getName(), sigProvider);
+ sigVerf = Signature.getInstance(sigName, sigProvider);
}
- sigVerf.initVerify(key);
+
+ try {
+ SignatureUtil.initVerifyWithParam(sigVerf, key,
+ SignatureUtil.getParamSpec(sigName, getSigAlgParams()));
+ } catch (ProviderException e) {
+ throw new CRLException(e.getMessage(), e.getCause());
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new CRLException(e);
+ }
if (tbsCertList == null) {
throw new CRLException("Uninitialized CRL");
@@ -423,12 +424,21 @@
throw new CRLException("Uninitialized CRL");
}
Signature sigVerf = null;
+ String sigName = sigAlgId.getName();
if (sigProvider == null) {
- sigVerf = Signature.getInstance(sigAlgId.getName());
+ sigVerf = Signature.getInstance(sigName);
} else {
- sigVerf = Signature.getInstance(sigAlgId.getName(), sigProvider);
+ sigVerf = Signature.getInstance(sigName, sigProvider);
}
- sigVerf.initVerify(key);
+
+ try {
+ SignatureUtil.initVerifyWithParam(sigVerf, key,
+ SignatureUtil.getParamSpec(sigName, getSigAlgParams()));
+ } catch (ProviderException e) {
+ throw new CRLException(e.getMessage(), e.getCause());
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new CRLException(e);
+ }
if (tbsCertList == null) {
throw new CRLException("Uninitialized CRL");
@@ -443,18 +453,6 @@
}
/**
- * This static method is the default implementation of the
- * verify(PublicKey key, Provider sigProvider) method in X509CRL.
- * Called from java.security.cert.X509CRL.verify(PublicKey key,
- * Provider sigProvider)
- */
- public static void verify(X509CRL crl, PublicKey key,
- Provider sigProvider) throws CRLException,
- NoSuchAlgorithmException, InvalidKeyException, SignatureException {
- crl.verify(key, sigProvider);
- }
-
- /**
* Encodes an X.509 CRL, and signs it using the given key.
*
* @param key the private key used for signing.
@@ -501,7 +499,7 @@
sigEngine.initSign(key);
- // in case the name is reset
+ // in case the name is reset
sigAlgId = AlgorithmId.get(sigEngine.getAlgorithm());
infoSigAlgId = sigAlgId;
diff --git a/jdk/src/share/classes/sun/security/x509/X509CertImpl.java b/jdk/src/share/classes/sun/security/x509/X509CertImpl.java
index ab1c450..012bb8c 100644
--- a/jdk/src/share/classes/sun/security/x509/X509CertImpl.java
+++ b/jdk/src/share/classes/sun/security/x509/X509CertImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@
import java.io.OutputStream;
import java.math.BigInteger;
import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
import java.security.cert.*;
import java.security.cert.Certificate;
import java.util.*;
@@ -42,7 +43,6 @@
import javax.security.auth.x500.X500Principal;
import sun.misc.HexDumpEncoder;
-import java.util.Base64;
import sun.security.util.*;
import sun.security.provider.X509Factory;
@@ -388,7 +388,6 @@
public void verify(PublicKey key)
throws CertificateException, NoSuchAlgorithmException,
InvalidKeyException, NoSuchProviderException, SignatureException {
-
verify(key, "");
}
@@ -430,12 +429,21 @@
}
// Verify the signature ...
Signature sigVerf = null;
+ String sigName = algId.getName();
if (sigProvider.length() == 0) {
- sigVerf = Signature.getInstance(algId.getName());
+ sigVerf = Signature.getInstance(sigName);
} else {
- sigVerf = Signature.getInstance(algId.getName(), sigProvider);
+ sigVerf = Signature.getInstance(sigName, sigProvider);
}
- sigVerf.initVerify(key);
+
+ try {
+ SignatureUtil.initVerifyWithParam(sigVerf, key,
+ SignatureUtil.getParamSpec(sigName, getSigAlgParams()));
+ } catch (ProviderException e) {
+ throw new CertificateException(e.getMessage(), e.getCause());
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new CertificateException(e);
+ }
byte[] rawCert = info.getEncodedInfo();
sigVerf.update(rawCert, 0, rawCert.length);
@@ -475,12 +483,21 @@
}
// Verify the signature ...
Signature sigVerf = null;
+ String sigName = algId.getName();
if (sigProvider == null) {
- sigVerf = Signature.getInstance(algId.getName());
+ sigVerf = Signature.getInstance(sigName);
} else {
- sigVerf = Signature.getInstance(algId.getName(), sigProvider);
+ sigVerf = Signature.getInstance(sigName, sigProvider);
}
- sigVerf.initVerify(key);
+
+ try {
+ SignatureUtil.initVerifyWithParam(sigVerf, key,
+ SignatureUtil.getParamSpec(sigName, getSigAlgParams()));
+ } catch (ProviderException e) {
+ throw new CertificateException(e.getMessage(), e.getCause());
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new CertificateException(e);
+ }
byte[] rawCert = info.getEncodedInfo();
sigVerf.update(rawCert, 0, rawCert.length);
@@ -494,18 +511,6 @@
}
}
- /**
- * This static method is the default implementation of the
- * verify(PublicKey key, Provider sigProvider) method in X509Certificate.
- * Called from java.security.cert.X509Certificate.verify(PublicKey key,
- * Provider sigProvider)
- */
- public static void verify(X509Certificate cert, PublicKey key,
- Provider sigProvider) throws CertificateException,
- NoSuchAlgorithmException, InvalidKeyException, SignatureException {
- cert.verify(key, sigProvider);
- }
-
/**
* Creates an X.509 certificate, and signs it using the given key
* (associating a signature algorithm and an X.500 name).
@@ -549,20 +554,63 @@
throws CertificateException, NoSuchAlgorithmException,
InvalidKeyException, NoSuchProviderException, SignatureException {
try {
- if (readOnly)
+ sign(key, null, algorithm, provider);
+ } catch (InvalidAlgorithmParameterException e) {
+ // should not happen; re-throw just in case
+ throw new SignatureException(e);
+ }
+ }
+
+ /**
+ * Creates an X.509 certificate, and signs it using the given key
+ * (associating a signature algorithm and an X.500 name), signature
+ * parameters, and security provider. If the given provider name
+ * is null or empty, the implementation look up will be based on
+ * provider configurations.
+ * This operation is used to implement the certificate generation
+ * functionality of a certificate authority.
+ *
+ * @param key the private key used for signing
+ * @param signingParams the parameters used for signing
+ * @param algorithm the name of the signature algorithm used
+ * @param provider the name of the provider, may be null
+ *
+ * @exception NoSuchAlgorithmException on unsupported signature
+ * algorithms
+ * @exception InvalidKeyException on incorrect key
+ * @exception InvalidAlgorithmParameterException on invalid signature
+ * parameters
+ * @exception NoSuchProviderException on incorrect provider
+ * @exception SignatureException on signature errors
+ * @exception CertificateException on encoding errors
+ */
+ public void sign(PrivateKey key, AlgorithmParameterSpec signingParams,
+ String algorithm, String provider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, InvalidAlgorithmParameterException,
+ NoSuchProviderException, SignatureException {
+ try {
+ if (readOnly) {
throw new CertificateEncodingException(
- "cannot over-write existing certificate");
+ "cannot over-write existing certificate");
+ }
+
Signature sigEngine = null;
- if ((provider == null) || (provider.length() == 0))
+ if ((provider == null) || (provider.length() == 0)) {
sigEngine = Signature.getInstance(algorithm);
- else
+ } else {
sigEngine = Signature.getInstance(algorithm, provider);
+ }
- sigEngine.initSign(key);
+ SignatureUtil.initSignWithParam(sigEngine, key, signingParams,
+ null);
- // in case the name is reset
- algId = AlgorithmId.get(sigEngine.getAlgorithm());
-
+ // in case the name is reset
+ if (signingParams != null) {
+ algId = AlgorithmId.get(sigEngine.getParameters());
+ } else {
+ algId = AlgorithmId.get(algorithm);
+ }
DerOutputStream out = new DerOutputStream();
DerOutputStream tmp = new DerOutputStream();
@@ -695,9 +743,10 @@
public void set(String name, Object obj)
throws CertificateException, IOException {
// check if immutable
- if (readOnly)
+ if (readOnly) {
throw new CertificateException("cannot over-write existing"
+ " certificate");
+ }
X509AttributeName attr = new X509AttributeName(name);
String id = attr.getPrefix();
@@ -736,9 +785,10 @@
public void delete(String name)
throws CertificateException, IOException {
// check if immutable
- if (readOnly)
+ if (readOnly) {
throw new CertificateException("cannot over-write existing"
+ " certificate");
+ }
X509AttributeName attr = new X509AttributeName(name);
String id = attr.getPrefix();
@@ -1768,9 +1818,10 @@
private void parse(DerValue val)
throws CertificateException, IOException {
// check if can over write the certificate
- if (readOnly)
+ if (readOnly) {
throw new CertificateParsingException(
"cannot over-write existing certificate");
+ }
if (val.data == null || val.tag != DerValue.tag_Sequence)
throw new CertificateParsingException(
diff --git a/jdk/src/share/classes/sun/security/x509/X509CertInfo.java b/jdk/src/share/classes/sun/security/x509/X509CertInfo.java
index b7f2dd8..fa64e9d 100644
--- a/jdk/src/share/classes/sun/security/x509/X509CertInfo.java
+++ b/jdk/src/share/classes/sun/security/x509/X509CertInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -708,7 +708,7 @@
}
/*
- * Verify if X.509 V3 Certificate is compliant with RFC 3280.
+ * Verify if X.509 V3 Certificate is compliant with RFC 5280.
*/
private void verifyCert(X500Name subject,
CertificateExtensions extensions)
diff --git a/jdk/src/share/lib/security/java.security-aix b/jdk/src/share/lib/security/java.security-aix
index 0f21179..7f20467 100644
--- a/jdk/src/share/lib/security/java.security-aix
+++ b/jdk/src/share/lib/security/java.security-aix
@@ -341,7 +341,7 @@
# By default, the location of the OCSP responder is determined implicitly
# from the certificate being validated. This property explicitly specifies
# the location of the OCSP responder. The property is used when the
-# Authority Information Access extension (defined in RFC 3280) is absent
+# Authority Information Access extension (defined in RFC 5280) is absent
# from the certificate or when it requires overriding.
#
# Example,
@@ -420,6 +420,32 @@
# krb5.kdc.bad.policy = tryLess:2,2000
krb5.kdc.bad.policy = tryLast
+#
+# Kerberos cross-realm referrals (RFC 6806)
+#
+# OpenJDK's Kerberos client supports cross-realm referrals as defined in
+# RFC 6806. This allows to setup more dynamic environments in which clients
+# do not need to know in advance how to reach the realm of a target principal
+# (either a user or service).
+#
+# When a client issues an AS or a TGS request, the "canonicalize" option
+# is set to announce support of this feature. A KDC server may fulfill the
+# request or reply referring the client to a different one. If referred,
+# the client will issue a new request and the cycle repeats.
+#
+# In addition to referrals, the "canonicalize" option allows the KDC server
+# to change the client name in response to an AS request. For security reasons,
+# RFC 6806 (section 11) FAST scheme is enforced.
+#
+# Disable Kerberos cross-realm referrals. Value may be overwritten with a
+# System property (-Dsun.security.krb5.disableReferrals).
+sun.security.krb5.disableReferrals=false
+
+# Maximum number of AS or TGS referrals to avoid infinite loops. Value may
+# be overwritten with a System property (-Dsun.security.krb5.maxReferrals).
+sun.security.krb5.maxReferrals=5
+
+#
# Algorithm restrictions for certification path (CertPath) processing
#
# In some environments, certain algorithms or key lengths may be undesirable
@@ -860,8 +886,8 @@
# Patterns are separated by ";" (semicolon).
# Whitespace is significant and is considered part of the pattern.
#
-# If the system property jdk.serialFilter is also specified, it supersedes
-# the security property value defined here.
+# If the system property jdk.serialFilter is also specified on the command
+# line, it supersedes the security property value defined here.
#
# If a pattern includes a "=", it sets a limit.
# If a limit appears more than once the last value is used.
@@ -987,6 +1013,24 @@
#jdk.jceks.iterationCount = 200000
#
+# Disabled mechanisms for the Simple Authentication and Security Layer (SASL)
+#
+# Disabled mechanisms will not be negotiated by both SASL clients and servers.
+# These mechanisms will be ignored if they are specified in the "mechanisms"
+# argument of "Sasl.createSaslClient" or the "mechanism" argument of
+# "Sasl.createSaslServer".
+#
+# The value of this property is a comma-separated list of SASL mechanisms.
+# The mechanisms are case-sensitive. Whitespaces around the commas are ignored.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.sasl.disabledMechanisms=PLAIN, CRAM-MD5, DIGEST-MD5
+jdk.sasl.disabledMechanisms=
+
+#
# Policies for distrusting Certificate Authorities (CAs).
#
# This is a comma separated value of one or more case-sensitive strings, each
diff --git a/jdk/src/share/lib/security/java.security-linux b/jdk/src/share/lib/security/java.security-linux
index 3483921..a866a05 100644
--- a/jdk/src/share/lib/security/java.security-linux
+++ b/jdk/src/share/lib/security/java.security-linux
@@ -341,7 +341,7 @@
# By default, the location of the OCSP responder is determined implicitly
# from the certificate being validated. This property explicitly specifies
# the location of the OCSP responder. The property is used when the
-# Authority Information Access extension (defined in RFC 3280) is absent
+# Authority Information Access extension (defined in RFC 5280) is absent
# from the certificate or when it requires overriding.
#
# Example,
@@ -420,6 +420,32 @@
# krb5.kdc.bad.policy = tryLess:2,2000
krb5.kdc.bad.policy = tryLast
+#
+# Kerberos cross-realm referrals (RFC 6806)
+#
+# OpenJDK's Kerberos client supports cross-realm referrals as defined in
+# RFC 6806. This allows to setup more dynamic environments in which clients
+# do not need to know in advance how to reach the realm of a target principal
+# (either a user or service).
+#
+# When a client issues an AS or a TGS request, the "canonicalize" option
+# is set to announce support of this feature. A KDC server may fulfill the
+# request or reply referring the client to a different one. If referred,
+# the client will issue a new request and the cycle repeats.
+#
+# In addition to referrals, the "canonicalize" option allows the KDC server
+# to change the client name in response to an AS request. For security reasons,
+# RFC 6806 (section 11) FAST scheme is enforced.
+#
+# Disable Kerberos cross-realm referrals. Value may be overwritten with a
+# System property (-Dsun.security.krb5.disableReferrals).
+sun.security.krb5.disableReferrals=false
+
+# Maximum number of AS or TGS referrals to avoid infinite loops. Value may
+# be overwritten with a System property (-Dsun.security.krb5.maxReferrals).
+sun.security.krb5.maxReferrals=5
+
+#
# Algorithm restrictions for certification path (CertPath) processing
#
# In some environments, certain algorithms or key lengths may be undesirable
@@ -861,8 +887,8 @@
# Patterns are separated by ";" (semicolon).
# Whitespace is significant and is considered part of the pattern.
#
-# If the system property jdk.serialFilter is also specified, it supersedes
-# the security property value defined here.
+# If the system property jdk.serialFilter is also specified on the command
+# line, it supersedes the security property value defined here.
#
# If a pattern includes a "=", it sets a limit.
# If a limit appears more than once the last value is used.
@@ -993,6 +1019,24 @@
#jdk.jceks.iterationCount = 200000
#
+# Disabled mechanisms for the Simple Authentication and Security Layer (SASL)
+#
+# Disabled mechanisms will not be negotiated by both SASL clients and servers.
+# These mechanisms will be ignored if they are specified in the "mechanisms"
+# argument of "Sasl.createSaslClient" or the "mechanism" argument of
+# "Sasl.createSaslServer".
+#
+# The value of this property is a comma-separated list of SASL mechanisms.
+# The mechanisms are case-sensitive. Whitespaces around the commas are ignored.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.sasl.disabledMechanisms=PLAIN, CRAM-MD5, DIGEST-MD5
+jdk.sasl.disabledMechanisms=
+
+#
# Policies for distrusting Certificate Authorities (CAs).
#
# This is a comma separated value of one or more case-sensitive strings, each
diff --git a/jdk/src/share/lib/security/java.security-macosx b/jdk/src/share/lib/security/java.security-macosx
index aa3fe2d..9726d39 100644
--- a/jdk/src/share/lib/security/java.security-macosx
+++ b/jdk/src/share/lib/security/java.security-macosx
@@ -344,7 +344,7 @@
# By default, the location of the OCSP responder is determined implicitly
# from the certificate being validated. This property explicitly specifies
# the location of the OCSP responder. The property is used when the
-# Authority Information Access extension (defined in RFC 3280) is absent
+# Authority Information Access extension (defined in RFC 5280) is absent
# from the certificate or when it requires overriding.
#
# Example,
@@ -423,6 +423,32 @@
# krb5.kdc.bad.policy = tryLess:2,2000
krb5.kdc.bad.policy = tryLast
+#
+# Kerberos cross-realm referrals (RFC 6806)
+#
+# OpenJDK's Kerberos client supports cross-realm referrals as defined in
+# RFC 6806. This allows to setup more dynamic environments in which clients
+# do not need to know in advance how to reach the realm of a target principal
+# (either a user or service).
+#
+# When a client issues an AS or a TGS request, the "canonicalize" option
+# is set to announce support of this feature. A KDC server may fulfill the
+# request or reply referring the client to a different one. If referred,
+# the client will issue a new request and the cycle repeats.
+#
+# In addition to referrals, the "canonicalize" option allows the KDC server
+# to change the client name in response to an AS request. For security reasons,
+# RFC 6806 (section 11) FAST scheme is enforced.
+#
+# Disable Kerberos cross-realm referrals. Value may be overwritten with a
+# System property (-Dsun.security.krb5.disableReferrals).
+sun.security.krb5.disableReferrals=false
+
+# Maximum number of AS or TGS referrals to avoid infinite loops. Value may
+# be overwritten with a System property (-Dsun.security.krb5.maxReferrals).
+sun.security.krb5.maxReferrals=5
+
+#
# Algorithm restrictions for certification path (CertPath) processing
#
# In some environments, certain algorithms or key lengths may be undesirable
@@ -864,8 +890,8 @@
# Patterns are separated by ";" (semicolon).
# Whitespace is significant and is considered part of the pattern.
#
-# If the system property jdk.serialFilter is also specified, it supersedes
-# the security property value defined here.
+# If the system property jdk.serialFilter is also specified on the command
+# line, it supersedes the security property value defined here.
#
# If a pattern includes a "=", it sets a limit.
# If a limit appears more than once the last value is used.
@@ -991,6 +1017,24 @@
#jdk.jceks.iterationCount = 200000
#
+# Disabled mechanisms for the Simple Authentication and Security Layer (SASL)
+#
+# Disabled mechanisms will not be negotiated by both SASL clients and servers.
+# These mechanisms will be ignored if they are specified in the "mechanisms"
+# argument of "Sasl.createSaslClient" or the "mechanism" argument of
+# "Sasl.createSaslServer".
+#
+# The value of this property is a comma-separated list of SASL mechanisms.
+# The mechanisms are case-sensitive. Whitespaces around the commas are ignored.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.sasl.disabledMechanisms=PLAIN, CRAM-MD5, DIGEST-MD5
+jdk.sasl.disabledMechanisms=
+
+#
# Policies for distrusting Certificate Authorities (CAs).
#
# This is a comma separated value of one or more case-sensitive strings, each
diff --git a/jdk/src/share/lib/security/java.security-solaris b/jdk/src/share/lib/security/java.security-solaris
index 9fe3304..f50b9fe 100644
--- a/jdk/src/share/lib/security/java.security-solaris
+++ b/jdk/src/share/lib/security/java.security-solaris
@@ -343,7 +343,7 @@
# By default, the location of the OCSP responder is determined implicitly
# from the certificate being validated. This property explicitly specifies
# the location of the OCSP responder. The property is used when the
-# Authority Information Access extension (defined in RFC 3280) is absent
+# Authority Information Access extension (defined in RFC 5280) is absent
# from the certificate or when it requires overriding.
#
# Example,
@@ -422,6 +422,32 @@
# krb5.kdc.bad.policy = tryLess:2,2000
krb5.kdc.bad.policy = tryLast
+#
+# Kerberos cross-realm referrals (RFC 6806)
+#
+# OpenJDK's Kerberos client supports cross-realm referrals as defined in
+# RFC 6806. This allows to setup more dynamic environments in which clients
+# do not need to know in advance how to reach the realm of a target principal
+# (either a user or service).
+#
+# When a client issues an AS or a TGS request, the "canonicalize" option
+# is set to announce support of this feature. A KDC server may fulfill the
+# request or reply referring the client to a different one. If referred,
+# the client will issue a new request and the cycle repeats.
+#
+# In addition to referrals, the "canonicalize" option allows the KDC server
+# to change the client name in response to an AS request. For security reasons,
+# RFC 6806 (section 11) FAST scheme is enforced.
+#
+# Disable Kerberos cross-realm referrals. Value may be overwritten with a
+# System property (-Dsun.security.krb5.disableReferrals).
+sun.security.krb5.disableReferrals=false
+
+# Maximum number of AS or TGS referrals to avoid infinite loops. Value may
+# be overwritten with a System property (-Dsun.security.krb5.maxReferrals).
+sun.security.krb5.maxReferrals=5
+
+#
# Algorithm restrictions for certification path (CertPath) processing
#
# In some environments, certain algorithms or key lengths may be undesirable
@@ -863,8 +889,8 @@
# Patterns are separated by ";" (semicolon).
# Whitespace is significant and is considered part of the pattern.
#
-# If the system property jdk.serialFilter is also specified, it supersedes
-# the security property value defined here.
+# If the system property jdk.serialFilter is also specified on the command
+# line, it supersedes the security property value defined here.
#
# If a pattern includes a "=", it sets a limit.
# If a limit appears more than once the last value is used.
@@ -990,6 +1016,24 @@
#jdk.jceks.iterationCount = 200000
#
+# Disabled mechanisms for the Simple Authentication and Security Layer (SASL)
+#
+# Disabled mechanisms will not be negotiated by both SASL clients and servers.
+# These mechanisms will be ignored if they are specified in the "mechanisms"
+# argument of "Sasl.createSaslClient" or the "mechanism" argument of
+# "Sasl.createSaslServer".
+#
+# The value of this property is a comma-separated list of SASL mechanisms.
+# The mechanisms are case-sensitive. Whitespaces around the commas are ignored.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.sasl.disabledMechanisms=PLAIN, CRAM-MD5, DIGEST-MD5
+jdk.sasl.disabledMechanisms=
+
+#
# Policies for distrusting Certificate Authorities (CAs).
#
# This is a comma separated value of one or more case-sensitive strings, each
diff --git a/jdk/src/share/lib/security/java.security-windows b/jdk/src/share/lib/security/java.security-windows
index 695c8bb..dd66f69 100644
--- a/jdk/src/share/lib/security/java.security-windows
+++ b/jdk/src/share/lib/security/java.security-windows
@@ -344,7 +344,7 @@
# By default, the location of the OCSP responder is determined implicitly
# from the certificate being validated. This property explicitly specifies
# the location of the OCSP responder. The property is used when the
-# Authority Information Access extension (defined in RFC 3280) is absent
+# Authority Information Access extension (defined in RFC 5280) is absent
# from the certificate or when it requires overriding.
#
# Example,
@@ -423,6 +423,32 @@
# krb5.kdc.bad.policy = tryLess:2,2000
krb5.kdc.bad.policy = tryLast
+#
+# Kerberos cross-realm referrals (RFC 6806)
+#
+# OpenJDK's Kerberos client supports cross-realm referrals as defined in
+# RFC 6806. This allows to setup more dynamic environments in which clients
+# do not need to know in advance how to reach the realm of a target principal
+# (either a user or service).
+#
+# When a client issues an AS or a TGS request, the "canonicalize" option
+# is set to announce support of this feature. A KDC server may fulfill the
+# request or reply referring the client to a different one. If referred,
+# the client will issue a new request and the cycle repeats.
+#
+# In addition to referrals, the "canonicalize" option allows the KDC server
+# to change the client name in response to an AS request. For security reasons,
+# RFC 6806 (section 11) FAST scheme is enforced.
+#
+# Disable Kerberos cross-realm referrals. Value may be overwritten with a
+# System property (-Dsun.security.krb5.disableReferrals).
+sun.security.krb5.disableReferrals=false
+
+# Maximum number of AS or TGS referrals to avoid infinite loops. Value may
+# be overwritten with a System property (-Dsun.security.krb5.maxReferrals).
+sun.security.krb5.maxReferrals=5
+
+#
# Algorithm restrictions for certification path (CertPath) processing
#
# In some environments, certain algorithms or key lengths may be undesirable
@@ -864,8 +890,8 @@
# Patterns are separated by ";" (semicolon).
# Whitespace is significant and is considered part of the pattern.
#
-# If the system property jdk.serialFilter is also specified, it supersedes
-# the security property value defined here.
+# If the system property jdk.serialFilter is also specified on the command
+# line, it supersedes the security property value defined here.
#
# If a pattern includes a "=", it sets a limit.
# If a limit appears more than once the last value is used.
@@ -991,6 +1017,24 @@
#jdk.jceks.iterationCount = 200000
#
+# Disabled mechanisms for the Simple Authentication and Security Layer (SASL)
+#
+# Disabled mechanisms will not be negotiated by both SASL clients and servers.
+# These mechanisms will be ignored if they are specified in the "mechanisms"
+# argument of "Sasl.createSaslClient" or the "mechanism" argument of
+# "Sasl.createSaslServer".
+#
+# The value of this property is a comma-separated list of SASL mechanisms.
+# The mechanisms are case-sensitive. Whitespaces around the commas are ignored.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.sasl.disabledMechanisms=PLAIN, CRAM-MD5, DIGEST-MD5
+jdk.sasl.disabledMechanisms=
+
+#
# Policies for distrusting Certificate Authorities (CAs).
#
# This is a comma separated value of one or more case-sensitive strings, each
diff --git a/jdk/src/share/native/sun/font/freetypeScaler.c b/jdk/src/share/native/sun/font/freetypeScaler.c
index 228a4f9..30f34e4 100644
--- a/jdk/src/share/native/sun/font/freetypeScaler.c
+++ b/jdk/src/share/native/sun/font/freetypeScaler.c
@@ -675,10 +675,14 @@
pScalerContext, pScaler, glyphCode);
info = (GlyphInfo*) jlong_to_ptr(image);
- (*env)->SetFloatField(env, metrics, sunFontIDs.xFID, info->advanceX);
- (*env)->SetFloatField(env, metrics, sunFontIDs.yFID, info->advanceY);
-
- free(info);
+ if (info != NULL) {
+ (*env)->SetFloatField(env, metrics, sunFontIDs.xFID, info->advanceX);
+ (*env)->SetFloatField(env, metrics, sunFontIDs.yFID, info->advanceY);
+ free(info);
+ } else {
+ (*env)->SetFloatField(env, metrics, sunFontIDs.xFID, 0.0f);
+ (*env)->SetFloatField(env, metrics, sunFontIDs.yFID, 0.0f);
+ }
}
diff --git a/jdk/src/share/native/sun/security/krb5/nativeccache.c b/jdk/src/share/native/sun/security/krb5/nativeccache.c
index 1b50a2e..5ab3f73 100644
--- a/jdk/src/share/native/sun/security/krb5/nativeccache.c
+++ b/jdk/src/share/native/sun/security/krb5/nativeccache.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -418,7 +418,7 @@
if (krbcredsConstructor == 0) {
krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "<init>",
- "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V");
+ "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V");
if (krbcredsConstructor == 0) {
printf("Couldn't find sun.security.krb5.internal.Ticket constructor\n");
break;
@@ -432,7 +432,9 @@
krbcredsConstructor,
ticket,
clientPrincipal,
+ NULL,
targetPrincipal,
+ NULL,
encryptionKey,
ticketFlags,
authTime,
diff --git a/jdk/src/solaris/classes/java/lang/UNIXProcess.java b/jdk/src/solaris/classes/java/lang/UNIXProcess.java
index 1793a8f..fe26fd8 100644
--- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java
+++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java
@@ -408,8 +408,7 @@
long deadline = System.nanoTime() + remainingNanos;
do {
- // Round up to next millisecond
- wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L));
+ TimeUnit.NANOSECONDS.timedWait(this, remainingNanos);
if (hasExited) {
return true;
}
diff --git a/jdk/src/solaris/native/java/util/TimeZone_md.c b/jdk/src/solaris/native/java/util/TimeZone_md.c
index 3507c1c..7ec893b 100644
--- a/jdk/src/solaris/native/java/util/TimeZone_md.c
+++ b/jdk/src/solaris/native/java/util/TimeZone_md.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,6 +42,8 @@
#include "jvm.h"
#include "TimeZone_md.h"
+static char *isFileIdentical(char* buf, size_t size, char *pathname);
+
#define SKIP_SPACE(p) while (*p == ' ' || *p == '\t') p++;
#if defined(_ALLBSD_SOURCE)
@@ -65,6 +67,8 @@
static const char *DEFAULT_ZONEINFO_FILE = "/usr/share/lib/zoneinfo/localtime";
#endif /* defined(__linux__) || defined(_ALLBSD_SOURCE) */
+static const char popularZones[][4] = {"UTC", "GMT"};
+
#if defined(_AIX)
static const char *ETC_ENVIRONMENT_FILE = "/etc/environment";
#endif
@@ -114,14 +118,28 @@
findZoneinfoFile(char *buf, size_t size, const char *dir)
{
DIR *dirp = NULL;
- struct stat statbuf;
struct dirent64 *dp = NULL;
struct dirent64 *entry = NULL;
char *pathname = NULL;
- int fd = -1;
- char *dbuf = NULL;
char *tz = NULL;
+ if (strcmp(dir, ZONEINFO_DIR) == 0) {
+ /* fast path for 1st iteration */
+ unsigned int i;
+ for (i = 0; i < sizeof (popularZones) / sizeof (popularZones[0]); i++) {
+ pathname = getPathName(dir, popularZones[i]);
+ if (pathname == NULL) {
+ continue;
+ }
+ tz = isFileIdentical(buf, size, pathname);
+ free((void *) pathname);
+ pathname = NULL;
+ if (tz != NULL) {
+ return tz;
+ }
+ }
+ }
+
dirp = opendir(dir);
if (dirp == NULL) {
return NULL;
@@ -161,40 +179,14 @@
if (pathname == NULL) {
break;
}
- if (stat(pathname, &statbuf) == -1) {
- break;
- }
- if (S_ISDIR(statbuf.st_mode)) {
- tz = findZoneinfoFile(buf, size, pathname);
- if (tz != NULL) {
- break;
- }
- } else if (S_ISREG(statbuf.st_mode) && (size_t)statbuf.st_size == size) {
- dbuf = (char *) malloc(size);
- if (dbuf == NULL) {
- break;
- }
- if ((fd = open(pathname, O_RDONLY)) == -1) {
- break;
- }
- if (read(fd, dbuf, size) != (ssize_t) size) {
- break;
- }
- if (memcmp(buf, dbuf, size) == 0) {
- tz = getZoneName(pathname);
- if (tz != NULL) {
- tz = strdup(tz);
- }
- break;
- }
- free((void *) dbuf);
- dbuf = NULL;
- (void) close(fd);
- fd = -1;
- }
+ tz = isFileIdentical(buf, size, pathname);
+
free((void *) pathname);
pathname = NULL;
+ if (tz != NULL) {
+ break;
+ }
}
if (entry != NULL) {
@@ -203,16 +195,53 @@
if (dirp != NULL) {
(void) closedir(dirp);
}
- if (pathname != NULL) {
- free((void *) pathname);
+ return tz;
+}
+
+/*
+ * Checks if the file pointed to by pathname matches
+ * the data contents in buf.
+ * Returns a representation of the timezone file name
+ * if file match is found, otherwise NULL.
+ */
+static char *
+isFileIdentical(char *buf, size_t size, char *pathname)
+{
+ char *possibleMatch = NULL;
+ struct stat statbuf;
+ char *dbuf = NULL;
+ int fd = -1;
+ int res;
+
+ if (stat(pathname, &statbuf) == -1) {
+ return NULL;
}
- if (fd != -1) {
+
+ if (S_ISDIR(statbuf.st_mode)) {
+ possibleMatch = findZoneinfoFile(buf, size, pathname);
+ } else if (S_ISREG(statbuf.st_mode) && (size_t)statbuf.st_size == size) {
+ dbuf = (char *) malloc(size);
+ if (dbuf == NULL) {
+ return NULL;
+ }
+ if ((fd = open(pathname, O_RDONLY)) == -1) {
+ goto freedata;
+ }
+ if (read(fd, dbuf, size) != (ssize_t) size) {
+ goto freedata;
+ }
+ if (memcmp(buf, dbuf, size) == 0) {
+ possibleMatch = getZoneName(pathname);
+ if (possibleMatch != NULL) {
+ possibleMatch = strdup(possibleMatch);
+ }
+ }
+ freedata:
+ free((void *) dbuf);
+ dbuf = NULL;
(void) close(fd);
}
- if (dbuf != NULL) {
- free((void *) dbuf);
- }
- return tz;
+ return possibleMatch;
}
#if defined(__linux__) || defined(MACOSX)
diff --git a/jdk/src/solaris/native/sun/awt/gtk_interface.c b/jdk/src/solaris/native/sun/awt/gtk_interface.c
index 8157efe..42db9b6 100644
--- a/jdk/src/solaris/native/sun/awt/gtk_interface.c
+++ b/jdk/src/solaris/native/sun/awt/gtk_interface.c
@@ -45,18 +45,18 @@
static GtkLib gtk_libs[] = {
{
- GTK_2,
- JNI_LIB_NAME("gtk-x11-2.0"),
- VERSIONED_JNI_LIB_NAME("gtk-x11-2.0", "0"),
- >k2_load,
- >k2_check
- },
- {
GTK_3,
JNI_LIB_NAME("gtk-3"),
VERSIONED_JNI_LIB_NAME("gtk-3", "0"),
>k3_load,
>k3_check
+ },
+ {
+ GTK_2,
+ JNI_LIB_NAME("gtk-x11-2.0"),
+ VERSIONED_JNI_LIB_NAME("gtk-x11-2.0", "0"),
+ >k2_load,
+ >k2_check
}
};
diff --git a/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c b/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
index b4518af..7d1c058 100644
--- a/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
+++ b/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
@@ -78,6 +78,7 @@
static XImage * X11SD_GetImage(JNIEnv *env, X11SDOps *xsdo,
SurfaceDataBounds *bounds,
jint lockFlags);
+static int X11SD_GetBitmapPad(int pixelStride);
extern jfieldID validID;
@@ -438,11 +439,33 @@
xsdo->drawable = drawable;
xsdo->isPixmap = JNI_FALSE;
} else {
+ jboolean sizeIsInvalid = JNI_FALSE;
+ jlong scan = 0;
+
/*
* width , height must be nonzero otherwise XCreatePixmap
* generates BadValue in error_handler
*/
if (width <= 0 || height <= 0 || width > 32767 || height > 32767) {
+ sizeIsInvalid = JNI_TRUE;
+ } else {
+ XImage* tmpImg = NULL;
+
+ AWT_LOCK();
+ tmpImg = XCreateImage(awt_display,
+ xsdo->configData->awt_visInfo.visual,
+ depth, ZPixmap, 0, NULL, width, height,
+ X11SD_GetBitmapPad(xsdo->configData->pixelStride), 0);
+ if (tmpImg) {
+ scan = (jlong) tmpImg->bytes_per_line;
+ XDestroyImage(tmpImg);
+ tmpImg = NULL;
+ }
+ AWT_UNLOCK();
+ JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
+ }
+
+ if (sizeIsInvalid || (scan * height > 0x7FFFFFFFL)) {
JNU_ThrowOutOfMemoryError(env,
"Can't create offscreen surface");
return JNI_FALSE;
@@ -457,7 +480,7 @@
xsdo->pmHeight = height;
#ifdef MITSHM
- xsdo->shmPMData.pmSize = width * height * depth;
+ xsdo->shmPMData.pmSize = (jlong) width * height * depth;
xsdo->shmPMData.pixelsReadThreshold = width * height / 8;
if (forceSharedPixmaps) {
AWT_LOCK();
@@ -560,7 +583,7 @@
return NULL;
}
shminfo->shmid =
- shmget(IPC_PRIVATE, height * img->bytes_per_line,
+ shmget(IPC_PRIVATE, (size_t) height * img->bytes_per_line,
IPC_CREAT|mitShmPermissionMask);
if (shminfo->shmid < 0) {
J2dRlsTraceLn1(J2D_TRACE_ERROR,
@@ -622,7 +645,7 @@
XSync(awt_display, False);
retImage = cachedXImage;
cachedXImage = (XImage *)NULL;
- } else if (width * height * xsdo->depth > 0x10000) {
+ } else if ((jlong) width * height * xsdo->depth > 0x10000) {
retImage = X11SD_CreateSharedImage(xsdo, width, height);
}
return retImage;
@@ -978,7 +1001,7 @@
int scan = xpriv->img->bytes_per_line;
xpriv->x = x;
xpriv->y = y;
- pRasInfo->rasBase = xpriv->img->data - x * mult - y * scan;
+ pRasInfo->rasBase = xpriv->img->data - x * mult - (intptr_t) y * scan;
pRasInfo->pixelStride = mult;
pRasInfo->pixelBitOffset = 0;
pRasInfo->scanStride = scan;
@@ -1140,8 +1163,8 @@
static void
X11SD_SwapBytes(X11SDOps *xsdo, XImage * img, int depth, int bpp) {
- int lengthInBytes = img->height * img->bytes_per_line;
- int i;
+ jlong lengthInBytes = (jlong) img->height * img->bytes_per_line;
+ jlong i;
switch (depth) {
case 12:
@@ -1214,7 +1237,7 @@
Drawable drawable;
int depth = xsdo->depth;
int mult = xsdo->configData->pixelStride;
- int pad = (mult == 3) ? 32 : mult * 8; // pad must be 8, 16, or 32
+ int pad = X11SD_GetBitmapPad(mult);
jboolean readBits = lockFlags & SD_LOCK_NEED_PIXELS;
x = bounds->x1;
@@ -1280,7 +1303,7 @@
}
scan = img->bytes_per_line;
- img->data = malloc(h * scan);
+ img->data = malloc((size_t) h * scan);
if (img->data == NULL) {
XFree(img);
return NULL;
@@ -1315,7 +1338,7 @@
int i;
img_addr = img->data +
- (temp.y1 - y) * scan + (temp.x1 - x) * mult;
+ (intptr_t) (temp.y1 - y) * scan + (temp.x1 - x) * mult;
temp_scan = temp_image->bytes_per_line;
temp_addr = temp_image->data;
bytes_to_copy = (temp.x2 - temp.x1) * mult;
@@ -1349,7 +1372,7 @@
return NULL;
}
- img->data = malloc(h * img->bytes_per_line);
+ img->data = malloc((size_t) h * img->bytes_per_line);
if (img->data == NULL) {
XFree(img);
return NULL;
@@ -1532,6 +1555,11 @@
#endif /* MITSHM */
}
+static int X11SD_GetBitmapPad(int pixelStride) {
+ // pad must be 8, 16, or 32
+ return (pixelStride == 3) ? 32 : pixelStride * 8;
+}
+
#endif /* !HEADLESS */
/*
diff --git a/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h b/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h
index 91ad462..cc8ae6a 100644
--- a/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h
+++ b/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h
@@ -81,7 +81,7 @@
XShmSegmentInfo *shmSegInfo; /* Shared Memory Segment Info */
jint bytesPerLine; /* needed for ShMem lock */
jboolean xRequestSent; /* true if x request is sent w/o XSync */
- jint pmSize;
+ jlong pmSize;
jboolean usingShmPixmap;
Drawable pixmap;
diff --git a/jdk/src/windows/classes/java/lang/ProcessImpl.java b/jdk/src/windows/classes/java/lang/ProcessImpl.java
index 37c3237..1970260 100644
--- a/jdk/src/windows/classes/java/lang/ProcessImpl.java
+++ b/jdk/src/windows/classes/java/lang/ProcessImpl.java
@@ -520,11 +520,15 @@
if (timeout <= 0) return false;
long remainingNanos = unit.toNanos(timeout);
- long deadline = System.nanoTime() + remainingNanos ;
+ long deadline = System.nanoTime() + remainingNanos;
do {
// Round up to next millisecond
long msTimeout = TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L);
+ if (msTimeout < 0) {
+ // if wraps around then wait a long while
+ msTimeout = Integer.MAX_VALUE;
+ }
waitForTimeoutInterruptibly(handle, msTimeout);
if (Thread.interrupted())
throw new InterruptedException();
@@ -538,7 +542,7 @@
}
private static native void waitForTimeoutInterruptibly(
- long handle, long timeout);
+ long handle, long timeoutMillis);
public void destroy() { terminateProcess(handle); }
diff --git a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
index add8f73..bc4039a 100644
--- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
+++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,8 @@
package sun.awt.shell;
-import java.awt.*;
+import java.awt.Image;
+import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
@@ -33,14 +34,29 @@
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
-import java.util.concurrent.*;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
-import static sun.awt.shell.Win32ShellFolder2.*;
import sun.awt.OSInfo;
import sun.misc.ThreadGroupUtils;
+import sun.util.logging.PlatformLogger;
+
+import static sun.awt.shell.Win32ShellFolder2.DESKTOP;
+import static sun.awt.shell.Win32ShellFolder2.DRIVES;
+import static sun.awt.shell.Win32ShellFolder2.Invoker;
+import static sun.awt.shell.Win32ShellFolder2.NETWORK;
+import static sun.awt.shell.Win32ShellFolder2.PERSONAL;
+import static sun.awt.shell.Win32ShellFolder2.RECENT;
// NOTE: This class supersedes Win32ShellFolderManager, which was removed
// from distribution after version 1.4.2.
@@ -54,6 +70,9 @@
public class Win32ShellFolderManager2 extends ShellFolderManager {
+ private static final PlatformLogger
+ log = PlatformLogger.getLogger("sun.awt.shell.Win32ShellFolderManager2");
+
static {
// Load library here
sun.awt.windows.WToolkit.loadLibraries();
@@ -137,12 +156,13 @@
if (desktop == null) {
try {
desktop = new Win32ShellFolder2(DESKTOP);
- } catch (SecurityException e) {
- // Ignore error
- } catch (IOException e) {
- // Ignore error
- } catch (InterruptedException e) {
- // Ignore error
+ } catch (final SecurityException ignored) {
+ // Ignore, the message may have sensitive information, not
+ // accessible other ways
+ } catch (IOException | InterruptedException e) {
+ if (log.isLoggable(PlatformLogger.Level.WARNING)) {
+ log.warning("Cannot access 'Desktop'", e);
+ }
}
}
return desktop;
@@ -152,12 +172,13 @@
if (drives == null) {
try {
drives = new Win32ShellFolder2(DRIVES);
- } catch (SecurityException e) {
- // Ignore error
- } catch (IOException e) {
- // Ignore error
- } catch (InterruptedException e) {
- // Ignore error
+ } catch (final SecurityException ignored) {
+ // Ignore, the message may have sensitive information, not
+ // accessible other ways
+ } catch (IOException | InterruptedException e) {
+ if (log.isLoggable(PlatformLogger.Level.WARNING)) {
+ log.warning("Cannot access 'Drives'", e);
+ }
}
}
return drives;
@@ -170,12 +191,13 @@
if (path != null) {
recent = createShellFolder(getDesktop(), new File(path));
}
- } catch (SecurityException e) {
- // Ignore error
- } catch (InterruptedException e) {
- // Ignore error
- } catch (IOException e) {
- // Ignore error
+ } catch (final SecurityException ignored) {
+ // Ignore, the message may have sensitive information, not
+ // accessible other ways
+ } catch (InterruptedException | IOException e) {
+ if (log.isLoggable(PlatformLogger.Level.WARNING)) {
+ log.warning("Cannot access 'Recent'", e);
+ }
}
}
return recent;
@@ -185,12 +207,13 @@
if (network == null) {
try {
network = new Win32ShellFolder2(NETWORK);
- } catch (SecurityException e) {
- // Ignore error
- } catch (IOException e) {
- // Ignore error
- } catch (InterruptedException e) {
- // Ignore error
+ } catch (final SecurityException ignored) {
+ // Ignore, the message may have sensitive information, not
+ // accessible other ways
+ } catch (IOException | InterruptedException e) {
+ if (log.isLoggable(PlatformLogger.Level.WARNING)) {
+ log.warning("Cannot access 'Network'", e);
+ }
}
}
return network;
@@ -210,12 +233,13 @@
personal.setIsPersonal();
}
}
- } catch (SecurityException e) {
- // Ignore error
- } catch (InterruptedException e) {
- // Ignore error
- } catch (IOException e) {
- // Ignore error
+ } catch (final SecurityException ignored) {
+ // Ignore, the message may have sensitive information, not
+ // accessible other ways
+ } catch (InterruptedException | IOException e) {
+ if (log.isLoggable(PlatformLogger.Level.WARNING)) {
+ log.warning("Cannot access 'Personal'", e);
+ }
}
}
return personal;
@@ -316,8 +340,14 @@
folders.add(createShellFolder(new File((String)value)));
}
} catch (IOException e) {
+ if (log.isLoggable(PlatformLogger.Level.WARNING)) {
+ log.warning("Cannot read value = " + value, e);
+ }
// Skip this value
} catch (InterruptedException e) {
+ if (log.isLoggable(PlatformLogger.Level.WARNING)) {
+ log.warning("Cannot read value = " + value, e);
+ }
// Return empty result
return new File[0];
}
diff --git a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java
index a436d58..5839a5e 100644
--- a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java
+++ b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Kinit.java
@@ -36,7 +36,6 @@
import sun.security.krb5.internal.ccache.*;
import java.io.IOException;
import java.util.Arrays;
-import javax.security.auth.kerberos.KerberosPrincipal;
import sun.security.util.Password;
import javax.security.auth.kerberos.KeyTab;
@@ -53,22 +52,9 @@
/**
* The main method is used to accept user command line input for ticket
- * request.
- * <p>
- * Usage: kinit [-A] [-f] [-p] [-c cachename] [[-k [-t keytab_file_name]]
- * [principal] [password]
- * <ul>
- * <li> -A do not include addresses
- * <li> -f forwardable
- * <li> -p proxiable
- * <li> -c cache name (i.e., FILE://c:\temp\mykrb5cc)
- * <li> -k use keytab
- * <li> -t keytab file name
- * <li> principal the principal name (i.e., duke@java.sun.com)
- * <li> password the principal's Kerberos password
- * </ul>
- * <p>
- * Use java sun.security.krb5.tools.Kinit -help to bring up help menu.
+ * request. Read {@link KinitOptions#printHelp} for usages or call
+ * java sun.security.krb5.internal.tools.Kinit -help
+ * to bring up help menu.
* <p>
* We currently support only file-based credentials cache to
* store the tickets obtained from the KDC.
@@ -146,6 +132,49 @@
} else {
options = new KinitOptions(args);
}
+ switch (options.action) {
+ case 1:
+ acquire();
+ break;
+ case 2:
+ renew();
+ break;
+ default:
+ throw new KrbException("kinit does not support action "
+ + options.action);
+ }
+ }
+
+ private void renew()
+ throws IOException, RealmException, KrbException {
+
+ PrincipalName principal = options.getPrincipal();
+ String realm = principal.getRealmAsString();
+ CredentialsCache cache = CredentialsCache.getInstance(options.cachename);
+
+ if (cache == null) {
+ throw new IOException("Unable to find existing cache file " +
+ options.cachename);
+ }
+ sun.security.krb5.internal.ccache.Credentials credentials =
+ cache.getCreds(PrincipalName.tgsService(realm, realm));
+
+ credentials = credentials.setKrbCreds()
+ .renew()
+ .toCCacheCreds();
+
+ cache = CredentialsCache.create(principal, options.cachename);
+ if (cache == null) {
+ throw new IOException("Unable to create the cache file " +
+ options.cachename);
+ }
+ cache.update(credentials);
+ cache.save();
+ }
+
+ private void acquire()
+ throws IOException, RealmException, KrbException {
+
String princName = null;
PrincipalName principal = options.getPrincipal();
if (principal != null) {
@@ -216,6 +245,9 @@
if (options.getAddressOption())
builder.setAddresses(HostAddresses.getLocalAddresses());
+ builder.setTill(options.lifetime);
+ builder.setRTime(options.renewable_lifetime);
+
builder.action();
sun.security.krb5.internal.ccache.Credentials credentials =
diff --git a/jdk/src/windows/classes/sun/security/krb5/internal/tools/KinitOptions.java b/jdk/src/windows/classes/sun/security/krb5/internal/tools/KinitOptions.java
index e7507a0..23bfeca 100644
--- a/jdk/src/windows/classes/sun/security/krb5/internal/tools/KinitOptions.java
+++ b/jdk/src/windows/classes/sun/security/krb5/internal/tools/KinitOptions.java
@@ -33,12 +33,8 @@
import sun.security.krb5.*;
import sun.security.krb5.internal.*;
import sun.security.krb5.internal.ccache.*;
-import java.io.File;
import java.io.IOException;
-import java.util.StringTokenizer;
-import java.util.Vector;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
+import java.time.Instant;
import java.io.FileInputStream;
/**
@@ -49,14 +45,15 @@
* @author Ram Marti
*/
class KinitOptions {
- public boolean validate = false;
+
+ // 1. acquire, 2. renew, 3. validate
+ public int action = 1;
// forwardable and proxiable flags have two states:
// -1 - flag set to be not forwardable or proxiable;
// 1 - flag set to be forwardable or proxiable.
- public short forwardable = -1;
- public short proxiable = -1;
- public boolean renew = false;
+ public short forwardable = 0;
+ public short proxiable = 0;
public KerberosTime lifetime;
public KerberosTime renewable_lifetime;
public String target_service;
@@ -134,6 +131,12 @@
}
useKeytab = true;
+ } else if (args[i].equals("-R")) {
+ action = 2;
+ } else if (args[i].equals("-l")) {
+ lifetime = getTime(Config.duration(args[++i]));
+ } else if (args[i].equals("-r")) {
+ renewable_lifetime = getTime(Config.duration(args[++i]));
} else if (args[i].equalsIgnoreCase("-help")) {
printHelp();
System.exit(0);
@@ -223,23 +226,28 @@
void printHelp() {
- System.out.println("Usage: kinit " +
- "[-A] [-f] [-p] [-c cachename] " +
- "[[-k [-t keytab_file_name]] [principal] " +
+ System.out.println("Usage:\n\n1. Initial ticket request:\n" +
+ " kinit [-A] [-f] [-p] [-c cachename] " +
+ "[-l lifetime] [-r renewable_time]\n" +
+ " [[-k [-t keytab_file_name]] [principal] " +
"[password]");
- System.out.println("\tavailable options to " +
+ System.out.println("2. Renew a ticket:\n" +
+ " kinit -R [-c cachename] [principal]");
+ System.out.println("\nAvailable options to " +
"Kerberos 5 ticket request:");
- System.out.println("\t -A do not include addresses");
- System.out.println("\t -f forwardable");
- System.out.println("\t -p proxiable");
- System.out.println("\t -c cache name " +
- "(i.e., FILE:\\d:\\myProfiles\\mykrb5cache)");
- System.out.println("\t -k use keytab");
- System.out.println("\t -t keytab file name");
- System.out.println("\t principal the principal name "+
- "(i.e., qweadf@ATHENA.MIT.EDU qweadf)");
- System.out.println("\t password " +
- "the principal's Kerberos password");
+ System.out.println("\t-A do not include addresses");
+ System.out.println("\t-f forwardable");
+ System.out.println("\t-p proxiable");
+ System.out.println("\t-c cache name " +
+ "(i.e., FILE:\\d:\\myProfiles\\mykrb5cache)");
+ System.out.println("\t-l lifetime");
+ System.out.println("\t-r renewable time " +
+ "(total lifetime a ticket can be renewed)");
+ System.out.println("\t-k use keytab");
+ System.out.println("\t-t keytab file name");
+ System.out.println("\tprincipal the principal name "+
+ "(i.e., qweadf@ATHENA.MIT.EDU qweadf)");
+ System.out.println("\tpassword the principal's Kerberos password");
}
public boolean getAddressOption() {
@@ -257,4 +265,8 @@
public PrincipalName getPrincipal() {
return principal;
}
+
+ private KerberosTime getTime(int s) {
+ return new KerberosTime(Instant.now().plusSeconds(s));
+ }
}
diff --git a/jdk/src/windows/classes/sun/security/mscapi/CKey.java b/jdk/src/windows/classes/sun/security/mscapi/CKey.java
new file mode 100644
index 0000000..84d3e82
--- /dev/null
+++ b/jdk/src/windows/classes/sun/security/mscapi/CKey.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.mscapi;
+
+import sun.security.util.KeyUtil;
+import sun.security.util.Length;
+
+import java.math.BigInteger;
+import java.security.Key;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+
+/**
+ * The handle for a key using the Microsoft Crypto API.
+ *
+ * @see CPrivateKey
+ * @see CPublicKey
+ *
+ * @since 1.6
+ * @author Stanley Man-Kit Ho
+ */
+abstract class CKey implements Key, Length {
+ private static final long serialVersionUID = -1088859394025049194L;
+
+ static class NativeHandles {
+
+ long hCryptProv = 0;
+ long hCryptKey = 0;
+
+ public NativeHandles(long hCryptProv, long hCryptKey) {
+ this.hCryptProv = hCryptProv;
+ this.hCryptKey = hCryptKey;
+ }
+
+ @SuppressWarnings("deprecation")
+ protected void finalize() throws Throwable {
+ try {
+ synchronized(this) {
+ cleanUp(hCryptProv, hCryptKey);
+ hCryptProv = 0;
+ hCryptKey = 0;
+ }
+
+ } finally {
+ super.finalize();
+ }
+ }
+ }
+
+ protected final NativeHandles handles;
+
+ protected final int keyLength;
+
+ protected final String algorithm;
+
+ protected CKey(String algorithm, NativeHandles handles, int keyLength) {
+ this.algorithm = algorithm;
+ this.handles = handles;
+ this.keyLength = keyLength;
+ }
+
+ // Native method to cleanup the key handle.
+ private native static void cleanUp(long hCryptProv, long hCryptKey);
+
+ @Override
+ public int length() {
+ return keyLength;
+ }
+
+ public long getHCryptKey() {
+ return handles.hCryptKey;
+ }
+
+ public long getHCryptProvider() {
+ return handles.hCryptProv;
+ }
+
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ protected native static String getContainerName(long hCryptProv);
+
+ protected native static String getKeyType(long hCryptKey);
+
+ // This java method generates EC BLOBs for public key or private key.
+ // See https://docs.microsoft.com/en-us/windows/desktop/api/bcrypt/ns-bcrypt-_bcrypt_ecckey_blob
+ static byte[] generateECBlob(Key k) {
+
+ int keyBitLength = KeyUtil.getKeySize(k);
+ int keyLen = (keyBitLength + 7) / 8;
+ boolean isPrivate = k instanceof ECPrivateKey;
+
+ byte[] keyBlob = new byte[8 + keyLen * (isPrivate ? 3 : 2)];
+ keyBlob[0] = 'E';
+ keyBlob[1] = 'C';
+ keyBlob[2] = 'S';
+ if (isPrivate) {
+ keyBlob[3] = (byte) (keyBitLength == 256 ? '2'
+ : (keyBitLength == 384 ? '4' : '6'));
+ } else {
+ keyBlob[3] = (byte) (keyBitLength == 256 ? '1'
+ : (keyBitLength == 384 ? '3' : '5'));
+ }
+ BigInteger x;
+ BigInteger y;
+ // Fill the array in reverse order (s -> y -> x -> len) in case
+ // one BigInteger encoding has an extra 0 at the beginning
+ if (isPrivate) {
+ // We can keep X and Y zero and it still works
+ ECPrivateKey prk = (ECPrivateKey)k;
+ BigInteger s = prk.getS();
+ byte[] bs = s.toByteArray();
+ System.arraycopy(
+ bs, 0,
+ keyBlob, 8 + keyLen + keyLen + keyLen - bs.length,
+ bs.length);
+ } else {
+ ECPublicKey puk = (ECPublicKey)k;
+ x = puk.getW().getAffineX();
+ y = puk.getW().getAffineY();
+ byte[] by = y.toByteArray();
+ System.arraycopy(by, 0, keyBlob, 8 + keyLen + keyLen - by.length,
+ by.length);
+ byte[] bx = x.toByteArray();
+ System.arraycopy(bx, 0, keyBlob, 8 + keyLen - bx.length, bx.length);
+ }
+ keyBlob[4] = (byte) keyLen;
+ keyBlob[5] = keyBlob[6] = keyBlob[7] = 0;
+ return keyBlob;
+ }
+}
diff --git a/jdk/src/windows/classes/sun/security/mscapi/RSAKeyPair.java b/jdk/src/windows/classes/sun/security/mscapi/CKeyPair.java
similarity index 70%
rename from jdk/src/windows/classes/sun/security/mscapi/RSAKeyPair.java
rename to jdk/src/windows/classes/sun/security/mscapi/CKeyPair.java
index 0880c20..ce0f1a2 100644
--- a/jdk/src/windows/classes/sun/security/mscapi/RSAKeyPair.java
+++ b/jdk/src/windows/classes/sun/security/mscapi/CKeyPair.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,27 +30,26 @@
*
* @since 1.6
*/
-class RSAKeyPair {
+class CKeyPair {
- private final RSAPrivateKey privateKey;
+ private final CPrivateKey privateKey;
- private final RSAPublicKey publicKey;
+ private final CPublicKey publicKey;
/**
- * Construct an RSAKeyPair object.
+ * This method is called by native codes in security.cpp.
*/
- RSAKeyPair(long hCryptProv, long hCryptKey, int keyLength)
- {
- Key.NativeHandles handles = new Key.NativeHandles(hCryptProv, hCryptKey);
- privateKey = new RSAPrivateKey(handles, keyLength);
- publicKey = new RSAPublicKey(handles, keyLength);
+ CKeyPair(String alg, long hCryptProv, long hCryptKey, int keyLength) {
+ CKey.NativeHandles handles = new CKey.NativeHandles(hCryptProv, hCryptKey);
+ privateKey = CPrivateKey.of(alg, handles, keyLength);
+ publicKey = CPublicKey.of(alg, handles, keyLength);
}
- public RSAPrivateKey getPrivate() {
+ public CPrivateKey getPrivate() {
return privateKey;
}
- public RSAPublicKey getPublic() {
+ public CPublicKey getPublic() {
return publicKey;
}
}
diff --git a/jdk/src/windows/classes/sun/security/mscapi/CKeyPairGenerator.java b/jdk/src/windows/classes/sun/security/mscapi/CKeyPairGenerator.java
new file mode 100644
index 0000000..2745b93
--- /dev/null
+++ b/jdk/src/windows/classes/sun/security/mscapi/CKeyPairGenerator.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.mscapi;
+
+import java.util.UUID;
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.RSAKeyGenParameterSpec;
+
+import sun.security.rsa.RSAKeyFactory;
+import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
+
+/**
+ * RSA keypair generator.
+ *
+ * Standard algorithm, minimum key length is 512 bit, maximum is 16,384.
+ * Generates a private key that is exportable.
+ *
+ * @since 1.6
+ */
+public abstract class CKeyPairGenerator extends KeyPairGeneratorSpi {
+
+ protected String keyAlg;
+
+ public CKeyPairGenerator(String keyAlg) {
+ this.keyAlg = keyAlg;
+ }
+
+ public static class RSA extends CKeyPairGenerator {
+ public RSA() {
+ super("RSA");
+ // initialize to default in case the app does not call initialize()
+ initialize(DEF_RSA_KEY_SIZE, null);
+ }
+
+ // Supported by Microsoft Base, Strong and Enhanced Cryptographic Providers
+ static final int KEY_SIZE_MIN = 512; // disallow MSCAPI min. of 384
+ static final int KEY_SIZE_MAX = 16384;
+
+ // size of the key to generate, KEY_SIZE_MIN <= keySize <= KEY_SIZE_MAX
+ private int keySize;
+
+ // initialize the generator. See JCA doc
+ // random is always ignored
+ @Override
+ public void initialize(int keySize, SecureRandom random) {
+
+ try {
+ RSAKeyFactory.checkKeyLengths(keySize, null,
+ KEY_SIZE_MIN, KEY_SIZE_MAX);
+ } catch (InvalidKeyException e) {
+ throw new InvalidParameterException(e.getMessage());
+ }
+
+ this.keySize = keySize;
+ }
+
+ // second initialize method. See JCA doc
+ // random and exponent are always ignored
+ @Override
+ public void initialize(AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidAlgorithmParameterException {
+
+ int tmpSize;
+ if (params == null) {
+ tmpSize = DEF_RSA_KEY_SIZE;
+ } else if (params instanceof RSAKeyGenParameterSpec) {
+
+ if (((RSAKeyGenParameterSpec) params).getPublicExponent() != null) {
+ throw new InvalidAlgorithmParameterException
+ ("Exponent parameter is not supported");
+ }
+ tmpSize = ((RSAKeyGenParameterSpec) params).getKeysize();
+
+ } else {
+ throw new InvalidAlgorithmParameterException
+ ("Params must be an instance of RSAKeyGenParameterSpec");
+ }
+
+ try {
+ RSAKeyFactory.checkKeyLengths(tmpSize, null,
+ KEY_SIZE_MIN, KEY_SIZE_MAX);
+ } catch (InvalidKeyException e) {
+ throw new InvalidAlgorithmParameterException(
+ "Invalid Key sizes", e);
+ }
+
+ this.keySize = tmpSize;
+ }
+
+ // generate the keypair. See JCA doc
+ @Override
+ public KeyPair generateKeyPair() {
+
+ try {
+ // Generate each keypair in a unique key container
+ CKeyPair keys =
+ generateCKeyPair(keyAlg, keySize,
+ "{" + UUID.randomUUID().toString() + "}");
+ return new KeyPair(keys.getPublic(), keys.getPrivate());
+
+ } catch (KeyException e) {
+ throw new ProviderException(e);
+ }
+ }
+
+ private static native CKeyPair generateCKeyPair(String alg, int keySize,
+ String keyContainerName) throws KeyException;
+ }
+}
diff --git a/jdk/src/windows/classes/sun/security/mscapi/KeyStore.java b/jdk/src/windows/classes/sun/security/mscapi/CKeyStore.java
similarity index 86%
rename from jdk/src/windows/classes/sun/security/mscapi/KeyStore.java
rename to jdk/src/windows/classes/sun/security/mscapi/CKeyStore.java
index 6ad2ed0..9e2f8a3 100644
--- a/jdk/src/windows/classes/sun/security/mscapi/KeyStore.java
+++ b/jdk/src/windows/classes/sun/security/mscapi/CKeyStore.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,8 +31,10 @@
import java.io.OutputStream;
import java.security.AccessController;
import java.security.InvalidKeyException;
+import java.security.Key;
import java.security.KeyStoreSpi;
import java.security.KeyStoreException;
+import java.security.PrivilegedAction;
import java.security.UnrecoverableKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecurityPermission;
@@ -43,8 +45,6 @@
import java.security.interfaces.RSAPrivateCrtKey;
import java.util.*;
-import sun.security.action.GetPropertyAction;
-
import sun.security.util.Debug;
/**
@@ -52,31 +52,30 @@
*
* @since 1.6
*/
-abstract class KeyStore extends KeyStoreSpi {
+abstract class CKeyStore extends KeyStoreSpi {
- public static final class MY extends KeyStore {
+ public static final class MY extends CKeyStore {
public MY() {
super("MY");
}
}
- public static final class ROOT extends KeyStore {
+ public static final class ROOT extends CKeyStore {
public ROOT() {
super("ROOT");
}
}
- class KeyEntry
- {
- private Key privateKey;
- private X509Certificate certChain[];
+ class KeyEntry {
+ private CKey privateKey;
+ private X509Certificate[] certChain;
private String alias;
- KeyEntry(Key key, X509Certificate[] chain) {
+ KeyEntry(CKey key, X509Certificate[] chain) {
this(null, key, chain);
}
- KeyEntry(String alias, Key key, X509Certificate[] chain) {
+ KeyEntry(String alias, CKey key, X509Certificate[] chain) {
this.privateKey = key;
this.certChain = chain;
/*
@@ -93,16 +92,14 @@
/**
* Gets the alias for the keystore entry.
*/
- String getAlias()
- {
+ String getAlias() {
return alias;
}
/**
* Sets the alias for the keystore entry.
*/
- void setAlias(String alias)
- {
+ void setAlias(String alias) {
// TODO - set friendly name prop in cert store
this.alias = alias;
}
@@ -110,44 +107,42 @@
/**
* Gets the private key for the keystore entry.
*/
- Key getPrivateKey()
- {
+ CKey getPrivateKey() {
return privateKey;
}
/**
* Sets the private key for the keystore entry.
*/
- void setPrivateKey(RSAPrivateCrtKey key)
- throws InvalidKeyException, KeyStoreException
- {
+ void setRSAPrivateKey(Key k)
+ throws InvalidKeyException, KeyStoreException {
+ RSAPrivateCrtKey key = (RSAPrivateCrtKey) k;
byte[] modulusBytes = key.getModulus().toByteArray();
// Adjust key length due to sign bit
int keyBitLength = (modulusBytes[0] == 0)
- ? (modulusBytes.length - 1) * 8
- : modulusBytes.length * 8;
+ ? (modulusBytes.length - 1) * 8
+ : modulusBytes.length * 8;
- byte[] keyBlob = generatePrivateKeyBlob(
- keyBitLength,
- modulusBytes,
- key.getPublicExponent().toByteArray(),
- key.getPrivateExponent().toByteArray(),
- key.getPrimeP().toByteArray(),
- key.getPrimeQ().toByteArray(),
- key.getPrimeExponentP().toByteArray(),
- key.getPrimeExponentQ().toByteArray(),
- key.getCrtCoefficient().toByteArray());
+ byte[] keyBlob = generateRSAPrivateKeyBlob(
+ keyBitLength,
+ modulusBytes,
+ key.getPublicExponent().toByteArray(),
+ key.getPrivateExponent().toByteArray(),
+ key.getPrimeP().toByteArray(),
+ key.getPrimeQ().toByteArray(),
+ key.getPrimeExponentP().toByteArray(),
+ key.getPrimeExponentQ().toByteArray(),
+ key.getCrtCoefficient().toByteArray());
- privateKey = storePrivateKey(Objects.requireNonNull(keyBlob),
- "{" + UUID.randomUUID().toString() + "}", keyBitLength);
+ privateKey = storePrivateKey("RSA", Objects.requireNonNull(keyBlob),
+ "{" + UUID.randomUUID().toString() + "}", keyBitLength);
}
/**
* Gets the certificate chain for the keystore entry.
*/
- X509Certificate[] getCertificateChain()
- {
+ X509Certificate[] getCertificateChain() {
return certChain;
}
@@ -155,8 +150,7 @@
* Sets the certificate chain for the keystore entry.
*/
void setCertificateChain(X509Certificate[] chain)
- throws CertificateException, KeyStoreException
- {
+ throws CertificateException, KeyStoreException {
for (int i = 0; i < chain.length; i++) {
byte[] encoding = chain[i].getEncoded();
if (i == 0 && privateKey != null) {
@@ -203,11 +197,10 @@
*/
private final String storeName;
- KeyStore(String storeName) {
+ CKeyStore(String storeName) {
// Get the compatibility mode
- String prop =
- AccessController.doPrivileged(
- new GetPropertyAction(KEYSTORE_COMPATIBILITY_MODE_PROP));
+ String prop = AccessController.doPrivileged(
+ (PrivilegedAction<String>) () -> System.getProperty(KEYSTORE_COMPATIBILITY_MODE_PROP));
if ("false".equalsIgnoreCase(prop)) {
keyStoreCompatibilityMode = false;
@@ -242,8 +235,7 @@
* @exception UnrecoverableKeyException if the key cannot be recovered.
*/
public java.security.Key engineGetKey(String alias, char[] password)
- throws NoSuchAlgorithmException, UnrecoverableKeyException
- {
+ throws NoSuchAlgorithmException, UnrecoverableKeyException {
if (alias == null) {
return null;
}
@@ -272,8 +264,7 @@
* alias identifies either a <i>trusted certificate entry</i> or a
* <i>key entry</i> without a certificate chain).
*/
- public Certificate[] engineGetCertificateChain(String alias)
- {
+ public Certificate[] engineGetCertificateChain(String alias) {
if (alias == null) {
return null;
}
@@ -302,8 +293,7 @@
* @return the certificate, or null if the given alias does not exist or
* does not contain a certificate.
*/
- public Certificate engineGetCertificate(String alias)
- {
+ public Certificate engineGetCertificate(String alias) {
if (alias == null) {
return null;
}
@@ -366,8 +356,7 @@
* some other reason.
*/
public void engineSetKeyEntry(String alias, java.security.Key key,
- char[] password, Certificate[] chain) throws KeyStoreException
- {
+ char[] password, Certificate[] chain) throws KeyStoreException {
if (alias == null) {
throw new KeyStoreException("alias must not be null");
}
@@ -402,7 +391,7 @@
entry.setAlias(alias);
try {
- entry.setPrivateKey((RSAPrivateCrtKey) key);
+ entry.setRSAPrivateKey(key);
entry.setCertificateChain(xchain);
} catch (CertificateException ce) {
@@ -443,8 +432,7 @@
*/
public void engineSetKeyEntry(String alias, byte[] key,
Certificate[] chain)
- throws KeyStoreException
- {
+ throws KeyStoreException {
throw new UnsupportedOperationException(
"Cannot assign the encoded key to the given alias.");
}
@@ -464,8 +452,7 @@
* fails for some other reason.
*/
public void engineSetCertificateEntry(String alias, Certificate cert)
- throws KeyStoreException
- {
+ throws KeyStoreException {
if (alias == null) {
throw new KeyStoreException("alias must not be null");
}
@@ -507,9 +494,7 @@
*
* @exception KeyStoreException if the entry cannot be removed.
*/
- public void engineDeleteEntry(String alias)
- throws KeyStoreException
- {
+ public void engineDeleteEntry(String alias) throws KeyStoreException {
if (alias == null) {
throw new KeyStoreException("alias must not be null");
}
@@ -518,7 +503,7 @@
if (entry != null) {
// Get end-entity certificate and remove from system cert store
X509Certificate[] certChain = entry.getCertificateChain();
- if (certChain != null) {
+ if (certChain != null && certChain.length > 0) {
try {
@@ -530,10 +515,10 @@
throw new KeyStoreException("Cannot remove entry: ", e);
}
}
- Key privateKey = entry.getPrivateKey();
+ CKey privateKey = entry.getPrivateKey();
if (privateKey != null) {
destroyKeyContainer(
- Key.getContainerName(privateKey.getHCryptProvider()));
+ CKey.getContainerName(privateKey.getHCryptProvider()));
}
}
}
@@ -546,15 +531,12 @@
public Enumeration<String> engineAliases() {
final Iterator<String> iter = entries.keySet().iterator();
- return new Enumeration<String>()
- {
- public boolean hasMoreElements()
- {
+ return new Enumeration<String>() {
+ public boolean hasMoreElements() {
return iter.hasNext();
}
- public String nextElement()
- {
+ public String nextElement() {
return iter.next();
}
};
@@ -634,7 +616,9 @@
for (Map.Entry<String,KeyEntry> mapEntry : entries.entrySet()) {
KeyEntry entry = mapEntry.getValue();
- if (entry.certChain != null && entry.certChain[0].equals(cert)) {
+ if (entry.certChain != null &&
+ entry.certChain.length > 0 &&
+ entry.certChain[0].equals(cert)) {
return entry.getAlias();
}
}
@@ -662,8 +646,7 @@
* parameter is non-null.
*/
public void engineStore(OutputStream stream, char[] password)
- throws IOException, NoSuchAlgorithmException, CertificateException
- {
+ throws IOException, NoSuchAlgorithmException, CertificateException {
if (stream != null && !keyStoreCompatibilityMode) {
throw new IOException("Keystore output stream must be null");
}
@@ -701,8 +684,7 @@
* this provider's <code>getName</code> method.
*/
public void engineLoad(InputStream stream, char[] password)
- throws IOException, NoSuchAlgorithmException, CertificateException
- {
+ throws IOException, NoSuchAlgorithmException, CertificateException {
if (stream != null && !keyStoreCompatibilityMode) {
throw new IOException("Keystore input stream must be null");
}
@@ -761,79 +743,67 @@
/**
* Generates a certificate chain from the collection of
* certificates and stores the result into a key entry.
- * This method is called by native code in libsunmscapi.
+ * <p>
+ * This method is called by native codes in security.cpp.
*/
private void generateCertificateChain(String alias,
- Collection<? extends Certificate> certCollection)
- {
- try
- {
+ Collection<? extends Certificate> certCollection) {
+ try {
X509Certificate[] certChain =
new X509Certificate[certCollection.size()];
int i = 0;
for (Iterator<? extends Certificate> iter =
- certCollection.iterator(); iter.hasNext(); i++)
- {
+ certCollection.iterator(); iter.hasNext(); i++) {
certChain[i] = (X509Certificate) iter.next();
}
storeWithUniqueAlias(alias,
new KeyEntry(alias, null, certChain));
- }
- catch (Throwable e)
- {
+ } catch (Throwable e) {
// Ignore the exception and skip this entry
- // If e is thrown, remember to deal with it in
- // native code.
+ // TODO - throw CertificateException?
}
}
/**
- * Generates RSA key and certificate chain from the private key handle,
+ * Generates key and certificate chain from the private key handle,
* collection of certificates and stores the result into key entries.
- * This method is called by native code in libsunmscapi.
+ * <p>
+ * This method is called by native codes in security.cpp.
*/
- private void generateRSAKeyAndCertificateChain(String alias,
- long hCryptProv, long hCryptKey, int keyLength,
- Collection<? extends Certificate> certCollection)
- {
- try
- {
+ private void generateKeyAndCertificateChain(boolean isRSA, String alias,
+ long hCryptProv, long hCryptKey, int keyLength,
+ Collection<? extends Certificate> certCollection) {
+ try {
X509Certificate[] certChain =
new X509Certificate[certCollection.size()];
int i = 0;
for (Iterator<? extends Certificate> iter =
- certCollection.iterator(); iter.hasNext(); i++)
- {
+ certCollection.iterator(); iter.hasNext(); i++) {
certChain[i] = (X509Certificate) iter.next();
}
-
storeWithUniqueAlias(alias, new KeyEntry(alias,
- new RSAPrivateKey(new Key.NativeHandles(hCryptProv,
- hCryptKey), keyLength),
+ CPrivateKey.of(isRSA ? "RSA" : "EC", hCryptProv, hCryptKey, keyLength),
certChain));
- }
- catch (Throwable e)
- {
+ } catch (Throwable e) {
// Ignore the exception and skip this entry
- // If e is thrown, remember to deal with it in
- // native code.
+ // TODO - throw CertificateException?
}
}
/**
* Generates certificates from byte data and stores into cert collection.
- * This method is called by native code in libsunmscapi.
+ * <p>
+ * This method is called by native codes in security.cpp.
*
* @param data Byte data.
* @param certCollection Collection of certificates.
*/
private void generateCertificate(byte[] data,
Collection<Certificate> certCollection) {
- try
- {
+ try {
ByteArrayInputStream bis = new ByteArrayInputStream(data);
// Obtain certificate factory
@@ -845,26 +815,19 @@
Collection<? extends Certificate> c =
certificateFactory.generateCertificates(bis);
certCollection.addAll(c);
- }
- catch (CertificateException e)
- {
+ } catch (CertificateException e) {
// Ignore the exception and skip this certificate
- // If e is thrown, remember to deal with it in
- // native code.
- }
- catch (Throwable te)
- {
+ // TODO - throw CertificateException?
+ } catch (Throwable te) {
// Ignore the exception and skip this certificate
- // If e is thrown, remember to deal with it in
- // native code.
+ // TODO - throw CertificateException?
}
}
/**
* Returns the name of the keystore.
*/
- private String getName()
- {
+ private String getName() {
return storeName;
}
@@ -909,7 +872,7 @@
/**
* Generates a private-key BLOB from a key's components.
*/
- private native byte[] generatePrivateKeyBlob(
+ private native byte[] generateRSAPrivateKeyBlob(
int keyBitLength,
byte[] modulus,
byte[] publicExponent,
@@ -920,6 +883,6 @@
byte[] exponentQ,
byte[] crtCoefficient) throws InvalidKeyException;
- private native RSAPrivateKey storePrivateKey(byte[] keyBlob,
+ private native CPrivateKey storePrivateKey(String alg, byte[] keyBlob,
String keyContainerName, int keySize) throws KeyStoreException;
}
diff --git a/jdk/src/windows/classes/sun/security/mscapi/CPrivateKey.java b/jdk/src/windows/classes/sun/security/mscapi/CPrivateKey.java
new file mode 100644
index 0000000..60fb4fb
--- /dev/null
+++ b/jdk/src/windows/classes/sun/security/mscapi/CPrivateKey.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.mscapi;
+
+import java.security.PrivateKey;
+
+/**
+ * The handle for a private key using the Microsoft Crypto API.
+ *
+ * @author Stanley Man-Kit Ho
+ * @since 1.6
+ */
+class CPrivateKey extends CKey implements PrivateKey {
+
+ private static final long serialVersionUID = 8113152807912338063L;
+
+ private CPrivateKey(String alg, NativeHandles handles, int keyLength) {
+ super(alg, handles, keyLength);
+ }
+
+ // Called by native code inside security.cpp
+ static CPrivateKey of(
+ String alg, long hCryptProv, long hCryptKey, int keyLength) {
+ return of(alg, new NativeHandles(hCryptProv, hCryptKey), keyLength);
+ }
+
+ public static CPrivateKey of(String alg, NativeHandles handles, int keyLength) {
+ return new CPrivateKey(alg, handles, keyLength);
+ }
+
+ // this key does not support encoding
+ public String getFormat() {
+ return null;
+ }
+
+ // this key does not support encoding
+ public byte[] getEncoded() {
+ return null;
+ }
+
+ public String toString() {
+ if (handles.hCryptKey != 0) {
+ return algorithm + "PrivateKey [size=" + keyLength + " bits, type=" +
+ getKeyType(handles.hCryptKey) + ", container=" +
+ getContainerName(handles.hCryptProv) + "]";
+ } else {
+ return algorithm + "PrivateKey [size=" + keyLength + " bits, type=CNG]";
+ }
+ }
+
+ // This class is not serializable
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException {
+ throw new java.io.NotSerializableException();
+ }
+}
diff --git a/jdk/src/windows/classes/sun/security/mscapi/CPublicKey.java b/jdk/src/windows/classes/sun/security/mscapi/CPublicKey.java
new file mode 100644
index 0000000..8a81c5d
--- /dev/null
+++ b/jdk/src/windows/classes/sun/security/mscapi/CPublicKey.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.mscapi;
+
+import java.math.BigInteger;
+import java.security.AlgorithmParameters;
+import java.security.KeyException;
+import java.security.KeyFactory;
+import java.security.KeyRep;
+import java.security.ProviderException;
+import java.security.PublicKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPublicKeySpec;
+import java.util.Arrays;
+
+import sun.security.rsa.RSAUtil.KeyType;
+import sun.security.rsa.RSAPublicKeyImpl;
+import sun.security.util.ECKeySizeParameterSpec;
+
+/**
+ * The handle for an RSA public key using the Microsoft Crypto API.
+ *
+ * @since 1.6
+ */
+public abstract class CPublicKey extends CKey implements PublicKey {
+
+ private static final long serialVersionUID = -2289561342425825391L;
+
+ protected byte[] encoding = null;
+
+ public static class CECPublicKey extends CPublicKey implements ECPublicKey {
+
+ private ECPoint w = null;
+ private static final long serialVersionUID = 12L;
+
+ CECPublicKey(NativeHandles handles, int keyLength) {
+ super("EC", handles, keyLength);
+ }
+
+ @Override
+ public ECPoint getW() {
+ if (w == null) {
+ // See CKey::generateECBlob.
+ try {
+ byte[] blob = getPublicKeyBlob(
+ handles.hCryptProv, handles.hCryptKey);
+ int len = blob[8] & 0xff;
+ byte[] x = Arrays.copyOfRange(blob, 8, 8 + len);
+ byte[] y = Arrays.copyOfRange(blob, 8 + len, 8 + len + len);
+ w = new ECPoint(new BigInteger(1, x), new BigInteger(1, y));
+ } catch (KeyException e) {
+ throw new ProviderException(e);
+ }
+ }
+ return w;
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ if (encoding == null) {
+ try {
+ encoding = KeyFactory.getInstance("EC").generatePublic(
+ new ECPublicKeySpec(getW(), getParams()))
+ .getEncoded();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ return encoding;
+ }
+
+ @Override
+ public ECParameterSpec getParams() {
+ try {
+ AlgorithmParameters ap = AlgorithmParameters.getInstance("EC");
+ ap.init(new ECKeySizeParameterSpec(keyLength));
+ return ap.getParameterSpec(ECParameterSpec.class);
+ } catch (Exception e) {
+ throw new ProviderException(e);
+ }
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(algorithm + "PublicKey [size=").append(keyLength)
+ .append("]\n ECPoint: ").append(getW())
+ .append("\n params: ").append(getParams());
+ return sb.toString();
+ }
+ }
+
+ public static class CRSAPublicKey extends CPublicKey implements RSAPublicKey {
+
+ private BigInteger modulus = null;
+ private BigInteger exponent = null;
+ private static final long serialVersionUID = 12L;
+
+ CRSAPublicKey(NativeHandles handles, int keyLength) {
+ super("RSA", handles, keyLength);
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(algorithm + "PublicKey [size=").append(keyLength)
+ .append(" bits, type=");
+ if (handles.hCryptKey != 0) {
+ sb.append(getKeyType(handles.hCryptKey))
+ .append(", container=").append(getContainerName(handles.hCryptProv));
+ } else {
+ sb.append("CNG");
+ }
+ sb.append("]\n modulus: ").append(getModulus())
+ .append("\n public exponent: ").append(getPublicExponent());
+ return sb.toString();
+ }
+
+ @Override
+ public BigInteger getPublicExponent() {
+ if (exponent == null) {
+ try {
+ byte[] publicKeyBlob = getPublicKeyBlob(
+ handles.hCryptProv, handles.hCryptKey);
+ exponent = new BigInteger(1, getExponent(publicKeyBlob));
+ } catch (KeyException e) {
+ throw new ProviderException(e);
+ }
+ }
+ return exponent;
+ }
+
+ @Override
+ public BigInteger getModulus() {
+ if (modulus == null) {
+ try {
+ byte[] publicKeyBlob = getPublicKeyBlob(
+ handles.hCryptProv, handles.hCryptKey);
+ modulus = new BigInteger(1, getModulus(publicKeyBlob));
+ } catch (KeyException e) {
+ throw new ProviderException(e);
+ }
+ }
+ return modulus;
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ if (encoding == null) {
+ try {
+ encoding = RSAPublicKeyImpl.newKey(KeyType.RSA, null,
+ getModulus(), getPublicExponent()).getEncoded();
+ } catch (KeyException e) {
+ // ignore
+ }
+ }
+ return encoding;
+ }
+
+ private native byte[] getExponent(byte[] keyBlob) throws KeyException;
+
+ private native byte[] getModulus(byte[] keyBlob) throws KeyException;
+ }
+
+ // Called by native code inside security.cpp
+ static CPublicKey of(
+ String alg, long hCryptProv, long hCryptKey, int keyLength) {
+ return of(alg, new NativeHandles(hCryptProv, hCryptKey), keyLength);
+ }
+
+ public static CPublicKey of(
+ String alg, NativeHandles handles, int keyLength) {
+ switch (alg) {
+ case "RSA":
+ return new CRSAPublicKey(handles, keyLength);
+ case "EC":
+ return new CECPublicKey(handles, keyLength);
+ default:
+ throw new AssertionError("Unsupported algorithm: " + alg);
+ }
+ }
+
+ protected CPublicKey(
+ String alg, NativeHandles handles, int keyLength) {
+ super(alg, handles, keyLength);
+ }
+
+ @Override
+ public String getFormat() {
+ return "X.509";
+ }
+
+ protected Object writeReplace() throws java.io.ObjectStreamException {
+ return new KeyRep(KeyRep.Type.PUBLIC,
+ getAlgorithm(),
+ getFormat(),
+ getEncoded());
+ }
+
+ // Returns the CAPI or CNG representation of the key.
+ native byte[] getPublicKeyBlob(long hCryptProv, long hCryptKey)
+ throws KeyException;
+}
diff --git a/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java b/jdk/src/windows/classes/sun/security/mscapi/CRSACipher.java
similarity index 95%
rename from jdk/src/windows/classes/sun/security/mscapi/RSACipher.java
rename to jdk/src/windows/classes/sun/security/mscapi/CRSACipher.java
index 023725b..95f6cbf 100644
--- a/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java
+++ b/jdk/src/windows/classes/sun/security/mscapi/CRSACipher.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,7 @@
import sun.security.util.KeyUtil;
/**
- * RSA cipher implementation using the Microsoft Crypto API.
+ * Cipher implementation using the Microsoft Crypto API.
* Supports RSA en/decryption and signing/verifying using PKCS#1 v1.5 padding.
*
* Objects should be instantiated by calling Cipher.getInstance() using the
@@ -59,7 +59,7 @@
* @author Andreas Sterbenz
* @author Vincent Ryan
*/
-public final class RSACipher extends CipherSpi {
+public final class CRSACipher extends CipherSpi {
// constant for an empty byte array
private final static byte[] B0 = new byte[0];
@@ -93,10 +93,10 @@
private int outputSize;
// the public key, if we were initialized using a public key
- private sun.security.mscapi.Key publicKey;
+ private CKey publicKey;
// the private key, if we were initialized using a private key
- private sun.security.mscapi.Key privateKey;
+ private CKey privateKey;
// cipher parameter for TLS RSA premaster secret
private AlgorithmParameterSpec spec = null;
@@ -104,7 +104,7 @@
// the source of randomness
private SecureRandom random;
- public RSACipher() {
+ public CRSACipher() {
paddingType = PAD_PKCS1;
}
@@ -159,6 +159,7 @@
}
// see JCE spec
+ @SuppressWarnings("deprecation")
protected void engineInit(int opmode, Key key,
AlgorithmParameterSpec params, SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
@@ -206,7 +207,7 @@
throw new InvalidKeyException("Unknown mode: " + opmode);
}
- if (!(key instanceof sun.security.mscapi.Key)) {
+ if (!(key instanceof CKey)) {
if (key instanceof java.security.interfaces.RSAPublicKey) {
java.security.interfaces.RSAPublicKey rsaKey =
(java.security.interfaces.RSAPublicKey) key;
@@ -219,7 +220,7 @@
// Check against the local and global values to make sure
// the sizes are ok. Round up to the nearest byte.
RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),
- exponent, -1, RSAKeyPairGenerator.KEY_SIZE_MAX);
+ exponent, -1, CKeyPairGenerator.RSA.KEY_SIZE_MAX);
byte[] modulusBytes = modulus.toByteArray();
byte[] exponentBytes = exponent.toByteArray();
@@ -229,11 +230,11 @@
? (modulusBytes.length - 1) * 8
: modulusBytes.length * 8;
- byte[] keyBlob = RSASignature.generatePublicKeyBlob(
+ byte[] keyBlob = CSignature.RSA.generatePublicKeyBlob(
keyBitLength, modulusBytes, exponentBytes);
try {
- key = RSASignature.importPublicKey(keyBlob, keyBitLength);
+ key = CSignature.importPublicKey("RSA", keyBlob, keyBitLength);
} catch (KeyStoreException e) {
throw new InvalidKeyException(e);
@@ -246,12 +247,12 @@
if (key instanceof PublicKey) {
mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY;
- publicKey = (sun.security.mscapi.Key)key;
+ publicKey = (CKey)key;
privateKey = null;
outputSize = publicKey.length() / 8;
} else if (key instanceof PrivateKey) {
mode = encrypt ? MODE_SIGN : MODE_DECRYPT;
- privateKey = (sun.security.mscapi.Key)key;
+ privateKey = (CKey)key;
publicKey = null;
outputSize = privateKey.length() / 8;
} else {
@@ -369,6 +370,7 @@
}
// see JCE spec
+ @SuppressWarnings("deprecation")
protected java.security.Key engineUnwrap(byte[] wrappedKey,
String algorithm,
int type) throws InvalidKeyException, NoSuchAlgorithmException {
@@ -415,8 +417,8 @@
// see JCE spec
protected int engineGetKeySize(Key key) throws InvalidKeyException {
- if (key instanceof sun.security.mscapi.Key) {
- return ((sun.security.mscapi.Key) key).length();
+ if (key instanceof CKey) {
+ return ((CKey) key).length();
} else if (key instanceof RSAKey) {
return ((RSAKey) key).getModulus().bitLength();
diff --git a/jdk/src/windows/classes/sun/security/mscapi/CSignature.java b/jdk/src/windows/classes/sun/security/mscapi/CSignature.java
new file mode 100644
index 0000000..b12d957
--- /dev/null
+++ b/jdk/src/windows/classes/sun/security/mscapi/CSignature.java
@@ -0,0 +1,954 @@
+/*
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.mscapi;
+
+import java.nio.ByteBuffer;
+import java.security.*;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+import java.math.BigInteger;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
+import java.util.Locale;
+
+import sun.security.rsa.RSAKeyFactory;
+import sun.security.util.ECUtil;
+import sun.security.util.KeyUtil;
+
+/**
+ * Signature implementation.
+ *
+ * Objects should be instantiated by calling Signature.getInstance() using the
+ * following algorithm names:
+ *
+ * . "NONEwithRSA"
+ * . "SHA1withRSA"
+ * . "SHA256withRSA"
+ * . "SHA384withRSA"
+ * . "SHA512withRSA"
+ * . "MD5withRSA"
+ * . "MD2withRSA"
+ * . "RSASSA-PSS"
+ * . "SHA1withECDSA"
+ * . "SHA224withECDSA"
+ * . "SHA256withECDSA"
+ * . "SHA384withECDSA"
+ * . "SHA512withECDSA"
+ *
+ * NOTE: RSA keys must be at least 512 bits long.
+ *
+ * NOTE: NONEwithRSA must be supplied with a pre-computed message digest.
+ * Only the following digest algorithms are supported: MD5, SHA-1,
+ * SHA-256, SHA-384, SHA-512 and a special-purpose digest
+ * algorithm which is a concatenation of SHA-1 and MD5 digests.
+ *
+ * @since 1.6
+ * @author Stanley Man-Kit Ho
+ */
+abstract class CSignature extends SignatureSpi {
+ // private key algorithm name
+ protected String keyAlgorithm;
+
+ // message digest implementation we use
+ protected MessageDigest messageDigest;
+
+ // message digest name
+ protected String messageDigestAlgorithm;
+
+ // flag indicating whether the digest has been reset
+ protected boolean needsReset;
+
+ // the signing key
+ protected CPrivateKey privateKey = null;
+
+ // the verification key
+ protected CPublicKey publicKey = null;
+
+ /**
+ * Constructs a new CSignature. Used by subclasses.
+ */
+ CSignature(String keyName, String digestName) {
+
+ this.keyAlgorithm = keyName;
+ if (digestName != null) {
+ try {
+ messageDigest = MessageDigest.getInstance(digestName);
+ // Get the digest's canonical name
+ messageDigestAlgorithm = messageDigest.getAlgorithm();
+ } catch (NoSuchAlgorithmException e) {
+ throw new ProviderException(e);
+ }
+ } else {
+ messageDigest = null;
+ messageDigestAlgorithm = null;
+ }
+ needsReset = false;
+ }
+
+ static class RSA extends CSignature {
+
+ public RSA(String digestAlgorithm) {
+ super("RSA", digestAlgorithm);
+ }
+
+ // initialize for signing. See JCA doc
+ @Override
+ protected void engineInitSign(PrivateKey key) throws InvalidKeyException {
+ if (key == null) {
+ throw new InvalidKeyException("Key cannot be null");
+ }
+ if ((key instanceof CPrivateKey) == false
+ || !key.getAlgorithm().equalsIgnoreCase("RSA")) {
+ throw new InvalidKeyException("Key type not supported: "
+ + key.getClass() + " " + key.getAlgorithm());
+ }
+ privateKey = (CPrivateKey) key;
+
+ // Check against the local and global values to make sure
+ // the sizes are ok. Round up to nearest byte.
+ RSAKeyFactory.checkKeyLengths(((privateKey.length() + 7) & ~7),
+ null, CKeyPairGenerator.RSA.KEY_SIZE_MIN,
+ CKeyPairGenerator.RSA.KEY_SIZE_MAX);
+
+ this.publicKey = null;
+ resetDigest();
+ }
+
+ // initialize for signing. See JCA doc
+ @Override
+ protected void engineInitVerify(PublicKey key) throws InvalidKeyException {
+ if (key == null) {
+ throw new InvalidKeyException("Key cannot be null");
+ }
+ // This signature accepts only RSAPublicKey
+ if ((key instanceof RSAPublicKey) == false) {
+ throw new InvalidKeyException("Key type not supported: "
+ + key.getClass());
+ }
+
+
+ if ((key instanceof CPublicKey) == false) {
+
+ // convert key to MSCAPI format
+ java.security.interfaces.RSAPublicKey rsaKey =
+ (java.security.interfaces.RSAPublicKey) key;
+
+ BigInteger modulus = rsaKey.getModulus();
+ BigInteger exponent = rsaKey.getPublicExponent();
+
+ // Check against the local and global values to make sure
+ // the sizes are ok. Round up to the nearest byte.
+ RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),
+ exponent, -1, CKeyPairGenerator.RSA.KEY_SIZE_MAX);
+
+ byte[] modulusBytes = modulus.toByteArray();
+ byte[] exponentBytes = exponent.toByteArray();
+
+ // Adjust key length due to sign bit
+ int keyBitLength = (modulusBytes[0] == 0)
+ ? (modulusBytes.length - 1) * 8
+ : modulusBytes.length * 8;
+
+ byte[] keyBlob = generatePublicKeyBlob(
+ keyBitLength, modulusBytes, exponentBytes);
+
+ try {
+ publicKey = importPublicKey("RSA", keyBlob, keyBitLength);
+
+ } catch (KeyStoreException e) {
+ throw new InvalidKeyException(e);
+ }
+
+ } else {
+ publicKey = (CPublicKey) key;
+ }
+
+ this.privateKey = null;
+ resetDigest();
+ }
+
+ /**
+ * Returns the signature bytes of all the data
+ * updated so far.
+ * The format of the signature depends on the underlying
+ * signature scheme.
+ *
+ * @return the signature bytes of the signing operation's result.
+ *
+ * @exception SignatureException if the engine is not
+ * initialized properly or if this signature algorithm is unable to
+ * process the input data provided.
+ */
+ @Override
+ protected byte[] engineSign() throws SignatureException {
+
+ byte[] hash = getDigestValue();
+
+ if (privateKey.getHCryptKey() == 0) {
+ return signCngHash(1, hash, hash.length,
+ 0,
+ this instanceof NONEwithRSA ? null : messageDigestAlgorithm,
+ privateKey.getHCryptProvider(), 0);
+ } else {
+ // Omit the hash OID when generating a NONEwithRSA signature
+ boolean noHashOID = this instanceof NONEwithRSA;
+ // Sign hash using MS Crypto APIs
+ byte[] result = signHash(noHashOID, hash, hash.length,
+ messageDigestAlgorithm, privateKey.getHCryptProvider(),
+ privateKey.getHCryptKey());
+
+ // Convert signature array from little endian to big endian
+ return convertEndianArray(result);
+ }
+ }
+
+ /**
+ * Verifies the passed-in signature.
+ *
+ * @param sigBytes the signature bytes to be verified.
+ *
+ * @return true if the signature was verified, false if not.
+ *
+ * @exception SignatureException if the engine is not
+ * initialized properly, the passed-in signature is improperly
+ * encoded or of the wrong type, if this signature algorithm is unable to
+ * process the input data provided, etc.
+ */
+ @Override
+ protected boolean engineVerify(byte[] sigBytes)
+ throws SignatureException {
+ byte[] hash = getDigestValue();
+
+ if (publicKey.getHCryptKey() == 0) {
+ return verifyCngSignedHash(
+ 1, hash, hash.length,
+ sigBytes, sigBytes.length,
+ 0,
+ messageDigestAlgorithm,
+ publicKey.getHCryptProvider(),
+ 0);
+ } else {
+ return verifySignedHash(hash, hash.length,
+ messageDigestAlgorithm, convertEndianArray(sigBytes),
+ sigBytes.length, publicKey.getHCryptProvider(),
+ publicKey.getHCryptKey());
+ }
+ }
+
+ /**
+ * Generates a public-key BLOB from a key's components.
+ */
+ // used by CRSACipher
+ static native byte[] generatePublicKeyBlob(
+ int keyBitLength, byte[] modulus, byte[] publicExponent)
+ throws InvalidKeyException;
+
+ }
+
+ // Nested class for NONEwithRSA signatures
+ public static final class NONEwithRSA extends RSA {
+
+ // the longest supported digest is 512 bits (SHA-512)
+ private static final int RAW_RSA_MAX = 64;
+
+ private final byte[] precomputedDigest;
+ private int offset = 0;
+
+ public NONEwithRSA() {
+ super(null);
+ precomputedDigest = new byte[RAW_RSA_MAX];
+ }
+
+ // Stores the precomputed message digest value.
+ @Override
+ protected void engineUpdate(byte b) throws SignatureException {
+ if (offset >= precomputedDigest.length) {
+ offset = RAW_RSA_MAX + 1;
+ return;
+ }
+ precomputedDigest[offset++] = b;
+ }
+
+ // Stores the precomputed message digest value.
+ @Override
+ protected void engineUpdate(byte[] b, int off, int len)
+ throws SignatureException {
+ if (len > (precomputedDigest.length - offset)) {
+ offset = RAW_RSA_MAX + 1;
+ return;
+ }
+ System.arraycopy(b, off, precomputedDigest, offset, len);
+ offset += len;
+ }
+
+ // Stores the precomputed message digest value.
+ @Override
+ protected void engineUpdate(ByteBuffer byteBuffer) {
+ int len = byteBuffer.remaining();
+ if (len <= 0) {
+ return;
+ }
+ if (len > (precomputedDigest.length - offset)) {
+ offset = RAW_RSA_MAX + 1;
+ return;
+ }
+ byteBuffer.get(precomputedDigest, offset, len);
+ offset += len;
+ }
+
+ @Override
+ protected void resetDigest(){
+ offset = 0;
+ }
+
+ // Returns the precomputed message digest value.
+ @Override
+ protected byte[] getDigestValue() throws SignatureException {
+ if (offset > RAW_RSA_MAX) {
+ throw new SignatureException("Message digest is too long");
+ }
+
+ // Determine the digest algorithm from the digest length
+ if (offset == 20) {
+ setDigestName("SHA1");
+ } else if (offset == 36) {
+ setDigestName("SHA1+MD5");
+ } else if (offset == 32) {
+ setDigestName("SHA-256");
+ } else if (offset == 48) {
+ setDigestName("SHA-384");
+ } else if (offset == 64) {
+ setDigestName("SHA-512");
+ } else if (offset == 16) {
+ setDigestName("MD5");
+ } else {
+ throw new SignatureException(
+ "Message digest length is not supported");
+ }
+
+ byte[] result = new byte[offset];
+ System.arraycopy(precomputedDigest, 0, result, 0, offset);
+ offset = 0;
+
+ return result;
+ }
+ }
+
+ public static final class SHA1withRSA extends RSA {
+ public SHA1withRSA() {
+ super("SHA1");
+ }
+ }
+
+ public static final class SHA256withRSA extends RSA {
+ public SHA256withRSA() {
+ super("SHA-256");
+ }
+ }
+
+ public static final class SHA384withRSA extends RSA {
+ public SHA384withRSA() {
+ super("SHA-384");
+ }
+ }
+
+ public static final class SHA512withRSA extends RSA {
+ public SHA512withRSA() {
+ super("SHA-512");
+ }
+ }
+
+ public static final class MD5withRSA extends RSA {
+ public MD5withRSA() {
+ super("MD5");
+ }
+ }
+
+ public static final class MD2withRSA extends RSA {
+ public MD2withRSA() {
+ super("MD2");
+ }
+ }
+
+ public static final class SHA1withECDSA extends ECDSA {
+ public SHA1withECDSA() {
+ super("SHA-1");
+ }
+ }
+
+ public static final class SHA224withECDSA extends ECDSA {
+ public SHA224withECDSA() {
+ super("SHA-224");
+ }
+ }
+
+ public static final class SHA256withECDSA extends ECDSA {
+ public SHA256withECDSA() {
+ super("SHA-256");
+ }
+ }
+
+ public static final class SHA384withECDSA extends ECDSA {
+ public SHA384withECDSA() {
+ super("SHA-384");
+ }
+ }
+
+ public static final class SHA512withECDSA extends ECDSA {
+ public SHA512withECDSA() {
+ super("SHA-512");
+ }
+ }
+
+ static class ECDSA extends CSignature {
+
+ public ECDSA(String messageDigestAlgorithm) {
+ super("EC", messageDigestAlgorithm);
+ }
+
+ // initialize for signing. See JCA doc
+ @Override
+ protected void engineInitSign(PrivateKey key) throws InvalidKeyException {
+ if (key == null) {
+ throw new InvalidKeyException("Key cannot be null");
+ }
+ if ((key instanceof CPrivateKey) == false
+ || !key.getAlgorithm().equalsIgnoreCase("EC")) {
+ throw new InvalidKeyException("Key type not supported: "
+ + key.getClass() + " " + key.getAlgorithm());
+ }
+ privateKey = (CPrivateKey) key;
+
+ this.publicKey = null;
+ resetDigest();
+ }
+
+ // initialize for signing. See JCA doc
+ @Override
+ protected void engineInitVerify(PublicKey key) throws InvalidKeyException {
+ if (key == null) {
+ throw new InvalidKeyException("Key cannot be null");
+ }
+ // This signature accepts only ECPublicKey
+ if ((key instanceof ECPublicKey) == false) {
+ throw new InvalidKeyException("Key type not supported: "
+ + key.getClass());
+ }
+
+ if ((key instanceof CPublicKey) == false) {
+ try {
+ publicKey = importECPublicKey("EC",
+ CKey.generateECBlob(key),
+ KeyUtil.getKeySize(key));
+ } catch (KeyStoreException e) {
+ throw new InvalidKeyException(e);
+ }
+ } else {
+ publicKey = (CPublicKey) key;
+ }
+
+ this.privateKey = null;
+ resetDigest();
+ }
+
+ @Override
+ protected byte[] engineSign() throws SignatureException {
+ byte[] hash = getDigestValue();
+ byte[] raw = signCngHash(0, hash, hash.length,
+ 0,
+ null,
+ privateKey.getHCryptProvider(), 0);
+ return ECUtil.encodeSignature(raw);
+ }
+
+ @Override
+ protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+ byte[] hash = getDigestValue();
+ sigBytes = ECUtil.decodeSignature(sigBytes);
+ return verifyCngSignedHash(
+ 0,
+ hash, hash.length,
+ sigBytes, sigBytes.length,
+ 0,
+ null,
+ publicKey.getHCryptProvider(),
+ 0
+ );
+ }
+ }
+
+ public static final class PSS extends RSA {
+
+ private PSSParameterSpec pssParams = null;
+
+ // Workaround: Cannot import raw public key to CNG. This signature
+ // will be used for verification if key is not from MSCAPI.
+ private Signature fallbackSignature;
+
+ public PSS() {
+ super(null);
+ }
+
+ @Override
+ protected void engineInitSign(PrivateKey key) throws InvalidKeyException {
+ super.engineInitSign(key);
+ fallbackSignature = null;
+ }
+
+ @Override
+ protected void engineInitVerify(PublicKey key) throws InvalidKeyException {
+ if (key == null) {
+ throw new InvalidKeyException("Key cannot be null");
+ }
+ // This signature accepts only RSAPublicKey
+ if ((key instanceof java.security.interfaces.RSAPublicKey) == false) {
+ throw new InvalidKeyException("Key type not supported: "
+ + key.getClass());
+ }
+
+ this.privateKey = null;
+
+ if (key instanceof CPublicKey) {
+ fallbackSignature = null;
+ publicKey = (CPublicKey) key;
+ } else {
+ if (fallbackSignature == null) {
+ try {
+ fallbackSignature = Signature.getInstance(
+ "RSASSA-PSS", "SunRsaSign");
+ } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
+ throw new InvalidKeyException("Invalid key", e);
+ }
+ }
+ fallbackSignature.initVerify(key);
+ if (pssParams != null) {
+ try {
+ fallbackSignature.setParameter(pssParams);
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new InvalidKeyException("Invalid params", e);
+ }
+ }
+ publicKey = null;
+ }
+ resetDigest();
+ }
+
+ @Override
+ protected void engineUpdate(byte b) throws SignatureException {
+ ensureInit();
+ if (fallbackSignature != null) {
+ fallbackSignature.update(b);
+ } else {
+ messageDigest.update(b);
+ }
+ needsReset = true;
+ }
+
+ @Override
+ protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {
+ ensureInit();
+ if (fallbackSignature != null) {
+ fallbackSignature.update(b, off, len);
+ } else {
+ messageDigest.update(b, off, len);
+ }
+ needsReset = true;
+ }
+
+ @Override
+ protected void engineUpdate(ByteBuffer input) {
+ try {
+ ensureInit();
+ } catch (SignatureException se) {
+ // hack for working around API bug
+ throw new RuntimeException(se.getMessage());
+ }
+ if (fallbackSignature != null) {
+ try {
+ fallbackSignature.update(input);
+ } catch (SignatureException se) {
+ // hack for working around API bug
+ throw new RuntimeException(se.getMessage());
+ }
+ } else {
+ messageDigest.update(input);
+ }
+ needsReset = true;
+ }
+
+ @Override
+ protected byte[] engineSign() throws SignatureException {
+ ensureInit();
+ byte[] hash = getDigestValue();
+ return signCngHash(2, hash, hash.length,
+ pssParams.getSaltLength(),
+ ((MGF1ParameterSpec)
+ pssParams.getMGFParameters()).getDigestAlgorithm(),
+ privateKey.getHCryptProvider(), privateKey.getHCryptKey());
+ }
+
+ @Override
+ protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+ ensureInit();
+ if (fallbackSignature != null) {
+ needsReset = false;
+ return fallbackSignature.verify(sigBytes);
+ } else {
+ byte[] hash = getDigestValue();
+ return verifyCngSignedHash(
+ 2, hash, hash.length,
+ sigBytes, sigBytes.length,
+ pssParams.getSaltLength(),
+ ((MGF1ParameterSpec)
+ pssParams.getMGFParameters()).getDigestAlgorithm(),
+ publicKey.getHCryptProvider(),
+ publicKey.getHCryptKey()
+ );
+ }
+ }
+
+ @Override
+ protected void engineSetParameter(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ if (needsReset) {
+ throw new ProviderException
+ ("Cannot set parameters during operations");
+ }
+ this.pssParams = validateSigParams(params);
+ if (fallbackSignature != null) {
+ fallbackSignature.setParameter(params);
+ }
+ }
+
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ AlgorithmParameters ap = null;
+ if (this.pssParams != null) {
+ try {
+ ap = AlgorithmParameters.getInstance("RSASSA-PSS");
+ ap.init(this.pssParams);
+ } catch (GeneralSecurityException gse) {
+ throw new ProviderException(gse.getMessage());
+ }
+ }
+ return ap;
+ }
+
+ private void ensureInit() throws SignatureException {
+ if (this.privateKey == null && this.publicKey == null
+ && fallbackSignature == null) {
+ throw new SignatureException("Missing key");
+ }
+ if (this.pssParams == null) {
+ // Parameters are required for signature verification
+ throw new SignatureException
+ ("Parameters required for RSASSA-PSS signatures");
+ }
+ if (fallbackSignature == null && messageDigest == null) {
+ // This could happen if initVerify(softKey), setParameter(),
+ // and initSign() were called. No messageDigest. Create it.
+ try {
+ messageDigest = MessageDigest
+ .getInstance(pssParams.getDigestAlgorithm());
+ } catch (NoSuchAlgorithmException e) {
+ throw new SignatureException(e);
+ }
+ }
+ }
+
+ /**
+ * Validate the specified Signature PSS parameters.
+ */
+ private PSSParameterSpec validateSigParams(AlgorithmParameterSpec p)
+ throws InvalidAlgorithmParameterException {
+
+ if (p == null) {
+ throw new InvalidAlgorithmParameterException
+ ("Parameters cannot be null");
+ }
+
+ if (!(p instanceof PSSParameterSpec)) {
+ throw new InvalidAlgorithmParameterException
+ ("parameters must be type PSSParameterSpec");
+ }
+
+ // no need to validate again if same as current signature parameters
+ PSSParameterSpec params = (PSSParameterSpec) p;
+ if (params == this.pssParams) return params;
+
+ // now sanity check the parameter values
+ if (!(params.getMGFAlgorithm().equalsIgnoreCase("MGF1"))) {
+ throw new InvalidAlgorithmParameterException("Only supports MGF1");
+
+ }
+
+ if (params.getTrailerField() != PSSParameterSpec.TRAILER_FIELD_BC) {
+ throw new InvalidAlgorithmParameterException
+ ("Only supports TrailerFieldBC(1)");
+ }
+
+ AlgorithmParameterSpec algSpec = params.getMGFParameters();
+ if (!(algSpec instanceof MGF1ParameterSpec)) {
+ throw new InvalidAlgorithmParameterException
+ ("Only support MGF1ParameterSpec");
+ }
+
+ MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)algSpec;
+
+ String msgHashAlg = params.getDigestAlgorithm()
+ .toLowerCase(Locale.ROOT).replaceAll("-", "");
+ if (msgHashAlg.equals("sha")) {
+ msgHashAlg = "sha1";
+ }
+ String mgf1HashAlg = mgfSpec.getDigestAlgorithm()
+ .toLowerCase(Locale.ROOT).replaceAll("-", "");
+ if (mgf1HashAlg.equals("sha")) {
+ mgf1HashAlg = "sha1";
+ }
+
+ if (!mgf1HashAlg.equals(msgHashAlg)) {
+ throw new InvalidAlgorithmParameterException
+ ("MGF1 hash must be the same as message hash");
+ }
+
+ return params;
+ }
+ }
+
+ /**
+ * Sign hash using CNG API with HCRYPTKEY.
+ * @param type 0 no padding, 1, pkcs1, 2, pss
+ */
+ native static byte[] signCngHash(
+ int type, byte[] hash,
+ int hashSize, int saltLength, String hashAlgorithm,
+ long hCryptProv, long nCryptKey)
+ throws SignatureException;
+
+ /**
+ * Verify a signed hash using CNG API with HCRYPTKEY.
+ * @param type 0 no padding, 1, pkcs1, 2, pss
+ */
+ private native static boolean verifyCngSignedHash(
+ int type, byte[] hash, int hashSize,
+ byte[] signature, int signatureSize,
+ int saltLength, String hashAlgorithm,
+ long hCryptProv, long hKey) throws SignatureException;
+
+ /**
+ * Resets the message digest if needed.
+ */
+ protected void resetDigest() {
+ if (needsReset) {
+ if (messageDigest != null) {
+ messageDigest.reset();
+ }
+ needsReset = false;
+ }
+ }
+
+ protected byte[] getDigestValue() throws SignatureException {
+ needsReset = false;
+ return messageDigest.digest();
+ }
+
+ protected void setDigestName(String name) {
+ messageDigestAlgorithm = name;
+ }
+
+ /**
+ * Updates the data to be signed or verified
+ * using the specified byte.
+ *
+ * @param b the byte to use for the update.
+ *
+ * @exception SignatureException if the engine is not initialized
+ * properly.
+ */
+ @Override
+ protected void engineUpdate(byte b) throws SignatureException {
+ messageDigest.update(b);
+ needsReset = true;
+ }
+
+ /**
+ * Updates the data to be signed or verified, using the
+ * specified array of bytes, starting at the specified offset.
+ *
+ * @param b the array of bytes
+ * @param off the offset to start from in the array of bytes
+ * @param len the number of bytes to use, starting at offset
+ *
+ * @exception SignatureException if the engine is not initialized
+ * properly
+ */
+ @Override
+ protected void engineUpdate(byte[] b, int off, int len)
+ throws SignatureException {
+ messageDigest.update(b, off, len);
+ needsReset = true;
+ }
+
+ /**
+ * Updates the data to be signed or verified, using the
+ * specified ByteBuffer.
+ *
+ * @param input the ByteBuffer
+ */
+ @Override
+ protected void engineUpdate(ByteBuffer input) {
+ messageDigest.update(input);
+ needsReset = true;
+ }
+
+ /**
+ * Convert array from big endian to little endian, or vice versa.
+ */
+ private static byte[] convertEndianArray(byte[] byteArray) {
+ if (byteArray == null || byteArray.length == 0)
+ return byteArray;
+
+ byte [] retval = new byte[byteArray.length];
+
+ // make it big endian
+ for (int i=0;i < byteArray.length;i++)
+ retval[i] = byteArray[byteArray.length - i - 1];
+
+ return retval;
+ }
+
+ /**
+ * Sign hash using Microsoft Crypto API with HCRYPTKEY.
+ * The returned data is in little-endian.
+ */
+ private native static byte[] signHash(boolean noHashOID, byte[] hash,
+ int hashSize, String hashAlgorithm, long hCryptProv, long hCryptKey)
+ throws SignatureException;
+
+ /**
+ * Verify a signed hash using Microsoft Crypto API with HCRYPTKEY.
+ */
+ private native static boolean verifySignedHash(byte[] hash, int hashSize,
+ String hashAlgorithm, byte[] signature, int signatureSize,
+ long hCryptProv, long hCryptKey) throws SignatureException;
+
+ /**
+ * Sets the specified algorithm parameter to the specified
+ * value. This method supplies a general-purpose mechanism through
+ * which it is possible to set the various parameters of this object.
+ * A parameter may be any settable parameter for the algorithm, such as
+ * a parameter size, or a source of random bits for signature generation
+ * (if appropriate), or an indication of whether or not to perform
+ * a specific but optional computation. A uniform algorithm-specific
+ * naming scheme for each parameter is desirable but left unspecified
+ * at this time.
+ *
+ * @param param the string identifier of the parameter.
+ *
+ * @param value the parameter value.
+ *
+ * @exception InvalidParameterException if <code>param</code> is an
+ * invalid parameter for this signature algorithm engine,
+ * the parameter is already set
+ * and cannot be set again, a security exception occurs, and so on.
+ *
+ * @deprecated Replaced by {@link
+ * #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
+ * engineSetParameter}.
+ */
+ @Override
+ @Deprecated
+ protected void engineSetParameter(String param, Object value)
+ throws InvalidParameterException {
+ throw new InvalidParameterException("Parameter not supported");
+ }
+
+ /**
+ * Sets this signature engine with the specified algorithm parameter.
+ *
+ * @param params the parameters
+ *
+ * @exception InvalidAlgorithmParameterException if the given
+ * parameter is invalid
+ */
+ @Override
+ protected void engineSetParameter(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ if (params != null) {
+ throw new InvalidAlgorithmParameterException("No parameter accepted");
+ }
+ }
+
+ /**
+ * Gets the value of the specified algorithm parameter.
+ * This method supplies a general-purpose mechanism through which it
+ * is possible to get the various parameters of this object. A parameter
+ * may be any settable parameter for the algorithm, such as a parameter
+ * size, or a source of random bits for signature generation (if
+ * appropriate), or an indication of whether or not to perform a
+ * specific but optional computation. A uniform algorithm-specific
+ * naming scheme for each parameter is desirable but left unspecified
+ * at this time.
+ *
+ * @param param the string name of the parameter.
+ *
+ * @return the object that represents the parameter value, or null if
+ * there is none.
+ *
+ * @exception InvalidParameterException if <code>param</code> is an
+ * invalid parameter for this engine, or another exception occurs while
+ * trying to get this parameter.
+ *
+ * @deprecated
+ */
+ @Override
+ @Deprecated
+ protected Object engineGetParameter(String param)
+ throws InvalidParameterException {
+ throw new InvalidParameterException("Parameter not supported");
+ }
+
+ /**
+ * Gets the algorithm parameter from this signature engine.
+ *
+ * @return the parameter, or null if no parameter is used.
+ */
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ return null;
+ }
+
+ /**
+ * Imports a public-key BLOB.
+ */
+ // used by CRSACipher
+ static native CPublicKey importPublicKey(
+ String alg, byte[] keyBlob, int keySize) throws KeyStoreException;
+
+ static native CPublicKey importECPublicKey(
+ String alg, byte[] keyBlob, int keySize) throws KeyStoreException;
+}
diff --git a/jdk/src/windows/classes/sun/security/mscapi/Key.java b/jdk/src/windows/classes/sun/security/mscapi/Key.java
deleted file mode 100644
index 8154c48..0000000
--- a/jdk/src/windows/classes/sun/security/mscapi/Key.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.mscapi;
-
-import sun.security.util.Length;
-
-/**
- * The handle for an RSA or DSA key using the Microsoft Crypto API.
- *
- * @see RSAPrivateKey
- * @see RSAPublicKey
- *
- * @since 1.6
- * @author Stanley Man-Kit Ho
- */
-abstract class Key implements java.security.Key, Length
-{
- private static final long serialVersionUID = -1088859394025049194L;
-
- static class NativeHandles {
- long hCryptProv = 0;
- long hCryptKey = 0;
-
- public NativeHandles(long hCryptProv, long hCryptKey) {
- this.hCryptProv = hCryptProv;
- this.hCryptKey = hCryptKey;
- }
-
- /**
- * Finalization method
- */
- protected void finalize() throws Throwable
- {
- try {
- synchronized(this)
- {
- cleanUp(hCryptProv, hCryptKey);
- hCryptProv = 0;
- hCryptKey = 0;
- }
-
- } finally {
- super.finalize();
- }
- }
- }
-
- protected NativeHandles handles;
-
- // Key length
- protected int keyLength = 0;
-
- /**
- * Construct a Key object.
- */
- protected Key(NativeHandles handles, int keyLength)
- {
- this.handles = handles;
- this.keyLength = keyLength;
- }
-
- /**
- * Native method to cleanup the key handle.
- */
- private native static void cleanUp(long hCryptProv, long hCryptKey);
-
- /**
- * Return bit length of the key.
- */
- @Override
- public int length()
- {
- return keyLength;
- }
-
-
- /**
- * Return native HCRYPTKEY handle.
- */
- public long getHCryptKey()
- {
- return handles.hCryptKey;
- }
-
- /**
- * Return native HCRYPTPROV handle.
- */
- public long getHCryptProvider()
- {
- return handles.hCryptProv;
- }
-
- /**
- * Returns the standard algorithm name for this key. For
- * example, "RSA" would indicate that this key is a RSA key.
- * See Appendix A in the <a href=
- * "../../../guide/security/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
- * for information about standard algorithm names.
- *
- * @return the name of the algorithm associated with this key.
- */
- public abstract String getAlgorithm();
-
- /**
- * Returns the name of the primary encoding format of this key,
- * or null if this key does not support encoding.
- * The primary encoding format is
- * named in terms of the appropriate ASN.1 data format, if an
- * ASN.1 specification for this key exists.
- * For example, the name of the ASN.1 data format for public
- * keys is <I>SubjectPublicKeyInfo</I>, as
- * defined by the X.509 standard; in this case, the returned format is
- * <code>"X.509"</code>. Similarly,
- * the name of the ASN.1 data format for private keys is
- * <I>PrivateKeyInfo</I>,
- * as defined by the PKCS #8 standard; in this case, the returned format is
- * <code>"PKCS#8"</code>.
- *
- * @return the primary encoding format of the key.
- */
- public String getFormat()
- {
- return null;
- }
-
- /**
- * Returns the key in its primary encoding format, or null
- * if this key does not support encoding.
- *
- * @return the encoded key, or null if the key does not support
- * encoding.
- */
- public byte[] getEncoded()
- {
- return null;
- }
-
- protected native static String getContainerName(long hCryptProv);
-
- protected native static String getKeyType(long hCryptKey);
-}
diff --git a/jdk/src/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java b/jdk/src/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java
deleted file mode 100644
index 4222dee..0000000
--- a/jdk/src/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.mscapi;
-
-import java.util.UUID;
-import java.security.*;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.RSAKeyGenParameterSpec;
-
-import sun.security.jca.JCAUtil;
-import sun.security.rsa.RSAKeyFactory;
-import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
-
-/**
- * RSA keypair generator.
- *
- * Standard algorithm, minimum key length is 512 bit, maximum is 16,384.
- * Generates a private key that is exportable.
- *
- * @since 1.6
- */
-public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
-
- // Supported by Microsoft Base, Strong and Enhanced Cryptographic Providers
- static final int KEY_SIZE_MIN = 512; // disallow MSCAPI min. of 384
- static final int KEY_SIZE_MAX = 16384;
-
- // size of the key to generate, KEY_SIZE_MIN <= keySize <= KEY_SIZE_MAX
- private int keySize;
-
- public RSAKeyPairGenerator() {
- // initialize to default in case the app does not call initialize()
- initialize(DEF_RSA_KEY_SIZE, null);
- }
-
- // initialize the generator. See JCA doc
- // random is always ignored
- public void initialize(int keySize, SecureRandom random) {
-
- try {
- RSAKeyFactory.checkKeyLengths(keySize, null,
- KEY_SIZE_MIN, KEY_SIZE_MAX);
- } catch (InvalidKeyException e) {
- throw new InvalidParameterException(e.getMessage());
- }
-
- this.keySize = keySize;
- }
-
- // second initialize method. See JCA doc
- // random and exponent are always ignored
- public void initialize(AlgorithmParameterSpec params, SecureRandom random)
- throws InvalidAlgorithmParameterException {
-
- int tmpSize;
- if (params == null) {
- tmpSize = DEF_RSA_KEY_SIZE;
- } else if (params instanceof RSAKeyGenParameterSpec) {
-
- if (((RSAKeyGenParameterSpec) params).getPublicExponent() != null) {
- throw new InvalidAlgorithmParameterException
- ("Exponent parameter is not supported");
- }
- tmpSize = ((RSAKeyGenParameterSpec) params).getKeysize();
-
- } else {
- throw new InvalidAlgorithmParameterException
- ("Params must be an instance of RSAKeyGenParameterSpec");
- }
-
- try {
- RSAKeyFactory.checkKeyLengths(tmpSize, null,
- KEY_SIZE_MIN, KEY_SIZE_MAX);
- } catch (InvalidKeyException e) {
- throw new InvalidAlgorithmParameterException(
- "Invalid Key sizes", e);
- }
-
- this.keySize = tmpSize;
- }
-
- // generate the keypair. See JCA doc
- public KeyPair generateKeyPair() {
-
- try {
-
- // Generate each keypair in a unique key container
- RSAKeyPair keys =
- generateRSAKeyPair(keySize,
- "{" + UUID.randomUUID().toString() + "}");
-
- return new KeyPair(keys.getPublic(), keys.getPrivate());
-
- } catch (KeyException e) {
- throw new ProviderException(e);
- }
- }
-
- private static native RSAKeyPair generateRSAKeyPair(int keySize,
- String keyContainerName) throws KeyException;
-}
diff --git a/jdk/src/windows/classes/sun/security/mscapi/RSAPrivateKey.java b/jdk/src/windows/classes/sun/security/mscapi/RSAPrivateKey.java
deleted file mode 100644
index ca692df..0000000
--- a/jdk/src/windows/classes/sun/security/mscapi/RSAPrivateKey.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.mscapi;
-
-import java.security.PrivateKey;
-
-/**
- * The handle for an RSA private key using the Microsoft Crypto API.
- *
- * @author Stanley Man-Kit Ho
- * @since 1.6
- */
-class RSAPrivateKey extends Key implements PrivateKey
-{
- private static final long serialVersionUID = 8113152807912338063L;
-
- /**
- * Construct an RSAPrivateKey object.
- */
- RSAPrivateKey(long hCryptProv, long hCryptKey, int keyLength)
- {
- super(new NativeHandles(hCryptProv, hCryptKey), keyLength);
- }
-
- /**
- * Construct an RSAPrivateKey object.
- */
- RSAPrivateKey(NativeHandles handles, int keyLength)
- {
- super(handles, keyLength);
- }
-
- /**
- * Returns the standard algorithm name for this key. For
- * example, "RSA" would indicate that this key is a RSA key.
- * See Appendix A in the <a href=
- * "../../../guide/security/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
- * for information about standard algorithm names.
- *
- * @return the name of the algorithm associated with this key.
- */
- public String getAlgorithm()
- {
- return "RSA";
- }
-
- public String toString()
- {
- return "RSAPrivateKey [size=" + keyLength + " bits, type=" +
- getKeyType(handles.hCryptKey) + ", container=" +
- getContainerName(handles.hCryptProv) + "]";
- }
-
- // This class is not serializable
- private void writeObject(java.io.ObjectOutputStream out)
- throws java.io.IOException {
-
- throw new java.io.NotSerializableException();
- }
-}
diff --git a/jdk/src/windows/classes/sun/security/mscapi/RSAPublicKey.java b/jdk/src/windows/classes/sun/security/mscapi/RSAPublicKey.java
deleted file mode 100644
index 52081ab..0000000
--- a/jdk/src/windows/classes/sun/security/mscapi/RSAPublicKey.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.mscapi;
-
-import java.math.BigInteger;
-import java.security.KeyException;
-import java.security.KeyRep;
-import java.security.ProviderException;
-
-import sun.security.rsa.RSAPublicKeyImpl;
-
-/**
- * The handle for an RSA public key using the Microsoft Crypto API.
- *
- * @since 1.6
- */
-class RSAPublicKey extends Key implements java.security.interfaces.RSAPublicKey
-{
- private static final long serialVersionUID = -2289561342425825391L;
-
- private byte[] publicKeyBlob = null;
- private byte[] encoding = null;
- private BigInteger modulus = null;
- private BigInteger exponent = null;
-
- /**
- * Construct an RSAPublicKey object.
- */
- RSAPublicKey(long hCryptProv, long hCryptKey, int keyLength)
- {
- super(new NativeHandles(hCryptProv, hCryptKey), keyLength);
- }
-
- /**
- * Construct an RSAPublicKey object.
- */
- RSAPublicKey(NativeHandles handles, int keyLength)
- {
- super(handles, keyLength);
- }
-
- /**
- * Returns the standard algorithm name for this key. For
- * example, "RSA" would indicate that this key is a RSA key.
- * See Appendix A in the <a href=
- * "../../../guide/security/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
- * for information about standard algorithm names.
- *
- * @return the name of the algorithm associated with this key.
- */
- public String getAlgorithm()
- {
- return "RSA";
- }
-
- /**
- * Returns a printable description of the key.
- */
- public String toString()
- {
- StringBuffer sb = new StringBuffer();
-
- sb.append("RSAPublicKey [size=").append(keyLength)
- .append(" bits, type=").append(getKeyType(handles.hCryptKey))
- .append(", container=").append(getContainerName(handles.hCryptProv))
- .append("]\n modulus: ").append(getModulus())
- .append("\n public exponent: ").append(getPublicExponent());
-
- return sb.toString();
- }
-
- /**
- * Returns the public exponent.
- */
- public BigInteger getPublicExponent() {
-
- if (exponent == null) {
-
- try {
- publicKeyBlob = getPublicKeyBlob(handles.hCryptKey);
- exponent = new BigInteger(1, getExponent(publicKeyBlob));
-
- } catch (KeyException e) {
- throw new ProviderException(e);
- }
- }
-
- return exponent;
- }
-
- /**
- * Returns the modulus.
- */
- public BigInteger getModulus() {
-
- if (modulus == null) {
-
- try {
- publicKeyBlob = getPublicKeyBlob(handles.hCryptKey);
- modulus = new BigInteger(1, getModulus(publicKeyBlob));
-
- } catch (KeyException e) {
- throw new ProviderException(e);
- }
- }
-
- return modulus;
- }
-
- /**
- * Returns the name of the primary encoding format of this key,
- * or null if this key does not support encoding.
- * The primary encoding format is
- * named in terms of the appropriate ASN.1 data format, if an
- * ASN.1 specification for this key exists.
- * For example, the name of the ASN.1 data format for public
- * keys is <I>SubjectPublicKeyInfo</I>, as
- * defined by the X.509 standard; in this case, the returned format is
- * <code>"X.509"</code>. Similarly,
- * the name of the ASN.1 data format for private keys is
- * <I>PrivateKeyInfo</I>,
- * as defined by the PKCS #8 standard; in this case, the returned format is
- * <code>"PKCS#8"</code>.
- *
- * @return the primary encoding format of the key.
- */
- public String getFormat()
- {
- return "X.509";
- }
-
- /**
- * Returns the key in its primary encoding format, or null
- * if this key does not support encoding.
- *
- * @return the encoded key, or null if the key does not support
- * encoding.
- */
- public byte[] getEncoded()
- {
- if (encoding == null) {
-
- try {
- encoding = new RSAPublicKeyImpl(getModulus(),
- getPublicExponent()).getEncoded();
-
- } catch (KeyException e) {
- // ignore
- }
- }
- return encoding;
- }
-
- protected Object writeReplace() throws java.io.ObjectStreamException {
- return new KeyRep(KeyRep.Type.PUBLIC,
- getAlgorithm(),
- getFormat(),
- getEncoded());
- }
-
- /*
- * Returns the Microsoft CryptoAPI representation of the key.
- */
- private native byte[] getPublicKeyBlob(long hCryptKey) throws KeyException;
-
- /*
- * Returns the key's public exponent (in big-endian 2's complement format).
- */
- private native byte[] getExponent(byte[] keyBlob) throws KeyException;
-
- /*
- * Returns the key's modulus (in big-endian 2's complement format).
- */
- private native byte[] getModulus(byte[] keyBlob) throws KeyException;
-}
diff --git a/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java b/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java
deleted file mode 100644
index 24f8190..0000000
--- a/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.mscapi;
-
-import java.nio.ByteBuffer;
-import java.security.PublicKey;
-import java.security.PrivateKey;
-import java.security.InvalidKeyException;
-import java.security.InvalidParameterException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.ProviderException;
-import java.security.MessageDigest;
-import java.security.SignatureException;
-import java.math.BigInteger;
-
-import sun.security.rsa.RSAKeyFactory;
-
-/**
- * RSA signature implementation. Supports RSA signing using PKCS#1 v1.5 padding.
- *
- * Objects should be instantiated by calling Signature.getInstance() using the
- * following algorithm names:
- *
- * . "NONEwithRSA"
- * . "SHA1withRSA"
- * . "SHA256withRSA"
- * . "SHA384withRSA"
- * . "SHA512withRSA"
- * . "MD5withRSA"
- * . "MD2withRSA"
- *
- * NOTE: RSA keys must be at least 512 bits long.
- *
- * NOTE: NONEwithRSA must be supplied with a pre-computed message digest.
- * Only the following digest algorithms are supported: MD5, SHA-1,
- * SHA-256, SHA-384, SHA-512 and a special-purpose digest
- * algorithm which is a concatenation of SHA-1 and MD5 digests.
- *
- * @since 1.6
- * @author Stanley Man-Kit Ho
- */
-abstract class RSASignature extends java.security.SignatureSpi
-{
- // message digest implementation we use
- private final MessageDigest messageDigest;
-
- // message digest name
- private String messageDigestAlgorithm;
-
- // flag indicating whether the digest has been reset
- private boolean needsReset;
-
- // the signing key
- private Key privateKey = null;
-
- // the verification key
- private Key publicKey = null;
-
- /**
- * Constructs a new RSASignature. Used by Raw subclass.
- */
- RSASignature() {
- messageDigest = null;
- messageDigestAlgorithm = null;
- }
-
- /**
- * Constructs a new RSASignature. Used by subclasses.
- */
- RSASignature(String digestName) {
-
- try {
- messageDigest = MessageDigest.getInstance(digestName);
- // Get the digest's canonical name
- messageDigestAlgorithm = messageDigest.getAlgorithm();
-
- } catch (NoSuchAlgorithmException e) {
- throw new ProviderException(e);
- }
-
- needsReset = false;
- }
-
- // Nested class for NONEwithRSA signatures
- public static final class Raw extends RSASignature {
-
- // the longest supported digest is 512 bits (SHA-512)
- private static final int RAW_RSA_MAX = 64;
-
- private final byte[] precomputedDigest;
- private int offset = 0;
-
- public Raw() {
- precomputedDigest = new byte[RAW_RSA_MAX];
- }
-
- // Stores the precomputed message digest value.
- @Override
- protected void engineUpdate(byte b) throws SignatureException {
- if (offset >= precomputedDigest.length) {
- offset = RAW_RSA_MAX + 1;
- return;
- }
- precomputedDigest[offset++] = b;
- }
-
- // Stores the precomputed message digest value.
- @Override
- protected void engineUpdate(byte[] b, int off, int len)
- throws SignatureException {
- if (len > (precomputedDigest.length - offset)) {
- offset = RAW_RSA_MAX + 1;
- return;
- }
- System.arraycopy(b, off, precomputedDigest, offset, len);
- offset += len;
- }
-
- // Stores the precomputed message digest value.
- @Override
- protected void engineUpdate(ByteBuffer byteBuffer) {
- int len = byteBuffer.remaining();
- if (len <= 0) {
- return;
- }
- if (len > (precomputedDigest.length - offset)) {
- offset = RAW_RSA_MAX + 1;
- return;
- }
- byteBuffer.get(precomputedDigest, offset, len);
- offset += len;
- }
-
- @Override
- protected void resetDigest(){
- offset = 0;
- }
-
- // Returns the precomputed message digest value.
- @Override
- protected byte[] getDigestValue() throws SignatureException {
- if (offset > RAW_RSA_MAX) {
- throw new SignatureException("Message digest is too long");
- }
-
- // Determine the digest algorithm from the digest length
- if (offset == 20) {
- setDigestName("SHA1");
- } else if (offset == 36) {
- setDigestName("SHA1+MD5");
- } else if (offset == 32) {
- setDigestName("SHA-256");
- } else if (offset == 48) {
- setDigestName("SHA-384");
- } else if (offset == 64) {
- setDigestName("SHA-512");
- } else if (offset == 16) {
- setDigestName("MD5");
- } else {
- throw new SignatureException(
- "Message digest length is not supported");
- }
-
- byte[] result = new byte[offset];
- System.arraycopy(precomputedDigest, 0, result, 0, offset);
- offset = 0;
-
- return result;
- }
- }
-
- public static final class SHA1 extends RSASignature {
- public SHA1() {
- super("SHA1");
- }
- }
-
- public static final class SHA256 extends RSASignature {
- public SHA256() {
- super("SHA-256");
- }
- }
-
- public static final class SHA384 extends RSASignature {
- public SHA384() {
- super("SHA-384");
- }
- }
-
- public static final class SHA512 extends RSASignature {
- public SHA512() {
- super("SHA-512");
- }
- }
-
- public static final class MD5 extends RSASignature {
- public MD5() {
- super("MD5");
- }
- }
-
- public static final class MD2 extends RSASignature {
- public MD2() {
- super("MD2");
- }
- }
-
- // initialize for signing. See JCA doc
- protected void engineInitVerify(PublicKey key)
- throws InvalidKeyException
- {
- // This signature accepts only RSAPublicKey
- if ((key instanceof java.security.interfaces.RSAPublicKey) == false) {
- throw new InvalidKeyException("Key type not supported");
- }
-
- java.security.interfaces.RSAPublicKey rsaKey =
- (java.security.interfaces.RSAPublicKey) key;
-
- if ((key instanceof sun.security.mscapi.RSAPublicKey) == false) {
-
- // convert key to MSCAPI format
-
- BigInteger modulus = rsaKey.getModulus();
- BigInteger exponent = rsaKey.getPublicExponent();
-
- // Check against the local and global values to make sure
- // the sizes are ok. Round up to the nearest byte.
- RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),
- exponent, -1, RSAKeyPairGenerator.KEY_SIZE_MAX);
-
- byte[] modulusBytes = modulus.toByteArray();
- byte[] exponentBytes = exponent.toByteArray();
-
- // Adjust key length due to sign bit
- int keyBitLength = (modulusBytes[0] == 0)
- ? (modulusBytes.length - 1) * 8
- : modulusBytes.length * 8;
-
- byte[] keyBlob = generatePublicKeyBlob(
- keyBitLength, modulusBytes, exponentBytes);
-
- try {
- publicKey = importPublicKey(keyBlob, keyBitLength);
-
- } catch (KeyStoreException e) {
- throw new InvalidKeyException(e);
- }
-
- } else {
- publicKey = (sun.security.mscapi.RSAPublicKey) key;
- }
-
- this.privateKey = null;
- resetDigest();
- }
-
- // initialize for signing. See JCA doc
- protected void engineInitSign(PrivateKey key) throws InvalidKeyException
- {
- // This signature accepts only RSAPrivateKey
- if ((key instanceof sun.security.mscapi.RSAPrivateKey) == false) {
- throw new InvalidKeyException("Key type not supported");
- }
- privateKey = (sun.security.mscapi.RSAPrivateKey) key;
-
- // Check against the local and global values to make sure
- // the sizes are ok. Round up to nearest byte.
- RSAKeyFactory.checkKeyLengths(((privateKey.length() + 7) & ~7),
- null, RSAKeyPairGenerator.KEY_SIZE_MIN,
- RSAKeyPairGenerator.KEY_SIZE_MAX);
-
- this.publicKey = null;
- resetDigest();
- }
-
- /**
- * Resets the message digest if needed.
- */
- protected void resetDigest() {
- if (needsReset) {
- messageDigest.reset();
- needsReset = false;
- }
- }
-
- protected byte[] getDigestValue() throws SignatureException {
- needsReset = false;
- return messageDigest.digest();
- }
-
- protected void setDigestName(String name) {
- messageDigestAlgorithm = name;
- }
-
- /**
- * Updates the data to be signed or verified
- * using the specified byte.
- *
- * @param b the byte to use for the update.
- *
- * @exception SignatureException if the engine is not initialized
- * properly.
- */
- protected void engineUpdate(byte b) throws SignatureException
- {
- messageDigest.update(b);
- needsReset = true;
- }
-
- /**
- * Updates the data to be signed or verified, using the
- * specified array of bytes, starting at the specified offset.
- *
- * @param b the array of bytes
- * @param off the offset to start from in the array of bytes
- * @param len the number of bytes to use, starting at offset
- *
- * @exception SignatureException if the engine is not initialized
- * properly
- */
- protected void engineUpdate(byte[] b, int off, int len)
- throws SignatureException
- {
- messageDigest.update(b, off, len);
- needsReset = true;
- }
-
- /**
- * Updates the data to be signed or verified, using the
- * specified ByteBuffer.
- *
- * @param input the ByteBuffer
- */
- protected void engineUpdate(ByteBuffer input)
- {
- messageDigest.update(input);
- needsReset = true;
- }
-
- /**
- * Returns the signature bytes of all the data
- * updated so far.
- * The format of the signature depends on the underlying
- * signature scheme.
- *
- * @return the signature bytes of the signing operation's result.
- *
- * @exception SignatureException if the engine is not
- * initialized properly or if this signature algorithm is unable to
- * process the input data provided.
- */
- protected byte[] engineSign() throws SignatureException {
-
- byte[] hash = getDigestValue();
-
- // Omit the hash OID when generating a Raw signature
- boolean noHashOID = this instanceof Raw;
-
- // Sign hash using MS Crypto APIs
-
- byte[] result = signHash(noHashOID, hash, hash.length,
- messageDigestAlgorithm, privateKey.getHCryptProvider(),
- privateKey.getHCryptKey());
-
- // Convert signature array from little endian to big endian
- return convertEndianArray(result);
- }
-
- /**
- * Convert array from big endian to little endian, or vice versa.
- */
- private byte[] convertEndianArray(byte[] byteArray)
- {
- if (byteArray == null || byteArray.length == 0)
- return byteArray;
-
- byte [] retval = new byte[byteArray.length];
-
- // make it big endian
- for (int i=0;i < byteArray.length;i++)
- retval[i] = byteArray[byteArray.length - i - 1];
-
- return retval;
- }
-
- /**
- * Sign hash using Microsoft Crypto API with HCRYPTKEY.
- * The returned data is in little-endian.
- */
- private native static byte[] signHash(boolean noHashOID, byte[] hash,
- int hashSize, String hashAlgorithm, long hCryptProv, long hCryptKey)
- throws SignatureException;
-
- /**
- * Verify a signed hash using Microsoft Crypto API with HCRYPTKEY.
- */
- private native static boolean verifySignedHash(byte[] hash, int hashSize,
- String hashAlgorithm, byte[] signature, int signatureSize,
- long hCryptProv, long hCryptKey) throws SignatureException;
-
- /**
- * Verifies the passed-in signature.
- *
- * @param sigBytes the signature bytes to be verified.
- *
- * @return true if the signature was verified, false if not.
- *
- * @exception SignatureException if the engine is not
- * initialized properly, the passed-in signature is improperly
- * encoded or of the wrong type, if this signature algorithm is unable to
- * process the input data provided, etc.
- */
- protected boolean engineVerify(byte[] sigBytes)
- throws SignatureException
- {
- byte[] hash = getDigestValue();
-
- return verifySignedHash(hash, hash.length,
- messageDigestAlgorithm, convertEndianArray(sigBytes),
- sigBytes.length, publicKey.getHCryptProvider(),
- publicKey.getHCryptKey());
- }
-
- /**
- * Sets the specified algorithm parameter to the specified
- * value. This method supplies a general-purpose mechanism through
- * which it is possible to set the various parameters of this object.
- * A parameter may be any settable parameter for the algorithm, such as
- * a parameter size, or a source of random bits for signature generation
- * (if appropriate), or an indication of whether or not to perform
- * a specific but optional computation. A uniform algorithm-specific
- * naming scheme for each parameter is desirable but left unspecified
- * at this time.
- *
- * @param param the string identifier of the parameter.
- *
- * @param value the parameter value.
- *
- * @exception InvalidParameterException if <code>param</code> is an
- * invalid parameter for this signature algorithm engine,
- * the parameter is already set
- * and cannot be set again, a security exception occurs, and so on.
- *
- * @deprecated Replaced by {@link
- * #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
- * engineSetParameter}.
- */
- @Deprecated
- protected void engineSetParameter(String param, Object value)
- throws InvalidParameterException
- {
- throw new InvalidParameterException("Parameter not supported");
- }
-
-
- /**
- * Gets the value of the specified algorithm parameter.
- * This method supplies a general-purpose mechanism through which it
- * is possible to get the various parameters of this object. A parameter
- * may be any settable parameter for the algorithm, such as a parameter
- * size, or a source of random bits for signature generation (if
- * appropriate), or an indication of whether or not to perform a
- * specific but optional computation. A uniform algorithm-specific
- * naming scheme for each parameter is desirable but left unspecified
- * at this time.
- *
- * @param param the string name of the parameter.
- *
- * @return the object that represents the parameter value, or null if
- * there is none.
- *
- * @exception InvalidParameterException if <code>param</code> is an
- * invalid parameter for this engine, or another exception occurs while
- * trying to get this parameter.
- *
- * @deprecated
- */
- @Deprecated
- protected Object engineGetParameter(String param)
- throws InvalidParameterException
- {
- throw new InvalidParameterException("Parameter not supported");
- }
-
- /**
- * Generates a public-key BLOB from a key's components.
- */
- // used by RSACipher
- static native byte[] generatePublicKeyBlob(
- int keyBitLength, byte[] modulus, byte[] publicExponent)
- throws InvalidKeyException;
-
- /**
- * Imports a public-key BLOB.
- */
- // used by RSACipher
- static native RSAPublicKey importPublicKey(byte[] keyBlob, int keySize)
- throws KeyStoreException;
-}
diff --git a/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java b/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java
index 7725b27..fb9cb9e 100644
--- a/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java
+++ b/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -73,8 +73,8 @@
/*
* Key store
*/
- map.put("KeyStore.Windows-MY", "sun.security.mscapi.KeyStore$MY");
- map.put("KeyStore.Windows-ROOT", "sun.security.mscapi.KeyStore$ROOT");
+ map.put("KeyStore.Windows-MY", "sun.security.mscapi.CKeyStore$MY");
+ map.put("KeyStore.Windows-ROOT", "sun.security.mscapi.CKeyStore$ROOT");
/*
* Signature engines
@@ -84,60 +84,99 @@
// SHA-256, SHA-384, SHA-512 and a special-purpose digest
// algorithm which is a concatenation of SHA-1 and MD5 digests.
map.put("Signature.NONEwithRSA",
- "sun.security.mscapi.RSASignature$Raw");
+ "sun.security.mscapi.CSignature$NONEwithRSA");
map.put("Signature.SHA1withRSA",
- "sun.security.mscapi.RSASignature$SHA1");
+ "sun.security.mscapi.CSignature$SHA1withRSA");
map.put("Signature.SHA256withRSA",
- "sun.security.mscapi.RSASignature$SHA256");
+ "sun.security.mscapi.CSignature$SHA256withRSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.11", "SHA256withRSA");
map.put("Signature.SHA384withRSA",
- "sun.security.mscapi.RSASignature$SHA384");
+ "sun.security.mscapi.CSignature$SHA384withRSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.12", "SHA384withRSA");
-
map.put("Signature.SHA512withRSA",
- "sun.security.mscapi.RSASignature$SHA512");
+ "sun.security.mscapi.CSignature$SHA512withRSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.13", "SHA512withRSA");
map.put("Signature.MD5withRSA",
- "sun.security.mscapi.RSASignature$MD5");
+ "sun.security.mscapi.CSignature$MD5withRSA");
map.put("Signature.MD2withRSA",
- "sun.security.mscapi.RSASignature$MD2");
+ "sun.security.mscapi.CSignature$MD2withRSA");
+
+ map.put("Signature.RSASSA-PSS",
+ "sun.security.mscapi.CSignature$PSS");
+ map.put("Alg.Alias.Signature.1.2.840.113549.1.1.10", "RSASSA-PSS");
+ map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
+
+ map.put("Signature.SHA1withECDSA",
+ "sun.security.mscapi.CSignature$SHA1withECDSA");
+ map.put("Alg.Alias.Signature.1.2.840.10045.4.1", "SHA1withECDSA");
+ map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.1", "SHA1withECDSA");
+ map.put("Signature.SHA224withECDSA",
+ "sun.security.mscapi.CSignature$SHA224withECDSA");
+ map.put("Alg.Alias.Signature.1.2.840.10045.4.3.1", "SHA224withECDSA");
+ map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.1", "SHA224withECDSA");
+ map.put("Signature.SHA256withECDSA",
+ "sun.security.mscapi.CSignature$SHA256withECDSA");
+ map.put("Alg.Alias.Signature.1.2.840.10045.4.3.2", "SHA256withECDSA");
+ map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.2", "SHA256withECDSA");
+ map.put("Signature.SHA384withECDSA",
+ "sun.security.mscapi.CSignature$SHA384withECDSA");
+ map.put("Alg.Alias.Signature.1.2.840.10045.4.3.3", "SHA384withECDSA");
+ map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.3", "SHA384withECDSA");
+ map.put("Signature.SHA512withECDSA",
+ "sun.security.mscapi.CSignature$SHA512withECDSA");
+ map.put("Alg.Alias.Signature.1.2.840.10045.4.3.4", "SHA512withECDSA");
+ map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.4", "SHA512withECDSA");
// supported key classes
map.put("Signature.NONEwithRSA SupportedKeyClasses",
- "sun.security.mscapi.Key");
+ "sun.security.mscapi.CKey");
map.put("Signature.SHA1withRSA SupportedKeyClasses",
- "sun.security.mscapi.Key");
+ "sun.security.mscapi.CKey");
map.put("Signature.SHA256withRSA SupportedKeyClasses",
- "sun.security.mscapi.Key");
+ "sun.security.mscapi.CKey");
map.put("Signature.SHA384withRSA SupportedKeyClasses",
- "sun.security.mscapi.Key");
+ "sun.security.mscapi.CKey");
map.put("Signature.SHA512withRSA SupportedKeyClasses",
- "sun.security.mscapi.Key");
+ "sun.security.mscapi.CKey");
map.put("Signature.MD5withRSA SupportedKeyClasses",
- "sun.security.mscapi.Key");
+ "sun.security.mscapi.CKey");
map.put("Signature.MD2withRSA SupportedKeyClasses",
- "sun.security.mscapi.Key");
+ "sun.security.mscapi.CKey");
+
+ map.put("Signature.RSASSA-PSS SupportedKeyClasses",
+ "sun.security.mscapi.CKey");
+
+ map.put("Signature.SHA1withECDSA SupportedKeyClasses",
+ "sun.security.mscapi.CKey");
+ map.put("Signature.SHA224withECDSA SupportedKeyClasses",
+ "sun.security.mscapi.CKey");
+ map.put("Signature.SHA256withECDSA SupportedKeyClasses",
+ "sun.security.mscapi.CKey");
+ map.put("Signature.SHA384withECDSA SupportedKeyClasses",
+ "sun.security.mscapi.CKey");
+ map.put("Signature.SHA512withECDSA SupportedKeyClasses",
+ "sun.security.mscapi.CKey");
/*
* Key Pair Generator engines
*/
map.put("KeyPairGenerator.RSA",
- "sun.security.mscapi.RSAKeyPairGenerator");
+ "sun.security.mscapi.CKeyPairGenerator$RSA");
map.put("KeyPairGenerator.RSA KeySize", "1024");
/*
* Cipher engines
*/
- map.put("Cipher.RSA", "sun.security.mscapi.RSACipher");
+ map.put("Cipher.RSA", "sun.security.mscapi.CRSACipher");
map.put("Cipher.RSA/ECB/PKCS1Padding",
- "sun.security.mscapi.RSACipher");
+ "sun.security.mscapi.CRSACipher");
map.put("Cipher.RSA SupportedModes", "ECB");
map.put("Cipher.RSA SupportedPaddings", "PKCS1PADDING");
- map.put("Cipher.RSA SupportedKeyClasses", "sun.security.mscapi.Key");
+ map.put("Cipher.RSA SupportedKeyClasses", "sun.security.mscapi.CKey");
if (map != this) {
AccessController.doPrivileged(new PutAllAction(this, map));
diff --git a/jdk/src/windows/native/java/lang/ProcessImpl_md.c b/jdk/src/windows/native/java/lang/ProcessImpl_md.c
index 3a013c1..8dcf897 100644
--- a/jdk/src/windows/native/java/lang/ProcessImpl_md.c
+++ b/jdk/src/windows/native/java/lang/ProcessImpl_md.c
@@ -421,10 +421,10 @@
Java_java_lang_ProcessImpl_waitForTimeoutInterruptibly(JNIEnv *env,
jclass ignored,
jlong handle,
- jlong timeout)
+ jlong timeoutMillis)
{
HANDLE events[2];
- DWORD dwTimeout = (DWORD)timeout;
+ DWORD dwTimeout = (DWORD)timeoutMillis;
DWORD result;
events[0] = (HANDLE) handle;
events[1] = JVM_GetThreadInterruptEvent();
diff --git a/jdk/src/windows/native/sun/security/krb5/NativeCreds.c b/jdk/src/windows/native/sun/security/krb5/NativeCreds.c
index b7f81d2..ec891a9 100644
--- a/jdk/src/windows/native/sun/security/krb5/NativeCreds.c
+++ b/jdk/src/windows/native/sun/security/krb5/NativeCreds.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -404,6 +404,8 @@
"(Lsun/security/krb5/internal/Ticket;"
"Lsun/security/krb5/PrincipalName;"
"Lsun/security/krb5/PrincipalName;"
+ "Lsun/security/krb5/PrincipalName;"
+ "Lsun/security/krb5/PrincipalName;"
"Lsun/security/krb5/EncryptionKey;"
"Lsun/security/krb5/internal/TicketFlags;"
"Lsun/security/krb5/internal/KerberosTime;"
@@ -665,7 +667,9 @@
krbcredsConstructor,
ticket,
clientPrincipal,
+ NULL,
targetPrincipal,
+ NULL,
encryptionKey,
ticketFlags,
authTime, // mdu
diff --git a/jdk/src/windows/native/sun/security/mscapi/security.cpp b/jdk/src/windows/native/sun/security/mscapi/security.cpp
index 12c408e..8ba36f5 100644
--- a/jdk/src/windows/native/sun/security/mscapi/security.cpp
+++ b/jdk/src/windows/native/sun/security/mscapi/security.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,14 @@
#include <wincrypt.h>
#include <stdio.h>
#include <memory>
+#include "sun_security_mscapi_CKey.h"
+#include "sun_security_mscapi_CKeyStore.h"
+#include "sun_security_mscapi_CRSACipher.h"
+#include "sun_security_mscapi_CKeyPairGenerator_RSA.h"
+#include "sun_security_mscapi_CPublicKey.h"
+#include "sun_security_mscapi_CPublicKey_CRSAPublicKey.h"
+#include "sun_security_mscapi_CSignature.h"
+#include "sun_security_mscapi_CSignature_RSA.h"
#define OID_EKU_ANY "2.5.29.37.0"
@@ -50,8 +58,55 @@
#define SIGNATURE_EXCEPTION "java/security/SignatureException"
#define OUT_OF_MEMORY_ERROR "java/lang/OutOfMemoryError"
+#define SS_CHECK(Status) \
+ if (Status != ERROR_SUCCESS) { \
+ ThrowException(env, SIGNATURE_EXCEPTION, Status); \
+ __leave; \
+ }
+
+#define PP(fmt, ...) \
+ if (trace) { \
+ fprintf(stdout, "MSCAPI (%ld): ", __LINE__); \
+ fprintf(stdout, fmt, ##__VA_ARGS__); \
+ fprintf(stdout, "\n"); \
+ fflush(stdout); \
+ }
+
extern "C" {
+char* trace = getenv("CAPI_TRACE");
+
+void showProperty(NCRYPT_HANDLE hKey);
+
+void dump(LPSTR title, PBYTE data, DWORD len)
+{
+ if (trace) {
+ printf("==== %s ====\n", title);
+ for (DWORD i = 0; i < len; i+=16) {
+ printf("%04x: ", i);
+ for (int j = 0; j < 16; j++) {
+ if (j == 8) {
+ printf(" ");
+ }
+ if (i + j < len) {
+ printf("%02X ", *(data + i + j) & 0xff);
+ } else {
+ printf(" ");
+ }
+ }
+ for (int j = 0; j < 16; j++) {
+ if (i + j < len) {
+ int k = *(data + i + j) & 0xff;
+ if (k < 32 || k > 127) printf(".");
+ else printf("%c", (char)k);
+ }
+ }
+ printf("\n");
+ }
+ fflush(stdout);
+ }
+}
+
/*
* Throws an arbitrary Java exception with the given message.
*/
@@ -134,6 +189,37 @@
return algId;
}
+/*
+ * Maps the name of a hash algorithm to a CNG Algorithm Identifier.
+ */
+LPCWSTR MapHashIdentifier(JNIEnv *env, jstring jHashAlgorithm) {
+
+ const char* pszHashAlgorithm = NULL;
+ LPCWSTR id = NULL;
+
+ if ((pszHashAlgorithm = env->GetStringUTFChars(jHashAlgorithm, NULL))
+ == NULL) {
+ return id;
+ }
+
+ if ((strcmp("SHA", pszHashAlgorithm) == 0) ||
+ (strcmp("SHA1", pszHashAlgorithm) == 0) ||
+ (strcmp("SHA-1", pszHashAlgorithm) == 0)) {
+
+ id = BCRYPT_SHA1_ALGORITHM;
+ } else if (strcmp("SHA-256", pszHashAlgorithm) == 0) {
+ id = BCRYPT_SHA256_ALGORITHM;
+ } else if (strcmp("SHA-384", pszHashAlgorithm) == 0) {
+ id = BCRYPT_SHA384_ALGORITHM;
+ } else if (strcmp("SHA-512", pszHashAlgorithm) == 0) {
+ id = BCRYPT_SHA512_ALGORITHM;
+ }
+
+ if (pszHashAlgorithm)
+ env->ReleaseStringUTFChars(jHashAlgorithm, pszHashAlgorithm);
+
+ return id;
+}
/*
* Returns a certificate chain context given a certificate context and key
@@ -190,7 +276,7 @@
__try
{
// Acquire a CSP context.
- if(::CryptAcquireContext(
+ if(::CryptAcquireContext( //deprecated
&hCryptProv,
NULL,
NULL,
@@ -218,7 +304,7 @@
__leave;
}
- if (::CryptGenRandom(
+ if (::CryptGenRandom( //deprecated
hCryptProv,
length,
(BYTE *) reseedBytes) == FALSE) {
@@ -244,7 +330,7 @@
__leave;
}
- if (::CryptGenRandom(
+ if (::CryptGenRandom( //deprecated
hCryptProv,
length,
(BYTE *) seedBytes) == FALSE) {
@@ -268,7 +354,7 @@
env->ReleaseByteArrayElements(seed, seedBytes, 0); // update orig
if (hCryptProv)
- ::CryptReleaseContext(hCryptProv, 0);
+ ::CryptReleaseContext(hCryptProv, 0); //deprecated
}
return result;
@@ -276,11 +362,11 @@
/*
- * Class: sun_security_mscapi_KeyStore
+ * Class: sun_security_mscapi_CKeyStore
* Method: loadKeysOrCertificateChains
- * Signature: (Ljava/lang/String;Ljava/util/Collection;)V
+ * Signature: (Ljava/lang/String;)V
*/
-JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_loadKeysOrCertificateChains
+JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateChains
(JNIEnv *env, jobject obj, jstring jCertStoreName)
{
/**
@@ -346,10 +432,10 @@
}
// Determine method ID to generate RSA certificate chain
- jmethodID mGenRSAKeyAndCertChain = env->GetMethodID(clazzOfThis,
- "generateRSAKeyAndCertificateChain",
- "(Ljava/lang/String;JJILjava/util/Collection;)V");
- if (mGenRSAKeyAndCertChain == NULL) {
+ jmethodID mGenKeyAndCertChain = env->GetMethodID(clazzOfThis,
+ "generateKeyAndCertificateChain",
+ "(ZLjava/lang/String;JJILjava/util/Collection;)V");
+ if (mGenKeyAndCertChain == NULL) {
__leave;
}
@@ -358,6 +444,7 @@
// NULL to retrieve the first certificate in the store.
while (pCertContext = ::CertEnumCertificatesInStore(hCertStore, pCertContext))
{
+ PP("--------------------------");
// Check if private key available - client authentication certificate
// must have private key available.
HCRYPTPROV hCryptProv = NULL;
@@ -368,41 +455,48 @@
DWORD dwPublicKeyLength = 0;
// First, probe it silently
- if (::CryptAcquireCertificatePrivateKey(pCertContext, CRYPT_ACQUIRE_SILENT_FLAG, NULL,
+ if (::CryptAcquireCertificatePrivateKey(pCertContext,
+ CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG | CRYPT_ACQUIRE_SILENT_FLAG, NULL,
&hCryptProv, &dwKeySpec, &bCallerFreeProv) == FALSE
&& GetLastError() != NTE_SILENT_CONTEXT)
{
+ PP("bHasNoPrivateKey = TRUE!");
bHasNoPrivateKey = TRUE;
}
else
{
if (bCallerFreeProv == TRUE) {
- ::CryptReleaseContext(hCryptProv, NULL);
+ ::CryptReleaseContext(hCryptProv, NULL); // deprecated
bCallerFreeProv = FALSE;
}
// Second, acquire the key normally (not silently)
- if (::CryptAcquireCertificatePrivateKey(pCertContext, 0, NULL,
+ if (::CryptAcquireCertificatePrivateKey(pCertContext, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, NULL,
&hCryptProv, &dwKeySpec, &bCallerFreeProv) == FALSE)
{
+ PP("bHasNoPrivateKey = TRUE!!");
bHasNoPrivateKey = TRUE;
}
else
{
- // Private key is available
- BOOL bGetUserKey = ::CryptGetUserKey(hCryptProv, dwKeySpec, &hUserKey);
+ if ((dwKeySpec & CERT_NCRYPT_KEY_SPEC) == CERT_NCRYPT_KEY_SPEC) {
+ PP("CNG %I64d", (__int64)hCryptProv);
+ } else {
+ // Private key is available
+ BOOL bGetUserKey = ::CryptGetUserKey(hCryptProv, dwKeySpec, &hUserKey); //deprecated
- // Skip certificate if cannot find private key
- if (bGetUserKey == FALSE) {
- if (bCallerFreeProv)
- ::CryptReleaseContext(hCryptProv, NULL);
- continue;
+ // Skip certificate if cannot find private key
+ if (bGetUserKey == FALSE) {
+ if (bCallerFreeProv)
+ ::CryptReleaseContext(hCryptProv, NULL); // deprecated
+ continue;
+ }
+
+ // Set cipher mode to ECB
+ DWORD dwCipherMode = CRYPT_MODE_ECB;
+ ::CryptSetKeyParam(hUserKey, KP_MODE, (BYTE*)&dwCipherMode, NULL); //deprecated
+ PP("CAPI %I64d %I64d", (__int64)hCryptProv, (__int64)hUserKey);
}
-
- // Set cipher mode to ECB
- DWORD dwCipherMode = CRYPT_MODE_ECB;
- ::CryptSetKeyParam(hUserKey, KP_MODE, (BYTE*)&dwCipherMode, NULL);
-
// If the private key is present in smart card, we may not be able to
// determine the key length by using the private key handle. However,
// since public/private key pairs must have the same length, we could
@@ -491,6 +585,8 @@
// or SAN.
if (pszNameString)
{
+ PP("%s: %s", pszNameString,
+ pCertContext->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
if (bHasNoPrivateKey)
{
// Generate certificate chain and store into cert chain
@@ -505,24 +601,57 @@
}
else
{
- // Determine key type: RSA or DSA
- DWORD dwData = CALG_RSA_KEYX;
- DWORD dwSize = sizeof(DWORD);
- ::CryptGetKeyParam(hUserKey, KP_ALGID, (BYTE*)&dwData,
- &dwSize, NULL);
-
- if ((dwData & ALG_TYPE_RSA) == ALG_TYPE_RSA)
- {
- // Generate RSA certificate chain and store into cert
- // chain collection
- jstring name = env->NewStringUTF(pszNameString);
- if (name == NULL) {
- __leave;
+ if (hUserKey) {
+ // Only accept RSA for CAPI
+ DWORD dwData = CALG_RSA_KEYX;
+ DWORD dwSize = sizeof(DWORD);
+ ::CryptGetKeyParam(hUserKey, KP_ALGID, (BYTE*)&dwData, //deprecated
+ &dwSize, NULL);
+ if ((dwData & ALG_TYPE_RSA) == ALG_TYPE_RSA)
+ {
+ // Generate RSA certificate chain and store into cert
+ // chain collection
+ jstring name = env->NewStringUTF(pszNameString);
+ if (name == NULL) {
+ __leave;
+ }
+ env->CallVoidMethod(obj, mGenKeyAndCertChain,
+ 1,
+ name,
+ (jlong) hCryptProv, (jlong) hUserKey,
+ dwPublicKeyLength, jArrayList);
}
- env->CallVoidMethod(obj, mGenRSAKeyAndCertChain,
- name,
- (jlong) hCryptProv, (jlong) hUserKey,
- dwPublicKeyLength, jArrayList);
+ } else {
+ // Only accept EC for CNG
+ BYTE buffer[32];
+ DWORD len = 0;
+ if (::NCryptGetProperty(
+ hCryptProv, NCRYPT_ALGORITHM_PROPERTY,
+ (PBYTE)buffer, 32, &len, NCRYPT_SILENT_FLAG) == ERROR_SUCCESS) {
+ jstring name = env->NewStringUTF(pszNameString);
+ if (name == NULL) {
+ __leave;
+ }
+ if (buffer[0] == 'E' && buffer[2] == 'C'
+ && (dwPublicKeyLength == 256
+ || dwPublicKeyLength == 384
+ || dwPublicKeyLength == 521)) {
+ env->CallVoidMethod(obj, mGenKeyAndCertChain,
+ 0,
+ name,
+ (jlong) hCryptProv, (jlong) 0,
+ dwPublicKeyLength, jArrayList);
+ } else if (buffer[0] == 'R' && buffer[2] == 'S'
+ && buffer[4] == 'A') {
+ env->CallVoidMethod(obj, mGenKeyAndCertChain,
+ 1,
+ name,
+ (jlong) hCryptProv, (jlong) 0,
+ dwPublicKeyLength, jArrayList);
+ } else {
+ dump("Unknown NCRYPT_ALGORITHM_PROPERTY", buffer, len);
+ }
+ }
}
}
}
@@ -531,6 +660,8 @@
// Free cert chain
if (pCertChainContext)
::CertFreeCertificateChain(pCertChainContext);
+ } else {
+ PP("GetCertificateChain failed %d", GetLastError());
}
}
}
@@ -549,27 +680,30 @@
/*
- * Class: sun_security_mscapi_Key
+ * Class: sun_security_mscapi_CKey
* Method: cleanUp
* Signature: (JJ)V
*/
-JNIEXPORT void JNICALL Java_sun_security_mscapi_Key_cleanUp
+JNIEXPORT void JNICALL Java_sun_security_mscapi_CKey_cleanUp
(JNIEnv *env, jclass clazz, jlong hCryptProv, jlong hCryptKey)
{
- if (hCryptKey != NULL)
- ::CryptDestroyKey((HCRYPTKEY) hCryptKey);
+ if (hCryptKey == NULL && hCryptProv != NULL) {
+ NCryptFreeObject((NCRYPT_HANDLE)hCryptProv);
+ } else {
+ if (hCryptKey != NULL)
+ ::CryptDestroyKey((HCRYPTKEY) hCryptKey); // deprecated
- if (hCryptProv != NULL)
- ::CryptReleaseContext((HCRYPTPROV) hCryptProv, NULL);
+ if (hCryptProv != NULL)
+ ::CryptReleaseContext((HCRYPTPROV) hCryptProv, NULL); // deprecated
+ }
}
-
/*
- * Class: sun_security_mscapi_RSASignature
+ * Class: sun_security_mscapi_CSignature
* Method: signHash
* Signature: (Z[BILjava/lang/String;JJ)[B
*/
-JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CSignature_signHash
(JNIEnv *env, jclass clazz, jboolean noHashOID, jbyteArray jHash,
jint jHashSize, jstring jHashAlgorithm, jlong hCryptProv,
jlong hCryptKey)
@@ -586,7 +720,7 @@
ALG_ID algId = MapHashAlgorithm(env, jHashAlgorithm);
// Acquire a hash object handle.
- if (::CryptCreateHash(HCRYPTPROV(hCryptProv), algId, 0, 0, &hHash) == FALSE)
+ if (::CryptCreateHash(HCRYPTPROV(hCryptProv), algId, 0, 0, &hHash) == FALSE) //deprecated
{
// Failover to using the PROV_RSA_AES CSP
@@ -595,11 +729,11 @@
pbData[0] = '\0';
// Get name of the key container
- ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER,
+ ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER, //deprecated
(BYTE *)pbData, &cbData, 0);
// Acquire an alternative CSP handle
- if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL,
+ if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL, //deprecated
PROV_RSA_AES, 0) == FALSE)
{
@@ -608,7 +742,7 @@
}
// Acquire a hash object handle.
- if (::CryptCreateHash(HCRYPTPROV(hCryptProvAlt), algId, 0, 0,
+ if (::CryptCreateHash(HCRYPTPROV(hCryptProvAlt), algId, 0, 0, //deprecated
&hHash) == FALSE)
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
@@ -624,7 +758,7 @@
env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer);
// Set hash value in the hash object
- if (::CryptSetHashParam(hHash, HP_HASHVAL, (BYTE*)pHashBuffer, NULL) == FALSE)
+ if (::CryptSetHashParam(hHash, HP_HASHVAL, (BYTE*)pHashBuffer, NULL) == FALSE) //deprecated
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave;
@@ -635,7 +769,7 @@
ALG_ID dwAlgId;
DWORD dwAlgIdLen = sizeof(ALG_ID);
- if (! ::CryptGetKeyParam((HCRYPTKEY) hCryptKey, KP_ALGID, (BYTE*)&dwAlgId, &dwAlgIdLen, 0)) {
+ if (! ::CryptGetKeyParam((HCRYPTKEY) hCryptKey, KP_ALGID, (BYTE*)&dwAlgId, &dwAlgIdLen, 0)) { //deprecated
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave;
@@ -652,7 +786,7 @@
dwFlags = CRYPT_NOHASHOID; // omit hash OID in NONEwithRSA signature
}
- if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, NULL, &dwBufLen) == FALSE)
+ if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, NULL, &dwBufLen) == FALSE) //deprecated
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave;
@@ -662,7 +796,7 @@
if (pSignedHashBuffer == NULL) {
__leave;
}
- if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, (BYTE*)pSignedHashBuffer, &dwBufLen) == FALSE)
+ if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, (BYTE*)pSignedHashBuffer, &dwBufLen) == FALSE) //deprecated
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave;
@@ -688,21 +822,143 @@
delete [] pHashBuffer;
if (hHash)
- ::CryptDestroyHash(hHash);
+ ::CryptDestroyHash(hHash); //deprecated
if (hCryptProvAlt)
- ::CryptReleaseContext(hCryptProvAlt, 0);
+ ::CryptReleaseContext(hCryptProvAlt, 0); // deprecated
}
return jSignedHash;
}
/*
- * Class: sun_security_mscapi_RSASignature
+ * Class: sun_security_mscapi_CSignature
+ * Method: signCngHash
+ * Signature: (I[BIILjava/lang/String;JJ)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CSignature_signCngHash
+ (JNIEnv *env, jclass clazz, jint type, jbyteArray jHash,
+ jint jHashSize, jint saltLen, jstring jHashAlgorithm, jlong hCryptProv,
+ jlong hCryptKey)
+{
+ jbyteArray jSignedHash = NULL;
+
+ jbyte* pHashBuffer = NULL;
+ jbyte* pSignedHashBuffer = NULL;
+ NCRYPT_KEY_HANDLE hk = NULL;
+
+ __try
+ {
+ if (hCryptKey == 0) {
+ hk = (NCRYPT_KEY_HANDLE)hCryptProv;
+ } else {
+ SS_CHECK(::NCryptTranslateHandle(
+ NULL,
+ &hk,
+ (HCRYPTPROV)hCryptProv,
+ (HCRYPTKEY)hCryptKey,
+ NULL,
+ 0));
+ }
+
+ // Copy hash from Java to native buffer
+ pHashBuffer = new (env) jbyte[jHashSize];
+ if (pHashBuffer == NULL) {
+ __leave;
+ }
+ env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer);
+
+ VOID* param;
+ DWORD dwFlags;
+
+ switch (type) {
+ case 0:
+ param = NULL;
+ dwFlags = 0;
+ break;
+ case 1:
+ BCRYPT_PKCS1_PADDING_INFO pkcs1Info;
+ if (jHashAlgorithm) {
+ pkcs1Info.pszAlgId = MapHashIdentifier(env, jHashAlgorithm);
+ if (pkcs1Info.pszAlgId == NULL) {
+ ThrowExceptionWithMessage(env, SIGNATURE_EXCEPTION,
+ "Unrecognised hash algorithm");
+ __leave;
+ }
+ } else {
+ pkcs1Info.pszAlgId = NULL;
+ }
+ param = &pkcs1Info;
+ dwFlags = BCRYPT_PAD_PKCS1;
+ break;
+ case 2:
+ BCRYPT_PSS_PADDING_INFO pssInfo;
+ pssInfo.pszAlgId = MapHashIdentifier(env, jHashAlgorithm);
+ pssInfo.cbSalt = saltLen;
+ if (pssInfo.pszAlgId == NULL) {
+ ThrowExceptionWithMessage(env, SIGNATURE_EXCEPTION,
+ "Unrecognised hash algorithm");
+ __leave;
+ }
+ param = &pssInfo;
+ dwFlags = BCRYPT_PAD_PSS;
+ break;
+ }
+
+ DWORD jSignedHashSize = 0;
+ SS_CHECK(::NCryptSignHash(
+ hk,
+ param,
+ (BYTE*)pHashBuffer, jHashSize,
+ NULL, 0, &jSignedHashSize,
+ dwFlags
+ ));
+
+ pSignedHashBuffer = new (env) jbyte[jSignedHashSize];
+ if (pSignedHashBuffer == NULL) {
+ __leave;
+ }
+
+ SS_CHECK(::NCryptSignHash(
+ hk,
+ param,
+ (BYTE*)pHashBuffer, jHashSize,
+ (BYTE*)pSignedHashBuffer, jSignedHashSize, &jSignedHashSize,
+ dwFlags
+ ));
+
+ // Create new byte array
+ jbyteArray temp = env->NewByteArray(jSignedHashSize);
+ if (temp == NULL) {
+ __leave;
+ }
+
+ // Copy data from native buffer
+ env->SetByteArrayRegion(temp, 0, jSignedHashSize, pSignedHashBuffer);
+
+ jSignedHash = temp;
+ }
+ __finally
+ {
+ if (pSignedHashBuffer)
+ delete [] pSignedHashBuffer;
+
+ if (pHashBuffer)
+ delete [] pHashBuffer;
+
+ if (hCryptKey != 0 && hk != NULL)
+ ::NCryptFreeObject(hk);
+ }
+
+ return jSignedHash;
+}
+
+/*
+ * Class: sun_security_mscapi_CSignature
* Method: verifySignedHash
* Signature: ([BIL/java/lang/String;[BIJJ)Z
*/
-JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_RSASignature_verifySignedHash
+JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_CSignature_verifySignedHash
(JNIEnv *env, jclass clazz, jbyteArray jHash, jint jHashSize,
jstring jHashAlgorithm, jbyteArray jSignedHash, jint jSignedHashSize,
jlong hCryptProv, jlong hCryptKey)
@@ -730,11 +986,11 @@
pbData[0] = '\0';
// Get name of the key container
- ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER,
+ ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER, //deprecated
(BYTE *)pbData, &cbData, 0);
// Acquire an alternative CSP handle
- if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL,
+ if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL, //deprecated
PROV_RSA_AES, 0) == FALSE)
{
@@ -766,7 +1022,7 @@
pSignedHashBuffer);
// Set hash value in the hash object
- if (::CryptSetHashParam(hHash, HP_HASHVAL, (BYTE*) pHashBuffer, NULL)
+ if (::CryptSetHashParam(hHash, HP_HASHVAL, (BYTE*) pHashBuffer, NULL) //deprecated
== FALSE)
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
@@ -777,7 +1033,7 @@
// public key algorithm, so AT_SIGNATURE is used.
// Verify the signature
- if (::CryptVerifySignatureA(hHash, (BYTE *) pSignedHashBuffer,
+ if (::CryptVerifySignatureA(hHash, (BYTE *) pSignedHashBuffer, //deprecated
dwSignedHashBufferLen, (HCRYPTKEY) hCryptKey, NULL, 0) == TRUE)
{
result = JNI_TRUE;
@@ -793,22 +1049,225 @@
delete [] pHashBuffer;
if (hHash)
- ::CryptDestroyHash(hHash);
+ ::CryptDestroyHash(hHash); //deprecated
if (hCryptProvAlt)
- ::CryptReleaseContext(hCryptProvAlt, 0);
+ ::CryptReleaseContext(hCryptProvAlt, 0); // deprecated
}
return result;
}
/*
- * Class: sun_security_mscapi_RSAKeyPairGenerator
- * Method: generateRSAKeyPair
- * Signature: (ILjava/lang/String;)Lsun/security/mscapi/RSAKeyPair;
+ * Class: sun_security_mscapi_CSignature
+ * Method: verifyCngSignedHash
+ * Signature: (I[BI[BIILjava/lang/String;JJ)Z
*/
-JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSAKeyPairGenerator_generateRSAKeyPair
- (JNIEnv *env, jclass clazz, jint keySize, jstring keyContainerName)
+JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_CSignature_verifyCngSignedHash
+ (JNIEnv *env, jclass clazz, jint type,
+ jbyteArray jHash, jint jHashSize,
+ jbyteArray jSignedHash, jint jSignedHashSize,
+ jint saltLen, jstring jHashAlgorithm,
+ jlong hCryptProv, jlong hCryptKey)
+{
+ jbyte* pHashBuffer = NULL;
+ jbyte* pSignedHashBuffer = NULL;
+ jboolean result = JNI_FALSE;
+ NCRYPT_KEY_HANDLE hk = NULL;
+
+ __try
+ {
+ if (hCryptKey == 0) {
+ hk = (NCRYPT_KEY_HANDLE)hCryptProv;
+ } else {
+ SS_CHECK(::NCryptTranslateHandle(
+ NULL,
+ &hk,
+ (HCRYPTPROV)hCryptProv,
+ (HCRYPTKEY)hCryptKey,
+ NULL,
+ 0));
+ }
+
+ // Copy hash and signedHash from Java to native buffer
+ pHashBuffer = new (env) jbyte[jHashSize];
+ if (pHashBuffer == NULL) {
+ __leave;
+ }
+ env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer);
+
+ pSignedHashBuffer = new (env) jbyte[jSignedHashSize];
+ if (pSignedHashBuffer == NULL) {
+ __leave;
+ }
+ env->GetByteArrayRegion(jSignedHash, 0, jSignedHashSize,
+ pSignedHashBuffer);
+
+ VOID* param;
+ DWORD dwFlags;
+
+ switch (type) {
+ case 0:
+ param = NULL;
+ dwFlags = 0;
+ break;
+ case 1:
+ BCRYPT_PKCS1_PADDING_INFO pkcs1Info;
+ if (jHashAlgorithm) {
+ pkcs1Info.pszAlgId = MapHashIdentifier(env, jHashAlgorithm);
+ if (pkcs1Info.pszAlgId == NULL) {
+ ThrowExceptionWithMessage(env, SIGNATURE_EXCEPTION,
+ "Unrecognised hash algorithm");
+ __leave;
+ }
+ } else {
+ pkcs1Info.pszAlgId = NULL;
+ }
+ param = &pkcs1Info;
+ dwFlags = NCRYPT_PAD_PKCS1_FLAG;
+ break;
+ case 2:
+ BCRYPT_PSS_PADDING_INFO pssInfo;
+ pssInfo.pszAlgId = MapHashIdentifier(env, jHashAlgorithm);
+ pssInfo.cbSalt = saltLen;
+ if (pssInfo.pszAlgId == NULL) {
+ ThrowExceptionWithMessage(env, SIGNATURE_EXCEPTION,
+ "Unrecognised hash algorithm");
+ __leave;
+ }
+ param = &pssInfo;
+ dwFlags = NCRYPT_PAD_PSS_FLAG;
+ break;
+ }
+
+ if (::NCryptVerifySignature(hk, param,
+ (BYTE *) pHashBuffer, jHashSize,
+ (BYTE *) pSignedHashBuffer, jSignedHashSize,
+ dwFlags) == ERROR_SUCCESS)
+ {
+ result = JNI_TRUE;
+ }
+ }
+
+ __finally
+ {
+ if (pSignedHashBuffer)
+ delete [] pSignedHashBuffer;
+
+ if (pHashBuffer)
+ delete [] pHashBuffer;
+
+ if (hCryptKey != 0 && hk != NULL)
+ ::NCryptFreeObject(hk);
+ }
+
+ return result;
+}
+
+#define DUMP_PROP(p) \
+ if (::NCryptGetProperty(hKey, p, (PBYTE)buffer, 8192, &len, NCRYPT_SILENT_FLAG) == ERROR_SUCCESS) { \
+ sprintf(header, "%s %ls", #p, p); \
+ dump(header, buffer, len); \
+ }
+
+#define EXPORT_BLOB(p) \
+ desc.cBuffers = 0; \
+ if (::NCryptExportKey(hKey, NULL, p, &desc, (PBYTE)buffer, 8192, &len, NCRYPT_SILENT_FLAG) == ERROR_SUCCESS) { \
+ sprintf(header, "%s %ls (%ld)", #p, p, desc.cBuffers); \
+ dump(header, buffer, len); \
+ for (int i = 0; i < (int)desc.cBuffers; i++) { \
+ sprintf(header, "desc %ld", desc.pBuffers[i].BufferType); \
+ dump(header, (PBYTE)desc.pBuffers[i].pvBuffer, desc.pBuffers[i].cbBuffer); \
+ } \
+ }
+
+void showProperty(NCRYPT_HANDLE hKey) {
+ char header[100];
+ BYTE buffer[8192];
+ DWORD len = 9;
+ NCryptBufferDesc desc;
+ DUMP_PROP(NCRYPT_ALGORITHM_GROUP_PROPERTY);
+ DUMP_PROP(NCRYPT_ALGORITHM_PROPERTY);
+ DUMP_PROP(NCRYPT_ASSOCIATED_ECDH_KEY);
+ DUMP_PROP(NCRYPT_BLOCK_LENGTH_PROPERTY);
+ DUMP_PROP(NCRYPT_CERTIFICATE_PROPERTY);
+ DUMP_PROP(NCRYPT_DH_PARAMETERS_PROPERTY);
+ DUMP_PROP(NCRYPT_EXPORT_POLICY_PROPERTY);
+ DUMP_PROP(NCRYPT_IMPL_TYPE_PROPERTY);
+ DUMP_PROP(NCRYPT_KEY_TYPE_PROPERTY);
+ DUMP_PROP(NCRYPT_KEY_USAGE_PROPERTY);
+ DUMP_PROP(NCRYPT_LAST_MODIFIED_PROPERTY);
+ DUMP_PROP(NCRYPT_LENGTH_PROPERTY);
+ DUMP_PROP(NCRYPT_LENGTHS_PROPERTY);
+ DUMP_PROP(NCRYPT_MAX_NAME_LENGTH_PROPERTY);
+ DUMP_PROP(NCRYPT_NAME_PROPERTY);
+ DUMP_PROP(NCRYPT_PIN_PROMPT_PROPERTY);
+ DUMP_PROP(NCRYPT_PIN_PROPERTY);
+ DUMP_PROP(NCRYPT_PROVIDER_HANDLE_PROPERTY);
+ DUMP_PROP(NCRYPT_READER_PROPERTY);
+ DUMP_PROP(NCRYPT_ROOT_CERTSTORE_PROPERTY);
+ DUMP_PROP(NCRYPT_SCARD_PIN_ID);
+ DUMP_PROP(NCRYPT_SCARD_PIN_INFO);
+ DUMP_PROP(NCRYPT_SECURE_PIN_PROPERTY);
+ DUMP_PROP(NCRYPT_SECURITY_DESCR_PROPERTY);
+ DUMP_PROP(NCRYPT_SECURITY_DESCR_SUPPORT_PROPERTY);
+ DUMP_PROP(NCRYPT_SMARTCARD_GUID_PROPERTY);
+ DUMP_PROP(NCRYPT_UI_POLICY_PROPERTY);
+ DUMP_PROP(NCRYPT_UNIQUE_NAME_PROPERTY);
+ DUMP_PROP(NCRYPT_USE_CONTEXT_PROPERTY);
+ DUMP_PROP(NCRYPT_USE_COUNT_ENABLED_PROPERTY);
+ DUMP_PROP(NCRYPT_USE_COUNT_PROPERTY);
+ DUMP_PROP(NCRYPT_USER_CERTSTORE_PROPERTY);
+ DUMP_PROP(NCRYPT_VERSION_PROPERTY);
+ DUMP_PROP(NCRYPT_WINDOW_HANDLE_PROPERTY);
+
+ EXPORT_BLOB(BCRYPT_DH_PRIVATE_BLOB);
+ EXPORT_BLOB(BCRYPT_DH_PUBLIC_BLOB);
+ EXPORT_BLOB(BCRYPT_DSA_PRIVATE_BLOB);
+ EXPORT_BLOB(BCRYPT_DSA_PUBLIC_BLOB);
+ EXPORT_BLOB(BCRYPT_ECCPRIVATE_BLOB);
+ EXPORT_BLOB(BCRYPT_ECCPUBLIC_BLOB);
+ EXPORT_BLOB(BCRYPT_PUBLIC_KEY_BLOB);
+ EXPORT_BLOB(BCRYPT_PRIVATE_KEY_BLOB);
+ EXPORT_BLOB(BCRYPT_RSAFULLPRIVATE_BLOB);
+ EXPORT_BLOB(BCRYPT_RSAPRIVATE_BLOB);
+ EXPORT_BLOB(BCRYPT_RSAPUBLIC_BLOB);
+ EXPORT_BLOB(LEGACY_DH_PRIVATE_BLOB);
+ EXPORT_BLOB(LEGACY_DH_PUBLIC_BLOB);
+ EXPORT_BLOB(LEGACY_DSA_PRIVATE_BLOB);
+ EXPORT_BLOB(LEGACY_DSA_PUBLIC_BLOB);
+ EXPORT_BLOB(LEGACY_RSAPRIVATE_BLOB);
+ EXPORT_BLOB(LEGACY_RSAPUBLIC_BLOB);
+ // Support starts from Windows 8 and Windows Server 2012
+ //EXPORT_BLOB(NCRYPT_CIPHER_KEY_BLOB);
+ EXPORT_BLOB(NCRYPT_OPAQUETRANSPORT_BLOB);
+ EXPORT_BLOB(NCRYPT_PKCS7_ENVELOPE_BLOB);
+ //EXPORT_BLOB(NCRYPTBUFFER_CERT_BLOB);
+ //EXPORT_BLOB(NCRYPT_PKCS8_PRIVATE_KEY_BLOB);
+ BCryptBuffer bb;
+ bb.BufferType = NCRYPTBUFFER_PKCS_SECRET;
+ bb.cbBuffer = 18;
+ bb.pvBuffer = L"changeit";
+ BCryptBufferDesc bbd;
+ bbd.ulVersion = 0;
+ bbd.cBuffers = 1;
+ bbd.pBuffers = &bb;
+ if(::NCryptExportKey(hKey, NULL, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, NULL,
+ (PBYTE)buffer, 8192, &len, NCRYPT_SILENT_FLAG) == ERROR_SUCCESS) {
+ sprintf(header, "NCRYPT_PKCS8_PRIVATE_KEY_BLOB %ls", NCRYPT_PKCS8_PRIVATE_KEY_BLOB);
+ dump(header, buffer, len);
+ }
+ // Support starts from Windows 8 and Windows Server 2012
+ //EXPORT_BLOB(NCRYPT_PROTECTED_KEY_BLOB);
+}
+
+/*
+ * Class: sun_security_mscapi_CKeyPairGenerator_RSA
+ * Method: generateCKeyPair
+ * Signature: (Ljava/lang/String;ILjava/lang/String;)Lsun/security/mscapi/CKeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_sun_security_mscapi_CKeyPairGenerator_00024RSA_generateCKeyPair
+ (JNIEnv *env, jclass clazz, jstring alg, jint keySize, jstring keyContainerName)
{
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKeyPair;
@@ -826,7 +1285,7 @@
// Acquire a CSP context (create a new key container).
// Prefer a PROV_RSA_AES CSP, when available, due to its support
// for SHA-2-based signatures.
- if (::CryptAcquireContext(
+ if (::CryptAcquireContext( //deprecated
&hCryptProv,
pszKeyContainerName,
NULL,
@@ -835,7 +1294,7 @@
{
// Failover to using the default CSP (PROV_RSA_FULL)
- if (::CryptAcquireContext(
+ if (::CryptAcquireContext( //deprecated
&hCryptProv,
pszKeyContainerName,
NULL,
@@ -847,8 +1306,8 @@
}
}
- // Generate an RSA keypair
- if(::CryptGenKey(
+ // Generate an keypair
+ if(::CryptGenKey( //deprecated
hCryptProv,
AT_KEYEXCHANGE,
dwFlags,
@@ -858,22 +1317,22 @@
__leave;
}
- // Get the method ID for the RSAKeyPair constructor
- jclass clazzRSAKeyPair =
- env->FindClass("sun/security/mscapi/RSAKeyPair");
- if (clazzRSAKeyPair == NULL) {
+ // Get the method ID for the CKeyPair constructor
+ jclass clazzCKeyPair =
+ env->FindClass("sun/security/mscapi/CKeyPair");
+ if (clazzCKeyPair == NULL) {
__leave;
}
- jmethodID mNewRSAKeyPair =
- env->GetMethodID(clazzRSAKeyPair, "<init>", "(JJI)V");
- if (mNewRSAKeyPair == NULL) {
+ jmethodID mNewCKeyPair =
+ env->GetMethodID(clazzCKeyPair, "<init>", "(Ljava/lang/String;JJI)V");
+ if (mNewCKeyPair == NULL) {
__leave;
}
- // Create a new RSA keypair
- keypair = env->NewObject(clazzRSAKeyPair, mNewRSAKeyPair,
- (jlong) hCryptProv, (jlong) hKeyPair, keySize);
+ // Create a new keypair
+ keypair = env->NewObject(clazzCKeyPair, mNewCKeyPair,
+ alg, (jlong) hCryptProv, (jlong) hKeyPair, keySize);
}
__finally
@@ -889,18 +1348,18 @@
}
/*
- * Class: sun_security_mscapi_Key
+ * Class: sun_security_mscapi_CKey
* Method: getContainerName
* Signature: (J)Ljava/lang/String;
*/
-JNIEXPORT jstring JNICALL Java_sun_security_mscapi_Key_getContainerName
+JNIEXPORT jstring JNICALL Java_sun_security_mscapi_CKey_getContainerName
(JNIEnv *env, jclass jclazz, jlong hCryptProv)
{
DWORD cbData = 256;
BYTE pbData[256];
pbData[0] = '\0';
- ::CryptGetProvParam(
+ ::CryptGetProvParam( //deprecated
(HCRYPTPROV)hCryptProv,
PP_CONTAINER,
(BYTE *)pbData,
@@ -911,17 +1370,17 @@
}
/*
- * Class: sun_security_mscapi_Key
+ * Class: sun_security_mscapi_CKey
* Method: getKeyType
* Signature: (J)Ljava/lang/String;
*/
-JNIEXPORT jstring JNICALL Java_sun_security_mscapi_Key_getKeyType
+JNIEXPORT jstring JNICALL Java_sun_security_mscapi_CKey_getKeyType
(JNIEnv *env, jclass jclazz, jlong hCryptKey)
{
ALG_ID dwAlgId;
DWORD dwAlgIdLen = sizeof(ALG_ID);
- if (::CryptGetKeyParam((HCRYPTKEY) hCryptKey, KP_ALGID, (BYTE*)&dwAlgId, &dwAlgIdLen, 0)) {
+ if (::CryptGetKeyParam((HCRYPTKEY) hCryptKey, KP_ALGID, (BYTE*)&dwAlgId, &dwAlgIdLen, 0)) { //deprecated
if (CALG_RSA_SIGN == dwAlgId) {
return env->NewStringUTF("Signature");
@@ -941,11 +1400,11 @@
}
/*
- * Class: sun_security_mscapi_KeyStore
+ * Class: sun_security_mscapi_CKeyStore
* Method: storeCertificate
* Signature: (Ljava/lang/String;Ljava/lang/String;[BIJJ)V
*/
-JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_storeCertificate
+JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_storeCertificate
(JNIEnv *env, jobject obj, jstring jCertStoreName, jstring jCertAliasName,
jbyteArray jCertEncoding, jint jCertEncodingSize, jlong hCryptProv,
jlong hCryptKey)
@@ -1023,7 +1482,7 @@
DWORD dwDataLen;
// Get the name of the key container
- if (! ::CryptGetProvParam(
+ if (! ::CryptGetProvParam( //deprecated
(HCRYPTPROV) hCryptProv,
PP_CONTAINER,
NULL,
@@ -1039,7 +1498,7 @@
__leave;
}
- if (! ::CryptGetProvParam(
+ if (! ::CryptGetProvParam( //deprecated
(HCRYPTPROV) hCryptProv,
PP_CONTAINER,
(BYTE *) pszContainerName,
@@ -1066,7 +1525,7 @@
// Get the name of the provider
- if (! ::CryptGetProvParam(
+ if (! ::CryptGetProvParam( //deprecated
(HCRYPTPROV) hCryptProv,
PP_NAME,
NULL,
@@ -1082,7 +1541,7 @@
__leave;
}
- if (! ::CryptGetProvParam(
+ if (! ::CryptGetProvParam( //deprecated
(HCRYPTPROV) hCryptProv,
PP_NAME,
(BYTE *) pszProviderName,
@@ -1108,7 +1567,7 @@
keyProviderInfo.pwszProvName = pwszProviderName;
// Get and set the type of the provider
- if (! ::CryptGetProvParam(
+ if (! ::CryptGetProvParam( //deprecated
(HCRYPTPROV) hCryptProv,
PP_PROVTYPE,
(LPBYTE) &keyProviderInfo.dwProvType,
@@ -1127,7 +1586,7 @@
keyProviderInfo.rgProvParam = NULL;
// Get the key's algorithm ID
- if (! ::CryptGetKeyParam(
+ if (! ::CryptGetKeyParam( //deprecated
(HCRYPTKEY) hCryptKey,
KP_ALGID,
(LPBYTE) &keyProviderInfo.dwKeySpec,
@@ -1206,11 +1665,11 @@
}
/*
- * Class: sun_security_mscapi_KeyStore
+ * Class: sun_security_mscapi_CKeyStore
* Method: removeCertificate
* Signature: (Ljava/lang/String;Ljava/lang/String;[BI)V
*/
-JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_removeCertificate
+JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_removeCertificate
(JNIEnv *env, jobject obj, jstring jCertStoreName, jstring jCertAliasName,
jbyteArray jCertEncoding, jint jCertEncodingSize) {
@@ -1322,12 +1781,12 @@
}
/*
- * Class: sun_security_mscapi_KeyStore
+ * Class: sun_security_mscapi_CKeyStore
* Method: destroyKeyContainer
* Signature: (Ljava/lang/String;)V
*/
-JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_destroyKeyContainer
- (JNIEnv *env, jclass clazz, jstring keyContainerName)
+JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_destroyKeyContainer
+ (JNIEnv *env, jobject clazz, jstring keyContainerName)
{
HCRYPTPROV hCryptProv = NULL;
const char* pszKeyContainerName = NULL;
@@ -1348,7 +1807,7 @@
}
// Acquire a CSP context (to the key container).
- if (::CryptAcquireContext(
+ if (::CryptAcquireContext( //deprecated
&hCryptProv,
pszKeyContainerName,
NULL,
@@ -1370,218 +1829,12 @@
}
}
-
-
-
/*
- * Class: sun_security_mscapi_RSACipher
- * Method: findCertificateUsingAlias
- * Signature: (Ljava/lang/String;Ljava/lang/String;)J
- */
-JNIEXPORT jlong JNICALL Java_sun_security_mscapi_RSACipher_findCertificateUsingAlias
- (JNIEnv *env, jobject obj, jstring jCertStoreName, jstring jCertAliasName)
-{
- const char* pszCertStoreName = NULL;
- const char* pszCertAliasName = NULL;
- HCERTSTORE hCertStore = NULL;
- PCCERT_CONTEXT pCertContext = NULL;
- char* pszNameString = NULL; // certificate's friendly name
- DWORD cchNameString = 0;
-
- __try
- {
- if ((pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL))
- == NULL) {
- __leave;
- }
- if ((pszCertAliasName = env->GetStringUTFChars(jCertAliasName, NULL))
- == NULL) {
- __leave;
- }
-
- // Open a system certificate store.
- if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName)) == NULL) {
- ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
- __leave;
- }
-
- // Use CertEnumCertificatesInStore to get the certificates
- // from the open store. pCertContext must be reset to
- // NULL to retrieve the first certificate in the store.
- while (pCertContext = ::CertEnumCertificatesInStore(hCertStore, pCertContext))
- {
- if ((cchNameString = ::CertGetNameString(pCertContext,
- CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, NULL, 0)) == 1) {
-
- continue; // not found
- }
-
- pszNameString = new (env) char[cchNameString];
- if (pszNameString == NULL) {
- __leave;
- }
-
- if (::CertGetNameString(pCertContext,
- CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString,
- cchNameString) == 1) {
-
- continue; // not found
- }
-
- // Compare the certificate's friendly name with supplied alias name
- if (strcmp(pszCertAliasName, pszNameString) == 0) {
- delete [] pszNameString;
- break;
-
- } else {
- delete [] pszNameString;
- }
- }
- }
- __finally
- {
- if (hCertStore)
- ::CertCloseStore(hCertStore, 0);
-
- if (pszCertStoreName)
- env->ReleaseStringUTFChars(jCertStoreName, pszCertStoreName);
-
- if (pszCertAliasName)
- env->ReleaseStringUTFChars(jCertAliasName, pszCertAliasName);
- }
-
- return (jlong) pCertContext;
-}
-
-/*
- * Class: sun_security_mscapi_RSACipher
- * Method: getKeyFromCert
- * Signature: (JZ)J
- */
-JNIEXPORT jlong JNICALL Java_sun_security_mscapi_RSACipher_getKeyFromCert
- (JNIEnv *env, jobject obj, jlong pCertContext, jboolean usePrivateKey)
-{
- HCRYPTPROV hCryptProv = NULL;
- HCRYPTKEY hKey = NULL;
- DWORD dwKeySpec;
- BOOL bCallerFreeProv = FALSE;
- BOOL bRes;
-
- __try
- {
- if (usePrivateKey == JNI_TRUE) {
- // Locate the key container for the certificate's private key
-
- // First, probe it silently
- bRes = ::CryptAcquireCertificatePrivateKey(
- (PCCERT_CONTEXT) pCertContext, CRYPT_ACQUIRE_SILENT_FLAG,
- NULL, &hCryptProv, &dwKeySpec, &bCallerFreeProv);
-
- if (bRes == FALSE && GetLastError() != NTE_SILENT_CONTEXT)
- {
- ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
- __leave;
- }
-
- if (bCallerFreeProv == TRUE) {
- ::CryptReleaseContext(hCryptProv, NULL);
- bCallerFreeProv = FALSE;
- }
-
- // Now, do it normally (not silently)
- if (::CryptAcquireCertificatePrivateKey(
- (PCCERT_CONTEXT) pCertContext, 0, NULL, &hCryptProv,
- &dwKeySpec, &bCallerFreeProv) == FALSE)
- {
- ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
- __leave;
- }
-
- // Get a handle to the private key
- if (::CryptGetUserKey(hCryptProv, dwKeySpec, &hKey) == FALSE) {
- ThrowException(env, KEY_EXCEPTION, GetLastError());
- __leave;
- }
- }
- else // use public key
- {
- bCallerFreeProv = TRUE;
-
- // Acquire a CSP context.
- if (::CryptAcquireContext(&hCryptProv, "J2SE", NULL,
- PROV_RSA_FULL, 0) == FALSE)
- {
- // If CSP context hasn't been created, create one.
- //
- if (::CryptAcquireContext(&hCryptProv, "J2SE", NULL,
- PROV_RSA_FULL, CRYPT_NEWKEYSET) == FALSE)
- {
- ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
- __leave;
- }
- }
-
- // Import the certificate's public key into the key container
- if (::CryptImportPublicKeyInfo(hCryptProv, X509_ASN_ENCODING,
- &(((PCCERT_CONTEXT) pCertContext)->pCertInfo->SubjectPublicKeyInfo),
- &hKey) == FALSE)
- {
- ThrowException(env, KEY_EXCEPTION, GetLastError());
- __leave;
- }
- }
- }
- __finally
- {
- //--------------------------------------------------------------------
- // Clean up.
-
- if (bCallerFreeProv == TRUE && hCryptProv != NULL)
- ::CryptReleaseContext(hCryptProv, 0);
- }
-
- return hKey; // TODO - when finished with this key, call
- // CryptDestroyKey(hKey)
-}
-
-/*
- * Class: sun_security_mscapi_KeyStore
- * Method: getKeyLength
- * Signature: (J)I
- */
-JNIEXPORT jint JNICALL Java_sun_security_mscapi_KeyStore_getKeyLength
- (JNIEnv *env, jobject obj, jlong hKey)
-{
- DWORD dwDataLen = sizeof(DWORD);
- BYTE pbData[sizeof(DWORD)];
- DWORD length = 0;
-
- __try
- {
- // Get key length (in bits)
- //TODO - may need to use KP_BLOCKLEN instead?
- if (!(::CryptGetKeyParam((HCRYPTKEY) hKey, KP_KEYLEN, (BYTE *)pbData, &dwDataLen,
- 0))) {
-
- ThrowException(env, KEY_EXCEPTION, GetLastError());
- __leave;
- }
- length = (DWORD) pbData;
- }
- __finally
- {
- // no cleanup required
- }
-
- return (jint) length;
-}
-
-/*
- * Class: sun_security_mscapi_RSACipher
+ * Class: sun_security_mscapi_CRSACipher
* Method: encryptDecrypt
* Signature: ([BIJZ)[B
*/
-JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSACipher_encryptDecrypt
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CRSACipher_encryptDecrypt
(JNIEnv *env, jclass clazz, jbyteArray jData, jint jDataSize, jlong hKey,
jboolean doEncrypt)
{
@@ -1603,7 +1856,7 @@
if (doEncrypt == JNI_TRUE) {
// encrypt
- if (! ::CryptEncrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData,
+ if (! ::CryptEncrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData, //deprecated
&dwDataLen, dwBufLen)) {
ThrowException(env, KEY_EXCEPTION, GetLastError());
@@ -1626,7 +1879,7 @@
}
// decrypt
- if (! ::CryptDecrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData,
+ if (! ::CryptDecrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData, //deprecated
&dwBufLen)) {
ThrowException(env, KEY_EXCEPTION, GetLastError());
@@ -1652,12 +1905,12 @@
}
/*
- * Class: sun_security_mscapi_RSAPublicKey
+ * Class: sun_security_mscapi_CPublicKey
* Method: getPublicKeyBlob
- * Signature: (J)[B
+ * Signature: (JJ)[B
*/
-JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSAPublicKey_getPublicKeyBlob
- (JNIEnv *env, jclass clazz, jlong hCryptKey) {
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_getPublicKeyBlob
+ (JNIEnv *env, jobject clazz, jlong hCryptProv, jlong hCryptKey) {
jbyteArray blob = NULL;
DWORD dwBlobLen;
@@ -1667,11 +1920,17 @@
{
// Determine the size of the blob
- if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0, NULL,
- &dwBlobLen)) {
+ if (hCryptKey == 0) {
+ SS_CHECK(::NCryptExportKey(
+ (NCRYPT_KEY_HANDLE)hCryptProv, NULL, BCRYPT_ECCPUBLIC_BLOB,
+ NULL, NULL, 0, &dwBlobLen, NCRYPT_SILENT_FLAG));
+ } else {
+ if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0, NULL, //deprecated
+ &dwBlobLen)) {
- ThrowException(env, KEY_EXCEPTION, GetLastError());
- __leave;
+ ThrowException(env, KEY_EXCEPTION, GetLastError());
+ __leave;
+ }
}
pbKeyBlob = new (env) BYTE[dwBlobLen];
@@ -1680,11 +1939,17 @@
}
// Generate key blob
- if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0,
- pbKeyBlob, &dwBlobLen)) {
+ if (hCryptKey == 0) {
+ SS_CHECK(::NCryptExportKey(
+ (NCRYPT_KEY_HANDLE)hCryptProv, NULL, BCRYPT_ECCPUBLIC_BLOB,
+ NULL, pbKeyBlob, dwBlobLen, &dwBlobLen, NCRYPT_SILENT_FLAG));
+ } else {
+ if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0, //deprecated
+ pbKeyBlob, &dwBlobLen)) {
- ThrowException(env, KEY_EXCEPTION, GetLastError());
- __leave;
+ ThrowException(env, KEY_EXCEPTION, GetLastError());
+ __leave;
+ }
}
// Create new byte array
@@ -1705,12 +1970,12 @@
}
/*
- * Class: sun_security_mscapi_RSAPublicKey
+ * Class: sun_security_mscapi_CPublicKey_CRSAPublicKey
* Method: getExponent
* Signature: ([B)[B
*/
-JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSAPublicKey_getExponent
- (JNIEnv *env, jclass clazz, jbyteArray jKeyBlob) {
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_00024CRSAPublicKey_getExponent
+ (JNIEnv *env, jobject clazz, jbyteArray jKeyBlob) {
jbyteArray exponent = NULL;
jbyte* exponentBytes = NULL;
@@ -1770,12 +2035,12 @@
}
/*
- * Class: sun_security_mscapi_RSAPublicKey
+ * Class: sun_security_mscapi_CPublicKey_CRSAPublicKey
* Method: getModulus
* Signature: ([B)[B
*/
-JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSAPublicKey_getModulus
- (JNIEnv *env, jclass clazz, jbyteArray jKeyBlob) {
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_00024CRSAPublicKey_getModulus
+ (JNIEnv *env, jobject clazz, jbyteArray jKeyBlob) {
jbyteArray modulus = NULL;
jbyte* modulusBytes = NULL;
@@ -1844,38 +2109,47 @@
* Convert an array in big-endian byte order into little-endian byte order.
*/
int convertToLittleEndian(JNIEnv *env, jbyteArray source, jbyte* destination,
- int destinationLength) {
+ int destinationLength) {
- int sourceLength = env->GetArrayLength(source);
+ int result = -1;
+ jbyte* sourceBytes = NULL;
- jbyte* sourceBytes = env->GetByteArrayElements(source, 0);
- if (sourceBytes == NULL) {
- return -1;
- }
+ __try {
+ int sourceLength = env->GetArrayLength(source);
- int copyLen = sourceLength;
- if (sourceLength > destinationLength) {
- // source might include an extra sign byte
- if (sourceLength == destinationLength + 1 && sourceBytes[0] == 0) {
- copyLen--;
- } else {
- return -1;
+ sourceBytes = env->GetByteArrayElements(source, 0);
+ if (sourceBytes == NULL) {
+ __leave;
+ }
+
+ int copyLen = sourceLength;
+ if (sourceLength > destinationLength) {
+ // source might include an extra sign byte
+ if (sourceLength == destinationLength + 1 && sourceBytes[0] == 0) {
+ copyLen--;
+ } else {
+ __leave;
+ }
+ }
+
+ // Copy bytes from the end of the source array to the beginning of the
+ // destination array (until the destination array is full).
+ // This ensures that the sign byte from the source array will be excluded.
+ for (int i = 0; i < copyLen; i++) {
+ destination[i] = sourceBytes[sourceLength - 1 - i];
+ }
+ if (copyLen < destinationLength) {
+ memset(destination + copyLen, 0, destinationLength - copyLen);
+ }
+ result = destinationLength;
+ } __finally {
+ // Clean up.
+ if (sourceBytes) {
+ env->ReleaseByteArrayElements(source, sourceBytes, JNI_ABORT);
}
}
- // Copy bytes from the end of the source array to the beginning of the
- // destination array (until the destination array is full).
- // This ensures that the sign byte from the source array will be excluded.
- for (int i = 0; i < copyLen; i++) {
- destination[i] = sourceBytes[sourceLength - 1 - i];
- }
- if (copyLen < destinationLength) {
- memset(destination + copyLen, 0, destinationLength - copyLen);
- }
-
- env->ReleaseByteArrayElements(source, sourceBytes, JNI_ABORT);
-
- return destinationLength;
+ return result;
}
/*
@@ -2049,12 +2323,12 @@
}
/*
- * Class: sun_security_mscapi_KeyStore
- * Method: generatePrivateKeyBlob
+ * Class: sun_security_mscapi_CKeyStore
+ * Method: generateRSAPrivateKeyBlob
* Signature: (I[B[B[B[B[B[B[B[B)[B
*/
-JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_KeyStore_generatePrivateKeyBlob
- (JNIEnv *env, jclass clazz,
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CKeyStore_generateRSAPrivateKeyBlob
+ (JNIEnv *env, jobject clazz,
jint jKeyBitLength,
jbyteArray jModulus,
jbyteArray jPublicExponent,
@@ -2071,11 +2345,11 @@
}
/*
- * Class: sun_security_mscapi_RSASignature
+ * Class: sun_security_mscapi_CSignature_RSA
* Method: generatePublicKeyBlob
* Signature: (I[B[B)[B
*/
-JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_generatePublicKeyBlob
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CSignature_00024RSA_generatePublicKeyBlob
(JNIEnv *env, jclass clazz,
jint jKeyBitLength,
jbyteArray jModulus,
@@ -2086,13 +2360,13 @@
}
/*
- * Class: sun_security_mscapi_KeyStore
+ * Class: sun_security_mscapi_CKeyStore
* Method: storePrivateKey
- * Signature: ([BLjava/lang/String;I)Lsun/security/mscapi/RSAPrivateKey;
+ * Signature: (Ljava/lang/String;[BLjava/lang/String;I)Lsun/security/mscapi/CPrivateKey;
*/
-JNIEXPORT jobject JNICALL Java_sun_security_mscapi_KeyStore_storePrivateKey
- (JNIEnv *env, jclass clazz, jbyteArray keyBlob, jstring keyContainerName,
- jint keySize)
+JNIEXPORT jobject JNICALL Java_sun_security_mscapi_CKeyStore_storePrivateKey
+ (JNIEnv *env, jobject clazz, jstring alg, jbyteArray keyBlob,
+ jstring keyContainerName, jint keySize)
{
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKey = NULL;
@@ -2114,7 +2388,7 @@
}
// Acquire a CSP context (create a new key container).
- if (::CryptAcquireContext(
+ if (::CryptAcquireContext( //deprecated
&hCryptProv,
pszKeyContainerName,
NULL,
@@ -2126,7 +2400,7 @@
}
// Import the private key
- if (::CryptImportKey(
+ if (::CryptImportKey( //deprecated
hCryptProv,
pbKeyBlob,
dwBlobLen,
@@ -2138,22 +2412,23 @@
__leave;
}
- // Get the method ID for the RSAPrivateKey constructor
- jclass clazzRSAPrivateKey =
- env->FindClass("sun/security/mscapi/RSAPrivateKey");
- if (clazzRSAPrivateKey == NULL) {
+ // Get the method ID for the CPrivateKey constructor
+ jclass clazzCPrivateKey =
+ env->FindClass("sun/security/mscapi/CPrivateKey");
+ if (clazzCPrivateKey == NULL) {
__leave;
}
- jmethodID mNewRSAPrivateKey =
- env->GetMethodID(clazzRSAPrivateKey, "<init>", "(JJI)V");
- if (mNewRSAPrivateKey == NULL) {
+ jmethodID mNewCPrivateKey =
+ env->GetStaticMethodID(clazzCPrivateKey, "of",
+ "(Ljava/lang/String;JJI)Lsun/security/mscapi/CPrivateKey;");
+ if (mNewCPrivateKey == NULL) {
__leave;
}
- // Create a new RSA private key
- privateKey = env->NewObject(clazzRSAPrivateKey, mNewRSAPrivateKey,
- (jlong) hCryptProv, (jlong) hKey, keySize);
+ // Create a new private key
+ privateKey = env->CallStaticObjectMethod(clazzCPrivateKey, mNewCPrivateKey,
+ alg, (jlong) hCryptProv, (jlong) hKey, keySize);
}
__finally
@@ -2173,12 +2448,72 @@
}
/*
- * Class: sun_security_mscapi_RSASignature
- * Method: importPublicKey
- * Signature: ([BI)Lsun/security/mscapi/RSAPublicKey;
+ * Class: sun_security_mscapi_CSignature
+ * Method: importECPublicKey
+ * Signature: (Ljava/lang/String;[BI)Lsun/security/mscapi/CPublicKey;
*/
-JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSASignature_importPublicKey
- (JNIEnv *env, jclass clazz, jbyteArray keyBlob, jint keySize)
+JNIEXPORT jobject JNICALL Java_sun_security_mscapi_CSignature_importECPublicKey
+ (JNIEnv *env, jclass clazz, jstring alg, jbyteArray keyBlob, jint keySize)
+{
+ BCRYPT_ALG_HANDLE hSignAlg = NULL;
+ NCRYPT_KEY_HANDLE hTmpKey = NULL;
+ DWORD dwBlobLen;
+ BYTE * pbKeyBlob = NULL;
+ jobject publicKey = NULL;
+
+ __try
+ {
+ dwBlobLen = env->GetArrayLength(keyBlob);
+ if ((pbKeyBlob = (BYTE *) env->GetByteArrayElements(keyBlob, 0))
+ == NULL) {
+ __leave;
+ }
+ dump("NCryptImportKey", pbKeyBlob, dwBlobLen);
+ NCRYPT_PROV_HANDLE hProv;
+ SS_CHECK(NCryptOpenStorageProvider(
+ &hProv, L"Microsoft Software Key Storage Provider", 0 ));
+ SS_CHECK(NCryptImportKey(
+ hProv,
+ NULL,
+ BCRYPT_ECCPUBLIC_BLOB,
+ NULL,
+ &hTmpKey,
+ pbKeyBlob,
+ dwBlobLen,
+ 0));
+ NCryptFreeObject( hProv );
+ // Get the method ID for the CPublicKey constructor
+ jclass clazzCPublicKey =
+ env->FindClass("sun/security/mscapi/CPublicKey");
+ if (clazzCPublicKey == NULL) {
+ __leave;
+ }
+
+ jmethodID mNewCPublicKey =
+ env->GetStaticMethodID(clazzCPublicKey, "of",
+ "(Ljava/lang/String;JJI)Lsun/security/mscapi/CPublicKey;");
+ if (mNewCPublicKey == NULL) {
+ __leave;
+ }
+
+ // Create a new public key
+ publicKey = env->CallStaticObjectMethod(clazzCPublicKey, mNewCPublicKey,
+ alg, (jlong) hTmpKey, (jlong) 0, keySize);
+ }
+ __finally
+ {
+ }
+
+ return publicKey;
+}
+
+/*
+ * Class: sun_security_mscapi_CSignature
+ * Method: importPublicKey
+ * Signature: (Ljava/lang/String;[BI)Lsun/security/mscapi/CPublicKey;
+ */
+JNIEXPORT jobject JNICALL Java_sun_security_mscapi_CSignature_importPublicKey
+ (JNIEnv *env, jclass clazz, jstring alg, jbyteArray keyBlob, jint keySize)
{
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKey = NULL;
@@ -2197,7 +2532,7 @@
// Acquire a CSP context (create a new key container).
// Prefer a PROV_RSA_AES CSP, when available, due to its support
// for SHA-2-based signatures.
- if (::CryptAcquireContext(
+ if (::CryptAcquireContext( //deprecated
&hCryptProv,
NULL,
NULL,
@@ -2206,7 +2541,7 @@
{
// Failover to using the default CSP (PROV_RSA_FULL)
- if (::CryptAcquireContext(
+ if (::CryptAcquireContext( //deprecated
&hCryptProv,
NULL,
NULL,
@@ -2219,7 +2554,7 @@
}
// Import the public key
- if (::CryptImportKey(
+ if (::CryptImportKey( //deprecated
hCryptProv,
pbKeyBlob,
dwBlobLen,
@@ -2231,22 +2566,23 @@
__leave;
}
- // Get the method ID for the RSAPublicKey constructor
- jclass clazzRSAPublicKey =
- env->FindClass("sun/security/mscapi/RSAPublicKey");
- if (clazzRSAPublicKey == NULL) {
+ // Get the method ID for the CPublicKey constructor
+ jclass clazzCPublicKey =
+ env->FindClass("sun/security/mscapi/CPublicKey");
+ if (clazzCPublicKey == NULL) {
__leave;
}
- jmethodID mNewRSAPublicKey =
- env->GetMethodID(clazzRSAPublicKey, "<init>", "(JJI)V");
- if (mNewRSAPublicKey == NULL) {
+ jmethodID mNewCPublicKey =
+ env->GetStaticMethodID(clazzCPublicKey, "of",
+ "(Ljava/lang/String;JJI)Lsun/security/mscapi/CPublicKey;");
+ if (mNewCPublicKey == NULL) {
__leave;
}
- // Create a new RSA public key
- publicKey = env->NewObject(clazzRSAPublicKey, mNewRSAPublicKey,
- (jlong) hCryptProv, (jlong) hKey, keySize);
+ // Create a new public key
+ publicKey = env->CallStaticObjectMethod(clazzCPublicKey, mNewCPublicKey,
+ alg, (jlong) hCryptProv, (jlong) hKey, keySize);
}
__finally
diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt
index b94b292..c86b5ec 100644
--- a/jdk/test/ProblemList.txt
+++ b/jdk/test/ProblemList.txt
@@ -270,6 +270,9 @@
# 8026976
sun/security/pkcs11/ec/TestKeyFactory.java generic-all
+# 8180837
+sun/security/pkcs11/Secmod/AddTrustedCert.java generic-all
+sun/security/pkcs11/tls/TestKeyMaterial.java generic-all
# 7164518
sun/security/krb5/auto/Unreachable.java macosx-all
diff --git a/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEP.java b/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEP.java
index 55b501e..1f550c9 100644
--- a/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEP.java
+++ b/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEP.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4894151
+ * @bug 4894151 8146293
* @summary encryption/decryption test for OAEP
* @author Andreas Sterbenz
*/
@@ -62,6 +62,8 @@
Cipher.getInstance("RSA/ECB/OAEPwithSHA-256andMGF1Padding");
Cipher.getInstance("RSA/ECB/OAEPwithSHA-384andMGF1Padding");
Cipher.getInstance("RSA/ECB/OAEPwithSHA-512andMGF1Padding");
+ Cipher.getInstance("RSA/ECB/OAEPwithSHA-512/224andMGF1Padding");
+ Cipher.getInstance("RSA/ECB/OAEPwithSHA-512/256andMGF1Padding");
// basic test using MD5
testEncryptDecrypt("MD5", 0);
@@ -89,28 +91,32 @@
// tests alias works
testEncryptDecrypt("SHA-1", 16);
- // basic test using SHA-224
- testEncryptDecrypt("SHA-224", 0);
- testEncryptDecrypt("SHA-224", 16);
- testEncryptDecrypt("SHA-224", 38);
- try {
- testEncryptDecrypt("SHA-224", 39);
- throw new Exception("Unexpectedly completed call");
- } catch (IllegalBlockSizeException e) {
- // ok
- System.out.println(e);
+ String[] HASH_ALG_224 = { "SHA-224", "SHA-512/224" };
+ for (String ha : HASH_ALG_224) {
+ testEncryptDecrypt(ha, 0);
+ testEncryptDecrypt(ha, 16);
+ testEncryptDecrypt(ha, 38);
+ try {
+ testEncryptDecrypt(ha, 39);
+ throw new Exception("Unexpectedly completed call");
+ } catch (IllegalBlockSizeException e) {
+ // ok
+ System.out.println(e);
+ }
}
- // basic test using SHA-256
- testEncryptDecrypt("SHA-256", 0);
- testEncryptDecrypt("SHA-256", 16);
- testEncryptDecrypt("SHA-256", 30);
- try {
- testEncryptDecrypt("SHA-256", 31);
- throw new Exception("Unexpectedly completed call");
- } catch (IllegalBlockSizeException e) {
- // ok
- System.out.println(e);
+ String[] HASH_ALG_256 = { "SHA-256", "SHA-512/256" };
+ for (String ha : HASH_ALG_256) {
+ testEncryptDecrypt(ha, 0);
+ testEncryptDecrypt(ha, 16);
+ testEncryptDecrypt(ha, 30);
+ try {
+ testEncryptDecrypt(ha, 31);
+ throw new Exception("Unexpectedly completed call");
+ } catch (IllegalBlockSizeException e) {
+ // ok
+ System.out.println(e);
+ }
}
// 768 bit key too short for OAEP with 64 byte digest
diff --git a/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPPadding.java b/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPPadding.java
index 3804253..becfcb0 100644
--- a/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPPadding.java
+++ b/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPPadding.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -130,6 +130,16 @@
MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT));
test(new OAEPParameterSpec("SHA-512", "MGF1",
MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT));
+ // SHA-512/224 and SHA-512/256
+ test(new OAEPParameterSpec("SHA-512/224", "MGF1",
+ MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-512/224", "MGF1",
+ MGF1ParameterSpec.SHA512_224, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-512/256", "MGF1",
+ MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT));
+ test(new OAEPParameterSpec("SHA-512/256", "MGF1",
+ MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT));
+
if (failed) {
throw new Exception("Test failed");
}
@@ -154,9 +164,9 @@
dlen = 16;
} else if (algo.equals("SHA1")) {
dlen = 20;
- } else if (algo.equals("SHA-224")) {
+ } else if (algo.equals("SHA-224") || algo.equals("SHA-512/224")) {
dlen = 28;
- } else if (algo.equals("SHA-256")) {
+ } else if (algo.equals("SHA-256") || algo.equals("SHA-512/256")) {
dlen = 32;
} else if (algo.equals("SHA-384")) {
dlen = 48;
diff --git a/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPParameterSpec.java b/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPParameterSpec.java
index 1a15285..412ec66 100644
--- a/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPParameterSpec.java
+++ b/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPParameterSpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4923484
+ * @bug 4923484 8146293
* @summary test ASN.1 encoding generation/parsing for the OAEPParameters
* implementation in SunJCE provider.
* @author Valerie Peng
@@ -125,6 +125,8 @@
status &= runTest("SHA-256", MGF1ParameterSpec.SHA256, p);
status &= runTest("SHA-384", MGF1ParameterSpec.SHA384, p);
status &= runTest("SHA-512", MGF1ParameterSpec.SHA512, p);
+ status &= runTest("SHA-512/224", MGF1ParameterSpec.SHA512_224, p);
+ status &= runTest("SHA-512/256", MGF1ParameterSpec.SHA512_256, p);
status &= runTest("SHA", MGF1ParameterSpec.SHA1, new byte[0]);
status &= runTest("SHA-1", MGF1ParameterSpec.SHA1, new byte[0]);
status &= runTest("SHA1", MGF1ParameterSpec.SHA1, new byte[0]);
diff --git a/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPWithParams.java b/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPWithParams.java
index 13bdfe1a..6e63a51 100644
--- a/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPWithParams.java
+++ b/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPWithParams.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4923484
+ * @bug 4923484 8146293
* @summary encryption/decryption test for using OAEPParameterSpec.
* @author Valerie Peng
*/
@@ -47,10 +47,10 @@
private static Random random = new Random();
private static String MD[] = {
- "MD5", "SHA1", "SHA-224", "SHA-256"
+ "MD5", "SHA1", "SHA-224", "SHA-256", "SHA-512/224", "SHA-512/256"
};
private static int DATA_LENGTH[] = {
- 62, 54, 34, 30
+ 62, 54, 34, 30, 34, 30
};
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
diff --git a/jdk/test/com/sun/tools/attach/StartManagementAgent.java b/jdk/test/com/sun/tools/attach/StartManagementAgent.java
index da82895..cc39690 100644
--- a/jdk/test/com/sun/tools/attach/StartManagementAgent.java
+++ b/jdk/test/com/sun/tools/attach/StartManagementAgent.java
@@ -93,7 +93,7 @@
} catch(AttachOperationFailedException ex) {
// We expect parsing of "apa" above to fail, but if the file path
// can't be read we get a different exception message
- if (!ex.getMessage().contains("Invalid com.sun.management.jmxremote.port number")) {
+ if (!ex.getMessage().contains("NumberFormatException: For input string: \"apa\"")) {
throw ex;
}
}
diff --git a/jdk/test/java/awt/GraphicsDevice/CheckDisplayModes.java b/jdk/test/java/awt/GraphicsDevice/CheckDisplayModes.java
index 719ee9b..9fced18 100644
--- a/jdk/test/java/awt/GraphicsDevice/CheckDisplayModes.java
+++ b/jdk/test/java/awt/GraphicsDevice/CheckDisplayModes.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8007146
+ * @bug 8007146 8213119
* @summary [macosx] Setting a display mode crashes JDK under VNC
* @author Alexander Scherbatiy
* @run main CheckDisplayModes
@@ -36,27 +36,28 @@
public static void main(String[] args) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
- GraphicsDevice graphicDevice = ge.getDefaultScreenDevice();
- if (!graphicDevice.isDisplayChangeSupported()) {
- System.err.println("Display mode change is not supported on this host. Test is considered passed.");
- return;
- }
- DisplayMode defaultDisplayMode = graphicDevice.getDisplayMode();
- checkDisplayMode(defaultDisplayMode);
- graphicDevice.setDisplayMode(defaultDisplayMode);
-
- DisplayMode[] displayModes = graphicDevice.getDisplayModes();
- boolean isDefaultDisplayModeIncluded = false;
- for (DisplayMode displayMode : displayModes) {
- checkDisplayMode(displayMode);
- graphicDevice.setDisplayMode(displayMode);
- if (defaultDisplayMode.equals(displayMode)) {
- isDefaultDisplayModeIncluded = true;
+ for (GraphicsDevice graphicDevice : ge.getScreenDevices()) {
+ if (!graphicDevice.isDisplayChangeSupported()) {
+ System.err.println("Display mode change is not supported on this host. Test is considered passed.");
+ continue;
}
- }
+ DisplayMode defaultDisplayMode = graphicDevice.getDisplayMode();
+ checkDisplayMode(defaultDisplayMode);
+ graphicDevice.setDisplayMode(defaultDisplayMode);
- if (!isDefaultDisplayModeIncluded) {
- throw new RuntimeException("Default display mode is not included");
+ DisplayMode[] displayModes = graphicDevice.getDisplayModes();
+ boolean isDefaultDisplayModeIncluded = false;
+ for (DisplayMode displayMode : displayModes) {
+ checkDisplayMode(displayMode);
+ graphicDevice.setDisplayMode(displayMode);
+ if (defaultDisplayMode.equals(displayMode)) {
+ isDefaultDisplayModeIncluded = true;
+ }
+ }
+
+ if (!isDefaultDisplayModeIncluded) {
+ throw new RuntimeException("Default display mode is not included");
+ }
}
}
diff --git a/jdk/test/java/io/Serializable/serialFilter/GlobalFilterTest.java b/jdk/test/java/io/Serializable/serialFilter/GlobalFilterTest.java
index 20503d1..3810f38 100644
--- a/jdk/test/java/io/Serializable/serialFilter/GlobalFilterTest.java
+++ b/jdk/test/java/io/Serializable/serialFilter/GlobalFilterTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,9 +42,11 @@
import sun.misc.ObjectInputFilter;
/* @test
+ * @bug 8231422
* @build GlobalFilterTest SerialFilterTest
* @run testng/othervm GlobalFilterTest
- * @run testng/othervm -Djdk.serialFilter=java.** GlobalFilterTest
+ * @run testng/othervm -Djdk.serialFilter=java.**
+ * -Dexpected-jdk.serialFilter=java.** GlobalFilterTest
* @run testng/othervm/policy=security.policy GlobalFilterTest
* @run testng/othervm/policy=security.policy
* -Djava.security.properties=${test.src}/java.security-extra1
@@ -54,6 +56,10 @@
*/
@Test
public class GlobalFilterTest {
+ private static final String serialPropName = "jdk.serialFilter";
+ private static final String badSerialFilter = "java.lang.StringBuffer;!*";
+ private static final String origSerialFilterProperty =
+ System.setProperty(serialPropName, badSerialFilter);
/**
* DataProvider of patterns and objects derived from the configured process-wide filter.
@@ -62,8 +68,8 @@
@DataProvider(name="globalPatternElements")
Object[][] globalPatternElements() {
String globalFilter =
- System.getProperty("jdk.serialFilter",
- Security.getProperty("jdk.serialFilter"));
+ System.getProperty("expected-" + serialPropName,
+ Security.getProperty(serialPropName));
if (globalFilter == null) {
return new Object[0][];
}
@@ -100,12 +106,20 @@
*/
@Test()
static void globalFilter() {
- String pattern =
- System.getProperty("jdk.serialFilter",
- Security.getProperty("jdk.serialFilter"));
ObjectInputFilter filter = ObjectInputFilter.Config.getSerialFilter();
+
+ // Check that the System.setProperty(jdk.serialFilter) DOES NOT affect the filter.
+ String asSetSystemProp = System.getProperty(serialPropName,
+ Security.getProperty(serialPropName));
+ Assert.assertNotEquals(Objects.toString(filter, null), asSetSystemProp,
+ "System.setProperty(\"jdk.serialfilter\", ...) should not change filter: " +
+ asSetSystemProp);
+
+ String pattern =
+ System.getProperty("expected-" + serialPropName,
+ Security.getProperty(serialPropName));
System.out.printf("global pattern: %s, filter: %s%n", pattern, filter);
- Assert.assertEquals(pattern, Objects.toString(filter, null),
+ Assert.assertEquals(Objects.toString(filter, null), pattern,
"process-wide filter pattern does not match");
}
diff --git a/jdk/test/java/io/Serializable/serialFilter/security.policy b/jdk/test/java/io/Serializable/serialFilter/security.policy
index f986e25..a79251b 100644
--- a/jdk/test/java/io/Serializable/serialFilter/security.policy
+++ b/jdk/test/java/io/Serializable/serialFilter/security.policy
@@ -3,7 +3,7 @@
// Specific permission under test
permission java.security.SerializablePermission "serialFilter";
// Permissions needed to run the test
- permission java.util.PropertyPermission "*", "read";
+ permission java.util.PropertyPermission "*", "read,write";
permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
permission java.security.SecurityPermission "*";
diff --git a/jdk/test/java/lang/ProcessBuilder/Basic.java b/jdk/test/java/lang/ProcessBuilder/Basic.java
index 1db1d31..7a9260a 100644
--- a/jdk/test/java/lang/ProcessBuilder/Basic.java
+++ b/jdk/test/java/lang/ProcessBuilder/Basic.java
@@ -61,6 +61,15 @@
/* used for AIX only */
static final String libpath = System.getenv("LIBPATH");
+ /**
+ * Returns the number of milliseconds since time given by
+ * startNanoTime, which must have been previously returned from a
+ * call to {@link System.nanoTime()}.
+ */
+ private static long millisElapsedSince(long startNanoTime) {
+ return TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanoTime);
+ }
+
private static String commandOutput(Reader r) throws Throwable {
StringBuilder sb = new StringBuilder();
int c;
@@ -2294,40 +2303,98 @@
//----------------------------------------------------------------
// Check that Process.waitFor(timeout, TimeUnit.MILLISECONDS)
- // interrupt works as expected.
+ // interrupt works as expected, if interrupted while waiting.
//----------------------------------------------------------------
try {
List<String> childArgs = new ArrayList<String>(javaChildArgs);
childArgs.add("sleep");
final Process p = new ProcessBuilder(childArgs).start();
final long start = System.nanoTime();
- final CountDownLatch ready = new CountDownLatch(1);
- final CountDownLatch done = new CountDownLatch(1);
+ final CountDownLatch aboutToWaitFor = new CountDownLatch(1);
final Thread thread = new Thread() {
public void run() {
try {
- final boolean result;
- try {
- ready.countDown();
- result = p.waitFor(30000, TimeUnit.MILLISECONDS);
- } catch (InterruptedException e) {
- return;
- }
+ aboutToWaitFor.countDown();
+ Thread.currentThread().interrupt();
+ boolean result = p.waitFor(30L * 1000L, TimeUnit.MILLISECONDS);
fail("waitFor() wasn't interrupted, its return value was: " + result);
- } catch (Throwable t) {
- unexpected(t);
- } finally {
- done.countDown();
- }
+ } catch (InterruptedException success) {
+ } catch (Throwable t) { unexpected(t); }
}
};
thread.start();
- ready.await();
- Thread.sleep(1000);
+ aboutToWaitFor.await();
thread.interrupt();
- done.await();
+ thread.join(10L * 1000L);
+ check(millisElapsedSince(start) < 10L * 1000L);
+ check(!thread.isAlive());
+ p.destroy();
+ } catch (Throwable t) { unexpected(t); }
+
+ //----------------------------------------------------------------
+ // Check that Process.waitFor(Long.MAX_VALUE, TimeUnit.MILLISECONDS)
+ // interrupt works as expected, if interrupted while waiting.
+ //----------------------------------------------------------------
+ try {
+ List<String> childArgs = new ArrayList<String>(javaChildArgs);
+ childArgs.add("sleep");
+ final Process p = new ProcessBuilder(childArgs).start();
+ final long start = System.nanoTime();
+ final CountDownLatch aboutToWaitFor = new CountDownLatch(1);
+
+ final Thread thread = new Thread() {
+ public void run() {
+ try {
+ aboutToWaitFor.countDown();
+ Thread.currentThread().interrupt();
+ boolean result = p.waitFor(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
+ fail("waitFor() wasn't interrupted, its return value was: " + result);
+ } catch (InterruptedException success) {
+ } catch (Throwable t) { unexpected(t); }
+ }
+ };
+
+ thread.start();
+ aboutToWaitFor.await();
+ thread.interrupt();
+ thread.join(10L * 1000L);
+ check(millisElapsedSince(start) < 10L * 1000L);
+ check(!thread.isAlive());
+ p.destroy();
+ } catch (Throwable t) { unexpected(t); }
+
+ //----------------------------------------------------------------
+ // Check that Process.waitFor(timeout, TimeUnit.MILLISECONDS)
+ // interrupt works as expected, if interrupted before waiting.
+ //----------------------------------------------------------------
+ try {
+ List<String> childArgs = new ArrayList<String>(javaChildArgs);
+ childArgs.add("sleep");
+ final Process p = new ProcessBuilder(childArgs).start();
+ final long start = System.nanoTime();
+ final CountDownLatch threadStarted = new CountDownLatch(1);
+
+ final Thread thread = new Thread() {
+ public void run() {
+ try {
+ threadStarted.countDown();
+ do { Thread.yield(); }
+ while (!Thread.currentThread().isInterrupted());
+ boolean result = p.waitFor(30L * 1000L, TimeUnit.MILLISECONDS);
+ fail("waitFor() wasn't interrupted, its return value was: " + result);
+ } catch (InterruptedException success) {
+ } catch (Throwable t) { unexpected(t); }
+ }
+ };
+
+ thread.start();
+ threadStarted.await();
+ thread.interrupt();
+ thread.join(10L * 1000L);
+ check(millisElapsedSince(start) < 10L * 1000L);
+ check(!thread.isAlive());
p.destroy();
} catch (Throwable t) { unexpected(t); }
diff --git a/jdk/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java b/jdk/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java
new file mode 100644
index 0000000..62eac12
--- /dev/null
+++ b/jdk/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2018, Amazon and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Azul Systems, 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 8231584
+ * @library /lib/testlibrary
+ * @run main/othervm LoadLibraryTest
+ */
+
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.Path;
+import java.net.MalformedURLException;
+import java.net.URLClassLoader;
+import java.net.URL;
+
+public class LoadLibraryTest {
+ static Thread thread1 = null;
+ static Thread thread2 = null;
+
+ static volatile boolean thread1Ready = false;
+
+ private static final String TEST_SRC = System.getProperty("test.src");
+ private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+ private static final Path CLS_DIR = Paths.get("classes");
+
+ static TestClassLoader loader;
+ static void someLibLoad() {
+ try {
+/*
+ FileSystems.getDefault();
+
+ // jdk/jdk: loads directly from Bootstrap Classloader (doesn't take lock on Runtime)
+ java.net.NetworkInterface.getNetworkInterfaces();
+
+ System.out.println(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
+*/
+ Class c = Class.forName("Target2", true, loader);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static class TestClassLoader extends URLClassLoader {
+ boolean passed = false;
+
+ public boolean passed() {
+ return passed;
+ }
+
+ TestClassLoader() throws MalformedURLException {
+ super(new URL[] { new URL("file://" + CLS_DIR.toAbsolutePath().toString() + '/') });
+ }
+
+ public String findLibrary(String name) {
+ System.out.println("findLibrary " + name);
+
+ if ("someLibrary".equals(name)) {
+ try {
+ synchronized(thread1) {
+ while(!thread1Ready) {
+ thread1.wait();
+ }
+ thread1.notifyAll();
+ }
+
+ Thread.sleep(10000);
+
+ System.out.println("Thread2 load");
+ someLibLoad();
+
+ // no deadlock happened
+ passed = true;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return null;
+ }
+
+ return super.findLibrary(name);
+ }
+ }
+
+
+ public static void main(String[] args) throws Exception {
+ loader = new TestClassLoader();
+
+ if (!CompilerUtils.compile(SRC_DIR, CLS_DIR)) {
+ throw new Exception("Can't compile");
+ }
+
+ thread1 = new Thread() {
+ public void run() {
+ try {
+ synchronized(this) {
+ thread1Ready = true;
+ thread1.notifyAll();
+ thread1.wait();
+ }
+ } catch(InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+
+ System.out.println("Thread1 load");
+ someLibLoad();
+ };
+ };
+
+ thread2 = new Thread() {
+ public void run() {
+ try {
+ Class c = Class.forName("Target", true, loader);
+ System.out.println(c);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ };
+ };
+
+ thread1.setDaemon(true);
+ thread2.setDaemon(true);
+
+ thread1.start();
+ thread2.start();
+
+ thread1.join();
+ thread2.join();
+
+ if (!loader.passed()) {
+ throw new RuntimeException("FAIL");
+ }
+ }
+}
diff --git a/jdk/test/java/lang/Runtime/loadLibrary/src/Target.java b/jdk/test/java/lang/Runtime/loadLibrary/src/Target.java
new file mode 100644
index 0000000..fc51481
--- /dev/null
+++ b/jdk/test/java/lang/Runtime/loadLibrary/src/Target.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019, Azul Systems, 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.
+ */
+
+class Target {
+ static {
+ try {
+ System.loadLibrary("someLibrary");
+ throw new RuntimeException("someLibrary was loaded");
+ } catch (UnsatisfiedLinkError e) {
+ // expected: we do not have a someLibrary
+ }
+ }
+}
+
diff --git a/jdk/test/java/lang/Runtime/loadLibrary/src/Target2.java b/jdk/test/java/lang/Runtime/loadLibrary/src/Target2.java
new file mode 100644
index 0000000..bc8dfc5
--- /dev/null
+++ b/jdk/test/java/lang/Runtime/loadLibrary/src/Target2.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2019, Azul Systems, 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.
+ */
+
+class Target2 {
+ static {
+ System.loadLibrary("awt");
+ }
+}
+
diff --git a/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java b/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java
index 2d79c61..3258925 100644
--- a/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java
+++ b/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,15 +25,18 @@
* @test
* @summary Test consistent parsing of ex-RUNTIME annotations that
* were changed and separately compiled to have CLASS retention
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.IOUtils
+ * @run main AnnotationTypeRuntimeAssumptionTest
*/
-import sun.misc.IOUtils;
-
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import jdk.testlibrary.IOUtils;
+
import static java.lang.annotation.RetentionPolicy.CLASS;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@@ -137,7 +140,7 @@
String altPath = altName.replace('.', '/').concat(".class");
try (InputStream is = getResourceAsStream(altPath)) {
if (is != null) {
- byte[] bytes = IOUtils.readFully(is, -1, true);
+ byte[] bytes = IOUtils.readFully(is);
// patch class bytes to contain original name
for (int i = 0; i < bytes.length - 2; i++) {
if (bytes[i] == '_' &&
@@ -160,7 +163,7 @@
String path = name.replace('.', '/').concat(".class");
try (InputStream is = getResourceAsStream(path)) {
if (is != null) {
- byte[] bytes = IOUtils.readFully(is, -1, true);
+ byte[] bytes = IOUtils.readFully(is);
return defineClass(name, bytes, 0, bytes.length);
}
else {
diff --git a/jdk/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java b/jdk/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java
index 9d38102..6c97e34 100644
--- a/jdk/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java
+++ b/jdk/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -22,11 +22,14 @@
*/
/*
-@test
-@bug 8004970
-@summary Lambda serialization in the presence of class loaders
-@author Peter Levart
-*/
+ * @test
+ * @bug 8004970
+ * @summary Lambda serialization in the presence of class loaders
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.IOUtils
+ * @run main LambdaClassLoaderSerialization
+ * @author Peter Levart
+ */
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -37,6 +40,8 @@
import java.io.Serializable;
import java.util.Arrays;
+import jdk.testlibrary.IOUtils;
+
public class LambdaClassLoaderSerialization {
public interface SerializableRunnable extends Runnable, Serializable {}
@@ -125,7 +130,7 @@
String path = name.replace('.', '/').concat(".class");
try (InputStream is = getResourceAsStream(path)) {
if (is != null) {
- byte[] bytes = readFully(is);
+ byte[] bytes = IOUtils.readFully(is);
return defineClass(name, bytes, 0, bytes.length);
} else {
throw new ClassNotFoundException(name);
@@ -135,30 +140,5 @@
throw new ClassNotFoundException(name, e);
}
}
-
- static byte[] readFully(InputStream is) throws IOException {
- byte[] output = {};
- int pos = 0;
- while (true) {
- int bytesToRead;
- if (pos >= output.length) { // Only expand when there's no room
- bytesToRead = output.length + 1024;
- if (output.length < pos + bytesToRead) {
- output = Arrays.copyOf(output, pos + bytesToRead);
- }
- } else {
- bytesToRead = output.length - pos;
- }
- int cc = is.read(output, pos, bytesToRead);
- if (cc < 0) {
- if (output.length != pos) {
- output = Arrays.copyOf(output, pos);
- }
- break;
- }
- pos += cc;
- }
- return output;
- }
}
}
diff --git a/jdk/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java b/jdk/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java
index ffb384f..4ad93eb 100644
--- a/jdk/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java
+++ b/jdk/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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,6 +27,9 @@
* @summary Test that a static method on an interface doesn't hide a default
* method with the same name and signature in a separate compilation
* scenario.
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.IOUtils
+ * @run main StaticInterfaceMethodInWayOfDefault
*/
import java.io.IOException;
@@ -35,7 +38,7 @@
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
-import sun.misc.IOUtils;
+import jdk.testlibrary.IOUtils;
public class StaticInterfaceMethodInWayOfDefault {
public interface A_v1 {
@@ -144,7 +147,7 @@
String altPath = altName.replace('.', '/').concat(".class");
try (InputStream is = getResourceAsStream(altPath)) {
if (is != null) {
- byte[] bytes = IOUtils.readFully(is, -1, true);
+ byte[] bytes = IOUtils.readFully(is);
// patch class bytes to contain original name
for (int i = 0; i < bytes.length - 2; i++) {
if (bytes[i] == '_' &&
@@ -167,7 +170,7 @@
String path = name.replace('.', '/').concat(".class");
try (InputStream is = getResourceAsStream(path)) {
if (is != null) {
- byte[] bytes = IOUtils.readFully(is, -1, true);
+ byte[] bytes = IOUtils.readFully(is);
return defineClass(name, bytes, 0, bytes.length);
}
else {
diff --git a/jdk/test/java/security/KeyPairGenerator/FinalizeHalf.java b/jdk/test/java/security/KeyPairGenerator/FinalizeHalf.java
index a2a1eb3..4a8fa1e 100644
--- a/jdk/test/java/security/KeyPairGenerator/FinalizeHalf.java
+++ b/jdk/test/java/security/KeyPairGenerator/FinalizeHalf.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 8163896
+ * @bug 8163896 8223003
* @summary Finalizing one key of a KeyPair invalidates the other key
*/
diff --git a/jdk/test/java/security/Signature/Offsets.java b/jdk/test/java/security/Signature/Offsets.java
index 1db510d..9d24084 100644
--- a/jdk/test/java/security/Signature/Offsets.java
+++ b/jdk/test/java/security/Signature/Offsets.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,20 +21,13 @@
* questions.
*/
-import java.security.InvalidKeyException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
+import java.security.*;
+import java.security.spec.*;
import jdk.testlibrary.RandomFactory;
/*
* @test
- * @bug 8050374 8181048
+ * @bug 8050374 8181048 8146293
* @key randomness
* @summary This test validates signature verification
* Signature.verify(byte[], int, int). The test uses RandomFactory to
@@ -46,6 +39,12 @@
* @run main Offsets SUN SHA1withDSA
* @run main Offsets SUN SHA224withDSA
* @run main Offsets SUN SHA256withDSA
+ * @run main Offsets SunRsaSign SHA224withRSA
+ * @run main Offsets SunRsaSign SHA256withRSA
+ * @run main Offsets SunRsaSign SHA384withRSA
+ * @run main Offsets SunRsaSign SHA512withRSA
+ * @run main Offsets SunRsaSign SHA512/224withRSA
+ * @run main Offsets SunRsaSign SHA512/256withRSA
*/
public class Offsets {
@@ -58,11 +57,13 @@
private Offsets(Signature signature, PublicKey pubkey, PrivateKey privkey,
int size, byte[] cleartext) throws InvalidKeyException,
SignatureException {
+ System.out.println("Testing signature " + signature.getAlgorithm());
this.pubkey = pubkey;
this.signature = signature;
this.size = size;
this.cleartext = cleartext;
+ String sigAlg = signature.getAlgorithm();
signature.initSign(privkey);
signature.update(cleartext, 0, size);
signed = signature.sign();
@@ -85,7 +86,7 @@
boolean verifySignature(byte[] sigData, int sigOffset, int sigLength,
int updateOffset, int updateLength)
- throws InvalidKeyException, SignatureException {
+ throws InvalidKeyException, SignatureException {
signature.initVerify(pubkey);
signature.update(cleartext, updateOffset, updateLength);
return signature.verify(sigData, sigOffset, sigLength);
diff --git a/jdk/test/java/security/Signature/SignatureGetInstance.java b/jdk/test/java/security/Signature/SignatureGetInstance.java
new file mode 100644
index 0000000..1c1d796
--- /dev/null
+++ b/jdk/test/java/security/Signature/SignatureGetInstance.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8216039
+ * @summary Ensure the BC provider-reselection workaround in Signature class
+ * functions correctly
+ * @run main/othervm SignatureGetInstance
+ */
+import java.security.*;
+import java.security.interfaces.*;
+import java.security.spec.*;
+import sun.security.util.SignatureUtil;
+
+public class SignatureGetInstance {
+
+ private static final String SIGALG = "RSASSA-PSS";
+
+ public static void main(String[] args) throws Exception {
+ Provider testProvider = new TestProvider();
+ // put test provider before SunRsaSign provider
+ Security.insertProviderAt(testProvider, 1);
+ //Security.addProvider(testProvider);
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+ KeyPair kp = kpg.generateKeyPair();
+
+ MyPrivKey testPriv = new MyPrivKey();
+ MyPubKey testPub = new MyPubKey();
+
+ testDblInit(testPriv, testPub, true, "TestProvider");
+ testDblInit(kp.getPrivate(), kp.getPublic(), true, "SunRsaSign");
+ testDblInit(testPriv, kp.getPublic(), false, null);
+ testDblInit(kp.getPrivate(), testPub, false, null);
+
+ testSetAndInit(null, testPriv, true);
+ testSetAndInit(null, testPub, true);
+ testSetAndInit(null, kp.getPrivate(), true);
+ testSetAndInit(null, kp.getPublic(), true);
+
+ String provName = "SunRsaSign";
+ testSetAndInit(provName, testPriv, false);
+ testSetAndInit(provName, testPub, false);
+ testSetAndInit(provName, kp.getPrivate(), true);
+ testSetAndInit(provName, kp.getPublic(), true);
+
+ provName = "TestProvider";
+ testSetAndInit(provName, testPriv, true);
+ testSetAndInit(provName, testPub, true);
+ testSetAndInit(provName, kp.getPrivate(), false);
+ testSetAndInit(provName, kp.getPublic(), false);
+
+ System.out.println("Test Passed");
+ }
+
+ private static void checkName(Signature s, String name) {
+ if (name != null &&
+ !(name.equals(s.getProvider().getName()))) {
+ throw new RuntimeException("Fail: provider name mismatch");
+ }
+ }
+
+ private static void testDblInit(PrivateKey key1, PublicKey key2,
+ boolean shouldPass, String expectedProvName) throws Exception {
+ Signature sig = Signature.getInstance(SIGALG);
+ SignatureUtil.initSignWithParam(sig, key1, PSSParameterSpec.DEFAULT, null);
+ try {
+ sig.initVerify(key2);
+ if (!shouldPass) {
+ throw new RuntimeException("Fail: should throw InvalidKeyException");
+ }
+ checkName(sig, expectedProvName);
+ } catch (InvalidKeyException ike) {
+ if (shouldPass) {
+ System.out.println("Fail: Unexpected InvalidKeyException");
+ throw ike;
+ }
+ }
+ }
+
+ private static void testSetAndInit(String provName, Key key,
+ boolean shouldPass) throws Exception {
+ Signature sig;
+ if (provName == null) {
+ sig = Signature.getInstance(SIGALG);
+ } else {
+ sig = Signature.getInstance(SIGALG, provName);
+ }
+ AlgorithmParameterSpec params = PSSParameterSpec.DEFAULT;
+ boolean doSign = (key instanceof PrivateKey);
+ try {
+ if (doSign) {
+ SignatureUtil.initSignWithParam(sig, (PrivateKey)key, params, null);
+ } else {
+ SignatureUtil.initVerifyWithParam(sig, (PublicKey)key, params);
+ }
+ if (!shouldPass) {
+ throw new RuntimeException("Fail: should throw InvalidKeyException");
+ }
+ checkName(sig, provName);
+ // check that the earlier parameter is still there
+ if (sig.getParameters() == null) {
+ throw new RuntimeException("Fail: parameters not preserved");
+ }
+ } catch (InvalidKeyException ike) {
+ if (shouldPass) {
+ System.out.println("Fail: Unexpected InvalidKeyException");
+ throw ike;
+ }
+ }
+ }
+
+ // Test provider which only accepts its own Key objects
+ // Registered to be more preferred than SunRsaSign provider
+ // for testing deferred provider selection
+ public static class TestProvider extends Provider {
+ TestProvider() {
+ super("TestProvider", 1.0d, "provider for SignatureGetInstance");
+ put("Signature.RSASSA-PSS",
+ "SignatureGetInstance$MySigImpl");
+ }
+ }
+
+ public static class MyPrivKey implements PrivateKey {
+ public String getAlgorithm() { return "RSASSA-PSS"; }
+ public String getFormat() { return "MyOwn"; }
+ public byte[] getEncoded() { return null; }
+ }
+
+ public static class MyPubKey implements PublicKey {
+ public String getAlgorithm() { return "RSASSA-PSS"; }
+ public String getFormat() { return "MyOwn"; }
+ public byte[] getEncoded() { return null; }
+ }
+
+ public static class MySigImpl extends SignatureSpi {
+ // simulate BC behavior of only using params set before init calls
+ AlgorithmParameterSpec initParamSpec = null;
+ AlgorithmParameterSpec paramSpec = null;
+
+ public MySigImpl() {
+ super();
+ }
+
+ @Override
+ protected void engineInitVerify(PublicKey publicKey)
+ throws InvalidKeyException {
+ if (!(publicKey instanceof MyPubKey)) {
+ throw new InvalidKeyException("Must be MyPubKey");
+ }
+ initParamSpec = paramSpec;
+ }
+
+ @Override
+ protected void engineInitSign(PrivateKey privateKey)
+ throws InvalidKeyException {
+ if (!(privateKey instanceof MyPrivKey)) {
+ throw new InvalidKeyException("Must be MyPrivKey");
+ }
+ initParamSpec = paramSpec;
+ }
+
+ @Override
+ protected void engineUpdate(byte b) throws SignatureException {
+ }
+
+ @Override
+ protected void engineUpdate(byte[] b, int off, int len)
+ throws SignatureException {
+ }
+
+ @Override
+ protected byte[] engineSign()
+ throws SignatureException {
+ return new byte[0];
+ }
+
+ @Override
+ protected boolean engineVerify(byte[] sigBytes)
+ throws SignatureException {
+ return false;
+ }
+
+ @Override
+ @Deprecated
+ protected void engineSetParameter(String param, Object value)
+ throws InvalidParameterException {
+ }
+
+ @Override
+ protected void engineSetParameter(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ paramSpec = params;
+ }
+
+ @Override
+ @Deprecated
+ protected AlgorithmParameters engineGetParameter(String param)
+ throws InvalidParameterException {
+ return null;
+ }
+
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ if (initParamSpec != null) {
+ try {
+ AlgorithmParameters ap =
+ AlgorithmParameters.getInstance("RSASSA-PSS");
+ ap.init(initParamSpec);
+ return ap;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/jdk/test/java/security/SignedObject/Chain.java b/jdk/test/java/security/SignedObject/Chain.java
index 3c9bad3..ff922ba 100644
--- a/jdk/test/java/security/SignedObject/Chain.java
+++ b/jdk/test/java/security/SignedObject/Chain.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,12 +28,18 @@
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
-import java.util.Arrays;
+import java.security.spec.*;
+import java.util.*;
+import jdk.test.lib.SigTestUtil;
+import static jdk.test.lib.SigTestUtil.SignatureType;
/*
* @test
- * @bug 8050374 8181048
+ * @bug 8050374 8181048 8146293
* @summary Verify a chain of signed objects
+ * @library /lib
+ * @build jdk.test.lib.SigTestUtil
+ * @run main Chain
*/
public class Chain {
@@ -77,6 +83,8 @@
SHA256withRSA("SHA256withRSA"),
SHA384withRSA("SHA384withRSA"),
SHA512withRSA("SHA512withRSA"),
+ SHA512_224withRSA("SHA512/224withRSA"),
+ SHA512_256withRSA("SHA512/256withRSA"),
SHA1withECDSA("SHA1withECDSA"),
SHA256withECDSA("SHA256withECDSA"),
@@ -84,7 +92,9 @@
SHA384withECDSA("SHA384withECDSA"),
SHA512withECDSA("SHA512withECDSA"),
- MD5andSHA1withRSA("MD5andSHA1withRSA");
+ MD5andSHA1withRSA("MD5andSHA1withRSA"),
+
+ RSASSA_PSS("RSASSA-PSS");
final String name;
@@ -98,16 +108,44 @@
final KeyAlg keyAlg;
final SigAlg sigAlg;
final int keySize;
+ final AlgorithmParameterSpec sigParams;
Test(SigAlg sigAlg, KeyAlg keyAlg, Provider provider) {
- this(sigAlg, keyAlg, provider, -1);
+ this(sigAlg, keyAlg, provider, -1, null);
}
Test(SigAlg sigAlg, KeyAlg keyAlg, Provider provider, int keySize) {
+ this(sigAlg, keyAlg, provider, keySize, null);
+ }
+
+ Test(SigAlg sigAlg, KeyAlg keyAlg, Provider provider, int keySize,
+ AlgorithmParameterSpec sigParams) {
this.provider = provider;
this.keyAlg = keyAlg;
this.sigAlg = sigAlg;
this.keySize = keySize;
+ this.sigParams = sigParams;
+ }
+
+ private static String formatParams(AlgorithmParameterSpec aps) {
+ if (aps == null) return "null";
+ if (aps instanceof PSSParameterSpec) {
+ PSSParameterSpec p = (PSSParameterSpec) aps;
+ return String.format("PSSParameterSpec (%s, %s, %s, %s)",
+ p.getDigestAlgorithm(), formatParams(p.getMGFParameters()),
+ p.getSaltLength(), p.getTrailerField());
+ } else if (aps instanceof MGF1ParameterSpec) {
+ return "MGF1" +
+ ((MGF1ParameterSpec)aps).getDigestAlgorithm();
+ } else {
+ return aps.toString();
+ }
+ }
+
+ public String toString() {
+ return String.format("Test: provider = %s, signature alg = %s, "
+ + " w/ %s, key alg = %s", provider, sigAlg,
+ formatParams(sigParams), keyAlg);
}
}
@@ -126,17 +164,29 @@
public static void main(String argv[]) {
boolean result = Arrays.stream(tests).allMatch((test) -> runTest(test));
- if(result) {
+ result &= runTestPSS(2048);
+ if (result) {
System.out.println("All tests passed");
} else {
throw new RuntimeException("Some tests failed");
}
}
+ private static boolean runTestPSS(int keysize) {
+ boolean result = true;
+ SigAlg pss = SigAlg.RSASSA_PSS;
+ Iterator<String> mdAlgs = SigTestUtil.getDigestAlgorithms
+ (SignatureType.RSASSA_PSS, keysize).iterator();
+ while (mdAlgs.hasNext()) {
+ result &= runTest(new Test(pss, KeyAlg.RSA, Provider.SunRsaSign,
+ keysize, SigTestUtil.generateDefaultParameter
+ (SignatureType.RSASSA_PSS, mdAlgs.next())));
+ }
+ return result;
+ }
+
static boolean runTest(Test test) {
- System.out.format("Test: provider = %s, signature algorithm = %s, "
- + "key algorithm = %s\n",
- test.provider, test.sigAlg, test.keyAlg);
+ System.out.println(test);
try {
// Generate all private/public key pairs
PrivateKey[] privKeys = new PrivateKey[N];
@@ -153,6 +203,10 @@
signature = Signature.getInstance(test.sigAlg.name);
kpg = KeyPairGenerator.getInstance(test.keyAlg.name);
}
+ if (test.sigParams != null) {
+ signature.setParameter(test.sigParams);
+ }
+
for (int j=0; j < N; j++) {
if (test.keySize != -1) {
kpg.initialize(test.keySize);
@@ -187,7 +241,6 @@
System.out.println("Failed: verification failed, n = " + n);
return false;
}
-
if (object.verify(anotherPubKeys[n], signature)) {
System.out.println("Failed: verification should not "
+ "succeed with wrong public key, n = " + n);
diff --git a/jdk/test/java/security/cert/X509CRL/VerifyDefault.java b/jdk/test/java/security/cert/X509CRL/VerifyDefault.java
new file mode 100644
index 0000000..c20f73b
--- /dev/null
+++ b/jdk/test/java/security/cert/X509CRL/VerifyDefault.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8175029
+ * @library ../../testlibrary
+ * @summary check that default implementation of
+ * X509CRL.verify(PublicKey, Provider) works on custom X509CRL impl.
+ */
+
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.cert.Certificate;
+import java.security.cert.CRLException;
+import java.security.cert.X509Certificate;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.util.Date;
+import java.util.Set;
+
+public class VerifyDefault {
+ private static final String TEST_CRL =
+ "-----BEGIN X509 CRL-----\n" +
+ "MIIBGzCBhQIBATANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQMA4GA1UE\n" +
+ "ChMHRXhhbXBsZRcNMDkwNDI3MDIzODA0WhcNMjgwNjI2MDIzODA0WjAiMCACAQUX\n" +
+ "DTA5MDQyNzAyMzgwMFowDDAKBgNVHRUEAwoBBKAOMAwwCgYDVR0UBAMCAQIwDQYJ\n" +
+ "KoZIhvcNAQEEBQADgYEAoarfzXEtw3ZDi4f9U8eSvRIipHSyxOrJC7HR/hM5VhmY\n" +
+ "CErChny6x9lBVg9s57tfD/P9PSzBLusCcHwHMAbMOEcTltVVKUWZnnbumpywlYyg\n" +
+ "oKLrE9+yCOkYUOpiRlz43/3vkEL5hjIKMcDSZnPKBZi1h16Yj2hPe9GMibNip54=\n" +
+ "-----END X509 CRL-----";
+
+ private static final String TEST_CERT =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICKzCCAZSgAwIBAgIBAjANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ\n" +
+ "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA0MjcwMjI0MzNaFw0yOTAxMTIwMjI0MzNa\n" +
+ "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIGfMA0GCSqGSIb3DQEB\n" +
+ "AQUAA4GNADCBiQKBgQDMJeBMBybHykI/YpwUJ4O9euqDSLb1kpWpceBS8TVqvgBC\n" +
+ "SgUJWtFZL0i6bdvF6mMdlbuBkGzhXqHiVAi96/zRLbUC9F8SMEJ6MuD+YhQ0ZFTQ\n" +
+ "atKy8zf8O9XzztelLJ26Gqb7QPV133WY3haAqHtCXOhEKkCN16NOYNC37DTaJwID\n" +
+ "AQABo3cwdTAdBgNVHQ4EFgQULXSWzXzUOIpOJpzbSCpW42IJUugwRwYDVR0jBEAw\n" +
+ "PoAUgiXdIaZeT3QA/SGUvh854OJVyxuhI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYD\n" +
+ "VQQKEwdFeGFtcGxlggEAMAsGA1UdDwQEAwIBAjANBgkqhkiG9w0BAQQFAAOBgQAY\n" +
+ "eMnf5AHSNlyUlzXk8o2S0h4gCuvKX6C3kFfKuZcWvFAbx4yQOWLS2s15/nzR4+AP\n" +
+ "FGX3lgJjROyAh7fGedTQK+NFWwkM2ag1g3hXktnlnT1qHohi0w31nVBJxXEDO/Ck\n" +
+ "uJTpJGt8XxxbFaw5v7cHy7XuTAeU/sekvjEiNHW00Q==\n" +
+ "-----END CERTIFICATE-----";
+
+ private static class TestX509CRL extends X509CRL {
+ private final X509CRL crl;
+ TestX509CRL(X509CRL crl) {
+ this.crl = crl;
+ }
+ public Set<String> getCriticalExtensionOIDs() {
+ return crl.getCriticalExtensionOIDs();
+ }
+ public byte[] getExtensionValue(String oid) {
+ return crl.getExtensionValue(oid);
+ }
+ public Set<String> getNonCriticalExtensionOIDs() {
+ return crl.getNonCriticalExtensionOIDs();
+ }
+ public boolean hasUnsupportedCriticalExtension() {
+ return crl.hasUnsupportedCriticalExtension();
+ }
+ public Set<? extends X509CRLEntry> getRevokedCertificates() {
+ return crl.getRevokedCertificates();
+ }
+ public X509CRLEntry getRevokedCertificate(BigInteger serialNumber) {
+ return crl.getRevokedCertificate(serialNumber);
+ }
+ public boolean isRevoked(Certificate cert) {
+ return crl.isRevoked(cert);
+ }
+ public Date getNextUpdate() { return crl.getNextUpdate(); }
+ public Date getThisUpdate() { return crl.getThisUpdate(); }
+ public int getVersion() { return crl.getVersion(); }
+ public Principal getIssuerDN() { return crl.getIssuerDN(); }
+ public byte[] getTBSCertList() throws CRLException {
+ return crl.getTBSCertList();
+ }
+ public byte[] getSignature() { return crl.getSignature(); }
+ public String getSigAlgName() { return crl.getSigAlgName(); }
+ public String getSigAlgOID() { return crl.getSigAlgOID(); }
+ public byte[] getSigAlgParams() { return crl.getSigAlgParams(); }
+ public byte[] getEncoded() throws CRLException {
+ return crl.getEncoded();
+ }
+ public void verify(PublicKey key) throws CRLException,
+ InvalidKeyException, NoSuchAlgorithmException,
+ NoSuchProviderException, SignatureException {
+ crl.verify(key);
+ }
+ public void verify(PublicKey key, String sigProvider) throws
+ CRLException, InvalidKeyException, NoSuchAlgorithmException,
+ NoSuchProviderException, SignatureException {
+ crl.verify(key, sigProvider);
+ }
+ public String toString() { return crl.toString(); }
+ }
+
+ public static void main(String[] args) throws Exception {
+ X509Certificate cert = CertUtils.getCertFromString(TEST_CERT);
+ X509CRL crl = CertUtils.getCRLFromString(TEST_CRL);
+ new TestX509CRL(crl).verify(cert.getPublicKey(), (Provider)null);
+ }
+}
diff --git a/jdk/test/java/security/cert/X509Certificate/VerifyDefault.java b/jdk/test/java/security/cert/X509Certificate/VerifyDefault.java
new file mode 100644
index 0000000..6a46a7d
--- /dev/null
+++ b/jdk/test/java/security/cert/X509Certificate/VerifyDefault.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8175029
+ * @library ../../testlibrary
+ * @summary check that default implementation of
+ * X509Certificate.verify(PublicKey, Provider) works on custom
+ * X509Certificate impl.
+ */
+
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+public class VerifyDefault {
+ private static final String TEST_CERT =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICvTCCAaWgAwIBAgIEGYqL9TANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwRT\n" +
+ "ZWxmMB4XDTE3MDMyODE2NDcyNloXDTE3MDYyNjE2NDcyNlowDzENMAsGA1UEAxME\n" +
+ "U2VsZjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL1pfSJljFVSABOL\n" +
+ "tJbIVPEkz1+2AFgzY1hqwE0EH80lvhOEkiPPYCKwBE5VTZdyFfwFjpyx7eEeJMNT\n" +
+ "o7cixfmkQaiXHr/S1AS4BRTqLG/zgLzoJpVbzi45rnVEZc0oTm11KG3uUxkZTRr3\n" +
+ "5ORbYyZpkscKwHL2M0J/1GmnA1hmhQdwUQyIKxg4eKQwyE+/TdbFlCWVNnOlb+91\n" +
+ "eXvS11nIJ1oaBgn7u4qihuVmFmngLMxExnLYKV6AwdkwFD6pERObclRD9vAl5eUk\n" +
+ "+sM6zQYwfLdyC2i8e+ETBeOg1ijptM4KT5Uaq89zxjLR0DPH4S+aILp3gYHGrW5r\n" +
+ "eMxZAEMCAwEAAaMhMB8wHQYDVR0OBBYEFOME39JtbjzQaK3ufpKo/Pl4sZ8XMA0G\n" +
+ "CSqGSIb3DQEBCwUAA4IBAQCDcw0+Sf0yeVROVlb2/VV3oIblHkGQheXeIurW64k7\n" +
+ "tEzHtx9i8dnj5lzTZNH6hU4GRlyULbSDzjcM3P2XFRsM+0a/kEJZVqnLz5ji//7/\n" +
+ "ZXaRX0TiE2IfFOTGbO6LusO3yR4tOER/WHllz2H21C2SbW3+92Ou28glTZa42AAZ\n" +
+ "mUj9j+p6mZqD4/tUBqAEqqQoMIhw9CNjc46STNayBjt/0/+I2pfy6LagrMbjBzZ0\n" +
+ "A5kXg9WjnywGk8XFr/3RZz8DrUmCYs2qCYLCHQHsuCE6gCuf9wKhKyD51MFXXRr0\n" +
+ "cyG6LYQjrreMHYk4ZfN2NPC6lGjWxB5mIbV/DuikCnYu\n" +
+ "-----END CERTIFICATE-----";
+
+ private static class TestX509Certificate extends X509Certificate {
+ private final X509Certificate cert;
+ TestX509Certificate(X509Certificate cert) {
+ this.cert = cert;
+ }
+ public Set<String> getCriticalExtensionOIDs() {
+ return cert.getCriticalExtensionOIDs();
+ }
+ public byte[] getExtensionValue(String oid) {
+ return cert.getExtensionValue(oid);
+ }
+ public Set<String> getNonCriticalExtensionOIDs() {
+ return cert.getNonCriticalExtensionOIDs();
+ }
+ public boolean hasUnsupportedCriticalExtension() {
+ return cert.hasUnsupportedCriticalExtension();
+ }
+ public void checkValidity() throws CertificateExpiredException,
+ CertificateNotYetValidException {
+ cert.checkValidity();
+ }
+ public void checkValidity(Date date) throws CertificateExpiredException,
+ CertificateNotYetValidException {
+ cert.checkValidity(date);
+ }
+ public int getVersion() { return cert.getVersion(); }
+ public BigInteger getSerialNumber() { return cert.getSerialNumber(); }
+ public Principal getIssuerDN() { return cert.getIssuerDN(); }
+ public Principal getSubjectDN() { return cert.getSubjectDN(); }
+ public Date getNotBefore() { return cert.getNotBefore(); }
+ public Date getNotAfter() { return cert.getNotAfter(); }
+ public byte[] getTBSCertificate() throws CertificateEncodingException {
+ return cert.getTBSCertificate();
+ }
+ public byte[] getSignature() { return cert.getSignature(); }
+ public String getSigAlgName() { return cert.getSigAlgName(); }
+ public String getSigAlgOID() { return cert.getSigAlgOID(); }
+ public byte[] getSigAlgParams() { return cert.getSigAlgParams(); }
+ public boolean[] getIssuerUniqueID() {
+ return cert.getIssuerUniqueID();
+ }
+ public boolean[] getSubjectUniqueID() {
+ return cert.getSubjectUniqueID();
+ }
+ public boolean[] getKeyUsage() { return cert.getKeyUsage(); }
+ public int getBasicConstraints() { return cert.getBasicConstraints(); }
+ public byte[] getEncoded() throws CertificateEncodingException {
+ return cert.getEncoded();
+ }
+ public void verify(PublicKey key) throws CertificateException,
+ InvalidKeyException, NoSuchAlgorithmException,
+ NoSuchProviderException, SignatureException {
+ cert.verify(key);
+ }
+ public void verify(PublicKey key, String sigProvider) throws
+ CertificateException, InvalidKeyException, NoSuchAlgorithmException,
+ NoSuchProviderException, SignatureException {
+ cert.verify(key, sigProvider);
+ }
+ public PublicKey getPublicKey() { return cert.getPublicKey(); }
+ public String toString() { return cert.toString(); }
+ }
+
+ public static void main(String[] args) throws Exception {
+ X509Certificate cert = CertUtils.getCertFromString(TEST_CERT);
+ new TestX509Certificate(cert).verify(cert.getPublicKey(),
+ (Provider)null);
+ }
+}
diff --git a/jdk/test/java/security/testlibrary/CertUtils.java b/jdk/test/java/security/testlibrary/CertUtils.java
index e850ed1..0605706 100644
--- a/jdk/test/java/security/testlibrary/CertUtils.java
+++ b/jdk/test/java/security/testlibrary/CertUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,17 +27,20 @@
* @author Steve Hanna
*
*/
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
+import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertPath;
import java.security.cert.CertPathBuilder;
import java.security.cert.CertPathValidator;
import java.security.cert.CertStore;
import java.security.cert.CollectionCertStoreParameters;
+import java.security.cert.CRLException;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.PKIXCertPathBuilderResult;
import java.security.cert.PKIXCertPathValidatorResult;
@@ -60,59 +63,71 @@
* Get a DER-encoded X.509 certificate from a file.
*
* @param certFilePath path to file containing DER-encoded certificate
- * @return X509Certificate
- * @throws IOException on error
+ * @return the X509Certificate
+ * @throws CertificateException if the certificate type is not supported
+ * or cannot be parsed
+ * @throws IOException if the file cannot be opened
*/
public static X509Certificate getCertFromFile(String certFilePath)
- throws IOException {
- X509Certificate cert = null;
- try {
- File certFile = new File(System.getProperty("test.src", "."),
- certFilePath);
- if (!certFile.canRead())
- throw new IOException("File " +
- certFile.toString() +
- " is not a readable file.");
- FileInputStream certFileInputStream =
- new FileInputStream(certFile);
- CertificateFactory cf = CertificateFactory.getInstance("X509");
- cert = (X509Certificate)
- cf.generateCertificate(certFileInputStream);
- } catch (Exception e) {
- e.printStackTrace();
- throw new IOException("Can't construct X509Certificate: " +
- e.getMessage());
- }
- return cert;
+ throws CertificateException, IOException {
+ File certFile = new File(System.getProperty("test.src", "."),
+ certFilePath);
+ try (FileInputStream fis = new FileInputStream(certFile)) {
+ return (X509Certificate)
+ CertificateFactory.getInstance("X.509")
+ .generateCertificate(fis);
+ }
}
/**
+ * Get a PEM-encoded X.509 certificate from a string.
+ *
+ * @param cert string containing the PEM-encoded certificate
+ * @return the X509Certificate
+ * @throws CertificateException if the certificate type is not supported
+ * or cannot be parsed
+ */
+ public static X509Certificate getCertFromString(String cert)
+ throws CertificateException {
+ byte[] certBytes = cert.getBytes();
+ ByteArrayInputStream bais = new ByteArrayInputStream(certBytes);
+ return (X509Certificate)
+ CertificateFactory.getInstance("X.509").generateCertificate(bais);
+ }
+
+ /**
* Get a DER-encoded X.509 CRL from a file.
*
* @param crlFilePath path to file containing DER-encoded CRL
- * @return X509CRL
- * @throws IOException on error
+ * @return the X509CRL
+ * @throws CertificateException if the crl type is not supported
+ * @throws CRLException if the crl cannot be parsed
+ * @throws IOException if the file cannot be opened
*/
public static X509CRL getCRLFromFile(String crlFilePath)
- throws IOException {
- X509CRL crl = null;
- try {
- File crlFile = new File(System.getProperty("test.src", "."),
- crlFilePath);
- if (!crlFile.canRead())
- throw new IOException("File " +
- crlFile.toString() +
- " is not a readable file.");
- FileInputStream crlFileInputStream =
- new FileInputStream(crlFile);
- CertificateFactory cf = CertificateFactory.getInstance("X509");
- crl = (X509CRL) cf.generateCRL(crlFileInputStream);
- } catch (Exception e) {
- e.printStackTrace();
- throw new IOException("Can't construct X509CRL: " +
- e.getMessage());
- }
- return crl;
+ throws CertificateException, CRLException, IOException {
+ File crlFile = new File(System.getProperty("test.src", "."),
+ crlFilePath);
+ try (FileInputStream fis = new FileInputStream(crlFile)) {
+ return (X509CRL)
+ CertificateFactory.getInstance("X.509").generateCRL(fis);
+ }
+ }
+
+ /**
+ * Get a PEM-encoded X.509 crl from a string.
+ *
+ * @param crl string containing the PEM-encoded crl
+ * @return the X509CRL
+ * @throws CertificateException if the crl type is not supported
+ * @throws CRLException if the crl cannot be parsed
+ */
+ public static X509CRL getCRLFromString(String crl)
+ throws CertificateException, CRLException {
+ byte[] crlBytes = crl.getBytes();
+ ByteArrayInputStream bais = new ByteArrayInputStream(crlBytes);
+ return (X509CRL)
+ CertificateFactory.getInstance("X.509").generateCRL(bais);
}
/**
diff --git a/jdk/test/java/security/testlibrary/Proc.java b/jdk/test/java/security/testlibrary/Proc.java
index 1ab58bf..95192cd 100644
--- a/jdk/test/java/security/testlibrary/Proc.java
+++ b/jdk/test/java/security/testlibrary/Proc.java
@@ -235,6 +235,13 @@
br = new BufferedReader(new InputStreamReader(p.getInputStream()));
return this;
}
+ String getId(String suffix) {
+ if (debug != null) {
+ return debug + "." + suffix;
+ } else {
+ return System.identityHashCode(this) + "." + suffix;
+ }
+ }
// Reads a line from stdout of proc
public String readLine() throws IOException {
String s = br.readLine();
@@ -303,9 +310,13 @@
boolean isEmpty = true;
while (true) {
int i = System.in.read();
- if (i == -1) break;
+ if (i == -1) {
+ break;
+ }
isEmpty = false;
- if (i == '\n') break;
+ if (i == '\n') {
+ break;
+ }
if (i != 13) {
// Force it to a char, so only simple ASCII works.
sb.append((char)i);
diff --git a/jdk/test/javax/security/sasl/Sasl/DisabledMechanisms.java b/jdk/test/javax/security/sasl/Sasl/DisabledMechanisms.java
new file mode 100644
index 0000000..428cc3a
--- /dev/null
+++ b/jdk/test/javax/security/sasl/Sasl/DisabledMechanisms.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2019, 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 8200400
+ * @library /lib/testlibrary
+ * @run main/othervm DisabledMechanisms
+ * DIGEST-MD5 DIGEST-MD5
+ * @run main/othervm -DdisabledMechanisms= DisabledMechanisms
+ * DIGEST-MD5 DIGEST-MD5
+ * @run main/othervm -DdisabledMechanisms=DIGEST-MD5,NTLM DisabledMechanisms
+ * null null
+ * @run main/othervm -DdisabledMechanisms=DIGEST-MD5 DisabledMechanisms
+ * NTLM null
+ * @run main/othervm -DdisabledMechanisms=NTLM DisabledMechanisms
+ * DIGEST-MD5 DIGEST-MD5
+ */
+
+import java.security.Security;
+import java.util.Collections;
+import java.util.Map;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslServer;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+
+import jdk.testlibrary.Asserts;
+
+public class DisabledMechanisms {
+
+ public static void main(String[] args) throws Exception {
+
+ String authorizationId = "username";
+ String protocol = "ldap";
+ String serverName = "server1";
+ Map props = Collections.emptyMap();
+
+ String disabled = System.getProperty("disabledMechanisms");
+ if (disabled != null) {
+ Security.setProperty("jdk.sasl.disabledMechanisms", disabled);
+ }
+
+ CallbackHandler callbackHandler = callbacks -> {
+ for (Callback cb : callbacks) {
+ if (cb instanceof PasswordCallback) {
+ ((PasswordCallback) cb).setPassword("password".toCharArray());
+ }
+ }
+ };
+
+ SaslClient client = Sasl.createSaslClient(
+ new String[]{"DIGEST-MD5", "NTLM"}, authorizationId,
+ protocol, serverName, props, callbackHandler);
+ Asserts.assertEQ(client == null ? null : client.getMechanismName(),
+ args[0].equals("null") ? null : args[0]);
+
+ SaslServer server = Sasl.createSaslServer(
+ "DIGEST-MD5", protocol, serverName, props, callbackHandler);
+ Asserts.assertEQ(server == null ? null : server.getMechanismName(),
+ args[1].equals("null") ? null : args[1]);
+ }
+}
diff --git a/jdk/test/javax/xml/crypto/dsig/ErrorHandlerPermissions.java b/jdk/test/javax/xml/crypto/dsig/ErrorHandlerPermissions.java
new file mode 100644
index 0000000..1231d3c
--- /dev/null
+++ b/jdk/test/javax/xml/crypto/dsig/ErrorHandlerPermissions.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.security.KeyFactory;
+import java.security.PublicKey;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
+import javax.xml.XMLConstants;
+import javax.xml.crypto.Data;
+import javax.xml.crypto.KeySelector;
+import javax.xml.crypto.OctetStreamData;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.URIReference;
+import javax.xml.crypto.URIReferenceException;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import javax.xml.crypto.dsig.dom.DOMValidateContext;
+import javax.xml.parsers.DocumentBuilderFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * @test
+ * @bug 8079140
+ * @summary Check if IgnoreAllErrorHandler doesn't require additional permission
+ * @run main/othervm/java.security.policy=ErrorHandlerPermissions.policy
+ * ErrorHandlerPermissions
+ */
+public class ErrorHandlerPermissions {
+
+ private final static String FS = System.getProperty("file.separator");
+ private final static String DIR = System.getProperty("test.src", ".");
+ private final static String DATA_DIR = DIR + FS + "data";
+ private final static String SIGNATURE = DATA_DIR + FS +
+ "signature-external-rsa.xml";
+
+ private static final String validationKey =
+ "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnx4TdvPSA5vcsPi0OJZi9Ox0Z" +
+ "2FRz2oeUCtuWoyEg0kUCeFd+jJZMstDJUiZNSOeuCO3FWSpdJgAwI4zlveHvuU/o" +
+ "qHSa1eYTObOCvxfVYGGflWsSvGXyiANtRWVUrYODBeyL+2pWxDYh+Fi5EKizPfTG" +
+ "wRjBVRSkRZKTnSjnQwIDAQAB";
+
+ private static final URIDereferencer dereferencer =
+ new DummyURIDereferencer();
+
+ public static void main(String[] args) throws Exception {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ dbf.setValidating(false);
+ dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
+ Document doc = dbf.newDocumentBuilder().parse(new File(SIGNATURE));
+ NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS,
+ "Signature");
+ if (nl.getLength() == 0) {
+ throw new RuntimeException("Couldn't find 'Signature' element");
+ }
+ Element element = (Element) nl.item(0);
+
+ byte[] keyBytes = Base64.getDecoder().decode(validationKey);
+ X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ PublicKey key = kf.generatePublic(spec);
+ KeySelector ks = KeySelector.singletonKeySelector(key);
+
+ DOMValidateContext vc = new DOMValidateContext(ks, element);
+
+ // disable secure validation mode
+ vc.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.FALSE);
+
+ // set a dummy dereferencer to be able to get content by references
+ vc.setURIDereferencer(dereferencer);
+
+ XMLSignatureFactory factory = XMLSignatureFactory.getInstance();
+ XMLSignature signature = factory.unmarshalXMLSignature(vc);
+
+ // run validation
+ signature.validate(vc);
+ }
+
+ /**
+ * This URIDereferencer returns a static XML document.
+ */
+ private static class DummyURIDereferencer implements URIDereferencer {
+
+ @Override
+ public Data dereference(final URIReference ref, XMLCryptoContext ctx)
+ throws URIReferenceException {
+ // return static content
+ return new OctetStreamData(new ByteArrayInputStream(
+ "<test>test</test>".getBytes()), ref.getURI(),
+ ref.getType());
+ }
+ }
+
+}
diff --git a/jdk/test/javax/xml/crypto/dsig/ErrorHandlerPermissions.policy b/jdk/test/javax/xml/crypto/dsig/ErrorHandlerPermissions.policy
new file mode 100644
index 0000000..8db9c01
--- /dev/null
+++ b/jdk/test/javax/xml/crypto/dsig/ErrorHandlerPermissions.policy
@@ -0,0 +1,5 @@
+grant {
+ permission java.util.PropertyPermission "test.src", "read";
+ permission java.util.PropertyPermission "file.separator", "read";
+ permission java.io.FilePermission "${test.src}/-", "read";
+};
diff --git a/jdk/test/javax/xml/crypto/dsig/GenerationTests.java b/jdk/test/javax/xml/crypto/dsig/GenerationTests.java
index 4a3e191..b6f284b 100644
--- a/jdk/test/javax/xml/crypto/dsig/GenerationTests.java
+++ b/jdk/test/javax/xml/crypto/dsig/GenerationTests.java
@@ -24,7 +24,7 @@
/**
* @test
* @bug 4635230 6283345 6303830 6824440 6867348 7094155 8038184
- * 8038349 8074784 8210736
+ * 8038349 8046724 8074784 8210736
* @summary Basic unit tests for generating XML Signatures with JSR 105
* @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java
* X509KeySelector.java GenerationTests.java
@@ -54,6 +54,13 @@
import java.security.spec.KeySpec;
import java.security.spec.DSAPrivateKeySpec;
import java.security.spec.DSAPublicKeySpec;
+import java.security.spec.ECField;
+import java.security.spec.ECFieldFp;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPrivateKeySpec;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.EllipticCurve;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.*;
@@ -91,9 +98,10 @@
private static DocumentBuilder db;
private static CanonicalizationMethod withoutComments;
private static SignatureMethod dsaSha1, dsaSha256, rsaSha1,
- rsaSha256, rsaSha384, rsaSha512;
+ rsaSha256, rsaSha384, rsaSha512,
+ ecdsaSha1;
private static DigestMethod sha1, sha256, sha384, sha512;
- private static KeyInfo dsa1024, dsa2048, rsa, rsa1024;
+ private static KeyInfo dsa1024, dsa2048, rsa, rsa1024, p256ki;
private static KeySelector kvks = new KeySelectors.KeyValueKeySelector();
private static KeySelector sks;
private static Key signingKey;
@@ -201,6 +209,7 @@
test_create_signature_enveloping_hmac_sha384();
test_create_signature_enveloping_hmac_sha512();
test_create_signature_enveloping_rsa();
+ test_create_signature_enveloping_p256_sha1();
test_create_signature_external_b64_dsa();
test_create_signature_external_dsa();
test_create_signature_keyname();
@@ -346,6 +355,8 @@
(kifac.newKeyValue(getPublicKey("RSA", 512))));
rsa1024 = kifac.newKeyInfo(Collections.singletonList
(kifac.newKeyValue(getPublicKey("RSA", 1024))));
+ p256ki = kifac.newKeyInfo(Collections.singletonList
+ (kifac.newKeyValue(getECPublicKey())));
rsaSha1 = fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null);
rsaSha256 = fac.newSignatureMethod
("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null);
@@ -353,6 +364,8 @@
("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", null);
rsaSha512 = fac.newSignatureMethod
("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", null);
+ ecdsaSha1 = fac.newSignatureMethod
+ ("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1", null);
sks = new KeySelectors.SecretKeySelector("secret".getBytes("ASCII"));
httpUd = new HttpURIDereferencer();
@@ -513,6 +526,13 @@
System.out.println();
}
+ static void test_create_signature_enveloping_p256_sha1() throws Exception {
+ System.out.println("* Generating signature-enveloping-p256-sha1.xml");
+ test_create_signature_enveloping(sha1, ecdsaSha1, p256ki,
+ getECPrivateKey(), kvks, false);
+ System.out.println();
+ }
+
static void test_create_signature_external_b64_dsa() throws Exception {
System.out.println("* Generating signature-external-b64-dsa.xml");
test_create_signature_external(dsaSha1, dsa1024, signingKey, kvks, true);
@@ -1526,7 +1546,42 @@
"237008997971129772408397621801631622129297063463868593083106979716" +
"204903524890556839550490384015324575598723478554854070823335021842" +
"210112348400928769";
+ private static final String EC_X =
+ "335863644451761614592446380116804721648611739647823420286081723541" +
+ "6166183710";
+ private static final String EC_Y =
+ "951559601159729477487064127150143688502130342917782252098602422796" +
+ "95457910701";
+ private static final String EC_S =
+ "425976209773168452211813225517384419928639977904006759709292218082" +
+ "7440083936";
+ private static final ECParameterSpec EC_PARAMS;
+ static {
+ final String ec_sfield, ec_a, ec_b, ec_gx, ec_gy, ec_n;
+ ec_sfield =
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF";
+ ec_a =
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC";
+ ec_b =
+ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B";
+ ec_gx =
+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296";
+ ec_gy =
+ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5";
+ ec_n =
+ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551";
+ final int ec_h = 1;
+ final ECField ec_field = new ECFieldFp(bigInt(ec_sfield));
+ final EllipticCurve ec_curve = new EllipticCurve(ec_field,
+ bigInt(ec_a), bigInt(ec_b));
+ final ECPoint ec_g = new ECPoint(bigInt(ec_gx), bigInt(ec_gy));
+ EC_PARAMS = new ECParameterSpec(ec_curve, ec_g, bigInt(ec_n), ec_h);
+ }
+
+ private static BigInteger bigInt(String s) {
+ return new BigInteger(s, 16);
+ }
private static PublicKey getPublicKey(String algo, int keysize)
throws Exception {
KeyFactory kf = KeyFactory.getInstance(algo);
@@ -1555,6 +1610,14 @@
return kf.generatePublic(kspec);
}
+ private static PublicKey getECPublicKey() throws Exception {
+ KeyFactory kf = KeyFactory.getInstance("EC");
+ KeySpec kspec = new ECPublicKeySpec(new ECPoint(new BigInteger(EC_X),
+ new BigInteger(EC_Y)),
+ EC_PARAMS);
+ return kf.generatePublic(kspec);
+ }
+
private static PrivateKey getPrivateKey(String algo, int keysize)
throws Exception {
KeyFactory kf = KeyFactory.getInstance(algo);
@@ -1581,6 +1644,12 @@
return kf.generatePrivate(kspec);
}
+ private static PrivateKey getECPrivateKey() throws Exception {
+ KeyFactory kf = KeyFactory.getInstance("EC");
+ KeySpec kspec = new ECPrivateKeySpec(new BigInteger(EC_S), EC_PARAMS);
+ return kf.generatePrivate(kspec);
+ }
+
private static SecretKey getSecretKey(final byte[] secret) {
return new SecretKey() {
public String getFormat() { return "RAW"; }
diff --git a/jdk/test/javax/xml/crypto/dsig/KeySelectors.java b/jdk/test/javax/xml/crypto/dsig/KeySelectors.java
index 290c55b..2195b8c 100644
--- a/jdk/test/javax/xml/crypto/dsig/KeySelectors.java
+++ b/jdk/test/javax/xml/crypto/dsig/KeySelectors.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, 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
@@ -172,7 +172,6 @@
throw new KeySelectorException("No KeyValue element found!");
}
- //@@@FIXME: this should also work for key types other than DSA/RSA
static boolean algEquals(String algURI, String algName) {
if (algName.equalsIgnoreCase("DSA") &&
algURI.equals(SignatureMethod.DSA_SHA1) ||
@@ -187,6 +186,10 @@
algURI.equals
("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"))) {
return true;
+ } else if (algName.equalsIgnoreCase("EC") &&
+ (algURI.equals
+ ("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"))) {
+ return true;
} else {
return false;
}
diff --git a/jdk/test/javax/xml/crypto/dsig/ValidationTests.java b/jdk/test/javax/xml/crypto/dsig/ValidationTests.java
index 278d64c..d738481 100644
--- a/jdk/test/javax/xml/crypto/dsig/ValidationTests.java
+++ b/jdk/test/javax/xml/crypto/dsig/ValidationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, 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
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 4635230 6365103 6366054 6824440 7131084
+ * @bug 4635230 6365103 6366054 6824440 7131084 8046724
* @summary Basic unit tests for validating XML Signatures with JSR 105
* @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java
* X509KeySelector.java ValidationTests.java
@@ -99,6 +99,7 @@
new Test("signature-enveloping-b64-dsa.xml", KVKS),
new Test("signature-enveloping-dsa.xml", KVKS),
new Test("signature-enveloping-rsa.xml", KVKS),
+ new Test("signature-enveloping-p256-sha1.xml", KVKS),
new Test("signature-enveloping-hmac-sha1.xml", SKKS),
new Test("signature-external-dsa.xml", KVKS),
new Test("signature-external-b64-dsa.xml", KVKS),
diff --git a/jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-p256-sha1.xml b/jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-p256-sha1.xml
new file mode 100644
index 0000000..0ace115
--- /dev/null
+++ b/jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-p256-sha1.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"/><Reference URI="#object"><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>7/XTsHaBSOnJ/jXD5v0zL6VKYsk=</DigestValue></Reference></SignedInfo><SignatureValue>WiF/Hd0s7BiH36Ds/1iJcbKiXOUVBSGFteuTjXwBbezR43NAwpMmMX5c1su0A9hG9rVVzE/1DOlO
+vuDVLBBblg==</SignatureValue><KeyInfo><KeyValue><ECKeyValue xmlns="http://www.w3.org/2009/xmldsig11#"><NamedCurve URI="urn:oid:1.2.840.10045.3.1.7"/><PublicKey>BAds672US3sCYunM2k2bEQLbuRxdQlNTvq+5fitOpDMe0mBdZV4J3yZaG0taziYIuAT9GJGfds+q
+xtXOCNWe/60=</PublicKey></ECKeyValue></KeyValue></KeyInfo><Object Id="object">some text</Object></Signature>
\ No newline at end of file
diff --git a/jdk/test/javax/xml/crypto/dsig/data/signature-external-rsa.xml b/jdk/test/javax/xml/crypto/dsig/data/signature-external-rsa.xml
new file mode 100644
index 0000000..fb3a0f4
--- /dev/null
+++ b/jdk/test/javax/xml/crypto/dsig/data/signature-external-rsa.xml
@@ -0,0 +1,3 @@
+<test xmlns="http://example.org/envelope">test<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></CanonicalizationMethod><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod><Reference URI="http://oracle.com"><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod><DigestValue>1Bq8FsjajUBYPD7stQeJSc66GlM=</DigestValue></Reference></SignedInfo><SignatureValue>f6trDCcPsLLkIV/V4DGFbRf8b9Jwal8xGBDshNzEXwPmym2ChN85rbKIg/cbunf04F89/SXLo2v9
+AYjLcUr3G/Vz5YUmqNhnBvJukXgsIG0ddWl3mFi9Tk+CLINlbgfsaFqU9pQwFjmDyAqIrvZYqW7p
+rTHLetv218mbUVBBAkc=</SignatureValue></Signature></test>
\ No newline at end of file
diff --git a/jdk/test/lib/jdk/test/lib/SigTestUtil.java b/jdk/test/lib/jdk/test/lib/SigTestUtil.java
new file mode 100644
index 0000000..f569c06
--- /dev/null
+++ b/jdk/test/lib/jdk/test/lib/SigTestUtil.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.test.lib;
+
+import java.security.*;
+import java.security.spec.*;
+import java.util.*;
+
+/*
+ * Utility class used by various Signature related regression tests for
+ * common functions such as generating the list of to-be-tested algorithms
+ * based on key size, etc. Currently, this is mostly needed by RSA
+ * signatures.
+ */
+public class SigTestUtil {
+
+ public enum SignatureType {
+ RSA("RSA"),
+ RSASSA_PSS("RSASSA-PSS")
+ ;
+
+ private String keyAlg;
+
+ SignatureType(String keyAlg) {
+ this.keyAlg = keyAlg;
+ }
+ @Override
+ public String toString() {
+ return keyAlg;
+ }
+ }
+
+ // collection of all supported digest algorithms
+ // note that the entries are ordered by required key sizes
+ private static final String[] DIGEST_ALGS = {
+ "SHA-512",
+ "SHA-384",
+ "SHA-256",
+ "SHA-512/256",
+ "SHA-224",
+ "SHA-512/224",
+ "SHA-1",
+ "MD2", "MD5" // these aren't supported by RSA PSS
+ };
+
+ // indice for message digest algorithms lookup
+ // may need to be adjusted if new algorithms are added
+ private static final int PKCS1_5_INDEX_768 = 0;
+ private static final int PKCS1_5_INDEX_512 = 2;
+ private static final int PKCS1_5_INDEX_END = DIGEST_ALGS.length;
+ private static final int PSS_INDEX_2048 = 0;
+ private static final int PSS_INDEX_1024 = 1;
+ private static final int PSS_INDEX_768 = 2;
+ private static final int PSS_INDEX_512 = 4;
+ private static final int PSS_INDEX_END = 7;
+
+ public static Iterable<String> getDigestAlgorithms(SignatureType type,
+ int keysize) throws RuntimeException {
+
+ // initialize to all, then trim based on key size
+ List<String> result = new ArrayList<>(Arrays.asList(DIGEST_ALGS));
+ int index = 0;
+ switch (type) {
+ case RSA:
+ if (keysize >= 768) {
+ index = PKCS1_5_INDEX_768;
+ } else if (keysize >= 512) {
+ index = PKCS1_5_INDEX_512;
+ } else {
+ throw new RuntimeException("Keysize too small: " + keysize);
+ }
+ result = result.subList(index, PKCS1_5_INDEX_END);
+ break;
+ case RSASSA_PSS:
+ if (keysize >= 2048) {
+ index = PSS_INDEX_2048;
+ } else if (keysize >= 1024) {
+ index = PSS_INDEX_1024;
+ } else if (keysize >= 768) {
+ index = PSS_INDEX_768;
+ } else if (keysize >= 512) {
+ index = PSS_INDEX_512;
+ } else {
+ throw new RuntimeException("Keysize too small: " + keysize);
+ }
+ result = result.subList(index, PSS_INDEX_END);
+ break;
+ default:
+ // XXX maybe just return result instead of error out?
+ throw new RuntimeException("Unsupported signature type: " + type);
+ }
+ return result;
+ }
+
+ public static AlgorithmParameterSpec generateDefaultParameter(
+ SignatureType type, String mdAlg) throws RuntimeException {
+ // only RSASSA-PSS signature uses parameters
+ switch (type) {
+ case RSASSA_PSS:
+ try {
+ MessageDigest md = MessageDigest.getInstance(mdAlg);
+ return new PSSParameterSpec(mdAlg, "MGF1",
+ new MGF1ParameterSpec(mdAlg), md.getDigestLength(),
+ PSSParameterSpec.TRAILER_FIELD_BC);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ default:
+ return null;
+ }
+ }
+
+ public static String generateSigAlg(SignatureType type,
+ String mdAlg) throws RuntimeException {
+ switch (type) {
+ case RSA:
+ int idx = mdAlg.indexOf("-");
+ if (idx != -1) {
+ mdAlg = mdAlg.substring(0, idx) + mdAlg.substring(idx+1);
+ }
+ return mdAlg + "with" + type.toString();
+ case RSASSA_PSS:
+ return type.toString();
+ default:
+ throw new RuntimeException("Unsupported signature type " + type );
+ }
+ }
+
+}
diff --git a/jdk/test/lib/testlibrary/ClassFileInstaller.java b/jdk/test/lib/testlibrary/ClassFileInstaller.java
index dd8777b..0f5b515 100644
--- a/jdk/test/lib/testlibrary/ClassFileInstaller.java
+++ b/jdk/test/lib/testlibrary/ClassFileInstaller.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,28 +21,229 @@
* questions.
*/
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
import java.io.InputStream;
+import java.io.ByteArrayInputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
/**
- * Dump a class file for a class on the class path in the current directory
+ * Dump a class file for a class on the class path in the current directory, or
+ * in the specified JAR file. This class is usually used when you build a class
+ * from a test library, but want to use this class in a sub-process.
+ *
+ * For example, to build the following library class:
+ * test/lib/sun/hotspot/WhiteBox.java
+ *
+ * You would use the following tags:
+ *
+ * @library /test/lib
+ * @build sun.hotspot.WhiteBox
+ *
+ * JTREG would build the class file under
+ * ${JTWork}/classes/test/lib/sun/hotspot/WhiteBox.class
+ *
+ * With you run your main test class using "@run main MyMainClass", JTREG would setup the
+ * -classpath to include "${JTWork}/classes/test/lib/", so MyMainClass would be able to
+ * load the WhiteBox class.
+ *
+ * However, if you run a sub process, and do not wish to use the exact same -classpath,
+ * You can use ClassFileInstaller to ensure that WhiteBox is available in the current
+ * directory of your test:
+ *
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *
+ * Or, you can use the -jar option to store the class in the specified JAR file. If a relative
+ * path name is given, the JAR file would be relative to the current directory of
+ *
+ * @run main ClassFileInstaller -jar myjar.jar sun.hotspot.WhiteBox
*/
public class ClassFileInstaller {
/**
+ * You can enable debug tracing of ClassFileInstaller by running JTREG with
+ * jtreg -DClassFileInstaller.debug=true ... <names of tests>
+ */
+ public static boolean DEBUG = Boolean.getBoolean("ClassFileInstaller.debug");
+
+ /**
* @param args The names of the classes to dump
* @throws Exception
*/
public static void main(String... args) throws Exception {
- for (String arg : args) {
- ClassLoader cl = ClassFileInstaller.class.getClassLoader();
+ if (args.length > 1 && args[0].equals("-jar")) {
+ if (args.length < 2) {
+ throw new RuntimeException("Usage: ClassFileInstaller <options> <classes>\n" +
+ "where possible options include:\n" +
+ " -jar <path> Write to the JAR file <path>");
+ }
+ writeJar(args[1], null, args, 2, args.length);
+ } else {
+ if (DEBUG) {
+ System.out.println("ClassFileInstaller: Writing to " + System.getProperty("user.dir"));
+ }
+ for (String arg : args) {
+ writeClassToDisk(arg);
+ }
+ }
+ }
- // Convert dotted class name to a path to a class file
- String pathName = arg.replace('.', '/').concat(".class");
- InputStream is = cl.getResourceAsStream(pathName);
+ public static class Manifest {
+ private InputStream in;
+ private Manifest(InputStream in) {
+ this.in = in;
+ }
+
+ static Manifest fromSourceFile(String fileName) throws Exception {
+ String pathName = System.getProperty("test.src") + File.separator + fileName;
+ return new Manifest(new FileInputStream(pathName));
+ }
+
+ // Example:
+ // String manifest = "Premain-Class: RedefineClassHelper\n" +
+ // "Can-Redefine-Classes: true\n";
+ // ClassFileInstaller.writeJar("redefineagent.jar",
+ // ClassFileInstaller.Manifest.fromString(manifest),
+ // "RedefineClassHelper");
+ static Manifest fromString(String manifest) throws Exception {
+ return new Manifest(new ByteArrayInputStream(manifest.getBytes()));
+ }
+
+ public InputStream getInputStream() {
+ return in;
+ }
+ }
+
+ private static void writeJar(String jarFile, Manifest manifest, String classes[], int from, int to) throws Exception {
+ if (DEBUG) {
+ System.out.println("ClassFileInstaller: Writing to " + getJarPath(jarFile));
+ }
+
+ (new File(jarFile)).delete();
+ FileOutputStream fos = new FileOutputStream(jarFile);
+ ZipOutputStream zos = new ZipOutputStream(fos);
+
+ // The manifest must be the first or second entry. See comments in JarInputStream
+ // constructor and JDK-5046178.
+ if (manifest != null) {
+ writeToDisk(zos, "META-INF/MANIFEST.MF", manifest.getInputStream());
+ }
+
+ for (int i=from; i<to; i++) {
+ writeClassToDisk(zos, classes[i]);
+ }
+
+ zos.close();
+ fos.close();
+ }
+
+ /*
+ * You can call ClassFileInstaller.writeJar() from your main test class instead of
+ * using "@run ClassFileInstaller -jar ...". E.g.,
+ *
+ * String jarPath = ClassFileInstaller.getJarPath("myjar.jar", "sun.hotspot.WhiteBox")
+ *
+ * If you call this API, make sure you build ClassFileInstaller with the following tags:
+ *
+ * @library testlibrary
+ * @build ClassFileInstaller
+ */
+ public static String writeJar(String jarFile, String... classes) throws Exception {
+ writeJar(jarFile, null, classes, 0, classes.length);
+ return getJarPath(jarFile);
+ }
+
+ public static String writeJar(String jarFile, Manifest manifest, String... classes) throws Exception {
+ writeJar(jarFile, manifest, classes, 0, classes.length);
+ return getJarPath(jarFile);
+ }
+
+ /**
+ * This returns the absolute path to the file specified in "@ClassFileInstaller -jar myjar.jar",
+ * In your test program, instead of using the JAR file name directly:
+ *
+ * String jarPath = "myjar.jar";
+ *
+ * you should call this function, like:
+ *
+ * String jarPath = ClassFileInstaller.getJarPath("myjar.jar")
+ *
+ * The reasons are:
+ * (1) Using absolute path makes it easy to cut-and-paste from the JTR file and rerun your
+ * test in any directory.
+ * (2) In the future, we may make the JAR file name unique to avoid clobbering
+ * during parallel JTREG execution.
+ *
+ */
+ public static String getJarPath(String jarFileName) {
+ return new File(jarFileName).getAbsolutePath();
+ }
+
+ public static void writeClassToDisk(String className) throws Exception {
+ writeClassToDisk((ZipOutputStream)null, className);
+ }
+ private static void writeClassToDisk(ZipOutputStream zos, String className) throws Exception {
+ writeClassToDisk(zos, className, "");
+ }
+
+ public static void writeClassToDisk(String className, String prependPath) throws Exception {
+ writeClassToDisk(null, className, prependPath);
+ }
+ private static void writeClassToDisk(ZipOutputStream zos, String className, String prependPath) throws Exception {
+ ClassLoader cl = ClassFileInstaller.class.getClassLoader();
+
+ // Convert dotted class name to a path to a class file
+ String pathName = className.replace('.', '/').concat(".class");
+ InputStream is = cl.getResourceAsStream(pathName);
+ if (is == null) {
+ throw new RuntimeException("Failed to find " + pathName);
+ }
+ if (prependPath.length() > 0) {
+ pathName = prependPath + "/" + pathName;
+ }
+ writeToDisk(zos, pathName, is);
+ }
+
+ public static void writeClassToDisk(String className, byte[] bytecode) throws Exception {
+ writeClassToDisk(null, className, bytecode);
+ }
+ private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode) throws Exception {
+ writeClassToDisk(zos, className, bytecode, "");
+ }
+
+ public static void writeClassToDisk(String className, byte[] bytecode, String prependPath) throws Exception {
+ writeClassToDisk(null, className, bytecode, prependPath);
+ }
+ private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode, String prependPath) throws Exception {
+ // Convert dotted class name to a path to a class file
+ String pathName = className.replace('.', '/').concat(".class");
+ if (prependPath.length() > 0) {
+ pathName = prependPath + "/" + pathName;
+ }
+ writeToDisk(zos, pathName, new ByteArrayInputStream(bytecode));
+ }
+
+ private static void writeToDisk(ZipOutputStream zos, String pathName, InputStream is) throws Exception {
+ if (DEBUG) {
+ System.out.println("ClassFileInstaller: Writing " + pathName);
+ }
+ if (zos != null) {
+ ZipEntry ze = new ZipEntry(pathName);
+ zos.putNextEntry(ze);
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = is.read(buf))>0){
+ zos.write(buf, 0, len);
+ }
+ } else {
// Create the class file's package directory
Path p = Paths.get(pathName);
Path parent = p.getParent();
@@ -52,5 +253,6 @@
// Create the class file
Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
}
+ is.close();
}
}
diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/FileUtils.java b/jdk/test/lib/testlibrary/jdk/testlibrary/FileUtils.java
index b9f3088..587bf82 100644
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/FileUtils.java
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/FileUtils.java
@@ -228,4 +228,3 @@
return areFileSystemsAccessible;
}
}
-
diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/IOUtils.java b/jdk/test/lib/testlibrary/jdk/testlibrary/IOUtils.java
new file mode 100644
index 0000000..4bfddd0
--- /dev/null
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/IOUtils.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014, 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.
+ */
+
+package jdk.testlibrary;
+
+/**
+ * Defines useful I/O methods.
+ */
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+public final class IOUtils {
+
+ /*
+ * Prevent instantiation.
+ */
+ private IOUtils() {}
+
+ /**
+ * Read all bytes from <code>in</code>
+ * until EOF is detected.
+ * @param in input stream, must not be null
+ * @return bytes read
+ * @throws IOException Any IO error.
+ */
+ public static byte[] readFully(InputStream is) throws IOException {
+ byte[] output = {};
+ int pos = 0;
+ while (true) {
+ int bytesToRead;
+ if (pos >= output.length) { // Only expand when there's no room
+ bytesToRead = output.length + 1024;
+ if (output.length < pos + bytesToRead) {
+ output = Arrays.copyOf(output, pos + bytesToRead);
+ }
+ } else {
+ bytesToRead = output.length - pos;
+ }
+ int cc = is.read(output, pos, bytesToRead);
+ if (cc < 0) {
+ if (output.length != pos) {
+ output = Arrays.copyOf(output, pos);
+ }
+ break;
+ }
+ pos += cc;
+ }
+ return output;
+ }
+}
diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/security/DerUtils.java b/jdk/test/lib/testlibrary/jdk/testlibrary/security/DerUtils.java
new file mode 100644
index 0000000..aedbd54
--- /dev/null
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/security/DerUtils.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.testlibrary.security;
+
+import jdk.testlibrary.Asserts;
+import sun.security.util.DerInputStream;
+import sun.security.util.DerValue;
+import sun.security.util.ObjectIdentifier;
+
+import java.io.IOException;
+
+public class DerUtils {
+ /**
+ * Returns a DerValue (deep) inside another DerValue.
+ * <p>
+ * The location of the inner DerValue is expressed as a string, in which
+ * each character is a step from the outer DerValue into the inner one.
+ * If it's a number n, the n'th element (starting from 0) of a sequence
+ * is the next step. If it's 'c', the content of an OctetString parsed
+ * as a DerValue is the next step. Note that n cannot be bigger than 9.
+ * <p>
+ * Attention: do not reuse the return value. DerValue is mutable and
+ * reading it advances a pointer inside.
+ * <p>
+ * For example, here is a PKCS #12 file:
+ * <pre>
+ * 0000:0845 [] SEQUENCE
+ * 0004:0003 [0] INTEGER 3
+ * 0007:07FE [1] SEQUENCE
+ * 000B:000B [10] OID 1.2.840.113549.1.7.1 (data)
+ * 0016:07EF [11] cont [0]
+ * 001A:07EB [110] OCTET STRING
+ * ...
+ * </pre>
+ * and the content of OCTET string at offset 001A can be parsed as another
+ * DerValue which is:
+ * <pre>
+ * 0000:07E7 [] SEQUENCE
+ * 0004:0303 [0] SEQUENCE
+ * 0008:000B [00] OID 1.2.840.113549.1.7.1 (data)
+ * ....
+ * </pre>
+ * Then the OID is {@code innerDerValue(data, "110c00").getOID()}.
+ *
+ * @param data the outer DerValue. We choose byte[] instead of DerValue
+ * because DerValue is mutable and cannot be reused.
+ * @param location the location of the inner DerValue
+ * @return the inner DerValue, or null if no DerValue is at the location
+ * @throws IOException if an I/O error happens
+ */
+ public static DerValue innerDerValue(byte[] data, String location)
+ throws IOException {
+
+ DerValue v = new DerValue(data);
+ for (char step : location.toCharArray()) {
+ if (step == 'c') {
+ v = new DerValue(v.getOctetString());
+ } else {
+ DerInputStream ins = v.getData();
+ // skip n DerValue in the sequence
+ for (int i = 0; i < step - '0'; i++) {
+ ins.getDerValue();
+ }
+ if (ins.available() > 0) {
+ v = ins.getDerValue();
+ } else {
+ return null;
+ }
+ }
+ }
+ return v;
+ }
+
+ /**
+ * Ensures that the inner DerValue is the expected ObjectIdentifier.
+ */
+ public static void checkAlg(byte[] der, String location,
+ ObjectIdentifier expected) throws Exception {
+ Asserts.assertEQ(innerDerValue(der, location).getOID(), expected);
+ }
+
+ /**
+ * Ensures that the inner DerValue is the expected integer.
+ */
+ public static void checkInt(byte[] der, String location, int expected)
+ throws Exception {
+ Asserts.assertEQ(innerDerValue(der, location).getInteger(), expected);
+ }
+
+ /**
+ * Ensures that there is no inner DerValue at the specified location.
+ */
+ public static void shouldNotExist(byte[] der, String location)
+ throws Exception {
+ Asserts.assertTrue(innerDerValue(der, location) == null);
+ }
+}
diff --git a/jdk/test/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java b/jdk/test/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java
new file mode 100644
index 0000000..6cb5006
--- /dev/null
+++ b/jdk/test/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java
@@ -0,0 +1,552 @@
+/*
+ * Copyright (c) 2019, 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 8233223
+ * @summary Interoperability tests with Amazon's CA1, CA2, CA3, and CA4
+ * @build ValidatePathWithParams
+ * @run main/othervm -Djava.security.debug=certpath AmazonCA OCSP
+ * @run main/othervm -Djava.security.debug=certpath AmazonCA CRL
+ */
+
+/*
+ * Obtain TLS test artifacts for Amazon CAs from:
+ *
+ * Amazon Root CA 1
+ * Valid - https://good.sca1a.amazontrust.com/
+ * Revoked - https://revoked.sca1a.amazontrust.com/
+ * Amazon Root CA 2
+ * Valid - https://good.sca2a.amazontrust.com/
+ * Revoked - https://revoked.sca2a.amazontrust.com/
+ * Amazon Root CA 3
+ * Valid - https://good.sca3a.amazontrust.com/
+ * Revoked - https://revoked.sca3a.amazontrust.com/
+ * Amazon Root CA 4
+ * Valid - https://good.sca4a.amazontrust.com/
+ * Revoked - https://revoked.sca4a.amazontrust.com/
+ */
+public class AmazonCA {
+
+ public static void main(String[] args) throws Exception {
+
+ ValidatePathWithParams pathValidator = new ValidatePathWithParams(null);
+ boolean ocspEnabled = false;
+
+ if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) {
+ pathValidator.enableCRLCheck();
+ } else {
+ // OCSP check by default
+ pathValidator.enableOCSPCheck();
+ ocspEnabled = true;
+ }
+
+ new AmazonCA_1().runTest(pathValidator, ocspEnabled);
+ new AmazonCA_2().runTest(pathValidator, ocspEnabled);
+ new AmazonCA_3().runTest(pathValidator, ocspEnabled);
+ new AmazonCA_4().runTest(pathValidator, ocspEnabled);
+ }
+}
+
+class AmazonCA_1 {
+
+ // Owner: CN=Amazon, OU=Server CA 1A, O=Amazon, C=US
+ // Issuer: CN=Amazon Root CA 1, O=Amazon, C=US
+ // Serial number: 67f9457508c648c09ca652e71791830e72592
+ // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025
+ private static final String INT = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIERzCCAy+gAwIBAgITBn+UV1CMZIwJymUucXkYMOclkjANBgkqhkiG9w0BAQsF\n" +
+ "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" +
+ "b24gUm9vdCBDQSAxMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjEL\n" +
+ "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENB\n" +
+ "IDFBMQ8wDQYDVQQDEwZBbWF6b24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n" +
+ "AoIBAQCeQM3XCsIZunv8bSJxOqkc/ed87uL76FDB7teBNThDRB+1J7aITuadbNfH\n" +
+ "5ZfZykrdZ1qQLKxP6DwHOmJr9u2b4IxjUX9qUMuq4B02ghD2g6yU3YivEosZ7fpo\n" +
+ "srD2TBN29JpgPGrOrpOE+ArZuIpBjdKFinemu6fTDD0NCeQlfyHXd1NOYyfYRLTa\n" +
+ "xlpDqr/2M41BgSkWQfSPHHyRWNQgWBiGsIQaS8TK0g8OWi1ov78+2K9DWT+AHgXW\n" +
+ "AanjZK91GfygPXJYSlAGxSiBAwH/KhAMifhaoFYAbH0Yuohmd85B45G2xVsop4TM\n" +
+ "Dsl007U7qnS7sdJ4jYGzEvva/a95AgMBAAGjggE5MIIBNTASBgNVHRMBAf8ECDAG\n" +
+ "AQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUYtRCXoZwdWqQvMa40k1g\n" +
+ "wjS6UTowHwYDVR0jBBgwFoAUhBjMhTTsvAyUlC4IWZzHshBOCggwewYIKwYBBQUH\n" +
+ "AQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5yb290Y2ExLmFtYXpvbnRy\n" +
+ "dXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NydC5yb290Y2ExLmFtYXpvbnRy\n" +
+ "dXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3Js\n" +
+ "LnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTEuY3JsMBEGA1UdIAQKMAgw\n" +
+ "BgYEVR0gADANBgkqhkiG9w0BAQsFAAOCAQEAMHbSWHRFMzGNIE0qhN6gnRahTrTU\n" +
+ "CDPwe7l9/q0IA+QBlrpUHnlAreetYeH1jB8uF3qXXzy22gpBU7NqulTkqSPByT1J\n" +
+ "xOhpT2FpO5R3VAdMPdWfSEgtrED0jkmyUQrR1T+/A+nBLdJZeQcl+OqLgeY790JM\n" +
+ "JJTsJnnI6FBWeTGhcDI4Y+n3KS3QCVePeWI7jx1dhrHcXH+QDX8Ywe31hV7YENdr\n" +
+ "HDpUXrjK6eHN8gazy8G6pndXHFwHp4auiZbJbYAk/q1peOTRagD2JojcLkm+i3cD\n" +
+ "843t4By6YT/PVlePU2PCWejkrJQnKQAPOov7IA8kuO2RDWuzE/zF6Hotdg==\n" +
+ "-----END CERTIFICATE-----";
+
+ // Owner: CN=good.sca1a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+ // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+ // OID.1.3.6.1.4.1.311.60.2.1.3=US
+ // Issuer: CN=Amazon, OU=Server CA 1A, O=Amazon, C=US
+ // Serial number: 703e4e4bbd78e2b6db5634f36c4ee944cb1a4
+ // Valid from: Mon Jul 29 16:53:36 PDT 2019 until: Sat Aug 29 16:53:36 PDT 2020
+ private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIFEzCCA/ugAwIBAgITBwPk5LvXjitttWNPNsTulEyxpDANBgkqhkiG9w0BAQsF\n" +
+ "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" +
+ "ZXIgQ0EgMUExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzUzMzZaFw0yMDA4\n" +
+ "MjkyMzUzMzZaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" +
+ "AQITCERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4G\n" +
+ "A1UEBRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x\n" +
+ "EDAOBgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNl\n" +
+ "czEjMCEGA1UEAxMaZ29vZC5zY2ExYS5hbWF6b250cnVzdC5jb20wggEiMA0GCSqG\n" +
+ "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQyuJ83c2Zf9k29f6iLqd8nJSuHSk1v+SS\n" +
+ "0sYyG8tjscfCC1HcOdNj37vtiNN65sXh/e/kBKH9wvzhCLOJbBqVKRHOZuHdJEpH\n" +
+ "35R6C/PbcV/tp49g6mNmBe+lcmm/cwwCtYvkL0rgL/OKB0liFhhRIqy2TPg08op/\n" +
+ "RlY2DdbgBA2B3g7wdMo0hK3SO56/QUccUtLRm43km9Yd4E3U+CEUyDd0Bmc/YbPa\n" +
+ "htuXVsXJwiwlwooomujIIENhFw3htdcsu2apRj8EYUrKL8Mvvn+h16gDyobj0f01\n" +
+ "jWXlUgmH2lzUzca5eGuphfvmWN/ME/yqC2mMvWGnWySycqtT8VdJAgMBAAGjggFj\n" +
+ "MIIBXzAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0OBBYEFFENOZBwFkjVdQX0iK32c77z\n" +
+ "SUl6MB8GA1UdIwQYMBaAFGLUQl6GcHVqkLzGuNJNYMI0ulE6MB0GA1UdJQQWMBQG\n" +
+ "CCsGAQUFBwMBBggrBgEFBQcDAjB1BggrBgEFBQcBAQRpMGcwLQYIKwYBBQUHMAGG\n" +
+ "IWh0dHA6Ly9vY3NwLnNjYTFhLmFtYXpvbnRydXN0LmNvbTA2BggrBgEFBQcwAoYq\n" +
+ "aHR0cDovL2NydC5zY2ExYS5hbWF6b250cnVzdC5jb20vc2NhMWEuY2VyMCUGA1Ud\n" +
+ "EQQeMByCGmdvb2Quc2NhMWEuYW1hem9udHJ1c3QuY29tMFAGA1UdIARJMEcwDQYL\n" +
+ "YIZIAYb9bgEHGAMwNgYFZ4EMAQEwLTArBggrBgEFBQcCARYfaHR0cHM6Ly93d3cu\n" +
+ "YW1hem9udHJ1c3QuY29tL2NwczANBgkqhkiG9w0BAQsFAAOCAQEAmn7z6Ub1sL77\n" +
+ "wyUEaCq/Odqm+2RtYYMJ1MeW6nTXTfAgZ/iLx/6hStafd9AK9gHiTCggBpj6KgnF\n" +
+ "UsGMDeX879jP675fH6SEk710QPDhIrfAzwE0pF/eUNsd7pLwne32zHX0ouCoAt4d\n" +
+ "KwBCZkKNUkdj4U+bpOJzvtcTP9JlzziLp9IFRjjQh3xKgfblx57CmRJbqH3fT5JJ\n" +
+ "IAIDVTz3ZUcqhPTFAnNsO1oNBEyrO5X9rwCiSy7aRijY/11R75mIIvyA9zyd9ss1\n" +
+ "kvrrER0GWMTDvC84FZD2vhkXgPTFrB1Dn9f3QgO5APT9GCFY5hdpqqPEXOSdRzQo\n" +
+ "h9j4OQAqtA==\n" +
+ "-----END CERTIFICATE-----";
+
+ // Owner: CN=revoked.sca1a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+ // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+ // OID.1.3.6.1.4.1.311.60.2.1.3=US
+ // Issuer: CN=Amazon, OU=Server CA 1A, O=Amazon, C=US
+ // Serial number: 6f1d774ad5e7b6d251d217661782bbdb6f37d
+ // Valid from: Mon Jan 28 15:34:38 PST 2019 until: Thu Apr 28 16:34:38 PDT 2022
+ private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIE2zCCA8OgAwIBAgITBvHXdK1ee20lHSF2YXgrvbbzfTANBgkqhkiG9w0BAQsF\n" +
+ "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" +
+ "ZXIgQ0EgMUExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzM0MzhaFw0yMjA0\n" +
+ "MjgyMzM0MzhaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" +
+ "AQITCERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYD\n" +
+ "VQQFEwc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ\n" +
+ "MA4GA1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2Vz\n" +
+ "MSYwJAYDVQQDEx1yZXZva2VkLnNjYTFhLmFtYXpvbnRydXN0LmNvbTCCASIwDQYJ\n" +
+ "KoZIhvcNAQEBBQADggEPADCCAQoCggEBANUoHop9sW+QlgVsdtacioraTAWHcSTd\n" +
+ "MNkOkOEMgJIFPyfdcDvW/H2NvpdYeIQqzaCgT2kcsONWTZTPJMirCPnzl1ohHOZU\n" +
+ "uTnOVkamGxvNmQCURLBXmlCMRTCI5RY3CuYntFFbSPAnbumsF+K/gKqcE6ME53Bw\n" +
+ "PAwn4qwavB0i5Ib7Jk8XYzxSYXC9l8QLxt6fshPJRlecpXzfmVFvMAm3IbaLcpuv\n" +
+ "AtD+8I2KwjNtBPRPNYeFsWxwsgUGAyHEGa61oTGUqqAXu5YmPfyK+YTOJdoofsh4\n" +
+ "Tf3K7AKxnPWuvY3RNTs1pzEVwJYZqSsNwbgyKJJ4+0Xe4iP7qB8SYf8CAwEAAaOC\n" +
+ "ASkwggElMA4GA1UdDwEB/wQEAwIFoDAdBgNVHQ4EFgQUGHreoz+LP/Wr+RKzuexO\n" +
+ "V8ICtmEwHwYDVR0jBBgwFoAUYtRCXoZwdWqQvMa40k1gwjS6UTowHQYDVR0lBBYw\n" +
+ "FAYIKwYBBQUHAwEGCCsGAQUFBwMCMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcw\n" +
+ "AYYhaHR0cDovL29jc3Auc2NhMWEuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAC\n" +
+ "hipodHRwOi8vY3J0LnNjYTFhLmFtYXpvbnRydXN0LmNvbS9zY2ExYS5jZXIwKAYD\n" +
+ "VR0RBCEwH4IdcmV2b2tlZC5zY2ExYS5hbWF6b250cnVzdC5jb20wEwYDVR0gBAww\n" +
+ "CjAIBgZngQwBAgEwDQYJKoZIhvcNAQELBQADggEBABSbe1UCLL7Qay6XK5wD8B5a\n" +
+ "wvR1XG3UrggpVIz/w5cutEm/yE71hzE0gag/3YPbNYEnaLbJH+9jz4YW9wd/cEPj\n" +
+ "xSK5PErAQjCd+aA4LKN1xqkSysgYknl0y47hJBXGnWf+hxvBBHeSoUzM0KIC21pC\n" +
+ "ZyXrmfaPCQAz13ruYIYdQaETqXGVORmKbf/a+Zn18/tfQt0LeeCYVoSopbXWQvcJ\n" +
+ "gUMtdIqYQmb8aVj0pdZXwKl4yZ2DtlS3Z9MpWNgQNlhRPmiYlu28y2yTtZ9SwD6m\n" +
+ "2f+cwc19aJrDT4Y280px+jRU7dIE6oZVJU+yBRVIZYpUFAB7extCMVxnTkCf8Dk=\n" +
+ "-----END CERTIFICATE-----";
+
+ public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception {
+ // EE certificates don't have CRLDP extension
+ if (!ocspEnabled){
+ pathValidator.validate(new String[]{INT},
+ ValidatePathWithParams.Status.GOOD, null, System.out);
+
+ return;
+ }
+
+ // 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,
+ "Mon Jan 28 15:35:56 PST 2019", System.out);
+ }
+}
+
+class AmazonCA_2 {
+
+ // Owner: CN=Amazon, OU=Server CA 2A, O=Amazon, C=US
+ // Issuer: CN=Amazon Root CA 2, O=Amazon, C=US
+ // Serial number: 67f945755f187a91f8163f3e624620177ff38
+ // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025
+ private static final String INT = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIGRzCCBC+gAwIBAgITBn+UV1Xxh6kfgWPz5iRiAXf/ODANBgkqhkiG9w0BAQwF\n" +
+ "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" +
+ "b24gUm9vdCBDQSAyMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjEL\n" +
+ "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENB\n" +
+ "IDJBMQ8wDQYDVQQDEwZBbWF6b24wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK\n" +
+ "AoICAQC0P8hSLewmrZ41CCPBQytZs5NBFMq5ztbnMf+kZUp9S25LPfjNW3zgC/6E\n" +
+ "qCTWNVMMHhq7ez9IQJk48qbfBTLlZkuKnUWbA9vowrDfcxUN0mRE4B/TJbveXyTf\n" +
+ "vE91iDlqDrERecE9D8sdjzURrtHTp27lZdRkXFvfEVCq4hl3sHkzjodisaQthLp1\n" +
+ "gLsiA7vKt+8zcL4Aeq52UyYb8r4/jdZ3KaQp8O/T4VwDCRKm8ey3kttpJWaflci7\n" +
+ "eRzNjY7gE3NMANVXCeQwOBfH2GjINFCObmPsqiBuoAnsv2k5aQLNoU1OZk08ClXm\n" +
+ "mEZ2rI5qZUTX1HuefBJnpMkPugFCw8afaHnB13SkLE7wxX8SZRdDIe5WiwyDL1tR\n" +
+ "2+8lpz4JsMoFopHmD3GaHyjbN+hkOqHgLltwewOsiyM0u3CZphypN2KeD+1FLjnY\n" +
+ "TgdIAd1FRgK2ZXDDrEdjnsSEfShKf0l4mFPSBs9E3U6sLmubDRXKLLLpa/dF4eKu\n" +
+ "LEKS1bXYT28iM6D5gSCnzho5G4d18jQD/slmc5XmRo5Pig0RyBwDaLuxeIZuiJ0A\n" +
+ "J6YFhffbrLYF5dEQl0cU+t3VBK5u/o1WkWXsZawU038lWn/AXerodT/pAcrtWA4E\n" +
+ "NQEN09WEKMhZVPhqdwhF/Gusr04mQtKt7T2v6UMQvtVglv5E7wIDAQABo4IBOTCC\n" +
+ "ATUwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYE\n" +
+ "FNpDStD8AcBLv1gnjHbNCoHzlC70MB8GA1UdIwQYMBaAFLAM8Eww9AVYAkj9M+VS\n" +
+ "r0uE42ZSMHsGCCsGAQUFBwEBBG8wbTAvBggrBgEFBQcwAYYjaHR0cDovL29jc3Au\n" +
+ "cm9vdGNhMi5hbWF6b250cnVzdC5jb20wOgYIKwYBBQUHMAKGLmh0dHA6Ly9jcnQu\n" +
+ "cm9vdGNhMi5hbWF6b250cnVzdC5jb20vcm9vdGNhMi5jZXIwPwYDVR0fBDgwNjA0\n" +
+ "oDKgMIYuaHR0cDovL2NybC5yb290Y2EyLmFtYXpvbnRydXN0LmNvbS9yb290Y2Ey\n" +
+ "LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggIBAEO5W+iF\n" +
+ "yChjDyyrmiwFupVWQ0Xy2ReFNQiZq7XKVHvsLQe01moSLnxcBxioOPBKt1KkZO7w\n" +
+ "Gcbmke0+7AxLaG/F5NPnzRtK1/pRhXQ0XdU8pVh/1/h4GoqRlZ/eN0JDarUhZPkV\n" +
+ "kSr96LUYDTxcsAidF7zkzWfmtcJg/Aw8mi14xKVEa6aVyKu54c8kKkdlt0WaigOv\n" +
+ "Z/xYhxp24AfoFKaIraDNdsD8q2N7eDYeN4WGLzNSlil+iFjzflI9mq1hTuI/ZNjV\n" +
+ "rbvob6FUQ8Cc524gMjbpZCNuZ1gfXzwwhGp0AnQF6CJsWF9uwPpZEVFnnnfiWH3M\n" +
+ "oup41EvBhqaAqOlny0sm5pI82nRUCAE3DLkJ1+eAtdQaYblZQkQrRyTuPmJEm+5y\n" +
+ "QwdDVw6uHc5OsSj/tyhh8zJ2Xq3zgh3dMONGjJEysxGaCoIb+61PWwMy2dIarVwI\n" +
+ "r+c+AY+3PrhgBspNdWZ87JzNHii7ksdjUSVGTTy1vGXgPYrv0lp0IMnKaZP58xiw\n" +
+ "rDx7uTlQuPVWNOZvCaT3ZcoxTsNKNscIUe+WJjWx5hdzpv/oksDPY5ltZ0j3hlDS\n" +
+ "D+Itk95/cNJVRM/0HpxI1SX9MTZtOSJoEDdUtOpVaOuBAvEK4gvTzdt0r5L+fuI6\n" +
+ "o5LAuRo/LO1xVRH49KFRoaznzU3Ch9+kbPb3\n" +
+ "-----END CERTIFICATE-----";
+
+ // Owner: CN=good.sca2a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+ // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+ // OID.1.3.6.1.4.1.311.60.2.1.3=US
+ // Issuer: CN=Amazon, OU=Server CA 2A, O=Amazon, C=US
+ // Serial number: 703e4e70616c90d611fd04a5ecc635665184e
+ // Valid from: Mon Jul 29 16:54:06 PDT 2019 until: Sat Aug 29 16:54:06 PDT 2020
+ private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIHEzCCBPugAwIBAgITBwPk5wYWyQ1hH9BKXsxjVmUYTjANBgkqhkiG9w0BAQwF\n" +
+ "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" +
+ "ZXIgQ0EgMkExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzU0MDZaFw0yMDA4\n" +
+ "MjkyMzU0MDZaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" +
+ "AQITCERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4G\n" +
+ "A1UEBRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x\n" +
+ "EDAOBgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNl\n" +
+ "czEjMCEGA1UEAxMaZ29vZC5zY2EyYS5hbWF6b250cnVzdC5jb20wggIiMA0GCSqG\n" +
+ "SIb3DQEBAQUAA4ICDwAwggIKAoICAQC+XjOB3ZCFX+b9y9reP+e6EAQz4ytiMSqU\n" +
+ "O4s5MyYLkY6n4BIZHmgWeQ2IgW1VrH8ho+Iu3UsTiuhd3/L/q/w+T0OJfcrWngTs\n" +
+ "uVcIuvUr32ObPeeWbg/m/lkN7hqH1jY62iybYVrFXiLo1+0G92PUazcyNvyA20+G\n" +
+ "HsvGG5jlArWNgRLdc8KUXxvnDUxx5vu4jeHEZnqSwuulV1h9ve0UutkmoK0Sk7Rz\n" +
+ "HMxYK0LmUT5OvcNQSkUi5nLi+M1FxnYYgsELwSiKSSEDfEdgxooMAiVTgw51Q/DB\n" +
+ "lTOjAIDL3K3J0yGfIG3bwLvE1qz2Z5yWn8f3JibIah7LrC4PiZDDLHFM6V9l+YqU\n" +
+ "RqimJ5BltSyAx7bxQNZ1AW3Lxvvm894i4k6/Vdf1CDovRuTMPCDAQmKA/A/AQ7TN\n" +
+ "q3bBimX6UyuJu0I8RyvAYKzFhOOqe4vXrbndTbje/jnzTNQPeIIcuRa9cgXTOrbw\n" +
+ "86FTUKj6AZXihRWjKWsQpDwdgE0tQETZ3ynCXfbBKfFmn0MSjeX0CEEAZdYHR8EV\n" +
+ "F271Yt7UJjS/FP702aHTOWk7zFbIRfFQODvBhn0I8p/Stk2sDq4/YsbXVZOe3+ad\n" +
+ "YavoiODGSAH6ZcZzULumgK9eii0koAOPB/xqXnkcTS63gEHOKjLQl3hqdVZRCugv\n" +
+ "1CwUXLvoSwIDAQABo4IBYzCCAV8wDgYDVR0PAQH/BAQDAgWgMB0GA1UdDgQWBBTa\n" +
+ "j6dHgPdOxTGLcwaNDeaMnlSxNjAfBgNVHSMEGDAWgBTaQ0rQ/AHAS79YJ4x2zQqB\n" +
+ "85Qu9DAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYIKwYBBQUHAQEE\n" +
+ "aTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5zY2EyYS5hbWF6b250cnVzdC5j\n" +
+ "b20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuc2NhMmEuYW1hem9udHJ1c3QuY29t\n" +
+ "L3NjYTJhLmNlcjAlBgNVHREEHjAcghpnb29kLnNjYTJhLmFtYXpvbnRydXN0LmNv\n" +
+ "bTBQBgNVHSAESTBHMA0GC2CGSAGG/W4BBxgDMDYGBWeBDAEBMC0wKwYIKwYBBQUH\n" +
+ "AgEWH2h0dHBzOi8vd3d3LmFtYXpvbnRydXN0LmNvbS9jcHMwDQYJKoZIhvcNAQEM\n" +
+ "BQADggIBAE6RwZAZvN0i9ygwzqoX9DhSPtvZ3xIO0G0Bhgjkb986+p8XJstU3gEM\n" +
+ "8P2i1J/YthXCnRGedm+Odxx+31G6xIYfP5S5g7HyRGkj/aXNXy4s3KjH8HJgOY9N\n" +
+ "ra3XfC05OKq5FpyZQDZ+hxCdLrH3Gs+UxREbu+LuIKUpI7nMVEjn9XynKyOdKN21\n" +
+ "Kq5VsuI0fDWCYvUN1M+lI/LgE5HbNJVQJs+dB7g1/kaOeaLia7Wk1ys+uRzB58rp\n" +
+ "FKAoLk++HWTfNDkbN8vKRfHhJ/xhI9ju3TWcci6EyFVAym1C62UkJNI0KHgQ+zc7\n" +
+ "nl1tv/ytj8N/eJoysyp23lJ5qrVetlQORfgXryGkWBMYBvYF8zbBb/f+UXHDKVWt\n" +
+ "9l1lL6HQGY/tTo253pj6/FgDD35bZdjLQeUVmbnz679S5oUmoH5ZtSdnpUTghU3p\n" +
+ "bae9adBFY9S1pm50Q3ckRVBAwNqNmI0KKUh14Ms8KSAUHg19NvGsBonqwOT2rdbv\n" +
+ "xZ47N6c2eCl/cjMvzre0v0NoUO+3og2GHeAoOwVos6480YDbMqp739tOFPxBcsII\n" +
+ "6SjpDVh+14dkSW6kEKeaCFLR+eChqutri1VQbQ49nmADQWw9Al8vBytSnPv0YN6W\n" +
+ "XfIE1Qj7YmHu/UuoeKVsqDqoP/no29+96dtfd4afJqlIoyZUqXpt\n" +
+ "-----END CERTIFICATE-----";
+
+ // Owner: CN=revoked.sca2a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+ // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+ // OID.1.3.6.1.4.1.311.60.2.1.3=US
+ //Issuer: CN=Amazon, OU=Server CA 2A, O=Amazon, C=US
+ //Serial number: 6f1d782c0aa2f4866b7b522c279b939b92369
+ //Valid from: Mon Jan 28 15:37:45 PST 2019 until: Thu Apr 28 16:37:45 PDT 2022
+ private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIG2zCCBMOgAwIBAgITBvHXgsCqL0hmt7Uiwnm5ObkjaTANBgkqhkiG9w0BAQwF\n" +
+ "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" +
+ "ZXIgQ0EgMkExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzM3NDVaFw0yMjA0\n" +
+ "MjgyMzM3NDVaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" +
+ "AQITCERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYD\n" +
+ "VQQFEwc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ\n" +
+ "MA4GA1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2Vz\n" +
+ "MSYwJAYDVQQDEx1yZXZva2VkLnNjYTJhLmFtYXpvbnRydXN0LmNvbTCCAiIwDQYJ\n" +
+ "KoZIhvcNAQEBBQADggIPADCCAgoCggIBAKFm418X8hN1YTgD2XpMb4sp78mw8k3j\n" +
+ "Dq/vnpX48evVUzNpHpy4qRz/ZHBR4HUJO4lhfnX+CO0uRqqqx4F0JZRQB3KevaU8\n" +
+ "QGWHdJGhEddnurDhrgOUa+ZroqUnMCsTJfbyGtC6aiEXeu/eMhEUFkuBxJH1JtwD\n" +
+ "dQXMXuMjG07SVjOkhTkbMDzA/YbUqkDeOIybifDuvA5LEsl+kReY0b6RYFo2Tt/M\n" +
+ "dPhJD8q3Wsu+XCiCnbpcwlEVGxiD2RVRXJJ9o3ALGOxqU69V+lYS0kkwNHT7oV9J\n" +
+ "rhgt7iOCq0aoTAxu2j4FCp0JHNhGoW9pXoMXnmS6kK80hzLNYDxvKEaVaKkiYHw5\n" +
+ "CV0Vwii05ICa14nrStH/jcRNLyU+gp+6OeerPV3jpKWshGKWewF+2UiWU2WHTSrd\n" +
+ "Wis0/qEfFK/kSraAxpd+KavEEavKeudoMAHIxMACOk9E/fF5zhd2y4G1q1BdoRlR\n" +
+ "KP4GIV2v6qH6Ru2mNSuge9il6kDXxFNucrYKLDbAqkqalohkvDavcPoG9gZT3etv\n" +
+ "4IcgJriIWRxbJwKPpwJM+6wa6RpwoeJMuEp3ZBP7KDaQ8YX4rlf4zXLAsOKCNA9K\n" +
+ "OS/qYQ/I4g0E1WhfgEKClaLPS2u7jeVR6s1t4txGo4vq5Dkt17KTCew/WsX3rckf\n" +
+ "a2p5zvFcfpCNAgMBAAGjggEpMIIBJTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0OBBYE\n" +
+ "FAF8N1wV8EoYFkMXH6tEnmR/7vI+MB8GA1UdIwQYMBaAFNpDStD8AcBLv1gnjHbN\n" +
+ "CoHzlC70MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BggrBgEFBQcB\n" +
+ "AQRpMGcwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLnNjYTJhLmFtYXpvbnRydXN0\n" +
+ "LmNvbTA2BggrBgEFBQcwAoYqaHR0cDovL2NydC5zY2EyYS5hbWF6b250cnVzdC5j\n" +
+ "b20vc2NhMmEuY2VyMCgGA1UdEQQhMB+CHXJldm9rZWQuc2NhMmEuYW1hem9udHJ1\n" +
+ "c3QuY29tMBMGA1UdIAQMMAowCAYGZ4EMAQIBMA0GCSqGSIb3DQEBDAUAA4ICAQBC\n" +
+ "VwR1NFk1IYIF4cjU7ML1aj8OIn+8mtakGQnuSJLK6ypSysINJBS48ZDdP6XZXvyD\n" +
+ "iTS0xEAPjAZHTqrABdNYmvJeL2RnN99DIwVzBpZp4NLTXbiSW7jb0Y5cEPDGJMOo\n" +
+ "SUAAM6fsiPRfz5vX4XVPznbcF2AwE/NVV+L3n9LVRt7qv2VqIEvLioR56Dq+5ofR\n" +
+ "4bw0BVlEYWF4Gsy7WDDTL1iLNBUwZTqBHwTv0fgDRiPqb/odmLQuRANwcJy8B8Zr\n" +
+ "s/yX4SeESaRdA82lAlQilksQitXS2qvQN06GEDOgUxYE6EabFdgklV5JypKqdOly\n" +
+ "vzpaDpF3z5W8Bj3D4fns1Kjrh1pPh5JRvg+616diKnQRt4X5q+EtmnXhDvIGMISI\n" +
+ "FuGwj57CNQ2x2MY2HHKWPrOccpQfEEvoSNR+ntYWrtSSttZq948O+zZBk1TXWuXV\n" +
+ "TVXllqTg8lp6d5cfKgvtHKgt98WkpPOcLVrNuVnMAIfDw6ar54dVKqrvkeEcF6mJ\n" +
+ "7oMKjJX/Vu9lYoGViBIfdeqcCPWSI8BpnCKaG7dTQO3Q1ObGmLdGBRlsRh+d+S5l\n" +
+ "Fq326ckbjx537e5/ai31lOR7OwVh9TDweKLqIACjs987C0EJSEfoOue25WRww2va\n" +
+ "iX9SrTPm4GxQ2OJgYwx0+HbezJXFN+dhaOFUavTSFw==\n" +
+ "-----END CERTIFICATE-----";
+
+ public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception {
+ // EE certificates don't have CRLDP extension
+ if (!ocspEnabled){
+ pathValidator.validate(new String[]{INT},
+ ValidatePathWithParams.Status.GOOD, null, System.out);
+
+ return;
+ }
+
+ // 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,
+ "Mon Jan 28 15:38:57 PST 2019", System.out);
+ }
+}
+
+class AmazonCA_3 {
+
+ // Owner: CN=Amazon, OU=Server CA 3A, O=Amazon, C=US
+ // Issuer: CN=Amazon Root CA 3, O=Amazon, C=US
+ // Serial number: 67f945758fe55b9ee3f75831d47f07d226c8a
+ // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025
+ private static final String INT = "-----BEGIN CERTIFICATE-----\n" +
+ "MIICuzCCAmGgAwIBAgITBn+UV1j+VbnuP3WDHUfwfSJsijAKBggqhkjOPQQDAjA5\n" +
+ "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n" +
+ "Um9vdCBDQSAzMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjELMAkG\n" +
+ "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENBIDNB\n" +
+ "MQ8wDQYDVQQDEwZBbWF6b24wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATYcYsK\n" +
+ "mYdR0Gj8Xz45E/lfcTTnXhg2EtAIYBIHyXv/ZQyyyCas1aptX/I5T1coT6XK181g\n" +
+ "nB8hADuKfWlNoIYRo4IBOTCCATUwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8B\n" +
+ "Af8EBAMCAYYwHQYDVR0OBBYEFATc4JXl6LlrlKHvjFsxHhN+VZfaMB8GA1UdIwQY\n" +
+ "MBaAFKu229cGnjesMIYHkXDHnMQZsXjAMHsGCCsGAQUFBwEBBG8wbTAvBggrBgEF\n" +
+ "BQcwAYYjaHR0cDovL29jc3Aucm9vdGNhMy5hbWF6b250cnVzdC5jb20wOgYIKwYB\n" +
+ "BQUHMAKGLmh0dHA6Ly9jcnQucm9vdGNhMy5hbWF6b250cnVzdC5jb20vcm9vdGNh\n" +
+ "My5jZXIwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC5yb290Y2EzLmFtYXpv\n" +
+ "bnRydXN0LmNvbS9yb290Y2EzLmNybDARBgNVHSAECjAIMAYGBFUdIAAwCgYIKoZI\n" +
+ "zj0EAwIDSAAwRQIgOl/vux0qfxNm05W3eofa9lKwz6oKvdu6g6Sc0UlwgRcCIQCS\n" +
+ "WSQ6F6JHLoeOWLyFFF658eNKEKbkEGMHz34gLX/N3g==\n" +
+ "-----END CERTIFICATE-----";
+
+ // Owner: CN=good.sca3a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+ // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+ // OID.1.3.6.1.4.1.311.60.2.1.3=US
+ // Issuer: CN=Amazon, OU=Server CA 3A, O=Amazon, C=US
+ // Serial number: 703e4e9bbc2605f37967a0e95f31f4789a677
+ // Valid from: Mon Jul 29 16:54:43 PDT 2019 until: Sat Aug 29 16:54:43 PDT 2020
+ private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIDhzCCAy2gAwIBAgITBwPk6bvCYF83lnoOlfMfR4mmdzAKBggqhkjOPQQDAjBG\n" +
+ "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" +
+ "Q0EgM0ExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzU0NDNaFw0yMDA4Mjky\n" +
+ "MzU0NDNaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" +
+ "CERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4GA1UE\n" +
+ "BRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO\n" +
+ "BgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNlczEj\n" +
+ "MCEGA1UEAxMaZ29vZC5zY2EzYS5hbWF6b250cnVzdC5jb20wWTATBgcqhkjOPQIB\n" +
+ "BggqhkjOPQMBBwNCAARl4yxf8XcvWR0LZ+YuBC0CpkwtU2NiMdlIM7eX0lxhQp53\n" +
+ "NpLlCrPRNzOWrjCJDdn21D0u7PrtN94UHLHOg9X0o4IBYzCCAV8wDgYDVR0PAQH/\n" +
+ "BAQDAgeAMB0GA1UdDgQWBBT2cHmOJFLWfg1Op7xAdAnqYcwaPzAfBgNVHSMEGDAW\n" +
+ "gBQE3OCV5ei5a5Sh74xbMR4TflWX2jAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB\n" +
+ "BQUHAwIwdQYIKwYBBQUHAQEEaTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5z\n" +
+ "Y2EzYS5hbWF6b250cnVzdC5jb20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuc2Nh\n" +
+ "M2EuYW1hem9udHJ1c3QuY29tL3NjYTNhLmNlcjAlBgNVHREEHjAcghpnb29kLnNj\n" +
+ "YTNhLmFtYXpvbnRydXN0LmNvbTBQBgNVHSAESTBHMA0GC2CGSAGG/W4BBxgDMDYG\n" +
+ "BWeBDAEBMC0wKwYIKwYBBQUHAgEWH2h0dHBzOi8vd3d3LmFtYXpvbnRydXN0LmNv\n" +
+ "bS9jcHMwCgYIKoZIzj0EAwIDSAAwRQIgURdcqJVr4PWNIkmWcSKmzgZ1i94hQpGe\n" +
+ "mWbE9osk4m0CIQDhxIguihwvDa5RsBwdM0aRDgGKLNHigGqJoKqgH0d2qg==\n" +
+ "-----END CERTIFICATE-----";
+
+ // Owner: CN=revoked.sca3a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+ // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+ // OID.1.3.6.1.4.1.311.60.2.1.3=US
+ // Issuer: CN=Amazon, OU=Server CA 3A, O=Amazon, C=US
+ // Serial number: 6f1d78cf0ca64ce7f551a6f2a0715cc0e8b50
+ // Valid from: Mon Jan 28 15:40:01 PST 2019 until: Thu Apr 28 16:40:01 PDT 2022
+ private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIDTzCCAvWgAwIBAgITBvHXjPDKZM5/VRpvKgcVzA6LUDAKBggqhkjOPQQDAjBG\n" +
+ "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" +
+ "Q0EgM0ExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzQwMDFaFw0yMjA0Mjgy\n" +
+ "MzQwMDFaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" +
+ "CERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYDVQQF\n" +
+ "Ewc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G\n" +
+ "A1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2VzMSYw\n" +
+ "JAYDVQQDEx1yZXZva2VkLnNjYTNhLmFtYXpvbnRydXN0LmNvbTBZMBMGByqGSM49\n" +
+ "AgEGCCqGSM49AwEHA0IABJNl90Jq0wddpFj+JbLtmvGR/1geL5t1tvV406jGpYn2\n" +
+ "C5lAFjwASFy7pAnazZbfSkIDUU2i2XU0+7Cs+j1S/EOjggEpMIIBJTAOBgNVHQ8B\n" +
+ "Af8EBAMCB4AwHQYDVR0OBBYEFPhX3dYays5Sps0xTgouLkZzYLg4MB8GA1UdIwQY\n" +
+ "MBaAFATc4JXl6LlrlKHvjFsxHhN+VZfaMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr\n" +
+ "BgEFBQcDAjB1BggrBgEFBQcBAQRpMGcwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3Nw\n" +
+ "LnNjYTNhLmFtYXpvbnRydXN0LmNvbTA2BggrBgEFBQcwAoYqaHR0cDovL2NydC5z\n" +
+ "Y2EzYS5hbWF6b250cnVzdC5jb20vc2NhM2EuY2VyMCgGA1UdEQQhMB+CHXJldm9r\n" +
+ "ZWQuc2NhM2EuYW1hem9udHJ1c3QuY29tMBMGA1UdIAQMMAowCAYGZ4EMAQIBMAoG\n" +
+ "CCqGSM49BAMCA0gAMEUCICLb16/50S4fOAFafi5lagdx7q6EDPPm596g19eQDMXk\n" +
+ "AiEAksCMLypRB4t30FABlsEjhVCBIxay0iIer2OcCIrhfEI=\n" +
+ "-----END CERTIFICATE-----";
+
+ public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception {
+ // EE certificates don't have CRLDP extension
+ if (!ocspEnabled){
+ pathValidator.validate(new String[]{INT},
+ ValidatePathWithParams.Status.GOOD, null, System.out);
+
+ return;
+ }
+
+ // 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,
+ "Mon Jan 28 15:40:35 PST 2019", System.out);
+ }
+}
+
+class AmazonCA_4 {
+
+ // Owner: CN=Amazon, OU=Server CA 4A, O=Amazon, C=US
+ // Issuer: CN=Amazon Root CA 4, O=Amazon, C=US
+ // Serial number: 67f94575a8862a9072e3239c37ceba1274e18
+ // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025
+ private static final String INT = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIC+TCCAn6gAwIBAgITBn+UV1qIYqkHLjI5w3zroSdOGDAKBggqhkjOPQQDAzA5\n" +
+ "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n" +
+ "Um9vdCBDQSA0MB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjELMAkG\n" +
+ "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENBIDRB\n" +
+ "MQ8wDQYDVQQDEwZBbWF6b24wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASRP0kIW0Ha\n" +
+ "7+ORvEVhIS5gIgkH66X5W9vBRTX14oG/1elIyI6LbFZ+E5KAufL0XoWJGI1WbPRm\n" +
+ "HW246FKSzF0wOEZZyxEROz6tuaVsnXRHRE76roS/Wr064uJpKH+Lv+SjggE5MIIB\n" +
+ "NTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU\n" +
+ "pSHN2+tTIZmqytlnQpQlsnv0wuMwHwYDVR0jBBgwFoAU0+zHOmVuzOHadppW+5zz\n" +
+ "hm1X5YEwewYIKwYBBQUHAQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5y\n" +
+ "b290Y2E0LmFtYXpvbnRydXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NydC5y\n" +
+ "b290Y2E0LmFtYXpvbnRydXN0LmNvbS9yb290Y2E0LmNlcjA/BgNVHR8EODA2MDSg\n" +
+ "MqAwhi5odHRwOi8vY3JsLnJvb3RjYTQuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTQu\n" +
+ "Y3JsMBEGA1UdIAQKMAgwBgYEVR0gADAKBggqhkjOPQQDAwNpADBmAjEA59RAOBaj\n" +
+ "uh0rT/OOTWPEv6TBnb9XEadburBaXb8SSrR8il+NdkfS9WXRAzbwrG7LAjEA3ukD\n" +
+ "1HrQq+WXHBM5sIuViJI/Zh7MOjsc159Q+dn36PBqLRq03AXqE/lRjnv8C5nj\n" +
+ "-----END CERTIFICATE-----";
+
+ // Owner: CN=good.sca4a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+ // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+ // OID.1.3.6.1.4.1.311.60.2.1.3=US
+ // Issuer: CN=Amazon, OU=Server CA 4A, O=Amazon, C=US
+ // Serial number: 703e4ec57c72d5669efbc98875c3f6bc3f934
+ // Valid from: Mon Jul 29 16:55:17 PDT 2019 until: Sat Aug 29 16:55:17 PDT 2020
+ private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIDxTCCA0qgAwIBAgITBwPk7FfHLVZp77yYh1w/a8P5NDAKBggqhkjOPQQDAzBG\n" +
+ "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" +
+ "Q0EgNEExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzU1MTdaFw0yMDA4Mjky\n" +
+ "MzU1MTdaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" +
+ "CERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4GA1UE\n" +
+ "BRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO\n" +
+ "BgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNlczEj\n" +
+ "MCEGA1UEAxMaZ29vZC5zY2E0YS5hbWF6b250cnVzdC5jb20wdjAQBgcqhkjOPQIB\n" +
+ "BgUrgQQAIgNiAAS9fqMYfOBsdXMSsPjqOlTgIGOlOQWA7Wg6XwVvHTr0+UN+XTeC\n" +
+ "yZN+XjLbEDQ0CF5eryRZ535sDpwh3qNe0lYFO1n1+2iDtDI1jhhLNYNxBpVnR2BU\n" +
+ "2l9EuRmgRbQpDCajggFjMIIBXzAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFMd0\n" +
+ "itH5IcE6DpM1uTSBV/6DLmK7MB8GA1UdIwQYMBaAFKUhzdvrUyGZqsrZZ0KUJbJ7\n" +
+ "9MLjMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BggrBgEFBQcBAQRp\n" +
+ "MGcwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLnNjYTRhLmFtYXpvbnRydXN0LmNv\n" +
+ "bTA2BggrBgEFBQcwAoYqaHR0cDovL2NydC5zY2E0YS5hbWF6b250cnVzdC5jb20v\n" +
+ "c2NhNGEuY2VyMCUGA1UdEQQeMByCGmdvb2Quc2NhNGEuYW1hem9udHJ1c3QuY29t\n" +
+ "MFAGA1UdIARJMEcwDQYLYIZIAYb9bgEHGAMwNgYFZ4EMAQEwLTArBggrBgEFBQcC\n" +
+ "ARYfaHR0cHM6Ly93d3cuYW1hem9udHJ1c3QuY29tL2NwczAKBggqhkjOPQQDAwNp\n" +
+ "ADBmAjEA2RBD1F+rnm394VkqA3ncysM3deoyfWqaoAO5923MNisswPnHfVqnfeXf\n" +
+ "ZwTAvVTBAjEAiiaPx9GRjEk8IBKvCSbTp9rPogVTN7zDDQGrwA83O0pRP7A0dxtT\n" +
+ "pn/0K5Sj8otp\n" +
+ "-----END CERTIFICATE-----";
+
+ // Owner: CN=revoked.sca4a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \
+ // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \
+ // OID.1.3.6.1.4.1.311.60.2.1.3=US
+ // Issuer: CN=Amazon, OU=Server CA 4A, O=Amazon, C=US
+ // Serial number: 6f1d79295c384a699d51c2d756bd46213b5b3
+ // Valid from: Mon Jan 28 15:41:16 PST 2019 until: Thu Apr 28 16:41:16 PDT 2022
+ private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIDjTCCAxKgAwIBAgITBvHXkpXDhKaZ1RwtdWvUYhO1szAKBggqhkjOPQQDAzBG\n" +
+ "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" +
+ "Q0EgNEExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzQxMTZaFw0yMjA0Mjgy\n" +
+ "MzQxMTZaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" +
+ "CERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYDVQQF\n" +
+ "Ewc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G\n" +
+ "A1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2VzMSYw\n" +
+ "JAYDVQQDEx1yZXZva2VkLnNjYTRhLmFtYXpvbnRydXN0LmNvbTB2MBAGByqGSM49\n" +
+ "AgEGBSuBBAAiA2IABLuNpZTcNU3FElNP3Y/OeXIZcIMXkFTBi/n92fNwHfqUbEhH\n" +
+ "H+PovJ26eAGvb5a8bGc275MBFcVnWL0rCVgM+j9KAtBDCRJX3f7mo0D2VKcmtZKu\n" +
+ "jPxwGPy2kuqM505dGqOCASkwggElMA4GA1UdDwEB/wQEAwIHgDAdBgNVHQ4EFgQU\n" +
+ "zUFIhn+hphzCKA2qgAdLztSBzJgwHwYDVR0jBBgwFoAUpSHN2+tTIZmqytlnQpQl\n" +
+ "snv0wuMwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHUGCCsGAQUFBwEB\n" +
+ "BGkwZzAtBggrBgEFBQcwAYYhaHR0cDovL29jc3Auc2NhNGEuYW1hem9udHJ1c3Qu\n" +
+ "Y29tMDYGCCsGAQUFBzAChipodHRwOi8vY3J0LnNjYTRhLmFtYXpvbnRydXN0LmNv\n" +
+ "bS9zY2E0YS5jZXIwKAYDVR0RBCEwH4IdcmV2b2tlZC5zY2E0YS5hbWF6b250cnVz\n" +
+ "dC5jb20wEwYDVR0gBAwwCjAIBgZngQwBAgEwCgYIKoZIzj0EAwMDaQAwZgIxALDA\n" +
+ "klY3iKwyzwpwVtLfLxzQEl45xvE2VjBJvfJJ60KhJt7Ud0gt0zxkogh29+mpEQIx\n" +
+ "ANTG1mk8OJB41DU7ru1Pwc6ju8STw1FdwDp/Eliqhvnm2i0k4/F1bBHLta2mlC2V\n" +
+ "hg==\n" +
+ "-----END CERTIFICATE-----";
+
+ public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception {
+ // EE certificates don't have CRLDP extension
+ if (!ocspEnabled){
+ pathValidator.validate(new String[]{INT},
+ ValidatePathWithParams.Status.GOOD, null, System.out);
+
+ return;
+ }
+
+ // 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,
+ "Mon Jan 28 15:41:53 PST 2019", System.out);
+ }
+}
diff --git a/jdk/test/security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java b/jdk/test/security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java
new file mode 100644
index 0000000..63ba5e1
--- /dev/null
+++ b/jdk/test/security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2019, 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 8232019
+ * @summary Interoperability tests with LuxTrust Global Root 2 CA
+ * @build ValidatePathWithParams
+ * @run main/othervm -Djava.security.debug=certpath LuxTrustCA OCSP
+ * @run main/othervm -Djava.security.debug=certpath LuxTrustCA CRL
+ */
+
+/*
+ * Obtain TLS test artifacts for LuxTrust CAs from:
+ *
+ * LuxTrust Global Root 2 CA sent test certificates as attachment
+ */
+public class LuxTrustCA {
+
+ // Owner: CN=LuxTrust Global Qualified CA 3, O=LuxTrust S.A., C=LU
+ // Issuer: CN=LuxTrust Global Root 2, O=LuxTrust S.A., C=LU
+ // Serial number: 413dea1a28c2253845558e047f3e2a8b5b9baeae
+ // Valid from: Fri Mar 06 06:12:15 PST 2015 until: Mon Mar 05 05:21:57 PST 2035
+ private static final String INT = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIGcjCCBFqgAwIBAgIUQT3qGijCJThFVY4Efz4qi1ubrq4wDQYJKoZIhvcNAQEL\n" +
+ "BQAwRjELMAkGA1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNV\n" +
+ "BAMMFkx1eFRydXN0IEdsb2JhbCBSb290IDIwHhcNMTUwMzA2MTQxMjE1WhcNMzUw\n" +
+ "MzA1MTMyMTU3WjBOMQswCQYDVQQGEwJMVTEWMBQGA1UECgwNTHV4VHJ1c3QgUy5B\n" +
+ "LjEnMCUGA1UEAwweTHV4VHJ1c3QgR2xvYmFsIFF1YWxpZmllZCBDQSAzMIICIjAN\n" +
+ "BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuZ5iXSmFbP80gWb0kieYsImcyIo3\n" +
+ "QYg+XA3NlwH6QtI0PgZEG9dSo8pM7VMIzE5zq8tgJ50HnPdYflvfhkEKvAW2NuNX\n" +
+ "6hi/6HK4Nye+kB+INjpfAHmLft3GT95e+frk/t7hJNorK44xzqfWZKLNGysEHIri\n" +
+ "ddcePWOk3J/VMc9CsSemeZbmeZW1/xXeqolMS7JIDZ3+0DgVCYsKIK+b3sAQ8iqX\n" +
+ "bQlQyvymG6QyoQoJbuEP23iawRMWKNWk+sjzOkPAAQDtgEEVdggzzudLSM04C5Cj\n" +
+ "eLlLYuXgljler9bKRk9wW8nkareLZsn9uCDihGXGyC5m9jseGY1KAnlV8usLjBFA\n" +
+ "iW5OCnzcOg+CPsVucoRhS6uvXcu7VtHRGo5yLysJVv7sj6cx5lMvQKAMLviVi3kp\n" +
+ "hZKYfqVLAVFJpXTpunY2GayVGf/uOpzNoiSRpcxxYjmAlPKNeTgXVl5Mc0zojgT/\n" +
+ "MZTGFN7ov7n01yodN6OhfTADacvaKfj2C2CwdCJvMqvlUuCKrvuXbdZrtRm3BZXr\n" +
+ "ghGhuQmG0Tir7VVCI0WZjVjyHs2rpUcCQ6+D1WymKhzp0mrXdaFzYRce7FrEk69J\n" +
+ "WzWVp/9/GKnnb0//camavEaI4V64MVxYAir5AL/j7d4JIOqhPPU14ajxmC6dEH84\n" +
+ "guVs0Lo/dwVTUzsCAwEAAaOCAU4wggFKMBIGA1UdEwEB/wQIMAYBAf8CAQAwQwYD\n" +
+ "VR0gBDwwOjA4BggrgSsBAQEKAzAsMCoGCCsGAQUFBwIBFh5odHRwczovL3JlcG9z\n" +
+ "aXRvcnkubHV4dHJ1c3QubHUwagYIKwYBBQUHAQEEXjBcMCsGCCsGAQUFBzABhh9o\n" +
+ "dHRwOi8vbHRncm9vdC5vY3NwLmx1eHRydXN0Lmx1MC0GCCsGAQUFBzAChiFodHRw\n" +
+ "Oi8vY2EubHV4dHJ1c3QubHUvTFRHUkNBMi5jcnQwDgYDVR0PAQH/BAQDAgEGMB8G\n" +
+ "A1UdIwQYMBaAFP8YKHb5SAUsoa7xKxsrslP4S3yzMDMGA1UdHwQsMCowKKAmoCSG\n" +
+ "Imh0dHA6Ly9jcmwubHV4dHJ1c3QubHUvTFRHUkNBMi5jcmwwHQYDVR0OBBYEFGOP\n" +
+ "wosDsauO2FNHlh2ZqH32rKh1MA0GCSqGSIb3DQEBCwUAA4ICAQADB6M/edbOO9iJ\n" +
+ "COnVxayJ1NBk08/BVKlHwe7HBYAzT6Kmo3TbMUwOpcGI2e/NBCR3F4wTzXOVvFmv\n" +
+ "dBl7sdS6uMSLBTrav+5LChcFDBQj26X5VQDcXkA8b/u6J4Ve7CwoSesYg9H0fsJ3\n" +
+ "v12QrmGUUao9gbamKP1TFriO+XiIaDLYectruusRktIke9qy8MCpNSarZqr3oD3c\n" +
+ "/+N5D3lDlGpaz1IL8TpbubFEQHPCr6JiwR+qSqGRfxv8vIvOOAVxe7np5QhtwmCk\n" +
+ "XdMOPQ/XOOuEA06bez+zHkASX64at7dXru+4JUEbpijjMA+1jbFZr20OeBIQZL7o\n" +
+ "Est+FF8lFuvmucC9TS9QnlF28WJExvpIknjS7LhFMGXB9w380q38ZOuKjPZpoztY\n" +
+ "eyUpf8gxzV7fE5Q1okhnsDZ+12vBzBruzJcwtNuXyLyIh3fVN0LunVd+NP2kGjB2\n" +
+ "t9WD2Y0CaKxWx8snDdrSbAi46TpNoe04eroWgZOvdN0hEmf2d8tYBSJ/XZekU9sC\n" +
+ "Aww5vxHnXJi6CZHhjt8f1mMhyE2gBvmpk4CFetViO2sG0n/nsxCQNpnclsax/eJu\n" +
+ "XmGiZ3OPCIRijI5gy3pLRgnbgLyktWoOkmT/gxtWDLfVZwEt52JL8d550KIgttyR\n" +
+ "qX81LJWGSDdpnzeRVQEnzAt6+RebAQ==\n" +
+ "-----END CERTIFICATE-----";
+
+ // Owner: T=Private Person, SERIALNUMBER=00100978855105608536,
+ // GIVENNAME=TokenPRIActive, SURNAME=Test, CN=TokenPRIActive Test, C=DE
+ // Issuer: CN=LuxTrust Global Qualified CA 3, O=LuxTrust S.A., C=LU
+ // Serial number: 3814b6
+ // Valid from: Wed Jul 10 04:36:12 PDT 2019 until: Sun Jul 10 04:36:12 PDT 2022
+ private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIG/jCCBOagAwIBAgIDOBS2MA0GCSqGSIb3DQEBCwUAME4xCzAJBgNVBAYTAkxV\n" +
+ "MRYwFAYDVQQKDA1MdXhUcnVzdCBTLkEuMScwJQYDVQQDDB5MdXhUcnVzdCBHbG9i\n" +
+ "YWwgUXVhbGlmaWVkIENBIDMwHhcNMTkwNzEwMTEzNjEyWhcNMjIwNzEwMTEzNjEy\n" +
+ "WjCBizELMAkGA1UEBhMCREUxHDAaBgNVBAMTE1Rva2VuUFJJQWN0aXZlIFRlc3Qx\n" +
+ "DTALBgNVBAQTBFRlc3QxFzAVBgNVBCoTDlRva2VuUFJJQWN0aXZlMR0wGwYDVQQF\n" +
+ "ExQwMDEwMDk3ODg1NTEwNTYwODUzNjEXMBUGA1UEDBMOUHJpdmF0ZSBQZXJzb24w\n" +
+ "ggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDb8l2RJNS7iA9hJFj8aR25\n" +
+ "kpU/ZQTHl8Z9yrTLhr4VcMWMxqeOQUcUU27SgIuFvU9s/68OuaIhxyu6eohaGCLC\n" +
+ "wzFFRg8OlsUYuI1QtUEliIjmHOMDqSNIt093+SDV64osnHw5fpfy8V0zehEkd7QR\n" +
+ "t7Aq38ixCQyxCmNIDJeDCKJT+wwdLaKuw/4SEpR9sygSxZ3kG6kF4icsgYuiOCRx\n" +
+ "+DrS1wP9kcrQVWQ0bJbGzwxLZXCHaJsWE1Y17mQAO4Iv/9icqDkP3bZBU5GCgbNT\n" +
+ "JEP2GiUUPU3nL41Tlq03+iDmkS2bpWCtFZmTgUg+1nJEb7PSCJ9VcoflOOFgX/ku\n" +
+ "TQCJWwhsgyOneEZAg7PpzOj2msxA9RWI88FzRnX/zyjWEpdUCVJ85hFw8u+UZ7k1\n" +
+ "eF37oOpgNxQMJ+/ey7huneTzyhpFz/TqJpfMmwaGbPL6zmPLAMQalIPQj+68zlcX\n" +
+ "qyeKVbZU74Vm051kXb/3qs6CeUpT4HrY3UmHWLvOdNkCAwEAAaOCAiUwggIhMB8G\n" +
+ "A1UdIwQYMBaAFGOPwosDsauO2FNHlh2ZqH32rKh1MGYGCCsGAQUFBwEBBFowWDAn\n" +
+ "BggrBgEFBQcwAYYbaHR0cDovL3FjYS5vY3NwLmx1eHRydXN0Lmx1MC0GCCsGAQUF\n" +
+ "BzAChiFodHRwOi8vY2EubHV4dHJ1c3QubHUvTFRHUUNBMy5jcnQwggEuBgNVHSAE\n" +
+ "ggElMIIBITCCARMGC4g3AQOBKwEBCgMFMIIBAjAqBggrBgEFBQcCARYeaHR0cHM6\n" +
+ "Ly9yZXBvc2l0b3J5Lmx1eHRydXN0Lmx1MIHTBggrBgEFBQcCAjCBxgyBw0x1eFRy\n" +
+ "dXN0IENlcnRpZmljYXRlIG5vdCBvbiBTU0NEIGNvbXBsaWFudCB3aXRoIEVUU0kg\n" +
+ "VFMgMTAyIDA0MiBOQ1AgY2VydGlmaWNhdGUgcG9saWN5LiBLZXkgR2VuZXJhdGlv\n" +
+ "biBieSBDU1AuIFNvbGUgQXV0aG9yaXNlZCBVc2FnZTogU2lnbmF0dXJlLCBEYXRh\n" +
+ "IG9yIEVudGl0eSBBdXRoZW50aWNhdGlvbiBhbmQgRGF0YSBFbmNyeXB0aW9uLjAI\n" +
+ "BgYEAI96AQEwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5sdXh0cnVzdC5s\n" +
+ "dS9MVEdRQ0EzLmNybDARBgNVHQ4ECgQISND+8GZyXrcwDgYDVR0PAQH/BAQDAgTw\n" +
+ "MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAA54w2kGy+hJsYSyrQ5C\n" +
+ "ft0rasUHQviEiy31H2Z1lh4yEPLiuUsaepdzG4bov/J1RewX1fL7fvErraKK7nNr\n" +
+ "ioAXNElHtC0wfxGx0xGaCz7xsZIDFgpzyPqS+vd8VKbRCOY66AI+3aPiatCsk+BM\n" +
+ "Hp9GwW3B1e5EOgXiWVNxzYFtav5QSAj28IEV7ZuN2BIiU+phawRaoFy+4glMB7zE\n" +
+ "J5AM/Zfi50Q85ljy1kWUueFE3VNDafAUGOF5gTHvkKqj6LznUkqcT8m96Wd0IbF2\n" +
+ "BLYjnKPF6lGJsivErGqMwQIhlUUMkRQ13/hftL12rIiSjC1C/6cnbxOjWEOGnler\n" +
+ "Qn2zu2OTGnnrYxp/hojdZggb5Yt9mkM3EmyuqP1W4g0xtMv9q97swm/fHz/rDh8T\n" +
+ "MqrEOJzz284IM0DXjXq1wkmsZ/6/ueCyf0oBN0csvYspZKmLAydZ+jZmjdKKxX+N\n" +
+ "dreauHgOq1knLHkMb/YIyA+Oh6SBlNXL4Iae8APQcRGnylHQ1lc/YHTqWh8N1tmn\n" +
+ "no5r1kVJBYYtkI3oufaLtP7JIazteZlqTN+tubMJhO4xGgt6bqEpQiid9r3UnIjR\n" +
+ "esLYxXS5qRwSoOSleXT98H75+Ok1WR3ciD4exBR8/KcUtDITvDJhkBHnRHm40jFs\n" +
+ "5UbHFf98S6G9dqzsqW8+2Bpn\n" +
+ "-----END CERTIFICATE-----";
+
+ // Owner: T=Private Person, SERIALNUMBER=00100918135105608625,
+ // GIVENNAME=TokenPRIREV, SURNAME=Test, CN=TokenPRIREV Test, C=LU
+ // Issuer: CN=LuxTrust Global Qualified CA 3, O=LuxTrust S.A., C=LU
+ // Serial number: 3814b8
+ // Valid from: Wed Jul 10 04:36:48 PDT 2019 until: Sun Jul 10 04:36:48 PDT 2022
+ private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIG+DCCBOCgAwIBAgIDOBS4MA0GCSqGSIb3DQEBCwUAME4xCzAJBgNVBAYTAkxV\n" +
+ "MRYwFAYDVQQKDA1MdXhUcnVzdCBTLkEuMScwJQYDVQQDDB5MdXhUcnVzdCBHbG9i\n" +
+ "YWwgUXVhbGlmaWVkIENBIDMwHhcNMTkwNzEwMTEzNjQ4WhcNMjIwNzEwMTEzNjQ4\n" +
+ "WjCBhTELMAkGA1UEBhMCTFUxGTAXBgNVBAMTEFRva2VuUFJJUkVWIFRlc3QxDTAL\n" +
+ "BgNVBAQTBFRlc3QxFDASBgNVBCoTC1Rva2VuUFJJUkVWMR0wGwYDVQQFExQwMDEw\n" +
+ "MDkxODEzNTEwNTYwODYyNTEXMBUGA1UEDBMOUHJpdmF0ZSBQZXJzb24wggGiMA0G\n" +
+ "CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCcm7y4c/D58u6g3m6HGdfiqDXa2yEl\n" +
+ "H2cAeSb85fsAX08iXfa/U/kmFqqycwp2nsJdfor6HEEqHsmozyjjIWHDEsq+cUre\n" +
+ "SO6d2Ag29MrxsAWZ1XAol40FcxNN+yEL9Xs5doqqcbz3OoKdxkoWVdYq3D7peizF\n" +
+ "OER4M2XA0KSLiKXDapDCfTVLE6qRG6Cn5mqnlqbUtkI6vSsda5mWLSNe4Qw/PIMw\n" +
+ "v7ZDn5dHeHoV6UpZC95Ole5vMQfjAOsy4nRc1zofQz7iPw4ClNzDQSuonaAKSk3Y\n" +
+ "1KjWPmHshb6BoANL+ce1KuWESKV3D5lBkVVLTeoBkWQu7ViJviF2HE5UoPRSGijO\n" +
+ "nmGOTZRsjOJXPe7/pEq9SQ477EufnSsoCj1cPCtaowbsO7oswzV/axKMhhZf6nU7\n" +
+ "0wd9xUuMgMRKBfi026mYK7pdxJ85qE8qKlqeNprje+g1sjxMDbMHARA427Px0IUJ\n" +
+ "mzIJk0ysAQvbqQVe8QQM/f+PH3mUkXR02H8CAwEAAaOCAiUwggIhMB8GA1UdIwQY\n" +
+ "MBaAFGOPwosDsauO2FNHlh2ZqH32rKh1MGYGCCsGAQUFBwEBBFowWDAnBggrBgEF\n" +
+ "BQcwAYYbaHR0cDovL3FjYS5vY3NwLmx1eHRydXN0Lmx1MC0GCCsGAQUFBzAChiFo\n" +
+ "dHRwOi8vY2EubHV4dHJ1c3QubHUvTFRHUUNBMy5jcnQwggEuBgNVHSAEggElMIIB\n" +
+ "ITCCARMGC4g3AQOBKwEBCgMFMIIBAjAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBv\n" +
+ "c2l0b3J5Lmx1eHRydXN0Lmx1MIHTBggrBgEFBQcCAjCBxgyBw0x1eFRydXN0IENl\n" +
+ "cnRpZmljYXRlIG5vdCBvbiBTU0NEIGNvbXBsaWFudCB3aXRoIEVUU0kgVFMgMTAy\n" +
+ "IDA0MiBOQ1AgY2VydGlmaWNhdGUgcG9saWN5LiBLZXkgR2VuZXJhdGlvbiBieSBD\n" +
+ "U1AuIFNvbGUgQXV0aG9yaXNlZCBVc2FnZTogU2lnbmF0dXJlLCBEYXRhIG9yIEVu\n" +
+ "dGl0eSBBdXRoZW50aWNhdGlvbiBhbmQgRGF0YSBFbmNyeXB0aW9uLjAIBgYEAI96\n" +
+ "AQEwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5sdXh0cnVzdC5sdS9MVEdR\n" +
+ "Q0EzLmNybDARBgNVHQ4ECgQIS0KUXpWyku0wDgYDVR0PAQH/BAQDAgTwMAwGA1Ud\n" +
+ "EwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAFSnezuyeRO0sh9e8/1N+2RE6Uhb\n" +
+ "RIdLKmaS8hMOyUNBapnHfJAdOn7j767qWQjRop5VNCcv0zDOxAqApxFiz4gJdzBY\n" +
+ "FVrEVwYos8a3BHLXNxfwIWEJ6EjlqI2qI3NjqK8m4M8LTq4G94V2/MOFVpXeCLju\n" +
+ "r0s+XZep2Sk9J4ofUOc8Gp7IZNhPzIlfKQ+KhnWovde4bpL3zRpp4u7Y580XsBuN\n" +
+ "kow2Eg84tRzSVizmgLPuRbySHuMo1jGIP7F9FdtOC8VVSjntfCXSEQqOvpH4YZ8S\n" +
+ "V4qP17CQHPWW1kOHAyXpkAjU+6SOlmF76Adv9nQFTZ6DAnKqiuxmi8EVCv96aFD7\n" +
+ "Ih+zBF7kj7fghPjUzsVdB6gI4VwuFCXEaAfWlxJS67s1hKnsCyqX3cu+Gnq9aRt+\n" +
+ "08iaTVEdrKL95AYYobVbnGJ7bH87SpenjLL+CDctXNNDlpJZ8eRYcQe+Q4dg+8L8\n" +
+ "X8tkXBeRbiZD1U7XwVBnKF6sJmhA4F/h/EJzwX0lp7EU6EO91bSiwD2NFVs+64UR\n" +
+ "9lftfFFm5In2N3vjDR/3nrCf3Jq9f0g7bTrNJmo+hc0+fD+zlAhZAx+ii2xE1cY1\n" +
+ "KLH2zXNzPUgIqYGdVQwn1TUFJN8JgGKsXwc+P51nEpgf6JVyK1m7EtVGtr9gF7DI\n" +
+ "P+4VSqTbTp4/l5n0\n" +
+ "-----END CERTIFICATE-----";
+
+ 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();
+ }
+
+ // 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,
+ "Wed Jul 10 04:48:49 PDT 2019", System.out);
+ }
+}
diff --git a/jdk/test/sun/misc/IOUtils/ReadAllBytes.java b/jdk/test/sun/misc/IOUtils/ReadAllBytes.java
new file mode 100644
index 0000000..440aad0
--- /dev/null
+++ b/jdk/test/sun/misc/IOUtils/ReadAllBytes.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Random;
+
+import jdk.testlibrary.RandomFactory;
+
+import sun.misc.IOUtils;
+
+/*
+ * @test
+ * @bug 8080835 8193832
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
+ * @run main ReadAllBytes
+ * @summary Basic test for IOUtils.readAllBytes
+ * @key randomness
+ */
+
+public class ReadAllBytes {
+
+ private static Random generator = RandomFactory.getRandom();
+
+ public static void main(String[] args) throws IOException {
+ test(new byte[]{});
+ test(new byte[]{1, 2, 3});
+ test(createRandomBytes(1024));
+ for (int shift : new int[] {13, 14, 15, 17}) {
+ for (int offset : new int[] {-1, 0, 1}) {
+ test(createRandomBytes((1 << shift) + offset));
+ }
+ }
+ }
+
+ static void test(byte[] expectedBytes) throws IOException {
+ int expectedLength = expectedBytes.length;
+ WrapperInputStream in = new WrapperInputStream(new ByteArrayInputStream(expectedBytes));
+ byte[] readBytes = IOUtils.readAllBytes(in);
+
+ int x;
+ byte[] tmp = new byte[10];
+ check((x = in.read()) == -1,
+ "Expected end of stream from read(), got " + x);
+ check((x = in.read(tmp)) == -1,
+ "Expected end of stream from read(byte[]), got " + x);
+ check((x = in.read(tmp, 0, tmp.length)) == -1,
+ "Expected end of stream from read(byte[], int, int), got " + x);
+ check(IOUtils.readAllBytes(in).length == 0,
+ "Expected readAllBytes to return empty byte array");
+ check(expectedLength == readBytes.length,
+ "Expected length " + expectedLength + ", got " + readBytes.length);
+ check(Arrays.equals(expectedBytes, readBytes),
+ "Expected[" + expectedBytes + "], got:[" + readBytes + "]");
+ check(!in.isClosed(), "Stream unexpectedly closed");
+ }
+
+ static byte[] createRandomBytes(int size) {
+ byte[] bytes = new byte[size];
+ generator.nextBytes(bytes);
+ return bytes;
+ }
+
+ static void check(boolean cond, Object ... failedArgs) {
+ if (cond)
+ return;
+ StringBuilder sb = new StringBuilder();
+ for (Object o : failedArgs)
+ sb.append(o);
+ throw new RuntimeException(sb.toString());
+ }
+
+ static class WrapperInputStream extends FilterInputStream {
+ private boolean closed;
+ WrapperInputStream(InputStream in) { super(in); }
+ @Override public void close() throws IOException { closed = true; in.close(); }
+ boolean isClosed() { return closed; }
+ }
+}
diff --git a/jdk/test/sun/misc/IOUtils/ReadNBytes.java b/jdk/test/sun/misc/IOUtils/ReadNBytes.java
new file mode 100644
index 0000000..96ae6c3
--- /dev/null
+++ b/jdk/test/sun/misc/IOUtils/ReadNBytes.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Random;
+import jdk.testlibrary.RandomFactory;
+
+import sun.misc.IOUtils;
+
+/*
+ * @test
+ * @bug 8080835 8139206
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
+ * @run main ReadNBytes
+ * @summary Basic test for IOUtils.readNBytes
+ * @key randomness
+ */
+
+public class ReadNBytes {
+
+ private static Random generator = RandomFactory.getRandom();
+
+ public static void main(String[] args) throws IOException {
+ test(new byte[]{1, 2, 3});
+ test(createRandomBytes(1024));
+ for (int shift : new int[] {13, 15, 17}) {
+ for (int offset : new int[] {-1, 0, 1}) {
+ test(createRandomBytes((1 << shift) + offset));
+ }
+ }
+
+ test(-1);
+ test(0);
+ for (int shift : new int[] {13, 15, 17}) {
+ for (int offset : new int[] {-1, 0, 1}) {
+ test((1 << shift) + offset);
+ }
+ }
+ }
+
+ static void test(byte[] inputBytes) throws IOException {
+ int length = inputBytes.length;
+ WrapperInputStream in = new WrapperInputStream(new ByteArrayInputStream(inputBytes));
+ byte[] readBytes = new byte[(length / 2) + 1];
+ int nread = IOUtils.readNBytes(in, readBytes, 0, readBytes.length);
+
+ int x;
+ byte[] tmp;
+ check(nread == readBytes.length,
+ "Expected number of bytes read: " + readBytes.length + ", got: " + nread);
+ check(Arrays.equals((tmp = Arrays.copyOf(inputBytes, nread)), readBytes),
+ "Expected[" + tmp + "], got:[" + readBytes + "]");
+ check(!in.isClosed(), "Stream unexpectedly closed");
+
+ // Read again
+ nread = IOUtils.readNBytes(in, readBytes, 0, readBytes.length);
+
+ check(nread == length - readBytes.length,
+ "Expected number of bytes read: " + (length - readBytes.length) + ", got: " + nread);
+ check(Arrays.equals((tmp = Arrays.copyOfRange(inputBytes, readBytes.length, length)),
+ Arrays.copyOf(readBytes, nread)),
+ "Expected[" + tmp + "], got:[" + readBytes + "]");
+ // Expect end of stream
+ check((x = in.read()) == -1,
+ "Expected end of stream from read(), got " + x);
+ check((x = in.read(tmp)) == -1,
+ "Expected end of stream from read(byte[]), got " + x);
+ check((x = in.read(tmp, 0, tmp.length)) == -1,
+ "Expected end of stream from read(byte[], int, int), got " + x);
+ check((x = IOUtils.readNBytes(in, tmp, 0, tmp.length)) == 0,
+ "Expected end of stream, 0, from readNBytes(byte[], int, int), got " + x);
+ check(!in.isClosed(), "Stream unexpectedly closed");
+ }
+
+ static void test(int max) throws IOException {
+ byte[] subset1, subset2;
+ byte[] inputBytes = max <= 0 ? new byte[0] : createRandomBytes(max);
+ WrapperInputStream in =
+ new WrapperInputStream(new ByteArrayInputStream(inputBytes));
+
+ if (max < 0) {
+ try {
+ IOUtils.readNBytes(in, max);
+ check(false, "Expected IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException iae) {
+ return;
+ }
+ } else if (max == 0) {
+ int x;
+ check((x = IOUtils.readNBytes(in, max).length) == 0,
+ "Expected zero bytes, got " + x);
+ return;
+ }
+
+ int off = Math.toIntExact(in.skip(generator.nextInt(max/2)));
+ int len = generator.nextInt(max - 1 - off);
+ byte[] readBytes = IOUtils.readNBytes(in, len);
+ check(readBytes.length == len,
+ "Expected " + len + " bytes, got " + readBytes.length);
+ subset1 = Arrays.copyOfRange(inputBytes, off, off + len);
+ subset2 = Arrays.copyOfRange(readBytes, 0, len);
+ check(Arrays.equals(subset1, subset2), "Expected[" + subset1 +
+ "], got:[" + readBytes + "]");
+
+ int remaining = max - (off + len);
+ readBytes = IOUtils.readNBytes(in, remaining);
+ check(readBytes.length == remaining,
+ "Expected " + remaining + "bytes, got " + readBytes.length);
+ subset1 = Arrays.copyOfRange(inputBytes, off + len, max);
+ subset2 = Arrays.copyOfRange(readBytes, 0, remaining);
+ check(Arrays.equals(subset1, subset2), "Expected[" + subset1 +
+ "], got:[" + readBytes + "]");
+
+ check(!in.isClosed(), "Stream unexpectedly closed");
+ }
+
+ static byte[] createRandomBytes(int size) {
+ byte[] bytes = new byte[size];
+ generator.nextBytes(bytes);
+ return bytes;
+ }
+
+ static void check(boolean cond, Object ... failedArgs) {
+ if (cond)
+ return;
+ StringBuilder sb = new StringBuilder();
+ for (Object o : failedArgs)
+ sb.append(o);
+ throw new RuntimeException(sb.toString());
+ }
+
+
+ static class WrapperInputStream extends FilterInputStream {
+ private boolean closed;
+ WrapperInputStream(InputStream in) { super(in); }
+ @Override public void close() throws IOException { closed = true; in.close(); }
+ boolean isClosed() { return closed; }
+ }
+}
diff --git a/jdk/test/sun/misc/URLClassPath/JarClassPathFileEntry.java b/jdk/test/sun/misc/URLClassPath/JarClassPathFileEntry.java
new file mode 100644
index 0000000..6f57ec5
--- /dev/null
+++ b/jdk/test/sun/misc/URLClassPath/JarClassPathFileEntry.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import jdk.testlibrary.InMemoryJavaCompiler;
+import jdk.testlibrary.JarUtils;
+
+/*
+ * @test
+ * @bug 8216401
+ * @summary Test loading of JAR Class-Path entry with file: scheme
+ * @library /lib/testlibrary
+ *
+ * @run main/othervm JarClassPathFileEntry
+ * @run main/othervm -Djdk.net.URLClassPath.disableClassPathURLCheck=true JarClassPathFileEntry
+ * @run main/othervm -Djdk.net.URLClassPath.disableClassPathURLCheck=false JarClassPathFileEntry
+ */
+
+public class JarClassPathFileEntry {
+ private final static boolean IS_WINDOWS = System.getProperty("os.name").startsWith("Windows");
+
+ private final static String TEST_CLASSES = System.getProperty("test.classes");
+ private final static String OTHER_DIR = TEST_CLASSES + "/OTHER/";
+
+ private final static Path OTHER_JAR_PATH = Paths.get(OTHER_DIR, "Other.jar");
+ private final static Path CONTEXT_JAR_PATH = Paths.get(TEST_CLASSES, "Context.jar");
+
+ public static void main(String[] args) throws Throwable {
+ // Create Other.class in OTHER_DIR, off the default classpath
+ byte klassbuf[] = InMemoryJavaCompiler.compile("Other",
+ "public class Other {}");
+ ClassFileInstaller.writeClassToDisk("Other", klassbuf, OTHER_DIR);
+
+ // Create Other.jar in OTHER_DIR
+ JarUtils.createJarFile(OTHER_JAR_PATH,
+ Paths.get(OTHER_DIR),
+ Paths.get(OTHER_DIR, "Other.class"));
+
+ // Create Context.class
+ klassbuf = InMemoryJavaCompiler.compile("Context",
+ "public class Context {}");
+ ClassFileInstaller.writeClassToDisk("Context", klassbuf, TEST_CLASSES);
+
+ // Create Context.jar w/ "file:" entry for Other.jar
+ Manifest mf = new Manifest();
+ Attributes attrs = mf.getMainAttributes();
+ attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
+
+ String classPathEntry = "file:" + (IS_WINDOWS ? toUnixPath(OTHER_JAR_PATH.toString())
+ : OTHER_JAR_PATH.toString());
+ attrs.put(Attributes.Name.CLASS_PATH, classPathEntry);
+
+ System.out.println("Creating Context.jar with Class-Path: " + classPathEntry);
+ JarUtils.createJarFile(CONTEXT_JAR_PATH, mf,
+ Paths.get(TEST_CLASSES),
+ Paths.get(TEST_CLASSES, "Context.class"));
+
+ // Use URLClassLoader w/ Context.jar to load Other.class, which will
+ // load via the Class-Path entry
+ URL url = CONTEXT_JAR_PATH.toUri().toURL();
+ URLClassLoader ucl = new URLClassLoader(new URL[]{ url },
+ null); // don't delegate to App CL
+ Class<?> otherClass = Class.forName("Other", true, ucl); // ClassNotFoundException -> fail
+ System.out.println("Loaded: " + otherClass);
+ }
+
+ /* Convert a Windows path to a unix-style path, and remove any drive letter */
+ private static String toUnixPath(String orig) {
+ String retVal = new File(orig).toURI().getPath();
+ int colonAt = retVal.indexOf(':');
+
+ if (colonAt != -1 && colonAt < 3) {
+ retVal = retVal.substring(colonAt + 1); // Start after the drive letter
+ }
+ return retVal;
+ }
+}
diff --git a/jdk/test/sun/net/www/B8185898.java b/jdk/test/sun/net/www/B8185898.java
new file mode 100644
index 0000000..67f3998
--- /dev/null
+++ b/jdk/test/sun/net/www/B8185898.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2019, 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 8185898
+ * @library /lib/testlibrary
+ * @run main/othervm B8185898
+ * @summary setRequestProperty(key, null) results in HTTP header without colon in request
+ */
+
+import java.io.*;
+import java.net.*;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
+import java.util.Collections;
+
+import jdk.testlibrary.net.URIBuilder;
+import sun.net.www.MessageHeader;
+import com.sun.net.httpserver.HttpContext;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+/*
+ * Test checks that MessageHeader with key != null and value == null is set correctly
+ * and printed according to HTTP standard in the format <key>: <value>
+ * */
+public class B8185898 {
+
+ static HttpServer server;
+ static final String RESPONSE_BODY = "Test response body";
+ static final String H1 = "X-header1";
+ static final String H2 = "X-header2";
+ static final String VALUE = "This test value should appear";
+ static final List<String> oneList = Arrays.asList(VALUE);
+ static final List<String> zeroList = Arrays.asList("");
+ static int port;
+ static URL url;
+ static volatile Map<String, List<String>> headers;
+
+ static class Handler implements HttpHandler {
+
+ public void handle(HttpExchange t) throws IOException {
+ InputStream is = t.getRequestBody();
+ InetSocketAddress rem = t.getRemoteAddress();
+ headers = t.getRequestHeaders(); // Get request headers on the server side
+ while(is.read() != -1){}
+ is.close();
+
+ OutputStream os = t.getResponseBody();
+ t.sendResponseHeaders(200, RESPONSE_BODY.length());
+ os.write(RESPONSE_BODY.getBytes(UTF_8));
+ t.close();
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ ExecutorService exec = Executors.newCachedThreadPool();
+ InetAddress loopback = InetAddress.getLoopbackAddress();
+
+ try {
+ InetSocketAddress addr = new InetSocketAddress(loopback, 0);
+ server = HttpServer.create(addr, 100);
+ HttpHandler handler = new Handler();
+ HttpContext context = server.createContext("/", handler);
+ server.setExecutor(exec);
+ server.start();
+
+ port = server.getAddress().getPort();
+ System.out.println("Server on port: " + port);
+ url = URIBuilder.newBuilder()
+ .scheme("http")
+ .loopback()
+ .port(port)
+ .path("/foo")
+ .toURLUnchecked();
+ System.out.println("URL: " + url);
+ testMessageHeader();
+ testMessageHeaderMethods();
+ testURLConnectionMethods();
+ } finally {
+ server.stop(0);
+ System.out.println("After server shutdown");
+ exec.shutdown();
+ }
+ }
+
+ // Test message header with malformed message header and fake request line
+ static void testMessageHeader() {
+ final String badHeader = "This is not a request line for HTTP/1.1";
+ final String fakeRequestLine = "This /is/a/fake/status/line HTTP/2.0";
+ final String expectedHeaders = fakeRequestLine + "\r\n"
+ + H1 + ": " + VALUE + "\r\n"
+ + H2 + ": " + VALUE + "\r\n"
+ + badHeader + ":\r\n\r\n";
+
+ MessageHeader header = new MessageHeader();
+ header.add(H1, VALUE);
+ header.add(H2, VALUE);
+ header.add(badHeader, null);
+ header.prepend(fakeRequestLine, null);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ header.print(new PrintStream(out));
+
+ if (!out.toString().equals(expectedHeaders)) {
+ throw new AssertionError("FAILED: expected: "
+ + expectedHeaders + "\nReceived: " + out.toString());
+ } else {
+ System.out.println("PASSED: ::print returned correct "
+ + "status line and headers:\n" + out.toString());
+ }
+ }
+
+ // Test MessageHeader::print, ::toString, implicitly testing that
+ // MessageHeader::mergeHeader formats headers correctly for responses
+ static void testMessageHeaderMethods() throws IOException {
+ // {{inputString1, expectedToString1, expectedPrint1}, {...}}
+ String[][] strings = {
+ {"HTTP/1.1 200 OK\r\n"
+ + "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"
+ + "Connection: keep-alive\r\n"
+ + "Host: 127.0.0.1:12345\r\n"
+ + "User-agent: Java/12\r\n\r\nfoooo",
+ "pairs: {null: HTTP/1.1 200 OK}"
+ + "{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}"
+ + "{Connection: keep-alive}"
+ + "{Host: 127.0.0.1:12345}"
+ + "{User-agent: Java/12}",
+ "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"
+ + "Connection: keep-alive\r\n"
+ + "Host: 127.0.0.1:12345\r\n"
+ + "User-agent: Java/12\r\n\r\n"},
+ {"HTTP/1.1 200 OK\r\n"
+ + "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"
+ + "Connection: keep-alive\r\n"
+ + "Host: 127.0.0.1:12345\r\n"
+ + "User-agent: Java/12\r\n"
+ + "X-Header:\r\n\r\n",
+ "pairs: {null: HTTP/1.1 200 OK}"
+ + "{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}"
+ + "{Connection: keep-alive}"
+ + "{Host: 127.0.0.1:12345}"
+ + "{User-agent: Java/12}"
+ + "{X-Header: }",
+ "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"
+ + "Connection: keep-alive\r\n"
+ + "Host: 127.0.0.1:12345\r\n"
+ + "User-agent: Java/12\r\n"
+ + "X-Header: \r\n\r\n"},
+ };
+
+ System.out.println("Test custom message headers");
+ for (String[] s : strings) {
+ // Test MessageHeader::toString
+ MessageHeader header = new MessageHeader(
+ new ByteArrayInputStream(s[0].getBytes(ISO_8859_1)));
+ if (!header.toString().endsWith(s[1])) {
+ throw new AssertionError("FAILED: expected: "
+ + s[1] + "\nReceived: " + header);
+ } else {
+ System.out.println("PASSED: ::toString returned correct "
+ + "status line and headers:\n" + header);
+ }
+
+ // Test MessageHeader::print
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ header.print(new PrintStream(out));
+ if (!out.toString().equals(s[2])) {
+ throw new AssertionError("FAILED: expected: "
+ + s[2] + "\nReceived: " + out.toString());
+ } else {
+ System.out.println("PASSED: ::print returned correct "
+ + "status line and headers:\n" + out.toString());
+ }
+ }
+ }
+
+ // Test methods URLConnection::getRequestProperties,
+ // ::getHeaderField, ::getHeaderFieldKey
+ static void testURLConnectionMethods() throws IOException {
+ HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
+ urlConn.setRequestProperty(H1, "");
+ urlConn.setRequestProperty(H1, VALUE);
+ urlConn.setRequestProperty(H2, null); // Expected to contain ':' between key and value
+ Map<String, List<String>> props = urlConn.getRequestProperties();
+ Map<String, List<String>> expectedMap = new HashMap<String, List<String>>();
+ expectedMap.put(H1, oneList);
+ expectedMap.put(H2, Arrays.asList((String)null));
+
+ // Test request properties
+ System.out.println("Client request properties");
+ StringBuilder sb = new StringBuilder();
+ props.forEach((k, v) -> sb.append(k + ": "
+ + v.stream().collect(Collectors.joining()) + "\n"));
+ System.out.println(sb);
+
+ if (!props.equals(expectedMap)) {
+ throw new AssertionError("Unexpected properties returned: "
+ + props);
+ } else {
+ System.out.println("Properties returned as expected");
+ }
+
+ // Test header fields
+ String headerField = urlConn.getHeaderField(0);
+ if (!headerField.contains("200 OK")) {
+ throw new AssertionError("Expected headerField[0]: status line. "
+ + "Received: " + headerField);
+ } else {
+ System.out.println("PASSED: headerField[0] contains status line: "
+ + headerField);
+ }
+
+ String headerFieldKey = urlConn.getHeaderFieldKey(0);
+ if (headerFieldKey != null) {
+ throw new AssertionError("Expected headerFieldKey[0]: null. "
+ + "Received: " + headerFieldKey);
+ } else {
+ System.out.println("PASSED: headerFieldKey[0] is null");
+ }
+
+ // Check that test request headers are included with correct format
+ try (
+ BufferedReader in = new BufferedReader(
+ new InputStreamReader(urlConn.getInputStream()))
+ ) {
+ if (!headers.keySet().contains(H1)) {
+ throw new AssertionError("Expected key not found: "
+ + H1 + ": " + VALUE);
+ } else if (!headers.get(H1).equals(oneList)) {
+ throw new AssertionError("Unexpected key-value pair: "
+ + H1 + ": " + headers.get(H1));
+ } else {
+ System.out.println("PASSED: " + H1 + " included in request headers");
+ }
+
+ if (!headers.keySet().contains(H2)) {
+ throw new AssertionError("Expected key not found: "
+ + H2 + ": ");
+ // Check that empty list is returned
+ } else if (!headers.get(H2).equals(zeroList)) {
+ throw new AssertionError("Unexpected key-value pair: "
+ + H2 + ": " + headers.get(H2));
+ } else {
+ System.out.println("PASSED: " + H2 + " included in request headers");
+ }
+
+ String inputLine;
+ while ((inputLine = in.readLine()) != null) {
+ System.out.println(inputLine);
+ }
+ }
+ }
+}
diff --git a/jdk/test/sun/security/ec/SignatureDigestTruncate.java b/jdk/test/sun/security/ec/SignatureDigestTruncate.java
index a0ebbb2..18208fc 100644
--- a/jdk/test/sun/security/ec/SignatureDigestTruncate.java
+++ b/jdk/test/sun/security/ec/SignatureDigestTruncate.java
@@ -91,22 +91,25 @@
String privateKeyStr, String msgStr, String kStr, String sigStr)
throws Exception {
+ System.out.println("Testing " + alg + " with " + curveName);
+
byte[] privateKey = Convert.hexStringToByteArray(privateKeyStr);
byte[] msg = Convert.hexStringToByteArray(msgStr);
byte[] k = Convert.hexStringToByteArray(kStr);
byte[] expectedSig = Convert.hexStringToByteArray(sigStr);
- AlgorithmParameters params = AlgorithmParameters.getInstance("EC");
+ AlgorithmParameters params =
+ AlgorithmParameters.getInstance("EC", "SunEC");
params.init(new ECGenParameterSpec(curveName));
ECParameterSpec ecParams =
params.getParameterSpec(ECParameterSpec.class);
- KeyFactory kf = KeyFactory.getInstance("EC");
+ KeyFactory kf = KeyFactory.getInstance("EC", "SunEC");
BigInteger s = new BigInteger(1, privateKey);
ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec(s, ecParams);
PrivateKey privKey = kf.generatePrivate(privKeySpec);
- Signature sig = Signature.getInstance(alg);
+ Signature sig = Signature.getInstance(alg, "SunEC");
sig.initSign(privKey, new FixedRandom(k));
sig.update(msg);
byte[] computedSig = sig.sign();
diff --git a/jdk/test/sun/security/ec/SignedObjectChain.java b/jdk/test/sun/security/ec/SignedObjectChain.java
index 6e93053..d7adb0e 100644
--- a/jdk/test/sun/security/ec/SignedObjectChain.java
+++ b/jdk/test/sun/security/ec/SignedObjectChain.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,8 @@
/*
* @test
- * @bug 8050374
+ * @bug 8050374 8146293
+ * @library /lib
* @compile ../../../java/security/SignedObject/Chain.java
* @summary Verify a chain of signed objects
*/
diff --git a/jdk/test/sun/security/krb5/auto/Addresses.java b/jdk/test/sun/security/krb5/auto/Addresses.java
new file mode 100644
index 0000000..0bd62e4
--- /dev/null
+++ b/jdk/test/sun/security/krb5/auto/Addresses.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2012, 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 8031111
+ * @summary fix krb5 caddr
+ * @compile -XDignore.symbol.file Addresses.java
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Addresses
+ */
+
+import sun.security.krb5.Config;
+
+import javax.security.auth.kerberos.KerberosTicket;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+
+public class Addresses {
+
+ public static void main(String[] args) throws Exception {
+
+ KDC.saveConfig(OneKDC.KRB5_CONF, new OneKDC(null),
+ "noaddresses = false",
+ "extra_addresses = 10.0.0.10, 10.0.0.11 10.0.0.12");
+ Config.refresh();
+
+ KerberosTicket ticket =
+ Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false)
+ .s().getPrivateCredentials(KerberosTicket.class)
+ .iterator().next();
+
+ InetAddress loopback = InetAddress.getLoopbackAddress();
+ InetAddress extra1 = InetAddress.getByName("10.0.0.10");
+ InetAddress extra2 = InetAddress.getByName("10.0.0.11");
+ InetAddress extra3 = InetAddress.getByName("10.0.0.12");
+
+ boolean loopbackFound = false;
+ boolean extra1Found = false;
+ boolean extra2Found = false;
+ boolean extra3Found = false;
+ boolean networkFound = false;
+
+ for (InetAddress ia: ticket.getClientAddresses()) {
+ System.out.println(ia);
+ if (ia.equals(loopback)) {
+ loopbackFound = true;
+ System.out.println(" loopback found");
+ } else if (ia.equals(extra1)) {
+ extra1Found = true;
+ System.out.println(" extra1 found");
+ } else if (ia.equals(extra2)) {
+ extra2Found = true;
+ System.out.println(" extra2 found");
+ } else if (ia.equals(extra3)) {
+ extra3Found = true;
+ System.out.println(" extra3 found");
+ } else if (ia instanceof Inet4Address) {
+ networkFound = true;
+ System.out.println(" another address (" + ia +
+ "), assumed real network");
+ }
+ }
+
+ if (!loopbackFound || !networkFound
+ || !extra1Found || !extra2Found || !extra3Found ) {
+ throw new Exception();
+ }
+ }
+}
diff --git a/jdk/test/sun/security/krb5/auto/Basic.java b/jdk/test/sun/security/krb5/auto/Basic.java
index 7ec3873..cc934ff 100644
--- a/jdk/test/sun/security/krb5/auto/Basic.java
+++ b/jdk/test/sun/security/krb5/auto/Basic.java
@@ -23,10 +23,12 @@
/*
* @test
- * @bug 7152176
+ * @bug 7152176 8201627
* @summary More krb5 tests
* @compile -XDignore.symbol.file Basic.java
- * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Basic
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock
+ * -Dsun.security.krb5.acceptor.sequence.number.nonmutual=zero
+ * Basic
*/
import sun.security.jgss.GSSUtil;
@@ -45,6 +47,7 @@
c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
c.x().requestCredDeleg(true);
+ c.x().requestMutualAuth(false);
s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
Context.handshake(c, s);
diff --git a/jdk/test/sun/security/krb5/auto/BasicKrb5Test.java b/jdk/test/sun/security/krb5/auto/BasicKrb5Test.java
index ade0b54..f18ae16 100644
--- a/jdk/test/sun/security/krb5/auto/BasicKrb5Test.java
+++ b/jdk/test/sun/security/krb5/auto/BasicKrb5Test.java
@@ -79,7 +79,7 @@
String etype = null;
for (String arg: args) {
if (arg.equals("-s")) Context.usingStream = true;
- else if(arg.equals("-C")) conf = false;
+ else if (arg.equals("-C")) conf = false;
else etype = arg;
}
diff --git a/jdk/test/sun/security/krb5/auto/BasicProc.java b/jdk/test/sun/security/krb5/auto/BasicProc.java
index bcc3cd0..50f65ea 100644
--- a/jdk/test/sun/security/krb5/auto/BasicProc.java
+++ b/jdk/test/sun/security/krb5/auto/BasicProc.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -23,180 +23,306 @@
/*
* @test
- * @bug 8009977
- * @summary A test library to launch multiple Java processes
- * @library ../../../../java/security/testlibrary/
+ * @bug 8009977 8186884 8201627
+ * @summary A test to launch multiple Java processes using either Java GSS
+ * or native GSS
+ * @library ../../../../java/security/testlibrary /lib/testlibrary
* @compile -XDignore.symbol.file BasicProc.java
- * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock BasicProc
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock BasicProc launcher
*/
-import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.attribute.PosixFilePermission;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.PropertyPermission;
+import java.util.Set;
+
+import jdk.testlibrary.Asserts;
import org.ietf.jgss.Oid;
+import sun.security.krb5.Config;
import javax.security.auth.PrivateCredentialPermission;
+/**
+ * Run this test automatically and test Java GSS with embedded KDC.
+ *
+ * Run with customized native.krb5.libs to test interop between Java GSS
+ * and native GSS, and native.kdc.path with a native KDC. For example,
+ * run the following command to test interop among Java, default native,
+ * MIT, and Heimdal krb5 libraries with the Heimdal KDC:
+ *
+ * jtreg -Dnative.krb5.libs=j=,
+ * n=,
+ * k=/usr/local/krb5/lib/libgssapi_krb5.so,
+ * h=/space/install/heimdal/lib/libgssapi.so \
+ * -Dnative.kdc.path=/usr/local/heimdal \
+ * BasicProc.java
+ *
+ * Note: The first 4 lines should be concatenated to make a long system
+ * property value with no blank around ",". This comma-separated value
+ * has each element being name=libpath. The special name "j" means the
+ * Java library and libpath is ignored. Otherwise it means a native library,
+ * and libpath (can be empty) will be the value for the sun.security.jgss.lib
+ * system property. If this system property is not set, only the Java
+ * library will be tested.
+ */
+
public class BasicProc {
- static String CONF = "krb5.conf";
- static String KTAB = "ktab";
+ private static final String CONF = "krb5.conf";
+ private static final String KTAB_S = "server.ktab";
+ private static final String KTAB_B = "backend.ktab";
+
+ private static final String HOST = "localhost";
+ private static final String SERVER = "server/" + HOST;
+ private static final String BACKEND = "backend/" + HOST;
+ private static final String USER = "user";
+ private static final char[] PASS = "password".toCharArray();
+ private static final String REALM = "REALM";
+
+ private static final int MSGSIZE = 1024;
+ private static final byte[] MSG = new byte[MSGSIZE];
+
public static void main(String[] args) throws Exception {
- String HOST = "localhost";
- String SERVER = "server/" + HOST;
- String BACKEND = "backend/" + HOST;
- String USER = "user";
- char[] PASS = "password".toCharArray();
- String REALM = "REALM";
Oid oid = new Oid("1.2.840.113554.1.2.2");
+ byte[] token, msg;
- if (args.length == 0) {
- System.setProperty("java.security.krb5.conf", CONF);
- KDC kdc = KDC.create(REALM, HOST, 0, true);
- kdc.addPrincipal(USER, PASS);
- kdc.addPrincipalRandKey("krbtgt/" + REALM);
- kdc.addPrincipalRandKey(SERVER);
- kdc.addPrincipalRandKey(BACKEND);
+ switch (args[0]) {
+ case "launcher":
+ KDC kdc = KDC.create(REALM, HOST, 0, true);
+ try {
+ kdc.addPrincipal(USER, PASS);
+ kdc.addPrincipalRandKey("krbtgt/" + REALM);
+ kdc.addPrincipalRandKey(SERVER);
+ kdc.addPrincipalRandKey(BACKEND);
- String cwd = System.getProperty("user.dir");
- kdc.writeKtab(KTAB);
- KDC.saveConfig(CONF, kdc, "forwardable = true");
+ // Native lib might do some name lookup
+ KDC.saveConfig(CONF, kdc,
+ "dns_lookup_kdc = no",
+ "ticket_lifetime = 1h",
+ "dns_lookup_realm = no",
+ "dns_canonicalize_hostname = false",
+ "forwardable = true");
+ System.setProperty("java.security.krb5.conf", CONF);
+ Config.refresh();
+ kdc.writeKtab(KTAB_S, false, SERVER);
+ kdc.writeKtab(KTAB_B, false, BACKEND);
- Proc pc = Proc.create("BasicProc")
- .args("client")
- .prop("java.security.krb5.conf", CONF)
- .prop("java.security.manager", "")
- .prop("sun.net.spi.nameservice.provider.1", "ns,mock")
- .perm(new java.lang.RuntimePermission(
- "accessClassInPackage.sun.net.spi.nameservice"))
- .perm(new java.util.PropertyPermission(
- "sun.security.krb5.principal", "read"))
- .perm(new javax.security.auth.AuthPermission(
- "modifyPrincipals"))
- .perm(new javax.security.auth.AuthPermission(
- "modifyPrivateCredentials"))
- .perm(new javax.security.auth.AuthPermission("doAs"))
- .perm(new javax.security.auth.kerberos.ServicePermission(
- "krbtgt/" + REALM + "@" + REALM, "initiate"))
- .perm(new javax.security.auth.kerberos.ServicePermission(
- "server/localhost@" + REALM, "initiate"))
- .perm(new javax.security.auth.kerberos.DelegationPermission(
- "\"server/localhost@" + REALM + "\" " +
- "\"krbtgt/" + REALM + "@" + REALM + "\""))
- .debug("C")
- .start();
- Proc ps = Proc.create("BasicProc")
- .args("server")
- .prop("java.security.krb5.conf", CONF)
- .prop("java.security.manager", "")
- .prop("sun.net.spi.nameservice.provider.1", "ns,mock")
- .perm(new java.lang.RuntimePermission(
- "accessClassInPackage.sun.net.spi.nameservice"))
- .perm(new java.util.PropertyPermission(
- "sun.security.krb5.principal", "read"))
- .perm(new javax.security.auth.AuthPermission(
- "modifyPrincipals"))
- .perm(new javax.security.auth.AuthPermission(
- "modifyPrivateCredentials"))
- .perm(new javax.security.auth.AuthPermission("doAs"))
- .perm(new PrivateCredentialPermission(
- "javax.security.auth.kerberos.KeyTab * \"*\"",
- "read"))
- .perm(new javax.security.auth.kerberos.ServicePermission(
- "server/localhost@" + REALM, "accept"))
- .perm(new java.io.FilePermission(
- cwd + File.separator + KTAB, "read"))
- .perm(new javax.security.auth.kerberos.ServicePermission(
- "backend/localhost@" + REALM, "initiate"))
- .debug("S")
- .start();
- Proc pb = Proc.create("BasicProc")
- .args("backend")
- .prop("java.security.krb5.conf", CONF)
- .prop("java.security.manager", "")
- .prop("sun.net.spi.nameservice.provider.1", "ns,mock")
- .perm(new java.lang.RuntimePermission(
- "accessClassInPackage.sun.net.spi.nameservice"))
- .perm(new java.util.PropertyPermission(
- "sun.security.krb5.principal", "read"))
- .perm(new javax.security.auth.AuthPermission(
- "modifyPrincipals"))
- .perm(new javax.security.auth.AuthPermission(
- "modifyPrivateCredentials"))
- .perm(new javax.security.auth.AuthPermission("doAs"))
- .perm(new PrivateCredentialPermission(
- "javax.security.auth.kerberos.KeyTab * \"*\"",
- "read"))
- .perm(new javax.security.auth.kerberos.ServicePermission(
- "backend/localhost@" + REALM, "accept"))
- .perm(new java.io.FilePermission(
- cwd + File.separator + KTAB, "read"))
- .debug("B")
- .start();
+ String[] tmp = System.getProperty("native.krb5.libs", "j=")
+ .split(",");
- // Client and server handshake
- String token = pc.readData();
- ps.println(token);
- token = ps.readData();
- pc.println(token);
- // Server and backend handshake
- token = ps.readData();
- pb.println(token);
- token = pb.readData();
- ps.println(token);
- // wrap/unwrap/getMic/verifyMic and plain text
- token = ps.readData();
- pb.println(token);
- token = pb.readData();
- ps.println(token);
- token = pb.readData();
- ps.println(token);
+ // Library paths. The 1st one is always null which means
+ // Java, "" means the default native lib.
+ String[] libs = new String[tmp.length];
- if ((pc.waitFor() | ps.waitFor() | pb.waitFor()) != 0) {
- throw new Exception();
- }
- } else if (args[0].equals("client")) {
- Context c = Context.fromUserPass(USER, PASS, false);
- c.startAsClient(SERVER, oid);
- c.x().requestCredDeleg(true);
- Proc.binOut(c.take(new byte[0]));
- byte[] token = Proc.binIn();
- c.take(token);
- } else if (args[0].equals("server")) {
- Context s = Context.fromUserKtab(SERVER, KTAB, true);
- s.startAsServer(oid);
- byte[] token = Proc.binIn();
- token = s.take(token);
- Proc.binOut(token);
- Context s2 = s.delegated();
- s2.startAsClient(BACKEND, oid);
- Proc.binOut(s2.take(new byte[0]));
- token = Proc.binIn();
- s2.take(token);
- byte[] msg = "Hello".getBytes();
- Proc.binOut(s2.wrap(msg, true));
- s2.verifyMic(Proc.binIn(), msg);
- String in = Proc.textIn();
- if (!in.equals("Hello")) {
- throw new Exception();
- }
- } else if (args[0].equals("backend")) {
- Context b = Context.fromUserKtab(BACKEND, KTAB, true);
- b.startAsServer(oid);
- byte[] token = Proc.binIn();
- Proc.binOut(b.take(token));
- byte[] msg = b.unwrap(Proc.binIn(), true);
- Proc.binOut(b.getMic(msg));
- Proc.textOut(new String(msg));
+ // Names for each lib above. Use in file names.
+ String[] names = new String[tmp.length];
+
+ boolean hasNative = false;
+
+ for (int i = 0; i < tmp.length; i++) {
+ if (tmp[i].isEmpty()) {
+ throw new Exception("Invalid native.krb5.libs");
+ }
+ String[] pair = tmp[i].split("=", 2);
+ names[i] = pair[0];
+ if (!pair[0].equals("j")) {
+ libs[i] = pair.length > 1 ? pair[1] : "";
+ hasNative = true;
+ }
+ }
+
+ if (hasNative) {
+ kdc.kinit(USER, "base.ccache");
+ }
+
+ // Try the same lib first
+ for (int i = 0; i < libs.length; i++) {
+ once(names[i] + names[i] + names[i],
+ libs[i], libs[i], libs[i]);
+ }
+
+ for (int i = 0; i < libs.length; i++) {
+ for (int j = 0; j < libs.length; j++) {
+ for (int k = 0; k < libs.length; k++) {
+ if (i != j || i != k) {
+ once(names[i] + names[j] + names[k],
+ libs[i], libs[j], libs[k]);
+ }
+ }
+ }
+ }
+ } finally {
+ kdc.terminate();
+ }
+ break;
+ case "client":
+ Context c = args[1].equals("n") ?
+ Context.fromThinAir() :
+ Context.fromUserPass(USER, PASS, false);
+ c.startAsClient(SERVER, oid);
+ c.x().requestCredDeleg(true);
+ c.x().requestMutualAuth(true);
+ Proc.binOut(c.take(new byte[0])); // AP-REQ
+ c.take(Proc.binIn()); // AP-REP
+ Proc.binOut(c.wrap(MSG, true));
+ Proc.binOut(c.getMic(MSG));
+ break;
+ case "server":
+ Context s = args[1].equals("n") ?
+ Context.fromThinAir() :
+ Context.fromUserKtab(SERVER, KTAB_S, true);
+ s.startAsServer(oid);
+ token = Proc.binIn(); // AP-REQ
+ Proc.binOut(s.take(token)); // AP-REP
+ msg = s.unwrap(Proc.binIn(), true);
+ Asserts.assertTrue(Arrays.equals(msg, MSG));
+ s.verifyMic(Proc.binIn(), msg);
+ Context s2 = s.delegated();
+ s2.startAsClient(BACKEND, oid);
+ s2.x().requestMutualAuth(false);
+ Proc.binOut(s2.take(new byte[0])); // AP-REQ
+ msg = s2.unwrap(Proc.binIn(), true);
+ Asserts.assertTrue(Arrays.equals(msg, MSG));
+ s2.verifyMic(Proc.binIn(), msg);
+ break;
+ case "backend":
+ Context b = args[1].equals("n") ?
+ Context.fromThinAir() :
+ Context.fromUserKtab(BACKEND, KTAB_B, true);
+ b.startAsServer(oid);
+ token = b.take(Proc.binIn()); // AP-REQ
+ Asserts.assertTrue(token == null);
+ Proc.binOut(b.wrap(MSG, true));
+ Proc.binOut(b.getMic(MSG));
+ break;
}
}
- // create a native server
- private static Proc ns(Proc p) throws Exception {
- return p
- .env("KRB5_CONFIG", CONF)
- .env("KRB5_KTNAME", KTAB)
- .prop("sun.net.spi.nameservice.provider.1", "ns,mock")
- .prop("sun.security.jgss.native", "true")
- .prop("javax.security.auth.useSubjectCredsOnly", "false")
- .prop("sun.security.nativegss.debug", "true");
+
+ /**
+ * One test run.
+ *
+ * @param label test label
+ * @param lc lib of client
+ * @param ls lib of server
+ * @param lb lib of backend
+ */
+ private static void once(String label, String lc, String ls, String lb)
+ throws Exception {
+
+ Proc pc = proc(lc)
+ .args("client", lc == null ? "j" : "n")
+ .perm(new javax.security.auth.kerberos.ServicePermission(
+ "krbtgt/" + REALM + "@" + REALM, "initiate"))
+ .perm(new javax.security.auth.kerberos.ServicePermission(
+ SERVER + "@" + REALM, "initiate"))
+ .perm(new javax.security.auth.kerberos.DelegationPermission(
+ "\"" + SERVER + "@" + REALM + "\" " +
+ "\"krbtgt/" + REALM + "@" + REALM + "\""))
+ .debug(label + "-C");
+ if (lc == null) {
+ // for Krb5LoginModule::promptForName
+ pc.perm(new PropertyPermission("user.name", "read"));
+ } else {
+ Files.copy(Paths.get("base.ccache"), Paths.get(label + ".ccache"));
+ Set<PosixFilePermission> perms = new HashSet<>();
+ perms.add(PosixFilePermission.OWNER_READ);
+ perms.add(PosixFilePermission.OWNER_WRITE);
+ Files.setPosixFilePermissions(Paths.get(label + ".ccache"),
+ Collections.unmodifiableSet(perms));
+ pc.env("KRB5CCNAME", label + ".ccache");
+ // Do not try system ktab if ccache fails
+ pc.env("KRB5_KTNAME", "none");
+ }
+ pc.start();
+
+ Proc ps = proc(ls)
+ .args("server", ls == null ? "j" : "n")
+ .perm(new javax.security.auth.kerberos.ServicePermission(
+ SERVER + "@" + REALM, "accept"))
+ .perm(new javax.security.auth.kerberos.ServicePermission(
+ BACKEND + "@" + REALM, "initiate"))
+ .debug(label + "-S");
+ if (ls == null) {
+ ps.perm(new PrivateCredentialPermission(
+ "javax.security.auth.kerberos.KeyTab * \"*\"", "read"))
+ .perm(new java.io.FilePermission(KTAB_S, "read"));
+ } else {
+ ps.env("KRB5_KTNAME", KTAB_S);
+ }
+ ps.start();
+
+ Proc pb = proc(lb)
+ .args("backend", lb == null ? "j" : "n")
+ .perm(new javax.security.auth.kerberos.ServicePermission(
+ BACKEND + "@" + REALM, "accept"))
+ .debug(label + "-B");
+ if (lb == null) {
+ pb.perm(new PrivateCredentialPermission(
+ "javax.security.auth.kerberos.KeyTab * \"*\"", "read"))
+ .perm(new java.io.FilePermission(KTAB_B, "read"));
+ } else {
+ pb.env("KRB5_KTNAME", KTAB_B);
+ }
+ pb.start();
+
+ // Client and server
+ ps.println(pc.readData()); // AP-REQ
+ pc.println(ps.readData()); // AP-REP
+
+ ps.println(pc.readData()); // KRB-PRIV
+ ps.println(pc.readData()); // KRB-SAFE
+
+ // Server and backend
+ pb.println(ps.readData()); // AP-REQ
+
+ ps.println(pb.readData()); // KRB-PRIV
+ ps.println(pb.readData()); // KRB-SAFE
+
+ if ((pc.waitFor() | ps.waitFor() | pb.waitFor()) != 0) {
+ throw new Exception("Process failed");
+ }
+ }
+
+ /**
+ * A Proc for a child process.
+ *
+ * @param lib the library. Null is Java. "" is default native lib.
+ */
+ private static Proc proc(String lib) throws Exception {
+ Proc p = Proc.create("BasicProc")
+ .prop("java.security.manager", "")
+ .prop("sun.net.spi.nameservice.provider.1", "ns,mock")
+ .perm(new javax.security.auth.AuthPermission("doAs"));
+ if (lib != null) {
+ p.env("KRB5_CONFIG", CONF)
+ .env("KRB5_TRACE", "/dev/stderr")
+ .prop("sun.security.jgss.native", "true")
+ .prop("sun.security.jgss.lib", lib)
+ .prop("javax.security.auth.useSubjectCredsOnly", "false")
+ .prop("sun.security.nativegss.debug", "true");
+ int pos = lib.lastIndexOf('/');
+ if (pos > 0) {
+ p.env("LD_LIBRARY_PATH", lib.substring(0, pos));
+ p.env("DYLD_LIBRARY_PATH", lib.substring(0, pos));
+ }
+ } else {
+ p.perm(new java.util.PropertyPermission(
+ "sun.security.krb5.principal", "read"))
+ // For Krb5LoginModule::login.
+ .perm(new java.lang.RuntimePermission(
+ "accessClassInPackage.sun.net.spi.nameservice"))
+ .perm(new javax.security.auth.AuthPermission(
+ "modifyPrincipals"))
+ .perm(new javax.security.auth.AuthPermission(
+ "modifyPrivateCredentials"))
+ .prop("sun.security.krb5.debug", "true")
+ .prop("java.security.krb5.conf", CONF);
+ }
+ return p;
}
}
diff --git a/jdk/test/sun/security/krb5/auto/Context.java b/jdk/test/sun/security/krb5/auto/Context.java
index f664605..2c49153 100644
--- a/jdk/test/sun/security/krb5/auto/Context.java
+++ b/jdk/test/sun/security/krb5/auto/Context.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,14 +22,21 @@
*/
import com.sun.security.auth.module.Krb5LoginModule;
-import java.security.Key;
+import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
+import java.security.Key;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.kerberos.KerberosKey;
import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.login.LoginContext;
@@ -40,6 +47,10 @@
import org.ietf.jgss.GSSName;
import org.ietf.jgss.MessageProp;
import org.ietf.jgss.Oid;
+import sun.security.jgss.krb5.Krb5Util;
+import sun.security.krb5.Credentials;
+import sun.security.krb5.internal.ccache.CredentialsCache;
+
import com.sun.security.jgss.ExtendedGSSContext;
import com.sun.security.jgss.InquireType;
import com.sun.security.jgss.AuthorizationDataEntry;
@@ -154,24 +165,36 @@
Map<String, String> map = new HashMap<>();
Map<String, Object> shared = new HashMap<>();
+ if (storeKey) {
+ map.put("storeKey", "true");
+ }
+
if (pass != null) {
- map.put("useFirstPass", "true");
- shared.put("javax.security.auth.login.name", user);
- shared.put("javax.security.auth.login.password", pass);
+ krb5.initialize(out.s, new CallbackHandler() {
+ @Override
+ public void handle(Callback[] callbacks)
+ throws IOException, UnsupportedCallbackException {
+ for (Callback cb: callbacks) {
+ if (cb instanceof NameCallback) {
+ ((NameCallback)cb).setName(user);
+ } else if (cb instanceof PasswordCallback) {
+ ((PasswordCallback)cb).setPassword(pass);
+ }
+ }
+ }
+ }, shared, map);
} else {
map.put("doNotPrompt", "true");
map.put("useTicketCache", "true");
if (user != null) {
map.put("principal", user);
}
- }
- if (storeKey) {
- map.put("storeKey", "true");
+ krb5.initialize(out.s, null, shared, map);
}
- krb5.initialize(out.s, null, shared, map);
krb5.login();
krb5.commit();
+
return out;
}
@@ -452,18 +475,21 @@
out = me.x.wrap(input, 0, input.length, p1);
}
System.out.println(printProp(p1));
+ if ((x.getConfState() && privacy) != p1.getPrivacy()) {
+ throw new Exception("unexpected privacy status");
+ }
return out;
}
}, t);
}
- public byte[] unwrap(byte[] t, final boolean privacy)
+ public byte[] unwrap(byte[] t, final boolean privacyExpected)
throws Exception {
return doAs(new Action() {
@Override
public byte[] run(Context me, byte[] input) throws Exception {
- System.out.printf("unwrap %s privacy from %s: ", privacy?"with":"without", me.name);
- MessageProp p1 = new MessageProp(0, privacy);
+ System.out.printf("unwrap from %s", me.name);
+ MessageProp p1 = new MessageProp(0, true);
byte[] bytes;
if (usingStream) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
@@ -473,6 +499,9 @@
bytes = me.x.unwrap(input, 0, input.length, p1);
}
System.out.println(printProp(p1));
+ if (p1.getPrivacy() != privacyExpected) {
+ throw new Exception("Unexpected privacy: " + p1.getPrivacy());
+ }
return bytes;
}
}, t);
@@ -514,6 +543,10 @@
p1);
}
System.out.println(printProp(p1));
+ if (p1.isUnseqToken() || p1.isOldToken()
+ || p1.isDuplicateToken() || p1.isGapToken()) {
+ throw new Exception("Wrong sequence number detected");
+ }
return null;
}
}, t);
@@ -529,13 +562,27 @@
* @param s2 the receiver
* @throws java.lang.Exception If anything goes wrong
*/
- static public void transmit(final String message, final Context s1,
+ static public void transmit(String message, final Context s1,
+ final Context s2) throws Exception {
+ transmit(message.getBytes(), s1, s2);
+ }
+
+ /**
+ * Transmits a message from one Context to another. The sender wraps the
+ * message and sends it to the receiver. The receiver unwraps it, creates
+ * a MIC of the clear text and sends it back to the sender. The sender
+ * verifies the MIC against the message sent earlier.
+ * @param messageBytes the message
+ * @param s1 the sender
+ * @param s2 the receiver
+ * @throws java.lang.Exception If anything goes wrong
+ */
+ static public void transmit(byte[] messageBytes, final Context s1,
final Context s2) throws Exception {
- final byte[] messageBytes = message.getBytes();
System.out.printf("-------------------- TRANSMIT from %s to %s------------------------\n",
s1.name, s2.name);
byte[] wrapped = s1.wrap(messageBytes, true);
- byte[] unwrapped = s2.unwrap(wrapped, true);
+ byte[] unwrapped = s2.unwrap(wrapped, s2.x.getConfState());
if (!Arrays.equals(messageBytes, unwrapped)) {
throw new Exception("wrap/unwrap mismatch");
}
@@ -616,6 +663,32 @@
}
/**
+ * Saves the tickets to a ccache file.
+ *
+ * @param file pathname of the ccache file
+ * @return true if created, false otherwise.
+ */
+ public boolean ccache(String file) throws Exception {
+ Set<KerberosTicket> tickets
+ = s.getPrivateCredentials(KerberosTicket.class);
+ if (tickets != null && !tickets.isEmpty()) {
+ CredentialsCache cc = null;
+ for (KerberosTicket t : tickets) {
+ Credentials cred = Krb5Util.ticketToCreds(t);
+ if (cc == null) {
+ cc = CredentialsCache.create(cred.getClient(), file);
+ }
+ cc.update(cred.toCCacheCreds());
+ }
+ if (cc != null) {
+ cc.save();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Handshake (security context establishment process) between two Contexts
* @param c the initiator
* @param s the acceptor
diff --git a/jdk/test/sun/security/krb5/auto/DiffSaltParams.java b/jdk/test/sun/security/krb5/auto/DiffSaltParams.java
new file mode 100644
index 0000000..275b827
--- /dev/null
+++ b/jdk/test/sun/security/krb5/auto/DiffSaltParams.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017, 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 8186831
+ * @summary Kerberos ignores PA-DATA with a non-null s2kparams
+ * @compile -XDignore.symbol.file DiffSaltParams.java
+ * @run main/othervm -Dsun.security.krb5.debug=true -Dsun.net.spi.nameservice.provider.1=ns,mock DiffSaltParams
+ */
+
+public class DiffSaltParams {
+
+ public static void main(String[] args) throws Exception {
+
+ OneKDC kdc = new OneKDC(null).writeJAASConf();
+ kdc.addPrincipal("user1", "user1pass".toCharArray(),
+ "hello", new byte[]{0, 0, 1, 0});
+ kdc.addPrincipal("user2", "user2pass".toCharArray(),
+ "hello", null);
+ kdc.addPrincipal("user3", "user3pass".toCharArray(),
+ null, new byte[]{0, 0, 1, 0});
+ kdc.addPrincipal("user4", "user4pass".toCharArray());
+
+ Context.fromUserPass("user1", "user1pass".toCharArray(), true);
+ Context.fromUserPass("user2", "user2pass".toCharArray(), true);
+ Context.fromUserPass("user3", "user3pass".toCharArray(), true);
+ Context.fromUserPass("user4", "user4pass".toCharArray(), true);
+ }
+}
diff --git a/jdk/test/sun/security/krb5/auto/Forwarded.java b/jdk/test/sun/security/krb5/auto/Forwarded.java
new file mode 100644
index 0000000..0bdc3f5
--- /dev/null
+++ b/jdk/test/sun/security/krb5/auto/Forwarded.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, 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 8031111
+ * @summary fix krb5 caddr
+ * @compile -XDignore.symbol.file Forwarded.java
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Forwarded
+ */
+
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.internal.KDCOptions;
+import sun.security.krb5.internal.KDCReqBody;
+import sun.security.krb5.internal.TGSReq;
+
+public class Forwarded {
+
+ public static void main(String[] args) throws Exception {
+
+ new OneKDC(null).setOption(KDC.Option.CHECK_ADDRESSES, true);
+
+ Context c;
+ c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+
+ c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+ c.x().requestCredDeleg(true);
+
+ c.take(new byte[0]);
+ }
+}
diff --git a/jdk/test/sun/security/krb5/auto/KDC.java b/jdk/test/sun/security/krb5/auto/KDC.java
index 02a363d..5805bb6 100644
--- a/jdk/test/sun/security/krb5/auto/KDC.java
+++ b/jdk/test/sun/security/krb5/auto/KDC.java
@@ -27,19 +27,19 @@
import java.net.*;
import java.io.*;
import java.lang.reflect.Method;
-import java.security.SecureRandom;
-import java.time.Instant;
-import java.time.temporal.ChronoUnit;
-import java.time.temporal.TemporalAmount;
-import java.time.temporal.TemporalUnit;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import sun.net.spi.nameservice.NameService;
import sun.net.spi.nameservice.NameServiceDescriptor;
import sun.security.krb5.*;
import sun.security.krb5.internal.*;
import sun.security.krb5.internal.ccache.CredentialsCache;
+import sun.security.krb5.internal.crypto.EType;
import sun.security.krb5.internal.crypto.KeyUsage;
import sun.security.krb5.internal.ktab.KeyTab;
import sun.security.util.DerInputStream;
@@ -50,6 +50,11 @@
/**
* A KDC server.
+ *
+ * Note: By setting the system property native.kdc.path to a native
+ * krb5 installation, this class starts a native KDC with the
+ * given realm and host. It can also add new principals and save keytabs.
+ * Other features might not be available.
* <p>
* Features:
* <ol>
@@ -127,13 +132,21 @@
*/
public class KDC {
- // Under the hood.
-
public static final int DEFAULT_LIFETIME = 39600;
public static final int DEFAULT_RENEWTIME = 86400;
- // The random generator to generate random keys (including session keys)
- private static SecureRandom secureRandom = new SecureRandom();
+ // What etypes the KDC supports. Comma-separated strings. Null for all.
+ // Please note native KDCs might use different names.
+ private static final String SUPPORTED_ETYPES
+ = System.getProperty("kdc.supported.enctypes");
+
+ // The native KDC
+ private final NativeKdc nativeKdc;
+
+ // The native KDC process
+ private Process kdcProc = null;
+
+ // Under the hood.
// Principal db. principal -> pass. A case-insensitive TreeMap is used
// so that even if the client provides a name with different case, the KDC
@@ -141,6 +154,25 @@
private TreeMap<String,char[]> passwords = new TreeMap<>
(String.CASE_INSENSITIVE_ORDER);
+ // Non default salts. Precisely, there should be different salts for
+ // different etypes, pretend they are the same at the moment.
+ private TreeMap<String,String> salts = new TreeMap<>
+ (String.CASE_INSENSITIVE_ORDER);
+
+ // Non default s2kparams for newer etypes. Precisely, there should be
+ // different s2kparams for different etypes, pretend they are the same
+ // at the moment.
+ private TreeMap<String,byte[]> s2kparamses = new TreeMap<>
+ (String.CASE_INSENSITIVE_ORDER);
+
+ // Alias for referrals.
+ private TreeMap<String,KDC> aliasReferrals = new TreeMap<>
+ (String.CASE_INSENSITIVE_ORDER);
+
+ // Alias for local resolution.
+ private TreeMap<String,PrincipalName> alias2Principals = new TreeMap<>
+ (String.CASE_INSENSITIVE_ORDER);
+
// Realm name
private String realm;
// KDC
@@ -213,6 +245,10 @@
* Sensitive accounts can never be delegated.
*/
SENSITIVE_ACCOUNTS,
+ /**
+ * If true, will check if TGS-REQ contains a non-null addresses field.
+ */
+ CHECK_ADDRESSES,
};
//static {
@@ -223,7 +259,8 @@
* A standalone KDC server.
*/
public static void main(String[] args) throws Exception {
- KDC kdc = create("RABBIT.HOLE", "kdc.rabbit.hole", 0, false);
+ int port = args.length > 0 ? Integer.parseInt(args[0]) : 0;
+ KDC kdc = create("RABBIT.HOLE", "kdc.rabbit.hole", port, false);
kdc.addPrincipal("dummy", "bogus".toCharArray());
kdc.addPrincipal("foo", "bar".toCharArray());
kdc.addPrincipalRandKey("krbtgt/RABBIT.HOLE");
@@ -257,7 +294,8 @@
* @return the running KDC instance
* @throws java.io.IOException for any socket creation error
*/
- public static KDC create(String realm, String kdc, int port, boolean asDaemon) throws IOException {
+ public static KDC create(String realm, String kdc, int port,
+ boolean asDaemon) throws IOException {
return new KDC(realm, kdc, port, asDaemon);
}
@@ -297,26 +335,38 @@
*/
public void writeKtab(String tab, boolean append, String... names)
throws IOException, KrbException {
- KeyTab ktab = append ? KeyTab.getInstance(tab) : KeyTab.create(tab);
+ KeyTab ktab = null;
+ if (nativeKdc == null) {
+ ktab = append ? KeyTab.getInstance(tab) : KeyTab.create(tab);
+ }
Iterable<String> entries =
(names.length != 0) ? Arrays.asList(names): passwords.keySet();
for (String name : entries) {
- char[] pass = passwords.get(name);
- int kvno = 0;
- if (Character.isDigit(pass[pass.length-1])) {
- kvno = pass[pass.length-1] - '0';
+ if (name.indexOf('@') < 0) {
+ name = name + "@" + realm;
}
- PrincipalName pn = new PrincipalName(name,
+ if (nativeKdc == null) {
+ char[] pass = passwords.get(name);
+ int kvno = 0;
+ if (Character.isDigit(pass[pass.length - 1])) {
+ kvno = pass[pass.length - 1] - '0';
+ }
+ PrincipalName pn = new PrincipalName(name,
name.indexOf('/') < 0 ?
- PrincipalName.KRB_NT_UNKNOWN :
- PrincipalName.KRB_NT_SRV_HST);
- ktab.addEntry(pn,
+ PrincipalName.KRB_NT_UNKNOWN :
+ PrincipalName.KRB_NT_SRV_HST);
+ ktab.addEntry(pn,
getSalt(pn),
pass,
kvno,
true);
+ } else {
+ nativeKdc.ktadd(name, tab);
+ }
}
- ktab.save();
+ if (nativeKdc == null) {
+ ktab.save();
+ }
}
/**
@@ -362,10 +412,36 @@
* @param pass the password for the principal
*/
public void addPrincipal(String user, char[] pass) {
+ addPrincipal(user, pass, null, null);
+ }
+
+ /**
+ * Adds a new principal to this realm with a given password.
+ * @param user the principal's name. For a service principal, use the
+ * form of host/f.q.d.n
+ * @param pass the password for the principal
+ * @param salt the salt, or null if a default value will be used
+ * @param s2kparams the s2kparams, or null if a default value will be used
+ */
+ public void addPrincipal(
+ String user, char[] pass, String salt, byte[] s2kparams) {
if (user.indexOf('@') < 0) {
user = user + "@" + realm;
}
- passwords.put(user, pass);
+ if (nativeKdc != null) {
+ if (!user.equals("krbtgt/" + realm)) {
+ nativeKdc.addPrincipal(user, new String(pass));
+ }
+ passwords.put(user, new char[0]);
+ } else {
+ passwords.put(user, pass);
+ if (salt != null) {
+ salts.put(user, salt);
+ }
+ if (s2kparams != null) {
+ s2kparamses.put(user, s2kparams);
+ }
+ }
}
/**
@@ -461,12 +537,11 @@
*/
public static void saveConfig(String file, KDC kdc, Object... more)
throws IOException {
- File f = new File(file);
StringBuffer sb = new StringBuffer();
sb.append("[libdefaults]\ndefault_realm = ");
sb.append(kdc.realm);
sb.append("\n");
- for (Object o: more) {
+ for (Object o : more) {
if (o instanceof String) {
sb.append(o);
sb.append("\n");
@@ -474,14 +549,12 @@
}
sb.append("\n[realms]\n");
sb.append(kdc.realmLine());
- for (Object o: more) {
+ for (Object o : more) {
if (o instanceof KDC) {
- sb.append(((KDC)o).realmLine());
+ sb.append(((KDC) o).realmLine());
}
}
- FileOutputStream fos = new FileOutputStream(f);
- fos.write(sb.toString().getBytes());
- fos.close();
+ Files.write(Paths.get(file), sb.toString().getBytes());
}
/**
@@ -492,6 +565,29 @@
return port;
}
+ /**
+ * Register an alias name to be referred to a different KDC for
+ * resolution, according to RFC 6806.
+ * @param alias Alias name (i.e. user@REALM.COM).
+ * @param referredKDC KDC to which the alias is referred for resolution.
+ */
+ public void registerAlias(String alias, KDC referredKDC) {
+ aliasReferrals.remove(alias);
+ aliasReferrals.put(alias, referredKDC);
+ }
+
+ /**
+ * Register an alias to be resolved to a Principal Name locally,
+ * according to RFC 6806.
+ * @param alias Alias name (i.e. user@REALM.COM).
+ * @param user Principal Name to which the alias is resolved.
+ */
+ public void registerAlias(String alias, String user)
+ throws RealmException {
+ alias2Principals.remove(alias);
+ alias2Principals.put(alias, new PrincipalName(user));
+ }
+
// Private helper methods
/**
@@ -501,6 +597,7 @@
private KDC(String realm, String kdc) {
this.realm = realm;
this.kdc = kdc;
+ this.nativeKdc = null;
}
/**
@@ -508,7 +605,9 @@
*/
protected KDC(String realm, String kdc, int port, boolean asDaemon)
throws IOException {
- this(realm, kdc);
+ this.realm = realm;
+ this.kdc = kdc;
+ this.nativeKdc = NativeKdc.get(this);
startServer(port, asDaemon);
}
/**
@@ -517,8 +616,9 @@
*/
private static char[] randomPassword() {
char[] pass = new char[32];
+ Random r = new Random();
for (int i=0; i<31; i++)
- pass[i] = (char)secureRandom.nextInt();
+ pass[i] = (char)('a' + r.nextInt(26));
// The last char cannot be a number, otherwise, keyForUser()
// believes it's a sign of kvno
pass[31] = 'Z';
@@ -580,6 +680,9 @@
if (p.getRealmString() == null) {
pn = pn + "@" + getRealm();
}
+ if (salts.containsKey(pn)) {
+ return salts.get(pn);
+ }
if (passwords.containsKey(pn)) {
try {
// Find the principal name with correct case.
@@ -597,6 +700,29 @@
}
/**
+ * Returns the s2kparams for the principal given the etype.
+ * @param p principal
+ * @param etype encryption type
+ * @return the s2kparams, might be null
+ */
+ protected byte[] getParams(PrincipalName p, int etype) {
+ switch (etype) {
+ case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96:
+ case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96:
+ String pn = p.toString();
+ if (p.getRealmString() == null) {
+ pn = pn + "@" + getRealm();
+ }
+ if (s2kparamses.containsKey(pn)) {
+ return s2kparamses.get(pn);
+ }
+ return new byte[] {0, 0, 0x10, 0};
+ default:
+ return null;
+ }
+ }
+
+ /**
* Returns the key for a given principal of the given encryption type
* @param p the principal
* @param etype the encryption type
@@ -604,7 +730,7 @@
* @return the key
* @throws sun.security.krb5.KrbException for unknown/unsupported etype
*/
- private EncryptionKey keyForUser(PrincipalName p, int etype, boolean server)
+ EncryptionKey keyForUser(PrincipalName p, int etype, boolean server)
throws KrbException {
try {
// Do not call EncryptionKey.acquireSecretKeys(), otherwise
@@ -619,7 +745,7 @@
}
}
return new EncryptionKey(EncryptionKeyDotStringToKey(
- getPassword(p, server), getSalt(p), null, etype),
+ getPassword(p, server), getSalt(p), getParams(p, etype), etype),
etype, kvno);
} catch (KrbException ke) {
throw ke;
@@ -668,17 +794,36 @@
" sends TGS-REQ for " +
service + ", " + tgsReq.reqBody.kdcOptions);
KDCReqBody body = tgsReq.reqBody;
- int[] eTypes = KDCReqBodyDotEType(body);
+ int[] eTypes = filterSupported(KDCReqBodyDotEType(body));
+ if (eTypes.length == 0) {
+ throw new KrbException(Krb5.KDC_ERR_ETYPE_NOSUPP);
+ }
int e2 = eTypes[0]; // etype for outgoing session key
int e3 = eTypes[0]; // etype for outgoing ticket
- PAData[] pas = KDCReqDotPAData(tgsReq);
+ PAData[] pas = tgsReq.pAData;
Ticket tkt = null;
EncTicketPart etp = null;
PrincipalName cname = null;
boolean allowForwardable = true;
+ boolean isReferral = false;
+ if (body.kdcOptions.get(KDCOptions.CANONICALIZE)) {
+ System.out.println(realm + "> verifying referral for " +
+ body.sname.getNameString());
+ KDC referral = aliasReferrals.get(body.sname.getNameString());
+ if (referral != null) {
+ service = new PrincipalName(
+ PrincipalName.TGS_DEFAULT_SRV_NAME +
+ PrincipalName.NAME_COMPONENT_SEPARATOR_STR +
+ referral.getRealm(), PrincipalName.KRB_NT_SRV_INST,
+ this.getRealm());
+ System.out.println(realm + "> referral to " +
+ referral.getRealm());
+ isReferral = true;
+ }
+ }
if (pas == null || pas.length == 0) {
throw new KrbException(Krb5.KDC_ERR_PADATA_TYPE_NOSUPP);
@@ -687,7 +832,6 @@
for (PAData pa: pas) {
if (pa.getType() == Krb5.PA_TGS_REQ) {
APReq apReq = new APReq(pa.getValue());
- EncryptedData ed = apReq.authenticator;
tkt = apReq.ticket;
int te = tkt.encPart.getEType();
EncryptionKey kkey = keyForUser(tkt.sname, te, true);
@@ -705,13 +849,14 @@
PAForUserEnc p4u = new PAForUserEnc(
new DerValue(pa.getValue()), null);
forUserCName = p4u.name;
- System.out.println(realm + "> presenting a PA_FOR_USER "
+ System.out.println(realm + "> See PA_FOR_USER "
+ " in the name of " + p4u.name);
}
}
}
if (forUserCName != null) {
- List<String> names = (List<String>)options.get(Option.ALLOW_S4U2SELF);
+ List<String> names = (List<String>)
+ options.get(Option.ALLOW_S4U2SELF);
if (!names.contains(cname.toString())) {
// Mimic the normal KDC behavior. When a server is not
// allowed to send S4U2self, do not send an error.
@@ -732,11 +877,19 @@
EncryptionKey key = generateRandomKey(e2);
// Check time, TODO
+ KerberosTime from = body.from;
KerberosTime till = body.till;
+ if (from == null || from.isZero()) {
+ from = timeAfter(0);
+ }
+ KerberosTime rtime = body.rtime;
if (till == null) {
throw new KrbException(Krb5.KDC_ERR_NEVER_VALID); // TODO
} else if (till.isZero()) {
- till = new KerberosTime(new Date().getTime() + 1000 * 3600 * 11);
+ till = timeAfter(DEFAULT_LIFETIME);
+ }
+ if (rtime == null && body.kdcOptions.get(KDCOptions.RENEWABLE)) {
+ rtime = timeAfter(DEFAULT_RENEWTIME);
}
boolean[] bFlags = new boolean[Krb5.TKT_OPTS_MAX+1];
@@ -750,13 +903,19 @@
bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true;
}
}
+ // We do not request for addresses for FORWARDED tickets
+ if (options.containsKey(Option.CHECK_ADDRESSES)
+ && body.kdcOptions.get(KDCOptions.FORWARDED)
+ && body.addresses != null) {
+ throw new KrbException(Krb5.KDC_ERR_BADOPTION);
+ }
if (body.kdcOptions.get(KDCOptions.FORWARDED) ||
etp.flags.get(Krb5.TKT_OPTS_FORWARDED)) {
bFlags[Krb5.TKT_OPTS_FORWARDED] = true;
}
if (body.kdcOptions.get(KDCOptions.RENEWABLE)) {
bFlags[Krb5.TKT_OPTS_RENEWABLE] = true;
- //renew = new KerberosTime(new Date().getTime() + 1000 * 3600 * 24 * 7);
+ //renew = timeAfter(3600 * 24 * 7);
}
if (body.kdcOptions.get(KDCOptions.PROXIABLE)) {
bFlags[Krb5.TKT_OPTS_PROXIABLE] = true;
@@ -775,7 +934,8 @@
Map<String,List<String>> map = (Map<String,List<String>>)
options.get(Option.ALLOW_S4U2PROXY);
Ticket second = KDCReqBodyDotFirstAdditionalTicket(body);
- EncryptionKey key2 = keyForUser(second.sname, second.encPart.getEType(), true);
+ EncryptionKey key2 = keyForUser(
+ second.sname, second.encPart.getEType(), true);
byte[] bb = second.encPart.decrypt(key2, KeyUsage.KU_TICKET);
DerInputStream derIn = new DerInputStream(bb);
DerValue der = derIn.getDerValue();
@@ -807,19 +967,29 @@
}
bFlags[Krb5.TKT_OPTS_INITIAL] = true;
+ KerberosTime renewTill = etp.renewTill;
+ if (renewTill != null && body.kdcOptions.get(KDCOptions.RENEW)) {
+ // till should never pass renewTill
+ if (till.greaterThan(renewTill)) {
+ till = renewTill;
+ }
+ if (System.getProperty("test.set.null.renew") != null) {
+ // Testing 8186576, see NullRenewUntil.java.
+ renewTill = null;
+ }
+ }
+
TicketFlags tFlags = new TicketFlags(bFlags);
EncTicketPart enc = new EncTicketPart(
tFlags,
key,
cname,
new TransitedEncoding(1, new byte[0]), // TODO
- new KerberosTime(new Date()),
- body.from,
- till, body.rtime,
- body.addresses != null // always set caddr
- ? body.addresses
- : new HostAddresses(
- new InetAddress[]{InetAddress.getLocalHost()}),
+ timeAfter(0),
+ from,
+ till, renewTill,
+ body.addresses != null ? body.addresses
+ : etp.caddr,
null);
EncryptionKey skey = keyForUser(service, e3, true);
if (skey == null) {
@@ -833,23 +1003,22 @@
);
EncTGSRepPart enc_part = new EncTGSRepPart(
key,
- new LastReq(new LastReqEntry[]{
- new LastReqEntry(0, new KerberosTime(new Date().getTime() - 10000))
+ new LastReq(new LastReqEntry[] {
+ new LastReqEntry(0, timeAfter(-10))
}),
body.getNonce(), // TODO: detect replay
- new KerberosTime(new Date().getTime() + 1000 * 3600 * 24),
+ timeAfter(3600 * 24),
// Next 5 and last MUST be same with ticket
tFlags,
- new KerberosTime(new Date()),
- body.from,
- till, body.rtime,
+ timeAfter(0),
+ from,
+ till, renewTill,
service,
- body.addresses != null // always set caddr
- ? body.addresses
- : new HostAddresses(
- new InetAddress[]{InetAddress.getLocalHost()})
+ body.addresses,
+ null
);
- EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(), KeyUsage.KU_ENC_TGS_REP_PART_SESSKEY);
+ EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(),
+ KeyUsage.KU_ENC_TGS_REP_PART_SESSKEY);
TGSRep tgsRep = new TGSRep(null,
cname,
t,
@@ -870,7 +1039,7 @@
+ " " +ke.returnCodeMessage());
if (kerr == null) {
kerr = new KRBError(null, null, null,
- new KerberosTime(new Date()),
+ timeAfter(0),
0,
ke.returnCode(),
body.cname,
@@ -890,6 +1059,7 @@
*/
protected byte[] processAsReq(byte[] in) throws Exception {
ASReq asReq = new ASReq(in);
+ byte[] asReqbytes = asReq.asn1Encode();
int[] eTypes = null;
List<PAData> outPAs = new ArrayList<>();
@@ -906,9 +1076,29 @@
KDCReqBody body = asReq.reqBody;
- eTypes = KDCReqBodyDotEType(body);
+ eTypes = filterSupported(KDCReqBodyDotEType(body));
+ if (eTypes.length == 0) {
+ throw new KrbException(Krb5.KDC_ERR_ETYPE_NOSUPP);
+ }
int eType = eTypes[0];
+ if (body.kdcOptions.get(KDCOptions.CANONICALIZE)) {
+ PrincipalName principal = alias2Principals.get(
+ body.cname.getNameString());
+ if (principal != null) {
+ body.cname = principal;
+ } else {
+ KDC referral = aliasReferrals.get(body.cname.getNameString());
+ if (referral != null) {
+ body.cname = new PrincipalName(
+ PrincipalName.TGS_DEFAULT_SRV_NAME,
+ PrincipalName.KRB_NT_SRV_INST,
+ referral.getRealm());
+ throw new KrbException(Krb5.KRB_ERR_WRONG_REALM);
+ }
+ }
+ }
+
EncryptionKey ckey = keyForUser(body.cname, eType, false);
EncryptionKey skey = keyForUser(service, eType, true);
@@ -936,8 +1126,12 @@
// Session key
EncryptionKey key = generateRandomKey(eType);
// Check time, TODO
+ KerberosTime from = body.from;
KerberosTime till = body.till;
KerberosTime rtime = body.rtime;
+ if (from == null || from.isZero()) {
+ from = timeAfter(0);
+ }
if (till == null) {
throw new KrbException(Krb5.KDC_ERR_NEVER_VALID); // TODO
} else if (till.isZero()) {
@@ -963,7 +1157,8 @@
if (body.kdcOptions.get(KDCOptions.FORWARDABLE)) {
List<String> sensitives = (List<String>)
options.get(Option.SENSITIVE_ACCOUNTS);
- if (sensitives != null && sensitives.contains(body.cname.toString())) {
+ if (sensitives != null
+ && sensitives.contains(body.cname.toString())) {
// Cannot make FORWARDABLE
} else {
bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true;
@@ -971,7 +1166,7 @@
}
if (body.kdcOptions.get(KDCOptions.RENEWABLE)) {
bFlags[Krb5.TKT_OPTS_RENEWABLE] = true;
- //renew = new KerberosTime(new Date().getTime() + 1000 * 3600 * 24 * 7);
+ //renew = timeAfter(3600 * 24 * 7);
}
if (body.kdcOptions.get(KDCOptions.PROXIABLE)) {
bFlags[Krb5.TKT_OPTS_PROXIABLE] = true;
@@ -993,7 +1188,8 @@
pas2 = new DerValue[] {
new DerValue(new ETypeInfo2(1, null, null).asn1Encode()),
new DerValue(new ETypeInfo2(1, "", null).asn1Encode()),
- new DerValue(new ETypeInfo2(1, realm, new byte[]{1}).asn1Encode()),
+ new DerValue(new ETypeInfo2(
+ 1, realm, new byte[]{1}).asn1Encode()),
};
pas = new DerValue[] {
new DerValue(new ETypeInfo(1, null).asn1Encode()),
@@ -1003,7 +1199,8 @@
break;
case 2: // we still reject non-null s2kparams and prefer E2 over E
pas2 = new DerValue[] {
- new DerValue(new ETypeInfo2(1, realm, new byte[]{1}).asn1Encode()),
+ new DerValue(new ETypeInfo2(
+ 1, realm, new byte[]{1}).asn1Encode()),
new DerValue(new ETypeInfo2(1, null, null).asn1Encode()),
new DerValue(new ETypeInfo2(1, "", null).asn1Encode()),
};
@@ -1054,7 +1251,7 @@
epas[i],
epas[i] == EncryptedData.ETYPE_ARCFOUR_HMAC ?
null : getSalt(body.cname),
- null).asn1Encode());
+ getParams(body.cname, epas[i])).asn1Encode());
}
boolean allOld = true;
for (int i: eTypes) {
@@ -1088,21 +1285,47 @@
outPAs.add(new PAData(Krb5.PA_ETYPE_INFO, eid.toByteArray()));
}
- PAData[] inPAs = KDCReqDotPAData(asReq);
- if (inPAs == null || inPAs.length == 0) {
+ PAData[] inPAs = asReq.pAData;
+ List<PAData> enc_outPAs = new ArrayList<>();
+
+ byte[] paEncTimestamp = null;
+ if (inPAs != null) {
+ for (PAData inPA : inPAs) {
+ if (inPA.getType() == Krb5.PA_ENC_TIMESTAMP) {
+ paEncTimestamp = inPA.getValue();
+ }
+ }
+ }
+
+ if (paEncTimestamp == null) {
Object preauth = options.get(Option.PREAUTH_REQUIRED);
if (preauth == null || preauth.equals(Boolean.TRUE)) {
throw new KrbException(Krb5.KDC_ERR_PREAUTH_REQUIRED);
}
} else {
+ EncryptionKey pakey = null;
try {
- EncryptedData data = newEncryptedData(new DerValue(inPAs[0].getValue()));
- EncryptionKey pakey = keyForUser(body.cname, data.getEType(), false);
+ EncryptedData data = newEncryptedData(
+ new DerValue(paEncTimestamp));
+ pakey = keyForUser(body.cname, data.getEType(), false);
data.decrypt(pakey, KeyUsage.KU_PA_ENC_TS);
} catch (Exception e) {
- throw new KrbException(Krb5.KDC_ERR_PREAUTH_FAILED);
+ KrbException ke = new KrbException(Krb5.KDC_ERR_PREAUTH_FAILED);
+ ke.initCause(e);
+ throw ke;
}
bFlags[Krb5.TKT_OPTS_PRE_AUTHENT] = true;
+ for (PAData pa : inPAs) {
+ if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) {
+ Checksum ckSum = new Checksum(
+ Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128,
+ asReqbytes, ckey, KeyUsage.KU_AS_REQ);
+ enc_outPAs.add(new PAData(Krb5.PA_REQ_ENC_PA_REP,
+ ckSum.asn1Encode()));
+ bFlags[Krb5.TKT_OPTS_ENC_PA_REP] = true;
+ break;
+ }
+ }
}
TicketFlags tFlags = new TicketFlags(bFlags);
@@ -1111,8 +1334,8 @@
key,
body.cname,
new TransitedEncoding(1, new byte[0]),
- new KerberosTime(new Date()),
- body.from,
+ timeAfter(0),
+ from,
till, rtime,
body.addresses,
null);
@@ -1123,19 +1346,21 @@
EncASRepPart enc_part = new EncASRepPart(
key,
new LastReq(new LastReqEntry[]{
- new LastReqEntry(0, new KerberosTime(new Date().getTime() - 10000))
+ new LastReqEntry(0, timeAfter(-10))
}),
body.getNonce(), // TODO: detect replay?
- new KerberosTime(new Date().getTime() + 1000 * 3600 * 24),
+ timeAfter(3600 * 24),
// Next 5 and last MUST be same with ticket
tFlags,
- new KerberosTime(new Date()),
- body.from,
+ timeAfter(0),
+ from,
till, rtime,
service,
- body.addresses
+ body.addresses,
+ enc_outPAs.toArray(new PAData[enc_outPAs.size()])
);
- EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(), KeyUsage.KU_ENC_AS_REP_PART);
+ EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(),
+ KeyUsage.KU_ENC_AS_REP_PART);
ASRep asRep = new ASRep(
outPAs.toArray(new PAData[outPAs.size()]),
body.cname,
@@ -1180,8 +1405,10 @@
if (kerr == null) {
if (ke.returnCode() == Krb5.KDC_ERR_PREAUTH_REQUIRED ||
ke.returnCode() == Krb5.KDC_ERR_PREAUTH_FAILED) {
+ outPAs.add(new PAData(Krb5.PA_ENC_TIMESTAMP, new byte[0]));
+ }
+ if (outPAs.size() > 0) {
DerOutputStream bytes = new DerOutputStream();
- bytes.write(new PAData(Krb5.PA_ENC_TIMESTAMP, new byte[0]).asn1Encode());
for (PAData p: outPAs) {
bytes.write(p.asn1Encode());
}
@@ -1190,7 +1417,7 @@
eData = temp.toByteArray();
}
kerr = new KRBError(null, null, null,
- new KerberosTime(new Date()),
+ timeAfter(0),
0,
ke.returnCode(),
body.cname,
@@ -1268,6 +1495,35 @@
throw new KrbException("Illegal duration format " + s);
}
+ private int[] filterSupported(int[] input) {
+ int count = 0;
+ for (int i = 0; i < input.length; i++) {
+ if (!EType.isSupported(input[i])) {
+ continue;
+ }
+ if (SUPPORTED_ETYPES != null) {
+ boolean supported = false;
+ for (String se : SUPPORTED_ETYPES.split(",")) {
+ if (Config.getType(se) == input[i]) {
+ supported = true;
+ break;
+ }
+ }
+ if (!supported) {
+ continue;
+ }
+ }
+ if (count != i) {
+ input[count] = input[i];
+ }
+ count++;
+ }
+ if (count != input.length) {
+ input = Arrays.copyOf(input, count);
+ }
+ return input;
+ }
+
/**
* Generates a line for a KDC to put inside [realms] of krb5.conf
* @return REALM.NAME = { kdc = host:port etc }
@@ -1292,6 +1548,20 @@
* @throws java.io.IOException for any communication error
*/
protected void startServer(int port, boolean asDaemon) throws IOException {
+ if (nativeKdc != null) {
+ startNativeServer(port, asDaemon);
+ } else {
+ startJavaServer(port, asDaemon);
+ }
+ }
+
+ private void startNativeServer(int port, boolean asDaemon) throws IOException {
+ nativeKdc.prepare();
+ nativeKdc.init();
+ kdcProc = nativeKdc.kdc();
+ }
+
+ private void startJavaServer(int port, boolean asDaemon) throws IOException {
if (port > 0) {
u1 = new DatagramSocket(port, InetAddress.getByName("127.0.0.1"));
t1 = new ServerSocket(port);
@@ -1384,19 +1654,37 @@
}
}
+ public void kinit(String user, String ccache) throws Exception {
+ if (user.indexOf('@') < 0) {
+ user = user + "@" + realm;
+ }
+ if (nativeKdc != null) {
+ nativeKdc.kinit(user, ccache);
+ } else {
+ Context.fromUserPass(user, passwords.get(user), false)
+ .ccache(ccache);
+ }
+ }
+
boolean isReady() {
return udpConsumerReady && tcpConsumerReady && dispatcherReady;
}
public void terminate() {
- try {
- thread1.stop();
- thread2.stop();
- thread3.stop();
- u1.close();
- t1.close();
- } catch (Exception e) {
- // OK
+ if (nativeKdc != null) {
+ System.out.println("Killing kdc...");
+ kdcProc.destroyForcibly();
+ System.out.println("Done");
+ } else {
+ try {
+ thread1.stop();
+ thread2.stop();
+ thread3.stop();
+ u1.close();
+ t1.close();
+ } catch (Exception e) {
+ // OK
+ }
}
}
@@ -1551,8 +1839,270 @@
}
}
+ /**
+ * A native KDC using the binaries in nativePath. Attention:
+ * this is using binaries, not an existing KDC instance.
+ * An implementation of this takes care of configuration,
+ * principal db managing and KDC startup.
+ */
+ static abstract class NativeKdc {
+
+ protected Map<String,String> env;
+ protected String nativePath;
+ protected String base;
+ protected String realm;
+ protected int port;
+
+ NativeKdc(String nativePath, KDC kdc) {
+ if (kdc.port == 0) {
+ kdc.port = 8000 + new java.util.Random().nextInt(10000);
+ }
+ this.nativePath = nativePath;
+ this.realm = kdc.realm;
+ this.port = kdc.port;
+ this.base = Paths.get("" + port).toAbsolutePath().toString();
+ }
+
+ // Add a new principal
+ abstract void addPrincipal(String user, String pass);
+ // Add a keytab entry
+ abstract void ktadd(String user, String ktab);
+ // Initialize KDC
+ abstract void init();
+ // Start kdc
+ abstract Process kdc();
+ // Configuration
+ abstract void prepare();
+ // Fill ccache
+ abstract void kinit(String user, String ccache);
+
+ static NativeKdc get(KDC kdc) {
+ String prop = System.getProperty("native.kdc.path");
+ if (prop == null) {
+ return null;
+ } else if (Files.exists(Paths.get(prop, "sbin/krb5kdc"))) {
+ return new MIT(true, prop, kdc);
+ } else if (Files.exists(Paths.get(prop, "kdc/krb5kdc"))) {
+ return new MIT(false, prop, kdc);
+ } else if (Files.exists(Paths.get(prop, "libexec/kdc"))) {
+ return new Heimdal(prop, kdc);
+ } else {
+ throw new IllegalArgumentException("Strange " + prop);
+ }
+ }
+
+ Process run(boolean wait, String... cmd) {
+ try {
+ System.out.println("Running " + cmd2str(env, cmd));
+ ProcessBuilder pb = new ProcessBuilder();
+ pb.inheritIO();
+ pb.environment().putAll(env);
+ Process p = pb.command(cmd).start();
+ if (wait) {
+ if (p.waitFor() < 0) {
+ throw new RuntimeException("exit code is not null");
+ }
+ return null;
+ } else {
+ return p;
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private String cmd2str(Map<String,String> env, String... cmd) {
+ return env.entrySet().stream().map(e -> e.getKey()+"="+e.getValue())
+ .collect(Collectors.joining(" ")) + " " +
+ Stream.of(cmd).collect(Collectors.joining(" "));
+ }
+ }
+
+ // Heimdal KDC. Build your own and run "make install" to nativePath.
+ static class Heimdal extends NativeKdc {
+
+ Heimdal(String nativePath, KDC kdc) {
+ super(nativePath, kdc);
+ Map<String, String> environment = new HashMap<>();
+ environment.put("KRB5_CONFIG", base + "/krb5.conf");
+ environment.put("KRB5_TRACE", "/dev/stderr");
+ environment.put("DYLD_LIBRARY_PATH", nativePath + "/lib");
+ environment.put("LD_LIBRARY_PATH", nativePath + "/lib");
+ this.env = Collections.unmodifiableMap(environment);
+ }
+
+ @Override
+ public void addPrincipal(String user, String pass) {
+ run(true, nativePath + "/bin/kadmin", "-l", "-r", realm,
+ "add", "-p", pass, "--use-defaults", user);
+ }
+
+ @Override
+ public void ktadd(String user, String ktab) {
+ run(true, nativePath + "/bin/kadmin", "-l", "-r", realm,
+ "ext_keytab", "-k", ktab, user);
+ }
+
+ @Override
+ public void init() {
+ run(true, nativePath + "/bin/kadmin", "-l", "-r", realm,
+ "init", "--realm-max-ticket-life=1day",
+ "--realm-max-renewable-life=1month", realm);
+ }
+
+ @Override
+ public Process kdc() {
+ return run(false, nativePath + "/libexec/kdc",
+ "--addresses=127.0.0.1", "-P", "" + port);
+ }
+
+ @Override
+ public void prepare() {
+ try {
+ Files.createDirectory(Paths.get(base));
+ Files.write(Paths.get(base + "/krb5.conf"), Arrays.asList(
+ "[libdefaults]",
+ "default_realm = " + realm,
+ "default_keytab_name = FILE:" + base + "/krb5.keytab",
+ "forwardable = true",
+ "dns_lookup_kdc = no",
+ "dns_lookup_realm = no",
+ "dns_canonicalize_hostname = false",
+ "\n[realms]",
+ realm + " = {",
+ " kdc = localhost:" + port,
+ "}",
+ "\n[kdc]",
+ "db-dir = " + base,
+ "database = {",
+ " label = {",
+ " dbname = " + base + "/current-db",
+ " realm = " + realm,
+ " mkey_file = " + base + "/mkey.file",
+ " acl_file = " + base + "/heimdal.acl",
+ " log_file = " + base + "/current.log",
+ " }",
+ "}",
+ SUPPORTED_ETYPES == null ? ""
+ : ("\n[kadmin]\ndefault_keys = "
+ + (SUPPORTED_ETYPES + ",")
+ .replaceAll(",", ":pw-salt ")),
+ "\n[logging]",
+ "kdc = 0-/FILE:" + base + "/messages.log",
+ "krb5 = 0-/FILE:" + base + "/messages.log",
+ "default = 0-/FILE:" + base + "/messages.log"
+ ));
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ @Override
+ void kinit(String user, String ccache) {
+ String tmpName = base + "/" + user + "." +
+ System.identityHashCode(this) + ".keytab";
+ ktadd(user, tmpName);
+ run(true, nativePath + "/bin/kinit",
+ "-f", "-t", tmpName, "-c", ccache, user);
+ }
+ }
+
+ // MIT krb5 KDC. Make your own exploded (install == false), or
+ // "make install" into nativePath (install == true).
+ static class MIT extends NativeKdc {
+
+ private boolean install; // "make install" or "make"
+
+ MIT(boolean install, String nativePath, KDC kdc) {
+ super(nativePath, kdc);
+ this.install = install;
+ Map<String, String> environment = new HashMap<>();
+ environment.put("KRB5_KDC_PROFILE", base + "/kdc.conf");
+ environment.put("KRB5_CONFIG", base + "/krb5.conf");
+ environment.put("KRB5_TRACE", "/dev/stderr");
+ environment.put("DYLD_LIBRARY_PATH", nativePath + "/lib");
+ environment.put("LD_LIBRARY_PATH", nativePath + "/lib");
+ this.env = Collections.unmodifiableMap(environment);
+ }
+
+ @Override
+ public void addPrincipal(String user, String pass) {
+ run(true, nativePath +
+ (install ? "/sbin/" : "/kadmin/cli/") + "kadmin.local",
+ "-q", "addprinc -pw " + pass + " " + user);
+ }
+
+ @Override
+ public void ktadd(String user, String ktab) {
+ run(true, nativePath +
+ (install ? "/sbin/" : "/kadmin/cli/") + "kadmin.local",
+ "-q", "ktadd -k " + ktab + " -norandkey " + user);
+ }
+
+ @Override
+ public void init() {
+ run(true, nativePath +
+ (install ? "/sbin/" : "/kadmin/dbutil/") + "kdb5_util",
+ "create", "-s", "-W", "-P", "olala");
+ }
+
+ @Override
+ public Process kdc() {
+ return run(false, nativePath +
+ (install ? "/sbin/" : "/kdc/") + "krb5kdc",
+ "-n");
+ }
+
+ @Override
+ public void prepare() {
+ try {
+ Files.createDirectory(Paths.get(base));
+ Files.write(Paths.get(base + "/kdc.conf"), Arrays.asList(
+ "[kdcdefaults]",
+ "\n[realms]",
+ realm + "= {",
+ " kdc_listen = " + this.port,
+ " kdc_tcp_listen = " + this.port,
+ " database_name = " + base + "/principal",
+ " key_stash_file = " + base + "/.k5.ATHENA.MIT.EDU",
+ SUPPORTED_ETYPES == null ? ""
+ : (" supported_enctypes = "
+ + (SUPPORTED_ETYPES + ",")
+ .replaceAll(",", ":normal ")),
+ "}"
+ ));
+ Files.write(Paths.get(base + "/krb5.conf"), Arrays.asList(
+ "[libdefaults]",
+ "default_realm = " + realm,
+ "default_keytab_name = FILE:" + base + "/krb5.keytab",
+ "forwardable = true",
+ "dns_lookup_kdc = no",
+ "dns_lookup_realm = no",
+ "dns_canonicalize_hostname = false",
+ "\n[realms]",
+ realm + " = {",
+ " kdc = localhost:" + port,
+ "}",
+ "\n[logging]",
+ "kdc = FILE:" + base + "/krb5kdc.log"
+ ));
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ @Override
+ void kinit(String user, String ccache) {
+ String tmpName = base + "/" + user + "." +
+ System.identityHashCode(this) + ".keytab";
+ ktadd(user, tmpName);
+ run(true, nativePath +
+ (install ? "/bin/" : "/clients/kinit/") + "kinit",
+ "-f", "-t", tmpName, "-c", ccache, user);
+ }
+ }
+
// Calling private methods thru reflections
- private static final Field getPADataField;
private static final Field getEType;
private static final Constructor<EncryptedData> ctorEncryptedData;
private static final Method stringToKey;
@@ -1562,8 +2112,6 @@
try {
ctorEncryptedData = EncryptedData.class.getDeclaredConstructor(DerValue.class);
ctorEncryptedData.setAccessible(true);
- getPADataField = KDCReq.class.getDeclaredField("pAData");
- getPADataField.setAccessible(true);
getEType = KDCReqBody.class.getDeclaredField("eType");
getEType.setAccessible(true);
stringToKey = EncryptionKey.class.getDeclaredMethod(
@@ -1585,13 +2133,6 @@
throw new AssertionError(e);
}
}
- private static PAData[] KDCReqDotPAData(KDCReq req) {
- try {
- return (PAData[])getPADataField.get(req);
- } catch (Exception e) {
- throw new AssertionError(e);
- }
- }
private static int[] KDCReqBodyDotEType(KDCReqBody body) {
try {
return (int[]) getEType.get(body);
diff --git a/jdk/test/sun/security/krb5/auto/LifeTimeInSeconds.java b/jdk/test/sun/security/krb5/auto/LifeTimeInSeconds.java
index 9d4c6d7..23c95318 100644
--- a/jdk/test/sun/security/krb5/auto/LifeTimeInSeconds.java
+++ b/jdk/test/sun/security/krb5/auto/LifeTimeInSeconds.java
@@ -40,7 +40,7 @@
int time = cred.getRemainingLifetime();
int time2 = cred.getRemainingInitLifetime(null);
// The test KDC issues a TGT with a default lifetime of 11 hours
- int elevenhrs = 11*3600;
+ int elevenhrs = KDC.DEFAULT_LIFETIME;
if (time > elevenhrs+60 || time < elevenhrs-60) {
throw new Exception("getRemainingLifetime returns wrong value.");
}
diff --git a/jdk/test/sun/security/krb5/auto/NullRenewUntil.java b/jdk/test/sun/security/krb5/auto/NullRenewUntil.java
new file mode 100644
index 0000000..2f7d4a4
--- /dev/null
+++ b/jdk/test/sun/security/krb5/auto/NullRenewUntil.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, 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 8186576
+ * @summary KerberosTicket does not properly handle renewable tickets
+ * at the end of their lifetime
+ * @library /lib/testlibrary/
+ * @compile -XDignore.symbol.file NullRenewUntil.java
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock -Dtest.set.null.renew NullRenewUntil
+ */
+
+import jdk.testlibrary.Asserts;
+import sun.security.krb5.Config;
+
+import javax.security.auth.kerberos.KerberosTicket;
+
+public class NullRenewUntil {
+
+ public static void main(String[] args) throws Exception {
+
+ OneKDC kdc = new OneKDC(null);
+
+ KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
+ "ticket_lifetime = 10s",
+ "renew_lifetime = 11s");
+ Config.refresh();
+
+ KerberosTicket ticket = Context
+ .fromUserPass(OneKDC.USER, OneKDC.PASS, false).s()
+ .getPrivateCredentials(KerberosTicket.class).iterator().next();
+
+ System.out.println(ticket);
+ Asserts.assertTrue(ticket.getRenewTill() != null, ticket.toString());
+
+ Thread.sleep(2000);
+
+ ticket.refresh();
+ System.out.println(ticket);
+ Asserts.assertTrue(ticket.getRenewTill() == null, ticket.toString());
+
+ Thread.sleep(2000);
+ ticket.refresh();
+ System.out.println(ticket);
+ }
+}
diff --git a/jdk/test/sun/security/krb5/auto/ReferralsTest.java b/jdk/test/sun/security/krb5/auto/ReferralsTest.java
new file mode 100644
index 0000000..3361102
--- /dev/null
+++ b/jdk/test/sun/security/krb5/auto/ReferralsTest.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc.
+ * 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 8215032
+ * @run main/othervm/timeout=120 -Dsun.security.krb5.debug=true ReferralsTest
+ * @summary Test Kerberos cross-realm referrals (RFC 6806)
+ */
+
+import java.io.File;
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.security.auth.kerberos.KerberosTicket;
+import javax.security.auth.Subject;
+
+import org.ietf.jgss.GSSName;
+
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.PrincipalName;
+
+public class ReferralsTest {
+ private static final boolean DEBUG = true;
+ private static final String krbConfigName = "krb5-localkdc.conf";
+ private static final String realmKDC1 = "RABBIT.HOLE";
+ private static final String realmKDC2 = "DEV.RABBIT.HOLE";
+ private static final char[] password = "123qwe@Z".toCharArray();
+
+ // Names
+ private static final String clientName = "test";
+ private static final String userName = "user";
+ private static final String serviceName = "http" +
+ PrincipalName.NAME_COMPONENT_SEPARATOR_STR +
+ "server.dev.rabbit.hole";
+ private static final String backendServiceName = "cifs" +
+ PrincipalName.NAME_COMPONENT_SEPARATOR_STR +
+ "backend.rabbit.hole";
+
+ // Alias
+ private static final String clientAlias = clientName +
+ PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC1;
+
+ // Names + realms
+ private static final String clientKDC1Name = clientAlias.replaceAll(
+ PrincipalName.NAME_REALM_SEPARATOR_STR, "\\\\" +
+ PrincipalName.NAME_REALM_SEPARATOR_STR) +
+ PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC1;
+ private static final String clientKDC2Name = clientName +
+ PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC2;
+ private static final String userKDC1Name = userName +
+ PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC1;
+ private static final String serviceKDC2Name = serviceName +
+ PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC2;
+ private static final String backendKDC1Name = backendServiceName +
+ PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC1;
+ private static final String krbtgtKDC1 =
+ PrincipalName.TGS_DEFAULT_SRV_NAME +
+ PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC1;
+ private static final String krbtgtKDC2 =
+ PrincipalName.TGS_DEFAULT_SRV_NAME +
+ PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC2;
+ private static final String krbtgtKDC1toKDC2 =
+ PrincipalName.TGS_DEFAULT_SRV_NAME +
+ PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC2 +
+ PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC1;
+ private static final String krbtgtKDC2toKDC1 =
+ PrincipalName.TGS_DEFAULT_SRV_NAME +
+ PrincipalName.NAME_COMPONENT_SEPARATOR_STR + realmKDC1 +
+ PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC2;
+
+ public static void main(String[] args) throws Exception {
+ try {
+ initializeKDCs();
+ testSubjectCredentials();
+ testDelegation();
+ testImpersonation();
+ testDelegationWithReferrals();
+ } finally {
+ cleanup();
+ }
+ }
+
+ private static void initializeKDCs() throws Exception {
+ KDC kdc1 = KDC.create(realmKDC1, "localhost", 0, true);
+ kdc1.addPrincipalRandKey(krbtgtKDC1);
+ kdc1.addPrincipal(krbtgtKDC2toKDC1, password);
+ kdc1.addPrincipal(krbtgtKDC2, password);
+ kdc1.addPrincipal(userKDC1Name, password);
+ kdc1.addPrincipal(backendServiceName, password);
+
+ KDC kdc2 = KDC.create(realmKDC2, "localhost", 0, true);
+ kdc2.addPrincipalRandKey(krbtgtKDC2);
+ kdc2.addPrincipal(clientKDC2Name, password);
+ kdc2.addPrincipal(serviceName, password);
+ kdc2.addPrincipal(krbtgtKDC1, password);
+ kdc2.addPrincipal(krbtgtKDC1toKDC2, password);
+
+ kdc1.registerAlias(clientAlias, kdc2);
+ kdc1.registerAlias(serviceName, kdc2);
+ kdc2.registerAlias(clientAlias, clientKDC2Name);
+ kdc2.registerAlias(backendServiceName, kdc1);
+
+ kdc1.setOption(KDC.Option.ALLOW_S4U2SELF, Arrays.asList(
+ new String[]{serviceName + "@" + realmKDC2}));
+ Map<String,List<String>> mapKDC1 = new HashMap<>();
+ mapKDC1.put(serviceName + "@" + realmKDC2, Arrays.asList(
+ new String[]{backendKDC1Name}));
+ kdc1.setOption(KDC.Option.ALLOW_S4U2PROXY, mapKDC1);
+
+ Map<String,List<String>> mapKDC2 = new HashMap<>();
+ mapKDC2.put(serviceName + "@" + realmKDC2, Arrays.asList(
+ new String[]{serviceName + "@" + realmKDC2,
+ krbtgtKDC2toKDC1}));
+ kdc2.setOption(KDC.Option.ALLOW_S4U2PROXY, mapKDC2);
+
+ KDC.saveConfig(krbConfigName, kdc1, kdc2,
+ "forwardable=true");
+ System.setProperty("java.security.krb5.conf", krbConfigName);
+ }
+
+ private static void cleanup() {
+ File f = new File(krbConfigName);
+ if (f.exists()) {
+ f.delete();
+ }
+ }
+
+ /*
+ * The client subject (whose principal is
+ * test@RABBIT.HOLE@RABBIT.HOLE) will obtain a TGT after
+ * realm referral and name canonicalization (TGT cname
+ * will be test@DEV.RABBIT.HOLE). With this TGT, the client will request
+ * a TGS for service http/server.dev.rabbit.hole@RABBIT.HOLE. After
+ * realm referral, a http/server.dev.rabbit.hole@DEV.RABBIT.HOLE TGS
+ * will be obtained.
+ *
+ * Assert that we get the proper TGT and TGS tickets, and that they are
+ * associated to the client subject.
+ *
+ * Assert that if we request a TGS for the same service again (based on the
+ * original service name), we don't get a new one but the previous,
+ * already in the subject credentials.
+ */
+ private static void testSubjectCredentials() throws Exception {
+ Subject clientSubject = new Subject();
+ Context clientContext = Context.fromUserPass(clientSubject,
+ clientKDC1Name, password, false);
+
+ Set<Principal> clientPrincipals = clientSubject.getPrincipals();
+ if (clientPrincipals.size() != 1) {
+ throw new Exception("Only one client subject principal expected");
+ }
+ Principal clientPrincipal = clientPrincipals.iterator().next();
+ if (DEBUG) {
+ System.out.println("Client subject principal: " +
+ clientPrincipal.getName());
+ }
+ if (!clientPrincipal.getName().equals(clientKDC1Name)) {
+ throw new Exception("Unexpected client subject principal.");
+ }
+
+ clientContext.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID);
+ clientContext.take(new byte[0]);
+ Set<KerberosTicket> clientTickets =
+ clientSubject.getPrivateCredentials(KerberosTicket.class);
+ boolean tgtFound = false;
+ boolean tgsFound = false;
+ for (KerberosTicket clientTicket : clientTickets) {
+ String cname = clientTicket.getClient().getName();
+ String sname = clientTicket.getServer().getName();
+ if (cname.equals(clientKDC2Name)) {
+ if (sname.equals(krbtgtKDC2 +
+ PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC2)) {
+ tgtFound = true;
+ } else if (sname.equals(serviceKDC2Name)) {
+ tgsFound = true;
+ }
+ }
+ if (DEBUG) {
+ System.out.println("Client subject KerberosTicket:");
+ System.out.println(clientTicket);
+ }
+ }
+ if (!tgtFound || !tgsFound) {
+ throw new Exception("client subject tickets (TGT/TGS) not found.");
+ }
+ int numOfTickets = clientTickets.size();
+ clientContext.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID);
+ clientContext.take(new byte[0]);
+ clientContext.status();
+ int newNumOfTickets =
+ clientSubject.getPrivateCredentials(KerberosTicket.class).size();
+ if (DEBUG) {
+ System.out.println("client subject number of tickets: " +
+ numOfTickets);
+ System.out.println("client subject new number of tickets: " +
+ newNumOfTickets);
+ }
+ if (numOfTickets != newNumOfTickets) {
+ throw new Exception("Useless client subject TGS request because" +
+ " TGS was not found in private credentials.");
+ }
+ }
+
+ /*
+ * The server (http/server.dev.rabbit.hole@DEV.RABBIT.HOLE)
+ * will authenticate on itself on behalf of the client
+ * (test@DEV.RABBIT.HOLE). Cross-realm referrals will occur
+ * when requesting different TGTs and TGSs (including the
+ * request for delegated credentials).
+ */
+ private static void testDelegation() throws Exception {
+ Context c = Context.fromUserPass(clientKDC2Name,
+ password, false);
+ c.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID);
+ Context s = Context.fromUserPass(serviceKDC2Name,
+ password, true);
+ s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+ Context.handshake(c, s);
+ Context delegatedContext = s.delegated();
+ delegatedContext.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID);
+ delegatedContext.x().requestMutualAuth(false);
+ Context s2 = Context.fromUserPass(serviceKDC2Name,
+ password, true);
+ s2.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+
+ // Test authentication
+ Context.handshake(delegatedContext, s2);
+ if (!delegatedContext.x().isEstablished() || !s2.x().isEstablished()) {
+ throw new Exception("Delegated authentication failed");
+ }
+
+ // Test identities
+ GSSName contextInitiatorName = delegatedContext.x().getSrcName();
+ GSSName contextAcceptorName = delegatedContext.x().getTargName();
+ if (DEBUG) {
+ System.out.println("Context initiator: " + contextInitiatorName);
+ System.out.println("Context acceptor: " + contextAcceptorName);
+ }
+ if (!contextInitiatorName.toString().equals(clientKDC2Name) ||
+ !contextAcceptorName.toString().equals(serviceName)) {
+ throw new Exception("Unexpected initiator or acceptor names");
+ }
+ }
+
+ /*
+ * The server (http/server.dev.rabbit.hole@DEV.RABBIT.HOLE)
+ * will get a TGS ticket for itself on behalf of the client
+ * (user@RABBIT.HOLE). Cross-realm referrals will be handled
+ * in S4U2Self requests because the user and the server are
+ * on different realms.
+ */
+ private static void testImpersonation() throws Exception {
+ Context s = Context.fromUserPass(serviceKDC2Name, password, true);
+ s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+ GSSName impName = s.impersonate(userKDC1Name).cred().getName();
+ if (DEBUG) {
+ System.out.println("Impersonated name: " + impName);
+ }
+ if (!impName.toString().equals(userKDC1Name)) {
+ throw new Exception("Unexpected impersonated name");
+ }
+ }
+
+ /*
+ * The server (http/server.dev.rabbit.hole@DEV.RABBIT.HOLE)
+ * will use delegated credentials (user@RABBIT.HOLE) to
+ * authenticate in the backend (cifs/backend.rabbit.hole@RABBIT.HOLE).
+ * Cross-realm referrals will be handled in S4U2Proxy requests
+ * because the server and the backend are on different realms.
+ */
+ private static void testDelegationWithReferrals() throws Exception {
+ Context c = Context.fromUserPass(userKDC1Name, password, false);
+ c.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID);
+ Context s = Context.fromUserPass(serviceKDC2Name, password, true);
+ s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+ Context.handshake(c, s);
+ Context delegatedContext = s.delegated();
+ delegatedContext.startAsClient(backendServiceName,
+ GSSUtil.GSS_KRB5_MECH_OID);
+ delegatedContext.x().requestMutualAuth(false);
+ Context b = Context.fromUserPass(backendKDC1Name, password, true);
+ b.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+
+ // Test authentication
+ Context.handshake(delegatedContext, b);
+ if (!delegatedContext.x().isEstablished() || !b.x().isEstablished()) {
+ throw new Exception("Delegated authentication failed");
+ }
+
+ // Test identities
+ GSSName contextInitiatorName = delegatedContext.x().getSrcName();
+ GSSName contextAcceptorName = delegatedContext.x().getTargName();
+ if (DEBUG) {
+ System.out.println("Context initiator: " + contextInitiatorName);
+ System.out.println("Context acceptor: " + contextAcceptorName);
+ }
+ if (!contextInitiatorName.toString().equals(userKDC1Name) ||
+ !contextAcceptorName.toString().equals(backendServiceName)) {
+ throw new Exception("Unexpected initiator or acceptor names");
+ }
+ }
+}
diff --git a/jdk/test/sun/security/krb5/auto/Renew.java b/jdk/test/sun/security/krb5/auto/Renew.java
new file mode 100644
index 0000000..fdfb488
--- /dev/null
+++ b/jdk/test/sun/security/krb5/auto/Renew.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2015, 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 8058290
+ * @summary JAAS Krb5LoginModule has suspect ticket-renewal logic,
+ * relies on clockskew grace
+ * @compile -XDignore.symbol.file Renew.java
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Renew 1
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Renew 2
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Renew 3
+ */
+
+import sun.security.krb5.Config;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Date;
+import javax.security.auth.kerberos.KerberosTicket;
+
+public class Renew {
+
+ public static void main(String[] args) throws Exception {
+
+ // Three test cases:
+ // 1. renewTGT=false
+ // 2. renewTGT=true with a short life time, renew will happen
+ // 3. renewTGT=true with a long life time, renew won't happen
+ int test = Integer.parseInt(args[0]);
+
+ OneKDC k = new OneKDC(null);
+ KDC.saveConfig(OneKDC.KRB5_CONF, k,
+ "renew_lifetime = 1d",
+ "ticket_lifetime = " + (test == 2? "10s": "8h"));
+ Config.refresh();
+ k.writeJAASConf();
+
+ // KDC would save ccache in a file
+ System.setProperty("test.kdc.save.ccache", "cache.here");
+
+ Files.write(Paths.get(OneKDC.JAAS_CONF), Arrays.asList(
+ "first {",
+ " com.sun.security.auth.module.Krb5LoginModule required;",
+ "};",
+ "second {",
+ " com.sun.security.auth.module.Krb5LoginModule required",
+ " doNotPrompt=true",
+ " renewTGT=" + (test != 1),
+ " useTicketCache=true",
+ " ticketCache=cache.here;",
+ "};"
+ ));
+
+ Context c;
+
+ // The first login uses username and password
+ c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+ Date d1 = c.s().getPrivateCredentials(KerberosTicket.class).iterator().next().getAuthTime();
+
+ // 6s is longer than half of 10s
+ Thread.sleep(6000);
+
+ // The second login uses the cache
+ c = Context.fromJAAS("second");
+ Date d2 = c.s().getPrivateCredentials(KerberosTicket.class).iterator().next().getAuthTime();
+
+ if (test == 2) {
+ if (d1.equals(d2)) {
+ throw new Exception("Ticket not renewed");
+ }
+ } else {
+ if (!d1.equals(d2)) {
+ throw new Exception("Ticket renewed");
+ }
+ }
+ }
+}
diff --git a/jdk/test/sun/security/krb5/auto/Renewal.java b/jdk/test/sun/security/krb5/auto/Renewal.java
new file mode 100644
index 0000000..38639c7
--- /dev/null
+++ b/jdk/test/sun/security/krb5/auto/Renewal.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2012, 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 8044500
+ * @summary Add kinit options and krb5.conf flags that allow users to
+ * obtain renewable tickets and specify ticket lifetimes
+ * @library ../../../../java/security/testlibrary/
+ * @compile -XDignore.symbol.file Renewal.java
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock Renewal
+ */
+
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.Config;
+import sun.security.krb5.internal.ccache.Credentials;
+import sun.security.krb5.internal.ccache.FileCredentialsCache;
+
+import javax.security.auth.kerberos.KerberosTicket;
+import java.util.Date;
+import java.util.Random;
+import java.util.Set;
+
+// The basic krb5 test skeleton you can copy from
+public class Renewal {
+
+ static OneKDC kdc;
+ static String clazz = "sun.security.krb5.internal.tools.Kinit";
+
+ public static void main(String[] args) throws Exception {
+
+ kdc = new OneKDC(null);
+ kdc.writeJAASConf();
+ kdc.setOption(KDC.Option.PREAUTH_REQUIRED, false);
+
+ checkLogin(null, null, KDC.DEFAULT_LIFETIME, -1);
+ checkLogin("1h", null, 3600, -1);
+ checkLogin(null, "2d", KDC.DEFAULT_LIFETIME, 86400*2);
+ checkLogin("1h", "10h", 3600, 36000);
+ // When rtime is before till, use till as rtime
+ checkLogin("10h", "1h", 36000, 36000);
+
+ try {
+ Class.forName(clazz);
+ } catch (ClassNotFoundException cnfe) {
+ return;
+ }
+
+ checkKinit(null, null, null, null, KDC.DEFAULT_LIFETIME, -1);
+ checkKinit("1h", "10h", null, null, 3600, 36000);
+ checkKinit(null, null, "30m", "5h", 1800, 18000);
+ checkKinit("1h", "10h", "30m", "5h", 1800, 18000);
+
+ checkKinitRenew();
+ }
+
+ static int count = 0;
+
+ static void checkKinit(
+ String s1, // ticket_lifetime in krb5.conf, null if none
+ String s2, // renew_lifetime in krb5.conf, null if none
+ String c1, // -l on kinit, null if none
+ String c2, // -r on kinit, null if none
+ int t1, int t2 // expected lifetimes, -1 of unexpected
+ ) throws Exception {
+ KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
+ s1 != null ? ("ticket_lifetime = " + s1) : "",
+ s2 != null ? ("renew_lifetime = " + s2) : "");
+ Proc p = Proc.create(clazz);
+ if (c1 != null) {
+ p.args("-l", c1);
+ }
+ if (c2 != null) {
+ p.args("-r", c2);
+ }
+ count++;
+ p.args(OneKDC.USER, new String(OneKDC.PASS))
+ .inheritIO()
+ .prop("sun.net.spi.nameservice.provider.1", "ns,mock")
+ .prop("java.security.krb5.conf", OneKDC.KRB5_CONF)
+ .env("KRB5CCNAME", "ccache" + count)
+ .start();
+ if (p.waitFor() != 0) {
+ throw new Exception();
+ }
+ FileCredentialsCache fcc =
+ FileCredentialsCache.acquireInstance(null, "ccache" + count);
+ Credentials cred = fcc.getDefaultCreds();
+ checkRough(cred.getEndTime().toDate(), t1);
+ if (cred.getRenewTill() == null) {
+ checkRough(null, t2);
+ } else {
+ checkRough(cred.getRenewTill().toDate(), t2);
+ }
+ }
+
+ static void checkKinitRenew() throws Exception {
+ Proc p = Proc.create(clazz)
+ .args("-R")
+ .inheritIO()
+ .prop("sun.net.spi.nameservice.provider.1", "ns,mock")
+ .prop("java.security.krb5.conf", OneKDC.KRB5_CONF)
+ .env("KRB5CCNAME", "ccache" + count)
+ .start();
+ if (p.waitFor() != 0) {
+ throw new Exception();
+ }
+ }
+
+ static void checkLogin(
+ String s1, // ticket_lifetime in krb5.conf, null if none
+ String s2, // renew_lifetime in krb5.conf, null if none
+ int t1, int t2 // expected lifetimes, -1 of unexpected
+ ) throws Exception {
+ KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
+ s1 != null ? ("ticket_lifetime = " + s1) : "",
+ s2 != null ? ("renew_lifetime = " + s2) : "");
+ Config.refresh();
+
+ Context c;
+ c = Context.fromJAAS("client");
+
+ Set<KerberosTicket> tickets =
+ c.s().getPrivateCredentials(KerberosTicket.class);
+ if (tickets.size() != 1) {
+ throw new Exception();
+ }
+ KerberosTicket ticket = tickets.iterator().next();
+
+ checkRough(ticket.getEndTime(), t1);
+ checkRough(ticket.getRenewTill(), t2);
+ }
+
+ static void checkRough(Date t, int duration) throws Exception {
+ Date now = new Date();
+ if (t == null && duration == -1) {
+ return;
+ }
+ long change = (t.getTime() - System.currentTimeMillis()) / 1000;
+ if (change > duration + 20 || change < duration - 20) {
+ throw new Exception(t + " is not " + duration);
+ }
+ }
+}
diff --git a/jdk/test/sun/security/krb5/auto/SaslGSS.java b/jdk/test/sun/security/krb5/auto/SaslGSS.java
deleted file mode 100644
index d21cfeb..0000000
--- a/jdk/test/sun/security/krb5/auto/SaslGSS.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) 2013, 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 8012082 8019267
- * @summary SASL: auth-conf negotiated, but unencrypted data is accepted,
- * reset to unencrypt
- * @compile -XDignore.symbol.file SaslGSS.java
- * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock SaslGSS
- */
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.sasl.AuthorizeCallback;
-import javax.security.sasl.RealmCallback;
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslServer;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.logging.ConsoleHandler;
-import java.util.logging.Handler;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.ietf.jgss.*;
-import sun.security.jgss.GSSUtil;
-
-public class SaslGSS {
-
- public static void main(String[] args) throws Exception {
-
- String name = "host." + OneKDC.REALM.toLowerCase(Locale.US);
-
- new OneKDC(null).writeJAASConf();
- System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
-
- // Client in JGSS so that it can control wrap privacy mode
- GSSManager m = GSSManager.getInstance();
- GSSContext sc = m.createContext(
- m.createName(OneKDC.SERVER, GSSUtil.NT_GSS_KRB5_PRINCIPAL),
- GSSUtil.GSS_KRB5_MECH_OID,
- null,
- GSSContext.DEFAULT_LIFETIME);
- sc.requestMutualAuth(false);
-
- // Server in SASL
- final HashMap props = new HashMap();
- props.put(Sasl.QOP, "auth-conf");
- SaslServer ss = Sasl.createSaslServer("GSSAPI", "server",
- name, props,
- new CallbackHandler() {
- public void handle(Callback[] callbacks)
- throws IOException, UnsupportedCallbackException {
- for (Callback cb : callbacks) {
- if (cb instanceof RealmCallback) {
- ((RealmCallback) cb).setText(OneKDC.REALM);
- } else if (cb instanceof AuthorizeCallback) {
- ((AuthorizeCallback) cb).setAuthorized(true);
- }
- }
- }
- });
-
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- PrintStream oldErr = System.err;
- System.setErr(new PrintStream(bout));
-
- Logger.getLogger("javax.security.sasl").setLevel(Level.ALL);
- Handler h = new ConsoleHandler();
- h.setLevel(Level.ALL);
- Logger.getLogger("javax.security.sasl").addHandler(h);
-
- byte[] token = new byte[0];
-
- try {
- // Handshake
- token = sc.initSecContext(token, 0, token.length);
- token = ss.evaluateResponse(token);
- token = sc.unwrap(token, 0, token.length, new MessageProp(0, false));
- token[0] = (byte)(((token[0] & 4) != 0) ? 4 : 2);
- token = sc.wrap(token, 0, token.length, new MessageProp(0, false));
- ss.evaluateResponse(token);
- } finally {
- System.setErr(oldErr);
- }
-
- // Talk
- // 1. Client sends a auth-int message
- byte[] hello = "hello".getBytes();
- MessageProp qop = new MessageProp(0, false);
- token = sc.wrap(hello, 0, hello.length, qop);
- // 2. Server accepts it anyway
- ss.unwrap(token, 0, token.length);
- // 3. Server sends a message
- token = ss.wrap(hello, 0, hello.length);
- // 4. Client accepts, should be auth-conf
- sc.unwrap(token, 0, token.length, qop);
- if (!qop.getPrivacy()) {
- throw new Exception();
- }
-
- for (String s: bout.toString().split("\\n")) {
- if (s.contains("KRB5SRV04") && s.contains("NULL")) {
- return;
- }
- }
- System.out.println("=======================");
- System.out.println(bout.toString());
- System.out.println("=======================");
- throw new Exception("Haven't seen KRB5SRV04 with NULL");
- }
-}
diff --git a/jdk/test/sun/security/krb5/config/Duration.java b/jdk/test/sun/security/krb5/config/Duration.java
new file mode 100644
index 0000000..d9c0f39
--- /dev/null
+++ b/jdk/test/sun/security/krb5/config/Duration.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014, 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 8044500
+ * @summary Add kinit options and krb5.conf flags that allow users to
+ * obtain renewable tickets and specify ticket lifetimes
+ * @compile -XDignore.symbol.file Duration.java
+ * @run main Duration
+ */
+import sun.security.krb5.Config;
+import sun.security.krb5.KrbException;
+
+public class Duration {
+ public static void main(String[] args) throws Exception {
+ check("123", 123);
+ check("1:1", 3660);
+ check("1:1:1", 3661);
+ check("1d", 86400);
+ check("1h", 3600);
+ check("1h1m", 3660);
+ check("1h 1m", 3660);
+ check("1d 1h 1m 1s", 90061);
+ check("1d1h1m1s", 90061);
+
+ check("", -1);
+ check("abc", -1);
+ check("1ms", -1);
+ check("1d1d", -1);
+ check("1h1d", -1);
+ check("x1h", -1);
+ check("1h x 1m", -1);
+ check(":", -1);
+ check("1:60", -1);
+ check("1:1:1:1", -1);
+ check("1:1:1:", -1);
+ }
+
+ static void check(String s, int ex) throws Exception {
+ System.out.print("\u001b[1;37;41m" +s + " " + ex);
+ System.out.print("\u001b[m\n");
+ try {
+ int result = Config.duration(s);
+ if (result != ex) throw new Exception("for " + s + " is " + result);
+ } catch (KrbException ke) {
+ ke.printStackTrace();
+ if (ex != -1) throw new Exception();
+ }
+ }
+}
diff --git a/jdk/test/sun/security/lib/cacerts/VerifyCACerts.java b/jdk/test/sun/security/lib/cacerts/VerifyCACerts.java
index 585f1e9..e21e4bc 100644
--- a/jdk/test/sun/security/lib/cacerts/VerifyCACerts.java
+++ b/jdk/test/sun/security/lib/cacerts/VerifyCACerts.java
@@ -26,11 +26,13 @@
* @test
* @bug 8189131 8198240 8191844 8189949 8191031 8196141 8204923 8195774 8199779
* 8209452 8209506 8210432 8195793 8216577 8222089 8222133 8222137 8222136
- * 8223499
+ * 8223499 8225392 8232019 8234245 8233223
* @summary Check root CA entries in cacerts file
*/
+import java.io.ByteArrayInputStream;
import java.io.File;
-import java.io.FileInputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.Certificate;
@@ -50,7 +52,12 @@
+ File.separator + "security" + File.separator + "cacerts";
// The numbers of certs now.
- private static final int COUNT = 88;
+ private static final int COUNT = 93;
+
+ // 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
+ = "22:AA:EB:89:4E:A4:EA:25:CA:3E:DA:0F:F1:2B:FA:05:4B:68:C5:E1:3A:F9:03:40:BF:EF:F5:13:7C:CE:BC:60";
// map of cert alias to SHA-256 fingerprint
@SuppressWarnings("serial")
@@ -233,6 +240,16 @@
"DD:69:36:FE:21:F8:F0:77:C1:23:A1:A5:21:C1:22:24:F7:22:55:B7:3E:03:A7:26:06:93:E8:A2:4B:0F:A3:89");
put("globalsignrootcar6 [jdk]",
"2C:AB:EA:FE:37:D0:6C:A2:2A:BA:73:91:C0:03:3D:25:98:29:52:C4:53:64:73:49:76:3A:3A:B5:AD:6C:CF:69");
+ put("luxtrustglobalroot2ca [jdk]",
+ "54:45:5F:71:29:C2:0B:14:47:C4:18:F9:97:16:8F:24:C5:8F:C5:02:3B:F5:DA:5B:E2:EB:6E:1D:D8:90:2E:D5");
+ put("amazonrootca1 [jdk]",
+ "8E:CD:E6:88:4F:3D:87:B1:12:5B:A3:1A:C3:FC:B1:3D:70:16:DE:7F:57:CC:90:4F:E1:CB:97:C6:AE:98:19:6E");
+ put("amazonrootca2 [jdk]",
+ "1B:A5:B2:AA:8C:65:40:1A:82:96:01:18:F8:0B:EC:4F:62:30:4D:83:CE:C4:71:3A:19:C3:9C:01:1E:A4:6D:B4");
+ put("amazonrootca3 [jdk]",
+ "18:CE:6C:FE:7B:F1:4E:60:B2:E3:47:B8:DF:E8:68:CB:31:D0:2E:BB:3A:DA:27:15:69:F5:03:43:B4:6D:B3:A4");
+ put("amazonrootca4 [jdk]",
+ "E3:5D:28:41:9E:D0:20:25:CF:A6:90:38:CD:62:39:62:45:8D:A5:C6:95:FB:DE:A3:C2:2B:0B:FB:25:89:70:92");
}
};
@@ -256,8 +273,17 @@
public static void main(String[] args) throws Exception {
System.out.println("cacerts file: " + CACERTS);
md = MessageDigest.getInstance("SHA-256");
+
+ byte[] data = Files.readAllBytes(Paths.get(CACERTS));
+ String checksum = toHexString(md.digest(data));
+ if (!checksum.equals(CHECKSUM)) {
+ atLeastOneFailed = true;
+ System.err.println("ERROR: wrong checksum\n" + checksum);
+ System.err.println("Expected checksum\n" + CHECKSUM);
+ }
+
KeyStore ks = KeyStore.getInstance("JKS");
- ks.load(new FileInputStream(CACERTS), "changeit".toCharArray());
+ ks.load(new ByteArrayInputStream(data), "changeit".toCharArray());
// check the count of certs inside
if (ks.size() != COUNT) {
diff --git a/jdk/test/sun/security/mscapi/InteropWithSunRsaSign.java b/jdk/test/sun/security/mscapi/InteropWithSunRsaSign.java
new file mode 100644
index 0000000..5002320
--- /dev/null
+++ b/jdk/test/sun/security/mscapi/InteropWithSunRsaSign.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8205445
+ * @summary Interop test between SunMSCAPI and SunRsaSign on RSASSA-PSS
+ * @requires os.family == "windows"
+ */
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
+import java.util.Random;
+
+public class InteropWithSunRsaSign {
+
+ private static final SecureRandom NOT_SECURE_RANDOM = new SecureRandom() {
+ Random r = new Random();
+ @Override
+ public void nextBytes(byte[] bytes) {
+ r.nextBytes(bytes);
+ }
+ };
+
+ private static boolean allResult = true;
+ private static byte[] msg = "hello".getBytes();
+
+ public static void main(String[] args) throws Exception {
+
+ matrix(new PSSParameterSpec(
+ "SHA-1",
+ "MGF1",
+ MGF1ParameterSpec.SHA1,
+ 20,
+ PSSParameterSpec.TRAILER_FIELD_BC));
+
+ matrix(new PSSParameterSpec(
+ "SHA-256",
+ "MGF1",
+ MGF1ParameterSpec.SHA256,
+ 32,
+ PSSParameterSpec.TRAILER_FIELD_BC));
+
+ matrix(new PSSParameterSpec(
+ "SHA-384",
+ "MGF1",
+ MGF1ParameterSpec.SHA384,
+ 48,
+ PSSParameterSpec.TRAILER_FIELD_BC));
+
+ matrix(new PSSParameterSpec(
+ "SHA-512",
+ "MGF1",
+ MGF1ParameterSpec.SHA512,
+ 64,
+ PSSParameterSpec.TRAILER_FIELD_BC));
+
+ // non-typical salt length
+ matrix(new PSSParameterSpec(
+ "SHA-1",
+ "MGF1",
+ MGF1ParameterSpec.SHA1,
+ 17,
+ PSSParameterSpec.TRAILER_FIELD_BC));
+
+ if (!allResult) {
+ throw new Exception("Failed");
+ }
+ }
+
+ static void matrix(PSSParameterSpec pss) throws Exception {
+
+ System.out.printf("\n%10s%20s%20s%20s %s\n", pss.getDigestAlgorithm(),
+ "KeyPairGenerator", "signer", "verifier", "result");
+ System.out.printf("%10s%20s%20s%20s %s\n",
+ "-------", "----------------", "------", "--------", "------");
+
+ // KeyPairGenerator chooses SPI when getInstance() is called.
+ String[] provsForKPG = {"SunRsaSign", "SunMSCAPI"};
+
+ // "-" means no preferred provider. In this case, SPI is chosen
+ // when initSign/initVerify is called. Worth testing.
+ String[] provsForSignature = {"SunRsaSign", "SunMSCAPI", "-"};
+
+ int pos = 0;
+ for (String pg : provsForKPG) {
+ for (String ps : provsForSignature) {
+ for (String pv : provsForSignature) {
+ System.out.printf("%10d%20s%20s%20s ", ++pos, pg, ps, pv);
+ try {
+ boolean result = test(pg, ps, pv, pss);
+ System.out.println(result);
+ if (!result) {
+ allResult = false;
+ }
+ } catch (Exception e) {
+ if (pg.equals("-") || pg.equals(ps)) {
+ // When Signature provider is automatically
+ // chosen or the same with KeyPairGenerator,
+ // this is an error.
+ allResult = false;
+ System.out.println("X " + e.getMessage());
+ } else {
+ // Known restriction: SunRsaSign and SunMSCAPI can't
+ // use each other's private key for signing.
+ System.out.println(e.getMessage());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ static boolean test(String pg, String ps, String pv, PSSParameterSpec pss)
+ throws Exception {
+
+ KeyPairGenerator kpg = pg.length() == 1
+ ? KeyPairGenerator.getInstance("RSA")
+ :KeyPairGenerator.getInstance("RSA", pg);
+ kpg.initialize(
+ pss.getDigestAlgorithm().equals("SHA-512") ? 2048: 1024,
+ NOT_SECURE_RANDOM);
+ KeyPair kp = kpg.generateKeyPair();
+ PrivateKey pr = kp.getPrivate();
+ PublicKey pu = kp.getPublic();
+
+ Signature s = ps.length() == 1
+ ? Signature.getInstance("RSASSA-PSS")
+ : Signature.getInstance("RSASSA-PSS", ps);
+ s.initSign(pr);
+ s.setParameter(pss);
+ s.update(msg);
+ byte[] sig = s.sign();
+
+ Signature s2 = pv.length() == 1
+ ? Signature.getInstance("RSASSA-PSS")
+ : Signature.getInstance("RSASSA-PSS", pv);
+ s2.initVerify(pu);
+ s2.setParameter(pss);
+ s2.update(msg);
+
+ return s2.verify(sig);
+ }
+}
diff --git a/jdk/test/sun/security/mscapi/KeyAlgorithms.java b/jdk/test/sun/security/mscapi/KeyAlgorithms.java
new file mode 100644
index 0000000..98796e3
--- /dev/null
+++ b/jdk/test/sun/security/mscapi/KeyAlgorithms.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8213009
+ * @summary Make sure SunMSCAPI keys have correct algorithm names
+ * @requires os.family == "windows"
+ * @library /lib/testlibrary
+ */
+
+import java.security.*;
+
+import jdk.testlibrary.Asserts;
+import jdk.testlibrary.SecurityTools;
+
+public class KeyAlgorithms {
+
+ private static final String ALIAS = "8213009";
+ private static final String ALG = "RSA";
+
+ public static void main(String[] arg) throws Exception {
+
+ SecurityTools.keytool("-genkeypair",
+ "-storetype", "Windows-My",
+ "-keyalg", ALG,
+ "-alias", ALIAS,
+ "-dname", "cn=" + ALIAS,
+ "-noprompt").shouldHaveExitValue(0);
+
+ try {
+ test(loadKeysFromKeyStore());
+ } finally {
+ KeyStore ks = KeyStore.getInstance("Windows-MY");
+ ks.load(null, null);
+ ks.deleteEntry(ALIAS);
+ ks.store(null, null);
+ }
+
+ test(generateKeys());
+ }
+
+ static KeyPair loadKeysFromKeyStore() throws Exception {
+ KeyStore ks = KeyStore.getInstance("Windows-MY");
+ ks.load(null, null);
+ return new KeyPair(ks.getCertificate(ALIAS).getPublicKey(),
+ (PrivateKey) ks.getKey(ALIAS, null));
+ }
+
+ static KeyPair generateKeys() throws Exception {
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALG, "SunMSCAPI");
+ return kpg.generateKeyPair();
+ }
+
+ static void test(KeyPair kp) {
+ Asserts.assertEQ(kp.getPrivate().getAlgorithm(), ALG);
+ Asserts.assertEQ(kp.getPublic().getAlgorithm(), ALG);
+ }
+}
diff --git a/jdk/test/sun/security/mscapi/NullKey.java b/jdk/test/sun/security/mscapi/NullKey.java
new file mode 100644
index 0000000..9f7f24c
--- /dev/null
+++ b/jdk/test/sun/security/mscapi/NullKey.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.security.InvalidKeyException;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.util.*;
+
+/**
+ * @test
+ * @bug 8225180
+ * @requires os.family == "windows"
+ * @summary SunMSCAPI Signature should throw InvalidKeyException when
+ * initialized with a null key
+ */
+
+public class NullKey {
+ public static void main(String[] args) throws Exception {
+ List<String> algs = Arrays.asList(
+ "SHA256withRSA", "SHA256withECDSA", "RSASSA-PSS");
+ for (String alg : algs) {
+ Signature sig = Signature.getInstance(alg, "SunMSCAPI");
+ try {
+ sig.initSign(null);
+ } catch (InvalidKeyException e) {
+ // Expected
+ }
+ try {
+ sig.initVerify((PublicKey)null);
+ } catch (InvalidKeyException e) {
+ // Expected
+ }
+ }
+ }
+}
diff --git a/jdk/test/sun/security/mscapi/SignedObjectChain.java b/jdk/test/sun/security/mscapi/SignedObjectChain.java
index 9790daa..45176de 100644
--- a/jdk/test/sun/security/mscapi/SignedObjectChain.java
+++ b/jdk/test/sun/security/mscapi/SignedObjectChain.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,8 @@
/*
* @test
- * @bug 8050374
+ * @bug 8050374 8146293
+ * @library /lib
* @compile ../../../java/security/SignedObject/Chain.java
* @summary Verify a chain of signed objects
*/
diff --git a/jdk/test/sun/security/mscapi/VeryLongAlias.java b/jdk/test/sun/security/mscapi/VeryLongAlias.java
new file mode 100644
index 0000000..7fee43d
--- /dev/null
+++ b/jdk/test/sun/security/mscapi/VeryLongAlias.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8223063
+ * @requires os.family == "windows"
+ * @library /lib/testlibrary
+ * @summary Support CNG RSA keys
+ */
+
+import jdk.testlibrary.SecurityTools;
+import jdk.testlibrary.ProcessTools;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.KeyStore;
+import java.security.MessageDigest;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.cert.X509Certificate;
+import java.util.List;
+import java.util.Random;
+
+public class VeryLongAlias {
+
+ static String alias = String.format("%0512d", new Random().nextInt(100000));
+
+ public static void main(String[] args) throws Throwable {
+
+ SecurityTools.keytool("-genkeypair -storetype pkcs12 -keystore ks"
+ + " -storepass changeit -keyalg RSA -dname CN=A -alias "
+ + alias);
+
+ KeyStore ks = KeyStore.getInstance("PKCS12");
+
+ try (FileInputStream fis = new FileInputStream("ks")) {
+ ks.load(fis, "changeit".toCharArray());
+ }
+
+ String id = ((X509Certificate)ks.getCertificate(alias))
+ .getSerialNumber().toString(16);
+ try {
+ // Importing pkcs12 file. Long alias is only supported by CNG.
+ //ProcessTools.executeCommand("certutil", "-v", "-p", "changeit",
+ // "-csp", "Microsoft Software Key Storage Provider",
+ // "-user", "-importpfx", "MY", "ks", "NoRoot,NoExport")
+ // Adapt for Win7 as it only support a subset of above arguments
+ ProcessTools.executeCommand("certutil", "-v", "-p", "changeit",
+ "-user", "-importpfx", "ks", "NoRoot")
+ .shouldHaveExitValue(0);
+ test();
+ } finally {
+ ProcessTools.executeCommand("certutil", "-user", "-delstore", "MY",
+ id);
+ }
+ }
+
+ static void test() throws Exception {
+
+ char[] pass = "changeit".toCharArray();
+
+ KeyStore k1 = KeyStore.getInstance("Windows-MY");
+ k1.load(null, null);
+
+ KeyStore k2 = KeyStore.getInstance("PKCS12");
+
+ try (FileInputStream fis = new FileInputStream("ks")) {
+ k2.load(fis, pass);
+ }
+
+ PrivateKey p1 = (PrivateKey)k1.getKey(alias, null);
+ PublicKey u1 = k1.getCertificate(alias).getPublicKey();
+
+ PrivateKey p2 = (PrivateKey)k2.getKey(alias, pass);
+ PublicKey u2 = k2.getCertificate(alias).getPublicKey();
+
+ System.out.println(p1.toString());
+ System.out.println(u1.toString());
+ if (!p1.toString().contains("type=CNG")) {
+ throw new Exception("Not a CNG key");
+ }
+
+ testSignature(p1, u1);
+ testSignature(p1, u2);
+ testSignature(p2, u1);
+ testSignature(p2, u2);
+ }
+
+ static void testSignature(PrivateKey p, PublicKey u) throws Exception {
+ byte[] data = "hello".getBytes();
+
+ String[] ALGS = {
+ "NONEwithRSA", "SHA1withRSA",
+ "SHA256withRSA", "SHA512withRSA"
+ };
+
+ for (String alg : ALGS) {
+ if (alg.contains("NONE")) {
+ data = MessageDigest.getInstance("SHA-256").digest(data);
+ }
+ Signature s1 = Signature.getInstance(alg);
+ Signature s2 = Signature.getInstance(alg);
+ s1.initSign(p);
+ s2.initVerify(u);
+ s1.update(data);
+ s2.update(data);
+ if (!s2.verify(s1.sign())) {
+ throw new Exception("Error");
+ }
+ }
+ }
+}
diff --git a/jdk/test/sun/security/provider/DSA/TestMaxLengthDER.java b/jdk/test/sun/security/provider/DSA/TestMaxLengthDER.java
new file mode 100644
index 0000000..a4f447c
--- /dev/null
+++ b/jdk/test/sun/security/provider/DSA/TestMaxLengthDER.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017, 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 8183591
+ * @summary Test decoding of DER length fields containing Integer.MAX_VALUE
+ * @run main TestMaxLengthDER
+ */
+
+import java.io.*;
+import java.math.*;
+import java.security.*;
+import java.security.spec.*;
+
+public class TestMaxLengthDER {
+
+ public static void main(String[] args) throws Exception {
+
+ String message = "Message";
+ Signature sig = Signature.getInstance("SHA256withDSA");
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
+ SecureRandom rnd = new SecureRandom();
+ rnd.setSeed(1);
+ kpg.initialize(2048, rnd);
+ KeyPair kp = kpg.generateKeyPair();
+ sig.initSign(kp.getPrivate());
+ sig.update(message.getBytes());
+ byte[] sigData = sig.sign();
+
+ // Set the length of the second integer to Integer.MAX_VALUE
+ // First copy all the signature data to the correct location
+ int lengthPos = sigData[3] + 5;
+ byte[] modifiedSigData = new byte[sigData.length + 4];
+ System.arraycopy(sigData, 0, modifiedSigData, 0, lengthPos);
+ System.arraycopy(sigData, lengthPos + 1, modifiedSigData,
+ lengthPos + 5, sigData.length - (lengthPos + 1));
+
+ // Increase the length (in bytes) of the sequence to account for
+ // the larger length field
+ modifiedSigData[1] += 4;
+
+ // Modify the length field
+ modifiedSigData[lengthPos] = (byte) 0x84;
+ modifiedSigData[lengthPos + 1] = (byte) 0x7F;
+ modifiedSigData[lengthPos + 2] = (byte) 0xFF;
+ modifiedSigData[lengthPos + 3] = (byte) 0xFF;
+ modifiedSigData[lengthPos + 4] = (byte) 0xFF;
+
+ sig.initVerify(kp.getPublic());
+ sig.update(message.getBytes());
+
+ try {
+ sig.verify(modifiedSigData);
+ throw new RuntimeException("No exception on misencoded signature");
+ } catch (SignatureException ex) {
+ if (ex.getCause() instanceof EOFException) {
+ // this is expected
+ } else {
+ throw ex;
+ }
+ }
+ }
+}
diff --git a/jdk/test/sun/security/provider/MessageDigest/SHA512.java b/jdk/test/sun/security/provider/MessageDigest/SHA512.java
new file mode 100644
index 0000000..d5042e4
--- /dev/null
+++ b/jdk/test/sun/security/provider/MessageDigest/SHA512.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import jdk.testlibrary.Asserts;
+
+import java.security.MessageDigest;
+import java.util.Arrays;
+
+/**
+ * @test
+ * @bug 8051408
+ * @library /lib/testlibrary
+ * @summary testing SHA-512/224 and SHA-512/256.
+ */
+public class SHA512 {
+ public static void main(String[] args) throws Exception {
+
+ MessageDigest md;
+
+ // Test vectors obtained from
+ // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA512_224.pdf
+ md = MessageDigest.getInstance("SHA-512/224");
+ Asserts.assertTrue(Arrays.equals(md.digest("abc".getBytes()),
+ xeh("4634270F 707B6A54 DAAE7530 460842E2 0E37ED26 5CEEE9A4 3E8924AA")));
+ Asserts.assertTrue(Arrays.equals(md.digest((
+ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" +
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu").getBytes()),
+ xeh("23FEC5BB 94D60B23 30819264 0B0C4533 35D66473 4FE40E72 68674AF9")));
+
+ // Test vectors obtained from
+ // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA512_256.pdf
+ md = MessageDigest.getInstance("SHA-512/256");
+ Asserts.assertTrue(Arrays.equals(md.digest("abc".getBytes()),
+ xeh("53048E26 81941EF9 9B2E29B7 6B4C7DAB E4C2D0C6 34FC6D46 E0E2F131 07E7AF23")));
+ Asserts.assertTrue(Arrays.equals(md.digest((
+ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" +
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu").getBytes()),
+ xeh("3928E184 FB8690F8 40DA3988 121D31BE 65CB9D3E F83EE614 6FEAC861 E19B563A")));
+ }
+
+ static byte[] xeh(String in) {
+ in = in.replaceAll(" ", "");
+ int len = in.length() / 2;
+ byte[] out = new byte[len];
+ for (int i = 0; i < len; i++) {
+ out[i] = (byte)Integer.parseInt(in.substring(i * 2, i * 2 + 2), 16);
+ }
+ return out;
+ }
+}
diff --git a/jdk/test/sun/security/rsa/SigGen15_186-3.txt b/jdk/test/sun/security/rsa/SigGen15_186-3.txt
new file mode 100644
index 0000000..f50c837
--- /dev/null
+++ b/jdk/test/sun/security/rsa/SigGen15_186-3.txt
@@ -0,0 +1,341 @@
+# CAVS 11.4
+# "SigGen PKCS#1 Ver1.5" information
+# Combinations selected:Mod Size 2048 with SHA-224 SHA-256 SHA-384 SHA-512; Mod Size 3072 with SHA-224 SHA-256 SHA-384 SHA-512
+
+
+[mod = 2048]
+
+n = cea80475324c1dc8347827818da58bac069d3419c614a6ea1ac6a3b510dcd72cc516954905e9fef908d45e13006adf27d467a7d83c111d1a5df15ef293771aefb920032a5bb989f8e4f5e1b05093d3f130f984c07a772a3683f4dc6fb28a96815b32123ccdd13954f19d5b8b24a103e771a34c328755c65ed64e1924ffd04d30b2142cc262f6e0048fef6dbc652f21479ea1c4b1d66d28f4d46ef7185e390cbfa2e02380582f3188bb94ebbf05d31487a09aff01fcbb4cd4bfd1f0a833b38c11813c84360bb53c7d4481031c40bad8713bb6b835cb08098ed15ba31ee4ba728a8c8e10f7294e1b4163b7aee57277bfd881a6f9d43e02c6925aa3a043fb7fb78d
+
+e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000260445
+d = 0997634c477c1a039d44c810b2aaa3c7862b0b88d3708272e1e15f66fc9389709f8a11f3ea6a5af7effa2d01c189c50f0d5bcbe3fa272e56cfc4a4e1d388a9dcd65df8628902556c8b6bb6a641709b5a35dd2622c73d4640bfa1359d0e76e1f219f8e33eb9bd0b59ec198eb2fccaae0346bd8b401e12e3c67cb629569c185a2e0f35a2f741644c1cca5ebb139d77a89a2953fc5e30048c0e619f07c8d21d1e56b8af07193d0fdf3f49cd49f2ef3138b5138862f1470bd2d16e34a2b9e7777a6c8c8d4cb94b4e8b5d616cd5393753e7b0f31cc7da559ba8e98d888914e334773baf498ad88d9631eb5fe32e53a4145bf0ba548bf2b0a50c63f67b14e398a34b0d
+
+
+SHAAlg = SHA224
+Msg = 74230447bcd492f2f8a8c594a04379271690bf0c8a13ddfc1b7b96413e77ab2664cba1acd7a3c57ee5276e27414f8283a6f93b73bd392bd541f07eb461a080bb667e5ff095c9319f575b3893977e658c6c001ceef88a37b7902d4db31c3e34f3c164c47bbeefde3b946bad416a752c2cafcee9e401ae08884e5b8aa839f9d0b5
+S = 27da4104eace1991e08bd8e7cfccd97ec48b896a0e156ce7bdc23fd570aaa9a00ed015101f0c6261c7371ceca327a73c3cecfcf6b2d9ed920c9698046e25c89adb2360887d99983bf632f9e6eb0e5df60715902b9aeaa74bf5027aa246510891c74ae366a16f397e2c8ccdc8bd56aa10e0d01585e69f8c4856e76b53acfd3d782b8171529008fa5eff030f46956704a3f5d9167348f37021fc277c6c0a8f93b8a23cfbf918990f982a56d0ed2aa08161560755adc0ce2c3e2ab2929f79bfc0b24ff3e0ff352e6445d8a617f1785d66c32295bb365d61cfb107e9993bbd93421f2d344a86e4127827fa0d0b2535f9b1d547de12ba2868acdecf2cb5f92a6a159a
+
+SHAAlg = SHA224
+Msg = 9af2c5a919e5dadc668799f365fc23da6231437ea51ca5314645425043851f23d00d3704eeabb5c43f49674a19b7707dd9aa3d657a04ba8c6655c5ab8ba2e382b26631080cd79ec40e6a587b7f99840bd0e43297ab1690e4cec95d031a2ca131e7049cfb9bf1fca67bf353cdc12cc74ceee80c5d61da8f0129a8f4a218abc3f6
+S = c5dfbefd35cec846e2c7b2434dc9c46a5a9b1b6ce65b2b18665aedb1404de1f466e024f849eec308c2d2f2f0193df1898a581c9ea32581185553b171b6507082617c5c018afe0c3af64d2ec5a563795aa585e77753cd18836f6f0c29535f6200ca899928fe78e949b0a216ec47a6adf2223e17236cfc167cf00ed6136f03cf6ffd4f3f7787aeb005840978d8d6ba593d4f4cfe6920be102b9847d10140dff86b0db14ffccc9a96e673c672c1128ae45489d2cbfe6e195ca5206eda519cad3d6e0abf4653e36b5a264e87494a4d63ee91ff7c35a6ab12adfa3bb537f6198b06f5de0717076b0ec83ae0da9ea419cc0c96669d1d7c9e529271428401e09e04888a
+
+SHAAlg = SHA224
+Msg = 59b5b85b9dc246d30a3fc8a2de3c9dfa971643b0c1f7c9e40c9c87e4a15b0c4eb664587560474c06a9b65eece38c91703c0fa5a592728a03889f1b52d93309caecc91578a97b83e38ca6cbf0f7ee9103cd82d7673ca172f0da5ebadef4a08605226c582b1f67d4b2d8967777c36985f972f843be688c67f22b61cd529baa6b48
+S = 29b5ac417226444bc8570a279e0e561a4c39707bdbea936064ed603ba96889eb3d786b1999b5180cd5d0611788837a9df1496bacea31cbf8f24a1a2232d4158913c963f5066aad4b65e617d0903359696d759d84c1392e22c246d5f5bed4b806f4091d5e8f71a513f1319bb4e56971cd3e168c9a7e2789832293991a73d3027072ecee6863514549029fb3553478c8f4103bf62d7de1fb53fe76ce9778ada3bb9efa62da44cd00d02bb0eb7488ac24da3814c653cba612301373837a0c3f11885493cbf3024c3572eaed396d0ebb8039ddf843c218d8bc7783549046c33586fb3428562cb8046090040c0e4eea50a19a428bde34626277ff48a84faa189b5440
+
+SHAAlg = SHA224
+Msg = 49a5f3930ad45aca5e22caac6646f0bede1228838d49f8f2e0b2dd27d26a4b590e7eef0c58b9378829bb1489994bff3882ef3a5ae3b958c88263ff1fd69fedb823a839dbe71ddb2f750f6f75e05936761a2f5e3a5dfa837bca63755951ae3c50d04a59667fa64fa98b4662d801159f61eefd1c8bc5b581f500dac73f0a424007
+S = 604eb637ca54bea5ad1fd3165911f3baa2e06c859dc73945a38bca7ff9bfa9ed39435348623d3e60f1ce487443840c6b2c000f1582e8526067a5e8923f1a1bdaabb1a40c0f49ee6906a4c8fc9b8cfa6d07c2cc5bdf2ada65c53d79548089c524fa364319a90d46213febdce6db795914cbda04d7bbbf26bbb299fc7d1449dcc81d139e3c33d4c1de96473994730a4b639633d677db25695ffd157e591bddead03dd2f1c1b8f5c8a213b785879bf7c9a992bb11dd5e91df3aff0931ca76c406230a19e307f33419c9d9d3f6f64bf8881c0ddf74a5716cbc433329368d6e55f1f751d7b9f9b0a26eb5811772f5f698530efc1eaceee6e1dc6839b2133c2fccfa8c
+
+SHAAlg = SHA224
+Msg = 9bfc4dac8c2232387216a532ce62d98c1aafa35c65dc388e3d4d37d6d186eae957f8c9edac1a3f2e3abcb1121f99bd4f8c2bbf5b6ac39a2544d8b502619f43ea30ddc8e4eafad8bf7256220380e0ae27fee46304b224cc8a1e2b1cb2a4de6fb3ee5452798de78653e08b01ec385f367c3982963f8428572793ed74cee369f5ae
+S = 444f7efbfef586fad431e17fea1a2d59f19b3d619bb6fa3664301833a4db1243459e31aa6a703b22572f0912754e56f7231a55ac7abca514c79d9fb3564214b4af835d7d1eaf2b58ceb6a344f1c36890f5e83b50188c0147d6d1156da289ccf4bdb0b9a66f1e4a1f2643591d5ffb53702cf70ddf351592575488f1929010aca37714b234eeb5b952b9323ae26533e9ecd516df26392d1254228bd9ca21a369bb6ab0a33d5eb44cee92b0ea7471ffe5fa43c21de2a8975d4c5c8e185fcb7aab33d88a8365ddf0119c108803c56288643a056e781abd4a0242a92e2529d405efcfd4248662cfbb332d6e6fad6aceb90b5b58a5541abe07bef25d9d89215e398426
+
+SHAAlg = SHA224
+Msg = bf5ff1968a39f809de73e6a8014fc6e8df159367f46340da6cc5fb468985b37446c5d89f3aca626fbe9b142b52cb022a3d93518a74243e25bd3a61c114f533874ee5cfb7fc63f599922854b7c9180949415f63f16bbfe9a8a6289ef8a88a836d20e75e4699acba6fa2412fb42cdfe32f33a25102a1df494c6fb738550decaa0c
+S = 017e053d1ef85c43193a0009a903952aaf400fbcfee9c028975777ab540d2d22ab5c25f4cf1d3794afac6697e1f243829052a84e2843cc0e254dbac1021572999f2dcafab58b9dfef2fcaf701e431bdcd16dbef110095bcfba501059d7994dad5b0b54d0812a4380a1f0ba8ec2bcba768bf5b544695626a5f395e784d4b2962fb7533818de1d6ec686edc9f66868ad03ee64361a6cb91fd8ef536ca6454d16c537c07aa42923e62057df9dd9e7fa4ad0384f35721f6eb3b816d352a095c605d5c10e0a7a2e8640e27307cd44b9d71ac50c0043caca28ae8d6f8fa5bb483158a4e415ef6cfad47f34c0042a2d588ace0f1371d93865397bd21516da2cc15e909c
+
+SHAAlg = SHA224
+Msg = 2ff4fcd0be260bf4a0d73112d0e5649c0bef5bbcdf15423a05ffb2a1f021e09da63d15a8cf295ee50bd2844c89813e08d65da61df232ea4ea970443e20772cd5af11cce5ee40b40e133bcfdf7bb3953d865a8309a8a6c8fdbdd242d79d27a8baf17909d145f475355e19fa11cd03d204c4efdac629fb460fe92e93b48fb9be13
+S = abee5c868f850c17794f021ee9709cc2301320dd246fb3eadb7802a300a98a67083a2e4e250df13314c25453b898110801f7e7acb9b694644e5c4a2623dff1884913c05e636fe77ed5155d954ee38f1262c6c2e38d1114cf6cc5143c7277c8649f5a423f83dfd5f829d9dc74aa4b2fcdc8960cde5ce146b289136064b13bd0d36a1e64a261d680fb7e23d2ae92efb743c3db54609eca7a1be0e47e6f724dc5cf61cb2a369c2bb173f2c6cfecb9a887d583d277b8e30b24ec8549c4d53ba3988642a61f1f939f0f3898005c5d13aaaa54bcb8ae83b72b3cb644b9439d1d2accc800271d23e52f98480d270fad6aced512252ee98332af903563d982d8cbdefb7d
+
+SHAAlg = SHA224
+Msg = b5dca1532dffda0831cb2d21ebd1bdca23c9319c6427fdcc5aefe3a27fc9b92df7586c36b7c84572eda66bfb9cf5aa01877e72bd516723a7e20787e90df9a0136f6fa5109ac9475973673868d8bbee7086a2a54b3af4a3b41759bfb6485f2464e6ca53cb1c2c672589b59d50e54b137ee8ddd02d67f5055ac18d92f17924cc89
+S = 9ae5b9633f9adc7ff923d8875748bc6220dd8f6781b3d46d6008ae69fda072d205f87a12d54c3c7ecc85b88b6ef4770eeb4b71debeff8401e329f6b3e8dc8a9af13a533b60b962930bc0ce3d65d0b5a276e85a0c74f459fb072992991ba96849023478ab28d381aa67d22c9c3b092a023f06c96e11fd2f1b4d9daf0f3449de1797612a8113d6e626cc3f995e1c110e65d17c636c92929f913639a97cd049155830dc0f76049123be3d3d79159fc2b4258e94b8bf808d7c46beefe6df0a83037d15a72a581d8adedd8f013b38f5502d736d1d2f04b0e5dc22eb1a414e52b1a9e8735e0592288c9e5a0a78531e95974a5d48860f8e5b04ebd3eb56ad12adc46ec7
+
+SHAAlg = SHA224
+Msg = 1e563fc3ad027a9cc606be19b258bf70dd8b5273e296236ee8d7a65331585014f05006515bedd6330250e5985fdaa870aea65766ff569fc48913989041cff6fbabcd83fdf064cd3932001b261c69a670bd48069c96e7ebecf1380d82751966c7f8d69e0e94efc775fd1c4a0c118f213ab179475cd0cf6daec94eef6ff6bd0640
+S = 80d3ff1f74a81095d0baa2e9de248c0312ca5a817bc9f5156a293d80896adec5507ee8f2df417afe8779668e25b46f49e4357a7170531ed30761103dbb994135b510d91db9fe1f1268f437e0f3a7a4ba6a4d0b9eb70dfc09fed4b44b35608501c2dfd7a230a28dad14926da4600ba785e496212e57738dd575b40c23347b1635ecdf2b9194d96b1450a6876aa76d04aa5947cce71d85121e0bf578e81cf78c6a047e30fc1d87cfd3019de4bb48294c25860b450355bc2662aa36d6e33f00ad79257d2d8b91f73f27c32a9afcb1e1f015f77cb6b0df51fb39ee1bd76ac42c20791d79cf3f363fb324db30ee82bcc1df1a9564330c12a549659bd3010001573133
+
+SHAAlg = SHA224
+Msg = 900ae7e2e7e5f615750c4ee4c13cca8f9f450714a6b273f2e4aca632d11cf6a8821045771f601ed39791010b92f9fac6a824788cd0775d891b13528ea2fd5d59bc7bb51675c1d5263ccccf1edc8fe313ae4d50150c466af90895ed5c5e5991e4a813dec9d14f4294cc8761278644acfe198635b44266c1c915fa1fa2ef79b9d1
+S = 39c64891d9ac4741a57dd8aec7f7243613d155df4492814b40ceabee79eadb8d8bc5fa611bdebe0e0d9714c43d6d29ef309f782bc8e68a4d317ce1ece468552305a73db9d0d2891e2804f4201b1bf8a3246fa082adde1fc9b3d299f88cb93b7b47fe9f73137096c2b8c59ec0612a085363c04cc374769a964feaf1f8e491381e16d7ae2a0c672e69a3667310feed012156dca630a68d339ec80496c6b594fed17091d3a1c6ac3e4da1419b05d589cb32468288f7df4daaceff5a39bcf297dc508ce9549f602e973edbc2aa44332ec3661b19c8c58c5616924beb892f77b5e200d6fb3fc759263a749d157eff9f736798d281b25b71fb470bdb700f211f841db7
+
+SHAAlg = SHA256
+Msg = 5af283b1b76ab2a695d794c23b35ca7371fc779e92ebf589e304c7f923d8cf976304c19818fcd89d6f07c8d8e08bf371068bdf28ae6ee83b2e02328af8c0e2f96e528e16f852f1fc5455e4772e288a68f159ca6bdcf902b858a1f94789b3163823e2d0717ff56689eec7d0e54d93f520d96e1eb04515abc70ae90578ff38d31b
+S = 6b8be97d9e518a2ede746ff4a7d91a84a1fc665b52f154a927650db6e7348c69f8c8881f7bcf9b1a6d3366eed30c3aed4e93c203c43f5528a45de791895747ade9c5fa5eee81427edee02082147aa311712a6ad5fb1732e93b3d6cd23ffd46a0b3caf62a8b69957cc68ae39f9993c1a779599cdda949bdaababb77f248fcfeaa44059be5459fb9b899278e929528ee130facd53372ecbc42f3e8de2998425860406440f248d817432de687112e504d734028e6c5620fa282ca07647006cf0a2ff83e19a916554cc61810c2e855305db4e5cf893a6a96767365794556ff033359084d7e38a8456e68e21155b76151314a29875feee09557161cbc654541e89e42
+
+SHAAlg = SHA256
+Msg = c43011f3ee88c9c9adcac8bf37221afa31769d347dec705e53aca98993e74606591867ccd289ba1b4f19365f983e0c578346da76c5e2228a07e4fc9b3d4807163371a52b68b66873201dc7d6b56616ac2e4cb522120787df7f15a5e8763a54c179c635d65816bc19485de3eb35a52040591094fe0e6485a7e0c60e38e7c61551
+S = aa3a4e12eb87596c711c9a22bcabcb9dadffcabcecbd16228889e9bb457d5d22571a72f034be4783384f43ce6fffc60534b8331cdd5d7c77f49180bfd194b5fd43a508c66d786c558876735894e6a9300952de792f747045e74d87fd50980230707a34a4df013ce050bbff0d6f570885c9c7bf8dc499132caee071b41d81ff91b8ce21aa2f282cbf52389f239afe1490890be21f9d808b3d70b97efd59c0b60e466088bb42714f212bc90db7e942ebcee60e7b107fff44fb3564ff07d6d02850215fd357d897c4d32bef8661689f2d84ff897637fb6d5568a7270e783426b74b7037493e5155fd7cb3ddddfd36bd8a9c877d71d2a966057c08263d2939c84987
+
+SHAAlg = SHA256
+Msg = 61d7b3150131351e7b4c8e5645d38be9335b40289af34cc6b6fc5e48493bf8b7852c73982c99441ef66c7d9d33c29742b1406e02e0aa8dd034b1ac13cb0d775750cc91421fead9caa921eca61a02eb023a457e77915e183acf517d946bc68292896014fd214b7c8c5e14e15944be0f9296127771f736766e4f81dab3708ea2d0
+S = 84e92a145ae6be1ff9242d9ed2d68de668e802524e8ac0a79de62fe74048c35491fd2ffdb185057e666dbfaac84c34fde7891263f8b2bc74746230320f67a7bd7319c9b9de4190547014e2d7a2a5060d6200aadc3a44bac029ff3992edd30ec53ab0d9123eaa6b147352a073a98161e64f394bb99492c6977e24f445c7125bfb90f87faf262272134acb18823a99a5228d1495463297fd774877fb63d4918106347e6f29315e48363f39b33299eaa32d8da71b229d8ffee5f66f722ad3aa4175d3f84ece9cc8eca8d6f2f356a85c1524896c18f7b5c8f9bcdef45c496d539179891ddc76e5208ad8353d48c624054f3440eeba4432a10654a11ef53783bd116f
+
+SHAAlg = SHA256
+Msg = b6771ab0e128b41b32b8b05e05add23ce0fb877b40bfcc3b992f4c8698d1c828abecbcc1c33d401859ea2cb2afbc7fa4588802a5faee2867534639287ad8af84674be18db661de1da8e19c6b6bd452dd9bf3221d0861fb6fba96be42329b9f04f37dcf3b41fc58d2298348b0c15d1190b125300cf27e0dfad60522fc49846053
+S = 6276925568626f0cbe6f5150b050e1702582f8daf99a6f880ef75cd96c2d4208fb6e91b01ba6aba2a816b2d3cb975df850b1d268c4662dd1ea3a300c1d7171c633dd2efbac3000c56ab80f989dbc18243e636ba5d4d26a7d3f1965ad3cb0f1a8513f998003f7b67e2ac5c718cb688b3201d56e68f0b9f86257b84794cdffbc1fe3ea24b7bb6e9ef0539bd4fbc1afb55bc1dca39996ea8a63769f6e225707f69047555e1a4ef3c639c5f2a497b889424a90148639bb64df0a06e0b7f0e8ed466a977baca32f482337b2abe3983eaec3fe1075016e5867521760fd0607d799f1766b3ff6e2ae155d69250f8bf08c8edca0b4f31d0f838cfd298cb7312df93f0997
+
+SHAAlg = SHA256
+Msg = 6a81cb6c7b268f4b9fb9172adbbb36a237a0dcf1c3c83a95dcb0271aac6ac330f04a5a00fee38bc00631a98598186159660d9d8e4c14a9528dea94836083dac4abb73fd00e38fe0e23c7236604a736540e52193ae56c33fbb8f5cfc5c7c2be2e222e4483b30d325c7ee14f742851fcb8b6d6189e98b822b8e6399d89e90fb997
+S = b67991050c083e645097db03fff34758868beb19e9c0c48475f0f913361e71d3d6f27a8c4f0b269b49e8534039e53ad3bab9a3e62abe078ee75e7fb5959006fbfb014ca7b81b3d5afe0ee5f6fc2dfbc450f2839543002f33f4f354f827278c76c041686eea7886ebb2a7afa5995c6cddb1c0b58066ddb8dc54a6927c146c3b2a0fa7cef28903c6c672bc20ef68ffbfab247eb688ab4bde7106d9c59d2153096dc9e5207267038d88e2174e76adc1508ae24eb602332e53c0c2e33154a66a97a0f12f66c61258c7bf6bbf3f1dcbe9caf2fd30ec68c0a9d09f4fd776304b540e62fc8512beaabc4be2107a1ec18e87f61f9db25e871dc0693cef17c2a687fc854f
+
+SHAAlg = SHA256
+Msg = 056c1e4644599e3183dd8d2f64e4bb2352ff00d012ab763f9ad6e560279f7ff38a5ecea9c2e4ea87d004ef8cc752ae93232aa37b5bf42884baa7e7fc6a8c951cd245de2d220d9bee2b414b3a7520c1e68bcf1ae99a9ff2bf3a93d80f8c1dfe8b85293517895c192e3c9e898295d65be334f44d62f5353eb6c5a29edfb4db2309
+S = ae05204e409d727eb9e4dc24be8f863328c2813da4fcef28866e21a5dab21a485321b735274af06bf17e271518e11164d722ab073548f02e1b441923db6f1cee65a017edfbaf3361c67fbc2b39fe038cb5cb65a640f95887389ce8a5ad2ec6e69d3d603505b025f6d6330c8b648802caf7e6fa3fe7b38141659986cb89e6232f106222564d5e5195eda6a25f99068572c2fafe97f147f7f2f4119f21385af1fced97f78632d8bf4fd9a9054d8b9aa2a9f4ded587847a91d42c6391125f103ae288547e8489693ae8686b84891b772b10c4796883f66cd459a8c1a6a4187bd6b387d349e92d7b604953727c9e9fdc449e7345e7ca6b339e26b086f5548898cbe9
+
+SHAAlg = SHA256
+Msg = cec5c9b6f84497ac327f68ef886641fec995178b307192304374115efcc5ee96270c03db0b846d674c528f9d10155a3f61becce1d3a2b79d66cdc409ad99b7663080f51a102f4361e9dbd03ffcd876b98e683d448bd1217e6fb2151c66964723b2caa65c4e6ca201d1c532bd94d91cd4173b719da126563927ca0a7f6fe42536
+S = c48a8e01d4bbfe0f2f05659337ea71d21f38d7f7a10b00b06e1f899eaf40a8e97ead64bca37f13a55ef1cf3fb52cee279cdcb096085a467afa97b03d78d6076e472b12d6be9647cec32d8d91a26247693771687460ba5269de18e1edef6022533a9579f91d584f9e0cee1100c447b77576b1b4ee163ed4700147a9aa61bdc4e2316d2d818c1028ed1c3e372c9f6a1745572444637248091b83f7b539f9bd58b7675676034c20e4ca119b91c4ca5dc76acbff3d0462898352c591c2ca6f2d8b09e2e6338a84336e06f0cc020e9eb8da785889b497f3b98e827ee7a7d3f1b0b73c1958e16aa97861e6675970ce31d9d119bb340be80fd0f43c3dbe64f2a59d629d
+
+SHAAlg = SHA256
+Msg = 9193f8b914dfe0e62521f35afa4fa5d42835e198af673809377a3e7a99733142a180dc0e13e6bb7ceb3b60e5e9d515794d82c392e07913423391d22e2bb19aa0bd88afd7f77e27a240ea4e2de085481ac31ff8d37990211f82f2cbf4c90de98d6e1338bbc88e6a80ab9684dae64785dd107248048593abc9ab03f1737a6f6530
+S = 5c2fe453a8b08c90b02eb2c9994242d518f3f21b368895cffd624050e48aa714005ae675fe79aa3cadd4df55bdf12bec5be8a41d87538f7e031b782e34d392468e5f14bc613b8f4d28c8fb79a2537e1e601031da720acd7b2c8dcbe9858624a7a9a92a06f91845f732370d67365c6464f7b68f22eb3edfeec97e3285024d7f6943b6d50a16cc96d60f680351deaa25f0bc868948607a6ba7f1949b85943c6a92bd6172e81bcc055014b78a733972e3f39d14099d1607a20ff8681c29ae1ef99ef115ed6a1084b514b81a69d4a15ce1e2576fdcf2b2af615b52fec70132112dcc5bc19ec17f32281460623420317353e8a255fda502bd1fb11a58832ae2c04f9a
+
+SHAAlg = SHA256
+Msg = 0e57ef40b021bf87f642c5756b6515a0e06c15a01856d716c566a6edb381dfdf44d9033b1cc809e61dfef9a096dfb689b7271be449d04a1a9c354102c077af5ff72005ab6b06cf131d7345c21e821d6201cca4e090440d70be6009d2dd7a98d311751e1605a3b914dce6d2626b16f233a5a3d71d567cc820152f25e473514242
+S = 7643aa3fe63e66f79d6b409d145ea820c9f7356f71b4acdcbd43fe1e99f8802cd1662b16240f5cfd94a769b0b3f2cb0b11887e886e5ba43733367490b3fc188f2fb3a0c0c8a68b5d2726c8f7a31902b6b86cd402287d385c3e3c06503ce17fd6e54e582f4a907a91f952d2a360e2fba00028e4d3b02aabf7d220b31d1f8ee7faa070147682ccc8bcc756ca6a68fc20954550c317e87918781a3d1f1923503091090c3c60ca1c0b1c699906fbf85aa70ad9ae48709ff743b82dcc31074cfcea623ea45e48644b19a21772ca107ed64239c56574a087f1a6aadf0f4b00ffe581c1410274c875e4599063e46e5168803f0d28d21fcd3509b4c6222995add7753bf3
+
+SHAAlg = SHA256
+Msg = 0c8491fc348d341fe85c46a56115f26035c59e6a2be765c44e2ec83d407ea096d13b57e3d0c758342246c47510a56793e5daeae1b96d4ab988378966876aa341b7d1c31bba59b7dbe6d1a16898eef0caca928f8ce84d5c64e025dc1679922d95e5cd3c6b994a385c5c8346469ef8764c0c74f5336191850c7f7e2b14be0027d8
+S = cacc8d9f5ecd34c143488461135c4951676145c6e472b92f12f758046f172142fa388f285f3fff068242028829047e248059ed4fd39d2c5ade469dc7c39345e5114950d2031cc7465fe712c4041d05c756d3f2d88a46ceb99f2e24a52e958a03cd2519a9b137e62d5ca2b353f7b047b625c3602313fdb53c8db23d83951a599db328fedc4ae06da89ce7f56259b5c8222f7bd3d9740478fd28e5810db78aee8623fdd39f603f8ddf98081d7873980c4eb0e22a9cd408f7c4134c12d2049a2d120f4b62e6b382b997fc375ef7ac955fcf80b045c3d6385ff422dad350c68870539068a162a2edbb93ceefed9677939b90bd3dfa0dc053460b4e2332efa692179a
+
+SHAAlg = SHA384
+Msg = 6cd59fdd3efd893d091afdc3155d354f10d6d88167427a2cf7246207e51791a6ca6200a914cd2834a9b3c79fcd59e26e457e0683bc33d49267edbdd6e5d90902696f1e7b1a4affc4ba371339868c28015ebbb73e262669866c35db974ba69e468f2583b9191d15d686cd66fb0b9e0ff0a3b4721a6dc342f14f2446b4e028595b
+S = 3974900bec3fcb081f0e5a299adf30d087aabaa633911410e87a4979bbe3fa80c3abcf221686399a49bc2f1e5ac40c35df1700e4b9cb7c805a896646573f4a570a9704d2a2e6baee4b43d916906884ad3cf283529ea265e8fcb5cc1bdf7b7dee85941e4b4fb25c1fc7b951fb129ab393cb069be271c1d954da3c43674309f1d212826fabb8e812de2d53d12597de040d32cb28c9f813159cb18c1b51f7a874cbf229cc222caeb98e35ec5e4bf5c5e22cc8528631f15117e8c2be6eac91f4070eecdd07ecc6db6c46eaa65f472f2006988efef0b51c538c6e04d7519c8e3da4b172b1e2761089ed3ad1197992ef37c168dc881c8b5f8bbfee919f7c7afd25b8fc
+
+SHAAlg = SHA384
+Msg = acb30be9092b2f18f25934a0d678b6bcd6b67c2b88e75884f47b4fcae3adfa405afe2c7e61e2d6c508b92790ac00f76b77c965082668bf900f70a33762de6413af93af2ea8086fda293ded4475f23c4cc31ad494f98d7dd7b7fd6f7d972bb76cb35adc206804c3fe5acdd0e5b8b54e07c29111f788bc5902f40afac30afdbaf2
+S = b5c60d8da9b3943878cb2359cf65e4817c0794f950453ca77c81a5a1c1585591aa50a67468e3b399e4faf1d606bea0d9e6cc1d2d70db8063739e0c27d3dc9f9afe88dea52e73298a07d05c7d9707002efa537c389e38bd37bca74eb0af6261a5da06136202c8ad487eebd50bef74767089c70870be1d8fab9156f9fdbc2f2e9cc330a95018ce7943984becc25621bfa66018ef8320b60059f941156e9cdd87ff0d82cf7be77465e0203e7120aaeced84abd8186947d4ac3daf3f993902aec47c3090475c857b5d359f0a5572d4688e5a76a4653868ff54ce9f999e6bb559d1c11c67c15be9d7fe5f8c1704301d055f3d2907722779d6012036084e950de36f4f
+
+SHAAlg = SHA384
+Msg = 601a6aad3faa7988d5ae528a6969031b10a6f39216946aa89fd4532c8ed141f9a650b126ef488f7c5cf3fb2daa254cc28bdd55560419e80214ef999896dac4946852d24fcd9fb77610eebfbb6ba58bca26f4567f03ac7e56da553f23817bc103ee485592a058fb5e3bc8299c7290c71a29137e75dbf5328c3a2dcd34165b3f2e
+S = 301d60d56576f3663a7fbe8036bbe4fbc0fbd82cd6a42e36d7bbc8b206543dc2d56d3198e7911ad138cad222dd99050dd1f85fe19c8a88bf67135e7f8f11b5f5e485c91fc7d478069b72f46ebcdcf2d2ae7de6ac8fe53bb6c04911d122cc231dc210b2147ebe8b052e8b2ccc09f338b349de2025cc87b2619a7b163347ca66a34791a2e46b4e2ac57eb9f6029cdbe024e896d57f7d0491f7783312f8f06c790770150cd139f61fd2b3e7041b37261c6e7ea86d4e06d9300b1a5667cb0288c550b2afb355944834b461cead13794276bb46e5e20aec7b63aaca4d491a500facd59a37c52779cf467d74af1e62b1ebe0fd0be1cacb7ce6d050d86e4eb76cde0693
+
+SHAAlg = SHA384
+Msg = 44d3e0fc90100a1c9316063f26b180326cc2e3834ce56e4324528a0bbb015b3d7812958cd26b91bf08a3a0b1121f9f9dd77acb98a02ad75fcd613c53c732d1c235f59b6873ece6363f279452b6a4b65e80bb59fd47b9a2936dcc1e4dfe1f5362e3459b9859db3209a2698d27fa8aedfecd4d35b927daf8686c59d700490f0aa3
+S = af2229e94a857b89e0e890daca3a8fe12ebdba04948d1883a7d7816a3b682f7da3032540a8769f9ccac9586cf24e8c204b45b85d1bdcc5a5450a215b4048ea42983b3456fa8c76c6786e024f705e088d694559d668caa8684cad0fc57850fcaf34e458aee8fad4e09e6f196557d4e8860284d982c0105d98ce4912e96c3550e2a0c7e8bad5abc29a9a542f57a8c60579038067b3d5391abc21b4f9deb024ca58f9b0c38c0d1f82373f528e939bd73a24d501c591168814c872c525db0e56cae47df00fa3728dc3a0976965323ce8d2dee2b138b50ab7afd48495114673e91bb3ed2205e26a8455474c3d4ec8739bbff6df39b2b72ee050410930423b1472b6ed
+
+SHAAlg = SHA384
+Msg = 5af09077a1f534b89822b26c3272adf8500d3c6bd90f9b5e0d8b211f16d0720ee0eaf6462b6c8a80df6d75359fd19d03a0cafb52bc9d4c37c2aa099911a79a92652cc717f0746fdcad627c72f1c216b243d2175f6d00bf07d3f6aa2a04d4fe9f8fbce93218944b92aa07af6b4fcd80cfde2d7ada15c05e96e777ea1c17df08fc
+S = a56823fa577e8946f1d2f6e351b738b53592544358528af88807ea4f19017dfe81a3d69f62fbff649550d9b310faf27a041fe624f0a02bdcddb79bfb0a465739ec8b64b748cc29e5a02c777e1826d3e2f1eee6fe2edee4a8bcac519c7c7ca5c039e76d630668945a1e5e8618e235864561a440e73e39f6d6842ad7da64ef5b0ce1c4ab88db157b68107174ad7d5c9a6065068768c11c4c96ff67050b5d07b8cd027fcd0d347ec79a197cf43435985bc1aeb479db0022289e8dd3b31bb7c62d8831cfe6952f41d24f89d753789535f918ff68b36950af6fd31dee1ac476a0cf93afe9f4a766f3c4d2c0c3f92825d5572eb2eb8a2b644e329eea1683f90810ed77
+
+SHAAlg = SHA384
+Msg = f60a3a543768fabe37f003009a8c26f7dc91f1422d4429ed7f9d744cdd4b552afef75d241acda04ffc39672159ee248e602dab7192449e2ed4552995c258f00a476346e36a29a0126bc249040faa57c9380bdd74b83f62c56790920574433432f8d65c5cd185e24fad13127265c6a5ef8db4f114493d5cfa61d91664981408e9
+S = 08d396481deef18cb0bef7c3e826fe6e5c9ecc85e5230d35d66772b8d2d015d4e5f5794fbe0550df2f745730d6f8d1d3b850d164fce4630805e711b59308f8608506b7e01e8e9294ed8b7e7582165677f180e965169dca81b3daf24d7b92fe32d6a9ac63821d48b1a0a144fc7a04b0bfc63a3bc16a0fd837b02037ed76e50d46cbfa3857e658e370c586ab1eed825076321ac8e82be374bacb295e4d3408f0cc1fc4c300b84275a51c3573e9cabfdbe3dc51e4a6f5811d860d725aaf8fd0af19a2437b0f1c80f5ac222f6b25f1fa09e93399a6976b1b3ca76afe6086e9b232aae6c7b818255bf963f31c04ae3fa2136c0a442997d4cf12f395fb804a4755b56b
+
+SHAAlg = SHA384
+Msg = 2c07a81de58955b676fec0572d48d1955b4875ff62a44b0010c7a1072b299ee44dd0c076f2178a83d0ae76e767e231f1d81e070afab29c97abd4de2164e437b311f507841f8851d6d69ab51ee9e29e654b54bcee45e9b519c6a21787facb927f1d7d6491926614792fcc6346dcd080bb5cf07bf56ad0fc4e083a358214631510
+S = 9aa391e7c2f0e920aac27ed9fc2081d3c9caa3735883d01ad7a7e3b11867d0ad624156477bbbdde659f474682d0d774489e2b5b039d1eb35454c9e3eed78cff9c4262e3aecfca1d817542b486096598e1114bfc03f20a45de36f6df70d144d01dc4866a0f83319e7c2b8530f8c27a41b7add9f692d8a8e646455b67c9ec47a4d2ce3dfe35d6a2e89d9be50c5b6da39bb0254bd23a809ab97b2b48a068a87abde6b6a6e35955fc92a9626f9607d5b3f401517271594bef73859812b6a621ed6bdaf3c5f2a90b1e1680f68dcfccacb65e0081f1ccb6a2073709d1ba067065016ed73ebd7ebe9e7a7b60c8c9dd04a56fab30702c8a6df6a353a301047df4c7aff62
+
+SHAAlg = SHA384
+Msg = 35ec92afdbc2fcefe48f1e2f6e4829ae53b3da0459cc4ea8a96818b5831891ee2f506fff37c89906d3233a51a5cf1469a62c185061f033085fca6a54e24529c3d6f0d8e904bcb0f089a5cd50869484da1a84f6fb8de4e53fce3dc714201519d11013f6f6aa64e8b5ec5cfeb27b611f0895059d8c47720d55e00b577ca5500920
+S = 6b0f5b50e678da083ed0f1b64e943e8c6279c7246af5ad079cdbf223e42a0d471e56314bc0d58f202aa6c5e1e5255985b0795d48eb3d4b8e3fc92240ae02b4088c6ce8ab0e8c79c68dfdc48657d6a28295391b9a5a5f35255126bf8ca53cbcc0082eab52ec109d22a1185f6dc792fc290aa8dbaebb2fbe404f1d039aa6343cd7af9fcb2d1e05def48096c237e10daa7cfac5ae9b3b3022005d0d2d5c9c5c502b2f23594e80d1604bbb8f5dec07cd3afe1f777743b0b58a4e0e4e5caa148830eee047968e7f40661f9f1a02e1a7fd2b6caf19326a75e9565efdc0114bcecb14dda06c329cf322a5bd3e6ab48d95f2d2a9c1c1233a0aa015a738f901f13148b454
+
+SHAAlg = SHA384
+Msg = 80c9debdf93174d75750a6cf09af71fc18fd513bff9cb491be60af112a93f000873cf43858a07aca760a37e760c8cb01d276f42d997f01cca5e08a6a602f5fe63edcbed395b8c91fb0b336f21fea49d950e1ff24640c8d8d3b95081ad1596644ce34a558587e4a1e2cd50db9ed1dd3cebbc6dce8084d3e1ba70692e82618ed61
+S = 4a15a783adbf274622d5a610bb6fc73337999e445dc2133accb788d6203d70f3cdc63e67daa4171a7952a4986456fab3c077a8941fb259e37a5c0cbb20c408fa24ad0ec850e9bf028c3604609941f5ae2f18bf1ac37a24f755abb9c85ddcd0bf4a12fabd9d253029e081f628e2bbe9f9afe9224954d8315db86c2125512bb98ce9b36930994b091a8a1d7d4e2f4a0e58d0a35876adad14300530b39c8dc11ded3ef2fa95d5f22e67cae34cc21ad5e23f9122b53dfb79f1a2ac63c1844e9ef069a2e41f178d6dcedc518aafcf81e0ebd882556e731cb0ab41d957274a3fbbb7cef2608791000c6b860868cb7393e7d03d945689ffb77555efe08f461451d33c11
+
+SHAAlg = SHA384
+Msg = 31395cef349551343a49271a8d812b4c7b65b455b7eda811fcf74161f397112357ae446257be26c93cfce55e4ba7976ded997ec10d1c8b1ac2fe22dc2ee81d05a6eb1361125cda0197e24ae974cd44092aa9f36fe01352ba05ccefd2370ceed6641950562f1776c39522e023d09a3b097bbe9bc5f87d05d80f8830abd7ac8c80
+S = 162f387695cf9d82dda89c749318e46c9be895ec364ea4aece97ccfa63925af3710894da2b7b5967e46f4efa80ca25d2a965a7e15f75e0aa1bd4250f8f41099e6e9714c3fc4311077ae9bddfe35ba4727531529c239d546ab1c298187f165f708ccc0ae3979a8da193e34859a59c2c3bc42253c8346688e6bba6fb1b01b10c1ec2c6493dedcc2696269d851bde63e27e37bed357455c8fee5629f94afa7a986695cfd5b99212657a6c884644596086b89e0c7c05e819faebebef745fd295af8866e0750f5479baed50cbb3d059f8a5eb7e0e61e2733ae50f0c1ec42be71f5dff324195cb4f0e941a21561513c3037db92fec9556b772ccab239e34b1876c56b1
+
+SHAAlg = SHA512
+Msg = a7c309d44a57188bbd7b726b98b98ce12582228e1415864870a23961d2afb82cd5bc98bec922d5f2ac4168b056da176ef3ba91f6b699ba6acc4144868ff37f26fd06720868d12ad26ecb52572cf10416af68df03ab645a8b704857d2190ffc3f07eabe3a8e2abe34ed6159e884c4fae141d4333d5c3e0db044ff9cccd9cbd67f
+S = 148af61ed5ea8a87a08b3f403929bf8031db4fd3999b64409ba489f97a3ee5208ea4202d2ec18734f615003a51f77441085be6ac0f11810ffa2dad58f0e186d5520ac2b8a5d3966e8d2abb8074e13b50a4e7de83be10a66fdc7ca18118c5774f781212de9efebc6376fcdddc65a3b1b8f1ab31492fe478259ce719b3db587498d879a01dec96e8eabeb07ff7073f3f3eb446084955ca26329a791315a2c259d225e26b2154b2047b21faba68115bfd962e5e24ec52d7c5d231e3044cbcd8c8804855703cbaa622b15b6ef78c7421a367166f1b02576c87360593da75b7189efafd1082bd59f6857f1701f646c24d70c95273c49d5b11e6afe258821b55c1680c
+
+SHAAlg = SHA512
+Msg = ca505d4591121664990747d95d9555cc75bfc3fdaeeceeaa60eafab3fc320cfce56eb9138138bf138f25f3c8bb027b136f5d3d90ed4897779b5951c09df5d08ba9ce8cbe17abc4f038687086e93d771b684322266633d0d65d71ec41234a1dbec07abc8f7df28bc43dd8a45b10ceafac06775805413701914e3bb37eb6ba5b5e
+S = 589ccd4ebf9764f87e6afa7f13c4062579b02228117b15a8738ab39cd64477069cb4f52cd8d5f4574c657b453835ca3cedb824f03b92a573d6d3d91361313f11bdcb34d2059fe2e6ce2b854461af58a9294c88cbfb2a639976b56e4748026f3040e2fd7112d6ad44500689ac777c071d17391969762e186417c4400abdda5c16dce0077642f1fc1354e0e8c14e558c923c1bfb85488b8350f415866a60871ed7151f5fbc5b880500011977c778e17fe8918c5d343f70b00d58f718956125fe28b3a5e2d07604a2b8a877204434ce903b35a030936bc71951ca593df97d24e8e8ad8f2dc9b78f76ef13a1d386ca857ced48f19f3ebe39108f9b33ff59eb0556b1
+
+SHAAlg = SHA512
+Msg = 237a7e44b0a6c268bb63364b958ae02b95e7eed36b3ea5bfb18b9b81c38e2663d187144e323f9ceafb479507d184e63cfbec3ecdbb8a05d2dfc8929693ed9e3e79e5f8abfc417ba1e17e3e281e8a0a32f084117f28c3dcbec51b86f5c85b2822441a9423b5b446d3928f977626a334579b39cfaf58f214c98d0cdf640be1ac59
+S = af076bc213caf75619f4bd1d787cc198f7df3324a0dd87a88416e0a4b81c2fb9a9db5f98aed43bc15fe2357143a6e4ff701d9c48f51de9eb803670bbc4b0aea7220be2f84b8300318c77a9f615986c4980abda85e3ad0089564dbaf7f44d81b6664eec0311adb194d46de96bb17d5a5d47426845802ca0f49a169eb82b75afa191027a0cc8fce9dd16055350df9745fc7200ff9f4ea3cfbfc66c42848113e3be3293d510382d0999f032515527bd99f66efa2a755e011247b223a68e51258b6bc319a7cdef4aec533e9dcd8ae26e349e5b33c79121907de509a1cb83c2e59a47c1a884bf68e7229316a62e3c49d1f542ebe7105cfc27099268120a7743908471
+
+SHAAlg = SHA512
+Msg = ab18939230b096646a37a781629fbd9270f3891a5ceab4a8c3bc6851bc34115dbc066541b764a2ce88cc16a79324e5f8a90807652c639041733c34016fd30af08fed9024e26cf0b07c22811b1ae7911109e9625943447207dcd3fff39c45cb69ee731d22f8f008730ce2efc53f114945573ea2ddebb6e262c527d20f8bb1dc32
+S = 95bd0bf2362f34b2e04075b2934f404798703ea472b81ac3cc223aec486e4c3d9c5d1c2f9ee22417132964ed58e49937f5b257d316ca7fffe290b19f5b58103836812bef30ca0327039d8b9ea91295392fc394b881e2d2ac9e30c5a44256700fc9de0dba298273aec30c4f778d2e7127e8b8a88b0274fce04081cc13adbefe555014e1b5d5dcf6224c5ae2775423a66c81818eec014a3faf9ee75a3f6c3e51c556b0a288e8c262946684eb628b88e3f875e62ef6e801cae75f61cee404971c39d24a9712eb342ddc663515dec103b18d97d78ed68212f27900e77c049b60c853002b08022df56f707efa71027589e1a3ca6e415ba5f4437e978b07af3b73ba0d
+
+SHAAlg = SHA512
+Msg = a280e89ceb2c8cf26297191baf9a955d0d52375da023633e0afcdb0d39dc335d8295852ef4d06714e6511a95d37c04d26818606ada54359b7d0784aa933cc68561ee96a88910aa3d93d10787cd1d7580556731c174a6e3a32d9dcfa416604f0c671481d051f63db6919f4aba4486d1b0fdc6112c1521559f424523c26b4fb738
+S = cd60de3b4a1289a84ca761f90fa63f4d5688bd885f4b531c8515add2de1251f993ff7f986bef3fba692ecdebc81942d7429c7a59c5d3f1fb872fc1da1915e94586a5c3d963603619008f7efeded1d70b0a11ce2cd81b5b0d86b3760c9483674f55e9fa47f2f310d588fb2160e8b5c32be4e7a968d5a8d4ac6576b71a2b91cd6af0016cbc816d4aae8c70649e08dce90b3ce52ab49ce2cb5b0ed8a45e33d94cf2d4cfdee1151270b2073aeffeaf717d39e04192b8b693c53f21a6123813280806920b7dc582201c9d117050320671e86139a027976b7ecf413369a9fc28e0bd719ceb5e107de799f1bc2e255a9f29476d4574d1332f66468afb9004ff7b535302
+
+SHAAlg = SHA512
+Msg = 85ed1e3dfcd5bca24cad1d01ebe192b7d059ec9b884436e18714a43fbcc9c64f687301352ff240817001e757d27309cd1fbbda9456b267dbfb958470b24d06280cf43382a19477875f3259f4210bac9b831d0a07f5e97e5f0f78818c259c289e1a789b6c7942c97bc1485a220131e5eba586643b9071e5366bc482dd3c3c9279
+S = 138134bbecefafc7ca8b102cbe87b012f8aada8878995002cf1887694b5be3b8f0bb616bc6e07962d5482d3a52c52ab91b3ee0064d24558e13c75c80f6a95b7dc498442879d5baf8ffa7e2f638808b97ff70136bb645e30944dd97a997a0205169553a5b9e874c5a9441e18c15ebed76043b639dfd64db79e174847a102724a2a05c649473cc7dacd39e2e1d5666bbb5f01246747048fffcdfcddf782da24a6dcc022b2695f70781bd9f8ff7d03be22eb8fc793f5c071a66d9a6ea46c6a2cf0556526ba8b085073546448081732ac15f12833c1db1701ff7f68344ca65dff86211a003adbf5189cfae79eaa8c8b7141ea378e44cc9c5bf024d2c710ff5cd68af
+
+SHAAlg = SHA512
+Msg = 0bdba34e35fca65a1781d4d7c933a5f210d3a59483aebc95ec71b32df13ff4abf401916937fd88ff44ab46b78cc369414e9bcaa8bab0bb8557828d73a2a656c2f816f070b5cb45549e8eca9d7c0b4a7b0a27e51c119358dad2a17fb3a45718f9dec3c94af78d65c3ecd36b71e230cf080d1efdd8d07f1cfc26768fd5407bc2b7
+S = 9f48deb96bec0b72fbc4f12f08afb46bccf19d9e0cd0368ebeb312d83872626380ac928b612c5cd77438d47aa9ceea905a9de7182c8ef76e8a7a03d6efec8400b6496362bf6a30ceb1ced2185fc7c2117b6a6d888ac20c1687b0f2aa9b76705fd3154889b6acaf4e63be25880c71e6c239ecfb965004cd6321257f846afd2a6590c72ad83146eefc7b0dc4796339a7f64da0fbe359f94ace1fd151c5ac7bb5707b32eacf564fe1622e66e1844e639602ca36274ae01f93e6b2bd1effd34ab63d852cc9caf3ce8446c29c8ae3c6110fb7538cc8371c2a3981249cdc1be2b24b6a0c951764d0b7efa92a22cd8ed165e182863579377997a9ee50c8ac3aa4df1aca
+
+SHAAlg = SHA512
+Msg = 9aeed85b40ba7f86a228b5a1515ba190b2efff66993a5ece19d18baa9b4e4df92e5152fe1ec56a9fc865f30bac7e949fc4f62f0b158d10b083636b4de9bb05db69fe31b50103fefc5f8daf3af7156b4552ca3667a9d720bbb2e4bcdabadfd4b7f4fc5bc811faa36710a9d17758a98d4a0474fec27e9ef5b74f5c689935442357
+S = 9eecdbd7fbf618ddddfb6e75d64440f60445b853c542fe0fbaaa6a431294e6cb6683ae1a71ea055eb49cd2a3cb5154dc93d9aa166399f4e6294f0eb0652800d71e041c1ce1ad849c03c963bc0929dcdd11be5d67a050d02b64b29eaba655642b6436fbfb163690bf432fdceedd106c2f4972ecbf3077ed8b753bb605ec1ea03020839a318a24f8d4c1d7d8df99a7f0010ae41a8b068e2888531056a7dabbe921878dcd3c7d69416867f4012a606ae86855f15aed0da1250e59687706e89c9494baf37f61fb1703b79928795f90ccbe293a1e9472f6e0f4b890fdda3ea2522e3d11d5abdf0069519424d147b5646a5a601f19ec89729a8b48461e71c08bbe9cda
+
+SHAAlg = SHA512
+Msg = 654e189f06c7d42d5539a5872184f8336cf100691f190818fd02082ad68a7609fd095e62fc32b529853aebddac3dbf0d54dd571be72c90404bcc93d01154a9bfeff65065705f8e7eeadf8575b1ca48e28a1eed516265e34540dd867c79d7f175235d1330cb1706356b709bd796f43abaf6fce993f88eaa2fc67f0ab776daf732
+S = af90298bcef615309f235d5c3360f0df11f5fb988789f213d4c46134fee5eb104aa1fabb1307c9a904709de88673ed9951cba93167c67c09d827021b08a22c0505828ab4beb42e59a38832cb4da24ecf91f470a3b412c0712a8a59f6f2739d4e9eb4cc58d2c52592f1452dc65759abe43e8d2bc804e2efb3efc9b23cc1734ff7caefa46b03ba4b397d0714cdb8501a812c1b9f47411c91cba53a3d3b139edbd7cbb543f5bf3829ba7f5fafd8a712c0b111943f53209353afaba176b3f5dc060339d09b1fb3c213dae5d0f004d302828560fb5debf9fe491eaa66f597aa4de23eeef9176358755c952ef96e3672583b6ecd95a02e8ca7b21d7c20cbb7a757af71
+
+SHAAlg = SHA512
+Msg = 121f80b43f9757b3fa80906aeab232195f0e2c41e5bf8c091ac0f1e0bc9e43640680a1823d649bdf86aba277fad8bc85fc957da2caf7323053025ff949706c1476ae9b0953283d34d7c6266f8db65eebe96d195fdce8e965a6383320ec3de0230ab2548eaa69a47a96d80398cad57e14ce9eeac0421c1a6eba69559dcd8f0659
+S = 06a2d74585f12ea7a80527b8c635a21cc11b45dbb0885a12722126811dd25d657bfa9fda774301ca3498d05dfdfb78a6aa16a9f8a95f40f1f04bd354a522f6a2d62b324efa3c006c22c2314b01fa0e91a3dba49aa35b46b19804b07ad98fe4bc990393a4a273ce8f1c85fc19cd5eae9af0b7d1957bb23409778a010b00c6959e1b67066fdb9f8495b4de4dcbb987358145b1ff6a39ef6fc588cda1744e0ab9e7eb002c29a78531d25157c5c2cd6470551560a02845db6dbee242f965a255406f6ef47b3221a5110edb44d38b94191aeaf433c0ece3480b9d1b06d8b8b6c0a232a04c567888e6372f2e94bc2be6b827f8712af48c6f1e4f223f5528fcf348799d
+
+[mod = 3072]
+
+n = dca98304b729e819b340e26cecb730aecbd8930e334c731493b180de970e6d3bc579f86c8d5d032f8cd33c4397ee7ffd019d51b0a7dbe4f52505a1a34ae35d23cfaaf594419d509f469b1369589f9c8616a7d698513bc1d423d70070d3d72b996c23abe68b22ccc39aabd16507124042c88d4da6a7451288ec87c9244be226aac02d1817682f80cc34c6eaf37ec84d247aaedebb56c3bbcaffb5cf42f61fe1b7f3fc89748e213973bf5f679d8b8b42a47ac4afd9e51e1d1214dfe1a7e1169080bd9ad91758f6c0f9b22ae40af6b41403d8f2d96db5a088daa5ef8683f86f501f7ad3f358b6337da55c6cfc003197420c1c75abdb7be1403ea4f3e64259f5c6da3325bb87d605b6e14b5350e6e1455c9d497d81046608e38795dc85aba406c9de1f4f9990d5153b98bbabbdcbd6bb18854312b2da48b411e838f26ae3109f104dfd1619f991824ec819861e5199f26bb9b3b299bfa9ec2fd691271b58a8adecbf0ff627b54336f3df7003d70e37d11ddbd930d9aba7e88ed401acb44092fd53d5
+
+e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eaf05d
+d = 2d6db91eb32e36e5d5127deb034d14072fe60c1cd13c8c3dd9adbc87140b5e7136f4f89e61bbee7826f45ac1d99194fbaa8c5a0bb94db31d93723b51419d9c6f6eeb5f3610b67f4b4e2ade05cc6b8990e8832cf4cd40f2df0388c9a52072e27efebae20b4ad5951f4d20dd18943e58b786d8797652b2bb759c319d2b0046dbf69c53c075d00c287b876042fafa23fe4dd705e4e423277c9000311e94ea3f7456e32fd12afe4a2bde358a65824f1055064823c893fc93be3b8c658bb441d7f0b00ac246bf043a9c0053d319f003ef5a5533f74d630d8ce93bab416a82951e05b82c6036593eca89f0ebacd7d51ed9610af43537fcd266e5e47c0d25fedad6d047a1a1ee3eb444367e3eff7c7520ca4f779f2027fe45036204168454df4918b547a4d19e938f3c6db6ca2702ad9bbda1261c64d00b578285bdcfc9851f96a4f2cd14d66b9c1f65742a1344948c9f1da8d338ed4e3deb1ebadf11f8c281944e8849823496f86111f378bdd084c99f65fb9b4ee6271b1d1be424c294d185d9fd9cdf
+
+
+SHAAlg = SHA224
+Msg = 254ce36e8ed62e0887d4be00eefa82515acef956540cff45c448e7f9a9d5c9f40de61da439f389e5255ef8c83257ec921bfd150829c522eaa720d7be965860cea2bbe57454fc5e9588d6a96c22f2d989fd0bd21924501367450ad2a3627e4ee3ca15616748ba54219a84f8742495f23de6425710ac7479c4844d0031750f3c38
+S = 9dfd3f32091b916a56f4f357a961a525a527fd29b114b3f03829df1b25c0c5973b1c51af36633116f4c77aa2f677a3b0f82368a538bdb33e49db9fa704bd5123edefbd3a86dcc39283c2a03c96c69030f04c648417f544f08a9b4e01ae4d429ef21422ddfe76834f925c5653b1227835a9a4413da7942b0a015196faec31504111c9f084d6dd6d5a6956c55412c1bd14aaf95d828e844961fdd60cc078f169f6e1186cb0cb6ba3d21168c5bfd067dc6e460784e7c6a76ee3d8b332acfa97e5d4b656ec8c611ebd896fe90e619b588d0c615492464a1b3d05d3a963f451051c65d8f81feea925bcbee9ce7a39ba3c915a18a24a451e470e761d09855a965e83edae3fca41678cc9d098ba9928b525b50e48cb030c510c4ce727c6b93bd091b7d20b4b961165ae0e2848aa995bb73abe9a2634378d224128541ab056a31b784885aef8034dedac13167402f9f62b55741220df8aff5defb69c035d9a31e2a5b8817057241bcf854932f5edee7ee66e8917aa4a718b6c446bddf084f5cd769caeff
+
+SHAAlg = SHA224
+Msg = 35adcd3f24b6725518815cf4606f7b1d940c396384370a376e84456974de32ec4c7164da3ac749b73b30fffa836869c92a74830523cdf2866dc0e0a88d1506063bef0a855cf30c9530ac7cb3cd2e2e32ccfab03c4222db14f2aea89dc03d452069f0684a7283e4745ebd7a28240bf1e0e0686810c97fec6763144652f6a016c3
+S = b5120be98bcdfdc1e1e3312dd7b5910f073132a42776c4da75690c641f32d2899187d9b39b55f99ebe6ca0a08036372749816706664f39b27312135c50339f2bb17b2ceee25768c2bc0ac37d6ca6ee903c84e82e2f4d005d73bdc335f135399c49123662e8908119918437edb615b14e906c9f8ba1b85d5b45909f439cc8992951be1684a99eba04ecb0f6df923353516977774f69e826651190affa86a40be75b06a4128e5509c51557ae4fb410c7e5841ac9fdc4bc1f97e2862429f371aaaf99824dacfee0bc3961fb98b3ffc091f77956223ebf5bb546552358208a32ef9c37825e81668fd2c230f788ca16ffbcc0f1d884b30fe8efe6498295004ca7c7f2b173e5666b8b0fdf9d32756559f99d105c1e8042a7aed7262ca9a17025aa096075fe4433f34db6b0f197776c21fbe00e832eba028e6652653018079fee04eb3e3c12803c39830d072ab4971bcab4b79758694b5d3d8ab21ce874b7c42bedd52652219ff516fd694c3d7cb0bef0181bb85eb4b13184ea3aefe3cceea5c57596f7
+
+SHAAlg = SHA224
+Msg = 0ba573a9dbb7f62e5a4d3d841bfd9298e8bb299eb4fdb256d11d2f8d64fe03e615f24cda0bdb73fe179102842f84b5051fa3d37e7b7cbe98d8a4c92c3b594b06d266f2e9e24759d4018edc848585ab3a3c151dbe5ee647a4bfc8cece4952f932aac80add4a42cf38800b748b05489bbfa9daae6844857403f051e37b753036f3
+S = 36fd6813ab411c4dcb2d7be1ed616c1e40de291a00acd87d2b4d9d4b73c8864a44413c51f09b37844a9804f823b27a9094627aaaf00a6be942d7558be11b84a73d98029c2e26eb8f650580ecb11b4ec2363597333444569634351600212962fef5352bdba367832899d3188a747236f08528f086d93ca33a06b10392bbbd625c867ddba74bb151dcc6afdd4ce41016dc2ef0ceea2ca20917fbdb0777e23503464d0bb59cd4e12c10945250889bae2ed839b70964b2c9d957eac6222a49b337730411984448e58c027371bcf9c2c7d686de3bdae16738db5276e0f538d15b3541c0ed86d318b423d8c7f1859602108a4b11c2772941396a14a2a88ec7971297c18633020998ee02b3114d19012a09a181d01f11cb8f8cb5f438e82fb45e7678bc8df9a26f1a3495439a7ac1f1bda6fb86c9b3ed6cb5f788634946348b7e24b0894c39c506ced2da657a335e54e8f997384e40c56a17a28a9bb64875a159cada5a644ab3bd6ea7bc4ccaed43dd0955f6be6e459e2e6a7ba652f1e9a3f8a83e4795
+
+SHAAlg = SHA224
+Msg = 89530f816a5e2abd4b422fdf968ffd964e0ccf82a4fc6d9ac5a1a4cbf7fff3e1e4e287ab35226a5a6326f72bcaa7914600b694e564018cb8fa52a5897658631c96aa9359b50982ac9ee56cad9e2337fcdd1e616fedec3870a4e249a0275a1ac148b31cd2129adb7ba18878ac388c59828d4b1f6a6745d8886b5a765a338c8198
+S = 27c796caeee6b4bcd750d8df13cbe5164fd726f91baa575f702fe2966744cf2bef38c93efa1111c9277d77f3ecf697d02030f01e3d964c3125533d408834b7ce652824303eb278dca61023a2f9280352f89b5d03d008c103032b2b5c6b8cf7befc1ffffa9b559a995759a8d33c6f49ae574a2d31805ab055e646abed71b30ecf7367030bf26b962d41a2c7d7735ddc0e5f1eda30b1ae6efeaae9a4cf50b68506c21b12e3df2b993feaee448a6443e613cf536e2a711aa526487187b4fcd1fa684e99478c28b84d9af0eb6a4956c0377d08ee26ebd2d8d2f4ce7e66048da3c09c0538ff8efa178690d42f0341b28a8fcb649b531a07af1f21c4243242e045b194a04ad0f92edce482f355f66969cd90254ab159ff9d9c0c6680f78c996d7048e2c5f007ad36219d672a0e76f1bf8bc890faa56e493f0c52d09fa1265ce538e166709a00a2cd64e45b9e5acae2b95dcb22bcfe9630e32f37d0bb529efc8d298c0ba7b8d65e16dee99ad7446a393946258724d08d8476e7f16ccbc0e42638381a58
+
+SHAAlg = SHA224
+Msg = e37656defdeedfb46b14628dff3f6917b8420e5a97ef6c54afda55e07c6043dd75e7908be466e938f629001d0ece81835f94482abad5d1eaa4d0ef9bacacc133fcbae22e2dfbe13360e2f1f48a5ae1560f0b4ed293d9171a0cae11001c7afc949f78b68d80b2afebd0c79dda19ec71d8ef31891ac906272c0ffd22d974d1db4a
+S = a927ec4ceb2ec147cc457e66c12a646fdc412d9eeb1d51f3b5a3e5a8f4b0d36deba3a71914cc6f2321c39d834addb4857c82abe9280c7c8231893904bd27474cb2cce1012b921f0a4d6380aaed614356d653653388ce86ac71a27c976747c9213cf297e759fc3e2d7b1ad5ba8cb3106c0a67624479ce55d0cd67c24b5a45c180efb5830fc20d87ad3b1515e90b77af87f06c6b0e7129718a2f93aefbd1028b1ac63f6bd7eca0a00269c0473eaac55797511950b11525c24141cb5ac4cfe2d9fdbffcbddf8412a70eb1b8f45648553b7067581bc8ee2d6aa089b97e40dfe61c33faf9fcd5650f61078571f03c6df94e01dd7f90f1dbeaf042d9bbc8b3635c4c89932852b311f63ff619550aaba00f061418886224f8478708f9ecdbd96f0f2515353192ad93d46cfa8a4b3ac3eaf7ab9d1a3c4dfc62746ceb089ed3ab4051ae09274f54f2a9c379ffe8c8c0109487b6883a4849415c6a0cccc68b3096938d6e54669edaf7b82ec901c05333e6c3105541f031ab590461e7f1f776a293e593d00d
+
+SHAAlg = SHA224
+Msg = 99ea30dfbb1eff6f56ad6e0b055989a2cba11fd39e386b0026b5f3a4c28cb1e6cc3d716e1ecb7a77d4707025548f79198cea9f447b1576f8f32bfe459dbfca823d15622a3792e7ea5372f5f7bdb9cda5506cb436130096ef0413ef72155aec4775dbcdbc105c8def591bc52947bfce6d9d8f25516fe2140de2d68fd233455d5d
+S = 69210ee27a00dfbfcd50aaf2eb502c5706ddff6d9d23fb38d1112f25c047eaac57dc90a6da673876319d5c04494ece8037c2fb60203c9f23322e2c2063fa7d19165eddd89e1b91935a2b50021e626825bf19cc46aaebfab09b4904dedef8c4632aaedb429feb687bbac2b406f923ff1e844941b0c02b08dc2d8b4265fceb61a82fcef0624f28eef3a9193b86f15f7ac470df590ae855a7aa7540499dd46a67855a5bae6ec5dca8b0c16bcc69c0a1f9218ec7ccae217ac9b47e8f7caefc1e102e3bdb42a677fabe18274a5e69447b33414df5bb29cceb2abd35c94d369eed256302d758df9948bee4efbdcc4ae356e78be735f7425b6443cbff7e85c653a666ded2e74ec7f61103d6e8bac110b157aebf61ce32f8b6f567acbe92f6e3e26efdd3942af6c279c2c7b4f18398cc0ab4e276881b6046cc552594cd9656f22c3ee49807cce0f09f2bfa7abb879727b734dc19c468f4af4d720da8ffd650cdd6938249b6a4c847a51383888d1292a6163222126d5a42dca6fb2283e7bbb6c20d7b60b1
+
+SHAAlg = SHA224
+Msg = 1ee43de2d8797e65bfaf52c25a0b00b6c04e0e40469205565a9674d6af5737bf9be0f9a1bd62f852e28708e32904dbd2666e7f81c54e28e7b0773086f2975c9d1c0d619e27faa7e25c9b4c9c71d66c0cf512a0f5ee4cc450c067fe4250c4fb4c6a137cc26069127ef49225d578a83bca34e4778208b560f8530fe5f213069d34
+S = 3dd722d2f0543e66743f8cdb60341d61fd7b6ef8cb23a9e9f34057d7a0af49e30826aa0aaf1fd34efebdbfc93ae5212711a160f2b8786f4f5becc49209bd05ddf8de9fecd00af5304d6615272f2e4940bc8c39c2fbc636f8c105565ec0f15700cdb066c5ca1fd0e3e3f49452e4f6715a582227d59ec104575c174f8cd13ecabc4d5899e02ebd3e81bd2c003242738b3b95b0e0cf0ef02f8ee02896df646068ae233ffc4436f1e97d37d45d497e1a54a0d6fc5aaf275ec50cbf0b402052200f6bc35373828bcdb48a178c9688658a2363a8683ab9eafa9790eef2c79da148a9d995395d9f6a7b310f6f7141d3cb0f206e8baa82a338d519ee881cf61d5e1f906d42c2e85f25cd19d9864ab54a32969c8edf29e5ac52f62006d9219c21140007b05c63e3ba4c04ece5d8805026dbe8ff665252d537d013f709d84999f84b4382a894c1ba0318493783a598f637bc2d8d5678cf65d0383380ada0db5a510737a8b70c3baeeee47085088e96d99438ba5e988788f2886aa7e295d8578eb27f1d6838
+
+SHAAlg = SHA224
+Msg = 740322953bfc8e840cecd9963f58bea70d2bd20a506366d78a0bad86296922bd097824673b99e3060585804a298670e26ae722924da8e1861d77fbe631dc23aa72b414b017e0770bb33e079f72d8f3eb9f5c83256acdff8ce977cdfa5c28d9b8b59d3a97583b123c1f00b5bca1b80e69b4743feb30388892f6f46aea31b50c90
+S = 7c414840910ca08fecd23ff12ceebcd48b7afa4e6a87a40654baaec6c9050087b1f0b6fa04e36cd595ad293d0827e9e1c94fe033ec42bbd021f7ce2e75da6dd206b99151768d6d5ae7b1f04416804c2ad7c6744c7343c8f01be259361c116810f0ada1c64348055b2594a06bdc08db390d750e4aeea5435932a04d0e69d5906304c84e19d5fb8688ca2598b6fae6d169593fac2909238c553c664de92cba6d8915e01a6e99d8d92fecbc6eaefd93151c61fbbde2eacf2634e7b6116ad2fe8859b65a7066d7b5b77638650b60a43d8277dab0aca145065b3cf00d963b7f818ddadd7c54be5b4ba769ae013446a574dbbb8f7c22b2d1543e7b5ec08dfde38ef9ad843c1bb6d9558aefcd45d3b12c8206b792ca72bf4950befbeec04fc1a28c3720588513a29af9691d2f31dd7d39a56bcb5f499fb14ca47fa541e2ea67843399e0c8ab89c81e5893415942bfe4e470a678c0e561ed64554711b16be3350c985b61f29219c5274d879308dd25fc033f819c385904654399e5438fd9c8cf1ec76ecc
+
+SHAAlg = SHA224
+Msg = f7e37820a19d5f6a05eb4779c240e7fb586ae8c3df713bcdf9c2af7c058cc327956bb8d42244eb43ff70622f8c1ca5d0acefcfa479eee46f369d658184672237d94050c42f89db31f934fea35b2810dd9ae7a105d26ec5abe75db007bd578382acac66792e35d73ddb80415e982dd1290b98856f52b98688f448b79817248e11
+S = 563e22617dd889e7be8dd26a176ee9f67b9b3eb040ad7a7fabc089b27ed4e7a782f1522b446f42a567492137770c612dc5e428ec28a3c502aa2508fb46b703d79d1fde8e1a507d7062e26440b3a3ff16bc82fcc9b301f2b58fa81852b57f951d925164be0c70bd281d726c9a71b984280352289f8c1b394a85df9e1732a4539a30a759e8f126096bf73f7b25a5ed34c32af345bc32e412e08b6ca9b656a6928519655ec9769cf1dae7c985505a812ee44bb3b42ecbec911beced8fe87365f113aac00a659c0eb37bfe7536f9176afe9c459a08ae23600d4c8543ef3c3af4cd1011e08fdcf199ba49024f08808c475986870561d6a088b79c38ae8ce0e6ec40268bc9fb7a3b618587f55fbcd31cea9370243865492e5f13c9fdad61f40b32d3a915194244949add15026c0ae19f52ad5b70365e77f2cf53298c9e2bad06171b0908df26b22ef1c737c3b321395ffcdb71c8228fe9de027f0d310686b1683a67419ea08971cf0bf1a3e5a1072724834601d5f944fa23f77d8e77e887f88ddbeeb1
+
+SHAAlg = SHA224
+Msg = 8710a877b7a4c2e578793bd3e4d19cb56de97fcd1f2af5fb25a326d68fb737fb521371a690e49f7f1a46b7b634ffbd51986de5c5bdbdf8c4585ef85724b5072cde13853194e47962202932def0282e4108613a2e49c5db2bf323edb269e38a8434f62d414b0d17369109f276a0b3b52cc5aec72f4baa67d7fdd94b10e6a787ac
+S = a78358ef28303deba1bf1bc3cae59ab0ff6614c520eeb7d8c8fd5ced34da7454ad140b539ef75e2d65dd891ebf899a88ada25bcc35726053da68e2e02b6acd2e7e21cb8b37355d19bd4c3e36a8c1647e1a384c8ad2ab39bd22f3d30f0f9dd685fe4dd7f836ec46bbcef0805d08a784a6964cd50f58071ed79f882491a331b445390b43f2a295a13a28ce0f44bb6d63f319d8de90e39017f4cbc14533da33380f553f097e796a671ba29c94582cd519f1f64db3be894b6615f6844ff2fc62101382b044f5856b9bb97871cf137c4e9e484e84a3cd2daea8e1c6358d66cd8326c1925ce1f7d2d2e90457adaa65ec3a67f4865bf6120effa06a79deb6b6ca9f85c9dd967f2f31a22d5db25b15530a9e850aca486bc0cac2be6b0af66ecb568c0955a30495bdd5d05a220cd06cb06f04f216076aaad4382a94040dccda68a19d55b49338c9315aa802910655fe9394aa73590a6b2a0439bbef5ec7ccb520f2c5cb71d393a6cce25bf77d8033444fb3da8ac861c63dc2561ffdcce8c2065b35b5c83b
+
+SHAAlg = SHA256
+Msg = bcf6074333a7ede592ffc9ecf1c51181287e0a69363f467de4bf6b5aa5b03759c150c1c2b23b023cce8393882702b86fb0ef9ef9a1b0e1e01cef514410f0f6a05e2252fd3af4e566d4e9f79b38ef910a73edcdfaf89b4f0a429614dabab46b08da94405e937aa049ec5a7a8ded33a338bb9f1dd404a799e19ddb3a836aa39c77
+S = d1d21b8dfa55f0681e8fa86135cf292d71b7669713c291d8f8dc246464de3bbb961b596dfc8fda6c823c384008d05bcb3dccc36accf1b2bede1a95e52258d7d1bdf1fc44e18072abd45c1392015ee71692690ef8cdaaed337dd8546783f961bb9620eb5c7b8b6716e8c600351fab7765ee38a15d32d8a2c0949825c49a7f25eedd9be7b807bbfd517913786620d249823dae6fe2fd39ac639dd74821b0c120b42f31c2c639d2c61b395f09f86851bc809b34c4981ac65cf25b2e8adcbce190ef2ef67a0189039c9110f26701c3eed731c8d9ead178220ffcac7f0f678aa22268e1d01942ec51e80eef06e2112830855e87bafe8cc9c22fd737c7abbca5eb7a221d3835a86610d24b507b5dcb4618aa421f63a5609ef5d68f5760fddf970135602efad0851bbff98fe87fa58bc365f38ee7ec8ef5aab17fd11d89d91ef4c604e0d1f001d0e08869df9225e3b4cef52ff86815e13b3efdf45776f9353769a8a51fe7d891a7ef7035eecfa259848738376886edc91cc78f6da31c2f07ee362c3d82
+
+SHAAlg = SHA256
+Msg = 2bcad6e744f2490ba6a6e0722832417ebd910f9146eb62baaa5c749529f79d6ced0b81a2e2a48852c8558e338735dcbfc2285794ae60f81a25237c66f6ce5d5e801a001e7f9e309b2595cb866de2bb74ac51283b6820ec9f6ebe482e1fd2d5680b7fbd23c1e62a2ee4edff35823fc7e4a295ea4f1c332792aeb53eb44b0bedd2
+S = 37d960fe391298bbdc223fa1eb1d3cd9a46ba8c62e1da8c563c89a8f0e67b864fc89837ffc08aab7122b84c435c7f9406e165a1029857c1e4dea653569277273b1d9b0a9f5b0dc24afdd214476d47208ad5221a7d793cab80671fb4987c86bd6144880c59d24871400f64bdc6d496dbd497f3dbf642864fe49af3e21515e62d60f0071db4884f49670eaa9e4e4982f269abe724244288859c2adf60a09faaabb07990e09e56de254babbee14be7eb6eda0cdb22f3d0de8724804673fb99f86efb4263dcc5017abc91bd9cd833679475bfac50a2be8db86296bbf8017889357371314604e83d68b6efecd4b79f0a8afa0dffa448fb7fce6d344709a670e0cff432c3e187bcff7fdc4f4e9abe1095c46b01d88b6044bb950e92859010d9a0e3b2d1f27a096eacaa24263a2a0523d6e0da1fba8af768196f7a51f92fdf152bef062dd1f8327cee1d344c200c2115ac6ec1dd8514cef9e36d0ce8c32e58783c4fcba901aa70c2b42966488002ff171d36414a144bf46775183a8815de9ee3e81f31b
+
+SHAAlg = SHA256
+Msg = c3978bd050d46da4a79227d8270a2202953482875930fb1aeae4e67f87e79495289de293b4a40d92746fc84cc8318c2318fd30650e2bb9ce02fd734eb683410d44bb31ad54fd53cf9296ccd860b426f5c782ea5cb49371d56184f77911ddf1ba0039a0a49aa7e763eb4f5a04575997808b0ad9f6b330ca38edc19989febf4da5
+S = 9aed20a8bdaf26f1f119020d8f3ea6ce915138d4c87dce025e7f4e49536c8ec079edc6caf0d603bf42bd6a454a6d52d0d99fd0f59ffb3b22e9e67b3d0bb2d275d9aedc6da96a72cbff35c43e7f39a996fa8a6d338a0725f785254fe91a20834ba557fedfe7152b9956feddfd941741eff9177c2fbb55e200bbe42162b32a940cc300ab375557dffd48dfa539f50edd52df158d9072d14982e96303bc612c2c2506dbca3a939d626d2e7fb444c6ad7d8d9f3bba8210b2ac2f696783c349fc5280c105402a4b3d86bef5026c3dd999e3b22380f9dcce40e3a9cc9f1d7bc38ef3dd7e9413bb579800c0e6c3e9ab912da8fec1a4ab21398e9680ba0d04f3b4c8d53c02f05c7ae49b70a5611cf82e38de84aa8c2426f0b63ea01b289f201d3af40dad5d6e5bccc75b9959e5c9758e79105af7a9afb12aee577cb3991879db0fd8662c5bc49022752498a301d95f4b1d08c01ebc313f89c00b1ec2735a07983fd528e6388245036f0ed4a2dbb65dd33ab7f124c014ec1679f1c2f11edffb93fa2d1d73
+
+SHAAlg = SHA256
+Msg = 0c119502c2a01920a090e43357e7b28e33c7ee858b4330e05c71048931c0ed88468ca931ecf0b79c2fdc1756b7675156ec66b8335e3df09463f5aee7028fbf560f984cf698fe5c4280229ac96a2e5923d8a9d5299449bb665008ecc889797e9bb15d04b88c7210fadb8bf6f238e5d2dc41b9ccd1f80e9a3e6ad147948f273341
+S = 8abf2a30774e6e7338eca09cccaca3684399940492fb94b23b5ad62ce3e11d2dbef8966ba5269979eb9653baad719516d3e8399079a2f670275a2ed42c820a9a31fcd703a76637e0d713f32d792b9ae36d7288f60c2d1ae52683bb15941b1cd890d2cd64998b772585e76032a1702e0652cbf259a1ceae695d40cf2f4f6d81341c8bc9082cb96c752c355dfbe296dd21d69846fa37613e73817b2a07046658c9e3fc6d091e17591bb1a4fb6e2ac00a3194c1488e16a9d2903786db86ae90e96acb4de9901aaf1b0651fb76a58dcb3db473efbfb831ef8e30f89967ddd3a6c2f18979a0450657cdaeef6e59377c6db1ec46065f614024a69c518a559942594a46266e0d3ca1334296b968a23a4b11c63a97e29eb16b24c02d545d5b427e6aa585333318e63a204524e0e42ac1edb70d3456780dbead31f785f0b2a77ffeb0d37384cb5f65b4e36ca241f3b2b059105faaa3222d6c135ea5a36651aea396d22fc4ea1b404d7e834b6df1fb838bb5ba0d784a96e2ae2843db3eeea496c7ad2b4241
+
+SHAAlg = SHA256
+Msg = ddbd8468bdb036f4799f428bc8b4374ed9b7cde541337ac439d441ac0614cb75b816b80c17d237b8db73d4a11bfd929208333afedbb8f2410c741129c53932b596a7881c6a4d7111ba104d4600d1902f6f4a1608e139b71911c11c390a0dd091df369aa29d670b8a7e3f53825f7659ac74c40a0c3bfef0d3ae8307e4bdd6cd91
+S = 4e377e2459815d5b33915fa63cd477b5be7c6b7f7814d1350034ce710be67ed69139db622ef60ec6b7638e94b202368bac631e057702b0e6487b324a6b98ed7e03d1f3f20a9814b00e217a4648e4bbc449a2af405ca4b59f8438ddfd75d34d1064e58bfb325c55bd54ea6cdf7712ba807c3e4c665d620cd59513d7bc0855247eb670ecc292509661812702703275d9b2f87ef279d7700e69d995db98144a14c81774a4cd890ec03d13f858f3769e5048ed55caa81201e8785d3771ce6da51175d017d211fa703794416f469b1129d731abde744da5b2facd7a9b093d6c9743509b0103bab9c81c6e5f38bc9718e3e4faa86475d13725a829ac61df8d15f0b27cb40d0eba0b246b9c360b569b81b3abf380eec27492316bc292e5150ee0607219a2bd80ba984c7e3f1989bc51e4c5da3ae5070676e0c150d037a86a0f91bfc07cde64c19f9c7a7af44d6929970041448d3b17c249d5e0b5862e9a25209e8f97d7a0f030181504fead2266c873fd235983df3d0657b92096e2b490df33ca115733
+
+SHAAlg = SHA256
+Msg = f996f3adc2aba505ad4ae52bc5a43371a33d0f28e1950b66d208240670f352ef96185e9a7044f4ce2f2ff9ae01a31ef640e0b682e940c5105117594613dd1df74d8f2ba20c52223b045a782e850a12a2aa5c12fad484f1a256d0cd0872d304e885c201cd7e1e56d594930bb4392136fb4979cc9b88aab7a44bfc2953751c2f4c
+S = 30b348624faa9985fcd95f9c7ead3afe6456badf8c0fedbdadb3a9003a6702973acdb4e86652367db23e0a8141880d6631834f9f171c94a8fe9c315bcb8680ecfb5a4f59b45d4e4c3c05828b7faaa8e4234aada4e766646cc510d07b42bd3883a83b5bcb92d9e7cc1ddf590a690111bfc62a51af7e55543ea5188c92453d41d3e8fdabee3e1defa9d0afdb85c8153a5019ae45563ea3080a3022668168f0c273a6db1afadcd5edbca5021c2e53f4d951c604206ae10f287f451867271d370482791cdfdcb6a4010f6b3d9b928563d168da19f1c1e570f8c158f3d490b29aa23abd1ffdf20866c34c6e63b9e8a9a02d7a1b196d055f4c53ce82b400e4ab9e1b9d70d0049d6d57cf0a4949cfc68d633882882dcfdfc50cf449df10acf20305c2aa43bda10fd8a10b4ecaa23100aa47e92936dce1bfb8d6595235bbfe2c8585cb1647b2beacb1e1d4b6cef758811a68330fa9c3a82573c08fa2cda5a03f3425554e45d98c1645c5bd27d12e6c20b2c462a746e882a3421a7b1b1e25b4c36c8b16a1
+
+SHAAlg = SHA256
+Msg = 6ace052d7e99cd973bb5c9f6679b1c305e07208965fe58c63b10a692f1dbbe22fcd0db15893ab19e107ba2e42c9934a9aafac32adf6c73473f6969e42c983b8f0c96a4639ef77d2c8e88e8cc47d7cfdd08f68d973a7beaf401cb4d1311992ddac3a9c9e067da198adc6304745f5dd312a182e6971c34a515a6c1bae647e57e4c
+S = 5f0e74f454754a3074faafc605f3c9af47604a8983650a9b6211fb191d9afa5315df4db4501fd4f04c741d764656d4a5d006388ad8fdb219ec6b756908e23b30cb639ffa7bbf2874713bfd5a1062c19d04e0e4a74b14446a7fdf5cb812e9ac7b6012d9ae991c47656d2aded24074bb8a38b1a88b1c2b131e5b09c93757fdb2d6b69aa8265a435fba00aeb36a1f629bc34b876089d28a948dd6ab4c899430da60a26f6c13603fc889c7b2936ca3c5156bd7fa6e34eac9e04800833ef0cb9b6eef788c0ef0021a4536fb8371fa3e2c8bb8befac16e8092d69c571c1e15fd255ec0a07acf9ae9953831efd3dcbef44e0fccebb1af959d71f50130e8acb4fa2319261fba12f2715def82bfafbf40e345ec5dcdab5c1bf5f66b1d0e9f7a9c62c9375746e1ae0c8f14a489184383e81dce2070ad4b525df76b446b1f22921d424d9ba3ce21577501df6280fdc69f0239ae1127b69950759d5f0b693f54e87e0763623bf5d3ff69430081b9c9e2445a05e115675e090bcab2aa1d75ceee2ad619ec8b80
+
+SHAAlg = SHA256
+Msg = 0e49740fdcca6bfce294c11f45407805b3da412b01ef3fb513e70e62fd9504c0670db69c36b6bebd69a0bcd240179ba8a47816a0c3437a61fb72adcaf9096f2a22efe0b431fc422d225301e850f2f0f4da87d6944a8529ef79781909ad96d1f20596f93e17c57fb4d756974bbbf900521cb089eee0ded5c956a15b096162b07f
+S = 7bbb3ddd17a42be7cc4e7eaf456509a4ba58d40c49a3d99573b733e1942f9fca20ba8b910708d6e750367e847302fc603b8063c19af883e7507fb0d9cc2be37479a37cca25b8c7c46f6bf661dc6a3232f88b483f1b8f41b46d49ba3f1795d68eaad4a2556fb5d7873bbb6501ecf06ac558235ed13990b0e16f67965b09366bcb362cfc6fb978f4f68d8146dc8b819804df424e8ca5b63cf1fcf97bbf300d0b998860798a63424383fcd81d37773d59bb13b4fa5d468cd128bbab18a8ce5173be5d9d54d3177f0245788409973df4a9016b944baefbf3bf1146a9393d22e35ec2be0ae6f4c31dc4981f40fc1baf382600699eafcea92cbe24e26ee846fa23bc193b6e721401b7ac3f5f4ebeb633979f8ef35f4ab1117a869d5b9dbb7482f0d5a59e4163548d2512ae067205b57d030c483f720d2c44350428f5268943fc5f6ea1c88e2ec13ab3dc1456e96a3b8e7c121af4d6a5fe4ee55e99fbc3592a487c194bc2f2bf6e79fb79c2876cf3365e075beeacc7db4db7ee69e7f1fe12a327e6cb0f
+
+SHAAlg = SHA256
+Msg = 0e675dac9aec910106a6ab219b4cceb52ded2549e899c9a24d5ee55177761888a3be1a2def6aa32d62f788132d6227d9309806fdc02db7d8a850ff2c6dff37fcd777f1a0acefdf18bf85f1a12979be86d799253945fc34a288f348b7923d764db27a2a2d5ae20e6b25372ef318f8596529d8ca23fd6f08a8f62e0a1b6d989f23
+S = 8052d95f12ce0e6e53a5a356a0eb353bdcc1a66514d6cfb3a3d96155310bdda0a0d1795f97643f3a4496634f2dd9b95a2138ee390e1e74be3134f3f47a919ee7b59f8ecd272ab88c82cbce7c217e5f92d057a5b00fbf0575cdaecd7dc285a4218c8a955216598f0742671e018e8e4e76839a575f50b2102a8b77d1b84f6dce98d78e5758e0a6f92bf35d6a2f18ad400925d7880f9efc774a8c7ebf64885cd2f6f629b54a7c12ec91d39b3c2518241fdc322d9b235a8ea44f77e82f3dc4f728f620c07d1e7ff4094f29c674ab0f0802efa1c9e6481ebb84e0bf13ef468d8cca114570b9edcddf98ac4a834fe7a0d5c6fae8a60a48399f3c8af42ff4026e42a81aac36114ffc053f3f729b7cf9a97a56848ebea0115aa8298341aa226963ebdf57ab2d8e4b9000dd051a6c5d69f60e1dc1b33f2094fdbf8e5b627bc0764db9522cbbc081dbf38c21b13f980813bd2b00c757ebb8c0b21213152e694039f306f7342857651f722bdda01212a8552799bda6ef07c5207dc744ef7969afd5af2e6f12
+
+SHAAlg = SHA256
+Msg = f6a7a6e52659125fbbc8727417283b9a64441f87121e27f386d5019f10cc9b961e09f1b3b0db23630cc0caacb3858c6f93afeeea7e1a6a80dbe0c2bd9c7c939570302dec39a4a25cc0cf1d32a71a75b9a0c302bcdd80b046c86651acf30838cd52e30399a8fab8d03fbd140cdc2f1f02f2480405169820ccb32e5974ffb8b1c8
+S = 84603acbfe1f2f769f1a62b0f287f306940b225476714a4b6827c02d7bd052f303f30a5fa6da83e60615305669ca9ec177c5b32b1415eebef78620296ebad6dbbd520839d3aacc9781ac8602ddce0736dcfa7290b45f155b8e924d0afdf7dfc8d199bf09509d0176a68b145756eef53de456e17078859849a352a5bb654239d8ebaf8800ca8263d34a868d52bf8f22644dd9f3c05bd891cd92f263530c5896023c6b213ddb64ede1770ff1686c34036e281e911d9dc960354fd844cb7b22dc0cd81a96203ba818401ccc225f857e59a5cb7ba6dfc7f5135ea32781e63daa14fbda1bacc18ebc50824d4028b8fdecda49e810bae5acc8adc0dca2e236fc832a97330a1214fa0aed15cd10c049efb65ce855c060f05befb317b8065843c4eb5a0371fc6f209f6ffb948c881f2f2091caf0f59f60b72c5f67271bae96b913fd21fa1dfa975d5ecd62b0d50873b686d29c880d36edcad33ec3e2216c9cfcfb4f984c23fde815e280a802428608bed3739af9200de1f85edee2834c04942c068aacd2
+
+SHAAlg = SHA384
+Msg = bb294b95d913005b110987cde45887484ae6df794873dfc5c41fb7e8992c2fdce70699fcac8004699961b3ad1e1fce9ec8ea5685ccec5e80e4d0792559816f68613434bfaca81a843aac459a6fe35f5369c48e9191e4a32c70789594c5152db8d4bb02260012a8739cf325ddff2aa42fd67b6ee5bfe31591131ff27d0273d292
+S = 32637c60798b450bff100bff12838357deff281d5b31e4f4c2cfc96eb779ce6d31b1ce8bd7aa7fa88ddc4279c8c3280604b018ccf452004a1488ed4750181c5025636511ac6724fe51761c27d7cf9a0c8782ea2231268853c4b1f7acb0005e5687c8f3df16c962f02ce56b23d387a2baadc8bec94229c3557526e61707a8b59293a976e32c7fa133285088f3ce3e677788aaa947e7622c757e844b117592be99fe45376f8b3013e8772ec92c5bb0b9fa301b95544599690ad93668d83b2daa7df05c66214e275014780a912d8b1932d7a655058e743f50b074b1d9691ca23a2f95f6affbd516d64ccb2aa43c236eb95d36d272545e3beb8ff5aacd95b30f7f1d6418af042cd9a0cf0189846262322a18875ae4c3e68e4e8ffaa0276cdd99a0047c86c0f71d2deefd50642d29c195e6d14fb46fbac33a508c1f03a232de08aae09faf1da8ed2ba2ae84bcca88b78dccbde9afde08a3beb322dc79356b29c84841698914b050beb75a7b2f6701aa8101a5a4955ee27bafe81b21d03b43e3c77398
+
+SHAAlg = SHA384
+Msg = f946c6bd5e1d6b89092f3c487c0568fa07c356fae9b8e831b8320289039746a435b122cfbc4a0d316bf90d481d3b7d979cc50d98c1190af8dc58e0035557dd5e94f437f41fab513202643a77748f76c6b77302bf40c392cd18731da082c99bdedeb70e15cd68bff59619cabcc92adcf122753c55afde0817352bc247d1170b8d
+S = 50706ba49d9a316688a3ee80a0bd986757d43ec83285af9e78196bd52c900d40b280fa0de54e35ace7d6660012f1a66204092f0e634b97e0e51665b4075e36f1422266c7cad7b2d9981b913df3fa3e6a5a1cadfc6378a8540e0faa26f1cc6fb2fb492a80d0a6945bce5bbc23ddb3b10701f0249b27407a6700802e8842ef3cc761c4823acb5d1453508dcdbb979e7bd8d00128e60a9b3789167c91417d93f0e9fbb00c9af1498e09eb6485eb94cea4883f6a256eab2caa826de4fdac01baca3a216e3d204a3d837ffd4d0be2b2cef711909054c4da1d5b93a8f98451c7002ae84a5e7080d98671c50e3c91c4087d0477b104f916010e742f2d207fb40d122d8f211af6d7c5eca49542d9acb0f166e36abc37155070c12e9f28b907d67a2ca70bfce554e1c44c91520e98fc9ad0c0ee477f750516476a94168066ce47000030a99c23e2c38755de946d5edf0d6aa94212f992315b248c1f82723b29c42216c78cdcb668f11278261cee9252c8fd0ed37d0a8580ca9b9fde7505615943712da19a
+
+SHAAlg = SHA384
+Msg = 9a337d4c0bb9a005b47f4765d696d19dec58bc8482f2173a4a203a0b6d38b4961f6a852e76468e807c7e457683eead5cb8d98642fb76c0a1eeab36414c1899597d57aaf96782ada586f61a423f57953771d520cc4ead90d569f23d950f8dfedddb8355748576e6bbfb6f2e91b3da71753fd2f4ea229f6d20e27db8d05e9fcb68
+S = cff7aa7f875642fb9343e07ef5e7303bbf5f069b44c19fbf83e59d422e25267ef9307414b6b1ef61711ed0013276d1a2ad98390474027a0a703bfe8a6e87706059d89c060980c9c9e60dc7e1fb9f777a41785ab4d2b663ba0e3c1921545c479c2a383a50da8e489cb22b71101d0ec148ac70928732a772195a140d080152762a9c40803a39fa2a6978c2a75ac4d8bd1bccaa1f4204ba65edddf32fedf2d9d0a3aed9b06c47e717733c577812d723dba74a852b2905235c812dc5f1d0df0f0de73dfb86221c6ffdd1eda119bbe98d148add36a4fe50489b06aaeefcb5c2066d90fa79738706cd18e474d69609ff1210c77de7cd23ba2a775a4329cb271a826d602c401a71439019cec10cd9f184c4d04584211827b19eadac3258d8a0f2631613f051aae0c613050cb24442f15ed4fe0dbd290e42629141bd2cd56d20584a1d10e1f2c2a9ec731433d5bcd1d318bed5243b4b7d0f9a7982061c55dfaa86b2c01845c021fdd2a978d42034212f43b3351b6adeb03bdd6caf7de059502f16d77348
+
+SHAAlg = SHA384
+Msg = 32fd45e73f6f6949f20cab78c0cc31d814baea6389546a365d35f54f23f1d995b74101187760c89bb0b40b5057b182e2fafb50b8f5cad879e993d3cb6ae59f61f891da34310d3010441a7153a9a5e7f210ebe6bc97e1a4e33fd34bb8a14b4db6dd34f8c2d43f4ab19786060b1e70070e3ed4d5f6d561767c483d879d2fec8b9c
+S = c389613717ec7476ecda2144d0e8c8f9d66fb469c167c4209ec0bdeebfb471665d33dad47b8f3c319a76fe8a8a9f662b6c690b74903d17f61e2314e5ea8d26670ee4db4dad295b277ca08ade880de2e42d12b92952764c1dc808c266dbbedb670158eef36e896f55a203fb99556ded0597410ba37486b1d841f3d6d5c0b39f2f49f0c5794824fba94a8ec7c2b2c91eadd5c8cbe44895fe3be3bc1727d6fc0e5364f53578639d3b3af696b750a07853694ffe145a28c03620c78dd7377d094d92c3e09546883d4703e62a98ddf81fd01fcdf3c4b215224fe2b1b4992abf31f20d12afa868202390de334a846b2d58b253ea8ab3c5265d84773a659e8bac7af44123d9ea15062e65d4d419cf2d97077d0624f8e5c36f2c7b35ccf95435d5c36886ff9105a6c1ea225e15ea8cbc7b6bf6856151cd76fbb75b5b98f0e3db516a8e218189fcb1cd5de3cafeaa33ef135c5d8b8aa5f881afaacaf4c08bd7281255bc2a33b76d4a36e0b170c45588239e5b38c679b08cf802af73b6d79b3935949461e7
+
+SHAAlg = SHA384
+Msg = ab66cc487ec951f2119d6e0fa17a6d8feb7d07149bec7db20718e4f31d88c01f9a53d5ba7ece3a4dbc67af6a35d130eae762cb7962b9ae557ca38452464002223f61bcd3c7353e99d62558ceedfcb9374d4bbf89680c8e2b9585603e076f1cdb0058299b4246845dc79d1043b1422efe84018e4c932c45beb8851fbf485e36d2
+S = b51331552b08be35a1698aa6203d84dbfff9001ed5dd776f2be4ddfc07dd4620e9654e82a33465bd20f11863c0ed02a0aea27a44d414c328a938bf877e15838ab99d670d01414262e8865dc1d9fc30fd0812699fa690c34f302f637ec802cd40ac8591e976c0b8bccb1b0137af64a2870210e8fa3dc431fe0956b8addff1e4b18cf07e078aa93af81bb3023c9e594e66595fd92b10226ea126005f4724427352c38e9e85fc2e0723f80af1f61599550b5ef54c5b38ca405738017b89cb9468d9741cd6bdf7112162251ba1d083cc370a4a8261c39b6b94bf21a53b7564531ae9ebc4ccea7ebb8bd314b2e13b58ed1018ae5b415e0f9e3e19a5ead3a44603f90674a190febde25f8ad8778aeead4d0f64fbae37166a54e3a763e35559bf8c3f173f19ff7bab98f3ef803dd56c07628399aff87485ee73dbc3db34ecc7bff3a53226cf87bc81d256e80c09520c8f38e9bcda095e3635128e1bedd9970600546a751eb11dab42e289d6fdfea04bd58d4571a79d24bce4508c54e1ec4cf75b985fd3
+
+SHAAlg = SHA384
+Msg = fef7fe89b9a59902a70a1d9caad09ced8bee4145edcbe3ef7fa6dab37635129f3b8c5e0860410ecbd9cec3d8693682f25aec08b071f05dc8213bac8cff5d52b576653560bc01575604e6ab90f67227fb5c901a781eddc027700913e54a7fe51318482c9ab42c9d2b911b7ccc39ccb290f9a420a5dad93394d4d7b8c53fe3f242
+S = 45068ca6d82f2c123925cde11971215d8fa4a4df6848bb7654868700978764854638921bea5869280dc6ad9581ab43ff7012969948a5677fa0a66136a316a4bfecb89adf4131b5bedf3d4693b780d133af9bf9c133305be78374afda3ba3854203324481a9d10b9ca9b92dc7d74df531872ddfc76caa82de020e2c415643cbcc4280e6d2f4371fda7d9249314a8f437648991a9b03d71b5839ad38a1555ad34526994ba56870b6ea18011295f2ca2b0713b2e92ad77680c0dc5bed8d3b9b31ac14df769949c4a43ea67f6deeb3dc9ed589ea4e8a2cf6695df46f946f1467b28e875477ae4e645080fafda6dd551d2c02fd6b2b194fc0bdb050e06d4c784105f5a33b53e73098055963071efc1bf397fd325f3a6f4e10d76f0411a001e62ec73729018316f56310f893a59363d1f6fe5c17444b6c728a4933b75212fdfa258e4018b7763951ab4e5096411df9e5bc16df3896e46c973d32ac9276a4e2b5b80e3d8d798dc0470b45096b4d738669ce052ed818e560af1e92c915187d66cc308b70
+
+SHAAlg = SHA384
+Msg = 82b3840eeb95c9c57724c70f112b6c2dc617c31785acd0c823f8bcdda285325eb3d308dc790522bc90db93d24ee0063249e55d4219ad97145feaf7f30668623cc8890a70f4f149866f82cf86f98b0053b23c98c8dd5e9107e341460e9bf5d88cc8bcd1f2e4c007cc1c02c4529b93233a0b06bdd15925854ab9e3f156eb925bf5
+S = 0593b9fd4421452376d27bc7a280101cfd6e88a6727d7d77cf65ceb723ecd257f32fe10277e85798e0da75917736da1a3bfc22adc7658fbb84da6ebea0b07d1cc405732fb040b585c1b63c8034069bffb8220656f1ac54ce693720d6fb1b5aec67b03c887c8077da148d10f48af7c028f992b18f13c0e57530c086d775483da5f66f3a6a19187868340ac63c6212bcbd6cbb7beda8620afd9b66de47473ef24d1b6a36f4ece9add49514fdf1d84c7a785b7f0e00f382235899790f472d13f48558a4314742f376808dec96edd2e229e943f7b983bea5ec6edfa5e9bb37f588e55ef62ebc9214beaf9da502434e1088df272c6c77c1e1d897c47beab77e3bbe317f8d43d21fd7e94337c7e263e2867bf580a2a8ecb9e36ab7d3e1d5cf9a23230953d59df0d7e23558fb612b7918abba31b164ce178818a1a9e6b6687f4de685d70e16bef6e192faedfe0b2b95477d37b0a3a2d002f33ef4321cb905040ce06fda1c98a008767fbc781a1eaf3375dab8664b590336b99e157b8687a6602fef6a3b
+
+SHAAlg = SHA384
+Msg = e153cca4431ed9713f4744ba054f5f191cb37b280108ae3a114ad349a872d1308b46211a83758a3b4be32fbeac42ccfee7e23df853ca400147077bb43a44c12f299b917f3aabdf589eeb1709bb3d60b08bc71eaa3ffeba4e2903a5dbd8339aae85fa24b9aee76130000605857a6aa197d00926270dcda58b7de758a6ca67e617
+S = a835cd4146bef465642d494936268a311a5490d2c9f9166c6ce98216a9a23a643597300a0050e6445abd5a9bfc7a2d9b70726c824c383bf5acaddddc34d434a31e5314d25fb58e258f518866c136e52855c16fe64ff8f1c4d66c4e9e39b8cb1196d80944d0746c0a3e1769cd4167df72ab5e4c9dbae9cb35f4828e12099f9b36a5a70c48d4aec9872d7b19e1291b33cbdf08a2263d500c0a83b5237ef6ce92de344b3b41d0d07404fcd5467b046b52b8f85fc6b5d7afc437f1ee9e78390ca9bb6cec618885ece29758f2fd6f4e5f4f896935de5f67cc04055a4c4c0fba5def8d2caa179331a85501ed25822ae79da9bc815cc39c6a979211083e8683136c942e1e17e9eb8f84aacf091aa1e51665fae446bc48c304af65391f279afb98b92e04c2b73d9d94e991198fe7781f0f9696fcba2c03485f76e6de30b9535cf3903db2f3afa851a47bcde72d4ed2e8fabf9bb7d4696cb4ab8c289b0c21e1f979ebc532e280cd9010df4ee72f84bb9e82752828f167030c0fe348ebc31ec17b8f07d94b
+
+SHAAlg = SHA384
+Msg = 9c63899dfc7bdc0db384727244caf71ecfb9b8792b9f57e936b3c2f5695565a9b0979f3c78fd73f00981813a16da342392fe3ceec6e63ffba191cbeb4f4b90050d2fccd83beb0622b2c3fff159d9e608f3abcb843bdd56c03339b975b9f4e3265b32f6bb6ccdfc6c5752d6e0344d749699c74c85b30c04ff95b272dbcfd6c7d3
+S = 4d38a297302ad0770d9729ce5b7212eef287ce0250f403e32b4acc3617dc0d2edcccc2d580ddbdbca5722b70704058a3b807f592e400bd563fcaa8b066a614b4906f1433968ed2f520a2f6b034d4b2d6890a241afd1adb8639a6cad9dbfd2e278dfebf79740d75f295759d29130b19ab19983dd68f779de41ffefd4e82b5e62f72f90efb73437f08a2503dd9819dae20ba9706c199de9cf884433eeb756286a85eae14bf9f6dbeb705461d91822282f18efbb10589a578f2c9c345b079a7e9dd07fd4b34051b27119729906c77dfb7d2f8fa6bdd5faa1e132bfba9d391e66395e67f01353fa275eace8b53aa91cb6fb693e19191d42a4c1a85a0c504b1c85f49a4d60936dee4646aca62a94aa4bc7828c1ffafde8be656317d506abec179cc90191d12356ff50644d3e01aa5bcfdd71d3c828dc3539dc0cf3fe8b9b91e0c2524f6a3710379c90affd0d0a50d74387f9ca88b46463ef1bdba58cc9a36e5c2c435a20d968350d15d941c3212cdce815592b310d259860de1dc1a3d70ac22302a51
+
+SHAAlg = SHA384
+Msg = 04846c2e676ac73160bf4e45652bdc6cc4d4c9284577b4320ab77f6ebbb59a1fe0e085588e0f90b346cde6441af3c9d0117d1f3bcd962e406bf5a465ab6cda2d51be598fcbb29ea713651aacd7e47d22d8fa3450904730f51792ea374761a4dc1fc6f1bc657b77768f31f463e4267fc8dff61150d4b343b9d53759cdd7b98094
+S = 103bee57e25be8c3a2f774e739b47f93435e414932c0494b6b6aa2475bf7c9305c73747e0adf82c2032007b3f75a69c93112617a62566c5a2deaa25fb95209da49fe9c161cb2ffa40fd9d77f1ff660c8b6cd3b54e3e79a759c57c5719802c9311db704ba3c67b4a3113754a41b8da59c645be3909e7db7e7cf7294dab44f74240f81a281eecd6ef31c7cf18b1a19c7d02a312b91d6edfaa954462d34740af5ab708db5a10b00c542be82fa2b2026b09ef38a4001457e27a6023770e4b4d5003267c85c9eea1d5f8d770bd40b554d5b4daf146dccabac3ea8a13a05c3bddfc971c5158fac027ca19b7232621e9d2e37b6a655af545e44a298be78cd475c22a48bff7c3494a5f8a6abdf1a46f9de082e374fd598867d61e4d51daed84152e43cc6a2affae205edc52613480d411aba84fcc9b69d1c28f16f76836901a7c5b3eb2f2c940d0a3fad38a8efab968a0c85eb22e11d3d0861136ced5f06734fdf8d4f151d23861b1cba9b9c580d3350c76d4dc808461d5f872ec548b2b427dff74b1d1a
+
+SHAAlg = SHA512
+Msg = db6c9d4badb1d9b74d68346448b4d5340631783b5a35ac2458563ed0672cf54197587fb734c4ac189b2dda954cdfb18b41c010a77e90464eea6f863c5da0956bfa8cc636bf0a28be5addfe8d3e7e6f79f71d7fcbbae23ea141783f91d6cc4c8fad125811760ab57133818892471a79c6d04eafef37b2fbe506785318f9398377
+S = d480d5a979ad1a0c4ca329ebd88a4aa6948a8cf66a3c0bfee2254409c53054d6fff59f72a46f02c668146a144f8f2ba7c4e6b4de31400eba00ae3ee87589dcb6ea139e70f7704f691bc37d722f62bb3b2cd303a34d92fde4deb54a64dd39184382d59ccaf0c07a7ea4107d0808260ed8d421cb8b1407cdf9e915159282b9f7bffdbf40d877885da7399edebd300a7e77a908f756659a1824f95c8a812aa540ebaa64ab54a233723db55caa8b4466ea9ae6614ad1bb869e9d8e0d032f3901671e94c0b673be6537cd54278ed3da2e1edbc04ee3a9e8070d73ba0ffb93e60f30b87ff3862e9c53908f2c8e99915668c1f46635e05bf7163051ff9d92bc71a626553c69dfdd06a49f7ff1ed51e918f3ed801dae62ca276d7063d72a6ebc136ba06cfedf5aa23277e81008c63b2e0083d0fd6814f6d4b4b40a42e8c0206f3c356a5ec709b7c8a4b74b7b48d53c9d8694d27359c2c7701938d2f0161721a57313bb1a2e11da215872498182493d8517043b4c03f93446aac93830276542026ce83055
+
+SHAAlg = SHA512
+Msg = d5dd3b6ce9772d9a97fe21648497783bac5bb5254aad82b6f7cbf43b15a40f386eea8d151967db149e9465865968133f246e1347301adad2345d6572ca77c58c150dda09a87b5f4da36b266d1fa7a59ccd2bb2e7d97f8b2315431923530b762e126eacaf5e5ac02ff1aaef819efb373cf0bb196f0e829e8fe1a698b4790a2a05
+S = bf9e8b4f2ae513f73d788958003733dbe20957b147b17c3f4fd6d024e8e83f07b65d9f3dbc3b1fe84da021ceabfccd8c57a014fbe5a2bce3e4051b7d03e09fc0350b6a21fad214ae7a073277c77a40dc44a5aeea5194a756b69c93977b69ee9294360eaa73a574548fa6a974a7cd5a6adcf09e80631156af85a8e5c5317e189eead47e2ead65c381396b5cacde260e937284a8e90eff2cbcb9dee22925f2f7256f74c67cf3ffc7b8ce657e8d135f0f376d9d936a79792c981614d98e3f7d662a4fd46dcda96916b32f366ed27dab188f184b984df0b559710d8ff2040be462f91943501bda4840fdd5c8ec15d189064def756e545db319e007c433f0468a6723357ba47d156ab7652b06ae2b18874f0771c626466dbd6423e6cbc518b5e4ae7b8f15e0f2d0471a9516dfa9591697f742862324d8d103fb631d6c2073d406b65cdee7bda543e2e9ebff9906985d1cb365172ea623ed7aa4c7a322f0984680e34e99bc6231b02e3d14581608bc55bca7fbe22d7f03e904da4552e009e5607f0418
+
+SHAAlg = SHA512
+Msg = 591652b6eb1b52c9bebd583256c2228680110b878917dea5ad69e8c5d2ab514277b0ac31e7e2cceab2e5d9c45d77a41f599b38a832f6b2d8097952be4440d1ff84baf51bd70b64f130aeb686145fcd02953869fb841af7f6e34eaa2b996ccd89697c58fa255cc1e81f621400e14146361e31c709e84a56082231199539f7ede9
+S = 1de79d7216dde125deb77c34d90ab321a4de5fb11c296656ad9bf9a24653591117ace415e18eadce92823f31afe56fc8e29494e37cf2ba85abc3bac66e019584799aee234ad5559e21c7fd4ffd24d82649f679b4c05d8c15d3d4574a2e76b1f3ee9f8dec0af60b0ced1be8a19c2fa71bcbc1fb190899ec8556958e0782ace7196b36658656cf364d3773de86260fd8987604ef35eae8f38ec2cb0da864cca719219c2ad71c08506c412ec77995f37439c856977b71dfb9647990ef70faf43273ae60839cd0679ec9aa42bf914e421b797cba218a400ff9dbaa206cb9c2b0596c709a322b73cb82721d79f9db24211bf075a1cef74e8f6d2ba07fe0dc8a60f48af511ad469dcd06e07a4ce68072139c46d8be5e721253c3b18b3c94485ce55c0e7c1cbc39b77bc6bb7e5e9f42b1539e442da857658c9e771ccb86be7397647efbc0ccb2c3ad31ac4e32bf248cc0ced3a4f094526b25631cb50247096129b08a9c2cdfb775978b0feee265a6c41991c1dc4452615b78c906c7ed1bd207969d98d0
+
+SHAAlg = SHA512
+Msg = 8dffaa9151271ad22622f228c892e1d9748b3c394397f2cbb6febeaa9244a027eef28db48a9a660162152764830f617e1ec6ea1cdb0ed25b6f999a107175a16669d6dfc92b16d50363fac4a570371ea976343a55ae124b6301ea935ed655d44f28320899dba35122505933b3371201a2a45f95ae65ab442a9479125e68ed212a
+S = b329aef83a56ddc57cd9a0e15eb0b0b7aea7d78d5e8ca3982bd31cc825a0cd1c444d9f7bea9e7a27f3bbb3761060ff95fee1a3e864d2108fc40b64786a96a6d62d201217e03a8ba2c07ee94c267149d1e72cc5779b737e8547acd6aa4bba3ff38bf9687e9e82f511b597ad7ec1d795c36a98bf83a90fc86b0cad41953360738921936a458674b2e9a7012ac3029fdb0a9d12318202d2544a0d976ee536e03b7e8d894b3b9c762dab0110849cc1eaad747e3d88d7dcf49f824df027e645c0b9294e655d9fc9e1ef95eb53aaff5775c349486d4b5d67dba29b6217f8b9976612b57e16fc1f99983f2af04579938606879b7c7253e870714b4f0f24e26dc8c7a6fceffb5f98e3b2fb5db949d2f98cd1ae1aa552696b48c39f678e154351cc756d3e9a97f79279853ebd0db9ae6859fb2d5721385d06f5565a3a8ff0992d517acda1af69a92854a1b32a79cb9e442a90b055bb2ec3af8d9926a0d857e3cb1e7e4a7300d1accb9492ec7832af453529ff0f4a6ad3259757f707f713aaa5df231f7487
+
+SHAAlg = SHA512
+Msg = 71d4163e708c121e931bb9692b217dddd35c7346f61cfc9591f7a4313abd4a9262af820bd7eb37e78c2b95b89daf25ec8e783aa1d4b78dbb96852433b4d478b109a6d65eed7d06f3fe122b172149eae7c365ced66578ebb7571ec218c36b65d2ee22dcdebb28c66a7138432cbdd712f7fb8bf78cb14860b25c2b4789706b5a1b
+S = 2522ee3bda30c0434e54b199da8c9733964fd402b707f5b330f4f754a0502c7a713c7814f0e851a4a4db72690db96ea8b8813bd8629a948bb30c1b8272a816b30a755fc6fb1754167c3eb1f194395907a56cf5a73b4154383a05b78b731fedd9077f3c2267a5cf926697871fe0a4bed9c219552dd1c87aff50613094bcaa2dec42a35380a6bac673da2594f824a8f32f21d7593a3e49c78ee280193a478621d3b095c16dce72935314d4a2323eebe7855ca4738a19b5a31a5f95ab91fbe1289c02fea7a65b91327b7b9790556289e1b988e45d50eb8cea1581de5d5dfd21001c73b43921d8b21b9644b0f2b96ee6b09d73709c33338143d6a2fec559a436c5ec865d3acca5fee654f1325ae57255dfd42188c84dcb1f7c1e86028a74e31d736078741ee97c39a56e4de00fc12b8051835bbd0d8fcae737322099adc1017107022dd15c114da57e78b95681ba9945615b59da90f5a2a99a252eb42b2006eedd6e78476c2905473ee6b4f23c1c5cf0b80451c5426ea009141cb3fcb0df2ded92be
+
+SHAAlg = SHA512
+Msg = d00e1529228c79a20a1c3668ffa4a54140bb170bc5c669fd7560d9309900175e91d5a0e9c5f5471fdfb714bc385d52b08ff7e4230184d8b735593f0dd8c73b8a49f8595b951a21b6a5bfec63b684f67c0af1b471dda1684e9ba3f241501fe957603dea86784230f0c4fd65666361b82b187330fb4267404c0e059bd4eb52494b
+S = 1835dd97e5093a33ce1e62d683863f6b3507f358a62fc879b524350fbc7330681cb0c682eef4330419caf8543bd9269b6d91d8e107ec38b6e9c6eaabf906457205d52a900e05579aa11fc581375264e69a925798e5a348e5a16f1567d5d0e40853380b34deac93ad7377aae8a27b090d0d3a92bf7a824d926e2e35a0c3bd0e990b591120d74dd9b052a73568e3c3f29c5a77fb1c921bce9c1e7f764aa67bac119f5839a5303860edeb634814c2386c831fee6200cf55b6bfea058b795a0fcf26eb7216ae1b7587c82e5685e584170cbddc89a77e0989d4ce5c3c7fdb664aaeaadbce1f231e64798f6f9a85456b5a93a502126a80e2d21f46921cc3601f5ecdbd56998a63b865fce7eb299f76af40e91281bfc019f40e0d46811e383691e4024c94566f18024ff2b22aa7e1270233ff16e92f89c68509ea0be2d34511581d472207d1b65f7ede45133de87a5ffb9262c1ff84088ff04c0183f48467996a94d82ba7510cb0b36cf2548209a50603375cb82e678f51493345ca33f9345ffdf54be9
+
+SHAAlg = SHA512
+Msg = a35926685561f09f30925e94d74e5661892a2ddd524f751f8321163d611ea1591a08e0dffd46b208e98815a306aa8514b4db859dc1fe7bdcdf50c095554bf8b2f4cb9f884d70e55c2143bc26199c2f94b743f5528dd54689ad69eda660749f5c1bea8becaea632a4bf0c79a577edfcea7baaa6861e9d7f2dd5b4c4f6eb5f3d5f
+S = b1a9c45a264d2c9af441a7b2d330dd788089ccef205d5d666bfe864367be9738124e9d74648ad99160bd3af81a81858babe667a5d95c980fe2f6ac34861eb2ec9b4b4e8b642ef3820f56ca388a556530d42754c47212e9b2f25238a1ef5afe29be63408cf38caa2d23a78824ae0b925975d3e983558df6d2e9b1d34a18b1d973ffaccc745e527ce76c663e903719355e45cd6d118ed0b85b70cbb8e496411353f84f8866a01fadc819ca0ff95bbe2cc68c8cf78da5581becc96247b911d185ed1fae36c4cad26208eb80883f42a08123dac68d88f2f9893cde02ef5a57661db2b3e1e9269cbb0e15c407bcf55d92e679383c90802cd0bffd469646dcb60ca01a1dead43228934018391dd81f8b7e797e527fbe1815b91bf3cd6a1f2ffbf5dd166acd5526761ca8bab5d463fb9fb820659f5cd50f8150f12f7e8d52e77773c1e6480c2cc184d411d641f71a9dedc2c5fc2ec37a2770a9383bfbf6a489cf32b56a12cf99378e39b50bdadb9f0591b2065f9d44e511c9dfb6158fddddd1bc2cece6
+
+SHAAlg = SHA512
+Msg = 1271a0ddb99a0e1e9a501ca33c131b0a1c7820a397790869090fba373703ac38ea00a9a0ddeed199d97be1801ffab45206710a61e5ed894c3319012ded0ff414386e56b548ad915d80afcc2bdb976d7c8adddca7dfa28aeb694033a5612660c644e32f85c2805651d713660a38914d70f0e41fdc4b3d162ef3acd70659eef637
+S = bffd010b2ec4e4a32777b77619b87622f8921dab56e102c8d824fe52b5df7a203fe71799eeafdcc0c8872dba6a374407b5639aeb5a30a904712f15097dba0f2d62e845412395cf09540abd6e10c1a2e23dbf2fe1dfd2b02af4eea47515957fa3738b06411a551f8f8dc4b85ea7f5a3a1e26ccc4498bd64af8038c1da5cbd8e80b3cbacdef1a41ec5af205566c8dd80b2eadaf97dd0aa9833ba3fd0e4b673e2f8960b04eda76161643914242b961e74deae497caf005b00515d78492ec2c2deb60a57b9dce36e68dd82007d942ae7c023e1210f0be8a3eb3f004824074b8f725eaf8ac773e60fbbb7cba9630e88b69c8bcb2d74dbdb29bfff8b22545b80bb634e4c05f73e002a928efd5a6aa45621ce1b032a2244de48f4df4358156678cbe039c9ebe4cee945a25b9038469fe00c3092936a8cff9369045f906733a9d2ab3660182069b157ca8f9b99a71fc153c68301e97a38fc3a87ae2b6f03754e6da82d0b0726e0703979c9320289feefbcddcd9d706b71b51e9a1b9dc1412e6ed4b56676
+
+SHAAlg = SHA512
+Msg = f30c783b4eaeb465767fa1b96d0af52435d85fab912b6aba10efa5b946ed01e15d427a4ecd0ff9556773791798b66956ecc75288d1e9ba2a9ea94857d3132999a225b1ffaf844670156e7a3ea9f077fe8259a098b9ee759a6ddfb7d20a7acd1bcb9f67777e74615e8859ea56281fe5c400748f02d1a263b1867a3b51748ab70f
+S = 345e2f60f7c82c89ef7dfd7dff2bc2348bab020479330899d4410213b35e98d9bac92fd8ae806b5bce8a6c4bd8275b0facb4dd13f9d68ba67141fa5085264da6dd685a6d212170a2c9cbf2cf5930180effc250868c984bf50ff69d6069ea28f5bc1b63705d0732416fd829a5f5d6217462c22a33fd4652f7c1d198794646c08406024e8163a7ebe39cfb514c5443897b5894dd19a213e037f27e0ffbd6c5447a805a54dfdf4f65819d4e0fbee25e3dac47fb6b636e8de6190adccbcee937d0977b35b973606b0ca348758b50cdbba028b73d0ef01c56014c031c598fe8db87d2ca4644770aaa0451c376ded82ff5c6b8e7d2ed9d1c8a17c3122c128273c60fd1b0088dfbc9c927f162e43879405964cb11ef7899123feb8f88dd2734df98aa696d936a8df07000e84af90101f7006a9bd2549fdd0ad3f9de093012d32d2afaa828017ee9c607cbf5b54f223666d4b5f3e26e0dfec003961b83d83de39ff6a0e81e1883c1db4aaaf082fec5aa30a7e578553d89774c67907790c96dc4f5be4c8c
+
+SHAAlg = SHA512
+Msg = 132cf50c66ac4cc54339751a0ebb865e1d3d320562fc905c4abd1e78e464066c46c3a0c02db0371ee35a104d66dda864c6133e37cfad9116e883ebb73b295e7016c34ea9911a309272ef90114d8f59fff0a75193fe5ae31ed99121f9c59209bc4bd507b1dc12bc89b79ffe4d0df9209762a1730136290cdee58ec828ccc88eba
+S = b12503b7b2f783618884174bcb9be10877960431ed6363c807e12db71b8b6bd9d6401d064e253740158e8b900152d37faf20333a7d80b3d47c7c7a3fa12091ce31cd8aae272a4da15fe2cb5cfdea541195a469c96bcf695e0b526dfa48a59003c6763af8136392c4b8d24db314746f42aca550acc65e074913ab82232eb8593509158a8ba34bc0f0e3125a834a3ed2d6a8cb1d085f234ae868b86aea8d6f82e13a08842485066e48aae4837873150f44475e12602b552dcb34d1f9fdaadbc6bff5134c6fc76263888be67efe63ee1840fa08c49938858a9d48b1058d18976bf2e3bfc625552f75b3ea44eb91dd366865f240a0c336a0110e0fa09d09cd94c70cbc8895ae3d44ae3dff545f0e8c8cc662ecd40f9099a952494396c6b423ebb463409969281cdd54ad87a308e487ce19745b30d5da76b98d2aa9a007a55783b3037e5b8662322810bdd11d86dc3f61451149391fb2f14ed9c17c751623a4042ce7edb875ee27bcd1f19d6dc9283ad06d15e097e2b0b15a7eb7128adbca0aa6adcc
+
diff --git a/jdk/test/sun/security/rsa/SigGen15_186-3_TruncatedSHAs.txt b/jdk/test/sun/security/rsa/SigGen15_186-3_TruncatedSHAs.txt
new file mode 100644
index 0000000..a5f9ec4
--- /dev/null
+++ b/jdk/test/sun/security/rsa/SigGen15_186-3_TruncatedSHAs.txt
@@ -0,0 +1,233 @@
+# CAVS 17.6
+# "FIPS186-4 - SigGen RSA PKCS#1 Ver 1.5" information for "testverforgen"
+# Combinations selected:Mod Size 2048 with SHA-512/224 SHA-512/256; Mod Size 3072 with SHA-512/224 SHA-512/256
+# Generated on Mon May 11 12:12:05 2015
+
+[mod = 2048]
+
+n = d39a426f8b81cd954f3df5512d6fcdb796457c172b6d510247e45ebecd1e0f7e8aa3253a61293a7b70094b70d65d73828719ef6aaabbb24e083b943be775b0bf3b5a0dc8388433de78e0c113ef7763f767ddd1542bcbdd9845919886ce20e28922754af2a733204bce9b5bd50140e18e5ba91e4800b50ef30ecd48b4ecded67a2f7be8bf7d7f14378a8c9ba0e6103d02f1685a334e46713033c89908da2e9f8bf72cb2a529281d4dc66799cc2a63c872b6bd5ffc1fa9ada236e7f8d5796dd9724e5e4ccadaf160de7f2d69c84009d31e952ac808c89a784be70cf60f42811928abdec6f896a0fa5fb164f9f4298a5a8831f6684dae31f2e76146d6be14c3ea7d
+
+e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101957
+d = 057076fbab758efba2945f16d3456c21df4b7cfe1a8a762af8389e42e0b648f4d452d8bdffdf2097f75bc661efe939dd99c170c1672c9a0f21ad450347333fdc52f350d02ca1e6516cdbee38d3eb56b15f3f062b0d4f0901ed9a05a566917c5c108b20e0da091b8ca9da43b7b066d8c28d849068f6eb803d8e84ff243172c258cd7bd18858d2648dd7a55a2cb4db3feaf3171846e3e2c883f50a192be5ab4c79dd330584adcae17f1458bcb2ab43e3929cbef840e9999bf0eb5601e88ff8758db564a756346d65d8c55f1b11b9b092fca7f6b2394ebc3109b3d02ec5a0967ea645d127fe0fb9f9fa71637ac6f0b92671809f4aad1278a6cb5e8a7247fe53afdf
+
+SHAAlg = SHA512/224
+Msg = 2ed1a4a7188b534678ece3b40ecca29e2359d2c8b5aff149d4a93ef84cf67822846fe97ea6a7a36200c40a36ab8e922a6ac6ca24d4b99afcb615c8ecb3fac1422d549758696946c6edae3bd62ddf1739674eb0f8cc7c58ade0e663f22321e31af129b61fa7f7c3dc0751807cdee6b833e39a8b2ce31fb6c21bc514f2e6936510
+S = bb2969df7eac0f17e07992c00c8b561d1c21482f042a4fc95b739aace629a12f6086e399bff9aa71268203c1656ddfc890570bf49dc75d8a7bc510413135ef931473b0ba77af4e5691970466bc2a5ef811b4eb94269173bb365ed28688c0078a11e0776ed7f539717209536079dc7af515386698c1e539dcf0b3c08e584e3bef987702aa02e5ab329725026dcf3fe64193a4e27451e5e77713908f07c742af0a2583a04c1f1a0ac4e9af5878a9c8e53ac1eba469ceef836f3f6eb9ee2625feaf933905c308c21aa75a76cde1d8bc41cf77beeed6919dd75d3834b3135a781cce01a04b468f339bbd21c74a323793c8f439e6df0f3dd4226e5ba8c712b29f7acc
+
+SHAAlg = SHA512/224
+Msg = 0553550199e9dfb9ac4260d6b44e1376e7b9083af2ca764bef8b529b912a206ea29f0a18b08f2f0803703d05d2ef42b8b68ebf6b5e92ff10851ca68521968d16dd50cd44ca6b1ac451f753cb6d58568917ee19f301f5f7c686a947c9e1ae33529eb0c80b4f4749f6801dc9afed52f8f2f21f3e5c42ba0676dc7a5def3b3cbb29
+S = 7cd30a88ee2da986e79b74a23a1831e4a95f9cbe665c9ee2e87b55dd13cc71791377c532a55a437dd4c473aec38bb094c876f67b62b03d473cbf868eb56add83981ced4e4aac6deef6835378e8916a434b9119d5d89204b858913889a4a1682c711bd1b951d354902758d0ef78cfd63b6b45d7d5433f3d4dd52e945be9d9d86c620585df3592a51b5855fa412ace6131c14be6ecd77f15ab7e77f55255bd5ad2edfdf8a1830b4be0836b21f806920c6998ccc3262b971cd4ee0ca48a60fb90606fa0c16d7141a92cac3c3c561d0673d700b0539e8b512d4764e5be5a9ab41d295d1a1e80f342a4ae2df75ac5dfc7d5f44d3e9bdee9cf25e7d2f04fc707b92cdf
+
+
+SHAAlg = SHA512/224
+Msg = 63f2e16f20af0c0366156f5c16138b075bb7879f30a1d2e523b60a1358191d6ed057ae1bebe1ba332cc07b1a3d848c0c337d4ff8122e8c9294ff5aa4263243a43418a38ca68551e6ab818126b540e93dc555236be822535501930957ca0c691b169f896b59831a4369c14b2b8631eac399a5cca0b9647056f3dadfd64b8dd6fb
+S = 796cba47cc498f03e78aca4b5919b6f0df5ed22e8d62b1124a6633033dbccd2a54aa9721d00a1e6854c1fc348686ad5cc86055e0454ab55365cd871d1fb6be5575eeecc10f1b66e4d4e4930bcadce6cd2d8bd4af1abb2ff7d905475e29e4e2eefb71d6ac7da59ba2efdc8ea16c2fe5d130fb6d002a7ed81e88a29c08010766c74f192c8741bf36f739198bbcce1e44a86d09251f8737b3089fe145e110bd2ed116635d7a6ee09590a390ff4599dd08a50900f283e2dd1c1760bd9b0eb8603fc17c6f8bb58aedf985b5a58784b1b0162d8532244835092afe4f647ce3110beb934192c8fa80c202e1777511f74734d8ac138c3d18a605b4c7250757738e2c86f8
+
+
+SHAAlg = SHA512/224
+Msg = 4b94be1d97d9b71f112bbc5abc55fe9160cab66726e65cc462771a7ab07c8029422d7960783b7e04b15809f662fa4df0655c24b093c64959940fc716f660b1007d3a1442babb2a7adf1dd063d27f3ab280e8e63d7489ce62a842e2a79b68b59ea3c6770c85e123494381f9ea356c2f9e5b75e456f2b555a945195376c61df5cb
+S = ac4dd101f9d7afc504da2d6f920a4b0075eb04604bab6fb9602eed006b3cb19ec14ff9ecd175df7ced0a06f0c2b6270b9fb022eb4950c570f636dbe134070c8b2b3b4a3f47f843c3a9ef27806b5ce8d857807491771134ca4df42b68c51d2181c788ab78916b296b75796b7b8e65487e962fca3f1ef941748cafecb184cd1ce5e0a7a9af1c4c11b08b0f78f287c9e4227621da2d5040424645c9613b0630a239cc46977e9bcc92099d471a696955b939831454b4896cf0e453d2daafb56793adda28fd5667e7448f594a4c7c080f2707dcffceb739e431e0309fdcdc6129167c083ac223d1d5490fe6c9f6b46338b6482589850cc5815777099d48432155d39c
+
+
+SHAAlg = SHA512/224
+Msg = eda30ca60e21329172c70ed55f113a716b911222ec91c629b0faad4eee75dc257dcff89044a24885f2320e11ef95189d9217927194dc1e76c4c72740fd9b714b5560f5859809ed0df5532b3bf6f0aee0b6e577cf4e31999c90af90a3f83dd34cdf1ead8ef29d48b2e3f30b5a5e6b25c13fc46a4402d75f227a7a9080c6a32ab0
+S = 5f7c8326b43a402c8593c4972a127b6573fe9f482ccda74c476981ba329da45d4d4c5b1b5030f6b9bfee4f5d8baad7c09f0e25b69b938fb61519ee37fe8f3b9ac22b8dc34fa30d02d5ce942ddef0bbdc0d1a340ca06d0433ff319eed5963c0e647acfdb772623e743334ba2514dc67095cb4c3ded5ea0236ace1104cb9092b9bdd1dc9e730ef5d2f8b2a34735d33ca86b57fff5340e0e7ef4693e6cb0c178b26524e250376f7eb0a52c33891f7e19aae2b2647f5104606b7f6638c0782f6daef8186e22d35de9329447eaf4a61e8411edcfaa19c2d39332671ba402b96e1769001278aa1218589b15b6cb154e6283b43e2537db37a8080583b09a4788a5cbb7e
+
+
+SHAAlg = SHA512/224
+Msg = 0219c1b20f988cb51c781ea982b5528ca14810363af7ced31a715696f99acaaca124e66f535f86dd66526848310a324e2b32b70c51e4768fc8bf638bc43aeb50a83732f96fdc9fe74a9e9a6e8a9e94cdc139486424da412134139d3c9eed10245f7c2cb92bb6dfbb10853d82571a7ff0ab854ca57d823871a6968b0f4e5b4310
+S = 858b91cc53411dbed6483fd904ab75820f8c8c9519297c472438492a2bda440aa6ae35dcdfdcefd26641a85f33540e0880da323f09af8787cdf5e160e793de127882edeb1eb045f29146616cdad622abd183b60c051b54adf8fa20726f4e88cc54c0bd9723d3553eb7d0687ce0fbc43e53e2e8eeba009b7545e97de3a457a8e7516d3d5ac4f18a98cf678e076d3a8e3644919afebc2a785567abec9f8de54e5ba051620a709d2bfddf0679666ae17b1cb6d7cdc5164728d2d77a7013392b418c0e87a4a89d396ea955cbc347365f67a5e711504fbe499715ff0764feb75dc0956eacd964ad41d399bf17825a2f4c33b710783903367d3f50994e3eebc634caf0
+
+
+SHAAlg = SHA512/224
+Msg = 8bf4a151ce9d8b24dc1a65e006c04024ffcb7c9d4cfddecef688e210822e53d722a718382d4351a8cdd0a307f8becfdda1818ae32f3789c52e8bdb2644d97be46793269e4ee36a742591000e85285be0a35481acc88f1a4801fcc6a11793b400c17f718c19c4fd114d2524ff97450bb66f0c0a00ff4cb9dfd7a54e8ae2a626b2
+S = 2da985add2123356dbac7b673198cedf499d7f0fd0db13dfd4e56ffee3f267d82e0c4dc0e64696817255b8dc6db336ef0be6a170dc30ada05466edefc04f5e36afe144debce14be4500bfbf87619c0968283b2d2e4b8068f10db18b64668d1d0345befac543971a2c2fa9f1a41fc2dbf6a4ab0f649b6c639af54b52a39d7d1af0da135e0414ae89a1cccb3a944a99a719e4fa6461757e0d1ae26f551a9337c557435832b30a3a42dafdbd43294d3aeaf52e7086ec8e47509e0a281207a3d4980240d2c11a5a577dee6e8fd61b9b90e91c4bc8f5157d004d5e4cf6c42c2dd8bfa253742f27d36d709cb2382e54103d911ba9230e4e348c822f9468525d46abb5a
+
+
+SHAAlg = SHA512/224
+Msg = f1de99141084e4bbbdd13b3ce88c97bdec31d9a8599fb000f611bcf6064ff4b7cb26458949157b164c496507accc34d5d0f925dc713360b2a0d61fb60b6e12ec7c270308a285b6c81455138793e486108f6ea7b0edd9168f08a3a93ff61aca960ccb1ab9a43c5b7a1dde8ce4243d5513327aa64a56fb9c3f3561a4b94fbae25d
+S = c6201050e62d28500cce52aaebdebf30a008c6f491715d75cd60a3e9b5230e88e902120e536fa269b391e824f262457529e744f13e098e8c43832dc1db1432235b58d88fc35edb4c5de8854d2198a708dcdd274f267d40079169b29b78edc969462fc623cc04269f6eef15b1e6fffda09d618eba04512371a855225ae5cb95b3ad455373ba2734879ef6e711c3cc7cdad9b107bed385a29124307e8e3b2bc506923f08802446d1c0e6d91208b5242f20ed2637cd47a20f7e1839de8fb77109467f4cfd6e04080d5d8fbcf2c3ba7e7324c2d26ded80b90b053d8b431879ab73fc587c0383f59ad7382fc20589a740d139b8b60aebddaed1866a6c47788207b782
+
+
+SHAAlg = SHA512/224
+Msg = daa7f32aa297904a9cd29e24437efa2f02e611393c73fefd8fd8f2f75a8cd9777c7d3af55f035fa43612b74982b5784edbb78812eda39e84c1f0a5f03e756119ef23548706f2e322a11cb5004d8a5c7cc88b37880ccc9644888520cfb1f0725cb9ff09899e4e62ed67575ff0abe5ede052cbe4419fd52f646fff2c3bbbe5556b
+S = 1a38bf4fdb86d3838b7ec493930b8833a65aeec2cff022f24cbdcef0687e00043d815bb680a394bb64922a97f92b908a028698dac233219801cb353406b5dbe638d0e03865916905b124b88c58dd349b7cae77964a54ce019e9f98cf3fc48f9f735b28d4ac471a423851e13cddc377997b33337f0496720b3bcc628ff33d1f710b6880f19957c144748d0c189a9c3502697c0f06f5e29271cf52c3a3f8ff489abb55eb26cfdda242b0e7f9fe2c9e8cfba5fc20dab7220a62b391f61d8d95f7d4d623f6c39951f07f071918b462f971c70937674abfdd2c4eff79e7953d4214b217f972e0a2ea6fabeea818d830d723af1c07c23cefd7b55a30c0be2d452d1f02
+
+
+SHAAlg = SHA512/224
+Msg = e46df524b45b52dc601c061ad57317e1d6acf4eefd8ca04cfc8413232929ded13ae90d3b4cf651652b875f41cd4093c51feed9400578cdee9b1321cac2b43fa3d8cb3072c62ebdeb4053d45248c32d90f4cb2c8672750aa149b730afe1e9e3f1467c267129eadc9528e92ef54fe42c6adeabb7674c6a9e8d8dd8077991b011e1
+S = c66d6dd789496caa62af318c023b24fe99444c0a2f179414c03c03aa3bcfd547d74e56cbc2c48a4678ffa3904964c0b836717d115538d386138096dec8e5a329e16183a2096dddc6a0e3c559c3d273568eefdf3d75e5af3bd433e3657892700b95fdb408f8e5653c48cf5672cf9d838a9a75fbffeb5b85fa8453198f566195a3bc2e2bd900d15b752b5395b8f79226748fa2e39d6d2efd701bc86d18f6e1582b2129bc7b961d8fc0d00f464c7922b8ab3d860d021ecc40df63bd8844d47a8f9d1c4d919f85da59c0c048db5b5fb64057be25fee66966c7486a796fe94f6c32b5464e87b6b59e30cb63253f5896a03ba55866ed2e8c8414af2823b11b43446a8b
+
+
+SHAAlg = SHA512/256
+Msg = ebd3a776554384912b8b900160a07c024f3ca4d05229411090bce06b16a0137c2ad466ecdbf794dbddc4fb8294d94e176fbc8af1771f2bed28639f107f5cfb6e5454ed4aea52f17ec59cc81ebb7a27584e3dac9e3980150849aeb4f36ec41eef125824d8a9db04428a1be01afd0b6e8b95c7f21fc0d369279ca3075c0c61e4c6
+S = 802fed875ef06dd2fad2ef123f14b360c0ed51eada42b4db56d8e62627a85a18fc15eacd2467d76e84efd1245e4e62ff9dd7c5dbcfb3c83d9cad6e0be064a3cb0100f3ffcd4c4025d654174a91a0b13767f5f8352305e61d54cfc61b9b801c57e1287e759ea1599b68bfcbba043d776e3f1e75887a1cc5d1ab878418bc15a356b479e6b4d12b7d49de850b2976b8113135c0df094ee476a5d6ba3b2a3a03ecf1f6e97f1e0c3ad17245221449a1e0b69b9441d97f596cffdbd93041b11757d19d6a3a07c7d204eb0f53ac94a5e3bc69d8c49cf1bfa4ee9c1e4c077c5a18296bef3a0db41524feee3cc83c2c2642c633436e635f11b43056c8c590f02ba3d2dfae
+
+
+SHAAlg = SHA512/256
+Msg = 266070328b55680fe6ae6154c257ea69b71cf487eb177bcad96a69875134b7dfc0bdd594b2f44c1c951ca2f4c0c27d37b4f20c6fa1aaa3ab2c8fa5d26fdfa73641a7d26cb836895cedd14c94ffa8dde25b09a1213ad448536b2fb1f0527a077e31863162a60169f675352adb88f3509134c97b44be7bb4e91eb1538a02ee1fde
+S = c0ac3e5e77fedc499caa520f186135588f3e49e2034c22ca5b74951d41f73bc656ee958bc43e9fc460db006c94e46b03f05c5a730b16e6f0ee78ae32cc6fdf40994fdc978529f97452db1f7acea4b8eed5aca0a29d7e27e5625aefff258b8f1468590445202cac19d47fca0b0f51e1f4d6dbe53d9e5abd26f889354ec2ab369782f4f1974f6a96141d509cec6e575e83dd7175c61923bde8c022242c089e080eb209604d90aaf8e75771b13497236ab10c37fb9eccb13ca8ced8f54ece38b0ee40938464d9a423bed7d99a2d5ba186bd0950b201511bcd79e379fc3bf254bc519f61beb06ab3bb1e1efaefa185fb9db286043752cfd9590a292650bc86e3f8b8
+
+
+SHAAlg = SHA512/256
+Msg = 379c93ef037a702fff952ffcb463419aa861f99682aadbfc6ec816cac3ca4fa5e496a0cb6481e1496d1d266e6252887fc3b129ac51047243732a9f24d9227e755f6573963479c0573bc30369b19d001311a8a12634633b33bdfd13fbb468212771af143abc8996c3322ed0d7eb6931be59ef6bed73efbf3413ea7b399dc5c125
+S = 4f11c9706aadddb4e1b7eb2bb3bb103622e196f1910263051797eb50144be64bff13e9ed98a0359010fbba008b326b2b32b576d027dd27f72b25309af9f9ed7055ba450bed042aa6139c7267bdb0a2e7ce42825e85a408c436cb34777229709d1002e8cc674bac7181de213976a204c34aacb705c09d113df285a3033f8d613efc0a1b76c323931c9ad57ece6c92ee5943d3f25edce1c909b2abe53421df9617acf1eb954957feec82270d75818710d0e6902ea907b8ec7b7c46bbd02d5dfca53f7d7638dd600eaadee55d897d03f3be1305f2b55d75df913d2954f0076c622d79a1f6d64e7a010b0c4ce4243869375be5348a330c79d6f23ea022db1848b73e
+
+
+SHAAlg = SHA512/256
+Msg = 5621976367502d7cca6282203b39be61d495771076e3322f6a5627a548394535188476b1b8ad246b7ec0fced1db2f2eacdf38574a642446e4dc59145d359a5dbda27d4c4fa7812b563cab739c3227fa66aa5d550ac6251fc86737f988544e229e4323804f4580041c1a53a6df3326e7ff2d3ef0d4eed61c05d87790626a30406
+S = c7af1eda2595e00132dddaa70c0c661175446cbd0408c22d63e6c3deb0beb7788ea2980996c3bf9ac54237e453ff0c17e50972b1a9ed6edbf36beead7c95b448b6d071595bc768d67813c94da0ad60e0234520db54e8d7c0f1830345d5f69a42fc25f0e4bfb0fc2ab3cc16d6bc1326be091f60f94f4c5329080b4946907b5e65dbb9469da47b6acc0e91784491de3118916837d34f20d6370111c31ac9435f31957c2e11aacf0d8bd035a5babcd24b9c86eb063d60aaba2d82dd2a3b0a9a9d6ae1e00587e10062f9b9e79abc70786ce5f236f76edd3844e094aef5b545e9a1491615a15908e1dd462f0464c2eeaf65bfca63b16e41639bf6329feb1a23f9d4d7
+
+
+SHAAlg = SHA512/256
+Msg = 320844c2661569bb86cc39aadca462569e49f26865406a2ae0ca148eca0c9772196cc922793ec41ff8a03c1f03a2105491ab1ef19e185cebdb2525fca411d0ee327d87161216561fd57383090a401e70699dd81251c1198c75e34c64d25a7e4ce40327a519e34743860db570d8c6b4338ee8c8d26684c89515cb33cd3b2fc715
+S = 9895bac5cc4c597b67fa64d2fdfa04a80f939aeaf2a77008ee3640aabeb7f4c9c9985180943ca6b1f5c69c2a80b82481203a273a097ab695dcb34e5156c2dbc91f8130bb7ad5c41611896f765e9dc00403864f1e0b356ed033dc2bc1ce80af7c5a4db8b5adc46291c1296b4bd07b9b8939b251d6b16e7c381bd9d15679216fdf26d70caef87e98d5626040e6330a1403175ff486fcbd193e490b68874231f286a41ae8d4064746b56d05dbb44606544b826c1a2a640311fea0da8c334700cd24f23dcf04cca02b1ccc926660a40eee4ef52b499e1e6d621adc5d5fba3dd1ad8ec821cce5fdc4f483b37d034b1e43c75260b6e8279aa19368ed11caef97767645
+
+
+SHAAlg = SHA512/256
+Msg = 27ca9976ae87ae9965460706f263a58e73d5b08a6f560b1c0cc52cb783c82be1d2b51837b1b392b2c61c952a1c269418d2c3c8a010c5c7cf3f4658217a4786463f97f3256bf76f22657bc99c9933e5ba280b0f68ddf08f9c64347edeb634d807d838d249c59a6d6fa92b4b664fd2c1fddd762fe9bf1e8c0ce15745f721d748ad
+S = 55e970eeb2e59d99e8dd99624e17dbc6fcd116440a3c52f3ccbe44a1cff830da6ca689eecface8d741f75caf86d32a6c39f40c03fc5c139bac8534c58f110843b7c3be2029077c03c2bba8141f9d3c6ab6bfbc9b50e1e9f01b86c025e8e53dfb08945a9bfebe21d92eca4d6ba17e9287887870aa6128862536b8edec77ef67f7a487cf3efe1abef05c0f91c7bc754a9eaa76f6c52164f603ddac34fcaa48e4b108f1510d0cc07865fcdcce9137fb6e5e9b6056783ae28c85078ccbe79ef13e17bcfb9e144887f7f12e465331ec1aaab017881d7d8535852814a30ce30cc8f43abd8ac1221c3b9075e21a0c7b0b403adba4ff4f03fde2d453fb7982aa045e10fc
+
+
+SHAAlg = SHA512/256
+Msg = f807793110d50bc5b9e8e63f6ea36cc6c60a231c9184677e24de5cccf19427ea5b4c5e66c8a4bc5bf72d1a9594b79af509d0261798871933a6763b415afff36167d5b87926bec920e8981ebb8a9a9ee54add9215d81b5a7ab1b65e2aa8fc487cc5a971b253ad98dc3530daf979d4de5e303a515c7cc7921deaa8aecf02138e04
+S = bc1b30f08663959cc99613a77fbd5fb4708601f3ccb0ea60e8e4097d841dbcee0ccde9c981439f7bc57e4e731b824206c9fc112bacbe1202f241e3e304348ebfe4e1c5fb1ce2f7b8ca13d951b159632743c31bcef015f5b1721adef6dcc8272314e04ff6132aec675899062d22017cebdf9f137c46d8e60136364ae3c1a6ebe162e61e94345b5f01c383a1d0d0e8b40638aa799c2c9232aec1cff1a335b3ca81eea40810ceae8ba0861cc1c58c7167c62e71e2348cbc975cb6d544b11bb18e9126677ff08ef2dda191da6a6b0335830fcd497cbdbc0e93f1af6e76a3d04f0fdb00ccaccf433e395acc3f46a33656a36bf19738e055ab700ac6bf7bf340c3bb15
+
+
+SHAAlg = SHA512/256
+Msg = 6dd9bf3b2c5d312ad15baf8a61d6ff9a751126d8e0a42fb892d0279cbc106c0135f028f61d2218d3c0cf9227bc2bc6f2674c44156b3cbe06b34d0fc88bac7d1b02393bf09396321f057e025c90594368410d1084a016c62b8fd90900753508069c5c020fd8e10a776a1207112387fe62cdfb940dc65bce8fee1d1c2cc3d39629
+S = 0a77f1a9adbecac036af4ac6d9cbb3174cece1e49bda029f488293c560965ee5d4da14739a91f5592363e4e48524e4da509ef42cf89ec1dc0ac15228e7cfcad359294ec054552fe8b4f3b326ae4a423cfbda45035ac60d253c0fc3b8a4f97b1e2868d32ed3d328fa3720ec6930953538ebfdf2ab152df1b7a4d759eeb75a9dad89612819100d60491e0f5df6db1823f6129029a97d3b1b83d167cb5cffde87eede6c866b4c1527b710628c15c9d2506082efe7f3ca29a27853c2b8cf3ed38f95c119c534c69b67d42fc84bfa26410d9954a70a0845bc6a7a360126346861eba3c01a88191c1153892c253f2b9f94848735767abba4cd61b606fe98209b1839a3
+
+
+SHAAlg = SHA512/256
+Msg = 1120ebd1bed0fe7773fbdef2f2eb01f1feebd5381cfca7f297c9c549c6dddf359114b391324fea74396c3cbed376dbf14b180f43d1581df17b826ed58961ed3bedb5b1f10be2dc9dbde6c3539a8d4f6778e8a3802ffbfeeea0b6e33ef627780b2ced2d17d0f09d9a064fb9d9cf9a23fb8b42d818bd4d12940f4e6dab9695484c
+S = b6d865ecf7a530f44db0ec48c9cbc3344fca90f3f995a797721690064481430f70d1c4895792fa96cf30538399bf0d72fd72cad522a0bd8844711767be2ec124afd6721ac1da69b27ab82299e9a04e727114bc18aa7926e2c5d023e9dcae02aefe0dfc6558af44cef4bc2743767f883c61402f6340111610c22fb0bac98bf4ce59f3a68f7bf3b972ab96ede3929a0fc6de4d1ff345fd240554a4a94b9ff1dda1e9f201cc76a68ddbe81a869cbc308051b4d23f4364504c29242c0106a9ffb86c185f70759086a176a0b02387ee274ac7663eeeb7e90125c3c3a939e63b2c6aa7009af62ceae5985e05e8aa9da33f7dda6afe2b2dacf7c67627e1fbb7f627ad0a
+
+
+SHAAlg = SHA512/256
+Msg = 5c8c2f1d7fc7da4e9ba6e5758be726e6e227d7bddb0332228f7e3ecb6ba2e8c3e06b556a5ce077be7a83ded876ebd1b9e3b09e47a0872e9308aedc5d698b87dab790e6b582611c5326398d5b428aef766be3a453211747ef019c85133d312e1e4ac38b04d892f39707909905d809a8a2e18992e846fba4bce40edff3cfdd0315
+S = d1c062a5caade51ffc1b5da0f5aba1c737b5b7b745c8a3afbf8d14806cad6e2707d664aa89266dbc1ed6815659d8481fca830e0191119670f386951420d7347d40f2e94bda8e74db2d169ca4c169fcf63e49d062f96e7fa843f85042a9e291a1c2f1460c6169a529355dd951fc1ad312d6a74d95ab38bce753328f181bfd6973787910b17b31c819b2fa02765ff7567fb99741e1f26a400e754ae01ffc2b1c1cde69b019982697c471fc3091a67c2f08f6728180b22f793cdded0c5ec15ce611ea353886c97bc45779fcb2ac07a40877c1771bba6b337c706f6718d40e1e7591d5a0371d2ee7003c087ce9244f56381a9431ff56ba8d60b170c19e02d65cd226
+
+
+[mod = 3072]
+
+n = a5e68e379f3c4c3c908a04ce63c460423a7a10a16df4da6166fcd8b141000b14c113b216fe4f5f174a5935c937e0c6d83286ba13b137c4d0be7d7b415ced1d6dc0951098a477dac41df6382b9a50108f57455d853d4d8663fefdd5017a533cb71a8707ae4803dc2cb93e5453573652485eaf9e175e095c7fe72df7dbae96902c15ed0ef968835e72cfbd5290d2e3ea35ace7a2d30e58687d388a3a6540cb4706a6e596a8a7cb9e18741c6eab632a2300453fb47d3b543381519b7c727913dbd6e037af5bc8d013c3fd16c04ad2ca464041898c54b0067db757b88dda0a2986b4520c514caa0739b30d1da85c0c84188507ed3979bafb9f8cca0b2d6dde20c6ac06eda11e6a69bd9e9bfc3c35a1d4b52b85568105ed694c33ddc810b1d4a506538cf9f4b3de2fca2bf899c9b8b8911466fc0830cc1f3a9c70356fb9b2cb9a62021674e80e024b89bcfff00e633c548852d4eea21a5e5ffe7f7ff86ace07926f4cd9ebdcfeb90fb2cbaa9152f79223aac5fbcce9e66b6ca9d721f0714e6def0699
+
+
+e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c9c53
+d = 06903d86fc4b1351727ec45d3bae17c70b180f8824a087e8afd452850ee2803afaaf599b71c07982c23cd8b09713cd1e93526ba803898a2674fdb2d8c2716b8da670116ca4aa4fc5f6c020796ad5c27a6d1a27afe8c2806794623116494e6374e773c9b2686f2453da69747ad2e0b68a490e7e513289ace6f6d1a0dd990b222cfadb6a800f9dce7bd3995cda61e1f590e412555515af9b919bb3823da1b5d6beb47fff2a28acf8d7f40dbae7263038680a4b642d8a28048509e2db9d41c65c23eb605a4d1cc64f140ff5ec7d46afaef5532ae140f9a50f9d2763f2d25080b9afc7d35bec13a11d34c4ab95ceebfedf0ceac76e7ab1d66b9dab618aa00667715e6054a06add76a73ac5b9a0fbb7f14015757b9d07c70114f4d3759fac34c22ea8ea1cc9af9761b688fdfdb0f481615675c5b70759a202ed80eac1f60259653537d132bf2edf7770fb376f513056594a558ea9ff66df859ca4cfad1447cde2299fd2658f8db01bdd15abfcef391a1ce4e0d6127dd9464048b2f92a185da88abc6d
+
+SHAAlg = SHA512/224
+Msg = 1480473f19360f666e20dba9f0f29b073932ced8cf9b50529ac473529cfd525adc7962d5a3b34aa3eb0af5d115aee5a8dac0caea84b553585efc447769e0c99450af09069e1cffb32fe285d6e4aab2ff9b2f665b5fa02335db461fbd1566970859696559723ad59f21f0b53ec7adab1265c5ccb1c62369f1fbe92cab085764be
+S = 1f954da53b48fdcf3dc3e82c623881756a17bd938fe0c3610defb7b648b7ca0c274df369a5548edcde37ac77e8ff0703e238a11881e7a9da5b62bdc6147c29526126de03fe75d5e8602cf32936a205c26928d6b590cb10d4d0982f2b7201bbdbeececb9e8bf55ad67012b722243c4aa721ce8370968316fe9326fce6c89c5951ebfdd7c3ce847532a4388a980495af4a6733d823f9dfcd0c19c15332946282f998d38e1992ba4b721c45fca9e51289a9693421206a968a49b14911d89a2fb030e6cb4b949b0a3d6b2486807c8e2f6be81ac4369cce00d600009880503dd4f5635cdeb056b20ed320e9e9eb4432e9c13cc2d091f2be459b3900cff12b2c270d56775ca61b2d80b83528c02d9ce35e42bc36b1a56b3dd6ce4e334b331034e6fc0ba07831905e83d0231e3468db4c04918b5a90d508f597573caa1f265c5e9a25e21801aa6c39ad95b56dd024b3818f82a72892f9827f65e9f5f1346eb71baca0c2f4f2f1ae5f7f249286a4f301e5e32c5746220d41335078cfbc511c19b2ad5ec0
+
+
+
+SHAAlg = SHA512/224
+Msg = 8a09fb05b7e6779636123ac0a347603aa71f6d8f7787ed2a9d7157affbca37920dac8ce26ed46f659e56f6ea028f58db2c5c52125d89c9ed488db0a519742cdbb61cf67445a402a7ee225e54e2945c989c1af39e676263b8206318ae3d4ed1560ec10164433e7584afdd38a64b3db4997ec019dc9bf803b1ac5c57726e406d28
+S = a3baa7ce193ca98c05aeb3defde2820bea072d4dc02737fe8e3492ae4b329a7b1631c9ab4ffb6180d33aa6ca27b639d04fca9dd46ea82f0ce060ae56ac15b52e5116432184ab009e57df080c2ae17ec7a4f33613b846b1609766b084de34c0080d3695eac5dd3eee83ee57bf70b303d5ea7b1a96de0b32578008d6149069767125fa1afd05a54b734c70dd8c58b07d46e7e0d065717a2b445dce21b115522d5c0598504e1fa69a633228b713e4ad280d4d855fd1caefbdc0ff877a003584acc57fa62e791d165f5d63d33d8087c302311d7889c59443406708566bd2446bebbdf975dec7d42af661f75ea9b37a0e85de3e7d59fa53a62ffdcae04b1ed6d9cb69ac586b948dcb645bc6cde6789d465a1b723d8504cbbff1c27aa7c9fc0e8e8c697e253ad1d81ca6f56e6c7305b7b51ea93081a75b5d8588357f6afe8919122f79e63ef7ecee572bc1d016e68ba1ad93c5d4aa26faf638abe09a34b1afcbafaf4c32d15998119350a39df6b48affbda59ea642bc4aeb869a8dbcbd2a5a31e68f8b
+
+
+
+SHAAlg = SHA512/224
+Msg = d3472740773ed7b3d637edab7ed397711e591121f758bc688d8e6f8da20911ae648c684de6342c0bcd5b60b24cbde27952d94084019bcdab6337f47c5858cd83d37aeec94694849a5bfba28be583d8bc16e7085bf26b756903bf1dc14f27495687d962bc81a606eae8dd5b3e336da3c1d34911adb111db2cd7ee91636dbeadaf
+S = 9289ade35270d2b5081036fce186ae1dfbfccd4bbddfe1ea5e685fbc47d6705f02122be8633370735ec308676ccb8b969353faf5fc01b8a30b35fd6db088d216380bc0076f54e77eed258b382bc051d8ea37b986074ad2bdfc51faf4facfb33f9d5b007836b9edbc857e4ffdd13fd54a167d54492cc4a5b808a5cf23d31639ae195390ebfc8b722014f1c1a1806ce6d7ad9432f706a55cf6184737e99beb5880e70078b821ff414c0c65506da170b2613418dcf2d1dffc51fb9e4a109382c4c5661201cd3a696b64186f184b5ac1ac3fa50fcfef1f87757d01685d3929e997a3a23ef35f2bfab09c605cdc82dc322c290741f76b4561f1dd388a1b916030f00a4ced805c68b833fba956413f77aaf4ba08cf2cd04f2d91f5cbdd4b6555b8bd4960b43dbd244464d6efb5e35ecd19102b4bc27b43e40e624505768900c165a23f4074d54206c2e116f1576529b29bd8385c1cd91b83aeb520cc4ba9d08e133f224bbb0dffa95d9ff5b60504ba9b3c008a90b0e49521570d586c4ae96f89892095
+
+
+
+SHAAlg = SHA512/224
+Msg = c4db70981a925eccc116a6bbd9597e9763a80eb1f68cc984b3f3fcf57b8ba7d95f6f8db8570587d037261d5de0805718b339d1fe4cd50e526c5a0ee536b223959f500014201713ebad7715beebd9dfd19e3d7fcb60218bba99a5b558abeea08d6dc8f234db8fab220c4fb564642abbc90afa3fa19c38e7c3221d18d54106c6c7
+S = a58c3f480e1871ea4981352e8501f69c91fe6c8674bed6be0129eda5d86f1425584bb4c1a0399e5e1a8feff2190e8cfcc9945236f527c34a35fdc3448535c8287ff7ace9994519f78ca5304984c449165f37172b99bf2095b12c8e58f57faadb77ffcf76a3d5329cedcfcf825edd254d379fa8c4abbb5cedf75aadf04e841f8d0f4bd4a170c3f6ca6aaea4ec6a2eef57f402f02b99aa454af1916a8b117a48a8743c2be2642d8bc9b51bc044ea661dc7a0985772346c1f05355e03fd16f12af24e4baebc28538537b8b79f0c81e4777aa7afc7b82ae76a0b8ee96185015d6586e2d7db07cf503ff41ff43eaa97ccb7a1c48e45d2dd45cd0c531ddf1a34244a1fb155d9bc4990099c4b2f692f951d5992afe88dcc98fd18f32af13c479dbd6a725a01fb2f4a82a7957ee2896f384ecb3d19c5c1c802e9e1dd97ff2f8bc67031225aec773d5d52cc9b9079f3543aa0d053e9122f6b68a2224b8727189038fdaf439a1d03671891c3c7c13b30643672ceb7cfeeddf79bb5063004221ecb284fb6f1
+
+
+
+SHAAlg = SHA512/224
+Msg = 4c4d20122e7676d8be5f347b853a4d6b41a08e96388e8b8ccdadd9e151d67dd31bd5a52ddb6d966c2b9de61f6722eb94bf3d73b08ab6b51fdd2188ae5d60d3f451694538fc4a468f296a2d450711b37e372aa71d2448e4e593e881de7bf647fb169268f938136d8ae04c71b30c0f8d73d2f093a5ad4bff2715892a3c529ec12f
+S = a2793a4988185c97755437fb1f0bc536f5f2d913ccffbbab02c4c61c96795d5d6d3229607576ff902f2314a3347e89b31c9ab74c102e7a3e6f6bb09a405fc7d210d3dd707a8330127ee437d498946680e0e37eec8318a06aebb72eb77006de51bb43661190c0a06454e72fa811b6208b17222169b0834b2adaffe35b5f9ff1f2a55ae94e9680ae1596e28a9d9a7067a7a1858b5b8ffd1e94b3274520e14beed4f8ac3eddb161b3fe8afc2eee5dc203814b665d6252901717d6de61dbb86c74b82134adec317e19f7456d22ed40acd41674bdde76be7da452349ce9cb5211489ba9b42e3af4a0e6b6ae6ff345a4c4c89f7ebf5d88c610cb87d6cac609a1e32fa9d613f4f2cde329984766cbc066a5f61a015e7cd7e08c61ff2b9ceb5ddcabac7c5c41a57f56829c5a3b86e85eefac304406047ef6ec320e1d27c237f59b456f5dc2fe4a351e56283da7da6b41e5be7e9552a2d41fd1a564be8ddc3e9cea9f1cff9f76fd808f9e9d73354217ccd93244682ee006aaa465754bc6d1ea936aa68d47
+
+
+
+SHAAlg = SHA512/224
+Msg = 5dc60e1fe596a96be814d8232d3cb5ccb65d64c5f07becd02cf145ce525ab3cad4b25239e2b9f180dd9823b70dc794ad962e9a2ca88b0c7ef713572f6b5cce15187a428e7069d309b7ab05c8b83117e4b77f9091a60c1aa39ce7935182a06239106607a5f86df60d6093a6dd9642e577ff986e7c51c5bd4802b522bb01f0153f
+S = 556080ed70dfd893ef304bce1e8eb40d1c1542f76fd95b9923211bdba627eeb11f686ef91518cb9c8416d1bdb2b4a5c539a8fc729ef4a7512d75ec14fb70c877341c9f85d34e439af1f6669af16f47a62c5a45a3c005933221af60bd36cd2874a00f09d0fa85e615b3322ee6b53829803634e65bd122e41ee97df1ec69959dc29702f323a7b445aa4acbc778304ca5658661c38e078027ec5b28315762a963b82efd4dcbb68793e41e271d4f374004dba5edcae3039c92e02f97e50f0e7bb1150726895eaec38214e654dbab1426ba280ce4cfdd549f47cde618025e741dbe469ccabe3ed341deae95003da5503e232dae9a27e3a8a198f2c7653ba867cb37c983b29e66eccefa746821670bb5657d6ed8bccaf4f6612402da4362f7e6dc9c1643ff796572d00f17fb3783e6c532ebcc42ad36008656584844b69a25db5f77ca9b234e45587eacd67c49635d6ac7d24721b3fa61a67e40fa65941e6ae45b2b4c6b5af86c1729c5be6ed979c2be035ae2ba285692b5d5f5e558ce9866a7fdc329
+
+
+
+SHAAlg = SHA512/224
+Msg = c37ec28ba564ae2cd1f7fa7e76747b552aee89f23a4efb263e9953bbf171350f40df1e02a14f5212a6dc16c5d2ce2048ab614c5510c99059cd7232d76d8c380750c721c4fd5bd2a5b84cd36958ecbb9853a1e9671be875dcad9a6634666f268219c033986091162a2fce9931afd5358e4935caf000b593f70599589a8520e5c6
+S = a4d5891dba2e4fdb5626d2c92a3874c8d378c8725b510041b3234af3ccd1d3744469ab4f9705ff9e16fea91922f02cb0e816b65c19f4ac5abff1d18871d8086e5d8c846f43e6cb6e8817c99ecdb94f5f2fc9c43091193bca25127670eb2c006b20e5f27f32d4a1cc8ffa14dfe910a3b3813a8bffd2eb656753ca667cfaab81f9ad7e6a48184ea05ddb980aca5731171bb7cb58dc30c379dd40186e689fbde378aa9d76ea5a4128cf58e4440c1a6929ac1ade86fed75a4a10f61ae7892f6961db17b0e2ca99d24ef3fe72d647b98ed83c743ce004b70863a35cd35616358ea2342288e74b5e4b229ff569ed47f97e57af8b55e8968c8d0315600b0bc049ccdfeed4904cd5aba05538361febad22926469e44acda42b4663a2c2755fe26041a5b8491f824a405ea377b55d4d86951736b699a1537d24f99fb9b72f142c25a49b62165691d6202c9ccf2b149005364b7d455f6b235a953097fd6aa2f5b9c5f4297a473f1fb883bd74b9a48f71fad4376737ac3906d6e1b14c53a3c035b585798711
+
+
+
+SHAAlg = SHA512/224
+Msg = 8aa66795a6d68e37bae9a93420e276de2ed29bd45c61eb30a4aae5022f4c7dfe2dbd207105e2f27aaedd5a765c27c0bc60de958b49609440501848ccf398cf66dfe8dd7d131e04f1432f32827a057b8904d218e68ba3b0398038d755bd13d5f168cfa8a11ab34c0540873940c2a62eace3552dcd6953c683fdb29983d4e41707
+S = 3976c37b7625b02d799594d2cb853419ee714d72e895a107d49e26a356409f9d8470d437a248296ea4c141d4ad3a3fdcaab0cc1c84714550567c1a9a3009234b8786f5912e9c4f6c02470e665f71638d5599ed8c1d66645ab56ea11211dfaedf53dd4ba64e26492b4e83cfa7ea7b9af3da713e8ecbf90b6dd8b4ca35a29ccda80e337a40e67111e266586593a67ade79104d51fadc33506177fddada9ec9bb6908f5d25ff85423694ad66fdc2c4a34ba13bf0f25f096ac2847263aad34e917cc0fc3142c237f073922a76332598ee49aaa1816ebb88d054f35e03a25295d6f5f320a949c73428ee9ebde930ece4de633aed10f1d502086cb4666d06384d84f4fb0f60558278713c49cf007268b9870734ada1ce820fce3c5ac3b95d3956c2a38b03c07b16009ff673e2f3f29f8cc3d92eb53f138f1d4653e4203f7fd05e0e1aed0ecd7d4bcab95e5296ac63b58aee6164fcb74d7a222eae82cc5b5050620fa26171ee0ccfeb5377ee52758905a4cd759a8b2da02e15401afab3b56f345fb59ce
+
+
+
+SHAAlg = SHA512/224
+Msg = 10f58ddbd998e26004300e4079d656fcc6a9eb55b91619b22d56c0c324370864162051c4894f69c6e26602a77b2663e2f57a5d50d0b78194382290b622b3330e9818ec6451fd4d55858b68f8ff2e86c2749c1ca71313fa825de1c6b7372aa9173ee648045a29f6d596a7277c2f772865ea170ea2abb1ed46449c4a0e8b26d247
+S = 8e3a05bae94408530cc00a60fdfb33405b2a087fb2613b30f446ea5520c29c6615f5122fb5c1d29a2e45b488ca118b97088560fa1a7d86e11cccfad237264d4fbb951a3a4fecc4a1171a508e1b7ca4619047d6d216e97c1955ab73ac77942e005c07b2ee95dca824e13545f67d79847a53bcf0d4222e70e2e26b2b28c1be915141c638e77bc93e8f1d4793fdce77507ab710007e07c1b553f57e599d7fd9d4ffe208312d8447281d1ebada5c517a7735a46768213e856ea1129ad326f7c15124223c33ce136ceff3e6715a47b4ae7cf8e95be94317142d12ead5ed59fa91ce157db293f5f2bd3042500e7f0a7a281cf825171d6620d61b5188e0951c53c17bd22b72e7d7520b490781a846e50ee21aed2f3262b6369f59de19d0888434180d367b553c0eb47bcfd085ba1b8cc2b5e48a11758fcbfc8f5adba95b0658107997d53207d2205fd33f0e7891c54eb5a8cac031c7f138824b15e5a1d276ad9c642005442c6ada0b2161ad5ba6dd339a38946475e2efd0a5c01a6b6a93360f2698e34d
+
+
+
+SHAAlg = SHA512/224
+Msg = 013d90b2699ceb79cb94edfaf8418f565bee415080898c5bd855f6f7b6df263e9e3348babf4fb37abed8c965b50c1fce7cf8df4827eb6abbcf2a41b796e52509e56a7d8cf899f9429d9875a338c820350bf7dd5db4d7e975f7aebe1ebe5038d85e4bf7d01c6104f8f03bb75d895bd8b690530438313452b2d84a37d53806a7d3
+S = 21e65d04c41bfb837cb9b9f26bd1d920f6c16f1178980adf3db297c16a7675f9e1ad15e00e1c86b397250e1c5fabd7bfe69155b8db4b5e18c5c8b16948348f8b73dba274c9a47d7a35329e4d6ac3601a08af34fb6272264e4ae5268c1e59a73fe4abde5be02cc14ab33e3de77ab06446fc4f320f0805279d74733645bc2de6b6f518b841350048e1078c07521a02d7569f5e700e80099b69b8c4dcf6d4aa896a644754a3a97492f82a9664b9fef041f6fda2967ddf88da8482158a1797856bf6b8d071a1eef50df83d6f6484e2a3db02c652531d8c04466a55e79f467fbaced5670d65325b87885abd6d16c78cb424c19a090b4dbdacb1fa8eebfde97ba4faf51e576521756be3c761cdfa85dab3d4ba89f276fff9436f176b839fa5934c88612d7a775ccdbac8ea59e3b6f7e2479022172f17f1ad749ac6fca28d698aa50bc4ab92d8ea36e4b3409dd4b671cb00cd2f7d3e544b96d74953d0509a15bcb0b52aa6671a5e132814d18908b7da88fc9e3a7ee843957f6bcd0a793f41ef9054823d
+
+
+SHAAlg = SHA512/256
+Msg = f23660b33375dade2f5119ecdfee7c53397a4ace54c0f59bccfa9be768e7d287fa1ea5e887a2da49a8b6772730f384f90f97111e77207b143d1aecea813521f8919a70cd0b7f096942f97cade3127b0fd91ce1926d45f4f6b26be72b2031a40c7f52c84a0735eea6c5c230644075ebfc5db0c3128056e7a8f49596938d03e32b
+S = 31f3551b299c1ebcf1a67111e64e56ba6361a0fcf6ad813fcc3f7bbc937bfcb991da384b7c6b5e6a110dbd6c4c9d94de2145437855442d1eca3a4bcbf421de8d7b5a8d54525abb1df6095d52fff33d4d74ed2fb4c3af430fc0cc3bde9fd05f1021ca267e95bc82f09cd50bd5cc7ec7ede63f3e5b8eefb3d024fff0ec7479de983bea9ed36ed871ef5c65389d833264382bbb6c48a6dc5bde540a4ba8d94163e66d93c415c34b5c06b965626e850d1ec794540db27c551801177a781aaa321f77124e63c63b428ae8816c5f14505b33e4f10a93060cb4105b034b54575c6252d1561bbe242fb9be1371e47261472f91472f81f602942357cde641cf73015e161d03fcce0755ab6a7c9278a535b27a9da4c002f6f61231221543be579e9bc9d0d5239e2fce7fcd1dd6ea0ac1954aaf27d7d804f549256e957b7e8266eef02b6b905f5fe6ecb47288a5f3d97449846ccb3ac564046697dacd05f1b6357637e000052e4431d42a484afe7db85d821b1ccd37eaa0131f8d1667af940f32f2c2fe969b
+
+
+
+SHAAlg = SHA512/256
+Msg = 43e2cc2a6a8ea64565ff6ce2fd2c4f43fc02926ee44ee02fe1dce25cfde0115c9396c9ea06269f17b2caf58e2332cc1c8528d9705c70da1f76f22aeb1d1b93449180640fb5c4c4a708bc4621d7d2bed5b1a752191cfdd45086d34f247ed1df0f24e7c620de32bdfc4d1f882380d2cd7467c926f48abc75cbfac8788f88cd9dc5
+S = 85f3e1c60a2d06290b0c8ad0b2d92194048e3ad17bd0a1f2271f5cb1457513db2d0601186508cd151a7a86c238cdbba8d451eebec42f3c7bae0317e02ae9fbe29a0451ee7dc23be3185f76c2b3c8f302b205958d3211d244a3b021e6a703f0bb346512c73d0a2b656798471da493e1813e1317b198d4852bf2e865fb53c1eddc4ce8f446a7b32bec755c0c570dc1decc62fc051d2729226db93f39a01499f945e85c0723e919c1d0a00401dfa0d1c21f4a19db8174aca10b07dc70bdf0914e15235f1483c25139932a8eb33364e7ee7956cb2fdc5f6747898b808f0d72276793e7ab7982283d0721d7d560fe36db6fc8e6761245f964a04cb49abfbef8d2ab330a0d507c7a147f0ab17ac1ac6f8ddf97a74b7f63df61f6c690d5c5209c788201a0f22c429f8f0524861f3b780ba03facf9949b570fe620db18c556b2ca8379295248994d6a4ae8e593751dc0bc908bef26169f48b25d16ad634ad13bd3a0d9f87e2d0113680996c84722a6f4c87e4693146901e94e0793e1e1eccff336adf697
+
+
+
+SHAAlg = SHA512/256
+Msg = 6e3280f4edb24513845083560a176549a81b04b1df668b1fcc3599c5ab65e6899b282a58a0fc3abdeede74b265ba5eb658278a1f9251bdb29b364f713716d5b43024fe7b5582bb03c36ca39763b495a9b46e9f21cbec1ef598ed27fa6a1126fab590c506142c100d8a64d6ae0deb524b45580a5f911ff8114bc0e8094d3e2182
+S = 2b146c0a9963500795dcc7fccd53ce8ad223ba899a980726c1d08040688ecdd3cbd7f648fc7e8865da6b12e743c4f34a544a746b1c902cf5f2f130245cca3c500675d1786efc2f6685bd6c82f9c06dfea9840a172de27be6788caae3ffc5365eacc7506f88f60bdf9b9e95d78df1020ff897ceadb35d006dcf080a25f45e65d74880d5a005a234146277332283f575bbab122789dcb62b685290648d1e240f471e8ea036c4b2064efa533d5887670b8eb6067e1b99fc2d44d2afd134f26b716811767e8de06963f84988a6247aeb58d9c86a860cbe48e997848cb5aa7d42d833d4e72826ec67a822ae618796f51397f42ffe559db9cd33140e482586c8142b4341392839d41ec1b5e9e5c83eb35b5f53ccc79086fa4e71deda678db71130a73f7f68d45c1354f1536da781aa5c17575f78cb58a456fece8d9d9755e6b8d5b8c82c42b037996a30fc823ccfb4c1d06f6a5897bd64d2a4912ddadb7d247eb1b56140cf8b435788d6cac7c9563f019da5afe350efdccf5545e882ec59fc7660be83
+
+
+
+SHAAlg = SHA512/256
+Msg = 59dcada047c130bd4026539fed6023f7d037576e7b4b242d00b059a3a8dca782e8c3400b9040a58c46b7b82733f919d4fc67afa9f45b855a90c3d8fc1b0f6e0eaa4e29b95393db579a9e5c332cb8da8fd0df71ec9a23fb8561502a1d74cdd4fa89c48d32f6837b252423664b40670f3033e6c3bcd56d2fb85d9f768e1dde8150
+S = 84ccaa672f52af4f285e81153df426883f535021e89716c307706c35d93fd61be14131753c8bb5932fe1236e9ada13765fa74be339796a7501e3fdf153c4142fbe4248fbd91048c4ac76645715b991490c0f463febf4893c02b542a655f073c64efe20ab2b5cb77c8ecd41c39a7388a5b530f6ebf822e263b88cdd312964e85c7588c8720b7fcdcf2b5289b044949640036249fed30e347c1a40d9574601ad8637faa4acf92959729664c41103da6bb66edf95d1a20dab6dc6a4010de76f0ccd8ee6129696b2e14053da514943685d6f52700389d931bead03af43d6fc31fa281b1e41da244c1b69f377e4d7b1d75d1fa5f1e63af83a39b8c59b2a19281e6f65af83568d04e283a5e744cecfd4a261db48d2159b0b7f0c8a3416d873eb72c76898a11bf9ada070f4b9d3762f942ffa74a5b57d26dd527e95d762e1d62f38e1693c1688e30b6e56812f0e01e425bf4cc2a297deb14319e5a3f0ec244cd050437d9301268fd55a9f758123985d4a0ad596fd456b4b24c09572c0781ae21364e0c3
+
+
+
+SHAAlg = SHA512/256
+Msg = 073b071975d8b6b8cf609fc0b307f22e74e33fe3bffe38587faab98dfd1405424c1c536ae46489dd8da7474d7f4d277bc73c43aaecf0f854d3ceea1de0b548055ed752e121c7180c69d2845a0a939a4dcac2ff8c0b4db890aaaa35a1266b8e0105130c677328ebae2d895ecf9d02d40d461e7a6f633c0173cbe5a101185d5e9e
+S = 099d03209073b4009482911b6dc9a2a9d938397cee5694b61de28178e40fd07435121323b36d1074b9debd50386c0bdd63e1f26bd1f29c7beec2be3e4e0233bb88552319daca3d35f4602a6eb653e22926315a95231d9cfd7aef40e280ac1ac572d45f11d11539b858bdf2bf785cb31cb38dbccbd707b63eafcb0ca1626448ba810caaf1edd6faf3d53a0229c1effa6256e41d3eb7962fb93bf4adc0dc835b6c460e4db28a3dd7ea6e818cab8dc0fe3c3525aeec5fa6f64ded105ef90c46b5598f39e8263e20268d072ead3cfe07bc73dfee40cb257b55938ce1b7dd402367710a18b505d58326d2def24e1b76b342c5b996a5991d9dad6f369b9158eb603d7a9d783eef6bc8f16c1c458c4ee11127096fb3e78261e3965e0be037aa02fee083a2c661739faf44c1017a225f6d7e1b9fb68608007fa93fd5604e4c0c0ade97834f102bfdad72fbe32dd7ea070ec4d0a7345d2ebb2eb405285ab4a4c9c6e6a1153f1da84202752e4ecac38c809ae2b7589979cc624d683d054c17ac336ac18f83
+
+
+
+SHAAlg = SHA512/256
+Msg = d3c6aa33a80cc85035fc721da56357652cf85b48f58830835b5026f15bab445249ed974cc38ecaafe48bf7fdb909bd2af93b93a0f0875b86bde43b42bd87a83c47bec3e59a1ce9f913d68501a46d291b818ddefd1c36b8385419adbae945a6973402d70915fd4cb52ca6c52f4cd7c4c12cb6e46860dc6c2088b72461c82c68ea
+S = 9befb09cfdd96b3e4232e66eadb8858065f15e5e6ef00b6c1fe66defe61696bf05766a81830ec88d875f33062845905591eea0dacb004cc0227a497ad62d89a12cc2cd3fd1f8d03a744dae9129e8382d9cb35ee04213bd02de5f4c7fc7b2ac0bea68bc03ebcb9e77c2ad3c624b5bb3a969960b1ebafc70f226cdd6daa2dea5f8475b77706e3f341fb428833c4485127a078785500408dae6bef791c839d8a0e1a935f5434777d52a47b8b8bd6bd14244d6129dd63f0ed53426d6b0344714ed68773b59eb3a4e2c39fa0907969c40be6618c8355aeb5269f5ab328aeb355211c8eee72fe8141cfacc8b22ae1e1d6b45443faa7c6f8909385f785db074b317b37a7e9460148f7f440f142ce03bbcd7dcbc2539031a4e334d5dd9fb6ca6ecb367e0a78a2153dd9bb9aead009578fef558dd618c022548ff5bfd63bc2a401237d48b565bb02bc55c92466ef29a754573e146d8b02effd116a5175063395bcbdefdc9dfb58027e6a3f61a323c73670075004f3e53979074f99fcbf2dba3fe0e47f030
+
+
+
+SHAAlg = SHA512/256
+Msg = 849e5d6b17802aea210dc2a5ab7b9418d4bcdc63c6a22f96ea47542c58ac56d592a0d77971e4a7795f8c9638c7a886daca24c44b34ed9883ae551a0935b948b6ca6156bc6ba745e7435cb7221e67023c1faf83ecb53c3513cb9981423f7c587c96a8803dee132bba3344ce6b960030c73b25c24f32d62ecda9d832de603cafae
+S = 7a2f7a8a22dae7021167b40af37fc2793602b34f1bef039bff7ebfdbb8d89c326bf92957d8e4218cb15839128e6f6c71f9cfcc52132a320057b0415f831762aaaef1b19175d5186366df74963dbbc402023aa416d17e2aa515e04c8eb0b26e8d8c00f1a74610fbea45747fefc6fa9a9002b82028e444eb45302e2ae93a4bd4a126e413c701226a234382c92d38d846acd663b5ac99f2d3374c1a34cafa8cf4db8fadf8d6ac6f84c8c1e82a34cb948e3c21bac80587ffe8864c7bd106a4572f1feb1dbe8bf47bea91c5b4f8ecbd5c3a0391c35a2429ef66184ef7649192b961005cfe96572ab1f1479fed569b9dada7cde74a0329eb63f6e91e1647c424aca2a4be2c106eb9e67b8192021fa23f3eb17595d5b0e6bd3ce5d9c9939192b786acab778a456b4ace7bc8aa96f80c1f407607d3fe0130d82193a4f63080800de10ddff692e385489e67dba5fb33a877860aa1f300376220c57117a3f411dd18ec603cd2b66a56e57ff4b9c4431267643f3f99ae6b769d860999bae7b74303583e8b1c
+
+
+SHAAlg = SHA512/256
+Msg = d7f95e001d6a826e7f7ce4c05f9995d3f6a737d0993762003aff46e1318a91793d2e93eac53f9f476482b5a6a5e45f760b6cd913556f7498ff033cf50cb5d941037fb35138f45a894cbe24f2f74a188d05c20ae79f3c08eecc31f5033830745033d3085cfcf379dc401879cdde3387bfed9014740006e4a9a871b8343b622a4f
+S = 72364e031cd57ceb29a47bb0685b1213d7e0e971728673fd19c0265879c5896958e3d78ac90a398f636c093f979bee99f5ff70539830e4ad44e988b63bced427728ad43f8df064c82e9fb682185f2abcde5c52b29a5918173c13e9890eff41f7a15bd9efd4b65b2ff5a2f706821e38f627805142e6f5ce527641ae7b46c1e9405e6faa7848ac7da98d00ab2196074b1c092018337a0a25473139ff0cb71e6880e7aa6ea2ea0d6b25966de48589dfde90e49a741134e0489406839abf97a2e378def59df53862878305699063052001a4297ee1dc9938c4db686c9bedab9a8d95ee84e016365c812c407d915dd1eaf38fae32fa40ce0bfef6c092f30c4b9e9edd7741e3a4a1f2c79b52d3e75c23bcb641ff1e81d863a941902aeb87b7d9e8d17576620a35d75e23e56e3c2e23146324ac31740c1bbd30aaf427efb1a3b850589cae305a9e516ee21f0045c213661394674d589b2e66534992d9bd0938cec8289167c824a49cb095d7de57ee8e5ec7bbf107888759d4d13d81243018c62d60efa8
+
+
+SHAAlg = SHA512/256
+Msg = 0074ba726144b96dc93c7b68575723c968c629f853dbae6657250ccfd1ddb2bcb2802f4b31be8c32bd93df0236b41da95c2c303b884749f29aaf787332d57a522392d2d9240f1b05c9e29cd2b2791db803bcf97613ee750e69d45011e41a9b1c39f2cba3a3fe0dedd570d9603470caff43bead315e98d8c4acdebd314f74be22
+S = 99eb491965dc7dac3793cff573bf1178a03134ad9977db883c4b4188fa574e7ea892969c6a0e084bf03cacb4d2a756e5adc82a8b8db7af9f3cee6f77f1ab23f0a5dc40c1450d2d23539ca29336558a5201b67432a22e881fa3c304ee5e796dbdec9dd5e9aca63e99c4b2e52baf292bd278b4c131efbd54ee953b7e849eb835cd17b9f0df4a1b869c0313df23551aa60f570515c6c186aeda72135aa8c1ff5a42e8bf312f14b0d9f4f042d5e69c4467e9ba8715f0d206eab291a288981109bc3cb7512f1998f5d2ddfc99040b108f15c7d4f70620fc4882f8b17654dc70cff93c5d4ff83480e305683c73b038e10bf5f0c4ea56f03edf38d5e84e0ae6c9364846acbaeaa2729314064666f1d93f6351e610edbe30e2952796dc01ed8e7727dad32ecfb40d78ca23e526be97ff070c919f61a2b9dcfe10d8e35442ee76cc1b3c22d60af7b7c23dc2fea3b0a89d1eded7c7fcf89826011bcab7430c31ac86f7b0b9c857066a6b7d1f4cbfcc64b4a14f7156d3d69dcd3b9fa6e2a468fe13861624a3
+
+
+SHAAlg = SHA512/256
+Msg = b6b26aae4d1fcbd43d6205595758939917dfeffad637607441af13500a7d6e2fdeeda14f96be7e0ab1c88a9f02e35435a605051d39aa395849790d590b24790b4d90e116ac36e65f07c982cd34185453f137382b1dd91b5f28010e8ec8da98edede2518cf84eacdb27ab156c54c13cfae0bcb0abea8eaf92c48f3d78a76673dc
+S = 460876efb3ade4c119b9a1ac22c7f3fa7278af8fb0656292d03453c68352c5a462bc720af460add40fe28078d9dda46922ddb9b78c858feff5c2433688902bdd3447850dc88f9d8c1b003891bda081116800e2bb32f9795427db84ed1084342283f5903ea9b898bc8ee083d069da457333c26f4c4dc75682dd0be73c685d9acdabe5a59de8d12c4d8e7d62cfd4299238f849325e1abeaa7763e392a5019059e33f31b0a6a4cad36b3b5801c23358e7b9d055cc4dd0c9b1991169edf61480e05f74f4388145afc447f1704114818205096c117d2ae8ee747efe03b6213a6f8cfb6aabed9f85902fb9682c17bc92df250bbfcf57a94fd9cea74c90f1bb92a77dba5f318cdb0950fbce14f4d82ca09704222d01c8d6f08c31b11e11d55cb99856cbe6f199da4a41a34ce878a3b3641a1f4b6921977025f4d2297823f773dabbb8b587a280bf87f3045a6609090b925cea7676a4f1c63d4fd8efaa6e8c3be7dde035d8e9433499cd1935423db18e92add2d7a595ee6f80c1a233d10de1a3febaebac
+
diff --git a/jdk/test/sun/security/rsa/SigRecord.java b/jdk/test/sun/security/rsa/SigRecord.java
new file mode 100644
index 0000000..b72300c
--- /dev/null
+++ b/jdk/test/sun/security/rsa/SigRecord.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.math.BigInteger;
+import java.security.*;
+import java.security.spec.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public final class SigRecord {
+
+ static final String TEST_SRC = System.getProperty("test.src", ".");
+
+ // utility method for converting byte array to hex string
+ static String toHexString(byte[] array) {
+ StringBuilder sb = new StringBuilder(array.length * 2);
+ for (byte b : array) {
+ // The single digits 0123456789abcdef get a leading 0
+ if ((b >= 0x00) && (b < 0x10)) {
+ sb.append('0');
+ }
+ sb.append(Integer.toHexString(b & 0xff));
+ }
+ return sb.toString();
+ }
+
+ // utility method for converting hex string to byte array
+ static byte[] toByteArray(String s) {
+ byte[] bytes = new byte[s.length() / 2];
+ for (int i = 0; i < bytes.length; i++) {
+ int index = i * 2;
+ int v = Integer.parseInt(s.substring(index, index + 2), 16);
+ bytes[i] = (byte) v;
+ }
+ return bytes;
+ }
+
+ public static final class SigVector {
+ // digest algorithm to use
+ final String mdAlg;
+
+ // message to test
+ final String msg;
+
+ // expected signature
+ final String sig;
+
+ public SigVector(String mdAlg, String msg, String sig) {
+ if (mdAlg == null || mdAlg.isEmpty()) {
+ throw new IllegalArgumentException("Digest algo must be specified");
+ }
+ if (msg == null || mdAlg.isEmpty()) {
+ throw new IllegalArgumentException("Message must be specified");
+ }
+ if (sig == null || mdAlg.isEmpty()) {
+ throw new IllegalArgumentException("Signature must be specified");
+ }
+ this.mdAlg = mdAlg;
+ this.msg = msg;
+ this.sig = sig;
+ }
+
+ @Override
+ public String toString() {
+ return (mdAlg + ": msg=" + msg + ": sig=" + sig);
+ }
+ }
+
+ final String id;
+ // RSA private key value associated with the corresponding test vectors
+ final RSAPrivateKeySpec privKeySpec;
+
+ // RSA public key value associated with the corresponding test vectors
+ final RSAPublicKeySpec pubKeySpec;
+
+ // set of test vectors
+ final List<SigVector> testVectors;
+
+ SigRecord(String mod, String pubExp, String privExp, List<SigVector> testVectors) {
+ if (mod == null || mod.isEmpty()) {
+ throw new IllegalArgumentException("Modulus n must be specified");
+ }
+ if (pubExp == null || pubExp.isEmpty()) {
+ throw new IllegalArgumentException("Public Exponent e must be specified");
+ }
+ if (privExp == null || privExp.isEmpty()) {
+ throw new IllegalArgumentException("Private Exponent d must be specified");
+ }
+ if (testVectors == null || (testVectors.size() == 0)) {
+ throw new IllegalArgumentException("One or more test vectors must be specified");
+ }
+
+ BigInteger n = new BigInteger(1, toByteArray(mod));
+ BigInteger e = new BigInteger(1, toByteArray(pubExp));
+ BigInteger d = new BigInteger(1, toByteArray(privExp));
+ this.id = ("n=" + mod + ", e=" + pubExp);
+ this.pubKeySpec = new RSAPublicKeySpec(n, e);
+ this.privKeySpec = new RSAPrivateKeySpec(n, d);
+ this.testVectors = testVectors;
+ }
+
+ /*
+ * Read a data file into an ArrayList.
+ * This function will exit the program if reading the file fails
+ * or if the file is not in the expected format.
+ */
+ public static List<SigRecord> read(String filename)
+ throws IOException {
+
+ List<SigRecord> data = new ArrayList<>();
+ try (BufferedReader br = new BufferedReader(
+ new InputStreamReader(new FileInputStream(
+ TEST_SRC + File.separator + filename)))) {
+ String line;
+ String mod = null;
+ String pubExp = null;
+ String privExp = null;
+ List<SigVector> testVectors = new ArrayList<>();
+ while ((line = br.readLine()) != null) {
+ if (line.startsWith("n =")) {
+ mod = line.split("=")[1].trim();
+ } else if (line.startsWith("e =")) {
+ pubExp = line.split("=")[1].trim();
+ } else if (line.startsWith("d =")) {
+ privExp = line.split("=")[1].trim();
+
+ // now should start parsing for test vectors
+ String mdAlg = null;
+ String msg = null;
+ String sig = null;
+ boolean sigVectorDone = false;
+ while ((line = br.readLine()) != null) {
+ // we only care for lines starting with
+ // SHAALG, Msg, S
+ if (line.startsWith("SHAAlg =")) {
+ mdAlg = line.split(" = ")[1].trim();
+ } else if (line.startsWith("Msg =")) {
+ msg = line.split(" = ")[1].trim();
+ } else if (line.startsWith("S =")) {
+ sig = line.split(" = ")[1].trim();
+ } else if (line.startsWith("[mod")) {
+ sigVectorDone = true;
+ }
+
+ if ((mdAlg != null) && (msg != null) && (sig != null)) {
+ // finish off current SigVector
+ testVectors.add(new SigVector(mdAlg, msg, sig));
+ mdAlg = msg = sig = null;
+ }
+ if (sigVectorDone) {
+ break;
+ }
+ }
+ // finish off current SigRecord and clear data for next SigRecord
+ data.add(new SigRecord(mod, pubExp, privExp, testVectors));
+ mod = pubExp = privExp = null;
+ testVectors = new ArrayList<>();
+ }
+ }
+
+ if (data.isEmpty()) {
+ throw new RuntimeException("Nothing read from file "
+ + filename);
+ }
+ }
+ return data;
+ }
+
+ @Override
+ public String toString() {
+ return (id + ", " + testVectors.size() + " test vectors");
+ }
+}
diff --git a/jdk/test/sun/security/rsa/SignatureOffsets.java b/jdk/test/sun/security/rsa/SignatureOffsets.java
index b813b26..7f12fea 100644
--- a/jdk/test/sun/security/rsa/SignatureOffsets.java
+++ b/jdk/test/sun/security/rsa/SignatureOffsets.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
/*
* @test
- * @bug 8050374
+ * @bug 8050374 8146293
* @key randomness
* @summary This test validates signature verification
* Signature.verify(byte[], int, int). The test uses RandomFactory to
@@ -43,6 +43,8 @@
* @run main SignatureOffsets SunRsaSign SHA256withRSA
* @run main SignatureOffsets SunRsaSign SHA384withRSA
* @run main SignatureOffsets SunRsaSign SHA512withRSA
+ * @run main SignatureOffsets SunRsaSign SHA512/224withRSA
+ * @run main SignatureOffsets SunRsaSign SHA512/256withRSA
*/
public class SignatureOffsets {
@@ -50,4 +52,4 @@
InvalidKeyException, SignatureException {
Offsets.main(args);
}
-}
\ No newline at end of file
+}
diff --git a/jdk/test/sun/security/rsa/SignatureTest.java b/jdk/test/sun/security/rsa/SignatureTest.java
index 0eed4ec..0752bd0 100644
--- a/jdk/test/sun/security/rsa/SignatureTest.java
+++ b/jdk/test/sun/security/rsa/SignatureTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -20,35 +20,25 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
+import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.RSAPrivateKeySpec;
-import java.security.spec.RSAPublicKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Arrays;
+import java.security.spec.*;
+import java.util.*;
import static javax.crypto.Cipher.PRIVATE_KEY;
import static javax.crypto.Cipher.PUBLIC_KEY;
import jdk.testlibrary.RandomFactory;
+import jdk.test.lib.SigTestUtil;
+import static jdk.test.lib.SigTestUtil.SignatureType;
+
/**
* @test
- * @bug 8044199
+ * @bug 8044199 8146293
* @summary Create a signature for RSA and get its signed data. re-initiate
* the signature with the public key. The signature can be verified
* by acquired signed data.
+ * @library /lib
* @key randomness
* @library ../../../lib/testlibrary
* @run main SignatureTest MD2withRSA 512
@@ -75,10 +65,10 @@
* @run main/timeout=240 SignatureTest MD5withRSA 5120
* @run main/timeout=240 SignatureTest SHA1withRSA 5120
* @run main/timeout=240 SignatureTest SHA256withRSA 5120
- * @run main/timeout=240 SignatureTest MD2withRSA 6144
- * @run main/timeout=240 SignatureTest MD5withRSA 6144
- * @run main/timeout=240 SignatureTest SHA1withRSA 6144
- * @run main/timeout=240 SignatureTest SHA256withRSA 6144
+ * @run main/timeout=480 SignatureTest MD2withRSA 6144
+ * @run main/timeout=480 SignatureTest MD5withRSA 6144
+ * @run main/timeout=480 SignatureTest SHA1withRSA 6144
+ * @run main/timeout=480 SignatureTest SHA256withRSA 6144
*/
public class SignatureTest {
/**
@@ -103,29 +93,46 @@
public static void main(String[] args) throws Exception {
String testAlg = args[0];
- int testSize = Integer.parseInt(args[1]);
+ int keySize = Integer.parseInt(args[1]);
+ Iterable<String> md_alg_pkcs15 =
+ SigTestUtil.getDigestAlgorithms(SignatureType.RSA, keySize);
+
+ Iterable<String> md_alg_pss =
+ SigTestUtil.getDigestAlgorithms(SignatureType.RSASSA_PSS, keySize);
byte[] data = new byte[100];
RandomFactory.getRandom().nextBytes(data);
// create a key pair
- KeyPair kpair = generateKeys(KEYALG, testSize);
+ KeyPair kpair = generateKeys(KEYALG, keySize);
Key[] privs = manipulateKey(PRIVATE_KEY, kpair.getPrivate());
Key[] pubs = manipulateKey(PUBLIC_KEY, kpair.getPublic());
+
+ test(SignatureType.RSA, md_alg_pkcs15, privs, pubs, data);
+ test(SignatureType.RSASSA_PSS, md_alg_pss, privs, pubs, data);
+ }
+
+ private static void test(SignatureType type, Iterable<String> digestAlgs,
+ Key[] privs, Key[] pubs, byte[] data) throws RuntimeException {
+
// For signature algorithm, create and verify a signature
Arrays.stream(privs).forEach(priv
- -> Arrays.stream(pubs).forEach(pub -> {
- try {
- checkSignature(data, (PublicKey) pub, (PrivateKey) priv,
- testAlg);
- } catch (NoSuchAlgorithmException | InvalidKeyException
- | SignatureException | NoSuchProviderException ex) {
- throw new RuntimeException(ex);
- }
- }
- ));
-
+ -> Arrays.stream(pubs).forEach(pub
+ -> digestAlgs.forEach(digestAlg -> {
+ try {
+ AlgorithmParameterSpec sigParams =
+ SigTestUtil.generateDefaultParameter(type, digestAlg);
+ String sigAlg = SigTestUtil.generateSigAlg(type, digestAlg);
+ checkSignature(data, (PublicKey) pub, (PrivateKey) priv,
+ sigAlg, sigParams);
+ } catch (NoSuchAlgorithmException | InvalidKeyException |
+ SignatureException | NoSuchProviderException |
+ InvalidAlgorithmParameterException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ )));
}
private static KeyPair generateKeys(String keyalg, int size)
@@ -175,9 +182,14 @@
}
private static void checkSignature(byte[] data, PublicKey pub,
- PrivateKey priv, String sigalg) throws NoSuchAlgorithmException,
- InvalidKeyException, SignatureException, NoSuchProviderException {
- Signature sig = Signature.getInstance(sigalg, PROVIDER);
+ PrivateKey priv, String sigAlg, AlgorithmParameterSpec sigParams)
+ throws NoSuchAlgorithmException, InvalidKeyException,
+ SignatureException, NoSuchProviderException,
+ InvalidAlgorithmParameterException {
+ System.out.println("Testing " + sigAlg);
+ Signature sig = Signature.getInstance(sigAlg, PROVIDER);
+ sig.setParameter(sigParams);
+
sig.initSign(priv);
for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) {
sig.update(data);
@@ -185,12 +197,13 @@
byte[] signedData = sig.sign();
// Make sure signature verifies with original data
+ sig.setParameter(sigParams);
sig.initVerify(pub);
for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) {
sig.update(data);
}
if (!sig.verify(signedData)) {
- throw new RuntimeException("Failed to verify " + sigalg
+ throw new RuntimeException("Failed to verify " + sigAlg
+ " signature");
}
@@ -202,7 +215,7 @@
}
if (sig.verify(signedData)) {
- throw new RuntimeException("Failed to detect bad " + sigalg
+ throw new RuntimeException("Failed to detect bad " + sigAlg
+ " signature");
}
}
diff --git a/jdk/test/sun/security/rsa/SignedObjectChain.java b/jdk/test/sun/security/rsa/SignedObjectChain.java
index 7bda7cd..fea6028 100644
--- a/jdk/test/sun/security/rsa/SignedObjectChain.java
+++ b/jdk/test/sun/security/rsa/SignedObjectChain.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,9 +23,11 @@
/*
* @test
- * @bug 8050374
- * @compile ../../../java/security/SignedObject/Chain.java
+ * @bug 8050374 8146293
* @summary Verify a chain of signed objects
+ * @library /lib
+ * @compile ../../../java/security/SignedObject/Chain.java
+ * @run main SignedObjectChain
*/
public class SignedObjectChain {
@@ -44,6 +46,8 @@
new Test(Chain.SigAlg.SHA256withRSA),
new Test(Chain.SigAlg.SHA384withRSA),
new Test(Chain.SigAlg.SHA512withRSA),
+ new Test(Chain.SigAlg.SHA512_224withRSA),
+ new Test(Chain.SigAlg.SHA512_256withRSA),
};
public static void main(String argv[]) {
diff --git a/jdk/test/sun/security/rsa/TestKeyPairGenerator.java b/jdk/test/sun/security/rsa/TestKeyPairGenerator.java
index 5e661b0..29696ee 100644
--- a/jdk/test/sun/security/rsa/TestKeyPairGenerator.java
+++ b/jdk/test/sun/security/rsa/TestKeyPairGenerator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,8 +23,11 @@
/**
* @test
- * @bug 4853305 4865198 4888410 4963723
+ * @bug 4853305 4865198 4888410 4963723 8146293
* @summary Verify that the RSA KeyPairGenerator works
+ * @library /lib
+ * @build jdk.test.lib.SigTestUtil
+ * @run main TestKeyPairGenerator
* @author Andreas Sterbenz
*/
@@ -36,15 +39,21 @@
import java.security.interfaces.*;
import java.security.spec.*;
+import jdk.test.lib.SigTestUtil;
+import static jdk.test.lib.SigTestUtil.SignatureType;
+
public class TestKeyPairGenerator {
private static Provider provider;
private static byte[] data;
- private static void testSignature(String algorithm, PrivateKey privateKey, PublicKey publicKey) throws Exception {
- System.out.println("Testing " + algorithm + "...");
- Signature s = Signature.getInstance(algorithm, provider);
+ private static void testSignature(SignatureType type, String mdAlg,
+ PrivateKey privateKey, PublicKey publicKey) throws
+ NoSuchAlgorithmException, InvalidKeyException, SignatureException {
+ System.out.println("Testing against " + mdAlg + "...");
+ String sigAlg = SigTestUtil.generateSigAlg(type, mdAlg);
+ Signature s = Signature.getInstance(sigAlg, provider);
s.initSign(privateKey);
s.update(data);
byte[] sig = s.sign();
@@ -52,22 +61,26 @@
s.update(data);
boolean result = s.verify(sig);
if (result == false) {
- throw new Exception("Verification failed");
+ throw new RuntimeException("Verification failed");
}
}
private static void test(PrivateKey privateKey, PublicKey publicKey) throws Exception {
- testSignature("MD2withRSA", privateKey, publicKey);
- testSignature("MD5withRSA", privateKey, publicKey);
- testSignature("SHA1withRSA", privateKey, publicKey);
- testSignature("SHA224withRSA", privateKey, publicKey);
- testSignature("SHA256withRSA", privateKey, publicKey);
- RSAPublicKey rsaKey = (RSAPublicKey)publicKey;
- if (rsaKey.getModulus().bitLength() > 512) {
- // for SHA384 and SHA512 the data is too long for 512 bit keys
- testSignature("SHA384withRSA", privateKey, publicKey);
- testSignature("SHA512withRSA", privateKey, publicKey);
+
+ int testSize = ((RSAPublicKey)publicKey).getModulus().bitLength();
+ System.out.println("modulus size = " + testSize);
+
+ Iterable<String> md_alg_pkcs15 =
+ SigTestUtil.getDigestAlgorithms(SignatureType.RSA, testSize);
+ md_alg_pkcs15.forEach(mdAlg -> {
+ try {
+ testSignature(SignatureType.RSA, mdAlg, privateKey, publicKey);
+ } catch (NoSuchAlgorithmException | InvalidKeyException |
+ SignatureException ex) {
+ throw new RuntimeException(ex);
+ }
}
+ );
}
// regression test for 4865198
diff --git a/jdk/test/sun/security/rsa/TestSigGen15.java b/jdk/test/sun/security/rsa/TestSigGen15.java
new file mode 100644
index 0000000..35925f9
--- /dev/null
+++ b/jdk/test/sun/security/rsa/TestSigGen15.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.security.*;
+import java.security.spec.*;
+import java.security.interfaces.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/*
+ * @test
+ * @bug 8146293
+ * @summary Known Answer Tests based on NIST 186-3 at:
+ * @compile SigRecord.java
+ * @run main/othervm TestSigGen15
+ */
+public class TestSigGen15 {
+
+ private static final String[] testFiles = {
+ "SigGen15_186-3.txt", "SigGen15_186-3_TruncatedSHAs.txt"
+ };
+
+ public static void main(String[] args) throws Exception {
+ boolean success = true;
+ for (String f : testFiles) {
+ System.out.println("[INPUT FILE " + f + "]");
+ try {
+ success &= runTest(SigRecord.read(f));
+ } catch (IOException e) {
+ System.out.println("Unexpected exception: " + e);
+ e.printStackTrace(System.out);
+ success = false;
+ }
+ }
+
+ if (!success) {
+ throw new RuntimeException("One or more test failed");
+ }
+ System.out.println("Test passed");
+ }
+
+ /*
+ * Run all the tests in the data list with specified algorithm
+ */
+ static boolean runTest(List<SigRecord> records) throws Exception {
+ boolean success = true;
+ //for (Provider provider : Security.getProviders()) {
+ Provider p = Security.getProvider("SunRsaSign");
+ KeyFactory kf = KeyFactory.getInstance("RSA", p);
+ for (SigRecord sr : records) {
+ System.out.println("==Testing Record : " + sr + "==");
+ PrivateKey privKey = kf.generatePrivate(sr.privKeySpec);
+ PublicKey pubKey = kf.generatePublic(sr.pubKeySpec);
+ success &= check(privKey, pubKey, sr.testVectors, p);
+ System.out.println("==Done==");
+ }
+ return success;
+ }
+
+ /*
+ * Generate the signature, check against known values and verify.
+ */
+ static boolean check(PrivateKey privKey, PublicKey pubKey,
+ List<SigRecord.SigVector> vectors, Provider p) throws Exception {
+
+ boolean success = true;
+ for (SigRecord.SigVector v : vectors) {
+ System.out.println("\tAgainst " + v.mdAlg);
+ String sigAlgo = v.mdAlg + "withRSA";
+ Signature sig;
+ try {
+ sig = Signature.getInstance(sigAlgo, p);
+ } catch (NoSuchAlgorithmException e) {
+ System.out.println("\tSkip " + sigAlgo +
+ " due to no support");
+ continue;
+ }
+ byte[] msgBytes = SigRecord.toByteArray(v.msg);
+ byte[] expSigBytes = SigRecord.toByteArray(v.sig);
+
+ sig.initSign(privKey);
+ sig.update(msgBytes);
+ byte[] actualSigBytes = sig.sign();
+
+ success &= MessageDigest.isEqual(actualSigBytes, expSigBytes);
+
+ if (!success) {
+ System.out.println("\tFailed:");
+ System.out.println("\tSHAALG = " + v.mdAlg);
+ System.out.println("\tMsg = " + v.msg);
+ System.out.println("\tExpected Sig = " + v.sig);
+ System.out.println("\tActual Sig = " + SigRecord.toHexString(actualSigBytes));
+ } else {
+ System.out.println("\t" + v.mdAlg + " Test Vector Passed");
+ }
+ }
+
+ return success;
+ }
+}
diff --git a/jdk/test/sun/security/rsa/TestSignatures.java b/jdk/test/sun/security/rsa/TestSignatures.java
index 1933f26..3b7fd1e 100644
--- a/jdk/test/sun/security/rsa/TestSignatures.java
+++ b/jdk/test/sun/security/rsa/TestSignatures.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,8 +23,11 @@
/**
* @test
- * @bug 4853305 4963723
+ * @bug 4853305 4963723 8146293
* @summary Test signing/verifying using all the signature algorithms
+ * @library /lib
+ * @build jdk.test.lib.SigTestUtil
+ * @run main TestSignatures
* @author Andreas Sterbenz
*/
@@ -34,6 +37,9 @@
import java.security.*;
import java.security.interfaces.*;
+import jdk.test.lib.SigTestUtil;
+import static jdk.test.lib.SigTestUtil.SignatureType;
+
public class TestSignatures {
private final static String BASE = System.getProperty("test.src", ".");
@@ -52,9 +58,12 @@
return ks;
}
- private static void testSignature(String algorithm, PrivateKey privateKey, PublicKey publicKey) throws Exception {
- System.out.println("Testing " + algorithm + "...");
- Signature s = Signature.getInstance(algorithm, provider);
+ private static void testSignature(String mdAlg, PrivateKey privateKey,
+ PublicKey publicKey) throws NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException {
+ System.out.println("Testing against " + mdAlg + "...");
+ String sigAlg = SigTestUtil.generateSigAlg(SignatureType.RSA, mdAlg);
+ Signature s = Signature.getInstance(sigAlg, provider);
s.initSign(privateKey);
s.update(data);
byte[] sig = s.sign();
@@ -63,31 +72,40 @@
boolean result;
result = s.verify(sig);
if (result == false) {
- throw new Exception("Verification 1 failed");
+ throw new RuntimeException("Verification 1 failed");
}
s.update(data);
result = s.verify(sig);
if (result == false) {
- throw new Exception("Verification 2 failed");
+ throw new RuntimeException("Verification 2 failed");
}
result = s.verify(sig);
if (result == true) {
- throw new Exception("Verification 3 succeeded");
+ throw new RuntimeException("Verification 3 succeeded");
}
}
- private static void test(PrivateKey privateKey, PublicKey publicKey) throws Exception {
- testSignature("MD2withRSA", privateKey, publicKey);
- testSignature("MD5withRSA", privateKey, publicKey);
- testSignature("SHA1withRSA", privateKey, publicKey);
- testSignature("SHA224withRSA", privateKey, publicKey);
- testSignature("SHA256withRSA", privateKey, publicKey);
- RSAPublicKey rsaKey = (RSAPublicKey)publicKey;
- if (rsaKey.getModulus().bitLength() > 512) {
- // for SHA384 and SHA512 the data is too long for 512 bit keys
- testSignature("SHA384withRSA", privateKey, publicKey);
- testSignature("SHA512withRSA", privateKey, publicKey);
+ private static void test(PrivateKey privateKey, PublicKey publicKey)
+ throws Exception {
+
+ int testSize = ((RSAPublicKey)publicKey).getModulus().bitLength();
+ System.out.println("modulus size = " + testSize);
+ // work around a corner case where the key size is one bit short
+ if ((testSize & 0x07) != 0) {
+ testSize += (8 - (testSize & 0x07));
+ System.out.println("adjusted modulus size = " + testSize);
}
+ Iterable<String> sign_alg_pkcs15 =
+ SigTestUtil.getDigestAlgorithms(SignatureType.RSA, testSize);
+ sign_alg_pkcs15.forEach(testAlg -> {
+ try {
+ testSignature(testAlg, privateKey, publicKey);
+ } catch (NoSuchAlgorithmException | InvalidKeyException |
+ SignatureException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ );
}
public static void main(String[] args) throws Exception {
diff --git a/jdk/test/sun/security/rsa/pss/InitAgain.java b/jdk/test/sun/security/rsa/pss/InitAgain.java
new file mode 100644
index 0000000..a8085cc
--- /dev/null
+++ b/jdk/test/sun/security/rsa/pss/InitAgain.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+import java.security.*;
+import java.security.spec.*;
+
+/**
+ * @test
+ * @bug 8205445
+ * @summary Make sure old state is cleared when init is called again
+ */
+public class InitAgain {
+
+ public static void main(String[] args) throws Exception {
+
+ byte[] msg = "hello".getBytes();
+
+ Signature s1 = Signature.getInstance("RSASSA-PSS");
+ Signature s2 = Signature.getInstance("RSASSA-PSS");
+
+ s1.setParameter(PSSParameterSpec.DEFAULT);
+ s2.setParameter(PSSParameterSpec.DEFAULT);
+
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+ kpg.initialize(1024);
+ KeyPair kp = kpg.generateKeyPair();
+
+ s1.initSign(kp.getPrivate());
+ s1.update(msg);
+ s1.initSign(kp.getPrivate());
+ s1.update(msg);
+ // Data digested in s1:
+ // Before this fix, msg | msg
+ // After this fix, msg
+
+ s2.initVerify(kp.getPublic());
+ s2.update(msg);
+ s2.initVerify(kp.getPublic());
+ s2.update(msg);
+ s2.initVerify(kp.getPublic());
+ s2.update(msg);
+ // Data digested in s2:
+ // Before this fix, msg | msg | msg
+ // After this fix, msg
+
+ if (!s2.verify(s1.sign())) {
+ throw new Exception();
+ }
+ }
+}
diff --git a/jdk/test/sun/security/rsa/pss/PSSParametersTest.java b/jdk/test/sun/security/rsa/pss/PSSParametersTest.java
new file mode 100644
index 0000000..1075b93
--- /dev/null
+++ b/jdk/test/sun/security/rsa/pss/PSSParametersTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+import java.security.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.*;
+import java.util.Arrays;
+import java.util.stream.IntStream;
+import static javax.crypto.Cipher.PRIVATE_KEY;
+import static javax.crypto.Cipher.PUBLIC_KEY;
+
+/**
+ * @test
+ * @bug 8146293
+ * @summary Test RSASSA-PSS AlgorithmParameters impl of SunRsaSign provider.
+ * @run main PSSParametersTest
+ */
+public class PSSParametersTest {
+ /**
+ * JDK default RSA Provider.
+ */
+ private static final String PROVIDER = "SunRsaSign";
+
+ private static final String ALGO = "RSASSA-PSS";
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("Testing against DEFAULT parameters");
+ test(PSSParameterSpec.DEFAULT);
+ System.out.println("Testing against custom parameters");
+ test(new PSSParameterSpec("SHA-512/224", "MGF1", MGF1ParameterSpec.SHA384,
+ 100, 1));
+ System.out.println("Test Passed");
+ }
+
+ // test against the given spec by initializing w/ it, generate the DER bytes,
+ // then initialize another instance w/ the DER bytes, retrieve the spec.
+ // compare both spec for equality and throw exception if the comparison failed.
+ private static void test(PSSParameterSpec spec) throws Exception {
+ AlgorithmParameters params = AlgorithmParameters.getInstance(ALGO, PROVIDER);
+ params.init(spec);
+ byte[] encoded = params.getEncoded();
+ AlgorithmParameters params2 = AlgorithmParameters.getInstance(ALGO, PROVIDER);
+ params2.init(encoded);
+ PSSParameterSpec spec2 = params2.getParameterSpec(PSSParameterSpec.class);
+ if (!isEqual(spec, spec2)) {
+ throw new RuntimeException("Spec check Failed");
+ }
+ }
+
+ private static boolean isEqual(PSSParameterSpec spec, PSSParameterSpec spec2)
+ throws Exception {
+ if (spec == spec2) return true;
+ if (spec == null || spec2 == null) return false;
+
+ if (!spec.getDigestAlgorithm().equals(spec2.getDigestAlgorithm())) {
+ System.out.println("Different digest algorithms: " +
+ spec.getDigestAlgorithm() + " vs " + spec2.getDigestAlgorithm());
+ return false;
+ }
+ if (!spec.getMGFAlgorithm().equals(spec2.getMGFAlgorithm())) {
+ System.out.println("Different MGF algorithms: " +
+ spec.getMGFAlgorithm() + " vs " + spec2.getMGFAlgorithm());
+ return false;
+ }
+ if (spec.getSaltLength() != spec2.getSaltLength()) {
+ System.out.println("Different Salt Length: " +
+ spec.getSaltLength() + " vs " + spec2.getSaltLength());
+ return false;
+ }
+ if (spec.getTrailerField() != spec2.getTrailerField()) {
+ System.out.println("Different TrailerField: " +
+ spec.getTrailerField() + " vs " + spec2.getTrailerField());
+ return false;
+ }
+ // continue checking MGF Parameters
+ AlgorithmParameterSpec mgfParams = spec.getMGFParameters();
+ AlgorithmParameterSpec mgfParams2 = spec2.getMGFParameters();
+ if (mgfParams == mgfParams2) return true;
+ if (mgfParams == null || mgfParams2 == null) {
+ System.out.println("Different MGF Parameters: " +
+ mgfParams + " vs " + mgfParams2);
+ return false;
+ }
+ if (mgfParams instanceof MGF1ParameterSpec) {
+ if (mgfParams2 instanceof MGF1ParameterSpec) {
+ boolean result =
+ ((MGF1ParameterSpec)mgfParams).getDigestAlgorithm().equals
+ (((MGF1ParameterSpec)mgfParams2).getDigestAlgorithm());
+ if (!result) {
+ System.out.println("Different Digest algo in MGF Parameters: " +
+ ((MGF1ParameterSpec)mgfParams).getDigestAlgorithm() + " vs " +
+ ((MGF1ParameterSpec)mgfParams2).getDigestAlgorithm());
+ }
+ return result;
+ } else {
+ System.out.println("Different MGF Parameters types: " +
+ mgfParams.getClass() + " vs " + mgfParams2.getClass());
+ return false;
+ }
+ }
+ throw new RuntimeException("Unrecognized MGFParameters: " + mgfParams);
+ }
+}
diff --git a/jdk/test/sun/security/rsa/pss/SigGenPSS_186-3.txt b/jdk/test/sun/security/rsa/pss/SigGenPSS_186-3.txt
new file mode 100644
index 0000000..4db0223
--- /dev/null
+++ b/jdk/test/sun/security/rsa/pss/SigGenPSS_186-3.txt
@@ -0,0 +1,420 @@
+# CAVS 11.4
+# "FIPS186-3 - SigGen RSA PKCS#1 RSASSA-PSS" information
+# Combinations selected:Mod Size 2048 with SHA-224(Salt len: 15); SHA-256(Salt len: 20); SHA-384(Salt len: 25); SHA-512(Salt len: 30);; Mod Size 3072 with SHA-224(Salt len: 28); SHA-256(Salt len: 32); SHA-384(Salt len: 48); SHA-512(Salt len: 62);
+
+
+[mod = 2048]
+
+n = c5062b58d8539c765e1e5dbaf14cf75dd56c2e13105fecfd1a930bbb5948ff328f126abe779359ca59bca752c308d281573bc6178b6c0fef7dc445e4f826430437b9f9d790581de5749c2cb9cb26d42b2fee15b6b26f09c99670336423b86bc5bec71113157be2d944d7ff3eebffb28413143ea36755db0ae62ff5b724eecb3d316b6bac67e89cacd8171937e2ab19bd353a89acea8c36f81c89a620d5fd2effea896601c7f9daca7f033f635a3a943331d1b1b4f5288790b53af352f1121ca1bef205f40dc012c412b40bdd27585b946466d75f7ee0a7f9d549b4bece6f43ac3ee65fe7fd37123359d9f1a850ad450aaf5c94eb11dea3fc0fc6e9856b1805ef
+
+e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c94f
+d = 49e5786bb4d332f94586327bde088875379b75d128488f08e574ab4715302a87eea52d4c4a23d8b97af7944804337c5f55e16ba9ffafc0c9fd9b88eca443f39b7967170ddb8ce7ddb93c6087c8066c4a95538a441b9dc80dc9f7810054fd1e5c9d0250c978bb2d748abe1e9465d71a8165d3126dce5db2adacc003e9062ba37a54b63e5f49a4eafebd7e4bf5b0a796c2b3a950fa09c798d3fa3e86c4b62c33ba9365eda054e5fe74a41f21b595026acf1093c90a8c71722f91af1ed29a41a2449a320fc7ba3120e3e8c3e4240c04925cc698ecd66c7c906bdf240adad972b4dff4869d400b5d13e33eeba38e075e872b0ed3e91cc9c283867a4ffc3901d2069f
+
+
+SHAAlg = SHA-224
+Msg = 37ddd9901478ae5c16878702cea4a19e786d35582de44ae65a16cd5370fbe3ffdd9e7ee83c7d2f27c8333bbe1754f090059939b1ee3d71e020a675528f48fdb2cbc72c65305b65125c796162e7b07e044ed15af52f52a1febcf4237e6aa42a69e99f0a9159daf924bba12176a57ef4013a5cc0ab5aec83471648005d67d7122e
+S = 7e628bcbe6ff83a937b8961197d8bdbb322818aa8bdf30cdfb67ca6bf025ef6f09a99dba4c3ee2807d0b7c77776cfeff33b68d7e3fa859c4688626b2441897d26e5d6b559dd72a596e7dad7def9278419db375f7c67cee0740394502212ebdd4a6c8d3af6ee2fd696d8523de6908492b7cbf2254f15a348956c19840dc15a3d732ef862b62ede022290de3af11ca5e79a3392fff06f75aca8c88a2de1858b35a216d8f73fd70e9d67958ed39a6f8976fb94ec6e61f238a52f9d42241e8354f89e3ece94d6fa5bfbba1eeb70e1698bff31a685fbe799fb44efe21338ed6eea2129155aabc0943bc9f69a8e58897db6a8abcc2879d5d0c5d3e6dc5eb48cf16dac8
+SaltVal = 463729b3eaf43502d9cff129925681
+
+SHAAlg = SHA-224
+Msg = 5c61546b848a36e8e51f8beb1140823dbd95b06660924d16fdf9a1c33ca0b994c0745e7eb5be48ada8a58e259cf461a95a1efadb0880d1a6fde510d9d44f4714bff561e81e88d73a51ba23e8ca0178b06698b04dfdc886e23865059ca29b409302eb44f2e9704b588767327ec2ee2d198a0cba0266f2d39453806855cf0b0cd9
+S = 134e6acd94b76a86e7ff730f064a3d480d1cff1687b993163ce09f21d494a4a15e6d92758a93f7c83ead21c4ca290f9478241c9811c231f32d9d17e0b479a9b34cad02e5bbdde6c8e4ec4f35f93524f8afde49e6a4740bab2f2fdeff3fc5d92a1b50adc7af964eec82fb80be24092ab28791807c664a9106b5df3296747c014b75d69d181f2e58dafbbf9127164f88c862a48d5e9edcd6d2b2cbc20abceb0e98c7e731d27c8d04fad95ff50dd64af20e6388ed74b9b3cf33b4a316b0c752f33697e5a7445ae2f726f30333f107928872776225a3e0b1b14a7e84f9a695c7b3910330d225b4834110b54d6b05e69df6b7a2c9dc352942e3bce970cec677253230
+SaltVal = 463729b3eaf43502d9cff129925681
+
+SHAAlg = SHA-224
+Msg = 7540edea54a4fa579684a5b59c51eb20e61106f82157917c6173ee9babe6e506b6198d8af24e709dcad6ea372684d2e335635c1569a43ebec3da121e506afcd9f43c8c4e66b7e6247ced2025a912eb50c43376290a248f5467bb0c62f13b69ebb513b2ddb7c9a31334310f2a2ae27e901bea1add0dc1cc67d57ca21095437463
+S = 45541aa65fbb0773b1434c4fdaafe23fe800f78eba900c6104a6f0e76dc08daedc28a3380c8078f82055cd4a20cf30541c32d9ac625378355c156880b35a29645325d488f7a0d2de7df92cf9bccdf851445c2b834ad0e6849a6549db72affa7ce66fbbfc5bc0194504a5fb031267b6ca9b57f583e7e11c927e3dc203f7d6d4b9df675d2a302231400008fbbd4a05e17f88bea074de9ab8211a18dcceae6c9fd8fad96ce0626eb25c9ab81df55ba4d0a6ae01eb25a2529e16c98ded286cb345d4fd59124297ba9b3efcb67884ed853ea96d74e00951987bcda54d404d08f2baf7f0d7ff13d81d1fa20cde1d21663684c13ffc7164448f4e85a6c811a850a3faed
+SaltVal = 463729b3eaf43502d9cff129925681
+
+SHAAlg = SHA-224
+Msg = 840ff32993223efe341eeb55558e6ab1fbae15d17bcf0731edfd32d4dee0ac4145e04accb88c7016e03d27d72bf670dbc08fd94bb8134d2e8b66302fc82baca10ae445c0275bb43aaa42f2ee841693f3fe4955dcf29ff93a3bd951636a919b72ba650d8f4757b1717a747320c8b479009c22b20b913cb25ee59dbdf72bd921bd
+S = 07f07ef5e793d59b0c3f899dc846bb831d88dd4d2d8345ad2d726c5c532d13e05b26f0fd03b2b9bde7b6d5b6febc8fe5d3228887eac443c99ec39fffeb939785f87be8a93e497cfdea3d8d06356518a5254c5946236458b29f1cd47e97718c805b167791d10f9304328635330116a2aeae1e0ecc16bfd5a31356d06892b8ca04aec27a417320be7bf6fc1083d70fa522c23850f5d6beda1a251d1a5e71762bc8fd5f16ef0c7a961f4858a5b760a8032f3fd6bdce2ed26351f2beab8b89d9312d88736ee5253a9da6753283e5b3d0d9cdd3e19ca0b60b9fae3e3dfd67831df72ed9611d5f2b3ac256052a207a5245d2cdeaad0d1266c7177b1a0844d5974a8a41
+SaltVal = 463729b3eaf43502d9cff129925681
+
+SHAAlg = SHA-224
+Msg = a5fb396eee4045f886191f7ff9ea68aaa1bcd8e781903b6071f3ba2b7cd35cc08691cdb131575d9502ac4b45c046444c1d1f279899cb0b76a20883bd00972148704a38aa8f5fe61efa0c52bdb45b33f4c83892342fc8d0ebf3fdeab49568fccaad4e04c3d0fde97bb660bc4e9cd23d8ae830a1230c3292a9acfb787803eef72f
+S = 4428c389d0c80a9320e4859e41cbd4a47f78e4da5d1c0644ff50bad172de9ffe74d84a76d6de4f72bbe34d7dccaa03e1324041cb98308d73dcff0bcf7ffc35936473cf3ec53c66ea8a6135742e0ea9056a4897a7cbd2b0654b344786bf3047d122dcbbc4bea1840e84bce066c3385dccb021a79e8de18dc114a40d824141d8331a4df6901b3409c30552519b097a96ded6793cbb9ae18bb9a4185b6f4e83aad6dce878c689bf595d272719b9f50b3ede1803dfae6dd3f54e4ca9c458c14463f4f19af6cc8127bec80a6a9e5a5fe0d3e14dfcc6ba052750ebbf84a652adde9d6be68d5b134cd09bb94d0875e5527fe3f3fa2a516dc05c14fd5516dff2d434f0c4
+SaltVal = 463729b3eaf43502d9cff129925681
+
+SHAAlg = SHA-224
+Msg = 6e891589d71d2eff6cb986b071a31e2696d8ce671fa18c244267eb33d0c8e24018ebcfbf0910bb24966be0575f3268628df5786dfd2e6deda219661824c5029ccd6b6b90a60093abdd06bdb46aa74039f2048784eccb5dcb020767a7ba3df2c755b4f0e6f8143cfa093326afdc2b2b138fb0049332a0e3262bdcf9c8d9573b2a
+S = 01909328c24dd0ef912040f61492e3711243f8ca1262067cca6bdab165efe4157982323f13152999e9f21e6852d8c2efc4130e2c46a38446aacfc59fbca5d1a38946923b7e08be397fb787bc79a71ba08fc2b693d1bcbe897d1dface2858ba80a086a0e0a45efe66fd5350add819fd0dc1931d3eba2765f84f147422f5330d0efa0cd827197a5d89e2dd62db9051d5df8b9680169f349086dd038a9ac62f9941565b3f747d528ec4c36e9c948ad3a73240d07ef14b354ffef1b1965a9aafb13d0fc88a09707c6a0ad3028d5a5c6efaab50aad05304b1d5b2930abb8f58c0188b6a94231f8698c96ddd614343a0218494dfff9a293dfc7d5c3b5afbed8f079458
+SaltVal = 463729b3eaf43502d9cff129925681
+
+SHAAlg = SHA-224
+Msg = d66747638d8276920352b215158cefe0727a5e2b079d892cbb969f265d470ca2da354dfcb4300322af374699ce963bc17d51e95910c548456c8d9b8f04a300ad08c74602d825fea7bf32d56aded7211766d1b9f70b580a97b5fe67ca78dba1f1c6e7d87ae3a790a79a0c07912f98c76c94c2770cdf9cf6a8fcb3abdf9f3616f8
+S = 85f296084bda823556aa369e5cb19e10ce6e982a6d10a85ba6af6d3fed8f2c05599faed069215cc9eed9e72a4fe510a6c09ff721cf1a860e48cf645438c92c5c86d0885e7d246ccf9d0cfd8c56ca8d673b7094a3daa77db272d716f31b1380f72b50378f595471e4e481851c57a6b574bfb3fc7aa03636632045fcc8e9cc54594759f6014b527877e605ef60cf109b4ca71e772a99acfc7243318655ec50f74e48485668ed42859ff2c5934581ba184d926c8467d7c35257dce9964049568a990f65d591c2db86b48a7256da947fd7d978dd6734bd8685025d1a87e32f52a0299394c93e6d518b18e0b8db1d763f46905f405df0cbc8455e039f173e2b68c9de
+SaltVal = 463729b3eaf43502d9cff129925681
+
+SHAAlg = SHA-224
+Msg = 23d92665e88a4f6f732de384034d493d5df37b767a8260557de05688e8d60dcd0eba9cb8cc4bceb174dcbd3c0ab5a37db3b6ecfb6a3d90a4f54a9f1117e11e0c08b0114f22f2d98fdd93c0b9fd95d37c0ab2f00701431f1449602525e849570df704adb353481713969a148546b680424c30ad24a75bb6ad616a104bc2d562da
+S = 8beeb201aedb9fe7d535fc7989713062497a03e18ef9977b98a93f18f37545c38f5e5206e2b5df7f4a41ab9e0675f7d46d172dc3af90fb7b1a6fa6c986b803a7f2ea4ed217872cc686165b1278450c23c329ee2855f65e651c3db085e407bf3e3a96eaa833ba2056a084031546cea2f454f7acf84c3b90fd7b6210ef6d1ad71ed1b0049262f5b4e3ca99d10a3307752b2ad8e8fbba3a3e8432bc966553901e87150738aac9170fab1d27219274ec528299f8afbbd861ee837f2c86ecce7e73c9b7bd6f6661d1efe3fd2ff7b3efa0d1fc7b84fefffa14b55a2c5fe3252cae0cf0da6e50e3d615f86ae6721aa5e29ed3a1c71c243c2529eef483c56b902e93718c
+SaltVal = 463729b3eaf43502d9cff129925681
+
+SHAAlg = SHA-224
+Msg = 40abb42db34067fadb5aacbb2fdedd2d0324030bb75ca58f2e2ade378194b2c5f51ea2892b337ee297c77b03333b86f37581d7d77e80c87494bae8f0d22c4bd81e7525685c3b9706e1cbc90f2bff39d6cf6553eab29d41987c0304b14a8fc48ea4f96450ae205a6ca2acbe687df2a0dff9199fcbbc7bb704cf4e5b035184c4ec
+S = 54bec66241dc197ad92e695526b3b6a030216b48af90d93c36b2d70644e40cda2cb259f27ca9d141e5753f938497e84208b380ffe1788701c71d89bbea3edd352dabd32d9425edcf9a33e185cbc4031aa6069863fe47d499536a59da12a8bdbbf2a3a9f0039318d066f5117bbf6fce4f6752088ccc3a081d85da461a8bdcaf349fd4054f76384e668d00a6f747688c8420c7e452b0736ad62e1738a3f10cb62bc7ddc12fa670f858b2d5def9a42ac8f2fc91d488738a7c23168f51ddfbdae6a5d8ee1fc561cc3add4a7e14eb103bf9593cebf391c1f7a07d262faf03d47d07424ffb3a916a9564652a1be020a0e922e99a57da1abf931f74cfbdd484c0a9568f
+SaltVal = 463729b3eaf43502d9cff129925681
+
+SHAAlg = SHA-224
+Msg = ef10b03c04578bd5f783358df367456a73de38c6fab2c35405bc685e3d4c4850f2cb387ac59e1612a44e5e78fce6f8be299d546832b5b970b3a3da8e1a70abb6165f72e14dd021104e64e38ec662f576f65ab776640803d2d17abdac6c75ab82451687f804b553d8db0eed57b9a3e39ac15c8878fa714882488938409b24f1be
+S = 4a183b82616f3bbc27a146710b28729161feb17900be62e69eed5d254d15f34bce52d6f3deba89a787ebeb0611e240cc23e16add3796d4a29783e2cbe8797e066cecbd66059c394f0e2f9e377f1ffa194fcb895e1c48874b9b6430a13c779f5ca29e3f42bca4b916710590ab6501809d645a4885b058dba0647971f04f6f2f4a296c45d89dd848b7c2f8777ec50846c97d35c12d54ebb6ff167327b1d4daedf4468031b59057d57ceddb79fdd013167ee6e46d9130693322c3ae6702901a1e90bd4b621d141977d0680acd524921bc540e34ac640ace02f89d5436808283e026e138ba3a5a4310fe1e048833f9b581baef5f891f9cdb2f0673bafa11ceabc7d7
+SaltVal = 463729b3eaf43502d9cff129925681
+
+SHAAlg = SHA-256
+Msg = dfc22604b95d15328059745c6c98eb9dfb347cf9f170aff19deeec555f22285a6706c4ecbf0fb1458c60d9bf913fbae6f4c554d245d946b4bc5f34aec2ac6be8b33dc8e0e3a9d601dfd53678f5674443f67df78a3a9e0933e5f158b169ac8d1c4cd0fb872c14ca8e001e542ea0f9cfda88c42dcad8a74097a00c22055b0bd41f
+S = 8b46f2c889d819f860af0a6c4c889e4d1436c6ca174464d22ae11b9ccc265d743c67e569accbc5a80d4dd5f1bf4039e23de52aece40291c75f8936c58c9a2f77a780bbe7ad31eb76742f7b2b8b14ca1a7196af7e673a3cfc237d50f615b75cf4a7ea78a948bedaf9242494b41e1db51f437f15fd2551bb5d24eefb1c3e60f03694d0033a1e0a9b9f5e4ab97d457dff9b9da516dc226d6d6529500308ed74a2e6d9f3c10595788a52a1bc0664aedf33efc8badd037eb7b880772bdb04a6046e9edeee4197c25507fb0f11ab1c9f63f53c8820ea8405cfd7721692475b4d72355fa9a3804f29e6b6a7b059c4441d54b28e4eed2529c6103b5432c71332ce742bcc
+SaltVal = e1256fc1eeef81773fdd54657e4007fde6bcb9b1
+
+SHAAlg = SHA-256
+Msg = fd6a063e61c2b354fe8cb37a5f3788b5c01ff15a725f6b8181e6f6b795ce1cf316e930cc939cd4e865f0bdb88fe6bb62e90bf3ff7e4d6f07320dda09a87584a0620cada22a87ff9ab1e35c7977b0da88eab00ca1d2a0849fec569513d50c5e392afc032aee2d3e522c8c1725dd3eef0e0b35c3a83701af31f9e9b13ce63bb0a5
+S = 492b6f6884df461fe10516b6b8cc205385c20108ec47d5db69283f4a7688e318cfdc3c491fb29225325aeb46efc75e855840910bbaf0d1c8d4784542b970754aaa84bfe47c77b3a1b5037d4d79759471e96cc7a527a0ed067e21709ef7f4c4111b60b8c08082c8180c7c96b61c0f7102ed9b90e24de11e6298bb244518f9b446ce641fe995e9cc299ed411b65eb25eaae9e553484a0a7e956eadf0840888c70e5ca6ebc3e479f8c69c53cf31370ab385e8b673dc45a0c1964ec49468d18246213a8f93a2a96aad5a2701c191a14a31519e4f36544d668708ff37be5481cb0ffa2b0e1f145e29f8575dfa9ec30c6cb41c393439292210ea806a505598ebdf0833
+SaltVal = e1256fc1eeef81773fdd54657e4007fde6bcb9b1
+
+SHAAlg = SHA-256
+Msg = 7e6690203cb068b8530cb1ff4eeaf0fc69a4e304f556072dfeef5c052c886c83e7f58a3dbe9a58dc0a808ccdcea9f33ae2a0b6395153dc43ff2510e78f40a4bf8328d7a4a596531ea683fa1e0683e2f033549e6bf5b7c06b097e9b810de74ee89c28febbb94b6266713c855bbc21c706a5e92502aa28bb8d662287396d2570e5
+S = 509a01bb0360d1160ed3ff33432291cfbb63daa2933819600db7dd825aef13dd1e9a888a9fb6fea93debd4cf4bc77129b06dd4727193d7e8a2e5aa5a6020b64524e93abb0406f5a18f74ff0aa804919df4072e319ce8234431c94e8eef8c5ce813a07b2f66dd6a032c3e69a3c58c6b54acf08bbbb019df15f3abd22c67f3e2cbffe99887adee58a39cc30ac45a6e6e59283ee0890aa87072a857845f5cf3ddacdc776e58e50b66e95eb13dec49ce45505c378734e964e8095d34a01317768b7b9fbef6eb24b08b1bf0312ab51e0acea4a3dfdfa6fa7bb115b8b685d354841d1901bc73cc655ae246a5453ea8d160610425c2c14969bf22a7e11e663cff1501f1
+SaltVal = e1256fc1eeef81773fdd54657e4007fde6bcb9b1
+
+SHAAlg = SHA-256
+Msg = 1dce34c62e4aef45e1e738497b602e82c1fe469f730cf164178b79fdf7272c926d69bd1b5e2de776055753b6f2c2bcbf52795110702a5bdf7cd71f6b8ccf068ee0ddfb916abf15458dd9764f262b73c4c981f5f64de91e8d8a6a30d961f3ab66fd92b6d159e6c0db02d767bc1f8499baae7df9f910338495c8ad74ee807c6443
+S = 1bd79d25ac6b0f242f39555c85d858c23680e1ebf9590d05463ebc58454a7822cf0e0c2ab9872b6eac5ae8ce3da773d6b2039e9b26ce751dadc48579320ea63b978b0df038191d9128102128a365c01d9e2b43fe2b5ef1ce9ee8f4a1e12caef1bbe7f3a8d1a93c9f399753bbfd60d22d8f39206a511ea448dc23cc0e4fcf0b77d3f3fbd9188b740de3f85009de94ee157dbf7edc3165e9f69b59db37f7fdc507496de8941a2a2628774b06c8cab034bbe3d2c04d253b5948d6e5712373ada99b7f860612440c5eed81efeea18d76329dc30bd9fcc500e92315677142d5e1b6b45ae0e6e725122f046c9a544ad1ef1ddc7c6b2a7809715ab75ef870ee6670627a
+SaltVal = e1256fc1eeef81773fdd54657e4007fde6bcb9b1
+
+SHAAlg = SHA-256
+Msg = c32976432e240d23df6594f2885f00db7fa7e53b7aa84ef89798ec149fab74828b86423847f64285b7e210a5f87e5e93e8c2971ee81bc13fe060a8aa840739a3d6992c13ec63e6dbf46f9d6875b2bd87d8878a7b265c074e13ab17643c2de356ad4a7bfda6d3c0cc9ff381638963e46257de087bbdd5e8cc3763836b4e833a42
+S = be69c54dad9d8b6db7676fe74321a0aeb08d1cc17f6607e87982f99489344e99378c38341e0e605b8ff903c74a973872a9880e05a8ef0bd3e6049931acf152dd54fec9105a57b73f77631db736b427f1bd83275e0173d4e09cd4f8c382e8b502a3b0adbd0c68911d02de17fff3d927e250e1826762efc0b895dfa502f18dc334b4c573f99b51b74fdd23009861028f1eed6875bf31d557acd6de8f63fa1274f7bed7a1b4c079f5a9b85bfab29f552c7f647d6c9241563fac123a739674b0ad09c3f94208795d9a50529d799afc597e025f1254995f043234891620b10d5c5569be14b0f463a495f416024618486c7ff5ec775cfb46fbdff5379c5e09150b81a3
+SaltVal = e1256fc1eeef81773fdd54657e4007fde6bcb9b1
+
+SHAAlg = SHA-256
+Msg = 218551f425b3557d09ccfdecc9ab499085bd7fe7d60820be626c1a9aae293f5734a2f60fb661313dd15a9f22d5742268d4458306f91d65631b4777be928beecd4af733a416e0d8d94623d1e67bb0e1ceba4a5204c088e98895201953646477f58a0d6e7ded3834998faefcfe63686e0a5f5354a8d2509675f87f6821cbbdc217
+S = 96a269e0ca4af626aa8b7f45acdaa76d5dabfea5a7d762ab39b138dc7575fe196aeb182bee5b18503969b5ba111f057ccdbf292d7488173a4a4dd04e62c254d502673d5a076d326c66c9a71a3b83b1005c6366f8a0902987dbf08cee7562d0abffbdd661c3525be8e12dfd73ed31efaa817f61e7fef700a3215e77b6231d59c098fa455b69ec6e658a66cca2e8f2e090ef704270995170ba9a1f561b848676804413645a943d883191d95b024d6ffc9cb611c68f3319403bd7c07ac6694501368e8147a256e928604b63d50e2c65f3b2c30df1eb0363e29fe448f94b6907cdf42fbc9c27b31a43a8f5c15ce813f9b20d16da6c298843f052ed37678b4ef1d78e
+SaltVal = e1256fc1eeef81773fdd54657e4007fde6bcb9b1
+
+SHAAlg = SHA-256
+Msg = 06b76aaeb946fe6867e4716a8f1ee8d61c483ab345cbf8e5b2bfab5ce0bd5c8bc6ee5a1cb96837e28dbb140ffdc61ea74cd059342dd49dbce11bdef09f10b0a638510989fb02490fd66679acbfb0d04652167ce8bc289fbad760973196fa8283a405015e48bb3dd98c0e28ab9e83069a76432b37b97006c9deb55e878f21dc0a
+S = 65e2358bafc9fcb65536a19d27f710596cc31f9a8328cf9de21257506047ab1340a74505581a54f258bcbe0c1520f84ebd2e36913560dbd71574e3738428097d6b819e6900f27df159dcaf08c6e1591b073bfefe3da6bc827a649e0bae9c52fe9ae180d1efc01e5a38adef102c6d106af12163b1a0f6d1543ffce3980ca0f8b70d38007288d47bc565e995b8c21da2f959c928aa2f8574a660226048dc9dba59526a30e3274808683b41c0cf086ea5afc48eb294a88c4b8b7383dae6469e8483345b1daf1d2801bda93ff91ca75dfaa8dd5d47e73cecf0efb0629fda16c601070bee2e8cc0695150739202e3be270b9801d085e11e1df07f9a4cab54fda23da6
+SaltVal = e1256fc1eeef81773fdd54657e4007fde6bcb9b1
+
+SHAAlg = SHA-256
+Msg = f91670bf6b8bf5c8c75056d844168fc6ec0c28d09400c1df11c7ef0da9e04664c854b7e8f4e01dd8035612328c4107759bc894aaa9d50ca5cb7655892983f68ab28172f70ec6d577d4de8c93fe2e79749ad747eec2ddfbbecd89cc10c70b35451f6448f2a083452ca2ae6b0382240e4c4f01eaa4c661b7b181c8feab6bc22a1b
+S = 2eac03233c4e24b3328447cc09661c259676b569e6a0848b5a193065296a59e3b6d35a2ecd91c6cefda4f2bf9f2252a27334fbbc2d79e450d44bc282f7d7321b46f82028c154f30f6d62edf3672a1019d914ec617aab2d007f844e63e295bbd8f66163deb278d99d66fddc58cca2b911ce0af95265134af55a4b786cc214fa11ffa29bcdfbed12c5ce6438e9b6beaeffa3587978a83409c29f115423174c05cb8c30198da8b193f9446b9b49f7e3e2862ec9a350e8441ba4e5550e87db54712865fc2690a5938aebb28409b88cf0d172111a74f678ee0819ff8bdc22b08fc6fed37b676d0705396f3247a267c60f7ccf1fb260c0c2e924c1ef5540eb6125f3b1
+SaltVal = e1256fc1eeef81773fdd54657e4007fde6bcb9b1
+
+SHAAlg = SHA-256
+Msg = 64e3f541453170db952c09b93f98bcf5cb77d8b4983861fa652cb2c31639664fb5d279bdb826abdb8298253d2c705f8c84d0412156e989d2eb6e6c0cd0498023d88ed9e564ad7275e2ebcf579413e1c793682a4f13df2298e88bd8814a59dc6ed5fd5de2d32c8f51be0c4f2f01e90a4dff29db655682f3f4656a3e470ccf44d9
+S = 76c297fbe302f686377cb155ae8a2b65a6c577af303035c4a755fe67014c560476e7a789b8f2195b0f80416f5f33b7fdccc380f988cebadb640e354bf5679ee973a1e1485b68be432b446ff5949504515a65cddb0faf6dcd1e1188656ce941af3ddc8600cf0e4087ac8382f0d5061d3d05f58c9362eb88f30a724d18a15ee68a60c5e4dedb4084c9d01522999092094c85622e67a66ed034564ac286b0ff8791e9933a23f83b4a88d2e79e3a29d6a3f87e63bb1a96a6bfd6898edaa938f74c72d6c10cb94d055ef3fda9e6dd097d52738754800ed403b1444195a311fd6962007999e31edcf2870d1c3ae3b3646bc7da55e5f1e6627e6248839e8f70b997fc1e
+SaltVal = e1256fc1eeef81773fdd54657e4007fde6bcb9b1
+
+SHAAlg = SHA-256
+Msg = 33ba932aaf388458639f06eb9d5201fca5d106aaa8dedf61f5de6b5d6c81a96932a512edaa782c27a1dd5cb9c912fb64698fad135231ee1b1597eec173cd9ffd15270c7d7e70eced3d44777667bb78844448a4cd49e02a8f465e8b18e126ac8c43082ae31168ed319e9c002a5f969fe59fc392e07332ba45f1f9ea6b9dd5f8a0
+S = 2891cbe23ccf10c396ef76a5840adaad6498b6fc8c6a2f6c26496cb428a9221ed59b3645f9a25f5747feda0f51b45319e0978f22ac4facbc15db9a4e5849ac2a1404aeb6c00e5eed3c07eeeee2435668fd17f16ab244c9d38f9ba0de9d3f3ef0d994094e92e327948f1409ef827752344a1375f608dc3cafe74970745a023b320b3bd3171b62a68a5ccaadbc64b82cee4b8a81840ed8b751ac66a29eb81fb819ec54c76b01c7b412a43ea057a80202f1c3c06a4ee60547c13c6c2fac34a5d5aae982b9dabd119b470829bd77a560e0973409115bd1ab5bdc6bb46fe4048022b0cf4fc6aad4184c28621ec6f82edb54733c902620bf45f2517f24902e56d58038
+SaltVal = e1256fc1eeef81773fdd54657e4007fde6bcb9b1
+
+SHAAlg = SHA-384
+Msg = 833aa2b1dcc77607a44e804ee77d45408586c536861f6648adcd2fb65063368767c55c6fe2f237f6404250d75dec8fa68bcaf3b6e561863ae01c91aa23d80c6999a558a4c4cb317d540cde69f829aad674a89812f4d353689f04648c7020a73941620018295a4ae4083590cc603e801867a51c105a7fb319130f1022de44f13e
+S = 2ca37a3d6abd28c1eaf9bde5e7ac17f1fa799ce1b4b899d19985c2ff7c8ba959fe54e5afb8bc4021a1f1c687eebb8cba800d1c51636b1f68dc3e48f63e2da6bc6d09c6668f68e508c5d8c19bef154759e2f89ade152717370a8944f537578296380d1fe6be809e8b113d2b9d89e6a46f5c333d4fd48770fc1ea1c548104575b84cf071042bfe5acf496392be8351a41c46a2cab0864c4c1c5b5e0c7b27e7b88c69f37ffa7e1a8cd98f343ac84a4ad67025a40ed8f664e9d630337de6e48bb2125e2552123609491f183afd92634487f0b2cf971f2626e88858879d45a29b0fefb66cd41b2e4e968385bd9fc8c7211976bc6bd3e1ad6df60856985a825f4726d2
+SaltVal = b750587671afd76886e8ffb7865e78f706641b2e4251b48706
+
+SHAAlg = SHA-384
+Msg = 8925b87e9d1d739d8f975450b79d0919dde63e8a9eaa1cb511b40fe3abb9cd8960e894770bc2b253102c4b4640c357f5fd6feab39e3bb8f41564d805ceafc8fbdb00b2ea4f29ed57e700c7eff0b4827964619c0957e1547691e6690f7d45258a42959a3d2ff92c915c3a4fb38e19928c5ce3ddf49045f622d0624a677e23eb1d
+S = 43ef93d14e89b05d5e0db2dbd57a12403910646b4b0a24d9b80d947954591afa6e9809e96d7d3e711003ee0a9186ab3d8e0b4d3425c6da4b5f7899537e737b71df9ed6355529aace77a7cba96b5b0a86399252f1286a6fcab180b598455dfe1de4b80470d06318d5f7a52e45b6d0bcc00bd365819a4a142b83072775f485f63c8004f53378a9a0d2345d07b1b326238ed070d1e69fc0b5cf853a807cfb723562d1f5682482e8a4840588bcc7154ce0740c768616cf04d7aa103642917ec5b4b514a3734d9e0c58427cff42f27f43fdfc85991e045acd17af6fba7bdab818e90eb4117684e89f9163dff7b98b82a08baa2b49acde480c5702c335237d1be771b7
+SaltVal = b750587671afd76886e8ffb7865e78f706641b2e4251b48706
+
+SHAAlg = SHA-384
+Msg = d0eb4623eedbd97ee03672f8e4174d2e30a68323ce9980e2aafbb864ea2c96b37d2ab550f70e53d29cda03d1ba71a1023de78ba37dfb0e1a5ae21fd98b474c84338ff256b561afc1ca661a54d14db2e2661315e13581731010f6415d4066320519a363fdd2dbd5919362214bceb26716d3b188a39f32950cf5bd87b7b193307e
+S = 213ea3fb11cdd71bd5b839de8a598b6a142023825e24db7cb1a4459e78092b32b07643c7270839f247870efbd320b419ff3b1914c41b6ca4bc3cf17017d9a94d86f0f022f4495666c4a89f08e216a161d4664f2d616fa4bb2a17ccb85004e63f488ba29564ca136aa3a6f9561f85cb550b8cf8b0a85afbc8aee2c76891a53e7cb66e36f8709e7990d8de8d0c73865c1cb44727f18c0faf25c53f15e070c430e73f77b1e9c8f8ec13114d7e7ac790ade4ec6f1de0cec13f25a48d534965a8ede12090a928a91d5a1f214aefe6cee576ad43eaeccf635409a8646853d9cef93c9c04a884253380a49e682bff0750577c5a80becdef21a4a9793fabb579eb50e3fa
+SaltVal = b750587671afd76886e8ffb7865e78f706641b2e4251b48706
+
+SHAAlg = SHA-384
+Msg = d58e0997224d12e635586e9cedd82dddf6a268aa5570774c417163f635059ea643c1f24cabbab82eac004a8b9a68bb7e318fc526291b02040a445fa44294cf8075ea3c2114c5c38731bf20cb9258670304f5f666f129a7b135324ac92ec752a11211ce5e86f79bb96c9ed8a5fc309b3216dde2b2d620cd1a6a440aab202690d1
+S = 4385e67819283d81eab2b59357c51ce37b5ea32b76af345a457e5aa2dd61113865a587d2c8a8f1c8825281c052a88fc67797adb6251d28efb911564671affcbfc7e1a3c055dce8d93497fe80da459647ac71f17e9aa07d1aafd5260ac284d622a03b6670c55b0d40696d436c638f9b48bd08f37db4eaf1d9746d2c24de347dcca0a62df244bd2a554bd08d047efe52cb1266ee5988447e1b2740f960d22e9ed3f2573ea8753a60d306d654a26503a5416a4439ee44aefe08cfebbed56585eaa01a64bc812f589da9e9d51849b4d4feea04e2b03c4d4fe516decea1e3d9e7e35bfec17d7b2c218d8553bab921eab6410ad30cc131579497d186fa25cf62521fe9
+SaltVal = b750587671afd76886e8ffb7865e78f706641b2e4251b48706
+
+SHAAlg = SHA-384
+Msg = 3b9dc97a36492a68816aff839c135da2d7dec5505ddf496670dbf0e0f6b65ce9352baa38dbc09a9f41f8f0e1f0ca1ac56552126811c786d7a4ad37dd8b4b9f1ab760d655a112b6148b273e690877340ebea10eb46bfe139926d3be59e8cb63064aa4147a9028c6ece75fb0c2eb03f4a66c3481dc726d38d37eb74efa131cf1d4
+S = 3fc0e79913fc234e4f271cd6f5aa63bcd00e0c4fe2242815645d384781d5a00485076bc011f4412457bb7a2cb2695abfa18471ff6087038d585f802995159c8beee7607330759f310107c35b4a6a9a48fc910f45f70bffed1281f2215af34759ab08b68acd539ddd37f98a528434cf11ae0e85ef221f7117c757d970f3181e9ccda927469aa88de59ceae91c270818137761e56d75a3c01ac128b65818f28dbf7dd268337356e97bd104df6218db3b1292ec2652b62e5aeaafd905ec8fe67d6ed42e805048deb55cd9d75f818236687bc5b2cf33e17678c45a9b2144d58a4c77c163e57c1ee42cbd92bab46678092aef867968d8e6a387f7cef3920e4ee046eb
+SaltVal = b750587671afd76886e8ffb7865e78f706641b2e4251b48706
+
+SHAAlg = SHA-384
+Msg = 93ebc05837d0d50897a1d10bf1b08a6a767e52bfaa887da40d631d6cfb0b1011d1793d6e51731aae48a872056dfc659e8d21b0d4e5672ea4d0d59f62a278a9acd3fb1c9d60787a426e8eb75230b43d190ccc33b6f9fcff862cb909e0f324c203e19ae64c2b86fead527a285a027f1ac53ba965cdaeeef7326a37e44db7b866fe
+S = 19b1bbc3e4a23b44ec429dc4479f3fa45da87037136ada535bb325c0c03193a2ed8216a9621e9f48ad2c53af330570fdfc85fc1dbb077105af39e8e3a9faba4a79ffe987e1a37e5a49c60320d086e9292060e9fe671f1bfa18ad79f1ae559551a1d5520f8164a877b3fe1938fa51cbe8b5110a332c500585d288d8b30855afdddd233254f62e56eda75ea6854b84bb05e5b4497aca3d20baaf2d6d228a400135ecc45161c3f2e7258f8e4742aa687bd9f7a4468a61558fa0ddf79e5e0ca51ffaf0151bb255152219c76a08c3e46557ed6b1415622bdfd94f733ac10d8f388c0ef646d8f5d71a3205307db703d627287e2b7be15c33fff19147e5daa36d4252b1
+SaltVal = b750587671afd76886e8ffb7865e78f706641b2e4251b48706
+
+SHAAlg = SHA-384
+Msg = 8bb56404897a19140d112d939f73fd7d18a5d107aaa20332209664a0674cdba64eea4fa48adcc791fd0ed0da385e206d3e5178108a04cff85466ac9711a5d4b539e625c24c39c26b17cc706b345f40a4d0f76f6eb0d78a2f76acd52c2108ee9ed411ae09d87b50c9e3b3d5ed9b5da64956017cc724017dfe0fcfa806a15c728a
+S = 12f03c6f02b34f921831df384cc6e30d0b64f8ed133133ff190caca2503f1a4f4f721de6824ffde125bf41ae216e5feb8510e4d6337cec56f18550e78c69b1618457bc1b604d109e526c788628391ad8c29ad6c5da268922a55e4eb3053415a9de109112b5fac1f996236f46ed3a6c2f845c36bab09a4c21da20b17d2590c7b058fec130fbec4856ade373b6b0773994bed5ac7a420a09df8c1de246ad453dc8a62310accc9f0bdff16104dfd74c7752c33df20ef08c52d0bcdeacdf2a31298a3c72bb7397c3f9306fdbec45287688877fd6c965b8dcc513c9bdefc2f9ee7e92bac62438e4d80bd3ee2ca50a024d6fdedf39266480b2ec77eedea6b64a9c58ad
+SaltVal = b750587671afd76886e8ffb7865e78f706641b2e4251b48706
+
+SHAAlg = SHA-384
+Msg = 35ef7f038e9b98a421b9f6a129ebc641596380ea1648bf9fe35c50c71ddd8930e8a9dc5369a5acda365e5e5f0af1b477be2956ef74e8b25516c806baff01bbb7f78ef5ae658b6852c0e26d6a472655d2f2bffdc2a848a252b235f73e70b975e74ae7f39bea177616a88b4a494652525ade6d9ceb1831389fa0ec4bdad8cb5fc9
+S = af809f10fd160a88d42dc9d92285e2b2afd8162c38eb91a6b6273a66c30c79d7caec94a00fa732710d9f751219767185da5064ce26fec0647cb0670ecc68f2a601390dff07ff0237f284dd4fcb0b11148835c8114c5a15c513713dbc16286707eecaf2c450f588fc96217d34f59e0c716c7348270041b2c4386f5a5877f7fa48510cca8b07b70490f9eee957ec0a52ab955a3f1054695a7f5806f705fe3e9802770d591eddf2a83fe03d8adbf553ae59528051218db1f3fd070f8e1d3d4b4083588cf2710271ecca5d9369468d045b0f2e0ef285f9cfa65a04cd223fd84c01b8c740a4e95b9fb675c0d7c470b3598d06489bb7d6722eb72ab8120d7f0ae29a06
+SaltVal = b750587671afd76886e8ffb7865e78f706641b2e4251b48706
+
+SHAAlg = SHA-384
+Msg = b4422216f1e75f1cea1e971e29d945b9a2c7aa3d3cca70bc8dab8e61e50d6b038f9f46fa5396d5323f5b2c7ea880e12e6bf96ee37889d6a2927a8c285091907d6841dbcc2c1ffd725596055500dca177f62486cb301612479b7c303a183e7de0c790a933856a1f05b338e84c3ad4ccbdcbb1bb9c6c596cd23019444045fa7953
+S = 0f31c8fb4cef7233cc20bca20eaa5b42a9aed4a4f40855e2c518501ae1cfd71f98bf9ffdec1a74bea75bdf90b9c67c5824a7054ae57ef49806359ed64b2c5efdaf52829395fe426c802665bd7530ca3cbb40d5f29367ea55eba29903e8eba5df7556b5527335ac06a211c597e916fd6978ea5bc6daadccd4fcbc61ee64aacc902f652e545ef48579cd523944461d9161a542e2e7bd2a1da72ec9a751651d184fb75b16951e1b5a98107ab3ba680df0dd06131a9318e47e15326f27fc34dddeeac89b11236fdc9b8f799828dfa9714e6ca3982d8f79efa2a455e6d73421a1c933c92902790eb79adf0e4fb6202b6a0868aecac2208ab673b249a826646518aabc
+SaltVal = b750587671afd76886e8ffb7865e78f706641b2e4251b48706
+
+SHAAlg = SHA-384
+Msg = 882c97fad763ca235b162fba88fd714d023bf7380133681cfa9e6a8d7cdab00b58853334044bbf3741fcb28cfce201e372517b5a987f52f2ba96d744620885707b234157b6e5e00a2d11ea8147829d91dbc0351898d16b7ba4523c5283c6eb613b2d49cbb5d93482677d5e023087503f83afaedbc8d0bc9dfff7211fa7baebc6
+S = 0c4850b815169cda5c11f77bee14ff2fa1399af8dba09fb9485211ddd458e4152f966b2162cced299e496ca0c6cc891fce52fde9be554aa213c9f9dcce053452fe0702bf2e953ac6490c97660d8dae7ae557d94e4de409100951bd3f8be77ad5e6a7f8551190a1f2ede40fa5a12e5d995c7739221fd9be3970c05dfc990a103db1e9dff25e37234be4f70b372a4071a9c921a34de8f6c56f1106a2431b2fc2d60026c7f2cfab11ee75afaab90d72dc8e15c6d6ddee0d4302341f107c541b23368995b6e95a0efb3624e70e7980533a4d6cd823e26072a4bc88f2c01349222472ee394b86ec83f4fb9df8fd105fedc77d28b7a7e9d71451219eb42c25764bfec6
+SaltVal = b750587671afd76886e8ffb7865e78f706641b2e4251b48706
+
+SHAAlg = SHA-512
+Msg = 5f0fe2afa61b628c43ea3b6ba60567b1ae95f682076f01dfb64de011f25e9c4b3602a78b94cecbc14cd761339d2dc320dba504a3c2dcdedb0a78eb493bb11879c31158e5467795163562ec0ca26c19e0531530a815c28f9b52061076e61f831e2fc45b86631ea7d3271444be5dcb513a3d6de457a72afb67b77db65f9bb1c380
+S = 5e0712bb363e5034ef6b23c119e3b498644445faab5a4c0b4e217e4c832ab34c142d7f81dbf8affdb2dacefabb2f83524c5aa883fc5f06e528b232d90fbea9ca08ae5ac180d477eaed27d137e2b51bd613b69c543d555bfc7cd81a4f795753c8c64c6b5d2acd9e26d6225f5b26e4e66a945fd6477a277b580dbeaa46d0be498df9a093392926c905641945ec5b9597525e449af3743f80554788fc358bc0401a968ff98aaf34e50b352751f32274750ff5c1fba503050204cec9c77deede7f8fa20845d95f5177030bc91d51f26f29d2a65b870dc72b81e5ef9eeef990d7c7145bbf1a3bc7aedd19fa7cbb020756525f1802216c13296fd6aac11bf2d2d90494
+SaltVal = aa10fec3f83b7a97e092877a5bf9081283f502a0a46b50e395ab983a49ac
+
+SHAAlg = SHA-512
+Msg = 9e880ce59f547d592c309c22a2974ba5a52cf1c164f2d8a81ebbd4ede6e326dea33d9f135a4e0947b0b9c267aafbaae9b8583f5ff215074ca1e82f3601ad71fc455a3b6adc350d0bf345223e3b06548cec613a390ada9319e70ce7a5e9526b4e8dc82612ac72524cfdba05d0dc201037492d277834a843b9f80d4564253bdc7c
+S = 8c4f819e682081bb16ddd459662a8078bca4793e18110033539460b408c0af747ea5d941f712691f5d9ddb643166fd965f5b51b819d55141d67c1553b27a4682e67d5555b64d7cd3db7fc5c2e701dd26e422af8a1fb52cd5f5a09e0d6db900a992f318deeb6f6e39dfd6af44cb217c6854089ceaa16e3f9b100ef8e78f6b453458b8ef6d71493e7c6e45282c617fa87ccdd4a0f2f9f7166281806fb41d0fe188e00c40afeaa07d2da09a2cd78052f8d56b7af40d4c7314ccf02e490d5e2123bf676f2bcbdabeffcf58792998dd0f67ed24e483d8976b00d6151a6e0ba740bdb57c9bc27fe5df9126a47020075eb222d5ca2470724460c5adf067b5750287cd00
+SaltVal = aa10fec3f83b7a97e092877a5bf9081283f502a0a46b50e395ab983a49ac
+
+SHAAlg = SHA-512
+Msg = a6133ca436d3f2e0a6562f138975bcf785cd0c3b58b7671d197b483bc0c003a6e947aa39d5d93229b27ed2dc1cf0acffe34fafd30f16bcc7214e074c9c02c1e5c4f2f47da68baefe5817611f82328a7e1d7d91ee7b96f0128847982b4ffd902ec07ce01ab0d2ad882189a583c4219e9bbcbe7935a51d4d25d5ccc27fe19bbaa9
+S = 20ceee0fd620160ef6a40966fa4ef3d8f68c002a66d0103eb62a868a7ad7dce9523a5b83607b8cd0ca54f833f3a68c9fafa1de7fd723e22a0f724dfca1fb6bd1a88a7dbd17255ba1e06102c2cddf584f511bdd09e132b016f867896a592a28c53c70752a0b10d86bdbae9503928d2e0203ab8f845c1f77adef2bd2f4e126066fe15af4a5282d5d9fa73bec18d2e6a5969d766eba55c0bb95e13671f82646c35b31d894e7f95f2fd35f60d88c3e70b20f6f387326400f0a825bb9517df88bbcc4798861144782dd92ccaed36aec47d5365d3b61a495339ed58e2553b74f06a295ae47a309d8477b9ca838e77094718565903432ce243c9dffe6dad464cd5ee279
+SaltVal = aa10fec3f83b7a97e092877a5bf9081283f502a0a46b50e395ab983a49ac
+
+SHAAlg = SHA-512
+Msg = 6d60a4ee806bf0fdb5e3848f58342c0dbab5ee3929d2996e1f6aa029ba7629c96cec6293f4e314f98df77a1c65ef538f509d365ebe06264febc3666755a78eb073a2df3aa4e5d4606647f94cc8e800be22141208036a635e6b3d094c3a3a0e88e94bc4ea78bc58b9a79daa2869675c2096e22a40e0457923089f32e15277d0d8
+S = 912fdcc5719a8af7389db8756bb0f630a4c78a1bd1fec7c4a6f3e50924a9818c9eca4a4efbaf9e8bad55d6468d83c54d0450b53a267a50685e7fb93550c2ef3554f69b4e49d3be359bc0b88f3e753714684ac047b4dfb436140b13129fc4bbfeed86548500d487094d222ed4e249db0a46b34ba5247c1b86e8650a703c9d3e0374433d3af52578d35f0f9108439df0701188da206b579e1712811c1e33b3da32f33acc9cd0bed60cfe977a4a6c6aa6498ecebab9be86c216a7214eecb13c2b7d4d309f5488012056905060c3eabe90f36b01588acb328869034e00bd19bf5c1a44d8ea2a89b747b2875d97047c53f2903f67b5a60aa87aa70a9479735198a508
+SaltVal = aa10fec3f83b7a97e092877a5bf9081283f502a0a46b50e395ab983a49ac
+
+SHAAlg = SHA-512
+Msg = 1aa215c9f16050f31f0ce5adc8cfa594e44ef29087dc23ac65ed2a2595ce73c0959410618f5314dada903c01c4f8d5058f52d902b9b25cd281ef2627a658a2d672a3f776f726742a994a31bbcc3cf3ea1fe551047a1d15b6a31be52307302334b8b6112fb243398c62220c046903c9ea9df1a0be50851800d659ae4241c0be81
+S = 6ba800b8692ae568344c448094e3e16f50dc2c53edcfbbc9c7be9c07461c0e0686fcfed607af2a66291fcf8e9653fb3e9857b208ba210100df9e6c0495ab4d13f1029089cfea49a6be8b62036f30e0d4e4c1d95a5eb9580397d3bcf65a9311c2d8de249c2d1d7472369537cccedf8a7feb0c170eef41341f05e7d17caac4261b62498776a5eb1d9ce7e4746b4849f9021f0aff917179750253c719017fb5dd6855672eeb0847ca075e589e320f356f49872455b30f8cc1a3a7e1a4276ed6a909be06bd9f89c3494ff7db432d0d4d3f3ccb0be71b0bda4f66ff79773004905c6102d964b3b5a5e28e4578840c0e488b7f2b4f31066b61e13821e88a0ddd2b1c2e
+SaltVal = aa10fec3f83b7a97e092877a5bf9081283f502a0a46b50e395ab983a49ac
+
+SHAAlg = SHA-512
+Msg = cce6ea5a46bdd6805160dce409d1023cd71d3893303ca0497f392d5c5f936fe50ee2ade61ebd35426edcf00d597a39062dfdef62dfd9c9ccfdb2eaa9e3c1b6a03278e35a7e69d386476421212bdf7af4599bae5e49850653abdbd9a59d8f5a8220f0b43fcd875953c43f96a7e6ca6c0d443f9b0dd608ffe871fb1fd7f3c70494
+S = 9a465479c1474c1a54f16f309bd87b0c641a458d86173a4f29c2829fea0410787a81b3c1360cfc525d133dfdecc13acdd5199954dd8440739608545724cf1270caa39a221e9c6bfba399b9b05e55708875bac1578642ba7211260662299bf5ef68a39594e38faee14989ac5b2daa13211ece394cde46afa1b110bb55f631bdae5b848dfdb8920d7c74eff82ecdf59f2c6ed9b818c2336364b2a56d34a22ac42089dc5730e8e57b356cc4822c1e646268dc6a423e034b8b1512d41b88c70b27e431d68151e61a4fa5c89f1e90d621e07228c0346ca46f767a989f1b0d007237645d448030a7fe45ee0f46521272a8cc453a835984f8268752bef801b6226140b5
+SaltVal = aa10fec3f83b7a97e092877a5bf9081283f502a0a46b50e395ab983a49ac
+
+SHAAlg = SHA-512
+Msg = cb79cee1e7c3546750dd49fb760546e651e2a42ba4bbe16083e744bd1385c473916d273e9566673e98995903b44590e7acb580a02c6fdf1552af51716c134376049817151ac5823bb02633ed8cfcb697393397a14f94ca44f43c4a9ca34d01fe2ce3e88bfc4a6f059f6e1fe283927e9fff45335793926a9472787a653d9ac5b1
+S = 7cfcc23518bc137b94dbc87e83e5c942a5297ab4f70a4ad797b1dfa931c9cfcb30449ba3b443fd3abf4d350b80feaa9687b39e7b5b524ffa35063ae6b4e12a41fd734a24f89c3652b449c2154099a1c7739d5db77ba9de0358a69ec99bcc626f657213a256732631461851c919a93b04ad39800f02d0e627cd01d4b80697a9a1fb0d71df4f32ecaad3f1d5c80cac67a58c71ce81e23fc8a05ec840019c834d78ee1955c5e41065b323d01fdbe81b768448b4a7388886c9740b1541ecd8454f73ab64f90dd46cce6a2329beae9f3ee0bf567b507440ab3ca9de2e855374ddf6e105b3d0b33a138d716d138ce9f9570797a82eae557cf321fa09b862e31ee8d85b
+SaltVal = aa10fec3f83b7a97e092877a5bf9081283f502a0a46b50e395ab983a49ac
+
+SHAAlg = SHA-512
+Msg = 3ddc491798c6d8c2d6932502e14ca0d6cd90016c219438427268a38b377c84d4d862b2e708d58ff055fb39defde7050c0462292183ebb83543fcd4358a8f1f8835e172f20776d2b9415d9f0773b50f909170db7449573867944e090f8cda53ad7de0f1003eb08967c241be45eabea7a99d42802f1be1a0218ee7abe2e364098d
+S = 68a46140382dbf84b1794ce86937812d8220fc59e83dd1afa087efc41883616bfffb8283bd6dd5ee1930337951ded3be23fdc657e1bc07f41b539eb779ec98f436b367259b6841e495bf84555aff07674c9fb705c85a9cc1fde4bad40506e3373cc3a490daada1c10705177c165719104daa8ab675666625335e09a24f7a2363d7b3b878f34fe68fe01425275881c34b60ee78fcc0a54d56ac8304fc7a4bc0d5a447ab89b9206401e3c445bb1cc8e0c2541fe0f3634bb49d5af3a1b7c2e7651d208392718311247f0f15e4041a46301b93da2cda7af833d80191565833926a78468abac9eb4b02c5f047ed38851c3ed7add4edc05e8407481b8b942ab627e03d
+SaltVal = aa10fec3f83b7a97e092877a5bf9081283f502a0a46b50e395ab983a49ac
+
+SHAAlg = SHA-512
+Msg = d422e63e3c65eff3ee15c7eeb2ef0de7ab96a3c37e2af9c2b71d8ffa6842b504122796f5c9a5748f94b535b913851f2d64cce071465ad1087ff37be97c5d5b3038b8e2145f0ec019b22b6286adafb91a67613efbbbc633efa5f32bceee9fcc380c7cd48344c85af7111e573ec99364167efec5492297a7dfefc4a692062f9282
+S = 2bc6331715b62972a0a5dab2138c5663b0e33961063ce973e68e1ad172723bcea293f7ba35af24504cb2e373b11f80b49f79d3905e0aaef838fc7c7fb5df49a322d7c3daa294a1a0a8b71a52e2c5dd94575f319c64ef9f6fc6bbb70c0c97fa12ae78f73234aaeb93df299f81513458ecd243fca5284f44a1afcd0575dbf5f81d406236ce315e98ba4c9ef7c1d43896af3b5d172e7a786fc58c4220c27b56e5c7a9be49a40b49158305034a295a6c5743cda6c2c69f7ac02f87ed6cf7b4e989ce8218e5e7cbdac12fe7de3a5437170084ef8ce33e3530392c25a58ebeddc086685a4dfb9c0c5b91d946df65161ffbf82aa3d6a80c7c07995aa3ee06b1800a54ee
+SaltVal = aa10fec3f83b7a97e092877a5bf9081283f502a0a46b50e395ab983a49ac
+
+SHAAlg = SHA-512
+Msg = 6e87214fc1a8b0116f04a45a67e101ac75e9933366c532f96cee4559c4c085b695d1046d1c806d0706d18db41d7812f5273393980b5dd1e936c13d273dacba35c446a3929e21108b361355af2d41cc84447dd5787dd21a1a7d5c188a355ddb2ec18e08a790b32104c6720535de65b6c2946e5fbd024b96f5096ade6cf2fe700b
+S = 802db067a8d90967c2860c9076c1a0227560b59b66350490af1153d20b31840918e7d7262f633d37880a153b1a23e40d3cf9fcbd9c1610878b6317d9d1187f80074512524561f1c0f99f1b2ba168a15eac098b2b20673ac63f9b002e60887ff296d1212dc696450e7bb14a3efbdcdbc7f4ae2210ed35a3bf028d3eb99ab696f63a2fc69d8cce4b45846ab88943f89d588a72f00f15e1ea16d99961084542467b8f998c118fe76a2a326cb1ca3f9959c06c810a004a67cb0655f8c6202ff5e4ced43c4d8e0c3683d55607d4ddbcc0d9dd4e1783b58f51f95e159fe593066cec53b544f2391cbf0e3dc4172afd5ff6de23088404f7a496bbc6a4ce22826204b6aa
+SaltVal = aa10fec3f83b7a97e092877a5bf9081283f502a0a46b50e395ab983a49ac
+
+[mod = 3072]
+
+n = a7a1882a7fb896786034d07fb1b9f6327c27bdd7ce6fe39c285ae3b6c34259adc0dc4f7b9c7dec3ca4a20d3407339eedd7a12a421da18f5954673cac2ff059156ecc73c6861ec761e6a0f2a5a033a6768c6a42d8b459e1b4932349e84efd92df59b45935f3d0e30817c66201aa99d07ae36c5d74f408d69cc08f044151ff4960e531360cb19077833adf7bce77ecfaa133c0ccc63c93b856814569e0b9884ee554061b9a20ab46c38263c094dae791aa61a17f8d16f0e85b7e5ce3b067ece89e20bc4e8f1ae814b276d234e04f4e766f501da74ea7e3817c24ea35d016676cece652b823b051625573ca92757fc720d254ecf1dcbbfd21d98307561ecaab545480c7c52ad7e9fa6b597f5fe550559c2fe923205ac1761a99737ca02d7b19822e008a8969349c87fb874c81620e38f613c8521f0381fe5ba55b74827dad3e1cf2aa29c6933629f2b286ad11be88fa6436e7e3f64a75e3595290dc0d1cd5eee7aaac54959cc53bd5a934a365e72dd81a2bd4fb9a67821bffedf2ef2bd94913de8b
+
+e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001415a7
+d = 073a5fc4cd642f6113dffc4f84035cee3a2b8acc549703751a1d6a5eaa13487229a58ef7d7a522bb9f4f25510f1aa0f74c6a8fc8a5c5be8b91a674ede50e92f7e34a90a3c9da999fffb1d695e4588f451256c163484c151350cb9c7825a7d910845ee5cf826fecf9a7c0fbbbba22bb4a531c131d2e7761ba898f002ebef8ab87218511f81d3266e1ec07a7ca8622514c6dfdc86c67679a2c8f5f031de9a0c22b5a88060b46ee0c64d3b9af3c0a379bcd9c6a1b51cf6480456d3fd6def94cd2a6c171dd3f010e3c9d662bc857208248c94ebcb9fd997b9ff4a7e5fd95558569906525e741d78344f6f6cfdbd59d4faa52ee3fa964fb7cccb2d6be1935d211fe1498217716273939a946081fd8509913fd47747c5c2f03efd4d6fc9c6fcfd8402e9f40a0a5b3de3ca2b3c0fac9456938faa6cf2c20e3912e5981c9876d8ca1ff29b87a15eeae0ccce3f8a8f1e405091c083b98bcc5fe0d0deaae33c67c0394437f0eccb385b7efb17aeebba8afaecca30a2f63eac8f0ac8f1eacad85bbcaf3960b
+
+SHAAlg = SHA-224
+Msg = c8ed14895c80a91fda8367cf4aee386b8a378645f06afee72f7c94047fddc7aef84c26c83fef13bf65a3c7750c91967ecc02748fd574b933d5ec21c01c8f178afe6c3356789d0112178e04c3169cfabec6e2621b334f3c6705fc1099a4bd3147a0f7431a4fb1fb80b8ed26a0af38ed93428057d154260fe98854687661919e4e
+S = 27b4f0aa139565fbd7860760610f6866d5b5f0d777921f06f5053291123e3b259d67294ccb8c0d068b8dae360aad2cf7d07296b539e4d2e9b08c343286d522f7dd63c6620e8672be492f3b039f73d88ab9d22a5463cd1f07d688e8ba3fbad531b0c3870ccbfebb596ce4ec643d309744bdbd675d5841284cbac902cfb70ade6d33946d8dc6109bbbc42412db25b8c62222c5ff94f8eb868982265392a44e807474910b4b39558bbef33197907178ce146fdd7e94092ad58bf41a474e626136789fc2fe6374a1b5fefddd5fecb7f8ca5893220d1ab9e822c3ae8adda1ebaddb18a6a12bfc165d12071441a991377cee6dc8e50839497346fee13f12c5b7b6d024b8ecfdad80d5ef6e9e4996ac21c4eb6036bb51f5be5e38f265181154000824e3c1f231d18589ccdaee90fe307ba56324318b5358468e9f3913b83ab8b34d949629ed7839f8da85bdcda52f3da5a419f777b3860dbf2ffe28d96244312549528a20cc7399fc010844365806167fe43235521c909587c2c7b8db4e296dad2aefa2
+SaltVal = 3f805057471aab0a28cfc8430dabcf990612e8a908b158ae36b4ed53
+
+SHAAlg = SHA-224
+Msg = d04be758e97644ee60a9212e5eb81a1088041aab31e428b0cd4a8437a9a3f3bedafe576e747182a1fcb84ca21f20e3b3a3a463559f55a7c3e7ff5ec0cb096192019d444fdf092a57cd65de22fb76203c4fd33d8da246e3de2b7532993bc216d02b6fd5819306e419bdf8ff365a8478b173dad0dca281840881f6294b6396bb80
+S = 4aba732c6255f0bc443939c131dd4ce64478d4f58dcbf1d73f5f0e660c492315e987cafbc83a1a0be3d359a960783d293d375ccc3ec0d82c72abcacc339f1b42207a03795be6808ba06a891e3b4251e1b3001dfb537252572a33b4c52846dafefb24aca53fc08e63c39da02c4138b3de9510fb790f87566cd14380b138c728c243543b89d1f916ce27cada85fa32d8185deefa25c323c65c7ed578ca57276b66744a7a1a78e66d4e570999d17015bdbdd8d3d6185a3eb1dec8bc3a1287a2e235e4f116a8b91d06128d36b58ed4c9a6ed84773dc49f755e2e27a6f1aea31417069bd066b848095c002f22dd6caa72957e21a1e640f9ab9b9180df8ef8963e3611df2693a7ed064f348221e7edb1a5a81acce24acc335c6ee7d4f1af6d68acaf15d77e128142ca9bfc55a121b1b13fe5bafe2e4d6a5546b8cc631bb9d304c0e9f3d6d5dfe833c346965f0103698d34a51bca5db266afded271d8490645b3f63efc991e01683211f9482d214cfa9220f7bc81e8cbb4d118a2c306709807c070c60d
+SaltVal = 3f805057471aab0a28cfc8430dabcf990612e8a908b158ae36b4ed53
+
+SHAAlg = SHA-224
+Msg = 39d8ec4816fa9365cdf299ce60053b9c1e99540ed29d2d163a249718ba5337ee527e222fce8eaab13ca6774ca306d9e1f22f5c9b37479d7511c05dfd6835d4575b9447847a82dde536fbaffa95391e702bd8695b45377fc067211156f9adec8d3d6286d0849fd607a23a69619f68b350afdda3d564347afd2390dcacd5842799
+S = 0df81ec6e9c2f0ebe824c445009902cd55e2718523546f08ed13faf811ec4e57e6f5772037e07025c3c0c99cd9d6c885682e0eb904a3314b825948819acecd195c845a81e22ae62c13251823d6ee386e0be17a604bafc6497b7a6cdaad1a33cd5ae33bdd50e62063bddf6d12b878b31d3b7d490ce86810f9d456739bcebde592b07808350aee542455d1761154188e6e02cbda795e48e4f28acb819440bcd8da53fdf19808456898a18fba517af06b51156129b0b8029547ca9bd9436a0673e5b5cb995340fc425fecc566acc99884e0b4fc87248f5b35bbf08b0dfd0b9ead06737b67c85f94e1eac8802fea1b1dcea446b7cab8a45b25429750946bc8b22e076828a0a9718277568b9b7202a8cc3688d44194e834e0a405fb9eea46bc7e94255d600ff6c95a46ebf46449510fdb39b6ce05a20ac1832938b659318764dc0b7e4a0215fd253f5219296fbc82f03a7b95a12628d219093e2cdac42e20eba3dd5aeeb9dd7bef5d647f151b04ab85c48970cfe73ef9fc3e7d1d8a138dec3f5d5fb5
+SaltVal = 3f805057471aab0a28cfc8430dabcf990612e8a908b158ae36b4ed53
+
+SHAAlg = SHA-224
+Msg = f7b22de3bee8295c4d8c8a94da8cd704c5541c97214390bc6f5c75baac3f40458f57fa4e0c54e61f1cdc64a6c07d151143e7409cc05874a7e5576f0cf6a53faf1571a757c0cbc4bc9b5bf0e17053e7a374a22992cc6b9f014fb580598e6476b31168fda5e4340c5b5371f8eaf1f495e2dfee9e224a6357f136de704a7a622d76
+S = 727669abeb6bcc9502d7e88162f4a6c1dfe1a0f5141d3763e0f7e16744f9063874f153cc2de48784de84426b548b03e05a9074cef6a951640eaf9b32014d97cd9f3a828b45def13527f72a3e5e5adccaece82212c016c28f9f3312853bf52062e719081bc028f70831f9fc9132e8b63824e37c7cdeba463f9034d815683e27750cb9b383c3420f122a3b7fc6e9440925a77d766f93d586161e9607beb8a6e4ac72c32ef7b69ed52f5077a881dd0e494591e2ba552b74731c18cece9905561459f4553d49acfd6cc6be027833a220429d46bcb88dfcff0d2c5cb567371563b4852b7e628c4a6432af967e8ed69c9b6428ac552cd370922a0a4b01ef1bdfdcbc9088cdfb6d9fe326bd6b2bb1fc2acfea3bcf60d1fac5880b0510736b7e201ee8f6bc6332c0756315789700350fa549009d16e0bac084bf6aa3492f63367819506bf0c4f9c232fbd7c4d4ad663a7566108238c31fed887f368666dc75a623f222d357f8e523ff084111be4db6baf444f191ad1468d077349fef8a22f3fa56085975
+SaltVal = 3f805057471aab0a28cfc8430dabcf990612e8a908b158ae36b4ed53
+
+SHAAlg = SHA-224
+Msg = 8d48fddf28b05b42c9b4df4742ed8e735a140a6972165ca6696bf06ebea4e106f44478243bd1efa44c2b7a7c951c88f2962f450d8bc664494b671d8e70577163b86ab560ab194ee17ed5ba02389bd0c713c9489a25307dfb3f6a7273166d13c9a061be79c1af0262275ba7bf7393ee58998819fa897c2e240f1cf903f71150a0
+S = a1a4d16956d718830f625f06c42e99189e36a80523b25f0c9a7bb85568ce76d1e85e437db0a7728b8a9c90d25e6f38150208debe54e1e3f648ff01798a8ce132e4b33f3d26fa8963771440fdc4f5d852117b3ccea975da10e5d4f27af1bec1b853b7b5c9b420012317a6c33b2596dbdcebf97bef821b3076ce86345309b6bdf29a4acd391d3b2e5c4a6866136287d17cb0e2d4d6a6cf89d64272d5c01849ed57fa2842074d3b7734c4c92be50a922d0517ebb9891072b1b47a710887004b238f90079d10fb2cad7f5013e7243089f3c601865c6bce1cb8d0d669f2bb709253e3f1e421936f6a1643bbbb7d503b0631f7e1660382bacf4680de8d70e24abf4450510e6b40475bfc9fe547752d0d5f63f40f62f4dcc903fe6d260fa45a1b85a7501065aa1900a3f841e54c136d686fadbb33b225d15ae6fc348be57fc9ccbfdeb57d5cbf53e3479d9bae9f4ff859cbd3fb076073ca016ad94086700cc85aced83aebb4254b0cfc814585f930dc623c7f85e89de6a554b9898918d7cbb4cd2db075
+SaltVal = 3f805057471aab0a28cfc8430dabcf990612e8a908b158ae36b4ed53
+
+SHAAlg = SHA-224
+Msg = 4753183ce5607fa03636db2fdc84722aeb9d98a6ed70d0282aba3571267a189b6aa6eb65871c5dcc59dbc7db8973c7c355ba2a2e94c110d1f4064a4087eb07077e67b0f634fc10bc6ee9b8b8e1a0a20bf47a14f2c8aac75375704995978fa0b50a003096f1e8df99fdc8766eecf34a2a4f461d9991133fd5355ef8175f4c2bce
+S = 2e078b29b5288a77ed25ecececa645f6d9298e4294e3ef08173cc37ccbf727ac9b092cd27d6fbd378fff7b1061b56ed5cf077fd1a227771f58cbb2c1195a01f830f0366f989aa2d0c486d441e112daeaf83e85958f65a9e60a1937d2a7022781fcd1a83b3f7641a743001ebad53a4669405603ba0393bcd94f64324f1b777068a3ab101a086a6972b2c11376307e7d2485fbfad85be7171d20a5251cf9a5f004847d172c77bd80fbac0870a0b6bb9733537ca72bb6eac351c21588287c317625a25f416129e6f53c607ae08f43e5e0339740775a531c720f3f731840184ac7cd3b1f7bb820ff30ba7bb120b21b4bae7f9d7fc34d7418f700b142cf8fff43d81599236ebabe93d2e89f4702fada8742dc3bb4bc8fc5e55b4f874ae59f5dc9636868828efbe1025a8ca5c61ed8cc832686d5d00c08775590b316060285dc5bb9d32c90a474a727ddba9e7a8b7d69bae555604add9de0dab0eb0d551bac067c0088523d134b2e50dfe3ff73eefed934c0984aa4a5c563b862d46ed957ec3446fd24
+SaltVal = 3f805057471aab0a28cfc8430dabcf990612e8a908b158ae36b4ed53
+
+SHAAlg = SHA-224
+Msg = aad03f3aa4cbd236d30fcf239c40da68de8ef54dcb36f5a6f64b32b6acb6834e887c6a35423f8bccc80863f2904336262c0b49eb1fa85271ef562d717b48d0598fed81a9b672479d4f889e0ce3676e90b6133ee79cdea5990e2e02db7d806db4e6adee5ea76cecef9119e8393eb56beea52d3c08ebdfd7677d5a1bbc5b6543a7
+S = 1bc325412cc952a8dd6918db8fb08192cdf81bf4111cb5f0a580a82d4dd2e14d7445eb7cb94cca6da06d2b5cc43e6ec22a5c9c845d99ac0353050c1374866befd9b6b849cf3b0efcc644ce17cca0dafcf7700c9c7d870c1e14511651b1d03a535110139c53b55938cc4a471d756a55b50d1bd280c324ac4dbaf526590c48c197573f3a91c70373ec62bd168288b0d163a09e623589d1ca5a70d17aa54c8627c7a64d921aad12626f7d32d61e8f14d0aa97c2d6502021e70855581f5e353e27f96efe1bc78c7fbaece66a560b93c0e7365d97dc4c729235484abe10bccae99fa8db9425614b673d5bbc188ea8f465424f768d8031f7eefbb698f058e1578ac41426739410aa7eacf796f43a4e4b2b4a463984d3d17d6d667cd15bf2e2b487aec3493440794c09908545f416b701a130f08027b8bcab4dc4a78cf4a55a688b2e1ca3a73a08ff0ed890bee4a0fa858cf69142f2f765400e7c29c4b540530a054641961499c709dbb4f36e7e75a5993cb3ab8cd4c886f6a3f5e3bdd3d68ef0a77750
+SaltVal = 3f805057471aab0a28cfc8430dabcf990612e8a908b158ae36b4ed53
+
+SHAAlg = SHA-224
+Msg = c828eca460b39703696750999e23486a432d80000882d061316b2e3ef4512d6d22d2c49a0a1551399b5addbec8d5a21131bcca3cff9f7a670ff80f075403a85276cfe4f6bf95ed0a384ab5450f707f6e3c31a21364ae897efe95ffe5b4f1a9e10c47d42147de72608a5e5e943b9de869aeb58ded015a068d446a8540ddc63b02
+S = 799450a1256d245df0bb7d5290abcefe69d3b0e3b94924072f2d67d53a966513955fa7a01b830ba2cbbb056716fd605a0cfdc05f8ff58d88cb1bf32248f117de41ddfdc466215fa4e704096947a2dbe836a99071ea7344be0ffc782d14f995e4bfc74dc3ab1fa96d7223ec456497a2f51e1eb199f0464d415aef00f841e39f4578a0c26d726f3065ee687adbe40207801857160d440151fa374257eaa3f777337d129dc8b8c701eed56a276ec90c03df54305f300ef8c51155db30b68c0b06dae4c4aa07e75ef0fb09299b2b04d73d0b3e874ea1b6ac4e16f1bed0cd8dd3cf958a27e14e09705d4f0e10f8d46c75a195380126b437c68183e6bd39097e2f45b1184f519b2eb101110db74519016297683aca4b461cec1d92a7e68cbf30c2bb0d96c3b33dc62d278b9a640478258c3405a6ab5fcef5280408d4573b7ae42408b9c40483768f16a01c9ee4163b325bbb8e377034fd31c787cc0db8a53f6c0ce93e7d854411a136e1013d69fd03a0171176dc0712640ef2f792c340eedd0d07a8e6
+SaltVal = 3f805057471aab0a28cfc8430dabcf990612e8a908b158ae36b4ed53
+
+SHAAlg = SHA-224
+Msg = 87edd97182f322c24e937664c94443a25dd4ebe528fe0cdf5a3e050adfe4b6513f68870cc2fdab32d768a6cab6130ca3455d8c4538352e277de7d923d7351826c9aa1d2cb52b076c45cf60cf0af1eaa763839b9ea1a4e6ec68753cce5829d333ed5ca6b8a4a6bdd6606fae5a0b05641680eb1fd7a975bc97e49137f3ace86edf
+S = 9cba01f79f3551acfccf56e74428e270949f78a00b4ff3507ef180ce4c78ef4c53f3b7347ee37633c653aaeca834fc004385f87798922c53f8fd741cbce15de8dcae8bb04c7d481a823eadac7d4d4546fa4b0cc7e25e67b166edde4b6f66748017a4dcef85952cbf37e802fe534ecb984cb32f446c02ccb60e257a18ac368c2d2ed21975093499e35880930f8529790c1c7762ae11526e829dc0621ac904b822ba4815d8f83ac8f0fb0f8fc11bd33b02aff4e406f8fda5efabf39e6641a791cf8241b0946b675fa48d07e48639cc1ecf420380b8581a539a4de60adb0da22e10ad41f8ba6af40d11e2720086a63db72a5d7fbe97929ab23cae1d75c485d614ca38094baca699e47200f7a792292b5c7ab95b960d6921f8beab94d26f9629d8702c40df696787a6fb6ab9d6f3c1240c2fe58c565c9328dcab603897693d9dc7dcdaf500850711e6f30b5d8498a38e348469df79c3628fe1403a7649e82f06161e0ece42479a56eaa845f0582cbf817d4ba7dced36e93a6dc7dc7362f658f06461
+SaltVal = 3f805057471aab0a28cfc8430dabcf990612e8a908b158ae36b4ed53
+
+SHAAlg = SHA-224
+Msg = 02a1a65f8af90a298636fe8fd31164b6907d74c8d38a0ef59a8a4eb80572625cc28398bec829bb544823a06ee0e4fcbc13397811f62d08662b2a782213604899406ab9d2292f288d22079b848b209af2471f4052700a916948650e86739b870964a0312216d5f8dbfc2c16593a8ce55e1577f113a8ea5205d984396d8cebc8b4
+S = 740eeb1c71940ccbc041cf204469bd2d6a461558b1d15c9eb23361cd55e1ad418a7d2851ed3d44f9c02881a22f9e4be042d451998bc181887950da38246dc1656243db15fef359fe50d2af8711b3973a57763bfc3964cfe3c911b937572e639aee53a98752598c4b15dd53dd9355aee866d5f1e48137c12c342e8f274690b7b277acd087f293cb8b8c9a3e4b3f0277e831a6864e503f925557511e57b5285221421879696802066587ce6f993aacb70dafd39f63f09cb3dcc28e56782dbfb8b4ccb1b19876101573ee9678a5f6265f808f75e7711946c27c7a22dce9f592acddac81c67afa17bffb766058e2318a1211079842bd5fc58f9cef4b50ff0ee1a293f80ac1bf2eb64ce4e1051e1abe55ee067db6c24130f0bf4c134b0abf1e2f4465dc50fd3799f6dc206b9a7d2fe34b4f4257065d7494ae733c28d70aadb057ce1bcff36edf9f9ca6908cac2141845310660ab759d1f3e651dd9fa8056a624efc714f51f3a4f85adcba68f4a58e3a956af93a5a52f2b89f9c914b48e8dfb919cfc6
+SaltVal = 3f805057471aab0a28cfc8430dabcf990612e8a908b158ae36b4ed53
+
+SHAAlg = SHA-256
+Msg = c16499110ed577202aed2d3e4d51ded6c66373faef6533a860e1934c63484f87a8d9b92f3ac45197b2909710abba1daf759fe0510e9bd8dd4d73cec961f06ee07acd9d42c6d40dac9f430ef90374a7e944bde5220096737454f96b614d0f6cdd9f08ed529a4ad0e759cf3a023dc8a30b9a872974af9b2af6dc3d111d0feb7006
+S = 4335707da735cfd10411c9c048ca9b60bb46e2fe361e51fbe336f9508dc945afe075503d24f836610f2178996b52c411693052d5d7aed97654a40074ed20ed6689c0501b7fbac21dc46b665ac079760086414406cd66f8537d1ebf0dce4cf0c98d4c30c71da359e9cd401ff49718fdd4d0f99efe70ad8dd8ba1304cefb88f24b0eedf70116da15932c76f0069551a245b5fc3b91ec101f1d63b9853b598c6fa1c1acdbacf9626356c760119be0955644301896d9d0d3ea5e6443cb72ca29f4d45246d16d74d00568c219182feb191179e4593dc152c608fd80536329a533b3a631566814cd654f587c2d8ce696085e6ed1b0b0278e60a049ec7a399f94fccae6462371a69695ef525e00936fa7d9781f9ee289d4105ee827a27996583033cedb2f297e7b4926d906ce0d09d84128406ab33d7da0f8a1d4d2f666568686c394d139b0e5e99337758de85910a5fa25ca2aa6d8fb1c777244e7d98de4c79bbd426a5e6f657e37477e01247432f83797fbf31b50d02b83f69ded26d4945b2bc3f86e
+SaltVal = 3e07ade72a3f52530f53135a5d7d93217435ba001ea55a8f5d5d1304684874bc
+
+SHAAlg = SHA-256
+Msg = 60402ded89d0979afb49f8508eb978a841abc2aec59cacef40b31ad34bac1f2d3c166611abbed1e62f6b5fbb69cb53df44ae93ab7a724ea35bbee1beca74fc0188e00052b536ac8c933bf9cf8e42421a795aa81b1bc6b545eaad4024161390edc908c45aae1f71b4b0228e3104048d816917cba4ae7f2afe75e7fcad3873241a
+S = 5f183009708b379637dac2b14293709aa6d7e86c267a0b690a3c275031139891267c64e5edecdff14c2cc2f2d985b62f900aee6e04ca51a70a5f946463691cf16c2d45547c5374f15bdb8881641d3040ef57807532cf5b2ced07623d0f638b39ebc2f2ce283eea2247e1df3af5430554d1d4b88b7b21622993419971b7d0d5449122a10fc31b2ddcc53ff751ff4bf4d336fac667b646780272db89a3ea4226afa20877bfb86ba3ff4204e5cd56e13a1dc9d53f5c9465b97a182b2bf671512ef89e6c3969f97307a3e4beba39a78e0ad1bb9799cda92976ca39d99db4ac149c84bb9bc8997e8d5e056d67ca23fe4be28e66c4bc00a25d65bb9d7d623fea2d3b9cf859dfd9efa9e52268bfa297afb1cc2883db0c9c42fc04180e2ec6f49657c7008e4025061f896886613895a35bc2d3655a8f50a9fca2ac648f352eb06bfba2fc340aaeead4a8457c65e2e8fdba568c60a6d8d381f5d9caa30127771f4a94fdb8cde7be4fa7b4f89fe379dd3e1ca66ae1fdd63bebdc0015448e61ef1666594b8f
+SaltVal = 3e07ade72a3f52530f53135a5d7d93217435ba001ea55a8f5d5d1304684874bc
+
+SHAAlg = SHA-256
+Msg = 2f03701c2fe07d47f5fa2c83a8ea824f1d429ce4fa1df2671bfadd6234ca5775b8470249fa886dc693d2928603b2a3899b48062a9ae69e5196da4ceb1d87b5979dbb46a2813c76369da44bcecc6f20edd753a51099d027e1610712ad98cfb418a40643100b2522ffdc1760454b4c82e59b09827e4102177e462a3792edcada61
+S = 8291bc1be9c981663156ec80c1ed1675763de06199b9f2760caaed5207fb4b3d6037bd08462b100bb1767e3340105b1a68728bc45c7d6fd078dc1b5e7cbfa193006d52f67e77fcf809cf26172a46db384eaf552a5fb8e33840fa3ef3d6b20c7b46c32ef019e8d15dd38eab66f6e40399ad0bbb07f94b8c555196901c27e2d4573958f53060d800cfff40c602308044b75d6451801c688d276525c3fee17a6792882a074c8a41420109e2511418c9eeaf3ab47350dd8c2d3e066abeb7913e08f0a40abe71d397c3dddafc41fbd04cc8fa3b0641bf53a90031b61a2a9b63d8ed8aacc9b301593c9f425105498cc4f84627f4950758e01a291b9b1a33ba918aacc172b68c9fb2c767c65910816921281aa8e5482512cee686e51cabe88e18f923fde170a506ba3c340fd1d68261986347d30d124931db2ce17602150000b794c050e137f4ebd45cc41f70ef3df1656218ff76f2e75ad96e4167eed524fa2ed9fd1a0cf76926f382ffb16124dfc87bb1a4110928d5b1cd3b16204ceeeccb7db88fce
+SaltVal = 3e07ade72a3f52530f53135a5d7d93217435ba001ea55a8f5d5d1304684874bc
+
+SHAAlg = SHA-256
+Msg = af90f131f9fc13db0bcebfae4a2e90ad39dc533f34165e3262bc23ffe5b20450538669bf6a5210e1ffe4a583381d9333fb971903a68aa08901f14c2a71e8d1996e59889a36d7c20cc3ca5c26fbcd930128541a56a7926a8ae49a5ae786c4ef2de6527549c653ce6440c80b1ffc06391da65b7dc39ff4643bf3fe74bf8c0c0714
+S = 8c45e38eafaaf10a710e131bec63e51e67741774a9ddbfccdd131a123ae2a03067e7a6a92e653a25178bf527b93d6aa83fa366a2bd44896baa8b7f3f54830e4d9f5632c2d1bcae2aaae8c55782132aa7279cf1cbb6b7a81e4965ff84635c296c5ac206a04680e91e7b1ee7e5793701b1feb832250010d4ad4017c1608de8f405014ca73c39adae7c4adcbaee35fbbc71151cf955acecd8083677fe49ececcb62353c0a89c9dcb9c507979b56bfe060fec45567517c05f29e262df50767df7547630d8a7b32483b923bb1e3d510422dd4cc2d61a647e4f9636aa7587d4f8ed84b6174c1fdca9a217d9b907972a66c1f5a2ec2dadb60b93b515bf74072d315d17d54d57d721c8f4ce1a43eedf2025e51a48e9ea28160cf300d7a26010383c3280a186c44a53b7188e6caa364bf4dbe0baf4dcbe37d70e3a475cfdae339386558ccbc119873b1863975e2300ede1e420031b4cdac567e7b9c5d575c8bae27eebb37097050acdc87008ca2380f5631d190029a1d712acda147c5c4378cb6eac81731
+SaltVal = 3e07ade72a3f52530f53135a5d7d93217435ba001ea55a8f5d5d1304684874bc
+
+SHAAlg = SHA-256
+Msg = e57debad3563fa81f4b9819405e41f98a54096d44f6ed119dceb25f8efe7d7329054de70173deb344c59a710cce03b16af9d168f6745eaf0eb07f80916648e804941ce7e583ab0a8a43a4b51844850edeaa4d7c943135efa9e770e9411a2411c586c423fc00353c34483f5bff5c763079f7e60eba98132213d64efffa94af7ed
+S = 851dcd2d4e1d34dae0fd585af126be448d611acaeacfa34f1492aa7d1caff616707dc31b05186cdbef769479243afb341577803b579e105070ad5406a6744f56e55f569370b9fcf6ab10e1aa0383f9182d451afb41358a2f8c29d1a571e11c404e6870cbb04f6ef30414d9b6d7f1416bacab0184eebd8deae72f2a48bea3a7844a8bf472a5f8d349d5973ffde3b1c40623dbaabd6f681485a9691c9be12618bba393b396f41cfeb89e18e378c51f147c7b0ededbc403bb1306454848c9bdb89f947843d0aeaadcdf09bad99efb76e742322521929f034dadffa483958df58a71af7da45461fc408c7c45973fc60c37a6358743315169b3100d4cd54f810d6e0369b9847ee38795cfe58443019523c3c9003edec4cdaa70de31d00958653058d8509907a5149a9f81be0ed028724f7232b57f93dc62ccf093a2635ee1e5bfe6ca9ea017ffab79182eefff542d278c471e1a2b34231700423bd0e757f6a572a14a99c90329dd0701f347d8a679cff25fd6b0d380ee5dc330d6ff1b4b1a347fc98d
+SaltVal = 3e07ade72a3f52530f53135a5d7d93217435ba001ea55a8f5d5d1304684874bc
+
+SHAAlg = SHA-256
+Msg = 28db8ffa55e115df7f188d627cd291fdecfbeea1109e1155e0aabc2157f7fe2a1284611e190365d2fd972d2a23dc793a5f28d4aac4100f5fbb2eed57532220d5d8d774bfa7084b44400249c19dab50e6c3c3af15966a960af1e2cec1f697a694a35c31a5a6f8ae7b73e148f09347004a3f54e7a82db390a0aa4fc526e95d79af
+S = 72c5555111eaef954236163753674a6ff81f182cbb379bfc6b548a52f9a5f260a0ed58f562a6086cf5ed00ed30adb023e90076a8adfa17cfd7d74f1e7b1978b210da847eda6b49891e6bd3fc6cd4c87b9326e8481a16c66e40021e5f878c303d3d8532bd7d966513717d5499865b2d03e378e76f7940f0448ab4d112e3c52cb332d340af122de3ee849f2e2544a40691ddf701d902bfe629766b36d82449286fd03f75bb2632dd61d6b3c6ce1c9ea8e5aff92ad2ca95a950eecd998e495e90e1f0966f922b7fb3f03380385f3b143ac1960c3bb688adbfd91d8fe1a1c32160243d3bd231a31c95dd78b6648c1175fa9c3c1244b1fa34d7c6f3255853ebacf5b3ec19b864e0a4eaee63fd719c21a72fc25b30b03207cf2aa45fd15d7102e5bae90882d00a812959593031ea3a436898582cae5eded5c7ce43de3dcac30b8690631e8db9f7a0a7f3f67b7524db275aafe02448727ff629d13afa94801d37526fbd9176fc4c216211037f8ec26b4f2672975887d70bcdbeef1e6ae99edbfb6c9a9c
+SaltVal = 3e07ade72a3f52530f53135a5d7d93217435ba001ea55a8f5d5d1304684874bc
+
+SHAAlg = SHA-256
+Msg = 4839d71aabdad8b15d9f37c3d37a346758d8941b01c83909e460f589855ca0e691096865cf62698353787e7ff517561801a6ca98304f6d11d76065e75ff17a8ef5c86d9582798be4ded181424175721afac7477e6309476c14c5e750576ce3cbdc3d8db3ae68655b6674eb149fdeb1f3a903b4d5823feca1015722cd55140224
+S = 796ac3f6adf4eabcb7a528ca63a6168ca6d31d5e357ad7a3fd180334a90d22bab20b762d767a6e3077c2cc8732784e81330041dc79068d50753bd4109c9c6f9ba03b5ac44efbcc23ecda27948511645fa17897dad7c122957ae56bf4ffe3d7bef85010b33d3b91785b0427417d94b11f73fda90e6a8748e6acc1d2d582e8836bc7dbe196876a9545b2a3207c1d4ec28acf8fe6f24c240b56ab3b4e4313a3d951aa1a558230e5f1eaf38cd7fd9b393d58d359f58f4ae51dd3971b418c5b81d0707cd9e2c33a148e492e74bfdd565eba8b1f3935e37a9d1a8764cd30497066e3c4622611fc14c45bf46fc85b3ed3f6c9d4d65e9925fe4b85ed30ec35ffc69c5fdc2bfa35d1bbdcb20e399cf934fe938f4c5798cf091d51100b4db4be42e81901e5dc79a98074119b7980b02821f4c3ff8ea07a2fc09a701978364bbd00ce4c5e2e45629526e34a3652719d27a47371480daf52fa49844f6495f35e6f5e3116c00b27042b3cead283bfc577905f8be87f0d5daa13d1ca74203a9e0d9199e885f4fb
+SaltVal = 3e07ade72a3f52530f53135a5d7d93217435ba001ea55a8f5d5d1304684874bc
+
+SHAAlg = SHA-256
+Msg = c0b8b24f4b8e0bf29168ba73aa912c97121f7140f3259c40a72a6d6f78da2dfcabfcda00bea48459edaaf7b5fb5a9aed2e6d97959c393cd1a524a269c15e8c207cd09142be4f7e7d5016f6f19c735b8ab4c0f28e96954172af3cbcf29d65a161391b213dd5f7c006c294fe5016423718abffc8546ba373cdcb5a053196573564
+S = 8503b85dbd9eba8d6fc57c6ae2103a78df1fff3600585e3e18f6ba6436a3acaf8e49fd12dcbb37c25b4b765037f545c3da8c39ef6842bc9ec264af6f519272f3d8698ef2ceac55393baa9846a7961b738e41f6360053d866763c824bc5873da14a28eb47d68d67f0cad7880853aeb561045f757a31d9f5c756f54d793637d721c88fb1f60126d3d16478f1fc15e0c4edbb531c2ca2e2fd9e8dabe1df2c09fd55bbc724ebeba290a7646249cd779fa1a923909b29345e54a2e25dd935bf0612a5580018b233d765a6fae3b46ef51bd8325912f439a7dc40148fdb754e2d866f357b8f0ebff6f18a6504ba31d10fe45226c88c9207b9be3c63261d75270466b43c271f75b1ab3c1d6b5a00dda8457b4d5c2195f320b0bd545fdd0679c84483c14a46b4d43c8452879725aa91d01fcc2c3867391c72200ca5d628ed9b566389f02fe74ba2a428a7ba31c00ef6b8d38c6b82b7379d2feb11031848fec0fac5b6091eb7607138bf0b96c3d2c174b5713d0dc8470b532eee6ea0ca1e8ffa3b15cbe0bb
+SaltVal = 3e07ade72a3f52530f53135a5d7d93217435ba001ea55a8f5d5d1304684874bc
+
+SHAAlg = SHA-256
+Msg = 4935eaccd2af7c5b99405471bed9b21da8965004f5e6f2a6b7ed3ee2dd26cebcef4d845fff7c1d5edc94093f88de7a3aecf2bc3ecbd8c435f56e0b89bd099de7ac5f6c4377a5eb1c2ff4d801b8f159547cad4b4e60cad743f8e04627f61e1652e9354d8024710d1cfb2969be365a77f2bf8fa63b9e045257270a96c572ad6285
+S = 66d1cea94b9603efad92b6ca8a1fbe0c6c4b9dc60ec0ab2c33bb62d27a100e839378a39208715de2102eae384ca407e92787ce1118f91a0ca2640a5c93fdb78635bc91082c99968ceab289890b3ec210d6cc6f1cf7e0fbe2dae88155e88f2fb7b325ab5e529e4b63493e551c53ae38c3fbfae49810050a81cdcea627da21b63224612d4361b9df19761d6ead44488dcabb50127149f077c2963afc049ac8837ff2c29e6a35593e22531ecc2e9ef8bcbaae4349bd7227ff3e13b31bb929bbd49e50059f28fd9ffe8c296a056c2760e5f6d8dab43e9bd557793f0759ad8e08b5c3773a305a0d316ff9bd07b43106335942055adc461a4346f05ab455780f32027de8b8bb6d4845bb24d0c5a21c293d2b0740e8d06ef5fb9dbdacb4fa1c6225fd4e19dae69a8e2cbfdff1ef8b7f21804ead0a45274c735fccbfa1d60bf497a3aa931bebac2e0c8beda9af596dff0cbe11e8d4602d36b2f6c6f5bb80f12f4b9daf2c0748f591098ea63d3193f50a1f4737efacb62ea85fb6fb212b3ec8effe788e55
+SaltVal = 3e07ade72a3f52530f53135a5d7d93217435ba001ea55a8f5d5d1304684874bc
+
+SHAAlg = SHA-256
+Msg = 3b8a68da11b61b5fee1c2ca00a6aa35bbfdbdd42855b284320ec8d0c1848edcf6ac850427d8479eb57bcbe9a11771637886974bd561a5387014592cb717e8364a8183fd4ad463c89c980215ff629d867956ee5e75f71f7a19ea7bd589d7efb915d44dd9789448bc1ac32fdf7a2c911734db2dbc589a83c1a61dab6bd83907ede
+S = 790058355d7ab9eccb46ea12368f3be9cf6b895e1734eb20a13c749557b9fecf92b316870f0f765864b607439ee5f7e510e2c83b2756a0d9877b48e0cf257b13c997b9dc70421d2d87c9b9e5625c36a17e21e20ed389657a3e544c677464eefff08a9ee4adb091a9fbce7626cdc127b5cf817c2a5f069e32c720bc2041cd21a6bae816dbbbe28552d022b7b608fa99da4d217dae8a69f54004fa3c004d50540957648296e14cca729f791b38e3645204c2c6d4cb678b0db63a181b40cd9851be84629a068415d54cab5cb5244c8dac8dc9799a0df1b58cebfbcd8377a391778869dd275e0dc8305eb0351d81e3afa46719355eee4f90894f7fed662dd3b03270660adff637b91e18330a4f3a62c914f0d32b4eb6a30b79371ab55190578a1e7d43294bb0a721def7dae3e021981707930bd9b5cb58675851c83acf330c6ba3aecb3a890ad3c151a1e2b583a7dccbf204850daa9f4679e759ec056abef7ba4d6e0bdfa57a5c5afb6368b048a2b74e3530bfa8991c55de7cc8bbfa990d118ada80
+SaltVal = 3e07ade72a3f52530f53135a5d7d93217435ba001ea55a8f5d5d1304684874bc
+
+SHAAlg = SHA-384
+Msg = 9221f0fe9115843554d5685d9fe69dc49e95ceb5793986e428b8a10b894c01d6af8782fd7d952faf74c2b637ca3b19dabc19a7fe259b2b924eb363a908c5b368f8ab1b2333fc67c30b8ea56b2839dc5bdadefb14ada810bc3e92bac54e2ae1ca1594a4b9d8d19337be421f40e0674e0e9fedb43d3ae89e2ca05d90a68203f2c2
+S = 9687115be478e4b642cd369392b9dd0f3576e704af7218b1f94d7f8fe7f07073e3e8e1186fa768977d6b514e513459f2373df6ec52e3de9bd83fcc5cc3e6b97f8b3fb534163c64f5267620700e9d8c52b3df61a7c3748ef159d6b390895afa3af59109a5478d016d96c49f68dfc735ba2aafd5012c13515ed6644f0d4109c45556e14a3821e1aa24beb8a81a48da27f131de84f7ba51581d81b8ff31ba92b8a1fde867f07e32e6c2709253448174dd31324dbc32b05f07587f76a9997decb80f38d8c13d0f6eb3c10e3d96a2293f7464f1e04602ef6e84c2d0245d7db256a67d132a47cae9abe06b61a8968f50a1749995dc15ef0dcb1d5f5959e4d454c8547bbb4d195698f484617bfd122acaae2d0e8c76d28b24005ab03caa781ea97b1c4d9396a16f7998eee7ddd9de4cabe57032d9438a5d99c6b34a956122350263c7e998bc61dec91381012e686d079e39e96b1ea4bfdb7cdf630ddb422c6b580e5506c9cc3d6c100f2041d17ceaaaa54589249f04a1370ffa3bf3ff1adeb890688698
+SaltVal = 61a762f8968d5f367e2dbcacb4021653dc75437d9000e3169d943729703837a5cbf4de62bdedc95fd0d1004e84751452
+
+SHAAlg = SHA-384
+Msg = 752a9916f449aebf814ce59ca6e82fa8038e4685419241c1488c6659b2ff3f7b7f38f0900a79c77a3b57151aff613c16f5020ad96ba945db88268722ca584c09b4054a40c00901149bb392f0916cd4244699a5e6a8c37e9621f54b471166797a7b58502cff4083140827052646501f5b5f1bc0b4e129147d7cc157cf6e73ec58
+S = 6646a88ee4b845da4931274c23840dada6145fe0af954829d1d56661546a25e46316e216bb6b9446b368884ba14969a6f68ccbc1cf5b4e7a6d3aabec67f64963f63b088fa817c855d776ddcada57e5daa50fc1c877389c3cb9d99095a869a963bc91ec24b2422ef6b8dd18fd20d2b215fee6e98cda415ae44d2d2616fe1708292a3ef50a075170b3a7ebab02918ab0301794c17fb35e2038f369d94dd49569c066f7c392889dc4b878c50c7e52586b5081114d202338d23304f16f912d519a9ad21baff0e3d21761f373d08421e10108a983048fcb90eb2adc7c7f12ffa1571b091c781b255a77a880e97975f14f42baf5aa285ecc142157c3e1addd6aa0c09253a11c59144abd3b1e212d89e27ed96fb75756afc20ec67423b151194cb0b0648c659987a5583cb7757779d8a39e205e7101a5351ce1af2c9c6b0847cca57af52593323905e3d2297c0d54541a0125621640fe1deef13e759f8f6c56a2ec2a94831ac2c614b911e79edd542fef651f5a827f480575ae220c495f2a2842f99ec4
+SaltVal = 61a762f8968d5f367e2dbcacb4021653dc75437d9000e3169d943729703837a5cbf4de62bdedc95fd0d1004e84751452
+
+SHAAlg = SHA-384
+Msg = 0403ef219938b8cdbf85d3b88cbb9c60d174134e43a7284cd87936d37456cdc3c541b4566b682e575dfc7d8f883fa581b9df7257bc82bc1bc6a2ea2a109bb5e6c5022fac1e390306cb40fe2196cece8143a10af3ba1273c368ec7a30e27e021dcbef6609f9d2be41d3fa5e54fd90a0c83862e40b837ed4ac8600edcb31283bcf
+S = 0a217503fc4870481264d8308292c663476b25f8dec08ea1d1276f0951ec6df27aae3beb93d630bf8fac08b6cce50bd92994851b4f310fdddce8e0d6a8b7a1e866a567b298c5577dc50d8a906ab1be880084e681b26456279149b4b85201621c445de13d127fb77e7f236c39df34052b4629572abe1c02c09eb198188003dd852f88f4f767f1000458680258fa4b63dafc761822ca8b98c1a121b72b1455393bee416d24051290f02a28a7b49b18b30ccb29c26fbac991401a3a6fe01fcd0608920facae9d5bc56540c80f4740af02c9b7a078958a8d8a7a93a5e5b6d2571f49d775ef7c35a6d674290b52cfbcd67277e2b2e829ec437fb70e90537eaa6fe4548551939bfa98fc98e235b264aa6064a505a8d67946e2c33e5c6f0f34fa86ba65715c258f238b69e4f6e36d86a89822b4802d21ba0ba760b2f3a5bd061f50aaadff12e0d86627294bd0c4cd1085b5dab6a6ab30146c9bbb37de3ac5c4f8ee29736d46047e450cfdcb1279e4ca83ab69e858741bfd01a779d475dfc0f71c621d78
+SaltVal = 61a762f8968d5f367e2dbcacb4021653dc75437d9000e3169d943729703837a5cbf4de62bdedc95fd0d1004e84751452
+
+SHAAlg = SHA-384
+Msg = 453e0835fee7cde81f18c2b309b804c67b9fd9e96ef0a96e3da94b640978830e5cd1c8940c3d4af763f5334a7caf2d20f0b82541b3434fa138016b92dcf14638817a833d79b79bc7a71223a7e0144ed4977bb217ba8d4f07d7adcd38832c05b0fc61c39a0dfcca3f32971931fd8e6dc9b81107d44c77af8a62d5f9c0c7d0c75e
+S = 6ec22bd58c32d41374c017a77027e770f678fd81017e20cdaaab48a8324b050749e5d864082f1f77fecf67a59c2885e931c3c2f58130fa6806fe1ca899045114b09d09cf9c513ce1109d2210511a3b2e93af511badad2716f48555310e6c5f547afbdb0b9a684491ff3588df933d6b04dae8883f5f8aad62a4570646f72f3656c4a7085623f5152164a81a06ccb59ca478c5c2315414550b0ad8eecd0328b2db01fff7db0f26596c41f970d032925887f1c8a446da889be64d48925b9c6b79a3d897700ab40af20b451aaa6b427ed162864db89f7824b6ae9b475b5433b865335d6f91491c1e32f635cb930dec1aa3ee7ddaa08e8ebd67b6b11a46ba049922446fa69f1a804acc29f6cee487723f2e61a40007865d80cde0119f3fe6e161a339487f5789e1fd23ac0a63b4673969fd8722e3edc9439778928f09610cbefbb42fe6242c73b68d466cef889da156d9d4ff888362db4cf9a941e80f577c944b79fb27dbe0a6967e88f1f67b91b0d38e083fc0c0228cd49d27352521312163f90fba
+SaltVal = 61a762f8968d5f367e2dbcacb4021653dc75437d9000e3169d943729703837a5cbf4de62bdedc95fd0d1004e84751452
+
+SHAAlg = SHA-384
+Msg = 9aff46c14fd810a039c0a62eda403f5ca902ac41b8e225c6944748a36cb45f8a769ae2a18f713d362206d2af4a1742bf3b1de8e0de69a7fdbb72e66e1c6ed82a6f1f0138edf0f6677940643fcbfe5337cd76ac29456af902b5656dbe7f4c24944d36ab6db07dc39b081662c8a31dfb2c29b4ff04370ea43f4ac7e57adf77ca2e
+S = 62a505b3f3adda45c6badb61b464a28bc45d4c66159a34b63c1cce32604242eb8fcd9ac6929ec6ee4ac1144932d725cbf4638511464ec70dbb5543a4487a241396adb804c9794b271f9d35310ee560368d949a20a2b64cb4617fcf63cf7b60978cad734650dae86c7e51b766522ef0be48bceafe2030564d5b7b17ba125097bdafee48e4df60fbb7ac2d9f14af9a270c2b7ef18cadac45b9b54ef230794339d279d72ba48783bb09b1d1d5c1c65301276523fe90e63789ffbcd489e45f8aa9cf98f33de8f7d9c5cdd21a9ab2847896de6dce0b92f07b1ffb4230ee71ba1fe8048c22dd38af80f8762e747cdec6e99f1ce0d1c743ef98ddbaf7c764412446dca58e6ff5ac0dd13322649acbc96f1c5e0bc58d1a8211853a7d2f51538c5e5e803de0b13044608d6e650bace12945a7008194586e3b74809714b2a52e9f3824be41de9fec3f36175a289baf9fd68b7e92f3754e00b41782d055faa65433c25259aa653fda069386b083fb31aeec8e30c769553f8f0389b6e6d4b392cadd24ce3f74
+SaltVal = 61a762f8968d5f367e2dbcacb4021653dc75437d9000e3169d943729703837a5cbf4de62bdedc95fd0d1004e84751452
+
+SHAAlg = SHA-384
+Msg = b50bf2767250f14fa7b6f5ea21a54da8d01e91151eb491107fd88b2d4a5aa157c72d89ba896b87e0fe989819442bf0213e4aa7fde8d6b026e7a70ae965193a0e1bc7f8b8af96298c41f60d154164ba678333c903958d4ffb50b50f57ad8eedb6da61a6398ddbbf9c9955bba6bf5991c4c6615df1cde156d8e188003dcbc3a399
+S = 1f068bd083a26534040f41c1387e71a8c00370c5f1c958127e0bc721751b5940513023fad02a6101bbcefaaaaeea2875952bf859d494bfb23fd89149d91290359ecb44ecf2fcaa5775e2e61e5f8d5151343576fe9c7167e919a5d081dac6bb8117229c420fd2b0fcb521f4e72366bfb443e688a65fa392eaa5115c292ab05bb4db65468aab267178653dfa0a5efc960636fcce86433528dbce955a0b1aa188ac33ea128206ecc0feeab8f7df6f8c381b10489c8cfb2d02459e4cffc16f43a66aa4eaa19bc518ccfcf9fc1e4861cfa13e9b41fcefade2cd2ebc001ec8430a1cb949a0f2f876badc568c703e4209e7ca16f688ba9705c14fa1c882e6c4871b9deff31521d2d418e0342e189c40ed19c1b6f4320d89a36f78eca143d3c16dd3eb338c0743646fd314c725c2d36a13080bfcdeea0e431de71d61f652033a75424fe1e1586695c3dc463ad553c1cf3ab24a41ff4e031f9e0c2cb0024cef68273ea3b8c1be9d923d3e9c9686c41977ac7be94a6d23181936131c17a39a898c943dcc8b
+SaltVal = 61a762f8968d5f367e2dbcacb4021653dc75437d9000e3169d943729703837a5cbf4de62bdedc95fd0d1004e84751452
+
+SHAAlg = SHA-384
+Msg = 5ff000f84a951dbfdd635a4d9f1891e94fc2a6b11c245f26195b76ebebc2edcac412a2f896ce239a80dec3878d79ee509d49b97ea3cabd1a11f426739119071bf610f1337293c3e809e6c33e45b9ee0d2c508d486fe10985e43e00ba36b39845dc32143047ada5b260c482f931a03a26e21f499ae831ea7079822d4a43594951
+S = 18cb47bbf80bad51006424830412d281c66ae45c0b756d03e5d8d49f73037968d13df46ebebd9b5b4c58b164d91d0608e8ebe31d8644cb0bebfaa8e2ccaa1f5746ac8f3bc02ff6930e219f53fe13fc070f910ba1cff0617aea6eb312c1ef285869746673ac1348e89c3646f583d7633f5a2341626bc2e7e2087ff9d8f13d573dc6455dc0068c7ac6eaf5b3093b081614f7b252170c4893891e469121fda655a2a55d67f5df0ff6e29ce5f9b0c3a1a88342140ead748edeea9706d6570e900f1cf3a9adcd7ae64f207585417946b104b3990d1a2d950e0e6a5533d3cfc8c470250e4c797273210f248b8922ab00422f2ecf85aef73587e8c5cd1c2ee6ed9509508409673fe07ee2c462c52d091e7a795d8d3c55fdd5a710d5450695a5a31ed76f115e71a73c6757d2def7ef472571b0bdc7558c71eaefeddec946860b0c77936db31f2001d0499a381e5018870b41ba04c8d42ec0dc55c9fa2af237dc1c405dd8f555b07a237cc50cbce46c3016118cf4ea06c047599283ad4719d647a225206e
+SaltVal = 61a762f8968d5f367e2dbcacb4021653dc75437d9000e3169d943729703837a5cbf4de62bdedc95fd0d1004e84751452
+
+SHAAlg = SHA-384
+Msg = 531dc2b8566e01a8bfc580da607ec212fc1fbebd5a2590d897046f0ec069df20a1c2278ad70006642d9ba28625d7c1efd4473b68f38fb064346d762bd2fbd5376c2e77de13a31a32a29b88264d44c9f27d3a97b8dc4d1267ab85b5e05c6389575d6a98fc32dea5dbc6cc1a01034a42e1a000b8f63ae720a9a7511474872a6148
+S = 80baa663877615c2e7ca9dd89958a74e54012efad55ad05868dd74b0ce78a661e2b893c3ac1fd837f282327efe4b041220942649b5472c1ac702070787ae5549398a57653d5fca69cd5446d63f6e9d0684925a235acc96b8a10bdf14fbe209fcd4930b5945910d84b08867b2055fe8eb1d771b753759593b90d6aec5ef182cb33bf2fe29e8c67ea4e8433ecfa3f9ba4ce461f0ab19997f299e95409af97bf57e2de410ef7538f699f385c1abafdf9337f7f9d268da87b2b389131fe3dbefd8c67bd2a158cc4e04f9ab7fee2a58d74d063e6c16958a90574e3e4cb881d32c3116987e46bf5bd44f80abe6b9eb717a9fcd4c0cfe80dd2ca62c33b5dd3a59c64810073e0476085ec7b76638983291b69559c815cd3bb87d4b07e24c6b9ebb7028e800a04f09b110c167f6ee3a3bbb73695d89bee92407d4adcea3eaa47811e23f8c7f2fdfe891f8cfc071cb984a63846b95ec04d6261bb1c5980018feee15c4e7bf632dc8306128fa22c47decfd9e8b099554f17253635e6316712e0b95efa3fb00
+SaltVal = 61a762f8968d5f367e2dbcacb4021653dc75437d9000e3169d943729703837a5cbf4de62bdedc95fd0d1004e84751452
+
+SHAAlg = SHA-384
+Msg = a454391a7c3695486c337a41c2add417d8e9e9c6466d2ebb56ad5f97b9e7ce30784cfcd82d6066e372a3a1639a71a9369f2777435c87d100fc5e6638b3631a0bac639f36429b4594726613e5901816cf3a29f9228b96d66090844c7d0026d2e327e24ab924afda6554c2f74f0e69c2e8913798ec3a61e4e4fb6838ee08f89dc0
+S = 261180717edd905b647bc869f5259203811606221f545a3aee5fc123f297cf7d8a7ee6cee3dc8f97d24284ccdec2fd4680f1428ee75797e0379512aecb9fc1667523413e323c4bd7dded5caf9e5c606e5ee0c694d4d1b5a1f1cb613b980129f64146e42e8261c1f7ef5603954d34d56a50f7431beee5ab291a4759168655a5123640d596b744d97979d39f874ea7ff13a7466a7655d02edb492b58049f2208852297eb023e657f3240c5da9a99fd377728bff3cc073109c31712d94bc24e08c433533d4b86a73b58fbf2c598ccad78d46ca0a055601850960195aac1364dfaddbd06f14a78aac2ab4d374505cc61fc72c1050647d95a733517b709aed2d896721e7484208501480058fa4f6044302dd705c273fa7fb42eaeb02d025092b252e16d270d88dab6f68fd7ad571011f89627683e029d1bf1edc149d47452ebe87ec68679579940f5aec25999b0dedb820a5483ec6901abfee041c03b1a7f743548a2caabca613ff5d9f8fd7c694af12b29f2c2468eff55f9e008757443960fae459e
+SaltVal = 61a762f8968d5f367e2dbcacb4021653dc75437d9000e3169d943729703837a5cbf4de62bdedc95fd0d1004e84751452
+
+SHAAlg = SHA-384
+Msg = a05e5782a96ee6d6f10be8830d8c27c0acf272abbf77e684dd6a6c19e5398381e5d0400d3a21927cf904cb6e8e425c1ca3ece04544f25d6c40f0c640d24bc45c807db53044adf63fea835d8cb93a0a4e55f760ebe4594e247051d38d8c34c1413b0ec1d30d3a97888b2fa7c3d59db8c08ab9f985e8d4411635339be95d1b0299
+S = 87d80275df7b196b7e1d0a41147719d773edd80b5627301a500d91665ba86076e6a31c8f3ae86aedb643fe2af223976ea4eb3d4dca2cbcf81ffd14b7ef7de3ee355a8d0f4143e5b0f0a0950a42811102e602cd214e1c945c47e8b7b66d507103c3456f404f9c48aa7fe48dee0aad05e599f242adcf8ccb0cc9db3a6c244a913551ab595600ecfbb67c25a95b54f4054397abe47650e5c4991edaf1441ba9c8e3fbed904ffbc977142ebdc84769865a215158d5b052e75de318d75012172e28c31db2d8bd4edca787216dde2a7387c543f162fc91924918fd6c845bf1ebc0220a1027fb4227340ca4cb0f183e5b34b1e7f93e14fa57bb9d2d2ea53f86d838bcbe3f055b473b0b469afd2960c0d76ce2c30f3d49a3b29065bb9260248e728cbe328bdf502b109e1f20b9d037860cf9e261611b4cbf27ff9b5bf425b2612afc7cfa3138f78ad26077cbfb947fb2aae6f4be85ab2d1a15860839b822dd03a1a92a19a5c7244e98bdf561625ca2a8df410ff855752ebdf3d49f5eb98f228acdd52791
+SaltVal = 61a762f8968d5f367e2dbcacb4021653dc75437d9000e3169d943729703837a5cbf4de62bdedc95fd0d1004e84751452
+
+SHAAlg = SHA-512
+Msg = 44240ce519f00239bd66ba03c84d3160b1ce39e3932866e531a62b1c37cf4170c3dc4809236fb1ade181db49fc9c7ccd794b433d1ad0bc056e14738e0ae45c0e155972a40a989fa4b9bcdc308f11990818835fa2c256b47ee4173fb4fed22ccf4385d2dd54d593c74f0004df08134eb8965dd53a122317f59b95d6b69d017958
+S = 8f47abc2326e22cf62404508b442e81ad45afff7274096b9a13e478cdd0a72f99a76bf517f1bb0f872a523d8c588d4402569e948fd6a108ae1a45c65830828a10e94d432765314ba82ead310fc87ac99a5b39f30ab8820bf69e6934a9c1c915c19f36ea7717eaff7af67b4991315b1873ba929bedf18a975be808e7aa14a6726126c79cc93f69541c5cefdeb5b67ec279d8f5a446583e4b4faed1685140ee4b3b757c8ff4a1ef9cd76a88e05319ee62003d2d77290c94c579b0ca2ab0deb3176ef10a3fdb85c80ffbc9e2a665a23744fc836f9a9a103cd9fb756952356a2f1acdd68a645e20179006558b5d4d0b9b0bd3adf5e290f49dae60b9d19920953ea8bb237d5b3dcfe149a60f12a4ee3a889b33bcd3a3b753d610757cbcd093dd5a734255333689695ab636963e3d215a8e77ff31973718a4944a1e9e44f45754d39f6fa431c53f9a2ef36e16a5f70636eb5fba54e15c20a714f2809a7cff4b8dc1165f836607eb5a5a3bb0c4567eee26941fef46fb41e73b565c0cf8c72e404221264
+SaltVal = 2d0c49b20789f39502eefd092a2b6a9b2757c1456147569a685fca4492a8d5b0e6234308385d3d629644ca37e3399616c266f199b6521a9987b2be9ee783
+
+SHAAlg = SHA-512
+Msg = 06d5534b7769256e8cf65c6ce52a3e86965a1fd12c7582d2eb36824a5a9d7053029fbeac721d1b528613e050e912abd7d9f049912abeda338efa2f5213067777edd91b7576f5e6fa7398696599379ed75028cb8db69fa96de7dbc6de7ca128dd51ea334e8cd9cd8fdaefbf53fc825eae836b6c6cd70039a77e420d999b57caae
+S = 913fc118d5ac1edffb4b8fcfa4e85986b46231cef3dad911d5e9534cc88261f6b6969b75a3f25d83ece7ec2034b01d3b2be6c5bd958cc4afcd44839e3953f01e4a15ea5ef6e1b4b0e8ae90bdfd404199e8f86547f67ff6b84f2162c4311cc9eee06bfb2fe46198afb9745d9c443833bf2387eb92406a6339521396f2cbda55d98fe64074d2f2e27b8bc6a79be3d1cc568869b0b50fcbf702b0831668fbfdedc2d1b5491e8ec623edeb60ac870e6e8d058593fbbc938fbf741700efc2b2467e7eb254ae008509e91607f8e50aa16a4e851abca7c8d20c6ff61cfee6c1fb676098e5cdf127c9b79538fd1e6c014161054caf43b734fa69fe06a00d76f710acc198f3da906a7d2e73a2ca882526cc354dd7630a303d8f32c655b5b33cf78859beeaba3f9ae052c8d7471cd2bd9edf42fd8f70c3b0aa79c076928068ca9770959afa632ca6aaba6679e45d6888c50125a73b9deb00d42a125f25df5434beff0d5b0ee13a16b17045cece0f2da7577d79d7cd75a4b6c5bc345f460a173487b51bc6a6
+SaltVal = 2d0c49b20789f39502eefd092a2b6a9b2757c1456147569a685fca4492a8d5b0e6234308385d3d629644ca37e3399616c266f199b6521a9987b2be9ee783
+
+SHAAlg = SHA-512
+Msg = 756c51bae61d75e8cf44930e1781dd6b8db6bf8b1f68b4ca4c685d14dcb2d4eece953eba92149f36788df34769987af5d53253b6ec1b4cef117cf9b88bcd03e07ef6c3301ab40ff4133f54b8512ae550e88a931b4a5a7e88bc1e2bd806c7d6266fd709a5e8c56d2a88a3e1ea38fec984b006a842a2eef29b34961bfdb468f4ca
+S = 735186ebf08d505161a8bab36786138414bb5ca2f4025289af237a40f8d0963df9117b619f83d9a98dfcf74b8f001a4a742c85ae018c3b51f16eb5015ba7027cb9a0d0b9e6b65c08ba58b671a9b3dd62107bbd5ae932784d328cdb2e1a551eb67e9d33ff1cf9bffdb223afd75d3650459fdb58143cd4490981efb0b3fe36f642e1837a5d95c3d444af73729dd1a5e9937b8114a28e065d1081f061049e650e45ff5ccf75c246e2e9433b27e79a1b06f7b6b57f9b009e97168a61297cfd0a8156d026a6bf8c3764d0b715c619d856b061df35725498d86cec25f7e1da65b99d9ecbb9a1a6364252e4790d97ea0ffd6234b515929b5ef22676c243d386ebb90a22e67a0e1d1094dddf7721099868c31326814887b646ca52a2c4bcd43f7c71399e7d13e19de688ae5c20463df5965d8255a3e6928d614b601274b757cfacdd4002d9ba8b248ae700d8776475d79d0a55ed4241c9919a3c44dfb9a1f5d0fec7ca341774c596144c38174af59af6deb8937a7d14c459b5d768a977445dafee1a4eeb
+SaltVal = 2d0c49b20789f39502eefd092a2b6a9b2757c1456147569a685fca4492a8d5b0e6234308385d3d629644ca37e3399616c266f199b6521a9987b2be9ee783
+
+SHAAlg = SHA-512
+Msg = a9579cce619ebade345e105a9214b938a21f2b7191c4211b2b75d9d2a853805dc8f1eb8f225b876ab857938bd0ea8cc2ff1ee90087030976e3f46afb9f1b1bae6d3874dd769d0426ee7dcbdceb67a9ad770e1781e34b15a45f656328c88ff485c1b2a083056d195afc5b20178c94f94131761cbd50a52defc8502e22cbb6f42a
+S = 603ff63ff638f1ad410e266d82a04c6d475416a0470d97f483c0c99e8fc7212d61e02cc8b4493c9a9dac711d2a8edf196a26563866d68fb04849e82db0f9741f721f2ba4e9db62f6ecfe3b87ebe7feed0c9e2dd46c3f9252d4c122c6bf1bf4ce215ba82fe7c5a91249da70dd30fc9c8ac8b3bb2810b4ff38bfacc13fd41f6fa26507a055e0f1242f18ea8ed8a702d265f893cb4eb61a3dc8e18777157552a1c58db14349a0d0a2a900a0a1f4de863fbadb063ad2a9e526a0a8c3bdcfca5524c181637b1c4a574809fb45b2e4f06f3f89f4ccfb30217b32fc484bb908276d659a0d9a3e7e3fbd46565a0924f918b16b2d6527ec4b5d1d6ef6d6720f3e00485e87de61ed49ed13e85ca6a10d46d4ca4839f486621cca48a7f955a878c4785d55de96facbb91b6ea12e9e4fe4beed00141b0372a3812465e65030f4fb8ddd58701aa3da27d26feb8644f7c80b8ee2a3c3b20a516c7f0b068b503fbb65d3f3b84b253466a887314aa8eb9d85cd035bf8dbb178ebd8d5496fd1b68432457c78c69cad
+SaltVal = 2d0c49b20789f39502eefd092a2b6a9b2757c1456147569a685fca4492a8d5b0e6234308385d3d629644ca37e3399616c266f199b6521a9987b2be9ee783
+
+SHAAlg = SHA-512
+Msg = c3287c23b613aefc2425a8b8317d647a447816bac56d0c99259bd9711f5fb2b13eab18e8a0b3b81ff9e98f6cda2c51c4343c0c1118720884c0aef32dd3903ac9e5ebbadb3d7698fedcc56d79bb78a71453b32c2a62ce4000ed4da85581120f3abfd1aa2418c51840d4a18c0659ca2d11aac3bd2e2ee879b3b3604112b24df9ad
+S = 878b9a443921bc7d720e3e288e8f39e550113e01d04fb1635a26f796fb8b161d5b758cff914a2441d8350f8d3922aa5615edfd86501c9a05c210c93a1ae04ff761151dc8d652fb5509ed100999d2bf6e40b1bbb64cf6c5d8e067b445daf567137cb8f0863996de8de9a647f982c9e21a787ee8d72657a2dd42ec9fec49ea1c3345cf004e94594a064b6b6b222845d64c935b539d3fd2d535fe0e47ac6746028e748556c2d88e4d40707e74a1c0cad5cd95dad263efd3ca637ac6b8f78ddf7ba81e443b836d85a83dbe843bd6271e45d842e1bb241c9c18805f37bc19838ba2bc6cd38401dce0cc9780306ea8a87d43110b3e395bbfb81c3ba45ce1cd71596ed27c03e2090a7ee81f60119e187adff0d96acfbaac38f7cb503039ead9cf9550ded5693d3c257406dd0bc061d451bd81d64f969b7c2b84619f0dd82481781eaf5b8fc82a3ac5b9fc20b42f86d4225a435b903d2258f5cf693d1b5c6a5d144f7f4eab9e70de2f3879f68e4c1c7a38dda63e6186534fcd78d58db709bf57a78a848c
+SaltVal = 2d0c49b20789f39502eefd092a2b6a9b2757c1456147569a685fca4492a8d5b0e6234308385d3d629644ca37e3399616c266f199b6521a9987b2be9ee783
+
+SHAAlg = SHA-512
+Msg = d54c51f90b278c1c602bb54a23419a62c2e8527229352ed74a17eda6fde02f4b0b012d708515a6215b221d2d291b41cf54a9ad8d562ad16156fb3017fcf2cdf6832fdfa21015cc41429355dd0aa80e09bd2612c867b6f4aa631cf93828bc8492665dd157522ee6c53d06c7226cf0ea5a24e7eae904de7ffb9804aed22a453d69
+S = 265749f7afb1e1d16492eebcee9f5004234e1dcb95b832d14165992f4d1c49d518ba15a6b3adedfd803287cf60ce8c915882e2c78d69ffc46fdecef008e5d7f146e38f268efe49065ddb6fd7969a842189b9d7b3ccb32d62aa05e87e932930f7a1775c338736d9bc8f36521609d8be0c29fdd1728430a537f0a2b9b9fef2cd9f0946c221c08aaa0270e3187ee5c518cfeb00169e7718b01ac0faef097e9cb6a4df3e87a5548a6c3d9f1ba230ee1caa01297e5f17d1be1d776552f36638cff13ab73a1058fe7c1eee28c76a145e9ff9b17074963c22c6435b6c5a619a6f39df94ce348b244320b207a9117e98b9aa5a8c58516d39c71878c4ecfd741ce6e51222fcd92ad32d70c3b92cbbe301dacddf2ec3aec21fdd38a7e110f4f5448577b9546f1a7cd71a35670c1ca47a9199437cbbc65926cd17dddd2c0c3b1ffebe682be616e638839744a147ea897885afefbe6f0e37d4e482dd005f4ff199d0d033bb753380780c90228a87d14d8dbfb829a195b5d8b2dbd67c9eedac48ae639c158eb3
+SaltVal = 2d0c49b20789f39502eefd092a2b6a9b2757c1456147569a685fca4492a8d5b0e6234308385d3d629644ca37e3399616c266f199b6521a9987b2be9ee783
+
+SHAAlg = SHA-512
+Msg = 57724b7062193d22f2b6bfd18461d87af122c27bf06093a5dd9c1d92b95f123971706cbf634b0b911ecfa0af6937cb4b884b8092bad7afca065d249d3707acb426df79883742c7752692c011042c9dbb7c9a0f775b09ddf950fdceffef43c9e4fc283b72e7e8b9f99369e79d5b2998f4577536d1dbdd655a41e4e361e9fcb2f1
+S = 84a21a5cc060d141ba9caeca77fd04be8ba8270235e9948d0706dca77413ce7f0811da8b2f5372f8ff5a2eb2bbeae43752c5d1c1e3877992a49574899a6ec9d2a9483156540322fdaa66eec4a2601c281ea5ae996190853644b48231bc22729f32c2188e5f5f7b5056fd3e99ccca3effcb9793343f52a9ee60217d1c492102534a334c1c60a9c4ed63ae861bec7de9898c2dde026d9a029e7d9fe44d552cd3763b8ec3f4371f4e682315657d72a888913d15e1a84a981b3d8d437589a6deb37d14e86aaa365124bf165045040b1f959accff35565205d0ee72bc56d273d1973410774cea7735ca79c6bcb256b54fef0172e058ba91619c66bc45e11b6bcc0f68b529ec3a4133598bcf09c9c4bb0f874c7095f3ebbf85a5f669bb3717eef929fb1c22943268c310282e8842840aecfdc942a468045b02595bb16336634da20ca0b8d758cd30a2b7a0bd0e3e2a6f30f36a1422adfed88e211485066d6c0fa5c986f1dc5b4c1d965021dcc24b3f729f07c02b47af75d01f49da3dea0f1bdd6b4c0f
+SaltVal = 2d0c49b20789f39502eefd092a2b6a9b2757c1456147569a685fca4492a8d5b0e6234308385d3d629644ca37e3399616c266f199b6521a9987b2be9ee783
+
+SHAAlg = SHA-512
+Msg = bf5ff776122898e22333fb6da96d2a87a3e6c4e63f28fe7afbc8e8a40a3af2a3f9e9ae4f9287d70901a293f23579f55b890dc67da47b856a9d88ac44637e35ad5d375d7e4d77a8bc7a7f25c80edef3d5bd8b049fa731215b80ca2ee9ee6fb051326e8c6d0b9e11e3d7ef3957fc452cde868706b512f2da33eab4f7fc71b66a78
+S = 86ece9321faf1387de6afa7b1e16c2127e71e6472e093708f0ac4b40e6efb30eedc546907182798535ad6b88ae4a6f8c4fae429d225058294ef76d44ca81defdadd12cea16c58c660a4d158cb6728545307f5a6234c3aa16ae6d989b0b788cc4c18b08c89b57fe302ca6560affc57bd533bdec6ae90fc37167c4355b07c6c7c7aa2bdaf96002832d62c2dd090c61cb8658ecc0e224964b50b9abf1b4271869a8951d81cd5b46af4ead70b0454c01a7229ef2ff27599c7370e747988b45b9a8148575d73014166082947c97e8730d5458ff4a4606b1185f1bfd476e8fea2d1d7fb5d14a061f90e438ce5e36b489b5873b7400ed779ec82adfdc2d9314d6e6547dec3be9853359821e6f6d853c2292f1731789002033ecb46cfc3a7f197a18a677574fcf6870d7e47db874cff258f0f6589386fd9667af292c315ffd849bf71749ef1b4fc5a3fdf39e2782f986bc8f523162c0016c51702513ed17c8f68672cf425fd6ef8b6c8e983bd2128ce4614085e7fb216af7ff01501941f23ffbce556f14
+SaltVal = 2d0c49b20789f39502eefd092a2b6a9b2757c1456147569a685fca4492a8d5b0e6234308385d3d629644ca37e3399616c266f199b6521a9987b2be9ee783
+
+SHAAlg = SHA-512
+Msg = 61b6dd24903672621810cbe3342497a6b298b524f7cd50e342914f483596ecad9122a2b341094dd99ad98d4ee1546b040d233f06cfc8d10bd0d5be4b3a5b1d9179a663924327847dd5b25bd380ea4c7965f9280c7d845074dcdd1ebc367b8020a2a8e6689e7a5f755304fe1a1bcd832d418237dd08e71845ee13364231dd5d82
+S = 57d827593ad09f00005ff1ba4521a9ab2717fe34d7af12d7ef5dc07814cb93257a2903cedf0a80704b16fd8aa9dbd06fe3d96fcc7be3843ea161e80ca56f3ef6f760dfc7f1704ed4a50142267b87d244c71fc72102112fe4ea801c82c631edd9d917808c0a1f1c81a9de859dd87569898cba76b35702232aa492850739ec0371b0342318b92eefc45e6ae8547a604d9a15c2829ea85533d6d23fb61ef569be63779d3d2c7cd3bfbc26df02616b7bdbbc0b4e2b5ebba7ec93886a369d10b7bfc0e7f56e7b7ccc814880baa634f4afd874a841d40cdf9c8f117535650b55129b8913d53417bdaf163d68e7044ac011a55ac0e1afd9279d46d31ef83a0bb4a7dbe70bde4b33396750b676576497e202e40cd1401fd6cb08878a6c22db61404b4c2aa88072f7a4851d9faaf016a60a7a49147fc234ad67f8375a90069c274aaddaea43df6292ccdf7daab5f5113070f8ca5e7f43c791acc7e1737cbc311bd5714abb66561703b9ac3629bb10bd1b7709f081840eb3e939c69657ea8f7cfd596b0265
+SaltVal = 2d0c49b20789f39502eefd092a2b6a9b2757c1456147569a685fca4492a8d5b0e6234308385d3d629644ca37e3399616c266f199b6521a9987b2be9ee783
+
+SHAAlg = SHA-512
+Msg = dcc271b1bb2e50ebc23330be36539d50338baf2e9d7a969358c677e8bcbc7787433615c485c2bc2e670098128f4caa411b9d171392adc6ac1a5b297eec4d5b0f06d96cfd1f26f93fe08effad5147f0c3924307a2cb54d95765942e607b040e6c8b731f6372a22ea697a50b98668c9a5d004327e230b7fa1da23a2b964f29b826
+S = 0ac938ab04bf4efa587e34143436ce608ad089420956a72b23103fea769c03f02c3a0db764cd5bf3cc8518565b7efff70c74cc653665dc06e7f1d584e967ba193a70f5e3f7416ed0d4d5dc0e761b24ac8a8be172eb95691f02244379c9aeda8a9f760e061fd476b063b5ededa56bed819fb7136a4604879a92b2cd35507fd49b7d478fbd24c764aa5bc535a6abd7bff5c7692035620597f6329a454ce9188731c4e74d56c5bdef11372540b958cf2f8c42cbdbf915e0c07c77f04b05d876afbc3f2c205a4048826319184d650a243d192fbe35a163ab8ea84a001dd7c1472988a78042cf9fffd96f6948f0e692fc3f3b1c9c13de4b7a021be25c80606e1105cd56815d27c45fef995b1fea36e2e12aafc4a69924785c4855c50c61b1f43be9a1adfd8d7ff2ef5240dcfe5ea4613db4ad085bb0a6fb8627b1ed94dd164a4d9c4c9f375983734f9d2c35ec69d6d7421157d8658dcec1bf6599ea94280a63422376bfabf1b9f730292c498c953654401743c9e6bc499446759484d93e28d5f9f486
+SaltVal = 2d0c49b20789f39502eefd092a2b6a9b2757c1456147569a685fca4492a8d5b0e6234308385d3d629644ca37e3399616c266f199b6521a9987b2be9ee783
+
diff --git a/jdk/test/sun/security/rsa/pss/SigGenPSS_186-3_TruncatedSHAs.txt b/jdk/test/sun/security/rsa/pss/SigGenPSS_186-3_TruncatedSHAs.txt
new file mode 100644
index 0000000..7a2f601
--- /dev/null
+++ b/jdk/test/sun/security/rsa/pss/SigGenPSS_186-3_TruncatedSHAs.txt
@@ -0,0 +1,257 @@
+# CAVS 17.6
+# "FIPS186-4 - SigGen RSA PKCS#1 RSASSA-PSS" information for "testverforgen"
+# Combinations selected:Mod Size 2048 with SHA-512/224(Salt len: 0); SHA-512/256(Salt len: 0);; Mod Size 3072 with SHA-512/224(Salt len: 0); SHA-512/256(Salt len: 0);
+# Generated on Mon May 11 14:15:38 2015
+
+[mod = 2048]
+
+n = abf44a770836fee434fc7bf17b06428a7cb50d27213facac88fb38d3a29ee81669d18e71daa3c78fd89774a223e7a15df4216290c4fda8e15a00088d4071b682f3121c45e25d93b03b2332a9f1a0772018548302f60b2d366528b2364a8962c8bf0ab64e87e1d6ae13432038e3f9e9fd8eb37aef736a19987c259106f4cbbcc4ed6a4d679fa9422489092cc4f12b17d974fe799477995b8cfa3494bc5b426ec3b2d8c02373969630c003e08a42e5e62072dfcb1183ea5364513e6e357bd6c47d69c41767a304b7e7ba115f348963b49b02f34c87e17f5fdd29674dc125d333a4c0c6ba96a5b8afb4e4f785d2e9eecb0165e7f2bbb464e2a65f03baec25d7f519
+
+e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009b34af
+d = 1fd04b94cdfa3cdb225082a261b12b739ae7c359148acd5ac0899b54347eea93e1375aac688e3a2e6a40a4f4010126edf569a039566b315784bb6a3b3e370e89694f4e6d94608df9e1fc086eb9b3c283fcb7aaff7011e2d5a6f0aa56f2fd64d7dd75abce5e37247c6cccec7cb04e0b5e597020c7f63cce7dd7f84564a6c0fa8d73813d187878271d74cf8b696ff676204847cffa599f61cc3ae39fc1805be01fa2308011b7b1f1c39be87869b7faea7bf22d7fb2adffee26b364014554f6cf31e98d3fb68175731af23355048a22e9a3de432fe434f88cf0689aaba5aefbff08b9d996d92152a5bab5a650c73a1db065b8fcd4a9e260c69b7c806cadda8b0c4b
+
+SHAAlg = SHA-512/224
+Msg = 877b48928e3fae877f436179c74fd2a7fbb3e4f7be96f2e5e68b14bfda659e143e4dea6ad311582f98bf92f2367315d39a6ded38e466bfc280240d80924db6629879bcf04b8a4a3bc540f614e908437d00156a5da0b25a78d2d7fd9d73fabd21db27478dbd538e944eee1348aab7658d73d4e3cdbb22c9ed24ca6b804515bb3b
+S = a08596d43d483c01d959691c1b8d5bb22bb6e1bdb250a8a4d7d4c192e33389baf5328e84d8262115d5ed0eb1bfaa509285dcd17bb4da684e3fab339bf356d74a26e785e1c4e6b2b17518ed0fe796c86ed0b5be64b571f0abf19667e98656054edd3b1bd20c6aedb17b39aabfc5542673fb73bd9614ea37ac4dfd22dbdb1a55d3028984e65475d14caaf7088004555adc39b3cad91526b3812c943c2504bc9145b784f8ae534b6ac6d1395beaaa3d80467bf9b83ec0cd2edf31e50c582cd035b44215779393543e250dbf1c789e248bf980fe4ecfe23c84c78230db169a3b1f2959f63cc6a6950cbb30c91f7bd68fe8298c3c1619af9ee413169e5942626bfa92
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = 6c2cdf5fcbb2a735f76045a50c35cc43db0cb86be0c48085759d6f8844e5afbd02d5a7c65bb687de28472062e863fa916edfa090d7b23fb0bf586ff4b57851ceebc4da2a32206ead2607b13fa62b9ac7885cc9358aab1ac68bcf7a83fbc8f90c90c221933a3b862b5a689f432fd5d46d904dd865e1f9394e40cb363eff1ed0fd
+S = 2c9796e896b6a034ad2bd39ff85fbd2764280f38e4a4e7ea7e369ef65b5cc43226ec9615be328330b2e598ab6e407808c44cce49c89d02adef349af24ac5c279e1ea6eb5d7930a612559ec8607e159be5df95f6df6227a4d55a6b4e75be5b7ca59f93c7c93d2c1fa1f25c4acf8e55fc920d4e21b84ad71d4601e3cf68cbca1b41ecdd2b770134d336e6a9c02e4531fc4bf8bbfd157e1d50a633e0b22c49eba6dbfad2743d0f586d49c9cd74bbe725f6633fddfc73b06fdf4c8673d4c723e0d81e5578e186af059e1e62197e270f7fccd97506b5d9bcf9e17463efe6ac15e3f1b7fe2addb1dd49732575676bbeef8339ce96a8800657d1d7bf8adb9ce5ff380af
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = 64be9e2354f13bec61d7a59ac983318890be155dcf0764314fd840f1562b4b04c13d5e2e53927eb54d390bc33f513b0c1dccc7b09573e463a02a75cb58767f29093cdd3c8acc3563ce1d2a01b65ad325299e6c6b67fd4c1d9ac3179eaf00350963448315a1a7483c0b0c6a1cd7a7e21ddcbd6d54ecab84a7652a8f3203d156ea
+S = 57457c844156d5e608579f117e87f9721dfb86c72de9b464dff60201e81a5095b891e5c2d5cd1d902bb3b75881f930edbb3a955bc35a102202b6676637792d22135cc7bc67411258bc3a5a4d0bdd5bc2e2362e6bbef30cb40573e4cd404f374090a1b0417c9659244e33878f297006b3113635af5713f24d971f32fa2be633ee7bf12c4539ffede0026cbb9eeecc8312f375d1a4c8676cc51a9f26fbf64926adea4a1a3746a4276e5d4d2f282e81007ec0e498e54ffb2e7a318ab21f5a10d6c7f4d52c4723f22fc51ee4899221f7cab15477326bebfd031a771e937e3754be3695227ffed0f87677c0fce2fba40345b7f77c86ae04ec5cecb34bbc62112fd957
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = 40c62273c4b139e7807d1f987b9dc8c0da351bb9628a971039b83cdaeca3a94bb62f828400b414ad24ac3c4476af84b485a2902a9e2bb9a49267f74bb9e0040237b9be3f7e2cce19153787a397911079fee3c6982135dc737ca644433061d39e4acca04b4803ad55da84c95ee52cb436cd6285acf49249a47edded6a580e5e46
+S = 3e6a0621cfaa5ff9c896ded65fa0480a86cfd22c7367bb11721b912441eefcc4f43fd6c60bc519c72d2ae3ec7c945b15d0a664b6183224cf08d9a14b3b30fafbf7fa90a582f68fa428fd1cd6c3c76400a4c0a1a256616bcc3494b2d96354ce0e31d6421299cfe56a8764f0ba6f97f77f063c3feb66e0d3bc89d174bd039b239edd553be0c677d7cdd1b1245563453e619c4673f7480bdce096c4a7344e7ed335d284cee291798fba609e16a06133b63891ca9c293dcee039af1fafda36fdce52f10d24bbca8756659bdb1b09297c95561b94362f85898fcb9bd90496ce1ea4b0db316d0057ea12f770d2d61fa5a1ed01f517cb439d7a3cc5a70ff961e9d51231
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = ca89b42f3a534fb6dd079bd8a463b1581c512197f15f94abb26fb0b0d3af3c63f8cc85ed716300fc00b93018e3abca350ee81884b95d9b8f1af1f485747305d250d053f30a8aae89906515ac6764d481eff3ef0fe766c34e33a2eb81dd1a61c65bfee5ec10aea3841575103b3874156745dc6fdf8561561085eb5c4d188e9967
+S = 6c6b9d1a5aa486e6f9b9cc83edf8390bdb1e9086d3600698ad2c56980f249860e73975b51fadfe64f4383f99b545714da25b246b8feee234af16f43f7822fef569851817ad669ac75d311ed82aaf0d31987b885bacab8886e4f53da93fb208d94dd7767172e22ca9d1c9677f1484e21bb71bc6a01c1db8eb95f5b2ecf0624bbfa048141022a781e3959935290fd477d95c2999bd0dc08a92614f7eff0d11cf56afd3ff05646d47a00559238131099532b425fd44830ed2af8677e539a135dfaf8a0f86e9da0bd614a59a22a1c009d303d623fd178d935d9322f9840c9b58494c1e689237f81ceca727b09203b72f750da314c9bc583978c34010e9af7cd0aa5f
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = 847c8d5f082149677d5c0816e9ec20bc6e39e5ad1fdb1ce71260b3f4b64aaf12675865924007ed7e3157d47e51d211fc75cb3a8701e4f875fed3b9cd6d65a464dbc2d24536f4bb56dfa3ee390022067120b0d9c6f5f7f2ea79d9425c406c128d08433c4292f09b39b0c6c00fa0e4e661986f2832a21ef28caafcb66ad569e0d6
+S = 6e332aada45368149e434a5fd56aabd1034c2387d662b323c6d00919f90808b75d011a9418f8e876e1142008b2c637c94887cdd6d9341375934efa022cbd372a8573afbc2f221c2b25814de43708b9e3068f685f7a08c422bd65911f4609ee059f9e1e4a6658838192ffeb221d16a5bcb099d37d0032b04fafe84fd4e535153fcc980b4c2e8ce8473ad184191cdece6d8b3d06c88af24e80eabcac5c38ed36bd790d5cac562bb62b92f270d9c269c7f4a38b4db96b661733e5bcc0928184b6bef1b9d96de1dafbde41d481cf683fdf43f41793a54a82cfbfc9e17cf60e7d46d8c7323a1308aa4c1efd53e7ca9b6adce17612ce87872b11165122df1a18a92c5e
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = 32c9805889b6208134896c8e74cdd00d3511b4954046514db268c3adad615f894d2a464bde333a804c05b196da2628e3173cbaea0f76f1dabe28dc58cab5627e71b2d524bf48cb5e05da294588e880fb76349de91e235b4b5f65bcef61d8383984aa556b96bf78234952fb26e4de7f5b383f841bd61437a87f698afadc938ac2
+S = 28f10bb4f6f9bf3c5e33bdb9c0f48cf583bda58b2cecf1917ea450f59951da191e8f77a05929efa6c8eb324629a21e9e894ad9a45b48e967c7f2aed3a44bc68200535901ce342d36a2e1a8785c353119975ef38a0064877d3b67a220ac6ced595e1ff351902e065c65ec94238b4d5d18b9b4c146489b1ac2c2cc70c159dfff13d13b05254355af3381499c2b2072e20e6dfcaf3b89f46d0154cce353f4b5b1a51b0586417ef824d00090f9e71ea274a7e12073482f467c6e7d383d9ca027c0fbb51db4e0139227c2f6775132c4c75c9548f0f139c3473be03d35c8f3054b5920aedf7e9e0bd3b0d21d271ab77414b75f3ad11283a47a35a54392464e50053bc8
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = e631de1cbe356af118de8a7808be1c6c6f012bfccff362715dc2c7105884a6429a7bcaf26d98f3379f3f8533d94a7e3b2c50aa37ed271a4cc3a7d2b9feb1c2ff2a70f845e4df13faed8cfbbc7d9bcf79da0d1fd428435cca83bd8c954b2842d0bf98ceddce12b184294d54dc9db9f96fa0c1f1992a4d0f31c68c5e6be8f00ffd
+S = 1d2da7020c7f307dfc97d775ad8d1a218761fb9d55c632398a63ecb2eac7712899362dd8e373226ae0955c8d7a37ae75fe74bf42d8af0e6c4f61a532c1fbb9223b22cf2de1283a7b4f00cf2ee473f79de7b364327e3443dbbf2983312b5df9a2b64b9c8c1ba67b568ca24b37ebf695a1080b2f1c472bb965c3b49fae480486d5ad082b6c649241b9fbd031cc679ea683c446bd131c7060ee77140df1eb4fbc28948ac47f6f500f3d27c4aa76ae50c3ea8ae1f1dbfe8de2df42a93c112994264ba5e6a5c67aca13c485c326fadb4a44d35337916588bc57ec45908b5f27a0d05d8fe5b2fce109fc7e0e2b2eddd936bb4a116aa2ee6fb5ec2f39d476a0973e9add
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = 607889b7ba0071c5840960147da438d3ad0e51c754d41190203abd2ea2de8ec30399089af3a68769e3061bd3742295312fb3e29276df9800baa4cf06ef7a326f3d34564ff9284a48d38f6f06512f890c7c3717b3d96ae06f9a7fcf5516c800da77131bdeb2cee1e9bd6e04b4fc113cebfc61973163bc116527936423ff10218e
+S = 5c318b9e83c78bb1a3a26a3e6bbf619ca566ca0fbcffd4b382163c7deada6c095fbe3be8f7501e5b09b8ea4cd70b50d519b7d8572ce60e354d193ed584e499e4fdab6bc66e7c10faa8eb097a11c7c02180afec545a69e78b128441ff1fb3ca59258bd702b34a30e39a31bde69b50eb312f9aac82c8b5013a57edead1c4a8250158639d637b3ecde9c1764bae8177e596e8da98ba9bada550c7a59ea662f12de60dc965c9c08f85bfd179560e65c56394c98a0eb476e405539717ec667a0f29f0a63b57df171a60e76ffce83338d37b1234af79623654f911bf38df146b8efd8ef3e4d9e0303674cdde2be7f7a05ab67c4ff01492ec61c9cabf608070fd4b5542
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = 8dc8f2d43a54d5da6080bb26c0d59b2621cf91d4a3e2d4de50bbe804f4c815c22efa1730c8ca1726447adaa3b79d3970dbd9d1005fecfb9b81edffbcdfd484b78a3d4b9e5d691d668d8602468030b460e33753a3f7a35af02bf5d27bf0b0c675c918f6e8a13acfe2622c9bd5c396f63e62718185120fda24765ccb0ccf63c144
+S = 42b530b315fb5507cf9a361b45eb179442992c1e6b3df9c405c44fa8f07f6bdb12c7929f08308e65a1aa4a8ce69c72002144801c1cc50ff1b55418ad24a4c853fbc3faf025f6fb592c768eae48ddbfe1485904c87cdc5a0bc6e27cfd21a5bc482c2455fb32bac168de1104939ce006b3005dc4c99dc6e13a03b3eec838f3a7f4151b470212b45cf946338750554ac3ac553e3c0a746e3c435a05f44639f912177187fbbbab58ec8ae1f5d148d1a3b0f7946876f99b844e17377d62cd4c38e88ba387bcc92a72c855c5b827df8597c38e01d3ecf0ac4b51d5c1f54bc0a6e5a8f5765b6788bdf866e090512a16283dcb689169851d04fec33f890df7dae82ddaa2
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = b75c5176eb13776150b26d43a11b6120219154828312216f07e7bb98e779b6d3f16609cb75d412f66106dac8ab2d9b27ef807f1e5a8eabd5c6d37cc1268a101825c309880ab58d28df5591afd22858e4db5536559ffe9a4c95d04cff67d9f2079b9ad913725ef2de10ca1b5edeb4a03f2d39028f1c09f7bbbb06b1ba700e6388
+S = 83855773c5c8d64c4d84a92b82259da5bc6ad0a6a1cdc001bcda472b41a98841bc85ff46692c9556e51001a0d6566d7e48776166e2ed69ce386d96e544bd498d0f58ec68f1a5739db424b43e1aac84bff459528c0928a04eecd6e199bc568cf376d6abfac1eff0993404ba4a40c8a80cc55d068b6fe5a7709a9b39e60686098f3289623feff411fdf1b333ef66d1b40e44f1041a05a7c53ab88e4a95a78b24ed821f774f748b80cb9f782c8cfd33882347361843723acd1b2366480423dcb953d22ad1a30329e042ae0e9264464a281a51fad7b5466e94c3438cb675bbc5be781511dc512a8c155ed09bb8b6ef66db604618e83e718bfafcd5d882676afc273b
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = 6315b1755461ac2790fc33cc32a1e41a6bcc1b8727cdbb01ed1b2be007ec9e19e40298b4bac8ae806f9d8d05ba703dba868da77897b6552f6f767ad873b232aa4a810a91863ec3dc86db53359a772dd76933c2fb904248938c40ba3bdac5206d5c3910f4ffea75a39b5b8f461be03bd9dd6775f85c991b970c22f3f3854cf0c8
+S = 406231681c7ad1cf287f97daa602eca3547eb0e1ad196aa94c833fba93e95dcbe7f6fd71158940d4c1df03d86cb44ce4746c333444c385110dc431c9006140274ab49d66789a87507b025511d166bd9c42f20f62a407cbe473c7da815ff282d5d727898dac2e8ef735e1720dbdffac02e7956ddde13e355211c5922daaff52ab95c40cec6a4b3de46087319dc62354e156834d0b8431026b8607e079714ffeb9397706449900908adb26de948ad1960915b2fe26b47747a7bf034bedfdcb37fc57938c2f40a9de9683e78906da005c305acea3f6c1a186fba5bd36508cf0976d45204c3a2d90bb2f14f7b5d441d372b2e1c65ff9e774f01adc72f392c989d40d
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = 4088572485b70f746faf4998c4a7b79057bd4999413196fe6fd17d315db40c1a202ba0afaaf54ec54ab28225729ae6e3bd6f86eb30b031ddc110221b1527e0208e6662138550779bd4e765f69865d045352dde2a9a019995c67595db8aa4d2099121e3779f3150a016373a30be6f3d5fc5df9b7e058b96cf86e91d9a4494ab7d
+S = 27572f4dc4785c626fa30adf0fc67202babb69fa731378e9aa30072fa70c9d5cc54494136d394e57bd380c5503debd0d041030617c9f3cb45915e6037c183699c708f24dc1c34de0b0d3395ec4f7f23d959e2a6536824bb6457e7bfaf9006ae23970b0b5b356204fdec8a134c15dab604edb79f91c9c676500a11c62deab67953d4fc01f633d7c159927ca44da0a41c748cd7871395e60028366e69257adfeb4f079a4f11903d1c46a4387bd29f3c4f2b135bf1f683c2d1dc62761d65c84a0d914bf22a0af025810ea9f75e0a50c6c1df1cc07212df625bc6f4ae70754dbaf7a6a41a46b8c2318260ef098220517b9cbadba89f918c895f52f48bf146aa3e177
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = 29bcd97286a17dced9b367f4039f9f977d507790470f1f2521ef748cfe6819abb642c922fbb4eb8b8ece6700b214b9dee26c44c9bf3ae8f14cc9d6935deda3c24de69c67f0885a87c89996c47c7b3e27850ac71c2bc8c6beb038ba55cb872c1d5871fb4a4d63f148f0dd9947471b55f7d0f4ab907302e016b503c8db2e7fdc45
+S = 84183b2f03a27954833e90ccd8ce5dacf6d1b68fbc87862f48b113dd1e50c395ac3c86eeaa0a8b0c6909f47eb798987b24a69b3c1b114652c5fec23584db9dd5eaae0ea8ff9498c6942b7ecb51bb0969710b3a47b9e41380826d54668bc8eaf5da5c46c836689a950630df22adc5eb6f6a3acba79e5c11bef042070ce695ad92e9a45f9c831d237e439d284f7f62d52902a995651c3c0fa8729d7954c937eff7c77d106536b2042e2d6ce7840b1d1e0772b9fa5f23d1450133b11729e1478d20e5fbf1f38a3c95d938bdca362ce947d2aab1b9ecfcd4fc8876434c1bf845e810aeb0b1d9117376f0b93d35084bd435701b70fdfc6930d754a1f7b1e120750e56
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = 6259622d0aea50b8a69ee33aae19f7ad84469d7258a91b4249f13467cccda92c5201ff9225b98344931d8ccd4f25000914af19d98bcf691b6f661cdaeff67ec154b4bdd6e3dfef6505515639a554e312dab6fa54c62075fdbea3ebd9aa9432f9af9a22610c059c014261cbe7784baab21d84c74acf4446ce7cd128cec74fcebb
+S = 0bb0c8cf7aa68abe7d1f3f65166bbd110b8d371f859312afed10241fe007a7cb977d01275d512a97d70d9b114b082e61516043b1958ab759bd86e0efc52b13b6c449c3fd4fd122737ad0d51244a83ddc7d4da6f66a6c56fc5e724c264ef627717ca28439ea8fe9b444d56ef096010142e21b910c10d0ad662cbe45b71c550783d0216ded08bb6dc5aa238023d953d7b6eaa5943452561e48dcd340ff41e989f19a76c99f0f3ee2bd1951e5623c9fdd32373982c1da91bab73833516b51107a13b2e8908465d9c1a91d3cdda4f9ccce1db3fa6b6a7ac23eeaa4c95f77ccab558377331420075bf1d1946abe139331a0818aecb32a6cf9e65ba8979bb5627d22c5
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = 356a946ad7f0f8997ea518b8e36d19e7f97f253cd1bc6cb5ba3e6971ac336720e7ec43b9d731736b3bd847d586966f798514be6e43452e562af823906aa9f4af9f9da72aae2efc54ef63ae8f92c3f5bd3b6b4ff8f05f8083351ed7007579b4e3a4a44726238e9a3fe46ed24fce9eb29c63ad6041a0b06c2424d80e29954aafa5
+S = a995981fc9e3022e31e8f1e951ff4e1597bb614789a40dec0347f17ce3511df0882b60becadbb34d7ab3ed74f58dc539bbe5910b9060facbdc815859b2f6fe8069b710b1919913bc143081ffeb7af33a50858bcb0e985660f5e9fac4fa9c39afa76e7a57a160f1cf8143cc09d8758109635588469aaf0ef3cfaba3e815b2712e9ec1b6acc0e0c887187414b70fa546df49eb45f4ae9ca1743311b4d4f11d22d3934f1a3a11aa700f7b99b517586ca1d7c1f4e2e44a75a4c1b9c864d9b0a176c7ef08ffd1f4e10c9f9c8efa926605b15dd110a6d6c83b75ea445c07b5756289e69d0daf9478f468ab3de45b1e5151ad7c0afdda46bd55e8cd92c25c8e9e43691a
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = abd35f9e6bd9bc82151b770a8dbbbffb9a37a672f433d4c79e7978b6753e85c10aa71ad0ad8b411bca7bdd4979ffded95023b7c27b3212560fc2c26c9cf0f9be02edbb9085ba9293232f840824424228f486a2c42ef24f29f9e4bf46976566113baf2a261bed16b1c741528fb90b53b02d694fc033faf40602e8598c8f253580
+S = 63271499bfb0661dc5b28e39e19a7c1dd03f740ec9af3babaf739b2650af5eb876665cf7fa2c684eff47dcc1536d4f74040abd27380462886f1d558e92fc8760ae05f99db35705051f9ec765440a43c429d2064c8e51e23fc35432de3f0b5f4b712d2d6f06e0f73e5165df0ef27f5326f88732ed215e291dac2eb511190a8d14a8fff9ba10e69e4d2d3064746b8b8674b75048f54859eca43a62988f003f49ae87d36bf4404fa7cef5d30416f254fb044b420f949fb189dc431f3e43887fad4896956f5e16faeb67264cb02e29b3317abbe9312ec25bd2fa06e84178a39fa541e3510d28f35f90a206ba4734afa349528f2eb24c213699ff9953ff0b5cc7ad6f
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = 1fba005c70aace58878615351e7472e6f0939b1f6ddeaa5db354b826ba56ae92ce50580a439bbb5064a2a9bfac4492d5397a9dee7d3af752379b6b72a139346febdb0fdce95394c509a6c5f0876de862e47b922594c00549f76dbb298a5943f05fa44c5bca9a00c05eda934f17b71b98d9dea24d19397949da14d0d2dc7f841b
+S = 248bea977c17b32876452b645309dc7bf989cf60090de1451e9776d09107eaa4c29897ed6c45e74a0042e8d82846e3ea15a3c09c1bd4b9a7c0a482ccfac324aeab4e209ac3738801084b8706f603413bbf5bf7fc10aeaf2f690792a27e47462f842a2213bdd46e2f006489d6f7f030daf32b0bab6f7c15854ab95870620b289a170ad4d8922b263f82e47e4f06c51af2b021eaf0448a7b3ecb731ea94a0822945868229b8e2a1981d81aac6315b2de197e2963f349ba5cea98147eecb3a8673250366038b5b73b2c43f589e08bad52ea817ab7e5c888e4dc41dd484b3d7439f53657749c5f12fd443ff863c11dbb9ac11aa0f475da16d76918affa68452a0732
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = 73228209ad875ca1b92e458b47d68f24594f5e4e52395d5b500eaf2ebc63299c206abe1838bc3a904b553492bbe03db3dc365e310221c2d7de65af210a01bba1e2b23ca196b9000a7dde3e85acb5cddfc82094b218154242dea13fa5e82de2276201e4ecee0614d7f7d04dab41dba570c515e819bd9d4563fbcb46007e7006f5
+S = 96db5837e5644d02af09f74a91e12d9aec84f68e7c2f5b3228ec17e00ee25806ccf7f705b5c82166d8a043c8a4110fd289210a559e93b8ad9839bcbf18a3a79767d3617729d8c318d7e2019a330d7816a8e6cd637819aa7ace36df615853ff90253cad34d7b8aeaf86208e6154c8c691632982096d380631693dcae3492eaa6ff8ffc3454f3602bca6ec93cf3d56d338b7f1ae45d9afd12d1c0338fa73694a61c3c2b019bf444cdea8eac94245b089cf9caa8aa6fae776d43941a143532fde33348818b620bc1bea4e791909d7b64f44474a0c1c20c9ef4d0c467d4f9371927e2c8d2bba4cd8618fccf5f91bbba1336ce49b2f5de13b8f4d792d70a070b306ff
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = 09d1932d2a8376d487b833ca5f43a09ed741b379414eebf79df9eb356075692c7591463d82e9fe0c6c5e43921dc5e56e85dcf57cde822aa93527830626812e1be780a97d888527a378cf35f54c359d26bc1b8bc4ee9fee0df8132105a0b0cbc565880416c4bdb93eb4f1511a73fd906d84e6bc78f90dffcbeea50d5a566a06d3
+S = 78248f02a777283a462dc6fcf94d7f0b0c4e6f10622af034f38f326469e0ad1bd8efc22bb441f9e7a8cda25c851a7aa6d690819cc6ff163fa3c0ebd583392256621a21dc8bbc193060b51eb194f8295438b10f0bf774f2eb48d030b6b6206cbe791698e89c71da2ba3c05b78996709904b3288fc6e2d5bb5929eab74e9b028092b45dd4acf11edfdf49aa8259c9a639868b70f0273c69991ca088855b3d1c7fb534d54bf8e507a33966b0185b0bd5204592515fd402da922ba68a6834e4b7176df5eb3114efa32dc5d328480b2cd0c018c783be87b267ff2c595a0392a6d920b023c21620aa58ebae4b0cff347ddf08418189cd16047a80dca087c8e0abe2907
+SaltVal = 00
+
+
+[mod = 3072]
+
+n = a9d6499f2f8bd5c848194a6b444ea48700b13a1988753cbd187d6e5ad8b99347a27a0f0c3bdc038e74b8dab1a958fb1988377de00e4a1c8b9fde61df9cbf6c6df20c57d1ebb99988208784cb2ccf067e4c1bd269f74d8b897896aaf7e4901b7861143440f054c7f53f0e3a29248677d707e4624e4e2c5d075b98bf0a18be780905a1588aa3440ce2d5760ecc767b1c43cbd00924428478923fbe6f4602fce36184d21fb895b04e6a8cde5f0b8798110cb0497155be5336b9fbc0529ab9980c85ba0edcb4af2dbc7cd268b2f699d15f2a7e91510fd782c581672dfc1d1ca8e798f70ee56080db77470118cfc398efa728471e5c4ffdadddfb3232251e1bf61e295acf80d874ccc2ec052ac1806276f98eaf25d2f9156853ea3f27a3f0ad6b9cff46b0deed82fd9f5175b6f845768b45881fb5e584129033161232a4da5375a719729c8f427390c2859997a5ac21bfc7c4cb3c433d29265a19399868a8c16744bbb5e44350c8b2b3acf766966ee04e91db3b564081d7b456d9d78d46ac438577bb
+
+e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fdecf
+d = 18402aa33d47f27bd0a21ff764132aa93da95e75e6d5fcd038b0bc89c94ca0fc65ff7d4145d50dec72d0a6d4a2ab331b5cdef5977db2251bd3ab0da528193f5c47afd4432525d075866c1543489a925352d97e91af471bb918176f9f4c6ff91d98560b073df25ccb850fb6bf6a1cfebb895e11e500f51cd55e3ff85203e753be3797fadba4e710ac1838fc1917ac12b4a8d01acf9d9fb1092f95ea861288ca4b618793754d2ecbec3d165e08133bf61e12ce799d5757811cc9fe1b2e63c9fd19b4f11390f8dcdc85667239cb77627e9307054a65a2dcd5411ea468adc6602eb9e71892c4a32fa1f353dd3c9559d2bf2f5f3731045745879e1b5a4de46c5aea1380016823eb48e4e2e0f5845407f03c2c34ec6cd09604d87c36f31c2f09b194f77ac27b56dce1bc582c55c439897876f49e8da0f6f15fd355e05e2254cc67c34671182622424dac86f680f08eb326a146e494d127168c4ff0b223c12cf761cf1ad2ed6cc5def7ff28b912b8a2cd313083950284bd7170839a4828f672ef22efdf
+
+SHAAlg = SHA-512/224
+Msg = c642a5a32850266844f96a1800a11c42fe728f80c1f0ffab11d41a4ba017be51ed4d050969347f4ad98dbef0fb2a188b6c49a859c920967214b998435a00b93d931b5acecaf976917e2e2ac247fe74f4bdb73b0695458f530d0033298bc8587d8054acdc93c793a5fc84b4762d44b8e4b8664e6f6d8673b4c250f0e579962477
+S = 341bec7948589d9deb40c0a65d17864229a7d221243883d1b10aff74181ff0a07db7d74e0b99203e668cacbb89b184e7e613e1129f6b61f7487beba7f1a9d5db81457c8c6269f2fc35972554dea977a73b42e6e9ed880bae8c66190bdf8937f1084a15c2a14f78784836ff566dd83533147c85773a10324a39d19e91abdc172542aa24b92ee09bb72d3ffb446ebd9ff61503e9629f09af6bd0903d484a6d8fef4b85759c932b67ac36bf65a691d42ef422e3e350e5779fa8e717641d8181a2543f7cb8162d41812b5560b8e178086666bdc7f9d3797959731718e8c9808967ca61d1657f07a28e523caef586c1894f66482b4d2f7c31a5247f0cbc4587b3c1aeeb9b32cc9f5d9907c47067a69aa0e1ba174c46ac15c1687f12287899413ab549f48a590c50a69bcab9498b0e48e220d5137efb4fbcf8b511ba9c20d8c5ebbe41459375956236bc87b208c10df1caa3f5ec349185bf4e89b6edddb6467056e197679390598abf8ef0ab98a5f2ecb6361cb895c6b9fd0ebf28eea48ffc5f2ae034
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = 0de36b28a6f8ce5e2b3cce3560ad862b5c5bd37ef61263f07b390fc7a2fa6b19c1a49b46404d68c64ebb9325d485684ba7759701023140b1331a4d6d94750433bdc9dc70f88790c2f6f07302c0340382efd7c09320593f4ba3167a85736b6a286b1ad8adb6f070db88a517d50b037e579d4af73d38d4884531f53e152625c480
+S = 9f4647d2c195b9d468bcfef71577ce312ea4249f9f97cbe11b45951b55d0f7a3ec7911a6a82b3b365c8b63b9567b8180a434d652ccb9397002e9016ca4e4565b60e960a5bfe5f861627879a2864cb4f27b377fe3b42540fb71a4b385e69f089bfa3da3eae608329a533bfd8822a0c2e33c9d4372ee0fa6b72820cfe700e68f7cd3c30ea5380269384fb01628d83a56452fd94cae62a17294dc42dd25fc83250e0f90e1c0693d7e95270c220cc206d68ce8f01127b9be0f05fe51f2dc1191887367c880bda23bf815b980074a4427e9bb587b771dc782eebb805cb5d3cbce4b4e0fde6f79f4770e911aaa7fd07b5a2d52ea1b7a2258d1dbdeb5b59915a55e859657604d4367d68a20d8c6fb2f26ce98b4e8695b9da0ed2473aecf6a118e5781bcb189542b77705a37155cdde702fbaa04ee8bb687c3995c0bf7e3a350c0acba2862e6b41d7edff4747d0d52e7645f3731ac4fbe32ca97ab76956190314ad86c83f04feb36e1ad5f73fa1fc291ecca8458d725d61ad0e0203292e3c08753b09ea6
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = 15984a7560c9bc4d8e5deb3e807cee541d42022ba5c27b10424b0163e1eaf83f3f2f405e47341f369bdc7b6871594d5ba0f15224fa0104aadd42c807054b6931a457c5d9b549c6938ded9438b3810988f1746614ab6d445c708fcd34cffc2b6c6c9741af530f99ac8b199e74effc0c233953a4c3600e246d24bb76b1e6042839
+S = 47f0f2e59c57d1368d8f7af9fbd9a276ba5664b7cceed05453af3a19e39221753a483afbb69b0ad2c3cb9eeba8a89b15fab2176c4d6f23d49901e755b26bcaa023a2d204ec3f9b1b86e884f915206e9700f1e3440c72ee82ef9cc9586e614bfcffe5f1ce5c1e88ca395dffe17092661763dd1f59342e85da7164877f34435549cc2f46beae3bda75cad2bb6245d95a78f42c35543df768fedc82c0c3eba0f8c9f0a9c9c49acf0659bb31c15e48f5210b40c2c908a7d16b741149f7a99ab662fb93ff03d2e1d1a9c747431a3bde0fc6bda2ca97ff0702c566a802850193f6015541b192d025fb4a066ac86fc3fac60dc126c8aab7407f96c57a9036f8c87101804f63d533bc27030108e9d818a0e781fccf84b1843491d2014d80e504499ffcc9652fae595536eeab6025e4349afbbbc39d98ef3651f9e396e440e10720d0088ddac25aa74c9678daa7009b27831455d724b92a7f385e30ce01348df8953757574d75db554253d6f0a98f44b6e1545bac6ba2ea9089ef53d50e74bf660f31a579
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = 6ecef36b3e3f3eeec7b2fcafd5d3fad44a0cc643c09f715a6ff294e15129913c85fa1be5f2bdf91a2cc306d39be97df7da6d73cf5d00a5bb571c7424da972eb140798fbecb0b880a88303eaf79f85658f27370ae44c3f113997506931f12e61769f057dc124e7324a3a0ac2cb6280e5d5cc6c4c6bd11decafea6511668c13fd7
+S = 8dfb3af8566d416b0651852316ca2dbf80b4eedb88bbee9c616760cfea3b6460877d7e63d745c634b3c775498148566ab5c71c69bd476dc2d5db0b5914e1d649ee7648a0dcedcb0132616a696cb665bb872792f1e2e7880ce29ef4226de033b84c0a518a6b1805dbe164ff176fd252e8d784f4696967f444e585e087a1e694a123f0d7e10b1e5ad4894d9ee43107f32665be9ce11ebfb4b722f9e2c6b151a8dd8695156ee1e98f228556c8dc47dfe029ec22fb5c4cf96d8c4c190de823509f57a9674578d705e35d9423449e0519f056a04c47eaa042204d064dff84bf0c6f7e77478c93c4fa2a17fa617b51db9b3ef021501cedce2948119b015200e3f79dec13ebf5d872a9c24f4388e6fea5930e0fce2353543c5de84299d7cb30c7b92bca46a75e5f1d589cc6cf9012ba8754bc288127ca7a47338c2479b560ba66be39333888a3fb408fa6bffa87ae363c2b8dd17ee8091add784cac3d84f7ef9d31829b2bfb9f960918e8a9a703635f2b817dd4d33e34af595460f25d20952513390a4d
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = 9d3851f81c9bcdd9bf1b49abb051cdedc3ce75d79eb0ba911d73f2a2f5091aab972cd45557f3ac88cda39fde7bc8de57b185cf4eae2955ab0802515b4e7669fdeb4f08de4d57a52847254956b4364beb5e405e641ec2cf6b44e0074d386e57ae624bf57c48f04121f6484dfda3c39d1391a62b0235a5ae3898b31c62fd196e26
+S = 8ad5a0410d3321c6db10825bb6cb6aff9b535ece860e234af1a765598deba1a3c0f9bcae8026d15fcdefa062465e24262f06444a0a3507742c867d35ea39df96d791970b2feed352987c70c138c7ec51555a6c74f86c7f2289881e10f1e97621397b1ff9664720f9d86ebe6baa42e0fadcacdaaaf72e0973e1d7f282818629697b2fc1bf513e52542ed79d9df500488582ca5bb27811a1f5cc22e9387ff1eb37e09cca5eca7599a17117cc58a5ed1cfb1cd09843a0ab617cdcaafb7657b166a6e2fc994506d728f1b4092fdd6c413922c4224ca9cf13bfde332f26659f93dfae176eeea066a4c5ab6f839c109a227f57b1bdbc7c282d4e683974bfd07184dde9af2ad9e0d5480c18680200cc7a4796188c970ded598610069709b7e57986087c583e46e19469956de5b7a2ec55d800db0483581cf1adface34db109fc1a32b2700a55722a920527511b3afcbe5205ae167f592b5e825770fd412f4c80a76fcaa18f49356dd9512a784350cd312b0b978234c178fa6db7523622fdec936b6ea65
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = d2d812b3558e77320d0a5ac5e028764a08cc74d517d10f4739427622bacdf19bc874c8f1798661fe10cea80c7c0ab3e9219fa73edb8ad51c409a29d826dcc5196657e92fdffa16a6bdd3731bfb826f4f26eca87a64340ce2b6e73dab7a763af134ea3d148dd3df539c81829d6577f0a39f1d4032bbb5fac021907b45bd829a4c
+S = 0c928fde1ba0d751a3416a9945a6d2d92348dcbded370d44ea2fd798d3909d616111cd7d7c1d53d213b94ff485a2c83a61eac10cfa52f5502d077b16b845c7d647fed022bca6ac5662ca71c9c7556750ee421cf3ca83c09227c95739cc1b9b2bd2d04ba65743b719aec6316f8d2a03b0bf09b79c56fa6c78180fb404253fb351945a3967303056a5d9d40640ae3d9089b894415a13dd525b9e68a0c431b0e2d97d99d88b20c63e8b44aff02b6ee7d6e919633e9b66f7cd4767993617ec29dd27714c10aa24fada7fdd3ca4c1f7eeef473e2426d59925337b1c0bcc5a408127c379cf0e5a3b003b15eebab349f1fa1744c0890cdc826bb498eda3d8f595f3b4d068e0c1670fd96e1d4ebec885322defa6ae3cf58501e9a23446004ac7301cfd239807fb03796dd5e07ab33f64bcadf2a51b41daac5e7030b3507b819627d67309ba591361a414964e109e98ccf9aa12b4f855c9f248d9c3546ba5553bd2fc355125375ed8ee5cd75ad32d44fcb58584670b397e8d7797fef0e0cb6968be1532a3
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = 80a5889f08f13fe823fc42b0939ae58fdd448de4376bb8c7a70c3d3f6a85d4b593a7d8a9f40c4ca441aa1d6e73a9a6806b7279bcd8095d5c5a9c9329e85c5eed6f8bc22abbd68b0c9be6919d40323b38e7174240b82ab711edcd48373600bfdf5c7acb8a25f9030979d628a5c2dcaa9e995a6ed79e77cfcfa7c6e3d31e1aff72
+S = 0aa0c1be7e36c187a5cd2c0720fe266794df19bee8623dd1291717396abaa02093ca436b76f9cb335b70a19e7712714312eba39c60eecd78748a7cec932f7dbf10daeb18160bd5926e6c5dbcb3e74111521d637f460b6f44b1a3df562f0c93d0fae165fd2e48c03251c95983fa1e6ab61249dafa206cd476cb7fbf672e7084bb358c221b2e94ee268e41b96d32a83a481aba41560e81ffd2e6a3087d88b0e3433255217370b7be41299b0888ea570b74c3cd063c0f02bfcb6ebf77ed4221cfc4d7d3909b7bc087c7a5f0787cfe3dea8f84106488261af265243eb395219acee63011a11d49027703e8a7c11f397925ef0812611be315d209c3138e32238c3755a2021b28706f33f2f8f3f03df24790f013dbccff8455e38e460555818d44f3c400e3105a6464e3955df9f9435bb6b34dbb18ad3477831b45ca84be381f52c2699932e0d9e51fe043be5246d66f6e27892a42fe9d91a258de9da71e0b059e4a34ee683c363f09ce14881d8d34facb67499f0c4e6d98442bb1996f8c4df939a592
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = ee436b6a38d986c178896a803f6e5146bdc518ccd8acf3c7802a60103c705902095ece2365495207a7fc157291fc12bd2811897bc301b05c639fa6514204a8f0af1d871b186659dc69f46f9495b988557104448cc947dce3ae1d0f650d8b60e386867e977ab60408667a622d702c1bd540a632471105de2508ad8596c48de8a3
+S = 37773bb5e8fd6f59b29cd58b5aa6ae9a94b9a317ee96d045ae5450dfea51b0dfef5f82d364349769bcafb987186a163a4091b4d4caae5a961afdfad05e0ede656c10f2914e20b73865e6809b081410b539ee7b0c077803c27e315bb3dc6c40fd05409f306a2d6a6600f6051d974a108d96c54c8dfa33a346799209beedc46842579cd9d668cb809b7c305e8941709ab005cdfeaadf4df17eba04b9f976546a83ae155c66c7f391b5f978509e515356c925df1d41f56db3d4f980ad8dd86408460b772d5ef8fe9b634aa092664085fe750debfe7863052db8124eb8deeb9f2bf4f5f78648c327925bab1cf8e62405b6f38ee85271e5575d42fd0c4f0c9cd0caf8ca22393f8209fbb692731fb2f5e8b0051149651efc83e8ae1a7c979611c0254fce70b78ad81bd4ff8a8988478492e07e12a80c020a42684e57f5c0d55790eaef9756b7f8e4504bf577909eea870a0b2d859f4dac1e2784f3eabaabde6534dc13c23ca3fb4e2ddbef9afd1dee1fbac74470d23ea8ea51b6191cd160f157070c91
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = a0f16e1a5ea9b152f46a250fb197b26adab0e8829f7794c44e519169c7eee13f302cfcadea3968f1c3f88aad6da7bca22fbea0bbda1ab34dff5a259d5f8ae8a3a3ff070d4d813987efb0b63a9aa049929ac7a6456019ff91c071d2c55d330502612f344371c94a9be0574ebe22cb80c38492a5281bbc9f17fa5c40e7a83260e6
+S = 32d142de909db1cc8aa6bc7648c3dbe15cf37c51c5c68b68e631eeca93cb59c3cb063f70ad68bd5c48341fa36d8050ce0d05c691d21b91ee172dd201bd7fdb12e4938e16488990d9fd73efd1223d2502a55c7444e03ab5acca23be2a8ba0af2b3e2281f08de6eee5dd6c3b7a9e6cb94b1e9c5a0eec16b3aefb4f19656d36a555f299811df683107fa7d23834e2aa2fc33a72b7b9a1a8a46ceebd51304fac650e3364c7852b5a339c14be424de63d879b3e5baa97d25a83089cec27963f15ed05dd01aa670b22e12f33c692e3944e60e7d2760e34f05c52de4b983977bf54cfc20a953f631917556609d9f1ad99822c3f522aa9559976ce43cd299cb2fc36e3ac4a462ad2fdd18e30f69b284e720ab073eabeaf3a8b703f1626f722711fb607a0bfdbc282acedb642d780db89de0b01436d41cf48680dd9da79620e2dc862e6fb89d6afa6d9446c8c203d239f888e2cae4c080487f7bc8e290c4cbf283f1b6605d3f3d97b1d725357631b729e0cb01ac1df37a773d0ed6c41143cd8d90d325a7d
+SaltVal = 00
+
+
+SHAAlg = SHA-512/224
+Msg = 947fca2fdd2e5fd21080e50c45804dd61b9a6697f4feafa362456a01dc57f171b68c4dad501105f08d8e34b58605dec180fe84631ce1f6fbcea369b990a4c9a7d8d851eac7265845a30d6ede878da745594537b2fdd93f8ec896e7353859adfbe2acfd6dab3301d93b47ba10afe0506a8eb8a60bffad326539670cfe3a3c4473
+S = 4a9bf3cd69369cebe2346d866aa502765983d52221a26b33528c97fb8b3e33bc8386619012f3eb0c21326798f63be2969fdb853cc19fa1788649be7b59445f5fa8118f5228080d3e80f5e71405b7ecf0f12ad153fec738ddf8196ed174a3d066297d90f0224eeae935af243b04ff39172d61609ce6d46c8490478c5b2240b85830c2e8e4d4c18188277fe9b8318260d7463845f86ef172fb607eaf3ab65eb871016269242ec4de6700e163f3711c237c07ee181477ea6d8e5f01c1519fb4f4bf18b68b58e0e849895b85eadd1ad9c8f5a59c1e6161f23fc1274fd428dd2c446a5764d7163e3852d742c7fd599fd71a47a87bb52b1ce2180b9f028fc0104847b8f6fa8428a4b5830415e58d7ccc5f5d0316d9af988b75bb81814ce47591247ab6f392d7b79f0842664bb7a666dc376461a92c74abbc72925685bf4de29def70890c8127445cf1820060e6378fb9aafb32ac4e4573f0c7cfeb8b1d2abf27e77aacb06fc96deaaac3d42ed91e23b3d187a36e1355df5b7340db434d0ecab713df08
+SaltVal = 00
+
+SHAAlg = SHA-512/256
+Msg = dede9344f021a6bfaab1f31a1156bae87cd631d9ec0477de9bf9c98dd8a2f8c8117b1a99329980612eeee932dac9f579029cdde0b7026072e60001002f8b6fc4f34b4545af9ff37a89e1fc3229eb63b4cada5fa2911256231d8209405f290d8facd87a0f103ae754e61395e4a5c5eae0fd1821e7233a413769054b151181b870
+S = 552e173156b6a9fad3e7a696b0aebf594d2c4c8cfea3b3d5cc16398b1c88d4257faa9398bbf1bd96cde845411e4b0e46f062b0cb6d02300246b6788c50300a399f5f55c89ed1a7d5f7ce95c0e1b4446f0bb11c3fedf79cad0ecadac9b3304ec734ebaf63588a7701355aa715d16ed9e2a3b338abd5a96b12bd3a7a28555440e1d22e010350fa329dab5d08aaa53c23f344962cc71d6a00593344d16b6b8d92e41fb68dc3fe321374a17146c1b1d33d434725f9c9716d3afc0cc0fcca755725b95931e9539282271423fb329bcd482c8388b8b79c6a24593586616a7380d5fa7ccba2dee30151ac8ef92150459c630c05ea15ec907964bdde7167a6c6491facacd8e7bcae2e564612e2bcaba4459f10c1cd6e5c608774165d2ff11752a88e1e2394f8750229ecc82173d7aa57e6f8a4b20b7e9f676dbef75229c281468d7c1a3c0be1a71987161bc469140f9c224d67e01ece5da69f09f0ec282500ddd351806791f4b363c35920f00e02c2fd49bda9ff7d5111d38d1aacbc3f795cfc2679148c
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = ed654056cf27081d61fa37d5a91b2940e7194001cb38c417e613eea55f863ff4e7cb16baeee3829d173855f3ea807acccae48832266296aff370521059e24d69ac0d99599f2d968fb404098df7c46eacec2f9061c6fd56bed97ee03c5280d2b72673f0ba48cbecfd1fa67b2c37afaeea3742801613d1ac4d8286c1b0b32977e7
+S = 2694ab79aa110de26e5bb0c5738280c13e4c4075d850f7bc249076f1b4bef6d189cd55c1207d77915ca19513f110a7dfa2e595f6a840fe45a996ac8ff2fae2aeda666ede3148df4cf4112725ea4c638b7393e52ae1e8c756cd139ebad9f69b7a5e2d6ef65dd06248b06669fd4a90cf6a6f957fc6923e1bd2cafe73a798f7473eb25c153a5d003002e036782e41ae7c3a9c2176ee59e9c3b4957d6f7dcadbf3a033da5ff4cd980f638ce0b49bd0ec1468511a91d31ab25978282058426874aa5e4a3228a6758962280340db921cd727137545cdff946d39db072183770edc815eda2dea83667f1a426cd1510419703078faac7dd6a593789c95ae8c206510fd5a653c58d2e158d6b3a4d50444679583f8009217c72a076f78da6074a7758be3d894f7fb0cd6054df29af04acc53df1c6f6af544e363698da5c72af039f2fd52f51eee27051bacaeafedd56b433ae144e52203b838d0a550aac92f1d7640f7e27c0b07e4421f4b2e87674c1c94c4028886032836c3f9d4fc573a62301b3e938e68
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = 78a462d13bced2fa9b5f4b5096b0d09a6c54b9a150fa06356495f470e4bbce3fa14b061db253842266313e3d7df809be9715ae17ec3241e33e5aae270c5e95d80978589ecc2f72d8c97a0ae08028c790f47fe7055f248ba2243b555805ce3525967380dbf1294323ac84d6c1080ab41a6bdc89f311998d7bfe7f118c37d3572e
+S = 6cde4917f5580de2a552238f2a866f34dba7817ccb913cf83e7b1fdb24f9768afb88d372a06fb01f1b904819e2c612d0d4b7dbb07484deb12a5135cdb7bacb79ca29aca60d3d5be245844efc15bb3d8fefb07f5e34b87c7bff61e5f68b71b55f5e7c41f88305100a3326e6dede69e8f9f5ed98de0fe5b3da716511188b4915c5e17b876d4e69c080da9ac3890499f9fb0c3af999a0f53f751c19736a17753e3de0e4bf597302f717424ccd628de245dd2f58dea65cf8ba70291f9ead1d11e68a83518ac9f43fd95eb308083ca5b1a9c750dd71a24e6604b752157eaa4ec12bde9cd10e5e6d2fe74bcef128059d260c9d3e43500099aa9df1bd1fc351878efb7d5e9096af9a453328a2bc4aa4d6cd95f16769bc5a639bfc3429a1ee3424680c74f558e0e716f18961e49b6f818f5ef2fb91b665835f703d3354aa3af41dd219b30162e58acdd0c42991d5929fcba63901681128bf10367df4caabdd3f788c3284d45b15f09a12031c2d79e3df43ff9c0c844332a458295417c9d1b5920b2b8c11
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = 0bffa55ea33452b4cb7e729d75952abe7f73e0ed35c0e847188e607cde46586eb9e237fbdc5d59163c68fd1d935f5f66ab7b211cd949ef49c75b6333773d26ec85aa5925ad0033438cf2ebb5ab7dd884b91dd72b1840edaa9cfb2dd68ffcdcf3f8c0d4841c0626624683030cc4d7dd3e32c0c9c5fb8d28911cd6860c2b6bc2aa
+S = 090aedc468b0fbc38c4dbdab04a683f174c6896b0d1063f87adc78f2152aa4e74b728e370aa9e766a4ee80b569a8abf9cd9891f68832f8e6f05561dc8ae111ead42be07e10bbcf5430e062fb6b49ab61e7cf3cd9c58ec79094e1db324903df577b509e9b29a5f95d8a7ef2b252ad7f48d16c08fa273e389738c457b36651097a859329d04be44d529bf75c41d1d14562537ecf3e919221e22a05fd9d2c9d775793f4d69614c8f9e8bbeaf7faa75f046a1ede659f15674fd2c89de67c64f99d2c29715a188932831beaa73e93273a17730067289c161a9c217b5a60c6c38473a4e2c2b62f93fcc99963a8dffdcb7ff0d36fb03d913e72e024b22e2f1c87d79c3801dfef2b5c17e0b3189db14100f7c31eee6dd92454adebef3237a6f50f1c5966ba4e44a012afd4c98f171009b31daee4ab671ae8b669e71d65e7c79181c7d31079766f578c923293405472a6fbbb121355260394e890697bf2f39f552cd5bcafb0670661dd31b531843a89e5566845873c6d05acec03ce1aeafd0e2b4fe8af97
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = 48031877336bb181d872f7dd7c9d6ecdeadd556965b433e8e299b21b749eb03a085094e352dede60077e03294d0d77a970f50b45d654799b355b3d0703f4a76c2ea72f310ebe088998a7f8f8d49b6613917db5875705d05c9d1d067b3c8b196e24d191684d515685f1b57e52f98e6490b53bfa35cf0d60b482a9b57e07ad2dc9
+S = 8e1e2ecd1b9b955fef52b996b25a20aa00c0bce4d6cbf8d2d3d9e6711411fa6b89a950a8168c43676050aa9a1d09461cb286891082e34aeb1693ba10bffc8669128009a480eb79b51ce708f31f31559d2111c3df4a1096cd8d3002ba24a4be18443f260d1c31ce4850b767fde5820645fdf1b6768c1c4edfe4c743ecaa656c4f26cd81a10df845bc7f109b7aba8b2b9ddf67eef88b3e715cfca8368c85c80949338007aebab6b821308e2bc5a1edbda48408f9a214d8694913da474135bb9a3e1ad6f9dfc30c78338b43f503ce62977bd34bea7eb3da52627c508db66ba80c02ea8c6082cfc0f06b2f47532f79f7364cce2ca80e24e65ad63620d1beb58ddf9ec940cc7896465f986a6bd5688ecb1099604f41f964722cc8aecbb31295b8ea02d7e71c4650183456c6d5f1a4dbb0e46407cce598174f5f42358d1948fdf5723b66839c35730c66b9beb04affedbd0624ebdea47e3f27f1ac7da98fa19a5210eb97961c6165c2f133651b74f6e6309bac135073034f0af5c3db8953b021c32de0
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = 7d462b2bd2ddec9aae0c50d9ee912f304c8f3276d331e5d497900dcba2d73b7831a5a11721b225c7a4b6b48c3886d99ada808ed1762a5284a3167b7e8d09ce47325b4da3d2a1505ca08ad741be071f6f68af73cf706145e0ea2b7db7286a1144e933d6d6cdf296e10c516200685c293660e28a79a71ee771d496bb7d5b442df7
+S = 2845dae6c700ae0b12b4ee09387f532c1df75e4d4d6b8ec2baacfa66d5baac53257b09b090587e0b8e524c366c3b330f668a7b3229f7b16776a598b48e9018c04f074b75abd30d016af665d9f8a8fbf81fede76c3102cf15de174ab69d8160bb28637b257636e7ea69bee46c128afc57bf2c8d1fd639e01d049997c90d286d75f82121ab51fa9d92951724d32725e559961de1345fac18dafc9b472e235dd32bbcda8dd544ff01338189dc191d69141a79b39b7edb56adb48cbdb2e370a0425beb78cfa980e30b92daddabd9e10dac6f13ab0d5a29cabba60d5d637ac9c6abfaeded5672941761d3eeec3763951823b86b4df20838f7170cfe509deff4b1597c5fe3785df0a0a62d70e7fb75f183f6f73a134b4d89004a559edba910157068157e29e25b10c18aa37d1569a484387218712c847a8aad93023fe00cdc71e55aab46ea371bc52fc0496139cf30c7a53e6cf043ef0b9aea086efdba8fd2cbd15c6b82493cae581500040821ccceebbe51de2a2b356006afacb90cbd39f3cee7c99a
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = 8ea2309acbdbf827b4af0a7f418741e147392587a474bc2abc5ea3c92a7b5ca7afd1ea936e4a9b6b5c5926e3f2e0f5832552c4ef97156b6b0f2af89e270f019644e4390dcbce40eb9299c00c95a1b542ebf20c9ef8ae70ebe3af617c4a6e862835234492492e8fae3fb60080949028278162251b2d0872b3223604eafd5f9262
+S = 3f5094a438d4bcdd51b54860f3d0e74f87350a0b230b125a7d7ba6c7782f5a38841a3c4dc89e2c51262f355661517184803f0324c83f54453bc3852348cea3683e48013222261bf28c5e1ed47c4f63f1bff0998f7551f71e427c5aca89e8b6558f802a7bfefdaa9c2834a08535d4b8ffc8734fd7d3e3eb903b50a96ba79eec6d114deb6e8cb1a3d301edb343b1f280fb1d6619f5aa980ab98c7fbe423854715226dfa87d2a065b0f77df1d3cc0f724af3764f1dd27dcc763c856c8b2ba64820fec6b8e3e837f31115aa36de077a54c3eb3d91b9bd162468a9036332cadbd295574fa57608ce24161d17a6421dc7425cd31f610fa4835d120a225fc0cba537b96ee5c03b135b62fe14fc95e10dea7a277cbeea8ce3364f284c691573e05fcb58f64b96634d9b49d13a9b271770e521abf4f6b67240a47f76a5cb30ddf33cfd6b0b608509e83b06f3166a8b544979520b5d7ffdcdd9520ea92a2437f33631c82d10ad722da93d16e873e5a279a77edf90924db213067ec94332c447e56b4c86a28
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = 81dd6c87d05cef3d2ff53f42830ff45ccbb9af3a47425ba9e003b20bc480030451b03376349803b0d21f90e2e71d20d46cb51bd8bfe558fefe5b9a86b38a5b9bb7fec83e50ec0c809d0ed1f434ad04640900d9c392b4106328cc7668b1abae7d7c6f31c56c819414596a0a60b3e929726842f1e108d80a4128fe4d98040b8611
+S = 5be4d75ed981159652b7794287be96d502cf7705618f590ae7209b7e43df10276009014eb0b101f1aa216af8ed4bd3406e0c98bcca7642324e4727d501d50d8d7e4aa071711bf387ec926eeff74d985078560157f05f4f95c4ae0e1f2adc512f076ae1920a3c197e928c591b7bf3376f0d854ee7c243f08dbb8451ae2547d8f1fcc7f776541f8a98a8d93c50096ae44b366e2a0ac1f8747871676a742f14fea1de0bf2c2857c7d3911b9a5166a3122941d0df4ad80a091fbcc1a700bf381d59a25b0546b2e24c702e33e0216d0c2b800409f84797040373e1f61e0ba73e1c6bbec397dfbca4ce399fef9f48064eca462c3fb0a01c47644e07b43bccf077ba2f0c30be391805f09180c6d996c41ef79bfa2f6ea8fc39db007cf122ec29746f9b4a322a62ac22d5216c77682801921324e72d542a8ab8b6e624da5156e2ace2d7cbcf09200056657369797d1c194b08ee073e7b3b302321611f8706f82924b5c6f5a5a3bc6e1fcfc381555a0350cba6152bda463313ed0f6353e99f05125141236
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = ef2d179cb22c7b89dd1c9f86f007b01630b0bb27a981cda074c559393617d98fe91ab878df6b709303d4f02463c3401febfa678373878de9fdf75d5d37c7ad6c481b617ec8b28c67101ad938b5202a5b4f8b7edf7f0a1810306ade4b1c0cff109297d85977ea192a8c55236aee08b5f1e3cbc8e2d3f0b73b9586a3aaedd016a3
+S = 131d2cdb1a5ef38ad4ed19ebca4b8cc14533bbde7039c957c026c6ccd82a6d1d6088949a88dde506b94fe8cf679a352ba505b982ba9e6c91cecc62c3da3592ac39505ef43e77feedc2b1e4b749a37d56e8fa55b6b579927248bf6a669d61be6923db46062a97ade441a0c43a68cbcec4dbd440a08ee9355aade4327eb18a4fca6bf73b23a557a27074a588e704d9687a1a66d2be3b9851d9fb7869228213e39a6173d60b3f5f2ddeb3fb6bf8ec85dfcfc6685eda41390ea8f8390f9336b181c39e779b930bc93c2867414a4382f47ecd713531425b9fe6ee1573827cde76c01e34d5918d8754a37777fab7d63111970ab806caf53cae6976a1d8409ffb47309d651bb22ab90d474c52bb42367e6a44cee2fb76d2e61b9b2f1fa31e1673f68c8affb551990d5e2ba369b4614cefda05bf21209c44b4033d754b43a8a5585274b6cd198e99b2a17f69c57fe283f3a8f573e7bb92348973acab578a56f4d0a742442c3cbcc323ace0b1605834add2b8d759537c8b773a60f175d7bef555dd15fd08
+SaltVal = 00
+
+
+SHAAlg = SHA-512/256
+Msg = 2393f956864f57c5dd9cbcf27d89ca8da2772d1c0e2b68a7f321d4b51323e578261bb0457c26aa47e3e9b373cb2853bea894438e98e52f6f4629ba080e5cc34d6238e6f66c4e462ff4568a9185c42651cb9cdcb7408682d20825056b18a5ae379e93a4509df2b3e6d88b4b32f284ccacd334007e4e36e93800bcbec57b26309e
+S = 523cfd39492fdc70370d02763e2185abdbaa5ed331694a52ee7ad0382c4d2aa0c78b0fd0bc0d7debdef5b471dfe5c59962fca60a0b1d7cf68f1cf2d44ef8d9e110abb4e1531a9cb26bf4b585d486fd6ef5ee4d7eb7b6e4d6a930090d0d9d201ecab88fcf5c4c9231fbd5fe4285538ff85554073f9e49b084ba6c03ee6d6966afa029318b07dbea55a1570911579149efe87d67391e665b52774bc498a9f7194b4f0d304c8adf0998461ad7e1902ddcc0f7c326f7d5062f7c32f8d7e0fd3b5189b2ccda6451b7a93db018c93baad28ad871a464a4f0da5a32c81f645a77f9e1b6da16aaf96eb32fcf7d658e1846aad21f85f4af856b9853adf16f5cf5b7ea1ac2136fc13fb735df03b010ae854068bc758e3b875c319df322cba923f4ee6668087d59d80f2e55fdf6e44e5f2dfa1e747d0fb8bb3542d5466c47a2324334c8f5d4edb5a1fcc760a2c71d79b4146cd9d6821d92c308b58ac48502da31a63cc525157d63b25fd59f31a73b5398ecafe12739af44c2f441dc47b93f7f4d10c4b2e484
+SaltVal = 00
+
diff --git a/jdk/test/sun/security/rsa/pss/SigRecord.java b/jdk/test/sun/security/rsa/pss/SigRecord.java
new file mode 100644
index 0000000..229dda1
--- /dev/null
+++ b/jdk/test/sun/security/rsa/pss/SigRecord.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.math.BigInteger;
+import java.security.*;
+import java.security.spec.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public final class SigRecord {
+
+ static final String TEST_SRC = System.getProperty("test.src", ".");
+
+ // utility method for converting byte array to hex string
+ static String toHexString(byte[] array) {
+ StringBuilder sb = new StringBuilder(array.length * 2);
+ for (byte b : array) {
+ // The single digits 0123456789abcdef get a leading 0
+ if ((b >= 0x00) && (b < 0x10)) {
+ sb.append('0');
+ }
+ sb.append(Integer.toHexString(b & 0xff));
+ }
+ return sb.toString();
+ }
+
+ // utility method for converting hex string to byte array
+ static byte[] toByteArray(String s) {
+ byte[] bytes = new byte[s.length() / 2];
+ for (int i = 0; i < bytes.length; i++) {
+ int index = i * 2;
+ int v = Integer.parseInt(s.substring(index, index + 2), 16);
+ bytes[i] = (byte) v;
+ }
+ return bytes;
+ }
+
+ public static final class SigVector {
+ // digest algorithm to use
+ final String mdAlg;
+
+ // message to test
+ final String msg;
+
+ // expected signature
+ final String sig;
+
+ // optional PSS-only salt value, maybe null
+ final String salt;
+
+ public SigVector(String mdAlg, String msg, String sig, String salt) {
+ if (mdAlg == null || mdAlg.isEmpty()) {
+ throw new IllegalArgumentException("Digest algo must be specified");
+ }
+ if (msg == null || mdAlg.isEmpty()) {
+ throw new IllegalArgumentException("Message must be specified");
+ }
+ if (sig == null || mdAlg.isEmpty()) {
+ throw new IllegalArgumentException("Signature must be specified");
+ }
+ this.mdAlg = mdAlg;
+ this.msg = msg;
+ this.sig = sig;
+ this.salt = salt;
+ }
+
+ @Override
+ public String toString() {
+ return mdAlg + ": msg=" + msg + ": sig=" + sig +
+ (salt != null? (": salt=" + salt) : "");
+ }
+ }
+
+ final String id;
+ // RSA private key value associated with the corresponding test vectors
+ final RSAPrivateKeySpec privKeySpec;
+
+ // RSA public key value associated with the corresponding test vectors
+ final RSAPublicKeySpec pubKeySpec;
+
+ // set of test vectors
+ final List<SigVector> testVectors;
+
+ SigRecord(String mod, String pubExp, String privExp, List<SigVector> testVectors) {
+ if (mod == null || mod.isEmpty()) {
+ throw new IllegalArgumentException("Modulus n must be specified");
+ }
+ if (pubExp == null || pubExp.isEmpty()) {
+ throw new IllegalArgumentException("Public Exponent e must be specified");
+ }
+ if (privExp == null || privExp.isEmpty()) {
+ throw new IllegalArgumentException("Private Exponent d must be specified");
+ }
+ if (testVectors == null || (testVectors.size() == 0)) {
+ throw new IllegalArgumentException("One or more test vectors must be specified");
+ }
+
+ BigInteger n = new BigInteger(1, toByteArray(mod));
+ BigInteger e = new BigInteger(1, toByteArray(pubExp));
+ BigInteger d = new BigInteger(1, toByteArray(privExp));
+ this.id = ("n=" + mod + ", e=" + pubExp);
+ this.pubKeySpec = new RSAPublicKeySpec(n, e);
+ this.privKeySpec = new RSAPrivateKeySpec(n, d);
+ this.testVectors = testVectors;
+ }
+
+ /*
+ * Read a data file into an ArrayList.
+ * This function will exit the program if reading the file fails
+ * or if the file is not in the expected format.
+ */
+ public static List<SigRecord> read(String filename)
+ throws IOException {
+
+ List<SigRecord> data = new ArrayList<>();
+ try (BufferedReader br = new BufferedReader(
+ new InputStreamReader(new FileInputStream(
+ TEST_SRC + File.separator + filename)))) {
+ String line;
+ String mod = null;
+ String pubExp = null;
+ String privExp = null;
+ List<SigVector> testVectors = new ArrayList<>();
+ while ((line = br.readLine()) != null) {
+ if (line.startsWith("n =")) {
+ mod = line.split("=")[1].trim();
+ } else if (line.startsWith("e =")) {
+ pubExp = line.split("=")[1].trim();
+ } else if (line.startsWith("d =")) {
+ privExp = line.split("=")[1].trim();
+
+ // now should start parsing for test vectors
+ String mdAlg = null;
+ String msg = null;
+ String sig = null;
+ String salt = null;
+ boolean sigVectorDone = false;
+ while ((line = br.readLine()) != null) {
+ // we only care for lines starting with
+ // SHAALG, Msg, S, and Salt
+ if (line.startsWith("SHAAlg =")) {
+ mdAlg = line.split(" = ")[1].trim();
+ } else if (line.startsWith("Msg =")) {
+ msg = line.split(" = ")[1].trim();
+ } else if (line.startsWith("S =")) {
+ sig = line.split(" = ")[1].trim();
+ } else if (line.startsWith("SaltVal =")) {
+ salt = line.split(" = ")[1].trim();
+ if (salt.equals("00")) {
+ salt = "";
+ }
+ } else if (line.startsWith("[mod")) {
+ sigVectorDone = true;
+ }
+
+ if ((mdAlg != null) && (msg != null) && (sig != null) &&
+ (salt != null)) {
+ // finish off current SigVector
+ testVectors.add(new SigVector(mdAlg, msg, sig, salt));
+ mdAlg = msg = sig = salt = null;
+ }
+ if (sigVectorDone) {
+ break;
+ }
+ }
+ // finish off current SigRecord and clear data for next SigRecord
+ data.add(new SigRecord(mod, pubExp, privExp, testVectors));
+ mod = pubExp = privExp = null;
+ testVectors = new ArrayList<>();
+ }
+ }
+
+ if (data.isEmpty()) {
+ throw new RuntimeException("Nothing read from file "
+ + filename);
+ }
+ }
+ return data;
+ }
+
+ @Override
+ public String toString() {
+ return (id + ", " + testVectors.size() + " test vectors");
+ }
+}
diff --git a/jdk/test/sun/security/rsa/pss/SignatureTest2.java b/jdk/test/sun/security/rsa/pss/SignatureTest2.java
new file mode 100644
index 0000000..7a6a5e0
--- /dev/null
+++ b/jdk/test/sun/security/rsa/pss/SignatureTest2.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+import java.security.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.*;
+import java.util.Arrays;
+import java.util.stream.IntStream;
+import static javax.crypto.Cipher.PRIVATE_KEY;
+import static javax.crypto.Cipher.PUBLIC_KEY;
+
+/**
+ * @test
+ * @bug 8146293
+ * @summary Create a signature for RSA and get its signed data. re-initiate
+ * the signature with the public key. The signature can be verified
+ * by acquired signed data.
+ * @run main SignatureTest2 768
+ * @run main SignatureTest2 1024
+ * @run main SignatureTest2 2048
+ * @run main/timeout=240 SignatureTest2 4096
+ */
+public class SignatureTest2 {
+ /**
+ * ALGORITHM name, fixed as RSA.
+ */
+ private static final String KEYALG = "RSASSA-PSS";
+
+ /**
+ * JDK default RSA Provider.
+ */
+ private static final String PROVIDER = "SunRsaSign";
+
+ /**
+ * How much times signature updated.
+ */
+ private static final int UPDATE_TIMES_TWO = 2;
+
+ /**
+ * How much times signature initial updated.
+ */
+ private static final int UPDATE_TIMES_TEN = 10;
+
+ /**
+ * Digest algorithms to test w/ RSASSA-PSS signature algorithms
+ */
+ private static final String[] DIGEST_ALG = {
+ "SHA-1", "SHA-224", "SHA-256", "SHA-384",
+ "SHA-512", "SHA-512/224", "SHA-512/256"
+ };
+
+ private static final String SIG_ALG = "RSASSA-PSS";
+
+ private static PSSParameterSpec genPSSParameter(String digestAlgo,
+ int digestLen, int keySize) {
+ // pick a salt length based on the key length and digestAlgo
+ int saltLength = keySize/8 - digestLen - 2;
+ if (saltLength < 0) {
+ System.out.println("keysize: " + keySize/8 + ", digestLen: " + digestLen);
+ return null;
+ }
+ return new PSSParameterSpec(digestAlgo, "MGF1",
+ new MGF1ParameterSpec(digestAlgo), saltLength, 1);
+ }
+
+ public static void main(String[] args) throws Exception {
+ final int testSize = Integer.parseInt(args[0]);
+
+ byte[] data = new byte[100];
+ IntStream.range(0, data.length).forEach(j -> {
+ data[j] = (byte) j;
+ });
+
+ // create a key pair
+ KeyPair kpair = generateKeys(KEYALG, testSize);
+ Key[] privs = manipulateKey(PRIVATE_KEY, kpair.getPrivate());
+ Key[] pubs = manipulateKey(PUBLIC_KEY, kpair.getPublic());
+
+ // For messsage digest algorithm, create and verify a RSASSA-PSS signature
+ Arrays.stream(privs).forEach(priv
+ -> Arrays.stream(pubs).forEach(pub
+ -> Arrays.stream(DIGEST_ALG).forEach(testAlg -> {
+ checkSignature(data, (PublicKey) pub, (PrivateKey) priv,
+ testAlg, testSize);
+ }
+ )));
+
+ }
+
+ private static KeyPair generateKeys(String keyalg, int size)
+ throws NoSuchAlgorithmException {
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyalg);
+ kpg.initialize(size);
+ return kpg.generateKeyPair();
+ }
+
+ private static Key[] manipulateKey(int type, Key key)
+ throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
+ KeyFactory kf = KeyFactory.getInstance(KEYALG, PROVIDER);
+
+ switch (type) {
+ case PUBLIC_KEY:
+ return new Key[]{
+ kf.generatePublic(kf.getKeySpec(key, RSAPublicKeySpec.class)),
+ kf.generatePublic(new X509EncodedKeySpec(key.getEncoded())),
+ kf.generatePublic(new RSAPublicKeySpec(
+ ((RSAPublicKey) key).getModulus(),
+ ((RSAPublicKey) key).getPublicExponent()))
+ };
+ case PRIVATE_KEY:
+ return new Key[]{
+ kf.generatePrivate(kf.getKeySpec(key,
+ RSAPrivateKeySpec.class)),
+ kf.generatePrivate(new PKCS8EncodedKeySpec(
+ key.getEncoded())),
+ kf.generatePrivate(new RSAPrivateKeySpec(((RSAPrivateKey) key).getModulus(),
+ ((RSAPrivateKey) key).getPrivateExponent()))
+ };
+ }
+ throw new RuntimeException("We shouldn't reach here");
+ }
+
+ private static void checkSignature(byte[] data, PublicKey pub,
+ PrivateKey priv, String digestAlg, int keySize) throws RuntimeException {
+ try {
+ Signature sig = Signature.getInstance(SIG_ALG, PROVIDER);
+ int digestLen = MessageDigest.getInstance(digestAlg).getDigestLength();
+ PSSParameterSpec params = genPSSParameter(digestAlg, digestLen, keySize);
+ if (params == null) {
+ System.out.println("Skip test due to short key size");
+ return;
+ }
+ sig.setParameter(params);
+ sig.initSign(priv);
+ for (int i = 0; i < UPDATE_TIMES_TEN; i++) {
+ sig.update(data);
+ }
+ byte[] signedDataTen = sig.sign();
+
+ // Make sure signature can be generated without re-init
+ sig.update(data);
+ byte[] signedDataOne = sig.sign();
+
+ // Make sure signature verifies with original data
+ System.out.println("Verify using params " + sig.getParameters());
+ sig.initVerify(pub);
+ sig.setParameter(params);
+ for (int i = 0; i < UPDATE_TIMES_TEN; i++) {
+ sig.update(data);
+ }
+ if (!sig.verify(signedDataTen)) {
+ throw new RuntimeException("Signature verification test#1 failed w/ "
+ + digestAlg);
+ }
+
+ // Make sure signature can verify without re-init
+ sig.update(data);
+ if (!sig.verify(signedDataOne)) {
+ throw new RuntimeException("Signature verification test#2 failed w/ "
+ + digestAlg);
+ }
+
+ // Make sure signature does NOT verify when the original data
+ // has changed
+ for (int i = 0; i < UPDATE_TIMES_TWO; i++) {
+ sig.update(data);
+ }
+
+ if (sig.verify(signedDataOne)) {
+ throw new RuntimeException("Bad signature accepted w/ "
+ + digestAlg);
+ }
+ } catch (NoSuchAlgorithmException | InvalidKeyException |
+ SignatureException | NoSuchProviderException |
+ InvalidAlgorithmParameterException e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/jdk/test/sun/security/rsa/pss/SignatureTestPSS.java b/jdk/test/sun/security/rsa/pss/SignatureTestPSS.java
new file mode 100644
index 0000000..3037778
--- /dev/null
+++ b/jdk/test/sun/security/rsa/pss/SignatureTestPSS.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+import java.security.*;
+import java.security.interfaces.*;
+import java.security.spec.*;
+import java.util.Arrays;
+import java.util.stream.IntStream;
+import jdk.test.lib.SigTestUtil;
+import static jdk.test.lib.SigTestUtil.SignatureType;
+import static javax.crypto.Cipher.PRIVATE_KEY;
+import static javax.crypto.Cipher.PUBLIC_KEY;
+
+/**
+ * @test
+ * @bug 8146293
+ * @summary Create a signature for RSA and get its signed data. re-initiate
+ * the signature with the public key. The signature can be verified
+ * by acquired signed data.
+ * @library /lib
+ * @build jdk.test.lib.SigTestUtil
+ * @run main SignatureTestPSS 512
+ * @run main SignatureTestPSS 768
+ * @run main SignatureTestPSS 1024
+ * @run main SignatureTestPSS 2048
+ * @run main/timeout=240 SignatureTestPSS 4096
+ * @run main/timeout=240 SignatureTestPSS 5120
+ * @run main/timeout=480 SignatureTestPSS 6144
+ */
+public class SignatureTestPSS {
+ /**
+ * ALGORITHM name, fixed as RSASSA-PSS.
+ */
+ private static final String KEYALG = SignatureType.RSASSA_PSS.toString();
+
+ /**
+ * JDK default RSA Provider.
+ */
+ private static final String PROVIDER = "SunRsaSign";
+
+ /**
+ * How much times signature updated.
+ */
+ private static final int UPDATE_TIMES_FIFTY = 50;
+
+ /**
+ * How much times signature initial updated.
+ */
+ private static final int UPDATE_TIMES_HUNDRED = 100;
+
+ public static void main(String[] args) throws Exception {
+ int testSize = Integer.parseInt(args[0]);
+
+ Iterable<String> md_alg_pss =
+ SigTestUtil.getDigestAlgorithms(SignatureType.RSASSA_PSS, testSize);
+
+ byte[] data = new byte[100];
+ IntStream.range(0, data.length).forEach(j -> {
+ data[j] = (byte) j;
+ });
+
+ // create a key pair
+ KeyPair kpair = generateKeys(KEYALG, testSize);
+ Key[] privs = manipulateKey(PRIVATE_KEY, kpair.getPrivate());
+ Key[] pubs = manipulateKey(PUBLIC_KEY, kpair.getPublic());
+
+ test(md_alg_pss, privs, pubs, data);
+ }
+
+ private static void test(Iterable<String> testAlgs, Key[] privs,
+ Key[] pubs, byte[] data) throws RuntimeException {
+ // For signature algorithm, create and verify a signature
+ Arrays.stream(privs).forEach(priv
+ -> Arrays.stream(pubs).forEach(pub
+ -> testAlgs.forEach(testAlg -> {
+ try {
+ checkSignature(data, (PublicKey) pub, (PrivateKey) priv,
+ testAlg);
+ } catch (NoSuchAlgorithmException | InvalidKeyException |
+ SignatureException | NoSuchProviderException |
+ InvalidAlgorithmParameterException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ )));
+
+ }
+
+ private static KeyPair generateKeys(String keyalg, int size)
+ throws NoSuchAlgorithmException {
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyalg);
+ kpg.initialize(size);
+ return kpg.generateKeyPair();
+ }
+
+ private static Key[] manipulateKey(int type, Key key)
+ throws NoSuchAlgorithmException, InvalidKeySpecException,
+ NoSuchProviderException {
+ KeyFactory kf = KeyFactory.getInstance(KEYALG, PROVIDER);
+ switch (type) {
+ case PUBLIC_KEY:
+ try {
+ kf.getKeySpec(key, RSAPrivateKeySpec.class);
+ throw new RuntimeException("Expected InvalidKeySpecException"
+ + " not thrown");
+ } catch (InvalidKeySpecException expected) {
+ System.out.println("Expected IKSE thrown for PublicKey");
+ }
+ return new Key[]{
+ kf.generatePublic(kf.getKeySpec(key, RSAPublicKeySpec.class)),
+ kf.generatePublic(new X509EncodedKeySpec(key.getEncoded())),
+ kf.generatePublic(new RSAPublicKeySpec(
+ ((RSAPublicKey)key).getModulus(),
+ ((RSAPublicKey)key).getPublicExponent(),
+ ((RSAPublicKey)key).getParams()))
+ };
+ case PRIVATE_KEY:
+ try {
+ kf.getKeySpec(key, RSAPublicKeySpec.class);
+ throw new RuntimeException("Expected InvalidKeySpecException"
+ + " not thrown");
+ } catch (InvalidKeySpecException expected) {
+ System.out.println("Expected IKSE thrown for PrivateKey");
+ }
+ return new Key[]{
+ kf.generatePrivate(kf.getKeySpec(key, RSAPrivateKeySpec.class)),
+ kf.generatePrivate(new PKCS8EncodedKeySpec(key.getEncoded())),
+ kf.generatePrivate(new RSAPrivateKeySpec(
+ ((RSAPrivateKey)key).getModulus(),
+ ((RSAPrivateKey)key).getPrivateExponent(),
+ ((RSAPrivateKey)key).getParams()))
+ };
+ }
+ throw new RuntimeException("We shouldn't reach here");
+ }
+
+ private static void checkSignature(byte[] data, PublicKey pub,
+ PrivateKey priv, String mdAlg) throws NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException, NoSuchProviderException,
+ InvalidAlgorithmParameterException {
+ System.out.println("Testing against " + mdAlg);
+ Signature sig = Signature.getInstance
+ (SignatureType.RSASSA_PSS.toString(), PROVIDER);
+ AlgorithmParameterSpec params =
+ SigTestUtil.generateDefaultParameter(SignatureType.RSASSA_PSS, mdAlg);
+ sig.setParameter(params);
+ sig.initSign(priv);
+ for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) {
+ sig.update(data);
+ }
+ byte[] signedData = sig.sign();
+
+ // Make sure signature verifies with original data
+ // do we need to call sig.setParameter(params) again?
+ sig.initVerify(pub);
+ for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) {
+ sig.update(data);
+ }
+ if (!sig.verify(signedData)) {
+ throw new RuntimeException("Failed to verify signature");
+ }
+
+ // Make sure signature does NOT verify when the original data
+ // has changed
+ sig.initVerify(pub);
+ for (int i = 0; i < UPDATE_TIMES_FIFTY; i++) {
+ sig.update(data);
+ }
+
+ if (sig.verify(signedData)) {
+ throw new RuntimeException("Failed to detect bad signature");
+ }
+ }
+}
diff --git a/jdk/test/sun/security/rsa/pss/TestPSSKeySupport.java b/jdk/test/sun/security/rsa/pss/TestPSSKeySupport.java
new file mode 100644
index 0000000..0a27553
--- /dev/null
+++ b/jdk/test/sun/security/rsa/pss/TestPSSKeySupport.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8146293
+ * @summary Test RSASSA-PSS Key related support such as KeyPairGenerator
+ * and KeyFactory of the SunRsaSign provider
+ */
+
+import java.io.*;
+import java.util.*;
+import java.math.BigInteger;
+
+import java.security.*;
+import java.security.interfaces.*;
+import java.security.spec.*;
+
+public class TestPSSKeySupport {
+
+ private static final String ALGO = "RSASSA-PSS";
+
+ /**
+ * Test that key1 (reference key) and key2 (key to be tested) are
+ * equivalent
+ */
+ private static void testKey(Key key1, Key key2) throws Exception {
+ if (key2.getAlgorithm().equals(ALGO) == false) {
+ throw new Exception("Algorithm not " + ALGO);
+ }
+ if (key1 instanceof PublicKey) {
+ if (key2.getFormat().equals("X.509") == false) {
+ throw new Exception("Format not X.509");
+ }
+ } else if (key1 instanceof PrivateKey) {
+ if (key2.getFormat().equals("PKCS#8") == false) {
+ throw new Exception("Format not PKCS#8");
+ }
+ }
+ if (key1.equals(key2) == false) {
+ throw new Exception("Keys not equal");
+ }
+ if (Arrays.equals(key1.getEncoded(), key2.getEncoded()) == false) {
+ throw new Exception("Encodings not equal");
+ }
+ }
+
+ private static void testPublic(KeyFactory kf, PublicKey key) throws Exception {
+ System.out.println("Testing public key...");
+ PublicKey key2 = (PublicKey)kf.translateKey(key);
+ KeySpec rsaSpec = kf.getKeySpec(key, RSAPublicKeySpec.class);
+ PublicKey key3 = kf.generatePublic(rsaSpec);
+ KeySpec x509Spec = kf.getKeySpec(key, X509EncodedKeySpec.class);
+ PublicKey key4 = kf.generatePublic(x509Spec);
+ KeySpec x509Spec2 = new X509EncodedKeySpec(key.getEncoded());
+ PublicKey key5 = kf.generatePublic(x509Spec2);
+ testKey(key, key);
+ testKey(key, key2);
+ testKey(key, key3);
+ testKey(key, key4);
+ testKey(key, key5);
+ }
+
+ private static void testPrivate(KeyFactory kf, PrivateKey key) throws Exception {
+ System.out.println("Testing private key...");
+ PrivateKey key2 = (PrivateKey)kf.translateKey(key);
+ KeySpec rsaSpec = kf.getKeySpec(key, RSAPrivateCrtKeySpec.class);
+ PrivateKey key3 = kf.generatePrivate(rsaSpec);
+ KeySpec pkcs8Spec = kf.getKeySpec(key, PKCS8EncodedKeySpec.class);
+ PrivateKey key4 = kf.generatePrivate(pkcs8Spec);
+ KeySpec pkcs8Spec2 = new PKCS8EncodedKeySpec(key.getEncoded());
+ PrivateKey key5 = kf.generatePrivate(pkcs8Spec2);
+ testKey(key, key);
+ testKey(key, key2);
+ testKey(key, key3);
+ testKey(key, key4);
+ testKey(key, key5);
+
+ KeySpec rsaSpec2 = kf.getKeySpec(key, RSAPrivateKeySpec.class);
+ PrivateKey key6 = kf.generatePrivate(rsaSpec2);
+ RSAPrivateKey rsaKey = (RSAPrivateKey)key;
+ KeySpec rsaSpec3 = new RSAPrivateKeySpec(rsaKey.getModulus(),
+ rsaKey.getPrivateExponent(), rsaKey.getParams());
+ PrivateKey key7 = kf.generatePrivate(rsaSpec3);
+ testKey(key6, key6);
+ testKey(key6, key7);
+ }
+
+ private static void test(KeyFactory kf, Key key) throws Exception {
+ if (key.getAlgorithm().equals(ALGO) == false) {
+ throw new Exception("Error: key algo should be " + ALGO);
+ }
+ if (key instanceof PublicKey) {
+ testPublic(kf, (PublicKey)key);
+ } else if (key instanceof PrivateKey) {
+ testPrivate(kf, (PrivateKey)key);
+ }
+ }
+
+ private static void checkKeyPair(KeyPair kp) throws Exception {
+ PublicKey pubKey = kp.getPublic();
+ if (!(pubKey instanceof RSAPublicKey)) {
+ throw new Exception("Error: public key should be RSAPublicKey");
+ }
+ PrivateKey privKey = kp.getPrivate();
+ if (!(privKey instanceof RSAPrivateKey)) {
+ throw new Exception("Error: private key should be RSAPrivateKey");
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ KeyPairGenerator kpg =
+ KeyPairGenerator.getInstance(ALGO, "SunRsaSign");
+
+ // Algorithm-Independent Initialization
+ kpg.initialize(2048);
+ KeyPair kp = kpg.generateKeyPair();
+ checkKeyPair(kp);
+ BigInteger pubExp = ((RSAPublicKey)kp.getPublic()).getPublicExponent();
+
+ // Algorithm-specific Initialization
+ PSSParameterSpec params = new PSSParameterSpec("SHA-256", "MGF1",
+ MGF1ParameterSpec.SHA256, 32, 1);
+ kpg.initialize(new RSAKeyGenParameterSpec(2048, pubExp, params));
+ KeyPair kp2 = kpg.generateKeyPair();
+ checkKeyPair(kp2);
+
+ KeyFactory kf = KeyFactory.getInstance(ALGO, "SunRsaSign");
+ test(kf, kp.getPublic());
+ test(kf, kp.getPrivate());
+ }
+}
diff --git a/jdk/test/sun/security/rsa/pss/TestSigGenPSS.java b/jdk/test/sun/security/rsa/pss/TestSigGenPSS.java
new file mode 100644
index 0000000..2dd65e4
--- /dev/null
+++ b/jdk/test/sun/security/rsa/pss/TestSigGenPSS.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.security.*;
+import java.security.spec.*;
+import java.security.interfaces.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/*
+ * @test
+ * @bug 8146293
+ * @summary Known Answer Tests based on NIST 186-3 at:
+ * @compile SigRecord.java
+ * @run main/othervm TestSigGenPSS
+ */
+public class TestSigGenPSS {
+
+ private static final String[] testFiles = {
+ "SigGenPSS_186-3.txt", "SigGenPSS_186-3_TruncatedSHAs.txt"
+ };
+
+ static final class MyKnownRandomSrc extends SecureRandom {
+ final byte[] srcBytes;
+ int numBytes;
+
+ MyKnownRandomSrc(String srcString) {
+ this.srcBytes = SigRecord.toByteArray(srcString);
+ this.numBytes = this.srcBytes.length;
+ }
+ @Override
+ public void nextBytes(byte[] bytes) {
+ if (bytes.length > numBytes) {
+ throw new RuntimeException("Not enough bytes, need "
+ + bytes.length + ", got " + numBytes);
+ }
+ System.arraycopy(this.srcBytes, this.srcBytes.length - numBytes, bytes, 0, bytes.length);
+ numBytes -= bytes.length;
+ }
+
+ }
+
+ public static void main(String[] args) throws Exception {
+ //for (Provider provider : Security.getProviders()) {
+ Provider p = Security.getProvider("SunRsaSign");
+ Signature sig;
+ try {
+ sig = Signature.getInstance("RSASSA-PSS", p);
+ } catch (NoSuchAlgorithmException e) {
+ System.out.println("Skip testing RSASSA-PSS" +
+ " due to no support");
+ return;
+ }
+
+ boolean success = true;
+ for (String f : testFiles) {
+ System.out.println("[INPUT FILE " + f + "]");
+ try {
+ success &= runTest(SigRecord.read(f), sig);
+ } catch (IOException e) {
+ System.out.println("Unexpected exception: " + e);
+ e.printStackTrace(System.out);
+ success = false;
+ }
+ }
+
+ if (!success) {
+ throw new RuntimeException("One or more test failed");
+ }
+ System.out.println("Test passed");
+ }
+
+ /*
+ * Run all the tests in the data list with specified algorithm
+ */
+ static boolean runTest(List<SigRecord> records, Signature sig) throws Exception {
+ boolean success = true;
+ KeyFactory kf = KeyFactory.getInstance("RSA", sig.getProvider());
+ for (SigRecord sr : records) {
+ System.out.println("==Testing Record : " + sr + "==");
+ PrivateKey privKey = kf.generatePrivate(sr.privKeySpec);
+ PublicKey pubKey = kf.generatePublic(sr.pubKeySpec);
+ success &= check(sig, privKey, pubKey, sr.testVectors);
+ System.out.println("==Done==");
+ }
+ return success;
+ }
+
+ /*
+ * Generate the signature, check against known values and verify.
+ */
+ static boolean check(Signature sig, PrivateKey privKey, PublicKey pubKey,
+ List<SigRecord.SigVector> vectors) throws Exception {
+
+ boolean success = true;
+ for (SigRecord.SigVector v : vectors) {
+ System.out.println("\tAgainst " + v.mdAlg);
+ byte[] msgBytes = SigRecord.toByteArray(v.msg);
+ byte[] expSigBytes = SigRecord.toByteArray(v.sig);
+
+ MyKnownRandomSrc saltSrc = new MyKnownRandomSrc(v.salt);
+ sig.initSign(privKey, saltSrc);
+ PSSParameterSpec params = new PSSParameterSpec(v.mdAlg, "MGF1",
+ new MGF1ParameterSpec(v.mdAlg), saltSrc.numBytes, 1);
+ sig.setParameter(params);
+ sig.update(msgBytes);
+ byte[] actualSigBytes = sig.sign();
+
+ // Check if the supplied salt bytes are used up
+ if (saltSrc.numBytes != 0) {
+ throw new RuntimeException("Error: salt length mismatch! "
+ + saltSrc.numBytes + " bytes leftover");
+ }
+
+ success &= MessageDigest.isEqual(actualSigBytes, expSigBytes);
+
+ if (!success) {
+ System.out.println("\tFailed:");
+ System.out.println("\tSHAALG = " + v.mdAlg);
+ System.out.println("\tMsg = " + v.msg);
+ System.out.println("\tSalt = " + v.salt);
+ System.out.println("\tExpected Sig = " + v.sig);
+ System.out.println("\tActual Sig = " + SigRecord.toHexString(actualSigBytes));
+ } else {
+ System.out.println("\t" + v.mdAlg + " Test Vector Passed");
+ }
+ }
+ return success;
+ }
+}
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/ALPN/MyX509ExtendedKeyManager.java b/jdk/test/sun/security/ssl/javax/net/ssl/ALPN/MyX509ExtendedKeyManager.java
new file mode 100644
index 0000000..a32e68d
--- /dev/null
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/ALPN/MyX509ExtendedKeyManager.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.net.Socket;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.X509ExtendedKeyManager;
+
+public class MyX509ExtendedKeyManager extends X509ExtendedKeyManager {
+
+ static final String ERROR = "ERROR";
+ X509ExtendedKeyManager akm;
+ String expectedAP;
+ boolean doCheck = true;
+
+ MyX509ExtendedKeyManager(X509ExtendedKeyManager akm) {
+ this.akm = akm;
+ }
+
+ public MyX509ExtendedKeyManager(
+ X509ExtendedKeyManager akm, String expectedAP, boolean doCheck) {
+ this.akm = akm;
+ this.expectedAP = expectedAP;
+ this.doCheck = doCheck;
+
+ }
+
+ @Override
+ public String[] getClientAliases(String keyType, Principal[] issuers) {
+ return akm.getClientAliases(keyType, issuers);
+ }
+
+ @Override
+ public String chooseClientAlias(String[] keyType, Principal[] issuers,
+ Socket socket) {
+ String nap = ((SSLSocket) socket).getHandshakeApplicationProtocol();
+ checkALPN(nap);
+
+ return akm.chooseClientAlias(keyType, issuers, socket);
+ }
+
+ @Override
+ public String[] getServerAliases(String keyType, Principal[] issuers) {
+ return akm.getServerAliases(keyType, issuers);
+ }
+
+ @Override
+ public String chooseServerAlias(String keyType, Principal[] issuers,
+ Socket socket) {
+ String nap = ((SSLSocket) socket).getHandshakeApplicationProtocol();
+ checkALPN(nap);
+
+ return akm.chooseServerAlias(keyType, issuers, socket);
+ }
+
+ @Override
+ public X509Certificate[] getCertificateChain(String alias) {
+ return akm.getCertificateChain(alias);
+ }
+
+ @Override
+ public PrivateKey getPrivateKey(String alias) {
+ return akm.getPrivateKey(alias);
+ }
+
+ @Override
+ public String chooseEngineClientAlias(String[] keyType, Principal[] issuers,
+ SSLEngine engine) {
+ String nap = engine.getHandshakeApplicationProtocol();
+ checkALPN(nap);
+
+ return akm.chooseEngineClientAlias(keyType, issuers, engine);
+ }
+
+ @Override
+ public String chooseEngineServerAlias(String keyType, Principal[] issuers,
+ SSLEngine engine) {
+ String nap = engine.getHandshakeApplicationProtocol();
+ checkALPN(nap);
+
+ return akm.chooseEngineServerAlias(keyType, issuers, engine);
+ }
+
+ private void checkALPN(String ap) {
+
+ if (!doCheck) {
+ System.out.println("Skipping KeyManager checks " +
+ "because a callback has been registered");
+ return;
+ }
+
+ if (ERROR.equals(expectedAP)) {
+ throw new RuntimeException("Should not reach here");
+ }
+
+ System.out.println("Expected ALPN value: " + expectedAP
+ + " Got: " + ap);
+
+ if (ap == null) {
+ throw new RuntimeException(
+ "ALPN should be negotiated, but null was received");
+ }
+ if (expectedAP.equals("NONE")) {
+ if (!ap.isEmpty()) {
+ throw new RuntimeException("Expected no ALPN value");
+ } else {
+ System.out.println("No ALPN value negotiated, as expected");
+ }
+ } else if (!expectedAP.equals(ap)) {
+ throw new RuntimeException(expectedAP
+ + " ALPN value not available on negotiated connection");
+ }
+
+ }
+}
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/ALPN/SSLEngineAlpnTest.java b/jdk/test/sun/security/ssl/javax/net/ssl/ALPN/SSLEngineAlpnTest.java
new file mode 100644
index 0000000..15f332b
--- /dev/null
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/ALPN/SSLEngineAlpnTest.java
@@ -0,0 +1,583 @@
+/*
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+
+/*
+ * @test
+ * @bug 8051498 8145849 8170282
+ * @summary JEP 244: TLS Application-Layer Protocol Negotiation Extension
+ * @compile MyX509ExtendedKeyManager.java
+ *
+ * @run main/othervm SSLEngineAlpnTest h2 UNUSED h2 h2
+ * @run main/othervm SSLEngineAlpnTest h2 UNUSED h2,http/1.1 h2
+ * @run main/othervm SSLEngineAlpnTest h2,http/1.1 UNUSED h2,http/1.1 h2
+ * @run main/othervm SSLEngineAlpnTest http/1.1,h2 UNUSED h2,http/1.1 http/1.1
+ * @run main/othervm SSLEngineAlpnTest h4,h3,h2 UNUSED h1,h2 h2
+ * @run main/othervm SSLEngineAlpnTest EMPTY UNUSED h2,http/1.1 NONE
+ * @run main/othervm SSLEngineAlpnTest h2 UNUSED EMPTY NONE
+ * @run main/othervm SSLEngineAlpnTest H2 UNUSED h2 ERROR
+ * @run main/othervm SSLEngineAlpnTest h2 UNUSED http/1.1 ERROR
+ *
+ * @run main/othervm SSLEngineAlpnTest UNUSED h2 h2 h2
+ * @run main/othervm SSLEngineAlpnTest UNUSED h2 h2,http/1.1 h2
+ * @run main/othervm SSLEngineAlpnTest UNUSED h2 http/1.1,h2 h2
+ * @run main/othervm SSLEngineAlpnTest UNUSED http/1.1 h2,http/1.1 http/1.1
+ * @run main/othervm SSLEngineAlpnTest UNUSED EMPTY h2,http/1.1 NONE
+ * @run main/othervm SSLEngineAlpnTest UNUSED h2 EMPTY NONE
+ * @run main/othervm SSLEngineAlpnTest UNUSED H2 h2 ERROR
+ * @run main/othervm SSLEngineAlpnTest UNUSED h2 http/1.1 ERROR
+ *
+ * @run main/othervm SSLEngineAlpnTest h2 h2 h2 h2
+ * @run main/othervm SSLEngineAlpnTest H2 h2 h2,http/1.1 h2
+ * @run main/othervm SSLEngineAlpnTest h2,http/1.1 http/1.1 h2,http/1.1 http/1.1
+ * @run main/othervm SSLEngineAlpnTest http/1.1,h2 h2 h2,http/1.1 h2
+ * @run main/othervm SSLEngineAlpnTest EMPTY h2 h2 h2
+ * @run main/othervm SSLEngineAlpnTest h2,http/1.1 EMPTY http/1.1 NONE
+ * @run main/othervm SSLEngineAlpnTest h2,http/1.1 h2 EMPTY NONE
+ * @run main/othervm SSLEngineAlpnTest UNUSED UNUSED http/1.1,h2 NONE
+ * @run main/othervm SSLEngineAlpnTest h2 h2 http/1.1 ERROR
+ * @run main/othervm SSLEngineAlpnTest h2,http/1.1 H2 http/1.1 ERROR
+ */
+/**
+ * A simple SSLEngine-based client/server that demonstrates the proposed API
+ * changes for JEP 244 in support of the TLS ALPN extension (RFC 7301).
+ *
+ * Usage:
+ * java SSLEngineAlpnTest <server-APs> <callback-AP> <client-APs> <result>
+ *
+ * where:
+ * EMPTY indicates that ALPN is disabled
+ * UNUSED indicates that no ALPN values are supplied (server-side only)
+ * ERROR indicates that an exception is expected
+ * NONE indicates that no ALPN is expected
+ *
+ * This example is based on our standard SSLEngineTemplate.
+ *
+ * The immediate consumer of ALPN will be HTTP/2 (RFC 7540), aka H2. The H2 IETF
+ * Working Group wanted to use TLSv1.3+ as the secure transport mechanism, but
+ * TLSv1.3 wasn't ready. The H2 folk agreed to a compromise that only TLSv1.2+
+ * can be used, and that if TLSv1.2 was selected, non-TLSv.1.3-approved
+ * ciphersuites would be blacklisted and their use discouraged.
+ *
+ * In order to support connections that might negotiate either HTTP/1.1 and H2,
+ * the guidance from the IETF Working Group is that the H2 ciphersuites be
+ * prioritized/tried first.
+ */
+
+/*
+ * The original SSLEngineTemplate comments follow.
+ *
+ * A SSLEngine usage example which simplifies the presentation
+ * by removing the I/O and multi-threading concerns.
+ *
+ * The test creates two SSLEngines, simulating a client and server.
+ * The "transport" layer consists two byte buffers: think of them
+ * as directly connected pipes.
+ *
+ * Note, this is a *very* simple example: real code will be much more
+ * involved. For example, different threading and I/O models could be
+ * used, transport mechanisms could close unexpectedly, and so on.
+ *
+ * When this application runs, notice that several messages
+ * (wrap/unwrap) pass before any application data is consumed or
+ * produced. (For more information, please see the SSL/TLS
+ * specifications.) There may several steps for a successful handshake,
+ * so it's typical to see the following series of operations:
+ *
+ * client server message
+ * ====== ====== =======
+ * wrap() ... ClientHello
+ * ... unwrap() ClientHello
+ * ... wrap() ServerHello/Certificate
+ * unwrap() ... ServerHello/Certificate
+ * wrap() ... ClientKeyExchange
+ * wrap() ... ChangeCipherSpec
+ * wrap() ... Finished
+ * ... unwrap() ClientKeyExchange
+ * ... unwrap() ChangeCipherSpec
+ * ... unwrap() Finished
+ * ... wrap() ChangeCipherSpec
+ * ... wrap() Finished
+ * unwrap() ... ChangeCipherSpec
+ * unwrap() ... Finished
+ */
+import javax.net.ssl.*;
+import javax.net.ssl.SSLEngineResult.*;
+import java.io.*;
+import java.security.*;
+import java.nio.*;
+import java.util.Arrays;
+
+public class SSLEngineAlpnTest {
+
+ /*
+ * Enables logging of the SSLEngine operations.
+ */
+ private static final boolean logging = true;
+
+ /*
+ * Enables the JSSE system debugging system property:
+ *
+ * -Djavax.net.debug=all
+ *
+ * This gives a lot of low-level information about operations underway,
+ * including specific handshake messages, and might be best examined
+ * after gaining some familiarity with this application.
+ */
+ private static final boolean debug = false;
+
+ private static boolean hasServerAPs; // whether server APs are present
+ private static boolean hasCallback; // whether a callback is present
+
+ private final SSLContext sslc;
+
+ private SSLEngine clientEngine; // client Engine
+ private ByteBuffer clientOut; // write side of clientEngine
+ private ByteBuffer clientIn; // read side of clientEngine
+
+ private SSLEngine serverEngine; // server Engine
+ private ByteBuffer serverOut; // write side of serverEngine
+ private ByteBuffer serverIn; // read side of serverEngine
+
+ /*
+ * For data transport, this example uses local ByteBuffers. This
+ * isn't really useful, but the purpose of this example is to show
+ * SSLEngine concepts, not how to do network transport.
+ */
+ private ByteBuffer cTOs; // "reliable" transport client->server
+ private ByteBuffer sTOc; // "reliable" transport server->client
+
+ /*
+ * The following is to set up the keystores.
+ */
+ private static final String pathToStores = "../../../../etc";
+ private static final String keyStoreFile = "keystore";
+ private static final String trustStoreFile = "truststore";
+ private static final String passwd = "passphrase";
+
+ private static final String keyFilename
+ = System.getProperty("test.src", ".") + "/" + pathToStores
+ + "/" + keyStoreFile;
+ private static final String trustFilename
+ = System.getProperty("test.src", ".") + "/" + pathToStores
+ + "/" + trustStoreFile;
+
+ /*
+ * Main entry point for this test.
+ */
+ public static void main(String args[]) throws Exception {
+ if (debug) {
+ System.setProperty("javax.net.debug", "all");
+ }
+ System.out.println("Test args: " + Arrays.toString(args));
+
+ // Validate parameters
+ if (args.length != 4) {
+ throw new Exception("Invalid number of test parameters");
+ }
+
+ hasServerAPs = !args[0].equals("UNUSED"); // are server APs being used?
+ hasCallback = !args[1].equals("UNUSED"); // is callback being used?
+
+ SSLEngineAlpnTest test = new SSLEngineAlpnTest(args[3]);
+ try {
+ test.runTest(convert(args[0]), args[1], convert(args[2]), args[3]);
+ } catch (SSLHandshakeException she) {
+ if (args[3].equals("ERROR")) {
+ System.out.println("Caught the expected exception: " + she);
+ } else {
+ throw she;
+ }
+ }
+
+ System.out.println("Test Passed.");
+ }
+
+ /*
+ * Create an initialized SSLContext to use for these tests.
+ */
+ public SSLEngineAlpnTest(String expectedAP) throws Exception {
+
+ KeyStore ks = KeyStore.getInstance("JKS");
+ KeyStore ts = KeyStore.getInstance("JKS");
+
+ char[] passphrase = "passphrase".toCharArray();
+
+ ks.load(new FileInputStream(keyFilename), passphrase);
+ ts.load(new FileInputStream(trustFilename), passphrase);
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(ks, passphrase);
+
+ KeyManager [] kms = kmf.getKeyManagers();
+ if (!(kms[0] instanceof X509ExtendedKeyManager)) {
+ throw new Exception("kms[0] not X509ExtendedKeyManager");
+ }
+
+ kms = new KeyManager[] { new MyX509ExtendedKeyManager(
+ (X509ExtendedKeyManager) kms[0], expectedAP,
+ !hasCallback && hasServerAPs) };
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(ts);
+
+ SSLContext sslCtx = SSLContext.getInstance("TLS");
+
+ sslCtx.init(kms, tmf.getTrustManagers(), null);
+
+ sslc = sslCtx;
+ }
+
+ /*
+ * Convert a comma-separated list into an array of strings.
+ */
+ private static String[] convert(String list) {
+ if (list.equals("UNUSED")) {
+ return null;
+ }
+
+ if (list.equals("EMPTY")) {
+ return new String[0];
+ }
+
+ String[] strings;
+ if (list.indexOf(',') > 0) {
+ strings = list.split(",");
+ } else {
+ strings = new String[]{ list };
+ }
+
+ return strings;
+ }
+
+ /*
+ * Run the test.
+ *
+ * Sit in a tight loop, both engines calling wrap/unwrap regardless
+ * of whether data is available or not. We do this until both engines
+ * report back they are closed.
+ *
+ * The main loop handles all of the I/O phases of the SSLEngine's
+ * lifetime:
+ *
+ * initial handshaking
+ * application data transfer
+ * engine closing
+ *
+ * One could easily separate these phases into separate
+ * sections of code.
+ */
+ private void runTest(String[] serverAPs, String callbackAP,
+ String[] clientAPs, String expectedAP) throws Exception {
+
+ boolean dataDone = false;
+
+ createSSLEngines(serverAPs, callbackAP, clientAPs);
+ createBuffers();
+
+ SSLEngineResult clientResult; // results from client's last operation
+ SSLEngineResult serverResult; // results from server's last operation
+
+ /*
+ * Examining the SSLEngineResults could be much more involved,
+ * and may alter the overall flow of the application.
+ *
+ * For example, if we received a BUFFER_OVERFLOW when trying
+ * to write to the output pipe, we could reallocate a larger
+ * pipe, but instead we wait for the peer to drain it.
+ */
+ while (!isEngineClosed(clientEngine)
+ || !isEngineClosed(serverEngine)) {
+
+ log("================");
+
+ clientResult = clientEngine.wrap(clientOut, cTOs);
+ log("client wrap: ", clientResult);
+ runDelegatedTasks(clientResult, clientEngine);
+ checkAPResult(clientEngine, clientResult, expectedAP);
+
+ serverResult = serverEngine.wrap(serverOut, sTOc);
+ log("server wrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ checkAPResult(serverEngine, serverResult, expectedAP);
+
+ cTOs.flip();
+ sTOc.flip();
+
+ log("----");
+
+ clientResult = clientEngine.unwrap(sTOc, clientIn);
+ log("client unwrap: ", clientResult);
+ runDelegatedTasks(clientResult, clientEngine);
+ checkAPResult(clientEngine, clientResult, expectedAP);
+
+ serverResult = serverEngine.unwrap(cTOs, serverIn);
+ log("server unwrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ checkAPResult(serverEngine, serverResult, expectedAP);
+
+ cTOs.compact();
+ sTOc.compact();
+
+ /*
+ * After we've transfered all application data between the client
+ * and server, we close the clientEngine's outbound stream.
+ * This generates a close_notify handshake message, which the
+ * server engine receives and responds by closing itself.
+ */
+ if (!dataDone && (clientOut.limit() == serverIn.position())
+ && (serverOut.limit() == clientIn.position())) {
+
+ /*
+ * A sanity check to ensure we got what was sent.
+ */
+ checkTransfer(serverOut, clientIn);
+ checkTransfer(clientOut, serverIn);
+
+ log("\tClosing clientEngine's *OUTBOUND*...");
+ clientEngine.closeOutbound();
+ dataDone = true;
+ }
+ }
+ }
+
+ /*
+ * Check that the resulting connection meets our defined ALPN
+ * criteria. If we were connecting to a non-JSSE implementation,
+ * the server might have negotiated something we shouldn't accept.
+ *
+ * If we were expecting an ALPN value from server, let's make sure
+ * the conditions match.
+ */
+ private static void checkAPResult(SSLEngine engine, SSLEngineResult result,
+ String expectedAP) throws Exception {
+
+ if (result.getHandshakeStatus() != HandshakeStatus.FINISHED) {
+ return;
+ }
+
+ if (engine.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null after the handshake is completed");
+ }
+
+ String ap = engine.getApplicationProtocol();
+ System.out.println("Application Protocol: \"" + ap + "\"");
+
+ if (ap == null) {
+ throw new Exception(
+ "Handshake was completed but null was received");
+ }
+ if (expectedAP.equals("NONE")) {
+ if (!ap.isEmpty()) {
+ throw new Exception("Expected no ALPN value");
+ } else {
+ System.out.println("No ALPN value negotiated, as expected");
+ }
+ } else if (!expectedAP.equals(ap)) {
+ throw new Exception(expectedAP +
+ " ALPN value not available on negotiated connection");
+ }
+ }
+
+ /*
+ * Using the SSLContext created during object creation,
+ * create/configure the SSLEngines we'll use for this test.
+ */
+ private void createSSLEngines(String[] serverAPs, String callbackAP,
+ String[] clientAPs) throws Exception {
+ /*
+ * Configure the serverEngine to act as a server in the SSL/TLS
+ * handshake. Also, require SSL client authentication.
+ */
+ serverEngine = sslc.createSSLEngine();
+ serverEngine.setUseClientMode(false);
+
+ SSLParameters sslp = serverEngine.getSSLParameters();
+
+ sslp.setNeedClientAuth(true);
+
+ /*
+ * The default ciphersuite ordering from the SSLContext may not
+ * reflect "h2" ciphersuites as being preferred, additionally the
+ * client may not send them in an appropriate order. We could resort
+ * the suite list if so desired.
+ */
+ String[] suites = sslp.getCipherSuites();
+ sslp.setCipherSuites(suites);
+ if (serverAPs != null) {
+ sslp.setApplicationProtocols(serverAPs);
+ }
+ sslp.setUseCipherSuitesOrder(true); // Set server side order
+
+ serverEngine.setSSLParameters(sslp);
+
+ // check that no callback has been registered
+ if (serverEngine.getHandshakeApplicationProtocolSelector() != null) {
+ throw new Exception("getHandshakeApplicationProtocolSelector() " +
+ "should return null");
+ }
+
+ if (hasCallback) {
+ serverEngine.setHandshakeApplicationProtocolSelector(
+ (sslEngine, clientProtocols) -> {
+ return callbackAP.equals("EMPTY") ? "" : callbackAP;
+ });
+
+ // check that the callback can be retrieved
+ if (serverEngine.getHandshakeApplicationProtocolSelector()
+ == null) {
+ throw new Exception("getHandshakeApplicationProtocolSelector()"
+ + " should return non-null");
+ }
+ }
+
+ /*
+ * Similar to above, but using client mode instead.
+ */
+ clientEngine = sslc.createSSLEngine("client", 80);
+ clientEngine.setUseClientMode(true);
+ sslp = clientEngine.getSSLParameters();
+ if (clientAPs != null) {
+ sslp.setApplicationProtocols(clientAPs);
+ }
+ clientEngine.setSSLParameters(sslp);
+
+ if ((clientEngine.getHandshakeApplicationProtocol() != null) ||
+ (serverEngine.getHandshakeApplicationProtocol() != null)) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null before the handshake starts");
+ }
+ }
+
+ /*
+ * Create and size the buffers appropriately.
+ */
+ private void createBuffers() {
+
+ /*
+ * We'll assume the buffer sizes are the same
+ * between client and server.
+ */
+ SSLSession session = clientEngine.getSession();
+ int appBufferMax = session.getApplicationBufferSize();
+ int netBufferMax = session.getPacketBufferSize();
+
+ /*
+ * We'll make the input buffers a bit bigger than the max needed
+ * size, so that unwrap()s following a successful data transfer
+ * won't generate BUFFER_OVERFLOWS.
+ *
+ * We'll use a mix of direct and indirect ByteBuffers for
+ * tutorial purposes only. In reality, only use direct
+ * ByteBuffers when they give a clear performance enhancement.
+ */
+ clientIn = ByteBuffer.allocate(appBufferMax + 50);
+ serverIn = ByteBuffer.allocate(appBufferMax + 50);
+
+ cTOs = ByteBuffer.allocateDirect(netBufferMax);
+ sTOc = ByteBuffer.allocateDirect(netBufferMax);
+
+ clientOut = ByteBuffer.wrap("Hi Server, I'm Client".getBytes());
+ serverOut = ByteBuffer.wrap("Hello Client, I'm Server".getBytes());
+ }
+
+ /*
+ * If the result indicates that we have outstanding tasks to do,
+ * go ahead and run them in this thread.
+ */
+ private static void runDelegatedTasks(SSLEngineResult result,
+ SSLEngine engine) throws Exception {
+
+ if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ Runnable runnable;
+ while ((runnable = engine.getDelegatedTask()) != null) {
+ log("\trunning delegated task...");
+ runnable.run();
+ }
+ HandshakeStatus hsStatus = engine.getHandshakeStatus();
+ if (hsStatus == HandshakeStatus.NEED_TASK) {
+ throw new Exception(
+ "handshake shouldn't need additional tasks");
+ }
+ log("\tnew HandshakeStatus: " + hsStatus);
+ }
+ }
+
+ private static boolean isEngineClosed(SSLEngine engine) {
+ return (engine.isOutboundDone() && engine.isInboundDone());
+ }
+
+ /*
+ * Simple check to make sure everything came across as expected.
+ */
+ private static void checkTransfer(ByteBuffer a, ByteBuffer b)
+ throws Exception {
+ a.flip();
+ b.flip();
+
+ if (!a.equals(b)) {
+ throw new Exception("Data didn't transfer cleanly");
+ } else {
+ log("\tData transferred cleanly");
+ }
+
+ a.position(a.limit());
+ b.position(b.limit());
+ a.limit(a.capacity());
+ b.limit(b.capacity());
+ }
+
+ /*
+ * Logging code
+ */
+ private static boolean resultOnce = true;
+
+ private static void log(String str, SSLEngineResult result) {
+ if (!logging) {
+ return;
+ }
+ if (resultOnce) {
+ resultOnce = false;
+ System.out.println("The format of the SSLEngineResult is: \n"
+ + "\t\"getStatus() / getHandshakeStatus()\" +\n"
+ + "\t\"bytesConsumed() / bytesProduced()\"\n");
+ }
+ HandshakeStatus hsStatus = result.getHandshakeStatus();
+ log(str
+ + result.getStatus() + "/" + hsStatus + ", "
+ + result.bytesConsumed() + "/" + result.bytesProduced()
+ + " bytes");
+ if (hsStatus == HandshakeStatus.FINISHED) {
+ log("\t...ready for application data");
+ }
+ }
+
+ private static void log(String str) {
+ if (logging) {
+ System.out.println(str);
+ }
+ }
+}
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/ALPN/SSLServerSocketAlpnTest.java b/jdk/test/sun/security/ssl/javax/net/ssl/ALPN/SSLServerSocketAlpnTest.java
new file mode 100644
index 0000000..358f9ce
--- /dev/null
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/ALPN/SSLServerSocketAlpnTest.java
@@ -0,0 +1,567 @@
+/*
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+
+/*
+ * @test
+ * @bug 8051498 8145849 8158978 8170282
+ * @summary JEP 244: TLS Application-Layer Protocol Negotiation Extension
+ * @compile MyX509ExtendedKeyManager.java
+ *
+ * @run main/othervm SSLServerSocketAlpnTest h2 UNUSED h2 h2
+ * @run main/othervm SSLServerSocketAlpnTest h2 UNUSED h2,http/1.1 h2
+ * @run main/othervm SSLServerSocketAlpnTest h2,http/1.1 UNUSED h2,http/1.1 h2
+ * @run main/othervm SSLServerSocketAlpnTest http/1.1,h2 UNUSED h2,http/1.1 http/1.1
+ * @run main/othervm SSLServerSocketAlpnTest h4,h3,h2 UNUSED h1,h2 h2
+ * @run main/othervm SSLServerSocketAlpnTest EMPTY UNUSED h2,http/1.1 NONE
+ * @run main/othervm SSLServerSocketAlpnTest h2 UNUSED EMPTY NONE
+ * @run main/othervm SSLServerSocketAlpnTest H2 UNUSED h2 ERROR
+ * @run main/othervm SSLServerSocketAlpnTest h2 UNUSED http/1.1 ERROR
+ *
+ * @run main/othervm SSLServerSocketAlpnTest UNUSED h2 h2 h2
+ * @run main/othervm SSLServerSocketAlpnTest UNUSED h2 h2,http/1.1 h2
+ * @run main/othervm SSLServerSocketAlpnTest UNUSED h2 http/1.1,h2 h2
+ * @run main/othervm SSLServerSocketAlpnTest UNUSED http/1.1 h2,http/1.1 http/1.1
+ * @run main/othervm SSLServerSocketAlpnTest UNUSED EMPTY h2,http/1.1 NONE
+ * @run main/othervm SSLServerSocketAlpnTest UNUSED h2 EMPTY NONE
+ * @run main/othervm SSLServerSocketAlpnTest UNUSED H2 h2 ERROR
+ * @run main/othervm SSLServerSocketAlpnTest UNUSED h2 http/1.1 ERROR
+ *
+ * @run main/othervm SSLServerSocketAlpnTest h2 h2 h2 h2
+ * @run main/othervm SSLServerSocketAlpnTest H2 h2 h2,http/1.1 h2
+ * @run main/othervm SSLServerSocketAlpnTest h2,http/1.1 http/1.1 h2,http/1.1 http/1.1
+ * @run main/othervm SSLServerSocketAlpnTest http/1.1,h2 h2 h2,http/1.1 h2
+ * @run main/othervm SSLServerSocketAlpnTest EMPTY h2 h2 h2
+ * @run main/othervm SSLServerSocketAlpnTest h2,http/1.1 EMPTY http/1.1 NONE
+ * @run main/othervm SSLServerSocketAlpnTest h2,http/1.1 h2 EMPTY NONE
+ * @run main/othervm SSLServerSocketAlpnTest UNUSED UNUSED http/1.1,h2 NONE
+ * @run main/othervm SSLServerSocketAlpnTest h2 h2 http/1.1 ERROR
+ * @run main/othervm SSLServerSocketAlpnTest h2,http/1.1 H2 http/1.1 ERROR
+ *
+ * @author Brad Wetmore
+ */
+/**
+ * A simple SSLSocket-based client/server that demonstrates the proposed API
+ * changes for JEP 244 in support of the TLS ALPN extension (RFC 7301).
+ *
+ * Usage:
+ * java SSLServerSocketAlpnTest
+ * <server-APs> <callback-AP> <client-APs> <result>
+ *
+ * where:
+ * EMPTY indicates that ALPN is disabled
+ * UNUSED indicates that no ALPN values are supplied (server-side only)
+ * ERROR indicates that an exception is expected
+ * NONE indicates that no ALPN is expected
+ *
+ * This example is based on our standard SSLSocketTemplate.
+ */
+import java.io.*;
+import java.security.KeyStore;
+import java.util.Arrays;
+
+import javax.net.ssl.*;
+
+public class SSLServerSocketAlpnTest {
+
+ /*
+ * =============================================================
+ * Set the various variables needed for the tests, then
+ * specify what tests to run on each side.
+ */
+
+ /*
+ * Should we run the client or server in a separate thread?
+ * Both sides can throw exceptions, but do you have a preference
+ * as to which side should be the main thread.
+ */
+ static boolean separateServerThread = false;
+
+ /*
+ * Where do we find the keystores?
+ */
+ static String pathToStores = "../../../../etc";
+ static String keyStoreFile = "keystore";
+ static String trustStoreFile = "truststore";
+ static String passwd = "passphrase";
+
+ static String keyFilename = System.getProperty("test.src", ".") + "/"
+ + pathToStores + "/" + keyStoreFile;
+ static String trustFilename = System.getProperty("test.src", ".") + "/"
+ + pathToStores + "/" + trustStoreFile;
+
+ private static boolean hasServerAPs; // whether server APs are present
+ private static boolean hasCallback; // whether a callback is present
+
+ /*
+ * SSLContext
+ */
+ SSLContext mySSLContext = null;
+
+ /*
+ * Is the server ready to serve?
+ */
+ volatile static boolean serverReady = false;
+
+ /*
+ * Turn on SSL debugging?
+ */
+ static boolean debug = false;
+
+ static String[] serverAPs;
+ static String callbackAP;
+ static String[] clientAPs;
+ static String expectedAP;
+
+ /*
+ * If the client or server is doing some kind of object creation
+ * that the other side depends on, and that thread prematurely
+ * exits, you may experience a hang. The test harness will
+ * terminate all hung threads after its timeout has expired,
+ * currently 3 minutes by default, but you might try to be
+ * smart about it....
+ */
+
+ /*
+ * Define the server side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doServerSide() throws Exception {
+ SSLServerSocketFactory sslssf = mySSLContext.getServerSocketFactory();
+ SSLServerSocket sslServerSocket
+ = (SSLServerSocket) sslssf.createServerSocket(serverPort);
+ sslServerSocket.setNeedClientAuth(true);
+
+ SSLParameters sslp = sslServerSocket.getSSLParameters();
+
+ // for both client/server to call into X509KM
+ sslp.setNeedClientAuth(true);
+
+ /*
+ * The default ciphersuite ordering from the SSLContext may not
+ * reflect "h2" ciphersuites as being preferred, additionally the
+ * client may not send them in an appropriate order. We could resort
+ * the suite list if so desired.
+ */
+ String[] suites = sslp.getCipherSuites();
+ sslp.setCipherSuites(suites);
+ sslp.setUseCipherSuitesOrder(true); // Set server side order
+
+ // Set the ALPN selection.
+ if (serverAPs != null) {
+ sslp.setApplicationProtocols(serverAPs);
+ }
+ sslServerSocket.setSSLParameters(sslp);
+
+ serverPort = sslServerSocket.getLocalPort();
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+
+ SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
+
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null before the handshake starts");
+ }
+
+ // check that no callback has been registered
+ if (sslSocket.getHandshakeApplicationProtocolSelector() != null) {
+ throw new Exception("getHandshakeApplicationProtocolSelector() " +
+ "should return null");
+ }
+
+ if (hasCallback) {
+ sslSocket.setHandshakeApplicationProtocolSelector(
+ (serverSocket, clientProtocols) -> {
+ return callbackAP.equals("EMPTY") ? "" : callbackAP;
+ });
+
+ // check that the callback can be retrieved
+ if (sslSocket.getHandshakeApplicationProtocolSelector() == null) {
+ throw new Exception("getHandshakeApplicationProtocolSelector()"
+ + " should return non-null");
+ }
+ }
+
+ sslSocket.startHandshake();
+
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null after the handshake is completed");
+ }
+
+ String ap = sslSocket.getApplicationProtocol();
+ System.out.println("Application Protocol: \"" + ap + "\"");
+
+ if (ap == null) {
+ throw new Exception(
+ "Handshake was completed but null was received");
+ }
+ if (expectedAP.equals("NONE")) {
+ if (!ap.isEmpty()) {
+ throw new Exception("Expected no ALPN value");
+ } else {
+ System.out.println("No ALPN value negotiated, as expected");
+ }
+ } else if (!expectedAP.equals(ap)) {
+ throw new Exception(expectedAP
+ + " ALPN value not available on negotiated connection");
+ }
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslIS.read();
+ sslOS.write(85);
+ sslOS.flush();
+
+ sslSocket.close();
+ }
+
+ /*
+ * Define the client side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doClientSide() throws Exception {
+
+ /*
+ * Wait for server to get started.
+ */
+ while (!serverReady) {
+ Thread.sleep(50);
+ }
+
+ SSLSocketFactory sslsf = mySSLContext.getSocketFactory();
+ SSLSocket sslSocket
+ = (SSLSocket) sslsf.createSocket("localhost", serverPort);
+
+ SSLParameters sslp = sslSocket.getSSLParameters();
+
+ /*
+ * The default ciphersuite ordering from the SSLContext may not
+ * reflect "h2" ciphersuites as being preferred, additionally the
+ * client may not send them in an appropriate order. We could resort
+ * the suite list if so desired.
+ */
+ String[] suites = sslp.getCipherSuites();
+ sslp.setCipherSuites(suites);
+ sslp.setUseCipherSuitesOrder(true); // Set server side order
+
+ // Set the ALPN selection.
+ sslp.setApplicationProtocols(clientAPs);
+ sslSocket.setSSLParameters(sslp);
+
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null before the handshake starts");
+ }
+
+ sslSocket.startHandshake();
+
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null after the handshake is completed");
+ }
+
+ /*
+ * Check that the resulting connection meets our defined ALPN
+ * criteria. If we were connecting to a non-JSSE implementation,
+ * the server might have negotiated something we shouldn't accept.
+ */
+ String ap = sslSocket.getApplicationProtocol();
+ System.out.println("Application Protocol: \"" + ap + "\"");
+
+ if (ap == null) {
+ throw new Exception(
+ "Handshake was completed but null was received");
+ }
+ if (expectedAP.equals("NONE")) {
+ if (!ap.isEmpty()) {
+ throw new Exception("Expected no ALPN value");
+ } else {
+ System.out.println("No ALPN value negotiated, as expected");
+ }
+ } else if (!expectedAP.equals(ap)) {
+ throw new Exception(expectedAP
+ + " ALPN value not available on negotiated connection");
+ }
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write(280);
+ sslOS.flush();
+ sslIS.read();
+
+ sslSocket.close();
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+ // use any free port by default
+ volatile int serverPort = 0;
+
+ volatile Exception serverException = null;
+ volatile Exception clientException = null;
+
+ public static void main(String[] args) throws Exception {
+
+ if (debug) {
+ System.setProperty("javax.net.debug", "all");
+ }
+ System.out.println("Test args: " + Arrays.toString(args));
+
+ // Validate parameters
+ if (args.length != 4) {
+ throw new Exception("Invalid number of test parameters");
+ }
+ serverAPs = convert(args[0]);
+ callbackAP = args[1];
+ clientAPs = convert(args[2]);
+ expectedAP = args[3];
+
+ hasServerAPs = !args[0].equals("UNUSED"); // are server APs being used?
+ hasCallback = !callbackAP.equals("UNUSED"); // is callback being used?
+
+ /*
+ * Start the tests.
+ */
+ try {
+ new SSLServerSocketAlpnTest();
+ } catch (SSLHandshakeException she) {
+ if (args[3].equals("ERROR")) {
+ System.out.println("Caught the expected exception: " + she);
+ } else {
+ throw she;
+ }
+ }
+
+ System.out.println("Test Passed.");
+ }
+
+ SSLContext getSSLContext(String keyFilename, String trustFilename)
+ throws Exception {
+ SSLContext ctx = SSLContext.getInstance("TLS");
+
+ // Keystores
+ KeyStore keyKS = KeyStore.getInstance("JKS");
+ keyKS.load(new FileInputStream(keyFilename), passwd.toCharArray());
+
+ KeyStore trustKS = KeyStore.getInstance("JKS");
+ trustKS.load(new FileInputStream(trustFilename), passwd.toCharArray());
+
+ // Generate KeyManager and TrustManager
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(keyKS, passwd.toCharArray());
+
+ KeyManager[] kms = kmf.getKeyManagers();
+ if (!(kms[0] instanceof X509ExtendedKeyManager)) {
+ throw new Exception("kms[0] not X509ExtendedKeyManager");
+ }
+
+ kms = new KeyManager[] { new MyX509ExtendedKeyManager(
+ (X509ExtendedKeyManager) kms[0], expectedAP,
+ !hasCallback && hasServerAPs) };
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(trustKS);
+ TrustManager[] tms = tmf.getTrustManagers();
+
+ // initial SSLContext
+ ctx.init(kms, tms, null);
+
+ return ctx;
+ }
+
+ /*
+ * Convert a comma-separated list into an array of strings.
+ */
+ private static String[] convert(String list) {
+ if (list.equals("UNUSED")) {
+ return null;
+ }
+
+ if (list.equals("EMPTY")) {
+ return new String[0];
+ }
+
+ String[] strings;
+ if (list.indexOf(',') > 0) {
+ strings = list.split(",");
+ } else {
+ strings = new String[]{ list };
+ }
+
+ return strings;
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ SSLServerSocketAlpnTest() throws Exception {
+ Exception startException = null;
+ mySSLContext = getSSLContext(keyFilename, trustFilename);
+ try {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+ } catch (Exception e) {
+ startException = e;
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ if (serverThread != null) {
+ serverThread.join();
+ }
+ } else {
+ if (clientThread != null) {
+ clientThread.join();
+ }
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ * Which side threw the error?
+ */
+ Exception local;
+ Exception remote;
+
+ if (separateServerThread) {
+ remote = serverException;
+ local = clientException;
+ } else {
+ remote = clientException;
+ local = serverException;
+ }
+
+ Exception exception = null;
+
+ /*
+ * Check various exception conditions.
+ */
+ if ((local != null) && (remote != null)) {
+ // If both failed, return the curthread's exception.
+ local.initCause(remote);
+ exception = local;
+ } else if (local != null) {
+ exception = local;
+ } else if (remote != null) {
+ exception = remote;
+ } else if (startException != null) {
+ exception = startException;
+ }
+
+ /*
+ * If there was an exception *AND* a startException,
+ * output it.
+ */
+ if (exception != null) {
+ if (exception != startException && startException != null) {
+ exception.addSuppressed(startException);
+ }
+ throw exception;
+ }
+
+ // Fall-through: no exception to throw!
+ }
+
+ void startServer(boolean newThread) throws Exception {
+ if (newThread) {
+ serverThread = new Thread() {
+ @Override
+ public void run() {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ /*
+ * Our server thread just died.
+ *
+ * Release the client, if not active already...
+ */
+ System.err.println("Server died...");
+ serverReady = true;
+ serverException = e;
+ }
+ }
+ };
+ serverThread.start();
+ } else {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ serverException = e;
+ } finally {
+ serverReady = true;
+ }
+ }
+ }
+
+ void startClient(boolean newThread) throws Exception {
+ if (newThread) {
+ clientThread = new Thread() {
+ @Override
+ public void run() {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ /*
+ * Our client thread just died.
+ */
+ System.err.println("Client died...");
+ clientException = e;
+ }
+ }
+ };
+ clientThread.start();
+ } else {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ clientException = e;
+ }
+ }
+ }
+}
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/ALPN/SSLSocketAlpnTest.java b/jdk/test/sun/security/ssl/javax/net/ssl/ALPN/SSLSocketAlpnTest.java
new file mode 100644
index 0000000..877dbfb
--- /dev/null
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/ALPN/SSLSocketAlpnTest.java
@@ -0,0 +1,563 @@
+/*
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+
+/*
+ * @test
+ * @bug 8051498 8145849 8170282
+ * @summary JEP 244: TLS Application-Layer Protocol Negotiation Extension
+ * @compile MyX509ExtendedKeyManager.java
+ *
+ * @run main/othervm SSLSocketAlpnTest h2 UNUSED h2 h2
+ * @run main/othervm SSLSocketAlpnTest h2 UNUSED h2,http/1.1 h2
+ * @run main/othervm SSLSocketAlpnTest h2,http/1.1 UNUSED h2,http/1.1 h2
+ * @run main/othervm SSLSocketAlpnTest http/1.1,h2 UNUSED h2,http/1.1 http/1.1
+ * @run main/othervm SSLSocketAlpnTest h4,h3,h2 UNUSED h1,h2 h2
+ * @run main/othervm SSLSocketAlpnTest EMPTY UNUSED h2,http/1.1 NONE
+ * @run main/othervm SSLSocketAlpnTest h2 UNUSED EMPTY NONE
+ * @run main/othervm SSLSocketAlpnTest H2 UNUSED h2 ERROR
+ * @run main/othervm SSLSocketAlpnTest h2 UNUSED http/1.1 ERROR
+ *
+ * @run main/othervm SSLSocketAlpnTest UNUSED h2 h2 h2
+ * @run main/othervm SSLSocketAlpnTest UNUSED h2 h2,http/1.1 h2
+ * @run main/othervm SSLSocketAlpnTest UNUSED h2 http/1.1,h2 h2
+ * @run main/othervm SSLSocketAlpnTest UNUSED http/1.1 h2,http/1.1 http/1.1
+ * @run main/othervm SSLSocketAlpnTest UNUSED EMPTY h2,http/1.1 NONE
+ * @run main/othervm SSLSocketAlpnTest UNUSED h2 EMPTY NONE
+ * @run main/othervm SSLSocketAlpnTest UNUSED H2 h2 ERROR
+ * @run main/othervm SSLSocketAlpnTest UNUSED h2 http/1.1 ERROR
+ *
+ * @run main/othervm SSLSocketAlpnTest h2 h2 h2 h2
+ * @run main/othervm SSLSocketAlpnTest H2 h2 h2,http/1.1 h2
+ * @run main/othervm SSLSocketAlpnTest h2,http/1.1 http/1.1 h2,http/1.1 http/1.1
+ * @run main/othervm SSLSocketAlpnTest http/1.1,h2 h2 h2,http/1.1 h2
+ * @run main/othervm SSLSocketAlpnTest EMPTY h2 h2 h2
+ * @run main/othervm SSLSocketAlpnTest h2,http/1.1 EMPTY http/1.1 NONE
+ * @run main/othervm SSLSocketAlpnTest h2,http/1.1 h2 EMPTY NONE
+ * @run main/othervm SSLSocketAlpnTest UNUSED UNUSED http/1.1,h2 NONE
+ * @run main/othervm SSLSocketAlpnTest h2 h2 http/1.1 ERROR
+ * @run main/othervm SSLSocketAlpnTest h2,http/1.1 H2 http/1.1 ERROR
+ *
+ * @author Brad Wetmore
+ */
+/**
+ * A simple SSLSocket-based client/server that demonstrates the proposed API
+ * changes for JEP 244 in support of the TLS ALPN extension (RFC 7301).
+ *
+ * Usage:
+ * java SSLSocketAlpnTest <server-APs> <callback-AP> <client-APs> <result>
+ *
+ * where:
+ * EMPTY indicates that ALPN is disabled
+ * UNUSED indicates that no ALPN values are supplied (server-side only)
+ * ERROR indicates that an exception is expected
+ * NONE indicates that no ALPN is expected
+ *
+ * This example is based on our standard SSLSocketTemplate.
+ */
+import java.io.*;
+import java.security.KeyStore;
+import java.util.Arrays;
+
+import javax.net.ssl.*;
+
+public class SSLSocketAlpnTest {
+
+ /*
+ * =============================================================
+ * Set the various variables needed for the tests, then
+ * specify what tests to run on each side.
+ */
+
+ /*
+ * Should we run the client or server in a separate thread?
+ * Both sides can throw exceptions, but do you have a preference
+ * as to which side should be the main thread.
+ */
+ static boolean separateServerThread = false;
+
+ /*
+ * Where do we find the keystores?
+ */
+ static String pathToStores = "../../../../etc";
+ static String keyStoreFile = "keystore";
+ static String trustStoreFile = "truststore";
+ static String passwd = "passphrase";
+
+ static String keyFilename = System.getProperty("test.src", ".") + "/"
+ + pathToStores + "/" + keyStoreFile;
+ static String trustFilename = System.getProperty("test.src", ".") + "/"
+ + pathToStores + "/" + trustStoreFile;
+
+ private static boolean hasServerAPs; // whether server APs are present
+ private static boolean hasCallback; // whether a callback is present
+
+ /*
+ * SSLContext
+ */
+ SSLContext mySSLContext = null;
+
+ /*
+ * Is the server ready to serve?
+ */
+ volatile static boolean serverReady = false;
+
+ /*
+ * Turn on SSL debugging?
+ */
+ static boolean debug = false;
+
+ static String[] serverAPs;
+ static String callbackAP;
+ static String[] clientAPs;
+ static String expectedAP;
+
+ /*
+ * If the client or server is doing some kind of object creation
+ * that the other side depends on, and that thread prematurely
+ * exits, you may experience a hang. The test harness will
+ * terminate all hung threads after its timeout has expired,
+ * currently 3 minutes by default, but you might try to be
+ * smart about it....
+ */
+
+ /*
+ * Define the server side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doServerSide() throws Exception {
+ SSLServerSocketFactory sslssf = mySSLContext.getServerSocketFactory();
+ SSLServerSocket sslServerSocket
+ = (SSLServerSocket) sslssf.createServerSocket(serverPort);
+ // for both client/server to call into X509KM
+ sslServerSocket.setNeedClientAuth(true);
+
+ serverPort = sslServerSocket.getLocalPort();
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+
+ SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
+
+ SSLParameters sslp = sslSocket.getSSLParameters();
+
+ /*
+ * The default ciphersuite ordering from the SSLContext may not
+ * reflect "h2" ciphersuites as being preferred, additionally the
+ * client may not send them in an appropriate order. We could resort
+ * the suite list if so desired.
+ */
+ String[] suites = sslp.getCipherSuites();
+ sslp.setCipherSuites(suites);
+ sslp.setUseCipherSuitesOrder(true); // Set server side order
+
+ // Set the ALPN selection.
+ if (serverAPs != null) {
+ sslp.setApplicationProtocols(serverAPs);
+ }
+ sslSocket.setSSLParameters(sslp);
+
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null before the handshake starts");
+ }
+
+ // check that no callback has been registered
+ if (sslSocket.getHandshakeApplicationProtocolSelector() != null) {
+ throw new Exception("getHandshakeApplicationProtocolSelector() " +
+ "should return null");
+ }
+
+ if (hasCallback) {
+ sslSocket.setHandshakeApplicationProtocolSelector(
+ (serverSocket, clientProtocols) -> {
+ return callbackAP.equals("EMPTY") ? "" : callbackAP;
+ });
+
+ // check that the callback can be retrieved
+ if (sslSocket.getHandshakeApplicationProtocolSelector() == null) {
+ throw new Exception("getHandshakeApplicationProtocolSelector()" + " should return non-null");
+ }
+ }
+
+ sslSocket.startHandshake();
+
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null after the handshake is completed");
+ }
+
+ String ap = sslSocket.getApplicationProtocol();
+ System.out.println("Application Protocol: \"" + ap + "\"");
+
+ if (ap == null) {
+ throw new Exception(
+ "Handshake was completed but null was received");
+ }
+ if (expectedAP.equals("NONE")) {
+ if (!ap.isEmpty()) {
+ throw new Exception("Expected no ALPN value");
+ } else {
+ System.out.println("No ALPN value negotiated, as expected");
+ }
+ } else if (!expectedAP.equals(ap)) {
+ throw new Exception(expectedAP
+ + " ALPN value not available on negotiated connection");
+ }
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslIS.read();
+ sslOS.write(85);
+ sslOS.flush();
+
+ sslSocket.close();
+ }
+
+ /*
+ * Define the client side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doClientSide() throws Exception {
+
+ /*
+ * Wait for server to get started.
+ */
+ while (!serverReady) {
+ Thread.sleep(50);
+ }
+
+ SSLSocketFactory sslsf = mySSLContext.getSocketFactory();
+ SSLSocket sslSocket
+ = (SSLSocket) sslsf.createSocket("localhost", serverPort);
+
+ SSLParameters sslp = sslSocket.getSSLParameters();
+
+ /*
+ * The default ciphersuite ordering from the SSLContext may not
+ * reflect "h2" ciphersuites as being preferred, additionally the
+ * client may not send them in an appropriate order. We could resort
+ * the suite list if so desired.
+ */
+ String[] suites = sslp.getCipherSuites();
+ sslp.setCipherSuites(suites);
+ sslp.setUseCipherSuitesOrder(true); // Set server side order
+
+ // Set the ALPN selection.
+ sslp.setApplicationProtocols(clientAPs);
+ sslSocket.setSSLParameters(sslp);
+
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null before the handshake starts");
+ }
+
+ sslSocket.startHandshake();
+
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null after the handshake is completed");
+ }
+
+ /*
+ * Check that the resulting connection meets our defined ALPN
+ * criteria. If we were connecting to a non-JSSE implementation,
+ * the server might have negotiated something we shouldn't accept.
+ */
+ String ap = sslSocket.getApplicationProtocol();
+ System.out.println("Application Protocol: \"" + ap + "\"");
+
+ if (ap == null) {
+ throw new Exception(
+ "Handshake was completed but null was received");
+ }
+ if (expectedAP.equals("NONE")) {
+ if (!ap.isEmpty()) {
+ throw new Exception("Expected no ALPN value");
+ } else {
+ System.out.println("No ALPN value negotiated, as expected");
+ }
+ } else if (!expectedAP.equals(ap)) {
+ throw new Exception(expectedAP
+ + " ALPN value not available on negotiated connection");
+ }
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write(280);
+ sslOS.flush();
+ sslIS.read();
+
+ sslSocket.close();
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+ // use any free port by default
+ volatile int serverPort = 0;
+
+ volatile Exception serverException = null;
+ volatile Exception clientException = null;
+
+ public static void main(String[] args) throws Exception {
+
+ if (debug) {
+ System.setProperty("javax.net.debug", "all");
+ }
+ System.out.println("Test args: " + Arrays.toString(args));
+
+ // Validate parameters
+ if (args.length != 4) {
+ throw new Exception("Invalid number of test parameters");
+ }
+ serverAPs = convert(args[0]);
+ callbackAP = args[1];
+ clientAPs = convert(args[2]);
+ expectedAP = args[3];
+
+ hasServerAPs = !args[0].equals("UNUSED"); // are server APs being used?
+ hasCallback = !callbackAP.equals("UNUSED"); // is callback being used?
+
+ /*
+ * Start the tests.
+ */
+ try {
+ new SSLSocketAlpnTest();
+ } catch (SSLHandshakeException she) {
+ if (args[3].equals("ERROR")) {
+ System.out.println("Caught the expected exception: " + she);
+ } else {
+ throw she;
+ }
+ }
+
+ System.out.println("Test Passed.");
+ }
+
+ SSLContext getSSLContext(String keyFilename, String trustFilename)
+ throws Exception {
+ SSLContext ctx = SSLContext.getInstance("TLS");
+
+ // Keystores
+ KeyStore keyKS = KeyStore.getInstance("JKS");
+ keyKS.load(new FileInputStream(keyFilename), passwd.toCharArray());
+
+ KeyStore trustKS = KeyStore.getInstance("JKS");
+ trustKS.load(new FileInputStream(trustFilename), passwd.toCharArray());
+
+ // Generate KeyManager and TrustManager
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(keyKS, passwd.toCharArray());
+
+ KeyManager[] kms = kmf.getKeyManagers();
+ if (!(kms[0] instanceof X509ExtendedKeyManager)) {
+ throw new Exception("kms[0] not X509ExtendedKeyManager");
+ }
+
+ kms = new KeyManager[] { new MyX509ExtendedKeyManager(
+ (X509ExtendedKeyManager) kms[0], expectedAP,
+ !hasCallback && hasServerAPs) };
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(trustKS);
+ TrustManager[] tms = tmf.getTrustManagers();
+
+ // initial SSLContext
+ ctx.init(kms, tms, null);
+
+ return ctx;
+ }
+
+ /*
+ * Convert a comma-separated list into an array of strings.
+ */
+ private static String[] convert(String list) {
+ if (list.equals("UNUSED")) {
+ return null;
+ }
+
+ if (list.equals("EMPTY")) {
+ return new String[0];
+ }
+
+ String[] strings;
+ if (list.indexOf(',') > 0) {
+ strings = list.split(",");
+ } else {
+ strings = new String[]{ list };
+ }
+
+ return strings;
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ SSLSocketAlpnTest() throws Exception {
+ Exception startException = null;
+ mySSLContext = getSSLContext(keyFilename, trustFilename);
+ try {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+ } catch (Exception e) {
+ startException = e;
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ if (serverThread != null) {
+ serverThread.join();
+ }
+ } else {
+ if (clientThread != null) {
+ clientThread.join();
+ }
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ * Which side threw the error?
+ */
+ Exception local;
+ Exception remote;
+
+ if (separateServerThread) {
+ remote = serverException;
+ local = clientException;
+ } else {
+ remote = clientException;
+ local = serverException;
+ }
+
+ Exception exception = null;
+
+ /*
+ * Check various exception conditions.
+ */
+ if ((local != null) && (remote != null)) {
+ // If both failed, return the curthread's exception.
+ local.initCause(remote);
+ exception = local;
+ } else if (local != null) {
+ exception = local;
+ } else if (remote != null) {
+ exception = remote;
+ } else if (startException != null) {
+ exception = startException;
+ }
+
+ /*
+ * If there was an exception *AND* a startException,
+ * output it.
+ */
+ if (exception != null) {
+ if (exception != startException && startException != null) {
+ exception.addSuppressed(startException);
+ }
+ throw exception;
+ }
+
+ // Fall-through: no exception to throw!
+ }
+
+ void startServer(boolean newThread) throws Exception {
+ if (newThread) {
+ serverThread = new Thread() {
+ @Override
+ public void run() {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ /*
+ * Our server thread just died.
+ *
+ * Release the client, if not active already...
+ */
+ System.err.println("Server died...");
+ serverReady = true;
+ serverException = e;
+ }
+ }
+ };
+ serverThread.start();
+ } else {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ serverException = e;
+ } finally {
+ serverReady = true;
+ }
+ }
+ }
+
+ void startClient(boolean newThread) throws Exception {
+ if (newThread) {
+ clientThread = new Thread() {
+ @Override
+ public void run() {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ /*
+ * Our client thread just died.
+ */
+ System.err.println("Client died...");
+ clientException = e;
+ }
+ }
+ };
+ clientThread.start();
+ } else {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ clientException = e;
+ }
+ }
+ }
+}
diff --git a/jdk/test/sun/security/ssl/rsa/SignedObjectChain.java b/jdk/test/sun/security/ssl/rsa/SignedObjectChain.java
index ba4b00c..711a3ab 100644
--- a/jdk/test/sun/security/ssl/rsa/SignedObjectChain.java
+++ b/jdk/test/sun/security/ssl/rsa/SignedObjectChain.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,9 +23,10 @@
/*
* @test
- * @bug 8050374
- * @compile ../../../../java/security/SignedObject/Chain.java
+ * @bug 8050374 8146293
* @summary Verify a chain of signed objects
+ * @library /lib
+ * @compile ../../../../java/security/SignedObject/Chain.java
*/
public class SignedObjectChain {
diff --git a/jdk/test/sun/security/ssl/templates/SSLEngineTemplate.java b/jdk/test/sun/security/ssl/templates/SSLEngineTemplate.java
index 0f87ee2..badce43 100644
--- a/jdk/test/sun/security/ssl/templates/SSLEngineTemplate.java
+++ b/jdk/test/sun/security/ssl/templates/SSLEngineTemplate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -78,7 +78,7 @@
/*
* Enables logging of the SSLEngine operations.
*/
- private static boolean logging = true;
+ private static final boolean logging = true;
/*
* Enables the JSSE system debugging system property:
@@ -89,9 +89,9 @@
* including specific handshake messages, and might be best examined
* after gaining some familiarity with this application.
*/
- private static boolean debug = false;
+ private static final boolean debug = false;
- private SSLContext sslc;
+ private final SSLContext sslc;
private SSLEngine clientEngine; // client Engine
private ByteBuffer clientOut; // write side of clientEngine
@@ -112,15 +112,15 @@
/*
* The following is to set up the keystores.
*/
- private static String pathToStores = "../etc";
- private static String keyStoreFile = "keystore";
- private static String trustStoreFile = "truststore";
- private static String passwd = "passphrase";
+ private static final String pathToStores = "../etc";
+ private static final String keyStoreFile = "keystore";
+ private static final String trustStoreFile = "truststore";
+ private static final String passwd = "passphrase";
- private static String keyFilename =
+ private static final String keyFilename =
System.getProperty("test.src", ".") + "/" + pathToStores +
"/" + keyStoreFile;
- private static String trustFilename =
+ private static final String trustFilename =
System.getProperty("test.src", ".") + "/" + pathToStores +
"/" + trustStoreFile;
diff --git a/jdk/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java b/jdk/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java
index 16696dbe..6619416 100644
--- a/jdk/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java
+++ b/jdk/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -86,7 +86,7 @@
/*
* Enables logging of the SSL/TLS operations.
*/
- private static boolean logging = true;
+ private static final boolean logging = true;
/*
* Enables the JSSE system debugging system property:
@@ -97,8 +97,8 @@
* including specific handshake messages, and might be best examined
* after gaining some familiarity with this application.
*/
- private static boolean debug = false;
- private SSLContext sslc;
+ private static final boolean debug = false;
+ private final SSLContext sslc;
private SSLEngine serverEngine; // server-side SSLEngine
private SSLSocket sslSocket; // client-side socket
private ServerSocket serverSocket; // server-side Socket, generates the...
@@ -128,10 +128,10 @@
private static final String keyStoreFile = "keystore";
private static final String trustStoreFile = "truststore";
private static final String passwd = "passphrase";
- private static String keyFilename =
+ private static final String keyFilename =
System.getProperty("test.src", ".") + "/" + pathToStores
+ "/" + keyStoreFile;
- private static String trustFilename =
+ private static final String trustFilename =
System.getProperty("test.src", ".") + "/" + pathToStores
+ "/" + trustStoreFile;
@@ -239,7 +239,7 @@
byte[] outbound = new byte[8192];
while (!isEngineClosed(serverEngine)) {
- int len = 0;
+ int len;
// Inbound data
log("================");
@@ -307,7 +307,6 @@
serverIn.compact();
}
}
- return;
} catch (Exception e) {
serverException = e;
} finally {
@@ -361,13 +360,12 @@
int pos = 0;
int len;
-done:
while ((len = is.read(inbound, pos, 2048 - pos)) != -1) {
pos += len;
// Let the client do the closing.
if ((pos == serverMsg.length) && !serverClose) {
sslSocket.close();
- break done;
+ break;
}
}
diff --git a/jdk/test/sun/security/ssl/templates/SSLSocketTemplate.java b/jdk/test/sun/security/ssl/templates/SSLSocketTemplate.java
index af9f40f..0a2f9f4 100644
--- a/jdk/test/sun/security/ssl/templates/SSLSocketTemplate.java
+++ b/jdk/test/sun/security/ssl/templates/SSLSocketTemplate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,6 @@
*/
import java.io.*;
-import java.net.*;
import javax.net.ssl.*;
public class SSLSocketTemplate {
@@ -162,8 +161,9 @@
System.setProperty("javax.net.ssl.trustStore", trustFilename);
System.setProperty("javax.net.ssl.trustStorePassword", passwd);
- if (debug)
+ if (debug) {
System.setProperty("javax.net.debug", "all");
+ }
/*
* Start the tests.
@@ -255,6 +255,7 @@
void startServer(boolean newThread) throws Exception {
if (newThread) {
serverThread = new Thread() {
+ @Override
public void run() {
try {
doServerSide();
@@ -285,6 +286,7 @@
void startClient(boolean newThread) throws Exception {
if (newThread) {
clientThread = new Thread() {
+ @Override
public void run() {
try {
doClientSide();
diff --git a/jdk/test/sun/security/tools/jarsigner/EntriesOrder.java b/jdk/test/sun/security/tools/jarsigner/EntriesOrder.java
index 96c90e9..908f6ef 100644
--- a/jdk/test/sun/security/tools/jarsigner/EntriesOrder.java
+++ b/jdk/test/sun/security/tools/jarsigner/EntriesOrder.java
@@ -25,6 +25,9 @@
* @test
* @bug 8031572
* @summary jarsigner -verify exits with 0 when a jar file is not properly signed
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.IOUtils
+ * @run main EntriesOrder
*/
import java.io.FileInputStream;
@@ -39,6 +42,8 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
+import jdk.testlibrary.IOUtils;
+
public class EntriesOrder {
public static void main(String[] args) throws Exception {
@@ -106,7 +111,7 @@
Enumeration<JarEntry> jes = jf.entries();
while (jes.hasMoreElements()) {
JarEntry je = jes.nextElement();
- sun.misc.IOUtils.readFully(jf.getInputStream(je), -1, true);
+ IOUtils.readFully(jf.getInputStream(je));
Certificate[] certs = je.getCertificates();
if (certs != null && certs.length > 0) {
cc++;
@@ -138,7 +143,7 @@
while (true) {
JarEntry je = jis.getNextJarEntry();
if (je == null) break;
- sun.misc.IOUtils.readFully(jis, -1, true);
+ IOUtils.readFully(jis);
Certificate[] certs = je.getCertificates();
if (certs != null && certs.length > 0) {
cc++;
diff --git a/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java b/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java
index b5070ce..1018ace 100644
--- a/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java
+++ b/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java
@@ -743,7 +743,7 @@
try (JarFile jf = new JarFile(file)) {
JarEntry je = jf.getJarEntry("META-INF/SIGNER.RSA");
try (InputStream is = jf.getInputStream(je)) {
- byte[] content = IOUtils.readFully(is, -1, true);
+ byte[] content = IOUtils.readAllBytes(is);
PKCS7 p7 = new PKCS7(content);
SignerInfo[] si = p7.getSignerInfos();
if (si == null || si.length == 0) {
diff --git a/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java b/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java
index 96116e1..0bf70d3 100644
--- a/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java
+++ b/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java
@@ -87,6 +87,7 @@
"-storepass", PASSWORD,
"-keypass", PASSWORD,
"-dname", "CN=CA",
+ "-ext", "bc:c",
"-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
ProcessTools.executeCommand(KEYTOOL,
"-genkey",
diff --git a/jdk/test/sun/security/tools/jarsigner/Warning.java b/jdk/test/sun/security/tools/jarsigner/Warning.java
index 095d205..adb7833 100644
--- a/jdk/test/sun/security/tools/jarsigner/Warning.java
+++ b/jdk/test/sun/security/tools/jarsigner/Warning.java
@@ -42,7 +42,7 @@
Files.deleteIfExists(Paths.get("ks"));
- newCert("ca", "-validity 365000");
+ newCert("ca", "-validity 365000", "-ext bc:c");
recreateJar();
diff --git a/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh b/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh
index b9ec9e8..b2affb4 100644
--- a/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh
+++ b/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh
@@ -22,7 +22,7 @@
#
# @test
-# @bug 6802846 8172529
+# @bug 6802846 8172529 8227758
# @summary jarsigner needs enhanced cert validation(options)
#
# @run shell/timeout=240 concise_jarsigner.sh
@@ -207,15 +207,11 @@
$JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain
[ $? = 0 ] || exit $LINENO
-# if ca2 is removed, -certchain still work because altchain is a self-signed entry and
-# it is trusted by jarsigner
+# if ca2 is removed and cert is imported, -certchain won't work because this certificate
+# entry is not trusted
# save ca2.cert for easy replay
$KT -exportcert -file ca2.cert -alias ca2
$KT -delete -alias ca2
-$JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain
-[ $? = 0 ] || exit $LINENO
-
-# if cert is imported, -certchain won't work because this certificate entry is not trusted
$KT -importcert -file certchain -alias altchain -noprompt
$JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain
[ $? = 4 ] || exit $LINENO
@@ -228,8 +224,8 @@
# ==========================================================
$KT -genkeypair -alias ee -dname CN=ee
-$KT -genkeypair -alias caone -dname CN=caone
-$KT -genkeypair -alias catwo -dname CN=catwo
+$KT -genkeypair -alias caone -dname CN=caone -ext bc:c
+$KT -genkeypair -alias catwo -dname CN=catwo -ext bc:c
$KT -certreq -alias ee | $KT -gencert -alias catwo -rfc > ee.cert
$KT -certreq -alias catwo | $KT -gencert -alias caone -sigalg MD5withRSA -rfc > catwo.cert
diff --git a/jdk/test/sun/security/tools/jarsigner/ec.sh b/jdk/test/sun/security/tools/jarsigner/ec.sh
index 442e854..2893dca 100644
--- a/jdk/test/sun/security/tools/jarsigner/ec.sh
+++ b/jdk/test/sun/security/tools/jarsigner/ec.sh
@@ -53,7 +53,7 @@
echo A > A
$JAR cvf $JFILE A
-$KT -alias ca -dname CN=ca -keyalg ec -genkey -validity 300 || exit 11
+$KT -alias ca -dname CN=ca -keyalg ec -genkey -validity 300 -ext bc:c || exit 11
$KT -alias a -dname CN=a -keyalg ec -genkey || exit 11
$KT -alias a -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias a || exit 111
diff --git a/jdk/test/sun/security/tools/jarsigner/onlymanifest.sh b/jdk/test/sun/security/tools/jarsigner/onlymanifest.sh
index bbc90a1..cc42e8f 100644
--- a/jdk/test/sun/security/tools/jarsigner/onlymanifest.sh
+++ b/jdk/test/sun/security/tools/jarsigner/onlymanifest.sh
@@ -57,7 +57,7 @@
echo "Key: Value" > manifest
$JAR cvfm $JFILE manifest
-$KT -alias ca -dname CN=ca -genkey -validity 300 || exit 1
+$KT -alias ca -dname CN=ca -genkey -validity 300 -ext bc:c || exit 1
$KT -alias a -dname CN=a -genkey -validity 300 || exit 2
$KT -alias a -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias a || exit 3
$JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 4
diff --git a/jdk/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java b/jdk/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java
index 1a49c15..bb0f448 100644
--- a/jdk/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -53,7 +53,7 @@
// create a certificate whose signer certificate's
// ExtendedKeyUsage extension doesn't allow code signing
// create key pair for jar signing
- createAlias(CA_KEY_ALIAS);
+ createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
createAlias(KEY_ALIAS);
issueCert(
diff --git a/jdk/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java b/jdk/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java
index fb0fac9..46cd564 100644
--- a/jdk/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -53,7 +53,7 @@
// create a certificate whose signer certificate's KeyUsage extension
// doesn't allow code signing
- createAlias(CA_KEY_ALIAS);
+ createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
createAlias(KEY_ALIAS);
issueCert(
diff --git a/jdk/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java b/jdk/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java
index 443331d..0d1a063 100644
--- a/jdk/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -54,7 +54,7 @@
// create a certificate whose signer certificate's
// NetscapeCertType extension doesn't allow code signing
// create key pair for jar signing
- createAlias(CA_KEY_ALIAS);
+ createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
createAlias(KEY_ALIAS);
issueCert(
diff --git a/jdk/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java b/jdk/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java
index b9d0ae5..6055546 100644
--- a/jdk/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -54,7 +54,7 @@
// Root CA is not checked at all. If the intermediate CA has
// BasicConstraints extension set to true, it will be valid.
// Otherwise, chain validation will fail.
- createAlias(CA_KEY_ALIAS);
+ createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
createAlias(CA2_KEY_ALIAS);
issueCert(CA2_KEY_ALIAS,
"-ext",
diff --git a/jdk/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java b/jdk/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java
index f457776..1a8ee17 100644
--- a/jdk/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,7 @@
JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
// create key pair for jar signing
- createAlias(CA_KEY_ALIAS);
+ createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
createAlias(KEY_ALIAS);
issueCert(
diff --git a/jdk/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java b/jdk/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java
index 8a71c667..c414f48 100644
--- a/jdk/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,7 @@
JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
// create key pair for jar signing
- createAlias(CA_KEY_ALIAS);
+ createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
createAlias(KEY_ALIAS);
issueCert(
diff --git a/jdk/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java b/jdk/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java
index 078ff89..1aafc58 100644
--- a/jdk/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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,7 +51,7 @@
JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
// create key pair for signing
- createAlias(CA_KEY_ALIAS);
+ createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
createAlias(KEY_ALIAS);
issueCert(
KEY_ALIAS,
diff --git a/jdk/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java b/jdk/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java
index 862e8ca..0831dc5 100644
--- a/jdk/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -54,7 +54,7 @@
// create a jar file that contains one class file
JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
- createAlias(CA_KEY_ALIAS);
+ createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
// create first expired certificate
// whose ExtendedKeyUsage extension does not allow code signing
diff --git a/jdk/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java b/jdk/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java
index 8429fe2..447baab 100644
--- a/jdk/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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,7 +57,7 @@
* 24 * 60 * 60 * 1000L);
// create key pair
- createAlias(CA_KEY_ALIAS);
+ createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
createAlias(KEY_ALIAS);
issueCert(KEY_ALIAS,
"-validity", Integer.toString(VALIDITY));
diff --git a/jdk/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java b/jdk/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java
index 9fb9262..db415f9 100644
--- a/jdk/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -49,7 +49,7 @@
Utils.createFiles(FIRST_FILE);
JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
- createAlias(CA_KEY_ALIAS);
+ createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
// create first key pair for signing
createAlias(FIRST_KEY_ALIAS);
diff --git a/jdk/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java b/jdk/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java
index 4d19c9a..a9aa77d 100644
--- a/jdk/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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,7 +50,7 @@
JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
// create certificate that will be valid only tomorrow
- createAlias(CA_KEY_ALIAS);
+ createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
createAlias(KEY_ALIAS);
issueCert(
diff --git a/jdk/test/sun/security/tools/keytool/ListOrder.java b/jdk/test/sun/security/tools/keytool/ListOrder.java
new file mode 100644
index 0000000..cf24bc5
--- /dev/null
+++ b/jdk/test/sun/security/tools/keytool/ListOrder.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2019, 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 8225392
+ * @summary Comparison builds are failing due to cacerts file
+ * @library /lib/testlibrary
+ */
+
+import jdk.testlibrary.SecurityTools;
+
+import java.util.Random;
+
+public class ListOrder {
+
+ public static void main(String[] args) throws Throwable {
+
+ Random rand = new Random();
+ for (int i = 0; i < 10; i++) {
+ gen(String.format("a%02d", rand.nextInt(100)));
+ }
+
+ String last = "";
+ for (String line : SecurityTools.keytool(
+ "-keystore ks -storepass changeit -list").asLines()) {
+ if (line.contains("PrivateKeyEntry")) {
+ // This is the line starting with the alias
+ System.out.println(line);
+ if (line.compareTo(last) <= 0) {
+ throw new RuntimeException("Not ordered");
+ } else {
+ last = line;
+ }
+ }
+ }
+ }
+
+ static void gen(String a) throws Exception {
+ // Do not check result, there might be duplicated alias(es).
+ SecurityTools.keytool("-keystore ks -storepass changeit "
+ + "-keyalg ec -genkeypair -alias " + a + " -dname CN=" + a);
+ }
+}
diff --git a/jdk/test/sun/security/tools/keytool/PSS.java b/jdk/test/sun/security/tools/keytool/PSS.java
new file mode 100644
index 0000000..4510899
--- /dev/null
+++ b/jdk/test/sun/security/tools/keytool/PSS.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8215694
+ * @summary keytool cannot generate RSASSA-PSS certificates
+ * @library /lib/testlibrary
+ * @run main/timeout=600 PSS
+ */
+
+import jdk.testlibrary.Asserts;
+import jdk.testlibrary.security.DerUtils;
+import sun.security.util.ObjectIdentifier;
+import sun.security.x509.AlgorithmId;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+
+public class PSS {
+
+ public static void main(String[] args) throws Exception {
+
+ // make sure no old file exists
+ new File("ks").delete();
+
+ genkeypair("p", "-keyalg RSASSA-PSS -sigalg RSASSA-PSS");
+ genkeypair("a", "-keyalg RSA -sigalg RSASSA-PSS -keysize 2048");
+ genkeypair("b", "-keyalg RSA -sigalg RSASSA-PSS -keysize 4096");
+ genkeypair("c", "-keyalg RSA -sigalg RSASSA-PSS -keysize 8192");
+
+ //@since jdk9
+ //KeyStore ks = KeyStore.getInstance(
+ // new File("ks"), "changeit".toCharArray());
+
+ KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+ // get user password and file input stream
+ char[] password = "changeit".toCharArray();
+ try (FileInputStream fis = new FileInputStream("ks")) {
+ ks.load(fis, password);
+ }
+
+ check((X509Certificate)ks.getCertificate("p"), "RSASSA-PSS",
+ AlgorithmId.SHA256_oid);
+
+ check((X509Certificate)ks.getCertificate("a"), "RSA",
+ AlgorithmId.SHA256_oid);
+
+ check((X509Certificate)ks.getCertificate("b"), "RSA",
+ AlgorithmId.SHA384_oid);
+
+ check((X509Certificate)ks.getCertificate("c"), "RSA",
+ AlgorithmId.SHA512_oid);
+
+ // More commands
+ kt("-certreq -alias p -sigalg RSASSA-PSS -file p.req");
+
+ kt("-gencert -alias a -sigalg RSASSA-PSS -infile p.req -outfile p.cert");
+ kt("-importcert -alias p -file p.cert");
+
+ kt("-selfcert -alias p -sigalg RSASSA-PSS");
+ }
+
+ static void genkeypair(String alias, String options)
+ throws Exception {
+ kt("-genkeypair -alias " + alias
+ + " -dname CN=" + alias + " " + options);
+ }
+
+ static void kt(String cmd) throws Exception {
+ String listStr = "-storepass changeit -keypass changeit "
+ + "-keystore ks " + cmd;
+ sun.security.tools.keytool.Main.main(listStr.split(" "));
+ }
+
+ static void check(X509Certificate cert, String expectedKeyAlg,
+ ObjectIdentifier expectedMdAlg) throws Exception {
+ Asserts.assertEQ(cert.getPublicKey().getAlgorithm(), expectedKeyAlg);
+ Asserts.assertEQ(cert.getSigAlgName(), "RSASSA-PSS");
+ DerUtils.checkAlg(cert.getSigAlgParams(), "000", expectedMdAlg);
+ }
+}
diff --git a/jdk/test/sun/security/util/DerValue/BadValue.java b/jdk/test/sun/security/util/DerValue/BadValue.java
index ef3a9ef..d02a478 100644
--- a/jdk/test/sun/security/util/DerValue/BadValue.java
+++ b/jdk/test/sun/security/util/DerValue/BadValue.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, 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
@@ -35,43 +35,48 @@
public static void main(String[] args) throws Exception {
- // Test IOUtils.readFully
+ // Test IOUtils.
// We have 4 bytes
InputStream in = new ByteArrayInputStream(new byte[10]);
- byte[] bs = IOUtils.readFully(in, 4, true);
+ byte[] bs = IOUtils.readExactlyNBytes(in, 4);
if (bs.length != 4 || in.available() != 6) {
throw new Exception("First read error");
}
// But only 6 left
- bs = IOUtils.readFully(in, 10, false);
+ bs = IOUtils.readNBytes(in, 10);
if (bs.length != 6 || in.available() != 0) {
throw new Exception("Second read error");
}
- // MAX read as much as it can
+ // MAX length results in exception
in = new ByteArrayInputStream(new byte[10]);
- bs = IOUtils.readFully(in, Integer.MAX_VALUE, true);
- if (bs.length != 10 || in.available() != 0) {
- throw new Exception("Second read error");
+ try {
+ bs = IOUtils.readExactlyNBytes(in, Integer.MAX_VALUE);
+ throw new Exception("No exception on MAX_VALUE length");
+ } catch (EOFException ex) {
+ // this is expected
}
- // MAX ignore readAll
+ // -1 length results in exception
in = new ByteArrayInputStream(new byte[10]);
- bs = IOUtils.readFully(in, Integer.MAX_VALUE, false);
- if (bs.length != 10 || in.available() != 0) {
- throw new Exception("Second read error");
+ try {
+ bs = IOUtils.readExactlyNBytes(in, -1);
+ throw new Exception("No exception on -1 length");
+ } catch (IOException ex) {
+ // this is expected
}
+
// 20>10, readAll means failure
in = new ByteArrayInputStream(new byte[10]);
try {
- bs = IOUtils.readFully(in, 20, true);
- throw new Exception("Third read error");
+ bs = IOUtils.readExactlyNBytes(in, 20);
+ throw new Exception("No exception on EOF");
} catch (EOFException e) {
// OK
}
int bignum = 10 * 1024 * 1024;
- bs = IOUtils.readFully(new SuperSlowStream(bignum), -1, true);
+ bs = IOUtils.readExactlyNBytes(new SuperSlowStream(bignum), bignum);
if (bs.length != bignum) {
- throw new Exception("Fourth read error");
+ throw new Exception("Read returned small array");
}
// Test DerValue
diff --git a/jdk/test/sun/security/util/misc/SetNullSigParams.java b/jdk/test/sun/security/util/misc/SetNullSigParams.java
new file mode 100644
index 0000000..e5e5167
--- /dev/null
+++ b/jdk/test/sun/security/util/misc/SetNullSigParams.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8214096 8216039
+ * @summary Make sure SignatureUtil can accept null algorithm parameters
+ */
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+import sun.security.util.SignatureUtil;
+
+public class SetNullSigParams {
+
+ public static void main(String[] args) throws Exception {
+ Signature sig = new SpecialSigImpl();
+ SignatureUtil.initVerifyWithParam(sig, (PublicKey) null, null);
+ SignatureUtil.initSignWithParam(sig, null, null, null);
+ }
+
+ // Sample Signature impl class which simulates 3rd party provider behavior
+ // and throws NPE when given null algorithm parameters
+ // For max backward-compatibility, sun.security.util.SignatureUtil class
+ // now calls setParameter() only when algorithm parameters is non-null
+ private static class SpecialSigImpl extends Signature {
+ SpecialSigImpl() {
+ super("ANY");
+ }
+ @Override
+ protected void engineInitVerify(PublicKey publicKey)
+ throws InvalidKeyException {}
+ @Override
+ protected void engineInitSign(PrivateKey privateKey)
+ throws InvalidKeyException {}
+ @Override
+ protected void engineUpdate(byte b) throws SignatureException {}
+ @Override
+ protected void engineUpdate(byte[] b, int off, int len)
+ throws SignatureException {}
+ @Override
+ protected byte[] engineSign() throws SignatureException { return null; }
+ @Override
+ protected boolean engineVerify(byte[] sigBytes)
+ throws SignatureException { return false; }
+ @Override
+ protected void engineSetParameter(String param, Object value)
+ throws InvalidParameterException {}
+ @Override
+ protected void engineSetParameter(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ if (params == null) throw new NullPointerException("Test Failed");
+ }
+ @Override
+ protected Object engineGetParameter(String param)
+ throws InvalidParameterException { return null; }
+ }
+}
diff --git a/jdk/test/sun/security/validator/EndEntityExtensionCheck.java b/jdk/test/sun/security/validator/EndEntityExtensionCheck.java
index 3cff8fc..72db277 100644
--- a/jdk/test/sun/security/validator/EndEntityExtensionCheck.java
+++ b/jdk/test/sun/security/validator/EndEntityExtensionCheck.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
* @bug 8076117
* @summary EndEntityChecker should not process custom extensions
* after PKIX validation
+ * @run main/othervm -Djdk.security.allowNonCaAnchor EndEntityExtensionCheck
*/
import java.io.ByteArrayInputStream;
diff --git a/jdk/test/sun/security/x509/X509CertImpl/ECSigParamsVerifyWithCert.java b/jdk/test/sun/security/x509/X509CertImpl/ECSigParamsVerifyWithCert.java
new file mode 100644
index 0000000..4ed0121
--- /dev/null
+++ b/jdk/test/sun/security/x509/X509CertImpl/ECSigParamsVerifyWithCert.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8225745
+ * @summary Ensure ECDSA certificates with signature algorithm parameters
+ * can be verified successfully
+ * @run main ECSigParamsVerifyWithCert
+ */
+import java.io.*;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+public class ECSigParamsVerifyWithCert {
+
+ // ECDSA certificate with non-null signature parameters, i.e.
+ // Signature Algorithm: SHA256withECDSA, params unparsed,
+ // OID = 1.2.840.10045.4.3.2
+ private static String ecEntityWithSigParamsStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICXjCCAfmgAwIBAgIIHzREzASpiTowFAYIKoZIzj0EAwIGCCqGSM49AwEHMGAx\n" +
+ "IzAhBgNVBAMMGkNvcmRhIE5vZGUgSW50ZXJtZWRpYXRlIENBMQswCQYDVQQKDAJS\n" +
+ "MzEOMAwGA1UECwwFY29yZGExDzANBgNVBAcMBkxvbmRvbjELMAkGA1UEBhMCVUsw\n" +
+ "HhcNMTgwNjI1MDAwMDAwWhcNMjcwNTIwMDAwMDAwWjAxMQswCQYDVQQGEwJHQjEP\n" +
+ "MA0GA1UEBwwGTG9uZG9uMREwDwYDVQQKDAhNZWdhQ29ycDBZMBMGByqGSM49AgEG\n" +
+ "CCqGSM49AwEHA0IABG2VjWPPFnGVka3G9++Sz/GPRkAkht4BDoYTlkRz8hpwr4iu\n" +
+ "fU6NlReirLOB4LBLZcmp16xm4RYsN5ouTS7Z3wKjgcEwgb4wHQYDVR0OBBYEFBnY\n" +
+ "sikYpaSL9U8FUygbqN3sIvMOMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgGG\n" +
+ "MCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADARBgorBgEEAYOK\n" +
+ "YgEBBAMCAQQwRwYDVR0eAQH/BD0wO6A3MDWkMzAxMQswCQYDVQQGEwJHQjEPMA0G\n" +
+ "A1UEBwwGTG9uZG9uMREwDwYDVQQKDAhNZWdhQ29ycKEAMBQGCCqGSM49BAMCBggq\n" +
+ "hkjOPQMBBwNJADBGAiEAos+QzgwwH2hfOtrlLncHnoT2YXXHP4q5h01T2DRmjcMC\n" +
+ "IQDa3xZz7CkyyNO1+paAthiNVIlGwwnl4UxuYMwkAiWACw==\n" +
+ "-----END CERTIFICATE-----\n";
+
+ // ECDSA certificate with only signature algorithm oid, no parameters, i.e.
+ // Signature Algorithm: SHA256withECDSA, OID = 1.2.840.10045.4.3.2
+ private static String ecSigner =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICETCCAbigAwIBAgIIaHr3YTnjT8YwCgYIKoZIzj0EAwIwWDEbMBkGA1UEAwwS\n" +
+ "Q29yZGEgTm9kZSBSb290IENBMQswCQYDVQQKDAJSMzEOMAwGA1UECwwFY29yZGEx\n" +
+ "DzANBgNVBAcMBkxvbmRvbjELMAkGA1UEBhMCVUswHhcNMTcwNTIyMDAwMDAwWhcN\n" +
+ "MjcwNTIwMDAwMDAwWjBgMSMwIQYDVQQDDBpDb3JkYSBOb2RlIEludGVybWVkaWF0\n" +
+ "ZSBDQTELMAkGA1UECgwCUjMxDjAMBgNVBAsMBWNvcmRhMQ8wDQYDVQQHDAZMb25k\n" +
+ "b24xCzAJBgNVBAYTAlVLMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEA8veoCbh\n" +
+ "ZmazlyIFWjExBd8ru5OYdFW9Z9ZD5BVg/dswdKC4dlHMHe/sQ4TxFmkYNqf7DTTt\n" +
+ "ePtdHT7Eb1LGYKNkMGIwHQYDVR0OBBYEFOvuLjAVKUCuGZge2G/jfX8HosITMAsG\n" +
+ "A1UdDwQEAwIBhjAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAw\n" +
+ "DwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNHADBEAiB6wr47tuC71qi6+FbY\n" +
+ "XYDTvK+QmAi5ywkFc95I9fPLaQIgIM+nNNQ50NwK610h3bG37XC2tGu+A7Dhtt2Q\n" +
+ "4nDqu30=\n" +
+ "-----END CERTIFICATE-----\n";
+
+ public static void main(String[] args) throws Exception {
+ CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+ ByteArrayInputStream is
+ = new ByteArrayInputStream(ecEntityWithSigParamsStr.getBytes());
+ X509Certificate ecEntityWithSigParams = (X509Certificate)certFactory.generateCertificate(is);
+ is = new ByteArrayInputStream(ecSigner.getBytes());
+ X509Certificate ecSigner = (X509Certificate)certFactory.generateCertificate(is);
+
+ try {
+ ecEntityWithSigParams.verify(ecSigner.getPublicKey());
+ System.out.println("Test Passed: EC Cert verified");
+ } catch (Exception e) {
+ System.out.println("Failed, cannot verify EC certificate with sig params");
+ throw e;
+ }
+ }
+}
diff --git a/langtools/.hgtags b/langtools/.hgtags
index 5b2c2ff..bdb11de 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -1021,5 +1021,11 @@
5b0a0cf41fc1243f32ffe5682ac5dde265902daa jdk8u242-b02
fbe99e0b4e74edb310cebd774399d80c77be636d jdk8u242-b03
764b933d3443949279024afa13db853246c4238e jdk8u242-b04
+7f8e21b79cceeda47fb986ecbfd738a08cbb0e54 jdk8u242-b05
+03512b6e35cbe46659ef2568d76836d4fbaa5f25 jdk8u242-b06
+2b1a419389932f0367ab68ad60c4ec209e1ae417 jdk8u242-b07
+b2b31daec366e7725872dd53dd800cbc9ada70c9 jdk8u242-b08
+b2b31daec366e7725872dd53dd800cbc9ada70c9 jdk8u242-ga
fefafdbaeb2db73e15f2be0784538f9917235b5c jdk8u252-b00
dba0e28b9488325476ce34fa47af1ada3614685d jdk8u252-b01
+24a2778069293cc97b79df91049265be1061c3bf jdk8u252-b02
diff --git a/langtools/THIRD_PARTY_README b/langtools/THIRD_PARTY_README
index 3f18756..a9adb43 100644
--- a/langtools/THIRD_PARTY_README
+++ b/langtools/THIRD_PARTY_README
@@ -1334,11 +1334,13 @@
--------------------------------------------------------------------------------
-%% This notice is provided with respect to Joni v1.1.9, which may be
+%% This notice is provided with respect to Joni v2.1.16, which may be
included with JRE 8, JDK 8, and OpenJDK 8.
--- begin of LICENSE ---
+Copyright (c) 2017 JRuby Team
+
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
diff --git a/nashorn/.hgtags b/nashorn/.hgtags
index f825cf6..a9190cc 100644
--- a/nashorn/.hgtags
+++ b/nashorn/.hgtags
@@ -1055,5 +1055,11 @@
49b31f2616534d74144a4fa8480609e70dc56c06 jdk8u242-b02
2c0573615bbb89bd2b522d0b4619ef513d3f51dd jdk8u242-b03
6375475624314776773afbd023fabae34054cf52 jdk8u242-b04
+735e7a309c5b0623bf25b29a0a1e7e437d56a43c jdk8u242-b05
+0735b1dcec3677634ca632683ca14911431a236a jdk8u242-b06
+1bccea33f6dbb43bf0cb74b82bd9669aba5319ab jdk8u242-b07
+0704986602a8506f41e5a4648d724be74f1e6f95 jdk8u242-b08
+0704986602a8506f41e5a4648d724be74f1e6f95 jdk8u242-ga
191f7b51899b59c104f0ec3fc135cf50bf836e99 jdk8u252-b00
7487b6f12a01cd9596f80b49440859aa33ba4890 jdk8u252-b01
+bbf9c324a735c6b9f95fedc61803346ef93b27f2 jdk8u252-b02
diff --git a/nashorn/THIRD_PARTY_README b/nashorn/THIRD_PARTY_README
index 3f18756..a9adb43 100644
--- a/nashorn/THIRD_PARTY_README
+++ b/nashorn/THIRD_PARTY_README
@@ -1334,11 +1334,13 @@
--------------------------------------------------------------------------------
-%% This notice is provided with respect to Joni v1.1.9, which may be
+%% This notice is provided with respect to Joni v2.1.16, which may be
included with JRE 8, JDK 8, and OpenJDK 8.
--- begin of LICENSE ---
+Copyright (c) 2017 JRuby Team
+
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights