Merge
This commit is contained in:
commit
4e93f8fc9f
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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) :
|
||||
|
@ -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;
|
||||
|
@ -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++) {
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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..."},
|
||||
};
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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); \
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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++];
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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>.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user