Merge
This commit is contained in:
commit
2af47c361c
@ -375,6 +375,7 @@ TOOLS = \
|
||||
com/sun/tools/javadoc \
|
||||
com/sun/tools/javah \
|
||||
com/sun/tools/javap \
|
||||
com/sun/tools/jdeps \
|
||||
com/sun/tools/corba \
|
||||
com/sun/tools/internal/xjc \
|
||||
com/sun/tools/internal/ws \
|
||||
@ -457,6 +458,7 @@ NOTJRETOOLS = \
|
||||
javadoc$(EXE_SUFFIX) \
|
||||
javah$(EXE_SUFFIX) \
|
||||
javap$(EXE_SUFFIX) \
|
||||
jdeps$(EXE_SUFFIX) \
|
||||
jcmd$(EXE_SUFFIX) \
|
||||
jdb$(EXE_SUFFIX) \
|
||||
jps$(EXE_SUFFIX) \
|
||||
@ -564,6 +566,7 @@ $(NOT_RT_JAR_LIST): FRC
|
||||
$(ECHO) "sun/tools/javac/" >> $@
|
||||
$(ECHO) "com/sun/tools/classfile/" >> $@
|
||||
$(ECHO) "com/sun/tools/javap/" >> $@
|
||||
$(ECHO) "com/sun/tools/jdeps/" >> $@
|
||||
$(ECHO) "sun/tools/jcmd/" >> $@
|
||||
$(ECHO) "sun/tools/jconsole/" >> $@
|
||||
$(ECHO) "sun/tools/jps/" >> $@
|
||||
|
@ -76,7 +76,7 @@ ATTACH_PKGS = com.sun.tools.attach \
|
||||
|
||||
JCONSOLE_PKGS = com.sun.tools.jconsole
|
||||
|
||||
TREEAPI_PKGS = com.sunsource.doctree \
|
||||
TREEAPI_PKGS = com.sun.source.doctree \
|
||||
com.sun.source.tree \
|
||||
com.sun.source.util
|
||||
|
||||
|
@ -63,6 +63,7 @@ $(call make-launcher, javac, com.sun.tools.javac.Main, , )
|
||||
$(call make-launcher, javadoc, com.sun.tools.javadoc.Main, , )
|
||||
$(call make-launcher, javah, com.sun.tools.javah.Main, , )
|
||||
$(call make-launcher, javap, com.sun.tools.javap.Main, , )
|
||||
$(call make-launcher, jdeps, com.sun.tools.jdeps.Main, , )
|
||||
$(call make-launcher, jcmd, sun.tools.jcmd.JCmd, , )
|
||||
$(call make-launcher, jconsole, sun.tools.jconsole.JConsole, \
|
||||
-J-Djconsole.showOutputViewer, )
|
||||
|
@ -62,6 +62,10 @@ ifeq ($(PROGRAM),javap)
|
||||
WILDCARDS=true
|
||||
NEVER_ACT_AS_SERVER_CLASS_MACHINE=true
|
||||
endif
|
||||
ifeq ($(PROGRAM),jdeps)
|
||||
WILDCARDS=true
|
||||
NEVER_ACT_AS_SERVER_CLASS_MACHINE=true
|
||||
endif
|
||||
ifeq ($(PROGRAM),javah)
|
||||
WILDCARDS=true
|
||||
NEVER_ACT_AS_SERVER_CLASS_MACHINE=true
|
||||
|
@ -267,6 +267,11 @@ $(eval $(call SetupLauncher,javap,\
|
||||
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
|
||||
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javap.Main"$(COMMA) }'))
|
||||
|
||||
$(eval $(call SetupLauncher,jdeps,\
|
||||
-DEXPAND_CLASSPATH_WILDCARDS \
|
||||
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
|
||||
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.jdeps.Main"$(COMMA) }'))
|
||||
|
||||
BUILD_LAUNCHER_jconsole_CFLAGS_windows:=-DJAVAW
|
||||
BUILD_LAUNCHER_jconsole_LDFLAGS_windows:=user32.lib
|
||||
|
||||
|
@ -738,6 +738,7 @@ TOOLS_JAR_INCLUDES := \
|
||||
com/sun/tools/javadoc \
|
||||
com/sun/tools/javah \
|
||||
com/sun/tools/javap \
|
||||
com/sun/tools/jdeps \
|
||||
com/sun/tools/corba \
|
||||
com/sun/tools/internal/xjc \
|
||||
com/sun/tools/internal/ws \
|
||||
|
@ -100,6 +100,7 @@ NOT_JRE_BIN_FILES := \
|
||||
javadoc$(EXE_SUFFIX) \
|
||||
javah$(EXE_SUFFIX) \
|
||||
javap$(EXE_SUFFIX) \
|
||||
jdeps$(EXE_SUFFIX) \
|
||||
jcmd$(EXE_SUFFIX) \
|
||||
jdb$(EXE_SUFFIX) \
|
||||
jps$(EXE_SUFFIX) \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -30,6 +30,7 @@ import java.security.spec.*;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* This class implements the AES algorithm in its various modes
|
||||
@ -127,6 +128,21 @@ abstract class AESCipher extends CipherSpi {
|
||||
super(32, "CFB", "NOPADDING");
|
||||
}
|
||||
}
|
||||
public static final class AES128_GCM_NoPadding extends OidImpl {
|
||||
public AES128_GCM_NoPadding() {
|
||||
super(16, "GCM", "NOPADDING");
|
||||
}
|
||||
}
|
||||
public static final class AES192_GCM_NoPadding extends OidImpl {
|
||||
public AES192_GCM_NoPadding() {
|
||||
super(24, "GCM", "NOPADDING");
|
||||
}
|
||||
}
|
||||
public static final class AES256_GCM_NoPadding extends OidImpl {
|
||||
public AES256_GCM_NoPadding() {
|
||||
super(32, "GCM", "NOPADDING");
|
||||
}
|
||||
}
|
||||
|
||||
// utility method used by AESCipher and AESWrapCipher
|
||||
static final void checkKeySize(Key key, int fixedKeySize)
|
||||
@ -531,4 +547,79 @@ abstract class AESCipher extends CipherSpi {
|
||||
return core.unwrap(wrappedKey, wrappedKeyAlgorithm,
|
||||
wrappedKeyType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Continues a multi-part update of the Additional Authentication
|
||||
* Data (AAD), using a subset of the provided buffer.
|
||||
* <p>
|
||||
* Calls to this method provide AAD to the cipher when operating in
|
||||
* modes such as AEAD (GCM/CCM). If this cipher is operating in
|
||||
* either GCM or CCM mode, all AAD must be supplied before beginning
|
||||
* operations on the ciphertext (via the {@code update} and {@code
|
||||
* doFinal} methods).
|
||||
*
|
||||
* @param src the buffer containing the AAD
|
||||
* @param offset the offset in {@code src} where the AAD input starts
|
||||
* @param len the number of AAD bytes
|
||||
*
|
||||
* @throws IllegalStateException if this cipher is in a wrong state
|
||||
* (e.g., has not been initialized), does not accept AAD, or if
|
||||
* operating in either GCM or CCM mode and one of the {@code update}
|
||||
* methods has already been called for the active
|
||||
* encryption/decryption operation
|
||||
* @throws UnsupportedOperationException if this method
|
||||
* has not been overridden by an implementation
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
protected void engineUpdateAAD(byte[] src, int offset, int len) {
|
||||
core.updateAAD(src, offset, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Continues a multi-part update of the Additional Authentication
|
||||
* Data (AAD).
|
||||
* <p>
|
||||
* Calls to this method provide AAD to the cipher when operating in
|
||||
* modes such as AEAD (GCM/CCM). If this cipher is operating in
|
||||
* either GCM or CCM mode, all AAD must be supplied before beginning
|
||||
* operations on the ciphertext (via the {@code update} and {@code
|
||||
* doFinal} methods).
|
||||
* <p>
|
||||
* All {@code src.remaining()} bytes starting at
|
||||
* {@code src.position()} are processed.
|
||||
* Upon return, the input buffer's position will be equal
|
||||
* to its limit; its limit will not have changed.
|
||||
*
|
||||
* @param src the buffer containing the AAD
|
||||
*
|
||||
* @throws IllegalStateException if this cipher is in a wrong state
|
||||
* (e.g., has not been initialized), does not accept AAD, or if
|
||||
* operating in either GCM or CCM mode and one of the {@code update}
|
||||
* methods has already been called for the active
|
||||
* encryption/decryption operation
|
||||
* @throws UnsupportedOperationException if this method
|
||||
* has not been overridden by an implementation
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
protected void engineUpdateAAD(ByteBuffer src) {
|
||||
if (src != null) {
|
||||
int aadLen = src.limit() - src.position();
|
||||
if (aadLen != 0) {
|
||||
if (src.hasArray()) {
|
||||
int aadOfs = src.arrayOffset() + src.position();
|
||||
core.updateAAD(src.array(), aadOfs, aadLen);
|
||||
src.position(src.limit());
|
||||
} else {
|
||||
byte[] aad = new byte[aadLen];
|
||||
src.get(aad);
|
||||
core.updateAAD(aad, 0, aadLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -106,7 +106,7 @@ public final class AESKeyGenerator extends KeyGeneratorSpi {
|
||||
SecretKeySpec aesKey = null;
|
||||
|
||||
if (this.random == null) {
|
||||
this.random = SunJCE.RANDOM;
|
||||
this.random = SunJCE.getRandom();
|
||||
}
|
||||
|
||||
byte[] keyBytes = new byte[keySize];
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@ -104,7 +104,7 @@ public final class BlowfishKeyGenerator extends KeyGeneratorSpi {
|
||||
*/
|
||||
protected SecretKey engineGenerateKey() {
|
||||
if (this.random == null) {
|
||||
this.random = SunJCE.RANDOM;
|
||||
this.random = SunJCE.getRandom();
|
||||
}
|
||||
|
||||
byte[] keyBytes = new byte[this.keysize];
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
import java.security.*;
|
||||
@ -59,7 +60,7 @@ final class CipherCore {
|
||||
private byte[] buffer = null;
|
||||
|
||||
/*
|
||||
* internal buffer
|
||||
* block size of cipher in bytes
|
||||
*/
|
||||
private int blockSize = 0;
|
||||
|
||||
@ -76,10 +77,12 @@ final class CipherCore {
|
||||
/*
|
||||
* minimum number of bytes in the buffer required for
|
||||
* FeedbackCipher.encryptFinal()/decryptFinal() call.
|
||||
* update() must buffer this many bytes before before starting
|
||||
* update() must buffer this many bytes before starting
|
||||
* to encrypt/decrypt data.
|
||||
* currently, only CTS mode has a non-zero value due to its special
|
||||
* handling on the last two blocks (the last one may be incomplete).
|
||||
* currently, only the following cases have non-zero values:
|
||||
* 1) CTS mode - due to its special handling on the last two blocks
|
||||
* (the last one may be incomplete).
|
||||
* 2) GCM mode + decryption - due to its trailing tag bytes
|
||||
*/
|
||||
private int minBytes = 0;
|
||||
|
||||
@ -121,6 +124,24 @@ final class CipherCore {
|
||||
private static final int PCBC_MODE = 4;
|
||||
private static final int CTR_MODE = 5;
|
||||
private static final int CTS_MODE = 6;
|
||||
private static final int GCM_MODE = 7;
|
||||
|
||||
/*
|
||||
* variables used for performing the GCM (key+iv) uniqueness check.
|
||||
* To use GCM mode safely, the cipher object must be re-initialized
|
||||
* with a different combination of key + iv values for each
|
||||
* encryption operation. However, checking all past key + iv values
|
||||
* isn't feasible. Thus, we only do a per-instance check of the
|
||||
* key + iv values used in previous encryption.
|
||||
* For decryption operations, no checking is necessary.
|
||||
* NOTE: this key+iv check have to be done inside CipherCore class
|
||||
* since CipherCore class buffers potential tag bytes in GCM mode
|
||||
* and may not call GaloisCounterMode when there isn't sufficient
|
||||
* input to process.
|
||||
*/
|
||||
private boolean requireReinit = false;
|
||||
private byte[] lastEncKey = null;
|
||||
private byte[] lastEncIv = null;
|
||||
|
||||
/**
|
||||
* Creates an instance of CipherCore with default ECB mode and
|
||||
@ -149,7 +170,7 @@ final class CipherCore {
|
||||
* @param mode the cipher mode
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if the requested cipher mode does
|
||||
* not exist
|
||||
* not exist for this cipher
|
||||
*/
|
||||
void setMode(String mode) throws NoSuchAlgorithmException {
|
||||
if (mode == null)
|
||||
@ -165,30 +186,34 @@ final class CipherCore {
|
||||
if (modeUpperCase.equals("CBC")) {
|
||||
cipherMode = CBC_MODE;
|
||||
cipher = new CipherBlockChaining(rawImpl);
|
||||
}
|
||||
else if (modeUpperCase.equals("CTS")) {
|
||||
} else if (modeUpperCase.equals("CTS")) {
|
||||
cipherMode = CTS_MODE;
|
||||
cipher = new CipherTextStealing(rawImpl);
|
||||
minBytes = blockSize+1;
|
||||
padding = null;
|
||||
}
|
||||
else if (modeUpperCase.equals("CTR")) {
|
||||
} else if (modeUpperCase.equals("CTR")) {
|
||||
cipherMode = CTR_MODE;
|
||||
cipher = new CounterMode(rawImpl);
|
||||
unitBytes = 1;
|
||||
padding = null;
|
||||
}
|
||||
else if (modeUpperCase.startsWith("CFB")) {
|
||||
} else if (modeUpperCase.startsWith("GCM")) {
|
||||
// can only be used for block ciphers w/ 128-bit block size
|
||||
if (blockSize != 16) {
|
||||
throw new NoSuchAlgorithmException
|
||||
("GCM mode can only be used for AES cipher");
|
||||
}
|
||||
cipherMode = GCM_MODE;
|
||||
cipher = new GaloisCounterMode(rawImpl);
|
||||
padding = null;
|
||||
} else if (modeUpperCase.startsWith("CFB")) {
|
||||
cipherMode = CFB_MODE;
|
||||
unitBytes = getNumOfUnit(mode, "CFB".length(), blockSize);
|
||||
cipher = new CipherFeedback(rawImpl, unitBytes);
|
||||
}
|
||||
else if (modeUpperCase.startsWith("OFB")) {
|
||||
} else if (modeUpperCase.startsWith("OFB")) {
|
||||
cipherMode = OFB_MODE;
|
||||
unitBytes = getNumOfUnit(mode, "OFB".length(), blockSize);
|
||||
cipher = new OutputFeedback(rawImpl, unitBytes);
|
||||
}
|
||||
else if (modeUpperCase.equals("PCBC")) {
|
||||
} else if (modeUpperCase.equals("PCBC")) {
|
||||
cipherMode = PCBC_MODE;
|
||||
cipher = new PCBC(rawImpl);
|
||||
}
|
||||
@ -219,6 +244,7 @@ final class CipherCore {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the padding mechanism of this cipher.
|
||||
*
|
||||
@ -242,11 +268,27 @@ final class CipherCore {
|
||||
+ " not implemented");
|
||||
}
|
||||
if ((padding != null) &&
|
||||
((cipherMode == CTR_MODE) || (cipherMode == CTS_MODE))) {
|
||||
((cipherMode == CTR_MODE) || (cipherMode == CTS_MODE)
|
||||
|| (cipherMode == GCM_MODE))) {
|
||||
padding = null;
|
||||
throw new NoSuchPaddingException
|
||||
((cipherMode == CTR_MODE? "CTR":"CTS") +
|
||||
" mode must be used with NoPadding");
|
||||
String modeStr = null;
|
||||
switch (cipherMode) {
|
||||
case CTR_MODE:
|
||||
modeStr = "CTR";
|
||||
break;
|
||||
case GCM_MODE:
|
||||
modeStr = "GCM";
|
||||
break;
|
||||
case CTS_MODE:
|
||||
modeStr = "CTS";
|
||||
break;
|
||||
default:
|
||||
// should never happen
|
||||
}
|
||||
if (modeStr != null) {
|
||||
throw new NoSuchPaddingException
|
||||
(modeStr + " mode must be used with NoPadding");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,7 +299,7 @@ final class CipherCore {
|
||||
* <code>inputLen</code> (in bytes).
|
||||
*
|
||||
* <p>This call takes into account any unprocessed (buffered) data from a
|
||||
* previous <code>update</code> call, and padding.
|
||||
* previous <code>update</code> call, padding, and AEAD tagging.
|
||||
*
|
||||
* <p>The actual output length of the next <code>update</code> or
|
||||
* <code>doFinal</code> call may be smaller than the length returned by
|
||||
@ -270,23 +312,60 @@ final class CipherCore {
|
||||
int getOutputSize(int inputLen) {
|
||||
int totalLen = buffered + inputLen;
|
||||
|
||||
if (padding == null)
|
||||
return totalLen;
|
||||
// GCM: this call may be for either update() or doFinal(), so have to
|
||||
// return the larger value of both
|
||||
// Encryption: based on doFinal value: inputLen + tag
|
||||
// Decryption: based on update value: inputLen
|
||||
if (!decrypting && (cipherMode == GCM_MODE)) {
|
||||
return (totalLen + ((GaloisCounterMode) cipher).getTagLen());
|
||||
}
|
||||
|
||||
if (decrypting)
|
||||
if (padding == null) {
|
||||
return totalLen;
|
||||
}
|
||||
|
||||
if (decrypting) {
|
||||
return totalLen;
|
||||
}
|
||||
|
||||
if (unitBytes != blockSize) {
|
||||
if (totalLen < diffBlocksize)
|
||||
if (totalLen < diffBlocksize) {
|
||||
return diffBlocksize;
|
||||
else
|
||||
} else {
|
||||
return (totalLen + blockSize -
|
||||
((totalLen - diffBlocksize) % blockSize));
|
||||
}
|
||||
} else {
|
||||
return totalLen + padding.padLength(totalLen);
|
||||
}
|
||||
}
|
||||
|
||||
private int getOutputSizeByOperation(int inputLen, boolean isDoFinal) {
|
||||
int totalLen = 0;
|
||||
switch (cipherMode) {
|
||||
case GCM_MODE:
|
||||
totalLen = buffered + inputLen;
|
||||
if (isDoFinal) {
|
||||
int tagLen = ((GaloisCounterMode) cipher).getTagLen();
|
||||
if (decrypting) {
|
||||
// need to get the actual value from cipher??
|
||||
// deduct tagLen
|
||||
totalLen -= tagLen;
|
||||
} else {
|
||||
totalLen += tagLen;
|
||||
}
|
||||
}
|
||||
if (totalLen < 0) {
|
||||
totalLen = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
totalLen = getOutputSize(inputLen);
|
||||
break;
|
||||
}
|
||||
return totalLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the initialization vector (IV) in a new buffer.
|
||||
*
|
||||
@ -318,34 +397,49 @@ final class CipherCore {
|
||||
* does not use any parameters.
|
||||
*/
|
||||
AlgorithmParameters getParameters(String algName) {
|
||||
if (cipherMode == ECB_MODE) {
|
||||
return null;
|
||||
}
|
||||
AlgorithmParameters params = null;
|
||||
if (cipherMode == ECB_MODE) return null;
|
||||
AlgorithmParameterSpec spec;
|
||||
byte[] iv = getIV();
|
||||
if (iv != null) {
|
||||
AlgorithmParameterSpec ivSpec;
|
||||
if (algName.equals("RC2")) {
|
||||
RC2Crypt rawImpl = (RC2Crypt) cipher.getEmbeddedCipher();
|
||||
ivSpec = new RC2ParameterSpec(rawImpl.getEffectiveKeyBits(),
|
||||
iv);
|
||||
if (iv == null) {
|
||||
// generate spec using default value
|
||||
if (cipherMode == GCM_MODE) {
|
||||
iv = new byte[GaloisCounterMode.DEFAULT_IV_LEN];
|
||||
} else {
|
||||
ivSpec = new IvParameterSpec(iv);
|
||||
}
|
||||
try {
|
||||
params = AlgorithmParameters.getInstance(algName, "SunJCE");
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
// should never happen
|
||||
throw new RuntimeException("Cannot find " + algName +
|
||||
" AlgorithmParameters implementation in SunJCE provider");
|
||||
} catch (NoSuchProviderException nspe) {
|
||||
// should never happen
|
||||
throw new RuntimeException("Cannot find SunJCE provider");
|
||||
}
|
||||
try {
|
||||
params.init(ivSpec);
|
||||
} catch (InvalidParameterSpecException ipse) {
|
||||
// should never happen
|
||||
throw new RuntimeException("IvParameterSpec not supported");
|
||||
iv = new byte[blockSize];
|
||||
}
|
||||
SunJCE.getRandom().nextBytes(iv);
|
||||
}
|
||||
if (cipherMode == GCM_MODE) {
|
||||
algName = "GCM";
|
||||
spec = new GCMParameterSpec
|
||||
(((GaloisCounterMode) cipher).getTagLen()*8, iv);
|
||||
} else {
|
||||
if (algName.equals("RC2")) {
|
||||
RC2Crypt rawImpl = (RC2Crypt) cipher.getEmbeddedCipher();
|
||||
spec = new RC2ParameterSpec
|
||||
(rawImpl.getEffectiveKeyBits(), iv);
|
||||
} else {
|
||||
spec = new IvParameterSpec(iv);
|
||||
}
|
||||
}
|
||||
try {
|
||||
params = AlgorithmParameters.getInstance(algName, "SunJCE");
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
// should never happen
|
||||
throw new RuntimeException("Cannot find " + algName +
|
||||
" AlgorithmParameters implementation in SunJCE provider");
|
||||
} catch (NoSuchProviderException nspe) {
|
||||
// should never happen
|
||||
throw new RuntimeException("Cannot find SunJCE provider");
|
||||
}
|
||||
try {
|
||||
params.init(spec);
|
||||
} catch (InvalidParameterSpecException ipse) {
|
||||
// should never happen
|
||||
throw new RuntimeException(spec.getClass() + " not supported");
|
||||
}
|
||||
return params;
|
||||
}
|
||||
@ -420,44 +514,63 @@ final class CipherCore {
|
||||
|| (opmode == Cipher.UNWRAP_MODE);
|
||||
|
||||
byte[] keyBytes = getKeyBytes(key);
|
||||
|
||||
byte[] ivBytes;
|
||||
if (params == null) {
|
||||
ivBytes = null;
|
||||
} else if (params instanceof IvParameterSpec) {
|
||||
ivBytes = ((IvParameterSpec)params).getIV();
|
||||
if ((ivBytes == null) || (ivBytes.length != blockSize)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Wrong IV length: must be " + blockSize +
|
||||
" bytes long");
|
||||
int tagLen = -1;
|
||||
byte[] ivBytes = null;
|
||||
if (params != null) {
|
||||
if (cipherMode == GCM_MODE) {
|
||||
if (params instanceof GCMParameterSpec) {
|
||||
tagLen = ((GCMParameterSpec)params).getTLen();
|
||||
if (tagLen < 96 || tagLen > 128 || ((tagLen & 0x07) != 0)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Unsupported TLen value; must be one of " +
|
||||
"{128, 120, 112, 104, 96}");
|
||||
}
|
||||
tagLen = tagLen >> 3;
|
||||
ivBytes = ((GCMParameterSpec)params).getIV();
|
||||
} else {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Unsupported parameter: " + params);
|
||||
}
|
||||
} else {
|
||||
if (params instanceof IvParameterSpec) {
|
||||
ivBytes = ((IvParameterSpec)params).getIV();
|
||||
if ((ivBytes == null) || (ivBytes.length != blockSize)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Wrong IV length: must be " + blockSize +
|
||||
" bytes long");
|
||||
}
|
||||
} else if (params instanceof RC2ParameterSpec) {
|
||||
ivBytes = ((RC2ParameterSpec)params).getIV();
|
||||
if ((ivBytes != null) && (ivBytes.length != blockSize)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Wrong IV length: must be " + blockSize +
|
||||
" bytes long");
|
||||
}
|
||||
} else {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Unsupported parameter: " + params);
|
||||
}
|
||||
}
|
||||
} else if (params instanceof RC2ParameterSpec) {
|
||||
ivBytes = ((RC2ParameterSpec)params).getIV();
|
||||
if ((ivBytes != null) && (ivBytes.length != blockSize)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Wrong IV length: must be " + blockSize +
|
||||
" bytes long");
|
||||
}
|
||||
} else {
|
||||
throw new InvalidAlgorithmParameterException("Wrong parameter "
|
||||
+ "type: IV "
|
||||
+ "expected");
|
||||
}
|
||||
|
||||
if (cipherMode == ECB_MODE) {
|
||||
if (ivBytes != null) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("ECB mode cannot use IV");
|
||||
}
|
||||
} else if (ivBytes == null) {
|
||||
} else if (ivBytes == null) {
|
||||
if (decrypting) {
|
||||
throw new InvalidAlgorithmParameterException("Parameters "
|
||||
+ "missing");
|
||||
}
|
||||
|
||||
if (random == null) {
|
||||
random = SunJCE.RANDOM;
|
||||
random = SunJCE.getRandom();
|
||||
}
|
||||
if (cipherMode == GCM_MODE) {
|
||||
ivBytes = new byte[GaloisCounterMode.DEFAULT_IV_LEN];
|
||||
} else {
|
||||
ivBytes = new byte[blockSize];
|
||||
}
|
||||
ivBytes = new byte[blockSize];
|
||||
random.nextBytes(ivBytes);
|
||||
}
|
||||
|
||||
@ -466,23 +579,57 @@ final class CipherCore {
|
||||
|
||||
String algorithm = key.getAlgorithm();
|
||||
|
||||
cipher.init(decrypting, algorithm, keyBytes, ivBytes);
|
||||
// GCM mode needs additional handling
|
||||
if (cipherMode == GCM_MODE) {
|
||||
if(tagLen == -1) {
|
||||
tagLen = GaloisCounterMode.DEFAULT_TAG_LEN;
|
||||
}
|
||||
if (decrypting) {
|
||||
minBytes = tagLen;
|
||||
} else {
|
||||
// check key+iv for encryption in GCM mode
|
||||
requireReinit =
|
||||
Arrays.equals(ivBytes, lastEncIv) &&
|
||||
Arrays.equals(keyBytes, lastEncKey);
|
||||
if (requireReinit) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Cannot reuse iv for GCM encryption");
|
||||
}
|
||||
lastEncIv = ivBytes;
|
||||
lastEncKey = keyBytes;
|
||||
}
|
||||
((GaloisCounterMode) cipher).init
|
||||
(decrypting, algorithm, keyBytes, ivBytes, tagLen);
|
||||
} else {
|
||||
cipher.init(decrypting, algorithm, keyBytes, ivBytes);
|
||||
}
|
||||
// skip checking key+iv from now on until after doFinal()
|
||||
requireReinit = false;
|
||||
}
|
||||
|
||||
void init(int opmode, Key key, AlgorithmParameters params,
|
||||
SecureRandom random)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
IvParameterSpec ivSpec = null;
|
||||
AlgorithmParameterSpec spec = null;
|
||||
String paramType = null;
|
||||
if (params != null) {
|
||||
try {
|
||||
ivSpec = params.getParameterSpec(IvParameterSpec.class);
|
||||
if (cipherMode == GCM_MODE) {
|
||||
paramType = "GCM";
|
||||
spec = params.getParameterSpec(GCMParameterSpec.class);
|
||||
} else {
|
||||
// NOTE: RC2 parameters are always handled through
|
||||
// init(..., AlgorithmParameterSpec,...) method, so
|
||||
// we can assume IvParameterSpec type here.
|
||||
paramType = "IV";
|
||||
spec = params.getParameterSpec(IvParameterSpec.class);
|
||||
}
|
||||
} catch (InvalidParameterSpecException ipse) {
|
||||
throw new InvalidAlgorithmParameterException("Wrong parameter "
|
||||
+ "type: IV "
|
||||
+ "expected");
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Wrong parameter type: " + paramType + " expected");
|
||||
}
|
||||
}
|
||||
init(opmode, key, ivSpec, random);
|
||||
init(opmode, key, spec, random);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -504,6 +651,7 @@ final class CipherCore {
|
||||
return keyBytes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Continues a multiple-part encryption or decryption operation
|
||||
* (depending on how this cipher was initialized), processing another data
|
||||
@ -524,22 +672,25 @@ final class CipherCore {
|
||||
* (e.g., has not been initialized)
|
||||
*/
|
||||
byte[] update(byte[] input, int inputOffset, int inputLen) {
|
||||
if (requireReinit) {
|
||||
throw new IllegalStateException
|
||||
("Must use either different key or iv for GCM encryption");
|
||||
}
|
||||
|
||||
byte[] output = null;
|
||||
byte[] out = null;
|
||||
try {
|
||||
output = new byte[getOutputSize(inputLen)];
|
||||
output = new byte[getOutputSizeByOperation(inputLen, false)];
|
||||
int len = update(input, inputOffset, inputLen, output,
|
||||
0);
|
||||
if (len == output.length) {
|
||||
out = output;
|
||||
return output;
|
||||
} else {
|
||||
out = new byte[len];
|
||||
System.arraycopy(output, 0, out, 0, len);
|
||||
return Arrays.copyOf(output, len);
|
||||
}
|
||||
} catch (ShortBufferException e) {
|
||||
// never thrown
|
||||
// should never happen
|
||||
throw new ProviderException("Unexpected exception", e);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -567,6 +718,11 @@ final class CipherCore {
|
||||
*/
|
||||
int update(byte[] input, int inputOffset, int inputLen, byte[] output,
|
||||
int outputOffset) throws ShortBufferException {
|
||||
if (requireReinit) {
|
||||
throw new IllegalStateException
|
||||
("Must use either different key or iv for GCM encryption");
|
||||
}
|
||||
|
||||
// figure out how much can be sent to crypto function
|
||||
int len = buffered + inputLen - minBytes;
|
||||
if (padding != null && decrypting) {
|
||||
@ -582,6 +738,7 @@ final class CipherCore {
|
||||
+ "(at least) " + len
|
||||
+ " bytes long");
|
||||
}
|
||||
|
||||
if (len != 0) {
|
||||
// there is some work to do
|
||||
byte[] in = new byte[len];
|
||||
@ -600,7 +757,6 @@ final class CipherCore {
|
||||
System.arraycopy(input, inputOffset, in,
|
||||
bufferedConsumed, inputConsumed);
|
||||
}
|
||||
|
||||
if (decrypting) {
|
||||
cipher.decrypt(in, 0, len, output, outputOffset);
|
||||
} else {
|
||||
@ -611,11 +767,12 @@ final class CipherCore {
|
||||
// the total input length a multiple of blocksize when
|
||||
// padding is applied
|
||||
if (unitBytes != blockSize) {
|
||||
if (len < diffBlocksize)
|
||||
if (len < diffBlocksize) {
|
||||
diffBlocksize -= len;
|
||||
else
|
||||
} else {
|
||||
diffBlocksize = blockSize -
|
||||
((len - diffBlocksize) % blockSize);
|
||||
}
|
||||
}
|
||||
|
||||
inputLen -= inputConsumed;
|
||||
@ -669,21 +826,18 @@ final class CipherCore {
|
||||
byte[] doFinal(byte[] input, int inputOffset, int inputLen)
|
||||
throws IllegalBlockSizeException, BadPaddingException {
|
||||
byte[] output = null;
|
||||
byte[] out = null;
|
||||
try {
|
||||
output = new byte[getOutputSize(inputLen)];
|
||||
output = new byte[getOutputSizeByOperation(inputLen, true)];
|
||||
int len = doFinal(input, inputOffset, inputLen, output, 0);
|
||||
if (len < output.length) {
|
||||
out = new byte[len];
|
||||
if (len != 0)
|
||||
System.arraycopy(output, 0, out, 0, len);
|
||||
return Arrays.copyOf(output, len);
|
||||
} else {
|
||||
out = output;
|
||||
return output;
|
||||
}
|
||||
} catch (ShortBufferException e) {
|
||||
// never thrown
|
||||
throw new ProviderException("Unexpected exception", e);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -726,6 +880,10 @@ final class CipherCore {
|
||||
int outputOffset)
|
||||
throws IllegalBlockSizeException, ShortBufferException,
|
||||
BadPaddingException {
|
||||
if (requireReinit) {
|
||||
throw new IllegalStateException
|
||||
("Must use either different key or iv for GCM encryption");
|
||||
}
|
||||
|
||||
// calculate the total input length
|
||||
int totalLen = buffered + inputLen;
|
||||
@ -752,8 +910,9 @@ final class CipherCore {
|
||||
}
|
||||
|
||||
// if encrypting and padding not null, add padding
|
||||
if (!decrypting && padding != null)
|
||||
if (!decrypting && padding != null) {
|
||||
paddedLen += paddingLen;
|
||||
}
|
||||
|
||||
// check output buffer capacity.
|
||||
// if we are decrypting with padding applied, we can perform this
|
||||
@ -763,8 +922,8 @@ final class CipherCore {
|
||||
throw new ShortBufferException("Output buffer is null");
|
||||
}
|
||||
int outputCapacity = output.length - outputOffset;
|
||||
if (((!decrypting) || (padding == null)) &&
|
||||
(outputCapacity < paddedLen) ||
|
||||
|
||||
if (((!decrypting) && (outputCapacity < paddedLen)) ||
|
||||
(decrypting && (outputCapacity < (paddedLen - blockSize)))) {
|
||||
throw new ShortBufferException("Output buffer too short: "
|
||||
+ outputCapacity + " bytes given, "
|
||||
@ -812,6 +971,7 @@ final class CipherCore {
|
||||
}
|
||||
totalLen = padStart;
|
||||
}
|
||||
|
||||
if ((output.length - outputOffset) < totalLen) {
|
||||
// restore so users can retry with a larger buffer
|
||||
cipher.restore();
|
||||
@ -824,8 +984,13 @@ final class CipherCore {
|
||||
output[outputOffset + i] = outWithPadding[i];
|
||||
}
|
||||
} else { // encrypting
|
||||
totalLen = finalNoPadding(finalBuf, finalOffset, output,
|
||||
outputOffset, paddedLen);
|
||||
try {
|
||||
totalLen = finalNoPadding(finalBuf, finalOffset, output,
|
||||
outputOffset, paddedLen);
|
||||
} finally {
|
||||
// reset after doFinal() for GCM encryption
|
||||
requireReinit = (cipherMode == GCM_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
buffered = 0;
|
||||
@ -836,33 +1001,33 @@ final class CipherCore {
|
||||
return totalLen;
|
||||
}
|
||||
|
||||
private int finalNoPadding(byte[] in, int inOff, byte[] out, int outOff,
|
||||
private int finalNoPadding(byte[] in, int inOfs, byte[] out, int outOfs,
|
||||
int len)
|
||||
throws IllegalBlockSizeException
|
||||
{
|
||||
if (in == null || len == 0)
|
||||
throws IllegalBlockSizeException, AEADBadTagException {
|
||||
|
||||
if ((cipherMode != GCM_MODE) && (in == null || len == 0)) {
|
||||
return 0;
|
||||
|
||||
if ((cipherMode != CFB_MODE) && (cipherMode != OFB_MODE)
|
||||
&& ((len % unitBytes) != 0) && (cipherMode != CTS_MODE)) {
|
||||
if (padding != null) {
|
||||
throw new IllegalBlockSizeException
|
||||
("Input length (with padding) not multiple of " +
|
||||
unitBytes + " bytes");
|
||||
} else {
|
||||
throw new IllegalBlockSizeException
|
||||
("Input length not multiple of " + unitBytes
|
||||
+ " bytes");
|
||||
}
|
||||
}
|
||||
|
||||
if ((cipherMode != CFB_MODE) && (cipherMode != OFB_MODE) &&
|
||||
(cipherMode != GCM_MODE) &&
|
||||
((len % unitBytes) != 0) && (cipherMode != CTS_MODE)) {
|
||||
if (padding != null) {
|
||||
throw new IllegalBlockSizeException
|
||||
("Input length (with padding) not multiple of " +
|
||||
unitBytes + " bytes");
|
||||
} else {
|
||||
throw new IllegalBlockSizeException
|
||||
("Input length not multiple of " + unitBytes
|
||||
+ " bytes");
|
||||
}
|
||||
}
|
||||
int outLen = 0;
|
||||
if (decrypting) {
|
||||
cipher.decryptFinal(in, inOff, len, out, outOff);
|
||||
outLen = cipher.decryptFinal(in, inOfs, len, out, outOfs);
|
||||
} else {
|
||||
cipher.encryptFinal(in, inOff, len, out, outOff);
|
||||
outLen = cipher.encryptFinal(in, inOfs, len, out, outOfs);
|
||||
}
|
||||
|
||||
return len;
|
||||
return outLen;
|
||||
}
|
||||
|
||||
// Note: Wrap() and Unwrap() are the same in
|
||||
@ -939,4 +1104,36 @@ final class CipherCore {
|
||||
return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm,
|
||||
wrappedKeyType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Continues a multi-part update of the Additional Authentication
|
||||
* Data (AAD), using a subset of the provided buffer.
|
||||
* <p>
|
||||
* Calls to this method provide AAD to the cipher when operating in
|
||||
* modes such as AEAD (GCM/CCM). If this cipher is operating in
|
||||
* either GCM or CCM mode, all AAD must be supplied before beginning
|
||||
* operations on the ciphertext (via the {@code update} and {@code
|
||||
* doFinal} methods).
|
||||
*
|
||||
* @param src the buffer containing the AAD
|
||||
* @param offset the offset in {@code src} where the AAD input starts
|
||||
* @param len the number of AAD bytes
|
||||
*
|
||||
* @throws IllegalStateException if this cipher is in a wrong state
|
||||
* (e.g., has not been initialized), does not accept AAD, or if
|
||||
* operating in either GCM or CCM mode and one of the {@code update}
|
||||
* methods has already been called for the active
|
||||
* encryption/decryption operation
|
||||
* @throws UnsupportedOperationException if this method
|
||||
* has not been overridden by an implementation
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
void updateAAD(byte[] src, int offset, int len) {
|
||||
if (requireReinit) {
|
||||
throw new IllegalStateException
|
||||
("Must use either different key or iv for GCM encryption");
|
||||
}
|
||||
cipher.updateAAD(src, offset, len);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 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
|
||||
@ -83,9 +83,10 @@ final class CipherTextStealing extends CipherBlockChaining {
|
||||
* @param plainLen the length of the input data
|
||||
* @param cipher the buffer for the result
|
||||
* @param cipherOffset the offset in <code>cipher</code>
|
||||
* @return the number of bytes placed into <code>cipher</code>
|
||||
*/
|
||||
void encryptFinal(byte[] plain, int plainOffset, int plainLen,
|
||||
byte[] cipher, int cipherOffset)
|
||||
int encryptFinal(byte[] plain, int plainOffset, int plainLen,
|
||||
byte[] cipher, int cipherOffset)
|
||||
throws IllegalBlockSizeException {
|
||||
|
||||
if (plainLen < blockSize) {
|
||||
@ -134,6 +135,7 @@ final class CipherTextStealing extends CipherBlockChaining {
|
||||
embeddedCipher.encryptBlock(tmp2, 0, cipher, cipherOffset);
|
||||
}
|
||||
}
|
||||
return plainLen;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -158,9 +160,10 @@ final class CipherTextStealing extends CipherBlockChaining {
|
||||
* @param cipherLen the length of the input data
|
||||
* @param plain the buffer for the result
|
||||
* @param plainOffset the offset in <code>plain</code>
|
||||
* @return the number of bytes placed into <code>plain</code>
|
||||
*/
|
||||
void decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
|
||||
byte[] plain, int plainOffset)
|
||||
int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
|
||||
byte[] plain, int plainOffset)
|
||||
throws IllegalBlockSizeException {
|
||||
if (cipherLen < blockSize) {
|
||||
throw new IllegalBlockSizeException("input is too short!");
|
||||
@ -211,5 +214,6 @@ final class CipherTextStealing extends CipherBlockChaining {
|
||||
}
|
||||
}
|
||||
}
|
||||
return cipherLen;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -102,7 +102,7 @@ public final class DESKeyGenerator extends KeyGeneratorSpi {
|
||||
DESKey desKey = null;
|
||||
|
||||
if (this.random == null) {
|
||||
this.random = SunJCE.RANDOM;
|
||||
this.random = SunJCE.getRandom();
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -105,7 +105,7 @@ public final class DESedeKeyGenerator extends KeyGeneratorSpi {
|
||||
*/
|
||||
protected SecretKey engineGenerateKey() {
|
||||
if (this.random == null) {
|
||||
this.random = SunJCE.RANDOM;
|
||||
this.random = SunJCE.getRandom();
|
||||
}
|
||||
|
||||
byte[] rawkey = new byte[DESedeKeySpec.DES_EDE_KEY_LEN];
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 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
|
||||
@ -217,7 +217,7 @@ public final class DESedeWrapCipher extends CipherSpi {
|
||||
if (params == null) {
|
||||
iv = new byte[8];
|
||||
if (random == null) {
|
||||
random = SunJCE.RANDOM;
|
||||
random = SunJCE.getRandom();
|
||||
}
|
||||
random.nextBytes(iv);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -140,7 +140,7 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||
*/
|
||||
public KeyPair generateKeyPair() {
|
||||
if (random == null) {
|
||||
random = SunJCE.RANDOM;
|
||||
random = SunJCE.getRandom();
|
||||
}
|
||||
|
||||
if (params == null) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -131,7 +131,7 @@ extends AlgorithmParameterGeneratorSpi {
|
||||
}
|
||||
|
||||
if (this.random == null)
|
||||
this.random = SunJCE.RANDOM;
|
||||
this.random = SunJCE.getRandom();
|
||||
|
||||
try {
|
||||
AlgorithmParameterGenerator paramGen;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -26,7 +26,7 @@
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.*;
|
||||
|
||||
/**
|
||||
* This class represents a block cipher in one of its modes. It wraps
|
||||
@ -150,11 +150,13 @@ abstract class FeedbackCipher {
|
||||
* @param plainLen the length of the input data
|
||||
* @param cipher the buffer for the encryption result
|
||||
* @param cipherOffset the offset in <code>cipher</code>
|
||||
* @return the number of bytes placed into <code>cipher</code>
|
||||
*/
|
||||
void encryptFinal(byte[] plain, int plainOffset, int plainLen,
|
||||
byte[] cipher, int cipherOffset)
|
||||
int encryptFinal(byte[] plain, int plainOffset, int plainLen,
|
||||
byte[] cipher, int cipherOffset)
|
||||
throws IllegalBlockSizeException {
|
||||
encrypt(plain, plainOffset, plainLen, cipher, cipherOffset);
|
||||
return plainLen;
|
||||
}
|
||||
/**
|
||||
* Performs decryption operation.
|
||||
@ -190,10 +192,40 @@ abstract class FeedbackCipher {
|
||||
* @param cipherLen the length of the input data
|
||||
* @param plain the buffer for the decryption result
|
||||
* @param plainOffset the offset in <code>plain</code>
|
||||
* @return the number of bytes placed into <code>plain</code>
|
||||
*/
|
||||
void decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
|
||||
byte[] plain, int plainOffset)
|
||||
throws IllegalBlockSizeException {
|
||||
int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
|
||||
byte[] plain, int plainOffset)
|
||||
throws IllegalBlockSizeException, AEADBadTagException {
|
||||
decrypt(cipher, cipherOffset, cipherLen, plain, plainOffset);
|
||||
return cipherLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Continues a multi-part update of the Additional Authentication
|
||||
* Data (AAD), using a subset of the provided buffer. If this
|
||||
* cipher is operating in either GCM or CCM mode, all AAD must be
|
||||
* supplied before beginning operations on the ciphertext (via the
|
||||
* {@code update} and {@code doFinal} methods).
|
||||
* <p>
|
||||
* NOTE: Given most modes do not accept AAD, default impl for this
|
||||
* method throws IllegalStateException.
|
||||
*
|
||||
* @param src the buffer containing the AAD
|
||||
* @param offset the offset in {@code src} where the AAD input starts
|
||||
* @param len the number of AAD bytes
|
||||
*
|
||||
* @throws IllegalStateException if this cipher is in a wrong state
|
||||
* (e.g., has not been initialized), does not accept AAD, or if
|
||||
* operating in either GCM or CCM mode and one of the {@code update}
|
||||
* methods has already been called for the active
|
||||
* encryption/decryption operation
|
||||
* @throws UnsupportedOperationException if this method
|
||||
* has not been overridden by an implementation
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
void updateAAD(byte[] src, int offset, int len) {
|
||||
throw new IllegalStateException("No AAD accepted");
|
||||
}
|
||||
}
|
||||
|
146
jdk/src/share/classes/com/sun/crypto/provider/GCMParameters.java
Normal file
146
jdk/src/share/classes/com/sun/crypto/provider/GCMParameters.java
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. 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.io.IOException;
|
||||
import java.security.AlgorithmParametersSpi;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import sun.misc.HexDumpEncoder;
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class implements the parameter set used with
|
||||
* GCM encryption, which is defined in RFC 5084 as follows:
|
||||
*
|
||||
* <pre>
|
||||
* GCMParameters ::= SEQUENCE {
|
||||
* aes-iv OCTET STRING, -- recommended size is 12 octets
|
||||
* aes-tLen AES-GCM-ICVlen DEFAULT 12 }
|
||||
*
|
||||
* AES-GCM-ICVlen ::= INTEGER (12 | 13 | 14 | 15 | 16)
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author Valerie Peng
|
||||
* @since 1.8
|
||||
*/
|
||||
public final class GCMParameters extends AlgorithmParametersSpi {
|
||||
|
||||
// the iv
|
||||
private byte[] iv;
|
||||
// the tag length in bytes
|
||||
private int tLen;
|
||||
|
||||
public GCMParameters() {}
|
||||
|
||||
protected void engineInit(AlgorithmParameterSpec paramSpec)
|
||||
throws InvalidParameterSpecException {
|
||||
|
||||
if (!(paramSpec instanceof GCMParameterSpec)) {
|
||||
throw new InvalidParameterSpecException
|
||||
("Inappropriate parameter specification");
|
||||
}
|
||||
GCMParameterSpec gps = (GCMParameterSpec) paramSpec;
|
||||
// need to convert from bits to bytes for ASN.1 encoding
|
||||
this.tLen = gps.getTLen()/8;
|
||||
this.iv = gps.getIV();
|
||||
}
|
||||
|
||||
protected void engineInit(byte[] encoded) throws IOException {
|
||||
DerValue val = new DerValue(encoded);
|
||||
// check if IV or params
|
||||
if (val.tag == DerValue.tag_Sequence) {
|
||||
byte[] iv = val.data.getOctetString();
|
||||
int tLen;
|
||||
if (val.data.available() != 0) {
|
||||
tLen = val.data.getInteger();
|
||||
if (tLen < 12 || tLen > 16 ) {
|
||||
throw new IOException
|
||||
("GCM parameter parsing error: unsupported tag len: " +
|
||||
tLen);
|
||||
}
|
||||
if (val.data.available() != 0) {
|
||||
throw new IOException
|
||||
("GCM parameter parsing error: extra data");
|
||||
}
|
||||
} else {
|
||||
tLen = 12;
|
||||
}
|
||||
this.iv = iv.clone();
|
||||
this.tLen = tLen;
|
||||
} else {
|
||||
throw new IOException("GCM parameter parsing error: no SEQ tag");
|
||||
}
|
||||
}
|
||||
|
||||
protected void engineInit(byte[] encoded, String decodingMethod)
|
||||
throws IOException {
|
||||
engineInit(encoded);
|
||||
}
|
||||
|
||||
protected <T extends AlgorithmParameterSpec>
|
||||
T engineGetParameterSpec(Class<T> paramSpec)
|
||||
throws InvalidParameterSpecException {
|
||||
|
||||
if (GCMParameterSpec.class.isAssignableFrom(paramSpec)) {
|
||||
return paramSpec.cast(new GCMParameterSpec(tLen * 8, iv));
|
||||
} else {
|
||||
throw new InvalidParameterSpecException
|
||||
("Inappropriate parameter specification");
|
||||
}
|
||||
}
|
||||
|
||||
protected byte[] engineGetEncoded() throws IOException {
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
|
||||
bytes.putOctetString(iv);
|
||||
bytes.putInteger(tLen);
|
||||
out.write(DerValue.tag_Sequence, bytes);
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
protected byte[] engineGetEncoded(String encodingMethod)
|
||||
throws IOException {
|
||||
return engineGetEncoded();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a formatted string describing the parameters.
|
||||
*/
|
||||
protected String engineToString() {
|
||||
String LINE_SEP = System.getProperty("line.separator");
|
||||
HexDumpEncoder encoder = new HexDumpEncoder();
|
||||
StringBuilder sb
|
||||
= new StringBuilder(LINE_SEP + " iv:" + LINE_SEP + "["
|
||||
+ encoder.encodeBuffer(iv) + "]");
|
||||
|
||||
sb.append(LINE_SEP + "tLen(bits):" + LINE_SEP + tLen*8 + LINE_SEP);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
144
jdk/src/share/classes/com/sun/crypto/provider/GCTR.java
Normal file
144
jdk/src/share/classes/com/sun/crypto/provider/GCTR.java
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 2013
|
||||
*/
|
||||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.security.*;
|
||||
import javax.crypto.*;
|
||||
import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
|
||||
|
||||
/**
|
||||
* This class represents the GCTR function defined in NIST 800-38D
|
||||
* under section 6.5. It needs to be constructed w/ an initialized
|
||||
* cipher object, and initial counter block(ICB). Given an input X
|
||||
* of arbitrary length, it processes and returns an output which has
|
||||
* the same length as X.
|
||||
*
|
||||
* <p>This function is used in the implementation of GCM mode.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
final class GCTR {
|
||||
|
||||
// these fields should not change after the object has been constructed
|
||||
private final SymmetricCipher aes;
|
||||
private final byte[] icb;
|
||||
|
||||
// the current counter value
|
||||
private byte[] counter;
|
||||
|
||||
// needed for save/restore calls
|
||||
private byte[] counterSave;
|
||||
|
||||
// NOTE: cipher should already be initialized
|
||||
GCTR(SymmetricCipher cipher, byte[] initialCounterBlk) {
|
||||
this.aes = cipher;
|
||||
this.icb = initialCounterBlk;
|
||||
this.counter = icb.clone();
|
||||
}
|
||||
|
||||
// input must be multiples of 128-bit blocks when calling update
|
||||
int update(byte[] in, int inOfs, int inLen, byte[] out, int outOfs) {
|
||||
if (inLen - inOfs > in.length) {
|
||||
throw new RuntimeException("input length out of bound");
|
||||
}
|
||||
if (inLen < 0 || inLen % AES_BLOCK_SIZE != 0) {
|
||||
throw new RuntimeException("input length unsupported");
|
||||
}
|
||||
if (out.length - outOfs < inLen) {
|
||||
throw new RuntimeException("output buffer too small");
|
||||
}
|
||||
|
||||
byte[] encryptedCntr = new byte[AES_BLOCK_SIZE];
|
||||
|
||||
int numOfCompleteBlocks = inLen / AES_BLOCK_SIZE;
|
||||
for (int i = 0; i < numOfCompleteBlocks; i++) {
|
||||
aes.encryptBlock(counter, 0, encryptedCntr, 0);
|
||||
for (int n = 0; n < AES_BLOCK_SIZE; n++) {
|
||||
int index = (i * AES_BLOCK_SIZE + n);
|
||||
out[outOfs + index] =
|
||||
(byte) ((in[inOfs + index] ^ encryptedCntr[n]));
|
||||
}
|
||||
GaloisCounterMode.increment32(counter);
|
||||
}
|
||||
return inLen;
|
||||
}
|
||||
|
||||
// input can be arbitrary size when calling doFinal
|
||||
protected int doFinal(byte[] in, int inOfs, int inLen, byte[] out,
|
||||
int outOfs) throws IllegalBlockSizeException {
|
||||
try {
|
||||
if (inLen < 0) {
|
||||
throw new IllegalBlockSizeException("Negative input size!");
|
||||
} else if (inLen > 0) {
|
||||
int lastBlockSize = inLen % AES_BLOCK_SIZE;
|
||||
// process the complete blocks first
|
||||
update(in, inOfs, inLen - lastBlockSize, out, outOfs);
|
||||
if (lastBlockSize != 0) {
|
||||
// do the last partial block
|
||||
byte[] encryptedCntr = new byte[AES_BLOCK_SIZE];
|
||||
aes.encryptBlock(counter, 0, encryptedCntr, 0);
|
||||
|
||||
int processed = inLen - lastBlockSize;
|
||||
for (int n = 0; n < lastBlockSize; n++) {
|
||||
out[outOfs + processed + n] =
|
||||
(byte) ((in[inOfs + processed + n] ^
|
||||
encryptedCntr[n]));
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
reset();
|
||||
}
|
||||
return inLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the current counter to its initial value.
|
||||
* This is used after the doFinal() is called so this object can be
|
||||
* reused w/o explicit re-initialization.
|
||||
*/
|
||||
void reset() {
|
||||
System.arraycopy(icb, 0, counter, 0, icb.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the current content of this object.
|
||||
*/
|
||||
void save() {
|
||||
this.counterSave = this.counter.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the content of this object to the previous saved one.
|
||||
*/
|
||||
void restore() {
|
||||
this.counter = this.counterSave;
|
||||
}
|
||||
}
|
178
jdk/src/share/classes/com/sun/crypto/provider/GHASH.java
Normal file
178
jdk/src/share/classes/com/sun/crypto/provider/GHASH.java
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. 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.
|
||||
*/
|
||||
/*
|
||||
* (C) Copyright IBM Corp. 2013
|
||||
*/
|
||||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.security.*;
|
||||
import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
|
||||
|
||||
/**
|
||||
* This class represents the GHASH function defined in NIST 800-38D
|
||||
* under section 6.4. It needs to be constructed w/ a hash subkey, i.e.
|
||||
* block H. Given input of 128-bit blocks, it will process and output
|
||||
* a 128-bit block.
|
||||
*
|
||||
* <p>This function is used in the implementation of GCM mode.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
final class GHASH {
|
||||
|
||||
private static final byte P128 = (byte) 0xe1; //reduction polynomial
|
||||
|
||||
private static boolean getBit(byte[] b, int pos) {
|
||||
int p = pos / 8;
|
||||
pos %= 8;
|
||||
int i = (b[p] >>> (7 - pos)) & 1;
|
||||
return i != 0;
|
||||
}
|
||||
|
||||
private static void shift(byte[] b) {
|
||||
byte temp, temp2;
|
||||
temp2 = 0;
|
||||
for (int i = 0; i < b.length; i++) {
|
||||
temp = (byte) ((b[i] & 0x01) << 7);
|
||||
b[i] = (byte) ((b[i] & 0xff) >>> 1);
|
||||
b[i] = (byte) (b[i] | temp2);
|
||||
temp2 = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// Given block X and Y, returns the muliplication of X * Y
|
||||
private static byte[] blockMult(byte[] x, byte[] y) {
|
||||
if (x.length != AES_BLOCK_SIZE || y.length != AES_BLOCK_SIZE) {
|
||||
throw new RuntimeException("illegal input sizes");
|
||||
}
|
||||
byte[] z = new byte[AES_BLOCK_SIZE];
|
||||
byte[] v = y.clone();
|
||||
// calculate Z1-Z127 and V1-V127
|
||||
for (int i = 0; i < 127; i++) {
|
||||
// Zi+1 = Zi if bit i of x is 0
|
||||
if (getBit(x, i)) {
|
||||
for (int n = 0; n < z.length; n++) {
|
||||
z[n] ^= v[n];
|
||||
}
|
||||
}
|
||||
boolean lastBitOfV = getBit(v, 127);
|
||||
shift(v);
|
||||
if (lastBitOfV) v[0] ^= P128;
|
||||
}
|
||||
// calculate Z128
|
||||
if (getBit(x, 127)) {
|
||||
for (int n = 0; n < z.length; n++) {
|
||||
z[n] ^= v[n];
|
||||
}
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
// hash subkey H; should not change after the object has been constructed
|
||||
private final byte[] subkeyH;
|
||||
|
||||
// buffer for storing hash
|
||||
private byte[] state;
|
||||
|
||||
// variables for save/restore calls
|
||||
private byte[] stateSave = null;
|
||||
|
||||
/**
|
||||
* Initializes the cipher in the specified mode with the given key
|
||||
* and iv.
|
||||
*
|
||||
* @param subkeyH the hash subkey
|
||||
*
|
||||
* @exception ProviderException if the given key is inappropriate for
|
||||
* initializing this digest
|
||||
*/
|
||||
GHASH(byte[] subkeyH) throws ProviderException {
|
||||
if ((subkeyH == null) || subkeyH.length != AES_BLOCK_SIZE) {
|
||||
throw new ProviderException("Internal error");
|
||||
}
|
||||
this.subkeyH = subkeyH;
|
||||
this.state = new byte[AES_BLOCK_SIZE];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the GHASH object to its original state, i.e. blank w/
|
||||
* the same subkey H. Used after digest() is called and to re-use
|
||||
* this object for different data w/ the same H.
|
||||
*/
|
||||
void reset() {
|
||||
Arrays.fill(state, (byte) 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the current snapshot of this GHASH object.
|
||||
*/
|
||||
void save() {
|
||||
stateSave = state.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores this object using the saved snapshot.
|
||||
*/
|
||||
void restore() {
|
||||
state = stateSave;
|
||||
}
|
||||
|
||||
private void processBlock(byte[] data, int ofs) {
|
||||
if (data.length - ofs < AES_BLOCK_SIZE) {
|
||||
throw new RuntimeException("need complete block");
|
||||
}
|
||||
for (int n = 0; n < state.length; n++) {
|
||||
state[n] ^= data[ofs + n];
|
||||
}
|
||||
state = blockMult(state, subkeyH);
|
||||
}
|
||||
|
||||
void update(byte[] in) {
|
||||
update(in, 0, in.length);
|
||||
}
|
||||
|
||||
void update(byte[] in, int inOfs, int inLen) {
|
||||
if (inLen - inOfs > in.length) {
|
||||
throw new RuntimeException("input length out of bound");
|
||||
}
|
||||
if (inLen % AES_BLOCK_SIZE != 0) {
|
||||
throw new RuntimeException("input length unsupported");
|
||||
}
|
||||
|
||||
for (int i = inOfs; i < (inOfs + inLen); i += AES_BLOCK_SIZE) {
|
||||
processBlock(in, i);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] digest() {
|
||||
try {
|
||||
return state.clone();
|
||||
} finally {
|
||||
reset();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,501 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.S
|
||||
*
|
||||
* 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.util.Arrays;
|
||||
import java.io.*;
|
||||
import java.security.*;
|
||||
import javax.crypto.*;
|
||||
import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
|
||||
|
||||
/**
|
||||
* This class represents ciphers in GaloisCounter (GCM) mode.
|
||||
*
|
||||
* <p>This mode currently should only be used w/ AES cipher.
|
||||
* Although no checking is done here, caller should only
|
||||
* pass AES Cipher to the constructor.
|
||||
*
|
||||
* <p>NOTE: This class does not deal with buffering or padding.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
final class GaloisCounterMode extends FeedbackCipher {
|
||||
|
||||
static int DEFAULT_TAG_LEN = AES_BLOCK_SIZE;
|
||||
static int DEFAULT_IV_LEN = 12; // in bytes
|
||||
|
||||
// buffer for AAD data; if null, meaning update has been called
|
||||
private ByteArrayOutputStream aadBuffer = new ByteArrayOutputStream();
|
||||
private int sizeOfAAD = 0;
|
||||
|
||||
// in bytes; need to convert to bits (default value 128) when needed
|
||||
private int tagLenBytes = DEFAULT_TAG_LEN;
|
||||
|
||||
// these following 2 fields can only be initialized after init() is
|
||||
// called, e.g. after cipher key k is set, and STAY UNCHANGED
|
||||
private byte[] subkeyH = null;
|
||||
private byte[] preCounterBlock = null;
|
||||
|
||||
private GCTR gctrPAndC = null;
|
||||
private GHASH ghashAllToS = null;
|
||||
|
||||
// length of total data, i.e. len(C)
|
||||
private int processed = 0;
|
||||
|
||||
// additional variables for save/restore calls
|
||||
private byte[] aadBufferSave = null;
|
||||
private int sizeOfAADSave = 0;
|
||||
private int processedSave = 0;
|
||||
|
||||
// value must be 16-byte long; used by GCTR and GHASH as well
|
||||
static void increment32(byte[] value) {
|
||||
if (value.length != AES_BLOCK_SIZE) {
|
||||
throw new RuntimeException("Unexpected counter block length");
|
||||
}
|
||||
// start from last byte and only go over 4 bytes, i.e. total 32 bits
|
||||
int n = value.length - 1;
|
||||
while ((n >= value.length - 4) && (++value[n] == 0)) {
|
||||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
// ivLen in bits
|
||||
private static byte[] getLengthBlock(int ivLen) {
|
||||
byte[] out = new byte[AES_BLOCK_SIZE];
|
||||
out[12] = (byte)(ivLen >>> 24);
|
||||
out[13] = (byte)(ivLen >>> 16);
|
||||
out[14] = (byte)(ivLen >>> 8);
|
||||
out[15] = (byte)ivLen;
|
||||
return out;
|
||||
}
|
||||
|
||||
// aLen and cLen both in bits
|
||||
private static byte[] getLengthBlock(int aLen, int cLen) {
|
||||
byte[] out = new byte[AES_BLOCK_SIZE];
|
||||
out[4] = (byte)(aLen >>> 24);
|
||||
out[5] = (byte)(aLen >>> 16);
|
||||
out[6] = (byte)(aLen >>> 8);
|
||||
out[7] = (byte)aLen;
|
||||
out[12] = (byte)(cLen >>> 24);
|
||||
out[13] = (byte)(cLen >>> 16);
|
||||
out[14] = (byte)(cLen >>> 8);
|
||||
out[15] = (byte)cLen;
|
||||
return out;
|
||||
}
|
||||
|
||||
private static byte[] expandToOneBlock(byte[] in, int inOfs, int len) {
|
||||
if (len > AES_BLOCK_SIZE) {
|
||||
throw new ProviderException("input " + len + " too long");
|
||||
}
|
||||
if (len == AES_BLOCK_SIZE && inOfs == 0) {
|
||||
return in;
|
||||
} else {
|
||||
byte[] paddedIn = new byte[AES_BLOCK_SIZE];
|
||||
System.arraycopy(in, inOfs, paddedIn, 0, len);
|
||||
return paddedIn;
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] getJ0(byte[] iv, byte[] subkeyH) {
|
||||
byte[] j0;
|
||||
if (iv.length == 12) { // 96 bits
|
||||
j0 = expandToOneBlock(iv, 0, iv.length);
|
||||
j0[AES_BLOCK_SIZE - 1] = 1;
|
||||
} else {
|
||||
GHASH g = new GHASH(subkeyH);
|
||||
int lastLen = iv.length % AES_BLOCK_SIZE;
|
||||
if (lastLen != 0) {
|
||||
g.update(iv, 0, iv.length - lastLen);
|
||||
byte[] padded =
|
||||
expandToOneBlock(iv, iv.length - lastLen, lastLen);
|
||||
g.update(padded);
|
||||
} else {
|
||||
g.update(iv);
|
||||
}
|
||||
byte[] lengthBlock = getLengthBlock(iv.length*8);
|
||||
g.update(lengthBlock);
|
||||
j0 = g.digest();
|
||||
}
|
||||
return j0;
|
||||
}
|
||||
|
||||
GaloisCounterMode(SymmetricCipher embeddedCipher) {
|
||||
super(embeddedCipher);
|
||||
aadBuffer = new ByteArrayOutputStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the feedback mechanism
|
||||
*
|
||||
* @return the name of the feedback mechanism
|
||||
*/
|
||||
String getFeedback() {
|
||||
return "GCM";
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the cipher object to its original state.
|
||||
* This is used when doFinal is called in the Cipher class, so that the
|
||||
* cipher can be reused (with its original key and iv).
|
||||
*/
|
||||
void reset() {
|
||||
if (aadBuffer == null) {
|
||||
aadBuffer = new ByteArrayOutputStream();
|
||||
} else {
|
||||
aadBuffer.reset();
|
||||
}
|
||||
if (gctrPAndC != null) gctrPAndC.reset();
|
||||
if (ghashAllToS != null) ghashAllToS.reset();
|
||||
processed = 0;
|
||||
sizeOfAAD = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the current content of this cipher.
|
||||
*/
|
||||
void save() {
|
||||
processedSave = processed;
|
||||
sizeOfAADSave = sizeOfAAD;
|
||||
aadBufferSave =
|
||||
((aadBuffer == null || aadBuffer.size() == 0)?
|
||||
null : aadBuffer.toByteArray());
|
||||
if (gctrPAndC != null) gctrPAndC.save();
|
||||
if (ghashAllToS != null) ghashAllToS.save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the content of this cipher to the previous saved one.
|
||||
*/
|
||||
void restore() {
|
||||
processed = processedSave;
|
||||
sizeOfAAD = sizeOfAADSave;
|
||||
if (aadBuffer != null) {
|
||||
aadBuffer.reset();
|
||||
if (aadBufferSave != null) {
|
||||
aadBuffer.write(aadBufferSave, 0, aadBufferSave.length);
|
||||
}
|
||||
}
|
||||
if (gctrPAndC != null) gctrPAndC.restore();
|
||||
if (ghashAllToS != null) ghashAllToS.restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the cipher in the specified mode with the given key
|
||||
* and iv.
|
||||
*
|
||||
* @param decrypting flag indicating encryption or decryption
|
||||
* @param algorithm the algorithm name
|
||||
* @param key the key
|
||||
* @param iv the iv
|
||||
* @param tagLenBytes the length of tag in bytes
|
||||
*
|
||||
* @exception InvalidKeyException if the given key is inappropriate for
|
||||
* initializing this cipher
|
||||
*/
|
||||
void init(boolean decrypting, String algorithm, byte[] key, byte[] iv)
|
||||
throws InvalidKeyException {
|
||||
init(decrypting, algorithm, key, iv, DEFAULT_TAG_LEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the cipher in the specified mode with the given key
|
||||
* and iv.
|
||||
*
|
||||
* @param decrypting flag indicating encryption or decryption
|
||||
* @param algorithm the algorithm name
|
||||
* @param key the key
|
||||
* @param iv the iv
|
||||
* @param tagLenBytes the length of tag in bytes
|
||||
*
|
||||
* @exception InvalidKeyException if the given key is inappropriate for
|
||||
* initializing this cipher
|
||||
*/
|
||||
void init(boolean decrypting, String algorithm, byte[] keyValue,
|
||||
byte[] ivValue, int tagLenBytes)
|
||||
throws InvalidKeyException {
|
||||
if (keyValue == null || ivValue == null) {
|
||||
throw new InvalidKeyException("Internal error");
|
||||
}
|
||||
|
||||
// always encrypt mode for embedded cipher
|
||||
this.embeddedCipher.init(false, algorithm, keyValue);
|
||||
this.subkeyH = new byte[AES_BLOCK_SIZE];
|
||||
this.embeddedCipher.encryptBlock(new byte[AES_BLOCK_SIZE], 0,
|
||||
this.subkeyH, 0);
|
||||
|
||||
this.iv = ivValue.clone();
|
||||
preCounterBlock = getJ0(iv, subkeyH);
|
||||
byte[] j0Plus1 = preCounterBlock.clone();
|
||||
increment32(j0Plus1);
|
||||
gctrPAndC = new GCTR(embeddedCipher, j0Plus1);
|
||||
ghashAllToS = new GHASH(subkeyH);
|
||||
|
||||
this.tagLenBytes = tagLenBytes;
|
||||
if (aadBuffer == null) {
|
||||
aadBuffer = new ByteArrayOutputStream();
|
||||
} else {
|
||||
aadBuffer.reset();
|
||||
}
|
||||
processed = 0;
|
||||
sizeOfAAD = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Continues a multi-part update of the Additional Authentication
|
||||
* Data (AAD), using a subset of the provided buffer. If this
|
||||
* cipher is operating in either GCM or CCM mode, all AAD must be
|
||||
* supplied before beginning operations on the ciphertext (via the
|
||||
* {@code update} and {@code doFinal} methods).
|
||||
* <p>
|
||||
* NOTE: Given most modes do not accept AAD, default impl for this
|
||||
* method throws IllegalStateException.
|
||||
*
|
||||
* @param src the buffer containing the AAD
|
||||
* @param offset the offset in {@code src} where the AAD input starts
|
||||
* @param len the number of AAD bytes
|
||||
*
|
||||
* @throws IllegalStateException if this cipher is in a wrong state
|
||||
* (e.g., has not been initialized), does not accept AAD, or if
|
||||
* operating in either GCM or CCM mode and one of the {@code update}
|
||||
* methods has already been called for the active
|
||||
* encryption/decryption operation
|
||||
* @throws UnsupportedOperationException if this method
|
||||
* has not been overridden by an implementation
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
void updateAAD(byte[] src, int offset, int len) {
|
||||
if (aadBuffer != null) {
|
||||
aadBuffer.write(src, offset, len);
|
||||
} else {
|
||||
// update has already been called
|
||||
throw new IllegalStateException
|
||||
("Update has been called; no more AAD data");
|
||||
}
|
||||
}
|
||||
|
||||
// Feed the AAD data to GHASH, pad if necessary
|
||||
void processAAD() {
|
||||
if (aadBuffer != null) {
|
||||
byte[] aad = aadBuffer.toByteArray();
|
||||
sizeOfAAD = aad.length;
|
||||
aadBuffer = null;
|
||||
|
||||
int lastLen = aad.length % AES_BLOCK_SIZE;
|
||||
if (lastLen != 0) {
|
||||
ghashAllToS.update(aad, 0, aad.length - lastLen);
|
||||
byte[] padded = expandToOneBlock(aad, aad.length - lastLen,
|
||||
lastLen);
|
||||
ghashAllToS.update(padded);
|
||||
} else {
|
||||
ghashAllToS.update(aad);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Utility to process the last block; used by encryptFinal and decryptFinal
|
||||
void doLastBlock(byte[] in, int inOfs, int len, byte[] out, int outOfs,
|
||||
boolean isEncrypt) throws IllegalBlockSizeException {
|
||||
// process data in 'in'
|
||||
gctrPAndC.doFinal(in, inOfs, len, out, outOfs);
|
||||
processed += len;
|
||||
|
||||
byte[] ct;
|
||||
int ctOfs;
|
||||
if (isEncrypt) {
|
||||
ct = out;
|
||||
ctOfs = outOfs;
|
||||
} else {
|
||||
ct = in;
|
||||
ctOfs = inOfs;
|
||||
}
|
||||
int lastLen = len % AES_BLOCK_SIZE;
|
||||
if (lastLen != 0) {
|
||||
ghashAllToS.update(ct, ctOfs, len - lastLen);
|
||||
byte[] padded =
|
||||
expandToOneBlock(ct, (ctOfs + len - lastLen), lastLen);
|
||||
ghashAllToS.update(padded);
|
||||
} else {
|
||||
ghashAllToS.update(ct, ctOfs, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs encryption operation.
|
||||
*
|
||||
* <p>The input plain text <code>in</code>, starting at <code>inOff</code>
|
||||
* and ending at <code>(inOff + len - 1)</code>, is encrypted. The result
|
||||
* is stored in <code>out</code>, starting at <code>outOfs</code>.
|
||||
*
|
||||
* <p>It is the application's responsibility to make sure that
|
||||
* <code>len</code> is a multiple of the embedded cipher's block size,
|
||||
* otherwise, a ProviderException will be thrown.
|
||||
*
|
||||
* <p>It is also the application's responsibility to make sure that
|
||||
* <code>init</code> has been called before this method is called.
|
||||
* (This check is omitted here, to avoid double checking.)
|
||||
*
|
||||
* @param in the buffer with the input data to be encrypted
|
||||
* @param inOfs the offset in <code>in</code>
|
||||
* @param len the length of the input data
|
||||
* @param out the buffer for the result
|
||||
* @param outOfs the offset in <code>out</code>
|
||||
*/
|
||||
void encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
|
||||
processAAD();
|
||||
if (len > 0) {
|
||||
gctrPAndC.update(in, inOfs, len, out, outOfs);
|
||||
processed += len;
|
||||
ghashAllToS.update(out, outOfs, len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs encryption operation for the last time.
|
||||
*
|
||||
* <p>NOTE: <code>len</code> may not be multiple of the embedded
|
||||
* cipher's block size for this call.
|
||||
*
|
||||
* @param in the input buffer with the data to be encrypted
|
||||
* @param inOfs the offset in <code>in</code>
|
||||
* @param len the length of the input data
|
||||
* @param out the buffer for the encryption result
|
||||
* @param outOfs the offset in <code>out</code>
|
||||
* @return the number of bytes placed into the <code>out</code> buffer
|
||||
*/
|
||||
int encryptFinal(byte[] in, int inOfs, int len, byte[] out, int outOfs)
|
||||
throws IllegalBlockSizeException {
|
||||
if (out.length - outOfs < (len + tagLenBytes)) {
|
||||
throw new RuntimeException("Output buffer too small");
|
||||
}
|
||||
|
||||
processAAD();
|
||||
if (len > 0) {
|
||||
//ByteUtil.dumpArray(Arrays.copyOfRange(in, inOfs, inOfs + len));
|
||||
doLastBlock(in, inOfs, len, out, outOfs, true);
|
||||
}
|
||||
|
||||
byte[] lengthBlock = getLengthBlock(sizeOfAAD*8, processed*8);
|
||||
ghashAllToS.update(lengthBlock);
|
||||
byte[] s = ghashAllToS.digest();
|
||||
byte[] sOut = new byte[s.length];
|
||||
GCTR gctrForSToTag = new GCTR(embeddedCipher, this.preCounterBlock);
|
||||
gctrForSToTag.doFinal(s, 0, s.length, sOut, 0);
|
||||
|
||||
System.arraycopy(sOut, 0, out, (outOfs + len), tagLenBytes);
|
||||
return (len + tagLenBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs decryption operation.
|
||||
*
|
||||
* <p>The input cipher text <code>in</code>, starting at
|
||||
* <code>inOfs</code> and ending at <code>(inOfs + len - 1)</code>,
|
||||
* is decrypted. The result is stored in <code>out</code>, starting at
|
||||
* <code>outOfs</code>.
|
||||
*
|
||||
* <p>It is the application's responsibility to make sure that
|
||||
* <code>len</code> is a multiple of the embedded cipher's block
|
||||
* size, as any excess bytes are ignored.
|
||||
*
|
||||
* <p>It is also the application's responsibility to make sure that
|
||||
* <code>init</code> has been called before this method is called.
|
||||
* (This check is omitted here, to avoid double checking.)
|
||||
*
|
||||
* @param in the buffer with the input data to be decrypted
|
||||
* @param inOfs the offset in <code>in</code>
|
||||
* @param len the length of the input data
|
||||
* @param out the buffer for the result
|
||||
* @param outOfs the offset in <code>out</code>
|
||||
*/
|
||||
void decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
|
||||
processAAD();
|
||||
|
||||
if (len > 0) { // must be at least AES_BLOCK_SIZE bytes long
|
||||
gctrPAndC.update(in, inOfs, len, out, outOfs);
|
||||
processed += len;
|
||||
ghashAllToS.update(in, inOfs, len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs decryption operation for the last time.
|
||||
*
|
||||
* <p>NOTE: For cipher feedback modes which does not perform
|
||||
* special handling for the last few blocks, this is essentially
|
||||
* the same as <code>encrypt(...)</code>. Given most modes do
|
||||
* not do special handling, the default impl for this method is
|
||||
* to simply call <code>decrypt(...)</code>.
|
||||
*
|
||||
* @param in the input buffer with the data to be decrypted
|
||||
* @param inOfs the offset in <code>cipher</code>
|
||||
* @param len the length of the input data
|
||||
* @param out the buffer for the decryption result
|
||||
* @param outOfs the offset in <code>plain</code>
|
||||
* @return the number of bytes placed into the <code>out</code> buffer
|
||||
*/
|
||||
int decryptFinal(byte[] in, int inOfs, int len,
|
||||
byte[] out, int outOfs)
|
||||
throws IllegalBlockSizeException, AEADBadTagException {
|
||||
if (len < tagLenBytes) {
|
||||
throw new RuntimeException("Input buffer too short - need tag");
|
||||
}
|
||||
if (out.length - outOfs < (len - tagLenBytes)) {
|
||||
throw new RuntimeException("Output buffer too small");
|
||||
}
|
||||
processAAD();
|
||||
|
||||
int processedOld = processed;
|
||||
byte[] tag = new byte[tagLenBytes];
|
||||
// get the trailing tag bytes from 'in'
|
||||
System.arraycopy(in, inOfs + len - tagLenBytes, tag, 0, tagLenBytes);
|
||||
len -= tagLenBytes;
|
||||
|
||||
if (len > 0) {
|
||||
doLastBlock(in, inOfs, len, out, outOfs, false);
|
||||
}
|
||||
|
||||
byte[] lengthBlock = getLengthBlock(sizeOfAAD*8, processed*8);
|
||||
ghashAllToS.update(lengthBlock);
|
||||
|
||||
byte[] s = ghashAllToS.digest();
|
||||
byte[] sOut = new byte[s.length];
|
||||
GCTR gctrForSToTag = new GCTR(embeddedCipher, this.preCounterBlock);
|
||||
gctrForSToTag.doFinal(s, 0, s.length, sOut, 0);
|
||||
for (int i = 0; i < tagLenBytes; i++) {
|
||||
if (tag[i] != sOut[i]) {
|
||||
throw new AEADBadTagException("Tag mismatch!");
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
// return tag length in bytes
|
||||
int getTagLen() {
|
||||
return this.tagLenBytes;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -98,7 +98,7 @@ public final class HmacMD5KeyGenerator extends KeyGeneratorSpi {
|
||||
*/
|
||||
protected SecretKey engineGenerateKey() {
|
||||
if (this.random == null) {
|
||||
this.random = SunJCE.RANDOM;
|
||||
this.random = SunJCE.getRandom();
|
||||
}
|
||||
|
||||
byte[] keyBytes = new byte[this.keysize];
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -89,7 +89,7 @@ public final class HmacPKCS12PBESHA1 extends HmacCore {
|
||||
// generate default for salt and iteration count if necessary
|
||||
if (salt == null) {
|
||||
salt = new byte[20];
|
||||
SunJCE.RANDOM.nextBytes(salt);
|
||||
SunJCE.getRandom().nextBytes(salt);
|
||||
}
|
||||
if (iCount == 0) iCount = 100;
|
||||
} else if (!(params instanceof PBEParameterSpec)) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -98,7 +98,7 @@ public final class HmacSHA1KeyGenerator extends KeyGeneratorSpi {
|
||||
*/
|
||||
protected SecretKey engineGenerateKey() {
|
||||
if (this.random == null) {
|
||||
this.random = SunJCE.RANDOM;
|
||||
this.random = SunJCE.getRandom();
|
||||
}
|
||||
|
||||
byte[] keyBytes = new byte[this.keysize];
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -69,7 +69,7 @@ final class ISO10126Padding implements Padding {
|
||||
|
||||
byte paddingOctet = (byte) (len & 0xff);
|
||||
byte[] padding = new byte[len];
|
||||
SunJCE.RANDOM.nextBytes(padding);
|
||||
SunJCE.getRandom().nextBytes(padding);
|
||||
padding[len-1] = paddingOctet;
|
||||
System.arraycopy(padding, 0, in, off, len);
|
||||
return;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -98,7 +98,7 @@ final class KeyGeneratorCore {
|
||||
// generate the key
|
||||
SecretKey implGenerateKey() {
|
||||
if (random == null) {
|
||||
random = SunJCE.RANDOM;
|
||||
random = SunJCE.getRandom();
|
||||
}
|
||||
byte[] b = new byte[(keySize + 7) >> 3];
|
||||
random.nextBytes(b);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@ -99,7 +99,7 @@ final class KeyProtector {
|
||||
{
|
||||
// create a random salt (8 bytes)
|
||||
byte[] salt = new byte[8];
|
||||
SunJCE.RANDOM.nextBytes(salt);
|
||||
SunJCE.getRandom().nextBytes(salt);
|
||||
|
||||
// create PBE parameters from salt and iteration count
|
||||
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
|
||||
@ -284,7 +284,7 @@ final class KeyProtector {
|
||||
{
|
||||
// create a random salt (8 bytes)
|
||||
byte[] salt = new byte[8];
|
||||
SunJCE.RANDOM.nextBytes(salt);
|
||||
SunJCE.getRandom().nextBytes(salt);
|
||||
|
||||
// create PBE parameters from salt and iteration count
|
||||
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -164,7 +164,7 @@ final class PBECipherCore {
|
||||
AlgorithmParameters params = null;
|
||||
if (salt == null) {
|
||||
salt = new byte[8];
|
||||
SunJCE.RANDOM.nextBytes(salt);
|
||||
SunJCE.getRandom().nextBytes(salt);
|
||||
}
|
||||
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount);
|
||||
try {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -164,7 +164,7 @@ final class PBES1Core {
|
||||
AlgorithmParameters params = null;
|
||||
if (salt == null) {
|
||||
salt = new byte[8];
|
||||
SunJCE.RANDOM.nextBytes(salt);
|
||||
SunJCE.getRandom().nextBytes(salt);
|
||||
}
|
||||
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount);
|
||||
try {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
@ -134,13 +134,13 @@ abstract class PBES2Core extends CipherSpi {
|
||||
if (salt == null) {
|
||||
// generate random salt and use default iteration count
|
||||
salt = new byte[DEFAULT_SALT_LENGTH];
|
||||
SunJCE.RANDOM.nextBytes(salt);
|
||||
SunJCE.getRandom().nextBytes(salt);
|
||||
iCount = DEFAULT_COUNT;
|
||||
}
|
||||
if (ivSpec == null) {
|
||||
// generate random IV
|
||||
byte[] ivBytes = new byte[blkSize];
|
||||
SunJCE.RANDOM.nextBytes(ivBytes);
|
||||
SunJCE.getRandom().nextBytes(ivBytes);
|
||||
ivSpec = new IvParameterSpec(ivBytes);
|
||||
}
|
||||
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount, ivSpec);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -123,7 +123,7 @@ abstract class PBMAC1Core extends HmacCore {
|
||||
// generate default for salt and iteration count if necessary
|
||||
if (salt == null) {
|
||||
salt = new byte[DEFAULT_SALT_LENGTH];
|
||||
SunJCE.RANDOM.nextBytes(salt);
|
||||
SunJCE.getRandom().nextBytes(salt);
|
||||
}
|
||||
if (iCount == 0) iCount = DEFAULT_COUNT;
|
||||
} else if (!(params instanceof PBEParameterSpec)) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -227,7 +227,7 @@ final class PKCS12PBECipherCore {
|
||||
// follow the recommendation in PKCS12 v1.0
|
||||
// section B.4 to generate salt and iCount.
|
||||
salt = new byte[DEFAULT_SALT_LENGTH];
|
||||
SunJCE.RANDOM.nextBytes(salt);
|
||||
SunJCE.getRandom().nextBytes(salt);
|
||||
iCount = DEFAULT_COUNT;
|
||||
}
|
||||
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount);
|
||||
@ -294,7 +294,7 @@ final class PKCS12PBECipherCore {
|
||||
if (random != null) {
|
||||
random.nextBytes(salt);
|
||||
} else {
|
||||
SunJCE.RANDOM.nextBytes(salt);
|
||||
SunJCE.getRandom().nextBytes(salt);
|
||||
}
|
||||
}
|
||||
if (iCount == 0) iCount = DEFAULT_COUNT;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -57,6 +57,7 @@ import java.security.SecureRandom;
|
||||
* - ARCFOUR (RC4 compatible)
|
||||
*
|
||||
* - Cipher modes ECB, CBC, CFB, OFB, PCBC, CTR, and CTS for all block ciphers
|
||||
* and mode GCM for AES cipher
|
||||
*
|
||||
* - Cipher padding ISO10126Padding for non-PKCS#5 block ciphers and
|
||||
* NoPadding and PKCS5Padding for all block ciphers
|
||||
@ -90,7 +91,12 @@ public final class SunJCE extends Provider {
|
||||
/* Are we debugging? -- for developers */
|
||||
static final boolean debug = false;
|
||||
|
||||
static final SecureRandom RANDOM = new SecureRandom();
|
||||
// lazy initialize SecureRandom to avoid potential recursion if Sun
|
||||
// provider has not been installed yet
|
||||
private static class SecureRandomHolder {
|
||||
static final SecureRandom RANDOM = new SecureRandom();
|
||||
}
|
||||
static SecureRandom getRandom() { return SecureRandomHolder.RANDOM; }
|
||||
|
||||
public SunJCE() {
|
||||
/* We are the "SunJCE" provider */
|
||||
@ -100,7 +106,7 @@ public final class SunJCE extends Provider {
|
||||
"|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64" +
|
||||
"|OFB8|OFB16|OFB24|OFB32|OFB40|OFB48|OFB56|OFB64";
|
||||
final String BLOCK_MODES128 = BLOCK_MODES +
|
||||
"|CFB72|CFB80|CFB88|CFB96|CFB104|CFB112|CFB120|CFB128" +
|
||||
"|GCM|CFB72|CFB80|CFB88|CFB96|CFB104|CFB112|CFB120|CFB128" +
|
||||
"|OFB72|OFB80|OFB88|OFB96|OFB104|OFB112|OFB120|OFB128";
|
||||
final String BLOCK_PADS = "NOPADDING|PKCS5PADDING|ISO10126PADDING";
|
||||
|
||||
@ -258,6 +264,9 @@ public final class SunJCE extends Provider {
|
||||
put("Cipher.AES_128/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_CFB_NoPadding");
|
||||
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding");
|
||||
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding");
|
||||
put("Cipher.AES_128/GCM/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_GCM_NoPadding");
|
||||
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.6", "AES_128/GCM/NoPadding");
|
||||
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.6", "AES_128/GCM/NoPadding");
|
||||
|
||||
put("Cipher.AES_192/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_ECB_NoPadding");
|
||||
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding");
|
||||
@ -271,7 +280,9 @@ public final class SunJCE extends Provider {
|
||||
put("Cipher.AES_192/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_CFB_NoPadding");
|
||||
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding");
|
||||
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding");
|
||||
|
||||
put("Cipher.AES_192/GCM/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_GCM_NoPadding");
|
||||
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.26", "AES_192/GCM/NoPadding");
|
||||
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.26", "AES_192/GCM/NoPadding");
|
||||
|
||||
put("Cipher.AES_256/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_ECB_NoPadding");
|
||||
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding");
|
||||
@ -285,6 +296,9 @@ public final class SunJCE extends Provider {
|
||||
put("Cipher.AES_256/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_CFB_NoPadding");
|
||||
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding");
|
||||
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding");
|
||||
put("Cipher.AES_256/GCM/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_GCM_NoPadding");
|
||||
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.46", "AES_256/GCM/NoPadding");
|
||||
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.46", "AES_256/GCM/NoPadding");
|
||||
|
||||
put("Cipher.AESWrap", "com.sun.crypto.provider.AESWrapCipher$General");
|
||||
put("Cipher.AESWrap SupportedModes", "ECB");
|
||||
@ -509,6 +523,8 @@ public final class SunJCE extends Provider {
|
||||
put("AlgorithmParameters.AES",
|
||||
"com.sun.crypto.provider.AESParameters");
|
||||
put("Alg.Alias.AlgorithmParameters.Rijndael", "AES");
|
||||
put("AlgorithmParameters.GCM",
|
||||
"com.sun.crypto.provider.GCMParameters");
|
||||
|
||||
|
||||
put("AlgorithmParameters.RC2",
|
||||
|
@ -860,9 +860,9 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
* @return the specified subsequence.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if <tt>start</tt> or <tt>end</tt> are negative,
|
||||
* if <tt>end</tt> is greater than <tt>length()</tt>,
|
||||
* or if <tt>start</tt> is greater than <tt>end</tt>
|
||||
* if {@code start} or {@code end} are negative,
|
||||
* if {@code end} is greater than {@code length()},
|
||||
* or if {@code start} is greater than {@code end}
|
||||
* @spec JSR-51
|
||||
*/
|
||||
@Override
|
||||
@ -1292,7 +1292,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
/**
|
||||
* Returns the index within this string of the first occurrence of the
|
||||
* specified substring, starting at the specified index. The integer
|
||||
* returned is the smallest value <tt>k</tt> for which:
|
||||
* returned is the smallest value {@code k} for which:
|
||||
* <blockquote><pre>
|
||||
* k >= Math.min(fromIndex, str.length()) &&
|
||||
* this.toString().startsWith(str, k)
|
||||
@ -1418,7 +1418,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
public abstract String toString();
|
||||
|
||||
/**
|
||||
* Needed by <tt>String</tt> for the contentEquals method.
|
||||
* Needed by {@code String} for the contentEquals method.
|
||||
*/
|
||||
final char[] getValue() {
|
||||
return value;
|
||||
|
63
jdk/src/share/classes/java/lang/FunctionalInterface.java
Normal file
63
jdk/src/share/classes/java/lang/FunctionalInterface.java
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* Indicates that an interface type declaration is intended to be a
|
||||
* <i>functional interface</i> as defined by the Java Language
|
||||
* Specification.
|
||||
*
|
||||
* Conceptually, a functional interface has exactly one abstract
|
||||
* method. Since {@linkplain java.lang.reflect.Method#isDefault()
|
||||
* default methods} have an implementation, they are not abstract. If
|
||||
* an interface declares an abstract method overriding one of the
|
||||
* public methods of {@code java.lang.Object}, that also does
|
||||
* <em>not</em> count toward the interface's abstract method count
|
||||
* since any implementation of the interface will have an
|
||||
* implementation from {@code java.lang.Object} or elsewhere.
|
||||
*
|
||||
* <p>Note that instances of functional interfaces can be created with
|
||||
* lambda expressions, method references, or constructor references.
|
||||
*
|
||||
* <p>If a type is annotated with this annotation type, compilers are
|
||||
* required to generate an error message unless:
|
||||
*
|
||||
* <ul>
|
||||
* <li> The type is an interface type and not an annotation type, enum, or class.
|
||||
* <li> The annotated type satisfies the requirements of a functional interface.
|
||||
* </ul>
|
||||
*
|
||||
* @jls 4.3.2. The Class Object
|
||||
* @jls 9.8 Functional Interfaces
|
||||
* @jls 9.4.3 Interface Method Body
|
||||
* @since 1.8
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface FunctionalInterface {}
|
@ -772,7 +772,7 @@ public final class Integer extends Number implements Comparable<Integer> {
|
||||
int i = parseInt(integerCacheHighPropValue);
|
||||
i = Math.max(i, 127);
|
||||
// Maximum array size is Integer.MAX_VALUE
|
||||
h = Math.min(i, Integer.MAX_VALUE - (-low));
|
||||
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
|
||||
}
|
||||
high = h;
|
||||
|
||||
|
@ -615,10 +615,10 @@ public final class String
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if, and only if, {@link #length()} is <tt>0</tt>.
|
||||
* Returns {@code true} if, and only if, {@link #length()} is {@code 0}.
|
||||
*
|
||||
* @return <tt>true</tt> if {@link #length()} is <tt>0</tt>, otherwise
|
||||
* <tt>false</tt>
|
||||
* @return {@code true} if {@link #length()} is {@code 0}, otherwise
|
||||
* {@code false}
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
@ -1229,23 +1229,23 @@ public final class String
|
||||
/**
|
||||
* Tests if two string regions are equal.
|
||||
* <p>
|
||||
* A substring of this <tt>String</tt> object is compared to a substring
|
||||
* A substring of this {@code String} object is compared to a substring
|
||||
* of the argument other. The result is true if these substrings
|
||||
* represent identical character sequences. The substring of this
|
||||
* <tt>String</tt> object to be compared begins at index <tt>toffset</tt>
|
||||
* and has length <tt>len</tt>. The substring of other to be compared
|
||||
* begins at index <tt>ooffset</tt> and has length <tt>len</tt>. The
|
||||
* result is <tt>false</tt> if and only if at least one of the following
|
||||
* {@code String} object to be compared begins at index {@code toffset}
|
||||
* and has length {@code len}. The substring of other to be compared
|
||||
* begins at index {@code ooffset} and has length {@code len}. The
|
||||
* result is {@code false} if and only if at least one of the following
|
||||
* is true:
|
||||
* <ul><li><tt>toffset</tt> is negative.
|
||||
* <li><tt>ooffset</tt> is negative.
|
||||
* <li><tt>toffset+len</tt> is greater than the length of this
|
||||
* <tt>String</tt> object.
|
||||
* <li><tt>ooffset+len</tt> is greater than the length of the other
|
||||
* <ul><li>{@code toffset} is negative.
|
||||
* <li>{@code ooffset} is negative.
|
||||
* <li>{@code toffset+len} is greater than the length of this
|
||||
* {@code String} object.
|
||||
* <li>{@code ooffset+len} is greater than the length of the other
|
||||
* argument.
|
||||
* <li>There is some nonnegative integer <i>k</i> less than <tt>len</tt>
|
||||
* <li>There is some nonnegative integer <i>k</i> less than {@code len}
|
||||
* such that:
|
||||
* <tt>this.charAt(toffset+<i>k</i>) != other.charAt(ooffset+<i>k</i>)</tt>
|
||||
* <code>this.charAt(toffset+<i>k</i>) != other.charAt(ooffset+<i>k</i>)</code>
|
||||
* </ul>
|
||||
*
|
||||
* @param toffset the starting offset of the subregion in this string.
|
||||
@ -1280,28 +1280,28 @@ public final class String
|
||||
/**
|
||||
* Tests if two string regions are equal.
|
||||
* <p>
|
||||
* A substring of this <tt>String</tt> object is compared to a substring
|
||||
* of the argument <tt>other</tt>. The result is <tt>true</tt> if these
|
||||
* A substring of this {@code String} object is compared to a substring
|
||||
* of the argument {@code other}. The result is {@code true} if these
|
||||
* substrings represent character sequences that are the same, ignoring
|
||||
* case if and only if <tt>ignoreCase</tt> is true. The substring of
|
||||
* this <tt>String</tt> object to be compared begins at index
|
||||
* <tt>toffset</tt> and has length <tt>len</tt>. The substring of
|
||||
* <tt>other</tt> to be compared begins at index <tt>ooffset</tt> and
|
||||
* has length <tt>len</tt>. The result is <tt>false</tt> if and only if
|
||||
* case if and only if {@code ignoreCase} is true. The substring of
|
||||
* this {@code String} object to be compared begins at index
|
||||
* {@code toffset} and has length {@code len}. The substring of
|
||||
* {@code other} to be compared begins at index {@code ooffset} and
|
||||
* has length {@code len}. The result is {@code false} if and only if
|
||||
* at least one of the following is true:
|
||||
* <ul><li><tt>toffset</tt> is negative.
|
||||
* <li><tt>ooffset</tt> is negative.
|
||||
* <li><tt>toffset+len</tt> is greater than the length of this
|
||||
* <tt>String</tt> object.
|
||||
* <li><tt>ooffset+len</tt> is greater than the length of the other
|
||||
* <ul><li>{@code toffset} is negative.
|
||||
* <li>{@code ooffset} is negative.
|
||||
* <li>{@code toffset+len} is greater than the length of this
|
||||
* {@code String} object.
|
||||
* <li>{@code ooffset+len} is greater than the length of the other
|
||||
* argument.
|
||||
* <li><tt>ignoreCase</tt> is <tt>false</tt> and there is some nonnegative
|
||||
* integer <i>k</i> less than <tt>len</tt> such that:
|
||||
* <li>{@code ignoreCase} is {@code false} and there is some nonnegative
|
||||
* integer <i>k</i> less than {@code len} such that:
|
||||
* <blockquote><pre>
|
||||
* this.charAt(toffset+k) != other.charAt(ooffset+k)
|
||||
* </pre></blockquote>
|
||||
* <li><tt>ignoreCase</tt> is <tt>true</tt> and there is some nonnegative
|
||||
* integer <i>k</i> less than <tt>len</tt> such that:
|
||||
* <li>{@code ignoreCase} is {@code true} and there is some nonnegative
|
||||
* integer <i>k</i> less than {@code len} such that:
|
||||
* <blockquote><pre>
|
||||
* Character.toLowerCase(this.charAt(toffset+k)) !=
|
||||
Character.toLowerCase(other.charAt(ooffset+k))
|
||||
@ -1500,12 +1500,12 @@ public final class String
|
||||
* of {@code ch} in the range from 0 to 0xFFFF (inclusive),
|
||||
* this is the smallest value <i>k</i> such that:
|
||||
* <blockquote><pre>
|
||||
* (this.charAt(<i>k</i>) == ch) && (<i>k</i> >= fromIndex)
|
||||
* (this.charAt(<i>k</i>) == ch) {@code &&} (<i>k</i> >= fromIndex)
|
||||
* </pre></blockquote>
|
||||
* is true. For other values of {@code ch}, it is the
|
||||
* smallest value <i>k</i> such that:
|
||||
* <blockquote><pre>
|
||||
* (this.codePointAt(<i>k</i>) == ch) && (<i>k</i> >= fromIndex)
|
||||
* (this.codePointAt(<i>k</i>) == ch) {@code &&} (<i>k</i> >= fromIndex)
|
||||
* </pre></blockquote>
|
||||
* is true. In either case, if no such character occurs in this
|
||||
* string at or after position {@code fromIndex}, then
|
||||
@ -1604,12 +1604,12 @@ public final class String
|
||||
* from 0 to 0xFFFF (inclusive), the index returned is the largest
|
||||
* value <i>k</i> such that:
|
||||
* <blockquote><pre>
|
||||
* (this.charAt(<i>k</i>) == ch) && (<i>k</i> <= fromIndex)
|
||||
* (this.charAt(<i>k</i>) == ch) {@code &&} (<i>k</i> <= fromIndex)
|
||||
* </pre></blockquote>
|
||||
* is true. For other values of {@code ch}, it is the
|
||||
* largest value <i>k</i> such that:
|
||||
* <blockquote><pre>
|
||||
* (this.codePointAt(<i>k</i>) == ch) && (<i>k</i> <= fromIndex)
|
||||
* (this.codePointAt(<i>k</i>) == ch) {@code &&} (<i>k</i> <= fromIndex)
|
||||
* </pre></blockquote>
|
||||
* is true. In either case, if no such character occurs in this
|
||||
* string at or before position {@code fromIndex}, then
|
||||
@ -1690,7 +1690,7 @@ public final class String
|
||||
*
|
||||
* <p>The returned index is the smallest value <i>k</i> for which:
|
||||
* <blockquote><pre>
|
||||
* <i>k</i> >= fromIndex && this.startsWith(str, <i>k</i>)
|
||||
* <i>k</i> >= fromIndex {@code &&} this.startsWith(str, <i>k</i>)
|
||||
* </pre></blockquote>
|
||||
* If no such value of <i>k</i> exists, then {@code -1} is returned.
|
||||
*
|
||||
@ -1799,7 +1799,7 @@ public final class String
|
||||
*
|
||||
* <p>The returned index is the largest value <i>k</i> for which:
|
||||
* <blockquote><pre>
|
||||
* <i>k</i> <= fromIndex && this.startsWith(str, <i>k</i>)
|
||||
* <i>k</i> {@code <=} fromIndex {@code &&} this.startsWith(str, <i>k</i>)
|
||||
* </pre></blockquote>
|
||||
* If no such value of <i>k</i> exists, then {@code -1} is returned.
|
||||
*
|
||||
@ -2080,17 +2080,18 @@ public final class String
|
||||
* href="../util/regex/Pattern.html#sum">regular expression</a>.
|
||||
*
|
||||
* <p> An invocation of this method of the form
|
||||
* <i>str</i><tt>.matches(</tt><i>regex</i><tt>)</tt> yields exactly the
|
||||
* <i>str</i>{@code .matches(}<i>regex</i>{@code )} yields exactly the
|
||||
* same result as the expression
|
||||
*
|
||||
* <blockquote><tt> {@link java.util.regex.Pattern}.{@link
|
||||
* java.util.regex.Pattern#matches(String,CharSequence)
|
||||
* matches}(</tt><i>regex</i><tt>,</tt> <i>str</i><tt>)</tt></blockquote>
|
||||
* <blockquote>
|
||||
* {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#matches(String,CharSequence)
|
||||
* matches(<i>regex</i>, <i>str</i>)}
|
||||
* </blockquote>
|
||||
*
|
||||
* @param regex
|
||||
* the regular expression to which this string is to be matched
|
||||
*
|
||||
* @return <tt>true</tt> if, and only if, this string matches the
|
||||
* @return {@code true} if, and only if, this string matches the
|
||||
* given regular expression
|
||||
*
|
||||
* @throws PatternSyntaxException
|
||||
@ -2124,18 +2125,20 @@ public final class String
|
||||
* given replacement.
|
||||
*
|
||||
* <p> An invocation of this method of the form
|
||||
* <i>str</i><tt>.replaceFirst(</tt><i>regex</i><tt>,</tt> <i>repl</i><tt>)</tt>
|
||||
* <i>str</i>{@code .replaceFirst(}<i>regex</i>{@code ,} <i>repl</i>{@code )}
|
||||
* yields exactly the same result as the expression
|
||||
*
|
||||
* <blockquote><tt>
|
||||
* {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile
|
||||
* compile}(</tt><i>regex</i><tt>).{@link
|
||||
* java.util.regex.Pattern#matcher(java.lang.CharSequence)
|
||||
* matcher}(</tt><i>str</i><tt>).{@link java.util.regex.Matcher#replaceFirst
|
||||
* replaceFirst}(</tt><i>repl</i><tt>)</tt></blockquote>
|
||||
* <blockquote>
|
||||
* <code>
|
||||
* {@link java.util.regex.Pattern}.{@link
|
||||
* java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
|
||||
* java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link
|
||||
* java.util.regex.Matcher#replaceFirst replaceFirst}(<i>repl</i>)
|
||||
* </code>
|
||||
* </blockquote>
|
||||
*
|
||||
*<p>
|
||||
* Note that backslashes (<tt>\</tt>) and dollar signs (<tt>$</tt>) in the
|
||||
* Note that backslashes ({@code \}) and dollar signs ({@code $}) in the
|
||||
* replacement string may cause the results to be different than if it were
|
||||
* being treated as a literal replacement string; see
|
||||
* {@link java.util.regex.Matcher#replaceFirst}.
|
||||
@ -2147,7 +2150,7 @@ public final class String
|
||||
* @param replacement
|
||||
* the string to be substituted for the first match
|
||||
*
|
||||
* @return The resulting <tt>String</tt>
|
||||
* @return The resulting {@code String}
|
||||
*
|
||||
* @throws PatternSyntaxException
|
||||
* if the regular expression's syntax is invalid
|
||||
@ -2167,18 +2170,20 @@ public final class String
|
||||
* given replacement.
|
||||
*
|
||||
* <p> An invocation of this method of the form
|
||||
* <i>str</i><tt>.replaceAll(</tt><i>regex</i><tt>,</tt> <i>repl</i><tt>)</tt>
|
||||
* <i>str</i>{@code .replaceAll(}<i>regex</i>{@code ,} <i>repl</i>{@code )}
|
||||
* yields exactly the same result as the expression
|
||||
*
|
||||
* <blockquote><tt>
|
||||
* {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile
|
||||
* compile}(</tt><i>regex</i><tt>).{@link
|
||||
* java.util.regex.Pattern#matcher(java.lang.CharSequence)
|
||||
* matcher}(</tt><i>str</i><tt>).{@link java.util.regex.Matcher#replaceAll
|
||||
* replaceAll}(</tt><i>repl</i><tt>)</tt></blockquote>
|
||||
* <blockquote>
|
||||
* <code>
|
||||
* {@link java.util.regex.Pattern}.{@link
|
||||
* java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
|
||||
* java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link
|
||||
* java.util.regex.Matcher#replaceAll replaceAll}(<i>repl</i>)
|
||||
* </code>
|
||||
* </blockquote>
|
||||
*
|
||||
*<p>
|
||||
* Note that backslashes (<tt>\</tt>) and dollar signs (<tt>$</tt>) in the
|
||||
* Note that backslashes ({@code \}) and dollar signs ({@code $}) in the
|
||||
* replacement string may cause the results to be different than if it were
|
||||
* being treated as a literal replacement string; see
|
||||
* {@link java.util.regex.Matcher#replaceAll Matcher.replaceAll}.
|
||||
@ -2190,7 +2195,7 @@ public final class String
|
||||
* @param replacement
|
||||
* the string to be substituted for each match
|
||||
*
|
||||
* @return The resulting <tt>String</tt>
|
||||
* @return The resulting {@code String}
|
||||
*
|
||||
* @throws PatternSyntaxException
|
||||
* if the regular expression's syntax is invalid
|
||||
@ -2234,7 +2239,7 @@ public final class String
|
||||
* expression does not match any part of the input then the resulting array
|
||||
* has just one element, namely this string.
|
||||
*
|
||||
* <p> The <tt>limit</tt> parameter controls the number of times the
|
||||
* <p> The {@code limit} parameter controls the number of times the
|
||||
* pattern is applied and therefore affects the length of the resulting
|
||||
* array. If the limit <i>n</i> is greater than zero then the pattern
|
||||
* will be applied at most <i>n</i> - 1 times, the array's
|
||||
@ -2245,7 +2250,7 @@ public final class String
|
||||
* the pattern will be applied as many times as possible, the array can
|
||||
* have any length, and trailing empty strings will be discarded.
|
||||
*
|
||||
* <p> The string <tt>"boo:and:foo"</tt>, for example, yields the
|
||||
* <p> The string {@code "boo:and:foo"}, for example, yields the
|
||||
* following results with these parameters:
|
||||
*
|
||||
* <blockquote><table cellpadding=1 cellspacing=0 summary="Split example showing regex, limit, and result">
|
||||
@ -2256,33 +2261,34 @@ public final class String
|
||||
* </tr>
|
||||
* <tr><td align=center>:</td>
|
||||
* <td align=center>2</td>
|
||||
* <td><tt>{ "boo", "and:foo" }</tt></td></tr>
|
||||
* <td>{@code { "boo", "and:foo" }}</td></tr>
|
||||
* <tr><td align=center>:</td>
|
||||
* <td align=center>5</td>
|
||||
* <td><tt>{ "boo", "and", "foo" }</tt></td></tr>
|
||||
* <td>{@code { "boo", "and", "foo" }}</td></tr>
|
||||
* <tr><td align=center>:</td>
|
||||
* <td align=center>-2</td>
|
||||
* <td><tt>{ "boo", "and", "foo" }</tt></td></tr>
|
||||
* <td>{@code { "boo", "and", "foo" }}</td></tr>
|
||||
* <tr><td align=center>o</td>
|
||||
* <td align=center>5</td>
|
||||
* <td><tt>{ "b", "", ":and:f", "", "" }</tt></td></tr>
|
||||
* <td>{@code { "b", "", ":and:f", "", "" }}</td></tr>
|
||||
* <tr><td align=center>o</td>
|
||||
* <td align=center>-2</td>
|
||||
* <td><tt>{ "b", "", ":and:f", "", "" }</tt></td></tr>
|
||||
* <td>{@code { "b", "", ":and:f", "", "" }}</td></tr>
|
||||
* <tr><td align=center>o</td>
|
||||
* <td align=center>0</td>
|
||||
* <td><tt>{ "b", "", ":and:f" }</tt></td></tr>
|
||||
* <td>{@code { "b", "", ":and:f" }}</td></tr>
|
||||
* </table></blockquote>
|
||||
*
|
||||
* <p> An invocation of this method of the form
|
||||
* <i>str.</i><tt>split(</tt><i>regex</i><tt>,</tt> <i>n</i><tt>)</tt>
|
||||
* <i>str.</i>{@code split(}<i>regex</i>{@code ,} <i>n</i>{@code )}
|
||||
* yields the same result as the expression
|
||||
*
|
||||
* <blockquote>
|
||||
* {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile
|
||||
* compile}<tt>(</tt><i>regex</i><tt>)</tt>.{@link
|
||||
* java.util.regex.Pattern#split(java.lang.CharSequence,int)
|
||||
* split}<tt>(</tt><i>str</i><tt>,</tt> <i>n</i><tt>)</tt>
|
||||
* <code>
|
||||
* {@link java.util.regex.Pattern}.{@link
|
||||
* java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
|
||||
* java.util.regex.Pattern#split(java.lang.CharSequence,int) split}(<i>str</i>, <i>n</i>)
|
||||
* </code>
|
||||
* </blockquote>
|
||||
*
|
||||
*
|
||||
@ -2364,7 +2370,7 @@ public final class String
|
||||
* argument of zero. Trailing empty strings are therefore not included in
|
||||
* the resulting array.
|
||||
*
|
||||
* <p> The string <tt>"boo:and:foo"</tt>, for example, yields the following
|
||||
* <p> The string {@code "boo:and:foo"}, for example, yields the following
|
||||
* results with these expressions:
|
||||
*
|
||||
* <blockquote><table cellpadding=1 cellspacing=0 summary="Split examples showing regex and result">
|
||||
@ -2373,9 +2379,9 @@ public final class String
|
||||
* <th>Result</th>
|
||||
* </tr>
|
||||
* <tr><td align=center>:</td>
|
||||
* <td><tt>{ "boo", "and", "foo" }</tt></td></tr>
|
||||
* <td>{@code { "boo", "and", "foo" }}</td></tr>
|
||||
* <tr><td align=center>o</td>
|
||||
* <td><tt>{ "b", "", ":and:f" }</tt></td></tr>
|
||||
* <td>{@code { "b", "", ":and:f" }}</td></tr>
|
||||
* </table></blockquote>
|
||||
*
|
||||
*
|
||||
@ -2815,7 +2821,7 @@ public final class String
|
||||
* limited by the maximum dimension of a Java array as defined by
|
||||
* <cite>The Java™ Virtual Machine Specification</cite>.
|
||||
* The behaviour on a
|
||||
* <tt>null</tt> argument depends on the <a
|
||||
* {@code null} argument depends on the <a
|
||||
* href="../util/Formatter.html#syntax">conversion</a>.
|
||||
*
|
||||
* @throws java.util.IllegalFormatException
|
||||
@ -2828,7 +2834,7 @@ public final class String
|
||||
* formatter class specification.
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* If the <tt>format</tt> is <tt>null</tt>
|
||||
* If the {@code format} is {@code null}
|
||||
*
|
||||
* @return A formatted string
|
||||
*
|
||||
@ -2845,7 +2851,7 @@ public final class String
|
||||
*
|
||||
* @param l
|
||||
* The {@linkplain java.util.Locale locale} to apply during
|
||||
* formatting. If <tt>l</tt> is <tt>null</tt> then no localization
|
||||
* formatting. If {@code l} is {@code null} then no localization
|
||||
* is applied.
|
||||
*
|
||||
* @param format
|
||||
@ -2859,7 +2865,7 @@ public final class String
|
||||
* limited by the maximum dimension of a Java array as defined by
|
||||
* <cite>The Java™ Virtual Machine Specification</cite>.
|
||||
* The behaviour on a
|
||||
* <tt>null</tt> argument depends on the <a
|
||||
* {@code null} argument depends on the <a
|
||||
* href="../util/Formatter.html#syntax">conversion</a>.
|
||||
*
|
||||
* @throws java.util.IllegalFormatException
|
||||
@ -2872,7 +2878,7 @@ public final class String
|
||||
* formatter class specification
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* If the <tt>format</tt> is <tt>null</tt>
|
||||
* If the {@code format} is {@code null}
|
||||
*
|
||||
* @return A formatted string
|
||||
*
|
||||
@ -3143,7 +3149,7 @@ public final class String
|
||||
* programmer should be aware that producing distinct integer results
|
||||
* for unequal objects may improve the performance of hash tables.
|
||||
* </ul>
|
||||
* <p/>
|
||||
* </p>
|
||||
* The hash value will never be zero.
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
|
@ -57,7 +57,7 @@ package java.lang;
|
||||
* <p>
|
||||
* In general, if sb refers to an instance of a {@code StringBuffer},
|
||||
* then {@code sb.append(x)} has the same effect as
|
||||
* {@code sb.insert(sb.length(), x)}.
|
||||
* {@code sb.insert(sb.length(), x)}.
|
||||
* <p>
|
||||
* Whenever an operation occurs involving a source sequence (such as
|
||||
* appending or inserting from a source sequence), this class synchronizes
|
||||
@ -80,7 +80,7 @@ package java.lang;
|
||||
*
|
||||
* As of release JDK 5, this class has been supplemented with an equivalent
|
||||
* class designed for use by a single thread, {@link StringBuilder}. The
|
||||
* <tt>StringBuilder</tt> class should generally be used in preference to
|
||||
* {@code StringBuilder} class should generally be used in preference to
|
||||
* this one, as it supports all of the same operations but it is faster, as
|
||||
* it performs no synchronization.
|
||||
*
|
||||
@ -262,17 +262,17 @@ package java.lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the specified <tt>StringBuffer</tt> to this sequence.
|
||||
* Appends the specified {@code StringBuffer} to this sequence.
|
||||
* <p>
|
||||
* The characters of the <tt>StringBuffer</tt> argument are appended,
|
||||
* in order, to the contents of this <tt>StringBuffer</tt>, increasing the
|
||||
* length of this <tt>StringBuffer</tt> by the length of the argument.
|
||||
* If <tt>sb</tt> is <tt>null</tt>, then the four characters
|
||||
* <tt>"null"</tt> are appended to this <tt>StringBuffer</tt>.
|
||||
* The characters of the {@code StringBuffer} argument are appended,
|
||||
* in order, to the contents of this {@code StringBuffer}, increasing the
|
||||
* length of this {@code StringBuffer} by the length of the argument.
|
||||
* If {@code sb} is {@code null}, then the four characters
|
||||
* {@code "null"} are appended to this {@code StringBuffer}.
|
||||
* <p>
|
||||
* Let <i>n</i> be the length of the old character sequence, the one
|
||||
* contained in the <tt>StringBuffer</tt> just prior to execution of the
|
||||
* <tt>append</tt> method. Then the character at index <i>k</i> in
|
||||
* contained in the {@code StringBuffer} just prior to execution of the
|
||||
* {@code append} method. Then the character at index <i>k</i> in
|
||||
* the new character sequence is equal to the character at index <i>k</i>
|
||||
* in the old character sequence, if <i>k</i> is less than <i>n</i>;
|
||||
* otherwise, it is equal to the character at index <i>k-n</i> in the
|
||||
@ -281,7 +281,7 @@ package java.lang;
|
||||
* This method synchronizes on {@code this}, the destination
|
||||
* object, but does not synchronize on the source ({@code sb}).
|
||||
*
|
||||
* @param sb the <tt>StringBuffer</tt> to append.
|
||||
* @param sb the {@code StringBuffer} to append.
|
||||
* @return a reference to this object.
|
||||
* @since 1.4
|
||||
*/
|
||||
|
@ -28,39 +28,39 @@ package java.lang;
|
||||
|
||||
/**
|
||||
* A mutable sequence of characters. This class provides an API compatible
|
||||
* with <code>StringBuffer</code>, but with no guarantee of synchronization.
|
||||
* with {@code StringBuffer}, but with no guarantee of synchronization.
|
||||
* This class is designed for use as a drop-in replacement for
|
||||
* <code>StringBuffer</code> in places where the string buffer was being
|
||||
* {@code StringBuffer} in places where the string buffer was being
|
||||
* used by a single thread (as is generally the case). Where possible,
|
||||
* it is recommended that this class be used in preference to
|
||||
* <code>StringBuffer</code> as it will be faster under most implementations.
|
||||
* {@code StringBuffer} as it will be faster under most implementations.
|
||||
*
|
||||
* <p>The principal operations on a <code>StringBuilder</code> are the
|
||||
* <code>append</code> and <code>insert</code> methods, which are
|
||||
* <p>The principal operations on a {@code StringBuilder} are the
|
||||
* {@code append} and {@code insert} methods, which are
|
||||
* overloaded so as to accept data of any type. Each effectively
|
||||
* converts a given datum to a string and then appends or inserts the
|
||||
* characters of that string to the string builder. The
|
||||
* <code>append</code> method always adds these characters at the end
|
||||
* of the builder; the <code>insert</code> method adds the characters at
|
||||
* {@code append} method always adds these characters at the end
|
||||
* of the builder; the {@code insert} method adds the characters at
|
||||
* a specified point.
|
||||
* <p>
|
||||
* For example, if <code>z</code> refers to a string builder object
|
||||
* whose current contents are "<code>start</code>", then
|
||||
* the method call <code>z.append("le")</code> would cause the string
|
||||
* builder to contain "<code>startle</code>", whereas
|
||||
* <code>z.insert(4, "le")</code> would alter the string builder to
|
||||
* contain "<code>starlet</code>".
|
||||
* For example, if {@code z} refers to a string builder object
|
||||
* whose current contents are "{@code start}", then
|
||||
* the method call {@code z.append("le")} would cause the string
|
||||
* builder to contain "{@code startle}", whereas
|
||||
* {@code z.insert(4, "le")} would alter the string builder to
|
||||
* contain "{@code starlet}".
|
||||
* <p>
|
||||
* In general, if sb refers to an instance of a {@code StringBuilder},
|
||||
* then {@code sb.append(x)} has the same effect as
|
||||
* {@code sb.insert(sb.length(), x)}.
|
||||
* <p>
|
||||
* In general, if sb refers to an instance of a <code>StringBuilder</code>,
|
||||
* then <code>sb.append(x)</code> has the same effect as
|
||||
* <code>sb.insert(sb.length(), x)</code>.
|
||||
*
|
||||
* Every string builder has a capacity. As long as the length of the
|
||||
* character sequence contained in the string builder does not exceed
|
||||
* the capacity, it is not necessary to allocate a new internal
|
||||
* buffer. If the internal buffer overflows, it is automatically made larger.
|
||||
*
|
||||
* <p>Instances of <code>StringBuilder</code> are not safe for
|
||||
* <p>Instances of {@code StringBuilder} are not safe for
|
||||
* use by multiple threads. If such synchronization is required then it is
|
||||
* recommended that {@link java.lang.StringBuffer} be used.
|
||||
*
|
||||
@ -87,11 +87,11 @@ public final class StringBuilder
|
||||
|
||||
/**
|
||||
* Constructs a string builder with no characters in it and an
|
||||
* initial capacity specified by the <code>capacity</code> argument.
|
||||
* initial capacity specified by the {@code capacity} argument.
|
||||
*
|
||||
* @param capacity the initial capacity.
|
||||
* @throws NegativeArraySizeException if the <code>capacity</code>
|
||||
* argument is less than <code>0</code>.
|
||||
* @throws NegativeArraySizeException if the {@code capacity}
|
||||
* argument is less than {@code 0}.
|
||||
*/
|
||||
public StringBuilder(int capacity) {
|
||||
super(capacity);
|
||||
@ -100,10 +100,10 @@ public final class StringBuilder
|
||||
/**
|
||||
* Constructs a string builder initialized to the contents of the
|
||||
* specified string. The initial capacity of the string builder is
|
||||
* <code>16</code> plus the length of the string argument.
|
||||
* {@code 16} plus the length of the string argument.
|
||||
*
|
||||
* @param str the initial contents of the buffer.
|
||||
* @throws NullPointerException if <code>str</code> is <code>null</code>
|
||||
* @throws NullPointerException if {@code str} is {@code null}
|
||||
*/
|
||||
public StringBuilder(String str) {
|
||||
super(str.length() + 16);
|
||||
@ -112,12 +112,12 @@ public final class StringBuilder
|
||||
|
||||
/**
|
||||
* Constructs a string builder that contains the same characters
|
||||
* as the specified <code>CharSequence</code>. The initial capacity of
|
||||
* the string builder is <code>16</code> plus the length of the
|
||||
* <code>CharSequence</code> argument.
|
||||
* as the specified {@code CharSequence}. The initial capacity of
|
||||
* the string builder is {@code 16} plus the length of the
|
||||
* {@code CharSequence} argument.
|
||||
*
|
||||
* @param seq the sequence to copy.
|
||||
* @throws NullPointerException if <code>seq</code> is <code>null</code>
|
||||
* @throws NullPointerException if {@code seq} is {@code null}
|
||||
*/
|
||||
public StringBuilder(CharSequence seq) {
|
||||
this(seq.length() + 16);
|
||||
@ -136,22 +136,22 @@ public final class StringBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the specified <tt>StringBuffer</tt> to this sequence.
|
||||
* Appends the specified {@code StringBuffer} to this sequence.
|
||||
* <p>
|
||||
* The characters of the <tt>StringBuffer</tt> argument are appended,
|
||||
* The characters of the {@code StringBuffer} argument are appended,
|
||||
* in order, to this sequence, increasing the
|
||||
* length of this sequence by the length of the argument.
|
||||
* If <tt>sb</tt> is <tt>null</tt>, then the four characters
|
||||
* <tt>"null"</tt> are appended to this sequence.
|
||||
* If {@code sb} is {@code null}, then the four characters
|
||||
* {@code "null"} are appended to this sequence.
|
||||
* <p>
|
||||
* Let <i>n</i> be the length of this character sequence just prior to
|
||||
* execution of the <tt>append</tt> method. Then the character at index
|
||||
* execution of the {@code append} method. Then the character at index
|
||||
* <i>k</i> in the new character sequence is equal to the character at
|
||||
* index <i>k</i> in the old character sequence, if <i>k</i> is less than
|
||||
* <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i>
|
||||
* in the argument <code>sb</code>.
|
||||
* in the argument {@code sb}.
|
||||
*
|
||||
* @param sb the <tt>StringBuffer</tt> to append.
|
||||
* @param sb the {@code StringBuffer} to append.
|
||||
* @return a reference to this object.
|
||||
*/
|
||||
public StringBuilder append(StringBuffer sb) {
|
||||
@ -418,13 +418,13 @@ public final class StringBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the state of the <tt>StringBuilder</tt> instance to a stream
|
||||
* Save the state of the {@code StringBuilder} instance to a stream
|
||||
* (that is, serialize it).
|
||||
*
|
||||
* @serialData the number of characters currently stored in the string
|
||||
* builder (<tt>int</tt>), followed by the characters in the
|
||||
* string builder (<tt>char[]</tt>). The length of the
|
||||
* <tt>char</tt> array may be greater than the number of
|
||||
* builder ({@code int}), followed by the characters in the
|
||||
* string builder ({@code char[]}). The length of the
|
||||
* {@code char} array may be greater than the number of
|
||||
* characters currently stored in the string builder, in which
|
||||
* case extra characters are ignored.
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,7 +26,7 @@
|
||||
package java.lang;
|
||||
|
||||
/**
|
||||
* Thrown by <code>String</code> methods to indicate that an index
|
||||
* Thrown by {@code String} methods to indicate that an index
|
||||
* is either negative or greater than the size of the string. For
|
||||
* some methods such as the charAt method, this exception also is
|
||||
* thrown when the index is equal to the size of the string.
|
||||
@ -40,7 +40,7 @@ class StringIndexOutOfBoundsException extends IndexOutOfBoundsException {
|
||||
private static final long serialVersionUID = -6762910422159637258L;
|
||||
|
||||
/**
|
||||
* Constructs a <code>StringIndexOutOfBoundsException</code> with no
|
||||
* Constructs a {@code StringIndexOutOfBoundsException} with no
|
||||
* detail message.
|
||||
*
|
||||
* @since JDK1.0.
|
||||
@ -50,7 +50,7 @@ class StringIndexOutOfBoundsException extends IndexOutOfBoundsException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>StringIndexOutOfBoundsException</code> with
|
||||
* Constructs a {@code StringIndexOutOfBoundsException} with
|
||||
* the specified detail message.
|
||||
*
|
||||
* @param s the detail message.
|
||||
@ -60,7 +60,7 @@ class StringIndexOutOfBoundsException extends IndexOutOfBoundsException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>StringIndexOutOfBoundsException</code>
|
||||
* Constructs a new {@code StringIndexOutOfBoundsException}
|
||||
* class with an argument indicating the illegal index.
|
||||
*
|
||||
* @param index the illegal index.
|
||||
|
48
jdk/src/share/classes/java/lang/annotation/Repeatable.java
Normal file
48
jdk/src/share/classes/java/lang/annotation/Repeatable.java
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.annotation;
|
||||
|
||||
/**
|
||||
* The annotation type {@code java.lang.annotation.Repeatable} is
|
||||
* used to indicate that the annotation type whose declaration it
|
||||
* (meta-)annotates is <em>repeatable</em>. The value of
|
||||
* {@code @Repeatable} indicates the <em>containing annotation
|
||||
* type</em> for the repeatable annotation type.
|
||||
*
|
||||
* @since 1.8
|
||||
* @jls 9.6 Annotation Types
|
||||
* @jls 9.7 Annotations
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.ANNOTATION_TYPE)
|
||||
public @interface Repeatable {
|
||||
/**
|
||||
* Indicates the <em>containing annotation type</em> for the
|
||||
* repeatable annotation type.
|
||||
*/
|
||||
Class<? extends Annotation> value();
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,8 @@
|
||||
|
||||
package java.security;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
/**
|
||||
* This interface represents the abstract notion of a principal, which
|
||||
* can be used to represent any entity, such as an individual, a
|
||||
@ -45,7 +47,6 @@ public interface Principal {
|
||||
*
|
||||
* @return true if the principal passed in is the same as that
|
||||
* encapsulated by this principal, and false otherwise.
|
||||
|
||||
*/
|
||||
public boolean equals(Object another);
|
||||
|
||||
@ -69,4 +70,24 @@ public interface Principal {
|
||||
* @return the name of this principal.
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* Returns true if the specified subject is implied by this principal.
|
||||
*
|
||||
* <p>The default implementation of this method returns true if
|
||||
* {@code subject} is non-null and contains at least one principal that
|
||||
* is equal to this principal.
|
||||
*
|
||||
* <p>Subclasses may override this with a different implementation, if
|
||||
* necessary.
|
||||
*
|
||||
* @return true if {@code subject} is non-null and is
|
||||
* implied by this principal, or false otherwise.
|
||||
* @since 1.8
|
||||
*/
|
||||
public default boolean implies(Subject subject) {
|
||||
if (subject == null)
|
||||
return false;
|
||||
return subject.getPrincipals().contains(this);
|
||||
}
|
||||
}
|
||||
|
@ -2611,6 +2611,7 @@ public class ForkJoinPool extends AbstractExecutorService {
|
||||
* {@link #shutdown} or {@link #shutdownNow}.
|
||||
*
|
||||
* @return the common pool instance
|
||||
* @since 1.8
|
||||
*/
|
||||
public static ForkJoinPool commonPool() {
|
||||
// assert commonPool != null : "static init error";
|
||||
@ -2793,6 +2794,7 @@ public class ForkJoinPool extends AbstractExecutorService {
|
||||
* Returns the targeted parallelism level of the common pool.
|
||||
*
|
||||
* @return the targeted parallelism level of the common pool
|
||||
* @since 1.8
|
||||
*/
|
||||
public static int getCommonPoolParallelism() {
|
||||
return commonPoolParallelism;
|
||||
|
@ -111,7 +111,7 @@ public class AtomicBoolean implements java.io.Serializable {
|
||||
*
|
||||
* @param expect the expected value
|
||||
* @param update the new value
|
||||
* @return true if successful.
|
||||
* @return true if successful
|
||||
*/
|
||||
public boolean weakCompareAndSet(boolean expect, boolean update) {
|
||||
int e = expect ? 1 : 0;
|
||||
@ -146,16 +146,16 @@ public class AtomicBoolean implements java.io.Serializable {
|
||||
* @return the previous value
|
||||
*/
|
||||
public final boolean getAndSet(boolean newValue) {
|
||||
for (;;) {
|
||||
boolean current = get();
|
||||
if (compareAndSet(current, newValue))
|
||||
return current;
|
||||
}
|
||||
boolean prev;
|
||||
do {
|
||||
prev = get();
|
||||
} while (!compareAndSet(prev, newValue));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the String representation of the current value.
|
||||
* @return the String representation of the current value.
|
||||
* @return the String representation of the current value
|
||||
*/
|
||||
public String toString() {
|
||||
return Boolean.toString(get());
|
||||
|
@ -115,11 +115,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
|
||||
* @return the previous value
|
||||
*/
|
||||
public final int getAndSet(int newValue) {
|
||||
for (;;) {
|
||||
int current = get();
|
||||
if (compareAndSet(current, newValue))
|
||||
return current;
|
||||
}
|
||||
return unsafe.getAndSetInt(this, valueOffset, newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,7 +141,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
|
||||
*
|
||||
* @param expect the expected value
|
||||
* @param update the new value
|
||||
* @return true if successful.
|
||||
* @return true if successful
|
||||
*/
|
||||
public final boolean weakCompareAndSet(int expect, int update) {
|
||||
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
|
||||
@ -157,12 +153,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
|
||||
* @return the previous value
|
||||
*/
|
||||
public final int getAndIncrement() {
|
||||
for (;;) {
|
||||
int current = get();
|
||||
int next = current + 1;
|
||||
if (compareAndSet(current, next))
|
||||
return current;
|
||||
}
|
||||
return getAndAdd(1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -171,12 +162,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
|
||||
* @return the previous value
|
||||
*/
|
||||
public final int getAndDecrement() {
|
||||
for (;;) {
|
||||
int current = get();
|
||||
int next = current - 1;
|
||||
if (compareAndSet(current, next))
|
||||
return current;
|
||||
}
|
||||
return getAndAdd(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,12 +172,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
|
||||
* @return the previous value
|
||||
*/
|
||||
public final int getAndAdd(int delta) {
|
||||
for (;;) {
|
||||
int current = get();
|
||||
int next = current + delta;
|
||||
if (compareAndSet(current, next))
|
||||
return current;
|
||||
}
|
||||
return unsafe.getAndAddInt(this, valueOffset, delta);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -200,12 +181,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
|
||||
* @return the updated value
|
||||
*/
|
||||
public final int incrementAndGet() {
|
||||
for (;;) {
|
||||
int current = get();
|
||||
int next = current + 1;
|
||||
if (compareAndSet(current, next))
|
||||
return next;
|
||||
}
|
||||
return getAndAdd(1) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -214,12 +190,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
|
||||
* @return the updated value
|
||||
*/
|
||||
public final int decrementAndGet() {
|
||||
for (;;) {
|
||||
int current = get();
|
||||
int next = current - 1;
|
||||
if (compareAndSet(current, next))
|
||||
return next;
|
||||
}
|
||||
return getAndAdd(-1) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -229,17 +200,12 @@ public class AtomicInteger extends Number implements java.io.Serializable {
|
||||
* @return the updated value
|
||||
*/
|
||||
public final int addAndGet(int delta) {
|
||||
for (;;) {
|
||||
int current = get();
|
||||
int next = current + delta;
|
||||
if (compareAndSet(current, next))
|
||||
return next;
|
||||
}
|
||||
return getAndAdd(delta) + delta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the String representation of the current value.
|
||||
* @return the String representation of the current value.
|
||||
* @return the String representation of the current value
|
||||
*/
|
||||
public String toString() {
|
||||
return Integer.toString(get());
|
||||
|
@ -145,12 +145,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
|
||||
* @return the previous value
|
||||
*/
|
||||
public final int getAndSet(int i, int newValue) {
|
||||
long offset = checkedByteOffset(i);
|
||||
while (true) {
|
||||
int current = getRaw(offset);
|
||||
if (compareAndSetRaw(offset, current, newValue))
|
||||
return current;
|
||||
}
|
||||
return unsafe.getAndSetInt(array, checkedByteOffset(i), newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -182,7 +177,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
|
||||
* @param i the index
|
||||
* @param expect the expected value
|
||||
* @param update the new value
|
||||
* @return true if successful.
|
||||
* @return true if successful
|
||||
*/
|
||||
public final boolean weakCompareAndSet(int i, int expect, int update) {
|
||||
return compareAndSet(i, expect, update);
|
||||
@ -216,12 +211,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
|
||||
* @return the previous value
|
||||
*/
|
||||
public final int getAndAdd(int i, int delta) {
|
||||
long offset = checkedByteOffset(i);
|
||||
while (true) {
|
||||
int current = getRaw(offset);
|
||||
if (compareAndSetRaw(offset, current, current + delta))
|
||||
return current;
|
||||
}
|
||||
return unsafe.getAndAddInt(array, checkedByteOffset(i), delta);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -231,7 +221,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
|
||||
* @return the updated value
|
||||
*/
|
||||
public final int incrementAndGet(int i) {
|
||||
return addAndGet(i, 1);
|
||||
return getAndAdd(i, 1) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,7 +231,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
|
||||
* @return the updated value
|
||||
*/
|
||||
public final int decrementAndGet(int i) {
|
||||
return addAndGet(i, -1);
|
||||
return getAndAdd(i, -1) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -252,13 +242,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
|
||||
* @return the updated value
|
||||
*/
|
||||
public final int addAndGet(int i, int delta) {
|
||||
long offset = checkedByteOffset(i);
|
||||
while (true) {
|
||||
int current = getRaw(offset);
|
||||
int next = current + delta;
|
||||
if (compareAndSetRaw(offset, current, next))
|
||||
return next;
|
||||
}
|
||||
return getAndAdd(i, delta) + delta;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -159,11 +159,11 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
* @return the previous value
|
||||
*/
|
||||
public int getAndSet(T obj, int newValue) {
|
||||
for (;;) {
|
||||
int current = get(obj);
|
||||
if (compareAndSet(obj, current, newValue))
|
||||
return current;
|
||||
}
|
||||
int prev;
|
||||
do {
|
||||
prev = get(obj);
|
||||
} while (!compareAndSet(obj, prev, newValue));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -174,12 +174,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
* @return the previous value
|
||||
*/
|
||||
public int getAndIncrement(T obj) {
|
||||
for (;;) {
|
||||
int current = get(obj);
|
||||
int next = current + 1;
|
||||
if (compareAndSet(obj, current, next))
|
||||
return current;
|
||||
}
|
||||
int prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = prev + 1;
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,12 +190,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
* @return the previous value
|
||||
*/
|
||||
public int getAndDecrement(T obj) {
|
||||
for (;;) {
|
||||
int current = get(obj);
|
||||
int next = current - 1;
|
||||
if (compareAndSet(obj, current, next))
|
||||
return current;
|
||||
}
|
||||
int prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = prev - 1;
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -207,12 +207,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
* @return the previous value
|
||||
*/
|
||||
public int getAndAdd(T obj, int delta) {
|
||||
for (;;) {
|
||||
int current = get(obj);
|
||||
int next = current + delta;
|
||||
if (compareAndSet(obj, current, next))
|
||||
return current;
|
||||
}
|
||||
int prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = prev + delta;
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -223,12 +223,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
* @return the updated value
|
||||
*/
|
||||
public int incrementAndGet(T obj) {
|
||||
for (;;) {
|
||||
int current = get(obj);
|
||||
int next = current + 1;
|
||||
if (compareAndSet(obj, current, next))
|
||||
return next;
|
||||
}
|
||||
int prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = prev + 1;
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -239,12 +239,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
* @return the updated value
|
||||
*/
|
||||
public int decrementAndGet(T obj) {
|
||||
for (;;) {
|
||||
int current = get(obj);
|
||||
int next = current - 1;
|
||||
if (compareAndSet(obj, current, next))
|
||||
return next;
|
||||
}
|
||||
int prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = prev - 1;
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -256,12 +256,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
* @return the updated value
|
||||
*/
|
||||
public int addAndGet(T obj, int delta) {
|
||||
for (;;) {
|
||||
int current = get(obj);
|
||||
int next = current + delta;
|
||||
if (compareAndSet(obj, current, next))
|
||||
return next;
|
||||
}
|
||||
int prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = prev + delta;
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -361,6 +361,36 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
return unsafe.getIntVolatile(obj, offset);
|
||||
}
|
||||
|
||||
public int getAndSet(T obj, int newValue) {
|
||||
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
|
||||
return unsafe.getAndSetInt(obj, offset, newValue);
|
||||
}
|
||||
|
||||
public int getAndIncrement(T obj) {
|
||||
return getAndAdd(obj, 1);
|
||||
}
|
||||
|
||||
public int getAndDecrement(T obj) {
|
||||
return getAndAdd(obj, -1);
|
||||
}
|
||||
|
||||
public int getAndAdd(T obj, int delta) {
|
||||
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
|
||||
return unsafe.getAndAddInt(obj, offset, delta);
|
||||
}
|
||||
|
||||
public int incrementAndGet(T obj) {
|
||||
return getAndAdd(obj, 1) + 1;
|
||||
}
|
||||
|
||||
public int decrementAndGet(T obj) {
|
||||
return getAndAdd(obj, -1) - 1;
|
||||
}
|
||||
|
||||
public int addAndGet(T obj, int delta) {
|
||||
return getAndAdd(obj, delta) + delta;
|
||||
}
|
||||
|
||||
private void ensureProtectedAccess(T obj) {
|
||||
if (cclass.isInstance(obj)) {
|
||||
return;
|
||||
|
@ -129,11 +129,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
|
||||
* @return the previous value
|
||||
*/
|
||||
public final long getAndSet(long newValue) {
|
||||
while (true) {
|
||||
long current = get();
|
||||
if (compareAndSet(current, newValue))
|
||||
return current;
|
||||
}
|
||||
return unsafe.getAndSetLong(this, valueOffset, newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -159,7 +155,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
|
||||
*
|
||||
* @param expect the expected value
|
||||
* @param update the new value
|
||||
* @return true if successful.
|
||||
* @return true if successful
|
||||
*/
|
||||
public final boolean weakCompareAndSet(long expect, long update) {
|
||||
return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
|
||||
@ -171,12 +167,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
|
||||
* @return the previous value
|
||||
*/
|
||||
public final long getAndIncrement() {
|
||||
while (true) {
|
||||
long current = get();
|
||||
long next = current + 1;
|
||||
if (compareAndSet(current, next))
|
||||
return current;
|
||||
}
|
||||
return getAndAdd(1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -185,12 +176,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
|
||||
* @return the previous value
|
||||
*/
|
||||
public final long getAndDecrement() {
|
||||
while (true) {
|
||||
long current = get();
|
||||
long next = current - 1;
|
||||
if (compareAndSet(current, next))
|
||||
return current;
|
||||
}
|
||||
return getAndAdd(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -200,12 +186,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
|
||||
* @return the previous value
|
||||
*/
|
||||
public final long getAndAdd(long delta) {
|
||||
while (true) {
|
||||
long current = get();
|
||||
long next = current + delta;
|
||||
if (compareAndSet(current, next))
|
||||
return current;
|
||||
}
|
||||
return unsafe.getAndAddLong(this, valueOffset, delta);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -214,12 +195,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
|
||||
* @return the updated value
|
||||
*/
|
||||
public final long incrementAndGet() {
|
||||
for (;;) {
|
||||
long current = get();
|
||||
long next = current + 1;
|
||||
if (compareAndSet(current, next))
|
||||
return next;
|
||||
}
|
||||
return getAndAdd(1) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -228,12 +204,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
|
||||
* @return the updated value
|
||||
*/
|
||||
public final long decrementAndGet() {
|
||||
for (;;) {
|
||||
long current = get();
|
||||
long next = current - 1;
|
||||
if (compareAndSet(current, next))
|
||||
return next;
|
||||
}
|
||||
return getAndAdd(-1) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -243,17 +214,12 @@ public class AtomicLong extends Number implements java.io.Serializable {
|
||||
* @return the updated value
|
||||
*/
|
||||
public final long addAndGet(long delta) {
|
||||
for (;;) {
|
||||
long current = get();
|
||||
long next = current + delta;
|
||||
if (compareAndSet(current, next))
|
||||
return next;
|
||||
}
|
||||
return getAndAdd(delta) + delta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the String representation of the current value.
|
||||
* @return the String representation of the current value.
|
||||
* @return the String representation of the current value
|
||||
*/
|
||||
public String toString() {
|
||||
return Long.toString(get());
|
||||
|
@ -144,12 +144,7 @@ public class AtomicLongArray implements java.io.Serializable {
|
||||
* @return the previous value
|
||||
*/
|
||||
public final long getAndSet(int i, long newValue) {
|
||||
long offset = checkedByteOffset(i);
|
||||
while (true) {
|
||||
long current = getRaw(offset);
|
||||
if (compareAndSetRaw(offset, current, newValue))
|
||||
return current;
|
||||
}
|
||||
return unsafe.getAndSetLong(array, checkedByteOffset(i), newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -181,7 +176,7 @@ public class AtomicLongArray implements java.io.Serializable {
|
||||
* @param i the index
|
||||
* @param expect the expected value
|
||||
* @param update the new value
|
||||
* @return true if successful.
|
||||
* @return true if successful
|
||||
*/
|
||||
public final boolean weakCompareAndSet(int i, long expect, long update) {
|
||||
return compareAndSet(i, expect, update);
|
||||
@ -215,12 +210,7 @@ public class AtomicLongArray implements java.io.Serializable {
|
||||
* @return the previous value
|
||||
*/
|
||||
public final long getAndAdd(int i, long delta) {
|
||||
long offset = checkedByteOffset(i);
|
||||
while (true) {
|
||||
long current = getRaw(offset);
|
||||
if (compareAndSetRaw(offset, current, current + delta))
|
||||
return current;
|
||||
}
|
||||
return unsafe.getAndAddLong(array, checkedByteOffset(i), delta);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,7 +220,7 @@ public class AtomicLongArray implements java.io.Serializable {
|
||||
* @return the updated value
|
||||
*/
|
||||
public final long incrementAndGet(int i) {
|
||||
return addAndGet(i, 1);
|
||||
return getAndAdd(i, 1) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -240,7 +230,7 @@ public class AtomicLongArray implements java.io.Serializable {
|
||||
* @return the updated value
|
||||
*/
|
||||
public final long decrementAndGet(int i) {
|
||||
return addAndGet(i, -1);
|
||||
return getAndAdd(i, -1) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -251,13 +241,7 @@ public class AtomicLongArray implements java.io.Serializable {
|
||||
* @return the updated value
|
||||
*/
|
||||
public long addAndGet(int i, long delta) {
|
||||
long offset = checkedByteOffset(i);
|
||||
while (true) {
|
||||
long current = getRaw(offset);
|
||||
long next = current + delta;
|
||||
if (compareAndSetRaw(offset, current, next))
|
||||
return next;
|
||||
}
|
||||
return getAndAdd(i, delta) + delta;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,7 +98,7 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
* @param obj An object whose field to conditionally set
|
||||
* @param expect the expected value
|
||||
* @param update the new value
|
||||
* @return true if successful.
|
||||
* @return true if successful
|
||||
* @throws ClassCastException if {@code obj} is not an instance
|
||||
* of the class possessing the field established in the constructor.
|
||||
*/
|
||||
@ -118,7 +118,7 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
* @param obj An object whose field to conditionally set
|
||||
* @param expect the expected value
|
||||
* @param update the new value
|
||||
* @return true if successful.
|
||||
* @return true if successful
|
||||
* @throws ClassCastException if {@code obj} is not an instance
|
||||
* of the class possessing the field established in the constructor.
|
||||
*/
|
||||
@ -162,11 +162,11 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
* @return the previous value
|
||||
*/
|
||||
public long getAndSet(T obj, long newValue) {
|
||||
for (;;) {
|
||||
long current = get(obj);
|
||||
if (compareAndSet(obj, current, newValue))
|
||||
return current;
|
||||
}
|
||||
long prev;
|
||||
do {
|
||||
prev = get(obj);
|
||||
} while (!compareAndSet(obj, prev, newValue));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -177,12 +177,12 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
* @return the previous value
|
||||
*/
|
||||
public long getAndIncrement(T obj) {
|
||||
for (;;) {
|
||||
long current = get(obj);
|
||||
long next = current + 1;
|
||||
if (compareAndSet(obj, current, next))
|
||||
return current;
|
||||
}
|
||||
long prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = prev + 1;
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -193,12 +193,12 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
* @return the previous value
|
||||
*/
|
||||
public long getAndDecrement(T obj) {
|
||||
for (;;) {
|
||||
long current = get(obj);
|
||||
long next = current - 1;
|
||||
if (compareAndSet(obj, current, next))
|
||||
return current;
|
||||
}
|
||||
long prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = prev - 1;
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -210,12 +210,12 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
* @return the previous value
|
||||
*/
|
||||
public long getAndAdd(T obj, long delta) {
|
||||
for (;;) {
|
||||
long current = get(obj);
|
||||
long next = current + delta;
|
||||
if (compareAndSet(obj, current, next))
|
||||
return current;
|
||||
}
|
||||
long prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = prev + delta;
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -226,12 +226,12 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
* @return the updated value
|
||||
*/
|
||||
public long incrementAndGet(T obj) {
|
||||
for (;;) {
|
||||
long current = get(obj);
|
||||
long next = current + 1;
|
||||
if (compareAndSet(obj, current, next))
|
||||
return next;
|
||||
}
|
||||
long prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = prev + 1;
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -242,12 +242,12 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
* @return the updated value
|
||||
*/
|
||||
public long decrementAndGet(T obj) {
|
||||
for (;;) {
|
||||
long current = get(obj);
|
||||
long next = current - 1;
|
||||
if (compareAndSet(obj, current, next))
|
||||
return next;
|
||||
}
|
||||
long prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = prev - 1;
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,12 +259,12 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
* @return the updated value
|
||||
*/
|
||||
public long addAndGet(T obj, long delta) {
|
||||
for (;;) {
|
||||
long current = get(obj);
|
||||
long next = current + delta;
|
||||
if (compareAndSet(obj, current, next))
|
||||
return next;
|
||||
}
|
||||
long prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = prev + delta;
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
|
||||
@ -345,6 +345,36 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
return unsafe.getLongVolatile(obj, offset);
|
||||
}
|
||||
|
||||
public long getAndSet(T obj, long newValue) {
|
||||
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
|
||||
return unsafe.getAndSetLong(obj, offset, newValue);
|
||||
}
|
||||
|
||||
public long getAndIncrement(T obj) {
|
||||
return getAndAdd(obj, 1);
|
||||
}
|
||||
|
||||
public long getAndDecrement(T obj) {
|
||||
return getAndAdd(obj, -1);
|
||||
}
|
||||
|
||||
public long getAndAdd(T obj, long delta) {
|
||||
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
|
||||
return unsafe.getAndAddLong(obj, offset, delta);
|
||||
}
|
||||
|
||||
public long incrementAndGet(T obj) {
|
||||
return getAndAdd(obj, 1) + 1;
|
||||
}
|
||||
|
||||
public long decrementAndGet(T obj) {
|
||||
return getAndAdd(obj, -1) - 1;
|
||||
}
|
||||
|
||||
public long addAndGet(T obj, long delta) {
|
||||
return getAndAdd(obj, delta) + delta;
|
||||
}
|
||||
|
||||
private void ensureProtectedAccess(T obj) {
|
||||
if (cclass.isInstance(obj)) {
|
||||
return;
|
||||
|
@ -124,7 +124,7 @@ public class AtomicReference<V> implements java.io.Serializable {
|
||||
*
|
||||
* @param expect the expected value
|
||||
* @param update the new value
|
||||
* @return true if successful.
|
||||
* @return true if successful
|
||||
*/
|
||||
public final boolean weakCompareAndSet(V expect, V update) {
|
||||
return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
|
||||
@ -136,17 +136,14 @@ public class AtomicReference<V> implements java.io.Serializable {
|
||||
* @param newValue the new value
|
||||
* @return the previous value
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public final V getAndSet(V newValue) {
|
||||
while (true) {
|
||||
V x = get();
|
||||
if (compareAndSet(x, newValue))
|
||||
return x;
|
||||
}
|
||||
return (V)unsafe.getAndSetObject(this, valueOffset, newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the String representation of the current value.
|
||||
* @return the String representation of the current value.
|
||||
* @return the String representation of the current value
|
||||
*/
|
||||
public String toString() {
|
||||
return String.valueOf(get());
|
||||
|
@ -159,13 +159,9 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
|
||||
* @param newValue the new value
|
||||
* @return the previous value
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public final E getAndSet(int i, E newValue) {
|
||||
long offset = checkedByteOffset(i);
|
||||
while (true) {
|
||||
E current = getRaw(offset);
|
||||
if (compareAndSetRaw(offset, current, newValue))
|
||||
return current;
|
||||
}
|
||||
return (E)unsafe.getAndSetObject(array, checkedByteOffset(i), newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -197,7 +193,7 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
|
||||
* @param i the index
|
||||
* @param expect the expected value
|
||||
* @param update the new value
|
||||
* @return true if successful.
|
||||
* @return true if successful
|
||||
*/
|
||||
public final boolean weakCompareAndSet(int i, E expect, E update) {
|
||||
return compareAndSet(i, expect, update);
|
||||
|
@ -116,7 +116,7 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
|
||||
* @param obj An object whose field to conditionally set
|
||||
* @param expect the expected value
|
||||
* @param update the new value
|
||||
* @return true if successful.
|
||||
* @return true if successful
|
||||
*/
|
||||
public abstract boolean compareAndSet(T obj, V expect, V update);
|
||||
|
||||
@ -134,7 +134,7 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
|
||||
* @param obj An object whose field to conditionally set
|
||||
* @param expect the expected value
|
||||
* @param update the new value
|
||||
* @return true if successful.
|
||||
* @return true if successful
|
||||
*/
|
||||
public abstract boolean weakCompareAndSet(T obj, V expect, V update);
|
||||
|
||||
@ -176,11 +176,11 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
|
||||
* @return the previous value
|
||||
*/
|
||||
public V getAndSet(T obj, V newValue) {
|
||||
for (;;) {
|
||||
V current = get(obj);
|
||||
if (compareAndSet(obj, current, newValue))
|
||||
return current;
|
||||
}
|
||||
V prev;
|
||||
do {
|
||||
prev = get(obj);
|
||||
} while (!compareAndSet(obj, prev, newValue));
|
||||
return prev;
|
||||
}
|
||||
|
||||
private static final class AtomicReferenceFieldUpdaterImpl<T,V>
|
||||
@ -321,6 +321,15 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
|
||||
return (V)unsafe.getObjectVolatile(obj, offset);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public V getAndSet(T obj, V newValue) {
|
||||
if (obj == null || obj.getClass() != tclass || cclass != null ||
|
||||
(newValue != null && vclass != null &&
|
||||
vclass != newValue.getClass()))
|
||||
updateCheck(obj, newValue);
|
||||
return (V)unsafe.getAndSetObject(obj, offset, newValue);
|
||||
}
|
||||
|
||||
private void ensureProtectedAccess(T obj) {
|
||||
if (cclass.isInstance(obj)) {
|
||||
return;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -104,17 +104,30 @@ import sun.security.jca.*;
|
||||
* must be supplied to GCM/CCM implementations (via the {@code
|
||||
* updateAAD} methods) <b>before</b> the ciphertext is processed (via
|
||||
* the {@code update} and {@code doFinal} methods).
|
||||
*
|
||||
* <p>
|
||||
* Note that GCM mode has a uniqueness requirement on IVs used in
|
||||
* encryption with a given key. When IVs are repeated for GCM
|
||||
* encryption, such usages are subject to forgery attacks. Thus, after
|
||||
* each encryption operation using GCM mode, callers should re-initialize
|
||||
* the cipher objects with GCM parameters which has a different IV value.
|
||||
* <pre>
|
||||
* GCMParameterSpec s = new GCMParameterSpec(...);
|
||||
* GCMParameterSpec s = ...;
|
||||
* cipher.init(..., s);
|
||||
*
|
||||
* // If the GCMParameterSpec is needed again
|
||||
* cipher.getParameters().getParameterSpec(GCMParameterSpec.class));
|
||||
* // If the GCM parameters were generated by the provider, it can
|
||||
* // be retrieved by:
|
||||
* // cipher.getParameters().getParameterSpec(GCMParameterSpec.class);
|
||||
*
|
||||
* cipher.updateAAD(...); // AAD
|
||||
* cipher.update(...); // Multi-part update
|
||||
* cipher.doFinal(...); // conclusion of operation
|
||||
*
|
||||
* // Use a different IV value for every encryption
|
||||
* byte[] newIv = ...;
|
||||
* s = new GCMParameterSpec(s.getTLen(), newIv);
|
||||
* cipher.init(..., s);
|
||||
* ...
|
||||
*
|
||||
* </pre>
|
||||
* Every implementation of the Java platform is required to support
|
||||
* the following standard <code>Cipher</code> transformations with the keysizes
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 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
|
||||
@ -43,7 +43,7 @@ import java.security.spec.AlgorithmParameterSpec;
|
||||
* (Additional Authenticated Data (AAD), Keys, block ciphers,
|
||||
* plain/ciphertext and authentication tags) are handled in the {@code
|
||||
* Cipher} class.
|
||||
<p>
|
||||
* <p>
|
||||
* Please see <a href="http://www.ietf.org/rfc/rfc5116.txt"> RFC 5116
|
||||
* </a> for more information on the Authenticated Encryption with
|
||||
* Associated Data (AEAD) algorithm, and <a href=
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 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
|
||||
@ -409,6 +409,15 @@ public enum LauncherHelper {
|
||||
if (mainValue == null) {
|
||||
abort(null, "java.launcher.jar.error3", jarname);
|
||||
}
|
||||
/*
|
||||
* Hand off to FXHelper if it detects a JavaFX application
|
||||
* This must be done after ensuring a Main-Class entry
|
||||
* exists to enforce compliance with the jar specification
|
||||
*/
|
||||
if (mainAttrs.containsKey(
|
||||
new Attributes.Name(FXHelper.JAVAFX_APPLICATION_MARKER))) {
|
||||
return FXHelper.class.getName();
|
||||
}
|
||||
return mainValue.trim();
|
||||
} catch (IOException ioe) {
|
||||
abort(ioe, "java.launcher.jar.error1", jarname);
|
||||
@ -483,26 +492,23 @@ public enum LauncherHelper {
|
||||
} catch (NoClassDefFoundError | ClassNotFoundException cnfe) {
|
||||
abort(cnfe, "java.launcher.cls.error1", cn);
|
||||
}
|
||||
// set to mainClass, FXHelper may return something else
|
||||
// set to mainClass
|
||||
appClass = mainClass;
|
||||
|
||||
Method m = getMainMethod(mainClass);
|
||||
if (m != null) {
|
||||
// this will abort if main method has the wrong signature
|
||||
validateMainMethod(m);
|
||||
return mainClass;
|
||||
/*
|
||||
* Check if FXHelper can launch it using the FX launcher. In an FX app,
|
||||
* the main class may or may not have a main method, so do this before
|
||||
* validating the main class.
|
||||
*/
|
||||
if (mainClass.equals(FXHelper.class) ||
|
||||
FXHelper.doesExtendFXApplication(mainClass)) {
|
||||
// Will abort() if there are problems with the FX runtime
|
||||
FXHelper.setFXLaunchParameters(what, mode);
|
||||
return FXHelper.class;
|
||||
}
|
||||
|
||||
// Check if FXHelper can launch it using the FX launcher
|
||||
Class<?> fxClass = FXHelper.getFXMainClass(mainClass);
|
||||
if (fxClass != null) {
|
||||
return fxClass;
|
||||
}
|
||||
|
||||
// not an FX application either, abort with an error
|
||||
abort(null, "java.launcher.cls.error4", mainClass.getName(),
|
||||
FXHelper.JAVAFX_APPLICATION_CLASS_NAME);
|
||||
return null; // avoid compiler error...
|
||||
validateMainClass(mainClass);
|
||||
return mainClass;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -515,16 +521,18 @@ public enum LauncherHelper {
|
||||
return appClass;
|
||||
}
|
||||
|
||||
// Check for main method or return null if not found
|
||||
static Method getMainMethod(Class<?> clazz) {
|
||||
// Check the existence and signature of main and abort if incorrect
|
||||
static void validateMainClass(Class<?> mainClass) {
|
||||
Method mainMethod;
|
||||
try {
|
||||
return clazz.getMethod("main", String[].class);
|
||||
} catch (NoSuchMethodException nsme) {}
|
||||
return null;
|
||||
}
|
||||
mainMethod = mainClass.getMethod("main", String[].class);
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
// invalid main or not FX application, abort with an error
|
||||
abort(null, "java.launcher.cls.error4", mainClass.getName(),
|
||||
FXHelper.JAVAFX_APPLICATION_CLASS_NAME);
|
||||
return; // Avoid compiler issues
|
||||
}
|
||||
|
||||
// Check the signature of main and abort if it's incorrect
|
||||
static void validateMainMethod(Method mainMethod) {
|
||||
/*
|
||||
* getMethod (above) will choose the correct method, based
|
||||
* on its name and parameter type, however, we still have to
|
||||
@ -644,41 +652,78 @@ public enum LauncherHelper {
|
||||
}
|
||||
|
||||
static final class FXHelper {
|
||||
// Marker entry in jar manifest that designates a JavaFX application jar
|
||||
private static final String JAVAFX_APPLICATION_MARKER =
|
||||
"JavaFX-Application-Class";
|
||||
private static final String JAVAFX_APPLICATION_CLASS_NAME =
|
||||
"javafx.application.Application";
|
||||
private static final String JAVAFX_LAUNCHER_CLASS_NAME =
|
||||
"com.sun.javafx.application.LauncherImpl";
|
||||
|
||||
/*
|
||||
* The launch method used to invoke the JavaFX launcher. These must
|
||||
* match the strings used in the launchApplication method.
|
||||
*
|
||||
* Command line JavaFX-App-Class Launch mode FX Launch mode
|
||||
* java -cp fxapp.jar FXClass N/A LM_CLASS "LM_CLASS"
|
||||
* java -cp somedir FXClass N/A LM_CLASS "LM_CLASS"
|
||||
* java -jar fxapp.jar Present LM_JAR "LM_JAR"
|
||||
* java -jar fxapp.jar Not Present LM_JAR "LM_JAR"
|
||||
*/
|
||||
private static final String JAVAFX_LAUNCH_MODE_CLASS = "LM_CLASS";
|
||||
private static final String JAVAFX_LAUNCH_MODE_JAR = "LM_JAR";
|
||||
|
||||
/*
|
||||
* FX application launcher and launch method, so we can launch
|
||||
* applications with no main method.
|
||||
*/
|
||||
private static String fxLaunchName = null;
|
||||
private static String fxLaunchMode = null;
|
||||
|
||||
private static Class<?> fxLauncherClass = null;
|
||||
private static Method fxLauncherMethod = null;
|
||||
|
||||
/*
|
||||
* We can assume that the class does NOT have a main method or it would
|
||||
* have been handled already. We do, however, need to check if the class
|
||||
* extends Application and the launcher is available and abort with an
|
||||
* error if it's not.
|
||||
* Set the launch params according to what was passed to LauncherHelper
|
||||
* so we can use the same launch mode for FX. Abort if there is any
|
||||
* issue with loading the FX runtime or with the launcher method.
|
||||
*/
|
||||
private static Class<?> getFXMainClass(Class<?> mainClass) {
|
||||
// Check if mainClass extends Application
|
||||
if (!doesExtendFXApplication(mainClass)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void setFXLaunchParameters(String what, int mode) {
|
||||
// Check for the FX launcher classes
|
||||
try {
|
||||
fxLauncherClass = scloader.loadClass(JAVAFX_LAUNCHER_CLASS_NAME);
|
||||
/*
|
||||
* signature must be:
|
||||
* public static void launchApplication(String launchName,
|
||||
* String launchMode, String[] args);
|
||||
*/
|
||||
fxLauncherMethod = fxLauncherClass.getMethod("launchApplication",
|
||||
Class.class, String[].class);
|
||||
String.class, String.class, String[].class);
|
||||
|
||||
// verify launcher signature as we do when validating the main method
|
||||
int mod = fxLauncherMethod.getModifiers();
|
||||
if (!Modifier.isStatic(mod)) {
|
||||
abort(null, "java.launcher.javafx.error1");
|
||||
}
|
||||
if (fxLauncherMethod.getReturnType() != java.lang.Void.TYPE) {
|
||||
abort(null, "java.launcher.javafx.error1");
|
||||
}
|
||||
} catch (ClassNotFoundException | NoSuchMethodException ex) {
|
||||
abort(ex, "java.launcher.cls.error5", ex);
|
||||
}
|
||||
|
||||
// That's all, return this class so we can launch later
|
||||
return FXHelper.class;
|
||||
fxLaunchName = what;
|
||||
switch (mode) {
|
||||
case LM_CLASS:
|
||||
fxLaunchMode = JAVAFX_LAUNCH_MODE_CLASS;
|
||||
break;
|
||||
case LM_JAR:
|
||||
fxLaunchMode = JAVAFX_LAUNCH_MODE_JAR;
|
||||
break;
|
||||
default:
|
||||
// should not have gotten this far...
|
||||
throw new InternalError(mode + ": Unknown launch mode");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -696,11 +741,15 @@ public enum LauncherHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
// preloader ?
|
||||
public static void main(String... args) throws Exception {
|
||||
if (fxLauncherMethod == null
|
||||
|| fxLaunchMode == null
|
||||
|| fxLaunchName == null) {
|
||||
throw new RuntimeException("Invalid JavaFX launch parameters");
|
||||
}
|
||||
// launch appClass via fxLauncherMethod
|
||||
fxLauncherMethod.invoke(null, new Object[] {appClass, args});
|
||||
fxLauncherMethod.invoke(null,
|
||||
new Object[] {fxLaunchName, fxLaunchMode, args});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,3 +140,6 @@ java.launcher.jar.error1=\
|
||||
java.launcher.jar.error2=manifest not found in {0}
|
||||
java.launcher.jar.error3=no main manifest attribute, in {0}
|
||||
java.launcher.init.error=initialization error
|
||||
java.launcher.javafx.error1=\
|
||||
Error: The JavaFX launchApplication method has the wrong signature, it\n\
|
||||
must be declared static and return a value of type void
|
||||
|
@ -206,7 +206,8 @@ public class AuthenticationHeader {
|
||||
|
||||
if(v == null) {
|
||||
if ((v=schemes.get ("digest")) == null) {
|
||||
if (((v=schemes.get("ntlm"))==null)) {
|
||||
if (!NTLMAuthenticationProxy.supported
|
||||
|| ((v=schemes.get("ntlm"))==null)) {
|
||||
v = schemes.get ("basic");
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ class InitSecContextToken extends InitialToken {
|
||||
* For the context acceptor to call. It reads the bytes out of an
|
||||
* InputStream and constructs an InitSecContextToken with them.
|
||||
*/
|
||||
InitSecContextToken(Krb5Context context, EncryptionKey[] keys,
|
||||
InitSecContextToken(Krb5Context context, Krb5AcceptCredential cred,
|
||||
InputStream is)
|
||||
throws IOException, GSSException, KrbException {
|
||||
|
||||
@ -105,7 +105,7 @@ class InitSecContextToken extends InitialToken {
|
||||
if (context.getChannelBinding() != null) {
|
||||
addr = context.getChannelBinding().getInitiatorAddress();
|
||||
}
|
||||
apReq = new KrbApReq(apReqBytes, keys, addr);
|
||||
apReq = new KrbApReq(apReqBytes, cred, addr);
|
||||
//debug("\nReceived AP-REQ and authenticated it.\n");
|
||||
|
||||
EncryptionKey sessionKey = apReq.getCreds().getSessionKey();
|
||||
|
@ -45,13 +45,10 @@ import javax.security.auth.DestroyFailedException;
|
||||
public class Krb5AcceptCredential
|
||||
implements Krb5CredElement {
|
||||
|
||||
private static final long serialVersionUID = 7714332137352567952L;
|
||||
private final Krb5NameElement name;
|
||||
private final ServiceCreds screds;
|
||||
|
||||
private Krb5NameElement name;
|
||||
|
||||
private Krb5Util.ServiceCreds screds;
|
||||
|
||||
private Krb5AcceptCredential(Krb5NameElement name, Krb5Util.ServiceCreds creds) {
|
||||
private Krb5AcceptCredential(Krb5NameElement name, ServiceCreds creds) {
|
||||
/*
|
||||
* Initialize this instance with the data from the acquired
|
||||
* KerberosKey. This class needs to be a KerberosKey too
|
||||
@ -69,11 +66,11 @@ public class Krb5AcceptCredential
|
||||
name.getKrb5PrincipalName().getName());
|
||||
final AccessControlContext acc = AccessController.getContext();
|
||||
|
||||
Krb5Util.ServiceCreds creds = null;
|
||||
ServiceCreds creds = null;
|
||||
try {
|
||||
creds = AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Krb5Util.ServiceCreds>() {
|
||||
public Krb5Util.ServiceCreds run() throws Exception {
|
||||
new PrivilegedExceptionAction<ServiceCreds>() {
|
||||
public ServiceCreds run() throws Exception {
|
||||
return Krb5Util.getServiceCreds(
|
||||
caller == GSSCaller.CALLER_UNKNOWN ? GSSCaller.CALLER_ACCEPT: caller,
|
||||
serverPrinc, acc);
|
||||
@ -92,8 +89,10 @@ public class Krb5AcceptCredential
|
||||
|
||||
if (name == null) {
|
||||
String fullName = creds.getName();
|
||||
name = Krb5NameElement.getInstance(fullName,
|
||||
if (fullName != null) {
|
||||
name = Krb5NameElement.getInstance(fullName,
|
||||
Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);
|
||||
}
|
||||
}
|
||||
|
||||
return new Krb5AcceptCredential(name, creds);
|
||||
@ -153,8 +152,8 @@ public class Krb5AcceptCredential
|
||||
return Krb5MechFactory.PROVIDER;
|
||||
}
|
||||
|
||||
EncryptionKey[] getKrb5EncryptionKeys() {
|
||||
return screds.getEKeys();
|
||||
public EncryptionKey[] getKrb5EncryptionKeys(PrincipalName princ) {
|
||||
return screds.getEKeys(princ);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -818,16 +818,23 @@ class Krb5Context implements GSSContextSpi {
|
||||
}
|
||||
myName = (Krb5NameElement) myCred.getName();
|
||||
|
||||
checkPermission(myName.getKrb5PrincipalName().getName(),
|
||||
"accept");
|
||||
|
||||
EncryptionKey[] secretKeys =
|
||||
((Krb5AcceptCredential) myCred).getKrb5EncryptionKeys();
|
||||
// If there is already a bound name, check now
|
||||
if (myName != null) {
|
||||
Krb5MechFactory.checkAcceptCredPermission(myName, myName);
|
||||
}
|
||||
|
||||
InitSecContextToken token = new InitSecContextToken(this,
|
||||
secretKeys, is);
|
||||
(Krb5AcceptCredential) myCred, is);
|
||||
PrincipalName clientName = token.getKrbApReq().getClient();
|
||||
peerName = Krb5NameElement.getInstance(clientName);
|
||||
|
||||
// If unbound, check after the bound name is found
|
||||
if (myName == null) {
|
||||
myName = Krb5NameElement.getInstance(
|
||||
token.getKrbApReq().getCreds().getServer());
|
||||
Krb5MechFactory.checkAcceptCredPermission(myName, myName);
|
||||
}
|
||||
|
||||
if (getMutualAuthState()) {
|
||||
retVal = new AcceptSecContextToken(this,
|
||||
token.getKrbApReq()).encode();
|
||||
|
@ -158,7 +158,7 @@ public final class Krb5MechFactory implements MechanismFactory {
|
||||
public static void checkAcceptCredPermission(Krb5NameElement name,
|
||||
GSSNameSpi originalName) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
if (sm != null && name != null) {
|
||||
ServicePermission perm = new ServicePermission
|
||||
(name.getKrb5PrincipalName().getName(), "accept");
|
||||
try {
|
||||
|
@ -186,114 +186,6 @@ public class Krb5Util {
|
||||
return subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Credentials of a service, the private secret to authenticate its
|
||||
* identity, which can be:
|
||||
* 1. Some KerberosKeys (generated from password)
|
||||
* 2. A KeyTab (for a typical service)
|
||||
* 3. A TGT (for S4U2proxy extension)
|
||||
*
|
||||
* Note that some creds can coexist. For example, a user2user service
|
||||
* can use its keytab (or keys) if the client can successfully obtain a
|
||||
* normal service ticket, otherwise, it can uses the TGT (actually, the
|
||||
* session key of the TGT) if the client can only acquire a service ticket
|
||||
* of ENC-TKT-IN-SKEY style.
|
||||
*/
|
||||
public static class ServiceCreds {
|
||||
private KerberosPrincipal kp;
|
||||
private List<KeyTab> ktabs;
|
||||
private List<KerberosKey> kk;
|
||||
private Subject subj;
|
||||
private KerberosTicket tgt;
|
||||
|
||||
private static ServiceCreds getInstance(
|
||||
Subject subj, String serverPrincipal) {
|
||||
|
||||
ServiceCreds sc = new ServiceCreds();
|
||||
sc.subj = subj;
|
||||
|
||||
for (KerberosPrincipal p: subj.getPrincipals(KerberosPrincipal.class)) {
|
||||
if (serverPrincipal == null ||
|
||||
p.getName().equals(serverPrincipal)) {
|
||||
sc.kp = p;
|
||||
serverPrincipal = p.getName();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sc.kp == null) {
|
||||
// Compatibility with old behavior: even when there is no
|
||||
// KerberosPrincipal, we can find one from KerberosKeys
|
||||
List<KerberosKey> keys = SubjectComber.findMany(
|
||||
subj, serverPrincipal, null, KerberosKey.class);
|
||||
if (!keys.isEmpty()) {
|
||||
sc.kp = keys.get(0).getPrincipal();
|
||||
serverPrincipal = sc.kp.getName();
|
||||
if (DEBUG) {
|
||||
System.out.println(">>> ServiceCreds: no kp?"
|
||||
+ " find one from kk: " + serverPrincipal);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
sc.ktabs = SubjectComber.findMany(
|
||||
subj, null, null, KeyTab.class);
|
||||
sc.kk = SubjectComber.findMany(
|
||||
subj, serverPrincipal, null, KerberosKey.class);
|
||||
sc.tgt = SubjectComber.find(
|
||||
subj, null, serverPrincipal, KerberosTicket.class);
|
||||
if (sc.ktabs.isEmpty() && sc.kk.isEmpty() && sc.tgt == null) {
|
||||
return null;
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return kp.getName();
|
||||
}
|
||||
|
||||
public KerberosKey[] getKKeys() {
|
||||
List<KerberosKey> keys = new ArrayList<>();
|
||||
for (KerberosKey k: kk) {
|
||||
keys.add(k);
|
||||
}
|
||||
for (KeyTab ktab: ktabs) {
|
||||
for (KerberosKey k: ktab.getKeys(kp)) {
|
||||
keys.add(k);
|
||||
}
|
||||
}
|
||||
return keys.toArray(new KerberosKey[keys.size()]);
|
||||
}
|
||||
|
||||
public EncryptionKey[] getEKeys() {
|
||||
KerberosKey[] kkeys = getKKeys();
|
||||
EncryptionKey[] ekeys = new EncryptionKey[kkeys.length];
|
||||
for (int i=0; i<ekeys.length; i++) {
|
||||
ekeys[i] = new EncryptionKey(
|
||||
kkeys[i].getEncoded(), kkeys[i].getKeyType(),
|
||||
new Integer(kkeys[i].getVersionNumber()));
|
||||
}
|
||||
return ekeys;
|
||||
}
|
||||
|
||||
public Credentials getInitCred() {
|
||||
if (tgt == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return ticketToCreds(tgt);
|
||||
} catch (KrbException | IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
kp = null;
|
||||
ktabs = null;
|
||||
kk = null;
|
||||
tgt = null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Retrieves the ServiceCreds for the specified server principal from
|
||||
* the Subject in the specified AccessControlContext. If not found, and if
|
||||
@ -361,5 +253,4 @@ public class Krb5Util {
|
||||
return KerberosSecrets.getJavaxSecurityAuthKerberosAccess().
|
||||
keyTabGetEncryptionKeys(ktab, cname);
|
||||
}
|
||||
|
||||
}
|
||||
|
229
jdk/src/share/classes/sun/security/jgss/krb5/ServiceCreds.java
Normal file
229
jdk/src/share/classes/sun/security/jgss/krb5/ServiceCreds.java
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. 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.jgss.krb5;
|
||||
|
||||
import javax.security.auth.kerberos.KerberosTicket;
|
||||
import javax.security.auth.kerberos.KerberosKey;
|
||||
import javax.security.auth.kerberos.KerberosPrincipal;
|
||||
import javax.security.auth.kerberos.KeyTab;
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
import sun.security.krb5.Credentials;
|
||||
import sun.security.krb5.EncryptionKey;
|
||||
import sun.security.krb5.KrbException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.Krb5;
|
||||
|
||||
/**
|
||||
* Credentials of a kerberos acceptor. A KerberosPrincipal object (kp) is
|
||||
* the principal. It can be specified as the serverPrincipal argument
|
||||
* in the getInstance() method, or uses only KerberosPrincipal in the subject.
|
||||
* Otherwise, the creds object is unbound and kp is null.
|
||||
*
|
||||
* The class also encapsulates various secrets, which can be:
|
||||
*
|
||||
* 1. Some KerberosKeys (generated from password)
|
||||
* 2. Some KeyTabs (for a typical service based on keytabs)
|
||||
* 3. A TGT (for S4U2proxy extension or user2user)
|
||||
*
|
||||
* Note that some secrets can coexist. For example, a user2user service
|
||||
* can use its keytab (or keys) if the client can successfully obtain a
|
||||
* normal service ticket, or it can use the TGT (actually, the session key
|
||||
* of the TGT) if the client can only acquire a service ticket
|
||||
* of ENC-TKT-IN-SKEY style.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public final class ServiceCreds {
|
||||
// The principal, or null if unbound
|
||||
private KerberosPrincipal kp;
|
||||
|
||||
// All principals in the subject's princ set
|
||||
private Set<KerberosPrincipal> allPrincs;
|
||||
|
||||
// All private credentials that can be used
|
||||
private List<KeyTab> ktabs;
|
||||
private List<KerberosKey> kk;
|
||||
private KerberosTicket tgt;
|
||||
|
||||
private boolean destroyed;
|
||||
|
||||
private ServiceCreds() {
|
||||
// Make sure this class cannot be instantiated externally.
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ServiceCreds object based on info in a Subject for
|
||||
* a given principal name (if specified).
|
||||
* @return the object, or null if there is no private creds for it
|
||||
*/
|
||||
public static ServiceCreds getInstance(
|
||||
Subject subj, String serverPrincipal) {
|
||||
|
||||
ServiceCreds sc = new ServiceCreds();
|
||||
|
||||
sc.allPrincs =
|
||||
subj.getPrincipals(KerberosPrincipal.class);
|
||||
|
||||
// Compatibility. A key implies its own principal
|
||||
for (KerberosKey key: SubjectComber.findMany(
|
||||
subj, serverPrincipal, null, KerberosKey.class)) {
|
||||
sc.allPrincs.add(key.getPrincipal());
|
||||
}
|
||||
|
||||
if (serverPrincipal != null) { // A named principal
|
||||
sc.kp = new KerberosPrincipal(serverPrincipal);
|
||||
} else {
|
||||
if (sc.allPrincs.size() == 1) { // choose the only one
|
||||
sc.kp = sc.allPrincs.iterator().next();
|
||||
serverPrincipal = sc.kp.getName();
|
||||
}
|
||||
}
|
||||
|
||||
sc.ktabs = SubjectComber.findMany(
|
||||
subj, serverPrincipal, null, KeyTab.class);
|
||||
sc.kk = SubjectComber.findMany(
|
||||
subj, serverPrincipal, null, KerberosKey.class);
|
||||
sc.tgt = SubjectComber.find(
|
||||
subj, null, serverPrincipal, KerberosTicket.class);
|
||||
if (sc.ktabs.isEmpty() && sc.kk.isEmpty() && sc.tgt == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
sc.destroyed = false;
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
// can be null
|
||||
public String getName() {
|
||||
if (destroyed) {
|
||||
throw new IllegalStateException("This object is destroyed");
|
||||
}
|
||||
return kp == null ? null : kp.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets keys for someone unknown.
|
||||
* Used by TLS or as a fallback in getEKeys(). Can still return an
|
||||
* empty array.
|
||||
*/
|
||||
public KerberosKey[] getKKeys() {
|
||||
if (destroyed) {
|
||||
throw new IllegalStateException("This object is destroyed");
|
||||
}
|
||||
if (kp != null) {
|
||||
return getKKeys(kp);
|
||||
} else if (!allPrincs.isEmpty()) {
|
||||
return getKKeys(allPrincs.iterator().next());
|
||||
}
|
||||
return new KerberosKey[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get kkeys for a principal,
|
||||
* @param princ the target name initiator requests. Not null.
|
||||
* @return keys for the princ, never null, might be empty
|
||||
*/
|
||||
private KerberosKey[] getKKeys(KerberosPrincipal princ) {
|
||||
ArrayList<KerberosKey> keys = new ArrayList<>();
|
||||
if (kp != null && !princ.equals(kp)) {
|
||||
return new KerberosKey[0]; // Not me
|
||||
}
|
||||
if (!allPrincs.contains(princ)) {
|
||||
return new KerberosKey[0]; // Not someone I know, This check
|
||||
// is necessary but a KeyTab has
|
||||
// no principal name recorded.
|
||||
}
|
||||
for (KerberosKey k: kk) {
|
||||
if (k.getPrincipal().equals(princ)) {
|
||||
keys.add(k);
|
||||
}
|
||||
}
|
||||
for (KeyTab ktab: ktabs) {
|
||||
for (KerberosKey k: ktab.getKeys(princ)) {
|
||||
keys.add(k);
|
||||
}
|
||||
}
|
||||
return keys.toArray(new KerberosKey[keys.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets EKeys for a principal.
|
||||
* @param princ the target name initiator requests. Not null.
|
||||
* @return keys for the princ, never null, might be empty
|
||||
*/
|
||||
public EncryptionKey[] getEKeys(PrincipalName princ) {
|
||||
if (destroyed) {
|
||||
throw new IllegalStateException("This object is destroyed");
|
||||
}
|
||||
KerberosKey[] kkeys = getKKeys(new KerberosPrincipal(princ.getName()));
|
||||
if (kkeys.length == 0) {
|
||||
// Note: old JDK does not perform real name checking. If the
|
||||
// acceptor starts by name A but initiator requests for B,
|
||||
// as long as their keys match (i.e. A's keys can decrypt B's
|
||||
// service ticket), the authentication is OK. There are real
|
||||
// customers depending on this to use different names for a
|
||||
// single service.
|
||||
kkeys = getKKeys();
|
||||
}
|
||||
EncryptionKey[] ekeys = new EncryptionKey[kkeys.length];
|
||||
for (int i=0; i<ekeys.length; i++) {
|
||||
ekeys[i] = new EncryptionKey(
|
||||
kkeys[i].getEncoded(), kkeys[i].getKeyType(),
|
||||
new Integer(kkeys[i].getVersionNumber()));
|
||||
}
|
||||
return ekeys;
|
||||
}
|
||||
|
||||
public Credentials getInitCred() {
|
||||
if (destroyed) {
|
||||
throw new IllegalStateException("This object is destroyed");
|
||||
}
|
||||
if (tgt == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Krb5Util.ticketToCreds(tgt);
|
||||
} catch (KrbException | IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
// Do not wipe out real keys because they are references to the
|
||||
// priv creds in subject. Just make it useless.
|
||||
destroyed = true;
|
||||
kp = null;
|
||||
ktabs.clear();
|
||||
kk.clear();
|
||||
tgt = null;
|
||||
}
|
||||
}
|
@ -33,6 +33,7 @@ import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.security.auth.kerberos.KerberosPrincipal;
|
||||
import javax.security.auth.kerberos.KeyTab;
|
||||
|
||||
/**
|
||||
@ -84,19 +85,37 @@ class SubjectComber {
|
||||
} else {
|
||||
List<T> answer = (oneOnly ? null : new ArrayList<T>());
|
||||
|
||||
if (credClass == KeyTab.class) { // Principal un-related
|
||||
// We are looking for credentials unrelated to serverPrincipal
|
||||
Iterator<T> iterator =
|
||||
subject.getPrivateCredentials(credClass).iterator();
|
||||
while (iterator.hasNext()) {
|
||||
T t = iterator.next();
|
||||
if (DEBUG) {
|
||||
System.out.println("Found " + credClass.getSimpleName());
|
||||
if (credClass == KeyTab.class) {
|
||||
// TODO: There is currently no good way to filter out keytabs
|
||||
// not for serverPrincipal. We can only check the principal
|
||||
// set. If the server is not there, we can be sure none of the
|
||||
// keytabs should be used, otherwise, use all for safety.
|
||||
boolean useAll = false;
|
||||
if (serverPrincipal != null) {
|
||||
for (KerberosPrincipal princ:
|
||||
subject.getPrincipals(KerberosPrincipal.class)) {
|
||||
if (princ.getName().equals(serverPrincipal)) {
|
||||
useAll = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (oneOnly) {
|
||||
return t;
|
||||
} else {
|
||||
answer.add(t);
|
||||
} else {
|
||||
useAll = true;
|
||||
}
|
||||
if (useAll) {
|
||||
Iterator<KeyTab> iterator =
|
||||
subject.getPrivateCredentials(KeyTab.class).iterator();
|
||||
while (iterator.hasNext()) {
|
||||
KeyTab t = iterator.next();
|
||||
if (DEBUG) {
|
||||
System.out.println("Found " + credClass.getSimpleName()
|
||||
+ " " + t);
|
||||
}
|
||||
if (oneOnly) {
|
||||
return t;
|
||||
} else {
|
||||
answer.add(credClass.cast(t));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (credClass == KerberosKey.class) {
|
||||
@ -114,11 +133,6 @@ class SubjectComber {
|
||||
if (oneOnly) {
|
||||
return t;
|
||||
} else {
|
||||
if (serverPrincipal == null) {
|
||||
// Record name so that keys returned will all
|
||||
// belong to the same principal
|
||||
serverPrincipal = name;
|
||||
}
|
||||
answer.add(credClass.cast(t));
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ package sun.security.krb5;
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.crypto.*;
|
||||
import sun.security.krb5.internal.rcache.*;
|
||||
import sun.security.jgss.krb5.Krb5AcceptCredential;
|
||||
import java.net.InetAddress;
|
||||
import sun.security.util.*;
|
||||
import java.io.IOException;
|
||||
@ -135,13 +136,13 @@ public class KrbApReq {
|
||||
*/
|
||||
// Used in InitSecContextToken (for AP_REQ and not TGS REQ)
|
||||
public KrbApReq(byte[] message,
|
||||
EncryptionKey[] keys,
|
||||
Krb5AcceptCredential cred,
|
||||
InetAddress initiator)
|
||||
throws KrbException, IOException {
|
||||
obuf = message;
|
||||
if (apReqMessg == null)
|
||||
decode();
|
||||
authenticate(keys, initiator);
|
||||
authenticate(cred, initiator);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -260,10 +261,11 @@ public class KrbApReq {
|
||||
}
|
||||
}
|
||||
|
||||
private void authenticate(EncryptionKey[] keys, InetAddress initiator)
|
||||
private void authenticate(Krb5AcceptCredential cred, InetAddress initiator)
|
||||
throws KrbException, IOException {
|
||||
int encPartKeyType = apReqMessg.ticket.encPart.getEType();
|
||||
Integer kvno = apReqMessg.ticket.encPart.getKeyVersionNumber();
|
||||
EncryptionKey[] keys = cred.getKrb5EncryptionKeys(apReqMessg.ticket.sname);
|
||||
EncryptionKey dkey = EncryptionKey.findKey(encPartKeyType, kvno, keys);
|
||||
|
||||
if (dkey == null) {
|
||||
|
@ -382,9 +382,15 @@ public class KeyTab implements KeyTabConstants {
|
||||
*/
|
||||
public void addEntry(PrincipalName service, char[] psswd,
|
||||
int kvno, boolean append) throws KrbException {
|
||||
addEntry(service, service.getSalt(), psswd, kvno, append);
|
||||
}
|
||||
|
||||
// Called by KDC test
|
||||
public void addEntry(PrincipalName service, String salt, char[] psswd,
|
||||
int kvno, boolean append) throws KrbException {
|
||||
|
||||
EncryptionKey[] encKeys = EncryptionKey.acquireSecretKeys(
|
||||
psswd, service.getSalt());
|
||||
psswd, salt);
|
||||
|
||||
// There should be only one maximum KVNO value for all etypes, so that
|
||||
// all added keys can have the same KVNO.
|
||||
|
@ -31,13 +31,7 @@ import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URI;
|
||||
import java.util.*;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.ListIterator;
|
||||
import java.text.MessageFormat;
|
||||
import com.sun.security.auth.PrincipalComparator;
|
||||
import java.security.*;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.X509Certificate;
|
||||
@ -46,19 +40,7 @@ import javax.security.auth.x500.X500Principal;
|
||||
import java.io.FilePermission;
|
||||
import java.net.SocketPermission;
|
||||
import java.net.NetPermission;
|
||||
import java.util.PropertyPermission;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
/*
|
||||
import javax.security.auth.AuthPermission;
|
||||
import javax.security.auth.kerberos.ServicePermission;
|
||||
import javax.security.auth.kerberos.DelegationPermission;
|
||||
import java.io.SerializablePermission;
|
||||
import java.util.logging.LoggingPermission;
|
||||
import java.sql.SQLPermission;
|
||||
import java.lang.reflect.ReflectPermission;
|
||||
import javax.sound.sampled.AudioPermission;
|
||||
import javax.net.ssl.SSLPermission;
|
||||
*/
|
||||
import sun.misc.JavaSecurityProtectionDomainAccess;
|
||||
import static sun.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
|
||||
import sun.misc.SharedSecrets;
|
||||
@ -794,12 +776,9 @@ public class PolicyFile extends java.security.Policy {
|
||||
debug.println("Adding policy entry: ");
|
||||
debug.println(" signedBy " + ge.signedBy);
|
||||
debug.println(" codeBase " + ge.codeBase);
|
||||
if (ge.principals != null && ge.principals.size() > 0) {
|
||||
ListIterator<PolicyParser.PrincipalEntry> li =
|
||||
ge.principals.listIterator();
|
||||
while (li.hasNext()) {
|
||||
PolicyParser.PrincipalEntry pppe = li.next();
|
||||
debug.println(" " + pppe.toString());
|
||||
if (ge.principals != null) {
|
||||
for (PolicyParser.PrincipalEntry pppe : ge.principals) {
|
||||
debug.println(" " + pppe.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -955,11 +934,15 @@ public class PolicyFile extends java.security.Policy {
|
||||
InvocationTargetException
|
||||
{
|
||||
//XXX we might want to keep a hash of created factories...
|
||||
Class<?> pc = Class.forName(type);
|
||||
Class<?> pc = Class.forName(type, false, null);
|
||||
Permission answer = getKnownInstance(pc, name, actions);
|
||||
if (answer != null) {
|
||||
return answer;
|
||||
}
|
||||
if (!Permission.class.isAssignableFrom(pc)) {
|
||||
// not the right subtype
|
||||
throw new ClassCastException(type + " is not a Permission");
|
||||
}
|
||||
|
||||
if (name == null && actions == null) {
|
||||
try {
|
||||
@ -1001,7 +984,6 @@ public class PolicyFile extends java.security.Policy {
|
||||
*/
|
||||
private static final Permission getKnownInstance(Class<?> claz,
|
||||
String name, String actions) {
|
||||
// XXX shorten list to most popular ones?
|
||||
if (claz.equals(FilePermission.class)) {
|
||||
return new FilePermission(name, actions);
|
||||
} else if (claz.equals(SocketPermission.class)) {
|
||||
@ -1014,30 +996,6 @@ public class PolicyFile extends java.security.Policy {
|
||||
return new NetPermission(name, actions);
|
||||
} else if (claz.equals(AllPermission.class)) {
|
||||
return SecurityConstants.ALL_PERMISSION;
|
||||
/*
|
||||
} else if (claz.equals(ReflectPermission.class)) {
|
||||
return new ReflectPermission(name, actions);
|
||||
} else if (claz.equals(SecurityPermission.class)) {
|
||||
return new SecurityPermission(name, actions);
|
||||
} else if (claz.equals(PrivateCredentialPermission.class)) {
|
||||
return new PrivateCredentialPermission(name, actions);
|
||||
} else if (claz.equals(AuthPermission.class)) {
|
||||
return new AuthPermission(name, actions);
|
||||
} else if (claz.equals(ServicePermission.class)) {
|
||||
return new ServicePermission(name, actions);
|
||||
} else if (claz.equals(DelegationPermission.class)) {
|
||||
return new DelegationPermission(name, actions);
|
||||
} else if (claz.equals(SerializablePermission.class)) {
|
||||
return new SerializablePermission(name, actions);
|
||||
} else if (claz.equals(AudioPermission.class)) {
|
||||
return new AudioPermission(name, actions);
|
||||
} else if (claz.equals(SSLPermission.class)) {
|
||||
return new SSLPermission(name, actions);
|
||||
} else if (claz.equals(LoggingPermission.class)) {
|
||||
return new LoggingPermission(name, actions);
|
||||
} else if (claz.equals(SQLPermission.class)) {
|
||||
return new SQLPermission(name, actions);
|
||||
*/
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@ -1079,7 +1037,7 @@ public class PolicyFile extends java.security.Policy {
|
||||
|
||||
if (cert != null) {
|
||||
if (vcerts == null)
|
||||
vcerts = new ArrayList<Certificate>();
|
||||
vcerts = new ArrayList<>();
|
||||
vcerts.add(cert);
|
||||
}
|
||||
}
|
||||
@ -1329,7 +1287,7 @@ public class PolicyFile extends java.security.Policy {
|
||||
|
||||
List<PolicyParser.PrincipalEntry> entryPs = entry.getPrincipals();
|
||||
if (debug != null) {
|
||||
ArrayList<PolicyParser.PrincipalEntry> accPs = new ArrayList<>();
|
||||
List<PolicyParser.PrincipalEntry> accPs = new ArrayList<>();
|
||||
if (principals != null) {
|
||||
for (int i = 0; i < principals.length; i++) {
|
||||
accPs.add(new PolicyParser.PrincipalEntry
|
||||
@ -1368,79 +1326,72 @@ public class PolicyFile extends java.security.Policy {
|
||||
// has principals. see if policy entry principals match
|
||||
// principals in current ACC
|
||||
|
||||
for (int i = 0; i < entryPs.size(); i++) {
|
||||
PolicyParser.PrincipalEntry pppe = entryPs.get(i);
|
||||
for (PolicyParser.PrincipalEntry pppe : entryPs) {
|
||||
|
||||
// see if principal entry is a PrincipalComparator
|
||||
// Check for wildcards
|
||||
if (pppe.isWildcardClass()) {
|
||||
// a wildcard class matches all principals in current ACC
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
Class<?> pClass = Class.forName
|
||||
(pppe.principalClass,
|
||||
true,
|
||||
Thread.currentThread().getContextClassLoader());
|
||||
|
||||
if (!PrincipalComparator.class.isAssignableFrom(pClass)) {
|
||||
|
||||
// common case - dealing with regular Principal class.
|
||||
// see if policy entry principal is in current ACC
|
||||
|
||||
if (!checkEntryPs(principals, pppe)) {
|
||||
if (debug != null) {
|
||||
debug.println("evaluation (principals) failed");
|
||||
}
|
||||
|
||||
// policy entry principal not in current ACC -
|
||||
// immediately return and go to next policy entry
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// dealing with a PrincipalComparator
|
||||
|
||||
Constructor<?> c = pClass.getConstructor(PARAMS1);
|
||||
PrincipalComparator pc = (PrincipalComparator)c.newInstance
|
||||
(new Object[] { pppe.principalName });
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("found PrincipalComparator " +
|
||||
pc.getClass().getName());
|
||||
}
|
||||
|
||||
// check if the PrincipalComparator
|
||||
// implies the current thread's principals
|
||||
|
||||
Set<Principal> pSet = new HashSet<>(principals.length);
|
||||
for (int j = 0; j < principals.length; j++) {
|
||||
pSet.add(principals[j]);
|
||||
}
|
||||
Subject subject = new Subject(true,
|
||||
pSet,
|
||||
Collections.EMPTY_SET,
|
||||
Collections.EMPTY_SET);
|
||||
|
||||
if (!pc.implies(subject)) {
|
||||
if (debug != null) {
|
||||
debug.println
|
||||
("evaluation (principal comparator) failed");
|
||||
}
|
||||
|
||||
// policy principal does not imply the current Subject -
|
||||
// immediately return and go to next policy entry
|
||||
return;
|
||||
if (pppe.isWildcardName()) {
|
||||
// a wildcard name matches any principal with the same class
|
||||
for (Principal p : principals) {
|
||||
if (pppe.principalClass.equals(p.getClass().getName())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (debug != null) {
|
||||
debug.println("evaluation (principal name wildcard) failed");
|
||||
}
|
||||
// policy entry principal not in current ACC -
|
||||
// immediately return and go to next policy entry
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Principal> pSet = new HashSet<>(Arrays.asList(principals));
|
||||
Subject subject = new Subject(true, pSet,
|
||||
Collections.EMPTY_SET,
|
||||
Collections.EMPTY_SET);
|
||||
try {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
Class<?> pClass = Class.forName(pppe.principalClass, false, cl);
|
||||
if (!Principal.class.isAssignableFrom(pClass)) {
|
||||
// not the right subtype
|
||||
throw new ClassCastException(pppe.principalClass +
|
||||
" is not a Principal");
|
||||
}
|
||||
|
||||
Constructor<?> c = pClass.getConstructor(PARAMS1);
|
||||
Principal p = (Principal)c.newInstance(new Object[] {
|
||||
pppe.principalName });
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("found Principal " + p.getClass().getName());
|
||||
}
|
||||
|
||||
// check if the Principal implies the current
|
||||
// thread's principals
|
||||
if (!p.implies(subject)) {
|
||||
if (debug != null) {
|
||||
debug.println("evaluation (principal implies) failed");
|
||||
}
|
||||
|
||||
// policy principal does not imply the current Subject -
|
||||
// immediately return and go to next policy entry
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// fall back to regular principal comparison.
|
||||
// fall back to default principal comparison.
|
||||
// see if policy entry principal is in current ACC
|
||||
|
||||
if (debug != null) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (!checkEntryPs(principals, pppe)) {
|
||||
if (!pppe.implies(subject)) {
|
||||
if (debug != null) {
|
||||
debug.println("evaluation (principals) failed");
|
||||
debug.println("evaluation (default principal implies) failed");
|
||||
}
|
||||
|
||||
// policy entry principal not in current ACC -
|
||||
@ -1450,7 +1401,7 @@ public class PolicyFile extends java.security.Policy {
|
||||
}
|
||||
|
||||
// either the principal information matched,
|
||||
// or the PrincipalComparator.implies succeeded.
|
||||
// or the Principal.implies succeeded.
|
||||
// continue loop and test the next policy principal
|
||||
}
|
||||
|
||||
@ -1484,47 +1435,6 @@ public class PolicyFile extends java.security.Policy {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns, true, if the principal in the policy entry,
|
||||
* pppe, is part of the current thread's principal array, pList.
|
||||
* This method also returns, true, if the policy entry's principal
|
||||
* is appropriately wildcarded.
|
||||
*
|
||||
* Note that the provided <i>pppe</i> argument may have
|
||||
* wildcards (*) for both the <code>Principal</code> class and name.
|
||||
*
|
||||
* @param pList an array of principals from the current thread's
|
||||
* AccessControlContext.
|
||||
*
|
||||
* @param pppe a Principal specified in a policy grant entry.
|
||||
*
|
||||
* @return true if the current thread's pList "contains" the
|
||||
* principal in the policy entry, pppe. This method
|
||||
* also returns true if the policy entry's principal
|
||||
* appropriately wildcarded.
|
||||
*/
|
||||
private boolean checkEntryPs(Principal[] pList,
|
||||
PolicyParser.PrincipalEntry pppe) {
|
||||
|
||||
for (int i = 0; i < pList.length; i++) {
|
||||
|
||||
if (pppe.principalClass.equals
|
||||
(PolicyParser.PrincipalEntry.WILDCARD_CLASS) ||
|
||||
pppe.principalClass.equals
|
||||
(pList[i].getClass().getName())) {
|
||||
|
||||
if (pppe.principalName.equals
|
||||
(PolicyParser.PrincipalEntry.WILDCARD_NAME) ||
|
||||
pppe.principalName.equals
|
||||
(pList[i].getName())) {
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
@ -1568,8 +1478,7 @@ public class PolicyFile extends java.security.Policy {
|
||||
sb.append(sp.getSelfName().substring(startIndex, v));
|
||||
|
||||
// expand SELF
|
||||
ListIterator<PolicyParser.PrincipalEntry> pli =
|
||||
entryPs.listIterator();
|
||||
Iterator<PolicyParser.PrincipalEntry> pli = entryPs.iterator();
|
||||
while (pli.hasNext()) {
|
||||
PolicyParser.PrincipalEntry pppe = pli.next();
|
||||
String[][] principalInfo = getPrincipalInfo(pppe,pdp);
|
||||
@ -1596,8 +1505,8 @@ public class PolicyFile extends java.security.Policy {
|
||||
try {
|
||||
// first try to instantiate the permission
|
||||
perms.add(getInstance(sp.getSelfType(),
|
||||
sb.toString(),
|
||||
sp.getSelfActions()));
|
||||
sb.toString(),
|
||||
sp.getSelfActions()));
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
// ok, the permission is not in the bootclasspath.
|
||||
// before we add an UnresolvedPermission, check to see
|
||||
@ -1673,10 +1582,7 @@ public class PolicyFile extends java.security.Policy {
|
||||
// 2) the entry's Principal name is wildcarded only
|
||||
// 3) the entry's Principal class and name are wildcarded
|
||||
|
||||
if (!pe.principalClass.equals
|
||||
(PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&
|
||||
!pe.principalName.equals
|
||||
(PolicyParser.PrincipalEntry.WILDCARD_NAME)) {
|
||||
if (!pe.isWildcardClass() && !pe.isWildcardName()) {
|
||||
|
||||
// build an info array for the principal
|
||||
// from the Policy entry
|
||||
@ -1685,24 +1591,19 @@ public class PolicyFile extends java.security.Policy {
|
||||
info[0][1] = pe.principalName;
|
||||
return info;
|
||||
|
||||
} else if (!pe.principalClass.equals
|
||||
(PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&
|
||||
pe.principalName.equals
|
||||
(PolicyParser.PrincipalEntry.WILDCARD_NAME)) {
|
||||
} else if (!pe.isWildcardClass() && pe.isWildcardName()) {
|
||||
|
||||
// build an info array for every principal
|
||||
// in the current domain which has a principal class
|
||||
// that is equal to policy entry principal class name
|
||||
List<Principal> plist = new ArrayList<>();
|
||||
for (int i = 0; i < pdp.length; i++) {
|
||||
if(pe.principalClass.equals(pdp[i].getClass().getName()))
|
||||
if (pe.principalClass.equals(pdp[i].getClass().getName()))
|
||||
plist.add(pdp[i]);
|
||||
}
|
||||
String[][] info = new String[plist.size()][2];
|
||||
int i = 0;
|
||||
java.util.Iterator<Principal> pIterator = plist.iterator();
|
||||
while (pIterator.hasNext()) {
|
||||
Principal p = pIterator.next();
|
||||
for (Principal p : plist) {
|
||||
info[i][0] = p.getClass().getName();
|
||||
info[i][1] = p.getName();
|
||||
i++;
|
||||
@ -1763,7 +1664,7 @@ public class PolicyFile extends java.security.Policy {
|
||||
// Done
|
||||
return certs;
|
||||
|
||||
ArrayList<Certificate> userCertList = new ArrayList<>();
|
||||
List<Certificate> userCertList = new ArrayList<>();
|
||||
i = 0;
|
||||
while (i < certs.length) {
|
||||
userCertList.add(certs[i]);
|
||||
@ -1889,10 +1790,8 @@ public class PolicyFile extends java.security.Policy {
|
||||
if (principals == null || principals.isEmpty() || keystore == null)
|
||||
return true;
|
||||
|
||||
ListIterator<PolicyParser.PrincipalEntry> i = principals.listIterator();
|
||||
while (i.hasNext()) {
|
||||
PolicyParser.PrincipalEntry pppe = i.next();
|
||||
if (pppe.principalClass.equals(PolicyParser.REPLACE_NAME)) {
|
||||
for (PolicyParser.PrincipalEntry pppe : principals) {
|
||||
if (pppe.isReplaceName()) {
|
||||
|
||||
// perform replacement
|
||||
// (only X509 replacement is possible now)
|
||||
@ -2241,8 +2140,7 @@ public class PolicyFile extends java.security.Policy {
|
||||
|
||||
if (this.certs == null) {
|
||||
// extract the signer certs
|
||||
ArrayList<Certificate> signerCerts =
|
||||
new ArrayList<>();
|
||||
List<Certificate> signerCerts = new ArrayList<>();
|
||||
i = 0;
|
||||
while (i < certs.length) {
|
||||
signerCerts.add(certs[i]);
|
||||
@ -2406,11 +2304,10 @@ public class PolicyFile extends java.security.Policy {
|
||||
private java.util.Random random;
|
||||
|
||||
PolicyInfo(int numCaches) {
|
||||
policyEntries = new ArrayList<PolicyEntry>();
|
||||
policyEntries = new ArrayList<>();
|
||||
identityPolicyEntries =
|
||||
Collections.synchronizedList(new ArrayList<PolicyEntry>(2));
|
||||
aliasMapping = Collections.synchronizedMap(
|
||||
new HashMap<Object, Object>(11));
|
||||
aliasMapping = Collections.synchronizedMap(new HashMap<>(11));
|
||||
|
||||
pdMapping = new ProtectionDomainCache[numCaches];
|
||||
JavaSecurityProtectionDomainAccess jspda
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,16 +29,17 @@ import java.io.*;
|
||||
import java.lang.RuntimePermission;
|
||||
import java.net.SocketPermission;
|
||||
import java.net.URL;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.Principal;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Vector;
|
||||
import java.util.StringTokenizer;
|
||||
import java.text.MessageFormat;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
import sun.security.util.Debug;
|
||||
import sun.security.util.PropertyExpander;
|
||||
import sun.security.util.ResourcesMgr;
|
||||
@ -72,7 +73,7 @@ import sun.security.util.ResourcesMgr;
|
||||
* Permissions perms = policy.getPermissions(protectiondomain)
|
||||
* </pre>
|
||||
*
|
||||
* <p>The protection domain contains CodeSource
|
||||
* <p>The protection domain contains a CodeSource
|
||||
* object, which encapsulates its codebase (URL) and public key attributes.
|
||||
* It also contains the principals associated with the domain.
|
||||
* The Policy object evaluates the global policy in light of who the
|
||||
@ -87,9 +88,6 @@ import sun.security.util.ResourcesMgr;
|
||||
|
||||
public class PolicyParser {
|
||||
|
||||
// needs to be public for PolicyTool
|
||||
public static final String REPLACE_NAME = "PolicyParser.REPLACE_NAME";
|
||||
|
||||
private static final String EXTDIRS_PROPERTY = "java.ext.dirs";
|
||||
private static final String OLD_EXTDIRS_EXPANSION =
|
||||
"${" + EXTDIRS_PROPERTY + "}";
|
||||
@ -452,7 +450,7 @@ public class PolicyParser {
|
||||
peekAndMatch(",");
|
||||
} else if (peekAndMatch("Principal")) {
|
||||
if (principals == null) {
|
||||
principals = new LinkedList<PrincipalEntry>();
|
||||
principals = new LinkedList<>();
|
||||
}
|
||||
|
||||
String principalClass;
|
||||
@ -461,7 +459,7 @@ public class PolicyParser {
|
||||
if (peek("\"")) {
|
||||
// both the principalClass and principalName
|
||||
// will be replaced later
|
||||
principalClass = REPLACE_NAME;
|
||||
principalClass = PrincipalEntry.REPLACE_NAME;
|
||||
principalName = match("principal type");
|
||||
} else {
|
||||
// check for principalClass wildcard
|
||||
@ -916,7 +914,7 @@ public class PolicyParser {
|
||||
out.print(",\n");
|
||||
}
|
||||
if (principals != null && principals.size() > 0) {
|
||||
ListIterator<PrincipalEntry> pli = principals.listIterator();
|
||||
Iterator<PrincipalEntry> pli = principals.iterator();
|
||||
while (pli.hasNext()) {
|
||||
out.print(" ");
|
||||
PrincipalEntry pe = pli.next();
|
||||
@ -949,23 +947,22 @@ public class PolicyParser {
|
||||
/**
|
||||
* Principal info (class and name) in a grant entry
|
||||
*/
|
||||
public static class PrincipalEntry {
|
||||
public static class PrincipalEntry implements Principal {
|
||||
|
||||
public static final String WILDCARD_CLASS = "WILDCARD_PRINCIPAL_CLASS";
|
||||
public static final String WILDCARD_NAME = "WILDCARD_PRINCIPAL_NAME";
|
||||
public static final String REPLACE_NAME = "PolicyParser.REPLACE_NAME";
|
||||
|
||||
String principalClass;
|
||||
String principalName;
|
||||
|
||||
/**
|
||||
* A PrincipalEntry consists of the <code>Principal</code>
|
||||
* class and <code>Principal</code> name.
|
||||
* A PrincipalEntry consists of the Principal class and Principal name.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param principalClass the <code>Principal</code> class. <p>
|
||||
*
|
||||
* @param principalName the <code>Principal</code> name. <p>
|
||||
* @param principalClass the Principal class
|
||||
* @param principalName the Principal name
|
||||
* @throws NullPointerException if principalClass or principalName
|
||||
* are null
|
||||
*/
|
||||
public PrincipalEntry(String principalClass, String principalName) {
|
||||
if (principalClass == null || principalName == null)
|
||||
@ -975,6 +972,18 @@ public class PolicyParser {
|
||||
this.principalName = principalName;
|
||||
}
|
||||
|
||||
boolean isWildcardName() {
|
||||
return principalName.equals(WILDCARD_NAME);
|
||||
}
|
||||
|
||||
boolean isWildcardClass() {
|
||||
return principalClass.equals(WILDCARD_CLASS);
|
||||
}
|
||||
|
||||
boolean isReplaceName() {
|
||||
return principalClass.equals(REPLACE_NAME);
|
||||
}
|
||||
|
||||
public String getPrincipalClass() {
|
||||
return principalClass;
|
||||
}
|
||||
@ -984,9 +993,9 @@ public class PolicyParser {
|
||||
}
|
||||
|
||||
public String getDisplayClass() {
|
||||
if (principalClass.equals(WILDCARD_CLASS)) {
|
||||
if (isWildcardClass()) {
|
||||
return "*";
|
||||
} else if (principalClass.equals(REPLACE_NAME)) {
|
||||
} else if (isReplaceName()) {
|
||||
return "";
|
||||
}
|
||||
else return principalClass;
|
||||
@ -997,7 +1006,7 @@ public class PolicyParser {
|
||||
}
|
||||
|
||||
public String getDisplayName(boolean addQuote) {
|
||||
if (principalName.equals(WILDCARD_NAME)) {
|
||||
if (isWildcardName()) {
|
||||
return "*";
|
||||
}
|
||||
else {
|
||||
@ -1006,8 +1015,14 @@ public class PolicyParser {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return principalName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (!principalClass.equals(REPLACE_NAME)) {
|
||||
if (!isReplaceName()) {
|
||||
return getDisplayClass() + "/" + getDisplayName();
|
||||
} else {
|
||||
return getDisplayName();
|
||||
@ -1016,15 +1031,13 @@ public class PolicyParser {
|
||||
|
||||
/**
|
||||
* Test for equality between the specified object and this object.
|
||||
* Two PrincipalEntries are equal if their PrincipalClass and
|
||||
* PrincipalName values are equal.
|
||||
* Two PrincipalEntries are equal if their class and name values
|
||||
* are equal.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param obj the object to test for equality with this object.
|
||||
*
|
||||
* @return true if the objects are equal, false otherwise.
|
||||
* @param obj the object to test for equality with this object
|
||||
* @return true if the objects are equal, false otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
@ -1033,27 +1046,23 @@ public class PolicyParser {
|
||||
return false;
|
||||
|
||||
PrincipalEntry that = (PrincipalEntry)obj;
|
||||
if (this.principalClass.equals(that.principalClass) &&
|
||||
this.principalName.equals(that.principalName)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return (principalClass.equals(that.principalClass) &&
|
||||
principalName.equals(that.principalName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a hashcode for this <code>PrincipalEntry</code>.
|
||||
* Return a hashcode for this PrincipalEntry.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return a hashcode for this <code>PrincipalEntry</code>.
|
||||
* @return a hashcode for this PrincipalEntry
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return principalClass.hashCode();
|
||||
}
|
||||
|
||||
public void write(PrintWriter out) {
|
||||
out.print("principal " + getDisplayClass() + " " +
|
||||
getDisplayName(true));
|
||||
getDisplayName(true));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1101,6 +1110,7 @@ public class PolicyParser {
|
||||
* Calculates a hash code value for the object. Objects
|
||||
* which are equal will also have the same hashcode.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int retval = permission.hashCode();
|
||||
if (name != null) retval ^= name.hashCode();
|
||||
@ -1108,6 +1118,7 @@ public class PolicyParser {
|
||||
return retval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this)
|
||||
return true;
|
||||
@ -1210,28 +1221,18 @@ public class PolicyParser {
|
||||
i18nMessage = form.format(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocalizedMessage() {
|
||||
return i18nMessage;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String arg[]) throws Exception {
|
||||
FileReader fr = null;
|
||||
FileWriter fw = null;
|
||||
try {
|
||||
try (FileReader fr = new FileReader(arg[0]);
|
||||
FileWriter fw = new FileWriter(arg[1])) {
|
||||
PolicyParser pp = new PolicyParser(true);
|
||||
fr = new FileReader(arg[0]);
|
||||
pp.read(fr);
|
||||
fw = new FileWriter(arg[1]);
|
||||
pp.write(fw);
|
||||
} finally {
|
||||
if (fr != null) {
|
||||
fr.close();
|
||||
}
|
||||
|
||||
if (fw != null) {
|
||||
fw.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import javax.security.auth.login.LoginException;
|
||||
|
||||
import sun.security.jgss.GSSCaller;
|
||||
import sun.security.jgss.krb5.Krb5Util;
|
||||
import sun.security.jgss.krb5.ServiceCreds;
|
||||
import sun.security.krb5.PrincipalName;
|
||||
import sun.security.ssl.Krb5Proxy;
|
||||
|
||||
@ -62,7 +63,7 @@ public class Krb5ProxyImpl implements Krb5Proxy {
|
||||
@Override
|
||||
public SecretKey[] getServerKeys(AccessControlContext acc)
|
||||
throws LoginException {
|
||||
Krb5Util.ServiceCreds serviceCreds =
|
||||
ServiceCreds serviceCreds =
|
||||
Krb5Util.getServiceCreds(GSSCaller.CALLER_SSL_SERVER, null, acc);
|
||||
return serviceCreds != null ? serviceCreds.getKKeys() :
|
||||
new KerberosKey[0];
|
||||
|
@ -604,7 +604,7 @@ public class PolicyTool {
|
||||
InstantiationException
|
||||
{
|
||||
if (type.equals(PolicyParser.PrincipalEntry.WILDCARD_CLASS) ||
|
||||
type.equals(PolicyParser.REPLACE_NAME)) {
|
||||
type.equals(PolicyParser.PrincipalEntry.REPLACE_NAME)) {
|
||||
return;
|
||||
}
|
||||
Class<?> PRIN = Class.forName("java.security.Principal");
|
||||
@ -2094,7 +2094,7 @@ class ToolDialog extends Dialog {
|
||||
} else if (pclass.equals("")) {
|
||||
// make this consistent with what PolicyParser does
|
||||
// when it sees an empty principal class
|
||||
pclass = PolicyParser.REPLACE_NAME;
|
||||
pclass = PolicyParser.PrincipalEntry.REPLACE_NAME;
|
||||
tool.warnings.addElement(
|
||||
"Warning: Principal name '" + pname +
|
||||
"' specified without a Principal class.\n" +
|
||||
|
@ -389,11 +389,19 @@ Java_java_lang_System_initProperties(JNIEnv *env, jclass cla, jobject props)
|
||||
sprops->display_variant, sprops->format_variant, putID, getPropID);
|
||||
GETPROP(props, "file.encoding", jVMVal);
|
||||
if (jVMVal == NULL) {
|
||||
#ifdef MACOSX
|
||||
/*
|
||||
* Since sun_jnu_encoding is now hard-coded to UTF-8 on Mac, we don't
|
||||
* want to use it to overwrite file.encoding
|
||||
*/
|
||||
PUTPROP(props, "file.encoding", sprops->encoding);
|
||||
#else
|
||||
if (fmtdefault) {
|
||||
PUTPROP(props, "file.encoding", sprops->encoding);
|
||||
} else {
|
||||
PUTPROP(props, "file.encoding", sprops->sun_jnu_encoding);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
(*env)->DeleteLocalRef(env, jVMVal);
|
||||
}
|
||||
|
@ -538,7 +538,12 @@ GetJavaProperties(JNIEnv *env)
|
||||
sprops.display_script = sprops.script;
|
||||
sprops.display_country = sprops.country;
|
||||
sprops.display_variant = sprops.variant;
|
||||
|
||||
#ifdef MACOSX
|
||||
sprops.sun_jnu_encoding = "UTF-8";
|
||||
#else
|
||||
sprops.sun_jnu_encoding = sprops.encoding;
|
||||
#endif
|
||||
|
||||
#ifdef _ALLBSD_SOURCE
|
||||
#if BYTE_ORDER == _LITTLE_ENDIAN
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -72,68 +72,98 @@ class PipeImpl
|
||||
|
||||
private final SelectorProvider sp;
|
||||
|
||||
private IOException ioe = null;
|
||||
|
||||
private Initializer(SelectorProvider sp) {
|
||||
this.sp = sp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void run() throws IOException {
|
||||
ServerSocketChannel ssc = null;
|
||||
SocketChannel sc1 = null;
|
||||
SocketChannel sc2 = null;
|
||||
|
||||
try {
|
||||
// loopback address
|
||||
InetAddress lb = InetAddress.getByName("127.0.0.1");
|
||||
assert(lb.isLoopbackAddress());
|
||||
|
||||
// bind ServerSocketChannel to a port on the loopback address
|
||||
ssc = ServerSocketChannel.open();
|
||||
ssc.socket().bind(new InetSocketAddress(lb, 0));
|
||||
|
||||
// Establish connection (assumes connections are eagerly
|
||||
// accepted)
|
||||
InetSocketAddress sa
|
||||
= new InetSocketAddress(lb, ssc.socket().getLocalPort());
|
||||
sc1 = SocketChannel.open(sa);
|
||||
|
||||
ByteBuffer bb = ByteBuffer.allocate(8);
|
||||
long secret = rnd.nextLong();
|
||||
bb.putLong(secret).flip();
|
||||
sc1.write(bb);
|
||||
|
||||
// Get a connection and verify it is legitimate
|
||||
LoopbackConnector connector = new LoopbackConnector();
|
||||
connector.run();
|
||||
if (ioe instanceof ClosedByInterruptException) {
|
||||
ioe = null;
|
||||
Thread connThread = new Thread(connector) {
|
||||
@Override
|
||||
public void interrupt() {}
|
||||
};
|
||||
connThread.start();
|
||||
for (;;) {
|
||||
sc2 = ssc.accept();
|
||||
bb.clear();
|
||||
sc2.read(bb);
|
||||
bb.rewind();
|
||||
if (bb.getLong() == secret)
|
||||
try {
|
||||
connThread.join();
|
||||
break;
|
||||
sc2.close();
|
||||
} catch (InterruptedException ex) {}
|
||||
}
|
||||
|
||||
// Create source and sink channels
|
||||
source = new SourceChannelImpl(sp, sc1);
|
||||
sink = new SinkChannelImpl(sp, sc2);
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
if (sc1 != null)
|
||||
sc1.close();
|
||||
if (sc2 != null)
|
||||
sc2.close();
|
||||
} catch (IOException e2) { }
|
||||
IOException x = new IOException("Unable to establish"
|
||||
+ " loopback connection");
|
||||
x.initCause(e);
|
||||
throw x;
|
||||
} finally {
|
||||
try {
|
||||
if (ssc != null)
|
||||
ssc.close();
|
||||
} catch (IOException e2) { }
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
if (ioe != null)
|
||||
throw new IOException("Unable to establish loopback connection", ioe);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private class LoopbackConnector implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ServerSocketChannel ssc = null;
|
||||
SocketChannel sc1 = null;
|
||||
SocketChannel sc2 = null;
|
||||
|
||||
try {
|
||||
// Loopback address
|
||||
InetAddress lb = InetAddress.getByName("127.0.0.1");
|
||||
assert(lb.isLoopbackAddress());
|
||||
InetSocketAddress sa = null;
|
||||
for(;;) {
|
||||
// Bind ServerSocketChannel to a port on the loopback
|
||||
// address
|
||||
if (ssc == null || !ssc.isOpen()) {
|
||||
ssc = ServerSocketChannel.open();
|
||||
ssc.socket().bind(new InetSocketAddress(lb, 0));
|
||||
sa = new InetSocketAddress(lb, ssc.socket().getLocalPort());
|
||||
}
|
||||
|
||||
// Establish connection (assume connections are eagerly
|
||||
// accepted)
|
||||
sc1 = SocketChannel.open(sa);
|
||||
ByteBuffer bb = ByteBuffer.allocate(8);
|
||||
long secret = rnd.nextLong();
|
||||
bb.putLong(secret).flip();
|
||||
sc1.write(bb);
|
||||
|
||||
// Get a connection and verify it is legitimate
|
||||
sc2 = ssc.accept();
|
||||
bb.clear();
|
||||
sc2.read(bb);
|
||||
bb.rewind();
|
||||
if (bb.getLong() == secret)
|
||||
break;
|
||||
sc2.close();
|
||||
sc1.close();
|
||||
}
|
||||
|
||||
// Create source and sink channels
|
||||
source = new SourceChannelImpl(sp, sc1);
|
||||
sink = new SinkChannelImpl(sp, sc2);
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
if (sc1 != null)
|
||||
sc1.close();
|
||||
if (sc2 != null)
|
||||
sc2.close();
|
||||
} catch (IOException e2) {}
|
||||
ioe = e;
|
||||
} finally {
|
||||
try {
|
||||
if (ssc != null)
|
||||
ssc.close();
|
||||
} catch (IOException e2) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PipeImpl(final SelectorProvider sp) throws IOException {
|
||||
@ -144,7 +174,6 @@ class PipeImpl
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public SourceChannel source() {
|
||||
return source;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
###########################################################################
|
||||
#
|
||||
# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2009, 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
|
||||
@ -122,9 +122,6 @@
|
||||
|
||||
# jdk_lang
|
||||
|
||||
# 7194607
|
||||
java/lang/instrument/VerifyLocalVariableTableOnRetransformTest.sh generic-all
|
||||
|
||||
# 6944188
|
||||
java/lang/management/ThreadMXBean/ThreadStateTest.java generic-all
|
||||
|
||||
@ -148,6 +145,9 @@ java/lang/management/MemoryMXBean/LowMemoryTest2.sh generic-all
|
||||
# 6959636
|
||||
javax/management/loading/LibraryLoader/LibraryLoaderTest.java windows-all
|
||||
|
||||
# 8005472
|
||||
com/sun/jmx/remote/NotificationMarshalVersions/TestSerializationMismatch.sh windows-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_math
|
||||
@ -238,9 +238,6 @@ java/nio/channels/AsynchronousChannelGroup/Unbounded.java windows-amd64
|
||||
# 7146541
|
||||
java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java linux-all
|
||||
|
||||
# 7187882
|
||||
java/rmi/activation/checkusage/CheckUsage.java generic-all
|
||||
|
||||
# 7190106
|
||||
java/rmi/reliability/benchmark/runRmiBench.sh generic-all
|
||||
|
||||
@ -324,6 +321,9 @@ tools/pack200/Pack200Test.java generic-all
|
||||
# 7150569
|
||||
tools/launcher/UnicodeTest.java macosx-all
|
||||
|
||||
# 8005252
|
||||
tools/pack200/AttributeTests.java generic-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_jdi
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -40,13 +40,13 @@ import com.sun.crypto.provider.*;
|
||||
public class Test4512524 {
|
||||
|
||||
private static final String ALGO = "AES";
|
||||
private static final String MODE = "CBC";
|
||||
private static final String PADDING = "NoPadding";
|
||||
private static final int KEYSIZE = 16; // in bytes
|
||||
|
||||
public boolean execute() throws Exception {
|
||||
public void execute(String mode) throws Exception {
|
||||
|
||||
Cipher ci = Cipher.getInstance(ALGO+"/"+MODE+"/"+PADDING, "SunJCE");
|
||||
String transformation = ALGO+"/"+mode+"/"+PADDING;
|
||||
Cipher ci = Cipher.getInstance(transformation, "SunJCE");
|
||||
|
||||
// TEST FIX 4512524
|
||||
KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE");
|
||||
@ -61,17 +61,14 @@ public class Test4512524 {
|
||||
}
|
||||
|
||||
// passed all tests...hooray!
|
||||
return true;
|
||||
System.out.println(transformation + ": Passed");
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
Security.addProvider(new com.sun.crypto.provider.SunJCE());
|
||||
|
||||
Test4512524 test = new Test4512524();
|
||||
String testName = test.getClass().getName() + "[" + ALGO +
|
||||
"/" + MODE + "/" + PADDING + "]";
|
||||
if (test.execute()) {
|
||||
System.out.println(testName + ": Passed!");
|
||||
}
|
||||
test.execute("CBC");
|
||||
test.execute("GCM");
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -39,14 +39,14 @@ import com.sun.crypto.provider.*;
|
||||
|
||||
public class Test4512704 {
|
||||
private static final String ALGO = "AES";
|
||||
private static final String MODE = "CBC";
|
||||
private static final String PADDING = "PKCS5Padding";
|
||||
private static final String PADDING = "NoPadding";
|
||||
private static final int KEYSIZE = 16; // in bytes
|
||||
|
||||
public boolean execute() throws Exception {
|
||||
AlgorithmParameterSpec aps = null;
|
||||
public void execute(String mode) throws Exception {
|
||||
|
||||
Cipher ci = Cipher.getInstance(ALGO+"/"+MODE+"/"+PADDING, "SunJCE");
|
||||
AlgorithmParameterSpec aps = null;
|
||||
String transformation = ALGO + "/" + mode + "/"+PADDING;
|
||||
Cipher ci = Cipher.getInstance(transformation, "SunJCE");
|
||||
|
||||
KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE");
|
||||
kg.init(KEYSIZE*8);
|
||||
@ -57,19 +57,14 @@ public class Test4512704 {
|
||||
} catch(InvalidAlgorithmParameterException ex) {
|
||||
throw new Exception("parameter should be generated when null is specified!");
|
||||
}
|
||||
|
||||
// passed all tests...hooray!
|
||||
return true;
|
||||
System.out.println(transformation + ": Passed");
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
Security.addProvider(new com.sun.crypto.provider.SunJCE());
|
||||
|
||||
Test4512704 test = new Test4512704();
|
||||
String testName = test.getClass().getName() + "[" + ALGO +
|
||||
"/" + MODE + "/" + PADDING + "]";
|
||||
if (test.execute()) {
|
||||
System.out.println(testName + ": Passed!");
|
||||
}
|
||||
test.execute("CBC");
|
||||
test.execute("GCM");
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -41,16 +41,14 @@ import com.sun.crypto.provider.*;
|
||||
public class Test4517355 {
|
||||
|
||||
private static final String ALGO = "AES";
|
||||
private static final String MODE = "CBC";
|
||||
private static final String PADDING = "PKCS5Padding";
|
||||
private static final int KEYSIZE = 16; // in bytes
|
||||
|
||||
public boolean execute() throws Exception {
|
||||
Random rdm = new Random();
|
||||
byte[] plainText=new byte[125];
|
||||
rdm.nextBytes(plainText);
|
||||
private static byte[] plainText = new byte[125];
|
||||
|
||||
Cipher ci = Cipher.getInstance(ALGO+"/"+MODE+"/"+PADDING, "SunJCE");
|
||||
public void execute(String mode, String padding) throws Exception {
|
||||
String transformation = ALGO + "/" + mode + "/" + padding;
|
||||
|
||||
Cipher ci = Cipher.getInstance(transformation, "SunJCE");
|
||||
KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE");
|
||||
kg.init(KEYSIZE*8);
|
||||
SecretKey key = kg.generateKey();
|
||||
@ -59,9 +57,14 @@ public class Test4517355 {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key);
|
||||
byte[] cipherText = ci.doFinal(plainText);
|
||||
|
||||
byte[] iv = ci.getIV();
|
||||
AlgorithmParameterSpec aps = new IvParameterSpec(iv);
|
||||
ci.init(Cipher.DECRYPT_MODE, key, aps);
|
||||
if (mode.equalsIgnoreCase("GCM")) {
|
||||
AlgorithmParameters params = ci.getParameters();
|
||||
ci.init(Cipher.DECRYPT_MODE, key, params);
|
||||
} else {
|
||||
byte[] iv = ci.getIV();
|
||||
AlgorithmParameterSpec aps = new IvParameterSpec(iv);
|
||||
ci.init(Cipher.DECRYPT_MODE, key, aps);
|
||||
}
|
||||
byte[] recoveredText = new byte[plainText.length];
|
||||
try {
|
||||
int len = ci.doFinal(cipherText, 0, cipherText.length,
|
||||
@ -80,21 +83,22 @@ public class Test4517355 {
|
||||
throw new Exception("encryption does not work!");
|
||||
}
|
||||
// 3. make sure padding is working
|
||||
if ((cipherText.length/16)*16 != cipherText.length) {
|
||||
throw new Exception("padding does not work!");
|
||||
if (padding.equalsIgnoreCase("PKCS5Padding")) {
|
||||
if ((cipherText.length/16)*16 != cipherText.length) {
|
||||
throw new Exception("padding does not work!");
|
||||
}
|
||||
}
|
||||
// passed all tests...hooray!
|
||||
return true;
|
||||
System.out.println(transformation + ": Passed");
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
Security.addProvider(new com.sun.crypto.provider.SunJCE());
|
||||
|
||||
Test4517355 test = new Test4517355();
|
||||
String testName = test.getClass().getName() + "[" + ALGO +
|
||||
"/" + MODE + "/" + PADDING + "]";
|
||||
if (test.execute()) {
|
||||
System.out.println(testName + ": Passed!");
|
||||
}
|
||||
Random rdm = new Random();
|
||||
rdm.nextBytes(test.plainText);
|
||||
|
||||
test.execute("CBC", "PKCS5Padding");
|
||||
test.execute("GCM", "NoPadding");
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -34,13 +34,11 @@ import java.util.*;
|
||||
|
||||
public class Test4626070 {
|
||||
private static final String ALGO = "AES";
|
||||
private static final String MODE = "CBC";
|
||||
private static final String PADDING = "PKCS5Padding";
|
||||
private static final int KEYSIZE = 16; // in bytes
|
||||
|
||||
public boolean execute() throws Exception {
|
||||
|
||||
Cipher ci = Cipher.getInstance(ALGO+"/"+MODE+"/"+PADDING, "SunJCE");
|
||||
public void execute(String mode, String padding) throws Exception {
|
||||
String transformation = ALGO + "/" + mode + "/" + padding;
|
||||
Cipher ci = Cipher.getInstance(transformation, "SunJCE");
|
||||
KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE");
|
||||
kg.init(KEYSIZE*8);
|
||||
SecretKey key = kg.generateKey();
|
||||
@ -58,18 +56,14 @@ public class Test4626070 {
|
||||
throw new Exception(
|
||||
"key after wrap/unwrap is different from the original!");
|
||||
}
|
||||
// passed all tests...hooray!
|
||||
return true;
|
||||
System.out.println(transformation + ": Passed");
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
Security.addProvider(new com.sun.crypto.provider.SunJCE());
|
||||
|
||||
Test4626070 test = new Test4626070();
|
||||
String testName = test.getClass().getName() + "[" + ALGO +
|
||||
"/" + MODE + "/" + PADDING + "]";
|
||||
if (test.execute()) {
|
||||
System.out.println(testName + ": Passed!");
|
||||
}
|
||||
test.execute("CBC", "PKCS5Padding");
|
||||
test.execute("GCM", "NoPadding");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6996769
|
||||
* @library ../UTIL
|
||||
* @build TestUtil
|
||||
* @run main TestGCMKeyAndIvCheck
|
||||
* @summary Ensure that same key+iv can't be repeated used for encryption.
|
||||
* @author Valerie Peng
|
||||
*/
|
||||
|
||||
|
||||
import java.security.*;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.math.*;
|
||||
import com.sun.crypto.provider.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class TestGCMKeyAndIvCheck {
|
||||
|
||||
private static final byte[] AAD = new byte[5];
|
||||
private static final byte[] PT = new byte[18];
|
||||
|
||||
private static void checkISE(Cipher c) throws Exception {
|
||||
// Subsequent encryptions should fail
|
||||
try {
|
||||
c.updateAAD(AAD);
|
||||
throw new Exception("Should throw ISE for updateAAD()");
|
||||
} catch (IllegalStateException ise) {
|
||||
// expected
|
||||
}
|
||||
|
||||
try {
|
||||
c.update(PT);
|
||||
throw new Exception("Should throw ISE for update()");
|
||||
} catch (IllegalStateException ise) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
c.doFinal(PT);
|
||||
throw new Exception("Should throw ISE for doFinal()");
|
||||
} catch (IllegalStateException ise) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void test() throws Exception {
|
||||
Cipher c = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
|
||||
|
||||
SecretKey key = new SecretKeySpec(new byte[16], "AES");
|
||||
// First try parameter-less init.
|
||||
c.init(Cipher.ENCRYPT_MODE, key);
|
||||
c.updateAAD(AAD);
|
||||
byte[] ctPlusTag = c.doFinal(PT);
|
||||
|
||||
// subsequent encryption should fail unless re-init w/ different key+iv
|
||||
checkISE(c);
|
||||
|
||||
// Validate the retrieved parameters against the IV and tag length.
|
||||
AlgorithmParameters params = c.getParameters();
|
||||
if (params == null) {
|
||||
throw new Exception("getParameters() should not return null");
|
||||
}
|
||||
GCMParameterSpec spec = params.getParameterSpec(GCMParameterSpec.class);
|
||||
if (spec.getTLen() != (ctPlusTag.length - PT.length)*8) {
|
||||
throw new Exception("Parameters contains incorrect TLen value");
|
||||
}
|
||||
if (!Arrays.equals(spec.getIV(), c.getIV())) {
|
||||
throw new Exception("Parameters contains incorrect IV value");
|
||||
}
|
||||
|
||||
// Should be ok to use the same key+iv for decryption
|
||||
c.init(Cipher.DECRYPT_MODE, key, params);
|
||||
c.updateAAD(AAD);
|
||||
byte[] recovered = c.doFinal(ctPlusTag);
|
||||
if (!Arrays.equals(recovered, PT)) {
|
||||
throw new Exception("decryption result mismatch");
|
||||
}
|
||||
|
||||
// Now try to encrypt again using the same key+iv; should fail also
|
||||
try {
|
||||
c.init(Cipher.ENCRYPT_MODE, key, params);
|
||||
throw new Exception("Should throw exception when same key+iv is used");
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
// expected
|
||||
}
|
||||
|
||||
// Now try to encrypt again using parameter-less init; should work
|
||||
c.init(Cipher.ENCRYPT_MODE, key);
|
||||
c.doFinal(PT);
|
||||
|
||||
// make sure a different iv is used
|
||||
byte[] iv = c.getIV();
|
||||
if (Arrays.equals(spec.getIV(), iv)) {
|
||||
throw new Exception("IV should be different now");
|
||||
}
|
||||
|
||||
// Now try to encrypt again using a different parameter; should work
|
||||
c.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, new byte[30]));
|
||||
c.updateAAD(AAD);
|
||||
c.doFinal(PT);
|
||||
// subsequent encryption should fail unless re-init w/ different key+iv
|
||||
checkISE(c);
|
||||
|
||||
// Now try decryption twice in a row; no re-init required and
|
||||
// same parameters is used.
|
||||
c.init(Cipher.DECRYPT_MODE, key, params);
|
||||
c.updateAAD(AAD);
|
||||
recovered = c.doFinal(ctPlusTag);
|
||||
|
||||
c.updateAAD(AAD);
|
||||
recovered = c.doFinal(ctPlusTag);
|
||||
if (!Arrays.equals(recovered, PT)) {
|
||||
throw new Exception("decryption result mismatch");
|
||||
}
|
||||
|
||||
// Now try decryption again and re-init using the same parameters
|
||||
c.init(Cipher.DECRYPT_MODE, key, params);
|
||||
c.updateAAD(AAD);
|
||||
recovered = c.doFinal(ctPlusTag);
|
||||
|
||||
// init to decrypt w/o parameters; should fail with IKE as
|
||||
// javadoc specified
|
||||
try {
|
||||
c.init(Cipher.DECRYPT_MODE, key);
|
||||
throw new Exception("Should throw IKE for dec w/o params");
|
||||
} catch (InvalidKeyException ike) {
|
||||
// expected
|
||||
}
|
||||
|
||||
// Lastly, try encryption AND decryption w/ wrong type of parameters,
|
||||
// e.g. IvParameterSpec
|
||||
try {
|
||||
c.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
|
||||
throw new Exception("Should throw IAPE");
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
|
||||
throw new Exception("Should throw IAPE");
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
// expected
|
||||
}
|
||||
|
||||
System.out.println("Test Passed!");
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
TestGCMKeyAndIvCheck t = new TestGCMKeyAndIvCheck();
|
||||
t.test();
|
||||
}
|
||||
}
|
||||
|
314
jdk/test/com/sun/crypto/provider/Cipher/AES/TestKATForGCM.java
Normal file
314
jdk/test/com/sun/crypto/provider/Cipher/AES/TestKATForGCM.java
Normal file
@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6996769
|
||||
* @library ../UTIL
|
||||
* @build TestUtil
|
||||
* @run main TestKATForGCM
|
||||
* @summary Known Answer Test for AES cipher with GCM mode support in
|
||||
* SunJCE provider.
|
||||
* @author Valerie Peng
|
||||
*/
|
||||
|
||||
|
||||
import java.security.*;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.math.*;
|
||||
import com.sun.crypto.provider.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class TestKATForGCM {
|
||||
|
||||
// Utility methods
|
||||
private static byte[] HexToBytes(String hexVal) {
|
||||
if (hexVal == null) return new byte[0];
|
||||
byte[] result = new byte[hexVal.length()/2];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
// 2 characters at a time
|
||||
String byteVal = hexVal.substring(2*i, 2*i +2);
|
||||
result[i] = Integer.valueOf(byteVal, 16).byteValue();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static class TestVector {
|
||||
SecretKey key;
|
||||
byte[] plainText;
|
||||
byte[] aad;
|
||||
byte[] cipherText;
|
||||
byte[] tag;
|
||||
GCMParameterSpec spec;
|
||||
String info;
|
||||
|
||||
TestVector(String key, String iv, String pt, String aad,
|
||||
String ct, String tag) {
|
||||
this.key = new SecretKeySpec(HexToBytes(key), "AES");
|
||||
this.plainText = HexToBytes(pt);
|
||||
this.aad = HexToBytes(aad);
|
||||
this.cipherText = HexToBytes(ct);
|
||||
this.tag = HexToBytes(tag);
|
||||
this.spec = new GCMParameterSpec(this.tag.length * 8, HexToBytes(iv));
|
||||
this.info = "key=" + key + ", iv=" + iv + ", pt=" + pt +
|
||||
",aad=" + aad + ", ct=" + ct + ", tag=" + tag;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
// These test vectors are found off NIST's CAVP page
|
||||
// http://csrc.nist.gov/groups/STM/cavp/index.html
|
||||
// inside the link named "GCM Test Vectors", i.e.
|
||||
// http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
|
||||
// CAVS 14.0, set of test vectors w/ count = 0, keysize = 128
|
||||
private static TestVector[] testValues = {
|
||||
// 96-bit iv w/ 128/120/112/104/96-bit tags
|
||||
// no plain text, no aad
|
||||
new TestVector("11754cd72aec309bf52f7687212e8957",
|
||||
"3c819d9a9bed087615030b65",
|
||||
null, null, null,
|
||||
"250327c674aaf477aef2675748cf6971"),
|
||||
new TestVector("272f16edb81a7abbea887357a58c1917",
|
||||
"794ec588176c703d3d2a7a07",
|
||||
null, null, null,
|
||||
"b6e6f197168f5049aeda32dafbdaeb"),
|
||||
new TestVector("81b6844aab6a568c4556a2eb7eae752f",
|
||||
"ce600f59618315a6829bef4d",
|
||||
null, null, null,
|
||||
"89b43e9dbc1b4f597dbbc7655bb5"),
|
||||
new TestVector("cde2f9a9b1a004165ef9dc981f18651b",
|
||||
"29512c29566c7322e1e33e8e",
|
||||
null, null, null,
|
||||
"2e58ce7dabd107c82759c66a75"),
|
||||
new TestVector("b01e45cc3088aaba9fa43d81d481823f",
|
||||
"5a2c4a66468713456a4bd5e1",
|
||||
null, null, null,
|
||||
"014280f944f53c681164b2ff"),
|
||||
// 96-bit iv w/ 128/120/112/104/96-bit tags
|
||||
// no plain text, 16-byte aad
|
||||
new TestVector("77be63708971c4e240d1cb79e8d77feb",
|
||||
"e0e00f19fed7ba0136a797f3",
|
||||
null,
|
||||
"7a43ec1d9c0a5a78a0b16533a6213cab",
|
||||
null,
|
||||
"209fcc8d3675ed938e9c7166709dd946"),
|
||||
new TestVector("da0b615656135194ba6d3c851099bc48",
|
||||
"d39d4b4d3cc927885090e6c3",
|
||||
null,
|
||||
"e7e5e6f8dac913036cb2ff29e8625e0e",
|
||||
null,
|
||||
"ab967711a5770461724460b07237e2"),
|
||||
new TestVector("7e0986937a88eef894235aba4a2f43b2",
|
||||
"92c4a631695907166b422d60",
|
||||
null,
|
||||
"85c185f8518f9f2cd597a8f9208fc76b",
|
||||
null,
|
||||
"3bb916b728df94fe9d1916736be1"),
|
||||
new TestVector("c3db570d7f0c21e86b028f11465d1dc9",
|
||||
"f86970f58ceef89fc7cb679e",
|
||||
null,
|
||||
"c095240708c0f57c288d86090ae34ee1",
|
||||
null,
|
||||
"e043c52160d652e82c7262fcf4"),
|
||||
new TestVector("bea48ae4980d27f357611014d4486625",
|
||||
"32bddb5c3aa998a08556454c",
|
||||
null,
|
||||
"8a50b0b8c7654bced884f7f3afda2ead",
|
||||
null,
|
||||
"8e0f6d8bf05ffebe6f500eb1"),
|
||||
// 96-bit iv w/ 128/120/112/104/96-bit tags
|
||||
// no plain text, 20-byte aad
|
||||
new TestVector("2fb45e5b8f993a2bfebc4b15b533e0b4",
|
||||
"5b05755f984d2b90f94b8027",
|
||||
null,
|
||||
"e85491b2202caf1d7dce03b97e09331c32473941",
|
||||
null,
|
||||
"c75b7832b2a2d9bd827412b6ef5769db"),
|
||||
new TestVector("9bf406339fcef9675bbcf156aa1a0661",
|
||||
"8be4a9543d40f542abacac95",
|
||||
null,
|
||||
"7167cbf56971793186333a6685bbd58d47d379b3",
|
||||
null,
|
||||
"5e7968d7bbd5ba58cfcc750e2ef8f1"),
|
||||
new TestVector("a2e962fff70fd0f4d63be728b80556fc",
|
||||
"1fa7103483de43d09bc23db4",
|
||||
null,
|
||||
"2a58edf1d53f46e4e7ee5e77ee7aeb60fc360658",
|
||||
null,
|
||||
"fa37f2dbbefab1451eae1d0d74ca"),
|
||||
new TestVector("6bf4fdce82926dcdfc52616ed5f23695",
|
||||
"cc0f5899a10615567e1193ed",
|
||||
null,
|
||||
"3340655592374c1da2f05aac3ee111014986107f",
|
||||
null,
|
||||
"8ad3385cce3b5e7c985908192c"),
|
||||
new TestVector("4df7a13e43c3d7b66b1a72fac5ba398e",
|
||||
"97179a3a2d417908dcf0fb28",
|
||||
null,
|
||||
"cbb7fc0010c255661e23b07dbd804b1e06ae70ac",
|
||||
null,
|
||||
"37791edae6c137ea946cfb40"),
|
||||
// 96-bit iv w/ 128-bit tags, 13/16/32/51-byte plain text, no aad
|
||||
new TestVector("fe9bb47deb3a61e423c2231841cfd1fb",
|
||||
"4d328eb776f500a2f7fb47aa",
|
||||
"f1cc3818e421876bb6b8bbd6c9",
|
||||
null,
|
||||
"b88c5c1977b35b517b0aeae967",
|
||||
"43fd4727fe5cdb4b5b42818dea7ef8c9"),
|
||||
new TestVector("7fddb57453c241d03efbed3ac44e371c",
|
||||
"ee283a3fc75575e33efd4887",
|
||||
"d5de42b461646c255c87bd2962d3b9a2",
|
||||
null,
|
||||
"2ccda4a5415cb91e135c2a0f78c9b2fd",
|
||||
"b36d1df9b9d5e596f83e8b7f52971cb3"),
|
||||
new TestVector("9971071059abc009e4f2bd69869db338",
|
||||
"07a9a95ea3821e9c13c63251",
|
||||
"f54bc3501fed4f6f6dfb5ea80106df0bd836e6826225b75c0222f6e859b35983",
|
||||
null,
|
||||
"0556c159f84ef36cb1602b4526b12009c775611bffb64dc0d9ca9297cd2c6a01",
|
||||
"7870d9117f54811a346970f1de090c41"),
|
||||
new TestVector("594157ec4693202b030f33798b07176d",
|
||||
"49b12054082660803a1df3df",
|
||||
|
||||
"3feef98a976a1bd634f364ac428bb59cd51fb159ec1789946918dbd50ea6c9d594a3a31a5269b0da6936c29d063a5fa2cc8a1c",
|
||||
null,
|
||||
|
||||
"c1b7a46a335f23d65b8db4008a49796906e225474f4fe7d39e55bf2efd97fd82d4167de082ae30fa01e465a601235d8d68bc69",
|
||||
"ba92d3661ce8b04687e8788d55417dc2"),
|
||||
// 96-bit iv w/ 128-bit tags, 16-byte plain text, 16/20/48/90-byte aad
|
||||
new TestVector("c939cc13397c1d37de6ae0e1cb7c423c",
|
||||
"b3d8cc017cbb89b39e0f67e2",
|
||||
"c3b3c41f113a31b73d9a5cd432103069",
|
||||
"24825602bd12a984e0092d3e448eda5f",
|
||||
"93fe7d9e9bfd10348a5606e5cafa7354",
|
||||
"0032a1dc85f1c9786925a2e71d8272dd"),
|
||||
new TestVector("d4a22488f8dd1d5c6c19a7d6ca17964c",
|
||||
"f3d5837f22ac1a0425e0d1d5",
|
||||
"7b43016a16896497fb457be6d2a54122",
|
||||
"f1c5d424b83f96c6ad8cb28ca0d20e475e023b5a",
|
||||
"c2bd67eef5e95cac27e3b06e3031d0a8",
|
||||
"f23eacf9d1cdf8737726c58648826e9c"),
|
||||
new TestVector("89850dd398e1f1e28443a33d40162664",
|
||||
"e462c58482fe8264aeeb7231",
|
||||
"2805cdefb3ef6cc35cd1f169f98da81a",
|
||||
|
||||
"d74e99d1bdaa712864eec422ac507bddbe2b0d4633cd3dff29ce5059b49fe868526c59a2a3a604457bc2afea866e7606",
|
||||
"ba80e244b7fc9025cd031d0f63677e06",
|
||||
"d84a8c3eac57d1bb0e890a8f461d1065"),
|
||||
new TestVector("bd7c5c63b7542b56a00ebe71336a1588",
|
||||
"87721f23ba9c3c8ea5571abc",
|
||||
"de15ddbb1e202161e8a79af6a55ac6f3",
|
||||
|
||||
"a6ec8075a0d3370eb7598918f3b93e48444751624997b899a87fa6a9939f844e008aa8b70e9f4c3b1a19d3286bf543e7127bfecba1ad17a5ec53fccc26faecacc4c75369498eaa7d706aef634d0009279b11e4ba6c993e5e9ed9",
|
||||
"41eb28c0fee4d762de972361c863bc80",
|
||||
"9cb567220d0b252eb97bff46e4b00ff8"),
|
||||
// 8/1024-bit iv w/ 128-bit tag, no plain text, no aad
|
||||
new TestVector("1672c3537afa82004c6b8a46f6f0d026",
|
||||
"05",
|
||||
null, null, null,
|
||||
"8e2ad721f9455f74d8b53d3141f27e8e"),
|
||||
new TestVector("d0f1f4defa1e8c08b4b26d576392027c",
|
||||
|
||||
"42b4f01eb9f5a1ea5b1eb73b0fb0baed54f387ecaa0393c7d7dffc6af50146ecc021abf7eb9038d4303d91f8d741a11743166c0860208bcc02c6258fd9511a2fa626f96d60b72fcff773af4e88e7a923506e4916ecbd814651e9f445adef4ad6a6b6c7290cc13b956130eef5b837c939fcac0cbbcc9656cd75b13823ee5acdac",
|
||||
null, null, null,
|
||||
"7ab49b57ddf5f62c427950111c5c4f0d"),
|
||||
// 8-bit iv w/ 128-bit tag, 13-byte plain text, 90-byte aad
|
||||
new TestVector("9f79239f0904eace50784b863e723f6b",
|
||||
"d9",
|
||||
"bdb0bb10c87965acd34d146171",
|
||||
|
||||
"44db436089327726c5f01139e1f339735c9e85514ccc2f167bad728010fb34a9072a9794c8a5e7361b1d0dbcdc9ac4091e354bb2896561f0486645252e9c78c86beece91bfa4f7cc4a8794ce1f305b1b735efdbf1ed1563c0be0",
|
||||
"7e5a7c8dadb3f0c7335b4d9d8d",
|
||||
"6b6ef1f53723a89f3bb7c6d043840717"),
|
||||
// 1024-bit iv w/ 128-bit tag, 51-byte plain text, 48-byte aad
|
||||
new TestVector("141f1ce91989b07e7eb6ae1dbd81ea5e",
|
||||
|
||||
"49451da24bd6074509d3cebc2c0394c972e6934b45a1d91f3ce1d3ca69e194aa1958a7c21b6f21d530ce6d2cc5256a3f846b6f9d2f38df0102c4791e57df038f6e69085646007df999751e248e06c47245f4cd3b8004585a7470dee1690e9d2d63169a58d243c0b57b3e5b4a481a3e4e8c60007094ef3adea2e8f05dd3a1396f",
|
||||
|
||||
"d384305af2388699aa302f510913fed0f2cb63ba42efa8c5c9de2922a2ec2fe87719dadf1eb0aef212b51e74c9c5b934104a43",
|
||||
|
||||
"630cf18a91cc5a6481ac9eefd65c24b1a3c93396bd7294d6b8ba323951727666c947a21894a079ef061ee159c05beeb4",
|
||||
|
||||
"f4c34e5fbe74c0297313268296cd561d59ccc95bbfcdfcdc71b0097dbd83240446b28dc088abd42b0fc687f208190ff24c0548",
|
||||
"dbb93bbb56d0439cd09f620a57687f5d"),
|
||||
};
|
||||
|
||||
public boolean execute(TestVector[] testValues) throws Exception {
|
||||
boolean testFailed = false;
|
||||
Cipher c = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
|
||||
for (int i = 0; i < testValues.length; i++) {
|
||||
try {
|
||||
c.init(Cipher.ENCRYPT_MODE, testValues[i].key, testValues[i].spec);
|
||||
c.updateAAD(testValues[i].aad);
|
||||
byte[] ctPlusTag = c.doFinal(testValues[i].plainText);
|
||||
|
||||
c.init(Cipher.DECRYPT_MODE, testValues[i].key, testValues[i].spec);
|
||||
c.updateAAD(testValues[i].aad);
|
||||
byte[] pt = c.doFinal(ctPlusTag); // should fail if tag mismatched
|
||||
|
||||
// check encryption/decryption results just to be sure
|
||||
if (!Arrays.equals(testValues[i].plainText, pt)) {
|
||||
System.out.println("PlainText diff failed for test# " + i);
|
||||
testFailed = true;
|
||||
}
|
||||
int ctLen = testValues[i].cipherText.length;
|
||||
if (!Arrays.equals(testValues[i].cipherText,
|
||||
Arrays.copyOf(ctPlusTag, ctLen))) {
|
||||
System.out.println("CipherText diff failed for test# " + i);
|
||||
testFailed = true;
|
||||
}
|
||||
int tagLen = testValues[i].tag.length;
|
||||
if (!Arrays.equals
|
||||
(testValues[i].tag,
|
||||
Arrays.copyOfRange(ctPlusTag, ctLen, ctLen+tagLen))) {
|
||||
System.out.println("Tag diff failed for test# " + i);
|
||||
testFailed = true;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// continue testing other test vectors
|
||||
System.out.println("Failed Test Vector: " + testValues[i]);
|
||||
ex.printStackTrace();
|
||||
testFailed = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (testFailed) {
|
||||
throw new Exception("Test Failed");
|
||||
}
|
||||
// passed all tests...hooray!
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
TestKATForGCM test = new TestKATForGCM();
|
||||
if (test.execute(testValues)) {
|
||||
System.out.println("Test Passed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,24 +135,19 @@ public class WinCommand {
|
||||
|
||||
// Win9x systems don't have a cmd.exe
|
||||
if (new File(systemDirW, "cmd.exe").exists()) {
|
||||
try {
|
||||
out.println("Running cmd.exe tests...");
|
||||
writeFile("cdcmd.cmd", "@echo off\r\nCD\r\n");
|
||||
writeFile("cdbat.bat", "@echo off\r\nCD\r\n");
|
||||
checkCD("cmd",
|
||||
"cmd.exe",
|
||||
systemDirW + "\\cmd.exe",
|
||||
// Only the ".exe" extension can be omitted
|
||||
systemDirW + "\\cmd",
|
||||
systemDirM + "/cmd.exe",
|
||||
systemDirM + "/cmd",
|
||||
"/" + systemDirM + "/cmd",
|
||||
"cdcmd.cmd", "./cdcmd.cmd", ".\\cdcmd.cmd",
|
||||
"cdbat.bat", "./cdbat.bat", ".\\cdbat.bat");
|
||||
} finally {
|
||||
new File("cdcmd.cmd").delete();
|
||||
new File("cdbat.bat").delete();
|
||||
}
|
||||
out.println("Running cmd.exe tests...");
|
||||
writeFile("cdcmd.cmd", "@echo off\r\nCD\r\n");
|
||||
writeFile("cdbat.bat", "@echo off\r\nCD\r\n");
|
||||
checkCD("cmd",
|
||||
"cmd.exe",
|
||||
systemDirW + "\\cmd.exe",
|
||||
// Only the ".exe" extension can be omitted
|
||||
systemDirW + "\\cmd",
|
||||
systemDirM + "/cmd.exe",
|
||||
systemDirM + "/cmd",
|
||||
"/" + systemDirM + "/cmd",
|
||||
"cdcmd.cmd", "./cdcmd.cmd", ".\\cdcmd.cmd",
|
||||
"cdbat.bat", "./cdbat.bat", ".\\cdbat.bat");
|
||||
}
|
||||
|
||||
// 16-bit apps like command.com must have a console;
|
||||
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check that the value of file.encoding and sun.jnu.encoding match the expected
|
||||
* values passed in on the command-line.
|
||||
*/
|
||||
public class ExpectedEncoding {
|
||||
public static void main(String[] args) {
|
||||
boolean failed = false;
|
||||
if (args.length != 2) {
|
||||
System.out.println("Usage:");
|
||||
System.out.println("$ java ExpectedEncoding <expected file.encoding> <expected sun.jnu.encoding>");
|
||||
System.exit(1);
|
||||
}
|
||||
String expectFileEnc = args[0];
|
||||
String expectSunJnuEnc = args[1];
|
||||
|
||||
String fileEnc = System.getProperty("file.encoding");
|
||||
String jnuEnc = System.getProperty("sun.jnu.encoding");
|
||||
|
||||
if (fileEnc == null || !fileEnc.equals(expectFileEnc)) {
|
||||
System.err.println("Expected file.encoding: " + expectFileEnc);
|
||||
System.err.println("Actual file.encoding: " + fileEnc);
|
||||
failed = true;
|
||||
}
|
||||
if (jnuEnc == null || !jnuEnc.equals(expectSunJnuEnc)) {
|
||||
System.err.println("Expected sun.jnu.encoding: " + expectSunJnuEnc);
|
||||
System.err.println("Actual sun.jnu.encoding: " + jnuEnc);
|
||||
failed = true;
|
||||
}
|
||||
if (failed) {
|
||||
throw new RuntimeException("Test Failed");
|
||||
}
|
||||
}
|
||||
}
|
96
jdk/test/java/lang/System/MacJNUEncoding/MacJNUEncoding.sh
Normal file
96
jdk/test/java/lang/System/MacJNUEncoding/MacJNUEncoding.sh
Normal file
@ -0,0 +1,96 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
|
||||
# @test
|
||||
# @bug 8003228
|
||||
# @summary Test the value of sun.jnu.encoding on Mac
|
||||
# @author Brent Christian
|
||||
#
|
||||
# @run shell MacJNUEncoding.sh
|
||||
|
||||
# Only run test on Mac
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
Darwin ) ;;
|
||||
* )
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "${TESTJAVA}" = "" ]
|
||||
then
|
||||
echo "TESTJAVA not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then
|
||||
echo "TESTSRC not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTCLASSES}" = "" ]
|
||||
then
|
||||
echo "TESTCLASSES not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JAVAC="${TESTJAVA}"/bin/javac
|
||||
JAVA="${TESTJAVA}"/bin/java
|
||||
|
||||
echo "Building test classes..."
|
||||
"$JAVAC" -d "${TESTCLASSES}" "${TESTSRC}"/ExpectedEncoding.java
|
||||
|
||||
echo ""
|
||||
echo "Running test for C locale"
|
||||
export LANG=C
|
||||
export LC_ALL=C
|
||||
"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding US-ASCII UTF-8
|
||||
result1=$?
|
||||
|
||||
echo ""
|
||||
echo "Running test for en_US.UTF-8 locale"
|
||||
export LANG=en_US.UTF-8
|
||||
export LC_ALL=en_US.UTF-8
|
||||
"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding UTF-8 UTF-8
|
||||
result2=$?
|
||||
|
||||
echo ""
|
||||
echo "Cleanup"
|
||||
rm ${TESTCLASSES}/ExpectedEncoding.class
|
||||
|
||||
if [ ${result1} -ne 0 ] ; then
|
||||
echo "Test failed for C locale"
|
||||
echo " LANG=\"${LANG}\""
|
||||
echo " LC_ALL=\"${LC_ALL}\""
|
||||
exit ${result1}
|
||||
fi
|
||||
if [ ${result2} -ne 0 ] ; then
|
||||
echo "Test failed for en_US.UTF-8 locale"
|
||||
echo " LANG=\"${LANG}\""
|
||||
echo " LC_ALL=\"${LC_ALL}\""
|
||||
exit ${result2}
|
||||
fi
|
||||
exit 0
|
||||
|
@ -26,6 +26,7 @@
|
||||
* @bug 4727547
|
||||
* @summary SocksSocketImpl throws NullPointerException
|
||||
* @build SocksServer
|
||||
* @run main SocksV4Test
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
|
83
jdk/test/java/nio/channels/Pipe/PipeInterrupt.java
Normal file
83
jdk/test/java/nio/channels/Pipe/PipeInterrupt.java
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 8002306
|
||||
* @summary Ensure that a Pipe can open even if its thread has already
|
||||
* been interrupted.
|
||||
* @author Dan Xu
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.Pipe;
|
||||
|
||||
|
||||
public class PipeInterrupt {
|
||||
|
||||
private Exception exc = null;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
PipeInterrupt instance = new PipeInterrupt();
|
||||
instance.test();
|
||||
}
|
||||
|
||||
public void test() throws Exception {
|
||||
|
||||
Thread tester = new Thread("PipeTester") {
|
||||
private Pipe testPipe = null;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (;;) {
|
||||
boolean interrupted = this.isInterrupted();
|
||||
try {
|
||||
testPipe = Pipe.open();
|
||||
close();
|
||||
if (interrupted) {
|
||||
if (!this.isInterrupted())
|
||||
exc = new RuntimeException("interrupt status reset");
|
||||
break;
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
exc = ioe;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void close() throws IOException {
|
||||
if (testPipe != null) {
|
||||
testPipe.sink().close();
|
||||
testPipe.source().close();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
tester.start();
|
||||
Thread.sleep(200);
|
||||
tester.interrupt();
|
||||
tester.join();
|
||||
|
||||
if (exc != null)
|
||||
throw exc;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -168,7 +168,7 @@ public class ShutdownGracefully
|
||||
registering = null;
|
||||
|
||||
// Need to make sure that rmid goes away by itself
|
||||
Process rmidProcess = rmid.getVM();
|
||||
JavaVM rmidProcess = rmid;
|
||||
if (rmidProcess != null) {
|
||||
try {
|
||||
Runnable waitThread =
|
||||
@ -205,9 +205,9 @@ public class ShutdownGracefully
|
||||
* class that waits for rmid to exit
|
||||
*/
|
||||
private static class ShutdownDetectThread implements Runnable {
|
||||
private Process rmidProcess = null;
|
||||
private JavaVM rmidProcess = null;
|
||||
|
||||
ShutdownDetectThread(Process rmidProcess) {
|
||||
ShutdownDetectThread(JavaVM rmidProcess) {
|
||||
this.rmidProcess = rmidProcess;
|
||||
}
|
||||
public void run() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -23,6 +23,7 @@
|
||||
|
||||
/* @test
|
||||
* @bug 4259564
|
||||
* @summary RMID's usage message is incomplete and inconsistent with other tools
|
||||
*
|
||||
* @library ../../testlibrary
|
||||
* @build TestLibrary JavaVM
|
||||
@ -37,23 +38,16 @@ import java.io.ByteArrayOutputStream;
|
||||
*/
|
||||
public class CheckUsage {
|
||||
public static void main(String[] args) {
|
||||
|
||||
System.err.println("\nregression test for 4259564\n");
|
||||
|
||||
JavaVM rmidVM = null;
|
||||
|
||||
try {
|
||||
// make sure the registry exits with a proper usage statement
|
||||
ByteArrayOutputStream berr = new ByteArrayOutputStream();
|
||||
|
||||
// run a VM to start the registry
|
||||
rmidVM = new JavaVM("sun.rmi.server.Activation", "", "foo",
|
||||
System.out, berr);
|
||||
// create rmid with incorrect command line args
|
||||
JavaVM rmidVM = new JavaVM("sun.rmi.server.Activation", "", "foo",
|
||||
System.out, berr);
|
||||
System.err.println("starting rmid");
|
||||
rmidVM.start();
|
||||
|
||||
// wait for registry exit
|
||||
int rmidVMExitStatus = rmidVM.getVM().waitFor();
|
||||
// run the subprocess and wait for it to exit
|
||||
int rmidVMExitStatus = rmidVM.execute();
|
||||
System.err.println("rmid exited with status: " +
|
||||
rmidVMExitStatus);
|
||||
|
||||
@ -66,12 +60,8 @@ public class CheckUsage {
|
||||
} else {
|
||||
System.err.println("test passed");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
TestLibrary.bomb(e);
|
||||
} finally {
|
||||
rmidVM.destroy();
|
||||
rmidVM = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -76,8 +76,7 @@ public class AltSecurityManager implements Runnable {
|
||||
}
|
||||
|
||||
System.err.println("starting " + utilityToStart);
|
||||
vm.start();
|
||||
vm.getVM().waitFor();
|
||||
vm.execute();
|
||||
|
||||
} catch (Exception e) {
|
||||
TestLibrary.bomb(e);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -35,34 +35,21 @@ import java.io.ByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* Make sure that the rmiregistry prints out a correct usage statement
|
||||
* when run with an incorrect command line; test written to conform to
|
||||
* new tighter bug fix/regression test guidelines.
|
||||
* when run with an incorrect command line.
|
||||
*/
|
||||
public class CheckUsage {
|
||||
public static void main(String[] args) {
|
||||
|
||||
System.err.println("\nregression test for 4151966\n");
|
||||
|
||||
JavaVM registryVM = null;
|
||||
|
||||
try {
|
||||
// make sure the registry exits with a proper usage statement
|
||||
ByteArrayOutputStream berr = new ByteArrayOutputStream();
|
||||
|
||||
// run a VM to start the registry
|
||||
registryVM = new JavaVM("sun.rmi.registry.RegistryImpl",
|
||||
"", "foo",
|
||||
System.out, berr);
|
||||
JavaVM registryVM = new JavaVM("sun.rmi.registry.RegistryImpl",
|
||||
"", "foo",
|
||||
System.out, berr);
|
||||
System.err.println("starting registry");
|
||||
registryVM.start();
|
||||
|
||||
// wait for registry exit
|
||||
System.err.println(" registry exited with status: " +
|
||||
registryVM.getVM().waitFor());
|
||||
try {
|
||||
Thread.sleep(7000);
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
registryVM.execute());
|
||||
|
||||
String usage = new String(berr.toByteArray());
|
||||
|
||||
@ -75,9 +62,6 @@ public class CheckUsage {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
TestLibrary.bomb(e);
|
||||
} finally {
|
||||
registryVM.destroy();
|
||||
registryVM = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -122,8 +122,7 @@ public class Reexport {
|
||||
try {
|
||||
JavaVM jvm = new JavaVM("RegistryRunner", "", Integer.toString(p));
|
||||
jvm.start();
|
||||
Reexport.subreg = jvm.getVM();
|
||||
|
||||
Reexport.subreg = jvm;
|
||||
} catch (IOException e) {
|
||||
// one of these is summarily dropped, can't remember which one
|
||||
System.out.println ("Test setup failed - cannot run rmiregistry");
|
||||
@ -135,7 +134,8 @@ public class Reexport {
|
||||
} catch (Exception whatever) {
|
||||
}
|
||||
}
|
||||
private static Process subreg = null;
|
||||
|
||||
private static JavaVM subreg = null;
|
||||
|
||||
public static void killRegistry(int port) {
|
||||
if (Reexport.subreg != null) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@ -41,6 +41,8 @@ public class JavaVM {
|
||||
private OutputStream outputStream = System.out;
|
||||
private OutputStream errorStream = System.err;
|
||||
private String policyFileName = null;
|
||||
private StreamPipe outPipe;
|
||||
private StreamPipe errPipe;
|
||||
|
||||
private static void mesg(Object mesg) {
|
||||
System.err.println("JAVAVM: " + mesg.toString());
|
||||
@ -145,13 +147,12 @@ public class JavaVM {
|
||||
}
|
||||
|
||||
mesg("command = " + Arrays.asList(javaCommand).toString());
|
||||
System.err.println("");
|
||||
|
||||
vm = Runtime.getRuntime().exec(javaCommand);
|
||||
|
||||
/* output from the execed process may optionally be captured. */
|
||||
StreamPipe.plugTogether(vm.getInputStream(), this.outputStream);
|
||||
StreamPipe.plugTogether(vm.getErrorStream(), this.errorStream);
|
||||
outPipe = StreamPipe.plugTogether(vm.getInputStream(), this.outputStream);
|
||||
errPipe = StreamPipe.plugTogether(vm.getErrorStream(), this.errorStream);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
@ -161,7 +162,25 @@ public class JavaVM {
|
||||
vm = null;
|
||||
}
|
||||
|
||||
protected Process getVM() {
|
||||
return vm;
|
||||
/**
|
||||
* Waits for the subprocess to exit, joins the pipe threads to ensure that
|
||||
* all output is collected, and returns its exit status.
|
||||
*/
|
||||
public int waitFor() throws InterruptedException {
|
||||
if (vm == null)
|
||||
throw new IllegalStateException("can't wait for JavaVM that hasn't started");
|
||||
|
||||
int status = vm.waitFor();
|
||||
outPipe.join();
|
||||
errPipe.join();
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the subprocess, waits for it to exit, and returns its exit status.
|
||||
*/
|
||||
public int execute() throws IOException, InterruptedException {
|
||||
start();
|
||||
return waitFor();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@ -202,8 +202,6 @@ public class RMID extends JavaVM {
|
||||
|
||||
public void start(long waitTime) throws IOException {
|
||||
|
||||
if (getVM() != null) return;
|
||||
|
||||
// if rmid is already running, then the test will fail with
|
||||
// a well recognized exception (port already in use...).
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@ -114,6 +114,7 @@ public class CheckFQDN extends UnicastRemoteObject
|
||||
equal = "=";
|
||||
}
|
||||
|
||||
// create a client to tell checkFQDN what its rmi name is.
|
||||
JavaVM jvm = new JavaVM("CheckFQDNClient",
|
||||
propOption + property +
|
||||
equal +
|
||||
@ -125,10 +126,7 @@ public class CheckFQDN extends UnicastRemoteObject
|
||||
propertyBeingTested=property;
|
||||
propertyBeingTestedValue=propertyValue;
|
||||
|
||||
// create a client to tell checkFQDN what its rmi name is. */
|
||||
jvm.start();
|
||||
|
||||
if (jvm.getVM().waitFor() != 0 ) {
|
||||
if (jvm.execute() != 0) {
|
||||
TestLibrary.bomb("Test failed, error in client.");
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@ -102,9 +102,8 @@ public class CheckLeaseLeak extends UnicastRemoteObject implements LeaseLeak {
|
||||
" -Drmi.registry.port=" +
|
||||
registryPort,
|
||||
"");
|
||||
jvm.start();
|
||||
|
||||
if (jvm.getVM().waitFor() == 1 ) {
|
||||
if (jvm.execute() != 0) {
|
||||
TestLibrary.bomb("Client process failed");
|
||||
}
|
||||
}
|
||||
|
80
jdk/test/java/security/Principal/Implies.java
Normal file
80
jdk/test/java/security/Principal/Implies.java
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7019834
|
||||
* @summary test default implementation of Principal.implies
|
||||
*/
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.kerberos.KerberosPrincipal;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
public class Implies {
|
||||
public static void main(String[] args) throws Exception {
|
||||
X500Principal duke = new X500Principal("CN=Duke");
|
||||
// should not throw NullPointerException
|
||||
testImplies(duke, (Subject)null, false);
|
||||
|
||||
Set<Principal> principals = new HashSet<>();
|
||||
principals.add(duke);
|
||||
testImplies(duke, principals, true);
|
||||
|
||||
X500Principal tux = new X500Principal("CN=Tux");
|
||||
principals.add(tux);
|
||||
testImplies(duke, principals, true);
|
||||
|
||||
principals.add(new KerberosPrincipal("duke@java.com"));
|
||||
testImplies(duke, principals, true);
|
||||
|
||||
principals.clear();
|
||||
principals.add(tux);
|
||||
testImplies(duke, principals, false);
|
||||
|
||||
System.out.println("test passed");
|
||||
}
|
||||
|
||||
private static void testImplies(Principal principal,
|
||||
Set<? extends Principal> principals,
|
||||
boolean result)
|
||||
throws SecurityException
|
||||
{
|
||||
Subject subject = new Subject(true, principals, Collections.emptySet(),
|
||||
Collections.emptySet());
|
||||
testImplies(principal, subject, result);
|
||||
}
|
||||
|
||||
private static void testImplies(Principal principal,
|
||||
Subject subject, boolean result)
|
||||
throws SecurityException
|
||||
{
|
||||
if (principal.implies(subject) != result) {
|
||||
throw new SecurityException("test failed");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 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
|
||||
@ -78,6 +78,8 @@ public class GCMAPI {
|
||||
c.updateAAD(src);
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// swallow
|
||||
} catch (IllegalStateException ise) {
|
||||
// swallow
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
failed++;
|
||||
@ -99,6 +101,8 @@ public class GCMAPI {
|
||||
c.updateAAD(src, offset, len);
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// swallow
|
||||
} catch (IllegalStateException ise) {
|
||||
// swallow
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
failed++;
|
||||
@ -120,6 +124,8 @@ public class GCMAPI {
|
||||
c.updateAAD(src);
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// swallow
|
||||
} catch (IllegalStateException ise) {
|
||||
// swallow
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
failed++;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -48,8 +48,7 @@ public class Test4504153 {
|
||||
ByteArrayOutputStream err = new ByteArrayOutputStream();
|
||||
JavaVM vm = new JavaVM(StartRegistry.class.getName(),
|
||||
"-Dsun.rmi.transport.logLevel=v", "", out, err);
|
||||
vm.start();
|
||||
vm.getVM().waitFor();
|
||||
vm.execute();
|
||||
|
||||
String errString = err.toString();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 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
|
||||
@ -65,8 +65,7 @@ public class NoConsoleOutput {
|
||||
JavaVM vm = new JavaVM(DoRMIStuff.class.getName(),
|
||||
"-Djava.util.logging.config.file=" + loggingPropertiesFile,
|
||||
"", out, err);
|
||||
vm.start();
|
||||
vm.getVM().waitFor();
|
||||
vm.execute();
|
||||
|
||||
/*
|
||||
* Verify that the subprocess had no System.out or System.err
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user