diff --git a/.github/workflows/IKVM.yml b/.github/workflows/IKVM.yml index e0229fe73d..95a17ab109 100644 --- a/.github/workflows/IKVM.yml +++ b/.github/workflows/IKVM.yml @@ -1,6 +1,7 @@ name: IKVM on: + workflow_dispatch: push: branches: - main @@ -635,10 +636,11 @@ jobs: "--blame", "--blame-crash", "--blame-hang", - "--blame-hang-timeout", "120m", + "--blame-hang-timeout", "60m", + "--blame-hang-dump-type", "full", "-v:diag", "--results-directory", "TestResults", - "--logger:console;verbosity=diag", + "--logger:console;verbosity=detailed", "--logger:trx" # "--collect", "Code Coverage" ) diff --git a/Directory.Build.props b/Directory.Build.props index ca6d7ec004..915433575a 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -24,8 +24,8 @@ 1 8 0 - 92 - b34 + 152 + b16 OpenJDK $(OpenJdkMinorVersion)u$(OpenJdkUpdateVersion) $(OpenJdkBuildNumber) $(OpenJdkMajorVersion).$(OpenJdkMinorVersion).$(OpenJdkMicroVersion)_$(OpenJdkUpdateVersion)-$(OpenJdkBuildNumber) Oracle diff --git a/Directory.Build.targets b/Directory.Build.targets index 0c55181af6..b3f4ad1017 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -7,4 +7,5 @@ win-x64 true + diff --git a/Directory.Packages.props b/Directory.Packages.props index 91c496c3ad..189ea845b5 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -37,7 +37,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/IKVM.sln b/IKVM.sln index 8d200dc49f..06e62514ba 100644 --- a/IKVM.sln +++ b/IKVM.sln @@ -221,6 +221,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IKVM.Image.JRE.runtime.linu EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IKVM.Image.JRE.runtime.linux-musl-x64", "src\IKVM.Image.JRE.runtime.linux-musl-x64\IKVM.Image.JRE.runtime.linux-musl-x64.csproj", "{4AC61233-8347-4AC6-9E01-5C5BC48D5A8F}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "xjc", "src\xjc\xjc.msbuildproj", "{C35B9502-AC9F-4490-9480-6EAB4FD94AAA}" +EndProject Project("{6DE1C62B-E8D7-451A-8734-87EAEB46E35B}") = "libunpack", "src\libunpack\libunpack.clangproj", "{1E74B9F3-AF8C-4ADB-90EA-0E1696C7886C}" EndProject Project("{6DE1C62B-E8D7-451A-8734-87EAEB46E35B}") = "libjvm", "src\libjvm\libjvm.clangproj", "{FE90DDCB-06F3-4470-A9A7-7640B04EA9E4}" @@ -668,6 +670,10 @@ Global {4AC61233-8347-4AC6-9E01-5C5BC48D5A8F}.Debug|Any CPU.Build.0 = Debug|Any CPU {4AC61233-8347-4AC6-9E01-5C5BC48D5A8F}.Release|Any CPU.ActiveCfg = Release|Any CPU {4AC61233-8347-4AC6-9E01-5C5BC48D5A8F}.Release|Any CPU.Build.0 = Release|Any CPU + {C35B9502-AC9F-4490-9480-6EAB4FD94AAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C35B9502-AC9F-4490-9480-6EAB4FD94AAA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C35B9502-AC9F-4490-9480-6EAB4FD94AAA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C35B9502-AC9F-4490-9480-6EAB4FD94AAA}.Release|Any CPU.Build.0 = Release|Any CPU {1E74B9F3-AF8C-4ADB-90EA-0E1696C7886C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1E74B9F3-AF8C-4ADB-90EA-0E1696C7886C}.Debug|Any CPU.Build.0 = Debug|Any CPU {1E74B9F3-AF8C-4ADB-90EA-0E1696C7886C}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/ext/ikvm-native-sdk/Fix-SymbolicLinks.ps1 b/ext/ikvm-native-sdk/Fix-SymbolicLinks.ps1 index 79832e653d..a649f2a0d8 100644 --- a/ext/ikvm-native-sdk/Fix-SymbolicLinks.ps1 +++ b/ext/ikvm-native-sdk/Fix-SymbolicLinks.ps1 @@ -19,7 +19,7 @@ function Fix-SymbolicLink ($i, $p) { } # recurse into target, attempting to fix it - $t = gi $(Join-Path $i.DirectoryName $i.Target) + $t = gi $(Join-Path "$($i.DirectoryName)" "$($i.Target)") $t = Fix-SymbolicLink $t # is the target a directory? @@ -28,11 +28,11 @@ function Fix-SymbolicLink ($i, $p) { $t = $i.Target # remove original item and replace with mklink /D - ri $i + ri $i.FullName & cmd /c "mklink /D $n $t" | Write-Host # refresh item for recursive call - return (gi $i) + return (gi $i.FullName) } } catch { Write-Host -Foreground Red -Background Black ($i.FullName + ": " + $_.Exception.Message) diff --git a/openjdk b/openjdk index e0b32f678c..e58c8a60e3 160000 --- a/openjdk +++ b/openjdk @@ -1 +1 @@ -Subproject commit e0b32f678cccdc17aa34d6c9837457628f6aa500 +Subproject commit e58c8a60e38ef345be29ff8277dcac903044797a diff --git a/openjdk.props b/openjdk.props index bf2cb15a6a..81a4929efb 100644 --- a/openjdk.props +++ b/openjdk.props @@ -1113,11 +1113,6 @@ - - - - - @@ -1290,6 +1285,7 @@ + @@ -1300,6 +1296,7 @@ + @@ -1462,6 +1459,7 @@ + @@ -1478,6 +1476,7 @@ + @@ -1698,8 +1697,6 @@ - - @@ -1723,11 +1720,9 @@ - + - - diff --git a/src/IKVM.ByteCode.Tests/IKVM.ByteCode.Tests.csproj b/src/IKVM.ByteCode.Tests/IKVM.ByteCode.Tests.csproj index 6e54046a5b..c75d04d97c 100644 --- a/src/IKVM.ByteCode.Tests/IKVM.ByteCode.Tests.csproj +++ b/src/IKVM.ByteCode.Tests/IKVM.ByteCode.Tests.csproj @@ -7,9 +7,9 @@ - + - + diff --git a/src/IKVM.Image.JDK-bin/IKVM.Image.JDK-bin.csproj b/src/IKVM.Image.JDK-bin/IKVM.Image.JDK-bin.csproj index c72121ce10..f3671b461e 100644 --- a/src/IKVM.Image.JDK-bin/IKVM.Image.JDK-bin.csproj +++ b/src/IKVM.Image.JDK-bin/IKVM.Image.JDK-bin.csproj @@ -16,9 +16,10 @@ + - + diff --git a/src/IKVM.Image.runtime.linux-arm64/ikvm/any/linux-arm64/lib/security/java.security b/src/IKVM.Image.runtime.linux-arm64/ikvm/any/linux-arm64/lib/security/java.security index 12d1fd8efd..0a769887ed 100644 --- a/src/IKVM.Image.runtime.linux-arm64/ikvm/any/linux-arm64/lib/security/java.security +++ b/src/IKVM.Image.runtime.linux-arm64/ikvm/any/linux-arm64/lib/security/java.security @@ -209,6 +209,8 @@ package.access=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -220,7 +222,8 @@ package.access=sun.,\ jdk.internal.,\ jdk.nashorn.internal.,\ jdk.nashorn.tools.,\ - com.sun.activation.registries. + com.sun.activation.registries.,\ + com.sun.java.accessibility. # # List of comma-separated packages that start with or equal this string @@ -256,6 +259,8 @@ package.definition=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -267,7 +272,8 @@ package.definition=sun.,\ jdk.internal.,\ jdk.nashorn.internal.,\ jdk.nashorn.tools.,\ - com.sun.activation.registries. + com.sun.activation.registries.,\ + com.sun.java.accessibility. # # Determines whether this properties file can be appended to @@ -422,35 +428,37 @@ krb5.kdc.bad.policy = tryLast # describes the mechanism for disabling algorithms based on algorithm name # and/or key length. This includes algorithms used in certificates, as well # as revocation information such as CRLs and signed OCSP Responses. -# -# The syntax of the disabled algorithm string is described as this Java -# BNF-style: +# The syntax of the disabled algorithm string is described as follows: # DisabledAlgorithms: # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint | CAConstraint | DenyAfterConstraint | +# UsageConstraint # # KeySizeConstraint: -# keySize Operator DecimalInteger +# keySize Operator KeyLength # # Operator: # <= | < | == | != | >= | > # -# DecimalInteger: -# DecimalDigits +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# CAConstraint: +# jdkCA # -# DecimalDigits: -# DecimalDigit {DecimalDigit} +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD # -# DecimalDigit: one of -# 1 2 3 4 5 6 7 8 9 0 +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] # # The "AlgorithmName" is the standard algorithm name of the disabled # algorithm. See "Java Cryptography Architecture Standard Algorithm Name @@ -464,15 +472,69 @@ krb5.kdc.bad.policy = tryLast # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # will not disable algorithms related to "ECDSA". # -# A "Constraint" provides further guidance for the algorithm being specified. -# The "KeySizeConstraint" requires a key of a valid size range if the -# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the -# key size specified in number of bits. For example, "RSA keySize <= 1024" -# indicates that any RSA key with key size less than or equal to 1024 bits -# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates -# that any RSA key with key size less than 1024 or greater than 2048 should -# be disabled. Note that the "KeySizeConstraint" only makes sense to key -# algorithms. +# A "Constraint" defines restrictions on the keys and/or certificates for +# a specified AlgorithmName: +# +# KeySizeConstraint: +# keySize Operator KeyLength +# The constraint requires a key of a valid size range if the +# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates +# the key size specified in number of bits. For example, +# "RSA keySize <= 1024" indicates that any RSA key with key size less +# than or equal to 1024 bits should be disabled, and +# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key +# with key size less than 1024 or greater than 2048 should be disabled. +# This constraint is only used on algorithms that have a key size. +# +# CAConstraint: +# jdkCA +# This constraint prohibits the specified algorithm only if the +# algorithm is used in a certificate chain that terminates at a marked +# trust anchor in the lib/security/cacerts keystore. If the jdkCA +# constraint is not set, then all chains using the specified algorithm +# are restricted. jdkCA may only be used once in a DisabledAlgorithm +# expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following: "SHA1 jdkCA" +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# This constraint prohibits a certificate with the specified algorithm +# from being used after the date regardless of the certificate's +# validity. JAR files that are signed and timestamped before the +# constraint date with certificates containing the disabled algorithm +# will not be restricted. The date is processed in the UTC timezone. +# This constraint can only be used once in a DisabledAlgorithm +# expression. +# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020, +# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03" +# +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] +# This constraint prohibits the specified algorithm for +# a specified usage. This should be used when disabling an algorithm +# for all usages is not practical. 'TLSServer' restricts the algorithm +# in TLS server certificate chains when server authentication is +# performed. 'TLSClient' restricts the algorithm in TLS client +# certificate chains when client authentication is performed. +# 'SignedJAR' constrains use of certificates in signed jar files. +# The usage type follows the keyword and more than one usage type can +# be specified with a whitespace delimiter. +# Example: "SHA1 usage TLSServer TLSClient" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. # # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. @@ -481,8 +543,53 @@ krb5.kdc.bad.policy = tryLast # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 # # -jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \ + RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 +# +# Algorithm restrictions for signed JAR files +# +# In some environments, certain algorithms or key lengths may be undesirable +# for signed JAR validation. For example, "MD2" is generally no longer +# considered to be a secure hash algorithm. This section describes the +# mechanism for disabling algorithms based on algorithm name and/or key length. +# JARs signed with any of the disabled algorithms or key sizes will be treated +# as unsigned. +# +# The syntax of the disabled algorithm string is described as follows: +# DisabledAlgorithms: +# " DisabledAlgorithm { , DisabledAlgorithm } " +# +# DisabledAlgorithm: +# AlgorithmName [Constraint] { '&' Constraint } +# +# AlgorithmName: +# (see below) +# +# Constraint: +# KeySizeConstraint | DenyAfterConstraint +# +# KeySizeConstraint: +# keySize Operator KeyLength +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# +# Operator: +# <= | < | == | != | >= | > +# +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# Note: This property is currently used by the JDK Reference +# implementation. It is not guaranteed to be examined and used by other +# implementations. +# +# See "jdk.certpath.disabledAlgorithms" for syntax descriptions. +# +jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 + +# # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing # @@ -504,12 +611,16 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 # See the specification of "jdk.certpath.disabledAlgorithms" for the # syntax of the disabled algorithm string. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. +# +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -523,7 +634,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -553,7 +664,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -566,7 +677,8 @@ jdk.tls.legacyAlgorithms= \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing. @@ -624,3 +736,177 @@ jdk.tls.legacyAlgorithms= \ # E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ # EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ # FFFFFFFF FFFFFFFF, 2} + +# Cryptographic Jurisdiction Policy defaults +# +# Due to the import control restrictions of some countries, the default +# JCE policy files allow for strong but "limited" cryptographic key +# lengths to be used. If your country's cryptographic regulations allow, +# the "unlimited" strength policy files can be used instead, which contain +# no restrictions on cryptographic strengths. +# +# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY +# TO DETERMINE THE EXACT REQUIREMENTS. +# +# (below) refers to the directory where the JRE was +# installed. It is determined based on whether you are running JCE +# on a JRE or a JRE contained within the Java Development Kit, or +# JDK(TM). The JDK contains the JRE, but at a different level in the +# file hierarchy. For example, if the JDK is installed in +# /home/user1/jdk1.8.0 on Unix or in C:\jdk1.8.0 on Windows, then +# is: +# +# /home/user1/jdk1.8.0/jre [Unix] +# C:\jdk1.8.0\jre [Windows] +# +# If on the other hand the JRE is installed in /home/user1/jre1.8.0 +# on Unix or in C:\jre1.8.0 on Windows, and the JDK is not +# installed, then is: +# +# /home/user1/jre1.8.0 [Unix] +# C:\jre1.8.0 [Windows] +# +# On Windows, for each JDK installation, there may be additional +# JREs installed under the "Program Files" directory. Please make +# sure that you install the unlimited strength policy JAR files +# for all JREs that you plan to use. +# +# The policy files are jar files organized into subdirectories of +# /lib/security/policy. Each directory contains a complete +# set of policy files. +# +# The "crypto.policy" Security property controls the directory selection, +# and thus the effective cryptographic policy. +# +# The default set of directories is: +# +# limited | unlimited +# +# however other directories can be created and configured. +# +# To support older JDK Update releases, the crypto.policy property +# is not defined by default. When the property is not defined, an +# update release binary aware of the new property will use the following +# logic to decide what crypto policy files get used : +# +# * If the US_export_policy.jar and local_policy.jar files are located +# in the (legacy) /lib/security directory, then the rules +# embedded in those jar files will be used. This helps preserve compatibility +# for users upgrading from an older installation. +# +# * If crypto.policy is not defined and no such jar files are present in +# the legacy locations, then the JDK will use the limited settings +# (equivalent to crypto.policy=limited) +# +# Please see the JCA documentation for additional information on these +# files and formats. +crypto.policy=unlimited + +# +# The policy for the XML Signature secure validation mode. The mode is +# enabled by setting the property "org.jcp.xml.dsig.secureValidation" to +# true with the javax.xml.crypto.XMLCryptoContext.setProperty() method, +# or by running the code with a SecurityManager. +# +# Policy: +# Constraint {"," Constraint } +# Constraint: +# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint +# AlgConstraint +# "disallowAlg" Uri +# MaxTransformsConstraint: +# "maxTransforms" Integer +# MaxReferencesConstraint: +# "maxReferences" Integer +# ReferenceUriSchemeConstraint: +# "disallowReferenceUriSchemes" String { String } +# KeySizeConstraint: +# "minKeySize" KeyAlg Integer +# OtherConstraint: +# "noDuplicateIds" | "noRetrievalMethodLoops" +# +# For AlgConstraint, Uri is the algorithm URI String that is not allowed. +# See the XML Signature Recommendation for more information on algorithm +# URI Identifiers. For KeySizeConstraint, KeyAlg is the standard algorithm +# name of the key type (ex: "RSA"). If the MaxTransformsConstraint, +# MaxReferencesConstraint or KeySizeConstraint (for the same key type) is +# specified more than once, only the last entry is enforced. +# +# Note: This property is currently used by the JDK Reference implementation. It +# is not guaranteed to be examined and used by other implementations. +# +jdk.xml.dsig.secureValidationPolicy=\ + disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\ + maxTransforms 5,\ + maxReferences 30,\ + disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ + noDuplicateIds,\ + noRetrievalMethodLoops + +# +# Serialization process-wide filter +# +# A filter, if configured, is used by java.io.ObjectInputStream during +# deserialization to check the contents of the stream. +# A filter is configured as a sequence of patterns, each pattern is either +# matched against the name of a class in the stream or defines a limit. +# Patterns are separated by ";" (semicolon). +# Whitespace is significant and is considered part of the pattern. +# +# If a pattern includes a "=", it sets a limit. +# If a limit appears more than once the last value is used. +# Limits are checked before classes regardless of the order in the sequence of patterns. +# If any of the limits are exceeded, the filter status is REJECTED. +# +# maxdepth=value - the maximum depth of a graph +# maxrefs=value - the maximum number of internal references +# maxbytes=value - the maximum number of bytes in the input stream +# maxarray=value - the maximum array length allowed +# +# Other patterns, from left to right, match the class or package name as +# returned from Class.getName. +# If the class is an array type, the class or package to be matched is the element type. +# Arrays of any number of dimensions are treated the same as the element type. +# For example, a pattern of "!example.Foo", rejects creation of any instance or +# array of example.Foo. +# +# If the pattern starts with "!", the status is REJECTED if the remaining pattern +# is matched; otherwise the status is ALLOWED if the pattern matches. +# If the pattern ends with ".**" it matches any class in the package and all subpackages. +# If the pattern ends with ".*" it matches any class in the package. +# If the pattern ends with "*", it matches any class with the pattern as a prefix. +# If the pattern is equal to the class name, it matches. +# Otherwise, the status is UNDECIDED. +# +#jdk.serialFilter=pattern;pattern + +# +# RMI Registry Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI Registry. +# +#sun.rmi.registry.registryFilter=pattern;pattern + +# +# RMI Distributed Garbage Collector (DGC) Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI DGC. +# +# The builtin DGC filter can approximately be represented as the filter pattern: +# +#sun.rmi.transport.dgcFilter=\ +# java.rmi.server.ObjID;\ +# java.rmi.server.UID;\ +# java.rmi.dgc.VMID;\ +# java.rmi.dgc.Lease;\ +# maxdepth=5;maxarray=10000 diff --git a/src/IKVM.Image.runtime.linux-musl-arm/ikvm/any/linux-musl-arm/lib/security/java.security b/src/IKVM.Image.runtime.linux-musl-arm/ikvm/any/linux-musl-arm/lib/security/java.security index 12d1fd8efd..d8162670a2 100644 --- a/src/IKVM.Image.runtime.linux-musl-arm/ikvm/any/linux-musl-arm/lib/security/java.security +++ b/src/IKVM.Image.runtime.linux-musl-arm/ikvm/any/linux-musl-arm/lib/security/java.security @@ -209,6 +209,8 @@ package.access=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -256,6 +258,8 @@ package.definition=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -422,35 +426,37 @@ krb5.kdc.bad.policy = tryLast # describes the mechanism for disabling algorithms based on algorithm name # and/or key length. This includes algorithms used in certificates, as well # as revocation information such as CRLs and signed OCSP Responses. -# -# The syntax of the disabled algorithm string is described as this Java -# BNF-style: +# The syntax of the disabled algorithm string is described as follows: # DisabledAlgorithms: # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint | CAConstraint | DenyAfterConstraint | +# UsageConstraint # # KeySizeConstraint: -# keySize Operator DecimalInteger +# keySize Operator KeyLength # # Operator: # <= | < | == | != | >= | > # -# DecimalInteger: -# DecimalDigits +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# CAConstraint: +# jdkCA # -# DecimalDigits: -# DecimalDigit {DecimalDigit} +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD # -# DecimalDigit: one of -# 1 2 3 4 5 6 7 8 9 0 +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] # # The "AlgorithmName" is the standard algorithm name of the disabled # algorithm. See "Java Cryptography Architecture Standard Algorithm Name @@ -464,15 +470,69 @@ krb5.kdc.bad.policy = tryLast # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # will not disable algorithms related to "ECDSA". # -# A "Constraint" provides further guidance for the algorithm being specified. -# The "KeySizeConstraint" requires a key of a valid size range if the -# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the -# key size specified in number of bits. For example, "RSA keySize <= 1024" -# indicates that any RSA key with key size less than or equal to 1024 bits -# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates -# that any RSA key with key size less than 1024 or greater than 2048 should -# be disabled. Note that the "KeySizeConstraint" only makes sense to key -# algorithms. +# A "Constraint" defines restrictions on the keys and/or certificates for +# a specified AlgorithmName: +# +# KeySizeConstraint: +# keySize Operator KeyLength +# The constraint requires a key of a valid size range if the +# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates +# the key size specified in number of bits. For example, +# "RSA keySize <= 1024" indicates that any RSA key with key size less +# than or equal to 1024 bits should be disabled, and +# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key +# with key size less than 1024 or greater than 2048 should be disabled. +# This constraint is only used on algorithms that have a key size. +# +# CAConstraint: +# jdkCA +# This constraint prohibits the specified algorithm only if the +# algorithm is used in a certificate chain that terminates at a marked +# trust anchor in the lib/security/cacerts keystore. If the jdkCA +# constraint is not set, then all chains using the specified algorithm +# are restricted. jdkCA may only be used once in a DisabledAlgorithm +# expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following: "SHA1 jdkCA" +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# This constraint prohibits a certificate with the specified algorithm +# from being used after the date regardless of the certificate's +# validity. JAR files that are signed and timestamped before the +# constraint date with certificates containing the disabled algorithm +# will not be restricted. The date is processed in the UTC timezone. +# This constraint can only be used once in a DisabledAlgorithm +# expression. +# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020, +# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03" +# +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] +# This constraint prohibits the specified algorithm for +# a specified usage. This should be used when disabling an algorithm +# for all usages is not practical. 'TLSServer' restricts the algorithm +# in TLS server certificate chains when server authentication is +# performed. 'TLSClient' restricts the algorithm in TLS client +# certificate chains when client authentication is performed. +# 'SignedJAR' constrains use of certificates in signed jar files. +# The usage type follows the keyword and more than one usage type can +# be specified with a whitespace delimiter. +# Example: "SHA1 usage TLSServer TLSClient" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. # # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. @@ -481,8 +541,53 @@ krb5.kdc.bad.policy = tryLast # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 # # -jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \ + RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 + +# +# Algorithm restrictions for signed JAR files +# +# In some environments, certain algorithms or key lengths may be undesirable +# for signed JAR validation. For example, "MD2" is generally no longer +# considered to be a secure hash algorithm. This section describes the +# mechanism for disabling algorithms based on algorithm name and/or key length. +# JARs signed with any of the disabled algorithms or key sizes will be treated +# as unsigned. +# +# The syntax of the disabled algorithm string is described as follows: +# DisabledAlgorithms: +# " DisabledAlgorithm { , DisabledAlgorithm } " +# +# DisabledAlgorithm: +# AlgorithmName [Constraint] { '&' Constraint } +# +# AlgorithmName: +# (see below) +# +# Constraint: +# KeySizeConstraint | DenyAfterConstraint +# +# KeySizeConstraint: +# keySize Operator KeyLength +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# +# Operator: +# <= | < | == | != | >= | > +# +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# Note: This property is currently used by the JDK Reference +# implementation. It is not guaranteed to be examined and used by other +# implementations. +# +# See "jdk.certpath.disabledAlgorithms" for syntax descriptions. +# +jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +# # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing # @@ -504,12 +609,16 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 # See the specification of "jdk.certpath.disabledAlgorithms" for the # syntax of the disabled algorithm string. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. +# +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -523,7 +632,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -553,7 +662,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -566,7 +675,8 @@ jdk.tls.legacyAlgorithms= \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing. @@ -624,3 +734,178 @@ jdk.tls.legacyAlgorithms= \ # E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ # EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ # FFFFFFFF FFFFFFFF, 2} + +# Cryptographic Jurisdiction Policy defaults +# +# Due to the import control restrictions of some countries, the default +# JCE policy files allow for strong but "limited" cryptographic key +# lengths to be used. If your country's cryptographic regulations allow, +# the "unlimited" strength policy files can be used instead, which contain +# no restrictions on cryptographic strengths. +# +# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY +# TO DETERMINE THE EXACT REQUIREMENTS. +# +# (below) refers to the directory where the JRE was +# installed. It is determined based on whether you are running JCE +# on a JRE or a JRE contained within the Java Development Kit, or +# JDK(TM). The JDK contains the JRE, but at a different level in the +# file hierarchy. For example, if the JDK is installed in +# /home/user1/jdk1.8.0 on Unix or in C:\jdk1.8.0 on Windows, then +# is: +# +# /home/user1/jdk1.8.0/jre [Unix] +# C:\jdk1.8.0\jre [Windows] +# +# If on the other hand the JRE is installed in /home/user1/jre1.8.0 +# on Unix or in C:\jre1.8.0 on Windows, and the JDK is not +# installed, then is: +# +# /home/user1/jre1.8.0 [Unix] +# C:\jre1.8.0 [Windows] +# +# On Windows, for each JDK installation, there may be additional +# JREs installed under the "Program Files" directory. Please make +# sure that you install the unlimited strength policy JAR files +# for all JREs that you plan to use. +# +# The policy files are jar files organized into subdirectories of +# /lib/security/policy. Each directory contains a complete +# set of policy files. +# +# The "crypto.policy" Security property controls the directory selection, +# and thus the effective cryptographic policy. +# +# The default set of directories is: +# +# limited | unlimited +# +# however other directories can be created and configured. +# +# To support older JDK Update releases, the crypto.policy property +# is not defined by default. When the property is not defined, an +# update release binary aware of the new property will use the following +# logic to decide what crypto policy files get used : +# +# * If the US_export_policy.jar and local_policy.jar files are located +# in the (legacy) /lib/security directory, then the rules +# embedded in those jar files will be used. This helps preserve compatibility +# for users upgrading from an older installation. +# +# * If crypto.policy is not defined and no such jar files are present in +# the legacy locations, then the JDK will use the limited settings +# (equivalent to crypto.policy=limited) +# +# Please see the JCA documentation for additional information on these +# files and formats. +crypto.policy=unlimited + +# +# The policy for the XML Signature secure validation mode. The mode is +# enabled by setting the property "org.jcp.xml.dsig.secureValidation" to +# true with the javax.xml.crypto.XMLCryptoContext.setProperty() method, +# or by running the code with a SecurityManager. +# +# Policy: +# Constraint {"," Constraint } +# Constraint: +# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint +# AlgConstraint +# "disallowAlg" Uri +# MaxTransformsConstraint: +# "maxTransforms" Integer +# MaxReferencesConstraint: +# "maxReferences" Integer +# ReferenceUriSchemeConstraint: +# "disallowReferenceUriSchemes" String { String } +# KeySizeConstraint: +# "minKeySize" KeyAlg Integer +# OtherConstraint: +# "noDuplicateIds" | "noRetrievalMethodLoops" +# +# For AlgConstraint, Uri is the algorithm URI String that is not allowed. +# See the XML Signature Recommendation for more information on algorithm +# URI Identifiers. For KeySizeConstraint, KeyAlg is the standard algorithm +# name of the key type (ex: "RSA"). If the MaxTransformsConstraint, +# MaxReferencesConstraint or KeySizeConstraint (for the same key type) is +# specified more than once, only the last entry is enforced. +# +# Note: This property is currently used by the JDK Reference implementation. It +# is not guaranteed to be examined and used by other implementations. +# +jdk.xml.dsig.secureValidationPolicy=\ + disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\ + maxTransforms 5,\ + maxReferences 30,\ + disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ + noDuplicateIds,\ + noRetrievalMethodLoops + +# +# Serialization process-wide filter +# +# A filter, if configured, is used by java.io.ObjectInputStream during +# deserialization to check the contents of the stream. +# A filter is configured as a sequence of patterns, each pattern is either +# matched against the name of a class in the stream or defines a limit. +# Patterns are separated by ";" (semicolon). +# Whitespace is significant and is considered part of the pattern. +# +# If a pattern includes a "=", it sets a limit. +# If a limit appears more than once the last value is used. +# Limits are checked before classes regardless of the order in the sequence of patterns. +# If any of the limits are exceeded, the filter status is REJECTED. +# +# maxdepth=value - the maximum depth of a graph +# maxrefs=value - the maximum number of internal references +# maxbytes=value - the maximum number of bytes in the input stream +# maxarray=value - the maximum array length allowed +# +# Other patterns, from left to right, match the class or package name as +# returned from Class.getName. +# If the class is an array type, the class or package to be matched is the element type. +# Arrays of any number of dimensions are treated the same as the element type. +# For example, a pattern of "!example.Foo", rejects creation of any instance or +# array of example.Foo. +# +# If the pattern starts with "!", the status is REJECTED if the remaining pattern +# is matched; otherwise the status is ALLOWED if the pattern matches. +# If the pattern ends with ".**" it matches any class in the package and all subpackages. +# If the pattern ends with ".*" it matches any class in the package. +# If the pattern ends with "*", it matches any class with the pattern as a prefix. +# If the pattern is equal to the class name, it matches. +# Otherwise, the status is UNDECIDED. +# +#jdk.serialFilter=pattern;pattern + +# +# RMI Registry Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI Registry. +# +#sun.rmi.registry.registryFilter=pattern;pattern + +# +# RMI Distributed Garbage Collector (DGC) Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI DGC. +# +# The builtin DGC filter can approximately be represented as the filter pattern: +# +#sun.rmi.transport.dgcFilter=\ +# java.rmi.server.ObjID;\ +# java.rmi.server.UID;\ +# java.rmi.dgc.VMID;\ +# java.rmi.dgc.Lease;\ +# maxdepth=5;maxarray=10000 + diff --git a/src/IKVM.Image.runtime.linux-musl-arm64/ikvm/any/linux-musl-arm64/lib/security/java.security b/src/IKVM.Image.runtime.linux-musl-arm64/ikvm/any/linux-musl-arm64/lib/security/java.security index 12d1fd8efd..d8162670a2 100644 --- a/src/IKVM.Image.runtime.linux-musl-arm64/ikvm/any/linux-musl-arm64/lib/security/java.security +++ b/src/IKVM.Image.runtime.linux-musl-arm64/ikvm/any/linux-musl-arm64/lib/security/java.security @@ -209,6 +209,8 @@ package.access=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -256,6 +258,8 @@ package.definition=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -422,35 +426,37 @@ krb5.kdc.bad.policy = tryLast # describes the mechanism for disabling algorithms based on algorithm name # and/or key length. This includes algorithms used in certificates, as well # as revocation information such as CRLs and signed OCSP Responses. -# -# The syntax of the disabled algorithm string is described as this Java -# BNF-style: +# The syntax of the disabled algorithm string is described as follows: # DisabledAlgorithms: # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint | CAConstraint | DenyAfterConstraint | +# UsageConstraint # # KeySizeConstraint: -# keySize Operator DecimalInteger +# keySize Operator KeyLength # # Operator: # <= | < | == | != | >= | > # -# DecimalInteger: -# DecimalDigits +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# CAConstraint: +# jdkCA # -# DecimalDigits: -# DecimalDigit {DecimalDigit} +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD # -# DecimalDigit: one of -# 1 2 3 4 5 6 7 8 9 0 +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] # # The "AlgorithmName" is the standard algorithm name of the disabled # algorithm. See "Java Cryptography Architecture Standard Algorithm Name @@ -464,15 +470,69 @@ krb5.kdc.bad.policy = tryLast # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # will not disable algorithms related to "ECDSA". # -# A "Constraint" provides further guidance for the algorithm being specified. -# The "KeySizeConstraint" requires a key of a valid size range if the -# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the -# key size specified in number of bits. For example, "RSA keySize <= 1024" -# indicates that any RSA key with key size less than or equal to 1024 bits -# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates -# that any RSA key with key size less than 1024 or greater than 2048 should -# be disabled. Note that the "KeySizeConstraint" only makes sense to key -# algorithms. +# A "Constraint" defines restrictions on the keys and/or certificates for +# a specified AlgorithmName: +# +# KeySizeConstraint: +# keySize Operator KeyLength +# The constraint requires a key of a valid size range if the +# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates +# the key size specified in number of bits. For example, +# "RSA keySize <= 1024" indicates that any RSA key with key size less +# than or equal to 1024 bits should be disabled, and +# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key +# with key size less than 1024 or greater than 2048 should be disabled. +# This constraint is only used on algorithms that have a key size. +# +# CAConstraint: +# jdkCA +# This constraint prohibits the specified algorithm only if the +# algorithm is used in a certificate chain that terminates at a marked +# trust anchor in the lib/security/cacerts keystore. If the jdkCA +# constraint is not set, then all chains using the specified algorithm +# are restricted. jdkCA may only be used once in a DisabledAlgorithm +# expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following: "SHA1 jdkCA" +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# This constraint prohibits a certificate with the specified algorithm +# from being used after the date regardless of the certificate's +# validity. JAR files that are signed and timestamped before the +# constraint date with certificates containing the disabled algorithm +# will not be restricted. The date is processed in the UTC timezone. +# This constraint can only be used once in a DisabledAlgorithm +# expression. +# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020, +# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03" +# +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] +# This constraint prohibits the specified algorithm for +# a specified usage. This should be used when disabling an algorithm +# for all usages is not practical. 'TLSServer' restricts the algorithm +# in TLS server certificate chains when server authentication is +# performed. 'TLSClient' restricts the algorithm in TLS client +# certificate chains when client authentication is performed. +# 'SignedJAR' constrains use of certificates in signed jar files. +# The usage type follows the keyword and more than one usage type can +# be specified with a whitespace delimiter. +# Example: "SHA1 usage TLSServer TLSClient" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. # # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. @@ -481,8 +541,53 @@ krb5.kdc.bad.policy = tryLast # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 # # -jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \ + RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 + +# +# Algorithm restrictions for signed JAR files +# +# In some environments, certain algorithms or key lengths may be undesirable +# for signed JAR validation. For example, "MD2" is generally no longer +# considered to be a secure hash algorithm. This section describes the +# mechanism for disabling algorithms based on algorithm name and/or key length. +# JARs signed with any of the disabled algorithms or key sizes will be treated +# as unsigned. +# +# The syntax of the disabled algorithm string is described as follows: +# DisabledAlgorithms: +# " DisabledAlgorithm { , DisabledAlgorithm } " +# +# DisabledAlgorithm: +# AlgorithmName [Constraint] { '&' Constraint } +# +# AlgorithmName: +# (see below) +# +# Constraint: +# KeySizeConstraint | DenyAfterConstraint +# +# KeySizeConstraint: +# keySize Operator KeyLength +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# +# Operator: +# <= | < | == | != | >= | > +# +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# Note: This property is currently used by the JDK Reference +# implementation. It is not guaranteed to be examined and used by other +# implementations. +# +# See "jdk.certpath.disabledAlgorithms" for syntax descriptions. +# +jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +# # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing # @@ -504,12 +609,16 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 # See the specification of "jdk.certpath.disabledAlgorithms" for the # syntax of the disabled algorithm string. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. +# +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -523,7 +632,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -553,7 +662,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -566,7 +675,8 @@ jdk.tls.legacyAlgorithms= \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing. @@ -624,3 +734,178 @@ jdk.tls.legacyAlgorithms= \ # E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ # EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ # FFFFFFFF FFFFFFFF, 2} + +# Cryptographic Jurisdiction Policy defaults +# +# Due to the import control restrictions of some countries, the default +# JCE policy files allow for strong but "limited" cryptographic key +# lengths to be used. If your country's cryptographic regulations allow, +# the "unlimited" strength policy files can be used instead, which contain +# no restrictions on cryptographic strengths. +# +# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY +# TO DETERMINE THE EXACT REQUIREMENTS. +# +# (below) refers to the directory where the JRE was +# installed. It is determined based on whether you are running JCE +# on a JRE or a JRE contained within the Java Development Kit, or +# JDK(TM). The JDK contains the JRE, but at a different level in the +# file hierarchy. For example, if the JDK is installed in +# /home/user1/jdk1.8.0 on Unix or in C:\jdk1.8.0 on Windows, then +# is: +# +# /home/user1/jdk1.8.0/jre [Unix] +# C:\jdk1.8.0\jre [Windows] +# +# If on the other hand the JRE is installed in /home/user1/jre1.8.0 +# on Unix or in C:\jre1.8.0 on Windows, and the JDK is not +# installed, then is: +# +# /home/user1/jre1.8.0 [Unix] +# C:\jre1.8.0 [Windows] +# +# On Windows, for each JDK installation, there may be additional +# JREs installed under the "Program Files" directory. Please make +# sure that you install the unlimited strength policy JAR files +# for all JREs that you plan to use. +# +# The policy files are jar files organized into subdirectories of +# /lib/security/policy. Each directory contains a complete +# set of policy files. +# +# The "crypto.policy" Security property controls the directory selection, +# and thus the effective cryptographic policy. +# +# The default set of directories is: +# +# limited | unlimited +# +# however other directories can be created and configured. +# +# To support older JDK Update releases, the crypto.policy property +# is not defined by default. When the property is not defined, an +# update release binary aware of the new property will use the following +# logic to decide what crypto policy files get used : +# +# * If the US_export_policy.jar and local_policy.jar files are located +# in the (legacy) /lib/security directory, then the rules +# embedded in those jar files will be used. This helps preserve compatibility +# for users upgrading from an older installation. +# +# * If crypto.policy is not defined and no such jar files are present in +# the legacy locations, then the JDK will use the limited settings +# (equivalent to crypto.policy=limited) +# +# Please see the JCA documentation for additional information on these +# files and formats. +crypto.policy=unlimited + +# +# The policy for the XML Signature secure validation mode. The mode is +# enabled by setting the property "org.jcp.xml.dsig.secureValidation" to +# true with the javax.xml.crypto.XMLCryptoContext.setProperty() method, +# or by running the code with a SecurityManager. +# +# Policy: +# Constraint {"," Constraint } +# Constraint: +# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint +# AlgConstraint +# "disallowAlg" Uri +# MaxTransformsConstraint: +# "maxTransforms" Integer +# MaxReferencesConstraint: +# "maxReferences" Integer +# ReferenceUriSchemeConstraint: +# "disallowReferenceUriSchemes" String { String } +# KeySizeConstraint: +# "minKeySize" KeyAlg Integer +# OtherConstraint: +# "noDuplicateIds" | "noRetrievalMethodLoops" +# +# For AlgConstraint, Uri is the algorithm URI String that is not allowed. +# See the XML Signature Recommendation for more information on algorithm +# URI Identifiers. For KeySizeConstraint, KeyAlg is the standard algorithm +# name of the key type (ex: "RSA"). If the MaxTransformsConstraint, +# MaxReferencesConstraint or KeySizeConstraint (for the same key type) is +# specified more than once, only the last entry is enforced. +# +# Note: This property is currently used by the JDK Reference implementation. It +# is not guaranteed to be examined and used by other implementations. +# +jdk.xml.dsig.secureValidationPolicy=\ + disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\ + maxTransforms 5,\ + maxReferences 30,\ + disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ + noDuplicateIds,\ + noRetrievalMethodLoops + +# +# Serialization process-wide filter +# +# A filter, if configured, is used by java.io.ObjectInputStream during +# deserialization to check the contents of the stream. +# A filter is configured as a sequence of patterns, each pattern is either +# matched against the name of a class in the stream or defines a limit. +# Patterns are separated by ";" (semicolon). +# Whitespace is significant and is considered part of the pattern. +# +# If a pattern includes a "=", it sets a limit. +# If a limit appears more than once the last value is used. +# Limits are checked before classes regardless of the order in the sequence of patterns. +# If any of the limits are exceeded, the filter status is REJECTED. +# +# maxdepth=value - the maximum depth of a graph +# maxrefs=value - the maximum number of internal references +# maxbytes=value - the maximum number of bytes in the input stream +# maxarray=value - the maximum array length allowed +# +# Other patterns, from left to right, match the class or package name as +# returned from Class.getName. +# If the class is an array type, the class or package to be matched is the element type. +# Arrays of any number of dimensions are treated the same as the element type. +# For example, a pattern of "!example.Foo", rejects creation of any instance or +# array of example.Foo. +# +# If the pattern starts with "!", the status is REJECTED if the remaining pattern +# is matched; otherwise the status is ALLOWED if the pattern matches. +# If the pattern ends with ".**" it matches any class in the package and all subpackages. +# If the pattern ends with ".*" it matches any class in the package. +# If the pattern ends with "*", it matches any class with the pattern as a prefix. +# If the pattern is equal to the class name, it matches. +# Otherwise, the status is UNDECIDED. +# +#jdk.serialFilter=pattern;pattern + +# +# RMI Registry Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI Registry. +# +#sun.rmi.registry.registryFilter=pattern;pattern + +# +# RMI Distributed Garbage Collector (DGC) Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI DGC. +# +# The builtin DGC filter can approximately be represented as the filter pattern: +# +#sun.rmi.transport.dgcFilter=\ +# java.rmi.server.ObjID;\ +# java.rmi.server.UID;\ +# java.rmi.dgc.VMID;\ +# java.rmi.dgc.Lease;\ +# maxdepth=5;maxarray=10000 + diff --git a/src/IKVM.Image.runtime.linux-musl-x64/ikvm/any/linux-musl-x64/lib/security/java.security b/src/IKVM.Image.runtime.linux-musl-x64/ikvm/any/linux-musl-x64/lib/security/java.security index 12d1fd8efd..0a769887ed 100644 --- a/src/IKVM.Image.runtime.linux-musl-x64/ikvm/any/linux-musl-x64/lib/security/java.security +++ b/src/IKVM.Image.runtime.linux-musl-x64/ikvm/any/linux-musl-x64/lib/security/java.security @@ -209,6 +209,8 @@ package.access=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -220,7 +222,8 @@ package.access=sun.,\ jdk.internal.,\ jdk.nashorn.internal.,\ jdk.nashorn.tools.,\ - com.sun.activation.registries. + com.sun.activation.registries.,\ + com.sun.java.accessibility. # # List of comma-separated packages that start with or equal this string @@ -256,6 +259,8 @@ package.definition=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -267,7 +272,8 @@ package.definition=sun.,\ jdk.internal.,\ jdk.nashorn.internal.,\ jdk.nashorn.tools.,\ - com.sun.activation.registries. + com.sun.activation.registries.,\ + com.sun.java.accessibility. # # Determines whether this properties file can be appended to @@ -422,35 +428,37 @@ krb5.kdc.bad.policy = tryLast # describes the mechanism for disabling algorithms based on algorithm name # and/or key length. This includes algorithms used in certificates, as well # as revocation information such as CRLs and signed OCSP Responses. -# -# The syntax of the disabled algorithm string is described as this Java -# BNF-style: +# The syntax of the disabled algorithm string is described as follows: # DisabledAlgorithms: # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint | CAConstraint | DenyAfterConstraint | +# UsageConstraint # # KeySizeConstraint: -# keySize Operator DecimalInteger +# keySize Operator KeyLength # # Operator: # <= | < | == | != | >= | > # -# DecimalInteger: -# DecimalDigits +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# CAConstraint: +# jdkCA # -# DecimalDigits: -# DecimalDigit {DecimalDigit} +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD # -# DecimalDigit: one of -# 1 2 3 4 5 6 7 8 9 0 +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] # # The "AlgorithmName" is the standard algorithm name of the disabled # algorithm. See "Java Cryptography Architecture Standard Algorithm Name @@ -464,15 +472,69 @@ krb5.kdc.bad.policy = tryLast # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # will not disable algorithms related to "ECDSA". # -# A "Constraint" provides further guidance for the algorithm being specified. -# The "KeySizeConstraint" requires a key of a valid size range if the -# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the -# key size specified in number of bits. For example, "RSA keySize <= 1024" -# indicates that any RSA key with key size less than or equal to 1024 bits -# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates -# that any RSA key with key size less than 1024 or greater than 2048 should -# be disabled. Note that the "KeySizeConstraint" only makes sense to key -# algorithms. +# A "Constraint" defines restrictions on the keys and/or certificates for +# a specified AlgorithmName: +# +# KeySizeConstraint: +# keySize Operator KeyLength +# The constraint requires a key of a valid size range if the +# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates +# the key size specified in number of bits. For example, +# "RSA keySize <= 1024" indicates that any RSA key with key size less +# than or equal to 1024 bits should be disabled, and +# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key +# with key size less than 1024 or greater than 2048 should be disabled. +# This constraint is only used on algorithms that have a key size. +# +# CAConstraint: +# jdkCA +# This constraint prohibits the specified algorithm only if the +# algorithm is used in a certificate chain that terminates at a marked +# trust anchor in the lib/security/cacerts keystore. If the jdkCA +# constraint is not set, then all chains using the specified algorithm +# are restricted. jdkCA may only be used once in a DisabledAlgorithm +# expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following: "SHA1 jdkCA" +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# This constraint prohibits a certificate with the specified algorithm +# from being used after the date regardless of the certificate's +# validity. JAR files that are signed and timestamped before the +# constraint date with certificates containing the disabled algorithm +# will not be restricted. The date is processed in the UTC timezone. +# This constraint can only be used once in a DisabledAlgorithm +# expression. +# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020, +# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03" +# +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] +# This constraint prohibits the specified algorithm for +# a specified usage. This should be used when disabling an algorithm +# for all usages is not practical. 'TLSServer' restricts the algorithm +# in TLS server certificate chains when server authentication is +# performed. 'TLSClient' restricts the algorithm in TLS client +# certificate chains when client authentication is performed. +# 'SignedJAR' constrains use of certificates in signed jar files. +# The usage type follows the keyword and more than one usage type can +# be specified with a whitespace delimiter. +# Example: "SHA1 usage TLSServer TLSClient" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. # # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. @@ -481,8 +543,53 @@ krb5.kdc.bad.policy = tryLast # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 # # -jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \ + RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 +# +# Algorithm restrictions for signed JAR files +# +# In some environments, certain algorithms or key lengths may be undesirable +# for signed JAR validation. For example, "MD2" is generally no longer +# considered to be a secure hash algorithm. This section describes the +# mechanism for disabling algorithms based on algorithm name and/or key length. +# JARs signed with any of the disabled algorithms or key sizes will be treated +# as unsigned. +# +# The syntax of the disabled algorithm string is described as follows: +# DisabledAlgorithms: +# " DisabledAlgorithm { , DisabledAlgorithm } " +# +# DisabledAlgorithm: +# AlgorithmName [Constraint] { '&' Constraint } +# +# AlgorithmName: +# (see below) +# +# Constraint: +# KeySizeConstraint | DenyAfterConstraint +# +# KeySizeConstraint: +# keySize Operator KeyLength +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# +# Operator: +# <= | < | == | != | >= | > +# +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# Note: This property is currently used by the JDK Reference +# implementation. It is not guaranteed to be examined and used by other +# implementations. +# +# See "jdk.certpath.disabledAlgorithms" for syntax descriptions. +# +jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 + +# # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing # @@ -504,12 +611,16 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 # See the specification of "jdk.certpath.disabledAlgorithms" for the # syntax of the disabled algorithm string. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. +# +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -523,7 +634,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -553,7 +664,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -566,7 +677,8 @@ jdk.tls.legacyAlgorithms= \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing. @@ -624,3 +736,177 @@ jdk.tls.legacyAlgorithms= \ # E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ # EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ # FFFFFFFF FFFFFFFF, 2} + +# Cryptographic Jurisdiction Policy defaults +# +# Due to the import control restrictions of some countries, the default +# JCE policy files allow for strong but "limited" cryptographic key +# lengths to be used. If your country's cryptographic regulations allow, +# the "unlimited" strength policy files can be used instead, which contain +# no restrictions on cryptographic strengths. +# +# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY +# TO DETERMINE THE EXACT REQUIREMENTS. +# +# (below) refers to the directory where the JRE was +# installed. It is determined based on whether you are running JCE +# on a JRE or a JRE contained within the Java Development Kit, or +# JDK(TM). The JDK contains the JRE, but at a different level in the +# file hierarchy. For example, if the JDK is installed in +# /home/user1/jdk1.8.0 on Unix or in C:\jdk1.8.0 on Windows, then +# is: +# +# /home/user1/jdk1.8.0/jre [Unix] +# C:\jdk1.8.0\jre [Windows] +# +# If on the other hand the JRE is installed in /home/user1/jre1.8.0 +# on Unix or in C:\jre1.8.0 on Windows, and the JDK is not +# installed, then is: +# +# /home/user1/jre1.8.0 [Unix] +# C:\jre1.8.0 [Windows] +# +# On Windows, for each JDK installation, there may be additional +# JREs installed under the "Program Files" directory. Please make +# sure that you install the unlimited strength policy JAR files +# for all JREs that you plan to use. +# +# The policy files are jar files organized into subdirectories of +# /lib/security/policy. Each directory contains a complete +# set of policy files. +# +# The "crypto.policy" Security property controls the directory selection, +# and thus the effective cryptographic policy. +# +# The default set of directories is: +# +# limited | unlimited +# +# however other directories can be created and configured. +# +# To support older JDK Update releases, the crypto.policy property +# is not defined by default. When the property is not defined, an +# update release binary aware of the new property will use the following +# logic to decide what crypto policy files get used : +# +# * If the US_export_policy.jar and local_policy.jar files are located +# in the (legacy) /lib/security directory, then the rules +# embedded in those jar files will be used. This helps preserve compatibility +# for users upgrading from an older installation. +# +# * If crypto.policy is not defined and no such jar files are present in +# the legacy locations, then the JDK will use the limited settings +# (equivalent to crypto.policy=limited) +# +# Please see the JCA documentation for additional information on these +# files and formats. +crypto.policy=unlimited + +# +# The policy for the XML Signature secure validation mode. The mode is +# enabled by setting the property "org.jcp.xml.dsig.secureValidation" to +# true with the javax.xml.crypto.XMLCryptoContext.setProperty() method, +# or by running the code with a SecurityManager. +# +# Policy: +# Constraint {"," Constraint } +# Constraint: +# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint +# AlgConstraint +# "disallowAlg" Uri +# MaxTransformsConstraint: +# "maxTransforms" Integer +# MaxReferencesConstraint: +# "maxReferences" Integer +# ReferenceUriSchemeConstraint: +# "disallowReferenceUriSchemes" String { String } +# KeySizeConstraint: +# "minKeySize" KeyAlg Integer +# OtherConstraint: +# "noDuplicateIds" | "noRetrievalMethodLoops" +# +# For AlgConstraint, Uri is the algorithm URI String that is not allowed. +# See the XML Signature Recommendation for more information on algorithm +# URI Identifiers. For KeySizeConstraint, KeyAlg is the standard algorithm +# name of the key type (ex: "RSA"). If the MaxTransformsConstraint, +# MaxReferencesConstraint or KeySizeConstraint (for the same key type) is +# specified more than once, only the last entry is enforced. +# +# Note: This property is currently used by the JDK Reference implementation. It +# is not guaranteed to be examined and used by other implementations. +# +jdk.xml.dsig.secureValidationPolicy=\ + disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\ + maxTransforms 5,\ + maxReferences 30,\ + disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ + noDuplicateIds,\ + noRetrievalMethodLoops + +# +# Serialization process-wide filter +# +# A filter, if configured, is used by java.io.ObjectInputStream during +# deserialization to check the contents of the stream. +# A filter is configured as a sequence of patterns, each pattern is either +# matched against the name of a class in the stream or defines a limit. +# Patterns are separated by ";" (semicolon). +# Whitespace is significant and is considered part of the pattern. +# +# If a pattern includes a "=", it sets a limit. +# If a limit appears more than once the last value is used. +# Limits are checked before classes regardless of the order in the sequence of patterns. +# If any of the limits are exceeded, the filter status is REJECTED. +# +# maxdepth=value - the maximum depth of a graph +# maxrefs=value - the maximum number of internal references +# maxbytes=value - the maximum number of bytes in the input stream +# maxarray=value - the maximum array length allowed +# +# Other patterns, from left to right, match the class or package name as +# returned from Class.getName. +# If the class is an array type, the class or package to be matched is the element type. +# Arrays of any number of dimensions are treated the same as the element type. +# For example, a pattern of "!example.Foo", rejects creation of any instance or +# array of example.Foo. +# +# If the pattern starts with "!", the status is REJECTED if the remaining pattern +# is matched; otherwise the status is ALLOWED if the pattern matches. +# If the pattern ends with ".**" it matches any class in the package and all subpackages. +# If the pattern ends with ".*" it matches any class in the package. +# If the pattern ends with "*", it matches any class with the pattern as a prefix. +# If the pattern is equal to the class name, it matches. +# Otherwise, the status is UNDECIDED. +# +#jdk.serialFilter=pattern;pattern + +# +# RMI Registry Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI Registry. +# +#sun.rmi.registry.registryFilter=pattern;pattern + +# +# RMI Distributed Garbage Collector (DGC) Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI DGC. +# +# The builtin DGC filter can approximately be represented as the filter pattern: +# +#sun.rmi.transport.dgcFilter=\ +# java.rmi.server.ObjID;\ +# java.rmi.server.UID;\ +# java.rmi.dgc.VMID;\ +# java.rmi.dgc.Lease;\ +# maxdepth=5;maxarray=10000 diff --git a/src/IKVM.Image.runtime.linux-x64/ikvm/any/linux-x64/lib/security/java.security b/src/IKVM.Image.runtime.linux-x64/ikvm/any/linux-x64/lib/security/java.security index 12d1fd8efd..d8162670a2 100644 --- a/src/IKVM.Image.runtime.linux-x64/ikvm/any/linux-x64/lib/security/java.security +++ b/src/IKVM.Image.runtime.linux-x64/ikvm/any/linux-x64/lib/security/java.security @@ -209,6 +209,8 @@ package.access=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -256,6 +258,8 @@ package.definition=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -422,35 +426,37 @@ krb5.kdc.bad.policy = tryLast # describes the mechanism for disabling algorithms based on algorithm name # and/or key length. This includes algorithms used in certificates, as well # as revocation information such as CRLs and signed OCSP Responses. -# -# The syntax of the disabled algorithm string is described as this Java -# BNF-style: +# The syntax of the disabled algorithm string is described as follows: # DisabledAlgorithms: # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint | CAConstraint | DenyAfterConstraint | +# UsageConstraint # # KeySizeConstraint: -# keySize Operator DecimalInteger +# keySize Operator KeyLength # # Operator: # <= | < | == | != | >= | > # -# DecimalInteger: -# DecimalDigits +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# CAConstraint: +# jdkCA # -# DecimalDigits: -# DecimalDigit {DecimalDigit} +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD # -# DecimalDigit: one of -# 1 2 3 4 5 6 7 8 9 0 +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] # # The "AlgorithmName" is the standard algorithm name of the disabled # algorithm. See "Java Cryptography Architecture Standard Algorithm Name @@ -464,15 +470,69 @@ krb5.kdc.bad.policy = tryLast # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # will not disable algorithms related to "ECDSA". # -# A "Constraint" provides further guidance for the algorithm being specified. -# The "KeySizeConstraint" requires a key of a valid size range if the -# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the -# key size specified in number of bits. For example, "RSA keySize <= 1024" -# indicates that any RSA key with key size less than or equal to 1024 bits -# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates -# that any RSA key with key size less than 1024 or greater than 2048 should -# be disabled. Note that the "KeySizeConstraint" only makes sense to key -# algorithms. +# A "Constraint" defines restrictions on the keys and/or certificates for +# a specified AlgorithmName: +# +# KeySizeConstraint: +# keySize Operator KeyLength +# The constraint requires a key of a valid size range if the +# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates +# the key size specified in number of bits. For example, +# "RSA keySize <= 1024" indicates that any RSA key with key size less +# than or equal to 1024 bits should be disabled, and +# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key +# with key size less than 1024 or greater than 2048 should be disabled. +# This constraint is only used on algorithms that have a key size. +# +# CAConstraint: +# jdkCA +# This constraint prohibits the specified algorithm only if the +# algorithm is used in a certificate chain that terminates at a marked +# trust anchor in the lib/security/cacerts keystore. If the jdkCA +# constraint is not set, then all chains using the specified algorithm +# are restricted. jdkCA may only be used once in a DisabledAlgorithm +# expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following: "SHA1 jdkCA" +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# This constraint prohibits a certificate with the specified algorithm +# from being used after the date regardless of the certificate's +# validity. JAR files that are signed and timestamped before the +# constraint date with certificates containing the disabled algorithm +# will not be restricted. The date is processed in the UTC timezone. +# This constraint can only be used once in a DisabledAlgorithm +# expression. +# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020, +# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03" +# +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] +# This constraint prohibits the specified algorithm for +# a specified usage. This should be used when disabling an algorithm +# for all usages is not practical. 'TLSServer' restricts the algorithm +# in TLS server certificate chains when server authentication is +# performed. 'TLSClient' restricts the algorithm in TLS client +# certificate chains when client authentication is performed. +# 'SignedJAR' constrains use of certificates in signed jar files. +# The usage type follows the keyword and more than one usage type can +# be specified with a whitespace delimiter. +# Example: "SHA1 usage TLSServer TLSClient" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. # # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. @@ -481,8 +541,53 @@ krb5.kdc.bad.policy = tryLast # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 # # -jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \ + RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 + +# +# Algorithm restrictions for signed JAR files +# +# In some environments, certain algorithms or key lengths may be undesirable +# for signed JAR validation. For example, "MD2" is generally no longer +# considered to be a secure hash algorithm. This section describes the +# mechanism for disabling algorithms based on algorithm name and/or key length. +# JARs signed with any of the disabled algorithms or key sizes will be treated +# as unsigned. +# +# The syntax of the disabled algorithm string is described as follows: +# DisabledAlgorithms: +# " DisabledAlgorithm { , DisabledAlgorithm } " +# +# DisabledAlgorithm: +# AlgorithmName [Constraint] { '&' Constraint } +# +# AlgorithmName: +# (see below) +# +# Constraint: +# KeySizeConstraint | DenyAfterConstraint +# +# KeySizeConstraint: +# keySize Operator KeyLength +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# +# Operator: +# <= | < | == | != | >= | > +# +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# Note: This property is currently used by the JDK Reference +# implementation. It is not guaranteed to be examined and used by other +# implementations. +# +# See "jdk.certpath.disabledAlgorithms" for syntax descriptions. +# +jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +# # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing # @@ -504,12 +609,16 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 # See the specification of "jdk.certpath.disabledAlgorithms" for the # syntax of the disabled algorithm string. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. +# +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -523,7 +632,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -553,7 +662,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -566,7 +675,8 @@ jdk.tls.legacyAlgorithms= \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing. @@ -624,3 +734,178 @@ jdk.tls.legacyAlgorithms= \ # E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ # EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ # FFFFFFFF FFFFFFFF, 2} + +# Cryptographic Jurisdiction Policy defaults +# +# Due to the import control restrictions of some countries, the default +# JCE policy files allow for strong but "limited" cryptographic key +# lengths to be used. If your country's cryptographic regulations allow, +# the "unlimited" strength policy files can be used instead, which contain +# no restrictions on cryptographic strengths. +# +# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY +# TO DETERMINE THE EXACT REQUIREMENTS. +# +# (below) refers to the directory where the JRE was +# installed. It is determined based on whether you are running JCE +# on a JRE or a JRE contained within the Java Development Kit, or +# JDK(TM). The JDK contains the JRE, but at a different level in the +# file hierarchy. For example, if the JDK is installed in +# /home/user1/jdk1.8.0 on Unix or in C:\jdk1.8.0 on Windows, then +# is: +# +# /home/user1/jdk1.8.0/jre [Unix] +# C:\jdk1.8.0\jre [Windows] +# +# If on the other hand the JRE is installed in /home/user1/jre1.8.0 +# on Unix or in C:\jre1.8.0 on Windows, and the JDK is not +# installed, then is: +# +# /home/user1/jre1.8.0 [Unix] +# C:\jre1.8.0 [Windows] +# +# On Windows, for each JDK installation, there may be additional +# JREs installed under the "Program Files" directory. Please make +# sure that you install the unlimited strength policy JAR files +# for all JREs that you plan to use. +# +# The policy files are jar files organized into subdirectories of +# /lib/security/policy. Each directory contains a complete +# set of policy files. +# +# The "crypto.policy" Security property controls the directory selection, +# and thus the effective cryptographic policy. +# +# The default set of directories is: +# +# limited | unlimited +# +# however other directories can be created and configured. +# +# To support older JDK Update releases, the crypto.policy property +# is not defined by default. When the property is not defined, an +# update release binary aware of the new property will use the following +# logic to decide what crypto policy files get used : +# +# * If the US_export_policy.jar and local_policy.jar files are located +# in the (legacy) /lib/security directory, then the rules +# embedded in those jar files will be used. This helps preserve compatibility +# for users upgrading from an older installation. +# +# * If crypto.policy is not defined and no such jar files are present in +# the legacy locations, then the JDK will use the limited settings +# (equivalent to crypto.policy=limited) +# +# Please see the JCA documentation for additional information on these +# files and formats. +crypto.policy=unlimited + +# +# The policy for the XML Signature secure validation mode. The mode is +# enabled by setting the property "org.jcp.xml.dsig.secureValidation" to +# true with the javax.xml.crypto.XMLCryptoContext.setProperty() method, +# or by running the code with a SecurityManager. +# +# Policy: +# Constraint {"," Constraint } +# Constraint: +# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint +# AlgConstraint +# "disallowAlg" Uri +# MaxTransformsConstraint: +# "maxTransforms" Integer +# MaxReferencesConstraint: +# "maxReferences" Integer +# ReferenceUriSchemeConstraint: +# "disallowReferenceUriSchemes" String { String } +# KeySizeConstraint: +# "minKeySize" KeyAlg Integer +# OtherConstraint: +# "noDuplicateIds" | "noRetrievalMethodLoops" +# +# For AlgConstraint, Uri is the algorithm URI String that is not allowed. +# See the XML Signature Recommendation for more information on algorithm +# URI Identifiers. For KeySizeConstraint, KeyAlg is the standard algorithm +# name of the key type (ex: "RSA"). If the MaxTransformsConstraint, +# MaxReferencesConstraint or KeySizeConstraint (for the same key type) is +# specified more than once, only the last entry is enforced. +# +# Note: This property is currently used by the JDK Reference implementation. It +# is not guaranteed to be examined and used by other implementations. +# +jdk.xml.dsig.secureValidationPolicy=\ + disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\ + maxTransforms 5,\ + maxReferences 30,\ + disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ + noDuplicateIds,\ + noRetrievalMethodLoops + +# +# Serialization process-wide filter +# +# A filter, if configured, is used by java.io.ObjectInputStream during +# deserialization to check the contents of the stream. +# A filter is configured as a sequence of patterns, each pattern is either +# matched against the name of a class in the stream or defines a limit. +# Patterns are separated by ";" (semicolon). +# Whitespace is significant and is considered part of the pattern. +# +# If a pattern includes a "=", it sets a limit. +# If a limit appears more than once the last value is used. +# Limits are checked before classes regardless of the order in the sequence of patterns. +# If any of the limits are exceeded, the filter status is REJECTED. +# +# maxdepth=value - the maximum depth of a graph +# maxrefs=value - the maximum number of internal references +# maxbytes=value - the maximum number of bytes in the input stream +# maxarray=value - the maximum array length allowed +# +# Other patterns, from left to right, match the class or package name as +# returned from Class.getName. +# If the class is an array type, the class or package to be matched is the element type. +# Arrays of any number of dimensions are treated the same as the element type. +# For example, a pattern of "!example.Foo", rejects creation of any instance or +# array of example.Foo. +# +# If the pattern starts with "!", the status is REJECTED if the remaining pattern +# is matched; otherwise the status is ALLOWED if the pattern matches. +# If the pattern ends with ".**" it matches any class in the package and all subpackages. +# If the pattern ends with ".*" it matches any class in the package. +# If the pattern ends with "*", it matches any class with the pattern as a prefix. +# If the pattern is equal to the class name, it matches. +# Otherwise, the status is UNDECIDED. +# +#jdk.serialFilter=pattern;pattern + +# +# RMI Registry Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI Registry. +# +#sun.rmi.registry.registryFilter=pattern;pattern + +# +# RMI Distributed Garbage Collector (DGC) Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI DGC. +# +# The builtin DGC filter can approximately be represented as the filter pattern: +# +#sun.rmi.transport.dgcFilter=\ +# java.rmi.server.ObjID;\ +# java.rmi.server.UID;\ +# java.rmi.dgc.VMID;\ +# java.rmi.dgc.Lease;\ +# maxdepth=5;maxarray=10000 + diff --git a/src/IKVM.Image.runtime.osx-arm64/ikvm/any/osx-arm64/lib/security/java.security b/src/IKVM.Image.runtime.osx-arm64/ikvm/any/osx-arm64/lib/security/java.security index 12d1fd8efd..2a917e4a69 100644 --- a/src/IKVM.Image.runtime.osx-arm64/ikvm/any/osx-arm64/lib/security/java.security +++ b/src/IKVM.Image.runtime.osx-arm64/ikvm/any/osx-arm64/lib/security/java.security @@ -209,6 +209,8 @@ package.access=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -220,7 +222,8 @@ package.access=sun.,\ jdk.internal.,\ jdk.nashorn.internal.,\ jdk.nashorn.tools.,\ - com.sun.activation.registries. + com.sun.activation.registries.,\ + apple. # # List of comma-separated packages that start with or equal this string @@ -256,6 +259,8 @@ package.definition=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -267,7 +272,8 @@ package.definition=sun.,\ jdk.internal.,\ jdk.nashorn.internal.,\ jdk.nashorn.tools.,\ - com.sun.activation.registries. + com.sun.activation.registries.,\ + apple. # # Determines whether this properties file can be appended to @@ -422,35 +428,37 @@ krb5.kdc.bad.policy = tryLast # describes the mechanism for disabling algorithms based on algorithm name # and/or key length. This includes algorithms used in certificates, as well # as revocation information such as CRLs and signed OCSP Responses. -# -# The syntax of the disabled algorithm string is described as this Java -# BNF-style: +# The syntax of the disabled algorithm string is described as follows: # DisabledAlgorithms: # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint | CAConstraint | DenyAfterConstraint | +# UsageConstraint # # KeySizeConstraint: -# keySize Operator DecimalInteger +# keySize Operator KeyLength # # Operator: # <= | < | == | != | >= | > # -# DecimalInteger: -# DecimalDigits +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# CAConstraint: +# jdkCA # -# DecimalDigits: -# DecimalDigit {DecimalDigit} +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD # -# DecimalDigit: one of -# 1 2 3 4 5 6 7 8 9 0 +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] # # The "AlgorithmName" is the standard algorithm name of the disabled # algorithm. See "Java Cryptography Architecture Standard Algorithm Name @@ -464,15 +472,69 @@ krb5.kdc.bad.policy = tryLast # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # will not disable algorithms related to "ECDSA". # -# A "Constraint" provides further guidance for the algorithm being specified. -# The "KeySizeConstraint" requires a key of a valid size range if the -# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the -# key size specified in number of bits. For example, "RSA keySize <= 1024" -# indicates that any RSA key with key size less than or equal to 1024 bits -# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates -# that any RSA key with key size less than 1024 or greater than 2048 should -# be disabled. Note that the "KeySizeConstraint" only makes sense to key -# algorithms. +# A "Constraint" defines restrictions on the keys and/or certificates for +# a specified AlgorithmName: +# +# KeySizeConstraint: +# keySize Operator KeyLength +# The constraint requires a key of a valid size range if the +# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates +# the key size specified in number of bits. For example, +# "RSA keySize <= 1024" indicates that any RSA key with key size less +# than or equal to 1024 bits should be disabled, and +# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key +# with key size less than 1024 or greater than 2048 should be disabled. +# This constraint is only used on algorithms that have a key size. +# +# CAConstraint: +# jdkCA +# This constraint prohibits the specified algorithm only if the +# algorithm is used in a certificate chain that terminates at a marked +# trust anchor in the lib/security/cacerts keystore. If the jdkCA +# constraint is not set, then all chains using the specified algorithm +# are restricted. jdkCA may only be used once in a DisabledAlgorithm +# expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following: "SHA1 jdkCA" +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# This constraint prohibits a certificate with the specified algorithm +# from being used after the date regardless of the certificate's +# validity. JAR files that are signed and timestamped before the +# constraint date with certificates containing the disabled algorithm +# will not be restricted. The date is processed in the UTC timezone. +# This constraint can only be used once in a DisabledAlgorithm +# expression. +# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020, +# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03" +# +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] +# This constraint prohibits the specified algorithm for +# a specified usage. This should be used when disabling an algorithm +# for all usages is not practical. 'TLSServer' restricts the algorithm +# in TLS server certificate chains when server authentication is +# performed. 'TLSClient' restricts the algorithm in TLS client +# certificate chains when client authentication is performed. +# 'SignedJAR' constrains use of certificates in signed jar files. +# The usage type follows the keyword and more than one usage type can +# be specified with a whitespace delimiter. +# Example: "SHA1 usage TLSServer TLSClient" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. # # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. @@ -481,8 +543,53 @@ krb5.kdc.bad.policy = tryLast # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 # # -jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \ + RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 +# +# Algorithm restrictions for signed JAR files +# +# In some environments, certain algorithms or key lengths may be undesirable +# for signed JAR validation. For example, "MD2" is generally no longer +# considered to be a secure hash algorithm. This section describes the +# mechanism for disabling algorithms based on algorithm name and/or key length. +# JARs signed with any of the disabled algorithms or key sizes will be treated +# as unsigned. +# +# The syntax of the disabled algorithm string is described as follows: +# DisabledAlgorithms: +# " DisabledAlgorithm { , DisabledAlgorithm } " +# +# DisabledAlgorithm: +# AlgorithmName [Constraint] { '&' Constraint } +# +# AlgorithmName: +# (see below) +# +# Constraint: +# KeySizeConstraint | DenyAfterConstraint +# +# KeySizeConstraint: +# keySize Operator KeyLength +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# +# Operator: +# <= | < | == | != | >= | > +# +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# Note: This property is currently used by the JDK Reference +# implementation. It is not guaranteed to be examined and used by other +# implementations. +# +# See "jdk.certpath.disabledAlgorithms" for syntax descriptions. +# +jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 + +# # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing # @@ -504,12 +611,16 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 # See the specification of "jdk.certpath.disabledAlgorithms" for the # syntax of the disabled algorithm string. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. +# +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -523,7 +634,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -553,7 +664,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -566,7 +677,8 @@ jdk.tls.legacyAlgorithms= \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing. @@ -624,3 +736,177 @@ jdk.tls.legacyAlgorithms= \ # E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ # EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ # FFFFFFFF FFFFFFFF, 2} + +# Cryptographic Jurisdiction Policy defaults +# +# Due to the import control restrictions of some countries, the default +# JCE policy files allow for strong but "limited" cryptographic key +# lengths to be used. If your country's cryptographic regulations allow, +# the "unlimited" strength policy files can be used instead, which contain +# no restrictions on cryptographic strengths. +# +# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY +# TO DETERMINE THE EXACT REQUIREMENTS. +# +# (below) refers to the directory where the JRE was +# installed. It is determined based on whether you are running JCE +# on a JRE or a JRE contained within the Java Development Kit, or +# JDK(TM). The JDK contains the JRE, but at a different level in the +# file hierarchy. For example, if the JDK is installed in +# /home/user1/jdk1.8.0 on Unix or in C:\jdk1.8.0 on Windows, then +# is: +# +# /home/user1/jdk1.8.0/jre [Unix] +# C:\jdk1.8.0\jre [Windows] +# +# If on the other hand the JRE is installed in /home/user1/jre1.8.0 +# on Unix or in C:\jre1.8.0 on Windows, and the JDK is not +# installed, then is: +# +# /home/user1/jre1.8.0 [Unix] +# C:\jre1.8.0 [Windows] +# +# On Windows, for each JDK installation, there may be additional +# JREs installed under the "Program Files" directory. Please make +# sure that you install the unlimited strength policy JAR files +# for all JREs that you plan to use. +# +# The policy files are jar files organized into subdirectories of +# /lib/security/policy. Each directory contains a complete +# set of policy files. +# +# The "crypto.policy" Security property controls the directory selection, +# and thus the effective cryptographic policy. +# +# The default set of directories is: +# +# limited | unlimited +# +# however other directories can be created and configured. +# +# To support older JDK Update releases, the crypto.policy property +# is not defined by default. When the property is not defined, an +# update release binary aware of the new property will use the following +# logic to decide what crypto policy files get used : +# +# * If the US_export_policy.jar and local_policy.jar files are located +# in the (legacy) /lib/security directory, then the rules +# embedded in those jar files will be used. This helps preserve compatibility +# for users upgrading from an older installation. +# +# * If crypto.policy is not defined and no such jar files are present in +# the legacy locations, then the JDK will use the limited settings +# (equivalent to crypto.policy=limited) +# +# Please see the JCA documentation for additional information on these +# files and formats. +crypto.policy=unlimited + +# +# The policy for the XML Signature secure validation mode. The mode is +# enabled by setting the property "org.jcp.xml.dsig.secureValidation" to +# true with the javax.xml.crypto.XMLCryptoContext.setProperty() method, +# or by running the code with a SecurityManager. +# +# Policy: +# Constraint {"," Constraint } +# Constraint: +# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint +# AlgConstraint +# "disallowAlg" Uri +# MaxTransformsConstraint: +# "maxTransforms" Integer +# MaxReferencesConstraint: +# "maxReferences" Integer +# ReferenceUriSchemeConstraint: +# "disallowReferenceUriSchemes" String { String } +# KeySizeConstraint: +# "minKeySize" KeyAlg Integer +# OtherConstraint: +# "noDuplicateIds" | "noRetrievalMethodLoops" +# +# For AlgConstraint, Uri is the algorithm URI String that is not allowed. +# See the XML Signature Recommendation for more information on algorithm +# URI Identifiers. For KeySizeConstraint, KeyAlg is the standard algorithm +# name of the key type (ex: "RSA"). If the MaxTransformsConstraint, +# MaxReferencesConstraint or KeySizeConstraint (for the same key type) is +# specified more than once, only the last entry is enforced. +# +# Note: This property is currently used by the JDK Reference implementation. It +# is not guaranteed to be examined and used by other implementations. +# +jdk.xml.dsig.secureValidationPolicy=\ + disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\ + maxTransforms 5,\ + maxReferences 30,\ + disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ + noDuplicateIds,\ + noRetrievalMethodLoops + +# +# Serialization process-wide filter +# +# A filter, if configured, is used by java.io.ObjectInputStream during +# deserialization to check the contents of the stream. +# A filter is configured as a sequence of patterns, each pattern is either +# matched against the name of a class in the stream or defines a limit. +# Patterns are separated by ";" (semicolon). +# Whitespace is significant and is considered part of the pattern. +# +# If a pattern includes a "=", it sets a limit. +# If a limit appears more than once the last value is used. +# Limits are checked before classes regardless of the order in the sequence of patterns. +# If any of the limits are exceeded, the filter status is REJECTED. +# +# maxdepth=value - the maximum depth of a graph +# maxrefs=value - the maximum number of internal references +# maxbytes=value - the maximum number of bytes in the input stream +# maxarray=value - the maximum array length allowed +# +# Other patterns, from left to right, match the class or package name as +# returned from Class.getName. +# If the class is an array type, the class or package to be matched is the element type. +# Arrays of any number of dimensions are treated the same as the element type. +# For example, a pattern of "!example.Foo", rejects creation of any instance or +# array of example.Foo. +# +# If the pattern starts with "!", the status is REJECTED if the remaining pattern +# is matched; otherwise the status is ALLOWED if the pattern matches. +# If the pattern ends with ".**" it matches any class in the package and all subpackages. +# If the pattern ends with ".*" it matches any class in the package. +# If the pattern ends with "*", it matches any class with the pattern as a prefix. +# If the pattern is equal to the class name, it matches. +# Otherwise, the status is UNDECIDED. +# +#jdk.serialFilter=pattern;pattern + +# +# RMI Registry Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI Registry. +# +#sun.rmi.registry.registryFilter=pattern;pattern + +# +# RMI Distributed Garbage Collector (DGC) Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI DGC. +# +# The builtin DGC filter can approximately be represented as the filter pattern: +# +#sun.rmi.transport.dgcFilter=\ +# java.rmi.server.ObjID;\ +# java.rmi.server.UID;\ +# java.rmi.dgc.VMID;\ +# java.rmi.dgc.Lease;\ +# maxdepth=5;maxarray=10000 diff --git a/src/IKVM.Image.runtime.osx-x64/ikvm/any/osx-x64/lib/security/java.security b/src/IKVM.Image.runtime.osx-x64/ikvm/any/osx-x64/lib/security/java.security index 12d1fd8efd..d8162670a2 100644 --- a/src/IKVM.Image.runtime.osx-x64/ikvm/any/osx-x64/lib/security/java.security +++ b/src/IKVM.Image.runtime.osx-x64/ikvm/any/osx-x64/lib/security/java.security @@ -209,6 +209,8 @@ package.access=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -256,6 +258,8 @@ package.definition=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -422,35 +426,37 @@ krb5.kdc.bad.policy = tryLast # describes the mechanism for disabling algorithms based on algorithm name # and/or key length. This includes algorithms used in certificates, as well # as revocation information such as CRLs and signed OCSP Responses. -# -# The syntax of the disabled algorithm string is described as this Java -# BNF-style: +# The syntax of the disabled algorithm string is described as follows: # DisabledAlgorithms: # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint | CAConstraint | DenyAfterConstraint | +# UsageConstraint # # KeySizeConstraint: -# keySize Operator DecimalInteger +# keySize Operator KeyLength # # Operator: # <= | < | == | != | >= | > # -# DecimalInteger: -# DecimalDigits +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# CAConstraint: +# jdkCA # -# DecimalDigits: -# DecimalDigit {DecimalDigit} +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD # -# DecimalDigit: one of -# 1 2 3 4 5 6 7 8 9 0 +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] # # The "AlgorithmName" is the standard algorithm name of the disabled # algorithm. See "Java Cryptography Architecture Standard Algorithm Name @@ -464,15 +470,69 @@ krb5.kdc.bad.policy = tryLast # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # will not disable algorithms related to "ECDSA". # -# A "Constraint" provides further guidance for the algorithm being specified. -# The "KeySizeConstraint" requires a key of a valid size range if the -# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the -# key size specified in number of bits. For example, "RSA keySize <= 1024" -# indicates that any RSA key with key size less than or equal to 1024 bits -# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates -# that any RSA key with key size less than 1024 or greater than 2048 should -# be disabled. Note that the "KeySizeConstraint" only makes sense to key -# algorithms. +# A "Constraint" defines restrictions on the keys and/or certificates for +# a specified AlgorithmName: +# +# KeySizeConstraint: +# keySize Operator KeyLength +# The constraint requires a key of a valid size range if the +# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates +# the key size specified in number of bits. For example, +# "RSA keySize <= 1024" indicates that any RSA key with key size less +# than or equal to 1024 bits should be disabled, and +# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key +# with key size less than 1024 or greater than 2048 should be disabled. +# This constraint is only used on algorithms that have a key size. +# +# CAConstraint: +# jdkCA +# This constraint prohibits the specified algorithm only if the +# algorithm is used in a certificate chain that terminates at a marked +# trust anchor in the lib/security/cacerts keystore. If the jdkCA +# constraint is not set, then all chains using the specified algorithm +# are restricted. jdkCA may only be used once in a DisabledAlgorithm +# expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following: "SHA1 jdkCA" +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# This constraint prohibits a certificate with the specified algorithm +# from being used after the date regardless of the certificate's +# validity. JAR files that are signed and timestamped before the +# constraint date with certificates containing the disabled algorithm +# will not be restricted. The date is processed in the UTC timezone. +# This constraint can only be used once in a DisabledAlgorithm +# expression. +# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020, +# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03" +# +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] +# This constraint prohibits the specified algorithm for +# a specified usage. This should be used when disabling an algorithm +# for all usages is not practical. 'TLSServer' restricts the algorithm +# in TLS server certificate chains when server authentication is +# performed. 'TLSClient' restricts the algorithm in TLS client +# certificate chains when client authentication is performed. +# 'SignedJAR' constrains use of certificates in signed jar files. +# The usage type follows the keyword and more than one usage type can +# be specified with a whitespace delimiter. +# Example: "SHA1 usage TLSServer TLSClient" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. # # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. @@ -481,8 +541,53 @@ krb5.kdc.bad.policy = tryLast # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 # # -jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \ + RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 + +# +# Algorithm restrictions for signed JAR files +# +# In some environments, certain algorithms or key lengths may be undesirable +# for signed JAR validation. For example, "MD2" is generally no longer +# considered to be a secure hash algorithm. This section describes the +# mechanism for disabling algorithms based on algorithm name and/or key length. +# JARs signed with any of the disabled algorithms or key sizes will be treated +# as unsigned. +# +# The syntax of the disabled algorithm string is described as follows: +# DisabledAlgorithms: +# " DisabledAlgorithm { , DisabledAlgorithm } " +# +# DisabledAlgorithm: +# AlgorithmName [Constraint] { '&' Constraint } +# +# AlgorithmName: +# (see below) +# +# Constraint: +# KeySizeConstraint | DenyAfterConstraint +# +# KeySizeConstraint: +# keySize Operator KeyLength +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# +# Operator: +# <= | < | == | != | >= | > +# +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# Note: This property is currently used by the JDK Reference +# implementation. It is not guaranteed to be examined and used by other +# implementations. +# +# See "jdk.certpath.disabledAlgorithms" for syntax descriptions. +# +jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +# # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing # @@ -504,12 +609,16 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 # See the specification of "jdk.certpath.disabledAlgorithms" for the # syntax of the disabled algorithm string. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. +# +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -523,7 +632,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -553,7 +662,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -566,7 +675,8 @@ jdk.tls.legacyAlgorithms= \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing. @@ -624,3 +734,178 @@ jdk.tls.legacyAlgorithms= \ # E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ # EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ # FFFFFFFF FFFFFFFF, 2} + +# Cryptographic Jurisdiction Policy defaults +# +# Due to the import control restrictions of some countries, the default +# JCE policy files allow for strong but "limited" cryptographic key +# lengths to be used. If your country's cryptographic regulations allow, +# the "unlimited" strength policy files can be used instead, which contain +# no restrictions on cryptographic strengths. +# +# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY +# TO DETERMINE THE EXACT REQUIREMENTS. +# +# (below) refers to the directory where the JRE was +# installed. It is determined based on whether you are running JCE +# on a JRE or a JRE contained within the Java Development Kit, or +# JDK(TM). The JDK contains the JRE, but at a different level in the +# file hierarchy. For example, if the JDK is installed in +# /home/user1/jdk1.8.0 on Unix or in C:\jdk1.8.0 on Windows, then +# is: +# +# /home/user1/jdk1.8.0/jre [Unix] +# C:\jdk1.8.0\jre [Windows] +# +# If on the other hand the JRE is installed in /home/user1/jre1.8.0 +# on Unix or in C:\jre1.8.0 on Windows, and the JDK is not +# installed, then is: +# +# /home/user1/jre1.8.0 [Unix] +# C:\jre1.8.0 [Windows] +# +# On Windows, for each JDK installation, there may be additional +# JREs installed under the "Program Files" directory. Please make +# sure that you install the unlimited strength policy JAR files +# for all JREs that you plan to use. +# +# The policy files are jar files organized into subdirectories of +# /lib/security/policy. Each directory contains a complete +# set of policy files. +# +# The "crypto.policy" Security property controls the directory selection, +# and thus the effective cryptographic policy. +# +# The default set of directories is: +# +# limited | unlimited +# +# however other directories can be created and configured. +# +# To support older JDK Update releases, the crypto.policy property +# is not defined by default. When the property is not defined, an +# update release binary aware of the new property will use the following +# logic to decide what crypto policy files get used : +# +# * If the US_export_policy.jar and local_policy.jar files are located +# in the (legacy) /lib/security directory, then the rules +# embedded in those jar files will be used. This helps preserve compatibility +# for users upgrading from an older installation. +# +# * If crypto.policy is not defined and no such jar files are present in +# the legacy locations, then the JDK will use the limited settings +# (equivalent to crypto.policy=limited) +# +# Please see the JCA documentation for additional information on these +# files and formats. +crypto.policy=unlimited + +# +# The policy for the XML Signature secure validation mode. The mode is +# enabled by setting the property "org.jcp.xml.dsig.secureValidation" to +# true with the javax.xml.crypto.XMLCryptoContext.setProperty() method, +# or by running the code with a SecurityManager. +# +# Policy: +# Constraint {"," Constraint } +# Constraint: +# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint +# AlgConstraint +# "disallowAlg" Uri +# MaxTransformsConstraint: +# "maxTransforms" Integer +# MaxReferencesConstraint: +# "maxReferences" Integer +# ReferenceUriSchemeConstraint: +# "disallowReferenceUriSchemes" String { String } +# KeySizeConstraint: +# "minKeySize" KeyAlg Integer +# OtherConstraint: +# "noDuplicateIds" | "noRetrievalMethodLoops" +# +# For AlgConstraint, Uri is the algorithm URI String that is not allowed. +# See the XML Signature Recommendation for more information on algorithm +# URI Identifiers. For KeySizeConstraint, KeyAlg is the standard algorithm +# name of the key type (ex: "RSA"). If the MaxTransformsConstraint, +# MaxReferencesConstraint or KeySizeConstraint (for the same key type) is +# specified more than once, only the last entry is enforced. +# +# Note: This property is currently used by the JDK Reference implementation. It +# is not guaranteed to be examined and used by other implementations. +# +jdk.xml.dsig.secureValidationPolicy=\ + disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\ + maxTransforms 5,\ + maxReferences 30,\ + disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ + noDuplicateIds,\ + noRetrievalMethodLoops + +# +# Serialization process-wide filter +# +# A filter, if configured, is used by java.io.ObjectInputStream during +# deserialization to check the contents of the stream. +# A filter is configured as a sequence of patterns, each pattern is either +# matched against the name of a class in the stream or defines a limit. +# Patterns are separated by ";" (semicolon). +# Whitespace is significant and is considered part of the pattern. +# +# If a pattern includes a "=", it sets a limit. +# If a limit appears more than once the last value is used. +# Limits are checked before classes regardless of the order in the sequence of patterns. +# If any of the limits are exceeded, the filter status is REJECTED. +# +# maxdepth=value - the maximum depth of a graph +# maxrefs=value - the maximum number of internal references +# maxbytes=value - the maximum number of bytes in the input stream +# maxarray=value - the maximum array length allowed +# +# Other patterns, from left to right, match the class or package name as +# returned from Class.getName. +# If the class is an array type, the class or package to be matched is the element type. +# Arrays of any number of dimensions are treated the same as the element type. +# For example, a pattern of "!example.Foo", rejects creation of any instance or +# array of example.Foo. +# +# If the pattern starts with "!", the status is REJECTED if the remaining pattern +# is matched; otherwise the status is ALLOWED if the pattern matches. +# If the pattern ends with ".**" it matches any class in the package and all subpackages. +# If the pattern ends with ".*" it matches any class in the package. +# If the pattern ends with "*", it matches any class with the pattern as a prefix. +# If the pattern is equal to the class name, it matches. +# Otherwise, the status is UNDECIDED. +# +#jdk.serialFilter=pattern;pattern + +# +# RMI Registry Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI Registry. +# +#sun.rmi.registry.registryFilter=pattern;pattern + +# +# RMI Distributed Garbage Collector (DGC) Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI DGC. +# +# The builtin DGC filter can approximately be represented as the filter pattern: +# +#sun.rmi.transport.dgcFilter=\ +# java.rmi.server.ObjID;\ +# java.rmi.server.UID;\ +# java.rmi.dgc.VMID;\ +# java.rmi.dgc.Lease;\ +# maxdepth=5;maxarray=10000 + diff --git a/src/IKVM.Image.runtime.win-arm64/ikvm/any/win-arm64/lib/security/java.security b/src/IKVM.Image.runtime.win-arm64/ikvm/any/win-arm64/lib/security/java.security index 12d1fd8efd..0a769887ed 100644 --- a/src/IKVM.Image.runtime.win-arm64/ikvm/any/win-arm64/lib/security/java.security +++ b/src/IKVM.Image.runtime.win-arm64/ikvm/any/win-arm64/lib/security/java.security @@ -209,6 +209,8 @@ package.access=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -220,7 +222,8 @@ package.access=sun.,\ jdk.internal.,\ jdk.nashorn.internal.,\ jdk.nashorn.tools.,\ - com.sun.activation.registries. + com.sun.activation.registries.,\ + com.sun.java.accessibility. # # List of comma-separated packages that start with or equal this string @@ -256,6 +259,8 @@ package.definition=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -267,7 +272,8 @@ package.definition=sun.,\ jdk.internal.,\ jdk.nashorn.internal.,\ jdk.nashorn.tools.,\ - com.sun.activation.registries. + com.sun.activation.registries.,\ + com.sun.java.accessibility. # # Determines whether this properties file can be appended to @@ -422,35 +428,37 @@ krb5.kdc.bad.policy = tryLast # describes the mechanism for disabling algorithms based on algorithm name # and/or key length. This includes algorithms used in certificates, as well # as revocation information such as CRLs and signed OCSP Responses. -# -# The syntax of the disabled algorithm string is described as this Java -# BNF-style: +# The syntax of the disabled algorithm string is described as follows: # DisabledAlgorithms: # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint | CAConstraint | DenyAfterConstraint | +# UsageConstraint # # KeySizeConstraint: -# keySize Operator DecimalInteger +# keySize Operator KeyLength # # Operator: # <= | < | == | != | >= | > # -# DecimalInteger: -# DecimalDigits +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# CAConstraint: +# jdkCA # -# DecimalDigits: -# DecimalDigit {DecimalDigit} +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD # -# DecimalDigit: one of -# 1 2 3 4 5 6 7 8 9 0 +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] # # The "AlgorithmName" is the standard algorithm name of the disabled # algorithm. See "Java Cryptography Architecture Standard Algorithm Name @@ -464,15 +472,69 @@ krb5.kdc.bad.policy = tryLast # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # will not disable algorithms related to "ECDSA". # -# A "Constraint" provides further guidance for the algorithm being specified. -# The "KeySizeConstraint" requires a key of a valid size range if the -# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the -# key size specified in number of bits. For example, "RSA keySize <= 1024" -# indicates that any RSA key with key size less than or equal to 1024 bits -# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates -# that any RSA key with key size less than 1024 or greater than 2048 should -# be disabled. Note that the "KeySizeConstraint" only makes sense to key -# algorithms. +# A "Constraint" defines restrictions on the keys and/or certificates for +# a specified AlgorithmName: +# +# KeySizeConstraint: +# keySize Operator KeyLength +# The constraint requires a key of a valid size range if the +# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates +# the key size specified in number of bits. For example, +# "RSA keySize <= 1024" indicates that any RSA key with key size less +# than or equal to 1024 bits should be disabled, and +# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key +# with key size less than 1024 or greater than 2048 should be disabled. +# This constraint is only used on algorithms that have a key size. +# +# CAConstraint: +# jdkCA +# This constraint prohibits the specified algorithm only if the +# algorithm is used in a certificate chain that terminates at a marked +# trust anchor in the lib/security/cacerts keystore. If the jdkCA +# constraint is not set, then all chains using the specified algorithm +# are restricted. jdkCA may only be used once in a DisabledAlgorithm +# expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following: "SHA1 jdkCA" +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# This constraint prohibits a certificate with the specified algorithm +# from being used after the date regardless of the certificate's +# validity. JAR files that are signed and timestamped before the +# constraint date with certificates containing the disabled algorithm +# will not be restricted. The date is processed in the UTC timezone. +# This constraint can only be used once in a DisabledAlgorithm +# expression. +# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020, +# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03" +# +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] +# This constraint prohibits the specified algorithm for +# a specified usage. This should be used when disabling an algorithm +# for all usages is not practical. 'TLSServer' restricts the algorithm +# in TLS server certificate chains when server authentication is +# performed. 'TLSClient' restricts the algorithm in TLS client +# certificate chains when client authentication is performed. +# 'SignedJAR' constrains use of certificates in signed jar files. +# The usage type follows the keyword and more than one usage type can +# be specified with a whitespace delimiter. +# Example: "SHA1 usage TLSServer TLSClient" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. # # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. @@ -481,8 +543,53 @@ krb5.kdc.bad.policy = tryLast # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 # # -jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \ + RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 +# +# Algorithm restrictions for signed JAR files +# +# In some environments, certain algorithms or key lengths may be undesirable +# for signed JAR validation. For example, "MD2" is generally no longer +# considered to be a secure hash algorithm. This section describes the +# mechanism for disabling algorithms based on algorithm name and/or key length. +# JARs signed with any of the disabled algorithms or key sizes will be treated +# as unsigned. +# +# The syntax of the disabled algorithm string is described as follows: +# DisabledAlgorithms: +# " DisabledAlgorithm { , DisabledAlgorithm } " +# +# DisabledAlgorithm: +# AlgorithmName [Constraint] { '&' Constraint } +# +# AlgorithmName: +# (see below) +# +# Constraint: +# KeySizeConstraint | DenyAfterConstraint +# +# KeySizeConstraint: +# keySize Operator KeyLength +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# +# Operator: +# <= | < | == | != | >= | > +# +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# Note: This property is currently used by the JDK Reference +# implementation. It is not guaranteed to be examined and used by other +# implementations. +# +# See "jdk.certpath.disabledAlgorithms" for syntax descriptions. +# +jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 + +# # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing # @@ -504,12 +611,16 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 # See the specification of "jdk.certpath.disabledAlgorithms" for the # syntax of the disabled algorithm string. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. +# +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -523,7 +634,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -553,7 +664,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -566,7 +677,8 @@ jdk.tls.legacyAlgorithms= \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing. @@ -624,3 +736,177 @@ jdk.tls.legacyAlgorithms= \ # E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ # EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ # FFFFFFFF FFFFFFFF, 2} + +# Cryptographic Jurisdiction Policy defaults +# +# Due to the import control restrictions of some countries, the default +# JCE policy files allow for strong but "limited" cryptographic key +# lengths to be used. If your country's cryptographic regulations allow, +# the "unlimited" strength policy files can be used instead, which contain +# no restrictions on cryptographic strengths. +# +# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY +# TO DETERMINE THE EXACT REQUIREMENTS. +# +# (below) refers to the directory where the JRE was +# installed. It is determined based on whether you are running JCE +# on a JRE or a JRE contained within the Java Development Kit, or +# JDK(TM). The JDK contains the JRE, but at a different level in the +# file hierarchy. For example, if the JDK is installed in +# /home/user1/jdk1.8.0 on Unix or in C:\jdk1.8.0 on Windows, then +# is: +# +# /home/user1/jdk1.8.0/jre [Unix] +# C:\jdk1.8.0\jre [Windows] +# +# If on the other hand the JRE is installed in /home/user1/jre1.8.0 +# on Unix or in C:\jre1.8.0 on Windows, and the JDK is not +# installed, then is: +# +# /home/user1/jre1.8.0 [Unix] +# C:\jre1.8.0 [Windows] +# +# On Windows, for each JDK installation, there may be additional +# JREs installed under the "Program Files" directory. Please make +# sure that you install the unlimited strength policy JAR files +# for all JREs that you plan to use. +# +# The policy files are jar files organized into subdirectories of +# /lib/security/policy. Each directory contains a complete +# set of policy files. +# +# The "crypto.policy" Security property controls the directory selection, +# and thus the effective cryptographic policy. +# +# The default set of directories is: +# +# limited | unlimited +# +# however other directories can be created and configured. +# +# To support older JDK Update releases, the crypto.policy property +# is not defined by default. When the property is not defined, an +# update release binary aware of the new property will use the following +# logic to decide what crypto policy files get used : +# +# * If the US_export_policy.jar and local_policy.jar files are located +# in the (legacy) /lib/security directory, then the rules +# embedded in those jar files will be used. This helps preserve compatibility +# for users upgrading from an older installation. +# +# * If crypto.policy is not defined and no such jar files are present in +# the legacy locations, then the JDK will use the limited settings +# (equivalent to crypto.policy=limited) +# +# Please see the JCA documentation for additional information on these +# files and formats. +crypto.policy=unlimited + +# +# The policy for the XML Signature secure validation mode. The mode is +# enabled by setting the property "org.jcp.xml.dsig.secureValidation" to +# true with the javax.xml.crypto.XMLCryptoContext.setProperty() method, +# or by running the code with a SecurityManager. +# +# Policy: +# Constraint {"," Constraint } +# Constraint: +# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint +# AlgConstraint +# "disallowAlg" Uri +# MaxTransformsConstraint: +# "maxTransforms" Integer +# MaxReferencesConstraint: +# "maxReferences" Integer +# ReferenceUriSchemeConstraint: +# "disallowReferenceUriSchemes" String { String } +# KeySizeConstraint: +# "minKeySize" KeyAlg Integer +# OtherConstraint: +# "noDuplicateIds" | "noRetrievalMethodLoops" +# +# For AlgConstraint, Uri is the algorithm URI String that is not allowed. +# See the XML Signature Recommendation for more information on algorithm +# URI Identifiers. For KeySizeConstraint, KeyAlg is the standard algorithm +# name of the key type (ex: "RSA"). If the MaxTransformsConstraint, +# MaxReferencesConstraint or KeySizeConstraint (for the same key type) is +# specified more than once, only the last entry is enforced. +# +# Note: This property is currently used by the JDK Reference implementation. It +# is not guaranteed to be examined and used by other implementations. +# +jdk.xml.dsig.secureValidationPolicy=\ + disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\ + maxTransforms 5,\ + maxReferences 30,\ + disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ + noDuplicateIds,\ + noRetrievalMethodLoops + +# +# Serialization process-wide filter +# +# A filter, if configured, is used by java.io.ObjectInputStream during +# deserialization to check the contents of the stream. +# A filter is configured as a sequence of patterns, each pattern is either +# matched against the name of a class in the stream or defines a limit. +# Patterns are separated by ";" (semicolon). +# Whitespace is significant and is considered part of the pattern. +# +# If a pattern includes a "=", it sets a limit. +# If a limit appears more than once the last value is used. +# Limits are checked before classes regardless of the order in the sequence of patterns. +# If any of the limits are exceeded, the filter status is REJECTED. +# +# maxdepth=value - the maximum depth of a graph +# maxrefs=value - the maximum number of internal references +# maxbytes=value - the maximum number of bytes in the input stream +# maxarray=value - the maximum array length allowed +# +# Other patterns, from left to right, match the class or package name as +# returned from Class.getName. +# If the class is an array type, the class or package to be matched is the element type. +# Arrays of any number of dimensions are treated the same as the element type. +# For example, a pattern of "!example.Foo", rejects creation of any instance or +# array of example.Foo. +# +# If the pattern starts with "!", the status is REJECTED if the remaining pattern +# is matched; otherwise the status is ALLOWED if the pattern matches. +# If the pattern ends with ".**" it matches any class in the package and all subpackages. +# If the pattern ends with ".*" it matches any class in the package. +# If the pattern ends with "*", it matches any class with the pattern as a prefix. +# If the pattern is equal to the class name, it matches. +# Otherwise, the status is UNDECIDED. +# +#jdk.serialFilter=pattern;pattern + +# +# RMI Registry Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI Registry. +# +#sun.rmi.registry.registryFilter=pattern;pattern + +# +# RMI Distributed Garbage Collector (DGC) Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI DGC. +# +# The builtin DGC filter can approximately be represented as the filter pattern: +# +#sun.rmi.transport.dgcFilter=\ +# java.rmi.server.ObjID;\ +# java.rmi.server.UID;\ +# java.rmi.dgc.VMID;\ +# java.rmi.dgc.Lease;\ +# maxdepth=5;maxarray=10000 diff --git a/src/IKVM.Image.runtime.win-x64/ikvm/any/win-x64/lib/security/java.security b/src/IKVM.Image.runtime.win-x64/ikvm/any/win-x64/lib/security/java.security index 12d1fd8efd..d8162670a2 100644 --- a/src/IKVM.Image.runtime.win-x64/ikvm/any/win-x64/lib/security/java.security +++ b/src/IKVM.Image.runtime.win-x64/ikvm/any/win-x64/lib/security/java.security @@ -209,6 +209,8 @@ package.access=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -256,6 +258,8 @@ package.definition=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -422,35 +426,37 @@ krb5.kdc.bad.policy = tryLast # describes the mechanism for disabling algorithms based on algorithm name # and/or key length. This includes algorithms used in certificates, as well # as revocation information such as CRLs and signed OCSP Responses. -# -# The syntax of the disabled algorithm string is described as this Java -# BNF-style: +# The syntax of the disabled algorithm string is described as follows: # DisabledAlgorithms: # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint | CAConstraint | DenyAfterConstraint | +# UsageConstraint # # KeySizeConstraint: -# keySize Operator DecimalInteger +# keySize Operator KeyLength # # Operator: # <= | < | == | != | >= | > # -# DecimalInteger: -# DecimalDigits +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# CAConstraint: +# jdkCA # -# DecimalDigits: -# DecimalDigit {DecimalDigit} +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD # -# DecimalDigit: one of -# 1 2 3 4 5 6 7 8 9 0 +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] # # The "AlgorithmName" is the standard algorithm name of the disabled # algorithm. See "Java Cryptography Architecture Standard Algorithm Name @@ -464,15 +470,69 @@ krb5.kdc.bad.policy = tryLast # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # will not disable algorithms related to "ECDSA". # -# A "Constraint" provides further guidance for the algorithm being specified. -# The "KeySizeConstraint" requires a key of a valid size range if the -# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the -# key size specified in number of bits. For example, "RSA keySize <= 1024" -# indicates that any RSA key with key size less than or equal to 1024 bits -# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates -# that any RSA key with key size less than 1024 or greater than 2048 should -# be disabled. Note that the "KeySizeConstraint" only makes sense to key -# algorithms. +# A "Constraint" defines restrictions on the keys and/or certificates for +# a specified AlgorithmName: +# +# KeySizeConstraint: +# keySize Operator KeyLength +# The constraint requires a key of a valid size range if the +# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates +# the key size specified in number of bits. For example, +# "RSA keySize <= 1024" indicates that any RSA key with key size less +# than or equal to 1024 bits should be disabled, and +# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key +# with key size less than 1024 or greater than 2048 should be disabled. +# This constraint is only used on algorithms that have a key size. +# +# CAConstraint: +# jdkCA +# This constraint prohibits the specified algorithm only if the +# algorithm is used in a certificate chain that terminates at a marked +# trust anchor in the lib/security/cacerts keystore. If the jdkCA +# constraint is not set, then all chains using the specified algorithm +# are restricted. jdkCA may only be used once in a DisabledAlgorithm +# expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following: "SHA1 jdkCA" +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# This constraint prohibits a certificate with the specified algorithm +# from being used after the date regardless of the certificate's +# validity. JAR files that are signed and timestamped before the +# constraint date with certificates containing the disabled algorithm +# will not be restricted. The date is processed in the UTC timezone. +# This constraint can only be used once in a DisabledAlgorithm +# expression. +# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020, +# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03" +# +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] +# This constraint prohibits the specified algorithm for +# a specified usage. This should be used when disabling an algorithm +# for all usages is not practical. 'TLSServer' restricts the algorithm +# in TLS server certificate chains when server authentication is +# performed. 'TLSClient' restricts the algorithm in TLS client +# certificate chains when client authentication is performed. +# 'SignedJAR' constrains use of certificates in signed jar files. +# The usage type follows the keyword and more than one usage type can +# be specified with a whitespace delimiter. +# Example: "SHA1 usage TLSServer TLSClient" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. # # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. @@ -481,8 +541,53 @@ krb5.kdc.bad.policy = tryLast # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 # # -jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \ + RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 + +# +# Algorithm restrictions for signed JAR files +# +# In some environments, certain algorithms or key lengths may be undesirable +# for signed JAR validation. For example, "MD2" is generally no longer +# considered to be a secure hash algorithm. This section describes the +# mechanism for disabling algorithms based on algorithm name and/or key length. +# JARs signed with any of the disabled algorithms or key sizes will be treated +# as unsigned. +# +# The syntax of the disabled algorithm string is described as follows: +# DisabledAlgorithms: +# " DisabledAlgorithm { , DisabledAlgorithm } " +# +# DisabledAlgorithm: +# AlgorithmName [Constraint] { '&' Constraint } +# +# AlgorithmName: +# (see below) +# +# Constraint: +# KeySizeConstraint | DenyAfterConstraint +# +# KeySizeConstraint: +# keySize Operator KeyLength +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# +# Operator: +# <= | < | == | != | >= | > +# +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# Note: This property is currently used by the JDK Reference +# implementation. It is not guaranteed to be examined and used by other +# implementations. +# +# See "jdk.certpath.disabledAlgorithms" for syntax descriptions. +# +jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +# # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing # @@ -504,12 +609,16 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 # See the specification of "jdk.certpath.disabledAlgorithms" for the # syntax of the disabled algorithm string. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. +# +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -523,7 +632,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -553,7 +662,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -566,7 +675,8 @@ jdk.tls.legacyAlgorithms= \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing. @@ -624,3 +734,178 @@ jdk.tls.legacyAlgorithms= \ # E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ # EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ # FFFFFFFF FFFFFFFF, 2} + +# Cryptographic Jurisdiction Policy defaults +# +# Due to the import control restrictions of some countries, the default +# JCE policy files allow for strong but "limited" cryptographic key +# lengths to be used. If your country's cryptographic regulations allow, +# the "unlimited" strength policy files can be used instead, which contain +# no restrictions on cryptographic strengths. +# +# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY +# TO DETERMINE THE EXACT REQUIREMENTS. +# +# (below) refers to the directory where the JRE was +# installed. It is determined based on whether you are running JCE +# on a JRE or a JRE contained within the Java Development Kit, or +# JDK(TM). The JDK contains the JRE, but at a different level in the +# file hierarchy. For example, if the JDK is installed in +# /home/user1/jdk1.8.0 on Unix or in C:\jdk1.8.0 on Windows, then +# is: +# +# /home/user1/jdk1.8.0/jre [Unix] +# C:\jdk1.8.0\jre [Windows] +# +# If on the other hand the JRE is installed in /home/user1/jre1.8.0 +# on Unix or in C:\jre1.8.0 on Windows, and the JDK is not +# installed, then is: +# +# /home/user1/jre1.8.0 [Unix] +# C:\jre1.8.0 [Windows] +# +# On Windows, for each JDK installation, there may be additional +# JREs installed under the "Program Files" directory. Please make +# sure that you install the unlimited strength policy JAR files +# for all JREs that you plan to use. +# +# The policy files are jar files organized into subdirectories of +# /lib/security/policy. Each directory contains a complete +# set of policy files. +# +# The "crypto.policy" Security property controls the directory selection, +# and thus the effective cryptographic policy. +# +# The default set of directories is: +# +# limited | unlimited +# +# however other directories can be created and configured. +# +# To support older JDK Update releases, the crypto.policy property +# is not defined by default. When the property is not defined, an +# update release binary aware of the new property will use the following +# logic to decide what crypto policy files get used : +# +# * If the US_export_policy.jar and local_policy.jar files are located +# in the (legacy) /lib/security directory, then the rules +# embedded in those jar files will be used. This helps preserve compatibility +# for users upgrading from an older installation. +# +# * If crypto.policy is not defined and no such jar files are present in +# the legacy locations, then the JDK will use the limited settings +# (equivalent to crypto.policy=limited) +# +# Please see the JCA documentation for additional information on these +# files and formats. +crypto.policy=unlimited + +# +# The policy for the XML Signature secure validation mode. The mode is +# enabled by setting the property "org.jcp.xml.dsig.secureValidation" to +# true with the javax.xml.crypto.XMLCryptoContext.setProperty() method, +# or by running the code with a SecurityManager. +# +# Policy: +# Constraint {"," Constraint } +# Constraint: +# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint +# AlgConstraint +# "disallowAlg" Uri +# MaxTransformsConstraint: +# "maxTransforms" Integer +# MaxReferencesConstraint: +# "maxReferences" Integer +# ReferenceUriSchemeConstraint: +# "disallowReferenceUriSchemes" String { String } +# KeySizeConstraint: +# "minKeySize" KeyAlg Integer +# OtherConstraint: +# "noDuplicateIds" | "noRetrievalMethodLoops" +# +# For AlgConstraint, Uri is the algorithm URI String that is not allowed. +# See the XML Signature Recommendation for more information on algorithm +# URI Identifiers. For KeySizeConstraint, KeyAlg is the standard algorithm +# name of the key type (ex: "RSA"). If the MaxTransformsConstraint, +# MaxReferencesConstraint or KeySizeConstraint (for the same key type) is +# specified more than once, only the last entry is enforced. +# +# Note: This property is currently used by the JDK Reference implementation. It +# is not guaranteed to be examined and used by other implementations. +# +jdk.xml.dsig.secureValidationPolicy=\ + disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\ + maxTransforms 5,\ + maxReferences 30,\ + disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ + noDuplicateIds,\ + noRetrievalMethodLoops + +# +# Serialization process-wide filter +# +# A filter, if configured, is used by java.io.ObjectInputStream during +# deserialization to check the contents of the stream. +# A filter is configured as a sequence of patterns, each pattern is either +# matched against the name of a class in the stream or defines a limit. +# Patterns are separated by ";" (semicolon). +# Whitespace is significant and is considered part of the pattern. +# +# If a pattern includes a "=", it sets a limit. +# If a limit appears more than once the last value is used. +# Limits are checked before classes regardless of the order in the sequence of patterns. +# If any of the limits are exceeded, the filter status is REJECTED. +# +# maxdepth=value - the maximum depth of a graph +# maxrefs=value - the maximum number of internal references +# maxbytes=value - the maximum number of bytes in the input stream +# maxarray=value - the maximum array length allowed +# +# Other patterns, from left to right, match the class or package name as +# returned from Class.getName. +# If the class is an array type, the class or package to be matched is the element type. +# Arrays of any number of dimensions are treated the same as the element type. +# For example, a pattern of "!example.Foo", rejects creation of any instance or +# array of example.Foo. +# +# If the pattern starts with "!", the status is REJECTED if the remaining pattern +# is matched; otherwise the status is ALLOWED if the pattern matches. +# If the pattern ends with ".**" it matches any class in the package and all subpackages. +# If the pattern ends with ".*" it matches any class in the package. +# If the pattern ends with "*", it matches any class with the pattern as a prefix. +# If the pattern is equal to the class name, it matches. +# Otherwise, the status is UNDECIDED. +# +#jdk.serialFilter=pattern;pattern + +# +# RMI Registry Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI Registry. +# +#sun.rmi.registry.registryFilter=pattern;pattern + +# +# RMI Distributed Garbage Collector (DGC) Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI DGC. +# +# The builtin DGC filter can approximately be represented as the filter pattern: +# +#sun.rmi.transport.dgcFilter=\ +# java.rmi.server.ObjID;\ +# java.rmi.server.UID;\ +# java.rmi.dgc.VMID;\ +# java.rmi.dgc.Lease;\ +# maxdepth=5;maxarray=10000 + diff --git a/src/IKVM.Image.runtime.win-x86/ikvm/any/win-x86/lib/security/java.security b/src/IKVM.Image.runtime.win-x86/ikvm/any/win-x86/lib/security/java.security index 12d1fd8efd..d8162670a2 100644 --- a/src/IKVM.Image.runtime.win-x86/ikvm/any/win-x86/lib/security/java.security +++ b/src/IKVM.Image.runtime.win-x86/ikvm/any/win-x86/lib/security/java.security @@ -209,6 +209,8 @@ package.access=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -256,6 +258,8 @@ package.definition=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -422,35 +426,37 @@ krb5.kdc.bad.policy = tryLast # describes the mechanism for disabling algorithms based on algorithm name # and/or key length. This includes algorithms used in certificates, as well # as revocation information such as CRLs and signed OCSP Responses. -# -# The syntax of the disabled algorithm string is described as this Java -# BNF-style: +# The syntax of the disabled algorithm string is described as follows: # DisabledAlgorithms: # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint | CAConstraint | DenyAfterConstraint | +# UsageConstraint # # KeySizeConstraint: -# keySize Operator DecimalInteger +# keySize Operator KeyLength # # Operator: # <= | < | == | != | >= | > # -# DecimalInteger: -# DecimalDigits +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# CAConstraint: +# jdkCA # -# DecimalDigits: -# DecimalDigit {DecimalDigit} +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD # -# DecimalDigit: one of -# 1 2 3 4 5 6 7 8 9 0 +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] # # The "AlgorithmName" is the standard algorithm name of the disabled # algorithm. See "Java Cryptography Architecture Standard Algorithm Name @@ -464,15 +470,69 @@ krb5.kdc.bad.policy = tryLast # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # will not disable algorithms related to "ECDSA". # -# A "Constraint" provides further guidance for the algorithm being specified. -# The "KeySizeConstraint" requires a key of a valid size range if the -# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the -# key size specified in number of bits. For example, "RSA keySize <= 1024" -# indicates that any RSA key with key size less than or equal to 1024 bits -# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates -# that any RSA key with key size less than 1024 or greater than 2048 should -# be disabled. Note that the "KeySizeConstraint" only makes sense to key -# algorithms. +# A "Constraint" defines restrictions on the keys and/or certificates for +# a specified AlgorithmName: +# +# KeySizeConstraint: +# keySize Operator KeyLength +# The constraint requires a key of a valid size range if the +# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates +# the key size specified in number of bits. For example, +# "RSA keySize <= 1024" indicates that any RSA key with key size less +# than or equal to 1024 bits should be disabled, and +# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key +# with key size less than 1024 or greater than 2048 should be disabled. +# This constraint is only used on algorithms that have a key size. +# +# CAConstraint: +# jdkCA +# This constraint prohibits the specified algorithm only if the +# algorithm is used in a certificate chain that terminates at a marked +# trust anchor in the lib/security/cacerts keystore. If the jdkCA +# constraint is not set, then all chains using the specified algorithm +# are restricted. jdkCA may only be used once in a DisabledAlgorithm +# expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following: "SHA1 jdkCA" +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# This constraint prohibits a certificate with the specified algorithm +# from being used after the date regardless of the certificate's +# validity. JAR files that are signed and timestamped before the +# constraint date with certificates containing the disabled algorithm +# will not be restricted. The date is processed in the UTC timezone. +# This constraint can only be used once in a DisabledAlgorithm +# expression. +# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020, +# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03" +# +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] +# This constraint prohibits the specified algorithm for +# a specified usage. This should be used when disabling an algorithm +# for all usages is not practical. 'TLSServer' restricts the algorithm +# in TLS server certificate chains when server authentication is +# performed. 'TLSClient' restricts the algorithm in TLS client +# certificate chains when client authentication is performed. +# 'SignedJAR' constrains use of certificates in signed jar files. +# The usage type follows the keyword and more than one usage type can +# be specified with a whitespace delimiter. +# Example: "SHA1 usage TLSServer TLSClient" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. # # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. @@ -481,8 +541,53 @@ krb5.kdc.bad.policy = tryLast # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 # # -jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \ + RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 + +# +# Algorithm restrictions for signed JAR files +# +# In some environments, certain algorithms or key lengths may be undesirable +# for signed JAR validation. For example, "MD2" is generally no longer +# considered to be a secure hash algorithm. This section describes the +# mechanism for disabling algorithms based on algorithm name and/or key length. +# JARs signed with any of the disabled algorithms or key sizes will be treated +# as unsigned. +# +# The syntax of the disabled algorithm string is described as follows: +# DisabledAlgorithms: +# " DisabledAlgorithm { , DisabledAlgorithm } " +# +# DisabledAlgorithm: +# AlgorithmName [Constraint] { '&' Constraint } +# +# AlgorithmName: +# (see below) +# +# Constraint: +# KeySizeConstraint | DenyAfterConstraint +# +# KeySizeConstraint: +# keySize Operator KeyLength +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# +# Operator: +# <= | < | == | != | >= | > +# +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# Note: This property is currently used by the JDK Reference +# implementation. It is not guaranteed to be examined and used by other +# implementations. +# +# See "jdk.certpath.disabledAlgorithms" for syntax descriptions. +# +jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +# # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing # @@ -504,12 +609,16 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 # See the specification of "jdk.certpath.disabledAlgorithms" for the # syntax of the disabled algorithm string. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. +# +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -523,7 +632,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -553,7 +662,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -566,7 +675,8 @@ jdk.tls.legacyAlgorithms= \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing. @@ -624,3 +734,178 @@ jdk.tls.legacyAlgorithms= \ # E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ # EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ # FFFFFFFF FFFFFFFF, 2} + +# Cryptographic Jurisdiction Policy defaults +# +# Due to the import control restrictions of some countries, the default +# JCE policy files allow for strong but "limited" cryptographic key +# lengths to be used. If your country's cryptographic regulations allow, +# the "unlimited" strength policy files can be used instead, which contain +# no restrictions on cryptographic strengths. +# +# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY +# TO DETERMINE THE EXACT REQUIREMENTS. +# +# (below) refers to the directory where the JRE was +# installed. It is determined based on whether you are running JCE +# on a JRE or a JRE contained within the Java Development Kit, or +# JDK(TM). The JDK contains the JRE, but at a different level in the +# file hierarchy. For example, if the JDK is installed in +# /home/user1/jdk1.8.0 on Unix or in C:\jdk1.8.0 on Windows, then +# is: +# +# /home/user1/jdk1.8.0/jre [Unix] +# C:\jdk1.8.0\jre [Windows] +# +# If on the other hand the JRE is installed in /home/user1/jre1.8.0 +# on Unix or in C:\jre1.8.0 on Windows, and the JDK is not +# installed, then is: +# +# /home/user1/jre1.8.0 [Unix] +# C:\jre1.8.0 [Windows] +# +# On Windows, for each JDK installation, there may be additional +# JREs installed under the "Program Files" directory. Please make +# sure that you install the unlimited strength policy JAR files +# for all JREs that you plan to use. +# +# The policy files are jar files organized into subdirectories of +# /lib/security/policy. Each directory contains a complete +# set of policy files. +# +# The "crypto.policy" Security property controls the directory selection, +# and thus the effective cryptographic policy. +# +# The default set of directories is: +# +# limited | unlimited +# +# however other directories can be created and configured. +# +# To support older JDK Update releases, the crypto.policy property +# is not defined by default. When the property is not defined, an +# update release binary aware of the new property will use the following +# logic to decide what crypto policy files get used : +# +# * If the US_export_policy.jar and local_policy.jar files are located +# in the (legacy) /lib/security directory, then the rules +# embedded in those jar files will be used. This helps preserve compatibility +# for users upgrading from an older installation. +# +# * If crypto.policy is not defined and no such jar files are present in +# the legacy locations, then the JDK will use the limited settings +# (equivalent to crypto.policy=limited) +# +# Please see the JCA documentation for additional information on these +# files and formats. +crypto.policy=unlimited + +# +# The policy for the XML Signature secure validation mode. The mode is +# enabled by setting the property "org.jcp.xml.dsig.secureValidation" to +# true with the javax.xml.crypto.XMLCryptoContext.setProperty() method, +# or by running the code with a SecurityManager. +# +# Policy: +# Constraint {"," Constraint } +# Constraint: +# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint +# AlgConstraint +# "disallowAlg" Uri +# MaxTransformsConstraint: +# "maxTransforms" Integer +# MaxReferencesConstraint: +# "maxReferences" Integer +# ReferenceUriSchemeConstraint: +# "disallowReferenceUriSchemes" String { String } +# KeySizeConstraint: +# "minKeySize" KeyAlg Integer +# OtherConstraint: +# "noDuplicateIds" | "noRetrievalMethodLoops" +# +# For AlgConstraint, Uri is the algorithm URI String that is not allowed. +# See the XML Signature Recommendation for more information on algorithm +# URI Identifiers. For KeySizeConstraint, KeyAlg is the standard algorithm +# name of the key type (ex: "RSA"). If the MaxTransformsConstraint, +# MaxReferencesConstraint or KeySizeConstraint (for the same key type) is +# specified more than once, only the last entry is enforced. +# +# Note: This property is currently used by the JDK Reference implementation. It +# is not guaranteed to be examined and used by other implementations. +# +jdk.xml.dsig.secureValidationPolicy=\ + disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\ + maxTransforms 5,\ + maxReferences 30,\ + disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ + noDuplicateIds,\ + noRetrievalMethodLoops + +# +# Serialization process-wide filter +# +# A filter, if configured, is used by java.io.ObjectInputStream during +# deserialization to check the contents of the stream. +# A filter is configured as a sequence of patterns, each pattern is either +# matched against the name of a class in the stream or defines a limit. +# Patterns are separated by ";" (semicolon). +# Whitespace is significant and is considered part of the pattern. +# +# If a pattern includes a "=", it sets a limit. +# If a limit appears more than once the last value is used. +# Limits are checked before classes regardless of the order in the sequence of patterns. +# If any of the limits are exceeded, the filter status is REJECTED. +# +# maxdepth=value - the maximum depth of a graph +# maxrefs=value - the maximum number of internal references +# maxbytes=value - the maximum number of bytes in the input stream +# maxarray=value - the maximum array length allowed +# +# Other patterns, from left to right, match the class or package name as +# returned from Class.getName. +# If the class is an array type, the class or package to be matched is the element type. +# Arrays of any number of dimensions are treated the same as the element type. +# For example, a pattern of "!example.Foo", rejects creation of any instance or +# array of example.Foo. +# +# If the pattern starts with "!", the status is REJECTED if the remaining pattern +# is matched; otherwise the status is ALLOWED if the pattern matches. +# If the pattern ends with ".**" it matches any class in the package and all subpackages. +# If the pattern ends with ".*" it matches any class in the package. +# If the pattern ends with "*", it matches any class with the pattern as a prefix. +# If the pattern is equal to the class name, it matches. +# Otherwise, the status is UNDECIDED. +# +#jdk.serialFilter=pattern;pattern + +# +# RMI Registry Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI Registry. +# +#sun.rmi.registry.registryFilter=pattern;pattern + +# +# RMI Distributed Garbage Collector (DGC) Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI DGC. +# +# The builtin DGC filter can approximately be represented as the filter pattern: +# +#sun.rmi.transport.dgcFilter=\ +# java.rmi.server.ObjID;\ +# java.rmi.server.UID;\ +# java.rmi.dgc.VMID;\ +# java.rmi.dgc.Lease;\ +# maxdepth=5;maxarray=10000 + diff --git a/src/IKVM.JTReg.TestAdapter.Core/IKVM.JTReg.TestAdapter.Core.csproj b/src/IKVM.JTReg.TestAdapter.Core/IKVM.JTReg.TestAdapter.Core.csproj index d6414ed142..b142c6c953 100644 --- a/src/IKVM.JTReg.TestAdapter.Core/IKVM.JTReg.TestAdapter.Core.csproj +++ b/src/IKVM.JTReg.TestAdapter.Core/IKVM.JTReg.TestAdapter.Core.csproj @@ -9,6 +9,7 @@ false true true + true diff --git a/src/IKVM.JTReg.TestAdapter.Core/JTRegTestManager.cs b/src/IKVM.JTReg.TestAdapter.Core/JTRegTestManager.cs index 291f08a6e5..191e4afe8a 100644 --- a/src/IKVM.JTReg.TestAdapter.Core/JTRegTestManager.cs +++ b/src/IKVM.JTReg.TestAdapter.Core/JTRegTestManager.cs @@ -35,8 +35,6 @@ public class JTRegTestManager internal const string DEFAULT_PARAM_TAG = "regtest"; internal const string ENV_PREFIX = "JTREG_"; - static readonly MD5 md5 = MD5.Create(); - /// /// Initializes the static instance. /// @@ -47,7 +45,7 @@ static JTRegTestManager() if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { var javaHome = java.lang.System.getProperty("java.home"); - foreach (var exec in new[] { "java", "javac", "jar", "jarsigner", "javadoc", "javah", "javap", "jdeps", "keytool", "native2ascii", "orbd", "policytool", "rmic", "schemagen", "wsgen", "wsimport" }) + foreach (var exec in new[] { "java", "javac", "jar", "jarsigner", "javadoc", "javah", "javap", "jdeps", "keytool", "native2ascii", "orbd", "policytool", "rmic", "schemagen", "wsgen", "wsimport", "xjc" }) { var execPath = Path.Combine(javaHome, "bin", exec); if (File.Exists(execPath)) @@ -76,22 +74,13 @@ static JTRegTestManager() /// protected static string GetSourceId(string source) { - // allows a lock around the MD5 instance - byte[] ComputeHash(byte[] buffer) - { - lock (md5) - { - var b = new byte[8]; - var h = md5.ComputeHash(buffer); - Array.Copy(h, b, 8); - return b; - } - } + using var md5 = MD5.Create(); + var h = md5.ComputeHash(Encoding.UTF8.GetBytes(source)); - var b = ComputeHash(Encoding.UTF8.GetBytes(source)); var s = new StringBuilder(16); - for (int i = 0; i < b.Length; i++) - s.Append(b[i].ToString("x2")); + for (int i = 0; i < 8; i++) + s.Append(h[i].ToString("x2")); + return s.ToString(); } diff --git a/src/IKVM.JTReg.TestAdapter.Tests/IKVM.JTReg.TestAdapter.Tests.csproj b/src/IKVM.JTReg.TestAdapter.Tests/IKVM.JTReg.TestAdapter.Tests.csproj index ac726cac6c..7137908d62 100644 --- a/src/IKVM.JTReg.TestAdapter.Tests/IKVM.JTReg.TestAdapter.Tests.csproj +++ b/src/IKVM.JTReg.TestAdapter.Tests/IKVM.JTReg.TestAdapter.Tests.csproj @@ -12,11 +12,11 @@ - - - + + + - + diff --git a/src/IKVM.JTReg.TestAdapter/IKVM.JTReg.TestAdapter.csproj b/src/IKVM.JTReg.TestAdapter/IKVM.JTReg.TestAdapter.csproj index e22e600b64..6a9fecb831 100644 --- a/src/IKVM.JTReg.TestAdapter/IKVM.JTReg.TestAdapter.csproj +++ b/src/IKVM.JTReg.TestAdapter/IKVM.JTReg.TestAdapter.csproj @@ -5,7 +5,7 @@ - + diff --git a/src/IKVM.Java-ref/java/io/FileNotFoundException.cs b/src/IKVM.Java-ref/java/io/FileNotFoundException.cs new file mode 100644 index 0000000000..86579c5d34 --- /dev/null +++ b/src/IKVM.Java-ref/java/io/FileNotFoundException.cs @@ -0,0 +1,9 @@ +namespace java.io +{ + + public class FileNotFoundException : IOException + { + + } + +} diff --git a/src/IKVM.Java-ref/java/io/IOException.cs b/src/IKVM.Java-ref/java/io/IOException.cs new file mode 100644 index 0000000000..bcfb6ccb4f --- /dev/null +++ b/src/IKVM.Java-ref/java/io/IOException.cs @@ -0,0 +1,11 @@ +using java.lang; + +namespace java.io +{ + + public class IOException : Exception + { + + } + +} diff --git a/src/IKVM.Java-ref/java/lang/UnsupportedOperationException.cs b/src/IKVM.Java-ref/java/lang/UnsupportedOperationException.cs new file mode 100644 index 0000000000..69258d207f --- /dev/null +++ b/src/IKVM.Java-ref/java/lang/UnsupportedOperationException.cs @@ -0,0 +1,9 @@ +namespace java.lang +{ + + public class UnsupportedOperationException : RuntimeException + { + + } + +} diff --git a/src/IKVM.Java.Extensions/IKVM.Java.Extensions.csproj b/src/IKVM.Java.Extensions/IKVM.Java.Extensions.csproj index d70a87b5ef..132453ad92 100644 --- a/src/IKVM.Java.Extensions/IKVM.Java.Extensions.csproj +++ b/src/IKVM.Java.Extensions/IKVM.Java.Extensions.csproj @@ -1,4 +1,4 @@ - + net472;net6.0 diff --git a/src/IKVM.Java.Extensions/java/nio/channels/DelegateCompletionHandler.cs b/src/IKVM.Java.Extensions/java/nio/channels/DelegateCompletionHandler.cs new file mode 100644 index 0000000000..ac461a2576 --- /dev/null +++ b/src/IKVM.Java.Extensions/java/nio/channels/DelegateCompletionHandler.cs @@ -0,0 +1,89 @@ +using System; + +namespace java.nio.channels +{ + + /// + /// An implementation of a that accepts a delegate. + /// + public class DelegateCompletionHandler : DelegateCompletionHandler + { + + /// + /// Initializes a new instance. + /// + /// + /// + public DelegateCompletionHandler(Action onCompleted, Action onFailed) : + base(onCompleted, onFailed) + { + + } + + } + + /// + /// An implementation of a that accepts a delegate. + /// + /// + public class DelegateCompletionHandler : DelegateCompletionHandler + { + + + /// + /// Initializes a new instance. + /// + /// + /// + public DelegateCompletionHandler(Action onCompleted, Action onFailed) : + base((r, a) => onCompleted(r), (e, a) => onFailed(e)) + { + + } + + } + + /// + /// An implementation of a that accepts a delegate. + /// + /// + public class DelegateCompletionHandler : CompletionHandler + { + + readonly Action onCompleted; + readonly Action onFailed; + + /// + /// Initializes a new instance. + /// + /// + /// + public DelegateCompletionHandler(Action onCompleted, Action onFailed) + { + this.onCompleted = onCompleted; + this.onFailed = onFailed; + } + + /// + /// Invoked when the handler is signaled completion. + /// + /// + /// + void CompletionHandler.completed(object result, object attachment) + { + onCompleted((V)result, (A)attachment); + } + + /// + /// Invoked when the handler is signaled failure. + /// + /// + /// + void CompletionHandler.failed(Exception exc, object attachment) + { + onFailed(exc, (A)attachment); + } + + } + +} diff --git a/src/IKVM.Java.Tests.Util/IKVM.Java.Tests.Util.csproj b/src/IKVM.Java.Tests.Util/IKVM.Java.Tests.Util.csproj index 1b6ae8895c..6f6ea7e202 100644 --- a/src/IKVM.Java.Tests.Util/IKVM.Java.Tests.Util.csproj +++ b/src/IKVM.Java.Tests.Util/IKVM.Java.Tests.Util.csproj @@ -4,7 +4,7 @@ - + diff --git a/src/IKVM.Java.Tests/IKVM.Java.Tests.msbuildproj b/src/IKVM.Java.Tests/IKVM.Java.Tests.msbuildproj index b3d38cba03..972f2c1e16 100644 --- a/src/IKVM.Java.Tests/IKVM.Java.Tests.msbuildproj +++ b/src/IKVM.Java.Tests/IKVM.Java.Tests.msbuildproj @@ -8,7 +8,7 @@ - + diff --git a/src/IKVM.Java.Tests/java/lang/invoke/MethodInvokeTests.java b/src/IKVM.Java.Tests/java/lang/invoke/MethodInvokeTests.java new file mode 100644 index 0000000000..0d57219a92 --- /dev/null +++ b/src/IKVM.Java.Tests/java/lang/invoke/MethodInvokeTests.java @@ -0,0 +1,34 @@ +package ikvm.tests.java.java.lang.invoke; + +import java.lang.*; +import java.lang.invoke.*; +import java.lang.reflect.*; +import java.util.*; + +@cli.Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute.Annotation() +public class MethodInvokeTests { + + public static void shouldWrapNullPointerExceptionInFastMethodInvokeImpl() { + throw new NullPointerException(); + } + + @cli.Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute.Annotation() + public void shouldWrapNullPointerExceptionInMethodInvoke() throws Throwable { + Method method = MethodInvokeTests.class.getDeclaredMethod("shouldWrapNullPointerExceptionInFastMethodInvokeImpl"); + + for (int i = 0; i < 30; i++) { + try { + method.invoke(null); + } catch (InvocationTargetException ite) { + if (ite.getTargetException() instanceof NullPointerException) { + continue; + } else { + throw new RuntimeException("Expected exception not thrown.", ite); + } + } + + throw new RuntimeException("Expected exception not thrown."); + } + } + +} diff --git a/src/IKVM.Java/local/java/io/FileDescriptor.java b/src/IKVM.Java/local/java/io/FileDescriptor.java index 76a6bd2b54..50d4db9b7a 100644 --- a/src/IKVM.Java/local/java/io/FileDescriptor.java +++ b/src/IKVM.Java/local/java/io/FileDescriptor.java @@ -22,7 +22,7 @@ public final class FileDescriptor { sun.misc.SharedSecrets.setJavaIOFileDescriptorAccess( new sun.misc.JavaIOFileDescriptorAccess() { public void set(FileDescriptor obj, int fd) { - + obj.fd = fd; } public int get(FileDescriptor obj) { @@ -30,7 +30,7 @@ public int get(FileDescriptor obj) { } public void setHandle(FileDescriptor obj, long handle) { - + obj.handle = handle; } public long getHandle(FileDescriptor obj) { diff --git a/src/IKVM.Java/local/java/lang/ProcessImpl.java b/src/IKVM.Java/local/java/lang/ProcessImpl.java index ae211b1e71..a931aa029d 100644 --- a/src/IKVM.Java/local/java/lang/ProcessImpl.java +++ b/src/IKVM.Java/local/java/lang/ProcessImpl.java @@ -1,46 +1,156 @@ +/* + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + package java.lang; -import java.io.*; +import java.io.IOException; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.lang.ProcessBuilder.Redirect; import java.util.*; -final class ProcessImpl extends Process { +/** + * This class is for the exclusive use of ProcessBuilder.start() to + * create new processes. + * + * @author Martin Buchholz + * @since 1.5 + */ +final class ProcessImpl { + + public native void dummy(); - cli.System.Diagnostics.Process process; - OutputStream outputStream; - InputStream inputStream; - InputStream errorStream; + private static final sun.misc.JavaIOFileDescriptorAccess fdAccess + = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess(); - static native Process start(String cmdarray[], java.util.Map environment, String dir, ProcessBuilder.Redirect[] redirects, boolean redirectErrorStream) throws IOException; + private ProcessImpl() {} // Not instantiable - private ProcessImpl(cli.System.Diagnostics.Process process, OutputStream outputStream, InputStream inputStream, InputStream errorStream) { - this.process = process; - this.outputStream = outputStream; - this.inputStream = inputStream; - this.errorStream = errorStream; + private static byte[] toCString(String s) { + if (s == null) + return null; + byte[] bytes = s.getBytes(); + byte[] result = new byte[bytes.length + 1]; + System.arraycopy(bytes, 0, + result, 0, + bytes.length); + result[result.length-1] = (byte)0; + return result; } - @Override - public OutputStream getOutputStream() { - return outputStream; - } + // Only for use by ProcessBuilder.start() + static Process start(String[] cmdarray, + java.util.Map environment, + String dir, + ProcessBuilder.Redirect[] redirects, + boolean redirectErrorStream) + throws IOException + { + if (cli.IKVM.Runtime.RuntimeUtil.get_IsWindows()) { + return Win32Process.start(cmdarray, environment, dir, redirects, redirectErrorStream); + } else { - @Override - public InputStream getInputStream() { - return inputStream; - } - - @Override - public InputStream getErrorStream() { - return errorStream; - } - - @Override - public native int waitFor() throws InterruptedException; - - @Override - public native int exitValue(); - - @Override - public native void destroy(); + assert cmdarray != null && cmdarray.length > 0; + + // Convert arguments to a contiguous block; it's easier to do + // memory management in Java than in C. + byte[][] args = new byte[cmdarray.length-1][]; + int size = args.length; // For added NUL bytes + for (int i = 0; i < args.length; i++) { + args[i] = cmdarray[i+1].getBytes(); + size += args[i].length; + } + byte[] argBlock = new byte[size]; + int i = 0; + for (byte[] arg : args) { + System.arraycopy(arg, 0, argBlock, i, arg.length); + i += arg.length + 1; + // No need to write NUL bytes explicitly + } + int[] envc = new int[1]; + byte[] envBlock = UNIXProcessEnvironment.toEnvironmentBlock(environment, envc); + + int[] std_fds; + + FileInputStream f0 = null; + FileOutputStream f1 = null; + FileOutputStream f2 = null; + + try { + if (redirects == null) { + std_fds = new int[] { -1, -1, -1 }; + } else { + std_fds = new int[3]; + + if (redirects[0] == Redirect.PIPE) + std_fds[0] = -1; + else if (redirects[0] == Redirect.INHERIT) + std_fds[0] = 0; + else { + f0 = new FileInputStream(redirects[0].file()); + std_fds[0] = fdAccess.get(f0.getFD()); + } + + if (redirects[1] == Redirect.PIPE) + std_fds[1] = -1; + else if (redirects[1] == Redirect.INHERIT) + std_fds[1] = 1; + else { + f1 = new FileOutputStream(redirects[1].file(), + redirects[1].append()); + std_fds[1] = fdAccess.get(f1.getFD()); + } + + if (redirects[2] == Redirect.PIPE) + std_fds[2] = -1; + else if (redirects[2] == Redirect.INHERIT) + std_fds[2] = 2; + else { + f2 = new FileOutputStream(redirects[2].file(), + redirects[2].append()); + std_fds[2] = fdAccess.get(f2.getFD()); + } + } + + return new UNIXProcess + (toCString(cmdarray[0]), + argBlock, args.length, + envBlock, envc[0], + toCString(dir), + std_fds, + redirectErrorStream); + } finally { + // In theory, close() can throw IOException + // (although it is rather unlikely to happen here) + try { if (f0 != null) f0.close(); } + finally { + try { if (f1 != null) f1.close(); } + finally { if (f2 != null) f2.close(); } + } + } + + } + } } diff --git a/src/IKVM.Java/local/java/lang/Thread.java b/src/IKVM.Java/local/java/lang/Thread.java index dabf278766..b48ef57efe 100644 --- a/src/IKVM.Java/local/java/lang/Thread.java +++ b/src/IKVM.Java/local/java/lang/Thread.java @@ -173,7 +173,7 @@ protected void finalize() { int parkState; // used by cmpxchgParkState in map.xml /* --- end IKVM specific state --- */ - private volatile char name[]; + private volatile String name; private int priority; private Thread threadQ; private long eetop; @@ -448,11 +448,11 @@ public static void sleep(long millis, int nanos) /** * Initializes a Thread with the current AccessControlContext. - * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext) + * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext,boolean) */ private void init(ThreadGroup g, Runnable target, String name, long stackSize) { - init(g, target, name, stackSize, null); + init(g, target, name, stackSize, null, true); } /** @@ -465,14 +465,17 @@ private void init(ThreadGroup g, Runnable target, String name, * zero to indicate that this parameter is to be ignored. * @param acc the AccessControlContext to inherit, or * AccessController.getContext() if null + * @param inheritThreadLocals if {@code true}, inherit initial values for + * inheritable thread-locals from the constructing thread */ private void init(ThreadGroup g, Runnable target, String name, - long stackSize, AccessControlContext acc) { + long stackSize, AccessControlContext acc, + boolean inheritThreadLocals) { if (name == null) { throw new NullPointerException("name cannot be null"); } - this.name = name.toCharArray(); + this.name = name; Thread parent = currentThread(); SecurityManager security = System.getSecurityManager(); @@ -518,7 +521,7 @@ private void init(ThreadGroup g, Runnable target, String name, acc != null ? acc : AccessController.getLazyContext(parent.inheritedAccessControlContext); this.target = target; setPriority(priority); - if (parent.inheritableThreadLocals != null) + if (inheritThreadLocals && parent.inheritableThreadLocals != null) this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); /* Stash the specified stack size in case the VM cares */ @@ -541,7 +544,7 @@ private void init(ThreadGroup g, Runnable target, String name, this.group = g; this.daemon = thread.get_IsBackground(); this.priority = mapClrPriorityToJava(thread.get_Priority().Value); - this.name = name.toCharArray(); + this.name = name; this.contextClassLoader = ClassLoader.DUMMY; this.threadStatus = 0x0005; /* JVMTI_THREAD_STATE_ALIVE + JVMTI_THREAD_STATE_RUNNABLE */ @@ -645,7 +648,7 @@ public Thread(Runnable target) { * This is not a public constructor. */ Thread(Runnable target, AccessControlContext acc) { - init(null, target, "Thread-" + nextThreadNum(), 0, acc); + init(null, target, "Thread-" + nextThreadNum(), 0, acc, false); } /** @@ -1393,7 +1396,11 @@ public final int getPriority() { */ public final synchronized void setName(String name) { checkAccess(); - this.name = name.toCharArray(); + if (name == null) { + throw new NullPointerException("name cannot be null"); + } + + this.name = name; if (threadStatus != 0) { setNativeName(name); } @@ -1406,7 +1413,7 @@ public final synchronized void setName(String name) { * @see #setName(String) */ public final String getName() { - return String.valueOf(name); + return name; } /** diff --git a/src/IKVM.Java/local/java/lang/UNIXProcess.java b/src/IKVM.Java/local/java/lang/UNIXProcess.java new file mode 100644 index 0000000000..735cbdae91 --- /dev/null +++ b/src/IKVM.Java/local/java/lang/UNIXProcess.java @@ -0,0 +1,829 @@ +/* + * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Locale; +import java.util.Set; +import java.util.concurrent.Executors; +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.security.AccessController; +import static java.security.AccessController.doPrivileged; +import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; + +/** + * java.lang.Process subclass in the UNIX environment. + * + * @author Mario Wolczko and Ross Knippel. + * @author Konstantin Kladko (ported to Linux and Bsd) + * @author Martin Buchholz + * @author Volker Simonis (ported to AIX) + */ +final class UNIXProcess extends Process { + private static final sun.misc.JavaIOFileDescriptorAccess fdAccess + = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess(); + + private final int pid; + private int exitcode; + private boolean hasExited; + + private /* final */ OutputStream stdin; + private /* final */ InputStream stdout; + private /* final */ InputStream stderr; + + // only used on Solaris + private /* final */ DeferredCloseInputStream stdout_inner_stream; + + private static enum LaunchMechanism { + // order IS important! + FORK, + POSIX_SPAWN, + VFORK + } + + private static enum Platform { + + LINUX(LaunchMechanism.VFORK, LaunchMechanism.FORK), + + BSD(LaunchMechanism.FORK), + + SOLARIS(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK), + + AIX(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK); + + final LaunchMechanism defaultLaunchMechanism; + final Set validLaunchMechanisms; + + Platform(LaunchMechanism ... launchMechanisms) { + this.defaultLaunchMechanism = launchMechanisms[0]; + this.validLaunchMechanisms = + EnumSet.copyOf(Arrays.asList(launchMechanisms)); + } + + private String helperPath(String javahome, String osArch) { + switch (this) { + case SOLARIS: + if (osArch.equals("x86")) { osArch = "i386"; } + else if (osArch.equals("x86_64")) { osArch = "amd64"; } + // fall through... + case LINUX: + case AIX: + return javahome + "/lib/" + osArch + "/jspawnhelper"; + + case BSD: + return javahome + "/lib/jspawnhelper"; + + default: + throw new AssertionError("Unsupported platform: " + this); + } + } + + String helperPath() { + return AccessController.doPrivileged( + (PrivilegedAction) () -> + helperPath(System.getProperty("java.home"), + System.getProperty("os.arch")) + ); + } + + LaunchMechanism launchMechanism() { + return AccessController.doPrivileged( + (PrivilegedAction) () -> { + String s = System.getProperty( + "jdk.lang.Process.launchMechanism"); + LaunchMechanism lm; + if (s == null) { + lm = defaultLaunchMechanism; + s = lm.name().toLowerCase(Locale.ENGLISH); + } else { + try { + lm = LaunchMechanism.valueOf( + s.toUpperCase(Locale.ENGLISH)); + } catch (IllegalArgumentException e) { + lm = null; + } + } + if (lm == null || !validLaunchMechanisms.contains(lm)) { + throw new Error( + s + " is not a supported " + + "process launch mechanism on this platform." + ); + } + return lm; + } + ); + } + + static Platform get() { + String osName = AccessController.doPrivileged( + (PrivilegedAction) () -> System.getProperty("os.name") + ); + + if (osName.equals("Linux")) { return LINUX; } + if (osName.contains("OS X")) { return BSD; } + if (osName.equals("SunOS")) { return SOLARIS; } + if (osName.equals("AIX")) { return AIX; } + + throw new Error(osName + " is not a supported OS platform."); + } + } + + private static final Platform platform = Platform.get(); + private static final LaunchMechanism launchMechanism = platform.launchMechanism(); + private static final byte[] helperpath = toCString(platform.helperPath()); + + private static byte[] toCString(String s) { + if (s == null) + return null; + byte[] bytes = s.getBytes(); + byte[] result = new byte[bytes.length + 1]; + System.arraycopy(bytes, 0, + result, 0, + bytes.length); + result[result.length-1] = (byte)0; + return result; + } + + /* this is for the reaping thread */ + private native int waitForProcessExit(int pid); + + /** + * Creates a process. Depending on the {@code mode} flag, this is done by + * one of the following mechanisms: + *
+     *   1 - fork(2) and exec(2)
+     *   2 - posix_spawn(3P)
+     *   3 - vfork(2) and exec(2)
+     *
+     *  (4 - clone(2) and exec(2) - obsolete and currently disabled in native code)
+     * 
+ * @param fds an array of three file descriptors. + * Indexes 0, 1, and 2 correspond to standard input, + * standard output and standard error, respectively. On + * input, a value of -1 means to create a pipe to connect + * child and parent processes. On output, a value which + * is not -1 is the parent pipe fd corresponding to the + * pipe which has been created. An element of this array + * is -1 on input if and only if it is not -1 on + * output. + * @return the pid of the subprocess + */ + private native int forkAndExec(int mode, byte[] helperpath, + byte[] prog, + byte[] argBlock, int argc, + byte[] envBlock, int envc, + byte[] dir, + int[] fds, + boolean redirectErrorStream) + throws IOException; + + /** + * The thread pool of "process reaper" daemon threads. + */ + private static final Executor processReaperExecutor = + doPrivileged((PrivilegedAction) () -> { + + ThreadGroup tg = Thread.currentThread().getThreadGroup(); + while (tg.getParent() != null) tg = tg.getParent(); + ThreadGroup systemThreadGroup = tg; + + ThreadFactory threadFactory = grimReaper -> { + long stackSize = Boolean.getBoolean("jdk.lang.processReaperUseDefaultStackSize") ? 0 : 32768; + Thread t = new Thread(systemThreadGroup, grimReaper,"process reaper", stackSize); + t.setDaemon(true); + // A small attempt (probably futile) to avoid priority inversion + t.setPriority(Thread.MAX_PRIORITY); + return t; + }; + + return Executors.newCachedThreadPool(threadFactory); + }); + + UNIXProcess(final byte[] prog, + final byte[] argBlock, final int argc, + final byte[] envBlock, final int envc, + final byte[] dir, + final int[] fds, + final boolean redirectErrorStream) + throws IOException { + + pid = forkAndExec(launchMechanism.ordinal() + 1, + helperpath, + prog, + argBlock, argc, + envBlock, envc, + dir, + fds, + redirectErrorStream); + + try { + doPrivileged((PrivilegedExceptionAction) () -> { + initStreams(fds); + return null; + }); + } catch (PrivilegedActionException ex) { + throw (IOException) ex.getException(); + } + } + + static FileDescriptor newFileDescriptor(int fd) { + FileDescriptor fileDescriptor = new FileDescriptor(); + fdAccess.set(fileDescriptor, fd); + return fileDescriptor; + } + + void initStreams(int[] fds) throws IOException { + switch (platform) { + case LINUX: + case BSD: + stdin = (fds[0] == -1) ? + ProcessBuilder.NullOutputStream.INSTANCE : + new ProcessPipeOutputStream(fds[0]); + + stdout = (fds[1] == -1) ? + ProcessBuilder.NullInputStream.INSTANCE : + new ProcessPipeInputStream(fds[1]); + + stderr = (fds[2] == -1) ? + ProcessBuilder.NullInputStream.INSTANCE : + new ProcessPipeInputStream(fds[2]); + + processReaperExecutor.execute(() -> { + int exitcode = waitForProcessExit(pid); + + synchronized (this) { + this.exitcode = exitcode; + this.hasExited = true; + this.notifyAll(); + } + + if (stdout instanceof ProcessPipeInputStream) + ((ProcessPipeInputStream) stdout).processExited(); + + if (stderr instanceof ProcessPipeInputStream) + ((ProcessPipeInputStream) stderr).processExited(); + + if (stdin instanceof ProcessPipeOutputStream) + ((ProcessPipeOutputStream) stdin).processExited(); + }); + break; + + case SOLARIS: + stdin = (fds[0] == -1) ? + ProcessBuilder.NullOutputStream.INSTANCE : + new BufferedOutputStream( + new FileOutputStream(newFileDescriptor(fds[0]))); + + stdout = (fds[1] == -1) ? + ProcessBuilder.NullInputStream.INSTANCE : + new BufferedInputStream( + stdout_inner_stream = + new DeferredCloseInputStream( + newFileDescriptor(fds[1]))); + + stderr = (fds[2] == -1) ? + ProcessBuilder.NullInputStream.INSTANCE : + new DeferredCloseInputStream(newFileDescriptor(fds[2])); + + /* + * For each subprocess forked a corresponding reaper task + * is submitted. That task is the only thread which waits + * for the subprocess to terminate and it doesn't hold any + * locks while doing so. This design allows waitFor() and + * exitStatus() to be safely executed in parallel (and they + * need no native code). + */ + processReaperExecutor.execute(() -> { + int exitcode = waitForProcessExit(pid); + + synchronized (this) { + this.exitcode = exitcode; + this.hasExited = true; + this.notifyAll(); + } + }); + break; + + case AIX: + stdin = (fds[0] == -1) ? + ProcessBuilder.NullOutputStream.INSTANCE : + new ProcessPipeOutputStream(fds[0]); + + stdout = (fds[1] == -1) ? + ProcessBuilder.NullInputStream.INSTANCE : + new DeferredCloseProcessPipeInputStream(fds[1]); + + stderr = (fds[2] == -1) ? + ProcessBuilder.NullInputStream.INSTANCE : + new DeferredCloseProcessPipeInputStream(fds[2]); + + processReaperExecutor.execute(() -> { + int exitcode = waitForProcessExit(pid); + + synchronized (this) { + this.exitcode = exitcode; + this.hasExited = true; + this.notifyAll(); + } + + if (stdout instanceof DeferredCloseProcessPipeInputStream) + ((DeferredCloseProcessPipeInputStream) stdout).processExited(); + + if (stderr instanceof DeferredCloseProcessPipeInputStream) + ((DeferredCloseProcessPipeInputStream) stderr).processExited(); + + if (stdin instanceof ProcessPipeOutputStream) + ((ProcessPipeOutputStream) stdin).processExited(); + }); + break; + + default: throw new AssertionError("Unsupported platform: " + platform); + } + } + + public OutputStream getOutputStream() { + return stdin; + } + + public InputStream getInputStream() { + return stdout; + } + + public InputStream getErrorStream() { + return stderr; + } + + public synchronized int waitFor() throws InterruptedException { + while (!hasExited) { + wait(); + } + return exitcode; + } + + @Override + public synchronized boolean waitFor(long timeout, TimeUnit unit) + throws InterruptedException + { + if (hasExited) return true; + if (timeout <= 0) return false; + + long remainingNanos = unit.toNanos(timeout); + long deadline = System.nanoTime() + remainingNanos; + + do { + // Round up to next millisecond + wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L)); + if (hasExited) { + return true; + } + remainingNanos = deadline - System.nanoTime(); + } while (remainingNanos > 0); + return hasExited; + } + + public synchronized int exitValue() { + if (!hasExited) { + throw new IllegalThreadStateException("process hasn't exited"); + } + return exitcode; + } + + private static native void destroyProcess(int pid, boolean force); + + private void destroy(boolean force) { + switch (platform) { + case LINUX: + case BSD: + case AIX: + // There is a risk that pid will be recycled, causing us to + // kill the wrong process! So we only terminate processes + // that appear to still be running. Even with this check, + // there is an unavoidable race condition here, but the window + // is very small, and OSes try hard to not recycle pids too + // soon, so this is quite safe. + synchronized (this) { + if (!hasExited) + destroyProcess(pid, force); + } + try { stdin.close(); } catch (IOException ignored) {} + try { stdout.close(); } catch (IOException ignored) {} + try { stderr.close(); } catch (IOException ignored) {} + break; + + case SOLARIS: + // There is a risk that pid will be recycled, causing us to + // kill the wrong process! So we only terminate processes + // that appear to still be running. Even with this check, + // there is an unavoidable race condition here, but the window + // is very small, and OSes try hard to not recycle pids too + // soon, so this is quite safe. + synchronized (this) { + if (!hasExited) + destroyProcess(pid, force); + try { + stdin.close(); + if (stdout_inner_stream != null) + stdout_inner_stream.closeDeferred(stdout); + if (stderr instanceof DeferredCloseInputStream) + ((DeferredCloseInputStream) stderr) + .closeDeferred(stderr); + } catch (IOException e) { + // ignore + } + } + break; + + default: throw new AssertionError("Unsupported platform: " + platform); + } + } + + public void destroy() { + destroy(false); + } + + @Override + public Process destroyForcibly() { + destroy(true); + return this; + } + + @Override + public synchronized boolean isAlive() { + return !hasExited; + } + + private static native void init(); + + static { + init(); + } + + /** + * A buffered input stream for a subprocess pipe file descriptor + * that allows the underlying file descriptor to be reclaimed when + * the process exits, via the processExited hook. + * + * This is tricky because we do not want the user-level InputStream to be + * closed until the user invokes close(), and we need to continue to be + * able to read any buffered data lingering in the OS pipe buffer. + */ + private static class ProcessPipeInputStream extends BufferedInputStream { + private final Object closeLock = new Object(); + + ProcessPipeInputStream(int fd) { + super(new FileInputStream(newFileDescriptor(fd))); + } + private static byte[] drainInputStream(InputStream in) + throws IOException { + int n = 0; + int j; + byte[] a = null; + while ((j = in.available()) > 0) { + a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j); + n += in.read(a, n, j); + } + return (a == null || n == a.length) ? a : Arrays.copyOf(a, n); + } + + /** Called by the process reaper thread when the process exits. */ + synchronized void processExited() { + synchronized (closeLock) { + try { + InputStream in = this.in; + // this stream is closed if and only if: in == null + if (in != null) { + byte[] stragglers = drainInputStream(in); + in.close(); + this.in = (stragglers == null) ? + ProcessBuilder.NullInputStream.INSTANCE : + new ByteArrayInputStream(stragglers); + } + } catch (IOException ignored) {} + } + } + + @Override + public void close() throws IOException { + // BufferedInputStream#close() is not synchronized unlike most other + // methods. Synchronizing helps avoid race with processExited(). + synchronized (closeLock) { + super.close(); + } + } + } + + /** + * A buffered output stream for a subprocess pipe file descriptor + * that allows the underlying file descriptor to be reclaimed when + * the process exits, via the processExited hook. + */ + private static class ProcessPipeOutputStream extends BufferedOutputStream { + ProcessPipeOutputStream(int fd) { + super(new FileOutputStream(newFileDescriptor(fd))); + } + + /** Called by the process reaper thread when the process exits. */ + synchronized void processExited() { + OutputStream out = this.out; + if (out != null) { + try { + out.close(); + } catch (IOException ignored) { + // We know of no reason to get an IOException, but if + // we do, there's nothing else to do but carry on. + } + this.out = ProcessBuilder.NullOutputStream.INSTANCE; + } + } + } + + // A FileInputStream that supports the deferment of the actual close + // operation until the last pending I/O operation on the stream has + // finished. This is required on Solaris because we must close the stdin + // and stdout streams in the destroy method in order to reclaim the + // underlying file descriptors. Doing so, however, causes any thread + // currently blocked in a read on one of those streams to receive an + // IOException("Bad file number"), which is incompatible with historical + // behavior. By deferring the close we allow any pending reads to see -1 + // (EOF) as they did before. + // + private static class DeferredCloseInputStream extends FileInputStream + { + DeferredCloseInputStream(FileDescriptor fd) { + super(fd); + } + + private Object lock = new Object(); // For the following fields + private boolean closePending = false; + private int useCount = 0; + private InputStream streamToClose; + + private void raise() { + synchronized (lock) { + useCount++; + } + } + + private void lower() throws IOException { + synchronized (lock) { + useCount--; + if (useCount == 0 && closePending) { + streamToClose.close(); + } + } + } + + // stc is the actual stream to be closed; it might be this object, or + // it might be an upstream object for which this object is downstream. + // + private void closeDeferred(InputStream stc) throws IOException { + synchronized (lock) { + if (useCount == 0) { + stc.close(); + } else { + closePending = true; + streamToClose = stc; + } + } + } + + public void close() throws IOException { + synchronized (lock) { + useCount = 0; + closePending = false; + } + super.close(); + } + + public int read() throws IOException { + raise(); + try { + return super.read(); + } finally { + lower(); + } + } + + public int read(byte[] b) throws IOException { + raise(); + try { + return super.read(b); + } finally { + lower(); + } + } + + public int read(byte[] b, int off, int len) throws IOException { + raise(); + try { + return super.read(b, off, len); + } finally { + lower(); + } + } + + public long skip(long n) throws IOException { + raise(); + try { + return super.skip(n); + } finally { + lower(); + } + } + + public int available() throws IOException { + raise(); + try { + return super.available(); + } finally { + lower(); + } + } + } + + /** + * A buffered input stream for a subprocess pipe file descriptor + * that allows the underlying file descriptor to be reclaimed when + * the process exits, via the processExited hook. + * + * This is tricky because we do not want the user-level InputStream to be + * closed until the user invokes close(), and we need to continue to be + * able to read any buffered data lingering in the OS pipe buffer. + * + * On AIX this is especially tricky, because the 'close()' system call + * will block if another thread is at the same time blocked in a file + * operation (e.g. 'read()') on the same file descriptor. We therefore + * combine 'ProcessPipeInputStream' approach used on Linux and Bsd + * with the DeferredCloseInputStream approach used on Solaris. This means + * that every potentially blocking operation on the file descriptor + * increments a counter before it is executed and decrements it once it + * finishes. The 'close()' operation will only be executed if there are + * no pending operations. Otherwise it is deferred after the last pending + * operation has finished. + * + */ + private static class DeferredCloseProcessPipeInputStream + extends BufferedInputStream { + + private final Object closeLock = new Object(); + private int useCount = 0; + private boolean closePending = false; + + DeferredCloseProcessPipeInputStream(int fd) { + super(new FileInputStream(newFileDescriptor(fd))); + } + + private InputStream drainInputStream(InputStream in) + throws IOException { + int n = 0; + int j; + byte[] a = null; + synchronized (closeLock) { + if (buf == null) // asynchronous close()? + return null; // discard + j = in.available(); + } + while (j > 0) { + a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j); + synchronized (closeLock) { + if (buf == null) // asynchronous close()? + return null; // discard + n += in.read(a, n, j); + j = in.available(); + } + } + return (a == null) ? + ProcessBuilder.NullInputStream.INSTANCE : + new ByteArrayInputStream(n == a.length ? a : Arrays.copyOf(a, n)); + } + + /** Called by the process reaper thread when the process exits. */ + synchronized void processExited() { + try { + InputStream in = this.in; + if (in != null) { + InputStream stragglers = drainInputStream(in); + in.close(); + this.in = stragglers; + } + } catch (IOException ignored) { } + } + + private void raise() { + synchronized (closeLock) { + useCount++; + } + } + + private void lower() throws IOException { + synchronized (closeLock) { + useCount--; + if (useCount == 0 && closePending) { + closePending = false; + super.close(); + } + } + } + + @Override + public int read() throws IOException { + raise(); + try { + return super.read(); + } finally { + lower(); + } + } + + @Override + public int read(byte[] b) throws IOException { + raise(); + try { + return super.read(b); + } finally { + lower(); + } + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + raise(); + try { + return super.read(b, off, len); + } finally { + lower(); + } + } + + @Override + public long skip(long n) throws IOException { + raise(); + try { + return super.skip(n); + } finally { + lower(); + } + } + + @Override + public int available() throws IOException { + raise(); + try { + return super.available(); + } finally { + lower(); + } + } + + @Override + public void close() throws IOException { + // BufferedInputStream#close() is not synchronized unlike most other + // methods. Synchronizing helps avoid racing with drainInputStream(). + synchronized (closeLock) { + if (useCount == 0) { + super.close(); + } + else { + closePending = true; + } + } + } + } +} diff --git a/src/IKVM.Java/local/java/lang/UNIXProcessEnvironment.java b/src/IKVM.Java/local/java/lang/UNIXProcessEnvironment.java new file mode 100644 index 0000000000..fbe4f37ef2 --- /dev/null +++ b/src/IKVM.Java/local/java/lang/UNIXProcessEnvironment.java @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* We use APIs that access the standard Unix environ array, which + * is defined by UNIX98 to look like: + * + * char **environ; + * + * These are unsorted, case-sensitive, null-terminated arrays of bytes + * of the form FOO=BAR\000 which are usually encoded in the user's + * default encoding (file.encoding is an excellent choice for + * encoding/decoding these). However, even though the user cannot + * directly access the underlying byte representation, we take pains + * to pass on the child the exact byte representation we inherit from + * the parent process for any environment name or value not created by + * Javaland. So we keep track of all the byte representations. + * + * Internally, we define the types Variable and Value that exhibit + * String/byteArray duality. The internal representation of the + * environment then looks like a Map. But we don't + * expose this to the user -- we only provide a Map + * view, although we could also provide a Map view. + * + * The non-private methods in this class are not for general use even + * within this package. Instead, they are the system-dependent parts + * of the system-independent method of the same name. Don't even + * think of using this class unless your method's name appears below. + * + * @author Martin Buchholz + * @since 1.5 + */ + + // IKVM Largely a copy of the UNIX version of ProcessEnvironment. Used currently to provide the toEnvironmentBlock method needed by JNI for UNIXProcess. + +package java.lang; + +import java.io.*; +import java.util.*; + + +final class UNIXProcessEnvironment +{ + private static final HashMap theEnvironment; + private static final Map theUnmodifiableEnvironment; + static final int MIN_NAME_LENGTH = 0; + + static { + // We cache the C environment. This means that subsequent calls + // to putenv/setenv from C will not be visible from Java code. + byte[][] environ = environ(); + theEnvironment = new HashMap<>(environ.length/2 + 3); + // Read environment variables back to front, + // so that earlier variables override later ones. + for (int i = environ.length-1; i > 0; i-=2) + theEnvironment.put(Variable.valueOf(environ[i-1]), + Value.valueOf(environ[i])); + + theUnmodifiableEnvironment + = Collections.unmodifiableMap + (new StringEnvironment(theEnvironment)); + } + + /* Only for use by System.getenv(String) */ + static String getenv(String name) { + return theUnmodifiableEnvironment.get(name); + } + + /* Only for use by System.getenv() */ + static Map getenv() { + return theUnmodifiableEnvironment; + } + + /* Only for use by ProcessBuilder.environment() */ + @SuppressWarnings("unchecked") + static Map environment() { + return new StringEnvironment + ((Map)(theEnvironment.clone())); + } + + /* Only for use by Runtime.exec(...String[]envp...) */ + static Map emptyEnvironment(int capacity) { + return new StringEnvironment(new HashMap(capacity)); + } + + private static native byte[][] environ(); + + // This class is not instantiable. + private UNIXProcessEnvironment() {} + + // Check that name is suitable for insertion into Environment map + private static void validateVariable(String name) { + if (name.indexOf('=') != -1 || + name.indexOf('\u0000') != -1) + throw new IllegalArgumentException + ("Invalid environment variable name: \"" + name + "\""); + } + + // Check that value is suitable for insertion into Environment map + private static void validateValue(String value) { + if (value.indexOf('\u0000') != -1) + throw new IllegalArgumentException + ("Invalid environment variable value: \"" + value + "\""); + } + + // A class hiding the byteArray-String duality of + // text data on Unixoid operating systems. + private static abstract class ExternalData { + protected final String str; + protected final byte[] bytes; + + protected ExternalData(String str, byte[] bytes) { + this.str = str; + this.bytes = bytes; + } + + public byte[] getBytes() { + return bytes; + } + + public String toString() { + return str; + } + + public boolean equals(Object o) { + return o instanceof ExternalData + && arrayEquals(getBytes(), ((ExternalData) o).getBytes()); + } + + public int hashCode() { + return arrayHash(getBytes()); + } + } + + private static class Variable + extends ExternalData implements Comparable + { + protected Variable(String str, byte[] bytes) { + super(str, bytes); + } + + public static Variable valueOfQueryOnly(Object str) { + return valueOfQueryOnly((String) str); + } + + public static Variable valueOfQueryOnly(String str) { + return new Variable(str, str.getBytes()); + } + + public static Variable valueOf(String str) { + validateVariable(str); + return valueOfQueryOnly(str); + } + + public static Variable valueOf(byte[] bytes) { + return new Variable(new String(bytes), bytes); + } + + public int compareTo(Variable variable) { + return arrayCompare(getBytes(), variable.getBytes()); + } + + public boolean equals(Object o) { + return o instanceof Variable && super.equals(o); + } + } + + private static class Value + extends ExternalData implements Comparable + { + protected Value(String str, byte[] bytes) { + super(str, bytes); + } + + public static Value valueOfQueryOnly(Object str) { + return valueOfQueryOnly((String) str); + } + + public static Value valueOfQueryOnly(String str) { + return new Value(str, str.getBytes()); + } + + public static Value valueOf(String str) { + validateValue(str); + return valueOfQueryOnly(str); + } + + public static Value valueOf(byte[] bytes) { + return new Value(new String(bytes), bytes); + } + + public int compareTo(Value value) { + return arrayCompare(getBytes(), value.getBytes()); + } + + public boolean equals(Object o) { + return o instanceof Value && super.equals(o); + } + } + + // This implements the String map view the user sees. + private static class StringEnvironment + extends AbstractMap + { + private Map m; + private static String toString(Value v) { + return v == null ? null : v.toString(); + } + public StringEnvironment(Map m) {this.m = m;} + public int size() {return m.size();} + public boolean isEmpty() {return m.isEmpty();} + public void clear() { m.clear();} + public boolean containsKey(Object key) { + return m.containsKey(Variable.valueOfQueryOnly(key)); + } + public boolean containsValue(Object value) { + return m.containsValue(Value.valueOfQueryOnly(value)); + } + public String get(Object key) { + return toString(m.get(Variable.valueOfQueryOnly(key))); + } + public String put(String key, String value) { + return toString(m.put(Variable.valueOf(key), + Value.valueOf(value))); + } + public String remove(Object key) { + return toString(m.remove(Variable.valueOfQueryOnly(key))); + } + public Set keySet() { + return new StringKeySet(m.keySet()); + } + public Set> entrySet() { + return new StringEntrySet(m.entrySet()); + } + public Collection values() { + return new StringValues(m.values()); + } + + // It is technically feasible to provide a byte-oriented view + // as follows: + // public Map asByteArrayMap() { + // return new ByteArrayEnvironment(m); + // } + + + // Convert to Unix style environ as a monolithic byte array + // inspired by the Windows Environment Block, except we work + // exclusively with bytes instead of chars, and we need only + // one trailing NUL on Unix. + // This keeps the JNI as simple and efficient as possible. + public byte[] toEnvironmentBlock(int[]envc) { + int count = m.size() * 2; // For added '=' and NUL + for (Map.Entry entry : m.entrySet()) { + count += entry.getKey().getBytes().length; + count += entry.getValue().getBytes().length; + } + + byte[] block = new byte[count]; + + int i = 0; + for (Map.Entry entry : m.entrySet()) { + byte[] key = entry.getKey ().getBytes(); + byte[] value = entry.getValue().getBytes(); + System.arraycopy(key, 0, block, i, key.length); + i+=key.length; + block[i++] = (byte) '='; + System.arraycopy(value, 0, block, i, value.length); + i+=value.length + 1; + // No need to write NUL byte explicitly + //block[i++] = (byte) '\u0000'; + } + envc[0] = m.size(); + return block; + } + } + + static byte[] toEnvironmentBlock(Map map, int[]envc) { + if (map == null) { + return null; + } + + StringEnvironment env = new StringEnvironment(new HashMap(map.size())); + for (Map.Entry entry : map.entrySet()) { + env.put(entry.getKey(), entry.getValue()); + } + + return env.toEnvironmentBlock(envc); + } + + + private static class StringEntry + implements Map.Entry + { + private final Map.Entry e; + public StringEntry(Map.Entry e) {this.e = e;} + public String getKey() {return e.getKey().toString();} + public String getValue() {return e.getValue().toString();} + public String setValue(String newValue) { + return e.setValue(Value.valueOf(newValue)).toString(); + } + public String toString() {return getKey() + "=" + getValue();} + public boolean equals(Object o) { + return o instanceof StringEntry + && e.equals(((StringEntry)o).e); + } + public int hashCode() {return e.hashCode();} + } + + private static class StringEntrySet + extends AbstractSet> + { + private final Set> s; + public StringEntrySet(Set> s) {this.s = s;} + public int size() {return s.size();} + public boolean isEmpty() {return s.isEmpty();} + public void clear() { s.clear();} + public Iterator> iterator() { + return new Iterator>() { + Iterator> i = s.iterator(); + public boolean hasNext() {return i.hasNext();} + public Map.Entry next() { + return new StringEntry(i.next()); + } + public void remove() {i.remove();} + }; + } + private static Map.Entry vvEntry(final Object o) { + if (o instanceof StringEntry) + return ((StringEntry)o).e; + return new Map.Entry() { + public Variable getKey() { + return Variable.valueOfQueryOnly(((Map.Entry)o).getKey()); + } + public Value getValue() { + return Value.valueOfQueryOnly(((Map.Entry)o).getValue()); + } + public Value setValue(Value value) { + throw new UnsupportedOperationException(); + } + }; + } + public boolean contains(Object o) { return s.contains(vvEntry(o)); } + public boolean remove(Object o) { return s.remove(vvEntry(o)); } + public boolean equals(Object o) { + return o instanceof StringEntrySet + && s.equals(((StringEntrySet) o).s); + } + public int hashCode() {return s.hashCode();} + } + + private static class StringValues + extends AbstractCollection + { + private final Collection c; + public StringValues(Collection c) {this.c = c;} + public int size() {return c.size();} + public boolean isEmpty() {return c.isEmpty();} + public void clear() { c.clear();} + public Iterator iterator() { + return new Iterator() { + Iterator i = c.iterator(); + public boolean hasNext() {return i.hasNext();} + public String next() {return i.next().toString();} + public void remove() {i.remove();} + }; + } + public boolean contains(Object o) { + return c.contains(Value.valueOfQueryOnly(o)); + } + public boolean remove(Object o) { + return c.remove(Value.valueOfQueryOnly(o)); + } + public boolean equals(Object o) { + return o instanceof StringValues + && c.equals(((StringValues)o).c); + } + public int hashCode() {return c.hashCode();} + } + + private static class StringKeySet extends AbstractSet { + private final Set s; + public StringKeySet(Set s) {this.s = s;} + public int size() {return s.size();} + public boolean isEmpty() {return s.isEmpty();} + public void clear() { s.clear();} + public Iterator iterator() { + return new Iterator() { + Iterator i = s.iterator(); + public boolean hasNext() {return i.hasNext();} + public String next() {return i.next().toString();} + public void remove() { i.remove();} + }; + } + public boolean contains(Object o) { + return s.contains(Variable.valueOfQueryOnly(o)); + } + public boolean remove(Object o) { + return s.remove(Variable.valueOfQueryOnly(o)); + } + } + + // Replace with general purpose method someday + private static int arrayCompare(byte[]x, byte[] y) { + int min = x.length < y.length ? x.length : y.length; + for (int i = 0; i < min; i++) + if (x[i] != y[i]) + return x[i] - y[i]; + return x.length - y.length; + } + + // Replace with general purpose method someday + private static boolean arrayEquals(byte[] x, byte[] y) { + if (x.length != y.length) + return false; + for (int i = 0; i < x.length; i++) + if (x[i] != y[i]) + return false; + return true; + } + + // Replace with general purpose method someday + private static int arrayHash(byte[] x) { + int hash = 0; + for (int i = 0; i < x.length; i++) + hash = 31 * hash + x[i]; + return hash; + } + +} diff --git a/src/IKVM.Java/local/java/lang/Win32Process.java b/src/IKVM.Java/local/java/lang/Win32Process.java new file mode 100644 index 0000000000..9f804716be --- /dev/null +++ b/src/IKVM.Java/local/java/lang/Win32Process.java @@ -0,0 +1,46 @@ +package java.lang; + +import java.io.*; +import java.util.*; + +final class Win32Process extends Process { + + cli.System.Diagnostics.Process process; + OutputStream outputStream; + InputStream inputStream; + InputStream errorStream; + + static native Process start(String cmdarray[], java.util.Map environment, String dir, ProcessBuilder.Redirect[] redirects, boolean redirectErrorStream) throws IOException; + + private Win32Process(cli.System.Diagnostics.Process process, OutputStream outputStream, InputStream inputStream, InputStream errorStream) { + this.process = process; + this.outputStream = outputStream; + this.inputStream = inputStream; + this.errorStream = errorStream; + } + + @Override + public OutputStream getOutputStream() { + return outputStream; + } + + @Override + public InputStream getInputStream() { + return inputStream; + } + + @Override + public InputStream getErrorStream() { + return errorStream; + } + + @Override + public native int waitFor() throws InterruptedException; + + @Override + public native int exitValue(); + + @Override + public native void destroy(); + +} diff --git a/src/IKVM.Java/local/java/security/ProtectionDomain.java b/src/IKVM.Java/local/java/security/ProtectionDomain.java index 920ac3d633..3a583ec2df 100644 --- a/src/IKVM.Java/local/java/security/ProtectionDomain.java +++ b/src/IKVM.Java/local/java/security/ProtectionDomain.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,16 @@ package java.security; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Map; -import java.util.WeakHashMap; +import java.util.concurrent.ConcurrentHashMap; import sun.misc.JavaSecurityProtectionDomainAccess; import static sun.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache; import sun.security.util.Debug; @@ -518,25 +522,135 @@ public PermissionCollection run() { /** * Used for storing ProtectionDomains as keys in a Map. */ - final class Key {} + static final class Key {} static { SharedSecrets.setJavaSecurityProtectionDomainAccess( new JavaSecurityProtectionDomainAccess() { + @Override public ProtectionDomainCache getProtectionDomainCache() { - return new ProtectionDomainCache() { - private final Map map = - Collections.synchronizedMap - (new WeakHashMap()); - public void put(ProtectionDomain pd, - PermissionCollection pc) { - map.put((pd == null ? null : pd.key), pc); - } - public PermissionCollection get(ProtectionDomain pd) { - return pd == null ? map.get(null) : map.get(pd.key); - } - }; + return new PDCache(); + } + + @Override + public boolean getStaticPermissionsField(ProtectionDomain pd) { + return pd.staticPermissions; } }); } + + /** + * A cache of ProtectionDomains and their Permissions. + * + * This class stores ProtectionDomains as weak keys in a ConcurrentHashMap + * with additional support for checking and removing weak keys that are no + * longer in use. There can be cases where the permission collection may + * have a chain of strong references back to the ProtectionDomain, which + * ordinarily would prevent the entry from being removed from the map. To + * address that, we wrap the permission collection in a SoftReference so + * that it can be reclaimed by the garbage collector due to memory demand. + */ + private static class PDCache implements ProtectionDomainCache { + private final ConcurrentHashMap> + pdMap = new ConcurrentHashMap<>(); + private final ReferenceQueue queue = new ReferenceQueue<>(); + + @Override + public void put(ProtectionDomain pd, PermissionCollection pc) { + processQueue(queue, pdMap); + WeakProtectionDomainKey weakPd = + new WeakProtectionDomainKey(pd, queue); + pdMap.put(weakPd, new SoftReference<>(pc)); + } + + @Override + public PermissionCollection get(ProtectionDomain pd) { + processQueue(queue, pdMap); + WeakProtectionDomainKey weakPd = new WeakProtectionDomainKey(pd); + SoftReference sr = pdMap.get(weakPd); + return (sr == null) ? null : sr.get(); + } + + /** + * Removes weak keys from the map that have been enqueued + * on the reference queue and are no longer in use. + */ + private static void processQueue(ReferenceQueue queue, + ConcurrentHashMap, ?> pdMap) { + Reference ref; + while ((ref = queue.poll()) != null) { + pdMap.remove(ref); + } + } + } + + /** + * A weak key for a ProtectionDomain. + */ + private static class WeakProtectionDomainKey extends WeakReference { + /** + * Saved value of the referent's identity hash code, to maintain + * a consistent hash code after the referent has been cleared + */ + private final int hash; + + /** + * A key representing a null ProtectionDomain. + */ + private static final Key NULL_KEY = new Key(); + + /** + * Create a new WeakProtectionDomain with the specified domain and + * registered with a queue. + */ + WeakProtectionDomainKey(ProtectionDomain pd, ReferenceQueue rq) { + this((pd == null ? NULL_KEY : pd.key), rq); + } + + WeakProtectionDomainKey(ProtectionDomain pd) { + this(pd == null ? NULL_KEY : pd.key); + } + + private WeakProtectionDomainKey(Key key, ReferenceQueue rq) { + super(key, rq); + hash = key.hashCode(); + } + + private WeakProtectionDomainKey(Key key) { + super(key); + hash = key.hashCode(); + } + + /** + * Returns the identity hash code of the original referent. + */ + @Override + public int hashCode() { + return hash; + } + + /** + * Returns true if the given object is an identical + * WeakProtectionDomainKey instance, or, if this object's referent + * has not been cleared and the given object is another + * WeakProtectionDomainKey instance with an identical non-null + * referent as this one. + */ + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + + if (obj instanceof WeakProtectionDomainKey) { + Object referent = get(); + return (referent != null) && + (referent == ((WeakProtectionDomainKey)obj).get()); + } else { + return false; + } + } + } } diff --git a/src/IKVM.Java/local/sun/misc/SharedSecrets.java b/src/IKVM.Java/local/sun/misc/SharedSecrets.java index 091fcfafe9..5a147ffba6 100644 --- a/src/IKVM.Java/local/sun/misc/SharedSecrets.java +++ b/src/IKVM.Java/local/sun/misc/SharedSecrets.java @@ -25,6 +25,7 @@ package sun.misc; +import java.io.ObjectInputStream; import java.util.jar.JarFile; import java.io.Console; import java.io.FileDescriptor; @@ -56,6 +57,7 @@ public class SharedSecrets { private static JavaSecurityAccess javaSecurityAccess; private static JavaUtilZipFileAccess javaUtilZipFileAccess; private static JavaAWTAccess javaAWTAccess; + private static JavaOISAccess javaOISAccess; private static JavaObjectInputStreamAccess javaObjectInputStreamAccess; public static JavaUtilJarAccess javaUtilJarAccess() { @@ -142,6 +144,17 @@ public static JavaIOFileDescriptorAccess getJavaIOFileDescriptorAccess() { return javaIOFileDescriptorAccess; } + public static void setJavaOISAccess(JavaOISAccess access) { + javaOISAccess = access; + } + + public static JavaOISAccess getJavaOISAccess() { + if (javaOISAccess == null) + unsafe.ensureClassInitialized(ObjectInputStream.class); + + return javaOISAccess; + } + public static void setJavaSecurityProtectionDomainAccess (JavaSecurityProtectionDomainAccess jspda) { javaSecurityProtectionDomainAccess = jspda; diff --git a/src/IKVM.Java/local/sun/nio/fs/DotNetFileSystem.java b/src/IKVM.Java/local/sun/nio/fs/DotNetFileSystem.java index d5d2be8ded..250d354979 100644 --- a/src/IKVM.Java/local/sun/nio/fs/DotNetFileSystem.java +++ b/src/IKVM.Java/local/sun/nio/fs/DotNetFileSystem.java @@ -79,17 +79,12 @@ public String getSeparator() { public Iterable getRootDirectories() { SecurityManager sm = System.getSecurityManager(); ArrayList list = new ArrayList<>(); - for (DriveInfo info : DriveInfo.GetDrives()) - { - try - { - if (sm != null) - { + for (DriveInfo info : DriveInfo.GetDrives()) { + try { + if (sm != null) { sm.checkRead(info.get_Name()); } - } - catch (SecurityException _) - { + } catch (SecurityException _) { continue; } @@ -99,41 +94,28 @@ public Iterable getRootDirectories() { return list; } - public Iterable getFileStores() - { + public Iterable getFileStores() { SecurityManager sm = System.getSecurityManager(); - if (sm != null) - { - try - { + if (sm != null) { + try { sm.checkPermission(new RuntimePermission("getFileStoreAttributes")); - } - catch (SecurityException _) - { + } catch (SecurityException _) { return Collections.emptyList(); } } ArrayList list = new ArrayList<>(); - for (DriveInfo info : DriveInfo.GetDrives()) - { - try - { - if (sm != null) - { + for (DriveInfo info : DriveInfo.GetDrives()) { + try { + if (sm != null) { sm.checkRead(info.get_Name()); } - } - catch (SecurityException _) - { + } catch (SecurityException _) { continue; } - try - { + try { list.add(provider.getFileStore(info)); - } - catch (IOException _) - { + } catch (IOException _) { } } @@ -141,25 +123,18 @@ public Iterable getFileStores() return list; } - public Set supportedFileAttributeViews() - { + public Set supportedFileAttributeViews() { return attributes; } - public Path getPath(String first, String... more) - { - if (more.length == 0) - { + public Path getPath(String first, String... more) { + if (more.length == 0) { return new DotNetPath(this, first); - } - else - { + } else { StringBuilder sb = new StringBuilder(first); String sep = sb.length() == 0 ? "" : separator; - for (String s : more) - { - if (s.length() != 0) - { + for (String s : more) { + if (s.length() != 0) { sb.append(sep); sb.append(s); sep = separator; @@ -170,33 +145,23 @@ public Path getPath(String first, String... more) } } - public PathMatcher getPathMatcher(String syntaxAndPattern) - { + public PathMatcher getPathMatcher(String syntaxAndPattern) { String regex; - if (syntaxAndPattern.startsWith("glob:")) - { + if (syntaxAndPattern.startsWith("glob:")) { String pattern = syntaxAndPattern.substring(5); - if (cli.IKVM.Runtime.RuntimeUtil.get_IsWindows()) - { + if (cli.IKVM.Runtime.RuntimeUtil.get_IsWindows()) { regex = Globs.toWindowsRegexPattern(pattern); - } - else - { + } else { regex = Globs.toUnixRegexPattern(pattern); } - } - else if (syntaxAndPattern.startsWith("regex:")) - { + } else if (syntaxAndPattern.startsWith("regex:")) { regex = syntaxAndPattern.substring(6); - } - else if (syntaxAndPattern.indexOf(':') <= 0) - { + } else if (syntaxAndPattern.indexOf(':') <= 0) { throw new IllegalArgumentException(); - } - else - { + } else { throw new UnsupportedOperationException(); } + final Pattern pattern = Pattern.compile(regex, cli.IKVM.Runtime.RuntimeUtil.get_IsWindows() ? Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE : 0); return new PathMatcher() { @Override @@ -206,13 +171,12 @@ public boolean matches(Path path) { }; } - public UserPrincipalLookupService getUserPrincipalLookupService() - { + public UserPrincipalLookupService getUserPrincipalLookupService() { throw new UnsupportedOperationException(); } - static final class NetWatchService implements WatchService - { + static final class NetWatchService implements WatchService { + static final WatchEvent overflowEvent = new WatchEvent() { public Object context() { return null; @@ -224,6 +188,7 @@ public WatchEvent.Kind kind() { return StandardWatchEventKinds.OVERFLOW; } }; + private static final WatchKey CLOSED = new WatchKey() { public boolean isValid() { return false; } public List> pollEvents() { return null; } @@ -231,143 +196,143 @@ public WatchEvent.Kind kind() { public void cancel() { } public Watchable watchable() { return null; } }; + private boolean closed; private final ArrayList keys = new ArrayList<>(); private final LinkedBlockingQueue queue = new LinkedBlockingQueue<>(); - public synchronized void close() - { - if (!closed) - { + public synchronized void close() { + if (!closed) { closed = true; - for (NetWatchKey key : keys) - { + for (NetWatchKey key : keys) { key.close(); } enqueue(CLOSED); } } - private WatchKey checkClosed(WatchKey key) - { - if (key == CLOSED) - { + private WatchKey checkClosed(WatchKey key) { + if (key == CLOSED) { enqueue(CLOSED); throw new ClosedWatchServiceException(); } + return key; } - public WatchKey poll() - { + public WatchKey poll() { return checkClosed(queue.poll()); } - public WatchKey poll(long timeout, TimeUnit unit) throws InterruptedException - { + public WatchKey poll(long timeout, TimeUnit unit) throws InterruptedException { return checkClosed(queue.poll(timeout, unit)); } - public WatchKey take() throws InterruptedException - { + public WatchKey take() throws InterruptedException { return checkClosed(queue.take()); } - void enqueue(WatchKey key) - { - for (;;) - { - try - { + void enqueue(WatchKey key) { + for (;;) { + try { queue.put(key); return; - } - catch (InterruptedException _) - { + } catch (InterruptedException _) { + } } } - private final class NetWatchKey implements WatchKey - { + private final class NetWatchKey implements WatchKey { + private final DotNetPath path; private FileSystemWatcher fsw; private ArrayList> list = new ArrayList<>(); private HashSet modified = new HashSet<>(); private boolean signaled; - NetWatchKey(DotNetPath path) - { + NetWatchKey(DotNetPath path) { this.path = path; } - synchronized void init(final boolean create, final boolean delete, final boolean modify, final boolean overflow, final boolean subtree) - { - if (fsw != null) - { - // we could reuse the FileSystemWatcher, but for now we just recreate it - // (and we run the risk of missing some events while we're doing that) - fsw.Dispose(); - fsw = null; - } - fsw = new FileSystemWatcher(path.path); - if (create) - { - fsw.add_Created(new FileSystemEventHandler(new FileSystemEventHandler.Method() { - public void Invoke(Object sender, FileSystemEventArgs e) { - addEvent(createEvent(e), null); - } - })); - } - if (delete) - { - fsw.add_Deleted(new FileSystemEventHandler(new FileSystemEventHandler.Method() { - public void Invoke(Object sender, FileSystemEventArgs e) { - addEvent(createEvent(e), null); - } - })); - } - if (modify) - { - fsw.add_Changed(new FileSystemEventHandler(new FileSystemEventHandler.Method() { - public void Invoke(Object sender, FileSystemEventArgs e) { - synchronized (NetWatchKey.this) { - if (modified.contains(e.get_Name())) { - // we already have an ENTRY_MODIFY event pending - return; + synchronized void init(final boolean create, final boolean delete, final boolean modify, final boolean overflow, final boolean subtree) throws IOException { + try { + if (fsw != null) { + // we could reuse the FileSystemWatcher, but for now we just recreate it + // (and we run the risk of missing some events while we're doing that) + fsw.Dispose(); + fsw = null; + } + + fsw = new FileSystemWatcher(path.path); + if (create) { + fsw.add_Created(new FileSystemEventHandler(new FileSystemEventHandler.Method() { + public void Invoke(Object sender, FileSystemEventArgs e) { + addEvent(createEvent(e), null); + } + })); + } + + if (delete) { + fsw.add_Deleted(new FileSystemEventHandler(new FileSystemEventHandler.Method() { + public void Invoke(Object sender, FileSystemEventArgs e) { + addEvent(createEvent(e), null); + } + })); + } + + if (modify) { + fsw.add_Changed(new FileSystemEventHandler(new FileSystemEventHandler.Method() { + public void Invoke(Object sender, FileSystemEventArgs e) { + synchronized (NetWatchKey.this) { + if (modified.contains(e.get_Name())) { + // we already have an ENTRY_MODIFY event pending + return; + } } + addEvent(createEvent(e), e.get_Name()); + } + })); + } + + fsw.add_Error(new ErrorEventHandler(new ErrorEventHandler.Method() { + public void Invoke(Object sender, ErrorEventArgs e) { + if (e.GetException() instanceof cli.System.ComponentModel.Win32Exception && ((cli.System.ComponentModel.Win32Exception)e.GetException()).get_ErrorCode() == -2147467259) { + // the directory we were watching was deleted + cancelledByError(); + } else if (overflow) { + addEvent(overflowEvent, null); } - addEvent(createEvent(e), e.get_Name()); } })); - } - fsw.add_Error(new ErrorEventHandler(new ErrorEventHandler.Method() { - public void Invoke(Object sender, ErrorEventArgs e) { - if (e.GetException() instanceof cli.System.ComponentModel.Win32Exception - && ((cli.System.ComponentModel.Win32Exception)e.GetException()).get_ErrorCode() == -2147467259) { - // the directory we were watching was deleted - cancelledByError(); - } else if (overflow) { - addEvent(overflowEvent, null); - } + + if (subtree) { + fsw.set_IncludeSubdirectories(true); + } + + fsw.set_EnableRaisingEvents(true); + } catch (Throwable t) { + if (t instanceof cli.System.IO.FileNotFoundException) { + throw new java.nio.file.NoSuchFileException(((cli.System.IO.FileNotFoundException)t).get_FileName()); + } else if (t instanceof cli.System.Exception) { + throw new IOException(((cli.System.Exception)t).get_Message(), t); + } else { + throw new IOException(t); } - })); - if (subtree) - { - fsw.set_IncludeSubdirectories(true); } - fsw.set_EnableRaisingEvents(true); } - WatchEvent createEvent(final FileSystemEventArgs e) - { + WatchEvent createEvent(final FileSystemEventArgs e) { return new WatchEvent() { + public Path context() { return new DotNetPath((DotNetFileSystem)path.getFileSystem(), e.get_Name()); } + public int count() { return 1; } + public WatchEvent.Kind kind() { switch (e.get_ChangeType().Value) { case WatcherChangeTypes.Created: @@ -378,120 +343,103 @@ public WatchEvent.Kind kind() { return StandardWatchEventKinds.ENTRY_MODIFY; } } + }; } - void cancelledByError() - { + void cancelledByError() { cancel(); - synchronized (this) - { - if (!signaled) - { + synchronized (this) { + if (!signaled) { signaled = true; enqueue(this); } } } - synchronized void addEvent(WatchEvent event, String modified) - { + synchronized void addEvent(WatchEvent event, String modified) { list.add(event); - if (modified != null) - { + if (modified != null) { this.modified.add(modified); } - if (!signaled) - { + if (!signaled) { signaled = true; enqueue(this); } } - public synchronized boolean isValid() - { + public synchronized boolean isValid() { return fsw != null; } - public synchronized List> pollEvents() - { + public synchronized List> pollEvents() { ArrayList> r = list; list = new ArrayList<>(); modified.clear(); return r; } - public synchronized boolean reset() - { - if (fsw == null) - { + public synchronized boolean reset() { + if (fsw == null) { return false; } - if (signaled) - { - if (list.size() == 0) - { + + if (signaled) { + if (list.size() == 0) { signaled = false; - } - else - { + } else { enqueue(this); } } + return true; } - void close() - { - if (fsw != null) - { + void close() { + if (fsw != null) { fsw.Dispose(); fsw = null; } } - public void cancel() - { - synchronized (NetWatchService.this) - { + public void cancel() { + synchronized (NetWatchService.this) { keys.remove(this); close(); } } - public Watchable watchable() - { + public Watchable watchable() { return path; } + } - synchronized WatchKey register(DotNetPath path, boolean create, boolean delete, boolean modify, boolean overflow, boolean subtree) - { - if (closed) - { + synchronized WatchKey register(DotNetPath path, boolean create, boolean delete, boolean modify, boolean overflow, boolean subtree) throws IOException { + if (closed) { throw new ClosedWatchServiceException(); } + NetWatchKey existing = null; - for (NetWatchKey key : keys) - { - if (key.watchable().equals(path)) - { + for (NetWatchKey key : keys) { + if (key.watchable().equals(path)) { existing = key; break; } } - if (existing == null) - { + + if (existing == null) { existing = new NetWatchKey(path); keys.add(existing); } + existing.init(create, delete, modify, overflow, subtree); return existing; } + } - public WatchService newWatchService() throws IOException - { + public WatchService newWatchService() throws IOException { return new NetWatchService(); } diff --git a/src/IKVM.Java/local/sun/nio/fs/DotNetPath.java b/src/IKVM.Java/local/sun/nio/fs/DotNetPath.java index 5ee0e320e6..2766c08381 100644 --- a/src/IKVM.Java/local/sun/nio/fs/DotNetPath.java +++ b/src/IKVM.Java/local/sun/nio/fs/DotNetPath.java @@ -39,14 +39,10 @@ final class DotNetPath extends AbstractPath { private final DotNetFileSystem fs; final String path; - DotNetPath(DotNetFileSystem fs, String path) - { - if (cli.IKVM.Runtime.RuntimeUtil.get_IsWindows()) - { + DotNetPath(DotNetFileSystem fs, String path) { + if (cli.IKVM.Runtime.RuntimeUtil.get_IsWindows()) { path = WindowsPathParser.parse(path).path(); - } - else - { + } else { StringBuilder sb = null; int separatorCount = 0; boolean prevWasSeparator = false; @@ -107,132 +103,108 @@ public Path getRoot() { } private int getRootLength() { - if (cli.IKVM.Runtime.RuntimeUtil.get_IsWindows()) - { - if (path.length() >= 2 && path.charAt(1) == ':') - { - if (path.length() >= 3 && path.charAt(2) == '\\') - { + if (cli.IKVM.Runtime.RuntimeUtil.get_IsWindows()) { + if (path.length() >= 2 && path.charAt(1) == ':') { + if (path.length() >= 3 && path.charAt(2) == '\\') { return 3; - } - else - { + } else { return 2; } - } - else if (path.startsWith("\\\\")) - { + } else if (path.startsWith("\\\\")) { return path.indexOf('\\', path.indexOf('\\', 2) + 1) + 1; } } - if (path.length() >= 1 && path.charAt(0) == cli.System.IO.Path.DirectorySeparatorChar) - { + if (path.length() >= 1 && path.charAt(0) == cli.System.IO.Path.DirectorySeparatorChar) { return 1; - } - else - { + } else { return 0; } } public Path getFileName() { - if (path.length() == 0) - { + if (path.length() == 0) { return this; } - if (path.length() == getRootLength()) - { + if (path.length() == getRootLength()) { return null; } String name = cli.System.IO.Path.GetFileName(path); - if (name == null || name.length() == 0) - { + if (name == null || name.length() == 0) { return null; } + return new DotNetPath(fs, name); } - public Path getParent() - { - if (path.length() == getRootLength()) - { + public Path getParent() { + if (path.length() == getRootLength()) { return null; } String parent = cli.System.IO.Path.GetDirectoryName(path); - if (parent == null || parent.length() == 0) - { + if (parent == null || parent.length() == 0) { return null; } + return new DotNetPath(fs, parent); } - public int getNameCount() - { + public int getNameCount() { int len = getRootLength(); - if (path.length() == len) - { + if (path.length() == len) { return len == 0 ? 1 : 0; } int count = 1; - for (int i = len; i < path.length(); i++) - { - if (path.charAt(i) == cli.System.IO.Path.DirectorySeparatorChar) - { + for (int i = len; i < path.length(); i++) { + if (path.charAt(i) == cli.System.IO.Path.DirectorySeparatorChar) { count++; } } + return count; } - public Path getName(int index) - { + public Path getName(int index) { return new DotNetPath(fs, getNameImpl(index)); } - private String getNameImpl(int index) - { - for (int pos = getRootLength(); pos < path.length(); index--) - { + private String getNameImpl(int index) { + for (int pos = getRootLength(); pos < path.length(); index--) { int next = path.indexOf(cli.System.IO.Path.DirectorySeparatorChar, pos); - if (index == 0) - { + if (index == 0) { return next == -1 ? path.substring(pos) : path.substring(pos, next); } - if (next == -1) - { + if (next == -1) { break; } pos = next + 1; } - if (path.length() == 0 && index == 0) - { + + if (path.length() == 0 && index == 0) { return ""; } + throw new IllegalArgumentException(); } - public Path subpath(int beginIndex, int endIndex) - { + public Path subpath(int beginIndex, int endIndex) { StringBuilder sb = new StringBuilder(); - for (int i = beginIndex; i < endIndex; i++) - { - if (i != beginIndex) - { + for (int i = beginIndex; i < endIndex; i++) { + if (i != beginIndex) { sb.append(cli.System.IO.Path.DirectorySeparatorChar); } sb.append(getNameImpl(i)); } + return new DotNetPath(fs, sb.toString()); } - public boolean startsWith(Path other) - { + public boolean startsWith(Path other) { String npath = DotNetPath.from(other).path; - if (npath.length() == 0) - { + if (npath.length() == 0) { return path.length() == 0; } + return path.regionMatches(cli.IKVM.Runtime.RuntimeUtil.get_IsWindows(), 0, npath, 0, npath.length()) && (npath.length() == getRootLength() || (npath.length() > getRootLength() @@ -240,27 +212,22 @@ public boolean startsWith(Path other) || (path.length() > npath.length() && path.charAt(npath.length()) == cli.System.IO.Path.DirectorySeparatorChar)))); } - public boolean endsWith(Path other) - { + public boolean endsWith(Path other) { DotNetPath nother = DotNetPath.from(other); String npath = nother.path; - if (npath.length() > path.length()) - { + if (npath.length() > path.length()) { return false; } - if (npath.length() == 0) - { + if (npath.length() == 0) { return path.length() == 0; } int nameCount = getNameCount(); int otherNameCount = nother.getNameCount(); - if (otherNameCount > nameCount) - { + if (otherNameCount > nameCount) { return false; } int otherRootLength = nother.getRootLength(); - if (otherRootLength > 0) - { + if (otherRootLength > 0) { if (otherNameCount != nameCount || getRootLength() != otherRootLength || !path.regionMatches(cli.IKVM.Runtime.RuntimeUtil.get_IsWindows(), 0, npath, 0, otherRootLength)) @@ -268,6 +235,7 @@ public boolean endsWith(Path other) return false; } } + int skip = nameCount - otherNameCount; for (int i = 0; i < otherNameCount; i++) { @@ -278,6 +246,7 @@ public boolean endsWith(Path other) return false; } } + return true; } @@ -473,170 +442,165 @@ private DotNetPath emptyPath() { return new DotNetPath(fs, ""); } - public URI toUri() - { - if (cli.IKVM.Runtime.RuntimeUtil.get_IsWindows()) - { + public URI toUri() { + if (cli.IKVM.Runtime.RuntimeUtil.get_IsWindows()) { return DotNetWindowsUriSupport.toUri(this); - } - else - { + } else { return DotNetUnixUriUtils.toUri(this); } } - public DotNetPath toAbsolutePath() - { - if (isAbsolute()) - { + public DotNetPath toAbsolutePath() { + if (isAbsolute()) { return this; } + // System.getProperty("user.dir") will trigger the specified security check return new DotNetPath(fs, cli.System.IO.Path.GetFullPath(cli.System.IO.Path.Combine(System.getProperty("user.dir"), path))); } - public Path toRealPath(LinkOption... options) throws IOException - { + public Path toRealPath(LinkOption... options) throws IOException { SecurityManager sm = System.getSecurityManager(); - if (sm != null) - { + if (sm != null) { sm.checkRead(path); - if (!isAbsolute()) - { + if (!isAbsolute()) { sm.checkPropertyAccess("user.dir"); } } + return new DotNetPath(fs, toRealPathImpl(path)); } private static native String toRealPathImpl(String path); - public WatchKey register(WatchService watcher, WatchEvent.Kind[] events, WatchEvent.Modifier... modifiers) throws IOException - { - if (!(watcher instanceof DotNetFileSystem.NetWatchService)) - { - // null check - watcher.getClass(); - throw new ProviderMismatchException(); - } - boolean create = false; - boolean delete = false; - boolean modify = false; - boolean overflow = false; - boolean subtree = false; - for (WatchEvent.Kind kind : events) - { - if (kind == StandardWatchEventKinds.ENTRY_CREATE) - { - create = true; - } - else if (kind == StandardWatchEventKinds.ENTRY_DELETE) - { - delete = true; - } - else if (kind == StandardWatchEventKinds.ENTRY_MODIFY) - { - modify = true; - } - else if (kind == StandardWatchEventKinds.OVERFLOW) - { - overflow = true; + public WatchKey register(WatchService watcher, WatchEvent.Kind[] events, WatchEvent.Modifier... modifiers) throws IOException { + if (watcher instanceof DotNetFileSystem.NetWatchService) { + boolean create = false; + boolean delete = false; + boolean modify = false; + boolean overflow = false; + boolean subtree = false; + + for (WatchEvent.Kind kind : events) { + if (kind == StandardWatchEventKinds.ENTRY_CREATE) { + create = true; + } else if (kind == StandardWatchEventKinds.ENTRY_DELETE) { + delete = true; + } else if (kind == StandardWatchEventKinds.ENTRY_MODIFY) { + modify = true; + } else if (kind == StandardWatchEventKinds.OVERFLOW) { + overflow = true; + } else { + // null check + kind.getClass(); + throw new UnsupportedOperationException(); + } } - else - { - // null check - kind.getClass(); - throw new UnsupportedOperationException(); + + if (!create && !delete && !modify) { + throw new IllegalArgumentException(); } - } - if (!create && !delete && !modify) - { - throw new IllegalArgumentException(); - } - for (WatchEvent.Modifier modifier : modifiers) - { - if (modifier == ExtendedWatchEventModifier.FILE_TREE) - { - subtree = true; + + for (WatchEvent.Modifier modifier : modifiers) { + if (modifier == ExtendedWatchEventModifier.FILE_TREE) { + subtree = true; + } else if (modifier instanceof SensitivityWatchEventModifier) { + // ignore + } else { + // null check + modifier.getClass(); + throw new UnsupportedOperationException(); + } } - else if (modifier instanceof SensitivityWatchEventModifier) - { - // ignore + + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkRead(path); + if (subtree) { + sm.checkRead(path + cli.System.IO.Path.DirectorySeparatorChar + '-'); + } } - else - { - // null check - modifier.getClass(); - throw new UnsupportedOperationException(); + + return ((DotNetFileSystem.NetWatchService)watcher).register(this, create, delete, modify, overflow, subtree); + } else if (watcher instanceof PollingWatchService) { + boolean subtree = false; + + for (WatchEvent.Modifier modifier : modifiers) { + if (modifier == ExtendedWatchEventModifier.FILE_TREE) { + subtree = true; + } else if (modifier instanceof SensitivityWatchEventModifier) { + // ignore + } else { + // null check + modifier.getClass(); + throw new UnsupportedOperationException(); + } } - } - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - { - sm.checkRead(path); - if (subtree) - { - sm.checkRead(path + cli.System.IO.Path.DirectorySeparatorChar + '-'); + + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkRead(path); + if (subtree) { + sm.checkRead(path + cli.System.IO.Path.DirectorySeparatorChar + '-'); + } } + + return ((PollingWatchService)watcher).register(this, events, modifiers); + } else { + watcher.getClass(); // null check + throw new ProviderMismatchException(); } - return ((DotNetFileSystem.NetWatchService)watcher).register(this, create, delete, modify, overflow, subtree); } - public int compareTo(Path other) - { + public int compareTo(Path other) { String path2 = ((DotNetPath)other).path; int len1 = path.length(); int len2 = path2.length(); int min = Math.min(len1, len2); - for (int i = 0; i < min; i++) - { + for (int i = 0; i < min; i++) { char c1 = path.charAt(i); char c2 = path2.charAt(i); - if (c1 != c2 && Character.toUpperCase(c1) != Character.toUpperCase(c2)) - { + if (c1 != c2 && Character.toUpperCase(c1) != Character.toUpperCase(c2)) { return c1 - c2; } } + return len1 - len2; } - public boolean equals(Object other) - { - if (!(other instanceof DotNetPath)) - { + public boolean equals(Object other) { + if (!(other instanceof DotNetPath)) { return false; } + return compareTo((DotNetPath)other) == 0; } - public int hashCode() - { + public int hashCode() { int hash = 0; - for (int i = 0; i < path.length(); i++) - { + for (int i = 0; i < path.length(); i++) { hash = 97 * hash + Character.toUpperCase(path.charAt(i)); } + return hash; } - public String toString() - { + public String toString() { return path; } - boolean isUnc() - { + boolean isUnc() { return cli.IKVM.Runtime.RuntimeUtil.get_IsWindows() && getRootLength() > 3; } - static DotNetPath from(Path path) - { - if (!(path instanceof DotNetPath)) - { + static DotNetPath from(Path path) { + if (!(path instanceof DotNetPath)) { // null check path.getClass(); throw new ProviderMismatchException(); } + return (DotNetPath)path; } -} + +} \ No newline at end of file diff --git a/src/IKVM.Java/local/sun/nio/fs/DotNetUnixUriUtils.java b/src/IKVM.Java/local/sun/nio/fs/DotNetUnixUriUtils.java index 7b4c82543d..e05a86d9e4 100644 --- a/src/IKVM.Java/local/sun/nio/fs/DotNetUnixUriUtils.java +++ b/src/IKVM.Java/local/sun/nio/fs/DotNetUnixUriUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,6 +69,32 @@ static Path fromUri(DotNetFileSystem fs, URI uri) { // transform escaped octets and unescaped characters to bytes if (p.endsWith("/") && len > 1) len--; + byte[] result = new byte[len]; + int rlen = 0; + int pos = 0; + while (pos < len) { + char c = p.charAt(pos++); + byte b; + if (c == '%') { + assert (pos+2) <= len; + char c1 = p.charAt(pos++); + char c2 = p.charAt(pos++); + b = (byte)((decode(c1) << 4) | decode(c2)); + if (b == 0) + throw new IllegalArgumentException("Nul character not allowed"); + } else { + if (c == 0 || c >= 0x80) + throw new IllegalArgumentException("Bad escape"); + b = (byte)c; + } + if (b == '/' && rlen > 0 && result[rlen-1] == '/') { + // skip redundant slashes + continue; + } + result[rlen++] = b; + } + if (rlen != result.length) + result = Arrays.copyOf(result, rlen); return new DotNetPath(fs, p); } @@ -94,7 +120,7 @@ static URI toUri(DotNetPath up) { // trailing slash if directory if (sb.charAt(sb.length()-1) != '/') { try { - if (cli.System.IO.Directory.Exists(sb.toString()) || isVfsDirectory(sb.toString())) + if (cli.System.IO.Directory.Exists(up.toString()) || isVfsDirectory(up.toString())) sb.append('/'); } catch (Throwable x) { // ignore @@ -217,15 +243,15 @@ private static int decode(char c) { private static final long H_PCHAR = H_UNRESERVED | highMask(":@&=+$,"); - // All valid path characters - private static final long L_PATH = L_PCHAR | lowMask(";/"); - private static final long H_PATH = H_PCHAR | highMask(";/"); + // All valid path characters + private static final long L_PATH = L_PCHAR | lowMask(";/"); + private static final long H_PATH = H_PCHAR | highMask(";/"); - private final static char[] hexDigits = { + private final static char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; static native boolean isVfsDirectory(String path); -} \ No newline at end of file +} diff --git a/src/IKVM.Java/local/sun/nio/fs/DotNetWindowsUriSupport.java b/src/IKVM.Java/local/sun/nio/fs/DotNetWindowsUriSupport.java index fa37311593..7c98fd3f5f 100644 --- a/src/IKVM.Java/local/sun/nio/fs/DotNetWindowsUriSupport.java +++ b/src/IKVM.Java/local/sun/nio/fs/DotNetWindowsUriSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,9 +104,8 @@ static URI toUri(DotNetPath path) { boolean addSlash = false; if (!s.endsWith("\\")) { try { - addSlash = cli.System.IO.Directory.Exists(s) || isVfsDirectory(s); + addSlash = cli.System.IO.Directory.Exists(s) || isVfsDirectory(s); } catch (Throwable x) { - } } @@ -168,4 +167,4 @@ static DotNetPath fromUri(DotNetFileSystem fs, URI uri) { static native boolean isVfsDirectory(String path); -} \ No newline at end of file +} diff --git a/src/IKVM.Java/local/sun/reflect/ReflectionFactory.java b/src/IKVM.Java/local/sun/reflect/ReflectionFactory.java index 35cae84cc3..76456056c7 100644 --- a/src/IKVM.Java/local/sun/reflect/ReflectionFactory.java +++ b/src/IKVM.Java/local/sun/reflect/ReflectionFactory.java @@ -31,16 +31,28 @@ package sun.reflect; +import java.io.Externalizable; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamClass; +import java.io.OptionalDataException; +import java.io.Serializable; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import java.lang.reflect.Field; import java.lang.reflect.Executable; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; import java.security.AccessController; import java.security.Permission; import java.security.PrivilegedAction; +import java.util.Objects; + import sun.reflect.misc.ReflectUtil; + /**

The master factory for all reflective objects, both those in java.lang.reflect (Fields, Methods, Constructors) as well as their delegates (FieldAccessors, MethodAccessors, ConstructorAccessors). @@ -61,6 +73,9 @@ public class ReflectionFactory { // Provides access to package-private mechanisms in java.lang.reflect private static volatile LangReflectAccess langReflectAccess; + /* Method for static class initializer , or null */ + private static volatile Method hasStaticInitializerMethod; + private ReflectionFactory() { } @@ -282,6 +297,42 @@ public byte[] getExecutableTypeAnnotationBytes(Executable ex) { if (constructorToCall.getDeclaringClass() == classToInstantiate) { return constructorToCall; } + return generateConstructor(classToInstantiate, constructorToCall); + } + + /** + * Returns an accessible constructor capable of creating instances + * of the given class, initialized by the given constructor. + * + * @param classToInstantiate the class to instantiate + * @param constructorToCall the constructor to call + * @return an accessible constructor + */ + public final Constructor newConstructorForSerialization(Class cl) { + Class initCl = cl; + while (Serializable.class.isAssignableFrom(initCl)) { + if ((initCl = initCl.getSuperclass()) == null) { + return null; + } + } + Constructor constructorToCall; + try { + constructorToCall = initCl.getDeclaredConstructor(); + int mods = constructorToCall.getModifiers(); + if ((mods & Modifier.PRIVATE) != 0 || + ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 && + !packageEquals(cl, initCl))) { + return null; + } + } catch (NoSuchMethodException ex) { + return null; + } + return generateConstructor(cl, constructorToCall); + } + + private final Constructor generateConstructor(Class classToInstantiate, + Constructor constructorToCall) { + ConstructorAccessor acc = newConstructorAccessorForSerialization(classToInstantiate, constructorToCall); Constructor c = newConstructor(constructorToCall.getDeclaringClass(), @@ -297,9 +348,222 @@ public byte[] getExecutableTypeAnnotationBytes(Executable ex) { langReflectAccess(). getConstructorParameterAnnotations(constructorToCall)); setConstructorAccessor(c, acc); + c.setAccessible(true); return c; } + /** + * Returns an accessible no-arg constructor for an externalizable class to be + * initialized using a public no-argument constructor. + * + * @param cl the class to instantiate + * @return A no-arg constructor for the class; returns {@code null} if + * the class does not implement {@link java.io.Externalizable} + */ + public final Constructor newConstructorForExternalization(Class cl) { + if (!Externalizable.class.isAssignableFrom(cl)) { + return null; + } + try { + Constructor cons = cl.getConstructor(); + cons.setAccessible(true); + return cons; + } catch (NoSuchMethodException ex) { + return null; + } + } + + /** + * Returns a direct MethodHandle for the {@code readObject} method on + * a Serializable class. + * The first argument of {@link MethodHandle#invoke} is the serializable + * object and the second argument is the {@code ObjectInputStream} passed to + * {@code readObject}. + * + * @param cl a Serializable class + * @return a direct MethodHandle for the {@code readObject} method of the class or + * {@code null} if the class does not have a {@code readObject} method + */ + public final MethodHandle readObjectForSerialization(Class cl) { + return findReadWriteObjectForSerialization(cl, "readObject", ObjectInputStream.class); + } + + /** + * Returns a direct MethodHandle for the {@code readObjectNoData} method on + * a Serializable class. + * The first argument of {@link MethodHandle#invoke} is the serializable + * object and the second argument is the {@code ObjectInputStream} passed to + * {@code readObjectNoData}. + * + * @param cl a Serializable class + * @return a direct MethodHandle for the {@code readObjectNoData} method + * of the class or {@code null} if the class does not have a + * {@code readObjectNoData} method + */ + public final MethodHandle readObjectNoDataForSerialization(Class cl) { + return findReadWriteObjectForSerialization(cl, "readObjectNoData", ObjectInputStream.class); + } + + /** + * Returns a direct MethodHandle for the {@code writeObject} method on + * a Serializable class. + * The first argument of {@link MethodHandle#invoke} is the serializable + * object and the second argument is the {@code ObjectOutputStream} passed to + * {@code writeObject}. + * + * @param cl a Serializable class + * @return a direct MethodHandle for the {@code writeObject} method of the class or + * {@code null} if the class does not have a {@code writeObject} method + */ + public final MethodHandle writeObjectForSerialization(Class cl) { + return findReadWriteObjectForSerialization(cl, "writeObject", ObjectOutputStream.class); + } + + private final MethodHandle findReadWriteObjectForSerialization(Class cl, + String methodName, + Class streamClass) { + if (!Serializable.class.isAssignableFrom(cl)) { + return null; + } + + try { + Method meth = cl.getDeclaredMethod(methodName, streamClass); + int mods = meth.getModifiers(); + if (meth.getReturnType() != Void.TYPE || + Modifier.isStatic(mods) || + !Modifier.isPrivate(mods)) { + return null; + } + meth.setAccessible(true); + return MethodHandles.lookup().unreflect(meth); + } catch (NoSuchMethodException ex) { + return null; + } catch (IllegalAccessException ex1) { + throw new InternalError("Error", ex1); + } + } + + /** + * Returns a direct MethodHandle for the {@code readResolve} method on + * a serializable class. + * The single argument of {@link MethodHandle#invoke} is the serializable + * object. + * + * @param cl the Serializable class + * @return a direct MethodHandle for the {@code readResolve} method of the class or + * {@code null} if the class does not have a {@code readResolve} method + */ + public final MethodHandle readResolveForSerialization(Class cl) { + return getReplaceResolveForSerialization(cl, "readResolve"); + } + + /** + * Returns a direct MethodHandle for the {@code writeReplace} method on + * a serializable class. + * The single argument of {@link MethodHandle#invoke} is the serializable + * object. + * + * @param cl the Serializable class + * @return a direct MethodHandle for the {@code writeReplace} method of the class or + * {@code null} if the class does not have a {@code writeReplace} method + */ + public final MethodHandle writeReplaceForSerialization(Class cl) { + return getReplaceResolveForSerialization(cl, "writeReplace"); + } + + /** + * Returns a direct MethodHandle for the {@code writeReplace} method on + * a serializable class. + * The single argument of {@link MethodHandle#invoke} is the serializable + * object. + * + * @param cl the Serializable class + * @return a direct MethodHandle for the {@code writeReplace} method of the class or + * {@code null} if the class does not have a {@code writeReplace} method + */ + private MethodHandle getReplaceResolveForSerialization(Class cl, + String methodName) { + if (!Serializable.class.isAssignableFrom(cl)) { + return null; + } + + Class defCl = cl; + while (defCl != null) { + try { + Method m = defCl.getDeclaredMethod(methodName); + if (m.getReturnType() != Object.class) { + return null; + } + int mods = m.getModifiers(); + if (Modifier.isStatic(mods) | Modifier.isAbstract(mods)) { + return null; + } else if (Modifier.isPublic(mods) | Modifier.isProtected(mods)) { + // fall through + } else if (Modifier.isPrivate(mods) && (cl != defCl)) { + return null; + } else if (!packageEquals(cl, defCl)) { + return null; + } + try { + // Normal return + m.setAccessible(true); + return MethodHandles.lookup().unreflect(m); + } catch (IllegalAccessException ex0) { + // setAccessible should prevent IAE + throw new InternalError("Error", ex0); + } + } catch (NoSuchMethodException ex) { + defCl = defCl.getSuperclass(); + } + } + return null; + } + + /** + * Returns true if the class has a static initializer. + * The presence of a static initializer is used to compute the serialVersionUID. + * @param cl a serializable classLook + * @return {@code true} if the class has a static initializer, + * otherwise {@code false} + */ + public final boolean hasStaticInitializerForSerialization(Class cl) { + Method m = hasStaticInitializerMethod; + if (m == null) { + try { + m = ObjectStreamClass.class.getDeclaredMethod("hasStaticInitializer", + new Class[]{Class.class}); + m.setAccessible(true); + hasStaticInitializerMethod = m; + } catch (NoSuchMethodException ex) { + throw new InternalError("No such method hasStaticInitializer on " + + ObjectStreamClass.class, ex); + } + } + try { + return (Boolean) m.invoke(null, cl); + } catch (InvocationTargetException | IllegalAccessException ex) { + throw new InternalError("Exception invoking hasStaticInitializer", ex); + } + } + + /** + * Returns a new OptionalDataException with {@code eof} set to {@code true} + * or {@code false}. + * @param bool the value of {@code eof} in the created OptionalDataException + * @return a new OptionalDataException + */ + public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) { + try { + Constructor boolCtor = + OptionalDataException.class.getDeclaredConstructor(Boolean.TYPE); + boolCtor.setAccessible(true); + return boolCtor.newInstance(bool); + } catch (NoSuchMethodException | InstantiationException| + IllegalAccessException|InvocationTargetException ex) { + throw new InternalError("unable to create OptionalDataException", ex); + } + } + //-------------------------------------------------------------------------- // // Internals only below this point @@ -315,4 +579,17 @@ private static LangReflectAccess langReflectAccess() { } return langReflectAccess; } + + /** + * Returns true if classes are defined in the classloader and same package, false + * otherwise. + * @param cl1 a class + * @param cl2 another class + * @returns true if the two classes are in the same classloader and package + */ + private static boolean packageEquals(Class cl1, Class cl2) { + return cl1.getClassLoader() == cl2.getClassLoader() && + Objects.equals(cl1.getPackage(), cl2.getPackage()); + } + } diff --git a/src/IKVM.MSBuild.Tasks.Tests/IKVM.MSBuild.Tasks.Tests.csproj b/src/IKVM.MSBuild.Tasks.Tests/IKVM.MSBuild.Tasks.Tests.csproj index 6b89928275..3adcdd1793 100644 --- a/src/IKVM.MSBuild.Tasks.Tests/IKVM.MSBuild.Tasks.Tests.csproj +++ b/src/IKVM.MSBuild.Tasks.Tests/IKVM.MSBuild.Tasks.Tests.csproj @@ -16,11 +16,11 @@ - - + + - - + + diff --git a/src/IKVM.MSBuild.Tasks/IKVM.MSBuild.Tasks.csproj b/src/IKVM.MSBuild.Tasks/IKVM.MSBuild.Tasks.csproj index af84027354..b11eec0712 100644 --- a/src/IKVM.MSBuild.Tasks/IKVM.MSBuild.Tasks.csproj +++ b/src/IKVM.MSBuild.Tasks/IKVM.MSBuild.Tasks.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/IKVM.MSBuild.Tasks/IkvmJsonParser.cs b/src/IKVM.MSBuild.Tasks/IkvmJsonParser.cs index 5aba198027..238256265c 100644 --- a/src/IKVM.MSBuild.Tasks/IkvmJsonParser.cs +++ b/src/IKVM.MSBuild.Tasks/IkvmJsonParser.cs @@ -5,6 +5,7 @@ using System.Collections; using System.Collections.Generic; using System.Reflection; + using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Text; @@ -321,7 +322,11 @@ static Dictionary CreateMemberNameDictionary(T[] members) where T static object ParseObject(Type type, string json) { +#if NETFRAMEWORK object instance = FormatterServices.GetUninitializedObject(type); +#else + object instance = RuntimeHelpers.GetUninitializedObject(type); +#endif //The list is split into key/value pairs only, this means the split must be divisible by 2 to be valid JSON List elems = Split(json); diff --git a/src/IKVM.MSBuild.Tests/IKVM.MSBuild.Tests.csproj b/src/IKVM.MSBuild.Tests/IKVM.MSBuild.Tests.csproj index 5bd05d0dbd..7d8e160b92 100644 --- a/src/IKVM.MSBuild.Tests/IKVM.MSBuild.Tests.csproj +++ b/src/IKVM.MSBuild.Tests/IKVM.MSBuild.Tests.csproj @@ -23,10 +23,10 @@ - - - - + + + + diff --git a/src/IKVM.MSBuild/buildTransitive/IKVM.MSBuild.IkvmToolReference.targets b/src/IKVM.MSBuild/buildTransitive/IKVM.MSBuild.IkvmToolReference.targets index f907d67543..c78d621306 100644 --- a/src/IKVM.MSBuild/buildTransitive/IKVM.MSBuild.IkvmToolReference.targets +++ b/src/IKVM.MSBuild/buildTransitive/IKVM.MSBuild.IkvmToolReference.targets @@ -55,7 +55,7 @@ - + @@ -77,7 +77,7 @@ - + @@ -99,7 +99,7 @@ - + diff --git a/src/IKVM.NET.Sdk.Tests/IKVM.NET.Sdk.Tests.csproj b/src/IKVM.NET.Sdk.Tests/IKVM.NET.Sdk.Tests.csproj index d0f8d5e694..a3c347fb76 100644 --- a/src/IKVM.NET.Sdk.Tests/IKVM.NET.Sdk.Tests.csproj +++ b/src/IKVM.NET.Sdk.Tests/IKVM.NET.Sdk.Tests.csproj @@ -13,11 +13,11 @@ - - + + - - + + diff --git a/src/IKVM.NET.Sdk/targets/IKVM.Java.Core.NoTasks.targets b/src/IKVM.NET.Sdk/targets/IKVM.Java.Core.NoTasks.targets index 713fbd42c7..6416b1baa8 100644 --- a/src/IKVM.NET.Sdk/targets/IKVM.Java.Core.NoTasks.targets +++ b/src/IKVM.NET.Sdk/targets/IKVM.Java.Core.NoTasks.targets @@ -111,7 +111,7 @@ Items = Items.OrderBy(i => i.ItemSpec).ToArray(); - + @@ -181,7 +181,7 @@ Items = Items.OrderBy(i => i.ItemSpec).ToArray(); - + @@ -205,7 +205,7 @@ Items = Items.OrderBy(i => i.ItemSpec).ToArray(); - + <_Convert Include="@(Convert)" /> @@ -252,7 +252,7 @@ Items = Items.OrderBy(i => i.ItemSpec).ToArray(); <_IkvmCompilerArgs Include="-sharedclassloader" Condition=" '$(SharedClassLoader)' == 'true' " /> <_IkvmCompilerArgs Include="-w$(WarningLevel)" /> <_IkvmCompilerArgs Include="-noparameterreflection" Condition=" '$(NoParameterReflection)' == 'true' " /> - <_IkvmCompilerArgs Include="-exclude:$([System.IO.Path]::GetFullPath('$(_ExcludeFilePath)'))" Condition="Exists('$(_ExcludeFilePath)')" /> + <_IkvmCompilerArgs Include="-exclude:$([System.IO.Path]::GetFullPath('$(_ExcludeFilePath)'))" Condition="Exists('$(_ExcludeFilePath)') And '@(ExcludeRegex)' != '' " /> <_IkvmCompilerArgs Include="@(_AssemblyAttributesClass->'-assemblyattributes:%(FullPath)')" /> <_IkvmCompilerReferencePath Remove="@(_IkvmCompilerReferencePath)" /> <_IkvmCompilerReferencePath Include="@(_IkvmCompilerReferencePathWithRefAssemblies)" Condition=" '%(_IkvmCompilerReferencePathWithRefAssemblies.HideFromJava)' != 'true' " /> @@ -282,7 +282,7 @@ Items = Items.OrderBy(i => i.ItemSpec).ToArray(); - + diff --git a/src/IKVM.OpenJDK.Tests/IKVM.OpenJDK.Tests.csproj b/src/IKVM.OpenJDK.Tests/IKVM.OpenJDK.Tests.csproj index a3dcf6db76..cf068e8b66 100644 --- a/src/IKVM.OpenJDK.Tests/IKVM.OpenJDK.Tests.csproj +++ b/src/IKVM.OpenJDK.Tests/IKVM.OpenJDK.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/IKVM.OpenJDK.Tests/jdk/ExcludeList.txt b/src/IKVM.OpenJDK.Tests/jdk/ExcludeList.txt index 4588743322..4048399a9e 100644 --- a/src/IKVM.OpenJDK.Tests/jdk/ExcludeList.txt +++ b/src/IKVM.OpenJDK.Tests/jdk/ExcludeList.txt @@ -831,6 +831,27 @@ java/awt/xembed/server/RunTestXEmbed.java java/awt/xembed/server/TestXEmbedServer.java generic-all java/awt/xembed/server/TestXEmbedServerJava.java generic-all java/awt/xembed/server/TesterClient.java generic-all +com/sun/java/swing/plaf/windows/Test8173145.java generic-all +java/awt/Container/MoveToOtherScreenTest/MoveToOtherScreenTest.java generic-all +java/awt/Dialog/DialogAboveFrame/DialogAboveFrameTest.java generic-all +java/awt/EventQueue/6980209/bug6980209.java generic-all +java/awt/Focus/ModalDialogActivationTest/ModalDialogActivationTest.java generic-all +java/awt/font/MonospacedGlyphWidth/MonospacedGlyphWidthTest.java generic-all +java/awt/font/TextLayout/DiacriticsDrawingTest.java generic-all +java/awt/Frame/FrameResize/ShowChildWhileResizingTest.java generic-all +java/awt/Frame/NormalToIconified/NormalToIconifiedTest.java generic-all +java/awt/Frame/ObscuredFrame/ObscuredFrameTest.java generic-all +java/awt/geom/AffineTransform/InvalidTransformParameterTest.java generic-all +java/awt/image/VolatileImage/VolatileImageBug.java generic-all +java/awt/Mouse/EnterExitEvents/ModalDialogEnterExitEventsTest.java generic-all +java/awt/MouseInfo/GetPointerInfoTest.java generic-all +java/awt/MouseInfo/MultiscreenPointerInfo.java generic-all +java/awt/Paint/ComponentIsNotDrawnAfterRemoveAddTest/ComponentIsNotDrawnAfterRemoveAddTest.java generic-all +java/awt/print/PrinterJob/PrintCrashTest.java generic-all +java/awt/TextArea/TextAreaEditing/TextAreaEditing.java generic-all +java/awt/Window/WindowDeadlockTest/WindowDeadlockTest.java generic-all +java/awt/Window/WindowJumpingTest/WindowJumpingTest.java generic-all +sun/java2d/ClassCastExceptionForInvalidSurface.java generic-all java/beans/Beans/6669869/TestDesignTime.java generic-all java/beans/Beans/6669869/TestGuiAvailable.java generic-all java/beans/EventHandler/Test6179222.java generic-all @@ -1568,7 +1589,6 @@ java/security/cert/pkix/policyChanges/TestPolicy.java java/security/cert/PKIXRevocationChecker/OcspUnauthorized.java generic-all java/security/cert/PKIXRevocationChecker/UnitTest.java generic-all java/security/cert/PolicyNode/GetPolicyQualifiers.java generic-all -java/security/cert/pkix/policyChanges/TestPolicy.java generic-all java/text/Bidi/BidiConformance.java generic-all java/text/Bidi/BidiEmbeddingTest.java generic-all java/text/Format/DateFormat/Bug6645292.java generic-all @@ -1845,6 +1865,7 @@ java/util/zip/ZipFile/ReadLongZipFileName.java java/util/zip/ZipFile/StreamZipEntriesTest.java generic-all javax/accessibility/6986385/bug6986385.java generic-all javax/accessibility/8069268/bug8069268.java generic-all +javax/accessibility/JList/AccessibleJListChildNPETest.java generic-all javax/crypto/JceSecurity/SunJCE_BC_LoadOrdering.java generic-all javax/crypto/SecretKeyFactory/FailOverTest.sh generic-all javax/crypto/sanity/CheckManifestForRelease.java generic-all @@ -2616,6 +2637,14 @@ javax/swing/text/html/parser/Parser/7165725/bug7165725.java javax/swing/text/html/parser/Parser/8028616/bug8028616.java generic-all javax/swing/text/html/parser/Test8017492.java generic-all javax/swing/tree/DefaultTreeCellRenderer/7142955/bug7142955.java generic-all +javax/swing/JComboBox/8136998/bug8136998.java generic-all +javax/swing/JMenuItem/8152981/MenuItemIconTest.java generic-all +javax/swing/JProgressBar/8161664/ProgressBarMemoryLeakTest.java generic-all +javax/swing/plaf/basic/BasicComboPopup/8154069/Bug8154069.java generic-all +javax/swing/plaf/basic/BasicLabelUI/bug7172652.java generic-all +javax/swing/plaf/nimbus/8057791/bug8057791.java generic-all +javax/swing/text/FlowView/LayoutTest.java generic-all +javax/swing/text/html/parser/Parser/HtmlCommentTagParseTest/HtmlCommentTagParseTest.java generic-all javax/xml/bind/marshal/8036981/Test.java generic-all javax/xml/crypto/dsig/GenerationTests.java generic-all javax/xml/crypto/dsig/SecurityManager/XMLDSigWithSecMgr.java generic-all @@ -2900,6 +2929,8 @@ sun/security/krb5/auto/TwoPrinces.java sun/security/krb5/auto/TwoTab.java generic-all sun/security/krb5/auto/UdpTcp.java generic-all sun/security/krb5/auto/UnboundService.java generic-all +sun/security/krb5/auto/UnboundSSLMultipleKeys.java generic-all +sun/security/krb5/auto/UnboundSSLPrincipalProperty.java generic-all sun/security/krb5/auto/UseCacheAndStoreKey.java generic-all sun/security/krb5/auto/W83.java generic-all sun/security/krb5/ccache/EmptyCC.java generic-all @@ -3041,12 +3072,6 @@ sun/security/x509/AlgorithmId/ExtensibleAlgorithmId.java sun/text/resources/LocaleDataTest.java generic-all sun/tools/common/CommonTests.sh generic-all sun/tools/java/CFCTest.java generic-all -sun/tools/jcmd/jcmd-Defaults.sh generic-all -sun/tools/jcmd/jcmd-big-script.sh generic-all -sun/tools/jcmd/jcmd-f.sh generic-all -sun/tools/jcmd/jcmd-help-help.sh generic-all -sun/tools/jcmd/jcmd-help.sh generic-all -sun/tools/jcmd/jcmd-pid.sh generic-all sun/tools/jconsole/ResourceCheckTest.sh generic-all sun/tools/jhat/HatHeapDump1Test.java generic-all sun/tools/jhat/ParseTest.sh generic-all @@ -3352,13 +3377,11 @@ javax/swing/plaf/nimbus/8041642/ScrollBarThumbVisibleTest.java sun/security/mscapi/IterateWindowsRootStore.java generic-all sun/security/mscapi/CastError.java generic-all -# TODO: Reenable after 8u112 is integrated -java/lang/invoke/CustomizedLambdaFormTest.java generic-all - # probably related to field or method order javax/xml/bind/jxc/8073519/SchemagenErrorReporting.java generic-all # Broken on OS X +com/apple/laf/ScreenMenu/ScreenMenuMemoryLeakTest.java macosx-all com/sun/corba/transport/KeepAliveSockets.java macosx-all com/sun/crypto/provider/Cipher/AES/TestISO10126Padding.java macosx-all com/sun/crypto/provider/Cipher/Blowfish/BlowfishTestVector.java macosx-all @@ -3369,6 +3392,9 @@ java/net/DatagramPacket/ReuseBuf.java java/net/DatagramSocket/PortUnreachable.java macosx-all java/net/DatagramSocket/Send12k.java macosx-all java/net/DatagramSocket/SendSize.java macosx-all +java/net/Inet6Address/B6206527.java macosx-all +java/net/Inet6Address/B6558853.java macosx-all +java/net/InetAddress/CheckJNI.java macosx-all java/net/MulticastSocket/B6427403.java macosx-all java/net/MulticastSocket/JoinGroup.java macosx-all java/net/MulticastSocket/Leave.java macosx-all @@ -3378,12 +3404,12 @@ java/net/PlainSocketImpl/SetBufferSize.java java/net/Socket/LinkLocal.java macosx-all java/net/Socket/SetSoLinger.java macosx-all java/net/Socket/TrafficClass.java macosx-all +java/net/SocketPermission/SocketPermissionTest.java macosx-all java/net/ipv6tests/TcpTest.java macosx-all java/net/ipv6tests/UdpTest.java macosx-all java/nio/MappedByteBuffer/Basic.java macosx-all java/nio/MappedByteBuffer/Force.java macosx-all java/nio/channels/AsynchronousSocketChannel/Basic.java macosx-all -java/nio/channels/AsynchronousFileChannel/Basic.java macosx-all java/nio/channels/DatagramChannel/AdaptDatagramSocket.java macosx-all java/nio/channels/DatagramChannel/BasicMulticastTests.java macosx-all java/nio/channels/DatagramChannel/Connect.java macosx-all @@ -3415,9 +3441,71 @@ java/util/prefs/RemoveNullKeyCheck.java java/util/prefs/RemoveReadOnlyNode.java macosx-all java/util/prefs/RemoveUnregedListener.java macosx-all jdk/net/Sockets/SupportedOptions.java macosx-all -sun/security/krb5/auto/MSOID2.java macosx-all +#java/nio/channels/AsynchronousFileChannel/Basic.java macosx-all sun/net/www/http/KeepAliveStream/KeepAliveStreamCloseWithWrongContentLength.java macosx-all -java/net/InetAddress/CheckJNI.java macosx-all -java/net/Inet6Address/B6206527.java macosx-all -java/net/Inet6Address/B6558853.java macosx-all +sun/security/krb5/auto/MSOID2.java macosx-all +sun/security/krb5/auto/TicketSName.java macosx-all +sun/security/krb5/auto/ForwardableCheck.java macosx-all +sun/security/krb5/auto/RefreshKrb5Config.java macosx-all +sun/security/krb5/auto/principalProperty/PrincipalSystemPropTest.java macosx-all +sun/security/krb5/auto/BogusKDC.java macosx-all +sun/security/krb5/auto/KrbTicket.java macosx-all +sun/security/krb5/auto/UnboundSSL.java macosx-all +sun/nio/ch/TestMaxCachedBufferSize.java macosx-all + +# Windows-PRNG SecureRandom +java/security/SecureRandom/DefaultProvider.java generic-all + +# pkcs11 +sun/security/pkcs11/Mac/MacKAT.java generic-all +sun/security/pkcs11/Mac/MacSameTest.java generic-all +sun/security/pkcs11/Secmod/LoadKeystore.java generic-all + +# JPS +sun/tools/jps/TestJpsClass.java generic-all +sun/tools/jps/TestJpsJar.java generic-all +sun/tools/jps/TestJpsSanity.java generic-all + +# jcmd +sun/tools/jcmd/TestJcmdDefaults.java generic-all +sun/tools/jcmd/TestJcmdSanity.java generic-all + +# jdi +com/sun/jdi/oom/OomDebugTest.java generic-all +com/sun/jdi/EvalArraysAsList.sh generic-all +com/sun/jdi/RedefineAddPrivateMethod.sh generic-all + +# not implemented/not applicable +javax/management/mxbean/MXBeanInteropTest1.java generic-all + +# rogue. +java/beans/Introspector/8159696/UnloadClassBeanInfo.java generic-all + +# fails with -Xbootclasspath/a (needs implement) +java/lang/invoke/CustomizedLambdaFormTest.java generic-all + +# Shell fails on Windows +sun/security/tools/keytool/keyalg.sh windows-all + +# Class(-Loader) GC not supported +javax/management/mxbean/MXBeanLoadingTest1.java generic-all + +# RMI, fails, but works in Debug with attached Debugger +sun/rmi/server/UnicastServerRef/FilterUSRTest.java generic-all + +# These tests assume limited policy, reenable after integrating u161 +javax/crypto/CryptoPermission/TestUnlimited.java generic-all +com/sun/crypto/provider/Cipher/Blowfish/TestCipherBlowfish.java generic-all +com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBESameBuffer.java generic-all +com/sun/crypto/provider/Cipher/PBE/TestCipherKeyWrapperPBEKey.java generic-all +com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithDefaultProvider.java generic-all +com/sun/crypto/provider/Cipher/PBE/TestCipherPBE.java generic-all +com/sun/crypto/provider/Cipher/PBE/TestCipherPBECons.java generic-all +com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithProviderChange.java generic-all +com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithRemoveAddProvider.java generic-all + +## JDK8u152-b16, new broken tests +sun/nio/cs/Test4200310.sh generic-all +# expired certificate +sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java generic-all diff --git a/src/IKVM.Reflection.Tests/IKVM.Reflection.Tests.csproj b/src/IKVM.Reflection.Tests/IKVM.Reflection.Tests.csproj index be055641bd..34778cc416 100644 --- a/src/IKVM.Reflection.Tests/IKVM.Reflection.Tests.csproj +++ b/src/IKVM.Reflection.Tests/IKVM.Reflection.Tests.csproj @@ -5,14 +5,14 @@ - + - - - + + + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/IKVM.Reflection/IKVM.Reflection.csproj b/src/IKVM.Reflection/IKVM.Reflection.csproj index 754032f372..a6ce4b5996 100644 --- a/src/IKVM.Reflection/IKVM.Reflection.csproj +++ b/src/IKVM.Reflection/IKVM.Reflection.csproj @@ -3,9 +3,9 @@ net472;net6.0;net7.0 IKVM implementation of System.Reflection[.Emit] - true true 11 + true diff --git a/src/IKVM.Runtime/Accessors/Java/Lang/ProcessImplAccessor.cs b/src/IKVM.Runtime/Accessors/Java/Lang/Win32ProcessAccessor.cs similarity index 77% rename from src/IKVM.Runtime/Accessors/Java/Lang/ProcessImplAccessor.cs rename to src/IKVM.Runtime/Accessors/Java/Lang/Win32ProcessAccessor.cs index df6f9aa7ea..8ad55e96c2 100644 --- a/src/IKVM.Runtime/Accessors/Java/Lang/ProcessImplAccessor.cs +++ b/src/IKVM.Runtime/Accessors/Java/Lang/Win32ProcessAccessor.cs @@ -7,9 +7,9 @@ namespace IKVM.Runtime.Accessors.Java.Lang #if FIRST_PASS == false && EXPORTER == false && IMPORTER == false ///

- /// Provides runtime access to the 'java.io.ProcessImpl' type. + /// Provides runtime access to the 'java.lang.Win32Process' type. /// - internal sealed class ProcessImplAccessor : Accessor + internal sealed class Win32ProcessAccessor : Accessor { MethodAccessor> init; @@ -19,8 +19,8 @@ internal sealed class ProcessImplAccessor : Accessor /// Initializes a new instance. /// /// - public ProcessImplAccessor(AccessorTypeResolver resolver) : - base(resolver, "java.lang.ProcessImpl") + public Win32ProcessAccessor(AccessorTypeResolver resolver) : + base(resolver, "java.lang.Win32Process") { } diff --git a/src/IKVM.Runtime/Accessors/Sun/Nio/Fs/UnixFileKeyAccessor.cs b/src/IKVM.Runtime/Accessors/Sun/Nio/Fs/UnixFileKeyAccessor.cs new file mode 100644 index 0000000000..52899938b2 --- /dev/null +++ b/src/IKVM.Runtime/Accessors/Sun/Nio/Fs/UnixFileKeyAccessor.cs @@ -0,0 +1,35 @@ +using System; + +namespace IKVM.Runtime.Accessors.Sun.Nio.Fs +{ + +#if FIRST_PASS == false && EXPORTER == false && IMPORTER == false + + internal sealed class UnixFileKeyAccessor : Accessor + { + + MethodAccessor> init; + + /// + /// Initializes a new instance. + /// + /// + public UnixFileKeyAccessor(AccessorTypeResolver resolver) : + base(resolver, "sun.nio.fs.UnixFileKey") + { + + } + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public object Init(long st_dev, long st_ino) => GetConstructor(ref init, typeof(long), typeof(long)).Invoker(st_dev, st_ino); + + } + +#endif + +} \ No newline at end of file diff --git a/src/IKVM.Runtime/CodeEmitter.cs b/src/IKVM.Runtime/CodeEmitter.cs index ae01e8bfa6..289f66fac7 100644 --- a/src/IKVM.Runtime/CodeEmitter.cs +++ b/src/IKVM.Runtime/CodeEmitter.cs @@ -245,7 +245,8 @@ internal void RealEmit(int ilOffset, CodeEmitter codeEmitter, ref int lineNumber } } - public override string ToString() => (pseudo == CodeType.OpCode ? opcode.ToString() : Enum.GetName(typeof(CodeType), pseudo)) + " " + data; + /// + public override readonly string ToString() => pseudo == CodeType.OpCode ? opcode.ToString() + " " + data : pseudo.ToString() + " " + data; } @@ -2144,7 +2145,7 @@ internal CodeEmitterLocal AllocTempLocal(Type type) { for (int i = 0; i < tempLocals.Length; i++) { - CodeEmitterLocal lb = tempLocals[i]; + var lb = tempLocals[i]; if (lb != null && lb.LocalType == type) { tempLocals[i] = null; diff --git a/src/IKVM.Runtime/JNI/JNIEnv.cs b/src/IKVM.Runtime/JNI/JNIEnv.cs index 6d0963d143..265d629351 100644 --- a/src/IKVM.Runtime/JNI/JNIEnv.cs +++ b/src/IKVM.Runtime/JNI/JNIEnv.cs @@ -25,7 +25,9 @@ Jeroen Frijters using System.Collections.Generic; using System.Diagnostics; using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Serialization; using IKVM.ByteCode.Text; @@ -739,7 +741,11 @@ static jobject AllocObjectImpl(JNIEnv* pEnv, RuntimeJavaType wrapper) return IntPtr.Zero; } wrapper.Finish(); - return pEnv->MakeLocalRef(System.Runtime.Serialization.FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType)); +#if NETFRAMEWORK + return pEnv->MakeLocalRef(FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType)); +#else + return pEnv->MakeLocalRef(RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType)); +#endif } catch (RetargetableJavaException e) { diff --git a/src/IKVM.Runtime/Java/Externs/java/io/FileInputStream.cs b/src/IKVM.Runtime/Java/Externs/java/io/FileInputStream.cs index eead14b991..65133f02ef 100644 --- a/src/IKVM.Runtime/Java/Externs/java/io/FileInputStream.cs +++ b/src/IKVM.Runtime/Java/Externs/java/io/FileInputStream.cs @@ -33,9 +33,9 @@ static class FileInputStream delegate int __jniDelegate__readBytes(IntPtr jniEnv, IntPtr self, IntPtr bytes, int off, int len); static __jniDelegate__readBytes __jniPtr__readBytes; delegate long __jniDelegate__skip(IntPtr jniEnv, IntPtr self, long toSkip); - static __jniDelegate__skip __jniPtr__skip; + static __jniDelegate__skip __jniPtr__skip0; delegate int __jniDelegate__available(IntPtr jniEnv, IntPtr self); - static __jniDelegate__available __jniPtr__available; + static __jniDelegate__available __jniPtr__available0; delegate int __jniDelegate__close0(IntPtr jniEnv, IntPtr self); static __jniDelegate__close0 __jniPtr__close0; @@ -249,12 +249,12 @@ public static int readBytes(object this_, byte[] bytes, int off, int len) } /// - /// Implements the native method 'skip'. + /// Implements the native method 'skip0'. /// /// - /// + /// /// - public static long skip(object this_, long toSkip) + public static long skip0(object this_, long n) { #if FIRST_PASS throw new NotImplementedException(); @@ -275,7 +275,7 @@ public static long skip(object this_, long toSkip) try { long cur = stream.Position; - long end = stream.Seek(toSkip, SeekOrigin.Current); + long end = stream.Seek(n, SeekOrigin.Current); return end - cur; } catch (ObjectDisposedException e) @@ -294,12 +294,12 @@ public static long skip(object this_, long toSkip) else { __callerID ??= global::ikvm.@internal.CallerID.create(typeof(global::java.io.FileInputStream).TypeHandle); - __jniPtr__skip ??= Marshal.GetDelegateForFunctionPointer<__jniDelegate__skip>(JNIFrame.GetFuncPtr(__callerID, "java/io/FileInputStream", nameof(skip), "(J)J")); + __jniPtr__skip0 ??= Marshal.GetDelegateForFunctionPointer<__jniDelegate__skip>(JNIFrame.GetFuncPtr(__callerID, "java/io/FileInputStream", nameof(skip0), "(J)J")); var jniFrm = new JNIFrame(); var jniEnv = jniFrm.Enter(__callerID); try { - return __jniPtr__skip(jniEnv, jniFrm.MakeLocalRef(this_), toSkip); + return __jniPtr__skip0(jniEnv, jniFrm.MakeLocalRef(this_), n); } catch (Exception ex) { @@ -316,11 +316,11 @@ public static long skip(object this_, long toSkip) } /// - /// Implements the native method 'available'. + /// Implements the native method 'available0'. /// /// /// - public static int available(object this_) + public static int available0(object this_) { #if FIRST_PASS throw new NotImplementedException(); @@ -358,12 +358,12 @@ public static int available(object this_) else { __callerID ??= global::ikvm.@internal.CallerID.create(typeof(global::java.io.FileInputStream).TypeHandle); - __jniPtr__available ??= Marshal.GetDelegateForFunctionPointer<__jniDelegate__available>(JNIFrame.GetFuncPtr(__callerID, "java/io/FileInputStream", nameof(available), "()I")); + __jniPtr__available0 ??= Marshal.GetDelegateForFunctionPointer<__jniDelegate__available>(JNIFrame.GetFuncPtr(__callerID, "java/io/FileInputStream", nameof(available0), "()I")); var jniFrm = new JNIFrame(); var jniEnv = jniFrm.Enter(__callerID); try { - return __jniPtr__available(jniEnv, jniFrm.MakeLocalRef(this_)); + return __jniPtr__available0(jniEnv, jniFrm.MakeLocalRef(this_)); } catch (Exception ex) { diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/UNIXProcess.cs b/src/IKVM.Runtime/Java/Externs/java/lang/UNIXProcess.cs new file mode 100644 index 0000000000..725f3285d8 --- /dev/null +++ b/src/IKVM.Runtime/Java/Externs/java/lang/UNIXProcess.cs @@ -0,0 +1,78 @@ +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +using IKVM.Runtime; +using IKVM.Runtime.JNI; + +namespace IKVM.Java.Externs.java.lang +{ + + static class UNIXProcess + { + +#if FIRST_PASS == false + + static global::ikvm.@internal.CallerID __callerID; + delegate void __jniDelegate__init(IntPtr jniEnv, IntPtr clazz); + static __jniDelegate__init __jniPtr__init; + +#endif + + /// + /// Implements the native method 'init'. + /// + /// + /// We save and load the old SIGCHLD handler between calls to prevent Java from overwriting the .NET handler. This isn't thread safe but should suffice since it's limited to static initialization. + /// + /// + public static unsafe void init() + { +#if FIRST_PASS + throw new NotImplementedException(); +#else + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + return; + + // get size of sigaction structure and allocate space + var size = LibIkvm.Instance.sig_get_size_sigaction(); + Debug.Assert(size > 0); + var save = stackalloc byte[size]; + + // save old SIGCHLD structure + if (LibIkvm.Instance.sig_get_chld_action(save) != 0) + throw new InternalException("Could not save SIGCHLD handler."); + + try + { + __callerID ??= global::ikvm.@internal.CallerID.create(typeof(global::java.lang.UNIXProcess).TypeHandle); + __jniPtr__init ??= Marshal.GetDelegateForFunctionPointer<__jniDelegate__init>(JNIFrame.GetFuncPtr(__callerID, "java/lang/UNIXProcess", nameof(init), "()V")); + var jniFrm = new JNIFrame(); + var jniEnv = jniFrm.Enter(__callerID); + try + { + __jniPtr__init(jniEnv, jniFrm.MakeLocalRef(ClassLiteral.Value)); + } + catch (Exception ex) + { + global::System.Console.WriteLine("*** exception in native code ***"); + global::System.Console.WriteLine(ex); + throw; + } + finally + { + jniFrm.Leave(); + } + } + finally + { + // restore old SIGCHLD structure + if (LibIkvm.Instance.sig_set_chld_action(save) != 0) + throw new InternalException("Could not restore SIGCHLD handler."); + } +#endif + } + + } + +} diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/UNIXProcessEnvironment.cs b/src/IKVM.Runtime/Java/Externs/java/lang/UNIXProcessEnvironment.cs new file mode 100644 index 0000000000..8ff1cdad6b --- /dev/null +++ b/src/IKVM.Runtime/Java/Externs/java/lang/UNIXProcessEnvironment.cs @@ -0,0 +1,53 @@ +using System; +using System.Runtime.InteropServices; + +using IKVM.Runtime; +using IKVM.Runtime.JNI; + +namespace IKVM.Java.Externs.java.lang +{ + + static class UNIXProcessEnvironment + { + +#if FIRST_PASS == false + + static global::ikvm.@internal.CallerID __callerID; + delegate IntPtr __jniDelegate__environ(IntPtr jniEnv, IntPtr clazz); + static __jniDelegate__environ __jniPtr__environ; + +#endif + + /// + /// Implements the native method 'environ'. + /// + /// + public static object environ() + { +#if FIRST_PASS + throw new NotImplementedException(); +#else + __callerID ??= global::ikvm.@internal.CallerID.create(typeof(global::java.lang.UNIXProcessEnvironment).TypeHandle); + __jniPtr__environ ??= Marshal.GetDelegateForFunctionPointer<__jniDelegate__environ>(JNIFrame.GetFuncPtr(__callerID, "java/lang/ProcessEnvironment", nameof(environ), "()[[B")); + var jniFrm = new JNIFrame(); + var jniEnv = jniFrm.Enter(__callerID); + try + { + return jniFrm.UnwrapLocalRef(__jniPtr__environ(jniEnv, jniFrm.MakeLocalRef(ClassLiteral.Value))); + } + catch (Exception ex) + { + global::System.Console.WriteLine("*** exception in native code ***"); + global::System.Console.WriteLine(ex); + throw; + } + finally + { + jniFrm.Leave(); + } +#endif + } + + } + +} diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/ProcessImpl.cs b/src/IKVM.Runtime/Java/Externs/java/lang/Win32Process.cs similarity index 94% rename from src/IKVM.Runtime/Java/Externs/java/lang/ProcessImpl.cs rename to src/IKVM.Runtime/Java/Externs/java/lang/Win32Process.cs index 5440adfbfe..816a96b821 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/ProcessImpl.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/Win32Process.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Linq; using System.Security.AccessControl; using System.Text.RegularExpressions; using System.Threading; @@ -18,9 +17,9 @@ namespace IKVM.Java.Externs.java.lang { /// - /// Implements the native methods for 'ProcessImpl'. + /// Implements the native methods for 'Win32Process'. /// - static class ProcessImpl + static class Win32Process { #if FIRST_PASS == false @@ -45,7 +44,7 @@ static class ProcessImpl static MapEntryAccessor mapEntryAccessor; static SetAccessor setAccessor; static IteratorAccessor iteratorAccessor; - static ProcessImplAccessor processImplAccessor; + static Win32ProcessAccessor win32ProcessAccessor; static CallerIDAccessor CallerIDAccessor => JVM.Internal.BaseAccessors.Get(ref callerIDAccessor); @@ -87,7 +86,7 @@ static class ProcessImpl static IteratorAccessor IteratorAccessor => JVM.Internal.BaseAccessors.Get(ref iteratorAccessor); - static ProcessImplAccessor ProcessImplAccessor => JVM.Internal.BaseAccessors.Get(ref processImplAccessor); + static Win32ProcessAccessor Win32ProcessAccessor => JVM.Internal.BaseAccessors.Get(ref win32ProcessAccessor); #endif @@ -229,10 +228,7 @@ static object Create(string[] cmd, Dictionary env, string dir, S #if FIRST_PASS throw new NotImplementedException(); #else - if (RuntimeUtil.IsWindows) - return CreateWindows(cmd, env, dir, s0, s1, s2, redirectErrorStream); - else - return CreateUnix(cmd, env, dir, s0, s1, s2, redirectErrorStream); + return CreateWindows(cmd, env, dir, s0, s1, s2, redirectErrorStream); #endif } @@ -607,10 +603,11 @@ static bool WindowsExecutableExists(string file) return true; else if (Directory.Exists(file)) return false; - else if (file.IndexOf('.') == -1 && File.Exists(file + ".exe")) - return true; - else + if (Path.GetFileName(file) is not string filename) + return false; + if (filename.IndexOf('.') != -1) return false; + return File.Exists(file + ".exe"); } catch { @@ -618,34 +615,6 @@ static bool WindowsExecutableExists(string file) } } - /// - /// Creates a new 'ProcessImpl' for a Unix machine. - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - static object CreateUnix(string[] cmd, Dictionary env, string dir, Stream h0, Stream h1, Stream h2, bool redirectErrorStream) - { -#if NETFRAMEWORK - throw new NotImplementedException(); -#else - var psi = new ProcessStartInfo(); - psi.FileName = cmd[0]; - - foreach (var arg in cmd.Skip(1)) - psi.ArgumentList.Add(arg); - - return Create(psi, env, dir, h0, h1, h2, redirectErrorStream); -#endif - - } - /// /// Creates a new 'ProcessImpl' based on the filename and arguments configured on the . /// @@ -752,10 +721,10 @@ static object Create(ProcessStartInfo psi, Dictionary env, strin s0 = h0 == null ? ProcessBuilderNullOutputStreamAccessor.GetInstance() : BufferedOutputStreamAccessor.Init(FileOutputStreamAccessor.Init2(CreateFileDescriptor(h0))); s1 = h1 == null ? ProcessBuilderNullInputStreamAccessor.GetInstance() : BufferedInputStreamAccessor.Init(FileInputStreamAccessor.Init2(CreateFileDescriptor(h1))); s2 = h2 == null ? ProcessBuilderNullInputStreamAccessor.GetInstance() : FileInputStreamAccessor.Init2(CreateFileDescriptor(h2)); - }), null, CallerIDAccessor.InvokeCreate(ProcessImplAccessor.Type.TypeHandle)); + }), null, CallerIDAccessor.InvokeCreate(Win32ProcessAccessor.Type.TypeHandle)); // return new process - return ProcessImplAccessor.Init(process, s0, s1, s2); + return Win32ProcessAccessor.Init(process, s0, s1, s2); #endif } @@ -933,7 +902,7 @@ public static int waitFor(object self) #if FIRST_PASS throw new NotImplementedException(); #else - var pid = ProcessImplAccessor.GetProcess(self); + var pid = Win32ProcessAccessor.GetProcess(self); if (pid.HasExited) return pid.ExitCode; @@ -953,7 +922,7 @@ public static int exitValue(object self) #if FIRST_PASS throw new NotImplementedException(); #else - var pid = ProcessImplAccessor.GetProcess(self); + var pid = Win32ProcessAccessor.GetProcess(self); if (pid.HasExited == false) throw new global::java.lang.IllegalThreadStateException("process has not exited"); @@ -966,7 +935,7 @@ public static void destroy(object self) #if FIRST_PASS throw new NotImplementedException(); #else - var pid = ProcessImplAccessor.GetProcess(self); + var pid = Win32ProcessAccessor.GetProcess(self); if (pid.HasExited) return; diff --git a/src/IKVM.Runtime/Java/Externs/java/net/PlainDatagramSocketImpl.cs b/src/IKVM.Runtime/Java/Externs/java/net/PlainDatagramSocketImpl.cs index 32f9236bb8..b2282b62aa 100644 --- a/src/IKVM.Runtime/Java/Externs/java/net/PlainDatagramSocketImpl.cs +++ b/src/IKVM.Runtime/Java/Externs/java/net/PlainDatagramSocketImpl.cs @@ -98,6 +98,7 @@ static Action MakeAnonymousTypeDelegate(MethodInfo method) static __jniDelegate__init __jniPtr__init; #if NETCOREAPP3_1_OR_GREATER + // HACK .NET Core has an explicit check for _isConnected https://github.com/dotnet/runtime/issues/77962 static readonly FieldInfo SocketIsConnectedField = typeof(Socket).GetField("_isConnected", BindingFlags.NonPublic | BindingFlags.Instance); static readonly Action SocketIsConnectedFieldSetter = MakeFieldSetter(SocketIsConnectedField); @@ -538,38 +539,42 @@ public static int peek(object this_, object address_) #if !FIRST_PASS /// - /// Peek at the queue to see if there is an ICMP port unreachable. If there is, then receive it. + /// Peek at the queue to see if there is an ICMP port unreachable. If there is then receive it. /// /// static void PurgeOutstandingICMP(Socket socket) { - while (true) + // check for outstanding packet + while (socket.Poll(0, SelectMode.SelectRead)) { - // check for outstanding packet - if (socket.Poll(0, SelectMode.SelectRead) == false) - break; + var ep = (EndPoint)new IPEndPoint(IPAddress.IPv6Any, 0); + // check for real data on the socket, if so, we can exit, no exceptions try { - var ep = (EndPoint)new IPEndPoint(IPAddress.IPv6Any, 0); socket.EndReceiveFrom(socket.BeginReceiveFrom(TempBuffer, 0, TempBuffer.Length, SocketFlags.Peek, ref ep, null, null), ref ep); + return; } - catch (SocketException e) when (e.SocketErrorCode == SocketError.ConnectionReset) + catch { - try - { - var ep = (EndPoint)new IPEndPoint(IPAddress.IPv6Any, 0); - socket.EndReceiveFrom(socket.BeginReceiveFrom(TempBuffer, 0, TempBuffer.Length, SocketFlags.Peek, ref ep, null, null), ref ep); - } - catch (SocketException e2) when (e2.SocketErrorCode == SocketError.ConnectionReset) - { - - } - - continue; + // swallow any exceptions emitted by peek, the exception will be thrown again upon following read } - break; + // consume real data (exception) + try + { + socket.EndReceiveFrom(socket.BeginReceiveFrom(TempBuffer, 0, TempBuffer.Length, SocketFlags.None, ref ep, null, null), ref ep); + } + catch (SocketException e) when (e.SocketErrorCode == SocketError.ConnectionReset) + { + // we consumed exception reset and thus can continue to look for next + } + catch + { + // some other exception besides connection reset + // ignore since the purge method should only purge + return; + } } } diff --git a/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs b/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs index f62ef262f6..16202305f3 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs @@ -1704,7 +1704,11 @@ public static object allocateInstance(object self, global::java.lang.Class cls) throw x.ToJava(); } +#if NETFRAMEWORK return FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType); +#else + return RuntimeHelpers.GetUninitializedObject(wrapper.TypeAsBaseType); +#endif } /// diff --git a/src/IKVM.Runtime/Java/Externs/sun/nio/fs/DotNetDosFileAttributes.cs b/src/IKVM.Runtime/Java/Externs/sun/nio/fs/DotNetDosFileAttributes.cs index ba2858bf09..70f8ba83b5 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/nio/fs/DotNetDosFileAttributes.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/nio/fs/DotNetDosFileAttributes.cs @@ -1,10 +1,12 @@ using System; using System.IO; +using System.Runtime.InteropServices; using System.Security; using IKVM.Runtime; using IKVM.Runtime.Accessors.Java.Lang; using IKVM.Runtime.Accessors.Sun.Nio.Ch; +using IKVM.Runtime.Accessors.Sun.Nio.Fs; using IKVM.Runtime.Vfs; namespace IKVM.Java.Externs.sun.nio.fs @@ -22,6 +24,7 @@ static class DotNetDosFileAttributes static SecurityManagerAccessor securityManagerAccessor; static FileTimeAccessor fileTimeAccessor; static DotNetDosFileAttributesAccessor dotNetDosFileAttributesAccessor; + static UnixFileKeyAccessor unixFileKeyAccessor; static SystemAccessor SystemAccessor => JVM.Internal.BaseAccessors.Get(ref systemAccessor); @@ -31,6 +34,8 @@ static class DotNetDosFileAttributes static DotNetDosFileAttributesAccessor DotNetDosFileAttributesAccessor => JVM.Internal.BaseAccessors.Get(ref dotNetDosFileAttributesAccessor); + static UnixFileKeyAccessor UnixFileKeyAccessor => JVM.Internal.BaseAccessors.Get(ref unixFileKeyAccessor); + #endif /// @@ -111,11 +116,17 @@ public static object read(string path) { var fileInfo = new FileInfo(path); if (fileInfo.Exists) + { + object fileKey = null; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) == false) + if (LibIkvm.Instance.io_lstat(fileInfo.FullName, out var st_ino, out var st_dev) == 0) + fileKey = UnixFileKeyAccessor.Init(st_dev, st_ino); + return DotNetDosFileAttributesAccessor.Init( ToFileTime(fileInfo.CreationTimeUtc), ToFileTime(fileInfo.LastAccessTimeUtc), ToFileTime(fileInfo.LastWriteTimeUtc), - null, + fileKey, false, false, true, @@ -125,14 +136,21 @@ public static object read(string path) (fileInfo.Attributes & FileAttributes.Hidden) != 0, (fileInfo.Attributes & FileAttributes.Archive) != 0, (fileInfo.Attributes & FileAttributes.System) != 0); + } var directoryInfo = new DirectoryInfo(path); if (directoryInfo.Exists) + { + object fileKey = null; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) == false) + if (LibIkvm.Instance.io_lstat(fileInfo.FullName, out var st_ino, out var st_dev) == 0) + fileKey = UnixFileKeyAccessor.Init(st_dev, st_ino); + return DotNetDosFileAttributesAccessor.Init( ToFileTime(directoryInfo.CreationTimeUtc), ToFileTime(directoryInfo.LastAccessTimeUtc), ToFileTime(directoryInfo.LastWriteTimeUtc), - null, + fileKey, true, false, false, @@ -142,6 +160,7 @@ public static object read(string path) (directoryInfo.Attributes & FileAttributes.Hidden) != 0, (directoryInfo.Attributes & FileAttributes.Archive) != 0, (directoryInfo.Attributes & FileAttributes.System) != 0); + } throw new global::java.nio.file.NoSuchFileException(path); } diff --git a/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs b/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs index b27ab6d627..9c4a43cc86 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs @@ -25,6 +25,8 @@ Jeroen Frijters using System.Reflection; #if !NO_REF_EMIT using System.Reflection.Emit; +using System.Runtime.CompilerServices; + #endif using System.Runtime.Serialization; using System.Security; @@ -282,7 +284,11 @@ internal SerializationConstructorAccessorImpl(global::java.lang.reflect.Construc [SecuritySafeCritical] public object newInstance(object[] args) { +#if NETFRAMEWORK var obj = FormatterServices.GetUninitializedObject(type); +#else + var obj = RuntimeHelpers.GetUninitializedObject(type); +#endif if (mw != null) mw.Invoke(obj, ConvertArgs(mw.DeclaringType.GetClassLoader(), mw.GetParameters(), args)); @@ -966,13 +972,17 @@ public object newInstance(object[] args) } - private sealed class FastSerializationConstructorAccessorImpl : global::sun.reflect.ConstructorAccessor + sealed class FastSerializationConstructorAccessorImpl : global::sun.reflect.ConstructorAccessor { - private static readonly MethodInfo GetTypeFromHandleMethod = typeof(Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) }); - private static readonly MethodInfo GetUninitializedObjectMethod = typeof(FormatterServices).GetMethod("GetUninitializedObject", new Type[] { typeof(Type) }); - private delegate object InvokeCtor(); - private InvokeCtor invoker; + static readonly MethodInfo GetTypeFromHandleMethod = typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle), new[] { typeof(RuntimeTypeHandle) }); +#if NETFRAMEWORK + static readonly MethodInfo GetUninitializedObjectMethod = typeof(FormatterServices).GetMethod(nameof(FormatterServices.GetUninitializedObject), new[] { typeof(Type) }); +#else + static readonly MethodInfo GetUninitializedObjectMethod = typeof(RuntimeHelpers).GetMethod(nameof(RuntimeHelpers.GetUninitializedObject), new[] { typeof(Type) }); +#endif + delegate object InvokeCtor(); + InvokeCtor invoker; internal FastSerializationConstructorAccessorImpl(global::java.lang.reflect.Constructor constructorToCall, global::java.lang.Class classToInstantiate) { diff --git a/src/IKVM.Runtime/Launcher.cs b/src/IKVM.Runtime/Launcher.cs index 7b74f02d35..907d8b9c4e 100644 --- a/src/IKVM.Runtime/Launcher.cs +++ b/src/IKVM.Runtime/Launcher.cs @@ -446,6 +446,9 @@ public static int Run(string main, bool jar, string[] args, string rarg, IDictio arg.StartsWith("-Xmn".AsSpan()) || arg.StartsWith("-Xss".AsSpan()) || arg.StartsWith("-XX:".AsSpan()) || + arg.StartsWith("-mn".AsSpan()) || + arg.StartsWith("-ms".AsSpan()) || + arg.StartsWith("-mx".AsSpan()) || ArgEquals(arg, "-Xmixed") || ArgEquals(arg, "-Xint") || ArgEquals(arg, "-Xincgc") || diff --git a/src/IKVM.Runtime/LibIkvm.cs b/src/IKVM.Runtime/LibIkvm.cs index be7739b947..2c75606b22 100644 --- a/src/IKVM.Runtime/LibIkvm.cs +++ b/src/IKVM.Runtime/LibIkvm.cs @@ -93,6 +93,39 @@ static class Externs [DllImport("ikvm", SetLastError = false)] internal static extern void IKVM_io_close_socket(long handle); + /// + /// Invokes the native 'IKVM_io_close_socket' function. + /// + /// + /// + /// + /// + [DllImport("ikvm", SetLastError = false)] + internal static extern int IKVM_io_lstat(string pathname, out long st_ino, out long st_dev); + + /// + /// Invokes the native 'IKVM_sig_get_size_sigaction' function. + /// + /// + [DllImport("ikvm", SetLastError = false)] + internal static unsafe extern int IKVM_sig_get_size_sigaction(); + + /// + /// Invokes the native 'IKVM_sig_get_chld_action' function. + /// + /// + /// + [DllImport("ikvm", SetLastError = false)] + internal static unsafe extern int IKVM_sig_get_chld_action(void* sig); + + /// + /// Invokes the native 'IKVM_sig_set_chld_action' function. + /// + /// + /// + [DllImport("ikvm", SetLastError = false)] + internal static unsafe extern int IKVM_sig_set_chld_action(void* sig); + } /// @@ -270,6 +303,35 @@ static nint Load() /// public long io_duplicate_socket(long handle) => Externs.IKVM_io_duplicate_socket(handle); + /// + /// Invokes the 'io_lstat' function. + /// + /// + /// + /// + /// + public int io_lstat(string pathname, out long st_ino, out long st_dev) => Externs.IKVM_io_lstat(pathname, out st_ino, out st_dev); + + /// + /// Invokes the 'sig_get_size_sigaction' function. + /// + /// + public unsafe int sig_get_size_sigaction() => Externs.IKVM_sig_get_size_sigaction(); + + /// + /// Invokes the 'sig_get_chld_action' function. + /// + /// + /// + public unsafe int sig_get_chld_action(void* sig) => Externs.IKVM_sig_get_chld_action(sig); + + /// + /// Invokes the 'sig_set_chld_action' function. + /// + /// + /// + public unsafe int sig_set_chld_action(void* sig) => Externs.IKVM_sig_set_chld_action(sig); + /// /// Releases the instance. /// diff --git a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs index c276613ef0..0fc236e1d0 100644 --- a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs @@ -31,6 +31,9 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.Runtime.Syntax; +using System.Runtime.CompilerServices; + + #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -1253,7 +1256,11 @@ void InitializeJavaClassLoader(JavaClassLoaderConstructionInProgress jclcip, Typ [System.Security.SecuritySafeCritical] static object GetUninitializedObject(Type type) { +#if NETFRAMEWORK return FormatterServices.GetUninitializedObject(type); +#else + return RuntimeHelpers.GetUninitializedObject(type); +#endif } static void LoadCustomClassLoaderRedirects(RuntimeContext context) diff --git a/src/IKVM.Runtime/Vfs/VfsCacertsFile.cs b/src/IKVM.Runtime/Vfs/VfsCacertsFile.cs index aab046aeba..8530bc20a7 100644 --- a/src/IKVM.Runtime/Vfs/VfsCacertsFile.cs +++ b/src/IKVM.Runtime/Vfs/VfsCacertsFile.cs @@ -92,7 +92,7 @@ byte[] GenerateCacertsFile() } var baos = new java.io.ByteArrayOutputStream(); - jstore.store(baos, new char[0]); + jstore.store(baos, "changeit".ToCharArray()); return baos.toByteArray(); #endif } diff --git a/src/IKVM.Tests.Util/DotNetSdkResolver.cs b/src/IKVM.Tests.Util/DotNetSdkResolver.cs index 8734762113..0e97a2cddc 100644 --- a/src/IKVM.Tests.Util/DotNetSdkResolver.cs +++ b/src/IKVM.Tests.Util/DotNetSdkResolver.cs @@ -34,12 +34,12 @@ public static string ResolvePath(string dotnetExePath) /// /// /// - static List GetInfo(string dotnetExePath) + static IList GetInfo(string dotnetExePath) { // Ensure that we set the DOTNET_CLI_UI_LANGUAGE environment variable to "en-US" before // running 'dotnet --info'. Otherwise, we may get localized results // Also unset some MSBuild variables, see https://github.com/OmniSharp/omnisharp-roslyn/blob/df160f86ce906bc566fe3e04e38a4077bd6023b4/src/OmniSharp.Abstractions/Services/DotNetCliService.cs#L36 - var environmentVariables = new Dictionary + var envv = new Dictionary { ["DOTNET_CLI_UI_LANGUAGE"] = "en-US", ["MSBUILD_EXE_PATH"] = null, @@ -47,15 +47,15 @@ static List GetInfo(string dotnetExePath) ["MSBuildExtensionsPath"] = null, }; - var lines = new List(); + var info = new List(); var task = (Cli.Wrap(dotnetExePath) .WithArguments("--info") - .WithEnvironmentVariables(environmentVariables) - | lines.Add) - .ExecuteAsync(new CancellationTokenSource(10000).Token); + .WithEnvironmentVariables(envv) + | info.Add) + .ExecuteAsync(new CancellationTokenSource(2000).Token); task.GetAwaiter().GetResult(); - return lines; + return info; } /// @@ -63,7 +63,7 @@ static List GetInfo(string dotnetExePath) /// /// /// - static string ParseBasePath(List lines) + static string ParseBasePath(IList lines) { foreach (var line in lines.Where(x => x != null)) { @@ -74,13 +74,13 @@ static string ParseBasePath(List lines) // Make sure the base path matches the runtime architecture if on Windows // Note that this only works for the default installation locations under "Program Files" - if (basePath.Contains(@"\Program Files\") && !System.Environment.Is64BitProcess) + if (basePath.Contains(@"\Program Files\") && Environment.Is64BitProcess == false) { var newBasePath = basePath.Replace(@"\Program Files\", @"\Program Files (x86)\"); if (Directory.Exists(newBasePath)) basePath = newBasePath; } - else if (basePath.Contains(@"\Program Files (x86)\") && System.Environment.Is64BitProcess) + else if (basePath.Contains(@"\Program Files (x86)\") && Environment.Is64BitProcess) { var newBasePath = basePath.Replace(@"\Program Files (x86)\", @"\Program Files\"); if (Directory.Exists(newBasePath)) @@ -100,7 +100,7 @@ static string ParseBasePath(List lines) /// /// /// - static string ParseInstalledSdksPath(List lines) + static string ParseInstalledSdksPath(IList lines) { var index = lines.IndexOf(".NET SDKs installed:"); if (index == -1) diff --git a/src/IKVM.Tests.Util/DotNetSdkUtil.cs b/src/IKVM.Tests.Util/DotNetSdkUtil.cs index b0a49b1347..b93f2b98fb 100644 --- a/src/IKVM.Tests.Util/DotNetSdkUtil.cs +++ b/src/IKVM.Tests.Util/DotNetSdkUtil.cs @@ -9,6 +9,7 @@ namespace IKVM.Tests.Util { + public static class DotNetSdkUtil { @@ -80,7 +81,7 @@ static IList GetCorePathToReferenceAssemblies(string tfm, string targetF { // parse requested version if (Version.TryParse(targetFrameworkVersion, out var targetVer) == false) - throw new InvalidOperationException(); + throw new InvalidOperationException(targetFrameworkVersion); // back up to pack directory and get list of ref packs var sdkBase = DotNetSdkResolver.ResolvePath(null) ?? throw new InvalidOperationException(); @@ -88,14 +89,14 @@ static IList GetCorePathToReferenceAssemblies(string tfm, string targetF var sdkVers = Directory.EnumerateDirectories(packDir).Select(Path.GetFileName); // identify maximum matching version - var thisVer = new Version(0, 0); + var thisVer = new Version(0, 0, 0); foreach (var ver in sdkVers) if (Version.TryParse(ver, out var v)) - if (v > thisVer && v.Major == targetVer.Major && v.Minor == targetVer.Minor) + if (v.Major == targetVer.Major && v.Minor == targetVer.Minor && v > thisVer) thisVer = v; // no higher version found - if (thisVer == new Version(0, 0)) + if (thisVer.Major == 0) return null; // check for TFM refs directory diff --git a/src/IKVM.Tests.Util/IKVM.Tests.Util.csproj b/src/IKVM.Tests.Util/IKVM.Tests.Util.csproj index 604868a84d..dea085c541 100644 --- a/src/IKVM.Tests.Util/IKVM.Tests.Util.csproj +++ b/src/IKVM.Tests.Util/IKVM.Tests.Util.csproj @@ -4,7 +4,7 @@ - + diff --git a/src/IKVM.Tests/IKVM.Tests.csproj b/src/IKVM.Tests/IKVM.Tests.csproj index 69d2a485f6..b33d9284b6 100644 --- a/src/IKVM.Tests/IKVM.Tests.csproj +++ b/src/IKVM.Tests/IKVM.Tests.csproj @@ -24,17 +24,19 @@ - + - - - + + + + + diff --git a/src/IKVM.Tests/Java/ikvm/runtime/AssemblyClassLoaderTests.cs b/src/IKVM.Tests/Java/ikvm/runtime/AssemblyClassLoaderTests.cs index 769996e9a6..f092e2e5e0 100644 --- a/src/IKVM.Tests/Java/ikvm/runtime/AssemblyClassLoaderTests.cs +++ b/src/IKVM.Tests/Java/ikvm/runtime/AssemblyClassLoaderTests.cs @@ -8,7 +8,6 @@ using FluentAssertions; -using IKVM.Runtime.Extensions; using IKVM.Tests.Util; using IKVM.Tools.Runner; using IKVM.Tools.Runner.Importer; @@ -28,12 +27,8 @@ public class AssemblyClassLoaderTests public TestContext TestContext { get; set; } - /// - /// Initializes the test DLL. - /// - /// [TestInitialize] - public async Task Setup() + public async Task TestInitialize() { #if NET7_0 var ikvmTool = "net6.0"; @@ -86,6 +81,12 @@ public async Task Setup() helloworldDll = Assembly.LoadFrom(p); } + [TestCleanup] + public void TestCleanup() + { + helloworldDll = null; + } + [TestMethod] public void CanGetPackage() { diff --git a/src/IKVM.Tests/Java/java/lang/ProcessTests.cs b/src/IKVM.Tests/Java/java/lang/ProcessTests.cs index 999780c229..07a17c5aef 100644 --- a/src/IKVM.Tests/Java/java/lang/ProcessTests.cs +++ b/src/IKVM.Tests/Java/java/lang/ProcessTests.cs @@ -1,4 +1,5 @@ -using System.Runtime.InteropServices; +using System.IO; +using System.Runtime.InteropServices; using FluentAssertions; @@ -14,6 +15,24 @@ namespace IKVM.Tests.Java.java.lang public class ProcessTests { + public TestContext TestContext { get; set; } + + [TestMethod] + public void CanReadExitCode() + { + string[] c; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + c = new[] { "cmd.exe", "/c", "exit 1" }; + else + c = new[] { "/bin/sh", "-c", "exit 1" }; + + var b = new ProcessBuilder(c); + var p = b.start(); + + p.waitFor(); + p.exitValue().Should().Be(1); + } + [TestMethod] public void CanReadFromInputStream() { @@ -24,6 +43,7 @@ public void CanReadFromInputStream() c = new[] { "/bin/sh", "-c", "echo hello" }; var b = new ProcessBuilder(c); + b.redirectOutput(ProcessBuilder.Redirect.PIPE); var p = b.start(); var r = new BufferedReader(new InputStreamReader(p.getInputStream())); @@ -43,6 +63,7 @@ public void CanReadFromErrorStream() c = new[] { "/bin/sh", "-c", "echo hello>&2" }; var b = new ProcessBuilder(c); + b.redirectError(ProcessBuilder.Redirect.PIPE); var p = b.start(); var r = new BufferedReader(new InputStreamReader(p.getErrorStream())); @@ -52,6 +73,120 @@ public void CanReadFromErrorStream() l.Should().Be("hello"); } + [TestMethod] + public void CanRedirectOutputToFile() + { + var f = Path.GetTempFileName(); + + string[] c; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + c = new[] { "cmd.exe", "/c", "echo hello" }; + else + c = new[] { "/bin/sh", "-c", "echo hello" }; + + var b = new ProcessBuilder(c); + b.redirectOutput(ProcessBuilder.Redirect.to(new global::java.io.File(f))); + var p = b.start(); + p.waitFor(); + + System.IO.File.ReadAllText(f).TrimEnd().Should().Be("hello"); + } + + [TestMethod] + public void CanRedirectErrorToFile() + { + var f = Path.GetTempFileName(); + + string[] c; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + c = new[] { "cmd.exe", "/c", "echo hello>&2" }; + else + c = new[] { "/bin/sh", "-c", "echo hello>&2" }; + + var b = new ProcessBuilder(c); + b.redirectError(ProcessBuilder.Redirect.to(new global::java.io.File(f))); + var p = b.start(); + p.waitFor(); + + System.IO.File.ReadAllText(f).TrimEnd().Should().Be("hello"); + } + + [TestMethod] + public void CanRedirectOutputToPipe() + { + string[] c; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + c = new[] { "cmd.exe", "/c", "echo hello" }; + else + c = new[] { "/bin/sh", "-c", "echo hello" }; + + var b = new ProcessBuilder(c); + b.redirectOutput(ProcessBuilder.Redirect.PIPE); + var p = b.start(); + p.waitFor(); + } + + [TestMethod] + public void CanRedirectErrorToPipe() + { + string[] c; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + c = new[] { "cmd.exe", "/c", "echo hello>&2" }; + else + c = new[] { "/bin/sh", "-c", "echo hello>&2" }; + + var b = new ProcessBuilder(c); + b.redirectError(ProcessBuilder.Redirect.PIPE); + var p = b.start(); + p.waitFor(); + } + + [TestMethod] + public void CanInheritInput() + { + string[] c; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + c = new[] { "cmd.exe", "/c", "echo hello" }; + else + c = new[] { "/bin/sh", "-c", "echo hello" }; + + var b = new ProcessBuilder(c); + b.redirectError(ProcessBuilder.Redirect.INHERIT); + var p = b.start(); + p.waitFor(); + TestContext.WriteLine(p.ToString()); + } + + [TestMethod] + public void CanInheritError() + { + string[] c; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + c = new[] { "cmd.exe", "/c", "echo hello" }; + else + c = new[] { "/bin/sh", "-c", "echo hello" }; + + var b = new ProcessBuilder(c); + b.redirectError(ProcessBuilder.Redirect.INHERIT); + var p = b.start(); + TestContext.WriteLine(p.ToString()); + } + + [TestMethod] + public void CanWaitForWithInheritIO() + { + string[] c; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + c = new[] { "cmd.exe", "/c", "echo hello" }; + else + c = new[] { "/bin/sh", "-c", "echo hello" }; + + var b = new ProcessBuilder(c); + b.inheritIO(); + var p = b.start(); + p.waitFor(); + } + } } diff --git a/src/IKVM.Tests/Java/java/net/ServerSocketTests.cs b/src/IKVM.Tests/Java/java/net/ServerSocketTests.cs index ad0d53cb9f..45763d720a 100644 --- a/src/IKVM.Tests/Java/java/net/ServerSocketTests.cs +++ b/src/IKVM.Tests/Java/java/net/ServerSocketTests.cs @@ -47,17 +47,10 @@ public EchoSocketServer(int port) /// public void Start() { - try - { - serverSocket = new ServerSocket(port); - port = serverSocket.getLocalPort(); - serverSocket.setSoTimeout(15000); - base.start(); - } - catch (IOException e) - { - e.printStackTrace(); - } + serverSocket = new ServerSocket(port); + port = serverSocket.getLocalPort(); + serverSocket.setSoTimeout(15000); + base.start(); } public void Stop() @@ -74,14 +67,7 @@ public override void run() while (running) { - try - { - new ClientHandler(serverSocket.accept()).start(); - } - catch (IOException e) - { - e.printStackTrace(); - } + new ClientHandler(serverSocket.accept()).start(); } } finally diff --git a/src/IKVM.Tests/Java/java/net/URITests.cs b/src/IKVM.Tests/Java/java/net/URITests.cs new file mode 100644 index 0000000000..32c455b65a --- /dev/null +++ b/src/IKVM.Tests/Java/java/net/URITests.cs @@ -0,0 +1,52 @@ +using FluentAssertions; + +using java.nio.file; + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IKVM.Tests.Java.java.net +{ + + [TestClass] + public class URITests + { + + [TestMethod] + public void CanCreateHttpURI() + { + var u = new global::java.net.URI("http://www.site.com/"); + u.getScheme().Should().Be("http"); + u.getHost().Should().Be("www.site.com"); + u.getPath().Should().Be("/"); + } + + [TestMethod] + public void CanCreateHttpsURI() + { + var u = new global::java.net.URI("https://www.site.com/"); + u.getScheme().Should().Be("https"); + u.getHost().Should().Be("www.site.com"); + u.getPath().Should().Be("/"); + } + + [TestMethod] + public void CanCreateWindowsFileURI() + { + var u = new global::java.net.URI("file:///c:/dir"); + u.getScheme().Should().Be("file"); + u.getHost().Should().Be(null); + u.getPath().Should().Be("/c:/dir"); + } + + [TestMethod] + public void CanCreateUnixFileURI() + { + var u = new global::java.net.URI("file:///tmp/foo"); + u.getScheme().Should().Be("file"); + u.getHost().Should().Be(null); + u.getPath().Should().Be("/tmp/foo"); + } + + } + +} diff --git a/src/IKVM.Tests/Java/java/nio/channels/AsynchronousFileChannelTests.cs b/src/IKVM.Tests/Java/java/nio/channels/AsynchronousFileChannelTests.cs index 92ddf8b54a..b1331e3067 100644 --- a/src/IKVM.Tests/Java/java/nio/channels/AsynchronousFileChannelTests.cs +++ b/src/IKVM.Tests/Java/java/nio/channels/AsynchronousFileChannelTests.cs @@ -4,6 +4,7 @@ using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Security.Policy; +using System.Threading; using System.Threading.Tasks; using FluentAssertions; @@ -365,9 +366,9 @@ public NamedThreadFactory(string name) this.name = name ?? throw new ArgumentNullException(nameof(name)); } - public Thread newThread(Runnable r) + public global::java.lang.Thread newThread(Runnable r) { - var t = new Thread(r, name); + var t = new global::java.lang.Thread(r, name); t.setDaemon(true); return t; } @@ -379,40 +380,50 @@ public Thread newThread(Runnable r) /// /// [TestMethod] - public async Task ShouldExecuteOnThreadPool() + public void ShouldResumeAsyncOnThreadPool() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - return; + // check current thread + global::java.lang.Thread.currentThread().getName().Should().NotBe("ShouldResumeAsyncOnThreadPool"); - Thread.currentThread().getName().Should().NotBe("ShouldExecuteOnThreadPool"); - var thisThread = Thread.currentThread(); + // create temporary file + var file = File.createTempFile("ShouldResumeAsyncOnThreadPool", null); + file.deleteOnExit(); + System.IO.File.Create(file.getPath()).Close(); - var f = new File("AsynchronousFileChannelTests_ShouldExecuteOnThreadPool.txt"); - if (f.exists()) - f.delete(); + // custom executor to resume on named thread + var t = Executors.newSingleThreadExecutor(new NamedThreadFactory("ShouldResumeAsyncOnThreadPool")); + using var c = AsynchronousFileChannel.open(file.toPath(), Collections.singleton(StandardOpenOption.WRITE), t); - f.createNewFile(); - using var s = new FileOutputStream(f); - s.write(new byte[] { 1 }); - s.close(); + // fill buffer with random data + var rng = RandomNumberGenerator.Create(); + var buf = ByteBuffer.allocate(1024 * 1024 * 64); + rng.GetBytes(buf.array(), buf.arrayOffset(), buf.limit()); - var t = Executors.newSingleThreadExecutor(new NamedThreadFactory("ShouldExecuteOnThreadPool")); - using var c = AsynchronousFileChannel.open(f.toPath(), Collections.singleton(StandardOpenOption.READ), t); - var b = ByteBuffer.allocate(1); + // capture results + var r = new AutoResetEvent(false); + var o = default(System.Exception); - var h = new AwaitableCompletionHandler(); - c.read(b, 0, null, h); - var n = await h; + // on complete check proper thread + void OnCompleted(Integer i) + { + global::java.lang.Thread.currentThread().getName().Should().Be("ShouldResumeAsyncOnThreadPool"); + r.Set(); + } - // should resume execution either on the same thread (synchronous) or on a thread pool thread - if (Thread.currentThread() != thisThread) - Thread.currentThread().getName().Should().Be("ShouldExecuteOnThreadPool"); + // on failed set exception + void OnFailed(System.Exception e) + { + o = e; + r.Set(); + } - n.intValue().Should().Be(1); - c.close(); + // begin async operation + c.write(buf, 0, null, new DelegateCompletionHandler(OnCompleted, OnFailed)); - b.flip(); - b.get().Should().Be(1); + // wait for completion + r.WaitOne(); + if (o != null) + throw new System.Exception("", o); } /// diff --git a/src/IKVM.Tests/Java/java/nio/channels/ServerSocketChannelTests.cs b/src/IKVM.Tests/Java/java/nio/channels/ServerSocketChannelTests.cs index 4c0df169b0..3567b7c790 100644 --- a/src/IKVM.Tests/Java/java/nio/channels/ServerSocketChannelTests.cs +++ b/src/IKVM.Tests/Java/java/nio/channels/ServerSocketChannelTests.cs @@ -120,15 +120,17 @@ public async Task CanReceiveNonBlocking() { var cancellationTokenSource = new CancellationTokenSource(); var receive = ByteBuffer.allocate(sizeof(int) * 4); + int port = 0; // server receives messages until cancelled var serverTask = Task.Run(() => { // initialize server using var server = ServerSocketChannel.open(); - var serverAddr = new InetSocketAddress(42342); + var serverAddr = new InetSocketAddress(port); server.bind(serverAddr); server.configureBlocking(false); + port = server.socket().getLocalPort(); // begin selector var selector = Selector.open(); @@ -171,7 +173,7 @@ public async Task CanReceiveNonBlocking() // wait a second and write some messages to the server await Task.Delay(1000); - using (var c = SocketChannel.open(new InetSocketAddress("127.0.0.1", 42342))) + using (var c = SocketChannel.open(new InetSocketAddress("127.0.0.1", port))) { foreach (var i in new[] { 1, 2, 3, 4 }) { diff --git a/src/IKVM.Tests/Java/java/nio/file/PathTests.cs b/src/IKVM.Tests/Java/java/nio/file/PathTests.cs index 8d6c3a9f0f..ea2f149c26 100644 --- a/src/IKVM.Tests/Java/java/nio/file/PathTests.cs +++ b/src/IKVM.Tests/Java/java/nio/file/PathTests.cs @@ -48,6 +48,24 @@ public void CanResolveUnixPaths(string path, string other, string expected) Paths.get(path).resolve(other).ToString().Should().Be(expected); } + [TestMethod] + public void ShouldAppendSlashToUriForExistingDirectory() + { + var t = System.IO.Path.GetTempPath().TrimEnd(System.IO.Path.DirectorySeparatorChar); + var p = Paths.get(t); + var u = p.toUri(); + u.ToString().Should().EndWith("/"); + } + + [TestMethod] + public void ShouldNotAppendSlashToUriForMissingDirectory() + { + var r = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:\missing" : @"/missing"; + var p = Paths.get(r); + var u = p.toUri(); + u.ToString().Should().NotEndWith("/"); + } + } } diff --git a/src/IKVM.Tests/Java/java/nio/file/WatchServiceTests.cs b/src/IKVM.Tests/Java/java/nio/file/WatchServiceTests.cs new file mode 100644 index 0000000000..231705ed71 --- /dev/null +++ b/src/IKVM.Tests/Java/java/nio/file/WatchServiceTests.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; + +using com.sun.nio.file; + +using FluentAssertions; + +using java.lang; +using java.nio.file; +using java.util.concurrent; + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IKVM.Tests.Java.java.nio.file +{ + + [TestClass] + public class WatchServiceTests + { + + [TestMethod] + public void CanWatchDirectoryForBasicOperations() + { + // though it works on OS X, events come out in a bit of an incorrect order, and we aren't going to fix this today + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + return; + + var cts = new CancellationTokenSource(); + + using var watcher = FileSystems.getDefault().newWatchService(); + + var dir = Paths.get(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString()); + System.IO.Directory.CreateDirectory(dir.ToString()); + + var key = dir.register(watcher, new[] { StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE }, SensitivityWatchEventModifier.HIGH); + var lst = new List<(WatchEvent.Kind, string)>(); + + var tsk = Task.Run(() => + { + while (cts.IsCancellationRequested == false) + { + var key = watcher.poll(1, TimeUnit.SECONDS); + if (key == null) + continue; + + foreach (var evt in key.pollEvents().AsEnumerable()) + { + var kind = evt.kind(); + if (kind == StandardWatchEventKinds.OVERFLOW) + continue; + + var name = (Path)evt.context(); + var item = dir.resolve(name).ToString(); + lst.Add((kind, item)); + } + + key.reset(); + } + }); + + System.Threading.Thread.Sleep(3000); + + // create a file and directory + System.IO.File.WriteAllText(dir.resolve("test.txt").ToString(), "HELLO"); + System.Threading.Thread.Sleep(3000); + System.IO.Directory.CreateDirectory(dir.resolve("test.dir").ToString()); + System.Threading.Thread.Sleep(3000); + + // remove a file and directory + System.IO.File.Delete(dir.resolve("test.txt").ToString()); + System.Threading.Thread.Sleep(3000); + System.IO.Directory.Delete(dir.resolve("test.dir").ToString()); + System.Threading.Thread.Sleep(3000); + + // wait for event loop to exit + cts.Cancel(); + tsk.Wait(); + key.cancel(); + + lst[0].Item1.Should().Be(StandardWatchEventKinds.ENTRY_CREATE); + lst[0].Item2.Should().Be(System.IO.Path.Combine(dir.ToString(), "test.txt")); + + lst[1].Item1.Should().Be(StandardWatchEventKinds.ENTRY_CREATE); + lst[1].Item2.Should().Be(System.IO.Path.Combine(dir.ToString(), "test.dir")); + + lst[2].Item1.Should().Be(StandardWatchEventKinds.ENTRY_DELETE); + lst[2].Item2.Should().Be(System.IO.Path.Combine(dir.ToString(), "test.txt")); + + lst[3].Item1.Should().Be(StandardWatchEventKinds.ENTRY_DELETE); + lst[3].Item2.Should().Be(System.IO.Path.Combine(dir.ToString(), "test.dir")); + } + + } + +} diff --git a/src/IKVM.Tests/Tools/XjcTests.cs b/src/IKVM.Tests/Tools/XjcTests.cs new file mode 100644 index 0000000000..6f7a7413ad --- /dev/null +++ b/src/IKVM.Tests/Tools/XjcTests.cs @@ -0,0 +1,44 @@ +using System.IO; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +using CliWrap; + +using FluentAssertions; + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IKVM.Tests.Tools +{ + + [TestClass] + public class XjcTests + { + + [TestMethod] + public async Task CanDisplayHelp() + { + var s = new StringBuilder(); + var c = Path.Combine(java.lang.System.getProperty("java.home"), "bin", "xjc"); +#if NETCOREAPP + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + var psx = Mono.Unix.UnixFileSystemInfo.GetFileSystemEntry(c); + var prm = psx.FileAccessPermissions; + prm |= Mono.Unix.FileAccessPermissions.UserExecute; + prm |= Mono.Unix.FileAccessPermissions.GroupExecute; + prm |= Mono.Unix.FileAccessPermissions.OtherExecute; + if (prm != psx.FileAccessPermissions) + psx.FileAccessPermissions = prm; + } +#endif + + var r = await Cli.Wrap(c).WithArguments("-help").WithStandardOutputPipe(PipeTarget.ToDelegate(i => s.Append(i))).WithValidation(CommandResultValidation.None).ExecuteAsync(); + r.ExitCode.Should().Be(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? -1 : 255); + s.ToString().Should().StartWith("Usage: xjc"); + } + + } + +} diff --git a/src/IKVM.Tools.Exporter.Tests/IKVM.Tools.Exporter.Tests.csproj b/src/IKVM.Tools.Exporter.Tests/IKVM.Tools.Exporter.Tests.csproj index 445b327634..aa1e7b5ca0 100644 --- a/src/IKVM.Tools.Exporter.Tests/IKVM.Tools.Exporter.Tests.csproj +++ b/src/IKVM.Tools.Exporter.Tests/IKVM.Tools.Exporter.Tests.csproj @@ -7,10 +7,10 @@ - - - - + + + + diff --git a/src/IKVM.Tools.Exporter/IkvmExporterContext.NetCore.cs b/src/IKVM.Tools.Exporter/IkvmExporterContext.NetCore.cs index f263decfd8..2188bf4fd4 100644 --- a/src/IKVM.Tools.Exporter/IkvmExporterContext.NetCore.cs +++ b/src/IKVM.Tools.Exporter/IkvmExporterContext.NetCore.cs @@ -1,17 +1,12 @@ #if NETCOREAPP using System; -using System.IO; using System.Reflection; using System.Runtime.Loader; -using System.Runtime.Serialization.Formatters.Binary; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using Microsoft.Extensions.DependencyModel.Resolution; - -using System.Text.Json; - namespace IKVM.Tools.Exporter { diff --git a/src/IKVM.Tools.Importer.Tests/IKVM.Tools.Importer.Tests.csproj b/src/IKVM.Tools.Importer.Tests/IKVM.Tools.Importer.Tests.csproj index 6305756282..d3e9fd3595 100644 --- a/src/IKVM.Tools.Importer.Tests/IKVM.Tools.Importer.Tests.csproj +++ b/src/IKVM.Tools.Importer.Tests/IKVM.Tools.Importer.Tests.csproj @@ -7,10 +7,10 @@ - - - - + + + + diff --git a/src/IKVM.Tools.Runner/IKVM.Tools.Runner.csproj b/src/IKVM.Tools.Runner/IKVM.Tools.Runner.csproj index 0766910bc6..d3e2b6ee24 100644 --- a/src/IKVM.Tools.Runner/IKVM.Tools.Runner.csproj +++ b/src/IKVM.Tools.Runner/IKVM.Tools.Runner.csproj @@ -5,7 +5,7 @@ - + diff --git a/src/IKVM.Tools.Runner/IkvmToolLauncher.cs b/src/IKVM.Tools.Runner/IkvmToolLauncher.cs index 767be1ed4c..63be52b7f1 100644 --- a/src/IKVM.Tools.Runner/IkvmToolLauncher.cs +++ b/src/IKVM.Tools.Runner/IkvmToolLauncher.cs @@ -38,7 +38,10 @@ public IkvmToolLauncher(string toolName, string toolPath, IIkvmToolDiagnosticEve /// protected Task LogEvent(IkvmToolDiagnosticEventLevel level, string message, params object[] args) { - return listener?.ReceiveAsync(new IkvmToolDiagnosticEvent(level, message, args)); + if (message != null && listener != null) + return listener.ReceiveAsync(new IkvmToolDiagnosticEvent(level, message, args)); + else + return Task.CompletedTask; } /// diff --git a/src/IKVM.Tools.Runner/Importer/IkvmImporterLauncher.cs b/src/IKVM.Tools.Runner/Importer/IkvmImporterLauncher.cs index 986832adfd..2a4673a91b 100644 --- a/src/IKVM.Tools.Runner/Importer/IkvmImporterLauncher.cs +++ b/src/IKVM.Tools.Runner/Importer/IkvmImporterLauncher.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; @@ -278,8 +277,12 @@ public async Task ExecuteAsync(IkvmImporterOptions options, CancellationTok try { var psx = Mono.Unix.UnixFileSystemInfo.GetFileSystemEntry(exe); - if (psx.FileAccessPermissions.HasFlag(Mono.Unix.FileAccessPermissions.UserExecute) == false) - psx.FileAccessPermissions |= Mono.Unix.FileAccessPermissions.UserExecute; + var prm = psx.FileAccessPermissions; + prm |= Mono.Unix.FileAccessPermissions.UserExecute; + prm |= Mono.Unix.FileAccessPermissions.GroupExecute; + prm |= Mono.Unix.FileAccessPermissions.OtherExecute; + if (prm != psx.FileAccessPermissions) + psx.FileAccessPermissions = prm; } catch (Exception e) { @@ -305,7 +308,7 @@ public async Task ExecuteAsync(IkvmImporterOptions options, CancellationTok ctk = CancellationTokenSource.CreateLinkedTokenSource(ctk, new CancellationTokenSource(options.Timeout).Token).Token; // execute command - var pid = cli.ExecuteAsync(ctk); + using var pid = cli.ExecuteAsync(ctk); // windows provides special support for killing subprocesses on termination of parent if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) diff --git a/src/IKVM.Tools.Tests/IKVM.Tools.Tests.csproj b/src/IKVM.Tools.Tests/IKVM.Tools.Tests.csproj index d73c82b683..55a5e053a2 100644 --- a/src/IKVM.Tools.Tests/IKVM.Tools.Tests.csproj +++ b/src/IKVM.Tools.Tests/IKVM.Tools.Tests.csproj @@ -6,9 +6,9 @@ - - - + + + diff --git a/src/IKVM.Util/IKVM.Util.csproj b/src/IKVM.Util/IKVM.Util.csproj index c2f9d420cb..f7bbcb0876 100644 --- a/src/IKVM.Util/IKVM.Util.csproj +++ b/src/IKVM.Util/IKVM.Util.csproj @@ -1,4 +1,4 @@ - + net472;net6.0 true diff --git a/src/dist-image/ikvm/lib/security/java.security b/src/dist-image/ikvm/lib/security/java.security index 12d1fd8efd..d8162670a2 100644 --- a/src/dist-image/ikvm/lib/security/java.security +++ b/src/dist-image/ikvm/lib/security/java.security @@ -209,6 +209,8 @@ package.access=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -256,6 +258,8 @@ package.definition=sun.,\ com.sun.org.apache.xalan.internal.xsltc.trax.,\ com.sun.org.apache.xalan.internal.xsltc.util.,\ com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.resolver.helpers.,\ + com.sun.org.apache.xml.internal.resolver.readers.,\ com.sun.org.apache.xml.internal.security.,\ com.sun.org.apache.xml.internal.serializer.utils.,\ com.sun.org.apache.xml.internal.utils.,\ @@ -422,35 +426,37 @@ krb5.kdc.bad.policy = tryLast # describes the mechanism for disabling algorithms based on algorithm name # and/or key length. This includes algorithms used in certificates, as well # as revocation information such as CRLs and signed OCSP Responses. -# -# The syntax of the disabled algorithm string is described as this Java -# BNF-style: +# The syntax of the disabled algorithm string is described as follows: # DisabledAlgorithms: # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint | CAConstraint | DenyAfterConstraint | +# UsageConstraint # # KeySizeConstraint: -# keySize Operator DecimalInteger +# keySize Operator KeyLength # # Operator: # <= | < | == | != | >= | > # -# DecimalInteger: -# DecimalDigits +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# CAConstraint: +# jdkCA # -# DecimalDigits: -# DecimalDigit {DecimalDigit} +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD # -# DecimalDigit: one of -# 1 2 3 4 5 6 7 8 9 0 +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] # # The "AlgorithmName" is the standard algorithm name of the disabled # algorithm. See "Java Cryptography Architecture Standard Algorithm Name @@ -464,15 +470,69 @@ krb5.kdc.bad.policy = tryLast # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # will not disable algorithms related to "ECDSA". # -# A "Constraint" provides further guidance for the algorithm being specified. -# The "KeySizeConstraint" requires a key of a valid size range if the -# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the -# key size specified in number of bits. For example, "RSA keySize <= 1024" -# indicates that any RSA key with key size less than or equal to 1024 bits -# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates -# that any RSA key with key size less than 1024 or greater than 2048 should -# be disabled. Note that the "KeySizeConstraint" only makes sense to key -# algorithms. +# A "Constraint" defines restrictions on the keys and/or certificates for +# a specified AlgorithmName: +# +# KeySizeConstraint: +# keySize Operator KeyLength +# The constraint requires a key of a valid size range if the +# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates +# the key size specified in number of bits. For example, +# "RSA keySize <= 1024" indicates that any RSA key with key size less +# than or equal to 1024 bits should be disabled, and +# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key +# with key size less than 1024 or greater than 2048 should be disabled. +# This constraint is only used on algorithms that have a key size. +# +# CAConstraint: +# jdkCA +# This constraint prohibits the specified algorithm only if the +# algorithm is used in a certificate chain that terminates at a marked +# trust anchor in the lib/security/cacerts keystore. If the jdkCA +# constraint is not set, then all chains using the specified algorithm +# are restricted. jdkCA may only be used once in a DisabledAlgorithm +# expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following: "SHA1 jdkCA" +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# This constraint prohibits a certificate with the specified algorithm +# from being used after the date regardless of the certificate's +# validity. JAR files that are signed and timestamped before the +# constraint date with certificates containing the disabled algorithm +# will not be restricted. The date is processed in the UTC timezone. +# This constraint can only be used once in a DisabledAlgorithm +# expression. +# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020, +# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03" +# +# UsageConstraint: +# usage [TLSServer] [TLSClient] [SignedJAR] +# This constraint prohibits the specified algorithm for +# a specified usage. This should be used when disabling an algorithm +# for all usages is not practical. 'TLSServer' restricts the algorithm +# in TLS server certificate chains when server authentication is +# performed. 'TLSClient' restricts the algorithm in TLS client +# certificate chains when client authentication is performed. +# 'SignedJAR' constrains use of certificates in signed jar files. +# The usage type follows the keyword and more than one usage type can +# be specified with a whitespace delimiter. +# Example: "SHA1 usage TLSServer TLSClient" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. # # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. @@ -481,8 +541,53 @@ krb5.kdc.bad.policy = tryLast # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 # # -jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \ + RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 + +# +# Algorithm restrictions for signed JAR files +# +# In some environments, certain algorithms or key lengths may be undesirable +# for signed JAR validation. For example, "MD2" is generally no longer +# considered to be a secure hash algorithm. This section describes the +# mechanism for disabling algorithms based on algorithm name and/or key length. +# JARs signed with any of the disabled algorithms or key sizes will be treated +# as unsigned. +# +# The syntax of the disabled algorithm string is described as follows: +# DisabledAlgorithms: +# " DisabledAlgorithm { , DisabledAlgorithm } " +# +# DisabledAlgorithm: +# AlgorithmName [Constraint] { '&' Constraint } +# +# AlgorithmName: +# (see below) +# +# Constraint: +# KeySizeConstraint | DenyAfterConstraint +# +# KeySizeConstraint: +# keySize Operator KeyLength +# +# DenyAfterConstraint: +# denyAfter YYYY-MM-DD +# +# Operator: +# <= | < | == | != | >= | > +# +# KeyLength: +# Integer value of the algorithm's key length in bits +# +# Note: This property is currently used by the JDK Reference +# implementation. It is not guaranteed to be examined and used by other +# implementations. +# +# See "jdk.certpath.disabledAlgorithms" for syntax descriptions. +# +jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 +# # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing # @@ -504,12 +609,16 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 # See the specification of "jdk.certpath.disabledAlgorithms" for the # syntax of the disabled algorithm string. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: The algorithm restrictions do not apply to trust anchors or +# self-signed certificates. +# +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -523,7 +632,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -553,7 +662,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -566,7 +675,8 @@ jdk.tls.legacyAlgorithms= \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing. @@ -624,3 +734,178 @@ jdk.tls.legacyAlgorithms= \ # E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ # EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ # FFFFFFFF FFFFFFFF, 2} + +# Cryptographic Jurisdiction Policy defaults +# +# Due to the import control restrictions of some countries, the default +# JCE policy files allow for strong but "limited" cryptographic key +# lengths to be used. If your country's cryptographic regulations allow, +# the "unlimited" strength policy files can be used instead, which contain +# no restrictions on cryptographic strengths. +# +# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY +# TO DETERMINE THE EXACT REQUIREMENTS. +# +# (below) refers to the directory where the JRE was +# installed. It is determined based on whether you are running JCE +# on a JRE or a JRE contained within the Java Development Kit, or +# JDK(TM). The JDK contains the JRE, but at a different level in the +# file hierarchy. For example, if the JDK is installed in +# /home/user1/jdk1.8.0 on Unix or in C:\jdk1.8.0 on Windows, then +# is: +# +# /home/user1/jdk1.8.0/jre [Unix] +# C:\jdk1.8.0\jre [Windows] +# +# If on the other hand the JRE is installed in /home/user1/jre1.8.0 +# on Unix or in C:\jre1.8.0 on Windows, and the JDK is not +# installed, then is: +# +# /home/user1/jre1.8.0 [Unix] +# C:\jre1.8.0 [Windows] +# +# On Windows, for each JDK installation, there may be additional +# JREs installed under the "Program Files" directory. Please make +# sure that you install the unlimited strength policy JAR files +# for all JREs that you plan to use. +# +# The policy files are jar files organized into subdirectories of +# /lib/security/policy. Each directory contains a complete +# set of policy files. +# +# The "crypto.policy" Security property controls the directory selection, +# and thus the effective cryptographic policy. +# +# The default set of directories is: +# +# limited | unlimited +# +# however other directories can be created and configured. +# +# To support older JDK Update releases, the crypto.policy property +# is not defined by default. When the property is not defined, an +# update release binary aware of the new property will use the following +# logic to decide what crypto policy files get used : +# +# * If the US_export_policy.jar and local_policy.jar files are located +# in the (legacy) /lib/security directory, then the rules +# embedded in those jar files will be used. This helps preserve compatibility +# for users upgrading from an older installation. +# +# * If crypto.policy is not defined and no such jar files are present in +# the legacy locations, then the JDK will use the limited settings +# (equivalent to crypto.policy=limited) +# +# Please see the JCA documentation for additional information on these +# files and formats. +crypto.policy=unlimited + +# +# The policy for the XML Signature secure validation mode. The mode is +# enabled by setting the property "org.jcp.xml.dsig.secureValidation" to +# true with the javax.xml.crypto.XMLCryptoContext.setProperty() method, +# or by running the code with a SecurityManager. +# +# Policy: +# Constraint {"," Constraint } +# Constraint: +# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint +# AlgConstraint +# "disallowAlg" Uri +# MaxTransformsConstraint: +# "maxTransforms" Integer +# MaxReferencesConstraint: +# "maxReferences" Integer +# ReferenceUriSchemeConstraint: +# "disallowReferenceUriSchemes" String { String } +# KeySizeConstraint: +# "minKeySize" KeyAlg Integer +# OtherConstraint: +# "noDuplicateIds" | "noRetrievalMethodLoops" +# +# For AlgConstraint, Uri is the algorithm URI String that is not allowed. +# See the XML Signature Recommendation for more information on algorithm +# URI Identifiers. For KeySizeConstraint, KeyAlg is the standard algorithm +# name of the key type (ex: "RSA"). If the MaxTransformsConstraint, +# MaxReferencesConstraint or KeySizeConstraint (for the same key type) is +# specified more than once, only the last entry is enforced. +# +# Note: This property is currently used by the JDK Reference implementation. It +# is not guaranteed to be examined and used by other implementations. +# +jdk.xml.dsig.secureValidationPolicy=\ + disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\ + maxTransforms 5,\ + maxReferences 30,\ + disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ + noDuplicateIds,\ + noRetrievalMethodLoops + +# +# Serialization process-wide filter +# +# A filter, if configured, is used by java.io.ObjectInputStream during +# deserialization to check the contents of the stream. +# A filter is configured as a sequence of patterns, each pattern is either +# matched against the name of a class in the stream or defines a limit. +# Patterns are separated by ";" (semicolon). +# Whitespace is significant and is considered part of the pattern. +# +# If a pattern includes a "=", it sets a limit. +# If a limit appears more than once the last value is used. +# Limits are checked before classes regardless of the order in the sequence of patterns. +# If any of the limits are exceeded, the filter status is REJECTED. +# +# maxdepth=value - the maximum depth of a graph +# maxrefs=value - the maximum number of internal references +# maxbytes=value - the maximum number of bytes in the input stream +# maxarray=value - the maximum array length allowed +# +# Other patterns, from left to right, match the class or package name as +# returned from Class.getName. +# If the class is an array type, the class or package to be matched is the element type. +# Arrays of any number of dimensions are treated the same as the element type. +# For example, a pattern of "!example.Foo", rejects creation of any instance or +# array of example.Foo. +# +# If the pattern starts with "!", the status is REJECTED if the remaining pattern +# is matched; otherwise the status is ALLOWED if the pattern matches. +# If the pattern ends with ".**" it matches any class in the package and all subpackages. +# If the pattern ends with ".*" it matches any class in the package. +# If the pattern ends with "*", it matches any class with the pattern as a prefix. +# If the pattern is equal to the class name, it matches. +# Otherwise, the status is UNDECIDED. +# +#jdk.serialFilter=pattern;pattern + +# +# RMI Registry Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI Registry. +# +#sun.rmi.registry.registryFilter=pattern;pattern + +# +# RMI Distributed Garbage Collector (DGC) Serial Filter +# +# The filter pattern uses the same format as jdk.serialFilter. +# This filter can override the builtin filter if additional types need to be +# allowed or rejected from the RMI DGC. +# +# The builtin DGC filter can approximately be represented as the filter pattern: +# +#sun.rmi.transport.dgcFilter=\ +# java.rmi.server.ObjID;\ +# java.rmi.server.UID;\ +# java.rmi.dgc.VMID;\ +# java.rmi.dgc.Lease;\ +# maxdepth=5;maxarray=10000 + diff --git a/src/ikvmc/ikvmc.csproj b/src/ikvmc/ikvmc.csproj index ad17ab129b..b4c4c1bcaf 100644 --- a/src/ikvmc/ikvmc.csproj +++ b/src/ikvmc/ikvmc.csproj @@ -3,6 +3,7 @@ Exe net6.0;net472 $(_SupportedToolRuntimes) + true true diff --git a/src/ikvmstub/ikvmstub.csproj b/src/ikvmstub/ikvmstub.csproj index 0e8f641af8..28d5833f3d 100644 --- a/src/ikvmstub/ikvmstub.csproj +++ b/src/ikvmstub/ikvmstub.csproj @@ -3,6 +3,7 @@ Exe net472;net6.0 $(_SupportedToolRuntimes) + true true diff --git a/src/jar/jar.msbuildproj b/src/jar/jar.msbuildproj index df6b0cc9a2..a9a9b22b67 100644 --- a/src/jar/jar.msbuildproj +++ b/src/jar/jar.msbuildproj @@ -9,6 +9,7 @@ $(_SupportedImageRuntimes) sun.tools.jar.Main ikvm.tools.jar + true diff --git a/src/jarsigner/jarsigner.msbuildproj b/src/jarsigner/jarsigner.msbuildproj index e7067311aa..75f7b4b1cf 100644 --- a/src/jarsigner/jarsigner.msbuildproj +++ b/src/jarsigner/jarsigner.msbuildproj @@ -9,6 +9,7 @@ $(_SupportedImageRuntimes) sun.security.tools.jarsigner.Main ikvm.tools.jarsigner + true diff --git a/src/java/java.csproj b/src/java/java.csproj index cf3d36b052..aaf0b9345b 100644 --- a/src/java/java.csproj +++ b/src/java/java.csproj @@ -4,6 +4,7 @@ net6.0;net472 $(_SupportedImageRuntimes) ikvm.tools.java + true diff --git a/src/javac-ref/javac-ref.msbuildproj b/src/javac-ref/javac-ref.msbuildproj index e29b588154..b8ea8a7fe0 100644 --- a/src/javac-ref/javac-ref.msbuildproj +++ b/src/javac-ref/javac-ref.msbuildproj @@ -10,6 +10,7 @@ $(_SupportedImageRuntimes) com.sun.tools.javac.Main ikvm.tools.javac + true diff --git a/src/javac/javac.msbuildproj b/src/javac/javac.msbuildproj index 1ee2572e49..f4e9563637 100644 --- a/src/javac/javac.msbuildproj +++ b/src/javac/javac.msbuildproj @@ -9,6 +9,7 @@ $(_SupportedImageRuntimes) com.sun.tools.javac.Main ikvm.tools.javac + true diff --git a/src/javadoc/javadoc.msbuildproj b/src/javadoc/javadoc.msbuildproj index e0ff70a70a..f6941cf5b1 100644 --- a/src/javadoc/javadoc.msbuildproj +++ b/src/javadoc/javadoc.msbuildproj @@ -9,6 +9,7 @@ $(_SupportedImageRuntimes) com.sun.tools.javadoc.Main ikvm.tools.javadoc + true diff --git a/src/javah/javah.msbuildproj b/src/javah/javah.msbuildproj index cb7214428b..53f60cbbc4 100644 --- a/src/javah/javah.msbuildproj +++ b/src/javah/javah.msbuildproj @@ -9,6 +9,7 @@ $(_SupportedImageRuntimes) com.sun.tools.javah.Main ikvm.tools.javah + true diff --git a/src/javap/javap.msbuildproj b/src/javap/javap.msbuildproj index 643cab5b7d..70b6d90c12 100644 --- a/src/javap/javap.msbuildproj +++ b/src/javap/javap.msbuildproj @@ -9,6 +9,7 @@ $(_SupportedImageRuntimes) com.sun.tools.javap.Main ikvm.tools.javap + true diff --git a/src/jdeps/jdeps.msbuildproj b/src/jdeps/jdeps.msbuildproj index 4f1fed6a2f..79cfb0db96 100644 --- a/src/jdeps/jdeps.msbuildproj +++ b/src/jdeps/jdeps.msbuildproj @@ -9,6 +9,7 @@ $(_SupportedImageRuntimes) com.sun.tools.jdeps.Main ikvm.tools.jdeps + true diff --git a/src/keytool/keytool.msbuildproj b/src/keytool/keytool.msbuildproj index ff6767116d..cd602a64ff 100644 --- a/src/keytool/keytool.msbuildproj +++ b/src/keytool/keytool.msbuildproj @@ -9,6 +9,7 @@ $(_SupportedImageRuntimes) sun.security.tools.keytool.Main ikvm.tools.keytool + true diff --git a/src/libiava/libiava.clangproj b/src/libiava/libiava.clangproj index d10120fbd4..27ea6f3bd3 100644 --- a/src/libiava/libiava.clangproj +++ b/src/libiava/libiava.clangproj @@ -6,9 +6,11 @@ iava - c99 + c89 $(IncludeDirectories);$(OpenJdkDir)jdk\src\share\native\java\io $(IncludeDirectories);$(OpenJdkDir)jdk\src\$(OpenJdkTargetOsApiDir)\native\java\io + $(IncludeDirectories);$(OpenJdkDir)jdk\src\share\native\java\lang + $(IncludeDirectories);$(OpenJdkDir)jdk\src\$(OpenJdkTargetOsApiDir)\native\java\lang @@ -19,12 +21,15 @@ + + + @@ -41,16 +46,23 @@ + + + + + + + - + \ No newline at end of file diff --git a/src/libikvm/io.c b/src/libikvm/io.c index f69a88fb60..e74954daa7 100644 --- a/src/libikvm/io.c +++ b/src/libikvm/io.c @@ -108,3 +108,17 @@ NETEXPORT void NETCALL IKVM_io_close_socket(long long handle) #endif } } + +NETEXPORT int NETCALL IKVM_io_lstat(const char* pathname, long long* st_ino, long long* st_dev) +{ +#ifdef WIN32 +#else + struct stat st; + if (lstat(pathname, &st) < 0) + return -1; + + *st_ino = st.st_ino; + *st_dev = st.st_dev; + return 0; +#endif +} diff --git a/src/libikvm/sig.c b/src/libikvm/sig.c new file mode 100644 index 0000000000..e17b8b4775 --- /dev/null +++ b/src/libikvm/sig.c @@ -0,0 +1,29 @@ +#ifdef WIN32 +#define NETEXPORT __declspec(dllexport) +#define NETCALL __stdcall +#else +#define NETEXPORT +#define NETCALL +#endif + +#if defined LINUX | MACOSX +#include +#include +#include + +NETEXPORT int NETCALL IKVM_sig_get_size_sigaction() +{ + return sizeof(struct sigaction); +} + +NETEXPORT int NETCALL IKVM_sig_get_chld_action(struct sigaction* sig) +{ + return sigaction(SIGCHLD, NULL, sig); +} + +NETEXPORT int NETCALL IKVM_sig_set_chld_action(struct sigaction* sig) +{ + return sigaction(SIGCHLD, sig, NULL); +} + +#endif diff --git a/src/libjvm/jni_md.h b/src/libjvm/jni_md.h new file mode 100644 index 0000000000..33d1ed4273 --- /dev/null +++ b/src/libjvm/jni_md.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* Switch to the correct jni_md.h file without reliance on -I options. */ +#ifdef TARGET_ARCH_x86 +# include "jni_x86.h" +#endif +#ifdef TARGET_ARCH_sparc +# include "jni_sparc.h" +#endif +#ifdef TARGET_ARCH_zero +# include "jni_zero.h" +#endif +#ifdef TARGET_ARCH_arm +# include "jni_arm.h" +#endif +#ifdef TARGET_ARCH_aarch64 +# include "jni_arm.h" +#endif +#ifdef TARGET_ARCH_ppc +# include "jni_ppc.h" +#endif + + +/* + The local copies of JNI header files may be refreshed + from a JDK distribution by means of these commands: + + cp ${JDK_DIST}/solaris/include/solaris/jni_md.h ./jni_sparc.h + cp ${JDK_DIST}/win32/include/win32/jni_md.h ./jni_i486.h + cp ${JDK_DIST}/win32/include/jni.h ./jni.h + +*/ diff --git a/src/libjvm/jvm.cpp b/src/libjvm/jvm.cpp index 463aaa4376..018dcfc005 100644 --- a/src/libjvm/jvm.cpp +++ b/src/libjvm/jvm.cpp @@ -1,6 +1,5 @@ #include #include -#include "jvm.h" #include #include @@ -21,6 +20,11 @@ #include #include #include +#include +#endif + +#ifdef __cplusplus +extern "C" { #endif #define assert(condition, fmt, ...); @@ -976,55 +980,58 @@ void* JNICALL JVM_FindLibraryEntry(void* handle, const char* name) return os_dll_lookup(handle, name); } -#ifdef __cplusplus -extern "C" { +#ifdef WIN32 +void* JNICALL JVM_GetThreadInterruptEvent() +{ + return 0; +} #endif - int jio_vsnprintf(char* str, size_t count, const char* fmt, va_list args) - { - // Reject count values that are negative signed values converted to - // unsigned; see bug 4399518, 4417214 - if ((intptr_t)count <= 0) return -1; - - int result = vsnprintf(str, count, fmt, args); - if (result > 0 && (size_t)result >= count) { - result = -1; - } +int jio_vsnprintf(char* str, size_t count, const char* fmt, va_list args) +{ + // Reject count values that are negative signed values converted to + // unsigned; see bug 4399518, 4417214 + if ((intptr_t)count <= 0) return -1; - return result; + int result = vsnprintf(str, count, fmt, args); + if (result > 0 && (size_t)result >= count) { + result = -1; } - int jio_snprintf(char* str, size_t count, const char* fmt, ...) { - va_list args; - int len; - va_start(args, fmt); - len = jio_vsnprintf(str, count, fmt, args); - va_end(args); - return len; - } + return result; +} - int jio_fprintf(FILE* f, const char* fmt, ...) { - int len; - va_list args; - va_start(args, fmt); - len = jio_vfprintf(f, fmt, args); - va_end(args); - return len; - } +int jio_snprintf(char* str, size_t count, const char* fmt, ...) { + va_list args; + int len; + va_start(args, fmt); + len = jio_vsnprintf(str, count, fmt, args); + va_end(args); + return len; +} - int jio_vfprintf(FILE* f, const char* fmt, va_list args) - { - return vfprintf(f, fmt, args); - } +int jio_fprintf(FILE* f, const char* fmt, ...) { + int len; + va_list args; + va_start(args, fmt); + len = jio_vfprintf(f, fmt, args); + va_end(args); + return len; +} - int jio_printf(const char* fmt, ...) { - int len; - va_list args; - va_start(args, fmt); - len = jio_vfprintf(stdout, fmt, args); - va_end(args); - return len; - } +int jio_vfprintf(FILE* f, const char* fmt, va_list args) +{ + return vfprintf(f, fmt, args); +} + +int jio_printf(const char* fmt, ...) { + int len; + va_list args; + va_start(args, fmt); + len = jio_vfprintf(stdout, fmt, args); + va_end(args); + return len; +} #ifdef __cplusplus } diff --git a/src/libjvm/jvm.h b/src/libjvm/jvm.h deleted file mode 100644 index 681c648c54..0000000000 --- a/src/libjvm/jvm.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - -We use this file to redefine a few methods that should be exported, but which are not exported in jni.h. -OpenJDK passes /export or -export to the command line to do these manually. - -*/ - -#include - -#ifndef _IKVM_JVM_H_ -#define _IKVM_JVM_H_ - -#ifdef __cplusplus -extern "C" { -#endif - - JNIEXPORT int jio_vsnprintf(char* str, size_t count, const char* fmt, va_list args); - - JNIEXPORT int jio_snprintf(char* str, size_t count, const char* fmt, ...); - - JNIEXPORT int jio_fprintf(FILE*, const char* fmt, ...); - - JNIEXPORT int jio_vfprintf(FILE*, const char* fmt, va_list args); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libjvm/libjvm.clangproj b/src/libjvm/libjvm.clangproj index 002fc7a938..2646f5ef9a 100644 --- a/src/libjvm/libjvm.clangproj +++ b/src/libjvm/libjvm.clangproj @@ -6,19 +6,42 @@ jvm + $(AdditionalCompileOptions);-Wno-dll-attribute-on-redeclaration - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/orbd/orbd.msbuildproj b/src/orbd/orbd.msbuildproj index e4e75bcdea..6f0e5c21f8 100644 --- a/src/orbd/orbd.msbuildproj +++ b/src/orbd/orbd.msbuildproj @@ -9,6 +9,7 @@ $(_SupportedImageRuntimes) com.sun.corba.se.impl.activation.ORBD ikvm.tools.orbd + true diff --git a/src/policytool/policytool.msbuildproj b/src/policytool/policytool.msbuildproj index ab3f612a2d..ae1e634d04 100644 --- a/src/policytool/policytool.msbuildproj +++ b/src/policytool/policytool.msbuildproj @@ -9,6 +9,7 @@ $(_SupportedImageRuntimes) sun.security.tools.policytool.PolicyTool ikvm.tools.policytool + true diff --git a/src/rmic/rmic.msbuildproj b/src/rmic/rmic.msbuildproj index da1950b85d..1ba883983f 100644 --- a/src/rmic/rmic.msbuildproj +++ b/src/rmic/rmic.msbuildproj @@ -9,6 +9,7 @@ $(_SupportedImageRuntimes) sun.rmi.rmic.Main ikvm.tools.rmic + true diff --git a/src/schemagen/schemagen.msbuildproj b/src/schemagen/schemagen.msbuildproj index 1a91d2a683..fc3fff7098 100644 --- a/src/schemagen/schemagen.msbuildproj +++ b/src/schemagen/schemagen.msbuildproj @@ -9,6 +9,7 @@ $(_SupportedImageRuntimes) com.sun.tools.internal.jxc.SchemaGenerator ikvm.tools.schemagen + true diff --git a/src/wsgen/wsgen.msbuildproj b/src/wsgen/wsgen.msbuildproj index e96627dc58..11d07b94b1 100644 --- a/src/wsgen/wsgen.msbuildproj +++ b/src/wsgen/wsgen.msbuildproj @@ -9,6 +9,7 @@ $(_SupportedImageRuntimes) com.sun.tools.internal.ws.WsGen ikvm.tools.wsgen + true diff --git a/src/wsimport/wsimport.msbuildproj b/src/wsimport/wsimport.msbuildproj index 8fbe2662d5..014cb355ed 100644 --- a/src/wsimport/wsimport.msbuildproj +++ b/src/wsimport/wsimport.msbuildproj @@ -9,6 +9,7 @@ $(_SupportedImageRuntimes) com.sun.tools.internal.ws.WsImport ikvm.tools.wsimport + true diff --git a/src/xjc/xjc.msbuildproj b/src/xjc/xjc.msbuildproj new file mode 100644 index 0000000000..897bc1e15d --- /dev/null +++ b/src/xjc/xjc.msbuildproj @@ -0,0 +1,19 @@ + + + + + + + Exe + net472;net6.0 + $(_SupportedImageRuntimes) + com.sun.tools.internal.xjc.Driver + ikvm.tools.xjc + + + + + + + + diff --git a/targets/ClangProjectReference.targets b/targets/ClangProjectReference.targets index 5f09080cf5..b7c18acf49 100644 --- a/targets/ClangProjectReference.targets +++ b/targets/ClangProjectReference.targets @@ -58,8 +58,8 @@ %(_ClangProjectReference.SetConfiguration);%(_ClangProjectReference.SetPlatform);TargetIdentifier=%(_ClangProjectReference.RuntimeIdentifier) - - + + @@ -67,7 +67,7 @@ - + runtimes\%(_ClangProjectReferenceItems.TargetIdentifier)\native\%(_ClangProjectReferenceItems.Filename)%(_ClangProjectReferenceItems.Extension)