提交 b08c0f84 编写于 作者: L lana

Merge

...@@ -192,3 +192,5 @@ ce9b02a3a17edd1983201002cfa0f364e4ab7524 jdk8-b67 ...@@ -192,3 +192,5 @@ ce9b02a3a17edd1983201002cfa0f364e4ab7524 jdk8-b67
53fb43e4d614c92310e1fb00ec41d1960fd9facf jdk8-b68 53fb43e4d614c92310e1fb00ec41d1960fd9facf jdk8-b68
a8012d8d7e9c5035de0bdd4887dc9f7c54008f21 jdk8-b69 a8012d8d7e9c5035de0bdd4887dc9f7c54008f21 jdk8-b69
a996b57e554198f4592a5f3c30f2f9f4075e545d jdk8-b70 a996b57e554198f4592a5f3c30f2f9f4075e545d jdk8-b70
2a5af0f766d0acd68a81fb08fe11fd66795f86af jdk8-b71
32a57e645e012a1f0665c075969ca598e0dbb948 jdk8-b72
...@@ -375,6 +375,7 @@ TOOLS = \ ...@@ -375,6 +375,7 @@ TOOLS = \
com/sun/tools/javadoc \ com/sun/tools/javadoc \
com/sun/tools/javah \ com/sun/tools/javah \
com/sun/tools/javap \ com/sun/tools/javap \
com/sun/tools/jdeps \
com/sun/tools/corba \ com/sun/tools/corba \
com/sun/tools/internal/xjc \ com/sun/tools/internal/xjc \
com/sun/tools/internal/ws \ com/sun/tools/internal/ws \
...@@ -457,6 +458,7 @@ NOTJRETOOLS = \ ...@@ -457,6 +458,7 @@ NOTJRETOOLS = \
javadoc$(EXE_SUFFIX) \ javadoc$(EXE_SUFFIX) \
javah$(EXE_SUFFIX) \ javah$(EXE_SUFFIX) \
javap$(EXE_SUFFIX) \ javap$(EXE_SUFFIX) \
jdeps$(EXE_SUFFIX) \
jcmd$(EXE_SUFFIX) \ jcmd$(EXE_SUFFIX) \
jdb$(EXE_SUFFIX) \ jdb$(EXE_SUFFIX) \
jps$(EXE_SUFFIX) \ jps$(EXE_SUFFIX) \
...@@ -564,6 +566,7 @@ $(NOT_RT_JAR_LIST): FRC ...@@ -564,6 +566,7 @@ $(NOT_RT_JAR_LIST): FRC
$(ECHO) "sun/tools/javac/" >> $@ $(ECHO) "sun/tools/javac/" >> $@
$(ECHO) "com/sun/tools/classfile/" >> $@ $(ECHO) "com/sun/tools/classfile/" >> $@
$(ECHO) "com/sun/tools/javap/" >> $@ $(ECHO) "com/sun/tools/javap/" >> $@
$(ECHO) "com/sun/tools/jdeps/" >> $@
$(ECHO) "sun/tools/jcmd/" >> $@ $(ECHO) "sun/tools/jcmd/" >> $@
$(ECHO) "sun/tools/jconsole/" >> $@ $(ECHO) "sun/tools/jconsole/" >> $@
$(ECHO) "sun/tools/jps/" >> $@ $(ECHO) "sun/tools/jps/" >> $@
......
...@@ -76,7 +76,7 @@ ATTACH_PKGS = com.sun.tools.attach \ ...@@ -76,7 +76,7 @@ ATTACH_PKGS = com.sun.tools.attach \
JCONSOLE_PKGS = com.sun.tools.jconsole JCONSOLE_PKGS = com.sun.tools.jconsole
TREEAPI_PKGS = com.sunsource.doctree \ TREEAPI_PKGS = com.sun.source.doctree \
com.sun.source.tree \ com.sun.source.tree \
com.sun.source.util com.sun.source.util
......
...@@ -63,6 +63,7 @@ $(call make-launcher, javac, com.sun.tools.javac.Main, , ) ...@@ -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, javadoc, com.sun.tools.javadoc.Main, , )
$(call make-launcher, javah, com.sun.tools.javah.Main, , ) $(call make-launcher, javah, com.sun.tools.javah.Main, , )
$(call make-launcher, javap, com.sun.tools.javap.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, jcmd, sun.tools.jcmd.JCmd, , )
$(call make-launcher, jconsole, sun.tools.jconsole.JConsole, \ $(call make-launcher, jconsole, sun.tools.jconsole.JConsole, \
-J-Djconsole.showOutputViewer, ) -J-Djconsole.showOutputViewer, )
......
...@@ -62,6 +62,10 @@ ifeq ($(PROGRAM),javap) ...@@ -62,6 +62,10 @@ ifeq ($(PROGRAM),javap)
WILDCARDS=true WILDCARDS=true
NEVER_ACT_AS_SERVER_CLASS_MACHINE=true NEVER_ACT_AS_SERVER_CLASS_MACHINE=true
endif endif
ifeq ($(PROGRAM),jdeps)
WILDCARDS=true
NEVER_ACT_AS_SERVER_CLASS_MACHINE=true
endif
ifeq ($(PROGRAM),javah) ifeq ($(PROGRAM),javah)
WILDCARDS=true WILDCARDS=true
NEVER_ACT_AS_SERVER_CLASS_MACHINE=true NEVER_ACT_AS_SERVER_CLASS_MACHINE=true
......
...@@ -267,6 +267,11 @@ $(eval $(call SetupLauncher,javap,\ ...@@ -267,6 +267,11 @@ $(eval $(call SetupLauncher,javap,\
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE \ -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javap.Main"$(COMMA) }')) -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_CFLAGS_windows:=-DJAVAW
BUILD_LAUNCHER_jconsole_LDFLAGS_windows:=user32.lib BUILD_LAUNCHER_jconsole_LDFLAGS_windows:=user32.lib
......
...@@ -738,6 +738,7 @@ TOOLS_JAR_INCLUDES := \ ...@@ -738,6 +738,7 @@ TOOLS_JAR_INCLUDES := \
com/sun/tools/javadoc \ com/sun/tools/javadoc \
com/sun/tools/javah \ com/sun/tools/javah \
com/sun/tools/javap \ com/sun/tools/javap \
com/sun/tools/jdeps \
com/sun/tools/corba \ com/sun/tools/corba \
com/sun/tools/internal/xjc \ com/sun/tools/internal/xjc \
com/sun/tools/internal/ws \ com/sun/tools/internal/ws \
......
...@@ -100,6 +100,7 @@ NOT_JRE_BIN_FILES := \ ...@@ -100,6 +100,7 @@ NOT_JRE_BIN_FILES := \
javadoc$(EXE_SUFFIX) \ javadoc$(EXE_SUFFIX) \
javah$(EXE_SUFFIX) \ javah$(EXE_SUFFIX) \
javap$(EXE_SUFFIX) \ javap$(EXE_SUFFIX) \
jdeps$(EXE_SUFFIX) \
jcmd$(EXE_SUFFIX) \ jcmd$(EXE_SUFFIX) \
jdb$(EXE_SUFFIX) \ jdb$(EXE_SUFFIX) \
jps$(EXE_SUFFIX) \ jps$(EXE_SUFFIX) \
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -30,6 +30,7 @@ import java.security.spec.*; ...@@ -30,6 +30,7 @@ import java.security.spec.*;
import javax.crypto.*; import javax.crypto.*;
import javax.crypto.spec.*; import javax.crypto.spec.*;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;
import java.nio.ByteBuffer;
/** /**
* This class implements the AES algorithm in its various modes * This class implements the AES algorithm in its various modes
...@@ -127,6 +128,21 @@ abstract class AESCipher extends CipherSpi { ...@@ -127,6 +128,21 @@ abstract class AESCipher extends CipherSpi {
super(32, "CFB", "NOPADDING"); 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 // utility method used by AESCipher and AESWrapCipher
static final void checkKeySize(Key key, int fixedKeySize) static final void checkKeySize(Key key, int fixedKeySize)
...@@ -531,4 +547,79 @@ abstract class AESCipher extends CipherSpi { ...@@ -531,4 +547,79 @@ abstract class AESCipher extends CipherSpi {
return core.unwrap(wrappedKey, wrappedKeyAlgorithm, return core.unwrap(wrappedKey, wrappedKeyAlgorithm,
wrappedKeyType); 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);
}
}
}
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -106,7 +106,7 @@ public final class AESKeyGenerator extends KeyGeneratorSpi { ...@@ -106,7 +106,7 @@ public final class AESKeyGenerator extends KeyGeneratorSpi {
SecretKeySpec aesKey = null; SecretKeySpec aesKey = null;
if (this.random == null) { if (this.random == null) {
this.random = SunJCE.RANDOM; this.random = SunJCE.getRandom();
} }
byte[] keyBytes = new byte[keySize]; byte[] keyBytes = new byte[keySize];
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -104,7 +104,7 @@ public final class BlowfishKeyGenerator extends KeyGeneratorSpi { ...@@ -104,7 +104,7 @@ public final class BlowfishKeyGenerator extends KeyGeneratorSpi {
*/ */
protected SecretKey engineGenerateKey() { protected SecretKey engineGenerateKey() {
if (this.random == null) { if (this.random == null) {
this.random = SunJCE.RANDOM; this.random = SunJCE.getRandom();
} }
byte[] keyBytes = new byte[this.keysize]; byte[] keyBytes = new byte[this.keysize];
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package com.sun.crypto.provider; package com.sun.crypto.provider;
import java.util.Arrays;
import java.util.Locale; import java.util.Locale;
import java.security.*; import java.security.*;
...@@ -59,7 +60,7 @@ final class CipherCore { ...@@ -59,7 +60,7 @@ final class CipherCore {
private byte[] buffer = null; private byte[] buffer = null;
/* /*
* internal buffer * block size of cipher in bytes
*/ */
private int blockSize = 0; private int blockSize = 0;
...@@ -76,10 +77,12 @@ final class CipherCore { ...@@ -76,10 +77,12 @@ final class CipherCore {
/* /*
* minimum number of bytes in the buffer required for * minimum number of bytes in the buffer required for
* FeedbackCipher.encryptFinal()/decryptFinal() call. * 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. * to encrypt/decrypt data.
* currently, only CTS mode has a non-zero value due to its special * currently, only the following cases have non-zero values:
* handling on the last two blocks (the last one may be incomplete). * 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; private int minBytes = 0;
...@@ -121,6 +124,24 @@ final class CipherCore { ...@@ -121,6 +124,24 @@ final class CipherCore {
private static final int PCBC_MODE = 4; private static final int PCBC_MODE = 4;
private static final int CTR_MODE = 5; private static final int CTR_MODE = 5;
private static final int CTS_MODE = 6; 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 * Creates an instance of CipherCore with default ECB mode and
...@@ -149,7 +170,7 @@ final class CipherCore { ...@@ -149,7 +170,7 @@ final class CipherCore {
* @param mode the cipher mode * @param mode the cipher mode
* *
* @exception NoSuchAlgorithmException if the requested cipher mode does * @exception NoSuchAlgorithmException if the requested cipher mode does
* not exist * not exist for this cipher
*/ */
void setMode(String mode) throws NoSuchAlgorithmException { void setMode(String mode) throws NoSuchAlgorithmException {
if (mode == null) if (mode == null)
...@@ -165,30 +186,34 @@ final class CipherCore { ...@@ -165,30 +186,34 @@ final class CipherCore {
if (modeUpperCase.equals("CBC")) { if (modeUpperCase.equals("CBC")) {
cipherMode = CBC_MODE; cipherMode = CBC_MODE;
cipher = new CipherBlockChaining(rawImpl); cipher = new CipherBlockChaining(rawImpl);
} } else if (modeUpperCase.equals("CTS")) {
else if (modeUpperCase.equals("CTS")) {
cipherMode = CTS_MODE; cipherMode = CTS_MODE;
cipher = new CipherTextStealing(rawImpl); cipher = new CipherTextStealing(rawImpl);
minBytes = blockSize+1; minBytes = blockSize+1;
padding = null; padding = null;
} } else if (modeUpperCase.equals("CTR")) {
else if (modeUpperCase.equals("CTR")) {
cipherMode = CTR_MODE; cipherMode = CTR_MODE;
cipher = new CounterMode(rawImpl); cipher = new CounterMode(rawImpl);
unitBytes = 1; unitBytes = 1;
padding = null; padding = null;
} } else if (modeUpperCase.startsWith("GCM")) {
else if (modeUpperCase.startsWith("CFB")) { // 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; cipherMode = CFB_MODE;
unitBytes = getNumOfUnit(mode, "CFB".length(), blockSize); unitBytes = getNumOfUnit(mode, "CFB".length(), blockSize);
cipher = new CipherFeedback(rawImpl, unitBytes); cipher = new CipherFeedback(rawImpl, unitBytes);
} } else if (modeUpperCase.startsWith("OFB")) {
else if (modeUpperCase.startsWith("OFB")) {
cipherMode = OFB_MODE; cipherMode = OFB_MODE;
unitBytes = getNumOfUnit(mode, "OFB".length(), blockSize); unitBytes = getNumOfUnit(mode, "OFB".length(), blockSize);
cipher = new OutputFeedback(rawImpl, unitBytes); cipher = new OutputFeedback(rawImpl, unitBytes);
} } else if (modeUpperCase.equals("PCBC")) {
else if (modeUpperCase.equals("PCBC")) {
cipherMode = PCBC_MODE; cipherMode = PCBC_MODE;
cipher = new PCBC(rawImpl); cipher = new PCBC(rawImpl);
} }
...@@ -219,6 +244,7 @@ final class CipherCore { ...@@ -219,6 +244,7 @@ final class CipherCore {
return result; return result;
} }
/** /**
* Sets the padding mechanism of this cipher. * Sets the padding mechanism of this cipher.
* *
...@@ -242,11 +268,27 @@ final class CipherCore { ...@@ -242,11 +268,27 @@ final class CipherCore {
+ " not implemented"); + " not implemented");
} }
if ((padding != null) && if ((padding != null) &&
((cipherMode == CTR_MODE) || (cipherMode == CTS_MODE))) { ((cipherMode == CTR_MODE) || (cipherMode == CTS_MODE)
|| (cipherMode == GCM_MODE))) {
padding = null; padding = null;
throw new NoSuchPaddingException String modeStr = null;
((cipherMode == CTR_MODE? "CTR":"CTS") + switch (cipherMode) {
" mode must be used with NoPadding"); 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 { ...@@ -257,7 +299,7 @@ final class CipherCore {
* <code>inputLen</code> (in bytes). * <code>inputLen</code> (in bytes).
* *
* <p>This call takes into account any unprocessed (buffered) data from a * <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 * <p>The actual output length of the next <code>update</code> or
* <code>doFinal</code> call may be smaller than the length returned by * <code>doFinal</code> call may be smaller than the length returned by
...@@ -270,23 +312,60 @@ final class CipherCore { ...@@ -270,23 +312,60 @@ final class CipherCore {
int getOutputSize(int inputLen) { int getOutputSize(int inputLen) {
int totalLen = buffered + inputLen; int totalLen = buffered + inputLen;
if (padding == null) // 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 (padding == null) {
return totalLen; return totalLen;
}
if (decrypting) if (decrypting) {
return totalLen; return totalLen;
}
if (unitBytes != blockSize) { if (unitBytes != blockSize) {
if (totalLen < diffBlocksize) if (totalLen < diffBlocksize) {
return diffBlocksize; return diffBlocksize;
else } else {
return (totalLen + blockSize - return (totalLen + blockSize -
((totalLen - diffBlocksize) % blockSize)); ((totalLen - diffBlocksize) % blockSize));
}
} else { } else {
return totalLen + padding.padLength(totalLen); 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. * Returns the initialization vector (IV) in a new buffer.
* *
...@@ -318,34 +397,49 @@ final class CipherCore { ...@@ -318,34 +397,49 @@ final class CipherCore {
* does not use any parameters. * does not use any parameters.
*/ */
AlgorithmParameters getParameters(String algName) { AlgorithmParameters getParameters(String algName) {
if (cipherMode == ECB_MODE) {
return null;
}
AlgorithmParameters params = null; AlgorithmParameters params = null;
if (cipherMode == ECB_MODE) return null; AlgorithmParameterSpec spec;
byte[] iv = getIV(); byte[] iv = getIV();
if (iv != null) { if (iv == null) {
AlgorithmParameterSpec ivSpec; // generate spec using default value
if (algName.equals("RC2")) { if (cipherMode == GCM_MODE) {
RC2Crypt rawImpl = (RC2Crypt) cipher.getEmbeddedCipher(); iv = new byte[GaloisCounterMode.DEFAULT_IV_LEN];
ivSpec = new RC2ParameterSpec(rawImpl.getEffectiveKeyBits(),
iv);
} else { } else {
ivSpec = new IvParameterSpec(iv); iv = new byte[blockSize];
}
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");
} }
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; return params;
} }
...@@ -420,44 +514,63 @@ final class CipherCore { ...@@ -420,44 +514,63 @@ final class CipherCore {
|| (opmode == Cipher.UNWRAP_MODE); || (opmode == Cipher.UNWRAP_MODE);
byte[] keyBytes = getKeyBytes(key); byte[] keyBytes = getKeyBytes(key);
int tagLen = -1;
byte[] ivBytes; byte[] ivBytes = null;
if (params == null) { if (params != null) {
ivBytes = null; if (cipherMode == GCM_MODE) {
} else if (params instanceof IvParameterSpec) { if (params instanceof GCMParameterSpec) {
ivBytes = ((IvParameterSpec)params).getIV(); tagLen = ((GCMParameterSpec)params).getTLen();
if ((ivBytes == null) || (ivBytes.length != blockSize)) { if (tagLen < 96 || tagLen > 128 || ((tagLen & 0x07) != 0)) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("Wrong IV length: must be " + blockSize + ("Unsupported TLen value; must be one of " +
" bytes long"); "{128, 120, 112, 104, 96}");
} }
} else if (params instanceof RC2ParameterSpec) { tagLen = tagLen >> 3;
ivBytes = ((RC2ParameterSpec)params).getIV(); ivBytes = ((GCMParameterSpec)params).getIV();
if ((ivBytes != null) && (ivBytes.length != blockSize)) { } else {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("Wrong IV length: must be " + blockSize + ("Unsupported parameter: " + params);
" bytes long"); }
} 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 {
throw new InvalidAlgorithmParameterException("Wrong parameter "
+ "type: IV "
+ "expected");
} }
if (cipherMode == ECB_MODE) { if (cipherMode == ECB_MODE) {
if (ivBytes != null) { if (ivBytes != null) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("ECB mode cannot use IV"); ("ECB mode cannot use IV");
} }
} else if (ivBytes == null) { } else if (ivBytes == null) {
if (decrypting) { if (decrypting) {
throw new InvalidAlgorithmParameterException("Parameters " throw new InvalidAlgorithmParameterException("Parameters "
+ "missing"); + "missing");
} }
if (random == null) { 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); random.nextBytes(ivBytes);
} }
...@@ -466,23 +579,57 @@ final class CipherCore { ...@@ -466,23 +579,57 @@ final class CipherCore {
String algorithm = key.getAlgorithm(); 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, void init(int opmode, Key key, AlgorithmParameters params,
SecureRandom random) SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException { throws InvalidKeyException, InvalidAlgorithmParameterException {
IvParameterSpec ivSpec = null; AlgorithmParameterSpec spec = null;
String paramType = null;
if (params != null) { if (params != null) {
try { 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) { } catch (InvalidParameterSpecException ipse) {
throw new InvalidAlgorithmParameterException("Wrong parameter " throw new InvalidAlgorithmParameterException
+ "type: IV " ("Wrong parameter type: " + paramType + " expected");
+ "expected");
} }
} }
init(opmode, key, ivSpec, random); init(opmode, key, spec, random);
} }
/** /**
...@@ -504,6 +651,7 @@ final class CipherCore { ...@@ -504,6 +651,7 @@ final class CipherCore {
return keyBytes; return keyBytes;
} }
/** /**
* Continues a multiple-part encryption or decryption operation * Continues a multiple-part encryption or decryption operation
* (depending on how this cipher was initialized), processing another data * (depending on how this cipher was initialized), processing another data
...@@ -524,22 +672,25 @@ final class CipherCore { ...@@ -524,22 +672,25 @@ final class CipherCore {
* (e.g., has not been initialized) * (e.g., has not been initialized)
*/ */
byte[] update(byte[] input, int inputOffset, int inputLen) { 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[] output = null;
byte[] out = null;
try { try {
output = new byte[getOutputSize(inputLen)]; output = new byte[getOutputSizeByOperation(inputLen, false)];
int len = update(input, inputOffset, inputLen, output, int len = update(input, inputOffset, inputLen, output,
0); 0);
if (len == output.length) { if (len == output.length) {
out = output; return output;
} else { } else {
out = new byte[len]; return Arrays.copyOf(output, len);
System.arraycopy(output, 0, out, 0, len);
} }
} catch (ShortBufferException e) { } catch (ShortBufferException e) {
// never thrown // should never happen
throw new ProviderException("Unexpected exception", e);
} }
return out;
} }
/** /**
...@@ -567,6 +718,11 @@ final class CipherCore { ...@@ -567,6 +718,11 @@ final class CipherCore {
*/ */
int update(byte[] input, int inputOffset, int inputLen, byte[] output, int update(byte[] input, int inputOffset, int inputLen, byte[] output,
int outputOffset) throws ShortBufferException { 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 // figure out how much can be sent to crypto function
int len = buffered + inputLen - minBytes; int len = buffered + inputLen - minBytes;
if (padding != null && decrypting) { if (padding != null && decrypting) {
...@@ -582,6 +738,7 @@ final class CipherCore { ...@@ -582,6 +738,7 @@ final class CipherCore {
+ "(at least) " + len + "(at least) " + len
+ " bytes long"); + " bytes long");
} }
if (len != 0) { if (len != 0) {
// there is some work to do // there is some work to do
byte[] in = new byte[len]; byte[] in = new byte[len];
...@@ -600,7 +757,6 @@ final class CipherCore { ...@@ -600,7 +757,6 @@ final class CipherCore {
System.arraycopy(input, inputOffset, in, System.arraycopy(input, inputOffset, in,
bufferedConsumed, inputConsumed); bufferedConsumed, inputConsumed);
} }
if (decrypting) { if (decrypting) {
cipher.decrypt(in, 0, len, output, outputOffset); cipher.decrypt(in, 0, len, output, outputOffset);
} else { } else {
...@@ -611,11 +767,12 @@ final class CipherCore { ...@@ -611,11 +767,12 @@ final class CipherCore {
// the total input length a multiple of blocksize when // the total input length a multiple of blocksize when
// padding is applied // padding is applied
if (unitBytes != blockSize) { if (unitBytes != blockSize) {
if (len < diffBlocksize) if (len < diffBlocksize) {
diffBlocksize -= len; diffBlocksize -= len;
else } else {
diffBlocksize = blockSize - diffBlocksize = blockSize -
((len - diffBlocksize) % blockSize); ((len - diffBlocksize) % blockSize);
}
} }
inputLen -= inputConsumed; inputLen -= inputConsumed;
...@@ -669,21 +826,18 @@ final class CipherCore { ...@@ -669,21 +826,18 @@ final class CipherCore {
byte[] doFinal(byte[] input, int inputOffset, int inputLen) byte[] doFinal(byte[] input, int inputOffset, int inputLen)
throws IllegalBlockSizeException, BadPaddingException { throws IllegalBlockSizeException, BadPaddingException {
byte[] output = null; byte[] output = null;
byte[] out = null;
try { try {
output = new byte[getOutputSize(inputLen)]; output = new byte[getOutputSizeByOperation(inputLen, true)];
int len = doFinal(input, inputOffset, inputLen, output, 0); int len = doFinal(input, inputOffset, inputLen, output, 0);
if (len < output.length) { if (len < output.length) {
out = new byte[len]; return Arrays.copyOf(output, len);
if (len != 0)
System.arraycopy(output, 0, out, 0, len);
} else { } else {
out = output; return output;
} }
} catch (ShortBufferException e) { } catch (ShortBufferException e) {
// never thrown // never thrown
throw new ProviderException("Unexpected exception", e);
} }
return out;
} }
/** /**
...@@ -726,6 +880,10 @@ final class CipherCore { ...@@ -726,6 +880,10 @@ final class CipherCore {
int outputOffset) int outputOffset)
throws IllegalBlockSizeException, ShortBufferException, throws IllegalBlockSizeException, ShortBufferException,
BadPaddingException { BadPaddingException {
if (requireReinit) {
throw new IllegalStateException
("Must use either different key or iv for GCM encryption");
}
// calculate the total input length // calculate the total input length
int totalLen = buffered + inputLen; int totalLen = buffered + inputLen;
...@@ -752,8 +910,9 @@ final class CipherCore { ...@@ -752,8 +910,9 @@ final class CipherCore {
} }
// if encrypting and padding not null, add padding // if encrypting and padding not null, add padding
if (!decrypting && padding != null) if (!decrypting && padding != null) {
paddedLen += paddingLen; paddedLen += paddingLen;
}
// check output buffer capacity. // check output buffer capacity.
// if we are decrypting with padding applied, we can perform this // if we are decrypting with padding applied, we can perform this
...@@ -763,8 +922,8 @@ final class CipherCore { ...@@ -763,8 +922,8 @@ final class CipherCore {
throw new ShortBufferException("Output buffer is null"); throw new ShortBufferException("Output buffer is null");
} }
int outputCapacity = output.length - outputOffset; int outputCapacity = output.length - outputOffset;
if (((!decrypting) || (padding == null)) &&
(outputCapacity < paddedLen) || if (((!decrypting) && (outputCapacity < paddedLen)) ||
(decrypting && (outputCapacity < (paddedLen - blockSize)))) { (decrypting && (outputCapacity < (paddedLen - blockSize)))) {
throw new ShortBufferException("Output buffer too short: " throw new ShortBufferException("Output buffer too short: "
+ outputCapacity + " bytes given, " + outputCapacity + " bytes given, "
...@@ -812,6 +971,7 @@ final class CipherCore { ...@@ -812,6 +971,7 @@ final class CipherCore {
} }
totalLen = padStart; totalLen = padStart;
} }
if ((output.length - outputOffset) < totalLen) { if ((output.length - outputOffset) < totalLen) {
// restore so users can retry with a larger buffer // restore so users can retry with a larger buffer
cipher.restore(); cipher.restore();
...@@ -824,8 +984,13 @@ final class CipherCore { ...@@ -824,8 +984,13 @@ final class CipherCore {
output[outputOffset + i] = outWithPadding[i]; output[outputOffset + i] = outWithPadding[i];
} }
} else { // encrypting } else { // encrypting
totalLen = finalNoPadding(finalBuf, finalOffset, output, try {
outputOffset, paddedLen); totalLen = finalNoPadding(finalBuf, finalOffset, output,
outputOffset, paddedLen);
} finally {
// reset after doFinal() for GCM encryption
requireReinit = (cipherMode == GCM_MODE);
}
} }
buffered = 0; buffered = 0;
...@@ -836,33 +1001,33 @@ final class CipherCore { ...@@ -836,33 +1001,33 @@ final class CipherCore {
return totalLen; 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) int len)
throws IllegalBlockSizeException throws IllegalBlockSizeException, AEADBadTagException {
{
if (in == null || len == 0)
return 0;
if ((cipherMode != CFB_MODE) && (cipherMode != OFB_MODE) if ((cipherMode != GCM_MODE) && (in == null || len == 0)) {
&& ((len % unitBytes) != 0) && (cipherMode != CTS_MODE)) { return 0;
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) { if (decrypting) {
cipher.decryptFinal(in, inOff, len, out, outOff); outLen = cipher.decryptFinal(in, inOfs, len, out, outOfs);
} else { } else {
cipher.encryptFinal(in, inOff, len, out, outOff); outLen = cipher.encryptFinal(in, inOfs, len, out, outOfs);
} }
return outLen;
return len;
} }
// Note: Wrap() and Unwrap() are the same in // Note: Wrap() and Unwrap() are the same in
...@@ -939,4 +1104,36 @@ final class CipherCore { ...@@ -939,4 +1104,36 @@ final class CipherCore {
return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm, return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm,
wrappedKeyType); 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);
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -83,9 +83,10 @@ final class CipherTextStealing extends CipherBlockChaining { ...@@ -83,9 +83,10 @@ final class CipherTextStealing extends CipherBlockChaining {
* @param plainLen the length of the input data * @param plainLen the length of the input data
* @param cipher the buffer for the result * @param cipher the buffer for the result
* @param cipherOffset the offset in <code>cipher</code> * @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, int encryptFinal(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) byte[] cipher, int cipherOffset)
throws IllegalBlockSizeException { throws IllegalBlockSizeException {
if (plainLen < blockSize) { if (plainLen < blockSize) {
...@@ -134,6 +135,7 @@ final class CipherTextStealing extends CipherBlockChaining { ...@@ -134,6 +135,7 @@ final class CipherTextStealing extends CipherBlockChaining {
embeddedCipher.encryptBlock(tmp2, 0, cipher, cipherOffset); embeddedCipher.encryptBlock(tmp2, 0, cipher, cipherOffset);
} }
} }
return plainLen;
} }
/** /**
...@@ -158,9 +160,10 @@ final class CipherTextStealing extends CipherBlockChaining { ...@@ -158,9 +160,10 @@ final class CipherTextStealing extends CipherBlockChaining {
* @param cipherLen the length of the input data * @param cipherLen the length of the input data
* @param plain the buffer for the result * @param plain the buffer for the result
* @param plainOffset the offset in <code>plain</code> * @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, int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset) byte[] plain, int plainOffset)
throws IllegalBlockSizeException { throws IllegalBlockSizeException {
if (cipherLen < blockSize) { if (cipherLen < blockSize) {
throw new IllegalBlockSizeException("input is too short!"); throw new IllegalBlockSizeException("input is too short!");
...@@ -211,5 +214,6 @@ final class CipherTextStealing extends CipherBlockChaining { ...@@ -211,5 +214,6 @@ final class CipherTextStealing extends CipherBlockChaining {
} }
} }
} }
return cipherLen;
} }
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -102,7 +102,7 @@ public final class DESKeyGenerator extends KeyGeneratorSpi { ...@@ -102,7 +102,7 @@ public final class DESKeyGenerator extends KeyGeneratorSpi {
DESKey desKey = null; DESKey desKey = null;
if (this.random == null) { if (this.random == null) {
this.random = SunJCE.RANDOM; this.random = SunJCE.getRandom();
} }
try { try {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -105,7 +105,7 @@ public final class DESedeKeyGenerator extends KeyGeneratorSpi { ...@@ -105,7 +105,7 @@ public final class DESedeKeyGenerator extends KeyGeneratorSpi {
*/ */
protected SecretKey engineGenerateKey() { protected SecretKey engineGenerateKey() {
if (this.random == null) { if (this.random == null) {
this.random = SunJCE.RANDOM; this.random = SunJCE.getRandom();
} }
byte[] rawkey = new byte[DESedeKeySpec.DES_EDE_KEY_LEN]; byte[] rawkey = new byte[DESedeKeySpec.DES_EDE_KEY_LEN];
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -217,7 +217,7 @@ public final class DESedeWrapCipher extends CipherSpi { ...@@ -217,7 +217,7 @@ public final class DESedeWrapCipher extends CipherSpi {
if (params == null) { if (params == null) {
iv = new byte[8]; iv = new byte[8];
if (random == null) { if (random == null) {
random = SunJCE.RANDOM; random = SunJCE.getRandom();
} }
random.nextBytes(iv); random.nextBytes(iv);
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -140,7 +140,7 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -140,7 +140,7 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
*/ */
public KeyPair generateKeyPair() { public KeyPair generateKeyPair() {
if (random == null) { if (random == null) {
random = SunJCE.RANDOM; random = SunJCE.getRandom();
} }
if (params == null) { if (params == null) {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -131,7 +131,7 @@ extends AlgorithmParameterGeneratorSpi { ...@@ -131,7 +131,7 @@ extends AlgorithmParameterGeneratorSpi {
} }
if (this.random == null) if (this.random == null)
this.random = SunJCE.RANDOM; this.random = SunJCE.getRandom();
try { try {
AlgorithmParameterGenerator paramGen; AlgorithmParameterGenerator paramGen;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
package com.sun.crypto.provider; package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import javax.crypto.IllegalBlockSizeException; import javax.crypto.*;
/** /**
* This class represents a block cipher in one of its modes. It wraps * This class represents a block cipher in one of its modes. It wraps
...@@ -150,11 +150,13 @@ abstract class FeedbackCipher { ...@@ -150,11 +150,13 @@ abstract class FeedbackCipher {
* @param plainLen the length of the input data * @param plainLen the length of the input data
* @param cipher the buffer for the encryption result * @param cipher the buffer for the encryption result
* @param cipherOffset the offset in <code>cipher</code> * @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, int encryptFinal(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset) byte[] cipher, int cipherOffset)
throws IllegalBlockSizeException { throws IllegalBlockSizeException {
encrypt(plain, plainOffset, plainLen, cipher, cipherOffset); encrypt(plain, plainOffset, plainLen, cipher, cipherOffset);
return plainLen;
} }
/** /**
* Performs decryption operation. * Performs decryption operation.
...@@ -190,10 +192,40 @@ abstract class FeedbackCipher { ...@@ -190,10 +192,40 @@ abstract class FeedbackCipher {
* @param cipherLen the length of the input data * @param cipherLen the length of the input data
* @param plain the buffer for the decryption result * @param plain the buffer for the decryption result
* @param plainOffset the offset in <code>plain</code> * @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, int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset) byte[] plain, int plainOffset)
throws IllegalBlockSizeException { throws IllegalBlockSizeException, AEADBadTagException {
decrypt(cipher, cipherOffset, cipherLen, plain, plainOffset); 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");
}
} }
/*
* 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();
}
}
/*
* 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;
}
}
/*
* 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();
}
}
}
/*
* 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;
}
}
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -98,7 +98,7 @@ public final class HmacMD5KeyGenerator extends KeyGeneratorSpi { ...@@ -98,7 +98,7 @@ public final class HmacMD5KeyGenerator extends KeyGeneratorSpi {
*/ */
protected SecretKey engineGenerateKey() { protected SecretKey engineGenerateKey() {
if (this.random == null) { if (this.random == null) {
this.random = SunJCE.RANDOM; this.random = SunJCE.getRandom();
} }
byte[] keyBytes = new byte[this.keysize]; byte[] keyBytes = new byte[this.keysize];
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -89,7 +89,7 @@ public final class HmacPKCS12PBESHA1 extends HmacCore { ...@@ -89,7 +89,7 @@ public final class HmacPKCS12PBESHA1 extends HmacCore {
// generate default for salt and iteration count if necessary // generate default for salt and iteration count if necessary
if (salt == null) { if (salt == null) {
salt = new byte[20]; salt = new byte[20];
SunJCE.RANDOM.nextBytes(salt); SunJCE.getRandom().nextBytes(salt);
} }
if (iCount == 0) iCount = 100; if (iCount == 0) iCount = 100;
} else if (!(params instanceof PBEParameterSpec)) { } else if (!(params instanceof PBEParameterSpec)) {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -98,7 +98,7 @@ public final class HmacSHA1KeyGenerator extends KeyGeneratorSpi { ...@@ -98,7 +98,7 @@ public final class HmacSHA1KeyGenerator extends KeyGeneratorSpi {
*/ */
protected SecretKey engineGenerateKey() { protected SecretKey engineGenerateKey() {
if (this.random == null) { if (this.random == null) {
this.random = SunJCE.RANDOM; this.random = SunJCE.getRandom();
} }
byte[] keyBytes = new byte[this.keysize]; byte[] keyBytes = new byte[this.keysize];
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -69,7 +69,7 @@ final class ISO10126Padding implements Padding { ...@@ -69,7 +69,7 @@ final class ISO10126Padding implements Padding {
byte paddingOctet = (byte) (len & 0xff); byte paddingOctet = (byte) (len & 0xff);
byte[] padding = new byte[len]; byte[] padding = new byte[len];
SunJCE.RANDOM.nextBytes(padding); SunJCE.getRandom().nextBytes(padding);
padding[len-1] = paddingOctet; padding[len-1] = paddingOctet;
System.arraycopy(padding, 0, in, off, len); System.arraycopy(padding, 0, in, off, len);
return; return;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -98,7 +98,7 @@ final class KeyGeneratorCore { ...@@ -98,7 +98,7 @@ final class KeyGeneratorCore {
// generate the key // generate the key
SecretKey implGenerateKey() { SecretKey implGenerateKey() {
if (random == null) { if (random == null) {
random = SunJCE.RANDOM; random = SunJCE.getRandom();
} }
byte[] b = new byte[(keySize + 7) >> 3]; byte[] b = new byte[(keySize + 7) >> 3];
random.nextBytes(b); random.nextBytes(b);
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -99,7 +99,7 @@ final class KeyProtector { ...@@ -99,7 +99,7 @@ final class KeyProtector {
{ {
// create a random salt (8 bytes) // create a random salt (8 bytes)
byte[] salt = new byte[8]; byte[] salt = new byte[8];
SunJCE.RANDOM.nextBytes(salt); SunJCE.getRandom().nextBytes(salt);
// create PBE parameters from salt and iteration count // create PBE parameters from salt and iteration count
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20); PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
...@@ -284,7 +284,7 @@ final class KeyProtector { ...@@ -284,7 +284,7 @@ final class KeyProtector {
{ {
// create a random salt (8 bytes) // create a random salt (8 bytes)
byte[] salt = new byte[8]; byte[] salt = new byte[8];
SunJCE.RANDOM.nextBytes(salt); SunJCE.getRandom().nextBytes(salt);
// create PBE parameters from salt and iteration count // create PBE parameters from salt and iteration count
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20); PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -164,7 +164,7 @@ final class PBECipherCore { ...@@ -164,7 +164,7 @@ final class PBECipherCore {
AlgorithmParameters params = null; AlgorithmParameters params = null;
if (salt == null) { if (salt == null) {
salt = new byte[8]; salt = new byte[8];
SunJCE.RANDOM.nextBytes(salt); SunJCE.getRandom().nextBytes(salt);
} }
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount); PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount);
try { try {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -164,7 +164,7 @@ final class PBES1Core { ...@@ -164,7 +164,7 @@ final class PBES1Core {
AlgorithmParameters params = null; AlgorithmParameters params = null;
if (salt == null) { if (salt == null) {
salt = new byte[8]; salt = new byte[8];
SunJCE.RANDOM.nextBytes(salt); SunJCE.getRandom().nextBytes(salt);
} }
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount); PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount);
try { try {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -134,13 +134,13 @@ abstract class PBES2Core extends CipherSpi { ...@@ -134,13 +134,13 @@ abstract class PBES2Core extends CipherSpi {
if (salt == null) { if (salt == null) {
// generate random salt and use default iteration count // generate random salt and use default iteration count
salt = new byte[DEFAULT_SALT_LENGTH]; salt = new byte[DEFAULT_SALT_LENGTH];
SunJCE.RANDOM.nextBytes(salt); SunJCE.getRandom().nextBytes(salt);
iCount = DEFAULT_COUNT; iCount = DEFAULT_COUNT;
} }
if (ivSpec == null) { if (ivSpec == null) {
// generate random IV // generate random IV
byte[] ivBytes = new byte[blkSize]; byte[] ivBytes = new byte[blkSize];
SunJCE.RANDOM.nextBytes(ivBytes); SunJCE.getRandom().nextBytes(ivBytes);
ivSpec = new IvParameterSpec(ivBytes); ivSpec = new IvParameterSpec(ivBytes);
} }
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount, ivSpec); PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount, ivSpec);
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -123,7 +123,7 @@ abstract class PBMAC1Core extends HmacCore { ...@@ -123,7 +123,7 @@ abstract class PBMAC1Core extends HmacCore {
// generate default for salt and iteration count if necessary // generate default for salt and iteration count if necessary
if (salt == null) { if (salt == null) {
salt = new byte[DEFAULT_SALT_LENGTH]; salt = new byte[DEFAULT_SALT_LENGTH];
SunJCE.RANDOM.nextBytes(salt); SunJCE.getRandom().nextBytes(salt);
} }
if (iCount == 0) iCount = DEFAULT_COUNT; if (iCount == 0) iCount = DEFAULT_COUNT;
} else if (!(params instanceof PBEParameterSpec)) { } else if (!(params instanceof PBEParameterSpec)) {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -227,7 +227,7 @@ final class PKCS12PBECipherCore { ...@@ -227,7 +227,7 @@ final class PKCS12PBECipherCore {
// follow the recommendation in PKCS12 v1.0 // follow the recommendation in PKCS12 v1.0
// section B.4 to generate salt and iCount. // section B.4 to generate salt and iCount.
salt = new byte[DEFAULT_SALT_LENGTH]; salt = new byte[DEFAULT_SALT_LENGTH];
SunJCE.RANDOM.nextBytes(salt); SunJCE.getRandom().nextBytes(salt);
iCount = DEFAULT_COUNT; iCount = DEFAULT_COUNT;
} }
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount); PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount);
...@@ -294,7 +294,7 @@ final class PKCS12PBECipherCore { ...@@ -294,7 +294,7 @@ final class PKCS12PBECipherCore {
if (random != null) { if (random != null) {
random.nextBytes(salt); random.nextBytes(salt);
} else { } else {
SunJCE.RANDOM.nextBytes(salt); SunJCE.getRandom().nextBytes(salt);
} }
} }
if (iCount == 0) iCount = DEFAULT_COUNT; if (iCount == 0) iCount = DEFAULT_COUNT;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -57,6 +57,7 @@ import java.security.SecureRandom; ...@@ -57,6 +57,7 @@ import java.security.SecureRandom;
* - ARCFOUR (RC4 compatible) * - ARCFOUR (RC4 compatible)
* *
* - Cipher modes ECB, CBC, CFB, OFB, PCBC, CTR, and CTS for all block ciphers * - 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 * - Cipher padding ISO10126Padding for non-PKCS#5 block ciphers and
* NoPadding and PKCS5Padding for all block ciphers * NoPadding and PKCS5Padding for all block ciphers
...@@ -90,7 +91,12 @@ public final class SunJCE extends Provider { ...@@ -90,7 +91,12 @@ public final class SunJCE extends Provider {
/* Are we debugging? -- for developers */ /* Are we debugging? -- for developers */
static final boolean debug = false; 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() { public SunJCE() {
/* We are the "SunJCE" provider */ /* We are the "SunJCE" provider */
...@@ -100,7 +106,7 @@ public final class SunJCE extends Provider { ...@@ -100,7 +106,7 @@ public final class SunJCE extends Provider {
"|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64" + "|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64" +
"|OFB8|OFB16|OFB24|OFB32|OFB40|OFB48|OFB56|OFB64"; "|OFB8|OFB16|OFB24|OFB32|OFB40|OFB48|OFB56|OFB64";
final String BLOCK_MODES128 = BLOCK_MODES + 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"; "|OFB72|OFB80|OFB88|OFB96|OFB104|OFB112|OFB120|OFB128";
final String BLOCK_PADS = "NOPADDING|PKCS5PADDING|ISO10126PADDING"; final String BLOCK_PADS = "NOPADDING|PKCS5PADDING|ISO10126PADDING";
...@@ -258,6 +264,9 @@ public final class SunJCE extends Provider { ...@@ -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("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.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("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("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"); 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 { ...@@ -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("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.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("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("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"); 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 { ...@@ -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("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.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("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", "com.sun.crypto.provider.AESWrapCipher$General");
put("Cipher.AESWrap SupportedModes", "ECB"); put("Cipher.AESWrap SupportedModes", "ECB");
...@@ -509,6 +523,8 @@ public final class SunJCE extends Provider { ...@@ -509,6 +523,8 @@ public final class SunJCE extends Provider {
put("AlgorithmParameters.AES", put("AlgorithmParameters.AES",
"com.sun.crypto.provider.AESParameters"); "com.sun.crypto.provider.AESParameters");
put("Alg.Alias.AlgorithmParameters.Rijndael", "AES"); put("Alg.Alias.AlgorithmParameters.Rijndael", "AES");
put("AlgorithmParameters.GCM",
"com.sun.crypto.provider.GCMParameters");
put("AlgorithmParameters.RC2", put("AlgorithmParameters.RC2",
......
...@@ -860,9 +860,9 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { ...@@ -860,9 +860,9 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* @return the specified subsequence. * @return the specified subsequence.
* *
* @throws IndexOutOfBoundsException * @throws IndexOutOfBoundsException
* if <tt>start</tt> or <tt>end</tt> are negative, * if {@code start} or {@code end} are negative,
* if <tt>end</tt> is greater than <tt>length()</tt>, * if {@code end} is greater than {@code length()},
* or if <tt>start</tt> is greater than <tt>end</tt> * or if {@code start} is greater than {@code end}
* @spec JSR-51 * @spec JSR-51
*/ */
@Override @Override
...@@ -1292,7 +1292,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { ...@@ -1292,7 +1292,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
/** /**
* Returns the index within this string of the first occurrence of the * Returns the index within this string of the first occurrence of the
* specified substring, starting at the specified index. The integer * 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> * <blockquote><pre>
* k >= Math.min(fromIndex, str.length()) && * k >= Math.min(fromIndex, str.length()) &&
* this.toString().startsWith(str, k) * this.toString().startsWith(str, k)
...@@ -1418,7 +1418,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { ...@@ -1418,7 +1418,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
public abstract String toString(); public abstract String toString();
/** /**
* Needed by <tt>String</tt> for the contentEquals method. * Needed by {@code String} for the contentEquals method.
*/ */
final char[] getValue() { final char[] getValue() {
return value; return value;
......
/*
* 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> { ...@@ -772,7 +772,7 @@ public final class Integer extends Number implements Comparable<Integer> {
int i = parseInt(integerCacheHighPropValue); int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127); i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE // 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; high = h;
......
...@@ -615,10 +615,10 @@ public final class String ...@@ -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 * @return {@code true} if {@link #length()} is {@code 0}, otherwise
* <tt>false</tt> * {@code false}
* *
* @since 1.6 * @since 1.6
*/ */
...@@ -1229,23 +1229,23 @@ public final class String ...@@ -1229,23 +1229,23 @@ public final class String
/** /**
* Tests if two string regions are equal. * Tests if two string regions are equal.
* <p> * <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 * of the argument other. The result is true if these substrings
* represent identical character sequences. The substring of this * represent identical character sequences. The substring of this
* <tt>String</tt> object to be compared begins at index <tt>toffset</tt> * {@code String} object to be compared begins at index {@code toffset}
* and has length <tt>len</tt>. The substring of other to be compared * and has length {@code len}. The substring of other to be compared
* begins at index <tt>ooffset</tt> and has length <tt>len</tt>. The * begins at index {@code ooffset} and has length {@code len}. The
* result is <tt>false</tt> if and only if at least one of the following * result is {@code false} if and only if at least one of the following
* is true: * is true:
* <ul><li><tt>toffset</tt> is negative. * <ul><li>{@code toffset} is negative.
* <li><tt>ooffset</tt> is negative. * <li>{@code ooffset} is negative.
* <li><tt>toffset+len</tt> is greater than the length of this * <li>{@code toffset+len} is greater than the length of this
* <tt>String</tt> object. * {@code String} object.
* <li><tt>ooffset+len</tt> is greater than the length of the other * <li>{@code ooffset+len} is greater than the length of the other
* argument. * 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: * such that:
* <tt>this.charAt(toffset+<i>k</i>)&nbsp;!=&nbsp;other.charAt(ooffset+<i>k</i>)</tt> * <code>this.charAt(toffset+<i>k</i>)&nbsp;!=&nbsp;other.charAt(ooffset+<i>k</i>)</code>
* </ul> * </ul>
* *
* @param toffset the starting offset of the subregion in this string. * @param toffset the starting offset of the subregion in this string.
...@@ -1280,28 +1280,28 @@ public final class String ...@@ -1280,28 +1280,28 @@ public final class String
/** /**
* Tests if two string regions are equal. * Tests if two string regions are equal.
* <p> * <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 <tt>other</tt>. The result is <tt>true</tt> if these * of the argument {@code other}. The result is {@code true} if these
* substrings represent character sequences that are the same, ignoring * substrings represent character sequences that are the same, ignoring
* case if and only if <tt>ignoreCase</tt> is true. The substring of * case if and only if {@code ignoreCase} is true. The substring of
* this <tt>String</tt> object to be compared begins at index * this {@code String} object to be compared begins at index
* <tt>toffset</tt> and has length <tt>len</tt>. The substring of * {@code toffset} and has length {@code len}. The substring of
* <tt>other</tt> to be compared begins at index <tt>ooffset</tt> and * {@code other} to be compared begins at index {@code ooffset} and
* has length <tt>len</tt>. The result is <tt>false</tt> if and only if * has length {@code len}. The result is {@code false} if and only if
* at least one of the following is true: * at least one of the following is true:
* <ul><li><tt>toffset</tt> is negative. * <ul><li>{@code toffset} is negative.
* <li><tt>ooffset</tt> is negative. * <li>{@code ooffset} is negative.
* <li><tt>toffset+len</tt> is greater than the length of this * <li>{@code toffset+len} is greater than the length of this
* <tt>String</tt> object. * {@code String} object.
* <li><tt>ooffset+len</tt> is greater than the length of the other * <li>{@code ooffset+len} is greater than the length of the other
* argument. * argument.
* <li><tt>ignoreCase</tt> is <tt>false</tt> and there is some nonnegative * <li>{@code ignoreCase} is {@code false} and there is some nonnegative
* integer <i>k</i> less than <tt>len</tt> such that: * integer <i>k</i> less than {@code len} such that:
* <blockquote><pre> * <blockquote><pre>
* this.charAt(toffset+k) != other.charAt(ooffset+k) * this.charAt(toffset+k) != other.charAt(ooffset+k)
* </pre></blockquote> * </pre></blockquote>
* <li><tt>ignoreCase</tt> is <tt>true</tt> and there is some nonnegative * <li>{@code ignoreCase} is {@code true} and there is some nonnegative
* integer <i>k</i> less than <tt>len</tt> such that: * integer <i>k</i> less than {@code len} such that:
* <blockquote><pre> * <blockquote><pre>
* Character.toLowerCase(this.charAt(toffset+k)) != * Character.toLowerCase(this.charAt(toffset+k)) !=
Character.toLowerCase(other.charAt(ooffset+k)) Character.toLowerCase(other.charAt(ooffset+k))
...@@ -1500,12 +1500,12 @@ public final class String ...@@ -1500,12 +1500,12 @@ public final class String
* of {@code ch} in the range from 0 to 0xFFFF (inclusive), * of {@code ch} in the range from 0 to 0xFFFF (inclusive),
* this is the smallest value <i>k</i> such that: * this is the smallest value <i>k</i> such that:
* <blockquote><pre> * <blockquote><pre>
* (this.charAt(<i>k</i>) == ch) && (<i>k</i> &gt;= fromIndex) * (this.charAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &gt;= fromIndex)
* </pre></blockquote> * </pre></blockquote>
* is true. For other values of {@code ch}, it is the * is true. For other values of {@code ch}, it is the
* smallest value <i>k</i> such that: * smallest value <i>k</i> such that:
* <blockquote><pre> * <blockquote><pre>
* (this.codePointAt(<i>k</i>) == ch) && (<i>k</i> &gt;= fromIndex) * (this.codePointAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &gt;= fromIndex)
* </pre></blockquote> * </pre></blockquote>
* is true. In either case, if no such character occurs in this * is true. In either case, if no such character occurs in this
* string at or after position {@code fromIndex}, then * string at or after position {@code fromIndex}, then
...@@ -1604,12 +1604,12 @@ public final class String ...@@ -1604,12 +1604,12 @@ public final class String
* from 0 to 0xFFFF (inclusive), the index returned is the largest * from 0 to 0xFFFF (inclusive), the index returned is the largest
* value <i>k</i> such that: * value <i>k</i> such that:
* <blockquote><pre> * <blockquote><pre>
* (this.charAt(<i>k</i>) == ch) && (<i>k</i> &lt;= fromIndex) * (this.charAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &lt;= fromIndex)
* </pre></blockquote> * </pre></blockquote>
* is true. For other values of {@code ch}, it is the * is true. For other values of {@code ch}, it is the
* largest value <i>k</i> such that: * largest value <i>k</i> such that:
* <blockquote><pre> * <blockquote><pre>
* (this.codePointAt(<i>k</i>) == ch) && (<i>k</i> &lt;= fromIndex) * (this.codePointAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &lt;= fromIndex)
* </pre></blockquote> * </pre></blockquote>
* is true. In either case, if no such character occurs in this * is true. In either case, if no such character occurs in this
* string at or before position {@code fromIndex}, then * string at or before position {@code fromIndex}, then
...@@ -1690,7 +1690,7 @@ public final class String ...@@ -1690,7 +1690,7 @@ public final class String
* *
* <p>The returned index is the smallest value <i>k</i> for which: * <p>The returned index is the smallest value <i>k</i> for which:
* <blockquote><pre> * <blockquote><pre>
* <i>k</i> &gt;= fromIndex && this.startsWith(str, <i>k</i>) * <i>k</i> &gt;= fromIndex {@code &&} this.startsWith(str, <i>k</i>)
* </pre></blockquote> * </pre></blockquote>
* If no such value of <i>k</i> exists, then {@code -1} is returned. * If no such value of <i>k</i> exists, then {@code -1} is returned.
* *
...@@ -1799,7 +1799,7 @@ public final class String ...@@ -1799,7 +1799,7 @@ public final class String
* *
* <p>The returned index is the largest value <i>k</i> for which: * <p>The returned index is the largest value <i>k</i> for which:
* <blockquote><pre> * <blockquote><pre>
* <i>k</i> &lt;= fromIndex && this.startsWith(str, <i>k</i>) * <i>k</i> {@code <=} fromIndex {@code &&} this.startsWith(str, <i>k</i>)
* </pre></blockquote> * </pre></blockquote>
* If no such value of <i>k</i> exists, then {@code -1} is returned. * If no such value of <i>k</i> exists, then {@code -1} is returned.
* *
...@@ -2080,17 +2080,18 @@ public final class String ...@@ -2080,17 +2080,18 @@ public final class String
* href="../util/regex/Pattern.html#sum">regular expression</a>. * href="../util/regex/Pattern.html#sum">regular expression</a>.
* *
* <p> An invocation of this method of the form * <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 * same result as the expression
* *
* <blockquote><tt> {@link java.util.regex.Pattern}.{@link * <blockquote>
* java.util.regex.Pattern#matches(String,CharSequence) * {@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> * matches(<i>regex</i>, <i>str</i>)}
* </blockquote>
* *
* @param regex * @param regex
* the regular expression to which this string is to be matched * 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 * given regular expression
* *
* @throws PatternSyntaxException * @throws PatternSyntaxException
...@@ -2124,18 +2125,20 @@ public final class String ...@@ -2124,18 +2125,20 @@ public final class String
* given replacement. * given replacement.
* *
* <p> An invocation of this method of the form * <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 * yields exactly the same result as the expression
* *
* <blockquote><tt> * <blockquote>
* {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile * <code>
* compile}(</tt><i>regex</i><tt>).{@link * {@link java.util.regex.Pattern}.{@link
* java.util.regex.Pattern#matcher(java.lang.CharSequence) * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
* matcher}(</tt><i>str</i><tt>).{@link java.util.regex.Matcher#replaceFirst * java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link
* replaceFirst}(</tt><i>repl</i><tt>)</tt></blockquote> * java.util.regex.Matcher#replaceFirst replaceFirst}(<i>repl</i>)
* </code>
* </blockquote>
* *
*<p> *<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 * replacement string may cause the results to be different than if it were
* being treated as a literal replacement string; see * being treated as a literal replacement string; see
* {@link java.util.regex.Matcher#replaceFirst}. * {@link java.util.regex.Matcher#replaceFirst}.
...@@ -2147,7 +2150,7 @@ public final class String ...@@ -2147,7 +2150,7 @@ public final class String
* @param replacement * @param replacement
* the string to be substituted for the first match * the string to be substituted for the first match
* *
* @return The resulting <tt>String</tt> * @return The resulting {@code String}
* *
* @throws PatternSyntaxException * @throws PatternSyntaxException
* if the regular expression's syntax is invalid * if the regular expression's syntax is invalid
...@@ -2167,18 +2170,20 @@ public final class String ...@@ -2167,18 +2170,20 @@ public final class String
* given replacement. * given replacement.
* *
* <p> An invocation of this method of the form * <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 * yields exactly the same result as the expression
* *
* <blockquote><tt> * <blockquote>
* {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile * <code>
* compile}(</tt><i>regex</i><tt>).{@link * {@link java.util.regex.Pattern}.{@link
* java.util.regex.Pattern#matcher(java.lang.CharSequence) * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
* matcher}(</tt><i>str</i><tt>).{@link java.util.regex.Matcher#replaceAll * java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link
* replaceAll}(</tt><i>repl</i><tt>)</tt></blockquote> * java.util.regex.Matcher#replaceAll replaceAll}(<i>repl</i>)
* </code>
* </blockquote>
* *
*<p> *<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 * replacement string may cause the results to be different than if it were
* being treated as a literal replacement string; see * being treated as a literal replacement string; see
* {@link java.util.regex.Matcher#replaceAll Matcher.replaceAll}. * {@link java.util.regex.Matcher#replaceAll Matcher.replaceAll}.
...@@ -2190,7 +2195,7 @@ public final class String ...@@ -2190,7 +2195,7 @@ public final class String
* @param replacement * @param replacement
* the string to be substituted for each match * the string to be substituted for each match
* *
* @return The resulting <tt>String</tt> * @return The resulting {@code String}
* *
* @throws PatternSyntaxException * @throws PatternSyntaxException
* if the regular expression's syntax is invalid * if the regular expression's syntax is invalid
...@@ -2234,7 +2239,7 @@ public final class String ...@@ -2234,7 +2239,7 @@ public final class String
* expression does not match any part of the input then the resulting array * expression does not match any part of the input then the resulting array
* has just one element, namely this string. * 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 * 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 * array. If the limit <i>n</i> is greater than zero then the pattern
* will be applied at most <i>n</i>&nbsp;-&nbsp;1 times, the array's * will be applied at most <i>n</i>&nbsp;-&nbsp;1 times, the array's
...@@ -2245,7 +2250,7 @@ public final class String ...@@ -2245,7 +2250,7 @@ public final class String
* the pattern will be applied as many times as possible, the array can * the pattern will be applied as many times as possible, the array can
* have any length, and trailing empty strings will be discarded. * 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: * following results with these parameters:
* *
* <blockquote><table cellpadding=1 cellspacing=0 summary="Split example showing regex, limit, and result"> * <blockquote><table cellpadding=1 cellspacing=0 summary="Split example showing regex, limit, and result">
...@@ -2256,33 +2261,34 @@ public final class String ...@@ -2256,33 +2261,34 @@ public final class String
* </tr> * </tr>
* <tr><td align=center>:</td> * <tr><td align=center>:</td>
* <td align=center>2</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> * <tr><td align=center>:</td>
* <td align=center>5</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> * <tr><td align=center>:</td>
* <td align=center>-2</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> * <tr><td align=center>o</td>
* <td align=center>5</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> * <tr><td align=center>o</td>
* <td align=center>-2</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> * <tr><td align=center>o</td>
* <td align=center>0</td> * <td align=center>0</td>
* <td><tt>{ "b", "", ":and:f" }</tt></td></tr> * <td>{@code { "b", "", ":and:f" }}</td></tr>
* </table></blockquote> * </table></blockquote>
* *
* <p> An invocation of this method of the form * <p> An invocation of this method of the form
* <i>str.</i><tt>split(</tt><i>regex</i><tt>,</tt>&nbsp;<i>n</i><tt>)</tt> * <i>str.</i>{@code split(}<i>regex</i>{@code ,}&nbsp;<i>n</i>{@code )}
* yields the same result as the expression * yields the same result as the expression
* *
* <blockquote> * <blockquote>
* {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile * <code>
* compile}<tt>(</tt><i>regex</i><tt>)</tt>.{@link * {@link java.util.regex.Pattern}.{@link
* java.util.regex.Pattern#split(java.lang.CharSequence,int) * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
* split}<tt>(</tt><i>str</i><tt>,</tt>&nbsp;<i>n</i><tt>)</tt> * java.util.regex.Pattern#split(java.lang.CharSequence,int) split}(<i>str</i>,&nbsp;<i>n</i>)
* </code>
* </blockquote> * </blockquote>
* *
* *
...@@ -2364,7 +2370,7 @@ public final class String ...@@ -2364,7 +2370,7 @@ public final class String
* argument of zero. Trailing empty strings are therefore not included in * argument of zero. Trailing empty strings are therefore not included in
* the resulting array. * 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: * results with these expressions:
* *
* <blockquote><table cellpadding=1 cellspacing=0 summary="Split examples showing regex and result"> * <blockquote><table cellpadding=1 cellspacing=0 summary="Split examples showing regex and result">
...@@ -2373,9 +2379,9 @@ public final class String ...@@ -2373,9 +2379,9 @@ public final class String
* <th>Result</th> * <th>Result</th>
* </tr> * </tr>
* <tr><td align=center>:</td> * <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> * <tr><td align=center>o</td>
* <td><tt>{ "b", "", ":and:f" }</tt></td></tr> * <td>{@code { "b", "", ":and:f" }}</td></tr>
* </table></blockquote> * </table></blockquote>
* *
* *
...@@ -2815,7 +2821,7 @@ public final class String ...@@ -2815,7 +2821,7 @@ public final class String
* limited by the maximum dimension of a Java array as defined by * limited by the maximum dimension of a Java array as defined by
* <cite>The Java&trade; Virtual Machine Specification</cite>. * <cite>The Java&trade; Virtual Machine Specification</cite>.
* The behaviour on a * 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>. * href="../util/Formatter.html#syntax">conversion</a>.
* *
* @throws java.util.IllegalFormatException * @throws java.util.IllegalFormatException
...@@ -2828,7 +2834,7 @@ public final class String ...@@ -2828,7 +2834,7 @@ public final class String
* formatter class specification. * formatter class specification.
* *
* @throws NullPointerException * @throws NullPointerException
* If the <tt>format</tt> is <tt>null</tt> * If the {@code format} is {@code null}
* *
* @return A formatted string * @return A formatted string
* *
...@@ -2845,7 +2851,7 @@ public final class String ...@@ -2845,7 +2851,7 @@ public final class String
* *
* @param l * @param l
* The {@linkplain java.util.Locale locale} to apply during * 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. * is applied.
* *
* @param format * @param format
...@@ -2859,7 +2865,7 @@ public final class String ...@@ -2859,7 +2865,7 @@ public final class String
* limited by the maximum dimension of a Java array as defined by * limited by the maximum dimension of a Java array as defined by
* <cite>The Java&trade; Virtual Machine Specification</cite>. * <cite>The Java&trade; Virtual Machine Specification</cite>.
* The behaviour on a * 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>. * href="../util/Formatter.html#syntax">conversion</a>.
* *
* @throws java.util.IllegalFormatException * @throws java.util.IllegalFormatException
...@@ -2872,7 +2878,7 @@ public final class String ...@@ -2872,7 +2878,7 @@ public final class String
* formatter class specification * formatter class specification
* *
* @throws NullPointerException * @throws NullPointerException
* If the <tt>format</tt> is <tt>null</tt> * If the {@code format} is {@code null}
* *
* @return A formatted string * @return A formatted string
* *
...@@ -3143,7 +3149,7 @@ public final class String ...@@ -3143,7 +3149,7 @@ public final class String
* programmer should be aware that producing distinct integer results * programmer should be aware that producing distinct integer results
* for unequal objects may improve the performance of hash tables. * for unequal objects may improve the performance of hash tables.
* </ul> * </ul>
* <p/> * </p>
* The hash value will never be zero. * The hash value will never be zero.
* *
* @return a hash code value for this object. * @return a hash code value for this object.
......
...@@ -57,7 +57,7 @@ package java.lang; ...@@ -57,7 +57,7 @@ package java.lang;
* <p> * <p>
* In general, if sb refers to an instance of a {@code StringBuffer}, * In general, if sb refers to an instance of a {@code StringBuffer},
* then {@code sb.append(x)} has the same effect as * then {@code sb.append(x)} has the same effect as
* {@code sb.insert(sb.length(),&nbsp;x)}. * {@code sb.insert(sb.length(), x)}.
* <p> * <p>
* Whenever an operation occurs involving a source sequence (such as * Whenever an operation occurs involving a source sequence (such as
* appending or inserting from a source sequence), this class synchronizes * appending or inserting from a source sequence), this class synchronizes
...@@ -80,7 +80,7 @@ package java.lang; ...@@ -80,7 +80,7 @@ package java.lang;
* *
* As of release JDK 5, this class has been supplemented with an equivalent * As of release JDK 5, this class has been supplemented with an equivalent
* class designed for use by a single thread, {@link StringBuilder}. The * 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 * this one, as it supports all of the same operations but it is faster, as
* it performs no synchronization. * it performs no synchronization.
* *
...@@ -262,17 +262,17 @@ package java.lang; ...@@ -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> * <p>
* The characters of the <tt>StringBuffer</tt> argument are appended, * The characters of the {@code StringBuffer} argument are appended,
* in order, to the contents of this <tt>StringBuffer</tt>, increasing the * in order, to the contents of this {@code StringBuffer}, increasing the
* length of this <tt>StringBuffer</tt> by the length of the argument. * length of this {@code StringBuffer} by the length of the argument.
* If <tt>sb</tt> is <tt>null</tt>, then the four characters * If {@code sb} is {@code null}, then the four characters
* <tt>"null"</tt> are appended to this <tt>StringBuffer</tt>. * {@code "null"} are appended to this {@code StringBuffer}.
* <p> * <p>
* Let <i>n</i> be the length of the old character sequence, the one * 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 * contained in the {@code StringBuffer} just prior to execution of the
* <tt>append</tt> method. Then the character at index <i>k</i> in * {@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> * 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>; * 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 * otherwise, it is equal to the character at index <i>k-n</i> in the
...@@ -281,7 +281,7 @@ package java.lang; ...@@ -281,7 +281,7 @@ package java.lang;
* This method synchronizes on {@code this}, the destination * This method synchronizes on {@code this}, the destination
* object, but does not synchronize on the source ({@code sb}). * 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. * @return a reference to this object.
* @since 1.4 * @since 1.4
*/ */
......
...@@ -28,39 +28,39 @@ package java.lang; ...@@ -28,39 +28,39 @@ package java.lang;
/** /**
* A mutable sequence of characters. This class provides an API compatible * 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 * 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, * used by a single thread (as is generally the case). Where possible,
* it is recommended that this class be used in preference to * 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 * <p>The principal operations on a {@code StringBuilder} are the
* <code>append</code> and <code>insert</code> methods, which are * {@code append} and {@code insert} methods, which are
* overloaded so as to accept data of any type. Each effectively * overloaded so as to accept data of any type. Each effectively
* converts a given datum to a string and then appends or inserts the * converts a given datum to a string and then appends or inserts the
* characters of that string to the string builder. The * characters of that string to the string builder. The
* <code>append</code> method always adds these characters at the end * {@code append} method always adds these characters at the end
* of the builder; the <code>insert</code> method adds the characters at * of the builder; the {@code insert} method adds the characters at
* a specified point. * a specified point.
* <p> * <p>
* For example, if <code>z</code> refers to a string builder object * For example, if {@code z} refers to a string builder object
* whose current contents are "<code>start</code>", then * whose current contents are "{@code start}", then
* the method call <code>z.append("le")</code> would cause the string * the method call {@code z.append("le")} would cause the string
* builder to contain "<code>startle</code>", whereas * builder to contain "{@code startle}", whereas
* <code>z.insert(4, "le")</code> would alter the string builder to * {@code z.insert(4, "le")} would alter the string builder to
* contain "<code>starlet</code>". * 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> * <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(),&nbsp;x)</code>.
*
* Every string builder has a capacity. As long as the length of the * Every string builder has a capacity. As long as the length of the
* character sequence contained in the string builder does not exceed * character sequence contained in the string builder does not exceed
* the capacity, it is not necessary to allocate a new internal * the capacity, it is not necessary to allocate a new internal
* buffer. If the internal buffer overflows, it is automatically made larger. * 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 * use by multiple threads. If such synchronization is required then it is
* recommended that {@link java.lang.StringBuffer} be used. * recommended that {@link java.lang.StringBuffer} be used.
* *
...@@ -87,11 +87,11 @@ public final class StringBuilder ...@@ -87,11 +87,11 @@ public final class StringBuilder
/** /**
* Constructs a string builder with no characters in it and an * 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. * @param capacity the initial capacity.
* @throws NegativeArraySizeException if the <code>capacity</code> * @throws NegativeArraySizeException if the {@code capacity}
* argument is less than <code>0</code>. * argument is less than {@code 0}.
*/ */
public StringBuilder(int capacity) { public StringBuilder(int capacity) {
super(capacity); super(capacity);
...@@ -100,10 +100,10 @@ public final class StringBuilder ...@@ -100,10 +100,10 @@ public final class StringBuilder
/** /**
* Constructs a string builder initialized to the contents of the * Constructs a string builder initialized to the contents of the
* specified string. The initial capacity of the string builder is * 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. * @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) { public StringBuilder(String str) {
super(str.length() + 16); super(str.length() + 16);
...@@ -112,12 +112,12 @@ public final class StringBuilder ...@@ -112,12 +112,12 @@ public final class StringBuilder
/** /**
* Constructs a string builder that contains the same characters * Constructs a string builder that contains the same characters
* as the specified <code>CharSequence</code>. The initial capacity of * as the specified {@code CharSequence}. The initial capacity of
* the string builder is <code>16</code> plus the length of the * the string builder is {@code 16} plus the length of the
* <code>CharSequence</code> argument. * {@code CharSequence} argument.
* *
* @param seq the sequence to copy. * @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) { public StringBuilder(CharSequence seq) {
this(seq.length() + 16); this(seq.length() + 16);
...@@ -136,22 +136,22 @@ public final class StringBuilder ...@@ -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> * <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 * in order, to this sequence, increasing the
* length of this sequence by the length of the argument. * length of this sequence by the length of the argument.
* If <tt>sb</tt> is <tt>null</tt>, then the four characters * If {@code sb} is {@code null}, then the four characters
* <tt>"null"</tt> are appended to this sequence. * {@code "null"} are appended to this sequence.
* <p> * <p>
* Let <i>n</i> be the length of this character sequence just prior to * 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 * <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 * 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> * <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. * @return a reference to this object.
*/ */
public StringBuilder append(StringBuffer sb) { public StringBuilder append(StringBuffer sb) {
...@@ -418,13 +418,13 @@ public final class StringBuilder ...@@ -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). * (that is, serialize it).
* *
* @serialData the number of characters currently stored in the string * @serialData the number of characters currently stored in the string
* builder (<tt>int</tt>), followed by the characters in the * builder ({@code int}), followed by the characters in the
* string builder (<tt>char[]</tt>). The length of the * string builder ({@code char[]}). The length of the
* <tt>char</tt> array may be greater than the number of * {@code char} array may be greater than the number of
* characters currently stored in the string builder, in which * characters currently stored in the string builder, in which
* case extra characters are ignored. * case extra characters are ignored.
*/ */
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
package java.lang; 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 * is either negative or greater than the size of the string. For
* some methods such as the charAt method, this exception also is * some methods such as the charAt method, this exception also is
* thrown when the index is equal to the size of the string. * thrown when the index is equal to the size of the string.
...@@ -40,7 +40,7 @@ class StringIndexOutOfBoundsException extends IndexOutOfBoundsException { ...@@ -40,7 +40,7 @@ class StringIndexOutOfBoundsException extends IndexOutOfBoundsException {
private static final long serialVersionUID = -6762910422159637258L; private static final long serialVersionUID = -6762910422159637258L;
/** /**
* Constructs a <code>StringIndexOutOfBoundsException</code> with no * Constructs a {@code StringIndexOutOfBoundsException} with no
* detail message. * detail message.
* *
* @since JDK1.0. * @since JDK1.0.
...@@ -50,7 +50,7 @@ class StringIndexOutOfBoundsException extends IndexOutOfBoundsException { ...@@ -50,7 +50,7 @@ class StringIndexOutOfBoundsException extends IndexOutOfBoundsException {
} }
/** /**
* Constructs a <code>StringIndexOutOfBoundsException</code> with * Constructs a {@code StringIndexOutOfBoundsException} with
* the specified detail message. * the specified detail message.
* *
* @param s the detail message. * @param s the detail message.
...@@ -60,7 +60,7 @@ class StringIndexOutOfBoundsException extends IndexOutOfBoundsException { ...@@ -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. * class with an argument indicating the illegal index.
* *
* @param index the illegal index. * @param index the illegal index.
......
/*
* 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();
}
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
package java.security; package java.security;
import javax.security.auth.Subject;
/** /**
* This interface represents the abstract notion of a principal, which * This interface represents the abstract notion of a principal, which
* can be used to represent any entity, such as an individual, a * can be used to represent any entity, such as an individual, a
...@@ -45,7 +47,6 @@ public interface Principal { ...@@ -45,7 +47,6 @@ public interface Principal {
* *
* @return true if the principal passed in is the same as that * @return true if the principal passed in is the same as that
* encapsulated by this principal, and false otherwise. * encapsulated by this principal, and false otherwise.
*/ */
public boolean equals(Object another); public boolean equals(Object another);
...@@ -69,4 +70,24 @@ public interface Principal { ...@@ -69,4 +70,24 @@ public interface Principal {
* @return the name of this principal. * @return the name of this principal.
*/ */
public String getName(); 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 { ...@@ -2611,6 +2611,7 @@ public class ForkJoinPool extends AbstractExecutorService {
* {@link #shutdown} or {@link #shutdownNow}. * {@link #shutdown} or {@link #shutdownNow}.
* *
* @return the common pool instance * @return the common pool instance
* @since 1.8
*/ */
public static ForkJoinPool commonPool() { public static ForkJoinPool commonPool() {
// assert commonPool != null : "static init error"; // assert commonPool != null : "static init error";
...@@ -2793,6 +2794,7 @@ public class ForkJoinPool extends AbstractExecutorService { ...@@ -2793,6 +2794,7 @@ public class ForkJoinPool extends AbstractExecutorService {
* Returns the targeted parallelism level of the common pool. * Returns the targeted parallelism level of the common pool.
* *
* @return the targeted parallelism level of the common pool * @return the targeted parallelism level of the common pool
* @since 1.8
*/ */
public static int getCommonPoolParallelism() { public static int getCommonPoolParallelism() {
return commonPoolParallelism; return commonPoolParallelism;
......
...@@ -111,7 +111,7 @@ public class AtomicBoolean implements java.io.Serializable { ...@@ -111,7 +111,7 @@ public class AtomicBoolean implements java.io.Serializable {
* *
* @param expect the expected value * @param expect the expected value
* @param update the new value * @param update the new value
* @return true if successful. * @return true if successful
*/ */
public boolean weakCompareAndSet(boolean expect, boolean update) { public boolean weakCompareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0; int e = expect ? 1 : 0;
...@@ -146,16 +146,16 @@ public class AtomicBoolean implements java.io.Serializable { ...@@ -146,16 +146,16 @@ public class AtomicBoolean implements java.io.Serializable {
* @return the previous value * @return the previous value
*/ */
public final boolean getAndSet(boolean newValue) { public final boolean getAndSet(boolean newValue) {
for (;;) { boolean prev;
boolean current = get(); do {
if (compareAndSet(current, newValue)) prev = get();
return current; } while (!compareAndSet(prev, newValue));
} return prev;
} }
/** /**
* Returns the String representation of the current value. * 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() { public String toString() {
return Boolean.toString(get()); return Boolean.toString(get());
......
...@@ -115,11 +115,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { ...@@ -115,11 +115,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @return the previous value * @return the previous value
*/ */
public final int getAndSet(int newValue) { public final int getAndSet(int newValue) {
for (;;) { return unsafe.getAndSetInt(this, valueOffset, newValue);
int current = get();
if (compareAndSet(current, newValue))
return current;
}
} }
/** /**
...@@ -145,7 +141,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { ...@@ -145,7 +141,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* *
* @param expect the expected value * @param expect the expected value
* @param update the new value * @param update the new value
* @return true if successful. * @return true if successful
*/ */
public final boolean weakCompareAndSet(int expect, int update) { public final boolean weakCompareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update); return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
...@@ -157,12 +153,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { ...@@ -157,12 +153,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @return the previous value * @return the previous value
*/ */
public final int getAndIncrement() { public final int getAndIncrement() {
for (;;) { return getAndAdd(1);
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
} }
/** /**
...@@ -171,12 +162,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { ...@@ -171,12 +162,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @return the previous value * @return the previous value
*/ */
public final int getAndDecrement() { public final int getAndDecrement() {
for (;;) { return getAndAdd(-1);
int current = get();
int next = current - 1;
if (compareAndSet(current, next))
return current;
}
} }
/** /**
...@@ -186,12 +172,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { ...@@ -186,12 +172,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @return the previous value * @return the previous value
*/ */
public final int getAndAdd(int delta) { public final int getAndAdd(int delta) {
for (;;) { return unsafe.getAndAddInt(this, valueOffset, delta);
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return current;
}
} }
/** /**
...@@ -200,12 +181,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { ...@@ -200,12 +181,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @return the updated value * @return the updated value
*/ */
public final int incrementAndGet() { public final int incrementAndGet() {
for (;;) { return getAndAdd(1) + 1;
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
} }
/** /**
...@@ -214,12 +190,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { ...@@ -214,12 +190,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @return the updated value * @return the updated value
*/ */
public final int decrementAndGet() { public final int decrementAndGet() {
for (;;) { return getAndAdd(-1) - 1;
int current = get();
int next = current - 1;
if (compareAndSet(current, next))
return next;
}
} }
/** /**
...@@ -229,17 +200,12 @@ public class AtomicInteger extends Number implements java.io.Serializable { ...@@ -229,17 +200,12 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @return the updated value * @return the updated value
*/ */
public final int addAndGet(int delta) { public final int addAndGet(int delta) {
for (;;) { return getAndAdd(delta) + delta;
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return next;
}
} }
/** /**
* Returns the String representation of the current value. * 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() { public String toString() {
return Integer.toString(get()); return Integer.toString(get());
......
...@@ -145,12 +145,7 @@ public class AtomicIntegerArray implements java.io.Serializable { ...@@ -145,12 +145,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
* @return the previous value * @return the previous value
*/ */
public final int getAndSet(int i, int newValue) { public final int getAndSet(int i, int newValue) {
long offset = checkedByteOffset(i); return unsafe.getAndSetInt(array, checkedByteOffset(i), newValue);
while (true) {
int current = getRaw(offset);
if (compareAndSetRaw(offset, current, newValue))
return current;
}
} }
/** /**
...@@ -182,7 +177,7 @@ public class AtomicIntegerArray implements java.io.Serializable { ...@@ -182,7 +177,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
* @param i the index * @param i the index
* @param expect the expected value * @param expect the expected value
* @param update the new value * @param update the new value
* @return true if successful. * @return true if successful
*/ */
public final boolean weakCompareAndSet(int i, int expect, int update) { public final boolean weakCompareAndSet(int i, int expect, int update) {
return compareAndSet(i, expect, update); return compareAndSet(i, expect, update);
...@@ -216,12 +211,7 @@ public class AtomicIntegerArray implements java.io.Serializable { ...@@ -216,12 +211,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
* @return the previous value * @return the previous value
*/ */
public final int getAndAdd(int i, int delta) { public final int getAndAdd(int i, int delta) {
long offset = checkedByteOffset(i); return unsafe.getAndAddInt(array, checkedByteOffset(i), delta);
while (true) {
int current = getRaw(offset);
if (compareAndSetRaw(offset, current, current + delta))
return current;
}
} }
/** /**
...@@ -231,7 +221,7 @@ public class AtomicIntegerArray implements java.io.Serializable { ...@@ -231,7 +221,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
* @return the updated value * @return the updated value
*/ */
public final int incrementAndGet(int i) { 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 { ...@@ -241,7 +231,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
* @return the updated value * @return the updated value
*/ */
public final int decrementAndGet(int i) { 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 { ...@@ -252,13 +242,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
* @return the updated value * @return the updated value
*/ */
public final int addAndGet(int i, int delta) { public final int addAndGet(int i, int delta) {
long offset = checkedByteOffset(i); return getAndAdd(i, delta) + delta;
while (true) {
int current = getRaw(offset);
int next = current + delta;
if (compareAndSetRaw(offset, current, next))
return next;
}
} }
/** /**
......
...@@ -159,11 +159,11 @@ public abstract class AtomicIntegerFieldUpdater<T> { ...@@ -159,11 +159,11 @@ public abstract class AtomicIntegerFieldUpdater<T> {
* @return the previous value * @return the previous value
*/ */
public int getAndSet(T obj, int newValue) { public int getAndSet(T obj, int newValue) {
for (;;) { int prev;
int current = get(obj); do {
if (compareAndSet(obj, current, newValue)) prev = get(obj);
return current; } while (!compareAndSet(obj, prev, newValue));
} return prev;
} }
/** /**
...@@ -174,12 +174,12 @@ public abstract class AtomicIntegerFieldUpdater<T> { ...@@ -174,12 +174,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
* @return the previous value * @return the previous value
*/ */
public int getAndIncrement(T obj) { public int getAndIncrement(T obj) {
for (;;) { int prev, next;
int current = get(obj); do {
int next = current + 1; prev = get(obj);
if (compareAndSet(obj, current, next)) next = prev + 1;
return current; } while (!compareAndSet(obj, prev, next));
} return prev;
} }
/** /**
...@@ -190,12 +190,12 @@ public abstract class AtomicIntegerFieldUpdater<T> { ...@@ -190,12 +190,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
* @return the previous value * @return the previous value
*/ */
public int getAndDecrement(T obj) { public int getAndDecrement(T obj) {
for (;;) { int prev, next;
int current = get(obj); do {
int next = current - 1; prev = get(obj);
if (compareAndSet(obj, current, next)) next = prev - 1;
return current; } while (!compareAndSet(obj, prev, next));
} return prev;
} }
/** /**
...@@ -207,12 +207,12 @@ public abstract class AtomicIntegerFieldUpdater<T> { ...@@ -207,12 +207,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
* @return the previous value * @return the previous value
*/ */
public int getAndAdd(T obj, int delta) { public int getAndAdd(T obj, int delta) {
for (;;) { int prev, next;
int current = get(obj); do {
int next = current + delta; prev = get(obj);
if (compareAndSet(obj, current, next)) next = prev + delta;
return current; } while (!compareAndSet(obj, prev, next));
} return prev;
} }
/** /**
...@@ -223,12 +223,12 @@ public abstract class AtomicIntegerFieldUpdater<T> { ...@@ -223,12 +223,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
* @return the updated value * @return the updated value
*/ */
public int incrementAndGet(T obj) { public int incrementAndGet(T obj) {
for (;;) { int prev, next;
int current = get(obj); do {
int next = current + 1; prev = get(obj);
if (compareAndSet(obj, current, next)) next = prev + 1;
return next; } while (!compareAndSet(obj, prev, next));
} return next;
} }
/** /**
...@@ -239,12 +239,12 @@ public abstract class AtomicIntegerFieldUpdater<T> { ...@@ -239,12 +239,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
* @return the updated value * @return the updated value
*/ */
public int decrementAndGet(T obj) { public int decrementAndGet(T obj) {
for (;;) { int prev, next;
int current = get(obj); do {
int next = current - 1; prev = get(obj);
if (compareAndSet(obj, current, next)) next = prev - 1;
return next; } while (!compareAndSet(obj, prev, next));
} return next;
} }
/** /**
...@@ -256,12 +256,12 @@ public abstract class AtomicIntegerFieldUpdater<T> { ...@@ -256,12 +256,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
* @return the updated value * @return the updated value
*/ */
public int addAndGet(T obj, int delta) { public int addAndGet(T obj, int delta) {
for (;;) { int prev, next;
int current = get(obj); do {
int next = current + delta; prev = get(obj);
if (compareAndSet(obj, current, next)) next = prev + delta;
return next; } while (!compareAndSet(obj, prev, next));
} return next;
} }
/** /**
...@@ -361,6 +361,36 @@ public abstract class AtomicIntegerFieldUpdater<T> { ...@@ -361,6 +361,36 @@ public abstract class AtomicIntegerFieldUpdater<T> {
return unsafe.getIntVolatile(obj, offset); 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) { private void ensureProtectedAccess(T obj) {
if (cclass.isInstance(obj)) { if (cclass.isInstance(obj)) {
return; return;
......
...@@ -129,11 +129,7 @@ public class AtomicLong extends Number implements java.io.Serializable { ...@@ -129,11 +129,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @return the previous value * @return the previous value
*/ */
public final long getAndSet(long newValue) { public final long getAndSet(long newValue) {
while (true) { return unsafe.getAndSetLong(this, valueOffset, newValue);
long current = get();
if (compareAndSet(current, newValue))
return current;
}
} }
/** /**
...@@ -159,7 +155,7 @@ public class AtomicLong extends Number implements java.io.Serializable { ...@@ -159,7 +155,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* *
* @param expect the expected value * @param expect the expected value
* @param update the new value * @param update the new value
* @return true if successful. * @return true if successful
*/ */
public final boolean weakCompareAndSet(long expect, long update) { public final boolean weakCompareAndSet(long expect, long update) {
return unsafe.compareAndSwapLong(this, valueOffset, expect, update); return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
...@@ -171,12 +167,7 @@ public class AtomicLong extends Number implements java.io.Serializable { ...@@ -171,12 +167,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @return the previous value * @return the previous value
*/ */
public final long getAndIncrement() { public final long getAndIncrement() {
while (true) { return getAndAdd(1);
long current = get();
long next = current + 1;
if (compareAndSet(current, next))
return current;
}
} }
/** /**
...@@ -185,12 +176,7 @@ public class AtomicLong extends Number implements java.io.Serializable { ...@@ -185,12 +176,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @return the previous value * @return the previous value
*/ */
public final long getAndDecrement() { public final long getAndDecrement() {
while (true) { return getAndAdd(-1);
long current = get();
long next = current - 1;
if (compareAndSet(current, next))
return current;
}
} }
/** /**
...@@ -200,12 +186,7 @@ public class AtomicLong extends Number implements java.io.Serializable { ...@@ -200,12 +186,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @return the previous value * @return the previous value
*/ */
public final long getAndAdd(long delta) { public final long getAndAdd(long delta) {
while (true) { return unsafe.getAndAddLong(this, valueOffset, delta);
long current = get();
long next = current + delta;
if (compareAndSet(current, next))
return current;
}
} }
/** /**
...@@ -214,12 +195,7 @@ public class AtomicLong extends Number implements java.io.Serializable { ...@@ -214,12 +195,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @return the updated value * @return the updated value
*/ */
public final long incrementAndGet() { public final long incrementAndGet() {
for (;;) { return getAndAdd(1) + 1;
long current = get();
long next = current + 1;
if (compareAndSet(current, next))
return next;
}
} }
/** /**
...@@ -228,12 +204,7 @@ public class AtomicLong extends Number implements java.io.Serializable { ...@@ -228,12 +204,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @return the updated value * @return the updated value
*/ */
public final long decrementAndGet() { public final long decrementAndGet() {
for (;;) { return getAndAdd(-1) - 1;
long current = get();
long next = current - 1;
if (compareAndSet(current, next))
return next;
}
} }
/** /**
...@@ -243,17 +214,12 @@ public class AtomicLong extends Number implements java.io.Serializable { ...@@ -243,17 +214,12 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @return the updated value * @return the updated value
*/ */
public final long addAndGet(long delta) { public final long addAndGet(long delta) {
for (;;) { return getAndAdd(delta) + delta;
long current = get();
long next = current + delta;
if (compareAndSet(current, next))
return next;
}
} }
/** /**
* Returns the String representation of the current value. * 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() { public String toString() {
return Long.toString(get()); return Long.toString(get());
......
...@@ -144,12 +144,7 @@ public class AtomicLongArray implements java.io.Serializable { ...@@ -144,12 +144,7 @@ public class AtomicLongArray implements java.io.Serializable {
* @return the previous value * @return the previous value
*/ */
public final long getAndSet(int i, long newValue) { public final long getAndSet(int i, long newValue) {
long offset = checkedByteOffset(i); return unsafe.getAndSetLong(array, checkedByteOffset(i), newValue);
while (true) {
long current = getRaw(offset);
if (compareAndSetRaw(offset, current, newValue))
return current;
}
} }
/** /**
...@@ -181,7 +176,7 @@ public class AtomicLongArray implements java.io.Serializable { ...@@ -181,7 +176,7 @@ public class AtomicLongArray implements java.io.Serializable {
* @param i the index * @param i the index
* @param expect the expected value * @param expect the expected value
* @param update the new value * @param update the new value
* @return true if successful. * @return true if successful
*/ */
public final boolean weakCompareAndSet(int i, long expect, long update) { public final boolean weakCompareAndSet(int i, long expect, long update) {
return compareAndSet(i, expect, update); return compareAndSet(i, expect, update);
...@@ -215,12 +210,7 @@ public class AtomicLongArray implements java.io.Serializable { ...@@ -215,12 +210,7 @@ public class AtomicLongArray implements java.io.Serializable {
* @return the previous value * @return the previous value
*/ */
public final long getAndAdd(int i, long delta) { public final long getAndAdd(int i, long delta) {
long offset = checkedByteOffset(i); return unsafe.getAndAddLong(array, checkedByteOffset(i), delta);
while (true) {
long current = getRaw(offset);
if (compareAndSetRaw(offset, current, current + delta))
return current;
}
} }
/** /**
...@@ -230,7 +220,7 @@ public class AtomicLongArray implements java.io.Serializable { ...@@ -230,7 +220,7 @@ public class AtomicLongArray implements java.io.Serializable {
* @return the updated value * @return the updated value
*/ */
public final long incrementAndGet(int i) { 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 { ...@@ -240,7 +230,7 @@ public class AtomicLongArray implements java.io.Serializable {
* @return the updated value * @return the updated value
*/ */
public final long decrementAndGet(int i) { 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 { ...@@ -251,13 +241,7 @@ public class AtomicLongArray implements java.io.Serializable {
* @return the updated value * @return the updated value
*/ */
public long addAndGet(int i, long delta) { public long addAndGet(int i, long delta) {
long offset = checkedByteOffset(i); return getAndAdd(i, delta) + delta;
while (true) {
long current = getRaw(offset);
long next = current + delta;
if (compareAndSetRaw(offset, current, next))
return next;
}
} }
/** /**
......
...@@ -98,7 +98,7 @@ public abstract class AtomicLongFieldUpdater<T> { ...@@ -98,7 +98,7 @@ public abstract class AtomicLongFieldUpdater<T> {
* @param obj An object whose field to conditionally set * @param obj An object whose field to conditionally set
* @param expect the expected value * @param expect the expected value
* @param update the new value * @param update the new value
* @return true if successful. * @return true if successful
* @throws ClassCastException if {@code obj} is not an instance * @throws ClassCastException if {@code obj} is not an instance
* of the class possessing the field established in the constructor. * of the class possessing the field established in the constructor.
*/ */
...@@ -118,7 +118,7 @@ public abstract class AtomicLongFieldUpdater<T> { ...@@ -118,7 +118,7 @@ public abstract class AtomicLongFieldUpdater<T> {
* @param obj An object whose field to conditionally set * @param obj An object whose field to conditionally set
* @param expect the expected value * @param expect the expected value
* @param update the new value * @param update the new value
* @return true if successful. * @return true if successful
* @throws ClassCastException if {@code obj} is not an instance * @throws ClassCastException if {@code obj} is not an instance
* of the class possessing the field established in the constructor. * of the class possessing the field established in the constructor.
*/ */
...@@ -162,11 +162,11 @@ public abstract class AtomicLongFieldUpdater<T> { ...@@ -162,11 +162,11 @@ public abstract class AtomicLongFieldUpdater<T> {
* @return the previous value * @return the previous value
*/ */
public long getAndSet(T obj, long newValue) { public long getAndSet(T obj, long newValue) {
for (;;) { long prev;
long current = get(obj); do {
if (compareAndSet(obj, current, newValue)) prev = get(obj);
return current; } while (!compareAndSet(obj, prev, newValue));
} return prev;
} }
/** /**
...@@ -177,12 +177,12 @@ public abstract class AtomicLongFieldUpdater<T> { ...@@ -177,12 +177,12 @@ public abstract class AtomicLongFieldUpdater<T> {
* @return the previous value * @return the previous value
*/ */
public long getAndIncrement(T obj) { public long getAndIncrement(T obj) {
for (;;) { long prev, next;
long current = get(obj); do {
long next = current + 1; prev = get(obj);
if (compareAndSet(obj, current, next)) next = prev + 1;
return current; } while (!compareAndSet(obj, prev, next));
} return prev;
} }
/** /**
...@@ -193,12 +193,12 @@ public abstract class AtomicLongFieldUpdater<T> { ...@@ -193,12 +193,12 @@ public abstract class AtomicLongFieldUpdater<T> {
* @return the previous value * @return the previous value
*/ */
public long getAndDecrement(T obj) { public long getAndDecrement(T obj) {
for (;;) { long prev, next;
long current = get(obj); do {
long next = current - 1; prev = get(obj);
if (compareAndSet(obj, current, next)) next = prev - 1;
return current; } while (!compareAndSet(obj, prev, next));
} return prev;
} }
/** /**
...@@ -210,12 +210,12 @@ public abstract class AtomicLongFieldUpdater<T> { ...@@ -210,12 +210,12 @@ public abstract class AtomicLongFieldUpdater<T> {
* @return the previous value * @return the previous value
*/ */
public long getAndAdd(T obj, long delta) { public long getAndAdd(T obj, long delta) {
for (;;) { long prev, next;
long current = get(obj); do {
long next = current + delta; prev = get(obj);
if (compareAndSet(obj, current, next)) next = prev + delta;
return current; } while (!compareAndSet(obj, prev, next));
} return prev;
} }
/** /**
...@@ -226,12 +226,12 @@ public abstract class AtomicLongFieldUpdater<T> { ...@@ -226,12 +226,12 @@ public abstract class AtomicLongFieldUpdater<T> {
* @return the updated value * @return the updated value
*/ */
public long incrementAndGet(T obj) { public long incrementAndGet(T obj) {
for (;;) { long prev, next;
long current = get(obj); do {
long next = current + 1; prev = get(obj);
if (compareAndSet(obj, current, next)) next = prev + 1;
return next; } while (!compareAndSet(obj, prev, next));
} return next;
} }
/** /**
...@@ -242,12 +242,12 @@ public abstract class AtomicLongFieldUpdater<T> { ...@@ -242,12 +242,12 @@ public abstract class AtomicLongFieldUpdater<T> {
* @return the updated value * @return the updated value
*/ */
public long decrementAndGet(T obj) { public long decrementAndGet(T obj) {
for (;;) { long prev, next;
long current = get(obj); do {
long next = current - 1; prev = get(obj);
if (compareAndSet(obj, current, next)) next = prev - 1;
return next; } while (!compareAndSet(obj, prev, next));
} return next;
} }
/** /**
...@@ -259,12 +259,12 @@ public abstract class AtomicLongFieldUpdater<T> { ...@@ -259,12 +259,12 @@ public abstract class AtomicLongFieldUpdater<T> {
* @return the updated value * @return the updated value
*/ */
public long addAndGet(T obj, long delta) { public long addAndGet(T obj, long delta) {
for (;;) { long prev, next;
long current = get(obj); do {
long next = current + delta; prev = get(obj);
if (compareAndSet(obj, current, next)) next = prev + delta;
return next; } while (!compareAndSet(obj, prev, next));
} return next;
} }
private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> { private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
...@@ -345,6 +345,36 @@ public abstract class AtomicLongFieldUpdater<T> { ...@@ -345,6 +345,36 @@ public abstract class AtomicLongFieldUpdater<T> {
return unsafe.getLongVolatile(obj, offset); 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) { private void ensureProtectedAccess(T obj) {
if (cclass.isInstance(obj)) { if (cclass.isInstance(obj)) {
return; return;
......
...@@ -124,7 +124,7 @@ public class AtomicReference<V> implements java.io.Serializable { ...@@ -124,7 +124,7 @@ public class AtomicReference<V> implements java.io.Serializable {
* *
* @param expect the expected value * @param expect the expected value
* @param update the new value * @param update the new value
* @return true if successful. * @return true if successful
*/ */
public final boolean weakCompareAndSet(V expect, V update) { public final boolean weakCompareAndSet(V expect, V update) {
return unsafe.compareAndSwapObject(this, valueOffset, expect, update); return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
...@@ -136,17 +136,14 @@ public class AtomicReference<V> implements java.io.Serializable { ...@@ -136,17 +136,14 @@ public class AtomicReference<V> implements java.io.Serializable {
* @param newValue the new value * @param newValue the new value
* @return the previous value * @return the previous value
*/ */
@SuppressWarnings("unchecked")
public final V getAndSet(V newValue) { public final V getAndSet(V newValue) {
while (true) { return (V)unsafe.getAndSetObject(this, valueOffset, newValue);
V x = get();
if (compareAndSet(x, newValue))
return x;
}
} }
/** /**
* Returns the String representation of the current value. * 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() { public String toString() {
return String.valueOf(get()); return String.valueOf(get());
......
...@@ -159,13 +159,9 @@ public class AtomicReferenceArray<E> implements java.io.Serializable { ...@@ -159,13 +159,9 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
* @param newValue the new value * @param newValue the new value
* @return the previous value * @return the previous value
*/ */
@SuppressWarnings("unchecked")
public final E getAndSet(int i, E newValue) { public final E getAndSet(int i, E newValue) {
long offset = checkedByteOffset(i); return (E)unsafe.getAndSetObject(array, checkedByteOffset(i), newValue);
while (true) {
E current = getRaw(offset);
if (compareAndSetRaw(offset, current, newValue))
return current;
}
} }
/** /**
...@@ -197,7 +193,7 @@ public class AtomicReferenceArray<E> implements java.io.Serializable { ...@@ -197,7 +193,7 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
* @param i the index * @param i the index
* @param expect the expected value * @param expect the expected value
* @param update the new value * @param update the new value
* @return true if successful. * @return true if successful
*/ */
public final boolean weakCompareAndSet(int i, E expect, E update) { public final boolean weakCompareAndSet(int i, E expect, E update) {
return compareAndSet(i, expect, update); return compareAndSet(i, expect, update);
......
...@@ -116,7 +116,7 @@ public abstract class AtomicReferenceFieldUpdater<T, V> { ...@@ -116,7 +116,7 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
* @param obj An object whose field to conditionally set * @param obj An object whose field to conditionally set
* @param expect the expected value * @param expect the expected value
* @param update the new value * @param update the new value
* @return true if successful. * @return true if successful
*/ */
public abstract boolean compareAndSet(T obj, V expect, V update); public abstract boolean compareAndSet(T obj, V expect, V update);
...@@ -134,7 +134,7 @@ public abstract class AtomicReferenceFieldUpdater<T, V> { ...@@ -134,7 +134,7 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
* @param obj An object whose field to conditionally set * @param obj An object whose field to conditionally set
* @param expect the expected value * @param expect the expected value
* @param update the new value * @param update the new value
* @return true if successful. * @return true if successful
*/ */
public abstract boolean weakCompareAndSet(T obj, V expect, V update); public abstract boolean weakCompareAndSet(T obj, V expect, V update);
...@@ -176,11 +176,11 @@ public abstract class AtomicReferenceFieldUpdater<T, V> { ...@@ -176,11 +176,11 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
* @return the previous value * @return the previous value
*/ */
public V getAndSet(T obj, V newValue) { public V getAndSet(T obj, V newValue) {
for (;;) { V prev;
V current = get(obj); do {
if (compareAndSet(obj, current, newValue)) prev = get(obj);
return current; } while (!compareAndSet(obj, prev, newValue));
} return prev;
} }
private static final class AtomicReferenceFieldUpdaterImpl<T,V> private static final class AtomicReferenceFieldUpdaterImpl<T,V>
...@@ -321,6 +321,15 @@ public abstract class AtomicReferenceFieldUpdater<T, V> { ...@@ -321,6 +321,15 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
return (V)unsafe.getObjectVolatile(obj, offset); 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) { private void ensureProtectedAccess(T obj) {
if (cclass.isInstance(obj)) { if (cclass.isInstance(obj)) {
return; return;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -104,17 +104,30 @@ import sun.security.jca.*; ...@@ -104,17 +104,30 @@ import sun.security.jca.*;
* must be supplied to GCM/CCM implementations (via the {@code * must be supplied to GCM/CCM implementations (via the {@code
* updateAAD} methods) <b>before</b> the ciphertext is processed (via * updateAAD} methods) <b>before</b> the ciphertext is processed (via
* the {@code update} and {@code doFinal} methods). * 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> * <pre>
* GCMParameterSpec s = new GCMParameterSpec(...); * GCMParameterSpec s = ...;
* cipher.init(..., s); * cipher.init(..., s);
* *
* // If the GCMParameterSpec is needed again * // If the GCM parameters were generated by the provider, it can
* cipher.getParameters().getParameterSpec(GCMParameterSpec.class)); * // be retrieved by:
* // cipher.getParameters().getParameterSpec(GCMParameterSpec.class);
* *
* cipher.updateAAD(...); // AAD * cipher.updateAAD(...); // AAD
* cipher.update(...); // Multi-part update * cipher.update(...); // Multi-part update
* cipher.doFinal(...); // conclusion of operation * 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> * </pre>
* Every implementation of the Java platform is required to support * Every implementation of the Java platform is required to support
* the following standard <code>Cipher</code> transformations with the keysizes * the following standard <code>Cipher</code> transformations with the keysizes
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -43,7 +43,7 @@ import java.security.spec.AlgorithmParameterSpec; ...@@ -43,7 +43,7 @@ import java.security.spec.AlgorithmParameterSpec;
* (Additional Authenticated Data (AAD), Keys, block ciphers, * (Additional Authenticated Data (AAD), Keys, block ciphers,
* plain/ciphertext and authentication tags) are handled in the {@code * plain/ciphertext and authentication tags) are handled in the {@code
* Cipher} class. * Cipher} class.
<p> * <p>
* Please see <a href="http://www.ietf.org/rfc/rfc5116.txt"> RFC 5116 * Please see <a href="http://www.ietf.org/rfc/rfc5116.txt"> RFC 5116
* </a> for more information on the Authenticated Encryption with * </a> for more information on the Authenticated Encryption with
* Associated Data (AEAD) algorithm, and <a href= * Associated Data (AEAD) algorithm, and <a href=
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -409,6 +409,15 @@ public enum LauncherHelper { ...@@ -409,6 +409,15 @@ public enum LauncherHelper {
if (mainValue == null) { if (mainValue == null) {
abort(null, "java.launcher.jar.error3", jarname); 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(); return mainValue.trim();
} catch (IOException ioe) { } catch (IOException ioe) {
abort(ioe, "java.launcher.jar.error1", jarname); abort(ioe, "java.launcher.jar.error1", jarname);
...@@ -483,26 +492,23 @@ public enum LauncherHelper { ...@@ -483,26 +492,23 @@ public enum LauncherHelper {
} catch (NoClassDefFoundError | ClassNotFoundException cnfe) { } catch (NoClassDefFoundError | ClassNotFoundException cnfe) {
abort(cnfe, "java.launcher.cls.error1", cn); abort(cnfe, "java.launcher.cls.error1", cn);
} }
// set to mainClass, FXHelper may return something else // set to mainClass
appClass = mainClass; appClass = mainClass;
Method m = getMainMethod(mainClass); /*
if (m != null) { * Check if FXHelper can launch it using the FX launcher. In an FX app,
// this will abort if main method has the wrong signature * the main class may or may not have a main method, so do this before
validateMainMethod(m); * validating the main class.
return mainClass; */
} if (mainClass.equals(FXHelper.class) ||
FXHelper.doesExtendFXApplication(mainClass)) {
// Check if FXHelper can launch it using the FX launcher // Will abort() if there are problems with the FX runtime
Class<?> fxClass = FXHelper.getFXMainClass(mainClass); FXHelper.setFXLaunchParameters(what, mode);
if (fxClass != null) { return FXHelper.class;
return fxClass;
} }
// not an FX application either, abort with an error validateMainClass(mainClass);
abort(null, "java.launcher.cls.error4", mainClass.getName(), return mainClass;
FXHelper.JAVAFX_APPLICATION_CLASS_NAME);
return null; // avoid compiler error...
} }
/* /*
...@@ -515,16 +521,18 @@ public enum LauncherHelper { ...@@ -515,16 +521,18 @@ public enum LauncherHelper {
return appClass; return appClass;
} }
// Check for main method or return null if not found // Check the existence and signature of main and abort if incorrect
static Method getMainMethod(Class<?> clazz) { static void validateMainClass(Class<?> mainClass) {
Method mainMethod;
try { try {
return clazz.getMethod("main", String[].class); mainMethod = mainClass.getMethod("main", String[].class);
} catch (NoSuchMethodException nsme) {} } catch (NoSuchMethodException nsme) {
return null; // 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 * getMethod (above) will choose the correct method, based
* on its name and parameter type, however, we still have to * on its name and parameter type, however, we still have to
...@@ -644,41 +652,78 @@ public enum LauncherHelper { ...@@ -644,41 +652,78 @@ public enum LauncherHelper {
} }
static final class FXHelper { 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 = private static final String JAVAFX_APPLICATION_CLASS_NAME =
"javafx.application.Application"; "javafx.application.Application";
private static final String JAVAFX_LAUNCHER_CLASS_NAME = private static final String JAVAFX_LAUNCHER_CLASS_NAME =
"com.sun.javafx.application.LauncherImpl"; "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 * FX application launcher and launch method, so we can launch
* applications with no main method. * applications with no main method.
*/ */
private static String fxLaunchName = null;
private static String fxLaunchMode = null;
private static Class<?> fxLauncherClass = null; private static Class<?> fxLauncherClass = null;
private static Method fxLauncherMethod = null; private static Method fxLauncherMethod = null;
/* /*
* We can assume that the class does NOT have a main method or it would * Set the launch params according to what was passed to LauncherHelper
* have been handled already. We do, however, need to check if the class * so we can use the same launch mode for FX. Abort if there is any
* extends Application and the launcher is available and abort with an * issue with loading the FX runtime or with the launcher method.
* error if it's not.
*/ */
private static Class<?> getFXMainClass(Class<?> mainClass) { private static void setFXLaunchParameters(String what, int mode) {
// Check if mainClass extends Application
if (!doesExtendFXApplication(mainClass)) {
return null;
}
// Check for the FX launcher classes // Check for the FX launcher classes
try { try {
fxLauncherClass = scloader.loadClass(JAVAFX_LAUNCHER_CLASS_NAME); fxLauncherClass = scloader.loadClass(JAVAFX_LAUNCHER_CLASS_NAME);
/*
* signature must be:
* public static void launchApplication(String launchName,
* String launchMode, String[] args);
*/
fxLauncherMethod = fxLauncherClass.getMethod("launchApplication", 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) { } catch (ClassNotFoundException | NoSuchMethodException ex) {
abort(ex, "java.launcher.cls.error5", ex); abort(ex, "java.launcher.cls.error5", ex);
} }
// That's all, return this class so we can launch later fxLaunchName = what;
return FXHelper.class; 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 { ...@@ -696,11 +741,15 @@ public enum LauncherHelper {
return false; return false;
} }
// preloader ?
public static void main(String... args) throws Exception { 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 // 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=\ ...@@ -140,3 +140,6 @@ java.launcher.jar.error1=\
java.launcher.jar.error2=manifest not found in {0} java.launcher.jar.error2=manifest not found in {0}
java.launcher.jar.error3=no main manifest attribute, in {0} java.launcher.jar.error3=no main manifest attribute, in {0}
java.launcher.init.error=initialization error 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 { ...@@ -206,7 +206,8 @@ public class AuthenticationHeader {
if(v == null) { if(v == null) {
if ((v=schemes.get ("digest")) == 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"); v = schemes.get ("basic");
} }
} }
......
...@@ -86,7 +86,7 @@ class InitSecContextToken extends InitialToken { ...@@ -86,7 +86,7 @@ class InitSecContextToken extends InitialToken {
* For the context acceptor to call. It reads the bytes out of an * For the context acceptor to call. It reads the bytes out of an
* InputStream and constructs an InitSecContextToken with them. * InputStream and constructs an InitSecContextToken with them.
*/ */
InitSecContextToken(Krb5Context context, EncryptionKey[] keys, InitSecContextToken(Krb5Context context, Krb5AcceptCredential cred,
InputStream is) InputStream is)
throws IOException, GSSException, KrbException { throws IOException, GSSException, KrbException {
...@@ -105,7 +105,7 @@ class InitSecContextToken extends InitialToken { ...@@ -105,7 +105,7 @@ class InitSecContextToken extends InitialToken {
if (context.getChannelBinding() != null) { if (context.getChannelBinding() != null) {
addr = context.getChannelBinding().getInitiatorAddress(); addr = context.getChannelBinding().getInitiatorAddress();
} }
apReq = new KrbApReq(apReqBytes, keys, addr); apReq = new KrbApReq(apReqBytes, cred, addr);
//debug("\nReceived AP-REQ and authenticated it.\n"); //debug("\nReceived AP-REQ and authenticated it.\n");
EncryptionKey sessionKey = apReq.getCreds().getSessionKey(); EncryptionKey sessionKey = apReq.getCreds().getSessionKey();
......
...@@ -45,13 +45,10 @@ import javax.security.auth.DestroyFailedException; ...@@ -45,13 +45,10 @@ import javax.security.auth.DestroyFailedException;
public class Krb5AcceptCredential public class Krb5AcceptCredential
implements Krb5CredElement { implements Krb5CredElement {
private static final long serialVersionUID = 7714332137352567952L; private final Krb5NameElement name;
private final ServiceCreds screds;
private Krb5NameElement name; private Krb5AcceptCredential(Krb5NameElement name, ServiceCreds creds) {
private Krb5Util.ServiceCreds screds;
private Krb5AcceptCredential(Krb5NameElement name, Krb5Util.ServiceCreds creds) {
/* /*
* Initialize this instance with the data from the acquired * Initialize this instance with the data from the acquired
* KerberosKey. This class needs to be a KerberosKey too * KerberosKey. This class needs to be a KerberosKey too
...@@ -69,11 +66,11 @@ public class Krb5AcceptCredential ...@@ -69,11 +66,11 @@ public class Krb5AcceptCredential
name.getKrb5PrincipalName().getName()); name.getKrb5PrincipalName().getName());
final AccessControlContext acc = AccessController.getContext(); final AccessControlContext acc = AccessController.getContext();
Krb5Util.ServiceCreds creds = null; ServiceCreds creds = null;
try { try {
creds = AccessController.doPrivileged( creds = AccessController.doPrivileged(
new PrivilegedExceptionAction<Krb5Util.ServiceCreds>() { new PrivilegedExceptionAction<ServiceCreds>() {
public Krb5Util.ServiceCreds run() throws Exception { public ServiceCreds run() throws Exception {
return Krb5Util.getServiceCreds( return Krb5Util.getServiceCreds(
caller == GSSCaller.CALLER_UNKNOWN ? GSSCaller.CALLER_ACCEPT: caller, caller == GSSCaller.CALLER_UNKNOWN ? GSSCaller.CALLER_ACCEPT: caller,
serverPrinc, acc); serverPrinc, acc);
...@@ -92,8 +89,10 @@ public class Krb5AcceptCredential ...@@ -92,8 +89,10 @@ public class Krb5AcceptCredential
if (name == null) { if (name == null) {
String fullName = creds.getName(); String fullName = creds.getName();
name = Krb5NameElement.getInstance(fullName, if (fullName != null) {
name = Krb5NameElement.getInstance(fullName,
Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL); Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);
}
} }
return new Krb5AcceptCredential(name, creds); return new Krb5AcceptCredential(name, creds);
...@@ -153,8 +152,8 @@ public class Krb5AcceptCredential ...@@ -153,8 +152,8 @@ public class Krb5AcceptCredential
return Krb5MechFactory.PROVIDER; return Krb5MechFactory.PROVIDER;
} }
EncryptionKey[] getKrb5EncryptionKeys() { public EncryptionKey[] getKrb5EncryptionKeys(PrincipalName princ) {
return screds.getEKeys(); return screds.getEKeys(princ);
} }
/** /**
......
...@@ -818,16 +818,23 @@ class Krb5Context implements GSSContextSpi { ...@@ -818,16 +818,23 @@ class Krb5Context implements GSSContextSpi {
} }
myName = (Krb5NameElement) myCred.getName(); myName = (Krb5NameElement) myCred.getName();
checkPermission(myName.getKrb5PrincipalName().getName(), // If there is already a bound name, check now
"accept"); if (myName != null) {
Krb5MechFactory.checkAcceptCredPermission(myName, myName);
EncryptionKey[] secretKeys = }
((Krb5AcceptCredential) myCred).getKrb5EncryptionKeys();
InitSecContextToken token = new InitSecContextToken(this, InitSecContextToken token = new InitSecContextToken(this,
secretKeys, is); (Krb5AcceptCredential) myCred, is);
PrincipalName clientName = token.getKrbApReq().getClient(); PrincipalName clientName = token.getKrbApReq().getClient();
peerName = Krb5NameElement.getInstance(clientName); 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()) { if (getMutualAuthState()) {
retVal = new AcceptSecContextToken(this, retVal = new AcceptSecContextToken(this,
token.getKrbApReq()).encode(); token.getKrbApReq()).encode();
......
...@@ -158,7 +158,7 @@ public final class Krb5MechFactory implements MechanismFactory { ...@@ -158,7 +158,7 @@ public final class Krb5MechFactory implements MechanismFactory {
public static void checkAcceptCredPermission(Krb5NameElement name, public static void checkAcceptCredPermission(Krb5NameElement name,
GSSNameSpi originalName) { GSSNameSpi originalName) {
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null && name != null) {
ServicePermission perm = new ServicePermission ServicePermission perm = new ServicePermission
(name.getKrb5PrincipalName().getName(), "accept"); (name.getKrb5PrincipalName().getName(), "accept");
try { try {
......
...@@ -186,114 +186,6 @@ public class Krb5Util { ...@@ -186,114 +186,6 @@ public class Krb5Util {
return subject; 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 * Retrieves the ServiceCreds for the specified server principal from
* the Subject in the specified AccessControlContext. If not found, and if * the Subject in the specified AccessControlContext. If not found, and if
...@@ -361,5 +253,4 @@ public class Krb5Util { ...@@ -361,5 +253,4 @@ public class Krb5Util {
return KerberosSecrets.getJavaxSecurityAuthKerberosAccess(). return KerberosSecrets.getJavaxSecurityAuthKerberosAccess().
keyTabGetEncryptionKeys(ktab, cname); keyTabGetEncryptionKeys(ktab, cname);
} }
} }
/*
* 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; ...@@ -33,6 +33,7 @@ import java.util.Iterator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.kerberos.KeyTab; import javax.security.auth.kerberos.KeyTab;
/** /**
...@@ -84,19 +85,37 @@ class SubjectComber { ...@@ -84,19 +85,37 @@ class SubjectComber {
} else { } else {
List<T> answer = (oneOnly ? null : new ArrayList<T>()); List<T> answer = (oneOnly ? null : new ArrayList<T>());
if (credClass == KeyTab.class) { // Principal un-related if (credClass == KeyTab.class) {
// We are looking for credentials unrelated to serverPrincipal // TODO: There is currently no good way to filter out keytabs
Iterator<T> iterator = // not for serverPrincipal. We can only check the principal
subject.getPrivateCredentials(credClass).iterator(); // set. If the server is not there, we can be sure none of the
while (iterator.hasNext()) { // keytabs should be used, otherwise, use all for safety.
T t = iterator.next(); boolean useAll = false;
if (DEBUG) { if (serverPrincipal != null) {
System.out.println("Found " + credClass.getSimpleName()); for (KerberosPrincipal princ:
subject.getPrincipals(KerberosPrincipal.class)) {
if (princ.getName().equals(serverPrincipal)) {
useAll = true;
break;
}
} }
if (oneOnly) { } else {
return t; useAll = true;
} else { }
answer.add(t); 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) { } else if (credClass == KerberosKey.class) {
...@@ -114,11 +133,6 @@ class SubjectComber { ...@@ -114,11 +133,6 @@ class SubjectComber {
if (oneOnly) { if (oneOnly) {
return t; return t;
} else { } else {
if (serverPrincipal == null) {
// Record name so that keys returned will all
// belong to the same principal
serverPrincipal = name;
}
answer.add(credClass.cast(t)); answer.add(credClass.cast(t));
} }
} }
......
...@@ -34,6 +34,7 @@ package sun.security.krb5; ...@@ -34,6 +34,7 @@ package sun.security.krb5;
import sun.security.krb5.internal.*; import sun.security.krb5.internal.*;
import sun.security.krb5.internal.crypto.*; import sun.security.krb5.internal.crypto.*;
import sun.security.krb5.internal.rcache.*; import sun.security.krb5.internal.rcache.*;
import sun.security.jgss.krb5.Krb5AcceptCredential;
import java.net.InetAddress; import java.net.InetAddress;
import sun.security.util.*; import sun.security.util.*;
import java.io.IOException; import java.io.IOException;
...@@ -135,13 +136,13 @@ public class KrbApReq { ...@@ -135,13 +136,13 @@ public class KrbApReq {
*/ */
// Used in InitSecContextToken (for AP_REQ and not TGS REQ) // Used in InitSecContextToken (for AP_REQ and not TGS REQ)
public KrbApReq(byte[] message, public KrbApReq(byte[] message,
EncryptionKey[] keys, Krb5AcceptCredential cred,
InetAddress initiator) InetAddress initiator)
throws KrbException, IOException { throws KrbException, IOException {
obuf = message; obuf = message;
if (apReqMessg == null) if (apReqMessg == null)
decode(); decode();
authenticate(keys, initiator); authenticate(cred, initiator);
} }
/** /**
...@@ -260,10 +261,11 @@ public class KrbApReq { ...@@ -260,10 +261,11 @@ public class KrbApReq {
} }
} }
private void authenticate(EncryptionKey[] keys, InetAddress initiator) private void authenticate(Krb5AcceptCredential cred, InetAddress initiator)
throws KrbException, IOException { throws KrbException, IOException {
int encPartKeyType = apReqMessg.ticket.encPart.getEType(); int encPartKeyType = apReqMessg.ticket.encPart.getEType();
Integer kvno = apReqMessg.ticket.encPart.getKeyVersionNumber(); Integer kvno = apReqMessg.ticket.encPart.getKeyVersionNumber();
EncryptionKey[] keys = cred.getKrb5EncryptionKeys(apReqMessg.ticket.sname);
EncryptionKey dkey = EncryptionKey.findKey(encPartKeyType, kvno, keys); EncryptionKey dkey = EncryptionKey.findKey(encPartKeyType, kvno, keys);
if (dkey == null) { if (dkey == null) {
......
...@@ -382,9 +382,15 @@ public class KeyTab implements KeyTabConstants { ...@@ -382,9 +382,15 @@ public class KeyTab implements KeyTabConstants {
*/ */
public void addEntry(PrincipalName service, char[] psswd, public void addEntry(PrincipalName service, char[] psswd,
int kvno, boolean append) throws KrbException { 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( EncryptionKey[] encKeys = EncryptionKey.acquireSecretKeys(
psswd, service.getSalt()); psswd, salt);
// There should be only one maximum KVNO value for all etypes, so that // There should be only one maximum KVNO value for all etypes, so that
// all added keys can have the same KVNO. // all added keys can have the same KVNO.
......
...@@ -31,13 +31,7 @@ import java.net.MalformedURLException; ...@@ -31,13 +31,7 @@ import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URI; import java.net.URI;
import java.util.*; 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 java.text.MessageFormat;
import com.sun.security.auth.PrincipalComparator;
import java.security.*; import java.security.*;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
...@@ -46,19 +40,7 @@ import javax.security.auth.x500.X500Principal; ...@@ -46,19 +40,7 @@ import javax.security.auth.x500.X500Principal;
import java.io.FilePermission; import java.io.FilePermission;
import java.net.SocketPermission; import java.net.SocketPermission;
import java.net.NetPermission; import java.net.NetPermission;
import java.util.PropertyPermission;
import java.util.concurrent.atomic.AtomicReference; 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 sun.misc.JavaSecurityProtectionDomainAccess;
import static sun.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache; import static sun.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
import sun.misc.SharedSecrets; import sun.misc.SharedSecrets;
...@@ -794,12 +776,9 @@ public class PolicyFile extends java.security.Policy { ...@@ -794,12 +776,9 @@ public class PolicyFile extends java.security.Policy {
debug.println("Adding policy entry: "); debug.println("Adding policy entry: ");
debug.println(" signedBy " + ge.signedBy); debug.println(" signedBy " + ge.signedBy);
debug.println(" codeBase " + ge.codeBase); debug.println(" codeBase " + ge.codeBase);
if (ge.principals != null && ge.principals.size() > 0) { if (ge.principals != null) {
ListIterator<PolicyParser.PrincipalEntry> li = for (PolicyParser.PrincipalEntry pppe : ge.principals) {
ge.principals.listIterator(); debug.println(" " + pppe.toString());
while (li.hasNext()) {
PolicyParser.PrincipalEntry pppe = li.next();
debug.println(" " + pppe.toString());
} }
} }
} }
...@@ -955,11 +934,15 @@ public class PolicyFile extends java.security.Policy { ...@@ -955,11 +934,15 @@ public class PolicyFile extends java.security.Policy {
InvocationTargetException InvocationTargetException
{ {
//XXX we might want to keep a hash of created factories... //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); Permission answer = getKnownInstance(pc, name, actions);
if (answer != null) { if (answer != null) {
return answer; return answer;
} }
if (!Permission.class.isAssignableFrom(pc)) {
// not the right subtype
throw new ClassCastException(type + " is not a Permission");
}
if (name == null && actions == null) { if (name == null && actions == null) {
try { try {
...@@ -1001,7 +984,6 @@ public class PolicyFile extends java.security.Policy { ...@@ -1001,7 +984,6 @@ public class PolicyFile extends java.security.Policy {
*/ */
private static final Permission getKnownInstance(Class<?> claz, private static final Permission getKnownInstance(Class<?> claz,
String name, String actions) { String name, String actions) {
// XXX shorten list to most popular ones?
if (claz.equals(FilePermission.class)) { if (claz.equals(FilePermission.class)) {
return new FilePermission(name, actions); return new FilePermission(name, actions);
} else if (claz.equals(SocketPermission.class)) { } else if (claz.equals(SocketPermission.class)) {
...@@ -1014,30 +996,6 @@ public class PolicyFile extends java.security.Policy { ...@@ -1014,30 +996,6 @@ public class PolicyFile extends java.security.Policy {
return new NetPermission(name, actions); return new NetPermission(name, actions);
} else if (claz.equals(AllPermission.class)) { } else if (claz.equals(AllPermission.class)) {
return SecurityConstants.ALL_PERMISSION; 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 { } else {
return null; return null;
} }
...@@ -1079,7 +1037,7 @@ public class PolicyFile extends java.security.Policy { ...@@ -1079,7 +1037,7 @@ public class PolicyFile extends java.security.Policy {
if (cert != null) { if (cert != null) {
if (vcerts == null) if (vcerts == null)
vcerts = new ArrayList<Certificate>(); vcerts = new ArrayList<>();
vcerts.add(cert); vcerts.add(cert);
} }
} }
...@@ -1329,7 +1287,7 @@ public class PolicyFile extends java.security.Policy { ...@@ -1329,7 +1287,7 @@ public class PolicyFile extends java.security.Policy {
List<PolicyParser.PrincipalEntry> entryPs = entry.getPrincipals(); List<PolicyParser.PrincipalEntry> entryPs = entry.getPrincipals();
if (debug != null) { if (debug != null) {
ArrayList<PolicyParser.PrincipalEntry> accPs = new ArrayList<>(); List<PolicyParser.PrincipalEntry> accPs = new ArrayList<>();
if (principals != null) { if (principals != null) {
for (int i = 0; i < principals.length; i++) { for (int i = 0; i < principals.length; i++) {
accPs.add(new PolicyParser.PrincipalEntry accPs.add(new PolicyParser.PrincipalEntry
...@@ -1368,79 +1326,72 @@ public class PolicyFile extends java.security.Policy { ...@@ -1368,79 +1326,72 @@ public class PolicyFile extends java.security.Policy {
// has principals. see if policy entry principals match // has principals. see if policy entry principals match
// principals in current ACC // principals in current ACC
for (int i = 0; i < entryPs.size(); i++) { for (PolicyParser.PrincipalEntry pppe : entryPs) {
PolicyParser.PrincipalEntry pppe = entryPs.get(i);
// see if principal entry is a PrincipalComparator
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)) { // Check for wildcards
if (debug != null) { if (pppe.isWildcardClass()) {
debug.println("evaluation (principals) failed"); // a wildcard class matches all principals in current ACC
} continue;
}
// policy entry principal not in current ACC - if (pppe.isWildcardName()) {
// immediately return and go to next policy entry // a wildcard name matches any principal with the same class
return; 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;
}
} else { 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");
}
// dealing with a PrincipalComparator Constructor<?> c = pClass.getConstructor(PARAMS1);
Principal p = (Principal)c.newInstance(new Object[] {
pppe.principalName });
Constructor<?> c = pClass.getConstructor(PARAMS1); if (debug != null) {
PrincipalComparator pc = (PrincipalComparator)c.newInstance debug.println("found Principal " + p.getClass().getName());
(new Object[] { pppe.principalName }); }
// check if the Principal implies the current
// thread's principals
if (!p.implies(subject)) {
if (debug != null) { if (debug != null) {
debug.println("found PrincipalComparator " + debug.println("evaluation (principal implies) failed");
pc.getClass().getName());
} }
// check if the PrincipalComparator // policy principal does not imply the current Subject -
// implies the current thread's principals // immediately return and go to next policy entry
return;
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;
}
} }
} catch (Exception e) { } catch (Exception e) {
// fall back to regular principal comparison. // fall back to default principal comparison.
// see if policy entry principal is in current ACC // see if policy entry principal is in current ACC
if (debug != null) { if (debug != null) {
e.printStackTrace(); e.printStackTrace();
} }
if (!checkEntryPs(principals, pppe)) { if (!pppe.implies(subject)) {
if (debug != null) { if (debug != null) {
debug.println("evaluation (principals) failed"); debug.println("evaluation (default principal implies) failed");
} }
// policy entry principal not in current ACC - // policy entry principal not in current ACC -
...@@ -1450,7 +1401,7 @@ public class PolicyFile extends java.security.Policy { ...@@ -1450,7 +1401,7 @@ public class PolicyFile extends java.security.Policy {
} }
// either the principal information matched, // either the principal information matched,
// or the PrincipalComparator.implies succeeded. // or the Principal.implies succeeded.
// continue loop and test the next policy principal // continue loop and test the next policy principal
} }
...@@ -1484,47 +1435,6 @@ public class PolicyFile extends java.security.Policy { ...@@ -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> * <p>
* *
...@@ -1568,8 +1478,7 @@ public class PolicyFile extends java.security.Policy { ...@@ -1568,8 +1478,7 @@ public class PolicyFile extends java.security.Policy {
sb.append(sp.getSelfName().substring(startIndex, v)); sb.append(sp.getSelfName().substring(startIndex, v));
// expand SELF // expand SELF
ListIterator<PolicyParser.PrincipalEntry> pli = Iterator<PolicyParser.PrincipalEntry> pli = entryPs.iterator();
entryPs.listIterator();
while (pli.hasNext()) { while (pli.hasNext()) {
PolicyParser.PrincipalEntry pppe = pli.next(); PolicyParser.PrincipalEntry pppe = pli.next();
String[][] principalInfo = getPrincipalInfo(pppe,pdp); String[][] principalInfo = getPrincipalInfo(pppe,pdp);
...@@ -1596,8 +1505,8 @@ public class PolicyFile extends java.security.Policy { ...@@ -1596,8 +1505,8 @@ public class PolicyFile extends java.security.Policy {
try { try {
// first try to instantiate the permission // first try to instantiate the permission
perms.add(getInstance(sp.getSelfType(), perms.add(getInstance(sp.getSelfType(),
sb.toString(), sb.toString(),
sp.getSelfActions())); sp.getSelfActions()));
} catch (ClassNotFoundException cnfe) { } catch (ClassNotFoundException cnfe) {
// ok, the permission is not in the bootclasspath. // ok, the permission is not in the bootclasspath.
// before we add an UnresolvedPermission, check to see // before we add an UnresolvedPermission, check to see
...@@ -1673,10 +1582,7 @@ public class PolicyFile extends java.security.Policy { ...@@ -1673,10 +1582,7 @@ public class PolicyFile extends java.security.Policy {
// 2) the entry's Principal name is wildcarded only // 2) the entry's Principal name is wildcarded only
// 3) the entry's Principal class and name are wildcarded // 3) the entry's Principal class and name are wildcarded
if (!pe.principalClass.equals if (!pe.isWildcardClass() && !pe.isWildcardName()) {
(PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&
!pe.principalName.equals
(PolicyParser.PrincipalEntry.WILDCARD_NAME)) {
// build an info array for the principal // build an info array for the principal
// from the Policy entry // from the Policy entry
...@@ -1685,24 +1591,19 @@ public class PolicyFile extends java.security.Policy { ...@@ -1685,24 +1591,19 @@ public class PolicyFile extends java.security.Policy {
info[0][1] = pe.principalName; info[0][1] = pe.principalName;
return info; return info;
} else if (!pe.principalClass.equals } else if (!pe.isWildcardClass() && pe.isWildcardName()) {
(PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&
pe.principalName.equals
(PolicyParser.PrincipalEntry.WILDCARD_NAME)) {
// build an info array for every principal // build an info array for every principal
// in the current domain which has a principal class // in the current domain which has a principal class
// that is equal to policy entry principal class name // that is equal to policy entry principal class name
List<Principal> plist = new ArrayList<>(); List<Principal> plist = new ArrayList<>();
for (int i = 0; i < pdp.length; i++) { 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]); plist.add(pdp[i]);
} }
String[][] info = new String[plist.size()][2]; String[][] info = new String[plist.size()][2];
int i = 0; int i = 0;
java.util.Iterator<Principal> pIterator = plist.iterator(); for (Principal p : plist) {
while (pIterator.hasNext()) {
Principal p = pIterator.next();
info[i][0] = p.getClass().getName(); info[i][0] = p.getClass().getName();
info[i][1] = p.getName(); info[i][1] = p.getName();
i++; i++;
...@@ -1763,7 +1664,7 @@ public class PolicyFile extends java.security.Policy { ...@@ -1763,7 +1664,7 @@ public class PolicyFile extends java.security.Policy {
// Done // Done
return certs; return certs;
ArrayList<Certificate> userCertList = new ArrayList<>(); List<Certificate> userCertList = new ArrayList<>();
i = 0; i = 0;
while (i < certs.length) { while (i < certs.length) {
userCertList.add(certs[i]); userCertList.add(certs[i]);
...@@ -1889,10 +1790,8 @@ public class PolicyFile extends java.security.Policy { ...@@ -1889,10 +1790,8 @@ public class PolicyFile extends java.security.Policy {
if (principals == null || principals.isEmpty() || keystore == null) if (principals == null || principals.isEmpty() || keystore == null)
return true; return true;
ListIterator<PolicyParser.PrincipalEntry> i = principals.listIterator(); for (PolicyParser.PrincipalEntry pppe : principals) {
while (i.hasNext()) { if (pppe.isReplaceName()) {
PolicyParser.PrincipalEntry pppe = i.next();
if (pppe.principalClass.equals(PolicyParser.REPLACE_NAME)) {
// perform replacement // perform replacement
// (only X509 replacement is possible now) // (only X509 replacement is possible now)
...@@ -2241,8 +2140,7 @@ public class PolicyFile extends java.security.Policy { ...@@ -2241,8 +2140,7 @@ public class PolicyFile extends java.security.Policy {
if (this.certs == null) { if (this.certs == null) {
// extract the signer certs // extract the signer certs
ArrayList<Certificate> signerCerts = List<Certificate> signerCerts = new ArrayList<>();
new ArrayList<>();
i = 0; i = 0;
while (i < certs.length) { while (i < certs.length) {
signerCerts.add(certs[i]); signerCerts.add(certs[i]);
...@@ -2406,11 +2304,10 @@ public class PolicyFile extends java.security.Policy { ...@@ -2406,11 +2304,10 @@ public class PolicyFile extends java.security.Policy {
private java.util.Random random; private java.util.Random random;
PolicyInfo(int numCaches) { PolicyInfo(int numCaches) {
policyEntries = new ArrayList<PolicyEntry>(); policyEntries = new ArrayList<>();
identityPolicyEntries = identityPolicyEntries =
Collections.synchronizedList(new ArrayList<PolicyEntry>(2)); Collections.synchronizedList(new ArrayList<PolicyEntry>(2));
aliasMapping = Collections.synchronizedMap( aliasMapping = Collections.synchronizedMap(new HashMap<>(11));
new HashMap<Object, Object>(11));
pdMapping = new ProtectionDomainCache[numCaches]; pdMapping = new ProtectionDomainCache[numCaches];
JavaSecurityProtectionDomainAccess jspda JavaSecurityProtectionDomainAccess jspda
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,16 +29,17 @@ import java.io.*; ...@@ -29,16 +29,17 @@ import java.io.*;
import java.lang.RuntimePermission; import java.lang.RuntimePermission;
import java.net.SocketPermission; import java.net.SocketPermission;
import java.net.URL; import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.Principal;
import java.text.MessageFormat;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Vector; import java.util.Vector;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.text.MessageFormat;
import javax.security.auth.x500.X500Principal; import javax.security.auth.x500.X500Principal;
import java.security.GeneralSecurityException;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.util.PropertyExpander; import sun.security.util.PropertyExpander;
import sun.security.util.ResourcesMgr; import sun.security.util.ResourcesMgr;
...@@ -72,7 +73,7 @@ import sun.security.util.ResourcesMgr; ...@@ -72,7 +73,7 @@ import sun.security.util.ResourcesMgr;
* Permissions perms = policy.getPermissions(protectiondomain) * Permissions perms = policy.getPermissions(protectiondomain)
* </pre> * </pre>
* *
* <p>The protection domain contains CodeSource * <p>The protection domain contains a CodeSource
* object, which encapsulates its codebase (URL) and public key attributes. * object, which encapsulates its codebase (URL) and public key attributes.
* It also contains the principals associated with the domain. * It also contains the principals associated with the domain.
* The Policy object evaluates the global policy in light of who the * The Policy object evaluates the global policy in light of who the
...@@ -87,9 +88,6 @@ import sun.security.util.ResourcesMgr; ...@@ -87,9 +88,6 @@ import sun.security.util.ResourcesMgr;
public class PolicyParser { 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 EXTDIRS_PROPERTY = "java.ext.dirs";
private static final String OLD_EXTDIRS_EXPANSION = private static final String OLD_EXTDIRS_EXPANSION =
"${" + EXTDIRS_PROPERTY + "}"; "${" + EXTDIRS_PROPERTY + "}";
...@@ -452,7 +450,7 @@ public class PolicyParser { ...@@ -452,7 +450,7 @@ public class PolicyParser {
peekAndMatch(","); peekAndMatch(",");
} else if (peekAndMatch("Principal")) { } else if (peekAndMatch("Principal")) {
if (principals == null) { if (principals == null) {
principals = new LinkedList<PrincipalEntry>(); principals = new LinkedList<>();
} }
String principalClass; String principalClass;
...@@ -461,7 +459,7 @@ public class PolicyParser { ...@@ -461,7 +459,7 @@ public class PolicyParser {
if (peek("\"")) { if (peek("\"")) {
// both the principalClass and principalName // both the principalClass and principalName
// will be replaced later // will be replaced later
principalClass = REPLACE_NAME; principalClass = PrincipalEntry.REPLACE_NAME;
principalName = match("principal type"); principalName = match("principal type");
} else { } else {
// check for principalClass wildcard // check for principalClass wildcard
...@@ -916,7 +914,7 @@ public class PolicyParser { ...@@ -916,7 +914,7 @@ public class PolicyParser {
out.print(",\n"); out.print(",\n");
} }
if (principals != null && principals.size() > 0) { if (principals != null && principals.size() > 0) {
ListIterator<PrincipalEntry> pli = principals.listIterator(); Iterator<PrincipalEntry> pli = principals.iterator();
while (pli.hasNext()) { while (pli.hasNext()) {
out.print(" "); out.print(" ");
PrincipalEntry pe = pli.next(); PrincipalEntry pe = pli.next();
...@@ -949,23 +947,22 @@ public class PolicyParser { ...@@ -949,23 +947,22 @@ public class PolicyParser {
/** /**
* Principal info (class and name) in a grant entry * 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_CLASS = "WILDCARD_PRINCIPAL_CLASS";
public static final String WILDCARD_NAME = "WILDCARD_PRINCIPAL_NAME"; public static final String WILDCARD_NAME = "WILDCARD_PRINCIPAL_NAME";
public static final String REPLACE_NAME = "PolicyParser.REPLACE_NAME";
String principalClass; String principalClass;
String principalName; String principalName;
/** /**
* A PrincipalEntry consists of the <code>Principal</code> * A PrincipalEntry consists of the Principal class and Principal name.
* class and <code>Principal</code> 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) { public PrincipalEntry(String principalClass, String principalName) {
if (principalClass == null || principalName == null) if (principalClass == null || principalName == null)
...@@ -975,6 +972,18 @@ public class PolicyParser { ...@@ -975,6 +972,18 @@ public class PolicyParser {
this.principalName = principalName; 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() { public String getPrincipalClass() {
return principalClass; return principalClass;
} }
...@@ -984,9 +993,9 @@ public class PolicyParser { ...@@ -984,9 +993,9 @@ public class PolicyParser {
} }
public String getDisplayClass() { public String getDisplayClass() {
if (principalClass.equals(WILDCARD_CLASS)) { if (isWildcardClass()) {
return "*"; return "*";
} else if (principalClass.equals(REPLACE_NAME)) { } else if (isReplaceName()) {
return ""; return "";
} }
else return principalClass; else return principalClass;
...@@ -997,7 +1006,7 @@ public class PolicyParser { ...@@ -997,7 +1006,7 @@ public class PolicyParser {
} }
public String getDisplayName(boolean addQuote) { public String getDisplayName(boolean addQuote) {
if (principalName.equals(WILDCARD_NAME)) { if (isWildcardName()) {
return "*"; return "*";
} }
else { else {
...@@ -1006,8 +1015,14 @@ public class PolicyParser { ...@@ -1006,8 +1015,14 @@ public class PolicyParser {
} }
} }
@Override
public String getName() {
return principalName;
}
@Override
public String toString() { public String toString() {
if (!principalClass.equals(REPLACE_NAME)) { if (!isReplaceName()) {
return getDisplayClass() + "/" + getDisplayName(); return getDisplayClass() + "/" + getDisplayName();
} else { } else {
return getDisplayName(); return getDisplayName();
...@@ -1016,15 +1031,13 @@ public class PolicyParser { ...@@ -1016,15 +1031,13 @@ public class PolicyParser {
/** /**
* Test for equality between the specified object and this object. * Test for equality between the specified object and this object.
* Two PrincipalEntries are equal if their PrincipalClass and * Two PrincipalEntries are equal if their class and name values
* PrincipalName values are equal. * 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) { public boolean equals(Object obj) {
if (this == obj) if (this == obj)
return true; return true;
...@@ -1033,27 +1046,23 @@ public class PolicyParser { ...@@ -1033,27 +1046,23 @@ public class PolicyParser {
return false; return false;
PrincipalEntry that = (PrincipalEntry)obj; PrincipalEntry that = (PrincipalEntry)obj;
if (this.principalClass.equals(that.principalClass) && return (principalClass.equals(that.principalClass) &&
this.principalName.equals(that.principalName)) { principalName.equals(that.principalName));
return true;
}
return false;
} }
/** /**
* 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() { public int hashCode() {
return principalClass.hashCode(); return principalClass.hashCode();
} }
public void write(PrintWriter out) { public void write(PrintWriter out) {
out.print("principal " + getDisplayClass() + " " + out.print("principal " + getDisplayClass() + " " +
getDisplayName(true)); getDisplayName(true));
} }
} }
...@@ -1101,6 +1110,7 @@ public class PolicyParser { ...@@ -1101,6 +1110,7 @@ public class PolicyParser {
* Calculates a hash code value for the object. Objects * Calculates a hash code value for the object. Objects
* which are equal will also have the same hashcode. * which are equal will also have the same hashcode.
*/ */
@Override
public int hashCode() { public int hashCode() {
int retval = permission.hashCode(); int retval = permission.hashCode();
if (name != null) retval ^= name.hashCode(); if (name != null) retval ^= name.hashCode();
...@@ -1108,6 +1118,7 @@ public class PolicyParser { ...@@ -1108,6 +1118,7 @@ public class PolicyParser {
return retval; return retval;
} }
@Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj == this) if (obj == this)
return true; return true;
...@@ -1210,28 +1221,18 @@ public class PolicyParser { ...@@ -1210,28 +1221,18 @@ public class PolicyParser {
i18nMessage = form.format(source); i18nMessage = form.format(source);
} }
@Override
public String getLocalizedMessage() { public String getLocalizedMessage() {
return i18nMessage; return i18nMessage;
} }
} }
public static void main(String arg[]) throws Exception { public static void main(String arg[]) throws Exception {
FileReader fr = null; try (FileReader fr = new FileReader(arg[0]);
FileWriter fw = null; FileWriter fw = new FileWriter(arg[1])) {
try {
PolicyParser pp = new PolicyParser(true); PolicyParser pp = new PolicyParser(true);
fr = new FileReader(arg[0]);
pp.read(fr); pp.read(fr);
fw = new FileWriter(arg[1]);
pp.write(fw); pp.write(fw);
} finally {
if (fr != null) {
fr.close();
}
if (fw != null) {
fw.close();
}
} }
} }
} }
...@@ -36,6 +36,7 @@ import javax.security.auth.login.LoginException; ...@@ -36,6 +36,7 @@ import javax.security.auth.login.LoginException;
import sun.security.jgss.GSSCaller; import sun.security.jgss.GSSCaller;
import sun.security.jgss.krb5.Krb5Util; import sun.security.jgss.krb5.Krb5Util;
import sun.security.jgss.krb5.ServiceCreds;
import sun.security.krb5.PrincipalName; import sun.security.krb5.PrincipalName;
import sun.security.ssl.Krb5Proxy; import sun.security.ssl.Krb5Proxy;
...@@ -62,7 +63,7 @@ public class Krb5ProxyImpl implements Krb5Proxy { ...@@ -62,7 +63,7 @@ public class Krb5ProxyImpl implements Krb5Proxy {
@Override @Override
public SecretKey[] getServerKeys(AccessControlContext acc) public SecretKey[] getServerKeys(AccessControlContext acc)
throws LoginException { throws LoginException {
Krb5Util.ServiceCreds serviceCreds = ServiceCreds serviceCreds =
Krb5Util.getServiceCreds(GSSCaller.CALLER_SSL_SERVER, null, acc); Krb5Util.getServiceCreds(GSSCaller.CALLER_SSL_SERVER, null, acc);
return serviceCreds != null ? serviceCreds.getKKeys() : return serviceCreds != null ? serviceCreds.getKKeys() :
new KerberosKey[0]; new KerberosKey[0];
......
...@@ -604,7 +604,7 @@ public class PolicyTool { ...@@ -604,7 +604,7 @@ public class PolicyTool {
InstantiationException InstantiationException
{ {
if (type.equals(PolicyParser.PrincipalEntry.WILDCARD_CLASS) || if (type.equals(PolicyParser.PrincipalEntry.WILDCARD_CLASS) ||
type.equals(PolicyParser.REPLACE_NAME)) { type.equals(PolicyParser.PrincipalEntry.REPLACE_NAME)) {
return; return;
} }
Class<?> PRIN = Class.forName("java.security.Principal"); Class<?> PRIN = Class.forName("java.security.Principal");
...@@ -2094,7 +2094,7 @@ class ToolDialog extends Dialog { ...@@ -2094,7 +2094,7 @@ class ToolDialog extends Dialog {
} else if (pclass.equals("")) { } else if (pclass.equals("")) {
// make this consistent with what PolicyParser does // make this consistent with what PolicyParser does
// when it sees an empty principal class // when it sees an empty principal class
pclass = PolicyParser.REPLACE_NAME; pclass = PolicyParser.PrincipalEntry.REPLACE_NAME;
tool.warnings.addElement( tool.warnings.addElement(
"Warning: Principal name '" + pname + "Warning: Principal name '" + pname +
"' specified without a Principal class.\n" + "' specified without a Principal class.\n" +
......
...@@ -389,11 +389,19 @@ Java_java_lang_System_initProperties(JNIEnv *env, jclass cla, jobject props) ...@@ -389,11 +389,19 @@ Java_java_lang_System_initProperties(JNIEnv *env, jclass cla, jobject props)
sprops->display_variant, sprops->format_variant, putID, getPropID); sprops->display_variant, sprops->format_variant, putID, getPropID);
GETPROP(props, "file.encoding", jVMVal); GETPROP(props, "file.encoding", jVMVal);
if (jVMVal == NULL) { 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) { if (fmtdefault) {
PUTPROP(props, "file.encoding", sprops->encoding); PUTPROP(props, "file.encoding", sprops->encoding);
} else { } else {
PUTPROP(props, "file.encoding", sprops->sun_jnu_encoding); PUTPROP(props, "file.encoding", sprops->sun_jnu_encoding);
} }
#endif
} else { } else {
(*env)->DeleteLocalRef(env, jVMVal); (*env)->DeleteLocalRef(env, jVMVal);
} }
......
...@@ -538,7 +538,12 @@ GetJavaProperties(JNIEnv *env) ...@@ -538,7 +538,12 @@ GetJavaProperties(JNIEnv *env)
sprops.display_script = sprops.script; sprops.display_script = sprops.script;
sprops.display_country = sprops.country; sprops.display_country = sprops.country;
sprops.display_variant = sprops.variant; sprops.display_variant = sprops.variant;
#ifdef MACOSX
sprops.sun_jnu_encoding = "UTF-8";
#else
sprops.sun_jnu_encoding = sprops.encoding; sprops.sun_jnu_encoding = sprops.encoding;
#endif
#ifdef _ALLBSD_SOURCE #ifdef _ALLBSD_SOURCE
#if BYTE_ORDER == _LITTLE_ENDIAN #if BYTE_ORDER == _LITTLE_ENDIAN
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -72,67 +72,97 @@ class PipeImpl ...@@ -72,67 +72,97 @@ class PipeImpl
private final SelectorProvider sp; private final SelectorProvider sp;
private IOException ioe = null;
private Initializer(SelectorProvider sp) { private Initializer(SelectorProvider sp) {
this.sp = sp; this.sp = sp;
} }
@Override
public Void run() throws IOException { public Void run() throws IOException {
ServerSocketChannel ssc = null; LoopbackConnector connector = new LoopbackConnector();
SocketChannel sc1 = null; connector.run();
SocketChannel sc2 = null; if (ioe instanceof ClosedByInterruptException) {
ioe = null;
try { Thread connThread = new Thread(connector) {
// loopback address @Override
InetAddress lb = InetAddress.getByName("127.0.0.1"); public void interrupt() {}
assert(lb.isLoopbackAddress()); };
connThread.start();
// 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
for (;;) { for (;;) {
sc2 = ssc.accept(); try {
bb.clear(); connThread.join();
sc2.read(bb);
bb.rewind();
if (bb.getLong() == secret)
break; break;
sc2.close(); } catch (InterruptedException ex) {}
} }
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;
// Create source and sink channels
source = new SourceChannelImpl(sp, sc1);
sink = new SinkChannelImpl(sp, sc2);
} catch (IOException e) {
try { try {
if (sc1 != null) // Loopback address
sc1.close(); InetAddress lb = InetAddress.getByName("127.0.0.1");
if (sc2 != null) 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(); sc2.close();
} catch (IOException e2) { } sc1.close();
IOException x = new IOException("Unable to establish" }
+ " loopback connection");
x.initCause(e); // Create source and sink channels
throw x; source = new SourceChannelImpl(sp, sc1);
} finally { sink = new SinkChannelImpl(sp, sc2);
try { } catch (IOException e) {
if (ssc != null) try {
ssc.close(); if (sc1 != null)
} catch (IOException e2) { } sc1.close();
if (sc2 != null)
sc2.close();
} catch (IOException e2) {}
ioe = e;
} finally {
try {
if (ssc != null)
ssc.close();
} catch (IOException e2) {}
}
} }
return null;
} }
} }
...@@ -144,7 +174,6 @@ class PipeImpl ...@@ -144,7 +174,6 @@ class PipeImpl
} }
} }
public SourceChannel source() { public SourceChannel source() {
return source; return source;
} }
......
########################################################################### ###########################################################################
# #
# 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. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -122,9 +122,6 @@ ...@@ -122,9 +122,6 @@
# jdk_lang # jdk_lang
# 7194607
java/lang/instrument/VerifyLocalVariableTableOnRetransformTest.sh generic-all
# 6944188 # 6944188
java/lang/management/ThreadMXBean/ThreadStateTest.java generic-all java/lang/management/ThreadMXBean/ThreadStateTest.java generic-all
...@@ -148,6 +145,9 @@ java/lang/management/MemoryMXBean/LowMemoryTest2.sh generic-all ...@@ -148,6 +145,9 @@ java/lang/management/MemoryMXBean/LowMemoryTest2.sh generic-all
# 6959636 # 6959636
javax/management/loading/LibraryLoader/LibraryLoaderTest.java windows-all javax/management/loading/LibraryLoader/LibraryLoaderTest.java windows-all
# 8005472
com/sun/jmx/remote/NotificationMarshalVersions/TestSerializationMismatch.sh windows-all
############################################################################ ############################################################################
# jdk_math # jdk_math
...@@ -238,9 +238,6 @@ java/nio/channels/AsynchronousChannelGroup/Unbounded.java windows-amd64 ...@@ -238,9 +238,6 @@ java/nio/channels/AsynchronousChannelGroup/Unbounded.java windows-amd64
# 7146541 # 7146541
java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java linux-all java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java linux-all
# 7187882
java/rmi/activation/checkusage/CheckUsage.java generic-all
# 7190106 # 7190106
java/rmi/reliability/benchmark/runRmiBench.sh generic-all java/rmi/reliability/benchmark/runRmiBench.sh generic-all
...@@ -324,6 +321,9 @@ tools/pack200/Pack200Test.java generic-all ...@@ -324,6 +321,9 @@ tools/pack200/Pack200Test.java generic-all
# 7150569 # 7150569
tools/launcher/UnicodeTest.java macosx-all tools/launcher/UnicodeTest.java macosx-all
# 8005252
tools/pack200/AttributeTests.java generic-all
############################################################################ ############################################################################
# jdk_jdi # jdk_jdi
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -40,13 +40,13 @@ import com.sun.crypto.provider.*; ...@@ -40,13 +40,13 @@ import com.sun.crypto.provider.*;
public class Test4512524 { public class Test4512524 {
private static final String ALGO = "AES"; private static final String ALGO = "AES";
private static final String MODE = "CBC";
private static final String PADDING = "NoPadding"; private static final String PADDING = "NoPadding";
private static final int KEYSIZE = 16; // in bytes 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 // TEST FIX 4512524
KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE"); KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE");
...@@ -61,17 +61,14 @@ public class Test4512524 { ...@@ -61,17 +61,14 @@ public class Test4512524 {
} }
// passed all tests...hooray! // passed all tests...hooray!
return true; System.out.println(transformation + ": Passed");
} }
public static void main (String[] args) throws Exception { public static void main (String[] args) throws Exception {
Security.addProvider(new com.sun.crypto.provider.SunJCE()); Security.addProvider(new com.sun.crypto.provider.SunJCE());
Test4512524 test = new Test4512524(); Test4512524 test = new Test4512524();
String testName = test.getClass().getName() + "[" + ALGO + test.execute("CBC");
"/" + MODE + "/" + PADDING + "]"; test.execute("GCM");
if (test.execute()) {
System.out.println(testName + ": Passed!");
}
} }
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -39,14 +39,14 @@ import com.sun.crypto.provider.*; ...@@ -39,14 +39,14 @@ import com.sun.crypto.provider.*;
public class Test4512704 { public class Test4512704 {
private static final String ALGO = "AES"; private static final String ALGO = "AES";
private static final String MODE = "CBC"; private static final String PADDING = "NoPadding";
private static final String PADDING = "PKCS5Padding";
private static final int KEYSIZE = 16; // in bytes private static final int KEYSIZE = 16; // in bytes
public boolean execute() throws Exception { public void execute(String mode) throws Exception {
AlgorithmParameterSpec aps = null;
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"); KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE");
kg.init(KEYSIZE*8); kg.init(KEYSIZE*8);
...@@ -57,19 +57,14 @@ public class Test4512704 { ...@@ -57,19 +57,14 @@ public class Test4512704 {
} catch(InvalidAlgorithmParameterException ex) { } catch(InvalidAlgorithmParameterException ex) {
throw new Exception("parameter should be generated when null is specified!"); throw new Exception("parameter should be generated when null is specified!");
} }
System.out.println(transformation + ": Passed");
// passed all tests...hooray!
return true;
} }
public static void main (String[] args) throws Exception { public static void main (String[] args) throws Exception {
Security.addProvider(new com.sun.crypto.provider.SunJCE()); Security.addProvider(new com.sun.crypto.provider.SunJCE());
Test4512704 test = new Test4512704(); Test4512704 test = new Test4512704();
String testName = test.getClass().getName() + "[" + ALGO + test.execute("CBC");
"/" + MODE + "/" + PADDING + "]"; test.execute("GCM");
if (test.execute()) {
System.out.println(testName + ": Passed!");
}
} }
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -41,16 +41,14 @@ import com.sun.crypto.provider.*; ...@@ -41,16 +41,14 @@ import com.sun.crypto.provider.*;
public class Test4517355 { public class Test4517355 {
private static final String ALGO = "AES"; 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 private static final int KEYSIZE = 16; // in bytes
public boolean execute() throws Exception { private static byte[] plainText = new byte[125];
Random rdm = new Random();
byte[] plainText=new byte[125]; public void execute(String mode, String padding) throws Exception {
rdm.nextBytes(plainText); String transformation = ALGO + "/" + mode + "/" + padding;
Cipher ci = Cipher.getInstance(ALGO+"/"+MODE+"/"+PADDING, "SunJCE"); Cipher ci = Cipher.getInstance(transformation, "SunJCE");
KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE"); KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE");
kg.init(KEYSIZE*8); kg.init(KEYSIZE*8);
SecretKey key = kg.generateKey(); SecretKey key = kg.generateKey();
...@@ -59,9 +57,14 @@ public class Test4517355 { ...@@ -59,9 +57,14 @@ public class Test4517355 {
ci.init(Cipher.ENCRYPT_MODE, key); ci.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = ci.doFinal(plainText); byte[] cipherText = ci.doFinal(plainText);
byte[] iv = ci.getIV(); if (mode.equalsIgnoreCase("GCM")) {
AlgorithmParameterSpec aps = new IvParameterSpec(iv); AlgorithmParameters params = ci.getParameters();
ci.init(Cipher.DECRYPT_MODE, key, aps); 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]; byte[] recoveredText = new byte[plainText.length];
try { try {
int len = ci.doFinal(cipherText, 0, cipherText.length, int len = ci.doFinal(cipherText, 0, cipherText.length,
...@@ -80,21 +83,22 @@ public class Test4517355 { ...@@ -80,21 +83,22 @@ public class Test4517355 {
throw new Exception("encryption does not work!"); throw new Exception("encryption does not work!");
} }
// 3. make sure padding is working // 3. make sure padding is working
if ((cipherText.length/16)*16 != cipherText.length) { if (padding.equalsIgnoreCase("PKCS5Padding")) {
throw new Exception("padding does not work!"); if ((cipherText.length/16)*16 != cipherText.length) {
throw new Exception("padding does not work!");
}
} }
// passed all tests...hooray! System.out.println(transformation + ": Passed");
return true;
} }
public static void main (String[] args) throws Exception { public static void main (String[] args) throws Exception {
Security.addProvider(new com.sun.crypto.provider.SunJCE()); Security.addProvider(new com.sun.crypto.provider.SunJCE());
Test4517355 test = new Test4517355(); Test4517355 test = new Test4517355();
String testName = test.getClass().getName() + "[" + ALGO + Random rdm = new Random();
"/" + MODE + "/" + PADDING + "]"; rdm.nextBytes(test.plainText);
if (test.execute()) {
System.out.println(testName + ": Passed!"); test.execute("CBC", "PKCS5Padding");
} test.execute("GCM", "NoPadding");
} }
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -34,13 +34,11 @@ import java.util.*; ...@@ -34,13 +34,11 @@ import java.util.*;
public class Test4626070 { public class Test4626070 {
private static final String ALGO = "AES"; 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 private static final int KEYSIZE = 16; // in bytes
public boolean execute() throws Exception { public void execute(String mode, String padding) throws Exception {
String transformation = ALGO + "/" + mode + "/" + padding;
Cipher ci = Cipher.getInstance(ALGO+"/"+MODE+"/"+PADDING, "SunJCE"); Cipher ci = Cipher.getInstance(transformation, "SunJCE");
KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE"); KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE");
kg.init(KEYSIZE*8); kg.init(KEYSIZE*8);
SecretKey key = kg.generateKey(); SecretKey key = kg.generateKey();
...@@ -58,18 +56,14 @@ public class Test4626070 { ...@@ -58,18 +56,14 @@ public class Test4626070 {
throw new Exception( throw new Exception(
"key after wrap/unwrap is different from the original!"); "key after wrap/unwrap is different from the original!");
} }
// passed all tests...hooray! System.out.println(transformation + ": Passed");
return true;
} }
public static void main (String[] args) throws Exception { public static void main (String[] args) throws Exception {
Security.addProvider(new com.sun.crypto.provider.SunJCE()); Security.addProvider(new com.sun.crypto.provider.SunJCE());
Test4626070 test = new Test4626070(); Test4626070 test = new Test4626070();
String testName = test.getClass().getName() + "[" + ALGO + test.execute("CBC", "PKCS5Padding");
"/" + MODE + "/" + PADDING + "]"; test.execute("GCM", "NoPadding");
if (test.execute()) {
System.out.println(testName + ": Passed!");
}
} }
} }
/*
* 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();
}
}
/*
* 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 { ...@@ -135,24 +135,19 @@ public class WinCommand {
// Win9x systems don't have a cmd.exe // Win9x systems don't have a cmd.exe
if (new File(systemDirW, "cmd.exe").exists()) { if (new File(systemDirW, "cmd.exe").exists()) {
try { out.println("Running cmd.exe tests...");
out.println("Running cmd.exe tests..."); writeFile("cdcmd.cmd", "@echo off\r\nCD\r\n");
writeFile("cdcmd.cmd", "@echo off\r\nCD\r\n"); writeFile("cdbat.bat", "@echo off\r\nCD\r\n");
writeFile("cdbat.bat", "@echo off\r\nCD\r\n"); checkCD("cmd",
checkCD("cmd", "cmd.exe",
"cmd.exe", systemDirW + "\\cmd.exe",
systemDirW + "\\cmd.exe", // Only the ".exe" extension can be omitted
// Only the ".exe" extension can be omitted systemDirW + "\\cmd",
systemDirW + "\\cmd", systemDirM + "/cmd.exe",
systemDirM + "/cmd.exe", systemDirM + "/cmd",
systemDirM + "/cmd", "/" + systemDirM + "/cmd",
"/" + systemDirM + "/cmd", "cdcmd.cmd", "./cdcmd.cmd", ".\\cdcmd.cmd",
"cdcmd.cmd", "./cdcmd.cmd", ".\\cdcmd.cmd", "cdbat.bat", "./cdbat.bat", ".\\cdbat.bat");
"cdbat.bat", "./cdbat.bat", ".\\cdbat.bat");
} finally {
new File("cdcmd.cmd").delete();
new File("cdbat.bat").delete();
}
} }
// 16-bit apps like command.com must have a console; // 16-bit apps like command.com must have a console;
......
/*
* 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");
}
}
}
#!/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 @@ ...@@ -26,6 +26,7 @@
* @bug 4727547 * @bug 4727547
* @summary SocksSocketImpl throws NullPointerException * @summary SocksSocketImpl throws NullPointerException
* @build SocksServer * @build SocksServer
* @run main SocksV4Test
*/ */
import java.net.*; import java.net.*;
......
/*
* 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;
}
}
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -168,7 +168,7 @@ public class ShutdownGracefully ...@@ -168,7 +168,7 @@ public class ShutdownGracefully
registering = null; registering = null;
// Need to make sure that rmid goes away by itself // Need to make sure that rmid goes away by itself
Process rmidProcess = rmid.getVM(); JavaVM rmidProcess = rmid;
if (rmidProcess != null) { if (rmidProcess != null) {
try { try {
Runnable waitThread = Runnable waitThread =
...@@ -205,9 +205,9 @@ public class ShutdownGracefully ...@@ -205,9 +205,9 @@ public class ShutdownGracefully
* class that waits for rmid to exit * class that waits for rmid to exit
*/ */
private static class ShutdownDetectThread implements Runnable { private static class ShutdownDetectThread implements Runnable {
private Process rmidProcess = null; private JavaVM rmidProcess = null;
ShutdownDetectThread(Process rmidProcess) { ShutdownDetectThread(JavaVM rmidProcess) {
this.rmidProcess = rmidProcess; this.rmidProcess = rmidProcess;
} }
public void run() { public void run() {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
/* @test /* @test
* @bug 4259564 * @bug 4259564
* @summary RMID's usage message is incomplete and inconsistent with other tools
* *
* @library ../../testlibrary * @library ../../testlibrary
* @build TestLibrary JavaVM * @build TestLibrary JavaVM
...@@ -37,23 +38,16 @@ import java.io.ByteArrayOutputStream; ...@@ -37,23 +38,16 @@ import java.io.ByteArrayOutputStream;
*/ */
public class CheckUsage { public class CheckUsage {
public static void main(String[] args) { public static void main(String[] args) {
System.err.println("\nregression test for 4259564\n");
JavaVM rmidVM = null;
try { try {
// make sure the registry exits with a proper usage statement
ByteArrayOutputStream berr = new ByteArrayOutputStream(); ByteArrayOutputStream berr = new ByteArrayOutputStream();
// run a VM to start the registry // create rmid with incorrect command line args
rmidVM = new JavaVM("sun.rmi.server.Activation", "", "foo", JavaVM rmidVM = new JavaVM("sun.rmi.server.Activation", "", "foo",
System.out, berr); System.out, berr);
System.err.println("starting rmid"); System.err.println("starting rmid");
rmidVM.start();
// wait for registry exit // run the subprocess and wait for it to exit
int rmidVMExitStatus = rmidVM.getVM().waitFor(); int rmidVMExitStatus = rmidVM.execute();
System.err.println("rmid exited with status: " + System.err.println("rmid exited with status: " +
rmidVMExitStatus); rmidVMExitStatus);
...@@ -66,12 +60,8 @@ public class CheckUsage { ...@@ -66,12 +60,8 @@ public class CheckUsage {
} else { } else {
System.err.println("test passed"); System.err.println("test passed");
} }
} catch (Exception e) { } catch (Exception e) {
TestLibrary.bomb(e); TestLibrary.bomb(e);
} finally {
rmidVM.destroy();
rmidVM = null;
} }
} }
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -76,8 +76,7 @@ public class AltSecurityManager implements Runnable { ...@@ -76,8 +76,7 @@ public class AltSecurityManager implements Runnable {
} }
System.err.println("starting " + utilityToStart); System.err.println("starting " + utilityToStart);
vm.start(); vm.execute();
vm.getVM().waitFor();
} catch (Exception e) { } catch (Exception e) {
TestLibrary.bomb(e); TestLibrary.bomb(e);
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -35,34 +35,21 @@ import java.io.ByteArrayOutputStream; ...@@ -35,34 +35,21 @@ import java.io.ByteArrayOutputStream;
/** /**
* Make sure that the rmiregistry prints out a correct usage statement * Make sure that the rmiregistry prints out a correct usage statement
* when run with an incorrect command line; test written to conform to * when run with an incorrect command line.
* new tighter bug fix/regression test guidelines.
*/ */
public class CheckUsage { public class CheckUsage {
public static void main(String[] args) { public static void main(String[] args) {
System.err.println("\nregression test for 4151966\n");
JavaVM registryVM = null;
try { try {
// make sure the registry exits with a proper usage statement
ByteArrayOutputStream berr = new ByteArrayOutputStream(); ByteArrayOutputStream berr = new ByteArrayOutputStream();
// run a VM to start the registry // run a VM to start the registry
registryVM = new JavaVM("sun.rmi.registry.RegistryImpl", JavaVM registryVM = new JavaVM("sun.rmi.registry.RegistryImpl",
"", "foo", "", "foo",
System.out, berr); System.out, berr);
System.err.println("starting registry"); System.err.println("starting registry");
registryVM.start();
// wait for registry exit
System.err.println(" registry exited with status: " + System.err.println(" registry exited with status: " +
registryVM.getVM().waitFor()); registryVM.execute());
try {
Thread.sleep(7000);
} catch (InterruptedException ie) {
}
String usage = new String(berr.toByteArray()); String usage = new String(berr.toByteArray());
...@@ -75,9 +62,6 @@ public class CheckUsage { ...@@ -75,9 +62,6 @@ public class CheckUsage {
} }
} catch (Exception e) { } catch (Exception e) {
TestLibrary.bomb(e); TestLibrary.bomb(e);
} finally {
registryVM.destroy();
registryVM = null;
} }
} }
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -122,8 +122,7 @@ public class Reexport { ...@@ -122,8 +122,7 @@ public class Reexport {
try { try {
JavaVM jvm = new JavaVM("RegistryRunner", "", Integer.toString(p)); JavaVM jvm = new JavaVM("RegistryRunner", "", Integer.toString(p));
jvm.start(); jvm.start();
Reexport.subreg = jvm.getVM(); Reexport.subreg = jvm;
} catch (IOException e) { } catch (IOException e) {
// one of these is summarily dropped, can't remember which one // one of these is summarily dropped, can't remember which one
System.out.println ("Test setup failed - cannot run rmiregistry"); System.out.println ("Test setup failed - cannot run rmiregistry");
...@@ -135,7 +134,8 @@ public class Reexport { ...@@ -135,7 +134,8 @@ public class Reexport {
} catch (Exception whatever) { } catch (Exception whatever) {
} }
} }
private static Process subreg = null;
private static JavaVM subreg = null;
public static void killRegistry(int port) { public static void killRegistry(int port) {
if (Reexport.subreg != null) { if (Reexport.subreg != null) {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -41,6 +41,8 @@ public class JavaVM { ...@@ -41,6 +41,8 @@ public class JavaVM {
private OutputStream outputStream = System.out; private OutputStream outputStream = System.out;
private OutputStream errorStream = System.err; private OutputStream errorStream = System.err;
private String policyFileName = null; private String policyFileName = null;
private StreamPipe outPipe;
private StreamPipe errPipe;
private static void mesg(Object mesg) { private static void mesg(Object mesg) {
System.err.println("JAVAVM: " + mesg.toString()); System.err.println("JAVAVM: " + mesg.toString());
...@@ -145,13 +147,12 @@ public class JavaVM { ...@@ -145,13 +147,12 @@ public class JavaVM {
} }
mesg("command = " + Arrays.asList(javaCommand).toString()); mesg("command = " + Arrays.asList(javaCommand).toString());
System.err.println("");
vm = Runtime.getRuntime().exec(javaCommand); vm = Runtime.getRuntime().exec(javaCommand);
/* output from the execed process may optionally be captured. */ /* output from the execed process may optionally be captured. */
StreamPipe.plugTogether(vm.getInputStream(), this.outputStream); outPipe = StreamPipe.plugTogether(vm.getInputStream(), this.outputStream);
StreamPipe.plugTogether(vm.getErrorStream(), this.errorStream); errPipe = StreamPipe.plugTogether(vm.getErrorStream(), this.errorStream);
} }
public void destroy() { public void destroy() {
...@@ -161,7 +162,25 @@ public class JavaVM { ...@@ -161,7 +162,25 @@ public class JavaVM {
vm = null; 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();
} }
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -202,8 +202,6 @@ public class RMID extends JavaVM { ...@@ -202,8 +202,6 @@ public class RMID extends JavaVM {
public void start(long waitTime) throws IOException { public void start(long waitTime) throws IOException {
if (getVM() != null) return;
// if rmid is already running, then the test will fail with // if rmid is already running, then the test will fail with
// a well recognized exception (port already in use...). // a well recognized exception (port already in use...).
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -114,6 +114,7 @@ public class CheckFQDN extends UnicastRemoteObject ...@@ -114,6 +114,7 @@ public class CheckFQDN extends UnicastRemoteObject
equal = "="; equal = "=";
} }
// create a client to tell checkFQDN what its rmi name is.
JavaVM jvm = new JavaVM("CheckFQDNClient", JavaVM jvm = new JavaVM("CheckFQDNClient",
propOption + property + propOption + property +
equal + equal +
...@@ -125,10 +126,7 @@ public class CheckFQDN extends UnicastRemoteObject ...@@ -125,10 +126,7 @@ public class CheckFQDN extends UnicastRemoteObject
propertyBeingTested=property; propertyBeingTested=property;
propertyBeingTestedValue=propertyValue; propertyBeingTestedValue=propertyValue;
// create a client to tell checkFQDN what its rmi name is. */ if (jvm.execute() != 0) {
jvm.start();
if (jvm.getVM().waitFor() != 0 ) {
TestLibrary.bomb("Test failed, error in client."); TestLibrary.bomb("Test failed, error in client.");
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -102,9 +102,8 @@ public class CheckLeaseLeak extends UnicastRemoteObject implements LeaseLeak { ...@@ -102,9 +102,8 @@ public class CheckLeaseLeak extends UnicastRemoteObject implements LeaseLeak {
" -Drmi.registry.port=" + " -Drmi.registry.port=" +
registryPort, registryPort,
""); "");
jvm.start();
if (jvm.getVM().waitFor() == 1 ) { if (jvm.execute() != 0) {
TestLibrary.bomb("Client process failed"); TestLibrary.bomb("Client process failed");
} }
} }
......
/*
* 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");
}
}
}
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -78,6 +78,8 @@ public class GCMAPI { ...@@ -78,6 +78,8 @@ public class GCMAPI {
c.updateAAD(src); c.updateAAD(src);
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {
// swallow // swallow
} catch (IllegalStateException ise) {
// swallow
}catch (Exception e) { }catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
failed++; failed++;
...@@ -99,6 +101,8 @@ public class GCMAPI { ...@@ -99,6 +101,8 @@ public class GCMAPI {
c.updateAAD(src, offset, len); c.updateAAD(src, offset, len);
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {
// swallow // swallow
} catch (IllegalStateException ise) {
// swallow
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
failed++; failed++;
...@@ -120,6 +124,8 @@ public class GCMAPI { ...@@ -120,6 +124,8 @@ public class GCMAPI {
c.updateAAD(src); c.updateAAD(src);
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {
// swallow // swallow
} catch (IllegalStateException ise) {
// swallow
}catch (Exception e) { }catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
failed++; failed++;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -48,8 +48,7 @@ public class Test4504153 { ...@@ -48,8 +48,7 @@ public class Test4504153 {
ByteArrayOutputStream err = new ByteArrayOutputStream(); ByteArrayOutputStream err = new ByteArrayOutputStream();
JavaVM vm = new JavaVM(StartRegistry.class.getName(), JavaVM vm = new JavaVM(StartRegistry.class.getName(),
"-Dsun.rmi.transport.logLevel=v", "", out, err); "-Dsun.rmi.transport.logLevel=v", "", out, err);
vm.start(); vm.execute();
vm.getVM().waitFor();
String errString = err.toString(); String errString = err.toString();
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -65,8 +65,7 @@ public class NoConsoleOutput { ...@@ -65,8 +65,7 @@ public class NoConsoleOutput {
JavaVM vm = new JavaVM(DoRMIStuff.class.getName(), JavaVM vm = new JavaVM(DoRMIStuff.class.getName(),
"-Djava.util.logging.config.file=" + loggingPropertiesFile, "-Djava.util.logging.config.file=" + loggingPropertiesFile,
"", out, err); "", out, err);
vm.start(); vm.execute();
vm.getVM().waitFor();
/* /*
* Verify that the subprocess had no System.out or System.err * Verify that the subprocess had no System.out or System.err
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -104,7 +104,7 @@ public class DeadCachedConnection { ...@@ -104,7 +104,7 @@ public class DeadCachedConnection {
JavaVM jvm = JavaVM jvm =
new JavaVM("sun.rmi.registry.RegistryImpl", "", Integer.toString(p)); new JavaVM("sun.rmi.registry.RegistryImpl", "", Integer.toString(p));
jvm.start(); jvm.start();
DeadCachedConnection.subreg = jvm.getVM(); DeadCachedConnection.subreg = jvm;
} catch (IOException e) { } catch (IOException e) {
// one of these is summarily dropped, can't remember which one // one of these is summarily dropped, can't remember which one
...@@ -117,7 +117,7 @@ public class DeadCachedConnection { ...@@ -117,7 +117,7 @@ public class DeadCachedConnection {
} catch (Exception whatever) { } catch (Exception whatever) {
} }
} }
private static Process subreg = null; private static JavaVM subreg = null;
public static void killRegistry() { public static void killRegistry() {
if (DeadCachedConnection.subreg != null) { if (DeadCachedConnection.subreg != null) {
......
/*
* 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 8005447
* @compile -XDignore.symbol.file ServiceCredsCombination.java
* @run main ServiceCredsCombination
* @summary default principal can act as anyone
*/
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Objects;
import javax.security.auth.Subject;
import javax.security.auth.kerberos.KerberosKey;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.kerberos.KeyTab;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import sun.security.jgss.GSSUtil;
public class ServiceCredsCombination {
public static void main(String[] args) throws Exception {
// pass
check("a", "a", princ("a"), key("a"));
check(null, "a", princ("a"), key("a"));
check("x", "NOCRED", princ("a"), key("a"));
// two pass
check("a", "a", princ("a"), key("a"), princ("b"), key("b"));
check("b", "b", princ("a"), key("a"), princ("b"), key("b"));
check(null, null, princ("a"), key("a"), princ("b"), key("b"));
check("x", "NOCRED", princ("a"), key("a"), princ("b"), key("b"));
// old ktab
check("b", "b", princ("b"), oldktab());
check("x", "NOCRED", princ("b"), oldktab());
check(null, "b", princ("b"), oldktab());
// Two old ktab
check("a", "a", princ("a"), princ("b"), oldktab(), oldktab());
check("b", "b", princ("a"), princ("b"), oldktab(), oldktab());
check(null, null, princ("a"), princ("b"), oldktab(), oldktab());
check("x", "NOCRED", princ("a"), princ("b"), oldktab(), oldktab());
// pass + old ktab
check("a", "a", princ("a"), princ("b"), key("a"), oldktab());
check("b", "b", princ("a"), princ("b"), key("a"), oldktab());
check(null, null, princ("a"), princ("b"), key("a"), oldktab());
check("x", "NOCRED", princ("a"), princ("b"), key("a"), oldktab());
// Compatibility, automatically add princ for keys
check(null, "a", key("a"));
check("x", "NOCRED", key("a"));
check(null, "a", key("a"), oldktab());
check("x", "NOCRED", key("a"), oldktab());
// Limitation, "a" has no key, but we don't know oldktab() is for "b"
check("a", "a", princ("a"), princ("b"), oldktab());
}
/**
* Checks the correct bound
* @param a get a creds for this principal, null for default one
* @param b expected name, null for still unbound, "NOCRED" for no creds
* @param objs princs, keys and keytabs in the subject
*/
private static void check(final String a, String b, Object... objs)
throws Exception {
Subject subj = new Subject();
for (Object obj: objs) {
if (obj instanceof KerberosPrincipal) {
subj.getPrincipals().add((KerberosPrincipal)obj);
} else if (obj instanceof KerberosKey || obj instanceof KeyTab) {
subj.getPrivateCredentials().add(obj);
}
}
final GSSManager man = GSSManager.getInstance();
try {
String result = Subject.doAs(
subj, new PrivilegedExceptionAction<String>() {
@Override
public String run() throws GSSException {
GSSCredential cred = man.createCredential(
a == null ? null : man.createName(r(a), null),
GSSCredential.INDEFINITE_LIFETIME,
GSSUtil.GSS_KRB5_MECH_OID,
GSSCredential.ACCEPT_ONLY);
GSSName name = cred.getName();
return name == null ? null : name.toString();
}
});
if (!Objects.equals(result, r(b))) {
throw new Exception("Check failed: getInstance(" + a
+ ") has name " + result + ", not " + b);
}
} catch (PrivilegedActionException e) {
if (!"NOCRED".equals(b)) {
throw new Exception("Check failed: getInstance(" + a
+ ") is null " + ", but not one with name " + b);
}
}
}
private static String r(String s) {
return s == null ? null : (s+"@REALM");
}
private static KerberosPrincipal princ(String s) {
return new KerberosPrincipal(r(s));
}
private static KerberosKey key(String s) {
return new KerberosKey(princ(s), new byte[0], 0, 0);
}
private static KeyTab oldktab() {
return KeyTab.getInstance();
}
}
/*
* 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 9999999
* @summary default principal can act as anyone
* @compile -XDignore.symbol.file AcceptPermissions.java
* @run main/othervm AcceptPermissions
*/
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.Permission;
import javax.security.auth.kerberos.ServicePermission;
import sun.security.jgss.GSSUtil;
import java.util.*;
public class AcceptPermissions extends SecurityManager {
private static Map<Permission,String> perms = new HashMap<>();
@Override
public void checkPermission(Permission perm) {
if (!(perm instanceof ServicePermission)) {
return;
}
ServicePermission sp = (ServicePermission)perm;
if (!sp.getActions().equals("accept")) {
return;
}
// We only care about accept ServicePermission in this test
try {
super.checkPermission(sp);
} catch (SecurityException se) {
if (perms.containsKey(sp)) {
perms.put(sp, "checked");
} else {
throw se; // We didn't expect this is needed
}
}
}
// Fills in permissions we are expecting
private static void initPerms(String... names) {
perms.clear();
for (String name: names) {
perms.put(new ServicePermission(
name + "@" + OneKDC.REALM, "accept"), "expected");
}
}
// Checks if they are all checked
private static void checkPerms() {
for (Map.Entry<Permission,String> entry: perms.entrySet()) {
if (entry.getValue().equals("expected")) {
throw new RuntimeException(
"Expected but not used: " + entry.getKey());
}
}
}
public static void main(String[] args) throws Exception {
System.setSecurityManager(new AcceptPermissions());
new OneKDC(null).writeJAASConf();
String two = "two {\n"
+ " com.sun.security.auth.module.Krb5LoginModule required"
+ " principal=\"" + OneKDC.SERVER + "\" useKeyTab=true"
+ " isInitiator=false storeKey=true;\n"
+ " com.sun.security.auth.module.Krb5LoginModule required"
+ " principal=\"" + OneKDC.BACKEND + "\" useKeyTab=true"
+ " isInitiator=false storeKey=true;\n"
+ "};\n";
Files.write(Paths.get(OneKDC.JAAS_CONF), two.getBytes(),
StandardOpenOption.APPEND);
Context c, s;
// In all cases, a ServicePermission on the acceptor name is needed
// for a handshake. For default principal with no predictable name,
// permission not needed (yet) for credentials creation.
// Named principal
initPerms(OneKDC.SERVER);
c = Context.fromJAAS("client");
s = Context.fromJAAS("server");
c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
s.startAsServer(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
checkPerms();
initPerms(OneKDC.SERVER);
Context.handshake(c, s);
checkPerms();
// Named principal (even if there are 2 JAAS modules)
initPerms(OneKDC.SERVER);
c = Context.fromJAAS("client");
s = Context.fromJAAS("two");
c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
s.startAsServer(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
checkPerms();
initPerms(OneKDC.SERVER);
Context.handshake(c, s);
checkPerms();
// Default principal with a predictable name
initPerms(OneKDC.SERVER);
c = Context.fromJAAS("client");
s = Context.fromJAAS("server");
c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
checkPerms();
initPerms(OneKDC.SERVER);
Context.handshake(c, s);
checkPerms();
// Default principal with no predictable name
initPerms(); // permission not needed for cred !!!
c = Context.fromJAAS("client");
s = Context.fromJAAS("two");
c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
checkPerms();
initPerms(OneKDC.SERVER); // still needed for handshake !!!
Context.handshake(c, s);
checkPerms();
}
}
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
/* /*
* @test * @test
* @bug 6716534 * @bug 6716534
* @compile -XDignore.symbol.file CleanState.java
* @run main/othervm CleanState * @run main/othervm CleanState
* @summary Krb5LoginModule has not cleaned temp info between authentication attempts * @summary Krb5LoginModule has not cleaned temp info between authentication attempts
*/ */
......
...@@ -131,21 +131,24 @@ public class Context { ...@@ -131,21 +131,24 @@ public class Context {
return out; return out;
} }
/**
* Logins with username/password as a new Subject
*/
public static Context fromUserPass( public static Context fromUserPass(
String user, char[] pass, boolean storeKey) throws Exception { String user, char[] pass, boolean storeKey) throws Exception {
return fromUserPass(null, user, pass, storeKey); return fromUserPass(new Subject(), user, pass, storeKey);
} }
/** /**
* Logins with a username and a password, using Krb5LoginModule directly * Logins with username/password as an existing Subject. The
* @param s existing subject, test multiple princ & creds for single subj * same subject can be used multiple times to simulate multiple logins.
* @param storeKey true if key should be saved, used on acceptor side * @param s existing subject
*/ */
public static Context fromUserPass(Subject s, public static Context fromUserPass(Subject s,
String user, char[] pass, boolean storeKey) throws Exception { String user, char[] pass, boolean storeKey) throws Exception {
Context out = new Context(); Context out = new Context();
out.name = user; out.name = user;
out.s = s == null ? new Subject() : s; out.s = s;
Krb5LoginModule krb5 = new Krb5LoginModule(); Krb5LoginModule krb5 = new Krb5LoginModule();
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
Map<String, Object> shared = new HashMap<>(); Map<String, Object> shared = new HashMap<>();
...@@ -172,14 +175,23 @@ public class Context { ...@@ -172,14 +175,23 @@ public class Context {
} }
/** /**
* Logins with a username and a keytab, using Krb5LoginModule directly * Logins with username/keytab as an existing Subject. The
* @param storeKey true if key should be saved, used on acceptor side * same subject can be used multiple times to simulate multiple logins.
* @param s existing subject
*/ */
public static Context fromUserKtab(String user, String ktab, boolean storeKey) public static Context fromUserKtab(
throws Exception { String user, String ktab, boolean storeKey) throws Exception {
return fromUserKtab(new Subject(), user, ktab, storeKey);
}
/**
* Logins with username/keytab as a new subject,
*/
public static Context fromUserKtab(Subject s,
String user, String ktab, boolean storeKey) throws Exception {
Context out = new Context(); Context out = new Context();
out.name = user; out.name = user;
out.s = new Subject(); out.s = s;
Krb5LoginModule krb5 = new Krb5LoginModule(); Krb5LoginModule krb5 = new Krb5LoginModule();
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
......
/*
* 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 8005447
* @summary default principal can act as anyone
* @compile -XDignore.symbol.file DiffNameSameKey.java
* @run main/othervm/fail DiffNameSameKey a
* @run main/othervm DiffNameSameKey b
*/
import sun.security.jgss.GSSUtil;
import sun.security.krb5.PrincipalName;
/**
* This test confirms the compatibility codes described in
* ServiceCreds.getEKeys(). If the acceptor starts as x.us.oracle.com
* but client requests for x.us, as long as the KDC supports both names
* and the keys are the same, the auth should succeed.
*/
public class DiffNameSameKey {
static final String SERVER2 = "x" + OneKDC.SERVER;
public static void main(String[] args) throws Exception {
OneKDC kdc = new KDC2();
kdc.addPrincipal(SERVER2, "samepass".toCharArray());
kdc.addPrincipal(OneKDC.SERVER, "samepass".toCharArray());
kdc.writeJAASConf();
kdc.writeKtab(OneKDC.KTAB);
Context c, s;
c = Context.fromJAAS("client");
s = Context.fromJAAS("server");
switch (args[0]) {
case "a": // If server starts as another service, should fail
c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_SPNEGO_MECH_OID);
s.startAsServer(SERVER2.replace('/', '@'),
GSSUtil.GSS_SPNEGO_MECH_OID);
break;
case "b": // If client requests another server with the same keys,
// succeed to be compatible
c.startAsClient(SERVER2, GSSUtil.GSS_SPNEGO_MECH_OID);
s.startAsServer(OneKDC.SERVER.replace('/', '@'),
GSSUtil.GSS_SPNEGO_MECH_OID);
break;
}
Context.handshake(c, s);
s.dispose();
c.dispose();
}
/**
* This KDC returns the same salt for all principals. This means same
* passwords generate same keys.
*/
static class KDC2 extends OneKDC {
KDC2() throws Exception {
super(null);
}
@Override
public String getSalt(PrincipalName pn) {
return "SAME";
}
}
}
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
/* /*
* @test * @test
* @bug 6894072 * @bug 6894072
* @compile -XDignore.symbol.file DynamicKeytab.java
* @run main/othervm DynamicKeytab * @run main/othervm DynamicKeytab
* @summary always refresh keytab * @summary always refresh keytab
*/ */
......
...@@ -285,10 +285,12 @@ public class KDC { ...@@ -285,10 +285,12 @@ public class KDC {
if (Character.isDigit(pass[pass.length-1])) { if (Character.isDigit(pass[pass.length-1])) {
kvno = pass[pass.length-1] - '0'; kvno = pass[pass.length-1] - '0';
} }
ktab.addEntry(new PrincipalName(name, PrincipalName pn = new PrincipalName(name,
name.indexOf('/') < 0 ? name.indexOf('/') < 0 ?
PrincipalName.KRB_NT_UNKNOWN : PrincipalName.KRB_NT_UNKNOWN :
PrincipalName.KRB_NT_SRV_HST), PrincipalName.KRB_NT_SRV_HST);
ktab.addEntry(pn,
getSalt(pn),
pass, pass,
kvno, kvno,
true); true);
...@@ -534,7 +536,7 @@ public class KDC { ...@@ -534,7 +536,7 @@ public class KDC {
if (pass == null) { if (pass == null) {
throw new KrbException(server? throw new KrbException(server?
Krb5.KDC_ERR_S_PRINCIPAL_UNKNOWN: Krb5.KDC_ERR_S_PRINCIPAL_UNKNOWN:
Krb5.KDC_ERR_C_PRINCIPAL_UNKNOWN); Krb5.KDC_ERR_C_PRINCIPAL_UNKNOWN, pn.toString());
} }
return pass; return pass;
} }
...@@ -544,7 +546,7 @@ public class KDC { ...@@ -544,7 +546,7 @@ public class KDC {
* @param p principal * @param p principal
* @return the salt * @return the salt
*/ */
private String getSalt(PrincipalName p) { protected String getSalt(PrincipalName p) {
String pn = p.toString(); String pn = p.toString();
if (p.getRealmString() == null) { if (p.getRealmString() == null) {
pn = pn + "@" + getRealm(); pn = pn + "@" + getRealm();
......
...@@ -38,7 +38,7 @@ import sun.security.jgss.GSSUtil; ...@@ -38,7 +38,7 @@ import sun.security.jgss.GSSUtil;
* *
* 1. If there is only KerberosKeys in private credential set and no * 1. If there is only KerberosKeys in private credential set and no
* KerberosPrincipal. JAAS login should go on. * KerberosPrincipal. JAAS login should go on.
* 2. Even if KeyTab is used, user can still get KerberosKeys from * 2. If KeyTab is used, user won't get KerberosKeys from
* private credentials set. * private credentials set.
*/ */
public class KeyTabCompat { public class KeyTabCompat {
......
/*
* 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 8005447
* @summary default principal can act as anyone
* @compile -XDignore.symbol.file TwoOrThree.java
* @run main/othervm TwoOrThree first first
* @run main/othervm/fail TwoOrThree first second
* @run main/othervm TwoOrThree - first
* @run main/othervm TwoOrThree - second
* @run main/othervm/fail TwoOrThree - third
*/
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import javax.security.auth.Subject;
import sun.security.jgss.GSSUtil;
/*
* The JAAS login has two krb5 modules
* 1. principal is A
* 2. principal is B
* A named principal can only accept itself. The default principal can accept
* either, but not any other service even if the keytab also include its keys.
*/
public class TwoOrThree {
public static void main(String[] args) throws Exception {
String server = args[0].equals("-") ? null : args[0];
String target = args[1];
OneKDC kdc = new OneKDC(null);
kdc.addPrincipal("first", "first".toCharArray());
kdc.addPrincipal("second", "second".toCharArray());
kdc.addPrincipal("third", "third".toCharArray());
kdc.writeKtab(OneKDC.KTAB);
Context c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
// Using keytabs
Subject sub4s = new Subject();
Context.fromUserKtab(sub4s, "first", OneKDC.KTAB, true);
Context s = Context.fromUserKtab(sub4s, "second", OneKDC.KTAB, true);
c.startAsClient(target, GSSUtil.GSS_KRB5_MECH_OID);
s.startAsServer(server, GSSUtil.GSS_KRB5_MECH_OID);
Context.handshake(c, s);
// Using keys
sub4s = new Subject();
Context.fromUserPass(sub4s, "first", "first".toCharArray(), true);
s = Context.fromUserPass(sub4s, "second", "second".toCharArray(), true);
c.startAsClient(target, GSSUtil.GSS_KRB5_MECH_OID);
s.startAsServer(server, GSSUtil.GSS_KRB5_MECH_OID);
Context.handshake(c, s);
s.dispose();
c.dispose();
}
}
/* /*
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -39,7 +39,6 @@ import javax.security.auth.Subject; ...@@ -39,7 +39,6 @@ import javax.security.auth.Subject;
import javax.security.auth.x500.X500Principal; import javax.security.auth.x500.X500Principal;
import sun.security.provider.PolicyFile; import sun.security.provider.PolicyFile;
import com.sun.security.auth.PrincipalComparator;
import com.sun.security.auth.UnixPrincipal; import com.sun.security.auth.UnixPrincipal;
import com.sun.security.auth.NTUserPrincipal; import com.sun.security.auth.NTUserPrincipal;
import com.sun.security.auth.SolarisPrincipal; import com.sun.security.auth.SolarisPrincipal;
...@@ -90,7 +89,7 @@ public class Comparator { ...@@ -90,7 +89,7 @@ public class Comparator {
private static final Principal[] badP = new Principal[] { private static final Principal[] badP = new Principal[] {
new SolarisPrincipal("bad") }; new SolarisPrincipal("bad") };
public static class PCompare1 implements PrincipalComparator { public static class PCompare1 implements Principal {
private String name; private String name;
...@@ -98,6 +97,12 @@ public class Comparator { ...@@ -98,6 +97,12 @@ public class Comparator {
this.name = name; this.name = name;
} }
@Override
public String getName() {
return name;
}
@Override
public boolean implies (Subject subject) { public boolean implies (Subject subject) {
if (subject.getPrincipals().contains(p1[0])) { if (subject.getPrincipals().contains(p1[0])) {
return true; return true;
...@@ -106,13 +111,19 @@ public class Comparator { ...@@ -106,13 +111,19 @@ public class Comparator {
} }
} }
public static class PCompare2 implements PrincipalComparator { public static class PCompare2 implements Principal {
private String name; private String name;
public PCompare2(String name) { public PCompare2(String name) {
this.name = name; this.name = name;
} }
@Override
public String getName() {
return name;
}
@Override
public boolean implies (Subject subject) { public boolean implies (Subject subject) {
if (subject.getPrincipals().contains(p2[0]) && if (subject.getPrincipals().contains(p2[0]) &&
subject.getPrincipals().contains(p2[1])) { subject.getPrincipals().contains(p2[1])) {
...@@ -122,13 +133,19 @@ public class Comparator { ...@@ -122,13 +133,19 @@ public class Comparator {
} }
} }
public static class PCompare3 implements PrincipalComparator { public static class PCompare3 implements Principal {
private String name; private String name;
public PCompare3(String name) { public PCompare3(String name) {
this.name = name; this.name = name;
} }
@Override
public String getName() {
return name;
}
@Override
public boolean implies (Subject subject) { public boolean implies (Subject subject) {
return false; return false;
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 8001533 * @bug 8001533 8004547
* @summary Test launching FX application with java -jar * @summary Test launching FX application with java -jar
* Test uses main method and blank main method, a jfx app class and an incorrest * Test uses main method and blank main method, a jfx app class and an incorrest
* jfx app class, a main-class for the manifest, a bogus one and none. * jfx app class, a main-class for the manifest, a bogus one and none.
...@@ -47,6 +47,8 @@ public class FXLauncherTest extends TestHelper { ...@@ -47,6 +47,8 @@ public class FXLauncherTest extends TestHelper {
/* standard main class can be used as java main for fx app class */ /* standard main class can be used as java main for fx app class */
static final String StdMainClass = "helloworld.HelloWorld"; static final String StdMainClass = "helloworld.HelloWorld";
static final String ExtMainClass = "helloworld.ExtHello";
static final String NonFXMainClass = "helloworld.HelloJava";
static int testcount = 0; static int testcount = 0;
/* a main method and a blank. */ /* a main method and a blank. */
...@@ -107,9 +109,7 @@ public class FXLauncherTest extends TestHelper { ...@@ -107,9 +109,7 @@ public class FXLauncherTest extends TestHelper {
} }
/* /*
* Create class to extend fx java file for test application * Create class that extends HelloWorld instead of Application
* TODO: make test to create java file and this extension of the java file
* and jar them together an run app via this java class.
*/ */
static void createExtJavaFile(String mainmethod) { static void createExtJavaFile(String mainmethod) {
try { try {
...@@ -125,16 +125,48 @@ public class FXLauncherTest extends TestHelper { ...@@ -125,16 +125,48 @@ public class FXLauncherTest extends TestHelper {
compile("-cp", ".", "-d", ".", mainClass + JAVA_FILE_EXT); compile("-cp", ".", "-d", ".", mainClass + JAVA_FILE_EXT);
} catch (java.io.IOException ioe) { } catch (java.io.IOException ioe) {
ioe.printStackTrace(); ioe.printStackTrace();
throw new RuntimeException("Failed creating HelloWorld."); throw new RuntimeException("Failed creating ExtHello.");
}
}
/*
* Create non-JavaFX class for testing if jfxrt.jar is being loaded
* when it shouldn't be
*/
static void createNonFXJavaFile() {
try {
String mainClass = "HelloJava";
List<String> contents = new ArrayList<>();
contents.add("package helloworld;");
contents.add("public class HelloJava {");
contents.add(" public static void main(String[] args) {");
contents.add(" for(String aa : args)");
contents.add(" System.out.println(\"arg: \" + aa);" );
contents.add(" }");
contents.add("}");
// Create and compile java source.
MainJavaFile = new File(mainClass + JAVA_FILE_EXT);
createFile(MainJavaFile, contents);
compile("-cp", ".", "-d", ".", mainClass + JAVA_FILE_EXT);
} catch (java.io.IOException ioe) {
ioe.printStackTrace();
throw new RuntimeException("Failed creating HelloJava.");
} }
} }
// Create manifest for test fx application // Create manifest for test fx application
static List<String> createManifestContents(String mainclassentry) { static List<String> createManifestContents(String mainClassEntry, String fxMainEntry) {
List<String> mcontents = new ArrayList<>(); List<String> mcontents = new ArrayList<>();
mcontents.add("Manifest-Version: 1.0"); mcontents.add("Manifest-Version: 1.0");
mcontents.add("Created-By: FXLauncherTest"); mcontents.add("Created-By: FXLauncherTest");
mcontents.add("Main-Class: " + mainclassentry); if (mainClassEntry != null) {
mcontents.add("Main-Class: " + mainClassEntry);
System.out.println("Main-Class: " + mainClassEntry);
}
if (fxMainEntry != null) {
mcontents.add("JavaFX-Application-Class: " + fxMainEntry);
System.out.println("JavaFX-Application-Class: " + fxMainEntry);
}
return mcontents; return mcontents;
} }
...@@ -175,31 +207,41 @@ public class FXLauncherTest extends TestHelper { ...@@ -175,31 +207,41 @@ public class FXLauncherTest extends TestHelper {
/* /*
* Set Main-Class and iterate main_methods. * Set Main-Class and iterate main_methods.
* Try launching with both -jar and -cp methods. * Try launching with both -jar and -cp methods, with and without FX main
* class manifest entry.
* All cases should run. * All cases should run.
*
* See sun.launcher.LauncherHelper$FXHelper for more details on how JavaFX
* applications are launched.
*/ */
@Test @Test
static void testBasicFXApp() throws Exception { static void testBasicFXApp() throws Exception {
testBasicFXApp(true); testBasicFXApp(true, false); // -cp, no JAC
testBasicFXApp(false); testBasicFXApp(false, true); // -jar, with JAC
testBasicFXApp(false, false); // -jar, no JAC
} }
static void testBasicFXApp(boolean useCP) throws Exception { static void testBasicFXApp(boolean useCP, boolean setFXMainClass) throws Exception {
String testname = "testBasicFXApp"; String testname = "testBasicFXApp";
if (useCP) {
testname = testname.concat("_useCP");
}
String fxMC = StdMainClass;
if (!setFXMainClass) {
testname = testname.concat("_noJAC");
fxMC = null;
}
for (String mm : MAIN_METHODS) { for (String mm : MAIN_METHODS) {
testcount++; testcount++;
line(); line();
System.out.println("test# " + testcount + System.out.println("test# " + testcount + "- Main method: " + mm);
"- Main method: " + mm +
"; MF main class: " + StdMainClass);
createJavaFile(mm); createJavaFile(mm);
createFile(ManifestFile, createManifestContents(StdMainClass)); createFile(ManifestFile, createManifestContents(StdMainClass, fxMC));
createJar(FXtestJar, ManifestFile); createJar(FXtestJar, ManifestFile);
String sTestJar = FXtestJar.getAbsolutePath(); String sTestJar = FXtestJar.getAbsolutePath();
TestResult tr; TestResult tr;
if (useCP) { if (useCP) {
tr = doExec(javaCmd, "-cp", sTestJar, StdMainClass, APP_PARMS[0], APP_PARMS[1]); tr = doExec(javaCmd, "-cp", sTestJar, StdMainClass, APP_PARMS[0], APP_PARMS[1]);
testname = testname.concat("_useCP");
} else { } else {
tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]); tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
} }
...@@ -224,26 +266,33 @@ public class FXLauncherTest extends TestHelper { ...@@ -224,26 +266,33 @@ public class FXLauncherTest extends TestHelper {
*/ */
@Test @Test
static void testExtendFXApp() throws Exception { static void testExtendFXApp() throws Exception {
testExtendFXApp(true); testExtendFXApp(true, false); // -cp, no JAC
testExtendFXApp(false); testExtendFXApp(false, true); // -jar, with JAC
testExtendFXApp(false, false); // -jar, no JAC
} }
static void testExtendFXApp(boolean useCP) throws Exception { static void testExtendFXApp(boolean useCP, boolean setFXMainClass) throws Exception {
String testname = "testExtendFXApp"; String testname = "testExtendFXApp";
if (useCP) {
testname = testname.concat("_useCP");
}
String fxMC = ExtMainClass;
if (!setFXMainClass) {
testname = testname.concat("_noJAC");
fxMC = null;
}
for (String mm : MAIN_METHODS) { for (String mm : MAIN_METHODS) {
testcount++; testcount++;
line(); line();
System.out.println("test# " + testcount + System.out.println("test# " + testcount + "- Main method: " + mm);
"- Main method: " + mm + "; MF main class: " + StdMainClass);
createJavaFile(mm); createJavaFile(mm);
createExtJavaFile(mm); createExtJavaFile(mm);
createFile(ManifestFile, createManifestContents(StdMainClass)); createFile(ManifestFile, createManifestContents(ExtMainClass, fxMC));
createJar(FXtestJar, ManifestFile); createJar(FXtestJar, ManifestFile);
String sTestJar = FXtestJar.getAbsolutePath(); String sTestJar = FXtestJar.getAbsolutePath();
TestResult tr; TestResult tr;
if (useCP) { if (useCP) {
tr = doExec(javaCmd, "-cp", sTestJar, StdMainClass, APP_PARMS[0], APP_PARMS[1]); tr = doExec(javaCmd, "-cp", sTestJar, ExtMainClass, APP_PARMS[0], APP_PARMS[1]);
testname = testname.concat("_useCP");
} else { } else {
tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]); tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
} }
...@@ -256,27 +305,82 @@ public class FXLauncherTest extends TestHelper { ...@@ -256,27 +305,82 @@ public class FXLauncherTest extends TestHelper {
} }
} }
} }
checkStatus(tr, testname, testcount, StdMainClass); checkStatus(tr, testname, testcount, ExtMainClass);
}
}
/*
* Ensure we can NOT launch a FX app jar with no Main-Class manifest entry
*/
@Test
static void testMissingMC() throws Exception {
String testname = "testMissingMC";
testcount++;
line();
System.out.println("test# " + testcount + ": abort on missing Main-Class");
createJavaFile(" "); // no main() needed
createFile(ManifestFile, createManifestContents(null, StdMainClass)); // No MC, but supply JAC
createJar(FXtestJar, ManifestFile);
String sTestJar = FXtestJar.getAbsolutePath();
TestResult tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
tr.checkNegative(); // should abort if no Main-Class
if (tr.testStatus) {
if (!tr.contains("no main manifest attribute")) {
System.err.println("ERROR: launcher did not abort properly");
}
} else {
System.err.println("ERROR: jar executed with no Main-Class!");
} }
checkStatus(tr, testname, testcount, StdMainClass);
} }
/* /*
* test to ensure that we don't load any extraneous fx jars when * test to ensure that we don't load any extraneous fx jars when
* launching a standard java application * launching a standard java application
* Test both -cp and -jar methods since they use different code paths.
* Neither case should cause jfxrt.jar to be loaded.
*/ */
@Test @Test
static void testExtraneousJars()throws Exception { static void testExtraneousJars() throws Exception {
testExtraneousJars(true);
testExtraneousJars(false);
}
static void testExtraneousJars(boolean useCP) throws Exception {
String testname = "testExtraneousJars"; String testname = "testExtraneousJars";
if (useCP) {
testname = testname.concat("_useCP");
}
testcount++; testcount++;
line(); line();
System.out.println("test# " + testcount); System.out.println("test# " + testcount
TestResult tr = doExec(javacCmd, "-J-verbose:class", "-version"); + ": test for erroneous jfxrt.jar loading");
if (!tr.notContains("jfxrt.jar")) { createNonFXJavaFile();
System.out.println("testing for extraneous jfxrt jar"); createFile(ManifestFile, createManifestContents(NonFXMainClass, null));
System.out.println(tr); createJar(FXtestJar, ManifestFile);
throw new Exception("jfxrt.jar is being loaded by javac!!!"); String sTestJar = FXtestJar.getAbsolutePath();
TestResult tr;
if (useCP) {
tr = doExec(javaCmd, "-verbose:class", "-cp", sTestJar, NonFXMainClass, APP_PARMS[0], APP_PARMS[1]);
} else {
tr = doExec(javaCmd, "-verbose:class", "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
} }
checkStatus(tr, testname, testcount, StdMainClass); tr.checkPositive();
if (tr.testStatus) {
if (!tr.notContains("jfxrt.jar")) {
System.out.println("testing for extraneous jfxrt jar");
System.out.println(tr);
throw new Exception("jfxrt.jar is being loaded, it should not be!");
}
for (String p : APP_PARMS) {
if (!tr.contains(p)) {
System.err.println("ERROR: Did not find "
+ p + " in output!");
}
}
}
checkStatus(tr, testname, testcount, NonFXMainClass);
} }
public static void main(String... args) throws Exception { public static void main(String... args) throws Exception {
......
...@@ -68,6 +68,7 @@ public class VersionCheck extends TestHelper { ...@@ -68,6 +68,7 @@ public class VersionCheck extends TestHelper {
"jcmd", "jcmd",
"jconsole", "jconsole",
"jcontrol", "jcontrol",
"jdeps",
"jinfo", "jinfo",
"jmap", "jmap",
"jps", "jps",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册