This commit is contained in:
Xiomara Jayasena 2008-04-18 13:24:06 -07:00
commit 3ceaec158c
100 changed files with 6084 additions and 706 deletions

View File

@ -1 +1,2 @@
37a05a11f281b4d238e2f9e7ebb67c63f64d0e77 jdk7-b24 37a05a11f281b4d238e2f9e7ebb67c63f64d0e77 jdk7-b24
75fca0b0ab83ab1392e615910cea020f66535390 jdk7-b25

View File

@ -1,5 +1,5 @@
# #
# Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. # Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -87,8 +87,7 @@
# sign Alias for sign-jar # sign Alias for sign-jar
# sign-jar Builds/signs sunjce_provider.jar (no install) # sign-jar Builds/signs sunjce_provider.jar (no install)
# #
# obfus Builds/obfuscates/signs/installs # obfus Builds/obfuscates/signs sunjce_provider.jar
# sunjce_provider.jar
# #
# release Builds all targets in preparation # release Builds all targets in preparation
# for workspace integration. # for workspace integration.
@ -101,8 +100,25 @@
BUILDDIR = ../../../.. BUILDDIR = ../../../..
PACKAGE = com.sun.crypto.provider PACKAGE = com.sun.crypto.provider
PRODUCT = sun PRODUCT = sun
#
# The following is for when we need to do postprocessing
# (signing/obfuscation) against a read-only build. If the OUTPUTDIR
# isn't writable, the build currently crashes out.
#
ifndef OPENJDK
ifdef ALT_JCE_BUILD_DIR
# =====================================================
# Where to place the output, in case we're building from a read-only
# build area. (e.g. a release engineering build.)
JCE_BUILD_DIR=${ALT_JCE_BUILD_DIR}
IGNORE_WRITABLE_OUTPUTDIR_TEST=true
else
JCE_BUILD_DIR=${TEMPDIR}
endif
endif
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
include $(BUILDDIR)/javax/crypto/Defs-jce.gmk
# #
# Location for the newly built classfiles. # Location for the newly built classfiles.
@ -147,6 +163,8 @@ endif # OPENJDK
# #
UNSIGNED_DIR = $(TEMPDIR)/unsigned UNSIGNED_DIR = $(TEMPDIR)/unsigned
include $(BUILDDIR)/javax/crypto/Defs-jce.gmk
# ===================================================== # =====================================================
# Build the unsigned sunjce_provider.jar file. # Build the unsigned sunjce_provider.jar file.
@ -184,44 +202,66 @@ ifndef OPENJDK
# Sign the provider jar file. Not needed for OpenJDK. # Sign the provider jar file. Not needed for OpenJDK.
# #
SIGNED_DIR = $(TEMPDIR)/signed SIGNED_DIR = $(JCE_BUILD_DIR)/signed
sign: sign-jar sign: sign-jar
sign-jar: $(SIGNED_DIR)/sunjce_provider.jar sign-jar: $(SIGNED_DIR)/sunjce_provider.jar
ifndef ALT_JCE_BUILD_DIR
$(SIGNED_DIR)/sunjce_provider.jar: $(UNSIGNED_DIR)/sunjce_provider.jar $(SIGNED_DIR)/sunjce_provider.jar: $(UNSIGNED_DIR)/sunjce_provider.jar
$(sign-file) else
#
# We have to remove the build dependency, otherwise, we'll try to rebuild it
# which we can't do on a read-only filesystem.
#
$(SIGNED_DIR)/sunjce_provider.jar:
@if [ ! -r $(UNSIGNED_DIR)/sunjce_provider.jar ] ; then \
$(ECHO) "Couldn't find $(UNSIGNED_DIR)/sunjce_provider.jar"; \
exit 1; \
fi
endif
$(call sign-file, $(UNSIGNED_DIR)/sunjce_provider.jar)
# ===================================================== # =====================================================
# Obfuscate/sign/install the JDK build. Not needed for OpenJDK. # Obfuscate/sign/install the JDK build. Not needed for OpenJDK.
# #
OBFUS_DIR = $(TEMPDIR)/obfus OBFUS_DIR = $(JCE_BUILD_DIR)/obfus/sunjce
CLOSED_DIR = $(BUILDDIR)/closed/com/sun/crypto/provider CLOSED_DIR = $(BUILDDIR)/closed/com/sun/crypto/provider
obfus: $(OBFUS_DIR)/sunjce_provider.jar obfus: $(OBFUS_DIR)/sunjce_provider.jar
$(release-warning) $(release-warning)
$(OBFUS_DIR)/sunjce_provider.jar: build-jar $(JCE_MANIFEST_FILE) ifndef ALT_JCE_BUILD_DIR
$(OBFUS_DIR)/sunjce_provider.jar: build-jar $(JCE_MANIFEST_FILE) \
$(OBFUS_DIR)/sunjce.dox
else
$(OBFUS_DIR)/sunjce_provider.jar: $(JCE_MANIFEST_FILE) $(OBFUS_DIR)/sunjce.dox
@if [ ! -d $(CLASSDESTDIR) ] ; then \
$(ECHO) "Couldn't find $(CLASSDESTDIR)"; \
exit 1; \
fi
endif
@$(ECHO) ">>>Obfuscating SunJCE Provider..."
$(presign) $(presign)
$(preobfus) $(preobfus)
@$(ECHO) ">>>Obfuscating Sun JCE Provider..."
$(prep-target) $(prep-target)
$(CD) $(OBFUS_DIR); \ $(CD) $(OBFUS_DIR); \
$(OBFUSCATOR) -fv \ $(OBFUSCATOR) -fv sunjce.dox
$(CURRENT_DIRECTORY)/$(CLOSED_DIR)/obfus/sunjce.dox
@$(CD) $(OBFUS_DIR); $(java-vm-cleanup) @$(CD) $(OBFUS_DIR); $(java-vm-cleanup)
$(BOOT_JAR_CMD) cmf $(JCE_MANIFEST_FILE) $@ \ $(BOOT_JAR_CMD) cmf $(JCE_MANIFEST_FILE) $@ \
-C $(OBFUS_DIR)/build com \ -C $(OBFUS_DIR)/build com \
$(JAR_JFLAGS) $(JAR_JFLAGS)
$(sign-target) $(sign-target)
$(MKDIR) -p $(dir $(JAR_DESTFILE))
$(RM) $(JAR_DESTFILE)
$(CP) $@ $(JAR_DESTFILE)
@$(java-vm-cleanup) @$(java-vm-cleanup)
$(OBFUS_DIR)/sunjce.dox: $(CLOSED_DIR)/obfus/sunjce.dox
@$(ECHO) ">>>Creating sunjce.dox"
$(prep-target)
$(SED) "s:@@TEMPDIR@@:$(ABS_TEMPDIR):" $< > $@
# #
# The current obfuscator has a limitation in that it currently only # The current obfuscator has a limitation in that it currently only
# supports up to v49 class file format. Force v49 classfiles in our # supports up to v49 class file format. Force v49 classfiles in our
@ -235,9 +275,9 @@ TARGET_CLASS_VERSION = 5
# #
release: $(OBFUS_DIR)/sunjce_provider.jar release: $(OBFUS_DIR)/sunjce_provider.jar
$(RM) $(RELEASE_DIR)/sunjce_provider.jar $(RM) $(JCE_BUILD_DIR)/release/sunjce_provider.jar
$(MKDIR) -p $(RELEASE_DIR) $(MKDIR) -p $(JCE_BUILD_DIR)/release
$(CP) $(OBFUS_DIR)/sunjce_provider.jar $(RELEASE_DIR) $(CP) $(OBFUS_DIR)/sunjce_provider.jar $(JCE_BUILD_DIR)/release
$(release-warning) $(release-warning)
endif # OPENJDK endif # OPENJDK
@ -275,7 +315,7 @@ endif
# #
clobber clean:: clobber clean::
$(RM) -r $(JAR_DESTFILE) $(TEMPDIR) $(RM) -r $(JAR_DESTFILE) $(TEMPDIR) $(JCE_BUILD_DIR)
.PHONY: build-jar jar install-jar .PHONY: build-jar jar install-jar
ifndef OPENJDK ifndef OPENJDK

View File

@ -1,5 +1,5 @@
# #
# Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. # Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -451,11 +451,20 @@ endif
# Check for spaces and null value # Check for spaces and null value
OUTPUTDIR:=$(call AltCheckSpaces,OUTPUTDIR) OUTPUTDIR:=$(call AltCheckSpaces,OUTPUTDIR)
OUTPUTDIR:=$(call AltCheckValue,OUTPUTDIR) OUTPUTDIR:=$(call AltCheckValue,OUTPUTDIR)
#
# When signing the JCE framework and provider, we could be using built
# bits on a read-only filesystem. If so, this test will fail and crash
# the build.
#
ifndef IGNORE_WRITABLE_OUTPUTDIR_TEST
# Create the output directory and make sure it exists and is writable # Create the output directory and make sure it exists and is writable
_create_outputdir:=$(shell $(MKDIR) -p "$(OUTPUTDIR)" > $(DEV_NULL) 2>&1) _create_outputdir:=$(shell $(MKDIR) -p "$(OUTPUTDIR)" > $(DEV_NULL) 2>&1)
ifeq ($(call WriteDirExists,$(OUTPUTDIR),/dev/null),/dev/null) ifeq ($(call WriteDirExists,$(OUTPUTDIR),/dev/null),/dev/null)
_outputdir_error:=$(error "ERROR: OUTPUTDIR '$(OUTPUTDIR)' not created or not writable") _outputdir_error:=$(error "ERROR: OUTPUTDIR '$(OUTPUTDIR)' not created or not writable")
endif endif
endif
# Define absolute path if needed and check for spaces and null value # Define absolute path if needed and check for spaces and null value
ifndef ABS_OUTPUTDIR ifndef ABS_OUTPUTDIR
ABS_OUTPUTDIR:=$(call FullPath,$(OUTPUTDIR)) ABS_OUTPUTDIR:=$(call FullPath,$(OUTPUTDIR))

View File

@ -1,5 +1,5 @@
# #
# Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. # Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -31,7 +31,7 @@ include $(BUILDDIR)/common/Release.gmk
JCE_MANIFEST_FILE = $(TEMPDIR)/manifest.mf JCE_MANIFEST_FILE = $(TEMPDIR)/manifest.mf
$(JCE_MANIFEST_FILE): $(MAINMANIFEST) $(JCE_MANIFEST_FILE): $(MAINMANIFEST)
$(prep-target) $(prep-target)
( $(SED) "s/@@RELEASE@@/$(RELEASE)/" $(MAINMANIFEST); \ ( $(SED) "s/@@RELEASE@@/$(RELEASE)/" $<; \
$(ECHO) "Extension-Name: javax.crypto"; \ $(ECHO) "Extension-Name: javax.crypto"; \
$(ECHO) "Implementation-Vendor-Id: com.sun"; ) > $@ $(ECHO) "Implementation-Vendor-Id: com.sun"; ) > $@
@ -75,6 +75,7 @@ endef
define sign-target define sign-target
$(BOOT_JARSIGNER_CMD) -keystore $(SIGNING_KEYSTORE) \ $(BOOT_JARSIGNER_CMD) -keystore $(SIGNING_KEYSTORE) \
$@ $(SIGNING_ALIAS) < $(SIGNING_PASSPHRASE) $@ $(SIGNING_ALIAS) < $(SIGNING_PASSPHRASE)
@$(java-vm-cleanup)
@$(ECHO) "\nJar codesigning finished." @$(ECHO) "\nJar codesigning finished."
endef endef
@ -88,13 +89,15 @@ define release-warning
endef endef
# #
# Convenience macro for steps needed to sign a jar file. # Convenience macros for signing a jar file.
#
# Call through $(call sign-file, target file)
# #
define sign-file define sign-file
$(presign) $(presign)
$(install-file) $(prep-target)
$(CP) $1 $@
$(sign-target) $(sign-target)
@$(java-vm-cleanup)
endef endef
# #

View File

@ -1,5 +1,5 @@
# #
# Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. # Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -96,7 +96,7 @@
# sign-jar Builds/signs jce.jar file (no install) # sign-jar Builds/signs jce.jar file (no install)
# sign-policy Builds/signs policy files (no install) # sign-policy Builds/signs policy files (no install)
# #
# obfus Builds/obfuscates/signs/installs jce.jar # obfus Builds/obfuscates/signs jce.jar
# #
# release Builds all targets in preparation # release Builds all targets in preparation
# for workspace integration. # for workspace integration.
@ -110,8 +110,24 @@ BUILDDIR = ../..
PACKAGE = javax.crypto PACKAGE = javax.crypto
PRODUCT = sun PRODUCT = sun
#
# The following is for when we need to do postprocessing
# (signing/obfuscation) against a read-only build. If the OUTPUTDIR
# isn't writable, the build currently crashes out.
#
ifndef OPENJDK
ifdef ALT_JCE_BUILD_DIR
# =====================================================
# Where to place the output, in case we're building from a read-only
# build area. (e.g. a release engineering build.)
JCE_BUILD_DIR=${ALT_JCE_BUILD_DIR}
IGNORE_WRITABLE_OUTPUTDIR_TEST=true
else
JCE_BUILD_DIR=${TEMPDIR}
endif
endif
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
include Defs-jce.gmk
# #
# Location for the newly built classfiles. # Location for the newly built classfiles.
@ -158,6 +174,8 @@ endif # OPENJDK
# #
UNSIGNED_DIR = $(TEMPDIR)/unsigned UNSIGNED_DIR = $(TEMPDIR)/unsigned
include Defs-jce.gmk
# ===================================================== # =====================================================
# Build the unsigned jce.jar file. Signing/obfuscation comes later. # Build the unsigned jce.jar file. Signing/obfuscation comes later.
@ -299,7 +317,7 @@ ifndef OPENJDK
# Sign the various jar files. Not needed for OpenJDK. # Sign the various jar files. Not needed for OpenJDK.
# #
SIGNED_DIR = $(TEMPDIR)/signed SIGNED_DIR = $(JCE_BUILD_DIR)/signed
SIGNED_POLICY_BUILDDIR = $(SIGNED_DIR)/policy SIGNED_POLICY_BUILDDIR = $(SIGNED_DIR)/policy
SIGNED_POLICY_FILES = \ SIGNED_POLICY_FILES = \
@ -312,61 +330,87 @@ sign-jar: $(SIGNED_DIR)/jce.jar
sign-policy: $(SIGNED_POLICY_FILES) sign-policy: $(SIGNED_POLICY_FILES)
ifndef ALT_JCE_BUILD_DIR
$(SIGNED_DIR)/jce.jar: $(UNSIGNED_DIR)/jce.jar $(SIGNED_DIR)/jce.jar: $(UNSIGNED_DIR)/jce.jar
$(sign-file) else
#
# We have to remove the build dependency, otherwise, we'll try to rebuild it
# which we can't do on a read-only filesystem.
#
$(SIGNED_DIR)/jce.jar:
@if [ ! -r $(UNSIGNED_DIR)/jce.jar ] ; then \
$(ECHO) "Couldn't find $(UNSIGNED_DIR)/jce.jar"; \
exit 1; \
fi
endif
$(call sign-file, $(UNSIGNED_DIR)/jce.jar)
$(SIGNED_POLICY_BUILDDIR)/unlimited/US_export_policy.jar: \ $(SIGNED_POLICY_BUILDDIR)/unlimited/US_export_policy.jar: \
$(UNSIGNED_POLICY_BUILDDIR)/unlimited/US_export_policy.jar $(UNSIGNED_POLICY_BUILDDIR)/unlimited/US_export_policy.jar
$(sign-file) $(call sign-file, $<)
$(SIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar: \ $(SIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar: \
$(UNSIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar $(UNSIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar
$(sign-file) $(call sign-file, $<)
$(SIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar: \ $(SIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar: \
$(UNSIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar $(UNSIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar
$(sign-file) $(call sign-file, $<)
$(SIGNED_POLICY_BUILDDIR)/limited/local_policy.jar: \ $(SIGNED_POLICY_BUILDDIR)/limited/local_policy.jar: \
$(UNSIGNED_POLICY_BUILDDIR)/limited/local_policy.jar $(UNSIGNED_POLICY_BUILDDIR)/limited/local_policy.jar
$(sign-file) $(call sign-file, $<)
# ===================================================== # =====================================================
# Obfuscate/sign/install the JDK build. Not needed for OpenJDK. # Obfuscate/sign/install the JDK build. Not needed for OpenJDK.
# #
OBFUS_DIR = $(TEMPDIR)/obfus OBFUS_DIR = $(JCE_BUILD_DIR)/obfus/jce
CLOSED_DIR = $(BUILDDIR)/closed/javax/crypto CLOSED_DIR = $(BUILDDIR)/closed/javax/crypto
obfus: $(OBFUS_DIR)/jce.jar obfus: $(OBFUS_DIR)/jce.jar
$(release-warning) $(release-warning)
$(OBFUS_DIR)/jce.jar: build-jar $(JCE_MANIFEST_FILE) ifndef ALT_JCE_BUILD_DIR
$(OBFUS_DIR)/jce.jar: build-jar $(JCE_MANIFEST_FILE) $(OBFUS_DIR)/framework.dox
else
#
# We have to remove the build dependency, otherwise, we'll try to rebuild it
# which we can't do on a read-only filesystem.
#
$(OBFUS_DIR)/jce.jar: $(JCE_MANIFEST_FILE) $(OBFUS_DIR)/framework.dox
@if [ ! -d $(CLASSDESTDIR) ] ; then \
$(ECHO) "Couldn't find $(CLASSDESTDIR)"; \
exit 1; \
fi
endif
@$(ECHO) ">>>Obfuscating JCE framework..."
$(presign) $(presign)
$(preobfus) $(preobfus)
@$(ECHO) ">>>Obfuscating JCE framework..."
$(prep-target) $(prep-target)
$(CD) $(OBFUS_DIR); \ $(CD) $(OBFUS_DIR); \
$(OBFUSCATOR) -fv \ $(OBFUSCATOR) -fv framework.dox
$(CURRENT_DIRECTORY)/$(CLOSED_DIR)/obfus/framework.dox
@$(CD) $(OBFUS_DIR); $(java-vm-cleanup) @$(CD) $(OBFUS_DIR); $(java-vm-cleanup)
@#
@# The sun.security.internal classes are currently not obfuscated @# The sun.security.internal classes are currently not obfuscated
@# due to an obfus problem. Manually copy them to the build directory @# due to an obfus problem. Manually copy them to the build directory
@# so that they are included in the jce.jar file. @# so that they are included in the jce.jar file.
@#
$(CP) -r $(CLASSDESTDIR)/sun $(OBFUS_DIR)/build $(CP) -r $(CLASSDESTDIR)/sun $(OBFUS_DIR)/build
$(RM) $(UNSIGNED_DIR)/jce.jar
$(BOOT_JAR_CMD) cmf $(JCE_MANIFEST_FILE) $@ \ $(BOOT_JAR_CMD) cmf $(JCE_MANIFEST_FILE) $@ \
-C $(OBFUS_DIR)/build javax \ -C $(OBFUS_DIR)/build javax \
-C $(OBFUS_DIR)/build sun \ -C $(OBFUS_DIR)/build sun \
$(JAR_JFLAGS) $(JAR_JFLAGS)
$(sign-target) $(sign-target)
$(MKDIR) -p $(dir $(JAR_DESTFILE))
$(RM) $(JAR_DESTFILE)
$(CP) $@ $(JAR_DESTFILE)
@$(java-vm-cleanup) @$(java-vm-cleanup)
$(OBFUS_DIR)/framework.dox: $(CLOSED_DIR)/obfus/framework.dox
@$(ECHO) ">>>Creating framework.dox"
$(prep-target)
$(SED) "s:@@TEMPDIR@@:$(ABS_TEMPDIR):" $< > $@
# #
# The current obfuscator has a limitation in that it currently only # The current obfuscator has a limitation in that it currently only
# supports up to v49 class file format. Force v49 classfiles in our # supports up to v49 class file format. Force v49 classfiles in our
@ -380,26 +424,27 @@ TARGET_CLASS_VERSION = 5
# unlimited policy file distribution, etc. # unlimited policy file distribution, etc.
# #
release: $(OBFUS_DIR)/jce.jar sign-policy release: $(OBFUS_DIR)/jce.jar sign-policy $(CLOSED_DIR)/doc/COPYRIGHT.html \
$(CLOSED_DIR)/doc/README.txt
$(RM) -r \ $(RM) -r \
$(RELEASE_DIR)/UnlimitedJCEPolicy \ $(JCE_BUILD_DIR)/release/UnlimitedJCEPolicy \
$(RELEASE_DIR)/jce.jar \ $(JCE_BUILD_DIR)/release/jce.jar \
$(RELEASE_DIR)/US_export_policy.jar \ $(JCE_BUILD_DIR)/release/US_export_policy.jar \
$(RELEASE_DIR)/local_policy.jar \ $(JCE_BUILD_DIR)/release/local_policy.jar \
$(RELEASE_DIR)/UnlimitedJCEPolicy.zip $(JCE_BUILD_DIR)/release/UnlimitedJCEPolicy.zip
$(MKDIR) -p $(RELEASE_DIR)/UnlimitedJCEPolicy $(MKDIR) -p $(JCE_BUILD_DIR)/release/UnlimitedJCEPolicy
$(CP) $(OBFUS_DIR)/jce.jar $(RELEASE_DIR) $(CP) $(OBFUS_DIR)/jce.jar $(JCE_BUILD_DIR)/release
$(CP) -r \ $(CP) \
$(SIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar \ $(SIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar \
$(SIGNED_POLICY_BUILDDIR)/limited/local_policy.jar \ $(SIGNED_POLICY_BUILDDIR)/limited/local_policy.jar \
$(RELEASE_DIR) $(JCE_BUILD_DIR)/release
$(CP) \ $(CP) \
$(SIGNED_POLICY_BUILDDIR)/unlimited/US_export_policy.jar \ $(SIGNED_POLICY_BUILDDIR)/unlimited/US_export_policy.jar \
$(SIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar \ $(SIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar \
$(RELEASE_DIR)/UnlimitedJCEPolicy $(CLOSED_DIR)/doc/COPYRIGHT.html \
$(CP) $(CLOSED_DIR)/doc/COPYRIGHT.html \ $(CLOSED_DIR)/doc/README.txt \
$(CLOSED_DIR)/doc/README.txt $(RELEASE_DIR)/UnlimitedJCEPolicy $(JCE_BUILD_DIR)/release/UnlimitedJCEPolicy
cd $(RELEASE_DIR) ; \ cd $(JCE_BUILD_DIR)/release ; \
$(ZIPEXE) -qr UnlimitedJCEPolicy.zip UnlimitedJCEPolicy $(ZIPEXE) -qr UnlimitedJCEPolicy.zip UnlimitedJCEPolicy
$(release-warning) $(release-warning)
@ -478,7 +523,8 @@ endif
clobber clean:: clobber clean::
$(RM) -r $(JAR_DESTFILE) $(POLICY_DESTDIR)/US_export_policy.jar \ $(RM) -r $(JAR_DESTFILE) $(POLICY_DESTDIR)/US_export_policy.jar \
$(POLICY_DESTDIR)/local_policy.jar $(DELETE_DIRS) $(TEMPDIR) $(POLICY_DESTDIR)/local_policy.jar $(DELETE_DIRS) $(TEMPDIR) \
$(JCE_BUILD_DIR)
.PHONY: build-jar jar build-policy unlimited limited install-jar \ .PHONY: build-jar jar build-policy unlimited limited install-jar \
install-limited install-unlimited install-limited install-unlimited

View File

@ -1,5 +1,5 @@
# #
# Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. # Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -92,8 +92,25 @@ BUILDDIR = ../../..
PACKAGE = sun.security.mscapi PACKAGE = sun.security.mscapi
LIBRARY = sunmscapi LIBRARY = sunmscapi
PRODUCT = sun PRODUCT = sun
#
# The following is for when we need to do postprocessing
# (signing/obfuscation) against a read-only build. If the OUTPUTDIR
# isn't writable, the build currently crashes out.
#
ifndef OPENJDK
ifdef ALT_JCE_BUILD_DIR
# =====================================================
# Where to place the output, in case we're building from a read-only
# build area. (e.g. a release engineering build.)
JCE_BUILD_DIR=${ALT_JCE_BUILD_DIR}
IGNORE_WRITABLE_OUTPUTDIR_TEST=true
else
JCE_BUILD_DIR=${TEMPDIR}
endif
endif
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
include $(BUILDDIR)/javax/crypto/Defs-jce.gmk
CPLUSPLUSLIBRARY=true CPLUSPLUSLIBRARY=true
@ -163,6 +180,8 @@ all: build-jar install-prebuilt
$(build-warning) $(build-warning)
endif endif
include $(BUILDDIR)/javax/crypto/Defs-jce.gmk
# ===================================================== # =====================================================
# Build the unsigned sunmscapi.jar file. # Build the unsigned sunmscapi.jar file.
@ -200,14 +219,26 @@ ifndef OPENJDK
# Sign the provider jar file. Not needed for OpenJDK. # Sign the provider jar file. Not needed for OpenJDK.
# #
SIGNED_DIR = $(TEMPDIR)/signed SIGNED_DIR = $(JCE_BUILD_DIR)/signed
sign: sign-jar sign: sign-jar
sign-jar: $(SIGNED_DIR)/sunmscapi.jar sign-jar: $(SIGNED_DIR)/sunmscapi.jar
ifndef ALT_JCE_BUILD_DIR
$(SIGNED_DIR)/sunmscapi.jar: $(UNSIGNED_DIR)/sunmscapi.jar $(SIGNED_DIR)/sunmscapi.jar: $(UNSIGNED_DIR)/sunmscapi.jar
$(sign-file) else
#
# We have to remove the build dependency, otherwise, we'll try to rebuild it
# which we can't do on a read-only filesystem.
#
$(SIGNED_DIR)/sunmscapi.jar:
@if [ ! -r $(UNSIGNED_DIR)/sunmscapi.jar ] ; then \
$(ECHO) "Couldn't find $(UNSIGNED_DIR)/sunmscapi.jar"; \
exit 1; \
fi
endif
$(call sign-file, $(UNSIGNED_DIR)/sunmscapi.jar)
# ===================================================== # =====================================================
@ -215,9 +246,9 @@ $(SIGNED_DIR)/sunmscapi.jar: $(UNSIGNED_DIR)/sunmscapi.jar
# #
release: $(SIGNED_DIR)/sunmscapi.jar release: $(SIGNED_DIR)/sunmscapi.jar
$(RM) $(RELEASE_DIR)/sunmscapi.jar $(RM) $(JCE_BUILD_DIR)/release/sunmscapi.jar
$(MKDIR) -p $(RELEASE_DIR) $(MKDIR) -p $(JCE_BUILD_DIR)/release
$(CP) $(SIGNED_DIR)/sunmscapi.jar $(RELEASE_DIR) $(CP) $(SIGNED_DIR)/sunmscapi.jar $(JCE_BUILD_DIR)/release
$(release-warning) $(release-warning)
endif # OPENJDK endif # OPENJDK
@ -255,7 +286,7 @@ endif
# #
clobber clean:: clobber clean::
$(RM) -r $(JAR_DESTFILE) $(TEMPDIR) $(RM) -r $(JAR_DESTFILE) $(TEMPDIR) $(JCE_BUILD_DIR)
.PHONY: build-jar jar install-jar .PHONY: build-jar jar install-jar
ifndef OPENJDK ifndef OPENJDK

View File

@ -1,5 +1,5 @@
# #
# Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. # Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -92,8 +92,25 @@ BUILDDIR = ../../..
PACKAGE = sun.security.pkcs11 PACKAGE = sun.security.pkcs11
LIBRARY = j2pkcs11 LIBRARY = j2pkcs11
PRODUCT = sun PRODUCT = sun
#
# The following is for when we need to do postprocessing
# (signing/obfuscation) against a read-only build. If the OUTPUTDIR
# isn't writable, the build currently crashes out.
#
ifndef OPENJDK
ifdef ALT_JCE_BUILD_DIR
# =====================================================
# Where to place the output, in case we're building from a read-only
# build area. (e.g. a release engineering build.)
JCE_BUILD_DIR=${ALT_JCE_BUILD_DIR}
IGNORE_WRITABLE_OUTPUTDIR_TEST=true
else
JCE_BUILD_DIR=${TEMPDIR}
endif
endif
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
include $(BUILDDIR)/javax/crypto/Defs-jce.gmk
# #
# C and Java Files # C and Java Files
@ -163,6 +180,8 @@ all: build-jar install-prebuilt
$(build-warning) $(build-warning)
endif endif
include $(BUILDDIR)/javax/crypto/Defs-jce.gmk
# ===================================================== # =====================================================
# Build the unsigned sunpkcs11.jar file. # Build the unsigned sunpkcs11.jar file.
@ -200,14 +219,26 @@ ifndef OPENJDK
# Sign the provider jar file. Not needed for OpenJDK. # Sign the provider jar file. Not needed for OpenJDK.
# #
SIGNED_DIR = $(TEMPDIR)/signed SIGNED_DIR = $(JCE_BUILD_DIR)/signed
sign: sign-jar sign: sign-jar
sign-jar: $(SIGNED_DIR)/sunpkcs11.jar sign-jar: $(SIGNED_DIR)/sunpkcs11.jar
ifndef ALT_JCE_BUILD_DIR
$(SIGNED_DIR)/sunpkcs11.jar: $(UNSIGNED_DIR)/sunpkcs11.jar $(SIGNED_DIR)/sunpkcs11.jar: $(UNSIGNED_DIR)/sunpkcs11.jar
$(sign-file) else
#
# We have to remove the build dependency, otherwise, we'll try to rebuild it
# which we can't do on a read-only filesystem.
#
$(SIGNED_DIR)/sunpkcs11.jar:
@if [ ! -r $(UNSIGNED_DIR)/sunpkcs11.jar ] ; then \
$(ECHO) "Couldn't find $(UNSIGNED_DIR)/sunpkcs11.jar"; \
exit 1; \
fi
endif
$(call sign-file, $(UNSIGNED_DIR)/sunpkcs11.jar)
# ===================================================== # =====================================================
@ -215,9 +246,9 @@ $(SIGNED_DIR)/sunpkcs11.jar: $(UNSIGNED_DIR)/sunpkcs11.jar
# #
release: $(SIGNED_DIR)/sunpkcs11.jar release: $(SIGNED_DIR)/sunpkcs11.jar
$(RM) $(RELEASE_DIR)/sunpkcs11.jar $(RM) $(JCE_BUILD_DIR)/release/sunpkcs11.jar
$(MKDIR) -p $(RELEASE_DIR) $(MKDIR) -p $(JCE_BUILD_DIR)/release
$(CP) $(SIGNED_DIR)/sunpkcs11.jar $(RELEASE_DIR) $(CP) $(SIGNED_DIR)/sunpkcs11.jar $(JCE_BUILD_DIR)/release
$(release-warning) $(release-warning)
endif # OPENJDK endif # OPENJDK
@ -255,7 +286,7 @@ endif
# #
clobber clean:: clobber clean::
$(RM) -r $(JAR_DESTFILE) $(TEMPDIR) $(RM) -r $(JAR_DESTFILE) $(TEMPDIR) $(JCE_BUILD_DIR)
.PHONY: build-jar jar install-jar .PHONY: build-jar jar install-jar
ifndef OPENJDK ifndef OPENJDK

View File

@ -34,8 +34,6 @@ import java.util.Set;
import java.util.HashSet; import java.util.HashSet;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.security.AccessControlContext; import java.security.AccessControlContext;
import java.security.Permission; import java.security.Permission;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
@ -51,7 +49,6 @@ import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException; import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException; import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException; import javax.management.InvalidAttributeValueException;
import javax.management.JMException;
import javax.management.JMRuntimeException; import javax.management.JMRuntimeException;
import javax.management.ListenerNotFoundException; import javax.management.ListenerNotFoundException;
import javax.management.MalformedObjectNameException; import javax.management.MalformedObjectNameException;
@ -84,11 +81,10 @@ import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;
import com.sun.jmx.mbeanserver.DynamicMBean2; import com.sun.jmx.mbeanserver.DynamicMBean2;
import com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository; import com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository;
import com.sun.jmx.mbeanserver.MBeanInstantiator; import com.sun.jmx.mbeanserver.MBeanInstantiator;
import com.sun.jmx.mbeanserver.MXBeanSupport;
import com.sun.jmx.mbeanserver.Repository; import com.sun.jmx.mbeanserver.Repository;
import com.sun.jmx.mbeanserver.NamedObject; import com.sun.jmx.mbeanserver.NamedObject;
import com.sun.jmx.defaults.ServiceName;
import com.sun.jmx.mbeanserver.Introspector; import com.sun.jmx.mbeanserver.Introspector;
import com.sun.jmx.mbeanserver.Util;
import com.sun.jmx.remote.util.EnvHelp; import com.sun.jmx.remote.util.EnvHelp;
/** /**
@ -623,18 +619,9 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
List<String> result = new ArrayList<String>(domains.length); List<String> result = new ArrayList<String>(domains.length);
for (int i = 0; i < domains.length; i++) { for (int i = 0; i < domains.length; i++) {
try { try {
ObjectName domain = new ObjectName(domains[i] + ":x=x"); ObjectName domain = Util.newObjectName(domains[i] + ":x=x");
checkMBeanPermission((String) null, null, domain, "getDomains"); checkMBeanPermission((String) null, null, domain, "getDomains");
result.add(domains[i]); result.add(domains[i]);
} catch (MalformedObjectNameException e) {
// Should never occur... But let's log it just in case.
if (MBEANSERVER_LOGGER.isLoggable(Level.SEVERE)) {
MBEANSERVER_LOGGER.logp(Level.SEVERE,
DefaultMBeanServerInterceptor.class.getName(),
"getDomains",
"Failed to check permission for domain = " +
domains[i], e);
}
} catch (SecurityException e) { } catch (SecurityException e) {
// OK: Do not add this domain to the list // OK: Do not add this domain to the list
} }

View File

@ -107,10 +107,7 @@ class MBeanAnalyzer<M> {
private MBeanAnalyzer(Class<?> mbeanInterface, private MBeanAnalyzer(Class<?> mbeanInterface,
MBeanIntrospector<M> introspector) MBeanIntrospector<M> introspector)
throws NotCompliantMBeanException { throws NotCompliantMBeanException {
if (!mbeanInterface.isInterface()) { introspector.checkCompliance(mbeanInterface);
throw new NotCompliantMBeanException("Not an interface: " +
mbeanInterface.getName());
}
try { try {
initMaps(mbeanInterface, introspector); initMaps(mbeanInterface, introspector);
@ -121,11 +118,10 @@ class MBeanAnalyzer<M> {
// Introspect the mbeanInterface and initialize this object's maps. // Introspect the mbeanInterface and initialize this object's maps.
// //
private void initMaps(Class<?> mbeanInterface, private void initMaps(Class<?> mbeanType,
MBeanIntrospector<M> introspector) throws Exception { MBeanIntrospector<M> introspector) throws Exception {
final Method[] methodArray = mbeanInterface.getMethods(); final List<Method> methods1 = introspector.getMethods(mbeanType);
final List<Method> methods = eliminateCovariantMethods(methods1);
final List<Method> methods = eliminateCovariantMethods(methodArray);
/* Run through the methods to detect inconsistencies and to enable /* Run through the methods to detect inconsistencies and to enable
us to give getter and setter together to visitAttribute. */ us to give getter and setter together to visitAttribute. */
@ -234,13 +230,13 @@ class MBeanAnalyzer<M> {
but existing code may depend on it and users may be used to seeing but existing code may depend on it and users may be used to seeing
operations or attributes appear in a particular order. */ operations or attributes appear in a particular order. */
static List<Method> static List<Method>
eliminateCovariantMethods(Method[] methodArray) { eliminateCovariantMethods(List<Method> startMethods) {
// We are assuming that you never have very many methods with the // We are assuming that you never have very many methods with the
// same name, so it is OK to use algorithms that are quadratic // same name, so it is OK to use algorithms that are quadratic
// in the number of methods with the same name. // in the number of methods with the same name.
final int len = methodArray.length; final int len = startMethods.size();
final Method[] sorted = methodArray.clone(); final Method[] sorted = startMethods.toArray(new Method[len]);
Arrays.sort(sorted,MethodOrder.instance); Arrays.sort(sorted,MethodOrder.instance);
final Set<Method> overridden = newSet(); final Set<Method> overridden = newSet();
for (int i=1;i<len;i++) { for (int i=1;i<len;i++) {
@ -259,7 +255,7 @@ class MBeanAnalyzer<M> {
} }
} }
final List<Method> methods = newList(Arrays.asList(methodArray)); final List<Method> methods = newList(startMethods);
methods.removeAll(overridden); methods.removeAll(overridden);
return methods; return methods;
} }

View File

@ -34,6 +34,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.WeakHashMap; import java.util.WeakHashMap;
@ -169,6 +170,19 @@ abstract class MBeanIntrospector<M> {
*/ */
abstract Descriptor getMBeanDescriptor(Class<?> resourceClass); abstract Descriptor getMBeanDescriptor(Class<?> resourceClass);
void checkCompliance(Class<?> mbeanType) throws NotCompliantMBeanException {
if (!mbeanType.isInterface()) {
throw new NotCompliantMBeanException("Not an interface: " +
mbeanType.getName());
}
}
/**
* Get the methods to be analyzed to build the MBean interface.
*/
List<Method> getMethods(final Class<?> mbeanType) throws Exception {
return Arrays.asList(mbeanType.getMethods());
}
final PerInterface<M> getPerInterface(Class<?> mbeanInterface) final PerInterface<M> getPerInterface(Class<?> mbeanInterface)
throws NotCompliantMBeanException { throws NotCompliantMBeanException {

View File

@ -0,0 +1,81 @@
/*
* Copyright 2007 Sun Microsystems, 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.jmx.mbeanserver;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import javax.management.NotCompliantMBeanException;
import javax.management.Notification;
/**
* <p>A variant of {@code StandardMBeanSupport} where the only
* methods included are public getters. This is used by
* {@code QueryNotificationFilter} to pretend that a Notification is
* an MBean so it can have a query evaluated on it. Standard queries
* never set attributes or invoke methods but custom queries could and
* we don't want to allow that. Also we don't want to fail if a
* Notification happens to have inconsistent types in a pair of getX and
* setX methods, and we want to include the Object.getClass() method.
*/
public class NotificationMBeanSupport extends StandardMBeanSupport {
public <T extends Notification> NotificationMBeanSupport(T n)
throws NotCompliantMBeanException {
super(n, Util.<Class<T>>cast(n.getClass()));
}
@Override
MBeanIntrospector<Method> getMBeanIntrospector() {
return introspector;
}
private static class Introspector extends StandardMBeanIntrospector {
@Override
void checkCompliance(Class<?> mbeanType) {}
@Override
List<Method> getMethods(final Class<?> mbeanType)
throws Exception {
List<Method> methods = new ArrayList<Method>();
for (Method m : mbeanType.getMethods()) {
String name = m.getName();
Class<?> ret = m.getReturnType();
if (m.getParameterTypes().length == 0) {
if ((name.startsWith("is") && name.length() > 2 &&
ret == boolean.class) ||
(name.startsWith("get") && name.length() > 3 &&
ret != void.class)) {
methods.add(m);
}
}
}
return methods;
}
}
private static final MBeanIntrospector<Method> introspector =
new Introspector();
}

View File

@ -438,7 +438,7 @@ public abstract class OpenConverter {
c.getClassLoader() == null); c.getClassLoader() == null);
final List<Method> methods = final List<Method> methods =
MBeanAnalyzer.eliminateCovariantMethods(c.getMethods()); MBeanAnalyzer.eliminateCovariantMethods(Arrays.asList(c.getMethods()));
final SortedMap<String,Method> getterMap = newSortedMap(); final SortedMap<String,Method> getterMap = newSortedMap();
/* Select public methods that look like "T getX()" or "boolean /* Select public methods that look like "T getX()" or "boolean
@ -1118,11 +1118,11 @@ public abstract class OpenConverter {
final Class<ConstructorProperties> propertyNamesClass = ConstructorProperties.class; final Class<ConstructorProperties> propertyNamesClass = ConstructorProperties.class;
Class targetClass = getTargetClass(); Class targetClass = getTargetClass();
Constructor[] constrs = targetClass.getConstructors(); Constructor<?>[] constrs = targetClass.getConstructors();
// Applicable if and only if there are any annotated constructors // Applicable if and only if there are any annotated constructors
List<Constructor> annotatedConstrList = newList(); List<Constructor<?>> annotatedConstrList = newList();
for (Constructor constr : constrs) { for (Constructor<?> constr : constrs) {
if (Modifier.isPublic(constr.getModifiers()) if (Modifier.isPublic(constr.getModifiers())
&& constr.getAnnotation(propertyNamesClass) != null) && constr.getAnnotation(propertyNamesClass) != null)
annotatedConstrList.add(constr); annotatedConstrList.add(constr);
@ -1152,7 +1152,7 @@ public abstract class OpenConverter {
// Also remember the set of properties in that constructor // Also remember the set of properties in that constructor
// so we can test unambiguity. // so we can test unambiguity.
Set<BitSet> getterIndexSets = newSet(); Set<BitSet> getterIndexSets = newSet();
for (Constructor constr : annotatedConstrList) { for (Constructor<?> constr : annotatedConstrList) {
String[] propertyNames = String[] propertyNames =
constr.getAnnotation(propertyNamesClass).value(); constr.getAnnotation(propertyNamesClass).value();
@ -1309,10 +1309,10 @@ public abstract class OpenConverter {
} }
private static class Constr { private static class Constr {
final Constructor constructor; final Constructor<?> constructor;
final int[] paramIndexes; final int[] paramIndexes;
final BitSet presentParams; final BitSet presentParams;
Constr(Constructor constructor, int[] paramIndexes, Constr(Constructor<?> constructor, int[] paramIndexes,
BitSet presentParams) { BitSet presentParams) {
this.constructor = constructor; this.constructor = constructor;
this.paramIndexes = paramIndexes; this.paramIndexes = paramIndexes;

View File

@ -415,17 +415,8 @@ public class Repository {
boolean to_default_domain = false; boolean to_default_domain = false;
// Set domain to default if domain is empty and not already set // Set domain to default if domain is empty and not already set
if (dom.length() == 0) { if (dom.length() == 0)
try { name = Util.newObjectName(domain + name.toString());
name = new ObjectName(domain + name.toString());
} catch (MalformedObjectNameException e) {
if (MBEANSERVER_LOGGER.isLoggable(Level.FINEST)) {
MBEANSERVER_LOGGER.logp(Level.FINEST,
Repository.class.getName(), "addMBean",
"Unexpected MalformedObjectNameException", e);
}
}
}
// Do we have default domain ? // Do we have default domain ?
if (dom == domain) { if (dom == domain) {

View File

@ -38,6 +38,8 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
public class Util { public class Util {
static <K, V> Map<K, V> newMap() { static <K, V> Map<K, V> newMap() {
@ -85,6 +87,14 @@ public class Util {
return new ArrayList<E>(c); return new ArrayList<E>(c);
} }
public static ObjectName newObjectName(String s) {
try {
return new ObjectName(s);
} catch (MalformedObjectNameException e) {
throw new IllegalArgumentException(e);
}
}
/* This method can be used by code that is deliberately violating the /* This method can be used by code that is deliberately violating the
* allowed checked casts. Rather than marking the whole method containing * allowed checked casts. Rather than marking the whole method containing
* the code with @SuppressWarnings, you can use a call to this method for * the code with @SuppressWarnings, you can use a call to this method for

View File

@ -1,4 +1,4 @@
CTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html> <html>
<head> <head>
<!-- <!--

View File

@ -1553,7 +1553,7 @@ class MetaData {
private static String[] getConstructorProperties(Class type) { private static String[] getConstructorProperties(Class type) {
String[] names = null; String[] names = null;
int length = 0; int length = 0;
for (Constructor constructor : type.getConstructors()) { for (Constructor<?> constructor : type.getConstructors()) {
String[] value = getAnnotationValue(constructor); String[] value = getAnnotationValue(constructor);
if ((value != null) && (length < value.length) && isValid(constructor, value)) { if ((value != null) && (length < value.length) && isValid(constructor, value)) {
names = value; names = value;
@ -1563,14 +1563,14 @@ class MetaData {
return names; return names;
} }
private static String[] getAnnotationValue(Constructor constructor) { private static String[] getAnnotationValue(Constructor<?> constructor) {
ConstructorProperties annotation = constructor.getAnnotation(ConstructorProperties.class); ConstructorProperties annotation = constructor.getAnnotation(ConstructorProperties.class);
return (annotation != null) return (annotation != null)
? annotation.value() ? annotation.value()
: null; : null;
} }
private static boolean isValid(Constructor constructor, String[] names) { private static boolean isValid(Constructor<?> constructor, String[] names) {
Class[] parameters = constructor.getParameterTypes(); Class[] parameters = constructor.getParameterTypes();
if (names.length != parameters.length) { if (names.length != parameters.length) {
return false; return false;

View File

@ -636,7 +636,11 @@ public interface Instrumentation {
* @param transformer * @param transformer
* The ClassFileTransformer which wraps using this prefix. * The ClassFileTransformer which wraps using this prefix.
* @param prefix * @param prefix
* The prefix which has been applied to wrapped native methods. * The prefix to apply to wrapped native methods when
* retrying a failed native method resolution. If prefix
* is either <code>null</code> or the empty string, then
* failed native method resolutions are not retried for
* this transformer.
* @throws java.lang.NullPointerException if passed a <code>null</code> transformer. * @throws java.lang.NullPointerException if passed a <code>null</code> transformer.
* @throws java.lang.UnsupportedOperationException if the current configuration of * @throws java.lang.UnsupportedOperationException if the current configuration of
* the JVM does not allow setting a native method prefix * the JVM does not allow setting a native method prefix

View File

@ -50,7 +50,7 @@ import javax.management.loading.ClassLoaderRepository;
* server. A Java object cannot be registered in the MBean server * server. A Java object cannot be registered in the MBean server
* unless it is a JMX compliant MBean.</p> * unless it is a JMX compliant MBean.</p>
* *
* <p>When an MBean is registered or unregistered in the MBean server * <p id="notif">When an MBean is registered or unregistered in the MBean server
* a {@link javax.management.MBeanServerNotification * a {@link javax.management.MBeanServerNotification
* MBeanServerNotification} Notification is emitted. To register an * MBeanServerNotification} Notification is emitted. To register an
* object as listener to MBeanServerNotifications you should call the * object as listener to MBeanServerNotifications you should call the
@ -258,27 +258,43 @@ import javax.management.loading.ClassLoaderRepository;
*/ */
public interface MBeanServer extends MBeanServerConnection { public interface MBeanServer extends MBeanServerConnection {
// doc comment inherited from MBeanServerConnection /**
* {@inheritDoc}
* <p>If this method successfully creates an MBean, a notification
* is sent as described <a href="#notif">above</a>.</p>
*/
public ObjectInstance createMBean(String className, ObjectName name) public ObjectInstance createMBean(String className, ObjectName name)
throws ReflectionException, InstanceAlreadyExistsException, throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException, MBeanRegistrationException, MBeanException,
NotCompliantMBeanException; NotCompliantMBeanException;
// doc comment inherited from MBeanServerConnection /**
* {@inheritDoc}
* <p>If this method successfully creates an MBean, a notification
* is sent as described <a href="#notif">above</a>.</p>
*/
public ObjectInstance createMBean(String className, ObjectName name, public ObjectInstance createMBean(String className, ObjectName name,
ObjectName loaderName) ObjectName loaderName)
throws ReflectionException, InstanceAlreadyExistsException, throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException, MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, InstanceNotFoundException; NotCompliantMBeanException, InstanceNotFoundException;
// doc comment inherited from MBeanServerConnection /**
* {@inheritDoc}
* <p>If this method successfully creates an MBean, a notification
* is sent as described <a href="#notif">above</a>.</p>
*/
public ObjectInstance createMBean(String className, ObjectName name, public ObjectInstance createMBean(String className, ObjectName name,
Object params[], String signature[]) Object params[], String signature[])
throws ReflectionException, InstanceAlreadyExistsException, throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException, MBeanRegistrationException, MBeanException,
NotCompliantMBeanException; NotCompliantMBeanException;
// doc comment inherited from MBeanServerConnection /**
* {@inheritDoc}
* <p>If this method successfully creates an MBean, a notification
* is sent as described <a href="#notif">above</a>.</p>
*/
public ObjectInstance createMBean(String className, ObjectName name, public ObjectInstance createMBean(String className, ObjectName name,
ObjectName loaderName, Object params[], ObjectName loaderName, Object params[],
String signature[]) String signature[])
@ -287,12 +303,15 @@ public interface MBeanServer extends MBeanServerConnection {
NotCompliantMBeanException, InstanceNotFoundException; NotCompliantMBeanException, InstanceNotFoundException;
/** /**
* Registers a pre-existing object as an MBean with the MBean * <p>Registers a pre-existing object as an MBean with the MBean
* server. If the object name given is null, the MBean must * server. If the object name given is null, the MBean must
* provide its own name by implementing the {@link * provide its own name by implementing the {@link
* javax.management.MBeanRegistration MBeanRegistration} interface * javax.management.MBeanRegistration MBeanRegistration} interface
* and returning the name from the {@link * and returning the name from the {@link
* MBeanRegistration#preRegister preRegister} method. * MBeanRegistration#preRegister preRegister} method.</p>
*
* <p>If this method successfully registers an MBean, a notification
* is sent as described <a href="#notif">above</a>.</p>
* *
* @param object The MBean to be registered as an MBean. * @param object The MBean to be registered as an MBean.
* @param name The object name of the MBean. May be null. * @param name The object name of the MBean. May be null.
@ -319,7 +338,12 @@ public interface MBeanServer extends MBeanServerConnection {
throws InstanceAlreadyExistsException, MBeanRegistrationException, throws InstanceAlreadyExistsException, MBeanRegistrationException,
NotCompliantMBeanException; NotCompliantMBeanException;
// doc comment inherited from MBeanServerConnection /**
* {@inheritDoc}
*
* <p>If this method successfully unregisters an MBean, a notification
* is sent as described <a href="#notif">above</a>.</p>
*/
public void unregisterMBean(ObjectName name) public void unregisterMBean(ObjectName name)
throws InstanceNotFoundException, MBeanRegistrationException; throws InstanceNotFoundException, MBeanRegistrationException;

View File

@ -26,6 +26,7 @@
package javax.management; package javax.management;
import com.sun.jmx.mbeanserver.GetPropertyAction; import com.sun.jmx.mbeanserver.GetPropertyAction;
import com.sun.jmx.mbeanserver.Util;
import java.io.IOException; import java.io.IOException;
import java.io.InvalidObjectException; import java.io.InvalidObjectException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
@ -1386,12 +1387,7 @@ public class ObjectName extends ToQueryString
throws NullPointerException { throws NullPointerException {
if (name.getClass().equals(ObjectName.class)) if (name.getClass().equals(ObjectName.class))
return name; return name;
try { return Util.newObjectName(name.getSerializedNameString());
return new ObjectName(name.getSerializedNameString());
} catch (MalformedObjectNameException e) {
throw new IllegalArgumentException("Unexpected: " + e);
// can't happen
}
} }
/** /**
@ -1950,14 +1946,7 @@ public class ObjectName extends ToQueryString
* *
* @since 1.6 * @since 1.6
*/ */
public static final ObjectName WILDCARD; public static final ObjectName WILDCARD = Util.newObjectName("*:*");
static {
try {
WILDCARD = new ObjectName("*:*");
} catch (MalformedObjectNameException e) {
throw new Error("Can't initialize wildcard name", e);
}
}
// Category : Utilities <=================================== // Category : Utilities <===================================

View File

@ -0,0 +1,417 @@
/*
* Copyright 2007 Sun Microsystems, 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package javax.management;
import com.sun.jmx.mbeanserver.NotificationMBeanSupport;
import com.sun.jmx.mbeanserver.Util;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.Set;
/**
* <p>General-purpose notification filter. This filter can be used to
* filter notifications from a possibly-remote MBean. Most filtering
* decisions can be coded using this filter, which avoids having to
* write a custom implementation of the {@link NotificationFilter}
* class. Writing a custom implementation requires you to deploy it
* on both the client and the server in the remote case, so using this class
* instead is recommended where possible.</p>
*
* <!-- <p>Because this class was introduced in version 2.0 of the JMX API,
* it may not be present on a remote JMX agent that is running an earlier
* version. The method {@link JMX#addListenerWithFilter JMX.addListenerWithFilter}
* can be used when you cannot be sure whether this class is present in the
* agent you are connecting to.</p> -->
*
* <p>This class uses the {@linkplain Query Query API} to specify the
* filtering logic. For example, to select only notifications where the
* {@linkplain Notification#getType() type} is {@code "com.example.mytype"},
* you could use</p>
*
* <pre>
* NotificationFilter filter =
* new QueryNotificationFilter("Type = 'com.example.mytype'");
* </pre>
*
* <p>or equivalently</p>
*
* <pre>
* NotificationFilter filter =
* new QueryNotificationFilter(
* Query.eq(Query.attr("Type"), Query.value("com.example.mytype")));
* </pre>
*
* <p>(This particular example could also use
* {@link NotificationFilterSupport}.)</p>
*
* <p>Here are some other examples of filters you can specify with this class.</p>
*
* <dl>
*
* <dt>{@code QueryNotificationFilter("Type = 'com.example.type1' or
* Type = 'com.example.type2'")}
* <dd>Notifications where the type is either of the given strings.
*
* <dt>{@code QueryNotificationFilter("Type in ('com.example.type1',
* 'com.example.type2')")}
* <dd>Another way to write the previous example.
*
* <dt>{@code QueryNotificationFilter("SequenceNumber > 1000")}
* <dd>Notifications where the {@linkplain Notification#getSequenceNumber()
* sequence number} is greater than 1000.
*
* <dt>{@code QueryNotificationFilter(AttributeChangeNotification.class, null)}
* <dd>Notifications where the notification class is
* {@link AttributeChangeNotification} or a subclass of it.
*
* <dt>{@code QueryNotificationFilter(AttributeChangeNotification.class,
* "AttributeName = 'Size'")}
* <dd>Notifications where the notification class is
* {@link AttributeChangeNotification} or a subclass, and where the
* {@linkplain AttributeChangeNotification#getAttributeName() name of the
* changed attribute} is {@code Size}.
*
* <dt>{@code QueryNotificationFilter(AttributeChangeNotification.class,
* "AttributeName = 'Size' and NewValue - OldValue > 100")}
* <dd>As above, but the difference between the
* {@linkplain AttributeChangeNotification#getNewValue() new value} and the
* {@linkplain AttributeChangeNotification#getOldValue() old value} must be
* greater than 100.
*
* <dt>{@code QueryNotificationFilter("like 'com.example.mydomain:*'")}
* <dd>Notifications where the {@linkplain Notification#getSource() source}
* is an ObjectName that matches the pattern.
*
* <dt>{@code QueryNotificationFilter("Source.canonicalName like
* 'com.example.mydomain:%'")}
* <dd>Another way to write the previous example.
*
* <dt>{@code QueryNotificationFilter(MBeanServerNotification.class,
* "Type = 'JMX.mbean.registered' and MBeanName.canonicalName like
* 'com.example.mydomain:%'")}
* <dd>Notifications of class {@link MBeanServerNotification} representing
* an object registered in the domain {@code com.example.mydomain}.
*
* </dl>
*
* <h4>How it works</h4>
*
* <p>Although the examples above are clear, looking closely at the
* Query API reveals a subtlety. A {@link QueryExp} is evaluated on
* an {@link ObjectName}, not a {@code Notification}.</p>
*
* <p>Every time a {@code Notification} is to be filtered by a
* {@code QueryNotificationFilter}, a special {@link MBeanServer} is created.
* This {@code MBeanServer} contains exactly one MBean, which represents the
* {@code Notification}. If the {@linkplain Notification#getSource()
* source} of the notification is an {@code ObjectName}, which is
* recommended practice, then the name of the MBean representing the
* {@code Notification} will be this {@code ObjectName}. Otherwise the
* name is unspecified.</p>
*
* <p>The query specified in the {@code QueryNotificationFilter} constructor
* is evaluated against this {@code MBeanServer} and {@code ObjectName},
* and the filter returns true if and only if the query does. If the
* query throws an exception, then the filter will return false.</p>
*
* <p>The MBean representing the {@code Notification} has one attribute for
* every property of the {@code Notification}. Specifically, for every public
* method {@code T getX()} in the {@code NotificationClass}, the MBean will
* have an attribute called {@code X} of type {@code T}. For example, if the
* {@code Notification} is an {@code AttributeChangeNotification}, then the
* MBean will have an attribute called {@code AttributeName} of type
* {@code "java.lang.String"}, corresponding to the method {@link
* AttributeChangeNotification#getAttributeName}.</p>
*
* <p>Query evaluation usually involves calls to the methods of {@code
* MBeanServer}. The methods have the following behavior:</p>
*
* <ul>
* <li>The {@link MBeanServer#getAttribute getAttribute} method returns the
* value of the corresponding property.
* <li>The {@link MBeanServer#getObjectInstance getObjectInstance}
* method returns an {@link ObjectInstance} where the {@link
* ObjectInstance#getObjectName ObjectName} is the name of the MBean and the
* {@link ObjectInstance#getClassName ClassName} is the class name of the
* {@code Notification}.
* <li>The {@link MBeanServer#isInstanceOf isInstanceOf} method returns true
* if and only if the {@code Notification}'s {@code ClassLoader} can load the
* named class, and the {@code Notification} is an {@linkplain Class#isInstance
* instance} of that class.
* </ul>
*
* <p>These are the only {@code MBeanServer} methods that are needed to
* evaluate standard queries. The behavior of the other {@code MBeanServer}
* methods is unspecified.</p>
*
* @since 1.7
*/
public class QueryNotificationFilter implements NotificationFilter {
private static final long serialVersionUID = -8408613922660635231L;
private static final ObjectName DEFAULT_NAME =
Util.newObjectName(":type=Notification");
private static final QueryExp trueQuery;
static {
ValueExp zero = Query.value(0);
trueQuery = Query.eq(zero, zero);
}
private final QueryExp query;
/**
* Construct a {@code QueryNotificationFilter} that evaluates the given
* {@code QueryExp} to determine whether to accept a notification.
*
* @param query the {@code QueryExp} to evaluate. Can be null,
* in which case all notifications are accepted.
*/
public QueryNotificationFilter(QueryExp query) {
if (query == null)
this.query = trueQuery;
else
this.query = query;
}
/**
* Construct a {@code QueryNotificationFilter} that evaluates the query
* in the given string to determine whether to accept a notification.
* The string is converted into a {@code QueryExp} using
* {@link Query#fromString Query.fromString}.
*
* @param query the string specifying the query to evaluate. Can be null,
* in which case all notifications are accepted.
*
* @throws IllegalArgumentException if the string is not a valid
* query string.
*/
public QueryNotificationFilter(String query) {
this(Query.fromString(query));
}
/**
* <p>Construct a {@code QueryNotificationFilter} that evaluates the query
* in the given string to determine whether to accept a notification,
* and where the notification must also be an instance of the given class.
* The string is converted into a {@code QueryExp} using
* {@link Query#fromString Query.fromString}.</p>
*
* @param notifClass the class that the notification must be an instance of.
* Cannot be null.
*
* @param query the string specifying the query to evaluate. Can be null,
* in which case all notifications are accepted.
*
* @throws IllegalArgumentException if the string is not a valid
* query string, or if {@code notifClass} is null.
*/
public QueryNotificationFilter(
Class<? extends Notification> notifClass, String query) {
this(Query.and(Query.isInstanceOf(Query.value(notNull(notifClass).getName())),
Query.fromString(query)));
}
private static <T> T notNull(T x) {
if (x == null)
throw new IllegalArgumentException("Null argument");
return x;
}
/**
* Retrieve the query that this notification filter will evaluate for
* each notification.
*
* @return the query.
*/
public QueryExp getQuery() {
return query;
}
public boolean isNotificationEnabled(Notification notification) {
ObjectName name;
Object source = notification.getSource();
if (source instanceof ObjectName)
name = (ObjectName) source;
else
name = DEFAULT_NAME;
MBS mbsImpl = new MBS(notification, name);
MBeanServer mbs = (MBeanServer) Proxy.newProxyInstance(
MBeanServer.class.getClassLoader(),
new Class<?>[] {MBeanServer.class},
new ForwardIH(mbsImpl));
return evalQuery(query, mbs, name);
}
private static boolean evalQuery(
QueryExp query, MBeanServer mbs, ObjectName name) {
MBeanServer oldMBS = QueryEval.getMBeanServer();
try {
if (mbs != null)
query.setMBeanServer(mbs);
return query.apply(name);
} catch (Exception e) {
return false;
} finally {
query.setMBeanServer(oldMBS);
}
}
private static class ForwardIH implements InvocationHandler {
private final MBS mbs;
ForwardIH(MBS mbs) {
this.mbs = mbs;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Method forward;
try {
forward = MBS.class.getMethod(
method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException e) {
throw new UnsupportedOperationException(method.getName());
}
try {
return forward.invoke(mbs, args);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
}
private static class MBS {
private final Notification notification;
private final ObjectName objectName;
private final ObjectInstance objectInstance;
private volatile DynamicMBean mbean;
MBS(Notification n, ObjectName name) {
this.notification = n;
this.objectName = name;
this.objectInstance = new ObjectInstance(name, n.getClass().getName());
}
private void checkName(ObjectName name) throws InstanceNotFoundException {
if (!objectName.equals(name))
throw new InstanceNotFoundException(String.valueOf(name));
}
private DynamicMBean mbean(ObjectName name)
throws InstanceNotFoundException, ReflectionException {
if (mbean == null) {
try {
mbean = new NotificationMBeanSupport(notification);
} catch (NotCompliantMBeanException e) {
throw new ReflectionException(e);
}
}
return mbean;
}
public ObjectInstance getObjectInstance(ObjectName name)
throws InstanceNotFoundException {
checkName(name);
return objectInstance;
}
public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
Set<ObjectName> names = queryNames(name, query);
switch (names.size()) {
case 0:
return Collections.emptySet();
case 1:
return Collections.singleton(objectInstance);
default:
throw new UnsupportedOperationException("Internal error");
}
}
public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
if ((name != null && !name.apply(objectName)) ||
(query != null && !evalQuery(query, null, name)))
return Collections.emptySet();
return Collections.singleton(objectName);
}
public boolean isRegistered(ObjectName name) {
return objectName.equals(name);
}
public Integer getMBeanCount() {
return 1;
}
public Object getAttribute(ObjectName name, String attribute)
throws MBeanException, AttributeNotFoundException,
InstanceNotFoundException, ReflectionException {
return mbean(name).getAttribute(attribute);
}
public AttributeList getAttributes(ObjectName name, String[] attributes)
throws InstanceNotFoundException, ReflectionException {
return mbean(name).getAttributes(attributes);
}
public String getDefaultDomain() {
return objectName.getDomain();
}
public String[] getDomains() {
return new String[] {objectName.getDomain()};
}
public MBeanInfo getMBeanInfo(ObjectName name)
throws InstanceNotFoundException, ReflectionException {
return mbean(name).getMBeanInfo();
}
public boolean isInstanceOf(ObjectName name, String className)
throws InstanceNotFoundException {
try {
mbean(name);
ClassLoader loader = notification.getClass().getClassLoader();
Class<?> c = Class.forName(className, false, loader);
return c.isInstance(notification);
} catch (ReflectionException e) {
return false;
} catch (ClassNotFoundException e) {
return false;
}
}
public ClassLoader getClassLoaderFor(ObjectName mbeanName)
throws InstanceNotFoundException {
checkName(mbeanName);
return notification.getClass().getClassLoader();
}
}
}

View File

@ -48,6 +48,7 @@ import java.util.logging.Level;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.Vector;
import javax.management.Attribute; import javax.management.Attribute;
import javax.management.AttributeChangeNotification; import javax.management.AttributeChangeNotification;
import javax.management.AttributeChangeNotificationFilter; import javax.management.AttributeChangeNotificationFilter;
@ -132,8 +133,6 @@ public class RequiredModelMBean
* and operations will be executed */ * and operations will be executed */
private Object managedResource = null; private Object managedResource = null;
private static final String currClass = "RequiredModelMBean";
/* records the registering in MBeanServer */ /* records the registering in MBeanServer */
private boolean registered = false; private boolean registered = false;
private transient MBeanServer server = null; private transient MBeanServer server = null;
@ -2488,10 +2487,13 @@ public class RequiredModelMBean
} }
if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) { if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
Vector<String> enabledAttrs = currFilter.getEnabledAttributes();
String s = (enabledAttrs.size() > 1) ?
"[" + enabledAttrs.firstElement() + ", ...]" :
enabledAttrs.toString();
MODELMBEAN_LOGGER.logp(Level.FINER, MODELMBEAN_LOGGER.logp(Level.FINER,
RequiredModelMBean.class.getName(), mth, RequiredModelMBean.class.getName(), mth,
"Set attribute change filter to " + "Set attribute change filter to " + s);
currFilter.getEnabledAttributes().firstElement());
} }
attributeBroadcaster.addNotificationListener(inlistener,currFilter, attributeBroadcaster.addNotificationListener(inlistener,currFilter,

View File

@ -303,39 +303,78 @@ public class InstrumentationImpl implements Instrumentation {
NoSuchMethodException firstExc = null; NoSuchMethodException firstExc = null;
boolean twoArgAgent = false; boolean twoArgAgent = false;
// The agent class has a premain or agentmain method that has 1 or 2 // The agent class must have a premain or agentmain method that
// arguments. We first check for a signature of (String, Instrumentation), // has 1 or 2 arguments. We check in the following order:
// and if not found we check for (String). If neither is found then we //
// throw the NoSuchMethodException from the first attempt so that the // 1) declared with a signature of (String, Instrumentation)
// exception text indicates the lookup failed for the 2-arg method // 2) declared with a signature of (String)
// (same as JDK5.0). // 3) inherited with a signature of (String, Instrumentation)
// 4) inherited with a signature of (String)
//
// So the declared version of either 1-arg or 2-arg always takes
// primary precedence over an inherited version. After that, the
// 2-arg version takes precedence over the 1-arg version.
//
// If no method is found then we throw the NoSuchMethodException
// from the first attempt so that the exception text indicates
// the lookup failed for the 2-arg method (same as JDK5.0).
try { try {
m = javaAgentClass.getMethod( methodname, m = javaAgentClass.getDeclaredMethod( methodname,
new Class[] { new Class[] {
String.class, String.class,
java.lang.instrument.Instrumentation.class java.lang.instrument.Instrumentation.class
} }
); );
twoArgAgent = true; twoArgAgent = true;
} catch (NoSuchMethodException x) { } catch (NoSuchMethodException x) {
// remember the NoSuchMethodException // remember the NoSuchMethodException
firstExc = x; firstExc = x;
} }
// check for the 1-arg method
if (m == null) { if (m == null) {
// now try the declared 1-arg method
try { try {
m = javaAgentClass.getMethod(methodname, new Class[] { String.class }); m = javaAgentClass.getDeclaredMethod(methodname,
new Class[] { String.class });
} catch (NoSuchMethodException x) { } catch (NoSuchMethodException x) {
// Neither method exists so we throw the first NoSuchMethodException // ignore this exception because we'll try
// as per 5.0 // two arg inheritance next
}
}
if (m == null) {
// now try the inherited 2-arg method
try {
m = javaAgentClass.getMethod( methodname,
new Class[] {
String.class,
java.lang.instrument.Instrumentation.class
}
);
twoArgAgent = true;
} catch (NoSuchMethodException x) {
// ignore this exception because we'll try
// one arg inheritance next
}
}
if (m == null) {
// finally try the inherited 1-arg method
try {
m = javaAgentClass.getMethod(methodname,
new Class[] { String.class });
} catch (NoSuchMethodException x) {
// none of the methods exists so we throw the
// first NoSuchMethodException as per 5.0
throw firstExc; throw firstExc;
} }
} }
// the premain method should not be required to be public, // the premain method should not be required to be public,
// make it accessible so we can call it // make it accessible so we can call it
// Note: The spec says the following:
// The agent class must implement a public static premain method...
setAccessible(m, true); setAccessible(m, true);
// invoke the 1 or 2-arg method // invoke the 1 or 2-arg method

View File

@ -64,7 +64,8 @@ class Flag {
} }
VMOption getVMOption() { VMOption getVMOption() {
return new VMOption(name, value.toString(), writeable, origin); String val = value == null ? "" : value.toString();
return new VMOption(name, val, writeable, origin);
} }
static Flag getFlag(String name) { static Flag getFlag(String name) {

View File

@ -91,9 +91,10 @@ public class NegotiatorImpl extends Negotiator {
GSSManagerImpl manager = new GSSManagerImpl( GSSManagerImpl manager = new GSSManagerImpl(
GSSUtil.CALLER_HTTP_NEGOTIATE); GSSUtil.CALLER_HTTP_NEGOTIATE);
String peerName = "HTTP/" + hostname; String peerName = "HTTP@" + hostname;
GSSName serverName = manager.createName(peerName, null); GSSName serverName = manager.createName(peerName,
GSSName.NT_HOSTBASED_SERVICE);
context = manager.createContext(serverName, context = manager.createContext(serverName,
oid, oid,
null, null,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,10 +22,10 @@
* CA 95054 USA or visit www.sun.com if you need additional information or * CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions. * have any questions.
*/ */
package sun.security.pkcs11; package sun.security.pkcs11;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Arrays;
import java.security.*; import java.security.*;
import java.security.spec.*; import java.security.spec.*;
@ -34,7 +34,6 @@ import javax.crypto.*;
import javax.crypto.spec.*; import javax.crypto.spec.*;
import sun.nio.ch.DirectBuffer; import sun.nio.ch.DirectBuffer;
import sun.security.pkcs11.wrapper.*; import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
@ -43,8 +42,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
* DES, DESede, AES, ARCFOUR, and Blowfish. * DES, DESede, AES, ARCFOUR, and Blowfish.
* *
* This class is designed to support ECB and CBC with NoPadding and * This class is designed to support ECB and CBC with NoPadding and
* PKCS5Padding for both. However, currently only CBC/NoPadding (and * PKCS5Padding for both. It will use its own padding impl if the
* ECB/NoPadding for stream ciphers) is functional. * native mechanism does not support padding.
* *
* Note that PKCS#11 current only supports ECB and CBC. There are no * Note that PKCS#11 current only supports ECB and CBC. There are no
* provisions for other modes such as CFB, OFB, PCBC, or CTR mode. * provisions for other modes such as CFB, OFB, PCBC, or CTR mode.
@ -62,10 +61,59 @@ final class P11Cipher extends CipherSpi {
private final static int MODE_CBC = 4; private final static int MODE_CBC = 4;
// padding constant for NoPadding // padding constant for NoPadding
private final static int PAD_NONE = 5; private final static int PAD_NONE = 5;
// padding constant for PKCS5Padding // padding constant for PKCS5Padding
private final static int PAD_PKCS5 = 6; private final static int PAD_PKCS5 = 6;
private static interface Padding {
// ENC: format the specified buffer with padding bytes and return the
// actual padding length
int setPaddingBytes(byte[] paddingBuffer, int padLen);
// DEC: return the length of trailing padding bytes given the specified
// padded data
int unpad(byte[] paddedData, int len)
throws BadPaddingException;
}
private static class PKCS5Padding implements Padding {
private final int blockSize;
PKCS5Padding(int blockSize)
throws NoSuchPaddingException {
if (blockSize == 0) {
throw new NoSuchPaddingException
("PKCS#5 padding not supported with stream ciphers");
}
this.blockSize = blockSize;
}
public int setPaddingBytes(byte[] paddingBuffer, int padLen) {
Arrays.fill(paddingBuffer, 0, padLen, (byte) (padLen & 0x007f));
return padLen;
}
public int unpad(byte[] paddedData, int len)
throws BadPaddingException {
if (len < 1 || len > paddedData.length) {
throw new BadPaddingException("Invalid pad array length!");
}
byte padValue = paddedData[len - 1];
if (padValue < 1 || padValue > blockSize) {
throw new BadPaddingException("Invalid pad value!");
}
// sanity check padding bytes
int padStartIndex = len - padValue;
for (int i = padStartIndex; i < len; i++) {
if (paddedData[i] != padValue) {
throw new BadPaddingException("Invalid pad bytes!");
}
}
return padValue;
}
}
// token instance // token instance
private final Token token; private final Token token;
@ -99,65 +147,93 @@ final class P11Cipher extends CipherSpi {
// padding type, on of PAD_* above (PAD_NONE for stream ciphers) // padding type, on of PAD_* above (PAD_NONE for stream ciphers)
private int paddingType; private int paddingType;
// when the padding is requested but unsupported by the native mechanism,
// we use the following to do padding and necessary data buffering.
// padding object which generate padding and unpad the decrypted data
private Padding paddingObj;
// buffer for holding back the block which contains padding bytes
private byte[] padBuffer;
private int padBufferLen;
// original IV, if in MODE_CBC // original IV, if in MODE_CBC
private byte[] iv; private byte[] iv;
// total number of bytes processed // number of bytes buffered internally by the native mechanism and padBuffer
private int bytesProcessed; // if we do the padding
private int bytesBuffered;
P11Cipher(Token token, String algorithm, long mechanism) P11Cipher(Token token, String algorithm, long mechanism)
throws PKCS11Exception { throws PKCS11Exception, NoSuchAlgorithmException {
super(); super();
this.token = token; this.token = token;
this.algorithm = algorithm; this.algorithm = algorithm;
this.mechanism = mechanism; this.mechanism = mechanism;
keyAlgorithm = algorithm.split("/")[0];
String algoParts[] = algorithm.split("/");
keyAlgorithm = algoParts[0];
if (keyAlgorithm.equals("AES")) { if (keyAlgorithm.equals("AES")) {
blockSize = 16; blockSize = 16;
blockMode = MODE_CBC; } else if (keyAlgorithm.equals("RC4") ||
// XXX change default to PKCS5Padding keyAlgorithm.equals("ARCFOUR")) {
paddingType = PAD_NONE;
} else if (keyAlgorithm.equals("RC4") || keyAlgorithm.equals("ARCFOUR")) {
blockSize = 0; blockSize = 0;
blockMode = MODE_ECB;
paddingType = PAD_NONE;
} else { // DES, DESede, Blowfish } else { // DES, DESede, Blowfish
blockSize = 8; blockSize = 8;
blockMode = MODE_CBC; }
// XXX change default to PKCS5Padding this.blockMode =
paddingType = PAD_NONE; (algoParts.length > 1 ? parseMode(algoParts[1]) : MODE_ECB);
String defPadding = (blockSize == 0 ? "NoPadding" : "PKCS5Padding");
String paddingStr =
(algoParts.length > 2 ? algoParts[2] : defPadding);
try {
engineSetPadding(paddingStr);
} catch (NoSuchPaddingException nspe) {
// should not happen
throw new ProviderException(nspe);
} }
session = token.getOpSession(); session = token.getOpSession();
} }
protected void engineSetMode(String mode) throws NoSuchAlgorithmException { protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
// Disallow change of mode for now since currently it's explicitly
// defined in transformation strings
throw new NoSuchAlgorithmException("Unsupported mode " + mode);
}
private int parseMode(String mode) throws NoSuchAlgorithmException {
mode = mode.toUpperCase(); mode = mode.toUpperCase();
int result;
if (mode.equals("ECB")) { if (mode.equals("ECB")) {
this.blockMode = MODE_ECB; result = MODE_ECB;
} else if (mode.equals("CBC")) { } else if (mode.equals("CBC")) {
if (blockSize == 0) { if (blockSize == 0) {
throw new NoSuchAlgorithmException throw new NoSuchAlgorithmException
("CBC mode not supported with stream ciphers"); ("CBC mode not supported with stream ciphers");
} }
this.blockMode = MODE_CBC; result = MODE_CBC;
} else { } else {
throw new NoSuchAlgorithmException("Unsupported mode " + mode); throw new NoSuchAlgorithmException("Unsupported mode " + mode);
} }
return result;
} }
// see JCE spec // see JCE spec
protected void engineSetPadding(String padding) protected void engineSetPadding(String padding)
throws NoSuchPaddingException { throws NoSuchPaddingException {
if (padding.equalsIgnoreCase("NoPadding")) { paddingObj = null;
padBuffer = null;
padding = padding.toUpperCase();
if (padding.equals("NOPADDING")) {
paddingType = PAD_NONE; paddingType = PAD_NONE;
} else if (padding.equalsIgnoreCase("PKCS5Padding")) { } else if (padding.equals("PKCS5PADDING")) {
if (blockSize == 0) {
throw new NoSuchPaddingException
("PKCS#5 padding not supported with stream ciphers");
}
paddingType = PAD_PKCS5; paddingType = PAD_PKCS5;
// XXX PKCS#5 not yet implemented if (mechanism != CKM_DES_CBC_PAD && mechanism != CKM_DES3_CBC_PAD &&
throw new NoSuchPaddingException("pkcs5"); mechanism != CKM_AES_CBC_PAD) {
// no native padding support; use our own padding impl
paddingObj = new PKCS5Padding(blockSize);
padBuffer = new byte[blockSize];
}
} else { } else {
throw new NoSuchPaddingException("Unsupported padding " + padding); throw new NoSuchPaddingException("Unsupported padding " + padding);
} }
@ -175,7 +251,7 @@ final class P11Cipher extends CipherSpi {
// see JCE spec // see JCE spec
protected byte[] engineGetIV() { protected byte[] engineGetIV() {
return (iv == null) ? null : (byte[])iv.clone(); return (iv == null) ? null : (byte[]) iv.clone();
} }
// see JCE spec // see JCE spec
@ -185,8 +261,9 @@ final class P11Cipher extends CipherSpi {
} }
IvParameterSpec ivSpec = new IvParameterSpec(iv); IvParameterSpec ivSpec = new IvParameterSpec(iv);
try { try {
AlgorithmParameters params = AlgorithmParameters.getInstance AlgorithmParameters params =
(keyAlgorithm, P11Util.getSunJceProvider()); AlgorithmParameters.getInstance(keyAlgorithm,
P11Util.getSunJceProvider());
params.init(ivSpec); params.init(ivSpec);
return params; return params;
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {
@ -210,38 +287,38 @@ final class P11Cipher extends CipherSpi {
protected void engineInit(int opmode, Key key, protected void engineInit(int opmode, Key key,
AlgorithmParameterSpec params, SecureRandom random) AlgorithmParameterSpec params, SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException { throws InvalidKeyException, InvalidAlgorithmParameterException {
byte[] iv; byte[] ivValue;
if (params != null) { if (params != null) {
if (params instanceof IvParameterSpec == false) { if (params instanceof IvParameterSpec == false) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("Only IvParameterSpec supported"); ("Only IvParameterSpec supported");
} }
IvParameterSpec ivSpec = (IvParameterSpec)params; IvParameterSpec ivSpec = (IvParameterSpec) params;
iv = ivSpec.getIV(); ivValue = ivSpec.getIV();
} else { } else {
iv = null; ivValue = null;
} }
implInit(opmode, key, iv, random); implInit(opmode, key, ivValue, random);
} }
// see JCE spec // see JCE spec
protected void engineInit(int opmode, Key key, AlgorithmParameters params, protected void engineInit(int opmode, Key key, AlgorithmParameters params,
SecureRandom random) SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException { throws InvalidKeyException, InvalidAlgorithmParameterException {
byte[] iv; byte[] ivValue;
if (params != null) { if (params != null) {
try { try {
IvParameterSpec ivSpec = (IvParameterSpec) IvParameterSpec ivSpec = (IvParameterSpec)
params.getParameterSpec(IvParameterSpec.class); params.getParameterSpec(IvParameterSpec.class);
iv = ivSpec.getIV(); ivValue = ivSpec.getIV();
} catch (InvalidParameterSpecException e) { } catch (InvalidParameterSpecException e) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("Could not decode IV", e); ("Could not decode IV", e);
} }
} else { } else {
iv = null; ivValue = null;
} }
implInit(opmode, key, iv, random); implInit(opmode, key, ivValue, random);
} }
// actual init() implementation // actual init() implementation
@ -250,31 +327,31 @@ final class P11Cipher extends CipherSpi {
throws InvalidKeyException, InvalidAlgorithmParameterException { throws InvalidKeyException, InvalidAlgorithmParameterException {
cancelOperation(); cancelOperation();
switch (opmode) { switch (opmode) {
case Cipher.ENCRYPT_MODE: case Cipher.ENCRYPT_MODE:
encrypt = true; encrypt = true;
break; break;
case Cipher.DECRYPT_MODE: case Cipher.DECRYPT_MODE:
encrypt = false; encrypt = false;
break; break;
default: default:
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("Unsupported mode: " + opmode); ("Unsupported mode: " + opmode);
} }
if (blockMode == MODE_ECB) { // ECB or stream cipher if (blockMode == MODE_ECB) { // ECB or stream cipher
if (iv != null) { if (iv != null) {
if (blockSize == 0) { if (blockSize == 0) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("IV not used with stream ciphers"); ("IV not used with stream ciphers");
} else { } else {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("IV not used in ECB mode"); ("IV not used in ECB mode");
} }
} }
} else { // MODE_CBC } else { // MODE_CBC
if (iv == null) { if (iv == null) {
if (encrypt == false) { if (encrypt == false) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("IV must be specified for decryption in CBC mode"); ("IV must be specified for decryption in CBC mode");
} }
// generate random IV // generate random IV
if (random == null) { if (random == null) {
@ -285,7 +362,7 @@ final class P11Cipher extends CipherSpi {
} else { } else {
if (iv.length != blockSize) { if (iv.length != blockSize) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("IV length must match block size"); ("IV length must match block size");
} }
} }
} }
@ -331,63 +408,43 @@ final class P11Cipher extends CipherSpi {
session = token.getOpSession(); session = token.getOpSession();
} }
if (encrypt) { if (encrypt) {
token.p11.C_EncryptInit token.p11.C_EncryptInit(session.id(),
(session.id(), new CK_MECHANISM(mechanism, iv), p11Key.keyID); new CK_MECHANISM(mechanism, iv), p11Key.keyID);
} else { } else {
token.p11.C_DecryptInit token.p11.C_DecryptInit(session.id(),
(session.id(), new CK_MECHANISM(mechanism, iv), p11Key.keyID); new CK_MECHANISM(mechanism, iv), p11Key.keyID);
} }
bytesProcessed = 0; bytesBuffered = 0;
padBufferLen = 0;
initialized = true; initialized = true;
} }
// XXX the calculations below assume the PKCS#11 implementation is smart.
// conceivably, not all implementations are and we may need to estimate
// more conservatively
private int bytesBuffered(int totalLen) {
if (paddingType == PAD_NONE) {
// with NoPadding, buffer only the current unfinished block
return totalLen & (blockSize - 1);
} else { // PKCS5
// with PKCS5Padding in decrypt mode, the buffer must never
// be empty. Buffer a full block instead of nothing.
int buffered = totalLen & (blockSize - 1);
if ((buffered == 0) && (encrypt == false)) {
buffered = blockSize;
}
return buffered;
}
}
// if update(inLen) is called, how big does the output buffer have to be? // if update(inLen) is called, how big does the output buffer have to be?
private int updateLength(int inLen) { private int updateLength(int inLen) {
if (inLen <= 0) { if (inLen <= 0) {
return 0; return 0;
} }
if (blockSize == 0) {
return inLen; int result = inLen + bytesBuffered;
} else { if (blockSize != 0) {
// bytes that need to be buffered now // minus the number of bytes in the last incomplete block.
int buffered = bytesBuffered(bytesProcessed); result -= (result & (blockSize - 1));
// bytes that need to be buffered after this update
int newBuffered = bytesBuffered(bytesProcessed + inLen);
return inLen + buffered - newBuffered;
} }
return result;
} }
// if doFinal(inLen) is called, how big does the output buffer have to be? // if doFinal(inLen) is called, how big does the output buffer have to be?
private int doFinalLength(int inLen) { private int doFinalLength(int inLen) {
if (paddingType == PAD_NONE) {
return updateLength(inLen);
}
if (inLen < 0) { if (inLen < 0) {
return 0; return 0;
} }
int buffered = bytesBuffered(bytesProcessed);
int newProcessed = bytesProcessed + inLen; int result = inLen + bytesBuffered;
int paddedProcessed = (newProcessed + blockSize) & ~(blockSize - 1); if (blockSize != 0 && encrypt && paddingType != PAD_NONE) {
return paddedProcessed - bytesProcessed + buffered; // add the number of bytes to make the last block complete.
result += (blockSize - (result & (blockSize - 1)));
}
return result;
} }
// see JCE spec // see JCE spec
@ -397,6 +454,7 @@ final class P11Cipher extends CipherSpi {
int n = engineUpdate(in, inOfs, inLen, out, 0); int n = engineUpdate(in, inOfs, inLen, out, 0);
return P11Util.convert(out, 0, n); return P11Util.convert(out, 0, n);
} catch (ShortBufferException e) { } catch (ShortBufferException e) {
// convert since the output length is calculated by updateLength()
throw new ProviderException(e); throw new ProviderException(e);
} }
} }
@ -409,6 +467,7 @@ final class P11Cipher extends CipherSpi {
} }
// see JCE spec // see JCE spec
@Override
protected int engineUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer) protected int engineUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer)
throws ShortBufferException { throws ShortBufferException {
return implUpdate(inBuffer, outBuffer); return implUpdate(inBuffer, outBuffer);
@ -422,14 +481,15 @@ final class P11Cipher extends CipherSpi {
int n = engineDoFinal(in, inOfs, inLen, out, 0); int n = engineDoFinal(in, inOfs, inLen, out, 0);
return P11Util.convert(out, 0, n); return P11Util.convert(out, 0, n);
} catch (ShortBufferException e) { } catch (ShortBufferException e) {
// convert since the output length is calculated by doFinalLength()
throw new ProviderException(e); throw new ProviderException(e);
} }
} }
// see JCE spec // see JCE spec
protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out, protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out,
int outOfs) throws ShortBufferException, IllegalBlockSizeException { int outOfs) throws ShortBufferException, IllegalBlockSizeException,
// BadPaddingException { BadPaddingException {
int n = 0; int n = 0;
if ((inLen != 0) && (in != null)) { if ((inLen != 0) && (in != null)) {
n = engineUpdate(in, inOfs, inLen, out, outOfs); n = engineUpdate(in, inOfs, inLen, out, outOfs);
@ -440,8 +500,10 @@ final class P11Cipher extends CipherSpi {
} }
// see JCE spec // see JCE spec
@Override
protected int engineDoFinal(ByteBuffer inBuffer, ByteBuffer outBuffer) protected int engineDoFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { throws ShortBufferException, IllegalBlockSizeException,
BadPaddingException {
int n = engineUpdate(inBuffer, outBuffer); int n = engineUpdate(inBuffer, outBuffer);
n += implDoFinal(outBuffer); n += implDoFinal(outBuffer);
return n; return n;
@ -454,18 +516,55 @@ final class P11Cipher extends CipherSpi {
} }
try { try {
ensureInitialized(); ensureInitialized();
int k; int k = 0;
if (encrypt) { if (encrypt) {
k = token.p11.C_EncryptUpdate k = token.p11.C_EncryptUpdate(session.id(), 0, in, inOfs, inLen,
(session.id(), 0, in, inOfs, inLen, 0, out, outOfs, outLen); 0, out, outOfs, outLen);
} else { } else {
k = token.p11.C_DecryptUpdate int newPadBufferLen = 0;
(session.id(), 0, in, inOfs, inLen, 0, out, outOfs, outLen); if (paddingObj != null) {
if (padBufferLen != 0) {
// NSS throws up when called with data not in multiple
// of blocks. Try to work around this by holding the
// extra data in padBuffer.
if (padBufferLen != padBuffer.length) {
int bufCapacity = padBuffer.length - padBufferLen;
if (inLen > bufCapacity) {
bufferInputBytes(in, inOfs, bufCapacity);
inOfs += bufCapacity;
inLen -= bufCapacity;
} else {
bufferInputBytes(in, inOfs, inLen);
return 0;
}
}
k = token.p11.C_DecryptUpdate(session.id(),
0, padBuffer, 0, padBufferLen,
0, out, outOfs, outLen);
padBufferLen = 0;
}
newPadBufferLen = inLen & (blockSize - 1);
if (newPadBufferLen == 0) {
newPadBufferLen = padBuffer.length;
}
inLen -= newPadBufferLen;
}
if (inLen > 0) {
k += token.p11.C_DecryptUpdate(session.id(), 0, in, inOfs,
inLen, 0, out, (outOfs + k), (outLen - k));
}
// update 'padBuffer' if using our own padding impl.
if (paddingObj != null) {
bufferInputBytes(in, inOfs + inLen, newPadBufferLen);
}
} }
bytesProcessed += inLen; bytesBuffered += (inLen - k);
return k; return k;
} catch (PKCS11Exception e) { } catch (PKCS11Exception e) {
// XXX throw correct exception if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
throw (ShortBufferException)
(new ShortBufferException().initCause(e));
}
throw new ProviderException("update() failed", e); throw new ProviderException("update() failed", e);
} }
} }
@ -481,101 +580,167 @@ final class P11Cipher extends CipherSpi {
if (outLen < updateLength(inLen)) { if (outLen < updateLength(inLen)) {
throw new ShortBufferException(); throw new ShortBufferException();
} }
boolean inPosChanged = false; int origPos = inBuffer.position();
try { try {
ensureInitialized(); ensureInitialized();
long inAddr = 0; long inAddr = 0;
int inOfs = inBuffer.position(); int inOfs = 0;
byte[] inArray = null; byte[] inArray = null;
if (inBuffer instanceof DirectBuffer) { if (inBuffer instanceof DirectBuffer) {
inAddr = ((DirectBuffer)inBuffer).address(); inAddr = ((DirectBuffer) inBuffer).address();
} else { inOfs = origPos;
if (inBuffer.hasArray()) { } else if (inBuffer.hasArray()) {
inArray = inBuffer.array(); inArray = inBuffer.array();
inOfs += inBuffer.arrayOffset(); inOfs = (origPos + inBuffer.arrayOffset());
} else {
inArray = new byte[inLen];
inBuffer.get(inArray);
inOfs = 0;
inPosChanged = true;
}
} }
long outAddr = 0; long outAddr = 0;
int outOfs = outBuffer.position(); int outOfs = 0;
byte[] outArray = null; byte[] outArray = null;
if (outBuffer instanceof DirectBuffer) { if (outBuffer instanceof DirectBuffer) {
outAddr = ((DirectBuffer)outBuffer).address(); outAddr = ((DirectBuffer) outBuffer).address();
outOfs = outBuffer.position();
} else { } else {
if (outBuffer.hasArray()) { if (outBuffer.hasArray()) {
outArray = outBuffer.array(); outArray = outBuffer.array();
outOfs += outBuffer.arrayOffset(); outOfs = (outBuffer.position() + outBuffer.arrayOffset());
} else { } else {
outArray = new byte[outLen]; outArray = new byte[outLen];
outOfs = 0;
} }
} }
int k; int k = 0;
if (encrypt) { if (encrypt) {
k = token.p11.C_EncryptUpdate if (inAddr == 0 && inArray == null) {
(session.id(), inAddr, inArray, inOfs, inLen, inArray = new byte[inLen];
outAddr, outArray, outOfs, outLen); inBuffer.get(inArray);
} else {
inBuffer.position(origPos + inLen);
}
k = token.p11.C_EncryptUpdate(session.id(),
inAddr, inArray, inOfs, inLen,
outAddr, outArray, outOfs, outLen);
} else { } else {
k = token.p11.C_DecryptUpdate int newPadBufferLen = 0;
(session.id(), inAddr, inArray, inOfs, inLen, if (paddingObj != null) {
outAddr, outArray, outOfs, outLen); if (padBufferLen != 0) {
} // NSS throws up when called with data not in multiple
bytesProcessed += inLen; // of blocks. Try to work around this by holding the
if (!inPosChanged) { // extra data in padBuffer.
inBuffer.position(inBuffer.position() + inLen); if (padBufferLen != padBuffer.length) {
int bufCapacity = padBuffer.length - padBufferLen;
if (inLen > bufCapacity) {
bufferInputBytes(inBuffer, bufCapacity);
inOfs += bufCapacity;
inLen -= bufCapacity;
} else {
bufferInputBytes(inBuffer, inLen);
return 0;
}
}
k = token.p11.C_DecryptUpdate(session.id(), 0,
padBuffer, 0, padBufferLen, outAddr, outArray,
outOfs, outLen);
padBufferLen = 0;
}
newPadBufferLen = inLen & (blockSize - 1);
if (newPadBufferLen == 0) {
newPadBufferLen = padBuffer.length;
}
inLen -= newPadBufferLen;
}
if (inLen > 0) {
if (inAddr == 0 && inArray == null) {
inArray = new byte[inLen];
inBuffer.get(inArray);
} else {
inBuffer.position(inBuffer.position() + inLen);
}
k += token.p11.C_DecryptUpdate(session.id(), inAddr,
inArray, inOfs, inLen, outAddr, outArray,
(outOfs + k), (outLen - k));
}
// update 'padBuffer' if using our own padding impl.
if (paddingObj != null && newPadBufferLen != 0) {
bufferInputBytes(inBuffer, newPadBufferLen);
}
} }
bytesBuffered += (inLen - k);
if (!(outBuffer instanceof DirectBuffer) && if (!(outBuffer instanceof DirectBuffer) &&
!outBuffer.hasArray()) { !outBuffer.hasArray()) {
outBuffer.put(outArray, outOfs, k); outBuffer.put(outArray, outOfs, k);
} else { } else {
outBuffer.position(outBuffer.position() + k); outBuffer.position(outBuffer.position() + k);
} }
return k; return k;
} catch (PKCS11Exception e) { } catch (PKCS11Exception e) {
// Un-read the bytes back to input buffer // Reset input buffer to its original position for
if (inPosChanged) { inBuffer.position(origPos);
inBuffer.position(inBuffer.position() - inLen); if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
throw (ShortBufferException)
(new ShortBufferException().initCause(e));
} }
// XXX throw correct exception
throw new ProviderException("update() failed", e); throw new ProviderException("update() failed", e);
} }
} }
private int implDoFinal(byte[] out, int outOfs, int outLen) private int implDoFinal(byte[] out, int outOfs, int outLen)
throws ShortBufferException, IllegalBlockSizeException { throws ShortBufferException, IllegalBlockSizeException,
if (outLen < doFinalLength(0)) { BadPaddingException {
int requiredOutLen = doFinalLength(0);
if (outLen < requiredOutLen) {
throw new ShortBufferException(); throw new ShortBufferException();
} }
try { try {
ensureInitialized(); ensureInitialized();
int k = 0;
if (encrypt) { if (encrypt) {
return token.p11.C_EncryptFinal if (paddingObj != null) {
(session.id(), 0, out, outOfs, outLen); int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
requiredOutLen - bytesBuffered);
k = token.p11.C_EncryptUpdate(session.id(),
0, padBuffer, 0, actualPadLen,
0, out, outOfs, outLen);
}
k += token.p11.C_EncryptFinal(session.id(),
0, out, (outOfs + k), (outLen - k));
} else { } else {
return token.p11.C_DecryptFinal if (paddingObj != null) {
(session.id(), 0, out, outOfs, outLen); if (padBufferLen != 0) {
k = token.p11.C_DecryptUpdate(session.id(), 0,
padBuffer, 0, padBufferLen, 0, padBuffer, 0,
padBuffer.length);
}
k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k,
padBuffer.length - k);
int actualPadLen = paddingObj.unpad(padBuffer, k);
k -= actualPadLen;
System.arraycopy(padBuffer, 0, out, outOfs, k);
} else {
k = token.p11.C_DecryptFinal(session.id(), 0, out, outOfs,
outLen);
}
} }
return k;
} catch (PKCS11Exception e) { } catch (PKCS11Exception e) {
handleException(e); handleException(e);
throw new ProviderException("doFinal() failed", e); throw new ProviderException("doFinal() failed", e);
} finally { } finally {
initialized = false; initialized = false;
bytesProcessed = 0; bytesBuffered = 0;
padBufferLen = 0;
session = token.releaseSession(session); session = token.releaseSession(session);
} }
} }
private int implDoFinal(ByteBuffer outBuffer) private int implDoFinal(ByteBuffer outBuffer)
throws ShortBufferException, IllegalBlockSizeException { throws ShortBufferException, IllegalBlockSizeException,
BadPaddingException {
int outLen = outBuffer.remaining(); int outLen = outBuffer.remaining();
if (outLen < doFinalLength(0)) { int requiredOutLen = doFinalLength(0);
if (outLen < requiredOutLen) {
throw new ShortBufferException(); throw new ShortBufferException();
} }
@ -583,30 +748,54 @@ final class P11Cipher extends CipherSpi {
ensureInitialized(); ensureInitialized();
long outAddr = 0; long outAddr = 0;
int outOfs = outBuffer.position();
byte[] outArray = null; byte[] outArray = null;
int outOfs = 0;
if (outBuffer instanceof DirectBuffer) { if (outBuffer instanceof DirectBuffer) {
outAddr = ((DirectBuffer)outBuffer).address(); outAddr = ((DirectBuffer) outBuffer).address();
outOfs = outBuffer.position();
} else { } else {
if (outBuffer.hasArray()) { if (outBuffer.hasArray()) {
outArray = outBuffer.array(); outArray = outBuffer.array();
outOfs += outBuffer.arrayOffset(); outOfs = outBuffer.position() + outBuffer.arrayOffset();
} else { } else {
outArray = new byte[outLen]; outArray = new byte[outLen];
outOfs = 0;
} }
} }
int k; int k = 0;
if (encrypt) { if (encrypt) {
k = token.p11.C_EncryptFinal if (paddingObj != null) {
(session.id(), outAddr, outArray, outOfs, outLen); int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
requiredOutLen - bytesBuffered);
k = token.p11.C_EncryptUpdate(session.id(),
0, padBuffer, 0, actualPadLen,
outAddr, outArray, outOfs, outLen);
}
k += token.p11.C_EncryptFinal(session.id(),
outAddr, outArray, (outOfs + k), (outLen - k));
} else { } else {
k = token.p11.C_DecryptFinal if (paddingObj != null) {
(session.id(), outAddr, outArray, outOfs, outLen); if (padBufferLen != 0) {
k = token.p11.C_DecryptUpdate(session.id(),
0, padBuffer, 0, padBufferLen,
0, padBuffer, 0, padBuffer.length);
padBufferLen = 0;
}
k += token.p11.C_DecryptFinal(session.id(),
0, padBuffer, k, padBuffer.length - k);
int actualPadLen = paddingObj.unpad(padBuffer, k);
k -= actualPadLen;
outArray = padBuffer;
outOfs = 0;
} else {
k = token.p11.C_DecryptFinal(session.id(),
outAddr, outArray, outOfs, outLen);
}
} }
if (!(outBuffer instanceof DirectBuffer) && if ((!encrypt && paddingObj != null) ||
!outBuffer.hasArray()) { (!(outBuffer instanceof DirectBuffer) &&
!outBuffer.hasArray())) {
outBuffer.put(outArray, outOfs, k); outBuffer.put(outArray, outOfs, k);
} else { } else {
outBuffer.position(outBuffer.position() + k); outBuffer.position(outBuffer.position() + k);
@ -617,20 +806,22 @@ final class P11Cipher extends CipherSpi {
throw new ProviderException("doFinal() failed", e); throw new ProviderException("doFinal() failed", e);
} finally { } finally {
initialized = false; initialized = false;
bytesProcessed = 0; bytesBuffered = 0;
session = token.releaseSession(session); session = token.releaseSession(session);
} }
} }
private void handleException(PKCS11Exception e) private void handleException(PKCS11Exception e)
throws IllegalBlockSizeException { throws ShortBufferException, IllegalBlockSizeException {
long errorCode = e.getErrorCode(); long errorCode = e.getErrorCode();
// XXX better check if (errorCode == CKR_BUFFER_TOO_SMALL) {
if (errorCode == CKR_DATA_LEN_RANGE) { throw (ShortBufferException)
throw (IllegalBlockSizeException)new (new ShortBufferException().initCause(e));
IllegalBlockSizeException(e.toString()).initCause(e); } else if (errorCode == CKR_DATA_LEN_RANGE ||
errorCode == CKR_ENCRYPTED_DATA_LEN_RANGE) {
throw (IllegalBlockSizeException)
(new IllegalBlockSizeException(e.toString()).initCause(e));
} }
} }
// see JCE spec // see JCE spec
@ -649,12 +840,14 @@ final class P11Cipher extends CipherSpi {
} }
// see JCE spec // see JCE spec
@Override
protected int engineGetKeySize(Key key) throws InvalidKeyException { protected int engineGetKeySize(Key key) throws InvalidKeyException {
int n = P11SecretKeyFactory.convertKey int n = P11SecretKeyFactory.convertKey
(token, key, keyAlgorithm).keyLength(); (token, key, keyAlgorithm).keyLength();
return n; return n;
} }
@Override
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
try { try {
if ((session != null) && token.isValid()) { if ((session != null) && token.isValid()) {
@ -666,4 +859,15 @@ final class P11Cipher extends CipherSpi {
} }
} }
private final void bufferInputBytes(byte[] in, int inOfs, int len) {
System.arraycopy(in, inOfs, padBuffer, padBufferLen, len);
padBufferLen += len;
bytesBuffered += len;
}
private final void bufferInputBytes(ByteBuffer inBuffer, int len) {
inBuffer.get(padBuffer, padBufferLen, len);
padBufferLen += len;
bytesBuffered += len;
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -65,10 +65,86 @@ final class P11KeyGenerator extends KeyGeneratorSpi {
// are supported. // are supported.
private boolean supportBothKeySizes; private boolean supportBothKeySizes;
// min and max key sizes (in bits) for variable-key-length /**
// algorithms, e.g. RC4 and Blowfish * Utility method for checking if the specified key size is valid
private int minKeySize; * and within the supported range. Return the significant key size
private int maxKeySize; * upon successful validation.
* @param keyGenMech the PKCS#11 key generation mechanism.
* @param keySize the to-be-checked key size for this mechanism.
* @param token token which provides this mechanism.
* @return the significant key size (in bits) corresponding to the
* specified key size.
* @throws InvalidParameterException if the specified key size is invalid.
* @throws ProviderException if this mechanism isn't supported by SunPKCS11
* or underlying native impl.
*/
static int checkKeySize(long keyGenMech, int keySize, Token token)
throws InvalidAlgorithmParameterException, ProviderException {
int sigKeySize;
switch ((int)keyGenMech) {
case (int)CKM_DES_KEY_GEN:
if ((keySize != 64) && (keySize != 56)) {
throw new InvalidAlgorithmParameterException
("DES key length must be 56 bits");
}
sigKeySize = 56;
break;
case (int)CKM_DES2_KEY_GEN:
case (int)CKM_DES3_KEY_GEN:
if ((keySize == 112) || (keySize == 128)) {
sigKeySize = 112;
} else if ((keySize == 168) || (keySize == 192)) {
sigKeySize = 168;
} else {
throw new InvalidAlgorithmParameterException
("DESede key length must be 112, or 168 bits");
}
break;
default:
// Handle all variable-key-length algorithms here
CK_MECHANISM_INFO info = null;
try {
info = token.getMechanismInfo(keyGenMech);
} catch (PKCS11Exception p11e) {
// Should never happen
throw new ProviderException
("Cannot retrieve mechanism info", p11e);
}
if (info == null) {
// XXX Unable to retrieve the supported key length from
// the underlying native impl. Skip the checking for now.
return keySize;
}
// PKCS#11 defines these to be in number of bytes except for
// RC4 which is in bits. However, some PKCS#11 impls still use
// bytes for all mechs, e.g. NSS. We try to detect this
// inconsistency if the minKeySize seems unreasonably small.
int minKeySize = (int)info.ulMinKeySize;
int maxKeySize = (int)info.ulMaxKeySize;
if (keyGenMech != CKM_RC4_KEY_GEN || minKeySize < 8) {
minKeySize = (int)info.ulMinKeySize << 3;
maxKeySize = (int)info.ulMaxKeySize << 3;
}
// Explicitly disallow keys shorter than 40-bits for security
if (minKeySize < 40) minKeySize = 40;
if (keySize < minKeySize || keySize > maxKeySize) {
throw new InvalidAlgorithmParameterException
("Key length must be between " + minKeySize +
" and " + maxKeySize + " bits");
}
if (keyGenMech == CKM_AES_KEY_GEN) {
if ((keySize != 128) && (keySize != 192) &&
(keySize != 256)) {
throw new InvalidAlgorithmParameterException
("AES key length must be " + minKeySize +
(maxKeySize >= 192? ", 192":"") +
(maxKeySize >= 256? ", or 256":"") + " bits");
}
}
sigKeySize = keySize;
}
return sigKeySize;
}
P11KeyGenerator(Token token, String algorithm, long mechanism) P11KeyGenerator(Token token, String algorithm, long mechanism)
throws PKCS11Exception { throws PKCS11Exception {
@ -85,72 +161,44 @@ final class P11KeyGenerator extends KeyGeneratorSpi {
supportBothKeySizes = supportBothKeySizes =
(token.provider.config.isEnabled(CKM_DES2_KEY_GEN) && (token.provider.config.isEnabled(CKM_DES2_KEY_GEN) &&
(token.getMechanismInfo(CKM_DES2_KEY_GEN) != null)); (token.getMechanismInfo(CKM_DES2_KEY_GEN) != null));
} else if (this.mechanism == CKM_RC4_KEY_GEN) {
CK_MECHANISM_INFO info = token.getMechanismInfo(mechanism);
// Although PKCS#11 spec documented that these are in bits,
// NSS, for one, uses bytes. Multiple by 8 if the number seems
// unreasonably small.
if (info.ulMinKeySize < 8) {
minKeySize = (int)info.ulMinKeySize << 3;
maxKeySize = (int)info.ulMaxKeySize << 3;
} else {
minKeySize = (int)info.ulMinKeySize;
maxKeySize = (int)info.ulMaxKeySize;
}
// Explicitly disallow keys shorter than 40-bits for security
if (minKeySize < 40) minKeySize = 40;
} else if (this.mechanism == CKM_BLOWFISH_KEY_GEN) {
CK_MECHANISM_INFO info = token.getMechanismInfo(mechanism);
maxKeySize = (int)info.ulMaxKeySize << 3;
minKeySize = (int)info.ulMinKeySize << 3;
// Explicitly disallow keys shorter than 40-bits for security
if (minKeySize < 40) minKeySize = 40;
} }
setDefaultKeySize(); setDefaultKeySize();
} }
// set default keysize and also initialize keyType // set default keysize and also initialize keyType
private void setDefaultKeySize() { private void setDefaultKeySize() {
// whether to check default key size against the min and max value
boolean validateKeySize = false;
switch ((int)mechanism) { switch ((int)mechanism) {
case (int)CKM_DES_KEY_GEN: case (int)CKM_DES_KEY_GEN:
keySize = 64; keySize = 64;
significantKeySize = 56;
keyType = CKK_DES; keyType = CKK_DES;
break; break;
case (int)CKM_DES2_KEY_GEN: case (int)CKM_DES2_KEY_GEN:
keySize = 128; keySize = 128;
significantKeySize = 112;
keyType = CKK_DES2; keyType = CKK_DES2;
break; break;
case (int)CKM_DES3_KEY_GEN: case (int)CKM_DES3_KEY_GEN:
keySize = 192; keySize = 192;
significantKeySize = 168;
keyType = CKK_DES3; keyType = CKK_DES3;
break; break;
case (int)CKM_AES_KEY_GEN: case (int)CKM_AES_KEY_GEN:
keyType = CKK_AES;
keySize = 128; keySize = 128;
significantKeySize = 128; keyType = CKK_AES;
break; break;
case (int)CKM_RC4_KEY_GEN: case (int)CKM_RC4_KEY_GEN:
keyType = CKK_RC4;
keySize = 128; keySize = 128;
validateKeySize = true; keyType = CKK_RC4;
break; break;
case (int)CKM_BLOWFISH_KEY_GEN: case (int)CKM_BLOWFISH_KEY_GEN:
keyType = CKK_BLOWFISH;
keySize = 128; keySize = 128;
validateKeySize = true; keyType = CKK_BLOWFISH;
break; break;
default: default:
throw new ProviderException("Unknown mechanism " + mechanism); throw new ProviderException("Unknown mechanism " + mechanism);
} }
if (validateKeySize && try {
((keySize > maxKeySize) || (keySize < minKeySize))) { significantKeySize = checkKeySize(mechanism, keySize, token);
throw new ProviderException("Unsupported key size"); } catch (InvalidAlgorithmParameterException iape) {
throw new ProviderException("Unsupported default key size", iape);
} }
} }
@ -170,57 +218,32 @@ final class P11KeyGenerator extends KeyGeneratorSpi {
// see JCE spec // see JCE spec
protected void engineInit(int keySize, SecureRandom random) { protected void engineInit(int keySize, SecureRandom random) {
token.ensureValid(); token.ensureValid();
switch ((int)mechanism) { int newSignificantKeySize;
case (int)CKM_DES_KEY_GEN: try {
if ((keySize != this.keySize) && newSignificantKeySize = checkKeySize(mechanism, keySize, token);
(keySize != this.significantKeySize)) { } catch (InvalidAlgorithmParameterException iape) {
throw new InvalidParameterException throw (InvalidParameterException)
("DES key length must be 56 bits"); (new InvalidParameterException().initCause(iape));
} }
break; if ((mechanism == CKM_DES2_KEY_GEN) ||
case (int)CKM_DES2_KEY_GEN: (mechanism == CKM_DES3_KEY_GEN)) {
case (int)CKM_DES3_KEY_GEN: long newMechanism = (newSignificantKeySize == 112 ?
long newMechanism; CKM_DES2_KEY_GEN : CKM_DES3_KEY_GEN);
if ((keySize == 112) || (keySize == 128)) {
newMechanism = CKM_DES2_KEY_GEN;
} else if ((keySize == 168) || (keySize == 192)) {
newMechanism = CKM_DES3_KEY_GEN;
} else {
throw new InvalidParameterException
("DESede key length must be 112, or 168 bits");
}
if (mechanism != newMechanism) { if (mechanism != newMechanism) {
if (supportBothKeySizes) { if (supportBothKeySizes) {
mechanism = newMechanism; mechanism = newMechanism;
setDefaultKeySize(); // Adjust keyType to reflect the mechanism change
keyType = (mechanism == CKM_DES2_KEY_GEN ?
CKK_DES2 : CKK_DES3);
} else { } else {
throw new InvalidParameterException throw new InvalidParameterException
("Only " + significantKeySize + ("Only " + significantKeySize +
"-bit DESede key length is supported"); "-bit DESede is supported");
} }
} }
break;
case (int)CKM_AES_KEY_GEN:
if ((keySize != 128) && (keySize != 192) && (keySize != 256)) {
throw new InvalidParameterException
("AES key length must be 128, 192, or 256 bits");
}
this.keySize = keySize;
significantKeySize = keySize;
break;
case (int)CKM_RC4_KEY_GEN:
case (int)CKM_BLOWFISH_KEY_GEN:
if ((keySize < minKeySize) || (keySize > maxKeySize)) {
throw new InvalidParameterException
(algorithm + " key length must be between " +
minKeySize + " and " + maxKeySize + " bits");
}
this.keySize = keySize;
this.significantKeySize = keySize;
break;
default:
throw new ProviderException("Unknown mechanism " + mechanism);
} }
this.keySize = keySize;
this.significantKeySize = newSignificantKeySize;
} }
// see JCE spec // see JCE spec

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -156,10 +156,10 @@ final class P11KeyStore extends KeyStoreSpi {
// CKA_CLASS - entry type // CKA_CLASS - entry type
private CK_ATTRIBUTE type = null; private CK_ATTRIBUTE type = null;
// CKA_LABEL of cert // CKA_LABEL of cert and secret key
private String label = null; private String label = null;
// CKA_ID - of private key/cert // CKA_ID of the private key/cert pair
private byte[] id = null; private byte[] id = null;
// CKA_TRUSTED - true if cert is trusted // CKA_TRUSTED - true if cert is trusted
@ -871,10 +871,8 @@ final class P11KeyStore extends KeyStoreSpi {
if ((token.tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) == 0) { if ((token.tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) == 0) {
token.provider.login(null, handler); token.provider.login(null, handler);
} else { } else {
// token supports protected authentication path // token supports protected authentication path
// (external pin-pad, for example) // (external pin-pad, for example)
if (handler != null && if (handler != null &&
!token.config.getKeyStoreCompatibilityMode()) { !token.config.getKeyStoreCompatibilityMode()) {
throw new LoginException("can not specify password if token " + throw new LoginException("can not specify password if token " +
@ -1130,19 +1128,14 @@ final class P11KeyStore extends KeyStoreSpi {
SecretKey skey = ske.getSecretKey(); SecretKey skey = ske.getSecretKey();
try { try {
// first see if the key already exists. // first check if the key already exists
// if so, update the CKA_LABEL AliasInfo aliasInfo = aliasMap.get(alias);
if (!updateSkey(alias)) {
// key entry does not exist.
// delete existing entry for alias and
// create new secret key entry
// (new entry might be a secret key
// session object converted into a token object)
if (aliasInfo != null) {
engineDeleteEntry(alias); engineDeleteEntry(alias);
storeSkey(alias, ske);
} }
storeSkey(alias, ske);
} catch (PKCS11Exception pe) { } catch (PKCS11Exception pe) {
throw new KeyStoreException(pe); throw new KeyStoreException(pe);
} }
@ -1396,41 +1389,6 @@ final class P11KeyStore extends KeyStoreSpi {
} }
} }
/**
* return true if update occurred
*/
private boolean updateSkey(String alias)
throws KeyStoreException, PKCS11Exception {
Session session = null;
try {
session = token.getOpSession();
// first update existing secret key CKA_LABEL
THandle h = getTokenObject(session, ATTR_CLASS_SKEY, null, alias);
if (h.type != ATTR_CLASS_SKEY) {
if (debug != null) {
debug.println("did not find secret key " +
"with CKA_LABEL [" + alias + "]");
}
return false;
}
CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_LABEL, alias) };
token.p11.C_SetAttributeValue(session.id(), h.handle, attrs);
if (debug != null) {
debug.println("updateSkey set new alias [" +
alias +
"] for secret key entry");
}
return true;
} finally {
token.releaseSession(session);
}
}
/** /**
* XXX On ibutton, when you C_SetAttribute(CKA_ID) for a private key * XXX On ibutton, when you C_SetAttribute(CKA_ID) for a private key
@ -1532,30 +1490,6 @@ final class P11KeyStore extends KeyStoreSpi {
} }
} }
private void updateP11Skey(String alias, P11Key key)
throws PKCS11Exception {
Session session = null;
try {
session = token.getOpSession();
// session key - convert to token key and set CKA_LABEL
CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
ATTR_TOKEN_TRUE,
new CK_ATTRIBUTE(CKA_LABEL, alias) };
token.p11.C_CopyObject(session.id(), key.keyID, attrs);
if (debug != null) {
debug.println("updateP11Skey copied secret session key " +
"for [" +
alias +
"] to token entry");
}
} finally {
token.releaseSession(session);
}
}
private void updateP11Pkey(String alias, CK_ATTRIBUTE attribute, P11Key key) private void updateP11Pkey(String alias, CK_ATTRIBUTE attribute, P11Key key)
throws PKCS11Exception { throws PKCS11Exception {
@ -1689,48 +1623,26 @@ final class P11KeyStore extends KeyStoreSpi {
throws PKCS11Exception, KeyStoreException { throws PKCS11Exception, KeyStoreException {
SecretKey skey = ske.getSecretKey(); SecretKey skey = ske.getSecretKey();
long keyType = CKK_GENERIC_SECRET; // No need to specify CKA_CLASS, CKA_KEY_TYPE, CKA_VALUE since
// they are handled in P11SecretKeyFactory.createKey() method.
if (skey instanceof P11Key && this.token == ((P11Key)skey).token) {
updateP11Skey(alias, (P11Key)skey);
return;
}
if ("AES".equalsIgnoreCase(skey.getAlgorithm())) {
keyType = CKK_AES;
} else if ("Blowfish".equalsIgnoreCase(skey.getAlgorithm())) {
keyType = CKK_BLOWFISH;
} else if ("DES".equalsIgnoreCase(skey.getAlgorithm())) {
keyType = CKK_DES;
} else if ("DESede".equalsIgnoreCase(skey.getAlgorithm())) {
keyType = CKK_DES3;
} else if ("RC4".equalsIgnoreCase(skey.getAlgorithm()) ||
"ARCFOUR".equalsIgnoreCase(skey.getAlgorithm())) {
keyType = CKK_RC4;
}
CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] { CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
ATTR_SKEY_TOKEN_TRUE, ATTR_SKEY_TOKEN_TRUE,
ATTR_CLASS_SKEY, ATTR_PRIVATE_TRUE,
ATTR_PRIVATE_TRUE, new CK_ATTRIBUTE(CKA_LABEL, alias),
new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType), };
new CK_ATTRIBUTE(CKA_LABEL, alias),
new CK_ATTRIBUTE(CKA_VALUE, skey.getEncoded()) };
attrs = token.getAttributes
(TemplateManager.O_IMPORT, CKO_SECRET_KEY, keyType, attrs);
// create the new entry
Session session = null;
try { try {
session = token.getOpSession(); P11SecretKeyFactory.convertKey(token, skey, null, attrs);
token.p11.C_CreateObject(session.id(), attrs); } catch (InvalidKeyException ike) {
if (debug != null) { // re-throw KeyStoreException to match javadoc
debug.println("storeSkey created token secret key for [" + throw new KeyStoreException("Cannot convert to PKCS11 keys", ike);
alias + }
"]");
} // update global alias map
} finally { aliasMap.put(alias, new AliasInfo(alias));
token.releaseSession(session);
if (debug != null) {
debug.println("storeSkey created token secret key for [" +
alias + "]");
} }
} }
@ -2492,7 +2404,8 @@ final class P11KeyStore extends KeyStoreSpi {
// if there are duplicates (either between secret keys, // if there are duplicates (either between secret keys,
// or between a secret key and another object), // or between a secret key and another object),
// throw an exception // throw an exception
HashSet<String> sKeySet = new HashSet<String>(); HashMap<String, AliasInfo> sKeyMap =
new HashMap<String, AliasInfo>();
attrs = new CK_ATTRIBUTE[] { attrs = new CK_ATTRIBUTE[] {
ATTR_SKEY_TOKEN_TRUE, ATTR_SKEY_TOKEN_TRUE,
@ -2507,8 +2420,8 @@ final class P11KeyStore extends KeyStoreSpi {
// there is a CKA_LABEL // there is a CKA_LABEL
String cka_label = new String(attrs[0].getCharArray()); String cka_label = new String(attrs[0].getCharArray());
if (!sKeySet.contains(cka_label)) { if (sKeyMap.get(cka_label) == null) {
sKeySet.add(cka_label); sKeyMap.put(cka_label, new AliasInfo(cka_label));
} else { } else {
throw new KeyStoreException("invalid KeyStore state: " + throw new KeyStoreException("invalid KeyStore state: " +
"found multiple secret keys sharing same " + "found multiple secret keys sharing same " +
@ -2523,7 +2436,7 @@ final class P11KeyStore extends KeyStoreSpi {
ArrayList<AliasInfo> matchedCerts = ArrayList<AliasInfo> matchedCerts =
mapPrivateKeys(pkeyIDs, certMap); mapPrivateKeys(pkeyIDs, certMap);
boolean sharedLabel = mapCerts(matchedCerts, certMap); boolean sharedLabel = mapCerts(matchedCerts, certMap);
mapSecretKeys(sKeySet); mapSecretKeys(sKeyMap);
return sharedLabel; return sharedLabel;
@ -2547,7 +2460,7 @@ final class P11KeyStore extends KeyStoreSpi {
HashMap<String, HashSet<AliasInfo>> certMap) HashMap<String, HashSet<AliasInfo>> certMap)
throws PKCS11Exception, CertificateException { throws PKCS11Exception, CertificateException {
// global alias map // reset global alias map
aliasMap = new HashMap<String, AliasInfo>(); aliasMap = new HashMap<String, AliasInfo>();
// list of matched certs that we will return // list of matched certs that we will return
@ -2722,18 +2635,17 @@ final class P11KeyStore extends KeyStoreSpi {
* If the secret key shares a CKA_LABEL with another entry, * If the secret key shares a CKA_LABEL with another entry,
* throw an exception * throw an exception
*/ */
private void mapSecretKeys(HashSet<String> sKeySet) private void mapSecretKeys(HashMap<String, AliasInfo> sKeyMap)
throws KeyStoreException { throws KeyStoreException {
for (String label : sKeySet) { for (String label : sKeyMap.keySet()) {
if (!aliasMap.containsKey(label)) { if (aliasMap.containsKey(label)) {
aliasMap.put(label, new AliasInfo(label));
} else {
throw new KeyStoreException("invalid KeyStore state: " + throw new KeyStoreException("invalid KeyStore state: " +
"found secret key sharing CKA_LABEL [" + "found secret key sharing CKA_LABEL [" +
label + label +
"] with another token object"); "] with another token object");
} }
} }
aliasMap.putAll(sKeyMap);
} }
private void dumpTokenMap() { private void dumpTokenMap() {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -98,7 +98,6 @@ final class P11RSACipher extends CipherSpi {
this.token = token; this.token = token;
this.algorithm = "RSA"; this.algorithm = "RSA";
this.mechanism = mechanism; this.mechanism = mechanism;
session = token.getOpSession();
} }
// modes do not make sense for RSA, but allow ECB // modes do not make sense for RSA, but allow ECB
@ -184,7 +183,8 @@ final class P11RSACipher extends CipherSpi {
throw new InvalidKeyException throw new InvalidKeyException
("Wrap has to be used with public keys"); ("Wrap has to be used with public keys");
} }
// No further setup needed for C_Wrap(). We remain uninitialized. // No further setup needed for C_Wrap(). We'll initialize later if
// we can't use C_Wrap().
return; return;
} else if (opmode == Cipher.UNWRAP_MODE) { } else if (opmode == Cipher.UNWRAP_MODE) {
if (p11Key.isPrivate() == false) { if (p11Key.isPrivate() == false) {
@ -383,7 +383,8 @@ final class P11RSACipher extends CipherSpi {
return implDoFinal(out, outOfs, out.length - outOfs); return implDoFinal(out, outOfs, out.length - outOfs);
} }
private byte[] doFinal() throws BadPaddingException, IllegalBlockSizeException { private byte[] doFinal() throws BadPaddingException,
IllegalBlockSizeException {
byte[] t = new byte[2048]; byte[] t = new byte[2048];
int n = implDoFinal(t, 0, t.length); int n = implDoFinal(t, 0, t.length);
byte[] out = new byte[n]; byte[] out = new byte[n];
@ -394,20 +395,37 @@ final class P11RSACipher extends CipherSpi {
// see JCE spec // see JCE spec
protected byte[] engineWrap(Key key) throws InvalidKeyException, protected byte[] engineWrap(Key key) throws InvalidKeyException,
IllegalBlockSizeException { IllegalBlockSizeException {
// XXX Note that if we cannot convert key to a key on this token,
// we will fail. For example, trying a wrap an AES key on a token that
// does not support AES.
// We could implement a fallback that just encrypts the encoding
// (assuming the key is not sensitive). For now, we are operating under
// the assumption that this is not necessary.
String keyAlg = key.getAlgorithm(); String keyAlg = key.getAlgorithm();
P11Key secretKey = P11SecretKeyFactory.convertKey(token, key, keyAlg); P11Key sKey = null;
try {
// The conversion may fail, e.g. trying to wrap an AES key on
// a token that does not support AES, or when the key size is
// not within the range supported by the token.
sKey = P11SecretKeyFactory.convertKey(token, key, keyAlg);
} catch (InvalidKeyException ike) {
byte[] toBeWrappedKey = key.getEncoded();
if (toBeWrappedKey == null) {
throw new InvalidKeyException
("wrap() failed, no encoding available", ike);
}
// Directly encrypt the key encoding when key conversion failed
implInit(Cipher.ENCRYPT_MODE, p11Key);
implUpdate(toBeWrappedKey, 0, toBeWrappedKey.length);
try {
return doFinal();
} catch (BadPaddingException bpe) {
// should not occur
throw new InvalidKeyException("wrap() failed", bpe);
} finally {
// Restore original mode
implInit(Cipher.WRAP_MODE, p11Key);
}
}
Session s = null; Session s = null;
try { try {
s = token.getOpSession(); s = token.getOpSession();
byte[] b = token.p11.C_WrapKey(s.id(), new CK_MECHANISM(mechanism), return token.p11.C_WrapKey(s.id(), new CK_MECHANISM(mechanism),
p11Key.keyID, secretKey.keyID); p11Key.keyID, sKey.keyID);
return b;
} catch (PKCS11Exception e) { } catch (PKCS11Exception e) {
throw new InvalidKeyException("wrap() failed", e); throw new InvalidKeyException("wrap() failed", e);
} finally { } finally {
@ -431,11 +449,13 @@ final class P11RSACipher extends CipherSpi {
}; };
attributes = token.getAttributes attributes = token.getAttributes
(O_IMPORT, CKO_SECRET_KEY, keyType, attributes); (O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
long keyID = token.p11.C_UnwrapKey(s.id(), new CK_MECHANISM(mechanism), long keyID = token.p11.C_UnwrapKey(s.id(),
p11Key.keyID, wrappedKey, attributes); new CK_MECHANISM(mechanism), p11Key.keyID, wrappedKey,
return P11Key.secretKey(session, keyID, algorithm, 48 << 3, attributes); attributes);
return P11Key.secretKey(session, keyID, algorithm, 48 << 3,
attributes);
} catch (PKCS11Exception e) { } catch (PKCS11Exception e) {
throw new InvalidKeyException("wrap() failed", e); throw new InvalidKeyException("unwrap() failed", e);
} finally { } finally {
token.releaseSession(s); token.releaseSession(s);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -104,9 +104,20 @@ final class P11SecretKeyFactory extends SecretKeyFactorySpi {
/** /**
* Convert an arbitrary key of algorithm into a P11Key of provider. * Convert an arbitrary key of algorithm into a P11Key of provider.
* Used engineTranslateKey(), P11Cipher.init(), and P11Mac.init(). * Used in engineTranslateKey(), P11Cipher.init(), and P11Mac.init().
*/ */
static P11Key convertKey(Token token, Key key, String algorithm) static P11Key convertKey(Token token, Key key, String algo)
throws InvalidKeyException {
return convertKey(token, key, algo, null);
}
/**
* Convert an arbitrary key of algorithm w/ custom attributes into a
* P11Key of provider.
* Used in P11KeyStore.storeSkey.
*/
static P11Key convertKey(Token token, Key key, String algo,
CK_ATTRIBUTE[] extraAttrs)
throws InvalidKeyException { throws InvalidKeyException {
token.ensureValid(); token.ensureValid();
if (key == null) { if (key == null) {
@ -115,25 +126,41 @@ final class P11SecretKeyFactory extends SecretKeyFactorySpi {
if (key instanceof SecretKey == false) { if (key instanceof SecretKey == false) {
throw new InvalidKeyException("Key must be a SecretKey"); throw new InvalidKeyException("Key must be a SecretKey");
} }
long algorithmType; long algoType;
if (algorithm == null) { if (algo == null) {
algorithm = key.getAlgorithm(); algo = key.getAlgorithm();
algorithmType = getKeyType(algorithm); algoType = getKeyType(algo);
} else { } else {
algorithmType = getKeyType(algorithm); algoType = getKeyType(algo);
long keyAlgorithmType = getKeyType(key.getAlgorithm()); long keyAlgorithmType = getKeyType(key.getAlgorithm());
if (algorithmType != keyAlgorithmType) { if (algoType != keyAlgorithmType) {
if ((algorithmType == PCKK_HMAC) || (algorithmType == PCKK_SSLMAC)) { if ((algoType == PCKK_HMAC) || (algoType == PCKK_SSLMAC)) {
// ignore key algorithm for MACs // ignore key algorithm for MACs
} else { } else {
throw new InvalidKeyException throw new InvalidKeyException
("Key algorithm must be " + algorithm); ("Key algorithm must be " + algo);
} }
} }
} }
if (key instanceof P11Key) { if (key instanceof P11Key) {
P11Key p11Key = (P11Key)key; P11Key p11Key = (P11Key)key;
if (p11Key.token == token) { if (p11Key.token == token) {
if (extraAttrs != null) {
Session session = null;
try {
session = token.getObjSession();
long newKeyID = token.p11.C_CopyObject(session.id(),
p11Key.keyID, extraAttrs);
p11Key = (P11Key) (P11Key.secretKey(p11Key.session,
newKeyID, p11Key.algorithm, p11Key.keyLength,
extraAttrs));
} catch (PKCS11Exception p11e) {
throw new InvalidKeyException
("Cannot duplicate the PKCS11 key", p11e);
} finally {
token.releaseSession(session);
}
}
return p11Key; return p11Key;
} }
} }
@ -141,11 +168,11 @@ final class P11SecretKeyFactory extends SecretKeyFactorySpi {
if (p11Key != null) { if (p11Key != null) {
return p11Key; return p11Key;
} }
if ("RAW".equals(key.getFormat()) == false) { if ("RAW".equalsIgnoreCase(key.getFormat()) == false) {
throw new InvalidKeyException("Encoded format must be RAW"); throw new InvalidKeyException("Encoded format must be RAW");
} }
byte[] encoded = key.getEncoded(); byte[] encoded = key.getEncoded();
p11Key = createKey(token, encoded, algorithm, algorithmType); p11Key = createKey(token, encoded, algo, algoType, extraAttrs);
token.secretCache.put(key, p11Key); token.secretCache.put(key, p11Key);
return p11Key; return p11Key;
} }
@ -159,79 +186,79 @@ final class P11SecretKeyFactory extends SecretKeyFactorySpi {
} }
private static P11Key createKey(Token token, byte[] encoded, private static P11Key createKey(Token token, byte[] encoded,
String algorithm, long keyType) throws InvalidKeyException { String algorithm, long keyType, CK_ATTRIBUTE[] extraAttrs)
int n = encoded.length; throws InvalidKeyException {
int keyLength; int n = encoded.length << 3;
switch ((int)keyType) { int keyLength = n;
case (int)CKK_RC4: try {
if ((n < 5) || (n > 128)) { switch ((int)keyType) {
throw new InvalidKeyException case (int)CKK_DES:
("ARCFOUR key length must be between 5 and 128 bytes"); keyLength =
P11KeyGenerator.checkKeySize(CKM_DES_KEY_GEN, n, token);
fixDESParity(encoded, 0);
break;
case (int)CKK_DES3:
keyLength =
P11KeyGenerator.checkKeySize(CKM_DES3_KEY_GEN, n, token);
fixDESParity(encoded, 0);
fixDESParity(encoded, 8);
if (keyLength == 112) {
keyType = CKK_DES2;
} else {
keyType = CKK_DES3;
fixDESParity(encoded, 16);
}
break;
case (int)CKK_AES:
keyLength =
P11KeyGenerator.checkKeySize(CKM_AES_KEY_GEN, n, token);
break;
case (int)CKK_RC4:
keyLength =
P11KeyGenerator.checkKeySize(CKM_RC4_KEY_GEN, n, token);
break;
case (int)CKK_BLOWFISH:
keyLength =
P11KeyGenerator.checkKeySize(CKM_BLOWFISH_KEY_GEN, n,
token);
break;
case (int)CKK_GENERIC_SECRET:
case (int)PCKK_TLSPREMASTER:
case (int)PCKK_TLSRSAPREMASTER:
case (int)PCKK_TLSMASTER:
keyType = CKK_GENERIC_SECRET;
break;
case (int)PCKK_SSLMAC:
case (int)PCKK_HMAC:
if (n == 0) {
throw new InvalidKeyException
("MAC keys must not be empty");
}
keyType = CKK_GENERIC_SECRET;
break;
default:
throw new InvalidKeyException("Unknown algorithm " +
algorithm);
} }
keyLength = n << 3; } catch (InvalidAlgorithmParameterException iape) {
break; throw new InvalidKeyException("Invalid key for " + algorithm,
case (int)CKK_DES: iape);
if (n != 8) { } catch (ProviderException pe) {
throw new InvalidKeyException throw new InvalidKeyException("Could not create key", pe);
("DES key length must be 8 bytes");
}
keyLength = 56;
fixDESParity(encoded, 0);
break;
case (int)CKK_DES3:
if (n == 16) {
keyType = CKK_DES2;
} else if (n == 24) {
keyType = CKK_DES3;
fixDESParity(encoded, 16);
} else {
throw new InvalidKeyException
("DESede key length must be 16 or 24 bytes");
}
fixDESParity(encoded, 0);
fixDESParity(encoded, 8);
keyLength = n * 7;
break;
case (int)CKK_AES:
if ((n != 16) && (n != 24) && (n != 32)) {
throw new InvalidKeyException
("AES key length must be 16, 24, or 32 bytes");
}
keyLength = n << 3;
break;
case (int)CKK_BLOWFISH:
if ((n < 5) || (n > 56)) {
throw new InvalidKeyException
("Blowfish key length must be between 5 and 56 bytes");
}
keyLength = n << 3;
break;
case (int)CKK_GENERIC_SECRET:
case (int)PCKK_TLSPREMASTER:
case (int)PCKK_TLSRSAPREMASTER:
case (int)PCKK_TLSMASTER:
keyType = CKK_GENERIC_SECRET;
keyLength = n << 3;
break;
case (int)PCKK_SSLMAC:
case (int)PCKK_HMAC:
if (n == 0) {
throw new InvalidKeyException
("MAC keys must not be empty");
}
keyType = CKK_GENERIC_SECRET;
keyLength = n << 3;
break;
default:
throw new InvalidKeyException("Unknown algorithm " + algorithm);
} }
Session session = null; Session session = null;
try { try {
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { CK_ATTRIBUTE[] attributes;
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY), if (extraAttrs != null) {
new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType), attributes = new CK_ATTRIBUTE[3 + extraAttrs.length];
new CK_ATTRIBUTE(CKA_VALUE, encoded), System.arraycopy(extraAttrs, 0, attributes, 3,
}; extraAttrs.length);
} else {
attributes = new CK_ATTRIBUTE[3];
}
attributes[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY);
attributes[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType);
attributes[2] = new CK_ATTRIBUTE(CKA_VALUE, encoded);
attributes = token.getAttributes attributes = token.getAttributes
(O_IMPORT, CKO_SECRET_KEY, keyType, attributes); (O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
session = token.getObjSession(); session = token.getObjSession();
@ -280,7 +307,7 @@ final class P11SecretKeyFactory extends SecretKeyFactorySpi {
private byte[] getKeyBytes(SecretKey key) throws InvalidKeySpecException { private byte[] getKeyBytes(SecretKey key) throws InvalidKeySpecException {
try { try {
key = engineTranslateKey(key); key = engineTranslateKey(key);
if ("RAW".equals(key.getFormat()) == false) { if ("RAW".equalsIgnoreCase(key.getFormat()) == false) {
throw new InvalidKeySpecException throw new InvalidKeySpecException
("Could not obtain key bytes"); ("Could not obtain key bytes");
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -601,14 +601,26 @@ public final class SunPKCS11 extends AuthProvider {
// XXX attributes for Ciphers (supported modes, padding) // XXX attributes for Ciphers (supported modes, padding)
d(CIP, "ARCFOUR", P11Cipher, s("RC4"), d(CIP, "ARCFOUR", P11Cipher, s("RC4"),
m(CKM_RC4)); m(CKM_RC4));
// XXX only CBC/NoPadding for block ciphers
d(CIP, "DES/CBC/NoPadding", P11Cipher, d(CIP, "DES/CBC/NoPadding", P11Cipher,
m(CKM_DES_CBC)); m(CKM_DES_CBC));
d(CIP, "DES/CBC/PKCS5Padding", P11Cipher,
m(CKM_DES_CBC_PAD, CKM_DES_CBC));
d(CIP, "DES/ECB", P11Cipher, s("DES"),
m(CKM_DES_ECB));
d(CIP, "DESede/CBC/NoPadding", P11Cipher, d(CIP, "DESede/CBC/NoPadding", P11Cipher,
m(CKM_DES3_CBC)); m(CKM_DES3_CBC));
d(CIP, "DESede/CBC/PKCS5Padding", P11Cipher,
m(CKM_DES3_CBC_PAD, CKM_DES3_CBC));
d(CIP, "DESede/ECB", P11Cipher, s("DESede"),
m(CKM_DES3_ECB));
d(CIP, "AES/CBC/NoPadding", P11Cipher, d(CIP, "AES/CBC/NoPadding", P11Cipher,
m(CKM_AES_CBC)); m(CKM_AES_CBC));
d(CIP, "Blowfish/CBC/NoPadding", P11Cipher, d(CIP, "AES/CBC/PKCS5Padding", P11Cipher,
m(CKM_AES_CBC_PAD, CKM_AES_CBC));
d(CIP, "AES/ECB", P11Cipher, s("AES"),
m(CKM_AES_ECB));
d(CIP, "Blowfish/CBC", P11Cipher,
m(CKM_BLOWFISH_CBC)); m(CKM_BLOWFISH_CBC));
// XXX RSA_X_509, RSA_OAEP not yet supported // XXX RSA_X_509, RSA_OAEP not yet supported

View File

@ -87,6 +87,9 @@ class EndEntityChecker {
// the Microsoft Server-Gated-Cryptography EKU extension OID // the Microsoft Server-Gated-Cryptography EKU extension OID
private final static String OID_EKU_MS_SGC = "1.3.6.1.4.1.311.10.3.3"; private final static String OID_EKU_MS_SGC = "1.3.6.1.4.1.311.10.3.3";
// the recognized extension OIDs
private final static String OID_SUBJECT_ALT_NAME = "2.5.29.17";
private final static String NSCT_SSL_CLIENT = private final static String NSCT_SSL_CLIENT =
NetscapeCertTypeExtension.SSL_CLIENT; NetscapeCertTypeExtension.SSL_CLIENT;
@ -171,6 +174,13 @@ class EndEntityChecker {
throws CertificateException { throws CertificateException {
// basic constraints irrelevant in EE certs // basic constraints irrelevant in EE certs
exts.remove(SimpleValidator.OID_BASIC_CONSTRAINTS); exts.remove(SimpleValidator.OID_BASIC_CONSTRAINTS);
// If the subject field contains an empty sequence, the subjectAltName
// extension MUST be marked critical.
// We do not check the validity of the critical extension, just mark
// it recognizable here.
exts.remove(OID_SUBJECT_ALT_NAME);
if (!exts.isEmpty()) { if (!exts.isEmpty()) {
throw new CertificateException("Certificate contains unsupported " throw new CertificateException("Certificate contains unsupported "
+ "critical extensions: " + exts); + "critical extensions: " + exts);

View File

@ -626,6 +626,7 @@ appendClassPath( JPLISAgent* agent,
jvmtiError jvmtierr; jvmtiError jvmtierr;
jvmtierr = (*jvmtienv)->AddToSystemClassLoaderSearch(jvmtienv, jarfile); jvmtierr = (*jvmtienv)->AddToSystemClassLoaderSearch(jvmtienv, jarfile);
check_phase_ret_1(jvmtierr);
if (jvmtierr == JVMTI_ERROR_NONE) { if (jvmtierr == JVMTI_ERROR_NONE) {
return 0; return 0;
@ -634,6 +635,7 @@ appendClassPath( JPLISAgent* agent,
jvmtiError err; jvmtiError err;
err = (*jvmtienv)->GetPhase(jvmtienv, &phase); err = (*jvmtienv)->GetPhase(jvmtienv, &phase);
/* can be called from any phase */
jplis_assert(err == JVMTI_ERROR_NONE); jplis_assert(err == JVMTI_ERROR_NONE);
if (phase == JVMTI_PHASE_LIVE) { if (phase == JVMTI_PHASE_LIVE) {
@ -805,6 +807,8 @@ appendBootClassPath( JPLISAgent* agent,
/* print warning if boot class path not updated */ /* print warning if boot class path not updated */
if (jvmtierr != JVMTI_ERROR_NONE) { if (jvmtierr != JVMTI_ERROR_NONE) {
check_phase_blob_ret(jvmtierr, free(path));
fprintf(stderr, "WARNING: %s not added to bootstrap class loader search: ", path); fprintf(stderr, "WARNING: %s not added to bootstrap class loader search: ", path);
switch (jvmtierr) { switch (jvmtierr) {
case JVMTI_ERROR_ILLEGAL_ARGUMENT : case JVMTI_ERROR_ILLEGAL_ARGUMENT :

View File

@ -179,6 +179,7 @@ getJPLISEnvironment(jvmtiEnv * jvmtienv) {
jvmtierror = (*jvmtienv)->GetEnvironmentLocalStorage( jvmtierror = (*jvmtienv)->GetEnvironmentLocalStorage(
jvmtienv, jvmtienv,
(void**)&environment); (void**)&environment);
/* can be called from any phase */
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
if (jvmtierror == JVMTI_ERROR_NONE) { if (jvmtierror == JVMTI_ERROR_NONE) {
@ -230,6 +231,7 @@ createNewJPLISAgent(JavaVM * vm, JPLISAgent **agent_ptr) {
/* don't leak envs */ /* don't leak envs */
if ( initerror != JPLIS_INIT_ERROR_NONE ) { if ( initerror != JPLIS_INIT_ERROR_NONE ) {
jvmtiError jvmtierror = (*jvmtienv)->DisposeEnvironment(jvmtienv); jvmtiError jvmtierror = (*jvmtienv)->DisposeEnvironment(jvmtienv);
/* can be called from any phase */
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
} }
} }
@ -259,7 +261,7 @@ initializeJPLISAgent( JPLISAgent * agent,
agent->mNormalEnvironment.mIsRetransformer = JNI_FALSE; agent->mNormalEnvironment.mIsRetransformer = JNI_FALSE;
agent->mRetransformEnvironment.mJVMTIEnv = NULL; /* NULL until needed */ agent->mRetransformEnvironment.mJVMTIEnv = NULL; /* NULL until needed */
agent->mRetransformEnvironment.mAgent = agent; agent->mRetransformEnvironment.mAgent = agent;
agent->mRetransformEnvironment.mIsRetransformer = JNI_TRUE; agent->mRetransformEnvironment.mIsRetransformer = JNI_FALSE; /* JNI_FALSE until mJVMTIEnv is set */
agent->mAgentmainCaller = NULL; agent->mAgentmainCaller = NULL;
agent->mInstrumentationImpl = NULL; agent->mInstrumentationImpl = NULL;
agent->mPremainCaller = NULL; agent->mPremainCaller = NULL;
@ -277,18 +279,25 @@ initializeJPLISAgent( JPLISAgent * agent,
jvmtierror = (*jvmtienv)->SetEnvironmentLocalStorage( jvmtierror = (*jvmtienv)->SetEnvironmentLocalStorage(
jvmtienv, jvmtienv,
&(agent->mNormalEnvironment)); &(agent->mNormalEnvironment));
/* can be called from any phase */
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
/* check what capabilities are available */ /* check what capabilities are available */
checkCapabilities(agent); checkCapabilities(agent);
/* check phase - if live phase then we don't need the VMInit event */ /* check phase - if live phase then we don't need the VMInit event */
jvmtierror == (*jvmtienv)->GetPhase(jvmtienv, &phase); jvmtierror = (*jvmtienv)->GetPhase(jvmtienv, &phase);
/* can be called from any phase */
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
if (phase == JVMTI_PHASE_LIVE) { if (phase == JVMTI_PHASE_LIVE) {
return JPLIS_INIT_ERROR_NONE; return JPLIS_INIT_ERROR_NONE;
} }
if (phase != JVMTI_PHASE_ONLOAD) {
/* called too early or called too late; either way bail out */
return JPLIS_INIT_ERROR_FAILURE;
}
/* now turn on the VMInit event */ /* now turn on the VMInit event */
if ( jvmtierror == JVMTI_ERROR_NONE ) { if ( jvmtierror == JVMTI_ERROR_NONE ) {
jvmtiEventCallbacks callbacks; jvmtiEventCallbacks callbacks;
@ -298,6 +307,7 @@ initializeJPLISAgent( JPLISAgent * agent,
jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv, jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv,
&callbacks, &callbacks,
sizeof(callbacks)); sizeof(callbacks));
check_phase_ret_blob(jvmtierror, JPLIS_INIT_ERROR_FAILURE);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
} }
@ -307,6 +317,7 @@ initializeJPLISAgent( JPLISAgent * agent,
JVMTI_ENABLE, JVMTI_ENABLE,
JVMTI_EVENT_VM_INIT, JVMTI_EVENT_VM_INIT,
NULL /* all threads */); NULL /* all threads */);
check_phase_ret_blob(jvmtierror, JPLIS_INIT_ERROR_FAILURE);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
} }
@ -622,6 +633,7 @@ setLivePhaseEventHandlers( JPLISAgent * agent) {
jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv, jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv,
&callbacks, &callbacks,
sizeof(callbacks)); sizeof(callbacks));
check_phase_ret_false(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
@ -632,6 +644,7 @@ setLivePhaseEventHandlers( JPLISAgent * agent) {
JVMTI_DISABLE, JVMTI_DISABLE,
JVMTI_EVENT_VM_INIT, JVMTI_EVENT_VM_INIT,
NULL /* all threads */); NULL /* all threads */);
check_phase_ret_false(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
} }
@ -642,6 +655,7 @@ setLivePhaseEventHandlers( JPLISAgent * agent) {
JVMTI_ENABLE, JVMTI_ENABLE,
JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
NULL /* all threads */); NULL /* all threads */);
check_phase_ret_false(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
} }
@ -660,6 +674,7 @@ checkCapabilities(JPLISAgent * agent) {
memset(&potentialCapabilities, 0, sizeof(potentialCapabilities)); memset(&potentialCapabilities, 0, sizeof(potentialCapabilities));
jvmtierror = (*jvmtienv)->GetPotentialCapabilities(jvmtienv, &potentialCapabilities); jvmtierror = (*jvmtienv)->GetPotentialCapabilities(jvmtienv, &potentialCapabilities);
check_phase_ret(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
if ( jvmtierror == JVMTI_ERROR_NONE ) { if ( jvmtierror == JVMTI_ERROR_NONE ) {
@ -681,9 +696,11 @@ enableNativeMethodPrefixCapability(jvmtiEnv * jvmtienv) {
jvmtiError jvmtierror; jvmtiError jvmtierror;
jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities); jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
/* can be called from any phase */
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
desiredCapabilities.can_set_native_method_prefix = 1; desiredCapabilities.can_set_native_method_prefix = 1;
jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities); jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
check_phase_ret(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
} }
@ -715,9 +732,11 @@ addOriginalMethodOrderCapability(JPLISAgent * agent) {
jvmtiError jvmtierror; jvmtiError jvmtierror;
jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities); jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
/* can be called from any phase */
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
desiredCapabilities.can_maintain_original_method_order = 1; desiredCapabilities.can_maintain_original_method_order = 1;
jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities); jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
check_phase_ret(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
} }
@ -732,9 +751,11 @@ addRedefineClassesCapability(JPLISAgent * agent) {
if (agent->mRedefineAvailable && !agent->mRedefineAdded) { if (agent->mRedefineAvailable && !agent->mRedefineAdded) {
jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities); jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
/* can be called from any phase */
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
desiredCapabilities.can_redefine_classes = 1; desiredCapabilities.can_redefine_classes = 1;
jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities); jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
check_phase_ret(jvmtierror);
/* /*
* With mixed premain/agentmain agents then it's possible that the * With mixed premain/agentmain agents then it's possible that the
@ -998,6 +1019,7 @@ retransformableEnvironment(JPLISAgent * agent) {
if (jvmtierror == JVMTI_ERROR_NONE) { if (jvmtierror == JVMTI_ERROR_NONE) {
// install the retransforming environment // install the retransforming environment
agent->mRetransformEnvironment.mJVMTIEnv = retransformerEnv; agent->mRetransformEnvironment.mJVMTIEnv = retransformerEnv;
agent->mRetransformEnvironment.mIsRetransformer = JNI_TRUE;
// Make it for ClassFileLoadHook handling // Make it for ClassFileLoadHook handling
jvmtierror = (*retransformerEnv)->SetEnvironmentLocalStorage( jvmtierror = (*retransformerEnv)->SetEnvironmentLocalStorage(
@ -1025,6 +1047,7 @@ isModifiableClass(JNIEnv * jnienv, JPLISAgent * agent, jclass clazz) {
jvmtierror = (*jvmtienv)->IsModifiableClass( jvmtienv, jvmtierror = (*jvmtienv)->IsModifiableClass( jvmtienv,
clazz, clazz,
&is_modifiable); &is_modifiable);
check_phase_ret_false(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
return is_modifiable; return is_modifiable;
@ -1032,7 +1055,7 @@ isModifiableClass(JNIEnv * jnienv, JPLISAgent * agent, jclass clazz) {
jboolean jboolean
isRetransformClassesSupported(JNIEnv * jnienv, JPLISAgent * agent) { isRetransformClassesSupported(JNIEnv * jnienv, JPLISAgent * agent) {
return retransformableEnvironment(agent) != NULL; return agent->mRetransformEnvironment.mIsRetransformer;
} }
void void
@ -1075,6 +1098,12 @@ retransformClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classes) {
numClasses = (*jnienv)->GetArrayLength(jnienv, classes); numClasses = (*jnienv)->GetArrayLength(jnienv, classes);
errorOccurred = checkForThrowable(jnienv); errorOccurred = checkForThrowable(jnienv);
jplis_assert(!errorOccurred); jplis_assert(!errorOccurred);
if (!errorOccurred && numClasses == 0) {
jplis_assert(numClasses != 0);
errorOccurred = JNI_TRUE;
errorCode = JVMTI_ERROR_NULL_POINTER;
}
} }
if (!errorOccurred) { if (!errorOccurred) {
@ -1096,6 +1125,13 @@ retransformClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classes) {
if (errorOccurred) { if (errorOccurred) {
break; break;
} }
if (classArray[index] == NULL) {
jplis_assert(classArray[index] != NULL);
errorOccurred = JNI_TRUE;
errorCode = JVMTI_ERROR_NULL_POINTER;
break;
}
} }
} }
@ -1217,6 +1253,7 @@ redefineClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classDefinitio
if (!errorOccurred) { if (!errorOccurred) {
jvmtiError errorCode = JVMTI_ERROR_NONE; jvmtiError errorCode = JVMTI_ERROR_NONE;
errorCode = (*jvmtienv)->RedefineClasses(jvmtienv, numDefs, classDefs); errorCode = (*jvmtienv)->RedefineClasses(jvmtienv, numDefs, classDefs);
check_phase_blob_ret(errorCode, deallocate(jvmtienv, (void*)classDefs));
errorOccurred = (errorCode != JVMTI_ERROR_NONE); errorOccurred = (errorCode != JVMTI_ERROR_NONE);
if ( errorOccurred ) { if ( errorOccurred ) {
createAndThrowThrowableFromJVMTIErrorCode(jnienv, errorCode); createAndThrowThrowableFromJVMTIErrorCode(jnienv, errorCode);
@ -1250,6 +1287,7 @@ commonGetClassList( JNIEnv * jnienv,
classLoader, classLoader,
&classCount, &classCount,
&classes); &classes);
check_phase_ret_blob(jvmtierror, localArray);
errorOccurred = (jvmtierror != JVMTI_ERROR_NONE); errorOccurred = (jvmtierror != JVMTI_ERROR_NONE);
jplis_assert(!errorOccurred); jplis_assert(!errorOccurred);
@ -1311,6 +1349,7 @@ getObjectSize(JNIEnv * jnienv, JPLISAgent * agent, jobject objectToSize) {
jvmtiError jvmtierror = JVMTI_ERROR_NONE; jvmtiError jvmtierror = JVMTI_ERROR_NONE;
jvmtierror = (*jvmtienv)->GetObjectSize(jvmtienv, objectToSize, &objectSize); jvmtierror = (*jvmtienv)->GetObjectSize(jvmtienv, objectToSize, &objectSize);
check_phase_ret_0(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE); jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
if ( jvmtierror != JVMTI_ERROR_NONE ) { if ( jvmtierror != JVMTI_ERROR_NONE ) {
createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror); createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
@ -1360,6 +1399,7 @@ appendToClassLoaderSearch(JNIEnv * jnienv, JPLISAgent * agent, jstring jarFile,
} else { } else {
jvmtierror = (*jvmtienv)->AddToSystemClassLoaderSearch(jvmtienv, platformChars); jvmtierror = (*jvmtienv)->AddToSystemClassLoaderSearch(jvmtienv, platformChars);
} }
check_phase_ret(jvmtierror);
if ( jvmtierror != JVMTI_ERROR_NONE ) { if ( jvmtierror != JVMTI_ERROR_NONE ) {
createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror); createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
@ -1450,6 +1490,7 @@ setNativeMethodPrefixes(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray prefix
} }
err = (*jvmtienv)->SetNativeMethodPrefixes(jvmtienv, inx, (char**)prefixes); err = (*jvmtienv)->SetNativeMethodPrefixes(jvmtienv, inx, (char**)prefixes);
/* can be called from any phase */
jplis_assert(err == JVMTI_ERROR_NONE); jplis_assert(err == JVMTI_ERROR_NONE);
for (i = 0; i < inx; i++) { for (i = 0; i < inx; i++) {

View File

@ -266,6 +266,48 @@ setNativeMethodPrefixes(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray prefix
#define jvmti(a) a->mNormalEnvironment.mJVMTIEnv #define jvmti(a) a->mNormalEnvironment.mJVMTIEnv
/*
* A set of macros for insulating the JLI method callers from
* JVMTI_ERROR_WRONG_PHASE return codes.
*/
/* for a JLI method where "blob" is executed before simply returning */
#define check_phase_blob_ret(ret, blob) \
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
blob; \
return; \
}
/* for a JLI method where simply returning is benign */
#define check_phase_ret(ret) \
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
return; \
}
/* for a JLI method where returning zero (0) is benign */
#define check_phase_ret_0(ret) \
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
return 0; \
}
/* for a JLI method where returning one (1) is benign */
#define check_phase_ret_1(ret) \
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
return 1; \
}
/* for a case where a specific "blob" must be returned */
#define check_phase_ret_blob(ret, blob) \
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
return (blob); \
}
/* for a JLI method where returning false is benign */
#define check_phase_ret_false(ret) \
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
return (jboolean) 0; \
}
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -23,6 +23,14 @@
* have any questions. * have any questions.
*/ */
#ifdef _WIN32
/*
* Win* needs this include. However, Linux and Solaris do not.
* Having this include on Solaris SPARC breaks having non US-ASCII
* characters in the value of the Premain-Class attribute.
*/
#include <ctype.h>
#endif /* _WIN32 */
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -45,11 +53,37 @@ doAttribute(const char* name, const char* value, void* user_data) {
if (attribute->name == NULL) { if (attribute->name == NULL) {
free(attribute); free(attribute);
} else { } else {
attribute->value = strdup(value); char *begin = (char *)value;
char *end;
size_t value_len;
/* skip any leading white space */
while (isspace(*begin)) {
begin++;
}
/* skip any trailing white space */
end = &begin[strlen(begin)];
while (end > begin && isspace(end[-1])) {
end--;
}
if (begin == end) {
/* no value so skip this attribute */
free(attribute->name);
free(attribute);
return;
}
value_len = (size_t)(end - begin);
attribute->value = malloc(value_len + 1);
if (attribute->value == NULL) { if (attribute->value == NULL) {
free(attribute->name); free(attribute->name);
free(attribute); free(attribute);
} else { } else {
/* save the value without leading or trailing whitespace */
strncpy(attribute->value, begin, value_len);
attribute->value[value_len] = '\0';
attribute->next = NULL; attribute->next = NULL;
if (context->head == NULL) { if (context->head == NULL) {
context->head = attribute; context->head = attribute;

View File

@ -74,6 +74,7 @@ confirmingTLSSet( jvmtiEnv * jvmtienv,
jvmtienv, jvmtienv,
thread, thread,
newValue); newValue);
check_phase_ret_blob(error, error);
#if JPLISASSERT_ENABLEASSERTIONS #if JPLISASSERT_ENABLEASSERTIONS
assertTLSValue( jvmtienv, assertTLSValue( jvmtienv,
@ -96,6 +97,7 @@ assertTLSValue( jvmtiEnv * jvmtienv,
jvmtienv, jvmtienv,
thread, thread,
&test); &test);
check_phase_ret(error);
jplis_assert(error == JVMTI_ERROR_NONE); jplis_assert(error == JVMTI_ERROR_NONE);
jplis_assert(test == expected); jplis_assert(test == expected);
} }
@ -111,6 +113,7 @@ tryToAcquireReentrancyToken( jvmtiEnv * jvmtienv,
jvmtienv, jvmtienv,
thread, thread,
&storedValue); &storedValue);
check_phase_ret_false(error);
jplis_assert(error == JVMTI_ERROR_NONE); jplis_assert(error == JVMTI_ERROR_NONE);
if ( error == JVMTI_ERROR_NONE ) { if ( error == JVMTI_ERROR_NONE ) {
/* if this thread is already inside, just return false and short-circuit */ /* if this thread is already inside, just return false and short-circuit */

View File

@ -46,6 +46,7 @@ allocate(jvmtiEnv * jvmtienv, size_t bytecount) {
error = (*jvmtienv)->Allocate(jvmtienv, error = (*jvmtienv)->Allocate(jvmtienv,
bytecount, bytecount,
(unsigned char**) &resultBuffer); (unsigned char**) &resultBuffer);
/* may be called from any phase */
jplis_assert(error == JVMTI_ERROR_NONE); jplis_assert(error == JVMTI_ERROR_NONE);
if ( error != JVMTI_ERROR_NONE ) { if ( error != JVMTI_ERROR_NONE ) {
resultBuffer = NULL; resultBuffer = NULL;
@ -66,6 +67,7 @@ deallocate(jvmtiEnv * jvmtienv, void * buffer) {
error = (*jvmtienv)->Deallocate(jvmtienv, error = (*jvmtienv)->Deallocate(jvmtienv,
(unsigned char*)buffer); (unsigned char*)buffer);
/* may be called from any phase */
jplis_assert_msg(error == JVMTI_ERROR_NONE, "Can't deallocate memory"); jplis_assert_msg(error == JVMTI_ERROR_NONE, "Can't deallocate memory");
return; return;
} }

View File

@ -123,7 +123,10 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
C_GetFunctionList = (CK_C_GetFunctionList) dlsym(hModule, getFunctionListStr); C_GetFunctionList = (CK_C_GetFunctionList) dlsym(hModule, getFunctionListStr);
(*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr); (*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr);
} }
if ((C_GetFunctionList == NULL) || ((systemErrorMessage = dlerror()) != NULL)){ if (C_GetFunctionList == NULL) {
throwIOException(env, "ERROR: C_GetFunctionList == NULL");
return;
} else if ( (systemErrorMessage = dlerror()) != NULL ){
throwIOException(env, systemErrorMessage); throwIOException(env, systemErrorMessage);
return; return;
} }

View File

@ -0,0 +1,61 @@
/*
* Copyright 2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6658779
* @summary Basic Test for HotSpotDiagnosticMXBean.getDiagnosticOptions()
* @author Daniel Fuchs
*
* @run main GetDiagnosticOptions
*/
import com.sun.management.HotSpotDiagnosticMXBean;
import com.sun.management.VMOption;
import java.lang.management.ManagementFactory;
import java.util.List;
import javax.management.MBeanServer;
public class GetDiagnosticOptions {
private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
"com.sun.management:type=HotSpotDiagnostic";
public static void main(String[] args) throws Exception {
HotSpotDiagnosticMXBean mbean =
sun.management.ManagementFactory.getDiagnosticMXBean();
checkDiagnosticOptions(mbean);
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
mbean = ManagementFactory.newPlatformMXBeanProxy(mbs,
HOTSPOT_DIAGNOSTIC_MXBEAN_NAME,
HotSpotDiagnosticMXBean.class);
checkDiagnosticOptions(mbean);
}
private static void checkDiagnosticOptions(HotSpotDiagnosticMXBean mbean) {
List<VMOption> options = mbean.getDiagnosticOptions();
for (VMOption opt : options) {
System.out.println("option: "+opt.getName()+"="+opt.getValue());
}
}
}

View File

@ -23,8 +23,10 @@
# @test # @test
# @bug 5055293 # @bug 5055293
# @summary Test non US-ASCII characters in the value of the Boot-Class-Path # @summary Test non US-ASCII characters in the value of the Boot-Class-Path
# attribute. # attribute.
#
# @run shell/timeout=240 BootClassPathTest.sh
if [ "${TESTJAVA}" = "" ] if [ "${TESTJAVA}" = "" ]
then then
@ -72,7 +74,7 @@ echo "Creating agent jar file..."
echo "Running test..." echo "Running test..."
"${JAVA}" -javaagent:"${TESTCLASSES}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain "${JAVA}" ${TESTVMOPTS} -javaagent:"${TESTCLASSES}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain
result=$? result=$?
echo "Cleanup..." echo "Cleanup..."

View File

@ -70,9 +70,11 @@ JAR="${TESTJAVA}/bin/jar"
cp ${TESTSRC}/${AGENT}.java . cp ${TESTSRC}/${AGENT}.java .
cp ${TESTSRC}/${APP}.java . cp ${TESTSRC}/${APP}.java .
rm -rf ilib rm -rf ilib
cp -r ${TESTSRC}/ilib . mkdir ilib
mkdir bootpath cp ${TESTSRC}/ilib/*.java ilib
cp -r ${TESTSRC}/bootreporter bootpath rm -rf bootpath
mkdir -p bootpath/bootreporter
cp ${TESTSRC}/bootreporter/*.java bootpath/bootreporter
cd bootpath cd bootpath
${JAVAC} bootreporter/*.java ${JAVAC} bootreporter/*.java

View File

@ -0,0 +1,483 @@
#
# Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
# @test
# @bug 6274276
# @summary JLI JAR manifest processing should ignore leading and trailing white space.
# @author Daniel D. Daugherty
#
# @run build ManifestTestApp
# @run shell/timeout=900 ManifestTest.sh
#
make_a_JAR() {
# version_line and premain_line are required
version_line="Manifest-Version: 1.0"
premain_line="Premain-Class: ${AGENT}"
boot_cp_line=""
expect_boot_cp_line="ExampleForBootClassPath was not loaded."
can_redef_line=""
expect_redef_line="isRedefineClassesSupported()=false"
can_retrans_line=""
expect_retrans_line="isRetransformClassesSupported()=false"
can_set_nmp_line=""
expect_set_nmp_line="isNativeMethodPrefixSupported()=false"
while [ $# != 0 ] ; do
case "$1" in
defaults)
# just use the defaults for the test
;;
boot_cp_line1)
boot_cp_line="Boot-Class-Path: no_white_space"
expect_boot_cp_line="ExampleForBootClassPath was loaded."
mkdir -p no_white_space
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class no_white_space
;;
boot_cp_line2)
boot_cp_line="Boot-Class-Path: has_leading_blank"
expect_boot_cp_line="ExampleForBootClassPath was loaded."
mkdir -p has_leading_blank " has_leading_blank"
# the good class is in the directory without the blank
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class \
has_leading_blank
# the bad class is in the directory with the blank
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class.bad \
" has_leading_blank"/ExampleForBootClassPath.class
;;
boot_cp_line3)
boot_cp_line="Boot-Class-Path: has_trailing_blank "
expect_boot_cp_line="ExampleForBootClassPath was loaded."
mkdir -p has_trailing_blank "has_trailing_blank "
# the good class is in the directory without the blank
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class \
has_trailing_blank
# the bad class is in the directory with the blank
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class.bad \
"has_trailing_blank "/ExampleForBootClassPath.class
;;
boot_cp_line4)
boot_cp_line="Boot-Class-Path: has_leading_and_trailing_blank "
expect_boot_cp_line="ExampleForBootClassPath was loaded."
mkdir -p has_leading_and_trailing_blank \
" has_leading_and_trailing_blank "
# the good class is in the directory without the blanks
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class \
has_leading_and_trailing_blank
# the bad class is in the directory with the blanks
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class.bad \
" has_leading_and_trailing_blank "/ExampleForBootClassPath.class
;;
boot_cp_line5)
boot_cp_line="Boot-Class-Path: has_embedded blank"
expect_boot_cp_line="ExampleForBootClassPath was loaded."
mkdir -p has_embedded "has_embedded blank"
# the good class is in the first blank separated word
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class has_embedded
# the bad class is in the directory with the blank
cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class.bad \
"has_embedded blank"/ExampleForBootClassPath.class
;;
can_redef_line1)
can_redef_line="Can-Redefine-Classes: true"
expect_redef_line="isRedefineClassesSupported()=true"
;;
can_redef_line2)
can_redef_line="Can-Redefine-Classes: true"
expect_redef_line="isRedefineClassesSupported()=true"
;;
can_redef_line3)
can_redef_line="Can-Redefine-Classes: true "
expect_redef_line="isRedefineClassesSupported()=true"
;;
can_redef_line4)
can_redef_line="Can-Redefine-Classes: true "
expect_redef_line="isRedefineClassesSupported()=true"
;;
can_redef_line5)
can_redef_line="Can-Redefine-Classes: false"
;;
can_redef_line6)
can_redef_line="Can-Redefine-Classes: false"
;;
can_redef_line7)
can_redef_line="Can-Redefine-Classes: false "
;;
can_redef_line8)
can_redef_line="Can-Redefine-Classes: false "
;;
can_redef_line9)
# this line makes the jar command unhappy and that's
# not what we're testing so skip this case
can_redef_line="Can-Redefine-Classes:"
;;
can_redef_line10)
can_redef_line="Can-Redefine-Classes: "
;;
can_redef_line11)
can_redef_line="Can-Redefine-Classes: "
;;
can_retrans_line1)
can_retrans_line="Can-Retransform-Classes: true"
expect_retrans_line="isRetransformClassesSupported()=true"
;;
can_retrans_line2)
can_retrans_line="Can-Retransform-Classes: true"
expect_retrans_line="isRetransformClassesSupported()=true"
;;
can_retrans_line3)
can_retrans_line="Can-Retransform-Classes: true "
expect_retrans_line="isRetransformClassesSupported()=true"
;;
can_retrans_line4)
can_retrans_line="Can-Retransform-Classes: true "
expect_retrans_line="isRetransformClassesSupported()=true"
;;
can_retrans_line5)
can_retrans_line="Can-Retransform-Classes: false"
;;
can_retrans_line6)
can_retrans_line="Can-Retransform-Classes: false"
;;
can_retrans_line7)
can_retrans_line="Can-Retransform-Classes: false "
;;
can_retrans_line8)
can_retrans_line="Can-Retransform-Classes: false "
;;
can_retrans_line9)
# this line makes the jar command unhappy and that's
# not what we're testing so skip this case
can_retrans_line="Can-Retransform-Classes:"
;;
can_retrans_line10)
can_retrans_line="Can-Retransform-Classes: "
;;
can_retrans_line11)
can_retrans_line="Can-Retransform-Classes: "
;;
can_set_nmp_line1)
can_set_nmp_line="Can-Set-Native-Method-Prefix: true"
expect_set_nmp_line="isNativeMethodPrefixSupported()=true"
;;
can_set_nmp_line2)
can_set_nmp_line="Can-Set-Native-Method-Prefix: true"
expect_set_nmp_line="isNativeMethodPrefixSupported()=true"
;;
can_set_nmp_line3)
can_set_nmp_line="Can-Set-Native-Method-Prefix: true "
expect_set_nmp_line="isNativeMethodPrefixSupported()=true"
;;
can_set_nmp_line4)
can_set_nmp_line="Can-Set-Native-Method-Prefix: true "
expect_set_nmp_line="isNativeMethodPrefixSupported()=true"
;;
can_set_nmp_line5)
can_set_nmp_line="Can-Set-Native-Method-Prefix: false"
;;
can_set_nmp_line6)
can_set_nmp_line="Can-Set-Native-Method-Prefix: false"
;;
can_set_nmp_line7)
can_set_nmp_line="Can-Set-Native-Method-Prefix: false "
;;
can_set_nmp_line8)
can_set_nmp_line="Can-Set-Native-Method-Prefix: false "
;;
can_set_nmp_line9)
# this line makes the jar command unhappy and that's
# not what we're testing so skip this case
can_set_nmp_line="Can-Set-Native-Method-Prefix:"
;;
can_set_nmp_line10)
can_set_nmp_line="Can-Set-Native-Method-Prefix: "
;;
can_set_nmp_line11)
can_set_nmp_line="Can-Set-Native-Method-Prefix: "
;;
premain_line1)
premain_line="Premain-Class: ${AGENT}"
;;
premain_line2)
premain_line="Premain-Class: ${AGENT} "
;;
premain_line3)
premain_line="Premain-Class: ${AGENT} "
;;
version_line1)
version_line="Manifest-Version: 1.0"
;;
version_line2)
version_line="Manifest-Version: 1.0 "
;;
version_line3)
version_line="Manifest-Version: 1.0 "
;;
*)
echo "ERROR: invalid test token"
exit 1
esac
shift
done
echo "${version_line}" > ${AGENT}.mf
echo "${premain_line}" >> ${AGENT}.mf
if [ -n "$boot_cp_line" ]; then
echo "${boot_cp_line}" >> ${AGENT}.mf
fi
if [ -n "$can_redef_line" ]; then
echo "${can_redef_line}" >> ${AGENT}.mf
fi
if [ -n "$can_retrans_line" ]; then
echo "${can_retrans_line}" >> ${AGENT}.mf
fi
if [ -n "$can_set_nmp_line" ]; then
echo "${can_set_nmp_line}" >> ${AGENT}.mf
fi
rm -f ${AGENT}.jar
${JAR} cvfm ${AGENT}.jar ${AGENT}.mf ${AGENT}.class
echo "$expect_boot_cp_line" > expect_boot_cp_line
echo "$expect_redef_line" > expect_redef_line
echo "$expect_retrans_line" > expect_retrans_line
echo "$expect_set_nmp_line" > expect_set_nmp_line
}
if [ "${TESTJAVA}" = "" ]
then
echo "TESTJAVA not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTCLASSES}" = "" ]
then
echo "TESTCLASSES not set. Test cannot execute. Failed."
exit 1
fi
JAR="${TESTJAVA}/bin/jar"
JAVAC="${TESTJAVA}"/bin/javac
JAVA="${TESTJAVA}"/bin/java
# Now that ManifestTestApp.class is built, we move
# ExampleForBootClassPath.class so that it cannot be found
# by default
OUT_OF_THE_WAY=out_of_the_way
mkdir $OUT_OF_THE_WAY
mv "${TESTCLASSES}/ExampleForBootClassPath.class" $OUT_OF_THE_WAY
# create a bad version of ExampleForBootClassPath.class
# so we can tell when the wrong version is run
sed 's/return 15/return 42/' "${TESTSRC}"/ExampleForBootClassPath.java \
> ExampleForBootClassPath.java
"$JAVAC" ExampleForBootClassPath.java
mv ExampleForBootClassPath.class \
$OUT_OF_THE_WAY/ExampleForBootClassPath.class.bad
mv ExampleForBootClassPath.java \
$OUT_OF_THE_WAY/ExampleForBootClassPath.java.bad
AGENT=ManifestTestAgent
# We compile the agent in the working directory instead of with
# a build task because we construct a different agent JAR file
# for each test case.
${JAVAC} -d . ${TESTSRC}/${AGENT}.java
FAIL_MARKER=fail_marker
rm -f $FAIL_MARKER
while read token; do
echo
echo "===== begin test case: $token ====="
make_a_JAR "$token"
"${JAVA}" ${TESTVMOPTS} -javaagent:${AGENT}.jar \
-classpath "${TESTCLASSES}" ManifestTestApp > output.log 2>&1
result=$?
cat output.log
if [ "$result" = 0 ]; then
echo "PASS: ManifestTestApp exited with status of 0."
else
echo "FAIL: ManifestTestApp exited with status of $result"
touch $FAIL_MARKER
fi
MESG="Hello from ${AGENT}!"
grep -s "$MESG" output.log > /dev/null
result=$?
if [ "$result" = 0 ]; then
echo "PASS: found '$MESG' in the test output"
else
echo "FAIL: did NOT find '$MESG' in the test output"
touch $FAIL_MARKER
fi
MESG=`cat expect_boot_cp_line`
grep -s "$MESG" output.log > /dev/null
result=$?
if [ "$result" = 0 ]; then
echo "PASS: found '$MESG' in the test output"
else
echo "FAIL: did NOT find '$MESG' in the test output"
touch $FAIL_MARKER
fi
MESG=`cat expect_redef_line`
grep -s "$MESG" output.log > /dev/null
result=$?
if [ "$result" = 0 ]; then
echo "PASS: found '$MESG' in the test output"
else
echo "FAIL: did NOT find '$MESG' in the test output"
touch $FAIL_MARKER
fi
MESG=`cat expect_retrans_line`
grep -s "$MESG" output.log > /dev/null
result=$?
if [ "$result" = 0 ]; then
echo "PASS: found '$MESG' in the test output"
else
echo "FAIL: did NOT find '$MESG' in the test output"
touch $FAIL_MARKER
fi
MESG=`cat expect_set_nmp_line`
grep -s "$MESG" output.log > /dev/null
result=$?
if [ "$result" = 0 ]; then
echo "PASS: found '$MESG' in the test output"
else
echo "FAIL: did NOT find '$MESG' in the test output"
touch $FAIL_MARKER
fi
echo "===== end test case: $token ====="
echo
done << EOF
defaults
version_line1
version_line2
version_line3
premain_line1
premain_line2
premain_line3
boot_cp_line1
boot_cp_line2
boot_cp_line3
boot_cp_line4
boot_cp_line5
can_redef_line1
can_redef_line2
can_redef_line3
can_redef_line4
can_redef_line5
can_redef_line6
can_redef_line7
can_redef_line8
can_redef_line10
can_redef_line11
can_retrans_line1
can_retrans_line2
can_retrans_line3
can_retrans_line4
can_retrans_line5
can_retrans_line6
can_retrans_line7
can_retrans_line8
can_retrans_line10
can_retrans_line11
can_set_nmp_line1
can_set_nmp_line2
can_set_nmp_line3
can_set_nmp_line4
can_set_nmp_line5
can_set_nmp_line6
can_set_nmp_line7
can_set_nmp_line8
can_set_nmp_line10
can_set_nmp_line11
EOF
if [ -f $FAIL_MARKER ]; then
exit 1
else
exit 0
fi

View File

@ -0,0 +1,41 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.lang.instrument.Instrumentation;
public class ManifestTestAgent {
private static Instrumentation instrumentation;
private ManifestTestAgent() {
}
public static void premain(String agentArgs, Instrumentation inst) {
System.out.println("Hello from ManifestTestAgent!");
System.out.println("isNativeMethodPrefixSupported()=" +
inst.isNativeMethodPrefixSupported());
System.out.println("isRedefineClassesSupported()=" +
inst.isRedefineClassesSupported());
System.out.println("isRetransformClassesSupported()=" +
inst.isRetransformClassesSupported());
}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
public class ManifestTestApp {
public static void main(String args[]) {
System.out.println("Hello from ManifestTestApp!");
new ManifestTestApp().doTest();
System.exit(0);
}
private void doTest() {
try {
// load the class only found via the Boot-Class-Path attribute
Object instance = loadExampleClass();
if (instance.getClass().getClassLoader() == null) {
System.out.println("PASS: ExampleForBootClassPath was loaded" +
" by the boot class path loader.");
} else {
System.out.println("FAIL: ExampleForBootClassPath was loaded" +
" by a non-boot class path loader.");
System.exit(1);
}
} catch (NoClassDefFoundError ncdfe) {
// This message just lets ManifestTest.sh know whether or
// not ExampleForBootClassPath was loaded. Depending on
// the current test case, that will be either a PASSing
// condition or a FAILing condition as determined by
// ManifestTest.sh.
System.out.println("ExampleForBootClassPath was not loaded.");
}
}
Object loadExampleClass() {
ExampleForBootClassPath instance = new ExampleForBootClassPath();
System.out.println("ExampleForBootClassPath was loaded.");
if (instance.fifteen() == 15) {
System.out.println("PASS: the correct" +
" ExampleForBootClassPath was loaded.");
} else {
System.out.println("FAIL: the wrong ExampleForBootClassPath" +
" was loaded.");
System.out.println("FAIL: instance.fifteen()=" +
instance.fifteen());
System.exit(1);
}
return instance;
}
}

View File

@ -27,7 +27,7 @@
* @summary test setNativeMethodPrefix * @summary test setNativeMethodPrefix
* @author Robert Field, Sun Microsystems * @author Robert Field, Sun Microsystems
* *
* @run shell MakeJAR2.sh NativeMethodPrefixAgent NativeMethodPrefixApp 'Can-Retransform-Classes: true' 'Can-Set-Native-Method-Prefix: true' * @run shell/timeout=240 MakeJAR2.sh NativeMethodPrefixAgent NativeMethodPrefixApp 'Can-Retransform-Classes: true' 'Can-Set-Native-Method-Prefix: true'
* @run main/othervm -javaagent:NativeMethodPrefixAgent.jar NativeMethodPrefixApp * @run main/othervm -javaagent:NativeMethodPrefixAgent.jar NativeMethodPrefixApp
*/ */

View File

@ -0,0 +1,72 @@
#
# Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
# @test
# @bug 5088398
# @summary Test parallel class loading by parallel transformers.
# @author Daniel D. Daugherty as modified from the code of Daryl Puryear @ Wily
#
# @run shell MakeJAR3.sh ParallelTransformerLoaderAgent
# @run build ParallelTransformerLoaderApp
# @run shell/timeout=240 ParallelTransformerLoader.sh
#
if [ "${TESTJAVA}" = "" ]
then
echo "TESTJAVA not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTCLASSES}" = "" ]
then
echo "TESTCLASSES not set. Test cannot execute. Failed."
exit 1
fi
JAR="${TESTJAVA}"/bin/jar
JAVAC="${TESTJAVA}"/bin/javac
JAVA="${TESTJAVA}"/bin/java
"${JAVAC}" -d . \
"${TESTSRC}"/TestClass1.java \
"${TESTSRC}"/TestClass2.java \
"${TESTSRC}"/TestClass3.java
"${JAR}" cvf Test.jar Test*.class
# Removing the test class files is important. If these
# .class files are available on the classpath other
# than via Test.jar, then the deadlock will not reproduce.
rm -f Test*.class
"${JAVA}" ${TESTVMOPTS} -javaagent:ParallelTransformerLoaderAgent.jar=Test.jar \
-classpath "${TESTCLASSES}" ParallelTransformerLoaderApp
result=$?
echo "result=$result"
exit $result

View File

@ -0,0 +1,120 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.lang.instrument.*;
import java.net.*;
import java.io.*;
import java.security.*;
/**
* Test Java Agent
*
* @author Daryl Puryear
* @copyright 1999-2004 Wily Technology, Inc. All rights reserved.
*/
public class ParallelTransformerLoaderAgent
{
private static URL sURL;
private static ClassLoader sClassLoader;
public static synchronized ClassLoader
getClassLoader()
{
return sClassLoader;
}
public static synchronized void
generateNewClassLoader()
{
sClassLoader = new URLClassLoader(new URL[] {sURL});
}
public static void
premain( String agentArgs,
Instrumentation instrumentation)
throws Exception
{
if (agentArgs == null || agentArgs == "")
{
System.err.println("Error: No jar file name provided, test will not run.");
return;
}
sURL = (new File(agentArgs)).toURL();
System.out.println("Using jar file: " + sURL);
generateNewClassLoader();
instrumentation.addTransformer(new TestTransformer());
}
private static class TestTransformer
implements ClassFileTransformer
{
public byte[]
transform( ClassLoader loader,
String className,
Class classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer)
throws IllegalClassFormatException
{
String tName = Thread.currentThread().getName();
// In 160_03 and older, transform() is called
// with the "system_loader_lock" held and that
// prevents the bootstrap class loaded from
// running in parallel. If we add a slight sleep
// delay here when the transform() call is not
// main or TestThread, then the deadlock in
// 160_03 and older is much more reproducible.
if (!tName.equals("main") && !tName.equals("TestThread")) {
System.out.println("Thread '" + tName +
"' has called transform()");
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
// load additional classes when called from other threads
if (!tName.equals("main"))
{
loadClasses(3);
}
return null;
}
public static void
loadClasses( int index)
{
ClassLoader loader = ParallelTransformerLoaderAgent.getClassLoader();
try
{
Class.forName("TestClass" + index, true, loader);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}

View File

@ -0,0 +1,90 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* Test Java Program
*
* @author Daryl Puryear
* @copyright 1999-2004 Wily Technology, Inc. All rights reserved.
*/
public class ParallelTransformerLoaderApp
{
private static final int kNumIterations = 1000;
public static void
main( String[] args)
throws Exception
{
System.out.println();
System.out.print("Starting test with " + kNumIterations + " iterations");
for (int i = 0; i < kNumIterations; i++)
{
// load some classes from multiple threads (this thread and one other)
Thread testThread = new TestThread(2);
testThread.start();
loadClasses(1);
// log that it completed and reset for the next iteration
testThread.join();
System.out.print(".");
ParallelTransformerLoaderAgent.generateNewClassLoader();
}
System.out.println();
System.out.println("Test completed successfully");
}
private static class TestThread
extends Thread
{
private final int fIndex;
public
TestThread( int index)
{
super("TestThread");
fIndex = index;
}
public void
run()
{
loadClasses(fIndex);
}
}
public static void
loadClasses( int index)
{
ClassLoader loader = ParallelTransformerLoaderAgent.getClassLoader();
try
{
Class.forName("TestClass" + index, true, loader);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

View File

@ -22,11 +22,10 @@
*/ */
/* /*
* * dummy "Hello World"ish application for "premain" tests
*
* Used by PremainClassTest.sh - dummy "main application" which doesn't do anything
*/ */
public class DummyMain { public class DummyMain {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Hello from DummyMain!");
} }
} }

View File

@ -0,0 +1,54 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6289149
* @summary test config (0,0,0,1): declared 1-arg in agent class
* @author Daniel D. Daugherty, Sun Microsystems
*
* @run shell ../MakeJAR3.sh InheritAgent0001
* @run main/othervm -javaagent:InheritAgent0001.jar DummyMain
*/
import java.lang.instrument.*;
class InheritAgent0001 extends InheritAgent0001Super {
//
// This agent has a single argument premain() method which
// is the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent0001!");
}
// This agent does NOT have a double argument premain() method.
}
class InheritAgent0001Super {
// This agent does NOT have a single argument premain() method.
// This agent does NOT have a double argument premain() method.
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6289149
* @summary test config (0,0,1,0): declared 2-arg in agent class
* @author Daniel D. Daugherty, Sun Microsystems
*
* @run shell ../MakeJAR3.sh InheritAgent0010
* @run main/othervm -javaagent:InheritAgent0010.jar DummyMain
*/
import java.lang.instrument.*;
class InheritAgent0010 extends InheritAgent0010Super {
// This agent does NOT have a single argument premain() method.
//
// This agent has a double argument premain() method which
// is the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent0010!");
}
}
class InheritAgent0010Super {
// This agent does NOT have a single argument premain() method.
// This agent does NOT have a double argument premain() method.
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6289149
* @summary test config (0,0,1,1): declared 2-arg and declared 1-arg in agent class
* @author Daniel D. Daugherty, Sun Microsystems
*
* @run shell ../MakeJAR3.sh InheritAgent0011
* @run main/othervm -javaagent:InheritAgent0011.jar DummyMain
*/
import java.lang.instrument.*;
class InheritAgent0011 extends InheritAgent0011Super {
//
// This agent has a single argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent0011!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
//
// This agent has a double argument premain() method which
// is the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent0011!");
}
}
class InheritAgent0011Super {
// This agent does NOT have a single argument premain() method.
// This agent does NOT have a double argument premain() method.
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6289149
* @summary test config (0,1,0,0): inherited 1-arg in agent class
* @author Daniel D. Daugherty, Sun Microsystems
*
* @run shell ../MakeJAR3.sh InheritAgent0100
* @run main/othervm -javaagent:InheritAgent0100.jar DummyMain
*/
import java.lang.instrument.*;
class InheritAgent0100 extends InheritAgent0100Super {
// This agent does NOT have a single argument premain() method.
// This agent does NOT have a double argument premain() method.
}
class InheritAgent0100Super {
//
// This agent has a single argument premain() method which
// is the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent0100Super!");
}
// This agent does NOT have a double argument premain() method.
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6289149
* @summary test config (0,1,0,1): inherited 1-arg and declared 1-arg in agent class
* @author Daniel D. Daugherty, Sun Microsystems
*
* @run shell ../MakeJAR3.sh InheritAgent0101
* @run main/othervm -javaagent:InheritAgent0101.jar DummyMain
*/
import java.lang.instrument.*;
class InheritAgent0101 extends InheritAgent0101Super {
//
// This agent has a single argument premain() method which
// is the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent0101!");
}
// This agent does NOT have a double argument premain() method.
}
class InheritAgent0101Super {
//
// This agent has a single argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent0101Super!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
// This agent does NOT have a double argument premain() method.
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6289149
* @summary test config (0,1,1,0): inherited 1-arg and declared 2-arg in agent class
* @author Daniel D. Daugherty, Sun Microsystems
*
* @run shell ../MakeJAR3.sh InheritAgent0110
* @run main/othervm -javaagent:InheritAgent0110.jar DummyMain
*/
import java.lang.instrument.*;
class InheritAgent0110 extends InheritAgent0110Super {
// This agent does NOT have a one argument premain() method.
//
// This agent has a double argument premain() method which
// is the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent0110!");
}
}
class InheritAgent0110Super {
//
// This agent has a single argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent0110Super!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
// This agent does NOT have a double argument premain() method.
}

View File

@ -0,0 +1,69 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6289149
* @summary test config (0,1,1,1): inherited 1-arg, declared 2-arg and declared 1-arg in agent class
* @author Daniel D. Daugherty, Sun Microsystems
*
* @run shell ../MakeJAR3.sh InheritAgent0111
* @run main/othervm -javaagent:InheritAgent0111.jar DummyMain
*/
import java.lang.instrument.*;
class InheritAgent0111 extends InheritAgent0111Super {
//
// This agent has a single argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent0111!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
//
// This agent has a double argument premain() method which
// is the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent0111!");
}
}
class InheritAgent0111Super {
//
// This agent has a single argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent0111Super!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
// This agent does NOT have a double argument premain() method.
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6289149
* @summary test config (1,0,0,0): inherited 2-arg in agent class
* @author Daniel D. Daugherty, Sun Microsystems
*
* @run shell ../MakeJAR3.sh InheritAgent1000
* @run main/othervm -javaagent:InheritAgent1000.jar DummyMain
*/
import java.lang.instrument.*;
class InheritAgent1000 extends InheritAgent1000Super {
// This agent does NOT have a single argument premain() method.
// This agent does NOT have a double argument premain() method.
}
class InheritAgent1000Super {
// This agent does NOT have a single argument premain() method.
//
// This agent has a double argument premain() method which
// is the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent1000Super!");
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6289149
* @summary test config (1,0,0,1): inherited 2-arg, and declared 1-arg in agent class
* @author Daniel D. Daugherty, Sun Microsystems
*
* @run shell ../MakeJAR3.sh InheritAgent1001
* @run main/othervm -javaagent:InheritAgent1001.jar DummyMain
*/
import java.lang.instrument.*;
class InheritAgent1001 extends InheritAgent1001Super {
//
// This agent has a single argument premain() method which
// is the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent1001!");
}
// This agent does NOT have a double argument premain() method.
}
class InheritAgent1001Super {
// This agent does NOT have a single argument premain() method.
//
// This agent has a double argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent1001Super!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6289149
* @summary test config (1,0,1,0): inherited 2-arg, and declared 2-arg in agent class
* @author Daniel D. Daugherty, Sun Microsystems
*
* @run shell ../MakeJAR3.sh InheritAgent1010
* @run main/othervm -javaagent:InheritAgent1010.jar DummyMain
*/
import java.lang.instrument.*;
class InheritAgent1010 extends InheritAgent1010Super {
// This agent does NOT have a single argument premain() method.
//
// This agent has a double argument premain() method which
// is the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent1010!");
}
}
class InheritAgent1010Super {
// This agent does NOT have a single argument premain() method.
//
// This agent has a double argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent1010Super!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6289149
* @summary test config (1,0,1,1): inherited 2-arg, declared 2-arg and declared 1-arg in agent class
* @author Daniel D. Daugherty, Sun Microsystems
*
* @run shell ../MakeJAR3.sh InheritAgent1011
* @run main/othervm -javaagent:InheritAgent1011.jar DummyMain
*/
import java.lang.instrument.*;
class InheritAgent1011 extends InheritAgent1011Super {
//
// This agent has a single argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent1011!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
//
// This agent has a double argument premain() method which
// is the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent1011!");
}
}
class InheritAgent1011Super {
// This agent does NOT have a single argument premain() method.
//
// This agent has a double argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent1011Super!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6289149
* @summary test config (1,1,0,0): inherited 2-arg and inherited 1-arg in agent class
* @author Daniel D. Daugherty, Sun Microsystems
*
* @run shell ../MakeJAR3.sh InheritAgent1100
* @run main/othervm -javaagent:InheritAgent1100.jar DummyMain
*/
import java.lang.instrument.*;
class InheritAgent1100 extends InheritAgent1100Super {
// This agent does NOT have a single argument premain() method.
// This agent does NOT have a double argument premain() method.
}
class InheritAgent1100Super {
//
// This agent has a single argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent1100Super!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
//
// This agent has a double argument premain() method which
// is the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent1100Super!");
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6289149
* @summary test config (1,1,0,1): inherited 2-arg, inherited 1-arg, and declared 1-arg in agent class
* @author Daniel D. Daugherty, Sun Microsystems
*
* @run shell ../MakeJAR3.sh InheritAgent1101
* @run main/othervm -javaagent:InheritAgent1101.jar DummyMain
*/
import java.lang.instrument.*;
class InheritAgent1101 extends InheritAgent1101Super {
//
// This agent has a single argument premain() method which
// is the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent1101!");
}
// This agent does NOT have a double argument premain() method.
}
class InheritAgent1101Super {
//
// This agent has a single argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent1101Super!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
//
// This agent has a double argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent1101Super!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6289149
* @summary test config (1,1,1,0): inherited 2-arg, inherited 1-arg, and declared 2-arg in agent class
* @author Daniel D. Daugherty, Sun Microsystems
*
* @run shell ../MakeJAR3.sh InheritAgent1110
* @run main/othervm -javaagent:InheritAgent1110.jar DummyMain
*/
import java.lang.instrument.*;
class InheritAgent1110 extends InheritAgent1110Super {
// This agent does NOT have a single argument premain() method.
//
// This agent has a double argument premain() method which
// is the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent1110!");
}
}
class InheritAgent1110Super {
//
// This agent has a single argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent1110Super!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
//
// This agent has a double argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent1110Super!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6289149
* @summary test config (1,1,1,1): inherited 2-arg, inherited 1-arg, declared 2-arg and declared 1-arg in agent class
* @author Daniel D. Daugherty, Sun Microsystems
*
* @run shell ../MakeJAR3.sh InheritAgent1111
* @run main/othervm -javaagent:InheritAgent1111.jar DummyMain
*/
import java.lang.instrument.*;
class InheritAgent1111 extends InheritAgent1111Super {
//
// This agent has a single argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent1111!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
//
// This agent has a double argument premain() method which
// is the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent1111!");
}
}
class InheritAgent1111Super {
//
// This agent has a single argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs) {
System.out.println("Hello from Single-Arg InheritAgent1111Super!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
//
// This agent has a double argument premain() method which
// is NOT the one that should be called.
//
public static void premain (String agentArgs, Instrumentation instArg) {
System.out.println("Hello from Double-Arg InheritAgent1111Super!");
throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.lang.instrument.*;
class NoPremainAgent {
// This agent is missing the premain() function.
}

View File

@ -0,0 +1,68 @@
#
# Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
# @test
# @bug 6289149
# @summary test when the agent's class is missing the premain() function.
# @author Daniel D. Daugherty, Sun Microsystems
#
# @run build DummyMain
# @run shell ../MakeJAR3.sh NoPremainAgent
# @run shell NoPremainAgent.sh
#
if [ "${TESTJAVA}" = "" ]
then
echo "TESTJAVA not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTCLASSES}" = "" ]
then
echo "TESTCLASSES not set. Test cannot execute. Failed."
exit 1
fi
JAVAC="${TESTJAVA}"/bin/javac
JAVA="${TESTJAVA}"/bin/java
"${JAVA}" ${TESTVMOPTS} -javaagent:NoPremainAgent.jar \
-classpath "${TESTCLASSES}" DummyMain > output.log 2>&1
cat output.log
MESG="java.lang.NoSuchMethodException"
grep "$MESG" output.log
result=$?
if [ "$result" = 0 ]; then
echo "PASS: found '$MESG' in the test output"
else
echo "FAIL: did NOT find '$MESG' in the test output"
fi
exit $result

View File

@ -49,7 +49,7 @@ JAVA="${TESTJAVA}"/bin/java
"$JAVAC" -d "${TESTCLASSES}" "${TESTSRC}"/DummyMain.java "$JAVAC" -d "${TESTCLASSES}" "${TESTSRC}"/DummyMain.java
"${JAVA}" -javaagent:"${TESTSRC}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain "${JAVA}" ${TESTVMOPTS} -javaagent:"${TESTSRC}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain
result=$? result=$?
exit $result exit $result

View File

@ -0,0 +1,32 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.lang.instrument.*;
class ZeroArgPremainAgent {
// This agent has a zero arg premain() function.
public static void premain () {
System.out.println("Hello from ZeroArgInheritAgent!");
}
}

View File

@ -0,0 +1,68 @@
#
# Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
# @test
# @bug 6289149
# @summary test when the agent's class has a zero arg premain() function.
# @author Daniel D. Daugherty, Sun Microsystems
#
# @run build DummyMain
# @run shell ../MakeJAR3.sh ZeroArgPremainAgent
# @run shell ZeroArgPremainAgent.sh
#
if [ "${TESTJAVA}" = "" ]
then
echo "TESTJAVA not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTCLASSES}" = "" ]
then
echo "TESTCLASSES not set. Test cannot execute. Failed."
exit 1
fi
JAVAC="${TESTJAVA}"/bin/javac
JAVA="${TESTJAVA}"/bin/java
"${JAVA}" ${TESTVMOPTS} -javaagent:ZeroArgPremainAgent.jar \
-classpath "${TESTCLASSES}" DummyMain > output.log 2>&1
cat output.log
MESG="java.lang.NoSuchMethodException"
grep "$MESG" output.log
result=$?
if [ "$result" = 0 ]; then
echo "PASS: found '$MESG' in the test output"
else
echo "FAIL: did NOT find '$MESG' in the test output"
fi
exit $result

View File

@ -0,0 +1,81 @@
#
# Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
# @test
# @bug 5003341 4917140 6545149
# @summary Redefine a class with a native method.
# @author Daniel D. Daugherty as modified from the test submitted by clovis@par.univie.ac.at
#
# @run shell MakeJAR3.sh RedefineClassWithNativeMethodAgent 'Can-Redefine-Classes: true'
# @run build RedefineClassWithNativeMethodApp
# @run shell RedefineClassWithNativeMethod.sh
#
if [ "${TESTJAVA}" = "" ]
then
echo "TESTJAVA not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTCLASSES}" = "" ]
then
echo "TESTCLASSES not set. Test cannot execute. Failed."
exit 1
fi
JAVAC="${TESTJAVA}"/bin/javac
JAVA="${TESTJAVA}"/bin/java
"${JAVA}" ${TESTVMOPTS} \
-javaagent:RedefineClassWithNativeMethodAgent.jar=java/lang/Thread.class \
-classpath "${TESTCLASSES}" RedefineClassWithNativeMethodApp \
> output.log 2>&1
result=$?
cat output.log
if [ "$result" = 0 ]; then
echo "PASS: RedefineClassWithNativeMethodApp exited with status of 0."
else
echo "FAIL: RedefineClassWithNativeMethodApp exited with status of $result"
exit "$result"
fi
MESG="Exception"
grep "$MESG" output.log
result=$?
if [ "$result" = 0 ]; then
echo "FAIL: found '$MESG' in the test output"
result=1
else
echo "PASS: did NOT find '$MESG' in the test output"
result=0
fi
exit $result

View File

@ -0,0 +1,70 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.lang.instrument.*;
import java.net.*;
import java.util.*;
import java.io.*;
public class RedefineClassWithNativeMethodAgent {
static Class clz;
// just read the original class and redefine it via a Timer
public static void premain(String agentArgs, final Instrumentation inst) throws Exception {
String s = agentArgs.substring(0, agentArgs.indexOf(".class"));
clz = Class.forName(s.replace('/', '.'));
ClassLoader loader =
RedefineClassWithNativeMethodAgent.class.getClassLoader();
URL classURL = loader.getResource(agentArgs);
if (classURL == null) {
throw new Exception("Cannot find class: " + agentArgs);
}
int redefineLength;
InputStream redefineStream;
System.out.println("Reading test class from " + classURL);
if (classURL.getProtocol().equals("file")) {
File f = new File(classURL.getFile());
redefineStream = new FileInputStream(f);
redefineLength = (int) f.length();
} else {
URLConnection conn = classURL.openConnection();
redefineStream = conn.getInputStream();
redefineLength = conn.getContentLength();
}
final byte[] buffer = new byte[redefineLength];
new BufferedInputStream(redefineStream).read(buffer);
new Timer(true).schedule(new TimerTask() {
public void run() {
try {
System.out.println("Instrumenting");
ClassDefinition cld = new ClassDefinition(clz, buffer);
inst.redefineClasses(new ClassDefinition[] { cld });
}
catch (Exception e) { e.printStackTrace(); }
}
}, 500);
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
public class RedefineClassWithNativeMethodApp {
public static void main(String[] args) throws Exception {
try {
// give the agent a chance to redefine the target class
Thread.sleep(2000);
} catch (InterruptedException ie) {
}
System.out.println("Creating instance of " +
RedefineClassWithNativeMethodAgent.clz);
RedefineClassWithNativeMethodAgent.clz.newInstance();
System.exit(0);
}
}

View File

@ -0,0 +1,82 @@
#
# Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
# @test
# @bug 6667089
# @summary Reflexive invocation of newly added methods broken.
# @author Daniel D. Daugherty
#
# @run shell MakeJAR3.sh RedefineMethodAddInvokeAgent 'Can-Redefine-Classes: true'
# @run build RedefineMethodAddInvokeApp
# @run shell RedefineMethodAddInvoke.sh
#
if [ "${TESTJAVA}" = "" ]
then
echo "TESTJAVA not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTCLASSES}" = "" ]
then
echo "TESTCLASSES not set. Test cannot execute. Failed."
exit 1
fi
JAVAC="${TESTJAVA}"/bin/javac
JAVA="${TESTJAVA}"/bin/java
cp "${TESTSRC}"/RedefineMethodAddInvokeTarget_1.java \
RedefineMethodAddInvokeTarget.java
"${JAVAC}" -d . RedefineMethodAddInvokeTarget.java
mv RedefineMethodAddInvokeTarget.java RedefineMethodAddInvokeTarget_1.java
mv RedefineMethodAddInvokeTarget.class RedefineMethodAddInvokeTarget_1.class
cp "${TESTSRC}"/RedefineMethodAddInvokeTarget_2.java \
RedefineMethodAddInvokeTarget.java
"${JAVAC}" -d . RedefineMethodAddInvokeTarget.java
mv RedefineMethodAddInvokeTarget.java RedefineMethodAddInvokeTarget_2.java
mv RedefineMethodAddInvokeTarget.class RedefineMethodAddInvokeTarget_2.class
"${JAVA}" ${TESTVMOPTS} -javaagent:RedefineMethodAddInvokeAgent.jar \
-classpath "${TESTCLASSES}" RedefineMethodAddInvokeApp > output.log 2>&1
cat output.log
MESG="Exception"
grep "$MESG" output.log
result=$?
if [ "$result" = 0 ]; then
echo "FAIL: found '$MESG' in the test output"
result=1
else
echo "PASS: did NOT find '$MESG' in the test output"
result=0
fi
exit $result

View File

@ -0,0 +1,43 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.lang.instrument.Instrumentation;
public class RedefineMethodAddInvokeAgent {
private static Instrumentation instrumentation;
private RedefineMethodAddInvokeAgent() {
}
public static void premain(String agentArgs, Instrumentation inst) {
System.out.println("Hello from RedefineMethodAddInvokeAgent!");
System.out.println("isRedefineClassesSupported()=" +
inst.isRedefineClassesSupported());
instrumentation = inst;
}
public static Instrumentation getInstrumentation() {
return instrumentation;
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.io.*;
import java.lang.instrument.*;
public class RedefineMethodAddInvokeApp {
public static void main(String args[]) throws Exception {
System.out.println("Hello from RedefineMethodAddInvokeApp!");
new RedefineMethodAddInvokeApp().doTest();
System.exit(0);
}
private void doTest() throws Exception {
RedefineMethodAddInvokeTarget target =
new RedefineMethodAddInvokeTarget();
System.out.println("RedefineMethodAddInvokeApp: invoking myMethod()");
target.test(0); // invoke the original myMethod()
// add myMethod1()
do_redefine(1);
System.out.println("RedefineMethodAddInvokeApp: invoking myMethod1()");
target.test(1); // invoke myMethod1()
// add myMethod2()
do_redefine(2);
System.out.println("RedefineMethodAddInvokeApp: invoking myMethod2()");
target.test(2); // invoke myMethod2()
}
private static void do_redefine(int counter) throws Exception {
File f = new File("RedefineMethodAddInvokeTarget_" + counter +
".class");
System.out.println("Reading test class from " + f);
InputStream redefineStream = new FileInputStream(f);
byte[] redefineBuffer = NamedBuffer.loadBufferFromStream(redefineStream);
ClassDefinition redefineParamBlock = new ClassDefinition(
RedefineMethodAddInvokeTarget.class, redefineBuffer);
RedefineMethodAddInvokeAgent.getInstrumentation().redefineClasses(
new ClassDefinition[] {redefineParamBlock});
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.lang.reflect.Method;
public class RedefineMethodAddInvokeTarget {
public void test(int counter) throws Exception {
Method method = getClass().getDeclaredMethod("myMethod" +
(counter == 0 ? "" : counter));
method.setAccessible(true);
method.invoke(this);
}
public void myMethod() {
System.out.println("Hello from the original myMethod()!");
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.lang.reflect.Method;
public class RedefineMethodAddInvokeTarget {
public void test(int counter) throws Exception {
Method method = getClass().getDeclaredMethod("myMethod" +
(counter == 0 ? "" : counter));
method.setAccessible(true);
method.invoke(this);
}
public void myMethod() {
System.out.println("Hello from the non-EMCP myMethod()!");
}
private final void myMethod1() {
System.out.println("Hello from myMethod1()!");
System.out.println("Calling myMethod() from myMethod1():");
myMethod();
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.lang.reflect.Method;
public class RedefineMethodAddInvokeTarget {
public void test(int counter) throws Exception {
Method method = getClass().getDeclaredMethod("myMethod" +
(counter == 0 ? "" : counter));
method.setAccessible(true);
method.invoke(this);
}
public void myMethod() {
System.out.println("Hello from the non-EMCP again myMethod()!");
}
private final void myMethod1() {
System.out.println("Hello from myMethod1()!");
System.out.println("Calling myMethod() from myMethod1():");
myMethod();
}
private final void myMethod2() {
System.out.println("Hello from myMethod2()!");
System.out.println("Calling myMethod1() from myMethod2():");
myMethod1();
}
}

View File

@ -27,7 +27,7 @@
* @summary test retransformClasses * @summary test retransformClasses
* @author Robert Field, Sun Microsystems * @author Robert Field, Sun Microsystems
* *
* @run shell MakeJAR2.sh RetransformAgent RetransformApp 'Can-Retransform-Classes: true' * @run shell/timeout=240 MakeJAR2.sh RetransformAgent RetransformApp 'Can-Retransform-Classes: true'
* @run main/othervm -javaagent:RetransformAgent.jar RetransformApp * @run main/othervm -javaagent:RetransformAgent.jar RetransformApp
*/ */

View File

@ -0,0 +1,86 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.lang.instrument.Instrumentation;
public class StressGetObjectSizeApp
extends ASimpleInstrumentationTestCase
{
/**
* Constructor for StressGetObjectSizeApp.
* @param name
*/
public StressGetObjectSizeApp(String name)
{
super(name);
}
public static void
main (String[] args)
throws Throwable {
ATestCaseScaffold test = new StressGetObjectSizeApp(args[0]);
test.runTest();
}
protected final void
doRunTest()
throws Throwable {
stressGetObjectSize();
}
public void stressGetObjectSize() {
System.out.println("main: an object size=" +
fInst.getObjectSize(new Object()));
RoundAndRound[] threads = new RoundAndRound[10];
for (int i = 0; i < threads.length; ++i) {
threads[i] = new RoundAndRound(fInst);
threads[i].start();
}
try {
Thread.sleep(500); // let all threads get going in their loops
} catch (InterruptedException ie) {
}
System.out.println("stressGetObjectSize: returning");
return;
}
private static class RoundAndRound extends Thread {
private final Instrumentation inst;
private final Object anObject;
public RoundAndRound(Instrumentation inst) {
this.inst = inst;
this.anObject = new Object();
setDaemon(true);
}
public void run() {
long sum = 0;
while (true) {
sum += inst.getObjectSize(anObject);
}
}
}
}

View File

@ -0,0 +1,70 @@
#
# Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
# @test
# @bug 6572160
# @summary stress getObjectSize() API
# @author Daniel D. Daugherty as modified from the code of fischman@google.com
#
# @run build StressGetObjectSizeApp
# @run shell MakeJAR.sh basicAgent
# @run shell StressGetObjectSizeTest.sh
#
if [ "${TESTJAVA}" = "" ]
then
echo "TESTJAVA not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTCLASSES}" = "" ]
then
echo "TESTCLASSES not set. Test cannot execute. Failed."
exit 1
fi
JAVA="${TESTJAVA}"/bin/java
"${JAVA}" ${TESTVMOPTS} -javaagent:basicAgent.jar \
-classpath "${TESTCLASSES}" StressGetObjectSizeApp StressGetObjectSizeApp \
> output.log 2>&1
cat output.log
MESG="ASSERTION FAILED"
grep "$MESG" output.log
result=$?
if [ "$result" = 0 ]; then
echo "FAIL: found '$MESG' in the test output"
result=1
else
echo "PASS: did NOT find '$MESG' in the test output"
result=0
fi
exit $result

View File

@ -0,0 +1,36 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* Test Java Program
*
* @author Daryl Puryear
* @copyright 1999-2004 Wily Technology, Inc. All rights reserved.
*/
public class TestClass1
{
public
TestClass1()
{
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* Test Java Program
*
* @author Daryl Puryear
* @copyright 1999-2004 Wily Technology, Inc. All rights reserved.
*/
public class TestClass2
{
public
TestClass2()
{
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* Test Java Program
*
* @author Daryl Puryear
* @copyright 1999-2004 Wily Technology, Inc. All rights reserved.
*/
public class TestClass3
{
public
TestClass3()
{
}
}

View File

@ -79,6 +79,12 @@ public class TransformerManagementThreadAddTests extends ATestCaseScaffold
protected static final int TOTAL_THREADS = MAX_TRANS - MIN_TRANS + 1; protected static final int TOTAL_THREADS = MAX_TRANS - MIN_TRANS + 1;
private byte[] fDummyClassBytes; private byte[] fDummyClassBytes;
// fCheckedTransformers is a Vector that is used to verify
// that the transform() function is called in the same
// order in which the transformers were added to the
// TransformerManager. The test currently verifies that all
// transformers for a specific worker thread are in
// increasing order by index value.
private Vector fCheckedTransformers; private Vector fCheckedTransformers;
private Instrumentation fInstrumentation; private Instrumentation fInstrumentation;
private int fFinished; private int fFinished;
@ -131,9 +137,16 @@ public class TransformerManagementThreadAddTests extends ATestCaseScaffold
threads[i].start(); threads[i].start();
} }
while (!exec.fDone) // Effective Java - Item 48: Synchronize access to shared mutable data
// Don't use a direct field getter.
while (!exec.isDone())
{ {
Thread.currentThread().yield(); // Effective Java - Item 51: Don't depend on the thread scheduler
// Use sleep() instead of yield().
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
} }
assertTrue(finalCheck()); assertTrue(finalCheck());
@ -169,13 +182,17 @@ public class TransformerManagementThreadAddTests extends ATestCaseScaffold
this.fExec = exec; this.fExec = exec;
} }
// Effective Java - Item 48: Synchronize access to shared mutable data
// Document a synchronized setter.
protected synchronized void protected synchronized void
threadFinished(Thread t) threadFinished(Thread t)
{ {
fFinished++; fFinished++;
} }
protected boolean // Effective Java - Item 48: Synchronize access to shared mutable data
// Provide synchronized getter.
protected synchronized boolean
threadsDone() threadsDone()
{ {
return fFinished == TOTAL_THREADS; return fFinished == TOTAL_THREADS;
@ -188,7 +205,9 @@ public class TransformerManagementThreadAddTests extends ATestCaseScaffold
protected boolean protected boolean
testCompleted() testCompleted()
{ {
return getExecThread().fDone; // Effective Java - Item 48: Synchronize access to shared mutable data
// Don't use direct field getter.
return getExecThread().isDone();
} }
/** /**
@ -264,11 +283,19 @@ public class TransformerManagementThreadAddTests extends ATestCaseScaffold
private void private void
executeTransform() executeTransform()
{ {
fCheckedTransformers.clear();
try try
{ {
ClassDefinition cd = new ClassDefinition(DummyClass.class, fDummyClassBytes); ClassDefinition cd = new ClassDefinition(DummyClass.class, fDummyClassBytes);
// When the ClassDefinition above is created for the first
// time and every time redefineClasses() below is called,
// the transform() function is called for each registered
// transformer. We only want one complete set of calls to
// be logged in the fCheckedTransformers Vector so we clear
// any calls logged for ClassDefinition above and just use
// the ones logged for redefineClasses() below.
fCheckedTransformers.clear();
getInstrumentation().redefineClasses(new ClassDefinition[]{ cd }); getInstrumentation().redefineClasses(new ClassDefinition[]{ cd });
} }
catch (ClassNotFoundException e) catch (ClassNotFoundException e)
@ -325,6 +352,18 @@ public class TransformerManagementThreadAddTests extends ATestCaseScaffold
{ {
private boolean fDone = false; private boolean fDone = false;
// Effective Java - Item 48: Synchronize access to shared mutable data
// Provide a synchronized getter.
private synchronized boolean isDone() {
return fDone;
}
// Effective Java - Item 48: Synchronize access to shared mutable data
// Provide a synchronized setter.
private synchronized void setIsDone() {
fDone = true;
}
public void public void
run() run()
{ {
@ -335,7 +374,9 @@ public class TransformerManagementThreadAddTests extends ATestCaseScaffold
// Do a final check for good measure // Do a final check for good measure
executeTransform(); executeTransform();
fDone = true; // Effective Java - Item 48: Synchronize access to shared mutable data
// Don't use direct field setter.
setIsDone();
} }
} }

View File

@ -27,10 +27,9 @@
* @summary multi-thread test to exercise sync and contention for removes to transformer registry * @summary multi-thread test to exercise sync and contention for removes to transformer registry
* @author Gabriel Adauto, Wily Technology * @author Gabriel Adauto, Wily Technology
* *
* @ignore Disabled until race condition which hangs test can be fixed.
* @run build TransformerManagementThreadRemoveTests * @run build TransformerManagementThreadRemoveTests
* @run shell MakeJAR.sh basicAgent * @run shell MakeJAR.sh redefineAgent
* @run main/othervm -javaagent:basicAgent.jar TransformerManagementThreadRemoveTests TransformerManagementThreadRemoveTests * @run main/othervm -javaagent:redefineAgent.jar TransformerManagementThreadRemoveTests TransformerManagementThreadRemoveTests
*/ */
import java.util.*; import java.util.*;
@ -87,7 +86,12 @@ public class TransformerManagementThreadRemoveTests
while (!testCompleted()) while (!testCompleted())
{ {
Thread.currentThread().yield(); // Effective Java - Item 51: Don't depend on the thread scheduler
// Use sleep() instead of yield().
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
} }
assertTrue(finalCheck()); assertTrue(finalCheck());

View File

@ -26,14 +26,14 @@
# @summary Unit tests for appendToBootstrapClassLoaderSearch and # @summary Unit tests for appendToBootstrapClassLoaderSearch and
# appendToSystemClasLoaderSearch methods. # appendToSystemClasLoaderSearch methods.
# #
# @run shell CircularityErrorTest.sh # @run shell/timeout=240 CircularityErrorTest.sh
if [ "${TESTSRC}" = "" ] if [ "${TESTSRC}" = "" ]
then then
echo "TESTSRC not set. Test cannot execute. Failed." echo "TESTSRC not set. Test cannot execute. Failed."
exit 1 exit 1
fi fi
. ${TESTSRC}/CommonSetup.sh . ${TESTSRC}/CommonSetup.sh
# Setup to create circularity condition # Setup to create circularity condition
@ -71,5 +71,5 @@ $JAR -cfm "${TESTCLASSES}"/CircularityErrorTest.jar "${MANIFEST}" \
-C "${TESTCLASSES}" CircularityErrorTest.class -C "${TESTCLASSES}" CircularityErrorTest.class
# Finally we run the test # Finally we run the test
(cd "${TESTCLASSES}"; (cd "${TESTCLASSES}";
$JAVA -javaagent:CircularityErrorTest.jar CircularityErrorTest) $JAVA ${TESTVMOPTS} -javaagent:CircularityErrorTest.jar CircularityErrorTest)

View File

@ -34,11 +34,11 @@ then
echo "TESTSRC not set. Test cannot execute. Failed." echo "TESTSRC not set. Test cannot execute. Failed."
exit 1 exit 1
fi fi
. ${TESTSRC}/CommonSetup.sh . ${TESTSRC}/CommonSetup.sh
# Create Foo and Bar # Create Foo and Bar
# Foo has a reference to Bar but we deleted Bar so that # Foo has a reference to Bar but we deleted Bar so that
# a NoClassDefFoundError will be thrown when Foo tries to # a NoClassDefFoundError will be thrown when Foo tries to
# resolve the reference to Bar # resolve the reference to Bar
@ -53,11 +53,11 @@ cat << EOF > "${FOO}"
public class Foo { public class Foo {
public static boolean doSomething() { public static boolean doSomething() {
try { try {
Bar b = new Bar(); Bar b = new Bar();
return true; return true;
} catch (NoClassDefFoundError x) { } catch (NoClassDefFoundError x) {
return false; return false;
} }
} }
} }
EOF EOF
@ -79,5 +79,5 @@ $JAR -cfm "${TESTCLASSES}"/ClassUnloadTest.jar "${MANIFEST}" \
# Finally we run the test # Finally we run the test
(cd "${TESTCLASSES}"; \ (cd "${TESTCLASSES}"; \
$JAVA -Xverify:none -XX:+TraceClassUnloading -javaagent:ClassUnloadTest.jar \ $JAVA ${TESTVMOPTS} -Xverify:none -XX:+TraceClassUnloading \
ClassUnloadTest "${OTHERDIR}" Bar.jar) -javaagent:ClassUnloadTest.jar ClassUnloadTest "${OTHERDIR}" Bar.jar)

View File

@ -24,7 +24,6 @@
# #
#%E
# #
# Common setup for unit tests. Setups up the following variables: # Common setup for unit tests. Setups up the following variables:
# #
@ -66,7 +65,7 @@ then
echo "TESTSRC not set. Test cannot execute. Failed." echo "TESTSRC not set. Test cannot execute. Failed."
exit 1 exit 1
fi fi
if [ "${TESTCLASSES}" = "" ] if [ "${TESTCLASSES}" = "" ]
then then
echo "TESTCLASSES not set. Test cannot execute. Failed." echo "TESTCLASSES not set. Test cannot execute. Failed."

View File

@ -23,24 +23,24 @@
# have any questions. # have any questions.
# #
# @test # @test
# @bug 6173575 6388987 # @bug 6173575 6388987
# @summary Unit tests for appendToBootstrapClassLoaderSearch and # @summary Unit tests for appendToBootstrapClassLoaderSearch and
# appendToSystemClasLoaderSearch methods. # appendToSystemClasLoaderSearch methods.
# #
# @build Agent AgentSupport BootSupport BasicTest PrematureLoadTest DynamicTest # @build Agent AgentSupport BootSupport BasicTest PrematureLoadTest DynamicTest
# @run shell run_tests.sh # @run shell/timeout=240 run_tests.sh
if [ "${TESTSRC}" = "" ] if [ "${TESTSRC}" = "" ]
then then
echo "TESTSRC not set. Test cannot execute. Failed." echo "TESTSRC not set. Test cannot execute. Failed."
exit 1 exit 1
fi fi
. ${TESTSRC}/CommonSetup.sh . ${TESTSRC}/CommonSetup.sh
# Simple tests # Simple tests
echo "Creating jar files for simple tests..." echo "Creating jar files for simple tests..."
@ -50,13 +50,13 @@ cd ${TESTCLASSES}
"$JAR" -cfm Agent.jar "${TESTSRC}"/manifest.mf Agent.class "$JAR" -cfm Agent.jar "${TESTSRC}"/manifest.mf Agent.class
"$JAR" -cf AgentSupport.jar AgentSupport.class "$JAR" -cf AgentSupport.jar AgentSupport.class
"$JAR" -cf BootSupport.jar BootSupport.class "$JAR" -cf BootSupport.jar BootSupport.class
"$JAR" -cf SimpleTests.jar BasicTest.class PrematureLoadTest.class "$JAR" -cf SimpleTests.jar BasicTest.class PrematureLoadTest.class
failures=0 failures=0
go() { go() {
echo '' echo ''
sh -xc "$JAVA -javaagent:Agent.jar -classpath SimpleTests.jar $1 $2 $3" 2>&1 sh -xc "$JAVA ${TESTVMOPTS} -javaagent:Agent.jar -classpath SimpleTests.jar $1 $2 $3" 2>&1
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
} }
@ -75,7 +75,7 @@ mkdir tmp
"${JAVAC}" -d tmp "${TESTSRC}"/Tracer.java "${JAVAC}" -d tmp "${TESTSRC}"/Tracer.java
(cd tmp; "${JAR}" cf ../Tracer.jar org/tools/Tracer.class) (cd tmp; "${JAR}" cf ../Tracer.jar org/tools/Tracer.class)
# InstrumentedApplication is Application+instrmentation - don't copy as # InstrumentedApplication is Application+instrmentation - don't copy as
# we don't want the original file permission # we don't want the original file permission
cat "${TESTSRC}"/InstrumentedApplication.java > ./Application.java cat "${TESTSRC}"/InstrumentedApplication.java > ./Application.java
@ -85,11 +85,11 @@ mv Application.class InstrumentedApplication.bytes
cp "${TESTSRC}"/Application.java . cp "${TESTSRC}"/Application.java .
"${JAVAC}" -d . Application.java "${JAVAC}" -d . Application.java
sh -xc "$JAVA -classpath . -javaagent:Agent.jar DynamicTest" 2>&1 sh -xc "$JAVA ${TESTVMOPTS} -classpath . -javaagent:Agent.jar DynamicTest" 2>&1
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
# Repeat test with security manager # Repeat test with security manager
sh -xc "$JAVA -classpath . -javaagent:Agent.jar -Djava.security.manager DynamicTest" 2>&1 sh -xc "$JAVA ${TESTVMOPTS} -classpath . -javaagent:Agent.jar -Djava.security.manager DynamicTest" 2>&1
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
# #

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -46,9 +46,7 @@ public class TestGetInstance {
Cipher c; Cipher c;
c = Cipher.getInstance("des"); c = Cipher.getInstance("PBEWithMD5AndTripleDES");
same(p, c.getProvider());
c = Cipher.getInstance("des/cbc/pkcs5padding");
same(p, c.getProvider()); same(p, c.getProvider());
c = Cipher.getInstance("des", "SunJCE"); c = Cipher.getInstance("des", "SunJCE");

View File

@ -0,0 +1,81 @@
/*
* @test
* @bug 6471865 6675768
* @summary DescriptorSupport constructors throw IAE when traces are enabled;
* RequiredModelMBean.addAttributeChangeNotificationListener throws exception
* when traces enabled and no attributes.
* @author Luis-Miguel Alventosa
* @author Paul Cheeseman
*/
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.modelmbean.DescriptorSupport;
import javax.management.modelmbean.RequiredModelMBean;
public class LoggingExceptionTest {
private static final String tests[] = new String[] {
"DescriptorSupport()",
"DescriptorSupport(int)",
"DescriptorSupport(String)",
"DescriptorSupport(String...)",
"DescriptorSupport(String[], Object[])",
"DescriptorSupport(DescriptorSupport)",
"RequiredModelMBean.addAttributeChangeNotificationListener",
};
public static void main(String[] args) {
Handler handler = new ConsoleHandler();
Logger logger = Logger.getLogger("javax.management.modelmbean");
logger.addHandler(handler);
logger.setLevel(Level.FINEST);
try {
for (int i = 0; i < tests.length; i++) {
System.out.println(">>> DescriptorSupportLoggingTest: Test Case " + i);
DescriptorSupport ds;
String msg = "Instantiate " + tests[i];
System.out.println(msg);
switch (i) {
case 0:
ds = new DescriptorSupport();
break;
case 1:
ds = new DescriptorSupport(10);
break;
case 2:
ds = new DescriptorSupport(new DescriptorSupport().toXMLString());
break;
case 3:
ds = new DescriptorSupport("name1=value1", "name2=value2");
break;
case 4:
ds = new DescriptorSupport(new String[] {"name"}, new Object[] {"value"});
break;
case 5:
ds = new DescriptorSupport(new DescriptorSupport());
break;
case 6:
RequiredModelMBean mbean = new RequiredModelMBean();
NotificationListener nl = new NotificationListener() {
public void handleNotification(Notification notification,
Object handback) {}
};
mbean.addAttributeChangeNotificationListener(nl, null, null);
break;
default:
throw new AssertionError();
}
System.out.println(msg + " OK");
}
} catch (Exception e) {
System.out.println("Got unexpected exception = " + e);
String msg = "Test FAILED!";
System.out.println(msg);
throw new IllegalArgumentException(msg);
}
System.out.println("Test PASSED!");
}
}

View File

@ -0,0 +1,347 @@
/*
* Copyright 2007 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test QueryNotifFilterTest
* @bug 6610917
* @summary Test the QueryNotificationFilter class
* @author Eamonn McManus
*/
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.management.Attribute;
import javax.management.AttributeChangeNotification;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.Query;
import javax.management.QueryEval;
import javax.management.QueryExp;
import javax.management.QueryNotificationFilter;
public class QueryNotifFilterTest {
private static class Case {
final Notification notif;
final QueryExp query;
final boolean expect;
final Class<? extends Notification> notifClass;
Case(Notification notif, String query, boolean expect) {
this(notif, query, notif.getClass(), expect);
}
Case(Notification notif, String query,
Class<? extends Notification> notifClass, boolean expect) {
this(notif, Query.fromString(query), notifClass, expect);
}
Case(Notification notif, QueryExp query, boolean expect) {
this(notif, query, notif.getClass(), expect);
}
Case(Notification notif, QueryExp query,
Class<? extends Notification> notifClass, boolean expect) {
this.notif = notif;
this.query = query;
this.expect = expect;
this.notifClass = notifClass;
}
}
/* In principle users can create their own implementations of QueryExp
* and use them with QueryNotificationFilter. If they do so, then
* they can call any MBeanServer method. Not all of those methods
* will work with the special MBeanServer we concoct to analyze a
* Notification, but some will, including some that are not called
* by the standard queries. So we check each of those cases too.
*/
private static class ExoticCase {
final Notification trueNotif;
final Notification falseNotif;
final QueryExp query;
ExoticCase(Notification trueNotif, Notification falseNotif, QueryExp query) {
this.trueNotif = trueNotif;
this.falseNotif = falseNotif;
this.query = query;
}
}
private static abstract class ExoticQuery
extends QueryEval implements QueryExp {
private final String queryString;
ExoticQuery(String queryString) {
this.queryString = queryString;
}
abstract boolean apply(MBeanServer mbs, ObjectName name) throws Exception;
@Override
public boolean apply(ObjectName name) {
try {
return apply(getMBeanServer(), name);
} catch (Exception e) {
e.printStackTrace(System.out);
return false;
}
}
@Override
public String toString() {
return queryString;
}
}
private static ObjectName makeObjectName(String s) {
try {
return new ObjectName(s);
} catch (MalformedObjectNameException e) {
throw new RuntimeException(e);
}
}
public static class CustomNotification extends Notification {
public CustomNotification(String type, Object source, long seqNo) {
super(type, source, seqNo);
}
public String getName() {
return "claude";
}
public boolean isInteresting() {
return true;
}
}
private static final Notification simpleNotif =
new Notification("mytype", "source", 0L);
private static final Notification attrChangeNotif =
new AttributeChangeNotification(
"x", 0L, 0L, "msg", "AttrName", "int", 2, 3);
private static final ObjectName testObjectName = makeObjectName("a:b=c");
private static final Notification sourcedNotif =
new Notification("mytype", testObjectName, 0L);
private static final Notification customNotif =
new CustomNotification("mytype", testObjectName, 0L);
private static final Case[] testCases = {
new Case(simpleNotif, "Type = 'mytype'", true),
new Case(simpleNotif, "Type = 'mytype'",
Notification.class, true),
new Case(simpleNotif, "Type = 'mytype'",
AttributeChangeNotification.class, false),
new Case(simpleNotif, "Type != 'mytype'", false),
new Case(simpleNotif, "Type = 'somethingelse'", false),
new Case(attrChangeNotif, "AttributeName = 'AttrName'", true),
new Case(attrChangeNotif,
"instanceof 'javax.management.AttributeChangeNotification'",
true),
new Case(attrChangeNotif,
"instanceof 'javax.management.Notification'",
true),
new Case(attrChangeNotif,
"instanceof 'javax.management.relation.MBeanServerNotification'",
false),
new Case(attrChangeNotif,
"class = 'javax.management.AttributeChangeNotification'",
true),
new Case(attrChangeNotif,
"javax.management.AttributeChangeNotification#AttributeName = 'AttrName'",
true),
new Case(sourcedNotif,
testObjectName,
true),
new Case(sourcedNotif,
makeObjectName("a*:b=*"),
true),
new Case(sourcedNotif,
makeObjectName("a*:c=*"),
false),
new Case(customNotif, "Name = 'claude'", true),
new Case(customNotif, "Name = 'tiddly'", false),
new Case(customNotif, "Interesting = true", true),
new Case(customNotif, "Interesting = false", false),
};
private static final ExoticCase[] exoticTestCases = {
new ExoticCase(
simpleNotif, new Notification("notmytype", "source", 0L),
new ExoticQuery("getAttributes") {
boolean apply(MBeanServer mbs, ObjectName name)
throws Exception {
List<Attribute> attrs = mbs.getAttributes(
name, new String[] {"Type", "Source"}).asList();
return (attrs.get(0).equals(new Attribute("Type", "mytype")) &&
attrs.get(1).equals(new Attribute("Source", "source")));
}
}),
new ExoticCase(
new Notification("mytype", "source", 0L) {},
simpleNotif,
new ExoticQuery("getClassLoaderFor") {
boolean apply(MBeanServer mbs, ObjectName name)
throws Exception {
return (mbs.getClassLoaderFor(name) ==
this.getClass().getClassLoader());
}
}),
new ExoticCase(
sourcedNotif, simpleNotif,
new ExoticQuery("getDomains") {
boolean apply(MBeanServer mbs, ObjectName name)
throws Exception {
return Arrays.equals(mbs.getDomains(),
new String[] {testObjectName.getDomain()});
}
}),
new ExoticCase(
simpleNotif, attrChangeNotif,
new ExoticQuery("getMBeanInfo") {
boolean apply(MBeanServer mbs, ObjectName name)
throws Exception {
MBeanInfo mbi = mbs.getMBeanInfo(name);
// If we ever add a constructor to Notification then
// we will have to change the 4 below.
if (mbi.getOperations().length > 0 ||
mbi.getConstructors().length != 4 ||
mbi.getNotifications().length > 0)
return false;
Set<String> expect = new HashSet<String>(
Arrays.asList(
"Class", "Message", "SequenceNumber", "Source",
"TimeStamp", "Type", "UserData"));
Set<String> actual = new HashSet<String>();
for (MBeanAttributeInfo mbai : mbi.getAttributes())
actual.add(mbai.getName());
return actual.equals(expect);
}
}),
new ExoticCase(
simpleNotif, attrChangeNotif,
new ExoticQuery("getObjectInstance") {
boolean apply(MBeanServer mbs, ObjectName name)
throws Exception {
ObjectInstance oi = mbs.getObjectInstance(name);
return oi.getClassName().equals(Notification.class.getName());
}
}),
new ExoticCase(
sourcedNotif, simpleNotif,
new ExoticQuery("queryNames") {
boolean apply(MBeanServer mbs, ObjectName name)
throws Exception {
Set<ObjectName> names = mbs.queryNames(null,
Query.eq(Query.attr("Type"), Query.value("mytype")));
return names.equals(Collections.singleton(testObjectName));
}
}),
new ExoticCase(
sourcedNotif, simpleNotif,
new ExoticQuery("queryMBeans") {
boolean apply(MBeanServer mbs, ObjectName name)
throws Exception {
Set<ObjectInstance> insts = mbs.queryMBeans(null,
Query.eq(Query.attr("Type"), Query.value("mytype")));
if (insts.size() != 1)
return false;
ObjectInstance inst = insts.iterator().next();
return (inst.getObjectName().equals(testObjectName) &&
inst.getClassName().equals(Notification.class.getName()));
}
}),
};
private static enum Test {
QUERY_EXP("query"), STRING("string"), STRING_PLUS_CLASS("string with class");
private final String name;
Test(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public static void main(String[] args) throws Exception {
boolean allok = true;
for (Case testCase : testCases) {
for (Test test : Test.values()) {
QueryNotificationFilter nf;
String queryString;
switch (test) {
case QUERY_EXP: {
QueryExp inst = Query.isInstanceOf(
Query.value(testCase.notifClass.getName()));
QueryExp and = Query.and(inst, testCase.query);
queryString = Query.toString(and);
nf = new QueryNotificationFilter(and);
break;
}
case STRING: {
String s = "instanceof '" + testCase.notifClass.getName() + "'";
queryString = s + " and " + Query.toString(testCase.query);
nf = new QueryNotificationFilter(queryString);
break;
}
case STRING_PLUS_CLASS:
queryString = null;
nf = new QueryNotificationFilter(
testCase.notifClass, Query.toString(testCase.query));
break;
default:
throw new AssertionError();
}
boolean accept = nf.isNotificationEnabled(testCase.notif);
if (queryString != null) {
queryString = Query.toString(Query.fromString(queryString));
if (!queryString.equals(Query.toString(nf.getQuery()))) {
System.out.println("FAIL: query string mismatch: expected " +
"\"" + queryString + "\", got \"" +
Query.toString(nf.getQuery()));
allok = false;
}
}
boolean ok = (accept == testCase.expect);
System.out.println((ok ? "pass" : "FAIL") + ": " +
testCase.query + " (" + test + ")");
allok &= ok;
}
}
for (ExoticCase testCase : exoticTestCases) {
NotificationFilter nf = new QueryNotificationFilter(testCase.query);
for (boolean expect : new boolean[] {true, false}) {
Notification n = expect ? testCase.trueNotif : testCase.falseNotif;
boolean accept = nf.isNotificationEnabled(n);
boolean ok = (accept == expect);
System.out.println((ok ? "pass" : "FAIL") + ": " +
testCase.query + ": " + n);
allok &= ok;
}
}
if (!allok)
throw new Exception("TEST FAILED");
}
}

View File

@ -0,0 +1,109 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6572331
* @summary basic test for RSA cipher key wrapping functionality
* @author Valerie Peng
* @library ..
*/
import java.io.*;
import java.util.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
public class TestRSACipherWrap extends PKCS11Test {
private static final String RSA_ALGO = "RSA/ECB/PKCS1Padding";
public void main(Provider p) throws Exception {
try {
Cipher.getInstance(RSA_ALGO, p);
} catch (GeneralSecurityException e) {
System.out.println("Not supported by provider, skipping");
return;
}
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", p);
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
PublicKey publicKey = kp.getPublic();
PrivateKey privateKey = kp.getPrivate();
Cipher cipherPKCS11 = Cipher.getInstance(RSA_ALGO, p);
Cipher cipherJce = Cipher.getInstance(RSA_ALGO, "SunJCE");
String algos[] = {"AES", "RC2", "Blowfish"};
int keySizes[] = {128, 256};
for (int j = 0; j < algos.length; j++) {
String algorithm = algos[j];
KeyGenerator keygen =
KeyGenerator.getInstance(algorithm);
for (int i = 0; i < keySizes.length; i++) {
SecretKey secretKey = null;
System.out.print("Generate " + keySizes[i] + "-bit " +
algorithm + " key using ");
try {
keygen.init(keySizes[i]);
secretKey = keygen.generateKey();
System.out.println(keygen.getProvider().getName());
} catch (InvalidParameterException ipe) {
secretKey = new SecretKeySpec(new byte[32], algorithm);
System.out.println("SecretKeySpec class");
}
test(kp, secretKey, cipherPKCS11, cipherJce);
test(kp, secretKey, cipherPKCS11, cipherPKCS11);
test(kp, secretKey, cipherJce, cipherPKCS11);
}
}
}
private static void test(KeyPair kp, SecretKey secretKey,
Cipher wrapCipher, Cipher unwrapCipher)
throws Exception {
String algo = secretKey.getAlgorithm();
wrapCipher.init(Cipher.WRAP_MODE, kp.getPublic());
byte[] wrappedKey = wrapCipher.wrap(secretKey);
unwrapCipher.init(Cipher.UNWRAP_MODE, kp.getPrivate());
Key unwrappedKey =
unwrapCipher.unwrap(wrappedKey, algo, Cipher.SECRET_KEY);
System.out.println("Test " + wrapCipher.getProvider().getName() +
"/" + unwrapCipher.getProvider().getName() + ": ");
if (!Arrays.equals(secretKey.getEncoded(),
unwrappedKey.getEncoded())) {
throw new Exception("Test Failed!");
}
System.out.println("Passed");
}
public static void main(String[] args) throws Exception {
main(new TestRSACipherWrap());
}
}

View File

@ -0,0 +1,282 @@
/*
* Copyright 2008 Sun Microsystems, 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 modi
fy it
* under the terms of the GNU General Public License version 2 onl
y, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, bu
t WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABIL
ITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public L
icense
* version 2 for more details (a copy is included in the LICENSE f
ile that
* accompanied this code).
*
* You should have received a copy of the GNU General Public Licen
se version
* 2 along with this work; if not, write to the Free Software Foun
dation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, San
ta Clara,
* CA 95054 USA or visit www.sun.com if you need additional inform
ation or
* have any questions.
*/
/**
* @test %I% %E%
* @bug 4898461
* @summary basic test for symmetric ciphers with padding
* @author Valerie Peng
* @library ..
*/
import java.io.*;
import java.nio.*;
import java.util.*;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
public class TestSymmCiphers extends PKCS11Test {
private static class CI { // class for holding Cipher Information
String transformation;
String keyAlgo;
int dataSize;
CI(String transformation, String keyAlgo, int dataSize) {
this.transformation = transformation;
this.keyAlgo = keyAlgo;
this.dataSize = dataSize;
}
}
private static final CI[] TEST_LIST = {
new CI("ARCFOUR", "ARCFOUR", 400),
new CI("RC4", "RC4", 401),
new CI("DES/CBC/NoPadding", "DES", 400),
new CI("DESede/CBC/NoPadding", "DESede", 160),
new CI("AES/CBC/NoPadding", "AES", 4800),
new CI("Blowfish/CBC/NoPadding", "Blowfish", 24),
new CI("DES/cbc/PKCS5Padding", "DES", 6401),
new CI("DESede/CBC/PKCS5Padding", "DESede", 402),
new CI("AES/CBC/PKCS5Padding", "AES", 30),
new CI("Blowfish/CBC/PKCS5Padding", "Blowfish", 19),
new CI("DES/ECB/NoPadding", "DES", 400),
new CI("DESede/ECB/NoPadding", "DESede", 160),
new CI("AES/ECB/NoPadding", "AES", 4800),
new CI("DES/ECB/PKCS5Padding", "DES", 32),
new CI("DES/ECB/PKCS5Padding", "DES", 6400),
new CI("DESede/ECB/PKCS5Padding", "DESede", 400),
new CI("AES/ECB/PKCS5Padding", "AES", 64),
new CI("DES", "DES", 6400),
new CI("DESede", "DESede", 408),
new CI("AES", "AES", 128)
};
private static StringBuffer debugBuf = new StringBuffer();
public void main(Provider p) throws Exception {
// NSS reports CKR_DEVICE_ERROR when the data passed to
// its EncryptUpdate/DecryptUpdate is not multiple of blocks
int firstBlkSize = 16;
boolean status = true;
Random random = new Random();
try {
for (int i = 0; i < TEST_LIST.length; i++) {
CI currTest = TEST_LIST[i];
System.out.println("===" + currTest.transformation + "===");
try {
KeyGenerator kg =
KeyGenerator.getInstance(currTest.keyAlgo, p);
SecretKey key = kg.generateKey();
Cipher c1 = Cipher.getInstance(currTest.transformation, p);
Cipher c2 = Cipher.getInstance(currTest.transformation,
"SunJCE");
byte[] plainTxt = new byte[currTest.dataSize];
random.nextBytes(plainTxt);
System.out.println("Testing inLen = " + plainTxt.length);
c2.init(Cipher.ENCRYPT_MODE, key);
AlgorithmParameters params = c2.getParameters();
byte[] answer = c2.doFinal(plainTxt);
System.out.println("Encryption tests: START");
test(c1, Cipher.ENCRYPT_MODE, key, params, firstBlkSize,
plainTxt, answer);
System.out.println("Encryption tests: DONE");
c2.init(Cipher.DECRYPT_MODE, key, params);
byte[] answer2 = c2.doFinal(answer);
System.out.println("Decryption tests: START");
test(c1, Cipher.DECRYPT_MODE, key, params, firstBlkSize,
answer, answer2);
System.out.println("Decryption tests: DONE");
} catch (NoSuchAlgorithmException nsae) {
System.out.println("Skipping unsupported algorithm: " +
nsae);
}
}
} catch (Exception ex) {
// print out debug info when exception is encountered
if (debugBuf != null) {
System.out.println(debugBuf.toString());
debugBuf = new StringBuffer();
}
throw ex;
}
}
private static void test(Cipher cipher, int mode, SecretKey key,
AlgorithmParameters params, int firstBlkSize,
byte[] in, byte[] answer) throws Exception {
// test setup
long startTime, endTime;
cipher.init(mode, key, params);
int outLen = cipher.getOutputSize(in.length);
//debugOut("Estimated output size = " + outLen + "\n");
// test data preparation
ByteBuffer inBuf = ByteBuffer.allocate(in.length);
inBuf.put(in);
inBuf.position(0);
ByteBuffer inDirectBuf = ByteBuffer.allocateDirect(in.length);
inDirectBuf.put(in);
inDirectBuf.position(0);
ByteBuffer outBuf = ByteBuffer.allocate(outLen);
ByteBuffer outDirectBuf = ByteBuffer.allocateDirect(outLen);
// test#1: byte[] in + byte[] out
//debugOut("Test#1:\n");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
startTime = System.nanoTime();
byte[] temp = cipher.update(in, 0, firstBlkSize);
if (temp != null && temp.length > 0) {
baos.write(temp, 0, temp.length);
}
temp = cipher.doFinal(in, firstBlkSize, in.length - firstBlkSize);
if (temp != null && temp.length > 0) {
baos.write(temp, 0, temp.length);
}
byte[] testOut1 = baos.toByteArray();
endTime = System.nanoTime();
perfOut("stream InBuf + stream OutBuf: " +
(endTime - startTime));
match(testOut1, answer);
// test#2: Non-direct Buffer in + non-direct Buffer out
//debugOut("Test#2:\n");
//debugOut("inputBuf: " + inBuf + "\n");
//debugOut("outputBuf: " + outBuf + "\n");
startTime = System.nanoTime();
cipher.update(inBuf, outBuf);
cipher.doFinal(inBuf, outBuf);
endTime = System.nanoTime();
perfOut("non-direct InBuf + non-direct OutBuf: " +
(endTime - startTime));
match(outBuf, answer);
// test#3: Direct Buffer in + direc Buffer out
//debugOut("Test#3:\n");
//debugOut("(pre) inputBuf: " + inDirectBuf + "\n");
//debugOut("(pre) outputBuf: " + outDirectBuf + "\n");
startTime = System.nanoTime();
cipher.update(inDirectBuf, outDirectBuf);
cipher.doFinal(inDirectBuf, outDirectBuf);
endTime = System.nanoTime();
perfOut("direct InBuf + direct OutBuf: " +
(endTime - startTime));
//debugOut("(post) inputBuf: " + inDirectBuf + "\n");
//debugOut("(post) outputBuf: " + outDirectBuf + "\n");
match(outDirectBuf, answer);
// test#4: Direct Buffer in + non-direct Buffer out
//debugOut("Test#4:\n");
inDirectBuf.position(0);
outBuf.position(0);
//debugOut("inputBuf: " + inDirectBuf + "\n");
//debugOut("outputBuf: " + outBuf + "\n");
startTime = System.nanoTime();
cipher.update(inDirectBuf, outBuf);
cipher.doFinal(inDirectBuf, outBuf);
endTime = System.nanoTime();
perfOut("direct InBuf + non-direct OutBuf: " +
(endTime - startTime));
match(outBuf, answer);
// test#5: Non-direct Buffer in + direct Buffer out
//debugOut("Test#5:\n");
inBuf.position(0);
outDirectBuf.position(0);
//debugOut("(pre) inputBuf: " + inBuf + "\n");
//debugOut("(pre) outputBuf: " + outDirectBuf + "\n");
startTime = System.nanoTime();
cipher.update(inBuf, outDirectBuf);
cipher.doFinal(inBuf, outDirectBuf);
endTime = System.nanoTime();
perfOut("non-direct InBuf + direct OutBuf: " +
(endTime - startTime));
//debugOut("(post) inputBuf: " + inBuf + "\n");
//debugOut("(post) outputBuf: " + outDirectBuf + "\n");
match(outDirectBuf, answer);
debugBuf = null;
}
private static void perfOut(String msg) {
if (debugBuf != null) {
debugBuf.append("PERF>" + msg);
}
}
private static void debugOut(String msg) {
if (debugBuf != null) {
debugBuf.append(msg);
}
}
private static void match(byte[] b1, byte[] b2) throws Exception {
if (b1.length != b2.length) {
debugOut("got len : " + b1.length + "\n");
debugOut("expect len: " + b2.length + "\n");
throw new Exception("mismatch - different length! got: " + b1.length + ", expect: " + b2.length + "\n");
} else {
for (int i = 0; i < b1.length; i++) {
if (b1[i] != b2[i]) {
debugOut("got : " + toString(b1) + "\n");
debugOut("expect: " + toString(b2) + "\n");
throw new Exception("mismatch");
}
}
}
}
private static void match(ByteBuffer bb, byte[] answer) throws Exception {
byte[] bbTemp = new byte[bb.position()];
bb.position(0);
bb.get(bbTemp, 0, bbTemp.length);
match(bbTemp, answer);
}
public static void main(String[] args) throws Exception {
main(new TestSymmCiphers());
}
}

View File

@ -0,0 +1,194 @@
/*
* Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.io.*;
import java.util.*;
import java.lang.reflect.*;
import java.security.*;
import java.security.cert.*;
import java.security.spec.*;
import java.security.interfaces.*;
import java.math.BigInteger;
import javax.crypto.*;
import javax.crypto.spec.*;
public class SecretKeysBasic extends PKCS11Test {
private static final char SEP = File.separatorChar;
private static char[] tokenPwd;
private static final char[] nssPwd =
new char[]{'t', 'e', 's', 't', '1', '2'};
private static final char[] solarisPwd =
new char[]{'p', 'i', 'n'};
private static SecretKey sk1;
private static SecretKey sk2;
private static SecretKey softkey;
private static KeyStore ks;
private static final String KS_TYPE = "PKCS11";
private static Provider provider;
public static void main(String[] args) throws Exception {
main(new SecretKeysBasic());
}
public void main(Provider p) throws Exception {
this.provider = p;
// create secret key
byte[] keyVal = new byte[16];
(new SecureRandom()).nextBytes(keyVal);
// NSS will throw CKR_HOST_MEMORY if calling C_DecryptInit w/
// (keyVal[0] == 0)
if (keyVal[0] == 0) {
keyVal[0] = 1;
}
softkey = new SecretKeySpec(keyVal, "AES");
dumpKey("softkey", softkey);
KeyGenerator kg = KeyGenerator.getInstance("DESede", provider);
sk1 = kg.generateKey();
dumpKey("skey1", sk1);
sk2 = kg.generateKey();
dumpKey("skey2", sk2);
String token = System.getProperty("TOKEN");
if (token == null || token.length() == 0) {
System.out.println("Error: missing TOKEN system property");
throw new Exception("token arg required");
}
if ("nss".equals(token)) {
tokenPwd = nssPwd;
} else if ("solaris".equals(token)) {
tokenPwd = solarisPwd;
}
int testnum = 1;
doTest();
}
private static boolean checkSecretKeyEntry(String alias,
SecretKey expected,
boolean saveBeforeCheck)
throws Exception {
if (saveBeforeCheck) {
ks.setKeyEntry(alias, expected, null, null);
}
SecretKey result = (SecretKey) (ks.getKey(alias, null));
String keyEncFormat = result.getFormat();
if (keyEncFormat == null) {
// sensitive or un-extractable keys - verify by encrypt/decrypt
byte[] data = new byte[64];
Cipher c =
Cipher.getInstance(result.getAlgorithm() + "/CBC/NoPadding",
provider);
c.init(Cipher.ENCRYPT_MODE, expected);
byte[] encOut = c.doFinal(data);
c.init(Cipher.DECRYPT_MODE, result, c.getParameters());
byte[] decOut = c.doFinal(encOut);
if (!Arrays.equals(data, decOut)) {
return false;
}
} else if (keyEncFormat.toUpperCase().equals("RAW")) {
if (!Arrays.equals(result.getEncoded(), expected.getEncoded())) {
dumpKey("\texpected:", expected);
dumpKey("\treturns:", result);
return false;
}
}
return true;
}
private static void dumpKey(String info, SecretKey key) {
System.out.println(info + "> " + key);
System.out.println("\tALGO=" + key.getAlgorithm());
if (key.getFormat() != null) {
System.out.println("\t[" + key.getFormat() + "] VALUE=" +
new BigInteger(key.getEncoded()));
} else {
System.out.println("\tVALUE=n/a");
}
}
private static void doTest() throws Exception {
if (ks == null) {
ks = KeyStore.getInstance(KS_TYPE, provider);
ks.load(null, tokenPwd);
}
System.out.println("Number of entries: " + ks.size());
if (ks.size() != 0) {
System.out.println("Deleting entries under aliases: ");
for (Enumeration<String> aliases = ks.aliases();
aliases.hasMoreElements();) {
String alias = aliases.nextElement();
System.out.println("\t" + alias);
ks.deleteEntry(alias);
}
}
String alias = "testSKey";
boolean testResult = checkSecretKeyEntry(alias, softkey, true);
if (!testResult) {
System.out.println("FAILURE: setKey() w/ softSecretKey failed");
}
if (!checkSecretKeyEntry(alias, sk1, true)) {
testResult = false;
System.out.println("FAILURE: setKey() w/ skey1 failed");
}
if (!checkSecretKeyEntry(alias, sk2, true)) {
testResult = false;
System.out.println("FAILURE: setKey() w/ skey2 failed");
}
ks.store(null);
System.out.println("Reloading keystore...");
ks.load(null, "whatever".toCharArray());
if (ks.size() != 1) {
System.out.println("FAILURE: reload#1 ks.size() != 1");
}
if (!checkSecretKeyEntry(alias, sk2, false)) {
testResult = false;
System.out.println("FAILURE: reload#1 ks entry check failed");
}
ks.deleteEntry(alias);
ks.store(null);
System.out.println("Reloading keystore...");
ks.load(null, "whatever".toCharArray());
if (ks.size() != 0) {
testResult = false;
System.out.println("FAILURE: reload#2 ks.size() != 0");
}
if (!testResult) {
throw new Exception("One or more test failed!");
}
}
}

View File

@ -0,0 +1,164 @@
#
# Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
# @test
# @bug 6599979
# @summary Ensure that re-assigning the alias works
#
# @run shell SecretKeysBasic.sh
#
# To run by hand:
# %sh SecretKeysBasic.sh
#
# Note:
# . test only runs on solaris at the moment
# set a few environment variables so that the shell-script can run stand-alone
# in the source directory
# if running by hand on windows, change TESTSRC and TESTCLASSES to "."
if [ "${TESTSRC}" = "" ] ; then
TESTSRC=`pwd`
fi
if [ "${TESTCLASSES}" = "" ] ; then
TESTCLASSES=`pwd`
fi
# if running by hand on windows, change this to appropriate value
if [ "${TESTJAVA}" = "" ] ; then
TESTJAVA="/net/shimmer/export/valeriep/jdk7/build/solaris-sparc"
fi
echo TESTSRC=${TESTSRC}
echo TESTCLASSES=${TESTCLASSES}
echo TESTJAVA=${TESTJAVA}
echo ""
#DEBUG=sunpkcs11,pkcs11keystore
echo DEBUG=${DEBUG}
echo ""
OS=`uname -s`
case "$OS" in
SunOS )
FS="/"
PS=":"
SCCS="${FS}usr${FS}ccs${FS}bin${FS}sccs"
CP="${FS}bin${FS}cp -f"
RM="${FS}bin${FS}rm -rf"
MKDIR="${FS}bin${FS}mkdir -p"
CHMOD="${FS}bin${FS}chmod"
;;
* )
echo "Unsupported System ${OS} - Test only runs on Solaris"
exit 0;
;;
esac
TOKENS="nss solaris"
STATUS=0
for token in ${TOKENS}
do
if [ ${token} = "nss" ]
then
# make cert/key DBs writable if token is NSS
${CP} ${TESTSRC}${FS}..${FS}nss${FS}db${FS}cert8.db ${TESTCLASSES}
${CHMOD} +w ${TESTCLASSES}${FS}cert8.db
${CP} ${TESTSRC}${FS}..${FS}nss${FS}db${FS}key3.db ${TESTCLASSES}
${CHMOD} +w ${TESTCLASSES}${FS}key3.db
USED_FILE_LIST="${TESTCLASSES}${FS}cert8.db ${TESTCLASSES}${FS}key3.db"
elif [ ${token} = "solaris" ]
then
OS_VERSION=`uname -r`
case "${OS_VERSION}" in
5.1* )
SOFTTOKEN_DIR=${TESTCLASSES}
export SOFTTOKEN_DIR
;;
* )
echo "Unsupported Version ${OS_VERSION} - Test only runs on Solaris"
exit 0;
;;
esac
# copy keystore into write-able location
if [ -d ${TESTCLASSES}${FS}pkcs11_softtoken ]
then
echo "Removing old pkcs11_keystore, creating new pkcs11_keystore"
echo ${RM} ${TESTCLASSES}${FS}pkcs11_softtoken
${RM} ${TESTCLASSES}${FS}pkcs11_softtoken
fi
echo ${MKDIR} ${TESTCLASSES}${FS}pkcs11_softtoken${FS}private
${MKDIR} ${TESTCLASSES}${FS}pkcs11_softtoken${FS}private
echo ${MKDIR} ${TESTCLASSES}${FS}pkcs11_softtoken${FS}public
${MKDIR} ${TESTCLASSES}${FS}pkcs11_softtoken${FS}public
echo ${CP} ${TESTSRC}${FS}BasicData${FS}pkcs11_softtoken${FS}objstore_info \
${TESTCLASSES}${FS}pkcs11_softtoken
${CP} ${TESTSRC}${FS}BasicData${FS}pkcs11_softtoken${FS}objstore_info \
${TESTCLASSES}${FS}pkcs11_softtoken
echo ${CHMOD} +w ${TESTCLASSES}${FS}pkcs11_softtoken${FS}objstore_info
${CHMOD} 600 ${TESTCLASSES}${FS}pkcs11_softtoken${FS}objstore_info
USED_FILE_LIST="${TESTCLASSES}${FS}pkcs11_softtoken"
fi
cd ${TESTCLASSES}
${TESTJAVA}${FS}bin${FS}javac \
-classpath ${TESTCLASSES} \
-d ${TESTCLASSES} \
${TESTSRC}${FS}SecretKeysBasic.java
# run test
cd ${TESTSRC}
${TESTJAVA}${FS}bin${FS}java \
-DDIR=${TESTSRC}${FS}BasicData${FS} \
-classpath ${TESTCLASSES}${PS}${TESTSRC}${FS}loader.jar \
-DCUSTOM_DB_DIR=${TESTCLASSES} \
-DCUSTOM_P11_CONFIG=${TESTSRC}${FS}BasicData${FS}p11-${token}.txt \
-DNO_DEFAULT=true \
-DNO_DEIMOS=true \
-DTOKEN=${token} \
-Djava.security.debug=${DEBUG} \
SecretKeysBasic
# -DCUSTOM_P11_CONFIG=${TESTSRC}${FS}BasicData${FS}p11-${token}.txt \
# save error status
if [ $? != 0 ]
then
echo "Test against " ${token} " Failed!"
STATUS=1
fi
# clean up
${RM} ${USED_FILE_LIST}
done
# return
exit ${STATUS}

View File

@ -0,0 +1,262 @@
/*
* Copyright 2001-2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6668231
* @summary Presence of a critical subjectAltName causes JSSE's SunX509 to
* fail trusted checks
* @author Xuelei Fan
*
* This test depends on binary keystore, crisubn.jks and trusted.jks. Because
* JAVA keytool cannot generate X509 certificate with SubjectAltName extension,
* the certificates are generated with openssl toolkits and then imported into
* JAVA keystore.
*
* The crisubn.jks holds a private key entry and the corresponding X509
* certificate issued with an empty Subject field, and a critical
* SubjectAltName extension.
*
* The trusted.jks holds the trusted certificate.
*/
import java.io.*;
import java.net.*;
import javax.net.ssl.*;
import java.security.cert.Certificate;
public class CriticalSubjectAltName implements HostnameVerifier {
/*
* =============================================================
* 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 = true;
/*
* Where do we find the keystores?
*/
static String pathToStores = "./";
static String keyStoreFile = "crisubn.jks";
static String trustStoreFile = "trusted.jks";
static String passwd = "passphrase";
/*
* Is the server ready to serve?
*/
volatile static boolean serverReady = false;
/*
* Turn on SSL debugging?
*/
static boolean debug = false;
/*
* 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 =
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket sslServerSocket =
(SSLServerSocket) sslssf.createServerSocket(serverPort);
serverPort = sslServerSocket.getLocalPort();
/*
* Signal Client, we're ready for his connect.
*/
serverReady = true;
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
OutputStream sslOS = sslSocket.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sslOS));
bw.write("HTTP/1.1 200 OK\r\n\r\n\r\n");
bw.flush();
Thread.sleep(5000);
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);
}
URL url = new URL("https://localhost:"+serverPort+"/index.html");
HttpsURLConnection urlc = (HttpsURLConnection)url.openConnection();
urlc.setHostnameVerifier(this);
urlc.getInputStream();
if (urlc.getResponseCode() == -1) {
throw new RuntimeException("getResponseCode() returns -1");
}
}
/*
* =============================================================
* 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 {
String keyFilename =
System.getProperty("test.src", "./") + "/" + pathToStores +
"/" + keyStoreFile;
String trustFilename =
System.getProperty("test.src", "./") + "/" + pathToStores +
"/" + trustStoreFile;
System.setProperty("javax.net.ssl.keyStore", keyFilename);
System.setProperty("javax.net.ssl.keyStorePassword", passwd);
System.setProperty("javax.net.ssl.trustStore", trustFilename);
System.setProperty("javax.net.ssl.trustStorePassword", passwd);
if (debug)
System.setProperty("javax.net.debug", "all");
/*
* Start the tests.
*/
new CriticalSubjectAltName();
}
Thread clientThread = null;
Thread serverThread = null;
/*
* Primary constructor, used to drive remainder of the test.
*
* Fork off the other side, then do your work.
*/
CriticalSubjectAltName() throws Exception {
if (separateServerThread) {
startServer(true);
startClient(false);
} else {
startClient(true);
startServer(false);
}
/*
* Wait for other side to close down.
*/
if (separateServerThread) {
serverThread.join();
} else {
clientThread.join();
}
/*
* When we get here, the test is pretty much over.
*
* If the main thread excepted, that propagates back
* immediately. If the other thread threw an exception, we
* should report back.
*/
if (serverException != null)
throw serverException;
if (clientException != null)
throw clientException;
}
void startServer(boolean newThread) throws Exception {
if (newThread) {
serverThread = new Thread() {
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 {
doServerSide();
}
}
void startClient(boolean newThread) throws Exception {
if (newThread) {
clientThread = new Thread() {
public void run() {
try {
doClientSide();
} catch (Exception e) {
/*
* Our client thread just died.
*/
System.err.println("Client died...");
clientException = e;
}
}
};
clientThread.start();
} else {
doClientSide();
}
}
// Simple test method to blindly agree that hostname and certname match
public boolean verify(String hostname, SSLSession session) {
return true;
}
}