This commit is contained in:
Henry Jen 2017-10-20 09:49:02 -07:00
commit 4e93f8fc9f
108 changed files with 2493 additions and 1429 deletions

View File

@ -1074,11 +1074,7 @@ void LinkResolver::resolve_special_call(CallInfo& result,
const LinkInfo& link_info,
TRAPS) {
methodHandle resolved_method = linktime_resolve_special_method(link_info, CHECK);
runtime_resolve_special_method(result, resolved_method,
link_info.resolved_klass(),
link_info.current_klass(),
recv,
link_info.check_access(), CHECK);
runtime_resolve_special_method(result, link_info, resolved_method, recv, CHECK);
}
// throws linktime exceptions
@ -1162,11 +1158,11 @@ methodHandle LinkResolver::linktime_resolve_special_method(const LinkInfo& link_
// throws runtime exceptions
void LinkResolver::runtime_resolve_special_method(CallInfo& result,
const LinkInfo& link_info,
const methodHandle& resolved_method,
Klass* resolved_klass,
Klass* current_klass,
Handle recv,
bool check_access, TRAPS) {
Handle recv, TRAPS) {
Klass* resolved_klass = link_info.resolved_klass();
// resolved method is selected method unless we have an old-style lookup
// for a superclass method
@ -1174,12 +1170,13 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result,
// no checks for shadowing
methodHandle sel_method(THREAD, resolved_method());
if (check_access &&
if (link_info.check_access() &&
// check if the method is not <init>
resolved_method->name() != vmSymbols::object_initializer_name()) {
// check if this is an old-style super call and do a new lookup if so
// check if this is an old-style super call and do a new lookup if so
// a) check if ACC_SUPER flag is set for the current class
Klass* current_klass = link_info.current_klass();
if ((current_klass->is_super() || !AllowNonVirtualCalls) &&
// b) check if the class of the resolved_klass is a superclass
// (not supertype in order to exclude interface classes) of the current class.
@ -1199,6 +1196,9 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result,
Method::name_and_sig_as_C_string(resolved_klass,
resolved_method->name(),
resolved_method->signature()));
// check loader constraints if found a different method
} else if (sel_method() != resolved_method()) {
check_method_loader_constraints(link_info, sel_method, "method", CHECK);
}
}

View File

@ -233,11 +233,10 @@ class LinkResolver: AllStatic {
static methodHandle linktime_resolve_interface_method (const LinkInfo& link_info, TRAPS);
static void runtime_resolve_special_method (CallInfo& result,
const LinkInfo& link_info,
const methodHandle& resolved_method,
Klass* resolved_klass,
Klass* current_klass,
Handle recv,
bool check_access, TRAPS);
Handle recv, TRAPS);
static void runtime_resolve_virtual_method (CallInfo& result,
const methodHandle& resolved_method,
Klass* resolved_klass,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -156,7 +156,7 @@ abstract class AESCipher extends CipherSpi {
throw new InvalidKeyException("Key encoding must not be null");
} else if (value.length != fixedKeySize) {
throw new InvalidKeyException("The key must be " +
fixedKeySize*8 + " bits");
fixedKeySize + " bytes");
}
}
}
@ -509,7 +509,7 @@ abstract class AESCipher extends CipherSpi {
throw new InvalidKeyException("Invalid AES key length: " +
encoded.length + " bytes");
}
return encoded.length * 8;
return Math.multiplyExact(encoded.length, 8);
}
/**
@ -628,9 +628,9 @@ abstract class AESCipher extends CipherSpi {
}
if (src != null) {
int aadLen = src.limit() - src.position();
if (aadLen != 0) {
if (aadLen > 0) {
if (src.hasArray()) {
int aadOfs = src.arrayOffset() + src.position();
int aadOfs = Math.addExact(src.arrayOffset(), src.position());
core.updateAAD(src.array(), aadOfs, aadLen);
src.position(src.limit());
} else {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -156,7 +156,7 @@ abstract class AESWrapCipher extends CipherSpi {
if (decrypting) {
result = inputLen - 8;
} else {
result = inputLen + 8;
result = Math.addExact(inputLen, 8);
}
return (result < 0? 0:result);
}
@ -378,7 +378,7 @@ abstract class AESWrapCipher extends CipherSpi {
throw new InvalidKeyException("Invalid key length: " +
encoded.length + " bytes");
}
return encoded.length * 8;
return Math.multiplyExact(encoded.length, 8);
}
/**
@ -404,7 +404,7 @@ abstract class AESWrapCipher extends CipherSpi {
throw new InvalidKeyException("Cannot get an encoding of " +
"the key to be wrapped");
}
byte[] out = new byte[keyVal.length + 8];
byte[] out = new byte[Math.addExact(keyVal.length, 8)];
if (keyVal.length == 8) {
System.arraycopy(IV, 0, out, 0, IV.length);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -257,7 +257,7 @@ public final class ARCFOURCipher extends CipherSpi {
// see JCE spec
protected int engineGetKeySize(Key key) throws InvalidKeyException {
byte[] encodedKey = getEncodedKey(key);
return encodedKey.length << 3;
return Math.multiplyExact(encodedKey.length, 8);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -373,7 +373,7 @@ public final class BlowfishCipher extends CipherSpi {
* @exception InvalidKeyException if <code>key</code> is invalid.
*/
protected int engineGetKeySize(Key key) throws InvalidKeyException {
return (key.getEncoded().length * 8);
return Math.multiplyExact(key.getEncoded().length, 8);
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -324,13 +324,14 @@ final class CipherCore {
}
private int getOutputSizeByOperation(int inputLen, boolean isDoFinal) {
int totalLen = buffered + inputLen + cipher.getBufferedLength();
int totalLen = Math.addExact(buffered, cipher.getBufferedLength());
totalLen = Math.addExact(totalLen, inputLen);
switch (cipherMode) {
case GCM_MODE:
if (isDoFinal) {
int tagLen = ((GaloisCounterMode) cipher).getTagLen();
if (!decrypting) {
totalLen += tagLen;
totalLen = Math.addExact(totalLen, tagLen);
} else {
totalLen -= tagLen;
}
@ -346,10 +347,10 @@ final class CipherCore {
totalLen = diffBlocksize;
} else {
int residue = (totalLen - diffBlocksize) % blockSize;
totalLen += (blockSize - residue);
totalLen = Math.addExact(totalLen, (blockSize - residue));
}
} else {
totalLen += padding.padLength(totalLen);
totalLen = Math.addExact(totalLen, padding.padLength(totalLen));
}
}
break;
@ -711,7 +712,8 @@ final class CipherCore {
}
// figure out how much can be sent to crypto function
int len = buffered + inputLen - minBytes;
int len = Math.addExact(buffered, inputLen);
len -= minBytes;
if (padding != null && decrypting) {
// do not include the padding bytes when decrypting
len -= blockSize;
@ -730,12 +732,12 @@ final class CipherCore {
int outLen = 0;
if (len != 0) { // there is some work to do
if ((input == output)
&& (outputOffset < (inputOffset + inputLen))
&& (inputOffset < (outputOffset + buffer.length))) {
&& (outputOffset - inputOffset < inputLen)
&& (inputOffset - outputOffset < buffer.length)) {
// copy 'input' out to avoid its content being
// overwritten prematurely.
input = Arrays.copyOfRange(input, inputOffset,
inputOffset + inputLen);
Math.addExact(inputOffset, inputLen));
inputOffset = 0;
}
if (len <= buffered) {
@ -757,13 +759,13 @@ final class CipherCore {
if (bufferCapacity != 0) {
temp = Math.min(bufferCapacity, inputConsumed);
if (unitBytes != blockSize) {
temp -= ((buffered + temp) % unitBytes);
temp -= (Math.addExact(buffered, temp) % unitBytes);
}
System.arraycopy(input, inputOffset, buffer, buffered, temp);
inputOffset += temp;
inputOffset = Math.addExact(inputOffset, temp);
inputConsumed -= temp;
inputLen -= temp;
buffered += temp;
buffered = Math.addExact(buffered, temp);
}
// process 'buffer'
if (decrypting) {
@ -771,7 +773,7 @@ final class CipherCore {
} else {
outLen = cipher.encrypt(buffer, 0, buffered, output, outputOffset);
}
outputOffset += outLen;
outputOffset = Math.addExact(outputOffset, outLen);
buffered = 0;
}
if (inputConsumed > 0) { // still has input to process
@ -802,7 +804,7 @@ final class CipherCore {
if (inputLen > 0) {
System.arraycopy(input, inputOffset, buffer, buffered,
inputLen);
buffered += inputLen;
buffered = Math.addExact(buffered, inputLen);
}
return outLen;
}
@ -912,10 +914,10 @@ final class CipherCore {
}
// calculate total input length
int len = buffered + inputLen;
int len = Math.addExact(buffered, inputLen);
// calculate padding length
int totalLen = len + cipher.getBufferedLength();
int totalLen = Math.addExact(len, cipher.getBufferedLength());
int paddingLen = 0;
// will the total input length be a multiple of blockSize?
if (unitBytes != blockSize) {
@ -948,12 +950,12 @@ final class CipherCore {
int finalBufLen = inputLen;
if ((buffered != 0) || (!decrypting && padding != null) ||
((input == output)
&& (outputOffset < (inputOffset + inputLen))
&& (inputOffset < (outputOffset + buffer.length)))) {
&& (outputOffset - inputOffset < inputLen)
&& (inputOffset - outputOffset < buffer.length))) {
if (decrypting || padding == null) {
paddingLen = 0;
}
finalBuf = new byte[len + paddingLen];
finalBuf = new byte[Math.addExact(len, paddingLen)];
finalOffset = 0;
if (buffered != 0) {
System.arraycopy(buffer, 0, finalBuf, 0, buffered);
@ -963,7 +965,7 @@ final class CipherCore {
buffered, inputLen);
}
if (paddingLen != 0) {
padding.padWithLen(finalBuf, (buffered+inputLen), paddingLen);
padding.padWithLen(finalBuf, Math.addExact(buffered, inputLen), paddingLen);
}
finalBufLen = finalBuf.length;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -140,7 +140,7 @@ public final class DESedeWrapCipher extends CipherSpi {
if (decrypting) {
result = inputLen - 16; // CHECKSUM_LEN + IV_LEN;
} else {
result = inputLen + 16;
result = Math.addExact(inputLen, 16);
}
return (result < 0? 0:result);
}
@ -449,11 +449,11 @@ public final class DESedeWrapCipher extends CipherSpi {
}
byte[] cks = getChecksum(keyVal);
byte[] in = new byte[keyVal.length + CHECKSUM_LEN];
byte[] in = new byte[Math.addExact(keyVal.length, CHECKSUM_LEN)];
System.arraycopy(keyVal, 0, in, 0, keyVal.length);
System.arraycopy(cks, 0, in, keyVal.length, CHECKSUM_LEN);
byte[] out = new byte[iv.length + in.length];
byte[] out = new byte[Math.addExact(iv.length, in.length)];
System.arraycopy(iv, 0, out, 0, iv.length);
cipher.encrypt(in, 0, in.length, out, iv.length);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,7 @@ import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.DHGenParameterSpec;
import sun.security.provider.ParameterCache;
import static sun.security.util.SecurityProviderConstants.DEF_DH_KEY_SIZE;
/**
* This class represents the key pair generator for Diffie-Hellman key pairs.
@ -42,8 +43,7 @@ import sun.security.provider.ParameterCache;
* <ul>
* <li>By providing the size in bits of the prime modulus -
* This will be used to create a prime modulus and base generator, which will
* then be used to create the Diffie-Hellman key pair. The default size of the
* prime modulus is 2048 bits.
* then be used to create the Diffie-Hellman key pair.
* <li>By providing a prime modulus and base generator
* </ul>
*
@ -68,7 +68,7 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
public DHKeyPairGenerator() {
super();
initialize(2048, null);
initialize(DEF_DH_KEY_SIZE, null);
}
private static void checkKeySize(int keysize)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -31,6 +31,8 @@ import java.security.spec.*;
import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.DHGenParameterSpec;
import static sun.security.util.SecurityProviderConstants.DEF_DH_KEY_SIZE;
/*
* This class generates parameters for the Diffie-Hellman algorithm.
* The parameters are a prime, a base, and optionally the length in bits of
@ -38,7 +40,6 @@ import javax.crypto.spec.DHGenParameterSpec;
*
* <p>The Diffie-Hellman parameter generation accepts the size in bits of the
* prime modulus and the size in bits of the random exponent as input.
* The size of the prime modulus defaults to 2048 bits.
*
* @author Jan Luehe
*
@ -50,7 +51,7 @@ import javax.crypto.spec.DHGenParameterSpec;
public final class DHParameterGenerator extends AlgorithmParameterGeneratorSpi {
// The size in bits of the prime modulus
private int primeSize = 2048;
private int primeSize = DEF_DH_KEY_SIZE;
// The size in bits of the random exponent (private value)
private int exponentSize = 0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -63,7 +63,8 @@ final class ISO10126Padding implements Padding {
if (in == null)
return;
if ((off + len) > in.length) {
int idx = Math.addExact(off, len);
if (idx > in.length) {
throw new ShortBufferException("Buffer too small to hold padding");
}
@ -71,7 +72,7 @@ final class ISO10126Padding implements Padding {
byte[] padding = new byte[len - 1];
SunJCE.getRandom().nextBytes(padding);
System.arraycopy(padding, 0, in, off, len - 1);
in[off + len - 1] = paddingOctet;
in[idx - 1] = paddingOctet;
return;
}
@ -94,14 +95,15 @@ final class ISO10126Padding implements Padding {
return 0;
}
byte lastByte = in[off + len - 1];
int idx = Math.addExact(off, len);
byte lastByte = in[idx - 1];
int padValue = (int)lastByte & 0x0ff;
if ((padValue < 0x01)
|| (padValue > blockSize)) {
return -1;
}
int start = off + len - padValue;
int start = idx - padValue;
if (start < off) {
return -1;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,12 +27,14 @@ package com.sun.crypto.provider;
import java.io.*;
import java.util.*;
import java.security.AccessController;
import java.security.DigestInputStream;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Key;
import java.security.PrivateKey;
import java.security.PrivilegedAction;
import java.security.KeyStoreSpi;
import java.security.KeyStoreException;
import java.security.UnrecoverableKeyException;
@ -835,11 +837,21 @@ public final class JceKeyStore extends KeyStoreSpi {
// read the sealed key
try {
ois = new ObjectInputStream(dis);
final ObjectInputStream ois2 = ois;
// Set a deserialization checker
AccessController.doPrivileged(
(PrivilegedAction<Void>)() -> {
ois2.setObjectInputFilter(
new DeserializationChecker());
return null;
});
entry.sealedKey = (SealedObject)ois.readObject();
// NOTE: don't close ois here since we are still
// using dis!!!
} catch (ClassNotFoundException cnfe) {
throw new IOException(cnfe.getMessage());
} catch (InvalidClassException ice) {
throw new IOException("Invalid secret key format");
}
// Add the entry to the list
@ -916,4 +928,34 @@ public final class JceKeyStore extends KeyStoreSpi {
return JCEKS_MAGIC == dataStream.readInt();
}
/*
* An ObjectInputFilter that checks the format of the secret key being
* deserialized.
*/
private static class DeserializationChecker implements ObjectInputFilter {
private static final int MAX_NESTED_DEPTH = 2;
@Override
public ObjectInputFilter.Status
checkInput(ObjectInputFilter.FilterInfo info) {
// First run a custom filter
long nestedDepth = info.depth();
if ((nestedDepth == 1 &&
info.serialClass() != SealedObjectForKeyProtector.class) ||
nestedDepth > MAX_NESTED_DEPTH) {
return Status.REJECTED;
}
// Next run the default filter, if available
ObjectInputFilter defaultFilter =
ObjectInputFilter.Config.getSerialFilter();
if (defaultFilter != null) {
return defaultFilter.checkInput(info);
}
return Status.UNDECIDED;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -38,6 +38,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.AlgorithmParameters;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import javax.crypto.Cipher;
@ -74,6 +75,8 @@ final class KeyProtector {
// keys in the keystore implementation that comes with JDK 1.2)
private static final String KEY_PROTECTOR_OID = "1.3.6.1.4.1.42.2.17.1.1";
private static final int MAX_ITERATION_COUNT = 5000000;
private static final int ITERATION_COUNT = 200000;
private static final int SALT_LEN = 20; // the salt length
private static final int DIGEST_LEN = 20;
@ -100,7 +103,7 @@ final class KeyProtector {
SunJCE.getRandom().nextBytes(salt);
// create PBE parameters from salt and iteration count
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, ITERATION_COUNT);
// create PBE key from password
PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
@ -155,6 +158,9 @@ final class KeyProtector {
pbeParams.init(encodedParams);
PBEParameterSpec pbeSpec =
pbeParams.getParameterSpec(PBEParameterSpec.class);
if (pbeSpec.getIterationCount() > MAX_ITERATION_COUNT) {
throw new IOException("PBE iteration count too large");
}
// create PBE key from password
PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
@ -285,7 +291,7 @@ final class KeyProtector {
SunJCE.getRandom().nextBytes(salt);
// create PBE parameters from salt and iteration count
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, ITERATION_COUNT);
// create PBE key from password
PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
@ -326,6 +332,15 @@ final class KeyProtector {
throw new UnrecoverableKeyException("Cannot get " +
"algorithm parameters");
}
PBEParameterSpec pbeSpec;
try {
pbeSpec = params.getParameterSpec(PBEParameterSpec.class);
} catch (InvalidParameterSpecException ipse) {
throw new IOException("Invalid PBE algorithm parameters");
}
if (pbeSpec.getIterationCount() > MAX_ITERATION_COUNT) {
throw new IOException("PBE iteration count too large");
}
PBEWithMD5AndTripleDESCipher cipherSpi;
cipherSpi = new PBEWithMD5AndTripleDESCipher();
Cipher cipher = new CipherForKeyProtector(cipherSpi,

View File

@ -1,535 +0,0 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. 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 com.sun.crypto.provider;
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
/**
* This class represents password-based encryption as defined by the PKCS #5
* standard.
*
* @author Jan Luehe
*
*
* @see javax.crypto.Cipher
*/
final class PBECipherCore {
// the encapsulated DES cipher
private CipherCore cipher;
private MessageDigest md;
private int blkSize;
private String algo = null;
private byte[] salt = null;
private int iCount = 10;
/**
* Creates an instance of PBE Cipher using the specified CipherSpi
* instance.
*
*/
PBECipherCore(String cipherAlg) throws NoSuchAlgorithmException,
NoSuchPaddingException {
algo = cipherAlg;
if (algo.equals("DES")) {
cipher = new CipherCore(new DESCrypt(),
DESConstants.DES_BLOCK_SIZE);
} else if (algo.equals("DESede")) {
cipher = new CipherCore(new DESedeCrypt(),
DESConstants.DES_BLOCK_SIZE);
} else {
throw new NoSuchAlgorithmException("No Cipher implementation " +
"for PBEWithMD5And" + algo);
}
cipher.setMode("CBC");
cipher.setPadding("PKCS5Padding");
// get instance of MD5
md = MessageDigest.getInstance("MD5");
}
/**
* Sets the mode of this cipher. This algorithm can only be run in CBC
* mode.
*
* @param mode the cipher mode
*
* @exception NoSuchAlgorithmException if the requested cipher mode is
* invalid
*/
void setMode(String mode) throws NoSuchAlgorithmException {
cipher.setMode(mode);
}
/**
* Sets the padding mechanism of this cipher. This algorithm only uses
* PKCS #5 padding.
*
* @param padding the padding mechanism
*
* @exception NoSuchPaddingException if the requested padding mechanism
* is invalid
*/
void setPadding(String paddingScheme) throws NoSuchPaddingException {
cipher.setPadding(paddingScheme);
}
/**
* Returns the block size (in bytes).
*
* @return the block size (in bytes)
*/
int getBlockSize() {
return DESConstants.DES_BLOCK_SIZE;
}
/**
* Returns the length in bytes that an output buffer would need to be in
* order to hold the result of the next <code>update</code> or
* <code>doFinal</code> operation, given the input length
* <code>inputLen</code> (in bytes).
*
* <p>This call takes into account any unprocessed (buffered) data from a
* previous <code>update</code> call, and padding.
*
* <p>The actual output length of the next <code>update</code> or
* <code>doFinal</code> call may be smaller than the length returned by
* this method.
*
* @param inputLen the input length (in bytes)
*
* @return the required output buffer size (in bytes)
*
*/
int getOutputSize(int inputLen) {
return cipher.getOutputSize(inputLen);
}
/**
* Returns the initialization vector (IV) in a new buffer.
*
* <p> This is useful in the case where a random IV has been created
* (see <a href = "#init">init</a>),
* or in the context of password-based encryption or
* decryption, where the IV is derived from a user-supplied password.
*
* @return the initialization vector in a new buffer, or null if the
* underlying algorithm does not use an IV, or if the IV has not yet
* been set.
*/
byte[] getIV() {
return cipher.getIV();
}
/**
* Returns the parameters used with this cipher.
*
* <p>The returned parameters may be the same that were used to initialize
* this cipher, or may contain the default set of parameters or a set of
* randomly generated parameters used by the underlying cipher
* implementation (provided that the underlying cipher implementation
* uses a default set of parameters or creates new parameters if it needs
* parameters but was not initialized with any).
*
* @return the parameters used with this cipher, or null if this cipher
* does not use any parameters.
*/
AlgorithmParameters getParameters() {
AlgorithmParameters params = null;
if (salt == null) {
salt = new byte[8];
SunJCE.getRandom().nextBytes(salt);
}
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount);
try {
params = AlgorithmParameters.getInstance("PBEWithMD5And" +
(algo.equalsIgnoreCase("DES")? "DES":"TripleDES"),
SunJCE.getInstance());
params.init(pbeSpec);
} catch (NoSuchAlgorithmException nsae) {
// should never happen
throw new RuntimeException("SunJCE called, but not configured");
} catch (InvalidParameterSpecException ipse) {
// should never happen
throw new RuntimeException("PBEParameterSpec not supported");
}
return params;
}
/**
* Initializes this cipher with a key, a set of
* algorithm parameters, and a source of randomness.
* The cipher is initialized for one of the following four operations:
* encryption, decryption, key wrapping or key unwrapping, depending on
* the value of <code>opmode</code>.
*
* <p>If this cipher (including its underlying feedback or padding scheme)
* requires any random bytes, it will get them from <code>random</code>.
*
* @param opmode the operation mode of this cipher (this is one of
* the following:
* <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>),
* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
* @param key the encryption key
* @param params the algorithm parameters
* @param random the source of randomness
*
* @exception InvalidKeyException if the given key is inappropriate for
* initializing this cipher
* @exception InvalidAlgorithmParameterException if the given algorithm
* parameters are inappropriate for this cipher
*/
void init(int opmode, Key key, AlgorithmParameterSpec params,
SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
if (((opmode == Cipher.DECRYPT_MODE) ||
(opmode == Cipher.UNWRAP_MODE)) && (params == null)) {
throw new InvalidAlgorithmParameterException("Parameters "
+ "missing");
}
if ((key == null) ||
(key.getEncoded() == null) ||
!(key.getAlgorithm().regionMatches(true, 0, "PBE", 0, 3))) {
throw new InvalidKeyException("Missing password");
}
if (params == null) {
// create random salt and use default iteration count
salt = new byte[8];
random.nextBytes(salt);
} else {
if (!(params instanceof PBEParameterSpec)) {
throw new InvalidAlgorithmParameterException
("Wrong parameter type: PBE expected");
}
salt = ((PBEParameterSpec) params).getSalt();
// salt must be 8 bytes long (by definition)
if (salt.length != 8) {
throw new InvalidAlgorithmParameterException
("Salt must be 8 bytes long");
}
iCount = ((PBEParameterSpec) params).getIterationCount();
if (iCount <= 0) {
throw new InvalidAlgorithmParameterException
("IterationCount must be a positive number");
}
}
byte[] derivedKey = deriveCipherKey(key);
// use all but the last 8 bytes as the key value
SecretKeySpec cipherKey = new SecretKeySpec(derivedKey, 0,
derivedKey.length-8, algo);
// use the last 8 bytes as the IV
IvParameterSpec ivSpec = new IvParameterSpec(derivedKey,
derivedKey.length-8,
8);
// initialize the underlying cipher
cipher.init(opmode, cipherKey, ivSpec, random);
}
private byte[] deriveCipherKey(Key key) {
byte[] result = null;
byte[] passwdBytes = key.getEncoded();
if (algo.equals("DES")) {
// P || S (password concatenated with salt)
byte[] concat = new byte[passwdBytes.length + salt.length];
System.arraycopy(passwdBytes, 0, concat, 0, passwdBytes.length);
java.util.Arrays.fill(passwdBytes, (byte)0x00);
System.arraycopy(salt, 0, concat, passwdBytes.length, salt.length);
// digest P || S with c iterations
byte[] toBeHashed = concat;
for (int i = 0; i < iCount; i++) {
md.update(toBeHashed);
toBeHashed = md.digest(); // this resets the digest
}
java.util.Arrays.fill(concat, (byte)0x00);
result = toBeHashed;
} else if (algo.equals("DESede")) {
// if the 2 salt halves are the same, invert one of them
int i;
for (i=0; i<4; i++) {
if (salt[i] != salt[i+4])
break;
}
if (i==4) { // same, invert 1st half
for (i=0; i<2; i++) {
byte tmp = salt[i];
salt[i] = salt[3-i];
salt[3-1] = tmp;
}
}
// Now digest each half (concatenated with password). For each
// half, go through the loop as many times as specified by the
// iteration count parameter (inner for loop).
// Concatenate the output from each digest round with the
// password, and use the result as the input to the next digest
// operation.
byte[] kBytes = null;
IvParameterSpec iv = null;
byte[] toBeHashed = null;
result = new byte[DESedeKeySpec.DES_EDE_KEY_LEN +
DESConstants.DES_BLOCK_SIZE];
for (i = 0; i < 2; i++) {
toBeHashed = new byte[salt.length/2];
System.arraycopy(salt, i*(salt.length/2), toBeHashed, 0,
toBeHashed.length);
for (int j=0; j < iCount; j++) {
md.update(toBeHashed);
md.update(passwdBytes);
toBeHashed = md.digest(); // this resets the digest
}
System.arraycopy(toBeHashed, 0, result, i*16,
toBeHashed.length);
}
}
return result;
}
void init(int opmode, Key key, AlgorithmParameters params,
SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
PBEParameterSpec pbeSpec = null;
if (params != null) {
try {
pbeSpec = params.getParameterSpec(PBEParameterSpec.class);
} catch (InvalidParameterSpecException ipse) {
throw new InvalidAlgorithmParameterException("Wrong parameter "
+ "type: PBE "
+ "expected");
}
}
init(opmode, key, pbeSpec, random);
}
/**
* Continues a multiple-part encryption or decryption operation
* (depending on how this cipher was initialized), processing another data
* part.
*
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
* buffer, starting at <code>inputOffset</code>, are processed, and the
* result is stored in a new buffer.
*
* @param input the input buffer
* @param inputOffset the offset in <code>input</code> where the input
* starts
* @param inputLen the input length
*
* @return the new buffer with the result
*
*/
byte[] update(byte[] input, int inputOffset, int inputLen) {
return cipher.update(input, inputOffset, inputLen);
}
/**
* Continues a multiple-part encryption or decryption operation
* (depending on how this cipher was initialized), processing another data
* part.
*
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
* buffer, starting at <code>inputOffset</code>, are processed, and the
* result is stored in the <code>output</code> buffer, starting at
* <code>outputOffset</code>.
*
* @param input the input buffer
* @param inputOffset the offset in <code>input</code> where the input
* starts
* @param inputLen the input length
* @param output the buffer for the result
* @param outputOffset the offset in <code>output</code> where the result
* is stored
*
* @return the number of bytes stored in <code>output</code>
*
* @exception ShortBufferException if the given output buffer is too small
* to hold the result
*/
int update(byte[] input, int inputOffset, int inputLen,
byte[] output, int outputOffset)
throws ShortBufferException {
return cipher.update(input, inputOffset, inputLen,
output, outputOffset);
}
/**
* Encrypts or decrypts data in a single-part operation,
* or finishes a multiple-part operation.
* The data is encrypted or decrypted, depending on how this cipher was
* initialized.
*
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
* buffer, starting at <code>inputOffset</code>, and any input bytes that
* may have been buffered during a previous <code>update</code> operation,
* are processed, with padding (if requested) being applied.
* The result is stored in a new buffer.
*
* <p>The cipher is reset to its initial state (uninitialized) after this
* call.
*
* @param input the input buffer
* @param inputOffset the offset in <code>input</code> where the input
* starts
* @param inputLen the input length
*
* @return the new buffer with the result
*
* @exception IllegalBlockSizeException if this cipher is a block cipher,
* no padding has been requested (only in encryption mode), and the total
* input length of the data processed by this cipher is not a multiple of
* block size
* @exception BadPaddingException if decrypting and padding is chosen,
* but the last input data does not have proper padding bytes.
*/
byte[] doFinal(byte[] input, int inputOffset, int inputLen)
throws IllegalBlockSizeException, BadPaddingException {
return cipher.doFinal(input, inputOffset, inputLen);
}
/**
* Encrypts or decrypts data in a single-part operation,
* or finishes a multiple-part operation.
* The data is encrypted or decrypted, depending on how this cipher was
* initialized.
*
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
* buffer, starting at <code>inputOffset</code>, and any input bytes that
* may have been buffered during a previous <code>update</code> operation,
* are processed, with padding (if requested) being applied.
* The result is stored in the <code>output</code> buffer, starting at
* <code>outputOffset</code>.
*
* <p>The cipher is reset to its initial state (uninitialized) after this
* call.
*
* @param input the input buffer
* @param inputOffset the offset in <code>input</code> where the input
* starts
* @param inputLen the input length
* @param output the buffer for the result
* @param outputOffset the offset in <code>output</code> where the result
* is stored
*
* @return the number of bytes stored in <code>output</code>
*
* @exception IllegalBlockSizeException if this cipher is a block cipher,
* no padding has been requested (only in encryption mode), and the total
* input length of the data processed by this cipher is not a multiple of
* block size
* @exception ShortBufferException if the given output buffer is too small
* to hold the result
* @exception BadPaddingException if decrypting and padding is chosen,
* but the last input data does not have proper padding bytes.
*/
int doFinal(byte[] input, int inputOffset, int inputLen,
byte[] output, int outputOffset)
throws ShortBufferException, IllegalBlockSizeException,
BadPaddingException {
return cipher.doFinal(input, inputOffset, inputLen,
output, outputOffset);
}
/**
* Wrap a key.
*
* @param key the key to be wrapped.
*
* @return the wrapped key.
*
* @exception IllegalBlockSizeException if this cipher is a block
* cipher, no padding has been requested, and the length of the
* encoding of the key to be wrapped is not a
* multiple of the block size.
*
* @exception InvalidKeyException if it is impossible or unsafe to
* wrap the key with this cipher (e.g., a hardware protected key is
* being passed to a software only cipher).
*/
byte[] wrap(Key key)
throws IllegalBlockSizeException, InvalidKeyException {
byte[] result = null;
try {
byte[] encodedKey = key.getEncoded();
if ((encodedKey == null) || (encodedKey.length == 0)) {
throw new InvalidKeyException("Cannot get an encoding of " +
"the key to be wrapped");
}
result = doFinal(encodedKey, 0, encodedKey.length);
} catch (BadPaddingException e) {
// Should never happen
}
return result;
}
/**
* Unwrap a previously wrapped key.
*
* @param wrappedKey the key to be unwrapped.
*
* @param wrappedKeyAlgorithm the algorithm the wrapped key is for.
*
* @param wrappedKeyType the type of the wrapped key.
* This is one of <code>Cipher.SECRET_KEY</code>,
* <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>.
*
* @return the unwrapped key.
*
* @exception NoSuchAlgorithmException if no installed providers
* can create keys of type <code>wrappedKeyType</code> for the
* <code>wrappedKeyAlgorithm</code>.
*
* @exception InvalidKeyException if <code>wrappedKey</code> does not
* represent a wrapped key of type <code>wrappedKeyType</code> for
* the <code>wrappedKeyAlgorithm</code>.
*/
Key unwrap(byte[] wrappedKey,
String wrappedKeyAlgorithm,
int wrappedKeyType)
throws InvalidKeyException, NoSuchAlgorithmException {
byte[] encodedKey;
try {
encodedKey = doFinal(wrappedKey, 0, wrappedKey.length);
} catch (BadPaddingException ePadding) {
throw new InvalidKeyException("The wrapped key is not padded " +
"correctly");
} catch (IllegalBlockSizeException eBlockSize) {
throw new InvalidKeyException("The wrapped key does not have " +
"the correct length");
}
return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm,
wrappedKeyType);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -260,7 +260,7 @@ final class PBES1Core {
if (algo.equals("DES")) {
// P || S (password concatenated with salt)
byte[] concat = new byte[passwdBytes.length + salt.length];
byte[] concat = new byte[Math.addExact(passwdBytes.length, salt.length)];
System.arraycopy(passwdBytes, 0, concat, 0, passwdBytes.length);
java.util.Arrays.fill(passwdBytes, (byte)0x00);
System.arraycopy(salt, 0, concat, passwdBytes.length, salt.length);
@ -284,7 +284,7 @@ final class PBES1Core {
for (i=0; i<2; i++) {
byte tmp = salt[i];
salt[i] = salt[3-i];
salt[3-1] = tmp;
salt[3-i] = tmp;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
package com.sun.crypto.provider;
import javax.crypto.ShortBufferException;
import java.util.Arrays;
/**
* This class implements padding as specified in the PKCS#5 standard.
@ -63,14 +64,13 @@ final class PKCS5Padding implements Padding {
if (in == null)
return;
if ((off + len) > in.length) {
int idx = Math.addExact(off, len);
if (idx > in.length) {
throw new ShortBufferException("Buffer too small to hold padding");
}
byte paddingOctet = (byte) (len & 0xff);
for (int i = 0; i < len; i++) {
in[i + off] = paddingOctet;
}
Arrays.fill(in, off, idx, paddingOctet);
return;
}
@ -92,25 +92,24 @@ final class PKCS5Padding implements Padding {
(len == 0)) { // this can happen if input is really a padded buffer
return 0;
}
byte lastByte = in[off + len - 1];
int idx = Math.addExact(off, len);
byte lastByte = in[idx - 1];
int padValue = (int)lastByte & 0x0ff;
if ((padValue < 0x01)
|| (padValue > blockSize)) {
return -1;
}
int start = off + len - ((int)lastByte & 0x0ff);
int start = idx - padValue;
if (start < off) {
return -1;
}
for (int i = 0; i < ((int)lastByte & 0x0ff); i++) {
if (in[start+i] != lastByte) {
for (int i = start; i < idx; i++) {
if (in[i] != lastByte) {
return -1;
}
}
return start;
}

View File

@ -38,6 +38,7 @@ package com.sun.net.ssl.internal.www.protocol.https;
import java.net.URL;
import java.net.Proxy;
import java.net.ProtocolException;
import java.net.MalformedURLException;
import java.io.*;
import java.net.Authenticator;
import javax.net.ssl.*;
@ -78,10 +79,18 @@ public class HttpsURLConnectionOldImpl
this(u, null, handler);
}
static URL checkURL(URL u) throws IOException {
if (u != null) {
if (u.toExternalForm().indexOf('\n') > -1) {
throw new MalformedURLException("Illegal character in URL");
}
}
return u;
}
// For both copies of the file, uncomment one line and comment the other
// HttpsURLConnectionImpl(URL u, Handler handler) throws IOException {
HttpsURLConnectionOldImpl(URL u, Proxy p, Handler handler) throws IOException {
super(u);
super(checkURL(u));
delegate = new DelegateHttpsURLConnection(url, p, handler, this);
}

View File

@ -44,7 +44,6 @@ import java.util.concurrent.ConcurrentMap;
import static java.io.ObjectStreamClass.processQueue;
import jdk.internal.misc.ObjectStreamClassValidator;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.Unsafe;
import sun.reflect.misc.ReflectUtil;
@ -1282,6 +1281,33 @@ public class ObjectInputStream
}
}
/**
* Checks the given array type and length to ensure that creation of such
* an array is permitted by this ObjectInputStream. The arrayType argument
* must represent an actual array type.
*
* This private method is called via SharedSecrets.
*
* @param arrayType the array type
* @param arrayLength the array length
* @throws NullPointerException if arrayType is null
* @throws IllegalArgumentException if arrayType isn't actually an array type
* @throws NegativeArraySizeException if arrayLength is negative
* @throws InvalidClassException if the filter rejects creation
*/
private void checkArray(Class<?> arrayType, int arrayLength) throws InvalidClassException {
Objects.requireNonNull(arrayType);
if (! arrayType.isArray()) {
throw new IllegalArgumentException("not an array type");
}
if (arrayLength < 0) {
throw new NegativeArraySizeException();
}
filterCheck(arrayType, arrayLength);
}
/**
* Provide access to the persistent fields read from the input stream.
*/
@ -1740,9 +1766,6 @@ public class ObjectInputStream
throw new StreamCorruptedException(
String.format("invalid type code: %02X", tc));
}
if (descriptor != null) {
validateDescriptor(descriptor);
}
return descriptor;
}
@ -1770,6 +1793,10 @@ public class ObjectInputStream
passHandle = NULL_HANDLE;
int numIfaces = bin.readInt();
if (numIfaces > 65535) {
throw new InvalidObjectException("interface limit exceeded: "
+ numIfaces);
}
String[] ifaces = new String[numIfaces];
for (int i = 0; i < numIfaces; i++) {
ifaces[i] = bin.readUTF();
@ -3978,20 +4005,8 @@ public class ObjectInputStream
}
}
private void validateDescriptor(ObjectStreamClass descriptor) {
ObjectStreamClassValidator validating = validator;
if (validating != null) {
validating.validateDescriptor(descriptor);
}
}
// controlled access to ObjectStreamClassValidator
private volatile ObjectStreamClassValidator validator;
private static void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator) {
ois.validator = validator;
}
static {
SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator);
SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::checkArray);
}
}

View File

@ -32,14 +32,19 @@ import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -53,7 +58,8 @@ import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import jdk.internal.reflect.ReflectionFactory;
import sun.reflect.misc.ReflectUtil;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.JavaSecurityAccess;
import static java.io.ObjectStreamField.*;
/**
@ -176,6 +182,9 @@ public class ObjectStreamClass implements Serializable {
/** serialization-appropriate constructor, or null if none */
private Constructor<?> cons;
/** protection domains that need to be checked when calling the constructor */
private ProtectionDomain[] domains;
/** class-defined writeObject method, or null if none */
private Method writeObjectMethod;
/** class-defined readObject method, or null if none */
@ -508,6 +517,7 @@ public class ObjectStreamClass implements Serializable {
cl, "readObjectNoData", null, Void.TYPE);
hasWriteObjectData = (writeObjectMethod != null);
}
domains = getProtectionDomains(cons, cl);
writeReplaceMethod = getInheritableMethod(
cl, "writeReplace", null, Object.class);
readResolveMethod = getInheritableMethod(
@ -550,6 +560,65 @@ public class ObjectStreamClass implements Serializable {
ObjectStreamClass() {
}
/**
* Creates a PermissionDomain that grants no permission.
*/
private ProtectionDomain noPermissionsDomain() {
PermissionCollection perms = new Permissions();
perms.setReadOnly();
return new ProtectionDomain(null, perms);
}
/**
* Aggregate the ProtectionDomains of all the classes that separate
* a concrete class {@code cl} from its ancestor's class declaring
* a constructor {@code cons}.
*
* If {@code cl} is defined by the boot loader, or the constructor
* {@code cons} is declared by {@code cl}, or if there is no security
* manager, then this method does nothing and {@code null} is returned.
*
* @param cons A constructor declared by {@code cl} or one of its
* ancestors.
* @param cl A concrete class, which is either the class declaring
* the constructor {@code cons}, or a serializable subclass
* of that class.
* @return An array of ProtectionDomain representing the set of
* ProtectionDomain that separate the concrete class {@code cl}
* from its ancestor's declaring {@code cons}, or {@code null}.
*/
private ProtectionDomain[] getProtectionDomains(Constructor<?> cons,
Class<?> cl) {
ProtectionDomain[] domains = null;
if (cons != null && cl.getClassLoader() != null
&& System.getSecurityManager() != null) {
Class<?> cls = cl;
Class<?> fnscl = cons.getDeclaringClass();
Set<ProtectionDomain> pds = null;
while (cls != fnscl) {
ProtectionDomain pd = cls.getProtectionDomain();
if (pd != null) {
if (pds == null) pds = new HashSet<>();
pds.add(pd);
}
cls = cls.getSuperclass();
if (cls == null) {
// that's not supposed to happen
// make a ProtectionDomain with no permission.
// should we throw instead?
if (pds == null) pds = new HashSet<>();
else pds.clear();
pds.add(noPermissionsDomain());
break;
}
}
if (pds != null) {
domains = pds.toArray(new ProtectionDomain[0]);
}
}
return domains;
}
/**
* Initializes class descriptor representing a proxy class.
*/
@ -580,6 +649,7 @@ public class ObjectStreamClass implements Serializable {
writeReplaceMethod = localDesc.writeReplaceMethod;
readResolveMethod = localDesc.readResolveMethod;
deserializeEx = localDesc.deserializeEx;
domains = localDesc.domains;
cons = localDesc.cons;
}
fieldRefl = getReflector(fields, localDesc);
@ -666,6 +736,7 @@ public class ObjectStreamClass implements Serializable {
if (deserializeEx == null) {
deserializeEx = localDesc.deserializeEx;
}
domains = localDesc.domains;
cons = localDesc.cons;
}
@ -1006,7 +1077,35 @@ public class ObjectStreamClass implements Serializable {
requireInitialized();
if (cons != null) {
try {
return cons.newInstance();
if (domains == null || domains.length == 0) {
return cons.newInstance();
} else {
JavaSecurityAccess jsa = SharedSecrets.getJavaSecurityAccess();
PrivilegedAction<?> pea = () -> {
try {
return cons.newInstance();
} catch (InstantiationException
| InvocationTargetException
| IllegalAccessException x) {
throw new UndeclaredThrowableException(x);
}
}; // Can't use PrivilegedExceptionAction with jsa
try {
return jsa.doIntersectionPrivilege(pea,
AccessController.getContext(),
new AccessControlContext(domains));
} catch (UndeclaredThrowableException x) {
Throwable cause = x.getCause();
if (cause instanceof InstantiationException)
throw (InstantiationException) cause;
if (cause instanceof InvocationTargetException)
throw (InvocationTargetException) cause;
if (cause instanceof IllegalAccessException)
throw (IllegalAccessException) cause;
// not supposed to happen
throw x;
}
}
} catch (IllegalAccessException ex) {
// should not occur, as access checks have been suppressed
throw new InternalError(ex);

View File

@ -35,6 +35,7 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.cert.*;
import sun.net.util.URLUtil;
import sun.security.util.IOUtils;
/**
*
@ -571,6 +572,8 @@ public class CodeSource implements java.io.Serializable {
// could all be present in the stream at the same time
cfs = new Hashtable<>(3);
certList = new ArrayList<>(size > 20 ? 20 : size);
} else if (size < 0) {
throw new IOException("size cannot be negative");
}
for (int i = 0; i < size; i++) {
@ -592,13 +595,7 @@ public class CodeSource implements java.io.Serializable {
cfs.put(certType, cf);
}
// parse the certificate
byte[] encoded = null;
try {
encoded = new byte[ois.readInt()];
} catch (OutOfMemoryError oome) {
throw new IOException("Certificate too big");
}
ois.readFully(encoded);
byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
try {
certList.add(cf.generateCertificate(bais));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,12 +25,16 @@
package java.security;
import sun.security.util.IOUtils;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Hashtable;
import java.lang.reflect.*;
import java.security.cert.*;
import java.util.List;
/**
* The UnresolvedPermission class is used to hold Permissions that
@ -550,6 +554,7 @@ implements java.io.Serializable
{
CertificateFactory cf;
Hashtable<String, CertificateFactory> cfs = null;
List<Certificate> certList = null;
ois.defaultReadObject();
@ -562,7 +567,9 @@ implements java.io.Serializable
// we know of 3 different cert types: X.509, PGP, SDSI, which
// could all be present in the stream at the same time
cfs = new Hashtable<>(3);
this.certs = new java.security.cert.Certificate[size];
certList = new ArrayList<>(size > 20 ? 20 : size);
} else if (size < 0) {
throw new IOException("size cannot be negative");
}
for (int i=0; i<size; i++) {
@ -584,20 +591,18 @@ implements java.io.Serializable
cfs.put(certType, cf);
}
// parse the certificate
byte[] encoded=null;
try {
encoded = new byte[ois.readInt()];
} catch (OutOfMemoryError oome) {
throw new IOException("Certificate too big");
}
ois.readFully(encoded);
byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
try {
this.certs[i] = cf.generateCertificate(bais);
certList.add(cf.generateCertificate(bais));
} catch (CertificateException ce) {
throw new IOException(ce.getMessage());
}
bais.close();
}
if (certList != null) {
this.certs = certList.toArray(
new java.security.cert.Certificate[size]);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -34,6 +34,7 @@ import java.util.HashMap;
import java.util.Map;
import javax.security.auth.x500.X500Principal;
import sun.security.util.IOUtils;
import sun.security.util.ObjectIdentifier;
import sun.security.x509.InvalidityDateExtension;
@ -230,17 +231,17 @@ public class CertificateRevokedException extends CertificateException {
int size = ois.readInt();
if (size == 0) {
extensions = Collections.emptyMap();
} else if (size < 0) {
throw new IOException("size cannot be negative");
} else {
extensions = new HashMap<>(size);
extensions = new HashMap<>(size > 20 ? 20 : size);
}
// Read in the extensions and put the mappings in the extensions map
for (int i = 0; i < size; i++) {
String oid = (String) ois.readObject();
boolean critical = ois.readBoolean();
int length = ois.readInt();
byte[] extVal = new byte[length];
ois.readFully(extVal);
byte[] extVal = IOUtils.readNBytes(ois, ois.readInt());
Extension ext = sun.security.x509.Extension.newExtension
(new ObjectIdentifier(oid), critical, extVal);
extensions.put(oid, ext);

View File

@ -38,6 +38,7 @@ import java.io.Serializable;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import jdk.internal.misc.SharedSecrets;
/**
* Resizable-array implementation of the {@link Deque} interface. Array
@ -1194,6 +1195,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
// Read in size and allocate array
int size = s.readInt();
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size + 1);
elements = new Object[size + 1];
this.tail = size;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,6 +28,7 @@ package java.util;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import jdk.internal.misc.SharedSecrets;
/**
* Resizable-array implementation of the {@code List} interface. Implements
@ -814,6 +815,7 @@ public class ArrayList<E> extends AbstractList<E>
if (size > 0) {
// like clone(), allocate array based upon size not capacity
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size);
Object[] elements = new Object[size];
// Read in all elements in the proper order.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -34,6 +34,7 @@ import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import jdk.internal.misc.SharedSecrets;
/**
* Hash table based implementation of the {@code Map} interface. This
@ -1448,6 +1449,10 @@ public class HashMap<K,V> extends AbstractMap<K,V>
float ft = (float)cap * lf;
threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?
(int)ft : Integer.MAX_VALUE);
// Check Map.Entry[].class since it's the nearest public type to
// what we're actually creating.
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Map.Entry[].class, cap);
@SuppressWarnings({"rawtypes","unchecked"})
Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
table = tab;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
package java.util;
import java.io.InvalidObjectException;
import jdk.internal.misc.SharedSecrets;
/**
* This class implements the {@code Set} interface, backed by a hash table
@ -322,6 +323,13 @@ public class HashSet<E>
capacity = (int) Math.min(size * Math.min(1 / loadFactor, 4.0f),
HashMap.MAXIMUM_CAPACITY);
// Constructing the backing map will lazily create an array when the first element is
// added, so check it before construction. Call HashMap.tableSizeFor to compute the
// actual allocation size. Check Map.Entry[].class since it's the nearest public type to
// what is actually created.
SharedSecrets.getJavaObjectInputStreamAccess()
.checkArray(s, Map.Entry[].class, HashMap.tableSizeFor(capacity));
// Create backing HashMap
map = (((HashSet<?>)this) instanceof LinkedHashSet ?
new LinkedHashMap<>(capacity, loadFactor) :

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,7 @@ import java.io.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.BiFunction;
import jdk.internal.misc.SharedSecrets;
/**
* This class implements a hash table, which maps keys to values. Any
@ -1291,6 +1292,10 @@ public class Hashtable<K,V>
if (length > elements && (length & 1) == 0)
length--;
length = Math.min(length, origlength);
// Check Map.Entry[].class since it's the nearest public type to
// what we're actually creating.
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Map.Entry[].class, length);
table = new Entry<?,?>[length];
threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1);
count = 0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,7 @@ import java.lang.reflect.Array;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import jdk.internal.misc.SharedSecrets;
/**
* This class implements the {@code Map} interface with a hash table, using
@ -1304,7 +1305,9 @@ public class IdentityHashMap<K,V>
if (size < 0)
throw new java.io.StreamCorruptedException
("Illegal mappings count: " + size);
init(capacity(size));
int cap = capacity(size);
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, cap);
init(cap);
// Read the keys and values, and put the mappings in the table
for (int i=0; i<size; i++) {

View File

@ -35,6 +35,7 @@ import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.vm.annotation.Stable;
/**
@ -885,6 +886,7 @@ final class CollSer implements Serializable {
throw new InvalidObjectException("negative length " + len);
}
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(ois, Object[].class, len);
Object[] a = new Object[len];
for (int i = 0; i < len; i++) {
a[i] = ois.readObject();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
package java.util;
import java.util.function.Consumer;
import jdk.internal.misc.SharedSecrets;
/**
* An unbounded priority {@linkplain Queue queue} based on a priority heap.
@ -795,6 +796,7 @@ public class PriorityQueue<E> extends AbstractQueue<E>
// Read in (and discard) array length
s.readInt();
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size);
queue = new Object[size];
// Read in all elements.

View File

@ -42,6 +42,7 @@ import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.util.xml.PropertiesDefaultHandler;
/**
@ -1441,6 +1442,16 @@ class Properties extends Hashtable<Object,Object> {
throw new StreamCorruptedException("Illegal # of Elements: " + elements);
}
// Constructing the backing map will lazily create an array when the first element is
// added, so check it before construction. Note that CHM's constructor takes a size
// that is the number of elements to be stored -- not the table size -- so it must be
// inflated by the default load factor of 0.75, then inflated to the next power of two.
// (CHM uses the same power-of-two computation as HashMap, and HashMap.tableSizeFor is
// accessible here.) Check Map.Entry[].class since it's the nearest public type to
// what is actually created.
SharedSecrets.getJavaObjectInputStreamAccess()
.checkArray(s, Map.Entry[].class, HashMap.tableSizeFor((int)(elements / 0.75)));
// create CHM of appropriate capacity
map = new ConcurrentHashMap<>(elements);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -41,6 +41,7 @@ package java.util;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.io.InvalidObjectException;
import sun.util.calendar.CalendarSystem;
import sun.util.calendar.CalendarUtils;
import sun.util.calendar.BaseCalendar;
@ -1278,6 +1279,9 @@ public class SimpleTimeZone extends TimeZone {
*/
private int serialVersionOnStream = currentSerialVersion;
// Maximum number of rules.
private static final int MAX_RULE_NUM = 6;
private synchronized void invalidateCache() {
cacheYear = startYear - 1;
cacheStart = cacheEnd = 0;
@ -1569,7 +1573,7 @@ public class SimpleTimeZone extends TimeZone {
*/
private byte[] packRules()
{
byte[] rules = new byte[6];
byte[] rules = new byte[MAX_RULE_NUM];
rules[0] = (byte)startDay;
rules[1] = (byte)startDayOfWeek;
rules[2] = (byte)endDay;
@ -1594,7 +1598,7 @@ public class SimpleTimeZone extends TimeZone {
endDayOfWeek = rules[3];
// As of serial version 2, include time modes
if (rules.length >= 6) {
if (rules.length >= MAX_RULE_NUM) {
startTimeMode = rules[4];
endTimeMode = rules[5];
}
@ -1691,9 +1695,13 @@ public class SimpleTimeZone extends TimeZone {
// store the actual rules (which have not be made compatible with 1.1)
// in the optional area. Read them in here and parse them.
int length = stream.readInt();
byte[] rules = new byte[length];
stream.readFully(rules);
unpackRules(rules);
if (length <= MAX_RULE_NUM) {
byte[] rules = new byte[length];
stream.readFully(rules);
unpackRules(rules);
} else {
throw new InvalidObjectException("Too many rules: " + length);
}
}
if (serialVersionOnStream >= 2) {

View File

@ -51,6 +51,7 @@ import java.util.Spliterators;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import jdk.internal.misc.SharedSecrets;
/**
* A thread-safe variant of {@link java.util.ArrayList} in which all mutative
@ -933,6 +934,7 @@ public class CopyOnWriteArrayList<E>
// Read in array length and allocate array
int len = s.readInt();
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, len);
Object[] elements = new Object[len];
// Read in all elements in the proper order.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,17 +25,14 @@
package jdk.internal.misc;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
/**
* The interface to specify methods for accessing {@code ObjectInputStream}
* @author sjiang
* Interface to specify methods for accessing {@code ObjectInputStream}.
*/
@FunctionalInterface
public interface JavaObjectInputStreamAccess {
/**
* Sets a descriptor validating.
* @param ois stream to have the descriptors validated
* @param validator validator used to validate a descriptor.
*/
public void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator);
void checkArray(ObjectInputStream ois, Class<?> arrayType, int arrayLength)
throws InvalidClassException;
}

View File

@ -1,42 +0,0 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.misc;
import java.io.ObjectStreamClass;
/**
* A callback used by {@code ObjectInputStream} to do descriptor validation.
*
* @author sjiang
*/
public interface ObjectStreamClassValidator {
/**
* This method will be called by ObjectInputStream to
* check a descriptor just before creating an object described by this descriptor.
* The object will not be created if this method throws a {@code RuntimeException}.
* @param descriptor descriptor to be checked.
*/
public void validateDescriptor(ObjectStreamClass descriptor);
}

View File

@ -115,8 +115,8 @@ public class FtpClient extends sun.net.ftp.FtpClient {
new PrivilegedAction<Object>() {
public Object run() {
vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 0).intValue();
vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 0).intValue();
vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 300_000).intValue();
vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 300_000).intValue();
encs[0] = System.getProperty("file.encoding", "ISO8859_1");
return null;
}

View File

@ -843,18 +843,36 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
this(u, null, handler);
}
public HttpURLConnection(URL u, String host, int port) {
this(u, new Proxy(Proxy.Type.HTTP, InetSocketAddress.createUnresolved(host, port)));
private static String checkHost(String h) throws IOException {
if (h != null) {
if (h.indexOf('\n') > -1) {
throw new MalformedURLException("Illegal character in host");
}
}
return h;
}
public HttpURLConnection(URL u, String host, int port) throws IOException {
this(u, new Proxy(Proxy.Type.HTTP,
InetSocketAddress.createUnresolved(checkHost(host), port)));
}
/** this constructor is used by other protocol handlers such as ftp
that want to use http to fetch urls on their behalf.*/
public HttpURLConnection(URL u, Proxy p) {
public HttpURLConnection(URL u, Proxy p) throws IOException {
this(u, p, new Handler());
}
protected HttpURLConnection(URL u, Proxy p, Handler handler) {
super(u);
private static URL checkURL(URL u) throws IOException {
if (u != null) {
if (u.toExternalForm().indexOf('\n') > -1) {
throw new MalformedURLException("Illegal character in URL");
}
}
return u;
}
protected HttpURLConnection(URL u, Proxy p, Handler handler)
throws IOException {
super(checkURL(u));
requests = new MessageHeader();
responses = new MessageHeader();
userHeaders = new MessageHeader();

View File

@ -38,6 +38,7 @@ package sun.net.www.protocol.https;
import java.net.URL;
import java.net.Proxy;
import java.net.ProtocolException;
import java.net.MalformedURLException;
import java.io.*;
import java.net.Authenticator;
import javax.net.ssl.*;
@ -80,10 +81,18 @@ public class HttpsURLConnectionImpl
this(u, null, handler);
}
static URL checkURL(URL u) throws IOException {
if (u != null) {
if (u.toExternalForm().indexOf('\n') > -1) {
throw new MalformedURLException("Illegal character in URL");
}
}
return u;
}
// For both copies of the file, uncomment one line and comment the other
HttpsURLConnectionImpl(URL u, Proxy p, Handler handler) throws IOException {
// HttpsURLConnectionOldImpl(URL u, Proxy p, Handler handler) throws IOException {
super(u);
super(checkURL(u));
delegate = new DelegateHttpsURLConnection(url, p, handler, this);
}

View File

@ -46,6 +46,7 @@ import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.*;
@ -147,6 +148,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
"keystore.PKCS12.keyProtectionAlgorithm"
};
private static final int MAX_ITERATION_COUNT = 5000000;
private static final int PBE_ITERATION_COUNT = 50000; // default
private static final int MAC_ITERATION_COUNT = 100000; // default
private static final int SALT_LEN = 20;
// friendlyName, localKeyId, trustedKeyUsage
private static final String[] CORE_ATTRIBUTES = {
"1.2.840.113549.1.9.20",
@ -192,8 +198,6 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
private static ObjectIdentifier[] AnyUsage;
private int counter = 0;
private static final int iterationCount = 1024;
private static final int SALT_LEN = 20;
// private key count
// Note: This is a workaround to allow null localKeyID attribute
@ -327,6 +331,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
byte[] encryptedKey;
AlgorithmParameters algParams;
ObjectIdentifier algOid;
try {
// get the encrypted private key
EncryptedPrivateKeyInfo encrInfo =
@ -347,7 +352,24 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
throw uke;
}
try {
try {
PBEParameterSpec pbeSpec;
int ic = 0;
if (algParams != null) {
try {
pbeSpec =
algParams.getParameterSpec(PBEParameterSpec.class);
} catch (InvalidParameterSpecException ipse) {
throw new IOException("Invalid PBE algorithm parameters");
}
ic = pbeSpec.getIterationCount();
if (ic > MAX_ITERATION_COUNT) {
throw new IOException("PBE iteration count too large");
}
}
byte[] keyInfo;
while (true) {
try {
@ -387,9 +409,10 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
key = kfac.generatePrivate(kspec);
if (debug != null) {
debug.println("Retrieved a protected private key (" +
key.getClass().getName() + ") at alias '" + alias +
"'");
debug.println("Retrieved a protected private key at alias" +
" '" + alias + "' (" +
new AlgorithmId(algOid).getName() +
" iterations: " + ic + ")");
}
// decode secret key
@ -410,9 +433,10 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
}
if (debug != null) {
debug.println("Retrieved a protected secret key (" +
key.getClass().getName() + ") at alias '" + alias +
"'");
debug.println("Retrieved a protected secret key at alias " +
"'" + alias + "' (" +
new AlgorithmId(algOid).getName() +
" iterations: " + ic + ")");
}
}
} catch (Exception e) {
@ -590,9 +614,9 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
(key.getFormat().equals("PKCS8"))) {
if (debug != null) {
debug.println("Setting a protected private key (" +
key.getClass().getName() + ") at alias '" + alias +
"'");
debug.println(
"Setting a protected private key at alias '" +
alias + "'");
}
// Encrypt the private key
@ -638,9 +662,8 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
encryptPrivateKey(pkcs8.toByteArray(), passwordProtection);
if (debug != null) {
debug.println("Setting a protected secret key (" +
key.getClass().getName() + ") at alias '" + alias +
"'");
debug.println("Setting a protected secret key at alias '" +
alias + "'");
}
secretKeyCount++;
entry = keyEntry;
@ -761,19 +784,19 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
/*
* Generate PBE Algorithm Parameters
*/
private AlgorithmParameters getAlgorithmParameters(String algorithm)
private AlgorithmParameters getPBEAlgorithmParameters(String algorithm)
throws IOException
{
AlgorithmParameters algParams = null;
// create PBE parameters from salt and iteration count
PBEParameterSpec paramSpec =
new PBEParameterSpec(getSalt(), iterationCount);
new PBEParameterSpec(getSalt(), PBE_ITERATION_COUNT);
try {
algParams = AlgorithmParameters.getInstance(algorithm);
algParams.init(paramSpec);
} catch (Exception e) {
throw new IOException("getAlgorithmParameters failed: " +
throw new IOException("getPBEAlgorithmParameters failed: " +
e.getMessage(), e);
}
return algParams;
@ -859,7 +882,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
algParams = AlgorithmParameters.getInstance(algorithm);
algParams.init(algParamSpec);
} else {
algParams = getAlgorithmParameters(algorithm);
algParams = getPBEAlgorithmParameters(algorithm);
}
} else {
// Check default key protection algorithm for PKCS12 keystores
@ -879,7 +902,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
if (algorithm == null || algorithm.isEmpty()) {
algorithm = "PBEWithSHA1AndDESede";
}
algParams = getAlgorithmParameters(algorithm);
algParams = getPBEAlgorithmParameters(algorithm);
}
ObjectIdentifier pbeOID = mapPBEAlgorithmToOID(algorithm);
@ -1194,7 +1217,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
if (debug != null) {
debug.println("Storing " + (privateKeyCount + secretKeyCount) +
" protected key(s) in a PKCS#7 data content-type");
" protected key(s) in a PKCS#7 data");
}
byte[] safeContentData = createSafeContent();
@ -1207,7 +1230,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
if (debug != null) {
debug.println("Storing " + certificateCount +
" certificate(s) in a PKCS#7 encryptedData content-type");
" certificate(s) in a PKCS#7 encryptedData");
}
byte[] encrData = createEncryptedData(password);
@ -1478,7 +1501,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
// generate MAC (MAC key is generated within JCE)
Mac m = Mac.getInstance("HmacPBESHA1");
PBEParameterSpec params =
new PBEParameterSpec(salt, iterationCount);
new PBEParameterSpec(salt, MAC_ITERATION_COUNT);
SecretKey key = getPBEKey(passwd);
m.init(key, params);
m.update(data);
@ -1486,7 +1509,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
// encode as MacData
MacData macData = new MacData(algName, macResult, salt,
iterationCount);
MAC_ITERATION_COUNT);
DerOutputStream bytes = new DerOutputStream();
bytes.write(macData.getEncoded());
mData = bytes.toByteArray();
@ -1878,7 +1901,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
// create AlgorithmParameters
AlgorithmParameters algParams =
getAlgorithmParameters("PBEWithSHA1AndRC2_40");
getPBEAlgorithmParameters("PBEWithSHA1AndRC2_40");
DerOutputStream bytes = new DerOutputStream();
AlgorithmId algId =
new AlgorithmId(pbeWithSHAAnd40BitRC2CBC_OID, algParams);
@ -1998,7 +2021,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
if (contentType.equals(ContentInfo.DATA_OID)) {
if (debug != null) {
debug.println("Loading PKCS#7 data content-type");
debug.println("Loading PKCS#7 data");
}
safeContentsData = safeContents.getData();
@ -2007,15 +2030,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
if (debug != null) {
debug.println("Warning: skipping PKCS#7 encryptedData" +
" content-type - no password was supplied");
" - no password was supplied");
}
continue;
}
if (debug != null) {
debug.println("Loading PKCS#7 encryptedData content-type");
}
DerInputStream edi =
safeContents.getContent().toDerInputStream();
int edVersion = edi.getInteger();
@ -2036,6 +2055,30 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
ObjectIdentifier algOid = in.getOID();
AlgorithmParameters algParams = parseAlgParameters(algOid, in);
PBEParameterSpec pbeSpec;
int ic = 0;
if (algParams != null) {
try {
pbeSpec =
algParams.getParameterSpec(PBEParameterSpec.class);
} catch (InvalidParameterSpecException ipse) {
throw new IOException(
"Invalid PBE algorithm parameters");
}
ic = pbeSpec.getIterationCount();
if (ic > MAX_ITERATION_COUNT) {
throw new IOException("PBE iteration count too large");
}
}
if (debug != null) {
debug.println("Loading PKCS#7 encryptedData " +
"(" + new AlgorithmId(algOid).getName() +
" iterations: " + ic + ")");
}
while (true) {
try {
// Use JCE
@ -2066,8 +2109,15 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
// The MacData is optional.
if (password != null && s.available() > 0) {
MacData macData = new MacData(s);
try {
MacData macData = new MacData(s);
int ic = macData.getIterations();
try {
if (ic > MAX_ITERATION_COUNT) {
throw new InvalidAlgorithmParameterException(
"MAC iteration count too large: " + ic);
}
String algName =
macData.getDigestAlgName().toUpperCase(Locale.ENGLISH);
@ -2077,8 +2127,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
// generate MAC (MAC key is created within JCE)
Mac m = Mac.getInstance("HmacPBE" + algName);
PBEParameterSpec params =
new PBEParameterSpec(macData.getSalt(),
macData.getIterations());
new PBEParameterSpec(macData.getSalt(), ic);
SecretKey key = getPBEKey(password);
m.init(key, params);
m.update(authSafeData);
@ -2086,16 +2135,16 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
if (debug != null) {
debug.println("Checking keystore integrity " +
"(MAC algorithm: " + m.getAlgorithm() + ")");
"(" + m.getAlgorithm() + " iterations: " + ic + ")");
}
if (!MessageDigest.isEqual(macData.getDigest(), macResult)) {
throw new UnrecoverableKeyException("Failed PKCS12" +
" integrity checking");
}
} catch (Exception e) {
} catch (Exception e) {
throw new IOException("Integrity check failed: " + e, e);
}
}
}
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -35,6 +35,8 @@ import java.security.spec.InvalidParameterSpecException;
import java.security.spec.DSAParameterSpec;
import sun.security.jca.JCAUtil;
import static sun.security.util.SecurityProviderConstants.DEF_DSA_KEY_SIZE;
import static sun.security.util.SecurityProviderConstants.getDefDSASubprimeSize;
/**
* This class generates DSA key parameters and public/private key
@ -45,15 +47,14 @@ import sun.security.jca.JCAUtil;
* @author Andreas Sterbenz
*
*/
public class DSAKeyPairGenerator extends KeyPairGenerator
implements java.security.interfaces.DSAKeyPairGenerator {
class DSAKeyPairGenerator extends KeyPairGenerator {
/* Length for prime P and subPrime Q in bits */
private int plen;
private int qlen;
/* whether to force new parameters to be generated for each KeyPair */
private boolean forceNewParameters;
boolean forceNewParameters;
/* preset algorithm parameters. */
private DSAParameterSpec params;
@ -61,9 +62,9 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
/* The source of random bits to use */
private SecureRandom random;
public DSAKeyPairGenerator() {
DSAKeyPairGenerator(int defaultKeySize) {
super("DSA");
initialize(1024, null);
initialize(defaultKeySize, null);
}
private static void checkStrength(int sizeP, int sizeQ) {
@ -84,61 +85,7 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
}
public void initialize(int modlen, SecureRandom random) {
// generate new parameters when no precomputed ones available.
initialize(modlen, true, random);
this.forceNewParameters = false;
}
/**
* Initializes the DSA key pair generator. If <code>genParams</code>
* is false, a set of pre-computed parameters is used.
*/
@Override
public void initialize(int modlen, boolean genParams, SecureRandom random)
throws InvalidParameterException {
int subPrimeLen = -1;
if (modlen <= 1024) {
subPrimeLen = 160;
} else if (modlen == 2048) {
subPrimeLen = 224;
} else if (modlen == 3072) {
subPrimeLen = 256;
}
checkStrength(modlen, subPrimeLen);
if (genParams) {
params = null;
} else {
params = ParameterCache.getCachedDSAParameterSpec(modlen,
subPrimeLen);
if (params == null) {
throw new InvalidParameterException
("No precomputed parameters for requested modulus size "
+ "available");
}
}
this.plen = modlen;
this.qlen = subPrimeLen;
this.random = random;
this.forceNewParameters = genParams;
}
/**
* Initializes the DSA object using a DSA parameter object.
*
* @param params a fully initialized DSA parameter object.
*/
@Override
public void initialize(DSAParams params, SecureRandom random)
throws InvalidParameterException {
if (params == null) {
throw new InvalidParameterException("Params must not be null");
}
DSAParameterSpec spec = new DSAParameterSpec
(params.getP(), params.getQ(), params.getG());
initialize0(spec, random);
init(modlen, random, false);
}
/**
@ -157,10 +104,21 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
throw new InvalidAlgorithmParameterException
("Inappropriate parameter");
}
initialize0((DSAParameterSpec)params, random);
init((DSAParameterSpec)params, random, false);
}
private void initialize0(DSAParameterSpec params, SecureRandom random) {
void init(int modlen, SecureRandom random, boolean forceNew) {
int subPrimeLen = getDefDSASubprimeSize(modlen);
checkStrength(modlen, subPrimeLen);
this.plen = modlen;
this.qlen = subPrimeLen;
this.params = null;
this.random = random;
this.forceNewParameters = forceNew;
}
void init(DSAParameterSpec params, SecureRandom random,
boolean forceNew) {
int sizeP = params.getP().bitLength();
int sizeQ = params.getQ().bitLength();
checkStrength(sizeP, sizeQ);
@ -168,7 +126,7 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
this.qlen = sizeQ;
this.params = params;
this.random = random;
this.forceNewParameters = false;
this.forceNewParameters = forceNew;
}
/**
@ -197,7 +155,7 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
return generateKeyPair(spec.getP(), spec.getQ(), spec.getG(), random);
}
public KeyPair generateKeyPair(BigInteger p, BigInteger q, BigInteger g,
private KeyPair generateKeyPair(BigInteger p, BigInteger q, BigInteger g,
SecureRandom random) {
BigInteger x = generateX(random, q);
@ -252,4 +210,55 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
return y;
}
public static final class Current extends DSAKeyPairGenerator {
public Current() {
super(DEF_DSA_KEY_SIZE);
}
}
public static final class Legacy extends DSAKeyPairGenerator
implements java.security.interfaces.DSAKeyPairGenerator {
public Legacy() {
super(1024);
}
/**
* Initializes the DSA key pair generator. If <code>genParams</code>
* is false, a set of pre-computed parameters is used.
*/
@Override
public void initialize(int modlen, boolean genParams,
SecureRandom random) throws InvalidParameterException {
if (genParams) {
super.init(modlen, random, true);
} else {
DSAParameterSpec cachedParams =
ParameterCache.getCachedDSAParameterSpec(modlen,
getDefDSASubprimeSize(modlen));
if (cachedParams == null) {
throw new InvalidParameterException
("No precomputed parameters for requested modulus" +
" size available");
}
super.init(cachedParams, random, false);
}
}
/**
* Initializes the DSA object using a DSA parameter object.
*
* @param params a fully initialized DSA parameter object.
*/
@Override
public void initialize(DSAParams params, SecureRandom random)
throws InvalidParameterException {
if (params == null) {
throw new InvalidParameterException("Params must not be null");
}
DSAParameterSpec spec = new DSAParameterSpec
(params.getP(), params.getQ(), params.getG());
super.init(spec, random, false);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -34,15 +34,18 @@ import java.security.NoSuchProviderException;
import java.security.InvalidParameterException;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.security.ProviderException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.DSAParameterSpec;
import java.security.spec.DSAGenParameterSpec;
import static sun.security.util.SecurityProviderConstants.DEF_DSA_KEY_SIZE;
import static sun.security.util.SecurityProviderConstants.getDefDSASubprimeSize;
/**
* This class generates parameters for the DSA algorithm. It uses a default
* prime modulus size of 1024 bits, which can be overwritten during
* initialization.
* This class generates parameters for the DSA algorithm.
*
* @author Jan Luehe
*
@ -56,10 +59,6 @@ import java.security.spec.DSAGenParameterSpec;
public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
// the default parameters
private static final DSAGenParameterSpec DEFAULTS =
new DSAGenParameterSpec(1024, 160, 160);
// the length of prime P, subPrime Q, and seed in bits
private int valueL = -1;
private int valueN = -1;
@ -80,18 +79,14 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
*/
@Override
protected void engineInit(int strength, SecureRandom random) {
if ((strength >= 512) && (strength <= 1024) && (strength % 64 == 0)) {
this.valueN = 160;
} else if (strength == 2048) {
this.valueN = 224;
} else if (strength == 3072) {
this.valueN = 256;
} else {
if ((strength != 2048) && (strength != 3072) &&
((strength < 512) || (strength > 1024) || (strength % 64 != 0))) {
throw new InvalidParameterException(
"Unexpected strength (size of prime): " + strength + ". " +
"Prime size should be 512 - 1024, or 2048, 3072");
"Unexpected strength (size of prime): " + strength +
". Prime size should be 512-1024, 2048, or 3072");
}
this.valueL = strength;
this.valueN = getDefDSASubprimeSize(strength);
this.seedLen = valueN;
this.random = random;
}
@ -110,7 +105,6 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
@Override
protected void engineInit(AlgorithmParameterSpec genParamSpec,
SecureRandom random) throws InvalidAlgorithmParameterException {
if (!(genParamSpec instanceof DSAGenParameterSpec)) {
throw new InvalidAlgorithmParameterException("Invalid parameter");
}
@ -136,11 +130,7 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
this.random = new SecureRandom();
}
if (valueL == -1) {
try {
engineInit(DEFAULTS, this.random);
} catch (InvalidAlgorithmParameterException iape) {
// should never happen
}
engineInit(DEF_DSA_KEY_SIZE, this.random);
}
BigInteger[] pAndQ = generatePandQ(this.random, valueL,
valueN, seedLen);
@ -206,13 +196,17 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
int b = (valueL - 1) % outLen;
byte[] seedBytes = new byte[seedLen/8];
BigInteger twoSl = BigInteger.TWO.pow(seedLen);
int primeCertainty = 80; // for 1024-bit prime P
if (valueL == 2048) {
int primeCertainty = -1;
if (valueL <= 1024) {
primeCertainty = 80;
} else if (valueL == 2048) {
primeCertainty = 112;
} else if (valueL == 3072) {
primeCertainty = 128;
}
if (primeCertainty < 0) {
throw new ProviderException("Invalid valueL: " + valueL);
}
BigInteger resultP, resultQ, seed = null;
int counter;
while (true) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,7 @@ import java.io.*;
import java.net.*;
import java.util.Map;
import java.security.*;
import sun.security.action.GetPropertyAction;
/**
* Defines the entries of the SUN provider.
@ -74,6 +75,10 @@ import java.security.*;
final class SunEntries {
private static final boolean useLegacyDSA =
Boolean.parseBoolean(GetPropertyAction.privilegedGetProperty
("jdk.security.legacyDSAKeyPairGenerator"));
private SunEntries() {
// empty
}
@ -174,8 +179,9 @@ final class SunEntries {
/*
* Key Pair Generator engines
*/
map.put("KeyPairGenerator.DSA",
"sun.security.provider.DSAKeyPairGenerator");
String dsaKPGImplClass = "sun.security.provider.DSAKeyPairGenerator$";
dsaKPGImplClass += (useLegacyDSA? "Legacy" : "Current");
map.put("KeyPairGenerator.DSA", dsaKPGImplClass);
map.put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -32,6 +32,7 @@ import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
import sun.security.jca.JCAUtil;
import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
/**
* RSA keypair generation. Standard algorithm, minimum key length 512 bit.
@ -55,7 +56,7 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
public RSAKeyPairGenerator() {
// initialize to default in case the app does not call initialize()
initialize(2048, null);
initialize(DEF_RSA_KEY_SIZE, null);
}
// initialize the generator. See JCA doc

View File

@ -26,6 +26,8 @@
package sun.security.tools.keytool;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.CodeSigner;
import java.security.CryptoPrimitive;
import java.security.KeyStore;
@ -72,6 +74,7 @@ import sun.security.pkcs10.PKCS10Attribute;
import sun.security.provider.X509Factory;
import sun.security.provider.certpath.ssl.SSLServerCertStore;
import sun.security.util.Password;
import sun.security.util.SecurityProviderConstants;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
@ -168,7 +171,12 @@ public final class Main {
private List<String> ids = new ArrayList<>(); // used in GENCRL
private List<String> v3ext = new ArrayList<>();
// Warnings on weak algorithms
// In-place importkeystore is special.
// A backup is needed, and no need to prompt for deststorepass.
private boolean inplaceImport = false;
private String inplaceBackupName = null;
// Warnings on weak algorithms etc
private List<String> weakWarnings = new ArrayList<>();
private static final DisabledAlgorithmConstraints DISABLED_CHECK =
@ -846,37 +854,52 @@ public final class Main {
("New.password.must.be.at.least.6.characters"));
}
// Set this before inplaceImport check so we can compare name.
if (ksfname == null) {
ksfname = System.getProperty("user.home") + File.separator
+ ".keystore";
}
KeyStore srcKeyStore = null;
if (command == IMPORTKEYSTORE) {
inplaceImport = inplaceImportCheck();
if (inplaceImport) {
// We load srckeystore first so we have srcstorePass that
// can be assigned to storePass
srcKeyStore = loadSourceKeyStore();
if (storePass == null) {
storePass = srcstorePass;
}
}
}
// Check if keystore exists.
// If no keystore has been specified at the command line, try to use
// the default, which is located in $HOME/.keystore.
// If the command is "genkey", "identitydb", "import", or "printcert",
// it is OK not to have a keystore.
if (isKeyStoreRelated(command)) {
if (ksfname == null) {
ksfname = System.getProperty("user.home") + File.separator
+ ".keystore";
}
if (!nullStream) {
try {
ksfile = new File(ksfname);
// Check if keystore file is empty
if (ksfile.exists() && ksfile.length() == 0) {
throw new Exception(rb.getString
("Keystore.file.exists.but.is.empty.") + ksfname);
}
ksStream = new FileInputStream(ksfile);
} catch (FileNotFoundException e) {
if (command != GENKEYPAIR &&
// DO NOT open the existing keystore if this is an in-place import.
// The keystore should be created as brand new.
if (isKeyStoreRelated(command) && !nullStream && !inplaceImport) {
try {
ksfile = new File(ksfname);
// Check if keystore file is empty
if (ksfile.exists() && ksfile.length() == 0) {
throw new Exception(rb.getString
("Keystore.file.exists.but.is.empty.") + ksfname);
}
ksStream = new FileInputStream(ksfile);
} catch (FileNotFoundException e) {
if (command != GENKEYPAIR &&
command != GENSECKEY &&
command != IDENTITYDB &&
command != IMPORTCERT &&
command != IMPORTPASS &&
command != IMPORTKEYSTORE &&
command != PRINTCRL) {
throw new Exception(rb.getString
("Keystore.file.does.not.exist.") + ksfname);
}
throw new Exception(rb.getString
("Keystore.file.does.not.exist.") + ksfname);
}
}
}
@ -900,7 +923,7 @@ public final class Main {
// Create new keystore
// Probe for keystore type when filename is available
if (ksfile != null && ksStream != null && providerName == null &&
hasStoretypeOption == false) {
hasStoretypeOption == false && !inplaceImport) {
keyStore = KeyStore.getInstance(ksfile, storePass);
} else {
if (providerName == null) {
@ -930,7 +953,11 @@ public final class Main {
* Null stream keystores are loaded later.
*/
if (!nullStream) {
keyStore.load(ksStream, storePass);
if (inplaceImport) {
keyStore.load(null, storePass);
} else {
keyStore.load(ksStream, storePass);
}
if (ksStream != null) {
ksStream.close();
}
@ -1167,7 +1194,11 @@ public final class Main {
}
}
} else if (command == IMPORTKEYSTORE) {
doImportKeyStore();
// When not in-place import, srcKeyStore is not loaded yet.
if (srcKeyStore == null) {
srcKeyStore = loadSourceKeyStore();
}
doImportKeyStore(srcKeyStore);
kssave = true;
} else if (command == KEYCLONE) {
keyPassNew = newPass;
@ -1298,6 +1329,51 @@ public final class Main {
}
}
}
if (isKeyStoreRelated(command)
&& !token && !nullStream && ksfname != null) {
// JKS storetype warning on the final result keystore
File f = new File(ksfname);
char[] pass = (storePassNew!=null) ? storePassNew : storePass;
if (f.exists()) {
// Probe for real type. A JKS can be loaded as PKCS12 because
// DualFormat support, vice versa.
keyStore = KeyStore.getInstance(f, pass);
String realType = keyStore.getType();
if (realType.equalsIgnoreCase("JKS")
|| realType.equalsIgnoreCase("JCEKS")) {
boolean allCerts = true;
for (String a : Collections.list(keyStore.aliases())) {
if (!keyStore.entryInstanceOf(
a, TrustedCertificateEntry.class)) {
allCerts = false;
break;
}
}
// Don't warn for "cacerts" style keystore.
if (!allCerts) {
weakWarnings.add(String.format(
rb.getString("jks.storetype.warning"),
realType, ksfname));
}
}
if (inplaceImport) {
String realSourceStoreType = KeyStore.getInstance(
new File(inplaceBackupName), srcstorePass).getType();
String format =
realType.equalsIgnoreCase(realSourceStoreType) ?
rb.getString("backup.keystore.warning") :
rb.getString("migrate.keystore.warning");
weakWarnings.add(
String.format(format,
srcksfname,
realSourceStoreType,
inplaceBackupName,
realType));
}
}
}
}
/**
@ -1742,9 +1818,12 @@ public final class Main {
{
if (keysize == -1) {
if ("EC".equalsIgnoreCase(keyAlgName)) {
keysize = 256;
} else {
keysize = 2048; // RSA and DSA
keysize = SecurityProviderConstants.DEF_EC_KEY_SIZE;
} else if ("RSA".equalsIgnoreCase(keyAlgName)) {
keysize = SecurityProviderConstants.DEF_RSA_KEY_SIZE;
} else if ("DSA".equalsIgnoreCase(keyAlgName)) {
// hardcode for now as DEF_DSA_KEY_SIZE is still 1024
keysize = 2048; // SecurityProviderConstants.DEF_DSA_KEY_SIZE;
}
}
@ -1989,12 +2068,40 @@ public final class Main {
}
}
boolean inplaceImportCheck() throws Exception {
if (P11KEYSTORE.equalsIgnoreCase(srcstoretype) ||
KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
return false;
}
if (srcksfname != null) {
File srcksfile = new File(srcksfname);
if (srcksfile.exists() && srcksfile.length() == 0) {
throw new Exception(rb.getString
("Source.keystore.file.exists.but.is.empty.") +
srcksfname);
}
if (srcksfile.getCanonicalFile()
.equals(new File(ksfname).getCanonicalFile())) {
return true;
} else {
// Informational, especially if destkeystore is not
// provided, which default to ~/.keystore.
System.err.println(String.format(rb.getString(
"importing.keystore.status"), srcksfname, ksfname));
return false;
}
} else {
throw new Exception(rb.getString
("Please.specify.srckeystore"));
}
}
/**
* Load the srckeystore from a stream, used in -importkeystore
* @return the src KeyStore
*/
KeyStore loadSourceKeyStore() throws Exception {
boolean isPkcs11 = false;
InputStream is = null;
File srcksfile = null;
@ -2007,20 +2114,9 @@ public final class Main {
System.err.println();
tinyHelp();
}
isPkcs11 = true;
} else {
if (srcksfname != null) {
srcksfile = new File(srcksfname);
if (srcksfile.exists() && srcksfile.length() == 0) {
throw new Exception(rb.getString
("Source.keystore.file.exists.but.is.empty.") +
srcksfname);
}
is = new FileInputStream(srcksfile);
} else {
throw new Exception(rb.getString
("Please.specify.srckeystore"));
}
srcksfile = new File(srcksfname);
is = new FileInputStream(srcksfile);
}
KeyStore store;
@ -2087,17 +2183,32 @@ public final class Main {
* keep alias unchanged if no name conflict, otherwise, prompt.
* keep keypass unchanged for keys
*/
private void doImportKeyStore() throws Exception {
private void doImportKeyStore(KeyStore srcKS) throws Exception {
if (alias != null) {
doImportKeyStoreSingle(loadSourceKeyStore(), alias);
doImportKeyStoreSingle(srcKS, alias);
} else {
if (dest != null || srckeyPass != null) {
throw new Exception(rb.getString(
"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified"));
}
doImportKeyStoreAll(loadSourceKeyStore());
doImportKeyStoreAll(srcKS);
}
if (inplaceImport) {
// Backup to file.old or file.old2...
// The keystore is not rewritten yet now.
for (int n = 1; /* forever */; n++) {
inplaceBackupName = srcksfname + ".old" + (n == 1 ? "" : n);
File bkFile = new File(inplaceBackupName);
if (!bkFile.exists()) {
Files.copy(Paths.get(srcksfname), bkFile.toPath());
break;
}
}
}
/*
* Information display rule of -importkeystore
* 1. inside single, shows failure

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -471,6 +471,10 @@ public class Resources extends java.util.ListResourceBundle {
{"verified.by.s.in.s.weak", "Verified by %s in %s with a %s"},
{"whose.sigalg.risk", "%s uses the %s signature algorithm which is considered a security risk."},
{"whose.key.risk", "%s uses a %s which is considered a security risk."},
{"jks.storetype.warning", "The %1$s keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using \"keytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12\"."},
{"migrate.keystore.warning", "Migrated \"%1$s\" to %4$s. The %2$s keystore is backed up as \"%3$s\"."},
{"backup.keystore.warning", "The original keystore \"%1$s\" is backed up as \"%3$s\"..."},
{"importing.keystore.status", "Importing keystore %1$s to %2$s..."},
};

View File

@ -37,7 +37,7 @@ import java.util.Arrays;
public class IOUtils {
/**
* Read up to <code>length</code> of bytes from <code>in</code>
* Read up to {@code length} of bytes from {@code in}
* until EOF is detected.
* @param is input stream, must not be null
* @param length number of bytes to read
@ -78,4 +78,22 @@ public class IOUtils {
}
return output;
}
/**
* Read {@code length} of bytes from {@code in}. An exception is
* thrown if there are not enough bytes in the stream.
*
* @param is input stream, must not be null
* @param length number of bytes to read, must not be negative
* @return bytes read
* @throws IOException if any IO error or a premature EOF is detected, or
* if {@code length} is negative since this length is usually also
* read from {@code is}.
*/
public static byte[] readNBytes(InputStream is, int length) throws IOException {
if (length < 0) {
throw new IOException("length cannot be negative: " + length);
}
return readFully(is, length, true);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -111,7 +111,11 @@ class ObjectIdentifier implements Serializable
is.defaultReadObject();
if (encoding == null) { // from an old version
init((int[])components, componentLen);
int[] comp = (int[])components;
if (componentLen > comp.length) {
componentLen = comp.length;
}
init(comp, componentLen);
}
}

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.util.regex.PatternSyntaxException;
import java.security.InvalidParameterException;
import sun.security.action.GetPropertyAction;
/**
* Various constants such as version number, default key length, used by
* the JDK security/crypto providers.
*/
public final class SecurityProviderConstants {
private static final Debug debug =
Debug.getInstance("jca", "ProviderConfig");
// Cannot create one of these
private SecurityProviderConstants () {
}
public static final int getDefDSASubprimeSize(int primeSize) {
if (primeSize <= 1024) {
return 160;
} else if (primeSize == 2048) {
return 224;
} else if (primeSize == 3072) {
return 256;
} else {
throw new InvalidParameterException("Invalid DSA Prime Size: " +
primeSize);
}
}
public static final int DEF_DSA_KEY_SIZE;
public static final int DEF_RSA_KEY_SIZE;
public static final int DEF_DH_KEY_SIZE;
public static final int DEF_EC_KEY_SIZE;
private static final String KEY_LENGTH_PROP =
"jdk.security.defaultKeySize";
static {
String keyLengthStr = GetPropertyAction.privilegedGetProperty
(KEY_LENGTH_PROP);
int dsaKeySize = 1024;
int rsaKeySize = 2048;
int dhKeySize = 2048;
int ecKeySize = 256;
if (keyLengthStr != null) {
try {
String[] pairs = keyLengthStr.split(",");
for (String p : pairs) {
String[] algoAndValue = p.split(":");
if (algoAndValue.length != 2) {
// invalid pair, skip to next pair
if (debug != null) {
debug.println("Ignoring invalid pair in " +
KEY_LENGTH_PROP + " property: " + p);
}
continue;
}
String algoName = algoAndValue[0].trim().toUpperCase();
int value = -1;
try {
value = Integer.parseInt(algoAndValue[1].trim());
} catch (NumberFormatException nfe) {
// invalid value, skip to next pair
if (debug != null) {
debug.println("Ignoring invalid value in " +
KEY_LENGTH_PROP + " property: " + p);
}
continue;
}
if (algoName.equals("DSA")) {
dsaKeySize = value;
} else if (algoName.equals("RSA")) {
rsaKeySize = value;
} else if (algoName.equals("DH")) {
dhKeySize = value;
} else if (algoName.equals("EC")) {
ecKeySize = value;
} else {
if (debug != null) {
debug.println("Ignoring unsupported algo in " +
KEY_LENGTH_PROP + " property: " + p);
}
continue;
}
if (debug != null) {
debug.println("Overriding default " + algoName +
" keysize with value from " +
KEY_LENGTH_PROP + " property: " + value);
}
}
} catch (PatternSyntaxException pse) {
// if property syntax is not followed correctly
if (debug != null) {
debug.println("Unexpected exception while parsing " +
KEY_LENGTH_PROP + " property: " + pse);
}
}
}
DEF_DSA_KEY_SIZE = dsaKeySize;
DEF_RSA_KEY_SIZE = rsaKeySize;
DEF_DH_KEY_SIZE = dhKeySize;
DEF_EC_KEY_SIZE = ecKeySize;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,7 @@ import java.util.*;
import javax.security.auth.x500.X500Principal;
import sun.net.util.IPAddressUtil;
import sun.security.util.*;
import sun.security.pkcs.PKCS9Attribute;
@ -440,6 +441,7 @@ implements CertAttrSet<String>, Cloneable {
X500Principal subjectPrincipal = cert.getSubjectX500Principal();
X500Name subject = X500Name.asX500Name(subjectPrincipal);
// Check subject as an X500Name
if (subject.isEmpty() == false) {
if (verify(subject) == false) {
return false;
@ -465,12 +467,51 @@ implements CertAttrSet<String>, Cloneable {
"certificate: " + ce.getMessage());
}
// If there are no subjectAlternativeNames, perform the special-case
// check where if the subjectName contains any EMAILADDRESS
// attributes, they must be checked against RFC822 constraints.
// If that passes, we're fine.
if (altNames == null) {
return verifyRFC822SpecialCase(subject);
altNames = new GeneralNames();
// RFC 5280 4.2.1.10:
// When constraints are imposed on the rfc822Name name form,
// but the certificate does not include a subject alternative name,
// the rfc822Name constraint MUST be applied to the attribute of
// type emailAddress in the subject distinguished name.
for (AVA ava : subject.allAvas()) {
ObjectIdentifier attrOID = ava.getObjectIdentifier();
if (attrOID.equals(PKCS9Attribute.EMAIL_ADDRESS_OID)) {
String attrValue = ava.getValueString();
if (attrValue != null) {
try {
altNames.add(new GeneralName(
new RFC822Name(attrValue)));
} catch (IOException ioe) {
continue;
}
}
}
}
}
// If there is no IPAddressName or DNSName in subjectAlternativeNames,
// see if the last CN inside subjectName can be used instead.
DerValue derValue = subject.findMostSpecificAttribute
(X500Name.commonName_oid);
String cn = derValue == null ? null : derValue.getAsString();
if (cn != null) {
try {
if (IPAddressUtil.isIPv4LiteralAddress(cn) ||
IPAddressUtil.isIPv6LiteralAddress(cn)) {
if (!hasNameType(altNames, GeneralNameInterface.NAME_IP)) {
altNames.add(new GeneralName(new IPAddressName(cn)));
}
} else {
if (!hasNameType(altNames, GeneralNameInterface.NAME_DNS)) {
altNames.add(new GeneralName(new DNSName(cn)));
}
}
} catch (IOException ioe) {
// OK, cn is neither IP nor DNS
}
}
// verify each subjectAltName
@ -485,6 +526,15 @@ implements CertAttrSet<String>, Cloneable {
return true;
}
private static boolean hasNameType(GeneralNames names, int type) {
for (GeneralName name : names.names()) {
if (name.getType() == type) {
return true;
}
}
return false;
}
/**
* check whether a name conforms to these NameConstraints.
* This involves verifying that the name is consistent with the
@ -566,37 +616,6 @@ implements CertAttrSet<String>, Cloneable {
return true;
}
/**
* Perform the RFC 822 special case check. We have a certificate
* that does not contain any subject alternative names. Check that
* any EMAILADDRESS attributes in its subject name conform to these
* NameConstraints.
*
* @param subject the certificate's subject name
* @return true if certificate verifies successfully
* @throws IOException on error
*/
public boolean verifyRFC822SpecialCase(X500Name subject) throws IOException {
for (AVA ava : subject.allAvas()) {
ObjectIdentifier attrOID = ava.getObjectIdentifier();
if (attrOID.equals(PKCS9Attribute.EMAIL_ADDRESS_OID)) {
String attrValue = ava.getValueString();
if (attrValue != null) {
RFC822Name emailName;
try {
emailName = new RFC822Name(attrValue);
} catch (IOException ioe) {
continue;
}
if (!verify(emailName)) {
return(false);
}
}
}
}
return true;
}
/**
* Clone all objects that may be modified during certificate validation.
*/

View File

@ -38,7 +38,10 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.DigestOutputStream;
import java.security.AccessController;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.lang.reflect.Modifier;
import java.lang.reflect.Field;
@ -57,6 +60,8 @@ import java.io.Serializable;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import com.sun.corba.se.impl.util.RepositoryId;
@ -443,6 +448,65 @@ public class ObjectStreamClass implements java.io.Serializable {
private static final PersistentFieldsValue persistentFieldsValue =
new PersistentFieldsValue();
/**
* Creates a PermissionDomain that grants no permission.
*/
private ProtectionDomain noPermissionsDomain() {
PermissionCollection perms = new Permissions();
perms.setReadOnly();
return new ProtectionDomain(null, perms);
}
/**
* Aggregate the ProtectionDomains of all the classes that separate
* a concrete class {@code cl} from its ancestor's class declaring
* a constructor {@code cons}.
*
* If {@code cl} is defined by the boot loader, or the constructor
* {@code cons} is declared by {@code cl}, or if there is no security
* manager, then this method does nothing and {@code null} is returned.
*
* @param cons A constructor declared by {@code cl} or one of its
* ancestors.
* @param cl A concrete class, which is either the class declaring
* the constructor {@code cons}, or a serializable subclass
* of that class.
* @return An array of ProtectionDomain representing the set of
* ProtectionDomain that separate the concrete class {@code cl}
* from its ancestor's declaring {@code cons}, or {@code null}.
*/
private ProtectionDomain[] getProtectionDomains(Constructor<?> cons,
Class<?> cl) {
ProtectionDomain[] domains = null;
if (cons != null && cl.getClassLoader() != null
&& System.getSecurityManager() != null) {
Class<?> cls = cl;
Class<?> fnscl = cons.getDeclaringClass();
Set<ProtectionDomain> pds = null;
while (cls != fnscl) {
ProtectionDomain pd = cls.getProtectionDomain();
if (pd != null) {
if (pds == null) pds = new HashSet<>();
pds.add(pd);
}
cls = cls.getSuperclass();
if (cls == null) {
// that's not supposed to happen
// make a ProtectionDomain with no permission.
// should we throw instead?
if (pds == null) pds = new HashSet<>();
else pds.clear();
pds.add(noPermissionsDomain());
break;
}
}
if (pds != null) {
domains = pds.toArray(new ProtectionDomain[0]);
}
}
return domains;
}
/*
* Initialize class descriptor. This method is only invoked on class
* descriptors created via calls to lookupInternal(). This method is kept
@ -568,11 +632,15 @@ public class ObjectStreamClass implements java.io.Serializable {
readResolveObjectMethod = bridge.readResolveForSerialization(cl);
domains = new ProtectionDomain[] {noPermissionsDomain()};
if (externalizable)
cons = getExternalizableConstructor(cl) ;
else
cons = getSerializableConstructor(cl) ;
domains = getProtectionDomains(cons, cl);
if (serializable && !forProxyClass) {
writeObjectMethod = bridge.writeObjectForSerialization(cl) ;
readObjectMethod = bridge.readObjectForSerialization(cl);
@ -910,7 +978,7 @@ public class ObjectStreamClass implements java.io.Serializable {
{
if (cons != null) {
try {
return cons.newInstance();
return bridge.newInstanceForSerialization(cons, domains);
} catch (IllegalAccessException ex) {
// should not occur, as access checks have been suppressed
InternalError ie = new InternalError();
@ -1506,6 +1574,7 @@ public class ObjectStreamClass implements java.io.Serializable {
private transient MethodHandle writeReplaceObjectMethod;
private transient MethodHandle readResolveObjectMethod;
private transient Constructor<?> cons;
private transient ProtectionDomain[] domains;
/**
* Beginning in Java to IDL ptc/02-01-12, RMI-IIOP has a

View File

@ -27,8 +27,9 @@ package sun.corba ;
import java.io.OptionalDataException;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Field ;
import java.lang.reflect.Constructor ;
import java.lang.reflect.Field;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.StackWalker;
import java.lang.StackWalker.StackFrame;
import java.util.Optional;
@ -37,6 +38,7 @@ import java.util.stream.Stream;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import sun.misc.Unsafe;
import sun.reflect.ReflectionFactory;
@ -340,6 +342,36 @@ public final class Bridge
return reflectionFactory.newConstructorForExternalization( cl ) ;
}
/**
* Invokes the supplied constructor, adding the provided protection domains
* to the invocation stack before invoking {@code Constructor::newInstance}.
*
* This is equivalent to calling
* {@code ReflectionFactory.newInstanceForSerialization(cons,domains)}.
*
* @param cons A constructor obtained from {@code
* newConstructorForSerialization} or {@code
* newConstructorForExternalization}.
*
* @param domains An array of protection domains that limit the privileges
* with which the constructor is invoked. Can be {@code null}
* or empty, in which case privileges are only limited by the
* {@linkplain AccessController#getContext() current context}.
*
* @return A new object built from the provided constructor.
*
* @throws NullPointerException if {@code cons} is {@code null}.
* @throws InstantiationException if thrown by {@code cons.newInstance()}.
* @throws InvocationTargetException if thrown by {@code cons.newInstance()}.
* @throws IllegalAccessException if thrown by {@code cons.newInstance()}.
*/
public final Object newInstanceForSerialization(Constructor<?> cons,
ProtectionDomain[] domains)
throws InstantiationException, InvocationTargetException, IllegalAccessException
{
return reflectionFactory.newInstanceForSerialization(cons, domains);
}
/**
* Returns true if the given class defines a static initializer method,
* false otherwise.

View File

@ -900,7 +900,7 @@ void InSymbol(cmsIT8* it8)
k = 0;
NextCh(it8);
while (k < MAXSTR && it8->ch != sng) {
while (k < (MAXSTR-1) && it8->ch != sng) {
if (it8->ch == '\n'|| it8->ch == '\r') k = MAXSTR+1;
else {
@ -2053,14 +2053,18 @@ cmsBool HeaderSection(cmsIT8* it8)
static
void ReadType(cmsIT8* it8, char* SheetTypePtr)
{
cmsInt32Number cnt = 0;
// First line is a very special case.
while (isseparator(it8->ch))
NextCh(it8);
while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != -1) {
while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != 0) {
*SheetTypePtr++= (char) it8 ->ch;
if (cnt++ < MAXSTR)
*SheetTypePtr++= (char) it8 ->ch;
NextCh(it8);
}
@ -2253,7 +2257,7 @@ void CookPointers(cmsIT8* it8)
// that should be something like some printable characters plus a \n
// returns 0 if this is not like a CGATS, or an integer otherwise. This integer is the number of words in first line?
static
int IsMyBlock(cmsUInt8Number* Buffer, int n)
int IsMyBlock(const cmsUInt8Number* Buffer, int n)
{
int words = 1, space = 0, quot = 0;
int i;
@ -2317,7 +2321,7 @@ cmsBool IsMyFile(const char* FileName)
// ---------------------------------------------------------- Exported routines
cmsHANDLE CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, void *Ptr, cmsUInt32Number len)
cmsHANDLE CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cmsUInt32Number len)
{
cmsHANDLE hIT8;
cmsIT8* it8;
@ -2326,7 +2330,7 @@ cmsHANDLE CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, void *Ptr, cmsUInt3
_cmsAssert(Ptr != NULL);
_cmsAssert(len != 0);
type = IsMyBlock((cmsUInt8Number*)Ptr, len);
type = IsMyBlock((const cmsUInt8Number*)Ptr, len);
if (type == 0) return NULL;
hIT8 = cmsIT8Alloc(ContextID);

View File

@ -546,7 +546,11 @@ cmsBool GrowNamedColorList(cmsNAMEDCOLORLIST* v)
size = v ->Allocated * 2;
// Keep a maximum color lists can grow, 100K entries seems reasonable
if (size > 1024*100) return FALSE;
if (size > 1024 * 100) {
_cmsFree(v->ContextID, (void*) v->List);
v->List = NULL;
return FALSE;
}
NewPtr = (_cmsNAMEDCOLOR*) _cmsRealloc(v ->ContextID, v ->List, size * sizeof(_cmsNAMEDCOLOR));
if (NewPtr == NULL)
@ -568,8 +572,11 @@ cmsNAMEDCOLORLIST* CMSEXPORT cmsAllocNamedColorList(cmsContext ContextID, cmsUIn
v ->nColors = 0;
v ->ContextID = ContextID;
while (v -> Allocated < n){
if (!GrowNamedColorList(v)) return NULL;
while (v -> Allocated < n) {
if (!GrowNamedColorList(v)) {
_cmsFree(ContextID, (void*) v);
return NULL;
}
}
strncpy(v ->Prefix, Prefix, sizeof(v ->Prefix)-1);

View File

@ -1483,6 +1483,7 @@ cmsBool OptimizeByJoiningCurves(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUI
// LUT optimizes to nothing. Set the identity LUT
cmsStageFree(ObtainedCurves);
ObtainedCurves = NULL;
if (!cmsPipelineInsertStage(Dest, cmsAT_BEGIN, cmsStageAllocIdentity(Dest ->ContextID, Src ->InputChannels)))
goto Error;

View File

@ -1489,6 +1489,7 @@ void *Type_MLU_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU
// Check for overflow
if (Offset < (SizeOfHeader + 8)) goto Error;
if (((Offset + Len) < Len) || ((Offset + Len) > SizeOfTag + 8)) goto Error;
// True begin of the string
BeginOfThisString = Offset - SizeOfHeader - 8;
@ -4460,18 +4461,19 @@ void *Type_MPE_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU
NewLUT = cmsPipelineAlloc(self ->ContextID, InputChans, OutputChans);
if (NewLUT == NULL) return NULL;
if (!_cmsReadUInt32Number(io, &ElementCount)) return NULL;
if (!ReadPositionTable(self, io, ElementCount, BaseOffset, NewLUT, ReadMPEElem)) {
if (NewLUT != NULL) cmsPipelineFree(NewLUT);
*nItems = 0;
return NULL;
}
if (!_cmsReadUInt32Number(io, &ElementCount)) goto Error;
if (!ReadPositionTable(self, io, ElementCount, BaseOffset, NewLUT, ReadMPEElem)) goto Error;
// Success
*nItems = 1;
return NewLUT;
// Error
Error:
if (NewLUT != NULL) cmsPipelineFree(NewLUT);
*nItems = 0;
return NULL;
cmsUNUSED_PARAMETER(SizeOfTag);
}

View File

@ -1836,7 +1836,7 @@ CMSAPI cmsInt32Number CMSEXPORT cmsIT8SetTable(cmsHANDLE hIT8, cmsUInt32Number
// Persistence
CMSAPI cmsHANDLE CMSEXPORT cmsIT8LoadFromFile(cmsContext ContextID, const char* cFileName);
CMSAPI cmsHANDLE CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, void *Ptr, cmsUInt32Number len);
CMSAPI cmsHANDLE CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cmsUInt32Number len);
// CMSAPI cmsHANDLE CMSEXPORT cmsIT8LoadFromIOhandler(cmsContext ContextID, cmsIOHANDLER* io);
CMSAPI cmsBool CMSEXPORT cmsIT8SaveToFile(cmsHANDLE hIT8, const char* cFileName);

View File

@ -61,29 +61,36 @@ INLINE void AwtCmdIDList::BuildFreeList(UINT first_index)
m_first_free = first_index; // head of the free list
}
jboolean AwtCmdIDList::isFreeIDAvailable() {
CriticalSection::Lock l(m_lock);
if (m_first_free == -1) { // out of free ids
if (m_capacity == ARRAY_MAXIMUM_SIZE) {
return JNI_FALSE;
}
}
return JNI_TRUE;
}
// Assign an id to the object. Recycle the first free entry from the
// head of the free list or allocate more memory for a new free list.
UINT AwtCmdIDList::Add(AwtObject* obj)
{
CriticalSection::Lock l(m_lock);
if (!isFreeIDAvailable()) {
throw std::bad_alloc(); // fatal error
}
if (m_first_free == -1) { // out of free ids
if (m_capacity == ARRAY_MAXIMUM_SIZE) {
// Really bad - out of ids. Since we hardly can have *so*
// many items simultaneously in existence, we have an id
// leak somewhere.
DASSERT(FALSE);
return 0;
}
else { // snarf a bigger arena
UINT old_capacity = m_capacity; // will be the first free entry
m_capacity += ARRAY_SIZE_INCREMENT;
if (m_capacity > ARRAY_MAXIMUM_SIZE)
m_capacity = ARRAY_MAXIMUM_SIZE;
m_array = (CmdIDEntry *)SAFE_SIZE_ARRAY_REALLOC(safe_Realloc, m_array,
m_capacity, sizeof(CmdIDEntry*));
BuildFreeList(old_capacity);
}
// snarf a bigger arena
UINT old_capacity = m_capacity; // will be the first free entry
m_capacity += ARRAY_SIZE_INCREMENT;
if (m_capacity > ARRAY_MAXIMUM_SIZE)
m_capacity = ARRAY_MAXIMUM_SIZE;
m_array = (CmdIDEntry *)SAFE_SIZE_ARRAY_REALLOC(safe_Realloc, m_array,
m_capacity, sizeof(CmdIDEntry*));
BuildFreeList(old_capacity);
}
DASSERT(m_first_free != -1);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -38,6 +38,7 @@ public:
UINT Add(AwtObject* obj);
AwtObject* Lookup(UINT id);
void Remove(UINT id);
jboolean isFreeIDAvailable();
CriticalSection m_lock;

View File

@ -57,15 +57,6 @@ typedef AwtObject* PDATA;
} \
}
#define JNI_CHECK_PEER_GOTO(peer, where) { \
JNI_CHECK_NULL_GOTO(peer, "peer", where); \
pData = JNI_GET_PDATA(peer); \
if (pData == NULL) { \
THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
goto where; \
} \
}
#define JNI_CHECK_NULL_RETURN(obj, msg) { \
if (obj == NULL) { \
env->ExceptionClear(); \
@ -74,15 +65,6 @@ typedef AwtObject* PDATA;
} \
}
#define JNI_CHECK_PEER_RETURN(peer) { \
JNI_CHECK_NULL_RETURN(peer, "peer"); \
pData = JNI_GET_PDATA(peer); \
if (pData == NULL) { \
THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
return; \
} \
}
#define JNI_CHECK_PEER_CREATION_RETURN(peer) { \
if (peer == NULL ) { \
return; \
@ -109,6 +91,33 @@ typedef AwtObject* PDATA;
} \
}
/**
* This macros must be used under SyncCall or on the Toolkit thread.
*/
#define JNI_CHECK_PEER_GOTO(peer, where) { \
JNI_CHECK_NULL_GOTO(peer, "peer", where); \
pData = JNI_GET_PDATA(peer); \
if (pData == NULL) { \
THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
goto where; \
} \
}
/**
* This macros must be used under SyncCall or on the Toolkit thread.
*/
#define JNI_CHECK_PEER_RETURN(peer) { \
JNI_CHECK_NULL_RETURN(peer, "peer"); \
pData = JNI_GET_PDATA(peer); \
if (pData == NULL) { \
THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
return; \
} \
}
/**
* This macros must be used under SyncCall or on the Toolkit thread.
*/
#define JNI_CHECK_PEER_RETURN_NULL(peer) { \
JNI_CHECK_NULL_RETURN_NULL(peer, "peer"); \
pData = JNI_GET_PDATA(peer); \
@ -118,6 +127,9 @@ typedef AwtObject* PDATA;
} \
}
/**
* This macros must be used under SyncCall or on the Toolkit thread.
*/
#define JNI_CHECK_PEER_RETURN_VAL(peer, val) { \
JNI_CHECK_NULL_RETURN_VAL(peer, "peer", val); \
pData = JNI_GET_PDATA(peer); \

View File

@ -65,6 +65,7 @@ LPCTSTR AwtButton::GetClassName() {
/* Create a new AwtButton object and window. */
AwtButton* AwtButton::Create(jobject self, jobject parent)
{
DASSERT(AwtToolkit::IsMainThread());
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
/* the result */
@ -88,7 +89,6 @@ AwtButton* AwtButton::Create(jobject self, jobject parent)
JNI_CHECK_PEER_GOTO(parent, done);
awtParent = (AwtCanvas*)pData;
JNI_CHECK_NULL_GOTO(awtParent, "awtParent", done);
target = env->GetObjectField(self, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "target", done);
@ -375,9 +375,6 @@ Java_sun_awt_windows_WButtonPeer_setLabel(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(self);
SetLabelStruct *sls = new SetLabelStruct;
sls->button = env->NewGlobalRef(self);
sls->label = (label != NULL) ? (jstring)env->NewGlobalRef(label) : NULL;
@ -399,14 +396,9 @@ Java_sun_awt_windows_WButtonPeer_create(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(parent);
AwtToolkit::CreateComponent(
self, parent, (AwtToolkit::ComponentFactory)AwtButton::Create);
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC;
}

View File

@ -59,6 +59,7 @@ LPCTSTR AwtCanvas::GetClassName() {
*/
AwtCanvas* AwtCanvas::Create(jobject self, jobject hParent)
{
DASSERT(AwtToolkit::IsMainThread());
TRY;
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
@ -74,12 +75,11 @@ AwtCanvas* AwtCanvas::Create(jobject self, jobject hParent)
return NULL;
}
PDATA pData;
AwtComponent* parent;
JNI_CHECK_NULL_GOTO(hParent, "null hParent", done);
parent = (AwtComponent*)JNI_GET_PDATA(hParent);
JNI_CHECK_NULL_GOTO(parent, "null parent", done);
JNI_CHECK_PEER_GOTO(hParent, done);
parent = (AwtCanvas*)pData;
target = env->GetObjectField(self, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "null target", done);
@ -236,12 +236,9 @@ Java_sun_awt_windows_WCanvasPeer_create(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(parent);
AwtToolkit::CreateComponent(self, parent,
(AwtToolkit::ComponentFactory)
AwtCanvas::Create);
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC;
}

View File

@ -70,6 +70,7 @@ LPCTSTR AwtCheckbox::GetClassName() {
AwtCheckbox* AwtCheckbox::Create(jobject peer, jobject parent)
{
DASSERT(AwtToolkit::IsMainThread());
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jstring label = NULL;
@ -81,11 +82,10 @@ AwtCheckbox* AwtCheckbox::Create(jobject peer, jobject parent)
return NULL;
}
PDATA pData;
AwtComponent* awtParent;
JNI_CHECK_NULL_GOTO(parent, "null parent", done);
awtParent = (AwtComponent*)JNI_GET_PDATA(parent);
JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
JNI_CHECK_PEER_GOTO(parent, done);
awtParent = (AwtCanvas*)pData;
target = env->GetObjectField(peer, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "null target", done);
@ -669,11 +669,10 @@ Java_sun_awt_windows_WCheckboxPeer_create(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(parent);
AwtToolkit::CreateComponent(self, parent,
(AwtToolkit::ComponentFactory)
AwtCheckbox::Create);
PDATA pData;
JNI_CHECK_PEER_CREATION_RETURN(self);
#ifdef DEBUG

View File

@ -104,7 +104,7 @@ void AwtChoice::Dispose() {
}
AwtChoice* AwtChoice::Create(jobject peer, jobject parent) {
DASSERT(AwtToolkit::IsMainThread());
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject target = NULL;
@ -115,12 +115,10 @@ AwtChoice* AwtChoice::Create(jobject peer, jobject parent) {
if (env->EnsureLocalCapacity(1) < 0) {
return NULL;
}
PDATA pData;
AwtCanvas* awtParent;
JNI_CHECK_NULL_GOTO(parent, "null parent", done);
awtParent = (AwtCanvas*)JNI_GET_PDATA(parent);
JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
JNI_CHECK_PEER_GOTO(parent, done);
awtParent = (AwtCanvas*)pData;
target = env->GetObjectField(peer, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "null target", done);
@ -830,12 +828,9 @@ Java_sun_awt_windows_WChoicePeer_create(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(parent);
AwtToolkit::CreateComponent(self, parent,
(AwtToolkit::ComponentFactory)
AwtChoice::Create);
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC;
}

View File

@ -151,6 +151,11 @@ struct SetFocusStruct {
jobject component;
jboolean doSetFocus;
};
// Struct for _SetParent function
struct SetParentStruct {
jobject component;
jobject parentComp;
};
/************************************************************************/
//////////////////////////////////////////////////////////////////////////
@ -269,9 +274,6 @@ AwtComponent::~AwtComponent()
{
DASSERT(AwtToolkit::IsMainThread());
/* Disconnect all links. */
UnlinkObjects();
/*
* All the messages for this component are processed, native
* resources are freed, and Java object is not connected to
@ -283,6 +285,8 @@ AwtComponent::~AwtComponent()
void AwtComponent::Dispose()
{
DASSERT(AwtToolkit::IsMainThread());
// NOTE: in case the component/toplevel was focused, Java should
// have already taken care of proper transferring it or clearing.
@ -301,8 +305,10 @@ void AwtComponent::Dispose()
/* Release global ref to input method */
SetInputMethod(NULL, TRUE);
if (m_childList != NULL)
if (m_childList != NULL) {
delete m_childList;
m_childList = NULL;
}
DestroyDropTarget();
ReleaseDragCapture(0);
@ -325,6 +331,9 @@ void AwtComponent::Dispose()
m_brushBackground = NULL;
}
/* Disconnect all links. */
UnlinkObjects();
if (m_bPauseDestroy) {
// AwtComponent::WmNcDestroy could be released now
m_bPauseDestroy = FALSE;
@ -6288,21 +6297,36 @@ ret:
return result;
}
void AwtComponent::SetParent(void * param) {
void AwtComponent::_SetParent(void * param)
{
if (AwtToolkit::IsMainThread()) {
AwtComponent** comps = (AwtComponent**)param;
if ((comps[0] != NULL) && (comps[1] != NULL)) {
HWND selfWnd = comps[0]->GetHWnd();
HWND parentWnd = comps[1]->GetHWnd();
if (::IsWindow(selfWnd) && ::IsWindow(parentWnd)) {
// Shouldn't trigger native focus change
// (only the proxy may be the native focus owner).
::SetParent(selfWnd, parentWnd);
}
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
SetParentStruct *data = (SetParentStruct*) param;
jobject self = data->component;
jobject parent = data->parentComp;
AwtComponent *awtComponent = NULL;
AwtComponent *awtParent = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
awtComponent = (AwtComponent *)pData;
JNI_CHECK_PEER_GOTO(parent, ret);
awtParent = (AwtComponent *)pData;
HWND selfWnd = awtComponent->GetHWnd();
HWND parentWnd = awtParent->GetHWnd();
if (::IsWindow(selfWnd) && ::IsWindow(parentWnd)) {
// Shouldn't trigger native focus change
// (only the proxy may be the native focus owner).
::SetParent(selfWnd, parentWnd);
}
delete[] comps;
ret:
env->DeleteGlobalRef(self);
env->DeleteGlobalRef(parent);
delete data;
} else {
AwtToolkit::GetInstance().InvokeFunction(AwtComponent::SetParent, param);
AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_SetParent, param);
}
}
@ -7129,15 +7153,12 @@ JNIEXPORT void JNICALL
Java_sun_awt_windows_WComponentPeer_pSetParent(JNIEnv* env, jobject self, jobject parent) {
TRY;
typedef AwtComponent* PComponent;
AwtComponent** comps = new PComponent[2];
AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(self);
AwtComponent* parentComp = (AwtComponent*)JNI_GET_PDATA(parent);
comps[0] = comp;
comps[1] = parentComp;
SetParentStruct * data = new SetParentStruct;
data->component = env->NewGlobalRef(self);
data->parentComp = env->NewGlobalRef(parent);
AwtToolkit::GetInstance().SyncCall(AwtComponent::SetParent, comps);
// comps is deleted in SetParent
AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetParent, data);
// global refs and data are deleted in SetParent
CATCH_BAD_ALLOC;
}

View File

@ -672,6 +672,7 @@ public:
static void _RemoveNativeDropTarget(void *param);
static jintArray _CreatePrintedPixels(void *param);
static jboolean _NativeHandlesWheelScrolling(void *param);
static void _SetParent(void * param);
static void _SetRectangularShape(void *param);
static void _SetZOrder(void *param);

View File

@ -111,12 +111,13 @@ AwtDialog* AwtDialog::Create(jobject peer, jobject parent)
PDATA pData;
AwtWindow* awtParent = NULL;
HWND hwndParent = NULL;
target = env->GetObjectField(peer, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "null target", done);
if (parent != NULL) {
JNI_CHECK_PEER_GOTO(parent, done);
awtParent = (AwtWindow *)(JNI_GET_PDATA(parent));
awtParent = (AwtWindow *)pData;
hwndParent = awtParent->GetHWnd();
} else {
// There is no way to prevent a parentless dialog from showing on
@ -775,11 +776,9 @@ Java_sun_awt_windows_WDialogPeer_createAwtDialog(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
AwtToolkit::CreateComponent(self, parent,
(AwtToolkit::ComponentFactory)
AwtDialog::Create);
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC;
}

View File

@ -691,7 +691,7 @@ Java_sun_awt_windows_WFileDialogPeer_getLocationOnScreen(JNIEnv *env,
jobject peerRef = env->NewGlobalRef(peer);
jobject resultRef = (jobject)AwtToolkit::GetInstance().SyncCall(
(void*(*)(void*))AwtFileDialog::_GetLocationOnScreen, (void *)peerRef);
env->DeleteLocalRef(peerRef);
env->DeleteGlobalRef(peerRef);
if (resultRef != NULL)
{

View File

@ -878,11 +878,16 @@ Java_sun_awt_windows_WFontMetrics_charsWidth(JNIEnv *env, jobject self,
if (str == NULL) {
JNU_ThrowNullPointerException(env, "str argument");
return NULL;
return 0;
}
if ((len < 0) || (off < 0) || (len + off > (env->GetArrayLength(str)))) {
if ((len < 0) || (off < 0) || (len + off < 0) ||
(len + off > (env->GetArrayLength(str)))) {
JNU_ThrowArrayIndexOutOfBoundsException(env, "off/len argument");
return NULL;
return 0;
}
if (off == env->GetArrayLength(str)) {
return 0;
}
jchar *strp = new jchar[len];
@ -914,12 +919,18 @@ Java_sun_awt_windows_WFontMetrics_bytesWidth(JNIEnv *env, jobject self,
if (str == NULL) {
JNU_ThrowNullPointerException(env, "bytes argument");
return NULL;
return 0;
}
if ((len < 0) || (off < 0) || (len + off > (env->GetArrayLength(str)))) {
if ((len < 0) || (off < 0) || (len + off < 0) ||
(len + off > (env->GetArrayLength(str)))) {
JNU_ThrowArrayIndexOutOfBoundsException(env, "off or len argument");
return NULL;
return 0;
}
if (off == env->GetArrayLength(str)) {
return 0;
}
char *pStrBody = NULL;
jint result = 0;
try {
@ -927,12 +938,12 @@ Java_sun_awt_windows_WFontMetrics_bytesWidth(JNIEnv *env, jobject self,
AwtFont::widthsID);
if (array == NULL) {
JNU_ThrowNullPointerException(env, "Can't access widths array.");
return NULL;
return 0;
}
pStrBody = (char *)env->GetPrimitiveArrayCritical(str, 0);
if (pStrBody == NULL) {
JNU_ThrowNullPointerException(env, "Can't access str bytes.");
return NULL;
return 0;
}
char *pStr = pStrBody + off;
@ -942,7 +953,7 @@ Java_sun_awt_windows_WFontMetrics_bytesWidth(JNIEnv *env, jobject self,
if (widths == NULL) {
env->ReleasePrimitiveArrayCritical(str, pStrBody, 0);
JNU_ThrowNullPointerException(env, "Can't access widths.");
return NULL;
return 0;
}
for (; len; len--) {
result += widths[*pStr++];

View File

@ -1580,12 +1580,12 @@ void AwtFrame::_NotifyModalBlocked(void *param)
PDATA pData;
pData = JNI_GET_PDATA(peer);
JNI_CHECK_PEER_GOTO(peer, ret);
AwtFrame *f = (AwtFrame *)pData;
// dialog here may be NULL, for example, if the blocker is a native dialog
// however, we need to install/unistall modal hooks anyway
pData = JNI_GET_PDATA(blockerPeer);
JNI_CHECK_PEER_GOTO(blockerPeer, ret);
AwtDialog *d = (AwtDialog *)pData;
if ((f != NULL) && ::IsWindow(f->GetHWnd()))
@ -1637,7 +1637,7 @@ void AwtFrame::_NotifyModalBlocked(void *param)
}
}
}
ret:
env->DeleteGlobalRef(self);
env->DeleteGlobalRef(peer);
env->DeleteGlobalRef(blockerPeer);
@ -1809,8 +1809,6 @@ Java_sun_awt_windows_WFramePeer_createAwtFrame(JNIEnv *env, jobject self,
AwtToolkit::CreateComponent(self, parent,
(AwtToolkit::ComponentFactory)
AwtFrame::Create);
PDATA pData;
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC;
}
@ -1924,8 +1922,6 @@ Java_sun_awt_windows_WEmbeddedFramePeer_create(JNIEnv *env, jobject self,
AwtToolkit::CreateComponent(self, parent,
(AwtToolkit::ComponentFactory)
AwtFrame::Create);
PDATA pData;
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC;
}

View File

@ -80,7 +80,7 @@ AwtLabel* AwtLabel::Create(jobject labelPeer, jobject parent)
JNI_CHECK_PEER_GOTO(parent, done);
awtParent = (AwtCanvas*)pData;
JNI_CHECK_NULL_GOTO(awtParent, "awtParent", done);
target = env->GetObjectField(labelPeer, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "target", done);
@ -392,12 +392,9 @@ Java_sun_awt_windows_WLabelPeer_create(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(parent);
AwtToolkit::CreateComponent(self, parent,
(AwtToolkit::ComponentFactory)
AwtLabel::Create);
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC;
}

View File

@ -89,10 +89,9 @@ AwtList* AwtList::Create(jobject peer, jobject parent)
PDATA pData;
AwtCanvas* awtParent;
JNI_CHECK_PEER_GOTO(parent, done);
JNI_CHECK_PEER_GOTO(parent, done);
awtParent = (AwtCanvas*)pData;
JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
/* target is Hjava_awt_List * */
target = env->GetObjectField(peer, AwtObject::targetID);
@ -928,9 +927,6 @@ Java_sun_awt_windows_WListPeer_deselect(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(self);
SelectElementStruct *ses = new SelectElementStruct;
ses->list = env->NewGlobalRef(self);
ses->index = pos;
@ -994,11 +990,8 @@ Java_sun_awt_windows_WListPeer_create(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(parent);
AwtToolkit::CreateComponent(self, parent,
(AwtToolkit::ComponentFactory)AwtList::Create);
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -217,6 +217,10 @@ AwtMenuItem* AwtMenuItem::Create(jobject peer, jobject menuPeer)
if (env->EnsureLocalCapacity(1) < 0) {
return NULL;
}
if (!AwtToolkit::GetInstance().isFreeIDAvailable()) {
return NULL;
}
JNI_CHECK_NULL_RETURN_NULL(menuPeer, "peer");
/* target is a java.awt.MenuItem */

View File

@ -96,10 +96,9 @@ AwtScrollPane* AwtScrollPane::Create(jobject self, jobject parent)
PDATA pData;
AwtComponent* awtParent;
JNI_CHECK_PEER_GOTO(parent, done);
JNI_CHECK_PEER_GOTO(parent, done);
awtParent = (AwtComponent*)pData;
JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
target = env->GetObjectField(self, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "null target", done);
@ -679,11 +678,10 @@ Java_sun_awt_windows_WScrollPanePeer_create(JNIEnv *env, jobject self,
DTRACE_PRINTLN2("%x: WScrollPanePeer.create(%x)", self, parent);
PDATA pData;
JNI_CHECK_PEER_RETURN(parent);
AwtToolkit::CreateComponent(self, parent,
(AwtToolkit::ComponentFactory)
AwtScrollPane::Create);
PDATA pData;
JNI_CHECK_PEER_CREATION_RETURN(self);
((AwtScrollPane*)pData)->VerifyState();

View File

@ -38,7 +38,11 @@ struct SetValuesStruct {
jint value;
jint visible;
jint min, max;
};
// struct for _SetLineIncrement()/_SetPageIncrement() methods
struct SetIncrementStruct {
jobject scrollbar;
jint increment;
};
/************************************************************************
* AwtScrollbar fields
@ -108,10 +112,9 @@ AwtScrollbar::Create(jobject peer, jobject parent)
PDATA pData;
AwtCanvas* awtParent;
JNI_CHECK_PEER_GOTO(parent, done);
JNI_CHECK_PEER_GOTO(parent, done);
awtParent = (AwtCanvas*)pData;
JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
target = env->GetObjectField(peer, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "null target", done);
@ -471,6 +474,52 @@ ret:
delete svs;
}
void AwtScrollbar::_SetLineIncrement(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
SetIncrementStruct *sis = (SetIncrementStruct *)param;
jobject self = sis->scrollbar;
jint increment = sis->increment;
AwtScrollbar *sb = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
sb = (AwtScrollbar *)pData;
if (::IsWindow(sb->GetHWnd()))
{
sb->SetLineIncrement(increment);
}
ret:
env->DeleteGlobalRef(self);
delete sis;
}
void AwtScrollbar::_SetPageIncrement(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
SetIncrementStruct *sis = (SetIncrementStruct *)param;
jobject self = sis->scrollbar;
jint increment = sis->increment;
AwtScrollbar *sb = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
sb = (AwtScrollbar *)pData;
if (::IsWindow(sb->GetHWnd()))
{
sb->SetPageIncrement(increment);
}
ret:
env->DeleteGlobalRef(self);
delete sis;
}
/************************************************************************
* Scrollbar native methods
*/
@ -546,10 +595,12 @@ Java_sun_awt_windows_WScrollbarPeer_setLineIncrement(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(self);
AwtScrollbar* c = (AwtScrollbar*)pData;
c->SetLineIncrement(increment);
SetIncrementStruct *sis = new SetIncrementStruct;
sis->scrollbar = env->NewGlobalRef(self);
sis->increment = increment;
AwtToolkit::GetInstance().SyncCall(AwtScrollbar::_SetLineIncrement, sis);
// global ref and svs are deleted in _SetValues
CATCH_BAD_ALLOC;
}
@ -565,10 +616,12 @@ Java_sun_awt_windows_WScrollbarPeer_setPageIncrement(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(self);
AwtScrollbar* c = (AwtScrollbar*)pData;
c->SetPageIncrement(increment);
SetIncrementStruct *sis = new SetIncrementStruct;
sis->scrollbar = env->NewGlobalRef(self);
sis->increment = increment;
AwtToolkit::GetInstance().SyncCall(AwtScrollbar::_SetPageIncrement, sis);
// global ref and svs are deleted in _SetValues
CATCH_BAD_ALLOC;
}
@ -584,12 +637,9 @@ Java_sun_awt_windows_WScrollbarPeer_create(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(parent);
AwtToolkit::CreateComponent(self, parent,
(AwtToolkit::ComponentFactory)
AwtScrollbar::Create);
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC;
}

View File

@ -77,6 +77,8 @@ public:
INLINE virtual BOOL IsScrollbar() { return TRUE; }
static void _SetLineIncrement(void *param);
static void _SetPageIncrement(void *param);
// invoked on Toolkit thread
static void _SetValues(void *param);

View File

@ -505,12 +505,9 @@ Java_sun_awt_windows_WTextAreaPeer_create(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(parent);
AwtToolkit::CreateComponent(self, parent,
(AwtToolkit::ComponentFactory)
AwtTextArea::Create);
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC;
}

View File

@ -95,10 +95,9 @@ AwtTextComponent* AwtTextComponent::Create(jobject peer, jobject parent, BOOL is
PDATA pData;
AwtCanvas* awtParent;
JNI_CHECK_PEER_GOTO(parent, done);
JNI_CHECK_PEER_GOTO(parent, done);
awtParent = (AwtCanvas*)pData;
JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
target = env->GetObjectField(peer, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "null target", done);

View File

@ -260,12 +260,9 @@ Java_sun_awt_windows_WTextFieldPeer_create(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(parent);
AwtToolkit::CreateComponent(self, parent,
(AwtToolkit::ComponentFactory)
AwtTextField::Create);
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -1869,6 +1869,11 @@ void AwtToolkit::SyncCall(void (*ftn)(void)) {
}
}
jboolean AwtToolkit::isFreeIDAvailable()
{
return m_cmdIDs->isFreeIDAvailable();
}
UINT AwtToolkit::CreateCmdID(AwtObject* object)
{
return m_cmdIDs->Add(object);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -373,6 +373,8 @@ public:
BOOL PreProcessMouseMsg(class AwtComponent* p, MSG& msg);
BOOL PreProcessKeyMsg(class AwtComponent* p, MSG& msg);
/* Checks that an free ID exists. */
jboolean isFreeIDAvailable();
/* Create an ID which maps to an AwtObject pointer, such as a menu. */
UINT CreateCmdID(AwtObject* object);

View File

@ -3400,12 +3400,9 @@ Java_sun_awt_windows_WWindowPeer_createAwtWindow(JNIEnv *env, jobject self,
{
TRY;
PDATA pData;
// JNI_CHECK_PEER_RETURN(parent);
AwtToolkit::CreateComponent(self, parent,
(AwtToolkit::ComponentFactory)
AwtWindow::Create);
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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,6 +25,7 @@
package com.sun.jmx.remote.internal.rmi;
import java.io.ObjectInputFilter;
import java.rmi.NoSuchObjectException;
import java.rmi.Remote;
import java.rmi.RemoteException;
@ -51,7 +52,8 @@ public interface RMIExporter {
public Remote exportObject(Remote obj,
int port,
RMIClientSocketFactory csf,
RMIServerSocketFactory ssf)
RMIServerSocketFactory ssf,
ObjectInputFilter filter)
throws RemoteException;
public boolean unexportObject(Remote obj, boolean force)

View File

@ -32,6 +32,7 @@ import com.sun.jmx.remote.util.EnvHelp;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputFilter;
import java.io.ObjectOutputStream;
import java.net.MalformedURLException;
import java.rmi.server.RMIClientSocketFactory;
@ -101,19 +102,59 @@ public class RMIConnectorServer extends JMXConnectorServer {
"jmx.remote.rmi.server.socket.factory";
/**
* Name of the attribute that specifies a list of class names acceptable
* as parameters to the {@link RMIServer#newClient(java.lang.Object) RMIServer.newClient()}
* Name of the attribute that specifies an
* {@link ObjectInputFilter} pattern string to filter classes acceptable
* for {@link RMIServer#newClient(java.lang.Object) RMIServer.newClient()}
* remote method call.
* <p>
* This list of classes should correspond to the transitive closure of the
* credentials class (or classes) used by the installed {@linkplain JMXAuthenticator}
* associated with the {@linkplain RMIServer} implementation.
* The filter pattern must be in same format as used in
* {@link java.io.ObjectInputFilter.Config#createFilter}
* <p>
* If the attribute is not set, or is null, then any class is
* deemed acceptable.
* This list of classes allowed by filter should correspond to the
* transitive closure of the credentials class (or classes) used by the
* installed {@linkplain JMXAuthenticator} associated with the
* {@linkplain RMIServer} implementation.
* If the attribute is not set then any class is deemed acceptable.
* @see ObjectInputFilter
*/
public static final String CREDENTIAL_TYPES =
"jmx.remote.rmi.server.credential.types";
public static final String CREDENTIALS_FILTER_PATTERN =
"jmx.remote.rmi.server.credentials.filter.pattern";
/**
* This attribute defines a pattern from which to create a
* {@link java.io.ObjectInputFilter} that will be used when deserializing
* objects sent to the {@code JMXConnectorServer} by any client.
* <p>
* The filter will be called for any class found in the serialized
* stream sent to server by client, including all JMX defined classes
* (such as {@link javax.management.ObjectName}), all method parameters,
* and, if present in the stream, all classes transitively referred by
* the serial form of any deserialized object.
* The pattern must be in same format as used in
* {@link java.io.ObjectInputFilter.Config#createFilter}.
* It may define a white list of permitted classes, a black list of
* rejected classes, a maximum depth for the deserialized objects,
* etc.
* <p>
* To be functional, the filter should allow at least all the
* concrete types in the transitive closure of all objects that
* might get serialized when serializing all JMX classes referred
* as parameters in the {@link
* javax.management.remote.rmi.RMIConnection} interface,
* plus all classes that a {@link javax.management.remote.rmi.RMIConnector client}
* might need to transmit wrapped in {@linkplain java.rmi.MarshalledObject
* marshalled objects} in order to interoperate with the MBeans registered
* in the {@code MBeanServer}. That would potentially include all the
* concrete {@linkplain javax.management.openmbean JMX OpenTypes} and the
* classes they use in their serial form.
* <p>
* Care must be taken when defining such a filter, as defining
* a white list too restrictive or a too wide a black list may
* prevent legitimate clients from interoperating with the
* {@code JMXConnectorServer}.
*/
public static final String SERIAL_FILTER_PATTERN =
"jmx.remote.rmi.server.serial.filter.pattern";
/**
* <p>Makes an <code>RMIConnectorServer</code>.

View File

@ -26,6 +26,7 @@
package javax.management.remote.rmi;
import java.io.IOException;
import java.io.ObjectInputFilter;
import java.rmi.NoSuchObjectException;
import java.rmi.Remote;
import java.rmi.RemoteException;
@ -39,15 +40,13 @@ import javax.security.auth.Subject;
import com.sun.jmx.remote.internal.rmi.RMIExporter;
import com.sun.jmx.remote.util.EnvHelp;
import java.io.ObjectStreamClass;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import sun.reflect.misc.ReflectUtil;
import sun.rmi.server.DeserializationChecker;
import sun.rmi.server.UnicastServerRef;
import sun.rmi.server.UnicastServerRef2;
import sun.rmi.transport.LiveRef;
/**
* <p>An {@link RMIServer} object that is exported through JRMP and that
@ -60,8 +59,6 @@ import sun.rmi.server.UnicastServerRef2;
*/
public class RMIJRMPServerImpl extends RMIServerImpl {
private final ExportedWrapper exportedWrapper;
/**
* <p>Creates a new {@link RMIServer} object that will be exported
* on the given port using the given socket factories.</p>
@ -100,33 +97,48 @@ public class RMIJRMPServerImpl extends RMIServerImpl {
this.ssf = ssf;
this.env = (env == null) ? Collections.<String, Object>emptyMap() : env;
// This attribute was represented by RMIConnectorServer.CREDENTIALS_TYPES.
// This attribute is superceded by
// RMIConnectorServer.CREDENTIALS_FILTER_PATTERN.
// Retaining this for backward compatibility.
String[] credentialsTypes
= (String[]) this.env.get(RMIConnectorServer.CREDENTIAL_TYPES);
List<String> types = null;
if (credentialsTypes != null) {
types = new ArrayList<>();
for (String type : credentialsTypes) {
if (type == null) {
throw new IllegalArgumentException("A credential type is null.");
}
ReflectUtil.checkPackageAccess(type);
types.add(type);
}
= (String[]) this.env.get("jmx.remote.rmi.server.credential.types");
String credentialsFilter
= (String) this.env.get(RMIConnectorServer.CREDENTIALS_FILTER_PATTERN);
// It is impossible for both attributes to be specified
if(credentialsTypes != null && credentialsFilter != null)
throw new IllegalArgumentException("Cannot specify both \""
+ "jmx.remote.rmi.server.credential.types" + "\" and \""
+ RMIConnectorServer.CREDENTIALS_FILTER_PATTERN + "\"");
else if(credentialsFilter != null){
cFilter = ObjectInputFilter.Config.createFilter(credentialsFilter);
allowedTypes = null;
}
exportedWrapper = types != null ?
new ExportedWrapper(this, types) :
null;
else if (credentialsTypes != null) {
allowedTypes = Arrays.stream(credentialsTypes).filter(
s -> s!= null).collect(Collectors.toSet());
allowedTypes.stream().forEach(ReflectUtil::checkPackageAccess);
cFilter = this::newClientCheckInput;
} else {
allowedTypes = null;
cFilter = null;
}
String userJmxFilter =
(String) this.env.get(RMIConnectorServer.SERIAL_FILTER_PATTERN);
if(userJmxFilter != null && !userJmxFilter.isEmpty())
jmxRmiFilter = ObjectInputFilter.Config.createFilter(userJmxFilter);
else
jmxRmiFilter = null;
}
protected void export() throws IOException {
if (exportedWrapper != null) {
export(exportedWrapper);
} else {
export(this);
}
export(this, cFilter);
}
private void export(Remote obj) throws RemoteException {
private void export(Remote obj, ObjectInputFilter typeFilter) throws RemoteException {
final RMIExporter exporter =
(RMIExporter) env.get(RMIExporter.EXPORTER_ATTRIBUTE);
final boolean daemon = EnvHelp.isServerDaemon(env);
@ -137,16 +149,14 @@ public class RMIJRMPServerImpl extends RMIServerImpl {
" cannot be used to specify an exporter!");
}
if (daemon) {
if (csf == null && ssf == null) {
new UnicastServerRef(port).exportObject(obj, null, true);
} else {
new UnicastServerRef2(port, csf, ssf).exportObject(obj, null, true);
}
} else if (exporter != null) {
exporter.exportObject(obj, port, csf, ssf);
if (exporter != null) {
exporter.exportObject(obj, port, csf, ssf, typeFilter);
} else {
UnicastRemoteObject.exportObject(obj, port, csf, ssf);
if (csf == null && ssf == null) {
new UnicastServerRef(new LiveRef(port), typeFilter).exportObject(obj, null, daemon);
} else {
new UnicastServerRef2(port, csf, ssf, typeFilter).exportObject(obj, null, daemon);
}
}
}
@ -173,11 +183,7 @@ public class RMIJRMPServerImpl extends RMIServerImpl {
* RMIJRMPServerImpl has not been exported yet.
*/
public Remote toStub() throws IOException {
if (exportedWrapper != null) {
return RemoteObject.toStub(exportedWrapper);
} else {
return RemoteObject.toStub(this);
}
return RemoteObject.toStub(this);
}
/**
@ -207,7 +213,7 @@ public class RMIJRMPServerImpl extends RMIServerImpl {
RMIConnection client =
new RMIConnectionImpl(this, connectionId, getDefaultClassLoader(),
subject, env);
export(client);
export(client, jmxRmiFilter);
return client;
}
@ -224,56 +230,39 @@ public class RMIJRMPServerImpl extends RMIServerImpl {
* server failed.
*/
protected void closeServer() throws IOException {
if (exportedWrapper != null) {
unexport(exportedWrapper, true);
} else {
unexport(this, true);
unexport(this, true);
}
/**
* Check that a type in the remote invocation of {@link RMIServerImpl#newClient}
* is one of the {@code allowedTypes}.
*
* @param clazz the class; may be null
* @param size the size for arrays, otherwise is 0
* @param nObjectRefs the current number of object references
* @param depth the current depth
* @param streamBytes the current number of bytes consumed
* @return {@code ObjectInputFilter.Status.ALLOWED} if the class is allowed,
* otherwise {@code ObjectInputFilter.Status.REJECTED}
*/
ObjectInputFilter.Status newClientCheckInput(ObjectInputFilter.FilterInfo filterInfo) {
ObjectInputFilter.Status status = ObjectInputFilter.Status.UNDECIDED;
if (allowedTypes != null && filterInfo.serialClass() != null) {
// If enabled, check type
String type = filterInfo.serialClass().getName();
if (allowedTypes.contains(type))
status = ObjectInputFilter.Status.ALLOWED;
else
status = ObjectInputFilter.Status.REJECTED;
}
return status;
}
private final int port;
private final RMIClientSocketFactory csf;
private final RMIServerSocketFactory ssf;
private final Map<String, ?> env;
private static class ExportedWrapper implements RMIServer, DeserializationChecker {
private final RMIServer impl;
private final List<String> allowedTypes;
private ExportedWrapper(RMIServer impl, List<String> credentialsTypes) {
this.impl = impl;
allowedTypes = credentialsTypes;
}
@Override
public String getVersion() throws RemoteException {
return impl.getVersion();
}
@Override
public RMIConnection newClient(Object credentials) throws IOException {
return impl.newClient(credentials);
}
@Override
public void check(Method method, ObjectStreamClass descriptor,
int paramIndex, int callID) {
String type = descriptor.getName();
if (!allowedTypes.contains(type)) {
throw new ClassCastException("Unsupported type: " + type);
}
}
@Override
public void checkProxyClass(Method method, String[] ifaces,
int paramIndex, int callID) {
if (ifaces != null && ifaces.length > 0) {
for (String iface : ifaces) {
if (!allowedTypes.contains(iface)) {
throw new ClassCastException("Unsupported type: " + iface);
}
}
}
}
}
private final Set<String> allowedTypes;
private final ObjectInputFilter jmxRmiFilter;
private final ObjectInputFilter cFilter;
}

View File

@ -35,8 +35,6 @@ import java.security.AccessControlException;
import java.security.Permission;
import java.rmi.server.RMIClassLoader;
import java.security.PrivilegedAction;
import jdk.internal.misc.ObjectStreamClassValidator;
import jdk.internal.misc.SharedSecrets;
/**
* MarshalInputStream is an extension of ObjectInputStream. When resolving
@ -54,11 +52,6 @@ import jdk.internal.misc.SharedSecrets;
* @author Peter Jones
*/
public class MarshalInputStream extends ObjectInputStream {
interface StreamChecker extends ObjectStreamClassValidator {
void checkProxyInterfaceNames(String[] ifaces);
}
private volatile StreamChecker streamChecker = null;
/**
* Value of "java.rmi.server.useCodebaseOnly" property,
@ -245,11 +238,6 @@ public class MarshalInputStream extends ObjectInputStream {
protected Class<?> resolveProxyClass(String[] interfaces)
throws IOException, ClassNotFoundException
{
StreamChecker checker = streamChecker;
if (checker != null) {
checker.checkProxyInterfaceNames(interfaces);
}
/*
* Always read annotation written by MarshalOutputStream.
*/
@ -330,28 +318,4 @@ public class MarshalInputStream extends ObjectInputStream {
void useCodebaseOnly() {
useCodebaseOnly = true;
}
synchronized void setStreamChecker(StreamChecker checker) {
streamChecker = checker;
SharedSecrets.getJavaObjectInputStreamAccess().setValidator(this, checker);
}
@Override
protected ObjectStreamClass readClassDescriptor() throws IOException,
ClassNotFoundException {
ObjectStreamClass descriptor = super.readClassDescriptor();
validateDesc(descriptor);
return descriptor;
}
private void validateDesc(ObjectStreamClass descriptor) {
StreamChecker checker;
synchronized (this) {
checker = streamChecker;
}
if (checker != null) {
checker.validateDescriptor(descriptor);
}
}
}

View File

@ -30,7 +30,6 @@ import java.io.ObjectInput;
import java.io.ObjectInputFilter;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectStreamClass;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.rmi.AccessException;
@ -330,11 +329,16 @@ public class UnicastServerRef extends UnicastRef
logCall(obj, method);
// unmarshal parameters
Object[] params = null;
Class<?>[] types = method.getParameterTypes();
Object[] params = new Object[types.length];
try {
unmarshalCustomCallData(in);
params = unmarshalParameters(obj, method, marshalStream);
// Unmarshal the parameters
for (int i = 0; i < types.length; i++) {
params[i] = unmarshalValue(types[i], in);
}
} catch (AccessException aex) {
// For compatibility, AccessException is not wrapped in UnmarshalException
// disable saving any refs in the inputStream for GC
@ -600,84 +604,4 @@ public class UnicastServerRef extends UnicastRef
}
}
/**
* Unmarshal parameters for the given method of the given instance over
* the given marshalinputstream. Perform any necessary checks.
*/
private Object[] unmarshalParameters(Object obj, Method method, MarshalInputStream in)
throws IOException, ClassNotFoundException {
return (obj instanceof DeserializationChecker) ?
unmarshalParametersChecked((DeserializationChecker)obj, method, in) :
unmarshalParametersUnchecked(method, in);
}
/**
* Unmarshal parameters for the given method of the given instance over
* the given marshalinputstream. Do not perform any additional checks.
*/
private Object[] unmarshalParametersUnchecked(Method method, ObjectInput in)
throws IOException, ClassNotFoundException {
Class<?>[] types = method.getParameterTypes();
Object[] params = new Object[types.length];
for (int i = 0; i < types.length; i++) {
params[i] = unmarshalValue(types[i], in);
}
return params;
}
/**
* Unmarshal parameters for the given method of the given instance over
* the given marshalinputstream. Do perform all additional checks.
*/
private Object[] unmarshalParametersChecked(
DeserializationChecker checker,
Method method, MarshalInputStream in)
throws IOException, ClassNotFoundException {
int callID = methodCallIDCount.getAndIncrement();
MyChecker myChecker = new MyChecker(checker, method, callID);
in.setStreamChecker(myChecker);
try {
Class<?>[] types = method.getParameterTypes();
Object[] values = new Object[types.length];
for (int i = 0; i < types.length; i++) {
myChecker.setIndex(i);
values[i] = unmarshalValue(types[i], in);
}
myChecker.end(callID);
return values;
} finally {
in.setStreamChecker(null);
}
}
private static class MyChecker implements MarshalInputStream.StreamChecker {
private final DeserializationChecker descriptorCheck;
private final Method method;
private final int callID;
private int parameterIndex;
MyChecker(DeserializationChecker descriptorCheck, Method method, int callID) {
this.descriptorCheck = descriptorCheck;
this.method = method;
this.callID = callID;
}
@Override
public void validateDescriptor(ObjectStreamClass descriptor) {
descriptorCheck.check(method, descriptor, parameterIndex, callID);
}
@Override
public void checkProxyInterfaceNames(String[] ifaces) {
descriptorCheck.checkProxyClass(method, ifaces, parameterIndex, callID);
}
void setIndex(int parameterIndex) {
this.parameterIndex = parameterIndex;
}
void end(int callId) {
descriptorCheck.end(callId);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -31,6 +31,7 @@ import java.rmi.server.ObjID;
import java.rmi.server.Unreferenced;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
import sun.rmi.runtime.Log;
import sun.rmi.runtime.NewThreadAction;
@ -322,27 +323,15 @@ public final class Target {
Remote obj = getImpl();
if (obj instanceof Unreferenced) {
final Unreferenced unrefObj = (Unreferenced) obj;
final Thread t =
java.security.AccessController.doPrivileged(
new NewThreadAction(new Runnable() {
public void run() {
unrefObj.unreferenced();
}
}, "Unreferenced-" + nextThreadNum++, false, true));
// REMIND: access to nextThreadNum not synchronized; you care?
/*
* We must manually set the context class loader appropriately
* for threads that may invoke user code (see bugid 4171278).
*/
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
t.setContextClassLoader(ccl);
return null;
}
});
t.start();
AccessController.doPrivileged(
new NewThreadAction(() -> {
Thread.currentThread().setContextClassLoader(ccl);
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
unrefObj.unreferenced();
return null;
}, acc);
}, "Unreferenced-" + nextThreadNum++, false, true)).start();
// REMIND: access to nextThreadNum not synchronized; you care?
}
unpinImpl();

View File

@ -270,7 +270,7 @@ final class CardImpl extends Card {
}
public String toString() {
return "PC/SC card in " + terminal.getName()
return "PC/SC card in " + terminal.name
+ ", protocol " + getProtocol() + ", state " + state;
}
@ -278,6 +278,7 @@ final class CardImpl extends Card {
protected void finalize() throws Throwable {
try {
if (state == State.OK) {
state = State.DISCONNECTED;
SCardDisconnect(cardId, SCARD_LEAVE_CARD);
}
} finally {

View File

@ -34,6 +34,8 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.xml.ws.WebServiceException;
@ -122,13 +124,21 @@ public abstract class JAXWSExceptionBase
String resourceBundleName = (String) in.readObject();
String key = (String) in.readObject();
int len = in.readInt();
if (len == -1) {
if (len < -1) {
throw new NegativeArraySizeException();
} else if (len == -1) {
args = null;
} else {
} else if (len < 255) {
args = new Object[len];
for (int i = 0; i < args.length; i++) {
args[i] = in.readObject();
}
} else {
List<Object> argList = new ArrayList<>(Math.min(len, 1024));
for (int i = 0; i < len; i++) {
argList.add(in.readObject());
}
args = argList.toArray(new Object[argList.size()]);
}
msg = new LocalizableMessageFactory(resourceBundleName).getMessage(key,args);
}

View File

@ -71,6 +71,14 @@ public abstract class PredicatedNodeTest extends NodeTest implements SubContextL
{
stream.defaultReadObject();
m_predicateIndex = -1;
/**
* Initialize to the declared value.
* As noted at declaration, this variable is used only for clones for getLastPos,
* it should have been excluded from serialization. For compatibility, we'll
* keep it as is but initializing to the declared value.
*/
m_predCount = -1;
resetProximityPositions();
}
catch (ClassNotFoundException cnfe)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -33,11 +33,13 @@ import java.security.spec.*;
import javax.crypto.spec.DHParameterSpec;
import sun.security.provider.ParameterCache;
import static sun.security.util.SecurityProviderConstants.*;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import sun.security.rsa.RSAKeyFactory;
/**
@ -98,7 +100,7 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
// override lower limit to disallow unsecure keys being generated
// override upper limit to deter DOS attack
if (algorithm.equals("EC")) {
keySize = 256;
keySize = DEF_EC_KEY_SIZE;
if ((minKeyLen == -1) || (minKeyLen < 112)) {
minKeyLen = 112;
}
@ -107,13 +109,11 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
}
} else {
if (algorithm.equals("DSA")) {
// keep default keysize at 1024 since larger keysizes may be
// incompatible with SHA1withDSA and SHA-2 Signature algs
// may not be supported by native pkcs11 implementations
keySize = 1024;
keySize = DEF_DSA_KEY_SIZE;
} else if (algorithm.equals("RSA")) {
keySize = DEF_RSA_KEY_SIZE;
} else {
// RSA and DH
keySize = 2048;
keySize = DEF_DH_KEY_SIZE;
}
if ((minKeyLen == -1) || (minKeyLen < 512)) {
minKeyLen = 512;

View File

@ -39,6 +39,7 @@ import sun.security.ec.ECPublicKeyImpl;
import sun.security.jca.JCAUtil;
import sun.security.util.ECParameters;
import sun.security.util.ECUtil;
import static sun.security.util.SecurityProviderConstants.DEF_EC_KEY_SIZE;
/**
* EC keypair generator.
@ -50,7 +51,6 @@ public final class ECKeyPairGenerator extends KeyPairGeneratorSpi {
private static final int KEY_SIZE_MIN = 112; // min bits (see ecc_impl.h)
private static final int KEY_SIZE_MAX = 571; // max bits (see ecc_impl.h)
private static final int KEY_SIZE_DEFAULT = 256;
// used to seed the keypair generator
private SecureRandom random;
@ -66,7 +66,7 @@ public final class ECKeyPairGenerator extends KeyPairGeneratorSpi {
*/
public ECKeyPairGenerator() {
// initialize to default in case the app does not call initialize()
initialize(KEY_SIZE_DEFAULT, null);
initialize(DEF_EC_KEY_SIZE, null);
}
// initialize the generator. See JCA doc

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -31,6 +31,7 @@ import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
import sun.security.rsa.RSAKeyFactory;
import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
/**
* RSA keypair generator.
@ -45,14 +46,13 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
// Supported by Microsoft Base, Strong and Enhanced Cryptographic Providers
static final int KEY_SIZE_MIN = 512; // disallow MSCAPI min. of 384
static final int KEY_SIZE_MAX = 16384;
private static final int KEY_SIZE_DEFAULT = 2048;
// size of the key to generate, KEY_SIZE_MIN <= keySize <= KEY_SIZE_MAX
private int keySize;
public RSAKeyPairGenerator() {
// initialize to default in case the app does not call initialize()
initialize(KEY_SIZE_DEFAULT, null);
initialize(DEF_RSA_KEY_SIZE, null);
}
// initialize the generator. See JCA doc
@ -76,7 +76,7 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
int tmpSize;
if (params == null) {
tmpSize = KEY_SIZE_DEFAULT;
tmpSize = DEF_RSA_KEY_SIZE;
} else if (params instanceof RSAKeyGenParameterSpec) {
if (((RSAKeyGenParameterSpec) params).getPublicExponent() != null) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -32,7 +32,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.io.ObjectInputFilter;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.MalformedURLException;
@ -45,14 +45,12 @@ import java.rmi.RemoteException;
import java.rmi.registry.Registry;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.RMISocketFactory;
import java.rmi.server.RemoteObject;
import java.rmi.server.UnicastRemoteObject;
import java.security.KeyStore;
import java.security.Principal;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@ -84,6 +82,7 @@ import jdk.internal.agent.FileSystem;
import sun.rmi.server.UnicastRef;
import sun.rmi.server.UnicastServerRef;
import sun.rmi.server.UnicastServerRef2;
import sun.rmi.transport.LiveRef;
/**
* This class initializes and starts the RMIConnectorServer for JSR 163
@ -142,6 +141,8 @@ public final class ConnectorBootstrap {
"com.sun.management.jmxremote.ssl.need.client.auth";
public static final String SSL_CONFIG_FILE_NAME =
"com.sun.management.jmxremote.ssl.config.file";
public static final String SERIAL_FILTER_PATTERN =
"com.sun.management.jmxremote.serial.filter.pattern";
}
/**
@ -182,7 +183,8 @@ public final class ConnectorBootstrap {
public Remote exportObject(Remote obj,
int port,
RMIClientSocketFactory csf,
RMIServerSocketFactory ssf)
RMIServerSocketFactory ssf,
ObjectInputFilter filter)
throws RemoteException {
synchronized (this) {
@ -193,9 +195,9 @@ public final class ConnectorBootstrap {
final UnicastServerRef ref;
if (csf == null && ssf == null) {
ref = new UnicastServerRef(port);
ref = new UnicastServerRef(new LiveRef(port), filter);
} else {
ref = new UnicastServerRef2(port, csf, ssf);
ref = new UnicastServerRef2(port, csf, ssf, filter);
}
return ref.exportObject(obj, null, true);
}
@ -435,6 +437,7 @@ public final class ConnectorBootstrap {
final String bindAddress =
props.getProperty(PropertyNames.HOST);
final String jmxRmiFilter = props.getProperty(PropertyNames.SERIAL_FILTER_PATTERN);
if (logger.isLoggable(Level.DEBUG)) {
logger.log(Level.DEBUG, "startRemoteConnectorServer",
@ -471,7 +474,7 @@ public final class ConnectorBootstrap {
sslConfigFileName, enabledCipherSuitesList,
enabledProtocolsList, sslNeedClientAuth,
useAuthentication, loginConfigName,
passwordFileName, accessFileName, bindAddress);
passwordFileName, accessFileName, bindAddress, jmxRmiFilter);
cs = data.jmxConnectorServer;
url = data.jmxRemoteURL;
config("startRemoteConnectorServer",
@ -511,9 +514,7 @@ public final class ConnectorBootstrap {
// This RMI server should not keep the VM alive
Map<String, Object> env = new HashMap<>();
env.put(RMIExporter.EXPORTER_ATTRIBUTE, new PermanentExporter());
env.put(RMIConnectorServer.CREDENTIAL_TYPES, new String[]{
String[].class.getName(), String.class.getName()
});
env.put(RMIConnectorServer.CREDENTIALS_FILTER_PATTERN, String.class.getName() + ";!*");
// The local connector server need only be available via the
// loopback connection.
@ -729,7 +730,8 @@ public final class ConnectorBootstrap {
String loginConfigName,
String passwordFileName,
String accessFileName,
String bindAddress)
String bindAddress,
String jmxRmiFilter)
throws IOException, MalformedURLException {
/* Make sure we use non-guessable RMI object IDs. Otherwise
@ -744,9 +746,11 @@ public final class ConnectorBootstrap {
PermanentExporter exporter = new PermanentExporter();
env.put(RMIExporter.EXPORTER_ATTRIBUTE, exporter);
env.put(RMIConnectorServer.CREDENTIAL_TYPES, new String[]{
String[].class.getName(), String.class.getName()
});
env.put(RMIConnectorServer.CREDENTIALS_FILTER_PATTERN, String.class.getName() + ";!*");
if(jmxRmiFilter != null && !jmxRmiFilter.isEmpty()) {
env.put(RMIConnectorServer.SERIAL_FILTER_PATTERN, jmxRmiFilter);
}
boolean useSocketFactory = bindAddress != null && !useSsl;

View File

@ -329,3 +329,42 @@
# The format of the value for that property is any string accepted
# by java.net.InetAddress.getByName(String).
#
# ################ Filter for ObjectInputStream #############################
# com.sun.management.jmxremote.serial.filter.pattern=<filter-string>
# A filter, if configured, is used by java.io.ObjectInputStream during
# deserialization of parameters sent to the JMX default agent to validate 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 contains "/", the non-empty prefix up to the "/" is the module name;
# if the module name matches the module name of the class then
# the remaining pattern is matched with the class name.
# If there is no "/", the module name is not compared.
# 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.

View File

@ -29,9 +29,14 @@ import java.io.OptionalDataException;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.Permission;
import java.security.ProtectionDomain;
import java.security.PrivilegedAction;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.JavaSecurityAccess;
/**
* ReflectionFactory supports custom serialization.
@ -139,6 +144,66 @@ public class ReflectionFactory {
return delegate.readObjectForSerialization(cl);
}
/**
* Invokes the supplied constructor, adding the provided protection domains
* to the invocation stack before invoking {@code Constructor::newInstance}.
* If no {@linkplain System#getSecurityManager() security manager} is present,
* or no domains are provided, then this method simply calls
* {@code cons.newInstance()}. Otherwise, it invokes the provided constructor
* with privileges at the intersection of the current context and the provided
* protection domains.
*
* @param cons A constructor obtained from {@code
* newConstructorForSerialization} or {@code
* newConstructorForExternalization}.
* @param domains An array of protection domains that limit the privileges
* with which the constructor is invoked. Can be {@code null}
* or empty, in which case privileges are only limited by the
* {@linkplain AccessController#getContext() current context}.
*
* @return A new object built from the provided constructor.
*
* @throws NullPointerException if {@code cons} is {@code null}.
* @throws InstantiationException if thrown by {@code cons.newInstance()}.
* @throws InvocationTargetException if thrown by {@code cons.newInstance()}.
* @throws IllegalAccessException if thrown by {@code cons.newInstance()}.
*/
public final Object newInstanceForSerialization(Constructor<?> cons,
ProtectionDomain[] domains)
throws InstantiationException, InvocationTargetException, IllegalAccessException
{
SecurityManager sm = System.getSecurityManager();
if (sm == null || domains == null || domains.length == 0) {
return cons.newInstance();
} else {
JavaSecurityAccess jsa = SharedSecrets.getJavaSecurityAccess();
PrivilegedAction<?> pea = () -> {
try {
return cons.newInstance();
} catch (InstantiationException
| InvocationTargetException
| IllegalAccessException x) {
throw new UndeclaredThrowableException(x);
}
}; // Can't use PrivilegedExceptionAction with jsa
try {
return jsa.doIntersectionPrivilege(pea,
AccessController.getContext(),
new AccessControlContext(domains));
} catch (UndeclaredThrowableException x) {
Throwable cause = x.getCause();
if (cause instanceof InstantiationException)
throw (InstantiationException) cause;
if (cause instanceof InvocationTargetException)
throw (InvocationTargetException) cause;
if (cause instanceof IllegalAccessException)
throw (IllegalAccessException) cause;
// not supposed to happen
throw x;
}
}
}
/**
* Returns a direct MethodHandle for the {@code readObjectNoData} method on
* a Serializable class.
@ -224,4 +289,3 @@ public class ReflectionFactory {
}
}
}

View File

@ -36,9 +36,11 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.LongAdder;
import javax.net.ssl.SSLEngineResult;
@ -165,6 +167,11 @@ public class SerialFilterTest implements Serializable {
interfaces, (p, m, args) -> p);
Runnable runnable = (Runnable & Serializable) SerialFilterTest::noop;
List<Class<?>> classList = new ArrayList<>();
classList.add(HashSet.class);
classList.addAll(Collections.nCopies(21, Map.Entry[].class));
Object[][] objects = {
{ null, 0, -1, 0, 0, 0,
Arrays.asList()}, // no callback, no values
@ -184,8 +191,7 @@ public class SerialFilterTest implements Serializable {
objArray.getClass(),
SerialFilterTest.class,
java.lang.invoke.SerializedLambda.class)},
{ deepHashSet(10), 48, -1, 50, 11, 619,
Arrays.asList(HashSet.class)},
{ deepHashSet(10), 69, 4, 50, 11, 619, classList },
{ proxy.getClass(), 3, -1, 2, 2, 112,
Arrays.asList(Runnable.class,
java.lang.reflect.Proxy.class,

View File

@ -34,7 +34,7 @@ import jdk.test.lib.RandomFactory;
/*
* @test
* @bug 8050374
* @bug 8050374 8181048
* @key randomness
* @summary This test validates signature verification
* Signature.verify(byte[], int, int). The test uses RandomFactory to
@ -106,18 +106,25 @@ public class Offsets {
Signature signature = Signature.getInstance(algorithm, provider);
String keyAlgo;
int keySize = 2048;
if (algorithm.contains("RSA")) {
keyAlgo = "RSA";
} else if (algorithm.contains("ECDSA")) {
keyAlgo = "EC";
keySize = 256;
} else if (algorithm.contains("DSA")) {
keyAlgo = "DSA";
if (algorithm.startsWith("SHAwith") ||
algorithm.startsWith("SHA1with")) {
keySize = 1024;
}
} else {
throw new RuntimeException("Test doesn't support this signature "
+ "algorithm: " + algorithm);
}
KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyAlgo, provider);
kpg.initialize(keySize);
KeyPair kp = kpg.generateKeyPair();
PublicKey pubkey = kp.getPublic();
PrivateKey privkey = kp.getPrivate();

View File

@ -32,7 +32,7 @@ import java.util.Arrays;
/*
* @test
* @bug 8050374
* @bug 8050374 8181048
* @summary Verify a chain of signed objects
*/
public class Chain {
@ -97,22 +97,28 @@ public class Chain {
final Provider provider;
final KeyAlg keyAlg;
final SigAlg sigAlg;
final int keySize;
Test(SigAlg sigAlg, KeyAlg keyAlg, Provider privider) {
this.provider = privider;
Test(SigAlg sigAlg, KeyAlg keyAlg, Provider provider) {
this(sigAlg, keyAlg, provider, -1);
}
Test(SigAlg sigAlg, KeyAlg keyAlg, Provider provider, int keySize) {
this.provider = provider;
this.keyAlg = keyAlg;
this.sigAlg = sigAlg;
this.keySize = keySize;
}
}
private static final Test[] tests = {
new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Default),
new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Default, 1024),
new Test(SigAlg.MD2withRSA, KeyAlg.RSA, Provider.Default),
new Test(SigAlg.MD5withRSA, KeyAlg.RSA, Provider.Default),
new Test(SigAlg.SHA1withRSA, KeyAlg.RSA, Provider.Default),
new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Sun),
new Test(SigAlg.SHA224withDSA, KeyAlg.DSA, Provider.Sun),
new Test(SigAlg.SHA256withDSA, KeyAlg.DSA, Provider.Sun),
new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Sun, 1024),
new Test(SigAlg.SHA224withDSA, KeyAlg.DSA, Provider.Sun, 2048),
new Test(SigAlg.SHA256withDSA, KeyAlg.DSA, Provider.Sun, 2048),
};
private static final String str = "to-be-signed";
@ -148,6 +154,9 @@ public class Chain {
kpg = KeyPairGenerator.getInstance(test.keyAlg.name);
}
for (int j=0; j < N; j++) {
if (test.keySize != -1) {
kpg.initialize(test.keySize);
}
KeyPair kp = kpg.genKeyPair();
KeyPair anotherKp = kpg.genKeyPair();
privKeys[j] = kp.getPrivate();

View File

@ -0,0 +1,333 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8159377
* @library /lib/testlibrary
* @summary Tests ObjectFilter on default agent
* @author Harsha Wardhana B
* @modules java.management
* @build jdk.testlibrary.* DefaultAgentFilterTest
* @run main/othervm/timeout=600 -XX:+UsePerfData DefaultAgentFilterTest
*/
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.InvalidClassException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.net.BindException;
import java.rmi.UnmarshalException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import jdk.testlibrary.ProcessTools;
import jdk.testlibrary.Utils;
public class DefaultAgentFilterTest {
public static class MyTestObject implements Serializable {
String a;
int id;
}
public interface TestMBean {
public void op1(HashSet<Object> params);
public void op2(String s, HashSet<String> params);
public void op3(MyTestObject obj, String s, HashMap<String, String> param);
}
public static class Test implements TestMBean {
@Override
public void op1(HashSet<Object> params) {
System.out.println("Invoked op1");
}
@Override
public void op2(String s, HashSet<String> params) {
System.out.println("Invoked op2");
}
@Override
public void op3(MyTestObject obj, String s, HashMap<String, String> param) {
System.out.println("Invoked op3");
}
}
private static class TestAppRun implements AutoCloseable {
private Process p;
private final ProcessBuilder pb;
private final String name;
private final AtomicBoolean started = new AtomicBoolean(false);
private volatile long pid = -1;
public TestAppRun(ProcessBuilder pb, String name) {
this.pb = pb;
this.name = name;
}
public synchronized void start() throws Exception {
if (started.compareAndSet(false, true)) {
try {
AtomicBoolean error = new AtomicBoolean(false);
AtomicBoolean bindError = new AtomicBoolean(false);
p = ProcessTools.startProcess(
TEST_APP_NAME + "{" + name + "}",
pb,
(line) -> {
if (line.toLowerCase().contains("exception")
|| line.toLowerCase().contains("error")) {
error.set(true);
}
bindError.set(line.toLowerCase().contains("bindexception"));
return true;
});
if (bindError.get()) {
throw new BindException("Process could not be started");
} else if (error.get()) {
throw new RuntimeException();
}
pid = p.pid();
} catch (Exception ex) {
if (p != null) {
p.destroy();
p.waitFor();
}
throw ex;
}
}
}
public long getPid() {
return pid;
}
public synchronized void stop()
throws IOException, InterruptedException {
if (started.compareAndSet(true, false)) {
p.getOutputStream().write(0);
p.getOutputStream().flush();
int ec = p.waitFor();
if (ec != 0) {
StringBuilder msg = new StringBuilder();
msg.append("Test application '").append(name);
msg.append("' failed with exit code: ");
msg.append(ec);
System.err.println(msg);
}
}
}
@Override
public void close() throws Exception {
stop();
}
}
private static final String TEST_APP_NAME = "TestApp";
private static void testDefaultAgent(String propertyFile) throws Exception {
int port = Utils.getFreePort();
String propFile = System.getProperty("test.src") + File.separator + propertyFile;
List<String> pbArgs = new ArrayList<>(Arrays.asList(
"-cp",
System.getProperty("test.class.path"),
"-XX:+UsePerfData"
));
String[] args = new String[]{
"-Dcom.sun.management.jmxremote.port=" + port,
"-Dcom.sun.management.jmxremote.authenticate=false",
"-Dcom.sun.management.jmxremote.ssl=false",
"-Dcom.sun.management.config.file=" + propFile
};
pbArgs.addAll(Arrays.asList(args));
pbArgs.add(TEST_APP_NAME);
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
pbArgs.toArray(new String[pbArgs.size()])
);
try (TestAppRun s = new TestAppRun(pb, DefaultAgentFilterTest.class.getSimpleName())) {
s.start();
JMXServiceURL url = testConnect(port);
testMBeanOperations(url);
}
}
private static JMXServiceURL testConnect(int port) throws Exception {
EOFException lastException = null;
JMXServiceURL url = null;
// factor adjusted timeout (5 seconds) for the RMI to become available
long timeout = System.currentTimeMillis() + Utils.adjustTimeout(5000);
do {
lastException = null;
try {
Registry registry = LocateRegistry.getRegistry(port);
String[] relist = registry.list();
for (int i = 0; i < relist.length; ++i) {
System.out.println("Got registry: " + relist[i]);
}
String jmxUrlStr = String.format(
"service:jmx:rmi:///jndi/rmi://localhost:%d/jmxrmi",
port);
url = new JMXServiceURL(jmxUrlStr);
try (JMXConnector c = JMXConnectorFactory.connect(url, null)) {
MBeanServerConnection conn = c.getMBeanServerConnection();
ObjectName name = new ObjectName("jtreg:type=Test");
conn.createMBean(Test.class.getName(), name);
}
} catch (Exception ex) {
if (ex instanceof EOFException) {
lastException = (EOFException) ex;
System.out.println("Error establishing RMI connection. Retrying in 500ms.");
Thread.sleep(500);
} else {
throw ex;
}
}
} while (lastException != null && System.currentTimeMillis() < timeout);
if (lastException != null) {
throw lastException;
}
return url;
}
public static void main(String[] args) throws Exception {
System.out.println("---" + DefaultAgentFilterTest.class.getName() + "-main: starting ...");
boolean retry = false;
do {
try {
// blacklist String
testDefaultAgent("mgmt1.properties");
System.out.println("----\tTest FAILED !!");
throw new RuntimeException("---" + DefaultAgentFilterTest.class.getName() + " - No exception reported");
} catch (Exception ex) {
if (ex instanceof InvocationTargetException) {
if (ex.getCause() instanceof BindException
|| ex.getCause() instanceof java.rmi.ConnectException) {
System.out.println("Failed to allocate ports. Retrying ...");
retry = true;
}
} else if (ex instanceof InvalidClassException) {
System.out.println("----\tTest PASSED !!");
} else if (ex instanceof UnmarshalException
&& ((UnmarshalException) ex).getCause() instanceof InvalidClassException) {
System.out.println("----\tTest PASSED !!");
} else {
System.out.println(ex);
System.out.println("----\tTest FAILED !!");
throw ex;
}
}
} while (retry);
retry = false;
do {
try {
// blacklist non-existent class
testDefaultAgent("mgmt2.properties");
System.out.println("----\tTest PASSED !!");
} catch (Exception ex) {
if (ex instanceof InvocationTargetException) {
if (ex.getCause() instanceof BindException
|| ex.getCause() instanceof java.rmi.ConnectException) {
System.out.println("Failed to allocate ports. Retrying ...");
retry = true;
}
} else {
System.out.println(ex);
System.out.println("----\tTest FAILED !!");
throw ex;
}
}
} while (retry);
System.out.println("---" + DefaultAgentFilterTest.class.getName() + "-main: finished ...");
}
private static void testMBeanOperations(JMXServiceURL serverUrl) throws Exception {
Map<String, Object> clientEnv = new HashMap<>(1);
ObjectName name = new ObjectName("jtreg:type=Test");
try (JMXConnector client = JMXConnectorFactory.connect(serverUrl, clientEnv)) {
MBeanServerConnection conn = client.getMBeanServerConnection();
HashSet<String> set = new HashSet<>();
set.add("test1");
set.add("test2");
String a = "A";
Object[] params1 = {set};
String[] sig1 = {HashSet.class.getName()};
conn.invoke(name, "op1", params1, sig1);
Object[] params2 = {a, set};
String[] sig2 = {String.class.getName(), HashSet.class.getName()};
conn.invoke(name, "op2", params2, sig2);
HashMap<String, String> map = new HashMap<>();
map.put("a", "A");
map.put("b", "B");
Object[] params3 = {new MyTestObject(), a, map};
String[] sig3 = {MyTestObject.class.getName(), String.class.getName(),
HashMap.class.getName()};
conn.invoke(name, "op3", params3, sig3);
}
}
}
class TestApp {
private static void doSomething() throws IOException {
int r = System.in.read();
System.out.println("read: " + r);
}
public static void main(String args[]) throws Exception {
System.out.println("main enter");
System.out.flush();
doSomething();
System.out.println("main exit");
}
}

Some files were not shown because too many files have changed in this diff Show More